diff --git a/nixos/modules/installer/tools/manpages/nixos-install.8 b/nixos/modules/installer/tools/manpages/nixos-install.8 index c6c8ed15224d..e1af90a37d76 100644 --- a/nixos/modules/installer/tools/manpages/nixos-install.8 +++ b/nixos/modules/installer/tools/manpages/nixos-install.8 @@ -14,6 +14,8 @@ .Op Fl -root Ar root .Op Fl -system Ar path .Op Fl -flake Ar flake-uri +.Op Fl -file | f Ar path +.Op Fl -attr | A Ar attrPath .Op Fl -impure .Op Fl -channel Ar channel .Op Fl -no-channel-copy @@ -111,6 +113,32 @@ output named .Ql nixosConfigurations. Ns Ar name Ns \&. . +.It Fl -file Ar path , Fl f Ar path +Enable and build the NixOS system from the specified file. The file must +evaluate to an attribute set, and it must contain a valid NixOS configuration +at attribute +.Va attrPath Ns +\&. This is useful for building a NixOS system from a nix file that is not +a flake or a NixOS configuration module. Attribute set a with valid NixOS +configuration can be made using +.Va nixos +function in nixpkgs or importing and calling +.Pa nixos/lib/eval-config.nix +from nixpkgs. If specified without +.Fl -attr +option, builds the configuration from the top-level +attribute of the file. +. +.It Fl -attr Ar attrPath , Fl A Ar attrPath +Enable and build the NixOS system from nix file and use the specified attribute +path from file specified by the +.Fl -file +option. If specified without +.Fl -file +option, uses +.Va [root] Ns Pa /etc/nixos/default.nix Ns +\&. +. .It Fl -channel Ar channel If this option is provided, do not copy the current .Dq nixos diff --git a/nixos/modules/installer/tools/nixos-install.sh b/nixos/modules/installer/tools/nixos-install.sh index 4e42875c0365..a76b4ffb4444 100755 --- a/nixos/modules/installer/tools/nixos-install.sh +++ b/nixos/modules/installer/tools/nixos-install.sh @@ -17,6 +17,9 @@ mountPoint=/mnt channelPath= system= verbosity=() +attr= +buildFile= +buildingAttribute=1 while [ "$#" -gt 0 ]; do i="$1"; shift 1 @@ -41,6 +44,24 @@ while [ "$#" -gt 0 ]; do flakeFlags=(--experimental-features 'nix-command flakes') shift 1 ;; + --file|-f) + if [ -z "$1" ]; then + log "$0: '$i' requires an argument" + exit 1 + fi + buildFile="$1" + buildingAttribute= + shift 1 + ;; + --attr|-A) + if [ -z "$1" ]; then + log "$0: '$i' requires an argument" + exit 1 + fi + attr="$1" + buildingAttribute= + shift 1 + ;; --recreate-lock-file|--no-update-lock-file|--no-write-lock-file|--no-registries|--commit-lock-file) lockFlags+=("$i") ;; @@ -101,17 +122,30 @@ while [[ "$checkPath" != "/" ]]; do checkPath="$(dirname "$checkPath")" done -# Get the path of the NixOS configuration file. -if [[ -z $NIXOS_CONFIG ]]; then - NIXOS_CONFIG=$mountPoint/etc/nixos/configuration.nix -fi - -if [[ ${NIXOS_CONFIG:0:1} != / ]]; then - echo "$0: \$NIXOS_CONFIG is not an absolute path" +# Verify that user is not trying to use attribute building and flake +# at the same time +if [[ -z $buildingAttribute && -n $flake ]]; then + echo "$0: '--flake' cannot be used with '--file' or '--attr'" exit 1 fi -if [[ -n $flake ]]; then +# Get the path of the NixOS configuration file. +if [[ -z $flake && -n $buildingAttribute ]]; then + if [[ -z $NIXOS_CONFIG ]]; then + NIXOS_CONFIG=$mountPoint/etc/nixos/configuration.nix + fi + + if [[ ${NIXOS_CONFIG:0:1} != / ]]; then + echo "$0: \$NIXOS_CONFIG is not an absolute path" + exit 1 + fi +elif [[ -z $buildingAttribute ]]; then + if [[ -z $buildFile ]]; then + buildFile="$mountPoint/etc/nixos/default.nix" + elif [[ -d $buildFile ]]; then + buildFile="$buildFile/default.nix" + fi +elif [[ -n $flake ]]; then if [[ $flake =~ ^(.*)\#([^\#\"]*)$ ]]; then flake="${BASH_REMATCH[1]}" flakeAttr="${BASH_REMATCH[2]}" @@ -129,11 +163,16 @@ if [[ -n $flake ]]; then flake=$(nix "${flakeFlags[@]}" flake metadata --json "${extraBuildFlags[@]}" "${lockFlags[@]}" -- "$flake" | jq -r .url) fi -if [[ ! -e $NIXOS_CONFIG && -z $system && -z $flake ]]; then +if [[ ! -e $NIXOS_CONFIG && -z $system && -z $flake && -n $buildingAttribute ]]; then echo "configuration file $NIXOS_CONFIG doesn't exist" exit 1 fi +if [[ ! -z $buildingAttribute && -e $buildFile && -z $system ]]; then + echo "configuration file $buildFile doesn't exist" + exit 1 +fi + # A place to drop temporary stuff. tmpdir="$(mktemp -d -p "$mountPoint")" trap 'rm -rf $tmpdir' EXIT @@ -163,11 +202,20 @@ fi # Build the system configuration in the target filesystem. if [[ -z $system ]]; then outLink="$tmpdir/system" - if [[ -z $flake ]]; then + if [[ -z $flake && -n $buildingAttribute ]]; then echo "building the configuration in $NIXOS_CONFIG..." nix-build --out-link "$outLink" --store "$mountPoint" "${extraBuildFlags[@]}" \ --extra-substituters "$sub" \ '' -A system -I "nixos-config=$NIXOS_CONFIG" "${verbosity[@]}" + elif [[ -z $buildingAttribute ]]; then + if [[ -n $attr ]]; then + echo "building the configuration in $buildFile and attribute $attr..." + else + echo "building the configuration in $buildFile..." + fi + nix-build --out-link "$outLink" --store "$mountPoint" "${extraBuildFlags[@]}" \ + --extra-substituters "$sub" \ + "$buildFile" -A "${attr:+$attr.}config.system.build.toplevel" "${verbosity[@]}" else echo "building the flake in $flake..." nix "${flakeFlags[@]}" build "$flake#$flakeAttr.config.system.build.toplevel" \ diff --git a/nixos/tests/installer.nix b/nixos/tests/installer.nix index bb6ad79615fa..49c50a6f5a3a 100644 --- a/nixos/tests/installer.nix +++ b/nixos/tests/installer.nix @@ -11,7 +11,7 @@ let # The configuration to install. makeConfig = { bootLoader, grubDevice, grubIdentifier, grubUseEfi - , extraConfig, forceGrubReinstallCount ? 0, flake ? false + , extraConfig, forceGrubReinstallCount ? 0, withTestInstrumentation ? true , clevisTest }: pkgs.writeText "configuration.nix" '' @@ -19,7 +19,7 @@ let { imports = [ ./hardware-configuration.nix - ${if flake + ${if !withTestInstrumentation then "" # Still included, but via installer/flake.nix else ""} ]; @@ -81,7 +81,7 @@ let # partitions and filesystems. testScriptFun = { bootLoader, createPartitions, grubDevice, grubUseEfi, grubIdentifier , postInstallCommands, postBootCommands, extraConfig - , testSpecialisationConfig, testFlakeSwitch, clevisTest, clevisFallbackTest + , testSpecialisationConfig, testFlakeSwitch, testByAttrSwitch, clevisTest, clevisFallbackTest , disableFileSystems }: let @@ -316,6 +316,119 @@ let target.shutdown() '' + + optionalString testByAttrSwitch '' + with subtest("Configure system with attribute set"): + target.succeed(""" + mkdir /root/my-config + mv /etc/nixos/hardware-configuration.nix /root/my-config/ + rm /etc/nixos/configuration.nix + """) + target.copy_from_host_via_shell( + "${makeConfig { + inherit bootLoader grubDevice grubIdentifier grubUseEfi extraConfig clevisTest; + forceGrubReinstallCount = 1; + withTestInstrumentation = false; + }}", + "/root/my-config/configuration.nix", + ) + target.copy_from_host_via_shell( + "${./installer/byAttrWithChannel.nix}", + "/root/my-config/default.nix", + ) + with subtest("Switch to attribute set based config with channels"): + target.succeed("nixos-rebuild switch --file /root/my-config/default.nix") + + target.shutdown() + + ${startTarget} + + target.succeed(""" + rm /root/my-config/default.nix + """) + target.copy_from_host_via_shell( + "${./installer/byAttrNoChannel.nix}", + "/root/my-config/default.nix", + ) + + target.succeed(""" + pkgs=$(readlink -f /nix/var/nix/profiles/per-user/root/channels)/nixos + if ! [[ -e $pkgs/pkgs/top-level/default.nix ]]; then + echo 1>&2 "$pkgs does not seem to be a nixpkgs source. Please fix the test so that pkgs points to a nixpkgs source."; + exit 1; + fi + sed -e s^@nixpkgs@^$pkgs^ -i /root/my-config/default.nix + + """) + + with subtest("Switch to attribute set based config without channels"): + target.succeed("nixos-rebuild switch --file /root/my-config/default.nix") + + target.shutdown() + + ${startTarget} + + with subtest("nix-channel command is not available anymore"): + target.succeed("! which nix-channel") + + with subtest("builtins.nixPath is now empty"): + target.succeed(""" + [[ "[ ]" == "$(nix-instantiate builtins.nixPath --eval --expr)" ]] + """) + + with subtest(" does not resolve"): + target.succeed(""" + ! nix-instantiate '' --eval --expr + """) + + with subtest("Evaluate attribute set based config in fresh env without nix-channel"): + target.succeed("nixos-rebuild switch --file /root/my-config/default.nix") + + with subtest("Evaluate attribute set based config in fresh env without channel profiles"): + target.succeed(""" + ( + exec 1>&2 + mkdir -p /root/restore + mv -v /root/.nix-channels /root/restore/ + mv -v ~/.nix-defexpr /root/restore/ + mkdir -p /root/restore/channels + mv -v /nix/var/nix/profiles/per-user/root/channels* /root/restore/channels/ + ) + """) + target.succeed("nixos-rebuild switch --file /root/my-config/default.nix") + '' + + optionalString (testByAttrSwitch && testFlakeSwitch) '' + with subtest("Restore channel profiles"): + target.succeed(""" + ( + exec 1>&2 + mv -v /root/restore/.nix-channels /root/ + mv -v /root/restore/.nix-defexpr ~/.nix-defexpr + mv -v /root/restore/channels/* /nix/var/nix/profiles/per-user/root/ + rm -vrf /root/restore + ) + """) + + with subtest("Restore /etc/nixos"): + target.succeed(""" + mv -v /root/my-config/hardware-configuration.nix /etc/nixos/ + """) + target.copy_from_host_via_shell( + "${makeConfig { + inherit bootLoader grubDevice grubIdentifier grubUseEfi extraConfig clevisTest; + forceGrubReinstallCount = 1; + }}", + "/etc/nixos/configuration.nix", + ) + + with subtest("Restore /root/my-config"): + target.succeed(""" + rm -vrf /root/my-config + """) + + '' + + optionalString (testByAttrSwitch && !testFlakeSwitch) '' + target.shutdown() + '' + optionalString testFlakeSwitch '' ${startTarget} @@ -330,7 +443,7 @@ let "${makeConfig { inherit bootLoader grubDevice grubIdentifier grubUseEfi extraConfig clevisTest; forceGrubReinstallCount = 1; - flake = true; + withTestInstrumentation = false; }}", "/root/my-config/configuration.nix", ) @@ -399,6 +512,7 @@ let , enableOCR ? false, meta ? {} , testSpecialisationConfig ? false , testFlakeSwitch ? false + , testByAttrSwitch ? false , clevisTest ? false , clevisFallbackTest ? false , disableFileSystems ? false @@ -533,7 +647,7 @@ let testScript = testScriptFun { inherit bootLoader createPartitions postInstallCommands postBootCommands grubDevice grubIdentifier grubUseEfi extraConfig - testSpecialisationConfig testFlakeSwitch clevisTest clevisFallbackTest + testSpecialisationConfig testFlakeSwitch testByAttrSwitch clevisTest clevisFallbackTest disableFileSystems; }; }; @@ -589,6 +703,15 @@ let testFlakeSwitch = true; }; + simple-test-config-by-attr = simple-test-config // { + testByAttrSwitch = true; + }; + + simple-test-config-from-by-attr-to-flake = simple-test-config // { + testByAttrSwitch = true; + testFlakeSwitch = true; + }; + simple-uefi-grub-config = { createPartitions = '' installer.succeed( @@ -782,6 +905,10 @@ in { switchToFlake = makeInstallerTest "switch-to-flake" simple-test-config-flake; + switchToByAttr = makeInstallerTest "switch-to-by-attr" simple-test-config-by-attr; + + switchFromByAttrToFlake = makeInstallerTest "switch-from-by-attr-to-flake" simple-test-config-from-by-attr-to-flake; + # Test cloned configurations with the simple grub configuration simpleSpecialised = makeInstallerTest "simpleSpecialised" (simple-test-config // specialisation-test-extraconfig); diff --git a/nixos/tests/installer/byAttrNoChannel.nix b/nixos/tests/installer/byAttrNoChannel.nix new file mode 100644 index 000000000000..03293cd4a0e3 --- /dev/null +++ b/nixos/tests/installer/byAttrNoChannel.nix @@ -0,0 +1,18 @@ +# This file gets copied into the installation + +let + nixpkgs = "@nixpkgs@"; +in + +{ evalConfig ? import "${nixpkgs}/nixos/lib/eval-config.nix" }: + +evalConfig { + modules = [ + ./configuration.nix + ( import "${nixpkgs}/nixos/modules/testing/test-instrumentation.nix" ) + { + # Disable nix channels + nix.channel.enable = false; + } + ]; +} diff --git a/nixos/tests/installer/byAttrWithChannel.nix b/nixos/tests/installer/byAttrWithChannel.nix new file mode 100644 index 000000000000..951231dcba3e --- /dev/null +++ b/nixos/tests/installer/byAttrWithChannel.nix @@ -0,0 +1,10 @@ +# This file gets copied into the installation + +{ evalConfig ? import }: + +evalConfig { + modules = [ + ./configuration.nix + ( import ) + ]; +} diff --git a/pkgs/os-specific/linux/nixos-rebuild/nixos-rebuild.8 b/pkgs/os-specific/linux/nixos-rebuild/nixos-rebuild.8 index 89c8e511154d..9ef46b564dda 100644 --- a/pkgs/os-specific/linux/nixos-rebuild/nixos-rebuild.8 +++ b/pkgs/os-specific/linux/nixos-rebuild/nixos-rebuild.8 @@ -19,6 +19,8 @@ .Op Fl -fast .Op Fl -rollback .br +.Op Fl -file | f Ar path +.Op Fl -attr | A Ar attrPath .Op Fl -flake Ar flake-uri .Op Fl -no-flake .Op Fl -recreate-lock-file @@ -62,11 +64,15 @@ .Sh DESCRIPTION This command updates the system so that it corresponds to the configuration specified in -.Pa /etc/nixos/configuration.nix -or -.Pa /etc/nixos/flake.nix Ns -\&. Thus, every time you modify the configuration or any other NixOS module, you -must run +.Pa /etc/nixos/configuration.nix Ns +, +.Pa /etc/nixos/flake.nix +or the file and attribute specified by the +.Fl -file +and/or +.Fl -attr +options. Thus, every time you modify the configuration or any other NixOS +module, you must run .Nm to make the changes take effect. It builds the new system in .Pa /nix/store Ns @@ -386,6 +392,32 @@ system with .Ic sudo Ns \&. Setting this option allows deploying as a non-root user. . +.It Fl -file Ar path , Fl f Ar path +Enable and build the NixOS system from the specified file. The file must +evaluate to an attribute set, and it must contain a valid NixOS configuration +at attribute +.Va attrPath Ns +\&. This is useful for building a NixOS system from a nix file that is not +a flake or a NixOS configuration module. Attribute set a with valid NixOS +configuration can be made using +.Va nixos +function in nixpkgs or importing and calling +.Pa nixos/lib/eval-config.nix +from nixpkgs. If specified without +.Fl -attr +option, builds the configuration from the top-level +attribute of the file. +. +.It Fl -attr Ar attrPath , Fl A Ar attrPath +Enable and build the NixOS system from nix file and use the specified attribute +path from file specified by the +.Fl -file +option. If specified without +.Fl -file +option, uses +.Pa default.nix +in current directory. +. .It Fl -flake Va flake-uri Ns Op Va #name Build the NixOS system from the specified flake. It defaults to the directory containing the target of the symlink diff --git a/pkgs/os-specific/linux/nixos-rebuild/nixos-rebuild.sh b/pkgs/os-specific/linux/nixos-rebuild/nixos-rebuild.sh index fb7c8b2322a7..03b2dbfbeb66 100755 --- a/pkgs/os-specific/linux/nixos-rebuild/nixos-rebuild.sh +++ b/pkgs/os-specific/linux/nixos-rebuild/nixos-rebuild.sh @@ -34,6 +34,9 @@ targetHost= remoteSudo= verboseScript= noFlake= +attr= +buildFile=default.nix +buildingAttribute=1 installBootloader= json= @@ -58,6 +61,24 @@ while [ "$#" -gt 0 ]; do if [ -n "$action" ]; then showSyntax; fi action="$i" ;; + --file|-f) + if [ -z "$1" ]; then + log "$0: '$i' requires an argument" + exit 1 + fi + buildFile="$1" + buildingAttribute= + shift 1 + ;; + --attr|-A) + if [ -z "$1" ]; then + log "$0: '$i' requires an argument" + exit 1 + fi + attr="$1" + buildingAttribute= + shift 1 + ;; --install-grub) log "$0: --install-grub deprecated, use --install-bootloader instead" installBootloader=1 @@ -345,6 +366,12 @@ if [[ "$action" = switch || "$action" = boot || "$action" = test ]]; then canRun=1 fi +# Verify that user is not trying to use attribute building and flake +# at the same time +if [[ -z $buildingAttribute && -n $flake ]]; then + log "error: '--flake' cannot be used with '--file' or '--attr'" + exit 1 +fi # If ‘--upgrade’ or `--upgrade-all` is given, # run ‘nix-channel --update nixos’. @@ -426,7 +453,10 @@ trap cleanup EXIT # Re-execute nixos-rebuild from the Nixpkgs tree. if [[ -z $_NIXOS_REBUILD_REEXEC && -n $canRun && -z $fast ]]; then - if [[ -z $flake ]]; then + if [[ -z $buildingAttribute ]]; then + p=$(runCmd nix-build --no-out-link $buildFile -A "${attr:+$attr.}config.system.build.nixos-rebuild" "${extraBuildFlags[@]}") + SHOULD_REEXEC=1 + elif [[ -z $flake ]]; then if p=$(runCmd nix-build --no-out-link --expr 'with import {}; config.system.build.nixos-rebuild' "${extraBuildFlags[@]}"); then SHOULD_REEXEC=1 fi @@ -448,7 +478,10 @@ fi # Find configuration.nix and open editor instead of building. if [ "$action" = edit ]; then - if [[ -z $flake ]]; then + if [[ -n $attr || -n $buildFile ]]; then + log "error: '--file' and '--attr' are not supported with 'edit'" + exit 1 + elif [[ -z $flake ]]; then NIXOS_CONFIG=${NIXOS_CONFIG:-$(runCmd nix-instantiate --find-file nixos-config)} if [[ -d $NIXOS_CONFIG ]]; then NIXOS_CONFIG=$NIXOS_CONFIG/default.nix @@ -490,31 +523,38 @@ prebuiltNix() { fi } -if [[ -n $buildNix && -z $flake ]]; then - log "building Nix..." +getNixDrv() { nixDrv= - if ! nixDrv="$(runCmd nix-instantiate '' --add-root "$tmpDir/nix.drv" --indirect -A config.nix.package.out "${extraBuildFlags[@]}")"; then - if ! nixDrv="$(runCmd nix-instantiate '' --add-root "$tmpDir/nix.drv" --indirect -A nix "${extraBuildFlags[@]}")"; then - if ! nixStorePath="$(runCmd nix-instantiate --eval '' -A "$(nixSystem)" | sed -e 's/^"//' -e 's/"$//')"; then - nixStorePath="$(prebuiltNix "$(uname -m)")" - fi - if ! runCmd nix-store -r "$nixStorePath" --add-root "${tmpDir}/nix" --indirect \ - --option extra-binary-caches https://cache.nixos.org/; then - log "warning: don't know how to get latest Nix" - fi - # Older version of nix-store -r don't support --add-root. - [ -e "$tmpDir/nix" ] || ln -sf "$nixStorePath" "$tmpDir/nix" - if [ -n "$buildHost" ]; then - remoteNixStorePath="$(runCmd prebuiltNix "$(buildHostCmd uname -m)")" - remoteNix="$remoteNixStorePath/bin" - if ! buildHostCmd nix-store -r "$remoteNixStorePath" \ - --option extra-binary-caches https://cache.nixos.org/ >/dev/null; then - remoteNix= - log "warning: don't know how to get latest Nix" - fi - fi + + if [[ -z $buildingAttribute ]]; then + if nixDrv="$(runCmd nix-instantiate $buildFile --add-root "$tmpDir/nix.drv" --indirect -A ${attr:+$attr.}config.nix.package.out "${extraBuildFlags[@]}")"; then return; fi + fi + if nixDrv="$(runCmd nix-instantiate '' --add-root "$tmpDir/nix.drv" --indirect -A config.nix.package.out "${extraBuildFlags[@]}")"; then return; fi + if nixDrv="$(runCmd nix-instantiate '' --add-root "$tmpDir/nix.drv" --indirect -A nix "${extraBuildFlags[@]}")"; then return; fi + + if ! nixStorePath="$(runCmd nix-instantiate --eval '' -A "$(nixSystem)" | sed -e 's/^"//' -e 's/"$//')"; then + nixStorePath="$(prebuiltNix "$(uname -m)")" + fi + if ! runCmd nix-store -r "$nixStorePath" --add-root "${tmpDir}/nix" --indirect \ + --option extra-binary-caches https://cache.nixos.org/; then + log "warning: don't know how to get latest Nix" + fi + # Older version of nix-store -r don't support --add-root. + [ -e "$tmpDir/nix" ] || ln -sf "$nixStorePath" "$tmpDir/nix" + if [ -n "$buildHost" ]; then + remoteNixStorePath="$(runCmd prebuiltNix "$(buildHostCmd uname -m)")" + remoteNix="$remoteNixStorePath/bin" + if ! buildHostCmd nix-store -r "$remoteNixStorePath" \ + --option extra-binary-caches https://cache.nixos.org/ >/dev/null; then + remoteNix= + log "warning: don't know how to get latest Nix" fi fi +} + +if [[ -n $buildNix && -z $flake ]]; then + log "building Nix..." + getNixDrv if [ -a "$nixDrv" ]; then nix-store -r "$nixDrv"'!'"out" --add-root "$tmpDir/nix" --indirect >/dev/null if [ -n "$buildHost" ]; then @@ -549,7 +589,9 @@ if [ "$action" = repl ]; then # This is a very end user command, implemented using sub-optimal means. # You should feel free to improve its behavior, as well as resolve tech # debt in "breaking" ways. Humans adapt quite well. - if [[ -z $flake ]]; then + if [[ -z $buildingAttribute ]]; then + exec nix repl --file $buildFile $attr "${extraBuildFlags[@]}" + elif [[ -z $flake ]]; then exec nix repl '' "${extraBuildFlags[@]}" else if [[ -n "${lockFlags[0]}" ]]; then @@ -702,7 +744,9 @@ fi if [ -z "$rollback" ]; then log "building the system configuration..." if [[ "$action" = switch || "$action" = boot ]]; then - if [[ -z $flake ]]; then + if [[ -z $buildingAttribute ]]; then + pathToConfig="$(nixBuild $buildFile -A "${attr:+$attr.}config.system.build.toplevel" "${extraBuildFlags[@]}")" + elif [[ -z $flake ]]; then pathToConfig="$(nixBuild '' --no-out-link -A system "${extraBuildFlags[@]}")" else pathToConfig="$(nixFlakeBuild "$flake#$flakeAttr.config.system.build.toplevel" "${extraBuildFlags[@]}" "${lockFlags[@]}")" @@ -710,19 +754,25 @@ if [ -z "$rollback" ]; then copyToTarget "$pathToConfig" targetHostSudoCmd nix-env -p "$profile" --set "$pathToConfig" elif [[ "$action" = test || "$action" = build || "$action" = dry-build || "$action" = dry-activate ]]; then - if [[ -z $flake ]]; then + if [[ -z $buildingAttribute ]]; then + pathToConfig="$(nixBuild $buildFile -A "${attr:+$attr.}config.system.build.toplevel" "${extraBuildFlags[@]}")" + elif [[ -z $flake ]]; then pathToConfig="$(nixBuild '' -A system -k "${extraBuildFlags[@]}")" else pathToConfig="$(nixFlakeBuild "$flake#$flakeAttr.config.system.build.toplevel" "${extraBuildFlags[@]}" "${lockFlags[@]}")" fi elif [ "$action" = build-vm ]; then - if [[ -z $flake ]]; then + if [[ -z $buildingAttribute ]]; then + pathToConfig="$(nixBuild $buildFile -A "${attr:+$attr.}config.system.build.vm" "${extraBuildFlags[@]}")" + elif [[ -z $flake ]]; then pathToConfig="$(nixBuild '' -A vm -k "${extraBuildFlags[@]}")" else pathToConfig="$(nixFlakeBuild "$flake#$flakeAttr.config.system.build.vm" "${extraBuildFlags[@]}" "${lockFlags[@]}")" fi elif [ "$action" = build-vm-with-bootloader ]; then - if [[ -z $flake ]]; then + if [[ -z $buildingAttribute ]]; then + pathToConfig="$(nixBuild $buildFile -A "${attr:+$attr.}config.system.build.vmWithBootLoader" "${extraBuildFlags[@]}")" + elif [[ -z $flake ]]; then pathToConfig="$(nixBuild '' -A vmWithBootLoader -k "${extraBuildFlags[@]}")" else pathToConfig="$(nixFlakeBuild "$flake#$flakeAttr.config.system.build.vmWithBootLoader" "${extraBuildFlags[@]}" "${lockFlags[@]}")"