Compare commits

...

6 Commits

Author SHA1 Message Date
801b9b4cb9 feat: Add rootful capability 2026-04-20 19:01:37 +02:00
da83cf1e00 feat: Move from Debian to Fedora 2026-04-14 18:45:49 +02:00
560a6d31e6 feat: Manage podman networks 2026-04-10 11:39:13 +02:00
5b872ba3cb fix: Review CoreOS compatibility 2025-04-15 14:22:51 +02:00
3cfe5831f2 fix: Bad file permissions 2025-02-27 18:18:27 +01:00
745fd321ea feat: Switch to CoreOS 2025-02-27 15:18:25 +01:00
11 changed files with 256 additions and 256 deletions

114
README.md
View File

@@ -1,82 +1,66 @@
# role_podman # role_podman
Rôle de déploiement de podman. Deploy podman, manage pods and containers.
## Pré-requis
Ce rôle créer un utilisateur dédié via [cet autre rôle](https://gitea.ykn.fr/ansible/role_users) dont il est dépendant.
L'utilisation de ce rôle et de sa dépendance dans un playbook nécessite d'utilise ansible-galaxy en lui indiquant un fichier dont le contenu est le suivant :
```bash
$ cd playbook_podman
$ tee requirements.yml <<EOF
---
roles:
- name: users
scm: git
src: ssh://gitea@git.ykn.fr:12393/ansible/role_users.git
version: alpha
- name: podman
scm: git
src: ssh://gitea@git.ykn.fr:12393/ansible/role_podman.git
version: alpha
EOF
$ ansible-galaxy install -fr requirements.yml
```
## Variables ## Variables
### podman_configure_rsyslog ### podman_auto_update
Désactive les messages du programme *podman* et des programmes dans les conteneurs si ils portent le nom du conteneur. Status of the automatic container update service.
<span style="text-decoration: underline">Valeur par défaut:</span> `true` (activé, `false` pour désactiver) <span style="text-decoration: underline">Default value:</span> `true
### podman_pods
List of dictionnaries to define pods ([see ansible documentation](https://docs.ansible.com/ansible/latest/collections/containers/podman/podman_pod_module.html)).
<span style="text-decoration: underline">Default value:</span> none
### podman_containers ### podman_containers
Définition des conteneurs à déployer. List of dictionnaries to define containers ([see ansible documentation](https://docs.ansible.com/ansible/latest/collections/containers/podman/podman_container_module.html#ansible-collections-containers-podman-podman-container-module)).
<span style="text-decoration: underline">Valeur par défaut:</span> *aucune* <span style="text-decoration: underline">Default value:</span> none
## Utilisation ## Usage
Définir la variable `podman_containers` dans un fichier sous `host_vars` ou `group_vars` : To deploy *wg-easy* container:
```bash
$ tee host_vars/lxd_podman_host.yml <<EOF
---
```yml
# BEGIN role_podman
podman_containers: podman_containers:
- image: docker.io/wallabag/wallabag:latest - image: "ghcr.io/wg-easy/wg-easy:latest"
name: wallbag name: wg-easy
userns: keep-id publish:
- "51820:51820/udp"
- "51821:51821/tcp"
volumes: volumes:
- wallbag-data:/var/www/wallabag/data - "/srv/wg-easy:/etc/wireguard"
- wallbag-image:/var/www/wallabag/web/assets/images env:
ports: LANG: fr
- 80:80/tcp PORT: 51821
environment_vars: UI_CHART_TYPE: 2
- SYMFONY__ENV__DOMAIN_NAME=https://wallbag.ykn.fr PASSWORD_HASH: <secret>
``` WG_HOST: noun.ykn.fr
WG_PORT: 51820
Il est également possible de définir l'utilisateur via la variable `user`, comme ceci : WG_PERSISTENT_KEEPALIVE: 25
WG_DEFAULT_DNS: ""
```bash WG_ALLOWED_IPS: 192.168.84.0/24
$ tee host_vars/lxd_podman_host.yml <<EOF cap_add:
--- - NET_ADMIN
- NET_RAW
podman_containers: - SYS_MODULE
- image: docker.io/wallabag/wallabag:latest sysctl:
name: wallbag net.ipv4.ip_forward: 1
user: un_utilisateur net.ipv4.conf.all.src_valid_mark: 1
userns: keep-id quadlet_options:
volumes: - AutoUpdate=registry
- wallbag-data:/var/www/wallabag/data - |-
- wallbag-image:/var/www/wallabag/web/assets/images [Service]
ports: Restart=on-failure
- 80:80/tcp TimeoutStartSec=900
environment_vars: - |-
- SYMFONY__ENV__DOMAIN_NAME=https://wallbag.ykn.fr [Install]
WantedBy=default.target
# END role_podman
``` ```

View File

@@ -1,25 +1,24 @@
--- ---
# defaults file for podman # defaults file for podman
podman_configure_rsyslog: true # Packages to install to run podman
podman_fix_pasta: true podman_packages:
- podman
- policycoreutils-python-utils # to manage SELinux
podman_ssh_host: "{{ inventory_hostname }}" # Dedicated user
podman_ssh_port: 22 podman_user: podman
podman_user_homedir: /home/{{ podman_user }}
# Enable container auto-update
podman_auto_update: true podman_auto_update: true
podman_containers: [] # List of quadlets to deploy
# Exemple: podman_quadlets_rootless: []
# - image: docker.io/wallabag/wallabag:latest # Example:
# name: wallbag # podman_quadlets:
# userns: keep-id # - uptime-kuma.network
# commands: # - uptime-kuma.container
# - echo toto # - signal-cli-rest-api.container
# volumes:
# - wallbag-data:/var/www/wallabag/data podman_quadlets_rootful: []
# - wallbag-image:/var/www/wallabag/web/assets/images
# ports:
# - 80:80/tcp
# environment_vars:
# - SYMFONY__ENV__DOMAIN_NAME=https://wallbag.ykn.fr

View File

@@ -1,32 +1,42 @@
--- ---
# handlers file for exim4 # handlers file for podman
# source: https://github.com/containers/buildah/issues/5440#issuecomment-2028911573 - name: Start or restart rootless quadlets
- name: Corriger le problème passt VS pasta ansible.builtin.systemd_service:
ansible.builtin.file: name: "{{ unit }}"
state: hard state: "{{ 'restarted' if item.changed else 'started' }}"
force: true daemon_reload: true
src: /usr/bin/passt enabled: true
dest: /usr/bin/pasta scope: user
when: podman_fix_pasta
become: true become: true
become_user: "{{ podman_user }}"
loop: "{{ deployed_quadlets_rootless.results }}"
loop_control:
label: "{{ unit }}"
vars:
unit: >-
{{
item.item | ansible.builtin.basename |
ansible.builtin.regex_replace('\.container$', '.service') |
ansible.builtin.regex_replace('\.network$', '-network.service') |
ansible.builtin.regex_replace('\.volume$', '-volume.service')
}}
- name: Redémarrer l'instance - name: Start or restart rootful quadlets
ansible.builtin.reboot: ansible.builtin.systemd_service:
become: true name: "{{ unit }}"
state: "{{ 'restarted' if item.changed else 'started' }}"
- name: Attendre que le port SSH soit ouvert daemon_reload: true
ansible.builtin.wait_for: enabled: true
host: "{{ podman_ssh_host }}"
port: "{{ podman_ssh_port }}"
search_regex: OpenSSH
delay: 30
timeout: 900
sleep: 10
delegate_to: 127.0.0.1
- name: Redémarrer rsyslog.service
ansible.builtin.systemd:
state: restarted
name: rsyslog.service
become: true become: true
loop: "{{ deployed_quadlets_rootful.results }}"
loop_control:
label: "{{ unit }}"
vars:
unit: >-
{{
item.item | ansible.builtin.basename |
ansible.builtin.regex_replace('\.container$', '.service') |
ansible.builtin.regex_replace('\.network$', '-network.service') |
ansible.builtin.regex_replace('\.volume$', '-volume.service')
}}

View File

@@ -1,15 +1,15 @@
galaxy_info: galaxy_info:
namespace: ykn namespace: ykn
author: pulsar89.5 author: pulsar89.5
description: Rôle de déploiement de podman description: Deploy podman quadlets
license: GPL-3.0-or-later license: GPL-3.0-or-later
min_ansible_version: '2.1' min_ansible_version: '2.1'
platforms: platforms:
- name: Debian - name: Fedora
versions: versions:
- bookworm - "43"
dependencies: [] dependencies: []

54
tasks/config.yml Normal file
View File

@@ -0,0 +1,54 @@
---
# tasks file for podman
- name: Create dedicated group
ansible.builtin.group:
name: "{{ podman_user }}"
become: true
- name: Create dedicated user
ansible.builtin.user:
name: "{{ podman_user }}"
comment: Dedicated Podman user
home: "{{ podman_user_homedir }}"
password_lock: true
shell: /bin/bash
group: podman
become: true
- name: Enable lingering for podman user
ansible.builtin.command:
cmd: "{{ item }}"
creates: /var/lib/systemd/linger/{{ podman_user }}
become: true
loop:
- sudo systemctl --machine={{ podman_user }}@.host --user daemon-reload
- loginctl enable-linger {{ podman_user }}
- name: Enable containers auto-update service
ansible.builtin.systemd_service:
name: podman-auto-update.timer
state: started
daemon_reload: true
scope: user
when: podman_auto_update
become: true
become_user: "{{ podman_user }}"
- name: Create podman user directory tree
ansible.builtin.file:
path: "{{ item.path }}"
owner: "{{ podman_user }}"
group: "{{ podman_user }}"
mode: "{{ item.mode }}"
state: directory
become: true
loop:
- path: "{{ podman_user_homedir }}/.config"
mode: u=rwX,g=,o=
- path: "{{ podman_user_homedir }}/.config/containers"
mode: u=rwX,g=rX,o=rX
- path: "{{ podman_user_homedir }}/.config/containers/systemd"
mode: u=rwX,g=rX,o=rX
loop_control:
label: "{{ item.path }}"

View File

@@ -1,82 +0,0 @@
---
# tasks file for podman
- name: Activer le lingering
ansible.builtin.command:
cmd: "loginctl enable-linger {{ container_user }}"
creates: /var/lib/systemd/linger/{{ container_user }}
become: true
loop: "{{ podman_containers }}"
loop_control:
label: "{{ item.name }}"
vars:
container_user: "podman-{{ item.user | default(item.name) }}"
- name: Créer les dossiers des volumes
ansible.builtin.file:
path: "{{ item.1 | split(':') | first }}"
state: directory
owner: "{{ container_user }}"
group: "{{ container_user }}"
mode: u=rwX,g=rX,o=rX
become: true
loop: "{{ q('ansible.builtin.subelements', podman_containers, 'volumes', {'skip_missing': True}) }}"
loop_control:
label: "{{ item.0.name }}"
vars:
container_user: "podman-{{ item.0.user | default(item.0.name) }}"
- name: Déployer les conteneurs
containers.podman.podman_container:
hostname: "{{ item.hostname | default(inventory_hostname) }}"
name: "{{ item.name }}"
image: "{{ item.image }}"
state: quadlet
device: "{{ item.device | default(omit) }}"
ports: "{{ item.ports | default(omit) }}"
volumes: "{{ item.volumes | default(omit) }}"
userns: "{{ item.userns | default(omit) }}"
mount: "{{ item.mount | default(omit) }}"
publish: "{{ item.publish | default(omit) }}"
env: "{{ item.env | default(omit) }}"
quadlet_options: "{{ item.quadlet_options | default(omit) }}"
sysctl: "{{ item.sysctl | default(omit) }}"
cap_add: "{{ item.cap_add | default(omit) }}"
recreate: true
become: true
become_user: "{{ container_user }}"
register: deploy_container
loop: "{{ podman_containers }}"
loop_control:
label: "{{ item.name }}"
vars:
container_user: "podman-{{ item.user | default(item.name) }}"
- name: Démarrer ou redémarrer le conteneur
ansible.builtin.systemd_service:
name: "{{ item.item.name }}.service"
state: "{{ 'restarted' if item.changed else 'started' }}"
daemon_reload: true
scope: user
become: true
become_user: "{{ container_user }}"
loop: "{{ deploy_container.results }}"
loop_control:
label: "{{ item.item.name }}"
vars:
container_user: "podman-{{ item.item.user | default(item.item.name) }}"
- name: Activer le service de mise à jour automatique
ansible.builtin.systemd_service:
name: podman-auto-update.timer
daemon_reload: true
enabled: true
scope: user
when: podman_auto_update
become: true
become_user: "{{ container_user }}"
loop: "{{ deploy_container.results }}"
loop_control:
label: "{{ item.item.name }}"
vars:
container_user: "podman-{{ item.item.user | default(item.item.name) }}"

View File

@@ -1,47 +0,0 @@
---
# tasks file for podman
- name: Installer les paquets
ansible.builtin.apt:
name:
- dbus-user-session
- containernetworking-dnsname
- containernetworking-plugins
- containernetworking-podman-machine
- dbus-user-session
- passt
- podman
- podman-aardvark-dns
- podman-docker
- podman-gvproxy
- podman-netavark
- python3-podman-compose
- uidmap
- systemd-container
install_recommends: true
state: present
become: true
notify:
- Corriger le problème passt VS pasta
- Redémarrer l'instance
- Attendre que le port SSH soit ouvert
- name: Exécuter les handlers
ansible.builtin.meta: flush_handlers
- name: Déployer la configuration de rsyslog
ansible.builtin.template:
src: templates/rsyslog.conf.j2
dest: /etc/rsyslog.d/10-podman.conf
owner: root
group: root
mode: u=rw,g=r,o=r
when: podman_configure_rsyslog
become: true
notify: Redémarrer rsyslog.service
- name: Désactiver le service de mise à jour automatique pour root
ansible.builtin.systemd_service:
name: podman-auto-update.timer
enabled: false
become: true

View File

@@ -1,10 +1,25 @@
--- ---
# tasks file for podman # tasks file for podman
- name: Importer les tâches d'installation - name: Install packages
ansible.builtin.import_tasks: ansible.builtin.dnf:
file: installation.yml name: "{{ podman_packages }}"
become: true
- name: Importer les tâches de configuration - name: Import configuration tasks
ansible.builtin.import_tasks: ansible.builtin.import_tasks:
file: configuration.yml file: config.yml
when: podman_quadlets_rootless | length > 0
- name: Import management tasks for rootless quadlets
ansible.builtin.import_tasks:
file: manage_rootless.yml
when: podman_quadlets_rootless | length > 0
- name: Import management tasks for rootful quadlets
ansible.builtin.import_tasks:
file: manage_rootful.yml
when: podman_quadlets_rootful | length > 0
- name: Flush handlers
ansible.builtin.meta: flush_handlers

17
tasks/manage_rootful.yml Normal file
View File

@@ -0,0 +1,17 @@
---
# tasks file for podman
- name: Deploy rootful quadlets
ansible.builtin.template:
src: "{{ item }}.j2"
dest: "/etc/containers/systemd/{{ item | ansible.builtin.basename }}"
owner: root
group: root
mode: u=rw,g=r,o=
become: true
loop: "{{ podman_quadlets_rootful }}"
register: deployed_quadlets_rootful
notify: Start or restart rootful quadlets
- name: Flush handlers
ansible.builtin.meta: flush_handlers

59
tasks/manage_rootless.yml Normal file
View File

@@ -0,0 +1,59 @@
---
# tasks file for podman
- name: List current rootless quadlets
ansible.builtin.find:
paths: "{{ podman_user_homedir }}/.config/containers/systemd"
become: true
register: current_quadlets
- name: Extract list of undefined quadlets
ansible.builtin.set_fact:
podman_quadlets_undefined: >-
{{
current_quadlets.files |
map(attribute='path') |
map('ansible.builtin.basename') |
ansible.builtin.difference(podman_qualets_filenames)
}}
vars:
podman_qualets_filenames: "{{ podman_quadlets_rootless | map('ansible.builtin.basename') }}"
- name: Stop unwanted rootless quadlets
ansible.builtin.systemd_service:
name: "{{ unit }}"
state: stopped
daemon_reload: true
scope: user
become: true
become_user: "{{ podman_user }}"
loop: "{{ podman_quadlets_undefined }}"
loop_control:
label: "{{ unit }}"
vars:
unit: >-
{{
item | ansible.builtin.basename |
ansible.builtin.regex_replace('\.container$', '.service') |
ansible.builtin.regex_replace('\.network$', '-network.service') |
ansible.builtin.regex_replace('\.volume$', '-volume.service')
}}
- name: Remove undefined rootless quadlets
ansible.builtin.file:
path: "{{ podman_user_homedir }}/.config/containers/systemd/{{ item }}"
state: absent
become: true
loop: "{{ podman_quadlets_undefined }}"
- name: Deploy rootless quadlets
ansible.builtin.template:
src: "{{ item }}.j2"
dest: "{{ podman_user_homedir }}/.config/containers/systemd/{{ item | ansible.builtin.basename }}"
owner: "{{ podman_user }}"
group: "{{ podman_user }}"
mode: u=rw,g=r,o=
become: true
loop: "{{ podman_quadlets_rootless }}"
register: deployed_quadlets_rootless
notify: Start or restart rootless quadlets

View File

@@ -1,9 +0,0 @@
# {{ ansible_managed }}
# Don't log podman
:programname, contains, "podman" stop
# Don't log progams inside podman container
{% for container in podman_containers %}
:programname, contains, "{{ container.name }}" stop
{% endfor %}