Merge ~lgp171188/launchpad:charm-launchpad-scripts-bzrsyncd into launchpad:master

Proposed by Guruprasad
Status: Merged
Approved by: Guruprasad
Approved revision: 1d48627a1cadf268cf81fef4dbb87fa1d1e799ed
Merge reported by: Otto Co-Pilot
Merged at revision: not available
Proposed branch: ~lgp171188/launchpad:charm-launchpad-scripts-bzrsyncd
Merge into: launchpad:master
Diff against target: 519 lines (+421/-0)
16 files modified
charm/launchpad-scripts-bzrsyncd/README.md (+19/-0)
charm/launchpad-scripts-bzrsyncd/actions.yaml (+8/-0)
charm/launchpad-scripts-bzrsyncd/actions/actions.py (+59/-0)
charm/launchpad-scripts-bzrsyncd/actions/start-services (+1/-0)
charm/launchpad-scripts-bzrsyncd/actions/stop-services (+1/-0)
charm/launchpad-scripts-bzrsyncd/charmcraft.yaml (+63/-0)
charm/launchpad-scripts-bzrsyncd/config.yaml (+11/-0)
charm/launchpad-scripts-bzrsyncd/layer.yaml (+14/-0)
charm/launchpad-scripts-bzrsyncd/metadata.yaml (+18/-0)
charm/launchpad-scripts-bzrsyncd/reactive/launchpad-scripts-bzrsyncd.py (+98/-0)
charm/launchpad-scripts-bzrsyncd/templates/celerybeat_bzrsyncd.service.j2 (+15/-0)
charm/launchpad-scripts-bzrsyncd/templates/celeryd_bzrsyncd_job.service.j2 (+24/-0)
charm/launchpad-scripts-bzrsyncd/templates/celeryd_bzrsyncd_job_slow.service.j2 (+24/-0)
charm/launchpad-scripts-bzrsyncd/templates/crontab.j2 (+34/-0)
charm/launchpad-scripts-bzrsyncd/templates/launchpad-scripts-bzrsyncd-lazr.conf.j2 (+19/-0)
charm/launchpad-scripts-bzrsyncd/templates/logrotate.conf.j2 (+13/-0)
Reviewer Review Type Date Requested Status
Colin Watson (community) Approve
Review via email: mp+446073@code.launchpad.net

Commit message

charm: Implement the launchpad-scripts-bzrsyncd charm

To post a comment you must log in.
Revision history for this message
Ines Almeida (ines-almeida) wrote :

LGTM, only a few minor comments.
I don't feel comfortable being the sole reviewer though, so I'll leave the approval for someone else :)

Revision history for this message
Guruprasad (lgp171188) :
Revision history for this message
Colin Watson (cjwatson) :
Revision history for this message
Colin Watson (cjwatson) :
review: Approve
Revision history for this message
Guruprasad (lgp171188) :
Revision history for this message
Guruprasad (lgp171188) :

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/charm/launchpad-scripts-bzrsyncd/README.md b/charm/launchpad-scripts-bzrsyncd/README.md
2new file mode 100644
3index 0000000..6e5fced
4--- /dev/null
5+++ b/charm/launchpad-scripts-bzrsyncd/README.md
6@@ -0,0 +1,19 @@
7+# Launchpad scripts - bzrsyncd
8+
9+This charm sets up and runs the Launchpad bzrsyncd scripts and Celery workers.
10+
11+You will need the following relations:
12+
13+ juju relate launchpad-scripts-bzrsyncd:db postgresql:db
14+ juju relate launchpad-scripts-bzrsyncd memcached
15+ juju relate launchpad-scripts-bzrsyncd rabbitmq-server
16+
17+## Maintenance actions
18+
19+To stop Celery workers (perhaps in preparation for a schema upgrade), run:
20+
21+ juju run-action --wait launchpad-scripts-bzrsyncd/leader stop-services
22+
23+To start them again once maintenance is complete:
24+
25+ juju run-action --wait launchpad-scripts-bzrsyncd/leader start-services
26diff --git a/charm/launchpad-scripts-bzrsyncd/actions.yaml b/charm/launchpad-scripts-bzrsyncd/actions.yaml
27new file mode 100644
28index 0000000..e99d06e
29--- /dev/null
30+++ b/charm/launchpad-scripts-bzrsyncd/actions.yaml
31@@ -0,0 +1,8 @@
32+start-services:
33+ description: Start celery workers. Usually run after maintenance.
34+stop-services:
35+ description: |
36+ Stop celery workers. Usually run in preparation for maintenance. (Note that
37+ this does not stop services in a way that will persist across a reboot. It
38+ also doesn't disable cron jobs, since those are handled by the cron-control
39+ mechanism instead. see lp.services.scripts.base.cronscript_enabled.)
40diff --git a/charm/launchpad-scripts-bzrsyncd/actions/actions.py b/charm/launchpad-scripts-bzrsyncd/actions/actions.py
41new file mode 100644
42index 0000000..02617ec
43--- /dev/null
44+++ b/charm/launchpad-scripts-bzrsyncd/actions/actions.py
45@@ -0,0 +1,59 @@
46+#! /usr/bin/python3
47+# Copyright 2023 Canonical Ltd. This software is licensed under the
48+# GNU Affero General Public License version 3 (see the file LICENSE).
49+
50+import subprocess
51+import sys
52+import traceback
53+from pathlib import Path
54+
55+sys.path.append("lib")
56+
57+from charms.layer import basic # noqa: E402
58+
59+basic.bootstrap_charm_deps()
60+basic.init_config_states()
61+
62+from charmhelpers.core import hookenv # noqa: E402
63+
64+services = (
65+ "celerybeat_bzrsyncd.service",
66+ "celeryd_bzrsyncd_job.service",
67+ "celeryd_bzrsyncd_job_slow.service",
68+)
69+
70+
71+def start_services():
72+ for service in services:
73+ hookenv.log(f"Starting {service}.")
74+ subprocess.run(["systemctl", "start", service], check=True)
75+ hookenv.action_set({"result": "Services started"})
76+
77+
78+def stop_services():
79+ for service in services:
80+ hookenv.log(f"Stopping {service}.")
81+ subprocess.run(["systemctl", "stop", service], check=True)
82+ hookenv.action_set({"result": "Services stopped"})
83+
84+
85+def main(argv):
86+ action = Path(argv[0]).name
87+ try:
88+ if action == "start-services":
89+ start_services()
90+ elif action == "stop-services":
91+ stop_services()
92+ else:
93+ hookenv.action_fail(f"Action {action} not implemented.")
94+ except Exception:
95+ hookenv.action_fail("Unhandled exception")
96+ tb = traceback.format_exc()
97+ hookenv.action_set(dict(traceback=tb))
98+ hookenv.log(f"Unhandled exception in action {action}:")
99+ for line in tb.splitlines():
100+ hookenv.log(line)
101+
102+
103+if __name__ == "__main__":
104+ main(sys.argv)
105diff --git a/charm/launchpad-scripts-bzrsyncd/actions/start-services b/charm/launchpad-scripts-bzrsyncd/actions/start-services
106new file mode 100644
107index 0000000..405a394
108--- /dev/null
109+++ b/charm/launchpad-scripts-bzrsyncd/actions/start-services
110@@ -0,0 +1 @@
111+actions.py
112\ No newline at end of file
113diff --git a/charm/launchpad-scripts-bzrsyncd/actions/stop-services b/charm/launchpad-scripts-bzrsyncd/actions/stop-services
114new file mode 100644
115index 0000000..405a394
116--- /dev/null
117+++ b/charm/launchpad-scripts-bzrsyncd/actions/stop-services
118@@ -0,0 +1 @@
119+actions.py
120\ No newline at end of file
121diff --git a/charm/launchpad-scripts-bzrsyncd/charmcraft.yaml b/charm/launchpad-scripts-bzrsyncd/charmcraft.yaml
122new file mode 100644
123index 0000000..9b28632
124--- /dev/null
125+++ b/charm/launchpad-scripts-bzrsyncd/charmcraft.yaml
126@@ -0,0 +1,63 @@
127+type: charm
128+bases:
129+ - build-on:
130+ - name: ubuntu
131+ channel: "20.04"
132+ architectures: [amd64]
133+ run-on:
134+ - name: ubuntu
135+ channel: "20.04"
136+ architectures: [amd64]
137+parts:
138+ charm-wheels:
139+ source: https://git.launchpad.net/~ubuntuone-hackers/ols-charm-deps/+git/wheels
140+ source-commit: "42c89d9c66dbe137139b047fd54aed49b66d1a5e"
141+ source-submodules: []
142+ source-type: git
143+ plugin: dump
144+ organize:
145+ "*": charm-wheels/
146+ prime:
147+ - "-charm-wheels"
148+ ols-layers:
149+ source: https://git.launchpad.net/ols-charm-deps
150+ source-commit: "f63ae0386275bf9089b30c8abae252a0ea523633"
151+ source-submodules: []
152+ source-type: git
153+ plugin: dump
154+ organize:
155+ "*": layers/
156+ stage:
157+ - layers
158+ prime:
159+ - "-layers"
160+ launchpad-layers:
161+ after:
162+ - ols-layers
163+ source: https://git.launchpad.net/launchpad-layers
164+ source-commit: "42a4b4c4f62936b1d050c775e84f7364dfb5efc0"
165+ source-submodules: []
166+ source-type: git
167+ plugin: dump
168+ organize:
169+ launchpad-base: layers/layer/launchpad-base
170+ launchpad-db: layers/layer/launchpad-db
171+ launchpad-payload: layers/layer/launchpad-payload
172+ stage:
173+ - layers
174+ prime:
175+ - "-layers"
176+ launchpad-scripts-bzrsyncd:
177+ after:
178+ - charm-wheels
179+ - launchpad-layers
180+ source: .
181+ plugin: reactive
182+ build-snaps: [charm]
183+ build-packages: [libpq-dev, python3-dev]
184+ build-environment:
185+ - CHARM_LAYERS_DIR: $CRAFT_STAGE/layers/layer
186+ - CHARM_INTERFACES_DIR: $CRAFT_STAGE/layers/interface
187+ - PIP_NO_INDEX: "true"
188+ - PIP_FIND_LINKS: $CRAFT_STAGE/charm-wheels
189+ reactive-charm-build-arguments: [--binary-wheels-from-source]
190diff --git a/charm/launchpad-scripts-bzrsyncd/config.yaml b/charm/launchpad-scripts-bzrsyncd/config.yaml
191new file mode 100644
192index 0000000..6fc917d
193--- /dev/null
194+++ b/charm/launchpad-scripts-bzrsyncd/config.yaml
195@@ -0,0 +1,11 @@
196+options:
197+ active:
198+ type: boolean
199+ description: Should the cron jobs and the celery services be active?
200+ default: true
201+ internal_branch_by_id_root:
202+ type: string
203+ description: |
204+ The URL prefix for where branches are served by URLs based on the
205+ branch ID.
206+ default:
207diff --git a/charm/launchpad-scripts-bzrsyncd/layer.yaml b/charm/launchpad-scripts-bzrsyncd/layer.yaml
208new file mode 100644
209index 0000000..e7b38bd
210--- /dev/null
211+++ b/charm/launchpad-scripts-bzrsyncd/layer.yaml
212@@ -0,0 +1,14 @@
213+includes:
214+ - layer:launchpad-db
215+ - interface:memcache
216+options:
217+ ols-pg:
218+ databases:
219+ db:
220+ name: launchpad_dev
221+ roles:
222+ - branchscanner
223+ - merge-proposal-jobs
224+ - request-daily-builds
225+ - send-branch-mail
226+ - translationsbranchscanner
227diff --git a/charm/launchpad-scripts-bzrsyncd/metadata.yaml b/charm/launchpad-scripts-bzrsyncd/metadata.yaml
228new file mode 100644
229index 0000000..2a49882
230--- /dev/null
231+++ b/charm/launchpad-scripts-bzrsyncd/metadata.yaml
232@@ -0,0 +1,18 @@
233+name: launchpad-scripts-bzrsyncd
234+display-name: launchpad-scripts-bzrsyncd
235+summary: Launchpad scripts - bzrsyncd
236+maintainer: Launchpad Developers <launchpad-dev@lists.launchpad.net>
237+description: |
238+ Launchpad is an open source suite of tools that help people and teams
239+ to work together on software projects.
240+
241+ This charm sets up the cron jobs to run the scripts needed for 'bzrsyncd'.
242+tags:
243+ # https://juju.is/docs/charm-metadata#heading--charm-store-fields
244+ - network
245+series:
246+ - focal
247+subordinate: false
248+requires:
249+ memcache:
250+ interface: memcache
251diff --git a/charm/launchpad-scripts-bzrsyncd/reactive/launchpad-scripts-bzrsyncd.py b/charm/launchpad-scripts-bzrsyncd/reactive/launchpad-scripts-bzrsyncd.py
252new file mode 100644
253index 0000000..6dd81a1
254--- /dev/null
255+++ b/charm/launchpad-scripts-bzrsyncd/reactive/launchpad-scripts-bzrsyncd.py
256@@ -0,0 +1,98 @@
257+# Copyright 2023 Canonical Ltd. This software is licensed under the
258+# GNU Affero General Public License version 3 (see the file LICENSE).
259+
260+import subprocess
261+
262+from charmhelpers.core import hookenv, host, templating
263+from charms.launchpad.base import configure_email, get_service_config
264+from charms.launchpad.payload import configure_cron, configure_lazr
265+from charms.reactive import (
266+ endpoint_from_flag,
267+ remove_state,
268+ set_state,
269+ when,
270+ when_not,
271+ when_not_all,
272+)
273+
274+
275+def configure_logrotate(config):
276+ hookenv.log("Writing logrotate configuration.")
277+ templating.render(
278+ "logrotate.conf.j2",
279+ "/etc/logrotate.d/launchpad",
280+ config,
281+ perms=0o644,
282+ )
283+
284+
285+@host.restart_on_change(
286+ {
287+ "/lib/systemd/system/celerybeat-bzrsyncd.service": [
288+ "celerybeat-bzrsyncd",
289+ ],
290+ "/lib/systemd/system/celeryd_bzrsyncd_job.service": [
291+ "celeryd_bzrsyncd_job",
292+ ],
293+ "/lib/systemd/system/celeryd_bzrsyncd_job_slow.service": [
294+ "celeryd_bzrsyncd_job_slow",
295+ ],
296+ }
297+)
298+def configure_celery(config):
299+ hookenv.log("Writing celery systemd service files.")
300+ destination_dir = "/lib/systemd/system"
301+ service_files = (
302+ "celerybeat_bzrsyncd.service",
303+ "celeryd_bzrsyncd_job.service",
304+ "celeryd_bzrsyncd_job_slow.service",
305+ )
306+ for service_file in service_files:
307+ templating.render(
308+ f"{service_file}.j2",
309+ f"{destination_dir}/{service_file}",
310+ config,
311+ )
312+ subprocess.check_call(["systemctl", "daemon-reload"])
313+ for service_file in service_files:
314+ subprocess.check_call(["systemctl", "enable", service_file])
315+
316+
317+@when(
318+ "launchpad.db.configured",
319+ "memcache.available",
320+)
321+@when_not("service.configured")
322+def configure():
323+ config = get_service_config()
324+ memcache = endpoint_from_flag("memcache.available")
325+ config["memcache_servers"] = ",".join(
326+ sorted(
327+ f"({host}:{port},1)"
328+ for host, port in memcache.memcache_hosts_ports()
329+ )
330+ )
331+ configure_lazr(
332+ config,
333+ "launchpad-scripts-bzrsyncd-lazr.conf.j2",
334+ "launchpad-scripts-bzrsyncd/launchpad-lazr.conf",
335+ )
336+ configure_email(config, "launchpad-scripts")
337+ configure_logrotate(config)
338+ configure_cron(config, "crontab.j2")
339+ configure_celery(config)
340+ set_state("service.configured")
341+
342+
343+@when("service.configured")
344+def check_is_running():
345+ hookenv.status_set("active", "Ready")
346+
347+
348+@when("service.configured")
349+@when_not_all(
350+ "launchpad.db.configured",
351+ "memcache.available",
352+)
353+def deconfigure():
354+ remove_state("service.configured")
355diff --git a/charm/launchpad-scripts-bzrsyncd/templates/celerybeat_bzrsyncd.service.j2 b/charm/launchpad-scripts-bzrsyncd/templates/celerybeat_bzrsyncd.service.j2
356new file mode 100644
357index 0000000..598aecc
358--- /dev/null
359+++ b/charm/launchpad-scripts-bzrsyncd/templates/celerybeat_bzrsyncd.service.j2
360@@ -0,0 +1,15 @@
361+[Unit]
362+Description=celerybeat scheduler for bzrsyncd
363+After=syslog.target network.target remote-fs.target nss-lookup.target
364+
365+[Service]
366+Environment=LPCONFIG=launchpad-scripts-bzrsyncd
367+User=launchpad
368+WorkingDirectory={{ code_dir }}
369+ExecStart={{ code_dir }}/bin/celery beat --config=lp.services.job.celeryconfig
370+Restart=on-failure
371+LimitNOFILE=10000
372+
373+[Install]
374+WantedBy=multi-user.target
375+
376diff --git a/charm/launchpad-scripts-bzrsyncd/templates/celeryd_bzrsyncd_job.service.j2 b/charm/launchpad-scripts-bzrsyncd/templates/celeryd_bzrsyncd_job.service.j2
377new file mode 100644
378index 0000000..47d6eda
379--- /dev/null
380+++ b/charm/launchpad-scripts-bzrsyncd/templates/celeryd_bzrsyncd_job.service.j2
381@@ -0,0 +1,24 @@
382+[Unit]
383+Description=Celery service for Launchpad bzrsyncd jobs
384+After=network.target
385+
386+[Service]
387+Type=exec
388+User=launchpad
389+Group=launchpad
390+Environment=LPCONFIG=launchpad-scripts-bzrsyncd
391+WorkingDirectory={{ code_dir }}
392+ExecStart={{ code_dir }}/bin/celery worker \
393+ --queue bzrsyncd_job \
394+ --config=lp.services.job.celeryconfig \
395+ --hostname=launchpad_bzrsyncd_job \
396+ --loglevel=DEBUG \
397+ --logfile={{ logs_dir }}/celeryd_launchpad_bzrsyncd_job.log
398+ExecStop=/bin/kill -TERM $MAINPID
399+ExecReload=/bin/kill -HUP $MAINPID
400+PrivateTmp=true
401+Restart=on-failure
402+
403+[Install]
404+WantedBy=multi-user.target
405+
406diff --git a/charm/launchpad-scripts-bzrsyncd/templates/celeryd_bzrsyncd_job_slow.service.j2 b/charm/launchpad-scripts-bzrsyncd/templates/celeryd_bzrsyncd_job_slow.service.j2
407new file mode 100644
408index 0000000..34923be
409--- /dev/null
410+++ b/charm/launchpad-scripts-bzrsyncd/templates/celeryd_bzrsyncd_job_slow.service.j2
411@@ -0,0 +1,24 @@
412+[Unit]
413+Description=Celery service for Launchpad bzrsyncd slow jobs
414+After=network.target
415+
416+[Service]
417+Type=exec
418+User=launchpad
419+Group=launchpad
420+Environment=LPCONFIG=launchpad-scripts-bzrsyncd
421+WorkingDirectory={{ code_dir }}
422+ExecStart={{ code_dir }}/bin/celery worker \
423+ --queue bzrsyncd_job_slow \
424+ --config=lp.services.job.celeryconfig \
425+ --hostname=launchpad_bzrsyncd_job_slow \
426+ --loglevel=DEBUG \
427+ --logfile={{ logs_dir }}/celeryd_launchpad_bzrsyncd_job_slow.log
428+ExecStop=/bin/kill -TERM $MAINPID
429+ExecReload=/bin/kill -HUP $MAINPID
430+PrivateTmp=true
431+Restart=on-failure
432+
433+[Install]
434+WantedBy=multi-user.target
435+
436diff --git a/charm/launchpad-scripts-bzrsyncd/templates/crontab.j2 b/charm/launchpad-scripts-bzrsyncd/templates/crontab.j2
437new file mode 100644
438index 0000000..6b12e34
439--- /dev/null
440+++ b/charm/launchpad-scripts-bzrsyncd/templates/crontab.j2
441@@ -0,0 +1,34 @@
442+TZ=UTC
443+MAILTO={{ cron_mailto }}
444+LPCONFIG=launchpad-scripts-bzrsyncd
445+
446+{%- if active %}
447+
448+{%- if domain_bzr %}
449+# cleanup /tmp/bzr-limbo-* leftovers
450+0 1 * * * find /tmp -maxdepth 1 -name 'bzr-limbo-??????' -type d -mtime +1|xargs -r -I@ rm -rf '@'
451+{%- endif %}
452+
453+# branch scanner
454+* * * * * {{ code_dir }}/cronscripts/process-job-source.py IBranchScanJobSource -q --log-file=DEBUG:{{ logs_dir }}/process-job-source.IBranchScanJobSource.log
455+
456+# Branch Updates - emailed out
457+# set hard memory limit as per https://bugs.launchpad.net/launchpad/+bug/585126
458+* * * * * ulimit -v 1843200; {{ code_dir }}/cronscripts/process-job-source.py IRevisionMailJobSource -q --log-file=DEBUG:{{ logs_dir }}/process-job-source.IRevisionMailJobSource.log
459+* * * * * ulimit -v 1843200; {{ code_dir}}/cronscripts/process-job-source.py IRevisionsAddedJobSource -q --log-file=DEBUG:{{ logs_dir }}/process-job-source.IRevisionsAddedJobSource.log
460+
461+# processes code branches that have new translations imports pending
462+*/10 * * * * {{ code_dir }}/cronscripts/process-job-source.py IRosettaUploadJobSource -q --log-file=DEBUG:{{ logs_dir }}/process-job-source.IRosettaUploadJobSource.log
463+
464+# Update or create preview diffs for branch merge proposals &
465+# Send email about new merge proposals, generating a diff first if needed
466+* * * * * {{ code_dir }}/cronscripts/process-job-source.py IBranchMergeProposalJobSource -q --log-file=DEBUG:{{ logs_dir }}/process-job-source.IBranchMergeProposalJobSource.log
467+
468+# Script requests builds for source package recipes that have "build daily" enabled
469+*/15 * * * * {{ code_dir }}/cronscripts/request_daily_builds.py -v >> {{ logs_dir }}/request_daily_builds.log 2>&1
470+
471+{%- endif %}
472+
473+# OOPS amqp
474+*/15 * * * * {{ code_dir }}/bin/datedir2amqp --exchange oopses --host {{ rabbitmq_host }} --username {{ rabbitmq_username }} --password {{ rabbitmq_password }} --vhost {{ rabbitmq_vhost }} --repo {{ oopses_dir }} --key ""
475+
476diff --git a/charm/launchpad-scripts-bzrsyncd/templates/launchpad-scripts-bzrsyncd-lazr.conf.j2 b/charm/launchpad-scripts-bzrsyncd/templates/launchpad-scripts-bzrsyncd-lazr.conf.j2
477new file mode 100644
478index 0000000..f3b2c01
479--- /dev/null
480+++ b/charm/launchpad-scripts-bzrsyncd/templates/launchpad-scripts-bzrsyncd-lazr.conf.j2
481@@ -0,0 +1,19 @@
482+# Public configuration data. The contents of this file may be freely shared
483+# with developers if needed for debugging.
484+
485+# A schema's sections, keys, and values are automatically inherited, except
486+# for '.optional' sections. Update this config to override key values.
487+# Values are strings, except for numbers that look like ints. The tokens
488+# true, false, and none are treated as True, False, and None.
489+
490+{% from "macros.j2" import opt -%}
491+
492+[meta]
493+extends: ../launchpad-db-lazr.conf
494+
495+[codehosting]
496+{{- opt("internal_branch_by_id_root", internal_branch_by_id_root) }}
497+
498+[memcache]
499+servers: {{ memcache_servers }}
500+
501diff --git a/charm/launchpad-scripts-bzrsyncd/templates/logrotate.conf.j2 b/charm/launchpad-scripts-bzrsyncd/templates/logrotate.conf.j2
502new file mode 100644
503index 0000000..fc28d9d
504--- /dev/null
505+++ b/charm/launchpad-scripts-bzrsyncd/templates/logrotate.conf.j2
506@@ -0,0 +1,13 @@
507+{{ logs_dir }}/*.log {
508+ rotate 21
509+ dateext
510+ daily
511+ compress
512+ delaycompress
513+ sharedscripts
514+ postrotate
515+ systemctl restart celeryd_bzrsyncd_job
516+ systemctl restart celeryd_bzrsyncd_job_slow
517+ endscript
518+}
519+

Subscribers

People subscribed via source and target branches

to status/vote changes: