diff --git a/synology_dsm_upgrade_api.yml b/synology_dsm_upgrade_api.yml index d130141..5e9ad21 100644 --- a/synology_dsm_upgrade_api.yml +++ b/synology_dsm_upgrade_api.yml @@ -14,13 +14,20 @@ refuse_if_no_upgrade_api: true - # méthodes candidates (DSM varie) + # Méthodes candidates (DSM varie selon versions) upgrade_status_methods: - "status" - "get" - "check" + + # Méthode "start" pour déclencher l'upgrade upgrade_start_method: "start" + # Attente reboot (sec) + reboot_wait_timeout: 1800 # 30 min + reboot_down_timeout: 300 # 5 min + reboot_up_timeout: 1800 # 30 min + tasks: - name: Construire base_url ansible.builtin.set_fact: @@ -118,15 +125,6 @@ | first) | default({}) }} - - name: Afficher les réponses status (debug) - ansible.builtin.debug: - var: upgrade_status_attempts.results - - - name: Afficher statut retenu (debug) - ansible.builtin.debug: - var: upgrade_status.json - when: upgrade_status | length > 0 - - name: Fail si aucune méthode status n'a fonctionné ansible.builtin.fail: msg: >- @@ -134,17 +132,25 @@ Vérifie les méthodes supportées (status/get/check) sur ce DSM. when: upgrade_status | length == 0 - # ---- START : seulement si "ready" (on ne devine pas : on log l’état) ---- - - name: Déterminer si une mise à jour semble prête (heuristique) + - name: Debug - statut retenu + ansible.builtin.debug: + var: upgrade_status.json + + # ---- READY CHECK (inclut ton cas "ready_upgrade") ---- + - name: Déterminer si une mise à jour est prête ansible.builtin.set_fact: upgrade_ready: >- {{ ( (upgrade_status.json.data is defined) and ( - (upgrade_status.json.data.ready is defined and upgrade_status.json.data.ready | bool) - or (upgrade_status.json.data.need_update is defined and upgrade_status.json.data.need_update | bool == false) - or (upgrade_status.json.data.status is defined and (upgrade_status.json.data.status|string) in ['ready','downloaded','prepared']) + (upgrade_status.json.data.allow_upgrade is defined and upgrade_status.json.data.allow_upgrade | bool) + and ( + (upgrade_status.json.data.status is defined and (upgrade_status.json.data.status|string) in + ['ready','downloaded','prepared','ready_upgrade'] + ) + or (upgrade_status.json.data.ready is defined and upgrade_status.json.data.ready | bool) + ) ) ) | default(false) }} @@ -152,7 +158,7 @@ - name: Stop si pas prête (évite code 103) + message clair ansible.builtin.fail: msg: >- - DSM refuse le start (souvent code 103) car la mise à jour n’est pas "prête". + DSM n'est pas prêt à lancer l'upgrade via API (souvent code 103 si on force). Vérifie sur DSM: Panneau de config > Mise à jour DSM : - téléchargement terminé - EULA/consentement accepté @@ -160,27 +166,54 @@ Statut API (data): {{ upgrade_status.json.data | default({}) | to_nice_json }} when: not upgrade_ready - - name: Start DSM upgrade (SYNO.Core.Upgrade) + # ---- START (POST form-urlencoded, plus fiable) ---- + - name: Start DSM upgrade (SYNO.Core.Upgrade start) ansible.builtin.uri: - url: "{{ base_url }}/webapi/{{ upgrade_path }}?api=SYNO.Core.Upgrade&version={{ upgrade_ver }}&method={{ upgrade_start_method }}&_sid={{ sid }}" - method: GET + url: "{{ base_url }}/webapi/{{ upgrade_path }}" + method: POST validate_certs: "{{ syno_verify_ssl }}" return_content: true status_code: 200 timeout: "{{ uri_timeout }}" + body_format: form-urlencoded + body: + api: SYNO.Core.Upgrade + version: "{{ upgrade_ver }}" + method: "{{ upgrade_start_method }}" + _sid: "{{ sid }}" register: upgrade_start - - name: Fail si start a échoué + - name: Fail si start a échoué (message lisible) ansible.builtin.fail: msg: >- Echec du démarrage upgrade DSM via API. - Réponse: {{ upgrade_start.json | to_nice_json }} - when: upgrade_start.json.success != true + Réponse: {{ upgrade_start.json | default(upgrade_start.content) }} + when: upgrade_start.json is not defined or upgrade_start.json.success is not defined or upgrade_start.json.success != true - name: Afficher résultat start ansible.builtin.debug: var: upgrade_start.json + # ---- WAIT REBOOT (si DSM indique reboot:true, on attend la chute + le retour) ---- + - name: Attendre que DSM tombe (reboot en cours) + ansible.builtin.wait_for: + host: "{{ inventory_hostname }}" + port: "{{ syno_port }}" + state: stopped + timeout: "{{ reboot_down_timeout }}" + delegate_to: localhost + when: upgrade_status.json.data.reboot is defined and upgrade_status.json.data.reboot | bool + + - name: Attendre le retour de DSM (port 5001) + ansible.builtin.wait_for: + host: "{{ inventory_hostname }}" + port: "{{ syno_port }}" + state: started + delay: 10 + timeout: "{{ reboot_up_timeout }}" + delegate_to: localhost + when: upgrade_status.json.data.reboot is defined and upgrade_status.json.data.reboot | bool + - name: Logout DSM API ansible.builtin.uri: url: "{{ base_url }}/webapi/{{ auth_path }}?api=SYNO.API.Auth&version=2&method=logout&session={{ syno_session | urlencode }}&_sid={{ sid }}" @@ -190,4 +223,4 @@ status_code: 200 timeout: "{{ uri_timeout }}" register: logout - failed_when: false \ No newline at end of file + failed_when: false