Still a work in progress.

This commit is contained in:
Yaro Kasear 2025-11-29 12:55:11 -06:00
parent 500eb9e859
commit 62899898fe
5 changed files with 42 additions and 75 deletions

8
flake.lock generated
View file

@ -233,16 +233,16 @@
},
"nixpkgs_4": {
"locked": {
"lastModified": 1735563628,
"narHash": "sha256-OnSAY7XDSx7CtDoqNh8jwVwh4xNL/2HaJxGjryLWzX8=",
"lastModified": 1764316264,
"narHash": "sha256-82L+EJU+40+FIdeG4gmUlOF1jeSwlf2AwMarrpdHF6o=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b134951a4c9f3c995fd7be05f3243f8ecd65d798",
"rev": "9a7b80b6f82a71ea04270d7ba11b48855681c4b0",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-24.05",
"ref": "nixos-25.05",
"repo": "nixpkgs",
"type": "github"
}

View file

@ -2,7 +2,7 @@
description = "Metanix static flake: meta.nix addressing, deploy-rs, disko, nixos-anywhere";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.05";
nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.05";
deploy-rs.url = "github:serokell/deploy-rs";
disko.url = "github:nix-community/disko";
nixos-anywhere.url = "github:numtide/nixos-anywhere";

View file

@ -47,7 +47,6 @@
deimos = {
role = "server";
hw-address = "10:98:36:a0:2c:b2";
interface = "eno2";
aliases = [
"kasear.net"
"cloud.kasear.net"
@ -115,6 +114,7 @@
phobos = {
role = "server";
hw-address = "10:98:36:a9:4a:26";
interface = "eno2";
aliases = [
"pbx.kasear.net"
"private.kasear.net"

View file

@ -1,45 +1,34 @@
{ lib, config, ... }:
let
inherit (lib) mkOption mkIf types attrValues filterAttrs head;
inherit (lib) mkOption mkIf types;
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;
hosts = (metanix.network or { }).hosts or { };
host = 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);
subnets = (metanix.network or { }).subnets or { };
subnet =
if host != null && host ? subnetKey
then subnets.${host.subnetKey} or null
else null;
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";
if m == null then 32 else builtins.fromJSON (builtins.head m);
prefixLen =
if hostSubnet == null then 32 else cidrPrefix hostSubnet.cidr;
if subnet == null then 32 else cidrPrefix subnet.cidr;
unitName =
if host == null then "metanix"
else "10-${host.location}-${host.subnetType}-${host.interface}";
in
{
options.metanix.thisHost = mkOption {
@ -54,24 +43,16 @@ in
config = mkIf (host != null && host ? interface) {
systemd.network.enable = true;
systemd.network.networks."10-metanix-${host.interface}" = {
matchConfig = {
Name = host.interface;
};
systemd.network.networks.${unitName} = {
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") {
linkConfig = mkIf (host ? "hw-address") {
MACAddress = host."hw-address";
};
# TODO later: gateway & DNS resolution from metanix.network / policy
# gateway = "...";
# dns = [ ... ];
};
};
}

View file

@ -2,49 +2,35 @@
let
system = "x86_64-linux";
# Bring in nixpkgs and lib
# Grab nixpkgs lib for convenience
pkgs = import <nixpkgs> { inherit system; };
lib = pkgs.lib;
# Your world + addressing lib
# Metanix world + addressing
meta = import ../meta.nix;
addressing = import ../lib/addressing { inherit lib; };
# NixOS module system library
nixosLib = import <nixpkgs/nixos/lib> {
inherit lib;
network = addressing.mkNetworkFromSpec meta;
# Fake NixOS config that your module expects
config = {
networking.hostName = "phobos";
metanix = {
thisHost = "phobos";
inherit network;
};
};
# All standard NixOS modules (as a list)
baseModules = import <nixpkgs/nixos/modules/module-list.nix>;
# Evaluate modules as if this were a NixOS system
evalResult = nixosLib.evalModules {
modules =
baseModules
++ [
# Metanix core wiring (meta + addressing)
../modules/metanix/core.nix
# systemd-networkd integration
../modules/metanix/networkd.nix
# Local stub: "this machine is phobos"
{
networking.hostName = "phobos";
metanix.thisHost = "phobos";
}
];
# Args passed to all modules: { lib, pkgs, system, meta, addressing, modulesPath, ... }
specialArgs = {
inherit lib pkgs system meta addressing;
modulesPath = builtins.toString <nixpkgs/nixos/modules>;
};
# Call the networkd module directly as a function
networkdModule = import ../modules/metanix/networkd.nix {
inherit lib config;
};
in
{
systemdNetwork = evalResult.config.systemd.network;
metanixHost = evalResult.config.metanix.network.hosts.phobos;
metanixSubnet = evalResult.config.metanix.network.subnets."home-main";
# Raw Metanix view
metanixHost = network.hosts.phobos;
metanixSubnet = network.subnets."home-main";
# What the module actually emits
systemdNetwork = networkdModule.config.systemd.network;
}