From 8ff8832f85b54c11cbd6044607736eec7491644d Mon Sep 17 00:00:00 2001 From: "Ivo C.S. Wingelaar" Date: Sun, 13 Oct 2024 19:34:14 +0200 Subject: [PATCH] Add simple NFS backup role --- roles/backup_nfs/defaults/main.yml | 3 ++ roles/backup_nfs/tasks/machinectl.yml | 6 ++++ roles/backup_nfs/tasks/main.yml | 40 ++++++++++++++++++++++++ roles/backup_nfs/tasks/per-container.yml | 24 ++++++++++++++ roles/backup_nfs/tasks/per-user.yml | 8 +++++ 5 files changed, 81 insertions(+) create mode 100644 roles/backup_nfs/defaults/main.yml create mode 100644 roles/backup_nfs/tasks/machinectl.yml create mode 100644 roles/backup_nfs/tasks/main.yml create mode 100644 roles/backup_nfs/tasks/per-container.yml create mode 100644 roles/backup_nfs/tasks/per-user.yml diff --git a/roles/backup_nfs/defaults/main.yml b/roles/backup_nfs/defaults/main.yml new file mode 100644 index 0000000..15d7595 --- /dev/null +++ b/roles/backup_nfs/defaults/main.yml @@ -0,0 +1,3 @@ +--- +backup_nfs_directory: /podman-nfs-backups +backup_nfs_mountpoint: /opt/podman-nfs-backups diff --git a/roles/backup_nfs/tasks/machinectl.yml b/roles/backup_nfs/tasks/machinectl.yml new file mode 100644 index 0000000..786a0b1 --- /dev/null +++ b/roles/backup_nfs/tasks/machinectl.yml @@ -0,0 +1,6 @@ +--- +- name: Import per-user tasks + ansible.builtin.import_tasks: per-user.yml + become_method: community.general.machinectl + become_user: "{{ backup_nfs_users['user'] }}" + become: true diff --git a/roles/backup_nfs/tasks/main.yml b/roles/backup_nfs/tasks/main.yml new file mode 100644 index 0000000..13977b8 --- /dev/null +++ b/roles/backup_nfs/tasks/main.yml @@ -0,0 +1,40 @@ +--- +- name: Install NFS client software + ansible.builtin.apt: + name: nfs-common + state: present + +- name: Check existence of mount directory + ansible.builtin.stat: + path: "{{ backup_nfs_mountpoint }}" + register: mountpoint + +- name: Create mountpoint if it does not exist + ansible.builtin.file: + path: "{{ backup_nfs_mountpoint }}" + state: directory + mode: "0700" + owner: root + group: root + when: not mountpoint.stat.exists + +- name: This block ensures the NFS directory will be unmounted if a task fails + block: + - name: Mount backup NFS directory + ansible.posix.mount: + src: "{{ backup_nfs_remote }}:{{ backup_nfs_directory }}" + path: "{{ backup_nfs_mountpoint }}" + opts: rw,sync,hard,vers=4 + state: ephemeral + fstype: nfs + + - name: Execute backup tasks inside service account + ansible.builtin.include_tasks: machinectl.yml + loop: "{{ backup_nfs_targets }}" + loop_control: + loop_var: backup_nfs_users + always: + - name: Unmount backup NFS directory + ansible.posix.mount: + path: "{{ backup_nfs_mountpoint }}" + state: unmounted diff --git a/roles/backup_nfs/tasks/per-container.yml b/roles/backup_nfs/tasks/per-container.yml new file mode 100644 index 0000000..d0f5067 --- /dev/null +++ b/roles/backup_nfs/tasks/per-container.yml @@ -0,0 +1,24 @@ +--- +- name: Ensure container is stopped + ansible.builtin.systemd_service: + name: container-{{ container }}.service + state: stopped + scope: user + register: container_state + +- name: Create volume export + containers.podman.podman_export: + volume: "{{ item }}" + dest: "{{ backup_nfs_mountpoint }}/{{ container }}-{{ item }}-{{ ansible_date_time['iso8601_basic_short'] }}.tar" + loop: "{{ backup_nfs_containers['volumes'] }}" + +# A container is not always running, so if it was stopped before +# the backup procedure even started, do not start it again. +# It's quite a hassle to have this behaviour with a handler, so +# we just supress the linting error. +- name: Start container again if necessary # noqa: no-handler + ansible.builtin.systemd_service: + name: container-{{ container }}.service + state: started + scope: user + when: container_state is changed diff --git a/roles/backup_nfs/tasks/per-user.yml b/roles/backup_nfs/tasks/per-user.yml new file mode 100644 index 0000000..fb8acd7 --- /dev/null +++ b/roles/backup_nfs/tasks/per-user.yml @@ -0,0 +1,8 @@ +--- +- name: Iterate over configured nginx sites + ansible.builtin.include_tasks: per-container.yml + loop: "{{ backup_nfs_users['containers'] }}" + loop_control: + loop_var: backup_nfs_containers + vars: + container: "{{ backup_nfs_containers['name'] }}"