Newer
Older
#!/usr/bin/env zsh
set -e
# fail on undeclared variable
set -u
set -o pipefail
readonly cmdname=$(basename $0)
readonly machines_repo_entry_point=$MACHINES_PATH/flake.nix
# This script cannot run without the nixos configuration entry point
if [[ ! -f "$machines_repo_entry_point" ]]
print -P "%B%F{red}Error: Machines repo %F{orange}default.nix%F{red} not found%b%f" >&2
source $DOTFILES_PATH/bin/lib/util.zsh
print "Usage: $cmdname [--via via_hostname] <hostname> [switch|boot|reboot|test|dry-activate|build|iso]" >&2
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
}
positional=()
via_hostname=""
while [[ $# -gt 0 ]]
do
case "$1" in
--help|-h)
usage
exit 0
;;
--via)
via_hostname="$2"
shift
;;
*)
positional+=("$1")
;;
esac
shift
done
if [[ ${#positional[@]} -ne 1 && ${#positional[@]} -ne 2 ]]
then
print "Invalid number of arguments." >&2
usage
exit 2
fi
readonly hostname="${positional[1]}"
if [[ ${#positional[@]} -ge 2 ]]
then
readonly original_operation="${positional[2]}"
else
# default operation
readonly original_operation=switch
fi
if [[ -z "$via_hostname" ]]
then
via_hostname="$hostname"
fi
operation=$original_operation
set_profile=""
reboot=""
if [[ "$operation" = "switch" || "$operation" = "boot" ]]
then
set_profile=1
elif [[ "$operation" = "reboot" ]]
then
operation="boot"
set_profile=1
reboot=1
elif [[ "$operation" = "test" || "$operation" = "dry-activate" || "$operation" = "build" || "$operation" = "iso" ]]
then
# pass
else
print_error "Invalid operation: $operation"
usage
exit 2
fi
if [[ "$(hostname)" = "$hostname" ]]
then
readonly is_target_host=1
else
readonly is_target_host=""
fi
if [[ "$operation" = "iso" ]]
then
print_info "Building iso image"
readonly nixos_iso_path=$(nix build --no-link --json "path:$MACHINES_PATH#nixosConfigurations.$hostname.config.system.build.iso" | jq --raw-output ".[0].outputs.out")
print_info "Iso generated"
print $nixos_iso_path
exit 0
fi
print_info "Evaluating target system configuration"
readonly system_installable="path:$MACHINES_PATH#nixosConfigurations.$hostname.config.system.build.toplevel"
readonly nixos_config_path=$(nix path-info --json "$system_installable" | jq --raw-output ".[0].path")
print >&2 "$nixos_config_path"
print_info "Deploying target system configuration"
if [[ "$is_target_host" || "$operation" = "build" ]]
then
# local deploy
print_info "Building target system configuration"
if [[ "$operation" = "build" ]]
then
print_info "Build completed"
print $nixos_config_path
exit 0
fi
if [[ -n "$set_profile" ]]
then
sudo nix-env --profile /nix/var/nix/profiles/system --set $nixos_config_path
fi
sudo $nixos_config_path/bin/switch-to-configuration $operation
sync
if [[ -n "$reboot" ]]
then
sudo systemctl reboot
fi
else
# remote deploy
nix copy --substitute-on-destination --to "ssh://root@$via_hostname" "$system_installable"
if [[ -n "$set_profile" ]]
then
ssh root@$via_hostname "nix-env --profile /nix/var/nix/profiles/system --set $nixos_config_path"
fi
ssh root@$via_hostname "$nixos_config_path/bin/switch-to-configuration $operation && sync"
# This should work instead, but has some bugs at the moment
#nixos-rebuild "$operation" --flake "path:$MACHINES_PATH#$hostname" --target-host "root@$via_hostname"
if [[ -n "$reboot" ]]
then
ssh root@$via_hostname "systemctl reboot"
fi
fi
print_info "Update completed"