diff --git a/src/default.nix b/src/default.nix index 0885211b..cbba34b4 100644 --- a/src/default.nix +++ b/src/default.nix @@ -11,6 +11,7 @@ , findutils , gnused , sshpass +, jq , terraform-docs , lib , makeWrapper @@ -29,6 +30,7 @@ let gnused # needed by ssh-copy-id sshpass # used to provide password for ssh-copy-id gnutar # used to upload extra-files + jq # used for checking if flakeAttr exists ]; in stdenv.mkDerivation { diff --git a/src/nixos-anywhere.sh b/src/nixos-anywhere.sh index 426504f2..3615a9c8 100755 --- a/src/nixos-anywhere.sh +++ b/src/nixos-anywhere.sh @@ -313,6 +313,20 @@ parseArgs() { echo 'For example, to use the output nixosConfigurations.foo from the flake.nix, append "#foo" to the flake-uri.' >&2 exit 1 fi + + # We check if nixosConfigurations."".config.system.build.toplevel exists + # to allow users to use the shorthand $flake#foo. We use `nix flake metadata $flake` + # to add $flake to the store, otherwise relative paths will fail when used with + # `builtins.getFlake`. We use `nix eval --expr ... ? toplevel` to avoid instantiating + # the derivation as this may require building the entire system if the user uses IFD + # like through `system.replaceDependencies`. + if [[ $(nix eval \ + --expr \ + "(builtins.getFlake \"$(nix flake metadata "$flake" --json | jq -r '.path')\").nixosConfigurations.\"$flakeAttr\".config.system.build ? toplevel" \ + --impure 2> /dev/null) == "true" ]]; + then + flakeAttr="nixosConfigurations.\"$flakeAttr\".config" + fi fi } @@ -363,7 +377,7 @@ runVmTest() { --no-link \ -L \ "${nixOptions[@]}" \ - "${flake}#nixosConfigurations.\"${flakeAttr}\".config.system.build.installTest" + "${flake}#${flakeAttr}.system.build.installTest" } uploadSshKey() { @@ -539,11 +553,11 @@ runDisko() { step Building disko script # We need to do a nix copy first because nix build doesn't have --no-check-sigs # Use ssh:// here to avoid https://github.com/NixOS/nix/issues/7359 - nixCopy --to "ssh://$sshConnection" "${flake}#nixosConfigurations.\"${flakeAttr}\".config.system.build.${diskoMode}Script" \ + nixCopy --to "ssh://$sshConnection" "${flake}#${flakeAttr}.system.build.${diskoMode}Script" \ --derivation --no-check-sigs # If we don't use ssh-ng here, we get `error: operation 'getFSAccessor' is not supported by store` diskoScript=$( - nixBuild "${flake}#nixosConfigurations.\"${flakeAttr}\".config.system.build.${diskoMode}Script" \ + nixBuild "${flake}#${flakeAttr}.system.build.${diskoMode}Script" \ --eval-store auto --store "ssh-ng://$sshConnection?ssh-key=$sshKeyDir/nixos-anywhere" ) fi @@ -561,11 +575,11 @@ nixosInstall() { step Building the system closure # We need to do a nix copy first because nix build doesn't have --no-check-sigs # Use ssh:// here to avoid https://github.com/NixOS/nix/issues/7359 - nixCopy --to "ssh://$sshConnection?remote-store=local?root=/mnt" "${flake}#nixosConfigurations.\"${flakeAttr}\".config.system.build.toplevel" \ + nixCopy --to "ssh://$sshConnection?remote-store=local?root=/mnt" "${flake}#${flakeAttr}.system.build.toplevel" \ --derivation --no-check-sigs # If we don't use ssh-ng here, we get `error: operation 'getFSAccessor' is not supported by store` nixosSystem=$( - nixBuild "${flake}#nixosConfigurations.\"${flakeAttr}\".config.system.build.toplevel" \ + nixBuild "${flake}#${flakeAttr}.system.build.toplevel" \ --eval-store auto --store "ssh-ng://$sshConnection?ssh-key=$sshKeyDir/nixos-anywhere&remote-store=local?root=/mnt" ) fi @@ -626,9 +640,9 @@ main() { if [[ -n ${flake} ]]; then if [[ ${buildOnRemote} == "n" ]] && [[ ${hardwareConfigBackend} == "none" ]]; then if [[ ${phases[disko]} == 1 ]]; then - diskoScript=$(nixBuild "${flake}#nixosConfigurations.\"${flakeAttr}\".config.system.build.${diskoMode}Script") + diskoScript=$(nixBuild "${flake}#${flakeAttr}.system.build.${diskoMode}Script") fi - nixosSystem=$(nixBuild "${flake}#nixosConfigurations.\"${flakeAttr}\".config.system.build.toplevel") + nixosSystem=$(nixBuild "${flake}#${flakeAttr}.system.build.toplevel") fi elif [[ -n ${diskoScript} ]] && [[ -n ${nixosSystem} ]]; then if [[ ! -e ${diskoScript} ]] || [[ ! -e ${nixosSystem} ]]; then @@ -684,9 +698,9 @@ main() { if [[ ${buildOnRemote} == "n" ]] && [[ -n ${flake} ]] && [[ ${hardwareConfigBackend} != "none" ]]; then if [[ ${phases[disko]} == 1 ]]; then - diskoScript=$(nixBuild "${flake}#nixosConfigurations.\"${flakeAttr}\".config.system.build.${diskoMode}Script") + diskoScript=$(nixBuild "${flake}#${flakeAttr}.system.build.${diskoMode}Script") fi - nixosSystem=$(nixBuild "${flake}#nixosConfigurations.\"${flakeAttr}\".config.system.build.toplevel") + nixosSystem=$(nixBuild "${flake}#${flakeAttr}.system.build.toplevel") fi # Installation will fail if non-root user is used for installer.