Skip to content

Commit

Permalink
nixos-anywhere: allow users to specify custom path NixOS configurations
Browse files Browse the repository at this point in the history
This is useful for users who use a similar `extendModules` pattern like
`virtualisation.vmVariant`, where an extended NixOS configuration lives
inside an existing configuration:

    nixos-anywhere --flake .#nixosConfigurations.alpha.config.virtualisation.vmVariant
  • Loading branch information
Enzime committed Nov 29, 2024
1 parent 80a2e7d commit 9eff6ec
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 9 deletions.
2 changes: 2 additions & 0 deletions src/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
, findutils
, gnused
, sshpass
, jq
, terraform-docs
, lib
, makeWrapper
Expand All @@ -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 {
Expand Down
32 changes: 23 additions & 9 deletions src/nixos-anywhere.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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."<flakeAttr>".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

}
Expand Down Expand Up @@ -363,7 +377,7 @@ runVmTest() {
--no-link \
-L \
"${nixOptions[@]}" \
"${flake}#nixosConfigurations.\"${flakeAttr}\".config.system.build.installTest"
"${flake}#${flakeAttr}.system.build.installTest"
}

uploadSshKey() {
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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.
Expand Down

0 comments on commit 9eff6ec

Please sign in to comment.