Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#!/usr/bin/env zsh
set -e
# fail on undeclared variable
set -u
set -o pipefail
readonly cmdname=$(basename $0)
nixos_system_file=$MACHINES_PATH/nixos.nix
# This script cannot run without the nixos configuration entry point
if [[ ! -f "$nixos_system_file" ]]
then
print -P "%B%F{red}Error: %F{orange}nixos.nix%F{red} not found%b%f" >&2
exit 2
fi
source $DOTFILES_PATH/bin/util.zsh
usage() {
print "Usage: $cmdname [--via via_hostname] <hostname> [switch|boot|reboot|test|dry-activate|build]" >&2
}
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" ]]
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
readonly local_temp_dir=$(mktemp --tmpdir --directory phoenix-deploy.XXXXXXXXXX)
trap "rm -rf $local_temp_dir" EXIT INT HUP TERM
print_info "Building target system configuration"
nix build --file "$nixos_system_file" --argstr hostname "$hostname" --out-link "$local_temp_dir/nixos-config-$hostname"
readonly nixos_config_path=$(realpath "$local_temp_dir/nixos-config-$hostname")
if [[ "$operation" = "build" ]]
then
print_info "Build completed"
print $nixos_config_path
exit 0
fi
print_info "Deploying target system configuration"
if [[ "$is_target_host" ]]
then
# local deploy
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 --file "$nixos_system_file" --argstr hostname "$hostname" --to "ssh://root@$via_hostname"
# The manual way to do it (this is in theory also supported by nixos-rebuild by using '-I')
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"
if [[ -n "$reboot" ]]
then
ssh root@$via_hostname "systemctl reboot"
fi
fi
print_info "Update completed"