diff options
author | Alex Auvolat <alex@adnab.me> | 2022-08-23 12:10:25 +0200 |
---|---|---|
committer | Alex Auvolat <alex@adnab.me> | 2022-08-23 12:10:25 +0200 |
commit | 8cd804a8c06dc97bca3101917aba1bfc90f3f0d2 (patch) | |
tree | f6e59f65a65c0d8b5ba10735326a6a973d871737 | |
parent | 7d7efab9ee6b45b62e8966bbb56a5cf90397b179 (diff) | |
download | nixcfg-8cd804a8c06dc97bca3101917aba1bfc90f3f0d2.tar.gz nixcfg-8cd804a8c06dc97bca3101917aba1bfc90f3f0d2.zip |
Add Drone CI server with sqlite-on-s3 thing
-rw-r--r-- | app/drone-ci/config/litestream.yml | 10 | ||||
-rw-r--r-- | app/drone-ci/deploy/server.hcl | 139 | ||||
-rw-r--r-- | app/drone-ci/integration/README.md | 74 | ||||
-rw-r--r-- | app/drone-ci/integration/docker-compose.yml | 32 | ||||
-rw-r--r-- | app/drone-ci/secrets/drone-ci/cookie_secret | 1 | ||||
-rw-r--r-- | app/drone-ci/secrets/drone-ci/db_enc_secret | 1 | ||||
-rw-r--r-- | app/drone-ci/secrets/drone-ci/oauth_client_id | 1 | ||||
-rw-r--r-- | app/drone-ci/secrets/drone-ci/oauth_client_secret | 1 | ||||
-rw-r--r-- | app/drone-ci/secrets/drone-ci/rpc_secret | 2 | ||||
-rw-r--r-- | app/drone-ci/secrets/drone-ci/s3_ak | 1 | ||||
-rw-r--r-- | app/drone-ci/secrets/drone-ci/s3_db_bucket | 1 | ||||
-rw-r--r-- | app/drone-ci/secrets/drone-ci/s3_sk | 1 | ||||
-rw-r--r-- | app/drone-ci/secrets/drone-ci/s3_storage_bucket | 1 |
13 files changed, 264 insertions, 1 deletions
diff --git a/app/drone-ci/config/litestream.yml b/app/drone-ci/config/litestream.yml new file mode 100644 index 0000000..813c824 --- /dev/null +++ b/app/drone-ci/config/litestream.yml @@ -0,0 +1,10 @@ +dbs: + - path: /ephemeral/drone.db + replicas: + - url: s3://{{ key "secrets/drone-ci/s3_db_bucket" | trimSpace }}/drone.db + region: garage + endpoint: https://garage.deuxfleurs.fr + access-key-id: {{ key "secrets/drone-ci/s3_ak" | trimSpace }} + secret-access-key: {{ key "secrets/drone-ci/s3_sk" | trimSpace }} + force-path-style: true + sync-interval: 60s diff --git a/app/drone-ci/deploy/server.hcl b/app/drone-ci/deploy/server.hcl new file mode 100644 index 0000000..85eb776 --- /dev/null +++ b/app/drone-ci/deploy/server.hcl @@ -0,0 +1,139 @@ +job "drone-ci" { + datacenters = ["neptune"] + type = "service" + + group "server" { + count = 1 + + network { + port "web_port" { + to = 80 + } + } + + task "restore-db" { + lifecycle { + hook = "prestart" + sidecar = false + } + + driver = "docker" + config { + image = "litestream/litestream:0.3.9" + args = [ + "restore", "-config", "/etc/litestream.yml", "/ephemeral/drone.db" + ] + volumes = [ + "../alloc/data:/ephemeral", + "secrets/litestream.yml:/etc/litestream.yml" + ] + } + + template { + data = file("../config/litestream.yml") + destination = "secrets/litestream.yml" + } + + resources { + memory = 200 + cpu = 1000 + } + } + + task "drone_server" { + driver = "docker" + config { + image = "drone/drone:2.12.0" + ports = [ "web_port" ] + + volumes = [ + "../alloc/data:/ephemeral", + ] + } + + template { + data = <<EOH +DRONE_GITEA_SERVER=https://git.deuxfleurs.fr +DRONE_GITEA_CLIENT_ID={{ key "secrets/drone-ci/oauth_client_id" }} +DRONE_GITEA_CLIENT_SECRET={{ key "secrets/drone-ci/oauth_client_secret" }} +DRONE_RPC_SECRET={{ key "secrets/drone-ci/rpc_secret" }} +DRONE_SERVER_HOST=drone.deuxfleurs.fr +DRONE_SERVER_PROTO=https +DRONE_DATABASE_SECRET={{ key "secrets/drone-ci/db_enc_secret" }} +DRONE_COOKIE_SECRET={{ key "secrets/drone-ci/cookie_secret" }} +AWS_ACCESS_KEY_ID={{ key "secrets/drone-ci/s3_ak" }} +AWS_SECRET_ACCESS_KEY={{ key "secrets/drone-ci/s3_sk" }} +AWS_DEFAULT_REGION=garage +AWS_REGION=garage +DRONE_S3_BUCKET={{ key "secrets/drone-ci/s3_storage_bucket" }} +DRONE_S3_ENDPOINT=https://garage.deuxfleurs.fr +DRONE_S3_PATH_STYLE=true +DRONE_DATABASE_DRIVER=sqlite3 +DRONE_DATABASE_DATASOURCE=/ephemeral/drone.db +DRONE_USER_CREATE=username:lx-admin,admin:true +__DRONE_REGISTRATION_CLOSED=true +DRONE_LOGS_TEXT=true +DRONE_LOGS_PRETTY=true +DRONE_LOGS_DEBUG=true +DOCKER_API_VERSION=1.39 +EOH + destination = "secrets/env" + env = true + } + + resources { + cpu = 100 + memory = 100 + } + + service { + name = "drone" + tags = [ + "drone", + "tricot drone.deuxfleurs.fr", + ] + port = "web_port" + address_mode = "host" + check { + type = "http" + protocol = "http" + port = "web_port" + path = "/" + interval = "60s" + timeout = "5s" + check_restart { + limit = 3 + grace = "600s" + ignore_warnings = false + } + } + } + } + + task "replicate-db" { + driver = "docker" + config { + image = "litestream/litestream:0.3.9" + entrypoint = [ "/bin/sh" ] + args = [ + "-c", + "echo sleeping; sleep 60; echo launching; litestream replicate -config /etc/litestream.yml" + ] + volumes = [ + "../alloc/data:/ephemeral", + "secrets/litestream.yml:/etc/litestream.yml" + ] + } + + template { + data = file("../config/litestream.yml") + destination = "secrets/litestream.yml" + } + + resources { + memory = 250 + cpu = 100 + } + } + } +} diff --git a/app/drone-ci/integration/README.md b/app/drone-ci/integration/README.md new file mode 100644 index 0000000..b3c1cc6 --- /dev/null +++ b/app/drone-ci/integration/README.md @@ -0,0 +1,74 @@ +## Install Debian + +We recommend Debian Bullseye + +## Install Docker CE from docker.io + +Do not use the docker engine shipped by Debian + +Doc: + + - https://docs.docker.com/engine/install/debian/ + - https://docs.docker.com/compose/install/ + +On a fresh install, as root: + +```bash +apt-get remove -y docker docker-engine docker.io containerd runc +apt-get update +apt-get install apt-transport-https ca-certificates curl gnupg lsb-release +curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg + echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null +apt-get update +apt-get install -y docker-ce docker-ce-cli containerd.io + +curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose +chmod +x /usr/local/bin/docker-compose +``` + +## Prepare the runner + +Nix folder must be populated before launching any build. + +```bash +docker run --rm -it -v /var/lib/drone/nix:/mnt nixpkgs/nix:nixos-21.05 cp -r /nix/{store,var} /mnt/ +``` + +This folder will grow over time and might need to be garbage collected. +As a rule of thumb, after running a full release of Garage, this folder will require 10GB. +Consider provisioning it with at least 20GB. + +## Launch the runner + +Because we use a shared nix folder, we set the number of concurrent builds to 1. +For more details and customizations, see `docker-compose.yml`. + +```bash +DRONE_NAME=lheureduthe DRONE_OWNER=quentin DRONE_SECRET=xxx docker-compose up -d +``` + +That's all folks. + +## Check if a given job is built by your runner + +```bash +export URL=https://drone.deuxfleurs.fr +export REPO=Deuxfleurs/garage +export BUILD=1312 +curl ${URL}/api/repos/${REPO}/builds/${BUILD} \ + | jq -c '[.stages[] | { name: .name, machine: .machine }]' +``` + +It will give you the following result: + +```json +[{"name":"default","machine":"1686a"},{"name":"release-linux-x86_64","machine":"vimaire"},{"name":"release-linux-i686","machine":"carcajou"},{"name":"release-linux-aarch64","machine":"caribou"},{"name":"release-linux-armv6l","machine":"cariacou"},{"name":"refresh-release-page","machine":null}] +``` + +## Random note + +This setup is done mainly to allow nix builds with some cache. +To use the cache in Drone, you must set your repository as trusted. +The command line tool does not work (it says it successfully set your repository as trusted but it did nothing): +the only way to set your repository as trusted is to connect on the DB and set the `repo_trusted` field of your repo to true. + diff --git a/app/drone-ci/integration/docker-compose.yml b/app/drone-ci/integration/docker-compose.yml new file mode 100644 index 0000000..1e37255 --- /dev/null +++ b/app/drone-ci/integration/docker-compose.yml @@ -0,0 +1,32 @@ +version: '3.4' +services: + drone-runner: + image: drone/drone-runner-docker:latest + restart: always + environment: + - DRONE_RPC_PROTO=https + - DRONE_RPC_HOST=drone.deuxfleurs.fr + - DRONE_RPC_SECRET=${DRONE_SECRET} + - DRONE_RUNNER_CAPACITY=1 + - DRONE_DEBUG=true + - DRONE_LOGS_TRACE=true + - DRONE_RPC_DUMP_HTTP=true + - DRONE_RPC_DUMP_HTTP_BODY=true + - DRONE_RUNNER_NAME=${DRONE_NAME} + - DRONE_RUNNER_LABELS=nix:1 + #- DRONE_RUNNER_VOLUMES=/var/lib/drone/nix:/nix + ports: + - "3000:3000/tcp" + volumes: + - "/var/run/docker.sock:/var/run/docker.sock" + - "/var/lib/drone/nix:/var/lib/drone/nix" + + drone-gc: + image: drone/gc:latest + restart: always + environment: + - GC_DEBUG=true + - GC_CACHE=10gb + - GC_INTERVAL=10m + volumes: + - "/var/run/docker.sock:/var/run/docker.sock" diff --git a/app/drone-ci/secrets/drone-ci/cookie_secret b/app/drone-ci/secrets/drone-ci/cookie_secret new file mode 100644 index 0000000..04c819e --- /dev/null +++ b/app/drone-ci/secrets/drone-ci/cookie_secret @@ -0,0 +1 @@ +CMD openssl rand -hex 16 diff --git a/app/drone-ci/secrets/drone-ci/db_enc_secret b/app/drone-ci/secrets/drone-ci/db_enc_secret new file mode 100644 index 0000000..3f9e696 --- /dev/null +++ b/app/drone-ci/secrets/drone-ci/db_enc_secret @@ -0,0 +1 @@ +CMD_ONCE openssl rand -hex 16 diff --git a/app/drone-ci/secrets/drone-ci/oauth_client_id b/app/drone-ci/secrets/drone-ci/oauth_client_id new file mode 100644 index 0000000..c801b28 --- /dev/null +++ b/app/drone-ci/secrets/drone-ci/oauth_client_id @@ -0,0 +1 @@ +USER OAuth client ID (on Gitea) diff --git a/app/drone-ci/secrets/drone-ci/oauth_client_secret b/app/drone-ci/secrets/drone-ci/oauth_client_secret new file mode 100644 index 0000000..b79b688 --- /dev/null +++ b/app/drone-ci/secrets/drone-ci/oauth_client_secret @@ -0,0 +1 @@ +USER OAuth client secret (for gitea) diff --git a/app/drone-ci/secrets/drone-ci/rpc_secret b/app/drone-ci/secrets/drone-ci/rpc_secret index 7f00649..04c819e 100644 --- a/app/drone-ci/secrets/drone-ci/rpc_secret +++ b/app/drone-ci/secrets/drone-ci/rpc_secret @@ -1 +1 @@ -USER Drone RPC secret +CMD openssl rand -hex 16 diff --git a/app/drone-ci/secrets/drone-ci/s3_ak b/app/drone-ci/secrets/drone-ci/s3_ak new file mode 100644 index 0000000..3a8e4a2 --- /dev/null +++ b/app/drone-ci/secrets/drone-ci/s3_ak @@ -0,0 +1 @@ +USER S3 (garage) access key for Drone diff --git a/app/drone-ci/secrets/drone-ci/s3_db_bucket b/app/drone-ci/secrets/drone-ci/s3_db_bucket new file mode 100644 index 0000000..c36f17d --- /dev/null +++ b/app/drone-ci/secrets/drone-ci/s3_db_bucket @@ -0,0 +1 @@ +CONST drone-db diff --git a/app/drone-ci/secrets/drone-ci/s3_sk b/app/drone-ci/secrets/drone-ci/s3_sk new file mode 100644 index 0000000..46fd9fa --- /dev/null +++ b/app/drone-ci/secrets/drone-ci/s3_sk @@ -0,0 +1 @@ +USER S3 (garage) secret key for Drone diff --git a/app/drone-ci/secrets/drone-ci/s3_storage_bucket b/app/drone-ci/secrets/drone-ci/s3_storage_bucket new file mode 100644 index 0000000..ca2702c --- /dev/null +++ b/app/drone-ci/secrets/drone-ci/s3_storage_bucket @@ -0,0 +1 @@ +CONST drone-storage |