From 062138cbf9b7374fe747d147520c7eb534d43eea Mon Sep 17 00:00:00 2001 From: "l.cuper@t-systems.com" Date: Thu, 20 Aug 2026 18:54:43 +0200 Subject: [PATCH 1/9] Fix the docker daemon diagnostic block The 'Fail with diagnostic context' task had no when condition, so the play failed even when docker started correctly. Conversely the wait_for above it aborted the play on real failure, so the diagnostics it was meant to collect never ran in the case they were written for. Make wait_for non-fatal and put the diagnostics and the failure behind 'docker_sock is failed', so they run exactly when the socket never appeared. Also drop the reference to docker_info, which is never registered, and use pgrep instead of 'ps aux | grep' under ansible.builtin.command, which does not interpret pipes - those characters were being passed to ps as literal arguments. --- playbooks_k8s/run.yaml | 78 ++++++++++++++++++++++-------------------- 1 file changed, 40 insertions(+), 38 deletions(-) diff --git a/playbooks_k8s/run.yaml b/playbooks_k8s/run.yaml index c250b68..785b964 100644 --- a/playbooks_k8s/run.yaml +++ b/playbooks_k8s/run.yaml @@ -139,44 +139,46 @@ ansible.builtin.wait_for: path: /var/run/docker.sock timeout: 60 - - # After 75s of retries the daemon still hasn't started. Capture - # stderr/stdout from the last attempt, show the process list, and - # dump the daemon log so we can diagnose why it fails. - - name: Show docker info output from last attempt - ansible.builtin.debug: - var: docker_info - when: docker_info is defined - - - name: Check if dockerd process exists - ansible.builtin.command: - cmd: ps aux | grep -v grep | grep dockerd - register: dockerd_ps - changed_when: false - failed_when: false - - - name: Show dockerd log (last 100 lines) - ansible.builtin.command: - cmd: tail -n 100 /var/log/dockerd.log - register: dockerd_tail - changed_when: false - failed_when: false - - - name: Show containerd log (last 100 lines) - ansible.builtin.command: - cmd: tail -n 100 /var/log/containerd.log - register: containerd_tail - changed_when: false - failed_when: false - - - name: Fail with diagnostic context - ansible.builtin.fail: - msg: >- - Docker daemon failed to start after 75s. - dockerd process: {{ dockerd_ps.stdout_lines | default(['no process found']) }} - Last docker info: {{ docker_info.msg | default('N/A') }} - dockerd log:\n{{ dockerd_tail.stdout | default('no log file') }} - containerd log:\n{{ containerd_tail.stdout | default('no log file') }} + register: docker_sock + ignore_errors: true + + # Only runs when the socket never appeared. wait_for above is + # non-fatal so these diagnostics can be collected before failing; + # previously it aborted the play, so they never ran on failure, and + # the fail below had no condition, so it always ran on success. + - name: Diagnose why the docker daemon did not start + when: docker_sock is failed + block: + - name: Check if dockerd process exists + ansible.builtin.command: + cmd: pgrep -a dockerd + register: dockerd_ps + changed_when: false + failed_when: false + + - name: Show dockerd log (last 100 lines) + ansible.builtin.command: + cmd: tail -n 100 /var/log/dockerd.log + register: dockerd_tail + changed_when: false + failed_when: false + + - name: Show containerd log (last 100 lines) + ansible.builtin.command: + cmd: tail -n 100 /var/log/containerd.log + register: containerd_tail + changed_when: false + failed_when: false + + - name: Fail with diagnostic context + ansible.builtin.fail: + msg: |- + Docker daemon failed to start after 60s. + dockerd process: {{ dockerd_ps.stdout_lines | default(['no process found']) }} + dockerd log: + {{ dockerd_tail.stdout | default('no log file') }} + containerd log: + {{ containerd_tail.stdout | default('no log file') }} - hosts: all become: true From f0bd65f481e429adbafc8eca99dddc51e1113467 Mon Sep 17 00:00:00 2001 From: "l.cuper@t-systems.com" Date: Thu, 20 Aug 2026 19:31:52 +0200 Subject: [PATCH 2/9] Install python packaging and venv tooling before cloudmon roles install_cloudmon failed on the zuul-debian-docker node with: ModuleNotFoundError: No module named 'packaging' ansible.builtin.pip imports packaging on the target, and cloudmon_venv_path defaults to ~/.venv so the module also has to build a virtualenv. The node image provides neither, so install them before the roles run. --- playbooks_k8s/run.yaml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/playbooks_k8s/run.yaml b/playbooks_k8s/run.yaml index 785b964..07ffff6 100644 --- a/playbooks_k8s/run.yaml +++ b/playbooks_k8s/run.yaml @@ -182,6 +182,21 @@ - hosts: all become: true + pre_tasks: + # The node image ships none of these: ansible.builtin.pip imports + # `packaging` on the target, and cloudmon_venv_path makes it build a + # venv, which needs the venv/virtualenv tooling. + - name: Install Python packaging and venv tooling + ansible.builtin.apt: + name: + - python3-packaging + - python3-pip + - python3-venv + - virtualenv + state: present + register: py_prereq + retries: 5 + until: py_prereq is success roles: - install_cloudmon - deploy_cloudmon_k8s From b600793d1514417f4e9335baeef2f56c16332cf4 Mon Sep 17 00:00:00 2001 From: "l.cuper@t-systems.com" Date: Thu, 20 Aug 2026 22:06:30 +0200 Subject: [PATCH 3/9] Surface cloudmon provision output instead of a bare rc The Deploy task ran graphite, statsd and postgres provisioning in one shell block with no 'set -e', so rc came from the last command only and an earlier failure would pass unnoticed. On failure Ansible reported just 'non-zero return code' with no stdout/stderr, and job-output.json is not uploaded, so there was nothing to debug from. Run one component per loop item, print rc/stdout/stderr for each, then fail listing the components that actually failed. --- roles/deploy_cloudmon_k8s/tasks/main.yaml | 34 +++++++++++++++++++++-- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/roles/deploy_cloudmon_k8s/tasks/main.yaml b/roles/deploy_cloudmon_k8s/tasks/main.yaml index 8dcc5c0..5e4b568 100644 --- a/roles/deploy_cloudmon_k8s/tasks/main.yaml +++ b/roles/deploy_cloudmon_k8s/tasks/main.yaml @@ -10,9 +10,37 @@ executable: "/bin/bash" ansible.builtin.shell: | source {{ cloudmon_venv_path }}/bin/activate - cloudmon --config etc/sample_config.yaml --inventory {{ ansible_user_dir }}/{{ zuul_work_dir }}/inventory --insecure graphite provision - cloudmon --config etc/sample_config.yaml --inventory {{ ansible_user_dir }}/{{ zuul_work_dir }}/inventory --insecure statsd provision - cloudmon --config etc/sample_config.yaml --inventory {{ ansible_user_dir }}/{{ zuul_work_dir }}/inventory --insecure postgres provision + cloudmon --config etc/sample_config.yaml --inventory {{ ansible_user_dir }}/{{ zuul_work_dir }}/inventory --insecure {{ item }} provision + loop: + - graphite + - statsd + - postgres + register: cloudmon_provision + failed_when: false + +# Run one component per task and report before failing. Previously all three +# ran in a single shell block with no `set -e`, so rc came from the last +# command only and the output was never surfaced -- a failure showed up as a +# bare "non-zero return code" with nothing to debug. +- name: Show cloudmon provision output + ansible.builtin.debug: + msg: |- + {{ item.item }} rc={{ item.rc }} + stdout: + {{ item.stdout | default('') }} + stderr: + {{ item.stderr | default('') }} + loop: "{{ cloudmon_provision.results }}" + loop_control: + label: "{{ item.item }}" + +- name: Fail if any cloudmon provision step failed + ansible.builtin.fail: + msg: >- + cloudmon provision failed for: + {{ cloudmon_provision.results | selectattr('rc', 'ne', 0) + | map(attribute='item') | list }} + when: cloudmon_provision.results | selectattr('rc', 'ne', 0) | list | length > 0 # cloudmon --config etc/sample_config.yaml --inventory {{ ansible_user_dir }}/{{ zuul_work_dir }}/inventory --insecure grafana provision # cloudmon --config etc/sample_config.yaml --inventory {{ ansible_user_dir }}/{{ zuul_work_dir }}/inventory --insecure apimon provision From ff9e113bf5e95138edbb9595f9221c0b5917b023 Mon Sep 17 00:00:00 2001 From: "l.cuper@t-systems.com" Date: Thu, 20 Aug 2026 22:11:38 +0200 Subject: [PATCH 4/9] Fix inventory template: group hosts must be a mapping Every child group declared its hosts as a list: statsd: hosts: - localhost Ansible's yaml inventory plugin requires a mapping there and rejected the whole file: Invalid "hosts" entry for "statsd" group, requires a dictionary With no inventory parsed, every provisioning play matched no hosts. graphite still exited 0 while doing nothing ('skipping: no hosts matched'), so the failure surfaced only as statsd/postgres rc=1. Reproduced with ansible-inventory: the old template raises the exact error, the new one resolves all 8 groups to localhost. --- .../templates/inventory.j2 | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/roles/deploy_cloudmon_k8s/templates/inventory.j2 b/roles/deploy_cloudmon_k8s/templates/inventory.j2 index e7c8bac..ef24aa5 100644 --- a/roles/deploy_cloudmon_k8s/templates/inventory.j2 +++ b/roles/deploy_cloudmon_k8s/templates/inventory.j2 @@ -7,27 +7,30 @@ all: ansible_host: localhost internal_address: localhost children: + # A group's `hosts` must be a mapping, not a list -- a list makes Ansible + # reject the whole inventory ("requires a dictionary"), after which every + # play matches no hosts. statsd: hosts: - - localhost + localhost: graphite: hosts: - - localhost + localhost: grafana: hosts: - - localhost + localhost: schedulers: hosts: - - localhost + localhost: executors: hosts: - - localhost + localhost: epmons: hosts: - - localhost + localhost: globalmons: hosts: - - localhost + localhost: postgres: hosts: - - localhost + localhost: From 6c96208f9b7402f81f5b8ab8b14e5501a8b0222b Mon Sep 17 00:00:00 2001 From: "l.cuper@t-systems.com" Date: Thu, 20 Aug 2026 22:16:01 +0200 Subject: [PATCH 5/9] Use local connection for localhost in cloudmon inventory Provisioning failed with: ssh: connect to host localhost port 22: Connection refused fatal: [localhost]: UNREACHABLE! Listing localhost explicitly in the inventory overrides Ansible's implicit local connection, so it fell back to ssh. The zuul-debian pod runs no sshd, so set ansible_connection: local. --- roles/deploy_cloudmon_k8s/templates/inventory.j2 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/roles/deploy_cloudmon_k8s/templates/inventory.j2 b/roles/deploy_cloudmon_k8s/templates/inventory.j2 index ef24aa5..61f62d4 100644 --- a/roles/deploy_cloudmon_k8s/templates/inventory.j2 +++ b/roles/deploy_cloudmon_k8s/templates/inventory.j2 @@ -5,6 +5,9 @@ all: # "localhost" from the pod's point of view. localhost: ansible_host: localhost + # Defining localhost explicitly loses Ansible's implicit local + # connection, and the pod runs no sshd, so this must be set. + ansible_connection: local internal_address: localhost children: # A group's `hosts` must be a mapping, not a list -- a list makes Ansible From 4c19b4020592b918bedbe8d78ae405cd52164854 Mon Sep 17 00:00:00 2001 From: "l.cuper@t-systems.com" Date: Thu, 20 Aug 2026 22:21:36 +0200 Subject: [PATCH 6/9] Allow skipping host firewall management Graphite provisioning failed in the pod-based job with: Could not find the requested service firewalld: host The firewalld role is pulled in unconditionally by seven install playbooks and manages host services. A container has no service manager and no host firewall, so those tasks cannot succeed. 'Disable iptables' already had ignore_errors; 'Enable firewalld' did not, so it aborted the play. Gate the role body behind cloudmon_manage_firewall, defaulting to true so VM-based deployments are unchanged, and set it false in the k8s job inventory. --- .../project/roles/firewalld/tasks/main.yaml | 71 ++----------------- .../project/roles/firewalld/tasks/manage.yaml | 64 +++++++++++++++++ .../templates/inventory.j2 | 4 ++ 3 files changed, 75 insertions(+), 64 deletions(-) create mode 100644 cloudmon/ansible/project/roles/firewalld/tasks/manage.yaml diff --git a/cloudmon/ansible/project/roles/firewalld/tasks/main.yaml b/cloudmon/ansible/project/roles/firewalld/tasks/main.yaml index b6e6d0f..a5caca4 100644 --- a/cloudmon/ansible/project/roles/firewalld/tasks/main.yaml +++ b/cloudmon/ansible/project/roles/firewalld/tasks/main.yaml @@ -1,64 +1,7 @@ -- name: Include OS-specific variables - include_vars: "{{ lookup('first_found', params) }}" - vars: - params: - files: "{{ distro_lookup_path }}" - paths: - - 'vars' - -- name: Install firewalld - ansible.builtin.package: - name: "{{ item }}" - state: "present" - loop: - - "{{ packages }}" - when: "ansible_facts.pkg_mgr != 'atomic_container'" - -- name: Enable services - ansible.posix.firewalld: - permanent: "yes" - service: "{{ item }}" - state: "enabled" - loop: "{{ firewalld_services_enable }}" - notify: - - Reload firewalld - -- name: Disable services - ansible.posix.firewalld: - permanent: "yes" - service: "{{ item }}" - state: "disabled" - loop: "{{ firewalld_services_disable }}" - notify: - - Reload firewalld - -- name: Enable ports - ansible.posix.firewalld: - permanent: "yes" - port: "{{ item }}" - state: "enabled" - loop: "{{ firewalld_ports_enable }}" - notify: - - Reload firewalld - -- name: Disable ports - ansible.posix.firewalld: - permanent: "yes" - port: "{{ item }}" - state: "disabled" - loop: "{{ firewalld_ports_disable }}" - notify: - - Reload firewalld - -- name: Disable iptables - ansible.builtin.service: - name: "iptables" - state: "stopped" - enabled: "false" - ignore_errors: "true" - -- name: Enable firewalld - ansible.builtin.service: - name: "firewalld" - state: "started" - enabled: "true" +--- +# Host firewall management is meaningless in a container (no service manager, +# no host firewall), so allow targets to opt out. Defaults to true, so +# existing VM-based deployments are unaffected. +- name: Manage host firewall + ansible.builtin.include_tasks: manage.yaml + when: cloudmon_manage_firewall | default(true) | bool diff --git a/cloudmon/ansible/project/roles/firewalld/tasks/manage.yaml b/cloudmon/ansible/project/roles/firewalld/tasks/manage.yaml new file mode 100644 index 0000000..b6e6d0f --- /dev/null +++ b/cloudmon/ansible/project/roles/firewalld/tasks/manage.yaml @@ -0,0 +1,64 @@ +- name: Include OS-specific variables + include_vars: "{{ lookup('first_found', params) }}" + vars: + params: + files: "{{ distro_lookup_path }}" + paths: + - 'vars' + +- name: Install firewalld + ansible.builtin.package: + name: "{{ item }}" + state: "present" + loop: + - "{{ packages }}" + when: "ansible_facts.pkg_mgr != 'atomic_container'" + +- name: Enable services + ansible.posix.firewalld: + permanent: "yes" + service: "{{ item }}" + state: "enabled" + loop: "{{ firewalld_services_enable }}" + notify: + - Reload firewalld + +- name: Disable services + ansible.posix.firewalld: + permanent: "yes" + service: "{{ item }}" + state: "disabled" + loop: "{{ firewalld_services_disable }}" + notify: + - Reload firewalld + +- name: Enable ports + ansible.posix.firewalld: + permanent: "yes" + port: "{{ item }}" + state: "enabled" + loop: "{{ firewalld_ports_enable }}" + notify: + - Reload firewalld + +- name: Disable ports + ansible.posix.firewalld: + permanent: "yes" + port: "{{ item }}" + state: "disabled" + loop: "{{ firewalld_ports_disable }}" + notify: + - Reload firewalld + +- name: Disable iptables + ansible.builtin.service: + name: "iptables" + state: "stopped" + enabled: "false" + ignore_errors: "true" + +- name: Enable firewalld + ansible.builtin.service: + name: "firewalld" + state: "started" + enabled: "true" diff --git a/roles/deploy_cloudmon_k8s/templates/inventory.j2 b/roles/deploy_cloudmon_k8s/templates/inventory.j2 index 61f62d4..99387a7 100644 --- a/roles/deploy_cloudmon_k8s/templates/inventory.j2 +++ b/roles/deploy_cloudmon_k8s/templates/inventory.j2 @@ -9,6 +9,10 @@ all: # connection, and the pod runs no sshd, so this must be set. ansible_connection: local internal_address: localhost + vars: + # The pod has no service manager and no host firewall, so firewalld and + # iptables service management cannot work here. + cloudmon_manage_firewall: false children: # A group's `hosts` must be a mapping, not a list -- a list makes Ansible # reject the whole inventory ("requires a dictionary"), after which every From 83b3bd6a4e49cc7604c6104b7622474fff3cd4f9 Mon Sep 17 00:00:00 2001 From: "l.cuper@t-systems.com" Date: Thu, 20 Aug 2026 22:27:13 +0200 Subject: [PATCH 7/9] Use the block keyword instead of ansible.builtin.block Provisioning aborted with: unexpected parameter type in action: Origin: roles/graphite/tasks/main.yaml:38:3 'block' is a task keyword, not a module -- there is no ansible.builtin.block action, so ansible-core treats it as a module receiving a list. Fixes all 22 occurrences across 11 roles, introduced in 685afcf. --- cloudmon/ansible/project/roles/apimon_executor/tasks/main.yml | 4 ++-- .../ansible/project/roles/apimon_scheduler/tasks/main.yml | 4 ++-- cloudmon/ansible/project/roles/carbonapi/tasks/main.yaml | 4 ++-- cloudmon/ansible/project/roles/epmon/tasks/main.yml | 4 ++-- cloudmon/ansible/project/roles/etcd/tasks/main.yaml | 4 ++-- cloudmon/ansible/project/roles/globalmon/tasks/main.yml | 4 ++-- cloudmon/ansible/project/roles/grafana/tasks/main.yml | 4 ++-- cloudmon/ansible/project/roles/graphite/tasks/main.yaml | 4 ++-- cloudmon/ansible/project/roles/postgresql/tasks/main.yaml | 4 ++-- cloudmon/ansible/project/roles/postgresql_ha/tasks/main.yaml | 4 ++-- cloudmon/ansible/project/roles/statsd/tasks/main.yaml | 4 ++-- 11 files changed, 22 insertions(+), 22 deletions(-) diff --git a/cloudmon/ansible/project/roles/apimon_executor/tasks/main.yml b/cloudmon/ansible/project/roles/apimon_executor/tasks/main.yml index be8ef36..736c573 100644 --- a/cloudmon/ansible/project/roles/apimon_executor/tasks/main.yml +++ b/cloudmon/ansible/project/roles/apimon_executor/tasks/main.yml @@ -36,7 +36,7 @@ retries: 5 - name: Clean up stale sockets after package changes - ansible.builtin.block: + block: - name: Stop Docker service and socket ansible.builtin.systemd: name: "{{ item }}" @@ -59,7 +59,7 @@ - ansible_facts.distribution_major_version == '22' - name: Clear systemd rate-limits and prepare containerd - ansible.builtin.block: + block: - name: Reset systemd failed state for Docker units ansible.builtin.systemd: name: "{{ item }}" diff --git a/cloudmon/ansible/project/roles/apimon_scheduler/tasks/main.yml b/cloudmon/ansible/project/roles/apimon_scheduler/tasks/main.yml index d5f73ca..8a68a6b 100644 --- a/cloudmon/ansible/project/roles/apimon_scheduler/tasks/main.yml +++ b/cloudmon/ansible/project/roles/apimon_scheduler/tasks/main.yml @@ -38,7 +38,7 @@ retries: 5 - name: Clean up stale sockets after package changes - ansible.builtin.block: + block: - name: Stop Docker service and socket ansible.builtin.systemd: name: "{{ item }}" @@ -61,7 +61,7 @@ - ansible_facts.distribution_major_version == '22' - name: Clear systemd rate-limits and prepare containerd - ansible.builtin.block: + block: - name: Reset systemd failed state for Docker units ansible.builtin.systemd: name: "{{ item }}" diff --git a/cloudmon/ansible/project/roles/carbonapi/tasks/main.yaml b/cloudmon/ansible/project/roles/carbonapi/tasks/main.yaml index 89e2cb6..23e4109 100644 --- a/cloudmon/ansible/project/roles/carbonapi/tasks/main.yaml +++ b/cloudmon/ansible/project/roles/carbonapi/tasks/main.yaml @@ -36,7 +36,7 @@ retries: 5 - name: Clean up stale sockets after package changes - ansible.builtin.block: + block: - name: Stop Docker service and socket ansible.builtin.systemd: name: "{{ item }}" @@ -59,7 +59,7 @@ - ansible_facts.distribution_major_version == '22' - name: Clear systemd rate-limits and prepare containerd - ansible.builtin.block: + block: - name: Reset systemd failed state for Docker units ansible.builtin.systemd: name: "{{ item }}" diff --git a/cloudmon/ansible/project/roles/epmon/tasks/main.yml b/cloudmon/ansible/project/roles/epmon/tasks/main.yml index ba9b0fe..4139183 100644 --- a/cloudmon/ansible/project/roles/epmon/tasks/main.yml +++ b/cloudmon/ansible/project/roles/epmon/tasks/main.yml @@ -37,7 +37,7 @@ retries: 5 - name: Clean up stale sockets after package changes - ansible.builtin.block: + block: - name: Stop Docker service and socket ansible.builtin.systemd: name: "{{ item }}" @@ -60,7 +60,7 @@ - ansible_facts.distribution_major_version == '22' - name: Clear systemd rate-limits and prepare containerd - ansible.builtin.block: + block: - name: Reset systemd failed state for Docker units ansible.builtin.systemd: name: "{{ item }}" diff --git a/cloudmon/ansible/project/roles/etcd/tasks/main.yaml b/cloudmon/ansible/project/roles/etcd/tasks/main.yaml index 8c46752..e80dc63 100644 --- a/cloudmon/ansible/project/roles/etcd/tasks/main.yaml +++ b/cloudmon/ansible/project/roles/etcd/tasks/main.yaml @@ -36,7 +36,7 @@ retries: 5 - name: Clean up stale sockets after package changes - ansible.builtin.block: + block: - name: Stop Docker service and socket ansible.builtin.systemd: name: "{{ item }}" @@ -59,7 +59,7 @@ - ansible_facts.distribution_major_version == '22' - name: Clear systemd rate-limits and prepare containerd - ansible.builtin.block: + block: - name: Reset systemd failed state for Docker units ansible.builtin.systemd: name: "{{ item }}" diff --git a/cloudmon/ansible/project/roles/globalmon/tasks/main.yml b/cloudmon/ansible/project/roles/globalmon/tasks/main.yml index 3061cc8..0a95f0f 100644 --- a/cloudmon/ansible/project/roles/globalmon/tasks/main.yml +++ b/cloudmon/ansible/project/roles/globalmon/tasks/main.yml @@ -42,7 +42,7 @@ retries: 5 - name: Clean up stale sockets after package changes - ansible.builtin.block: + block: - name: Stop Docker service and socket ansible.builtin.systemd: name: "{{ item }}" @@ -65,7 +65,7 @@ - ansible_facts.distribution_major_version == '22' - name: Clear systemd rate-limits and prepare containerd - ansible.builtin.block: + block: - name: Reset systemd failed state for Docker units ansible.builtin.systemd: name: "{{ item }}" diff --git a/cloudmon/ansible/project/roles/grafana/tasks/main.yml b/cloudmon/ansible/project/roles/grafana/tasks/main.yml index 6ce8ccc..de46ba2 100644 --- a/cloudmon/ansible/project/roles/grafana/tasks/main.yml +++ b/cloudmon/ansible/project/roles/grafana/tasks/main.yml @@ -36,7 +36,7 @@ retries: 5 - name: Clean up stale sockets after package changes - ansible.builtin.block: + block: - name: Stop Docker service and socket ansible.builtin.systemd: name: "{{ item }}" @@ -59,7 +59,7 @@ - ansible_facts.distribution_major_version == '22' - name: Clear systemd rate-limits and prepare containerd - ansible.builtin.block: + block: - name: Reset systemd failed state for Docker units ansible.builtin.systemd: name: "{{ item }}" diff --git a/cloudmon/ansible/project/roles/graphite/tasks/main.yaml b/cloudmon/ansible/project/roles/graphite/tasks/main.yaml index 2011deb..2454b18 100644 --- a/cloudmon/ansible/project/roles/graphite/tasks/main.yaml +++ b/cloudmon/ansible/project/roles/graphite/tasks/main.yaml @@ -36,7 +36,7 @@ retries: 5 - name: Clean up stale sockets after package changes - ansible.builtin.block: + block: - name: Stop Docker service and socket ansible.builtin.systemd: name: "{{ item }}" @@ -59,7 +59,7 @@ - ansible_facts.distribution_major_version == '22' - name: Clear systemd rate-limits and prepare containerd - ansible.builtin.block: + block: - name: Reset systemd failed state for Docker units ansible.builtin.systemd: name: "{{ item }}" diff --git a/cloudmon/ansible/project/roles/postgresql/tasks/main.yaml b/cloudmon/ansible/project/roles/postgresql/tasks/main.yaml index 29eaa2c..c8c5325 100644 --- a/cloudmon/ansible/project/roles/postgresql/tasks/main.yaml +++ b/cloudmon/ansible/project/roles/postgresql/tasks/main.yaml @@ -36,7 +36,7 @@ retries: 5 - name: Clean up stale sockets after package changes - ansible.builtin.block: + block: - name: Stop Docker service and socket ansible.builtin.systemd: name: "{{ item }}" @@ -59,7 +59,7 @@ - ansible_facts.distribution_major_version == '22' - name: Clear systemd rate-limits and prepare containerd - ansible.builtin.block: + block: - name: Reset systemd failed state for Docker units ansible.builtin.systemd: name: "{{ item }}" diff --git a/cloudmon/ansible/project/roles/postgresql_ha/tasks/main.yaml b/cloudmon/ansible/project/roles/postgresql_ha/tasks/main.yaml index 9e3f853..273e005 100644 --- a/cloudmon/ansible/project/roles/postgresql_ha/tasks/main.yaml +++ b/cloudmon/ansible/project/roles/postgresql_ha/tasks/main.yaml @@ -36,7 +36,7 @@ retries: 5 - name: Clean up stale sockets after package changes - ansible.builtin.block: + block: - name: Stop Docker service and socket ansible.builtin.systemd: name: "{{ item }}" @@ -59,7 +59,7 @@ - ansible_facts.distribution_major_version == '22' - name: Clear systemd rate-limits and prepare containerd - ansible.builtin.block: + block: - name: Reset systemd failed state for Docker units ansible.builtin.systemd: name: "{{ item }}" diff --git a/cloudmon/ansible/project/roles/statsd/tasks/main.yaml b/cloudmon/ansible/project/roles/statsd/tasks/main.yaml index fee2ae1..4b3e894 100644 --- a/cloudmon/ansible/project/roles/statsd/tasks/main.yaml +++ b/cloudmon/ansible/project/roles/statsd/tasks/main.yaml @@ -36,7 +36,7 @@ when: "ansible_facts.pkg_mgr != 'atomic_container'" - name: Clean up stale sockets after package changes - ansible.builtin.block: + block: - name: Stop Docker service and socket ansible.builtin.systemd: name: "{{ item }}" @@ -59,7 +59,7 @@ - ansible_facts.distribution_major_version == '22' - name: Clear systemd rate-limits and prepare containerd - ansible.builtin.block: + block: - name: Reset systemd failed state for Docker units ansible.builtin.systemd: name: "{{ item }}" From b039d045b5da0299c661238f01d998b6786b7370 Mon Sep 17 00:00:00 2001 From: "l.cuper@t-systems.com" Date: Thu, 20 Aug 2026 22:33:16 +0200 Subject: [PATCH 8/9] Use netcat-openbsd on Debian Package installation failed on the Debian bookworm node: E: Package 'netcat' has no installation candidate Package netcat is a virtual package provided by: netcat-openbsd 1.219-1 netcat-traditional 1.10-47 'netcat' is virtual on bookworm and cannot be installed directly. Use netcat-openbsd, which provides nc, in the graphite, statsd and carbonapi Debian vars. --- cloudmon/ansible/project/roles/carbonapi/vars/Debian.yaml | 2 +- cloudmon/ansible/project/roles/graphite/vars/Debian.yaml | 2 +- cloudmon/ansible/project/roles/statsd/vars/Debian.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cloudmon/ansible/project/roles/carbonapi/vars/Debian.yaml b/cloudmon/ansible/project/roles/carbonapi/vars/Debian.yaml index 1505647..69b51f0 100644 --- a/cloudmon/ansible/project/roles/carbonapi/vars/Debian.yaml +++ b/cloudmon/ansible/project/roles/carbonapi/vars/Debian.yaml @@ -6,7 +6,7 @@ remove_packages: [] packages: - - netcat + - netcat-openbsd - policycoreutils-python-utils - python3-selinux diff --git a/cloudmon/ansible/project/roles/graphite/vars/Debian.yaml b/cloudmon/ansible/project/roles/graphite/vars/Debian.yaml index 001aa59..3d95ca0 100644 --- a/cloudmon/ansible/project/roles/graphite/vars/Debian.yaml +++ b/cloudmon/ansible/project/roles/graphite/vars/Debian.yaml @@ -6,6 +6,6 @@ remove_packages: [] packages: - - netcat + - netcat-openbsd container_command: docker diff --git a/cloudmon/ansible/project/roles/statsd/vars/Debian.yaml b/cloudmon/ansible/project/roles/statsd/vars/Debian.yaml index fdaaeea..112be38 100644 --- a/cloudmon/ansible/project/roles/statsd/vars/Debian.yaml +++ b/cloudmon/ansible/project/roles/statsd/vars/Debian.yaml @@ -6,7 +6,7 @@ remove_packages: [] distro_packages: - - netcat + - netcat-openbsd - cron - apparmor-profiles From e5c528f55f1631440d8202c9830113fd14a51e02 Mon Sep 17 00:00:00 2001 From: "l.cuper@t-systems.com" Date: Thu, 20 Aug 2026 22:40:52 +0200 Subject: [PATCH 9/9] Gate per-role firewalld tasks too Graphite provisioning still failed after gating the firewalld role: TASK [graphite : Allow graphite port] Failed to import the required Python library (firewall) Origin: roles/graphite/tasks/firewall.yml:4:3 Six roles include their own firewall.yml to open ports via ansible.posix .firewalld, which needs the firewall python library and a running firewalld. Neither exists in a container, so gate these includes behind the same cloudmon_manage_firewall variable. --- cloudmon/ansible/project/roles/apimon_scheduler/tasks/main.yml | 1 + cloudmon/ansible/project/roles/etcd/tasks/main.yaml | 1 + cloudmon/ansible/project/roles/grafana/tasks/main.yml | 1 + cloudmon/ansible/project/roles/graphite/tasks/main.yaml | 1 + cloudmon/ansible/project/roles/postgresql/tasks/main.yaml | 1 + cloudmon/ansible/project/roles/postgresql_ha/tasks/main.yaml | 1 + 6 files changed, 6 insertions(+) diff --git a/cloudmon/ansible/project/roles/apimon_scheduler/tasks/main.yml b/cloudmon/ansible/project/roles/apimon_scheduler/tasks/main.yml index 8a68a6b..1c1744f 100644 --- a/cloudmon/ansible/project/roles/apimon_scheduler/tasks/main.yml +++ b/cloudmon/ansible/project/roles/apimon_scheduler/tasks/main.yml @@ -93,6 +93,7 @@ - ansible_facts.distribution_major_version == '22' - include_tasks: firewall.yml + when: cloudmon_manage_firewall | default(true) | bool - name: Create scheduler group become: yes diff --git a/cloudmon/ansible/project/roles/etcd/tasks/main.yaml b/cloudmon/ansible/project/roles/etcd/tasks/main.yaml index e80dc63..076d958 100644 --- a/cloudmon/ansible/project/roles/etcd/tasks/main.yaml +++ b/cloudmon/ansible/project/roles/etcd/tasks/main.yaml @@ -96,6 +96,7 @@ loop: "{{ play_hosts }}" - ansible.builtin.include_tasks: firewall.yml + when: cloudmon_manage_firewall | default(true) | bool - name: Ensure directories exist become: true diff --git a/cloudmon/ansible/project/roles/grafana/tasks/main.yml b/cloudmon/ansible/project/roles/grafana/tasks/main.yml index de46ba2..24cf8e8 100644 --- a/cloudmon/ansible/project/roles/grafana/tasks/main.yml +++ b/cloudmon/ansible/project/roles/grafana/tasks/main.yml @@ -91,6 +91,7 @@ - ansible_facts.distribution_major_version == '22' - include_tasks: firewall.yml + when: cloudmon_manage_firewall | default(true) | bool - name: Create Grafana group ansible.builtin.group: diff --git a/cloudmon/ansible/project/roles/graphite/tasks/main.yaml b/cloudmon/ansible/project/roles/graphite/tasks/main.yaml index 2454b18..11a44ea 100644 --- a/cloudmon/ansible/project/roles/graphite/tasks/main.yaml +++ b/cloudmon/ansible/project/roles/graphite/tasks/main.yaml @@ -91,6 +91,7 @@ - ansible_facts.distribution_major_version == '22' - include_tasks: firewall.yml + when: cloudmon_manage_firewall | default(true) | bool - name: Create graphite sync group become: yes diff --git a/cloudmon/ansible/project/roles/postgresql/tasks/main.yaml b/cloudmon/ansible/project/roles/postgresql/tasks/main.yaml index c8c5325..ac12375 100644 --- a/cloudmon/ansible/project/roles/postgresql/tasks/main.yaml +++ b/cloudmon/ansible/project/roles/postgresql/tasks/main.yaml @@ -91,6 +91,7 @@ - ansible_facts.distribution_major_version == '22' - include_tasks: firewall.yml + when: cloudmon_manage_firewall | default(true) | bool - name: Write Postgres Systemd unit file become: true diff --git a/cloudmon/ansible/project/roles/postgresql_ha/tasks/main.yaml b/cloudmon/ansible/project/roles/postgresql_ha/tasks/main.yaml index 273e005..3477d19 100644 --- a/cloudmon/ansible/project/roles/postgresql_ha/tasks/main.yaml +++ b/cloudmon/ansible/project/roles/postgresql_ha/tasks/main.yaml @@ -102,6 +102,7 @@ when: "item != inventory_hostname" - ansible.builtin.include_tasks: firewall.yml + when: cloudmon_manage_firewall | default(true) | bool - name: Create postgres group become: yes