Some work to do with systemd-networkd. Still nowhere near enough to create an actual config.

This commit is contained in:
Yaro Kasear 2025-11-29 11:21:10 -06:00
parent b46c51e720
commit 4a4b369136
5 changed files with 90 additions and 2 deletions

View file

@ -45,7 +45,8 @@
modules =
(sysCfg.modules or [ ]) ++ [
./modules/metanix-core.nix
./modules/metanix/core.nix
./modules/metanix/networkd.nix
# Disko wiring if present
(if sysCfg ? diskoConfig then

View file

@ -331,6 +331,11 @@ let
{
ip-address = ip;
inherit hostname fqdn;
# New context fields:
location = locationName;
subnetType = typeName;
subnetKey = "${locationName}-${typeName}";
}
// optionalAttrs (hostCfg ? hw-address) {
inherit (hostCfg) hw-address;
@ -341,7 +346,11 @@ let
// optionalAttrs (hostCfg ? aliases) {
inherit (hostCfg) aliases;
}
))
// optionalAttrs (hostCfg ? interface) {
inherit (hostCfg) interface;
}
)
)
hostNames))
subnets)
locations;

View file

@ -47,6 +47,7 @@
deimos = {
role = "server";
hw-address = "10:98:36:a0:2c:b2";
interface = "eno2";
aliases = [
"kasear.net"
"cloud.kasear.net"

View file

@ -0,0 +1,77 @@
{ lib, config, ... }:
let
inherit (lib) mkOption mkIf types attrValues filterAttrs head;
metanix = config.metanix or { };
# For now, tell Metanix "which host am I?"
thisHostName = config.metanix.thisHost or config.networking.hostName;
host = metanix.network.hosts.${thisHostName} or null;
# Find the subnet this host belongs to by matching IP prefix
# VERY SIMPLE: relies on your rigid addressing scheme
findSubnetForHost =
ip:
let
subnets = metanix.network.subnets or { };
matches =
filterAttrs
(_: s: lib.strings.hasPrefix (lib.strings.concatStringsSep "." (lib.take 3 (lib.splitString "." s.cidr)))
(lib.strings.concatStringsSep "." (lib.take 3 (lib.splitString "." ip))))
subnets;
in
if matches == { }
then null
else head (attrValues matches);
cidrPrefix =
cidr:
let
# match "10.1.32.0/19" → [ "19" ]
m = builtins.match ".*/([0-9]+)" cidr;
in
if m == null then 32 else builtins.fromJSON (head m);
hostSubnet =
if host == null then null else findSubnetForHost host."ip-address";
prefixLen =
if hostSubnet == null then 32 else cidrPrefix hostSubnet.cidr;
in
{
options.metanix.thisHost = mkOption {
type = types.nullOr types.str;
default = null;
description = ''
Logical Metanix host name for this machine.
Used to look up IP/interface in metanix.network.hosts.
'';
};
config = mkIf (host != null && host ? interface) {
systemd.network.enable = true;
systemd.network.networks."10-metanix-${host.interface}" = {
matchConfig = {
Name = host.interface;
};
# Static address from Metanix
address = [
"${host."ip-address"}/${toString prefixLen}"
];
# Optional: match MAC if present
linkConfig = lib.mkIf (host ? "hw-address") {
MACAddress = host."hw-address";
};
# TODO later: gateway & DNS resolution from metanix.network / policy
# gateway = "...";
# dns = [ ... ];
};
};
}