diff --git a/files/ansible-playbooks/update-indoor.yml b/files/ansible-playbooks/update-indoor.yml index 88e0afa..7ef9b00 100644 --- a/files/ansible-playbooks/update-indoor.yml +++ b/files/ansible-playbooks/update-indoor.yml @@ -642,56 +642,96 @@ ansible.builtin.debug: msg: "DEV2 firmux={{ (dev2_firmux.stdout | default('')) | trim }}" - - - - # ===== NEW: derive expected & current firmware cores and block if equal (unless force-upgrade) ===== - - name: Derive expected target_version core (early, from image filename) + # ===================== Early equality/substring check (same logic as checker) ===================== + # 1) expected_norm from image_filename (prefer extracted X.Y.Z-rNNNN) + - name: Normalize expected target step one compute base string (from image_filename) delegate_to: localhost ansible.builtin.set_fact: - expected_fw_core_early: "{{ (image_filename | regex_search('[0-9]+\\.[0-9]+\\.[0-9]+-r[0-9]+')) | default('', true) }}" + expected_norm_step1: "{{ (image_filename | default('') | trim) }}" + changed_when: false - - name: Parse current firmware core from DEV2 firmux (early, '-rNNNN' form) - when: dev2_firmux is defined + - name: Extract version core X dot Y dot Z dash rNNNN from image_filename if present delegate_to: localhost ansible.builtin.set_fact: - current_fw_core_dash: "{{ (dev2_firmux.stdout | default('') | regex_search('[0-9]+\\.[0-9]+\\.[0-9]+-r[0-9]+')) | default('', true) }}" + expected_norm_core_list: "{{ (image_filename | default('') | regex_findall('[0-9]+\\.[0-9]+\\.[0-9]+-r[0-9]+')) | default([]) }}" + changed_when: false - - name: Parse current firmware core from DEV2 firmux (alt 'X.Y.Z rev NNNN' → 'X.Y.Z-rNNNN') - when: dev2_firmux is defined and (current_fw_core_dash | length) == 0 + - name: Choose first extracted core if available delegate_to: localhost ansible.builtin.set_fact: - current_fw_core_rev_parts: "{{ (dev2_firmux.stdout | default('') | regex_search('([0-9]+\\.[0-9]+\\.[0-9]+)\\s+rev\\s+([0-9]+)')) | default('', true) }}" + expected_norm_core: "{{ (expected_norm_core_list | default([]) | length > 0) | ternary((expected_norm_core_list | first), '') }}" + changed_when: false - - name: Normalize current firmware core (prefer '-r' form; else build from 'rev') + - name: Normalize expected target step two prefer extracted core when available delegate_to: localhost ansible.builtin.set_fact: - current_fw_core: >- - {% if (current_fw_core_dash | default('') | length) > 0 -%} - {{ current_fw_core_dash }} - {%- elif (current_fw_core_rev_parts | default('') | length) > 0 -%} - {{ (dev2_firmux.stdout | regex_replace('.*([0-9]+\\.[0-9]+\\.[0-9]+)\\s+rev\\s+([0-9]+).*','\\1-r\\2')) }} - {%- else -%} - {{ '' }} - {%- endif %} + expected_norm: "{{ (expected_norm_core | default('') | length > 0) | ternary(expected_norm_core, expected_norm_step1) }}" + changed_when: false - - name: Debug version comparison (current vs expected; force-override) + # 2) banner_raw + banner_norm (convert "rev NNNN" → "-rNNNN" only if needed) + - name: Capture firmware banner line from DEV2 (raw) + delegate_to: localhost + ansible.builtin.set_fact: + banner_raw: "{{ (dev2_firmux.stdout | default('') | trim) }}" + changed_when: false + + - name: Normalize banner line to X dot Y dot Z dash rNNNN suffix + delegate_to: localhost + ansible.builtin.set_fact: + banner_norm: >- + {{ + ((banner_raw | lower) is search('-r[0-9]+$')) + | ternary( + banner_raw, + (banner_raw | regex_replace('\s*[Rr][Ee][Vv]\.?\s*([0-9]+)\s*$', '-r\1')) + ) + }} + changed_when: false + + # 3) evaluate (same equality OR substring, case-insensitive) + - name: Evaluate version match using normalized equality or substring + delegate_to: localhost + ansible.builtin.set_fact: + version_match: >- + {{ + (expected_norm | default('') | length > 0) + and ( + (banner_norm | default('')) == (expected_norm | default('')) + or ((banner_norm | default('') | lower) is search((expected_norm | default('') | lower))) + or ((expected_norm | default('') | lower) is search((banner_norm | default('') | lower))) + ) + }} + changed_when: false + + - name: Debug version compare snapshot (pre-write) delegate_to: localhost ansible.builtin.debug: msg: - - "expected_fw_core_early={{ expected_fw_core_early | default('') }}" - - "current_fw_core={{ current_fw_core | default('') }}" + - "expected_norm={{ expected_norm | default('') }}" + - "banner_raw={{ banner_raw | default('') }}" + - "banner_norm={{ banner_norm | default('') }}" - "force_upgrade={{ force_upgrade | default(false) }}" + - "version_match={{ version_match | default(false) }}" - - name: Soft-block if current firmware already matches target and not forced + # 4) soft-block when equal (unless forced) + back-fill legacy debug names + - name: Soft-block if already on target (skip staging/write unless force-upgrade) when: - not (force_upgrade | default(false)) - - (expected_fw_core_early | length) > 0 - - (current_fw_core | length) > 0 - - current_fw_core == expected_fw_core_early + - version_match | default(false) ansible.builtin.set_fact: _blocked: true - _journal: "{{ (_journal | default([])) + [ 'Device already running target image: ' ~ current_fw_core ~ ' — skipping write/flip (use force-upgrade=yes to override)' ] }}" + _journal: "{{ (_journal | default([])) + [ 'Device already running target image: ' ~ (banner_norm | default('')) ~ ' — skipping write/flip (use force-upgrade=yes to override)' ] }}" + expected_fw_core_early: "{{ expected_norm | default('') }}" + current_fw_core: "{{ banner_norm | default('') }}" + changed_when: false + + # If we are NOT blocked, still fill the legacy names so your later summary prints them + - name: Back-fill compare names for summary (no-op if already set) + when: not (_blocked | default(false)) + ansible.builtin.set_fact: + expected_fw_core_early: "{{ expected_fw_core_early | default(expected_norm | default('')) }}" + current_fw_core: "{{ current_fw_core | default(banner_norm | default('')) }}" + changed_when: false # ---------------------------- Normalize rebootin early (HOURS) ---------------------------- # Strict: rebootin is integer HOURS only. Always add +20s grace to the schedule.