Add read-only laptop doctor and trusted image recovery entrypoints
This commit is contained in:
@@ -35,6 +35,66 @@ class ImageTests(unittest.TestCase):
|
||||
self.file('boot/vmlinuz-' + version, 'kernel')
|
||||
return version
|
||||
|
||||
def test_installs_independent_updater_and_base_recovery_assets(self):
|
||||
self.kernel()
|
||||
source = Path(__file__).resolve().parents[1]
|
||||
image.configure_rootfs(self.root, source)
|
||||
for relative, asset, mode in (
|
||||
('usr/lib/hydra-update/engine.py', 'hydra/update_engine.py', 0o644),
|
||||
('usr/bin/hydra-update', 'bin/hydra-update', 0o755),
|
||||
('usr/bin/hydra-update-recover', 'bin/hydra-update-recover', 0o755),
|
||||
('usr/lib/hydra/bin/hydra-system', 'bin/hydra-system', 0o755),
|
||||
('etc/hydra/update.pub', 'image/rootfs/etc/hydra/update.pub', 0o644),
|
||||
):
|
||||
with self.subTest(relative=relative):
|
||||
path = self.root / relative
|
||||
self.assertTrue(path.is_file(), relative)
|
||||
self.assertEqual(path.read_bytes(), (source / asset).read_bytes())
|
||||
self.assertEqual(path.stat().st_mode & 0o777, mode)
|
||||
wrapper = self.root / 'usr/bin/hydra-system'
|
||||
self.assertTrue(wrapper.is_file(), 'base recovery launcher is missing')
|
||||
self.assertEqual(wrapper.stat().st_mode & 0o777, 0o755)
|
||||
self.assertEqual(wrapper.read_text(),
|
||||
'#!/usr/bin/python3 -I\nimport sys\nsys.path.insert(0, "/usr/lib/hydra")\n'
|
||||
'from hydra.system_recovery import main\nraise SystemExit(main())\n')
|
||||
self.assertEqual((self.root / 'usr/lib/hydra/hydra/doctor.py').read_bytes(),
|
||||
(source / 'hydra/doctor.py').read_bytes())
|
||||
|
||||
def test_root_assembly_sets_trusted_asset_ownership(self):
|
||||
from unittest.mock import patch
|
||||
self.kernel()
|
||||
with patch('hydra.image.os.geteuid', return_value=0), patch('hydra.image.os.chown') as chown:
|
||||
image.configure_rootfs(self.root, Path(__file__).resolve().parents[1])
|
||||
for relative in ('usr/lib/hydra-update/engine.py', 'usr/lib/hydra-update',
|
||||
'usr/bin/hydra-update', 'usr/bin/hydra-update-recover', 'etc/hydra/update.pub'):
|
||||
chown.assert_any_call(self.root / relative, 0, 0)
|
||||
|
||||
def test_missing_trusted_asset_refuses_configuration_before_mutation(self):
|
||||
import shutil
|
||||
source = Path(__file__).resolve().parents[1]
|
||||
fixture = Path(self.tmp.name) / 'source'
|
||||
fixture.mkdir()
|
||||
for directory in ('bin', 'hydra', 'image'):
|
||||
shutil.copytree(source / directory, fixture / directory,
|
||||
ignore=shutil.ignore_patterns('__pycache__'))
|
||||
for asset in ('bin/hydra-update', 'bin/hydra-update-recover', 'hydra/update_engine.py',
|
||||
'bin/hydra-system', 'hydra/system_recovery.py', 'image/rootfs/etc/hydra/update.pub'):
|
||||
with self.subTest(asset=asset):
|
||||
self.root = Path(self.tmp.name) / ('root-' + asset.replace('/', '-'))
|
||||
self.root.mkdir()
|
||||
self.kernel('6.18.54-gentoo-dist-bin')
|
||||
original = self.file('etc/machine-id', 'preserved-builder-id')
|
||||
missing = fixture / asset
|
||||
saved = missing.read_bytes()
|
||||
missing.unlink()
|
||||
try:
|
||||
with self.assertRaisesRegex(image.ImageError, 'missing'):
|
||||
image.configure_rootfs(self.root, fixture)
|
||||
self.assertEqual(original.read_text(), 'preserved-builder-id')
|
||||
self.assertFalse((self.root / 'usr').exists())
|
||||
finally:
|
||||
missing.write_bytes(saved)
|
||||
|
||||
def test_kernel_from_payload_not_running_host(self):
|
||||
self.kernel()
|
||||
self.assertEqual(image.kernel_version(self.root), '6.12.58-gentoo-dist')
|
||||
|
||||
Reference in New Issue
Block a user