#!/usr/bin/env bash # set -x sudo apt install -y \ sanoid # git \ # dh-make \ # libconfig-inifiles-perl \ echo "sanoid provides: sanoid, syncoid, findoid in /usr/sbin" echo "defaults are in /usr/share/sanoid/sanoid.defaults.conf" echo "override them in /etc/sanoid/sanoid.conf" echo "Installed files:" cat <<-EOF syncoid /usr/sbin/ sanoid /usr/sbin/ findoid /usr/sbin/ sanoid.defaults.conf /usr/share/sanoid/ debian/sanoid-prune.service /lib/systemd/system CHANGELIST /usr/share/doc/sanoid/changelog EOF # Cronjob for non-systemd systems: every 15 minutes. # If you require a different interval, you will need to disable the # timer or the cron job according to your system configuration. conf_print_syncoid_cron() { cat <<-EOF PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin */15 * * * * root [ -f /etc/sanoid/sanoid.conf ] && if [ ! -d /run/systemd/system ]; then TZ=UTC /usr/sbin/sanoid --cron --quiet; fi EOF } conf_print_sanoid_cron > /etc/cron.d/sanoid # Do the same for syncoid for backups. conf_print_syncoid_cron() { cat <<-EOF PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin */15 * * * * root [ -f /etc/sanoid/syncoid.conf ] && if [ ! -d /run/systemd/system ]; then TZ=UTC /usr/sbin/sanoid --cron --quiet; fi EOF } conf_print_syncoid_cron > /etc/cron.d/syncoid # Copied from /usr/shar/doc/sanoid/example.conf conf_print_sanoid() { cat <<-EOF | sudo tee /etc/sanoid/sanoid.conf ## name your backup modules with the path to their ZFS dataset - no leading slash. #[zpoolname/datasetname] # # pick one or more templates - they're defined (and editable) below. Comma separated, processed in order. # # in this example, template_demo's daily value overrides template_production's daily value. # use_template = production,demo # # # if you want to, you can override settings in the template directly inside module definitions like this. # # in this example, we override the template to only keep 12 hourly and 1 monthly snapshot for this dataset. # hourly = 12 # monthly = 1 # ## you can also handle datasets recursively. #[zpoolname/parent] # use_template = production # recursive = yes # # if you want sanoid to manage the child datasets but leave this one alone, set process_children_only. # process_children_only = yes # ## you can selectively override settings for child datasets which already fall under a recursive definition. #[zpoolname/parent/child] # # child datasets already initialized won't be wiped out, so if you use a new template, it will # # only override the values already set by the parent template, not replace it completely. # use_template = demo # you can also handle datasets recursively in an atomic way without the possibility to override settings for child datasets. [zpoolname/parent2] use_template = production recursive = zfs ############################# # templates below this line # ############################# # name your templates template_templatename. you can create your own, and use them in your module definitions above. [template_demo] daily = 60 [template_production] frequently = 0 hourly = 36 daily = 30 monthly = 3 yearly = 0 autosnap = yes autoprune = yes [template_backup] autoprune = yes frequently = 0 hourly = 30 daily = 90 monthly = 12 yearly = 0 ### don't take new snapshots - snapshots on backup ### datasets are replicated in from source, not ### generated locally autosnap = no ### monitor hourlies and dailies, but don't warn or ### crit until they're over 48h old, since replication ### is typically daily only hourly_warn = 2880 hourly_crit = 3600 daily_warn = 48 daily_crit = 60 [template_hotspare] autoprune = yes frequently = 0 hourly = 30 daily = 90 monthly = 3 yearly = 0 ### don't take new snapshots - snapshots on backup ### datasets are replicated in from source, not ### generated locally autosnap = no ### monitor hourlies and dailies, but don't warn or ### crit until they're over 4h old, since replication ### is typically hourly only hourly_warn = 4h hourly_crit = 6h daily_warn = 2d daily_crit = 4d [template_scripts] ### information about the snapshot will be supplied as environment variables, ### see the README.md file for details about what is passed when. ### run script before snapshot pre_snapshot_script = /path/to/script.sh ### run script after snapshot post_snapshot_script = /path/to/script.sh ### run script before pruning snapshot pre_pruning_script = /path/to/script.sh ### run script after pruning snapshot pruning_script = /path/to/script.sh ### don't take an inconsistent snapshot (skip if pre script fails) #no_inconsistent_snapshot = yes ### run post_snapshot_script when pre_snapshot_script is failing #force_post_snapshot_script = yes ### limit allowed execution time of scripts before continuing (<= 0: infinite) script_timeout = 5 [template_ignore] autoprune = no autosnap = no monitor = no EOF } conf_print_sanoid > /etc/sanoid/sanoid.conf # Both sanoid and synmcoid are oneshot processes so it makes little sense to # provide an init file, cron is just fine. In this case the systemd file is there # because systemd decided to manage cron tasks. # Generated using: # https://raw.githubusercontent.com/akhilvij/systemd-to-sysvinit-converter/master/converter.py # python2 converter /usr/src/sanoid-2.2.0/sanoid.service > sanoid conf_print_sanoid_init() { cat <<-'EOF' #!/bin/sh ### BEGIN INIT INFO # Provides: sanoid # Required-Start: $syslog $local_fs $remote_fs # Required-Stop: $syslog $local_fs $remote_fs # Short-Description: Snapshot ZFS filesystems ### END INIT INFO . /lib/lsb/init-functions prog=sanoid PIDFILE=/var/run/$prog.pid DESC="Snapshot ZFS filesystems" start() { log_daemon_msg "Starting $DESC" "$prog" start_daemon -p $PIDFILE /usr/sbin/sanoid --take-snapshots --verbose if [ $? -ne 0 ]; then log_end_msg 1 exit 1 fi if [ $? -eq 0 ]; then log_end_msg 0 fi exit 0 } stop() { log_daemon_msg "Stopping $DESC" "$prog" killproc -p $PIDFILE /usr/sbin/sanoid if [ $? -ne 0 ]; then log_end_msg 1 exit 1 fi if [ $? -eq 0 ]; then log_end_msg 0 fi } force_reload() { stop start } case "$1" in start) start ;; stop) stop ;; force-reload) force_reload ;; restart) stop start ;; *) echo "$Usage: $prog {start|stop|force-reload|restart}" exit 2 esac EOF } # conf_print_sanoid-init > /etc/init.d/sanoid # Generated using: # https://raw.githubusercontent.com/akhilvij/systemd-to-sysvinit-converter/master/converter.py # python2 converter /usr/src/sanoid-2.2.0/sanoid-prune.service > sanoid-prune conf_print_sanoid-prune_init() { cat <<-'EOF' | sudo tee /etc/init.d/sanoid=prune #!/bin/sh ### BEGIN INIT INFO # Provides: sanoid-prune # Required-Start: $syslog $local_fs $remote_fs # Required-Stop: $syslog $local_fs $remote_fs # Short-Description: Prune ZFS snapshots ### END INIT INFO . /lib/lsb/init-functions prog=sanoid-prune PIDFILE=/var/run/$prog.pid DESC="Prune ZFS snapshots" start() { log_daemon_msg "Starting $DESC" "$prog" start_daemon -p $PIDFILE /usr/sbin/sanoid --prune-snapshots --verbose if [ $? -ne 0 ]; then log_end_msg 1 exit 1 fi if [ $? -eq 0 ]; then log_end_msg 0 fi exit 0 } stop() { log_daemon_msg "Stopping $DESC" "$prog" killproc -p $PIDFILE /usr/sbin/sanoid if [ $? -ne 0 ]; then log_end_msg 1 exit 1 fi if [ $? -eq 0 ]; then log_end_msg 0 fi } force_reload() { stop start } case "$1" in start) start ;; stop) stop ;; force-reload) force_reload ;; restart) stop start ;; *) echo "$Usage: $prog {start|stop|force-reload|restart}" exit 2 esac EOF } # conf_print_sanoid-prune_init > /etc/init.d/sanoid-prune exit 0 # build a debian package from the git repo USER="jimsalterjrs" PROJECT="sanoid" LICENSE="mit" SECTION="admin" HOMEPAGE="https://openoid.net" BUILD_HOME="/var/tmp/sanoid-git_build" #VERSION="2.10.0" PACKAGE="sanoid" VERSION=$(curl "https://api.github.com/repos/${USER}/${PROJECT}/tags?per_page=5" | jq -r '.[0] | .name') VERSION=${VERSION:1} # strip the preceding 'v' DEBEMAIL="person@company.tld" DEBFULLNAME="Testy McTester" DESCRIPTION="Policy-driven snapshot management tool for ZFS filesystems." LONG_DESCRIPTION="Create, thin, and monitor snapshots and pool health from a single configuration file." RSS_FEED="https://github.com/${USER}/${PROJECT}/releases.atom" # xdg-open ${RSS_FEED} echo ${RSS_FEED} # Make the BUILD_HOME directory and clone upstream mkdir -p ${BUILD_HOME} cd ${BUILD_HOME} || exit git clone http://github.com/${USER}/${PROJECT}.git ${PACKAGE}-${VERSION} cd ${PACKAGE}-${VERSION} || exit mkdir -p m4 cat <.git/gbp.conf [DEFAULT] # this is the upstream-branch: upstream-branch=master EOF # debianize the BUILD_HOME directory echo ${DEBFULLNAME} dh_make \ --createorig \ --single \ --native \ --copyright ${LICENSE} \ --yes cp README.rst debian/README rm debian/README.source # Customize the debian directory values #sed -i 's,^\(Description: \).*,\1'${DESCRIPTION}',' debian/control sed -i "s,^\(Description: \).*,\1${DESCRIPTION}," debian/control sed -i 's,^\(Section: \).*,\1'${SECTION}',' debian/control sed -i "s,^\(Maintainer: \).*,\1'${DEBFULLNAME}\ \<${DEBEMAIL}\>'," debian/control sed -i 's,^\(Homepage: \).*,\1'${HOMEPAGE}',' debian/control sed -i "s/.*insert\ long.*/${LONG_DESCRIPTION}/" debian/control echo **************** cat debian/control echo **************** BUILD_OPTIONS="" cat <debian/rules #!/usr/bin/make -f %: dh \$@ override_dh_auto_configure: dh_auto_configure -- ${BUILD_OPTIONS} EOF cat <debian/watch version=4 opts=filenamemangle=s/.+\/v?(\d\S+)\.tar\.gz/${PROJECT}-$1\.tar\.gz/ \ http://github.com/${USER}/${PROJECT}/tags .*/v?(\d\S+)\.tar\.gz EOF cp -a packages/debian/* debian dpkg-buildpackage -us -uc -b echo ${PACKAGE}_${VERSION}_amd64.deb sudo dpkg -i ../${PACKAGE}_${VERSION}_amd64.deb