# requirements: ssh-to-age nixos-anywhere HECTIC_NAMESPACE="deploy" # ssh proxydoe 'cat /etc/os-release 2>/dev/null || echo "no /etc/os-release"' | grep '^NAME=NixOS$' # NAME=NixOS # ssh that not saves the host in ~/.ssh/know_hosts puressh() { # shellcheck disable=SC2068 ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null $@ } # echo | find_older_gen(gen) find_older_gen() { local gen="${1:?}" grep -oP '(?<=system-)\d+(?=-link)' \ | sort -n \ | awk -v n="$gen" '$1 < n {older=$1} END{if(older) print older}' } saved_args="$*" # parse command and independent params while [ $# -gt 0 ]; do case $1 in push) if [ ${founded_command+x} ]; then # shellcheck disable=SC2016 log error "ambiguous subcommand \`$1\` and \`$founded_command\`" exit 2 fi push_deploy=1 founded_command="$1" shift ;; rollback) if [ ${founded_command+x} ]; then # shellcheck disable=SC2016 log error "ambiguous subcommand \`$1\` and \`$founded_command\`" exit 2 fi rollback_deploy=1 founded_command="$1" shift ;; history) if [ ${founded_command+x} ]; then # shellcheck disable=SC2016 log error "ambiguous subcommand \`$1\` and \`$founded_command\`" exit 2 fi server_history=1 founded_command="$1" shift ;; --target-host) target_host=$2 shift 2 ;; --) shift break ;; *) shift ;; esac done # shellcheck disable=SC2086 set -- $saved_args # parse sub params while [ $# -gt 0 ]; do case $1 in --init) if [ ${push_deploy+x} ]; then server_init=1 else log warn "illegal $1" fi shift ;; --to) if [ ${rollback_deploy+x} ]; then rollback_to="$2" else log warn "illegal $1" fi shift 2 ;; --) shift break ;; *) shift ;; esac done # NOTE(yukkop): # after "end of arguments" (--) # need to parse nix argument `--target-host` # without lost of $@, that can be ruined by `shift` saved_nix_args="$*" while [ $# -gt 0 ]; do case $1 in --target-host) if [ "${target_host+x}" ] && [ "$target_host" != "$2" ]; then log error "you specified 2 ambiguous target hosts \`$target_host\` and \`$2\`" exit 2 fi target_host="$2" break shift 2 ;; *) shift ;; esac done # NOTE: restore original args # shellcheck disable=SC2086 set -- $saved_nix_args if ! [ ${target_host+x} ]; then log error "$(printf '%s' '--target-host') not set, but required" exit 3 fi if puressh "$target_host" 'cat /etc/os-release 2>/dev/null || echo "no /etc/os-release"' \ | grep -q '^NAME=NixOS$' then is_target_host_nixos=1 else is_target_host_nixos=0 fi #?? #ssh "$target_host" 'grep -q "^NAME=NixOS$" /etc/os-release 2>/dev/null' #is_target_host_nixos=$? if [ "${rollback_deploy+x}" ]; then if ! [ "${rollback_to+x}" ]; then current_gen=$(puressh "$target_host" readlink /nix/var/nix/profiles/system \ | sed -n 's/^system-\([0-9]\+\)-link$/\1/p') rollback_to=$(puressh "$target_host" ls /nix/var/nix/profiles | find_older_gen "$current_gen") if [ -z "$rollback_to" ]; then # shellcheck disable=SC2016 log error "no profile version older than the current \`$current_gen\` exists" exit fi else if ! puressh "$target_host" ls /nix/var/nix/profiles \ | grep -oP '(?<=system-)'"$rollback_to"'(?=-link)' > /dev/null then # shellcheck disable=SC2016 log error 'no profile version \`$rollback_to\` exists' exit fi fi puressh "$target_host" </dev/null; do sleep 5 done server_public_age_key=$(puressh "$target_host" cat /etc/ssh/ssh_host_ed25519_key.pub | ssh-to-age) # shellcheck disable=SC2016 log info "server's public age key is \`$server_public_age_key\` use it in sops file and run regular deploys" else if [ "$is_target_host_nixos" -ne 1 ]; then log error 'remote system not nixos' exit 1 fi # shellcheck disable=SC2068 nixos-rebuild switch $@ # --flake .#x86_64-linux --target-host proxydoe fi fi