Skip to content

fix(packaging): preserve operator TLS cert across the cert-shipping → rc.10 transition#598

Merged
remyluslosius merged 1 commit into
mainfrom
fix/tls-cert-upgrade-transition
Jun 18, 2026
Merged

fix(packaging): preserve operator TLS cert across the cert-shipping → rc.10 transition#598
remyluslosius merged 1 commit into
mainfrom
fix/tls-cert-upgrade-transition

Conversation

@remyluslosius

Copy link
Copy Markdown
Contributor

Summary

Running the Stage-3 gap-closure (real rpm/dpkg install-transition tests) surfaced a regression in the rc.10 TLS fix (#596): the steady-state case is correct, but the one-time upgrade from a release that shipped the cert in its payload (rc.9 and earlier) removed the operator's cert entirely.

Root cause: rc.9 owned /etc/openwatch/tls/cert.pem; rc.10 does not. On upgrade, the package manager reclaims the orphaned file — and on RPM it does so after rc.10's %post provisioning already ran and skipped (seeing the cert present). Net: RPM leaves it missing (service can't start TLS); DEB regenerates a demo (operator cert lost).

Fix (both proven in containers)

  • RPM: declare the cert/key paths %ghost — rpm tracks the paths with no payload content (still "not shipped"), so it does not reclaim the operator's file on the transition.
  • DEB: no %ghost equivalent, so preinst stashes an existing cert/key to .dpkg-bak on upgrade (before dpkg removes the orphan) and postinst restores it before provisioning.

Verified: genuine published rc.9 → rc.10 now preserves the operator cert+key on both formats; fresh install still generates a demo; steady-state reinstall preserves.

Tests / spec

  • AC-22 updated: assert RPM cert/key are %ghost (flag g, no content) and that the DEB preinst/postinst implement the preserve dance. Passes against freshly built packages.
  • upgrade-container-test.sh (run by package-smoke) now writes an operator cert before the rpm -U upgrade and asserts it survives — a CI guard that also fails if anyone re-introduces a payload cert.
  • release-package-build spec v1.3.0 (C-05 + AC-22 extended).

Release impact

This lands the fix for re-spinning rc.10 (the published rc.10 carries the transition bug). After merge I'll delete + re-push the v0.2.0-rc.10 tag so the published RC carries the fix.

🤖 Generated with Claude Code

…> rc.10 upgrade

The #596 generate-if-absent fix protects rc.10->onward upgrades, but the
one-time transition FROM a release that shipped the cert in its payload
(<= rc.9) removed the operator's cert entirely: rc.9 owned
/etc/openwatch/tls/cert.pem, rc.10 does not, so the package manager
reclaimed the orphaned file AFTER rc.10's provisioning had already run and
skipped it. RPM left it missing (service can't start TLS); DEB regenerated
a demo (operator cert lost). Found via the Stage-3 gap-closure RPM/DEB
install-transition tests.

Fix:
- RPM: declare the cert/key paths %ghost so rpm tracks them with no payload
  content and does not reclaim the operator's file on the transition.
- DEB: preinst stashes an existing cert/key to .dpkg-bak on upgrade (before
  dpkg removes the orphan); postinst restores it before provisioning.
- AC-22 updated: assert %ghost (flag 'g', no content) on RPM and the
  preinst/postinst preserve dance on DEB; upgrade-container-test.sh now
  asserts an operator cert survives the rpm -U upgrade.
- release-package-build spec v1.3.0 (C-05 + AC-22 extended).

Verified in containers: genuine published rc.9 -> rc.10 preserves the
operator cert+key on both RPM (%ghost) and DEB (preinst/postinst); fresh
install still generates a demo; steady-state reinstall preserves.
@remyluslosius remyluslosius merged commit 56ca8cd into main Jun 18, 2026
21 checks passed
@remyluslosius remyluslosius deleted the fix/tls-cert-upgrade-transition branch June 18, 2026 03:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant