From 25d33070e251d2bee5b1badc8a59d18f9042cccd Mon Sep 17 00:00:00 2001 From: Saber Haj Rabiee Date: Wed, 17 Sep 2025 00:09:40 -0700 Subject: [PATCH 1/7] feat: take into effect system-features --- src/nixos-anywhere.sh | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/nixos-anywhere.sh b/src/nixos-anywhere.sh index 80477425..0f105041 100755 --- a/src/nixos-anywhere.sh +++ b/src/nixos-anywhere.sh @@ -944,6 +944,27 @@ echo "extra-trusted-public-keys = ${trustedPublicKeys}" >> ~/.config/nix/nix.con SSH fi + # Get system-features with a specific cpu architecture from the machine and add them to the installer + if [[ -n ${flake} ]]; then + system_features=$(nix --extra-experimental-features 'nix-command flakes' eval --apply toString "${flake}"#"${flakeAttr}".nix.settings.system-features) + if [[ -z ${system_features} ]]; then + system_features=$(nix config show system-features) + fi + + platform_arch=$(nix --extra-experimental-features 'nix-command flakes' eval --apply 'x: toString (x.nixpkgs.hostPlatform.gcc.arch or "")' "${flake}#${flakeAttr}") + if [[ -n ${platform_arch} ]]; then + system_features="${system_features} gccarch-${platform_arch}" + fi + + # deduplicate the features + system_features=$(echo "${system_features}" | tr ' ' '\n' | sort -u | tr '\n' ' ' | sed 's/ $//') + + runSsh sh <> ~/.config/nix/nix.conf +SSH + fi + if [[ ${phases[disko]} == 1 ]]; then runDisko "$diskoScript" fi From 9a6bb22f4ab0bfa20c31c5cc7b5e72cfbafc3b0b Mon Sep 17 00:00:00 2001 From: Saber Haj Rabiee Date: Mon, 29 Sep 2025 21:27:43 -0700 Subject: [PATCH 2/7] fix: get target default system-features --- src/nixos-anywhere.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nixos-anywhere.sh b/src/nixos-anywhere.sh index 0f105041..58757c1a 100755 --- a/src/nixos-anywhere.sh +++ b/src/nixos-anywhere.sh @@ -948,7 +948,7 @@ SSH if [[ -n ${flake} ]]; then system_features=$(nix --extra-experimental-features 'nix-command flakes' eval --apply toString "${flake}"#"${flakeAttr}".nix.settings.system-features) if [[ -z ${system_features} ]]; then - system_features=$(nix config show system-features) + system_features=$(runSshNoTty -o ConnectTimeout=10 nix --extra-experimental-features 'nix-command' config show system-features) fi platform_arch=$(nix --extra-experimental-features 'nix-command flakes' eval --apply 'x: toString (x.nixpkgs.hostPlatform.gcc.arch or "")' "${flake}#${flakeAttr}") From 24c7cba0c856e17722754433a9ad5dac21927f58 Mon Sep 17 00:00:00 2001 From: Saber Haj Rabiee Date: Mon, 29 Sep 2025 21:41:02 -0700 Subject: [PATCH 3/7] fix: correctly handle not provided system-features --- src/nixos-anywhere.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nixos-anywhere.sh b/src/nixos-anywhere.sh index c4003063..5978c2a8 100755 --- a/src/nixos-anywhere.sh +++ b/src/nixos-anywhere.sh @@ -1050,7 +1050,7 @@ SSH # Get system-features with a specific cpu architecture from the machine and add them to the installer if [[ -n ${flake} ]]; then - system_features=$(nix --extra-experimental-features 'nix-command flakes' eval --apply toString "${flake}"#"${flakeAttr}".nix.settings.system-features) + system_features=$(nix --extra-experimental-features 'nix-command flakes' eval --apply 'x: toString (x.nix.settings.system-features or "")' "${flake}#${flakeAttr}") if [[ -z ${system_features} ]]; then system_features=$(runSshNoTty -o ConnectTimeout=10 nix --extra-experimental-features 'nix-command' config show system-features) fi From d229c4e832ebd3ba62057b673dc353d096891394 Mon Sep 17 00:00:00 2001 From: Saber Haj Rabiee Date: Mon, 29 Sep 2025 21:50:05 -0700 Subject: [PATCH 4/7] fix: ssh command should fail if it couldn't set the system-features --- src/nixos-anywhere.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nixos-anywhere.sh b/src/nixos-anywhere.sh index 5978c2a8..efa89c01 100755 --- a/src/nixos-anywhere.sh +++ b/src/nixos-anywhere.sh @@ -1063,7 +1063,7 @@ SSH # deduplicate the features system_features=$(echo "${system_features}" | tr ' ' '\n' | sort -u | tr '\n' ' ' | sed 's/ $//') - runSsh sh <> ~/.config/nix/nix.conf SSH From b5793e8243720fa96ed2b1eac62c787487f23300 Mon Sep 17 00:00:00 2001 From: Saber Haj Rabiee Date: Tue, 30 Sep 2025 05:28:42 -0700 Subject: [PATCH 5/7] feat: simplify and unify writing in nix.conf MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jörg Thalheim --- src/nixos-anywhere.sh | 75 +++++++++++++++++++++++++++---------------- 1 file changed, 47 insertions(+), 28 deletions(-) diff --git a/src/nixos-anywhere.sh b/src/nixos-anywhere.sh index efa89c01..c04d1365 100755 --- a/src/nixos-anywhere.sh +++ b/src/nixos-anywhere.sh @@ -1036,37 +1036,56 @@ main() { sshConnection="root@${sshHost}" fi - # Get substituters from the machine and add them to the installer - if [[ ${machineSubstituters} == "y" && -n ${flake} ]]; then - substituters=$(nix --extra-experimental-features 'nix-command flakes' eval --apply toString "${flake}"#"${flakeAttr}".nix.settings.substituters) - trustedPublicKeys=$(nix --extra-experimental-features 'nix-command flakes' eval --apply toString "${flake}"#"${flakeAttr}".nix.settings.trusted-public-keys) - - runSsh sh <> ~/.config/nix/nix.conf -echo "extra-trusted-public-keys = ${trustedPublicKeys}" >> ~/.config/nix/nix.conf -SSH - fi - - # Get system-features with a specific cpu architecture from the machine and add them to the installer if [[ -n ${flake} ]]; then - system_features=$(nix --extra-experimental-features 'nix-command flakes' eval --apply 'x: toString (x.nix.settings.system-features or "")' "${flake}#${flakeAttr}") - if [[ -z ${system_features} ]]; then - system_features=$(runSshNoTty -o ConnectTimeout=10 nix --extra-experimental-features 'nix-command' config show system-features) - fi - - platform_arch=$(nix --extra-experimental-features 'nix-command flakes' eval --apply 'x: toString (x.nixpkgs.hostPlatform.gcc.arch or "")' "${flake}#${flakeAttr}") - if [[ -n ${platform_arch} ]]; then - system_features="${system_features} gccarch-${platform_arch}" - fi - - # deduplicate the features - system_features=$(echo "${system_features}" | tr ' ' '\n' | sort -u | tr '\n' ' ' | sed 's/ $//') - - runSsh sh </dev/null || true) + + # First, try to evaluate all nix settings from the flake in one go + nixConfContent=$(nix --extra-experimental-features 'nix-command flakes' eval --raw --apply " + config: + let + settings = config.nix.settings or {}; + gccArch = config.nixpkgs.hostPlatform.gcc.arch or null; + + # Check if system-features are defined in configuration + configFeatures = settings.system-features or null; + hasConfigFeatures = configFeatures != null && configFeatures != []; + + remoteFeatures = let + remoteFeaturesStr = \"${system_features}\"; + # Parse remote features string (space-separated) into list + remoteFeaturesList = if remoteFeaturesStr != \"\" then + builtins.filter (x: x != \"\") (builtins.split \" +\" remoteFeaturesStr) + else []; + in remoteFeaturesList; + + # Combine base features (config or remote) with platform-specific features + baseFeatures = if hasConfigFeatures then configFeatures else remoteFeatures; + # At least one of nix.settings.system-features or nixpkgs.hostPlatform.gcc.arch has been explicitly defined + allFeatures = if (gccArch != null) || hasConfigFeatures then baseFeatures ++ (if gccArch != null then [\"gccarch-\${gccArch}\"] else []) else []; + + # Deduplicate using listToAttrs trick + uniqueFeatures = builtins.attrNames (builtins.listToAttrs (map (f: { name = f; value = true; }) allFeatures)); + + substituters = builtins.toString (settings.substituters or []); + trustedPublicKeys = builtins.toString (settings.trusted-public-keys or []); + systemFeatures = builtins.toString uniqueFeatures; + + # Helper function for optional config lines + optionalLine = cond: line: if cond then line + \"\n\" else \"\"; + useSubstituters = \"${machineSubstituters}\" == \"y\"; + in + optionalLine (useSubstituters && substituters != \"\") \"extra-substituters = \${substituters}\" + + optionalLine (useSubstituters && trustedPublicKeys != \"\") \"extra-trusted-public-keys = \${trustedPublicKeys}\" + + optionalLine (systemFeatures != \"\") \"system-features = \${systemFeatures}\" + " "${flake}#${flakeAttr}") + + # Write to nix.conf if we have any content + if [[ -n ${nixConfContent} ]]; then + runSsh sh <> ~/.config/nix/nix.conf +echo "${nixConfContent}" >> ~/.config/nix/nix.conf SSH + fi fi if [[ ${phases[disko]} == 1 ]]; then From e174e75ccc6e54161ebcdde9997cd3d493130c6c Mon Sep 17 00:00:00 2001 From: Saber Haj Rabiee Date: Tue, 30 Sep 2025 05:33:51 -0700 Subject: [PATCH 6/7] fix: formatting --- src/nixos-anywhere.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nixos-anywhere.sh b/src/nixos-anywhere.sh index c04d1365..0e032cec 100755 --- a/src/nixos-anywhere.sh +++ b/src/nixos-anywhere.sh @@ -1079,7 +1079,7 @@ main() { + optionalLine (systemFeatures != \"\") \"system-features = \${systemFeatures}\" " "${flake}#${flakeAttr}") - # Write to nix.conf if we have any content + # Write to nix.conf if we have any content if [[ -n ${nixConfContent} ]]; then runSsh sh < Date: Tue, 30 Sep 2025 05:59:49 -0700 Subject: [PATCH 7/7] fix: make runSshNoTty fallible for system_features and escape bash variables --- src/nixos-anywhere.sh | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/nixos-anywhere.sh b/src/nixos-anywhere.sh index 0e032cec..8a6f5654 100755 --- a/src/nixos-anywhere.sh +++ b/src/nixos-anywhere.sh @@ -1037,8 +1037,9 @@ main() { fi if [[ -n ${flake} ]]; then - system_features=$(runSshNoTty -o ConnectTimeout=10 nix --extra-experimental-features 'nix-command' config show system-features 2>/dev/null || true) - + system_features=$(runSshNoTty -o ConnectTimeout=10 nix --extra-experimental-features 'nix-command' config show system-features) + # Escape the bash variable for safe interpolation into Nix + system_features="$(printf '%s' "$system_features" | sed 's/\\/\\\\/g; s/"/\\"/g')" # First, try to evaluate all nix settings from the flake in one go nixConfContent=$(nix --extra-experimental-features 'nix-command flakes' eval --raw --apply " config: @@ -1054,7 +1055,7 @@ main() { remoteFeaturesStr = \"${system_features}\"; # Parse remote features string (space-separated) into list remoteFeaturesList = if remoteFeaturesStr != \"\" then - builtins.filter (x: x != \"\") (builtins.split \" +\" remoteFeaturesStr) + builtins.filter (x: builtins.isString x && x != \"\") (builtins.split \" +\" remoteFeaturesStr) else []; in remoteFeaturesList; @@ -1083,7 +1084,10 @@ main() { if [[ -n ${nixConfContent} ]]; then runSsh sh <> ~/.config/nix/nix.conf +printf '%s\n' "\$(cat <<'CONTENT' +${nixConfContent} +CONTENT +)" >> ~/.config/nix/nix.conf SSH fi fi