semaphore/synology_upgrade_ssh.yml

147 lines
5.2 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 (synoupgrade)
hosts: synology
gather_facts: false
vars:
# Chemin habituel sur Synology
synoupgrade_bin: "/usr/syno/sbin/synoupgrade"
# Temps max (en secondes) pour attendre download / reboot
download_timeout: 3600
reboot_timeout: 1200
poll_delay: 20
# Certaines versions DSM n'ont pas exactement les mêmes options,
# on essaie plusieurs commandes possibles pour démarrer l'upgrade.
upgrade_start_cmds:
- "{{ synoupgrade_bin }} --start"
- "{{ synoupgrade_bin }} --upgrade"
- "{{ synoupgrade_bin }} --apply"
- "{{ synoupgrade_bin }} --run"
- "{{ synoupgrade_bin }} --install"
tasks:
- name: Vérifier que synoupgrade existe
ansible.builtin.raw: "test -x {{ synoupgrade_bin }} && echo OK || echo MISSING"
register: synoupgrade_exists
changed_when: false
failed_when: "'MISSING' in synoupgrade_exists.stdout"
- name: Check mise à jour disponible (synoupgrade --check)
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 : si "no update" / "no newer version" etc, on stop proprement.
- 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 up')
or (check_out.stdout | lower) is search('up to date')
- name: Lancer le téléchargement (synoupgrade --download)
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
# Suivi du téléchargement : selon DSM, --status peut exister ou pas.
# On fait un poll best-effort sur --status, sinon on se base sur le 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
# fallback log courant (chemins variables selon DSM)
(tail -n 60 /var/log/synoupgrade.log 2>/dev/null || true)
(tail -n 60 /var/log/messages 2>/dev/null | grep -i synoupgrade || 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
# Démarrage de l'upgrade : on teste plusieurs commandes.
- name: Démarrer l'installation DSM (essais multi-commandes)
ansible.builtin.raw: "{{ item }}"
loop: "{{ upgrade_start_cmds }}"
register: start_attempts
changed_when: true
failed_when: false
- name: Choisir la première commande start qui a l'air OK
ansible.builtin.set_fact:
start_ok: >-
{{
(start_attempts.results
| rejectattr('stdout', 'search', '(?i)(invalid|unknown|usage|not found|error)')
| list
| first) | default({})
}}
- name: Fail si aucune commande start ne fonctionne
ansible.builtin.fail:
msg: >-
Impossible de démarrer l'installation via synoupgrade.
Sorties:
{{ start_attempts.results | map(attribute='stdout') | 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('') }}"
# Beaucoup de Synology rebootent pendant/après lupgrade.
# On attend que SSH tombe puis revienne.
- name: Attendre que le NAS coupe SSH (reboot en cours)
ansible.builtin.wait_for:
host: "{{ inventory_hostname }}"
port: 22
state: drained
timeout: 300
delegate_to: localhost
- name: Attendre le retour SSH (après reboot)
ansible.builtin.wait_for:
host: "{{ inventory_hostname }}"
port: 22
state: started
timeout: "{{ reboot_timeout }}"
delegate_to: localhost
- name: Re-check version / statut après reboot (best effort)
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