Fix ISO tool checks and fail promptly on installer refusal

This commit is contained in:
Codex
2026-10-13 05:35:20 +03:00
parent 43dc742e08
commit 0c02052a4e
2 changed files with 92 additions and 9 deletions
+62 -2
View File
@@ -101,6 +101,57 @@ class SmokeTests(unittest.TestCase):
with self.assertRaises(self.mod.SmokeError):
console.command('true', timeout=0.05)
def installer_console(self):
one, two = socket.socketpair()
self.addCleanup(two.close)
console = self.mod.Console(one, self.root / 'installer.log', ['test-secret'])
self.addCleanup(console.close)
return console, two
def test_captured_installer_refusal_fails_before_password_timeout(self):
console, guest = self.installer_console()
guest.sendall(b'\x1b]3008;type=command\x1b\\hydra-install: Command failed (1): '
b'findmnt --json --target /LiveOS/squashfs.img '
b'--output SOURCE,TARGET,FSTYPE,MAJ:MIN,OPTIONS: \r\n')
with self.assertRaisesRegex(self.mod.SmokeError, 'Installer.*findmnt'):
console.expect_installer(rb'Installed account password: ', 0.05, 'testtoken')
def test_installer_shell_return_without_completion_is_failure_even_zero(self):
for status in (0, 1, 127):
with self.subTest(status=status):
console, guest = self.installer_console()
guest.sendall(b'\x1etesttoken:INSTALL_EXIT:' + str(status).encode() + b'\x1f')
with self.assertRaisesRegex(self.mod.SmokeError, 'Installer.*INSTALL_EXIT'):
console.expect_installer(rb'Installation completed\. Diagnostic log: [^\r\n]+',
0.05, 'testtoken')
def test_installer_echo_cannot_fake_exit_and_complete_prompt_still_required(self):
console, guest = self.installer_console()
guest.sendall(self.mod.installer_command('testtoken').encode() + b'\r\n'
b'Installed account password: ')
self.assertEqual(console.expect_installer(rb'Installed account password: ',
0.05, 'testtoken').group(), b'Installed account password: ')
guest.sendall(b'Installation completed. Diagnostic')
with self.assertRaisesRegex(self.mod.SmokeError, 'Timed out'):
console.expect_installer(rb'Installation completed\. Diagnostic log: [^\r\n]+',
0.05, 'testtoken')
guest.sendall(b' log: /var/log/hydra-install.log\r\n')
self.assertIn(b'/var/log/hydra-install.log', console.expect_installer(
rb'Installation completed\. Diagnostic log: [^\r\n]+', 0.05, 'testtoken').group())
def test_installer_wrapper_marks_actual_shell_return_and_redacts_error(self):
console, guest = self.installer_console()
fake_sudo = self.root / 'sudo'
fake_sudo.write_text('#!/bin/sh\nprintf "hydra-install: test-secret refused\\n"\nexit 1\n')
fake_sudo.chmod(0o700)
result = subprocess.run(['/bin/sh', '-c', self.mod.installer_command('testtoken')],
env={'PATH': str(self.root)}, capture_output=True, check=True)
self.assertIn(b'\x1etesttoken:INSTALL_EXIT:1\x1f', result.stdout)
guest.sendall(result.stdout)
with self.assertRaisesRegex(self.mod.SmokeError, r'Installer.*\[REDACTED\] refused') as caught:
console.expect_installer(rb'Repeat password: ', 0.05, 'testtoken')
self.assertNotIn('test-secret', str(caught.exception))
def test_frame_real_shell_roundtrip_does_not_accept_sentinel_in_echo(self):
one, two = socket.socketpair()
self.addCleanup(one.close)
@@ -207,14 +258,19 @@ else: print('fixture tool')
dispatcher.chmod(0o755)
for command in ('id', 'findmnt', 'systemctl', 'getent', 'ip', 'nft',
'nmcli', 'sudo', 'hydra', 'hydra-install',
'qemu-system-x86_64', 'qemu-img', 'virt-viewer', 'foot', 'labwc'):
'qemu-system-x86_64', 'qemu-img', 'remote-viewer', 'foot', 'labwc'):
path = commands / command
if not path.exists():
path.symlink_to(dispatcher)
probe = self.mod.LIVE_CHECK if live else self.mod.INSTALLED_CHECK
for path in ('/etc/', '/usr/share', '/proc/cmdline', '/sys/firmware/efi', '/run/initramfs/live/LiveOS/squashfs.img'):
probe = probe.replace(path, str(root) + path)
env = dict(os.environ, PATH=str(commands) + ':' + os.environ['PATH'],
import shutil
for command in ('python3', 'sh', 'grep', 'find', 'cut', 'readlink', 'base64'):
target = shutil.which(command)
self.assertIsNotNone(target)
(commands / command).symlink_to(target) if not (commands / command).exists() else None
env = dict(os.environ, PATH=str(commands),
SMOKE_CASE=case, SMOKE_LIVE='1' if live else '0')
result = subprocess.run(['/bin/sh', '-c', self.mod.frame_command(probe, 'probecheck')],
env=env, capture_output=True, timeout=10)
@@ -500,3 +556,7 @@ else: sys.exit(1)
self.assertTrue(self.mod.no_open_logins(context))
with self.assertRaises(self.mod.SmokeError):
self.mod.capture_logout_snapshot(context)
def test_guest_tools_accept_gentoo_remote_viewer_without_virt_viewer(self):
self.assertEqual(self.probe_fixture('clean'), 0)
self.assertEqual(self.probe_fixture('clean', live=True), 0)