WIP

Agents are not working : can't connect to the server for some reason...

Maybe try to use the woodpecker-grpc domain...
add-woodpecker
Bruno BELANYI 6 months ago
parent ca59097b35
commit 7821618722
  1. 7
      machines/porthos/services.nix
  2. 1
      modules/secrets/TODO
  3. 4
      modules/secrets/secrets.nix
  4. BIN
      modules/secrets/woodpecker/gitea.age
  5. 10
      modules/secrets/woodpecker/secret.age
  6. BIN
      modules/secrets/woodpecker/ssh/private-key.age
  7. 3
      modules/services/default.nix
  8. 45
      modules/services/woodpecker/agent-docker/default.nix
  9. 68
      modules/services/woodpecker/agent-local/default.nix
  10. 50
      modules/services/woodpecker/default.nix
  11. 61
      modules/services/woodpecker/server/default.nix

@ -135,6 +135,13 @@ in
enable = true;
credentialsFile = secrets."transmission/credentials".path;
};
# Open-Source CI
woodpecker = {
enable = true;
runners = [ "docker" "local" ];
secretFile = secrets."woodpecker/gitea".path;
sharedSecretFile = secrets."woodpecker/secret".path;
};
# Simple, in-kernel VPN
wireguard = {
enable = true;

@ -0,0 +1 @@
use WOODPECKER_GITEA_CLIENT_FILE, WOODPECKER_GITEA_SECRET_FILE

@ -59,6 +59,10 @@ in
"users/ambroisie/hashed-password.age".publicKeys = all;
"users/root/hashed-password.age".publicKeys = all;
"woodpecker/gitea.age".publicKeys = all;
"woodpecker/secret.age".publicKeys = all;
"woodpecker/ssh/private-key.age".publicKeys = all;
"wireguard/aramis/private-key.age".publicKeys = all;
"wireguard/milady/private-key.age".publicKeys = all;
"wireguard/porthos/private-key.age".publicKeys = all;

@ -0,0 +1,10 @@
age-encryption.org/v1
-> ssh-ed25519 jPowng IveSI2+/Q15g6yydDjMREsLFEq3fpM0SDmLmlsFnPHI
wcRtjrmf+x1ZcqyliyYz6ljOltURWVhPI9x2TQSByK4
-> ssh-ed25519 cKojmg bHay1I+jWaOEuCZoCFy6rcWiDpQxz74ZIUjOX37ODT4
AKFTS5ZrQtHjJIYWZY7GLI8Rn6B1m+eTAl+KAr1oQC0
-> n.H-grease v@8;)[ gzbujmT v9qhv $w&qF&(
7DcEcfkZuSdAQzNuuein7/y9grPQ3rkdOrDHPKAtyPxRDH1U+6RALMHpkePYjYkl
aFk+uU9vY/3WDwCiqw
--- qgViLpjAghwtShzaGBwD9r+LKTz1wZRbt2uMRGBbhcQ
Úc<UË,ôFôL¤5÷IŸ¹Çè1Z ^LCÿE/ÐЋ¸T‹§WO{}èi‡•9kç2» Æ.AÊô³OtL¢ôj“#C†,’c0„˜¬&­<EFBFBD>ýÌc³ ÃŒŸ

@ -21,8 +21,8 @@
./paperless
./pirate
./podgrab
./postgresql-backup
./postgresql
./postgresql-backup
./quassel
./rss-bridge
./sabnzbd
@ -30,5 +30,6 @@
./tlp
./transmission
./wireguard
./woodpecker
];
}

@ -0,0 +1,45 @@
{ config, lib, pkgs, ... }:
let
cfg = config.my.services.woodpecker;
hasRunner = (name: builtins.elem name cfg.runners);
agentPkg = pkgs.ambroisie.woodpecker-agent;
in
{
config = lib.mkIf (cfg.enable && hasRunner "docker") {
systemd.services.woodpecker-agent-docker = {
wantedBy = [ "multi-user.target" ];
after = [ "docker.socket" ]; # Needs the socket to be available
# might break deployment
restartIfChanged = false;
confinement.enable = true;
serviceConfig = {
Environment = [
"WOODPECKER_SERVER=localhost:${toString cfg.grpcPort}"
"WOODPECKER_GRPC_SECURE=true"
"WOODPECKER_MAX_PROCS=10"
"WOODPECKER_BACKEND=docker"
# FIXME: docker settings
];
BindPaths = [
"/var/run/docker.sock"
];
EnvironmentFile = [
cfg.sharedSecretFile
];
ExecStart = "${agentPkg}/bin/woodpecker-agent";
User = "woodpecker-agent-docker";
Group = "woodpecker-agent-docker";
};
};
# Make sure it is activated in that case
virtualisation.docker.enable = true;
users.users.woodpecker-agent-docker = {
isSystemUser = true;
group = "woodpecker-agent-docker";
extraGroups = [ "docker" ]; # Give access to the daemon
};
users.groups.woodpecker-agent-docker = { };
};
}

@ -0,0 +1,68 @@
{ config, lib, pkgs, ... }:
let
cfg = config.my.services.woodpecker;
hasRunner = (name: builtins.elem name cfg.runners);
agentPkg = pkgs.ambroisie.woodpecker-agent;
in
{
config = lib.mkIf (cfg.enable && hasRunner "local") {
systemd.services.woodpecker-agent-local = {
wantedBy = [ "multi-user.target" ];
# might break deployment
restartIfChanged = false;
confinement.enable = true;
confinement.packages = with pkgs; [
git
gnutar
bash
nixUnstable
gzip
];
path = with pkgs; [
git
gnutar
bash
nixUnstable
gzip
];
serviceConfig = {
Environment = [
"WOODPECKER_SERVER=localhost:${toString cfg.grpcPort}"
"WOODPECKER_GRPC_SECURE=true"
"WOODPECKER_MAX_PROCS=10"
"WOODPECKER_BACKEND=local"
"NIX_REMOTE=daemon"
"PAGER=cat"
];
BindPaths = [
"/nix/var/nix/daemon-socket/socket"
"/run/nscd/socket"
];
BindReadOnlyPaths = [
"/etc/resolv.conf:/etc/resolv.conf"
"/etc/resolvconf.conf:/etc/resolvconf.conf"
"/etc/passwd:/etc/passwd"
"/etc/group:/etc/group"
"/nix/var/nix/profiles/system/etc/nix:/etc/nix"
"${config.environment.etc."ssl/certs/ca-certificates.crt".source}:/etc/ssl/certs/ca-certificates.crt"
"${config.environment.etc."ssh/ssh_known_hosts".source}:/etc/ssh/ssh_known_hosts"
"/etc/machine-id"
# channels are dynamic paths in the nix store, therefore we need to bind mount the whole thing
"/nix/"
];
EnvironmentFile = [
cfg.sharedSecretFile
];
ExecStart = "${agentPkg}/bin/woodpecker-agent";
User = "woodpecker-agent-local";
Group = "woodpecker-agent-local";
};
};
users.users.woodpecker-agent-local = {
isSystemUser = true;
group = "woodpecker-agent-local";
};
users.groups.woodpecker-agent-local = { };
};
}

@ -0,0 +1,50 @@
# A docker-based CI/CD system
#
# Inspired by [1]
# [1]: https://github.com/Mic92/dotfiles/blob/master/nixos/eve/modules/drone.nix
{ lib, ... }:
{
imports = [
./agent-docker
./agent-local
./server
];
options.my.services.woodpecker = with lib; {
enable = mkEnableOption "Woodpecker CI";
runners = mkOption {
type = with types; listOf (enum [ "local" "docker" ]);
default = [ ];
example = [ "local" "docker" ];
description = "Types of runners to enable";
};
admin = mkOption {
type = types.str;
default = "ambroisie";
example = "admin";
description = "Name of the admin user";
};
port = mkOption {
type = types.port;
default = 3031;
example = 8080;
description = "Internal port of the Woodpecker UI";
};
grpcPort = mkOption {
type = types.port;
default = 9001;
example = 8080;
description = "Internal port of the Woodpecker gRPC";
};
secretFile = mkOption {
type = types.str;
example = "/run/secrets/woodpecker-gitea.env";
description = "Secrets to inject into Woodpecker server";
};
sharedSecretFile = mkOption {
type = types.str;
example = "/run/secrets/woodpecker-rpc.env";
description = "Shared RPC secret to inject into server and runners";
};
};
}

@ -0,0 +1,61 @@
{ config, lib, pkgs, ... }:
let
cfg = config.my.services.woodpecker;
in
{
config = lib.mkIf cfg.enable {
systemd.services.woodpecker-server = {
wantedBy = [ "multi-user.target" ];
after = [ "postgresql.service" ];
serviceConfig = {
EnvironmentFile = [
cfg.secretFile
cfg.sharedSecretFile
];
Environment = [
"WOODPECKER_SERVER_ADDR=:${toString cfg.port}"
"WOODPECKER_GRPC_ADDR=:${toString cfg.grpcPort}"
"WOODPECKER_HOST=https://woodpecker.${config.networking.domain}"
"WOODPECKER_DATABASE_DRIVER=postgres"
"WOODPECKER_DATABASE_DATASOURCE=postgres:///woodpecker?host=/run/postgresql"
"WOODPECKER_ADMIN=${cfg.admin}"
# FIXME: not supported?
"WOODPECKER_JSONNET_ENABLED=true"
"WOODPECKER_STARLARK_ENABLED=true"
];
ExecStart = "${pkgs.ambroisie.woodpecker-server}/bin/woodpecker-server";
User = "woodpecker";
Group = "woodpecker";
};
};
users.users.woodpecker = {
isSystemUser = true;
createHome = true;
group = "woodpecker";
};
users.groups.woodpecker = { };
services.postgresql = {
enable = true;
ensureDatabases = [ "woodpecker" ];
ensureUsers = [{
name = "woodpecker";
ensurePermissions = {
"DATABASE woodpecker" = "ALL PRIVILEGES";
};
}];
};
my.services.nginx.virtualHosts = [
{
subdomain = "woodpecker";
inherit (cfg) port;
}
{
subdomain = "woodpecker-grpc";
port = cfg.grpcPort;
}
];
};
}
Loading…
Cancel
Save