- Front git-over-SSH with host sshd and live key lookup - Build and load custom SELinux policies oci_log and gitea_ssh
324 lines
9.3 KiB
YAML
324 lines
9.3 KiB
YAML
- name: Install Podman with Docker CLI tools
|
|
ansible.builtin.apt:
|
|
name: ["podman", "docker-cli", "docker-compose"]
|
|
state: present
|
|
|
|
- name: Allow rootless containers to use capabilities in their user namespace
|
|
ansible.posix.seboolean:
|
|
name: container_use_userns_all_caps
|
|
state: true
|
|
persistent: true
|
|
when: selinux is defined and selinux is not false
|
|
|
|
- name: Create SELinux policy build directory
|
|
ansible.builtin.file:
|
|
path: "{{ podman_selinux_dir }}"
|
|
state: directory
|
|
owner: root
|
|
group: root
|
|
mode: "0755"
|
|
when: selinux is defined and selinux is not false
|
|
|
|
- name: Install container log SELinux policy source
|
|
ansible.builtin.copy:
|
|
src: oci_log.te
|
|
dest: "{{ podman_selinux_dir }}/oci_log.te"
|
|
owner: root
|
|
group: root
|
|
mode: "0644"
|
|
register: podman_selinux_src
|
|
when: selinux is defined and selinux is not false
|
|
|
|
- name: Clear stale container log SELinux artifacts
|
|
ansible.builtin.file:
|
|
path: "{{ podman_selinux_dir }}/oci_log.{{ item }}"
|
|
state: absent
|
|
loop: [mod, pp]
|
|
when:
|
|
- selinux is defined and selinux is not false
|
|
- podman_selinux_src is changed
|
|
|
|
- name: Compile container log SELinux policy module
|
|
ansible.builtin.command:
|
|
cmd: >-
|
|
checkmodule -M -m -o {{ podman_selinux_dir }}/oci_log.mod
|
|
{{ podman_selinux_dir }}/oci_log.te
|
|
creates: "{{ podman_selinux_dir }}/oci_log.mod"
|
|
when: selinux is defined and selinux is not false
|
|
|
|
- name: Package container log SELinux policy module
|
|
ansible.builtin.command:
|
|
cmd: >-
|
|
semodule_package -o {{ podman_selinux_dir }}/oci_log.pp
|
|
-m {{ podman_selinux_dir }}/oci_log.mod
|
|
creates: "{{ podman_selinux_dir }}/oci_log.pp"
|
|
when: selinux is defined and selinux is not false
|
|
|
|
- name: List loaded SELinux policy modules
|
|
ansible.builtin.command:
|
|
cmd: semodule -l
|
|
register: podman_semodule_list
|
|
changed_when: false
|
|
when: selinux is defined and selinux is not false
|
|
|
|
- name: Load container log SELinux policy module
|
|
ansible.builtin.command:
|
|
cmd: semodule -i {{ podman_selinux_dir }}/oci_log.pp
|
|
register: podman_semodule
|
|
changed_when: podman_semodule.rc == 0
|
|
when:
|
|
- selinux is defined and selinux is not false
|
|
- podman_selinux_src is changed or "oci_log" not in podman_semodule_list.stdout_lines
|
|
|
|
- name: Set SELinux context on container log directory
|
|
community.general.sefcontext:
|
|
target: "{{ podman_log_root }}(/.*)?"
|
|
setype: oci_log_t
|
|
state: present
|
|
when: selinux is defined and selinux is not false
|
|
|
|
- name: Create container log directory
|
|
ansible.builtin.file:
|
|
path: "{{ podman_log_root }}"
|
|
state: directory
|
|
owner: root
|
|
group: root
|
|
mode: "0755"
|
|
setype: >-
|
|
{{ (selinux is defined and selinux is not false)
|
|
| ternary('oci_log_t', omit) }}
|
|
|
|
- name: Install GnuPG tools and trusted CA bundle
|
|
ansible.builtin.apt:
|
|
name: ["gnupg", "ca-certificates"]
|
|
state: present
|
|
when: podman_compose is defined
|
|
|
|
- name: Get podman user info for user namespace configuration
|
|
ansible.builtin.getent:
|
|
database: passwd
|
|
key: "{{ item }}"
|
|
loop: "{{ podman_compose.keys() | list }}"
|
|
register: user_info
|
|
loop_control:
|
|
label: "{{ item }}"
|
|
when: podman_compose is defined
|
|
|
|
- name: Set subuid base facts for podman users
|
|
ansible.builtin.set_fact:
|
|
podman_subuid_base: "{{ podman_subuid_base | default({}) | combine({
|
|
item.item: 100000 + ((item.ansible_facts.getent_passwd[item.item][1]
|
|
| int - 1000) * 65536) }) }}"
|
|
loop: "{{ user_info.results }}"
|
|
loop_control:
|
|
label: "{{ item.item }}"
|
|
|
|
- name: Configure /etc/subuid for rootless users
|
|
ansible.builtin.lineinfile:
|
|
path: "/etc/subuid"
|
|
line: "{{ item.item }}:{{ podman_subuid_base[item.item] }}:65536"
|
|
regexp: "^{{ item.item }}:"
|
|
create: true
|
|
backup: true
|
|
mode: "0644"
|
|
loop: "{{ user_info.results }}"
|
|
loop_control:
|
|
label: "{{ item.item }}"
|
|
|
|
- name: Configure /etc/subgid for rootless users
|
|
ansible.builtin.lineinfile:
|
|
path: "/etc/subgid"
|
|
line: "{{ item.item }}:{{ podman_subuid_base[item.item] }}:65536"
|
|
regexp: "^{{ item.item }}:"
|
|
create: true
|
|
backup: true
|
|
mode: "0644"
|
|
loop: "{{ user_info.results }}"
|
|
loop_control:
|
|
label: "{{ item.item }}"
|
|
|
|
- name: Ensure systemd linger directory exists
|
|
ansible.builtin.file:
|
|
path: /var/lib/systemd/linger
|
|
state: directory
|
|
owner: root
|
|
group: root
|
|
mode: "0755"
|
|
|
|
- name: Enable lingering for podman compose users
|
|
ansible.builtin.file:
|
|
path: "/var/lib/systemd/linger/{{ item.item }}"
|
|
state: touch
|
|
owner: root
|
|
group: root
|
|
mode: "0644"
|
|
access_time: preserve
|
|
modification_time: preserve
|
|
loop: "{{ user_info.results }}"
|
|
loop_control:
|
|
label: "{{ item.item }}"
|
|
|
|
- name: Start user manager for podman compose users
|
|
ansible.builtin.systemd_service:
|
|
name: "user@{{ item.ansible_facts.getent_passwd[item.item][1] }}.service"
|
|
state: started
|
|
loop: "{{ user_info.results }}"
|
|
loop_control:
|
|
label: "{{ item.item }}"
|
|
|
|
- name: Wait for user runtime directory
|
|
ansible.builtin.wait_for:
|
|
path: "/run/user/{{ item.ansible_facts.getent_passwd[item.item][1] }}/bus"
|
|
timeout: 30
|
|
loop: "{{ user_info.results }}"
|
|
loop_control:
|
|
label: "{{ item.item }}"
|
|
|
|
- name: Start and enable the Podman socket
|
|
ansible.builtin.systemd:
|
|
name: podman.socket
|
|
state: started
|
|
enabled: true
|
|
scope: user
|
|
vars:
|
|
uid: "{{ item.ansible_facts.getent_passwd[item.item][1] }}"
|
|
environment:
|
|
XDG_RUNTIME_DIR: "/run/user/{{ uid }}"
|
|
DBUS_SESSION_BUS_ADDRESS: "unix:path=/run/user/{{ uid }}/bus"
|
|
become: true
|
|
become_user: "{{ item.item }}"
|
|
loop: "{{ user_info.results }}"
|
|
loop_control:
|
|
label: "{{ item.item }}"
|
|
|
|
- name: Create global containers config directory
|
|
ansible.builtin.file:
|
|
path: /etc/containers
|
|
state: directory
|
|
mode: "0755"
|
|
|
|
- name: Configure global containers.conf for rootless
|
|
ansible.builtin.copy:
|
|
content: |
|
|
[engine]
|
|
cgroup_manager = "cgroupfs"
|
|
events_logger = "journald"
|
|
runtime = "crun"
|
|
dest: /etc/containers/containers.conf
|
|
backup: true
|
|
mode: "0644"
|
|
|
|
- name: Configure Docker CLI to use rootless Podman socket
|
|
ansible.builtin.copy:
|
|
src: files/docker-host.sh
|
|
dest: /etc/profile.d/docker-host.sh
|
|
owner: root
|
|
group: root
|
|
mode: "0755"
|
|
|
|
- name: Install git for repository cloning
|
|
ansible.builtin.apt:
|
|
name: git
|
|
state: present
|
|
when: podman_compose is defined
|
|
|
|
- name: Login to private Podman registries with Docker CLI for each user
|
|
ansible.builtin.include_tasks: login.yml
|
|
loop: "{{ podman_login | dict2items }}"
|
|
loop_control:
|
|
loop_var: podman_user
|
|
when: podman_login is defined
|
|
|
|
- name: Stat rootless Podman directory
|
|
ansible.builtin.stat:
|
|
path: "/home/{{ compose_user.key }}/.local/share/containers"
|
|
loop: "{{ podman_compose | dict2items }}"
|
|
loop_control:
|
|
loop_var: compose_user
|
|
label: "{{ compose_user.key }}"
|
|
register: podman_user_containers_stat
|
|
when:
|
|
- podman_compose is defined
|
|
- selinux is defined
|
|
- selinux is not false
|
|
|
|
- name: Create rootless Podman directory
|
|
ansible.builtin.file:
|
|
path: "/home/{{ item.compose_user.key }}/.local/share/containers"
|
|
state: directory
|
|
owner: "{{ item.compose_user.key }}"
|
|
group: "{{ item.compose_user.key }}"
|
|
mode: "700"
|
|
loop: "{{ podman_user_containers_stat.results }}"
|
|
loop_control:
|
|
label: "{{ item.compose_user.key }}"
|
|
when:
|
|
- podman_compose is defined
|
|
- selinux is defined
|
|
- selinux is not false
|
|
- not item.stat.exists
|
|
|
|
- name: Label rootless Podman directory
|
|
ansible.builtin.command: >-
|
|
restorecon -Rv /home/{{ item.compose_user.key }}/.local/share/containers
|
|
loop: "{{ podman_user_containers_stat.results }}"
|
|
loop_control:
|
|
label: "/home/{{ item.compose_user.key }}/.local/share/containers"
|
|
changed_when: true
|
|
when:
|
|
- podman_compose is defined
|
|
- selinux is defined
|
|
- selinux is not false
|
|
- not item.stat.exists
|
|
|
|
- name: Stat Podman label directories
|
|
ansible.builtin.stat:
|
|
path: "{{ item.path }}"
|
|
loop: "{{ podman_label }}"
|
|
register: podman_label_stat
|
|
loop_control:
|
|
label: "{{ item.path }}"
|
|
when:
|
|
- podman_label is defined
|
|
- selinux is defined
|
|
- selinux is not false
|
|
|
|
- name: Create Podman label directories
|
|
ansible.builtin.file:
|
|
path: "{{ item.item.path }}"
|
|
owner: "{{ item.item.owner | default(omit) }}"
|
|
group: "{{ item.item.group | default(omit) }}"
|
|
mode: "{{ item.item.mode | default('700') }}"
|
|
state: directory
|
|
loop: "{{ podman_label_stat.results }}"
|
|
loop_control:
|
|
label: "{{ item.item.path }}"
|
|
when:
|
|
- podman_label is defined
|
|
- selinux is defined
|
|
- selinux is not false
|
|
- not item.stat.exists
|
|
|
|
- name: Set labels on Podman label directories
|
|
ansible.builtin.command: "chcon {{ item.item.label }} {{ item.item.path }}"
|
|
loop: "{{ podman_label_stat.results }}"
|
|
changed_when: true
|
|
loop_control:
|
|
label: "{{ item.item.path }} => {{ item.item.label }}"
|
|
when:
|
|
- podman_label is defined
|
|
- selinux is defined
|
|
- selinux is not false
|
|
- not item.stat.exists
|
|
|
|
- name: Deploy Podman compose projects for each user
|
|
ansible.builtin.include_tasks: deploy.yml
|
|
vars:
|
|
podman_user: "{{ compose_user.key }}"
|
|
podman_compose_config: "{{ compose_user.value }}"
|
|
loop: "{{ podman_compose | dict2items }}"
|
|
loop_control:
|
|
loop_var: compose_user
|
|
when: podman_compose is defined
|
|
tags: podman_compose
|