initialize: add gitlab-runner role

This playbook sets up a Gitlab Runner with the choice between a Docker
executor and a custom KVM executor.

roles/gitlab-runner/templates/gitlab-runners-network.xml
master
Devan Carpenter 2 years ago
commit a917db54c4
Signed by: dvn
GPG Key ID: E1707CFFD7B85A02

@ -0,0 +1,11 @@
# Ansible Gitlab Runner
An `ansible-pull` repo to configure a Gitlab Runner with optional executors.
## Executors
- Docker
This is the standard Docker executor.
- Custom KVM
This is a custom qemu/kvm executor using shell scripts.

@ -0,0 +1,5 @@
---
- hosts: localhost
roles:
- role: gitlab-runner
when: ansible_local is defined and ansible_local.gitlab_runner is defined and ansible_local.gitlab_runner.registration_token is defined

@ -0,0 +1,7 @@
- name: reload systemd
command: systemctl daemon-reload
- name: restart gitlab-runner
service:
name: gitlab-runner
state: restarted

@ -0,0 +1,19 @@
- name: Install depends
apt:
name: [apt-transport-https]
state: present
- name: Add Docker apt signing key
apt_key:
id: 9DC858229FC7DD38854AE2D88D81803C0EBFCD88
url: https://download.docker.com/linux/debian/gpg
- name: Add Docker apt repo to souces.list
apt_repository:
codename: "{{ ansible_distribution_release }}"
repo: "deb [arch=amd64] https://download.docker.com/linux/debian {{ ansible_distribution_release }} stable"
update_cache: yes
- name: Install Docker CE
apt:
name: [docker-ce, docker-ce-cli, containerd.io]

@ -0,0 +1,61 @@
- name: Install Docker CE
include_tasks: "docker.yml"
when: ansible_local.gitlab_runner.executor == "docker"
- name: Install depends
apt:
name: [apt-transport-https]
state: present
- name: Add GitLab apt signing key
apt_key:
id: F6403F6544A38863DAA0B6E03F01618A51312F3F
url: https://packages.gitlab.com/gpg.key
- name: Add GitLab apt repo to souces.list
apt_repository:
codename: "{{ ansible_distribution_release }}"
repo: "deb https://packages.gitlab.com/runner/gitlab-runner/debian/ {{ ansible_distribution_release }} main"
update_cache: yes
- name: Install GitLab Runner
apt:
name: gitlab-runner
- name: Get a token for the runner
uri:
url: "https://{{ ansible_local.gitlab_runner.gitlab_domain }}/api/v4/runners"
method: POST
body_format: form-urlencoded
body:
name: "{{ ansible_fqdn }}"
description: "virtual machine on {{ ansible_fqdn }}"
token: "{{ ansible_local.gitlab_runner.registration_token }}"
tag_list: "{{ ansible_local.gitlab_runner.executor }}"
status_code: 201
return_content: yes
register: runner_token
when: ansible_local.gitlab_runner.runner_token is not defined
- name: Store the token
template:
src: gitlab_runner.fact
dest: /etc/ansible/facts.d/gitlab_runner.fact
when: ansible_local.gitlab_runner.runner_token is not defined
- name: Reread facts
setup: {}
when: ansible_local.gitlab_runner.runner_token is not defined
- name: Install gitlab custom executor scripts
template:
src: "{{ item }}.sh"
dest: "/etc/gitlab-runner/{{ item }}.sh"
mode: "0755"
with_items: [config, prepare, run, cleanup]
when: ansible_local.gitlab_runner.executor == "kvm"
- name: Install configuration for the gitlab runner
template:
src: gitlab-runner.toml
dest: /etc/gitlab-runner/config.toml

@ -0,0 +1,13 @@
#!/bin/bash
set -euo pipefail
VM_IMAGES_PATH="/var/lib/libvirt/images"
BASE_VM_IMAGE="$VM_IMAGES_PATH/gitlab-job.qcow2"
VM_ID="runner-$CUSTOM_ENV_CI_RUNNER_ID-project-$CUSTOM_ENV_CI_PROJECT_ID-concurrent-$CUSTOM_ENV_CI_CONCURRENT_PROJECT_ID-job-$CUSTOM_ENV_CI_JOB_ID"
VM_IMAGE="$VM_IMAGES_PATH/$VM_ID.qcow2"
VM_HOSTNAME="runner-${CUSTOM_ENV_CI_JOB_ID}"
IMAGE_HOST="127.0.0.1"
export LIBVIRT_DEFAULT_URI="qemu:///system"
_get_vm_ip() {
virsh -q domifaddr --source agent "$VM_ID" 2> /dev/null | awk '{print $4}' | sed -E 's|/([0-9]+)?$||' | grep '192.168.122' || true
}

@ -0,0 +1,9 @@
{% include "base.sh" %}
# Destroy VM.
virsh shutdown "$VM_ID" || true
# Undefine VM.
virsh undefine "$VM_ID" || true
rm -fv /tmp/${VM_ID}_ed25519 /tmp/${VM_ID}_ed25519.pub ${VM_IMAGES_PATH}/${VM_ID}*

@ -0,0 +1,10 @@
#!/usr/bin/env bash
cat << EOS
{
"driver": {
"name": "entanglement.garden driver",
"version": "v0.0.1"
}
}
EOS

@ -0,0 +1,23 @@
concurrent = 5
check_interval = 0
[session_server]
session_timeout = 1800
[[runners]]
name = "{{ ansible_fqdn }}"
url = "https://{{ ansible_local.gitlab_runner.gitlab_domain }}"
token = "{{ ansible_local.gitlab_runner.runner_token }}"
executor = "{{ ansible_local.gitlab_runner.executor }}"
builds_dir = "/home/debian/builds"
cache_dir = "/home/debian/.cache"
[runners.custom]
config_exec = "/etc/gitlab-runner/config.sh"
prepare_exec = "/etc/gitlab-runner/prepare.sh"
run_exec = "/etc/gitlab-runner/run.sh"
cleanup_exec = "/etc/gitlab-runner/cleanup.sh"
[runners.cache]
[runners.cache.s3]
[runners.cache.gcs]

@ -0,0 +1,12 @@
<network>
<name>gitlab-runners</name>
<forward mode='nat' />
<bridge stp='on' delay='0'/>
<mac address='52:54:00:01:61:fd'/>
<ip address='192.168.42.1' netmask='255.255.255.0'>
<dhcp>
<range start='192.168.42.2' end='192.168.42.254'/>
</dhcp>
</ip>
</network>

@ -0,0 +1,6 @@
{
"registration_token": "{{ ansible_local.gitlab_runner.registration_token }}",
"runner_token": "{{ runner_token.content | from_json | json_query('token') }}",
"gitlab_domain": "{{ ansible_local.gitlab_runner.gitlab_domain }}"
"executor": "{{ ansible_local.gitlab_runner.executor }}"
}

@ -0,0 +1,85 @@
{% include 'base.sh' %}
# trap any error, and mark it as a system failure.
trap "exit $SYSTEM_FAILURE_EXIT_CODE" ERR
#pushd /var/lib/libvirt/images
#if ! curl -s http://${IMAGE_HOST}/gitlab-job/SHA256SUMS | grep -E "gitlab-job.qcow2$" | sha256sum -c ; then
# wget -qO gitlab-job.qcow2.xz http://${IMAGE_HOST}/gitlab-job/gitlab-job.qcow2.xz
# curl -s http://${IMAGE_HOST}/gitlab-job/SHA256SUMS | grep -E "gitlab-job.qcow2.xz$" | sha256sum -c
# rm gitlab-job.qcow2 || true
# unxz -v gitlab-job.qcow2.xz
#fi
#popd
# Copy base disk to use for Job.
cp "$BASE_VM_IMAGE" "$VM_IMAGE"
tempconfig=$(mktemp -td cloudinit.XXXXX)
echo "instance-id: ${VM_HOSTNAME}" >> $tempconfig/meta-data
echo "local-hostname: ${VM_HOSTNAME}" >> $tempconfig/meta-data
ssh-keygen -t ed25519 -f /tmp/${VM_ID}_ed25519 -qN ""
cat > $tempconfig/user-data <<EOF
#cloud-config
ssh_authorized_keys:
- $(cat /tmp/${VM_ID}_ed25519.pub)
EOF
genisoimage -output "${VM_IMAGES_PATH}/${VM_ID}-cloudinit.iso" -volid cidata -joliet -r "${tempconfig}"
# Install the VM
virt-install \
--name "$VM_ID" \
--os-variant debian10 \
--disk "$VM_IMAGE" \
--disk "${VM_IMAGES_PATH}/${VM_ID}-cloudinit.iso,device=cdrom" \
--import \
--vcpus=4 \
--ram=4096 \
--network default \
--graphics none \
--noautoconsole
# Wait for VM to get IP
echo 'Waiting for VM to get IP'
for i in $(seq 1 300); do
VM_IP=$(_get_vm_ip)
if [ -n "$VM_IP" ]; then
echo "VM got IP: $VM_IP"
break
fi
if [ "$i" == "300" ]; then
echo 'Waited 5 minutes for VM to start, exiting...'
# Inform GitLab Runner that this is a system failure, so it
# should be retried.
exit "$SYSTEM_FAILURE_EXIT_CODE"
fi
sleep 1
done
ssh-keygen -R "$VM_IP" || true
# Wait for ssh to become available
echo "Waiting for sshd to be available"
for i in $(seq 1 300); do
if ssh -i /tmp/${VM_ID}_ed25519 -o StrictHostKeyChecking=no debian@"$VM_IP" >/dev/null 2>/dev/null; then
break
fi
if [ "$i" == "300" ]; then
echo 'Waited 5 minutes for sshd to start, exiting...'
# Inform GitLab Runner that this is a system failure, so it
# should be retried.
exit "$SYSTEM_FAILURE_EXIT_CODE"
fi
sleep 1
done
rm -rf "$tempconfig"

@ -0,0 +1,10 @@
{% include "base.sh" %}
VM_IP=$(_get_vm_ip)
ssh -i /tmp/${VM_ID}_ed25519 -o StrictHostKeyChecking=no debian@"$VM_IP" /bin/bash < "${1}"
if [ $? -ne 0 ]; then
# Exit using the variable, to make the build as failure in GitLab
# CI.
exit "$BUILD_FAILURE_EXIT_CODE"
fi
Loading…
Cancel
Save