From b8698cd8d62c42cf3e2b3a95224c57173b73e494 Mon Sep 17 00:00:00 2001 From: Gabriella Gonzalez Date: Fri, 1 Mar 2024 21:33:14 -0800 Subject: [PATCH] macOS support for NixOS tests (#282401) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes #193336 Closes #261694 Related to #108984 The goal here was to get the following flake to build and run on `aarch64-darwin`: ```nix { inputs.nixpkgs.url = ; outputs = { nixpkgs, ... }: { checks.aarch64-darwin.default = nixpkgs.legacyPackages.aarch64-darwin.nixosTest { name = "test"; nodes.machine = { }; testScript = ""; }; }; } ``` … and after this change it does. There's no longer a need for the user to set `nodes.*.nixpkgs.pkgs` or `nodes.*.virtualisation.host.pkgs` as the correct values are inferred from the host system. --- nixos/lib/testing/nodes.nix | 22 ++++++++++++++++++- nixos/lib/testing/pkgs.nix | 6 ++++- nixos/lib/testing/run.nix | 4 +++- nixos/tests/acme.nix | 5 ++++- nixos/tests/all-tests.nix | 3 ++- pkgs/build-support/testers/default.nix | 6 ++--- pkgs/build-support/testers/test/default.nix | 4 ++-- pkgs/top-level/release-attrpaths-superset.nix | 1 + pkgs/top-level/stage.nix | 10 +++++++++ 9 files changed, 51 insertions(+), 10 deletions(-) diff --git a/nixos/lib/testing/nodes.nix b/nixos/lib/testing/nodes.nix index 73e6d386fd1d..7941d69e38d2 100644 --- a/nixos/lib/testing/nodes.nix +++ b/nixos/lib/testing/nodes.nix @@ -14,6 +14,25 @@ let types ; + inherit (hostPkgs) hostPlatform; + + guestSystem = + if hostPlatform.isLinux + then hostPlatform.system + else + let + hostToGuest = { + "x86_64-darwin" = "x86_64-linux"; + "aarch64-darwin" = "aarch64-linux"; + }; + + supportedHosts = lib.concatStringsSep ", " (lib.attrNames hostToGuest); + + message = + "NixOS Test: don't know which VM guest system to pair with VM host system: ${hostPlatform.system}. Perhaps you intended to run the tests on a Linux host, or one of the following systems that may run NixOS tests: ${supportedHosts}"; + in + hostToGuest.${hostPlatform.system} or (throw message); + baseOS = import ../eval-config.nix { inherit lib; @@ -27,13 +46,14 @@ let ({ config, ... }: { virtualisation.qemu.package = testModuleArgs.config.qemu.package; + virtualisation.host.pkgs = hostPkgs; }) ({ options, ... }: { key = "nodes.nix-pkgs"; config = optionalAttrs (!config.node.pkgsReadOnly) ( mkIf (!options.nixpkgs.pkgs.isDefined) { # TODO: switch to nixpkgs.hostPlatform and make sure containers-imperative test still evaluates. - nixpkgs.system = hostPkgs.stdenv.hostPlatform.system; + nixpkgs.system = guestSystem; } ); }) diff --git a/nixos/lib/testing/pkgs.nix b/nixos/lib/testing/pkgs.nix index 22dd586868e3..46d82c65d26a 100644 --- a/nixos/lib/testing/pkgs.nix +++ b/nixos/lib/testing/pkgs.nix @@ -2,7 +2,11 @@ { config = { # default pkgs for use in VMs - _module.args.pkgs = hostPkgs; + _module.args.pkgs = + # TODO: deprecate it everywhere; not just on darwin. Throw on darwin? + lib.warnIf hostPkgs.stdenv.hostPlatform.isDarwin + "Do not use the `pkgs` module argument in tests you want to run on darwin. It is ambiguous, and many tests are broken because of it. If you need to use a package on the VM host, use `hostPkgs`. Otherwise, use `config.node.pkgs`, or `config.nodes..nixpkgs.pkgs`." + hostPkgs; defaults = { # TODO: a module to set a shared pkgs, if options.nixpkgs.* is untouched by user (highestPrio) */ diff --git a/nixos/lib/testing/run.nix b/nixos/lib/testing/run.nix index 9440c1acdfd8..de5a9b97e61d 100644 --- a/nixos/lib/testing/run.nix +++ b/nixos/lib/testing/run.nix @@ -41,7 +41,9 @@ in rawTestDerivation = hostPkgs.stdenv.mkDerivation { name = "vm-test-run-${config.name}"; - requiredSystemFeatures = [ "kvm" "nixos-test" ]; + requiredSystemFeatures = [ "nixos-test" ] + ++ lib.optionals hostPkgs.stdenv.hostPlatform.isLinux [ "kvm" ] + ++ lib.optionals hostPkgs.stdenv.hostPlatform.isDarwin [ "apple-virt" ]; buildCommand = '' mkdir -p $out diff --git a/nixos/tests/acme.nix b/nixos/tests/acme.nix index 272782dc2f62..d63a77fcdd23 100644 --- a/nixos/tests/acme.nix +++ b/nixos/tests/acme.nix @@ -1,4 +1,7 @@ -{ pkgs, lib, ... }: let +{ config, lib, ... }: let + + pkgs = config.node.pkgs; + commonConfig = ./common/acme/client; dnsServerIP = nodes: nodes.dnsserver.networking.primaryIPAddress; diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index 9795023bcea9..7376cd40b910 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -78,8 +78,9 @@ let # it with `allowAliases = false`? # warnIf pkgs.config.allowAliases "nixosTests: pkgs includes aliases." { + _file = "${__curPos.file} readOnlyPkgs"; _class = "nixosTest"; - node.pkgs = pkgs; + node.pkgs = pkgs.pkgsLinux; }; in { diff --git a/pkgs/build-support/testers/default.nix b/pkgs/build-support/testers/default.nix index fc10597e3e12..362622d9b7ee 100644 --- a/pkgs/build-support/testers/default.nix +++ b/pkgs/build-support/testers/default.nix @@ -1,4 +1,4 @@ -{ pkgs, buildPackages, lib, callPackage, runCommand, stdenv, substituteAll, testers }: +{ pkgs, pkgsLinux, buildPackages, lib, callPackage, runCommand, stdenv, substituteAll, testers }: # Documentation is in doc/builders/testers.chapter.md { # See https://nixos.org/manual/nixpkgs/unstable/#tester-testBuildFailure @@ -107,7 +107,7 @@ (lib.setDefaultModuleLocation "the argument that was passed to pkgs.runNixOSTest" testModule) ]; hostPkgs = pkgs; - node.pkgs = pkgs; + node.pkgs = pkgsLinux; }; # See doc/builders/testers.chapter.md or @@ -123,7 +123,7 @@ inherit pkgs; extraConfigurations = [( { lib, ... }: { - config.nixpkgs.pkgs = lib.mkDefault pkgs; + config.nixpkgs.pkgs = lib.mkDefault pkgsLinux; } )]; }); diff --git a/pkgs/build-support/testers/test/default.nix b/pkgs/build-support/testers/test/default.nix index c48c9f299ebf..da67711156be 100644 --- a/pkgs/build-support/testers/test/default.nix +++ b/pkgs/build-support/testers/test/default.nix @@ -27,11 +27,11 @@ lib.recurseIntoAttrs { # Check that the wiring of nixosTest is correct. # Correct operation of the NixOS test driver should be asserted elsewhere. - nixosTest-example = pkgs-with-overlay.testers.nixosTest ({ lib, pkgs, figlet, ... }: { + nixosTest-example = pkgs-with-overlay.testers.nixosTest ({ lib, ... }: { name = "nixosTest-test"; nodes.machine = { pkgs, ... }: { system.nixos = dummyVersioning; - environment.systemPackages = [ pkgs.proof-of-overlay-hello figlet ]; + environment.systemPackages = [ pkgs.proof-of-overlay-hello pkgs.figlet ]; }; testScript = '' machine.succeed("hello | figlet >/dev/console") diff --git a/pkgs/top-level/release-attrpaths-superset.nix b/pkgs/top-level/release-attrpaths-superset.nix index 55cce6101d71..cd48453fa0ee 100644 --- a/pkgs/top-level/release-attrpaths-superset.nix +++ b/pkgs/top-level/release-attrpaths-superset.nix @@ -53,6 +53,7 @@ let pkgsStatic = true; pkgsCross = true; pkgsi686Linux = true; + pkgsLinux = true; pkgsExtraHardening = true; }; diff --git a/pkgs/top-level/stage.nix b/pkgs/top-level/stage.nix index cbf0f585fe41..1fc551c0b453 100644 --- a/pkgs/top-level/stage.nix +++ b/pkgs/top-level/stage.nix @@ -243,6 +243,16 @@ let }; } else throw "x86_64 Darwin package set can only be used on Darwin systems."; + # If already linux: the same package set unaltered + # Otherwise, return a natively built linux package set for the current cpu architecture string. + # (ABI and other details will be set to the default for the cpu/os pair) + pkgsLinux = + if stdenv.hostPlatform.isLinux + then self + else nixpkgsFun { + localSystem = lib.systems.elaborate "${stdenv.hostPlatform.parsed.cpu.name}-linux"; + }; + # Extend the package set with zero or more overlays. This preserves # preexisting overlays. Prefer to initialize with the right overlays # in one go when calling Nixpkgs, for performance and simplicity.