diff --git a/ansible/roles/gitea_runner/defaults/main.yml b/ansible/roles/gitea_runner/defaults/main.yml index 92f8111..184a1bd 100644 --- a/ansible/roles/gitea_runner/defaults/main.yml +++ b/ansible/roles/gitea_runner/defaults/main.yml @@ -66,6 +66,15 @@ gitea_runner_log_level: "info" gitea_runner_container_label: "gitea-runner=true" gitea_runner_file: ".runner" +# Containerd version pinning — Docker 28.x vendors containerd v2.1.x internally. +# containerd.io >= 2.3 ships a shim that returns a protobuf BootstrapResult which +# Docker 28.x's vendored containerd code cannot parse, causing: +# "failed to create TTRPC connection: unsupported protocol: \b\x03\x12Yunix" +# When Docker 29+ is installed (it vendors containerd 2.3+), this pin is not needed. +# Set to "" to skip the compatibility check and allow any containerd.io version. +gitea_runner_containerd_max_compatible_major: 2 +gitea_runner_containerd_max_compatible_minor: 2 + # Docker installation (for rootless dependencies) gitea_runner_docker_gpg_key_path: "/etc/apt/keyrings/docker.gpg" gitea_runner_docker_apt_arch: "{{ 'amd64' if ansible_facts['architecture'] == 'x86_64' else ansible_facts['architecture'] }}" diff --git a/ansible/roles/gitea_runner/tasks/rootless_docker.yml b/ansible/roles/gitea_runner/tasks/rootless_docker.yml index 8f087dc..42ae55f 100644 --- a/ansible/roles/gitea_runner/tasks/rootless_docker.yml +++ b/ansible/roles/gitea_runner/tasks/rootless_docker.yml @@ -53,6 +53,72 @@ register: gitea_runner_docker_install when: ansible_facts['os_family'] == 'Debian' +# Docker 28.x vendors containerd v2.1.x. containerd.io >= 2.3 ships a shim that +# returns a protobuf BootstrapResult the vendored 2.1.x code cannot parse, causing +# "failed to create TTRPC connection: unsupported protocol" on every container start. +# Detect the mismatch and downgrade containerd.io to the latest compatible 2.2.x. +- name: Check installed Docker CE version (Debian/Ubuntu) + ansible.builtin.command: dpkg-query -W -f='${Version}' docker-ce + register: gitea_runner_docker_version_check + changed_when: false + when: ansible_facts['os_family'] == 'Debian' + +- name: Check installed containerd.io version (Debian/Ubuntu) + ansible.builtin.shell: "set -o pipefail; dpkg-query -W -f='${Version}' containerd.io 2>/dev/null | cut -d: -f2 | cut -d- -f1" + args: + executable: /bin/bash + register: gitea_runner_containerd_version_check + changed_when: false + when: ansible_facts['os_family'] == 'Debian' + +- name: Determine if containerd.io is incompatible with installed Docker + ansible.builtin.set_fact: + gitea_runner_containerd_needs_downgrade: >- + {{ + gitea_runner_containerd_version_check.stdout.split('.')[0] | int > gitea_runner_containerd_max_compatible_major + or ( + gitea_runner_containerd_version_check.stdout.split('.')[0] | int == gitea_runner_containerd_max_compatible_major + and gitea_runner_containerd_version_check.stdout.split('.')[1] | int > gitea_runner_containerd_max_compatible_minor + ) + }} + gitea_runner_docker_major: "{{ gitea_runner_docker_version_check.stdout.split('.')[0] | default('0') | int }}" + when: ansible_facts['os_family'] == 'Debian' + +- name: Find latest compatible containerd.io version (Debian/Ubuntu) + ansible.builtin.shell: | + set -o pipefail + apt-cache madison containerd.io \ + | awk -F'|' '{print $2}' \ + | tr -d ' ' \ + | grep -E '^{{ gitea_runner_containerd_max_compatible_major }}\.{{ gitea_runner_containerd_max_compatible_minor }}\.' \ + | head -1 + args: + executable: /bin/bash + register: gitea_runner_containerd_compatible_version + changed_when: false + when: + - ansible_facts['os_family'] == 'Debian' + - gitea_runner_containerd_needs_downgrade | default(false) + - gitea_runner_docker_major | int < 29 + +- name: Downgrade containerd.io to compatible version (Debian/Ubuntu) + ansible.builtin.apt: + name: "containerd.io={{ gitea_runner_containerd_compatible_version.stdout }}" + state: present + allow_downgrades: true + register: gitea_runner_containerd_downgrade + when: + - ansible_facts['os_family'] == 'Debian' + - gitea_runner_containerd_needs_downgrade | default(false) + - gitea_runner_docker_major | int < 29 + - gitea_runner_containerd_compatible_version.stdout | length > 0 + +- name: Hold containerd.io package to prevent auto-upgrade (Debian/Ubuntu) + ansible.builtin.dpkg_selections: + name: containerd.io + selection: hold + when: ansible_facts['os_family'] == 'Debian' + - name: Update pacman cache (Arch Linux) community.general.pacman: update_cache: true