Skip to main content

max / alloy

2.0 KB · 49 lines History Blame Raw
1 # Read `rpm-ostree status --json` down to the fields that answer the question.
2 #
3 # The distinction that matters is packages versus requested-packages, and
4 # base-local-replacements versus requested-base-local-replacements. A request
5 # that never becomes active is recorded in the second of each pair and absent
6 # from the first, and it survives a reboot looking exactly like a request that
7 # worked. Reading the human `rpm-ostree status` output instead is how a no-op
8 # gets mistaken for an applied hotfix.
9 #
10 # ./sshx 'rpm-ostree status --json' | python3 readstate.py
11 #
12 # With --requested PREFIX it prints nothing but the requested-packages of the
13 # booted deployment whose name starts with PREFIX, one per line, for a caller
14 # that means to uninstall them. The exact strings matter: a request is recorded
15 # under whatever was typed to install it, so a package installed by full NEVRA
16 # cannot be removed by its bare name — `rpm-ostree uninstall alloy-demo` on a
17 # machine holding `alloy-demo-0.0.2-1.fc43.x86_64` answers "not currently
18 # requested" and leaves it in place. Measured 2026-08-14, and it is the whole
19 # reason this mode exists rather than the caller writing a package name.
20
21 import json
22 import sys
23
24 KEYS = (
25 "base-local-replacements", "requested-base-local-replacements",
26 "packages", "requested-packages",
27 "base-removals", "requested-base-removals",
28 "origin", "version",
29 )
30
31 data = json.load(sys.stdin)
32
33 if len(sys.argv) > 2 and sys.argv[1] == "--requested":
34 prefix = sys.argv[2]
35 for deployment in data["deployments"]:
36 if not deployment.get("booted"):
37 continue
38 for package in deployment.get("requested-packages", []):
39 if package.startswith(prefix):
40 print(package)
41 sys.exit(0)
42
43 for index, deployment in enumerate(data["deployments"]):
44 print("--- deployment %d booted=%s staged=%s" % (
45 index, deployment.get("booted"), deployment.get("staged")))
46 for key in KEYS:
47 if deployment.get(key):
48 print(" %s = %s" % (key, deployment[key]))
49