commit 1c7ed45089572b0ff471e8394d93e8a3847fc334 Author: Ryan McCabe rmccabe@redhat.com Date: Sat Aug 20 14:24:48 2011 -0400
Add database backup and restore functionality to the luci init file.
input_files/initscript/initscript.in | 141 +++++++++++++++++++++++++++++++++- 1 files changed, 138 insertions(+), 3 deletions(-) --- diff --git a/input_files/initscript/initscript.in b/input_files/initscript/initscript.in index c4c4511..135e5e1 100755 --- a/input_files/initscript/initscript.in +++ b/input_files/initscript/initscript.in @@ -37,6 +37,7 @@ prog="@SERVICENAME@" config="@BASECONFIG@" sysconfig="@SYSCONFIG@" exec="@LAUNCHER@" +sqlite_bin="/usr/bin/sqlite3"
# Defaults that can be overridden by the content of $sysconfig @@ -62,6 +63,10 @@ PORT=@PORT@
STATE_DIR="@STATEDIR@" DB_FILE="@DBFILE@" +DB_DIR="$(dirname $DB_FILE)" +BACKUP_DIR="$(dirname $DB_FILE)" +DB_PERMS=0640 +BACKUP_PERMS=0640
RUNTIMEDATA_DIR="@RUNTIMEDATADIR@" CACHE_DIR="@CACHEDIR@" @@ -159,7 +164,7 @@ prepare_config() { prepare_db() { touch "$DB_FILE" chown $DAEMON_USER:$DAEMON_GROUP "$DB_FILE" \ - && chmod 0640 "$DB_FILE" + && chmod -- $DB_PERMS "$DB_FILE" if [ $? -ne 0 ]; then rm -f -- "$DB_FILE" &>/dev/null $ECHOFUNC "Unable to change ownership/attributes of the $PKG_NAME database file (`$DB_FILE')." >&2 @@ -272,8 +277,111 @@ initialize() { fi }
+list_database_dumps() { + /bin/ls -1 -- $BACKUP_DIR/@SERVICENAME@-backup*.db 2>/dev/null + return 0 +} + +dump_database() { + if [ -n "$1" ]; then + output_file="$1" + else + output_file="$BACKUP_DIR/@SERVICENAME@-backup$(/bin/date +%Y%m%d%H%M%S).db" + fi + + if [ -e "$output_file" ]; then + if [ "$2" != "--force" ] && [ "$2" != "-f" ]; then + echo "A file named `$output_file' already exists. Pass the additional argument of --force to overwrite it." >&2 + return 1 + fi + fi + $sqlite_bin "$DB_FILE" '.dump' > "$output_file" + if [ $? -ne 0 ]; then + echo "Failed to create `$output_file' properly." >&2 + rm -f -- "$output_file" + return 1 + fi + chown $DAEMON_USER:$DAEMON_GROUP "$output_file" \ + && chmod -- $BACKUP_PERMS "$output_file" + if [ $? -ne 0 ]; then + echo "Unable to change ownership/attributes of the $PKG_NAME database backup file (`$output_file')." >&2 + rm -f -- "$output_file" >&/dev/null + return 1 + fi + restorecon -R -- "$DB_DIR" "$BACKUP_DIR" >&/dev/null + return 0 +} + +load_database() { + db_dump_file=$1 + if [ ! "$db_dump_file" ]; then + echo "No database backup file was specified. Run `$0 list-backups' to get a list of known existing backup files." >&2 + return 1 + fi + + if [ ! -r "$db_dump_file" ]; then + echo "The database backup in `$db_dump_file' cannot be read." >&2 + return 1 + fi + + tmp_db="$(mktemp --tmpdir=$DB_DIR)" + if [ $? -ne 0 ]; then + echo "Unable to create a temporary file in `$DB_DIR'." >&2 + return 1 + fi + $sqlite_bin $tmp_db ".read $db_dump_file" + if [ $? -ne 0 ] || [ ! -s "$tmp_db" ]; then + # sqlite will return 0 even if you feed it non-sql input. In the case + # of bad input, the database file will have size 0. + echo "Unable to restore the database from the backup file `$db_dump_file'" >&2 + rm -f -- "$tmp_db" >&/dev/null + return 1 + fi + chown $DAEMON_USER:$DAEMON_GROUP "$tmp_db" \ + && chmod -- $DB_PERMS "$tmp_db" + if [ $? -ne 0 ]; then + echo "Unable to change ownership/attributes of the $PKG_NAME database file (`$tmp_db')." >&2 + rm -f -- "$tmp_db" >&/dev/null + return 1 + fi + + old_exists=0 + if [ -e "$DB_FILE" ]; then + old_exists=1 + bknum=0 + while [ -e "$DB_FILE".$bknum ]; do + bknum=$(($bknum+1)) + done + old_db_name="$DB_FILE".$bknum + + mv -n -- "$DB_FILE" "$old_db_name" + if [ $? -ne 0 ]; then + # it appeared out of nowhere + echo "Unable to move the existing database file to `$old_db_name'." >&2 + rm -f -- "$tmp_db" >&/dev/null + return 1 + fi + fi + + ret_code=0 + mv -- "$tmp_db" "$DB_FILE" + if [ $? -ne 0 ]; then + rm -f -- "$tmp_db" >&/dev/null + if [ $old_exists -eq 1 ]; then + echo "Unable to move the newly created database file to `$DB_FILE'. Trying to restore database from `$old_db_name'." >&2 + mv -- "$old_db_name" "$DB_FILE" + else + echo "Unable to move the newly created database file to `$DB_FILE'." >&2 + fi + ret_code=1 + fi + + restorecon -R -- "$DB_DIR" "$BACKUP_DIR" >&/dev/null + return $ret_code +} + start_server() { - # TODO: Can be the dependency on running saslauthd solved in a better way? + # TODO: Can the dependency on saslauthd running be solved in a better way? # LSB header doesn't seem to help there. /sbin/service saslauthd start || return 1
@@ -380,8 +488,35 @@ case "$1" in entry_check || exit 4 $1 ;; + backup-db) + entry_check || exit 4 + status &>/dev/null + if [ $? -eq 0 ]; then + echo "The database backup operation can proceed only when @SERVICENAME@ is stopped. Stop @SERVICENAME@, then try again." >&2 + exit 1 + fi + shift + dump_database $* + exit $? + ;; + restore-db) + entry_check || exit 4 + status &>/dev/null + if [ $? -eq 0 ]; then + echo "The database restore operation can proceed only when @SERVICENAME@ is stopped. Stop @SERVICENAME@, then try again." >&2 + exit 1 + fi + shift + load_database $* + exit $? + ;; + list-backups) + entry_check || exit 4 + list_database_dumps + exit $? + ;; *) - echo $"Usage: $0 {start|stop|status|reload|restart|condrestart|try-restart}" + echo $"Usage: $0 {start|stop|status|reload|restart|condrestart|try-restart|backup-db|restore-db|list-backups}" exit 2 esac exit $?
luci-commits@lists.fedorahosted.org