Files
ansible user 110301f862 first commit
2025-10-22 14:11:49 +02:00

385 lines
15 KiB
YAML

---
- name: Deploy WiFi debug (single device, linear)
hosts: all
gather_facts: no
vars:
remote_syslog_ip: "102.38.125.161"
ssh_user: "{{ ansible_user | default('root') }}"
ssh_pass: "{{ ansible_password | default(ansible_ssh_pass) }}"
# RabbitMQ (from env with defaults)
rmq_host: "{{ lookup('env','RMQ_HOST') | default('10.210.12.2', true) }}"
rmq_port: "{{ lookup('env','RMQ_PORT') | default('15672', true) }}"
rmq_user: "{{ lookup('env','RMQ_USER') | default('admin', true) }}"
rmq_pass: "{{ lookup('env','RMQ_PASS') | default('change_me', true) }}"
rmq_vhost: "{{ lookup('env','RMQ_VHOST') | default('app', true) }}"
rmq_exchange: "{{ lookup('env','RMQ_EXCHANGE') | default('amq.default', true) }}"
queue2_name: "{{ lookup('env','QUEUE2') | default('queue2', true) }}"
tasks:
- block:
# --- SSH reachability check ---
- name: Check SSH connectivity (raw ping)
raw: "echo ping"
register: ping_result
ignore_errors: true
- block:
############ step 1
- name: Check if crontab launch is already present in sysstart.lua
raw: |
grep -F 'crontabs -f -l 8' /usr/share/config/sysstart.lua >/dev/null 2>&1 && echo PRESENT || echo ABSENT
register: sysstart_cron_check
changed_when: false
failed_when: false
- name: Announce presence and skip edits
when: (sysstart_cron_check.stdout | trim) == 'PRESENT'
debug:
msg: "crontab is present in sysstart.lua; skipping download/edit/upload."
- name: Fetch sysstart.lua via scp (password auth)
when: (sysstart_cron_check.stdout | trim) != 'PRESENT'
delegate_to: localhost
command: >
sshpass -p {{ ssh_pass | quote }}
scp -q -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null
{{ ssh_user }}@{{ ansible_host }}:/usr/share/config/sysstart.lua
/tmp/{{ inventory_hostname }}_sysstart.lua
register: scp_get
retries: 3
delay: 2
until: scp_get.rc == 0
- name: Edit the file locally
when: (sysstart_cron_check.stdout | trim) != 'PRESENT'
delegate_to: localhost
lineinfile:
path: "/tmp/{{ inventory_hostname }}_sysstart.lua"
line: 'launchd.set_process("crontab", "crond -c /etc/crontabs -f -l 8")'
insertbefore: '^tasks\.start\(ctx,\s*"finished"\)'
- name: Push the file back (write to -2)
when: (sysstart_cron_check.stdout | trim) != 'PRESENT'
delegate_to: localhost
command: >
sshpass -p {{ ssh_pass | quote }}
scp -q -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null
/tmp/{{ inventory_hostname }}_sysstart.lua
{{ ssh_user }}@{{ ansible_host }}:/usr/share/config/sysstart.lua
register: scp_put
retries: 3
delay: 2
until: scp_put.rc == 0
############ step 2
- name: Compute MD5 of local wifidebug.sh
delegate_to: localhost
command: md5sum files/wifidebug.sh
register: md5_local_wdbg
changed_when: false
- name: Compute MD5 of remote /root/wifidebug.sh
raw: "md5sum /root/wifidebug.sh || busybox md5sum /root/wifidebug.sh"
register: md5_remote_wdbg
changed_when: false
failed_when: false
- name: Decide if wifidebug.sh needs upload
set_fact:
upload_wdbg: >-
{{ (md5_remote_wdbg.rc != 0)
or ((md5_local_wdbg.stdout.split()[0])
!= (md5_remote_wdbg.stdout.split()[0] if (md5_remote_wdbg.stdout is defined) else '')) }}
- name: Upload wifidebug.sh via scp (overwrite if changed)
when: upload_wdbg | bool
delegate_to: localhost
command: >
sshpass -p {{ ssh_pass | quote }}
scp -q -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null
files/wifidebug.sh
{{ ssh_user }}@{{ ansible_host }}:/root/wifidebug.sh
register: scp_wifidebug
retries: 3
delay: 2
until: scp_wifidebug.rc == 0
- name: Ensure /root/wifidebug.sh is executable and owned by root
raw: |
chown root:root /root/wifidebug.sh && chmod 0755 /root/wifidebug.sh
############ step 3
- name: Ensure /etc/crontabs/root exists (touch with perms)
raw: |
if [ ! -f /etc/crontabs/root ]; then
touch /etc/crontabs/root
fi
chown root:root /etc/crontabs/root
chmod 0644 /etc/crontabs/root
- name: Check if cron line already present
raw: |
grep -Fxq '*/1 * * * * /root/wifidebug.sh' /etc/crontabs/root
register: cron_grep
failed_when: false
changed_when: false
- name: Upload snippet crond-root to /tmp (only if missing)
when: cron_grep.rc != 0
delegate_to: localhost
command: >
sshpass -p {{ ssh_pass | quote }}
scp -q -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null
files/crond-root
{{ ssh_user }}@{{ ansible_host }}:/tmp/crond-root.snippet
- name: Append snippet to /etc/crontabs/root (only if missing)
when: cron_grep.rc != 0
raw: |
cat /tmp/crond-root.snippet >> /etc/crontabs/root && rm -f /tmp/crond-root.snippet
register: cron_append
changed_when: true
############ step 4
- name: Skip config.json edit if remote_syslog already matches
raw: |
EN_OK=$(cat /tmp/config.json | grep -A9 -m1 'remote_syslog' | grep 'enabled' | grep true | wc -l || echo 0)
SRV_OK=$(cat /tmp/config.json | grep -A9 -m1 'remote_syslog' | grep 'server' | grep '{{ remote_syslog_ip }}' | wc -l || echo 0)
if [ "$EN_OK" -eq 1 ] && [ "$SRV_OK" -eq 1 ]; then
echo "SKIP"
else
echo "EDIT"
fi
register: remote_syslog_check
changed_when: false
- name: Set do_edit flag from skip check
set_fact:
do_edit: "{{ (remote_syslog_check.stdout | default('EDIT')) | trim != 'SKIP' }}"
- name: Fetch /tmp/config.json to controller
when: do_edit
delegate_to: localhost
command: >
sshpass -p {{ ssh_pass | quote }}
scp -q -o StrictHostKeyChecking=no
{{ ssh_user }}@{{ ansible_host }}:/tmp/config.json
/tmp/{{ inventory_hostname }}_config.json
- name: Strict in-place style-preserving edit (services.remote_syslog only)
when: do_edit
delegate_to: localhost
shell: |
awk '
BEGIN { in_services=0; in_rs=0; depth=0; done_enabled=0; done_server=0 }
{
line = $0
if (!in_services && $0 ~ /"services"[[:space:]]*:/) { in_services=1 }
if (in_services && !in_rs && $0 ~ /"remote_syslog"[[:space:]]*:/) { in_rs=1; depth=0 }
if (in_rs) {
if (!done_enabled && line ~ /^[[:space:]]*"enabled"[[:space:]]*:[[:space:]]*false([[:space:]]*,?[[:space:]]*)$/) {
line = gensub(/^([[:space:]]*"enabled"[[:space:]]*:[[:space:]]*)false([[:space:]]*,?[[:space:]]*)$/, "\\1true\\2", 1, line)
done_enabled=1
}
if (!done_server && line ~ /^[[:space:]]*"server"[[:space:]]*:[[:space:]]*""([[:space:]]*,?[[:space:]]*)$/) {
line = gensub(/^([[:space:]]*"server"[[:space:]]*:[[:space:]]*)""([[:space:]]*,?[[:space:]]*)$/, "\\1\"102.38.125.161\"\\2", 1, line)
done_server=1
}
}
print line
if (in_rs) {
opens = gsub(/{/, "{", $0)
closes = gsub(/}/, "}", $0)
depth += (opens - closes)
if (depth <= 0 && $0 ~ /}/) { in_rs=0 }
}
}
' "/tmp/{{ inventory_hostname }}_config.json" \
> "/tmp/{{ inventory_hostname }}_config.json.new"
args:
executable: /bin/bash
- name: Push edited config.json.new to remote temp
when: do_edit
delegate_to: localhost
shell: |
sshpass -p {{ ssh_pass | quote }} scp -q -o StrictHostKeyChecking=no \
"/tmp/{{ inventory_hostname }}_config.json.new" \
{{ ssh_user }}@{{ ansible_host }}:/tmp/config.json.new
args:
executable: /bin/bash
- name: Compute MD5 of local .new
when: do_edit
delegate_to: localhost
command: md5sum "/tmp/{{ inventory_hostname }}_config.json.new"
register: md5_local
changed_when: false
- name: Compute MD5 of remote .new (no Python)
when: do_edit
raw: "md5sum /tmp/config.json.new || busybox md5sum /tmp/config.json.new"
register: md5_remote
changed_when: false
- name: Fail if MD5 mismatch
when:
- do_edit
- (md5_local.stdout.split()[0]) != (md5_remote.stdout.split()[0] if (md5_remote.stdout is defined) else 'BAD')
fail:
msg: "MD5 mismatch between controller and remote copy — aborting replace."
- name: Commit new config.json (overwrite original)
when: do_edit
raw: |
cp -a /tmp/config.json /tmp/config.json.bak.$(date +%Y%m%d%H%M%S)
mv /tmp/config.json.new /tmp/config.json
- name: Apply config to runtime (sysconf -w)
when: do_edit
raw: |
sysconf -w || /usr/sbin/sysconf -w
register: sysconf_result
changed_when: true
failed_when: sysconf_result.rc not in [0]
- name: Trigger full restart (system-stop; system-start) in background
when: do_edit
raw: |
sleep 1; /usr/sbin/system-stop; /usr/sbin/system-start
ignore_errors: true
changed_when: true
- name: Short grace delay before waiting
when: do_edit
delegate_to: localhost
pause:
seconds: 3
- name: Try to observe SSH port stopping (best effort)
when: do_edit
delegate_to: localhost
wait_for:
host: "{{ ansible_host }}"
port: 22
state: stopped
timeout: 30
sleep: 2
ignore_errors: true
- name: Wait for SSH port to be accepting connections
when: do_edit
delegate_to: localhost
wait_for:
host: "{{ ansible_host }}"
port: 22
state: started
timeout: 300
sleep: 2
- name: Reset Ansible SSH connection
when: do_edit
meta: reset_connection
- name: Verify command execution after restart (no python)
when: do_edit
raw: "echo rebooted_ok"
register: post_restart_probe
retries: 120
delay: 2
until: post_restart_probe is succeeded
changed_when: false
- name: Set result status (success deployed or no change)
set_fact:
result_status: "{{ 'SUCCESS_DEPLOYED' if (upload_wdbg | bool) else 'SUCCESS_NO_CHANGE' }}"
when: ping_result is succeeded
- name: Set status fact (no ssh)
when: ping_result is failed
set_fact:
result_status: "NO_SSH"
rescue:
- name: Mark result as failed
set_fact:
result_status: "FAILED during {{ ansible_failed_task.name }}"
always:
- name: Compute inscope device
set_fact:
inscope_device_name: "{{ ansible_hostname | default(inventory_hostname) }}"
- name: Build journal_add payload
set_fact:
journal_payload_obj:
inscope_device: "{{ inscope_device_name }}"
task_name: "journal_add"
task_result: "{{ result_status }}"
- name: Publish journal_add to queue2
uri:
url: "http://{{ rmq_host }}:{{ rmq_port }}/api/exchanges/{{ rmq_vhost | urlencode }}/{{ rmq_exchange | urlencode }}/publish"
method: POST
user: "{{ rmq_user }}"
password: "{{ rmq_pass }}"
force_basic_auth: true
status_code: 200
headers:
content-type: "application/json"
body_format: json
body:
properties:
content_type: "application/json"
routing_key: "{{ queue2_name }}"
payload: "{{ journal_payload_obj | to_json }}"
payload_encoding: "string"
delegate_to: localhost
- name: Build deploy_wifidebug success payload
when: result_status == 'SUCCESS_DEPLOYED'
set_fact:
success_payload_obj:
inscope_device: "{{ inscope_device_name }}"
task_name: "deploy_wifidebug"
task_result: "success"
- name: Publish deploy_wifidebug success to queue2
when: result_status == 'SUCCESS_DEPLOYED'
uri:
url: "http://{{ rmq_host }}:{{ rmq_port }}/api/exchanges/{{ rmq_vhost | urlencode }}/{{ rmq_exchange | urlencode }}/publish"
method: POST
user: "{{ rmq_user }}"
password: "{{ rmq_pass }}"
force_basic_auth: true
status_code: 200
headers:
content-type: "application/json"
body_format: json
body:
properties:
content_type: "application/json"
routing_key: "{{ queue2_name }}"
payload: "{{ success_payload_obj | to_json }}"
payload_encoding: "string"
delegate_to: localhost
- name: Summary
debug:
msg:
- "result_status: {{ result_status }}"
- "we're good"