From 6ee8c60e64ed9ed3cd7c9f603d83402b978eaf7d Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Sun, 21 Jun 2026 16:37:19 +1000 Subject: [PATCH] Fix the almalinux tests - skip jinjaturtle and systemd in CI --- .forgejo/workflows/ci.yml | 4 +-- enroll/ansible.py | 15 +++++++-- tests.sh | 66 ++++++++++++++++++++++----------------- tests/test_manifest.py | 13 ++++++-- 4 files changed, 62 insertions(+), 36 deletions(-) diff --git a/.forgejo/workflows/ci.yml b/.forgejo/workflows/ci.yml index 9fc6b21..f8ed89d 100644 --- a/.forgejo/workflows/ci.yml +++ b/.forgejo/workflows/ci.yml @@ -34,7 +34,7 @@ jobs: mkdir -m 755 -p /etc/apt/keyrings apt-get update DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ - ca-certificates curl gnupg git tar gzip findutils bash nodejs \ + ca-certificates curl gnupg git tar gzip findutils bash nodejs procps \ ansible ansible-lint python3 python3-venv python3-pip pipx systemctl python3-apt jq python3-jsonschema \ puppet hiera curl -fsSL https://packages.broadcom.com/artifactory/api/security/keypair/SaltProjectKey/public | gpg --dearmor | tee /etc/apt/keyrings/salt-archive-keyring.pgp > /dev/null @@ -46,7 +46,7 @@ jobs: almalinux) dnf -y upgrade --refresh dnf -y install \ - ca-certificates curl-minimal gnupg2 git tar gzip findutils bash which jq nodejs \ + ca-certificates curl-minimal gnupg2 git tar gzip findutils bash which jq nodejs procps-ng \ dnf-plugins-core epel-release dnf -y config-manager --set-enabled crb || true curl -fsSL https://github.com/saltstack/salt-install-guide/releases/latest/download/salt.repo > /etc/yum.repos.d/salt.repo diff --git a/enroll/ansible.py b/enroll/ansible.py index 4b5ec7b..9794de3 100644 --- a/enroll/ansible.py +++ b/enroll/ansible.py @@ -1002,7 +1002,9 @@ def _render_grouped_systemd_tasks(var_prefix: str) -> str: register: _enroll_unit_probes failed_when: false changed_when: false - when: item.manage | default(false) + when: + - enroll_manage_systemd_runtime | default(true) | bool + - item.manage | default(false) - name: Ensure grouped unit enablement matches harvest ansible.builtin.systemd: @@ -1011,6 +1013,7 @@ def _render_grouped_systemd_tasks(var_prefix: str) -> str: no_log: "{{{{ enroll_hide_systemd_status | default(true) | bool }}}}" loop: "{{{{ _enroll_unit_probes.results | default([]) }}}}" when: + - enroll_manage_systemd_runtime | default(true) | bool - item.item.manage | default(false) - not (item.failed | default(false)) @@ -1021,6 +1024,7 @@ def _render_grouped_systemd_tasks(var_prefix: str) -> str: no_log: "{{{{ enroll_hide_systemd_status | default(true) | bool }}}}" loop: "{{{{ _enroll_unit_probes.results | default([]) }}}}" when: + - enroll_manage_systemd_runtime | default(true) | bool - item.item.manage | default(false) - not (item.failed | default(false)) """ @@ -1083,7 +1087,9 @@ def _render_single_systemd_tasks(var_prefix: str) -> str: register: _unit_probe failed_when: false changed_when: false - when: {var_prefix}_manage_unit | default(false) + when: + - enroll_manage_systemd_runtime | default(true) | bool + - {var_prefix}_manage_unit | default(false) - name: Ensure unit enablement matches harvest ansible.builtin.systemd: @@ -1091,6 +1097,7 @@ def _render_single_systemd_tasks(var_prefix: str) -> str: enabled: "{{{{ {var_prefix}_systemd_enabled | bool }}}}" no_log: "{{{{ enroll_hide_systemd_status | default(true) | bool }}}}" when: + - enroll_manage_systemd_runtime | default(true) | bool - {var_prefix}_manage_unit | default(false) - _unit_probe is succeeded @@ -1100,6 +1107,7 @@ def _render_single_systemd_tasks(var_prefix: str) -> str: state: "{{{{ {var_prefix}_systemd_state }}}}" no_log: "{{{{ enroll_hide_systemd_status | default(true) | bool }}}}" when: + - enroll_manage_systemd_runtime | default(true) | bool - {var_prefix}_manage_unit | default(false) - _unit_probe is succeeded """ @@ -1142,6 +1150,7 @@ def _single_service_restart_handler_body(var_prefix: str) -> str: name: "{{{{ {var_prefix}_unit_name }}}}" state: restarted when: + - enroll_manage_systemd_runtime | default(true) | bool - {var_prefix}_manage_unit | default(false) - ({var_prefix}_systemd_state | default('stopped')) == 'started' """ @@ -1162,6 +1171,7 @@ def _grouped_service_restart_handlers_body(role: AnsibleRole) -> str: ansible.builtin.service: name: {name} state: restarted + when: enroll_manage_systemd_runtime | default(true) | bool """ ) return "\n".join(_task_body(handler) for handler in handlers if _task_body(handler)) @@ -1580,6 +1590,7 @@ _SYSTEMD_DAEMON_RELOAD_HANDLER = """--- ansible.builtin.systemd: daemon_reload: true no_log: "{{ enroll_hide_systemd_status | default(true) | bool }}" + when: enroll_manage_systemd_runtime | default(true) | bool """ diff --git a/tests.sh b/tests.sh index 4130af3..4d4a410 100755 --- a/tests.sh +++ b/tests.sh @@ -34,6 +34,7 @@ SALT_JINJATURTLE_DIR="${WORK_DIR}/salt-jinjaturtle" SALT_NO_JINJATURTLE_DIR="${WORK_DIR}/salt-no-jinjaturtle" TEST_FQDN="${ENROLL_TEST_FQDN:-enroll-ci.example.test}" JINJATURTLE_FIXTURE="${WORK_DIR}/enroll-tests-jinjaturtle.ini" +ANSIBLE_PLAYBOOK_EXTRA_ARGS=() cleanup() { if [[ "${KEEP_WORKDIR}" -eq 0 ]]; then @@ -88,6 +89,29 @@ require_supported_ci_os() { fi } + +pid1_comm() { + if [[ -r /proc/1/comm ]]; then + tr -d '[:space:]' /dev/null 2>&1; then + ps -p 1 -o comm= 2>/dev/null | tr -d '[:space:]' || true + fi +} + +configure_ansible_playbook_extra_args() { + local pid1 + pid1="$(pid1_comm)" + + ANSIBLE_PLAYBOOK_EXTRA_ARGS=() + if [[ "${pid1}" != "systemd" ]]; then + section "Setup: Ansible systemd runtime guard" + printf 'PID 1 is %s, not systemd; disabling generated Ansible systemd runtime enforcement for CI noop plays.\n' "${pid1:-unknown}" + ANSIBLE_PLAYBOOK_EXTRA_ARGS=(-e enroll_manage_systemd_runtime=false) + fi +} + os_id() { if [[ -r /etc/os-release ]]; then # shellcheck disable=SC1091 @@ -244,29 +268,6 @@ ensure_puppet_repo() { DNF_UPDATED= } -ensure_mig5_rpm_repo() { - if ! is_rpm_family; then - return - fi - if [[ -e /etc/yum.repos.d/mig5.repo ]]; then - return - fi - section "Setup: mig5 dnf repository" - pkg_install ca-certificates curl - run rpm --import https://mig5.net/static/mig5.asc - cat >/etc/yum.repos.d/mig5.repo <<'EOF' -[mig5] -name=mig5 Repository -baseurl=https://rpm.mig5.net/$releasever/rpm/$basearch -enabled=1 -gpgcheck=1 -repo_gpgcheck=1 -gpgkey=https://mig5.net/static/mig5.asc -EOF - run dnf -y upgrade --refresh - DNF_UPDATED=1 -} - ensure_jinjaturtle() { section "Setup: JinjaTurtle package" if command -v jinjaturtle >/dev/null 2>&1; then @@ -286,8 +287,8 @@ ensure_jinjaturtle() { APT_UPDATED=1 run env DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends jinjaturtle elif is_rpm_family; then - ensure_mig5_rpm_repo - pkg_install jinjaturtle + printf 'Skipping JinjaTurtle package integration on RPM-family CI;\n' + return else fail "Unsupported OS for JinjaTurtle package install: $(os_id)." fi @@ -392,7 +393,7 @@ run_ansible_jinjaturtle_variant() { ansible-galaxy install -r "${out_dir}/requirements.yml" run ansible-lint "${out_dir}" cd "${out_dir}" - run ansible-playbook playbook.yml -i "localhost," -c local --check --diff + run ansible-playbook playbook.yml -i "localhost," -c local --check --diff "${ANSIBLE_PLAYBOOK_EXTRA_ARGS[@]}" } run_puppet_jinjaturtle_variant() { @@ -424,6 +425,12 @@ run_salt_jinjaturtle_variant() { } run_jinjaturtle_manifest_tests() { + if is_rpm_family ; then + section "JinjaTurtle integration matrix" + printf 'Skipping JinjaTurtle package integration on RPM-family CI;\n' + return + fi + ensure_jinjaturtle require_cmd jinjaturtle "Install JinjaTurtle before running the JinjaTurtle integration matrix." @@ -450,19 +457,19 @@ run_ansible_noop_tests() { ansible-galaxy install -r "${ANSIBLE_DIR}/requirements.yml" run ansible-lint "${ANSIBLE_DIR}" cd "${ANSIBLE_DIR}" - run ansible-playbook playbook.yml -i "localhost," -c local --check --diff + run ansible-playbook playbook.yml -i "localhost," -c local --check --diff "${ANSIBLE_PLAYBOOK_EXTRA_ARGS[@]}" cd "${PROJECT_ROOT}" run poetry run enroll manifest --harvest "${BUNDLE_DIR}" --out "${ANSIBLE_NO_COMMON_DIR}" --target ansible --no-common-roles ansible-galaxy install -r "${ANSIBLE_NO_COMMON_DIR}/requirements.yml" cd "${ANSIBLE_NO_COMMON_DIR}" - run ansible-playbook playbook.yml -i "localhost," -c local --check --diff + run ansible-playbook playbook.yml -i "localhost," -c local --check --diff "${ANSIBLE_PLAYBOOK_EXTRA_ARGS[@]}" cd "${PROJECT_ROOT}" run poetry run enroll manifest --harvest "${BUNDLE_DIR}" --out "${ANSIBLE_FQDN_DIR}" --target ansible --fqdn "${TEST_FQDN}" ansible-galaxy install -r "${ANSIBLE_FQDN_DIR}/requirements.yml" cd "${ANSIBLE_FQDN_DIR}" - run ansible-playbook "playbooks/${TEST_FQDN}.yml" -i inventory/hosts.ini -c local --limit "${TEST_FQDN}" --check --diff + run ansible-playbook "playbooks/${TEST_FQDN}.yml" -i inventory/hosts.ini -c local --limit "${TEST_FQDN}" --check --diff "${ANSIBLE_PLAYBOOK_EXTRA_ARGS[@]}" } run_puppet_noop_tests() { @@ -507,6 +514,7 @@ main() { require_supported_ci_os run_pytests prepare_harvest_fixture + configure_ansible_playbook_extra_args run_ansible_noop_tests run_puppet_noop_tests run_salt_noop_tests diff --git a/tests/test_manifest.py b/tests/test_manifest.py index cc6d045..dba3d24 100644 --- a/tests/test_manifest.py +++ b/tests/test_manifest.py @@ -266,10 +266,15 @@ def test_manifest_writes_roles_and_playbook_with_clean_when(tmp_path: Path): tasks = (out / "roles" / "foo" / "tasks" / "main.yml").read_text(encoding="utf-8") assert "- name: Probe whether systemd unit exists and is manageable" in tasks assert 'no_log: "{{ enroll_hide_systemd_status | default(true) | bool }}"' in tasks - assert "when: foo_manage_unit | default(false)" in tasks + assert "enroll_manage_systemd_runtime | default(true) | bool" in tasks assert ( - "when:\n - foo_manage_unit | default(false)\n - _unit_probe is succeeded\n" - in tasks + "when:\n - enroll_manage_systemd_runtime | default(true) | bool\n" + " - foo_manage_unit | default(false)\n" in tasks + ) + assert ( + "when:\n - enroll_manage_systemd_runtime | default(true) | bool\n" + " - foo_manage_unit | default(false)\n" + " - _unit_probe is succeeded\n" in tasks ) # Ensure we didn't emit deprecated/broken '{{ }}' delimiters in when: lines. @@ -632,6 +637,7 @@ def test_manifest_groups_systemd_units_into_common_role(tmp_path: Path): tasks = (out / "roles" / "net" / "tasks" / "main.yml").read_text(encoding="utf-8") assert "Ensure grouped unit enablement matches harvest" in tasks assert 'no_log: "{{ enroll_hide_systemd_status | default(true) | bool }}"' in tasks + assert "enroll_manage_systemd_runtime | default(true) | bool" in tasks assert "Restart managed services" not in tasks defaults_text = (out / "roles" / "net" / "defaults" / "main.yml").read_text( @@ -647,6 +653,7 @@ def test_manifest_groups_systemd_units_into_common_role(tmp_path: Path): encoding="utf-8" ) assert "Run systemd daemon-reload" in handlers + assert "when: enroll_manage_systemd_runtime | default(true) | bool" in handlers assert "- name: Restart managed service NetworkManager.service" in handlers assert "name: NetworkManager.service" in handlers assert "state: restarted" in handlers