1
0
mirror of https://github.com/deajan/obackup.git synced 2026-02-12 01:50:55 +01:00

69 Commits

Author SHA1 Message Date
deajan
884fcf7eff Rebuilt targets for v2.1-beta3 2017-06-21 15:01:28 +02:00
deajan
92da7e68de Bumped version to v2.1-beta3 2017-06-21 15:01:03 +02:00
deajan
c02d301a45 Rebuilt targets 2017-06-20 19:02:22 +02:00
deajan
a48c55ef69 Updated changelog 2017-06-20 18:59:45 +02:00
deajan
83fdc5ee22 Moved rsync code before init 2017-06-20 16:23:14 +02:00
deajan
f097999bd3 Fixed missing rsync args 2017-06-20 16:20:44 +02:00
deajan
9a9a7ac8a3 Better cmdline option management 2017-06-20 15:56:07 +02:00
deajan
c60ac3784d Rebuilt targets 2017-06-20 15:23:29 +02:00
deajan
02fcf746ef Updated merge syntax 2017-06-20 15:22:57 +02:00
deajan
bd06dfe397 Made merge and bootstrap program agonstic 2017-06-20 15:22:37 +02:00
deajan
c7eb51f8a3 Fixed missing fi 2017-06-20 14:53:12 +02:00
deajan
ee689da7f3 Allow --partial, --delete and --dontgetsize to override config files 2017-06-20 14:50:50 +02:00
deajan
27a2b26473 Rebuilt targets 2017-06-09 11:50:10 +02:00
deajan
c2b14377c3 Update ofunctions 2017-06-09 11:49:53 +02:00
deajan
f15f216989 Rebuilt targets 2017-06-09 09:58:51 +02:00
deajan
0ee0bf52fd Updated ofunctions 2017-06-09 09:58:30 +02:00
deajan
8cd3ac6a50 Merge branch 'master' of https://github.com/deajan/obackup 2017-05-30 09:54:08 +02:00
deajan
e916df3e87 Update readme 2017-05-30 09:54:04 +02:00
deajan
be4ba9f366 Update ofunctions 2017-05-30 09:53:30 +02:00
Orsiris de Jong
cbdd836ddd Added BSD license badge 2017-05-22 14:57:55 +02:00
deajan
fbd5317010 Updated ofunctions 2017-05-22 12:05:50 +02:00
deajan
64c32bca07 Update ofunctions 2017-04-20 21:24:04 +02:00
deajan
644346316c Check program type for service files 2017-04-17 20:26:40 +02:00
deajan
304dace821 Added VerComp Subset 2017-04-11 13:28:32 +02:00
deajan
d311ef0574 Update ofunctions 2017-04-11 13:28:08 +02:00
deajan
56010d3a0d Update installer from pmocr 2017-04-11 13:27:58 +02:00
deajan
fefc01983d Added default umask 2017-04-08 22:11:27 +02:00
deajan
faafa81d10 Added umask for log & run dir files 2017-04-08 21:11:53 +02:00
deajan
5302c8c5f0 Updated common_batch from osync project 2017-03-30 22:19:41 +02:00
deajan
e2e4f4b563 Added --remove option to doc 2017-03-30 22:18:52 +02:00
deajan
67ecf9ea0a Update ofunctions from osync project 2017-03-30 22:18:36 +02:00
deajan
6f51b472c5 Updated installer from pmocr 2017-03-14 22:42:01 +01:00
deajan
f342cdb3b0 Rebuilt targets 2017-03-14 22:33:52 +01:00
deajan
2bb56d07b8 Fixed wrong program name 2017-03-14 22:33:35 +01:00
deajan
f291611011 Rebuilt targets 2017-03-14 22:31:15 +01:00
deajan
5d85b58f48 Updated changelog 2017-03-14 22:30:24 +01:00
deajan
30c88daaf2 Removed gzip --rsyncable option for MacOS 2017-03-14 22:18:15 +01:00
deajan
b121d96d69 Updated TSTAMP readability 2017-03-14 22:15:25 +01:00
deajan
375f5d413b Updated installer version logic 2017-03-14 22:15:13 +01:00
deajan
9474629d31 Check remote operation before remote cmd run 2017-02-13 12:16:10 +01:00
deajan
f4d587f1d1 Revert "Check backup type before remote system URI"
This reverts commit 52161b3faf.
2017-02-11 11:23:29 +01:00
deajan
52161b3faf Check backup type before remote system URI 2017-02-11 11:17:44 +01:00
deajan
34ba82784b Don't uninstall ssh filter if needed 2017-02-10 11:42:31 +01:00
deajan
d629105d92 Updated changelog 2017-02-10 11:40:59 +01:00
deajan
bc2705273f Funnier obfuscation :) 2017-02-10 11:06:40 +01:00
deajan
041ad4eaa7 More fine grained _REMOTE_TOKEN obfuscation 2017-02-10 10:59:56 +01:00
deajan
32c29f2ea3 Obfuscate _REMOTE_TOKEN in logs 2017-02-10 10:50:40 +01:00
deajan
bc799380a4 Don't show failed commands on stdout, only log them 2017-02-10 10:40:56 +01:00
deajan
b4829a798f Remove unnecessary spaces 2017-02-10 10:34:40 +01:00
deajan
a54577f6c8 rngd also needs sudo for travis 2017-02-09 13:30:03 +01:00
deajan
3b71ad70d2 Enabled sudo on travis 2017-02-09 13:10:38 +01:00
deajan
249e37db32 Fixed _REMOTE_TOKEN for rsync again (common) 2017-02-09 12:53:38 +01:00
deajan
d395e99640 Fixed wrong place for _REMOTE_TOKEN in rsync function 2017-02-09 12:49:31 +01:00
deajan
90857f4248 Fixed some typos 2017-02-09 12:48:20 +01:00
deajan
1f3da3a952 Removed debugging line 2017-02-09 12:45:54 +01:00
deajan
b5ef76bfa3 Added optional separator for SetConfFileValues 2017-02-09 12:45:27 +01:00
deajan
7a930c9aef Fixed typo 2017-02-09 12:35:33 +01:00
deajan
900783f543 Added _REMOTE_TOKEN option for ssh filter 2017-02-09 12:30:56 +01:00
deajan
ddd8e9eef3 Updated ssh filter from osync project 2017-02-09 12:28:30 +01:00
deajan
0a2df4efe9 Added _REMOTE_TOKEN and MAIL_BODY_CHARSET options 2017-02-09 12:28:02 +01:00
deajan
30f6e4e02c Added ssh_filter token options 2017-02-09 12:22:47 +01:00
deajan
7fc7676473 Imported ssh_filter fixes from osync 2017-02-09 12:21:11 +01:00
deajan
39cc2ca4b2 Update merger from osync 2017-02-09 12:13:36 +01:00
deajan
88a0718636 Update installer from osync 2017-02-09 12:13:10 +01:00
deajan
252df96e59 Updated ofunctions from osync 2017-02-09 12:12:41 +01:00
deajan
06efa18901 Fixed some typos 2017-01-09 12:30:38 +01:00
deajan
365c93a8a3 dd bs numeric format is not mac compatible 2017-01-09 11:21:47 +01:00
deajan
84bf01f2c8 Typos in assertEquals 2017-01-09 11:15:05 +01:00
deajan
84fa92e46c More preflight checks 2017-01-09 11:13:57 +01:00
19 changed files with 1611 additions and 776 deletions

View File

@@ -8,6 +8,9 @@ os:
linux linux
osx osx
sudo:
required
before_script: before_script:
mysql -e 'CREATE DATABASE travistest;' mysql -e 'CREATE DATABASE travistest;'

View File

@@ -9,6 +9,26 @@ KNOWN ISSUES
CHANGELOG CHANGELOG
--------- ---------
20 Jun 2017: obackup v2.1 beta3 released
----------------------------------------
- Fixed regression where some commandline arguments weren't honored anymore since 2.1 beta1 (--delete, --stats, --dontgetsize)
- Fixed commandline arguments aren't checked against valid list
14 Mar 2017: obackup v2.1 beta2 released
----------------------------------------
- Fixed remote commands can be run on local runs and obviously fail
- Uninstall leaves ssh_filter if needed by other programs
- Logger now obfuscates _REMOTE_TOKEN
- Improved sudo privilege run
- Brand new ssh filter from osync project
- Better installer with --remove option from osync project
- Updated ofunctions from osync project
- Fixes UTF-8 escaped characters in log files due to LC_ALL=C
- Optional MAIL_BODY_CHARSET so destination mails aren't sent as UTF-8 anymore depending on systems
- Minor fixes
04 Jan 2017: obackup v2.1 beta1 released 04 Jan 2017: obackup v2.1 beta1 released
---------------------------------------- ----------------------------------------

View File

@@ -1,7 +1,8 @@
# obackup [![Build Status](https://travis-ci.org/deajan/obackup.svg?branch=master)](https://travis-ci.org/deajan/obackup) [![GitHub Release](https://img.shields.io/github/release/deajan/obackup.svg?label=Latest)](https://github.com/deajan/obackup/releases/latest) # obackup [![Build Status](https://travis-ci.org/deajan/obackup.svg?branch=master)](https://travis-ci.org/deajan/obackup) [![License](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause) [![GitHub Release](https://img.shields.io/github/release/deajan/obackup.svg?label=Latest)](https://github.com/deajan/obackup/releases/latest)
A robust file & database backup script that works for local and remote push or pull backups via ssh. A robust file & database backup script that works for local and remote push or pull backups via ssh.
Designed to backup multiple subdirectories with a timeslot for each.
Supports encryption while still using rsync to lower transfered data (see advantages and caveats below).
## About ## About
@@ -34,7 +35,7 @@ You may disable this behavior in the config file.
You can download the latest obackup script from authors website. You can download the latest obackup script from authors website.
You may also clone the following git which will maybe have some more recent builds. You may also clone the following git which will maybe have some more recent builds.
$ git clone -b "v2.0-maint" git://github.com/deajan/obackup.git $ git clone -b "v2.1-maint" git://github.com/deajan/obackup.git
$ cd obackup $ cd obackup
$ ./install.sh $ ./install.sh

View File

@@ -1,30 +1,64 @@
#!/usr/bin/env bash #!/usr/bin/env bash
## dev pre-processor bootstrap rev 2016121302 ## dev pre-processor bootstrap rev 2017062001
## Yeah !!! A really tech sounding name... In fact it's just include emulation in bash ## Yeah !!! A really tech sounding name... In fact it's just include emulation in bash
function Usage {
echo "$0 - Quick and dirty preprocessor for including ofunctions into programs"
echo "Creates and executes $0.tmp.sh"
echo "Usage:"
echo ""
echo "$0 --program=osync|osync_target_helper|obackup|pmocr [options to pass to program]"
}
if [ ! -f "./merge.sh" ]; then if [ ! -f "./merge.sh" ]; then
echo "Plrase run bootstrap.sh from osync/dev directory." echo "Plrase run bootstrap.sh from osync/dev directory."
exit 1 exit 1
fi fi
bootstrapProgram=""
opts=""
outputFileName="$0" outputFileName="$0"
source "merge.sh" for i in "$@"; do
__PREPROCESSOR_PROGRAM=obackup case $i in
__PREPROCESSOR_Constants --program=*)
bootstrapProgram="${i##*=}"
;;
*)
opts=$opts" $i"
;;
esac
done
cp "n_$__PREPROCESSOR_PROGRAM.sh" "$outputFileName.tmp.sh" if [ "$bootstrapProgram" == "" ]; then
Usage
exit 128
else
source "merge.sh"
__PREPROCESSOR_PROGRAM=$bootstrapProgram
__PREPROCESSOR_PROGRAM_EXEC="n_$bootstrapProgram.sh"
__PREPROCESSOR_Constants
if [ ! -f "$__PREPROCESSOR_PROGRAM_EXEC" ]; then
echo "Cannot find file [n_$bootstrapProgram.sh]."
exit 1
fi
fi
cp "$__PREPROCESSOR_PROGRAM_EXEC" "$outputFileName.tmp.sh"
if [ $? != 0 ]; then if [ $? != 0 ]; then
echo "Cannot copy original file [n_$__PREPROCESSOR_PROGRAM.sh] to [$outputFileName.tmp.sh]." echo "Cannot copy original file [$__PREPROCESSOR_PROGRAM_EXEC] to [$outputFileName.tmp.sh]."
exit 1 exit 1
fi fi
for subset in "${__PREPROCESSOR_SUBSETS[@]}"; do for subset in "${__PREPROCESSOR_SUBSETS[@]}"; do
__PREPROCESSOR_MergeSubset "$subset" "${subset//SUBSET/SUBSET END}" "ofunctions.sh" "$outputFileName.tmp.sh" __PREPROCESSOR_MergeSubset "$subset" "${subset//SUBSET/SUBSET END}" "ofunctions.sh" "$outputFileName.tmp.sh"
done done
chmod +x "$0.tmp.sh" chmod +x "$outputFileName.tmp.sh"
if [ $? != 0 ]; then if [ $? != 0 ]; then
echo "Cannot make [$outputFileName] executable.." echo "Cannot make [$outputFileName] executable."
exit 1 exit 1
fi fi
@@ -33,4 +67,4 @@ if type termux-fix-shebang > /dev/null 2>&1; then
termux-fix-shebang "$outputFileName.tmp.sh" termux-fix-shebang "$outputFileName.tmp.sh"
fi fi
"$outputFileName.tmp.sh" "$@" "$outputFileName.tmp.sh" $opts

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env bash #!/usr/bin/env bash
SUBPROGRAM=[prgname] SUBPROGRAM=[prgname]
PROGRAM="$SUBPROGRAM-batch" # Batch program to run osync / obackup instances sequentially and rerun failed ones PROGRAM="$SUBPROGRAM-batch" # Batch program to run osync / obackup instances sequentially and rerun failed ones
AUTHOR="(L) 2013-2016 by Orsiris de Jong" AUTHOR="(L) 2013-2017 by Orsiris de Jong"
CONTACT="http://www.netpower.fr - ozy@netpower.fr" CONTACT="http://www.netpower.fr - ozy@netpower.fr"
PROGRAM_BUILD=2016120401 PROGRAM_BUILD=2016120401
@@ -119,15 +119,15 @@ function Batch {
fi fi
done done
runList=("${runAgainList[@]}") runList=("${runAgainList[@]}")
runs=$(($runs + 1)) runs=$((runs + 1))
done done
fi fi
} }
function Usage { function Usage {
echo "$PROGRAM $PROGRAM_BUILD" echo "$PROGRAM $PROGRAM_BUILD"
echo $AUTHOR echo "$AUTHOR"
echo $CONTACT echo "$CONTACT"
echo "" echo ""
echo "Batch script to sequentially run osync or obackup instances and rerun failed ones." echo "Batch script to sequentially run osync or obackup instances and rerun failed ones."
echo "Usage: $PROGRAM.sh [OPTIONS] [$SUBPROGRAM OPTIONS]" echo "Usage: $PROGRAM.sh [OPTIONS] [$SUBPROGRAM OPTIONS]"

View File

@@ -1,12 +1,18 @@
#!/usr/bin/env bash #!/usr/bin/env bash
## Installer script suitable for osync / obackup / pmocr
include #### _OFUNCTIONS_BOOTSTRAP SUBSET #### include #### _OFUNCTIONS_BOOTSTRAP SUBSET ####
PROGRAM=[prgname] PROGRAM=[prgname]
PROGRAM_VERSION=[version]
PROGRAM_VERSION=$(grep "PROGRAM_VERSION=" $PROGRAM.sh)
PROGRAM_VERSION=${PROGRAM_VERSION#*=}
PROGRAM_BINARY=$PROGRAM".sh" PROGRAM_BINARY=$PROGRAM".sh"
PROGRAM_BATCH=$PROGRAM"-batch.sh" PROGRAM_BATCH=$PROGRAM"-batch.sh"
SCRIPT_BUILD=2016122701 SSH_FILTER="ssh_filter.sh"
SCRIPT_BUILD=2017041701
## osync / obackup / pmocr / zsnap install script ## osync / obackup / pmocr / zsnap install script
## Tested on RHEL / CentOS 6 & 7, Fedora 23, Debian 7 & 8, Mint 17 and FreeBSD 8, 10 and 11 ## Tested on RHEL / CentOS 6 & 7, Fedora 23, Debian 7 & 8, Mint 17 and FreeBSD 8, 10 and 11
@@ -22,19 +28,20 @@ SERVICE_DIR_INIT=$FAKEROOT/etc/init.d
SERVICE_DIR_SYSTEMD_SYSTEM=$FAKEROOT/lib/systemd/system SERVICE_DIR_SYSTEMD_SYSTEM=$FAKEROOT/lib/systemd/system
SERVICE_DIR_SYSTEMD_USER=$FAKEROOT/etc/systemd/user SERVICE_DIR_SYSTEMD_USER=$FAKEROOT/etc/systemd/user
## osync specific code if [ "$PROGRAM" == "osync" ]; then
OSYNC_SERVICE_FILE_INIT="osync-srv" SERVICE_NAME="osync-srv"
OSYNC_SERVICE_FILE_SYSTEMD_SYSTEM="osync-srv@.service" elif [ "$PROGRAM" == "pmocr" ]; then
OSYNC_SERVICE_FILE_SYSTEMD_USER="osync-srv@.service.user" SERVICE_NAME="pmocr-srv"
fi
## pmocr specfic code SERVICE_FILE_INIT="$SERVICE_NAME"
PMOCR_SERVICE_FILE_INIT="pmocr-srv" SERVICE_FILE_SYSTEMD_SYSTEM="$SERVICE_NAME@.service"
PMOCR_SERVICE_FILE_SYSTEMD_SYSTEM="pmocr-srv@.service" SERVICE_FILE_SYSTEMD_USER="$SERVICE_NAME@.service.user"
## Generic code ## Generic code
## Default log file ## Default log file
if [ -w $FAKEROOT/var/log ]; then if [ -w "$FAKEROOT/var/log" ]; then
LOG_FILE="$FAKEROOT/var/log/$PROGRAM-install.log" LOG_FILE="$FAKEROOT/var/log/$PROGRAM-install.log"
elif ([ "$HOME" != "" ] && [ -w "$HOME" ]); then elif ([ "$HOME" != "" ] && [ -w "$HOME" ]); then
LOG_FILE="$HOME/$PROGRAM-install.log" LOG_FILE="$HOME/$PROGRAM-install.log"
@@ -45,6 +52,8 @@ fi
include #### QuickLogger SUBSET #### include #### QuickLogger SUBSET ####
include #### UrlEncode SUBSET #### include #### UrlEncode SUBSET ####
include #### GetLocalOS SUBSET #### include #### GetLocalOS SUBSET ####
include #### GetConfFileValue SUBSET ####
function SetLocalOSSettings { function SetLocalOSSettings {
USER=root USER=root
@@ -66,7 +75,7 @@ function SetLocalOSSettings {
;; ;;
esac esac
if [ "$LOCAL_OS" == "Android" ] || [ "$LOCAL_OS" == "MacOSX" ] || [ "$LOCAL_OS" == "BusyBox" ]; then if [ "$LOCAL_OS" == "Android" ] || [ "$LOCAL_OS" == "BusyBox" ]; then
QuickLogger "Cannot be installed on [$LOCAL_OS]. Please use $PROGRAM.sh directly." QuickLogger "Cannot be installed on [$LOCAL_OS]. Please use $PROGRAM.sh directly."
exit 1 exit 1
fi fi
@@ -92,126 +101,131 @@ function GetInit {
fi fi
} }
function CreateConfDir { function CreateDir {
if [ ! -d "$CONF_DIR" ]; then local dir="${1}"
mkdir "$CONF_DIR"
if [ ! -d "$dir" ]; then
mkdir "$dir"
if [ $? == 0 ]; then if [ $? == 0 ]; then
QuickLogger "Created directory [$CONF_DIR]." QuickLogger "Created directory [$dir]."
else else
QuickLogger "Cannot create directory [$CONF_DIR]." QuickLogger "Cannot create directory [$dir]."
exit 1 exit 1
fi fi
fi
}
function CopyFile {
local sourcePath="${1}"
local destPath="${2}"
local fileName="${3}"
local fileMod="${4}"
local fileUser="${5}"
local fileGroup="${6}"
local overwrite="${7:-false}"
local userGroup=""
local oldFileName
if [ -f "$destPath/$fileName" ] && [ $overwrite == false ]; then
oldFileName="$fileName"
fileName="$oldFileName.new"
cp "$sourcePath/$oldFileName" "$destPath/$fileName"
else else
QuickLogger "Config directory [$CONF_DIR] exists." cp "$sourcePath/$fileName" "$destPath"
fi
if [ $? != 0 ]; then
QuickLogger "Cannot copy [$fileName] to [$destPath]. Make sure to run install script in the directory containing all other files."
QuickLogger "Also make sure you have permissions to write to [$BIN_DIR]."
exit 1
else
QuickLogger "Copied [$fileName] to [$destPath]."
if [ "$fileMod" != "" ]; then
chmod "$fileMod" "$destPath/$fileName"
if [ $? != 0 ]; then
QuickLogger "Cannot set file permissions of [$destPath/$fileName] to [$fileMod]."
exit 1
else
QuickLogger "Set file permissions to [$fileMod] on [$destPath/$fileName]."
fi
fi
if [ "$fileUser" != "" ]; then
userGroup="$fileUser"
if [ "$fileGroup" != "" ]; then
userGroup="$userGroup"":$fileGroup"
fi
chown "$userGroup" "$destPath/$fileName"
if [ $? != 0 ]; then
QuickLogger "Could not set file ownership on [$destPath/$fileName] to [$userGroup]."
exit 1
else
QuickLogger "Set file ownership on [$destPath/$fileName] to [$userGroup]."
fi
fi
fi fi
} }
function CopyExampleFiles { function CopyExampleFiles {
if [ -f "$SCRIPT_PATH/sync.conf.example" ]; then exampleFiles=()
cp "$SCRIPT_PATH/sync.conf.example" "$CONF_DIR/sync.conf.example" exampleFiles[0]="sync.conf.example" # osync
fi exampleFiles[1]="host_backup.conf.example" # obackup
exampleFiles[2]="exclude.list.example" # osync & obackup
exampleFiles[3]="snapshot.conf.example" # zsnap
exampleFiles[4]="default.conf" # pmocr
if [ -f "$SCRIPT_PATH/host_backup.conf.example" ]; then for file in "${exampleFiles[@]}"; do
cp "$SCRIPT_PATH/host_backup.conf.example" "$CONF_DIR/host_backup.conf.example" if [ -f "$SCRIPT_PATH/$file" ]; then
fi CopyFile "$SCRIPT_PATH" "$CONF_DIR" "$file" "" "" "" false
if [ -f "$SCRIPT_PATH/exlude.list.example" ]; then
cp "$SCRIPT_PATH/exclude.list.example" "$CONF_DIR/exclude.list.example"
fi
if [ -f "$SCRIPT_PATH/snapshot.conf.example" ]; then
cp "$SCRIPT_PATH/snapshot.conf.example" "$CONF_DIR/snapshot.conf.example"
fi
if [ -f "$SCRIPT_PATH/default.conf" ]; then
if [ -f "$CONF_DIR/default.conf" ]; then
cp "$SCRIPT_PATH/default.conf" "$CONF_DIR/default.conf.new"
QuickLogger "Copied default.conf to [$CONF_DIR/default.conf.new]."
else
cp "$SCRIPT_PATH/default.conf" "$CONF_DIR/default.conf"
fi fi
fi done
} }
function CopyProgram { function CopyProgram {
cp "$SCRIPT_PATH/$PROGRAM_BINARY" "$BIN_DIR" binFiles=()
if [ $? != 0 ]; then binFiles[0]="$PROGRAM_BINARY"
QuickLogger "Cannot copy $PROGRAM_BINARY to [$BIN_DIR]. Make sure to run install script in the directory containing all other files." if [ "$PROGRAM" == "osync" ] || [ "$PROGRAM" == "obackup" ]; then
QuickLogger "Also make sure you have permissions to write to [$BIN_DIR]." binFiles[1]="$PROGRAM_BATCH"
exit 1 binFiles[2]="$SSH_FILTER"
else
chmod 755 "$BIN_DIR/$PROGRAM_BINARY"
QuickLogger "Copied $PROGRAM_BINARY to [$BIN_DIR]."
fi fi
if [ -f "$SCRIPT_PATH/$PROGRAM_BATCH" ]; then local user=""
cp "$SCRIPT_PATH/$PROGRAM_BATCH" "$BIN_DIR" local group=""
if [ $? != 0 ]; then
QuickLogger "Cannot copy $PROGRAM_BATCH to [$BIN_DIR]." if ([ "$USER" != "" ] && [ "$FAKEROOT" == "" ]); then
else user="$USER"
chmod 755 "$BIN_DIR/$PROGRAM_BATCH" fi
QuickLogger "Copied $PROGRAM_BATCH to [$BIN_DIR]." if ([ "$GROUP" != "" ] && [ "$FAKEROOT" == "" ]); then
fi group="$GROUP"
fi fi
if [ -f "$SCRIPT_PATH/ssh_filter.sh" ]; then for file in "${binFiles[@]}"; do
cp "$SCRIPT_PATH/ssh_filter.sh" "$BIN_DIR" CopyFile "$SCRIPT_PATH" "$BIN_DIR" "$file" 755 "$user" "$group" true
if [ $? != 0 ]; then done
QuickLogger "Cannot copy ssh_filter.sh to [$BIN_DIR]."
else
chmod 755 "$BIN_DIR/ssh_filter.sh"
if ([ "$USER" != "" ] && [ "$GROUP" != "" ] && [ "$FAKEROOT" == "" ]); then
chown $USER:$GROUP "$BIN_DIR/ssh_filter.sh"
fi
QuickLogger "Copied ssh_filter.sh to [$BIN_DIR]."
fi
fi
} }
function CopyServiceFiles { function CopyServiceFiles {
# OSYNC SPECIFIC if ([ "$init" == "systemd" ] && [ -f "$SCRIPT_PATH/$SERVICE_FILE_SYSTEMD_SYSTEM" ]); then
if ([ "$init" == "systemd" ] && [ -f "$SCRIPT_PATH/$OSYNC_SERVICE_FILE_SYSTEMD_SYSTEM" ]); then CopyFile "$SCRIPT_PATH" "$SERVICE_DIR_SYSTEMD_SYSTEM" "$SERVICE_FILE_SYSTEMD_SYSTEM" "" "" "" true
cp "$SCRIPT_PATH/$OSYNC_SERVICE_FILE_SYSTEMD_SYSTEM" "$SERVICE_DIR_SYSTEMD_SYSTEM" && cp "$SCRIPT_PATH/$OSYNC_SERVICE_FILE_SYSTEMD_USER" "$SERVICE_DIR_SYSTEMD_USER/$SERVICE_FILE_SYSTEMD_SYSTEM" if [ -f "$SCRIPT_PATH/$SERVICE_FILE_SYSTEMD_SYSTEM_USER" ]; then
if [ $? != 0 ]; then CopyFile "$SCRIPT_PATH" "$SERVICE_DIR_SYSTEMD_USER" "$SERVICE_FILE_SYSTEMD_USER" "" "" "" true
QuickLogger "Cannot copy the systemd file to [$SERVICE_DIR_SYSTEMD_SYSTEM] or [$SERVICE_DIR_SYSTEMD_USER]."
else
QuickLogger "Created osync-srv service in [$SERVICE_DIR_SYSTEMD_SYSTEM] and [$SERVICE_DIR_SYSTEMD_USER]."
QuickLogger "Can be activated with [systemctl start osync-srv@instance.conf] where instance.conf is the name of the config file in $CONF_DIR."
QuickLogger "Can be enabled on boot with [systemctl enable osync-srv@instance.conf]."
QuickLogger "In userland, active with [systemctl --user start osync-srv@instance.conf]."
fi fi
elif ([ "$init" == "initV" ] && [ -f "$SCRIPT_PATH/$OSYNC_SERVICE_FILE_INIT" ]); then
cp "$SCRIPT_PATH/$OSYNC_SERVICE_FILE_INIT" "$SERVICE_DIR_INIT"
if [ $? != 0 ]; then
QuickLogger "Cannot copy osync-srv to [$SERVICE_DIR_INIT]."
else
chmod 755 "$SERVICE_DIR_INIT/$OSYNC_SERVICE_FILE_INIT"
QuickLogger "Created osync-srv service in [$SERVICE_DIR_INIT]."
QuickLogger "Can be activated with [service $OSYNC_SERVICE_FILE_INIT start]."
QuickLogger "Can be enabled on boot with [chkconfig $OSYNC_SERVICE_FILE_INIT on]."
fi
fi
# PMOCR SPECIFIC QuickLogger "Created [$SERVICE_NAME] service in [$SERVICE_DIR_SYSTEMD_SYSTEM] and [$SERVICE_DIR_SYSTEMD_USER]."
if ([ "$init" == "systemd" ] && [ -f "$SCRIPT_PATH/$PMOCR_SERVICE_FILE_SYSTEMD_SYSTEM" ]); then QuickLogger "Can be activated with [systemctl start SERVICE_NAME@instance.conf] where instance.conf is the name of the config file in $CONF_DIR."
cp "$SCRIPT_PATH/$PMOCR_SERVICE_FILE_SYSTEMD_SYSTEM" "$SERVICE_DIR_SYSTEMD_SYSTEM" QuickLogger "Can be enabled on boot with [systemctl enable $SERVICE_NAME@instance.conf]."
if [ $? != 0 ]; then QuickLogger "In userland, active with [systemctl --user start $SERVICE_NAME@instance.conf]."
QuickLogger "Cannot copy the systemd file to [$SERVICE_DIR_SYSTEMD_SYSTEM] or [$SERVICE_DIR_SYSTEMD_USER]." elif ([ "$init" == "initV" ] && [ -f "$SCRIPT_PATH/$SERVICE_FILE_INIT" ] && [ -d "$SERVICE_DIR_INIT" ]); then
else CopyFile "$SCRIPT_PATH" "$SERVICE_DIR_INIT" "$SERVICE_FILE_INIT" "755" "" "" true
QuickLogger "Created pmocr-srv service in [$SERVICE_DIR_SYSTEMD_SYSTEM] and [$SERVICE_DIR_SYSTEMD_USER]."
QuickLogger "Can be activated with [systemctl start pmocr-srv@default.conf] where default.conf is the name of the config file in $CONF_DIR." QuickLogger "Created [$SERVICE_NAME] service in [$SERVICE_DIR_INIT]."
QuickLogger "Can be enabled on boot with [systemctl enable pmocr-srv@default.conf]." QuickLogger "Can be activated with [service $SERVICE_FILE_INIT start]."
fi QuickLogger "Can be enabled on boot with [chkconfig $SERVICE_FILE_INIT on]."
elif ([ "$init" == "initV" ] && [ -f "$SCRIPT_PATH/$PMOCR_SERVICE_FILE_INIT" ]); then else
cp "$SCRIPT_PATH/$PMOCR_SERVICE_FILE_INIT" "$SERVICE_DIR_INIT" QuickLogger "Cannot define what init style is in use on this system. Skipping service file installation."
if [ $? != 0 ]; then
QuickLogger "Cannot copy pmoct-srv to [$SERVICE_DIR_INIT]."
else
chmod 755 "$SERVICE_DIR_INIT/$PMOCR_SERVICE_FILE_INIT"
QuickLogger "Created osync-srv service in [$SERVICE_DIR_INIT]."
QuickLogger "Can be activated with [service $PMOCR_SERVICE_FILE_INIT start]."
QuickLogger "Can be enabled on boot with [chkconfig $PMOCR_SERVICE_FILE_INIT on]."
fi
fi fi
} }
@@ -234,16 +248,53 @@ function Statistics {
return 1 return 1
} }
function RemoveFile {
local file="${1}"
if [ -f "$file" ]; then
rm -f "$file"
if [ $? != 0 ]; then
QuickLogger "Could not remove file [$file]."
else
QuickLogger "Removed file [$file]."
fi
else
QuickLogger "File [$file] not found. Skipping."
fi
}
function RemoveAll {
RemoveFile "$BIN_DIR/$PROGRAM_BINARY"
if [ "$PROGRAM" == "osync" ] || [ "$PROGRAM" == "obackup" ]; then
RemoveFile "$BIN_DIR/$PROGRAM_BATCH"
fi
if [ ! -f "$BIN_DIR/osync.sh" ] && [ ! -f "$BIN_DIR/obackup.sh" ]; then # Check if any other program requiring ssh filter is present before removal
RemoveFile "$BIN_DIR/$SSH_FILTER"
else
QuickLogger "Skipping removal of [$BIN_DIR/$SSH_FILTER] because other programs present that need it."
fi
RemoveFile "$SERVICE_DIR_SYSTEMD_SYSTEM/$SERVICE_FILE_SYSTEMD_SYSTEM"
RemoveFile "$SERVICE_DIR_SYSTEMD_USER/$SERVICE_FILE_SYSTEMD_SYSTEM"
RemoveFile "$SERVICE_DIR_INIT/$SERVICE_FILE_INIT"
QuickLogger "Skipping configuration files in [$CONF_DIR]. You may remove this directory manually."
}
function Usage { function Usage {
echo "Installs $PROGRAM into $BIN_DIR" echo "Installs $PROGRAM into $BIN_DIR"
echo "options:" echo "options:"
echo "--silent Will log and bypass user interaction." echo "--silent Will log and bypass user interaction."
echo "--no-stats Used with --silent in order to refuse sending anonymous install stats." echo "--no-stats Used with --silent in order to refuse sending anonymous install stats."
echo "--remove Remove the program."
exit 127 exit 127
} }
_LOGGER_SILENT=false _LOGGER_SILENT=false
_STATS=1 _STATS=1
ACTION="install"
for i in "$@" for i in "$@"
do do
case $i in case $i in
@@ -253,6 +304,9 @@ do
--no-stats) --no-stats)
_STATS=0 _STATS=0
;; ;;
--remove)
ACTION="uninstall"
;;
--help|-h|-?) --help|-h|-?)
Usage Usage
esac esac
@@ -264,21 +318,35 @@ fi
GetLocalOS GetLocalOS
SetLocalOSSettings SetLocalOSSettings
CreateConfDir
CopyExampleFiles
CopyProgram
GetInit GetInit
CopyServiceFiles
STATS_LINK="http://instcount.netpower.fr?program=$PROGRAM&version=$PROGRAM_VERSION&os=$OS" STATS_LINK="http://instcount.netpower.fr?program=$PROGRAM&version=$PROGRAM_VERSION&os=$OS&action=$ACTION"
if [ "$ACTION" == "uninstall" ]; then
RemoveAll
QuickLogger "$PROGRAM uninstalled."
else
CreateDir "$CONF_DIR"
CreateDir "$BIN_DIR"
CopyExampleFiles
CopyProgram
if [ "$PROGRAM" == "osync" ] || [ "$PROGRAM" == "pmocr" ]; then
CopyServiceFiles
fi
QuickLogger "$PROGRAM installed. Use with $BIN_DIR/$PROGRAM"
if [ "$PROGRAM" == "osync" ] || [ "$PROGRAM" == "obackup" ]; then
QuickLogger ""
QuickLogger "If connecting remotely, consider setup ssh filter to enhance security."
QuickLogger ""
fi
fi
QuickLogger "$PROGRAM installed. Use with $BIN_DIR/$PROGRAM"
if [ $_STATS -eq 1 ]; then if [ $_STATS -eq 1 ]; then
if [ $_LOGGER_SILENT == true ]; then if [ $_LOGGER_SILENT == true ]; then
Statistics Statistics
else else
QuickLogger "In order to make install statistics, the script would like to connect to $STATS_LINK" QuickLogger "In order to make usage statistics, the script would like to connect to $STATS_LINK"
read -r -p "No data except those in the url will be send. Allow [Y/n]" response read -r -p "No data except those in the url will be send. Allow [Y/n] " response
case $response in case $response in
[nN]) [nN])
exit exit

View File

@@ -6,12 +6,11 @@
PROGRAM="obackup" PROGRAM="obackup"
AUTHOR="(C) 2013-2017 by Orsiris de Jong" AUTHOR="(C) 2013-2017 by Orsiris de Jong"
CONTACT="http://www.netpower.fr/obackup - ozy@netpower.fr" CONTACT="http://www.netpower.fr/obackup - ozy@netpower.fr"
PROGRAM_VERSION=2.1-beta1 PROGRAM_VERSION=2.1-beta3
PROGRAM_BUILD=2017010305 PROGRAM_BUILD=2017062004
IS_STABLE=no IS_STABLE=no
# Execution order #__WITH_PARANOIA_DEBUG #### Execution order #__WITH_PARANOIA_DEBUG
# GetLocalOS #__WITH_PARANOIA_DEBUG # GetLocalOS #__WITH_PARANOIA_DEBUG
# InitLocalOSDependingSettings #__WITH_PARANOIA_DEBUG # InitLocalOSDependingSettings #__WITH_PARANOIA_DEBUG
# CheckRunningInstances #__WITH_PARANOIA_DEBUG # CheckRunningInstances #__WITH_PARANOIA_DEBUG
@@ -36,9 +35,8 @@ IS_STABLE=no
# FilesBackup #__WITH_PARANOIA_DEBUG # FilesBackup #__WITH_PARANOIA_DEBUG
_OFUNCTIONS_VERSION=2.1.4-rc1
_OFUNCTIONS_VERSION=2.1-RC1+dev _OFUNCTIONS_BUILD=2017060903
_OFUNCTIONS_BUILD=2017010401
_OFUNCTIONS_BOOTSTRAP=true _OFUNCTIONS_BOOTSTRAP=true
## BEGIN Generic bash functions written in 2013-2017 by Orsiris de Jong - http://www.netpower.fr - ozy@netpower.fr ## BEGIN Generic bash functions written in 2013-2017 by Orsiris de Jong - http://www.netpower.fr - ozy@netpower.fr
@@ -63,6 +61,9 @@ fi
## Correct output of sort command (language agnostic sorting) ## Correct output of sort command (language agnostic sorting)
export LC_ALL=C export LC_ALL=C
## Default umask for file creation
umask 0077
# Standard alert mail body # Standard alert mail body
MAIL_ALERT_MSG="Execution of $PROGRAM instance $INSTANCE_ID on $(date) has warnings/errors." MAIL_ALERT_MSG="Execution of $PROGRAM instance $INSTANCE_ID on $(date) has warnings/errors."
@@ -99,7 +100,9 @@ if [ "$SLEEP_TIME" == "" ]; then # Leave the possibity to set SLEEP_TIME as envi
fi fi
SCRIPT_PID=$$ SCRIPT_PID=$$
TSTAMP=$(date '+%Y%m%d%H%M%S%N')
# TODO: Check if %N works on MacOS
TSTAMP=$(date '+%Y%m%dT%H%M%S.%N')
LOCAL_USER=$(whoami) LOCAL_USER=$(whoami)
LOCAL_HOST=$(hostname) LOCAL_HOST=$(hostname)
@@ -155,7 +158,7 @@ function joinString {
function _Logger { function _Logger {
local logValue="${1}" # Log to file local logValue="${1}" # Log to file
local stdValue="${2}" # Log to screeen local stdValue="${2}" # Log to screeen
local toStderr="${3:-false}" # Log to stderr instead of stdout local toStdErr="${3:-false}" # Log to stderr instead of stdout
if [ "$logValue" != "" ]; then if [ "$logValue" != "" ]; then
echo -e "$logValue" >> "$LOG_FILE" echo -e "$logValue" >> "$LOG_FILE"
@@ -164,7 +167,7 @@ function _Logger {
fi fi
if [ "$stdValue" != "" ] && [ "$_LOGGER_SILENT" != true ]; then if [ "$stdValue" != "" ] && [ "$_LOGGER_SILENT" != true ]; then
if [ $toStderr == true ]; then if [ $toStdErr == true ]; then
# Force stderr color in subshell # Force stderr color in subshell
(>&2 echo -e "$stdValue") (>&2 echo -e "$stdValue")
@@ -263,6 +266,10 @@ function Logger {
prefix="" prefix=""
fi fi
## Obfuscate _REMOTE_TOKEN in logs (for ssh_filter usage only in osync and obackup)
value="${value/env _REMOTE_TOKEN=$_REMOTE_TOKEN/__(o_O)__}"
value="${value/env _REMOTE_TOKEN=\$_REMOTE_TOKEN/__(o_O)__}"
if [ "$level" == "CRITICAL" ]; then if [ "$level" == "CRITICAL" ]; then
_Logger "$prefix($level):$value" "$prefix\e[1;33;41m$value\e[0m" true _Logger "$prefix($level):$value" "$prefix\e[1;33;41m$value\e[0m" true
ERROR_ALERT=true ERROR_ALERT=true
@@ -286,7 +293,7 @@ function Logger {
return return
elif [ "$level" == "VERBOSE" ]; then elif [ "$level" == "VERBOSE" ]; then
if [ $_LOGGER_VERBOSE == true ]; then if [ $_LOGGER_VERBOSE == true ]; then
_Logger "$prefix:$value" "$prefix$value" _Logger "$prefix($level):$value" "$prefix$value"
fi fi
return return
elif [ "$level" == "ALWAYS" ]; then elif [ "$level" == "ALWAYS" ]; then
@@ -337,15 +344,29 @@ function KillChilds {
local pid="${1}" # Parent pid to kill childs local pid="${1}" # Parent pid to kill childs
local self="${2:-false}" # Should parent be killed too ? local self="${2:-false}" # Should parent be killed too ?
# Warning: pgrep does not exist in cygwin, have this checked in CheckEnvironment # Paranoid checks, we can safely assume that $pid shouldn't be 0 nor 1
if children="$(pgrep -P "$pid")"; then if [ $(IsNumeric "$pid") -eq 0 ] || [ "$pid" == "" ] || [ "$pid" == "0" ] || [ "$pid" == "1" ]; then
for child in $children; do Logger "Bogus pid given [$pid]." "CRITICAL"
Logger "Launching KillChilds \"$child\" true" "DEBUG" #__WITH_PARANOIA_DEBUG return 1
KillChilds "$child" true
done
fi fi
# Try to kill nicely, if not, wait 15 seconds to let Trap actions happen before killing
if kill -0 "$pid" > /dev/null 2>&1; then
# Warning: pgrep is not native on cygwin, have this checked in CheckEnvironment
if children="$(pgrep -P "$pid")"; then
if [[ "$pid" == *"$children"* ]]; then
Logger "Bogus pgrep implementation." "CRITICAL"
children="${children/$pid/}"
fi
for child in $children; do
Logger "Launching KillChilds \"$child\" true" "DEBUG" #__WITH_PARANOIA_DEBUG
KillChilds "$child" true
done
fi
fi
# Try to kill nicely, if not, wait 15 seconds to let Trap actions happen before killing
if [ "$self" == true ]; then if [ "$self" == true ]; then
# We need to check for pid again because it may have disappeared after recursive function call
if kill -0 "$pid" > /dev/null 2>&1; then if kill -0 "$pid" > /dev/null 2>&1; then
kill -s TERM "$pid" kill -s TERM "$pid"
Logger "Sent SIGTERM to process [$pid]." "DEBUG" Logger "Sent SIGTERM to process [$pid]." "DEBUG"
@@ -408,13 +429,17 @@ function SendAlert {
eval "cat \"$LOG_FILE\" $COMPRESSION_PROGRAM > $ALERT_LOG_FILE" eval "cat \"$LOG_FILE\" $COMPRESSION_PROGRAM > $ALERT_LOG_FILE"
if [ $? != 0 ]; then if [ $? != 0 ]; then
Logger "Cannot create [$ALERT_LOG_FILE]" "WARN"
attachment=false attachment=false
else else
attachment=true attachment=true
fi fi
if [ -e "$RUN_DIR/$PROGRAM._Logger.$SCRIPT_PID.$TSTAMP" ]; then if [ -e "$RUN_DIR/$PROGRAM._Logger.$SCRIPT_PID.$TSTAMP" ]; then
body="$MAIL_ALERT_MSG"$'\n\n'"$(cat $RUN_DIR/$PROGRAM._Logger.$SCRIPT_PID.$TSTAMP)" if [ "$MAIL_BODY_CHARSET" != "" ] && type iconv > /dev/null 2>&1; then
iconv -f UTF-8 -t $MAIL_BODY_CHARSET "$RUN_DIR/$PROGRAM._Logger.$SCRIPT_PID.$TSTAMP" > "$RUN_DIR/$PROGRAM._Logger.iconv.$SCRIPT_PID.$TSTAMP"
body="$MAIL_ALERT_MSG"$'\n\n'"$(cat $RUN_DIR/$PROGRAM._Logger.iconv.$SCRIPT_PID.$TSTAMP)"
else
body="$MAIL_ALERT_MSG"$'\n\n'"$(cat $RUN_DIR/$PROGRAM._Logger.$SCRIPT_PID.$TSTAMP)"
fi
fi fi
if [ $ERROR_ALERT == true ]; then if [ $ERROR_ALERT == true ]; then
@@ -650,6 +675,22 @@ function Spinner {
fi fi
} }
function _PerfProfiler { #__WITH_PARANOIA_DEBUG
local perfString #__WITH_PARANOIA_DEBUG
#__WITH_PARANOIA_DEBUG
perfString=$(ps -p $$ -o args,pid,ppid,%cpu,%mem,time,etime,state,wchan) #__WITH_PARANOIA_DEBUG
#__WITH_PARANOIA_DEBUG
for i in $(pgrep -P $$); do #__WITH_PARANOIA_DEBUG
perfString="$perfString\n"$(ps -p $i -o args,pid,ppid,%cpu,%mem,time,etime,state,wchan | tail -1) #__WITH_PARANOIA_DEBUG
done #__WITH_PARANOIA_DEBUG
#__WITH_PARANOIA_DEBUG
if type iostat > /dev/null 2>&1; then #__WITH_PARANOIA_DEBUG
perfString="$perfString\n"$(iostat) #__WITH_PARANOIA_DEBUG
fi #__WITH_PARANOIA_DEBUG
#__WITH_PARANOIA_DEBUG
Logger "PerfProfiler:\n$perfString" "PARANOIA_DEBUG" #__WITH_PARANOIA_DEBUG
} #__WITH_PARANOIA_DEBUG
# Time control function for background processes, suitable for multiple synchronous processes # Time control function for background processes, suitable for multiple synchronous processes
# Fills a global variable called WAIT_FOR_TASK_COMPLETION_$callerName that contains list of failed pids in format pid1:result1;pid2:result2 # Fills a global variable called WAIT_FOR_TASK_COMPLETION_$callerName that contains list of failed pids in format pid1:result1;pid2:result2
@@ -782,6 +823,11 @@ function WaitForTaskCompletion {
pidsArray=("${newPidsArray[@]}") pidsArray=("${newPidsArray[@]}")
# Trivial wait time for bash to not eat up all CPU # Trivial wait time for bash to not eat up all CPU
sleep $sleepTime sleep $sleepTime
if [ "$_PERF_PROFILER" == "yes" ]; then ##__WITH_PARANOIA_DEBUG
_PerfProfiler ##__WITH_PARANOIA_DEBUG
fi ##__WITH_PARANOIA_DEBUG
done done
Logger "${FUNCNAME[0]} ended for [$callerName] using [$pidCount] subprocesses with [$errorcount] errors." "PARANOIA_DEBUG" #__WITH_PARANOIA_DEBUG Logger "${FUNCNAME[0]} ended for [$callerName] using [$pidCount] subprocesses with [$errorcount] errors." "PARANOIA_DEBUG" #__WITH_PARANOIA_DEBUG
@@ -947,6 +993,10 @@ function ParallelExec {
# Trivial wait time for bash to not eat up all CPU # Trivial wait time for bash to not eat up all CPU
sleep $sleepTime sleep $sleepTime
if [ "$_PERF_PROFILER" == "yes" ]; then ##__WITH_PARANOIA_DEBUG
_PerfProfiler ##__WITH_PARANOIA_DEBUG
fi ##__WITH_PARANOIA_DEBUG
done done
return $errorCount return $errorCount
@@ -1100,6 +1150,8 @@ function ArrayContains () {
function GetLocalOS { function GetLocalOS {
local localOsVar local localOsVar
local localOsName
local localOsVer
# There's no good way to tell if currently running in BusyBox shell. Using sluggish way. # There's no good way to tell if currently running in BusyBox shell. Using sluggish way.
if ls --help 2>&1 | grep -i "BusyBox" > /dev/null; then if ls --help 2>&1 | grep -i "BusyBox" > /dev/null; then
@@ -1130,7 +1182,7 @@ function GetLocalOS {
*"BSD"*) *"BSD"*)
LOCAL_OS="BSD" LOCAL_OS="BSD"
;; ;;
*"MINGW32"*|*"MSYS"*) *"MINGW32"*|*"MINGW64"*|*"MSYS"*)
LOCAL_OS="msys" LOCAL_OS="msys"
;; ;;
*"CYGWIN"*) *"CYGWIN"*)
@@ -1156,14 +1208,77 @@ function GetLocalOS {
exit 1 exit 1
;; ;;
esac esac
if [ "$_OFUNCTIONS_VERSION" != "" ]; then
Logger "Local OS: [$localOsVar]." "DEBUG" # Get linux versions
if [ -f "/etc/os-release" ]; then
localOsName=$(GetConfFileValue "/etc/os-release" "NAME")
localOsVer=$(GetConfFileValue "/etc/os-release" "VERSION")
fi fi
# Add a global variable for statistics in installer # Add a global variable for statistics in installer
LOCAL_OS_FULL="$localOsVar" LOCAL_OS_FULL="$localOsVar ($localOsName $localOsVer)"
if [ "$_OFUNCTIONS_VERSION" != "" ]; then
Logger "Local OS: [$LOCAL_OS_FULL]." "DEBUG"
fi
} }
#__BEGIN_WITH_PARANOIA_DEBUG
function __CheckArguments {
# Checks the number of arguments of a function and raises an error if some are missing
if [ "$_DEBUG" == "yes" ]; then
local numberOfArguments="${1}" # Number of arguments the tested function should have, can be a number of a range, eg 0-2 for zero to two arguments
local numberOfGivenArguments="${2}" # Number of arguments that have been passed
local minArgs
local maxArgs
# All arguments of the function to check are passed as array in ${3} (the function call waits for $@)
# If any of the arguments contains spaces, bash things there are two aguments
# In order to avoid this, we need to iterate over ${3} and count
callerName="${FUNCNAME[1]}"
local iterate=3
local fetchArguments=true
local argList=""
local countedArguments
while [ $fetchArguments == true ]; do
cmd='argument=${'$iterate'}'
eval $cmd
if [ "$argument" == "" ]; then
fetchArguments=false
else
argList="$argList[Argument $((iterate-2)): $argument] "
iterate=$((iterate+1))
fi
done
countedArguments=$((iterate-3))
if [ $(IsInteger "$numberOfArguments") -eq 1 ]; then
minArgs=$numberOfArguments
maxArgs=$numberOfArguments
else
IFS='-' read minArgs maxArgs <<< "$numberOfArguments"
fi
Logger "Entering function [$callerName]." "PARANOIA_DEBUG"
if ! ([ $countedArguments -ge $minArgs ] && [ $countedArguments -le $maxArgs ]); then
Logger "Function $callerName may have inconsistent number of arguments. Expected min: $minArgs, max: $maxArgs, count: $countedArguments, bash seen: $numberOfGivenArguments." "ERROR"
Logger "$callerName arguments: $argList" "ERROR"
else
if [ ! -z "$argList" ]; then
Logger "$callerName arguments: $argList" "PARANOIA_DEBUG"
fi
fi
fi
}
#__END_WITH_PARANOIA_DEBUG
function GetRemoteOS { function GetRemoteOS {
__CheckArguments 0 $# "$@" #__WITH_PARANOIA_DEBUG __CheckArguments 0 $# "$@" #__WITH_PARANOIA_DEBUG
@@ -1174,10 +1289,15 @@ function GetRemoteOS {
local remoteOsVar local remoteOsVar
$SSH_CMD bash -s << 'ENDSSH' >> "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP" 2>&1 $SSH_CMD env LC_ALL=C env _REMOTE_TOKEN="$_REMOTE_TOKEN" bash -s << 'ENDSSH' >> "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP" 2>&1
function GetOs { function GetOs {
local localOsVar local localOsVar
local localOsName
local localOsVer
local osInfo="/etc/os-release"
# There's no good way to tell if currently running in BusyBox shell. Using sluggish way. # There's no good way to tell if currently running in BusyBox shell. Using sluggish way.
if ls --help 2>&1 | grep -i "BusyBox" > /dev/null; then if ls --help 2>&1 | grep -i "BusyBox" > /dev/null; then
@@ -1196,7 +1316,15 @@ function GetOs {
fi fi
fi fi
fi fi
echo "$localOsVar" # Get linux versions
if [ -f "$osInfo" ]; then
localOsName=$(grep "^NAME=" "$osInfo")
localOsName="${localOsName##*=}"
localOsVer=$(grep "^VERSION=" "$osInfo")
localOsVer="${localOsVer##*=}"
fi
echo "$localOsVar ($localOsName $localOsVer)"
} }
GetOs GetOs
@@ -1215,7 +1343,7 @@ ENDSSH
*"BSD"*) *"BSD"*)
REMOTE_OS="BSD" REMOTE_OS="BSD"
;; ;;
*"MINGW32"*|*"MSYS"*) *"MINGW32"*|*"MINGW64"*|*"MSYS"*)
REMOTE_OS="msys" REMOTE_OS="msys"
;; ;;
*"CYGWIN"*) *"CYGWIN"*)
@@ -1286,6 +1414,12 @@ function RunRemoteCommand {
local hardMaxTime="${2}" # Max time to wait for command to compleet local hardMaxTime="${2}" # Max time to wait for command to compleet
__CheckArguments 2 $# "$@" #__WITH_PARANOIA_DEBUG __CheckArguments 2 $# "$@" #__WITH_PARANOIA_DEBUG
if [ "$REMOTE_OPERATION" != "yes" ]; then
Logger "Ignoring remote command [$command] because remote host is not configured." "WARN"
return 0
fi
CheckConnectivity3rdPartyHosts CheckConnectivity3rdPartyHosts
CheckConnectivityRemoteHost CheckConnectivityRemoteHost
if [ $_DRYRUN == true ]; then if [ $_DRYRUN == true ]; then
@@ -1294,7 +1428,7 @@ function RunRemoteCommand {
fi fi
Logger "Running command [$command] on remote host." "NOTICE" Logger "Running command [$command] on remote host." "NOTICE"
cmd=$SSH_CMD' "$command" > "'$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP'" 2>&1' cmd=$SSH_CMD' "env LC_ALL=C env _REMOTE_TOKEN="'$_REMOTE_TOKEN'" $command" > "'$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP'" 2>&1'
Logger "cmd: $cmd" "DEBUG" Logger "cmd: $cmd" "DEBUG"
eval "$cmd" & eval "$cmd" &
WaitForTaskCompletion $! 0 $hardMaxTime $SLEEP_TIME $KEEP_LOGGING true true false WaitForTaskCompletion $! 0 $hardMaxTime $SLEEP_TIME $KEEP_LOGGING true true false
@@ -1405,62 +1539,6 @@ function CheckConnectivity3rdPartyHosts {
fi #__WITH_PARANOIA_DEBUG fi #__WITH_PARANOIA_DEBUG
} }
#__BEGIN_WITH_PARANOIA_DEBUG
function __CheckArguments {
# Checks the number of arguments of a function and raises an error if some are missing
if [ "$_DEBUG" == "yes" ]; then
local numberOfArguments="${1}" # Number of arguments the tested function should have, can be a number of a range, eg 0-2 for zero to two arguments
local numberOfGivenArguments="${2}" # Number of arguments that have been passed
local minArgs
local maxArgs
# All arguments of the function to check are passed as array in ${3} (the function call waits for $@)
# If any of the arguments contains spaces, bash things there are two aguments
# In order to avoid this, we need to iterate over ${3} and count
callerName="${FUNCNAME[1]}"
local iterate=3
local fetchArguments=true
local argList=""
local countedArguments
while [ $fetchArguments == true ]; do
cmd='argument=${'$iterate'}'
eval $cmd
if [ "$argument" == "" ]; then
fetchArguments=false
else
argList="$argList[Argument $((iterate-2)): $argument] "
iterate=$((iterate+1))
fi
done
countedArguments=$((iterate-3))
if [ $(IsInteger "$numberOfArguments") -eq 1 ]; then
minArgs=$numberOfArguments
maxArgs=$numberOfArguments
else
IFS='-' read minArgs maxArgs <<< "$numberOfArguments"
fi
Logger "Entering function [$callerName]." "PARANOIA_DEBUG"
if ! ([ $countedArguments -ge $minArgs ] && [ $countedArguments -le $maxArgs ]); then
Logger "Function $callerName may have inconsistent number of arguments. Expected min: $minArgs, max: $maxArgs, count: $countedArguments, bash seen: $numberOfGivenArguments." "ERROR"
Logger "$callerName arguments: $argList" "ERROR"
else
if [ ! -z "$argList" ]; then
Logger "$callerName arguments: $argList" "PARANOIA_DEBUG"
fi
fi
fi
}
#__END_WITH_PARANOIA_DEBUG
function RsyncPatternsAdd { function RsyncPatternsAdd {
local patternType="${1}" # exclude or include local patternType="${1}" # exclude or include
local pattern="${2}" local pattern="${2}"
@@ -1591,13 +1669,13 @@ function PostInit {
# Define remote commands # Define remote commands
if [ -f "$SSH_RSA_PRIVATE_KEY" ]; then if [ -f "$SSH_RSA_PRIVATE_KEY" ]; then
SSH_CMD="$(type -p ssh) $SSH_COMP -i $SSH_RSA_PRIVATE_KEY $SSH_OPTS $REMOTE_USER@$REMOTE_HOST -p $REMOTE_PORT" SSH_CMD="$(type -p ssh) $SSH_COMP -q -i $SSH_RSA_PRIVATE_KEY $SSH_OPTS $REMOTE_USER@$REMOTE_HOST -p $REMOTE_PORT"
SCP_CMD="$(type -p scp) $SSH_COMP -i $SSH_RSA_PRIVATE_KEY -P $REMOTE_PORT" SCP_CMD="$(type -p scp) $SSH_COMP -q -i $SSH_RSA_PRIVATE_KEY -P $REMOTE_PORT"
RSYNC_SSH_CMD="$(type -p ssh) $SSH_COMP -i $SSH_RSA_PRIVATE_KEY $SSH_OPTS -p $REMOTE_PORT" RSYNC_SSH_CMD="$(type -p ssh) $SSH_COMP -q -i $SSH_RSA_PRIVATE_KEY $SSH_OPTS -p $REMOTE_PORT"
elif [ -f "$SSH_PASSWORD_FILE" ]; then elif [ -f "$SSH_PASSWORD_FILE" ]; then
SSH_CMD="$(type -p sshpass) -f $SSH_PASSWORD_FILE $(type -p ssh) $SSH_COMP $SSH_OPTS $REMOTE_USER@$REMOTE_HOST -p $REMOTE_PORT" SSH_CMD="$(type -p sshpass) -f $SSH_PASSWORD_FILE $(type -p ssh) $SSH_COMP -q $SSH_OPTS $REMOTE_USER@$REMOTE_HOST -p $REMOTE_PORT"
SCP_CMD="$(type -p sshpass) -f $SSH_PASSWORD_FILE $(type -p scp) $SSH_COMP -P $REMOTE_PORT" SCP_CMD="$(type -p sshpass) -f $SSH_PASSWORD_FILE $(type -p scp) $SSH_COMP -q -P $REMOTE_PORT"
RSYNC_SSH_CMD="$(type -p sshpass) -f $SSH_PASSWORD_FILE $(type -p ssh) $SSH_COMP $SSH_OPTS -p $REMOTE_PORT" RSYNC_SSH_CMD="$(type -p sshpass) -f $SSH_PASSWORD_FILE $(type -p ssh) $SSH_COMP -q $SSH_OPTS -p $REMOTE_PORT"
else else
SSH_PASSWORD="" SSH_PASSWORD=""
SSH_CMD="" SSH_CMD=""
@@ -1647,7 +1725,10 @@ function SetCompression {
COMPRESSION_EXTENSION= COMPRESSION_EXTENSION=
fi fi
fi fi
ALERT_LOG_FILE="$ALERT_LOG_FILE$COMPRESSION_EXTENSION"
if [ ".${ALERT_LOG_FILE##*.}" != "$COMPRESSION_EXTENSION" ]; then
ALERT_LOG_FILE="$ALERT_LOG_FILE$COMPRESSION_EXTENSION"
fi
} }
function InitLocalOSDependingSettings { function InitLocalOSDependingSettings {
@@ -1660,6 +1741,11 @@ function InitLocalOSDependingSettings {
if [ "$LOCAL_OS" == "msys" ] || [ "$LOCAL_OS" == "Cygwin" ]; then if [ "$LOCAL_OS" == "msys" ] || [ "$LOCAL_OS" == "Cygwin" ]; then
FIND_CMD=$(dirname $BASH)/find FIND_CMD=$(dirname $BASH)/find
PING_CMD='$SYSTEMROOT\system32\ping -n 2' PING_CMD='$SYSTEMROOT\system32\ping -n 2'
# On BSD, when not root, min ping interval is 1s
elif [ "$LOCAL_OS" == "BSD" ] && [ "$LOCAL_USER" != "root" ]; then
FIND_CMD=find
PING_CMD="ping -c 2 -i 1"
else else
FIND_CMD=find FIND_CMD=find
PING_CMD="ping -c 2 -i .2" PING_CMD="ping -c 2 -i .2"
@@ -1709,7 +1795,7 @@ function InitRemoteOSDependingSettings {
fi fi
## Set rsync default arguments ## Set rsync default arguments
RSYNC_ARGS="-rltD" RSYNC_ARGS="-rltD -8"
if [ "$_DRYRUN" == true ]; then if [ "$_DRYRUN" == true ]; then
RSYNC_DRY_ARG="-n" RSYNC_DRY_ARG="-n"
DRY_WARNING="/!\ DRY RUN " DRY_WARNING="/!\ DRY RUN "
@@ -1804,6 +1890,102 @@ function ParentPid {
fi fi
} }
# Neat version compare function found at http://stackoverflow.com/a/4025065/2635443
# Returns 0 if equal, 1 if $1 > $2 and 2 if $1 < $2
function VerComp () {
if [ "$1" == "" ] || [ "$2" == "" ]; then
Logger "Bogus Vercomp values [$1] and [$2]." "WARN"
return 1
fi
if [[ $1 == $2 ]]
then
echo 0
return
fi
local IFS=.
local i ver1=($1) ver2=($2)
# fill empty fields in ver1 with zeros
for ((i=${#ver1[@]}; i<${#ver2[@]}; i++))
do
ver1[i]=0
done
for ((i=0; i<${#ver1[@]}; i++))
do
if [[ -z ${ver2[i]} ]]
then
# fill empty fields in ver2 with zeros
ver2[i]=0
fi
if ((10#${ver1[i]} > 10#${ver2[i]}))
then
echo 1
return
fi
if ((10#${ver1[i]} < 10#${ver2[i]}))
then
echo 2
return
fi
done
echo 0
return
}
function GetConfFileValue () {
local file="${1}"
local name="${2}"
local value
value=$(grep "^$name=" "$file")
if [ $? == 0 ]; then
value="${value##*=}"
echo "$value"
else
Logger "Cannot get value for [$name] in config file [$file]." "ERROR"
fi
}
function SetConfFileValue () {
local file="${1}"
local name="${2}"
local value="${3}"
local separator="${4:-#}"
if grep "^$name=" "$file" > /dev/null; then
# Using -i.tmp for BSD compat
sed -i.tmp "s$separator^$name=.*$separator$name=$value$separator" "$file"
rm -f "$file.tmp"
Logger "Set [$name] to [$value] in config file [$file]." "DEBUG"
else
Logger "Cannot set value [$name] to [$value] in config file [$file]." "ERROR"
fi
}
# Function can replace [ -f /some/file* ] tests
# Modified version of http://stackoverflow.com/a/6364244/2635443
function WildcardFileExists () {
local file="${1}"
local exists=0
for f in $file; do
## Check if the glob gets expanded to existing files.
## If not, f here will be exactly the pattern above
## and the exists test will evaluate to false.
if [ -e "$f" ]; then
exists=1
break
fi
done
if [ $exists -eq 1 ]; then
echo 1
else
echo 0
fi
}
# If using "include" statements, make sure the script does not get executed unless it's loaded by bootstrap # If using "include" statements, make sure the script does not get executed unless it's loaded by bootstrap
_OFUNCTIONS_BOOTSTRAP=true _OFUNCTIONS_BOOTSTRAP=true
@@ -1913,6 +2095,11 @@ function CheckEnvironment {
if [ "$ENCRYPTION" == "yes" ]; then if [ "$ENCRYPTION" == "yes" ]; then
CheckCryptEnvironnment CheckCryptEnvironnment
fi fi
if ! type pgrep > /dev/null 2>&1 ; then
Logger "pgrep not present. $0 cannot start." "CRITICAL"
exit 1
fi
} }
function CheckCryptEnvironnment { function CheckCryptEnvironnment {
@@ -2030,7 +2217,7 @@ function _ListDatabasesLocal {
Logger "Listing databases succeeded." "NOTICE" Logger "Listing databases succeeded." "NOTICE"
else else
Logger "Listing databases failed." "ERROR" Logger "Listing databases failed." "ERROR"
Logger "Command was [$sqlCmd]." "WARN" _LOGGER_SILENT=true Logger "Command was [$sqlCmd]." "WARN"
if [ -f "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP" ]; then if [ -f "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP" ]; then
Logger "Command output:\n$(cat $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP)" "ERROR" Logger "Command output:\n$(cat $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP)" "ERROR"
fi fi
@@ -2047,7 +2234,7 @@ function _ListDatabasesRemote {
CheckConnectivity3rdPartyHosts CheckConnectivity3rdPartyHosts
CheckConnectivityRemoteHost CheckConnectivityRemoteHost
sqlCmd="$SSH_CMD \"mysql -u $SQL_USER -Bse 'SELECT table_schema, round(sum( data_length + index_length ) / 1024) FROM information_schema.TABLES GROUP by table_schema;'\" > \"$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP\" 2>&1" sqlCmd="$SSH_CMD \"env _REMOTE_TOKEN=$_REMOTE_TOKEN mysql -u $SQL_USER -Bse 'SELECT table_schema, round(sum( data_length + index_length ) / 1024) FROM information_schema.TABLES GROUP by table_schema;'\" > \"$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP\" 2>&1"
Logger "Command output: $sqlCmd" "DEBUG" Logger "Command output: $sqlCmd" "DEBUG"
eval "$sqlCmd" & eval "$sqlCmd" &
WaitForTaskCompletion $! $SOFT_MAX_EXEC_TIME_DB_TASK $HARD_MAX_EXEC_TIME_DB_TASK $SLEEP_TIME $KEEP_LOGGING true true false WaitForTaskCompletion $! $SOFT_MAX_EXEC_TIME_DB_TASK $HARD_MAX_EXEC_TIME_DB_TASK $SLEEP_TIME $KEEP_LOGGING true true false
@@ -2172,7 +2359,7 @@ function _ListRecursiveBackupDirectoriesLocal {
retval=$? retval=$?
if [ $retval -ne 0 ]; then if [ $retval -ne 0 ]; then
Logger "Could not enumerate directories in [$directory]." "ERROR" Logger "Could not enumerate directories in [$directory]." "ERROR"
Logger "Command was [$cmd]." "Warn" _LOGGER_SILENT=true Logger "Command was [$cmd]." "WARN"
if [ -f $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP ]; then if [ -f $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP ]; then
Logger "Command output:\n$(cat $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP)" "ERROR" Logger "Command output:\n$(cat $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP)" "ERROR"
fi fi
@@ -2198,7 +2385,8 @@ function _ListRecursiveBackupDirectoriesRemote {
local retval local retval
$SSH_CMD env _DEBUG="'$_DEBUG'" env _PARANOIA_DEBUG="'$_PARANOIA_DEBUG'" env _LOGGER_SILENT="'$_LOGGER_SILENT'" env _LOGGER_VERBOSE="'$_LOGGER_VERBOSE'" env _LOGGER_PREFIX="'$_LOGGER_PREFIX'" env _LOGGER_ERR_ONLY="'$_LOGGER_ERR_ONLY'" \ $SSH_CMD env _REMOTE_TOKEN=$_REMOTE_TOKEN \
env _DEBUG="'$_DEBUG'" env _PARANOIA_DEBUG="'$_PARANOIA_DEBUG'" env _LOGGER_SILENT="'$_LOGGER_SILENT'" env _LOGGER_VERBOSE="'$_LOGGER_VERBOSE'" env _LOGGER_PREFIX="'$_LOGGER_PREFIX'" env _LOGGER_ERR_ONLY="'$_LOGGER_ERR_ONLY'" \
env PROGRAM="'$PROGRAM'" env SCRIPT_PID="'$SCRIPT_PID'" TSTAMP="'$TSTAMP'" \ env PROGRAM="'$PROGRAM'" env SCRIPT_PID="'$SCRIPT_PID'" TSTAMP="'$TSTAMP'" \
env RECURSIVE_DIRECTORY_LIST="'$RECURSIVE_DIRECTORY_LIST'" env PATH_SEPARATOR_CHAR="'$PATH_SEPARATOR_CHAR'" \ env RECURSIVE_DIRECTORY_LIST="'$RECURSIVE_DIRECTORY_LIST'" env PATH_SEPARATOR_CHAR="'$PATH_SEPARATOR_CHAR'" \
env REMOTE_FIND_CMD="'$REMOTE_FIND_CMD'" $COMMAND_SUDO' bash -s' << 'ENDSSH' > "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP" 2> "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP" env REMOTE_FIND_CMD="'$REMOTE_FIND_CMD'" $COMMAND_SUDO' bash -s' << 'ENDSSH' > "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP" 2> "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP"
@@ -2239,7 +2427,7 @@ function joinString {
function _Logger { function _Logger {
local logValue="${1}" # Log to file local logValue="${1}" # Log to file
local stdValue="${2}" # Log to screeen local stdValue="${2}" # Log to screeen
local toStderr="${3:-false}" # Log to stderr instead of stdout local toStdErr="${3:-false}" # Log to stderr instead of stdout
if [ "$logValue" != "" ]; then if [ "$logValue" != "" ]; then
echo -e "$logValue" >> "$LOG_FILE" echo -e "$logValue" >> "$LOG_FILE"
@@ -2248,7 +2436,7 @@ function _Logger {
fi fi
if [ "$stdValue" != "" ] && [ "$_LOGGER_SILENT" != true ]; then if [ "$stdValue" != "" ] && [ "$_LOGGER_SILENT" != true ]; then
if [ $toStderr == true ]; then if [ $toStdErr == true ]; then
# Force stderr color in subshell # Force stderr color in subshell
(>&2 echo -e "$stdValue") (>&2 echo -e "$stdValue")
@@ -2455,14 +2643,14 @@ function _GetDirectoriesSizeLocal {
retval=$? retval=$?
if [ $retval -ne 0 ] || [ -s $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP ]; then if [ $retval -ne 0 ] || [ -s $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP ]; then
Logger "Could not get files size for some or all local directories." "ERROR" Logger "Could not get files size for some or all local directories." "ERROR"
Logger "Command was [$cmd]." "WARN" _LOGGER_SILENT=true Logger "Command was [$cmd]." "WARN"
if [ -f "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP" ]; then if [ -f "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP" ]; then
Logger "Command output:\n$(cat $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP)" "ERROR" Logger "Command output:\n$(cat $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP)" "ERROR"
fi fi
if [ -f "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP" ]; then if [ -f "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP" ]; then
Logger "Error output:\n$(cat $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP)" "ERROR" Logger "Error output:\n$(cat $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP)" "ERROR"
fi fi
elsew else
Logger "File size fetched successfully." "NOTICE" Logger "File size fetched successfully." "NOTICE"
fi fi
@@ -2484,7 +2672,8 @@ function _GetDirectoriesSizeRemote {
local retval local retval
# Error output is different from stdout because not all files in list may fail at once # Error output is different from stdout because not all files in list may fail at once
$SSH_CMD env _DEBUG="'$_DEBUG'" env _PARANOIA_DEBUG="'$_PARANOIA_DEBUG'" env _LOGGER_SILENT="'$_LOGGER_SILENT'" env _LOGGER_VERBOSE="'$_LOGGER_VERBOSE'" env _LOGGER_PREFIX="'$_LOGGER_PREFIX'" env _LOGGER_ERR_ONLY="'$_LOGGER_ERR_ONLY'" \ $SSH_CMD env _REMOTE_TOKEN=$_REMOTE_TOKEN \
env _DEBUG="'$_DEBUG'" env _PARANOIA_DEBUG="'$_PARANOIA_DEBUG'" env _LOGGER_SILENT="'$_LOGGER_SILENT'" env _LOGGER_VERBOSE="'$_LOGGER_VERBOSE'" env _LOGGER_PREFIX="'$_LOGGER_PREFIX'" env _LOGGER_ERR_ONLY="'$_LOGGER_ERR_ONLY'" \
env PROGRAM="'$PROGRAM'" env SCRIPT_PID="'$SCRIPT_PID'" TSTAMP="'$TSTAMP'" dirList="'$dirList'" \ env PROGRAM="'$PROGRAM'" env SCRIPT_PID="'$SCRIPT_PID'" TSTAMP="'$TSTAMP'" dirList="'$dirList'" \
$COMMAND_SUDO' bash -s' << 'ENDSSH' > "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP" 2> "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP" & $COMMAND_SUDO' bash -s' << 'ENDSSH' > "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP" 2> "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP" &
## allow function call checks #__WITH_PARANOIA_DEBUG ## allow function call checks #__WITH_PARANOIA_DEBUG
@@ -2524,7 +2713,7 @@ function joinString {
function _Logger { function _Logger {
local logValue="${1}" # Log to file local logValue="${1}" # Log to file
local stdValue="${2}" # Log to screeen local stdValue="${2}" # Log to screeen
local toStderr="${3:-false}" # Log to stderr instead of stdout local toStdErr="${3:-false}" # Log to stderr instead of stdout
if [ "$logValue" != "" ]; then if [ "$logValue" != "" ]; then
echo -e "$logValue" >> "$LOG_FILE" echo -e "$logValue" >> "$LOG_FILE"
@@ -2533,7 +2722,7 @@ function _Logger {
fi fi
if [ "$stdValue" != "" ] && [ "$_LOGGER_SILENT" != true ]; then if [ "$stdValue" != "" ] && [ "$_LOGGER_SILENT" != true ]; then
if [ $toStderr == true ]; then if [ $toStdErr == true ]; then
# Force stderr color in subshell # Force stderr color in subshell
(>&2 echo -e "$stdValue") (>&2 echo -e "$stdValue")
@@ -2683,7 +2872,8 @@ function _CreateDirectoryRemote {
CheckConnectivity3rdPartyHosts CheckConnectivity3rdPartyHosts
CheckConnectivityRemoteHost CheckConnectivityRemoteHost
$SSH_CMD env _DEBUG="'$_DEBUG'" env _PARANOIA_DEBUG="'$_PARANOIA_DEBUG'" env _LOGGER_SILENT="'$_LOGGER_SILENT'" env _LOGGER_VERBOSE="'$_LOGGER_VERBOSE'" env _LOGGER_PREFIX="'$_LOGGER_PREFIX'" env _LOGGER_ERR_ONLY="'$_LOGGER_ERR_ONLY'" \ $SSH_CMD env _REMOTE_TOKEN=$_REMOTE_TOKEN \
env _DEBUG="'$_DEBUG'" env _PARANOIA_DEBUG="'$_PARANOIA_DEBUG'" env _LOGGER_SILENT="'$_LOGGER_SILENT'" env _LOGGER_VERBOSE="'$_LOGGER_VERBOSE'" env _LOGGER_PREFIX="'$_LOGGER_PREFIX'" env _LOGGER_ERR_ONLY="'$_LOGGER_ERR_ONLY'" \
env PROGRAM="'$PROGRAM'" env SCRIPT_PID="'$SCRIPT_PID'" TSTAMP="'$TSTAMP'" \ env PROGRAM="'$PROGRAM'" env SCRIPT_PID="'$SCRIPT_PID'" TSTAMP="'$TSTAMP'" \
env dirToCreate="'$dirToCreate'" $COMMAND_SUDO' bash -s' << 'ENDSSH' > "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP" 2>&1 & env dirToCreate="'$dirToCreate'" $COMMAND_SUDO' bash -s' << 'ENDSSH' > "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP" 2>&1 &
## allow function call checks #__WITH_PARANOIA_DEBUG ## allow function call checks #__WITH_PARANOIA_DEBUG
@@ -2723,7 +2913,7 @@ function joinString {
function _Logger { function _Logger {
local logValue="${1}" # Log to file local logValue="${1}" # Log to file
local stdValue="${2}" # Log to screeen local stdValue="${2}" # Log to screeen
local toStderr="${3:-false}" # Log to stderr instead of stdout local toStdErr="${3:-false}" # Log to stderr instead of stdout
if [ "$logValue" != "" ]; then if [ "$logValue" != "" ]; then
echo -e "$logValue" >> "$LOG_FILE" echo -e "$logValue" >> "$LOG_FILE"
@@ -2732,7 +2922,7 @@ function _Logger {
fi fi
if [ "$stdValue" != "" ] && [ "$_LOGGER_SILENT" != true ]; then if [ "$stdValue" != "" ] && [ "$_LOGGER_SILENT" != true ]; then
if [ $toStderr == true ]; then if [ $toStdErr == true ]; then
# Force stderr color in subshell # Force stderr color in subshell
(>&2 echo -e "$stdValue") (>&2 echo -e "$stdValue")
@@ -2906,7 +3096,8 @@ function GetDiskSpaceRemote {
local cmd local cmd
local retval local retval
$SSH_CMD env _DEBUG="'$_DEBUG'" env _PARANOIA_DEBUG="'$_PARANOIA_DEBUG'" env _LOGGER_SILENT="'$_LOGGER_SILENT'" env _LOGGER_VERBOSE="'$_LOGGER_VERBOSE'" env _LOGGER_PREFIX="'$_LOGGER_PREFIX'" env _LOGGER_ERR_ONLY="'$_LOGGER_ERR_ONLY'" \ $SSH_CMD env _REMOTE_TOKEN=$_REMOTE_TOKEN \
env _DEBUG="'$_DEBUG'" env _PARANOIA_DEBUG="'$_PARANOIA_DEBUG'" env _LOGGER_SILENT="'$_LOGGER_SILENT'" env _LOGGER_VERBOSE="'$_LOGGER_VERBOSE'" env _LOGGER_PREFIX="'$_LOGGER_PREFIX'" env _LOGGER_ERR_ONLY="'$_LOGGER_ERR_ONLY'" \
env PROGRAM="'$PROGRAM'" env SCRIPT_PID="'$SCRIPT_PID'" TSTAMP="'$TSTAMP'" \ env PROGRAM="'$PROGRAM'" env SCRIPT_PID="'$SCRIPT_PID'" TSTAMP="'$TSTAMP'" \
env DF_CMD="'$DF_CMD'" \ env DF_CMD="'$DF_CMD'" \
env pathToCheck="'$pathToCheck'" $COMMAND_SUDO' bash -s' << 'ENDSSH' > "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP" 2> "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP" & env pathToCheck="'$pathToCheck'" $COMMAND_SUDO' bash -s' << 'ENDSSH' > "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP" 2> "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP" &
@@ -2947,7 +3138,7 @@ function joinString {
function _Logger { function _Logger {
local logValue="${1}" # Log to file local logValue="${1}" # Log to file
local stdValue="${2}" # Log to screeen local stdValue="${2}" # Log to screeen
local toStderr="${3:-false}" # Log to stderr instead of stdout local toStdErr="${3:-false}" # Log to stderr instead of stdout
if [ "$logValue" != "" ]; then if [ "$logValue" != "" ]; then
echo -e "$logValue" >> "$LOG_FILE" echo -e "$logValue" >> "$LOG_FILE"
@@ -2956,7 +3147,7 @@ function _Logger {
fi fi
if [ "$stdValue" != "" ] && [ "$_LOGGER_SILENT" != true ]; then if [ "$stdValue" != "" ] && [ "$_LOGGER_SILENT" != true ]; then
if [ $toStderr == true ]; then if [ $toStdErr == true ]; then
# Force stderr color in subshell # Force stderr color in subshell
(>&2 echo -e "$stdValue") (>&2 echo -e "$stdValue")
@@ -3233,10 +3424,10 @@ function _BackupDatabaseLocalToLocal {
retval=$? retval=$?
if [ -s "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP" ]; then if [ -s "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP" ]; then
if [ $_DRYRUN == false ]; then if [ $_DRYRUN == false ]; then
Logger "Command was [$sqlCmd]." "WARN" _LOGGER_SILENT=true Logger "Command was [$sqlCmd]." "WARN"
eval "$sqlCmd" & eval "$sqlCmd" &
else else
Logger "Command was [$drySqlCmd]." "WARN" _LOGGER_SILENT=true Logger "Command was [$drySqlCmd]." "WARN"
eval "$drySqlCmd" & eval "$drySqlCmd" &
fi fi
Logger "Error output:\n$(cat $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP)" "ERROR" Logger "Error output:\n$(cat $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP)" "ERROR"
@@ -3269,7 +3460,7 @@ function _BackupDatabaseLocalToRemote {
fi fi
local drySqlCmd="mysqldump -u $SQL_USER $exportOptions --databases $database $COMPRESSION_PROGRAM $COMPRESSION_OPTIONS $encryptOptions > /dev/null 2> $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP" local drySqlCmd="mysqldump -u $SQL_USER $exportOptions --databases $database $COMPRESSION_PROGRAM $COMPRESSION_OPTIONS $encryptOptions > /dev/null 2> $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP"
local sqlCmd="mysqldump -u $SQL_USER $exportOptions --databases $database $COMPRESSION_PROGRAM $COMPRESSION_OPTIONS $encryptOptions | $SSH_CMD '$COMMAND_SUDO tee \"$SQL_STORAGE/$database.sql$COMPRESSION_EXTENSION$encryptExtension\" > /dev/null' 2> $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP" local sqlCmd="mysqldump -u $SQL_USER $exportOptions --databases $database $COMPRESSION_PROGRAM $COMPRESSION_OPTIONS $encryptOptions | $SSH_CMD 'env _REMOTE_TOKEN=$_REMOTE_TOKEN $COMMAND_SUDO tee \"$SQL_STORAGE/$database.sql$COMPRESSION_EXTENSION$encryptExtension\" > /dev/null' 2> $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP"
if [ $_DRYRUN == false ]; then if [ $_DRYRUN == false ]; then
Logger "Launching command [$sqlCmd]." "DEBUG" Logger "Launching command [$sqlCmd]." "DEBUG"
@@ -3282,10 +3473,10 @@ function _BackupDatabaseLocalToRemote {
retval=$? retval=$?
if [ -s "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP" ]; then if [ -s "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP" ]; then
if [ $_DRYRUN == false ]; then if [ $_DRYRUN == false ]; then
Logger "Command was [$sqlCmd]." "WARN" _LOGGER_SILENT=true Logger "Command was [$sqlCmd]." "WARN"
eval "$sqlCmd" & eval "$sqlCmd" &
else else
Logger "Command was [$drySqlCmd]." "WARN" _LOGGER_SILENT=true Logger "Command was [$drySqlCmd]." "WARN"
eval "$drySqlCmd" & eval "$drySqlCmd" &
fi fi
Logger "Error output:\n$(cat $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP)" "ERROR" Logger "Error output:\n$(cat $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP)" "ERROR"
@@ -3317,8 +3508,8 @@ function _BackupDatabaseRemoteToLocal {
encryptExtension="$CRYPT_FILE_EXTENSION" encryptExtension="$CRYPT_FILE_EXTENSION"
fi fi
local drySqlCmd=$SSH_CMD' "mysqldump -u '$SQL_USER' '$exportOptions' --databases '$database' '$COMPRESSION_PROGRAM' '$COMPRESSION_OPTIONS' '$encryptOptions'" > /dev/null 2> "'$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP'"' local drySqlCmd=$SSH_CMD' "env _REMOTE_TOKEN=$_REMOTE_TOKEN mysqldump -u '$SQL_USER' '$exportOptions' --databases '$database' '$COMPRESSION_PROGRAM' '$COMPRESSION_OPTIONS' '$encryptOptions'" > /dev/null 2> "'$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP'"'
local sqlCmd=$SSH_CMD' "mysqldump -u '$SQL_USER' '$exportOptions' --databases '$database' '$COMPRESSION_PROGRAM' '$COMPRESSION_OPTIONS' '$encryptOptions'" > "'$SQL_STORAGE/$database.sql$COMPRESSION_EXTENSION$encryptExtension'" 2> "'$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP'"' local sqlCmd=$SSH_CMD' "env _REMOTE_TOKEN=$_REMOTE_TOKEN mysqldump -u '$SQL_USER' '$exportOptions' --databases '$database' '$COMPRESSION_PROGRAM' '$COMPRESSION_OPTIONS' '$encryptOptions'" > "'$SQL_STORAGE/$database.sql$COMPRESSION_EXTENSION$encryptExtension'" 2> "'$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP'"'
if [ $_DRYRUN == false ]; then if [ $_DRYRUN == false ]; then
Logger "Launching command [$sqlCmd]." "DEBUG" Logger "Launching command [$sqlCmd]." "DEBUG"
@@ -3331,10 +3522,10 @@ function _BackupDatabaseRemoteToLocal {
retval=$? retval=$?
if [ -s "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP" ]; then if [ -s "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP" ]; then
if [ $_DRYRUN == false ]; then if [ $_DRYRUN == false ]; then
Logger "Command was [$sqlCmd]." "WARN" _LOGGER_SILENT=true Logger "Command was [$sqlCmd]." "WARN"
eval "$sqlCmd" & eval "$sqlCmd" &
else else
Logger "Command was [$drySqlCmd]." "WARN" _LOGGER_SILENT=true Logger "Command was [$drySqlCmd]." "WARN"
eval "$drySqlCmd" & eval "$drySqlCmd" &
fi fi
Logger "Error output:\n$(cat $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP)" "ERROR" Logger "Error output:\n$(cat $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP)" "ERROR"
@@ -3474,7 +3665,7 @@ function EncryptFiles {
ParallelExec $PARALLEL_ENCRYPTION_PROCESSES "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.parallel.$SCRIPT_PID.$TSTAMP" true $softMaxExecTime $hardMaxExecTime $SLEEP_TIME $KEEP_LOGGING true true false ParallelExec $PARALLEL_ENCRYPTION_PROCESSES "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.parallel.$SCRIPT_PID.$TSTAMP" true $softMaxExecTime $hardMaxExecTime $SLEEP_TIME $KEEP_LOGGING true true false
retval=$? retval=$?
if [ $retval -ne 0 ]; then if [ $retval -ne 0 ]; then
Logger "Encryption error.." "ERROR" Logger "Encryption error." "ERROR"
# Output file is defined in ParallelExec # Output file is defined in ParallelExec
Logger "Command output:\n$(cat $RUN_DIR/$PROGRAM.ParallelExec.EncryptFiles.$SCRIPT_PID.$TSTAMP)" "DEBUG" Logger "Command output:\n$(cat $RUN_DIR/$PROGRAM.ParallelExec.EncryptFiles.$SCRIPT_PID.$TSTAMP)" "DEBUG"
fi fi
@@ -3630,13 +3821,13 @@ function Rsync {
CheckConnectivity3rdPartyHosts CheckConnectivity3rdPartyHosts
CheckConnectivityRemoteHost CheckConnectivityRemoteHost
sourceDir=$(EscapeSpaces "$sourceDir") sourceDir=$(EscapeSpaces "$sourceDir")
rsyncCmd="$(type -p $RSYNC_EXECUTABLE) $RSYNC_ARGS $RSYNC_DRY_ARG $RSYNC_ATTR_ARGS $RSYNC_TYPE_ARGS $RSYNC_NO_RECURSE_ARGS $RSYNC_DELETE $RSYNC_PATTERNS $RSYNC_PARTIAL_EXCLUDE --rsync-path=\"$RSYNC_PATH\" -e \"$RSYNC_SSH_CMD\" \"$REMOTE_USER@$REMOTE_HOST:$sourceDir\" \"$destinationDir\" > $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP 2>&1" rsyncCmd="$(type -p $RSYNC_EXECUTABLE) $RSYNC_ARGS $RSYNC_DRY_ARG $RSYNC_ATTR_ARGS $RSYNC_TYPE_ARGS $RSYNC_NO_RECURSE_ARGS $RSYNC_DELETE $RSYNC_PATTERNS $RSYNC_PARTIAL_EXCLUDE --rsync-path=\"env _REMOTE_TOKEN=$_REMOTE_TOKEN $RSYNC_PATH\" -e \"$RSYNC_SSH_CMD\" \"$REMOTE_USER@$REMOTE_HOST:$sourceDir\" \"$destinationDir\" > $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP 2>&1"
elif [ "$BACKUP_TYPE" == "push" ]; then elif [ "$BACKUP_TYPE" == "push" ]; then
destinationDir=$(EscapeSpaces "$destinationDir") destinationDir=$(EscapeSpaces "$destinationDir")
_CreateDirectoryRemote "$destinationDir" _CreateDirectoryRemote "$destinationDir"
CheckConnectivity3rdPartyHosts CheckConnectivity3rdPartyHosts
CheckConnectivityRemoteHost CheckConnectivityRemoteHost
rsyncCmd="$(type -p $RSYNC_EXECUTABLE) $RSYNC_ARGS $RSYNC_DRY_ARG $RSYNC_ATTR_ARGS $RSYNC_TYPE_ARGS $RSYNC_NO_RECURSE_ARGS $RSYNC_DELETE $RSYNC_PATTERNS $RSYNC_PARTIAL_EXCLUDE --rsync-path=\"$RSYNC_PATH\" -e \"$RSYNC_SSH_CMD\" \"$sourceDir\" \"$REMOTE_USER@$REMOTE_HOST:$destinationDir\" > $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP 2>&1" rsyncCmd="$(type -p $RSYNC_EXECUTABLE) $RSYNC_ARGS $RSYNC_DRY_ARG $RSYNC_ATTR_ARGS $RSYNC_TYPE_ARGS $RSYNC_NO_RECURSE_ARGS $RSYNC_DELETE $RSYNC_PATTERNS $RSYNC_PARTIAL_EXCLUDE --rsync-path=\"env _REMOTE_TOKEN=$_REMOTE_TOKEN $RSYNC_PATH\" -e \"$RSYNC_SSH_CMD\" \"$sourceDir\" \"$REMOTE_USER@$REMOTE_HOST:$destinationDir\" > $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP 2>&1"
fi fi
Logger "Launching command [$rsyncCmd]." "DEBUG" Logger "Launching command [$rsyncCmd]." "DEBUG"
@@ -3645,7 +3836,7 @@ function Rsync {
retval=$? retval=$?
if [ $retval -ne 0 ]; then if [ $retval -ne 0 ]; then
Logger "Failed to backup [$sourceDir] to [$destinationDir]." "ERROR" Logger "Failed to backup [$sourceDir] to [$destinationDir]." "ERROR"
Logger "Command was [$rsyncCmd]." "WARN" _LOGGER_SILENT=true Logger "Command was [$rsyncCmd]." "WARN"
Logger "Command output:\n $(cat $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP)" "ERROR" Logger "Command output:\n $(cat $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP)" "ERROR"
else else
Logger "File backup succeed." "NOTICE" Logger "File backup succeed." "NOTICE"
@@ -3794,7 +3985,7 @@ function _RotateBackupsLocal {
WaitForTaskCompletion $! 3600 0 $SLEEP_TIME $KEEP_LOGGING true true false WaitForTaskCompletion $! 3600 0 $SLEEP_TIME $KEEP_LOGGING true true false
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
Logger "Cannot delete oldest copy [$path]." "ERROR" Logger "Cannot delete oldest copy [$path]." "ERROR"
Logger "Command was [$cmd]." "WARN" _LOGGER_SILENT=true Logger "Command was [$cmd]." "WARN"
fi fi
fi fi
fi fi
@@ -3807,7 +3998,7 @@ function _RotateBackupsLocal {
WaitForTaskCompletion $! 3600 0 $SLEEP_TIME $KEEP_LOGGING true true false WaitForTaskCompletion $! 3600 0 $SLEEP_TIME $KEEP_LOGGING true true false
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
Logger "Cannot move [$path] to [$backup.$PROGRAM.$copy]." "ERROR" Logger "Cannot move [$path] to [$backup.$PROGRAM.$copy]." "ERROR"
Logger "Command was [$cmd]." "WARN" _LOGGER_SILENT=true Logger "Command was [$cmd]." "WARN"
fi fi
fi fi
@@ -3822,7 +4013,7 @@ function _RotateBackupsLocal {
WaitForTaskCompletion $! 3600 0 $SLEEP_TIME $KEEP_LOGGING true true false WaitForTaskCompletion $! 3600 0 $SLEEP_TIME $KEEP_LOGGING true true false
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
Logger "Cannot move [$backup] to [$backup.$PROGRAM.1]." "ERROR" Logger "Cannot move [$backup] to [$backup.$PROGRAM.1]." "ERROR"
Logger "Command was [$cmd]." "WARN" _LOGGER_SILENT=true Logger "Command was [$cmd]." "WARN"
fi fi
elif [ "$REMOTE_OPERATION" == "yes" ]; then elif [ "$REMOTE_OPERATION" == "yes" ]; then
@@ -3832,7 +4023,7 @@ function _RotateBackupsLocal {
WaitForTaskCompletion $! 3600 0 $SLEEP_TIME $KEEP_LOGGING true true false WaitForTaskCompletion $! 3600 0 $SLEEP_TIME $KEEP_LOGGING true true false
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
Logger "Cannot copy [$backup] to [$backup.$PROGRAM.1]." "ERROR" Logger "Cannot copy [$backup] to [$backup.$PROGRAM.1]." "ERROR"
Logger "Command was [$cmd]." "WARN" _LOGGER_SILENT=true Logger "Command was [$cmd]." "WARN"
fi fi
else else
@@ -3842,7 +4033,7 @@ function _RotateBackupsLocal {
WaitForTaskCompletion $! 3600 0 $SLEEP_TIME $KEEP_LOGGING true true false WaitForTaskCompletion $! 3600 0 $SLEEP_TIME $KEEP_LOGGING true true false
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
Logger "Cannot move [$backup] to [$backup.$PROGRAM.1]." "ERROR" Logger "Cannot move [$backup] to [$backup.$PROGRAM.1]." "ERROR"
Logger "Command was [$cmd]." "WARN" _LOGGER_SILENT=true Logger "Command was [$cmd]." "WARN"
fi fi
fi fi
done done
@@ -3853,7 +4044,8 @@ function _RotateBackupsRemote {
local rotateCopies="${2}" local rotateCopies="${2}"
__CheckArguments 2 $# "$@" #__WITH_PARANOIA_DEBUG __CheckArguments 2 $# "$@" #__WITH_PARANOIA_DEBUG
$SSH_CMD env _DEBUG="'$_DEBUG'" env _PARANOIA_DEBUG="'$_PARANOIA_DEBUG'" env _LOGGER_SILENT="'$_LOGGER_SILENT'" env _LOGGER_VERBOSE="'$_LOGGER_VERBOSE'" env _LOGGER_PREFIX="'$_LOGGER_PREFIX'" env _LOGGER_ERR_ONLY="'$_LOGGER_ERR_ONLY'" \ $SSH_CMD env _REMOTE_TOKEN=$_REMOTE_TOKEN \
env _DEBUG="'$_DEBUG'" env _PARANOIA_DEBUG="'$_PARANOIA_DEBUG'" env _LOGGER_SILENT="'$_LOGGER_SILENT'" env _LOGGER_VERBOSE="'$_LOGGER_VERBOSE'" env _LOGGER_PREFIX="'$_LOGGER_PREFIX'" env _LOGGER_ERR_ONLY="'$_LOGGER_ERR_ONLY'" \
env PROGRAM="'$PROGRAM'" env SCRIPT_PID="'$SCRIPT_PID'" TSTAMP="'$TSTAMP'" \ env PROGRAM="'$PROGRAM'" env SCRIPT_PID="'$SCRIPT_PID'" TSTAMP="'$TSTAMP'" \
env REMOTE_FIND_CMD="'$REMOTE_FIND_CMD'" env rotateCopies="'$rotateCopies'" env backupPath="'$backupPath'" \ env REMOTE_FIND_CMD="'$REMOTE_FIND_CMD'" env rotateCopies="'$rotateCopies'" env backupPath="'$backupPath'" \
$COMMAND_SUDO' bash -s' << 'ENDSSH' > "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP" 2> "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP" $COMMAND_SUDO' bash -s' << 'ENDSSH' > "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP" 2> "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP"
@@ -3894,7 +4086,7 @@ function joinString {
function _Logger { function _Logger {
local logValue="${1}" # Log to file local logValue="${1}" # Log to file
local stdValue="${2}" # Log to screeen local stdValue="${2}" # Log to screeen
local toStderr="${3:-false}" # Log to stderr instead of stdout local toStdErr="${3:-false}" # Log to stderr instead of stdout
if [ "$logValue" != "" ]; then if [ "$logValue" != "" ]; then
echo -e "$logValue" >> "$LOG_FILE" echo -e "$logValue" >> "$LOG_FILE"
@@ -3903,7 +4095,7 @@ function _Logger {
fi fi
if [ "$stdValue" != "" ] && [ "$_LOGGER_SILENT" != true ]; then if [ "$stdValue" != "" ] && [ "$_LOGGER_SILENT" != true ]; then
if [ $toStderr == true ]; then if [ $toStdErr == true ]; then
# Force stderr color in subshell # Force stderr color in subshell
(>&2 echo -e "$stdValue") (>&2 echo -e "$stdValue")
@@ -4109,23 +4301,23 @@ function Init {
REMOTE_HOST=${hosturi%%:*} REMOTE_HOST=${hosturi%%:*}
fi fi
## Add update to default RSYNC_ARGS ## Add update to default RSYNC_TYPE_ARGS
RSYNC_ARGS=$RSYNC_ARGS" -u" RSYNC_TYPE_ARGS=$RSYNC_TYPE_ARGS" -u"
if [ $_LOGGER_VERBOSE == true ]; then if [ $_LOGGER_VERBOSE == true ]; then
RSYNC_ARGS=$RSYNC_ARGS" -i" RSYNC_TYPE_ARGS=$RSYNC_TYPE_ARGS" -i"
fi fi
if [ "$DELETE_VANISHED_FILES" == "yes" ]; then if [ "$DELETE_VANISHED_FILES" == "yes" ]; then
RSYNC_ARGS=$RSYNC_ARGS" --delete" RSYNC_TYPE_ARGS=$RSYNC_TYPE_ARGS" --delete"
fi fi
if [ $stats == true ]; then if [ $stats == true ]; then
RSYNC_ARGS=$RSYNC_ARGS" --stats" RSYNC_TYPE_ARGS=$RSYNC_TYPE_ARGS" --stats"
fi fi
## Fix for symlink to directories on target cannot get updated ## Fix for symlink to directories on target cannot get updated
RSYNC_ARGS=$RSYNC_ARGS" --force" RSYNC_TYPE_ARGS=$RSYNC_TYPE_ARGS" --force"
} }
function Main { function Main {
@@ -4214,12 +4406,16 @@ function Usage {
_DRYRUN=false _DRYRUN=false
no_maxtime=false no_maxtime=false
stats=false stats=false
PARTIAL=no partial_transfers=false
delete_vanished=false
dont_get_backup_size=false
_DECRYPT_MODE=false _DECRYPT_MODE=false
DECRYPT_PATH="" DECRYPT_PATH=""
_ENCRYPT_MODE=false _ENCRYPT_MODE=false
function GetCommandlineArguments { function GetCommandlineArguments {
local isFirstArgument=true
if [ $# -eq 0 ]; then if [ $# -eq 0 ]; then
Usage Usage
fi fi
@@ -4239,16 +4435,16 @@ function GetCommandlineArguments {
stats=false stats=false
;; ;;
--partial) --partial)
PARTIAL="yes" partial_transfers=true
;; ;;
--no-maxtime) --no-maxtime)
no_maxtime=true no_maxtime=true
;; ;;
--delete) --delete)
DELETE_VANISHED_FILES="yes" delete_vanished=true
;; ;;
--dontgetsize) --dontgetsize)
GET_BACKUP_SIZE="no" dont_get_backup_size=true
;; ;;
--help|-h|--version|-v) --help|-h|--version|-v)
Usage Usage
@@ -4284,7 +4480,15 @@ function GetCommandlineArguments {
if [ $(IsNumeric $PARALLEL_ENCRYPTION_PROCESSES) -ne 1 ]; then if [ $(IsNumeric $PARALLEL_ENCRYPTION_PROCESSES) -ne 1 ]; then
Logger "Bogus --parallel value. Using only one CPU." "WARN" Logger "Bogus --parallel value. Using only one CPU." "WARN"
fi fi
;;
*)
if [ $isFirstArgument == false ]; then
Logger "Unknown option '$i'" "CRITICAL"
Usage
fi
;;
esac esac
isFirstArgument=false
done done
} }
@@ -4326,6 +4530,27 @@ else
Logger "Script begin, logging to [$LOG_FILE]." "DEBUG" Logger "Script begin, logging to [$LOG_FILE]." "DEBUG"
fi fi
if [ $no_maxtime == true ]; then
SOFT_MAX_EXEC_TIME_DB_TASK=0
SOFT_MAX_EXEC_TIME_FILE_TASK=0
HARD_MAX_EXEC_TIME_DB_TASK=0
HARD_MAX_EXEC_TIME_FILE_TASK=0
HARD_MAX_EXEC_TIME_TOTAL=0
fi
if [ $partial_transfers == true ]; then
PARTIAL="yes"
fi
if [ $delete_vanished == true ]; then
DELETE_VANISHED_FILES="yes"
fi
if [ $dont_get_backup_size == true ]; then
GET_BACKUP_SIZE="no"
fi
if [ "$IS_STABLE" != "yes" ]; then if [ "$IS_STABLE" != "yes" ]; then
Logger "This is an unstable dev build [$PROGRAM_BUILD]. Please use with caution." "WARN" Logger "This is an unstable dev build [$PROGRAM_BUILD]. Please use with caution." "WARN"
fi fi
@@ -4346,13 +4571,5 @@ PostInit
CheckCurrentConfig CheckCurrentConfig
GetRemoteOS GetRemoteOS
InitRemoteOSDependingSettings InitRemoteOSDependingSettings
if [ $no_maxtime == true ]; then
SOFT_MAX_EXEC_TIME_DB_TASK=0
SOFT_MAX_EXEC_TIME_FILE_TASK=0
HARD_MAX_EXEC_TIME_DB_TASK=0
HARD_MAX_EXEC_TIME_FILE_TASK=0
HARD_MAX_EXEC_TIME_TOTAL=0
fi
RunBeforeHook RunBeforeHook
Main Main

View File

@@ -1,15 +1,21 @@
#!/usr/bin/env bash #!/usr/bin/env bash
## MERGE 2016121901 ## MERGE 2017061901
## Merges ofunctions.sh and n_program.sh into program.sh ## Merges ofunctions.sh and n_program.sh into program.sh
## Adds installer ## Adds installer
function Usage {
echo "Merges ofunctions.sh and n_program.sh into debug_program.sh and ../program.sh"
echo "Usage"
echo "$0 osync|obackup|pmocr"
}
function __PREPROCESSOR_Merge { function __PREPROCESSOR_Merge {
PROGRAM=obackup local PROGRAM="$1"
VERSION=$(grep "PROGRAM_VERSION=" n_$PROGRAM.sh) VERSION=$(grep "PROGRAM_VERSION=" n_$PROGRAM.sh)
VERSION=${VERSION#*=} VERSION=${VERSION#*=}
__PREPROCESSOR_Constants __PREPROCESSOR_Constants
source "ofunctions.sh" source "ofunctions.sh"
@@ -24,8 +30,7 @@ function __PREPROCESSOR_Merge {
__PREPROCESSOR_MergeSubset "$subset" "${subset//SUBSET/SUBSET END}" "ofunctions.sh" "debug_$PROGRAM.sh" __PREPROCESSOR_MergeSubset "$subset" "${subset//SUBSET/SUBSET END}" "ofunctions.sh" "debug_$PROGRAM.sh"
done done
__PREPROCESSOR_CleanDebug __PREPROCESSOR_CleanDebug "$PROGRAM"
__PREPROCESSOR_CopyCommons
rm -f tmp_$PROGRAM.sh rm -f tmp_$PROGRAM.sh
if [ $? != 0 ]; then if [ $? != 0 ]; then
QuickLogger "Cannot remove tmp_$PROGRAM.sh" QuickLogger "Cannot remove tmp_$PROGRAM.sh"
@@ -51,6 +56,9 @@ function __PREPROCESSOR_Constants {
'#### UrlEncode SUBSET ####' '#### UrlEncode SUBSET ####'
'#### HumanToNumeric SUBSET ####' '#### HumanToNumeric SUBSET ####'
'#### ArrayContains SUBSET ####' '#### ArrayContains SUBSET ####'
'#### VerComp SUBSET ####'
'#### GetConfFileValue SUBSET ####'
'#### SetConfFileValue SUBSET ####'
) )
} }
@@ -101,6 +109,8 @@ function __PREPROCESSOR_MergeSubset {
} }
function __PREPROCESSOR_CleanDebug { function __PREPROCESSOR_CleanDebug {
local PROGRAM="$1"
sed '/'$PARANOIA_DEBUG_BEGIN'/,/'$PARANOIA_DEBUG_END'/d' debug_$PROGRAM.sh | grep -v "$PARANOIA_DEBUG_LINE" > ../$PROGRAM.sh sed '/'$PARANOIA_DEBUG_BEGIN'/,/'$PARANOIA_DEBUG_END'/d' debug_$PROGRAM.sh | grep -v "$PARANOIA_DEBUG_LINE" > ../$PROGRAM.sh
if [ $? != 0 ]; then if [ $? != 0 ]; then
QuickLogger "Cannot remove PARANOIA_DEBUG code from standard build." QuickLogger "Cannot remove PARANOIA_DEBUG code from standard build."
@@ -124,21 +134,23 @@ function __PREPROCESSOR_CleanDebug {
} }
function __PREPROCESSOR_CopyCommons { function __PREPROCESSOR_CopyCommons {
sed "s/\[prgname\]/$PROGRAM/g" common_install.sh > ../tmp_install.sh local PROGRAM="$1"
sed "s/\[prgname\]/$PROGRAM/g" common_install.sh > ../install.sh
if [ $? != 0 ]; then if [ $? != 0 ]; then
QuickLogger "Cannot assemble install." QuickLogger "Cannot assemble install."
exit 1 exit 1
fi fi
for subset in "${__PREPROCESSOR_SUBSETS[@]}"; do for subset in "${__PREPROCESSOR_SUBSETS[@]}"; do
__PREPROCESSOR_MergeSubset "$subset" "${subset//SUBSET/SUBSET END}" "ofunctions.sh" "../tmp_install.sh" __PREPROCESSOR_MergeSubset "$subset" "${subset//SUBSET/SUBSET END}" "ofunctions.sh" "../install.sh"
done done
sed "s/\[version\]/$VERSION/g" ../tmp_install.sh > ../install.sh #sed "s/\[version\]/$VERSION/g" ../tmp_install.sh > ../install.sh
if [ $? != 0 ]; then #if [ $? != 0 ]; then
QuickLogger "Cannot change install version." # QuickLogger "Cannot change install version."
exit 1 # exit 1
fi #fi
if [ -f "common_batch.sh" ]; then if [ -f "common_batch.sh" ]; then
sed "s/\[prgname\]/$PROGRAM/g" common_batch.sh > ../$PROGRAM-batch.sh sed "s/\[prgname\]/$PROGRAM/g" common_batch.sh > ../$PROGRAM-batch.sh
if [ $? != 0 ]; then if [ $? != 0 ]; then
@@ -169,5 +181,19 @@ function __PREPROCESSOR_CopyCommons {
# If sourced don't do anything # If sourced don't do anything
if [ "$(basename $0)" == "merge.sh" ]; then if [ "$(basename $0)" == "merge.sh" ]; then
__PREPROCESSOR_Merge if [ "$1" == "osync" ]; then
__PREPROCESSOR_Merge osync
__PREPROCESSOR_Merge osync_target_helper
__PREPROCESSOR_CopyCommons osync
elif [ "$1" == "obackup" ]; then
__PREPROCESSOR_Merge obackup
__PREPROCESSOR_CopyCommons obackup
elif [ "$1" == "pmocr" ]; then
__PREPROCESSOR_Merge pmocr
__PREPROCESSOR_CopyCommons pmocr
else
echo "No valid program given."
exit 1
fi
fi fi

View File

@@ -6,12 +6,11 @@
PROGRAM="obackup" PROGRAM="obackup"
AUTHOR="(C) 2013-2017 by Orsiris de Jong" AUTHOR="(C) 2013-2017 by Orsiris de Jong"
CONTACT="http://www.netpower.fr/obackup - ozy@netpower.fr" CONTACT="http://www.netpower.fr/obackup - ozy@netpower.fr"
PROGRAM_VERSION=2.1-beta1 PROGRAM_VERSION=2.1-beta3
PROGRAM_BUILD=2017010401 PROGRAM_BUILD=2017062004
IS_STABLE=no IS_STABLE=no
# Execution order #__WITH_PARANOIA_DEBUG #### Execution order #__WITH_PARANOIA_DEBUG
# GetLocalOS #__WITH_PARANOIA_DEBUG # GetLocalOS #__WITH_PARANOIA_DEBUG
# InitLocalOSDependingSettings #__WITH_PARANOIA_DEBUG # InitLocalOSDependingSettings #__WITH_PARANOIA_DEBUG
# CheckRunningInstances #__WITH_PARANOIA_DEBUG # CheckRunningInstances #__WITH_PARANOIA_DEBUG
@@ -35,9 +34,7 @@ IS_STABLE=no
# RsyncPatterns #__WITH_PARANOIA_DEBUG # RsyncPatterns #__WITH_PARANOIA_DEBUG
# FilesBackup #__WITH_PARANOIA_DEBUG # FilesBackup #__WITH_PARANOIA_DEBUG
include #### OFUNCTIONS FULL SUBSET #### include #### OFUNCTIONS FULL SUBSET ####
# If using "include" statements, make sure the script does not get executed unless it's loaded by bootstrap # If using "include" statements, make sure the script does not get executed unless it's loaded by bootstrap
include #### _OFUNCTIONS_BOOTSTRAP SUBSET #### include #### _OFUNCTIONS_BOOTSTRAP SUBSET ####
[ "$_OFUNCTIONS_BOOTSTRAP" != true ] && echo "Please use bootstrap.sh to load this dev version of $(basename $0)" && exit 1 [ "$_OFUNCTIONS_BOOTSTRAP" != true ] && echo "Please use bootstrap.sh to load this dev version of $(basename $0)" && exit 1
@@ -268,7 +265,7 @@ function _ListDatabasesLocal {
Logger "Listing databases succeeded." "NOTICE" Logger "Listing databases succeeded." "NOTICE"
else else
Logger "Listing databases failed." "ERROR" Logger "Listing databases failed." "ERROR"
Logger "Command was [$sqlCmd]." "WARN" _LOGGER_SILENT=true Logger "Command was [$sqlCmd]." "WARN"
if [ -f "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP" ]; then if [ -f "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP" ]; then
Logger "Command output:\n$(cat $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP)" "ERROR" Logger "Command output:\n$(cat $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP)" "ERROR"
fi fi
@@ -285,7 +282,7 @@ function _ListDatabasesRemote {
CheckConnectivity3rdPartyHosts CheckConnectivity3rdPartyHosts
CheckConnectivityRemoteHost CheckConnectivityRemoteHost
sqlCmd="$SSH_CMD \"mysql -u $SQL_USER -Bse 'SELECT table_schema, round(sum( data_length + index_length ) / 1024) FROM information_schema.TABLES GROUP by table_schema;'\" > \"$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP\" 2>&1" sqlCmd="$SSH_CMD \"env _REMOTE_TOKEN=$_REMOTE_TOKEN mysql -u $SQL_USER -Bse 'SELECT table_schema, round(sum( data_length + index_length ) / 1024) FROM information_schema.TABLES GROUP by table_schema;'\" > \"$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP\" 2>&1"
Logger "Command output: $sqlCmd" "DEBUG" Logger "Command output: $sqlCmd" "DEBUG"
eval "$sqlCmd" & eval "$sqlCmd" &
WaitForTaskCompletion $! $SOFT_MAX_EXEC_TIME_DB_TASK $HARD_MAX_EXEC_TIME_DB_TASK $SLEEP_TIME $KEEP_LOGGING true true false WaitForTaskCompletion $! $SOFT_MAX_EXEC_TIME_DB_TASK $HARD_MAX_EXEC_TIME_DB_TASK $SLEEP_TIME $KEEP_LOGGING true true false
@@ -410,7 +407,7 @@ function _ListRecursiveBackupDirectoriesLocal {
retval=$? retval=$?
if [ $retval -ne 0 ]; then if [ $retval -ne 0 ]; then
Logger "Could not enumerate directories in [$directory]." "ERROR" Logger "Could not enumerate directories in [$directory]." "ERROR"
Logger "Command was [$cmd]." "Warn" _LOGGER_SILENT=true Logger "Command was [$cmd]." "WARN"
if [ -f $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP ]; then if [ -f $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP ]; then
Logger "Command output:\n$(cat $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP)" "ERROR" Logger "Command output:\n$(cat $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP)" "ERROR"
fi fi
@@ -436,7 +433,8 @@ function _ListRecursiveBackupDirectoriesRemote {
local retval local retval
$SSH_CMD env _DEBUG="'$_DEBUG'" env _PARANOIA_DEBUG="'$_PARANOIA_DEBUG'" env _LOGGER_SILENT="'$_LOGGER_SILENT'" env _LOGGER_VERBOSE="'$_LOGGER_VERBOSE'" env _LOGGER_PREFIX="'$_LOGGER_PREFIX'" env _LOGGER_ERR_ONLY="'$_LOGGER_ERR_ONLY'" \ $SSH_CMD env _REMOTE_TOKEN=$_REMOTE_TOKEN \
env _DEBUG="'$_DEBUG'" env _PARANOIA_DEBUG="'$_PARANOIA_DEBUG'" env _LOGGER_SILENT="'$_LOGGER_SILENT'" env _LOGGER_VERBOSE="'$_LOGGER_VERBOSE'" env _LOGGER_PREFIX="'$_LOGGER_PREFIX'" env _LOGGER_ERR_ONLY="'$_LOGGER_ERR_ONLY'" \
env PROGRAM="'$PROGRAM'" env SCRIPT_PID="'$SCRIPT_PID'" TSTAMP="'$TSTAMP'" \ env PROGRAM="'$PROGRAM'" env SCRIPT_PID="'$SCRIPT_PID'" TSTAMP="'$TSTAMP'" \
env RECURSIVE_DIRECTORY_LIST="'$RECURSIVE_DIRECTORY_LIST'" env PATH_SEPARATOR_CHAR="'$PATH_SEPARATOR_CHAR'" \ env RECURSIVE_DIRECTORY_LIST="'$RECURSIVE_DIRECTORY_LIST'" env PATH_SEPARATOR_CHAR="'$PATH_SEPARATOR_CHAR'" \
env REMOTE_FIND_CMD="'$REMOTE_FIND_CMD'" $COMMAND_SUDO' bash -s' << 'ENDSSH' > "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP" 2> "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP" env REMOTE_FIND_CMD="'$REMOTE_FIND_CMD'" $COMMAND_SUDO' bash -s' << 'ENDSSH' > "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP" 2> "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP"
@@ -580,14 +578,14 @@ function _GetDirectoriesSizeLocal {
retval=$? retval=$?
if [ $retval -ne 0 ] || [ -s $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP ]; then if [ $retval -ne 0 ] || [ -s $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP ]; then
Logger "Could not get files size for some or all local directories." "ERROR" Logger "Could not get files size for some or all local directories." "ERROR"
Logger "Command was [$cmd]." "WARN" _LOGGER_SILENT=true Logger "Command was [$cmd]." "WARN"
if [ -f "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP" ]; then if [ -f "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP" ]; then
Logger "Command output:\n$(cat $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP)" "ERROR" Logger "Command output:\n$(cat $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP)" "ERROR"
fi fi
if [ -f "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP" ]; then if [ -f "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP" ]; then
Logger "Error output:\n$(cat $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP)" "ERROR" Logger "Error output:\n$(cat $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP)" "ERROR"
fi fi
elsew else
Logger "File size fetched successfully." "NOTICE" Logger "File size fetched successfully." "NOTICE"
fi fi
@@ -609,7 +607,8 @@ function _GetDirectoriesSizeRemote {
local retval local retval
# Error output is different from stdout because not all files in list may fail at once # Error output is different from stdout because not all files in list may fail at once
$SSH_CMD env _DEBUG="'$_DEBUG'" env _PARANOIA_DEBUG="'$_PARANOIA_DEBUG'" env _LOGGER_SILENT="'$_LOGGER_SILENT'" env _LOGGER_VERBOSE="'$_LOGGER_VERBOSE'" env _LOGGER_PREFIX="'$_LOGGER_PREFIX'" env _LOGGER_ERR_ONLY="'$_LOGGER_ERR_ONLY'" \ $SSH_CMD env _REMOTE_TOKEN=$_REMOTE_TOKEN \
env _DEBUG="'$_DEBUG'" env _PARANOIA_DEBUG="'$_PARANOIA_DEBUG'" env _LOGGER_SILENT="'$_LOGGER_SILENT'" env _LOGGER_VERBOSE="'$_LOGGER_VERBOSE'" env _LOGGER_PREFIX="'$_LOGGER_PREFIX'" env _LOGGER_ERR_ONLY="'$_LOGGER_ERR_ONLY'" \
env PROGRAM="'$PROGRAM'" env SCRIPT_PID="'$SCRIPT_PID'" TSTAMP="'$TSTAMP'" dirList="'$dirList'" \ env PROGRAM="'$PROGRAM'" env SCRIPT_PID="'$SCRIPT_PID'" TSTAMP="'$TSTAMP'" dirList="'$dirList'" \
$COMMAND_SUDO' bash -s' << 'ENDSSH' > "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP" 2> "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP" & $COMMAND_SUDO' bash -s' << 'ENDSSH' > "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP" 2> "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP" &
include #### DEBUG SUBSET #### include #### DEBUG SUBSET ####
@@ -695,7 +694,8 @@ function _CreateDirectoryRemote {
CheckConnectivity3rdPartyHosts CheckConnectivity3rdPartyHosts
CheckConnectivityRemoteHost CheckConnectivityRemoteHost
$SSH_CMD env _DEBUG="'$_DEBUG'" env _PARANOIA_DEBUG="'$_PARANOIA_DEBUG'" env _LOGGER_SILENT="'$_LOGGER_SILENT'" env _LOGGER_VERBOSE="'$_LOGGER_VERBOSE'" env _LOGGER_PREFIX="'$_LOGGER_PREFIX'" env _LOGGER_ERR_ONLY="'$_LOGGER_ERR_ONLY'" \ $SSH_CMD env _REMOTE_TOKEN=$_REMOTE_TOKEN \
env _DEBUG="'$_DEBUG'" env _PARANOIA_DEBUG="'$_PARANOIA_DEBUG'" env _LOGGER_SILENT="'$_LOGGER_SILENT'" env _LOGGER_VERBOSE="'$_LOGGER_VERBOSE'" env _LOGGER_PREFIX="'$_LOGGER_PREFIX'" env _LOGGER_ERR_ONLY="'$_LOGGER_ERR_ONLY'" \
env PROGRAM="'$PROGRAM'" env SCRIPT_PID="'$SCRIPT_PID'" TSTAMP="'$TSTAMP'" \ env PROGRAM="'$PROGRAM'" env SCRIPT_PID="'$SCRIPT_PID'" TSTAMP="'$TSTAMP'" \
env dirToCreate="'$dirToCreate'" $COMMAND_SUDO' bash -s' << 'ENDSSH' > "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP" 2>&1 & env dirToCreate="'$dirToCreate'" $COMMAND_SUDO' bash -s' << 'ENDSSH' > "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP" 2>&1 &
include #### DEBUG SUBSET #### include #### DEBUG SUBSET ####
@@ -805,7 +805,8 @@ function GetDiskSpaceRemote {
local cmd local cmd
local retval local retval
$SSH_CMD env _DEBUG="'$_DEBUG'" env _PARANOIA_DEBUG="'$_PARANOIA_DEBUG'" env _LOGGER_SILENT="'$_LOGGER_SILENT'" env _LOGGER_VERBOSE="'$_LOGGER_VERBOSE'" env _LOGGER_PREFIX="'$_LOGGER_PREFIX'" env _LOGGER_ERR_ONLY="'$_LOGGER_ERR_ONLY'" \ $SSH_CMD env _REMOTE_TOKEN=$_REMOTE_TOKEN \
env _DEBUG="'$_DEBUG'" env _PARANOIA_DEBUG="'$_PARANOIA_DEBUG'" env _LOGGER_SILENT="'$_LOGGER_SILENT'" env _LOGGER_VERBOSE="'$_LOGGER_VERBOSE'" env _LOGGER_PREFIX="'$_LOGGER_PREFIX'" env _LOGGER_ERR_ONLY="'$_LOGGER_ERR_ONLY'" \
env PROGRAM="'$PROGRAM'" env SCRIPT_PID="'$SCRIPT_PID'" TSTAMP="'$TSTAMP'" \ env PROGRAM="'$PROGRAM'" env SCRIPT_PID="'$SCRIPT_PID'" TSTAMP="'$TSTAMP'" \
env DF_CMD="'$DF_CMD'" \ env DF_CMD="'$DF_CMD'" \
env pathToCheck="'$pathToCheck'" $COMMAND_SUDO' bash -s' << 'ENDSSH' > "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP" 2> "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP" & env pathToCheck="'$pathToCheck'" $COMMAND_SUDO' bash -s' << 'ENDSSH' > "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP" 2> "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP" &
@@ -1019,10 +1020,10 @@ function _BackupDatabaseLocalToLocal {
retval=$? retval=$?
if [ -s "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP" ]; then if [ -s "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP" ]; then
if [ $_DRYRUN == false ]; then if [ $_DRYRUN == false ]; then
Logger "Command was [$sqlCmd]." "WARN" _LOGGER_SILENT=true Logger "Command was [$sqlCmd]." "WARN"
eval "$sqlCmd" & eval "$sqlCmd" &
else else
Logger "Command was [$drySqlCmd]." "WARN" _LOGGER_SILENT=true Logger "Command was [$drySqlCmd]." "WARN"
eval "$drySqlCmd" & eval "$drySqlCmd" &
fi fi
Logger "Error output:\n$(cat $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP)" "ERROR" Logger "Error output:\n$(cat $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP)" "ERROR"
@@ -1055,7 +1056,7 @@ function _BackupDatabaseLocalToRemote {
fi fi
local drySqlCmd="mysqldump -u $SQL_USER $exportOptions --databases $database $COMPRESSION_PROGRAM $COMPRESSION_OPTIONS $encryptOptions > /dev/null 2> $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP" local drySqlCmd="mysqldump -u $SQL_USER $exportOptions --databases $database $COMPRESSION_PROGRAM $COMPRESSION_OPTIONS $encryptOptions > /dev/null 2> $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP"
local sqlCmd="mysqldump -u $SQL_USER $exportOptions --databases $database $COMPRESSION_PROGRAM $COMPRESSION_OPTIONS $encryptOptions | $SSH_CMD '$COMMAND_SUDO tee \"$SQL_STORAGE/$database.sql$COMPRESSION_EXTENSION$encryptExtension\" > /dev/null' 2> $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP" local sqlCmd="mysqldump -u $SQL_USER $exportOptions --databases $database $COMPRESSION_PROGRAM $COMPRESSION_OPTIONS $encryptOptions | $SSH_CMD 'env _REMOTE_TOKEN=$_REMOTE_TOKEN $COMMAND_SUDO tee \"$SQL_STORAGE/$database.sql$COMPRESSION_EXTENSION$encryptExtension\" > /dev/null' 2> $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP"
if [ $_DRYRUN == false ]; then if [ $_DRYRUN == false ]; then
Logger "Launching command [$sqlCmd]." "DEBUG" Logger "Launching command [$sqlCmd]." "DEBUG"
@@ -1068,10 +1069,10 @@ function _BackupDatabaseLocalToRemote {
retval=$? retval=$?
if [ -s "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP" ]; then if [ -s "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP" ]; then
if [ $_DRYRUN == false ]; then if [ $_DRYRUN == false ]; then
Logger "Command was [$sqlCmd]." "WARN" _LOGGER_SILENT=true Logger "Command was [$sqlCmd]." "WARN"
eval "$sqlCmd" & eval "$sqlCmd" &
else else
Logger "Command was [$drySqlCmd]." "WARN" _LOGGER_SILENT=true Logger "Command was [$drySqlCmd]." "WARN"
eval "$drySqlCmd" & eval "$drySqlCmd" &
fi fi
Logger "Error output:\n$(cat $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP)" "ERROR" Logger "Error output:\n$(cat $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP)" "ERROR"
@@ -1103,8 +1104,8 @@ function _BackupDatabaseRemoteToLocal {
encryptExtension="$CRYPT_FILE_EXTENSION" encryptExtension="$CRYPT_FILE_EXTENSION"
fi fi
local drySqlCmd=$SSH_CMD' "mysqldump -u '$SQL_USER' '$exportOptions' --databases '$database' '$COMPRESSION_PROGRAM' '$COMPRESSION_OPTIONS' '$encryptOptions'" > /dev/null 2> "'$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP'"' local drySqlCmd=$SSH_CMD' "env _REMOTE_TOKEN=$_REMOTE_TOKEN mysqldump -u '$SQL_USER' '$exportOptions' --databases '$database' '$COMPRESSION_PROGRAM' '$COMPRESSION_OPTIONS' '$encryptOptions'" > /dev/null 2> "'$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP'"'
local sqlCmd=$SSH_CMD' "mysqldump -u '$SQL_USER' '$exportOptions' --databases '$database' '$COMPRESSION_PROGRAM' '$COMPRESSION_OPTIONS' '$encryptOptions'" > "'$SQL_STORAGE/$database.sql$COMPRESSION_EXTENSION$encryptExtension'" 2> "'$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP'"' local sqlCmd=$SSH_CMD' "env _REMOTE_TOKEN=$_REMOTE_TOKEN mysqldump -u '$SQL_USER' '$exportOptions' --databases '$database' '$COMPRESSION_PROGRAM' '$COMPRESSION_OPTIONS' '$encryptOptions'" > "'$SQL_STORAGE/$database.sql$COMPRESSION_EXTENSION$encryptExtension'" 2> "'$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP'"'
if [ $_DRYRUN == false ]; then if [ $_DRYRUN == false ]; then
Logger "Launching command [$sqlCmd]." "DEBUG" Logger "Launching command [$sqlCmd]." "DEBUG"
@@ -1117,10 +1118,10 @@ function _BackupDatabaseRemoteToLocal {
retval=$? retval=$?
if [ -s "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP" ]; then if [ -s "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP" ]; then
if [ $_DRYRUN == false ]; then if [ $_DRYRUN == false ]; then
Logger "Command was [$sqlCmd]." "WARN" _LOGGER_SILENT=true Logger "Command was [$sqlCmd]." "WARN"
eval "$sqlCmd" & eval "$sqlCmd" &
else else
Logger "Command was [$drySqlCmd]." "WARN" _LOGGER_SILENT=true Logger "Command was [$drySqlCmd]." "WARN"
eval "$drySqlCmd" & eval "$drySqlCmd" &
fi fi
Logger "Error output:\n$(cat $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP)" "ERROR" Logger "Error output:\n$(cat $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP)" "ERROR"
@@ -1260,7 +1261,7 @@ function EncryptFiles {
ParallelExec $PARALLEL_ENCRYPTION_PROCESSES "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.parallel.$SCRIPT_PID.$TSTAMP" true $softMaxExecTime $hardMaxExecTime $SLEEP_TIME $KEEP_LOGGING true true false ParallelExec $PARALLEL_ENCRYPTION_PROCESSES "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.parallel.$SCRIPT_PID.$TSTAMP" true $softMaxExecTime $hardMaxExecTime $SLEEP_TIME $KEEP_LOGGING true true false
retval=$? retval=$?
if [ $retval -ne 0 ]; then if [ $retval -ne 0 ]; then
Logger "Encryption error.." "ERROR" Logger "Encryption error." "ERROR"
# Output file is defined in ParallelExec # Output file is defined in ParallelExec
Logger "Command output:\n$(cat $RUN_DIR/$PROGRAM.ParallelExec.EncryptFiles.$SCRIPT_PID.$TSTAMP)" "DEBUG" Logger "Command output:\n$(cat $RUN_DIR/$PROGRAM.ParallelExec.EncryptFiles.$SCRIPT_PID.$TSTAMP)" "DEBUG"
fi fi
@@ -1416,13 +1417,13 @@ function Rsync {
CheckConnectivity3rdPartyHosts CheckConnectivity3rdPartyHosts
CheckConnectivityRemoteHost CheckConnectivityRemoteHost
sourceDir=$(EscapeSpaces "$sourceDir") sourceDir=$(EscapeSpaces "$sourceDir")
rsyncCmd="$(type -p $RSYNC_EXECUTABLE) $RSYNC_ARGS $RSYNC_DRY_ARG $RSYNC_ATTR_ARGS $RSYNC_TYPE_ARGS $RSYNC_NO_RECURSE_ARGS $RSYNC_DELETE $RSYNC_PATTERNS $RSYNC_PARTIAL_EXCLUDE --rsync-path=\"$RSYNC_PATH\" -e \"$RSYNC_SSH_CMD\" \"$REMOTE_USER@$REMOTE_HOST:$sourceDir\" \"$destinationDir\" > $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP 2>&1" rsyncCmd="$(type -p $RSYNC_EXECUTABLE) $RSYNC_ARGS $RSYNC_DRY_ARG $RSYNC_ATTR_ARGS $RSYNC_TYPE_ARGS $RSYNC_NO_RECURSE_ARGS $RSYNC_DELETE $RSYNC_PATTERNS $RSYNC_PARTIAL_EXCLUDE --rsync-path=\"env _REMOTE_TOKEN=$_REMOTE_TOKEN $RSYNC_PATH\" -e \"$RSYNC_SSH_CMD\" \"$REMOTE_USER@$REMOTE_HOST:$sourceDir\" \"$destinationDir\" > $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP 2>&1"
elif [ "$BACKUP_TYPE" == "push" ]; then elif [ "$BACKUP_TYPE" == "push" ]; then
destinationDir=$(EscapeSpaces "$destinationDir") destinationDir=$(EscapeSpaces "$destinationDir")
_CreateDirectoryRemote "$destinationDir" _CreateDirectoryRemote "$destinationDir"
CheckConnectivity3rdPartyHosts CheckConnectivity3rdPartyHosts
CheckConnectivityRemoteHost CheckConnectivityRemoteHost
rsyncCmd="$(type -p $RSYNC_EXECUTABLE) $RSYNC_ARGS $RSYNC_DRY_ARG $RSYNC_ATTR_ARGS $RSYNC_TYPE_ARGS $RSYNC_NO_RECURSE_ARGS $RSYNC_DELETE $RSYNC_PATTERNS $RSYNC_PARTIAL_EXCLUDE --rsync-path=\"$RSYNC_PATH\" -e \"$RSYNC_SSH_CMD\" \"$sourceDir\" \"$REMOTE_USER@$REMOTE_HOST:$destinationDir\" > $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP 2>&1" rsyncCmd="$(type -p $RSYNC_EXECUTABLE) $RSYNC_ARGS $RSYNC_DRY_ARG $RSYNC_ATTR_ARGS $RSYNC_TYPE_ARGS $RSYNC_NO_RECURSE_ARGS $RSYNC_DELETE $RSYNC_PATTERNS $RSYNC_PARTIAL_EXCLUDE --rsync-path=\"env _REMOTE_TOKEN=$_REMOTE_TOKEN $RSYNC_PATH\" -e \"$RSYNC_SSH_CMD\" \"$sourceDir\" \"$REMOTE_USER@$REMOTE_HOST:$destinationDir\" > $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP 2>&1"
fi fi
Logger "Launching command [$rsyncCmd]." "DEBUG" Logger "Launching command [$rsyncCmd]." "DEBUG"
@@ -1431,7 +1432,7 @@ function Rsync {
retval=$? retval=$?
if [ $retval -ne 0 ]; then if [ $retval -ne 0 ]; then
Logger "Failed to backup [$sourceDir] to [$destinationDir]." "ERROR" Logger "Failed to backup [$sourceDir] to [$destinationDir]." "ERROR"
Logger "Command was [$rsyncCmd]." "WARN" _LOGGER_SILENT=true Logger "Command was [$rsyncCmd]." "WARN"
Logger "Command output:\n $(cat $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP)" "ERROR" Logger "Command output:\n $(cat $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP)" "ERROR"
else else
Logger "File backup succeed." "NOTICE" Logger "File backup succeed." "NOTICE"
@@ -1580,7 +1581,7 @@ function _RotateBackupsLocal {
WaitForTaskCompletion $! 3600 0 $SLEEP_TIME $KEEP_LOGGING true true false WaitForTaskCompletion $! 3600 0 $SLEEP_TIME $KEEP_LOGGING true true false
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
Logger "Cannot delete oldest copy [$path]." "ERROR" Logger "Cannot delete oldest copy [$path]." "ERROR"
Logger "Command was [$cmd]." "WARN" _LOGGER_SILENT=true Logger "Command was [$cmd]." "WARN"
fi fi
fi fi
fi fi
@@ -1593,7 +1594,7 @@ function _RotateBackupsLocal {
WaitForTaskCompletion $! 3600 0 $SLEEP_TIME $KEEP_LOGGING true true false WaitForTaskCompletion $! 3600 0 $SLEEP_TIME $KEEP_LOGGING true true false
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
Logger "Cannot move [$path] to [$backup.$PROGRAM.$copy]." "ERROR" Logger "Cannot move [$path] to [$backup.$PROGRAM.$copy]." "ERROR"
Logger "Command was [$cmd]." "WARN" _LOGGER_SILENT=true Logger "Command was [$cmd]." "WARN"
fi fi
fi fi
@@ -1608,7 +1609,7 @@ function _RotateBackupsLocal {
WaitForTaskCompletion $! 3600 0 $SLEEP_TIME $KEEP_LOGGING true true false WaitForTaskCompletion $! 3600 0 $SLEEP_TIME $KEEP_LOGGING true true false
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
Logger "Cannot move [$backup] to [$backup.$PROGRAM.1]." "ERROR" Logger "Cannot move [$backup] to [$backup.$PROGRAM.1]." "ERROR"
Logger "Command was [$cmd]." "WARN" _LOGGER_SILENT=true Logger "Command was [$cmd]." "WARN"
fi fi
elif [ "$REMOTE_OPERATION" == "yes" ]; then elif [ "$REMOTE_OPERATION" == "yes" ]; then
@@ -1618,7 +1619,7 @@ function _RotateBackupsLocal {
WaitForTaskCompletion $! 3600 0 $SLEEP_TIME $KEEP_LOGGING true true false WaitForTaskCompletion $! 3600 0 $SLEEP_TIME $KEEP_LOGGING true true false
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
Logger "Cannot copy [$backup] to [$backup.$PROGRAM.1]." "ERROR" Logger "Cannot copy [$backup] to [$backup.$PROGRAM.1]." "ERROR"
Logger "Command was [$cmd]." "WARN" _LOGGER_SILENT=true Logger "Command was [$cmd]." "WARN"
fi fi
else else
@@ -1628,7 +1629,7 @@ function _RotateBackupsLocal {
WaitForTaskCompletion $! 3600 0 $SLEEP_TIME $KEEP_LOGGING true true false WaitForTaskCompletion $! 3600 0 $SLEEP_TIME $KEEP_LOGGING true true false
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
Logger "Cannot move [$backup] to [$backup.$PROGRAM.1]." "ERROR" Logger "Cannot move [$backup] to [$backup.$PROGRAM.1]." "ERROR"
Logger "Command was [$cmd]." "WARN" _LOGGER_SILENT=true Logger "Command was [$cmd]." "WARN"
fi fi
fi fi
done done
@@ -1639,7 +1640,8 @@ function _RotateBackupsRemote {
local rotateCopies="${2}" local rotateCopies="${2}"
__CheckArguments 2 $# "$@" #__WITH_PARANOIA_DEBUG __CheckArguments 2 $# "$@" #__WITH_PARANOIA_DEBUG
$SSH_CMD env _DEBUG="'$_DEBUG'" env _PARANOIA_DEBUG="'$_PARANOIA_DEBUG'" env _LOGGER_SILENT="'$_LOGGER_SILENT'" env _LOGGER_VERBOSE="'$_LOGGER_VERBOSE'" env _LOGGER_PREFIX="'$_LOGGER_PREFIX'" env _LOGGER_ERR_ONLY="'$_LOGGER_ERR_ONLY'" \ $SSH_CMD env _REMOTE_TOKEN=$_REMOTE_TOKEN \
env _DEBUG="'$_DEBUG'" env _PARANOIA_DEBUG="'$_PARANOIA_DEBUG'" env _LOGGER_SILENT="'$_LOGGER_SILENT'" env _LOGGER_VERBOSE="'$_LOGGER_VERBOSE'" env _LOGGER_PREFIX="'$_LOGGER_PREFIX'" env _LOGGER_ERR_ONLY="'$_LOGGER_ERR_ONLY'" \
env PROGRAM="'$PROGRAM'" env SCRIPT_PID="'$SCRIPT_PID'" TSTAMP="'$TSTAMP'" \ env PROGRAM="'$PROGRAM'" env SCRIPT_PID="'$SCRIPT_PID'" TSTAMP="'$TSTAMP'" \
env REMOTE_FIND_CMD="'$REMOTE_FIND_CMD'" env rotateCopies="'$rotateCopies'" env backupPath="'$backupPath'" \ env REMOTE_FIND_CMD="'$REMOTE_FIND_CMD'" env rotateCopies="'$rotateCopies'" env backupPath="'$backupPath'" \
$COMMAND_SUDO' bash -s' << 'ENDSSH' > "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP" 2> "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP" $COMMAND_SUDO' bash -s' << 'ENDSSH' > "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP" 2> "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP"
@@ -1782,23 +1784,23 @@ function Init {
REMOTE_HOST=${hosturi%%:*} REMOTE_HOST=${hosturi%%:*}
fi fi
## Add update to default RSYNC_ARGS ## Add update to default RSYNC_TYPE_ARGS
RSYNC_ARGS=$RSYNC_ARGS" -u" RSYNC_TYPE_ARGS=$RSYNC_TYPE_ARGS" -u"
if [ $_LOGGER_VERBOSE == true ]; then if [ $_LOGGER_VERBOSE == true ]; then
RSYNC_ARGS=$RSYNC_ARGS" -i" RSYNC_TYPE_ARGS=$RSYNC_TYPE_ARGS" -i"
fi fi
if [ "$DELETE_VANISHED_FILES" == "yes" ]; then if [ "$DELETE_VANISHED_FILES" == "yes" ]; then
RSYNC_ARGS=$RSYNC_ARGS" --delete" RSYNC_TYPE_ARGS=$RSYNC_TYPE_ARGS" --delete"
fi fi
if [ $stats == true ]; then if [ $stats == true ]; then
RSYNC_ARGS=$RSYNC_ARGS" --stats" RSYNC_TYPE_ARGS=$RSYNC_TYPE_ARGS" --stats"
fi fi
## Fix for symlink to directories on target cannot get updated ## Fix for symlink to directories on target cannot get updated
RSYNC_ARGS=$RSYNC_ARGS" --force" RSYNC_TYPE_ARGS=$RSYNC_TYPE_ARGS" --force"
} }
function Main { function Main {
@@ -1887,12 +1889,16 @@ function Usage {
_DRYRUN=false _DRYRUN=false
no_maxtime=false no_maxtime=false
stats=false stats=false
PARTIAL=no partial_transfers=false
delete_vanished=false
dont_get_backup_size=false
_DECRYPT_MODE=false _DECRYPT_MODE=false
DECRYPT_PATH="" DECRYPT_PATH=""
_ENCRYPT_MODE=false _ENCRYPT_MODE=false
function GetCommandlineArguments { function GetCommandlineArguments {
local isFirstArgument=true
if [ $# -eq 0 ]; then if [ $# -eq 0 ]; then
Usage Usage
fi fi
@@ -1912,16 +1918,16 @@ function GetCommandlineArguments {
stats=false stats=false
;; ;;
--partial) --partial)
PARTIAL="yes" partial_transfers=true
;; ;;
--no-maxtime) --no-maxtime)
no_maxtime=true no_maxtime=true
;; ;;
--delete) --delete)
DELETE_VANISHED_FILES="yes" delete_vanished=true
;; ;;
--dontgetsize) --dontgetsize)
GET_BACKUP_SIZE="no" dont_get_backup_size=true
;; ;;
--help|-h|--version|-v) --help|-h|--version|-v)
Usage Usage
@@ -1957,7 +1963,15 @@ function GetCommandlineArguments {
if [ $(IsNumeric $PARALLEL_ENCRYPTION_PROCESSES) -ne 1 ]; then if [ $(IsNumeric $PARALLEL_ENCRYPTION_PROCESSES) -ne 1 ]; then
Logger "Bogus --parallel value. Using only one CPU." "WARN" Logger "Bogus --parallel value. Using only one CPU." "WARN"
fi fi
;;
*)
if [ $isFirstArgument == false ]; then
Logger "Unknown option '$i'" "CRITICAL"
Usage
fi
;;
esac esac
isFirstArgument=false
done done
} }
@@ -1999,6 +2013,27 @@ else
Logger "Script begin, logging to [$LOG_FILE]." "DEBUG" Logger "Script begin, logging to [$LOG_FILE]." "DEBUG"
fi fi
if [ $no_maxtime == true ]; then
SOFT_MAX_EXEC_TIME_DB_TASK=0
SOFT_MAX_EXEC_TIME_FILE_TASK=0
HARD_MAX_EXEC_TIME_DB_TASK=0
HARD_MAX_EXEC_TIME_FILE_TASK=0
HARD_MAX_EXEC_TIME_TOTAL=0
fi
if [ $partial_transfers == true ]; then
PARTIAL="yes"
fi
if [ $delete_vanished == true ]; then
DELETE_VANISHED_FILES="yes"
fi
if [ $dont_get_backup_size == true ]; then
GET_BACKUP_SIZE="no"
fi
if [ "$IS_STABLE" != "yes" ]; then if [ "$IS_STABLE" != "yes" ]; then
Logger "This is an unstable dev build [$PROGRAM_BUILD]. Please use with caution." "WARN" Logger "This is an unstable dev build [$PROGRAM_BUILD]. Please use with caution." "WARN"
fi fi
@@ -2019,13 +2054,5 @@ PostInit
CheckCurrentConfig CheckCurrentConfig
GetRemoteOS GetRemoteOS
InitRemoteOSDependingSettings InitRemoteOSDependingSettings
if [ $no_maxtime == true ]; then
SOFT_MAX_EXEC_TIME_DB_TASK=0
SOFT_MAX_EXEC_TIME_FILE_TASK=0
HARD_MAX_EXEC_TIME_DB_TASK=0
HARD_MAX_EXEC_TIME_FILE_TASK=0
HARD_MAX_EXEC_TIME_TOTAL=0
fi
RunBeforeHook RunBeforeHook
Main Main

View File

@@ -2,8 +2,8 @@
#### OFUNCTIONS FULL SUBSET #### #### OFUNCTIONS FULL SUBSET ####
#### OFUNCTIONS MINI SUBSET #### #### OFUNCTIONS MINI SUBSET ####
_OFUNCTIONS_VERSION=2.1-RC1+dev _OFUNCTIONS_VERSION=2.1.4-rc1
_OFUNCTIONS_BUILD=2017010401 _OFUNCTIONS_BUILD=2017060903
#### _OFUNCTIONS_BOOTSTRAP SUBSET #### #### _OFUNCTIONS_BOOTSTRAP SUBSET ####
_OFUNCTIONS_BOOTSTRAP=true _OFUNCTIONS_BOOTSTRAP=true
#### _OFUNCTIONS_BOOTSTRAP SUBSET END #### #### _OFUNCTIONS_BOOTSTRAP SUBSET END ####
@@ -30,6 +30,9 @@ fi
## Correct output of sort command (language agnostic sorting) ## Correct output of sort command (language agnostic sorting)
export LC_ALL=C export LC_ALL=C
## Default umask for file creation
umask 0077
# Standard alert mail body # Standard alert mail body
MAIL_ALERT_MSG="Execution of $PROGRAM instance $INSTANCE_ID on $(date) has warnings/errors." MAIL_ALERT_MSG="Execution of $PROGRAM instance $INSTANCE_ID on $(date) has warnings/errors."
@@ -68,7 +71,9 @@ fi
#### DEBUG SUBSET END #### #### DEBUG SUBSET END ####
SCRIPT_PID=$$ SCRIPT_PID=$$
TSTAMP=$(date '+%Y%m%d%H%M%S%N')
# TODO: Check if %N works on MacOS
TSTAMP=$(date '+%Y%m%dT%H%M%S.%N')
LOCAL_USER=$(whoami) LOCAL_USER=$(whoami)
LOCAL_HOST=$(hostname) LOCAL_HOST=$(hostname)
@@ -125,7 +130,7 @@ function joinString {
function _Logger { function _Logger {
local logValue="${1}" # Log to file local logValue="${1}" # Log to file
local stdValue="${2}" # Log to screeen local stdValue="${2}" # Log to screeen
local toStderr="${3:-false}" # Log to stderr instead of stdout local toStdErr="${3:-false}" # Log to stderr instead of stdout
if [ "$logValue" != "" ]; then if [ "$logValue" != "" ]; then
echo -e "$logValue" >> "$LOG_FILE" echo -e "$logValue" >> "$LOG_FILE"
@@ -134,7 +139,7 @@ function _Logger {
fi fi
if [ "$stdValue" != "" ] && [ "$_LOGGER_SILENT" != true ]; then if [ "$stdValue" != "" ] && [ "$_LOGGER_SILENT" != true ]; then
if [ $toStderr == true ]; then if [ $toStdErr == true ]; then
# Force stderr color in subshell # Force stderr color in subshell
(>&2 echo -e "$stdValue") (>&2 echo -e "$stdValue")
@@ -234,6 +239,10 @@ function Logger {
prefix="" prefix=""
fi fi
## Obfuscate _REMOTE_TOKEN in logs (for ssh_filter usage only in osync and obackup)
value="${value/env _REMOTE_TOKEN=$_REMOTE_TOKEN/__(o_O)__}"
value="${value/env _REMOTE_TOKEN=\$_REMOTE_TOKEN/__(o_O)__}"
if [ "$level" == "CRITICAL" ]; then if [ "$level" == "CRITICAL" ]; then
_Logger "$prefix($level):$value" "$prefix\e[1;33;41m$value\e[0m" true _Logger "$prefix($level):$value" "$prefix\e[1;33;41m$value\e[0m" true
ERROR_ALERT=true ERROR_ALERT=true
@@ -257,7 +266,7 @@ function Logger {
return return
elif [ "$level" == "VERBOSE" ]; then elif [ "$level" == "VERBOSE" ]; then
if [ $_LOGGER_VERBOSE == true ]; then if [ $_LOGGER_VERBOSE == true ]; then
_Logger "$prefix:$value" "$prefix$value" _Logger "$prefix($level):$value" "$prefix$value"
fi fi
return return
elif [ "$level" == "ALWAYS" ]; then elif [ "$level" == "ALWAYS" ]; then
@@ -310,15 +319,29 @@ function KillChilds {
local pid="${1}" # Parent pid to kill childs local pid="${1}" # Parent pid to kill childs
local self="${2:-false}" # Should parent be killed too ? local self="${2:-false}" # Should parent be killed too ?
# Warning: pgrep does not exist in cygwin, have this checked in CheckEnvironment # Paranoid checks, we can safely assume that $pid shouldn't be 0 nor 1
if children="$(pgrep -P "$pid")"; then if [ $(IsNumeric "$pid") -eq 0 ] || [ "$pid" == "" ] || [ "$pid" == "0" ] || [ "$pid" == "1" ]; then
for child in $children; do Logger "Bogus pid given [$pid]." "CRITICAL"
Logger "Launching KillChilds \"$child\" true" "DEBUG" #__WITH_PARANOIA_DEBUG return 1
KillChilds "$child" true
done
fi fi
# Try to kill nicely, if not, wait 15 seconds to let Trap actions happen before killing
if kill -0 "$pid" > /dev/null 2>&1; then
# Warning: pgrep is not native on cygwin, have this checked in CheckEnvironment
if children="$(pgrep -P "$pid")"; then
if [[ "$pid" == *"$children"* ]]; then
Logger "Bogus pgrep implementation." "CRITICAL"
children="${children/$pid/}"
fi
for child in $children; do
Logger "Launching KillChilds \"$child\" true" "DEBUG" #__WITH_PARANOIA_DEBUG
KillChilds "$child" true
done
fi
fi
# Try to kill nicely, if not, wait 15 seconds to let Trap actions happen before killing
if [ "$self" == true ]; then if [ "$self" == true ]; then
# We need to check for pid again because it may have disappeared after recursive function call
if kill -0 "$pid" > /dev/null 2>&1; then if kill -0 "$pid" > /dev/null 2>&1; then
kill -s TERM "$pid" kill -s TERM "$pid"
Logger "Sent SIGTERM to process [$pid]." "DEBUG" Logger "Sent SIGTERM to process [$pid]." "DEBUG"
@@ -381,13 +404,17 @@ function SendAlert {
eval "cat \"$LOG_FILE\" $COMPRESSION_PROGRAM > $ALERT_LOG_FILE" eval "cat \"$LOG_FILE\" $COMPRESSION_PROGRAM > $ALERT_LOG_FILE"
if [ $? != 0 ]; then if [ $? != 0 ]; then
Logger "Cannot create [$ALERT_LOG_FILE]" "WARN"
attachment=false attachment=false
else else
attachment=true attachment=true
fi fi
if [ -e "$RUN_DIR/$PROGRAM._Logger.$SCRIPT_PID.$TSTAMP" ]; then if [ -e "$RUN_DIR/$PROGRAM._Logger.$SCRIPT_PID.$TSTAMP" ]; then
body="$MAIL_ALERT_MSG"$'\n\n'"$(cat $RUN_DIR/$PROGRAM._Logger.$SCRIPT_PID.$TSTAMP)" if [ "$MAIL_BODY_CHARSET" != "" ] && type iconv > /dev/null 2>&1; then
iconv -f UTF-8 -t $MAIL_BODY_CHARSET "$RUN_DIR/$PROGRAM._Logger.$SCRIPT_PID.$TSTAMP" > "$RUN_DIR/$PROGRAM._Logger.iconv.$SCRIPT_PID.$TSTAMP"
body="$MAIL_ALERT_MSG"$'\n\n'"$(cat $RUN_DIR/$PROGRAM._Logger.iconv.$SCRIPT_PID.$TSTAMP)"
else
body="$MAIL_ALERT_MSG"$'\n\n'"$(cat $RUN_DIR/$PROGRAM._Logger.$SCRIPT_PID.$TSTAMP)"
fi
fi fi
if [ $ERROR_ALERT == true ]; then if [ $ERROR_ALERT == true ]; then
@@ -625,6 +652,22 @@ function Spinner {
fi fi
} }
function _PerfProfiler { #__WITH_PARANOIA_DEBUG
local perfString #__WITH_PARANOIA_DEBUG
#__WITH_PARANOIA_DEBUG
perfString=$(ps -p $$ -o args,pid,ppid,%cpu,%mem,time,etime,state,wchan) #__WITH_PARANOIA_DEBUG
#__WITH_PARANOIA_DEBUG
for i in $(pgrep -P $$); do #__WITH_PARANOIA_DEBUG
perfString="$perfString\n"$(ps -p $i -o args,pid,ppid,%cpu,%mem,time,etime,state,wchan | tail -1) #__WITH_PARANOIA_DEBUG
done #__WITH_PARANOIA_DEBUG
#__WITH_PARANOIA_DEBUG
if type iostat > /dev/null 2>&1; then #__WITH_PARANOIA_DEBUG
perfString="$perfString\n"$(iostat) #__WITH_PARANOIA_DEBUG
fi #__WITH_PARANOIA_DEBUG
#__WITH_PARANOIA_DEBUG
Logger "PerfProfiler:\n$perfString" "PARANOIA_DEBUG" #__WITH_PARANOIA_DEBUG
} #__WITH_PARANOIA_DEBUG
# Time control function for background processes, suitable for multiple synchronous processes # Time control function for background processes, suitable for multiple synchronous processes
# Fills a global variable called WAIT_FOR_TASK_COMPLETION_$callerName that contains list of failed pids in format pid1:result1;pid2:result2 # Fills a global variable called WAIT_FOR_TASK_COMPLETION_$callerName that contains list of failed pids in format pid1:result1;pid2:result2
@@ -757,6 +800,11 @@ function WaitForTaskCompletion {
pidsArray=("${newPidsArray[@]}") pidsArray=("${newPidsArray[@]}")
# Trivial wait time for bash to not eat up all CPU # Trivial wait time for bash to not eat up all CPU
sleep $sleepTime sleep $sleepTime
if [ "$_PERF_PROFILER" == "yes" ]; then ##__WITH_PARANOIA_DEBUG
_PerfProfiler ##__WITH_PARANOIA_DEBUG
fi ##__WITH_PARANOIA_DEBUG
done done
Logger "${FUNCNAME[0]} ended for [$callerName] using [$pidCount] subprocesses with [$errorcount] errors." "PARANOIA_DEBUG" #__WITH_PARANOIA_DEBUG Logger "${FUNCNAME[0]} ended for [$callerName] using [$pidCount] subprocesses with [$errorcount] errors." "PARANOIA_DEBUG" #__WITH_PARANOIA_DEBUG
@@ -922,6 +970,10 @@ function ParallelExec {
# Trivial wait time for bash to not eat up all CPU # Trivial wait time for bash to not eat up all CPU
sleep $sleepTime sleep $sleepTime
if [ "$_PERF_PROFILER" == "yes" ]; then ##__WITH_PARANOIA_DEBUG
_PerfProfiler ##__WITH_PARANOIA_DEBUG
fi ##__WITH_PARANOIA_DEBUG
done done
return $errorCount return $errorCount
@@ -1084,6 +1136,8 @@ function ArrayContains () {
#### GetLocalOS SUBSET #### #### GetLocalOS SUBSET ####
function GetLocalOS { function GetLocalOS {
local localOsVar local localOsVar
local localOsName
local localOsVer
# There's no good way to tell if currently running in BusyBox shell. Using sluggish way. # There's no good way to tell if currently running in BusyBox shell. Using sluggish way.
if ls --help 2>&1 | grep -i "BusyBox" > /dev/null; then if ls --help 2>&1 | grep -i "BusyBox" > /dev/null; then
@@ -1114,7 +1168,7 @@ function GetLocalOS {
*"BSD"*) *"BSD"*)
LOCAL_OS="BSD" LOCAL_OS="BSD"
;; ;;
*"MINGW32"*|*"MSYS"*) *"MINGW32"*|*"MINGW64"*|*"MSYS"*)
LOCAL_OS="msys" LOCAL_OS="msys"
;; ;;
*"CYGWIN"*) *"CYGWIN"*)
@@ -1140,15 +1194,78 @@ function GetLocalOS {
exit 1 exit 1
;; ;;
esac esac
if [ "$_OFUNCTIONS_VERSION" != "" ]; then
Logger "Local OS: [$localOsVar]." "DEBUG" # Get linux versions
if [ -f "/etc/os-release" ]; then
localOsName=$(GetConfFileValue "/etc/os-release" "NAME")
localOsVer=$(GetConfFileValue "/etc/os-release" "VERSION")
fi fi
# Add a global variable for statistics in installer # Add a global variable for statistics in installer
LOCAL_OS_FULL="$localOsVar" LOCAL_OS_FULL="$localOsVar ($localOsName $localOsVer)"
if [ "$_OFUNCTIONS_VERSION" != "" ]; then
Logger "Local OS: [$LOCAL_OS_FULL]." "DEBUG"
fi
} }
#### GetLocalOS SUBSET END #### #### GetLocalOS SUBSET END ####
#__BEGIN_WITH_PARANOIA_DEBUG
function __CheckArguments {
# Checks the number of arguments of a function and raises an error if some are missing
if [ "$_DEBUG" == "yes" ]; then
local numberOfArguments="${1}" # Number of arguments the tested function should have, can be a number of a range, eg 0-2 for zero to two arguments
local numberOfGivenArguments="${2}" # Number of arguments that have been passed
local minArgs
local maxArgs
# All arguments of the function to check are passed as array in ${3} (the function call waits for $@)
# If any of the arguments contains spaces, bash things there are two aguments
# In order to avoid this, we need to iterate over ${3} and count
callerName="${FUNCNAME[1]}"
local iterate=3
local fetchArguments=true
local argList=""
local countedArguments
while [ $fetchArguments == true ]; do
cmd='argument=${'$iterate'}'
eval $cmd
if [ "$argument" == "" ]; then
fetchArguments=false
else
argList="$argList[Argument $((iterate-2)): $argument] "
iterate=$((iterate+1))
fi
done
countedArguments=$((iterate-3))
if [ $(IsInteger "$numberOfArguments") -eq 1 ]; then
minArgs=$numberOfArguments
maxArgs=$numberOfArguments
else
IFS='-' read minArgs maxArgs <<< "$numberOfArguments"
fi
Logger "Entering function [$callerName]." "PARANOIA_DEBUG"
if ! ([ $countedArguments -ge $minArgs ] && [ $countedArguments -le $maxArgs ]); then
Logger "Function $callerName may have inconsistent number of arguments. Expected min: $minArgs, max: $maxArgs, count: $countedArguments, bash seen: $numberOfGivenArguments." "ERROR"
Logger "$callerName arguments: $argList" "ERROR"
else
if [ ! -z "$argList" ]; then
Logger "$callerName arguments: $argList" "PARANOIA_DEBUG"
fi
fi
fi
}
#__END_WITH_PARANOIA_DEBUG
#### OFUNCTIONS MINI SUBSET END #### #### OFUNCTIONS MINI SUBSET END ####
function GetRemoteOS { function GetRemoteOS {
@@ -1160,10 +1277,15 @@ function GetRemoteOS {
local remoteOsVar local remoteOsVar
$SSH_CMD bash -s << 'ENDSSH' >> "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP" 2>&1 $SSH_CMD env LC_ALL=C env _REMOTE_TOKEN="$_REMOTE_TOKEN" bash -s << 'ENDSSH' >> "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP" 2>&1
function GetOs { function GetOs {
local localOsVar local localOsVar
local localOsName
local localOsVer
local osInfo="/etc/os-release"
# There's no good way to tell if currently running in BusyBox shell. Using sluggish way. # There's no good way to tell if currently running in BusyBox shell. Using sluggish way.
if ls --help 2>&1 | grep -i "BusyBox" > /dev/null; then if ls --help 2>&1 | grep -i "BusyBox" > /dev/null; then
@@ -1182,7 +1304,15 @@ function GetOs {
fi fi
fi fi
fi fi
echo "$localOsVar" # Get linux versions
if [ -f "$osInfo" ]; then
localOsName=$(grep "^NAME=" "$osInfo")
localOsName="${localOsName##*=}"
localOsVer=$(grep "^VERSION=" "$osInfo")
localOsVer="${localOsVer##*=}"
fi
echo "$localOsVar ($localOsName $localOsVer)"
} }
GetOs GetOs
@@ -1201,7 +1331,7 @@ ENDSSH
*"BSD"*) *"BSD"*)
REMOTE_OS="BSD" REMOTE_OS="BSD"
;; ;;
*"MINGW32"*|*"MSYS"*) *"MINGW32"*|*"MINGW64"*|*"MSYS"*)
REMOTE_OS="msys" REMOTE_OS="msys"
;; ;;
*"CYGWIN"*) *"CYGWIN"*)
@@ -1272,6 +1402,12 @@ function RunRemoteCommand {
local hardMaxTime="${2}" # Max time to wait for command to compleet local hardMaxTime="${2}" # Max time to wait for command to compleet
__CheckArguments 2 $# "$@" #__WITH_PARANOIA_DEBUG __CheckArguments 2 $# "$@" #__WITH_PARANOIA_DEBUG
if [ "$REMOTE_OPERATION" != "yes" ]; then
Logger "Ignoring remote command [$command] because remote host is not configured." "WARN"
return 0
fi
CheckConnectivity3rdPartyHosts CheckConnectivity3rdPartyHosts
CheckConnectivityRemoteHost CheckConnectivityRemoteHost
if [ $_DRYRUN == true ]; then if [ $_DRYRUN == true ]; then
@@ -1280,7 +1416,7 @@ function RunRemoteCommand {
fi fi
Logger "Running command [$command] on remote host." "NOTICE" Logger "Running command [$command] on remote host." "NOTICE"
cmd=$SSH_CMD' "$command" > "'$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP'" 2>&1' cmd=$SSH_CMD' "env LC_ALL=C env _REMOTE_TOKEN="'$_REMOTE_TOKEN'" $command" > "'$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP'" 2>&1'
Logger "cmd: $cmd" "DEBUG" Logger "cmd: $cmd" "DEBUG"
eval "$cmd" & eval "$cmd" &
WaitForTaskCompletion $! 0 $hardMaxTime $SLEEP_TIME $KEEP_LOGGING true true false WaitForTaskCompletion $! 0 $hardMaxTime $SLEEP_TIME $KEEP_LOGGING true true false
@@ -1391,62 +1527,6 @@ function CheckConnectivity3rdPartyHosts {
fi #__WITH_PARANOIA_DEBUG fi #__WITH_PARANOIA_DEBUG
} }
#__BEGIN_WITH_PARANOIA_DEBUG
function __CheckArguments {
# Checks the number of arguments of a function and raises an error if some are missing
if [ "$_DEBUG" == "yes" ]; then
local numberOfArguments="${1}" # Number of arguments the tested function should have, can be a number of a range, eg 0-2 for zero to two arguments
local numberOfGivenArguments="${2}" # Number of arguments that have been passed
local minArgs
local maxArgs
# All arguments of the function to check are passed as array in ${3} (the function call waits for $@)
# If any of the arguments contains spaces, bash things there are two aguments
# In order to avoid this, we need to iterate over ${3} and count
callerName="${FUNCNAME[1]}"
local iterate=3
local fetchArguments=true
local argList=""
local countedArguments
while [ $fetchArguments == true ]; do
cmd='argument=${'$iterate'}'
eval $cmd
if [ "$argument" == "" ]; then
fetchArguments=false
else
argList="$argList[Argument $((iterate-2)): $argument] "
iterate=$((iterate+1))
fi
done
countedArguments=$((iterate-3))
if [ $(IsInteger "$numberOfArguments") -eq 1 ]; then
minArgs=$numberOfArguments
maxArgs=$numberOfArguments
else
IFS='-' read minArgs maxArgs <<< "$numberOfArguments"
fi
Logger "Entering function [$callerName]." "PARANOIA_DEBUG"
if ! ([ $countedArguments -ge $minArgs ] && [ $countedArguments -le $maxArgs ]); then
Logger "Function $callerName may have inconsistent number of arguments. Expected min: $minArgs, max: $maxArgs, count: $countedArguments, bash seen: $numberOfGivenArguments." "ERROR"
Logger "$callerName arguments: $argList" "ERROR"
else
if [ ! -z "$argList" ]; then
Logger "$callerName arguments: $argList" "PARANOIA_DEBUG"
fi
fi
fi
}
#__END_WITH_PARANOIA_DEBUG
function RsyncPatternsAdd { function RsyncPatternsAdd {
local patternType="${1}" # exclude or include local patternType="${1}" # exclude or include
local pattern="${2}" local pattern="${2}"
@@ -1577,13 +1657,13 @@ function PostInit {
# Define remote commands # Define remote commands
if [ -f "$SSH_RSA_PRIVATE_KEY" ]; then if [ -f "$SSH_RSA_PRIVATE_KEY" ]; then
SSH_CMD="$(type -p ssh) $SSH_COMP -i $SSH_RSA_PRIVATE_KEY $SSH_OPTS $REMOTE_USER@$REMOTE_HOST -p $REMOTE_PORT" SSH_CMD="$(type -p ssh) $SSH_COMP -q -i $SSH_RSA_PRIVATE_KEY $SSH_OPTS $REMOTE_USER@$REMOTE_HOST -p $REMOTE_PORT"
SCP_CMD="$(type -p scp) $SSH_COMP -i $SSH_RSA_PRIVATE_KEY -P $REMOTE_PORT" SCP_CMD="$(type -p scp) $SSH_COMP -q -i $SSH_RSA_PRIVATE_KEY -P $REMOTE_PORT"
RSYNC_SSH_CMD="$(type -p ssh) $SSH_COMP -i $SSH_RSA_PRIVATE_KEY $SSH_OPTS -p $REMOTE_PORT" RSYNC_SSH_CMD="$(type -p ssh) $SSH_COMP -q -i $SSH_RSA_PRIVATE_KEY $SSH_OPTS -p $REMOTE_PORT"
elif [ -f "$SSH_PASSWORD_FILE" ]; then elif [ -f "$SSH_PASSWORD_FILE" ]; then
SSH_CMD="$(type -p sshpass) -f $SSH_PASSWORD_FILE $(type -p ssh) $SSH_COMP $SSH_OPTS $REMOTE_USER@$REMOTE_HOST -p $REMOTE_PORT" SSH_CMD="$(type -p sshpass) -f $SSH_PASSWORD_FILE $(type -p ssh) $SSH_COMP -q $SSH_OPTS $REMOTE_USER@$REMOTE_HOST -p $REMOTE_PORT"
SCP_CMD="$(type -p sshpass) -f $SSH_PASSWORD_FILE $(type -p scp) $SSH_COMP -P $REMOTE_PORT" SCP_CMD="$(type -p sshpass) -f $SSH_PASSWORD_FILE $(type -p scp) $SSH_COMP -q -P $REMOTE_PORT"
RSYNC_SSH_CMD="$(type -p sshpass) -f $SSH_PASSWORD_FILE $(type -p ssh) $SSH_COMP $SSH_OPTS -p $REMOTE_PORT" RSYNC_SSH_CMD="$(type -p sshpass) -f $SSH_PASSWORD_FILE $(type -p ssh) $SSH_COMP -q $SSH_OPTS -p $REMOTE_PORT"
else else
SSH_PASSWORD="" SSH_PASSWORD=""
SSH_CMD="" SSH_CMD=""
@@ -1633,7 +1713,10 @@ function SetCompression {
COMPRESSION_EXTENSION= COMPRESSION_EXTENSION=
fi fi
fi fi
ALERT_LOG_FILE="$ALERT_LOG_FILE$COMPRESSION_EXTENSION"
if [ ".${ALERT_LOG_FILE##*.}" != "$COMPRESSION_EXTENSION" ]; then
ALERT_LOG_FILE="$ALERT_LOG_FILE$COMPRESSION_EXTENSION"
fi
} }
function InitLocalOSDependingSettings { function InitLocalOSDependingSettings {
@@ -1646,6 +1729,11 @@ function InitLocalOSDependingSettings {
if [ "$LOCAL_OS" == "msys" ] || [ "$LOCAL_OS" == "Cygwin" ]; then if [ "$LOCAL_OS" == "msys" ] || [ "$LOCAL_OS" == "Cygwin" ]; then
FIND_CMD=$(dirname $BASH)/find FIND_CMD=$(dirname $BASH)/find
PING_CMD='$SYSTEMROOT\system32\ping -n 2' PING_CMD='$SYSTEMROOT\system32\ping -n 2'
# On BSD, when not root, min ping interval is 1s
elif [ "$LOCAL_OS" == "BSD" ] && [ "$LOCAL_USER" != "root" ]; then
FIND_CMD=find
PING_CMD="ping -c 2 -i 1"
else else
FIND_CMD=find FIND_CMD=find
PING_CMD="ping -c 2 -i .2" PING_CMD="ping -c 2 -i .2"
@@ -1695,7 +1783,7 @@ function InitRemoteOSDependingSettings {
fi fi
## Set rsync default arguments ## Set rsync default arguments
RSYNC_ARGS="-rltD" RSYNC_ARGS="-rltD -8"
if [ "$_DRYRUN" == true ]; then if [ "$_DRYRUN" == true ]; then
RSYNC_DRY_ARG="-n" RSYNC_DRY_ARG="-n"
DRY_WARNING="/!\ DRY RUN " DRY_WARNING="/!\ DRY RUN "
@@ -1790,4 +1878,107 @@ function ParentPid {
fi fi
} }
#### VerComp SUBSET ####
# Neat version compare function found at http://stackoverflow.com/a/4025065/2635443
# Returns 0 if equal, 1 if $1 > $2 and 2 if $1 < $2
function VerComp () {
if [ "$1" == "" ] || [ "$2" == "" ]; then
Logger "Bogus Vercomp values [$1] and [$2]." "WARN"
return 1
fi
if [[ $1 == $2 ]]
then
echo 0
return
fi
local IFS=.
local i ver1=($1) ver2=($2)
# fill empty fields in ver1 with zeros
for ((i=${#ver1[@]}; i<${#ver2[@]}; i++))
do
ver1[i]=0
done
for ((i=0; i<${#ver1[@]}; i++))
do
if [[ -z ${ver2[i]} ]]
then
# fill empty fields in ver2 with zeros
ver2[i]=0
fi
if ((10#${ver1[i]} > 10#${ver2[i]}))
then
echo 1
return
fi
if ((10#${ver1[i]} < 10#${ver2[i]}))
then
echo 2
return
fi
done
echo 0
return
}
#### VerComp SUBSET END ####
#### GetConfFileValue SUBSET ####
function GetConfFileValue () {
local file="${1}"
local name="${2}"
local value
value=$(grep "^$name=" "$file")
if [ $? == 0 ]; then
value="${value##*=}"
echo "$value"
else
Logger "Cannot get value for [$name] in config file [$file]." "ERROR"
fi
}
#### GetConfFileValue SUBSET END ####
#### SetConfFileValue SUBSET ####
function SetConfFileValue () {
local file="${1}"
local name="${2}"
local value="${3}"
local separator="${4:-#}"
if grep "^$name=" "$file" > /dev/null; then
# Using -i.tmp for BSD compat
sed -i.tmp "s$separator^$name=.*$separator$name=$value$separator" "$file"
rm -f "$file.tmp"
Logger "Set [$name] to [$value] in config file [$file]." "DEBUG"
else
Logger "Cannot set value [$name] to [$value] in config file [$file]." "ERROR"
fi
}
#### SetConfFileValue SUBSET END ####
# Function can replace [ -f /some/file* ] tests
# Modified version of http://stackoverflow.com/a/6364244/2635443
function WildcardFileExists () {
local file="${1}"
local exists=0
for f in $file; do
## Check if the glob gets expanded to existing files.
## If not, f here will be exactly the pattern above
## and the exists test will evaluate to false.
if [ -e "$f" ]; then
exists=1
break
fi
done
if [ $exists -eq 1 ]; then
echo 1
else
echo 0
fi
}
#### OFUNCTIONS FULL SUBSET END #### #### OFUNCTIONS FULL SUBSET END ####

View File

@@ -27,7 +27,7 @@ SQL_STORAGE="${HOME}/obackup-storage/sql-pull"
FILE_STORAGE="${HOME}/obackup-storage/files-pull" FILE_STORAGE="${HOME}/obackup-storage/files-pull"
## Encryption ## Encryption
ENCRYPTION=yes ENCRYPTION=no
## Backup encryption needs a temporary storage space in order to encrypt files before sending them (absolute paths of the local or remote system) ## Backup encryption needs a temporary storage space in order to encrypt files before sending them (absolute paths of the local or remote system)
CRYPT_STORAGE="${HOME}/obackup-storage/crypt-pull" CRYPT_STORAGE="${HOME}/obackup-storage/crypt-pull"
@@ -61,6 +61,11 @@ REMOTE_SYSTEM_URI="ssh://root@localhost:49999/"
## You can specify a RSA key (please use full path). If not defined, the default ~/.ssh/id_rsa will be used. See documentation for further information. ## You can specify a RSA key (please use full path). If not defined, the default ~/.ssh/id_rsa will be used. See documentation for further information.
SSH_RSA_PRIVATE_KEY="${HOME}/.ssh/id_rsa_local" SSH_RSA_PRIVATE_KEY="${HOME}/.ssh/id_rsa_local"
## Alternatively, you may specify an SSH password file (less secure). Needs sshpass utility installed.
SSH_PASSWORD_FILE=""
_REMOTE_TOKEN=SomeAlphaNumericToken9
## ssh compression should be used unless your remote connection is good enough (LAN) ## ssh compression should be used unless your remote connection is good enough (LAN)
SSH_COMPRESSION=yes SSH_COMPRESSION=yes
@@ -89,7 +94,7 @@ SQL_USER=root
DATABASES_ALL=yes DATABASES_ALL=yes
DATABASES_ALL_EXCLUDE_LIST="test;information_schema;zarafa_prod" DATABASES_ALL_EXCLUDE_LIST="test;information_schema;zarafa_prod"
## Alternatively, if DATABASES_ALL=no, you can specify a list of databases to backup separated by spaces. ## Alternatively, if DATABASES_ALL=no, you can specify a list of databases to backup separated by spaces.
DATABASES_LIST="mysql" DATABASES_LIST=mysql
## Max backup execution time per Database task. Soft max exec time generates a warning only. Hard max exec time generates a warning and stops current backup task. ## Max backup execution time per Database task. Soft max exec time generates a warning only. Hard max exec 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. ## If a task gets stopped, next one in the task list gets executed. Time is specified in seconds.
@@ -112,8 +117,8 @@ COMPRESSION_LEVEL=3
## You can exclude directories from the avove backup task creation, ex: avoid backing up "/home/dir2" by adding it to RECURSIVE_EXCLUDE_LIST. ## You can exclude directories from the avove backup task creation, ex: avoid backing up "/home/dir2" by adding it to RECURSIVE_EXCLUDE_LIST.
## Directories backup list. List of semicolon separated directories that will be backed up. ## Directories backup list. List of semicolon separated directories that will be backed up.
DIRECTORY_LIST="${HOME}/obackup-testdata/testData" DIRECTORY_LIST=/root/obackup-testdata/testData
RECURSIVE_DIRECTORY_LIST="${HOME}/obackup-testdata/testDataRecursive" RECURSIVE_DIRECTORY_LIST=/root/obackup-testdata/testDataRecursive
RECURSIVE_EXCLUDE_LIST="${HOME}/obackup-testdata/testDataRecursive/Excluded" RECURSIVE_EXCLUDE_LIST="${HOME}/obackup-testdata/testDataRecursive/Excluded"
## Rsync exclude / include order (the option set here will be set first, eg: include will make include then exclude patterns) ## Rsync exclude / include order (the option set here will be set first, eg: include will make include then exclude patterns)

View File

@@ -27,7 +27,7 @@ SQL_STORAGE="${HOME}/obackup-storage/sql-push"
FILE_STORAGE="${HOME}/obackup-storage/files-push" FILE_STORAGE="${HOME}/obackup-storage/files-push"
## Encryption ## Encryption
ENCRYPTION=yes ENCRYPTION=no
## Backup encryption needs a temporary storage space in order to encrypt files before sending them (absolute paths of the local or remote system) ## Backup encryption needs a temporary storage space in order to encrypt files before sending them (absolute paths of the local or remote system)
CRYPT_STORAGE="${HOME}/obackup-storage/crypt-push" CRYPT_STORAGE="${HOME}/obackup-storage/crypt-push"
@@ -61,6 +61,11 @@ REMOTE_SYSTEM_URI="ssh://root@localhost:49999/"
## You can specify a RSA key (please use full path). If not defined, the default ~/.ssh/id_rsa will be used. See documentation for further information. ## You can specify a RSA key (please use full path). If not defined, the default ~/.ssh/id_rsa will be used. See documentation for further information.
SSH_RSA_PRIVATE_KEY="${HOME}/.ssh/id_rsa_local" SSH_RSA_PRIVATE_KEY="${HOME}/.ssh/id_rsa_local"
## Alternatively, you may specify an SSH password file (less secure). Needs sshpass utility installed.
SSH_PASSWORD_FILE=""
_REMOTE_TOKEN=SomeAlphaNumericToken9
## ssh compression should be used unless your remote connection is good enough (LAN) ## ssh compression should be used unless your remote connection is good enough (LAN)
SSH_COMPRESSION=yes SSH_COMPRESSION=yes
@@ -89,7 +94,7 @@ SQL_USER=root
DATABASES_ALL=yes DATABASES_ALL=yes
DATABASES_ALL_EXCLUDE_LIST="test;information_schema;zarafa_prod" DATABASES_ALL_EXCLUDE_LIST="test;information_schema;zarafa_prod"
## Alternatively, if DATABASES_ALL=no, you can specify a list of databases to backup separated by spaces. ## Alternatively, if DATABASES_ALL=no, you can specify a list of databases to backup separated by spaces.
DATABASES_LIST="mysql" DATABASES_LIST=mysql
## Max backup execution time per Database task. Soft max exec time generates a warning only. Hard max exec time generates a warning and stops current backup task. ## Max backup execution time per Database task. Soft max exec time generates a warning only. Hard max exec 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. ## If a task gets stopped, next one in the task list gets executed. Time is specified in seconds.
@@ -112,8 +117,8 @@ COMPRESSION_LEVEL=3
## You can exclude directories from the avove backup task creation, ex: avoid backing up "/home/dir2" by adding it to RECURSIVE_EXCLUDE_LIST. ## You can exclude directories from the avove backup task creation, ex: avoid backing up "/home/dir2" by adding it to RECURSIVE_EXCLUDE_LIST.
## Directories backup list. List of semicolon separated directories that will be backed up. ## Directories backup list. List of semicolon separated directories that will be backed up.
DIRECTORY_LIST="${HOME}/obackup-testdata/testData" DIRECTORY_LIST=/root/obackup-testdata/testData
RECURSIVE_DIRECTORY_LIST="${HOME}/obackup-testdata/testDataRecursive" RECURSIVE_DIRECTORY_LIST=/root/obackup-testdata/testDataRecursive
RECURSIVE_EXCLUDE_LIST="${HOME}/obackup-testdata/testDataRecursive/Excluded" RECURSIVE_EXCLUDE_LIST="${HOME}/obackup-testdata/testDataRecursive/Excluded"
## Rsync exclude / include order (the option set here will be set first, eg: include will make include then exclude patterns) ## Rsync exclude / include order (the option set here will be set first, eg: include will make include then exclude patterns)

View File

@@ -2,7 +2,7 @@
#TODO Encrypted Pull runs on F25 fail for decryption #TODO Encrypted Pull runs on F25 fail for decryption
## obackup basic tests suite 2017010201 ## obackup basic tests suite 2017040801
OBACKUP_DIR="$(pwd)" OBACKUP_DIR="$(pwd)"
OBACKUP_DIR=${OBACKUP_DIR%%/dev*} OBACKUP_DIR=${OBACKUP_DIR%%/dev*}
@@ -71,42 +71,10 @@ OBACKUP_VERSION=2.x
OBACKUP_MIN_VERSION=x OBACKUP_MIN_VERSION=x
OBACKUP_IS_STABLE=maybe OBACKUP_IS_STABLE=maybe
# Setup an array with all function modes
#declare -Ag osyncParameters
function GetConfFileValue () {
local file="${1}"
local name="${2}"
local value
value=$(grep "^$name=" "$file")
if [ $? == 0 ]; then
value="${value##*=}"
echo "$value"
else
assertEquals "$name does not exist in [$file]." "1" "0"
fi
}
function SetConfFileValue () {
local file="${1}"
local name="${2}"
local value="${3}"
if grep "^$name=" "$file" > /dev/null; then
# Using -i.tmp for BSD compat
sed -i.tmp "s#^$name=.*#$name=$value#" "$file"
rm -f "$file.tmp"
assertEquals "Set $name to [$value]." "0" $?
else
assertEquals "$name does not exist in [$file]." "1" "0"
fi
}
function SetupSSH { function SetupSSH {
echo -e 'y\n'| ssh-keygen -t rsa -b 2048 -N "" -f "${HOME}/.ssh/id_rsa_local" echo -e 'y\n'| ssh-keygen -t rsa -b 2048 -N "" -f "${HOME}/.ssh/id_rsa_local"
if ! grep "$(cat ${HOME}/.ssh/id_rsa_local.pub)" "${HOME}/.ssh/authorized_keys"; then if ! grep "$(cat ${HOME}/.ssh/id_rsa_local.pub)" "${HOME}/.ssh/authorized_keys"; then
cat "${HOME}/.ssh/id_rsa_local.pub" >> "${HOME}/.ssh/authorized_keys" echo "from=\"*\",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty,command=\"/usr/local/bin/ssh_filter.sh SomeAlphaNumericToken9\" $(cat ${HOME}/.ssh/id_rsa_local.pub)" >> "${HOME}/.ssh/authorized_keys"
fi fi
chmod 600 "${HOME}/.ssh/authorized_keys" chmod 600 "${HOME}/.ssh/authorized_keys"
@@ -126,7 +94,7 @@ function RemoveSSH {
if [ -f "${HOME}/.ssh/id_rsa_local" ]; then if [ -f "${HOME}/.ssh/id_rsa_local" ]; then
pubkey=$(cat "${HOME}/.ssh/id_rsa_local.pub") pubkey=$(cat "${HOME}/.ssh/id_rsa_local.pub")
sed -i.bak "#$pubkey#d" "${HOME}/.ssh/authorized_keys" sed -i.bak "s|.*$pubkey.*||g" "${HOME}/.ssh/authorized_keys"
rm -f "${HOME}/.ssh/{id_rsa_local.pub,id_rsa_local}" rm -f "${HOME}/.ssh/{id_rsa_local.pub,id_rsa_local}"
fi fi
} }
@@ -138,6 +106,8 @@ function SetupGPG {
CRYPT_TOOL=gpg CRYPT_TOOL=gpg
else else
echo "No gpg support" echo "No gpg support"
assertEquals "Failed to detect gpg" "1" $?
return
fi fi
echo "Crypt tool=$CRYPT_TOOL" echo "Crypt tool=$CRYPT_TOOL"
@@ -164,7 +134,7 @@ EOF
# Setup fast entropy # Setup fast entropy
if type rngd > /dev/null 2>&1; then if type rngd > /dev/null 2>&1; then
rngd -r /dev/urandom $SUDO_CMD rngd -r /dev/urandom
else else
echo "No rngd support" echo "No rngd support"
fi fi
@@ -183,6 +153,10 @@ function oneTimeSetUp () {
START_TIME=$SECONDS START_TIME=$SECONDS
source "$DEV_DIR/ofunctions.sh" source "$DEV_DIR/ofunctions.sh"
# Set default umask because ofunctions set 0077
umask 0022
GetLocalOS GetLocalOS
echo "Detected OS: $LOCAL_OS" echo "Detected OS: $LOCAL_OS"
@@ -219,6 +193,17 @@ function oneTimeSetUp () {
SSH_PORT=22 SSH_PORT=22
fi fi
#TODO: Assuming that macos has the same syntax than bsd here
if [ "$LOCAL_OS" == "msys" ] || [ "$LOCAL_OS" == "Cygwin" ]; then
SUDO_CMD=""
elif [ "$LOCAL_OS" == "BSD" ] || [ "$LOCAL_OS" == "MacOSX" ]; then
SUDO_CMD=""
else
SUDO_CMD="sudo"
fi
SetupGPG SetupGPG
if [ "$SKIP_REMOTE" != "yes" ]; then if [ "$SKIP_REMOTE" != "yes" ]; then
SetupSSH SetupSSH
@@ -255,6 +240,10 @@ function oneTimeTearDown () {
#rm -rf "$TARGET_DIR" #rm -rf "$TARGET_DIR"
rm -f "$TMP_FILE" rm -f "$TMP_FILE"
cd "$OBACKUP_DIR"
$SUDO_CMD ./install.sh --remove --silent --no-stats
assertEquals "Uninstall failed" "0" $?
ELAPSED_TIME=$(($SECONDS - $START_TIME)) ELAPSED_TIME=$(($SECONDS - $START_TIME))
echo "It took $ELAPSED_TIME seconds to run these tests." echo "It took $ELAPSED_TIME seconds to run these tests."
} }
@@ -275,7 +264,8 @@ function setUp () {
touch "$SOURCE_DIR/$RECURSIVE_DIR/$N_FILE_1" touch "$SOURCE_DIR/$RECURSIVE_DIR/$N_FILE_1"
touch "$SOURCE_DIR/$RECURSIVE_DIR/$R_DIR_1/$R_FILE_1" touch "$SOURCE_DIR/$RECURSIVE_DIR/$R_DIR_1/$R_FILE_1"
touch "$SOURCE_DIR/$RECURSIVE_DIR/$R_DIR_2/$R_FILE_2" touch "$SOURCE_DIR/$RECURSIVE_DIR/$R_DIR_2/$R_FILE_2"
dd if=/dev/urandom of="$SOURCE_DIR/$RECURSIVE_DIR/$R_DIR_3/$R_FILE_3" bs=1M count=2 dd if=/dev/urandom of="$SOURCE_DIR/$RECURSIVE_DIR/$R_DIR_3/$R_FILE_3" bs=1048576 count=2
assertEquals "dd file creation" "0" $?
touch "$SOURCE_DIR/$RECURSIVE_DIR/$R_DIR_3/$EXCLUDED_FILE" touch "$SOURCE_DIR/$RECURSIVE_DIR/$R_DIR_3/$EXCLUDED_FILE"
FilePresence=( FilePresence=(
@@ -307,9 +297,13 @@ function setUp () {
function test_Merge () { function test_Merge () {
cd "$DEV_DIR" cd "$DEV_DIR"
./merge.sh ./merge.sh obackup
assertEquals "Merging code" "0" $? assertEquals "Merging code" "0" $?
cd "$OBACKUP_DIR"
$SUDO_CMD ./install.sh --silent --no-stats
assertEquals "Install failed" "0" $?
# Set obackup version to stable while testing to avoid warning message # Set obackup version to stable while testing to avoid warning message
SetConfFileValue "$OBACKUP_DIR/$OBACKUP_EXECUTABLE" "IS_STABLE" "yes" SetConfFileValue "$OBACKUP_DIR/$OBACKUP_EXECUTABLE" "IS_STABLE" "yes"
} }

View File

@@ -2,7 +2,7 @@
###### obackup - Local or Remote, push or pull backup script for files & mysql databases ###### obackup - Local or Remote, push or pull backup script for files & mysql databases
###### (C) 2013-2016 by Orsiris de Jong (www.netpower.fr) ###### (C) 2013-2016 by Orsiris de Jong (www.netpower.fr)
###### obackup v2.1x config file rev 2017010201 ###### obackup v2.1x config file rev 2017020901
###### GENERAL BACKUP OPTIONS ###### GENERAL BACKUP OPTIONS
@@ -38,7 +38,7 @@ CRYPT_STORAGE=/home/storage/backup/crpyt
## GPG recipient (pubkey for this recipient must exist, see gpg2 --list-keys or gpg --list-keys ## GPG recipient (pubkey for this recipient must exist, see gpg2 --list-keys or gpg --list-keys
GPG_RECIPIENT="John Doe" GPG_RECIPIENT="John Doe"
## Use n CPUs for encryption / decryption where n is an integer ## Use n CPUs for encryption / decryption where n is an integer. Defaults to 1
PARALLEL_ENCRYPTION_PROCESSES= PARALLEL_ENCRYPTION_PROCESSES=
## Create backup directories if they do not exist ## Create backup directories if they do not exist
@@ -70,6 +70,9 @@ SSH_RSA_PRIVATE_KEY="${HOME}/.ssh/id_rsa"
## Alternatively, you may specify an SSH password file (less secure). Needs sshpass utility installed. ## Alternatively, you may specify an SSH password file (less secure). Needs sshpass utility installed.
SSH_PASSWORD_FILE="" SSH_PASSWORD_FILE=""
## When using ssh filter, you must specify a remote token matching the one setup in authorized_keys
_REMOTE_TOKEN=SomeAlphaNumericToken9
## ssh compression should be used unless your remote connection is good enough (LAN) ## ssh compression should be used unless your remote connection is good enough (LAN)
SSH_COMPRESSION=yes SSH_COMPRESSION=yes
@@ -198,6 +201,11 @@ RSYNC_EXECUTABLE=rsync
## Alert email addresses separated by a space character ## Alert email addresses separated by a space character
DESTINATION_MAILS="your@mail.address" DESTINATION_MAILS="your@mail.address"
## Optional change of mail body encoding (using iconv)
## By default, all mails are sent in UTF-8 format without header (because of maximum compatibility of all platforms)
## You may specify an optional encoding here (like "ISO-8859-1" or whatever iconv can handle)
MAIL_BODY_CHARSET=""
## Environment specific mail options (used with busybox sendemail, mailsend.exe from muquit, http://github.com/muquit/mailsend or sendemail.exe from Brandon Zehm, http://caspian.dotconf.net/menu/Software/SendEmail) ## Environment specific mail options (used with busybox sendemail, mailsend.exe from muquit, http://github.com/muquit/mailsend or sendemail.exe from Brandon Zehm, http://caspian.dotconf.net/menu/Software/SendEmail)
SENDER_MAIL="alert@your.system.tld" SENDER_MAIL="alert@your.system.tld"
SMTP_SERVER=smtp.your.isp.tld SMTP_SERVER=smtp.your.isp.tld

View File

@@ -1,12 +1,18 @@
#!/usr/bin/env bash #!/usr/bin/env bash
## Installer script suitable for osync / obackup / pmocr
_OFUNCTIONS_BOOTSTRAP=true _OFUNCTIONS_BOOTSTRAP=true
PROGRAM=obackup PROGRAM=obackup
PROGRAM_VERSION=2.1-beta1
PROGRAM_VERSION=$(grep "PROGRAM_VERSION=" $PROGRAM.sh)
PROGRAM_VERSION=${PROGRAM_VERSION#*=}
PROGRAM_BINARY=$PROGRAM".sh" PROGRAM_BINARY=$PROGRAM".sh"
PROGRAM_BATCH=$PROGRAM"-batch.sh" PROGRAM_BATCH=$PROGRAM"-batch.sh"
SCRIPT_BUILD=2016122701 SSH_FILTER="ssh_filter.sh"
SCRIPT_BUILD=2017041701
## osync / obackup / pmocr / zsnap install script ## osync / obackup / pmocr / zsnap install script
## Tested on RHEL / CentOS 6 & 7, Fedora 23, Debian 7 & 8, Mint 17 and FreeBSD 8, 10 and 11 ## Tested on RHEL / CentOS 6 & 7, Fedora 23, Debian 7 & 8, Mint 17 and FreeBSD 8, 10 and 11
@@ -22,19 +28,20 @@ SERVICE_DIR_INIT=$FAKEROOT/etc/init.d
SERVICE_DIR_SYSTEMD_SYSTEM=$FAKEROOT/lib/systemd/system SERVICE_DIR_SYSTEMD_SYSTEM=$FAKEROOT/lib/systemd/system
SERVICE_DIR_SYSTEMD_USER=$FAKEROOT/etc/systemd/user SERVICE_DIR_SYSTEMD_USER=$FAKEROOT/etc/systemd/user
## osync specific code if [ "$PROGRAM" == "osync" ]; then
OSYNC_SERVICE_FILE_INIT="osync-srv" SERVICE_NAME="osync-srv"
OSYNC_SERVICE_FILE_SYSTEMD_SYSTEM="osync-srv@.service" elif [ "$PROGRAM" == "pmocr" ]; then
OSYNC_SERVICE_FILE_SYSTEMD_USER="osync-srv@.service.user" SERVICE_NAME="pmocr-srv"
fi
## pmocr specfic code SERVICE_FILE_INIT="$SERVICE_NAME"
PMOCR_SERVICE_FILE_INIT="pmocr-srv" SERVICE_FILE_SYSTEMD_SYSTEM="$SERVICE_NAME@.service"
PMOCR_SERVICE_FILE_SYSTEMD_SYSTEM="pmocr-srv@.service" SERVICE_FILE_SYSTEMD_USER="$SERVICE_NAME@.service.user"
## Generic code ## Generic code
## Default log file ## Default log file
if [ -w $FAKEROOT/var/log ]; then if [ -w "$FAKEROOT/var/log" ]; then
LOG_FILE="$FAKEROOT/var/log/$PROGRAM-install.log" LOG_FILE="$FAKEROOT/var/log/$PROGRAM-install.log"
elif ([ "$HOME" != "" ] && [ -w "$HOME" ]); then elif ([ "$HOME" != "" ] && [ -w "$HOME" ]); then
LOG_FILE="$HOME/$PROGRAM-install.log" LOG_FILE="$HOME/$PROGRAM-install.log"
@@ -83,6 +90,8 @@ function UrlEncode {
} }
function GetLocalOS { function GetLocalOS {
local localOsVar local localOsVar
local localOsName
local localOsVer
# There's no good way to tell if currently running in BusyBox shell. Using sluggish way. # There's no good way to tell if currently running in BusyBox shell. Using sluggish way.
if ls --help 2>&1 | grep -i "BusyBox" > /dev/null; then if ls --help 2>&1 | grep -i "BusyBox" > /dev/null; then
@@ -113,7 +122,7 @@ function GetLocalOS {
*"BSD"*) *"BSD"*)
LOCAL_OS="BSD" LOCAL_OS="BSD"
;; ;;
*"MINGW32"*|*"MSYS"*) *"MINGW32"*|*"MINGW64"*|*"MSYS"*)
LOCAL_OS="msys" LOCAL_OS="msys"
;; ;;
*"CYGWIN"*) *"CYGWIN"*)
@@ -139,13 +148,34 @@ function GetLocalOS {
exit 1 exit 1
;; ;;
esac esac
if [ "$_OFUNCTIONS_VERSION" != "" ]; then
Logger "Local OS: [$localOsVar]." "DEBUG" # Get linux versions
if [ -f "/etc/os-release" ]; then
localOsName=$(GetConfFileValue "/etc/os-release" "NAME")
localOsVer=$(GetConfFileValue "/etc/os-release" "VERSION")
fi fi
# Add a global variable for statistics in installer # Add a global variable for statistics in installer
LOCAL_OS_FULL="$localOsVar" LOCAL_OS_FULL="$localOsVar ($localOsName $localOsVer)"
if [ "$_OFUNCTIONS_VERSION" != "" ]; then
Logger "Local OS: [$LOCAL_OS_FULL]." "DEBUG"
fi
} }
function GetConfFileValue () {
local file="${1}"
local name="${2}"
local value
value=$(grep "^$name=" "$file")
if [ $? == 0 ]; then
value="${value##*=}"
echo "$value"
else
Logger "Cannot get value for [$name] in config file [$file]." "ERROR"
fi
}
function SetLocalOSSettings { function SetLocalOSSettings {
USER=root USER=root
@@ -167,7 +197,7 @@ function SetLocalOSSettings {
;; ;;
esac esac
if [ "$LOCAL_OS" == "Android" ] || [ "$LOCAL_OS" == "MacOSX" ] || [ "$LOCAL_OS" == "BusyBox" ]; then if [ "$LOCAL_OS" == "Android" ] || [ "$LOCAL_OS" == "BusyBox" ]; then
QuickLogger "Cannot be installed on [$LOCAL_OS]. Please use $PROGRAM.sh directly." QuickLogger "Cannot be installed on [$LOCAL_OS]. Please use $PROGRAM.sh directly."
exit 1 exit 1
fi fi
@@ -193,126 +223,131 @@ function GetInit {
fi fi
} }
function CreateConfDir { function CreateDir {
if [ ! -d "$CONF_DIR" ]; then local dir="${1}"
mkdir "$CONF_DIR"
if [ ! -d "$dir" ]; then
mkdir "$dir"
if [ $? == 0 ]; then if [ $? == 0 ]; then
QuickLogger "Created directory [$CONF_DIR]." QuickLogger "Created directory [$dir]."
else else
QuickLogger "Cannot create directory [$CONF_DIR]." QuickLogger "Cannot create directory [$dir]."
exit 1 exit 1
fi fi
fi
}
function CopyFile {
local sourcePath="${1}"
local destPath="${2}"
local fileName="${3}"
local fileMod="${4}"
local fileUser="${5}"
local fileGroup="${6}"
local overwrite="${7:-false}"
local userGroup=""
local oldFileName
if [ -f "$destPath/$fileName" ] && [ $overwrite == false ]; then
oldFileName="$fileName"
fileName="$oldFileName.new"
cp "$sourcePath/$oldFileName" "$destPath/$fileName"
else else
QuickLogger "Config directory [$CONF_DIR] exists." cp "$sourcePath/$fileName" "$destPath"
fi
if [ $? != 0 ]; then
QuickLogger "Cannot copy [$fileName] to [$destPath]. Make sure to run install script in the directory containing all other files."
QuickLogger "Also make sure you have permissions to write to [$BIN_DIR]."
exit 1
else
QuickLogger "Copied [$fileName] to [$destPath]."
if [ "$fileMod" != "" ]; then
chmod "$fileMod" "$destPath/$fileName"
if [ $? != 0 ]; then
QuickLogger "Cannot set file permissions of [$destPath/$fileName] to [$fileMod]."
exit 1
else
QuickLogger "Set file permissions to [$fileMod] on [$destPath/$fileName]."
fi
fi
if [ "$fileUser" != "" ]; then
userGroup="$fileUser"
if [ "$fileGroup" != "" ]; then
userGroup="$userGroup"":$fileGroup"
fi
chown "$userGroup" "$destPath/$fileName"
if [ $? != 0 ]; then
QuickLogger "Could not set file ownership on [$destPath/$fileName] to [$userGroup]."
exit 1
else
QuickLogger "Set file ownership on [$destPath/$fileName] to [$userGroup]."
fi
fi
fi fi
} }
function CopyExampleFiles { function CopyExampleFiles {
if [ -f "$SCRIPT_PATH/sync.conf.example" ]; then exampleFiles=()
cp "$SCRIPT_PATH/sync.conf.example" "$CONF_DIR/sync.conf.example" exampleFiles[0]="sync.conf.example" # osync
fi exampleFiles[1]="host_backup.conf.example" # obackup
exampleFiles[2]="exclude.list.example" # osync & obackup
exampleFiles[3]="snapshot.conf.example" # zsnap
exampleFiles[4]="default.conf" # pmocr
if [ -f "$SCRIPT_PATH/host_backup.conf.example" ]; then for file in "${exampleFiles[@]}"; do
cp "$SCRIPT_PATH/host_backup.conf.example" "$CONF_DIR/host_backup.conf.example" if [ -f "$SCRIPT_PATH/$file" ]; then
fi CopyFile "$SCRIPT_PATH" "$CONF_DIR" "$file" "" "" "" false
if [ -f "$SCRIPT_PATH/exlude.list.example" ]; then
cp "$SCRIPT_PATH/exclude.list.example" "$CONF_DIR/exclude.list.example"
fi
if [ -f "$SCRIPT_PATH/snapshot.conf.example" ]; then
cp "$SCRIPT_PATH/snapshot.conf.example" "$CONF_DIR/snapshot.conf.example"
fi
if [ -f "$SCRIPT_PATH/default.conf" ]; then
if [ -f "$CONF_DIR/default.conf" ]; then
cp "$SCRIPT_PATH/default.conf" "$CONF_DIR/default.conf.new"
QuickLogger "Copied default.conf to [$CONF_DIR/default.conf.new]."
else
cp "$SCRIPT_PATH/default.conf" "$CONF_DIR/default.conf"
fi fi
fi done
} }
function CopyProgram { function CopyProgram {
cp "$SCRIPT_PATH/$PROGRAM_BINARY" "$BIN_DIR" binFiles=()
if [ $? != 0 ]; then binFiles[0]="$PROGRAM_BINARY"
QuickLogger "Cannot copy $PROGRAM_BINARY to [$BIN_DIR]. Make sure to run install script in the directory containing all other files." if [ "$PROGRAM" == "osync" ] || [ "$PROGRAM" == "obackup" ]; then
QuickLogger "Also make sure you have permissions to write to [$BIN_DIR]." binFiles[1]="$PROGRAM_BATCH"
exit 1 binFiles[2]="$SSH_FILTER"
else
chmod 755 "$BIN_DIR/$PROGRAM_BINARY"
QuickLogger "Copied $PROGRAM_BINARY to [$BIN_DIR]."
fi fi
if [ -f "$SCRIPT_PATH/$PROGRAM_BATCH" ]; then local user=""
cp "$SCRIPT_PATH/$PROGRAM_BATCH" "$BIN_DIR" local group=""
if [ $? != 0 ]; then
QuickLogger "Cannot copy $PROGRAM_BATCH to [$BIN_DIR]." if ([ "$USER" != "" ] && [ "$FAKEROOT" == "" ]); then
else user="$USER"
chmod 755 "$BIN_DIR/$PROGRAM_BATCH" fi
QuickLogger "Copied $PROGRAM_BATCH to [$BIN_DIR]." if ([ "$GROUP" != "" ] && [ "$FAKEROOT" == "" ]); then
fi group="$GROUP"
fi fi
if [ -f "$SCRIPT_PATH/ssh_filter.sh" ]; then for file in "${binFiles[@]}"; do
cp "$SCRIPT_PATH/ssh_filter.sh" "$BIN_DIR" CopyFile "$SCRIPT_PATH" "$BIN_DIR" "$file" 755 "$user" "$group" true
if [ $? != 0 ]; then done
QuickLogger "Cannot copy ssh_filter.sh to [$BIN_DIR]."
else
chmod 755 "$BIN_DIR/ssh_filter.sh"
if ([ "$USER" != "" ] && [ "$GROUP" != "" ] && [ "$FAKEROOT" == "" ]); then
chown $USER:$GROUP "$BIN_DIR/ssh_filter.sh"
fi
QuickLogger "Copied ssh_filter.sh to [$BIN_DIR]."
fi
fi
} }
function CopyServiceFiles { function CopyServiceFiles {
# OSYNC SPECIFIC if ([ "$init" == "systemd" ] && [ -f "$SCRIPT_PATH/$SERVICE_FILE_SYSTEMD_SYSTEM" ]); then
if ([ "$init" == "systemd" ] && [ -f "$SCRIPT_PATH/$OSYNC_SERVICE_FILE_SYSTEMD_SYSTEM" ]); then CopyFile "$SCRIPT_PATH" "$SERVICE_DIR_SYSTEMD_SYSTEM" "$SERVICE_FILE_SYSTEMD_SYSTEM" "" "" "" true
cp "$SCRIPT_PATH/$OSYNC_SERVICE_FILE_SYSTEMD_SYSTEM" "$SERVICE_DIR_SYSTEMD_SYSTEM" && cp "$SCRIPT_PATH/$OSYNC_SERVICE_FILE_SYSTEMD_USER" "$SERVICE_DIR_SYSTEMD_USER/$SERVICE_FILE_SYSTEMD_SYSTEM" if [ -f "$SCRIPT_PATH/$SERVICE_FILE_SYSTEMD_SYSTEM_USER" ]; then
if [ $? != 0 ]; then CopyFile "$SCRIPT_PATH" "$SERVICE_DIR_SYSTEMD_USER" "$SERVICE_FILE_SYSTEMD_USER" "" "" "" true
QuickLogger "Cannot copy the systemd file to [$SERVICE_DIR_SYSTEMD_SYSTEM] or [$SERVICE_DIR_SYSTEMD_USER]."
else
QuickLogger "Created osync-srv service in [$SERVICE_DIR_SYSTEMD_SYSTEM] and [$SERVICE_DIR_SYSTEMD_USER]."
QuickLogger "Can be activated with [systemctl start osync-srv@instance.conf] where instance.conf is the name of the config file in $CONF_DIR."
QuickLogger "Can be enabled on boot with [systemctl enable osync-srv@instance.conf]."
QuickLogger "In userland, active with [systemctl --user start osync-srv@instance.conf]."
fi fi
elif ([ "$init" == "initV" ] && [ -f "$SCRIPT_PATH/$OSYNC_SERVICE_FILE_INIT" ]); then
cp "$SCRIPT_PATH/$OSYNC_SERVICE_FILE_INIT" "$SERVICE_DIR_INIT"
if [ $? != 0 ]; then
QuickLogger "Cannot copy osync-srv to [$SERVICE_DIR_INIT]."
else
chmod 755 "$SERVICE_DIR_INIT/$OSYNC_SERVICE_FILE_INIT"
QuickLogger "Created osync-srv service in [$SERVICE_DIR_INIT]."
QuickLogger "Can be activated with [service $OSYNC_SERVICE_FILE_INIT start]."
QuickLogger "Can be enabled on boot with [chkconfig $OSYNC_SERVICE_FILE_INIT on]."
fi
fi
# PMOCR SPECIFIC QuickLogger "Created [$SERVICE_NAME] service in [$SERVICE_DIR_SYSTEMD_SYSTEM] and [$SERVICE_DIR_SYSTEMD_USER]."
if ([ "$init" == "systemd" ] && [ -f "$SCRIPT_PATH/$PMOCR_SERVICE_FILE_SYSTEMD_SYSTEM" ]); then QuickLogger "Can be activated with [systemctl start SERVICE_NAME@instance.conf] where instance.conf is the name of the config file in $CONF_DIR."
cp "$SCRIPT_PATH/$PMOCR_SERVICE_FILE_SYSTEMD_SYSTEM" "$SERVICE_DIR_SYSTEMD_SYSTEM" QuickLogger "Can be enabled on boot with [systemctl enable $SERVICE_NAME@instance.conf]."
if [ $? != 0 ]; then QuickLogger "In userland, active with [systemctl --user start $SERVICE_NAME@instance.conf]."
QuickLogger "Cannot copy the systemd file to [$SERVICE_DIR_SYSTEMD_SYSTEM] or [$SERVICE_DIR_SYSTEMD_USER]." elif ([ "$init" == "initV" ] && [ -f "$SCRIPT_PATH/$SERVICE_FILE_INIT" ] && [ -d "$SERVICE_DIR_INIT" ]); then
else CopyFile "$SCRIPT_PATH" "$SERVICE_DIR_INIT" "$SERVICE_FILE_INIT" "755" "" "" true
QuickLogger "Created pmocr-srv service in [$SERVICE_DIR_SYSTEMD_SYSTEM] and [$SERVICE_DIR_SYSTEMD_USER]."
QuickLogger "Can be activated with [systemctl start pmocr-srv@default.conf] where default.conf is the name of the config file in $CONF_DIR." QuickLogger "Created [$SERVICE_NAME] service in [$SERVICE_DIR_INIT]."
QuickLogger "Can be enabled on boot with [systemctl enable pmocr-srv@default.conf]." QuickLogger "Can be activated with [service $SERVICE_FILE_INIT start]."
fi QuickLogger "Can be enabled on boot with [chkconfig $SERVICE_FILE_INIT on]."
elif ([ "$init" == "initV" ] && [ -f "$SCRIPT_PATH/$PMOCR_SERVICE_FILE_INIT" ]); then else
cp "$SCRIPT_PATH/$PMOCR_SERVICE_FILE_INIT" "$SERVICE_DIR_INIT" QuickLogger "Cannot define what init style is in use on this system. Skipping service file installation."
if [ $? != 0 ]; then
QuickLogger "Cannot copy pmoct-srv to [$SERVICE_DIR_INIT]."
else
chmod 755 "$SERVICE_DIR_INIT/$PMOCR_SERVICE_FILE_INIT"
QuickLogger "Created osync-srv service in [$SERVICE_DIR_INIT]."
QuickLogger "Can be activated with [service $PMOCR_SERVICE_FILE_INIT start]."
QuickLogger "Can be enabled on boot with [chkconfig $PMOCR_SERVICE_FILE_INIT on]."
fi
fi fi
} }
@@ -335,16 +370,53 @@ function Statistics {
return 1 return 1
} }
function RemoveFile {
local file="${1}"
if [ -f "$file" ]; then
rm -f "$file"
if [ $? != 0 ]; then
QuickLogger "Could not remove file [$file]."
else
QuickLogger "Removed file [$file]."
fi
else
QuickLogger "File [$file] not found. Skipping."
fi
}
function RemoveAll {
RemoveFile "$BIN_DIR/$PROGRAM_BINARY"
if [ "$PROGRAM" == "osync" ] || [ "$PROGRAM" == "obackup" ]; then
RemoveFile "$BIN_DIR/$PROGRAM_BATCH"
fi
if [ ! -f "$BIN_DIR/osync.sh" ] && [ ! -f "$BIN_DIR/obackup.sh" ]; then # Check if any other program requiring ssh filter is present before removal
RemoveFile "$BIN_DIR/$SSH_FILTER"
else
QuickLogger "Skipping removal of [$BIN_DIR/$SSH_FILTER] because other programs present that need it."
fi
RemoveFile "$SERVICE_DIR_SYSTEMD_SYSTEM/$SERVICE_FILE_SYSTEMD_SYSTEM"
RemoveFile "$SERVICE_DIR_SYSTEMD_USER/$SERVICE_FILE_SYSTEMD_SYSTEM"
RemoveFile "$SERVICE_DIR_INIT/$SERVICE_FILE_INIT"
QuickLogger "Skipping configuration files in [$CONF_DIR]. You may remove this directory manually."
}
function Usage { function Usage {
echo "Installs $PROGRAM into $BIN_DIR" echo "Installs $PROGRAM into $BIN_DIR"
echo "options:" echo "options:"
echo "--silent Will log and bypass user interaction." echo "--silent Will log and bypass user interaction."
echo "--no-stats Used with --silent in order to refuse sending anonymous install stats." echo "--no-stats Used with --silent in order to refuse sending anonymous install stats."
echo "--remove Remove the program."
exit 127 exit 127
} }
_LOGGER_SILENT=false _LOGGER_SILENT=false
_STATS=1 _STATS=1
ACTION="install"
for i in "$@" for i in "$@"
do do
case $i in case $i in
@@ -354,6 +426,9 @@ do
--no-stats) --no-stats)
_STATS=0 _STATS=0
;; ;;
--remove)
ACTION="uninstall"
;;
--help|-h|-?) --help|-h|-?)
Usage Usage
esac esac
@@ -365,21 +440,35 @@ fi
GetLocalOS GetLocalOS
SetLocalOSSettings SetLocalOSSettings
CreateConfDir
CopyExampleFiles
CopyProgram
GetInit GetInit
CopyServiceFiles
STATS_LINK="http://instcount.netpower.fr?program=$PROGRAM&version=$PROGRAM_VERSION&os=$OS" STATS_LINK="http://instcount.netpower.fr?program=$PROGRAM&version=$PROGRAM_VERSION&os=$OS&action=$ACTION"
if [ "$ACTION" == "uninstall" ]; then
RemoveAll
QuickLogger "$PROGRAM uninstalled."
else
CreateDir "$CONF_DIR"
CreateDir "$BIN_DIR"
CopyExampleFiles
CopyProgram
if [ "$PROGRAM" == "osync" ] || [ "$PROGRAM" == "pmocr" ]; then
CopyServiceFiles
fi
QuickLogger "$PROGRAM installed. Use with $BIN_DIR/$PROGRAM"
if [ "$PROGRAM" == "osync" ] || [ "$PROGRAM" == "obackup" ]; then
QuickLogger ""
QuickLogger "If connecting remotely, consider setup ssh filter to enhance security."
QuickLogger ""
fi
fi
QuickLogger "$PROGRAM installed. Use with $BIN_DIR/$PROGRAM"
if [ $_STATS -eq 1 ]; then if [ $_STATS -eq 1 ]; then
if [ $_LOGGER_SILENT == true ]; then if [ $_LOGGER_SILENT == true ]; then
Statistics Statistics
else else
QuickLogger "In order to make install statistics, the script would like to connect to $STATS_LINK" QuickLogger "In order to make usage statistics, the script would like to connect to $STATS_LINK"
read -r -p "No data except those in the url will be send. Allow [Y/n]" response read -r -p "No data except those in the url will be send. Allow [Y/n] " response
case $response in case $response in
[nN]) [nN])
exit exit

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env bash #!/usr/bin/env bash
SUBPROGRAM=obackup SUBPROGRAM=obackup
PROGRAM="$SUBPROGRAM-batch" # Batch program to run osync / obackup instances sequentially and rerun failed ones PROGRAM="$SUBPROGRAM-batch" # Batch program to run osync / obackup instances sequentially and rerun failed ones
AUTHOR="(L) 2013-2016 by Orsiris de Jong" AUTHOR="(L) 2013-2017 by Orsiris de Jong"
CONTACT="http://www.netpower.fr - ozy@netpower.fr" CONTACT="http://www.netpower.fr - ozy@netpower.fr"
PROGRAM_BUILD=2016120401 PROGRAM_BUILD=2016120401
@@ -119,15 +119,15 @@ function Batch {
fi fi
done done
runList=("${runAgainList[@]}") runList=("${runAgainList[@]}")
runs=$(($runs + 1)) runs=$((runs + 1))
done done
fi fi
} }
function Usage { function Usage {
echo "$PROGRAM $PROGRAM_BUILD" echo "$PROGRAM $PROGRAM_BUILD"
echo $AUTHOR echo "$AUTHOR"
echo $CONTACT echo "$CONTACT"
echo "" echo ""
echo "Batch script to sequentially run osync or obackup instances and rerun failed ones." echo "Batch script to sequentially run osync or obackup instances and rerun failed ones."
echo "Usage: $PROGRAM.sh [OPTIONS] [$SUBPROGRAM OPTIONS]" echo "Usage: $PROGRAM.sh [OPTIONS] [$SUBPROGRAM OPTIONS]"

View File

@@ -6,16 +6,14 @@
PROGRAM="obackup" PROGRAM="obackup"
AUTHOR="(C) 2013-2017 by Orsiris de Jong" AUTHOR="(C) 2013-2017 by Orsiris de Jong"
CONTACT="http://www.netpower.fr/obackup - ozy@netpower.fr" CONTACT="http://www.netpower.fr/obackup - ozy@netpower.fr"
PROGRAM_VERSION=2.1-beta1 PROGRAM_VERSION=2.1-beta3
PROGRAM_BUILD=2017010305 PROGRAM_BUILD=2017062004
IS_STABLE=no IS_STABLE=no
_OFUNCTIONS_VERSION=2.1.4-rc1
_OFUNCTIONS_BUILD=2017060903
_OFUNCTIONS_VERSION=2.1-RC1+dev
_OFUNCTIONS_BUILD=2017010401
_OFUNCTIONS_BOOTSTRAP=true _OFUNCTIONS_BOOTSTRAP=true
## BEGIN Generic bash functions written in 2013-2017 by Orsiris de Jong - http://www.netpower.fr - ozy@netpower.fr ## BEGIN Generic bash functions written in 2013-2017 by Orsiris de Jong - http://www.netpower.fr - ozy@netpower.fr
@@ -40,6 +38,9 @@ fi
## Correct output of sort command (language agnostic sorting) ## Correct output of sort command (language agnostic sorting)
export LC_ALL=C export LC_ALL=C
## Default umask for file creation
umask 0077
# Standard alert mail body # Standard alert mail body
MAIL_ALERT_MSG="Execution of $PROGRAM instance $INSTANCE_ID on $(date) has warnings/errors." MAIL_ALERT_MSG="Execution of $PROGRAM instance $INSTANCE_ID on $(date) has warnings/errors."
@@ -72,7 +73,9 @@ if [ "$SLEEP_TIME" == "" ]; then # Leave the possibity to set SLEEP_TIME as envi
fi fi
SCRIPT_PID=$$ SCRIPT_PID=$$
TSTAMP=$(date '+%Y%m%d%H%M%S%N')
# TODO: Check if %N works on MacOS
TSTAMP=$(date '+%Y%m%dT%H%M%S.%N')
LOCAL_USER=$(whoami) LOCAL_USER=$(whoami)
LOCAL_HOST=$(hostname) LOCAL_HOST=$(hostname)
@@ -127,7 +130,7 @@ function joinString {
function _Logger { function _Logger {
local logValue="${1}" # Log to file local logValue="${1}" # Log to file
local stdValue="${2}" # Log to screeen local stdValue="${2}" # Log to screeen
local toStderr="${3:-false}" # Log to stderr instead of stdout local toStdErr="${3:-false}" # Log to stderr instead of stdout
if [ "$logValue" != "" ]; then if [ "$logValue" != "" ]; then
echo -e "$logValue" >> "$LOG_FILE" echo -e "$logValue" >> "$LOG_FILE"
@@ -136,7 +139,7 @@ function _Logger {
fi fi
if [ "$stdValue" != "" ] && [ "$_LOGGER_SILENT" != true ]; then if [ "$stdValue" != "" ] && [ "$_LOGGER_SILENT" != true ]; then
if [ $toStderr == true ]; then if [ $toStdErr == true ]; then
# Force stderr color in subshell # Force stderr color in subshell
(>&2 echo -e "$stdValue") (>&2 echo -e "$stdValue")
@@ -230,6 +233,10 @@ function Logger {
prefix="" prefix=""
fi fi
## Obfuscate _REMOTE_TOKEN in logs (for ssh_filter usage only in osync and obackup)
value="${value/env _REMOTE_TOKEN=$_REMOTE_TOKEN/__(o_O)__}"
value="${value/env _REMOTE_TOKEN=\$_REMOTE_TOKEN/__(o_O)__}"
if [ "$level" == "CRITICAL" ]; then if [ "$level" == "CRITICAL" ]; then
_Logger "$prefix($level):$value" "$prefix\e[1;33;41m$value\e[0m" true _Logger "$prefix($level):$value" "$prefix\e[1;33;41m$value\e[0m" true
ERROR_ALERT=true ERROR_ALERT=true
@@ -253,7 +260,7 @@ function Logger {
return return
elif [ "$level" == "VERBOSE" ]; then elif [ "$level" == "VERBOSE" ]; then
if [ $_LOGGER_VERBOSE == true ]; then if [ $_LOGGER_VERBOSE == true ]; then
_Logger "$prefix:$value" "$prefix$value" _Logger "$prefix($level):$value" "$prefix$value"
fi fi
return return
elif [ "$level" == "ALWAYS" ]; then elif [ "$level" == "ALWAYS" ]; then
@@ -299,14 +306,28 @@ function KillChilds {
local pid="${1}" # Parent pid to kill childs local pid="${1}" # Parent pid to kill childs
local self="${2:-false}" # Should parent be killed too ? local self="${2:-false}" # Should parent be killed too ?
# Warning: pgrep does not exist in cygwin, have this checked in CheckEnvironment # Paranoid checks, we can safely assume that $pid shouldn't be 0 nor 1
if children="$(pgrep -P "$pid")"; then if [ $(IsNumeric "$pid") -eq 0 ] || [ "$pid" == "" ] || [ "$pid" == "0" ] || [ "$pid" == "1" ]; then
for child in $children; do Logger "Bogus pid given [$pid]." "CRITICAL"
KillChilds "$child" true return 1
done
fi fi
# Try to kill nicely, if not, wait 15 seconds to let Trap actions happen before killing
if kill -0 "$pid" > /dev/null 2>&1; then
# Warning: pgrep is not native on cygwin, have this checked in CheckEnvironment
if children="$(pgrep -P "$pid")"; then
if [[ "$pid" == *"$children"* ]]; then
Logger "Bogus pgrep implementation." "CRITICAL"
children="${children/$pid/}"
fi
for child in $children; do
KillChilds "$child" true
done
fi
fi
# Try to kill nicely, if not, wait 15 seconds to let Trap actions happen before killing
if [ "$self" == true ]; then if [ "$self" == true ]; then
# We need to check for pid again because it may have disappeared after recursive function call
if kill -0 "$pid" > /dev/null 2>&1; then if kill -0 "$pid" > /dev/null 2>&1; then
kill -s TERM "$pid" kill -s TERM "$pid"
Logger "Sent SIGTERM to process [$pid]." "DEBUG" Logger "Sent SIGTERM to process [$pid]." "DEBUG"
@@ -367,13 +388,17 @@ function SendAlert {
eval "cat \"$LOG_FILE\" $COMPRESSION_PROGRAM > $ALERT_LOG_FILE" eval "cat \"$LOG_FILE\" $COMPRESSION_PROGRAM > $ALERT_LOG_FILE"
if [ $? != 0 ]; then if [ $? != 0 ]; then
Logger "Cannot create [$ALERT_LOG_FILE]" "WARN"
attachment=false attachment=false
else else
attachment=true attachment=true
fi fi
if [ -e "$RUN_DIR/$PROGRAM._Logger.$SCRIPT_PID.$TSTAMP" ]; then if [ -e "$RUN_DIR/$PROGRAM._Logger.$SCRIPT_PID.$TSTAMP" ]; then
body="$MAIL_ALERT_MSG"$'\n\n'"$(cat $RUN_DIR/$PROGRAM._Logger.$SCRIPT_PID.$TSTAMP)" if [ "$MAIL_BODY_CHARSET" != "" ] && type iconv > /dev/null 2>&1; then
iconv -f UTF-8 -t $MAIL_BODY_CHARSET "$RUN_DIR/$PROGRAM._Logger.$SCRIPT_PID.$TSTAMP" > "$RUN_DIR/$PROGRAM._Logger.iconv.$SCRIPT_PID.$TSTAMP"
body="$MAIL_ALERT_MSG"$'\n\n'"$(cat $RUN_DIR/$PROGRAM._Logger.iconv.$SCRIPT_PID.$TSTAMP)"
else
body="$MAIL_ALERT_MSG"$'\n\n'"$(cat $RUN_DIR/$PROGRAM._Logger.$SCRIPT_PID.$TSTAMP)"
fi
fi fi
if [ $ERROR_ALERT == true ]; then if [ $ERROR_ALERT == true ]; then
@@ -608,6 +633,7 @@ function Spinner {
} }
# Time control function for background processes, suitable for multiple synchronous processes # Time control function for background processes, suitable for multiple synchronous processes
# Fills a global variable called WAIT_FOR_TASK_COMPLETION_$callerName that contains list of failed pids in format pid1:result1;pid2:result2 # Fills a global variable called WAIT_FOR_TASK_COMPLETION_$callerName that contains list of failed pids in format pid1:result1;pid2:result2
# Also sets a global variable called HARD_MAX_EXEC_TIME_REACHED_$callerName to true if hardMaxTime is reached # Also sets a global variable called HARD_MAX_EXEC_TIME_REACHED_$callerName to true if hardMaxTime is reached
@@ -732,6 +758,8 @@ function WaitForTaskCompletion {
pidsArray=("${newPidsArray[@]}") pidsArray=("${newPidsArray[@]}")
# Trivial wait time for bash to not eat up all CPU # Trivial wait time for bash to not eat up all CPU
sleep $sleepTime sleep $sleepTime
done done
@@ -890,6 +918,7 @@ function ParallelExec {
# Trivial wait time for bash to not eat up all CPU # Trivial wait time for bash to not eat up all CPU
sleep $sleepTime sleep $sleepTime
done done
return $errorCount return $errorCount
@@ -1042,6 +1071,8 @@ function ArrayContains () {
function GetLocalOS { function GetLocalOS {
local localOsVar local localOsVar
local localOsName
local localOsVer
# There's no good way to tell if currently running in BusyBox shell. Using sluggish way. # There's no good way to tell if currently running in BusyBox shell. Using sluggish way.
if ls --help 2>&1 | grep -i "BusyBox" > /dev/null; then if ls --help 2>&1 | grep -i "BusyBox" > /dev/null; then
@@ -1072,7 +1103,7 @@ function GetLocalOS {
*"BSD"*) *"BSD"*)
LOCAL_OS="BSD" LOCAL_OS="BSD"
;; ;;
*"MINGW32"*|*"MSYS"*) *"MINGW32"*|*"MINGW64"*|*"MSYS"*)
LOCAL_OS="msys" LOCAL_OS="msys"
;; ;;
*"CYGWIN"*) *"CYGWIN"*)
@@ -1098,15 +1129,23 @@ function GetLocalOS {
exit 1 exit 1
;; ;;
esac esac
if [ "$_OFUNCTIONS_VERSION" != "" ]; then
Logger "Local OS: [$localOsVar]." "DEBUG" # Get linux versions
if [ -f "/etc/os-release" ]; then
localOsName=$(GetConfFileValue "/etc/os-release" "NAME")
localOsVer=$(GetConfFileValue "/etc/os-release" "VERSION")
fi fi
# Add a global variable for statistics in installer # Add a global variable for statistics in installer
LOCAL_OS_FULL="$localOsVar" LOCAL_OS_FULL="$localOsVar ($localOsName $localOsVer)"
if [ "$_OFUNCTIONS_VERSION" != "" ]; then
Logger "Local OS: [$LOCAL_OS_FULL]." "DEBUG"
fi
} }
function GetRemoteOS { function GetRemoteOS {
if [ "$REMOTE_OPERATION" != "yes" ]; then if [ "$REMOTE_OPERATION" != "yes" ]; then
@@ -1115,10 +1154,15 @@ function GetRemoteOS {
local remoteOsVar local remoteOsVar
$SSH_CMD bash -s << 'ENDSSH' >> "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP" 2>&1 $SSH_CMD env LC_ALL=C env _REMOTE_TOKEN="$_REMOTE_TOKEN" bash -s << 'ENDSSH' >> "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP" 2>&1
function GetOs { function GetOs {
local localOsVar local localOsVar
local localOsName
local localOsVer
local osInfo="/etc/os-release"
# There's no good way to tell if currently running in BusyBox shell. Using sluggish way. # There's no good way to tell if currently running in BusyBox shell. Using sluggish way.
if ls --help 2>&1 | grep -i "BusyBox" > /dev/null; then if ls --help 2>&1 | grep -i "BusyBox" > /dev/null; then
@@ -1137,7 +1181,15 @@ function GetOs {
fi fi
fi fi
fi fi
echo "$localOsVar" # Get linux versions
if [ -f "$osInfo" ]; then
localOsName=$(grep "^NAME=" "$osInfo")
localOsName="${localOsName##*=}"
localOsVer=$(grep "^VERSION=" "$osInfo")
localOsVer="${localOsVer##*=}"
fi
echo "$localOsVar ($localOsName $localOsVer)"
} }
GetOs GetOs
@@ -1156,7 +1208,7 @@ ENDSSH
*"BSD"*) *"BSD"*)
REMOTE_OS="BSD" REMOTE_OS="BSD"
;; ;;
*"MINGW32"*|*"MSYS"*) *"MINGW32"*|*"MINGW64"*|*"MSYS"*)
REMOTE_OS="msys" REMOTE_OS="msys"
;; ;;
*"CYGWIN"*) *"CYGWIN"*)
@@ -1225,6 +1277,12 @@ function RunRemoteCommand {
local command="${1}" # Command to run local command="${1}" # Command to run
local hardMaxTime="${2}" # Max time to wait for command to compleet local hardMaxTime="${2}" # Max time to wait for command to compleet
if [ "$REMOTE_OPERATION" != "yes" ]; then
Logger "Ignoring remote command [$command] because remote host is not configured." "WARN"
return 0
fi
CheckConnectivity3rdPartyHosts CheckConnectivity3rdPartyHosts
CheckConnectivityRemoteHost CheckConnectivityRemoteHost
if [ $_DRYRUN == true ]; then if [ $_DRYRUN == true ]; then
@@ -1233,7 +1291,7 @@ function RunRemoteCommand {
fi fi
Logger "Running command [$command] on remote host." "NOTICE" Logger "Running command [$command] on remote host." "NOTICE"
cmd=$SSH_CMD' "$command" > "'$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP'" 2>&1' cmd=$SSH_CMD' "env LC_ALL=C env _REMOTE_TOKEN="'$_REMOTE_TOKEN'" $command" > "'$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP'" 2>&1'
Logger "cmd: $cmd" "DEBUG" Logger "cmd: $cmd" "DEBUG"
eval "$cmd" & eval "$cmd" &
WaitForTaskCompletion $! 0 $hardMaxTime $SLEEP_TIME $KEEP_LOGGING true true false WaitForTaskCompletion $! 0 $hardMaxTime $SLEEP_TIME $KEEP_LOGGING true true false
@@ -1336,7 +1394,6 @@ function CheckConnectivity3rdPartyHosts {
fi fi
} }
function RsyncPatternsAdd { function RsyncPatternsAdd {
local patternType="${1}" # exclude or include local patternType="${1}" # exclude or include
local pattern="${2}" local pattern="${2}"
@@ -1462,13 +1519,13 @@ function PostInit {
# Define remote commands # Define remote commands
if [ -f "$SSH_RSA_PRIVATE_KEY" ]; then if [ -f "$SSH_RSA_PRIVATE_KEY" ]; then
SSH_CMD="$(type -p ssh) $SSH_COMP -i $SSH_RSA_PRIVATE_KEY $SSH_OPTS $REMOTE_USER@$REMOTE_HOST -p $REMOTE_PORT" SSH_CMD="$(type -p ssh) $SSH_COMP -q -i $SSH_RSA_PRIVATE_KEY $SSH_OPTS $REMOTE_USER@$REMOTE_HOST -p $REMOTE_PORT"
SCP_CMD="$(type -p scp) $SSH_COMP -i $SSH_RSA_PRIVATE_KEY -P $REMOTE_PORT" SCP_CMD="$(type -p scp) $SSH_COMP -q -i $SSH_RSA_PRIVATE_KEY -P $REMOTE_PORT"
RSYNC_SSH_CMD="$(type -p ssh) $SSH_COMP -i $SSH_RSA_PRIVATE_KEY $SSH_OPTS -p $REMOTE_PORT" RSYNC_SSH_CMD="$(type -p ssh) $SSH_COMP -q -i $SSH_RSA_PRIVATE_KEY $SSH_OPTS -p $REMOTE_PORT"
elif [ -f "$SSH_PASSWORD_FILE" ]; then elif [ -f "$SSH_PASSWORD_FILE" ]; then
SSH_CMD="$(type -p sshpass) -f $SSH_PASSWORD_FILE $(type -p ssh) $SSH_COMP $SSH_OPTS $REMOTE_USER@$REMOTE_HOST -p $REMOTE_PORT" SSH_CMD="$(type -p sshpass) -f $SSH_PASSWORD_FILE $(type -p ssh) $SSH_COMP -q $SSH_OPTS $REMOTE_USER@$REMOTE_HOST -p $REMOTE_PORT"
SCP_CMD="$(type -p sshpass) -f $SSH_PASSWORD_FILE $(type -p scp) $SSH_COMP -P $REMOTE_PORT" SCP_CMD="$(type -p sshpass) -f $SSH_PASSWORD_FILE $(type -p scp) $SSH_COMP -q -P $REMOTE_PORT"
RSYNC_SSH_CMD="$(type -p sshpass) -f $SSH_PASSWORD_FILE $(type -p ssh) $SSH_COMP $SSH_OPTS -p $REMOTE_PORT" RSYNC_SSH_CMD="$(type -p sshpass) -f $SSH_PASSWORD_FILE $(type -p ssh) $SSH_COMP -q $SSH_OPTS -p $REMOTE_PORT"
else else
SSH_PASSWORD="" SSH_PASSWORD=""
SSH_CMD="" SSH_CMD=""
@@ -1518,7 +1575,10 @@ function SetCompression {
COMPRESSION_EXTENSION= COMPRESSION_EXTENSION=
fi fi
fi fi
ALERT_LOG_FILE="$ALERT_LOG_FILE$COMPRESSION_EXTENSION"
if [ ".${ALERT_LOG_FILE##*.}" != "$COMPRESSION_EXTENSION" ]; then
ALERT_LOG_FILE="$ALERT_LOG_FILE$COMPRESSION_EXTENSION"
fi
} }
function InitLocalOSDependingSettings { function InitLocalOSDependingSettings {
@@ -1530,6 +1590,11 @@ function InitLocalOSDependingSettings {
if [ "$LOCAL_OS" == "msys" ] || [ "$LOCAL_OS" == "Cygwin" ]; then if [ "$LOCAL_OS" == "msys" ] || [ "$LOCAL_OS" == "Cygwin" ]; then
FIND_CMD=$(dirname $BASH)/find FIND_CMD=$(dirname $BASH)/find
PING_CMD='$SYSTEMROOT\system32\ping -n 2' PING_CMD='$SYSTEMROOT\system32\ping -n 2'
# On BSD, when not root, min ping interval is 1s
elif [ "$LOCAL_OS" == "BSD" ] && [ "$LOCAL_USER" != "root" ]; then
FIND_CMD=find
PING_CMD="ping -c 2 -i 1"
else else
FIND_CMD=find FIND_CMD=find
PING_CMD="ping -c 2 -i .2" PING_CMD="ping -c 2 -i .2"
@@ -1578,7 +1643,7 @@ function InitRemoteOSDependingSettings {
fi fi
## Set rsync default arguments ## Set rsync default arguments
RSYNC_ARGS="-rltD" RSYNC_ARGS="-rltD -8"
if [ "$_DRYRUN" == true ]; then if [ "$_DRYRUN" == true ]; then
RSYNC_DRY_ARG="-n" RSYNC_DRY_ARG="-n"
DRY_WARNING="/!\ DRY RUN " DRY_WARNING="/!\ DRY RUN "
@@ -1673,6 +1738,102 @@ function ParentPid {
fi fi
} }
# Neat version compare function found at http://stackoverflow.com/a/4025065/2635443
# Returns 0 if equal, 1 if $1 > $2 and 2 if $1 < $2
function VerComp () {
if [ "$1" == "" ] || [ "$2" == "" ]; then
Logger "Bogus Vercomp values [$1] and [$2]." "WARN"
return 1
fi
if [[ $1 == $2 ]]
then
echo 0
return
fi
local IFS=.
local i ver1=($1) ver2=($2)
# fill empty fields in ver1 with zeros
for ((i=${#ver1[@]}; i<${#ver2[@]}; i++))
do
ver1[i]=0
done
for ((i=0; i<${#ver1[@]}; i++))
do
if [[ -z ${ver2[i]} ]]
then
# fill empty fields in ver2 with zeros
ver2[i]=0
fi
if ((10#${ver1[i]} > 10#${ver2[i]}))
then
echo 1
return
fi
if ((10#${ver1[i]} < 10#${ver2[i]}))
then
echo 2
return
fi
done
echo 0
return
}
function GetConfFileValue () {
local file="${1}"
local name="${2}"
local value
value=$(grep "^$name=" "$file")
if [ $? == 0 ]; then
value="${value##*=}"
echo "$value"
else
Logger "Cannot get value for [$name] in config file [$file]." "ERROR"
fi
}
function SetConfFileValue () {
local file="${1}"
local name="${2}"
local value="${3}"
local separator="${4:-#}"
if grep "^$name=" "$file" > /dev/null; then
# Using -i.tmp for BSD compat
sed -i.tmp "s$separator^$name=.*$separator$name=$value$separator" "$file"
rm -f "$file.tmp"
Logger "Set [$name] to [$value] in config file [$file]." "DEBUG"
else
Logger "Cannot set value [$name] to [$value] in config file [$file]." "ERROR"
fi
}
# Function can replace [ -f /some/file* ] tests
# Modified version of http://stackoverflow.com/a/6364244/2635443
function WildcardFileExists () {
local file="${1}"
local exists=0
for f in $file; do
## Check if the glob gets expanded to existing files.
## If not, f here will be exactly the pattern above
## and the exists test will evaluate to false.
if [ -e "$f" ]; then
exists=1
break
fi
done
if [ $exists -eq 1 ]; then
echo 1
else
echo 0
fi
}
# If using "include" statements, make sure the script does not get executed unless it's loaded by bootstrap # If using "include" statements, make sure the script does not get executed unless it's loaded by bootstrap
_OFUNCTIONS_BOOTSTRAP=true _OFUNCTIONS_BOOTSTRAP=true
@@ -1781,6 +1942,11 @@ function CheckEnvironment {
if [ "$ENCRYPTION" == "yes" ]; then if [ "$ENCRYPTION" == "yes" ]; then
CheckCryptEnvironnment CheckCryptEnvironnment
fi fi
if ! type pgrep > /dev/null 2>&1 ; then
Logger "pgrep not present. $0 cannot start." "CRITICAL"
exit 1
fi
} }
function CheckCryptEnvironnment { function CheckCryptEnvironnment {
@@ -1895,7 +2061,7 @@ function _ListDatabasesLocal {
Logger "Listing databases succeeded." "NOTICE" Logger "Listing databases succeeded." "NOTICE"
else else
Logger "Listing databases failed." "ERROR" Logger "Listing databases failed." "ERROR"
Logger "Command was [$sqlCmd]." "WARN" _LOGGER_SILENT=true Logger "Command was [$sqlCmd]." "WARN"
if [ -f "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP" ]; then if [ -f "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP" ]; then
Logger "Command output:\n$(cat $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP)" "ERROR" Logger "Command output:\n$(cat $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP)" "ERROR"
fi fi
@@ -1911,7 +2077,7 @@ function _ListDatabasesRemote {
CheckConnectivity3rdPartyHosts CheckConnectivity3rdPartyHosts
CheckConnectivityRemoteHost CheckConnectivityRemoteHost
sqlCmd="$SSH_CMD \"mysql -u $SQL_USER -Bse 'SELECT table_schema, round(sum( data_length + index_length ) / 1024) FROM information_schema.TABLES GROUP by table_schema;'\" > \"$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP\" 2>&1" sqlCmd="$SSH_CMD \"env _REMOTE_TOKEN=$_REMOTE_TOKEN mysql -u $SQL_USER -Bse 'SELECT table_schema, round(sum( data_length + index_length ) / 1024) FROM information_schema.TABLES GROUP by table_schema;'\" > \"$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP\" 2>&1"
Logger "Command output: $sqlCmd" "DEBUG" Logger "Command output: $sqlCmd" "DEBUG"
eval "$sqlCmd" & eval "$sqlCmd" &
WaitForTaskCompletion $! $SOFT_MAX_EXEC_TIME_DB_TASK $HARD_MAX_EXEC_TIME_DB_TASK $SLEEP_TIME $KEEP_LOGGING true true false WaitForTaskCompletion $! $SOFT_MAX_EXEC_TIME_DB_TASK $HARD_MAX_EXEC_TIME_DB_TASK $SLEEP_TIME $KEEP_LOGGING true true false
@@ -2034,7 +2200,7 @@ function _ListRecursiveBackupDirectoriesLocal {
retval=$? retval=$?
if [ $retval -ne 0 ]; then if [ $retval -ne 0 ]; then
Logger "Could not enumerate directories in [$directory]." "ERROR" Logger "Could not enumerate directories in [$directory]." "ERROR"
Logger "Command was [$cmd]." "Warn" _LOGGER_SILENT=true Logger "Command was [$cmd]." "WARN"
if [ -f $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP ]; then if [ -f $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP ]; then
Logger "Command output:\n$(cat $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP)" "ERROR" Logger "Command output:\n$(cat $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP)" "ERROR"
fi fi
@@ -2059,7 +2225,8 @@ function _ListRecursiveBackupDirectoriesRemote {
local retval local retval
$SSH_CMD env _DEBUG="'$_DEBUG'" env _PARANOIA_DEBUG="'$_PARANOIA_DEBUG'" env _LOGGER_SILENT="'$_LOGGER_SILENT'" env _LOGGER_VERBOSE="'$_LOGGER_VERBOSE'" env _LOGGER_PREFIX="'$_LOGGER_PREFIX'" env _LOGGER_ERR_ONLY="'$_LOGGER_ERR_ONLY'" \ $SSH_CMD env _REMOTE_TOKEN=$_REMOTE_TOKEN \
env _DEBUG="'$_DEBUG'" env _PARANOIA_DEBUG="'$_PARANOIA_DEBUG'" env _LOGGER_SILENT="'$_LOGGER_SILENT'" env _LOGGER_VERBOSE="'$_LOGGER_VERBOSE'" env _LOGGER_PREFIX="'$_LOGGER_PREFIX'" env _LOGGER_ERR_ONLY="'$_LOGGER_ERR_ONLY'" \
env PROGRAM="'$PROGRAM'" env SCRIPT_PID="'$SCRIPT_PID'" TSTAMP="'$TSTAMP'" \ env PROGRAM="'$PROGRAM'" env SCRIPT_PID="'$SCRIPT_PID'" TSTAMP="'$TSTAMP'" \
env RECURSIVE_DIRECTORY_LIST="'$RECURSIVE_DIRECTORY_LIST'" env PATH_SEPARATOR_CHAR="'$PATH_SEPARATOR_CHAR'" \ env RECURSIVE_DIRECTORY_LIST="'$RECURSIVE_DIRECTORY_LIST'" env PATH_SEPARATOR_CHAR="'$PATH_SEPARATOR_CHAR'" \
env REMOTE_FIND_CMD="'$REMOTE_FIND_CMD'" $COMMAND_SUDO' bash -s' << 'ENDSSH' > "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP" 2> "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP" env REMOTE_FIND_CMD="'$REMOTE_FIND_CMD'" $COMMAND_SUDO' bash -s' << 'ENDSSH' > "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP" 2> "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP"
@@ -2096,7 +2263,7 @@ function joinString {
function _Logger { function _Logger {
local logValue="${1}" # Log to file local logValue="${1}" # Log to file
local stdValue="${2}" # Log to screeen local stdValue="${2}" # Log to screeen
local toStderr="${3:-false}" # Log to stderr instead of stdout local toStdErr="${3:-false}" # Log to stderr instead of stdout
if [ "$logValue" != "" ]; then if [ "$logValue" != "" ]; then
echo -e "$logValue" >> "$LOG_FILE" echo -e "$logValue" >> "$LOG_FILE"
@@ -2105,7 +2272,7 @@ function _Logger {
fi fi
if [ "$stdValue" != "" ] && [ "$_LOGGER_SILENT" != true ]; then if [ "$stdValue" != "" ] && [ "$_LOGGER_SILENT" != true ]; then
if [ $toStderr == true ]; then if [ $toStdErr == true ]; then
# Force stderr color in subshell # Force stderr color in subshell
(>&2 echo -e "$stdValue") (>&2 echo -e "$stdValue")
@@ -2305,14 +2472,14 @@ function _GetDirectoriesSizeLocal {
retval=$? retval=$?
if [ $retval -ne 0 ] || [ -s $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP ]; then if [ $retval -ne 0 ] || [ -s $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP ]; then
Logger "Could not get files size for some or all local directories." "ERROR" Logger "Could not get files size for some or all local directories." "ERROR"
Logger "Command was [$cmd]." "WARN" _LOGGER_SILENT=true Logger "Command was [$cmd]." "WARN"
if [ -f "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP" ]; then if [ -f "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP" ]; then
Logger "Command output:\n$(cat $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP)" "ERROR" Logger "Command output:\n$(cat $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP)" "ERROR"
fi fi
if [ -f "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP" ]; then if [ -f "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP" ]; then
Logger "Error output:\n$(cat $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP)" "ERROR" Logger "Error output:\n$(cat $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP)" "ERROR"
fi fi
elsew else
Logger "File size fetched successfully." "NOTICE" Logger "File size fetched successfully." "NOTICE"
fi fi
@@ -2333,7 +2500,8 @@ function _GetDirectoriesSizeRemote {
local retval local retval
# Error output is different from stdout because not all files in list may fail at once # Error output is different from stdout because not all files in list may fail at once
$SSH_CMD env _DEBUG="'$_DEBUG'" env _PARANOIA_DEBUG="'$_PARANOIA_DEBUG'" env _LOGGER_SILENT="'$_LOGGER_SILENT'" env _LOGGER_VERBOSE="'$_LOGGER_VERBOSE'" env _LOGGER_PREFIX="'$_LOGGER_PREFIX'" env _LOGGER_ERR_ONLY="'$_LOGGER_ERR_ONLY'" \ $SSH_CMD env _REMOTE_TOKEN=$_REMOTE_TOKEN \
env _DEBUG="'$_DEBUG'" env _PARANOIA_DEBUG="'$_PARANOIA_DEBUG'" env _LOGGER_SILENT="'$_LOGGER_SILENT'" env _LOGGER_VERBOSE="'$_LOGGER_VERBOSE'" env _LOGGER_PREFIX="'$_LOGGER_PREFIX'" env _LOGGER_ERR_ONLY="'$_LOGGER_ERR_ONLY'" \
env PROGRAM="'$PROGRAM'" env SCRIPT_PID="'$SCRIPT_PID'" TSTAMP="'$TSTAMP'" dirList="'$dirList'" \ env PROGRAM="'$PROGRAM'" env SCRIPT_PID="'$SCRIPT_PID'" TSTAMP="'$TSTAMP'" dirList="'$dirList'" \
$COMMAND_SUDO' bash -s' << 'ENDSSH' > "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP" 2> "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP" & $COMMAND_SUDO' bash -s' << 'ENDSSH' > "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP" 2> "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP" &
@@ -2369,7 +2537,7 @@ function joinString {
function _Logger { function _Logger {
local logValue="${1}" # Log to file local logValue="${1}" # Log to file
local stdValue="${2}" # Log to screeen local stdValue="${2}" # Log to screeen
local toStderr="${3:-false}" # Log to stderr instead of stdout local toStdErr="${3:-false}" # Log to stderr instead of stdout
if [ "$logValue" != "" ]; then if [ "$logValue" != "" ]; then
echo -e "$logValue" >> "$LOG_FILE" echo -e "$logValue" >> "$LOG_FILE"
@@ -2378,7 +2546,7 @@ function _Logger {
fi fi
if [ "$stdValue" != "" ] && [ "$_LOGGER_SILENT" != true ]; then if [ "$stdValue" != "" ] && [ "$_LOGGER_SILENT" != true ]; then
if [ $toStderr == true ]; then if [ $toStdErr == true ]; then
# Force stderr color in subshell # Force stderr color in subshell
(>&2 echo -e "$stdValue") (>&2 echo -e "$stdValue")
@@ -2520,7 +2688,8 @@ function _CreateDirectoryRemote {
CheckConnectivity3rdPartyHosts CheckConnectivity3rdPartyHosts
CheckConnectivityRemoteHost CheckConnectivityRemoteHost
$SSH_CMD env _DEBUG="'$_DEBUG'" env _PARANOIA_DEBUG="'$_PARANOIA_DEBUG'" env _LOGGER_SILENT="'$_LOGGER_SILENT'" env _LOGGER_VERBOSE="'$_LOGGER_VERBOSE'" env _LOGGER_PREFIX="'$_LOGGER_PREFIX'" env _LOGGER_ERR_ONLY="'$_LOGGER_ERR_ONLY'" \ $SSH_CMD env _REMOTE_TOKEN=$_REMOTE_TOKEN \
env _DEBUG="'$_DEBUG'" env _PARANOIA_DEBUG="'$_PARANOIA_DEBUG'" env _LOGGER_SILENT="'$_LOGGER_SILENT'" env _LOGGER_VERBOSE="'$_LOGGER_VERBOSE'" env _LOGGER_PREFIX="'$_LOGGER_PREFIX'" env _LOGGER_ERR_ONLY="'$_LOGGER_ERR_ONLY'" \
env PROGRAM="'$PROGRAM'" env SCRIPT_PID="'$SCRIPT_PID'" TSTAMP="'$TSTAMP'" \ env PROGRAM="'$PROGRAM'" env SCRIPT_PID="'$SCRIPT_PID'" TSTAMP="'$TSTAMP'" \
env dirToCreate="'$dirToCreate'" $COMMAND_SUDO' bash -s' << 'ENDSSH' > "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP" 2>&1 & env dirToCreate="'$dirToCreate'" $COMMAND_SUDO' bash -s' << 'ENDSSH' > "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP" 2>&1 &
@@ -2556,7 +2725,7 @@ function joinString {
function _Logger { function _Logger {
local logValue="${1}" # Log to file local logValue="${1}" # Log to file
local stdValue="${2}" # Log to screeen local stdValue="${2}" # Log to screeen
local toStderr="${3:-false}" # Log to stderr instead of stdout local toStdErr="${3:-false}" # Log to stderr instead of stdout
if [ "$logValue" != "" ]; then if [ "$logValue" != "" ]; then
echo -e "$logValue" >> "$LOG_FILE" echo -e "$logValue" >> "$LOG_FILE"
@@ -2565,7 +2734,7 @@ function _Logger {
fi fi
if [ "$stdValue" != "" ] && [ "$_LOGGER_SILENT" != true ]; then if [ "$stdValue" != "" ] && [ "$_LOGGER_SILENT" != true ]; then
if [ $toStderr == true ]; then if [ $toStdErr == true ]; then
# Force stderr color in subshell # Force stderr color in subshell
(>&2 echo -e "$stdValue") (>&2 echo -e "$stdValue")
@@ -2731,7 +2900,8 @@ function GetDiskSpaceRemote {
local cmd local cmd
local retval local retval
$SSH_CMD env _DEBUG="'$_DEBUG'" env _PARANOIA_DEBUG="'$_PARANOIA_DEBUG'" env _LOGGER_SILENT="'$_LOGGER_SILENT'" env _LOGGER_VERBOSE="'$_LOGGER_VERBOSE'" env _LOGGER_PREFIX="'$_LOGGER_PREFIX'" env _LOGGER_ERR_ONLY="'$_LOGGER_ERR_ONLY'" \ $SSH_CMD env _REMOTE_TOKEN=$_REMOTE_TOKEN \
env _DEBUG="'$_DEBUG'" env _PARANOIA_DEBUG="'$_PARANOIA_DEBUG'" env _LOGGER_SILENT="'$_LOGGER_SILENT'" env _LOGGER_VERBOSE="'$_LOGGER_VERBOSE'" env _LOGGER_PREFIX="'$_LOGGER_PREFIX'" env _LOGGER_ERR_ONLY="'$_LOGGER_ERR_ONLY'" \
env PROGRAM="'$PROGRAM'" env SCRIPT_PID="'$SCRIPT_PID'" TSTAMP="'$TSTAMP'" \ env PROGRAM="'$PROGRAM'" env SCRIPT_PID="'$SCRIPT_PID'" TSTAMP="'$TSTAMP'" \
env DF_CMD="'$DF_CMD'" \ env DF_CMD="'$DF_CMD'" \
env pathToCheck="'$pathToCheck'" $COMMAND_SUDO' bash -s' << 'ENDSSH' > "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP" 2> "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP" & env pathToCheck="'$pathToCheck'" $COMMAND_SUDO' bash -s' << 'ENDSSH' > "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP" 2> "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP" &
@@ -2768,7 +2938,7 @@ function joinString {
function _Logger { function _Logger {
local logValue="${1}" # Log to file local logValue="${1}" # Log to file
local stdValue="${2}" # Log to screeen local stdValue="${2}" # Log to screeen
local toStderr="${3:-false}" # Log to stderr instead of stdout local toStdErr="${3:-false}" # Log to stderr instead of stdout
if [ "$logValue" != "" ]; then if [ "$logValue" != "" ]; then
echo -e "$logValue" >> "$LOG_FILE" echo -e "$logValue" >> "$LOG_FILE"
@@ -2777,7 +2947,7 @@ function _Logger {
fi fi
if [ "$stdValue" != "" ] && [ "$_LOGGER_SILENT" != true ]; then if [ "$stdValue" != "" ] && [ "$_LOGGER_SILENT" != true ]; then
if [ $toStderr == true ]; then if [ $toStdErr == true ]; then
# Force stderr color in subshell # Force stderr color in subshell
(>&2 echo -e "$stdValue") (>&2 echo -e "$stdValue")
@@ -3047,10 +3217,10 @@ function _BackupDatabaseLocalToLocal {
retval=$? retval=$?
if [ -s "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP" ]; then if [ -s "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP" ]; then
if [ $_DRYRUN == false ]; then if [ $_DRYRUN == false ]; then
Logger "Command was [$sqlCmd]." "WARN" _LOGGER_SILENT=true Logger "Command was [$sqlCmd]." "WARN"
eval "$sqlCmd" & eval "$sqlCmd" &
else else
Logger "Command was [$drySqlCmd]." "WARN" _LOGGER_SILENT=true Logger "Command was [$drySqlCmd]." "WARN"
eval "$drySqlCmd" & eval "$drySqlCmd" &
fi fi
Logger "Error output:\n$(cat $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP)" "ERROR" Logger "Error output:\n$(cat $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP)" "ERROR"
@@ -3082,7 +3252,7 @@ function _BackupDatabaseLocalToRemote {
fi fi
local drySqlCmd="mysqldump -u $SQL_USER $exportOptions --databases $database $COMPRESSION_PROGRAM $COMPRESSION_OPTIONS $encryptOptions > /dev/null 2> $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP" local drySqlCmd="mysqldump -u $SQL_USER $exportOptions --databases $database $COMPRESSION_PROGRAM $COMPRESSION_OPTIONS $encryptOptions > /dev/null 2> $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP"
local sqlCmd="mysqldump -u $SQL_USER $exportOptions --databases $database $COMPRESSION_PROGRAM $COMPRESSION_OPTIONS $encryptOptions | $SSH_CMD '$COMMAND_SUDO tee \"$SQL_STORAGE/$database.sql$COMPRESSION_EXTENSION$encryptExtension\" > /dev/null' 2> $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP" local sqlCmd="mysqldump -u $SQL_USER $exportOptions --databases $database $COMPRESSION_PROGRAM $COMPRESSION_OPTIONS $encryptOptions | $SSH_CMD 'env _REMOTE_TOKEN=$_REMOTE_TOKEN $COMMAND_SUDO tee \"$SQL_STORAGE/$database.sql$COMPRESSION_EXTENSION$encryptExtension\" > /dev/null' 2> $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP"
if [ $_DRYRUN == false ]; then if [ $_DRYRUN == false ]; then
Logger "Launching command [$sqlCmd]." "DEBUG" Logger "Launching command [$sqlCmd]." "DEBUG"
@@ -3095,10 +3265,10 @@ function _BackupDatabaseLocalToRemote {
retval=$? retval=$?
if [ -s "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP" ]; then if [ -s "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP" ]; then
if [ $_DRYRUN == false ]; then if [ $_DRYRUN == false ]; then
Logger "Command was [$sqlCmd]." "WARN" _LOGGER_SILENT=true Logger "Command was [$sqlCmd]." "WARN"
eval "$sqlCmd" & eval "$sqlCmd" &
else else
Logger "Command was [$drySqlCmd]." "WARN" _LOGGER_SILENT=true Logger "Command was [$drySqlCmd]." "WARN"
eval "$drySqlCmd" & eval "$drySqlCmd" &
fi fi
Logger "Error output:\n$(cat $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP)" "ERROR" Logger "Error output:\n$(cat $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP)" "ERROR"
@@ -3129,8 +3299,8 @@ function _BackupDatabaseRemoteToLocal {
encryptExtension="$CRYPT_FILE_EXTENSION" encryptExtension="$CRYPT_FILE_EXTENSION"
fi fi
local drySqlCmd=$SSH_CMD' "mysqldump -u '$SQL_USER' '$exportOptions' --databases '$database' '$COMPRESSION_PROGRAM' '$COMPRESSION_OPTIONS' '$encryptOptions'" > /dev/null 2> "'$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP'"' local drySqlCmd=$SSH_CMD' "env _REMOTE_TOKEN=$_REMOTE_TOKEN mysqldump -u '$SQL_USER' '$exportOptions' --databases '$database' '$COMPRESSION_PROGRAM' '$COMPRESSION_OPTIONS' '$encryptOptions'" > /dev/null 2> "'$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP'"'
local sqlCmd=$SSH_CMD' "mysqldump -u '$SQL_USER' '$exportOptions' --databases '$database' '$COMPRESSION_PROGRAM' '$COMPRESSION_OPTIONS' '$encryptOptions'" > "'$SQL_STORAGE/$database.sql$COMPRESSION_EXTENSION$encryptExtension'" 2> "'$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP'"' local sqlCmd=$SSH_CMD' "env _REMOTE_TOKEN=$_REMOTE_TOKEN mysqldump -u '$SQL_USER' '$exportOptions' --databases '$database' '$COMPRESSION_PROGRAM' '$COMPRESSION_OPTIONS' '$encryptOptions'" > "'$SQL_STORAGE/$database.sql$COMPRESSION_EXTENSION$encryptExtension'" 2> "'$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP'"'
if [ $_DRYRUN == false ]; then if [ $_DRYRUN == false ]; then
Logger "Launching command [$sqlCmd]." "DEBUG" Logger "Launching command [$sqlCmd]." "DEBUG"
@@ -3143,10 +3313,10 @@ function _BackupDatabaseRemoteToLocal {
retval=$? retval=$?
if [ -s "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP" ]; then if [ -s "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP" ]; then
if [ $_DRYRUN == false ]; then if [ $_DRYRUN == false ]; then
Logger "Command was [$sqlCmd]." "WARN" _LOGGER_SILENT=true Logger "Command was [$sqlCmd]." "WARN"
eval "$sqlCmd" & eval "$sqlCmd" &
else else
Logger "Command was [$drySqlCmd]." "WARN" _LOGGER_SILENT=true Logger "Command was [$drySqlCmd]." "WARN"
eval "$drySqlCmd" & eval "$drySqlCmd" &
fi fi
Logger "Error output:\n$(cat $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP)" "ERROR" Logger "Error output:\n$(cat $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP)" "ERROR"
@@ -3283,7 +3453,7 @@ function EncryptFiles {
ParallelExec $PARALLEL_ENCRYPTION_PROCESSES "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.parallel.$SCRIPT_PID.$TSTAMP" true $softMaxExecTime $hardMaxExecTime $SLEEP_TIME $KEEP_LOGGING true true false ParallelExec $PARALLEL_ENCRYPTION_PROCESSES "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.parallel.$SCRIPT_PID.$TSTAMP" true $softMaxExecTime $hardMaxExecTime $SLEEP_TIME $KEEP_LOGGING true true false
retval=$? retval=$?
if [ $retval -ne 0 ]; then if [ $retval -ne 0 ]; then
Logger "Encryption error.." "ERROR" Logger "Encryption error." "ERROR"
# Output file is defined in ParallelExec # Output file is defined in ParallelExec
Logger "Command output:\n$(cat $RUN_DIR/$PROGRAM.ParallelExec.EncryptFiles.$SCRIPT_PID.$TSTAMP)" "DEBUG" Logger "Command output:\n$(cat $RUN_DIR/$PROGRAM.ParallelExec.EncryptFiles.$SCRIPT_PID.$TSTAMP)" "DEBUG"
fi fi
@@ -3437,13 +3607,13 @@ function Rsync {
CheckConnectivity3rdPartyHosts CheckConnectivity3rdPartyHosts
CheckConnectivityRemoteHost CheckConnectivityRemoteHost
sourceDir=$(EscapeSpaces "$sourceDir") sourceDir=$(EscapeSpaces "$sourceDir")
rsyncCmd="$(type -p $RSYNC_EXECUTABLE) $RSYNC_ARGS $RSYNC_DRY_ARG $RSYNC_ATTR_ARGS $RSYNC_TYPE_ARGS $RSYNC_NO_RECURSE_ARGS $RSYNC_DELETE $RSYNC_PATTERNS $RSYNC_PARTIAL_EXCLUDE --rsync-path=\"$RSYNC_PATH\" -e \"$RSYNC_SSH_CMD\" \"$REMOTE_USER@$REMOTE_HOST:$sourceDir\" \"$destinationDir\" > $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP 2>&1" rsyncCmd="$(type -p $RSYNC_EXECUTABLE) $RSYNC_ARGS $RSYNC_DRY_ARG $RSYNC_ATTR_ARGS $RSYNC_TYPE_ARGS $RSYNC_NO_RECURSE_ARGS $RSYNC_DELETE $RSYNC_PATTERNS $RSYNC_PARTIAL_EXCLUDE --rsync-path=\"env _REMOTE_TOKEN=$_REMOTE_TOKEN $RSYNC_PATH\" -e \"$RSYNC_SSH_CMD\" \"$REMOTE_USER@$REMOTE_HOST:$sourceDir\" \"$destinationDir\" > $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP 2>&1"
elif [ "$BACKUP_TYPE" == "push" ]; then elif [ "$BACKUP_TYPE" == "push" ]; then
destinationDir=$(EscapeSpaces "$destinationDir") destinationDir=$(EscapeSpaces "$destinationDir")
_CreateDirectoryRemote "$destinationDir" _CreateDirectoryRemote "$destinationDir"
CheckConnectivity3rdPartyHosts CheckConnectivity3rdPartyHosts
CheckConnectivityRemoteHost CheckConnectivityRemoteHost
rsyncCmd="$(type -p $RSYNC_EXECUTABLE) $RSYNC_ARGS $RSYNC_DRY_ARG $RSYNC_ATTR_ARGS $RSYNC_TYPE_ARGS $RSYNC_NO_RECURSE_ARGS $RSYNC_DELETE $RSYNC_PATTERNS $RSYNC_PARTIAL_EXCLUDE --rsync-path=\"$RSYNC_PATH\" -e \"$RSYNC_SSH_CMD\" \"$sourceDir\" \"$REMOTE_USER@$REMOTE_HOST:$destinationDir\" > $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP 2>&1" rsyncCmd="$(type -p $RSYNC_EXECUTABLE) $RSYNC_ARGS $RSYNC_DRY_ARG $RSYNC_ATTR_ARGS $RSYNC_TYPE_ARGS $RSYNC_NO_RECURSE_ARGS $RSYNC_DELETE $RSYNC_PATTERNS $RSYNC_PARTIAL_EXCLUDE --rsync-path=\"env _REMOTE_TOKEN=$_REMOTE_TOKEN $RSYNC_PATH\" -e \"$RSYNC_SSH_CMD\" \"$sourceDir\" \"$REMOTE_USER@$REMOTE_HOST:$destinationDir\" > $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP 2>&1"
fi fi
Logger "Launching command [$rsyncCmd]." "DEBUG" Logger "Launching command [$rsyncCmd]." "DEBUG"
@@ -3452,7 +3622,7 @@ function Rsync {
retval=$? retval=$?
if [ $retval -ne 0 ]; then if [ $retval -ne 0 ]; then
Logger "Failed to backup [$sourceDir] to [$destinationDir]." "ERROR" Logger "Failed to backup [$sourceDir] to [$destinationDir]." "ERROR"
Logger "Command was [$rsyncCmd]." "WARN" _LOGGER_SILENT=true Logger "Command was [$rsyncCmd]." "WARN"
Logger "Command output:\n $(cat $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP)" "ERROR" Logger "Command output:\n $(cat $RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP)" "ERROR"
else else
Logger "File backup succeed." "NOTICE" Logger "File backup succeed." "NOTICE"
@@ -3598,7 +3768,7 @@ function _RotateBackupsLocal {
WaitForTaskCompletion $! 3600 0 $SLEEP_TIME $KEEP_LOGGING true true false WaitForTaskCompletion $! 3600 0 $SLEEP_TIME $KEEP_LOGGING true true false
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
Logger "Cannot delete oldest copy [$path]." "ERROR" Logger "Cannot delete oldest copy [$path]." "ERROR"
Logger "Command was [$cmd]." "WARN" _LOGGER_SILENT=true Logger "Command was [$cmd]." "WARN"
fi fi
fi fi
fi fi
@@ -3611,7 +3781,7 @@ function _RotateBackupsLocal {
WaitForTaskCompletion $! 3600 0 $SLEEP_TIME $KEEP_LOGGING true true false WaitForTaskCompletion $! 3600 0 $SLEEP_TIME $KEEP_LOGGING true true false
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
Logger "Cannot move [$path] to [$backup.$PROGRAM.$copy]." "ERROR" Logger "Cannot move [$path] to [$backup.$PROGRAM.$copy]." "ERROR"
Logger "Command was [$cmd]." "WARN" _LOGGER_SILENT=true Logger "Command was [$cmd]." "WARN"
fi fi
fi fi
@@ -3626,7 +3796,7 @@ function _RotateBackupsLocal {
WaitForTaskCompletion $! 3600 0 $SLEEP_TIME $KEEP_LOGGING true true false WaitForTaskCompletion $! 3600 0 $SLEEP_TIME $KEEP_LOGGING true true false
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
Logger "Cannot move [$backup] to [$backup.$PROGRAM.1]." "ERROR" Logger "Cannot move [$backup] to [$backup.$PROGRAM.1]." "ERROR"
Logger "Command was [$cmd]." "WARN" _LOGGER_SILENT=true Logger "Command was [$cmd]." "WARN"
fi fi
elif [ "$REMOTE_OPERATION" == "yes" ]; then elif [ "$REMOTE_OPERATION" == "yes" ]; then
@@ -3636,7 +3806,7 @@ function _RotateBackupsLocal {
WaitForTaskCompletion $! 3600 0 $SLEEP_TIME $KEEP_LOGGING true true false WaitForTaskCompletion $! 3600 0 $SLEEP_TIME $KEEP_LOGGING true true false
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
Logger "Cannot copy [$backup] to [$backup.$PROGRAM.1]." "ERROR" Logger "Cannot copy [$backup] to [$backup.$PROGRAM.1]." "ERROR"
Logger "Command was [$cmd]." "WARN" _LOGGER_SILENT=true Logger "Command was [$cmd]." "WARN"
fi fi
else else
@@ -3646,7 +3816,7 @@ function _RotateBackupsLocal {
WaitForTaskCompletion $! 3600 0 $SLEEP_TIME $KEEP_LOGGING true true false WaitForTaskCompletion $! 3600 0 $SLEEP_TIME $KEEP_LOGGING true true false
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
Logger "Cannot move [$backup] to [$backup.$PROGRAM.1]." "ERROR" Logger "Cannot move [$backup] to [$backup.$PROGRAM.1]." "ERROR"
Logger "Command was [$cmd]." "WARN" _LOGGER_SILENT=true Logger "Command was [$cmd]." "WARN"
fi fi
fi fi
done done
@@ -3656,7 +3826,8 @@ function _RotateBackupsRemote {
local backupPath="${1}" local backupPath="${1}"
local rotateCopies="${2}" local rotateCopies="${2}"
$SSH_CMD env _DEBUG="'$_DEBUG'" env _PARANOIA_DEBUG="'$_PARANOIA_DEBUG'" env _LOGGER_SILENT="'$_LOGGER_SILENT'" env _LOGGER_VERBOSE="'$_LOGGER_VERBOSE'" env _LOGGER_PREFIX="'$_LOGGER_PREFIX'" env _LOGGER_ERR_ONLY="'$_LOGGER_ERR_ONLY'" \ $SSH_CMD env _REMOTE_TOKEN=$_REMOTE_TOKEN \
env _DEBUG="'$_DEBUG'" env _PARANOIA_DEBUG="'$_PARANOIA_DEBUG'" env _LOGGER_SILENT="'$_LOGGER_SILENT'" env _LOGGER_VERBOSE="'$_LOGGER_VERBOSE'" env _LOGGER_PREFIX="'$_LOGGER_PREFIX'" env _LOGGER_ERR_ONLY="'$_LOGGER_ERR_ONLY'" \
env PROGRAM="'$PROGRAM'" env SCRIPT_PID="'$SCRIPT_PID'" TSTAMP="'$TSTAMP'" \ env PROGRAM="'$PROGRAM'" env SCRIPT_PID="'$SCRIPT_PID'" TSTAMP="'$TSTAMP'" \
env REMOTE_FIND_CMD="'$REMOTE_FIND_CMD'" env rotateCopies="'$rotateCopies'" env backupPath="'$backupPath'" \ env REMOTE_FIND_CMD="'$REMOTE_FIND_CMD'" env rotateCopies="'$rotateCopies'" env backupPath="'$backupPath'" \
$COMMAND_SUDO' bash -s' << 'ENDSSH' > "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP" 2> "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP" $COMMAND_SUDO' bash -s' << 'ENDSSH' > "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.$SCRIPT_PID.$TSTAMP" 2> "$RUN_DIR/$PROGRAM.${FUNCNAME[0]}.error.$SCRIPT_PID.$TSTAMP"
@@ -3693,7 +3864,7 @@ function joinString {
function _Logger { function _Logger {
local logValue="${1}" # Log to file local logValue="${1}" # Log to file
local stdValue="${2}" # Log to screeen local stdValue="${2}" # Log to screeen
local toStderr="${3:-false}" # Log to stderr instead of stdout local toStdErr="${3:-false}" # Log to stderr instead of stdout
if [ "$logValue" != "" ]; then if [ "$logValue" != "" ]; then
echo -e "$logValue" >> "$LOG_FILE" echo -e "$logValue" >> "$LOG_FILE"
@@ -3702,7 +3873,7 @@ function _Logger {
fi fi
if [ "$stdValue" != "" ] && [ "$_LOGGER_SILENT" != true ]; then if [ "$stdValue" != "" ] && [ "$_LOGGER_SILENT" != true ]; then
if [ $toStderr == true ]; then if [ $toStdErr == true ]; then
# Force stderr color in subshell # Force stderr color in subshell
(>&2 echo -e "$stdValue") (>&2 echo -e "$stdValue")
@@ -3901,23 +4072,23 @@ function Init {
REMOTE_HOST=${hosturi%%:*} REMOTE_HOST=${hosturi%%:*}
fi fi
## Add update to default RSYNC_ARGS ## Add update to default RSYNC_TYPE_ARGS
RSYNC_ARGS=$RSYNC_ARGS" -u" RSYNC_TYPE_ARGS=$RSYNC_TYPE_ARGS" -u"
if [ $_LOGGER_VERBOSE == true ]; then if [ $_LOGGER_VERBOSE == true ]; then
RSYNC_ARGS=$RSYNC_ARGS" -i" RSYNC_TYPE_ARGS=$RSYNC_TYPE_ARGS" -i"
fi fi
if [ "$DELETE_VANISHED_FILES" == "yes" ]; then if [ "$DELETE_VANISHED_FILES" == "yes" ]; then
RSYNC_ARGS=$RSYNC_ARGS" --delete" RSYNC_TYPE_ARGS=$RSYNC_TYPE_ARGS" --delete"
fi fi
if [ $stats == true ]; then if [ $stats == true ]; then
RSYNC_ARGS=$RSYNC_ARGS" --stats" RSYNC_TYPE_ARGS=$RSYNC_TYPE_ARGS" --stats"
fi fi
## Fix for symlink to directories on target cannot get updated ## Fix for symlink to directories on target cannot get updated
RSYNC_ARGS=$RSYNC_ARGS" --force" RSYNC_TYPE_ARGS=$RSYNC_TYPE_ARGS" --force"
} }
function Main { function Main {
@@ -4004,12 +4175,16 @@ function Usage {
_DRYRUN=false _DRYRUN=false
no_maxtime=false no_maxtime=false
stats=false stats=false
PARTIAL=no partial_transfers=false
delete_vanished=false
dont_get_backup_size=false
_DECRYPT_MODE=false _DECRYPT_MODE=false
DECRYPT_PATH="" DECRYPT_PATH=""
_ENCRYPT_MODE=false _ENCRYPT_MODE=false
function GetCommandlineArguments { function GetCommandlineArguments {
local isFirstArgument=true
if [ $# -eq 0 ]; then if [ $# -eq 0 ]; then
Usage Usage
fi fi
@@ -4029,16 +4204,16 @@ function GetCommandlineArguments {
stats=false stats=false
;; ;;
--partial) --partial)
PARTIAL="yes" partial_transfers=true
;; ;;
--no-maxtime) --no-maxtime)
no_maxtime=true no_maxtime=true
;; ;;
--delete) --delete)
DELETE_VANISHED_FILES="yes" delete_vanished=true
;; ;;
--dontgetsize) --dontgetsize)
GET_BACKUP_SIZE="no" dont_get_backup_size=true
;; ;;
--help|-h|--version|-v) --help|-h|--version|-v)
Usage Usage
@@ -4074,7 +4249,15 @@ function GetCommandlineArguments {
if [ $(IsNumeric $PARALLEL_ENCRYPTION_PROCESSES) -ne 1 ]; then if [ $(IsNumeric $PARALLEL_ENCRYPTION_PROCESSES) -ne 1 ]; then
Logger "Bogus --parallel value. Using only one CPU." "WARN" Logger "Bogus --parallel value. Using only one CPU." "WARN"
fi fi
;;
*)
if [ $isFirstArgument == false ]; then
Logger "Unknown option '$i'" "CRITICAL"
Usage
fi
;;
esac esac
isFirstArgument=false
done done
} }
@@ -4116,6 +4299,27 @@ else
Logger "Script begin, logging to [$LOG_FILE]." "DEBUG" Logger "Script begin, logging to [$LOG_FILE]." "DEBUG"
fi fi
if [ $no_maxtime == true ]; then
SOFT_MAX_EXEC_TIME_DB_TASK=0
SOFT_MAX_EXEC_TIME_FILE_TASK=0
HARD_MAX_EXEC_TIME_DB_TASK=0
HARD_MAX_EXEC_TIME_FILE_TASK=0
HARD_MAX_EXEC_TIME_TOTAL=0
fi
if [ $partial_transfers == true ]; then
PARTIAL="yes"
fi
if [ $delete_vanished == true ]; then
DELETE_VANISHED_FILES="yes"
fi
if [ $dont_get_backup_size == true ]; then
GET_BACKUP_SIZE="no"
fi
if [ "$IS_STABLE" != "yes" ]; then if [ "$IS_STABLE" != "yes" ]; then
Logger "This is an unstable dev build [$PROGRAM_BUILD]. Please use with caution." "WARN" Logger "This is an unstable dev build [$PROGRAM_BUILD]. Please use with caution." "WARN"
fi fi
@@ -4136,13 +4340,5 @@ PostInit
CheckCurrentConfig CheckCurrentConfig
GetRemoteOS GetRemoteOS
InitRemoteOSDependingSettings InitRemoteOSDependingSettings
if [ $no_maxtime == true ]; then
SOFT_MAX_EXEC_TIME_DB_TASK=0
SOFT_MAX_EXEC_TIME_FILE_TASK=0
HARD_MAX_EXEC_TIME_DB_TASK=0
HARD_MAX_EXEC_TIME_FILE_TASK=0
HARD_MAX_EXEC_TIME_TOTAL=0
fi
RunBeforeHook RunBeforeHook
Main Main

View File

@@ -5,102 +5,49 @@
##### It will filter the commands that can be run remotely via ssh. ##### It will filter the commands that can be run remotely via ssh.
##### Please chmod 755 and chown root:root this file ##### Please chmod 755 and chown root:root this file
##### Obackup needed commands: rsync find du mysql mysqldump (sudo) ##### Any command that has env _REMOTE_TOKEN= with the corresponding token in it will be run
##### Osync needed commands: rsync find du echo mkdir rm if df (sudo) ##### Any other command will return a "syntax error"
SCRIPT_BUILD=2016031401 ##### For details, see ssh_filter.log
## If enabled, execution of "sudo" command will be allowed. SCRIPT_BUILD=2017020802
## Allow sudo
SUDO_EXEC=yes SUDO_EXEC=yes
## Paranoia option. Don't change this unless you read the documentation and still feel concerned about security issues.
RSYNC_EXECUTABLE=rsync
## Enable other commands, useful for remote execution hooks like remotely creating snapshots.
CMD1=""
CMD2=""
CMD3=""
LOG_FILE=~/.ssh/ssh_filter.log ## Log all valid commands too
_DEBUG=no
## Set remote token in authorized_keys
if [ "$1" != "" ]; then
_REMOTE_TOKEN="${1}"
fi
LOG_FILE="${HOME}/.ssh/ssh_filter.log"
function Log { function Log {
DATE=$(date) DATE=$(date)
echo "$DATE - $1" >> $LOG_FILE echo "$DATE - $1" >> "$LOG_FILE"
} }
function Go { function Go {
if [ "$_DEBUG" == "yes" ]; then
Log "Executing [$SSH_ORIGINAL_COMMAND]."
fi
eval "$SSH_ORIGINAL_COMMAND" eval "$SSH_ORIGINAL_COMMAND"
} }
case ${SSH_ORIGINAL_COMMAND%% *} in case "${SSH_ORIGINAL_COMMAND}" in
"$RSYNC_EXECUTABLE") *"env _REMOTE_TOKEN=$_REMOTE_TOKEN"*)
Go ;; if [ "$SUDO_EXEC" != "yes" ] && [[ $SSH_ORIGINAL_COMMAND == *"sudo "* ]]; then
"echo") Log "Command [$SSH_ORIGINAL_COMMAND] contains sudo which is not allowed."
Go ;; echo "Syntax error unexpected end of file"
"find")
Go ;;
"du")
Go ;;
"mkdir")
Go ;;
"rm")
Go ;;
"df")
Go ;;
"mv")
Go ;;
"$CMD1")
if [ "$CMD1" != "" ]; then
Go
fi
;;
"$CMD2")
if [ "$CMD2" != "" ]; then
Go
fi
;;
"$CMD3")
if [ "$CMD3" != "" ]; then
Go
fi
;;
"sudo")
if [ "$SUDO_EXEC" == "yes" ]; then
if [[ "$SSH_ORIGINAL_COMMAND" == "sudo $RSYNC_EXECUTABLE"* ]]; then
Go
elif [[ "$SSH_ORIGINAL_COMMAND" == "sudo du"* ]]; then
Go
elif [[ "$SSH_ORIGINAL_COMMAND" == "sudo find"* ]]; then
Go
elif [[ "$SSH_ORIGINAL_COMMAND" == "sudo mkdir"* ]]; then
Go
elif [[ "$SSH_ORIGINAL_COMMAND" == "sudo rm"* ]]; then
Go
elif [[ "$SSH_ORIGINAL_COMMAND" == "sudo echo"* ]]; then
Go
elif [[ "$SSH_ORIGINAL_COMMAND" == "sudo df"* ]]; then
Go
elif [[ "$SSH_ORIGINAL_COMMAND" == "sudo mv"* ]]; then
Go
elif [[ "$SSH_ORIGINAL_COMMAND" == "sudo $CMD1"* ]]; then
if [ "$CMD1" != "" ]; then
Go
fi
elif [[ "$SSH_ORIGINAL_COMMAND" == "sudo $CMD2"* ]]; then
if [ "$CMD2" != "" ]; then
Go
fi
elif [[ "$SSH_ORIGINAL_COMMAND" == "sudo $CMD3"* ]]; then
if [ "$CMD3" != "" ]; then
Go
fi
else
Log "Command [$SSH_ORIGINAL_COMMAND] not allowed."
exit 1 exit 1
fi fi
else Go
Log "Command [$SSH_ORIGINAL_COMMAND] not allowed. sudo not enabled."
exit 1
fi
;; ;;
*) *)
Log "Command [$SSH_ORIGINAL_COMMAND] not allowed." Log "Command [$SSH_ORIGINAL_COMMAND] not allowed."
echo "Syntax error near unexpected token"
exit 1 exit 1
;;
esac esac

View File

@@ -6,7 +6,7 @@ AUTHOR="(C) 2016 by Orsiris de Jong"
CONTACT="http://www.netpower.fr/obacup - ozy@netpower.fr" CONTACT="http://www.netpower.fr/obacup - ozy@netpower.fr"
OLD_PROGRAM_VERSION="v1.x" OLD_PROGRAM_VERSION="v1.x"
NEW_PROGRAM_VERSION="v2.1x" NEW_PROGRAM_VERSION="v2.1x"
CONFIG_FILE_VERSION=2017010201 CONFIG_FILE_VERSION=2017020901
PROGRAM_BUILD=2016113001 PROGRAM_BUILD=2016113001
if ! type "$BASH" > /dev/null; then if ! type "$BASH" > /dev/null; then
@@ -39,6 +39,7 @@ FILE_WARN_MIN_SPACE
REMOTE_SYSTEM_URI REMOTE_SYSTEM_URI
SSH_RSA_PRIVATE_KEY SSH_RSA_PRIVATE_KEY
SSH_PASSWORD_FILE SSH_PASSWORD_FILE
_REMOTE_TOKEN
SSH_COMPRESSION SSH_COMPRESSION
SSH_IGNORE_KNOWN_HOSTS SSH_IGNORE_KNOWN_HOSTS
RSYNC_REMOTE_PATH RSYNC_REMOTE_PATH
@@ -81,6 +82,7 @@ DELTA_COPIES
BANDWIDTH BANDWIDTH
RSYNC_EXECUTABLE RSYNC_EXECUTABLE
DESTINATION_MAILS DESTINATION_MAILS
MAIL_BODY_CHARSET
SENDER_MAIL SENDER_MAIL
SMTP_SERVER SMTP_SERVER
SMTP_PORT SMTP_PORT
@@ -125,6 +127,7 @@ yes
ssh://backupuser@remote.system.tld:22/ ssh://backupuser@remote.system.tld:22/
${HOME}/.ssh/id_rsa ${HOME}/.ssh/id_rsa
'' ''
SomeAlphaNumericToken9
yes yes
no no
'' ''
@@ -167,6 +170,7 @@ yes
0 0
rsync rsync
infrastructure@example.com infrastructure@example.com
''
sender@example.com sender@example.com
smtp.isp.tld smtp.isp.tld
25 25