diff --git a/roles/proxmox_upgrade/tasks/preflight.yml b/roles/proxmox_upgrade/tasks/preflight.yml index b81a828..ec126af 100644 --- a/roles/proxmox_upgrade/tasks/preflight.yml +++ b/roles/proxmox_upgrade/tasks/preflight.yml @@ -2,7 +2,7 @@ # ============================================================================= # proxmox_upgrade — preflight.yml # Check cluster health before starting any upgrade work -# All tasks delegate_to: localhost — uses API only +# All API checks done in single tasks on localhost to avoid variable scope issues # ============================================================================= - name: Preflight | Check quorum via pvecm @@ -12,24 +12,39 @@ changed_when: false failed_when: quorum_check.rc != 0 -- name: Preflight | Get cluster node status via API - ansible.builtin.uri: - url: "https://{{ api_host }}:{{ api_port }}/api2/json/nodes" - method: GET - headers: - Authorization: "PVEAPIToken={{ api_token_id }}={{ api_token_secret }}" - validate_certs: false - register: cluster_nodes +- name: Preflight | Check all cluster nodes online via API + ansible.builtin.shell: | + python3 << 'PYEOF' + import urllib.request, urllib.error, json, ssl + + ctx = ssl.create_default_context() + ctx.check_hostname = False + ctx.verify_mode = ssl.CERT_NONE + + req = urllib.request.Request( + "https://{{ api_host }}:{{ api_port }}/api2/json/nodes", + headers={"Authorization": "PVEAPIToken={{ api_token_id }}={{ api_token_secret }}"} + ) + with urllib.request.urlopen(req, context=ctx) as r: + data = json.loads(r.read())["data"] + + offline = [n for n in data if n["status"] != "online"] + if offline: + print("FAIL: " + ", ".join(f"{n['node']}={n['status']}" for n in offline)) + exit(1) + else: + print("OK: " + ", ".join(f"{n['node']}={n['status']}" for n in data)) + exit(0) + PYEOF + register: node_check + changed_when: false + failed_when: node_check.rc != 0 delegate_to: localhost run_once: true -- name: Preflight | Check all nodes are online - ansible.builtin.fail: - msg: > - Cluster health check FAILED — node {{ item.node }} is {{ item.status }}. - Aborting upgrade to prevent data loss. Investigate before retrying. - loop: "{{ cluster_nodes.json.data }}" - when: item.status != 'online' +- name: Preflight | Log node status + ansible.builtin.debug: + msg: "{{ node_check.stdout }}" delegate_to: localhost run_once: true @@ -55,7 +70,7 @@ - name: Preflight | Cluster health check passed ansible.builtin.debug: - msg: "Cluster health check passed — all {{ cluster_nodes.json.data | length }} nodes online, quorum OK{{ ', CEPH checked' if ceph_enabled else '' }}" + msg: "Cluster health check passed — all nodes online, quorum OK{{ ', CEPH checked' if ceph_enabled else '' }}" delegate_to: localhost run_once: true