Skip to main content

max / alloy

4.5 KB · 103 lines History Blame Raw
1 #!/usr/bin/env bash
2 #
3 # case.sh — move the guest's base to a variant and report what became of the
4 # layered package.
5 #
6 # case.sh n2 upgrade with rpm-ostree, reboot, read the state back
7 # case.sh n2 --bootc use bootc upgrade instead, which is a separate answer
8 # case.sh n4 --drain drop our layers first, then upgrade
9 #
10 # --drain is the candidate answer to the wedge the first run measured: a base
11 # that moves ahead of a layered hotfix stops the machine updating, forever,
12 # and that is the normal life of a hotfix rather than an edge case. The rule
13 # it tests is that our own layers are disposable — never carried across an
14 # upgrade, dropped before it and re-applied after if the base still needs
15 # them. If that holds, the depsolve conflict cannot arise at all, because
16 # there is never a layer and a base copy in the same transaction.
17 #
18 # Chained into one transaction on purpose. rpm-ostree stages a deployment per
19 # command, and what matters is whether a user pays one reboot or two, so the
20 # uninstall and the upgrade go in a single invocation and the deployment count
21 # is part of the result.
22 #
23 # Retagging is how the base moves. The installed system points at :latest in
24 # the host registry, so pushing a different variant to that tag is the whole
25 # mechanism; nothing in the guest has to be reconfigured between cases.
26 #
27 # The reboot is not optional. rpm-ostree stages a deployment and the running
28 # system keeps running the old one, so reading `alloy-demo` before the reboot
29 # reports the previous answer and looks like a failure to apply.
30 set -euo pipefail
31
32 # shellcheck source=build/layertest/common.sh
33 . "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/common.sh"
34
35 # shellcheck source=build/privilege.sh
36 . "$HERE/../privilege.sh"
37
38 MARK="${1:-}"
39 [ -n "$MARK" ] || die "usage: case.sh <mark> [--bootc|--drain]"
40 VERB="rpm-ostree upgrade"
41 DRAIN=no
42 case "${2:-}" in
43 --bootc) VERB="bootc upgrade" ;;
44 --drain) DRAIN=yes ;;
45 "") ;;
46 *) die "unknown option ${2}" ;;
47 esac
48
49 privc podman push --tls-verify=false "$IMAGE:$MARK" \
50 "127.0.0.1:$REGISTRY_PORT/alloy-layertest:latest" >/dev/null 2>&1
51
52 # Drop our own layers before the upgrade rather than after, and by the exact
53 # string the request was recorded under. A bare package name does not match a
54 # request made by NEVRA, and rpm-ostree says so in a way that reads as "there
55 # was nothing to do" rather than as a failure — which is how a drain silently
56 # does not drain and the machine wedges anyway.
57 #
58 # Enumerated rather than `rpm-ostree reset`, which would work here and is
59 # wrong as a model: reset drops every layered package including ones the user
60 # layered themselves, and those are not ours to remove. Production has to be
61 # this precise, so the harness is too.
62 if [ "$DRAIN" = yes ]; then
63 say "=== drain: dropping our layers before the upgrade ==="
64 ours=$("$HERE/sshx" 'rpm-ostree status --json' \
65 | python3 "$HERE/readstate.py" --requested alloy-demo)
66 if [ -z "$ours" ]; then
67 say "nothing of ours is layered"
68 else
69 for package in $ours; do
70 say "uninstalling $package"
71 "$HERE/sshx" "rpm-ostree uninstall $package" 2>&1 | tail -3
72 done
73 fi
74 fi
75
76 say "=== $VERB onto $MARK ==="
77 # Not fatal. A refusal is a result, and the whole point of --bootc is to see
78 # one, so the script has to survive the command it is measuring.
79 "$HERE/sshx" "$VERB" 2>&1 | tail -6 || true
80
81 "$HERE/sshx" 'systemctl reboot' >/dev/null 2>&1 || true
82 sleep 45
83
84 say "--- booted ---"
85 # `|| true` on the last command: `rpm -q` exits 1 for a package that is not
86 # installed, and that is a result rather than a failure. Without it a case that
87 # legitimately ends with nothing layered reports "guest did not come back"
88 # about a guest that came back and answered the question.
89 "$HERE/sshx" 'echo -n "base-mark: "; cat /usr/share/base-mark; \
90 echo -n "binary: "; alloy-demo 2>&1 || echo "(absent)"; \
91 echo -n "rpm -q: "; rpm -q alloy-demo 2>&1 || true' \
92 || die "guest did not come back"
93 "$HERE/sshx" 'rpm-ostree status --json' | python3 "$HERE/readstate.py"
94
95 # Whether the machine can still take the next one. A wedge does not show up in
96 # the state above — it reports a perfectly ordinary deployment — and only
97 # announces itself the next time somebody tries to update. Both verbs, because
98 # the whole point of dropping the layer is to hand `bootc upgrade` back a
99 # deployment it will consent to work on.
100 say "--- can it still update? ---"
101 "$HERE/sshx" 'rpm-ostree upgrade --check 2>&1 | tail -3' || true
102 "$HERE/sshx" 'bootc upgrade --check 2>&1 | tail -3' || true
103