Loading Ansible/roles/debian_server/files/dvb 0 → 100755 +77 −0 Original line number Diff line number Diff line #!/bin/sh set -eu # Cleanup of snapshots, added as trap so it's always executed even in case of a # failure or ctrl+c. cleanup () { btrfs subvolume delete "$snapshot" } usage () { echo "Usage: $(basename "$0") DESTINATION" >&2 exit 1 } get_mountpoint () { df --output=target "$1" | tail +2 } get_snapshot () { name="$1" mountpoint="$(docker volume inspect --format '{{ .Mountpoint }}' "$name" )" snapshot="$(dirname "$mountpoint")/snapshot)" echo "$snapshot" } if [ "$#" -ne 1 ] then usage elif [ ! -d "$1" ] then echo "Destinaton $1 not found or is not a directory." >&2 exit 1 elif [ "$(id -u)" -ne 0 ] then echo "This program must run as root." >&2 exit 1 elif ! command -v btrfs >/dev/null then echo 'btrfs-progs must be installed.' >&2 exit 1 elif ! docker info --format '{{ .ServerVersion }}' >/dev/null then echo 'Docker must be installed and running.' >&2 exit 1 elif ! df --type=btrfs /var/lib/docker/volumes >/dev/null then echo "Docker volumes are not on a btrfs filesystem." >&2 exit 1 elif ! df --type=btrfs "$1" >/dev/null then echo "Destination $1 is not on a btrfs filesystem." >&2 exit 1 elif [ "$(df --output=target /var/lib/docker/volumes)" != "$(df --output=target "$1")" ] then echo "The destination $1 is not on the same btrfs volume as the Docker volumes." >&2 exit 1 elif [ -z "$(docker volume ls --filter label=snapshot=true --format '{{ .Name }}')" ] then echo "No Docker volumes marked for backup, exiting." >&2 exit 1 fi dest="$1" root_volume="$(get_mountpoint /var/lib/docker/volumes)" snapshot="$(mktemp --dry-run "--tmpdir=$root_volume")" trap 'cleanup' INT QUIT EXIT TERM btrfs subvolume snapshot "$root_volume" "$snapshot" for name in $(docker volume ls --filter label=snapshot=true --format '{{ .Name }}') do echo "Backing up $name." mountpoint="$(docker volume inspect --format '{{ .Mountpoint }}' "$name")" src="$snapshot/${mountpoint#$root_volume/}" # shellcheck disable=SC2115 [ ! -e "$dest/$name" ] || rm -rf "$dest/$name" cp --archive --force --reflink=always "$src" "$dest/$name" done Ansible/roles/debian_server/files/dvb.service 0 → 100644 +9 −0 Original line number Diff line number Diff line # vim: filetype=systemd [Unit] Description=Docker volume backup (dvb) ConditionACPower=true After=local-fs.target [Service] Type=exec ExecStart=dvb /var/backups/docker-volumes Ansible/roles/debian_server/files/dvb.timer 0 → 100644 +10 −0 Original line number Diff line number Diff line # vim: filetype=systemd [Unit] Description=Docker volume backup (dvb) [Timer] OnCalendar=weekly RandomizedDelaySec=21600 [Install] WantedBy=multi-user.target Ansible/roles/debian_server/tasks/btrfs.yml +4 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,8 @@ {{ (ansible_facts.mounts|selectattr("device", "equalto", device)|first)["mount"] }} # yamllint enable rule:line-length tags: [scrub] notify: - Systemd daemon reload - name: Enable btrfs scrub timers ansible.builtin.systemd: Loading @@ -46,6 +48,8 @@ mode: 0o0644 src: btrfs_check.{{ item }}.j2 vars: *vars notify: - Systemd daemon reload - name: Enable the btrfs check timers ansible.builtin.systemd: Loading Ansible/roles/debian_server/tasks/docker.yml +33 −0 Original line number Diff line number Diff line Loading @@ -37,6 +37,7 @@ mode: 0o0644 notify: - Systemd daemon reload - Restart Docker - name: Allow access from the toolbox container ansible.builtin.copy: Loading @@ -54,3 +55,35 @@ direction: in interface: docker0 rule: allow - name: Create the Docker volume backup destination directory ansible.builtin.file: group: backup mode: 0o0750 owner: root path: /var/backups/docker-volumes state: directory - name: Copy the Docker volume backup script ansible.builtin.copy: dest: /usr/local/bin/ mode: preserve src: dvb - name: Copy the Docker volume backup service and timer loop: - service - timer ansible.builtin.copy: dest: /etc/systemd/system/dvb.{{ item }} mode: 0o0644 src: dvb.{{ item }} notify: - Systemd daemon reload - name: Enable the Docker volume backup timer ansible.builtin.systemd: enabled: true name: dvb.timer notify: - Systemd daemon reload Loading
Ansible/roles/debian_server/files/dvb 0 → 100755 +77 −0 Original line number Diff line number Diff line #!/bin/sh set -eu # Cleanup of snapshots, added as trap so it's always executed even in case of a # failure or ctrl+c. cleanup () { btrfs subvolume delete "$snapshot" } usage () { echo "Usage: $(basename "$0") DESTINATION" >&2 exit 1 } get_mountpoint () { df --output=target "$1" | tail +2 } get_snapshot () { name="$1" mountpoint="$(docker volume inspect --format '{{ .Mountpoint }}' "$name" )" snapshot="$(dirname "$mountpoint")/snapshot)" echo "$snapshot" } if [ "$#" -ne 1 ] then usage elif [ ! -d "$1" ] then echo "Destinaton $1 not found or is not a directory." >&2 exit 1 elif [ "$(id -u)" -ne 0 ] then echo "This program must run as root." >&2 exit 1 elif ! command -v btrfs >/dev/null then echo 'btrfs-progs must be installed.' >&2 exit 1 elif ! docker info --format '{{ .ServerVersion }}' >/dev/null then echo 'Docker must be installed and running.' >&2 exit 1 elif ! df --type=btrfs /var/lib/docker/volumes >/dev/null then echo "Docker volumes are not on a btrfs filesystem." >&2 exit 1 elif ! df --type=btrfs "$1" >/dev/null then echo "Destination $1 is not on a btrfs filesystem." >&2 exit 1 elif [ "$(df --output=target /var/lib/docker/volumes)" != "$(df --output=target "$1")" ] then echo "The destination $1 is not on the same btrfs volume as the Docker volumes." >&2 exit 1 elif [ -z "$(docker volume ls --filter label=snapshot=true --format '{{ .Name }}')" ] then echo "No Docker volumes marked for backup, exiting." >&2 exit 1 fi dest="$1" root_volume="$(get_mountpoint /var/lib/docker/volumes)" snapshot="$(mktemp --dry-run "--tmpdir=$root_volume")" trap 'cleanup' INT QUIT EXIT TERM btrfs subvolume snapshot "$root_volume" "$snapshot" for name in $(docker volume ls --filter label=snapshot=true --format '{{ .Name }}') do echo "Backing up $name." mountpoint="$(docker volume inspect --format '{{ .Mountpoint }}' "$name")" src="$snapshot/${mountpoint#$root_volume/}" # shellcheck disable=SC2115 [ ! -e "$dest/$name" ] || rm -rf "$dest/$name" cp --archive --force --reflink=always "$src" "$dest/$name" done
Ansible/roles/debian_server/files/dvb.service 0 → 100644 +9 −0 Original line number Diff line number Diff line # vim: filetype=systemd [Unit] Description=Docker volume backup (dvb) ConditionACPower=true After=local-fs.target [Service] Type=exec ExecStart=dvb /var/backups/docker-volumes
Ansible/roles/debian_server/files/dvb.timer 0 → 100644 +10 −0 Original line number Diff line number Diff line # vim: filetype=systemd [Unit] Description=Docker volume backup (dvb) [Timer] OnCalendar=weekly RandomizedDelaySec=21600 [Install] WantedBy=multi-user.target
Ansible/roles/debian_server/tasks/btrfs.yml +4 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,8 @@ {{ (ansible_facts.mounts|selectattr("device", "equalto", device)|first)["mount"] }} # yamllint enable rule:line-length tags: [scrub] notify: - Systemd daemon reload - name: Enable btrfs scrub timers ansible.builtin.systemd: Loading @@ -46,6 +48,8 @@ mode: 0o0644 src: btrfs_check.{{ item }}.j2 vars: *vars notify: - Systemd daemon reload - name: Enable the btrfs check timers ansible.builtin.systemd: Loading
Ansible/roles/debian_server/tasks/docker.yml +33 −0 Original line number Diff line number Diff line Loading @@ -37,6 +37,7 @@ mode: 0o0644 notify: - Systemd daemon reload - Restart Docker - name: Allow access from the toolbox container ansible.builtin.copy: Loading @@ -54,3 +55,35 @@ direction: in interface: docker0 rule: allow - name: Create the Docker volume backup destination directory ansible.builtin.file: group: backup mode: 0o0750 owner: root path: /var/backups/docker-volumes state: directory - name: Copy the Docker volume backup script ansible.builtin.copy: dest: /usr/local/bin/ mode: preserve src: dvb - name: Copy the Docker volume backup service and timer loop: - service - timer ansible.builtin.copy: dest: /etc/systemd/system/dvb.{{ item }} mode: 0o0644 src: dvb.{{ item }} notify: - Systemd daemon reload - name: Enable the Docker volume backup timer ansible.builtin.systemd: enabled: true name: dvb.timer notify: - Systemd daemon reload