Running controller backup as a cron-job or how?

I’m trying to implement a nightly backup of a juju controller.

I’m reading the docs: https://juju.is/docs/olm/controller-backups

What is the recommended way of automating this, not having to run an external “juju command” which would add the need to distribute juju admin credentials.

My initial take on this, is to figure out how to run a simple systemd-cron job or something similar. But, I can’t find any such “system-level” command that I could use.

Any advice ?

2 Likes

@hallback You might have some material here?

Something that would also be valuable for doc @tmihoc

2 Likes

Hi. I use a shell script that I run daily from cron for this. It basically comes down to:

juju create-backup --model=CONTROLLERNAME:controller --filename=backup.tar.gz

To solve the problem with password for the Juju user in question, you can put a password in ~/.local/share/juju/accounts.yaml like this:

controllers:
  maas-controller:
    user: admin
    last-known-access: superuser
    password: xxxxxxxxxxx
  lxd-controller:
    user: admin
    last-known-access: superuser
    password: xxxxxxxxxxx

I have a script that I run for more than one controller from a specific location. It looks like this:

#!/bin/bash

# vim:set filetype=sh expandtab tabstop=4 softtabstop=4 shiftwidth=4 autoindent smartindent:

# johan.hallbaeck@ibeo-as.com 2022-04-27

# Configurables
JUJU=/snap/bin/juju
LOGFILE=/var/log/juju-controller-backup.log
KEEPCOUNT=10
DESTDIR=/opt/maasbackup
NOW=$(date +%Y%m%d-%H%M%S)

# Logging function, courtesy of cdarke:
# https://stackoverflow.com/questions/49851882/how-to-log-echo-statement-with-timestamp-in-shell-script/
logit() {
    while read -r
    do
        echo "$(date +%F-%H:%M:%S) $REPLY" >> ${LOGFILE}
    done
}

# Set up the logging
touch $LOGFILE || { echo No write access to $LOGFILE, cannot continue; exit 1 ; }

# Redirect stdout & stderr to logit(), saving the old file descriptors
exec 3>&1 4>&2 1>> >(logit) 2>&1

echo "$0" starting.

# Verify that the controller argument only contains letters etc
if ! echo "$1" | grep -Eq '^([A-Za-z0-9-]+)$' ; then
    echo Controller argument is invalid, exiting
    exit 1
fi

JUJUCONTROLLER="$1"
DESTDIR="$DESTDIR"/"$JUJUCONTROLLER"

# Check access
$JUJU status --model="$JUJUCONTROLLER":controller > /dev/null 2>&1
test $? -eq 0 || { echo Cannot check status of controller model on "$JUJUCONTROLLER", exiting ; exit 1 ; }

mkdir -p "$DESTDIR"

"$JUJU" create-backup --model="$JUJUCONTROLLER":controller \
    --filename="$DESTDIR"/juju-backup_"$JUJUCONTROLLER"_"$NOW".tar.gz \
    > "$DESTDIR"/juju-backup_"$JUJUCONTROLLER"_"$NOW".tar.gz.out 2>&1
BACKUPRET=$?

# Always append the output to the log
cat "$DESTDIR"/juju-backup_"$JUJUCONTROLLER"_"$NOW".tar.gz.out >> $LOGFILE

if [ $BACKUPRET -ne 0 ] ; then
    echo Backup failed, exiting
    exit 1
fi

echo Backup was successfully created in "$DESTDIR"/"$JUJUCONTROLLER"

for i in $(find "$DESTDIR" -type f -name '*.tar.gz' | sort | head -n -$KEEPCOUNT | xargs) ; do
    if [ -f "$i" ] ; then
        echo Removing old backup "$i" in destination
        rm -f "$i" "$i".out
    fi
done

echo "$0" exiting.

Then create a file in /etc/cron.d/ that looks something like this:

0 6 * * mon-fri root /path/to/juju-controller-backup.sh maas-controller
10 6 * * mon-fri root /path/to/juju-controller-backup.sh lxd-controller

Then of course the destination of your backups should not be on the same host as the controller :slight_smile:

1 Like

@joakimnyman ping you in on this.