aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2012-05-17 14:55:57 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2012-05-17 15:05:46 +0300
commit6b8fa542771cc9a93a9ecdfb20da9cea0781f1c4 (patch)
treee9998bd888fb29829e013a2de825a74b6e8db87d /lib
downloadbeam-6b8fa542771cc9a93a9ecdfb20da9cea0781f1c4.tar.gz
beam-6b8fa542771cc9a93a9ecdfb20da9cea0781f1c4.tar.bz2
Initial import
Diffstat (limited to 'lib')
-rw-r--r--lib/Makefile.am1
-rw-r--r--lib/backup/.gitignore1
-rw-r--r--lib/backup/Makefile.am11
-rw-r--r--lib/backup/common.in86
-rwxr-xr-xlib/backup/fs.sh92
-rwxr-xr-xlib/backup/postgres.sh72
6 files changed, 263 insertions, 0 deletions
diff --git a/lib/Makefile.am b/lib/Makefile.am
new file mode 100644
index 0000000..b26ee9a
--- /dev/null
+++ b/lib/Makefile.am
@@ -0,0 +1 @@
+SUBDIRS=backup \ No newline at end of file
diff --git a/lib/backup/.gitignore b/lib/backup/.gitignore
new file mode 100644
index 0000000..5621a6e
--- /dev/null
+++ b/lib/backup/.gitignore
@@ -0,0 +1 @@
+common.sh
diff --git a/lib/backup/Makefile.am b/lib/backup/Makefile.am
new file mode 100644
index 0000000..ec4cb91
--- /dev/null
+++ b/lib/backup/Makefile.am
@@ -0,0 +1,11 @@
+libbackupdir=$(libdir)/backup
+libbackup_SCRIPTS=\
+ common.sh\
+ fs.sh\
+ postgres.sh
+EXTRA_DIST=\
+ common.in\
+ fs.sh\
+ postgres.sh
+DISTCLEANFILES=common.sh
+include $(top_srcdir)/Make.rules
diff --git a/lib/backup/common.in b/lib/backup/common.in
new file mode 100644
index 0000000..ab80204
--- /dev/null
+++ b/lib/backup/common.in
@@ -0,0 +1,86 @@
+#! /bin/bash
+
+# Force C locale
+LC_ALL=C
+export LC_ALL
+
+prologue_hook=
+epilogue_hook=
+
+# User configuration variables
+backup_tar_options=
+backup_suffix=
+backup_archive_dir=
+backup_snapshot_dir=
+backup_verbose=
+backup_logfile="/var/log/backup"
+
+error() {
+ echo >&2 $0: $*
+}
+
+logit() {
+ echo `date`: $*
+}
+
+abend() {
+ ec=$1
+ shift
+ error $@
+ exit $ec
+}
+
+tarcode() {
+ case $1 in
+ 0) echo "`date`: success";;
+ 1) echo "`date`: some files changed while being archived";;
+ 2) echo "`date`: fatal error occurred, but trying to continue anyway"
+ tarerror=$((tarerror + 1));;
+ *) echo "`date`: unexpected error code $1"
+ tarerror=$((tarerror + 1));
+ esac
+}
+
+load_config() {
+ local delayed_exit
+
+ test -z "$BACKUP_CONFIG" && BACKUP_CONFIG=@SYSCONFDIR@/backup.conf
+ if [ -r $BACKUP_CONFIG ]; then
+ . $BACKUP_CONFIG
+ else
+ abend 1 "configuration file $BACKUP_CONFIG does not exist or is unreadable"
+ fi
+
+ if [ -z "$backup_items" ]; then
+ abend 1 "backup_items not specified"
+ fi
+
+ delayed_exit=
+ loaded_types=
+ for item in $backup_items
+ do
+ eval type=\$${item}_type
+ if [ -z "$type" ]; then
+ error "${item}_type not set"
+ delayed_exit=1
+ continue
+ fi
+
+ if echo "$loaded_types" | grep -wq $type; then
+ :
+ elif [ -x $libdir/${type}.sh ]; then
+ . $libdir/${type}.sh || delayed_exit=1
+ loaded_types="$loaded_files
+$type"
+ else
+ error "$libdir/${type}.sh not found"
+ delayed_exit=1
+ fi
+
+ ${type}_check $item || delayed_exit=1
+ done
+
+ test -n "$delayed_exit" && abend 1 "aborting"
+
+ tar_suffix=${backup_suffix:-.tar}
+}
diff --git a/lib/backup/fs.sh b/lib/backup/fs.sh
new file mode 100755
index 0000000..3950e37
--- /dev/null
+++ b/lib/backup/fs.sh
@@ -0,0 +1,92 @@
+#! /bin/bash
+
+# initdb item
+# Initializes snapshot for the given basename.
+initdb() {
+ local filename
+
+ if [ -n "$dry_run" ]; then
+ logit "initializing snapshot for $1"
+ return
+ fi
+
+ if [ $level -eq 0 ]; then
+ filename=$backup_snapshot_dir/$1-$week-$round-$level.db
+ test -r $filename && rm $filename
+ else
+ if [ $level -eq 1 ]; then
+ filename=$backup_snapshot_dir/$1-$week-0-0.db
+ else
+ filename=$backup_snapshot_dir/$1-$week-$round-$((level - 1)).db
+ fi
+ if [ -r $filename ]; then
+ cp $filename $backup_snapshot_dir/$1-$week-$round-$level.db
+ else
+ abend 1 "previous snapshot file $filename not found; cannot backup at level $level"
+ exit 1
+ fi
+ fi
+}
+
+# fs_check item
+fs_check() {
+ local rc=0
+
+ eval root=\$${1}_dir
+ eval files=\$${1}_files
+
+ test -z "$root" && rc=1 && error "${1}_dir not set"
+ test -z "$files" && rc=1 && error "${1}_files not set"
+ return $rc
+}
+
+# fs_backup item
+fs_backup() {
+ local basename text root files
+
+ basename=$1-$week-$round-$level
+ eval text=\$${1}_text
+ eval root=\$${1}_dir
+ eval files=\$${1}_files
+
+ test -z "$root" && abend 1 "${1}_dir not set"
+ test -z "$files" && abend 1 "${1}_files not set"
+ test -z "$text" && text="$1"
+ initdb $1
+ logit "backing up $text ($basename.$tar_suffix)"
+ $dry_run tar $verbose $taroptions \
+ -c -f $backup_archive_dir/$basename.$tar_suffix \
+ --listed=$backup_snapshot_dir/$basename.db \
+ -C $root $files
+ tarcode $?
+}
+
+# fs_restore item
+fs_restore() {
+ local i text root files tarcommand
+
+ eval text=\$${1}_text
+ eval root=\$${1}_dir
+ eval files=\$${1}_files
+
+ test -z "$root" && abend 1 "${1}_dir not set"
+ test -z "$files" && abend 1 "${1}_files not set"
+ test -z "$text" && text="$1"
+
+ tarcommand="tar $verbose $taroptions -C $root --listed-incremental=/dev/null -f"
+
+ logit "restoring $text"
+ logit "restoring from level 0 backup"
+
+ $dry_run $tarcommand $backup_archive_dir/$1-$week-0-0.$tar_suffix
+ tarcode $?
+
+ for i in $(seq 1 $level)
+ do
+ logit "restoring from the $round/$i backup"
+ $dry_run $tarcommand $backup_archive_dir/$1-$week-$round-$i.tar.bz2
+ tarcode $?
+ done
+ logit "finished restoring $text"
+}
+
diff --git a/lib/backup/postgres.sh b/lib/backup/postgres.sh
new file mode 100755
index 0000000..953c467
--- /dev/null
+++ b/lib/backup/postgres.sh
@@ -0,0 +1,72 @@
+#! /bin/bash
+
+# postgres_check item
+postgres_check() {
+ eval database=\$${1}_database
+ test -z "$database" && error "${1}_database not set" && return 1
+ return 0
+}
+
+# postgres_backup item
+postgres_backup() {
+ local database
+
+ logit "backing up PostgreSQL $1"
+ eval database=\$${1}_database
+ test -z "$database" && abend 1 "${1}_database not set"
+ if [ -z "$dry_run" ]; then
+ su postgres -c "pg_dump $verbose $database" > $backup_snapshot_dir/$1-$week-$round-$level
+ else
+ echo "su postgres -c \"pg_dump $verbose $database\" > $backup_snapshot_dir/$1-$week-$round-$level"
+ fi
+
+ if [ $? -ne 0 ]; then
+ tarerror=$((tarerror + 1))
+ echo >&2 "`date`: failed"
+ else
+ echo "`date`: creating $1-$week-$round-$level.$tar_suffix"
+ $dry_run tar $verbose $taroptions \
+ -f $backup_archive_dir/$1-$week-$round-$level.$tar_suffix \
+ -C $backup_snapshot_dir $1-$week-$round-$level
+ tarcode $?
+ $dry_run rm $snapshotdir/dbdump-$week-$round-$level
+ fi
+}
+
+postgres_restore() {
+ local u database
+
+ eval database=\$${1}_database
+ logit "restoring PostgreSQL database $database"
+ u=$(umask)
+ trap "umask $u" 1 2 3 13 15
+ umask 077
+ $dry_run tar $verbose $taroptions \
+ -f $backup_archive_dir/$1-$week-$round-$level.$tar_suffix
+ e=$?
+ tarcode $e
+ if [ $e -eq 0 ]; then
+ logit "restoring database from the dump"
+ if [ -n "$dry_run" ]; then
+ cat <<-EOT
+ su postgres -c "dropdb $database"
+ su postgres -c "createdb $database"
+ su postgres -c "psql -d $database -f $1-$week-$round-$level"
+ rm $1-$week-$round-$level
+EOT
+ elif [ -r $1-$week-$round-$level ]; then
+ su postgres -c "dropdb $database"
+ su postgres -c "createdb $database"
+ su postgres -c "psql -d $database -f $1-$week-$round-$level" > db-$1.log
+ if grep ERROR db-$1.log >/dev/null; then
+ error "errors occurred during restore; see db-$1.log for details"
+ error "dump preserved in file $1-$week-$round-$level"
+ tarerror=$((tarerror + 1))
+ else
+ rm $1-$week-$round-$level
+ fi
+ fi
+ fi
+ umask $u
+ trap - 1 2 3 13 15
+}

Return to:

Send suggestions and report system problems to the System administrator.