first commit
This commit is contained in:
384
files/ansible-playbooks/wifidebug14.yml
Normal file
384
files/ansible-playbooks/wifidebug14.yml
Normal file
@@ -0,0 +1,384 @@
|
||||
---
|
||||
- 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"
|
||||
|
||||
Reference in New Issue
Block a user