#!/bin/sh
#
# koha-dump: dump all contents and configs for a Koha site
# Copyright 2010  Catalyst IT, Ltd
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.


set -e

# include helper functions
if [ -f "/usr/share/koha/bin/koha-functions.sh" ]; then
    . "/usr/share/koha/bin/koha-functions.sh"
else
    echo "Error: /usr/share/koha/bin/koha-functions.sh not present." 1>&2
    exit 1
fi

# Make sure the files we create are not accessible by anyone else.
umask 0077

usage()
{
    local scriptname=$(basename $0)

    cat <<EOF
$scriptname

This script dumps your Koha instance data for backup or migration.

The schema only option can be used to compare your existing database schema
to the expected Koha structure.

Usage:
$scriptname [--quiet|-q] [--exclude-indexes] instancename1 [instancename2...]
$scriptname -h|--help

    --schema-only         Dump only the database schema
    --exclude-indexes     Exclude Zebra indexes from the backup
    --exclude-logs        Exclude /var/log/koha/name from the backup
    --uploaded_files      Include uploaded files.
    --uploaded_temp_files Include temporary uploaded files.
    --quiet|-q            Make the script avoid printing to STDOUT
                          (useful for calling from another scripts)
    --help|-h             Display this help message
    --without-db-name     Do not include database name

EOF
}

dump_instance()
{
    local name=$1

    kohaconfig="/etc/koha/sites/$name/koha-conf.xml"
    date="$(date +%Y-%m-%d)"

    [ "$quiet" = "no" ] && echo "Dumping Koha site $name:"

    # Dump database.
    mysqlhost="$( xmlstarlet sel -t -v 'yazgfs/config/hostname' $kohaconfig )"
    mysqldb="$( xmlstarlet sel -t -v 'yazgfs/config/database' $kohaconfig )"
    mysqluser="$( xmlstarlet sel -t -v 'yazgfs/config/user' $kohaconfig )"
    mysqlpass="$( xmlstarlet sel -t -v 'yazgfs/config/pass' $kohaconfig )"
    backupdir="$( xmlstarlet sel -t -v 'yazgfs/config/backupdir' $kohaconfig || true )"
    [ -z "$backupdir" ] && backupdir="/var/spool/koha/$name"
    dbdump="$backupdir/$name-$date.sql.gz"
    dbflag="--databases"
    [ "$without_db_name" = "yes" ] && dbflag=""
    if [ "$schema_only" = "yes" ]
    then
        schemadump="$backupdir/$name-schema-$date.sql"
        [ "$quiet" = "no" ] && echo "* schema to $schemadump"
        mysqldump $dbflag -d --host="$mysqlhost" --single-transaction \
            --user="$mysqluser" --password="$mysqlpass" "$mysqldb" | sed --expression='s/ AUTO_INCREMENT=[0-9]\+//' > "$schemadump"
        chown "root:$name-koha" "$schemadump"
        chmod g+r "$schemadump"
    else
        [ "$quiet" = "no" ] && echo "* DB to $dbdump"
        mysqldump $dbflag --host="$mysqlhost" --single-transaction \
            --user="$mysqluser" --password="$mysqlpass" "$mysqldb" |
            gzip > "$dbdump"
        chown "root:$name-koha" "$dbdump"
        chmod g+r "$dbdump"

        instancefile="$name.conf"

        # Dump configs, logs, etc.
        metadump="$backupdir/$name-$date.tar.gz"
        output="* configs, logs"

        if [ "$exclude_indexes" = "yes" ]; then
            excludes="--exclude=var/lib/koha/$name/biblios \
                  --exclude=var/lib/koha/$name/authorities"
        fi

        if [ "$uploaded_files" = "yes" ]; then
            # Remove leading /
            uploaded_files_dir=$(echo $(get_upload_path $name) | cut -c 2-)
            output="$output, uploaded files"
        fi

        if [ "$uploaded_temp_files" = "yes" ]; then
            # Remove leading /
            tempdir=$(echo $(get_tmp_path $name) | cut -c 2-)
            uploaded_temp_files_dir="$tempdir/koha_${name}_upload"
            if ! [ -d /$uploaded_temp_files_dir ]; then
                mkdir /$uploaded_temp_files_dir
            fi
            output="$output, uploaded temporary files"
        fi

        output="$output to $metadump"
        [ "$quiet" = "no" ] && echo "$output"

        # tar has exit status 1 if any file has changed while being read,
        # which is likely to happen as the logfiles are included.
        set +e

        if [ "$exclude_logs" = "yes" ]; then
            tar -czf "$metadump" -C / $excludes \
                "etc/koha/sites/$name" \
                "etc/apache2/sites-available/$instancefile" \
                "etc/apache2/sites-enabled/$instancefile" \
                "var/lib/koha/$name" \
                $uploaded_files_dir \
                $uploaded_temp_files_dir
        else
            tar -czf "$metadump" -C / $excludes \
                "etc/koha/sites/$name" \
                "etc/apache2/sites-available/$instancefile" \
                "etc/apache2/sites-enabled/$instancefile" \
                "var/lib/koha/$name" \
                "var/log/koha/$name" \
                $uploaded_files_dir \
                $uploaded_temp_files_dir
        fi

        if [ "$?" != "1" -a "$?" != "0" ]; then
            exit $?
        fi

        set -e

        chown "root:$name-koha" "$metadump"
        chmod g+r "$metadump"

        [ "$quiet" = "no" ] && echo "Done."
    fi
}

# Default values
quiet="no"
exclude_indexes="no"
without_db_name="no"
schema_only="no"
exclude_logs="no"

while [ $# -gt 0 ]; do

    case "$1" in
        --schema-only)
            schema_only="yes"
            shift ;;
        --exclude-indexes)
            exclude_indexes="yes"
            shift ;;
        --exclude-logs)
            exclude_logs="yes"
            shift ;;
        --without-db-name)
            without_db_name="yes"
            shift ;;
       --uploaded_files)
            uploaded_files="yes"
            shift ;;
        --uploaded_temp_files)
            uploaded_temp_files="yes"
            shift ;;
        -h|--help)
            usage ; exit 0 ;;
        -q|--quiet)
            quiet="yes"
            shift ;;
        -*)
            die "Error: invalid option switch ($1)" ;;
        *)
            # We expect the remaining stuff are the instance names
            break ;;
    esac

done

# Read instance names
if [ $# -gt 0 ]; then
    # We have at least one instance name
    for name in "$@"; do

        if is_instance $name; then

            dump_instance $name

        else
            if [ "$quiet" = "no" ]; then
                die "Error: Invalid instance name $name"
            else
                exit 1
            fi
        fi

    done
else
    if [ "$quiet" = "no" ]; then
        die "Error: you must provide at least one instance name"
    else
        exit 1
    fi
fi

exit 0
