# Drone CI server = coop-cloud `drone` recipe via abra (swarm, traefik-routed at # drone.ci.commoninternet.net, Gitea SSO, wildcard cert / no ACME). The exec *runner* is a # separate host systemd service (modules/drone-runner.nix). See DECISIONS.md "CI engine"/"Drone # deployment shape". # # Idempotent-RECONCILE oneshot (same pattern as proxy/swarm-init): converges every boot/activation. # RPC + OAuth-client secrets come from sops (/run/secrets), inserted as swarm secrets here. { pkgs, ... }: let giteaClientId = "ab4cdb9d-ee96-4867-875f-87384505fc52"; reconcile = pkgs.writeShellApplication { name = "cc-ci-reconcile-drone"; runtimeInputs = with pkgs; [ abra docker jq gnused gnugrep coreutils git ]; text = '' DRONE_DOMAIN="drone.ci.commoninternet.net" ENV_FILE="$HOME/.abra/servers/default/$DRONE_DOMAIN.env" if [ ! -r /run/secrets/drone_rpc_secret ] || [ ! -r /run/secrets/drone_gitea_client_secret ]; then echo "FATAL: drone sops secrets missing at /run/secrets (rebuild ordering?)" >&2 exit 1 fi abra server ls -m -n >/dev/null 2>&1 || abra server add --local -n || true abra recipe fetch drone -n >/dev/null [ -f "$ENV_FILE" ] || abra app new drone -s default -D "$DRONE_DOMAIN" -n set_env() { sed -i -E "/^[[:space:]]*#?[[:space:]]*$1=/d" "$ENV_FILE" printf '%s=%s\n' "$1" "$2" >> "$ENV_FILE" } set_env LETS_ENCRYPT_ENV "" set_env EXTRA_DOMAINS "" set_env DRONE_USER_CREATE "username:autonomic-bot,admin:true" set_env GITEA_DOMAIN "git.autonomic.zone" set_env GITEA_CLIENT_ID "${giteaClientId}" set_env RPC_SECRET_VERSION "v1" set_env CLIENT_SECRET_VERSION "v1" set_env DRONE_ENV_VERSION "v1" set_env COMPOSE_FILE '"compose.yml:compose.gitea.yml"' have_secret() { docker secret ls --format '{{.Name}}' | grep -q "_$1_v1$"; } have_secret rpc_secret || abra app secret insert "$DRONE_DOMAIN" rpc_secret v1 /run/secrets/drone_rpc_secret -f -n have_secret client_secret || abra app secret insert "$DRONE_DOMAIN" client_secret v1 /run/secrets/drone_gitea_client_secret -f -n abra app deploy "$DRONE_DOMAIN" -n -C ''; }; in { systemd.services.deploy-drone = { description = "Reconcile the Drone CI server (coop-cloud recipe, Gitea SSO) via abra"; after = [ "deploy-proxy.service" "swarm-init.service" "docker.service" "network-online.target" ]; requires = [ "swarm-init.service" "docker.service" ]; wants = [ "network-online.target" ]; wantedBy = [ "multi-user.target" ]; environment.HOME = "/root"; serviceConfig = { Type = "oneshot"; RemainAfterExit = true; ExecStart = "${reconcile}/bin/cc-ci-reconcile-drone"; }; }; }