Merge ~cjwatson/launchpad:charm-scripts-actions into launchpad:master

Proposed by Colin Watson
Status: Merged
Approved by: Colin Watson
Approved revision: 7169f5d2a6c300e02bbd651044caf2cd49165769
Merge reported by: Otto Co-Pilot
Merged at revision: not available
Proposed branch: ~cjwatson/launchpad:charm-scripts-actions
Merge into: launchpad:master
Diff against target: 116 lines (+82/-0)
5 files modified
charm/launchpad-scripts/README.md (+11/-0)
charm/launchpad-scripts/actions.yaml (+9/-0)
charm/launchpad-scripts/actions/actions.py (+60/-0)
charm/launchpad-scripts/actions/start-services (+1/-0)
charm/launchpad-scripts/actions/stop-services (+1/-0)
Reviewer Review Type Date Requested Status
Guruprasad Approve
Ines Almeida Approve
Review via email: mp+445674@code.launchpad.net

Commit message

charm/launchpad-scripts: Add start-services/stop-services actions

Description of the change

In our legacy production deployment, we stop and start these services around certain kinds of maintenance actions, mainly database schema upgrades. The preferred way to do this sort of thing in Juju is using actions, so define a couple of suitable actions; once we deploy this to production, we'll set up an SSH trigger allowing developers to run any of an allowlist of actions on production.

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

Makes sense to me

Added a small question in the comments.
Also what's the purpose of `hookenv.action_set()`? In the docs it seems to be the value that the action returns - but we don't seem to use any return value from the actions (?). Is it mostly because as action needs to return something?

review: Approve
Revision history for this message
Guruprasad (lgp171188) :
review: Approve
5458c60... by Colin Watson

Clarify a couple of documentation points

Revision history for this message
Colin Watson (cjwatson) :
Revision history for this message
Colin Watson (cjwatson) wrote :

`hookenv.action_set` is indeed just because it's generally expected that actions return something. The arguments to that should show up in the output from `juju run-action --wait`.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/charm/launchpad-scripts/README.md b/charm/launchpad-scripts/README.md
index ec07c92..257a0f7 100644
--- a/charm/launchpad-scripts/README.md
+++ b/charm/launchpad-scripts/README.md
@@ -8,3 +8,14 @@ You will need the following relations:
8 juju relate launchpad-scripts:session-db postgresql:db8 juju relate launchpad-scripts:session-db postgresql:db
9 juju relate launchpad-scripts memcached9 juju relate launchpad-scripts memcached
10 juju relate launchpad-scripts rabbitmq-server10 juju relate launchpad-scripts rabbitmq-server
11
12## Maintenance actions
13
14To stop Celery workers and `number-cruncher` (perhaps in preparation for a
15schema upgrade), run:
16
17 juju run-action --wait launchpad-scripts/leader stop-services
18
19To start them again once maintenance is complete:
20
21 juju run-action --wait launchpad-scripts/leader start-services
diff --git a/charm/launchpad-scripts/actions.yaml b/charm/launchpad-scripts/actions.yaml
11new file mode 10064422new file mode 100644
index 0000000..aa1c55c
--- /dev/null
+++ b/charm/launchpad-scripts/actions.yaml
@@ -0,0 +1,9 @@
1start-services:
2 description: Start services. Usually run after maintenance.
3stop-services:
4 description: |
5 Stop services. Usually run in preparation for maintenance. (Note that
6 this does not stop services in a way that will persist across a reboot.
7 It also doesn't disable cron jobs, since those are handled by the
8 cron-control mechanism instead; see
9 lp.services.scripts.base.cronscript_enabled.)
diff --git a/charm/launchpad-scripts/actions/actions.py b/charm/launchpad-scripts/actions/actions.py
0new file mode 10075510new file mode 100755
index 0000000..67d862c
--- /dev/null
+++ b/charm/launchpad-scripts/actions/actions.py
@@ -0,0 +1,60 @@
1#! /usr/bin/python3
2# Copyright 2023 Canonical Ltd. This software is licensed under the
3# GNU Affero General Public License version 3 (see the file LICENSE).
4
5import subprocess
6import sys
7import traceback
8from pathlib import Path
9
10sys.path.append("lib")
11
12from charms.layer import basic # noqa: E402
13
14basic.bootstrap_charm_deps()
15basic.init_config_states()
16
17from charmhelpers.core import hookenv # noqa: E402
18
19services = (
20 "celerybeat_launchpad.service",
21 "celeryd_launchpad_job.service",
22 "celeryd_launchpad_job_slow.service",
23 "number-cruncher.service",
24)
25
26
27def start_services():
28 for service in services:
29 hookenv.log(f"Starting {service}.")
30 subprocess.run(["systemctl", "start", service], check=True)
31 hookenv.action_set({"result": "Services started"})
32
33
34def stop_services():
35 for service in services:
36 hookenv.log(f"Stopping {service}.")
37 subprocess.run(["systemctl", "stop", service], check=True)
38 hookenv.action_set({"result": "Services stopped"})
39
40
41def main(argv):
42 action = Path(argv[0]).name
43 try:
44 if action == "start-services":
45 start_services()
46 elif action == "stop-services":
47 stop_services()
48 else:
49 hookenv.action_fail(f"Action {action} not implemented.")
50 except Exception:
51 hookenv.action_fail("Unhandled exception")
52 tb = traceback.format_exc()
53 hookenv.action_set(dict(traceback=tb))
54 hookenv.log(f"Unhandled exception in action {action}:")
55 for line in tb.splitlines():
56 hookenv.log(line)
57
58
59if __name__ == "__main__":
60 main(sys.argv)
diff --git a/charm/launchpad-scripts/actions/start-services b/charm/launchpad-scripts/actions/start-services
0new file mode 12000061new file mode 120000
index 0000000..405a394
--- /dev/null
+++ b/charm/launchpad-scripts/actions/start-services
@@ -0,0 +1 @@
1actions.py
0\ No newline at end of file2\ No newline at end of file
diff --git a/charm/launchpad-scripts/actions/stop-services b/charm/launchpad-scripts/actions/stop-services
1new file mode 1200003new file mode 120000
index 0000000..405a394
--- /dev/null
+++ b/charm/launchpad-scripts/actions/stop-services
@@ -0,0 +1 @@
1actions.py
0\ No newline at end of file2\ No newline at end of file

Subscribers

People subscribed via source and target branches

to status/vote changes: