refactor(flake): split assembly code #73

Merged
alexion merged 10 commits from refactor/flake-assembly into main 2026-08-29 17:21:41 -04:00
2 changed files with 236 additions and 261 deletions
Showing only changes of commit 4f105c81c2 - Show all commits

View File

@@ -39,7 +39,6 @@ let
inherit inherit
inputs inputs
lib lib
self
specialArgs specialArgs
registryAssembly registryAssembly
util util

View File

@@ -1,20 +1,38 @@
{ {
inputs, inputs,
lib, lib,
self,
specialArgs, specialArgs,
repositoryModules, repositoryModules,
registryAssembly, registryAssembly,
util, util,
}: }:
let {
mkGuestOptions = mkGuest =
{ {
config,
lib,
name, name,
interior ? { },
}: }:
{ config, lib, ... }:
let
cfg = config.guests.${name};
directoryMounts = lib.filterAttrs (_: mount: mount.directory != null) cfg.mounts;
directoryScript = lib.concatStringsSep "\n" (
lib.mapAttrsToList (
_: mount:
''
${config.system.path}/bin/install -d \
${lib.optionalString (mount.owner != null) "-o ${lib.escapeShellArg (toString mount.owner)}"} \
${lib.optionalString (mount.group != null) "-g ${lib.escapeShellArg mount.group}"} \
${lib.optionalString (mount.mode != null) "-m ${lib.escapeShellArg mount.mode}"} \
${lib.escapeShellArg mount.directory}
''
) directoryMounts
);
in
{ {
options.guests.${name} = {
enable = lib.mkEnableOption "the ${name} guest, run in its own nested container"; enable = lib.mkEnableOption "the ${name} guest, run in its own nested container";
vlan = lib.mkOption { vlan = lib.mkOption {
type = lib.types.ints.between 1 4094; type = lib.types.ints.between 1 4094;
@@ -146,75 +164,37 @@ let
}; };
}; };
mkGuestConfig = config = lib.mkIf cfg.enable {
{
config,
interior,
lib,
name,
}:
let
cfg = config.guests.${name};
directoryMounts = lib.filterAttrs (_: mount: mount.directory != null) cfg.mounts;
directoryScript = lib.concatStringsSep "\n" (
lib.mapAttrsToList (
_: mount:
''
${config.system.path}/bin/install -d ${lib.optionalString (mount.owner != null) "-o ${lib.escapeShellArg (toString mount.owner)}"} ${lib.optionalString (mount.group != null) "-g ${lib.escapeShellArg mount.group}"} ${lib.optionalString (mount.mode != null) "-m ${lib.escapeShellArg mount.mode}"} ${lib.escapeShellArg mount.directory}
''
) directoryMounts
);
guestNet =
{ lib, ... }:
{
networking.useNetworkd = true;
networking.useHostResolvConf = false;
systemd.network.networks."20-eth0" = {
matchConfig.Name = "eth0";
linkConfig.MACAddress = cfg.mac;
networkConfig.DHCP = "yes";
};
};
in
lib.mkIf cfg.enable {
registry.address.${config.networking.hostName}.${name} = lib.mkIf (cfg.address != null) cfg.address;
registry.route.${config.networking.hostName}.${name} = lib.mkIf cfg.reverseProxy.enable cfg.reverseProxy.route;
assertions = assertions =
let let
hasDirectorySettings = mount: mount.owner != null || mount.group != null || mount.mode != null; hasDirectorySettings = mount: mount.owner != null || mount.group != null || mount.mode != null;
hasCompleteDirectorySettings = mount: mount.owner != null && mount.group != null && mount.mode != null; hasCompleteDirectorySettings = mount: mount.owner != null && mount.group != null && mount.mode != null;
hasOneSource = mount: (mount.directory != null) != (mount.file != null); hasOneSource = mount: (mount.directory != null) != (mount.file != null);
mountsWithoutOneSource = lib.attrNames (lib.filterAttrs (_: mount: !hasOneSource mount) cfg.mounts); mountsWithInvalidSource = lib.attrNames (lib.filterAttrs (_: mount: !hasOneSource mount) cfg.mounts);
fileMountsWithDirectorySettings = lib.attrNames ( fileMountsWithHostSettings = lib.attrNames (
lib.filterAttrs (_: mount: mount.file != null && hasDirectorySettings mount) cfg.mounts lib.filterAttrs (_: mount: mount.file != null && hasDirectorySettings mount) cfg.mounts
); );
incompleteHostDirectoryMounts = lib.attrNames ( directoryMountsWithPartialHostSettings = lib.attrNames (
lib.filterAttrs (_: mount: mount.directory != null && hasDirectorySettings mount && !hasCompleteDirectorySettings mount) cfg.mounts lib.filterAttrs (_: mount: mount.directory != null && hasDirectorySettings mount && !hasCompleteDirectorySettings mount) cfg.mounts
); );
in in
[ [
{ {
assertion = mountsWithoutOneSource == [ ]; assertion = mountsWithInvalidSource == [ ];
message = '' message = ''
guests.${name} mounts must set exactly one of directory or file for ${lib.concatStringsSep ", " mountsWithoutOneSource}. guests.${name} mounts ${lib.concatStringsSep ", " mountsWithInvalidSource} must set exactly one of `directory` or `file`.
''; '';
} }
{ {
assertion = fileMountsWithDirectorySettings == [ ]; assertion = fileMountsWithHostSettings == [ ];
message = '' message = ''
guests.${name} file mounts must not set owner, group, or mode for ${lib.concatStringsSep ", " fileMountsWithDirectorySettings}. guests.${name} file mounts ${lib.concatStringsSep ", " fileMountsWithHostSettings} must not set `owner`, `group`, or `mode`.
''; '';
} }
{ {
assertion = incompleteHostDirectoryMounts == [ ]; assertion = directoryMountsWithPartialHostSettings == [ ];
message = '' message = ''
guests.${name} has incomplete host directory settings for ${lib.concatStringsSep ", " incompleteHostDirectoryMounts}. Set owner, group, and mode together. guests.${name} directory mounts ${lib.concatStringsSep ", " directoryMountsWithPartialHostSettings} must set `owner`, `group`, and `mode` together.
''; '';
} }
{ {
@@ -225,23 +205,27 @@ let
} }
]; ];
systemd.services."container@${name}" = lib.mkMerge [ registry.address.${config.networking.hostName}.${name} =
lib.mkIf (cfg.address != null) cfg.address;
registry.route.${config.networking.hostName}.${name} =
lib.mkIf cfg.reverseProxy.enable cfg.reverseProxy.route;
systemd.services."container@${name}" =
let
bridgeDevice = "sys-subsystem-net-devices-${lib.replaceStrings [ "-" ] [ "\\x2d" ] (util.bridgeName cfg.vlan)}.device";
in
{ {
after = [ bridgeDevice ];
wants = [ bridgeDevice ];
serviceConfig = lib.filterAttrs (_: v: v != null) { serviceConfig = lib.filterAttrs (_: v: v != null) {
MemoryMax = cfg.limits.memory; MemoryMax = cfg.limits.memory;
CPUQuota = cfg.limits.cpu; CPUQuota = cfg.limits.cpu;
TasksMax = cfg.limits.tasksMax; TasksMax = cfg.limits.tasksMax;
}; };
preStart = lib.mkIf (directoryMounts != { }) directoryScript; preStart = lib.mkIf (directoryMounts != { }) directoryScript;
} };
(let
bridgeDevice = "sys-subsystem-net-devices-${lib.replaceStrings [ "-" ] [ "\\x2d" ] (util.bridgeName cfg.vlan)}.device";
in
{
after = [ bridgeDevice ];
wants = [ bridgeDevice ];
})
];
containers.${name} = { containers.${name} = {
autoStart = true; autoStart = true;
@@ -257,36 +241,28 @@ let
config = { config = {
imports = [ imports = [
repositoryModules
registryAssembly.module
inputs.sops-nix.nixosModules.sops inputs.sops-nix.nixosModules.sops
inputs.stylix.nixosModules.stylix inputs.stylix.nixosModules.stylix
repositoryModules
registryAssembly.module
interior
{ {
modules.guest.enable = true; modules.guest.enable = true;
networking.useNetworkd = true;
networking.useHostResolvConf = false;
systemd.network.networks."20-eth0" = {
matchConfig.Name = "eth0";
linkConfig.MACAddress = cfg.mac;
networkConfig.DHCP = "yes";
};
} }
guestNet
interior
]; ];
}; };
}; };
}; };
in
{
mkGuest =
{
name,
interior ? { },
}:
{ config, lib, ... }:
{
options.guests.${name} = mkGuestOptions { inherit config lib name; };
config = mkGuestConfig {
inherit
config
interior
lib
name
;
};
}; };
} }