forked from iynaix/dotfiles
-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathinstall.sh
executable file
·460 lines (380 loc) · 14.1 KB
/
install.sh
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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
#!/usr/bin/env bash
set -e
echo "Current latest remote commit:"
git ls-remote -h https://github.com/rotteegher/rotfiles master
echo ""
# Check for fzf
if ! [ -x "$(command -v fzf)" ]; then
echo "fzf: command not found."
echo "Installing fzf"
nix-env -iA nixos.fzf
fi
function yesno() {
local prompt="$1"
while true; do
read -rp "$prompt [y/n] " yn
case $yn in
[Yy]* ) echo "y"; return;;
[Nn]* ) echo "n"; return;;
* ) echo "Please answer yes or no.";;
esac
done
}
function prompt_for_password() {
while true; do
# Prompt for password
read -rs -p "Enter root password: " password
printf "\n"
# Prompt for password confirmation
read -rs -p "Confirm root password: " confirm_password
printf "\n"
# Check if passwords match
if [ "$password" == "$confirm_password" ]; then
break
else
echo "Passwords do not match. Please try again."
fi
done
# Return the entered password
echo "$password"
}
cat << Introduction
This script will format the *entire* disk with a 1GB boot partition
(labelled NIXBOOT), 16GB of swap, then allocating the rest to ZFS.
OR BY CHOICE
This script will format selected by user boot, swap, root partitions
on already existing partition table.
The following ZFS datasets will be created on the root:
- zroot/root (mounted at / with blank snapshot)
- zroot/nix (mounted at /nix)
- zroot/tmp (mounted at /tmp)
- zroot/persist (mounted at /persist)
- zroot/persist/cache (mounted at /persist/cache)
Introduction
# in a vm, special case
if [[ -b "/dev/vda" ]]; then
DISK="/dev/vda"
BOOTDISK="${DISK}3"
SWAPDISK="${DISK}2"
ZFSDISK="${DISK}1"
# normal disk
else
cat << FormatWarning
YOUR DISK IS ABOUT TO BE FORMATTED
FormatWarning
install_type=$(yesno "Do you wish to install onto a whole empty disk [y]; or select existing partitions manually? [n];")
if [[ $install_type == "y" ]]; then
# FULL DISK SELECTION
# Select whole disk
DISKINPUT=$(ls -r /dev/disk/by-id/ | fzf --prompt="Select disk to install nixos on [WITHOUT '-part']: " | cut -d ' ' -f 1)
if [[ $DISKINPUT == *part* ]]; then
echo "Error: Select full disk without 'part' in the id name."
exit
fi
echo "Your disk is: $DISKINPUT"
echo ""
DISK="/dev/disk/by-id/${DISKINPUT}"
# Check if the specified disk exists
if [[ -e $DISK && ! -d $DISK ]]; then
BOOTDISK="${DISK}-part1"
SWAPDISK="${DISK}-part2"
ZFSDISK="${DISK}-part3"
else
echo "Error: Selected disk not found in /dev/disk/by-id directory."
exit
fi
# Selected partitions
echo "Selected partitions:"
echo " Boot Partiton [NIXBOOT] - '$BOOTDISK'"
echo " SWAP Partiton [SWAP] - '$SWAPDISK'"
echo " ZFS Root Partiton [zroot] - '$ZFSDISK'"
# Format Confirmation
do_format=$(yesno "This irreversibly formats the entire disk. Are you sure?")
if [[ $do_format != "y" ]]; then
exit
fi
# warning countdown
for i in {5..0}; do
message="Formatting in $i seconds... <Ctrl + C> to EXIT NOW!\r"
echo -e "\x1b[30;47m $message \x1b[0m"
sleep 1
done
echo ""
# DO INSTALL FULL DISK
# RUN CHECKS
echo "Checking mountpoint ''/mnt/boot':"
# Check boot partition
sudo mkdir -p /mnt/boot
if mountpoint -q /mnt/boot; then
echo "Unmounting /mnt/boot"
sudo umount -f /mnt/boot || true
fi
echo "Checking swap status for: $SWAPDISK"
# Check swap partition
if [ -b "$SWAPDISK" ]; then
swap_device=$(readlink -f "$SWAPDISK")
echo "Swap device: $swap_device"
# Check if the swap is currently on
if swapon --show | grep -q "$swap_device"; then
echo "Swap '$swap_device' is currently on."
echo "Turning off SWAP device: $SWAPDISK"
sudo swapoff "$SWAPDISK"
else
echo "Swap is already off. Continuing..."
fi
fi
echo "Checking for zpool 'zroot' if exists"
if zpool list zroot; then
do_reinstall=$(yesno "'zroot' zfs pool already exists. Reinstall? [This will DESTROY zpool 'zroot'!]")
if [[ $do_reinstall != "y" ]]; then
echo "Make sure there is no zpool 'zroot' pool to install!"
exit
else
# warning countdown
for i in {5..0}; do
message="Destroying zpool 'zroot' in $i seconds... <Ctrl + C> to EXIT NOW\r"
echo -e "\x1b[30;47m $message \x1b[0m"
sleep 1
done
echo ""
if mountpoint /mnt; then
sudo umount -R -f /mnt
fi
sudo zpool destroy zroot
fi
fi
echo ""
# POPULATE PARTITIONS ON THE WHOLE DISK
echo "Creating partitions"
sudo blkdiscard -f "$DISK"
echo "Creating Boot partition"
sudo sgdisk -n1:1M:+1G -t1:EF00 "$DISK"
echo "Creating Swap partition"
sudo sgdisk -n2:0:+16G -t2:8200 "$DISK"
echo "Creating Root partition for the remainder of the disk"
sudo sgdisk -n3:0:0 -t3:BF01 "$DISK"
# notify kernel of partition changes
sudo sgdisk -p "$DISK" > /dev/null
sync
sleep 5
echo "Formatting Boot partition"
sudo mkfs.fat -F 32 "$BOOTDISK"
sudo fatlabel "$BOOTDISK" NIXBOOT
echo "Setting up Swap"
sudo mkswap "$SWAPDISK" -L "SWAP"
sudo swapon "$SWAPDISK"
# setup encryption
use_encryption=$(yesno "Use encryption? (Encryption must also be enabled within host config.)")
if [[ $use_encryption == "y" ]]; then
encryption_options=(-O encryption=aes-256-gcm -O keyformat=passphrase -O keylocation=prompt)
else
encryption_options=()
fi
echo ""
echo "Created partitions: "
lsblk -o NAME,SIZE,TYPE,LABEL,ID-LINK "$DISK"
echo ""
echo "Proceeding to ZFS setup on '${ZFSDISK}' ..."
else
# MANUAL PARTITION SELECTION
BOOTDISK_INPUT=$(ls -r /dev/disk/by-id/ | fzf --prompt="Select Boot Partition: " | cut -d ' ' -f 1)
SWAPDISK_INPUT=$(ls -r /dev/disk/by-id/ | fzf --prompt="Select Swap Partition: " | cut -d ' ' -f 1)
ZFSDISK_INPUT=$(ls -r /dev/disk/by-id/ | fzf --prompt="Select ZFS Root Partition [zroot]: " | cut -d ' ' -f 1)
BOOTDISK="/dev/disk/by-id/${BOOTDISK_INPUT}"
SWAPDISK="/dev/disk/by-id/${SWAPDISK_INPUT}"
ZFSDISK="/dev/disk/by-id/${ZFSDISK_INPUT}"
# CHECK Selected partitions
echo "Selected partitions:"
if [[ -e $BOOTDISK && ! -d $BOOTDISK ]]; then
echo " Boot Partiton [NIXBOOT] - '$BOOTDISK'"
else
echo "'$BOOTDISK' does not exist!"
exit
fi
if [[ -e $SWAPDISK && ! -d $SWAPDISK ]]; then
echo " SWAP Partiton [SWAP] - '$SWAPDISK'"
else
echo "'$BOOTDISK' does not exist!"
exit
fi
if [[ -e $ZFSDISK && ! -d $ZFSDISK ]]; then
echo " ZFS Root Partiton [zroot] - '$ZFSDISK'"
else
echo "'$BOOTDISK' does not exist"
exit
fi
# Format Confirmation
do_format=$(yesno "This irreversibly formats selected partitions. Are you sure?")
if [[ $do_format != "y" ]]; then
exit
fi
# warning countdown
for i in {5..0}; do
message="Formatting in $i seconds... <Ctrl + C> to EXIT NOW\r"
echo -e "\x1b[30;47m $message \x1b[0m"
sleep 1
done
echo ""
# DO INSTALL MANUAL SELECTION
# RUN CHECKS
echo "Checking mountpoint ''/mnt/boot':"
# Check boot partition
sudo mkdir -p /mnt/boot
if mountpoint -q /mnt/boot; then
echo "Unmounting /mnt/boot"
sudo umount -f /mnt/boot || true
fi
echo "Checking swap status for: $SWAPDISK"
# Check swap partition
if [ -b "$SWAPDISK" ]; then
swap_device=$(readlink -f "$SWAPDISK")
echo "Swap device: $swap_device"
# Check if the swap is currently on
if swapon --show | grep -q "$swap_device"; then
echo "Swap '$swap_device' is currently on."
echo "Turning off SWAP device: $SWAPDISK"
sudo swapoff "$SWAPDISK"
else
echo "Swap is already off. Continuing..."
fi
fi
echo "Checking for zpool 'zroot' if exists"
if zpool list zroot; then
do_reinstall=$(yesno "'zroot' zfs pool already exists. Reinstall? [This will DESTROY zpool 'zroot'!]")
if [[ $do_reinstall != "y" ]]; then
echo "Make sure there is no zpool 'zroot' pool to install!"
exit
else
# warning countdown
for i in {5..0}; do
message="Destroying zpool 'zroot' in $i seconds... <Ctrl + C> to EXIT NOW\r"
echo -e "\x1b[30;47m $message \x1b[0m"
sleep 1
done
echo ""
if mountpoint /mnt; then
sudo umount -R -f /mnt
fi
sudo zpool destroy zroot
fi
fi
# FORMAT PARTITIONS
echo "Discarding selected partitions!"
sudo blkdiscard -f "$BOOTDISK"
sudo blkdiscard -f "$SWAPDISK"
sudo blkdiscard -f "$ZFSDISK"
# notify kernel of partition changes
sudo sgdisk -p "$BOOTDISK" > /dev/null
sudo sgdisk -p "$SWAPDISK" > /dev/null
sudo sgdisk -p "$ZFSDISK" > /dev/null
sync
sleep 5
echo "Setting up Swap"
sudo mkswap "$SWAPDISK" -L "SWAP"
sudo swapon "$SWAPDISK"
echo "Formatting Boot Disk"
sudo mkfs.fat -F 32 "$BOOTDISK"
sudo fatlabel "$BOOTDISK" NIXBOOT
# setup encryption
use_encryption=$(yesno "Use encryption? (Encryption must also be enabled within host config.)")
if [[ $use_encryption == "y" ]]; then
encryption_options=(-O encryption=aes-256-gcm -O keyformat=passphrase -O keylocation=prompt)
else
encryption_options=()
fi
echo "Proceeding to ZFS setup..."
fi
fi
# ZFS
echo "Creating base zpool"
sudo zpool create -f \
-o ashift=12 \
-o autotrim=on \
-O compression=zstd \
-O acltype=posixacl \
-O atime=off \
-O xattr=sa \
-O normalization=formD \
-O mountpoint=none \
"${encryption_options[@]}" \
zroot "$ZFSDISK"
echo "Creating 'zroot/root' -> '/'"
sudo zfs create -o mountpoint=legacy zroot/root
sudo zfs snapshot zroot/root@blank
sudo mount -t zfs zroot/root /mnt
# create the boot parition after creating root
echo "Mounting '$BOOTDISK' (ESP) -> '/mnt/boot'"
sudo mount --mkdir "$BOOTDISK" /mnt/boot
echo "Creating 'zroot/nix' -> '/mnt/boot'"
sudo zfs create -o mountpoint=legacy zroot/nix
sudo mount --mkdir -t zfs zroot/nix /mnt/nix
echo "Creating 'zroot/tmp' -> '/mnt/tmp'"
sudo zfs create -o mountpoint=legacy zroot/tmp
sudo mount --mkdir -t zfs zroot/tmp /mnt/tmp
echo "Creating 'root/cache' -> '/mnt/tmp'"
sudo zfs create -o mountpoint=legacy zroot/cache
sudo mount --mkdir -t zfs zroot/cache /mnt/cache
# handle persist, possibly from snapshot
restore_snapshot=$(yesno "Do you want to restore from a persist snapshot?")
if [[ "$restore_snapshot" == "y" ]]; then
snapshot_type=$(yesno "Is snapshot a file?")
if [[ "$snapshot_type" == "y" ]]; then
echo "Tip: use 'zfs send zroot/persist@snapshotname > /path/to/snapshotfile ' to create snapshot file."
echo "Enter full path to snapshot: "
read -r snapshot_file_path
echo ""
echo "Receiving 'zroot/persist' from snapshot '${snapshot_file_path}'"
# shellcheck disable=SC2024 (sudo doesn't affect redirects)
sudo zfs receive -o mountpoint=legacy zroot/persist < "$snapshot_file_path"
else
snapshot_name=$(zfs list -H -t snapshot -r | fzf --prompt="Select snapshot to restore from: " | awk '{print $1}')
echo "Selected snapshot: $snapshot_name"
if zfs list "zroot/persist" &> /dev/null; then
for i in {5..0}; do
message="Destroying 'zroot/persist' in $i seconds... <Ctrl + C> to EXIT NOW!\r"
echo -e "\x1b[30;47m $message \x1b[0m"
sleep 1
done
echo ""
zfs destroy -r zroot/persist
echo "'zroot/persist' destroyed!"
fi
echo ""
echo "Receiving 'zroot/persist' from snapshot '${snapshot_name}''"
sudo zfs send -v $snapshot_name | sudo zfs receive -v -F -o mountpoint=legacy zroot/persist
echo "Completed persist snapshot send: "
zfs list -o 'name,refer' -t snapshot zroot/persist
zfs list -o 'name,used' zroot/persist
fi
else
echo "Creating empty 'zroot/persist' -> '/mnt/persist'"
sudo zfs create -o mountpoint=legacy zroot/persist
fi
echo "Mounting 'zroot/persist' -> /mnt/persist"
sudo mount --mkdir -t zfs zroot/persist /mnt/persist
echo ""
echo "ZFS mounts:"
mount | grep zfs
echo ""
echo "Listing of block devices: "
lsblk -o NAME,SIZE,TYPE,LABEL,ID-LINK
echo ""
echo "ZFS pools:"
zpool list
echo "ZFS filesystems: "
zfs list -t filesystem
echo ""
# use fzf to select host
host=$(echo -e "desktop\nomen" | fzf --prompt="Select a host to install: ")
echo "Selected host: ${host}"
echo ""
echo "Current Directory: $(pwd)"
flake_path=$(yesno "Use current pwd as flake path?")
if [[ $flake_path == "y" ]]; then
echo "Recovering NixOS"
sudo nixos-install --flake .#$host
else
read -rp "Enter git rev for flake (default: master): " git_rev
echo "Recovering NixOS..."
sudo nixos-install --flake "github:rotteegher/rotfiles/${git_rev:-master}#$host"
fi