diff --git a/src/vm_runner/.gitignore b/src/vm_runner/.gitignore index 5d3ba6cc..62b67bd6 100644 --- a/src/vm_runner/.gitignore +++ b/src/vm_runner/.gitignore @@ -1,2 +1,3 @@ *.img *.deb +/target/ diff --git a/src/vm_runner/build_deb.sh b/src/vm_runner/build_deb.sh index f6cea3e4..6479c6bf 100644 --- a/src/vm_runner/build_deb.sh +++ b/src/vm_runner/build_deb.sh @@ -1,27 +1,35 @@ #!/bin/bash set -euo pipefail -boot_bin=target/aarch64-unknown-linux-gnu/release/opensut_boot -if ! [[ -f "$boot_bin" ]]; then - echo "Error: $boot_bin not found; build it first" 1>&2 - exit 1 -else - age=$(( "$(date +%s)" - "$(stat -c %Y "$boot_bin")" )) - age_hr=$(( age / 3600 )) - age_min=$(( age / 60 % 60 )) - age_sec=$(( age % 60 )) - age_str=$(printf %dh%02dm%02ds "$age_hr" "$age_min" "$age_sec") - echo "Using $boot_bin (built $age_str ago)" -fi - edo() { echo " >> $*" 1>&2 "$@" } +check_bin() { + local bin="$1" + if ! [[ -f "$bin" ]]; then + echo "Error: $bin not found; build it first" 1>&2 + exit 1 + else + age=$(( "$(date +%s)" - "$(stat -c %Y "$bin")" )) + age_hr=$(( age / 3600 )) + age_min=$(( age / 60 % 60 )) + age_sec=$(( age % 60 )) + age_str=$(printf %dh%02dm%02ds "$age_hr" "$age_min" "$age_sec") + echo "Using $bin (built $age_str ago)" + fi +} + +boot_bin=target/aarch64-unknown-linux-gnu/release/opensut_boot +check_bin "$boot_bin" +runner_bin=target/aarch64-unknown-linux-gnu/release/opensut_vm_runner +check_bin "$runner_bin" + image=$(mktemp -d) edo mkdir -p "$image/opt/opensut/bin" edo cp -v "$boot_bin" "$image/opt/opensut/bin/" +edo cp -v "$runner_bin" "$image/opt/opensut/bin/" cargo_version="$(cargo read-manifest | \ python3 -c 'import json, sys; print(json.load(sys.stdin)["version"])')" @@ -44,6 +52,11 @@ Description: VERSE OpenSUT boot-time agent services. EOF +systemd_dir="$image/usr/lib/systemd/system" +edo mkdir -p "$systemd_dir" +edo cp -v opensut-boot.service "$systemd_dir" +edo cp -v opensut-boot.target "$systemd_dir" + edo dpkg-deb --root-owner-group --build "$image" "verse-opensut-boot_${version}-1_arm64.deb" edo rm -rf "$image" diff --git a/src/vm_runner/opensut-boot.service b/src/vm_runner/opensut-boot.service new file mode 100644 index 00000000..c0627d6d --- /dev/null +++ b/src/vm_runner/opensut-boot.service @@ -0,0 +1,26 @@ +# Systemd unit file that runs `opensut_boot` and then shuts down the VM. To +# use this, boot with the kernel argument `systemd.unit=opensut-boot.target` +# (note `.target` rather than `.service`). This is similar to booting with +# `systemd.run=/opt/opensut/bin/opensut_boot` (and indeed these files are based +# on the ones autogenerated by `systemd-run-generator`), but using a custom +# unit file gives us more flexibility regarding dependencies. In particular, +# we use this to delay running `opensut_boot` until after the network +# interfaces have been set up. + +[Unit] +Description=OpenSUT Boot Agent +# Shut down the system once `opensut_boot` terminates. +SuccessAction=exit +FailureAction=exit +# Debian's `networking.service` brings up the interfaces with `ifup`. Since +# the OpenSUT VMs all use static IPs, the network should be ready immediately +# (no need to wait for DHCP, etc). We could instead depend on systemd's +# `network-online.target`, which waits "until the network is sufficiently set +# up", but so far this doesn't seem necessary. +Wants=networking.service +After=networking.service + +[Service] +Type=oneshot +StandardOutput=journal+console +ExecStart=/opt/opensut/bin/opensut_boot diff --git a/src/vm_runner/opensut-boot.target b/src/vm_runner/opensut-boot.target new file mode 100644 index 00000000..d0cd6e93 --- /dev/null +++ b/src/vm_runner/opensut-boot.target @@ -0,0 +1,6 @@ +# Systemd unit file that runs `opensut_boot` and then shuts down the VM. See +# `opensut-boot.service` for details. +[Unit] +Description=OpenSUT Boot Agent +Requires=opensut-boot.service +After=opensut-boot.service diff --git a/src/vm_runner/tests/hello/base_nested.toml b/src/vm_runner/tests/hello/base_nested.toml index 4f79f334..613904f9 100644 --- a/src/vm_runner/tests/hello/base_nested.toml +++ b/src/vm_runner/tests/hello/base_nested.toml @@ -9,7 +9,7 @@ kvm = false ram_mb = 1536 kernel = "../../../pkvm_setup/vms/pkvm-boot/vmlinuz" initrd = "../../../pkvm_setup/vms/pkvm-boot/initrd.img" -append = 'earlycon root=/dev/vda2 systemd.run=/opt/opensut/bin/opensut_boot opensut.app_device=/dev/vdc' +append = 'earlycon root=/dev/vda2 systemd.unit=opensut-boot.target opensut.app_device=/dev/vdc' [process.disk.vda] format = "qcow2" diff --git a/src/vm_runner/tests/hello/base_single.toml b/src/vm_runner/tests/hello/base_single.toml index 08c0c2b5..f023554c 100644 --- a/src/vm_runner/tests/hello/base_single.toml +++ b/src/vm_runner/tests/hello/base_single.toml @@ -5,7 +5,7 @@ type = "vm" kvm = false kernel = "../../../pkvm_setup/vms/pkvm-boot/vmlinuz" initrd = "../../../pkvm_setup/vms/pkvm-boot/initrd.img" -append = 'earlycon root=/dev/vda2 systemd.run=/opt/opensut/bin/opensut_boot opensut.app_device=/dev/vdb' +append = 'earlycon root=/dev/vda2 systemd.unit=opensut-boot.target opensut.app_device=/dev/vdb' [process.disk.vda] format = "qcow2" diff --git a/src/vm_runner/tests/hello/host.toml b/src/vm_runner/tests/hello/host.toml index 1f443f7e..e5270ea1 100644 --- a/src/vm_runner/tests/hello/host.toml +++ b/src/vm_runner/tests/hello/host.toml @@ -5,7 +5,7 @@ type = "vm" kvm = true kernel = "/boot/vmlinuz" initrd = "/boot/initrd.img" -append = 'earlycon root=/dev/vda2 systemd.run=/opt/opensut/bin/opensut_boot opensut.app_device=/dev/vdb' +append = 'earlycon root=/dev/vda2 systemd.unit=opensut-boot.target opensut.app_device=/dev/vdb' [process.disk.vda] format = "raw" diff --git a/src/vm_runner/tests/mps/base_nested.toml b/src/vm_runner/tests/mps/base_nested.toml index 4bcb7657..56232622 100644 --- a/src/vm_runner/tests/mps/base_nested.toml +++ b/src/vm_runner/tests/mps/base_nested.toml @@ -12,7 +12,7 @@ kvm = false ram_mb = 1536 kernel = "../../../pkvm_setup/vms/pkvm-boot/vmlinuz" initrd = "../../../pkvm_setup/vms/pkvm-boot/initrd.img" -append = 'earlycon root=/dev/vda2 nokaslr kvm-arm.mode=protected systemd.run=/opt/opensut/bin/opensut_boot opensut.app_device=/dev/vdc' +append = 'earlycon root=/dev/vda2 nokaslr kvm-arm.mode=protected systemd.unit=opensut-boot.target opensut.app_device=/dev/vdc' [process.disk.vda] format = "qcow2" diff --git a/src/vm_runner/tests/mps/base_single.toml b/src/vm_runner/tests/mps/base_single.toml index 3e2e558a..440e82d5 100644 --- a/src/vm_runner/tests/mps/base_single.toml +++ b/src/vm_runner/tests/mps/base_single.toml @@ -8,7 +8,7 @@ type = "vm" kvm = false kernel = "../../../pkvm_setup/vms/pkvm-boot/vmlinuz" initrd = "../../../pkvm_setup/vms/pkvm-boot/initrd.img" -append = 'earlycon root=/dev/vda2 nokaslr kvm-arm.mode=protected systemd.run=/opt/opensut/bin/opensut_boot opensut.app_device=/dev/vdb' +append = 'earlycon root=/dev/vda2 nokaslr kvm-arm.mode=protected systemd.unit=opensut-boot.target opensut.app_device=/dev/vdb' [process.disk.vda] format = "qcow2" diff --git a/src/vm_runner/tests/mps/host.toml b/src/vm_runner/tests/mps/host.toml index 258bef09..a2fab6fc 100644 --- a/src/vm_runner/tests/mps/host.toml +++ b/src/vm_runner/tests/mps/host.toml @@ -8,7 +8,7 @@ type = "vm" kvm = true kernel = "/boot/vmlinuz" initrd = "/boot/initrd.img" -append = 'earlycon root=/dev/vda2 systemd.run=/opt/opensut/bin/opensut_boot opensut.app_device=/dev/vdb' +append = 'earlycon root=/dev/vda2 systemd.unit=opensut-boot.target opensut.app_device=/dev/vdb' [process.disk.vda] format = "raw" diff --git a/src/vm_runner/tests/mps_tests/base_nested.toml b/src/vm_runner/tests/mps_tests/base_nested.toml index 4f79f334..613904f9 100644 --- a/src/vm_runner/tests/mps_tests/base_nested.toml +++ b/src/vm_runner/tests/mps_tests/base_nested.toml @@ -9,7 +9,7 @@ kvm = false ram_mb = 1536 kernel = "../../../pkvm_setup/vms/pkvm-boot/vmlinuz" initrd = "../../../pkvm_setup/vms/pkvm-boot/initrd.img" -append = 'earlycon root=/dev/vda2 systemd.run=/opt/opensut/bin/opensut_boot opensut.app_device=/dev/vdc' +append = 'earlycon root=/dev/vda2 systemd.unit=opensut-boot.target opensut.app_device=/dev/vdc' [process.disk.vda] format = "qcow2" diff --git a/src/vm_runner/tests/mps_tests/base_single.toml b/src/vm_runner/tests/mps_tests/base_single.toml index 08c0c2b5..f023554c 100644 --- a/src/vm_runner/tests/mps_tests/base_single.toml +++ b/src/vm_runner/tests/mps_tests/base_single.toml @@ -5,7 +5,7 @@ type = "vm" kvm = false kernel = "../../../pkvm_setup/vms/pkvm-boot/vmlinuz" initrd = "../../../pkvm_setup/vms/pkvm-boot/initrd.img" -append = 'earlycon root=/dev/vda2 systemd.run=/opt/opensut/bin/opensut_boot opensut.app_device=/dev/vdb' +append = 'earlycon root=/dev/vda2 systemd.unit=opensut-boot.target opensut.app_device=/dev/vdb' [process.disk.vda] format = "qcow2" diff --git a/src/vm_runner/tests/mps_tests/host.toml b/src/vm_runner/tests/mps_tests/host.toml index 1f443f7e..e5270ea1 100644 --- a/src/vm_runner/tests/mps_tests/host.toml +++ b/src/vm_runner/tests/mps_tests/host.toml @@ -5,7 +5,7 @@ type = "vm" kvm = true kernel = "/boot/vmlinuz" initrd = "/boot/initrd.img" -append = 'earlycon root=/dev/vda2 systemd.run=/opt/opensut/bin/opensut_boot opensut.app_device=/dev/vdb' +append = 'earlycon root=/dev/vda2 systemd.unit=opensut-boot.target opensut.app_device=/dev/vdb' [process.disk.vda] format = "raw"