1928
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
---
|
||||
# update-secondline.yml
|
||||
# update-indoor.yml (conservative, minimal fixes)
|
||||
- name: Second-line indoor upgrade via DEV1 → tunnel → DEV2 (non-invasive control path)
|
||||
hosts: all
|
||||
gather_facts: no
|
||||
@@ -50,7 +50,6 @@
|
||||
control_queue: "{{ lookup('env','CONTROLQUEUE') | default('queue_controls', true) }}"
|
||||
afterupgrade_routing_key: "{{ lookup('env','AFTERUP_ROUTING_KEY') | default('deviceconfig', true) }}"
|
||||
|
||||
|
||||
pre_tasks:
|
||||
# ------------------------------- Hostname sanity DEV1 -------------------------------
|
||||
- name: Read DEV1 hostname (busybox-safe)
|
||||
@@ -158,13 +157,31 @@
|
||||
echo "$p"; return 0
|
||||
fi
|
||||
fi
|
||||
done
|
||||
end
|
||||
return 1
|
||||
}
|
||||
pick
|
||||
register: pick_port
|
||||
changed_when: false
|
||||
|
||||
# (moved up) Stop immediately if no free local port was found
|
||||
- name: Stop if no free local port was found
|
||||
ansible.builtin.meta: end_host
|
||||
when: (pick_port.stdout | trim | length) == 0
|
||||
|
||||
# (moved up) Set chosen port and control socket path
|
||||
- name: Record chosen local port and create control dir for SSH ControlMaster
|
||||
delegate_to: localhost
|
||||
ansible.builtin.set_fact:
|
||||
_local_port: "{{ pick_port.stdout | trim }}"
|
||||
_ctrl_dir: "{{ lookup('ansible.builtin.pipe', 'mktemp -d') }}"
|
||||
|
||||
- name: Build path for SSH ControlMaster socket
|
||||
delegate_to: localhost
|
||||
ansible.builtin.set_fact:
|
||||
_ctrl_sock: "{{ _ctrl_dir }}/ssh_tunnel_ctl"
|
||||
|
||||
# (moved down) Now it’s safe to reference _local_port/_ctrl_sock
|
||||
- name: Debug picked local port (controller)
|
||||
delegate_to: localhost
|
||||
ansible.builtin.debug:
|
||||
@@ -191,30 +208,6 @@
|
||||
msg:
|
||||
- "listeners_before:\n{{ (port_listeners_before.stdout | default('')) | trim }}"
|
||||
|
||||
|
||||
- name: Stop if no free local port was found
|
||||
ansible.builtin.meta: end_host
|
||||
when: (pick_port.stdout | trim | length) == 0
|
||||
|
||||
- name: Record chosen local port and create control dir for SSH ControlMaster
|
||||
delegate_to: localhost
|
||||
ansible.builtin.set_fact:
|
||||
_local_port: "{{ pick_port.stdout | trim }}"
|
||||
_ctrl_dir: "{{ lookup('ansible.builtin.pipe', 'mktemp -d') }}"
|
||||
|
||||
- name: Build path for SSH ControlMaster socket
|
||||
delegate_to: localhost
|
||||
ansible.builtin.set_fact:
|
||||
_ctrl_sock: "{{ _ctrl_dir }}/ssh_tunnel_ctl"
|
||||
|
||||
- name: Debug tunnel parameters (controller side)
|
||||
delegate_to: localhost
|
||||
ansible.builtin.debug:
|
||||
msg:
|
||||
- "local_port={{ _local_port }}"
|
||||
- "ctrl_dir={{ _ctrl_dir }}"
|
||||
- "ctrl_sock={{ _ctrl_sock }}"
|
||||
|
||||
- name: Refresh ARP on DEV1’s LAN (send unsolicited ARP from temporary IP)
|
||||
ansible.builtin.raw: arping -U -I eth0 192.168.1.11 -c 3
|
||||
|
||||
@@ -251,8 +244,8 @@
|
||||
{ ss -ltnp 2>/dev/null || true; } | awk -v p=":${P}$" '$0 ~ p {print}'
|
||||
echo "== lsof LISTEN on :${P} =="
|
||||
{ lsof -nP -iTCP:"${P}" -sTCP:LISTEN 2>/dev/null || true; }
|
||||
echo "== grep ControlMaster PID =="
|
||||
pgrep -fa "ssh.*-S {{ _ctrl_sock | regex_escape }}" || true
|
||||
echo "== ps/grep ControlMaster by ControlPath =="
|
||||
ps -ef | grep -F " -S {{ _ctrl_sock }}" | grep -v grep || true
|
||||
register: port_listeners_after
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
@@ -263,7 +256,6 @@
|
||||
msg:
|
||||
- "{{ (port_listeners_after.stdout | default('')) | trim }}"
|
||||
|
||||
|
||||
- name: Wait a moment for tunnel to settle
|
||||
delegate_to: localhost
|
||||
ansible.builtin.wait_for:
|
||||
@@ -286,7 +278,6 @@
|
||||
- "tunnel_check.rc={{ tun_check.rc }}"
|
||||
- "tunnel_check.out={{ (tun_check.stdout | default('')) | trim }}"
|
||||
|
||||
# ADD THIS RIGHT AFTER THE EXISTING DEBUG:
|
||||
- name: Debug ControlMaster check (full rc/stdout/stderr)
|
||||
delegate_to: localhost
|
||||
ansible.builtin.debug:
|
||||
@@ -332,33 +323,7 @@
|
||||
- "{{ (dev2_ls.stdout | default('')) | trim }}"
|
||||
- "{{ (dev2_ls.stderr | default('')) | trim }}"
|
||||
|
||||
|
||||
- name: Probe SSH banner through tunnel without auth (quick)
|
||||
delegate_to: localhost
|
||||
ansible.builtin.shell: |
|
||||
set -e
|
||||
PORT="{{ _local_port }}"
|
||||
# No password, no interactive auth; prints preauth/banners then exits
|
||||
ssh -p "$PORT" \
|
||||
-o PreferredAuthentications=none \
|
||||
-o PubkeyAuthentication=no \
|
||||
-o KbdInteractiveAuthentication=no \
|
||||
-o PasswordAuthentication=no \
|
||||
-o NumberOfPasswordPrompts=0 \
|
||||
-o ConnectTimeout=5 \
|
||||
-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \
|
||||
-vvv root@127.0.0.1 true 2>&1 || true
|
||||
register: tunnel_banner_probe
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
|
||||
- name: Debug SSH preauth probe output (first 40 lines)
|
||||
delegate_to: localhost
|
||||
ansible.builtin.debug:
|
||||
msg: "{{ (tunnel_banner_probe.stdout | default('')) | regex_replace('^(?:.*\\n){,40}\\K[\\s\\S]*','[...truncated...]') }}"
|
||||
|
||||
|
||||
# ---------------------------- Pick DEV2 password for root ----------------------------
|
||||
# ---------------------------- Single banner probe (kept) ----------------------------
|
||||
- name: Probe SSH banner through tunnel (pre-auth, quick)
|
||||
delegate_to: localhost
|
||||
ansible.builtin.shell: |
|
||||
@@ -380,9 +345,9 @@
|
||||
- name: Debug SSH preauth probe (first 40 lines)
|
||||
delegate_to: localhost
|
||||
ansible.builtin.debug:
|
||||
msg: "{{ (tunnel_banner_probe.stdout | default('')) | regex_replace('^(?:.*\\n){,40}\\K[\\s\\S]*','[...truncated...]') }}"
|
||||
|
||||
msg: "{{ (tunnel_banner_probe.stdout | default('') | split('\n'))[:40] | join('\n') }}"
|
||||
|
||||
# ---------------------------- Pick DEV2 password for root ----------------------------
|
||||
- name: Try DEV2 login with 'basicpass' (root)
|
||||
delegate_to: localhost
|
||||
ansible.builtin.shell: |
|
||||
@@ -407,8 +372,8 @@
|
||||
{ ss -ltnp 2>/dev/null || true; } | awk -v p=":${P}$" '$0 ~ p {print}'
|
||||
echo "== lsof LISTEN on :${P} =="
|
||||
{ lsof -nP -iTCP:"${P}" -sTCP:LISTEN 2>/dev/null || true; }
|
||||
echo "== pgrep ControlMaster by socket =="
|
||||
pgrep -fa "ssh.*-S {{ _ctrl_sock | regex_escape }}" || true
|
||||
echo "== ps/grep ControlMaster by ControlPath =="
|
||||
ps -ef | grep -F " -S {{ _ctrl_sock }}" | grep -v grep || true
|
||||
register: listeners_after_basicpass
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
@@ -422,7 +387,6 @@
|
||||
- "ctrl_sock={{ _ctrl_sock }}"
|
||||
- "listeners:\n{{ (listeners_after_basicpass.stdout | default('')) | trim }}"
|
||||
|
||||
|
||||
- name: Select 'basicpass' if previous login succeeded
|
||||
when: dev2_try_basicpass.rc == 0
|
||||
delegate_to: localhost
|
||||
@@ -455,8 +419,8 @@
|
||||
{ ss -ltnp 2>/dev/null || true; } | awk -v p=":${P}$" '$0 ~ p {print}'
|
||||
echo "== lsof LISTEN on :${P} =="
|
||||
{ lsof -nP -iTCP:"${P}" -sTCP:LISTEN 2>/dev/null || true; }
|
||||
echo "== pgrep ControlMaster by socket =="
|
||||
pgrep -fa "ssh.*-S {{ _ctrl_sock | regex_escape }}" || true
|
||||
echo "== ps/grep ControlMaster by ControlPath =="
|
||||
ps -ef | grep -F " -S {{ _ctrl_sock }}" | grep -v grep || true
|
||||
register: listeners_after_basicpass2
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
@@ -471,7 +435,6 @@
|
||||
- "listeners:\n{{ (listeners_after_basicpass2.stdout | default('')) | trim }}"
|
||||
when: dev2_try_basicpass2 is defined
|
||||
|
||||
|
||||
- name: Select 'basicpass2' if second login succeeded
|
||||
when: dev2_passfile_used is not defined and dev2_try_basicpass2.rc == 0
|
||||
delegate_to: localhost
|
||||
@@ -1149,8 +1112,6 @@
|
||||
changed_when: true
|
||||
ignore_errors: true
|
||||
|
||||
|
||||
|
||||
# ---------------------------- Reboot scheduling (normalized) ----------------------------
|
||||
- name: Schedule DEV2 reboot after computed delay (seconds)
|
||||
when: _reboot_requested and (_reboot_minutes | int) >= 0 and dev2_passfile_used != "NONE" and not (_blocked | default(false))
|
||||
|
||||
Reference in New Issue
Block a user