refactor(guest): clean guest module implementation
This commit is contained in:
@@ -39,7 +39,6 @@ let
|
||||
inherit
|
||||
inputs
|
||||
lib
|
||||
self
|
||||
specialArgs
|
||||
registryAssembly
|
||||
util
|
||||
|
||||
146
flake/guest.nix
146
flake/guest.nix
@@ -1,20 +1,38 @@
|
||||
{
|
||||
inputs,
|
||||
lib,
|
||||
self,
|
||||
specialArgs,
|
||||
repositoryModules,
|
||||
registryAssembly,
|
||||
util,
|
||||
}:
|
||||
let
|
||||
mkGuestOptions =
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
mkGuest =
|
||||
{
|
||||
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";
|
||||
vlan = lib.mkOption {
|
||||
type = lib.types.ints.between 1 4094;
|
||||
@@ -146,75 +164,37 @@ let
|
||||
};
|
||||
};
|
||||
|
||||
mkGuestConfig =
|
||||
{
|
||||
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;
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
assertions =
|
||||
let
|
||||
hasDirectorySettings = 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);
|
||||
mountsWithoutOneSource = lib.attrNames (lib.filterAttrs (_: mount: !hasOneSource mount) cfg.mounts);
|
||||
fileMountsWithDirectorySettings = lib.attrNames (
|
||||
mountsWithInvalidSource = lib.attrNames (lib.filterAttrs (_: mount: !hasOneSource mount) cfg.mounts);
|
||||
fileMountsWithHostSettings = lib.attrNames (
|
||||
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
|
||||
);
|
||||
in
|
||||
[
|
||||
{
|
||||
assertion = mountsWithoutOneSource == [ ];
|
||||
assertion = mountsWithInvalidSource == [ ];
|
||||
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 = ''
|
||||
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 = ''
|
||||
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) {
|
||||
MemoryMax = cfg.limits.memory;
|
||||
CPUQuota = cfg.limits.cpu;
|
||||
TasksMax = cfg.limits.tasksMax;
|
||||
};
|
||||
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} = {
|
||||
autoStart = true;
|
||||
@@ -257,36 +241,28 @@ let
|
||||
|
||||
config = {
|
||||
imports = [
|
||||
repositoryModules
|
||||
registryAssembly.module
|
||||
inputs.sops-nix.nixosModules.sops
|
||||
inputs.stylix.nixosModules.stylix
|
||||
|
||||
repositoryModules
|
||||
registryAssembly.module
|
||||
interior
|
||||
|
||||
{
|
||||
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