diff --git a/ansible/roles/gitea-actions/tasks/user.yml b/ansible/roles/gitea-actions/tasks/user.yml index a4e88c9..e7f6520 100644 --- a/ansible/roles/gitea-actions/tasks/user.yml +++ b/ansible/roles/gitea-actions/tasks/user.yml @@ -69,3 +69,50 @@ group: "{{ gitea_runner_user }}" mode: "0644" tags: gitea-actions + +# CI jobs run in ephemeral rootless-podman containers that don't inherit the +# gitea-runner user's ~/.ssh. Stage a dedicated, SELinux-labelled copy of the +# runner's key + known_hosts and bind-mount it read-only into every job +# container at /root/.ssh (see config.yaml.j2) so submodule clones over +# ssh://git@git.skudak.com:2222 work. Kept separate from ~/.ssh so the real +# directory's label is never touched. +- name: create ci-ssh dir for job-container mount + become: true + ansible.builtin.file: + path: "{{ gitea_runner_home }}/ci-ssh" + state: directory + owner: "{{ gitea_runner_user }}" + group: "{{ gitea_runner_user }}" + mode: "0700" + tags: gitea-actions + +- name: stage runner ssh material into ci-ssh + become: true + ansible.builtin.copy: + src: "{{ gitea_runner_home }}/.ssh/{{ item.name }}" + dest: "{{ gitea_runner_home }}/ci-ssh/{{ item.name }}" + remote_src: true + owner: "{{ gitea_runner_user }}" + group: "{{ gitea_runner_user }}" + mode: "{{ item.mode }}" + loop: + - { name: id_ed25519, mode: "0600" } + - { name: known_hosts, mode: "0644" } + notify: restart act_runner services + tags: gitea-actions + +- name: label ci-ssh as container_file_t so job containers can read it + become: true + community.general.sefcontext: + target: "{{ gitea_runner_home }}/ci-ssh(/.*)?" + setype: container_file_t + state: present + register: ci_ssh_sefcontext + tags: gitea-actions + +- name: apply selinux label to ci-ssh + become: true + ansible.builtin.command: restorecon -RF {{ gitea_runner_home }}/ci-ssh + when: ci_ssh_sefcontext is changed + changed_when: true + tags: gitea-actions diff --git a/ansible/roles/gitea-actions/templates/Containerfile.ci b/ansible/roles/gitea-actions/templates/Containerfile.ci index b7d092e..12f4440 100644 --- a/ansible/roles/gitea-actions/templates/Containerfile.ci +++ b/ansible/roles/gitea-actions/templates/Containerfile.ci @@ -7,7 +7,8 @@ ARG DOCKER_CLI_VERSION=27.3.1 RUN apt-get update && apt-get install -y --no-install-recommends \ ca-certificates curl git openssh-client make build-essential \ - python3 python3-pip jq zip unzip \ + python3 python3-pip python3-yaml python3-jinja2 jq zip unzip \ + gcc-arm-none-eabi binutils-arm-none-eabi libnewlib-arm-none-eabi \ && rm -rf /var/lib/apt/lists/* # Static docker client (no daemon) for jobs that run `docker build` against the diff --git a/ansible/roles/gitea-actions/templates/config.yaml.j2 b/ansible/roles/gitea-actions/templates/config.yaml.j2 index ddca565..32d15e4 100644 --- a/ansible/roles/gitea-actions/templates/config.yaml.j2 +++ b/ansible/roles/gitea-actions/templates/config.yaml.j2 @@ -23,9 +23,16 @@ container: # per-job Go module/build caches and fixes cross-repo cache poisoning. network: host privileged: false - options: + # Bind-mount the runner's SSH material (key + known_hosts) read-only into + # every job container at /root/.ssh (CI image runs as root) so git submodule + # clones over ssh://git@git.skudak.com:2222 succeed. ci-ssh is a dedicated + # container_file_t-labelled copy staged in tasks/user.yml. + options: -v {{ gitea_runner_home }}/ci-ssh:/root/.ssh:ro workdir_parent: - valid_volumes: [] + # act_runner gates host bind-mounts against this allowlist; the ci-ssh source + # path must be listed or the -v above is silently stripped from the job container. + valid_volumes: + - {{ gitea_runner_home }}/ci-ssh # Point act at the real rootless socket so it mounts the correct path into # job containers (the documented rootless-podman gotcha). docker_host: "unix:///run/user/{{ gitea_runner_uid }}/podman/podman.sock"