From c0d233174c5fc3010e4b55363fd6e1c78f6248fa Mon Sep 17 00:00:00 2001 From: autonomic-bot Date: Mon, 7 Sep 2026 21:17:50 +0000 Subject: [PATCH] =?UTF-8?q?acme-dns.nix:=20one=20`systemd`=20attrset=20(st?= =?UTF-8?q?atix=20W20)=20=E2=80=94=20lint=20gate=20green?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit statix flagged the repeated `systemd.` keys (tmpfiles marker, acme-dns daemon, traefik handoff oneshot); they are now one nested attrset. Purely structural: `#cc-ci` still evaluates. With #33 this makes the push self-test's lint stage pass again. Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_01FqkQq3CDmFWcQ7u1LzoyRz --- nix/modules/acme-dns.nix | 135 ++++++++++++++++++++------------------- 1 file changed, 71 insertions(+), 64 deletions(-) diff --git a/nix/modules/acme-dns.nix b/nix/modules/acme-dns.nix index 71c1a25..54c8b66 100644 --- a/nix/modules/acme-dns.nix +++ b/nix/modules/acme-dns.nix @@ -60,79 +60,86 @@ in environment.etc."acme-dns/lego.env".source = legoEnvironment; - # The staging order has completed successfully. This marker permits the - # production ACME post-run hook to hand a renewed certificate to Traefik. - systemd.tmpfiles.rules = [ - "f /var/lib/ci-certs/acme-production-enabled 0600 root root -" - ]; networking.firewall = { allowedTCPPorts = [ 53 ]; allowedUDPPorts = [ 53 ]; }; - systemd.services.acme-dns = { - description = "Restricted authoritative DNS for cc-ci ACME DNS-01"; - wantedBy = [ "multi-user.target" ]; - after = [ "network-online.target" ]; - wants = [ "network-online.target" ]; - serviceConfig = { - User = "acme-dns"; - Group = "acme-dns"; - StateDirectory = "acme-dns"; - StateDirectoryMode = "0700"; - WorkingDirectory = "/var/lib/acme-dns"; - ExecStart = "${pkgs.acme-dns}/bin/acme-dns -c ${acmeDnsConfig}"; - Restart = "on-failure"; - RestartSec = "5s"; - AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ]; - CapabilityBoundingSet = [ "CAP_NET_BIND_SERVICE" ]; - NoNewPrivileges = true; - PrivateTmp = true; - PrivateDevices = true; - ProtectHome = true; - ProtectSystem = "strict"; - ReadWritePaths = [ "/var/lib/acme-dns" ]; - RestrictAddressFamilies = [ "AF_INET" "AF_UNIX" ]; + + + # One `systemd` attrset (statix W20): the tmpfiles marker, the acme-dns daemon and the + # traefik handoff oneshot. + systemd = { + # The staging order has completed successfully. This marker permits the + # production ACME post-run hook to hand a renewed certificate to Traefik. + tmpfiles.rules = [ + "f /var/lib/ci-certs/acme-production-enabled 0600 root root -" + ]; + + services.acme-dns = { + description = "Restricted authoritative DNS for cc-ci ACME DNS-01"; + wantedBy = [ "multi-user.target" ]; + after = [ "network-online.target" ]; + wants = [ "network-online.target" ]; + serviceConfig = { + User = "acme-dns"; + Group = "acme-dns"; + StateDirectory = "acme-dns"; + StateDirectoryMode = "0700"; + WorkingDirectory = "/var/lib/acme-dns"; + ExecStart = "${pkgs.acme-dns}/bin/acme-dns -c ${acmeDnsConfig}"; + Restart = "on-failure"; + RestartSec = "5s"; + AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ]; + CapabilityBoundingSet = [ "CAP_NET_BIND_SERVICE" ]; + NoNewPrivileges = true; + PrivateTmp = true; + PrivateDevices = true; + ProtectHome = true; + ProtectSystem = "strict"; + ReadWritePaths = [ "/var/lib/acme-dns" ]; + RestrictAddressFamilies = [ "AF_INET" "AF_UNIX" ]; + }; }; - }; - # Traefik consumes its wildcard as immutable Swarm secrets, so a renewed - # host certificate must be copied and reconciled rather than merely reloaded. - # This service is started only by the production-mode ACME postRun hook. - systemd.services.cc-ci-acme-traefik-handoff = { - description = "Install renewed cc-ci wildcard into Traefik Swarm secrets"; - after = [ "docker.service" "deploy-proxy.service" ]; - requires = [ "docker.service" ]; - path = [ pkgs.coreutils pkgs.docker pkgs.systemd pkgs.gnugrep ]; - serviceConfig = { - Type = "oneshot"; - UMask = "0077"; + # Traefik consumes its wildcard as immutable Swarm secrets, so a renewed + # host certificate must be copied and reconciled rather than merely reloaded. + # This service is started only by the production-mode ACME postRun hook. + services.cc-ci-acme-traefik-handoff = { + description = "Install renewed cc-ci wildcard into Traefik Swarm secrets"; + after = [ "docker.service" "deploy-proxy.service" ]; + requires = [ "docker.service" ]; + path = [ pkgs.coreutils pkgs.docker pkgs.systemd pkgs.gnugrep ]; + serviceConfig = { + Type = "oneshot"; + UMask = "0077"; + }; + script = '' + src=/var/lib/acme/ci.commoninternet.net + dst=/var/lib/ci-certs/live + test -s "$src/fullchain.pem" + test -s "$src/key.pem" + install -d -m 0700 "$dst" + install -m 0444 "$src/fullchain.pem" "$dst/fullchain.pem.new" + install -m 0400 "$src/key.pem" "$dst/privkey.pem.new" + mv -f "$dst/fullchain.pem.new" "$dst/fullchain.pem" + mv -f "$dst/privkey.pem.new" "$dst/privkey.pem" + + # deploy-proxy performs the health-gated Swarm rollout. Its reconciler + # derives a fresh version from the public certificate chain and inserts + # the matching ssl_cert/ssl_key secrets before deploying Traefik. + systemctl restart deploy-proxy.service + + # A successful rollout no longer references old wildcard versions. Best + # effort removal retains any secret Docker still reports as in use. + keep="v$(sha256sum "$dst/fullchain.pem" | cut -c1-16)" + docker secret ls --format '{{.Name}}' | \ + grep -E '^traefik_ci_commoninternet_net_ssl_(cert|key)_v' | \ + grep -v -E "_(ssl_cert|ssl_key)_$keep\$" | \ + while IFS= read -r stale; do docker secret rm "$stale" || true; done + ''; }; - script = '' - src=/var/lib/acme/ci.commoninternet.net - dst=/var/lib/ci-certs/live - test -s "$src/fullchain.pem" - test -s "$src/key.pem" - install -d -m 0700 "$dst" - install -m 0444 "$src/fullchain.pem" "$dst/fullchain.pem.new" - install -m 0400 "$src/key.pem" "$dst/privkey.pem.new" - mv -f "$dst/fullchain.pem.new" "$dst/fullchain.pem" - mv -f "$dst/privkey.pem.new" "$dst/privkey.pem" - - # deploy-proxy performs the health-gated Swarm rollout. Its reconciler - # derives a fresh version from the public certificate chain and inserts - # the matching ssl_cert/ssl_key secrets before deploying Traefik. - systemctl restart deploy-proxy.service - - # A successful rollout no longer references old wildcard versions. Best - # effort removal retains any secret Docker still reports as in use. - keep="v$(sha256sum "$dst/fullchain.pem" | cut -c1-16)" - docker secret ls --format '{{.Name}}' | \ - grep -E '^traefik_ci_commoninternet_net_ssl_(cert|key)_v' | \ - grep -v -E "_(ssl_cert|ssl_key)_$keep\$" | \ - while IFS= read -r stale; do docker secret rm "$stale" || true; done - ''; }; security.acme = { -- 2.54.0