Files
apex.ermnvldmr.com/ci/scripts/init-node/tests/test_docker_host.py
T

121 lines
5.6 KiB
Python

from contextlib import nullcontext
import hashlib
import io
import json
from pathlib import Path
from subprocess import CompletedProcess
import tempfile
import unittest
from unittest.mock import patch
from provisioning import baseline
class ManualDockerTests(unittest.TestCase):
def setUp(self):
tmp = tempfile.TemporaryDirectory()
self.addCleanup(tmp.cleanup)
self.root = Path(tmp.name).resolve()
(self.root / "etc").mkdir()
(self.root / "etc/os-release").write_text("ID=debian\nVERSION_ID=13\n")
self.commands = []
self.arch = "arm64"
self.running = False
self.data_root = "/custom/data"
self.missing_buildx = False
self.versions = {}
self.installations = []
def run_command(self, cmd, **kwargs):
self.commands.append(cmd)
if cmd == ["dpkg", "--print-architecture"]:
return CompletedProcess(cmd, 0, self.arch + "\n", "")
if cmd[-1] == "{{.DockerRootDir}}":
return CompletedProcess(cmd, 0 if self.running else 1, self.data_root + "\n", "")
if cmd[-2:] in (["version", "--short"], ["buildx", "version"]):
if self.missing_buildx and cmd[-2:] == ["buildx", "version"]:
if ["docker-buildx-plugin"] not in self.installations:
return CompletedProcess(cmd, 1, "", "plugin missing")
return CompletedProcess(cmd, 0, "installed\n", "")
raise AssertionError(cmd)
def apply(self):
def target(path):
path = Path(path)
return path if self.root in path.parents else self.root / str(path).lstrip("/")
with (patch.object(baseline, "Path", side_effect=target),
patch.object(baseline, "run", side_effect=self.run_command),
patch.object(baseline, "package_versions", return_value=self.versions),
patch.object(baseline.shutil, "which", return_value="/usr/bin/docker" if self.running else None),
patch.object(baseline, "install_missing", side_effect=self.installations.append)):
return baseline.apply_docker_policy()
def test_working_engine_keeps_local_data_root_without_writes(self):
self.running = True
self.versions = {"docker.io": "1"}
self.assertEqual(self.apply()["docker_data_root"], "/custom/data")
self.assertEqual(self.installations, [])
self.assertFalse((self.root / "etc/docker").exists())
def test_pve_refused_before_packages_or_daemon(self):
binary = self.root / "usr/bin/pveversion"
binary.parent.mkdir(parents=True)
binary.touch()
with self.assertRaisesRegex(baseline.BaselineError, "Proxmox"):
self.apply()
self.assertEqual(self.commands, [])
def test_unsupported_architecture_refused(self):
self.arch = "i386"
with self.assertRaisesRegex(baseline.BaselineError, "amd64|arm64"):
self.apply()
self.assertEqual(self.installations, [])
def test_existing_runtime_packages_not_replaced(self):
self.versions = {"containerd": "1.7"}
with self.assertRaisesRegex(baseline.BaselineError, "containerd"):
self.apply()
self.assertEqual(self.installations, [])
def test_fresh_arm64_install_verifies_the_pinned_key_and_starts_local_engine(self):
key = b"test repository signing key"
self.data_root = "/srv/docker"
def start(service):
if service == "docker":
self.running = True
with (patch.object(baseline, "service_start_guard", return_value=nullcontext()),
patch.object(baseline.urllib.request, "urlopen", return_value=io.BytesIO(key)),
patch.object(baseline, "DOCKER_KEY_SHA256", hashlib.sha256(key).hexdigest()),
patch.object(baseline, "ensure_service", side_effect=start)):
self.assertEqual(self.apply()["docker_data_root"], "/srv/docker")
source = (self.root / "etc/apt/sources.list.d/apex-docker.sources").read_text()
self.assertIn("Architectures: arm64", source)
self.assertIn("Signed-By: ", source)
self.assertEqual((self.root / "etc/apt/keyrings/apex-docker.asc").read_bytes(), key)
self.assertEqual(json.loads((self.root / "etc/docker/daemon.json").read_text())["data-root"],
"/srv/docker")
self.assertIn("docker-compose-plugin", self.installations[-1])
self.assertIn("docker-buildx-plugin", self.installations[-1])
self.assertNotIn("ufw", self.installations[-1])
def test_untrusted_signing_key_cannot_publish_apt_source_or_install_docker(self):
with (patch.object(baseline, "service_start_guard", return_value=nullcontext()),
patch.object(baseline.urllib.request, "urlopen", return_value=io.BytesIO(b"wrong key"))):
with self.assertRaisesRegex(baseline.BaselineError, "signing key"):
self.apply()
self.assertFalse((self.root / "etc/apt/sources.list.d/apex-docker.sources").exists())
self.assertFalse((self.root / "etc/docker/daemon.json").exists())
self.assertEqual(self.installations, [("ca-certificates",)])
def test_working_ce_engine_only_installs_the_missing_plugin(self):
self.running = True
self.missing_buildx = True
self.versions = {"docker-ce": "1"}
with patch.object(baseline, "service_start_guard", return_value=nullcontext()):
self.assertEqual(self.apply()["docker_data_root"], "/custom/data")
self.assertEqual(self.installations, [["docker-buildx-plugin"]])
self.assertFalse((self.root / "etc/docker").exists())