refactor: rootless Docker, fix auto-merge, molecule platform matrix
Three major improvements: 1. Rootless Docker refactor: Removes docker/binary modes, unifies to rootless Docker with per-runner system users. Each runner gets its own rootless Docker daemon, systemd user service, and isolated environment. Simplifies CLI (removes --mode option), Ansible role (single code path), and molecule scenarios (removes binary scenario). 2. Auto-merge fix: Fixes status check context mismatch in branch protection (was requiring "lint", "unit-tests", "molecule-tests" but actual contexts are "CI / quality", "CI / molecule-tests*"). Adds retry/wait logic to auto_merge.py that polls commit statuses for up to 15 minutes before attempting merge, eliminating the chicken-and-egg problem where auto-merge would fail because CI hadn't completed yet. 3. Molecule platform matrix: Adds OS platform matrix to CI — all 6 scenarios now run on all 4 supported OSes (ubuntu-2204, ubuntu-2404, debian-12, archlinux) = 24 test pairs distributed across 3 parallel runners. Updates distribute_molecule.py to distribute (scenario, platform) pairs. Updates Makefile with molecule-all target for local multi-platform testing. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
co-authored by
Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
parent
0c6c735000
commit
55c2746569
@@ -1,10 +1,14 @@
|
||||
---
|
||||
runner_mode: "docker"
|
||||
gitea_runner_version: "1.0.8"
|
||||
gitea_runner_docker_image: "gitea/runner"
|
||||
runner_labels: "ubuntu-latest:docker://runner-images:ubuntu-22.04"
|
||||
runner_labels: "docker,ubuntu-latest:docker://runner-images:ubuntu-22.04"
|
||||
skip_runner_registration: false
|
||||
|
||||
# Per-runner user (rootless isolation)
|
||||
gitea_runner_user_prefix: "grm-"
|
||||
gitea_runner_base_home: "/home"
|
||||
gitea_runner_service_user: "{{ gitea_runner_user_prefix }}{{ runner_name }}"
|
||||
gitea_runner_home: "{{ gitea_runner_base_home }}/{{ gitea_runner_service_user }}"
|
||||
|
||||
# Base paths (instance-scoped via runner_name)
|
||||
gitea_runner_base_data_dir: "/var/lib/gitea-runner"
|
||||
gitea_runner_base_config_dir: "/etc/gitea-runner"
|
||||
@@ -19,12 +23,11 @@ gitea_runner_prune_label: "gitea-runner=true"
|
||||
|
||||
# Service configuration
|
||||
gitea_runner_service_restart_sec: "5"
|
||||
gitea_runner_service_user: "{{ ansible_user | default('root') }}"
|
||||
|
||||
# Runner configuration
|
||||
gitea_runner_log_level: "info"
|
||||
gitea_runner_container_label: "gitea-runner=true"
|
||||
gitea_runner_file: ".runner"
|
||||
|
||||
# Docker installation
|
||||
# Docker installation (for rootless dependencies)
|
||||
docker_gpg_key_path: "/etc/apt/keyrings/docker.asc"
|
||||
|
||||
@@ -5,7 +5,10 @@
|
||||
when: ansible_facts is defined and ansible_facts['service_mgr'] | default('') == 'systemd'
|
||||
|
||||
- name: Restart gitea-runner
|
||||
ansible.builtin.systemd:
|
||||
name: "gitea-runner-{{ runner_mode }}@{{ runner_name }}"
|
||||
state: restarted
|
||||
ansible.builtin.command: systemctl --user restart gitea-runner
|
||||
become: true
|
||||
become_user: "{{ gitea_runner_service_user }}"
|
||||
environment:
|
||||
XDG_RUNTIME_DIR: "/run/user/{{ gitea_runner_uid }}"
|
||||
changed_when: true
|
||||
when: ansible_facts is defined and ansible_facts['service_mgr'] | default('') == 'systemd'
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
---
|
||||
- name: Converge
|
||||
hosts: all
|
||||
become: true
|
||||
vars:
|
||||
gitea_url: "http://localhost:3000"
|
||||
registration_token: "fake-token-for-testing"
|
||||
runner_name: "molecule-test-runner"
|
||||
runner_mode: "binary"
|
||||
skip_runner_registration: true
|
||||
roles:
|
||||
- role: gitea-runner
|
||||
@@ -1,39 +0,0 @@
|
||||
---
|
||||
driver:
|
||||
name: docker
|
||||
|
||||
platforms:
|
||||
- name: ${MOLECULE_PLATFORM_NAME:-ubuntu-2204}
|
||||
image: ${MOLECULE_PLATFORM_IMAGE:-ubuntu:22.04}
|
||||
command: ${MOLECULE_PLATFORM_COMMAND:-sleep infinity}
|
||||
volumes:
|
||||
- /sys/fs/cgroup:/sys/fs/cgroup:rw
|
||||
cgroupns_mode: host
|
||||
privileged: true
|
||||
pre_build_image: false
|
||||
|
||||
provisioner:
|
||||
name: ansible
|
||||
playbooks:
|
||||
converge: converge.yml
|
||||
prepare: ../common/prepare.yml
|
||||
env:
|
||||
ANSIBLE_ROLES_PATH: "../../.."
|
||||
|
||||
scenario:
|
||||
test_sequence:
|
||||
- dependency
|
||||
- cleanup
|
||||
- destroy
|
||||
- syntax
|
||||
- create
|
||||
- prepare
|
||||
- converge
|
||||
- idempotence
|
||||
- side_effect
|
||||
- verify
|
||||
- cleanup
|
||||
- destroy
|
||||
|
||||
verifier:
|
||||
name: ansible
|
||||
@@ -1,72 +0,0 @@
|
||||
---
|
||||
- name: Verify
|
||||
hosts: all
|
||||
become: true
|
||||
vars:
|
||||
runner_name: "molecule-test-runner"
|
||||
pre_tasks:
|
||||
- name: Load role defaults
|
||||
ansible.builtin.include_vars:
|
||||
dir: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/defaults"
|
||||
- name: Override runner mode for binary scenario
|
||||
ansible.builtin.set_fact:
|
||||
runner_mode: "binary"
|
||||
tasks:
|
||||
- name: Check gitea_runner binary exists
|
||||
ansible.builtin.stat:
|
||||
path: "{{ gitea_runner_binary_path }}"
|
||||
register: gitea_runner_stat
|
||||
|
||||
- name: Assert gitea_runner binary exists
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- gitea_runner_stat.stat.exists
|
||||
fail_msg: "gitea_runner binary is missing at {{ gitea_runner_binary_path }}"
|
||||
|
||||
- name: Check Docker is installed
|
||||
ansible.builtin.command: docker --version
|
||||
changed_when: false
|
||||
|
||||
- name: Check systemd template unit exists
|
||||
ansible.builtin.stat:
|
||||
path: "/etc/systemd/system/gitea-runner-{{ runner_mode | default('docker') }}@.service"
|
||||
register: service_stat
|
||||
|
||||
- name: Assert template unit exists
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- service_stat.stat.exists
|
||||
fail_msg: "Systemd template unit is missing"
|
||||
|
||||
- name: Check instance data directory exists
|
||||
ansible.builtin.stat:
|
||||
path: "{{ gitea_runner_data_dir }}"
|
||||
register: data_dir_stat
|
||||
|
||||
- name: Assert instance data directory exists
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- data_dir_stat.stat.exists
|
||||
fail_msg: "Instance data directory is missing"
|
||||
|
||||
- name: Check prune timer exists
|
||||
ansible.builtin.stat:
|
||||
path: /etc/systemd/system/docker-prune.timer
|
||||
register: timer_stat
|
||||
|
||||
- name: Assert prune timer exists
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- timer_stat.stat.exists
|
||||
fail_msg: "Docker prune timer is missing"
|
||||
|
||||
- name: Check config file exists
|
||||
ansible.builtin.stat:
|
||||
path: "{{ gitea_runner_config_dir }}/config.yaml"
|
||||
register: config_stat
|
||||
|
||||
- name: Assert config file exists
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- config_stat.stat.exists
|
||||
fail_msg: "Config file is missing"
|
||||
@@ -19,16 +19,3 @@
|
||||
community.general.pacman:
|
||||
update_cache: true
|
||||
when: ansible_facts['os_family'] == 'Archlinux'
|
||||
|
||||
- name: Ensure /etc/docker directory exists
|
||||
ansible.builtin.file:
|
||||
path: /etc/docker
|
||||
state: directory
|
||||
mode: "0755"
|
||||
|
||||
- name: Configure Docker daemon for vfs storage driver (DinD)
|
||||
ansible.builtin.copy:
|
||||
dest: /etc/docker/daemon.json
|
||||
content: |
|
||||
{"storage-driver": "vfs"}
|
||||
mode: "0644"
|
||||
|
||||
@@ -9,42 +9,39 @@
|
||||
ansible.builtin.include_vars:
|
||||
dir: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/defaults"
|
||||
tasks:
|
||||
- name: Check Docker is installed
|
||||
ansible.builtin.command: docker --version
|
||||
changed_when: false
|
||||
- name: Check runner user exists
|
||||
ansible.builtin.user:
|
||||
name: "{{ gitea_runner_service_user }}"
|
||||
register: user_info
|
||||
check_mode: true
|
||||
|
||||
- name: Check runner image was pulled
|
||||
ansible.builtin.command: docker images gitea/runner --format '{{ '{{' }} .Repository {{ '}}' }}:{{ '{{' }} .Tag {{ '}}' }}'
|
||||
register: image_list
|
||||
changed_when: false
|
||||
|
||||
- name: Assert runner image exists locally
|
||||
- name: Assert runner user exists
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- "'gitea/runner' in image_list.stdout"
|
||||
fail_msg: "Runner Docker image was not pulled"
|
||||
- user_info.state == "present"
|
||||
fail_msg: "Runner system user was not created"
|
||||
|
||||
- name: Check prune timer exists
|
||||
- name: Check runner binary exists
|
||||
ansible.builtin.stat:
|
||||
path: /etc/systemd/system/docker-prune.timer
|
||||
register: timer_stat
|
||||
path: "{{ gitea_runner_binary_path }}"
|
||||
register: binary_stat
|
||||
|
||||
- name: Assert prune timer exists
|
||||
- name: Assert runner binary exists
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- timer_stat.stat.exists
|
||||
fail_msg: "Docker prune timer is missing"
|
||||
- binary_stat.stat.exists
|
||||
fail_msg: "Gitea runner binary is missing"
|
||||
|
||||
- name: Check systemd template unit exists
|
||||
- name: Check systemd user service exists
|
||||
ansible.builtin.stat:
|
||||
path: "/etc/systemd/system/gitea-runner-{{ runner_mode | default('docker') }}@.service"
|
||||
path: "{{ gitea_runner_home }}/.config/systemd/user/gitea-runner.service"
|
||||
register: service_stat
|
||||
|
||||
- name: Assert template unit exists
|
||||
- name: Assert user service exists
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- service_stat.stat.exists
|
||||
fail_msg: "Systemd template unit is missing"
|
||||
fail_msg: "Systemd user service is missing"
|
||||
|
||||
- name: Check instance data directory exists
|
||||
ansible.builtin.stat:
|
||||
@@ -57,9 +54,9 @@
|
||||
- data_dir_stat.stat.exists
|
||||
fail_msg: "Instance data directory is missing"
|
||||
|
||||
- name: Check config file exists in data directory
|
||||
- name: Check config file exists in config directory
|
||||
ansible.builtin.stat:
|
||||
path: "{{ gitea_runner_data_dir }}/config.yaml"
|
||||
path: "{{ gitea_runner_config_dir }}/config.yaml"
|
||||
register: config_stat
|
||||
|
||||
- name: Assert config file exists
|
||||
@@ -67,3 +64,14 @@
|
||||
that:
|
||||
- config_stat.stat.exists
|
||||
fail_msg: "Config file is missing"
|
||||
|
||||
- name: Check prune timer exists
|
||||
ansible.builtin.stat:
|
||||
path: "{{ gitea_runner_home }}/.config/systemd/user/docker-prune.timer"
|
||||
register: timer_stat
|
||||
|
||||
- name: Assert prune timer exists
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- timer_stat.stat.exists
|
||||
fail_msg: "Docker prune timer is missing"
|
||||
|
||||
@@ -4,12 +4,18 @@
|
||||
become: true
|
||||
vars:
|
||||
runner_name: "deregister-test-runner"
|
||||
pre_tasks:
|
||||
- name: Load role defaults
|
||||
ansible.builtin.include_vars:
|
||||
dir: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/defaults"
|
||||
tasks:
|
||||
- name: Ensure fake .runner file exists
|
||||
ansible.builtin.copy:
|
||||
dest: "/var/lib/gitea-runner/{{ runner_name }}/.runner"
|
||||
dest: "{{ gitea_runner_data_dir }}/.runner"
|
||||
content: |
|
||||
{"id": 1, "uuid": "test-uuid-1234", "name": "{{ runner_name }}", "address": "http://localhost:3000"}
|
||||
owner: "{{ gitea_runner_service_user }}"
|
||||
group: "{{ gitea_runner_service_user }}"
|
||||
mode: "0644"
|
||||
|
||||
- name: Deregister runner
|
||||
@@ -19,7 +25,6 @@
|
||||
runner_name: "deregister-test-runner"
|
||||
registration_token: "fake-token-for-testing"
|
||||
gitea_url: "http://localhost:3000"
|
||||
runner_mode: "docker"
|
||||
skip_runner_registration: false
|
||||
tasks:
|
||||
- name: Include deregistration tasks
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
tasks:
|
||||
- name: Check registration file was removed
|
||||
ansible.builtin.stat:
|
||||
path: "/var/lib/gitea-runner/deregister-test-runner/.runner"
|
||||
path: "{{ gitea_runner_data_dir }}/.runner"
|
||||
register: runner_file_stat
|
||||
|
||||
- name: Assert registration file no longer exists
|
||||
@@ -18,13 +18,13 @@
|
||||
- not runner_file_stat.stat.exists
|
||||
fail_msg: "Registration file (.runner) was not removed by deregistration"
|
||||
|
||||
- name: Check systemd template still exists
|
||||
- name: Check systemd user service still exists
|
||||
ansible.builtin.stat:
|
||||
path: "/etc/systemd/system/gitea-runner-{{ runner_mode | default('docker') }}@.service"
|
||||
path: "{{ gitea_runner_home }}/.config/systemd/user/gitea-runner.service"
|
||||
register: service_stat
|
||||
|
||||
- name: Assert systemd template still exists after deregister
|
||||
- name: Assert user service still exists after deregister
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- service_stat.stat.exists
|
||||
fail_msg: "Systemd template unit was incorrectly removed"
|
||||
fail_msg: "Systemd user service was incorrectly removed"
|
||||
|
||||
@@ -5,24 +5,17 @@
|
||||
vars:
|
||||
runner_name: "lifecycle-test-runner"
|
||||
pre_tasks:
|
||||
- name: Check if systemd is available
|
||||
ansible.builtin.stat:
|
||||
path: /run/systemd/system
|
||||
register: systemd_available
|
||||
- name: Load role defaults
|
||||
ansible.builtin.include_vars:
|
||||
dir: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/defaults"
|
||||
tasks:
|
||||
- name: Stop gitea-runner systemd instance
|
||||
ansible.builtin.systemd:
|
||||
name: "gitea-runner-docker@{{ runner_name }}"
|
||||
state: stopped
|
||||
daemon_reload: true
|
||||
when: systemd_available.stat.exists
|
||||
- name: Stop gitea-runner user service
|
||||
ansible.builtin.command: "sudo -u {{ gitea_runner_service_user }} systemctl --user stop gitea-runner"
|
||||
changed_when: true
|
||||
|
||||
- name: Disable gitea-runner systemd instance
|
||||
ansible.builtin.systemd:
|
||||
name: "gitea-runner-docker@{{ runner_name }}"
|
||||
enabled: false
|
||||
daemon_reload: true
|
||||
when: systemd_available.stat.exists
|
||||
- name: Disable gitea-runner user service
|
||||
ansible.builtin.command: "sudo -u {{ gitea_runner_service_user }} systemctl --user disable gitea-runner"
|
||||
changed_when: true
|
||||
|
||||
- name: Re-enable and start runner
|
||||
hosts: all
|
||||
@@ -30,21 +23,14 @@
|
||||
vars:
|
||||
runner_name: "lifecycle-test-runner"
|
||||
pre_tasks:
|
||||
- name: Check if systemd is available
|
||||
ansible.builtin.stat:
|
||||
path: /run/systemd/system
|
||||
register: systemd_available
|
||||
- name: Load role defaults
|
||||
ansible.builtin.include_vars:
|
||||
dir: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/defaults"
|
||||
tasks:
|
||||
- name: Enable gitea-runner systemd instance
|
||||
ansible.builtin.systemd:
|
||||
name: "gitea-runner-docker@{{ runner_name }}"
|
||||
enabled: true
|
||||
daemon_reload: true
|
||||
when: systemd_available.stat.exists
|
||||
- name: Enable gitea-runner user service
|
||||
ansible.builtin.command: "sudo -u {{ gitea_runner_service_user }} systemctl --user enable gitea-runner"
|
||||
changed_when: true
|
||||
|
||||
- name: Start gitea-runner systemd instance
|
||||
ansible.builtin.systemd:
|
||||
name: "gitea-runner-docker@{{ runner_name }}"
|
||||
state: started
|
||||
daemon_reload: true
|
||||
when: systemd_available.stat.exists
|
||||
- name: Start gitea-runner user service
|
||||
ansible.builtin.command: "sudo -u {{ gitea_runner_service_user }} systemctl --user start gitea-runner"
|
||||
changed_when: true
|
||||
|
||||
@@ -9,38 +9,20 @@
|
||||
ansible.builtin.include_vars:
|
||||
dir: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/defaults"
|
||||
tasks:
|
||||
- name: Check systemd template unit exists
|
||||
- name: Check systemd user service exists
|
||||
ansible.builtin.stat:
|
||||
path: "/etc/systemd/system/gitea-runner-{{ runner_mode | default('docker') }}@.service"
|
||||
register: template_stat
|
||||
path: "{{ gitea_runner_home }}/.config/systemd/user/gitea-runner.service"
|
||||
register: service_stat
|
||||
|
||||
- name: Assert template unit exists
|
||||
- name: Assert user service exists
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- template_stat.stat.exists
|
||||
fail_msg: "Systemd template unit is missing"
|
||||
|
||||
- name: Check if systemd is available
|
||||
ansible.builtin.stat:
|
||||
path: /run/systemd/system
|
||||
register: systemd_available
|
||||
|
||||
- name: Check instance is enabled
|
||||
ansible.builtin.systemd:
|
||||
name: "gitea-runner-{{ runner_mode | default('docker') }}@lifecycle-test-runner"
|
||||
register: service_status
|
||||
when: systemd_available.stat.exists
|
||||
|
||||
- name: Assert instance is enabled
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- service_status.status.LoadState == 'loaded'
|
||||
fail_msg: "Systemd instance is not loaded"
|
||||
when: systemd_available.stat.exists
|
||||
- service_stat.stat.exists
|
||||
fail_msg: "Systemd user service is missing"
|
||||
|
||||
- name: Check instance data directory exists after lifecycle
|
||||
ansible.builtin.stat:
|
||||
path: "{{ gitea_runner_base_data_dir }}/{{ runner_name }}"
|
||||
path: "{{ gitea_runner_data_dir }}"
|
||||
register: data_dir_stat
|
||||
|
||||
- name: Assert instance data directory exists
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
gitea_url: "http://localhost:3000"
|
||||
registration_token: "fake-token-for-testing"
|
||||
runner_name: "molecule-runner-a"
|
||||
runner_mode: "binary"
|
||||
skip_runner_registration: true
|
||||
roles:
|
||||
- role: gitea-runner
|
||||
@@ -18,7 +17,6 @@
|
||||
gitea_url: "http://localhost:3000"
|
||||
registration_token: "fake-token-for-testing"
|
||||
runner_name: "molecule-runner-b"
|
||||
runner_mode: "binary"
|
||||
skip_runner_registration: true
|
||||
roles:
|
||||
- role: gitea-runner
|
||||
|
||||
@@ -6,24 +6,32 @@
|
||||
- name: Load role defaults
|
||||
ansible.builtin.include_vars:
|
||||
dir: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/defaults"
|
||||
- name: Override runner mode for multi-instance scenario
|
||||
ansible.builtin.set_fact:
|
||||
runner_mode: "binary"
|
||||
tasks:
|
||||
- name: Check systemd template unit exists
|
||||
- name: Check first runner user exists
|
||||
ansible.builtin.stat:
|
||||
path: "/etc/systemd/system/gitea-runner-{{ runner_mode | default('docker') }}@.service"
|
||||
register: template_stat
|
||||
path: "{{ gitea_runner_base_home }}/grm-molecule-runner-a"
|
||||
register: home_a_stat
|
||||
|
||||
- name: Assert template unit exists
|
||||
- name: Assert first runner user home exists
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- template_stat.stat.exists
|
||||
fail_msg: "Systemd template unit is missing"
|
||||
- home_a_stat.stat.exists
|
||||
fail_msg: "First runner user home is missing"
|
||||
|
||||
- name: Check second runner user exists
|
||||
ansible.builtin.stat:
|
||||
path: "{{ gitea_runner_base_home }}/grm-molecule-runner-b"
|
||||
register: home_b_stat
|
||||
|
||||
- name: Assert second runner user home exists
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- home_b_stat.stat.exists
|
||||
fail_msg: "Second runner user home is missing"
|
||||
|
||||
- name: Check first instance data directory exists
|
||||
ansible.builtin.stat:
|
||||
path: "/var/lib/gitea-runner/molecule-runner-a"
|
||||
path: "{{ gitea_runner_base_data_dir }}/molecule-runner-a"
|
||||
register: data_a_stat
|
||||
|
||||
- name: Assert first instance data directory exists
|
||||
@@ -34,7 +42,7 @@
|
||||
|
||||
- name: Check second instance data directory exists
|
||||
ansible.builtin.stat:
|
||||
path: "/var/lib/gitea-runner/molecule-runner-b"
|
||||
path: "{{ gitea_runner_base_data_dir }}/molecule-runner-b"
|
||||
register: data_b_stat
|
||||
|
||||
- name: Assert second instance data directory exists
|
||||
@@ -45,7 +53,7 @@
|
||||
|
||||
- name: Check first instance config exists
|
||||
ansible.builtin.stat:
|
||||
path: "/etc/gitea-runner/molecule-runner-a/config.yaml"
|
||||
path: "{{ gitea_runner_base_config_dir }}/molecule-runner-a/config.yaml"
|
||||
register: config_a_stat
|
||||
|
||||
- name: Assert first instance config exists
|
||||
@@ -56,7 +64,7 @@
|
||||
|
||||
- name: Check second instance config exists
|
||||
ansible.builtin.stat:
|
||||
path: "/etc/gitea-runner/molecule-runner-b/config.yaml"
|
||||
path: "{{ gitea_runner_base_config_dir }}/molecule-runner-b/config.yaml"
|
||||
register: config_b_stat
|
||||
|
||||
- name: Assert second instance config exists
|
||||
|
||||
@@ -1,23 +1,11 @@
|
||||
---
|
||||
- name: Converge Docker mode
|
||||
- name: Converge
|
||||
hosts: all
|
||||
become: true
|
||||
vars:
|
||||
gitea_url: "http://localhost:3000"
|
||||
registration_token: "fake-token-for-testing"
|
||||
runner_name: "template-docker-runner"
|
||||
skip_runner_registration: true
|
||||
roles:
|
||||
- role: gitea-runner
|
||||
|
||||
- name: Converge Binary mode
|
||||
hosts: all
|
||||
become: true
|
||||
vars:
|
||||
gitea_url: "http://localhost:3000"
|
||||
registration_token: "fake-token-for-testing"
|
||||
runner_name: "template-binary-runner"
|
||||
runner_mode: "binary"
|
||||
runner_name: "template-test-runner"
|
||||
skip_runner_registration: true
|
||||
roles:
|
||||
- role: gitea-runner
|
||||
|
||||
@@ -2,65 +2,42 @@
|
||||
- name: Verify
|
||||
hosts: all
|
||||
become: true
|
||||
vars:
|
||||
runner_name: "template-test-runner"
|
||||
pre_tasks:
|
||||
- name: Load role defaults
|
||||
ansible.builtin.include_vars:
|
||||
dir: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/defaults"
|
||||
tasks:
|
||||
- name: Check Docker mode systemd template exists
|
||||
- name: Check systemd user service exists
|
||||
ansible.builtin.stat:
|
||||
path: "/etc/systemd/system/gitea-runner-docker@.service"
|
||||
register: docker_template_stat
|
||||
path: "{{ gitea_runner_home }}/.config/systemd/user/gitea-runner.service"
|
||||
register: service_stat
|
||||
|
||||
- name: Assert Docker mode systemd template exists
|
||||
- name: Assert user service exists
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- docker_template_stat.stat.exists
|
||||
fail_msg: "Docker systemd template is missing"
|
||||
- service_stat.stat.exists
|
||||
fail_msg: "Systemd user service is missing"
|
||||
|
||||
- name: Read rendered Docker systemd template
|
||||
- name: Read rendered user service template
|
||||
ansible.builtin.slurp:
|
||||
src: "/etc/systemd/system/gitea-runner-docker@.service"
|
||||
register: docker_template
|
||||
src: "{{ gitea_runner_home }}/.config/systemd/user/gitea-runner.service"
|
||||
register: service_template
|
||||
|
||||
- name: Assert Docker mode template contains expected directives
|
||||
- name: Assert user service template contains expected directives
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- "'Type=oneshot' in docker_template.content | b64decode"
|
||||
- "'RemainAfterExit=yes' in docker_template.content | b64decode"
|
||||
- "'Requires=docker.service' in docker_template.content | b64decode"
|
||||
- "'docker run -d' in docker_template.content | b64decode"
|
||||
- "'ExecStop=/usr/bin/docker stop' in docker_template.content | b64decode"
|
||||
- "'Restart=on-failure' in docker_template.content | b64decode"
|
||||
fail_msg: "Docker systemd template is missing expected directives"
|
||||
|
||||
- name: Check Binary mode systemd template exists
|
||||
ansible.builtin.stat:
|
||||
path: "/etc/systemd/system/gitea-runner-binary@.service"
|
||||
register: binary_template_stat
|
||||
|
||||
- name: Assert Binary mode systemd template exists
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- binary_template_stat.stat.exists
|
||||
fail_msg: "Binary systemd template is missing"
|
||||
|
||||
- name: Read rendered Binary systemd template
|
||||
ansible.builtin.slurp:
|
||||
src: "/etc/systemd/system/gitea-runner-binary@.service"
|
||||
register: binary_template
|
||||
|
||||
- name: Assert Binary mode template contains expected directives
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- "'Type=simple' in binary_template.content | b64decode"
|
||||
- "'ExecStart={{ gitea_runner_binary_path }}' in binary_template.content | b64decode"
|
||||
- "'Restart=on-failure' in binary_template.content | b64decode"
|
||||
fail_msg: "Binary systemd template is missing expected directives"
|
||||
- "'Type=simple' in service_template.content | b64decode"
|
||||
- "'ExecStart={{ gitea_runner_binary_path }}' in service_template.content | b64decode"
|
||||
- "'Restart=on-failure' in service_template.content | b64decode"
|
||||
- "'DOCKER_HOST=unix:///run/user' in service_template.content | b64decode"
|
||||
- "'XDG_RUNTIME_DIR=/run/user' in service_template.content | b64decode"
|
||||
fail_msg: "User service template is missing expected directives"
|
||||
|
||||
- name: Read rendered prune service template
|
||||
ansible.builtin.slurp:
|
||||
src: "/etc/systemd/system/docker-prune.service"
|
||||
src: "{{ gitea_runner_home }}/.config/systemd/user/docker-prune.service"
|
||||
register: prune_service
|
||||
|
||||
- name: Assert prune service contains expected directives
|
||||
@@ -69,17 +46,16 @@
|
||||
- "'Type=oneshot' in prune_service.content | b64decode"
|
||||
- "'docker system prune' in prune_service.content | b64decode"
|
||||
- "'docker volume prune' in prune_service.content | b64decode"
|
||||
- "'label=gitea-runner=true' in prune_service.content | b64decode"
|
||||
fail_msg: "Prune service template is missing expected directives"
|
||||
|
||||
- name: Read rendered prune timer template
|
||||
ansible.builtin.slurp:
|
||||
src: "/etc/systemd/system/docker-prune.timer"
|
||||
src: "{{ gitea_runner_home }}/.config/systemd/user/docker-prune.timer"
|
||||
register: prune_timer
|
||||
|
||||
- name: Assert prune timer contains expected directives
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- "'OnCalendar=daily' in prune_timer.content | b64decode"
|
||||
- "'OnCalendar={{ gitea_runner_prune_schedule }}' in prune_timer.content | b64decode"
|
||||
- "'Persistent=true' in prune_timer.content | b64decode"
|
||||
fail_msg: "Prune timer template is missing expected directives"
|
||||
|
||||
@@ -1,23 +1,11 @@
|
||||
---
|
||||
- name: Converge Docker mode
|
||||
- name: Converge
|
||||
hosts: all
|
||||
become: true
|
||||
vars:
|
||||
gitea_url: "http://localhost:3000"
|
||||
registration_token: "fake-token-for-testing"
|
||||
runner_name: "update-docker-runner"
|
||||
skip_runner_registration: true
|
||||
roles:
|
||||
- role: gitea-runner
|
||||
|
||||
- name: Converge Binary mode
|
||||
hosts: all
|
||||
become: true
|
||||
vars:
|
||||
gitea_url: "http://localhost:3000"
|
||||
registration_token: "fake-token-for-testing"
|
||||
runner_name: "update-binary-runner"
|
||||
runner_mode: "binary"
|
||||
runner_name: "update-test-runner"
|
||||
skip_runner_registration: true
|
||||
roles:
|
||||
- role: gitea-runner
|
||||
|
||||
@@ -1,24 +1,11 @@
|
||||
---
|
||||
- name: Update Docker mode runner
|
||||
- name: Update runner
|
||||
hosts: all
|
||||
become: true
|
||||
vars:
|
||||
runner_name: "update-docker-runner"
|
||||
runner_mode: "docker"
|
||||
runner_name: "update-test-runner"
|
||||
tasks:
|
||||
- name: Include Docker update tasks
|
||||
- name: Include update tasks
|
||||
ansible.builtin.include_role:
|
||||
name: gitea-runner
|
||||
tasks_from: docker_update.yml
|
||||
|
||||
- name: Update Binary mode runner
|
||||
hosts: all
|
||||
become: true
|
||||
vars:
|
||||
runner_name: "update-binary-runner"
|
||||
runner_mode: "binary"
|
||||
tasks:
|
||||
- name: Include binary update tasks
|
||||
ansible.builtin.include_role:
|
||||
name: gitea-runner
|
||||
tasks_from: binary_update.yml
|
||||
tasks_from: update_runner.yml
|
||||
|
||||
@@ -2,23 +2,14 @@
|
||||
- name: Verify
|
||||
hosts: all
|
||||
become: true
|
||||
vars:
|
||||
runner_name: "update-test-runner"
|
||||
pre_tasks:
|
||||
- name: Load role defaults
|
||||
ansible.builtin.include_vars:
|
||||
dir: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/defaults"
|
||||
tasks:
|
||||
- name: Check Docker runner image still exists after update
|
||||
ansible.builtin.command: docker images gitea/runner --format '{{ '{{' }} .Repository {{ '}}' }}:{{ '{{' }} .Tag {{ '}}' }}'
|
||||
register: image_list
|
||||
changed_when: false
|
||||
|
||||
- name: Assert runner image exists after update
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- "'gitea/runner' in image_list.stdout"
|
||||
fail_msg: "Runner Docker image missing after update"
|
||||
|
||||
- name: Check binary runner executable still exists after update
|
||||
- name: Check runner binary still exists after update
|
||||
ansible.builtin.stat:
|
||||
path: "{{ gitea_runner_binary_path }}"
|
||||
register: binary_stat
|
||||
@@ -27,48 +18,26 @@
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- binary_stat.stat.exists
|
||||
fail_msg: "Binary runner executable missing after update"
|
||||
fail_msg: "Runner binary missing after update"
|
||||
|
||||
- name: Check Docker mode systemd template still exists
|
||||
- name: Check systemd user service still exists
|
||||
ansible.builtin.stat:
|
||||
path: "/etc/systemd/system/gitea-runner-docker@.service"
|
||||
register: docker_service_stat
|
||||
path: "{{ gitea_runner_home }}/.config/systemd/user/gitea-runner.service"
|
||||
register: service_stat
|
||||
|
||||
- name: Assert Docker mode systemd template still exists after update
|
||||
- name: Assert user service exists after update
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- docker_service_stat.stat.exists
|
||||
fail_msg: "Docker mode systemd template missing after update"
|
||||
- service_stat.stat.exists
|
||||
fail_msg: "Systemd user service missing after update"
|
||||
|
||||
- name: Check Binary mode systemd template still exists
|
||||
- name: Check instance data directory still exists
|
||||
ansible.builtin.stat:
|
||||
path: "/etc/systemd/system/gitea-runner-binary@.service"
|
||||
register: binary_service_stat
|
||||
path: "{{ gitea_runner_data_dir }}"
|
||||
register: data_stat
|
||||
|
||||
- name: Assert Binary mode systemd template still exists after update
|
||||
- name: Assert data directory exists after update
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- binary_service_stat.stat.exists
|
||||
fail_msg: "Binary mode systemd template missing after update"
|
||||
|
||||
- name: Check Docker mode data directory still exists
|
||||
ansible.builtin.stat:
|
||||
path: "/var/lib/gitea-runner/update-docker-runner"
|
||||
register: docker_data_stat
|
||||
|
||||
- name: Assert Docker mode data directory exists after update
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- docker_data_stat.stat.exists
|
||||
fail_msg: "Docker runner data directory missing after update"
|
||||
|
||||
- name: Check Binary mode data directory still exists
|
||||
ansible.builtin.stat:
|
||||
path: "/var/lib/gitea-runner/update-binary-runner"
|
||||
register: binary_data_stat
|
||||
|
||||
- name: Assert Binary mode data directory exists after update
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- binary_data_stat.stat.exists
|
||||
fail_msg: "Binary runner data directory missing after update"
|
||||
- data_stat.stat.exists
|
||||
fail_msg: "Runner data directory missing after update"
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
---
|
||||
- name: Include gitea_runner download
|
||||
ansible.builtin.include_tasks: download_gitea_runner.yml
|
||||
|
||||
- name: Restart gitea-runner systemd instance
|
||||
ansible.builtin.systemd:
|
||||
name: "gitea-runner-{{ runner_mode }}@{{ runner_name }}"
|
||||
state: restarted
|
||||
daemon_reload: true
|
||||
when: systemd_available is defined and systemd_available.stat is defined and systemd_available.stat.exists
|
||||
@@ -27,34 +27,18 @@
|
||||
--no-interactive
|
||||
args:
|
||||
chdir: "{{ gitea_runner_data_dir }}"
|
||||
become: true
|
||||
become_user: "{{ gitea_runner_service_user }}"
|
||||
environment:
|
||||
XDG_RUNTIME_DIR: "/run/user/{{ gitea_runner_uid }}"
|
||||
DOCKER_HOST: "unix:///run/user/{{ gitea_runner_uid }}/docker.sock"
|
||||
when:
|
||||
- runner_file_stat.stat.exists | default(false) | bool
|
||||
- not skip_runner_registration
|
||||
- runner_mode == 'binary'
|
||||
register: deregister_output
|
||||
changed_when: deregister_output.rc == 0
|
||||
failed_when: false
|
||||
|
||||
- name: Deregister runner with Gitea via Docker
|
||||
ansible.builtin.command: >
|
||||
docker run --rm
|
||||
--entrypoint /usr/local/bin/gitea-runner
|
||||
-v {{ gitea_runner_data_dir }}:/data
|
||||
-w /data
|
||||
{{ gitea_runner_docker_image }}:{{ gitea_runner_version | regex_replace('^v', '') }}
|
||||
delete
|
||||
--token {{ registration_token }}
|
||||
--name {{ runner_name }}
|
||||
--instance {{ gitea_url }}
|
||||
--no-interactive
|
||||
when:
|
||||
- runner_file_stat.stat.exists | default(false) | bool
|
||||
- not skip_runner_registration
|
||||
- runner_mode == 'docker'
|
||||
register: deregister_docker_output
|
||||
changed_when: deregister_docker_output.rc == 0
|
||||
failed_when: false
|
||||
|
||||
- name: Remove runner registration file
|
||||
ansible.builtin.file:
|
||||
path: "{{ gitea_runner_data_dir }}/.runner"
|
||||
|
||||
@@ -1,100 +0,0 @@
|
||||
---
|
||||
- name: Check if Docker is already installed
|
||||
ansible.builtin.command: docker --version
|
||||
register: docker_check
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
|
||||
- name: Install Docker (Debian/Ubuntu)
|
||||
when:
|
||||
- ansible_facts['os_family'] == 'Debian'
|
||||
- docker_check.rc != 0
|
||||
block:
|
||||
- name: Remove old Docker apt repository files
|
||||
ansible.builtin.file:
|
||||
path: "{{ item }}"
|
||||
state: absent
|
||||
loop:
|
||||
- /etc/apt/sources.list.d/docker.list
|
||||
- /etc/apt/keyrings/docker.gpg
|
||||
|
||||
- name: Install prerequisite packages
|
||||
ansible.builtin.apt:
|
||||
name:
|
||||
- apt-transport-https
|
||||
- ca-certificates
|
||||
- curl
|
||||
- gnupg
|
||||
state: present
|
||||
update_cache: true
|
||||
cache_valid_time: 0
|
||||
|
||||
- name: Add Docker GPG key
|
||||
ansible.builtin.get_url:
|
||||
url: https://download.docker.com/linux/{{ ansible_facts['distribution'] | lower }}/gpg
|
||||
dest: "{{ docker_gpg_key_path }}"
|
||||
mode: "0644"
|
||||
|
||||
- name: Add Docker repository
|
||||
ansible.builtin.deb822_repository:
|
||||
name: docker
|
||||
types: deb
|
||||
uris: https://download.docker.com/linux/{{ ansible_facts['distribution'] | lower }}
|
||||
suites: "{{ ansible_facts['distribution_release'] }}"
|
||||
components: stable
|
||||
signed_by: "{{ docker_gpg_key_path }}"
|
||||
state: present
|
||||
|
||||
- name: Install Docker packages
|
||||
ansible.builtin.apt:
|
||||
name:
|
||||
- docker-ce
|
||||
- docker-ce-cli
|
||||
- containerd.io
|
||||
- docker-compose-plugin
|
||||
state: present
|
||||
update_cache: true
|
||||
cache_valid_time: 0
|
||||
|
||||
- name: Install Docker (Arch Linux)
|
||||
when:
|
||||
- ansible_facts['os_family'] == 'Archlinux'
|
||||
- docker_check.rc != 0
|
||||
block:
|
||||
- name: Install Docker packages
|
||||
community.general.pacman:
|
||||
name:
|
||||
- docker
|
||||
- docker-compose
|
||||
state: present
|
||||
update_cache: true
|
||||
|
||||
- name: Ensure Docker service is running (systemd)
|
||||
ansible.builtin.systemd:
|
||||
name: docker
|
||||
state: started
|
||||
enabled: true
|
||||
when: systemd_available.stat.exists
|
||||
|
||||
- name: Start Docker daemon manually (no systemd)
|
||||
ansible.builtin.shell: nohup dockerd > /var/log/dockerd.log 2>&1 &
|
||||
when:
|
||||
- not systemd_available.stat.exists
|
||||
- docker_check.rc != 0
|
||||
changed_when: true
|
||||
|
||||
- name: Wait for Docker daemon to be ready
|
||||
ansible.builtin.command: docker version
|
||||
register: docker_ready
|
||||
until: docker_ready.rc == 0
|
||||
retries: 10
|
||||
delay: 2
|
||||
changed_when: false
|
||||
when: not systemd_available.stat.exists
|
||||
|
||||
- name: Add user to docker group
|
||||
ansible.builtin.user:
|
||||
name: "{{ ansible_user | default(ansible_facts['user_id']) }}"
|
||||
groups: docker
|
||||
append: true
|
||||
when: ansible_user is defined or ansible_facts['user_id'] is defined
|
||||
@@ -1,55 +0,0 @@
|
||||
---
|
||||
- name: Include Docker installation
|
||||
ansible.builtin.include_tasks: docker.yml
|
||||
|
||||
- name: Ensure runner data directory exists
|
||||
ansible.builtin.file:
|
||||
path: "{{ gitea_runner_data_dir }}"
|
||||
state: directory
|
||||
mode: "0755"
|
||||
|
||||
- name: Create gitea_runner config file in data directory
|
||||
ansible.builtin.template:
|
||||
src: gitea-runner-config.yaml.j2
|
||||
dest: "{{ gitea_runner_data_dir }}/config.yaml"
|
||||
mode: "0644"
|
||||
|
||||
- name: Pull gitea_runner image
|
||||
ansible.builtin.command: docker pull {{ gitea_runner_docker_image }}:{{ gitea_runner_version | regex_replace('^v', '') }}
|
||||
changed_when: "'Downloaded newer image' in pull_result.stdout or 'Status: Downloaded' in pull_result.stdout"
|
||||
register: pull_result
|
||||
|
||||
- name: Check if runner is already registered
|
||||
ansible.builtin.stat:
|
||||
path: "{{ gitea_runner_data_dir }}/.runner"
|
||||
register: runner_registered
|
||||
|
||||
- name: Register runner with Gitea via Docker
|
||||
ansible.builtin.command: >
|
||||
docker run --rm
|
||||
--entrypoint /usr/local/bin/gitea-runner
|
||||
-v {{ gitea_runner_data_dir }}:/data
|
||||
-w /data
|
||||
{{ gitea_runner_docker_image }}:{{ gitea_runner_version | regex_replace('^v', '') }}
|
||||
register
|
||||
--token {{ registration_token }}
|
||||
--name {{ runner_name }}
|
||||
--instance {{ gitea_url }}
|
||||
--labels {{ runner_labels }}
|
||||
--no-interactive
|
||||
when:
|
||||
- not runner_registered.stat.exists
|
||||
- not skip_runner_registration
|
||||
register: register_output
|
||||
changed_when: "'already exists' not in register_output.stdout | default('')"
|
||||
timeout: 60
|
||||
|
||||
- name: Restart gitea-runner service after registration
|
||||
ansible.builtin.systemd:
|
||||
name: "gitea-runner-docker@{{ runner_name }}"
|
||||
state: restarted
|
||||
daemon_reload: true
|
||||
when: systemd_available.stat.exists | default(false) | bool
|
||||
|
||||
- name: Include service setup
|
||||
ansible.builtin.include_tasks: service.yml
|
||||
@@ -1,12 +0,0 @@
|
||||
---
|
||||
- name: Pull gitea_runner image
|
||||
ansible.builtin.command: docker pull {{ gitea_runner_docker_image }}:{{ gitea_runner_version | regex_replace('^v', '') }}
|
||||
changed_when: "'Downloaded newer image' in pull_result.stdout or 'Status: Downloaded' in pull_result.stdout"
|
||||
register: pull_result
|
||||
|
||||
- name: Restart gitea-runner systemd instance
|
||||
ansible.builtin.systemd:
|
||||
name: "gitea-runner-{{ runner_mode }}@{{ runner_name }}"
|
||||
state: restarted
|
||||
daemon_reload: true
|
||||
when: systemd_available is defined and systemd_available.stat is defined and systemd_available.stat.exists
|
||||
+7
-11
@@ -1,18 +1,14 @@
|
||||
---
|
||||
- name: Include Docker installation
|
||||
ansible.builtin.include_tasks: docker.yml
|
||||
|
||||
- name: Include gitea_runner download
|
||||
ansible.builtin.include_tasks: download_gitea_runner.yml
|
||||
|
||||
- name: Ensure runner data directory exists
|
||||
ansible.builtin.file:
|
||||
path: "{{ gitea_runner_data_dir }}"
|
||||
state: directory
|
||||
mode: "0755"
|
||||
|
||||
- name: Include config creation
|
||||
ansible.builtin.include_tasks: config.yml
|
||||
- name: Create gitea_runner config file
|
||||
ansible.builtin.template:
|
||||
src: gitea-runner-config.yaml.j2
|
||||
dest: "{{ gitea_runner_config_dir }}/config.yaml"
|
||||
owner: "{{ gitea_runner_service_user }}"
|
||||
group: "{{ gitea_runner_service_user }}"
|
||||
mode: "0644"
|
||||
|
||||
- name: Include validation
|
||||
ansible.builtin.include_tasks: validate.yml
|
||||
@@ -18,19 +18,14 @@
|
||||
else {} }}
|
||||
when: runner_file_stat.stat.exists | default(false) | bool
|
||||
|
||||
- name: Verify runner container running (Docker mode)
|
||||
ansible.builtin.shell: |
|
||||
docker ps --filter "name=gitea-runner-{{ runner_name }}" --format "{{ '{{.Status}}' }}"
|
||||
register: docker_check
|
||||
changed_when: false
|
||||
when: runner_mode == 'docker'
|
||||
|
||||
- name: Verify runner service active (Binary mode)
|
||||
ansible.builtin.systemd:
|
||||
name: "gitea-runner-{{ runner_mode }}@{{ runner_name }}"
|
||||
state: started
|
||||
- name: Verify runner user service active
|
||||
ansible.builtin.command: systemctl --user is-active gitea-runner
|
||||
become: true
|
||||
become_user: "{{ gitea_runner_service_user }}"
|
||||
environment:
|
||||
XDG_RUNTIME_DIR: "/run/user/{{ gitea_runner_uid }}"
|
||||
register: service_check
|
||||
when: runner_mode == 'binary'
|
||||
changed_when: false
|
||||
|
||||
- name: Validate runner installation
|
||||
ansible.builtin.fail:
|
||||
@@ -39,16 +34,12 @@
|
||||
{% if not (runner_file_stat.stat.exists | default(false)) %}
|
||||
- Registration file (.runner) is missing. Registration may have failed.
|
||||
{% endif %}
|
||||
{% if runner_mode == 'docker' and not (docker_check.stdout | default('')) %}
|
||||
- Docker container is not running.
|
||||
{% endif %}
|
||||
{% if runner_mode == 'binary' and not (service_check.status.ActiveState | default('')) == 'active' %}
|
||||
- Systemd service is not active.
|
||||
{% if not (service_check.stdout | default('') | trim) == 'active' %}
|
||||
- Systemd user service is not active.
|
||||
{% endif %}
|
||||
when: >
|
||||
not (runner_file_stat.stat.exists | default(false))
|
||||
or (runner_mode == 'docker' and not (docker_check.stdout | default('')))
|
||||
or (runner_mode == 'binary' and not (service_check.status.ActiveState | default('')) == 'active')
|
||||
or not (service_check.stdout | default('') | trim) == 'active'
|
||||
|
||||
- name: Report runner status
|
||||
ansible.builtin.debug:
|
||||
@@ -58,8 +49,7 @@
|
||||
{% if runner_reg.id is defined %}Runner ID: {{ runner_reg.id }}{% endif %}
|
||||
{% if runner_reg.uuid is defined %}UUID: {{ runner_reg.uuid }}{% endif %}
|
||||
{% if runner_reg.address is defined %}Gitea: {{ runner_reg.address }}{% endif %}
|
||||
{% if runner_mode == 'docker' %}Container: {{ docker_check.stdout | default('unknown') }}{% endif %}
|
||||
{% if runner_mode == 'binary' %}Service: {{ service_check.status.ActiveState | default('unknown') }}{% endif %}
|
||||
Service: {{ service_check.stdout | default('unknown') | trim }}
|
||||
|
||||
- name: Optional Gitea API verification
|
||||
when:
|
||||
|
||||
@@ -2,13 +2,14 @@
|
||||
- name: Include systemd availability check
|
||||
ansible.builtin.include_tasks: systemd_check.yml
|
||||
|
||||
- name: Install runner (Docker mode)
|
||||
ansible.builtin.include_tasks: docker_mode.yml
|
||||
when: runner_mode == 'docker'
|
||||
- name: Include user setup
|
||||
ansible.builtin.include_tasks: user_setup.yml
|
||||
|
||||
- name: Install runner (Binary mode)
|
||||
ansible.builtin.include_tasks: binary_mode.yml
|
||||
when: runner_mode == 'binary'
|
||||
- name: Include rootless Docker setup
|
||||
ansible.builtin.include_tasks: rootless_docker.yml
|
||||
|
||||
- name: Include runner install
|
||||
ansible.builtin.include_tasks: install_runner.yml
|
||||
|
||||
- name: Include prune setup
|
||||
ansible.builtin.include_tasks: prune.yml
|
||||
|
||||
@@ -1,20 +1,33 @@
|
||||
---
|
||||
- name: Create docker-prune service file
|
||||
- name: Create docker-prune user service file
|
||||
ansible.builtin.template:
|
||||
src: docker-prune.service.j2
|
||||
dest: /etc/systemd/system/docker-prune.service
|
||||
dest: "{{ gitea_runner_home }}/.config/systemd/user/docker-prune.service"
|
||||
owner: "{{ gitea_runner_service_user }}"
|
||||
group: "{{ gitea_runner_service_user }}"
|
||||
mode: "0644"
|
||||
|
||||
- name: Create docker-prune timer file
|
||||
- name: Create docker-prune user timer file
|
||||
ansible.builtin.template:
|
||||
src: docker-prune.timer.j2
|
||||
dest: /etc/systemd/system/docker-prune.timer
|
||||
dest: "{{ gitea_runner_home }}/.config/systemd/user/docker-prune.timer"
|
||||
owner: "{{ gitea_runner_service_user }}"
|
||||
group: "{{ gitea_runner_service_user }}"
|
||||
mode: "0644"
|
||||
|
||||
- name: Enable and start docker-prune timer
|
||||
ansible.builtin.systemd:
|
||||
name: docker-prune.timer
|
||||
state: started
|
||||
enabled: true
|
||||
daemon_reload: true
|
||||
- name: Reload systemd user daemon for prune timer
|
||||
ansible.builtin.command: systemctl --user daemon-reload
|
||||
become: true
|
||||
become_user: "{{ gitea_runner_service_user }}"
|
||||
environment:
|
||||
XDG_RUNTIME_DIR: "/run/user/{{ gitea_runner_uid }}"
|
||||
changed_when: true
|
||||
|
||||
- name: Enable and start docker-prune user timer
|
||||
ansible.builtin.command: systemctl --user enable --now docker-prune.timer
|
||||
become: true
|
||||
become_user: "{{ gitea_runner_service_user }}"
|
||||
environment:
|
||||
XDG_RUNTIME_DIR: "/run/user/{{ gitea_runner_uid }}"
|
||||
changed_when: true
|
||||
when: systemd_available.stat.exists
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
ansible.builtin.file:
|
||||
path: "{{ gitea_runner_data_dir }}"
|
||||
state: directory
|
||||
owner: "{{ gitea_runner_service_user }}"
|
||||
group: "{{ gitea_runner_service_user }}"
|
||||
mode: "0755"
|
||||
|
||||
- name: Check if runner is already registered
|
||||
@@ -12,7 +14,7 @@
|
||||
|
||||
- name: Register runner with Gitea
|
||||
ansible.builtin.command: >
|
||||
"{{ gitea_runner_binary_path }}" register
|
||||
{{ gitea_runner_binary_path }} register
|
||||
--token {{ registration_token }}
|
||||
--name {{ runner_name }}
|
||||
--instance {{ gitea_url }}
|
||||
@@ -20,14 +22,12 @@
|
||||
--no-interactive
|
||||
args:
|
||||
chdir: "{{ gitea_runner_data_dir }}"
|
||||
become: true
|
||||
become_user: "{{ gitea_runner_service_user }}"
|
||||
environment:
|
||||
XDG_RUNTIME_DIR: "/run/user/{{ gitea_runner_uid }}"
|
||||
DOCKER_HOST: "unix:///run/user/{{ gitea_runner_uid }}/docker.sock"
|
||||
when: not runner_registered.stat.exists
|
||||
register: register_output
|
||||
changed_when: "'already exists' not in register_output.stdout | default('')"
|
||||
timeout: 60
|
||||
|
||||
- name: Restart gitea-runner service after registration
|
||||
ansible.builtin.systemd:
|
||||
name: "gitea-runner-binary@{{ runner_name }}"
|
||||
state: restarted
|
||||
daemon_reload: true
|
||||
when: systemd_available.stat.exists | default(false) | bool
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
---
|
||||
- name: Install rootless Docker dependencies (Debian/Ubuntu)
|
||||
ansible.builtin.apt:
|
||||
name:
|
||||
- uidmap
|
||||
- slirp4netns
|
||||
- fuse-overlayfs
|
||||
- docker-ce
|
||||
- docker-ce-cli
|
||||
- docker-ce-rootless-extras
|
||||
- containerd.io
|
||||
- docker-compose-plugin
|
||||
- rsync
|
||||
state: present
|
||||
update_cache: true
|
||||
cache_valid_time: 0
|
||||
when: ansible_facts['os_family'] == 'Debian'
|
||||
|
||||
- name: Install rootless Docker dependencies (Arch Linux)
|
||||
community.general.pacman:
|
||||
name:
|
||||
- docker
|
||||
- docker-compose
|
||||
- slirp4netns
|
||||
- fuse-overlayfs
|
||||
- rsync
|
||||
state: present
|
||||
update_cache: true
|
||||
when: ansible_facts['os_family'] == 'Archlinux'
|
||||
|
||||
- name: Check if rootless Docker is already set up
|
||||
ansible.builtin.stat:
|
||||
path: "{{ gitea_runner_home }}/.config/systemd/user/docker.service"
|
||||
register: rootless_docker_check
|
||||
|
||||
- name: Set up rootless Docker for runner user
|
||||
ansible.builtin.command: dockerd-rootless-setuptool.sh install
|
||||
args:
|
||||
creates: "{{ gitea_runner_home }}/.config/systemd/user/docker.service"
|
||||
become: true
|
||||
become_user: "{{ gitea_runner_service_user }}"
|
||||
environment:
|
||||
XDG_RUNTIME_DIR: "/run/user/{{ gitea_runner_uid }}"
|
||||
when: not rootless_docker_check.stat.exists
|
||||
|
||||
- name: Start rootless Docker daemon (systemd user service)
|
||||
ansible.builtin.command: systemctl --user start docker
|
||||
become: true
|
||||
become_user: "{{ gitea_runner_service_user }}"
|
||||
environment:
|
||||
XDG_RUNTIME_DIR: "/run/user/{{ gitea_runner_uid }}"
|
||||
changed_when: true
|
||||
|
||||
- name: Enable rootless Docker daemon (systemd user service)
|
||||
ansible.builtin.command: systemctl --user enable docker
|
||||
become: true
|
||||
become_user: "{{ gitea_runner_service_user }}"
|
||||
environment:
|
||||
XDG_RUNTIME_DIR: "/run/user/{{ gitea_runner_uid }}"
|
||||
changed_when: true
|
||||
|
||||
- name: Wait for rootless Docker daemon to be ready
|
||||
ansible.builtin.command: docker version
|
||||
become: true
|
||||
become_user: "{{ gitea_runner_service_user }}"
|
||||
environment:
|
||||
DOCKER_HOST: "unix:///run/user/{{ gitea_runner_uid }}/docker.sock"
|
||||
XDG_RUNTIME_DIR: "/run/user/{{ gitea_runner_uid }}"
|
||||
register: docker_ready
|
||||
until: docker_ready.rc == 0
|
||||
retries: 10
|
||||
delay: 2
|
||||
changed_when: false
|
||||
@@ -1,17 +1,25 @@
|
||||
---
|
||||
- name: Create systemd template service file
|
||||
- name: Create systemd user service file
|
||||
ansible.builtin.template:
|
||||
src: gitea-runner@.service.j2
|
||||
dest: "/etc/systemd/system/gitea-runner-{{ runner_mode }}@.service"
|
||||
src: gitea-runner-user.service.j2
|
||||
dest: "{{ gitea_runner_home }}/.config/systemd/user/gitea-runner.service"
|
||||
owner: "{{ gitea_runner_service_user }}"
|
||||
group: "{{ gitea_runner_service_user }}"
|
||||
mode: "0644"
|
||||
notify:
|
||||
- Reload systemd
|
||||
- Restart gitea-runner
|
||||
|
||||
- name: Enable and start gitea-runner instance
|
||||
ansible.builtin.systemd:
|
||||
name: "gitea-runner-{{ runner_mode }}@{{ runner_name }}"
|
||||
state: started
|
||||
enabled: true
|
||||
daemon_reload: true
|
||||
- name: Reload systemd user daemon
|
||||
ansible.builtin.command: systemctl --user daemon-reload
|
||||
become: true
|
||||
become_user: "{{ gitea_runner_service_user }}"
|
||||
environment:
|
||||
XDG_RUNTIME_DIR: "/run/user/{{ gitea_runner_uid }}"
|
||||
changed_when: true
|
||||
|
||||
- name: Enable and start gitea-runner user service
|
||||
ansible.builtin.command: systemctl --user enable --now gitea-runner
|
||||
become: true
|
||||
become_user: "{{ gitea_runner_service_user }}"
|
||||
environment:
|
||||
XDG_RUNTIME_DIR: "/run/user/{{ gitea_runner_uid }}"
|
||||
changed_when: true
|
||||
when: systemd_available.stat.exists
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
---
|
||||
- name: Include gitea_runner download
|
||||
ansible.builtin.include_tasks: download_gitea_runner.yml
|
||||
|
||||
- name: Restart gitea-runner user service
|
||||
ansible.builtin.command: systemctl --user restart gitea-runner
|
||||
become: true
|
||||
become_user: "{{ gitea_runner_service_user }}"
|
||||
environment:
|
||||
XDG_RUNTIME_DIR: "/run/user/{{ gitea_runner_uid }}"
|
||||
when: systemd_available.stat.exists | default(false) | bool
|
||||
changed_when: true
|
||||
@@ -0,0 +1,65 @@
|
||||
---
|
||||
- name: Create per-runner system user
|
||||
ansible.builtin.user:
|
||||
name: "{{ gitea_runner_service_user }}"
|
||||
home: "{{ gitea_runner_home }}"
|
||||
shell: /bin/bash
|
||||
system: true
|
||||
create_home: true
|
||||
register: runner_user
|
||||
|
||||
- name: Set runner UID fact
|
||||
ansible.builtin.set_fact:
|
||||
gitea_runner_uid: "{{ runner_user.uid }}"
|
||||
|
||||
- name: Enable lingering for runner user
|
||||
ansible.builtin.command: loginctl enable-linger {{ gitea_runner_service_user }}
|
||||
changed_when: true
|
||||
|
||||
- name: Ensure subuid entry for runner user
|
||||
ansible.builtin.lineinfile:
|
||||
path: /etc/subuid
|
||||
regexp: "^{{ gitea_runner_service_user }}:"
|
||||
line: "{{ gitea_runner_service_user }}:100000:65536"
|
||||
create: true
|
||||
mode: "0644"
|
||||
|
||||
- name: Ensure subgid entry for runner user
|
||||
ansible.builtin.lineinfile:
|
||||
path: /etc/subgid
|
||||
regexp: "^{{ gitea_runner_service_user }}:"
|
||||
line: "{{ gitea_runner_service_user }}:100000:65536"
|
||||
create: true
|
||||
mode: "0644"
|
||||
|
||||
- name: Ensure XDG_RUNTIME_DIR exists
|
||||
ansible.builtin.file:
|
||||
path: "/run/user/{{ gitea_runner_uid }}"
|
||||
state: directory
|
||||
owner: "{{ gitea_runner_service_user }}"
|
||||
group: "{{ gitea_runner_service_user }}"
|
||||
mode: "0700"
|
||||
|
||||
- name: Ensure runner data directory exists
|
||||
ansible.builtin.file:
|
||||
path: "{{ gitea_runner_data_dir }}"
|
||||
state: directory
|
||||
owner: "{{ gitea_runner_service_user }}"
|
||||
group: "{{ gitea_runner_service_user }}"
|
||||
mode: "0755"
|
||||
|
||||
- name: Ensure runner config directory exists
|
||||
ansible.builtin.file:
|
||||
path: "{{ gitea_runner_config_dir }}"
|
||||
state: directory
|
||||
owner: "{{ gitea_runner_service_user }}"
|
||||
group: "{{ gitea_runner_service_user }}"
|
||||
mode: "0755"
|
||||
|
||||
- name: Ensure systemd user directory exists
|
||||
ansible.builtin.file:
|
||||
path: "{{ gitea_runner_home }}/.config/systemd/user"
|
||||
state: directory
|
||||
owner: "{{ gitea_runner_service_user }}"
|
||||
group: "{{ gitea_runner_service_user }}"
|
||||
mode: "0755"
|
||||
@@ -14,7 +14,12 @@
|
||||
register: gitea_runner_version_output
|
||||
changed_when: false
|
||||
|
||||
- name: Verify Docker connectivity
|
||||
- name: Verify rootless Docker connectivity
|
||||
ansible.builtin.command: docker version
|
||||
become: true
|
||||
become_user: "{{ gitea_runner_service_user }}"
|
||||
environment:
|
||||
DOCKER_HOST: "unix:///run/user/{{ gitea_runner_uid }}/docker.sock"
|
||||
XDG_RUNTIME_DIR: "/run/user/{{ gitea_runner_uid }}"
|
||||
register: docker_version_output
|
||||
changed_when: false
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
[Unit]
|
||||
Description=Docker prune for Gitea runner resources
|
||||
After=docker.service
|
||||
Requires=docker.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
Environment=DOCKER_HOST=unix:///run/user/{{ gitea_runner_uid }}/docker.sock
|
||||
Environment=XDG_RUNTIME_DIR=/run/user/{{ gitea_runner_uid }}
|
||||
ExecStart=/usr/bin/docker system prune -f --filter "label={{ gitea_runner_prune_label }}" --filter "until={{ gitea_runner_prune_until }}"
|
||||
ExecStart=/usr/bin/docker volume prune -f --filter "label={{ gitea_runner_prune_label }}" --filter "until={{ gitea_runner_prune_until }}"
|
||||
|
||||
@@ -8,3 +8,4 @@ runner:
|
||||
|
||||
container:
|
||||
label: "{{ gitea_runner_container_label }}"
|
||||
docker_host: "unix:///run/user/{{ gitea_runner_uid }}/docker.sock"
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
[Unit]
|
||||
Description=Gitea Actions Runner (rootless)
|
||||
After=docker.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart={{ gitea_runner_binary_path }} daemon --config {{ gitea_runner_config_dir }}/config.yaml
|
||||
WorkingDirectory={{ gitea_runner_data_dir }}
|
||||
Environment=DOCKER_HOST=unix:///run/user/{{ gitea_runner_uid }}/docker.sock
|
||||
Environment=XDG_RUNTIME_DIR=/run/user/{{ gitea_runner_uid }}
|
||||
ExecStop=/bin/kill -TERM $MAINPID
|
||||
TimeoutStopSec=30
|
||||
Restart=on-failure
|
||||
RestartSec={{ gitea_runner_service_restart_sec }}
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
@@ -1,35 +0,0 @@
|
||||
[Unit]
|
||||
Description=Gitea Actions Runner %i ({% if runner_mode == 'docker' %}docker{% else %}binary{% endif %})
|
||||
After=network.target{% if runner_mode == 'docker' %} docker.service
|
||||
Requires=docker.service{% endif %}
|
||||
|
||||
[Service]
|
||||
{% if runner_mode == 'docker' %}
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStartPre=-/usr/bin/docker rm -f gitea-runner-%i
|
||||
ExecStart=/usr/bin/docker run -d --name gitea-runner-%i \
|
||||
--restart=no \
|
||||
-v /var/run/docker.sock:/var/run/docker.sock \
|
||||
-v {{ gitea_runner_base_data_dir }}/%i:/data \
|
||||
-w /data \
|
||||
{{ gitea_runner_docker_image }}:{{ gitea_runner_version | regex_replace('^v', '') }} \
|
||||
daemon --config /data/config.yaml
|
||||
ExecStop=/usr/bin/docker stop -t 30 gitea-runner-%i
|
||||
ExecStopPost=-/usr/bin/docker rm -f gitea-runner-%i
|
||||
Restart=on-failure
|
||||
RestartSec={{ gitea_runner_service_restart_sec }}
|
||||
{% else %}
|
||||
Type=simple
|
||||
ExecStart={{ gitea_runner_binary_path }} daemon --config {{ gitea_runner_base_config_dir }}/%i/config.yaml
|
||||
WorkingDirectory={{ gitea_runner_base_data_dir }}/%i
|
||||
ExecStop=/bin/kill -TERM $MAINPID
|
||||
TimeoutStopSec=30
|
||||
Restart=on-failure
|
||||
RestartSec={{ gitea_runner_service_restart_sec }}
|
||||
User={{ gitea_runner_service_user }}
|
||||
Group=docker
|
||||
{% endif %}
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
Reference in New Issue
Block a user