Script
This is a small script which is serving as installer for this project. It basically:
- Sets up an environment to install the system from
- Asks for basic information such as the disk to be used or the username
- Sets up the partition layout via disko and mounting the partitions to
/mnt
- Provides a basic, quite generic dr460nixed template and customizes it based on previous choices
- Executes the installation
#!/usr/bin/env bash
set -eo pipefail
# Check for root rights
if [ "$EUID" -ne 0 ]; then
echo "I can only run as root!"
exit 3
fi
# Prepare our environment
prepare() {
# Clone dr460nixed repo if it is not present, otherwise use current dir
if [ ! "$(test -f flake.nix)" ]; then
test -d /tmp/dr460nixed && sudo rm -rf /tmp/dr460nixed
WORK_DIR=/tmp/dr460nixed
git clone https://github.com/dr460nf1r3/dr460nixed.git "$WORK_DIR"
cd "$WORK_DIR"
else
WORK_DIR=$(pwd)
fi
# Ensure needed "experimental" features are always enabled
export NIX_CONFIG="experimental-features = nix-command flakes"
}
# Confirmation prompt
confirm_choices() {
# Continue if the user confirms our choice
read -rp "Are you sure you want to continue? $1 [y/n] " _ANSWER
while [ -z "${KILLIT+x}" ]; do
case "${_ANSWER}" in
y | yes | Y | YES)
KILLIT=1
;;
n | no | N | NO)
exit 1
;;
*)
read -rp "Invalid input. Only yes or no is valid: " _ANSWER
;;
esac
done
}
# Create a runner for disko, directly from git
disko_runner() {
nix run github:nix-community/disko -- --mode disko "$1" --arg disks "[ \"$2\" ]"
}
# Create partitions using disko and mount them to /mnt
disko() {
echo "The following partition layouts are available:
1) BTRFS with subvolumes
2) BTRFS on LUKS with subvolumes
3) Simple EFI
4) ZFS (recommended)
5) ZFS encrypted"
read -rp "Enter the number of the partition layout you want to use: " _LAYOUT
# https://stackoverflow.com/questions/3601515/how-to-check-if-a-variable-is-set-in-bash
while [ -z "${DISKO_MODULE+x}" ]; do
case "${_LAYOUT}" in
1)
DISKO_MODULE=btrfs-subvolumes
;;
2)
DISKO_MODULE=luks-btrfs-subvolumes
;;
3)
DISKO_MODULE=simple-efi
;;
4)
DISKO_MODULE=zfs-encrypted
;;
5)
DISKO_MODULE=zfs
;;
*)
read -rp "Invalid input. Enter the number of the partition layout you want to use: " _LAYOUT
;;
esac
done
while [ -z "${_VALID_DISK+x}" ]; do
read -rp "Specify the disk you want to use, eg. \"nvme0n1\": " DISK
# Disk identifiers should at least be 3 characters long and be present in our system
# this does not prevent all possible errors (eg. nvme0 would be valid) but good enough for now
if [ ${#DISK} -gt 2 ] && lsblk | grep "$DISK"; then
_VALID_DISK=1
else
echo "The disk you entered is invalid! Try again."
fi
done
# Ask whether the hard drive should really be wiped
echo "The disk you chose to format is $DISK."
confirm_choices "This will start the wiping process!"
# Create partitions and set up /mnt
disko_runner ./nixos/modules/disko/"$DISKO_MODULE".nix /dev/"$DISK"
}
# Create initial configuration
create_config() {
NIX_ROOT=/mnt/etc/nixos
read -rp "Enter the hostname you want to use: " HOSTNAME
read -rp "Enter your desired username: " USER
[ -d /sys/firmware/efi ] && SYSTEM_TYPE=systemd-boot || SYSTEM_TYPE=grub
# Create config without filesystems as disko provides those already
# also apply our dr460nixed template
nixos-generate-config --no-filesystems --root /mnt
pushd "$NIX_ROOT" || exit 2
nix flake init --template "$WORK_DIR"#dr460nixed
mv ./hardware-configuration.nix ./nixos/example-host
rm ./configuration.nix # we are using flakes, no need for that anymore
mv ./nixos/example-host ./nixos/"$HOSTNAME"
mv ./nixos/"$HOSTNAME"/example-host.nix ./nixos/"$HOSTNAME"/"$HOSTNAME".nix
sed -i s/example-boot/"$SYSTEM_TYPE"/g ./nixos/"$HOSTNAME"/"$HOSTNAME".nix
sed -i s/example-disk/"$DISK"/g .{/nixos/flake-module.nix,nixos/"$HOSTNAME"/"$HOSTNAME".nix}
sed -i s/example-hostname/"$HOSTNAME"/g {./nixos/flake-module.nix,nixos/"$HOSTNAME"/"$HOSTNAME".nix}
sed -i s/example-layout/"$DISKO_MODULE"/g ./nixos/flake-module.nix
sed -i s/example-user/"$USER"/g ./nixos/modules/users.nix
echo "Configuration successfully created.
You made the following choices:
hostname: $HOSTNAME
user: $USER"
confirm_choices "This starts the installation process."
popd || exit 2
}
# Install basic dr460nixed system
install_system() {
nixos-install --flake "$NIX_ROOT#$HOSTNAME" --verbose
}
# Notices
finish() {
echo "The installation finished successfully. You may now reboot into your new system."
confirm_choices "This will remove the temporary directory an reboot the system."
umount -Rf /mnt
rm -rf "$WORK_DIR"
}
# Actually execute our functions
prepare
disko
create_config
install_system
finish