mirror of
https://github.com/systemd/systemd.git
synced 2025-03-22 06:50:18 +03:00
mkosi: Enable History= option (#36500)
This option makes mkosi "remember" all the CLI options specified on the command line when building an image. This means they don't need to be specified again when booting the image afterwards or doing any other operation on the image with "mkosi xxx". As an example of how this is useful, currently, when running "mkosi -d opensuse -f" to build an opensuse image and then running "mkosi sandbox -- meson test -C build TEST-86-MULTI-UKI-PROFILE", running the test will try to add virtiofs mounts of the fedora~rawhide build directory on my machine instead of the opensuse one. With the History= option enabled, it will use the opensuse tumbleweed directory as expected.
This commit is contained in:
commit
54b67a669f
.github/workflows
mkosi.conftest
TEST-53-ISSUE-16347
TEST-64-UDEV-STORAGE
btrfs_basic.configureiscsi_lvm.configurelong_sysfs_path.configurelvm_basic.configuremdadm_basic.configuremdadm_lvm.configuremeson.buildmultipath_basic_failover.configurenvme_basic.configurenvme_subsystem.configuresimultaneous_events.configurevirtio_scsi_basic.configurevirtio_scsi_identically_named_partitions.configure
integration-test-wrapper.pymeson.build
2
.github/workflows/coverage.yml
vendored
2
.github/workflows/coverage.yml
vendored
@ -25,7 +25,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
|
||||
- uses: systemd/mkosi@13eb5b68bd5fb234dd0da3b242d80954faf91b95
|
||||
- uses: systemd/mkosi@87c540a5cf9fe24bb79fa946b9617d10e7f02b7e
|
||||
|
||||
# Freeing up disk space with rm -rf can take multiple minutes. Since we don't need the extra free space
|
||||
# immediately, we remove the files in the background. However, we first move them to a different location
|
||||
|
2
.github/workflows/mkosi.yml
vendored
2
.github/workflows/mkosi.yml
vendored
@ -120,7 +120,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
|
||||
- uses: systemd/mkosi@13eb5b68bd5fb234dd0da3b242d80954faf91b95
|
||||
- uses: systemd/mkosi@87c540a5cf9fe24bb79fa946b9617d10e7f02b7e
|
||||
|
||||
# Freeing up disk space with rm -rf can take multiple minutes. Since we don't need the extra free space
|
||||
# immediately, we remove the files in the background. However, we first move them to a different location
|
||||
|
@ -30,6 +30,7 @@ RepartDirectories=mkosi.repart
|
||||
OutputDirectory=build/mkosi.output
|
||||
|
||||
[Build]
|
||||
History=yes
|
||||
ToolsTree=default
|
||||
BuildDirectory=build/mkosi.builddir
|
||||
CacheDirectory=build/mkosi.cache
|
||||
|
@ -3,9 +3,7 @@
|
||||
integration_tests += [
|
||||
integration_test_template + {
|
||||
'name' : fs.name(meson.current_source_dir()),
|
||||
'mkosi-args' : integration_test_template['mkosi-args'] + [
|
||||
'--configure-script', meson.current_source_dir() / 'mkosi.configure',
|
||||
],
|
||||
'rtc' : true,
|
||||
'vm' : true,
|
||||
},
|
||||
]
|
||||
|
@ -1,6 +0,0 @@
|
||||
#!/bin/bash
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
set -e
|
||||
|
||||
RTC="$(date -u +%Y-%m-%dT%H:%M:%S -d "+3 days")"
|
||||
jq ".QemuArgs += [\"-rtc\", \"base=$RTC\"]"
|
@ -1,26 +0,0 @@
|
||||
#!/usr/bin/python3
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
import json
|
||||
import sys
|
||||
|
||||
|
||||
config = json.load(sys.stdin)
|
||||
|
||||
config["QemuArgs"] += ["-device", "virtio-scsi-pci,id=scsi0"]
|
||||
|
||||
for i in range(4):
|
||||
id = f"drivebtrfsbasic{i}"
|
||||
config["Drives"] += [
|
||||
{
|
||||
"Id": id,
|
||||
"Size": "350M" if i == 0 else "128M",
|
||||
"Options": "cache=unsafe",
|
||||
}
|
||||
]
|
||||
config["QemuArgs"] += [
|
||||
"-device",
|
||||
f"scsi-hd,drive={id},vendor=systemd,product=foobar,serial=deadbeefbtrfs{i}",
|
||||
]
|
||||
|
||||
json.dump(config, sys.stdout)
|
@ -1,26 +0,0 @@
|
||||
#!/usr/bin/python3
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
import json
|
||||
import sys
|
||||
|
||||
|
||||
config = json.load(sys.stdin)
|
||||
|
||||
config["QemuArgs"] += ["-device", "virtio-scsi-pci,id=scsi0"]
|
||||
|
||||
for i in range(4):
|
||||
id = f"driveiscsibasic{i}"
|
||||
config["Drives"] += [
|
||||
{
|
||||
"Id": id,
|
||||
"Size": "150M" if i == 0 else "70M",
|
||||
"Options": "cache=unsafe",
|
||||
}
|
||||
]
|
||||
config["QemuArgs"] += [
|
||||
"-device",
|
||||
f"scsi-hd,drive={id},vendor=systemd,product=foobar,serial=deadbeefiscsi{i}",
|
||||
]
|
||||
|
||||
json.dump(config, sys.stdout)
|
@ -1,31 +0,0 @@
|
||||
#!/usr/bin/python3
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
import json
|
||||
import sys
|
||||
|
||||
|
||||
config = json.load(sys.stdin)
|
||||
|
||||
config["Drives"] += [
|
||||
{
|
||||
"Id": "drive0",
|
||||
"Size": "64M",
|
||||
"Options": "cache=unsafe",
|
||||
}
|
||||
]
|
||||
config["QemuArgs"] += ["-device", "pci-bridge,id=pci_bridge0,chassis_nr=64"]
|
||||
|
||||
# Create 25 additional PCI bridges, each one connected to the previous one
|
||||
# (basically a really long extension cable), and attach a virtio drive to
|
||||
# the last one. This should force udev into attempting to create a device
|
||||
# unit with a _really_ long name.
|
||||
for bridge in range(1, 26):
|
||||
config["QemuArgs"] += [
|
||||
"-device",
|
||||
f"pci-bridge,id=pci_bridge{bridge},bus=pci_bridge{bridge - 1},chassis_nr={64 + bridge},addr=1",
|
||||
]
|
||||
|
||||
config["QemuArgs"] += ["-device", f"virtio-blk-pci,drive=drive0,bus=pci_bridge25,addr=1,serial=long-sysfs-path"]
|
||||
|
||||
json.dump(config, sys.stdout)
|
@ -1,25 +0,0 @@
|
||||
#!/usr/bin/python3
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
import json
|
||||
import sys
|
||||
|
||||
|
||||
config = json.load(sys.stdin)
|
||||
|
||||
config["QemuArgs"] += ["-device", "virtio-scsi-pci,id=scsi0"]
|
||||
|
||||
for i in range(4):
|
||||
id = f"drivelvmbasic{i}"
|
||||
config["Drives"] += [
|
||||
{
|
||||
"Id": id,
|
||||
"Size": "32M",
|
||||
"Options": "cache=unsafe",
|
||||
}
|
||||
]
|
||||
config["QemuArgs"] += [
|
||||
"-device", f"scsi-hd,drive={id},vendor=systemd,product=foobar,serial=deadbeeflvm{i}",
|
||||
]
|
||||
|
||||
json.dump(config, sys.stdout)
|
@ -1,25 +0,0 @@
|
||||
#!/usr/bin/python3
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
import json
|
||||
import sys
|
||||
|
||||
|
||||
config = json.load(sys.stdin)
|
||||
|
||||
config["QemuArgs"] += ["-device", "virtio-scsi-pci,id=scsi0"]
|
||||
|
||||
for i in range(5):
|
||||
id = f"drivemdadmbasic{i}"
|
||||
config["Drives"] += [
|
||||
{
|
||||
"Id": id,
|
||||
"Size": "64M",
|
||||
"Options": "cache=unsafe",
|
||||
}
|
||||
]
|
||||
config["QemuArgs"] += [
|
||||
"-device", f"scsi-hd,drive={id},vendor=systemd,product=foobar,serial=deadbeefmdadm{i}",
|
||||
]
|
||||
|
||||
json.dump(config, sys.stdout)
|
@ -1,25 +0,0 @@
|
||||
#!/usr/bin/python3
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
import json
|
||||
import sys
|
||||
|
||||
|
||||
config = json.load(sys.stdin)
|
||||
|
||||
config["QemuArgs"] += ["-device", "virtio-scsi-pci,id=scsi0"]
|
||||
|
||||
for i in range(5):
|
||||
id = f"drivemdadmlvm{i}"
|
||||
config["Drives"] += [
|
||||
{
|
||||
"Id": id,
|
||||
"Size": "64M",
|
||||
"Options": "cache=unsafe",
|
||||
}
|
||||
]
|
||||
config["QemuArgs"] += [
|
||||
"-device", f"scsi-hd,drive={id},vendor=systemd,product=foobar,serial=deadbeefmdadmlvm{i}",
|
||||
]
|
||||
|
||||
json.dump(config, sys.stdout)
|
@ -11,31 +11,253 @@ unit = configure_file(
|
||||
},
|
||||
)
|
||||
|
||||
foreach testcase : [
|
||||
'btrfs_basic',
|
||||
'iscsi_lvm',
|
||||
'long_sysfs_path',
|
||||
'lvm_basic',
|
||||
'mdadm_basic',
|
||||
'mdadm_lvm',
|
||||
'multipath_basic_failover',
|
||||
'nvme_basic',
|
||||
'nvme_subsystem',
|
||||
'simultaneous_events',
|
||||
'virtio_scsi_basic',
|
||||
'virtio_scsi_identically_named_partitions',
|
||||
]
|
||||
udev_storage_tests = []
|
||||
|
||||
cmdline = []
|
||||
qemu_args = ['-device', 'virtio-scsi-pci,id=scsi0']
|
||||
|
||||
foreach i : range(4)
|
||||
id = f'drivebtrfsbasic@i@'
|
||||
size = i == 0 ? '350M' : '128M'
|
||||
cmdline += [f'--drive=@id@:@size@::cache=unsafe']
|
||||
qemu_args += ['-device', f'scsi-hd,drive=@id@,vendor=systemd,product=foobar,serial=deadbeefbtrfs@i@']
|
||||
endforeach
|
||||
|
||||
udev_storage_tests += {
|
||||
'name' : 'btrfs_basic',
|
||||
'cmdline' : cmdline,
|
||||
'qemu-args' : qemu_args,
|
||||
}
|
||||
|
||||
cmdline = []
|
||||
qemu_args = ['-device', 'virtio-scsi-pci,id=scsi0']
|
||||
|
||||
foreach i : range(4)
|
||||
id = f'driveiscsibasic@i@'
|
||||
size = i == 0 ? '150M' : '70M'
|
||||
cmdline += [f'--drive=@id@:@size@::cache=unsafe']
|
||||
qemu_args += ['-device', f'scsi-hd,drive=@id@,vendor=systemd,product=foobar,serial=deadbeefiscsi@i@']
|
||||
endforeach
|
||||
|
||||
udev_storage_tests += {
|
||||
'name' : 'iscsi_lvm',
|
||||
'cmdline' : cmdline,
|
||||
'qemu-args' : qemu_args,
|
||||
}
|
||||
|
||||
cmdline = ['--drive=drive0:64M::cache=unsafe']
|
||||
qemu_args = ['-device', 'pci-bridge,id=pci_bridge0,chassis_nr=64']
|
||||
|
||||
# Create 25 additional PCI bridges, each one connected to the previous one
|
||||
# (basically a really long extension cable), and attach a virtio drive to
|
||||
# the last one. This should force udev into attempting to create a device
|
||||
# unit with a _really_ long name.
|
||||
foreach bridge : range(1, 26)
|
||||
bus = bridge - 1
|
||||
chassis = 64 + bridge
|
||||
qemu_args += ['-device', f'pci-bridge,id=pci_bridge@bridge@,bus=pci_bridge@bus@,chassis_nr=@chassis@,addr=1']
|
||||
endforeach
|
||||
|
||||
qemu_args += ['-device', 'virtio-blk-pci,drive=drive0,bus=pci_bridge25,addr=1,serial=long-sysfs-path']
|
||||
|
||||
udev_storage_tests += {
|
||||
'name' : 'long_sysfs_path',
|
||||
'cmdline' : cmdline,
|
||||
'qemu-args' : qemu_args,
|
||||
}
|
||||
|
||||
cmdline = []
|
||||
qemu_args = ['-device', 'virtio-scsi-pci,id=scsi0']
|
||||
|
||||
foreach i : range(4)
|
||||
id = f'drivelvmbasic@i@'
|
||||
cmdline += [f'--drive=@id@:32M::cache=unsafe']
|
||||
qemu_args += ['-device', f'scsi-hd,drive=@id@,vendor=systemd,product=foobar,serial=deadbeeflvm@i@']
|
||||
endforeach
|
||||
|
||||
udev_storage_tests += {
|
||||
'name' : 'lvm_basic',
|
||||
'cmdline' : cmdline,
|
||||
'qemu-args' : qemu_args,
|
||||
}
|
||||
|
||||
cmdline = []
|
||||
qemu_args = ['-device', 'virtio-scsi-pci,id=scsi0']
|
||||
|
||||
foreach i : range(5)
|
||||
id = f'drivemdadmbasic@i@'
|
||||
cmdline += [f'--drive=@id@:64M::cache=unsafe']
|
||||
qemu_args += ['-device', f'scsi-hd,drive=@id@,vendor=systemd,product=foobar,serial=deadbeefmdadm@i@']
|
||||
endforeach
|
||||
|
||||
udev_storage_tests += {
|
||||
'name' : 'mdadm_basic',
|
||||
'cmdline' : cmdline,
|
||||
'qemu-args' : qemu_args,
|
||||
}
|
||||
|
||||
cmdline = []
|
||||
qemu_args = ['-device', 'virtio-scsi-pci,id=scsi0']
|
||||
|
||||
foreach i : range(5)
|
||||
id = f'drivemdadmlvm@i@'
|
||||
cmdline += [f'--drive=@id@:64M::cache=unsafe']
|
||||
qemu_args += ['-device', f'scsi-hd,drive=@id@,vendor=systemd,product=foobar,serial=deadbeefmdadmlvm@i@']
|
||||
endforeach
|
||||
|
||||
udev_storage_tests += {
|
||||
'name' : 'mdadm_lvm',
|
||||
'cmdline' : cmdline,
|
||||
'qemu-args' : qemu_args,
|
||||
}
|
||||
|
||||
cmdline = []
|
||||
qemu_args = []
|
||||
|
||||
# Add 16 multipath devices, each backed by 4 paths
|
||||
foreach ndisk : range(16)
|
||||
ndiskfmt = ndisk >= 10 ? f'00@ndisk@' : f'000@ndisk@'
|
||||
wwn = f'0xDEADDEADBEEF@ndiskfmt@'
|
||||
size = ndisk == 0 ? '16M' : '1M'
|
||||
|
||||
foreach nback : range(4)
|
||||
id = f'drive@ndisk@x@nback@'
|
||||
cmdline += [f'--drive=@id@:@size@::cache=unsafe:@ndisk@']
|
||||
qemu_args += ['-device', f'scsi-hd,drive=@id@,serial=MPIO@ndisk@,wwn=@wwn@']
|
||||
endforeach
|
||||
endforeach
|
||||
|
||||
udev_storage_tests += {
|
||||
'name' : 'multipath_basic_failover',
|
||||
'cmdline' : cmdline,
|
||||
'qemu-args' : qemu_args,
|
||||
}
|
||||
|
||||
cmdline = []
|
||||
qemu_args = []
|
||||
|
||||
foreach i : range(10)
|
||||
id = f'drivesimultaneousevents@i@'
|
||||
cmdline += [f'--drive=@id@:128M::cache=unsafe']
|
||||
qemu_args += ['-device', f'scsi-hd,drive=@id@,serial=deadbeeftest@i@']
|
||||
endforeach
|
||||
|
||||
udev_storage_tests += {
|
||||
'name' : 'simultaneous_events',
|
||||
'cmdline' : cmdline,
|
||||
'qemu-args' : qemu_args,
|
||||
}
|
||||
|
||||
cmdline = []
|
||||
qemu_args = []
|
||||
|
||||
foreach i : range(4)
|
||||
qemu_args += ['-device', f'virtio-scsi-pci,id=scsi@i@']
|
||||
endforeach
|
||||
|
||||
foreach i : range(128)
|
||||
id = f'drive@i@'
|
||||
cmdline += [f'--drive=@id@:1M::cache=unsafe']
|
||||
div = i / 32
|
||||
mod = i % 32
|
||||
qemu_args += ['-device', f'scsi-hd,drive=@id@,bus=scsi@div@.0,channel=0,scsi-id=@mod@,lun=0']
|
||||
endforeach
|
||||
|
||||
udev_storage_tests += {
|
||||
'name' : 'virtio_scsi_basic',
|
||||
'cmdline' : cmdline,
|
||||
'qemu-args' : qemu_args,
|
||||
}
|
||||
|
||||
qemu = find_program('qemu-system-@0@'.format(host_machine.cpu_family()), 'qemu-kvm', dirs : ['/usr/libexec'], native : true, required : false)
|
||||
if qemu.found()
|
||||
devices = run_command(qemu, '-device', 'help', check : true).stdout().strip()
|
||||
if devices.contains('name "nvme"')
|
||||
cmdline = []
|
||||
qemu_args = []
|
||||
|
||||
foreach i : range(20)
|
||||
cmdline += [f'--drive=nvme@i@:1M::cache=unsafe']
|
||||
endforeach
|
||||
|
||||
foreach i : range(5)
|
||||
qemu_args += ['-device', f'nvme,drive=nvme@i@,serial=deadbeef@i@,max_ioqpairs=8']
|
||||
endforeach
|
||||
|
||||
foreach i : range(5, 10)
|
||||
qemu_args += ['-device', f'"nvme,drive=nvme@i@,serial= deadbeef @i@ ,max_ioqpairs=8"']
|
||||
endforeach
|
||||
|
||||
foreach i : range(10, 15)
|
||||
qemu_args += ['-device', f'"nvme,drive=nvme@i@,serial= dead/beef/@i@ ,max_ioqpairs=8"']
|
||||
endforeach
|
||||
|
||||
foreach i : range(15, 20)
|
||||
qemu_args += ['-device', f'"nvme,drive=nvme@i@,serial=dead/../../beef/@i@,max_ioqpairs=8"']
|
||||
endforeach
|
||||
|
||||
udev_storage_tests += {
|
||||
'name' : 'nvme_basic',
|
||||
'cmdline' : cmdline,
|
||||
'qemu-args' : qemu_args,
|
||||
}
|
||||
|
||||
cmdline = []
|
||||
|
||||
foreach id : ['nvme0', 'nvme1']
|
||||
cmdline += [f'--drive=@id@:1M::cache=unsafe']
|
||||
endforeach
|
||||
|
||||
qemu_args = [
|
||||
# Create an NVM Subsystem Device
|
||||
'-device', 'nvme-subsys,id=nvme-subsys-64,nqn=subsys64',
|
||||
# Attach two NVM controllers to it
|
||||
'-device', 'nvme,subsys=nvme-subsys-64,serial=deadbeef',
|
||||
'-device', 'nvme,subsys=nvme-subsys-64,serial=deadbeef',
|
||||
# And create two shared namespaces attached to both controllers
|
||||
'-device', 'nvme-ns,drive=nvme0,nsid=16,shared=on',
|
||||
'-device', 'nvme-ns,drive=nvme1,nsid=17,shared=on',
|
||||
]
|
||||
|
||||
udev_storage_tests += {
|
||||
'name' : 'nvme_subsystem',
|
||||
'cmdline' : cmdline,
|
||||
'qemu-args' : qemu_args,
|
||||
}
|
||||
endif
|
||||
|
||||
if devices.contains('name "virtio-scsi-pci"')
|
||||
cmdline = []
|
||||
qemu_args = ['-device', 'virtio-scsi-pci,id=scsi0,num_queues=4']
|
||||
|
||||
foreach i : range(16)
|
||||
id = f'drive@i@'
|
||||
cmdline += [f'--drive=@id@:40M::cache=unsafe']
|
||||
qemu_args += ['-device', f'scsi-hd,drive=@id@,bus=scsi0.0,channel=0,scsi-id=0,lun=@i@']
|
||||
endforeach
|
||||
|
||||
udev_storage_tests += {
|
||||
'name' : 'virtio_scsi_identically_named_partitions',
|
||||
'cmdline' : cmdline,
|
||||
'qemu-args' : qemu_args,
|
||||
}
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
foreach testcase : udev_storage_tests
|
||||
qemu_args = ' '.join(testcase['qemu-args'])
|
||||
cmdline = testcase['cmdline'] + [f'--qemu-args=@qemu_args@']
|
||||
|
||||
integration_tests += [
|
||||
integration_test_template + {
|
||||
'name' : '@0@-@1@'.format(name, testcase),
|
||||
'name' : '@0@-@1@'.format(name, testcase['name']),
|
||||
# Make sure the service is still named TEST-64-UDEV-STORAGE.service.
|
||||
'unit' : unit,
|
||||
'cmdline' : integration_test_template['cmdline'] + [
|
||||
'systemd.setenv=TEST_FUNCTION_NAME=testcase_@0@'.format(testcase)
|
||||
],
|
||||
'mkosi-args' : integration_test_template['mkosi-args'] + [
|
||||
'--configure-script', files('@0@.configure'.format(testcase)),
|
||||
'systemd.setenv=TEST_FUNCTION_NAME=testcase_@0@'.format(testcase['name'])
|
||||
],
|
||||
'mkosi-args' : integration_test_template['mkosi-args'] + cmdline,
|
||||
'priority' : 10,
|
||||
'vm' : true,
|
||||
# Suppress ASan error
|
||||
|
@ -1,31 +0,0 @@
|
||||
#!/usr/bin/python3
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
import json
|
||||
import sys
|
||||
|
||||
|
||||
config = json.load(sys.stdin)
|
||||
|
||||
# Add 16 multipath devices, each backed by 4 paths
|
||||
# We don't use --qemu-drive for this since they have to share the file.
|
||||
for ndisk in range(16):
|
||||
wwn = f"0xDEADDEADBEEF{ndisk:04d}"
|
||||
if ndisk == 0:
|
||||
size = "16M"
|
||||
else:
|
||||
size = "1M"
|
||||
|
||||
for nback in range(4):
|
||||
id = f"drive{ndisk}x{nback}"
|
||||
config["Drives"] += [
|
||||
{
|
||||
"Id": id,
|
||||
"Size": size,
|
||||
"Options": "cache=unsafe",
|
||||
"FileId": str(ndisk),
|
||||
}
|
||||
]
|
||||
config["QemuArgs"] += ["-device", f"scsi-hd,drive={id},serial=MPIO{ndisk},wwn={wwn}"]
|
||||
|
||||
json.dump(config, sys.stdout)
|
@ -1,40 +0,0 @@
|
||||
#!/usr/bin/python3
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
import json
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
|
||||
config = json.load(sys.stdin)
|
||||
|
||||
qemu = shutil.which("/usr/libexec/qemu-kvm") or f"qemu-system-{os.environ['QEMU_ARCHITECTURE']}"
|
||||
result = subprocess.run([qemu, "-device", "help"], check=True, text=True, stdout=subprocess.PIPE)
|
||||
if 'name "nvme"' not in result.stdout:
|
||||
print("nvme device driver is not available, skipping test...", file=sys.stderr)
|
||||
exit(77)
|
||||
|
||||
def add_drive(i: int, serial: str) -> None:
|
||||
global config
|
||||
id = f"nvme{i}"
|
||||
config["Drives"] += [
|
||||
{
|
||||
"Id": id,
|
||||
"Size": "1M",
|
||||
"Options": "cache=unsafe",
|
||||
}
|
||||
]
|
||||
config["QemuArgs"] += ["-device", f"nvme,drive={id},serial={serial},max_ioqpairs=8"]
|
||||
|
||||
for i in range(5):
|
||||
add_drive(i, serial=f"deadbeef{i}")
|
||||
for i in range(5, 10):
|
||||
add_drive(i, serial=f" deadbeef {i} ")
|
||||
for i in range(10, 15):
|
||||
add_drive(i, serial=f" dead/beef/{i} ")
|
||||
for i in range(15, 20):
|
||||
add_drive(i, serial=f"dead/../../beef/{i}")
|
||||
|
||||
json.dump(config, sys.stdout)
|
@ -1,40 +0,0 @@
|
||||
#!/usr/bin/python3
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
import json
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
|
||||
config = json.load(sys.stdin)
|
||||
|
||||
qemu = shutil.which("/usr/libexec/qemu-kvm") or f"qemu-system-{os.environ['QEMU_ARCHITECTURE']}"
|
||||
result = subprocess.run([qemu, "-device", "help"], check=True, text=True, stdout=subprocess.PIPE)
|
||||
if 'name "nvme"' not in result.stdout:
|
||||
print("nvme device driver is not available, skipping test...", file=sys.stderr)
|
||||
exit(77)
|
||||
|
||||
for id in ("nvme0", "nvme1"):
|
||||
config["Drives"] += [
|
||||
{
|
||||
"Id": id,
|
||||
"Size": "1M",
|
||||
"Options": "cache=unsafe",
|
||||
}
|
||||
|
||||
]
|
||||
|
||||
config["QemuArgs"] += [
|
||||
# Create an NVM Subsystem Device
|
||||
"-device", "nvme-subsys,id=nvme-subsys-64,nqn=subsys64",
|
||||
# Attach two NVM controllers to it
|
||||
"-device", "nvme,subsys=nvme-subsys-64,serial=deadbeef",
|
||||
"-device", "nvme,subsys=nvme-subsys-64,serial=deadbeef",
|
||||
# And create two shared namespaces attached to both controllers
|
||||
"-device", "nvme-ns,drive=nvme0,nsid=16,shared=on",
|
||||
"-device", "nvme-ns,drive=nvme1,nsid=17,shared=on",
|
||||
]
|
||||
|
||||
json.dump(config, sys.stdout)
|
@ -1,21 +0,0 @@
|
||||
#!/usr/bin/python3
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
import json
|
||||
import sys
|
||||
|
||||
|
||||
config = json.load(sys.stdin)
|
||||
|
||||
for i in range(10):
|
||||
id = f"drivesimultaneousevents{i}"
|
||||
config["Drives"] += [
|
||||
{
|
||||
"Id": id,
|
||||
"Size": "128M",
|
||||
"Options": "cache=unsafe",
|
||||
}
|
||||
]
|
||||
config["QemuArgs"] += ["-device", f"scsi-hd,drive={id},serial=deadbeeftest{i}"]
|
||||
|
||||
json.dump(config, sys.stdout)
|
@ -1,28 +0,0 @@
|
||||
#!/usr/bin/python3
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
import json
|
||||
import sys
|
||||
|
||||
|
||||
config = json.load(sys.stdin)
|
||||
|
||||
for i in range(4):
|
||||
config["QemuArgs"] += ['-device', f"virtio-scsi-pci,id=scsi{i}"]
|
||||
|
||||
for i in range(128):
|
||||
id = f"drive{i}"
|
||||
config["Drives"] += [
|
||||
{
|
||||
"Id": id,
|
||||
"Size": "1M",
|
||||
"Options": "cache=unsafe",
|
||||
}
|
||||
]
|
||||
config["QemuArgs"] += [
|
||||
'-device',
|
||||
f"scsi-hd,drive={id},bus=scsi{i // 32}.0,channel=0,"
|
||||
f"scsi-id={i % 32},lun=0",
|
||||
]
|
||||
|
||||
json.dump(config, sys.stdout)
|
@ -1,34 +0,0 @@
|
||||
#!/usr/bin/python3
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
import json
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
|
||||
config = json.load(sys.stdin)
|
||||
|
||||
qemu = shutil.which("/usr/libexec/qemu-kvm") or f"qemu-system-{os.environ['QEMU_ARCHITECTURE']}"
|
||||
result = subprocess.run([qemu, "-device", "help"], check=True, text=True, stdout=subprocess.PIPE)
|
||||
if 'name "virtio-scsi-pci"' not in result.stdout:
|
||||
print("virtio-scsi-pci device driver is not available, skipping test...", file=sys.stderr)
|
||||
exit(77)
|
||||
|
||||
num_disk = 16
|
||||
|
||||
config["QemuArgs"] += ["-device", "virtio-scsi-pci,id=scsi0,num_queues=4"]
|
||||
|
||||
for i in range(0, num_disk):
|
||||
id = f"drive{i}"
|
||||
config["Drives"] += [
|
||||
{
|
||||
"Id": id,
|
||||
"Size": "40M",
|
||||
"Options": "cache=unsafe"
|
||||
}
|
||||
]
|
||||
config["QemuArgs"] += ["-device", f"scsi-hd,drive={id},bus=scsi0.0,channel=0,scsi-id=0,lun={i}"]
|
||||
|
||||
json.dump(config, sys.stdout)
|
@ -6,6 +6,7 @@
|
||||
import argparse
|
||||
import base64
|
||||
import dataclasses
|
||||
import datetime
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
@ -363,6 +364,7 @@ def main() -> None:
|
||||
parser.add_argument('--exit-code', required=True, type=int)
|
||||
parser.add_argument('--coredump-exclude-regex', required=True)
|
||||
parser.add_argument('--sanitizer-exclude-regex', required=True)
|
||||
parser.add_argument('--rtc', action=argparse.BooleanOptionalAction)
|
||||
parser.add_argument('mkosi_args', nargs='*')
|
||||
args = parser.parse_args()
|
||||
|
||||
@ -466,11 +468,19 @@ def main() -> None:
|
||||
"""
|
||||
)
|
||||
|
||||
if args.rtc:
|
||||
if sys.version_info >= (3, 12):
|
||||
now = datetime.datetime.now(datetime.UTC)
|
||||
else:
|
||||
now = datetime.datetime.utcnow()
|
||||
|
||||
rtc = datetime.datetime.strftime(now, r'%Y-%m-%dT%H:%M:%S')
|
||||
else:
|
||||
rtc = None
|
||||
|
||||
cmd = [
|
||||
args.mkosi,
|
||||
'--directory', os.fspath(args.meson_source_dir),
|
||||
'--output-dir', os.fspath(args.meson_build_dir / 'mkosi.output'),
|
||||
'--extra-search-path', os.fspath(args.meson_build_dir),
|
||||
'--machine', name,
|
||||
'--ephemeral=yes',
|
||||
*(['--forward-journal', journal_file] if journal_file else []),
|
||||
@ -485,6 +495,7 @@ def main() -> None:
|
||||
'--credential', f'systemd.unit-dropin.{args.unit}={shlex.quote(dropin)}',
|
||||
'--runtime-network=none',
|
||||
'--runtime-scratch=no',
|
||||
*([f'--qemu-args=-rtc base={rtc}'] if rtc else []),
|
||||
*args.mkosi_args,
|
||||
'--firmware', args.firmware,
|
||||
*(['--kvm', 'no'] if int(os.getenv('TEST_NO_KVM', '0')) else []),
|
||||
|
359
test/meson.build
359
test/meson.build
@ -277,191 +277,198 @@ endif
|
||||
|
||||
############################################################
|
||||
|
||||
integration_test_wrapper = find_program('integration-test-wrapper.py')
|
||||
integration_tests = []
|
||||
integration_test_template = {
|
||||
'mkosi-args' : [],
|
||||
'timeout' : 1800,
|
||||
'storage' : 'volatile',
|
||||
'priority' : 0,
|
||||
'firmware' : 'linux',
|
||||
'enabled' : true,
|
||||
'configuration' : {
|
||||
'memory-accounting' : 'no',
|
||||
'command' : testdata_dir / 'units/%N.sh',
|
||||
'wants' : 'multi-user.target user@4711.service',
|
||||
'after' : 'user@4711.service',
|
||||
},
|
||||
'cmdline' : [],
|
||||
'credentials' : [],
|
||||
'qemu-args' : [],
|
||||
'exit-code' : 123,
|
||||
'vm' : false,
|
||||
'coredump-exclude-regex' : '',
|
||||
'sanitizer-exclude-regex' : '',
|
||||
}
|
||||
testdata_subdirs = [
|
||||
'auxv',
|
||||
'journal-data',
|
||||
'knot-data',
|
||||
'test-journals',
|
||||
'units',
|
||||
'test-execute',
|
||||
'test-fstab-generator',
|
||||
'test-path',
|
||||
'test-path-util',
|
||||
'test-umount',
|
||||
'test-network',
|
||||
'test-network-generator-conversion',
|
||||
]
|
||||
|
||||
foreach dirname : [
|
||||
'TEST-01-BASIC',
|
||||
'TEST-02-UNITTESTS',
|
||||
'TEST-03-JOBS',
|
||||
'TEST-04-JOURNAL',
|
||||
'TEST-05-RLIMITS',
|
||||
'TEST-06-SELINUX',
|
||||
'TEST-07-PID1',
|
||||
'TEST-08-INITRD',
|
||||
'TEST-09-REBOOT',
|
||||
'TEST-13-NSPAWN',
|
||||
'TEST-15-DROPIN',
|
||||
'TEST-16-EXTEND-TIMEOUT',
|
||||
'TEST-17-UDEV',
|
||||
'TEST-18-FAILUREACTION',
|
||||
'TEST-19-CGROUP',
|
||||
'TEST-21-DFUZZER',
|
||||
'TEST-22-TMPFILES',
|
||||
'TEST-23-UNIT-FILE',
|
||||
'TEST-24-CRYPTSETUP',
|
||||
'TEST-25-IMPORT',
|
||||
'TEST-26-SYSTEMCTL',
|
||||
'TEST-29-PORTABLE',
|
||||
'TEST-30-ONCLOCKCHANGE',
|
||||
'TEST-31-DEVICE-ENUMERATION',
|
||||
'TEST-32-OOMPOLICY',
|
||||
'TEST-34-DYNAMICUSERMIGRATE',
|
||||
'TEST-35-LOGIN',
|
||||
'TEST-36-NUMAPOLICY',
|
||||
'TEST-38-FREEZER',
|
||||
'TEST-43-PRIVATEUSER-UNPRIV',
|
||||
'TEST-44-LOG-NAMESPACE',
|
||||
'TEST-45-TIMEDATE',
|
||||
'TEST-46-HOMED',
|
||||
'TEST-50-DISSECT',
|
||||
'TEST-52-HONORFIRSTSHUTDOWN',
|
||||
'TEST-53-ISSUE-16347',
|
||||
'TEST-54-CREDS',
|
||||
'TEST-55-OOMD',
|
||||
'TEST-58-REPART',
|
||||
'TEST-59-RELOADING-RESTART',
|
||||
'TEST-60-MOUNT-RATELIMIT',
|
||||
'TEST-62-RESTRICT-IFACES',
|
||||
'TEST-63-PATH',
|
||||
'TEST-64-UDEV-STORAGE',
|
||||
'TEST-65-ANALYZE',
|
||||
'TEST-66-DEVICE-ISOLATION',
|
||||
'TEST-67-INTEGRITY',
|
||||
'TEST-68-PROPAGATE-EXIT-STATUS',
|
||||
'TEST-69-SHUTDOWN',
|
||||
'TEST-70-TPM2',
|
||||
'TEST-71-HOSTNAME',
|
||||
'TEST-72-SYSUPDATE',
|
||||
'TEST-73-LOCALE',
|
||||
'TEST-74-AUX-UTILS',
|
||||
'TEST-75-RESOLVED',
|
||||
'TEST-76-SYSCTL',
|
||||
'TEST-78-SIGQUEUE',
|
||||
'TEST-79-MEMPRESS',
|
||||
'TEST-80-NOTIFYACCESS',
|
||||
'TEST-81-GENERATORS',
|
||||
'TEST-82-SOFTREBOOT',
|
||||
'TEST-83-BTRFS',
|
||||
'TEST-84-STORAGETM',
|
||||
'TEST-85-NETWORK',
|
||||
'TEST-86-MULTI-PROFILE-UKI',
|
||||
'TEST-87-AUX-UTILS-VM',
|
||||
]
|
||||
subdir(dirname)
|
||||
endforeach
|
||||
|
||||
foreach integration_test : integration_tests
|
||||
integration_test_args = [
|
||||
'--meson-source-dir', meson.project_source_root(),
|
||||
'--meson-build-dir', meson.project_build_root(),
|
||||
'--name', integration_test['name'],
|
||||
'--storage', integration_test['storage'],
|
||||
'--firmware', integration_test['firmware'],
|
||||
'--exit-code', integration_test['exit-code'].to_string(),
|
||||
'--coredump-exclude-regex', integration_test['coredump-exclude-regex'],
|
||||
'--sanitizer-exclude-regex', integration_test['sanitizer-exclude-regex'],
|
||||
if want_tests != 'false'
|
||||
integration_test_wrapper = find_program('integration-test-wrapper.py')
|
||||
integration_tests = []
|
||||
integration_test_template = {
|
||||
'mkosi-args' : [],
|
||||
'timeout' : 1800,
|
||||
'storage' : 'volatile',
|
||||
'priority' : 0,
|
||||
'firmware' : 'linux',
|
||||
'enabled' : true,
|
||||
'configuration' : {
|
||||
'memory-accounting' : 'no',
|
||||
'command' : testdata_dir / 'units/%N.sh',
|
||||
'wants' : 'multi-user.target user@4711.service',
|
||||
'after' : 'user@4711.service',
|
||||
},
|
||||
'cmdline' : [],
|
||||
'credentials' : [],
|
||||
'qemu-args' : [],
|
||||
'exit-code' : 123,
|
||||
'vm' : false,
|
||||
'coredump-exclude-regex' : '',
|
||||
'sanitizer-exclude-regex' : '',
|
||||
'rtc' : false,
|
||||
}
|
||||
testdata_subdirs = [
|
||||
'auxv',
|
||||
'journal-data',
|
||||
'knot-data',
|
||||
'test-journals',
|
||||
'units',
|
||||
'test-execute',
|
||||
'test-fstab-generator',
|
||||
'test-path',
|
||||
'test-path-util',
|
||||
'test-umount',
|
||||
'test-network',
|
||||
'test-network-generator-conversion',
|
||||
]
|
||||
|
||||
if 'unit' in integration_test
|
||||
integration_test_unit = integration_test['unit']
|
||||
else
|
||||
integration_test_unit = configure_file(
|
||||
input : 'test.service.in',
|
||||
output : '@0@.service'.format(integration_test['name']),
|
||||
configuration : integration_test['configuration'],
|
||||
)
|
||||
endif
|
||||
|
||||
integration_test_args += ['--unit', fs.name(integration_test_unit)]
|
||||
if install_tests
|
||||
install_data(integration_test_unit, install_dir : testdata_dir / 'units')
|
||||
endif
|
||||
|
||||
if integration_test['vm']
|
||||
integration_test_args += ['--vm']
|
||||
endif
|
||||
|
||||
if not mkosi.found()
|
||||
continue
|
||||
endif
|
||||
|
||||
integration_test_args += ['--mkosi', mkosi.full_path(), '--']
|
||||
|
||||
if integration_test['cmdline'].length() > 0
|
||||
integration_test_args += [
|
||||
'--kernel-command-line-extra=@0@'.format(' '.join(integration_test['cmdline']))
|
||||
]
|
||||
endif
|
||||
|
||||
foreach credential : integration_test['credentials']
|
||||
integration_test_args += ['--credential', credential]
|
||||
foreach dirname : [
|
||||
'TEST-01-BASIC',
|
||||
'TEST-02-UNITTESTS',
|
||||
'TEST-03-JOBS',
|
||||
'TEST-04-JOURNAL',
|
||||
'TEST-05-RLIMITS',
|
||||
'TEST-06-SELINUX',
|
||||
'TEST-07-PID1',
|
||||
'TEST-08-INITRD',
|
||||
'TEST-09-REBOOT',
|
||||
'TEST-13-NSPAWN',
|
||||
'TEST-15-DROPIN',
|
||||
'TEST-16-EXTEND-TIMEOUT',
|
||||
'TEST-17-UDEV',
|
||||
'TEST-18-FAILUREACTION',
|
||||
'TEST-19-CGROUP',
|
||||
'TEST-21-DFUZZER',
|
||||
'TEST-22-TMPFILES',
|
||||
'TEST-23-UNIT-FILE',
|
||||
'TEST-24-CRYPTSETUP',
|
||||
'TEST-25-IMPORT',
|
||||
'TEST-26-SYSTEMCTL',
|
||||
'TEST-29-PORTABLE',
|
||||
'TEST-30-ONCLOCKCHANGE',
|
||||
'TEST-31-DEVICE-ENUMERATION',
|
||||
'TEST-32-OOMPOLICY',
|
||||
'TEST-34-DYNAMICUSERMIGRATE',
|
||||
'TEST-35-LOGIN',
|
||||
'TEST-36-NUMAPOLICY',
|
||||
'TEST-38-FREEZER',
|
||||
'TEST-43-PRIVATEUSER-UNPRIV',
|
||||
'TEST-44-LOG-NAMESPACE',
|
||||
'TEST-45-TIMEDATE',
|
||||
'TEST-46-HOMED',
|
||||
'TEST-50-DISSECT',
|
||||
'TEST-52-HONORFIRSTSHUTDOWN',
|
||||
'TEST-53-ISSUE-16347',
|
||||
'TEST-54-CREDS',
|
||||
'TEST-55-OOMD',
|
||||
'TEST-58-REPART',
|
||||
'TEST-59-RELOADING-RESTART',
|
||||
'TEST-60-MOUNT-RATELIMIT',
|
||||
'TEST-62-RESTRICT-IFACES',
|
||||
'TEST-63-PATH',
|
||||
'TEST-64-UDEV-STORAGE',
|
||||
'TEST-65-ANALYZE',
|
||||
'TEST-66-DEVICE-ISOLATION',
|
||||
'TEST-67-INTEGRITY',
|
||||
'TEST-68-PROPAGATE-EXIT-STATUS',
|
||||
'TEST-69-SHUTDOWN',
|
||||
'TEST-70-TPM2',
|
||||
'TEST-71-HOSTNAME',
|
||||
'TEST-72-SYSUPDATE',
|
||||
'TEST-73-LOCALE',
|
||||
'TEST-74-AUX-UTILS',
|
||||
'TEST-75-RESOLVED',
|
||||
'TEST-76-SYSCTL',
|
||||
'TEST-78-SIGQUEUE',
|
||||
'TEST-79-MEMPRESS',
|
||||
'TEST-80-NOTIFYACCESS',
|
||||
'TEST-81-GENERATORS',
|
||||
'TEST-82-SOFTREBOOT',
|
||||
'TEST-83-BTRFS',
|
||||
'TEST-84-STORAGETM',
|
||||
'TEST-85-NETWORK',
|
||||
'TEST-86-MULTI-PROFILE-UKI',
|
||||
'TEST-87-AUX-UTILS-VM',
|
||||
]
|
||||
subdir(dirname)
|
||||
endforeach
|
||||
|
||||
if integration_test['qemu-args'].length() > 0
|
||||
integration_test_args += ['--qemu-args=@0@'.format(' '.join(integration_test['qemu-args']))]
|
||||
endif
|
||||
foreach integration_test : integration_tests
|
||||
integration_test_args = [
|
||||
'--meson-source-dir', meson.project_source_root(),
|
||||
'--meson-build-dir', meson.project_build_root(),
|
||||
'--name', integration_test['name'],
|
||||
'--storage', integration_test['storage'],
|
||||
'--firmware', integration_test['firmware'],
|
||||
'--exit-code', integration_test['exit-code'].to_string(),
|
||||
'--coredump-exclude-regex', integration_test['coredump-exclude-regex'],
|
||||
'--sanitizer-exclude-regex', integration_test['sanitizer-exclude-regex'],
|
||||
]
|
||||
|
||||
integration_test_args += integration_test['mkosi-args']
|
||||
if 'unit' in integration_test
|
||||
integration_test_unit = integration_test['unit']
|
||||
else
|
||||
integration_test_unit = configure_file(
|
||||
input : 'test.service.in',
|
||||
output : '@0@.service'.format(integration_test['name']),
|
||||
configuration : integration_test['configuration'],
|
||||
)
|
||||
endif
|
||||
|
||||
integration_test_env = {}
|
||||
integration_test_args += ['--unit', fs.name(integration_test_unit)]
|
||||
if install_tests
|
||||
install_data(integration_test_unit, install_dir : testdata_dir / 'units')
|
||||
endif
|
||||
|
||||
if want_integration_tests
|
||||
integration_test_env += {'SYSTEMD_INTEGRATION_TESTS': '1'}
|
||||
endif
|
||||
if integration_test['vm']
|
||||
integration_test_args += ['--vm']
|
||||
endif
|
||||
|
||||
if not integration_test['enabled']
|
||||
continue
|
||||
endif
|
||||
if integration_test['rtc']
|
||||
integration_test_args += ['--rtc']
|
||||
endif
|
||||
|
||||
# We don't explicitly depend on the "mkosi" target because that means the image is rebuilt on every
|
||||
# "ninja -C build". Instead, the mkosi target has to be rebuilt manually before running the
|
||||
# integration tests with mkosi.
|
||||
test(
|
||||
integration_test['name'],
|
||||
integration_test_wrapper,
|
||||
env : integration_test_env,
|
||||
args : integration_test_args,
|
||||
timeout : integration_test['timeout'],
|
||||
priority : integration_test['priority'],
|
||||
suite : 'integration-tests',
|
||||
)
|
||||
endforeach
|
||||
if not mkosi.found()
|
||||
continue
|
||||
endif
|
||||
|
||||
integration_test_args += ['--mkosi', mkosi.full_path(), '--']
|
||||
|
||||
if integration_test['cmdline'].length() > 0
|
||||
integration_test_args += [
|
||||
'--kernel-command-line-extra=@0@'.format(' '.join(integration_test['cmdline']))
|
||||
]
|
||||
endif
|
||||
|
||||
foreach credential : integration_test['credentials']
|
||||
integration_test_args += ['--credential', credential]
|
||||
endforeach
|
||||
|
||||
if integration_test['qemu-args'].length() > 0
|
||||
integration_test_args += ['--qemu-args=@0@'.format(' '.join(integration_test['qemu-args']))]
|
||||
endif
|
||||
|
||||
integration_test_args += integration_test['mkosi-args']
|
||||
|
||||
integration_test_env = {}
|
||||
|
||||
if want_integration_tests
|
||||
integration_test_env += {'SYSTEMD_INTEGRATION_TESTS': '1'}
|
||||
endif
|
||||
|
||||
if not integration_test['enabled']
|
||||
continue
|
||||
endif
|
||||
|
||||
# We don't explicitly depend on the "mkosi" target because that means the image is rebuilt on every
|
||||
# "ninja -C build". Instead, the mkosi target has to be rebuilt manually before running the
|
||||
# integration tests with mkosi.
|
||||
test(
|
||||
integration_test['name'],
|
||||
integration_test_wrapper,
|
||||
env : integration_test_env,
|
||||
args : integration_test_args,
|
||||
timeout : integration_test['timeout'],
|
||||
priority : integration_test['priority'],
|
||||
suite : 'integration-tests',
|
||||
)
|
||||
endforeach
|
||||
endif
|
||||
|
||||
if install_tests
|
||||
foreach subdir : testdata_subdirs
|
||||
|
Loading…
x
Reference in New Issue
Block a user