refactor(flake): split assembly code #73
@@ -39,7 +39,6 @@ let
|
|||||||
inherit
|
inherit
|
||||||
inputs
|
inputs
|
||||||
lib
|
lib
|
||||||
self
|
|
||||||
specialArgs
|
specialArgs
|
||||||
registryAssembly
|
registryAssembly
|
||||||
util
|
util
|
||||||
|
|||||||
146
flake/guest.nix
146
flake/guest.nix
@@ -1,20 +1,38 @@
|
|||||||
{
|
{
|
||||||
inputs,
|
inputs,
|
||||||
lib,
|
lib,
|
||||||
self,
|
|
||||||
specialArgs,
|
specialArgs,
|
||||||
repositoryModules,
|
repositoryModules,
|
||||||
registryAssembly,
|
registryAssembly,
|
||||||
util,
|
util,
|
||||||
}:
|
}:
|
||||||
let
|
|
||||||
mkGuestOptions =
|
|
||||||
{
|
{
|
||||||
config,
|
mkGuest =
|
||||||
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
|
|
||||||
;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user