{ config , lib , pkgs , ... }: let cfg = config.services.woodpecker-agent; in { meta.maintainers = [ lib.maintainers.janik ]; options = { services.woodpecker-agent = { enable = lib.mkEnableOption (lib.mdDoc "the Woodpecker-Agent, Agents execute tasks generated by a Server, every install will need one server and at least one agent"); package = lib.mkPackageOptionMD pkgs "woodpecker-agent" { }; environment = lib.mkOption { default = { }; type = lib.types.attrsOf lib.types.str; example = lib.literalExpression '' { WOODPECKER_SERVER = "localhost:9000"; WOODPECKER_BACKEND = "docker"; DOCKER_HOST = "unix:///run/podman/podman.sock"; } ''; description = lib.mdDoc "woodpecker-agent config envrionment variables, for other options read the [documentation](https://woodpecker-ci.org/docs/administration/agent-config)"; }; extraGroups = lib.mkOption { default = null; type = lib.types.nullOr (lib.types.listOf lib.types.str); example = [ "podman" ]; description = lib.mdDoc '' Additional groups for the systemd service. ''; }; environmentFile = lib.mkOption { type = lib.types.nullOr lib.types.path; default = null; example = "/root/woodpecker-agent.env"; description = lib.mdDoc '' File to load environment variables from. This is helpful for specifying secrets. Example content of environmentFile: ``` WOODPECKER_AGENT_SECRET=your-shared-secret-goes-here ``` ''; }; }; }; config = lib.mkIf cfg.enable { systemd.services = { woodpecker-agent = { description = "Woodpecker-Agent Service"; wantedBy = [ "multi-user.target" ]; after = [ "network-online.target" ]; wants = [ "network-online.target" ]; serviceConfig = { DynamicUser = true; SupplementaryGroups = lib.optionals (cfg.extraGroups != null) cfg.extraGroups; EnvironmentFile = lib.optional (cfg.environmentFile != null) cfg.environmentFile; ExecStart = "${cfg.package}/bin/woodpecker-agent"; Restart = "on-failure"; RestartSec = 15; CapabilityBoundingSet = ""; # Security NoNewPrivileges = true; # Sandboxing ProtectSystem = "strict"; PrivateTmp = true; PrivateDevices = true; PrivateUsers = true; ProtectHostname = true; ProtectClock = true; ProtectKernelTunables = true; ProtectKernelModules = true; ProtectKernelLogs = true; ProtectControlGroups = true; RestrictAddressFamilies = [ "AF_UNIX AF_INET AF_INET6" ]; LockPersonality = true; MemoryDenyWriteExecute = true; RestrictRealtime = true; RestrictSUIDSGID = true; PrivateMounts = true; # System Call Filtering SystemCallArchitectures = "native"; SystemCallFilter = "~@clock @privileged @cpu-emulation @debug @keyring @module @mount @obsolete @raw-io @reboot @setuid @swap"; }; inherit (cfg) environment; }; }; }; }