Files
Nomarchy/installer/install-nomarchy.sh
2026-04-06 21:41:14 +01:00

317 lines
10 KiB
Bash

#!/usr/bin/env bash
set -e
# Nomarchy Installer
# Professionalized with Gum
# Function to display stylized headers
header() {
clear
gum style \
--foreground 212 --border-foreground 212 --border double \
--align center --width 50 --margin "1 2" --padding "2 4" \
"NOMARCHY" "The Omarchy-flavored NixOS"
}
# Function to show a section header
section() {
echo
gum style --foreground 10 --bold "» $1"
}
header
section "Environment Check"
gum spin --spinner dot --title "Verifying internet connection..." -- sleep 1
while ! ping -c 1 8.8.8.8 &> /dev/null; do
gum style --foreground 9 "Error: No internet connection detected."
CHOICE=$(gum choose "Open Network Manager (nmtui)" "Retry Connection" "Exit Installer")
if [ "$CHOICE" = "Open Network Manager (nmtui)" ]; then
nmtui
elif [ "$CHOICE" = "Exit Installer" ]; then
echo "Exiting installer."
exit 1
fi
done
echo "✓ Internet connection verified."
# 0. Environment Setup
NOMARCHY_REPO=""
if [ -d "/etc/nomarchy" ]; then
NOMARCHY_REPO="/etc/nomarchy"
elif [ -d "$(dirname "$0")/.." ] && [ -f "$(dirname "$0")/../flake.nix" ]; then
NOMARCHY_REPO="$(realpath "$(dirname "$0")/..")"
fi
if [ -z "$NOMARCHY_REPO" ]; then
gum style --foreground 9 "Error: Nomarchy repository not found."
exit 1
fi
# 1. Hardware Detection
section "Hardware Detection"
PRODUCT_NAME=$(cat /sys/class/dmi/id/product_name 2>/dev/null || echo "Unknown")
CPU_VENDOR=$(lscpu | grep "Vendor ID" | awk '{print $3}')
echo "Detected Device: $PRODUCT_NAME"
echo "Detected CPU: $CPU_VENDOR"
HARDWARE_MODULES=""
NOMARCHY_HW_OPTS=""
if [[ "$CPU_VENDOR" == "AuthenticAMD" ]]; then
HARDWARE_MODULES="inputs.nixos-hardware.nixosModules.common-cpu-amd"
elif [[ "$CPU_VENDOR" == "GenuineIntel" ]]; then
HARDWARE_MODULES="inputs.nixos-hardware.nixosModules.common-cpu-intel"
fi
echo "Select your hardware vendor for optimized profiles:"
VENDOR=$(gum choose --header "Hardware Vendor" \
"acer" "apple" "asus" "dell" "framework" "google" "hp" "lenovo" "microsoft" "msi" "purism" "samsung" "starlabs" "system76" "toshiba" "None/Generic")
if [ "$VENDOR" != "None/Generic" ]; then
case $VENDOR in
dell)
MODEL=$(gum choose "xps-13-9300" "xps-13-9310" "xps-13-9343" "xps-13-9360" "xps-13-9370" "xps-13-9380" "xps-15-7590" "xps-15-9500" "xps-15-9510" "xps-15-9550" "precision-5510" "precision-5530")
HARDWARE_MODULES="$HARDWARE_MODULES\n inputs.nixos-hardware.nixosModules.dell-$MODEL"
[[ "$MODEL" == *"xps"* ]] && NOMARCHY_HW_OPTS="nomarchy.hardware.isXPS = true;"
;;
lenovo)
MODEL=$(gum choose "thinkpad-x1-carbon-gen7" "thinkpad-x1-carbon-gen8" "thinkpad-x1-carbon-gen9" "thinkpad-x1-carbon-gen10" "thinkpad-x1-extreme" "thinkpad-t480" "thinkpad-t490" "thinkpad-t14-amd" "thinkpad-t14-intel" "thinkpad-p1-gen3")
HARDWARE_MODULES="$HARDWARE_MODULES\n inputs.nixos-hardware.nixosModules.lenovo-$MODEL"
;;
framework)
MODEL=$(gum choose "13-7040-amd" "13-intel-12th-gen" "13-intel-13th-gen" "16-7040-amd")
HARDWARE_MODULES="$HARDWARE_MODULES\n inputs.nixos-hardware.nixosModules.framework-$MODEL"
NOMARCHY_HW_OPTS="nomarchy.hardware.isFramework = true;"
;;
microsoft)
MODEL=$(gum choose "surface-pro-7" "surface-pro-8" "surface-pro-9" "surface-laptop-3" "surface-laptop-4")
HARDWARE_MODULES="$HARDWARE_MODULES\n inputs.nixos-hardware.nixosModules.microsoft-$MODEL"
;;
apple)
MODEL=$(gum choose "macbook-pro-12-1" "macbook-air-6-2" "t2")
if [ "$MODEL" == "t2" ]; then
NOMARCHY_HW_OPTS="nomarchy.hardware.isT2Mac = true;"
else
HARDWARE_MODULES="$HARDWARE_MODULES\n inputs.nixos-hardware.nixosModules.apple-$MODEL"
fi
;;
*)
INPUT_MOD=$(gum input --placeholder "Enter nixos-hardware module path")
HARDWARE_MODULES="$HARDWARE_MODULES\n $INPUT_MOD"
;;
esac
fi
# 2. Storage Setup
section "Storage & Partitioning"
DRIVES=$(lsblk -d -n -p -o NAME,SIZE | grep -v loop)
TARGET_DRIVE=$(echo "$DRIVES" | gum choose --header "Select target drive" | awk '{print $1}')
if [ -z "$TARGET_DRIVE" ]; then exit 1; fi
LAYOUT=$(gum choose "Standard Ext4" "Encrypted BTRFS (LUKS2)")
IMPERMANENCE="No"
if [ "$LAYOUT" = "Standard Ext4" ]; then
DISKO_FILE="installer/disko-ext4.nix"
else
DISKO_FILE="installer/disko-btrfs-luks.nix"
echo "Enable Impermanence? (Erase root on every boot)"
IMPERMANENCE=$(gum choose "No" "Yes")
fi
# 3. User & Localization
section "User & Localization"
USERNAME=$(gum input --placeholder "Enter target username (no spaces)")
if [ -z "$USERNAME" ]; then exit 1; fi
USER_PASSWORD=$(gum input --password --placeholder "Enter password for $USERNAME")
USER_PASSWORD_CONFIRM=$(gum input --password --placeholder "Confirm password")
if [ "$USER_PASSWORD" != "$USER_PASSWORD_CONFIRM" ]; then
gum style --foreground 9 "Error: Passwords do not match."
exit 1
fi
echo "Select Timezone:"
TIMEZONES=$(timedatectl list-timezones || echo "UTC")
TIMEZONE=$(echo "$TIMEZONES" | gum filter --placeholder "Type to search...")
[ -z "$TIMEZONE" ] && TIMEZONE="UTC"
echo "Select Keyboard Layout:"
KEYBOARD_LAYOUT=$(gum choose "us" "uk" "de" "fr" "es" "it" "br-abnt2" "latam" "Other...")
if [ "$KEYBOARD_LAYOUT" = "Other..." ]; then
KEYBOARD_LAYOUT=$(gum input --placeholder "Enter layout (e.g. jp)")
fi
# 4. Software Profiles
section "Software Profiles"
echo "Select additional profiles (Space to toggle):"
PROFILES=$(gum choose --no-limit "Development (VSCode, Docker, DBs)" "Gaming (Steam, Lutris)" "Media Production (OBS, Kdenlive)")
PROFILE_HOME_PKGS=""
PROFILE_SYSTEM_CONFIG=""
[[ $PROFILES == *"Development"* ]] && PROFILE_HOME_PKGS="$PROFILE_HOME_PKGS\n vscode\n docker-compose\n dbeaver-bin" && PROFILE_SYSTEM_CONFIG="$PROFILE_SYSTEM_CONFIG\n virtualisation.docker.enable = true;"
[[ $PROFILES == *"Gaming"* ]] && PROFILE_HOME_PKGS="$PROFILE_HOME_PKGS\n lutris\n protonup-qt\n mangohud" && PROFILE_SYSTEM_CONFIG="$PROFILE_SYSTEM_CONFIG\n programs.steam.enable = true;"
[[ $PROFILES == *"Media Production"* ]] && PROFILE_HOME_PKGS="$PROFILE_HOME_PKGS\n obs-studio\n kdenlive\n gimp\n audacity"
[[ "$IMPERMANENCE" == "Yes" ]] && PROFILE_SYSTEM_CONFIG="$PROFILE_SYSTEM_CONFIG\n nomarchy.system.impermanence.enable = true;"
# 5. Review
section "Review Configuration"
echo "Target Drive: $TARGET_DRIVE"
echo "Layout: $LAYOUT (Impermanence: $IMPERMANENCE)"
echo "User: $USERNAME"
echo "Timezone: $TIMEZONE"
echo "Profiles: $PROFILES"
if ! gum confirm "Ready to begin installation?"; then
echo "Aborted."
exit 0
fi
# 6. Execution
section "Executing Installation"
# 6.1. Partitioning
gum spin --spinner pulse --title "Partitioning $TARGET_DRIVE..." -- bash -c "
DISKO_NIX=\"$NOMARCHY_REPO/$DISKO_FILE\"
TMP_DISKO=\$(mktemp --suffix=.nix)
sed \"s|@TARGET_DRIVE@|$TARGET_DRIVE|g\" \"\$DISKO_NIX\" > \"\$TMP_DISKO\"
sudo env PATH=\"\$PATH\" disko --mode disko \"\$TMP_DISKO\"
"
# 6.2. Scaffold Config
gum spin --spinner pulse --title "Generating NixOS configuration..." -- bash -c "
mkdir -p /mnt/etc/nixos/
cat <<EOF > /mnt/etc/nixos/login-preference.nix
{
services.displayManager.autoLogin.enable = true;
services.displayManager.autoLogin.user = \"$USERNAME\";
}
EOF
cat <<EOF > /mnt/etc/nixos/localization.nix
{
time.timeZone = \"$TIMEZONE\";
services.xserver.xkb.layout = \"$KEYBOARD_LAYOUT\";
console.keyMap = \"$KEYBOARD_LAYOUT\";
}
EOF
cat <<EOF > /mnt/etc/nixos/hardware-selection.nix
{ inputs, ... }:
{
imports = [
\$(echo -e \"$HARDWARE_MODULES\")
];
$NOMARCHY_HW_OPTS
}
EOF
nixos-generate-config --root /mnt
cat <<EOF > /mnt/etc/nixos/system.nix
{ pkgs, ... }:
{
\$(echo -e \"$PROFILE_SYSTEM_CONFIG\")
users.users.\"$USERNAME\" = {
isNormalUser = true;
initialPassword = \"$USER_PASSWORD\";
extraGroups = [ \"networkmanager\" \"wheel\" \"video\" \"audio\" ];
};
system.stateVersion = \"25.11\";
environment.systemPackages = with pkgs; [];
}
EOF
cat <<EOF > /mnt/etc/nixos/home.nix
{ pkgs, ... }:
{
home.packages = with pkgs; [
\$(echo -e \"$PROFILE_HOME_PKGS\")
];
}
EOF
cat <<EOF > /mnt/etc/nixos/flake.nix
{
description = \"My Nomarchy - Downstream Configuration\";
inputs = {
nixpkgs.url = \"github:nixos/nixpkgs/nixos-25.11\";
nomarchy.url = \"git+https://git.bemagri.xyz/bernardo/Nomarchy.git\";
nixos-hardware.url = \"github:NixOS/nixos-hardware/master\";
home-manager = {
url = \"github:nix-community/home-manager/release-25.11\";
inputs.nixpkgs.follows = \"nixpkgs\";
};
};
outputs = { self, nixpkgs, nomarchy, home-manager, ... }@inputs: {
nixosConfigurations.default = nixpkgs.lib.nixosSystem {
specialArgs = { inputs = nomarchy.inputs // inputs; };
modules = [
{ nixpkgs.hostPlatform = \"x86_64-linux\"; }
./hardware-configuration.nix
./hardware-selection.nix
./login-preference.nix
./localization.nix
nomarchy.nixosModules.system
./system.nix
home-manager.nixosModules.home-manager
{
home-manager.useGlobalPkgs = true;
home-manager.useUserPackages = true;
home-manager.extraSpecialArgs = { inherit inputs; };
home-manager.users.$USERNAME = {
imports = [ nomarchy.nixosModules.home ./home.nix ];
home.username = \"$USERNAME\";
home.homeDirectory = \"/home/$USERNAME\";
home.stateVersion = \"25.11\";
};
}
];
};
};
}
EOF
"
# 6.3. Git Init
cd /mnt/etc/nixos/
git init
git add .
git config user.name "Nomarchy Installer"
git config user.email "installer@nomarchy"
git commit -m "Initial Nomarchy generation"
# 6.4. Impermanence logic
if [[ "$IMPERMANENCE" == "Yes" ]]; then
echo "Redirecting to persistent storage..."
mkdir -p /mnt/persist/etc
mv /mnt/etc/nixos /mnt/persist/etc/
mkdir -p /mnt/etc
ln -s /persist/etc/nixos /mnt/etc/nixos
fi
# 6.5. Install
section "Installing System"
echo "Starting nixos-install. This will take some time..."
sudo nixos-install --flake /mnt/etc/nixos#default --no-root-passwd
# 7. Finished
header
gum style --foreground 10 --bold "INSTALLATION COMPLETE!"
echo "Nomarchy has been successfully installed on $TARGET_DRIVE."
echo
echo "What's next?"
echo "1. Remove the installation media."
echo "2. Reboot your computer."
echo "3. Log in and run 'nomarchy-update' to finish setup."
echo
if gum confirm "Reboot now?"; then
reboot
fi