backup_file_to_s3.erb 2.64 KB
#!/bin/bash
#
# Generated by Chef
#
# Back up directories into an S3 bucket

set -e

suffix=.backup_file_to_s3
[ -f /tmp/*"$suffix" ] && exit 200
tmp_file=$( mktemp --suffix "$suffix" )

log_dir=<%= @log_dir %>
if [[ ! -d "$log_dir" ]] ; then
    mkdir -p "$log_dir"
fi

aws_cmd=<%= @aws_bin %>

exec 3>&1 4>&2
trap 'exec 2>&4 1>&3' 0 1 2 3
exec 1>>"${log_dir}/backup_file_to_s3.log" 2>&1

bucket=<%= @bucket %>
region=<%= @region %>
max_backups=<%= @max_backups %>
bak_dir=<%= @tmp_dir %>

# Array of directories to be backed up.
# 
# Example:
# declare -a tar_dirs=(
#   "/path/to/dira"
#   "/another/path/to/dirb"
# )
#
# Tarball names will be the basename of each path given.
declare -a tar_dirs=(
<% @dirs.each do |dirx| -%>
    "<%= dirx %>"
<% end -%>
)

if [[ ! -d "$bak_dir" ]] ; then
    echo "$(date) : Missing backup directory. Creating."
    mkdir -p "$bak_dir"
fi

# Rotate the current backups in S3
# $1 = directory to be tarred
increment_backup_names() {
    fname=$( basename "$1" )
    bak_keyname="${fname}.tar.gz"

    baks=$( "$aws_cmd" --output text --region "$region" \
                s3api list-objects --bucket "$bucket" \
            | grep '^CONTENTS' | cut -f3 | grep "^${bak_keyname}" || echo "" )

    echo "$(date) : Backup rotation for ${bak_keyname}"
    start=$((max_backups - 1))

    for (( x=start ; x > 0 ; x-- )) ; do
        if echo "$baks" | grep "^${bak_keyname}\\.${x}\$" ; then
            newx=$((x + 1))
            if [[ $newx -lt $max_backups ]] ; then
                "$aws_cmd" --region "$region" \
                    s3 cp "s3://${bucket}/${bak_keyname}.${x}" \
                          "s3://${bucket}/${bak_keyname}.${newx}"
            fi
        fi
    done

    if echo "$baks" | grep "^${bak_keyname}\$" ; then
        "$aws_cmd" --region "$region" \
            s3 cp "s3://${bucket}/${bak_keyname}" \
                  "s3://${bucket}/${bak_keyname}.1"
    fi
}

# Tar up the directory
# $1 = directory to be tarred
tar_dir() {
    fname=$( basename "$1" )
    parent=$( dirname "$1" )
    echo "$(date) : Tar up ${1}"

    tar -C "$parent" -czf "${bak_dir}/${fname}.tar.gz" "$fname"
}

# $1 = directory to be tarred
upload_to_s3() {
    fname=$( basename "$1" )
    echo "$(date) : Upload ${fname}.tar.gz to S3 bucket ${bucket}"

    "$aws_cmd" --region "$region" \
        s3 mv "${bak_dir}/${fname}.tar.gz" "s3://${bucket}/${fname}.tar.gz"
}

for dirx in "${tar_dirs[@]}" ; do
    if [[ -d "$dirx" ]] ; then
        increment_backup_names "$dirx"
        tar_dir "$dirx"
        upload_to_s3 "$dirx"
    else
        echo "$(date) : WARNING : Directory ${dirx} does not exist. Skipping."
    fi
done

rm "$tmp_file"
echo "$(date) : Done"