From 41d72cf9ef168e987433d95946c9eb25b7058e00 Mon Sep 17 00:00:00 2001 From: Someone Date: Fri, 4 Oct 2024 13:42:33 +0200 Subject: [PATCH] [roles/base/btrfs-helpers] possibly install btrfs helper scripts --- roles/base/btrfs-helpers/defaults/main.yml | 13 ++++ .../default/btrfs-regen-snaphot-homelinks.sh | 43 ++++++++++ .../files/default/btrfs-snapshot.sh | 78 +++++++++++++++++++ roles/base/btrfs-helpers/tasks/main.yml | 60 ++++++++++++++ roles/base/btrfs-helpers/templates/cron.j2 | 29 +++++++ 5 files changed, 223 insertions(+) create mode 100644 roles/base/btrfs-helpers/defaults/main.yml create mode 100644 roles/base/btrfs-helpers/files/default/btrfs-regen-snaphot-homelinks.sh create mode 100644 roles/base/btrfs-helpers/files/default/btrfs-snapshot.sh create mode 100644 roles/base/btrfs-helpers/tasks/main.yml create mode 100644 roles/base/btrfs-helpers/templates/cron.j2 diff --git a/roles/base/btrfs-helpers/defaults/main.yml b/roles/base/btrfs-helpers/defaults/main.yml new file mode 100644 index 0000000..7fa2c42 --- /dev/null +++ b/roles/base/btrfs-helpers/defaults/main.yml @@ -0,0 +1,13 @@ +##################################### +### someone's ansible provisioner ### +##################################### +# Part of: https://git.somenet.org/root/pub/somesible.git +# 2017-2024 by someone +# +# If not overridden in inventory or as a parameter, this is the value that will be used +# +--- +setup_btrfs_helpers: False +setup_btrfs_scrub_monthly: False +setup_btrfs_snapshot_daily: False +setup_btrfs_snapshot_reboot: False diff --git a/roles/base/btrfs-helpers/files/default/btrfs-regen-snaphot-homelinks.sh b/roles/base/btrfs-helpers/files/default/btrfs-regen-snaphot-homelinks.sh new file mode 100644 index 0000000..8b1bbdf --- /dev/null +++ b/roles/base/btrfs-helpers/files/default/btrfs-regen-snaphot-homelinks.sh @@ -0,0 +1,43 @@ +#!/bin/bash +################################################ +### Managed by someone's ansible provisioner ### +################################################ +# Part of: https://git.somenet.org/root/pub/somesible.git +# 2017-2024 by someone +# + +# Copyright 2018 by Jan Vales (Someone ) +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, version 3 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +# +# Regenerate /home/$user/.btrfs-snapshots/ symlinks +# we use relative symlinking in order to break infinite recursions. +# + +cd /home/ +for home in $(find . -xdev -mindepth 1 -maxdepth 1 -type d); do + echo "HOME: /home/${home}" + rm -rf "/home/${home}/.btrfs-snapshots" + mkdir "/home/${home}/.btrfs-snapshots" + + cd "/btrfs/" + for snap in $(find . -mindepth 2 -maxdepth 2 -type d -iname 'home.*.snap'); do + snap_name=$(echo -n $snap | sed -E -e 's#/#-#2g') + ln -snf "../../../btrfs/${snap}/${home}" "/home/${home}/.btrfs-snapshots/$snap_name" + touch -ahm -r "/btrfs/${snap}" "/home/${home}/.btrfs-snapshots/$snap_name" + done + + rename -v 's/home\.(.*)\.snap/$1/' /home/${home}/.btrfs-snapshots/* +done diff --git a/roles/base/btrfs-helpers/files/default/btrfs-snapshot.sh b/roles/base/btrfs-helpers/files/default/btrfs-snapshot.sh new file mode 100644 index 0000000..de45ee6 --- /dev/null +++ b/roles/base/btrfs-helpers/files/default/btrfs-snapshot.sh @@ -0,0 +1,78 @@ +#!/bin/bash +################################################ +### Managed by someone's ansible provisioner ### +################################################ +# Part of: https://git.somenet.org/root/pub/somesible.git +# 2017-2024 by someone +# + +# Copyright 2011 by Jan Vales (Someone ) +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, version 3 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +# +# Manage BTRFS snapshots +# 0 * * * * /root/somescripts/btrfs/snapshot.sh &> /dev/null +# + +BTRFS_SNAPSHOT_DELSNAP=10 + +if [ -z "$BTRFS_SNAPSHOT_MAXSNAP" ]; then + BTRFS_SNAPSHOT_MAXSNAP=13 +fi + +CALLPATH="`pwd`" + +for fs in $(find /btrfs/ -xdev -mindepth 1 -maxdepth 1 -type d); do + STARTTS="`date +'%Y-%m-%d--%H-%M'`" + echo "FS: $fs -- $STARTTS" + chmod u=rwX,go=X $fs + + if [ -e "${fs}.automount" ]; then + mount $fs &> /dev/null + fi + cd $fs + + #for every .autosnap subvol... + for vol in $(find $fs -xdev -maxdepth 1 -iname '*.autosnap'); do + VOLNAME=`echo "${vol}" | sed -e 's/\.autosnap//' ` + echo "VOL: ${VOLNAME}" + + # delete snapshots... + for i in $(seq -f %02g $(echo "${BTRFS_SNAPSHOT_MAXSNAP}+${BTRFS_SNAPSHOT_DELSNAP}"|bc) -1 ${BTRFS_SNAPSHOT_MAXSNAP}); do + if [ -e "${VOLNAME}.${i}.snap" ]; then + btrfs subvolume delete "${VOLNAME}.${i}.snap" + fi + done + + # move existing snapshots + for i in $(seq -f %02g ${BTRFS_SNAPSHOT_MAXSNAP} -1 0) ; do + if [ -e "${VOLNAME}.${i}.snap" ]; then + mv "${VOLNAME}.${i}.snap" "${VOLNAME}.$(echo "$i"|awk '{printf "%02g",$0+1}').snap" + fi + done + + # create new snapshot + touch -m -a "${VOLNAME}.autosnap" + btrfs subvolume snapshot -r "${VOLNAME}.autosnap" "${VOLNAME}.00.snap" + done + + cd $CALLPATH + + if [ -e "${fs}.automount" ]; then + umount $fs &> /dev/null || echo "Failed to unmount" + fi +done + +echo "my-btrfs-cleaner: $(ps x | grep '\[btrfs-cleaner\]')" > /dev/kmsg diff --git a/roles/base/btrfs-helpers/tasks/main.yml b/roles/base/btrfs-helpers/tasks/main.yml new file mode 100644 index 0000000..1a54899 --- /dev/null +++ b/roles/base/btrfs-helpers/tasks/main.yml @@ -0,0 +1,60 @@ +##################################### +### someone's ansible provisioner ### +##################################### +# Part of: https://git.somenet.org/root/pub/somesible.git +# 2017-2024 by someone +# +--- +- name: make sure /btrfs exists + file: + path: "/btrfs" + state: directory + mode: 0711 + owner: "root" + group: "root" + when: setup_btrfs_helpers | bool + + +- name: copy btrfs-snapshot.sh + copy: + src: "{{item}}" + dest: "/btrfs/btrfs-snapshot.sh" + mode: 0700 + owner: "root" + group: "root" + with_first_found: + - "{{lookup('env','PWD')}}/host_files/{{inventory_hostname}}/{{role_name}}/btrfs-snapshot.sh" + - "{{lookup('env','PWD')}}/group_files/{{group_files_group}}/{{role_name}}/btrfs-snapshot.sh" + - "{{lookup('env','PWD')}}/group_files/all/{{role_name}}/btrfs-snapshot.sh" + - "default/btrfs-snapshot.sh" + when: setup_btrfs_helpers | bool + + +- name: copy btrfs-regen-snaphot-homelinks.sh + copy: + src: "{{item}}" + dest: "/btrfs/btrfs-regen-snaphot-homelinks.sh" + mode: 0700 + owner: "root" + group: "root" + with_first_found: + - "{{lookup('env','PWD')}}/host_files/{{inventory_hostname}}/{{role_name}}/btrfs-regen-snaphot-homelinks.sh" + - "{{lookup('env','PWD')}}/group_files/{{group_files_group}}/{{role_name}}/btrfs-regen-snaphot-homelinks.sh" + - "{{lookup('env','PWD')}}/group_files/all/{{role_name}}/btrfs-regen-snaphot-homelinks.sh" + - "default/btrfs-regen-snaphot-homelinks.sh" + when: setup_btrfs_helpers | bool + + +- name: setup cron.d file for btrfs snapshots + scrub. + template: + src: "{{item}}" + dest: "/etc/cron.d/btrfs" + mode: 0644 + owner: "root" + group: "root" + with_first_found: + - "{{lookup('env','PWD')}}/host_files/{{inventory_hostname}}/{{role_name}}/cron.j2" + - "{{lookup('env','PWD')}}/group_files/{{group_files_group}}/{{role_name}}/cron.j2" + - "{{lookup('env','PWD')}}/group_files/all/{{role_name}}/cron.j2" + - "templates/cron.j2" + when: setup_btrfs_helpers | bool diff --git a/roles/base/btrfs-helpers/templates/cron.j2 b/roles/base/btrfs-helpers/templates/cron.j2 new file mode 100644 index 0000000..db2fbd7 --- /dev/null +++ b/roles/base/btrfs-helpers/templates/cron.j2 @@ -0,0 +1,29 @@ +# +################################################ +### Managed by someone's ansible provisioner ### +################################################ +# Part of: https://git.somenet.org/root/pub/somesible.git +# 2017-2024 by someone +# + +{% if setup_btrfs_scrub_monthly | bool %} +# scrub filesystems disk-wise every quarter. +# first seems faster and less stalling with btrfs raid6. +0 2 9 */3 * root btrfs filesystem show -m -d | grep devid | awk '{ print $8 }' | xargs -n 1 -- btrfs scrub start -c 3 -B -d | tee /tmp/btrfs-scrub.log +#0 2 9 */3 * root mount | grep "on /btrfs/" | awk '{ print $3 }' | xargs -n 1 -- btrfs scrub start -c 3 -B -d | tee /tmp/btrfs-scrub.log + +{% endif %} +{% if setup_btrfs_snapshot_daily | bool %} +# Take a new snapshot every midnight. +0 0 * * * root (/btrfs/btrfs-snapshot.sh; /btrfs/btrfs-regen-snaphot-homelinks.sh) &> /tmp/btrfs-snapshot-daily.log + +{% endif %} +{% if setup_btrfs_snapshot_reboot | bool %} +# Take a new snapshot every reboot. +@reboot root (/btrfs/btrfs-snapshot.sh; /btrfs/btrfs-regen-snaphot-homelinks.sh) &> /tmp/btrfs-snapshot-reboot.log + +{% endif %} +{% if not setup_btrfs_snapshot_daily | bool and not setup_btrfs_snapshot_reboot | bool and not setup_btrfs_scrub_monthly | bool %} +# Nothing configured. + +{% endif %} -- 2.43.0