Files
Server_Monitorizare_v2/ansible/playbooks/Update_Rest_WMT_client.yml

454 lines
16 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
# Update_Rest_WMT_client Push standard WMT client files to target devices
# ──────────────────────────────────────────────────────────────────────────
# What this playbook does (in order):
#
# 1. Verify that WMT_project exists on the controller
# 2. Kill any running WMT app.py on the target
# 3. Remove previous WMT_old (if any) and rename WMT → WMT_old
# 4. Copy WMT_project → fresh WMT on the target
# 5. Fix execute permissions on scripts
# 6. Migrate config values: old config.txt → new config.txt
# Rules:
# • For every key that exists in BOTH old and new config → use old value
# • Key exists only in new config (new feature) → keep new default
# • Key exists only in old config (removed key) → skip / ignore
# File structure, comments, and new keys are always from
# the new template (WMT_project/data/config.txt).
# 7. Restore runtime data files (log.txt, tag.txt) from WMT_old
# 8. Delete WMT_old (migration complete, backup no longer needed)
# 9. Reboot the target host
#
# Run via: Ansible > Playbooks > "Update_Rest_WMT_client" or
# POST /api/ansible/execute { "playbook": "Update_Rest_WMT_client.yml" }
# ──────────────────────────────────────────────────────────────────────────
- name: Update WMT client files on target devices
hosts: all
gather_facts: false
become: false
tasks:
# ── 1. Verify source exists on the controller ─────────────────────────
- name: Check WMT_project source folder exists on controller
delegate_to: localhost
stat:
path: /home/pi/Desktop/WMT_project
register: wmt_project_stat
- name: Fail if WMT_project is missing on the controller
delegate_to: localhost
fail:
msg: >
/home/pi/Desktop/WMT_project not found on the Ansible controller.
Ensure the WMT_project folder is present before running this playbook.
when: not wmt_project_stat.stat.exists
# ── 2. Kill any running WMT app.py ────────────────────────────────────
- name: Stop running WMT app.py (if any)
shell: pkill -f "python3.*WMT/app.py"
ignore_errors: true
changed_when: false
- name: Wait for process to terminate
wait_for:
timeout: 4
# ── 3a. Remove previous WMT_old backup (if one exists from a prior run)
- name: Check if WMT_old already exists
stat:
path: /home/pi/Desktop/WMT_old
register: wmt_old_stat
- name: Remove previous WMT_old folder
file:
path: /home/pi/Desktop/WMT_old
state: absent
when: wmt_old_stat.stat.exists
# ── 3b. Rename current WMT → WMT_old ─────────────────────────────────
- name: Check if WMT folder currently exists
stat:
path: /home/pi/Desktop/WMT
register: wmt_stat
- name: Rename WMT to WMT_old
command: mv /home/pi/Desktop/WMT /home/pi/Desktop/WMT_old
when: wmt_stat.stat.exists
# ── 4. Copy fresh WMT_project → WMT ──────────────────────────────────
- name: Copy WMT_project to target as /home/pi/Desktop/WMT
copy:
src: /home/pi/Desktop/WMT_project/
dest: /home/pi/Desktop/WMT/
owner: pi
group: pi
mode: preserve
force: true
- name: Ensure WMT/data directory exists
file:
path: /home/pi/Desktop/WMT/data
state: directory
owner: pi
group: pi
mode: '0755'
# ── 5. Fix execute permissions ────────────────────────────────────────
- name: Ensure app.py is executable
file:
path: /home/pi/Desktop/WMT/app.py
owner: pi
group: pi
mode: '0755'
- name: Ensure setup_port_capability.sh is executable
file:
path: /home/pi/Desktop/WMT/setup_port_capability.sh
state: file
owner: pi
group: pi
mode: '0755'
ignore_errors: true
# ── 6. Migrate config values from old config.txt into new template ────
#
# Strategy (line-preserving Python migration):
# • Read WMT_old/data/config.txt → source of device-specific values
# • Read WMT/data/config.txt → new template (correct keys & comments)
# • Walk the new template line by line:
# - Keep all comment lines and blank lines unchanged
# - For each key=value line:
# If old config has the SAME section + key → replace value with old value
# If old config does NOT have that key → keep new default value
# - Keys only in old config are silently ignored (removed features)
# • Write the result back to WMT/data/config.txt
#
- name: Check if old config.txt exists in WMT_old
stat:
path: /home/pi/Desktop/WMT_old/data/config.txt
register: old_cfg_stat
- name: Migrate config values (old → new template)
shell: |
python3 << 'PYEOF'
import configparser, os, re, sys
old_path = '/home/pi/Desktop/WMT_old/data/config.txt'
new_path = '/home/pi/Desktop/WMT/data/config.txt'
if not os.path.exists(old_path):
print('No old config.txt found keeping new defaults as-is')
sys.exit(0)
if not os.path.exists(new_path):
print('New config.txt missing nothing to migrate into')
sys.exit(1)
# Parse old config to get existing values
old = configparser.ConfigParser()
old.read(old_path)
# Walk new template line by line, replacing values where old config has them
current_section = None
output_lines = []
migrated = []
kept_new = []
with open(new_path, 'r') as f:
for line in f:
stripped = line.rstrip('\n')
# Detect section header e.g. [device]
section_match = re.match(r'^\s*\[([^\]]+)\]\s*$', stripped)
if section_match:
current_section = section_match.group(1)
output_lines.append(line)
continue
# Detect key = value line (skip comments and blank lines)
kv_match = re.match(r'^([^#;\s][^=]*?)\s*=\s*(.*)', stripped)
if kv_match and current_section:
key = kv_match.group(1).strip()
new_val = kv_match.group(2)
if old.has_section(current_section) and old.has_option(current_section, key):
old_val = old.get(current_section, key)
if old_val != new_val:
output_lines.append(f'{key}={old_val}\n')
migrated.append(f' [{current_section}] {key} = {old_val!r} (was: {new_val!r})')
else:
output_lines.append(line)
else:
output_lines.append(line)
kept_new.append(f' [{current_section}] {key} = {new_val!r} (new key keeping default)')
else:
output_lines.append(line)
with open(new_path, 'w') as f:
f.writelines(output_lines)
print('=== Config migration complete ===')
if migrated:
print(f'Migrated {len(migrated)} value(s) from old config:')
for m in migrated:
print(m)
if kept_new:
print(f'Kept {len(kept_new)} new default(s) (not in old config):')
for k in kept_new:
print(k)
PYEOF
register: cfg_migration_result
when: old_cfg_stat.stat.exists
changed_when: true
- name: Show config migration output
debug:
msg: "{{ cfg_migration_result.stdout_lines }}"
when: old_cfg_stat.stat.exists
- name: Note no old config found, new defaults kept
debug:
msg: "WMT_old/data/config.txt not found new WMT_project defaults will be used."
when: not old_cfg_stat.stat.exists
# ── 7. Restore runtime data files from WMT_old ───────────────────────
- name: Check if log.txt exists in WMT_old
stat:
path: /home/pi/Desktop/WMT_old/data/log.txt
register: old_log_stat
- name: Restore log.txt from WMT_old
copy:
src: /home/pi/Desktop/WMT_old/data/log.txt
dest: /home/pi/Desktop/WMT/data/log.txt
owner: pi
group: pi
mode: '0644'
remote_src: true
when: old_log_stat.stat.exists
- name: Check if tag.txt exists in WMT_old
stat:
path: /home/pi/Desktop/WMT_old/data/tag.txt
register: old_tag_stat
- name: Restore tag.txt from WMT_old (pending card posts)
copy:
src: /home/pi/Desktop/WMT_old/data/tag.txt
dest: /home/pi/Desktop/WMT/data/tag.txt
owner: pi
group: pi
mode: '0644'
remote_src: true
when: old_tag_stat.stat.exists
# ── 8. Remove WMT_old now that migration is complete ─────────────────
- name: Remove WMT_old folder (migration done, no longer needed)
file:
path: /home/pi/Desktop/WMT_old
state: absent
# ── 9. Show final config and reboot ───────────────────────────────────
- name: Show final config.txt on target
command: cat /home/pi/Desktop/WMT/data/config.txt
register: final_cfg
changed_when: false
- name: Display final config.txt
debug:
msg: "{{ final_cfg.stdout_lines }}"
- name: Show updated app.py version
command: head -1 /home/pi/Desktop/WMT/app.py
register: app_version
changed_when: false
- name: Report update summary
debug:
msg: >
✓ WMT updated on {{ inventory_hostname }} {{ app_version.stdout }}.
Rebooting now to apply changes.
- name: Reboot target to apply all changes
become: true
reboot:
msg: "Rebooting after WMT client update"
reboot_timeout: 180
pre_reboot_delay: 3
post_reboot_delay: 15
- name: Update WMT client files on target devices
hosts: all
gather_facts: false
become: false
tasks:
# ── 1. Confirm WMT_project source exists on the controller ────────────
- name: Check that WMT_project source folder exists on controller
delegate_to: localhost
stat:
path: /home/pi/Desktop/WMT_project
register: wmt_project_stat
- name: Fail if WMT_project is missing on the controller
delegate_to: localhost
fail:
msg: >
/home/pi/Desktop/WMT_project was not found on the Ansible controller.
Make sure the WMT_project folder is present before running this playbook.
when: not wmt_project_stat.stat.exists
# ── 2. Ensure WMT destination directory exists on target ─────────────
- name: Ensure /home/pi/Desktop/WMT directory exists
file:
path: /home/pi/Desktop/WMT
state: directory
owner: pi
group: pi
mode: '0755'
# ── 3. Kill any running WMT app.py process ────────────────────────────
- name: Stop running WMT app.py (if any)
shell: pkill -f "python3.*WMT/app.py"
ignore_errors: true
changed_when: false
- name: Wait for process to terminate
wait_for:
timeout: 3
# ── 4. Copy WMT_project → WMT, preserving device-specific data files ─
- name: Copy WMT_project files to target (excluding device-specific data)
copy:
src: /home/pi/Desktop/WMT_project/
dest: /home/pi/Desktop/WMT/
owner: pi
group: pi
mode: preserve
force: true
# Exclude device-specific files that must never be overwritten
# Note: Ansible's copy module does not support 'exclude' natively;
# we restore the originals in step 4b4e below.
# ── 4b-4e. Restore device-specific data files from the target backup ──
# Strategy: before overwriting we slurp the existing files, then
# write them back so the 'copy' above cannot clobber them.
- name: Check if device config.txt exists (pre-copy)
stat:
path: /home/pi/Desktop/WMT/data/config.txt
register: cfg_stat
- name: Slurp existing config.txt (if present)
slurp:
src: /home/pi/Desktop/WMT/data/config.txt
register: cfg_backup
when: cfg_stat.stat.exists
- name: Restore config.txt after copy (device config must not be overwritten)
copy:
content: "{{ cfg_backup.content | b64decode }}"
dest: /home/pi/Desktop/WMT/data/config.txt
owner: pi
group: pi
mode: '0644'
when: cfg_stat.stat.exists
# idmasa.txt is a legacy Prezenta file not used by WMT, not restored
- name: Check if log.txt exists
stat:
path: /home/pi/Desktop/WMT/data/log.txt
register: log_stat
- name: Slurp existing log.txt (if present)
slurp:
src: /home/pi/Desktop/WMT/data/log.txt
register: log_backup
when: log_stat.stat.exists
- name: Restore log.txt after copy
copy:
content: "{{ log_backup.content | b64decode }}"
dest: /home/pi/Desktop/WMT/data/log.txt
owner: pi
group: pi
mode: '0644'
when: log_stat.stat.exists
- name: Check if tag.txt exists
stat:
path: /home/pi/Desktop/WMT/data/tag.txt
register: tag_stat
- name: Slurp existing tag.txt (if present)
slurp:
src: /home/pi/Desktop/WMT/data/tag.txt
register: tag_backup
when: tag_stat.stat.exists
- name: Restore tag.txt after copy
copy:
content: "{{ tag_backup.content | b64decode }}"
dest: /home/pi/Desktop/WMT/data/tag.txt
owner: pi
group: pi
mode: '0644'
when: tag_stat.stat.exists
# ── 5. Fix execute permissions on scripts ─────────────────────────────
- name: Ensure app.py is executable
file:
path: /home/pi/Desktop/WMT/app.py
owner: pi
group: pi
mode: '0755'
- name: Ensure setup_port_capability.sh is executable
file:
path: /home/pi/Desktop/WMT/setup_port_capability.sh
state: file
owner: pi
group: pi
mode: '0755'
ignore_errors: true
# ── 6. Ensure WMT/data directory is intact ────────────────────────────
- name: Ensure WMT/data directory exists
file:
path: /home/pi/Desktop/WMT/data
state: directory
owner: pi
group: pi
mode: '0755'
# ── 7. Restart WMT app in a new lxterminal session ────────────────────
- name: Launch WMT app.py in background lxterminal
shell: >
DISPLAY=:0 lxterminal -e
"bash -c 'cd /home/pi/Desktop/WMT; python3 app.py; exec bash'" &
environment:
DISPLAY: ":0"
ignore_errors: true
changed_when: true
- name: Wait for WMT app to start
wait_for:
timeout: 5
# ── 8. Confirm update on target ───────────────────────────────────────
- name: Show updated app.py version line
command: head -1 /home/pi/Desktop/WMT/app.py
register: app_version
changed_when: false
- name: Report update result
debug:
msg: >
✓ WMT client updated on {{ inventory_hostname }} ({{ ansible_host }}).
Version: {{ app_version.stdout }}