2015-11-16 13:37:26 +01:00
#!/usr/bin/env bash
2016-09-09 12:31:54 +02:00
PROGRAM = "obackup.upgrade"
2015-11-16 13:37:26 +01:00
SUBPROGRAM = "obackup"
2016-08-17 17:21:32 +02:00
AUTHOR = "(C) 2016 by Orsiris de Jong"
2015-11-16 13:37:26 +01:00
CONTACT = "http://www.netpower.fr/obacup - ozy@netpower.fr"
OLD_PROGRAM_VERSION = "v1.x"
2016-08-17 17:21:32 +02:00
NEW_PROGRAM_VERSION = "v2.1x"
2019-05-21 12:51:46 +02:00
CONFIG_FILE_REVISION = 2.1
2019-05-21 13:54:31 +02:00
PROGRAM_BUILD = 2019052103
2016-04-13 12:16:23 +02:00
if ! type " $BASH " > /dev/null; then
echo "Please run this script only with bash shell. Tested on bash >= 3.2"
exit 127
fi
2015-11-16 13:37:26 +01:00
2016-09-09 12:31:54 +02:00
# Defines all keywords / value sets in obackup configuration files
# bash does not support two dimensional arrays, so we declare two arrays:
# ${KEYWORDS[index]}=${VALUES[index]}
KEYWORDS = (
INSTANCE_ID
LOGFILE
SQL_BACKUP
FILE_BACKUP
BACKUP_TYPE
SQL_STORAGE
FILE_STORAGE
ENCRYPTION
CRYPT_STORAGE
GPG_RECIPIENT
2017-01-02 13:12:56 +01:00
PARALLEL_ENCRYPTION_PROCESSES
2016-09-09 12:31:54 +02:00
CREATE_DIRS
KEEP_ABSOLUTE_PATHS
BACKUP_SIZE_MINIMUM
GET_BACKUP_SIZE
SQL_WARN_MIN_SPACE
FILE_WARN_MIN_SPACE
REMOTE_SYSTEM_URI
SSH_RSA_PRIVATE_KEY
2016-10-23 18:04:39 +02:00
SSH_PASSWORD_FILE
2017-02-09 12:28:02 +01:00
_REMOTE_TOKEN
2016-09-09 12:31:54 +02:00
SSH_COMPRESSION
SSH_IGNORE_KNOWN_HOSTS
RSYNC_REMOTE_PATH
REMOTE_HOST_PING
REMOTE_3RD_PARTY_HOSTS
SUDO_EXEC
SQL_USER
DATABASES_ALL
DATABASES_ALL_EXCLUDE_LIST
DATABASES_LIST
SOFT_MAX_EXEC_TIME_DB_TASK
HARD_MAX_EXEC_TIME_DB_TASK
MYSQLDUMP_OPTIONS
COMPRESSION_LEVEL
DIRECTORY_LIST
RECURSIVE_DIRECTORY_LIST
RECURSIVE_EXCLUDE_LIST
RSYNC_PATTERN_FIRST
RSYNC_INCLUDE_PATTERN
RSYNC_EXCLUDE_PATTERN
RSYNC_INCLUDE_FROM
RSYNC_EXCLUDE_FROM
PATH_SEPARATOR_CHAR
2016-12-19 23:17:25 +01:00
RSYNC_OPTIONAL_ARGS
2016-09-09 12:31:54 +02:00
PRESERVE_PERMISSIONS
PRESERVE_OWNER
PRESERVE_GROUP
PRESERVE_EXECUTABILITY
PRESERVE_ACL
PRESERVE_XATTR
COPY_SYMLINKS
KEEP_DIRLINKS
PRESERVE_HARDLINKS
RSYNC_COMPRESS
SOFT_MAX_EXEC_TIME_FILE_TASK
HARD_MAX_EXEC_TIME_FILE_TASK
PARTIAL
DELETE_VANISHED_FILES
DELTA_COPIES
BANDWIDTH
RSYNC_EXECUTABLE
DESTINATION_MAILS
2017-02-09 12:28:02 +01:00
MAIL_BODY_CHARSET
2016-09-09 12:31:54 +02:00
SENDER_MAIL
SMTP_SERVER
SMTP_PORT
SMTP_ENCRYPTION
SMTP_USER
SMTP_PASSWORD
SOFT_MAX_EXEC_TIME_TOTAL
HARD_MAX_EXEC_TIME_TOTAL
KEEP_LOGGING
ROTATE_SQL_BACKUPS
ROTATE_SQL_COPIES
ROTATE_FILE_BACKUPS
ROTATE_FILE_COPIES
LOCAL_RUN_BEFORE_CMD
LOCAL_RUN_AFTER_CMD
REMOTE_RUN_BEFORE_CMD
REMOTE_RUN_AFTER_CMD
MAX_EXEC_TIME_PER_CMD_BEFORE
MAX_EXEC_TIME_PER_CMD_AFTER
STOP_ON_CMD_ERROR
RUN_AFTER_CMD_ON_ERROR
)
VALUES = (
test-backup
''
2019-05-21 12:51:46 +02:00
true
true
2016-09-09 12:31:54 +02:00
local
/home/storage/sql
/home/storage/files
2019-05-21 12:51:46 +02:00
false
2016-09-09 12:31:54 +02:00
/home/storage/crypt
'Your Name used with GPG signature'
2017-01-02 13:12:56 +01:00
''
2019-05-21 12:51:46 +02:00
true
true
2016-09-09 12:31:54 +02:00
1024
2019-05-21 12:51:46 +02:00
true
2016-09-09 12:31:54 +02:00
1048576
1048576
ssh://backupuser@remote.system.tld:22/
${ HOME } /.ssh/id_rsa
2016-10-23 17:54:41 +02:00
''
2017-02-09 12:28:02 +01:00
SomeAlphaNumericToken9
2019-05-21 12:51:46 +02:00
true
false
2016-09-09 12:31:54 +02:00
''
2019-05-21 12:51:46 +02:00
true
2016-09-09 12:31:54 +02:00
'www.kernel.org www.google.com'
2019-05-21 12:51:46 +02:00
false
2016-09-09 12:31:54 +02:00
root
2019-05-21 12:51:46 +02:00
true
2016-09-09 12:31:54 +02:00
test
''
3600
7200
'--opt --single-transaction'
3
/some/path
/home
/home/backupuser\; /host/lost+found
include
''
''
''
''
\;
2016-12-19 23:17:25 +01:00
''
2019-05-21 12:51:46 +02:00
true
true
true
true
false
false
true
true
false
false
2016-09-09 12:31:54 +02:00
3600
7200
2019-05-21 12:51:46 +02:00
false
false
true
2016-09-09 12:31:54 +02:00
0
rsync
infrastructure@example.com
2017-02-09 12:28:02 +01:00
''
2016-09-09 12:31:54 +02:00
sender@example.com
smtp.isp.tld
25
2019-05-21 12:51:46 +02:00
falsene
2016-09-09 12:31:54 +02:00
''
''
30000
36000
1801
2019-05-21 12:51:46 +02:00
false
2016-09-09 12:31:54 +02:00
7
2019-05-21 12:51:46 +02:00
false
2016-09-09 12:31:54 +02:00
7
''
''
''
''
0
0
2019-05-21 12:51:46 +02:00
false
false
2016-09-09 12:31:54 +02:00
)
2015-11-16 13:37:26 +01:00
function Usage {
echo " $PROGRAM $PROGRAM_BUILD "
echo $AUTHOR
echo $CONTACT
echo ""
echo " This script migrates $SUBPROGRAM $OLD_PROGRAM_VERSION config files to $NEW_PROGRAM_VERSION . "
echo ""
echo " Usage: $0 /path/to/config_file.conf "
2016-04-06 21:08:24 +02:00
echo "Please make sure the config file is writable."
2015-11-16 13:37:26 +01:00
exit 128
}
function LoadConfigFile {
local config_file = " ${ 1 } "
if [ ! -f " $config_file " ] ; then
echo " Cannot load configuration file [ $config_file ]. Sync cannot start. "
exit 1
elif [ [ " $1 " != *".conf" ] ] ; then
echo " Wrong configuration file supplied [ $config_file ]. Sync cannot start. "
exit 1
else
egrep '^#|^[^ ]*=[^;&]*' " $config_file " > " ./ $SUBPROGRAM . $FUNCNAME . $$ "
source " ./ $SUBPROGRAM . $FUNCNAME . $$ "
rm -f " ./ $SUBPROGRAM . $FUNCNAME . $$ "
fi
}
2019-05-21 12:51:46 +02:00
function CheckAndBackup {
2015-11-16 13:37:26 +01:00
local config_file = " ${ 1 } "
2016-12-19 23:17:25 +01:00
if ! grep "BACKUP_ID=" $config_file > /dev/null && ! grep "INSTANCE_ID=" $config_file > /dev/null; then
2016-03-31 10:59:21 +02:00
echo " File [ $config_file ] does not seem to be a obackup config file. "
2015-11-16 13:37:26 +01:00
exit 1
fi
2016-04-06 20:47:04 +02:00
echo " Backing up [ $config_file ] as [ $config_file .save] "
2016-04-13 12:16:23 +02:00
cp -p " $config_file " " $config_file .save "
2015-11-16 13:37:26 +01:00
if [ $? != 0 ] ; then
echo "Cannot backup config file."
exit 1
fi
2019-05-21 12:51:46 +02:00
}
function RewriteOldConfigFiles {
local config_file = " ${ 1 } "
2015-11-16 13:37:26 +01:00
echo " Rewriting config file $config_file "
2016-04-13 12:16:23 +02:00
sed -i'.tmp' 's/^BACKUP_ID=/INSTANCE_ID=/g' " $config_file "
sed -i'.tmp' 's/^BACKUP_SQL=/SQL_BACKUP=/g' " $config_file "
sed -i'.tmp' 's/^BACKUP_FILES=/FILE_BACKUP=/g' " $config_file "
sed -i'.tmp' 's/^LOCAL_SQL_STORAGE=/SQL_STORAGE=/g' " $config_file "
sed -i'.tmp' 's/^LOCAL_FILE_STORAGE=/FILE_STORAGE=/g' " $config_file "
2016-08-31 11:25:09 +02:00
2019-05-21 12:51:46 +02:00
sed -i'.tmp' 's/^DISABLE_GET_BACKUP_FILE_SIZE=no/GET_BACKUP_SIZE=true/g' " $config_file "
sed -i'.tmp' 's/^DISABLE_GET_BACKUP_FILE_SIZE=yes/GET_BACKUP_SIZE=false/g' " $config_file "
2016-04-13 12:16:23 +02:00
sed -i'.tmp' 's/^LOCAL_STORAGE_KEEP_ABSOLUTE_PATHS=/KEEP_ABSOLUTE_PATHS=/g' " $config_file "
sed -i'.tmp' 's/^LOCAL_STORAGE_WARN_MIN_SPACE=/SQL_WARN_MIN_SPACE=/g' " $config_file "
if ! grep "^FILE_WARN_MIN_SPACE=" " $config_file " > /dev/null; then
2019-05-21 13:39:49 +02:00
VALUE = $( grep "SQL_WARN_MIN_SPACE=" " $config_file " )
VALUE = " ${ VALUE #*= } "
2016-04-13 12:16:23 +02:00
sed -i'.tmp' '/^SQL_WARN_MIN_SPACE=*/a\' $'\n' 'FILE_WARN_MIN_SPACE=' $VALUE '\' $'\n' '' " $config_file "
fi
sed -i'.tmp' 's/^DIRECTORIES_SIMPLE_LIST=/DIRECTORY_LIST=/g' " $config_file "
sed -i'.tmp' 's/^DIRECTORIES_RECURSE_LIST=/RECURSIVE_DIRECTORY_LIST=/g' " $config_file "
sed -i'.tmp' 's/^DIRECTORIES_RECURSE_EXCLUDE_LIST=/RECURSIVE_EXCLUDE_LIST=/g' " $config_file "
sed -i'.tmp' 's/^ROTATE_BACKUPS=/ROTATE_SQL_BACKUPS=/g' " $config_file "
if ! grep "^ROTATE_FILE_BACKUPS=" " $config_file " > /dev/null; then
2019-05-21 13:39:49 +02:00
VALUE = $( grep "ROTATE_SQL_BACKUPS=" " $config_file " )
VALUE = " ${ VALUE #*= } "
2016-04-13 12:16:23 +02:00
sed -i'.tmp' '/^ROTATE_SQL_BACKUPS=*/a\' $'\n' 'ROTATE_FILE_BACKUPS=' $VALUE '\' $'\n' '' " $config_file "
fi
sed -i'.tmp' 's/^ROTATE_COPIES=/ROTATE_SQL_COPIES=/g' " $config_file "
if ! grep "^ROTATE_FILE_COPIES=" " $config_file " > /dev/null; then
2019-05-21 13:39:49 +02:00
VALUE = $( grep "ROTATE_SQL_COPIES=" " $config_file " )
VALUE = " ${ VALUE #*= } "
2016-04-13 12:16:23 +02:00
sed -i'.tmp' '/^ROTATE_SQL_COPIES=*/a\' $'\n' 'ROTATE_FILE_COPIES=' $VALUE '\' $'\n' '' " $config_file "
fi
2019-05-21 13:39:49 +02:00
REMOTE_BACKUP = $( grep "REMOTE_BACKUP=" " $config_file " )
REMOTE_BACKUP = " ${ REMOTE_BACKUP #*= } "
2019-05-21 12:51:46 +02:00
if [ " $REMOTE_BACKUP " = = "true" ] ; then
2019-05-21 13:39:49 +02:00
REMOTE_USER = $( grep "REMOTE_USER=" " $config_file " )
REMOTE_USER = " ${ REMOTE_USER #*= } "
REMOTE_HOST = $( grep "REMOTE_HOST=" " $config_file " )
REMOTE_HOST = " ${ REMOTE_HOST #*= } "
REMOTE_PORT = $( grep "REMOTE_PORT=" " $config_file " )
REMOTE_PORT = " ${ REMOTE_PORT #*= } "
2015-11-16 13:37:26 +01:00
REMOTE_SYSTEM_URI = " ssh:// $REMOTE_USER @ $REMOTE_HOST : $REMOTE_PORT / "
2019-05-21 12:51:46 +02:00
sed -i'.tmp' 's#^REMOTE_BACKUP=true#REMOTE_SYSTEM_URI=' $REMOTE_SYSTEM_URI '#g' " $config_file "
2016-09-14 20:19:14 +02:00
sed -i'.tmp' '/^REMOTE_USER==*/d' " $config_file "
sed -i'.tmp' '/^REMOTE_HOST==*/d' " $config_file "
sed -i'.tmp' '/^REMOTE_PORT==*/d' " $config_file "
2015-11-16 13:37:26 +01:00
2016-04-13 12:16:23 +02:00
sed -i'.tmp' '/^INSTANCE_ID=*/a\' $'\n' 'BACKUP_TYPE=pull\' $'\n' '' " $config_file "
2015-11-16 13:37:26 +01:00
else
2016-04-13 12:16:23 +02:00
if ! grep "^BACKUP_TYPE=" " $config_file " > /dev/null; then
sed -i'.tmp' '/^INSTANCE_ID=*/a\' $'\n' 'BACKUP_TYPE=local\' $'\n' '' " $config_file "
fi
2015-12-15 14:08:54 +01:00
fi
2016-09-14 20:27:03 +02:00
sed -i'.tmp' 's/^REMOTE_3RD_PARTY_HOST=/REMOTE_3RD_PARTY_HOSTS=/g' " $config_file "
2016-09-09 12:31:54 +02:00
}
2015-12-15 14:08:54 +01:00
2016-09-09 12:31:54 +02:00
function AddMissingConfigOptions {
local config_file = " ${ 1 } "
local counter = 0
while [ $counter -lt ${# KEYWORDS [@] } ] ; do
2016-10-17 17:42:13 +02:00
if ! grep " ^ ${ KEYWORDS [ $counter ] } = " > /dev/null " $config_file " ; then
2016-09-14 20:19:14 +02:00
echo " ${ KEYWORDS [ $counter ] } not found "
if [ $counter -gt 0 ] ; then
2019-05-21 12:51:46 +02:00
if [ " { $VALUES [ $counter ]} " = = true ] || [ " ${ VALUES [ $counter ] } " = = false ] ; then
sed -i'.tmp' '/^' ${ KEYWORDS [ $(( counter-1)) ] } '=*/a\' $'\n' ${ KEYWORDS [ $counter ] } '=' " ${ VALUES [ $counter ] } " '\' $'\n' '' " $config_file "
else
sed -i'.tmp' '/^' ${ KEYWORDS [ $(( counter-1)) ] } '=*/a\' $'\n' ${ KEYWORDS [ $counter ] } '="' " ${ VALUES [ $counter ] } " '"\' $'\n' '' " $config_file "
fi
2016-09-14 20:19:14 +02:00
if [ $? -ne 0 ] ; then
echo " Cannot add missing ${ [KEYWORDS[ $counter ] } . "
exit 1
fi
2016-09-14 20:27:03 +02:00
else
2019-05-21 12:51:46 +02:00
if [ " { $VALUES [ $counter ]} " = = true ] || [ " ${ VALUES [ $counter ] } " = = false ] ; then
sed -i'.tmp' '/[GENERAL\]$//a\' $'\n' ${ KEYWORDS [ $counter ] } '=' " ${ VALUES [ $counter ] } " '\' $'\n' '' " $config_file "
else
sed -i'.tmp' '/[GENERAL\]$//a\' $'\n' ${ KEYWORDS [ $counter ] } '="' " ${ VALUES [ $counter ] } " '"\' $'\n' '' " $config_file "
fi
2019-05-21 13:21:58 +02:00
if [ $? -ne 0 ] ; then
echo " Cannot add missing ${ [KEYWORDS[ $counter ] } . "
exit 1
fi
2016-09-14 20:27:03 +02:00
fi
2016-09-09 12:31:54 +02:00
echo " Added missing ${ KEYWORDS [ $counter ] } config option with default option [ ${ VALUES [ $counter ] } ] "
2019-05-21 12:51:46 +02:00
else
# Not the most elegant but the quickest way :)
if grep " ^{ $KEYWORDS [ $counter ]}=yes " > /dev/null " $config_file " ; then
sed -i'.tmp' 's/^' ${ KEYWORDS [ $counter ] } '=.*/' ${ KEYWORDS [ $counter ] } '=true/g' " $config_file "
if [ $? -ne 0 ] ; then
echo " Cannot rewrite ${ [KEYWORDS[ $counter ] } boolean to true. "
exit 1
fi
elif grep " ^{ $KEYWORDS [ $counter ]}=no " > /dev/null " $config_file " ; then
2019-05-21 13:54:31 +02:00
sed -i'.tmp' 's/^' ${ KEYWORDS [ $counter ] } '=.*/' ${ KEYWORDS [ $counter ] } '=false/g' " $config_file "
2019-05-21 12:51:46 +02:00
if [ $? -ne 0 ] ; then
echo " Cannot rewrite ${ [KEYWORDS[ $counter ] } boolean to false. "
exit 1
fi
fi
2016-09-09 12:31:54 +02:00
fi
counter = $(( counter+1))
done
}
2016-04-06 20:47:04 +02:00
2019-05-21 12:51:46 +02:00
function RewriteSections {
local config_file = " ${ 1 } "
2019-05-21 13:21:58 +02:00
# Earlier config files has GENERAL BACKUP OPTIONS set twice. Let's replace the first one only. sed does a horrible job doing this, at least if portability is required
awk '/###### GENERAL BACKUP OPTIONS/ && !done { gsub(/###### GENERAL BACKUP OPTIONS/, "[GENERAL]"); done=1}; 1' " $config_file " >> " $config_file .tmp "
#sed -i'.tmp' 's/###### GENERAL BACKUP OPTIONS/[GENERAL]/' "$config_file"
# Fix using earlier tmp file from awk
sed 's/###### BACKUP STORAGE/[BACKUP STORAGE]/g' " $config_file .tmp " > " $config_file "
2019-05-21 12:51:46 +02:00
sed -i'.tmp' 's/###### REMOTE ONLY OPTIONS/[REMOTE_OPTIONS]/g' " $config_file "
sed -i'.tmp' 's/###### DATABASE SPECIFIC OPTIONS/[DATABASE BACKUP SETTINGS]/g' " $config_file "
sed -i'.tmp' 's/###### FILES SPECIFIC OPTIONS/[FILE BACKUP SETTINGS]/g' " $config_file "
sed -i'.tmp' 's/###### ALERT OPTIONS/[ALERT_OPTIONS]/g' " $config_file "
sed -i'.tmp' 's/###### GENERAL BACKUP OPTIONS/[BACKUP SETTINGS]/g' " $config_file "
sed -i'.tmp' 's/###### EXECUTION HOOKS/[EXECUTION_HOOKS]/g' " $config_file "
}
2016-09-09 12:31:54 +02:00
function UpdateConfigHeader {
local config_file = " ${ 1 } "
2016-04-06 20:47:04 +02:00
2019-05-21 12:51:46 +02:00
if ! grep "^CONFIG_FILE_REVISION=" > /dev/null " $config_file " ; then
# "onfig file rev" to deal with earlier variants of the file
sed -i'.tmp' 's/.*onfig file rev.*//' " $config_file "
sed -i'.tmp' '/^\[GENERAL\]$/a\' $'\n' CONFIG_FILE_REVISION = $CONFIG_FILE_REVISION $'\n' '' " $config_file "
rm -f " $config_file .tmp "
fi
2015-11-16 13:37:26 +01:00
}
if [ " $1 " != "" ] && [ -f " $1 " ] && [ -w " $1 " ] ; then
CONF_FILE = " $1 "
# Make sure there is no ending slash
CONF_FILE = " ${ CONF_FILE %/ } "
LoadConfigFile " $CONF_FILE "
2019-05-21 12:51:46 +02:00
CheckAndBackup " $CONF_FILE "
RewriteSections " $CONF_FILE "
2016-09-09 12:31:54 +02:00
RewriteOldConfigFiles " $CONF_FILE "
AddMissingConfigOptions " $CONF_FILE "
UpdateConfigHeader " $CONF_FILE "
2015-11-16 13:37:26 +01:00
else
Usage
fi