#!/bin/bash # snap-pac # https://github.com/wesbarnett/snap-pac # Copyright (C) 2016, 2017, 2018 James W. Barnett # # 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; either version 2 of the License, or # (at your option) any later version. # # 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, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. set -o errtrace readonly argv0="snap-pac" readonly SNAPPAC_CONFIG_FILE=/etc/snap-pac.conf readonly SNAPPER_CONFIG_FILE=/etc/conf.d/snapper readonly pacman_cmd="$(ps -q $(ps -p "$$" -o ppid=) -o args=)" readonly pre_or_post=$1 out() { printf "$1 $2\n" "${@:3}"; } error() { out "==> \033[00;31merror:\033[00m" "$@"; } >&2 die() { [[ $ABORT_ON_FAIL == "no" ]] && exit 0 exit 1 } read_config() { CONFIG_FILE="$1" if [[ -f "$CONFIG_FILE" ]] && [[ -r "$CONFIG_FILE" ]]; then while IFS='= ' read lhs rhs; do if [[ ! $lhs =~ ^\ *# && -n $lhs ]]; then rhs="${rhs%%\#*}" rhs="${rhs%%*( )}" rhs="${rhs%\"*}" rhs="${rhs#\"*}" declare -g $lhs="$rhs" fi done < "$CONFIG_FILE" fi } trapkill() { error "Exited due to user intervention." die } traperror() { error "Exited due to error on line $1" out "exit status:" "$2" out "command:" "$3" out "bash line:" "$4" out "function argv0:" "$5" die } truncate_description() { desc="$@" if [[ "${#desc}" -gt $DESC_LIMIT ]]; then echo "$(echo $desc | cut -c 1-$DESC_LIMIT)..." else echo $desc fi } trap 'traperror ${LINENO} $? "$BASH_COMMAND" $BASH_LINENO "${FUNCNAME[@]}"' ERR trap trapkill SIGTERM SIGINT readonly -f read_config out error die trapkill traperror truncate_description SNAPPER_CONFIGS=$(awk -F'=' '/SNAPPER_CONFIGS/ {gsub(/"/, "", $2); print $2}' "$SNAPPER_CONFIG_FILE") read_config "$SNAPPAC_CONFIG_FILE" readonly DESC_LIMIT=${DESC_LIMIT:-48} readonly ABORT_ON_FAIL=${ABORT_ON_FAIL:-"no"} for CONFIG in $SNAPPER_CONFIGS; do unset SNAPSHOT unset PRE_DESCRIPTION unset POST_DESCRIPTION unset CLEANUP_ALGORITHM read_config "/etc/snap-pac/$CONFIG.conf" if [[ $CONFIG == "root" ]]; then SNAPSHOT=${SNAPSHOT:-"yes"} else SNAPSHOT=${SNAPSHOT:-"no"} fi PRE_DESCRIPTION=${PRE_DESCRIPTION:-"$pacman_cmd"} POST_DESCRIPTION=${POST_DESCRIPTION:-"$pacman_cmd"} CLEANUP_ALGORITHM=${CLEANUP_ALGORITHM:-"number"} [[ $SNAPSHOT == "no" ]] && continue prefile="/tmp/$argv0-pre_$CONFIG" snapper_cmd="snapper --config $CONFIG create --type $pre_or_post --cleanup-algorithm $CLEANUP_ALGORITHM --print-number --description" if [[ "$pre_or_post" == "pre" ]]; then x=$($snapper_cmd "$(truncate_description $PRE_DESCRIPTION)") printf "==> %s: $(echo $x | tee "$prefile")\n" "$CONFIG" elif [[ -f $prefile && "$pre_or_post" == "post" ]]; then x=$($snapper_cmd "$(truncate_description $POST_DESCRIPTION)" --pre-number "$(< "$prefile")") printf "==> %s: %s\n" "$CONFIG" "$x" rm -f "$prefile" fi done exit 0