Set-OPS-Public/playbooks/backup/restauration.yml

122 lines
5.3 KiB
YAML
Raw Normal View History

---
# L'ETAT D'UNE INCARNATION PRECEDENTE — voir roles/client_backup/templates/restaurer.sh.j2
#
# make restauration-etat [HOTE=...]
# ce qui attend dans le depot, et ce que chaque jeu est devenu (lecture seule) ;
# make sauvegarder-maintenant [HOTE=...]
# deposer TOUT DE SUITE, et attendre que ce soit fait. A faire juste avant `raser` :
# sinon la reconstruction remet l'etat de la derniere nuit, et perd la journee ;
# make temoins-etat [HOTE=...] [SOURCE=candidat]
# l'etat VIVANT est-il celui d'avant le rasage ? Compare a l'instantane etiquete
# « avant-raser » (lecture seule). Une perte, ou une identite changee (cles de l'AC,
# DKIM, instanceid, mot de passe d'une entree de l'annuaire), fait echouer le jeu ;
# make restauration-renoncer HOTE=<hote> JEU=<jeu> CONFIRMER=true
# ECARTER un etat anterieur sans le remettre. La sauvegarde du noeud, qui refusait
# de deposer pour ne pas le chasser de la retention, reprend — et l'etat d'avant
# finira par sortir de la retention. C'est une decision, pas une reparation.
#
# La REMISE, elle, n'a pas de cible : elle est faite par le role proprietaire de l'etat,
# au deploiement, au moment ou il le creerait neuf.
- name: L'etat d'une incarnation precedente
hosts: client_backup
become: true
gather_facts: false
vars:
restauration_action: etat
restauration_jeu: ""
restauration_source: avant-raser
tasks:
- name: Refuser un renoncement sans jeu nomme
ansible.builtin.assert:
that:
- restauration_jeu | length > 0
fail_msg: "JEU=<jeu> requis (voir `make restauration-etat` pour les noms)."
when: restauration_action == 'renoncer'
- name: Lire ce qui attend, et ce qui a ete tranche
ansible.builtin.command:
argv: [/usr/local/sbin/setops-restaurer, etat]
register: restauration_lue
changed_when: false
failed_when: false
when: restauration_action == 'etat'
- name: Etat
ansible.builtin.debug:
msg: "{{ (restauration_lue.stdout_lines | default([])) + (restauration_lue.stderr_lines | default([])) }}"
when: restauration_action == 'etat'
# L'unite est `oneshot` : `systemctl start` rend la main quand le depot est fait, et
# echoue s'il a echoue — y compris quand la garde refuse (etat d'avant non remis).
- name: Ce noeud a-t-il quelque chose a deposer ?
ansible.builtin.stat:
path: /etc/systemd/system/setops-sauvegarde.service
register: restauration_unite
when: restauration_action == 'sauvegarder'
# LE DEPOT D'AVANT RASAGE EST ETIQUETE (2026-10-07), et la retention le garde jusqu'a la
# reconstruction suivante. Un noeud qui n'a pas encore cette unite deposerait SANS
# etiquette, et la premiere sauvegarde d'apres reconstruction le chasserait : c'est
# exactement ce qui s'est passe a M4. On refuse plutot que de deposer a moitie.
- name: L'unite du depot d'avant rasage est-elle deployee ?
ansible.builtin.stat:
path: /etc/systemd/system/setops-sauvegarde-avant-raser.service
register: restauration_unite_avant_raser
when:
- restauration_action == 'sauvegarder'
- restauration_unite.stat.exists
- name: Refuser un depot que la retention ne garderait pas
ansible.builtin.assert:
that:
- restauration_unite_avant_raser.stat.exists
fail_msg: >-
setops-sauvegarde-avant-raser.service absente : redeployer client_backup
(make appliquer GROUPE=client_backup) avant de raser.
when:
- restauration_action == 'sauvegarder'
- restauration_unite.stat.exists
- name: Deposer maintenant, etiquete avant rasage
ansible.builtin.systemd:
name: setops-sauvegarde-avant-raser.service
state: started
when:
- restauration_action == 'sauvegarder'
- restauration_unite.stat.exists
# Code 4 = rien a comparer (aucun etat, ou aucun instantane d'avant rasage) : ce n'est
# pas un echec. Code 1 = ecart : on affiche d'abord, on echoue ensuite.
- name: Temoins — l'etat vivant contre l'instantane d'avant rasage
ansible.builtin.command:
argv: >-
{{ ['/usr/local/sbin/setops-restaurer', 'temoins']
+ (['--candidat'] if restauration_source == 'candidat' else []) }}
register: restauration_temoins
changed_when: false
failed_when: false
when: restauration_action == 'temoins'
- name: Temoins
ansible.builtin.debug:
msg: "{{ (restauration_temoins.stdout_lines | default([])) + (restauration_temoins.stderr_lines | default([])) }}"
when: restauration_action == 'temoins'
- name: Temoins — verdict
ansible.builtin.assert:
that:
- restauration_temoins.rc in [0, 4]
fail_msg: >-
{{ 'ECART : une perte, ou une identite changee (voir ci-dessus).'
if restauration_temoins.rc == 1 else
'setops-restaurer temoins a echoue (code ' ~ restauration_temoins.rc ~ ') : '
~ 'client_backup est-il deploye ?' }}
quiet: true
when: restauration_action == 'temoins'
- name: Ecarter l'etat anterieur de ce jeu
ansible.builtin.command:
argv: [/usr/local/sbin/setops-restaurer, acter, "{{ restauration_jeu }}", abandonne]
changed_when: true
when: restauration_action == 'renoncer'