@@ -64,7 +64,7 @@ mkdir -p "$tempDir"
6464
6565declare -A diskEncryptionKeys=()
6666declare -A extraFilesOwnership=()
67- declare -a nixCopyOptions=()
67+ declare -a nixCopyOptions=(--no-check-sigs )
6868declare -a sshArgs=(" -o" " IdentitiesOnly=yes" " -i" " $tempDir /nixos-anywhere" " -o" " UserKnownHostsFile=/dev/null" " -o" " StrictHostKeyChecking=no" )
6969
7070showUsage () {
@@ -420,19 +420,76 @@ runSsh() {
420420 ssh " $sshTtyParam " " ${sshArgs[@]} " " $sshConnection " " $@ "
421421}
422422
423+ buildStoreUrl () {
424+ local storeUrl=" $1 "
425+
426+ # Add sshStoreSettings if present
427+ if [[ -n ${sshStoreSettings} ]] && [[ $storeUrl == ssh-ng://* ]]; then
428+ if [[ $storeUrl == * " ?" * ]]; then
429+ storeUrl=" ${storeUrl} &${sshStoreSettings} "
430+ else
431+ storeUrl=" ${storeUrl} ?${sshStoreSettings} "
432+ fi
433+ fi
434+
435+ # Add remote-program parameter when sudo is needed
436+ if [[ -n ${maybeSudo} ]] && [[ $storeUrl == ssh-ng://* ]]; then
437+ if [[ $storeUrl == * " ?" * ]]; then
438+ storeUrl=" ${storeUrl} &remote-program=${maybeSudo} nix-daemon"
439+ else
440+ storeUrl=" ${storeUrl} ?remote-program=${maybeSudo} nix-daemon"
441+ fi
442+ fi
443+
444+ echo " $storeUrl "
445+ }
446+
423447nixCopy () {
424- NIX_SSHOPTS=" ${sshArgs[*]} " nix copy \
425- " ${nixOptions[@]} " \
426- " ${nixCopyOptions[@]} " \
427- " $@ "
448+ # Process arguments to add remote-program parameter when sudo is needed
449+ local processedArgs=()
450+ local i=1
451+ while [[ $i -le $# ]]; do
452+ local arg=" ${! i} "
453+ if [[ $arg == " --to" ]]; then
454+ processedArgs+=(" $arg " )
455+ (( i++ ))
456+ local storeUrl=" ${! i} "
457+ storeUrl=$( buildStoreUrl " $storeUrl " )
458+ processedArgs+=(" $storeUrl " )
459+ else
460+ processedArgs+=(" $arg " )
461+ fi
462+ (( i++ ))
463+ done
464+
465+ local nixCopyArgs=(" ${nixOptions[@]} " " ${nixCopyOptions[@]} " )
466+
467+ NIX_SSHOPTS=" ${sshArgs[*]} " nix copy " ${nixCopyArgs[@]} " " ${processedArgs[@]} "
428468}
429469nixBuild () {
470+ # Process arguments to add remote-program parameter when sudo is needed
471+ local processedArgs=()
472+ local i=1
473+ while [[ $i -le $# ]]; do
474+ local arg=" ${! i} "
475+ if [[ $arg == " --store" ]]; then
476+ processedArgs+=(" $arg " )
477+ (( i++ ))
478+ local storeUrl=" ${! i} "
479+ storeUrl=$( buildStoreUrl " $storeUrl " )
480+ processedArgs+=(" $storeUrl " )
481+ else
482+ processedArgs+=(" $arg " )
483+ fi
484+ (( i++ ))
485+ done
486+
430487 NIX_SSHOPTS=" ${sshArgs[*]} " nix build \
431488 --print-out-paths \
432489 --no-link \
433490 " ${nixBuildFlags[@]} " \
434491 " ${nixOptions[@]} " \
435- " $@ "
492+ " ${processedArgs[@]} "
436493}
437494
438495runVmTest () {
@@ -688,6 +745,8 @@ TMPDIR=/root/kexec setsid --wait ${maybeSudo} /root/kexec/kexec/run --kexec-extr
688745
689746 # After kexec we explicitly set the user to root@
690747 sshConnection=" root@${sshHost} "
748+ # After kexec, we're running as root in the NixOS installer, so no need for sudo
749+ maybeSudo=" "
691750
692751 # waiting for machine to become available again
693752 until runSsh -o ConnectTimeout=10 -- exit 0; do sleep 5; done
@@ -697,55 +756,54 @@ runDisko() {
697756 local diskoScript=$1
698757 for path in " ${! diskEncryptionKeys[@]} " ; do
699758 step " Uploading ${diskEncryptionKeys[$path]} to $path "
700- runSsh " umask 077; mkdir -p \" $( dirname " $path " ) \" ; cat > $path " < " ${diskEncryptionKeys[$path]} "
759+ runSsh " ${maybeSudo} sh -c $( printf ' %q ' " umask 077; mkdir -p $( dirname " $path " ) ; cat > $path " ) " < " ${diskEncryptionKeys[$path]} "
701760 done
702761 if [[ -n ${diskoScript} ]]; then
703- nixCopy --to " ssh://$sshConnection ? $sshStoreSettings " " $diskoScript "
762+ nixCopy --to " ssh-ng ://$sshConnection " " $diskoScript "
704763 elif [[ ${buildOn} == " remote" ]]; then
705764 step Building disko script
706765 # We need to do a nix copy first because nix build doesn't have --no-check-sigs
707766 # Use ssh:// here to avoid https://github.com/NixOS/nix/issues/7359
708- nixCopy --to " ssh://$sshConnection ?$sshStoreSettings " " ${flake} #${flakeAttr} .system.build.${diskoMode} Script" \
709- --derivation --no-check-sigs
767+ nixCopy --to " ssh-ng://$sshConnection " --derivation " ${flake} #${flakeAttr} .system.build.${diskoMode} Script"
710768 # If we don't use ssh-ng here, we get `error: operation 'getFSAccessor' is not supported by store`
711769 diskoScript=$(
712770 nixBuild " ${flake} #${flakeAttr} .system.build.${diskoAttr} " \
713- --eval-store auto --store " ssh-ng://$sshConnection ?ssh-key=$tempDir %2Fnixos-anywhere& $sshStoreSettings "
771+ --eval-store auto --store " ssh-ng://$sshConnection ?ssh-key=$tempDir %2Fnixos-anywhere"
714772 )
715773 fi
716774
717775 step Formatting hard drive with disko
718- runSsh " $diskoScript "
776+ runSsh " ${maybeSudo} $ diskoScript"
719777}
720778
721779nixosInstall () {
722780 local nixosSystem=$1
781+ local remoteStoreUrl=" remote-store=local%3Froot=%2Fmnt"
723782 if [[ -n ${nixosSystem} ]]; then
724783 step Uploading the system closure
725- nixCopy --to " ssh://$sshConnection ?remote-store=local%3Froot=%2Fmnt& $sshStoreSettings " " $nixosSystem "
784+ nixCopy --to " ssh-ng ://$sshConnection ?${remoteStoreUrl} " " $nixosSystem "
726785 elif [[ ${buildOn} == " remote" ]]; then
727786 step Building the system closure
728787 # We need to do a nix copy first because nix build doesn't have --no-check-sigs
729788 # Use ssh:// here to avoid https://github.com/NixOS/nix/issues/7359
730- nixCopy --to " ssh://$sshConnection ?remote-store=local%3Froot=%2Fmnt&$sshStoreSettings " " ${flake} #${flakeAttr} .system.build.toplevel" \
731- --derivation --no-check-sigs
789+ nixCopy --to " ssh-ng://$sshConnection ?${remoteStoreUrl} " --derivation " ${flake} #${flakeAttr} .system.build.toplevel"
732790 # If we don't use ssh-ng here, we get `error: operation 'getFSAccessor' is not supported by store`
733791 nixosSystem=$(
734792 nixBuild " ${flake} #${flakeAttr} .system.build.toplevel" \
735- --eval-store auto --store " ssh-ng://$sshConnection ?ssh-key=$tempDir %2Fnixos-anywhere&remote-store=local%3Froot=%2Fmnt& $sshStoreSettings "
793+ --eval-store auto --store " ssh-ng://$sshConnection ?ssh-key=$tempDir %2Fnixos-anywhere&${remoteStoreUrl} "
736794 )
737795 fi
738796
739797 if [[ -n ${extraFiles} ]]; then
740798 step Copying extra files
741- tar -C " $extraFiles " -cpf- . | runSsh " tar -C /mnt -xf- --no-same-owner"
799+ tar -C " $extraFiles " -cpf- . | runSsh " ${maybeSudo} tar -C /mnt -xf- --no-same-owner"
742800
743- runSsh " chmod 755 /mnt" # tar also changes permissions of /mnt
801+ runSsh " ${maybeSudo} chmod 755 /mnt" # tar also changes permissions of /mnt
744802 fi
745803
746804 if [[ ${# extraFilesOwnership[@]} -gt 0 ]]; then
747805 # shellcheck disable=SC2016
748- printf " %s\n" " ${! extraFilesOwnership[@]} " " ${extraFilesOwnership[@]} " | pr -2t | runSsh ' while read file ownership; do chown -R "$ownership" "/mnt/$file"; done'
806+ printf " %s\n" " ${! extraFilesOwnership[@]} " " ${extraFilesOwnership[@]} " | pr -2t | runSsh ' while read file ownership; do ' " ${maybeSudo} " ' chown -R "$ownership" "/mnt/$file"; done'
749807 fi
750808
751809 step Installing NixOS
@@ -756,27 +814,27 @@ export PATH="\$PATH:/run/current-system/sw/bin"
756814
757815if [ ! -d "/mnt/tmp" ]; then
758816 # needed for installation if initrd-secrets are used
759- mkdir -p /mnt/tmp
760- chmod 777 /mnt/tmp
817+ ${maybeSudo} mkdir -p /mnt/tmp
818+ ${maybeSudo} chmod 777 /mnt/tmp
761819fi
762820
763821if [ ${copyHostKeys-n} = "y" ]; then
764822 # NB we copy host keys that are in turn copied by kexec installer.
765- mkdir -m 755 -p /mnt/etc/ssh
823+ ${maybeSudo} mkdir -m 755 -p /mnt/etc/ssh
766824 for p in /etc/ssh/ssh_host_*; do
767825 # Skip if the source file does not exist (i.e. glob did not match any files)
768826 # or the destination already exists (e.g. copied with --extra-files).
769827 if [ ! -e "\$ p" ] || [ -e "/mnt/\$ p" ]; then
770828 continue
771829 fi
772- cp -a "\$ p" "/mnt/\$ p"
830+ ${maybeSudo} cp -a "\$ p" "/mnt/\$ p"
773831 done
774832fi
775833# https://stackoverflow.com/a/13864829
776834if [ ! -z ${NIXOS_NO_CHECK+0} ]; then
777835 export NIXOS_NO_CHECK
778836fi
779- nixos-install --no-root-passwd --no-channel-copy --system "$nixosSystem "
837+ ${maybeSudo} nixos-install --no-root-passwd --no-channel-copy --system "$nixosSystem "
780838SSH
781839
782840}
@@ -786,11 +844,11 @@ nixosReboot() {
786844 runSsh sh << SSH
787845 if command -v zpool >/dev/null && [ "\$ (zpool list)" != "no pools available" ]; then
788846 # we always want to export the zfs pools so people can boot from it without force import
789- umount -Rv /mnt/
790- swapoff -a
791- zpool export -a || true
847+ ${maybeSudo} umount -Rv /mnt/
848+ ${maybeSudo} swapoff -a
849+ ${maybeSudo} zpool export -a || true
792850 fi
793- nohup sh -c 'sleep 6 && reboot' >/dev/null &
851+ ${maybeSudo} nohup sh -c 'sleep 6 && reboot' >/dev/null &
794852SSH
795853
796854 step Waiting for the machine to become unreachable due to reboot
@@ -840,7 +898,6 @@ main() {
840898 fi
841899
842900 sshSettings=$( ssh " ${sshArgs[@]} " -G " ${sshConnection} " )
843- sshUser=$( echo " $sshSettings " | awk ' /^user / { print $2 }' )
844901 sshHost=$( echo " $sshSettings " | awk ' /^hostname / { print $2 }' )
845902
846903 uploadSshKey
@@ -898,14 +955,6 @@ main() {
898955 fi
899956 fi
900957
901- # Installation will fail if non-root user is used for installer.
902- # Switch to root user by copying authorized_keys.
903- if [[ ${isInstaller} == " y" ]] && [[ ${sshUser} != " root" ]]; then
904- # Allow copy to fail if authorized_keys does not exist, like if using /etc/ssh/authorized_keys.d/
905- runSsh " ${maybeSudo} mkdir -p /root/.ssh; ${maybeSudo} cp ~/.ssh/authorized_keys /root/.ssh || true"
906- sshConnection=" root@${sshHost} "
907- fi
908-
909958 if [[ ${phases[disko]} == 1 ]]; then
910959 runDisko " $diskoScript "
911960 fi
0 commit comments