Woodpecker upgrade (#18)

This commit is contained in:
Patrick Stevens
2023-10-01 22:27:05 +01:00
committed by GitHub
parent e8cf9916ee
commit 713401546a
10 changed files with 94 additions and 81 deletions

View File

@@ -99,6 +99,7 @@ type WellKnownSubdomain =
| Radicale
| Rss
| Woodpecker
| WoodpeckerAgent
| Grafana
override this.ToString () =
@@ -109,6 +110,7 @@ type WellKnownSubdomain =
| Rss -> "rss"
| Grafana -> "grafana"
| Woodpecker -> "woodpecker"
| WoodpeckerAgent -> "woodpecker-agent"
static member Parse (s : string) =
match s with
@@ -117,6 +119,7 @@ type WellKnownSubdomain =
| "calendar" -> WellKnownSubdomain.Radicale
| "rss" -> WellKnownSubdomain.Rss
| "woodpecker" -> WellKnownSubdomain.Woodpecker
| "woodpecker-agent" -> WellKnownSubdomain.WoodpeckerAgent
| "grafana" -> WellKnownSubdomain.Grafana
| _ -> failwith $"Failed to deserialise: {s}"

View File

@@ -32,6 +32,9 @@ in {
services.miniflux-config.subdomain = "rss";
services.miniflux-config.domain = userConfig.domain;
services.woodpecker-config.domain = userConfig.domain;
# A small pun here: we assume that the Gitea/Woodpecker username
# is the same as the remote username.
services.woodpecker-config.admin-users = [userConfig.remoteUsername];
services.grafana-config.domain = userConfig.domain;
services.prometheus-config.domain-exporter-domains = [userConfig.domain];

View File

@@ -3,8 +3,9 @@
"gitea_admin_password": "ENC[AES256_GCM,data:M/JZ0x5ca9KAyE+HnbvAohpgQuk=,iv:PZWQ7IJRvRoAOrCJHx9yZaPmM1eEWl21kKTl776Cm4I=,tag:GNqB6vIv5B0ThiNvw/835g==,type:str]",
"gitea_admin_username": "ENC[AES256_GCM,data:vYwbK0WnDfc7Ox5YZQ==,iv:VTifWcYPYvkR+9u91f5lovOTVe8jhfDpPCvMQMSjHg0=,tag:IxMny/5HMlpU8tyQJxJHJw==,type:str]",
"gitea_admin_email": "ENC[AES256_GCM,data:d/uXN59unzpO7O54lN5qVoyZkMHSIX4iMejWeA4pdIzoiJiWg07mHLmrMhQPSg==,iv:mzg8ZvYAGoMcPI5lDEJ4VFoShoACecZMo4sOAqkKTJ0=,tag:G94XwFlVenBmWx1DD8z1dw==,type:str]",
"gitea_woodpecker_oauth_id": "ENC[AES256_GCM,data:5eZXcULdZSwA2ZJbIff1SNDIqFDcbpUmtlessuKDZvJ2ZVtJ,iv:PUw4e8/76kIJnMn01/nWpP1uqTdpTSvmk7Yhiy96x2s=,tag:+lZ/uqevpkIYdnOi3WbSeA==,type:str]",
"gitea_woodpecker_secret": "ENC[AES256_GCM,data:bvtrzsRePoa7AGEI9wVNPGwtu9otptzrjVEAK5XWvi6xg/1gcMTU0VpjSur0aLtMNMiQ7jvRsb0=,iv:NMev0UxWibwcQqdPvmYHItW05ZL4D3wfuWCPkuwPeF0=,tag:hhhxTIVgXdzrsDQ3m/koVw==,type:str]",
"gitea_woodpecker_oauth_id": "ENC[AES256_GCM,data:FDkAbOKWtrptDUf5us3j4vdWKjcPj76dvN8qmtPFrxuZV1Zy,iv:Tq1CPwraUcsQTIxomLLLXW3XmTsllH529EXtOlAcrsc=,tag:V7HwLitZ7mZNoZuiPiPeUw==,type:str]",
"gitea_woodpecker_secret": "ENC[AES256_GCM,data:t7TIjzuD/AdoxB/wwqZo8XY/gBkk9rXvAX0FWEastZR05NBc8PR7zzIMPU7yllZoFTMi8q5TdJU=,iv:bxgQ5KuPgYjIcyBQirXmoRpQbyNBqh0dEtMFsVCUOqM=,tag:4ZTeVUSU05FooOOK7nPYPg==,type:str]",
"woodpecker_agent_secret": "ENC[AES256_GCM,data:n0NZ7rXqs06SFaHHqENruZKczVqPUt/CYuQNbtd6FKCHzJJHgLeLT1GypeQpqRr9a/H4f+uW9q7ns43Ukce47A==,iv:SegoaLoi32JJkfDb7F7Yr+bOlD9nren0Ug0uQJriBCs=,tag:YDjxsXYO2ZHYzz4o0/qS4Q==,type:str]",
"acme_email": "ENC[AES256_GCM,data:5/Ex62y0nHATgHJMDDBqVtET/t7fwwlWtWVvgzmblCaG,iv:XKe5eXLOSnoL1LedJc/5egOTtFB3JRZCz30BFWLxt3A=,tag:D0IkAOV0VDmhSU++WVlXoA==,type:str]",
"radicale_user": "ENC[AES256_GCM,data:aKoxSeTypg==,iv:/r3U99EwAIigJUjISKnEtnFyZYYITEJ45jp4Q3mM0qM=,tag:T9GVZBSUwWUTFK8yS5i6iQ==,type:str]",
"radicale_password": "ENC[AES256_GCM,data:ByLueujmUMAM1Edh0YDeNVZ7GMg=,iv:x+JbD1g+NFk2AldmgyFjIbj1CmT+GGFSnx6hhx8ggoE=,tag:i4rnsGv95hC5PjXQzi6k1Q==,type:str]",
@@ -28,8 +29,8 @@
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBhL1FxdG1HM2VYdFNjMzJT\nOUZFNzFIMERNOWFNNWpGM1dVWFNQU3ZCYWhnCkdYZWdsRWpncDAzYTBaRzE5SFNq\nNFJhT3lXTElXVlJBaStaczhoYnorNWMKLS0tIDF1dlg0S1hnSkxjc01XUUVFcnd6\nSXJyL1BGb2JiVUpNK0FoNEo4cGRBL0EKdR+ZKb8hbP0wmjrzc0e3aIG5rGcyHm8g\njPfEtQx1Vt7rLSmWLNbw8tTx/5G3KFR1Bxa2t7pzEocJMDRW1g/gJA==\n-----END AGE ENCRYPTED FILE-----\n"
}
],
"lastmodified": "2023-07-21T20:59:51Z",
"mac": "ENC[AES256_GCM,data:/y/3XKfdtgxZWVFqOVDyR6wHCwCWg6YS/VV5Bne8blt8jLlVQSnzXY/nDhvy6I9MBxmPEzKlc0aWEW6WMtfHMTJ+R9Rz748zX1RFv4yoH3bnkfql0vzIR4swRivdrUEwtjvnfHF4KtvxxD86ZgDGQSOv3+XEMUtKsAx/3zlt8ZY=,iv:7YdGMWafBWGUl2UCDAp85Gy831tXKP7BOznzO9muVPw=,tag:1af74Cw14vRqsZ3DMH594Q==,type:str]",
"lastmodified": "2023-07-24T18:06:45Z",
"mac": "ENC[AES256_GCM,data:BpYJB+D++ZnEsEbUtSySPYxXGVGm11kGhtjekEf9tSD/pco4ErEwNs1O9ersCisyhRgeJ8C5TYiTBUaxvLKYStaoTPGtIYVCWXzBZt+njuebLg7NjUvT4gq2Bf/Qp3yCY5vdOfMsVBkuId+hMA/W6qG0StFCS+0HuBbpHPEnjcQ=,iv:sNJ07nY67Y+GANe2HmQr1ZBqt2r+hgjYz8aUQtgQ/Pc=,tag:zu6uS8WgpkisOy2NGvXq0w==,type:str]",
"pgp": null,
"unencrypted_suffix": "_unencrypted",
"version": "3.7.3"

View File

@@ -9,8 +9,9 @@
"gitea_admin_password" = {owner = "gitea";};
"gitea_admin_username" = {owner = "gitea";};
"gitea_admin_email" = {owner = "gitea";};
"gitea_woodpecker_oauth_id" = {owner = "woodpecker";};
"gitea_woodpecker_secret" = {owner = "woodpecker";};
"gitea_woodpecker_oauth_id" = {owner = "gitea";};
"gitea_woodpecker_secret" = {owner = "gitea";};
"woodpecker_agent_secret" = {owner = "gitea";};
"radicale_user" = {owner = "radicale";};
"radicale_htcrypt_password" = {owner = "radicale";};
"radicale_password" = {owner = "radicale";};

View File

@@ -1,31 +0,0 @@
# docker-compose.yml
version: '3'
services:
woodpecker-server:
image: woodpeckerci/woodpecker-server:next
ports: ["%%WOODPECKER_PORT%%:8000"]
volumes:
- woodpecker-server-data:/var/lib/woodpecker
environment:
- WOODPECKER_OPEN=true
- WOODPECKER_HOST=https://%%WOODPECKER_SUBDOMAIN%%.%%WOODPECKER_DOMAIN%%
- WOODPECKER_GITEA=true
- WOODPECKER_GITEA_URL=https://%%GITEA_SUBDOMAIN%%.%%WOODPECKER_DOMAIN%%
- WOODPECKER_GITEA_CLIENT=${WOODPECKER_GITEA_CLIENT_OAUTH_ID}
- WOODPECKER_GITEA_SECRET=${WOODPECKER_GITEA_SECRET}
- WOODPECKER_AGENT_SECRET=${WOODPECKER_AGENT_SECRET}
woodpecker-agent:
image: woodpeckerci/woodpecker-agent:next
command: agent
restart: always
depends_on: [woodpecker-server]
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
- WOODPECKER_SERVER=woodpecker-server:9000
- WOODPECKER_AGENT_SECRET=${WOODPECKER_AGENT_SECRET}
volumes:
woodpecker-server-data:

View File

@@ -0,0 +1,17 @@
#!/bin/sh
WOODPECKER_AGENT_SECRET=$(cat /run/secrets/woodpecker_agent_secret)
WOODPECKER_GITEA_SECRET=$(cat /run/secrets/gitea_woodpecker_secret)
WOODPECKER_GITEA_CLIENT_OAUTH_ID=$(cat /run/secrets/gitea_woodpecker_oauth_id)
outfile=$(mktemp)
chmod go-rwx "$outfile"
{
echo "WOODPECKER_AGENT_SECRET=$WOODPECKER_AGENT_SECRET"
echo "WOODPECKER_SECRET=$WOODPECKER_AGENT_SECRET"
echo "WOODPECKER_GITEA_SECRET=$WOODPECKER_GITEA_SECRET"
echo "WOODPECKER_GITEA_CLIENT=$WOODPECKER_GITEA_CLIENT_OAUTH_ID"
} >> "$outfile"
mkdir -p /preserve/woodpecker || exit 1
mv "$outfile" /preserve/woodpecker/woodpecker-combined-secrets.txt || exit 2

View File

@@ -1,10 +0,0 @@
#!/bin/sh
export WOODPECKER_AGENT_SECRET
WOODPECKER_AGENT_SECRET=$("$OPENSSL" rand -hex 32)
export WOODPECKER_GITEA_SECRET
WOODPECKER_GITEA_SECRET=$(cat /run/secrets/gitea_woodpecker_secret)
export WOODPECKER_GITEA_CLIENT_OAUTH_ID
WOODPECKER_GITEA_CLIENT_OAUTH_ID=$(cat /run/secrets/gitea_woodpecker_oauth_id)
"$DOCKER" compose -f "/etc/woodpecker.yaml" up

View File

@@ -1,3 +0,0 @@
#!/bin/sh
"$DOCKER" compose -f "/etc/woodpecker.yaml" down

View File

@@ -16,54 +16,88 @@
default = "woodpecker";
description = lib.mdDoc "Subdomain in which to put Woodpecker";
};
agent-subdomain = lib.mkOption {
type = lib.types.str;
default = "woodpecker-agent";
description = lib.mdDoc "Subdomain to open for Woodpecker agent gRPC";
};
port = lib.mkOption {
type = lib.types.port;
description = lib.mdDoc "Woodpecker localhost port";
default = 9001;
};
grpc-port = lib.mkOption {
type = lib.types.port;
description = lib.mdDoc "Woodpecker server-agent communication port";
default = 9010;
};
admin-users = lib.mkOption {
type = lib.types.listOf lib.types.str;
description = lib.mdDoc "List of admin usernames within the Woodpecker instance";
default = [];
};
};
};
config.users.users."woodpecker" = {
isSystemUser = true;
group = "woodpecker";
extraGroups = ["docker"];
config.services.woodpecker-server = {
enable = true;
environment = {
WOODPECKER_HOST = "https://${config.services.woodpecker-config.subdomain}.${config.services.woodpecker-config.domain}";
WOODPECKER_SERVER_ADDR = "localhost:${toString config.services.woodpecker-config.port}";
WOODPECKER_LOG_LEVEL = "debug";
WOODPECKER_GITEA = "true";
WOODPECKER_GITEA_URL = "https://${config.services.gitea-config.subdomain}.${config.services.gitea-config.domain}";
WOODPECKER_ADMIN = builtins.concatStringsSep "," config.services.woodpecker-config.admin-users;
WOODPECKER_GRPC_ADDR = "localhost:${toString config.services.woodpecker-config.grpc-port}";
};
environmentFile = "/preserve/woodpecker/woodpecker-combined-secrets.txt";
};
config.users.groups."woodpecker" = {};
config.environment.etc = {
"woodpecker.yaml" = {
text = builtins.replaceStrings ["%%WOODPECKER_PORT%%" "%%WOODPECKER_SUBDOMAIN%%" "%%WOODPECKER_DOMAIN%%" "%%GITEA_SUBDOMAIN%%"] [(toString config.services.woodpecker-config.port) config.services.woodpecker-config.subdomain config.services.woodpecker-config.domain config.services.gitea-config.subdomain] (builtins.readFile ./compose.yaml);
mode = "0440";
user = "woodpecker";
config.services.woodpecker-agents = {
agents = {
podman-agent = {
enable = true;
extraGroups = ["podman"];
environment = {
WOODPECKER_SERVER = "localhost:${toString config.services.woodpecker-config.grpc-port}";
WOODPECKER_BACKEND = "docker";
DOCKER_HOST = "unix:///run/podman/podman.sock";
};
environmentFile = ["/preserve/woodpecker/woodpecker-combined-secrets.txt"];
};
};
};
config.systemd.services.start-woodpecker = {
description = "start-woodpecker";
wantedBy = ["multi-user.target"];
path = [pkgs.docker];
script = builtins.readFile ./start.sh;
preStop = builtins.readFile ./stop.sh;
config.systemd.services.woodpecker-secret = {
description = "ensure woodpecker secrets are in place";
wantedBy = ["multi-user.target" "woodpecker-server.service" "woodpecker-agent-podman-agent.service"];
before = ["woodpecker-server.service" "woodpecker-agent-podman-agent.service"];
script = builtins.readFile ./secrets.sh;
serviceConfig = {
Restart = "on-failure";
Type = "exec";
User = "woodpecker";
Group = "woodpecker";
Restart = "no";
Type = "oneshot";
User = "root";
};
environment = {
DOCKER = "${pkgs.docker}/bin/docker";
OPENSSL = "${pkgs.openssl}/bin/openssl";
};
};
config = {
services.nginx.virtualHosts."${config.services.woodpecker-config.subdomain}.${config.services.woodpecker-config.domain}" = {
config.services.nginx.virtualHosts."${config.services.woodpecker-config.subdomain}.${config.services.woodpecker-config.domain}" = {
forceSSL = true;
enableACME = true;
locations."/" = {
proxyPass = "http://localhost:${toString config.services.woodpecker-config.port}/";
};
};
config.services.nginx.virtualHosts."${config.services.woodpecker-config.agent-subdomain}.${config.services.woodpecker-config.domain}" = {
forceSSL = true;
enableACME = true;
locations."/" = {
extraConfig = ''
grpc_pass grpc://127.0.0.1:${toString config.services.woodpecker-config.grpc-port};
'';
};
};
}

View File

@@ -43,10 +43,8 @@
<None Include="Nix\gitea\gitea-config.nix" />
<Content Include="Nix\config.json" />
<Content Include="Nix\ssh-keys.json" />
<Content Include="Nix\woodpecker\compose.yaml" />
<Content Include="Nix\woodpecker\start.sh" />
<Content Include="Nix\woodpecker\secrets.sh" />
<Content Include="Nix\woodpecker\woodpecker.nix" />
<Content Include="Nix\woodpecker\stop.sh" />
<Content Include="Nix\grafana\grafana.nix" />
<Content Include="Nix\grafana\node.json" />
<Content Include="Nix\prometheus\prometheus.nix" />