add hosts

This commit is contained in:
2026-07-28 00:19:14 +09:00
parent 09a4fd83a7
commit b1954ba5be
11 changed files with 519 additions and 40 deletions
+85 -15
View File
@@ -487,6 +487,59 @@ A host registry may use a specification like this:
```nix
# hosts/default.nix
{
nix-example = {
system = "x86_64-linux";
stateVersion = "26.05";
user = "moons";
path = ./nix-example;
profiles = [
"base"
"interface.cli"
"platform.vm"
"workload.development"
"workload.remote-access"
];
};
ops = {
system = "x86_64-linux";
stateVersion = "26.05";
user = "moons";
path = ./ops;
profiles = [
"base"
"interface.cli"
"platform.vm"
"workload.remote-access"
];
};
internal-app-01 = {
system = "x86_64-linux";
stateVersion = "26.05";
user = "moons";
path = ./internal-app-01;
profiles = [
"base"
"interface.cli"
"platform.vm"
"workload.server"
];
};
installer = {
system = "x86_64-linux";
stateVersion = "26.05";
user = "moons";
path = ./installer;
homeManager = false;
profiles = [ "base" ];
};
x1g9 = {
system = "x86_64-linux";
stateVersion = "26.05";
@@ -544,14 +597,16 @@ A host registry may use a specification like this:
}
```
The current role assignment is intentional: x1g9 is a full NixOS desktop with
niri, GNOME, ly, the shared Linux desktop applications, and the personal
workload. x1g13 is the secure NixOS development and personal ThinkPad, with the
same desktop sessions plus Tailscale client, SOPS, Secure Boot, and TPM-backed
disk unlock. m2 is the daily-use macOS development and personal machine with
the macOS interface defaults. Keep the desktop sessions independently
selectable, and keep the development and personal profiles usable across NixOS
and Darwin.
The current role assignment is intentional: nix-example is the development VM;
ops is the remote-access VM with host-specific static networking;
internal-app-01 is the container server VM; and installer builds the minimal
installation ISO without Home Manager. x1g9 is a full NixOS desktop with niri,
GNOME, ly, the shared Linux desktop applications, and the personal workload.
x1g13 is the secure NixOS development and personal ThinkPad, with the same
desktop sessions plus Tailscale client, SOPS, Secure Boot, and TPM-backed disk
unlock. m2 is the daily-use macOS development and personal machine with the
macOS interface defaults. Keep the desktop sessions independently selectable,
and keep the development and personal profiles usable across NixOS and Darwin.
Treat entries in `profiles` and the exceptional `applications` field as IDs
relative to their respective category roots. Add the category prefixes during
@@ -581,6 +636,17 @@ configuration fragments. For example:
```text
hosts/
├── installer/
│ └── nixos.nix
├── internal-app-01/
│ ├── nixos.nix
│ └── hardware-configuration.nix
├── nix-example/
│ ├── nixos.nix
│ └── hardware-configuration.nix
├── ops/
│ ├── nixos.nix
│ └── hardware-configuration.nix
├── x1g9/
│ ├── nixos.nix
│ └── hardware-configuration.nix
@@ -606,9 +672,10 @@ Derive the system class from the host's `system`:
- A host with integrated Home Manager additionally receives `home.nix`.
Home Manager is additive, not a system class mutually exclusive with NixOS or
nix-darwin. The supported combinations are NixOS plus Home Manager and
nix-darwin plus Home Manager. If standalone Home Manager is supported later, add
an explicit host kind because `system` alone cannot distinguish it from NixOS.
nix-darwin. Normal machine configurations combine NixOS or nix-darwin with Home
Manager; the installer ISO explicitly sets `homeManager = false`. If standalone
Home Manager is supported later, add an explicit host kind because `system`
alone cannot distinguish it from NixOS.
Do not duplicate reusable settings in hosts, but do not force genuinely
machine-specific values into a common unit merely to remove a host-local line.
@@ -694,10 +761,13 @@ For profile changes, additionally:
required host-owned values.
- When adding a Darwin application fragment, verify the resulting
`homebrew.casks` selection as well as module evaluation.
- Preserve the intended host roles: x1g9 provides niri, GNOME, ly, and the
personal application set; x1g13 additionally provides the development,
Tailscale client, secrets, Secure Boot, and TPM storage roles; m2 remains the
daily-use development and personal machine.
- Preserve the intended host roles: nix-example remains the development VM;
ops remains the statically networked remote-access VM; internal-app-01 remains
the container server VM; installer remains the Home Manager-free installation
ISO; x1g9 provides niri, GNOME, ly, and the personal application set; x1g13
additionally provides the development, Tailscale client, secrets, Secure Boot,
and TPM storage roles; m2 remains the daily-use development and personal
machine.
## Commit and Pull Request Guidelines
+53
View File
@@ -1,4 +1,57 @@
{
nix-example = {
system = "x86_64-linux";
stateVersion = "26.05";
user = "moons";
path = ./nix-example;
profiles = [
"base"
"interface.cli"
"platform.vm"
"workload.development"
"workload.remote-access"
];
};
ops = {
system = "x86_64-linux";
stateVersion = "26.05";
user = "moons";
path = ./ops;
profiles = [
"base"
"interface.cli"
"platform.vm"
"workload.remote-access"
];
};
internal-app-01 = {
system = "x86_64-linux";
stateVersion = "26.05";
user = "moons";
path = ./internal-app-01;
profiles = [
"base"
"interface.cli"
"platform.vm"
"workload.server"
];
};
installer = {
system = "x86_64-linux";
stateVersion = "26.05";
user = "moons";
path = ./installer;
homeManager = false;
profiles = [ "base" ];
};
x1g9 = {
system = "x86_64-linux";
stateVersion = "26.05";
+189
View File
@@ -0,0 +1,189 @@
{
pkgs,
lib,
modulesPath,
...
}:
{
imports = [ "${modulesPath}/installer/cd-dvd/installation-cd-minimal.nix" ];
boot.zfs.forceImportRoot = false;
networking = {
hostName = "nixos-installer";
networkmanager = {
enable = true;
wifi.powersave = false;
};
};
services.openssh = {
enable = true;
settings = {
PermitRootLogin = "prohibit-password";
PasswordAuthentication = false;
KbdInteractiveAuthentication = false;
PubkeyAuthentication = "yes";
};
};
users.users.root.openssh.authorizedKeys.keys = [
"sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIKhxDkucmeCor6CKoXAua7DgDSzuXrZOtpdkyzQxz5+aAAAABHNzaDo= moons@moons14.com"
"sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIN6hZJyng/5LgFKPjR6uZAd/00UkO0vN0uQOoIvfSELdAAAABHNzaDo= moons@moons14.com"
];
environment.systemPackages = with pkgs; [
git
disko
sops
age
ssh-to-age
age-plugin-yubikey
yubikey-manager
pcsc-tools
mkpasswd
rsync
vim
wget
curl
jq
parted
cryptsetup
btrfs-progs
];
services.pcscd.enable = true;
environment.etc."installer-help.txt".text = ''
╔══════════════════════════════════════════════════════════════╗
║ NixOS Installer ISO ║
╠══════════════════════════════════════════════════════════════╣
║ ║
║ SSH Access: ║
║ ssh root@<ip-address> ║
║ ║
║ Network Setup: ║
║ Wired: Auto-configured via DHCP ║
║ WiFi: nmcli device wifi connect <SSID> --ask ║
║ ║
║ Installation Workflow: ║
║ ║
║ 1. Clone dotfiles: ║
║ git clone git@github.com:moons-14/dotfiles.git ~/dotfiles║
║ ║
║ 2. Generate SSH host key for new host: ║
║ ssh-keygen -t ed25519 -f /tmp/ssh_host_ed25519_key -N "" ║
║ ║
║ 3. Get age public key from SSH host key: ║
║ ssh-to-age -i /tmp/ssh_host_ed25519_key.pub ║
║ ║
║ 4. Add age key to .sops.yaml: ║
║ cd ~/dotfiles ║
║ # Edit .sops.yaml and add the age key ║
║ # Add new host entry to creation_rules ║
║ ║
║ 5. Re-encrypt secrets: ║
║ sops updatekeys secrets/common/system.yaml ║
║ sops updatekeys secrets/hosts/<host>/*.yaml ║
║ ║
║ 6. Create disko.nix for new host: ║
║ # Check disk devices ║
║ lsblk -f ║
║ ║
║ # Create hosts/<host>/disko.nix ║
║ # Example: LUKS + btrfs ║
║ # See hosts/x1g13/disko.nix for reference ║
║ ║
║ 7. Partition disk with disko: ║
║ nix run github:nix-community/disko -- \ ║
║ --mode disko hosts/<host>/disko.nix ║
║ ║
║ 8. Copy host key to installed system: ║
║ mkdir -p /mnt/etc/ssh ║
║ cp /tmp/ssh_host_ed25519_key* /mnt/etc/ssh/ ║
║ chmod 600 /mnt/etc/ssh/ssh_host_ed25519_key ║
║ ║
║ 9. Install NixOS: ║
║ nixos-install --flake ~/dotfiles#<host> ║
║ ║
║ Disko Configuration Examples: ║
║ ║
║ Simple (no encryption): ║
║ disko.devices.disk.main = { ║
║ type = "disk"; ║
║ device = "/dev/sda"; ║
║ content = { ║
║ type = "gpt"; ║
║ partitions = { ║
║ ESP = { size = "512M"; type = "EF00"; ║
║ content = { type = "filesystem"; ║
║ format = "vfat"; mountpoint = "/boot"; }; }; ║
║ root = { size = "100%"; ║
║ content = { type = "filesystem"; ║
║ format = "ext4"; mountpoint = "/"; }; }; ║
║ }; ║
║ }; ║
║ }; ║
║ ║
║ LUKS + btrfs (see hosts/x1g13/disko.nix): ║
║ - Use partuuid for device path ║
║ - Set askPassword = true for LUKS ║
║ - Configure btrfs subvolumes ║
║ ║
╚══════════════════════════════════════════════════════════════╝
'';
systemd.services.installer-banner = {
description = "Display installer help on console";
wantedBy = [ "multi-user.target" ];
serviceConfig = {
Type = "oneshot";
ExecStart = "${pkgs.coreutils}/bin/cat /etc/installer-help.txt";
StandardOutput = "tty";
TTYPath = "/dev/tty1";
};
};
systemd.services.display-ip = {
description = "Display IP address on console";
wantedBy = [ "multi-user.target" ];
after = [ "network-online.target" ];
wants = [ "network-online.target" ];
serviceConfig = {
Type = "oneshot";
ExecStart = pkgs.writeShellScript "display-ip" ''
sleep 2
echo ""
echo "=== Network Interfaces ==="
${pkgs.iproute2}/bin/ip -4 addr show | ${pkgs.gnugrep}/bin/grep inet
echo ""
echo "=== SSH Access ==="
for ip in $(${pkgs.iproute2}/bin/ip -4 addr show | ${pkgs.gnugrep}/bin/grep -oP 'inet \K[\d.]+' | ${pkgs.gnugrep}/bin/grep -v '127.0.0.1'); do
echo " ssh root@$ip"
done
echo ""
'';
StandardOutput = "tty";
TTYPath = "/dev/tty1";
};
};
nix = {
settings = {
experimental-features = [
"nix-command"
"flakes"
];
trusted-users = [ "root" ];
};
extraOptions = ''
experimental-features = nix-command flakes
'';
};
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
}
@@ -0,0 +1,36 @@
# Do not modify this file! It was generated by `nixos-generate-config` and may
# be overwritten by future invocations.
{ lib, modulesPath, ... }:
{
imports = [ (modulesPath + "/profiles/qemu-guest.nix") ];
boot.initrd.availableKernelModules = [
"ata_piix"
"uhci_hcd"
"virtio_pci"
"virtio_scsi"
"sd_mod"
"sr_mod"
];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ ];
boot.extraModulePackages = [ ];
fileSystems."/" = {
device = "/dev/disk/by-uuid/1b12ab98-2537-4207-a3f4-bb8ba7b53b00";
fsType = "ext4";
};
fileSystems."/boot" = {
device = "/dev/disk/by-uuid/8365-C778";
fsType = "vfat";
options = [
"fmask=0077"
"dmask=0077"
];
};
swapDevices = [ ];
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
}
+3
View File
@@ -0,0 +1,3 @@
{
imports = [ ./hardware-configuration.nix ];
}
@@ -0,0 +1,36 @@
# Do not modify this file! It was generated by `nixos-generate-config` and may
# be overwritten by future invocations.
{ lib, modulesPath, ... }:
{
imports = [ (modulesPath + "/profiles/qemu-guest.nix") ];
boot.initrd.availableKernelModules = [
"ata_piix"
"uhci_hcd"
"virtio_pci"
"virtio_scsi"
"sd_mod"
"sr_mod"
];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ ];
boot.extraModulePackages = [ ];
fileSystems."/" = {
device = "/dev/disk/by-uuid/8f0eaec6-5dc9-4821-aa8d-fb6809b5a5bf";
fsType = "ext4";
};
fileSystems."/boot" = {
device = "/dev/disk/by-uuid/201C-961B";
fsType = "vfat";
options = [
"fmask=0077"
"dmask=0077"
];
};
swapDevices = [ ];
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
}
+3
View File
@@ -0,0 +1,3 @@
{
imports = [ ./hardware-configuration.nix ];
}
+36
View File
@@ -0,0 +1,36 @@
# Do not modify this file! It was generated by `nixos-generate-config` and may
# be overwritten by future invocations.
{ lib, modulesPath, ... }:
{
imports = [ (modulesPath + "/profiles/qemu-guest.nix") ];
boot.initrd.availableKernelModules = [
"ata_piix"
"uhci_hcd"
"virtio_pci"
"virtio_scsi"
"sd_mod"
"sr_mod"
];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ ];
boot.extraModulePackages = [ ];
fileSystems."/" = {
device = "/dev/disk/by-uuid/69fa2193-1e4f-438a-8898-5de8a3f36e5b";
fsType = "ext4";
};
fileSystems."/boot" = {
device = "/dev/disk/by-uuid/D09B-4277";
fsType = "vfat";
options = [
"fmask=0077"
"dmask=0077"
];
};
swapDevices = [ ];
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
}
+51
View File
@@ -0,0 +1,51 @@
{
imports = [ ./hardware-configuration.nix ];
networking = {
useDHCP = false;
interfaces = {
ens18 = {
useDHCP = false;
ipv4.addresses = [
{
address = "10.50.128.20";
prefixLength = 24;
}
];
};
ens19 = {
useDHCP = false;
ipv4.addresses = [
{
address = "10.50.7.101";
prefixLength = 24;
}
];
};
ens20 = {
useDHCP = false;
ipv4.routes = [
{
address = "10.50.64.0";
prefixLength = 24;
via = "10.50.82.1";
}
];
ipv4.addresses = [
{
address = "10.50.82.10";
prefixLength = 24;
}
];
};
};
defaultGateway = {
address = "10.50.128.1";
interface = "ens18";
};
};
}
+24 -24
View File
@@ -20,30 +20,30 @@ when removing it from any supported host would make that host invalid.
## Compatibility
| Profile | Supported host class |
| ------------------------------------ | ------------------------------------- |
| `base` | NixOS, macOS |
| `interface.cli` | NixOS, macOS with Home Manager |
| `interface.gui` | NixOS, macOS with Home Manager |
| `interface.macos` | macOS |
| `interface.linux-desktop` | NixOS with Home Manager |
| `interface.gnome` | NixOS with Home Manager |
| `interface.niri` | NixOS with Home Manager |
| `platform.nixos` | NixOS |
| `platform.desktop` | Physical NixOS desktop |
| `platform.laptop` | Physical NixOS laptop |
| `platform.thinkpad-x1` | Intel ThinkPad X1 running NixOS |
| `platform.vm` | QEMU NixOS guest |
| `workload.development` | NixOS, macOS with Home Manager |
| `workload.personal` | NixOS, macOS with Home Manager |
| `workload.remote-access` | NixOS, macOS |
| `workload.server` | NixOS, macOS with Home Manager |
| `networking.tailscale-client` | NixOS, macOS |
| `networking.tailscale-subnet-router` | NixOS |
| `security.fingerprint` | NixOS, macOS |
| `security.secrets` | NixOS, macOS |
| `security.secure-boot` | NixOS |
| `security.tpm-storage` | NixOS with a host-defined LUKS device |
| Profile | Supported host class |
| ------------------------------------ | --------------------------------------------- |
| `base` | NixOS, macOS |
| `interface.cli` | NixOS, macOS with Home Manager |
| `interface.gui` | NixOS, macOS with Home Manager |
| `interface.macos` | macOS |
| `interface.linux-desktop` | NixOS with Home Manager |
| `interface.gnome` | NixOS with Home Manager |
| `interface.niri` | NixOS with Home Manager |
| `platform.nixos` | NixOS |
| `platform.desktop` | Physical NixOS desktop |
| `platform.laptop` | Physical NixOS laptop |
| `platform.thinkpad-x1` | Intel ThinkPad X1 running NixOS |
| `platform.vm` | UEFI QEMU NixOS guest with NFS client support |
| `workload.development` | NixOS, macOS with Home Manager |
| `workload.personal` | NixOS, macOS with Home Manager |
| `workload.remote-access` | NixOS, macOS |
| `workload.server` | NixOS, macOS with Home Manager |
| `networking.tailscale-client` | NixOS, macOS |
| `networking.tailscale-subnet-router` | NixOS |
| `security.fingerprint` | NixOS, macOS |
| `security.secrets` | NixOS, macOS |
| `security.secure-boot` | NixOS |
| `security.tpm-storage` | NixOS with a host-defined LUKS device |
Select independent concerns independently in `hosts/default.nix`. For example,
a NixOS desktop can combine `interface.gnome` and `interface.niri` to provide
+3 -1
View File
@@ -1,8 +1,10 @@
{
description = "QEMU NixOS guest";
description = "UEFI QEMU NixOS guest with NFS client support";
includes = [
"profiles.platform.nixos"
"hardwares.qemu-guest"
"systems.boot.nfs"
"systems.boot.uefi"
];
}