133 lines
5.1 KiB
YAML
133 lines
5.1 KiB
YAML
|
|
---
|
||
|
|
# SORTIR LES SAUVEGARDES DU SITE, DU SITE.
|
||
|
|
#
|
||
|
|
# Le depot du site heberge trois choses irremplacables : la racine de son autorite de
|
||
|
|
# certification, la forge du genome, et l'etat de CHAQUE locataire. Tout cela vit sur une
|
||
|
|
# seule machine, dans un seul batiment. C'est le probleme du filet range dans la flotte
|
||
|
|
# qu'il protege — celui qu'on a mis deux jours a fermer pour Chezlepro — un etage plus haut.
|
||
|
|
#
|
||
|
|
# POURQUOI ON EMPORTE AUSSI LES DEPOTS DES LOCATAIRES. Si le site brule, les locataires
|
||
|
|
# perdent leurs sauvegardes avec lui, et EUX NE PEUVENT RIEN Y FAIRE : ils ont depose chez
|
||
|
|
# l'hebergeur, c'est a l'hebergeur de tenir cette promesse. 109 Mo au total — la question
|
||
|
|
# du volume ne se pose pas.
|
||
|
|
#
|
||
|
|
# CE QUE LE PORTEUR DE LA COPIE PEUT EN FAIRE : rien. Les depots sont chiffres par restic
|
||
|
|
# COTE CLIENT, avec des mots de passe qui vivent dans les voutes de chacun. Cette copie
|
||
|
|
# est un bloc opaque — c'est ce qui permet de la deposer chez un pair sans lui demander
|
||
|
|
# autre chose que de la disponibilite.
|
||
|
|
#
|
||
|
|
# ansible-playbook -i scripts/site_inventaire.py \
|
||
|
|
# playbooks/maintenance/depot-hors-site.yml -e vers=/media/…/setops-coffre
|
||
|
|
- name: Copier le depot du site hors du site
|
||
|
|
hosts: serveur_backup_site
|
||
|
|
gather_facts: false
|
||
|
|
become: true
|
||
|
|
|
||
|
|
vars:
|
||
|
|
racine: "{{ serveur_backup_site_parent | default('/srv/restic') }}"
|
||
|
|
|
||
|
|
pre_tasks:
|
||
|
|
- name: Exiger une destination
|
||
|
|
ansible.builtin.assert:
|
||
|
|
that:
|
||
|
|
- vers is defined
|
||
|
|
- vers | length > 0
|
||
|
|
fail_msg: >-
|
||
|
|
`-e vers=<repertoire>` requis. Viser un support amovible ou une machine tierce.
|
||
|
|
delegate_to: localhost
|
||
|
|
become: false
|
||
|
|
|
||
|
|
# UNE COPIE DANS L'INFRASTRUCTURE NE PROTEGE DE RIEN — elle boucle. Meme raisonnement
|
||
|
|
# que pour les cles : un coffre range dans ce qu'il protege n'est pas un coffre.
|
||
|
|
- name: Refuser une destination interne
|
||
|
|
ansible.builtin.assert:
|
||
|
|
that:
|
||
|
|
- not (vers is search('/srv/restic'))
|
||
|
|
- not (vers is search('Espace Chezlepro'))
|
||
|
|
fail_msg: >-
|
||
|
|
{{ vers }} est DANS l'infrastructure. Une copie qui partage le sort de
|
||
|
|
l'original ne protege de rien.
|
||
|
|
delegate_to: localhost
|
||
|
|
become: false
|
||
|
|
|
||
|
|
- name: La destination existe-t-elle ?
|
||
|
|
ansible.builtin.stat:
|
||
|
|
path: "{{ vers }}"
|
||
|
|
delegate_to: localhost
|
||
|
|
become: false
|
||
|
|
register: dest_etat
|
||
|
|
|
||
|
|
- name: Exiger une destination reelle
|
||
|
|
ansible.builtin.assert:
|
||
|
|
that:
|
||
|
|
- dest_etat.stat.exists
|
||
|
|
- dest_etat.stat.isdir
|
||
|
|
fail_msg: "{{ vers }} n'existe pas ou n'est pas un repertoire. Support monte ?"
|
||
|
|
delegate_to: localhost
|
||
|
|
become: false
|
||
|
|
|
||
|
|
tasks:
|
||
|
|
# L'EMPREINTE EST PRISE A LA SOURCE, AVANT LA COPIE. La comparer apres coup a une
|
||
|
|
# empreinte calculee sur la copie est la seule facon de savoir qu'on a emporte ce
|
||
|
|
# qu'on croit avoir emporte. Sans ca, on rentre chez soi avec un repertoire.
|
||
|
|
- name: Empreinte de ce qui est a la source
|
||
|
|
ansible.builtin.shell:
|
||
|
|
executable: /bin/bash
|
||
|
|
cmd: >-
|
||
|
|
set -o pipefail;
|
||
|
|
find {{ racine }} -type f -print0 | sort -z |
|
||
|
|
xargs -0 sha256sum | sed 's| {{ racine }}/| |'
|
||
|
|
register: empreinte_source
|
||
|
|
changed_when: false
|
||
|
|
|
||
|
|
- name: Combien, et quelle taille
|
||
|
|
ansible.builtin.shell:
|
||
|
|
executable: /bin/bash
|
||
|
|
cmd: "set -o pipefail; du -sb {{ racine }} | cut -f1"
|
||
|
|
register: taille_source
|
||
|
|
changed_when: false
|
||
|
|
|
||
|
|
- name: Copier vers la destination
|
||
|
|
ansible.posix.synchronize:
|
||
|
|
src: "{{ racine }}/"
|
||
|
|
dest: "{{ vers }}/depot-du-site/"
|
||
|
|
mode: pull
|
||
|
|
archive: true
|
||
|
|
delete: true
|
||
|
|
become: false
|
||
|
|
|
||
|
|
- name: Empreinte de ce qui est arrive
|
||
|
|
ansible.builtin.shell:
|
||
|
|
executable: /bin/bash
|
||
|
|
cmd: >-
|
||
|
|
set -o pipefail;
|
||
|
|
find {{ vers }}/depot-du-site -type f -print0 | sort -z |
|
||
|
|
xargs -0 sha256sum | sed 's| {{ vers }}/depot-du-site/| |'
|
||
|
|
delegate_to: localhost
|
||
|
|
become: false
|
||
|
|
register: empreinte_copie
|
||
|
|
changed_when: false
|
||
|
|
|
||
|
|
- name: Exiger une copie fidele
|
||
|
|
ansible.builtin.assert:
|
||
|
|
that:
|
||
|
|
- empreinte_source.stdout == empreinte_copie.stdout
|
||
|
|
fail_msg: >-
|
||
|
|
LA COPIE DIFFERE DE LA SOURCE.
|
||
|
|
Source : {{ empreinte_source.stdout_lines | length }} fichier(s).
|
||
|
|
Copie : {{ empreinte_copie.stdout_lines | length }} fichier(s).
|
||
|
|
Ne pas s'en servir : une copie qu'on croit fidele et qui ne l'est pas est pire
|
||
|
|
qu'aucune copie.
|
||
|
|
success_msg: >-
|
||
|
|
COPIE FIDELE : {{ empreinte_source.stdout_lines | length }} fichier(s),
|
||
|
|
{{ (taille_source.stdout | int / 1048576) | round(1) }} Mo, empreintes
|
||
|
|
identiques une a une.
|
||
|
|
|
||
|
|
- name: Ce qu'il reste a faire, et qui n'est pas facultatif
|
||
|
|
ansible.builtin.debug:
|
||
|
|
msg:
|
||
|
|
- "La copie est OPAQUE : chiffree cote client, illisible par qui la porte."
|
||
|
|
- "Elle ne vaut que si elle vit AILLEURS que le site — un tiroir a cote du"
|
||
|
|
- "serveur ne protege que du disque, pas de l'incendie ni du vol."
|
||
|
|
- "A refaire quand l'etat change. `restic` ne recopie que les differences."
|