#!/bin/sh # # ZFS subcommand wrapper VER="1.1-02" # # ZFS is very sysadmin-friendly by itself. With this script, # administration of ZFS becomes even more pleasant. # AUTHOR="kkatarn@sleepgate.ru 2016" # # TODO: documentation. # ECHO="" PREPEND_DATE="" DATE_HMS="Y" guess_dataset() { local _fs _dset _where=$(realpath $1 2>/dev/null) _dset=${_where} [ -z "${_dset}" ] && return 1 while true; do _fs=$(mount | grep " ${_dset} " | awk '{print $1;}' 2>/dev/null) if [ -n "${_fs}" ]; then echo -n ${_fs} | sed -e 's/^\///' return 0 fi if [ "${_dset}" = "/" ]; then echo ${_where} | sed -e 's/^\///' return 1 fi _dset=$(dirname "${_dset}") done } _me=$(basename $0) _argv="" _argc=0 _dset=$(guess_dataset $(pwd)) _snap="" _subargs="" usage() { echo "ZFS snapshot/rollback/list/destroy/send wrapper ver. ${VER}" echo "${AUTHOR}" echo "Usage: ${_me} [--help] [--echo] [--date|--date-hms] [snapshot-name] [-- ]" echo " --help (-h): print this message;" echo " --echo: just echo zfs command to be issued;" echo " --date (-d): prepend Year-Month-Day to the snapshot name;" echo -n " --date-hms (-dd): prepend Y-M-D-Hour-Min-Sec" if [ "${_me}" == "zlist" -o "${_me}" == "lss" ]; then echo ";" else echo " (default)." fi } for _arg in $@; do if [ -n "${_subargs}" ]; then _subargs="${_subargs}${_arg} " continue fi case ${_arg} in '--echo') ECHO="Y" ;; '-h'|'--help') usage exit 0 ;; '-d'|'--date') PREPEND_DATE="Y" DATE_HMS="" ;; '-dd'|'--date-hms') PREPEND_DATE="Y" ;; '--') _subargs=" " ;; *) _argc=$((${_argc}+1)) [ -z "${_argv}" ] && _argv="${_arg}" || _argv="${_argv} ${_arg}" ;; esac done case ${_argc} in 0) _snap="" PREPEND_DATE="Y" ;; 1) _snap=${_argv} ;; *) usage exit 1 ;; esac if [ -n "${PREPEND_DATE}" -a "${_me}" != "zlist" -a "${_me}" != "lss" ]; then [ -n "${_snap}" ] && _snap="-${_snap}" [ -n "${DATE_HMS}" ] && \ _date=$(date "+%Y-%m-%d-%H-%M-%S") || \ _date=$(date "+%Y-%m-%d") _snap="${_date}${_snap}" fi many_mees() { local _me=$(realpath $0) local _path=$(dirname ${_me}) mv "${_me}" "${_path}/znap" || exit 1 _me="${_path}/znap" ln -s "${_me}" "${_path}/zdel" 2>/dev/null ln -s "${_me}" "${_path}/zroll" 2>/dev/null ln -s "${_me}" "${_path}/zend" 2>/dev/null ln -s "${_me}" "${_path}/zlist" 2>/dev/null ln -s "${_me}" "${_path}/lss" 2>/dev/null } case "${_me}" in "znap") _subcmd="snapshot" ;; "zdel") _subcmd="destroy" ;; "zroll") _subcmd="rollback" ;; "zend") _subcmd="send" ;; "zlist") [ ${_argc} -eq 0 ] && _subcmd="list -r" || _subcmd="list" ;; "lss") [ ${_argc} -eq 0 ] && _subcmd="list -r" || _subcmd="list" _subargs="${_subargs} -t snapshot " ;; *) echo "${_me}: i don't know subcommand for my name \"${_me}\", thus i'm exploding." many_mees exit 0 ;; esac [ -n "${_snap}" ] && _snap="@${_snap}" CMD="zfs ${_subcmd} ${_subargs} ${_dset}${_snap}" [ -z "$ECHO" ] && $CMD || echo $CMD