Skip to content

Instantly share code, notes, and snippets.

@xtex404
Last active September 6, 2019 20:47
Show Gist options
  • Select an option

  • Save xtex404/45447e56bbb90904816f07986793eeca to your computer and use it in GitHub Desktop.

Select an option

Save xtex404/45447e56bbb90904816f07986793eeca to your computer and use it in GitHub Desktop.
cron script to scan for and auto-commit all on-disk etckeeper repo; make sure updatedb is installed and run daily. put in /etc/cron.hourly.d .. and remember to null out /etc/cron.daily.d/etckeeper
#!/bin/bash
##
## etckeeper hourly snapshot cron script
## justin matlock (https://github.com/xtex404/)
## 2015-02-15, updated 2019-09-06
##
## this script will use mlocate's database to find all .etckeeper directories
## on your server, then check to see if it should perform an etckeeper commit
## automatically. it will also run the gc/prune process on each etckeeper git
## repo once a week, since it can get pretty big on some servers.
##
## put this script in /etc/cron.hourly.d/etckeeper ... and then null out the
## script in /etc/cron.daily.d/etckeeper (cat /etc/null > /etc/cron.daily.d/etckeeper)
## since yum/dnf will put the crontab script back if you delete it.
##
MYNAME="$( basename "$0" )"
## if non-interactive (cron), redirect all output to syslog
[[ -t "0" || -p /dev/stdin ]] && INTERACTIVE=1 || unset INTERACTIVE
if [[ -z $INTERACTIVE ]]; then
exec > >(logger -t "${MYNAME}[$$]" -e -p user.info )
exec 2> >(logger -t "${MYNAME}[$$]" -se -p user.err >&2)
fi
## renice this so we don't slam the system
renice -n 10 -p $$ > /dev/null 2>&1
ionice -c3 -p $$
if [[ ! -x /usr/bin/etckeeper ]]; then
echo "etckeeper isn't installed or isn't executable. abort."
exit 99
fi
## weekly on sunday at 3am, also run a gc after the commit
## because these repos can get... big.
if [[ `date +"%w %H"` == "0 03" ]]; then
GC=1
else
GC=0
fi
# check etckeeper's (from dist /etc/etckeeper/daily)
lockfile=/var/cache/etckeeper/packagelist.pre-install
lockloop=0
lockwait=30
while [ -e $lockfile ]; do
lockloop=$(( $lockloop + 1 ))
if [ -e "$lockfile" ] && [ -n "$(find "$lockfile" -mtime +1)" ]; then
rm -f "$lockfile" # stale
elif [ -e $lockfile ]; then
echo "Active etckeeper lockfile (\"$lockfile\") exists. Waiting 2 seconds to try again ($lockloop of $lockwait)." >&2
sleep 2
fi
if [[ $lockloop -gt $lockwait ]]; then
echo "Active etckeeper is still running. Aborting." >&2
exit 1
fi
done
tmplog=$( mktemp )
abort() {
rm -f $tmplog
}
trap abort EXIT
. /etc/etckeeper/etckeeper.conf
AVOID_SPECIAL_FILE_WARNING=1
locate -q .etckeeper | while read EKCFGFILE; do
REPO_DIR="$( dirname "$EKCFGFILE" )"
if [[ -r "${REPO_DIR}/.git/config" ]]; then
# first check to see if we should even check the repo
/usr/bin/etckeeper unclean -d "${REPO_DIR}" > /dev/null
if [[ $? -eq 0 ]]; then
/usr/bin/etckeeper commit "automatic commit via $MYNAME ($(date))" -d "$REPO_DIR" > $tmplog 2>&1
if [[ $? -eq 0 ]]; then
echo "etckeeper repo \"$REPO_DIR\" committed."
else
echo "etckeeper repo \"$REPO_DIR\" commit failed." >&2
cat $tmplog >&2
echo "" >&2
fi
else
echo "etckeeper repo \"$REPO_DIR\" skipped (unchanged)."
fi
# garbage collection
if [[ $GC -eq 1 ]]; then
echo "etckeeper repo \"$REPO_DIR\" is now being optimized (aggressive)."
BEFORE="$( /bin/du -sh "${REPO_DIR}/.git" | awk '{ print $1 }' )"
/usr/bin/git gc --aggressive > $tmplog 2>&1
if [[ $? -ne 0 ]]; then
echo "Could not optimize \"$REPO_DIR\"." >&2
cat $tmplog >&2
echo "" >&2
else
AFTER="$( /bin/du -sh "${REPO_DIR}/.git" | awk '{ print $1 }' )"
echo "etckeeper repo \"$REPO_DIR\" optimization complete. Size before: $BEFORE, after: $AFTER."
fi
fi
fi
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment