Merge ~cjwatson/launchpad:charm-librarian-clear-storage-action into launchpad:master

Proposed by Colin Watson
Status: Merged
Approved by: Colin Watson
Approved revision: 37e2e7b71760f179910c4d5237f3466523fc3bca
Merge reported by: Otto Co-Pilot
Merged at revision: not available
Proposed branch: ~cjwatson/launchpad:charm-librarian-clear-storage-action
Merge into: launchpad:master
Diff against target: 98 lines (+78/-0)
3 files modified
charm/launchpad-librarian/README.md (+11/-0)
charm/launchpad-librarian/actions.yaml (+15/-0)
charm/launchpad-librarian/actions/clear-storage (+52/-0)
Reviewer Review Type Date Requested Status
Guruprasad Approve
Review via email: mp+444120@code.launchpad.net

Commit message

charm: Add a clear-storage action to the librarian

Description of the change

This is useful immediately after resetting the associated database. I expect to make use of it as part of automation for the staging environment, whose database is reset based on a production backup once a week.

Since this is destructive, I've included a couple of safety checks.

To post a comment you must log in.
Revision history for this message
Guruprasad (lgp171188) wrote :

LGTM 👍

review: Approve
Revision history for this message
Guruprasad (lgp171188) wrote :

> Since this is destructive, I've included a couple of safety checks.

I see one of the safety checks that compares the hostname against the production instance's hostname. Which is the other one?

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

The other one is the fact that you have to supply the expected librarian host name as an action parameter. (Inspired by https://manpages.debian.org/molly-guard.)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/charm/launchpad-librarian/README.md b/charm/launchpad-librarian/README.md
2index 52ab88c..5207d0a 100644
3--- a/charm/launchpad-librarian/README.md
4+++ b/charm/launchpad-librarian/README.md
5@@ -94,3 +94,14 @@ especially careful when redeploying. The general procedure is as follows:
6 1. As `stg-launchpad@launchpad-bastion-ps5.internal`, run `lpndt
7 service-start buildd-manager` to start `buildd-manager, then (after a
8 minute) `lpndt service-start cron-fdt` to enable all cron jobs.
9+
10+## Clearing librarian storage
11+
12+If you have reset the associated database, then it may be useful to clear
13+the librarian's storage as well, since the IDs used for stored files will no
14+longer exist in the database. To do this, run:
15+
16+ juju run-action --wait launchpad-librarian/leader clear-storage host=launchpadlibrarian.test
17+
18+The value passed to `host=` must match the hostname part of the
19+`librarian_download_url` configuration option.
20diff --git a/charm/launchpad-librarian/actions.yaml b/charm/launchpad-librarian/actions.yaml
21new file mode 100644
22index 0000000..54cd354
23--- /dev/null
24+++ b/charm/launchpad-librarian/actions.yaml
25@@ -0,0 +1,15 @@
26+clear-storage:
27+ description: |
28+ Clear local librarian storage. This irreversibly deletes data, so it
29+ requires the host name of this librarian instance to avoid accidentally
30+ clearing the wrong instance, and it always refuses to clear storage for
31+ the Launchpad production instance. It is useful when the associated
32+ database has been reset.
33+ params:
34+ host:
35+ type: string
36+ description: |
37+ The public host name of this librarian instance, required as a
38+ safety check.
39+ required:
40+ - host
41diff --git a/charm/launchpad-librarian/actions/clear-storage b/charm/launchpad-librarian/actions/clear-storage
42new file mode 100755
43index 0000000..8e77570
44--- /dev/null
45+++ b/charm/launchpad-librarian/actions/clear-storage
46@@ -0,0 +1,52 @@
47+#! /usr/bin/python3
48+# Copyright 2023 Canonical Ltd. This software is licensed under the
49+# GNU Affero General Public License version 3 (see the file LICENSE).
50+
51+import re
52+import shutil
53+import sys
54+from pathlib import Path
55+from urllib.parse import urlparse
56+
57+sys.path.append("lib")
58+
59+from charms.layer import basic # noqa: E402
60+
61+basic.bootstrap_charm_deps()
62+basic.init_config_states()
63+
64+from charmhelpers.core import hookenv # noqa: E402
65+from ols import base # noqa: E402
66+
67+
68+def clear_storage():
69+ params = hookenv.action_get()
70+ config = hookenv.config()
71+ expected_host = urlparse(config["librarian_download_url"]).hostname
72+ if expected_host == "launchpadlibrarian.net":
73+ hookenv.action_fail("Refusing to clear storage for production.")
74+ return
75+ if expected_host != params["host"]:
76+ hookenv.action_fail(
77+ f"Requested clearing storage for {params['host']}, but this is "
78+ f"{expected_host}."
79+ )
80+ return
81+
82+ librarian_dir = Path(base.base_dir()) / "librarian"
83+ hookenv.log(f"Clearing {librarian_dir}")
84+ # Only consider subdirectories created by
85+ # lp.services.librarianserver.storage._relFileLocation. In particular,
86+ # this excludes "incoming" and "lost+found".
87+ librarian_subdirs = [
88+ path
89+ for path in librarian_dir.iterdir()
90+ if re.match(r"^[0-9a-f][0-9a-f]$", path.name)
91+ ]
92+ for path in librarian_subdirs:
93+ shutil.rmtree(path)
94+ hookenv.action_set({"result": "Completed"})
95+
96+
97+if __name__ == "__main__":
98+ clear_storage()

Subscribers

People subscribed via source and target branches

to status/vote changes: