The Rackspace Cloud allows you to save your images to Cloud Files, however currently your automated backups are still stored with server.

Additionally you can only have a backup every day. What if you wanted one say, every 6 hours? You can achieve this with the API, curl and a bash script.

Below is the script, all you need to do is plug in your API key and your username. After that we just need to create a cron job to run it and we’re all good to go.

This Script Requires the Following:

  • Awk
  • cURL

These should all be installed by default, try running the script manually and making sure it doesn’t return any errors before setting up your cron job.

#!/bin/bash

# Pass in the server name to backup (the name in the control panel), and
# optionally a base name for the backup image
if [[ -z $1 ]]; then
    echo "usage: $0 server_name [base_name]"
    exit 1
else
    servername=$1
fi

if [[ -n $2 ]]; then
    imagename=$2;
else
    imagename=$servername;
fi

# Specify Username and API Key Here
username=USERNAME
apikey=APIKEY

# Helper functions
function die() { echo "[`timestamp`] $*"; exit 1; }
function timestamp() { echo "`date +%FT%H:%M:%S`"; }
function strip() { echo $1 | tr -d "\r"; }

# Authenticate and make sure it logs in.
# Additionally get the Auth Token and Server URL
while read -r key value rest ; do
    if [[ $key = "X-Server-Management-Url:" ]]; then
        url=`strip $value`
    elif [[ $key = "X-Auth-Token:" ]]; then
        token=`strip $value`
    elif [[ $key = "HTTP/1.1" ]]; then
        status=`strip $value`
    fi
done <<< "`curl -s -i -H "X-Auth-User: $username" -H "X-Auth-Key: $apikey" \
           https://auth.api.rackspacecloud.com/v1.0`"

# We should get a 204, but that could change, so we accept any 200 status
if [[ ! $status =~ 20. ]]; then
    die "Failed to Auth, check the username and apikey variables. " \
        "Currently they are set to $username and $apikey"
fi

shopt -s nocasematch
serverlist=`curl -s -H "X-Auth-Token: $token" $url/servers`

# nb: set our field seperator to "\n" for the "for" loop below
OLDIFS=$IFS
IFS=`echo -en "\n"`

# Find our server id...this is magical...don't edit it
for server in `echo $serverlist | \
               awk -F':\\\\[' '{gsub("},{", "\n", $2); \
                                gsub(/\{|\}|\[|\]|\"/, "", $2); \
                                print $2}'`
do
    id=`echo $server | awk -F: '{if ($3 == "'$servername'") { \
                                     split($2, a, ","); print a[]}}'`
    if [[ -n $id ]]; then break; fi
done

IFS=$OLDIFS

if [[ -z $id ]]; then
    die "Server not found, check the server name. " \
        "Currently it is set to $servername"
fi

# Create the server image
time=`timestamp`
tmp=`curl -s -X POST -H "X-Auth-Token: $token" \
                     -H "Content-type: application/json" \
     -d '{ "image" : {"serverId": '$id', \
                      "name": "'$imagename'-'$time'"}}' $url/images`

if [[ ! $tmp =~ "QUEUED" ]]; then
    die $tmp
fi
shopt -u nocasematch
echo "[`timestamp`] Image Created: $imagename-$time"

Now that we have our script, you'll want to copy and paste the contents into a file and save it, I'm going to call mine backup.sh. Once we have it saved, you can test it with (where server_name is the name of the server to take the image of, as it is displayed in the Control Panel)

./backup.sh server_name


After that, we need to create our log file. My non-root user:group will be dewey:dewey, alter this to your system needs.

             # touch /var/log/csbackup.log
             # chown dewey:dewey /var/log/csbackup.log


Now as our user we're going to manually test and make sure it logs

           $  ./backup.sh server_name >> /var/log/csbackup.log
           $ cat /var/log/csbackup.log

The last thing we need to do is create our cron job. First access the crontab with

          $ crontab -e

And we make it run every day at say, 11PM

        0  23  *  *  *  bash /home/dewey/backup.sh server_name >> /var/log/csbackup.log

You can of course specify it to run as much as you want, however keep in mind that if a backup is already running for the server, it can't initiate another.

« »