Add Docker runtime helper and explicitly labelled service inventory

This commit is contained in:
Mikei386
2026-09-28 18:48:13 +02:00
parent a0941c0549
commit 5cc732f993
15 changed files with 399 additions and 13 deletions
+50
View File
@@ -0,0 +1,50 @@
import json
from pathlib import Path
import tempfile
import unittest
from unittest.mock import patch,Mock
from docker_support import DockerSupport
from deploy.docker_helper import Manager,MANAGED_LABEL,ROLE_LABEL,PACKAGES
class DockerTests(unittest.TestCase):
def test_absent_helper_is_not_reported_as_absent_docker(self):
with patch.object(DockerSupport,'call',side_effect=OSError()):
value=DockerSupport().status();self.assertIsNone(value['installed']);self.assertFalse(value['helper_available']);self.assertEqual(value['services'],[])
def test_inventory_requires_both_exact_labels_and_exposes_no_inspect_data(self):
with tempfile.TemporaryDirectory() as d,patch('deploy.docker_helper.run',return_value=Mock(returncode=0,stdout='a'*64+'\tstudio\timage:v1\trunning\tUp 1 minute\n')) as run:
rows=Manager(d).inventory();args=run.call_args.args[0]
self.assertIn('label='+MANAGED_LABEL,args);self.assertIn('label='+ROLE_LABEL,args)
self.assertEqual(set(rows[0]),{'id','name','image','state','status'})
self.assertNotIn('inspect',args)
def test_arbitrary_helper_actions_are_rejected(self):
with tempfile.TemporaryDirectory() as d:
manager=Manager(d)
for data in ({'action':'exec','command':'id'},{'action':'stop'},[],{'action':'install','args':['--privileged']}):
with self.assertRaises(ValueError):manager.dispatch(data)
def test_existing_docker_is_never_reinstalled(self):
with tempfile.TemporaryDirectory() as d,patch('deploy.docker_helper.release',return_value={'ID':'debian','VERSION_ID':'13'}),patch('deploy.docker_helper.Path.exists',return_value=True),patch('deploy.docker_helper.threading.Thread') as thread:
manager=Manager.__new__(Manager);manager.allow_install=True;manager.lock=__import__('threading').RLock();manager.job=None
with self.assertRaises(ValueError):manager.install()
thread.assert_not_called()
def test_missing_authorization_prevents_install(self):
with tempfile.TemporaryDirectory() as d,patch('deploy.docker_helper.release',return_value={'ID':'debian','VERSION_ID':'13'}),patch('deploy.docker_helper.Path.exists',return_value=False):
manager=Manager(d);self.assertFalse(manager.preflight()[0])
with self.assertRaises(ValueError):manager.install()
def test_install_uses_fixed_official_packages_and_checks_compose(self):
with tempfile.TemporaryDirectory() as d:
root=Path(d);(root/'etc/apt/sources.list.d').mkdir(parents=True)
manager=Manager(root/'state',True);manager.job={'state':'running'};commands=[]
def path(value):return root/str(value).lstrip('/')
def checked(args):
commands.append(args)
if args[0]=='/usr/bin/curl':Path(args[-1]).touch()
with patch('deploy.docker_helper.release',return_value={'ID':'debian','VERSION_ID':'13'}),patch('deploy.docker_helper.run',return_value=Mock(stdout='amd64\n')),patch('deploy.docker_helper.Path',side_effect=path),patch.object(manager,'_checked',side_effect=checked):manager._install()
self.assertEqual(manager.job['state'],'complete')
self.assertIn(['/usr/bin/apt-get','install','-y','--no-remove',*PACKAGES],commands)
self.assertIn(['/usr/bin/docker','compose','version','--short'],commands)
self.assertFalse(any('restart' in c or 'reboot' in c for c in commands))
def test_package_failure_does_not_claim_success_or_reboot(self):
with tempfile.TemporaryDirectory() as d:
manager=Manager(d,True);manager.job={'state':'running'}
with patch('deploy.docker_helper.release',return_value={'VERSION_ID':'13'}),patch('deploy.docker_helper.run',return_value=Mock(stdout='amd64')),patch.object(manager,'_checked',side_effect=ValueError('failed')):manager._install()
self.assertEqual(manager.job['state'],'failed')