diff --git a/playbooks/nh3-extdev-althing-upgrade.yaml b/playbooks/nh3-extdev-althing-upgrade.yaml new file mode 100644 index 0000000..57cbee0 --- /dev/null +++ b/playbooks/nh3-extdev-althing-upgrade.yaml @@ -0,0 +1,60 @@ +# Upgrade althing on nh3-extdev to a given release. Version-parameterised and +# rerunnable — the sibling `nh3-extdev-althing-v3.yaml` is the historical +# v2→v3 CUTOVER and should not be mutated per release. +# +# scripts/elway infra-ops@10.100.50.42 \ +# --playbook playbooks/nh3-extdev-althing-upgrade.yaml --var version=3.7.0 +# +# ⚠ nh3-extdev is the box a `git pull` cannot move. althing is a system WHEEL +# at /opt/uv-tools/althing-core, entry points in /usr/local/bin, its herald is +# a SYSTEM unit (not a user unit like nh3-dev's), and `uv` is not on lkraven's +# PATH — it lives at /home/infra-ops/.local/bin/uv. BOTH UV_TOOL_DIR and +# UV_TOOL_BIN_DIR are required; setting only one installs to the wrong place. +# +# ⚠ `uv tool install` WITHOUT --force IS A SILENT NO-OP — uv matches the source +# SPEC, not its contents, so on a box that already installed from this path it +# prints "already installed" and exits 0 having done nothing. +# +# ⚠ VERIFY THE BINARY, NOT THE TAG. Every check below asserts the version the +# installed entry point actually reports. A wheel filename is a claim. +vars: + version: "3.7.0" + uv: /home/infra-ops/.local/bin/uv + tool_dir: /opt/uv-tools + bin_dir: /usr/local/bin + +steps: + - name: Stage the release wheel + upload: + src: /tmp/althing-release-3.7.0/althing_core-3.7.0-py3-none-any.whl + dest: /tmp/althing_core-{{ version }}-py3-none-any.whl + mode: "0644" + + - name: Record the version we are replacing + shell: "{{ bin_dir }}/postbox --version" + + - name: Install the staged wheel over the system wheel install + sudo: true + shell: env UV_TOOL_DIR={{ tool_dir }} UV_TOOL_BIN_DIR={{ bin_dir }} {{ uv }} tool install --force /tmp/althing_core-{{ version }}-py3-none-any.whl + # Idempotent on the INSTALLED VERSION, not on the wheel's presence. + when: "test \"$({{ bin_dir }}/postbox --version | awk '{print $2}')\" != '{{ version }}'" + + - name: Restart the herald so the new code is what is actually running + sudo: true + shell: systemctl restart althing-po-herald.service + +verify: + - name: the installed binary reports the new version + shell: "test \"$({{ bin_dir }}/postbox --version | awk '{print $2}')\" = '{{ version }}'" + changed_when: "false" + - name: the herald is running, and on the new code + sudo: true + shell: systemctl is-active --quiet althing-po-herald.service + changed_when: "false" + - name: the herald restarted just now rather than surviving from before + sudo: true + shell: "test $(( $(date +%s) - $(date -d \"$(systemctl show althing-po-herald.service -p ActiveEnterTimestamp --value)\" +%s) )) -lt 300" + changed_when: "false" + - name: the v2 entry points are still gone + shell: "! test -e {{ bin_dir }}/althing-cli && ! test -e {{ bin_dir }}/althing-receiver" + changed_when: "false" diff --git a/stacks/althing-post-office/compose.yaml b/stacks/althing-post-office/compose.yaml index da13c37..808ff0d 100644 --- a/stacks/althing-post-office/compose.yaml +++ b/stacks/althing-post-office/compose.yaml @@ -51,7 +51,7 @@ services: # Digest-pinned, not tag-floating: `:3.0.0` is a mutable pointer on a registry # anyone can re-push, and this container is the fleet's whole message bus. The # tag is kept alongside the digest purely so a human can read what it is. - image: gitea.phasefinal.com/claude-bot/althing-post-office:3.6.3@sha256:978f85533674ee248d6c6f29c54ffab0bc2cb16332c18c9fb8bfda1d566e2de4 + image: gitea.phasefinal.com/claude-bot/althing-post-office:3.7.0@sha256:df0709b3f532557aebb47d6ece486ae32e851776f732862094608d55eefcd4e7 container_name: althing-post-office # ─── Host networking, so the bind guard keeps working ────────────