#!/bin/sh

# Olivier Thauvin <nanardon@mandriva.org>

# $Id: mdk_pg,v 1.9 2006/02/06 20:05:50 othauvin Exp $

check_postgres_install() {
    [ -f /usr/bin/postgres ] || return 1
    [ -f /usr/bin/pg_dumpall ] || return 1
    [ -f /usr/bin/pg_restore ] || return 1
    return 0
}

dump_db() {
    echo "Dumping database into ${BACKUPDIR}/db.${backupid}.gz"
    if [ -z "$force" -a -e ${BACKUPDIR}/db.${backupid}.gz ]; then
        echo "Database dump already exists, aborting"
        return 1
    fi
    su postgres -c "pg_dumpall" | gzip > ${BACKUPDIR}/db.${backupid}.gz
    [ -n "`echo ${PIPESTATUS[*]} | grep '[^ 0]'`" ] && return 1
    return 0
}

dump_config() {
    (
    cd /var/lib/pgsql/data/ || exit 1;
    echo "Backuping configuration into ${BACKUPDIR}/config.${backupid}.tar"
    if [ -z "$force" -a -e ${BACKUPDIR}/config.${backupid}.tar ]; then
        echo "Backup of configuration already exists, aborting"
        return 1
    fi
    tar cf ${BACKUPDIR}/config.${backupid}.tar \
        pg_hba.conf \
        pg_ident.conf \
        postgresql.conf \
        postmaster.opts
    )
}

copy_pg_hba() {
    echo "Overriding pg_hba.conf to allow local connection"
    cat > /var/lib/pgsql/data/pg_hba.conf <<EOF
# This file is come from backup

# "local" is for Unix domain socket connections only
local   all         all                               trust
# IPv4 local connections:
host    all         all         127.0.0.1/32          trust
# IPv6 local connections:
host    all         all         ::1/128               trust

EOF
    return $?
}

restore_db() {
    echo "Reimporting DB from ${BACKUPDIR}/db.${backupid}.gz"
    zcat ${BACKUPDIR}/db.${backupid}.gz | su postgres -c "psql -q template1"
    return $?
}

restore_config() {
    (
    cd /var/lib/pgsql/data || return 1
    echo "Restoring configuration from ${BACKUPDIR}/config.${backupid}.tar"
    tar xf ${BACKUPDIR}/config.${backupid}.tar || return 1
    )
}

restore() {
    echo "
************************
* Starting restoration *
************************"
    service postgresql restart

    copy_pg_hba || exit 1

    service postgresql reload

    restore_db || exit 1

    restore_config || exit 1

    service postgresql reload
}

backup() {
    echo "
*******************
* Starting backup *
*******************"

    service postgresql restart
    
    dump_config || return 1

    copy_pg_hba || return 1

    service postgresql reload

    dump_db || return 1
}

movedata() {

    su postgres -c 'psql template1 -A -t -c "select spclocation from pg_catalog.pg_tablespace"' > ${BACKUPDIR}/tablespaces.${backupid} || return 1

    service postgresql stop

    echo "Moving data from /var/lib/pgsql/data/ to /var/lib/pgsql/data.${backupid}"
    if [ -e /var/lib/pgsql/data.${backupid} ]; then
        if [ -n "$force" ]; then
            rm -fr /var/lib/pgsql/data.${backupid}
        else
            echo "database backup already exists, aborting"
            return 1
        fi
    fi
    for i in `cat ${BACKUPDIR}/tablespaces.${backupid}`; do
        if [ -n ${i} -a -e ${i}.${backupid} ]; then
            if [ -n "$force" ]; then
                rm -fr ${i}.${backupid}
            else
                echo "tablespace backup already exists, aborting"
                return 1
            fi
        fi
    done

    install -d -m700 -o postgres -g postgres /var/lib/pgsql/data.${backupid}
    mv /var/lib/pgsql/data/* /var/lib/pgsql/data.${backupid}

    for i in `cat ${BACKUPDIR}/tablespaces.${backupid}`; do
        if [ -n "$i" ]; then
            echo "Moving tablespace data from ${i} into ${i}.${backupid}"
            mkdir "${i}.${backupid}" || return 1
            mv "${i}"/* "${i}.${backupid}" || return 1
        fi
    done
    return 0
}

umask 002

backupid=`date +%G%m%d-%H%M`

BACKUPDIR=/var/lib/pgsql/backups

version() {
    echo '$Revision: 1.9 $' | sed 's/.* \(.*\) .*/\1/'
}

usage() {
    echo "
`basename $0` -mode [...]

This script backup and restore PostgreSQL database to migrate data from
major PostgreSQL version to another.
It should be run with one of more of:
  -b  Perform a database backup, configuration is backuped into a tar
      pg_hba.conf is override to ensure local access to database, then
      the database is backup by pg_dumpall and compress by gzip.
  -m  Move current data into new directory and allow to create database
      with new internal structure. Tablespaces are also move.
  -r  Restore database from previous backup, postgresql is start, database
      is reimport and comfiguration are restored.

Running `basename $0` -b -m -r is a way to refresh your database then.

  -i backupid       Use this identifier as suffix for backup files, it use
                    during backup and restoration, and should be the same
                    of course.
  -f                Overwrite existing backup files if exists.

  -h                show this help.
  -v                show the version.

If the file /etc/sysconfig/mdkpg exists, it is used for configuration:
  BACKUPDIR=path    Set the backup location, default is /var/lib/pgsql/backups
                    Current settings is: ${BACKUPDIR}.
"
}

[ -f /etc/sysconfig/mdkpg ] && . /etc/sysconfig/mdkpg

while getopts mbrfi:hv option; do
    case $option in
        i) backupid="$OPTARG"   ;;
        r) dorestore=1          ;;
        b) dobackup=1           ;;
        m) domove=1             ;;
        f) force=1              ;;
        h) usage; exit 0        ;;
        v) version; exit 0      ;;
    esac
done

if [ ! check_postgres_install ]; then
    echo ""
    echo "Postgresql is not installed, I can't backup your current database"
    echo "Think to remove your old database to install a new version"
    echo ""
    exit 1
fi

if [ -z "$dobackup" -a -z "$domove" -a -z "$dorestore" ]; then
    usage
    exit 1
fi

if [ -n "$dobackup" ]; then
    backup || exit 1
fi

if [ -n "$domove" ]; then
    movedata || exit 1
fi

if [ -n "$dorestore" ]; then
    restore || exit 1
fi

