Merge pull request #221877 from ambroisie/woodpecker-agents

nixos/woodpecker: refactor to multi-agents setup

authored by

pennae and committed by
GitHub
dce79b3c 9d7912ff

+147 -102
+1 -1
nixos/doc/manual/release-notes/rl-2305.section.md
··· 79 80 - [nimdow](https://github.com/avahe-kellenberger/nimdow), a window manager written in Nim, inspired by dwm. 81 82 - - [woodpecker-agent](https://woodpecker-ci.org/), a simple CI engine with great extensibility. Available as [services.woodpecker-agent](#opt-services.woodpecker-agent.enable). 83 84 - [woodpecker-server](https://woodpecker-ci.org/), a simple CI engine with great extensibility. Available as [services.woodpecker-server](#opt-services.woodpecker-server.enable). 85
··· 79 80 - [nimdow](https://github.com/avahe-kellenberger/nimdow), a window manager written in Nim, inspired by dwm. 81 82 + - [woodpecker-agents](https://woodpecker-ci.org/), a simple CI engine with great extensibility. Available as [services.woodpecker-agents](#opt-services.woodpecker-agents.agents._name_.enable). 83 84 - [woodpecker-server](https://woodpecker-ci.org/), a simple CI engine with great extensibility. Available as [services.woodpecker-server](#opt-services.woodpecker-server.enable). 85
+1 -1
nixos/modules/module-list.nix
··· 376 ./services/continuous-integration/jenkins/default.nix 377 ./services/continuous-integration/jenkins/job-builder.nix 378 ./services/continuous-integration/jenkins/slave.nix 379 - ./services/continuous-integration/woodpecker/agent.nix 380 ./services/continuous-integration/woodpecker/server.nix 381 ./services/databases/aerospike.nix 382 ./services/databases/cassandra.nix
··· 376 ./services/continuous-integration/jenkins/default.nix 377 ./services/continuous-integration/jenkins/job-builder.nix 378 ./services/continuous-integration/jenkins/slave.nix 379 + ./services/continuous-integration/woodpecker/agents.nix 380 ./services/continuous-integration/woodpecker/server.nix 381 ./services/databases/aerospike.nix 382 ./services/databases/cassandra.nix
-99
nixos/modules/services/continuous-integration/woodpecker/agent.nix
··· 1 - { config 2 - , lib 3 - , pkgs 4 - , ... 5 - }: 6 - 7 - let 8 - cfg = config.services.woodpecker-agent; 9 - in 10 - { 11 - meta.maintainers = [ lib.maintainers.janik ]; 12 - 13 - options = { 14 - services.woodpecker-agent = { 15 - 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"); 16 - package = lib.mkPackageOptionMD pkgs "woodpecker-agent" { }; 17 - 18 - environment = lib.mkOption { 19 - default = { }; 20 - type = lib.types.attrsOf lib.types.str; 21 - example = lib.literalExpression '' 22 - { 23 - WOODPECKER_SERVER = "localhost:9000"; 24 - WOODPECKER_BACKEND = "docker"; 25 - DOCKER_HOST = "unix:///run/podman/podman.sock"; 26 - } 27 - ''; 28 - description = lib.mdDoc "woodpecker-agent config envrionment variables, for other options read the [documentation](https://woodpecker-ci.org/docs/administration/agent-config)"; 29 - }; 30 - 31 - extraGroups = lib.mkOption { 32 - default = null; 33 - type = lib.types.nullOr (lib.types.listOf lib.types.str); 34 - example = [ "podman" ]; 35 - description = lib.mdDoc '' 36 - Additional groups for the systemd service. 37 - ''; 38 - }; 39 - 40 - environmentFile = lib.mkOption { 41 - type = lib.types.nullOr lib.types.path; 42 - default = null; 43 - example = "/root/woodpecker-agent.env"; 44 - description = lib.mdDoc '' 45 - File to load environment variables 46 - from. This is helpful for specifying secrets. 47 - Example content of environmentFile: 48 - ``` 49 - WOODPECKER_AGENT_SECRET=your-shared-secret-goes-here 50 - ``` 51 - ''; 52 - }; 53 - }; 54 - }; 55 - 56 - config = lib.mkIf cfg.enable { 57 - systemd.services = { 58 - woodpecker-agent = { 59 - description = "Woodpecker-Agent Service"; 60 - wantedBy = [ "multi-user.target" ]; 61 - after = [ "network-online.target" ]; 62 - wants = [ "network-online.target" ]; 63 - serviceConfig = { 64 - DynamicUser = true; 65 - SupplementaryGroups = lib.optionals (cfg.extraGroups != null) cfg.extraGroups; 66 - EnvironmentFile = lib.optional (cfg.environmentFile != null) cfg.environmentFile; 67 - ExecStart = "${cfg.package}/bin/woodpecker-agent"; 68 - Restart = "on-failure"; 69 - RestartSec = 15; 70 - CapabilityBoundingSet = ""; 71 - # Security 72 - NoNewPrivileges = true; 73 - # Sandboxing 74 - ProtectSystem = "strict"; 75 - PrivateTmp = true; 76 - PrivateDevices = true; 77 - PrivateUsers = true; 78 - ProtectHostname = true; 79 - ProtectClock = true; 80 - ProtectKernelTunables = true; 81 - ProtectKernelModules = true; 82 - ProtectKernelLogs = true; 83 - ProtectControlGroups = true; 84 - RestrictAddressFamilies = [ "AF_UNIX AF_INET AF_INET6" ]; 85 - LockPersonality = true; 86 - MemoryDenyWriteExecute = true; 87 - RestrictRealtime = true; 88 - RestrictSUIDSGID = true; 89 - PrivateMounts = true; 90 - # System Call Filtering 91 - SystemCallArchitectures = "native"; 92 - SystemCallFilter = "~@clock @privileged @cpu-emulation @debug @keyring @module @mount @obsolete @raw-io @reboot @setuid @swap"; 93 - }; 94 - inherit (cfg) environment; 95 - }; 96 - }; 97 - }; 98 - } 99 -
···
+144
nixos/modules/services/continuous-integration/woodpecker/agents.nix
···
··· 1 + { config 2 + , lib 3 + , pkgs 4 + , ... 5 + }: 6 + 7 + let 8 + cfg = config.services.woodpecker-agents; 9 + 10 + agentModule = lib.types.submodule { 11 + options = { 12 + enable = lib.mkEnableOption (lib.mdDoc "this Woodpecker-Agent. Agents execute tasks generated by a Server, every install will need one server and at least one agent"); 13 + 14 + package = lib.mkPackageOptionMD pkgs "woodpecker-agent" { }; 15 + 16 + environment = lib.mkOption { 17 + default = { }; 18 + type = lib.types.attrsOf lib.types.str; 19 + example = lib.literalExpression '' 20 + { 21 + WOODPECKER_SERVER = "localhost:9000"; 22 + WOODPECKER_BACKEND = "docker"; 23 + DOCKER_HOST = "unix:///run/podman/podman.sock"; 24 + } 25 + ''; 26 + description = lib.mdDoc "woodpecker-agent config envrionment variables, for other options read the [documentation](https://woodpecker-ci.org/docs/administration/agent-config)"; 27 + }; 28 + 29 + extraGroups = lib.mkOption { 30 + type = lib.types.listOf lib.types.str; 31 + default = [ ]; 32 + example = [ "podman" ]; 33 + description = lib.mdDoc '' 34 + Additional groups for the systemd service. 35 + ''; 36 + }; 37 + 38 + environmentFile = lib.mkOption { 39 + type = lib.types.listOf lib.types.path; 40 + default = [ ]; 41 + example = [ "/var/secrets/woodpecker-agent.env" ]; 42 + description = lib.mdDoc '' 43 + File to load environment variables 44 + from. This is helpful for specifying secrets. 45 + Example content of environmentFile: 46 + ``` 47 + WOODPECKER_AGENT_SECRET=your-shared-secret-goes-here 48 + ``` 49 + ''; 50 + }; 51 + }; 52 + }; 53 + 54 + mkAgentService = name: agentCfg: { 55 + name = "woodpecker-agent-${name}"; 56 + value = { 57 + description = "Woodpecker-Agent Service - ${name}"; 58 + wantedBy = [ "multi-user.target" ]; 59 + after = [ "network-online.target" ]; 60 + wants = [ "network-online.target" ]; 61 + serviceConfig = { 62 + DynamicUser = true; 63 + SupplementaryGroups = agentCfg.extraGroups; 64 + EnvironmentFile = agentCfg.environmentFile; 65 + ExecStart = lib.getExe agentCfg.package; 66 + Restart = "on-failure"; 67 + RestartSec = 15; 68 + CapabilityBoundingSet = ""; 69 + NoNewPrivileges = true; 70 + ProtectSystem = "strict"; 71 + PrivateTmp = true; 72 + PrivateDevices = true; 73 + PrivateUsers = true; 74 + ProtectHostname = true; 75 + ProtectClock = true; 76 + ProtectKernelTunables = true; 77 + ProtectKernelModules = true; 78 + ProtectKernelLogs = true; 79 + ProtectControlGroups = true; 80 + RestrictAddressFamilies = [ "AF_UNIX AF_INET AF_INET6" ]; 81 + LockPersonality = true; 82 + MemoryDenyWriteExecute = true; 83 + RestrictRealtime = true; 84 + RestrictSUIDSGID = true; 85 + PrivateMounts = true; 86 + SystemCallArchitectures = "native"; 87 + SystemCallFilter = "~@clock @privileged @cpu-emulation @debug @keyring @module @mount @obsolete @raw-io @reboot @setuid @swap"; 88 + BindReadOnlyPaths = [ 89 + "-/etc/resolv.conf" 90 + "-/etc/nsswitch.conf" 91 + "-/etc/ssl/certs" 92 + "-/etc/static/ssl/certs" 93 + "-/etc/hosts" 94 + "-/etc/localtime" 95 + ]; 96 + }; 97 + inherit (agentCfg) environment; 98 + }; 99 + }; 100 + in 101 + { 102 + meta.maintainers = with lib.maintainers; [ janik ambroisie ]; 103 + 104 + options = { 105 + services.woodpecker-agents = { 106 + agents = lib.mkOption { 107 + default = { }; 108 + type = lib.types.attrsOf agentModule; 109 + example = { 110 + docker = { 111 + environment = { 112 + WOODPECKER_SERVER = "localhost:9000"; 113 + WOODPECKER_BACKEND = "docker"; 114 + DOCKER_HOST = "unix:///run/podman/podman.sock"; 115 + }; 116 + 117 + extraGroups = [ "docker" ]; 118 + 119 + environmentFile = "/run/secrets/woodpecker/agent-secret.txt"; 120 + }; 121 + 122 + exec = { 123 + environment = { 124 + WOODPECKER_SERVER = "localhost:9000"; 125 + WOODPECKER_BACKEND = "exec"; 126 + }; 127 + 128 + environmentFile = "/run/secrets/woodpecker/agent-secret.txt"; 129 + }; 130 + }; 131 + description = lib.mdDoc "woodpecker-agents configurations"; 132 + }; 133 + }; 134 + }; 135 + 136 + config = { 137 + systemd.services = 138 + let 139 + mkServices = lib.mapAttrs' mkAgentService; 140 + enabledAgents = lib.filterAttrs (_: agent: agent.enable) cfg.agents; 141 + in 142 + mkServices enabledAgents; 143 + }; 144 + }
+1 -1
nixos/modules/services/continuous-integration/woodpecker/server.nix
··· 8 cfg = config.services.woodpecker-server; 9 in 10 { 11 - meta.maintainers = [ lib.maintainers.janik ]; 12 13 14 options = {
··· 8 cfg = config.services.woodpecker-server; 9 in 10 { 11 + meta.maintainers = with lib.maintainers; [ janik ambroisie ]; 12 13 14 options = {