1
1
Fork 1
mirror of https://github.com/oddlama/nix-config.git synced 2025-10-10 14:50:40 +02:00

feat: finish transition to flake-parts

This commit is contained in:
oddlama 2024-06-01 00:31:38 +02:00
parent 1424778bc2
commit 78b92f06cc
No known key found for this signature in database
GPG key ID: 14EFE510775FE39A
24 changed files with 237 additions and 277 deletions

View file

@ -122,7 +122,7 @@ but here's a quick breakdown of the what you will find where.
- Create a bootable iso disk image with `nix build --print-out-paths --no-link .#images.<target-system>.live-iso`, dd it to a stick and boot
- (Alternative) Use an official NixOS live-iso and setup ssh manually
- Copy the installer from a local machine to the live system with `nix copy --to <target> .#packages.<target-system>.installer-package.<target>`
- Copy the installer from a local machine to the live system with `nix copy --to <target> .#nixosConfigurationsMinimal.config.system.build.installFromLive`
Afterwards:

View file

@ -19,8 +19,6 @@ Make sure to utilize the github search if you know what you need!
Some hosts define guests that run as containerized or virtualized guests. Their configuration is usually just a single file
stored in `guests/<name>.nix`. Their secrets are usually stored in a subfolder of the host's secrets folder.
- `lib/` contains extra library functions that are needed throughout the config.
- `modules/` contains modularized configuration. If you are interested in reusable parts of
my configuration, this is probably the folder you are looking for. These will be regular
reusable modules like those you would find in `nixpkgs/nixos/modules`.

View file

@ -23,6 +23,7 @@
./home-manager.nix
./impermanence.nix
./inputrc.nix
./installer.nix
./issue.nix
./net.nix
./nftables.nix
@ -35,8 +36,13 @@
./users.nix
];
nixpkgs.overlays = [
inputs.nixvim.overlays.default
inputs.wired-notify.overlays.default
];
nixpkgs.config.allowUnfree = true;
nixpkgs.overlays =
import ../pkgs/default.nix
++ [
inputs.nix-topology.overlays.default
inputs.nixos-extra-modules.overlays.default
inputs.nixvim.overlays.default
inputs.wired-notify.overlays.default
];
}

43
config/installer.nix Normal file
View file

@ -0,0 +1,43 @@
{
config,
lib,
pkgs,
...
}: let
disko-script = pkgs.writeShellScriptBin "disko-script" "${config.system.build.diskoScript}";
disko-mount = pkgs.writeShellScriptBin "disko-mount" "${config.system.build.mountScript}";
disko-format = pkgs.writeShellScriptBin "disko-format" "${config.system.build.formatScript}";
install-system = pkgs.writeShellScriptBin "install-system" ''
set -euo pipefail
echo "Formatting disks..."
${disko-script}/bin/disko-script
echo "Installing system..."
nixos-install --no-root-password --system ${config.system.build.toplevel}
echo "Done!"
echo "DONT FORGET TO EXPORT YOUR ZFS POOL(S)!"
'';
installer-package = pkgs.symlinkJoin {
name = "installer-package-${config.node.name}";
paths = [
disko-script
disko-mount
disko-format
install-system
];
};
in {
options.system.build.installFromLive = lib.mkOption {
type = lib.types.package;
description = ''
A single script that can be used from a live system, which will
format disks and copy the derivation.
'';
default = installer-package;
readOnly = true;
};
}

6
flake.lock generated
View file

@ -51,11 +51,11 @@
"pre-commit-hooks": "pre-commit-hooks"
},
"locked": {
"lastModified": 1716983518,
"narHash": "sha256-LdiPzaq6IwCfEpjaZfndO1CtW1ah1ONwyXKPs7s6UVk=",
"lastModified": 1717022817,
"narHash": "sha256-PHyHgQL5/b0+A/kmNCHVOM/WSJSGe1jZ+LFWfYNx31E=",
"owner": "oddlama",
"repo": "agenix-rekey",
"rev": "8cf73841a6fa127a64392c8603ce51af1c63b33f",
"rev": "c6c1ca5b9ceaaa40fd979fb25bb7043adf4554ad",
"type": "github"
},
"original": {

129
flake.nix
View file

@ -96,136 +96,19 @@
outputs = inputs:
inputs.flake-parts.lib.mkFlake {inherit inputs;} {
imports = [
./nix/devshell.nix
./nix/agenix-rekey.nix
./nix/devshell.nix
./nix/globals.nix
(
{
lib,
flake-parts-lib,
...
}:
flake-parts-lib.mkTransposedPerSystemModule {
name = "images";
file = ./flake.nix;
option = lib.mkOption {
type = lib.types.unspecified;
};
}
)
(
{
lib,
flake-parts-lib,
...
}:
flake-parts-lib.mkTransposedPerSystemModule {
name = "pkgs";
file = ./flake.nix;
option = lib.mkOption {
type = lib.types.unspecified;
};
}
)
./nix/hosts.nix
./nix/iso.nix
./nix/pkgs.nix
./nix/storage-box.nix
./topology/flake-module.nix
];
flake = {
config,
lib,
...
}: let
inherit
(lib)
foldl'
mapAttrs
mapAttrsToList
recursiveUpdate
;
in {
inherit
(import ./nix/hosts.nix inputs)
hosts
guestConfigs
nixosConfigurations
nixosConfigurationsMinimal
;
# All nixosSystem instanciations are collected here, so that we can refer
# to any system via nodes.<name>
nodes = config.nixosConfigurations // config.guestConfigs;
# Add a shorthand to easily target toplevel derivations
"@" = mapAttrs (_: v: v.config.system.build.toplevel) config.nodes;
# For each true NixOS system, we want to expose an installer package that
# can be used to do the initial setup on the node from a live environment.
# We use the minimal sibling configuration to reduce the amount of stuff
# we have to copy to the live system.
inherit
(foldl' recursiveUpdate {}
(mapAttrsToList
(import ./nix/generate-installer-package.nix inputs)
config.nixosConfigurationsMinimal))
packages
;
};
systems = [
"x86_64-linux"
"aarch64-linux"
];
perSystem = {
config,
pkgs,
system,
...
}: {
_module.args.pkgs = import inputs.nixpkgs {
inherit system;
config.allowUnfree = true;
overlays =
import ./lib inputs
++ import ./pkgs/default.nix
++ [
inputs.nix-topology.overlays.default
inputs.nixos-extra-modules.overlays.default
];
};
inherit pkgs;
apps.setupHetznerStorageBoxes = import (inputs.nixos-extra-modules + "/apps/setup-hetzner-storage-boxes.nix") {
inherit pkgs;
nixosConfigurations = config.nodes;
decryptIdentity = builtins.head config.secretsConfig.masterIdentities;
};
#topology = import inputs.nix-topology {
# inherit pkgs;
# modules = [
# ./topology
# {
# inherit (inputs.self) nixosConfigurations;
# }
# ];
#};
# For each major system, we provide a customized installer image that
# has ssh and some other convenience stuff preconfigured.
# Not strictly necessary for new setups.
images.live-iso = inputs.nixos-generators.nixosGenerate {
inherit pkgs;
modules = [
./nix/installer-configuration.nix
./config/ssh.nix
];
format =
{
x86_64-linux = "install-iso";
aarch64-linux = "sd-aarch64-installer";
}
.${system};
};
};
};
}

View file

@ -12,6 +12,7 @@
#./stalwart-mail.nix
];
nixpkgs.hostPlatform = "x86_64-linux";
boot.mode = "bios";
users.groups.acme.members = ["nginx"];

View file

@ -32,7 +32,9 @@
./net.nix
];
nixpkgs.hostPlatform = "x86_64-linux";
boot.mode = "efi";
boot.kernelModules = ["nvidia_uvm"]; # FIXME: For some reason this doesn't load automatically for me, causing CUDA_ERROR_UNKNOWN (999) issues when trying to cuInit
boot.initrd.availableKernelModules = ["xhci_pci" "ahci" "nvme" "usbhid" "usb_storage" "sd_mod"];
boot.binfmt.emulatedSystems = ["aarch64-linux"];
}

View file

@ -27,6 +27,7 @@
./net.nix
];
nixpkgs.hostPlatform = "x86_64-linux";
boot.mode = "efi";
boot.initrd.availableKernelModules = ["xhci_pci" "ahci" "nvme" "usbhid" "usb_storage" "sd_mod"];

View file

@ -16,6 +16,7 @@
./oauth2.nix
];
nixpkgs.hostPlatform = "x86_64-linux";
boot.mode = "bios";
wireguard.proxy-sentinel.firewallRuleForAll.allowedTCPPorts = [80 443];

View file

@ -22,6 +22,7 @@
topology.self.hardware.info = "AMD Ryzen Threadripper 1950X, 96GB RAM";
nixpkgs.hostPlatform = "x86_64-linux";
boot.mode = "efi";
boot.initrd.availableKernelModules = ["xhci_pci" "ahci" "nvme" "usbhid" "usb_storage" "e1000e" "alx"];

View file

@ -24,6 +24,7 @@
topology.self.hardware.image = ../../topology/images/odroid-h3.png;
topology.self.hardware.info = "O-Droid H3, 64GB RAM";
nixpkgs.hostPlatform = "x86_64-linux";
boot.mode = "efi";
boot.initrd.availableKernelModules = ["xhci_pci" "ahci" "nvme" "usbhid" "usb_storage" "sd_mod" "sdhci_pci" "r8169"];

View file

@ -28,6 +28,7 @@ in {
topology.self.hardware.image = ../../topology/images/odroid-n2plus.png;
topology.self.hardware.info = "O-Droid N2+";
nixpkgs.hostPlatform = "aarch64-linux";
boot.mode = "efi";
meta.promtail = {

View file

@ -1,3 +0,0 @@
inputs: [
(import ./secrets.nix inputs)
]

View file

@ -1,33 +0,0 @@
inputs: final: prev: let
inherit
(prev.lib)
concatMapStrings
escapeShellArg
;
inherit
(final.lib)
isAbsolutePath
;
in {
lib =
prev.lib
// {
secrets = let
rageMasterIdentityArgs = concatMapStrings (x: "-i ${escapeShellArg x} ") inputs.self.secretsConfig.masterIdentities;
rageExtraEncryptionPubkeys =
concatMapStrings (
x:
if isAbsolutePath x
then "-R ${escapeShellArg x} "
else "-r ${escapeShellArg x} "
)
inputs.self.secretsConfig.extraEncryptionPubkeys;
in {
# TODO replace these by lib.agenix-rekey
# The arguments required to de-/encrypt a secret in this repository
rageDecryptArgs = "${rageMasterIdentityArgs}";
rageEncryptArgs = "${rageMasterIdentityArgs} ${rageExtraEncryptionPubkeys}";
};
};
}

View file

@ -1,35 +0,0 @@
{self, ...}: nodeName: nodeAttrs: let
inherit (self.hosts.${nodeName}) system;
pkgs = self.pkgs.${system};
disko-script = pkgs.writeShellScriptBin "disko-script" "${nodeAttrs.config.system.build.diskoScript}";
disko-mount = pkgs.writeShellScriptBin "disko-mount" "${nodeAttrs.config.system.build.mountScript}";
disko-format = pkgs.writeShellScriptBin "disko-format" "${nodeAttrs.config.system.build.formatScript}";
install-system = pkgs.writeShellScriptBin "install-system" ''
set -euo pipefail
echo "Formatting disks..."
${disko-script}/bin/disko-script
echo "Installing system..."
nixos-install --no-root-password --system ${nodeAttrs.config.system.build.toplevel}
echo "Done!"
echo "DONT FORGET TO EXPORT YOUR ZFS POOL(S)!"
'';
installer-package = pkgs.symlinkJoin {
name = "installer-package-${nodeName}";
paths = [
disko-script
disko-mount
disko-format
install-system
];
};
in {
# Everything required for the installer as a single package,
# so it can be used from an existing live system by copying the derivation.
packages.${system}.installer-package.${nodeName} = installer-package;
}

View file

@ -1,70 +1,63 @@
inputs: let
inherit (inputs) self;
inherit
(inputs.nixpkgs.lib)
concatMapAttrs
filterAttrs
flip
mapAttrs
mapAttrs'
nameValuePair
nixosSystem
;
{inputs, ...}: {
flake = {
config,
lib,
...
}: let
inherit
(lib)
concatMapAttrs
filterAttrs
flip
genAttrs
mapAttrs
mapAttrs'
nameValuePair
;
# Creates a new nixosSystem with the correct specialArgs, pkgs and name definition
mkHost = {minimal}: name: hostCfg: let
pkgs = self.pkgs.${hostCfg.system};
in
nixosSystem {
specialArgs = {
# Use the correct instance lib that has our overlays
inherit (pkgs) lib;
inherit (self) nodes globals;
inherit inputs minimal;
# Creates a new nixosSystem with the correct specialArgs, pkgs and name definition
mkHost = {minimal}: name: let
pkgs = config.pkgs.x86_64-linux; # FIXME: NOOOOOOOOOOOOOOOOOOOOOOO
in
inputs.nixpkgs.lib.nixosSystem {
specialArgs = {
# Use the correct instance lib that has our overlays
inherit (pkgs) lib;
inherit (config) nodes globals;
inherit inputs minimal;
};
modules = [
{
node.name = name;
node.secretsDir = ../hosts/${name}/secrets;
}
../hosts/${name}
];
};
modules = [
{
# We cannot force the package set via nixpkgs.pkgs and
# inputs.nixpkgs.nixosModules.readOnlyPkgs, since some nixosModules
# like nixseparatedebuginfod depend on adding packages via nixpkgs.overlays.
# So we just mimic the options and overlays defined by the passed pkgs set.
nixpkgs.hostPlatform = hostCfg.system;
nixpkgs.overlays = pkgs.overlays;
nixpkgs.config = pkgs.config;
node.name = name;
node.secretsDir = ../hosts/${name}/secrets;
}
../hosts/${name}
];
};
# Load the list of hosts that this flake defines, which
# associates the minimum amount of metadata that is necessary
# to instanciate hosts correctly.
hosts = builtins.fromTOML (builtins.readFile ../hosts.toml);
# Get all hosts of type "nixos"
nixosHosts = filterAttrs (_: x: x.type == "nixos") hosts;
# Process each nixosHosts declaration and generatea nixosSystem definitions
nixosConfigurations = flip mapAttrs nixosHosts (mkHost {minimal = false;});
nixosConfigurationsMinimal = flip mapAttrs nixosHosts (mkHost {minimal = true;});
# Get all folders in hosts/
hosts = builtins.attrNames (filterAttrs (_: type: type == "directory") (builtins.readDir ../hosts));
in {
nixosConfigurations = genAttrs hosts (mkHost {minimal = false;});
nixosConfigurationsMinimal = genAttrs hosts (mkHost {minimal = true;});
# True NixOS nodes can define additional guest nodes that are built
# together with it. We collect all defined guests from each node here
# to allow accessing any node via the unified attribute `nodes`.
guestConfigs = flip concatMapAttrs self.nixosConfigurations (_: node:
flip mapAttrs' (node.config.guests or {}) (
guestName: guestDef:
nameValuePair guestDef.nodeName (
if guestDef.backend == "microvm"
then node.config.microvm.vms.${guestName}.config
else node.config.containers.${guestName}.nixosConfiguration
)
));
in {
inherit
hosts
guestConfigs
nixosConfigurations
nixosConfigurationsMinimal
;
# True NixOS nodes can define additional guest nodes that are built
# together with it. We collect all defined guests from each node here
# to allow accessing any node via the unified attribute `nodes`.
guestConfigs = flip concatMapAttrs config.nixosConfigurations (_: node:
flip mapAttrs' (node.config.guests or {}) (
guestName: guestDef:
nameValuePair guestDef.nodeName (
if guestDef.backend == "microvm"
then node.config.microvm.vms.${guestName}.config
else node.config.containers.${guestName}.nixosConfiguration
)
));
# All nixosSystem instanciations are collected here, so that we can refer
# to any system via nodes.<name>
nodes = config.nixosConfigurations // config.guestConfigs;
# Add a shorthand to easily target toplevel derivations
"@" = mapAttrs (_: v: v.config.system.build.toplevel) config.nodes;
};
}

24
nix/iso.nix Normal file
View file

@ -0,0 +1,24 @@
{inputs, ...}: {
perSystem = {
pkgs,
system,
...
}: {
# For each major system, we provide a customized installer image that
# has ssh and some other convenience stuff preconfigured.
# Not strictly necessary for new setups.
packages.live-iso = inputs.nixos-generators.nixosGenerate {
inherit pkgs;
modules = [
./installer-configuration.nix
../config/ssh.nix
];
format =
{
x86_64-linux = "install-iso";
aarch64-linux = "sd-aarch64-installer";
}
.${system};
};
};
}

37
nix/pkgs.nix Normal file
View file

@ -0,0 +1,37 @@
{inputs, ...}: {
imports = [
(
{
lib,
flake-parts-lib,
...
}:
flake-parts-lib.mkTransposedPerSystemModule {
name = "pkgs";
file = ./pkgs.nix;
option = lib.mkOption {
type = lib.types.unspecified;
};
}
)
];
perSystem = {
pkgs,
system,
...
}: {
_module.args.pkgs = import inputs.nixpkgs {
inherit system;
config.allowUnfree = true;
overlays =
import ../pkgs/default.nix
++ [
inputs.nix-topology.overlays.default
inputs.nixos-extra-modules.overlays.default
];
};
inherit pkgs;
};
}

9
nix/storage-box.nix Normal file
View file

@ -0,0 +1,9 @@
{inputs, ...}: {
perSystem = {pkgs, ...}: {
apps.setupHetznerStorageBoxes = import (inputs.nixos-extra-modules + "/apps/setup-hetzner-storage-boxes.nix") {
inherit pkgs;
nixosConfigurations = inputs.self.nodes;
decryptIdentity = builtins.head inputs.self.secretsConfig.masterIdentities;
};
};
}

View file

@ -0,0 +1,8 @@
age-encryption.org/v1
-> ssh-ed25519 1tdZKQ 0RQGWMKdlizirGx6o2XbuYXsefdLosiN/8qCokgA/ng
q73P4XM9fPNJnviWcy/ibcaarU5+CZpRQbJq250BhVs
-> t'#gZ,S-grease _M} rhid"l
sjt6COcSzS4Tem2vMhAxhp4ewtoylcYC0RUgdTc8U5X0spJL+ckRzxI7z1gqnQCp
dxdWGpYRQp0
--- k6eZqMwv+RK28dHW9Q+mYXUhkYFOTRtHu2eUHskOhJg
Ùàó^zîÊ$äFÑíPnžä×¢¢ýåМT¤³�Z;}E2øÍ™P¾zÒv^.±:óLÏ97´êÐr±º*¬œ¢2’Ó.U¬Œ3`

View file

@ -1,8 +0,0 @@
age-encryption.org/v1
-> ssh-ed25519 NwOpTA Rq5PyLLJdiYKkL+9vW+BS7sbFHBFoLwdxxWgPTH+0wU
wr1wRFGKYVgziwtzOm95pO4ZPnzF+pTuXlhedNd7HoU
-> Or$Ir-grease =Z{2b= (FvA*6m iV4)_
tePL0HELOtPx9UAsd0K7CvKv/56vQP++Y/PI5LMIl1IP7Opv2tiOqlB+R5bqWClO
lzV5jX+CVtQNABFgyDrQDfeqUgrw
--- YYlss0gmwNI2pNYbukrJl0hZpdCC8xKh+trLpAeTqFg
?1Ý7©ˆåˆ§¡êdÒÛ=2P»(û˜­Uuø/98ÊÖ.ËŒ¯;gyþúÄNö]ÄkdÞ|L/QJÞ…6ÀûMUÝ$Ørs9

30
topology/flake-module.nix Normal file
View file

@ -0,0 +1,30 @@
{inputs, ...}: {
imports = [
(
{
lib,
flake-parts-lib,
...
}:
flake-parts-lib.mkTransposedPerSystemModule {
name = "topology";
file = ./flake-module.nix;
option = lib.mkOption {
type = lib.types.unspecified;
};
}
)
];
perSystem = {pkgs, ...}: {
topology = import inputs.nix-topology {
inherit pkgs;
modules = [
./topology
{
inherit (inputs.self) nixosConfigurations;
}
];
};
};
}