138 lines
4.6 KiB
YAML
138 lines
4.6 KiB
YAML
---
|
|
- name: Synology Healthcheck
|
|
hosts: synology
|
|
gather_facts: yes
|
|
become: false
|
|
|
|
vars:
|
|
ts_candidates:
|
|
- /var/packages/Tailscale/target/bin/tailscale
|
|
- /usr/bin/tailscale
|
|
|
|
tasks:
|
|
# ---------- System info ----------
|
|
- name: DSM version
|
|
ansible.builtin.shell: |
|
|
set -e
|
|
if [ -f /etc.defaults/VERSION ]; then
|
|
. /etc.defaults/VERSION
|
|
echo "${productversion:-unknown} (build ${buildnumber:-unknown})"
|
|
else
|
|
echo "unknown"
|
|
fi
|
|
register: dsm_version
|
|
changed_when: false
|
|
failed_when: false
|
|
|
|
- name: Uptime (pretty)
|
|
ansible.builtin.command: uptime -p
|
|
register: uptime_pretty
|
|
changed_when: false
|
|
failed_when: false
|
|
|
|
- name: Load averages
|
|
ansible.builtin.command: cat /proc/loadavg
|
|
register: loadavg
|
|
changed_when: false
|
|
failed_when: false
|
|
|
|
- name: Memory summary (MB)
|
|
ansible.builtin.command: free -m
|
|
register: mem
|
|
changed_when: false
|
|
failed_when: false
|
|
|
|
# ---------- Storage ----------
|
|
- name: Disk usage of root (/)
|
|
ansible.builtin.shell: df -P / | awk 'NR==2 {print $5}' | tr -d '%'
|
|
register: root_usage
|
|
changed_when: false
|
|
failed_when: false
|
|
|
|
- name: Disk usage of /volume1 (if present)
|
|
ansible.builtin.shell: |
|
|
if mountpoint -q /volume1; then
|
|
df -P /volume1 | awk 'NR==2 {print $5}' | tr -d '%'
|
|
fi
|
|
register: vol1_usage
|
|
changed_when: false
|
|
failed_when: false
|
|
|
|
- name: RAID status (/proc/mdstat)
|
|
ansible.builtin.command: cat /proc/mdstat
|
|
register: mdstat
|
|
changed_when: false
|
|
failed_when: false
|
|
|
|
# ---------- Tailscale (optional) ----------
|
|
- name: Detect Tailscale binary path (first that exists)
|
|
ansible.builtin.shell: |
|
|
for p in {{ ts_candidates | join(' ') }}; do
|
|
[ -x "$p" ] && echo "$p" && exit 0
|
|
done
|
|
echo ""
|
|
register: ts_bin
|
|
changed_when: false
|
|
failed_when: false
|
|
|
|
- name: Get Tailscale IPv4 (if tailscale present)
|
|
ansible.builtin.command: "{{ ts_bin.stdout }} ip -4"
|
|
register: ts_ip
|
|
changed_when: false
|
|
failed_when: false
|
|
when: ts_bin.stdout | length > 0
|
|
|
|
- name: Get Tailscale self status (brief)
|
|
ansible.builtin.command: "{{ ts_bin.stdout }} status --self"
|
|
register: ts_status
|
|
changed_when: false
|
|
failed_when: false
|
|
when: ts_bin.stdout | length > 0
|
|
|
|
# ---------- Assertions (lightweight, no sudo) ----------
|
|
- name: Check RAID not degraded/resyncing
|
|
ansible.builtin.assert:
|
|
that:
|
|
- mdstat.stdout is not search('degraded', ignorecase=True)
|
|
- mdstat.stdout is not search('resync', ignorecase=True)
|
|
success_msg: "RAID OK"
|
|
fail_msg: "RAID issue detected (degraded or resync) — check Storage Manager"
|
|
changed_when: false
|
|
|
|
- name: Check root FS usage < 90%
|
|
ansible.builtin.assert:
|
|
that:
|
|
- (root_usage.stdout | default('0')) | int < 90
|
|
success_msg: "Root filesystem usage OK ({{ root_usage.stdout | default('n/a') }}%)"
|
|
fail_msg: "Root filesystem high ({{ root_usage.stdout | default('n/a') }}%)"
|
|
changed_when: false
|
|
|
|
- name: Check /volume1 usage < 90% (if present)
|
|
ansible.builtin.assert:
|
|
that:
|
|
- (vol1_usage.stdout | default('0')) | int < 90
|
|
success_msg: "/volume1 usage OK ({{ vol1_usage.stdout | default('n/a') }}%)"
|
|
fail_msg: "/volume1 usage high ({{ vol1_usage.stdout | default('n/a') }}%)"
|
|
when: vol1_usage.stdout is defined and vol1_usage.stdout != ""
|
|
changed_when: false
|
|
|
|
# ---------- Summary (shows the results) ----------
|
|
- name: Summary
|
|
ansible.builtin.debug:
|
|
msg: |
|
|
Host: {{ inventory_hostname }}
|
|
DSM: {{ dsm_version.stdout | default('unknown') }}
|
|
Uptime: {{ uptime_pretty.stdout | default('n/a') }}
|
|
Load: {{ loadavg.stdout | default('n/a') }}
|
|
Memory (MB):
|
|
{{ (mem.stdout | default('n/a')) | indent(2) }}
|
|
Root usage: {{ root_usage.stdout | default('n/a') }}%
|
|
Volume1 usage: {{ (vol1_usage.stdout | default('n/a')) if (vol1_usage.stdout is defined and vol1_usage.stdout != "") else 'n/a' }}%
|
|
RAID (/proc/mdstat):
|
|
{{ (mdstat.stdout | default('n/a')) | indent(2) }}
|
|
Tailscale:
|
|
binary: {{ (ts_bin.stdout | default('not found')) if ts_bin.stdout|length > 0 else 'not found' }}
|
|
ip: {{ ts_ip.stdout | default('n/a') }}
|
|
self:
|
|
{{ (ts_status.stdout | default('n/a')) | indent(2) }}
|