semaphore/synology_upgrade_ssh.yml

199 lines
6.5 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.

---
- name: Synology DSM - télécharger puis installer une mise à jour via SSH (auto-detect synoupgrade)
hosts: synology
gather_facts: false
vars:
# Temps max (en secondes) pour attendre download / reboot
download_timeout: 3600
reboot_timeout: 1800
poll_delay: 20
# Chemins probables (DSM varie selon versions/modèles)
synoupgrade_candidates:
- "/usr/syno/sbin/synoupgrade"
- "/usr/syno/bin/synoupgrade"
- "/sbin/synoupgrade"
- "/bin/synoupgrade"
- "/usr/bin/synoupgrade"
- "/usr/sbin/synoupgrade"
- "/usr/syno/sbin/synoupgrade2"
- "/usr/syno/bin/synoupgrade2"
- "/usr/bin/synoupgrade2"
- "/usr/sbin/synoupgrade2"
# Commandes possibles pour lancer linstall (selon DSM)
start_subcommands:
- "--start"
- "--upgrade"
- "--apply"
- "--run"
- "--install"
tasks:
# 0) Détecter le binaire présent
- name: Détecter synoupgrade (ou synoupgrade2) sur le NAS
ansible.builtin.raw: |
set -e
FOUND=""
for p in {{ synoupgrade_candidates | join(' ') }}; do
if [ -x "$p" ]; then
FOUND="$p"
break
fi
done
# fallback: PATH (busybox)
if [ -z "$FOUND" ]; then
if command -v synoupgrade >/dev/null 2>&1; then
FOUND="$(command -v synoupgrade)"
elif command -v synoupgrade2 >/dev/null 2>&1; then
FOUND="$(command -v synoupgrade2)"
fi
fi
if [ -n "$FOUND" ]; then
echo "FOUND=$FOUND"
exit 0
else
echo "FOUND="
exit 0
fi
register: detect
changed_when: false
- name: Enregistrer le chemin synoupgrade détecté
ansible.builtin.set_fact:
synoupgrade_bin: "{{ (detect.stdout | regex_search('FOUND=(.*)', '\\1')) | default('') | trim }}"
changed_when: false
- name: Fail si synoupgrade introuvable
ansible.builtin.fail:
msg: >-
synoupgrade introuvable sur ce NAS (DSM/ modèle).
stdout: {{ detect.stdout | default('') }}
=> Donne-moi la sortie de : "ls -l /usr/syno/sbin /usr/syno/bin | grep -i upgrad"
when: synoupgrade_bin == ""
- name: Afficher le binaire trouvé
ansible.builtin.debug:
msg: "synoupgrade utilisé: {{ synoupgrade_bin }}"
# 1) Check mise à jour dispo
- name: Check mise à jour disponible
ansible.builtin.raw: "{{ synoupgrade_bin }} --check || true"
register: check_out
changed_when: false
- name: Afficher le résultat du check
ansible.builtin.debug:
var: check_out.stdout_lines
# Heuristique : stop si rien
- name: Stop si aucune mise à jour détectée (heuristique)
ansible.builtin.meta: end_play
when: >
(check_out.stdout | lower) is search('no update')
or (check_out.stdout | lower) is search('no newer')
or (check_out.stdout | lower) is search('already')
or (check_out.stdout | lower) is search('up to date')
# 2) Download
- name: Lancer le téléchargement
ansible.builtin.raw: "{{ synoupgrade_bin }} --download"
register: download_start
changed_when: true
- name: Afficher retour download start
ansible.builtin.debug:
var: download_start.stdout_lines
# 3) Attendre fin download (status ou log)
- name: Attendre fin du téléchargement (poll status/log)
ansible.builtin.raw: |
set -e
if {{ synoupgrade_bin }} --status >/dev/null 2>&1; then
{{ synoupgrade_bin }} --status || true
else
(tail -n 80 /var/log/synoupgrade.log 2>/dev/null || true)
(tail -n 120 /var/log/messages 2>/dev/null | grep -i upgrad || true)
fi
register: dl_poll
changed_when: false
until: >
(dl_poll.stdout | lower) is search('downloaded')
or (dl_poll.stdout | lower) is search('ready')
or (dl_poll.stdout | lower) is search('finish')
or (dl_poll.stdout | lower) is search('completed')
or (dl_poll.stdout | lower) is search('done')
retries: "{{ (download_timeout // poll_delay) | int }}"
delay: "{{ poll_delay }}"
- name: Afficher statut fin téléchargement
ansible.builtin.debug:
var: dl_poll.stdout_lines
# 4) Démarrer installation (essais)
- name: Tenter de démarrer l'installation (plusieurs sous-commandes)
ansible.builtin.raw: "{{ synoupgrade_bin }} {{ item }} || true"
loop: "{{ start_subcommands }}"
register: start_attempts
changed_when: true
failed_when: false
- name: Choisir la première tentative qui ne ressemble pas à une erreur
ansible.builtin.set_fact:
start_ok: >-
{{
(start_attempts.results
| rejectattr('stdout', 'search', '(?i)(invalid|unknown|usage|not found|permission|error|failed)')
| rejectattr('stderr', 'search', '(?i)(invalid|unknown|usage|not found|permission|error|failed)')
| list
| first) | default({})
}}
- name: Fail si aucune commande de démarrage ne marche
ansible.builtin.fail:
msg: >-
Impossible de démarrer l'installation via synoupgrade.
stdout: {{ start_attempts.results | map(attribute='stdout') | list }}
stderr: {{ start_attempts.results | map(attribute='stderr') | list }}
when: start_ok | length == 0
- name: Afficher la commande start retenue
ansible.builtin.debug:
msg:
- "Commande retenue: {{ start_ok.item }}"
- "stdout: {{ start_ok.stdout | default('') }}"
- "stderr: {{ start_ok.stderr | default('') }}"
# 5) Attente reboot : le NAS peut couper SSH
- name: Attendre que le NAS coupe SSH (reboot probable)
ansible.builtin.wait_for:
host: "{{ inventory_hostname }}"
port: 22
state: drained
timeout: 300
delegate_to: localhost
- name: Attendre le retour SSH
ansible.builtin.wait_for:
host: "{{ inventory_hostname }}"
port: 22
state: started
timeout: "{{ reboot_timeout }}"
delegate_to: localhost
# 6) Post-check
- name: Post-check version / statut
ansible.builtin.raw: |
uname -a || true
cat /etc/VERSION 2>/dev/null || true
{{ synoupgrade_bin }} --status 2>/dev/null || true
register: post
changed_when: false
- name: Afficher post-check
ansible.builtin.debug:
var: post.stdout_lines