style(nix): apply style fixes

This commit was merged in pull request #53.
This commit is contained in:
2026-09-16 00:16:08 -04:00
parent d24f58a4c9
commit e15ce7f16b
42 changed files with 389 additions and 289 deletions

View File

@@ -109,12 +109,16 @@ in
inherit (cfg.reverseProxy) trustedSources;
};
volumes = lib.mapAttrs (_urlPath: volume: {
inherit (volume) path access flags readOnly;
inherit (volume)
path
access
flags
readOnly
;
}) cfg.volumes;
};
mounts =
{
mounts = {
${cfg.stateDir} = {
directory = cfg.statePath;
owner = config.registry."stable-uid".${config.networking.hostName}.copyparty;
@@ -126,7 +130,8 @@ in
readOnly = true;
};
}
// lib.mapAttrs' (_urlPath: volume:
// lib.mapAttrs' (
_urlPath: volume:
lib.nameValuePair volume.path {
directory = volume.hostPath;
owner = "root";

View File

@@ -88,14 +88,18 @@ in
guests.palworld = {
interior.modules.services.games.palworld = {
enable = true;
inherit (cfg) serverName port publicIP autoStart;
inherit (cfg)
serverName
port
publicIP
autoStart
;
inherit steamDir installDir stateDir;
passwordFile = "/run/secrets/${cfg.passwordSecret}";
adminPasswordFile = "/run/secrets/${cfg.adminPasswordSecret}";
};
mounts =
{
mounts = {
${steamDir} = {
directory = cfg.steamPath;
owner = config.registry."stable-uid".${config.networking.hostName}.steamcmd;
@@ -133,8 +137,7 @@ in
};
};
sops.secrets =
{
sops.secrets = {
${cfg.passwordSecret} = {
owner = "root";
group = "storage";

View File

@@ -34,7 +34,7 @@
registry.shell-shortcut.neogaia = {
vpn-on = "sudo systemctl start wireguard-wg-home.target";
vpn-off = ''sudo systemctl stop 'wireguard-wg-home*.service' wireguard-wg-home.target'';
vpn-off = "sudo systemctl stop 'wireguard-wg-home*.service' wireguard-wg-home.target";
};
modules.monorepo.enable = true;

View File

@@ -1,4 +1,4 @@
{ ... }:
_:
# neogaia's disk layout for disko: one NVMe disk, GPT, with an EFI system
# partition and a LUKS container holding btrfs subvolumes.
# No swap partition, since swap is zram.

View File

@@ -1,4 +1,4 @@
{ ... }:
_:
# pikachu's install layout for disko: one NVMe boot disk with an EFI system partition and ext4 root.
# The existing 8 TB ZFS mirror is imported by name and is never declared here.
{

View File

@@ -8,7 +8,10 @@
# Disk layout is in ./disk.nix.
# `fileSystems` are derived from it, none declared here.
{
imports = [ ./disk.nix ] ++ lib.optional (builtins.pathExists ./hardware-configuration.nix) ./hardware-configuration.nix;
imports = [
./disk.nix
]
++ lib.optional (builtins.pathExists ./hardware-configuration.nix) ./hardware-configuration.nix;
nixpkgs.hostPlatform = "x86_64-linux";

View File

@@ -1,4 +1,4 @@
{ ... }:
_:
# zeus's disk layout for disko: two NVMe disks with one EFI system partition
# and two LUKS containers joined into one btrfs filesystem.
# No swap partition, since swap is zram.

View File

@@ -10,7 +10,8 @@ let
user = config.user.name;
in
{
options.modules.desktop.apps.alacritty.enable = lib.mkEnableOption "Alacritty as the desktop terminal";
options.modules.desktop.apps.alacritty.enable =
lib.mkEnableOption "Alacritty as the desktop terminal";
config = lib.mkIf cfg.enable {
home-manager.users.${user}.home.packages = [ pkgs.alacritty ];

View File

@@ -10,7 +10,8 @@ let
user = config.user.name;
in
{
options.modules.desktop.apps.obsidian.enable = lib.mkEnableOption "Obsidian as the desktop note-taking vault";
options.modules.desktop.apps.obsidian.enable =
lib.mkEnableOption "Obsidian as the desktop note-taking vault";
config = lib.mkIf cfg.enable {
home-manager.users.${user}.home.packages = [ pkgs.obsidian ];

View File

@@ -10,7 +10,8 @@ let
user = config.user.name;
in
{
options.modules.desktop.apps.vencord.enable = lib.mkEnableOption "Vesktop, a Discord client with Vencord built in";
options.modules.desktop.apps.vencord.enable =
lib.mkEnableOption "Vesktop, a Discord client with Vencord built in";
config = lib.mkIf cfg.enable {
home-manager.users.${user}.home.packages = [ pkgs.vesktop ];

View File

@@ -67,8 +67,7 @@ in
# UWSM launches the session without the shell profile that would carry
# them, so a variable the compositor or its children must see is set
# here rather than through home-manager's sessionVariables.
env =
[
env = [
# Chromium and Electron apps read this to select native Wayland;
# nixpkgs wrappers (Obsidian's included) gate their Wayland flags on
# it, so without it they run under XWayland and blur at this DPI.

View File

@@ -45,7 +45,8 @@ let
'';
in
{
options.modules.desktop.session.hyprland.hyprlock.enable = lib.mkEnableOption "the hyprlock lock screen";
options.modules.desktop.session.hyprland.hyprlock.enable =
lib.mkEnableOption "the hyprlock lock screen";
config = lib.mkIf cfg.enable {
home-manager.users.${user} = {

View File

@@ -10,7 +10,8 @@ let
cfg = config.modules.desktop.session.login;
in
{
options.modules.desktop.session.login.enable = lib.mkEnableOption "greetd with the tuigreet text greeter";
options.modules.desktop.session.login.enable =
lib.mkEnableOption "greetd with the tuigreet text greeter";
config = lib.mkIf cfg.enable {
services.greetd = {

View File

@@ -25,7 +25,8 @@ let
'';
in
{
options.modules.desktop.utilities.clipboard.enable = lib.mkEnableOption "cliphist clipboard history";
options.modules.desktop.utilities.clipboard.enable =
lib.mkEnableOption "cliphist clipboard history";
config = lib.mkIf cfg.enable {
home-manager.users.${user} = {

View File

@@ -10,7 +10,8 @@ let
user = config.user.name;
in
{
options.modules.desktop.utilities.osd.enable = lib.mkEnableOption "the SwayOSD volume and brightness popup";
options.modules.desktop.utilities.osd.enable =
lib.mkEnableOption "the SwayOSD volume and brightness popup";
config = lib.mkIf cfg.enable {
environment.systemPackages = [ pkgs.swayosd ];

View File

@@ -41,7 +41,8 @@ let
'';
in
{
options.modules.desktop.utilities.recording.enable = lib.mkEnableOption "wf-recorder screen recording";
options.modules.desktop.utilities.recording.enable =
lib.mkEnableOption "wf-recorder screen recording";
config = lib.mkIf cfg.enable {
home-manager.users.${user} = {

View File

@@ -32,7 +32,8 @@ let
'';
in
{
options.modules.desktop.utilities.screenshot.enable = lib.mkEnableOption "screenshots via grimblast and satty";
options.modules.desktop.utilities.screenshot.enable =
lib.mkEnableOption "screenshots via grimblast and satty";
config = lib.mkIf cfg.enable {
home-manager.users.${user} = {

View File

@@ -5,7 +5,7 @@
}:
let
cfg = config.modules.host;
user = config.user;
inherit (config) user;
hostSecrets = ../secrets + "/${config.networking.hostName}.yaml";
passwordSecret = "${user.name}-password";
in

View File

@@ -104,8 +104,7 @@ let
isWorkstation = elem currentHost cfg.hosts.workstations;
defaultAuthorizedKeys = lib.flatten (
clientKeysFor workstationNames
++ optional isServer (clientKeysFor serverNames)
clientKeysFor workstationNames ++ optional isServer (clientKeysFor serverNames)
);
outboundTargetNames =
@@ -120,7 +119,8 @@ let
in
filter (name: name != currentHost) (targetNamesIn groupTargets);
sshSettingsFor = name:
sshSettingsFor =
name:
let
target = cfg.targets.${name};
in
@@ -131,7 +131,8 @@ let
}
// optionalAttrs (target.port != 22) { Port = target.port; };
knownHostNamesFor = target:
knownHostNamesFor =
target:
let
names = unique (target.aliases ++ [ target.hostName ]);
withPort = name: if target.port == 22 then name else "[${name}]:${toString target.port}";
@@ -142,7 +143,8 @@ let
concatLists (
mapAttrsToList (
targetName: target:
imap0 (i: key:
imap0 (
i: key:
nameValuePair "${targetName}-${toString i}" {
hostNames = knownHostNamesFor target;
publicKey = keyWithoutComment key;
@@ -290,8 +292,7 @@ in
};
};
config = mkIf cfg.enable (
mkMerge [
config = mkIf cfg.enable (mkMerge [
{
services.openssh.enable = true;
@@ -342,6 +343,5 @@ in
home-manager.users.${user}.programs.ssh.settings."*".IdentityFile =
config.sops.secrets.${userKeySecret}.path;
})
]
);
]);
}

View File

@@ -75,8 +75,9 @@ in
];
# networkd owns these interfaces so NetworkManager does not contend for them.
networking.networkmanager.unmanaged =
[ "interface-name:${cfg.trunk}" ]
networking.networkmanager.unmanaged = [
"interface-name:${cfg.trunk}"
]
++ map (id: "interface-name:${bridgeName id}") cfg.ids
++ map (id: "interface-name:${vlanName id}") cfg.ids;

View File

@@ -88,16 +88,18 @@ in
networking.wireguard.interfaces.${cfg.interface} = {
ips = [ cfg.address ];
mtu = cfg.mtu;
inherit (cfg) mtu;
privateKeyFile = config.sops.secrets.${cfg.privateKeySecret}.path;
peers = [
({
(
{
inherit (cfg.peer) publicKey endpoint allowedIPs;
}
// lib.optionalAttrs (cfg.peer.persistentKeepalive != null) {
inherit (cfg.peer) persistentKeepalive;
})
}
)
];
};
};

View File

@@ -45,14 +45,14 @@ in
users.users.${cfg.user} = {
isSystemUser = true;
uid = config.registry."stable-uid".${config.networking.hostName}.actualbudget;
group = cfg.group;
inherit (cfg) group;
};
services.actual = {
enable = true;
openFirewall = true;
user = cfg.user;
group = cfg.group;
inherit (cfg) user;
inherit (cfg) group;
settings = {
inherit (cfg) port dataDir;
};

View File

@@ -40,13 +40,16 @@ let
renderAccess = permission: accounts: " ${permission}: ${lib.concatStringsSep ", " accounts}";
hasFlag = name: flags: lib.any (flag: lib.hasPrefix "${name}:" flag || lib.hasPrefix "${name}=" flag) flags;
hasFlag =
name: flags: lib.any (flag: lib.hasPrefix "${name}:" flag || lib.hasPrefix "${name}=" flag) flags;
defaultPermissionFlags = flags:
defaultPermissionFlags =
flags:
lib.optionals (!(hasFlag "chmod_d" flags)) [ "chmod_d: 2770" ]
++ lib.optionals (!(hasFlag "chmod_f" flags)) [ "chmod_f: 660" ];
renderFlags = flags: lib.concatMapStringsSep "\n" (flag: " ${flag}") (flags ++ defaultPermissionFlags flags);
renderFlags =
flags: lib.concatMapStringsSep "\n" (flag: " ${flag}") (flags ++ defaultPermissionFlags flags);
renderVolume = urlPath: volume: ''
[${urlPath}]
@@ -173,7 +176,7 @@ in
users.users.${cfg.user} = {
isSystemUser = true;
uid = config.registry."stable-uid".${config.networking.hostName}.copyparty;
group = cfg.group;
inherit (cfg) group;
home = cfg.stateDir;
};
@@ -202,7 +205,10 @@ in
PrivateTmp = true;
ProtectSystem = "strict";
ProtectHome = true;
ReadWritePaths = [ cfg.stateDir ] ++ map (volume: volume.path) (lib.filter (volume: !volume.readOnly) (lib.attrValues cfg.volumes));
ReadWritePaths = [
cfg.stateDir
]
++ map (volume: volume.path) (lib.filter (volume: !volume.readOnly) (lib.attrValues cfg.volumes));
};
};

View File

@@ -134,8 +134,7 @@
appId = 2394010;
inherit (service) autoStart;
executable = "${startScript}";
arguments =
[
arguments = [
"-useperfthreads"
"-NoAsyncLoadingThread"
"-UseMultithreadForDS"

View File

@@ -7,7 +7,9 @@
let
cfg = config.modules.services.homepage;
mkRegistryPath = registryName: host: entry: "registry.${registryName}.${host}.${entry}";
mkRegistryPath =
registryName: host: entry:
"registry.${registryName}.${host}.${entry}";
homepageEntries = lib.concatLists (
lib.mapAttrsToList (
@@ -19,7 +21,8 @@ let
) registry.homepage
);
mkHref = item:
mkHref =
item:
if item.homepage.href != null then
item.homepage.href
else if (item.composite.route or null) != null then
@@ -32,7 +35,8 @@ let
else
throw "${mkRegistryPath "homepage" item.host item.entry} needs href or a matching route entry";
mkServiceAttrs = item:
mkServiceAttrs =
item:
lib.filterAttrs (_: value: value != null) {
href = mkHref item;
inherit (item.homepage) description icon;
@@ -40,11 +44,11 @@ let
sortedEntries = lib.sort (left: right: left.homepage.name < right.homepage.name) homepageEntries;
insertEntry = acc: item:
insertEntry =
acc: item:
acc
// {
${item.homepage.tab} = (acc.${item.homepage.tab} or { })
// {
${item.homepage.tab} = (acc.${item.homepage.tab} or { }) // {
${item.homepage.section} = (acc.${item.homepage.tab}.${item.homepage.section} or [ ]) ++ [
{ ${item.homepage.name} = mkServiceAttrs item; }
];
@@ -80,13 +84,15 @@ let
];
};
orderedSections = tab: sections:
orderedSections =
tab: sections:
let
sectionOrder = sectionOrderByTab.${tab} or [ ];
in
sectionOrder ++ lib.filter (section: !lib.elem section sectionOrder) (lib.attrNames sections);
mkTab = tab:
mkTab =
tab:
let
sections = entriesByTab.${tab};
in
@@ -148,7 +154,9 @@ in
openFirewall = true;
inherit (cfg) listenPort;
environmentFiles = [ cfg.environmentFile ];
allowedHosts = lib.concatStringsSep "," (if cfg.allowedHosts == null then derivedAllowedHosts else cfg.allowedHosts);
allowedHosts = lib.concatStringsSep "," (
if cfg.allowedHosts == null then derivedAllowedHosts else cfg.allowedHosts
);
services = homepageServices;
widgets = [
{

View File

@@ -50,7 +50,7 @@ in
user = "navidrome";
group = "storage";
openFirewall = true;
environmentFile = cfg.environmentFile;
inherit (cfg) environmentFile;
settings = {
Address = "0.0.0.0";
Port = 4533;

View File

@@ -7,15 +7,20 @@
let
cfg = config.modules.services.reverse-proxy;
mkRegistryPath = registryName: host: entry: "registry.${registryName}.${host}.${entry}";
mkRegistryPath =
registryName: host: entry:
"registry.${registryName}.${host}.${entry}";
mkBackend = address: port: "http://${address}:${toString port}";
mkVirtualHost = host: entry: mode:
mkVirtualHost =
host: entry: mode:
let
compositeEntry = registry.join host entry;
route = compositeEntry.route;
address = compositeEntry.address or (throw "no matching entry in registry.address for ${mkRegistryPath "route" host entry}");
inherit (compositeEntry) route;
address =
compositeEntry.address
or (throw "no matching entry in registry.address for ${mkRegistryPath "route" host entry}");
isHttp = mode == "http";
port = if isHttp then route.http.port else route.port;
in
@@ -63,7 +68,11 @@ let
domain: virtualHosts:
if lib.length virtualHosts > 1 then
[
"duplicate route domain ${domain} in ${lib.concatMapStringsSep " and " (virtualHost: mkRegistryPath virtualHost.registryName virtualHost.host virtualHost.entry) virtualHosts}"
"duplicate route domain ${domain} in ${
lib.concatMapStringsSep " and " (
virtualHost: mkRegistryPath virtualHost.registryName virtualHost.host virtualHost.entry
) virtualHosts
}"
]
else
[ ]
@@ -76,13 +85,21 @@ let
else
lib.listToAttrs generatedVirtualHostList;
mkUdpStream = host: entry: port:
mkUdpStream =
host: entry: port:
let
compositeEntry = registry.join host entry;
address = compositeEntry.address or (throw "no matching entry in registry.address for ${mkRegistryPath "route" host entry}");
address =
compositeEntry.address
or (throw "no matching entry in registry.address for ${mkRegistryPath "route" host entry}");
in
{
inherit host entry port address;
inherit
host
entry
port
address
;
};
generatedUdpStreams = lib.concatLists (

View File

@@ -10,7 +10,8 @@ let
user = config.user.name;
in
{
options.modules.shell.bazel.enable = lib.mkEnableOption "Bazel for the primary user's shell environment";
options.modules.shell.bazel.enable =
lib.mkEnableOption "Bazel for the primary user's shell environment";
config = lib.mkIf cfg.enable {
home-manager.users.${user}.home.packages = [ pkgs.bazel ];

View File

@@ -107,8 +107,7 @@ in
# Rendered by home-manager into ~/.config/fish/config.fish.
interactiveShellInit = lib.concatStringsSep "\n" (
(lib.mapAttrsToList exportEnvVar envVars)
++ [ (builtins.readFile ./config.fish) ]
(lib.mapAttrsToList exportEnvVar envVars) ++ [ (builtins.readFile ./config.fish) ]
);
};
};

View File

@@ -10,7 +10,8 @@ let
user = config.user.name;
in
{
options.modules.shell.herdr.enable = lib.mkEnableOption "Herdr, a terminal multiplexer for coding agents";
options.modules.shell.herdr.enable =
lib.mkEnableOption "Herdr, a terminal multiplexer for coding agents";
config = lib.mkIf cfg.enable {
registry.shell-shortcut.${config.networking.hostName}.hs = "herdr --session";

View File

@@ -11,7 +11,8 @@ let
user = config.user.name;
in
{
options.modules.shell.nvim.enable = lib.mkEnableOption "Neovim, configured declaratively via nixvim";
options.modules.shell.nvim.enable =
lib.mkEnableOption "Neovim, configured declaratively via nixvim";
config = lib.mkIf cfg.enable {
registry.shell-shortcut.${config.networking.hostName} = {

View File

@@ -18,8 +18,7 @@ let
in
{
options.modules.shell.pi = {
enable = lib.mkEnableOption ''
Pi, a terminal coding agent, configured through home-manager'';
enable = lib.mkEnableOption "Pi, a terminal coding agent, configured through home-manager";
};
config = lib.mkIf cfg.enable {

View File

@@ -10,7 +10,8 @@ let
user = config.user.name;
in
{
options.modules.shell.python.enable = lib.mkEnableOption "Python tools for the primary user's shell environment";
options.modules.shell.python.enable =
lib.mkEnableOption "Python tools for the primary user's shell environment";
config = lib.mkIf cfg.enable {
registry.env-var.${config.networking.hostName}.PYTHON_TOOLCHAIN_ROOT = "${pkgs.python3}";

View File

@@ -20,7 +20,8 @@ let
};
in
{
options.modules.shell.rust.enable = lib.mkEnableOption "Rust tools for the primary user's shell environment";
options.modules.shell.rust.enable =
lib.mkEnableOption "Rust tools for the primary user's shell environment";
config = lib.mkIf cfg.enable {
registry.env-var.${config.networking.hostName}.RUST_TOOLCHAIN_ROOT = "${toolchain}";

View File

@@ -6,14 +6,16 @@
message = "Route domains must be unique.";
}
{
assertion = entries:
assertion =
entries:
lib.registry.predicates.uniqueValue (entry: entry.value) (
lib.concatMap (entry: map (port: entry // { value = port; }) entry.value.udp.ports) entries
);
message = "Route UDP ports must be unique.";
}
{
assertion = entries: lib.all (entry: entry.value.port == null || entry.value.http.port == null) entries;
assertion =
entries: lib.all (entry: entry.value.port == null || entry.value.http.port == null) entries;
message = "Route entries must not set both port and http.port.";
}
];

View File

@@ -7,12 +7,14 @@ let
unique
;
serviceNamesByUid = entries:
serviceNamesByUid =
entries:
mapAttrs (_uid: uidEntries: unique (map (entry: entry.entry) uidEntries)) (
groupBy (entry: toString entry.value) entries
);
duplicateUids = entries:
duplicateUids =
entries:
filterAttrs (_uid: serviceNames: builtins.length serviceNames > 1) (serviceNamesByUid entries);
in

View File

@@ -78,7 +78,7 @@
{ self, nixpkgs, ... }@inputs:
import ./src/dotfiles {
inherit inputs self;
lib = nixpkgs.lib;
inherit (nixpkgs) lib;
root = ./configs/nixos;
system = "x86_64-linux";
};

View File

@@ -10,7 +10,8 @@ in
{
fix = {
type = "app";
program = lib.getExe (pkgs.writeShellApplication {
program = lib.getExe (
pkgs.writeShellApplication {
name = "fix";
runtimeInputs = [
formatter.config.build.wrapper
@@ -23,6 +24,7 @@ in
deadnix --edit --exclude configs/nixos/hosts/*/hardware-configuration.nix -- .
treefmt
'';
});
}
);
};
}

View File

@@ -17,16 +17,13 @@ let
directoryMounts = lib.filterAttrs (_: mount: mount.directory != null) cfg.mounts;
directoryScript = lib.concatStringsSep "\n" (
lib.mapAttrsToList (
_: mount:
''
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
'') directoryMounts
);
in
{
@@ -171,14 +168,20 @@ let
assertions =
let
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);
mountsWithInvalidSource = lib.attrNames (lib.filterAttrs (_: mount: !hasOneSource mount) cfg.mounts);
mountsWithInvalidSource = lib.attrNames (
lib.filterAttrs (_: mount: !hasOneSource mount) cfg.mounts
);
fileMountsWithHostSettings = lib.attrNames (
lib.filterAttrs (_: mount: mount.file != null && hasDirectorySettings mount) cfg.mounts
);
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
[
@@ -203,20 +206,23 @@ let
{
assertion = lib.elem cfg.vlan config.modules.network.vlans.ids;
message = ''
guests.${name}.vlan = ${toString cfg.vlan} is not among its host's modules.network.vlans.ids (${lib.concatMapStringsSep ", " toString config.modules.network.vlans.ids}). Declare the VLAN on the host or correct the guest's placement.
guests.${name}.vlan = ${toString cfg.vlan} is not among its host's modules.network.vlans.ids (${
lib.concatMapStringsSep ", " toString config.modules.network.vlans.ids
}). Declare the VLAN on the host or correct the guest's placement.
'';
}
];
registry.address.${config.networking.hostName}.${name} =
lib.mkIf (cfg.address != null) cfg.address;
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";
bridgeDevice = "sys-subsystem-net-devices-${
lib.replaceStrings [ "-" ] [ "\\x2d" ] (util.bridgeName cfg.vlan)
}.device";
in
{
after = [ bridgeDevice ];
@@ -268,10 +274,11 @@ let
};
};
};
in
let
files = util.collectNixFiles root;
guestFiles = lib.filterAttrs (file: type: type == "regular" && lib.hasSuffix ".nix" file) (builtins.readDir root);
guestFiles = lib.filterAttrs (file: type: type == "regular" && lib.hasSuffix ".nix" file) (
builtins.readDir root
);
names = map (file: lib.removeSuffix ".nix" file) (lib.attrNames guestFiles);
in
{

View File

@@ -26,7 +26,8 @@ let
guestModules
# TODO: refactor
registryModule (root + "/${name}")
registryModule
(root + "/${name}")
{
networking.hostName = name;
@@ -34,12 +35,8 @@ let
}
];
};
in
let
directories = lib.filterAttrs (_name: type: type == "directory") (builtins.readDir root);
names = lib.attrNames directories;
in
lib.genAttrs names (
name:
mkHost { inherit root name; }
)
lib.genAttrs names (name: mkHost { inherit root name; })

View File

@@ -1,4 +1,8 @@
{ hosts, lib, root }:
{
hosts,
lib,
root,
}:
let
checkType = lib.types.submodule {
options = {
@@ -19,7 +23,8 @@ let
};
predicates = {
uniqueValue = value: entries: builtins.length (lib.unique (map value entries)) == builtins.length entries;
uniqueValue =
value: entries: builtins.length (lib.unique (map value entries)) == builtins.length entries;
};
registryLib = lib // {
@@ -57,7 +62,9 @@ let
registryName = fileName: lib.removeSuffix ".nix" fileName;
registryOption = registry: lib.mkOption {
registryOption =
registry:
lib.mkOption {
type = lib.types.attrsOf (lib.types.attrsOf registry.type);
default = { };
description = ''
@@ -65,7 +72,8 @@ let
'';
};
mkRegistry = path:
mkRegistry =
path:
let
evaluated = lib.evalModules {
specialArgs.lib = registryLib;
@@ -79,15 +87,21 @@ let
inherit (evaluated.config) type replicate checks;
};
definitions = lib.mapAttrs' (
name: type:
definitions =
lib.mapAttrs'
(
name: _type:
let
path = root + "/${name}";
in
lib.nameValuePair (registryName name) (mkRegistry path)
) (lib.filterAttrs (name: type: type == "regular" && lib.hasSuffix ".nix" name) (builtins.readDir root));
)
(
lib.filterAttrs (name: type: type == "regular" && lib.hasSuffix ".nix" name) (builtins.readDir root)
);
flattenRegistryEntries = registryName: data:
flattenRegistryEntries =
registryName: data:
lib.concatLists (
lib.mapAttrsToList (
host: entries:
@@ -98,10 +112,12 @@ let
) data
);
rawDeclarations = registryName: hosts:
rawDeclarations =
registryName: hosts:
lib.mapAttrs (_hostName: host: host.config.registry.${registryName} or { }) hosts;
replicatedEntries = registryName: raw:
replicatedEntries =
registryName: raw:
let
entries = lib.concatLists (
lib.concatLists (
@@ -126,18 +142,21 @@ let
else
throw "conflicting replicated registry entry ${entry.path} does not match ${acc.${entry.entryName}.path}"
else
acc // {
acc
// {
${entry.entryName} = entry;
}
) { } entries;
replicatedData = registryName: hosts: raw:
replicatedData =
registryName: hosts: raw:
let
entries = lib.mapAttrs (_entryName: entry: entry.value) (replicatedEntries registryName raw);
in
lib.mapAttrs (_hostName: _host: entries) hosts;
validationAssertions = data:
validationAssertions =
data:
lib.concatLists (
lib.mapAttrsToList (
registryName: registry:
@@ -151,7 +170,8 @@ let
) definitions
);
assertValid = data:
assertValid =
data:
let
assertions = validationAssertions data;
failures = lib.filter (assertion: !assertion.assertion) assertions;
@@ -161,9 +181,12 @@ let
);
data;
join = registry: host: entry:
join =
registry: host: entry:
lib.filterAttrs (_name: value: value != null) (
lib.mapAttrs (registryName: _registry: (registry.${registryName}.${host} or { }).${entry} or null) definitions
lib.mapAttrs (
registryName: _registry: (registry.${registryName}.${host} or { }).${entry} or null
) definitions
);
collectData =
@@ -180,7 +203,8 @@ let
in
assertValid data;
withOperations = registry:
withOperations =
registry:
registry
// {
join = host: entry: join registry host entry;
@@ -190,8 +214,10 @@ in
types = lib.mapAttrs (_name: definition: definition.type) definitions;
module = {
options.registry = lib.mapAttrs (_name: registry: registryOption registry) definitions;
options.registry = lib.mapAttrs (_name: registryOption) definitions;
};
collected = withOperations (collectData { inherit hosts; });
collected = withOperations (collectData {
inherit hosts;
});
}

View File

@@ -28,5 +28,14 @@ in
hash = builtins.hashString "sha256" name;
octet = i: builtins.substring (i * 2) 2 hash;
in
lib.concatStringsSep ":" ([ "02" ] ++ map octet [ 0 1 2 3 4 ]);
lib.concatStringsSep ":" (
[ "02" ]
++ map octet [
0
1
2
3
4
]
);
}