UPD btrfs-snapshot script
This commit is contained in:
151
btrfs-snapshot/btrfs-snapshot
Executable file
151
btrfs-snapshot/btrfs-snapshot
Executable file
@ -0,0 +1,151 @@
|
||||
#!/bin/bash
|
||||
# By Thomas KUSCHEL <oe1tkt@gmail.com>
|
||||
# MIT License 2015
|
||||
VERSION="v6.15"
|
||||
set -o errexit # to make script exit when a command fails / a.k.a. set -e
|
||||
# then add "|| true" to commands that you allow to fail.
|
||||
set -o nounset # to exit when script tries to use undeclared variables / set -u
|
||||
# set -o xtrace # to trace when gets executed for debugging / a.k.a. set -x
|
||||
set -o pipefail
|
||||
SCRIPTNAME=${0##*/}
|
||||
SCRIPTPATH=$(dirname "$0")
|
||||
# echo $SCRIPTNAME
|
||||
# where the btrfs is found (use command: which btrfs)
|
||||
WHICH="/usr/bin/which"
|
||||
BTRFS_ALT="/sbin/btrfs"
|
||||
BTRFS="/usr/local/bin/btrfs"
|
||||
# Function to install this script:
|
||||
installation() {
|
||||
# you have to switch to administrator
|
||||
#`${WHICH} ${PATHINSTALL}`
|
||||
PATHINSTALL="/usr/local/bin"
|
||||
SNAPSYSTEMDCFG="/etc/systemd/system/"
|
||||
SCRIPTPATH=$(dirname "$0")
|
||||
# echo "Installation of ${SCRIPTNAME} to ${PATHINSTALL} and create systemd timer/service examples in ${SNAPSYSTEMDCFG}"
|
||||
read -n 1 -p "Install ${SCRIPTNAME} to ${PATHINSTALL}? [Y/n] " reply;
|
||||
if [ "$reply" != "" ]; then echo; fi
|
||||
if [ "$reply" = "${reply#[Nn]}" ]; then
|
||||
sudo cp $0 ${PATHINSTALL}/${SCRIPTNAME}
|
||||
fi
|
||||
read -n 1 -p "Do you want to create systemd timer/service examples in ${SNAPSYSTEMDCFG}? [Y/n] " reply;
|
||||
if [ "$reply" != "" ]; then echo; fi
|
||||
if [ "$reply" = "${reply#[Nn]}" ]; then
|
||||
sudo cp -a ${SCRIPTPATH}/system/. ${SNAPSYSTEMDCFG}.
|
||||
path=`$WHICH $SCRIPTNAME`
|
||||
fi
|
||||
}
|
||||
|
||||
deinstallation() {
|
||||
PATHINSTALL="/usr/local/bin"
|
||||
read -n 1 -p "Do you want to remove (deinstallation) of ${SCRIPTNAME} in ${PATHINSTALL}? [Y/n] " reply;
|
||||
if [ "$reply" != "" ]; then echo; fi
|
||||
if [ "$reply" = "${reply#[Nn]}" ]; then
|
||||
sudo rm -f ${PATHINSTALL}/${SCRIPTNAME}
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to display usage:
|
||||
usage() {
|
||||
path=`${WHICH} ${SCRIPTNAME}` || installation
|
||||
if [ -z "${path}" ] ; then
|
||||
path="/usr/local/bin/"
|
||||
echo "Please install $SCRIPTNAME to \"$path\""
|
||||
path="${path}${SCRIPTNAME}"
|
||||
fi
|
||||
cat <<EOF
|
||||
$SCRIPTNAME: Take and rotate snapshots on a btrfs file system
|
||||
|
||||
usage: $SCRIPTNAME [--version] source target snap_name count [-q]
|
||||
source: path to make snaphots of
|
||||
target: snapshot directory
|
||||
snap_name: Base name for snapshots, to be appended to
|
||||
date "+%F-%H%M"
|
||||
count: Number of snapshots in the timestamp-@snap_name format to
|
||||
keep at one time for a given snap_name.
|
||||
[-q]: Be quiet.
|
||||
--install: Force a new installation of this script.
|
||||
--version: Print the version of this script,
|
||||
additionally the version of btrfs-progs.
|
||||
|
||||
Example for crontab:
|
||||
15,30,45 * * * * root $0 /home /snap quarterly 4 -q
|
||||
0 * * * * root $0 /home /snap hourly 8 -q
|
||||
|
||||
Example for anacrontab:
|
||||
1 15 daily_snap $0 /home /snap daily 8
|
||||
7 17 weekly_snap $0 /home /snap weekly 5
|
||||
@monthly 19 monthly_snap $0 /home /snap monthly 3
|
||||
|
||||
NEW: If you are using systemd on your linux system, see http://f0x.at/btrfs
|
||||
EOF
|
||||
exit
|
||||
}
|
||||
if [ ! -f "$BTRFS" ] ; then
|
||||
if [ -f "$BTRFS_ALT" ] ; then
|
||||
# fallback
|
||||
BTRFS="$BTRFS_ALT"
|
||||
else
|
||||
echo "$BTRFS system file not found,"
|
||||
echo "please install btrfs-progs:"
|
||||
echo "Arch Linux: # sudo pacman -S btrfs-progs"
|
||||
echo "Debian/Ubuntu: # sudo apt-get install btrfs-tools"
|
||||
exit
|
||||
fi
|
||||
fi
|
||||
# Basic argument checks:
|
||||
if [ $# -gt 0 ] && [ "x$1" == "x--version" ] ; then
|
||||
echo "$SCRIPTNAME $VERSION"
|
||||
echo `$BTRFS --version`
|
||||
exit
|
||||
fi
|
||||
if [ $# -gt 0 ] && [ "x$1" == "x--install" ] ; then
|
||||
installation
|
||||
exit
|
||||
fi
|
||||
if [ $# -gt 0 ] && [ "x$1" == "x--deinstall" ] ; then
|
||||
deinstallation
|
||||
exit
|
||||
fi
|
||||
|
||||
# Check count of arguments
|
||||
if [ "$#" -ge 4 ]; then
|
||||
SOURCE=$1
|
||||
TARGET=$2
|
||||
SNAP=$3
|
||||
COUNT=$4
|
||||
QUIET=""
|
||||
if [ "$#" -gt 4 ]; then
|
||||
QUIET=$5
|
||||
fi
|
||||
else
|
||||
echo "You need some arguments."
|
||||
usage
|
||||
fi
|
||||
if [ $# -gt 5 ] ; then
|
||||
echo "Too many parameters."
|
||||
usage
|
||||
fi
|
||||
if [ -n "$QUIET" ] && [ "x$QUIET" != "x-q" ] ; then
|
||||
echo "Parameter 4 is either -q or empty. Given: \"$QUIET\""
|
||||
usage
|
||||
fi
|
||||
# $max_snap is the highest number of snapshots that will be kept for $SNAP.
|
||||
max_snap=$(($COUNT -1))
|
||||
|
||||
# Check if $TARGET already exists - if NOT then create subdir
|
||||
[ -d $TARGET ] || mkdir $TARGET
|
||||
|
||||
# Clean up older snapshots:
|
||||
for i in `ls $TARGET|sort |grep @${SNAP}|head -n -${max_snap}`; do
|
||||
cmd="$BTRFS subvolume delete $TARGET/$i"
|
||||
if [ -z $QUIET ]; then
|
||||
echo $cmd
|
||||
fi
|
||||
$cmd >/dev/null
|
||||
done
|
||||
# Create new snapshot:
|
||||
cmd="$BTRFS subvolume snapshot -r $SOURCE $TARGET/`date "+%F-%H%M-@${SNAP}"`"
|
||||
if [ -z $QUIET ]; then
|
||||
echo $cmd
|
||||
fi
|
||||
$cmd >/dev/null
|
8
btrfs-snapshot/system/snapshot_home_user_daily.service
Normal file
8
btrfs-snapshot/system/snapshot_home_user_daily.service
Normal file
@ -0,0 +1,8 @@
|
||||
[Unit]
|
||||
Description=rolling snapshot for /home/user
|
||||
[Service]
|
||||
Type=oneshot
|
||||
Nice=19
|
||||
IOSchedulingClass=best-effort
|
||||
IOSchedulingPriority=7
|
||||
ExecStart=/usr/local/bin/btrfs-snapshot /home/user /home/snap/user daily 4
|
9
btrfs-snapshot/system/snapshot_home_user_daily.timer
Normal file
9
btrfs-snapshot/system/snapshot_home_user_daily.timer
Normal file
@ -0,0 +1,9 @@
|
||||
[Unit]
|
||||
Description=daily snapshot
|
||||
[Timer]
|
||||
# see systemd.time(7) manual page for other scheduling options
|
||||
OnCalendar=01:00
|
||||
# run immediately if we missed a backup for some reason
|
||||
Persistent=true
|
||||
[Install]
|
||||
WantedBy=timers.target
|
Reference in New Issue
Block a user