diff --git a/.gitea b/.gitea new file mode 120000 index 00000000..821c19db --- /dev/null +++ b/.gitea @@ -0,0 +1 @@ +.github \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..84d8b909 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,97 @@ +name: "Continuous Integration" + +on: + workflow_dispatch: # allows manual triggering + push: + +jobs: + eval: + runs-on: nix + outputs: + matrix: ${{ steps.eval-jobs.outputs.matrix }} + steps: + - uses: actions/checkout@v4 + - name: Evaluate checks + id: eval-jobs + run: | + MATRIX=$(nix eval \ + --accept-flake-config \ + --json \ + .#checks.x86_64-linux --apply builtins.attrNames \ + ) + echo "matrix=$MATRIX" >> $GITHUB_OUTPUT + + build: + name: ${{ matrix.check }} + needs: eval + strategy: + fail-fast: false + matrix: + check: ${{ fromJson(needs.eval.outputs.matrix) }} + exclude: + # Cannot cross-build on Github CI + - check: qemu-tcg-9pstore-overlay-shutdown-command + - check: qemu-tcg-9pstore-overlay-startup-shutdown + - check: qemu-tcg-9pstore-overlay-systemd-shutdown-command + - check: qemu-tcg-9pstore-overlay-systemd-startup-shutdown + - check: qemu-tcg-9pstore-shutdown-command + - check: qemu-tcg-9pstore-startup-shutdown + - check: qemu-tcg-9pstore-systemd-shutdown-command + - check: qemu-tcg-9pstore-systemd-startup-shutdown + - check: qemu-tcg-overlay-shutdown-command + - check: qemu-tcg-overlay-startup-shutdown + - check: qemu-tcg-overlay-systemd-shutdown-command + - check: qemu-tcg-overlay-systemd-startup-shutdown + - check: qemu-tcg-shutdown-command + - check: qemu-tcg-startup-shutdown + - check: qemu-tcg-systemd-shutdown-command + - check: qemu-tcg-systemd-startup-shutdown + - check: qemu-tcg-9pstore-overlay-hardened-startup-shutdown + - check: qemu-tcg-9pstore-hardened-shutdown-command + - check: qemu-tcg-9pstore-hardened-startup-shutdown + - check: qemu-tcg-9pstore-systemd-hardened-shutdown-command + - check: qemu-tcg-9pstore-overlay-systemd-hardened-shutdown-command + - check: qemu-tcg-9pstore-overlay-hardened-shutdown-command + - check: qemu-tcg-9pstore-overlay-systemd-hardened-startup-shutdown + - check: qemu-tcg-overlay-hardened-startup-shutdown + - check: qemu-tcg-9pstore-systemd-hardened-startup-shutdown + - check: qemu-tcg-hardened-shutdown-command + - check: qemu-tcg-overlay-systemd-hardened-shutdown-command + - check: qemu-tcg-hardened-startup-shutdown + - check: qemu-tcg-overlay-hardened-shutdown-command + - check: qemu-tcg-systemd-hardened-shutdown-command + - check: qemu-tcg-overlay-systemd-hardened-startup-shutdown + - check: qemu-tcg-systemd-hardened-startup-shutdown + # Known broken + - check: cloud-hypervisor-overlay-startup-shutdown + - check: cloud-hypervisor-overlay-shutdown-command + - check: cloud-hypervisor-overlay-systemd-startup-shutdown + - check: cloud-hypervisor-overlay-systemd-shutdown-command + - check: firecracker-overlay-shutdown-command + - check: firecracker-overlay-startup-shutdown + - check: firecracker-overlay-overlay-startup-shutdown + - check: vm-firecracker + - check: vm-firecracker-iperf + # Not finishing + - check: firecracker-overlay-systemd-startup-shutdown + - check: qemu-overlay-startup-shutdown + - check: qemu-overlay-systemd-startup-shutdown + runs-on: nix + env: + NIX_ATTR: 'checks.x86_64-linux.${{ matrix.check }}' + steps: + - name: Enable KVM group perms + run: | + echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules + sudo udevadm control --reload-rules + sudo udevadm trigger --name-match=kvm + - uses: actions/checkout@v4 + - name: Build ${{ matrix.check }} + run: | + nix build \ + -L \ + --accept-flake-config \ + ".#$NIX_ATTR" + if [ -e result/summary.md ]; then + cat result/summary.md >> $GITHUB_STEP_SUMMARY + fi diff --git a/checks/default.nix b/checks/default.nix index 7cb48c88..95ae21c0 100644 --- a/checks/default.nix +++ b/checks/default.nix @@ -52,6 +52,11 @@ let modules = [ { microvm.hypervisor = "alioth"; } ]; + } { + id = "stratovirt"; + modules = [ { + microvm.hypervisor = "stratovirt"; + } ]; } ] # ro-store [ { @@ -70,28 +75,35 @@ let } ]; testing.enableTest = builtins.elem config.microvm.hypervisor [ # Hypervisors that support 9p - "qemu" "crosvm" "kvmtool" + "qemu" "kvmtool" + # "crosvm" ]; }; }) ]; } ] - # rw-store - [ { - # none - id = null; - } { - # overlay volume - id = "overlay"; - modules = [ ({ config, ... }: { - microvm.writableStoreOverlay = "/nix/.rw-store"; - microvm.volumes = [ { - image = "nix-store-overlay.img"; - label = "nix-store"; - mountPoint = config.microvm.writableStoreOverlay; - size = 128; - } ]; - }) ]; - } ] + # # rw-store + # [ { + # # none + # id = null; + # } { + # # overlay volume + # id = "overlay"; + # modules = [ ({ config, ... }: { + # microvm = { + # writableStoreOverlay = "/nix/.rw-store"; + # volumes = [ { + # image = "nix-store-overlay.img"; + # label = "nix-store"; + # mountPoint = config.microvm.writableStoreOverlay; + # size = 128; + # } ]; + # testing.enableTest = builtins.elem config.microvm.hypervisor [ + # # Known good + # "qemu" "cloud-hypervisor" "firecracker" + # ]; + # }; + # }) ]; + # } ] # boot.systemd [ { # no @@ -100,16 +112,22 @@ let boot.initrd.systemd.enable = false; } ]; } { + # yes id = "systemd"; - modules = [ { + modules = [ ({ config, ... }: { boot.initrd.systemd.enable = true; - } ]; + microvm.testing.enableTest = ! builtins.elem config.microvm.hypervisor [ + # Known broken + "crosvm" + "kvmtool" + ]; + }) ]; } ] # hardened profile [ { - # no - id = null; - } { + # # no + # id = null; + # } { id = "hardened"; modules = [ ({ modulesPath, ... }: { imports = [ "${modulesPath}/profiles/hardened.nix" ]; diff --git a/checks/iperf.nix b/checks/iperf.nix index 0cbe9a7d..69d93568 100644 --- a/checks/iperf.nix +++ b/checks/iperf.nix @@ -6,6 +6,8 @@ nixpkgs.lib.optionalAttrs (builtins.elem hypervisor self.lib.hypervisorsWithNetw name = "vm-${hypervisor}-iperf"; nodes.vm = { imports = [ self.nixosModules.host ]; + # TODO: this is a farce of a flake. replace with declarative + # microvm. microvm.vms."${hypervisor}-iperf-server".flake = nixpkgs.legacyPackages.${system}.runCommand "${hypervisor}-iperf-server.flake" { passthru.nixosConfigurations."${hypervisor}-iperf-server" = nixpkgs.lib.nixosSystem { inherit system; @@ -21,17 +23,19 @@ nixpkgs.lib.optionalAttrs (builtins.elem hypervisor self.lib.hypervisorsWithNetw } ]; }; networking.hostName = "${hypervisor}-microvm"; - networking = { - interfaces.eth0 = { - useDHCP = false; - ipv4.addresses = [ { - address = "10.0.0.1"; - prefixLength = 24; - } ]; + systemd.network = { + enable = true; + networks."10-eth" = { + matchConfig.Type = "ether"; + address = [ "10.0.0.1/24" ]; }; - firewall.enable = false; }; + networking.firewall.enable = false; services.iperf3.enable = true; + # Hack for slow Github CI + systemd.extraConfig = '' + DefaultTimeoutStartSec=600 + ''; } ]; }; @@ -50,6 +54,7 @@ nixpkgs.lib.optionalAttrs (builtins.elem hypervisor self.lib.hypervisorsWithNetw # # keep the store paths built inside the VM across reboots # writableStoreUseTmpfs = false; qemu.options = [ + "-M" "q35,accel=kvm" "-cpu" { "aarch64-linux" = "cortex-a72"; @@ -59,10 +64,19 @@ nixpkgs.lib.optionalAttrs (builtins.elem hypervisor self.lib.hypervisorsWithNetw }; }; testScript = '' - vm.wait_for_unit("microvm@${hypervisor}-iperf-server.service", timeout = 900) + import os + + vm.wait_for_unit("microvm@${hypervisor}-iperf-server.service", timeout = 600) vm.succeed("ip addr add 10.0.0.2/24 dev microvm") - result = vm.wait_until_succeeds("iperf -c 10.0.0.1", timeout = 180) + + result = vm.wait_until_succeeds("iperf -c 10.0.0.1 2>/dev/null", timeout = 1200) print(result) + + path = "{}/summary.md".format(os.environ.get("out")) + with open(path, 'w') as file: + file.write("```\n") + file.write(result) + file.write("```\n") ''; meta.timeout = 1800; }) { inherit system; pkgs = nixpkgs.legacyPackages.${system}; }; diff --git a/checks/shutdown-command.nix b/checks/shutdown-command.nix index bc42e551..8348e6e5 100644 --- a/checks/shutdown-command.nix +++ b/checks/shutdown-command.nix @@ -34,8 +34,9 @@ builtins.mapAttrs (_: nixos: } '' set -m microvm-run > $out & + export MAINPID=$! - sleep 10 + sleep 30 echo Now shutting down microvm-shutdown '' diff --git a/checks/startup-shutdown.nix b/checks/startup-shutdown.nix index 52290f7e..25819b79 100644 --- a/checks/startup-shutdown.nix +++ b/checks/startup-shutdown.nix @@ -34,6 +34,7 @@ let crosvm = "reboot"; kvmtool = "reboot"; alioth = "poweroff"; + stratovirt = "reboot"; }.${config.microvm.hypervisor}; in '' ${pkgs.coreutils}/bin/uname > /output/kernel-name diff --git a/checks/vm.nix b/checks/vm.nix index 3e4b30e9..2b19a6b7 100644 --- a/checks/vm.nix +++ b/checks/vm.nix @@ -16,6 +16,10 @@ ]; # Must be big enough for the store overlay volume virtualisation.diskSize = 4096; + # Hack for slow Github CI + systemd.extraConfig = '' + DefaultTimeoutStartSec=600 + ''; microvm.vms."${system}-${hypervisor}-example".flake = self; }; diff --git a/flake.nix b/flake.nix index c9c53139..6f0e3562 100644 --- a/flake.nix +++ b/flake.nix @@ -135,15 +135,14 @@ else result ) {} (builtins.attrNames self.nixosConfigurations); - # Takes too much memory in `nix flake show` - # checks = import ./checks { inherit self nixpkgs system; }; + checks = import ./checks { inherit self nixpkgs system; }; # hydraJobs are checks hydraJobs = builtins.mapAttrs (_: check: (nixpkgs.lib.recursiveUpdate check { meta.timeout = 12 * 60 * 60; }) - ) (import ./checks { inherit self nixpkgs system; }); + ) self.checks.${system}; }) // { lib = import ./lib { inherit (nixpkgs) lib; }; diff --git a/lib/runners/firecracker.nix b/lib/runners/firecracker.nix index f4c71b63..c6689140 100644 --- a/lib/runners/firecracker.nix +++ b/lib/runners/firecracker.nix @@ -30,6 +30,8 @@ let # Without this, starting of firecracker fails with an error message: # Enabling simultaneous multithreading is not supported on aarch64 smt = system != "aarch64-linux"; + # Run even on old CPUs + cpu_template = null; }; drives = [ { drive_id = "store"; diff --git a/lib/runners/qemu.nix b/lib/runners/qemu.nix index 1afe818e..fcab0a16 100644 --- a/lib/runners/qemu.nix +++ b/lib/runners/qemu.nix @@ -64,7 +64,7 @@ let accel = if microvmConfig.cpu == null - then "kvm:tcg" + then "kvm" else "tcg"; # PCI required by vfio-pci for PCI passthrough