{ config, lib, ... }: let inherit (config.networking) hostName; # linux iface name max length = 15 shortenNetName = name: if builtins.match "priv(.*)" name != null then "p" + builtins.substring 4 9 name else if name == "coloradio" then "cr" else if name == "coloradio-gw" then "cr-gw" else name; checkIfname = ifname: let len = builtins.stringLength ifname; in if len > 15 then throw "Interface name ${ifname} is ${toString (len - 15)} chars too long." else ifname; # `lxc.net.*` formatter for lxc.container.conf files netConfig = ctName: interfaces: let config = map (netName: let ifData = interfaces.${netName}; in { type = ifData.type; name = checkIfname netName; flags = "up"; hwaddr = if ifData ? hwaddr && ifData.hwaddr != null then ifData.hwaddr else "0A:14:48:xx:xx:xx"; } // (lib.optionalAttrs (ifData.type == "veth") { veth.pair = checkIfname "${shortenNetName ctName}-${shortenNetName netName}"; veth.mode = checkIfname "bridge"; link = checkIfname netName; }) // (lib.optionalAttrs (ifData.type == "phys") { link = checkIfname "ext-${netName}"; }) ) (builtins.attrNames interfaces); attrNamesOrdered = attrs: if attrs ? type then [ "type" ] ++ lib.remove "type" (builtins.attrNames attrs) else builtins.attrNames attrs; serialize = name: x: if builtins.isString x then "${name} = ${x}\n" else if builtins.isAttrs x then builtins.concatStringsSep "" ( map (n: serialize "${name}.${n}" x.${n}) (attrNamesOrdered x) ) else if builtins.isList x then let enumerate = xs: n: if xs == [] then [] else [ { e = builtins.head xs; i = n; } ] ++ enumerate (builtins.tail xs) (n + 1); in builtins.concatStringsSep "" ( map ({ e, i }: serialize "${name}.${toString i}" e) (enumerate x 0) ) else throw "Invalid data in lxc net config for ${name}: ${lib.generators.toPretty {} x}"; in serialize "lxc.net" config; in { system.build.lxcConfig = builtins.toFile "${hostName}.conf" '' # For lxcfs and sane defaults lxc.include = /etc/lxc/common.conf lxc.uts.name = ${hostName} # Handled by lxc@.service lxc.start.auto = 0 lxc.rootfs.path = /var/lib/lxc/${hostName}/rootfs lxc.init.cmd = "/init" lxc.mount.entry = /nix/store nix/store none bind,ro 0 0 lxc.mount.entry = none tmp tmpfs defaults 0 0 lxc.mount.auto = proc:mixed sys:ro cgroup:mixed lxc.autodev = 1 lxc.tty.max = 0 lxc.pty.max = 8 lxc.cap.drop = sys_module sys_time sys_nice sys_pacct sys_rawio security.privileged = false lxc.apparmor.profile = lxc-container-default-with-mounting lxc.cgroup.memory.limit_in_bytes = 1G lxc.cgroup.memory.kmem.tcp.limit_in_bytes = 128M # tuntap lxc.cgroup.devices.allow = c 10:200 rw lxc.cgroup2.devices.allow = c 10:200 rw # ppp lxc.cgroup.devices.allow = c 108:0 rwm lxc.cgroup2.devices.allow = c 108:0 rwm ${netConfig hostName config.site.hosts.${hostName}.physicalInterfaces} ''; }