test: make boot mode work in unprivileged containers, take TEST_MKOSI_ARGS (#43531)
The final enablement pieces needed for coco tests in systemd CI. Runners will be incus containers, these two commits enable running coco tests with mkosi boot (where image is a directory), then start a confidential guest with vmspawn as part of the test.
This commit is contained in:
@@ -120,6 +120,15 @@ rerun the test.
|
||||
`TEST_NO_KVM=1`: Disable qemu KVM auto-detection (may be necessary when you're
|
||||
trying to run the *vanilla* qemu and have both qemu and qemu-kvm installed)
|
||||
|
||||
`TEST_MKOSI_ARGS=options`: Extra options (split like a shell command line)
|
||||
passed to the `mkosi` invocation that launches the test image, without
|
||||
affecting the image build. Only the `--option=value` syntax is accepted. For example,
|
||||
`TEST_MKOSI_ARGS="--format=directory --output-dir=build/mkosi.output.dir"`
|
||||
boots the test container from a directory format output (which has to be built
|
||||
beforehand, into a separate output directory), allowing boot mode tests to run
|
||||
in environments that can't dissect disk images, such as unprivileged
|
||||
containers, where loop devices and udev are not available.
|
||||
|
||||
`TEST_MATCH_SUBTEST=subtest`: If the test makes use of `run_subtests` use this
|
||||
variable to provide a POSIX extended regex to run only subtests matching the
|
||||
expression.
|
||||
|
||||
@@ -365,6 +365,15 @@ def process_coverage(args: argparse.Namespace, summary: Summary, name: str, jour
|
||||
print(f'Wrote coverage report for {name} to {output}', file=sys.stderr)
|
||||
|
||||
|
||||
def in_userns() -> bool:
|
||||
# The initial user namespace has a well-known inode number (USER_NS_INIT_INO, linux/nsfs.h).
|
||||
# Without kernel support for user namespaces, ours can only be the initial one.
|
||||
try:
|
||||
return os.stat('/proc/self/ns/user').st_ino != 0xEFFFFFFD
|
||||
except OSError:
|
||||
return False
|
||||
|
||||
|
||||
def coco_host_type() -> Optional[str]:
|
||||
try:
|
||||
if Path('/sys/module/kvm_intel/parameters/tdx').read_text().strip() == 'Y':
|
||||
@@ -661,6 +670,12 @@ def main() -> None:
|
||||
'''
|
||||
)
|
||||
|
||||
# Extra mkosi options for this invocation only. Each has to use the '--option=value' syntax.
|
||||
test_mkosi_args = shlex.split(os.getenv('TEST_MKOSI_ARGS', ''))
|
||||
for arg in test_mkosi_args:
|
||||
if not re.fullmatch('--[^=]+=.*', arg):
|
||||
sys.exit(f"TEST_MKOSI_ARGS must contain only '--option=value' mkosi options, got: {arg}")
|
||||
|
||||
cmd = [
|
||||
args.mkosi,
|
||||
'--directory', os.fspath(args.mkosi_dir),
|
||||
@@ -704,9 +719,29 @@ def main() -> None:
|
||||
),
|
||||
'--credential', f"journal.storage={'persistent' if sys.stdin.isatty() else args.storage}",
|
||||
*(['--runtime-build-sources=no', '--register=no'] if not sys.stdin.isatty() else []),
|
||||
*test_mkosi_args,
|
||||
'vm' if vm else 'boot',
|
||||
*(
|
||||
['--', '--capability=CAP_BPF', f'--suppress-sync={"yes" if args.suppress_sync else "no"}', *vm_images_args, *coco_boot_args]
|
||||
[
|
||||
'--',
|
||||
'--capability=CAP_BPF',
|
||||
f'--suppress-sync={"yes" if args.suppress_sync else "no"}',
|
||||
# In a non-initial user namespace the kernel only allows mounting a fresh proc or
|
||||
# sysfs if the mount namespace already contains a fully visible mount of the same
|
||||
# filesystem type (mount_too_revealing()), which nspawn's pivoted root doesn't.
|
||||
# Satisfy the check with read-only binds, but only when actually confined, as
|
||||
# they expose the outer proc and sysfs to the container. Bind non-recursively:
|
||||
# carried-along submounts (e.g. lxcfs overmounts of container runtimes) would
|
||||
# spoil full visibility wherever they end up locked, and --bind-ro wouldn't make
|
||||
# them read-only either.
|
||||
*(
|
||||
['--bind-ro=/proc:/work/proc:norbind', '--bind-ro=/sys:/work/sys:norbind']
|
||||
if in_userns()
|
||||
else []
|
||||
),
|
||||
*vm_images_args,
|
||||
*coco_boot_args,
|
||||
]
|
||||
if not vm
|
||||
else []
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user