From b4766dadd0614c90ab6be3cca314ee616b068295 Mon Sep 17 00:00:00 2001 From: Jakob Meier Date: Fri, 3 Nov 2023 16:51:09 +0100 Subject: [PATCH] Added builds.sr.ht worker setup and guide --- README.md | 2 +- docs/CONFIGURATION.md | 3 + roles/builds.sr.ht/README.md | 105 ++++++++++++++++++ roles/builds.sr.ht/defaults/main.yml | 6 + roles/builds.sr.ht/tasks/config.yml | 44 -------- roles/builds.sr.ht/tasks/main.yml | 5 +- roles/builds.sr.ht/tasks/worker.yml | 94 ++++++++++++++++ .../builds.sr.ht/templates/image-control.conf | 2 + roles/builds.sr.ht/templates/worker.conf | 12 ++ roles/git.sr.ht/tasks/ssh.yml | 7 ++ 10 files changed, 233 insertions(+), 47 deletions(-) create mode 100644 roles/builds.sr.ht/README.md create mode 100644 roles/builds.sr.ht/tasks/worker.yml create mode 100644 roles/builds.sr.ht/templates/image-control.conf create mode 100644 roles/builds.sr.ht/templates/worker.conf diff --git a/README.md b/README.md index 78ce9bc..8d09c9e 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ Should be perfectly fine for a single user instance. - [x] [meta.sr.ht](https://man.sr.ht/meta.sr.ht/installation.md) - [x] [hub.sr.ht](https://man.sr.ht/hub.sr.ht/installation.md) - [x] [git.sr.ht](https://man.sr.ht/git.sr.ht/installation.md) -- [ ] [builds.sr.ht](https://man.sr.ht/builds.sr.ht/installation.md) +- [x] [builds.sr.ht](https://man.sr.ht/builds.sr.ht/installation.md) - [ ] [paste.sr.ht](https://man.sr.ht/paste.sr.ht/installation.md) - [ ] [lists.sr.ht](https://man.sr.ht/lists.sr.ht/installation.md) - [ ] [todo.sr.ht](https://man.sr.ht/todo.sr.ht/installation.md) diff --git a/docs/CONFIGURATION.md b/docs/CONFIGURATION.md index 0d7ae77..afe0e67 100644 --- a/docs/CONFIGURATION.md +++ b/docs/CONFIGURATION.md @@ -222,3 +222,6 @@ and use the `metasrht-manageuser` command to create a new user. `metasrht-manageuser -t admin -e ` Just make sure to remove the `-t admin` if the user is not supposed to be an administrator. + +## Specific Setup +- [builds.sr.ht setup guide](../roles/builds.sr.ht/README.md) diff --git a/roles/builds.sr.ht/README.md b/roles/builds.sr.ht/README.md new file mode 100644 index 0000000..bd3f5e5 --- /dev/null +++ b/roles/builds.sr.ht/README.md @@ -0,0 +1,105 @@ +# builds.sr.ht +## Worker +Unfortunately images cannot be automatically generated +and still require manual creation. + +### Configuration +The worker exposes two configuration options: +``` yaml +buildssrht_runner_log_dir: "/var/log/srhtrunner" +buildssrht_runner_mem: "2048" +``` + +`buildssrht_runner_log_dir` allows you to change the path, +where the logs are stored. +This is only here to keep it in sync with three or four spots, +and you probably do not need to change it. + +`buildssrht_runner_mem` allows you to specify the amount of memory (RAM) +the worker container/VM is allowed to use. + +### Setting up an Alpine Linux image +Creating images should differ on a platform by platform basis, +but lets walk through a basic alpine setup. + +First of all attach to your server running sourcehut +and navigate to `/var/lib/images`. +This directory is responsible for managing containers. + +Navigate into the `alpine` directory +and create a file called `bootstrap.sh`, +with the following content: +```shell +#!/bin/sh -eu + +arch="${1:-x86_64}" +version="${2:-3.18.4}" +release="$(echo $version | cut -d. -f 1-2)" + +# download the alpine virt iso +wget -O /tmp/alpine.iso https://dl-cdn.alpinelinux.org/alpine/v$release/releases/$arch/alpine-virt-$version-$arch.iso + +# start VM +${qemu:-qemu-system-$arch} \ + -m ${MEMORY:-4096} \ + -smp cpus=2 \ + -nic user \ + -boot d \ + -cdrom /tmp/alpine.iso \ + -virtfs local,path=./,mount_tag=host0,security_model=passthrough,id=host0 \ + -nographic +``` + +Now run the file `sh bootstrap.sh` and wait for the VM to boot. +Login in as `root` and run through the `setup-alpine` process until it wants to setup disks, +at this point just exit using `Ctrl-C`. +You should now have a working internet connection +and your mirrors/repositories should be setup. + +Afterwards open `/etc/fstab` using a text editor (i.e nano or vi) +and add the following line: +``` text +host0 /mnt 9p trans=virtio,version=9p2000.L 0 0 +``` +Close the file, run `mount -a` and navigate into `/mnt`. + +If you type `ls` you should see that the files from the host system are visible. + +Next up enable the community repository by running: +``` shell +sed -i -r 's/^\#(.*community)/\1/' /etc/apk/repositories +apk update +``` + +Install the following packages (as listed in the `build.yml`): +``` shell +apk add e2fsprogs qemu-img qemu-system-x86_64 sfdisk syslinux +``` +Keep in mind that these might be different if you are not building for `x86_64` + +Modprobe the ext4 module: +``` shell +modprobe ext4 +``` + +Now that all of the dependencies are out of the way, +decide on a release to build (i.e `3.18` or `edge`) +and `cd` into the version folder, +i.e: +``` shell +cd edge +``` + +And run `./genimage x86_64` to generate an image. + +Now repeat for all the image version you want. +If all the images were generated successfully, +you should be able to just start an example build.yml: +``` yaml +image: alpine/edge +tasks: + - say-hello: | + echo hello + - say-world: | + echo world +``` diff --git a/roles/builds.sr.ht/defaults/main.yml b/roles/builds.sr.ht/defaults/main.yml index 2e6c347..1fb27b4 100644 --- a/roles/builds.sr.ht/defaults/main.yml +++ b/roles/builds.sr.ht/defaults/main.yml @@ -1,3 +1,9 @@ --- +# probably not needed, but might help fix authentification issues buildssrht_oauth_client_id: "" buildssrht_oauth_client_secret: "" + +# where to store the logs +buildssrht_runner_log_dir: "/var/log/srhtrunner" +# how much memory the worker vm may use +buildssrht_runner_mem: "2048" diff --git a/roles/builds.sr.ht/tasks/config.yml b/roles/builds.sr.ht/tasks/config.yml index e9dac6f..d262f9f 100644 --- a/roles/builds.sr.ht/tasks/config.yml +++ b/roles/builds.sr.ht/tasks/config.yml @@ -40,50 +40,6 @@ # Only needed if not run behind a reverse proxy, e.g. for local development. # By default, the API port is 100 more than the web port # api-origin=http://127.0.0.1:5102 - - # - # These config options are only necessary for systems running a build runner - [builds.sr.ht::worker] - # - # Name of this build runner (with HTTP port if not 80) - name=runner.{{ srht_domain }} - # - # Path to write build logs - buildlogs=./logs - # - # Path to the build images - images=./images - # - # In production you should NOT put the build user in the docker group. Instead, - # make a scratch user who is and write a sudoers or doas.conf file that allows - # them to execute just the control command, then update this config option. For - # example: - # - # doas -u docker /var/lib/images/control - # - # Assuming doas.conf looks something like this: - # - # permit nopass builds as docker cmd /var/lib/images/control - # - # For more information about the security model of builds.sr.ht, visit the wiki: - # - # https://man.sr.ht/builds.sr.ht/installation.md - controlcmd=./images/control - # - # Max build duration. See https://golang.org/pkg/time/#ParseDuration - timeout=45m - # - # Http bind address for serving local build information/monitoring - bind-address=0.0.0.0:8080 - # - # Build trigger email - trigger-from={{ srht_smtp_from }} - # - # Configure the S3 bucket and prefix for object storage. Leave empty to disable - # object storage. Bucket is required to enable object storage; prefix is - # optional. - s3-bucket= - s3-prefix= register: conf - name: Enable & start builds.sr.ht service diff --git a/roles/builds.sr.ht/tasks/main.yml b/roles/builds.sr.ht/tasks/main.yml index d7472fa..836b7e4 100644 --- a/roles/builds.sr.ht/tasks/main.yml +++ b/roles/builds.sr.ht/tasks/main.yml @@ -3,8 +3,6 @@ community.general.apk: name: - builds.sr.ht - - builds.sr.ht-images - - builds.sr.ht-worker state: latest - name: Setup /etc/hosts localhost redirect @@ -20,3 +18,6 @@ - name: Setup nginx ansible.builtin.import_tasks: nginx.yml + +- name: Setup runner + ansible.builtin.import_tasks: worker.yml diff --git a/roles/builds.sr.ht/tasks/worker.yml b/roles/builds.sr.ht/tasks/worker.yml new file mode 100644 index 0000000..1bb5849 --- /dev/null +++ b/roles/builds.sr.ht/tasks/worker.yml @@ -0,0 +1,94 @@ +--- +- name: Install runner dependencies + community.general.apk: + name: + - builds.sr.ht-images + - builds.sr.ht-worker + # NOTE: add more qemu-system-$arch packages here, + # once sourehut supports other architectures + - qemu-system-x86_64 + state: latest + +- name: Ensure the builds.sr.ht runner config is injected + ansible.builtin.blockinfile: + path: /etc/sr.ht/config.ini + marker: "#-- {mark} ANSIBLE builds.sr.ht (runner) --#" + block: | + # These config options are only necessary for systems running a build runner + [builds.sr.ht::worker] + # + # Name of this build runner (with HTTP port if not 80) + name=runner.{{ srht_domain }} + # + # Path to write build logs + buildlogs={{ buildssrht_runner_log_dir }} + # + # Path to the build images + images=/var/lib/images/ + # + # In production you should NOT put the build user in the docker group. Instead, + # make a scratch user who is and write a sudoers or doas.conf file that allows + # them to execute just the control command, then update this config option. For + # example: + # + # doas -u docker /var/lib/images/control + # + # Assuming doas.conf looks something like this: + # + # permit nopass builds as docker cmd /var/lib/images/control + # + # For more information about the security model of builds.sr.ht, visit the wiki: + # + # https://man.sr.ht/builds.sr.ht/installation.md + controlcmd=/var/lib/images/control + # + # Max build duration. See https://golang.org/pkg/time/#ParseDuration + timeout=45m + # + # Http bind address for serving local build information/monitoring + bind-address=0.0.0.0:8080 + # + # Build trigger email + trigger-from={{ srht_smtp_from }} + # + # Configure the S3 bucket and prefix for object storage. Leave empty to disable + # object storage. Bucket is required to enable object storage; prefix is + # optional. + s3-bucket= + s3-prefix= + register: conf + +- name: Overwrite default runner setup + ansible.builtin.template: + src: image-control.conf + dest: /etc/image-control.conf + +- name: Make sure the runner user login shell is set correctly + ansible.builtin.user: + name: builds + shell: "/bin/sh" # may not be set to /sbin/nologin + +- name: Make sure runner log dir exists + ansible.builtin.file: + name: "{{ buildssrht_runner_log_dir }}" + state: "directory" + owner: builds + group: builds + +- name: Copy runner nginx config file + ansible.builtin.template: + src: worker.conf + dest: /etc/nginx/http.d/worker.sr.ht.conf + register: nginxconf + +- name: Start & enable nginx + ansible.builtin.service: + name: nginx + state: restarted + enabled: true + when: nginxconf.changed + +- name: Setup /etc/hosts localhost redirect for runner + ansible.builtin.lineinfile: + path: /etc/hosts + line: "127.0.0.1 runner.{{ srht_domain }}" diff --git a/roles/builds.sr.ht/templates/image-control.conf b/roles/builds.sr.ht/templates/image-control.conf new file mode 100644 index 0000000..aa4242b --- /dev/null +++ b/roles/builds.sr.ht/templates/image-control.conf @@ -0,0 +1,2 @@ +default_means="qemu" +MEMORY="{{ buildssrht_runner_mem }}" diff --git a/roles/builds.sr.ht/templates/worker.conf b/roles/builds.sr.ht/templates/worker.conf new file mode 100644 index 0000000..0fde91c --- /dev/null +++ b/roles/builds.sr.ht/templates/worker.conf @@ -0,0 +1,12 @@ +server { + include sourcehut.conf; + server_name runner.{{ srht_domain }}; + + client_max_body_size 100M; + + location /logs { + proxy_pass http://127.0.0.1:8080/logs; + include headers.conf; + include web.conf; + } +} diff --git a/roles/git.sr.ht/tasks/ssh.yml b/roles/git.sr.ht/tasks/ssh.yml index 9612e28..25501f9 100644 --- a/roles/git.sr.ht/tasks/ssh.yml +++ b/roles/git.sr.ht/tasks/ssh.yml @@ -27,6 +27,13 @@ group: git state: touch +- name: Manually create update-hook log file + ansible.builtin.file: + path: /var/log/gitsrht-update-hook + owner: git + group: git + state: touch + - name: Start & enable sshd ansible.builtin.service: name: sshd -- 2.38.5