Skip to content

Commit e71d91e

Browse files
committed
cmk-dev-deploy: Detect site reinstall and wipe stale overlay data
After `omd rm` + `omd create`, the overlay state at /var/tmp/cmk-dev-deploy/<site>/ lingered from the previous installation. The stale upper layer was re-mounted on the fresh site, causing permission errors in config_deploy and wheel_deploy. Fix: persist the bare site root inode before mounting and compare it on the next run. When the inode changes (site was reinstalled), wipe all stale overlay data so a clean setup runs instead of a broken resume. Change-Id: I8f7467f934f77c91247227c7252bf245ed9647df
1 parent 0c512de commit e71d91e

1 file changed

Lines changed: 52 additions & 0 deletions

File tree

  • packages/cmk-dev-deploy/cmk/dev_deploy/site

packages/cmk-dev-deploy/cmk/dev_deploy/site/overlay.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
# File in the overlay base that records which version was materialized.
4747
# Used to detect version changes that require re-materialization.
4848
_VERSION_MARKER = "materialized_version"
49+
_SITE_INODE_MARKER = "site_inode"
4950

5051

5152
def _run_omd_via_sudo(site_name: str, command: str) -> None:
@@ -74,6 +75,46 @@ def _site_overlay_dir(site_root: Path) -> Path:
7475
return _OVERLAY_BASE / site_root.name
7576

7677

78+
def _wipe_stale_overlay(site_root: Path) -> bool:
79+
"""Detect and wipe stale overlay data from a previous site installation.
80+
81+
Compares the current inode of the site root directory against the stored
82+
value. When they differ, the site was reinstalled (``omd rm`` + ``omd
83+
create``), so the old upper/work/markers are stale and must be removed.
84+
85+
Returns True if stale data was wiped.
86+
"""
87+
site_overlay = _site_overlay_dir(site_root)
88+
marker = site_overlay / _SITE_INODE_MARKER
89+
if not marker.is_file():
90+
return False
91+
try:
92+
stored_ino = int(marker.read_text().strip())
93+
except (ValueError, OSError):
94+
return False
95+
current_ino = site_root.stat().st_ino
96+
if current_ino == stored_ino:
97+
return False
98+
99+
output.warn(
100+
f"Site inode changed ({stored_ino} -> {current_ino}), "
101+
"wiping stale overlay data from previous installation..."
102+
)
103+
# Remove everything except the site overlay base dir itself
104+
for child in site_overlay.iterdir():
105+
if child.is_dir():
106+
run_as_root(["rm", "-rf", str(child)])
107+
else:
108+
child.unlink(missing_ok=True)
109+
return True
110+
111+
112+
def _save_site_inode(site_root: Path, inode: int) -> None:
113+
"""Persist the site root directory's inode for reinstall detection."""
114+
marker = _site_overlay_dir(site_root) / _SITE_INODE_MARKER
115+
marker.write_text(str(inode))
116+
117+
77118
def _ensure_overlay_dirs(site_overlay: Path) -> None:
78119
"""Ensure the site overlay directory exists and is writable by the deploy user.
79120
@@ -352,6 +393,13 @@ def ensure_overlay(site_root: Path, state: SSHState) -> None:
352393
# subsequent file operations (mkdir, marker writes) work without root.
353394
_ensure_overlay_dirs(site_overlay)
354395

396+
# Detect site reinstall: if the site root inode changed, the old overlay
397+
# data is stale and must be wiped before proceeding.
398+
_wipe_stale_overlay(site_root)
399+
400+
# Capture the bare site inode before mounting (overlay changes st_ino).
401+
bare_site_inode = site_root.stat().st_ino
402+
355403
resuming = upper.exists() and any(upper.iterdir())
356404

357405
# Create directories
@@ -417,6 +465,10 @@ def ensure_overlay(site_root: Path, state: SSHState) -> None:
417465
output.info(f"Starting site {site_name}...")
418466
_run_omd_via_sudo(site_name, "start")
419467

468+
# Persist the bare site inode (captured before mount) so we can detect
469+
# reinstalls on the next run.
470+
_save_site_inode(site_root, bare_site_inode)
471+
420472
if resuming:
421473
output.info(f"Overlay resumed on {site_root} (existing changes preserved)")
422474
else:

0 commit comments

Comments
 (0)