mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-09 20:26:33 +00:00
The nested dockerd writes /mnt/docker as root, so shutil.rmtree from the runner user silently removed nothing and the previous distro's containers survived into the next distro run. They restarted under unless-stopped against a fresh container rootfs, failed with exit 127, and sys-ctl-rpr-container-soft exited 2 because their compose working_dir no longer existed, which failed the guide deploy on the second distro. Escalate the wipe the same way dedicated.sh does and hard-fail when the root survives, so a silent no-op can no longer leak state across distros. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
49 lines
1.8 KiB
Python
49 lines
1.8 KiB
Python
"""Pins the inner-Docker-root wipe: it escalates, and a surviving root is fatal."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import tempfile
|
|
import unittest
|
|
from pathlib import Path
|
|
from unittest.mock import MagicMock, patch
|
|
|
|
from cli.administration.deploy.development.down import _wipe_docker_root
|
|
|
|
|
|
class TestWipeDockerRoot(unittest.TestCase):
|
|
@patch("cli.administration.deploy.development.down.subprocess.run", autospec=True)
|
|
def test_the_wipe_escalates(self, run_mock: MagicMock) -> None:
|
|
with tempfile.TemporaryDirectory() as tmp:
|
|
docker_root = Path(tmp) / "docker"
|
|
docker_root.mkdir()
|
|
|
|
_wipe_docker_root(docker_root)
|
|
|
|
commands = [call.args[0] for call in run_mock.call_args_list]
|
|
self.assertEqual(commands[0], ["sudo", "rm", "-rf", str(docker_root)])
|
|
self.assertTrue(all(cmd[0] == "sudo" for cmd in commands))
|
|
|
|
@patch("cli.administration.deploy.development.down.subprocess.run", autospec=True)
|
|
def test_a_surviving_docker_root_is_a_hard_error(self, run_mock: MagicMock) -> None:
|
|
with tempfile.TemporaryDirectory() as tmp:
|
|
docker_root = Path(tmp) / "docker"
|
|
docker_root.mkdir()
|
|
(docker_root / "containers").mkdir()
|
|
|
|
with self.assertRaises(RuntimeError) as ctx:
|
|
_wipe_docker_root(docker_root)
|
|
|
|
self.assertIn("containers", str(ctx.exception))
|
|
self.assertTrue(run_mock.called)
|
|
|
|
@patch("cli.administration.deploy.development.down.subprocess.run", autospec=True)
|
|
def test_a_missing_docker_root_is_not_wiped(self, run_mock: MagicMock) -> None:
|
|
with tempfile.TemporaryDirectory() as tmp:
|
|
_wipe_docker_root(Path(tmp) / "absent")
|
|
|
|
run_mock.assert_not_called()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|