feat: Phase 5 — remove legacy service blocks, one-shot container cleanup
Unit Tests / test (push) Successful in 11m20s
Unit Tests / test (push) Successful in 11m20s
Email, calendar, files, webmail (rainloop), and the file manager (filegator) are removed from the main docker-compose stack. They install as independent per-service compose projects via ServiceComposer. On startup, _cleanup_legacy_builtin_containers() stops and removes any of the 5 legacy containers still running from the old main stack (guarded by a one-shot sentinel in _meta.legacy_builtins_cleaned so it never runs twice). Per-service installs (com.docker.compose.project != 'pic') are left untouched. Changes: - docker-compose.yml: remove mail, radicale, webdav, rainloop, filegator blocks; fix dhcp + ntp to profiles: ["core","full"] so they start with --profile core - Makefile: replace all --profile full with --profile core (6 occurrences); remove mailserver.env conditional from update: target - api/legacy_cleanup.py: new module with cleanup_legacy_builtin_containers() - api/app.py: import and call cleanup at startup before reapply_on_startup() - tests/test_legacy_cleanup.py: 7 tests covering sentinel, absent containers, per-service project skip, main-stack removal, exception safety Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
"""One-shot cleanup of legacy builtin containers from the old main compose stack."""
|
||||
import logging
|
||||
import subprocess
|
||||
|
||||
logger = logging.getLogger('picell')
|
||||
|
||||
_LEGACY_BUILTIN_CONTAINERS = [
|
||||
'cell-mail', 'cell-rainloop', 'cell-radicale', 'cell-webdav', 'cell-filegator',
|
||||
]
|
||||
|
||||
|
||||
def cleanup_legacy_builtin_containers(config_manager) -> None:
|
||||
"""Remove legacy containers whose compose project is 'pic' (main stack).
|
||||
|
||||
Idempotent — guarded by _meta.legacy_builtins_cleaned in cell_config.json.
|
||||
Containers from per-service installs (project != 'pic') are left untouched.
|
||||
"""
|
||||
try:
|
||||
already_done = config_manager.configs.get('_meta', {}).get('legacy_builtins_cleaned', False)
|
||||
if already_done:
|
||||
return
|
||||
except Exception:
|
||||
return
|
||||
|
||||
removed = []
|
||||
for cname in _LEGACY_BUILTIN_CONTAINERS:
|
||||
try:
|
||||
inspect = subprocess.run(
|
||||
['docker', 'inspect', cname,
|
||||
'--format', '{{index .Config.Labels "com.docker.compose.project"}}'],
|
||||
capture_output=True, text=True, timeout=10,
|
||||
)
|
||||
if inspect.returncode != 0:
|
||||
continue
|
||||
project = inspect.stdout.strip()
|
||||
if project != 'pic':
|
||||
continue
|
||||
subprocess.run(['docker', 'stop', cname], capture_output=True, timeout=30)
|
||||
subprocess.run(['docker', 'rm', cname], capture_output=True, timeout=30)
|
||||
removed.append(cname)
|
||||
except Exception as exc:
|
||||
logger.warning('cleanup_legacy_builtin_containers: %s: %s', cname, exc)
|
||||
|
||||
try:
|
||||
meta = dict(config_manager.configs.get('_meta', {}))
|
||||
meta['legacy_builtins_cleaned'] = True
|
||||
config_manager.configs['_meta'] = meta
|
||||
config_manager._save_all_configs()
|
||||
except Exception as exc:
|
||||
logger.warning('cleanup_legacy_builtin_containers: failed to set sentinel: %s', exc)
|
||||
|
||||
if removed:
|
||||
logger.info('Removed legacy builtin containers: %s', ', '.join(removed))
|
||||
Reference in New Issue
Block a user