sync: add base.html improvements, update_wmt_code playbook, wmt_releases v2.9, run script
This commit is contained in:
@@ -124,183 +124,12 @@
|
|||||||
- name: Show data/ contents after update (should match before)
|
- name: Show data/ contents after update (should match before)
|
||||||
debug:
|
debug:
|
||||||
msg: "{{ data_files_after.stdout_lines }}"
|
msg: "{{ data_files_after.stdout_lines }}"
|
||||||
|
|
||||||
# ── 7. Restart WMT service ────────────────────────────────────────────
|
# ── 9. Reboot ─────────────────────────────────────────────────────────
|
||||||
- name: Restart WMT systemd service
|
- name: Reboot host to apply all changes
|
||||||
become: true
|
become: true
|
||||||
systemd:
|
reboot:
|
||||||
name: wmt
|
msg: "Rebooting after WMT code update "
|
||||||
state: restarted
|
reboot_timeout: 180
|
||||||
enabled: true
|
pre_reboot_delay: 3
|
||||||
register: service_result
|
post_reboot_delay: 15
|
||||||
ignore_errors: true
|
|
||||||
|
|
||||||
- name: Show service state
|
|
||||||
debug:
|
|
||||||
msg: "WMT service state: {{ service_result.status.ActiveState | default('unknown') }}"
|
|
||||||
when: service_result is not failed
|
|
||||||
|
|
||||||
- name: Warn if service restart failed
|
|
||||||
debug:
|
|
||||||
msg: "WARNING: wmt service restart failed – the device may need a manual reboot."
|
|
||||||
when: service_result is failed
|
|
||||||
|
|
||||||
vars:
|
|
||||||
wmt_dir: /home/pi/Desktop/WMT
|
|
||||||
tmp_zip: /tmp/wmt_update.zip
|
|
||||||
# Controller address – override on CLI with -e "server_url=http://..."
|
|
||||||
server_url: "http://{{ hostvars[inventory_hostname]['ansible_host'] | default(ansible_host) | regex_replace('\\d+\\.\\d+$', '10.76.157.1') }}"
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
|
|
||||||
# ── 0. Resolve server URL ─────────────────────────────────────────────
|
|
||||||
# The monitoring server address is read from the device's own config.txt
|
|
||||||
# so we don't have to hard-code it here.
|
|
||||||
- name: Read server_host from WMT config.txt
|
|
||||||
shell: |
|
|
||||||
grep -E '^\s*server_host\s*=' {{ wmt_dir }}/data/config.txt 2>/dev/null \
|
|
||||||
| head -1 | awk -F'=' '{print $2}' | tr -d ' \r\n'
|
|
||||||
register: cfg_server_host
|
|
||||||
changed_when: false
|
|
||||||
ignore_errors: true
|
|
||||||
|
|
||||||
- name: Read server_port from WMT config.txt
|
|
||||||
shell: |
|
|
||||||
grep -E '^\s*server_port\s*=' {{ wmt_dir }}/data/config.txt 2>/dev/null \
|
|
||||||
| head -1 | awk -F'=' '{print $2}' | tr -d ' \r\n'
|
|
||||||
register: cfg_server_port
|
|
||||||
changed_when: false
|
|
||||||
ignore_errors: true
|
|
||||||
|
|
||||||
- name: Set monitoring server base URL
|
|
||||||
set_fact:
|
|
||||||
monitoring_base: "http://{{ cfg_server_host.stdout | default('rpi-ansible') }}:{{ cfg_server_port.stdout | default('5000') }}"
|
|
||||||
|
|
||||||
- name: Show resolved server URL
|
|
||||||
debug:
|
|
||||||
msg: "Monitoring server: {{ monitoring_base }}"
|
|
||||||
|
|
||||||
# ── 1. Check latest version on server ────────────────────────────────
|
|
||||||
- name: Query latest WMT version from monitoring server
|
|
||||||
uri:
|
|
||||||
url: "{{ monitoring_base }}/api/wmt/client/version"
|
|
||||||
method: GET
|
|
||||||
return_content: true
|
|
||||||
timeout: 15
|
|
||||||
register: version_response
|
|
||||||
ignore_errors: true
|
|
||||||
|
|
||||||
- name: Show server version info
|
|
||||||
debug:
|
|
||||||
msg: "Server release: v{{ version_response.json.version | default('unknown') }} ({{ version_response.json.filename | default('n/a') }})"
|
|
||||||
when: version_response is not failed
|
|
||||||
|
|
||||||
- name: Fail if server version endpoint unreachable
|
|
||||||
fail:
|
|
||||||
msg: "Cannot reach {{ monitoring_base }}/api/wmt/client/version – is the server running?"
|
|
||||||
when: version_response is failed
|
|
||||||
|
|
||||||
# ── 2. Get current local version ─────────────────────────────────────
|
|
||||||
- name: Read first line of local app.py
|
|
||||||
shell: head -1 {{ wmt_dir }}/app.py 2>/dev/null || echo "unknown"
|
|
||||||
register: local_first_line
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Extract local version number
|
|
||||||
set_fact:
|
|
||||||
local_version: "{{ local_first_line.stdout | regex_search('version\\s+([\\d.]+)', '\\1') | first | default('0') }}"
|
|
||||||
|
|
||||||
- name: Show local version
|
|
||||||
debug:
|
|
||||||
msg: "Local version: {{ local_version }} | Server version: {{ version_response.json.version }}"
|
|
||||||
|
|
||||||
# ── 3. Ensure WMT directory exists ───────────────────────────────────
|
|
||||||
- name: Ensure WMT directory exists
|
|
||||||
file:
|
|
||||||
path: "{{ wmt_dir }}"
|
|
||||||
state: directory
|
|
||||||
owner: pi
|
|
||||||
group: pi
|
|
||||||
mode: '0755'
|
|
||||||
|
|
||||||
# ── 4. Download release zip ───────────────────────────────────────────
|
|
||||||
- name: Download WMT release zip from monitoring server
|
|
||||||
get_url:
|
|
||||||
url: "{{ monitoring_base }}/api/wmt/client/download"
|
|
||||||
dest: "{{ tmp_zip }}"
|
|
||||||
force: true
|
|
||||||
timeout: 120
|
|
||||||
mode: '0644'
|
|
||||||
|
|
||||||
# ── 5. Back up current app.py ─────────────────────────────────────────
|
|
||||||
- name: Back up current app.py
|
|
||||||
copy:
|
|
||||||
src: "{{ wmt_dir }}/app.py"
|
|
||||||
dest: "{{ wmt_dir }}/app.py.bak.{{ local_version }}"
|
|
||||||
remote_src: true
|
|
||||||
owner: pi
|
|
||||||
group: pi
|
|
||||||
mode: preserve
|
|
||||||
ignore_errors: true
|
|
||||||
|
|
||||||
# ── 6. Extract zip – skip data/ directory ─────────────────────────────
|
|
||||||
- name: Extract WMT release zip (preserving data/ directory)
|
|
||||||
shell: |
|
|
||||||
cd {{ wmt_dir }}
|
|
||||||
python3 - <<'EOF'
|
|
||||||
import zipfile, os, sys
|
|
||||||
zip_path = "{{ tmp_zip }}"
|
|
||||||
dest = "{{ wmt_dir }}"
|
|
||||||
skipped = 0
|
|
||||||
extracted = 0
|
|
||||||
with zipfile.ZipFile(zip_path, 'r') as zf:
|
|
||||||
for member in zf.infolist():
|
|
||||||
p = member.filename.replace('\\', '/')
|
|
||||||
if p.startswith('data/') or p == 'data':
|
|
||||||
skipped += 1
|
|
||||||
continue
|
|
||||||
zf.extract(member, dest)
|
|
||||||
extracted += 1
|
|
||||||
print(f"Extracted {extracted} files, skipped {skipped} data/ entries")
|
|
||||||
EOF
|
|
||||||
register: extract_result
|
|
||||||
changed_when: true
|
|
||||||
|
|
||||||
- name: Show extraction result
|
|
||||||
debug:
|
|
||||||
msg: "{{ extract_result.stdout }}"
|
|
||||||
|
|
||||||
# ── 7. Fix ownership ──────────────────────────────────────────────────
|
|
||||||
- name: Set correct ownership on WMT directory
|
|
||||||
become: true
|
|
||||||
file:
|
|
||||||
path: "{{ wmt_dir }}"
|
|
||||||
owner: pi
|
|
||||||
group: pi
|
|
||||||
recurse: true
|
|
||||||
|
|
||||||
# ── 8. Clean up temp zip ──────────────────────────────────────────────
|
|
||||||
- name: Remove temporary zip file
|
|
||||||
file:
|
|
||||||
path: "{{ tmp_zip }}"
|
|
||||||
state: absent
|
|
||||||
|
|
||||||
# ── 9. Restart WMT service ────────────────────────────────────────────
|
|
||||||
- name: Restart WMT systemd service
|
|
||||||
become: true
|
|
||||||
systemd:
|
|
||||||
name: wmt
|
|
||||||
state: restarted
|
|
||||||
enabled: true
|
|
||||||
register: service_result
|
|
||||||
ignore_errors: true
|
|
||||||
|
|
||||||
- name: Show service restart result
|
|
||||||
debug:
|
|
||||||
msg: "Service state: {{ service_result.status.ActiveState | default('unknown') }}"
|
|
||||||
when: service_result is not failed
|
|
||||||
|
|
||||||
- name: Warn if service restart failed
|
|
||||||
debug:
|
|
||||||
msg: "WARNING: wmt service restart failed – the device may need a manual reboot."
|
|
||||||
when: service_result is failed
|
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"version": "2.9",
|
||||||
|
"notes": "",
|
||||||
|
"uploaded_at": "2026-05-13T13:17:18",
|
||||||
|
"filename": "wmt_v2.9.zip"
|
||||||
|
}
|
||||||
Binary file not shown.
+64
-2
@@ -781,11 +781,73 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
body.dark-mode .nav-group-header:hover {
|
body.dark-mode .nav-group-header:hover {
|
||||||
background-color: rgba(255,255,255,0.08);
|
background-color: rgba(255,255,255,0.07);
|
||||||
}
|
}
|
||||||
|
|
||||||
body.dark-mode .nav-group-header.open {
|
body.dark-mode .nav-group-header.open {
|
||||||
background-color: rgba(255,255,255,0.1);
|
background-color: rgba(255,255,255,0.09);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ── Dark mode sidebar ── */
|
||||||
|
body.dark-mode .sidebar {
|
||||||
|
background: linear-gradient(160deg, #0d0d0d 0%, #1a1a2e 50%, #16213e 100%);
|
||||||
|
box-shadow: 2px 0 16px rgba(0,0,0,0.6);
|
||||||
|
}
|
||||||
|
|
||||||
|
body.dark-mode .sidebar .logo {
|
||||||
|
border-bottom-color: rgba(255,255,255,0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
body.dark-mode .sidebar .logo small {
|
||||||
|
color: #7f8c9a;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.dark-mode .sidebar .nav-link {
|
||||||
|
color: #b0bec5;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.dark-mode .sidebar .nav-link:hover {
|
||||||
|
background-color: rgba(100,181,246,0.12);
|
||||||
|
color: #e0f0ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.dark-mode .sidebar .nav-link.active {
|
||||||
|
background-color: rgba(100,181,246,0.2);
|
||||||
|
color: #e0f0ff;
|
||||||
|
border-left: 3px solid #64b5f6;
|
||||||
|
padding-left: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.dark-mode .sidebar .nav-link i {
|
||||||
|
color: #64b5f6;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.dark-mode .sidebar .nav-link.active i {
|
||||||
|
color: #90caf9;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.dark-mode .sidebar .nav-link.admin-link {
|
||||||
|
color: #ef9a9a;
|
||||||
|
border-top-color: rgba(255,255,255,0.07);
|
||||||
|
}
|
||||||
|
|
||||||
|
body.dark-mode .sidebar .nav-link.admin-link:hover {
|
||||||
|
background-color: rgba(239,154,154,0.15);
|
||||||
|
color: #ffcdd2;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.dark-mode .sidebar .nav-link.admin-link.active {
|
||||||
|
background-color: rgba(239,154,154,0.22);
|
||||||
|
color: #ffcdd2;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.dark-mode .sidebar .nav-link.admin-link i {
|
||||||
|
color: #ef9a9a;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.dark-mode .dark-mode-btn {
|
||||||
|
border-top-color: rgba(255,255,255,0.07);
|
||||||
|
color: #b0bec5;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
{% block extra_css %}{% endblock %}
|
{% block extra_css %}{% endblock %}
|
||||||
|
|||||||
Reference in New Issue
Block a user