mirror of
https://github.com/deajan/obackup.git
synced 2024-11-12 19:03:42 +01:00
Obackup v1.84 RC3
This commit is contained in:
parent
0d8a2fbb0c
commit
d6170c88b5
33
CHANGELOG.md
33
CHANGELOG.md
@ -1,17 +1,29 @@
|
||||
## FUTURE IMPROVEMENTS
|
||||
SHORT FUTURE IMPROVEMENTS
|
||||
-------------------------
|
||||
|
||||
- Exit trap function must also stop child processes
|
||||
- Rewrite rsync exclude patterns using \"pattern\" instead of escaped chars
|
||||
- Clean most of recursive task creation code
|
||||
|
||||
## Known issues
|
||||
FAR FUTURE IMPROVEMENTS
|
||||
-----------------------
|
||||
|
||||
- Backup size check counts excluded patterns
|
||||
- Recursive task creation from directories does only include subdirectories, but no files in root directory
|
||||
- Bandwidth parameter is ignored by SQL backups.
|
||||
- Missing symlink support under MSYS
|
||||
- (Secret world domination... Still need to get bald and get a cat)
|
||||
|
||||
## Latest changelog
|
||||
KNOWN ISSUES
|
||||
------------
|
||||
|
||||
- Backup size check does not honor rsync exclude patterns
|
||||
- Bandwidth parameter is ignored for SQL backups
|
||||
- Missing symlink support when run from MSYS environment
|
||||
|
||||
CHANGELOG
|
||||
---------
|
||||
|
||||
- 02 Nov. 2013: v1.84 RC3
|
||||
- Updated documentation
|
||||
- Minor rewrites in recursive backup code
|
||||
- Added base directory files backup for recursive directories backup
|
||||
- Minor improvements on permission checks
|
||||
- Added local and remote OS detection
|
||||
- Fixed ping arguments for FreeBSD compatibility
|
||||
- Added MSYS (MinGW minimal system) bash compatibility under Windows
|
||||
@ -63,8 +75,5 @@
|
||||
- Updated command line argument --silent processing
|
||||
- Added remote before and after command execution hook
|
||||
- Added local before and after command execution hook
|
||||
|
||||
14 Jun 2013
|
||||
-----------
|
||||
|
||||
- 14 Jun 2013
|
||||
- Initial public release, fully functionnal
|
||||
|
54
README.md
54
README.md
@ -1,29 +1,26 @@
|
||||
obackup
|
||||
=======
|
||||
|
||||
A small robust file & database backup script tailored for multiple virtualhost backups locally or remotely via ssh.
|
||||
Yet it is very versatile and actually works for a lot of backup tasks.
|
||||
A small robust file & database backup script for local to local or remote to local backups via ssh.
|
||||
Works especially well for multiple virtualhost backups with 'backup divide task' functionnality.
|
||||
|
||||
## About
|
||||
|
||||
OBackup is designed from ground to make the backup process as reliable as possible.
|
||||
It divides the whole backup process into tasks, allowing each task to execute for a certain amount of time.
|
||||
If a task doesn't finish in time, it's stopped and the next task is processed.
|
||||
If a task doesn't finish in time, it's stopped and the next task in list is processed.
|
||||
Before a task gets stopped, a first warning message is generated telling the task takes too long.
|
||||
Every action gets logged, and at the end of the backup process, if there was a warning,
|
||||
a stopped task or an error an alert email will be sent.
|
||||
Every action gets logged, and if a warning has been generated, a task gets stopped or an error happens, an alert email will be sent.
|
||||
|
||||
Remote backups are initiated from the backup server instead of the production server, so hacked servers won't get ssh access to the backup server.
|
||||
|
||||
OBackup can enumerate and backup all MariaDB / MySQL databases present on a server
|
||||
OBackup can enumerate and backup all MariaDB / MySQL databases present on a server.
|
||||
It can also enumarate all subdirectories of a given path and process them as separate tasks (usefull for multiple vhosts).
|
||||
It will do several checks before launching a backup like execution checks, dryruns,
|
||||
checking backup size and available local disk space.
|
||||
It will do several checks before launching a backup like execution checks, dryruns, checking backup size and available local disk space.
|
||||
|
||||
Obackup will work well to backup to a snapshot aware filesystem like ZFS or btrfs.
|
||||
In case you don't work with one of these, it may also rotate backups for you.
|
||||
|
||||
Obackup can execute local and remote commands before and after backup execution, thus providing possibilites to handle snapshots (see https://github.com/deajan/zsnap for a zfs snapshot management script).
|
||||
Obackup can execute local and remote commands before and after backup execution,
|
||||
thus providing an easy way to handle snapshots (see https://github.com/deajan/zsnap for a zfs snapshot management script).
|
||||
It may also rotate backups for you.
|
||||
|
||||
As of today, obackup has been tested successfully on RHEL / CentOS 5, CentOS 6, Debian 6.0.7 and Linux Mint 14.
|
||||
Currently, Obackup also runs on FreeBSD and Windows MSYS environment, altough it is not fully tested yet.
|
||||
@ -33,41 +30,52 @@ Feel free to drop me a mail for limited support in my free time.
|
||||
## Installation
|
||||
|
||||
You can download the latest obackup script from authors website.
|
||||
You may also clone this git which will maybe have some more recent build.
|
||||
You may also clone the following git which will maybe have some more recent builds.
|
||||
|
||||
$ git clone git://github.com/deajan/obackup.git
|
||||
$ chmod +x ./obackup.sh
|
||||
|
||||
Obackup needs to run with bash shell, using any other shell will most probably fail.
|
||||
Once you have grabbed a copy of Obackup, just edit the config file with your favorite text editor to setup your environment and you're ready to run. A detailled documentation can be found in the DOCUMENTATION.md file.
|
||||
You can run multiple instances of obackup scripts with different backup environments. Just create another configuration file, edit it's environment and you're ready to run concurrently.
|
||||
Once you have grabbed a copy, just edit the config file with your favorite text editor to setup your environment and you're ready to run.
|
||||
A detailled documentation can be found on the author's site.
|
||||
You can run multiple instances of obackup scripts with different backup environments. Just create another configuration file,
|
||||
edit it's environment and you're ready to run concurrently.
|
||||
|
||||
Performing remote backups requires you to create RSA private / public key pair. Please see documentation for further information.
|
||||
Performing mysql backups requires to create a mysql user with SELECT rights on all databases. Please see documentation for further information.
|
||||
Performing backup with SUDO_EXEC option requires to configure sudoers file to allow some commands without password. Keep in mind that running backup as superuser might be a security risk. You should generally prefer a read only enabled user. Please see documentation for further information.
|
||||
Performing backup with SUDO_EXEC option requires to configure sudoers file to allow some commands without password.
|
||||
Keep in mind that running backup as superuser might be a security risk. You should generally prefer a read only enabled user.
|
||||
Please see documentation for further information.
|
||||
|
||||
## Usage
|
||||
|
||||
MariaDB / MySQL backups are consistent because dumps are done with the --single-transaction option.
|
||||
File backups can be done directly if data won't change while a backup is going on (generally true on vhosts), but backing up a snapshot of the actual data is preferable as it will stay consistent. LVM, zfs or btrfs snapshots will do fine.
|
||||
File backups can be done directly if data won't change while a backup is going on (generally true on vhosts),
|
||||
but backing up a snapshot of the actual data is preferable as it will stay consistent. LVM, zfs or btrfs snapshots will do fine.
|
||||
|
||||
You may try your setup by specifying the "--dry" parameter which will run a simulation of what will be done.
|
||||
You may try your setup by specifying the "--dry" parameter which will run a simulation of what will be done. Specifying "--verbose" will also list any command
|
||||
that's actually launched and it's result.
|
||||
|
||||
$ ./obackup.sh path/to/backup.conf --dry
|
||||
$ ./obackup.sh path/to/backup.conf
|
||||
$ ./obackup.sh path/to/backup.conf --silent
|
||||
|
||||
|
||||
One you're happy with a test run, you may run obackup as a cron task with the "--silent" parameter so output will not be written to stdout.
|
||||
All backup activity is logged to "/var/log/obackup_backupname.log".
|
||||
All backup activity is logged to "/var/log/obackup_backupname.log" or current directory if /var/log is not writable.
|
||||
|
||||
## Final words
|
||||
|
||||
Backup tasks aren't always reliable, connectivity loss, insufficient disk space, hacked computers with tons of mangas to backup... Anything can happen. Obackup will sent your a warning email for every issue it can handle.
|
||||
Nevertheless, you should assure yourself that your backup tasks will get done the way you meant it. Also, a backup isn't valuable until you're sure it's restoration will be a success. Try to restore your backups to check whether everything is okay. Backups will keep file permissions and owners, but may loose ACLs if destination file system won't handle them.
|
||||
Backup tasks aren't always reliable, connectivity loss, insufficient disk space, hacked servers with tons of unusefull stuff to backup... Anything can happen.
|
||||
Obackup will sent your a warning email for every issue it can handle.
|
||||
Nevertheless, you should assure yourself that your backup tasks will get done the way you meant it. Also, a backup isn't valuable until you're sure
|
||||
you can successfully restore. Try to restore your backups to check whether everything is okay. Backups will keep file permissions and owners,
|
||||
but may loose ACLs if destination file system won't handle them.
|
||||
|
||||
## Author
|
||||
|
||||
Orsiris "Ozy" de Jong.
|
||||
ozy@badministrateur.com
|
||||
Feel free to mail me for limited support in my free time :)
|
||||
Orsiris "Ozy" de Jong | ozy@netpower.fr
|
||||
|
||||
|
||||
|
||||
|
1244
documentation.html
1244
documentation.html
File diff suppressed because it is too large
Load Diff
126
host_backup.conf
126
host_backup.conf
@ -1,119 +1,163 @@
|
||||
#!/bin/bash
|
||||
|
||||
###### Remote (or local) backup script for files & databases
|
||||
###### (L) 2013 by Ozy de Jong (www.badministrateur.com)
|
||||
###### Config file rev 2109201301
|
||||
###### (L) 2013 by Ozy de Jong (www.netpower.fr)
|
||||
###### Config file rev 0211201301
|
||||
|
||||
## Backup identification, any string you want
|
||||
## ---------- GENERAL BACKUP OPTIONS
|
||||
|
||||
## Backup identification name.
|
||||
BACKUP_ID="your backup name"
|
||||
|
||||
## Leaving this empty will create a logfile at /var/log/obackup_version_BACKUP_ID.log (or current directory if /var/log doesn't exist)
|
||||
## Log file location. Leaving this empty will create log file at /var/log/obackup_version_BACKUP_ID.log (or current directory if /var/log doesn't exist)
|
||||
LOGFILE=""
|
||||
|
||||
## General backup options
|
||||
## Backup databases
|
||||
BACKUP_SQL=no
|
||||
## Backup files
|
||||
BACKUP_FILES=yes
|
||||
|
||||
## Local storage paths
|
||||
## ---------- LOCAL BACKUP STORAGE OPTIONS
|
||||
|
||||
## Local storage paths where to put backups
|
||||
LOCAL_SQL_STORAGE="/home/storage/backup/sql"
|
||||
LOCAL_FILE_STORAGE="/home/storage/backup/files"
|
||||
## Create sync directories if they do not exist
|
||||
CREATE_DIRS=no
|
||||
## Keep the absolute source path in your backup, eg: /your/backup/storage/the/remote/server/files
|
||||
## You should leave this enabled if you use recursive directories backup lists or they'll all end in the same path.
|
||||
|
||||
## Create backup directories if they do not exist
|
||||
CREATE_DIRS=yes
|
||||
|
||||
## Keep absolute source path in your backup, eg: /your/backup/storage/the/remote/server/files
|
||||
## You should leave this enabled if you intend to use 'backup task division' functionality of OBackup, or everything will end up in the same directory.
|
||||
LOCAL_STORAGE_KEEP_ABSOLUTE_PATHS=yes
|
||||
## Generate an alert if backup size is lower than given value in Kb, useful for local mounted backups.
|
||||
|
||||
## Generate an alert if backup size is lower than given value in Kb (this can also help identifying empty mount dirs)
|
||||
BACKUP_SIZE_MINIMUM=1024
|
||||
|
||||
## Generate an alert if local storage free space is lower than given value in Kb.
|
||||
LOCAL_STORAGE_WARN_MIN_SPACE=1048576
|
||||
|
||||
## Bandwidth limit Kbytes / second. Leave 0 to disable limitation.
|
||||
## ---------- MISC OPTIONS
|
||||
|
||||
## Bandwidth limit Kbytes / second for file backups. Leave 0 to disable limitation.
|
||||
BANDWIDTH=0
|
||||
|
||||
## If enabled, file backups will be processed with sudo command. See documentation for /etc/sudoers configuration ("find", "du" and "rsync" need to be allowed). Requiretty needs to be disabled.
|
||||
## If enabled, file backups will be processed as superuser. See documentation for /etc/sudoers configuration ("find", "du" and "rsync" need to be allowed). Requiretty needs to be disabled.
|
||||
SUDO_EXEC=no
|
||||
## Paranoia option. Don't change this unless you read the documentation and still feel concerned about security issues.
|
||||
## Paranoia option. Don't change this unless you read the documentation.
|
||||
RSYNC_EXECUTABLE=rsync
|
||||
|
||||
## Remote options (will make backups of remote system through ssh tunnel, public RSA key need to be put into /home/.ssh/authorized_keys in remote users home directory)
|
||||
REMOTE_BACKUP=yes
|
||||
## ---------- REMOTE BACKUP OPTIONS
|
||||
|
||||
## The following options allow this Obackup instance to connect to a remote system via an ssh tunnel.
|
||||
## Needs public RSA key need to be put into ~/.ssh/authorized_keys in remote users home directory.
|
||||
REMOTE_BACKUP=no
|
||||
SSH_RSA_PRIVATE_KEY=~/.ssh/id_rsa
|
||||
REMOTE_USER=backupuser
|
||||
REMOTE_HOST=yourhost.local
|
||||
REMOTE_PORT=22
|
||||
## ssh compression should be used unless your remote connection is good enough (LAN)
|
||||
SSH_COMPRESSION=yes
|
||||
## Remote rsync executable path. Leave this empty in most cases
|
||||
REMOTE_RSYNC_PATH=""
|
||||
|
||||
## Check for connectivity to remote host before launching remote backup tasks. Be sure the hosts responds to ping. Failing to ping will skip current task.
|
||||
REMOTE_HOST_PING=yes
|
||||
## Check for internet access by pinging one or more 3rd party hosts before remote backup tasks. Leave empty if you don't want this check to be be performed. Failing to ping will skip current task.
|
||||
REMOTE_3RD_PARTY_HOSTS="www.kernel.org www.google.com"
|
||||
## Remote rsync executable path. Leave this empty in most cases
|
||||
REMOTE_RSYNC_PATH=""
|
||||
|
||||
## Databases options
|
||||
## ---------- DATABASE BACKUP OPTIONS
|
||||
|
||||
## Database backup user
|
||||
SQL_USER=backupuser
|
||||
## Save all databases except the ones specified in the exlude list. Every found database will be backed up as separate task (see documentation for explanation about tasks)
|
||||
|
||||
## Enabling the following option will save all databases on local or remote given SQL instance except the ones specified in the exlude list.
|
||||
## Every found database will be backed up as separate backup task.
|
||||
DATABASES_ALL=yes
|
||||
DATABASES_ALL_EXCLUDE_LIST="test;mysql"
|
||||
# Alternatively, you can specifiy a manual list of databases to backup separated by spaces
|
||||
## Alternatively, if DATABASES_ALL=no, you can specifiy a list of databases to backup separated by spaces.
|
||||
DATABASES_LIST=""
|
||||
## Max backup execution time per DB task. Soft is warning only. Hard is warning, stopping backup task and processing next one. Time is specified in seconds
|
||||
|
||||
## Max backup execution time per Database task. Soft max exec time generates a warning only. Hard max ecec time generates a warning and stops current backup task.
|
||||
## If a task gets stopped, next one in the task list gets executed. Time is specified in seconds.
|
||||
SOFT_MAX_EXEC_TIME_DB_TASK=3600
|
||||
HARD_MAX_EXEC_TIME_DB_TASK=7200
|
||||
## Preferred sql dump compression. Can be set to xz, lzma or gzip.
|
||||
|
||||
## Preferred SQL dump compression. Can be set to xz, lzma or gzip.
|
||||
## Generally, xz level 5 is a good compromise between cpu, memory hunger and compress ratio. Gzipped files are set to be rsyncable.
|
||||
COMPRESSION_PROGRAM=xz
|
||||
COMPRESSION_LEVEL=3
|
||||
## Dump compression should be done on remote side but can also be done locally to lower remote system usage (will take more bandwidth, check for ssh compression)
|
||||
|
||||
## SQL Dump compression should be done on remote side but can also be done locally to lower remote system usage (will take more bandwidth, check for ssh compression)
|
||||
COMPRESSION_REMOTE=yes
|
||||
|
||||
## Path separator. You can set whatever seperator you want in your directories list below. You may change this in case you have some esoteric filenames (try to use unconventional separators like | ).
|
||||
PATH_SEPARATOR_CHAR=";"
|
||||
## File backup lists. Double quoted directory list separated by the $PATH_SEPARATOR_CHAR. Every directory will be processed as task (see documentation for explanation about tasks)
|
||||
DIRECTORIES_SIMPLE_LIST="/var/named"
|
||||
## Recurse directory list separated by the $PATH_SEPARATOR_CHAR. Will create a backup task per subdirectory (one level only), eg RECURSE_LIST="/home /var" will create tasks "/home/dir1", "/home/dir2", ... "/home/dirN", "/var/log", "/var/lib"... "/var/whatever"
|
||||
## ---------- FILES BACKUP OPTIONS
|
||||
|
||||
## Directories backup list. List of semicolon separated directories that will be backed up recursively. Every directory will be processed as one backup task.
|
||||
DIRECTORIES_SIMPLE_LIST="/var/named;/var/lib"
|
||||
|
||||
## There's a special backup schema in Obackup called 'backup task division' which creates one backup task per level 1 subdirectory of a directory.
|
||||
## This is VERY usefull to backup multiple virtualhosts as separate tasks without having to specifiy each one separately.
|
||||
## This may also be usefull dividing big data directories in subdirectories tasks.
|
||||
|
||||
## Directories backup task division backup: Semicolon separated directories of which every level 1 subdirectory will be backed up recursively as a spearate backup task.
|
||||
## Example: "/home;/var" will create tasks "/home/dir1", "/home/dir2", ... "/home/dirN", "/var/log", "/var/lib"... "/var/whatever"
|
||||
DIRECTORIES_RECURSE_LIST="/home"
|
||||
## You can optionally exclude directories from RECURSE_LIST tasks, eg on the above example you could exclude /home/dir2 by adding it to RECURSE_EXCLUDE_LIST
|
||||
## You may optionally exclude subdirectories from task division. On the above example you could exclude /home/dir2 by adding it to DIRECTORIES_RECURSE_EXCLUDE_LIST
|
||||
DIRECTORIES_RECURSE_EXCLUDE_LIST="/home/backupuser;/home/lost+found"
|
||||
## Be aware that every recurse list will have it's own root (exclude pattern is relative from /home/web for /home/web/{recursedir})
|
||||
|
||||
## Rsync exclude patterns, used by simple and division lists
|
||||
RSYNC_EXCLUDE_PATTERN="*/tmp;*/ftp/www/cache/cachefs;*/sessions"
|
||||
## Preserve ACLS. Make sure target FS can hold ACLs or you'll get loads of errors.
|
||||
|
||||
## List separator char. You may set an alternative seperator char for your directories lists above.
|
||||
PATH_SEPARATOR_CHAR=";"
|
||||
|
||||
## Preserve ACLS. Make sure source and target FS can hold same ACLs or you'll get loads of errors.
|
||||
PRESERVE_ACL=no
|
||||
## Preserve Xattr
|
||||
## Preserve Xattr. MAke sure source and target FS can hold same Xattr or you'll get loads of errors.
|
||||
PRESERVE_XATTR=no
|
||||
## Let RSYNC compress file transfers. Do not use if you already enabled SSH compression.
|
||||
RSYNC_COMPRESS=yes
|
||||
|
||||
## Let RSYNC compress file transfers. Do not use this on local-local backup schemes. Also, this is not usefull if SSH compression is enabled.
|
||||
RSYNC_COMPRESS=no
|
||||
|
||||
## Max execution time per file backup task. Soft is warning only. Hard is warning, stopping backup and processing next one one file list. Tilme is specified in seconds
|
||||
SOFT_MAX_EXEC_TIME_FILE_TASK=3600
|
||||
HARD_MAX_EXEC_TIME_FILE_TASK=7200
|
||||
|
||||
## ---------- ALERT OPTIONS
|
||||
|
||||
## Alert email adresses separated by a space character
|
||||
DESTINATION_MAILS="your@mail.address"
|
||||
|
||||
## Windows only mail options (used by sendemail.exe)
|
||||
## Windows (MSYS environment) only mail options (used by sendemail.exe)
|
||||
SENDER_MAIL="alert@your.system"
|
||||
SMTP_SERVER=smtp.your.isp.com
|
||||
SMTP_USER=
|
||||
SMTP_PASSWORD=
|
||||
|
||||
## Max execution time of whole backup process. Soft is warning only. Hard is warning and stopping whole backup process.
|
||||
## ---------- GENERAL BACKUP OPTIONS
|
||||
|
||||
## Max execution time of whole backup process. Soft max exec time generates a warning only.
|
||||
## Hard max exec time generates a warning and stops the whole backup execution.
|
||||
SOFT_MAX_EXEC_TIME_TOTAL=30000
|
||||
HARD_MAX_EXEC_TIME_TOTAL=36000
|
||||
|
||||
## Backup Rotation in case you don't use a snapshot aware file system like zfs or btrfs to perform a snapshot before every backup
|
||||
## Backup Rotation. You may rotate backups if you don't use snapshots on your backup server.
|
||||
ROTATE_BACKUPS=no
|
||||
ROTATE_COPIES=7
|
||||
|
||||
## Commands that will be run before and / or after backup execution (remote execution will only happen if REMOTE_BACKUP is set to yes). Very usefull to initiate snapshots.
|
||||
## Set max execution time to 0 if you want these commands not to get stopped, else set a value in seconds after which execution will be stopped.
|
||||
## ---------- EXECUTION HOOKS
|
||||
|
||||
## Commands can will be run before and / or after backup execution (remote execution will only happen if REMOTE_BACKUP is set).
|
||||
## This is usefull to make a snapshot before backing up data, or even handle snapshots of backed up data.
|
||||
LOCAL_RUN_BEFORE_CMD=""
|
||||
LOCAL_RUN_AFTER_CMD=""
|
||||
|
||||
REMOTE_RUN_BEFORE_CMD=""
|
||||
REMOTE_RUN_AFTER_CMD=""
|
||||
|
||||
## Max execution time of commands before they get force killed. Leave 0 if you don't wan't this to happen. Time is specified in seconds.
|
||||
MAX_EXEC_TIME_PER_CMD_BEFORE=0
|
||||
MAX_EXEC_TIME_PER_CMD_AFTER=0
|
||||
|
||||
## Stops obackup execution if one of the above commands fail
|
||||
## Stops whole backup execution if one of the above commands fail
|
||||
STOP_ON_CMD_ERROR=no
|
||||
|
162
obackup.sh
162
obackup.sh
@ -2,8 +2,8 @@
|
||||
|
||||
###### Remote (or local) backup script for files & databases
|
||||
###### (L) 2013 by Orsiris "Ozy" de Jong (www.netpower.fr)
|
||||
OBACKUP_VERSION=1.84preRC3-MSYS-compatible
|
||||
OBACKUP_BUILD=1110201301
|
||||
OBACKUP_VERSION=1.84RC3
|
||||
OBACKUP_BUILD=0211201302
|
||||
|
||||
DEBUG=no
|
||||
SCRIPT_PID=$$
|
||||
@ -12,7 +12,7 @@ LOCAL_USER=$(whoami)
|
||||
LOCAL_HOST=$(hostname)
|
||||
|
||||
## Default log file until config file is loaded
|
||||
if [ -d /var/log ]
|
||||
if [ -w /var/log ]
|
||||
then
|
||||
LOG_FILE=/var/log/obackup.log
|
||||
else
|
||||
@ -20,13 +20,13 @@ else
|
||||
fi
|
||||
|
||||
## Default directory where to store run files
|
||||
if [ -d /dev/shm ]
|
||||
if [ -w /dev/shm ]
|
||||
then
|
||||
RUN_DIR=/dev/shm
|
||||
elif [ -d /tmp ]
|
||||
elif [ -w /tmp ]
|
||||
then
|
||||
RUN_DIR=/tmp
|
||||
elif [ -d /var/tmp ]
|
||||
elif [ -w /var/tmp ]
|
||||
then
|
||||
RUN_DIR=/var/tmp
|
||||
else
|
||||
@ -45,6 +45,7 @@ DIRECTORIES_EXCLUDED_LIST="" # Processed list of recursive directorires that
|
||||
DIRECTORIES_TO_BACKUP="" # Processed list of all directories to backup
|
||||
TOTAL_FILES_SIZE=0 # Total file size of $DIRECTORIES_TO_BACKUP
|
||||
|
||||
# $RUN_DIR/obackup_remote_os_$SCRIPT_PID Result of remote OS detection
|
||||
# $RUN_DIR/obackup_dblist_$SCRIPT_PID Databases list and sizes
|
||||
# $RUN_DIR/obackup_dirs_recurse_list_$SCRIPT_PID Recursive directories list
|
||||
# $RUN_DIR/obackup_local_sql_storage_$SCRIPT_PID Local free space for sql backup
|
||||
@ -57,7 +58,7 @@ TOTAL_FILES_SIZE=0 # Total file size of $DIRECTORIES_TO_BACKUP
|
||||
|
||||
function Log
|
||||
{
|
||||
echo "TIME: $SECONDS - $1" >> "$LOG_FILE"
|
||||
echo -e "TIME: $SECONDS - $1" >> "$LOG_FILE"
|
||||
if [ $silent -eq 0 ]
|
||||
then
|
||||
echo -e "TIME: $SECONDS - $1"
|
||||
@ -93,7 +94,7 @@ function TrapQuit
|
||||
if type -p pkill > /dev/null 2>&1
|
||||
then
|
||||
pkill -TERM -P $$
|
||||
elif [ "$LOCAL_OS" == "msys" ]
|
||||
elif [ "$LOCAL_OS" == "msys" ] || [ "$OSTYPE" == "msys" ]
|
||||
then
|
||||
## This is not really a clean way to get child process pids, especially the tail -n +2 which resolves a strange char apparition in msys bash
|
||||
for pid in $(ps -a | awk '{$1=$1}$1' | awk '{print $1" "$2}' | grep " $$$" | awk '{print $1}' | tail -n +2)
|
||||
@ -189,10 +190,10 @@ function CleanUp
|
||||
|
||||
function SendAlert
|
||||
{
|
||||
cat "$LOG_FILE" | gzip -9 > /tmp/obackup_lastlog.gz
|
||||
cat "$LOG_FILE" | gzip -9 > $RUN_DIR/obackup_lastlog.gz
|
||||
if type -p mutt > /dev/null 2>&1
|
||||
then
|
||||
echo $MAIL_ALERT_MSG | $(type -p mutt) -x -s "Backup alert for $BACKUP_ID" $DESTINATION_MAILS -a /tmp/obackup_lastlog.gz
|
||||
echo $MAIL_ALERT_MSG | $(type -p mutt) -x -s "Backup alert for $BACKUP_ID" $DESTINATION_MAILS -a $RUN_DIR/obackup_lastlog.gz
|
||||
if [ $? != 0 ]
|
||||
then
|
||||
Log "WARNING: Cannot send alert email via $(type -p mutt) !!!"
|
||||
@ -201,7 +202,7 @@ function SendAlert
|
||||
fi
|
||||
elif type -p mail > /dev/null 2>&1
|
||||
then
|
||||
echo $MAIL_ALERT_MSG | $(type -p mail) -a /tmp/obackup_lastlog.gz -s "Backup alert for $BACKUP_ID" $DESTINATION_MAILS
|
||||
echo $MAIL_ALERT_MSG | $(type -p mail) -a $RUN_DIR/obackup_lastlog.gz -s "Backup alert for $BACKUP_ID" $DESTINATION_MAILS
|
||||
if [ $? != 0 ]
|
||||
then
|
||||
Log "WARNING: Cannot send alert email via $(type -p mail) with attachments !!!"
|
||||
@ -226,7 +227,9 @@ function SendAlert
|
||||
fi
|
||||
else
|
||||
Log "WARNING: Cannot send alert email (no mutt / mail present) !!!"
|
||||
rm -f $RUN_DIR/obackup_lastlog.gz
|
||||
return 1
|
||||
rm -f $RUN_DIR/obackup_lastlog.gz
|
||||
fi
|
||||
}
|
||||
|
||||
@ -287,11 +290,17 @@ function CheckEnvironment
|
||||
function GetOperatingSystem
|
||||
{
|
||||
LOCAL_OS_VAR=$(uname -spio)
|
||||
if [ "$REMOTE_SYNC" == "yes" ]
|
||||
|
||||
if [ "$REMOTE_BACKUP" == "yes" ]
|
||||
then
|
||||
eval "$SSH_CMD uname -spio > $RUN_DIR/obackup_remote_os_$SCRIPT_PID 2>&1 &"
|
||||
REMOTE_OS_VAR=$(cat $RUN_DIR/obackup_remote_os_$SCRIPT_PID)
|
||||
fi
|
||||
eval "$SSH_CMD \"uname -spio\" > $RUN_DIR/obackup_remote_os_$SCRIPT_PID 2>&1"
|
||||
if [ $? != 0 ]
|
||||
then
|
||||
LogError "Cannot Get remote OS type."
|
||||
else
|
||||
REMOTE_OS_VAR=$(cat $RUN_DIR/obackup_remote_os_$SCRIPT_PID)
|
||||
fi
|
||||
fi
|
||||
|
||||
case $LOCAL_OS_VAR in
|
||||
"Linux"*)
|
||||
@ -325,6 +334,15 @@ function GetOperatingSystem
|
||||
LogError "Running on remote >> $REMOTE_OS_VAR << not supported. Please report to the author."
|
||||
exit 1
|
||||
esac
|
||||
|
||||
if [ "$DEBUG" == "yes" ]
|
||||
then
|
||||
Log "Local OS: [$LOCAL_OS_VAR]."
|
||||
if [ "$REMOTE_BACKUP" == "yes" ]
|
||||
then
|
||||
Log "Remote OS: [$REMOTE_OS_VAR]."
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Waits for pid $1 to complete. Will log an alert if $2 seconds exec time exceeded unless $2 equals 0. Will stop task and log alert if $3 seconds exec time exceeded.
|
||||
@ -386,15 +404,16 @@ function RunLocalCommand
|
||||
Log "Dryrun: Local command [$1] not run."
|
||||
return 1
|
||||
fi
|
||||
Log "Running command [$1] on local host."
|
||||
$1 > $RUN_DIR/obackup_run_local_$SCRIPT_PID 2>&1 &
|
||||
child_pid=$!
|
||||
WaitForTaskCompletion $child_pid 0 $2
|
||||
retval=$?
|
||||
if [ $retval -eq 0 ]
|
||||
then
|
||||
Log "Running command [$1] on local host succeded."
|
||||
Log "Command succeded."
|
||||
else
|
||||
LogError "Running command [$1] on local host failed."
|
||||
LogError "Command failed."
|
||||
fi
|
||||
|
||||
if [ $verbose -eq 1 ]
|
||||
@ -402,7 +421,7 @@ function RunLocalCommand
|
||||
Log "Command output:\n$(cat $RUN_DIR/obackup_run_local_$SCRIPT_PID)"
|
||||
fi
|
||||
|
||||
if [ "$STOP_ON_CMD_ERROR" == "yes" ]
|
||||
if [ "$STOP_ON_CMD_ERROR" == "yes" ] && [ $retval -ne 0 ]
|
||||
then
|
||||
exit 1
|
||||
fi
|
||||
@ -419,15 +438,16 @@ function RunRemoteCommand
|
||||
Log "Dryrun: Remote command [$1] not run."
|
||||
return 1
|
||||
fi
|
||||
Log "Running command [$1] on remote host."
|
||||
eval "$SSH_CMD \"$1\" > $RUN_DIR/obackup_run_remote_$SCRIPT_PID 2>&1 &"
|
||||
child_pid=$!
|
||||
WaitForTaskCompletion $child_pid 0 $2
|
||||
retval=$?
|
||||
if [ $retval -eq 0 ]
|
||||
then
|
||||
Log "Running command [$1] succeded."
|
||||
Log "Command succeded."
|
||||
else
|
||||
LogError "Running command [$1] failed."
|
||||
LogError "Command failed."
|
||||
fi
|
||||
|
||||
if [ -f $RUN_DIR/obackup_run_remote_$SCRIPT_PID ] && [ $verbose -eq 1 ]
|
||||
@ -435,9 +455,9 @@ function RunRemoteCommand
|
||||
Log "Command output:\n$(cat $RUN_DIR/obackup_run_remote_$SCRIPT_PID)"
|
||||
fi
|
||||
|
||||
if [ "$STOP_ON_CMD_ERROR" == "yes" ]
|
||||
if [ "$STOP_ON_CMD_ERROR" == "yes" ] && [ $retval -ne 0 ]
|
||||
then
|
||||
exit 1
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
@ -484,7 +504,7 @@ function CheckSpaceRequirements
|
||||
{
|
||||
if [ "$BACKUP_SQL" != "no" ]
|
||||
then
|
||||
if [ -d $LOCAL_SQL_STORAGE ]
|
||||
if [ -w $LOCAL_SQL_STORAGE ]
|
||||
then
|
||||
# Not elegant solution to make df silent on errors
|
||||
df -P $LOCAL_SQL_STORAGE > $RUN_DIR/obackup_local_sql_storage_$SCRIPT_PID 2>&1
|
||||
@ -505,7 +525,7 @@ function CheckSpaceRequirements
|
||||
fi
|
||||
else
|
||||
LOCAL_SQL_SPACE=0
|
||||
LogError "SQL storage path [$LOCAL_SQL_STORAGE] doesn't exist."
|
||||
LogError "SQL storage path [$LOCAL_SQL_STORAGE] doesn't exist or cannot write to it."
|
||||
fi
|
||||
else
|
||||
LOCAL_SQL_SPACE=0
|
||||
@ -513,7 +533,7 @@ function CheckSpaceRequirements
|
||||
|
||||
if [ "$BACKUP_FILES" != "no" ]
|
||||
then
|
||||
if [ -d $LOCAL_FILE_STORAGE ]
|
||||
if [ -w $LOCAL_FILE_STORAGE ]
|
||||
then
|
||||
df -P $LOCAL_FILE_STORAGE > $RUN_DIR/obackup_local_file_storage_$SCRIPT_PID 2>&1
|
||||
if [ $? != 0 ]
|
||||
@ -533,7 +553,7 @@ function CheckSpaceRequirements
|
||||
fi
|
||||
else
|
||||
LOCAL_FILE_SPACE=0
|
||||
LogError "File storage path [$LOCAL_FILE_STORAGE] doesn't exist."
|
||||
LogError "File storage path [$LOCAL_FILE_STORAGE] doesn't exist or cannot write to it."
|
||||
fi
|
||||
else
|
||||
LOCAL_FILE_SPACE=0
|
||||
@ -692,7 +712,12 @@ function ListDatabases
|
||||
fi
|
||||
done
|
||||
IFS=$OLD_IFS
|
||||
return 0
|
||||
|
||||
if [ $verbose -eq 1 ]
|
||||
then
|
||||
Log "Database backup list: $DATABASES_TO_BACKUP"
|
||||
Log "Database exclude list: $DATABASES_EXCLUDED_LIST"
|
||||
fi
|
||||
}
|
||||
|
||||
function BackupDatabase
|
||||
@ -706,7 +731,7 @@ function BackupDatabase
|
||||
LogError "Connectivity test failed. Stopping current task."
|
||||
exit 1
|
||||
fi
|
||||
eval "$SSH_CMD mysqldump -u $SQL_USER --skip-lock-tables --single-transaction --database $1 | $COMPRESSION_PROGRAM -$COMPRESSION_LEVEL $COMPRESSION_OPTIONS > $LOCAL_SQL_STORAGE/$1.sql$COMPRESSION_EXTENSION"
|
||||
sql_cmd="$SSH_CMD mysqldump -u $SQL_USER --skip-lock-tables --single-transaction --database $1 | $COMPRESSION_PROGRAM -$COMPRESSION_LEVEL $COMPRESSION_OPTIONS > $LOCAL_SQL_STORAGE/$1.sql$COMPRESSION_EXTENSION"
|
||||
elif [ "$REMOTE_BACKUP" == "yes" ] && [ "$COMPRESSION_REMOTE" == "yes" ]
|
||||
then
|
||||
CheckConnectivityRemoteHost
|
||||
@ -715,10 +740,16 @@ function BackupDatabase
|
||||
LogError "Connectivity test failed. Stopping current task."
|
||||
exit 1
|
||||
fi
|
||||
eval "$SSH_CMD \"mysqldump -u $SQL_USER --skip-lock-tables --single-transaction --database $1 | $COMPRESSION_PROGRAM -$COMPRESSION_LEVEL $COMPRESSION_OPTIONS\" > $LOCAL_SQL_STORAGE/$1.sql$COMPRESSION_EXTENSION"
|
||||
sql_cmd="$SSH_CMD \"mysqldump -u $SQL_USER --skip-lock-tables --single-transaction --database $1 | $COMPRESSION_PROGRAM -$COMPRESSION_LEVEL $COMPRESSION_OPTIONS\" > $LOCAL_SQL_STORAGE/$1.sql$COMPRESSION_EXTENSION"
|
||||
else
|
||||
mysqldump -u $SQL_USER --skip-lock-tables --single-transaction --database $1 | $COMPRESSION_PROGRAM -$COMPRESSION_LEVEL $COMPRESSION_OPTIONS > $LOCAL_SQL_STORAGE/$1.sql$COMPRESSION_EXTENSION
|
||||
sql_cmd="mysqldump -u $SQL_USER --skip-lock-tables --single-transaction --database $1 | $COMPRESSION_PROGRAM -$COMPRESSION_LEVEL $COMPRESSION_OPTIONS > $LOCAL_SQL_STORAGE/$1.sql$COMPRESSION_EXTENSION"
|
||||
fi
|
||||
|
||||
if [ $verbose -eq 1 ]
|
||||
then
|
||||
Log "SQL_CMD: $sql_cmd"
|
||||
fi
|
||||
eval $sql_cmd
|
||||
exit $?
|
||||
}
|
||||
|
||||
@ -780,14 +811,11 @@ function ListDirectories
|
||||
LogError "Command output:\n$(cat $RUN_DIR/obackup_dirs_recurse_list_$SCRIPT_PID)"
|
||||
fi
|
||||
return 1
|
||||
else
|
||||
Log "Listing of recursive directories succeeded for $dir."
|
||||
fi
|
||||
|
||||
OLD_IFS=$IFS
|
||||
IFS=$' \n'
|
||||
for line in $(cat $RUN_DIR/obackup_dirs_recurse_list_$SCRIPT_PID)
|
||||
# while read line
|
||||
do
|
||||
file_exclude=0
|
||||
for k in $DIRECTORIES_RECURSE_EXCLUDE_LIST
|
||||
@ -809,8 +837,12 @@ function ListDirectories
|
||||
else
|
||||
DIRECTORIES_EXCLUDED_LIST="$DIRECTORIES_EXCLUDED_LIST$PATH_SEPARATOR_CHAR'$line'"
|
||||
fi
|
||||
# done < <(cat $RUN_DIR/obackup_dirs_recurse_list_$SCRIPT_PID)
|
||||
done
|
||||
Log "Listing of recursive directories succeeded for $dir"
|
||||
if [ $verbose -eq 1 ]
|
||||
then
|
||||
Log "\n$(cat $RUN_DIR/obackup_dirs_recurse_list_$SCRIPT_PID)"
|
||||
fi
|
||||
IFS=$OLD_IFS
|
||||
done
|
||||
DIRECTORIES_TO_BACKUP_RECURSE=$DIRECTORIES_TO_BACKUP
|
||||
@ -887,14 +919,15 @@ function Rsync
|
||||
then
|
||||
local_file_storage_path="$(dirname $LOCAL_FILE_STORAGE$i)"
|
||||
else
|
||||
#### Leave the last directory path if recursive task when absolute paths not set so paths won't be mixed up
|
||||
if [ "$2" == "recurse" ]
|
||||
then
|
||||
local_file_storage_path="$LOCAL_FILE_STORAGE/$(basename $(dirname $i))"
|
||||
else
|
||||
local_file_storage_path="$LOCAL_FILE_STORAGE"
|
||||
fi
|
||||
local_file_storage_path=$LOCAL_FILE_STORAGE
|
||||
fi
|
||||
|
||||
## Manage to backup recursive directories lists files only (not recursing into subdirectories)
|
||||
if [ "$2" == "no-recurse" ]
|
||||
then
|
||||
RSYNC_EXCLUDE=$RSYNC_EXCLUDE" --exclude=*/*/"
|
||||
fi
|
||||
|
||||
if [ ! -d $local_file_storage_path ]
|
||||
then
|
||||
mkdir -p "$local_file_storage_path"
|
||||
@ -909,9 +942,9 @@ function Rsync
|
||||
LogError "Connectivity test failed. Stopping current task."
|
||||
exit 1
|
||||
fi
|
||||
rsync_cmd="$(type -p $RSYNC_EXECUTABLE) $RSYNC_ARGS --stats --delete $RSYNC_EXCLUDE --rsync-path=\"$RSYNC_PATH\" -e \"$RSYNC_SSH_CMD\" \"$REMOTE_USER@$REMOTE_HOST:$1\" \"$local_file_storage_path\" > $RUN_DIR/obackup_rsync_output_$SCRIPT_PID 2>&1"
|
||||
rsync_cmd="$(type -p $RSYNC_EXECUTABLE) $RSYNC_ARGS --stats $RSYNC_DELETE $RSYNC_EXCLUDE --rsync-path=\"$RSYNC_PATH\" -e \"$RSYNC_SSH_CMD\" \"$REMOTE_USER@$REMOTE_HOST:$1\" \"$local_file_storage_path\" > $RUN_DIR/obackup_rsync_output_$SCRIPT_PID 2>&1"
|
||||
else
|
||||
rsync_cmd="$(type -p $RSYNC_EXECUTABLE) $RSYNC_ARGS --stats --delete $RSYNC_EXCLUDE --rsync-path=\"$RSYNC_PATH\" \"$1\" \"$local_file_storage_path\" > $RUN_DIR/obackup_rsync_output_$SCRIPT_PID 2>&1"
|
||||
rsync_cmd="$(type -p $RSYNC_EXECUTABLE) $RSYNC_ARGS --stats $RSYNC_DELETE $RSYNC_EXCLUDE --rsync-path=\"$RSYNC_PATH\" \"$1\" \"$local_file_storage_path\" > $RUN_DIR/obackup_rsync_output_$SCRIPT_PID 2>&1"
|
||||
fi
|
||||
#### Eval is used so the full command is processed without bash adding single quotes round variables
|
||||
if [ $verbose -eq 1 ]
|
||||
@ -930,7 +963,7 @@ function FilesBackup
|
||||
for BACKUP_TASK in $DIRECTORIES_SIMPLE_LIST
|
||||
do
|
||||
BACKUP_TASK=$(StripQuotes $BACKUP_TASK)
|
||||
Log "Beginning file backup $BACKUP_TASK"
|
||||
Log "Beginning recursive file backup on $BACKUP_TASK"
|
||||
SECONDS_BEGIN=$SECONDS
|
||||
Rsync $BACKUP_TASK &
|
||||
child_pid=$!
|
||||
@ -954,10 +987,38 @@ function FilesBackup
|
||||
CheckTotalExecutionTime
|
||||
done
|
||||
|
||||
## Also backup files at root of DIRECTORIES_RECURSE_LIST directories
|
||||
for BACKUP_TASK in $DIRECTORIES_RECURSE_LIST
|
||||
do
|
||||
BACKUP_TASK="$(StripQuotes $BACKUP_TASK)"
|
||||
Log "Beginning non recursive file backup on $BACKUP_TASK"
|
||||
SECONDS_BEGIN=$SECONDS
|
||||
Rsync $BACKUP_TASK "no-recurse" &
|
||||
child_pid=$!
|
||||
WaitForTaskCompletion $child_pid $SOFT_MAX_EXEC_TIME_FILE_TASK $HARD_MAX_EXEC_TIME_FILE_TASK
|
||||
retval=$?
|
||||
if [ $verbose -eq 1 ] && [ -f $RUN_DIR/obackup_rsync_output_$SCRIPT_PID ]
|
||||
then
|
||||
Log "List:\n$(cat $RUN_DIR/obackup_rsync_output_$SCRIPT_PID)"
|
||||
fi
|
||||
|
||||
if [ $retval -ne 0 ]
|
||||
then
|
||||
LogError "Backup failed on remote files."
|
||||
if [ $verbose -eq 0 ] && [ -f $RUN_DIR/obackup_rsync_output_$SCRIPT_PID ]
|
||||
then
|
||||
LogError "$(cat $RUN_DIR/obackup_rsync_output_$SCRIPT_PID)"
|
||||
fi
|
||||
else
|
||||
Log "Backup succeeded."
|
||||
fi
|
||||
CheckTotalExecutionTime
|
||||
done
|
||||
|
||||
for BACKUP_TASK in $DIRECTORIES_TO_BACKUP_RECURSE
|
||||
do
|
||||
BACKUP_TASK=$(StripQuotes $BACKUP_TASK)
|
||||
Log "Beginning file backup $BACKUP_TASK"
|
||||
Log "Beginning recursive file backup on $BACKUP_TASK"
|
||||
SECONDS_BEGIN=$SECONDS
|
||||
Rsync $BACKUP_TASK "recurse" &
|
||||
child_pid=$!
|
||||
@ -980,6 +1041,7 @@ function FilesBackup
|
||||
fi
|
||||
CheckTotalExecutionTime
|
||||
done
|
||||
|
||||
IFS=$OLD_IFS
|
||||
}
|
||||
|
||||
@ -1034,7 +1096,7 @@ function Init
|
||||
|
||||
if [ "$LOGFILE" == "" ]
|
||||
then
|
||||
if [ -d /var/log ]
|
||||
if [ -w /var/log ]
|
||||
then
|
||||
LOG_FILE=/var/log/obackup_$OBACKUP_VERSION-$BACKUP_ID.log
|
||||
else
|
||||
@ -1113,7 +1175,7 @@ function Init
|
||||
RSYNC_ARGS=$RSYNC_ARGS"n"
|
||||
DRY_WARNING="/!\ DRY RUN"
|
||||
fi
|
||||
if [ "$BANDWIDTH" != "0" ]
|
||||
if [ "$BANDWIDTH" != "" ] && [ "$BANDWIDTH" != "0" ]
|
||||
then
|
||||
RSYNC_ARGS=$RSYNC_ARGS" --bwlimit=$BANDWIDTH"
|
||||
fi
|
||||
@ -1148,11 +1210,6 @@ function Main
|
||||
if [ $dryrun -ne 1 ]
|
||||
then
|
||||
CreateLocalStorageDirectories
|
||||
else
|
||||
Log "DB backup list: $DATABASES_TO_BACKUP"
|
||||
Log "DB exclude list: $DATABASES_EXCLUDED_LIST"
|
||||
Log "Dirs backup list: $DIRECTORIES_TO_BACKUP"
|
||||
Log "Dirs exclude list: $DIRECTORIES_EXCLUDED_LIST"
|
||||
fi
|
||||
|
||||
CheckSpaceRequirements
|
||||
@ -1249,6 +1306,7 @@ then
|
||||
if [ $? == 0 ]
|
||||
then
|
||||
Init
|
||||
GetOperatingSystem
|
||||
DATE=$(date)
|
||||
Log "--------------------------------------------------------------------"
|
||||
Log "$DRY_WARNING $DATE - Obackup v$OBACKUP_VERSION script begin."
|
||||
|
Loading…
Reference in New Issue
Block a user