refactor(flake): split assembly code #73
@@ -4,93 +4,59 @@
|
||||
self,
|
||||
}:
|
||||
let
|
||||
# TODO: refactor the registry code
|
||||
registryAssembly = import ./registry.nix { inherit lib self; };
|
||||
|
||||
collectNixFiles =
|
||||
dir:
|
||||
lib.flatten (
|
||||
lib.mapAttrsToList (
|
||||
name: type:
|
||||
let
|
||||
path = dir + "/${name}";
|
||||
in
|
||||
if type == "directory" then
|
||||
collectNixFiles path
|
||||
else if type == "regular" && lib.hasSuffix ".nix" name then
|
||||
[ path ]
|
||||
else
|
||||
[ ]
|
||||
) (builtins.readDir dir)
|
||||
);
|
||||
util = import ../lib { inherit lib; };
|
||||
mkModules = import ./module.nix { inherit util; };
|
||||
|
||||
moduleFiles = collectNixFiles (self + "/modules");
|
||||
guestFiles = collectNixFiles (self + "/guests");
|
||||
modules = mkModules {
|
||||
root = self + "/modules";
|
||||
};
|
||||
|
||||
#----------------------------------------------------------
|
||||
guestFiles = util.collectNixFiles (self + "/guests");
|
||||
|
||||
collectedRegistry = registryAssembly.collect { hosts = self.nixosConfigurations; };
|
||||
|
||||
specialArgs = {
|
||||
inherit
|
||||
dotfiles
|
||||
flake
|
||||
inputs
|
||||
self
|
||||
;
|
||||
registry = collectedRegistry;
|
||||
};
|
||||
|
||||
bridgeName = id: "br-vlan${toString id}";
|
||||
flake = {
|
||||
inherit (hosts) mkHosts;
|
||||
inherit (guests) mkGuest;
|
||||
|
||||
dotfiles = {
|
||||
inherit (guests) guest;
|
||||
|
||||
lib = {
|
||||
inherit bridgeName;
|
||||
inherit (guests) deriveMac;
|
||||
};
|
||||
inherit util;
|
||||
};
|
||||
|
||||
guests = import ./guests.nix {
|
||||
guests = import ./guest.nix {
|
||||
inherit
|
||||
inputs
|
||||
lib
|
||||
self
|
||||
specialArgs
|
||||
bridgeName
|
||||
moduleFiles
|
||||
registryAssembly
|
||||
util
|
||||
;
|
||||
repositoryModules = modules;
|
||||
};
|
||||
|
||||
mkHost =
|
||||
{
|
||||
hostName,
|
||||
system ? "x86_64-linux",
|
||||
}:
|
||||
inputs.nixpkgs.lib.nixosSystem {
|
||||
inherit system specialArgs;
|
||||
modules =
|
||||
moduleFiles
|
||||
++ guestFiles
|
||||
++ [
|
||||
inputs.chaotic.nixosModules.default
|
||||
inputs.disko.nixosModules.disko
|
||||
inputs.sops-nix.nixosModules.sops
|
||||
inputs.stylix.nixosModules.stylix
|
||||
registryAssembly.module
|
||||
(self + "/hosts/${hostName}")
|
||||
{
|
||||
networking.hostName = hostName;
|
||||
modules.host.enable = true;
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
mkHosts =
|
||||
hostsDir:
|
||||
let
|
||||
hostNames = lib.attrNames (lib.filterAttrs (_name: type: type == "directory") (builtins.readDir hostsDir));
|
||||
in
|
||||
lib.genAttrs hostNames (hostName: mkHost { inherit hostName; });
|
||||
hosts = import ./host.nix {
|
||||
inherit
|
||||
inputs
|
||||
lib
|
||||
self
|
||||
specialArgs
|
||||
guestFiles
|
||||
registryAssembly
|
||||
;
|
||||
repositoryModules = modules;
|
||||
};
|
||||
in
|
||||
{
|
||||
inherit mkHosts;
|
||||
}
|
||||
flake
|
||||
|
||||
@@ -3,22 +3,12 @@
|
||||
lib,
|
||||
self,
|
||||
specialArgs,
|
||||
bridgeName,
|
||||
moduleFiles,
|
||||
repositoryModules,
|
||||
registryAssembly,
|
||||
util,
|
||||
}:
|
||||
let
|
||||
inherit (lib) escapeShellArg mapAttrsToList;
|
||||
|
||||
deriveMac =
|
||||
name:
|
||||
let
|
||||
hash = builtins.hashString "sha256" name;
|
||||
octet = i: builtins.substring (i * 2) 2 hash;
|
||||
in
|
||||
lib.concatStringsSep ":" ([ "02" ] ++ map octet [ 0 1 2 3 4 ]);
|
||||
|
||||
guest =
|
||||
mkGuest =
|
||||
{
|
||||
name,
|
||||
interior ? { },
|
||||
@@ -59,13 +49,13 @@ let
|
||||
|
||||
createdMounts = lib.filterAttrs (_guestPath: m: m.create != null) cfg.mounts;
|
||||
mountCreateScript = lib.concatStringsSep "\n" (
|
||||
mapAttrsToList (
|
||||
lib.mapAttrsToList (
|
||||
_guestPath: m:
|
||||
let
|
||||
create = m.create;
|
||||
in
|
||||
''
|
||||
${config.system.path}/bin/install -d -o ${escapeShellArg (toString create.owner)} -g ${escapeShellArg create.group} -m ${escapeShellArg create.mode} ${escapeShellArg m.hostPath}
|
||||
${config.system.path}/bin/install -d -o ${lib.escapeShellArg (toString create.owner)} -g ${lib.escapeShellArg create.group} -m ${lib.escapeShellArg create.mode} ${lib.escapeShellArg m.hostPath}
|
||||
''
|
||||
) createdMounts
|
||||
);
|
||||
@@ -113,7 +103,7 @@ let
|
||||
};
|
||||
mac = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = deriveMac name;
|
||||
default = util.deriveMac name;
|
||||
defaultText = lib.literalMD "a stable address derived from the guest's namespace path";
|
||||
example = "bc:24:11:00:00:01";
|
||||
description = ''
|
||||
@@ -316,7 +306,7 @@ let
|
||||
}
|
||||
(lib.mkIf networked (
|
||||
let
|
||||
bridgeDevice = "sys-subsystem-net-devices-${lib.replaceStrings [ "-" ] [ "\\x2d" ] (bridgeName cfg.vlan)}.device";
|
||||
bridgeDevice = "sys-subsystem-net-devices-${lib.replaceStrings [ "-" ] [ "\\x2d" ] (util.bridgeName cfg.vlan)}.device";
|
||||
in
|
||||
{
|
||||
after = [ bridgeDevice ];
|
||||
@@ -329,7 +319,7 @@ let
|
||||
containers.${machineName} = lib.mkIf (cfg.backend == "container") {
|
||||
autoStart = cfg.autoStart;
|
||||
privateNetwork = lib.mkDefault true;
|
||||
hostBridge = lib.mkIf networked (bridgeName cfg.vlan);
|
||||
hostBridge = lib.mkIf networked (util.bridgeName cfg.vlan);
|
||||
privateUsers = lib.mkDefault "no";
|
||||
additionalCapabilities = lib.optionals cfg.nesting [ "CAP_NET_ADMIN" ];
|
||||
allowedDevices = lib.optionals cfg.nesting [
|
||||
@@ -349,7 +339,9 @@ let
|
||||
|
||||
config = {
|
||||
imports =
|
||||
moduleFiles
|
||||
[
|
||||
repositoryModules
|
||||
]
|
||||
++ [
|
||||
registryAssembly.module
|
||||
inputs.sops-nix.nixosModules.sops
|
||||
@@ -366,5 +358,5 @@ let
|
||||
};
|
||||
in
|
||||
{
|
||||
inherit deriveMac guest;
|
||||
inherit mkGuest;
|
||||
}
|
||||
46
flake/host.nix
Normal file
46
flake/host.nix
Normal file
@@ -0,0 +1,46 @@
|
||||
{
|
||||
inputs,
|
||||
lib,
|
||||
self,
|
||||
specialArgs,
|
||||
repositoryModules,
|
||||
guestFiles,
|
||||
registryAssembly,
|
||||
}:
|
||||
let
|
||||
mkHost =
|
||||
{
|
||||
hostName,
|
||||
system ? "x86_64-linux",
|
||||
}:
|
||||
inputs.nixpkgs.lib.nixosSystem {
|
||||
inherit system specialArgs;
|
||||
modules =
|
||||
[
|
||||
repositoryModules
|
||||
]
|
||||
++ guestFiles
|
||||
++ [
|
||||
inputs.chaotic.nixosModules.default
|
||||
inputs.disko.nixosModules.disko
|
||||
inputs.sops-nix.nixosModules.sops
|
||||
inputs.stylix.nixosModules.stylix
|
||||
registryAssembly.module
|
||||
(self + "/hosts/${hostName}")
|
||||
{
|
||||
networking.hostName = hostName;
|
||||
modules.host.enable = true;
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
mkHosts =
|
||||
hostsDir:
|
||||
let
|
||||
hostNames = lib.attrNames (lib.filterAttrs (_name: type: type == "directory") (builtins.readDir hostsDir));
|
||||
in
|
||||
lib.genAttrs hostNames (hostName: mkHost { inherit hostName; });
|
||||
in
|
||||
{
|
||||
inherit mkHosts;
|
||||
}
|
||||
5
flake/module.nix
Normal file
5
flake/module.nix
Normal file
@@ -0,0 +1,5 @@
|
||||
{ util }:
|
||||
{ root }:
|
||||
{
|
||||
imports = util.collectNixFiles root;
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
dotfiles,
|
||||
flake,
|
||||
...
|
||||
}:
|
||||
let
|
||||
@@ -10,7 +10,7 @@ let
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
(dotfiles.guest {
|
||||
(flake.mkGuest {
|
||||
name = "actualbudget";
|
||||
interior = {
|
||||
modules.services.actualbudget = {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
dotfiles,
|
||||
flake,
|
||||
...
|
||||
}:
|
||||
let
|
||||
@@ -35,7 +35,7 @@ let
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
(dotfiles.guest {
|
||||
(flake.mkGuest {
|
||||
name = "copyparty";
|
||||
interior = {
|
||||
modules.services.copyparty = {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
args@{ dotfiles, ... }:
|
||||
args@{ flake, ... }:
|
||||
# A sample guest whose interior runs an OCI container on Podman.
|
||||
# The image is pulled at runtime, so the guest builds with no build-time fetch.
|
||||
dotfiles.guest {
|
||||
flake.mkGuest {
|
||||
name = "nesting-sample";
|
||||
interior = {
|
||||
virtualisation.oci-containers.containers.hello = {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
dotfiles,
|
||||
flake,
|
||||
...
|
||||
}:
|
||||
let
|
||||
@@ -9,7 +9,7 @@ let
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
(dotfiles.guest {
|
||||
(flake.mkGuest {
|
||||
name = "reverse-proxy";
|
||||
interior = {
|
||||
modules.services.reverse-proxy.enable = true;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
args@{ dotfiles, ... }:
|
||||
args@{ flake, ... }:
|
||||
# The tracer-bullet guest: the thinnest complete path from discovery to a
|
||||
# running nested container. Its interior is just the guest-base — the baseline
|
||||
# toolset and SSH access — so it proves the concept without carrying a service.
|
||||
dotfiles.guest { name = "sample"; } args
|
||||
flake.mkGuest { name = "sample"; } args
|
||||
|
||||
9
lib/default.nix
Normal file
9
lib/default.nix
Normal file
@@ -0,0 +1,9 @@
|
||||
{ lib }:
|
||||
let
|
||||
files = import ./files.nix { inherit lib; };
|
||||
network = import ./network.nix { inherit lib; };
|
||||
in
|
||||
{
|
||||
inherit (files) collectNixFiles;
|
||||
inherit (network) bridgeName deriveMac;
|
||||
}
|
||||
22
lib/files.nix
Normal file
22
lib/files.nix
Normal file
@@ -0,0 +1,22 @@
|
||||
{ lib }:
|
||||
let
|
||||
collectNixFiles =
|
||||
dir:
|
||||
lib.flatten (
|
||||
lib.mapAttrsToList (
|
||||
name: type:
|
||||
let
|
||||
path = dir + "/${name}";
|
||||
in
|
||||
if type == "directory" then
|
||||
collectNixFiles path
|
||||
else if type == "regular" && lib.hasSuffix ".nix" name then
|
||||
[ path ]
|
||||
else
|
||||
[ ]
|
||||
) (builtins.readDir dir)
|
||||
);
|
||||
in
|
||||
{
|
||||
inherit collectNixFiles;
|
||||
}
|
||||
12
lib/network.nix
Normal file
12
lib/network.nix
Normal file
@@ -0,0 +1,12 @@
|
||||
{ lib }:
|
||||
{
|
||||
bridgeName = id: "br-vlan${toString id}";
|
||||
|
||||
deriveMac =
|
||||
name:
|
||||
let
|
||||
hash = builtins.hashString "sha256" name;
|
||||
octet = i: builtins.substring (i * 2) 2 hash;
|
||||
in
|
||||
lib.concatStringsSep ":" ([ "02" ] ++ map octet [ 0 1 2 3 4 ]);
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
dotfiles,
|
||||
flake,
|
||||
pkgs,
|
||||
inputs,
|
||||
...
|
||||
@@ -64,7 +64,7 @@ in
|
||||
useGlobalPkgs = true;
|
||||
useUserPackages = true;
|
||||
extraSpecialArgs = {
|
||||
inherit dotfiles inputs;
|
||||
inherit flake inputs;
|
||||
};
|
||||
users.${user.name} = {
|
||||
home.username = user.name;
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
dotfiles,
|
||||
flake,
|
||||
...
|
||||
}:
|
||||
# The host networking foundation: per-VLAN bridges over a tagged trunk.
|
||||
let
|
||||
cfg = config.modules.network.vlans;
|
||||
|
||||
inherit (dotfiles.lib) bridgeName;
|
||||
inherit (flake.util) bridgeName;
|
||||
|
||||
vlanName = id: "${cfg.trunk}.${toString id}";
|
||||
in
|
||||
|
||||
Reference in New Issue
Block a user