MikroTik Solutions

backup-routers at trunk
Login

File bin/backup-routers artifact 67a7890b6d on branch trunk


#!/bin/bash

# User-configurables
rdir=~/museum
repo=$rdir/routeros-backups.fossil
bdir=~/routeros-backups

# Make backup checkout directory if it doesn't exist already.
mkdir -p $bdir
cd $bdir

# Prepare Fossil repository and/or checkout as necessary.
if ! [ -r .fslckout ]
then
    mkdir -p $rdir
    if ! [ -r $repo ] 
    then
        fossil init \
            --project-name routeros-backups \
            --project-desc "RouterOS configuration backups" \
            $repo
    fi
    fossil open --force $repo
    if ! [ -d .fossil-settings ]
    then
        # Tell Fossil not to squawk about binary data in the binary
        # backup files nor CRLFs in the text backup files.
        mkdir .fossil-settings
        echo '*/*.rsc' > .fossil-settings/crlf-glob
        echo '*/*.bin' > .fossil-settings/binary-glob
        fossil add .fossil-settings
    fi
fi

# Default usage: pass all hostnames gleaned from subdirectories in
# Fossil checkout to ourself.
if [ -z "$1" ] ; then exec $0 * ; fi

# Host name passed in by above or interactively from the command line.
for host in "$@"
do
    bf=$host/config.bin
    ef=$host/export.rsc
    if ! [ -d $host ]
    then
        # We were passed a hostname without one or more local existing
        # backups, so set that up.  This simplifies the first-run case
        # by letting you pass the names of existing but as-yet unmanaged
        # hosts.
        mkdir $host
        touch $bf $ef
        fossil add $bf $ef
        initial=1
    fi

    if [ -w $bf ] && [ -w $ef ]
    then
        # Prior backups exist — i.e. not a sidecar dir holding who knows
        # what — so pull fresh ones.  Toss changes deemed trivial.
        ssh $host export show-sensitive terse > $host/export.rsc &&
            ssh $host '/system backup save' &&
            fn=$(ssh $host '/file print detail without-paging' |
                 grep 'name=".*" type="backup"' |
                 tail -1 | 
                 cut -f2 -d\") &&
            test -n "$fn" && scp $host:$fn $host/config.bin
        if [ -z "$initial" ] &&
                ! fossil diff --command diff $host/export.rsc |
                    grep '^[<>]' |
                    grep -qv ' by RouterOS '
        then
            fossil revert $host/config.bin $host/export.rsc
            ssh $host "/file remove $fn"
        fi
    fi
done

if [ -n "$initial" ]
then
    # We created one or more hostname subdirs and initial backup files
    # above, so unconditionally commit those initial versions now.
    fossil ci -m "initial backup for $@"
else
    # Normal case: commit only after user has a chance to look at the
    # diffs of the text backups.
    filter=cat
    if [ -n "$SSH_CONNECTION" ]
    then
        # We're being run over an SSH conn.  Since chances are not good
        # that X11 forwarding is being done, or if it is that the gdiff
        # implementation isn't X-based, use console diff.  Run it thru
        # a pager to make it block.
        diffcmd=diff
        if [ -n "$PAGER" ] ; then filter=$PAGER ; else filter=less ; fi
    elif [ "$(fossil set gdiff-command)" != "gdiff-command" ]
    then
        # The user's set a graphical diff command, so use it.
        diffcmd=gdiff 
    else
        # Fall back to the browser-based diff feature added in Fossil
        # 2.17.  Last because this won't block like the other options,
        # so you won't have a chance to abort the commit by sending
        # Ctrl-C to this script.
        diffcmd="diff -b"
    fi

    # Commit the changes unless the diff fails.
    if fossil $diffcmd */*.rsc | $filter
    then
        fossil ci
    else
        fossil revert
    fi
fi