2023-05-10 11:33:28 +03:00
#!/usr/bin/env bash
set -euo pipefail
2022-11-10 16:42:06 +03:00
showUsage( ) {
cat <<USAGE
2023-06-07 08:11:27 +03:00
Usage: nixos-anywhere [ options] <ssh-host>
2022-11-10 16:42:06 +03:00
Options:
2023-05-10 11:56:29 +03:00
* -f, --flake <flake_uri>
set the flake to install the system from.
* -i <identity_file>
selects which SSH private key file to use.
2023-05-29 03:11:43 +03:00
* -p, --ssh-port <ssh_port>
set the ssh port to connect with
* --ssh-option <ssh_option>
set an ssh option
2023-01-12 00:04:09 +03:00
* -L, --print-build-logs
print full build logs
2024-04-20 01:08:15 +03:00
* --env-password
2024-04-21 20:33:11 +03:00
set a password used by ssh-copy-id, the password should be set by
2024-04-20 01:08:15 +03:00
the environment variable SSH_PASS
2023-06-07 08:11:27 +03:00
* -s, --store-paths <disko-script> <nixos-system>
2022-12-07 18:06:02 +03:00
set the store paths to the disko-script and nixos-system directly
2024-04-19 17:17:59 +03:00
if this is given, flake is not needed
2022-12-29 22:11:06 +03:00
* --no-reboot
do not reboot after installation, allowing further customization of the target installation.
2023-07-18 14:41:36 +03:00
* --kexec <path>
2022-11-10 17:30:50 +03:00
use another kexec tarball to bootstrap NixOS
2023-05-29 03:11:43 +03:00
* --post-kexec-ssh-port <ssh_port>
after kexec is executed, use a custom ssh port to connect. Defaults to 22
2023-09-28 01:43:36 +03:00
* --copy-host-keys
copy over existing /etc/ssh/ssh_host_* host keys to the installation
2022-12-27 21:43:41 +03:00
* --stop-after-disko
2023-08-22 14:49:53 +03:00
exit after disko formatting, you can then proceed to install manually or some other way
2023-06-07 08:11:27 +03:00
* --extra-files <file...>
2022-12-23 20:22:25 +03:00
files to copy into the new nixos installation
2023-06-07 08:11:27 +03:00
* --disk-encryption-keys <remote_path> <local_path>
2023-01-04 22:02:23 +03:00
copy the contents of the file or pipe in local_path to remote_path in the installer environment,
after kexec but before installation. Can be repeated.
2023-01-15 21:08:29 +03:00
* --no-substitute-on-destination
disable passing --substitute-on-destination to nix-copy
2022-12-09 17:26:44 +03:00
* --debug
enable debug output
2023-06-07 08:11:27 +03:00
* --option <key> <value>
2023-01-17 18:28:44 +03:00
nix option to pass to every nix related command
2023-06-07 08:11:27 +03:00
* --from <store-uri>
2023-01-17 18:28:44 +03:00
URL of the source Nix store to copy the nixos and disko closure from
2023-04-21 17:39:31 +03:00
* --build-on-remote
build the closure on the remote machine instead of locally and copy-closuring it
2023-07-20 22:48:27 +03:00
* --vm-test
build the system and test the disk configuration inside a VM without installing it to the target.
2022-11-10 16:42:06 +03:00
USAGE
}
abort( ) {
echo " aborted: $* " >& 2
exit 1
}
2023-05-10 12:30:33 +03:00
step( ) {
echo " ### $* ### "
}
2024-04-05 17:24:40 +03:00
here = $( dirname " ${ BASH_SOURCE [0] } " )
2023-08-05 10:46:07 +03:00
kexec_url = ""
2022-12-30 15:16:00 +03:00
enable_debug = ""
2023-01-22 15:28:15 +03:00
maybe_reboot = "sleep 6 && reboot"
2023-01-17 18:28:44 +03:00
nix_options = (
--extra-experimental-features 'nix-command flakes'
"--no-write-lock-file"
)
2023-01-17 18:28:44 +03:00
substitute_on_destination = y
2023-05-10 11:56:29 +03:00
ssh_private_key_file =
2023-12-28 00:12:44 +03:00
if [ -t 0 ] ; then # stdin is a tty, we allow interactive input to ssh i.e. passwords
ssh_tty_param = "-t"
else
ssh_tty_param = "-T"
fi
2023-05-29 03:11:43 +03:00
post_kexec_ssh_port = 22
2022-11-10 16:42:06 +03:00
2023-01-04 22:02:23 +03:00
declare -A disk_encryption_keys
2023-01-12 23:23:45 +03:00
declare -a nix_copy_options
declare -a ssh_copy_id_args
2023-05-29 03:11:43 +03:00
declare -a ssh_args
2023-01-04 22:02:23 +03:00
2022-11-10 16:42:06 +03:00
while [ [ $# -gt 0 ] ] ; do
case " $1 " in
2023-01-12 05:34:12 +03:00
-f | --flake)
flake = $2
shift
; ;
2023-05-10 11:56:29 +03:00
-i)
ssh_private_key_file = $2
shift
; ;
2023-05-29 03:11:43 +03:00
-p | --ssh-port)
ssh_args += ( "-p" " $2 " )
shift
; ;
--ssh-option)
ssh_args += ( "-o" " $2 " )
shift
; ;
2023-01-12 05:34:12 +03:00
-L | --print-build-logs)
print_build_logs = y
; ;
-s | --store-paths)
disko_script = $( readlink -f " $2 " )
nixos_system = $( readlink -f " $3 " )
shift
shift
; ;
2023-06-13 21:16:34 +03:00
-t | --tty)
2023-12-28 00:12:44 +03:00
echo " the ' $1 ' flag is deprecated, a tty is now detected automatically " >& 2
2023-06-13 21:16:34 +03:00
; ;
2023-01-12 05:34:12 +03:00
--help)
showUsage
exit 0
; ;
--kexec)
kexec_url = $2
shift
; ;
2023-05-29 03:11:43 +03:00
--post-kexec-ssh-port)
post_kexec_ssh_port = $2
shift
; ;
2023-09-28 01:43:36 +03:00
--copy-host-keys)
copy_host_keys = y
; ;
2023-01-12 05:34:12 +03:00
--debug)
enable_debug = "-x"
print_build_logs = y
set -x
; ;
--extra-files)
extra_files = $2
shift
; ;
--disk-encryption-keys)
disk_encryption_keys[ " $2 " ] = " $3 "
shift
shift
; ;
--stop-after-disko)
stop_after_disko = y
; ;
--no-reboot)
2023-01-22 15:28:15 +03:00
maybe_reboot = ""
2023-01-12 05:34:12 +03:00
; ;
2023-01-17 18:28:44 +03:00
--from)
nix_copy_options += ( "--from" " $2 " )
shift
; ;
2023-01-17 18:28:44 +03:00
--option)
key = $2
shift
value = $2
shift
nix_options += ( "--option" " $key " " $value " )
; ;
2023-01-15 21:08:29 +03:00
--no-substitute-on-destination)
2023-01-17 18:28:44 +03:00
substitute_on_destination = n
2023-01-15 21:08:29 +03:00
; ;
2023-04-21 17:39:31 +03:00
--build-on-remote)
build_on_remote = y
; ;
2024-04-20 01:08:15 +03:00
--env-password)
env_password = y
; ;
2023-07-20 22:48:27 +03:00
--vm-test)
vm_test = y
; ;
2023-01-12 05:34:12 +03:00
*)
2023-01-22 11:46:42 +03:00
if [ [ -z ${ ssh_connection - } ] ] ; then
2023-01-12 05:34:12 +03:00
ssh_connection = " $1 "
else
2022-11-10 16:42:06 +03:00
showUsage
2023-01-12 05:34:12 +03:00
exit 1
fi
; ;
2022-11-10 16:42:06 +03:00
esac
shift
done
2023-01-12 00:04:09 +03:00
if [ [ ${ print_build_logs -n } = = "y" ] ] ; then
nix_options += ( "-L" )
fi
2023-01-17 18:28:44 +03:00
if [ [ ${ substitute_on_destination -n } = = "y" ] ] ; then
nix_copy_options += ( "--substitute-on-destination" )
fi
2023-01-12 23:23:45 +03:00
# ssh wrapper
timeout_ssh_( ) {
2023-05-29 03:11:43 +03:00
timeout 10 ssh -i " $ssh_key_dir " /nixos-anywhere -o UserKnownHostsFile = /dev/null -o StrictHostKeyChecking = no " ${ ssh_args [@] } " " $ssh_connection " " $@ "
2023-01-12 23:23:45 +03:00
}
ssh_( ) {
2023-05-29 03:11:43 +03:00
ssh " $ssh_tty_param " -i " $ssh_key_dir " /nixos-anywhere -o UserKnownHostsFile = /dev/null -o StrictHostKeyChecking = no " ${ ssh_args [@] } " " $ssh_connection " " $@ "
2023-01-12 23:23:45 +03:00
}
2023-01-11 22:28:36 +03:00
nix_copy( ) {
2023-07-31 20:08:56 +03:00
NIX_SSHOPTS = " -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i $ssh_key_dir /nixos-anywhere ${ ssh_args [*] } " nix copy \
2023-01-17 18:28:44 +03:00
" ${ nix_options [@] } " \
" ${ nix_copy_options [@] } " \
2023-01-11 22:28:36 +03:00
" $@ "
2022-11-23 20:32:36 +03:00
}
nix_build( ) {
2023-07-31 20:08:56 +03:00
NIX_SSHOPTS = " -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i $ssh_key_dir /nixos-anywhere ${ ssh_args [*] } " nix build \
2022-11-23 20:32:36 +03:00
--print-out-paths \
2023-01-11 22:28:36 +03:00
--no-link \
2023-01-17 18:28:44 +03:00
" ${ nix_options [@] } " \
2022-11-23 20:32:36 +03:00
" $@ "
}
2023-07-20 22:48:27 +03:00
if [ [ -z ${ vm_test - } ] ] ; then
if [ [ -z ${ ssh_connection - } ] ] ; then
abort "ssh-host must be set"
fi
2022-12-09 18:20:48 +03:00
2023-07-20 22:48:27 +03:00
# we generate a temporary ssh keypair that we can use during nixos-anywhere
ssh_key_dir = $( mktemp -d)
trap 'rm -rf "$ssh_key_dir"' EXIT
mkdir -p " $ssh_key_dir "
# ssh-copy-id requires this directory
mkdir -p " $HOME /.ssh/ "
ssh-keygen -t ed25519 -f " $ssh_key_dir " /nixos-anywhere -P "" -C "nixos-anywhere" >/dev/null
fi
2023-01-12 23:23:45 +03:00
2022-11-23 20:32:36 +03:00
# parse flake nixos-install style syntax, get the system attr
2023-01-22 11:46:42 +03:00
if [ [ -n ${ flake - } ] ] ; then
2022-11-23 20:32:36 +03:00
if [ [ $flake = ~ ^( .*) \# ( [ ^\# \" ] *) $ ] ] ; then
2023-01-12 05:34:12 +03:00
flake = " ${ BASH_REMATCH [1] } "
flakeAttr = " ${ BASH_REMATCH [2] } "
2022-11-23 20:32:36 +03:00
fi
2023-01-22 11:46:42 +03:00
if [ [ -z ${ flakeAttr - } ] ] ; then
2023-01-24 18:02:31 +03:00
echo "Please specify the name of the NixOS configuration to be installed, as a URI fragment in the flake-uri." >& 2
echo 'For example, to use the output nixosConfigurations.foo from the flake.nix, append "#foo" to the flake-uri.' >& 2
2022-11-23 20:32:36 +03:00
exit 1
fi
2023-04-21 17:39:31 +03:00
if [ [ ${ build_on_remote -n } = = "n" ] ] ; then
2023-07-20 22:48:27 +03:00
if [ [ -n ${ vm_test - } ] ] ; then
2023-09-02 21:30:44 +03:00
if [ [ -n ${ extra_files - } ] ] ; then
echo "--vm-test is not supported with --extra-files" >& 2
exit 1
fi
if [ [ -n ${ disk_encryption_keys - } ] ] ; then
echo "--vm-test is not supported with --disk-encryption-keys" >& 2
exit 1
fi
2023-07-20 22:48:27 +03:00
exec nix build \
--print-out-paths \
--no-link \
-L \
" ${ nix_options [@] } " \
" ${ flake } #nixosConfigurations.\" ${ flakeAttr } \".config.system.build.installTest "
fi
2023-06-01 21:37:28 +03:00
disko_script = $( nix_build " ${ flake } #nixosConfigurations.\" ${ flakeAttr } \".config.system.build.diskoScript " )
2023-04-21 17:39:31 +03:00
nixos_system = $( nix_build " ${ flake } #nixosConfigurations.\" ${ flakeAttr } \".config.system.build.toplevel " )
fi
2023-01-22 11:46:42 +03:00
elif [ [ -n ${ disko_script - } ] ] && [ [ -n ${ nixos_system - } ] ] ; then
2023-09-02 14:42:31 +03:00
if [ [ -n ${ vm_test - } ] ] ; then
echo "vm-test is not supported with --store-paths" >& 2
echo "Please use --flake instead or build config.system.build.installTest of your nixos configuration manually" >& 2
exit 1
fi
2023-01-12 05:34:12 +03:00
if [ [ ! -e ${ disko_script } ] ] || [ [ ! -e ${ nixos_system } ] ] ; then
2023-01-24 18:02:31 +03:00
abort " ${ disko_script } and ${ nixos_system } must be existing store-paths "
2022-12-07 18:06:02 +03:00
fi
2022-11-23 20:32:36 +03:00
else
abort "flake must be set"
fi
2023-05-10 11:56:29 +03:00
# overrides -i if passed as an env var
2023-01-12 23:23:45 +03:00
if [ [ -n ${ SSH_PRIVATE_KEY - } ] ] ; then
2023-05-10 11:56:29 +03:00
# $ssh_key_dir is getting deleted on trap EXIT
ssh_private_key_file = " $ssh_key_dir /from-env "
2023-01-12 23:23:45 +03:00
(
umask 077
2023-05-10 11:56:29 +03:00
printf '%s\n' " $SSH_PRIVATE_KEY " >" $ssh_private_key_file "
2023-01-12 23:23:45 +03:00
)
2023-05-10 11:56:29 +03:00
fi
if [ [ -n ${ ssh_private_key_file - } ] ] ; then
2023-01-12 23:23:45 +03:00
unset SSH_AUTH_SOCK # don't use system agent if key was supplied
2023-05-10 11:56:29 +03:00
ssh_copy_id_args += ( -o " IdentityFile= ${ ssh_private_key_file } " )
2023-01-12 23:23:45 +03:00
ssh_copy_id_args += ( -f)
fi
2023-09-23 18:38:16 +03:00
ssh_settings = $( ssh " ${ ssh_args [@] } " -G " ${ ssh_connection } " )
2024-03-23 03:47:24 +03:00
ssh_user = $( echo " $ssh_settings " | awk '/^user / { print $2 }' )
2023-06-07 08:34:41 +03:00
ssh_host = $( echo " $ssh_settings " | awk '/^hostname / { print $2 }' )
2023-06-07 01:29:39 +03:00
ssh_port = $( echo " $ssh_settings " | awk '/^port / { print $2 }' )
2023-05-10 12:30:33 +03:00
step Uploading install SSH keys
2023-01-12 23:23:45 +03:00
until
2024-04-20 01:08:15 +03:00
if [ [ -n ${ env_password - } ] ] ; then
sshpass -e \
ssh-copy-id \
-i " $ssh_key_dir " /nixos-anywhere.pub \
-o ConnectTimeout = 10 \
-o UserKnownHostsFile = /dev/null \
-o IdentitiesOnly = yes \
-o StrictHostKeyChecking = no \
" ${ ssh_copy_id_args [@] } " \
" ${ ssh_args [@] } " \
" $ssh_connection "
else
ssh-copy-id \
-i " $ssh_key_dir " /nixos-anywhere.pub \
-o ConnectTimeout = 10 \
-o UserKnownHostsFile = /dev/null \
-o StrictHostKeyChecking = no \
" ${ ssh_copy_id_args [@] } " \
" ${ ssh_args [@] } " \
" $ssh_connection "
fi
2023-01-12 23:23:45 +03:00
do
sleep 3
done
2023-01-22 11:36:29 +03:00
import_facts( ) {
local facts filtered_facts
2024-04-05 17:24:40 +03:00
if ! facts = $( ssh_ -o ConnectTimeout = 10 enable_debug = $enable_debug sh -- <" $here " /get-facts.sh) ; then
2023-01-12 23:23:45 +03:00
exit 1
2023-01-22 11:36:29 +03:00
fi
filtered_facts = $( echo " $facts " | grep -E '^(has|is)_[a-z0-9_]+=\S+' )
2023-01-22 11:46:42 +03:00
if [ [ -z $filtered_facts ] ] ; then
2023-01-22 11:36:29 +03:00
abort "Retrieving host facts via ssh failed. Check with --debug for the root cause, unless you have done so already"
fi
# make facts available in script
# shellcheck disable=SC2046
export $( echo " $filtered_facts " | xargs)
}
2023-05-10 12:30:33 +03:00
step Gathering machine facts
2023-01-12 23:23:45 +03:00
import_facts
2023-01-03 15:31:26 +03:00
2022-12-30 15:16:00 +03:00
if [ [ ${ has_tar -n } = = "n" ] ] ; then
abort "no tar command found, but required to unpack kexec tarball"
2022-12-14 15:34:23 +03:00
fi
2023-05-03 19:06:43 +03:00
if [ [ ${ has_setsid -n } = = "n" ] ] ; then
abort "no setsid command found, but required to run the kexec script under a new session"
fi
2023-01-22 15:28:15 +03:00
maybe_sudo = ""
2022-12-30 15:16:00 +03:00
if [ [ ${ has_sudo -n } = = "y" ] ] ; then
2023-01-22 15:28:15 +03:00
maybe_sudo = "sudo"
2024-02-28 01:08:52 +03:00
elif [ [ ${ has_doas -n } = = "y" ] ] ; then
maybe_sudo = "doas"
2022-11-10 19:15:00 +03:00
fi
2023-05-03 19:06:43 +03:00
2022-12-30 15:16:00 +03:00
if [ [ ${ is_os -n } != "Linux" ] ] ; then
abort " This script requires Linux as the operating system, but got $is_os "
2022-11-24 20:28:47 +03:00
fi
2023-01-12 17:20:54 +03:00
if [ [ ${ is_kexec -n } = = "n" ] ] && [ [ ${ is_installer -n } = = "n" ] ] ; then
2024-01-07 14:50:33 +03:00
if [ [ ${ is_container -none } != "none" ] ] ; then
echo " WARNING: This script does not support running from a ' ${ is_container } ' container. kexec will likely not work " >& 2
fi
2023-08-05 10:46:07 +03:00
if [ [ $kexec_url = = "" ] ] ; then
case " ${ is_arch -unknown } " in
x86_64 | aarch64)
2023-12-12 13:21:01 +03:00
kexec_url = " https://github.com/nix-community/nixos-images/releases/download/nixos-23.11/nixos-kexec-installer-noninteractive- ${ is_arch } -linux.tar.gz "
2023-08-05 10:46:07 +03:00
; ;
*)
2023-11-22 22:15:27 +03:00
abort " Unsupported architecture: ${ is_arch } . Our default kexec images only support x86_64 and aarch64 cpus. Checkout https://github.com/nix-community/nixos-anywhere/#using-your-own-kexec-image for more information. "
2023-08-05 10:46:07 +03:00
; ;
esac
2023-07-03 18:41:45 +03:00
fi
2023-05-10 12:30:33 +03:00
step Switching system into kexec
2024-02-28 01:07:52 +03:00
ssh_ sh <<SSH
2022-12-30 15:16:00 +03:00
set -efu ${ enable_debug }
2023-01-22 15:28:15 +03:00
$maybe_sudo rm -rf /root/kexec
$maybe_sudo mkdir -p /root/kexec
2022-12-30 15:16:00 +03:00
SSH
2024-04-21 20:33:11 +03:00
# no way to reach global ipv4 destinations, use gh-v6.com automatically if github url
if [ [ ${ has_ipv6_only -n } = = "y" ] ] && [ [ $kexec_url = = "https://github.com/" * ] ] ; then
kexec_url = ${ kexec_url / "github.com" / "gh-v6.com" }
fi
2023-01-12 05:34:12 +03:00
if [ [ -f $kexec_url ] ] ; then
2023-01-22 15:28:15 +03:00
ssh_ " ${ maybe_sudo } tar -C /root/kexec -xvzf- " <" $kexec_url "
2022-12-30 15:16:00 +03:00
elif [ [ ${ has_curl -n } = = "y" ] ] ; then
2023-01-22 15:28:15 +03:00
ssh_ " curl --fail -Ss -L ' ${ kexec_url } ' | ${ maybe_sudo } tar -C /root/kexec -xvzf- "
2022-12-30 15:16:00 +03:00
elif [ [ ${ has_wget -n } = = "y" ] ] ; then
2023-01-22 15:28:15 +03:00
ssh_ " wget ' ${ kexec_url } ' -O- | ${ maybe_sudo } tar -C /root/kexec -xvzf- "
2022-11-10 16:42:06 +03:00
else
2023-01-22 15:28:15 +03:00
curl --fail -Ss -L " ${ kexec_url } " | ssh_ " ${ maybe_sudo } tar -C /root/kexec -xvzf- "
2022-11-10 16:42:06 +03:00
fi
2022-11-12 13:47:17 +03:00
2023-01-12 05:34:12 +03:00
ssh_ <<SSH
2023-01-22 15:28:15 +03:00
TMPDIR = /root/kexec setsid ${ maybe_sudo } /root/kexec/kexec/run
2022-11-10 16:42:06 +03:00
SSH
2022-11-24 20:28:47 +03:00
2023-05-29 03:11:43 +03:00
# use the default SSH port to connect at this point
for i in " ${ !ssh_args[@] } " ; do
if [ [ ${ ssh_args [i] } = = "-p" ] ] ; then
ssh_args[ i + 1] = $post_kexec_ssh_port
break
fi
done
# wait for machine to become unreachable.
2022-11-10 18:45:14 +03:00
while timeout_ssh_ -- exit 0; do sleep 1; done
2022-11-10 16:42:06 +03:00
2022-12-30 20:51:46 +03:00
# After kexec we explicitly set the user to root@
2023-06-07 01:29:39 +03:00
ssh_connection = " root@ ${ ssh_host } "
2022-12-30 20:51:46 +03:00
2023-05-29 03:11:43 +03:00
# waiting for machine to become available again
2022-11-10 17:31:43 +03:00
until ssh_ -o ConnectTimeout = 10 -- exit 0; do sleep 5; done
2022-11-10 16:42:06 +03:00
fi
2024-03-23 03:47:24 +03:00
# Installation will fail if non-root user is used for installer.
# Switch to root user by copying authorized_keys.
if [ [ ${ is_installer -n } = = "y" ] ] && [ [ ${ ssh_user } != "root" ] ] ; then
ssh_ " ${ maybe_sudo } mkdir -p /root/.ssh; ${ maybe_sudo } cp ~/.ssh/authorized_keys /root/.ssh "
ssh_connection = " root@ ${ ssh_host } "
fi
2023-01-12 05:34:12 +03:00
for path in " ${ !disk_encryption_keys[@] } " ; do
2023-05-10 12:30:33 +03:00
step " Uploading ${ disk_encryption_keys [ $path ] } to $path "
2023-01-12 05:34:12 +03:00
ssh_ " umask 077; cat > $path " <" ${ disk_encryption_keys [ $path ] } "
2023-01-04 22:02:23 +03:00
done
2022-12-28 17:19:23 +03:00
2023-10-28 10:02:19 +03:00
if [ [ ${ build_on_remote -n } = = "y" ] ] ; then
pubkey = $( ssh-keyscan -p " $ssh_port " -t ed25519 " $ssh_host " 2>/dev/null || {
echo " ERROR: failed to retrieve host public key for ${ ssh_connection } " >& 2
exit 1
} )
pubkey = $( echo " $pubkey " | sed -e 's/^[^ ]* //' | base64 -w0)
fi
2023-04-21 17:39:31 +03:00
2023-12-28 01:03:37 +03:00
if [ [ -n ${ disko_script - } ] ] ; then
nix_copy --to " ssh:// $ssh_connection " " $disko_script "
elif [ [ ${ build_on_remote -n } = = "y" ] ] ; then
2023-05-10 12:30:33 +03:00
step Building disko script
2023-12-28 01:03:37 +03:00
# We need to do a nix copy first because nix build doesn't have --no-check-sigs
nix_copy --to " ssh-ng:// $ssh_connection " " ${ flake } #nixosConfigurations.\" ${ flakeAttr } \".config.system.build.diskoScript " \
--derivation --no-check-sigs
2023-04-21 17:39:31 +03:00
disko_script = $(
2023-06-01 21:37:28 +03:00
nix_build " ${ flake } #nixosConfigurations.\" ${ flakeAttr } \".config.system.build.diskoScript " \
2023-12-28 01:03:37 +03:00
--eval-store auto --store " ssh-ng:// $ssh_connection ?ssh-key= $ssh_key_dir /nixos-anywhere "
2023-04-21 17:39:31 +03:00
)
fi
2023-12-28 01:03:37 +03:00
2023-05-10 12:30:33 +03:00
step Formatting hard drive with disko
2022-12-21 15:57:39 +03:00
ssh_ " $disko_script "
2022-11-10 16:42:06 +03:00
2022-12-27 21:43:41 +03:00
if [ [ ${ stop_after_disko -n } = = "y" ] ] ; then
2023-01-12 23:23:45 +03:00
# Should we also do this for `--no-reboot`?
2023-02-01 21:49:46 +03:00
echo " WARNING: leaving temporary ssh key at ' $ssh_key_dir /nixos-anywhere' to login to the machine " >& 2
2023-01-12 23:23:45 +03:00
trap - EXIT
2022-12-27 21:43:41 +03:00
exit 0
fi
2023-12-28 01:03:37 +03:00
if [ [ -n ${ nixos_system - } ] ] ; then
step Uploading the system closure
nix_copy --to " ssh:// $ssh_connection ?remote-store=local?root=/mnt " " $nixos_system "
elif [ [ ${ build_on_remote -n } = = "y" ] ] ; then
2023-05-10 12:30:33 +03:00
step Building the system closure
2023-12-28 01:03:37 +03:00
# We need to do a nix copy first because nix build doesn't have --no-check-sigs
nix_copy --to " ssh-ng:// $ssh_connection ?remote-store=local?root=/mnt " " ${ flake } #nixosConfigurations.\" ${ flakeAttr } \".config.system.build.toplevel " \
--derivation --no-check-sigs
2023-04-21 17:39:31 +03:00
nixos_system = $(
nix_build " ${ flake } #nixosConfigurations.\" ${ flakeAttr } \".config.system.build.toplevel " \
2023-12-28 01:03:37 +03:00
--eval-store auto --store " ssh-ng:// $ssh_connection ?ssh-key= $ssh_key_dir /nixos-anywhere&remote-store=local?root=/mnt "
2023-04-21 17:39:31 +03:00
)
fi
2023-01-22 11:46:42 +03:00
if [ [ -n ${ extra_files - } ] ] ; then
2023-01-12 05:34:12 +03:00
if [ [ -d $extra_files ] ] ; then
2022-12-23 20:22:25 +03:00
extra_files = " $extra_files / "
fi
2023-05-10 12:30:33 +03:00
step Copying extra files
2023-08-05 11:37:25 +03:00
rsync -rlpv -FF \
-e " ssh -i \" $ssh_key_dir \"/nixos-anywhere -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no ${ ssh_args [*] } " \
" $extra_files " \
" ${ ssh_connection } :/mnt/ "
2023-02-08 18:21:48 +03:00
ssh_ "chmod 755 /mnt" # rsync also changes permissions of /mnt
2022-12-23 20:22:25 +03:00
fi
2022-12-30 13:24:26 +03:00
2023-05-10 12:30:33 +03:00
step Installing NixOS
2024-02-28 01:07:52 +03:00
ssh_ sh <<SSH
2023-09-28 01:43:36 +03:00
set -eu ${ enable_debug }
2023-06-07 17:46:52 +03:00
# when running not in nixos we might miss this directory, but it's needed in the nixos chroot during installation
2023-09-28 01:43:36 +03:00
export PATH = "\$PATH:/run/current-system/sw/bin"
2023-06-07 17:46:52 +03:00
2022-12-28 17:19:23 +03:00
# needed for installation if initrd-secrets are used
2023-02-08 18:22:39 +03:00
mkdir -p /mnt/tmp
chmod 777 /mnt/tmp
2024-04-05 17:24:40 +03:00
if [ ${ copy_host_keys -n } = "y" ] ; then
2023-09-28 01:43:36 +03:00
# NB we copy host keys that are in turn copied by kexec installer.
mkdir -m 755 -p /mnt/etc/ssh
for p in /etc/ssh/ssh_host_*; do
# Skip if the source file does not exist (i.e. glob did not match any files)
# or the destination already exists (e.g. copied with --extra-files).
2024-04-05 17:24:40 +03:00
if [ ! -e "\$p" ] || [ -e "/mnt/\$p" ] ; then
2023-09-28 01:43:36 +03:00
continue
2023-10-04 01:13:15 +03:00
fi
2023-09-28 01:43:36 +03:00
cp -a "\$p" "/mnt/\$p"
done
fi
2022-12-30 15:16:00 +03:00
nixos-install --no-root-passwd --no-channel-copy --system " $nixos_system "
2023-07-18 16:29:47 +03:00
if command -v zpool >/dev/null; then
2023-10-27 12:28:00 +03:00
# we always want to export the zfs pools so people can boot from it without force import
umount -Rv /mnt/
2023-10-27 12:35:06 +03:00
zpool export -a || true
2023-07-18 16:29:47 +03:00
fi
2023-01-12 13:53:19 +03:00
# We will reboot in background so we can cleanly finish the script before the hosts go down.
# This makes integration into scripts easier
2024-02-28 01:07:52 +03:00
nohup sh -c '${maybe_reboot}' >/dev/null &
2022-12-30 15:16:00 +03:00
SSH
2023-03-04 19:09:20 +03:00
if [ [ -n ${ maybe_reboot } ] ] ; then
2023-05-29 03:11:43 +03:00
step Waiting for the machine to become reachable again
2023-03-04 19:09:20 +03:00
while timeout_ssh_ -- exit 0; do sleep 1; done
fi
2023-05-10 12:30:33 +03:00
step "Done!"