Fediversity/machines/dev/fedi203/woodpecker.nix
Kiara Grouwstra b52ccfaf33
add woodpecker CI
add woodpecker

status: agents error `agent could not auth: individual agent not found
by token: sql: no rows in result set`

allow manual

set `image: bash` to initally test `local` woodpecker back-end

split CI jobs

image: `bash` (`local` back-end) -> `nixos/nix` (`docker` back-end)

add debugging lines to CD pipeline to debug error `Could not open a connection to your authentication agent`

add more debug prints to CD

even more debugging

continue debugging

debug harder

explicitly specify flakes as nixos/nix image is missing this

rm /home

update fedi203

wrap faulty statement

fix check-resources

split

strace pkg

un-strace

un-test cd

dedupe image

max 5

un-bash strace

configure user

simplify secrets

set just group for system users

unverbose npins

schema

add flakes

flakes
2025-08-04 23:32:01 +02:00

313 lines
9.7 KiB
Nix

{
lib,
pkgs,
config,
...
}:
{
networking = {
firewall.allowedTCPPorts = [
22
80
443
];
};
security.acme = {
acceptTerms = true;
defaults.email = "something@fediversity.eu";
};
age.secrets =
lib.mapAttrs
(_: group: {
owner = "root";
inherit group;
mode = "440";
})
{
woodpecker-gitea-client = "woodpecker-server";
woodpecker-gitea-secret = "woodpecker-server";
woodpecker-agent-exec = "woodpecker-agent-exec";
woodpecker-agent-container = "woodpecker-agent-docker";
};
# needs `sudo generate-vars`
vars.settings.on-machine.enable = true;
vars.generators.woodpecker-agent-secret = {
runtimeInputs = [ pkgs.openssl ];
files.my-secret.secret = true;
script = ''
openssl rand -hex 32 > "$out"/my-secret
'';
};
vars.generators.woodpecker-rpc-secret = {
runtimeInputs = with pkgs; [
coreutils
bash
];
files.rpc-secret.secret = true;
# wrap in bash command to prevent `vars`' pipefail aborting half-way
script = ''
bash -c "tr -dc 'A-Za-z0-9\!?%=' < /dev/urandom | head -c 32 > $out/rpc-secret"
'';
};
vars.generators.woodpecker =
let
fileNames = [
"woodpecker-gitea-client"
"woodpecker-gitea-secret"
"woodpecker-agent-exec"
"woodpecker-agent-container"
];
in
{
runtimeInputs = [
pkgs.coreutils
pkgs.openssl
];
files = lib.genAttrs fileNames (_: {
secret = true;
});
script = ''
${lib.concatStringsSep "\n" (
lib.lists.map (file: ''cp ${config.age.secrets.${file}.path} "$out/"'') fileNames
)}
'';
};
vars.generators."templates" = rec {
dependencies = [
"woodpecker"
"woodpecker-agent-secret"
"woodpecker-rpc-secret"
];
runtimeInputs = [
pkgs.coreutils
pkgs.gnused
];
script = lib.concatStringsSep "\n" (
lib.mapAttrsToList (template: _: ''
cp "$templates/${template}" "$out/${template}"
echo "filling placeholders in template ${template}..."
${lib.concatStringsSep "\n" (
lib.lists.map (dependency: ''
echo "filling placeholders in template ${template} from generator ${dependency}..."
${lib.concatStringsSep "\n" (
lib.mapAttrsToList (
parent:
{ placeholder, ... }:
''
sed -i "s/${placeholder}/$(cat "$in/${dependency}/${parent}")/g" "$out/${template}"
echo "- substituted ${parent}"
''
) config.vars.generators.${dependency}.files
)}
'') dependencies
)}
'') files
);
# files."woodpecker-server.conf" = {
# secret = true;
# template = pkgs.writeText "woodpecker-server.conf" ''
# WOODPECKER_DATABASE_DRIVER=sqlite3
# WOODPECKER_DISABLE_USER_AGENT_REGISTRATION=false
# WOODPECKER_OPEN=false
# WOODPECKER_ADMIN=kiara,fricklerhandwerk,niols
# WOODPECKER_HOST=https://woodpecker.fediversity.eu
# WOODPECKER_GITEA=true
# WOODPECKER_GITEA_URL=https://git.fediversity.eu
# WOODPECKER_GITEA_CLIENT_FILE=${config.vars.generators.woodpecker.files.woodpecker-gitea-client.placeholder}
# WOODPECKER_GITEA_SECRET_FILE=${config.vars.generators.woodpecker.files.woodpecker-gitea-secret.placeholder}
# WOODPECKER_AGENT_SECRET_FILE=${config.vars.generators.woodpecker-agent-secret.files.my-secret.placeholder}
# WOODPECKER_GRPC_SECRET_FILE=${config.vars.generators.woodpecker-rpc-secret.files.rpc-secret.placeholder}
# WOODPECKER_LOG_LEVEL=info
# WOODPECKER_DEFAULT_CLONE_PLUGIN=docker.io/woodpeckerci/plugin-git
# WOODPECKER_SERVER_ADDR=:8000
# WOODPECKER_GRPC_ADDR=:9000
# '';
# };
files =
let
shared = ''
WOODPECKER_SERVER=localhost:9000
WOODPECKER_USERNAME=x-oauth-basic
WOODPECKER_HOSTNAME=https://woodpecker.fediversity.eu
WOODPECKER_MAX_WORKFLOWS=5
WOODPECKER_LOG_LEVEL=info
WOODPECKER_DEBUG_PRETTY=false
WOODPECKER_DEBUG_NOCOLOR=true
WOODPECKER_HEALTHCHECK=false
WOODPECKER_GRPC_VERIFY=false
# TODO: fix
WOODPECKER_GRPC_SECURE=false
'';
in
{
"woodpecker-agent-exec.conf" = {
secret = true;
template = pkgs.writeText "woodpecker-agent-exec.conf" (
lib.concatStringsSep "\n" [
shared
''
WOODPECKER_AGENT_SECRET=${config.vars.generators.woodpecker.files.woodpecker-agent-exec.placeholder}
WOODPECKER_BACKEND=local
WOODPECKER_AGENT_LABELS=type=local
''
]
);
};
"woodpecker-agent-podman.conf" = {
secret = true;
template = pkgs.writeText "woodpecker-agent-podman.conf" (
lib.concatStringsSep "\n" [
shared
''
WOODPECKER_AGENT_SECRET=${config.vars.generators.woodpecker.files.woodpecker-agent-container.placeholder}
WOODPECKER_BACKEND=docker
DOCKER_HOST=unix:///run/podman/podman.sock
WOODPECKER_AGENT_LABELS=type=docker
''
]
);
};
};
};
# enable git-lfs
programs.git = {
enable = true;
lfs.enable = true;
};
services = {
nginx = {
enable = true;
recommendedProxySettings = true;
recommendedOptimisation = true;
recommendedTlsSettings = true;
virtualHosts."woodpecker.fediversity.eu" = {
enableACME = true;
forceSSL = true;
locations."/" = {
recommendedProxySettings = true;
proxyPass = "http://127.0.0.1:8000";
};
};
};
woodpecker-server = {
enable = true;
# environmentFile = config.vars.generators."templates".files."woodpecker-server.conf".path;
# https://woodpecker-ci.org/docs/administration/configuration/server
environment = {
WOODPECKER_DATABASE_DRIVER = "sqlite3";
WOODPECKER_DISABLE_USER_AGENT_REGISTRATION = "false";
WOODPECKER_OPEN = "false";
WOODPECKER_ADMIN = "kiara,fricklerhandwerk,niols";
WOODPECKER_HOST = "https://woodpecker.fediversity.eu";
WOODPECKER_GITEA = "true";
WOODPECKER_GITEA_URL = "https://git.fediversity.eu";
WOODPECKER_GITEA_CLIENT_FILE = config.age.secrets.woodpecker-gitea-client.path;
WOODPECKER_GITEA_SECRET_FILE = config.age.secrets.woodpecker-gitea-secret.path;
WOODPECKER_AGENT_SECRET_FILE = config.vars.generators.woodpecker-agent-secret.files.my-secret.path;
WOODPECKER_GRPC_SECRET_FILE = config.vars.generators.woodpecker-rpc-secret.files.rpc-secret.path;
WOODPECKER_LOG_LEVEL = "info";
WOODPECKER_DEFAULT_CLONE_PLUGIN = "docker.io/woodpeckerci/plugin-git";
WOODPECKER_SERVER_ADDR = ":8000";
WOODPECKER_GRPC_ADDR = ":9000";
};
};
# https://woodpecker-ci.org/docs/administration/configuration/agent
woodpecker-agents.agents =
# let
# shared = {
# WOODPECKER_SERVER = "localhost:9000";
# # TODO: separate to agent-specific tokens?
# # TODO: why will it only accept `WOODPECKER_AGENT_SECRET`, not `WOODPECKER_AGENT_SECRET_FILE`?
# # WOODPECKER_AGENT_SECRET_FILE = config.vars.generators.woodpecker-agent-secret.files.my-secret.path;
# WOODPECKER_USERNAME = "x-oauth-basic";
# WOODPECKER_HOSTNAME = "https://woodpecker.fediversity.eu";
# WOODPECKER_MAX_WORKFLOWS = "4";
# WOODPECKER_LOG_LEVEL = "info";
# WOODPECKER_DEBUG_PRETTY = "false";
# WOODPECKER_DEBUG_NOCOLOR = "true";
# WOODPECKER_GRPC_SECURE = "false"; # TODO: fix
# WOODPECKER_GRPC_VERIFY = "false";
# WOODPECKER_HEALTHCHECK = "false";
# };
# in
{
# local
exec = {
enable = true;
path = with pkgs; [
git
git-lfs
woodpecker-plugin-git
bash
coreutils
nix
attic-client
];
environmentFile = [ config.vars.generators."templates".files."woodpecker-agent-exec.conf".path ];
# # https://woodpecker-ci.org/docs/administration/configuration/backends/local#environment-variables
# environment = lib.mkMerge [
# shared
# {
# WOODPECKER_BACKEND = "local";
# WOODPECKER_AGENT_LABELS = "type=local";
# WOODPECKER_AGENT_SECRET_FILE = config.age.secrets.woodpecker-agent-exec.path;
# }
# ];
};
# container
podman = {
enable = true;
environmentFile = [ config.vars.generators."templates".files."woodpecker-agent-podman.conf".path ];
# # https://woodpecker-ci.org/docs/administration/configuration/backends/docker#environment-variables
# environment = lib.mkMerge [
# shared
# {
# WOODPECKER_BACKEND = "docker";
# DOCKER_HOST = "unix:///run/podman/podman.sock";
# WOODPECKER_AGENT_LABELS = "type=docker";
# WOODPECKER_AGENT_SECRET_FILE = config.age.secrets.woodpecker-agent-container.path;
# }
# ];
};
};
};
virtualisation.docker = {
enable = true;
autoPrune = {
enable = true;
dates = "weekly";
};
};
systemd.services.woodpecker-agent-docker = {
after = [ "docker.socket" ];
restartIfChanged = false;
serviceConfig = {
BindPaths = [ "/var/run/docker.sock" ];
};
};
}