Aquatic-Nix/modules/hosts/installer-iso/installer/installer.sh

281 lines
No EOL
7.9 KiB
Bash

#!/usr/bin/env bash
#Check if the script is being run as root
echo -e "\n\e[32m[INSTALL] PREFORMING PRE-RUN CHECKS\e[0m"
if [[ $EUID -ne 0 ]]; then
echo "This script must be run as root" 1>&2
exit 1
fi
#Check if with sudo and not "real root"
if [[ -z "$SUDO_USER" ]]; then
echo "This script must be run with sudo (not as a direct root login) so it knows which user's SSH/agenix identity to use" 1>&2
exit 1
fi
#Init Variables
echo -e "\n\e[32m[INSTALL] INITIALIZING VARIABLES\e[0m"
configSource="ssh://git@git.aquaticservers.com/aqua/AquaticOS.git"
configBranch="auto-install-script"
configName="AquaticOS"
newHostname=""
systemType=""
installDisk=""
installDiskID=""
shouldEncrypt=false
#Init functions
initializeDependencies() {
echo -e "\n\e[32m[INSTALL] INITIALIZING DEPENDANCIES\e[0m"
rm -rf /tmp/installer
sudo -u "$SUDO_USER" mkdir -p /tmp/installer
sudo -u "$SUDO_USER" git clone -b $configBranch --recurse-submodules $configSource /tmp/installer/$configName
}
listSystemTypes() {
ls "/tmp/installer/$configName/modules/system/types/" | cut -c 4- | sed 's/\.nix$//'
}
askForConfig() {
echo -e "\n\e[32m[INSTALL] ASKING FOR REQUIRED INFORMATION\e[0m"
echo "What is the hostname of this machine?"
read newHostname
echo
echo "Available types:"
#Parse the available system types from the config
listSystemTypes
echo "What system type do you want to use? (will be ignored if host config already exists)"
read systemType
echo
echo "Available Disks:"
lsblk --nodeps --noheadings --output NAME,SIZE,MODEL
echo "What disk do you want to install onto?"
read installDisk
echo
echo "Do you want to encrypt the disk? (y/n)"
read encryptChoice
if [[ $encryptChoice == "y" ]]; then
shouldEncrypt=true
else
shouldEncrypt=false
fi
}
confirmConfig() {
#Check if disk or system type actually exists
if [[ ! -b "/dev/$installDisk" ]]; then
echo -e "\n\e[31m[INSTALL] ERROR: DISK $installDisk DOES NOT EXIST\e[0m"
getConfigVars
elif ! listSystemTypes | grep -qxF "$systemType"; then
echo -e "\n\e[31m[INSTALL] ERROR: SYSTEM TYPE $systemType DOES NOT EXIST\e[0m"
getConfigVars
else
#Confirm the configuration with the user
echo -e "\n\e[32m[INSTALL] CONFIRMING CONFIGURATION\e[0m"
echo "You chose:"
echo "Hostname - " $newHostname
echo "System Type - " $systemType
echo "Install Disk - " $installDisk
echo "Encrypted - " $shouldEncrypt
echo "Is this correct? (y/n)"
read confirmation
if [[ $confirmation != "y" ]]; then
getConfigVars
fi
fi
}
getConfigVars() {
askForConfig
confirmConfig
}
prepAutoInstall() {
#Log start of automated install
echo -e "\n\e[32m[INSTALL] BEGINNING INSTALL PROCESS\e[0m"
#Grab install disk ID
installDiskID="/dev/$(udevadm info --query=symlink --name="/dev/$installDisk" | tr ' ' '\n' | grep '^disk/by-id/' | head -n1)"
}
generateSSHKeys() {
echo -e "\n\e[32m[INSTALL] GENERATING SSH KEYS\e[0m"
sudo -u "$SUDO_USER" mkdir -p /tmp/installer/keys
sudo -u "$SUDO_USER" ssh-keygen -t ed25519 -f /tmp/installer/keys/id_ed25519 -N ""
}
rekeyAllSecrets() {
#Roll SSH keys for new system into secrets.nix in config
echo -e "\n\e[32m[INSTALL] UPDATING SECRETS.NIX\e[0m"
secretsFile="/tmp/installer/$configName/secrets/secrets.nix"
pubkey=$(sed 's/ [^ ]*$//' /tmp/installer/keys/id_ed25519.pub)
#Set or add the key line
if grep -q "^[[:space:]]*$newHostname = " "$secretsFile"; then
sed -i "s|^\([[:space:]]*$newHostname = \).*|\1\"$pubkey\";|" "$secretsFile"
else
newKey=" $newHostname = \"$pubkey\";"
sed -i "s|^[[:space:]][[:space:]]systems =|$newKey\n&|" "$secretsFile"
fi
#Ensure it's in the systems list
if ! sed -n '/^[[:space:]]*systems = \[/,/^[[:space:]]*\];/p' "$secretsFile" \
| grep -qx "[[:space:]]*$newHostname"; then
sed -i "/^[[:space:]]*systems = \[/,/^[[:space:]]*\];/{
/^[[:space:]]*\];/i\\ $newHostname
}" "$secretsFile"
fi
#Re-key all secrets
echo -e "\e[32m[INSTALL] RE-KEYING ALL SECRETS\e[0m"
pushd /tmp/installer/$configName/secrets/
agenix --rekey --identity /etc/ssh/ssh_host_ed25519_key
popd
}
generateFlakeParts() {
cat << EOF > /tmp/installer/$configName/modules/custom/hosts/$newHostname/flake-parts.nix
{ inputs, ... }:
{
flake.nixosConfigurations = inputs.self.lib.mkNixos "x86_64-linux" "$newHostname";
}
EOF
}
generateFilesystemConfigEncrypted() {
cat << EOF > /tmp/installer/$configName/modules/custom/hosts/$newHostname/filesystems.nix
{ inputs, ... }:
{
flake.modules.nixos.$newHostname =
{ pkgs, config, ... }:
{
imports = with inputs.self.modules.nixos; [
disko-encrypted
];
disko.device = "$installDiskID";
};
}
EOF
}
generateFilesystemConfigUnencrypted() {
cat << EOF > /tmp/installer/$configName/modules/custom/hosts/$newHostname/filesystems.nix
{ inputs, ... }:
{
flake.modules.nixos.$newHostname =
{ pkgs, config, ... }:
{
imports = with inputs.self.modules.nixos; [
disko
];
disko.device = "$installDiskID";
};
}
EOF
}
generateFilesystemConfig() {
if [[ $shouldEncrypt == true ]]; then
generateFilesystemConfigEncrypted
else
generateFilesystemConfigUnencrypted
fi
}
generateMainConfig() {
cat << EOF > /tmp/installer/$configName/modules/custom/hosts/$newHostname/configuration.nix
{ inputs, ... }:
{
flake.modules.nixos.$newHostname = {
networking.hostName = "$newHostname";
imports = with inputs.self.modules.nixos; [
$systemType
];
home-manager.sharedModules = with inputs.self.modules.homeManager; [
$systemType
];
};
}
EOF
}
generateHardwareConfig() {
cat << EOF > /tmp/installer/$configName/modules/custom/hosts/$newHostname/hardware.nix
{ ... }:
{
flake.modules.nixos.$newHostname = {
$(sudo nixos-generate-config --no-filesystems --show-hardware-config \
| grep "^[[:space:]]*boot\." \
| sed 's/^[[:space:]]\{2\}//' \
| sed 's/^/ /')
};
}
EOF
}
generateNewHostConfig() {
#Generate per-host config for system
echo -e "\n\e[32m[INSTALL] GENERATING PER-HOST CONFIG\e[0m"
#Check if host already exists or not
if [[ -d /tmp/installer/$configName/modules/custom/hosts/$newHostname ]]; then
#Host already exists, only generate hardware and filesystem configs
generateHardwareConfig
generateFilesystemConfig
else
#Host does not exist, generate all configs
mkdir -p /tmp/installer/$configName/modules/custom/hosts/$newHostname
generateFlakeParts
generateHardwareConfig
generateFilesystemConfig
generateMainConfig
fi
}
partitionDisk() {
echo -e "\n\e[32m[INSTALL] PARTITIONING DISK WITH DISKO\e[0m"
nix --experimental-features "nix-command flakes" run github:nix-community/disko -- --mode disko --flake "path:/tmp/installer/$configName#$newHostname"
}
installConfig() {
echo -e "\n\e[32m[INSTALL] INSTALLING CONFIG ONTO NEW SYSTEM\e[0m"
nixos-install --root /mnt --flake "path:/tmp/installer/$configName#$newHostname" --no-root-password
}
loadFilesOnSystem() {
#Move config onto new system
echo -e "\n\e[32m[INSTALL] MOVING CONFIG ONTO NEW SYSTEM\e[0m"
cp -r "/tmp/installer/$configName" "/mnt/$configName"
#Move SSH keys onto new system
echo -e "\n\e[32m[INSTALL] MOVING SSH KEYS ONTO NEW SYSTEM\e[0m"
mkdir -p /mnt/etc/ssh
cp /tmp/installer/keys/id_ed25519 /mnt/etc/ssh/ssh_host_ed25519_key
cp /tmp/installer/keys/id_ed25519.pub /mnt/etc/ssh/ssh_host_ed25519_key.pub
chmod 0600 /mnt/etc/ssh/ssh_host_ed25519_key
chmod 0644 /mnt/etc/ssh/ssh_host_ed25519_key.pub
}
fixPermissionsOnConfig() {
echo -e "\n\e[32m[INSTALL] FIXING PERMISSIONS ON CONFIG\e[0m"
chown -R root:wheel /mnt/$configName
find /mnt/$configName -type d -exec chmod 775 {} \;
find /mnt/$configName -type f -exec chmod 664 {} \;
}
#Run through functions
initializeDependencies
getConfigVars
prepAutoInstall
generateSSHKeys
rekeyAllSecrets
generateNewHostConfig
partitionDisk
installConfig
loadFilesOnSystem
fixPermissionsOnConfig