Compare commits

...

2 commits

Author SHA1 Message Date
25fb8d345d
Add Woodpecker agent role 2024-11-17 14:02:38 +01:00
4560ccbbb7
Add Woodpecker server role 2024-11-17 14:02:01 +01:00
16 changed files with 268 additions and 0 deletions

View file

@ -0,0 +1,3 @@
---
podman_woodpecker_version: v2.7.1-alpine
podman_woodpecker_user: podman

View file

@ -0,0 +1,63 @@
---
- name: Create Woodpecker volume
containers.podman.podman_volume:
name: "{{ item }}"
state: present
loop:
- woodpecker
- logs
- name: Create Woodpecker Forgejo client secret
containers.podman.podman_secret:
name: woodpecker-forgejo-secret
state: present
data: "{{ podman_woodpecker_forgejo_client_secret }}"
skip_existing: true
- name: Create Woodpecker agent secret
containers.podman.podman_secret:
state: present
name: woodpecker-agent-secret
data: "{{ podman_woodpecker_agent_secret }}"
skip_existing: true
- name: Create Woodpecker container
containers.podman.podman_container:
name: woodpecker
state: present
image: docker.io/woodpeckerci/woodpecker-server:{{ podman_woodpecker_version }}
volumes:
- 'woodpecker:/var/lib/woodpecker'
- 'logs:/var/lib/woodpecker/logs'
- '/etc/timezone:/etc/timezone:ro'
- '/etc/localtime:/etc/localtime:ro'
ports:
- "3001:8000"
- "3002:9000"
env:
WOODPECKER_HOST: "{{ podman_woodpecker_host }}"
WOODPECKER_ADMIN: "{{ podman_woodpecker_admin }}"
WOODPECKER_OPEN: true
WOODPECKER_AGENT_SECRET_FILE: /run/secrets/woodpecker-agent-secret
WOODPECKER_FORGEJO: true
WOODPECKER_FORGEJO_URL: "{{ podman_woodpecker_forgejo_url }}"
WOODPECKER_FORGEJO_CLIENT: "{{ podman_woodpecker_forgejo_client_id }}"
WOODPECKER_LOG_STORE: file
WOODPECKER_LOG_STORE_FILE_PATH: /var/lib/woodpecker/logs
secrets:
# There is no *_FILE variable to mount the Forgejo secret, so use envvar instead.
- woodpecker-forgejo-secret,type=env,target=WOODPECKER_FORGEJO_SECRET
- woodpecker-agent-secret
# Gracefully stopping the gRPC handler might take some time; 2m30 is excessive but sufficient.
stop_timeout: 150
generate_systemd:
restart_policy: always
path: ~/.config/systemd/user
- name: Start and enable Woodpecker
ansible.builtin.systemd_service:
name: container-woodpecker.service
daemon_reload: true
state: started
enabled: true
scope: user

View file

@ -0,0 +1,6 @@
---
- name: Configure Woodpecker service
ansible.builtin.import_tasks: machinectl.yml
become_method: community.general.machinectl
become_user: "{{ podman_woodpecker_user }}"
become: true

View file

@ -0,0 +1,3 @@
---
podman_woodpecker_agent_filter_labels: ""
podman_woodpecker_agent_image_path: docker.io/woodpeckerci/woodpecker-agent

View file

@ -0,0 +1,12 @@
---
- name: Reload systemd daemon
ansible.builtin.systemd_service:
daemon_reload: true
- name: Reload user systemd daemon
ansible.builtin.systemd_service:
daemon_reload: true
scope: user
become_method: community.general.machinectl
become_user: "{{ podman_woodpecker_agent_user }}"
become: true

View file

@ -0,0 +1,11 @@
---
- name: Determine UID of workspace user
ansible.builtin.user:
name: "{{ workspace_user }}"
register: user_data
- name: Activate Podman socket proxy for the workspace
ansible.builtin.systemd_service:
name: woodpecker-proxy@{{ user_data['uid'] }}.path
state: started
enabled: true

View file

@ -0,0 +1,60 @@
---
- name: Create Woodpecker agent volume
containers.podman.podman_volume:
name: "woodpecker-agent-{{ workspace_user }}"
state: present
- name: Create Woodpecker agent secret
containers.podman.podman_secret:
state: present
name: "woodpecker-agent-secret-{{ workspace_user }}"
data: "{{ podman_woodpecker_agent_secret }}"
# Necessary to make the module idempotent on Podman < v4.7
# See: https://github.com/containers/ansible-podman-collections/issues/692
skip_existing: true
- name: Determine UID of workspace user
ansible.builtin.user:
name: "{{ workspace_user }}"
register: user_data
- name: Create Woodpecker container
containers.podman.podman_container:
name: "woodpecker-agent-{{ user_data['uid'] }}"
state: present
image: "{{ podman_woodpecker_agent_image_path }}:{{ podman_woodpecker_version }}"
volumes:
- 'woodpecker-agent-{{ workspace_user }}:/etc/woodpecker'
- '/etc/timezone:/etc/timezone:ro'
- '/etc/localtime:/etc/localtime:ro'
- "/run/woodpecker/{{ user_data['uid'] }}.sock:/var/run/docker.sock"
env:
WOODPECKER_SERVER: "{{ podman_woodpecker_agent_server }}"
WOODPECKER_HOSTNAME: "{{ workspace_user }}"
# Nothing is using the healthcheck IIUC, so disabling it doesn't reduce functionality.
WOODPECKER_HEALTHCHECK: false
WOODPECKER_LOG_LEVEL: debug
WOODPECKER_BACKEND: docker
WOODPECKER_FILTER_LABELS: "{{ podman_woodpecker_agent_filter_labels }}"
secrets:
- "woodpecker-agent-secret-{{ workspace_user }},type=env,target=WOODPECKER_AGENT_SECRET"
generate_systemd:
restart_policy: always
path: ~/.config/systemd/user
after: "podman-proxy@{{ user_data['uid'] }}.target"
requires: "podman-proxy@{{ user_data['uid'] }}.target"
notify: Reload user systemd daemon
- name: Flush handlers
ansible.builtin.meta: flush_handlers
- name: Start and enable Woodpecker services
ansible.builtin.systemd_service:
name: "{{ item }}"
daemon_reload: true
state: started
enabled: true
scope: user
loop:
- "podman-proxy@{{ user_data['uid'] }}.path"
- "container-woodpecker-agent-{{ user_data['uid'] }}.service"

View file

@ -0,0 +1,22 @@
---
- name: Create systemd user configuration directory
ansible.builtin.file:
dest: ~/.config/systemd/user
state: directory
mode: "0750"
- name: Install systemd unit files for the proxy target
ansible.builtin.template:
src: "{{ item }}.j2"
dest: "~/.config/systemd/user/{{ item }}"
mode: "0644"
notify: Reload user systemd daemon
loop:
- podman-proxy@.path
- podman-proxy@.target
- name: Create Woodpecker agents
ansible.builtin.include_tasks: agents.yml
loop: "{{ podman_woodpecker_agent_workspace_users }}"
loop_control:
loop_var: workspace_user

View file

@ -0,0 +1,20 @@
---
- name: Configure proxies for the Podman sockets
ansible.builtin.import_tasks: socket-proxy.yml
- name: Activate the workspace Podman systemd socket unit
ansible.builtin.systemd_service:
name: podman.socket
state: started
enabled: true
scope: user
become_method: community.general.machinectl
become_user: "{{ item }}"
become: true
loop: "{{ podman_woodpecker_agent_workspace_users }}"
- name: Configure Woodpecker agent services
ansible.builtin.import_tasks: machinectl.yml
become_method: community.general.machinectl
become_user: "{{ podman_woodpecker_agent_user }}"
become: true

View file

@ -0,0 +1,26 @@
---
- name: Install proxy systemd units
ansible.builtin.template:
src: "{{ item }}.j2"
dest: "/etc/systemd/system/{{ item }}"
mode: "0644"
loop:
- woodpecker-proxy@.path
- woodpecker-proxy@.service
- woodpecker-proxy@.socket
notify: Reload systemd daemon
- name: Flush handlers
ansible.builtin.meta: flush_handlers
- name: Install tmpfiles configuration
ansible.builtin.template:
src: tmpfiles.j2
dest: /etc/tmpfiles.d/woodpecker.conf
mode: "0644"
- name: Activate systemd units for the Podman sockets
ansible.builtin.include_tasks: activate-proxies.yml
loop: "{{ podman_woodpecker_agent_workspace_users }}"
loop_control:
loop_var: workspace_user

View file

@ -0,0 +1,10 @@
# {{ ansible_managed }}
[Unit]
Description=Watch for the creation of the workspace user Podman socket
[Path]
PathExists=/run/woodpecker/%i.sock
Unit=podman-proxy@%i.target
[Install]
WantedBy=default.target

View file

@ -0,0 +1,3 @@
# {{ ansible_managed }}
[Unit]
Description=The proxied socket to the Podman service is available to be mounted

View file

@ -0,0 +1,2 @@
# {{ ansible_managed }}
D /run/woodpecker 0750 root woodpecker-agent

View file

@ -0,0 +1,10 @@
# {{ ansible_managed }}
[Unit]
Description=Watch for the creation of the workspace user Podman socket
[Path]
PathExists=/run/user/%i/podman/podman.sock
Unit=woodpecker-proxy@%i.socket
[Install]
WantedBy=multi-user.target

View file

@ -0,0 +1,9 @@
# {{ ansible_managed }}
[Unit]
Requires=woodpecker-proxy@%i.socket
After=woodpecker-proxy@%i.socket
[Service]
ExecStart=/usr/lib/systemd/systemd-socket-proxyd /run/user/%i/podman/podman.sock
PrivateTmp=yes
PrivateNetwork=yes

View file

@ -0,0 +1,8 @@
# {{ ansible_managed }}
[Unit]
Description=Proxy connections
[Socket]
ListenStream=/run/woodpecker/%i.sock
SocketMode=0660
SocketUser={{ podman_woodpecker_agent_user }}