From e986f25b2d61759e92979a7d79d49097f5485e37 Mon Sep 17 00:00:00 2001 From: pavel Date: Wed, 26 Nov 2025 16:39:01 +0200 Subject: [PATCH] 1639 --- files/ansible-playbooks/update-indoor3.yml | 88 ++++++++++++++++++++-- 1 file changed, 83 insertions(+), 5 deletions(-) diff --git a/files/ansible-playbooks/update-indoor3.yml b/files/ansible-playbooks/update-indoor3.yml index 5f453fc..22704bd 100644 --- a/files/ansible-playbooks/update-indoor3.yml +++ b/files/ansible-playbooks/update-indoor3.yml @@ -29,7 +29,7 @@ ssh_opts_common: "-o PreferredAuthentications=password -o PubkeyAuthentication=no -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o NumberOfPasswordPrompts=1 -o ConnectTimeout=30" # Image to stage on DEV2 (we validate first; the actual write happens later) - image_filename: "fox200-2.2.1-r6801.bin" + image_filename: "2.2.1-r6801.bin" image_md5: "56b7211709de617e058b98d4204e2562" # Optional SHA256; leave empty to skip SHA256 checks image_sha256: "" @@ -173,6 +173,57 @@ - "dev2_conn_method={{ dev2_conn_method }}" - "lldp_dev2_ip={{ lldp_dev2_ip | default('') }}" + # ------ LLDP IPv6 discovery for tunnel mode (Dev1 → Dev2 link-local) ------ + - name: Discover DEV2 candidate IPv6 via LLDP on DEV1 (best-effort) + when: dev2_conn_method == "tunnel" + ansible.builtin.raw: > + {{ pathprefix }} + DIGITS="{{ dev2_lldp_digits }}"; + cat /var/run/lldp_server.json 2>/dev/null \ + | grep "${DIGITS}" -A 15 \ + | grep 'address_ipv6' \ + | awk -F'"' '{ print $4 }' \ + | head -n1 + register: dev2_lldp_ip6_raw + changed_when: false + failed_when: false + + - name: Capture LLDP-derived DEV2 IPv6 (if any) + when: dev2_conn_method == "tunnel" + ansible.builtin.set_fact: + lldp_dev2_ip6: "{{ (dev2_lldp_ip6_raw.stdout | default('')) | trim }}" + changed_when: false + + - name: Debug LLDP IPv6 candidate for DEV2 (new debug) + when: dev2_conn_method == "tunnel" and debugging | bool + delegate_to: localhost + ansible.builtin.debug: + msg: + - "LLDP candidate IPv6={{ lldp_dev2_ip6 | default('') }}" + + # Build the remote tunnel target: prefer LLDP IPv6 if present, else 192.168.1.1 + - name: Build tunnel remote target for DEV2 (prefer LLDP IPv6 when available) + when: dev2_conn_method == "tunnel" + delegate_to: localhost + ansible.builtin.set_fact: + dev2_tunnel_target: >- + {{ + (lldp_dev2_ip6 is defined and (lldp_dev2_ip6 | string | trim | length > 0)) + | ternary( + '[' ~ (lldp_dev2_ip6 | string | trim) ~ '%' ~ (dev1_iface | string | trim) ~ ']:' ~ (dev2_port | string), + (dev2_host | string) ~ ':' ~ (dev2_port | string) + ) + }} + changed_when: false + + - name: Debug tunnel remote target for DEV2 (IPv4/IPv6) + when: dev2_conn_method == "tunnel" and debugging | bool + delegate_to: localhost + ansible.builtin.debug: + msg: + - "dev2_tunnel_target={{ dev2_tunnel_target | default(dev2_host ~ ':' ~ dev2_port) }}" + + # Direct LLDP 10.x login (no tunnel, reusing two-step auth style) - name: Try DEV2 login via direct LLDP IP with 'basicpass' (10.x) when: dev2_conn_method == "direct_lldp" @@ -408,7 +459,7 @@ HOST="{{ ansible_host | default(inventory_hostname) }}" sshpass -p '{{ dev1_pass }}' ssh -f -N {{ ssh_opts_common }} \ -M -S "{{ _ctrl_sock }}" \ - -L "127.0.0.1:{{ _local_port }}:{{ dev2_host }}:{{ dev2_port }}" \ + -L "127.0.0.1:{{ _local_port }}:{{ dev2_tunnel_target | default(dev2_host ~ ':' ~ dev2_port) }}" \ "${USER}@${HOST}" args: executable: /bin/bash @@ -812,6 +863,33 @@ _blocked: true _journal: "{{ _journal + [ 'Preparation markers already present on DEV2 (count=' ~ (dev2_prep_count.stdout | trim) ~ '). Skipping staging/write' ] }}" + - name: Check bootenv-updated marker on DEV2 (/tmp/bootenv_updated) + when: dev2_passfile_used != "NONE" + delegate_to: localhost + ansible.builtin.shell: | + set -e + HOST="{{ dev2_ssh_host }}" + PORT="{{ dev2_ssh_port }}" + sshpass -f "{{ dev2_passfile_used }}" ssh \ + -o StrictHostKeyChecking=no -o PubkeyAuthentication=no \ + -o PreferredAuthentications=password -o NumberOfPasswordPrompts=1 \ + -o ConnectTimeout=10 \ + -p "$PORT" "{{ dev2_ssh_user }}@${HOST}" \ + "[ -f '/tmp/bootenv_updated' ] && echo PRESENT || echo ABSENT" + args: + executable: /bin/bash + register: dev2_bootenv_marker + changed_when: false + ignore_errors: true + + - name: Soft-block if bootenv-updated marker is present on DEV2 + when: dev2_bootenv_marker is defined + and (dev2_bootenv_marker.stdout | default('') | trim) == 'PRESENT' + ansible.builtin.set_fact: + _prep_blocked: true + _blocked: true + _journal: "{{ _journal + [ 'Bootenv updated marker present on DEV2 (/tmp/bootenv_updated). Skipping image staging/write' ] }}" + - name: Refresh ARP 1 on DEV1’s LAN (send unsolicited ARP from temporary IP) when: dev2_conn_method == "tunnel" ansible.builtin.raw: arping -U -I eth0 192.168.1.11 -c 3 @@ -1165,16 +1243,16 @@ HOST="{{ dev2_ssh_host }}" PORT="{{ dev2_ssh_port }}" sshpass -f "{{ dev2_passfile_used }}" scp \ - -O \ -P "$PORT" \ + -O \ -o StrictHostKeyChecking=no -o PubkeyAuthentication=no \ - "{{ image_filename }}" "{{ dev2_ssh_user }}@${HOST}:{{ dev2_ssh_user == 'root' | ternary('/', '') }}{{ dev2_image_dir }}/{{ image_filename }}" + "{{ image_filename }}" "{{ dev2_ssh_user }}@${HOST}:{{ (dev2_ssh_user == 'root') | ternary('/', '') }}{{ dev2_image_dir }}/{{ image_filename }}" + args: executable: /bin/bash register: scp_push changed_when: true - - name: Compute md5 of image on DEV2 after copy (or if already present) when: local_img.stat.exists and dev2_passfile_used != "NONE" and not (_blocked | default(false)) delegate_to: localhost