aboutsummaryrefslogtreecommitdiff
path: root/app/drone-ci
diff options
context:
space:
mode:
authorAlex Auvolat <alex@adnab.me>2022-08-23 12:10:25 +0200
committerAlex Auvolat <alex@adnab.me>2022-08-23 12:10:25 +0200
commit8cd804a8c06dc97bca3101917aba1bfc90f3f0d2 (patch)
treef6e59f65a65c0d8b5ba10735326a6a973d871737 /app/drone-ci
parent7d7efab9ee6b45b62e8966bbb56a5cf90397b179 (diff)
downloadnixcfg-8cd804a8c06dc97bca3101917aba1bfc90f3f0d2.tar.gz
nixcfg-8cd804a8c06dc97bca3101917aba1bfc90f3f0d2.zip
Add Drone CI server with sqlite-on-s3 thing
Diffstat (limited to 'app/drone-ci')
-rw-r--r--app/drone-ci/config/litestream.yml10
-rw-r--r--app/drone-ci/deploy/server.hcl139
-rw-r--r--app/drone-ci/integration/README.md74
-rw-r--r--app/drone-ci/integration/docker-compose.yml32
-rw-r--r--app/drone-ci/secrets/drone-ci/cookie_secret1
-rw-r--r--app/drone-ci/secrets/drone-ci/db_enc_secret1
-rw-r--r--app/drone-ci/secrets/drone-ci/oauth_client_id1
-rw-r--r--app/drone-ci/secrets/drone-ci/oauth_client_secret1
-rw-r--r--app/drone-ci/secrets/drone-ci/rpc_secret2
-rw-r--r--app/drone-ci/secrets/drone-ci/s3_ak1
-rw-r--r--app/drone-ci/secrets/drone-ci/s3_db_bucket1
-rw-r--r--app/drone-ci/secrets/drone-ci/s3_sk1
-rw-r--r--app/drone-ci/secrets/drone-ci/s3_storage_bucket1
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