feat(install): add disko direct-url workflow

This commit is contained in:
randogoth 2026-02-04 15:57:45 +02:00
parent 7a42926fba
commit 973bac7ed0
8 changed files with 154 additions and 92 deletions

View file

@ -1,22 +1,37 @@
Nanuqsaurus NixOS installer Nanuqsaurus NixOS installer
=========================== ===========================
Run the non-interactive installer: Direct-from-URL install (wipes the whole disk)
---------------------------------------------
Pick a stable disk path (prefer /dev/disk/by-id/*) and run:
sudo nix --experimental-features "nix-command flakes" \
run github:nix-community/disko/latest#disko-install -- \
--mode format \
--flake "git+https://codeberg.org/<owner>/<repo>.git#nanuqsaurus" \
--disk main /dev/disk/by-id/<your-disk> \
--mount-point /mnt
ISO shortcut
------------
If you are using the custom ISO from this repo, it embeds the flake at /etc/nixos.
You can run the wrapper script (defaults: DISK=/dev/vda, TARGET_HOST=nanuqsaurus):
sudo /etc/nixos/scripts/install-btrfs.sh sudo /etc/nixos/scripts/install-btrfs.sh
Optionally set DISK and TARGET_HOST (defaults: DISK=/dev/vda, TARGET_HOST=nanuqsaurus) Optionally set DISK, TARGET_HOST, and FLAKE:
sudo DISK=/dev/vda TARGET_HOST=nanuqsaurus /etc/nixos/scripts/install-btrfs.sh sudo DISK=/dev/disk/by-id/<your-disk> TARGET_HOST=nanuqsaurus \
FLAKE="github:<owner>/<repo>" \
/etc/nixos/scripts/install-btrfs.sh
The script wipes the whole disk, creates Btrfs subvolumes (root, home, nix), copies the flake, generates hardware config, and installs. It writes host files under `/etc/nixos/hosts/local-<hostname>.nix` and `local-<hostname>-hardware.nix` (kept local to the machine). This uses disko to create a GPT disk with a 550M EFI partition and a Btrfs partition
containing subvolumes root, home, and nix, mounted with compress=zstd.
If you need a more custom setup please run the partitioning manually, mount the target to /mnt and then install the system:
nixos-install --root /mnt --flake "/mnt/etc/nixos#local-${TARGET_HOST}" --no-root-passwd
After install finishes, reboot into the new system. After install finishes, reboot into the new system.

21
flake.lock generated
View file

@ -30,6 +30,26 @@
"type": "github" "type": "github"
} }
}, },
"disko": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1769524058,
"narHash": "sha256-zygdD6X1PcVNR2PsyK4ptzrVEiAdbMqLos7utrMDEWE=",
"owner": "nix-community",
"repo": "disko",
"rev": "71a3fc97d80881e91710fe721f1158d3b96ae14d",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "disko",
"type": "github"
}
},
"fenix": { "fenix": {
"inputs": { "inputs": {
"nixpkgs": [ "nixpkgs": [
@ -359,6 +379,7 @@
}, },
"root": { "root": {
"inputs": { "inputs": {
"disko": "disko",
"flox": "flox", "flox": "flox",
"lanzaboote": "lanzaboote", "lanzaboote": "lanzaboote",
"lix-module": "lix-module", "lix-module": "lix-module",

View file

@ -3,6 +3,10 @@
inputs = { inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.11"; nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.11";
disko = {
url = "github:nix-community/disko";
inputs.nixpkgs.follows = "nixpkgs";
};
nix-index-database = { nix-index-database = {
url = "github:nix-community/nix-index-database"; url = "github:nix-community/nix-index-database";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";

View file

@ -0,0 +1,14 @@
{ config, lib, modulesPath, ... }:
{
imports = [
(modulesPath + "/profiles/qemu-guest.nix")
];
boot.initrd.availableKernelModules = [ "ahci" "xhci_pci" "virtio_pci" "sr_mod" "virtio_blk" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-intel" ];
boot.extraModulePackages = [ ];
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
}

View file

@ -8,11 +8,13 @@
{ {
imports = [ imports = [
inputs.disko.nixosModules.disko
inputs.lix-module.nixosModules.lixFromNixpkgs inputs.lix-module.nixosModules.lixFromNixpkgs
inputs.nix-index-database.nixosModules.nix-index inputs.nix-index-database.nixosModules.nix-index
inputs.nix-flatpak.nixosModules.nix-flatpak inputs.nix-flatpak.nixosModules.nix-flatpak
../modules/system/flatpak.nix ../modules/system/flatpak.nix
../modules/system/base.nix ../modules/system/base.nix
../modules/system/disko-btrfs.nix
../modules/system/packages.nix ../modules/system/packages.nix
../modules/system/shell.nix ../modules/system/shell.nix
../modules/system/home-manager-skel.nix ../modules/system/home-manager-skel.nix
@ -23,8 +25,6 @@
../modules/desktop/gnome-minimal.nix ../modules/desktop/gnome-minimal.nix
../modules/development/flox.nix ../modules/development/flox.nix
../modules/users/admin.nix ../modules/users/admin.nix
]
++ lib.optionals (builtins.pathExists ./nanuqsaurus-hardware.nix) [
./nanuqsaurus-hardware.nix ./nanuqsaurus-hardware.nix
]; ];

View file

@ -0,0 +1,58 @@
{ lib, ... }:
{
disko.devices = {
disk.main = {
type = "disk";
device = lib.mkDefault "/dev/vda";
content = {
type = "gpt";
partitions = {
ESP = {
size = "550M";
type = "EF00";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
mountOptions = [
"fmask=0022"
"dmask=0022"
];
};
};
nixos = {
size = "100%";
content = {
type = "btrfs";
extraArgs = [ "-f" ];
subvolumes = {
root = {
mountpoint = "/";
mountOptions = [
"compress=zstd"
];
};
home = {
mountpoint = "/home";
mountOptions = [
"compress=zstd"
];
};
nix = {
mountpoint = "/nix";
mountOptions = [
"compress=zstd"
];
};
};
};
};
};
};
};
};
}

View file

@ -1,17 +1,18 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -euo pipefail set -euo pipefail
# Non-interactive Btrfs installer using the flake in this repo. # Non-interactive Btrfs installer using disko-install.
# Defaults: DISK=/dev/vda TARGET_HOST=nanuqsaurus # Defaults: DISK=/dev/vda TARGET_HOST=nanuqsaurus
# If FLAKE is unset and /etc/nixos/flake.nix exists, it uses /etc/nixos.
# Otherwise, set FLAKE to a flake URI like:
# - git+https://codeberg.org/<owner>/<repo>.git
# - github:<owner>/<repo>
DISK="${DISK:-/dev/vda}" DISK="${DISK:-/dev/vda}"
TARGET_HOST="${TARGET_HOST:-nanuqsaurus}" TARGET_HOST="${TARGET_HOST:-nanuqsaurus}"
FLAKE="${FLAKE:-}"
SCRIPT_DIR="$(cd -- "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd -- "$SCRIPT_DIR/.." && pwd)"
MNT=/mnt MNT=/mnt
EFI_SIZE=550M
have() { command -v "$1" >/dev/null 2>&1; } have() { command -v "$1" >/dev/null 2>&1; }
@ -27,85 +28,34 @@ confirm_disk() {
sleep 5 sleep 5
} }
resolve_flake() {
if [[ -n "$FLAKE" ]]; then
return 0
fi
if [[ -e /etc/nixos/flake.nix ]]; then
FLAKE=/etc/nixos
return 0
fi
die "FLAKE is unset. Set FLAKE to a flake URI (or run from an ISO that provides /etc/nixos)."
}
clear clear
confirm_disk confirm_disk
resolve_flake
echo "[1/7] Partitioning ${DISK}" echo "[1/1] Installing ${TARGET_HOST} via disko-install"
sfdisk "$DISK" <<EOF
label: gpt
,${EFI_SIZE},U
,,L
EOF
echo "[2/7] Formatting filesystems"
mkfs.fat -F32 "${DISK}1"
mkfs.btrfs -f "${DISK}2"
echo "[3/7] Creating Btrfs subvolumes"
mkdir -p "$MNT"
mount "${DISK}2" "$MNT"
for subvol in root home nix; do
btrfs subvolume create "$MNT/$subvol"
done
umount "$MNT"
echo "[4/7] Mounting subvolumes"
mount -o compress=zstd,subvol=root "${DISK}2" "$MNT"
mkdir -p "$MNT"/{home,nix,boot}
mount -o compress=zstd,subvol=home "${DISK}2" "$MNT/home"
mount -o compress=zstd,subvol=nix "${DISK}2" "$MNT/nix"
mount "${DISK}1" "$MNT/boot"
echo "[5/7] Copying flake to /etc/nixos"
mkdir -p "$MNT/etc/nixos"
EXCLUDES=(--exclude=.git --exclude=result --exclude=node_modules)
if have rsync; then
rsync -a "${EXCLUDES[@]}" "$REPO_ROOT/" "$MNT/etc/nixos/"
else
(cd "$REPO_ROOT" && tar -cf - "${EXCLUDES[@]/#/--exclude=}" .) \
| (cd "$MNT/etc/nixos" && tar -xf -)
fi
echo "[6/7] Generating hardware config"
HOSTS_DIR="$MNT/etc/nixos/hosts"
mkdir -p "$HOSTS_DIR"
HW_FILE="$HOSTS_DIR/local-${TARGET_HOST}-hardware.nix"
HOST_FILE="$HOSTS_DIR/local-${TARGET_HOST}.nix"
nixos-generate-config --root "$MNT" --show-hardware-config > "$HW_FILE"
if [[ ! -e "$HOST_FILE" ]]; then
cat > "$HOST_FILE" <<EOF
{ inputs, ... }:
{
imports = [
inputs.lix-module.nixosModules.lixFromNixpkgs
../modules/system/base.nix
../modules/system/packages.nix
../modules/system/home-manager-skel.nix
../modules/desktop/gnome-minimal.nix
../modules/users/admin.nix
./local-${TARGET_HOST}-hardware.nix
];
networking.hostName = "${TARGET_HOST}";
}
EOF
fi
echo "[7/7] Installing ${TARGET_HOST} via flake"
LOG=/tmp/nixos-install.log LOG=/tmp/nixos-install.log
nixos-install \
--root "$MNT" \ nix \
--flake "$MNT/etc/nixos#local-${TARGET_HOST}" \ --experimental-features "nix-command flakes" \
--no-root-passwd |& tee "$LOG" run "github:nix-community/disko/latest#disko-install" -- \
--mode format \
--flake "${FLAKE}#${TARGET_HOST}" \
--disk main "${DISK}" \
--mount-point "$MNT" \
--system-config '{"users":{"users":{"root":{"hashedPassword":"!"}}}}' |& tee "$LOG"
echo "Install log saved to $LOG" echo "Install log saved to $LOG"
echo "Install complete. You can reboot now." echo "Install complete. You can reboot now."

View file

@ -101,7 +101,7 @@
[no-cd] [no-cd]
rebuild: rebuild:
sudo nixos-rebuild switch --flake /etc/nixos#local-$HOSTNAME sudo nixos-rebuild switch --flake "${NIXOS_FLAKE:-/etc/nixos}#$HOSTNAME"
[no-cd] [no-cd]
clean: clean: