diff --git a/.editorconfig b/.editorconfig index aab3429..061699c 100644 --- a/.editorconfig +++ b/.editorconfig @@ -11,5 +11,5 @@ indent_style = space indent_size = 4 [*.nix] -indent_style = tab +indent_style = space indent_size = 2 diff --git a/default.nix b/default.nix index b17a6c7..4372c35 100644 --- a/default.nix +++ b/default.nix @@ -5,7 +5,8 @@ in import src { inherit pkgs; }, }: let inherit (qpkgs) lib; - dynix = qpkgs.callPackage ./package.nix { }; + dynix = qpkgs.callPackage ./package.nix { } + |> qpkgs.stdlib.mkStdenvPretty; byStdenv = lib.mapAttrs (stdenvName: stdenv: let withStdenv = dynix.override { inherit stdenv; }; dynix' = withStdenv.overrideAttrs (prev: { diff --git a/package.nix b/package.nix index d29908a..3d0e673 100644 --- a/package.nix +++ b/package.nix @@ -2,9 +2,12 @@ lib, stdenvNoCC, callPackage, + linkFarm, }: let stdenv = stdenvNoCC; -in stdenv.mkDerivation (self: { +in stdenv.mkDerivation (finalAttrs: let + self = finalAttrs.finalPackage; +in { name = "dynix-modules"; strictDeps = true; @@ -21,12 +24,15 @@ in stdenv.mkDerivation (self: { phases = [ "unpackPhase" "patchPhase" "installPhase" ]; + modulesOut = "${placeholder "modules"}/share/nixos/modules/dynix"; + installPhase = lib.dedent '' + runHook preInstall mkdir -p "$out" cp -r * "$out/" mkdir -p "$modules/share/nixos/modules/dynix" - cp --reflink=auto -r "$out/"* "$modules/share/nixos/modules/dynix/" + cp --reflink=auto -r "$out/"* "$modulesOut/" ''; passthru.mkDevShell = { @@ -39,7 +45,7 @@ in stdenv.mkDerivation (self: { p.beartype ]); in mkShell' { - name = "devshell-for-${self.finalPackage.name}"; + name = "devshell-for-${self.name}"; packages = [ pyEnv ]; env.PYTHONPATH = [ "${pyEnv}/${pyEnv.sitePackages}" @@ -48,13 +54,19 @@ in stdenv.mkDerivation (self: { ] |> lib.concatStringsSep ":"; }; - passthru.modulesPath = self.finalPackage.modules + "/share/nixos/modules"; + passthru.modulesPath = self.modules + "/share/nixos/modules"; passthru.tests = lib.fix (callPackage ./tests { - dynix = self.finalPackage; + dynix = self; }).packages; + passthru.allTests = linkFarm "dynix-all-tests" self.tests; + meta = { + longDescription = lib.dedent '' + Default output contains the modules at top-level, meant for `import`. + The `modules` output contains the modules prefixed under `/share/nixos/modules/dynix`. + ''; outputsToInstall = [ "modules" ]; }; }) diff --git a/tests/default.nix b/tests/default.nix index 5e3d082..dc690a6 100644 --- a/tests/default.nix +++ b/tests/default.nix @@ -3,23 +3,35 @@ qpkgs ? let src = fetchTree (builtins.parseFlakeRef "github:Qyriad/nur-packages"); in import src { inherit pkgs; }, + callPackage ? qpkgs.callPackage, lib ? qpkgs.lib, dynix ? qpkgs.callPackage ../package.nix { }, }: let + mkDynixConfigurationDotNix = callPackage ./mk-test-configuration-dot-nix.nix { }; + runDynixTest = testModule: pkgs.testers.runNixOSTest { imports = [ testModule ]; + # NOTE: these are arguments to each *test module*. + # Not the NixOS modules of the test's nodes. + _module.args = { inherit mkDynixConfigurationDotNix; }; + # Why is this argument called "extraBaseModule**s**" but take a single module argument... # Also note this is an extra base module for each node of the test, # not an extra test module. extraBaseModules = { name, config, options, modulesPath, ... }: { + /** + * Everything in this module will disappear once nixos-rebuild switch happens. + * So each test will need to use `mkDynixConfigurationDotNix` to get + * ./dynix-vm-configuration included in the in-VM configuration. + */ + imports = (import "${modulesPath}/module-list.nix") ++ [ ./module-allow-rebuild-in-vm.nix - "${modulesPath}/testing/test-instrumentation.nix" + ./dynix-vm-configuration.nix (toString dynix) ]; - environment.systemPackages = [ dynix ]; systemd.services."install-dynix" = { enable = true; @@ -27,9 +39,18 @@ serviceConfig.RemainAfterExit = true; path = [ config.system.path ]; wantedBy = [ "multi-user.target" ]; + serviceConfig.requisteOf = [ "multi-user.target" ]; after = [ "default.target" ]; script = '' - nix profile install -vv "$(realpath /run/current-system/sw/share/nixos/modules/dynix/)" + nix profile install -vv "${dynix.modules}" + + mkdir -vp /etc/nixos + nixos-generate-config + cp -rv --dereference /run/current-system/sw/share/nixos/*.nix /etc/nixos/ + if ! [[ -e /etc/nixos/dynix-vm-configuration.nix ]]; then + echo "FAILURE" + echo "FAILURE" >&2 + fi ''; }; diff --git a/tests/dynix-vm-configuration.nix b/tests/dynix-vm-configuration.nix new file mode 100644 index 0000000..fbc6193 --- /dev/null +++ b/tests/dynix-vm-configuration.nix @@ -0,0 +1,59 @@ +{ pkgs, lib, modulesPath, ... }: +let + moduleList = import "${modulesPath}/module-list.nix"; + + dynixFromSearchPath = let + res = builtins.tryEval ; + in lib.optional res.success res.value; +in +{ + imports = [ + "${modulesPath}/testing/test-instrumentation.nix" + ] ++ lib.concatLists [ + dynixFromSearchPath + moduleList + ]; + + system.switch.enable = true; + system.includeBuildDependencies = true; + documentation.enable = false; + + boot.loader.grub = { + enable = true; + device = "/dev/vda"; + forceInstall = true; + }; + + nix = { + package = pkgs.lixPackageSets.latest.lix; + nixPath = [ + "nixpkgs=${pkgs.path}" + "/nix/var/nix/profiles/per-user/root/profile/share/nixos/modules" + ]; + + settings = { + experimental-features = [ "nix-command" "pipe-operator" ]; + substituters = lib.mkForce [ ]; + hashed-mirrors = null; + connect-timeout = 1; + # For my debugging purposes. + show-trace = true; + }; + }; + + environment.pathsToLink = [ "/share" ]; + environment.extraOutputsToInstall = [ "modules" ]; + environment.variables = { + "NIXOS_CONFIG" = "/etc/nixos/configuration.nix"; + }; + + environment.shellAliases = { + ls = "eza --long --header --group --group-directories-first --classify --binary"; + }; + + environment.systemPackages = with pkgs; [ + eza + fd + ripgrep + ]; +} diff --git a/tests/gotosocial/configuration.nix b/tests/gotosocial/configuration.nix index deef056..8ada5c8 100644 --- a/tests/gotosocial/configuration.nix +++ b/tests/gotosocial/configuration.nix @@ -1,48 +1,9 @@ { pkgs, lib, config, modulesPath, ... }: let name = config.networking.hostName; - moduleList = import (modulesPath + "/module-list.nix"); - - dynixFromSearchPath = let - res = builtins.tryEval ; - in lib.optional res.success res.value; in { - imports = moduleList ++ [ - "${modulesPath}/testing/test-instrumentation.nix" - ./hardware-configuration.nix - ] ++ lib.concatLists [ - dynixFromSearchPath - ]; - - system.switch.enable = true; - documentation.enable = false; - networking.hostName = "gotosocial-machine"; - - boot.loader.grub = { - enable = true; - device = "/dev/vda"; - forceInstall = true; - }; - - nix = { - package = pkgs.lixPackageSets.latest.lix; - nixPath = [ - "nixpkgs=${pkgs.path}" - "/nix/var/nix/profiles/per-user/root/profile/share/nixos/modules" - ]; - - settings = { - experimental-features = [ "nix-command" "pipe-operator" ]; - substituters = lib.mkForce [ ]; - hashed-mirrors = null; - connect-timeout = 1; - # For my debugging purposes. - show-trace = true; - }; - }; - services.gotosocial = { enable = true; setupPostgresqlDB = true; @@ -53,19 +14,4 @@ in }; dynamicism.for.gotosocial.enable = true; - - environment.pathsToLink = [ "/share" ]; - environment.extraOutputsToInstall = [ "modules" ]; - environment.variables = { - "NIXOS_CONFIG" = "/etc/nixos/configuration.nix"; - }; - - environment.shellAliases = { - ls = "eza --long --header --group --group-directories-first --classify --binary"; - }; - environment.systemPackages = with pkgs; [ - eza - fd - ripgrep - ]; } diff --git a/tests/gotosocial/test-script.py b/tests/gotosocial/test-script.py index d8b2af8..2fa42ed 100644 --- a/tests/gotosocial/test-script.py +++ b/tests/gotosocial/test-script.py @@ -52,12 +52,6 @@ def get_config_file() -> str: machine.wait_for_unit("default.target") assert "lix" in machine.succeed("nix --version").lower() machine.log("INIT") -run_log(machine, "journalctl --no-pager -eu install-dynix.service") - -machine.succeed("nixos-generate-config") -machine.succeed("mkdir -vp /etc/nixos") -# Dereference is required since that configuration.nix is probably a symlink to the store. -machine.succeed("cp -rv --dereference /run/current-system/sw/share/nixos/configuration.nix /etc/nixos/") machine.log("REBUILDING configuration inside VM") machine.succeed("env PAGER= nixos-rebuild switch --log-format raw-with-logs --fallback") diff --git a/tests/gotosocial/test.nix b/tests/gotosocial/test.nix index 9628b93..fd5bfbb 100644 --- a/tests/gotosocial/test.nix +++ b/tests/gotosocial/test.nix @@ -1,4 +1,4 @@ -{ ... }: +{ mkDynixConfigurationDotNix, config, ... }: { name = "nixos-test-dynamicism-gotosocial"; @@ -17,7 +17,10 @@ imports = [ ./configuration.nix ]; environment.systemPackages = let - configFileTree = pkgs.callPackage ./configuration-package.nix { }; + configFileTree = mkDynixConfigurationDotNix { + inherit (config) name; + configuration = ./configuration.nix; + }; in [ configFileTree ]; diff --git a/tests/harmonia/configuration.nix b/tests/harmonia/configuration.nix index 7bf19bb..37494cb 100644 --- a/tests/harmonia/configuration.nix +++ b/tests/harmonia/configuration.nix @@ -1,4 +1,4 @@ -{ pkgs, lib, config, modulesPath, ... }: +{ lib, modulesPath, ... }: let moduleList = import "${modulesPath}/module-list.nix"; @@ -8,10 +8,10 @@ let in { imports = [ - "${modulesPath}/testing/test-instrumentation.nix" - ./hardware-configuration.nix + #"${modulesPath}/testing/test-instrumentation.nix" + #./hardware-configuration.nix ] ++ lib.concatLists [ - dynixFromSearchPath + #dynixFromSearchPath moduleList ]; @@ -26,47 +26,5 @@ in }; }; - system.switch.enable = true; - documentation.enable = false; - networking.hostName = "harmonia-machine"; - - boot.loader.grub = { - enable = true; - device = "/dev/vda"; - forceInstall = true; - }; - - nix = { - package = pkgs.lixPackageSets.latest.lix; - nixPath = [ - "nixpkgs=${pkgs.path}" - "/nix/var/nix/profiles/per-user/root/profile/share/nixos/modules" - ]; - - settings = { - experimental-features = [ "nix-command" "pipe-operator" ]; - substituters = lib.mkForce [ ]; - hashed-mirrors = null; - connect-timeout = 1; - # For my debugging purposes. - show-trace = true; - }; - }; - - environment.pathsToLink = [ "/share" ]; - environment.extraOutputsToInstall = [ "modules" ]; - environment.variables = { - "NIXOS_CONFIG" = "/etc/nixos/configuration.nix"; - }; - - environment.shellAliases = { - ls = "eza --long --header --group --group-directories-first --classify --binary"; - }; - - environment.systemPackages = with pkgs; [ - eza - fd - ripgrep - ]; } diff --git a/tests/harmonia/test-script.py b/tests/harmonia/test-script.py index a91bf78..e96a053 100644 --- a/tests/harmonia/test-script.py +++ b/tests/harmonia/test-script.py @@ -66,10 +66,6 @@ assert int(config_toml['workers']) == 4, f"{config_toml['workers']=} != 4" assert int(config_toml['max_connection_rate']) == 256, f"{config_toml['max_connection_rate']=} != 256" with machine.nested("must succeed: initial nixos-rebuild switch"): - machine.succeed("nixos-generate-config") - machine.succeed("mkdir -vp /etc/nixos") - # Dereference is required since that configuration.nix is probably a symlink to the store. - machine.succeed("cp -rv --dereference /run/current-system/sw/share/nixos/configuration.nix /etc/nixos/") machine.succeed("env PAGER= nixos-rebuild switch --log-format raw-with-logs --fallback") # Config should not have changed. diff --git a/tests/harmonia/test.nix b/tests/harmonia/test.nix index 0aea418..873c7dd 100644 --- a/tests/harmonia/test.nix +++ b/tests/harmonia/test.nix @@ -1,4 +1,4 @@ -{ ... }: +{ mkDynixConfigurationDotNix, config, ... }: { name = "nixos-test-dynamicism-harmonia"; @@ -10,10 +10,14 @@ imports = [ ./configuration.nix ]; environment.systemPackages = let - configFileTree = pkgs.runCommand "${name}-configuration-dot-nix" { } '' - set -euo pipefail - install -Dm a=r ${./configuration.nix} "$out/share/nixos/configuration.nix" - ''; + #configFileTree = pkgs.runCommand "${name}-configuration-dot-nix" { } '' + # set -euo pipefail + # install -Dm a=r ${./configuration.nix} "$out/share/nixos/configuration.nix" + #''; + configFileTree = mkDynixConfigurationDotNix { + inherit (config) name; + configuration = ./configuration.nix; + }; in [ configFileTree ]; diff --git a/tests/mk-test-configuration-dot-nix.nix b/tests/mk-test-configuration-dot-nix.nix new file mode 100644 index 0000000..a31cf50 --- /dev/null +++ b/tests/mk-test-configuration-dot-nix.nix @@ -0,0 +1,63 @@ +{ + lib, + stdenvNoCC, +}: let + stdenv = stdenvNoCC; + + mkDynixConfigurationDotNix = finalAttrs: { + name, + configuration, + }: assert lib.isStringLike configuration; let + self = finalAttrs.finalPackage; + in { + name = "configuration-dot-nix-for-${name}"; + strictDeps = true; + __structuredAttrs = true; + preferLocalBuild = true; + + phases = [ "installPhase" ]; + + #outputs = [ "out" "modules" ]; + outputs = [ "out" ]; + modulesOut = "${placeholder "out"}/share/nixos"; + #modulesOut = "${placeholder "modules"}/share/nixos/modules"; + + baseConfiguration = configuration; + + installPhase = '' + runHook preInstall + + install -Dm a=r "$baseConfiguration" "$modulesOut/test-configuration.nix" + install -Dm a=r "${./dynix-vm-configuration.nix}" "$modulesOut/dynix-vm-configuration.nix" + + echo "/** GENERATED BY mk-test-configuration-dot-nix! */" >> "$modulesOut/configuration.nix" + echo "{ ... }:" >> "$modulesOut/configuration.nix" + echo >> "$modulesOut/configuration.nix" + echo >> "$modulesOut/configuration.nix" + echo "{" >> "$modulesOut/configuration.nix" + echo " imports = [" >> "$modulesOut/configuration.nix" + echo " ./test-configuration.nix" >> "$modulesOut/configuration.nix" + echo " ./dynix-vm-configuration.nix" >> "$modulesOut/configuration.nix" + echo " ./hardware-configuration.nix" >> "$modulesOut/configuration.nix" + echo " ];" >> "$modulesOut/configuration.nix" + echo "}" >> "$modulesOut/configuration.nix" + + #mkdir -p "$out" + #cp -r --reflink=auto "$modulesOut/"* "$out/" + + runHook postInstall + ''; + + passthru = { + modulesPath = self.out + "/share/nixos"; + configuration = self.out + "/share/nixos/configuration.nix"; + }; + + meta = { + #outputsToInstall = [ "modules" ]; + }; + }; +in lib.extendMkDerivation { + constructDrv = stdenv.mkDerivation; + extendDrvArgs = mkDynixConfigurationDotNix; +}