From 6ffb3423644cffd959d624c8bee3fe4bb29f61a8 Mon Sep 17 00:00:00 2001 From: Bodo Schulz Date: Mon, 10 Jun 2024 16:53:34 +0200 Subject: [PATCH 1/9] some updates --- .github/workflows/main.yml | 10 ++ .github/workflows/test_role_coredump.yml | 12 +- .github/workflows/test_role_homed.yml | 12 +- .github/workflows/test_role_journald.yml | 12 +- .github/workflows/test_role_logind.yml | 18 ++- .github/workflows/test_role_networkd.yml | 12 +- .github/workflows/test_role_oomd.yml | 12 +- .github/workflows/test_role_pstore.yml | 12 +- .github/workflows/test_role_resolved.yml | 12 +- .github/workflows/test_role_sleep.yml | 18 ++- .github/workflows/test_role_system.yml | 12 +- .github/workflows/test_role_timesyncd.yml | 12 +- .github/workflows/test_role_user.yml | 12 +- roles/coredump/molecule/default/molecule.yml | 8 -- roles/coredump/molecule/default/prepare.yml | 3 + roles/coredump/test-requirements.txt | 3 +- roles/coredump/tox.ini | 11 +- roles/homed/molecule/default/molecule.yml | 6 - roles/homed/molecule/default/prepare.yml | 3 + roles/homed/test-requirements.txt | 3 +- roles/homed/tox.ini | 11 +- roles/journald/molecule/default/molecule.yml | 8 -- roles/journald/molecule/default/prepare.yml | 3 + roles/journald/test-requirements.txt | 3 +- roles/journald/tox.ini | 11 +- roles/logind/molecule/default/molecule.yml | 6 - roles/logind/molecule/default/prepare.yml | 3 + roles/logind/test-requirements.txt | 3 +- roles/logind/tox.ini | 11 +- roles/networkd/molecule/default/molecule.yml | 6 - roles/networkd/molecule/default/prepare.yml | 3 + roles/networkd/test-requirements.txt | 3 +- roles/networkd/tox.ini | 11 +- roles/oomd/molecule/default/molecule.yml | 6 - roles/oomd/molecule/default/prepare.yml | 3 + roles/oomd/test-requirements.txt | 3 +- roles/oomd/tox.ini | 11 +- roles/pstore/molecule/default/molecule.yml | 6 - roles/pstore/molecule/default/prepare.yml | 3 + roles/pstore/test-requirements.txt | 3 +- roles/pstore/tox.ini | 11 +- roles/resolved/molecule/default/molecule.yml | 6 - roles/resolved/molecule/default/prepare.yml | 3 + roles/resolved/test-requirements.txt | 3 +- roles/resolved/tox.ini | 11 +- roles/sleep/molecule/default/molecule.yml | 6 - roles/sleep/molecule/default/prepare.yml | 3 + roles/sleep/test-requirements.txt | 3 +- roles/sleep/tox.ini | 11 +- .../molecule/default/group_vars/all/vars.yml | 14 +-- roles/system/molecule/default/molecule.yml | 6 - roles/system/molecule/default/prepare.yml | 3 + roles/system/templates/systemd/system.conf.j2 | 116 +++++++++--------- roles/system/test-requirements.txt | 3 +- roles/system/tox.ini | 11 +- roles/timesyncd/molecule/default/molecule.yml | 6 - roles/timesyncd/molecule/default/prepare.yml | 3 + roles/timesyncd/test-requirements.txt | 3 +- roles/timesyncd/tox.ini | 11 +- roles/user/molecule/default/prepare.yml | 3 + roles/user/test-requirements.txt | 3 +- roles/user/tox.ini | 11 +- 62 files changed, 366 insertions(+), 204 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 6b4be41..b988bb0 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -63,6 +63,11 @@ jobs: python -m pip install --upgrade pip pip install -r test-requirements.txt + - name: force reinstall of community.docker + run: | + mkdir -p /home/runner/.ansible/collections + ansible-galaxy collection install community.docker --force + - name: Install collection run: | mkdir -p ~/.ansible/collections/ansible_collections/$COLLECTION_NAMESPACE @@ -112,6 +117,11 @@ jobs: python -m pip install --upgrade pip pip install -r test-requirements.txt + - name: force reinstall of community.docker + run: | + mkdir -p /home/runner/.ansible/collections + ansible-galaxy collection install community.docker --force + - name: Install collection run: | mkdir -p ~/.ansible/collections/ansible_collections/$COLLECTION_NAMESPACE diff --git a/.github/workflows/test_role_coredump.yml b/.github/workflows/test_role_coredump.yml index d189e71..652746a 100644 --- a/.github/workflows/test_role_coredump.yml +++ b/.github/workflows/test_role_coredump.yml @@ -80,6 +80,11 @@ jobs: python -m pip install --upgrade pip pip install -r test-requirements.txt + - name: force reinstall of community.docker + run: | + mkdir -p /home/runner/.ansible/collections + ansible-galaxy collection install community.docker --force + - name: Install collection run: | make \ @@ -105,7 +110,7 @@ jobs: fail-fast: false matrix: image: - - debian:11 + - debian:12 ansible-version: - '6.7' python_version: @@ -130,6 +135,11 @@ jobs: python -m pip install --upgrade pip pip install -r test-requirements.txt + - name: force reinstall of community.docker + run: | + mkdir -p /home/runner/.ansible/collections + ansible-galaxy collection install community.docker --force + - name: Install collection run: | make \ diff --git a/.github/workflows/test_role_homed.yml b/.github/workflows/test_role_homed.yml index 057d46b..ba61789 100644 --- a/.github/workflows/test_role_homed.yml +++ b/.github/workflows/test_role_homed.yml @@ -80,6 +80,11 @@ jobs: python -m pip install --upgrade pip pip install -r test-requirements.txt + - name: force reinstall of community.docker + run: | + mkdir -p /home/runner/.ansible/collections + ansible-galaxy collection install community.docker --force + - name: Install collection run: | make \ @@ -114,7 +119,7 @@ jobs: fail-fast: false matrix: image: - - debian:11 + - debian:12 ansible-version: - '6.7' python_version: @@ -139,6 +144,11 @@ jobs: python -m pip install --upgrade pip pip install -r test-requirements.txt + - name: force reinstall of community.docker + run: | + mkdir -p /home/runner/.ansible/collections + ansible-galaxy collection install community.docker --force + - name: Install collection run: | make \ diff --git a/.github/workflows/test_role_journald.yml b/.github/workflows/test_role_journald.yml index 44d701f..ca2a92a 100644 --- a/.github/workflows/test_role_journald.yml +++ b/.github/workflows/test_role_journald.yml @@ -80,6 +80,11 @@ jobs: python -m pip install --upgrade pip pip install -r test-requirements.txt + - name: force reinstall of community.docker + run: | + mkdir -p /home/runner/.ansible/collections + ansible-galaxy collection install community.docker --force + - name: Install collection run: | make \ @@ -105,7 +110,7 @@ jobs: fail-fast: false matrix: image: - - debian:11 + - debian:12 ansible-version: - '6.7' python_version: @@ -130,6 +135,11 @@ jobs: python -m pip install --upgrade pip pip install -r test-requirements.txt + - name: force reinstall of community.docker + run: | + mkdir -p /home/runner/.ansible/collections + ansible-galaxy collection install community.docker --force + - name: Install collection run: | make \ diff --git a/.github/workflows/test_role_logind.yml b/.github/workflows/test_role_logind.yml index 8bcc981..d607bc9 100644 --- a/.github/workflows/test_role_logind.yml +++ b/.github/workflows/test_role_logind.yml @@ -47,8 +47,7 @@ env: jobs: arch: - name: "${{ matrix.image }} / ${{ matrix.scenario }} / ${{ matrix.ansible-version }} / ${{ -matrix.python_version }}" + name: "${{ matrix.image }} / ${{ matrix.scenario }} / ${{ matrix.ansible-version }} / ${{ matrix.python_version }}" runs-on: ubuntu-20.04 strategy: fail-fast: false @@ -81,6 +80,11 @@ matrix.python_version }}" python -m pip install --upgrade pip pip install -r test-requirements.txt + - name: force reinstall of community.docker + run: | + mkdir -p /home/runner/.ansible/collections + ansible-galaxy collection install community.docker --force + - name: Install collection run: | make \ @@ -100,14 +104,13 @@ matrix.python_version }}" DISTRIBUTION: ${{ matrix.image }} deb: - name: "${{ matrix.image }} / ${{ matrix.scenario }} / ${{ matrix.ansible-version }} / ${{ -matrix.python_version }}" + name: "${{ matrix.image }} / ${{ matrix.scenario }} / ${{ matrix.ansible-version }} / ${{ matrix.python_version }}" runs-on: ubuntu-20.04 strategy: fail-fast: false matrix: image: - - debian:11 + - debian:12 ansible-version: - '6.7' python_version: @@ -132,6 +135,11 @@ matrix.python_version }}" python -m pip install --upgrade pip pip install -r test-requirements.txt + - name: force reinstall of community.docker + run: | + mkdir -p /home/runner/.ansible/collections + ansible-galaxy collection install community.docker --force + - name: Install collection run: | make \ diff --git a/.github/workflows/test_role_networkd.yml b/.github/workflows/test_role_networkd.yml index df5183d..671c190 100644 --- a/.github/workflows/test_role_networkd.yml +++ b/.github/workflows/test_role_networkd.yml @@ -80,6 +80,11 @@ jobs: python -m pip install --upgrade pip pip install -r test-requirements.txt + - name: force reinstall of community.docker + run: | + mkdir -p /home/runner/.ansible/collections + ansible-galaxy collection install community.docker --force + - name: Install collection run: | make \ @@ -105,7 +110,7 @@ jobs: fail-fast: false matrix: image: - - debian:11 + - debian:12 ansible-version: - '6.7' python_version: @@ -130,6 +135,11 @@ jobs: python -m pip install --upgrade pip pip install -r test-requirements.txt + - name: force reinstall of community.docker + run: | + mkdir -p /home/runner/.ansible/collections + ansible-galaxy collection install community.docker --force + - name: Install collection run: | make \ diff --git a/.github/workflows/test_role_oomd.yml b/.github/workflows/test_role_oomd.yml index 0092b25..574f82c 100644 --- a/.github/workflows/test_role_oomd.yml +++ b/.github/workflows/test_role_oomd.yml @@ -80,6 +80,11 @@ jobs: python -m pip install --upgrade pip pip install -r test-requirements.txt + - name: force reinstall of community.docker + run: | + mkdir -p /home/runner/.ansible/collections + ansible-galaxy collection install community.docker --force + - name: Install collection run: | make \ @@ -105,7 +110,7 @@ jobs: fail-fast: false matrix: image: - - debian:11 + - debian:12 ansible-version: - '6.7' python_version: @@ -130,6 +135,11 @@ jobs: python -m pip install --upgrade pip pip install -r test-requirements.txt + - name: force reinstall of community.docker + run: | + mkdir -p /home/runner/.ansible/collections + ansible-galaxy collection install community.docker --force + - name: Install collection run: | make \ diff --git a/.github/workflows/test_role_pstore.yml b/.github/workflows/test_role_pstore.yml index b16832a..4b0249b 100644 --- a/.github/workflows/test_role_pstore.yml +++ b/.github/workflows/test_role_pstore.yml @@ -80,6 +80,11 @@ jobs: python -m pip install --upgrade pip pip install -r test-requirements.txt + - name: force reinstall of community.docker + run: | + mkdir -p /home/runner/.ansible/collections + ansible-galaxy collection install community.docker --force + - name: Install collection run: | make \ @@ -105,7 +110,7 @@ jobs: fail-fast: false matrix: image: - - debian:11 + - debian:12 ansible-version: - '6.7' python_version: @@ -130,6 +135,11 @@ jobs: python -m pip install --upgrade pip pip install -r test-requirements.txt + - name: force reinstall of community.docker + run: | + mkdir -p /home/runner/.ansible/collections + ansible-galaxy collection install community.docker --force + - name: Install collection run: | make \ diff --git a/.github/workflows/test_role_resolved.yml b/.github/workflows/test_role_resolved.yml index 2881387..fe7342d 100644 --- a/.github/workflows/test_role_resolved.yml +++ b/.github/workflows/test_role_resolved.yml @@ -80,6 +80,11 @@ jobs: python -m pip install --upgrade pip pip install -r test-requirements.txt + - name: force reinstall of community.docker + run: | + mkdir -p /home/runner/.ansible/collections + ansible-galaxy collection install community.docker --force + - name: Install collection run: | make \ @@ -105,7 +110,7 @@ jobs: fail-fast: false matrix: image: - - debian:11 + - debian:12 ansible-version: - '6.7' python_version: @@ -130,6 +135,11 @@ jobs: python -m pip install --upgrade pip pip install -r test-requirements.txt + - name: force reinstall of community.docker + run: | + mkdir -p /home/runner/.ansible/collections + ansible-galaxy collection install community.docker --force + - name: Install collection run: | make \ diff --git a/.github/workflows/test_role_sleep.yml b/.github/workflows/test_role_sleep.yml index f2e9588..961390d 100644 --- a/.github/workflows/test_role_sleep.yml +++ b/.github/workflows/test_role_sleep.yml @@ -47,8 +47,7 @@ env: jobs: arch: - name: "${{ matrix.image }} / ${{ matrix.scenario }} / ${{ matrix.ansible-version }} / ${{ -matrix.python_version }}" + name: "${{ matrix.image }} / ${{ matrix.scenario }} / ${{ matrix.ansible-version }} / ${{ matrix.python_version }}" runs-on: ubuntu-20.04 strategy: fail-fast: false @@ -81,6 +80,11 @@ matrix.python_version }}" python -m pip install --upgrade pip pip install -r test-requirements.txt + - name: force reinstall of community.docker + run: | + mkdir -p /home/runner/.ansible/collections + ansible-galaxy collection install community.docker --force + - name: Install collection run: | make \ @@ -100,14 +104,13 @@ matrix.python_version }}" DISTRIBUTION: ${{ matrix.image }} deb: - name: "${{ matrix.image }} / ${{ matrix.scenario }} / ${{ matrix.ansible-version }} / ${{ -matrix.python_version }}" + name: "${{ matrix.image }} / ${{ matrix.scenario }} / ${{ matrix.ansible-version }} / ${{ matrix.python_version }}" runs-on: ubuntu-20.04 strategy: fail-fast: false matrix: image: - - debian:11 + - debian:12 ansible-version: - '6.7' python_version: @@ -132,6 +135,11 @@ matrix.python_version }}" python -m pip install --upgrade pip pip install -r test-requirements.txt + - name: force reinstall of community.docker + run: | + mkdir -p /home/runner/.ansible/collections + ansible-galaxy collection install community.docker --force + - name: Install collection run: | make \ diff --git a/.github/workflows/test_role_system.yml b/.github/workflows/test_role_system.yml index c2ac7f6..1ab18ab 100644 --- a/.github/workflows/test_role_system.yml +++ b/.github/workflows/test_role_system.yml @@ -80,6 +80,11 @@ jobs: python -m pip install --upgrade pip pip install -r test-requirements.txt + - name: force reinstall of community.docker + run: | + mkdir -p /home/runner/.ansible/collections + ansible-galaxy collection install community.docker --force + - name: Install collection run: | make \ @@ -105,7 +110,7 @@ jobs: fail-fast: false matrix: image: - - debian:11 + - debian:12 ansible-version: - '6.7' python_version: @@ -130,6 +135,11 @@ jobs: python -m pip install --upgrade pip pip install -r test-requirements.txt + - name: force reinstall of community.docker + run: | + mkdir -p /home/runner/.ansible/collections + ansible-galaxy collection install community.docker --force + - name: Install collection run: | make \ diff --git a/.github/workflows/test_role_timesyncd.yml b/.github/workflows/test_role_timesyncd.yml index 4ca8b5e..da53b5d 100644 --- a/.github/workflows/test_role_timesyncd.yml +++ b/.github/workflows/test_role_timesyncd.yml @@ -80,6 +80,11 @@ jobs: python -m pip install --upgrade pip pip install -r test-requirements.txt + - name: force reinstall of community.docker + run: | + mkdir -p /home/runner/.ansible/collections + ansible-galaxy collection install community.docker --force + - name: Install collection run: | make \ @@ -105,7 +110,7 @@ jobs: fail-fast: false matrix: image: - - debian:11 + - debian:12 ansible-version: - '6.7' python_version: @@ -130,6 +135,11 @@ jobs: python -m pip install --upgrade pip pip install -r test-requirements.txt + - name: force reinstall of community.docker + run: | + mkdir -p /home/runner/.ansible/collections + ansible-galaxy collection install community.docker --force + - name: Install collection run: | make \ diff --git a/.github/workflows/test_role_user.yml b/.github/workflows/test_role_user.yml index 9f8f9ae..b5bf8c3 100644 --- a/.github/workflows/test_role_user.yml +++ b/.github/workflows/test_role_user.yml @@ -80,6 +80,11 @@ jobs: python -m pip install --upgrade pip pip install -r test-requirements.txt + - name: force reinstall of community.docker + run: | + mkdir -p /home/runner/.ansible/collections + ansible-galaxy collection install community.docker --force + - name: Install collection run: | make \ @@ -105,7 +110,7 @@ jobs: fail-fast: false matrix: image: - - debian:11 + - debian:12 ansible-version: - '6.7' python_version: @@ -130,6 +135,11 @@ jobs: python -m pip install --upgrade pip pip install -r test-requirements.txt + - name: force reinstall of community.docker + run: | + mkdir -p /home/runner/.ansible/collections + ansible-galaxy collection install community.docker --force + - name: Install collection run: | make \ diff --git a/roles/coredump/molecule/default/molecule.yml b/roles/coredump/molecule/default/molecule.yml index 3b8b91a..ba28a37 100644 --- a/roles/coredump/molecule/default/molecule.yml +++ b/roles/coredump/molecule/default/molecule.yml @@ -5,12 +5,6 @@ dependency: driver: name: docker -lint: | - set -e - yamllint . - ansible-lint . - flake8 . - platforms: - name: instance image: "bodsch/ansible-${DISTRIBUTION:-debian:12}" @@ -31,8 +25,6 @@ platforms: tmpfs: - /run - /tmp - published_ports: - - 9090:9090 provisioner: name: ansible diff --git a/roles/coredump/molecule/default/prepare.yml b/roles/coredump/molecule/default/prepare.yml index bd4351e..399dd05 100644 --- a/roles/coredump/molecule/default/prepare.yml +++ b/roles/coredump/molecule/default/prepare.yml @@ -13,6 +13,9 @@ - name: update pacman system ansible.builtin.command: | pacman --refresh --sync --sysupgrade --noconfirm + register: pacman + changed_when: pacman.rc != 0 + failed_when: pacman.rc != 0 - name: create depends service ansible.builtin.copy: diff --git a/roles/coredump/test-requirements.txt b/roles/coredump/test-requirements.txt index 267ec92..dc5c9a1 100644 --- a/roles/coredump/test-requirements.txt +++ b/roles/coredump/test-requirements.txt @@ -2,10 +2,9 @@ ansible-lint docker dnspython flake8 -molecule>=5.0.1 +molecule molecule-plugins[docker] netaddr -pytest pytest-testinfra tox tox-gh-actions diff --git a/roles/coredump/tox.ini b/roles/coredump/tox.ini index d7cb253..c3099d3 100644 --- a/roles/coredump/tox.ini +++ b/roles/coredump/tox.ini @@ -1,9 +1,10 @@ [tox] +ignore_basepython_conflict = True +skip_missing_interpreters = True + minversion = 3.25 toxworkdir = /tmp/.tox/ -envlist = ansible_{2.9,2.10,3.4,4.10,5.1,5.2,6.1} - skipsdist = true [testenv] @@ -23,6 +24,12 @@ deps = ansible_6.1: ansible>=6.1,<6.2 ansible_6.7: ansible>=6.7,<6.8 ansible_7.0: ansible>=7.0,<7.1 + ansible_7.5: ansible>=7.5,<7.6 + ansible_8.0: ansible>=8.0,<8.1 + ansible_8.5: ansible>=8.5,<8.6 + ansible_9.0: ansible>=9.0,<9.1 + ansible_9.5: ansible>=9.5,<9.6 + ansible_10.0: ansible>=10.0,<10.1 #commands_pre = # /usr/bin/find {toxinidir} -type f -not -path '{toxworkdir}/*' -path '*/__pycache__/*' -name '*.py[c|o]' -delete diff --git a/roles/homed/molecule/default/molecule.yml b/roles/homed/molecule/default/molecule.yml index a8c4d00..ba28a37 100644 --- a/roles/homed/molecule/default/molecule.yml +++ b/roles/homed/molecule/default/molecule.yml @@ -5,12 +5,6 @@ dependency: driver: name: docker -lint: | - set -e - yamllint . - ansible-lint . - flake8 . - platforms: - name: instance image: "bodsch/ansible-${DISTRIBUTION:-debian:12}" diff --git a/roles/homed/molecule/default/prepare.yml b/roles/homed/molecule/default/prepare.yml index bd4351e..399dd05 100644 --- a/roles/homed/molecule/default/prepare.yml +++ b/roles/homed/molecule/default/prepare.yml @@ -13,6 +13,9 @@ - name: update pacman system ansible.builtin.command: | pacman --refresh --sync --sysupgrade --noconfirm + register: pacman + changed_when: pacman.rc != 0 + failed_when: pacman.rc != 0 - name: create depends service ansible.builtin.copy: diff --git a/roles/homed/test-requirements.txt b/roles/homed/test-requirements.txt index 267ec92..dc5c9a1 100644 --- a/roles/homed/test-requirements.txt +++ b/roles/homed/test-requirements.txt @@ -2,10 +2,9 @@ ansible-lint docker dnspython flake8 -molecule>=5.0.1 +molecule molecule-plugins[docker] netaddr -pytest pytest-testinfra tox tox-gh-actions diff --git a/roles/homed/tox.ini b/roles/homed/tox.ini index d7cb253..c3099d3 100644 --- a/roles/homed/tox.ini +++ b/roles/homed/tox.ini @@ -1,9 +1,10 @@ [tox] +ignore_basepython_conflict = True +skip_missing_interpreters = True + minversion = 3.25 toxworkdir = /tmp/.tox/ -envlist = ansible_{2.9,2.10,3.4,4.10,5.1,5.2,6.1} - skipsdist = true [testenv] @@ -23,6 +24,12 @@ deps = ansible_6.1: ansible>=6.1,<6.2 ansible_6.7: ansible>=6.7,<6.8 ansible_7.0: ansible>=7.0,<7.1 + ansible_7.5: ansible>=7.5,<7.6 + ansible_8.0: ansible>=8.0,<8.1 + ansible_8.5: ansible>=8.5,<8.6 + ansible_9.0: ansible>=9.0,<9.1 + ansible_9.5: ansible>=9.5,<9.6 + ansible_10.0: ansible>=10.0,<10.1 #commands_pre = # /usr/bin/find {toxinidir} -type f -not -path '{toxworkdir}/*' -path '*/__pycache__/*' -name '*.py[c|o]' -delete diff --git a/roles/journald/molecule/default/molecule.yml b/roles/journald/molecule/default/molecule.yml index 3b8b91a..ba28a37 100644 --- a/roles/journald/molecule/default/molecule.yml +++ b/roles/journald/molecule/default/molecule.yml @@ -5,12 +5,6 @@ dependency: driver: name: docker -lint: | - set -e - yamllint . - ansible-lint . - flake8 . - platforms: - name: instance image: "bodsch/ansible-${DISTRIBUTION:-debian:12}" @@ -31,8 +25,6 @@ platforms: tmpfs: - /run - /tmp - published_ports: - - 9090:9090 provisioner: name: ansible diff --git a/roles/journald/molecule/default/prepare.yml b/roles/journald/molecule/default/prepare.yml index bd4351e..399dd05 100644 --- a/roles/journald/molecule/default/prepare.yml +++ b/roles/journald/molecule/default/prepare.yml @@ -13,6 +13,9 @@ - name: update pacman system ansible.builtin.command: | pacman --refresh --sync --sysupgrade --noconfirm + register: pacman + changed_when: pacman.rc != 0 + failed_when: pacman.rc != 0 - name: create depends service ansible.builtin.copy: diff --git a/roles/journald/test-requirements.txt b/roles/journald/test-requirements.txt index 267ec92..dc5c9a1 100644 --- a/roles/journald/test-requirements.txt +++ b/roles/journald/test-requirements.txt @@ -2,10 +2,9 @@ ansible-lint docker dnspython flake8 -molecule>=5.0.1 +molecule molecule-plugins[docker] netaddr -pytest pytest-testinfra tox tox-gh-actions diff --git a/roles/journald/tox.ini b/roles/journald/tox.ini index d7cb253..c3099d3 100644 --- a/roles/journald/tox.ini +++ b/roles/journald/tox.ini @@ -1,9 +1,10 @@ [tox] +ignore_basepython_conflict = True +skip_missing_interpreters = True + minversion = 3.25 toxworkdir = /tmp/.tox/ -envlist = ansible_{2.9,2.10,3.4,4.10,5.1,5.2,6.1} - skipsdist = true [testenv] @@ -23,6 +24,12 @@ deps = ansible_6.1: ansible>=6.1,<6.2 ansible_6.7: ansible>=6.7,<6.8 ansible_7.0: ansible>=7.0,<7.1 + ansible_7.5: ansible>=7.5,<7.6 + ansible_8.0: ansible>=8.0,<8.1 + ansible_8.5: ansible>=8.5,<8.6 + ansible_9.0: ansible>=9.0,<9.1 + ansible_9.5: ansible>=9.5,<9.6 + ansible_10.0: ansible>=10.0,<10.1 #commands_pre = # /usr/bin/find {toxinidir} -type f -not -path '{toxworkdir}/*' -path '*/__pycache__/*' -name '*.py[c|o]' -delete diff --git a/roles/logind/molecule/default/molecule.yml b/roles/logind/molecule/default/molecule.yml index a8c4d00..ba28a37 100644 --- a/roles/logind/molecule/default/molecule.yml +++ b/roles/logind/molecule/default/molecule.yml @@ -5,12 +5,6 @@ dependency: driver: name: docker -lint: | - set -e - yamllint . - ansible-lint . - flake8 . - platforms: - name: instance image: "bodsch/ansible-${DISTRIBUTION:-debian:12}" diff --git a/roles/logind/molecule/default/prepare.yml b/roles/logind/molecule/default/prepare.yml index bd4351e..399dd05 100644 --- a/roles/logind/molecule/default/prepare.yml +++ b/roles/logind/molecule/default/prepare.yml @@ -13,6 +13,9 @@ - name: update pacman system ansible.builtin.command: | pacman --refresh --sync --sysupgrade --noconfirm + register: pacman + changed_when: pacman.rc != 0 + failed_when: pacman.rc != 0 - name: create depends service ansible.builtin.copy: diff --git a/roles/logind/test-requirements.txt b/roles/logind/test-requirements.txt index 267ec92..dc5c9a1 100644 --- a/roles/logind/test-requirements.txt +++ b/roles/logind/test-requirements.txt @@ -2,10 +2,9 @@ ansible-lint docker dnspython flake8 -molecule>=5.0.1 +molecule molecule-plugins[docker] netaddr -pytest pytest-testinfra tox tox-gh-actions diff --git a/roles/logind/tox.ini b/roles/logind/tox.ini index d7cb253..c3099d3 100644 --- a/roles/logind/tox.ini +++ b/roles/logind/tox.ini @@ -1,9 +1,10 @@ [tox] +ignore_basepython_conflict = True +skip_missing_interpreters = True + minversion = 3.25 toxworkdir = /tmp/.tox/ -envlist = ansible_{2.9,2.10,3.4,4.10,5.1,5.2,6.1} - skipsdist = true [testenv] @@ -23,6 +24,12 @@ deps = ansible_6.1: ansible>=6.1,<6.2 ansible_6.7: ansible>=6.7,<6.8 ansible_7.0: ansible>=7.0,<7.1 + ansible_7.5: ansible>=7.5,<7.6 + ansible_8.0: ansible>=8.0,<8.1 + ansible_8.5: ansible>=8.5,<8.6 + ansible_9.0: ansible>=9.0,<9.1 + ansible_9.5: ansible>=9.5,<9.6 + ansible_10.0: ansible>=10.0,<10.1 #commands_pre = # /usr/bin/find {toxinidir} -type f -not -path '{toxworkdir}/*' -path '*/__pycache__/*' -name '*.py[c|o]' -delete diff --git a/roles/networkd/molecule/default/molecule.yml b/roles/networkd/molecule/default/molecule.yml index a8c4d00..ba28a37 100644 --- a/roles/networkd/molecule/default/molecule.yml +++ b/roles/networkd/molecule/default/molecule.yml @@ -5,12 +5,6 @@ dependency: driver: name: docker -lint: | - set -e - yamllint . - ansible-lint . - flake8 . - platforms: - name: instance image: "bodsch/ansible-${DISTRIBUTION:-debian:12}" diff --git a/roles/networkd/molecule/default/prepare.yml b/roles/networkd/molecule/default/prepare.yml index bd4351e..399dd05 100644 --- a/roles/networkd/molecule/default/prepare.yml +++ b/roles/networkd/molecule/default/prepare.yml @@ -13,6 +13,9 @@ - name: update pacman system ansible.builtin.command: | pacman --refresh --sync --sysupgrade --noconfirm + register: pacman + changed_when: pacman.rc != 0 + failed_when: pacman.rc != 0 - name: create depends service ansible.builtin.copy: diff --git a/roles/networkd/test-requirements.txt b/roles/networkd/test-requirements.txt index 267ec92..dc5c9a1 100644 --- a/roles/networkd/test-requirements.txt +++ b/roles/networkd/test-requirements.txt @@ -2,10 +2,9 @@ ansible-lint docker dnspython flake8 -molecule>=5.0.1 +molecule molecule-plugins[docker] netaddr -pytest pytest-testinfra tox tox-gh-actions diff --git a/roles/networkd/tox.ini b/roles/networkd/tox.ini index d7cb253..c3099d3 100644 --- a/roles/networkd/tox.ini +++ b/roles/networkd/tox.ini @@ -1,9 +1,10 @@ [tox] +ignore_basepython_conflict = True +skip_missing_interpreters = True + minversion = 3.25 toxworkdir = /tmp/.tox/ -envlist = ansible_{2.9,2.10,3.4,4.10,5.1,5.2,6.1} - skipsdist = true [testenv] @@ -23,6 +24,12 @@ deps = ansible_6.1: ansible>=6.1,<6.2 ansible_6.7: ansible>=6.7,<6.8 ansible_7.0: ansible>=7.0,<7.1 + ansible_7.5: ansible>=7.5,<7.6 + ansible_8.0: ansible>=8.0,<8.1 + ansible_8.5: ansible>=8.5,<8.6 + ansible_9.0: ansible>=9.0,<9.1 + ansible_9.5: ansible>=9.5,<9.6 + ansible_10.0: ansible>=10.0,<10.1 #commands_pre = # /usr/bin/find {toxinidir} -type f -not -path '{toxworkdir}/*' -path '*/__pycache__/*' -name '*.py[c|o]' -delete diff --git a/roles/oomd/molecule/default/molecule.yml b/roles/oomd/molecule/default/molecule.yml index a8c4d00..ba28a37 100644 --- a/roles/oomd/molecule/default/molecule.yml +++ b/roles/oomd/molecule/default/molecule.yml @@ -5,12 +5,6 @@ dependency: driver: name: docker -lint: | - set -e - yamllint . - ansible-lint . - flake8 . - platforms: - name: instance image: "bodsch/ansible-${DISTRIBUTION:-debian:12}" diff --git a/roles/oomd/molecule/default/prepare.yml b/roles/oomd/molecule/default/prepare.yml index bd4351e..399dd05 100644 --- a/roles/oomd/molecule/default/prepare.yml +++ b/roles/oomd/molecule/default/prepare.yml @@ -13,6 +13,9 @@ - name: update pacman system ansible.builtin.command: | pacman --refresh --sync --sysupgrade --noconfirm + register: pacman + changed_when: pacman.rc != 0 + failed_when: pacman.rc != 0 - name: create depends service ansible.builtin.copy: diff --git a/roles/oomd/test-requirements.txt b/roles/oomd/test-requirements.txt index 267ec92..dc5c9a1 100644 --- a/roles/oomd/test-requirements.txt +++ b/roles/oomd/test-requirements.txt @@ -2,10 +2,9 @@ ansible-lint docker dnspython flake8 -molecule>=5.0.1 +molecule molecule-plugins[docker] netaddr -pytest pytest-testinfra tox tox-gh-actions diff --git a/roles/oomd/tox.ini b/roles/oomd/tox.ini index d7cb253..c3099d3 100644 --- a/roles/oomd/tox.ini +++ b/roles/oomd/tox.ini @@ -1,9 +1,10 @@ [tox] +ignore_basepython_conflict = True +skip_missing_interpreters = True + minversion = 3.25 toxworkdir = /tmp/.tox/ -envlist = ansible_{2.9,2.10,3.4,4.10,5.1,5.2,6.1} - skipsdist = true [testenv] @@ -23,6 +24,12 @@ deps = ansible_6.1: ansible>=6.1,<6.2 ansible_6.7: ansible>=6.7,<6.8 ansible_7.0: ansible>=7.0,<7.1 + ansible_7.5: ansible>=7.5,<7.6 + ansible_8.0: ansible>=8.0,<8.1 + ansible_8.5: ansible>=8.5,<8.6 + ansible_9.0: ansible>=9.0,<9.1 + ansible_9.5: ansible>=9.5,<9.6 + ansible_10.0: ansible>=10.0,<10.1 #commands_pre = # /usr/bin/find {toxinidir} -type f -not -path '{toxworkdir}/*' -path '*/__pycache__/*' -name '*.py[c|o]' -delete diff --git a/roles/pstore/molecule/default/molecule.yml b/roles/pstore/molecule/default/molecule.yml index a8c4d00..ba28a37 100644 --- a/roles/pstore/molecule/default/molecule.yml +++ b/roles/pstore/molecule/default/molecule.yml @@ -5,12 +5,6 @@ dependency: driver: name: docker -lint: | - set -e - yamllint . - ansible-lint . - flake8 . - platforms: - name: instance image: "bodsch/ansible-${DISTRIBUTION:-debian:12}" diff --git a/roles/pstore/molecule/default/prepare.yml b/roles/pstore/molecule/default/prepare.yml index bd4351e..399dd05 100644 --- a/roles/pstore/molecule/default/prepare.yml +++ b/roles/pstore/molecule/default/prepare.yml @@ -13,6 +13,9 @@ - name: update pacman system ansible.builtin.command: | pacman --refresh --sync --sysupgrade --noconfirm + register: pacman + changed_when: pacman.rc != 0 + failed_when: pacman.rc != 0 - name: create depends service ansible.builtin.copy: diff --git a/roles/pstore/test-requirements.txt b/roles/pstore/test-requirements.txt index 267ec92..dc5c9a1 100644 --- a/roles/pstore/test-requirements.txt +++ b/roles/pstore/test-requirements.txt @@ -2,10 +2,9 @@ ansible-lint docker dnspython flake8 -molecule>=5.0.1 +molecule molecule-plugins[docker] netaddr -pytest pytest-testinfra tox tox-gh-actions diff --git a/roles/pstore/tox.ini b/roles/pstore/tox.ini index d7cb253..c3099d3 100644 --- a/roles/pstore/tox.ini +++ b/roles/pstore/tox.ini @@ -1,9 +1,10 @@ [tox] +ignore_basepython_conflict = True +skip_missing_interpreters = True + minversion = 3.25 toxworkdir = /tmp/.tox/ -envlist = ansible_{2.9,2.10,3.4,4.10,5.1,5.2,6.1} - skipsdist = true [testenv] @@ -23,6 +24,12 @@ deps = ansible_6.1: ansible>=6.1,<6.2 ansible_6.7: ansible>=6.7,<6.8 ansible_7.0: ansible>=7.0,<7.1 + ansible_7.5: ansible>=7.5,<7.6 + ansible_8.0: ansible>=8.0,<8.1 + ansible_8.5: ansible>=8.5,<8.6 + ansible_9.0: ansible>=9.0,<9.1 + ansible_9.5: ansible>=9.5,<9.6 + ansible_10.0: ansible>=10.0,<10.1 #commands_pre = # /usr/bin/find {toxinidir} -type f -not -path '{toxworkdir}/*' -path '*/__pycache__/*' -name '*.py[c|o]' -delete diff --git a/roles/resolved/molecule/default/molecule.yml b/roles/resolved/molecule/default/molecule.yml index a8c4d00..ba28a37 100644 --- a/roles/resolved/molecule/default/molecule.yml +++ b/roles/resolved/molecule/default/molecule.yml @@ -5,12 +5,6 @@ dependency: driver: name: docker -lint: | - set -e - yamllint . - ansible-lint . - flake8 . - platforms: - name: instance image: "bodsch/ansible-${DISTRIBUTION:-debian:12}" diff --git a/roles/resolved/molecule/default/prepare.yml b/roles/resolved/molecule/default/prepare.yml index bd4351e..399dd05 100644 --- a/roles/resolved/molecule/default/prepare.yml +++ b/roles/resolved/molecule/default/prepare.yml @@ -13,6 +13,9 @@ - name: update pacman system ansible.builtin.command: | pacman --refresh --sync --sysupgrade --noconfirm + register: pacman + changed_when: pacman.rc != 0 + failed_when: pacman.rc != 0 - name: create depends service ansible.builtin.copy: diff --git a/roles/resolved/test-requirements.txt b/roles/resolved/test-requirements.txt index 267ec92..dc5c9a1 100644 --- a/roles/resolved/test-requirements.txt +++ b/roles/resolved/test-requirements.txt @@ -2,10 +2,9 @@ ansible-lint docker dnspython flake8 -molecule>=5.0.1 +molecule molecule-plugins[docker] netaddr -pytest pytest-testinfra tox tox-gh-actions diff --git a/roles/resolved/tox.ini b/roles/resolved/tox.ini index d7cb253..c3099d3 100644 --- a/roles/resolved/tox.ini +++ b/roles/resolved/tox.ini @@ -1,9 +1,10 @@ [tox] +ignore_basepython_conflict = True +skip_missing_interpreters = True + minversion = 3.25 toxworkdir = /tmp/.tox/ -envlist = ansible_{2.9,2.10,3.4,4.10,5.1,5.2,6.1} - skipsdist = true [testenv] @@ -23,6 +24,12 @@ deps = ansible_6.1: ansible>=6.1,<6.2 ansible_6.7: ansible>=6.7,<6.8 ansible_7.0: ansible>=7.0,<7.1 + ansible_7.5: ansible>=7.5,<7.6 + ansible_8.0: ansible>=8.0,<8.1 + ansible_8.5: ansible>=8.5,<8.6 + ansible_9.0: ansible>=9.0,<9.1 + ansible_9.5: ansible>=9.5,<9.6 + ansible_10.0: ansible>=10.0,<10.1 #commands_pre = # /usr/bin/find {toxinidir} -type f -not -path '{toxworkdir}/*' -path '*/__pycache__/*' -name '*.py[c|o]' -delete diff --git a/roles/sleep/molecule/default/molecule.yml b/roles/sleep/molecule/default/molecule.yml index a8c4d00..ba28a37 100644 --- a/roles/sleep/molecule/default/molecule.yml +++ b/roles/sleep/molecule/default/molecule.yml @@ -5,12 +5,6 @@ dependency: driver: name: docker -lint: | - set -e - yamllint . - ansible-lint . - flake8 . - platforms: - name: instance image: "bodsch/ansible-${DISTRIBUTION:-debian:12}" diff --git a/roles/sleep/molecule/default/prepare.yml b/roles/sleep/molecule/default/prepare.yml index bd4351e..399dd05 100644 --- a/roles/sleep/molecule/default/prepare.yml +++ b/roles/sleep/molecule/default/prepare.yml @@ -13,6 +13,9 @@ - name: update pacman system ansible.builtin.command: | pacman --refresh --sync --sysupgrade --noconfirm + register: pacman + changed_when: pacman.rc != 0 + failed_when: pacman.rc != 0 - name: create depends service ansible.builtin.copy: diff --git a/roles/sleep/test-requirements.txt b/roles/sleep/test-requirements.txt index 267ec92..dc5c9a1 100644 --- a/roles/sleep/test-requirements.txt +++ b/roles/sleep/test-requirements.txt @@ -2,10 +2,9 @@ ansible-lint docker dnspython flake8 -molecule>=5.0.1 +molecule molecule-plugins[docker] netaddr -pytest pytest-testinfra tox tox-gh-actions diff --git a/roles/sleep/tox.ini b/roles/sleep/tox.ini index d7cb253..c3099d3 100644 --- a/roles/sleep/tox.ini +++ b/roles/sleep/tox.ini @@ -1,9 +1,10 @@ [tox] +ignore_basepython_conflict = True +skip_missing_interpreters = True + minversion = 3.25 toxworkdir = /tmp/.tox/ -envlist = ansible_{2.9,2.10,3.4,4.10,5.1,5.2,6.1} - skipsdist = true [testenv] @@ -23,6 +24,12 @@ deps = ansible_6.1: ansible>=6.1,<6.2 ansible_6.7: ansible>=6.7,<6.8 ansible_7.0: ansible>=7.0,<7.1 + ansible_7.5: ansible>=7.5,<7.6 + ansible_8.0: ansible>=8.0,<8.1 + ansible_8.5: ansible>=8.5,<8.6 + ansible_9.0: ansible>=9.0,<9.1 + ansible_9.5: ansible>=9.5,<9.6 + ansible_10.0: ansible>=10.0,<10.1 #commands_pre = # /usr/bin/find {toxinidir} -type f -not -path '{toxworkdir}/*' -path '*/__pycache__/*' -name '*.py[c|o]' -delete diff --git a/roles/system/molecule/default/group_vars/all/vars.yml b/roles/system/molecule/default/group_vars/all/vars.yml index 9ac822a..a7d9305 100644 --- a/roles/system/molecule/default/group_vars/all/vars.yml +++ b/roles/system/molecule/default/group_vars/all/vars.yml @@ -1,12 +1,10 @@ --- -alertmanager_route: - group_by: - - 'alertname' - - 'service' - group_wait: 30s - group_interval: 5m - repeat_interval: 4h - default_receiver: blackhole +systemd_system: + log_level: "debug" # info + log_target: "" # auto + log_color: true # true + log_location: true # false + log_time: true # false ... diff --git a/roles/system/molecule/default/molecule.yml b/roles/system/molecule/default/molecule.yml index a8c4d00..ba28a37 100644 --- a/roles/system/molecule/default/molecule.yml +++ b/roles/system/molecule/default/molecule.yml @@ -5,12 +5,6 @@ dependency: driver: name: docker -lint: | - set -e - yamllint . - ansible-lint . - flake8 . - platforms: - name: instance image: "bodsch/ansible-${DISTRIBUTION:-debian:12}" diff --git a/roles/system/molecule/default/prepare.yml b/roles/system/molecule/default/prepare.yml index bd4351e..399dd05 100644 --- a/roles/system/molecule/default/prepare.yml +++ b/roles/system/molecule/default/prepare.yml @@ -13,6 +13,9 @@ - name: update pacman system ansible.builtin.command: | pacman --refresh --sync --sysupgrade --noconfirm + register: pacman + changed_when: pacman.rc != 0 + failed_when: pacman.rc != 0 - name: create depends service ansible.builtin.copy: diff --git a/roles/system/templates/systemd/system.conf.j2 b/roles/system/templates/systemd/system.conf.j2 index 5dd5690..c32aff7 100644 --- a/roles/system/templates/systemd/system.conf.j2 +++ b/roles/system/templates/systemd/system.conf.j2 @@ -29,220 +29,220 @@ LogTarget = {{ systemd_system.log_target }} {% if systemd_system.log_color is defined and systemd_system.log_color | string | length > 0 %} {% if systemd_system.log_color | bodsch.core.type == "bool" %} -LogColor = {{ systemd_system.log_color | bool | bodsch.core.config_bool(true_as='yes', false_as='no') }} +LogColor = {{ systemd_system.log_color | bool | bodsch.core.config_bool(true_as='yes', false_as='no') }} {% endif %} {% endif %} {% if systemd_system.log_location is defined and systemd_system.log_location | string | length > 0 %} {% if systemd_system.log_location | bodsch.core.type == "bool" %} -LogLocation = {{ systemd_system.log_location | bool | bodsch.core.config_bool(true_as='yes', false_as='no') }} +LogLocation = {{ systemd_system.log_location | bool | bodsch.core.config_bool(true_as='yes', false_as='no') }} {% endif %} {% endif %} {% if systemd_system.log_time is defined and systemd_system.log_time | string | length > 0 %} {% if systemd_system.log_time | bodsch.core.type == "bool" %} -LogTime = {{ systemd_system.log_time | bool | bodsch.core.config_bool(true_as='yes', false_as='no') }} +LogTime = {{ systemd_system.log_time | bool | bodsch.core.config_bool(true_as='yes', false_as='no') }} {% endif %} {% endif %} {% if systemd_system.dump_core is defined and systemd_system.dump_core | string | length > 0 %} -DumpCore = {{ systemd_system.dump_core | bool | bodsch.core.config_bool(true_as='yes', false_as='no') }} +DumpCore = {{ systemd_system.dump_core | bool | bodsch.core.config_bool(true_as='yes', false_as='no') }} {% endif %} {% if systemd_system.show_status is defined and systemd_system.show_status | string | length > 0 %} -ShowStatus = {{ systemd_system.show_status | bool | bodsch.core.config_bool(true_as='yes', false_as='no') }} +ShowStatus = {{ systemd_system.show_status | bool | bodsch.core.config_bool(true_as='yes', false_as='no') }} {% endif %} {% if systemd_system.crash_change_vt is defined and systemd_system.crash_change_vt | string | length > 0 %} -CrashChangeVT = {{ systemd_system.crash_change_vt | bool | bodsch.core.config_bool(true_as='yes', false_as='no') }} +CrashChangeVT = {{ systemd_system.crash_change_vt | bool | bodsch.core.config_bool(true_as='yes', false_as='no') }} {% endif %} {% if systemd_system.crash_shell is defined and systemd_system.crash_shell | string | length > 0 %} -CrashShell = {{ systemd_system.crash_shell | bool | bodsch.core.config_bool(true_as='yes', false_as='no') }} +CrashShell = {{ systemd_system.crash_shell | bool | bodsch.core.config_bool(true_as='yes', false_as='no') }} {% endif %} {% if systemd_system.crash_reboot is defined and systemd_system.crash_reboot | string | length > 0 %} -CrashReboot = {{ systemd_system.crash_reboot | bool | bodsch.core.config_bool(true_as='yes', false_as='no') }} +CrashReboot = {{ systemd_system.crash_reboot | bool | bodsch.core.config_bool(true_as='yes', false_as='no') }} {% endif %} {% if systemd_system.ctrl_alt_del_burst_action is defined and systemd_system.ctrl_alt_del_burst_action | string | length > 0 %} -CtrlAltDelBurstAction = {{ systemd_system.ctrl_alt_del_burst_action }} +CtrlAltDelBurstAction = {{ systemd_system.ctrl_alt_del_burst_action }} {% endif %} {% if systemd_system.cpu_affinity is defined and systemd_system.cpu_affinity | string | length > 0 %} -CPUAffinity = {{ systemd_system.cpu_affinity }} +CPUAffinity = {{ systemd_system.cpu_affinity }} {% endif %} {% if systemd_system.numa_policy is defined and systemd_system.numa_policy | string | length > 0 %} -NUMAPolicy = {{ systemd_system.numa_policy }} +NUMAPolicy = {{ systemd_system.numa_policy }} {% endif %} {% if systemd_system.numa_mask is defined and systemd_system.numa_mask | string | length > 0 %} -NUMAMask = {{ systemd_system.numa_mask }} +NUMAMask = {{ systemd_system.numa_mask }} {% endif %} {% if systemd_system.runtime_watchdog_sec is defined and systemd_system.runtime_watchdog_sec | string | length > 0 %} -RuntimeWatchdogSec = {{ systemd_system.runtime_watchdog_sec }} +RuntimeWatchdogSec = {{ systemd_system.runtime_watchdog_sec }} {% endif %} {% if systemd_system.runtime_watchdog_pre_sec is defined and systemd_system.runtime_watchdog_pre_sec | string | length > 0 %} -RuntimeWatchdogPreSec = {{ systemd_system.runtime_watchdog_pre_sec }} +RuntimeWatchdogPreSec = {{ systemd_system.runtime_watchdog_pre_sec }} {% endif %} {% if systemd_system.runtime_watchdog_pre_governor is defined and systemd_system.runtime_watchdog_pre_governor | string | length > 0 %} -RuntimeWatchdogPreGovernor = {{ systemd_system.runtime_watchdog_pre_governor }} +RuntimeWatchdogPreGovernor = {{ systemd_system.runtime_watchdog_pre_governor }} {% endif %} {% if systemd_system.reboot_watchdog_sec is defined and systemd_system.reboot_watchdog_sec | string | length > 0 %} -RebootWatchdogSec = {{ systemd_system.reboot_watchdog_sec }} +RebootWatchdogSec = {{ systemd_system.reboot_watchdog_sec }} {% endif %} {% if systemd_system.kexec_watchdog_sec is defined and systemd_system.kexec_watchdog_sec | string | length > 0 %} -KExecWatchdogSec = {{ systemd_system.kexec_watchdog_sec }} +KExecWatchdogSec = {{ systemd_system.kexec_watchdog_sec }} {% endif %} {% if systemd_system.watchdog_device is defined and systemd_system.watchdog_device | string | length > 0 %} -WatchdogDevice = {{ systemd_system.watchdog_device }} +WatchdogDevice = {{ systemd_system.watchdog_device }} {% endif %} {% if systemd_system.capability_bounding_set is defined and systemd_system.capability_bounding_set | string | length > 0 %} -CapabilityBoundingSet = {{ systemd_system.capability_bounding_set }} +CapabilityBoundingSet = {{ systemd_system.capability_bounding_set }} {% endif %} {% if systemd_system.no_new_privileges is defined and systemd_system.no_new_privileges | string | length > 0 %} -NoNewPrivileges = {{ systemd_system.no_new_privileges | bool | bodsch.core.config_bool(true_as='yes', false_as='no') }} +NoNewPrivileges = {{ systemd_system.no_new_privileges | bool | bodsch.core.config_bool(true_as='yes', false_as='no') }} {% endif %} {% if systemd_system.system_call_architectures is defined and systemd_system.system_call_architectures | string | length > 0 %} -SystemCallArchitectures = {{ systemd_system.system_call_architectures }} +SystemCallArchitectures = {{ systemd_system.system_call_architectures }} {% endif %} {% if systemd_system.timer_slack_nsec is defined and systemd_system.timer_slack_nsec | string | length > 0 %} -TimerSlackNSec = {{ systemd_system.timer_slack_nsec }} +TimerSlackNSec = {{ systemd_system.timer_slack_nsec }} {% endif %} {% if systemd_system.status_unit_format is defined and systemd_system.status_unit_format | string | length > 0 %} -StatusUnitFormat = {{ systemd_system.status_unit_format }} +StatusUnitFormat = {{ systemd_system.status_unit_format }} {% endif %} {% if systemd_system.default_timer_accuracy_sec is defined and systemd_system.default_timer_accuracy_sec | string | length > 0 %} -DefaultTimerAccuracySec = {{ systemd_system.default_timer_accuracy_sec }} +DefaultTimerAccuracySec = {{ systemd_system.default_timer_accuracy_sec }} {% endif %} {% if systemd_system.default_standard_output is defined and systemd_system.default_standard_output | string | length > 0 %} -DefaultStandardOutput = {{ systemd_system.default_standard_output }} +DefaultStandardOutput = {{ systemd_system.default_standard_output }} {% endif %} {% if systemd_system.default_standard_error is defined and systemd_system.default_standard_error | string | length > 0 %} -DefaultStandardError = {{ systemd_system.default_standard_error }} +DefaultStandardError = {{ systemd_system.default_standard_error }} {% endif %} {% if systemd_system.default_timeout_start_sec is defined and systemd_system.default_timeout_start_sec | string | length > 0 %} -DefaultTimeoutStartSec = {{ systemd_system.default_timeout_start_sec }} +DefaultTimeoutStartSec = {{ systemd_system.default_timeout_start_sec }} {% endif %} {% if systemd_system.default_timeout_stop_sec is defined and systemd_system.default_timeout_stop_sec | string | length > 0 %} -DefaultTimeoutStopSec = {{ systemd_system.default_timeout_stop_sec }} +DefaultTimeoutStopSec = {{ systemd_system.default_timeout_stop_sec }} {% endif %} {% if systemd_system.default_timeout_abort_sec is defined and systemd_system.default_timeout_abort_sec | string | length > 0 %} -DefaultTimeoutAbortSec = {{ systemd_system.default_timeout_abort_sec }} +DefaultTimeoutAbortSec = {{ systemd_system.default_timeout_abort_sec }} {% endif %} {% if systemd_system.default_device_timeout_sec is defined and systemd_system.default_device_timeout_sec | string | length > 0 %} -DefaultDeviceTimeoutSec = {{ systemd_system.default_device_timeout_sec }} +DefaultDeviceTimeoutSec = {{ systemd_system.default_device_timeout_sec }} {% endif %} {% if systemd_system.default_restart_sec is defined and systemd_system.default_restart_sec | string | length > 0 %} -DefaultRestartSec = {{ systemd_system.default_restart_sec }} +DefaultRestartSec = {{ systemd_system.default_restart_sec }} {% endif %} {% if systemd_system.default_start_limit_interval_sec is defined and systemd_system.default_start_limit_interval_sec | string | length > 0 %} -DefaultStartLimitIntervalSec = {{ systemd_system.default_start_limit_interval_sec }} +DefaultStartLimitIntervalSec = {{ systemd_system.default_start_limit_interval_sec }} {% endif %} {% if systemd_system.default_start_limit_burst is defined and systemd_system.default_start_limit_burst | string | length > 0 %} -DefaultStartLimitBurst = {{ systemd_system.default_start_limit_burst }} +DefaultStartLimitBurst = {{ systemd_system.default_start_limit_burst }} {% endif %} {% if systemd_system.default_environment is defined and systemd_system.default_environment | string | length > 0 %} -DefaultEnvironment = {{ systemd_system.default_environment }} +DefaultEnvironment = {{ systemd_system.default_environment }} {% endif %} {% if systemd_system.default_limit_cpu is defined and systemd_system.default_limit_cpu | string | length > 0 %} -DefaultLimitCPU = {{ systemd_system.default_limit_cpu }} +DefaultLimitCPU = {{ systemd_system.default_limit_cpu }} {% endif %} {% if systemd_system.default_limit_fsize is defined and systemd_system.default_limit_fsize | string | length > 0 %} -DefaultLimitFSIZE = {{ systemd_system.default_limit_fsize }} +DefaultLimitFSIZE = {{ systemd_system.default_limit_fsize }} {% endif %} {% if systemd_system.default_limit_data is defined and systemd_system.default_limit_data | string | length > 0 %} -DefaultLimitDATA = {{ systemd_system.default_limit_data }} +DefaultLimitDATA = {{ systemd_system.default_limit_data }} {% endif %} {% if systemd_system.default_limit_stack is defined and systemd_system.default_limit_stack | string | length > 0 %} -DefaultLimitSTACK = {{ systemd_system.default_limit_stack }} +DefaultLimitSTACK = {{ systemd_system.default_limit_stack }} {% endif %} {% if systemd_system.default_limit_core is defined and systemd_system.default_limit_core | string | length > 0 %} -DefaultLimitCORE = {{ systemd_system.default_limit_core }} +DefaultLimitCORE = {{ systemd_system.default_limit_core }} {% endif %} {% if systemd_system.default_limit_rss is defined and systemd_system.default_limit_rss | string | length > 0 %} -DefaultLimitRSS = {{ systemd_system.default_limit_rss }} +DefaultLimitRSS = {{ systemd_system.default_limit_rss }} {% endif %} {% if systemd_system.default_limit_nofile is defined and systemd_system.default_limit_nofile | string | length > 0 %} -DefaultLimitNOFILE = {{ systemd_system.default_limit_nofile }} +DefaultLimitNOFILE = {{ systemd_system.default_limit_nofile }} {% endif %} {% if systemd_system.default_limit_as is defined and systemd_system.default_limit_as | string | length > 0 %} -DefaultLimitAS = {{ systemd_system.default_limit_as }} +DefaultLimitAS = {{ systemd_system.default_limit_as }} {% endif %} {% if systemd_system.default_limit_nproc is defined and systemd_system.default_limit_nproc | string | length > 0 %} -DefaultLimitNPROC = {{ systemd_system.default_limit_nproc }} +DefaultLimitNPROC = {{ systemd_system.default_limit_nproc }} {% endif %} {% if systemd_system.default_limit_memlock is defined and systemd_system.default_limit_memlock | string | length > 0 %} -DefaultLimitMEMLOCK = {{ systemd_system.default_limit_memlock }} +DefaultLimitMEMLOCK = {{ systemd_system.default_limit_memlock }} {% endif %} {% if systemd_system.default_limit_locks is defined and systemd_system.default_limit_locks | string | length > 0 %} -DefaultLimitLOCKS = {{ systemd_system.default_limit_locks }} +DefaultLimitLOCKS = {{ systemd_system.default_limit_locks }} {% endif %} {% if systemd_system.default_limit_sigpending is defined and systemd_system.default_limit_sigpending | string | length > 0 %} -DefaultLimitSIGPENDING = {{ systemd_system.default_limit_sigpending }} +DefaultLimitSIGPENDING = {{ systemd_system.default_limit_sigpending }} {% endif %} {% if systemd_system.default_limit_msgqueue is defined and systemd_system.default_limit_msgqueue | string | length > 0 %} -DefaultLimitMSGQUEUE = {{ systemd_system.default_limit_msgqueue }} +DefaultLimitMSGQUEUE = {{ systemd_system.default_limit_msgqueue }} {% endif %} {% if systemd_system.default_limit_nice is defined and systemd_system.default_limit_nice | string | length > 0 %} -DefaultLimitNICE = {{ systemd_system.default_limit_nice }} +DefaultLimitNICE = {{ systemd_system.default_limit_nice }} {% endif %} {% if systemd_system.default_limit_rtprio is defined and systemd_system.default_limit_rtprio | string | length > 0 %} -DefaultLimitRTPRIO = {{ systemd_system.default_limit_rtprio }} +DefaultLimitRTPRIO = {{ systemd_system.default_limit_rtprio }} {% endif %} {% if systemd_system.default_limit_rttime is defined and systemd_system.default_limit_rttime | string | length > 0 %} -DefaultLimitRTTIME = {{ systemd_system.default_limit_rttime }} +DefaultLimitRTTIME = {{ systemd_system.default_limit_rttime }} {% endif %} {% if systemd_system.default_limit_msgqueue is defined and systemd_system.default_limit_msgqueue | string | length > 0 %} -DefaultLimitMSGQUEUE = {{ systemd_system.default_limit_msgqueue }} +DefaultLimitMSGQUEUE = {{ systemd_system.default_limit_msgqueue }} {% endif %} {% if systemd_system.default_limit_nice is defined and systemd_system.default_limit_nice | string | length > 0 %} -DefaultLimitNICE = {{ systemd_system.default_limit_nice }} +DefaultLimitNICE = {{ systemd_system.default_limit_nice }} {% endif %} {% if systemd_system.default_limit_rtprio is defined and systemd_system.default_limit_rtprio | string | length > 0 %} -DefaultLimitRTPRIO = {{ systemd_system.default_limit_rtprio }} +DefaultLimitRTPRIO = {{ systemd_system.default_limit_rtprio }} {% endif %} {% if systemd_system.default_memory_pressure_threshold_sec is defined and systemd_system.default_memory_pressure_threshold_sec | string | length > 0 %} @@ -250,21 +250,21 @@ DefaultMemoryPressureThresholdSec = {{ systemd_system.default_memory_pressure_th {% endif %} {% if systemd_system.default_memory_pressure_watch is defined and systemd_system.default_memory_pressure_watch | string | length > 0 %} -DefaultMemoryPressureWatch = {{ systemd_system.default_memory_pressure_watch }} +DefaultMemoryPressureWatch = {{ systemd_system.default_memory_pressure_watch }} {% endif %} {% if systemd_system.default_oom_policy is defined and systemd_system.default_oom_policy | string | length > 0 %} -DefaultOOMPolicy = {{ systemd_system.default_oom_policy }} +DefaultOOMPolicy = {{ systemd_system.default_oom_policy }} {% endif %} {% if systemd_system.default_smack_process_label is defined and systemd_system.default_smack_process_label | string | length > 0 %} -DefaultSmackProcessLabel = {{ systemd_system.default_smack_process_label }} +DefaultSmackProcessLabel = {{ systemd_system.default_smack_process_label }} {% endif %} {% if systemd_system.reload_limit_interval_sec is defined and systemd_system.reload_limit_interval_sec | string | length > 0 %} -ReloadLimitIntervalSec = {{ systemd_system.reload_limit_interval_sec }} +ReloadLimitIntervalSec = {{ systemd_system.reload_limit_interval_sec }} {% endif %} {% if systemd_system.reload_limit_burst is defined and systemd_system.reload_limit_burst | string | length > 0 %} -ReloadLimitBurst = {{ systemd_system.reload_limit_burst }} +ReloadLimitBurst = {{ systemd_system.reload_limit_burst }} {% endif %} diff --git a/roles/system/test-requirements.txt b/roles/system/test-requirements.txt index 267ec92..dc5c9a1 100644 --- a/roles/system/test-requirements.txt +++ b/roles/system/test-requirements.txt @@ -2,10 +2,9 @@ ansible-lint docker dnspython flake8 -molecule>=5.0.1 +molecule molecule-plugins[docker] netaddr -pytest pytest-testinfra tox tox-gh-actions diff --git a/roles/system/tox.ini b/roles/system/tox.ini index d7cb253..c3099d3 100644 --- a/roles/system/tox.ini +++ b/roles/system/tox.ini @@ -1,9 +1,10 @@ [tox] +ignore_basepython_conflict = True +skip_missing_interpreters = True + minversion = 3.25 toxworkdir = /tmp/.tox/ -envlist = ansible_{2.9,2.10,3.4,4.10,5.1,5.2,6.1} - skipsdist = true [testenv] @@ -23,6 +24,12 @@ deps = ansible_6.1: ansible>=6.1,<6.2 ansible_6.7: ansible>=6.7,<6.8 ansible_7.0: ansible>=7.0,<7.1 + ansible_7.5: ansible>=7.5,<7.6 + ansible_8.0: ansible>=8.0,<8.1 + ansible_8.5: ansible>=8.5,<8.6 + ansible_9.0: ansible>=9.0,<9.1 + ansible_9.5: ansible>=9.5,<9.6 + ansible_10.0: ansible>=10.0,<10.1 #commands_pre = # /usr/bin/find {toxinidir} -type f -not -path '{toxworkdir}/*' -path '*/__pycache__/*' -name '*.py[c|o]' -delete diff --git a/roles/timesyncd/molecule/default/molecule.yml b/roles/timesyncd/molecule/default/molecule.yml index a8c4d00..ba28a37 100644 --- a/roles/timesyncd/molecule/default/molecule.yml +++ b/roles/timesyncd/molecule/default/molecule.yml @@ -5,12 +5,6 @@ dependency: driver: name: docker -lint: | - set -e - yamllint . - ansible-lint . - flake8 . - platforms: - name: instance image: "bodsch/ansible-${DISTRIBUTION:-debian:12}" diff --git a/roles/timesyncd/molecule/default/prepare.yml b/roles/timesyncd/molecule/default/prepare.yml index bd4351e..399dd05 100644 --- a/roles/timesyncd/molecule/default/prepare.yml +++ b/roles/timesyncd/molecule/default/prepare.yml @@ -13,6 +13,9 @@ - name: update pacman system ansible.builtin.command: | pacman --refresh --sync --sysupgrade --noconfirm + register: pacman + changed_when: pacman.rc != 0 + failed_when: pacman.rc != 0 - name: create depends service ansible.builtin.copy: diff --git a/roles/timesyncd/test-requirements.txt b/roles/timesyncd/test-requirements.txt index 267ec92..dc5c9a1 100644 --- a/roles/timesyncd/test-requirements.txt +++ b/roles/timesyncd/test-requirements.txt @@ -2,10 +2,9 @@ ansible-lint docker dnspython flake8 -molecule>=5.0.1 +molecule molecule-plugins[docker] netaddr -pytest pytest-testinfra tox tox-gh-actions diff --git a/roles/timesyncd/tox.ini b/roles/timesyncd/tox.ini index d7cb253..c3099d3 100644 --- a/roles/timesyncd/tox.ini +++ b/roles/timesyncd/tox.ini @@ -1,9 +1,10 @@ [tox] +ignore_basepython_conflict = True +skip_missing_interpreters = True + minversion = 3.25 toxworkdir = /tmp/.tox/ -envlist = ansible_{2.9,2.10,3.4,4.10,5.1,5.2,6.1} - skipsdist = true [testenv] @@ -23,6 +24,12 @@ deps = ansible_6.1: ansible>=6.1,<6.2 ansible_6.7: ansible>=6.7,<6.8 ansible_7.0: ansible>=7.0,<7.1 + ansible_7.5: ansible>=7.5,<7.6 + ansible_8.0: ansible>=8.0,<8.1 + ansible_8.5: ansible>=8.5,<8.6 + ansible_9.0: ansible>=9.0,<9.1 + ansible_9.5: ansible>=9.5,<9.6 + ansible_10.0: ansible>=10.0,<10.1 #commands_pre = # /usr/bin/find {toxinidir} -type f -not -path '{toxworkdir}/*' -path '*/__pycache__/*' -name '*.py[c|o]' -delete diff --git a/roles/user/molecule/default/prepare.yml b/roles/user/molecule/default/prepare.yml index bd4351e..399dd05 100644 --- a/roles/user/molecule/default/prepare.yml +++ b/roles/user/molecule/default/prepare.yml @@ -13,6 +13,9 @@ - name: update pacman system ansible.builtin.command: | pacman --refresh --sync --sysupgrade --noconfirm + register: pacman + changed_when: pacman.rc != 0 + failed_when: pacman.rc != 0 - name: create depends service ansible.builtin.copy: diff --git a/roles/user/test-requirements.txt b/roles/user/test-requirements.txt index 267ec92..dc5c9a1 100644 --- a/roles/user/test-requirements.txt +++ b/roles/user/test-requirements.txt @@ -2,10 +2,9 @@ ansible-lint docker dnspython flake8 -molecule>=5.0.1 +molecule molecule-plugins[docker] netaddr -pytest pytest-testinfra tox tox-gh-actions diff --git a/roles/user/tox.ini b/roles/user/tox.ini index d7cb253..c3099d3 100644 --- a/roles/user/tox.ini +++ b/roles/user/tox.ini @@ -1,9 +1,10 @@ [tox] +ignore_basepython_conflict = True +skip_missing_interpreters = True + minversion = 3.25 toxworkdir = /tmp/.tox/ -envlist = ansible_{2.9,2.10,3.4,4.10,5.1,5.2,6.1} - skipsdist = true [testenv] @@ -23,6 +24,12 @@ deps = ansible_6.1: ansible>=6.1,<6.2 ansible_6.7: ansible>=6.7,<6.8 ansible_7.0: ansible>=7.0,<7.1 + ansible_7.5: ansible>=7.5,<7.6 + ansible_8.0: ansible>=8.0,<8.1 + ansible_8.5: ansible>=8.5,<8.6 + ansible_9.0: ansible>=9.0,<9.1 + ansible_9.5: ansible>=9.5,<9.6 + ansible_10.0: ansible>=10.0,<10.1 #commands_pre = # /usr/bin/find {toxinidir} -type f -not -path '{toxworkdir}/*' -path '*/__pycache__/*' -name '*.py[c|o]' -delete From 663f49b83aad0ee2b510acec658af896dd364854 Mon Sep 17 00:00:00 2001 From: Bodo Schulz Date: Mon, 10 Jun 2024 16:54:11 +0200 Subject: [PATCH 2/9] add unit_file.py to create own unit files --- plugins/modules/unit_file.py | 140 +++++++++ roles/systemd_unit/.ansible-lint | 6 + roles/systemd_unit/.editorconfig | 23 ++ roles/systemd_unit/.flake8 | 19 ++ roles/systemd_unit/.gitignore | 6 + roles/systemd_unit/.yamllint | 36 +++ roles/systemd_unit/CONTRIBUTING.md | 31 ++ roles/systemd_unit/LICENSE | 201 +++++++++++++ roles/systemd_unit/Makefile | 22 ++ roles/systemd_unit/README.md | 0 roles/systemd_unit/defaults/main.yml | 5 + roles/systemd_unit/hooks/converge | 3 + roles/systemd_unit/hooks/destroy | 3 + roles/systemd_unit/hooks/lint | 3 + roles/systemd_unit/hooks/molecule.rc | 9 + roles/systemd_unit/hooks/test | 3 + roles/systemd_unit/hooks/tox.sh | 26 ++ roles/systemd_unit/hooks/verify | 3 + .../molecule/default/converge.yml | 8 + .../molecule/default/group_vars/all/vars.yml | 107 +++++++ .../molecule/default/molecule.yml | 56 ++++ .../systemd_unit/molecule/default/prepare.yml | 48 ++++ .../molecule/default/tests/test_default.py | 125 ++++++++ roles/systemd_unit/tasks/main.yml | 20 ++ .../templates/systemd/system.conf.j2 | 270 ++++++++++++++++++ roles/systemd_unit/test-requirements.txt | 11 + roles/systemd_unit/tox.ini | 39 +++ roles/systemd_unit/vars/main.yml | 5 + 28 files changed, 1228 insertions(+) create mode 100644 plugins/modules/unit_file.py create mode 100644 roles/systemd_unit/.ansible-lint create mode 100644 roles/systemd_unit/.editorconfig create mode 100644 roles/systemd_unit/.flake8 create mode 100644 roles/systemd_unit/.gitignore create mode 100644 roles/systemd_unit/.yamllint create mode 100644 roles/systemd_unit/CONTRIBUTING.md create mode 100644 roles/systemd_unit/LICENSE create mode 100644 roles/systemd_unit/Makefile create mode 100644 roles/systemd_unit/README.md create mode 100644 roles/systemd_unit/defaults/main.yml create mode 100755 roles/systemd_unit/hooks/converge create mode 100755 roles/systemd_unit/hooks/destroy create mode 100755 roles/systemd_unit/hooks/lint create mode 100644 roles/systemd_unit/hooks/molecule.rc create mode 100755 roles/systemd_unit/hooks/test create mode 100755 roles/systemd_unit/hooks/tox.sh create mode 100755 roles/systemd_unit/hooks/verify create mode 100644 roles/systemd_unit/molecule/default/converge.yml create mode 100644 roles/systemd_unit/molecule/default/group_vars/all/vars.yml create mode 100644 roles/systemd_unit/molecule/default/molecule.yml create mode 100644 roles/systemd_unit/molecule/default/prepare.yml create mode 100644 roles/systemd_unit/molecule/default/tests/test_default.py create mode 100644 roles/systemd_unit/tasks/main.yml create mode 100644 roles/systemd_unit/templates/systemd/system.conf.j2 create mode 100644 roles/systemd_unit/test-requirements.txt create mode 100644 roles/systemd_unit/tox.ini create mode 100644 roles/systemd_unit/vars/main.yml diff --git a/plugins/modules/unit_file.py b/plugins/modules/unit_file.py new file mode 100644 index 0000000..e8cc49b --- /dev/null +++ b/plugins/modules/unit_file.py @@ -0,0 +1,140 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +# (c) 2020-2023, Bodo Schulz +# Apache-2.0 (see LICENSE or https://opensource.org/license/apache-2-0) +# SPDX-License-Identifier: Apache-2.0 + +from __future__ import absolute_import, division, print_function + +import os +from ansible_collections.bodsch.core.plugins.module_utils.directory import create_directory +from ansible_collections.bodsch.core.plugins.module_utils.checksum import Checksum + +from ansible.module_utils.basic import AnsibleModule + + +class SystemdUnitFile(object): + """ + """ + module = None + + def __init__(self, module): + """ + """ + self.module = module + + # self._journalctl = module.get_bin_path("journalctl", True) + + self.unit_type = module.params.get("unit_type") + self.name = module.params.get("name") + self.overwrite = module.params.get("overwrite") + self.drop_ins = module.params.get("drop_ins") + self.unit = module.params.get("unit") + self.service = module.params.get("service") + self.install = module.params.get("install") + + # module.log(msg="----------------------------") + # module.log(msg=f" journalctl : {self._journalctl}") + # module.log(msg=f" unit : {self.unit}") + # module.log(msg=f" identifier : {self.identifier}") + # module.log(msg=f" lines : {self.lines}") + # module.log(msg=f" reverse : {self.reverse}") + # module.log(msg=f" arguments : {self.arguments}") + # module.log(msg="----------------------------") + + def run(self): + """ + """ + result = dict( + rc=1, + failed=True, + changed=False, + ) + + if len(self.drop_ins) > 0: + self.module.log(msg="----------------------------") + service_name = f"/etc/systemd/system/{self.name}.d" + self.module.log(msg=f" service name : {service_name}") + + if not os.path.exists(service_name): + create_directory(service_name) + + for drop_in in self.drop_ins: + + + self.module.log(msg=f" drop in name : {drop_in}") + + file_name = f"{service_name}/{drop_in.get('name')}.conf" + if not os.path.exists(file_name): + with open(file_name, "w") as f: + f.write("# ansible controlled") + + self.module.log(msg="----------------------------") + + + # result = self.journalctl_lines() + + return result + + +def main(): + """ + """ + args = dict( + unit_type=dict( + required=True, + choose=[ + "service", + "socket", + "timer" + ], + type="str" + ), + name=dict( + required=True, + type="str" + ), + overwrite=dict( + required=False, + default=False, + type="bool" + ), + drop_ins=dict( + required=False, + default=[], + type=list + ), + unit=dict( + required=False, + default={}, + type=dict + ), + service=dict( + required=False, + default={}, + type=dict + ), + install=dict( + required=False, + default={}, + type=dict + ), + ) + + module = AnsibleModule( + argument_spec=args, + supports_check_mode=False, + ) + + k = SystemdUnitFile(module) + result = k.run() + + module.log(msg=f"= result: {result}") + + module.exit_json(**result) + + +# import module snippets +if __name__ == "__main__": + main() diff --git a/roles/systemd_unit/.ansible-lint b/roles/systemd_unit/.ansible-lint new file mode 100644 index 0000000..5343e85 --- /dev/null +++ b/roles/systemd_unit/.ansible-lint @@ -0,0 +1,6 @@ +--- + +skip_list: + - name[casing] + - name[template] + - syntax-check[specific] diff --git a/roles/systemd_unit/.editorconfig b/roles/systemd_unit/.editorconfig new file mode 100644 index 0000000..898cdbd --- /dev/null +++ b/roles/systemd_unit/.editorconfig @@ -0,0 +1,23 @@ +# EditorConfig helps developers define and maintain consistent +# coding styles between different editors and IDEs +# https://editorconfig.org/ + + +root = true + +[*] +indent_style = space +indent_size = 2 + +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true +max_line_length = 100 + +[*.py] +indent_style = space +indent_size = 4 + +[*.md] +trim_trailing_whitespace = false diff --git a/roles/systemd_unit/.flake8 b/roles/systemd_unit/.flake8 new file mode 100644 index 0000000..1962f7e --- /dev/null +++ b/roles/systemd_unit/.flake8 @@ -0,0 +1,19 @@ +[flake8] + +# E221 multiple spaces before operator +# E251 unexpected spaces around keyword / parameter equals + +ignore = E221,E251 + +exclude = + # No need to traverse our git directory + .git, + # There's no value in checking cache directories + __pycache__, + .tox + +# E203: https://github.com/python/black/issues/315 +# ignore = D,E741,W503,W504,H,E501,E203 + +max-line-length = 195 + diff --git a/roles/systemd_unit/.gitignore b/roles/systemd_unit/.gitignore new file mode 100644 index 0000000..3d35e6a --- /dev/null +++ b/roles/systemd_unit/.gitignore @@ -0,0 +1,6 @@ +.tox +.galaxy_install_info +*kate-swp +__pycache__ +.cache +.directory diff --git a/roles/systemd_unit/.yamllint b/roles/systemd_unit/.yamllint new file mode 100644 index 0000000..e3f52af --- /dev/null +++ b/roles/systemd_unit/.yamllint @@ -0,0 +1,36 @@ +--- +# Based on ansible-lint config +extends: default + +rules: + braces: + max-spaces-inside: 1 + level: error + brackets: + max-spaces-inside: 1 + level: error + colons: + max-spaces-after: -1 + level: error + commas: + max-spaces-after: -1 + level: error + comments: disable + comments-indentation: disable + document-start: disable + empty-lines: + max: 3 + level: error + hyphens: + level: error + indentation: + spaces: 2 + key-duplicates: enable + line-length: + max: 195 + level: warning + new-line-at-end-of-file: disable + new-lines: + type: unix + trailing-spaces: disable + truthy: disable diff --git a/roles/systemd_unit/CONTRIBUTING.md b/roles/systemd_unit/CONTRIBUTING.md new file mode 100644 index 0000000..e3cd4cc --- /dev/null +++ b/roles/systemd_unit/CONTRIBUTING.md @@ -0,0 +1,31 @@ +Contributing +============ +If you want to contribute to a project and make it better, your help is very welcome. +Contributing is also a great way to learn more about social coding on Github, new technologies and +and their ecosystems and how to make constructive, helpful bug reports, feature requests and the +noblest of all contributions: a good, clean pull request. + +### How to make a clean pull request + +Look for a project's contribution instructions. If there are any, follow them. + +- Create a personal fork of the project on Github. +- Clone the fork on your local machine. Your remote repo on Github is called `origin`. +- Add the original repository as a remote called `upstream`. +- If you created your fork a while ago be sure to pull upstream changes into your local repository. +- Create a new branch to work on! Branch from `develop` if it exists, else from `master`. +- Implement/fix your feature, comment your code. +- Follow the code style of the project, including indentation. +- If the project has tests run them! +- Write or adapt tests as needed. +- Add or change the documentation as needed. +- Squash your commits into a single commit. Create a new branch if necessary. +- Push your branch to your fork on Github, the remote `origin`. +- From your fork open a pull request in the correct branch. Target the project's `develop` branch if there is one, else go for `master`! +- If the maintainer requests further changes just push them to your branch. The PR will be updated automatically. +- Once the pull request is approved and merged you can pull the changes from `upstream` to your local repo and delete + your extra branch(es). + +And last but not least: Always write your commit messages in the present tense. +Your commit message should describe what the commit, when applied, does to the +code – not what you did to the code. diff --git a/roles/systemd_unit/LICENSE b/roles/systemd_unit/LICENSE new file mode 100644 index 0000000..8c8472f --- /dev/null +++ b/roles/systemd_unit/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2020-2021 Bodo Schulz + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/roles/systemd_unit/Makefile b/roles/systemd_unit/Makefile new file mode 100644 index 0000000..3abaf48 --- /dev/null +++ b/roles/systemd_unit/Makefile @@ -0,0 +1,22 @@ +# +export TOX_SCENARIO ?= default +export TOX_ANSIBLE ?= ansible_6.1 + +.PHONY: converge destroy verify test lint + +default: converge + +converge: + @hooks/converge + +destroy: + @hooks/destroy + +verify: + @hooks/verify + +test: + @hooks/test + +lint: + @hooks/lint diff --git a/roles/systemd_unit/README.md b/roles/systemd_unit/README.md new file mode 100644 index 0000000..e69de29 diff --git a/roles/systemd_unit/defaults/main.yml b/roles/systemd_unit/defaults/main.yml new file mode 100644 index 0000000..83b94ed --- /dev/null +++ b/roles/systemd_unit/defaults/main.yml @@ -0,0 +1,5 @@ +--- + +systemd_unit: [] + +... diff --git a/roles/systemd_unit/hooks/converge b/roles/systemd_unit/hooks/converge new file mode 100755 index 0000000..0c50932 --- /dev/null +++ b/roles/systemd_unit/hooks/converge @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +hooks/tox.sh "converge" diff --git a/roles/systemd_unit/hooks/destroy b/roles/systemd_unit/hooks/destroy new file mode 100755 index 0000000..b4a3f8d --- /dev/null +++ b/roles/systemd_unit/hooks/destroy @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +hooks/tox.sh "destroy" diff --git a/roles/systemd_unit/hooks/lint b/roles/systemd_unit/hooks/lint new file mode 100755 index 0000000..ef226a0 --- /dev/null +++ b/roles/systemd_unit/hooks/lint @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +hooks/tox.sh "lint" diff --git a/roles/systemd_unit/hooks/molecule.rc b/roles/systemd_unit/hooks/molecule.rc new file mode 100644 index 0000000..a15f7c3 --- /dev/null +++ b/roles/systemd_unit/hooks/molecule.rc @@ -0,0 +1,9 @@ + +TOX_ARGS= + +if [ -n "${TOX_SCENARIO}" ] +then + TOX_ARGS="--scenario-name ${TOX_SCENARIO}" +fi + +TOX_OPTS="-e ${TOX_ANSIBLE}" diff --git a/roles/systemd_unit/hooks/test b/roles/systemd_unit/hooks/test new file mode 100755 index 0000000..2869139 --- /dev/null +++ b/roles/systemd_unit/hooks/test @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +hooks/tox.sh "test" diff --git a/roles/systemd_unit/hooks/tox.sh b/roles/systemd_unit/hooks/tox.sh new file mode 100755 index 0000000..62bb777 --- /dev/null +++ b/roles/systemd_unit/hooks/tox.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash + +. hooks/molecule.rc + +TOX_TEST="${1}" + +if [ -f "./collections.yml" ] +then + for collection in $(grep -v "#" collections.yml | grep "^ - name: " | awk -F ': ' '{print $2}') + do + collections_installed="$(ansible-galaxy collection list | grep ${collection} 2> /dev/null)" + + if [ -z "${collections_installed}" ] + then + echo "Install the required collection '${collection}'" + ansible-galaxy collection install ${collection} + else + collection_version=$(echo "${collections_installed}" | awk -F ' ' '{print $2}') + + echo "The required collection '${collection}' is installed in version ${collection_version}." + fi + done + echo "" +fi + +tox ${TOX_OPTS} -- molecule ${TOX_TEST} ${TOX_ARGS} diff --git a/roles/systemd_unit/hooks/verify b/roles/systemd_unit/hooks/verify new file mode 100755 index 0000000..5f436af --- /dev/null +++ b/roles/systemd_unit/hooks/verify @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +hooks/tox.sh "verify" diff --git a/roles/systemd_unit/molecule/default/converge.yml b/roles/systemd_unit/molecule/default/converge.yml new file mode 100644 index 0000000..fa8cdb5 --- /dev/null +++ b/roles/systemd_unit/molecule/default/converge.yml @@ -0,0 +1,8 @@ +--- + +- name: converge + hosts: instance + any_errors_fatal: false + + roles: + - role: bodsch.systemd.systemd_unit diff --git a/roles/systemd_unit/molecule/default/group_vars/all/vars.yml b/roles/systemd_unit/molecule/default/group_vars/all/vars.yml new file mode 100644 index 0000000..962c434 --- /dev/null +++ b/roles/systemd_unit/molecule/default/group_vars/all/vars.yml @@ -0,0 +1,107 @@ +--- + +systemd_unit: + - name: "getty@tty1" + unit_type: service + overwrite: true + drop_ins: + - name: autologin + service: + exec_start: unsafe! + - "-/sbin/agetty -o '-p -f -- \\u' --noclear --autologin username %I $TERM" + type: simple + + - name: noclear + service: + TTYVTDisallocate: false + # - name: chronyd + # unit_type: service + # overwrite: false + # unit: + # Description: "NTP client/server" + # Documentation: "man:chronyd(8) man:chrony.conf(5)" + # After: + # - ntpdate.service + # - sntp.service + # - ntpd.service + # Conflicts: + # - ntpd.service + # - systemd-timesyncd.service + # ConditionCapability: + # - CAP_SYS_TIME + # service: + # Type: forking + # PIDFile: /run/chrony/chronyd.pid + # EnvironmentFile: + # - "-/etc/sysconfig/chronyd" + # ExecStart: + # - "/usr/bin/chronyd $OPTIONS" + # + # CapabilityBoundingSet: + # - CAP_AUDIT_CONTROL + # - CAP_AUDIT_READ + # - CAP_AUDIT_WRITE + # - CAP_BLOCK_SUSPEND + # - CAP_KILL + # - CAP_LEASE + # - CAP_LINUX_IMMUTABLE + # - CAP_MAC_ADMIN + # - CAP_MAC_OVERRIDE + # - CAP_MKNOD + # - CAP_SYS_ADMIN + # - CAP_SYS_BOOT + # - CAP_SYS_CHROOT + # - CAP_SYS_MODULE + # - CAP_SYS_PACCT + # - CAP_SYS_PTRACE + # - CAP_SYS_RAWIO + # - CAP_SYS_TTY_CONFIG + # - CAP_WAKE_ALARM + # DeviceAllow: + # - char-pps rw + # - char-ptp rw + # - char-rtc rw + # DevicePolicy: closed + # LockPersonality: true + # MemoryDenyWriteExecute: true + # NoNewPrivileges: true + # PrivateTmp: true + # ProtectControlGroups: true + # ProtectHome: true + # ProtectHostname: true + # ProtectKernelLogs: true + # ProtectKernelModules: true + # ProtectKernelTunables: true + # ProtectProc: invisible + # ProtectSystem: strict + # ReadWritePaths: + # - /run + # - /var/lib/chrony + # - -/var/log + # RestrictAddressFamilies: + # - AF_INET + # - AF_INET6 + # - AF_UNIX + # RestrictNamespaces: true + # RestrictSUIDSGID: true + # SystemCallArchitectures: native + # SystemCallFilter: + # - "@cpu-emulation" + # - "@debug" + # - "@module" + # - "@mount" + # - "@obsolete" + # - "@raw-io" + # - "@reboot" + # - "@swap" + # + # # Adjust restrictions for /usr/bin/sendmail (mailonchange directive) + # # NoNewPrivileges: false + # # ReadWritePaths: + # # - -/var/spool + # # RestrictAddressFamilies: + # # - AF_NETLINK + # + # install: + # WantedBy: multi-user.target +... diff --git a/roles/systemd_unit/molecule/default/molecule.yml b/roles/systemd_unit/molecule/default/molecule.yml new file mode 100644 index 0000000..ba28a37 --- /dev/null +++ b/roles/systemd_unit/molecule/default/molecule.yml @@ -0,0 +1,56 @@ +--- +dependency: + name: galaxy + +driver: + name: docker + +platforms: + - name: instance + image: "bodsch/ansible-${DISTRIBUTION:-debian:12}" + command: ${MOLECULE_DOCKER_COMMAND:-""} + docker_host: "${DOCKER_HOST:-unix://run/docker.sock}" + privileged: true + pre_build_image: true + cgroupns_mode: host + mounts: + - source: /sys/fs/cgroup + target: /sys/fs/cgroup + type: bind + read_only: false + volumes: + - /var/lib/containerd + capabilities: + - SYS_ADMIN + tmpfs: + - /run + - /tmp + +provisioner: + name: ansible + ansible_args: + - --diff + - -v + config_options: + defaults: + deprecation_warnings: true + stdout_callback: yaml + callbacks_enabled: profile_tasks + gathering: smart + fact_caching: jsonfile + fact_caching_timeout: 8640 + fact_caching_connection: ansible_facts + +scenario: + test_sequence: + - destroy + - dependency + - syntax + - create + - prepare + - converge + - verify + - destroy + +verifier: + name: testinfra diff --git a/roles/systemd_unit/molecule/default/prepare.yml b/roles/systemd_unit/molecule/default/prepare.yml new file mode 100644 index 0000000..edd82c8 --- /dev/null +++ b/roles/systemd_unit/molecule/default/prepare.yml @@ -0,0 +1,48 @@ +--- + +- name: information + hosts: all + gather_facts: true + + pre_tasks: + - name: arch- / artixlinux + when: + - ansible_distribution | lower == 'archlinux' or + ansible_os_family | lower == 'artix linux' + block: + - name: update pacman system + ansible.builtin.command: | + pacman --refresh --sync --sysupgrade --noconfirm + register: pacman + changed_when: pacman.rc != 0 + failed_when: pacman.rc != 0 + + - name: create depends service + ansible.builtin.copy: + mode: 0755 + dest: /etc/init.d/net + content: | + #!/usr/bin/openrc-run + true + when: + - ansible_os_family | lower == 'artix linux' + + - name: update package cache + become: true + ansible.builtin.package: + update_cache: true + + - name: environment + ansible.builtin.debug: + msg: + - "os family : {{ ansible_distribution }} ({{ ansible_os_family }})" + - "distribution version : {{ ansible_distribution_major_version }}" + - "ansible version : {{ ansible_version.full }}" + - "python version : {{ ansible_python.version.major }}.{{ ansible_python.version.minor }}" + +- name: converge + hosts: instance + any_errors_fatal: false + + roles: + - role: bodsch.systemd.system diff --git a/roles/systemd_unit/molecule/default/tests/test_default.py b/roles/systemd_unit/molecule/default/tests/test_default.py new file mode 100644 index 0000000..422e777 --- /dev/null +++ b/roles/systemd_unit/molecule/default/tests/test_default.py @@ -0,0 +1,125 @@ +# coding: utf-8 +from __future__ import unicode_literals + +from ansible.parsing.dataloader import DataLoader +from ansible.template import Templar + +import json +import pytest +import os + +import testinfra.utils.ansible_runner + +HOST = 'instance' + +testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner( + os.environ['MOLECULE_INVENTORY_FILE']).get_hosts(HOST) + + +def pp_json(json_thing, sort=True, indents=2): + if type(json_thing) is str: + print(json.dumps(json.loads(json_thing), sort_keys=sort, indent=indents)) + else: + print(json.dumps(json_thing, sort_keys=sort, indent=indents)) + return None + + +def base_directory(): + """ + """ + cwd = os.getcwd() + + if 'group_vars' in os.listdir(cwd): + directory = "../.." + molecule_directory = "." + else: + directory = "." + molecule_directory = f"molecule/{os.environ.get('MOLECULE_SCENARIO_NAME')}" + + return directory, molecule_directory + + +def read_ansible_yaml(file_name, role_name): + """ + """ + read_file = None + + for e in ["yml", "yaml"]: + test_file = f"{file_name}.{e}" + if os.path.isfile(test_file): + read_file = test_file + break + + return f"file={read_file} name={role_name}" + + +@pytest.fixture() +def get_vars(host): + """ + parse ansible variables + - defaults/main.yml + - vars/main.yml + - vars/${DISTRIBUTION}.yaml + - molecule/${MOLECULE_SCENARIO_NAME}/group_vars/all/vars.yml + """ + base_dir, molecule_dir = base_directory() + distribution = host.system_info.distribution + operation_system = None + + if distribution in ['debian', 'ubuntu']: + operation_system = "debian" + elif distribution in ['redhat', 'ol', 'centos', 'rocky', 'almalinux']: + operation_system = "redhat" + elif distribution in ['arch', 'artix']: + operation_system = f"{distribution}linux" + + # print(" -> {} / {}".format(distribution, os)) + # print(" -> {}".format(base_dir)) + + file_defaults = read_ansible_yaml(f"{base_dir}/defaults/main", "role_defaults") + file_vars = read_ansible_yaml(f"{base_dir}/vars/main", "role_vars") + file_distibution = read_ansible_yaml(f"{base_dir}/vars/{operation_system}", "role_distibution") + file_molecule = read_ansible_yaml(f"{molecule_dir}/group_vars/all/vars", "test_vars") + # file_host_molecule = read_ansible_yaml("{}/host_vars/{}/vars".format(base_dir, HOST), "host_vars") + + defaults_vars = host.ansible("include_vars", file_defaults).get("ansible_facts").get("role_defaults") + vars_vars = host.ansible("include_vars", file_vars).get("ansible_facts").get("role_vars") + distibution_vars = host.ansible("include_vars", file_distibution).get("ansible_facts").get("role_distibution") + molecule_vars = host.ansible("include_vars", file_molecule).get("ansible_facts").get("test_vars") + # host_vars = host.ansible("include_vars", file_host_molecule).get("ansible_facts").get("host_vars") + + ansible_vars = defaults_vars + ansible_vars.update(vars_vars) + ansible_vars.update(distibution_vars) + ansible_vars.update(molecule_vars) + # ansible_vars.update(host_vars) + + templar = Templar(loader=DataLoader(), variables=ansible_vars) + result = templar.template(ansible_vars, fail_on_undefined=False) + + return result + + +def local_facts(host): + """ + return local facts + """ + return host.ansible("setup").get("ansible_facts").get("ansible_local").get("system") + + +@pytest.mark.parametrize("directories", [ + "/etc/systemd", +]) +def test_directories(host, directories): + d = host.file(directories) + assert d.is_directory + + +@pytest.mark.parametrize("files", [ + "/etc/systemd/system.conf", +]) +def test_systemd_files(host, files): + """ + """ + d = host.file(files) + assert d.is_file diff --git a/roles/systemd_unit/tasks/main.yml b/roles/systemd_unit/tasks/main.yml new file mode 100644 index 0000000..273f217 --- /dev/null +++ b/roles/systemd_unit/tasks/main.yml @@ -0,0 +1,20 @@ +--- + +- name: create systemd unit files + bodsch.systemd.unit_file: + name: "{{ item.name }}" + unit_type: "{{ item.unit_type }}" + overwrite: "{{ item.overwrite }}" + drop_ins: "{{ item.drop_ins | default(omit) }}" + unit: "{{ item.drop_ins | default(omit) }}" + service: "{{ item.drop_ins | default(omit) }}" + install: "{{ item.drop_ins | default(omit) }}" + loop: + "{{ systemd_unit }}" + loop_control: + label: "{{ item.name }}" + + when: + - systemd_unit | count > 0 + +... diff --git a/roles/systemd_unit/templates/systemd/system.conf.j2 b/roles/systemd_unit/templates/systemd/system.conf.j2 new file mode 100644 index 0000000..5dd5690 --- /dev/null +++ b/roles/systemd_unit/templates/systemd/system.conf.j2 @@ -0,0 +1,270 @@ +#jinja2: trim_blocks: True, lstrip_blocks: True +# {{ ansible_managed }} +# This file is part of systemd. +# +# systemd is free software; you can redistribute it and/or modify it under the +# terms of the GNU Lesser General Public License as published by the Free +# Software Foundation; either version 2.1 of the License, or (at your option) +# any later version. +# +# Entries in this file show the compile time defaults. Local configuration +# should be created by either modifying this file, or by creating "drop-ins" in +# the system.conf.d/ subdirectory. The latter is generally recommended. +# Defaults can be restored by simply deleting this file and all drop-ins. +# +# Use 'systemd-analyze cat-config systemd/system.conf' to display the full config. +# +# See systemd-system.conf(5) for details. + +[Manager] +{% if systemd_system.log_level is defined and + systemd_system.log_level | string | length > 0 and + systemd_system.log_level in ["emerg", "alert", "crit", "err", "warning", "notice", "info", "debug"] %} +LogLevel = {{ systemd_system.log_level }} +{% endif %} +{% if systemd_system.log_target is defined and + systemd_system.log_target | string | length > 0 %} +LogTarget = {{ systemd_system.log_target }} +{% endif %} +{% if systemd_system.log_color is defined and + systemd_system.log_color | string | length > 0 %} + {% if systemd_system.log_color | bodsch.core.type == "bool" %} +LogColor = {{ systemd_system.log_color | bool | bodsch.core.config_bool(true_as='yes', false_as='no') }} + {% endif %} +{% endif %} +{% if systemd_system.log_location is defined and + systemd_system.log_location | string | length > 0 %} + {% if systemd_system.log_location | bodsch.core.type == "bool" %} +LogLocation = {{ systemd_system.log_location | bool | bodsch.core.config_bool(true_as='yes', false_as='no') }} + {% endif %} +{% endif %} +{% if systemd_system.log_time is defined and + systemd_system.log_time | string | length > 0 %} + {% if systemd_system.log_time | bodsch.core.type == "bool" %} +LogTime = {{ systemd_system.log_time | bool | bodsch.core.config_bool(true_as='yes', false_as='no') }} + {% endif %} +{% endif %} +{% if systemd_system.dump_core is defined and + systemd_system.dump_core | string | length > 0 %} +DumpCore = {{ systemd_system.dump_core | bool | bodsch.core.config_bool(true_as='yes', false_as='no') }} +{% endif %} +{% if systemd_system.show_status is defined and + systemd_system.show_status | string | length > 0 %} +ShowStatus = {{ systemd_system.show_status | bool | bodsch.core.config_bool(true_as='yes', false_as='no') }} +{% endif %} +{% if systemd_system.crash_change_vt is defined and + systemd_system.crash_change_vt | string | length > 0 %} +CrashChangeVT = {{ systemd_system.crash_change_vt | bool | bodsch.core.config_bool(true_as='yes', false_as='no') }} +{% endif %} +{% if systemd_system.crash_shell is defined and + systemd_system.crash_shell | string | length > 0 %} +CrashShell = {{ systemd_system.crash_shell | bool | bodsch.core.config_bool(true_as='yes', false_as='no') }} +{% endif %} +{% if systemd_system.crash_reboot is defined and + systemd_system.crash_reboot | string | length > 0 %} +CrashReboot = {{ systemd_system.crash_reboot | bool | bodsch.core.config_bool(true_as='yes', false_as='no') }} +{% endif %} +{% if systemd_system.ctrl_alt_del_burst_action is defined and + systemd_system.ctrl_alt_del_burst_action | string | length > 0 %} +CtrlAltDelBurstAction = {{ systemd_system.ctrl_alt_del_burst_action }} +{% endif %} +{% if systemd_system.cpu_affinity is defined and + systemd_system.cpu_affinity | string | length > 0 %} +CPUAffinity = {{ systemd_system.cpu_affinity }} +{% endif %} +{% if systemd_system.numa_policy is defined and + systemd_system.numa_policy | string | length > 0 %} +NUMAPolicy = {{ systemd_system.numa_policy }} +{% endif %} +{% if systemd_system.numa_mask is defined and + systemd_system.numa_mask | string | length > 0 %} +NUMAMask = {{ systemd_system.numa_mask }} +{% endif %} +{% if systemd_system.runtime_watchdog_sec is defined and + systemd_system.runtime_watchdog_sec | string | length > 0 %} +RuntimeWatchdogSec = {{ systemd_system.runtime_watchdog_sec }} +{% endif %} +{% if systemd_system.runtime_watchdog_pre_sec is defined and + systemd_system.runtime_watchdog_pre_sec | string | length > 0 %} +RuntimeWatchdogPreSec = {{ systemd_system.runtime_watchdog_pre_sec }} +{% endif %} +{% if systemd_system.runtime_watchdog_pre_governor is defined and + systemd_system.runtime_watchdog_pre_governor | string | length > 0 %} +RuntimeWatchdogPreGovernor = {{ systemd_system.runtime_watchdog_pre_governor }} +{% endif %} +{% if systemd_system.reboot_watchdog_sec is defined and + systemd_system.reboot_watchdog_sec | string | length > 0 %} +RebootWatchdogSec = {{ systemd_system.reboot_watchdog_sec }} +{% endif %} +{% if systemd_system.kexec_watchdog_sec is defined and + systemd_system.kexec_watchdog_sec | string | length > 0 %} +KExecWatchdogSec = {{ systemd_system.kexec_watchdog_sec }} +{% endif %} +{% if systemd_system.watchdog_device is defined and + systemd_system.watchdog_device | string | length > 0 %} +WatchdogDevice = {{ systemd_system.watchdog_device }} +{% endif %} +{% if systemd_system.capability_bounding_set is defined and + systemd_system.capability_bounding_set | string | length > 0 %} +CapabilityBoundingSet = {{ systemd_system.capability_bounding_set }} +{% endif %} +{% if systemd_system.no_new_privileges is defined and + systemd_system.no_new_privileges | string | length > 0 %} +NoNewPrivileges = {{ systemd_system.no_new_privileges | bool | bodsch.core.config_bool(true_as='yes', false_as='no') }} +{% endif %} +{% if systemd_system.system_call_architectures is defined and + systemd_system.system_call_architectures | string | length > 0 %} +SystemCallArchitectures = {{ systemd_system.system_call_architectures }} +{% endif %} +{% if systemd_system.timer_slack_nsec is defined and + systemd_system.timer_slack_nsec | string | length > 0 %} +TimerSlackNSec = {{ systemd_system.timer_slack_nsec }} +{% endif %} +{% if systemd_system.status_unit_format is defined and + systemd_system.status_unit_format | string | length > 0 %} +StatusUnitFormat = {{ systemd_system.status_unit_format }} +{% endif %} +{% if systemd_system.default_timer_accuracy_sec is defined and + systemd_system.default_timer_accuracy_sec | string | length > 0 %} +DefaultTimerAccuracySec = {{ systemd_system.default_timer_accuracy_sec }} +{% endif %} +{% if systemd_system.default_standard_output is defined and + systemd_system.default_standard_output | string | length > 0 %} +DefaultStandardOutput = {{ systemd_system.default_standard_output }} +{% endif %} +{% if systemd_system.default_standard_error is defined and + systemd_system.default_standard_error | string | length > 0 %} +DefaultStandardError = {{ systemd_system.default_standard_error }} +{% endif %} +{% if systemd_system.default_timeout_start_sec is defined and + systemd_system.default_timeout_start_sec | string | length > 0 %} +DefaultTimeoutStartSec = {{ systemd_system.default_timeout_start_sec }} +{% endif %} +{% if systemd_system.default_timeout_stop_sec is defined and + systemd_system.default_timeout_stop_sec | string | length > 0 %} +DefaultTimeoutStopSec = {{ systemd_system.default_timeout_stop_sec }} +{% endif %} +{% if systemd_system.default_timeout_abort_sec is defined and + systemd_system.default_timeout_abort_sec | string | length > 0 %} +DefaultTimeoutAbortSec = {{ systemd_system.default_timeout_abort_sec }} +{% endif %} +{% if systemd_system.default_device_timeout_sec is defined and + systemd_system.default_device_timeout_sec | string | length > 0 %} +DefaultDeviceTimeoutSec = {{ systemd_system.default_device_timeout_sec }} +{% endif %} +{% if systemd_system.default_restart_sec is defined and + systemd_system.default_restart_sec | string | length > 0 %} +DefaultRestartSec = {{ systemd_system.default_restart_sec }} +{% endif %} +{% if systemd_system.default_start_limit_interval_sec is defined and + systemd_system.default_start_limit_interval_sec | string | length > 0 %} +DefaultStartLimitIntervalSec = {{ systemd_system.default_start_limit_interval_sec }} +{% endif %} +{% if systemd_system.default_start_limit_burst is defined and + systemd_system.default_start_limit_burst | string | length > 0 %} +DefaultStartLimitBurst = {{ systemd_system.default_start_limit_burst }} +{% endif %} +{% if systemd_system.default_environment is defined and + systemd_system.default_environment | string | length > 0 %} +DefaultEnvironment = {{ systemd_system.default_environment }} +{% endif %} +{% if systemd_system.default_limit_cpu is defined and + systemd_system.default_limit_cpu | string | length > 0 %} +DefaultLimitCPU = {{ systemd_system.default_limit_cpu }} +{% endif %} +{% if systemd_system.default_limit_fsize is defined and + systemd_system.default_limit_fsize | string | length > 0 %} +DefaultLimitFSIZE = {{ systemd_system.default_limit_fsize }} +{% endif %} +{% if systemd_system.default_limit_data is defined and + systemd_system.default_limit_data | string | length > 0 %} +DefaultLimitDATA = {{ systemd_system.default_limit_data }} +{% endif %} +{% if systemd_system.default_limit_stack is defined and + systemd_system.default_limit_stack | string | length > 0 %} +DefaultLimitSTACK = {{ systemd_system.default_limit_stack }} +{% endif %} +{% if systemd_system.default_limit_core is defined and + systemd_system.default_limit_core | string | length > 0 %} +DefaultLimitCORE = {{ systemd_system.default_limit_core }} +{% endif %} +{% if systemd_system.default_limit_rss is defined and + systemd_system.default_limit_rss | string | length > 0 %} +DefaultLimitRSS = {{ systemd_system.default_limit_rss }} +{% endif %} +{% if systemd_system.default_limit_nofile is defined and + systemd_system.default_limit_nofile | string | length > 0 %} +DefaultLimitNOFILE = {{ systemd_system.default_limit_nofile }} +{% endif %} +{% if systemd_system.default_limit_as is defined and + systemd_system.default_limit_as | string | length > 0 %} +DefaultLimitAS = {{ systemd_system.default_limit_as }} +{% endif %} +{% if systemd_system.default_limit_nproc is defined and + systemd_system.default_limit_nproc | string | length > 0 %} +DefaultLimitNPROC = {{ systemd_system.default_limit_nproc }} +{% endif %} +{% if systemd_system.default_limit_memlock is defined and + systemd_system.default_limit_memlock | string | length > 0 %} +DefaultLimitMEMLOCK = {{ systemd_system.default_limit_memlock }} +{% endif %} +{% if systemd_system.default_limit_locks is defined and + systemd_system.default_limit_locks | string | length > 0 %} +DefaultLimitLOCKS = {{ systemd_system.default_limit_locks }} +{% endif %} +{% if systemd_system.default_limit_sigpending is defined and + systemd_system.default_limit_sigpending | string | length > 0 %} +DefaultLimitSIGPENDING = {{ systemd_system.default_limit_sigpending }} +{% endif %} +{% if systemd_system.default_limit_msgqueue is defined and + systemd_system.default_limit_msgqueue | string | length > 0 %} +DefaultLimitMSGQUEUE = {{ systemd_system.default_limit_msgqueue }} +{% endif %} +{% if systemd_system.default_limit_nice is defined and + systemd_system.default_limit_nice | string | length > 0 %} +DefaultLimitNICE = {{ systemd_system.default_limit_nice }} +{% endif %} +{% if systemd_system.default_limit_rtprio is defined and + systemd_system.default_limit_rtprio | string | length > 0 %} +DefaultLimitRTPRIO = {{ systemd_system.default_limit_rtprio }} +{% endif %} +{% if systemd_system.default_limit_rttime is defined and + systemd_system.default_limit_rttime | string | length > 0 %} +DefaultLimitRTTIME = {{ systemd_system.default_limit_rttime }} +{% endif %} +{% if systemd_system.default_limit_msgqueue is defined and + systemd_system.default_limit_msgqueue | string | length > 0 %} +DefaultLimitMSGQUEUE = {{ systemd_system.default_limit_msgqueue }} +{% endif %} +{% if systemd_system.default_limit_nice is defined and + systemd_system.default_limit_nice | string | length > 0 %} +DefaultLimitNICE = {{ systemd_system.default_limit_nice }} +{% endif %} +{% if systemd_system.default_limit_rtprio is defined and + systemd_system.default_limit_rtprio | string | length > 0 %} +DefaultLimitRTPRIO = {{ systemd_system.default_limit_rtprio }} +{% endif %} +{% if systemd_system.default_memory_pressure_threshold_sec is defined and + systemd_system.default_memory_pressure_threshold_sec | string | length > 0 %} +DefaultMemoryPressureThresholdSec = {{ systemd_system.default_memory_pressure_threshold_sec }} +{% endif %} +{% if systemd_system.default_memory_pressure_watch is defined and + systemd_system.default_memory_pressure_watch | string | length > 0 %} +DefaultMemoryPressureWatch = {{ systemd_system.default_memory_pressure_watch }} +{% endif %} +{% if systemd_system.default_oom_policy is defined and + systemd_system.default_oom_policy | string | length > 0 %} +DefaultOOMPolicy = {{ systemd_system.default_oom_policy }} +{% endif %} +{% if systemd_system.default_smack_process_label is defined and + systemd_system.default_smack_process_label | string | length > 0 %} +DefaultSmackProcessLabel = {{ systemd_system.default_smack_process_label }} +{% endif %} +{% if systemd_system.reload_limit_interval_sec is defined and + systemd_system.reload_limit_interval_sec | string | length > 0 %} +ReloadLimitIntervalSec = {{ systemd_system.reload_limit_interval_sec }} +{% endif %} +{% if systemd_system.reload_limit_burst is defined and + systemd_system.reload_limit_burst | string | length > 0 %} +ReloadLimitBurst = {{ systemd_system.reload_limit_burst }} +{% endif %} diff --git a/roles/systemd_unit/test-requirements.txt b/roles/systemd_unit/test-requirements.txt new file mode 100644 index 0000000..dc5c9a1 --- /dev/null +++ b/roles/systemd_unit/test-requirements.txt @@ -0,0 +1,11 @@ +ansible-lint +docker +dnspython +flake8 +molecule +molecule-plugins[docker] +netaddr +pytest-testinfra +tox +tox-gh-actions +yamllint diff --git a/roles/systemd_unit/tox.ini b/roles/systemd_unit/tox.ini new file mode 100644 index 0000000..c3099d3 --- /dev/null +++ b/roles/systemd_unit/tox.ini @@ -0,0 +1,39 @@ +[tox] +ignore_basepython_conflict = True +skip_missing_interpreters = True + +minversion = 3.25 +toxworkdir = /tmp/.tox/ + +skipsdist = true + +[testenv] +passenv = * + +# allowlist_externals = +# /usr/bin/find +# /bin/sh +# rm + +deps = + -r test-requirements.txt + ansible_4.10: ansible>=4.10,<4.11 + ansible_5.1: ansible>=5.1,<5.2 + ansible_5.2: ansible>=5.2,<5.3 + ansible_5.10: ansible>=5.10,<5.11 + ansible_6.1: ansible>=6.1,<6.2 + ansible_6.7: ansible>=6.7,<6.8 + ansible_7.0: ansible>=7.0,<7.1 + ansible_7.5: ansible>=7.5,<7.6 + ansible_8.0: ansible>=8.0,<8.1 + ansible_8.5: ansible>=8.5,<8.6 + ansible_9.0: ansible>=9.0,<9.1 + ansible_9.5: ansible>=9.5,<9.6 + ansible_10.0: ansible>=10.0,<10.1 + +#commands_pre = +# /usr/bin/find {toxinidir} -type f -not -path '{toxworkdir}/*' -path '*/__pycache__/*' -name '*.py[c|o]' -delete +# /bin/sh -c '/usr/bin/find {homedir}/.cache -type d -path "*/molecule_*" -exec rm -rfv \{\} +;' + +commands = + {posargs:molecule test --all --destroy always} diff --git a/roles/systemd_unit/vars/main.yml b/roles/systemd_unit/vars/main.yml new file mode 100644 index 0000000..6a63a96 --- /dev/null +++ b/roles/systemd_unit/vars/main.yml @@ -0,0 +1,5 @@ +--- + +systemd_defaults_unit: [] + +... From 7d49a85ce3b67fcf0c415d730990a1e5b9df7be7 Mon Sep 17 00:00:00 2001 From: Bodo Schulz Date: Tue, 11 Jun 2024 17:52:40 +0200 Subject: [PATCH 3/9] write temporary file --- plugins/modules/unit_file.py | 77 ++++- .../molecule/default/group_vars/all/vars.yml | 11 +- .../templates/systemd/system.conf.j2 | 270 ------------------ 3 files changed, 69 insertions(+), 289 deletions(-) delete mode 100644 roles/systemd_unit/templates/systemd/system.conf.j2 diff --git a/plugins/modules/unit_file.py b/plugins/modules/unit_file.py index e8cc49b..3a5f33a 100644 --- a/plugins/modules/unit_file.py +++ b/plugins/modules/unit_file.py @@ -8,10 +8,31 @@ from __future__ import absolute_import, division, print_function import os +import shutil + from ansible_collections.bodsch.core.plugins.module_utils.directory import create_directory from ansible_collections.bodsch.core.plugins.module_utils.checksum import Checksum from ansible.module_utils.basic import AnsibleModule +# from jinja2 import Environment, FileSystemLoader + +UNIT_TPL = """# generated by ansible + +{% for section, options in item.items() %} +[{{ section }}] + {% for option, values in options.items() %} + {% if values is string or values is number %} +{{ option }}={{ values }} + {% else %} + {% for value in values %} +{{ option }}={{ value }} + {% endfor %} + {% endif %} + {% endfor %} + +{% endfor %} + +""" class SystemdUnitFile(object): @@ -34,6 +55,8 @@ def __init__(self, module): self.service = module.params.get("service") self.install = module.params.get("install") + self.tmp_directory = os.path.join("/run/.ansible", f"systemd_unit.{str(os.getpid())}") + # module.log(msg="----------------------------") # module.log(msg=f" journalctl : {self._journalctl}") # module.log(msg=f" unit : {self.unit}") @@ -53,29 +76,55 @@ def run(self): ) if len(self.drop_ins) > 0: - self.module.log(msg="----------------------------") - service_name = f"/etc/systemd/system/{self.name}.d" - self.module.log(msg=f" service name : {service_name}") + create_directory(directory=self.tmp_directory, mode="0750") - if not os.path.exists(service_name): - create_directory(service_name) + self.create_drop_in(self.drop_ins) - for drop_in in self.drop_ins: + # shutil.rmtree(self.tmp_directory) + # result = self.journalctl_lines() - self.module.log(msg=f" drop in name : {drop_in}") + return result - file_name = f"{service_name}/{drop_in.get('name')}.conf" - if not os.path.exists(file_name): - with open(file_name, "w") as f: - f.write("# ansible controlled") + def create_drop_in(self, data): + """ + """ + self.module.log(msg="----------------------------") + service_name = f"/etc/systemd/system/{self.name}.d" + self.module.log(msg=f" service name : {service_name}") - self.module.log(msg="----------------------------") + if not os.path.exists(service_name): + create_directory(service_name) + for drop_in in data: + name = drop_in.get("name") + self.module.log(msg=f" drop in name : {name}") - # result = self.journalctl_lines() + file_temporary = os.path.join(self.tmp_directory, f"{name}.conf") - return result + data = self.__template(drop_in) + # checksum = self.__checksum(data) + + with open(file_temporary, "w") as f: + f.write(data) + + self.module.log(msg="----------------------------") + + def __template(self, data): + """ + """ + self.module.log(msg=f"__template({data} ({type(data)}))") + + from jinja2 import Template + + _ = data.pop('name') + + self.module.log(msg=f"{data} ({type(data)})") + + tm = Template(UNIT_TPL, trim_blocks=True, lstrip_blocks=True) + d = tm.render(item=data) + + return d def main(): diff --git a/roles/systemd_unit/molecule/default/group_vars/all/vars.yml b/roles/systemd_unit/molecule/default/group_vars/all/vars.yml index 962c434..2617316 100644 --- a/roles/systemd_unit/molecule/default/group_vars/all/vars.yml +++ b/roles/systemd_unit/molecule/default/group_vars/all/vars.yml @@ -6,13 +6,14 @@ systemd_unit: overwrite: true drop_ins: - name: autologin - service: - exec_start: unsafe! - - "-/sbin/agetty -o '-p -f -- \\u' --noclear --autologin username %I $TERM" - type: simple + Service: + ExecStart: + - "" + - "{% raw %}-/sbin/agetty -o '-p -f -- \\\\u' --noclear --autologin username %I $TERM{% endraw %}" + Type: simple - name: noclear - service: + Service: TTYVTDisallocate: false # - name: chronyd # unit_type: service diff --git a/roles/systemd_unit/templates/systemd/system.conf.j2 b/roles/systemd_unit/templates/systemd/system.conf.j2 deleted file mode 100644 index 5dd5690..0000000 --- a/roles/systemd_unit/templates/systemd/system.conf.j2 +++ /dev/null @@ -1,270 +0,0 @@ -#jinja2: trim_blocks: True, lstrip_blocks: True -# {{ ansible_managed }} -# This file is part of systemd. -# -# systemd is free software; you can redistribute it and/or modify it under the -# terms of the GNU Lesser General Public License as published by the Free -# Software Foundation; either version 2.1 of the License, or (at your option) -# any later version. -# -# Entries in this file show the compile time defaults. Local configuration -# should be created by either modifying this file, or by creating "drop-ins" in -# the system.conf.d/ subdirectory. The latter is generally recommended. -# Defaults can be restored by simply deleting this file and all drop-ins. -# -# Use 'systemd-analyze cat-config systemd/system.conf' to display the full config. -# -# See systemd-system.conf(5) for details. - -[Manager] -{% if systemd_system.log_level is defined and - systemd_system.log_level | string | length > 0 and - systemd_system.log_level in ["emerg", "alert", "crit", "err", "warning", "notice", "info", "debug"] %} -LogLevel = {{ systemd_system.log_level }} -{% endif %} -{% if systemd_system.log_target is defined and - systemd_system.log_target | string | length > 0 %} -LogTarget = {{ systemd_system.log_target }} -{% endif %} -{% if systemd_system.log_color is defined and - systemd_system.log_color | string | length > 0 %} - {% if systemd_system.log_color | bodsch.core.type == "bool" %} -LogColor = {{ systemd_system.log_color | bool | bodsch.core.config_bool(true_as='yes', false_as='no') }} - {% endif %} -{% endif %} -{% if systemd_system.log_location is defined and - systemd_system.log_location | string | length > 0 %} - {% if systemd_system.log_location | bodsch.core.type == "bool" %} -LogLocation = {{ systemd_system.log_location | bool | bodsch.core.config_bool(true_as='yes', false_as='no') }} - {% endif %} -{% endif %} -{% if systemd_system.log_time is defined and - systemd_system.log_time | string | length > 0 %} - {% if systemd_system.log_time | bodsch.core.type == "bool" %} -LogTime = {{ systemd_system.log_time | bool | bodsch.core.config_bool(true_as='yes', false_as='no') }} - {% endif %} -{% endif %} -{% if systemd_system.dump_core is defined and - systemd_system.dump_core | string | length > 0 %} -DumpCore = {{ systemd_system.dump_core | bool | bodsch.core.config_bool(true_as='yes', false_as='no') }} -{% endif %} -{% if systemd_system.show_status is defined and - systemd_system.show_status | string | length > 0 %} -ShowStatus = {{ systemd_system.show_status | bool | bodsch.core.config_bool(true_as='yes', false_as='no') }} -{% endif %} -{% if systemd_system.crash_change_vt is defined and - systemd_system.crash_change_vt | string | length > 0 %} -CrashChangeVT = {{ systemd_system.crash_change_vt | bool | bodsch.core.config_bool(true_as='yes', false_as='no') }} -{% endif %} -{% if systemd_system.crash_shell is defined and - systemd_system.crash_shell | string | length > 0 %} -CrashShell = {{ systemd_system.crash_shell | bool | bodsch.core.config_bool(true_as='yes', false_as='no') }} -{% endif %} -{% if systemd_system.crash_reboot is defined and - systemd_system.crash_reboot | string | length > 0 %} -CrashReboot = {{ systemd_system.crash_reboot | bool | bodsch.core.config_bool(true_as='yes', false_as='no') }} -{% endif %} -{% if systemd_system.ctrl_alt_del_burst_action is defined and - systemd_system.ctrl_alt_del_burst_action | string | length > 0 %} -CtrlAltDelBurstAction = {{ systemd_system.ctrl_alt_del_burst_action }} -{% endif %} -{% if systemd_system.cpu_affinity is defined and - systemd_system.cpu_affinity | string | length > 0 %} -CPUAffinity = {{ systemd_system.cpu_affinity }} -{% endif %} -{% if systemd_system.numa_policy is defined and - systemd_system.numa_policy | string | length > 0 %} -NUMAPolicy = {{ systemd_system.numa_policy }} -{% endif %} -{% if systemd_system.numa_mask is defined and - systemd_system.numa_mask | string | length > 0 %} -NUMAMask = {{ systemd_system.numa_mask }} -{% endif %} -{% if systemd_system.runtime_watchdog_sec is defined and - systemd_system.runtime_watchdog_sec | string | length > 0 %} -RuntimeWatchdogSec = {{ systemd_system.runtime_watchdog_sec }} -{% endif %} -{% if systemd_system.runtime_watchdog_pre_sec is defined and - systemd_system.runtime_watchdog_pre_sec | string | length > 0 %} -RuntimeWatchdogPreSec = {{ systemd_system.runtime_watchdog_pre_sec }} -{% endif %} -{% if systemd_system.runtime_watchdog_pre_governor is defined and - systemd_system.runtime_watchdog_pre_governor | string | length > 0 %} -RuntimeWatchdogPreGovernor = {{ systemd_system.runtime_watchdog_pre_governor }} -{% endif %} -{% if systemd_system.reboot_watchdog_sec is defined and - systemd_system.reboot_watchdog_sec | string | length > 0 %} -RebootWatchdogSec = {{ systemd_system.reboot_watchdog_sec }} -{% endif %} -{% if systemd_system.kexec_watchdog_sec is defined and - systemd_system.kexec_watchdog_sec | string | length > 0 %} -KExecWatchdogSec = {{ systemd_system.kexec_watchdog_sec }} -{% endif %} -{% if systemd_system.watchdog_device is defined and - systemd_system.watchdog_device | string | length > 0 %} -WatchdogDevice = {{ systemd_system.watchdog_device }} -{% endif %} -{% if systemd_system.capability_bounding_set is defined and - systemd_system.capability_bounding_set | string | length > 0 %} -CapabilityBoundingSet = {{ systemd_system.capability_bounding_set }} -{% endif %} -{% if systemd_system.no_new_privileges is defined and - systemd_system.no_new_privileges | string | length > 0 %} -NoNewPrivileges = {{ systemd_system.no_new_privileges | bool | bodsch.core.config_bool(true_as='yes', false_as='no') }} -{% endif %} -{% if systemd_system.system_call_architectures is defined and - systemd_system.system_call_architectures | string | length > 0 %} -SystemCallArchitectures = {{ systemd_system.system_call_architectures }} -{% endif %} -{% if systemd_system.timer_slack_nsec is defined and - systemd_system.timer_slack_nsec | string | length > 0 %} -TimerSlackNSec = {{ systemd_system.timer_slack_nsec }} -{% endif %} -{% if systemd_system.status_unit_format is defined and - systemd_system.status_unit_format | string | length > 0 %} -StatusUnitFormat = {{ systemd_system.status_unit_format }} -{% endif %} -{% if systemd_system.default_timer_accuracy_sec is defined and - systemd_system.default_timer_accuracy_sec | string | length > 0 %} -DefaultTimerAccuracySec = {{ systemd_system.default_timer_accuracy_sec }} -{% endif %} -{% if systemd_system.default_standard_output is defined and - systemd_system.default_standard_output | string | length > 0 %} -DefaultStandardOutput = {{ systemd_system.default_standard_output }} -{% endif %} -{% if systemd_system.default_standard_error is defined and - systemd_system.default_standard_error | string | length > 0 %} -DefaultStandardError = {{ systemd_system.default_standard_error }} -{% endif %} -{% if systemd_system.default_timeout_start_sec is defined and - systemd_system.default_timeout_start_sec | string | length > 0 %} -DefaultTimeoutStartSec = {{ systemd_system.default_timeout_start_sec }} -{% endif %} -{% if systemd_system.default_timeout_stop_sec is defined and - systemd_system.default_timeout_stop_sec | string | length > 0 %} -DefaultTimeoutStopSec = {{ systemd_system.default_timeout_stop_sec }} -{% endif %} -{% if systemd_system.default_timeout_abort_sec is defined and - systemd_system.default_timeout_abort_sec | string | length > 0 %} -DefaultTimeoutAbortSec = {{ systemd_system.default_timeout_abort_sec }} -{% endif %} -{% if systemd_system.default_device_timeout_sec is defined and - systemd_system.default_device_timeout_sec | string | length > 0 %} -DefaultDeviceTimeoutSec = {{ systemd_system.default_device_timeout_sec }} -{% endif %} -{% if systemd_system.default_restart_sec is defined and - systemd_system.default_restart_sec | string | length > 0 %} -DefaultRestartSec = {{ systemd_system.default_restart_sec }} -{% endif %} -{% if systemd_system.default_start_limit_interval_sec is defined and - systemd_system.default_start_limit_interval_sec | string | length > 0 %} -DefaultStartLimitIntervalSec = {{ systemd_system.default_start_limit_interval_sec }} -{% endif %} -{% if systemd_system.default_start_limit_burst is defined and - systemd_system.default_start_limit_burst | string | length > 0 %} -DefaultStartLimitBurst = {{ systemd_system.default_start_limit_burst }} -{% endif %} -{% if systemd_system.default_environment is defined and - systemd_system.default_environment | string | length > 0 %} -DefaultEnvironment = {{ systemd_system.default_environment }} -{% endif %} -{% if systemd_system.default_limit_cpu is defined and - systemd_system.default_limit_cpu | string | length > 0 %} -DefaultLimitCPU = {{ systemd_system.default_limit_cpu }} -{% endif %} -{% if systemd_system.default_limit_fsize is defined and - systemd_system.default_limit_fsize | string | length > 0 %} -DefaultLimitFSIZE = {{ systemd_system.default_limit_fsize }} -{% endif %} -{% if systemd_system.default_limit_data is defined and - systemd_system.default_limit_data | string | length > 0 %} -DefaultLimitDATA = {{ systemd_system.default_limit_data }} -{% endif %} -{% if systemd_system.default_limit_stack is defined and - systemd_system.default_limit_stack | string | length > 0 %} -DefaultLimitSTACK = {{ systemd_system.default_limit_stack }} -{% endif %} -{% if systemd_system.default_limit_core is defined and - systemd_system.default_limit_core | string | length > 0 %} -DefaultLimitCORE = {{ systemd_system.default_limit_core }} -{% endif %} -{% if systemd_system.default_limit_rss is defined and - systemd_system.default_limit_rss | string | length > 0 %} -DefaultLimitRSS = {{ systemd_system.default_limit_rss }} -{% endif %} -{% if systemd_system.default_limit_nofile is defined and - systemd_system.default_limit_nofile | string | length > 0 %} -DefaultLimitNOFILE = {{ systemd_system.default_limit_nofile }} -{% endif %} -{% if systemd_system.default_limit_as is defined and - systemd_system.default_limit_as | string | length > 0 %} -DefaultLimitAS = {{ systemd_system.default_limit_as }} -{% endif %} -{% if systemd_system.default_limit_nproc is defined and - systemd_system.default_limit_nproc | string | length > 0 %} -DefaultLimitNPROC = {{ systemd_system.default_limit_nproc }} -{% endif %} -{% if systemd_system.default_limit_memlock is defined and - systemd_system.default_limit_memlock | string | length > 0 %} -DefaultLimitMEMLOCK = {{ systemd_system.default_limit_memlock }} -{% endif %} -{% if systemd_system.default_limit_locks is defined and - systemd_system.default_limit_locks | string | length > 0 %} -DefaultLimitLOCKS = {{ systemd_system.default_limit_locks }} -{% endif %} -{% if systemd_system.default_limit_sigpending is defined and - systemd_system.default_limit_sigpending | string | length > 0 %} -DefaultLimitSIGPENDING = {{ systemd_system.default_limit_sigpending }} -{% endif %} -{% if systemd_system.default_limit_msgqueue is defined and - systemd_system.default_limit_msgqueue | string | length > 0 %} -DefaultLimitMSGQUEUE = {{ systemd_system.default_limit_msgqueue }} -{% endif %} -{% if systemd_system.default_limit_nice is defined and - systemd_system.default_limit_nice | string | length > 0 %} -DefaultLimitNICE = {{ systemd_system.default_limit_nice }} -{% endif %} -{% if systemd_system.default_limit_rtprio is defined and - systemd_system.default_limit_rtprio | string | length > 0 %} -DefaultLimitRTPRIO = {{ systemd_system.default_limit_rtprio }} -{% endif %} -{% if systemd_system.default_limit_rttime is defined and - systemd_system.default_limit_rttime | string | length > 0 %} -DefaultLimitRTTIME = {{ systemd_system.default_limit_rttime }} -{% endif %} -{% if systemd_system.default_limit_msgqueue is defined and - systemd_system.default_limit_msgqueue | string | length > 0 %} -DefaultLimitMSGQUEUE = {{ systemd_system.default_limit_msgqueue }} -{% endif %} -{% if systemd_system.default_limit_nice is defined and - systemd_system.default_limit_nice | string | length > 0 %} -DefaultLimitNICE = {{ systemd_system.default_limit_nice }} -{% endif %} -{% if systemd_system.default_limit_rtprio is defined and - systemd_system.default_limit_rtprio | string | length > 0 %} -DefaultLimitRTPRIO = {{ systemd_system.default_limit_rtprio }} -{% endif %} -{% if systemd_system.default_memory_pressure_threshold_sec is defined and - systemd_system.default_memory_pressure_threshold_sec | string | length > 0 %} -DefaultMemoryPressureThresholdSec = {{ systemd_system.default_memory_pressure_threshold_sec }} -{% endif %} -{% if systemd_system.default_memory_pressure_watch is defined and - systemd_system.default_memory_pressure_watch | string | length > 0 %} -DefaultMemoryPressureWatch = {{ systemd_system.default_memory_pressure_watch }} -{% endif %} -{% if systemd_system.default_oom_policy is defined and - systemd_system.default_oom_policy | string | length > 0 %} -DefaultOOMPolicy = {{ systemd_system.default_oom_policy }} -{% endif %} -{% if systemd_system.default_smack_process_label is defined and - systemd_system.default_smack_process_label | string | length > 0 %} -DefaultSmackProcessLabel = {{ systemd_system.default_smack_process_label }} -{% endif %} -{% if systemd_system.reload_limit_interval_sec is defined and - systemd_system.reload_limit_interval_sec | string | length > 0 %} -ReloadLimitIntervalSec = {{ systemd_system.reload_limit_interval_sec }} -{% endif %} -{% if systemd_system.reload_limit_burst is defined and - systemd_system.reload_limit_burst | string | length > 0 %} -ReloadLimitBurst = {{ systemd_system.reload_limit_burst }} -{% endif %} From 299568dd04adcfeb3c8bda609712d5fe9ad5580f Mon Sep 17 00:00:00 2001 From: Bodo Schulz Date: Wed, 12 Jun 2024 16:32:53 +0200 Subject: [PATCH 4/9] write temporary file --- plugins/modules/unit_file.py | 108 ++++++++++++++---- .../molecule/default/group_vars/all/vars.yml | 12 +- roles/systemd_unit/tasks/main.yml | 14 ++- 3 files changed, 102 insertions(+), 32 deletions(-) diff --git a/plugins/modules/unit_file.py b/plugins/modules/unit_file.py index 3a5f33a..665a40a 100644 --- a/plugins/modules/unit_file.py +++ b/plugins/modules/unit_file.py @@ -31,7 +31,8 @@ {% endfor %} {% endfor %} - +{# +#} """ @@ -49,13 +50,15 @@ def __init__(self, module): self.unit_type = module.params.get("unit_type") self.name = module.params.get("name") + self.state = module.params.get("state") self.overwrite = module.params.get("overwrite") self.drop_ins = module.params.get("drop_ins") - self.unit = module.params.get("unit") - self.service = module.params.get("service") - self.install = module.params.get("install") + # self.unit = module.params.get("unit") + # self.service = module.params.get("service") + # self.install = module.params.get("install") - self.tmp_directory = os.path.join("/run/.ansible", f"systemd_unit.{str(os.getpid())}") + self.tmp_directory = os.path.join("/run/.ansible", f"systemd_unit")#.{str(os.getpid())}") + self.service_name = f"/etc/systemd/system/{self.name}.d" # module.log(msg="----------------------------") # module.log(msg=f" journalctl : {self._journalctl}") @@ -75,54 +78,101 @@ def run(self): changed=False, ) - if len(self.drop_ins) > 0: - create_directory(directory=self.tmp_directory, mode="0750") + if self.state == "absent": + result = self.clean_unit_files() + + else: + if isinstance(self.drop_ins, list) and len(self.drop_ins) > 0: + create_directory(directory=self.tmp_directory, mode="0750") - self.create_drop_in(self.drop_ins) + result = self.create_drop_in(self.drop_ins) - # shutil.rmtree(self.tmp_directory) + # shutil.rmtree(self.tmp_directory) - # result = self.journalctl_lines() + # result = self.journalctl_lines() return result def create_drop_in(self, data): """ """ + # old_checksum = self.checksum.checksum_from_file(file_name) + # new_checksum = self.checksum.checksum_from_file(file_temporary) + self.module.log(msg="----------------------------") - service_name = f"/etc/systemd/system/{self.name}.d" - self.module.log(msg=f" service name : {service_name}") - if not os.path.exists(service_name): - create_directory(service_name) + self.module.log(msg=f" service name : {self.service_name}") + +# if + + # self.clean_unit_files(unit_state_absent) + # self.create_unit_files(unit_state_absent) + + if not os.path.exists(self.service_name): + create_directory(self.service_name) for drop_in in data: name = drop_in.get("name") - self.module.log(msg=f" drop in name : {name}") + state = drop_in.get("state", "present") + unit_file = os.path.join(self.service_name, f"{name}.conf") file_temporary = os.path.join(self.tmp_directory, f"{name}.conf") - data = self.__template(drop_in) - # checksum = self.__checksum(data) + self.module.log(msg=f" drop in name : {name}") + self.module.log(msg=f" drop file : {unit_file}") + self.module.log(msg=f" temporary file : {file_temporary}") + + if state == "present": + file_temporary = os.path.join(self.tmp_directory, f"{name}.conf") + + data = self.__template(drop_in) + # checksum = self.__checksum(data) + + with open(file_temporary, "w") as f: + f.write(data) - with open(file_temporary, "w") as f: - f.write(data) + result = dict( + changed=True, + failed=False + ) + + else: + self.module.log(msg=f"remove : {unit_file}") + + if os.path.exists(unit_file): + shutil.rmtree(unit_file) + + result = dict( + changed=True, + failed=False + ) + else: + result = dict( + changed=False, + failed=False + ) self.module.log(msg="----------------------------") + return result + def __template(self, data): """ """ self.module.log(msg=f"__template({data} ({type(data)}))") - from jinja2 import Template + if isinstance(data, dict): + from jinja2 import Template - _ = data.pop('name') + _ = data.pop('name') + _ = data.pop('state') - self.module.log(msg=f"{data} ({type(data)})") + self.module.log(msg=f"{data} ({type(data)})") - tm = Template(UNIT_TPL, trim_blocks=True, lstrip_blocks=True) - d = tm.render(item=data) + tm = Template(UNIT_TPL, trim_blocks=True, lstrip_blocks=True) + d = tm.render(item=data) + else: + d = None return d @@ -132,18 +182,26 @@ def main(): """ args = dict( unit_type=dict( - required=True, choose=[ "service", "socket", "timer" ], + default="service", type="str" ), name=dict( required=True, type="str" ), + state=dict( + choose=[ + "absent", + "present", + ], + default="present", + type="str" + ), overwrite=dict( required=False, default=False, diff --git a/roles/systemd_unit/molecule/default/group_vars/all/vars.yml b/roles/systemd_unit/molecule/default/group_vars/all/vars.yml index 2617316..ad0fba2 100644 --- a/roles/systemd_unit/molecule/default/group_vars/all/vars.yml +++ b/roles/systemd_unit/molecule/default/group_vars/all/vars.yml @@ -2,10 +2,12 @@ systemd_unit: - name: "getty@tty1" + state: present unit_type: service overwrite: true drop_ins: - name: autologin + state: present Service: ExecStart: - "" @@ -13,11 +15,15 @@ systemd_unit: Type: simple - name: noclear + state: absent Service: TTYVTDisallocate: false - # - name: chronyd - # unit_type: service - # overwrite: false + + - name: chronyd + state: present + unit_type: service + overwrite: false + # unit: # Description: "NTP client/server" # Documentation: "man:chronyd(8) man:chrony.conf(5)" diff --git a/roles/systemd_unit/tasks/main.yml b/roles/systemd_unit/tasks/main.yml index 273f217..2a97018 100644 --- a/roles/systemd_unit/tasks/main.yml +++ b/roles/systemd_unit/tasks/main.yml @@ -3,18 +3,24 @@ - name: create systemd unit files bodsch.systemd.unit_file: name: "{{ item.name }}" + state: "{{ item.state }}" unit_type: "{{ item.unit_type }}" overwrite: "{{ item.overwrite }}" drop_ins: "{{ item.drop_ins | default(omit) }}" - unit: "{{ item.drop_ins | default(omit) }}" - service: "{{ item.drop_ins | default(omit) }}" - install: "{{ item.drop_ins | default(omit) }}" + # unit: "{{ item.unit | default(omit) }}" + # service: "{{ item.service | default(omit) }}" + # install: "{{ item.install | default(omit) }}" loop: "{{ systemd_unit }}" loop_control: label: "{{ item.name }}" - + register: systemd_unit_file + ignore_errors: true when: - systemd_unit | count > 0 +- name: d + debug: + msg: "{{ systemd_unit_file }}" + ... From 35999cd4775c5bc08eef821ac256a8ed46394865 Mon Sep 17 00:00:00 2001 From: Bodo Schulz Date: Wed, 26 Jun 2024 07:59:44 +0200 Subject: [PATCH 5/9] fix molecule configurations --- .../molecule/default/group_vars/all/vars.yml | 9 +-------- .../molecule/default/group_vars/all/vars.yml | 2 +- .../molecule/default/group_vars/all/vars.yml | 13 +++++-------- .../molecule/default/group_vars/all/vars.yml | 16 ++++++++-------- .../molecule/default/group_vars/all/vars.yml | 9 +-------- 5 files changed, 16 insertions(+), 33 deletions(-) diff --git a/roles/homed/molecule/default/group_vars/all/vars.yml b/roles/homed/molecule/default/group_vars/all/vars.yml index 9ac822a..81cd342 100644 --- a/roles/homed/molecule/default/group_vars/all/vars.yml +++ b/roles/homed/molecule/default/group_vars/all/vars.yml @@ -1,12 +1,5 @@ --- -alertmanager_route: - group_by: - - 'alertname' - - 'service' - group_wait: 30s - group_interval: 5m - repeat_interval: 4h - default_receiver: blackhole +systemd_homed: {} ... diff --git a/roles/journald/molecule/default/group_vars/all/vars.yml b/roles/journald/molecule/default/group_vars/all/vars.yml index a0ef4c7..cdb324a 100644 --- a/roles/journald/molecule/default/group_vars/all/vars.yml +++ b/roles/journald/molecule/default/group_vars/all/vars.yml @@ -1,6 +1,6 @@ --- -systemd_coredump: +systemd_journald: storage: external compress: true process_size_max: 32G diff --git a/roles/resolved/molecule/default/group_vars/all/vars.yml b/roles/resolved/molecule/default/group_vars/all/vars.yml index 9ac822a..5a99a2e 100644 --- a/roles/resolved/molecule/default/group_vars/all/vars.yml +++ b/roles/resolved/molecule/default/group_vars/all/vars.yml @@ -1,12 +1,9 @@ --- -alertmanager_route: - group_by: - - 'alertname' - - 'service' - group_wait: 30s - group_interval: 5m - repeat_interval: 4h - default_receiver: blackhole +systemd_resolved: + dns: + - "1.1.1.1" + - "9.9.9.9" + ... diff --git a/roles/timesyncd/molecule/default/group_vars/all/vars.yml b/roles/timesyncd/molecule/default/group_vars/all/vars.yml index 9ac822a..4d9994b 100644 --- a/roles/timesyncd/molecule/default/group_vars/all/vars.yml +++ b/roles/timesyncd/molecule/default/group_vars/all/vars.yml @@ -1,12 +1,12 @@ --- -alertmanager_route: - group_by: - - 'alertname' - - 'service' - group_wait: 30s - group_interval: 5m - repeat_interval: 4h - default_receiver: blackhole +systemd_timesyncd: + ntp: [] + fallback_ntp: + - 0.arch.pool.ntp.org + - 1.arch.pool.ntp.org + - 2.arch.pool.ntp.org + - 3.arch.pool.ntp.org + ... diff --git a/roles/user/molecule/default/group_vars/all/vars.yml b/roles/user/molecule/default/group_vars/all/vars.yml index 9ac822a..0a8b4ab 100644 --- a/roles/user/molecule/default/group_vars/all/vars.yml +++ b/roles/user/molecule/default/group_vars/all/vars.yml @@ -1,12 +1,5 @@ --- -alertmanager_route: - group_by: - - 'alertname' - - 'service' - group_wait: 30s - group_interval: 5m - repeat_interval: 4h - default_receiver: blackhole +systemd_user: {} ... From dfbc2bcee876cc4c45d95aae270899c88dbfc6bf Mon Sep 17 00:00:00 2001 From: Bodo Schulz Date: Tue, 20 Aug 2024 17:44:11 +0200 Subject: [PATCH 6/9] Add support to create unit files for service und timer ressourcen --- plugins/modules/journalctl.py | 2 +- plugins/modules/unit_file.py | 103 ++++++++++++------ .../molecule/default/group_vars/all/vars.yml | 43 +++++++- roles/systemd_unit/tasks/main.yml | 3 +- 4 files changed, 113 insertions(+), 38 deletions(-) diff --git a/plugins/modules/journalctl.py b/plugins/modules/journalctl.py index cb93283..28f9832 100644 --- a/plugins/modules/journalctl.py +++ b/plugins/modules/journalctl.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python3 +#!/usr/bin/python3 # -*- coding: utf-8 -*- # (c) 2020-2023, Bodo Schulz diff --git a/plugins/modules/unit_file.py b/plugins/modules/unit_file.py index 665a40a..d0bca7e 100644 --- a/plugins/modules/unit_file.py +++ b/plugins/modules/unit_file.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python3 +#!/usr/bin/python3 # -*- coding: utf-8 -*- # (c) 2020-2023, Bodo Schulz @@ -19,7 +19,7 @@ UNIT_TPL = """# generated by ansible {% for section, options in item.items() %} -[{{ section }}] +[{{ section | capitalize }}] {% for option, values in options.items() %} {% if values is string or values is number %} {{ option }}={{ values }} @@ -46,28 +46,15 @@ def __init__(self, module): """ self.module = module - # self._journalctl = module.get_bin_path("journalctl", True) - self.unit_type = module.params.get("unit_type") self.name = module.params.get("name") self.state = module.params.get("state") self.overwrite = module.params.get("overwrite") self.drop_ins = module.params.get("drop_ins") - # self.unit = module.params.get("unit") - # self.service = module.params.get("service") - # self.install = module.params.get("install") - - self.tmp_directory = os.path.join("/run/.ansible", f"systemd_unit")#.{str(os.getpid())}") - self.service_name = f"/etc/systemd/system/{self.name}.d" - - # module.log(msg="----------------------------") - # module.log(msg=f" journalctl : {self._journalctl}") - # module.log(msg=f" unit : {self.unit}") - # module.log(msg=f" identifier : {self.identifier}") - # module.log(msg=f" lines : {self.lines}") - # module.log(msg=f" reverse : {self.reverse}") - # module.log(msg=f" arguments : {self.arguments}") - # module.log(msg="----------------------------") + self.unit_file = module.params.get("unit_file") + + self.tmp_directory = os.path.join("/run/.ansible", f"systemd_unit.{str(os.getpid())}") + def run(self): """ @@ -78,16 +65,33 @@ def run(self): changed=False, ) + self.module.log(msg=f"state: {self.state}") + self.module.log(msg=f"drop_ins: {self.drop_ins}") + self.module.log(msg=f"unit_file: {self.unit_file}") + if self.state == "absent": result = self.clean_unit_files() else: if isinstance(self.drop_ins, list) and len(self.drop_ins) > 0: + + self.service_name = f"/etc/systemd/system/{self.name}.d" + create_directory(directory=self.tmp_directory, mode="0750") result = self.create_drop_in(self.drop_ins) - # shutil.rmtree(self.tmp_directory) + # + if isinstance(self.unit_file, dict) and len(self.unit_file) > 0: + + self.service_name = f"/lib/systemd/system/{self.name}.{self.unit_type}" + + create_directory(directory=self.tmp_directory, mode="0750") + + result = self.create_unit_file(self.unit_file) + + #if os.path.exists(self.tmp_directory): + # shutil.rmtree(self.tmp_directory) # result = self.journalctl_lines() @@ -103,8 +107,6 @@ def create_drop_in(self, data): self.module.log(msg=f" service name : {self.service_name}") -# if - # self.clean_unit_files(unit_state_absent) # self.create_unit_files(unit_state_absent) @@ -156,6 +158,45 @@ def create_drop_in(self, data): return result + def create_unit_file(self, data): + """ + """ + # old_checksum = self.checksum.checksum_from_file(file_name) + # new_checksum = self.checksum.checksum_from_file(file_temporary) + + file_temporary = os.path.join(self.tmp_directory, self.name) + + self.module.log(msg="----------------------------") + + self.module.log(msg=f" service name : {self.service_name}") + self.module.log(msg=f" temporary file : {file_temporary}") + + if self.state == "present": + data = self.__template(data) + + with open(file_temporary, "w") as f: + f.write(data) + + result = dict( + changed=True, + failed=False + ) + else: + pass + + result = dict( + changed=False, + failed=False + ) + + self.module.log(msg="----------------------------") + + return result + + + + + def __template(self, data): """ """ @@ -164,8 +205,10 @@ def __template(self, data): if isinstance(data, dict): from jinja2 import Template - _ = data.pop('name') - _ = data.pop('state') + if data.get('name'): + _ = data.pop('name') + if data.get('state'): + _ = data.pop('state') self.module.log(msg=f"{data} ({type(data)})") @@ -212,17 +255,7 @@ def main(): default=[], type=list ), - unit=dict( - required=False, - default={}, - type=dict - ), - service=dict( - required=False, - default={}, - type=dict - ), - install=dict( + unit_file=dict( required=False, default={}, type=dict diff --git a/roles/systemd_unit/molecule/default/group_vars/all/vars.yml b/roles/systemd_unit/molecule/default/group_vars/all/vars.yml index ad0fba2..ef8a510 100644 --- a/roles/systemd_unit/molecule/default/group_vars/all/vars.yml +++ b/roles/systemd_unit/molecule/default/group_vars/all/vars.yml @@ -19,11 +19,52 @@ systemd_unit: Service: TTYVTDisallocate: false - - name: chronyd + - name: sshd state: present unit_type: service overwrite: false + unit_file: + unit: + Description: OpenBSD Secure Shell server + Documentation: man:sshd(8) man:sshd_config(5) + After: + - network.target + - auditd.service + ConditionPathExists: "!/etc/ssh/sshd_not_to_be_run" + service: + EnvironmentFile: -/etc/default/ssh + ExecStartPre: /usr/sbin/sshd -t + ExecStart: /usr/sbin/sshd -D $SSHD_OPTS + ExecReload: + - /usr/sbin/sshd -t + - /bin/kill -HUP $MAINPID + KillMode: process + Restart: on-failure + RestartPreventExitStatus: 255 + Type: notify + RuntimeDirectory: sshd + RuntimeDirectoryMode: "0755" + install: + WantedBy: multi-user.target + Alias: sshd.service + - name: systemd-tmpfiles-clean + state: present + unit_type: timer + unit_file: + unit: + Description: Daily Cleanup of Temporary Directories + Documentation: man:tmpfiles.d(5) man:systemd-tmpfiles(8) + ConditionPathExists: "!/etc/initrd-release" + timer: + OnBootSec: 15min + OnUnitActiveSec: 1d + + # - name: chronyd + # state: present + # unit_type: service + # overwrite: false + # # unit: # Description: "NTP client/server" # Documentation: "man:chronyd(8) man:chrony.conf(5)" diff --git a/roles/systemd_unit/tasks/main.yml b/roles/systemd_unit/tasks/main.yml index 2a97018..fc7bdc6 100644 --- a/roles/systemd_unit/tasks/main.yml +++ b/roles/systemd_unit/tasks/main.yml @@ -5,8 +5,9 @@ name: "{{ item.name }}" state: "{{ item.state }}" unit_type: "{{ item.unit_type }}" - overwrite: "{{ item.overwrite }}" + overwrite: "{{ item.overwrite | default(omit) }}" drop_ins: "{{ item.drop_ins | default(omit) }}" + unit_file: "{{ item.unit_file | default(omit) }}" # unit: "{{ item.unit | default(omit) }}" # service: "{{ item.service | default(omit) }}" # install: "{{ item.install | default(omit) }}" From 0dfa378b6da4525f4d8c540396e4d00cf59b913a Mon Sep 17 00:00:00 2001 From: Bodo Schulz Date: Tue, 20 Aug 2024 17:47:26 +0200 Subject: [PATCH 7/9] support for socket --- .../molecule/default/group_vars/all/vars.yml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/roles/systemd_unit/molecule/default/group_vars/all/vars.yml b/roles/systemd_unit/molecule/default/group_vars/all/vars.yml index ef8a510..8516d64 100644 --- a/roles/systemd_unit/molecule/default/group_vars/all/vars.yml +++ b/roles/systemd_unit/molecule/default/group_vars/all/vars.yml @@ -60,6 +60,23 @@ systemd_unit: OnBootSec: 15min OnUnitActiveSec: 1d + - name: systemd-initctl + state: present + unit_type: socket + unit_file: + unit: + Description: initctl Compatibility Named Pipe + Documentation: man:systemd-initctl.socket(8) + DefaultDependencies: no + Before: sockets.target + + Socket: + ListenFIFO: /run/initctl + Symlinks: /dev/initctl + SocketMode: "0600" + + + # - name: chronyd # state: present # unit_type: service From d90e0a67b3c5153a46b88d8c9b34ea3caa5a6460 Mon Sep 17 00:00:00 2001 From: Bodo Schulz Date: Wed, 21 Aug 2024 07:29:16 +0200 Subject: [PATCH 8/9] finalize unit_file module --- README.md | 32 +- galaxy.yml | 2 +- hooks/doc | 2 - plugins/filter/lists.py | 1 + plugins/modules/journalctl.py | 13 +- plugins/modules/unit_file.py | 324 ++++++++++++++---- .../molecule/default/group_vars/all/vars.yml | 219 ++++-------- roles/systemd_unit/tasks/main.yml | 63 +++- 8 files changed, 392 insertions(+), 264 deletions(-) diff --git a/README.md b/README.md index a6122c6..93c3d5f 100644 --- a/README.md +++ b/README.md @@ -6,16 +6,27 @@ Documentation for the collection. | Role | | Description | | :---- | :---- | :---- | -| [bodsch.systemd.coredump](./roles/coredump/README.md) | | configure systemd-coredump | -| [bodsch.systemd.homed](./roles/homed/README.md) | | configure systemd-homed | -| [bodsch.systemd.journald](./roles/journald/README.md) | | configure systemd-journald | -| [bodsch.systemd.oomd](./roles/oomd/README.md) | | configure systemd-oomd | -| [bodsch.systemd.logind](./roles/logind/README.md) | | configure systemd-logind | -| [bodsch.systemd.networkd](./roles/networkd/README.md) | | configure systemd-networkd | -| [bodsch.systemd.resolved](./roles/resolved/README.md) | | configure systemd-resolved | -| [bodsch.systemd.system](./roles/system/README.md) | | configure systemd-system | -| [bodsch.systemd.timesyncd](./roles/timesyncd/README.md) | | configure systemd-timesyncd | -| [bodsch.systemd.user](./roles/user/README.md) | | configure systemd-user | +| [bodsch.systemd.coredump](./roles/coredump/README.md) | [![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/bodsch/ansible-collection-systemd/coredump.yml?branch=main)][coredump] | configure systemd-coredump | +| [bodsch.systemd.homed](./roles/homed/README.md) | [![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/bodsch/ansible-collection-systemd/homed.yml?branch=main)][homed] | configure systemd-homed | +| [bodsch.systemd.journald](./roles/journald/README.md) | [![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/bodsch/ansible-collection-systemd/journald.yml?branch=main)][journald] | configure systemd-journald | +| [bodsch.systemd.oomd](./roles/oomd/README.md) | [![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/bodsch/ansible-collection-systemd/oomd.yml?branch=main)][oomd] | configure systemd-oomd | +| [bodsch.systemd.logind](./roles/logind/README.md) | [![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/bodsch/ansible-collection-systemd/logind.yml?branch=main)][logind] | configure systemd-logind | +| [bodsch.systemd.networkd](./roles/networkd/README.md) | [![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/bodsch/ansible-collection-systemd/networkd.yml?branch=main)][networkd] | configure systemd-networkd | +| [bodsch.systemd.resolved](./roles/resolved/README.md) | [![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/bodsch/ansible-collection-systemd/resolved.yml?branch=main)][resolved] | configure systemd-resolved | +| [bodsch.systemd.system](./roles/system/README.md) | [![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/bodsch/ansible-collection-systemd/system.yml?branch=main)][system] | configure systemd-system | +| [bodsch.systemd.timesyncd](./roles/timesyncd/README.md) | [![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/bodsch/ansible-collection-systemd/timesyncd.yml?branch=main)][timesyncd] | configure systemd-timesyncd | +| [bodsch.systemd.user](./roles/user/README.md) | [![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/bodsch/ansible-collection-systemd/user.yml?branch=main)][user] | configure systemd-user | + +[coredump]: https://github.com/bodsch/ansible-collection-systemd/actions/workflows/coredump.vml +[homed]: https://github.com/bodsch/ansible-collection-systemd/actions/workflows/homed.vml +[journald]: https://github.com/bodsch/ansible-collection-systemd/actions/workflows/journald.vml +[oomd]: https://github.com/bodsch/ansible-collection-systemd/actions/workflows/oomd.vml +[logind]: https://github.com/bodsch/ansible-collection-systemd/actions/workflows/logind.vml +[networkd]: https://github.com/bodsch/ansible-collection-systemd/actions/workflows/networkd.vml +[resolved]: https://github.com/bodsch/ansible-collection-systemd/actions/workflows/resolved.vml +[system]: https://github.com/bodsch/ansible-collection-systemd/actions/workflows/system.vml +[timesyncd]: https://github.com/bodsch/ansible-collection-systemd/actions/workflows/timesyncd.vml +[user]: https://github.com/bodsch/ansible-collection-systemd/actions/workflows/user.vml ## Included content @@ -25,6 +36,7 @@ Documentation for the collection. | Name | Description | |:--------------------------|:----| | [journalctl](./plugins/modules/journalctl.py) | Query the systemd journal with a very limited number of possible parameters | +| [unit_file](./plugins/modules/unit_file.py) | This can be used to create a systemd unit file. The `service`, `timer` and `socket` types are supported. | ## Installing this collection diff --git a/galaxy.yml b/galaxy.yml index 2b84b92..0a5d8ef 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -3,7 +3,7 @@ namespace: bodsch name: systemd -version: 1.1.0 +version: 1.2.0 readme: README.md diff --git a/hooks/doc b/hooks/doc index c600aae..ddcbbcc 100755 --- a/hooks/doc +++ b/hooks/doc @@ -2,8 +2,6 @@ . hooks/molecule.rc -set -x - if [ -z "${COLLECTION_DIR}" ] then echo "missing collection directory" diff --git a/plugins/filter/lists.py b/plugins/filter/lists.py index 0e3a5cb..689ce62 100644 --- a/plugins/filter/lists.py +++ b/plugins/filter/lists.py @@ -10,6 +10,7 @@ class FilterModule(object): """ """ + def filters(self): return { 'valid_list': self.valid_list, diff --git a/plugins/modules/journalctl.py b/plugins/modules/journalctl.py index 28f9832..3119ed0 100644 --- a/plugins/modules/journalctl.py +++ b/plugins/modules/journalctl.py @@ -12,7 +12,7 @@ DOCUMENTATION = """ module: journalctl author: - - Bodo 'bodsch' Schulz + - Bodo 'bodsch' Schulz (@bodsch) short_description: Query the systemd journal with a very limited number of possible parameters. version_added: 1.1.0 @@ -105,15 +105,6 @@ def __init__(self, module): self.reverse = module.params.get("reverse") self.arguments = module.params.get("arguments") - # module.log(msg="----------------------------") - # module.log(msg=f" journalctl : {self._journalctl}") - # module.log(msg=f" unit : {self.unit}") - # module.log(msg=f" identifier : {self.identifier}") - # module.log(msg=f" lines : {self.lines}") - # module.log(msg=f" reverse : {self.reverse}") - # module.log(msg=f" arguments : {self.arguments}") - # module.log(msg="----------------------------") - def run(self): """ """ @@ -214,7 +205,7 @@ def main(): k = JournalCtl(module) result = k.run() - module.log(msg=f"= result: {result}") + # module.log(msg=f"= result: {result}") module.exit_json(**result) diff --git a/plugins/modules/unit_file.py b/plugins/modules/unit_file.py index d0bca7e..9a7b915 100644 --- a/plugins/modules/unit_file.py +++ b/plugins/modules/unit_file.py @@ -14,18 +14,173 @@ from ansible_collections.bodsch.core.plugins.module_utils.checksum import Checksum from ansible.module_utils.basic import AnsibleModule -# from jinja2 import Environment, FileSystemLoader + + +DOCUMENTATION = """ +module: unit_file +author: + - Bodo 'bodsch' Schulz (@bodsch) +short_description: Creates a systemd unit file. +version_added: 1.2.0 + +description: + - Creates a systemd unit file. + - The `service`, `timer` and `socket` types are supported. + +options: + unit_type: + description: + - The unit type to be created. + - The (C(service), C(timer) and C(socket)) types are supported. + - Default is C(service). + type: str + choices: [ service, timer, socket ] + name: + description: + - The name of the unit file. + type: str + state: + description: + - Whether to install (C(present) or remove (C(absent) a unit file. + - Default is C(present). + type: str + choices: [ absent, present ] + drop_ins: + description: + - A list of possible systemd drop-ins. + - The structure corresponds exactly to that of a normal unit file. + type: list + unit_file: + description: The content of a systemd unit file. + type: dict + +""" + +EXAMPLES = """ +- name: create getty drop-ins + bodsch.systemd.unit_file: + name: "getty@tty1" + state: "present" + unit_type: "service" + drop_ins: + - name: autologin + state: present + service: + ExecStart: + - "" + - "{% raw %}-/sbin/agetty -o '-p -f -- \\\\u' --noclear --autologin username %I $TERM{% endraw %}" + Type: simple + + - name: noclear + state: absent + service: + TTYVTDisallocate: false + when: + - ansible_service_mgr == 'systemd' + +- name: create systemd unit file + bodsch.systemd.unit_file: + name: "vaultwarden" + state: "present" + unit_type: "service" + unit_file: + description: | + # + # + # + # + # + # + + Unit: + Description: Vaultwarden API server + Documentation: https://github.com/dani-garcia/vaultwarden + After: network.target + Service: + Type: simple + User: vaultwarden + Group: vaultwarden + LimitNOFILE: 1048576 + UMask: "0077" + + ExecStart: /usr/bin/vaultwarden + EnvironmentFile: /etc/vaultwarden/config.env + Install: + WantedBy: multi-user.target + when: + - ansible_service_mgr == 'systemd' + +- name: create systemd socket + bodsch.systemd.unit_file: + name: "systemd-initctl" + state: "present" + unit_type: "socket" + unit_file: + description: | + # SPDX-License-Identifier: LGPL-2.1-or-later + # + # This file is part of systemd. + # + # systemd is free software; you can redistribute it and/or modify it + # under the terms of the GNU Lesser General Public License as published by + # the Free Software Foundation; either version 2.1 of the License, or + # (at your option) any later version. + unit: + Description: initctl Compatibility Named Pipe + Documentation: man:systemd-initctl.socket(8) + DefaultDependencies: no + Before: sockets.target + + Socket: + ListenFIFO: /run/initctl + Symlinks: /dev/initctl + SocketMode: "0600" + when: + - ansible_service_mgr == 'systemd' + + +- name: create systemd timer + bodsch.systemd.unit_file: + name: "systemd-tmpfiles-clean" + state: "present" + unit_type: "timer" + unit_file: + unit: + Description: Daily Cleanup of Temporary Directories + Documentation: man:tmpfiles.d(5) man:systemd-tmpfiles(8) + ConditionPathExists: "!/etc/initrd-release" + timer: + OnBootSec: 15min + OnUnitActiveSec: 1d + when: + - ansible_service_mgr == 'systemd' +""" + +RETURN = """ +changed: + type: bool + description: Status of the action +msg: + type: str + description: Readable edition of what has been done. +""" + +# -------------------------------------------------------------------------------------------------- UNIT_TPL = """# generated by ansible +{% if item.description is defined %} +{{ item.description }} +{% set _ = item.pop('description') %} +{% endif %} {% for section, options in item.items() %} [{{ section | capitalize }}] {% for option, values in options.items() %} {% if values is string or values is number %} -{{ option }}={{ values }} +{{ option.ljust(34) }} = {{ values }} {% else %} {% for value in values %} -{{ option }}={{ value }} +{{ option.ljust(34) }} = {{ value }} {% endfor %} {% endif %} {% endfor %} @@ -55,7 +210,6 @@ def __init__(self, module): self.tmp_directory = os.path.join("/run/.ansible", f"systemd_unit.{str(os.getpid())}") - def run(self): """ """ @@ -65,111 +219,88 @@ def run(self): changed=False, ) - self.module.log(msg=f"state: {self.state}") - self.module.log(msg=f"drop_ins: {self.drop_ins}") - self.module.log(msg=f"unit_file: {self.unit_file}") + self.checksum = Checksum(self.module) if self.state == "absent": result = self.clean_unit_files() else: - if isinstance(self.drop_ins, list) and len(self.drop_ins) > 0: + result = self.create_unit_files() - self.service_name = f"/etc/systemd/system/{self.name}.d" + if os.path.exists(self.tmp_directory): + shutil.rmtree(self.tmp_directory) - create_directory(directory=self.tmp_directory, mode="0750") + return result + + def create_unit_files(self): + """ """ + if isinstance(self.drop_ins, list) and len(self.drop_ins) > 0: - result = self.create_drop_in(self.drop_ins) + create_directory(directory=self.tmp_directory, mode="0750") + result = self.create_drop_in(self.drop_ins) - # - if isinstance(self.unit_file, dict) and len(self.unit_file) > 0: + if isinstance(self.unit_file, dict) and len(self.unit_file) > 0: - self.service_name = f"/lib/systemd/system/{self.name}.{self.unit_type}" + create_directory(directory=self.tmp_directory, mode="0750") + result = self.create_unit_file(self.unit_file) - create_directory(directory=self.tmp_directory, mode="0750") + return result - result = self.create_unit_file(self.unit_file) + def clean_unit_files(self): + """ """ + if isinstance(self.drop_ins, list) and len(self.drop_ins) > 0: - #if os.path.exists(self.tmp_directory): - # shutil.rmtree(self.tmp_directory) + service_name = f"/etc/systemd/system/{self.name}.d" - # result = self.journalctl_lines() + for drop_in in self.drop_ins: + name = drop_in.get("name") + state = drop_in.get("state", "present") + + if state == "absent": + unit_file = os.path.join(service_name, f"{name}.conf") + result = self.__remove_unit(unit_file) + + if isinstance(self.unit_file, dict) and len(self.unit_file) > 0: + unit_file = os.path.join("/lib/systemd/system", f"{self.name}.{self.unit_type}") + result = self.__remove_unit(unit_file) return result def create_drop_in(self, data): """ """ - # old_checksum = self.checksum.checksum_from_file(file_name) - # new_checksum = self.checksum.checksum_from_file(file_temporary) - - self.module.log(msg="----------------------------") + service_name = f"/etc/systemd/system/{self.name}.d" - self.module.log(msg=f" service name : {self.service_name}") - - # self.clean_unit_files(unit_state_absent) - # self.create_unit_files(unit_state_absent) - - if not os.path.exists(self.service_name): - create_directory(self.service_name) + if not os.path.exists(service_name): + create_directory(service_name) for drop_in in data: name = drop_in.get("name") state = drop_in.get("state", "present") - unit_file = os.path.join(self.service_name, f"{name}.conf") + unit_file = os.path.join(service_name, f"{name}.conf") file_temporary = os.path.join(self.tmp_directory, f"{name}.conf") - self.module.log(msg=f" drop in name : {name}") - self.module.log(msg=f" drop file : {unit_file}") - self.module.log(msg=f" temporary file : {file_temporary}") - if state == "present": file_temporary = os.path.join(self.tmp_directory, f"{name}.conf") data = self.__template(drop_in) - # checksum = self.__checksum(data) with open(file_temporary, "w") as f: f.write(data) - result = dict( - changed=True, - failed=False - ) + result = self.__changed(file_temporary, unit_file) else: - self.module.log(msg=f"remove : {unit_file}") - - if os.path.exists(unit_file): - shutil.rmtree(unit_file) - - result = dict( - changed=True, - failed=False - ) - else: - result = dict( - changed=False, - failed=False - ) - - self.module.log(msg="----------------------------") + result = self.__remove_unit(unit_file) return result def create_unit_file(self, data): """ """ - # old_checksum = self.checksum.checksum_from_file(file_name) - # new_checksum = self.checksum.checksum_from_file(file_temporary) - - file_temporary = os.path.join(self.tmp_directory, self.name) - - self.module.log(msg="----------------------------") - - self.module.log(msg=f" service name : {self.service_name}") - self.module.log(msg=f" temporary file : {file_temporary}") + unit_file = os.path.join("/lib/systemd/system", f"{self.name}.{self.unit_type}") + file_temporary = os.path.join(self.tmp_directory, f"{self.name}.{self.unit_type}") if self.state == "present": data = self.__template(data) @@ -177,30 +308,71 @@ def create_unit_file(self, data): with open(file_temporary, "w") as f: f.write(data) + result = self.__changed(file_temporary, unit_file) + else: + pass + result = dict( - changed=True, + changed=False, failed=False ) - else: - pass + + return result + + def __changed(self, file_temporary, unit_file): + """ """ + + old_checksum = self.checksum.checksum_from_file(unit_file) + new_checksum = self.checksum.checksum_from_file(file_temporary) + + changed = not (new_checksum == old_checksum) + new_file = False + msg = "The unit-file has not been changed" + + # self.module.log(msg=f" file_name {unit_file}") + # self.module.log(msg=f" file_temporary {file_temporary}") + # self.module.log(msg=f" old_checksum {old_checksum}") + # self.module.log(msg=f" new_checksum {new_checksum}") + # self.module.log(msg=f" changed {changed}") + + if changed: + new_file = (old_checksum is None) + shutil.move(file_temporary, unit_file) + msg = "The unit-file was successfully changed" + + if new_file: + msg = "The unit-file was successfully created" result = dict( - changed=False, - failed=False + changed=changed, + msg=msg ) - self.module.log(msg="----------------------------") - return result + def __remove_unit(self, unit_file): + """ """ + if os.path.exists(unit_file): + os.remove(unit_file) + result = dict( + changed=True, + failed=False, + msg="The unit-file was successfully removed." + ) + else: + result = dict( + changed=False, + failed=False, + msg="The unit-file has already been removed." + ) - + return result def __template(self, data): """ """ - self.module.log(msg=f"__template({data} ({type(data)}))") + # self.module.log(msg=f"__template({data} ({type(data)}))") if isinstance(data, dict): from jinja2 import Template @@ -210,7 +382,7 @@ def __template(self, data): if data.get('state'): _ = data.pop('state') - self.module.log(msg=f"{data} ({type(data)})") + # self.module.log(msg=f"{data} ({type(data)})") tm = Template(UNIT_TPL, trim_blocks=True, lstrip_blocks=True) d = tm.render(item=data) @@ -270,7 +442,7 @@ def main(): k = SystemdUnitFile(module) result = k.run() - module.log(msg=f"= result: {result}") + # module.log(msg=f"= result: {result}") module.exit_json(**result) diff --git a/roles/systemd_unit/molecule/default/group_vars/all/vars.yml b/roles/systemd_unit/molecule/default/group_vars/all/vars.yml index 8516d64..e13386b 100644 --- a/roles/systemd_unit/molecule/default/group_vars/all/vars.yml +++ b/roles/systemd_unit/molecule/default/group_vars/all/vars.yml @@ -1,172 +1,75 @@ --- systemd_unit: - - name: "getty@tty1" - state: present - unit_type: service - overwrite: true - drop_ins: - - name: autologin - state: present - Service: - ExecStart: - - "" - - "{% raw %}-/sbin/agetty -o '-p -f -- \\\\u' --noclear --autologin username %I $TERM{% endraw %}" - Type: simple - - - name: noclear - state: absent - Service: - TTYVTDisallocate: false - - - name: sshd - state: present + - name: vaultwarden + state: absent unit_type: service overwrite: false unit_file: - unit: - Description: OpenBSD Secure Shell server - Documentation: man:sshd(8) man:sshd_config(5) - After: - - network.target - - auditd.service - ConditionPathExists: "!/etc/ssh/sshd_not_to_be_run" - service: - EnvironmentFile: -/etc/default/ssh - ExecStartPre: /usr/sbin/sshd -t - ExecStart: /usr/sbin/sshd -D $SSHD_OPTS - ExecReload: - - /usr/sbin/sshd -t - - /bin/kill -HUP $MAINPID - KillMode: process + description: | + # + # + # + # + # + # + + Unit: + Description: Vaultwarden API server + Documentation: https://github.com/dani-garcia/vaultwarden + After: network.target + + Service: + Type: simple + User: vaultwarden + Group: vaultwarden + LimitNOFILE: 1048576 + UMask: "0077" + + ExecStart: /usr/bin/vaultwarden + EnvironmentFile: /etc/vaultwarden/config.env + Restart: on-failure - RestartPreventExitStatus: 255 - Type: notify - RuntimeDirectory: sshd - RuntimeDirectoryMode: "0755" - install: - WantedBy: multi-user.target - Alias: sshd.service + RestartSec: 15s - - name: systemd-tmpfiles-clean - state: present - unit_type: timer - unit_file: - unit: - Description: Daily Cleanup of Temporary Directories - Documentation: man:tmpfiles.d(5) man:systemd-tmpfiles(8) - ConditionPathExists: "!/etc/initrd-release" - timer: - OnBootSec: 15min - OnUnitActiveSec: 1d + CapabilityBoundingSet: CAP_NET_BIND_SERVICE + AmbientCapabilities: CAP_NET_BIND_SERVICE - - name: systemd-initctl - state: present - unit_type: socket - unit_file: - unit: - Description: initctl Compatibility Named Pipe - Documentation: man:systemd-initctl.socket(8) - DefaultDependencies: no - Before: sockets.target + LockPersonality: true + MemoryDenyWriteExecute: true + PrivateDevices: true + PrivateTmp: true + ProtectClock: true + ProtectControlGroups: true + ProtectHome: true + ProtectHostname: true + ProtectKernelLogs: true + ProtectKernelModules: true + ProtectKernelTunables: true + ProtectSystem: strict + RemoveIPC: true + RestrictAddressFamilies: AF_UNIX AF_INET AF_INET6 + RestrictNamespaces: true + RestrictRealtime: true + RestrictSUIDSGID: true + + NoNewPrivileges: true - Socket: - ListenFIFO: /run/initctl - Symlinks: /dev/initctl - SocketMode: "0600" + SystemCallFilter: + - "@system-service" + - "~@privileged @resources" + SystemCallArchitectures: native + WorkingDirectory: /var/lib/vaultwarden + ReadWriteDirectories: /var/lib/vaultwarden + # ReadWriteDirectories: {{ vaultwarden_config.logging.log_file | dirname }} + # {% if vaultwarden_config.web_vault.enabled is defined and + # vaultwarden_config.web_vault.enabled | string | length > 0 and + # vaultwarden_config.web_vault.enabled | bool == True %} + # ReadWriteDirectories: {{ vaultwarden_config.directories.web_vault }}/web-vault + # {% endif %} + Install: + WantedBy: multi-user.target - # - name: chronyd - # state: present - # unit_type: service - # overwrite: false - # - # unit: - # Description: "NTP client/server" - # Documentation: "man:chronyd(8) man:chrony.conf(5)" - # After: - # - ntpdate.service - # - sntp.service - # - ntpd.service - # Conflicts: - # - ntpd.service - # - systemd-timesyncd.service - # ConditionCapability: - # - CAP_SYS_TIME - # service: - # Type: forking - # PIDFile: /run/chrony/chronyd.pid - # EnvironmentFile: - # - "-/etc/sysconfig/chronyd" - # ExecStart: - # - "/usr/bin/chronyd $OPTIONS" - # - # CapabilityBoundingSet: - # - CAP_AUDIT_CONTROL - # - CAP_AUDIT_READ - # - CAP_AUDIT_WRITE - # - CAP_BLOCK_SUSPEND - # - CAP_KILL - # - CAP_LEASE - # - CAP_LINUX_IMMUTABLE - # - CAP_MAC_ADMIN - # - CAP_MAC_OVERRIDE - # - CAP_MKNOD - # - CAP_SYS_ADMIN - # - CAP_SYS_BOOT - # - CAP_SYS_CHROOT - # - CAP_SYS_MODULE - # - CAP_SYS_PACCT - # - CAP_SYS_PTRACE - # - CAP_SYS_RAWIO - # - CAP_SYS_TTY_CONFIG - # - CAP_WAKE_ALARM - # DeviceAllow: - # - char-pps rw - # - char-ptp rw - # - char-rtc rw - # DevicePolicy: closed - # LockPersonality: true - # MemoryDenyWriteExecute: true - # NoNewPrivileges: true - # PrivateTmp: true - # ProtectControlGroups: true - # ProtectHome: true - # ProtectHostname: true - # ProtectKernelLogs: true - # ProtectKernelModules: true - # ProtectKernelTunables: true - # ProtectProc: invisible - # ProtectSystem: strict - # ReadWritePaths: - # - /run - # - /var/lib/chrony - # - -/var/log - # RestrictAddressFamilies: - # - AF_INET - # - AF_INET6 - # - AF_UNIX - # RestrictNamespaces: true - # RestrictSUIDSGID: true - # SystemCallArchitectures: native - # SystemCallFilter: - # - "@cpu-emulation" - # - "@debug" - # - "@module" - # - "@mount" - # - "@obsolete" - # - "@raw-io" - # - "@reboot" - # - "@swap" - # - # # Adjust restrictions for /usr/bin/sendmail (mailonchange directive) - # # NoNewPrivileges: false - # # ReadWritePaths: - # # - -/var/spool - # # RestrictAddressFamilies: - # # - AF_NETLINK - # - # install: - # WantedBy: multi-user.target ... diff --git a/roles/systemd_unit/tasks/main.yml b/roles/systemd_unit/tasks/main.yml index fc7bdc6..93592eb 100644 --- a/roles/systemd_unit/tasks/main.yml +++ b/roles/systemd_unit/tasks/main.yml @@ -1,5 +1,59 @@ --- +- name: create getty drop-ins + bodsch.systemd.unit_file: + name: "getty@tty1" + state: "present" + unit_type: "service" + drop_ins: + - name: autologin + state: present + service: + ExecStart: + - "" + - "{% raw %}-/sbin/agetty -o '-p -f -- \\\\u' --noclear --autologin username %I $TERM{% endraw %}" + Type: simple + + - name: noclear + state: absent + service: + TTYVTDisallocate: false + when: + - ansible_service_mgr == 'systemd' + +- name: create systemd unit + bodsch.systemd.unit_file: + name: "nextcloud-cron" + state: "present" + unit_type: "service" + unit_file: + unit: + Description: Nextcloud cron.php job + service: + User: www-data + ExecCondition: php -f /var/www/nextcloud/server/occ status --exit-code + ExecStart: /usr/bin/php -f /var/www/nextcloud/server/cron.php + KillMode: process + when: + - ansible_service_mgr == 'systemd' + +- name: create systemd timer + bodsch.systemd.unit_file: + name: "nextcloud-cron" + state: "present" + unit_type: "timer" + unit_file: + unit: + Description: Run Nextcloud cron.php every 5 minutes + timer: + OnBootSec: 5min + OnUnitActiveSec: 5min + Unit: nextcloud-cron.service + install: + WantedBy: timers.target + when: + - ansible_service_mgr == 'systemd' + - name: create systemd unit files bodsch.systemd.unit_file: name: "{{ item.name }}" @@ -8,9 +62,6 @@ overwrite: "{{ item.overwrite | default(omit) }}" drop_ins: "{{ item.drop_ins | default(omit) }}" unit_file: "{{ item.unit_file | default(omit) }}" - # unit: "{{ item.unit | default(omit) }}" - # service: "{{ item.service | default(omit) }}" - # install: "{{ item.install | default(omit) }}" loop: "{{ systemd_unit }}" loop_control: @@ -20,8 +71,8 @@ when: - systemd_unit | count > 0 -- name: d - debug: - msg: "{{ systemd_unit_file }}" +# - name: d +# debug: +# msg: "{{ systemd_unit_file }}" ... From c7af801395b51e987ef1641d0ed8eee4452e73b3 Mon Sep 17 00:00:00 2001 From: Bodo Schulz Date: Wed, 21 Aug 2024 07:33:32 +0200 Subject: [PATCH 9/9] fix pycodestyle --- .config/pycodestyle.cfg | 2 +- .github/workflows/linter.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.config/pycodestyle.cfg b/.config/pycodestyle.cfg index c370dd2..9660b71 100644 --- a/.config/pycodestyle.cfg +++ b/.config/pycodestyle.cfg @@ -3,5 +3,5 @@ ignore = E402, E123 # It's fine to have line-length of 99 -max-line-length = 99 +max-line-length = 150 diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml index 4beaf84..9937eae 100644 --- a/.github/workflows/linter.yml +++ b/.github/workflows/linter.yml @@ -65,4 +65,4 @@ jobs: - name: Lint code. run: | - pycodestyle plugins/ --config=.config/pycodestyle.cfg --statistics --count + pycodestyle plugins/ --config=.config/pycodestyle.cfg --statistics --count --exclude=test_*.py --exclude=hooks/*.py