diff --git a/.forgejo/workflows/update_lock.yaml b/.forgejo/workflows/update_lock.yaml index c49c5b4..4f16c1d 100644 --- a/.forgejo/workflows/update_lock.yaml +++ b/.forgejo/workflows/update_lock.yaml @@ -1,8 +1,13 @@ name: update-flake-lock on: - workflow_dispatch: # allows manual triggering - schedule: - - cron: '0 0 * * *' # daily at midnight + # workflow_dispatch: # allows manual triggering + # schedule: + # - cron: '0 0 * * *' # daily at midnight + push: + branches: + - main + paths: + - ".forgejo/workflows/update_lock.yaml" jobs: lockfile: diff --git a/nixos/hosts/telperion/default.nix b/nixos/hosts/telperion/default.nix index 5fbaa22..7cad4b4 100644 --- a/nixos/hosts/telperion/default.nix +++ b/nixos/hosts/telperion/default.nix @@ -94,6 +94,18 @@ config = import ./config/haproxy.nix { inherit config; }; tcpPorts = [ 6443 6444 50000 ]; }; + + matchbox = { + enable = true; + dataPath = "/var/lib/matchbox"; + assetPath = "/nas/matchbox/assets"; + }; + + dnsmasq = { + enable = true; + tftpRoot = "/srv/tftp"; + bootAsset = "http://10.1.1.57:8086/boot.ipxe"; + }; }; }; } diff --git a/nixos/modules/nixos/services/default.nix b/nixos/modules/nixos/services/default.nix index 3f7f915..2557439 100644 --- a/nixos/modules/nixos/services/default.nix +++ b/nixos/modules/nixos/services/default.nix @@ -2,9 +2,11 @@ imports = [ ./bind ./cockpit + ./dnsmasq ./forgejo ./haproxy ./libvirt-qemu + ./matchbox ./nginx ./onepassword-connect ./podman diff --git a/nixos/modules/nixos/services/dnsmasq/default.nix b/nixos/modules/nixos/services/dnsmasq/default.nix new file mode 100644 index 0000000..735d3c6 --- /dev/null +++ b/nixos/modules/nixos/services/dnsmasq/default.nix @@ -0,0 +1,56 @@ +{ lib, config, pkgs, ... }: +with lib; +let + cfg = config.mySystem.services.dnsmasq; +in +{ + options.mySystem.services.dnsmasq = { + enable = mkEnableOption "dnsmasq"; + package = mkPackageOption pkgs "dnsmasq" { }; + bootAsset = mkOption { + type = types.str; + example = "http://10.1.1.57:8086/boot.ipxe"; + }; + tftpRoot = mkOption { + type = types.str; + example = "/srv/tftp"; + }; + }; + + config = mkIf cfg.enable { + networking.firewall = { + # dhcp ports + allowedUDPPorts = [ 67 68 ]; # server/client + }; + + # Proxy DHCP for PXE booting. This leaves DHCP address allocation alone and dhcp clients + # should merge all responses from their DHCPDISCOVER request. + # https://matchbox.psdn.io/network-setup/#proxy-dhcp + services.dnsmasq = { + enable = true; + package = cfg.package; + # we just want to proxy DHCP, not serve DNS + resolveLocalQueries = false; + settings = { + # Disables only the DNS port. + port = 0; + dhcp-range = [ "10.1.1.1,proxy,255.255.255.0" ]; + # serves TFTP from dnsmasq + enable-tftp = true; + tftp-root = cfg.tftpRoot; + # if request comes from iPXE user class, set tag "ipxe" + dhcp-userclass = "set:ipxe,iPXE"; + # if request comes from older PXE ROM, chainload to iPXE (via TFTP) + # ALSO + # point ipxe tagged requests to the matchbox iPXE boot script (via HTTP) + # pxe-service="tag:ipxe,0,matchbox,http://10.1.1.57:8080/boot.ipxe"; + pxe-service = [ + "tag:#ipxe,x86PC,\"PXE chainload to iPXE\",undionly.kpxe" + "tag:ipxe,0,matchbox,${cfg.bootAsset}" + ]; + log-queries = true; + log-dhcp = true; + }; + }; + }; +} diff --git a/nixos/modules/nixos/services/matchbox/default.nix b/nixos/modules/nixos/services/matchbox/default.nix new file mode 100644 index 0000000..2184649 --- /dev/null +++ b/nixos/modules/nixos/services/matchbox/default.nix @@ -0,0 +1,51 @@ +{ lib, config, pkgs, ... }: +with lib; +let + cfg = config.mySystem.services.matchbox; +in +{ + options.mySystem.services.matchbox = { + enable = mkEnableOption "matchbox"; + package = mkPackageOption pkgs "matchbox" { }; + dataPath = mkOption { + type = types.str; + example = "/var/lib/matchbox"; + }; + assetPath = mkOption { + type = types.str; + example = "/nas/matchbox/assets"; + }; + }; + + config = mkIf cfg.enable { + environment.systemPackages = [ + cfg.package + ]; + + networking.firewall = { + # HTTP communication + allowedTCPPorts = [ 8086 ]; + }; + + # Matchbox Server for PXE booting via device profiles + users.groups.matchbox = { }; + users.users = { + matchbox = { + home = cfg.dataPath; + group = "matchbox"; + isSystemUser = true; + }; + }; + + systemd.services.matchbox = { + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + serviceConfig = { + ExecStart = "${pkgs.matchbox-server}/bin/matchbox -address=0.0.0.0:8086 -data-path=${cfg.dataPath} -assets-path=${cfg.assetPath} -log-level=debug"; + Restart = "on-failure"; + User = "matchbox"; + Group = "matchbox"; + }; + }; + }; +}