{ config, lib, pkgs, ... }: let cfg = config.services.node-agent; pidDir = "${cfg.stateDir}/pids"; in { options.services.node-agent = { enable = lib.mkEnableOption "PhotonCloud node-agent service"; chainfireEndpoint = lib.mkOption { type = lib.types.str; default = "http://127.0.0.1:7000"; description = "ChainFire endpoint consumed by node-agent"; }; clusterNamespace = lib.mkOption { type = lib.types.str; default = "photoncloud"; description = "Cluster namespace prefix"; }; clusterId = lib.mkOption { type = lib.types.str; description = "Cluster ID reconciled by node-agent"; }; nodeId = lib.mkOption { type = lib.types.str; default = config.networking.hostName; description = "Node ID represented by this agent"; }; intervalSecs = lib.mkOption { type = lib.types.int; default = 15; description = "Polling interval in seconds"; }; apply = lib.mkOption { type = lib.types.bool; default = true; description = "Apply desired runtime state on the node"; }; allowLocalInstanceUpsert = lib.mkOption { type = lib.types.bool; default = false; description = "Allow /etc/photoncloud/instances.json upserts into ChainFire"; }; enableContainers = lib.mkOption { type = lib.types.bool; default = true; description = "Install and enable Podman for container-based workloads"; }; extraPackages = lib.mkOption { type = lib.types.listOf lib.types.package; default = [ ]; description = "Additional packages made available to managed workloads"; }; package = lib.mkOption { type = lib.types.package; default = pkgs.node-agent or (throw "node-agent package not found"); description = "Package to use for node-agent"; }; stateDir = lib.mkOption { type = lib.types.str; default = "/var/lib/node-agent"; description = "State directory for node-agent process metadata"; }; }; config = lib.mkIf cfg.enable { virtualisation.podman.enable = cfg.enableContainers; environment.systemPackages = lib.mkAfter (lib.optionals cfg.enableContainers [ pkgs.podman ] ++ cfg.extraPackages); systemd.tmpfiles.rules = [ "d ${cfg.stateDir} 0750 root root -" "d ${pidDir} 0750 root root -" ]; systemd.services.node-agent = { description = "PhotonCloud Node Agent"; wantedBy = [ "multi-user.target" ]; after = [ "network-online.target" ]; wants = [ "network-online.target" ]; path = [ config.system.path ] ++ lib.optionals cfg.enableContainers [ pkgs.podman ] ++ cfg.extraPackages; serviceConfig = { Type = "simple"; Restart = "on-failure"; RestartSec = "5s"; WorkingDirectory = cfg.stateDir; ExecStart = '' ${cfg.package}/bin/node-agent \ --chainfire-endpoint ${lib.escapeShellArg cfg.chainfireEndpoint} \ --cluster-namespace ${lib.escapeShellArg cfg.clusterNamespace} \ --cluster-id ${lib.escapeShellArg cfg.clusterId} \ --node-id ${lib.escapeShellArg cfg.nodeId} \ --interval-secs ${toString cfg.intervalSecs} \ --pid-dir ${lib.escapeShellArg pidDir} \ ${lib.optionalString cfg.apply "--apply"} \ ${lib.optionalString cfg.allowLocalInstanceUpsert "--allow-local-instance-upsert"} ''; }; }; }; }