Compare commits
34 Commits
Author | SHA1 | Date |
---|---|---|
Harald Welte | 260f4786c0 | |
Harald Welte | 73d86aeb20 | |
Janek Bevendorff | 0cc469f2b5 | |
Janek Bevendorff | a8b36864e6 | |
Janek Bevendorff | c7427cf61d | |
Janek Bevendorff | 0a3d0cff18 | |
Janek Bevendorff | 8416d9a088 | |
Janek Bevendorff | 4f35991986 | |
Janek Bevendorff | 51f514506c | |
Janek Bevendorff | 5f03542d07 | |
Janek Bevendorff | 1a0c1b984f | |
Janek Bevendorff | 78853b7703 | |
Janek Bevendorff | fbe3702c90 | |
Janek Bevendorff | f22b634607 | |
Janek Bevendorff | 0f1b35e57c | |
Janek Bevendorff | 4b84ad5997 | |
Janek Bevendorff | 2c4d2915e5 | |
Janek Bevendorff | 52d0a17cae | |
Janek Bevendorff | 9c9eb7b98a | |
Janek Bevendorff | 3fae0fa63a | |
Janek Bevendorff | e68fed9277 | |
Janek Bevendorff | 18a2cc2774 | |
Janek Bevendorff | 2ac6c3fb6c | |
Janek Bevendorff | fe570455cf | |
Janek Bevendorff | 6ba2d541fa | |
Janek Bevendorff | 585cfa4a81 | |
Janek Bevendorff | d6e66ec303 | |
Janek Bevendorff | 0f0f43fc47 | |
Janek Bevendorff | 71a5983d27 | |
Janek Bevendorff | 5da9c7f6a7 | |
Janek Bevendorff | e9dc07e3e2 | |
Janek Bevendorff | 0f1cb0be0d | |
Janek Bevendorff | c502982cac | |
Janek Bevendorff | 785c0245f0 |
59
README.md
59
README.md
|
@ -51,17 +51,17 @@ rs-backup-suite can chroot backup users into the backup home base directory. For
|
|||
|
||||
# BEGIN: rs-backup-suite
|
||||
#/bin /bkp/bin none bind 0 0
|
||||
#/bin /bkp/bin none remount,ro 0 0
|
||||
#/bin /bkp/bin none remount,ro,bind 0 0
|
||||
#/lib /bkp/lib none bind 0 0
|
||||
#/lib /bkp/lib none remount,ro 0 0
|
||||
#/lib /bkp/lib none remount,ro,bind 0 0
|
||||
#/dev /bkp/dev none bind 0 0
|
||||
#/dev /bkp/dev none remount,ro 0 0
|
||||
#/dev /bkp/dev none remount,ro,bind 0 0
|
||||
#/usr/bin /bkp/usr/bin none bind 0 0
|
||||
#/usr/bin /bkp/usr/bin none remount,ro 0 0
|
||||
#/usr/bin /bkp/usr/bin none remount,ro,bind 0 0
|
||||
#/usr/lib /bkp/usr/lib none bind 0 0
|
||||
#/usr/lib /bkp/usr/lib none remount,ro 0 0
|
||||
#/usr/lib /bkp/usr/lib none remount,ro,bind 0 0
|
||||
#/usr/share/perl5 /bkp/usr/share/perl5 none bind 0 0
|
||||
#/usr/share/perl5 /bkp/usr/share/perl5 none remount,ro 0 0
|
||||
#/usr/share/perl5 /bkp/usr/share/perl5 none remount,ro,bind 0 0
|
||||
# END: rs-backup-suite
|
||||
|
||||
The necessary mounts may differ from system to system. For instance, Ubuntu needs `/usr/share/perl` instead of `/usr/share/perl5`. Synology DSM doesn't need `/usr/share/*` at all, but requires `/opt/bin`, `/opt/lib` and `/opt/libexec`. But in most cases you don't need to worry about that since the install script tries to make the correct decisions for you.
|
||||
|
@ -69,7 +69,7 @@ The necessary mounts may differ from system to system. For instance, Ubuntu need
|
|||
**NOTE:** If your 64-bit system doesn't have a `/lib` folder but only `/lib64` you may need to change the `/lib` line in your `/etc/fstab` as follows:
|
||||
|
||||
/lib64 /bkp/lib64 none bind 0 0
|
||||
/lib64 /bkp/lib64 none remount,ro 0 0
|
||||
/lib64 /bkp/lib64 none remount,ro,bind 0 0
|
||||
|
||||
Don't forget to rename `/bkp/lib` to `/bkp/lib64`. The do the same with `/usr/lib` / `/usr/lib64`.
|
||||
|
||||
|
@ -82,6 +82,8 @@ and restart OpenSSH. Your backup users are now chrooted into `/bkp`.
|
|||
|
||||
**NOTE:** When using a chroot environment and you change anything in your user configuration (e.g. the username) you need to run `rs-update-passwd` or your user might not be able to log in anymore.
|
||||
|
||||
**NOTE about logging:** Be aware that logging of backup success or failure on the server side will not work in a chroot environment since we mounted all our binds read-only. Additionally, certain files and libraries needed by the syslog facility may not be available. So if you want server-side logging, you cannot use chroot. Client-side logging will still work, of course.
|
||||
|
||||
#### Changing the rotation options/backup levels
|
||||
To change how many increments of which level are kept, edit the file `/bkp/etc/rsnapshot.global.conf`. This is the global configuration file for rsnapshot which will be included in each user-specific configuration. There you can tweak the names and numbers for all backup levels.
|
||||
|
||||
|
@ -132,8 +134,23 @@ This removes all the scripts but preserves the data in `/bkp` (or whatever your
|
|||
## Backup strategies
|
||||
The intended use case for rs-backup-suite is as follows: you set up the server part on your NAS. Then you create a backup user for each user on each client machine.
|
||||
|
||||
### Cron
|
||||
In the next step you edit the crontab for root on each client and add a job for running `/usr/bin/rs-backup-run` at certain times. You can of course also create a shell script that calls `rs-backup-run` and put it in `/etc/cron.daily` to perform a global backup once a day.
|
||||
|
||||
### Alternative: systemd
|
||||
Since version 0.2.5, rs-backup-run comes with systemd unit files which you can use for automatically running daily backups instead.
|
||||
To enable the timer, run
|
||||
|
||||
systemctl enable rs-backup-run.timer
|
||||
systemctl start rs-backup-run.timer
|
||||
|
||||
This will enable the timer when booting the system. By default, the timer is set to run once every day (or immediately if the system was down during the last timer tick).
|
||||
|
||||
You can also start a full system backup manually at any time by running
|
||||
|
||||
systemctl start rs-backup-run.service
|
||||
|
||||
### Inclusion patterns
|
||||
After everything is set up that way you create the file `/etc/rs-backup/include-file` and write to it a list of files and folders you want to back up as root (e.g. you can specify `/etc/***` to backup the whole `/etc` directory and all its subdirectories). Furthermore each user creates a file called `.rs-backup/include` inside his home directory that serves the same purpose for his own home directory instead of the global system. Such a file could look like this:
|
||||
|
||||
- /home/johndoe/.cache/***
|
||||
|
@ -164,32 +181,42 @@ Because rs-backup-suite uses rsync for the client-server communication you don't
|
|||
rs-backup-suite is designed to work on most generic Linux systems, but some embedded systems may require some extra love (especially those running on busybox):
|
||||
|
||||
### Synology DSM
|
||||
To run the server component on Synology DSM, you need to install the following packages via [ipkg](http://www.synology-wiki.de/index.php/IPKG):
|
||||
To run the server component on Synology DSM, you need to install the following packages via [Entware-ng / opkg](https://github.com/Entware-ng/Entware-ng/wiki/Install-on-Synology-NAS):
|
||||
|
||||
* `rsnapshot`
|
||||
* `openssh-sftp-server`
|
||||
* `util-linux-ng`
|
||||
* `logger`
|
||||
|
||||
In `/etc/ssh/sshd_config` make sure you replace whatever line contains the subsystem configuration for the sftp server with
|
||||
|
||||
Subsystem sftp /opt/libexec/sftp-server
|
||||
|
||||
and restart the SSH server using the configuration utility from the web interace. If you are using the `synoservicectl` utility from the command line instead, make sure you are actually starting the correct SSH server from `/usr/sbin` and not from `/opt/sbin` (although that works as well, but would have a different configuration file).
|
||||
|
||||
If you want to run your backups in a chroot environment please note that `/etc/fstab` will be reset to its defaults when rebooting the disk station. To avoid configuration loss, no mount directives are added to `/etc/fstab` by the install script. Instead the following entries are added to `/etc/rc` (which won't be overwritten upon reboot):
|
||||
|
||||
# BEGIN: rs-backup-suite
|
||||
#mount -o bind /bin /var/services/homes/bin
|
||||
#mount -o remount,ro /var/services/homes/bin
|
||||
#mount -o remount,ro,bind /var/services/homes/bin
|
||||
#mount -o bind /lib /var/services/homes/lib
|
||||
#mount -o remount,ro /var/services/homes/lib
|
||||
#mount -o remount,ro,bind /var/services/homes/lib
|
||||
#mount -o bind /dev /var/services/homes/dev
|
||||
#mount -o remount,ro /var/services/homes/dev
|
||||
#mount -o remount,ro,bind /var/services/homes/dev
|
||||
#mount -o bind /usr/bin /var/services/homes/usr/bin
|
||||
#mount -o remount,ro /var/services/homes/usr/bin
|
||||
#mount -o remount,ro,bind /var/services/homes/usr/bin
|
||||
#mount -o bind /opt/bin /var/services/homes/opt/bin
|
||||
#mount -o remount,ro /var/services/homes/opt/bin
|
||||
#mount -o remount,ro,bind /var/services/homes/opt/bin
|
||||
#mount -o bind /opt/lib /var/services/homes/opt/lib
|
||||
#mount -o remount,ro /var/services/homes/opt/lib
|
||||
#mount -o remount,ro,bind /var/services/homes/opt/lib
|
||||
#mount -o bind /opt/libexec /var/services/homes/opt/libexec
|
||||
#mount -o remount,ro /var/services/homes/opt/libexec
|
||||
#mount -o remount,ro,bind /var/services/homes/opt/libexec
|
||||
# END: rs-backup-suite
|
||||
|
||||
To enable the mounts, uncomment everything between the `BEGIN` and `END` block. Afterwards either run these commands by hand once or reboot.
|
||||
To enable the mounts, uncomment everything between the `BEGIN` and `END` block. Afterwards either run these commands by hand once or reboot. Of course, don't forget to also set the correct chroot path in `/etc/ssh/sshd_config` and restart the SSH daemon:
|
||||
|
||||
Match Group backup
|
||||
ChrootDirectory /var/services/homes/
|
||||
|
||||
### Cygwin
|
||||
The server component is incompatible with Cygwin for several reasons, but the client component works just fine. At the moment, though, there is no root mode for backing up all home directories at once. Desktop notifications are also unsupported.
|
||||
|
|
|
@ -24,20 +24,17 @@ REMOTE_USER="%h-%u"
|
|||
#SSH_OPTIONS="-C -i .ssh/id_rsa"
|
||||
|
||||
# Additional options for rsync
|
||||
RSYNC_OPTIONS="--acls --hard-links --xattrs"
|
||||
#
|
||||
# For systems that don't support it (e.g. Synology DSM), you may
|
||||
# need to remove the --acls option
|
||||
#
|
||||
# The block size setting should avoid hangs when backing up larger
|
||||
# files. It's set to the default maximum value allowed by rsync.
|
||||
# If you need larger values, recompile rsync with MAX_BLOCK_SIZE
|
||||
# set to an appropriate value.
|
||||
RSYNC_OPTIONS="--acls --hard-links --xattrs --block-size=131072"
|
||||
#RSYNC_OPTIONS="--hard-links --xattrs"
|
||||
|
||||
# Global log file to use when running as root
|
||||
LOG_FILE="/var/log/rs-backup.log"
|
||||
|
||||
# Log filename (only basename) of the log file to use when running as a
|
||||
# normal user. The file will be placed inside the user's home directory.
|
||||
# Leave empty if you don't want any per-user log file.
|
||||
# The user log file will only be written when the user originally invoked
|
||||
# the script, not if his home directory is backed up during a full system
|
||||
# backup run by root
|
||||
USER_LOG_FILE="rs-backup.user.log"
|
||||
|
||||
# Name of the file inside the users' home directories
|
||||
# containing the patterns for matching files to include or exclude.
|
||||
# The format is the same as the global 'include-files' config file
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
[Unit]
|
||||
Description=Start backup via rs-backup-suite
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=/usr/bin/rs-backup-run
|
|
@ -0,0 +1,10 @@
|
|||
[Unit]
|
||||
Description=Run rs-backup-run every day
|
||||
|
||||
[Timer]
|
||||
OnCalendar=daily
|
||||
Persistent=true
|
||||
Unit=rs-backup-run.service
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
|
@ -1,6 +1,6 @@
|
|||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
##
|
||||
# Copyright (C) 2013-2015 Janek Bevendorff
|
||||
# Copyright (C) 2013-2016 Janek Bevendorff
|
||||
# Website: http://www.refining-linux.org/
|
||||
#
|
||||
# Script to push backups to a remote rsync backup server.
|
||||
|
@ -44,12 +44,20 @@ _VERSION=$(rs-version version)
|
|||
_GLOBAL_INCLUSION_PATTERN_FILE="/etc/rs-backup/include-files"
|
||||
_FORCED_INCLUSION_PATTERN_FILE=""
|
||||
_SKIP_HOME_DIRS=false
|
||||
_FALLBACK_LOG_FILE="/var/log/rs-backup.log"
|
||||
_FALLBACK_USER_LOG_FILE="rs-backup.user.log"
|
||||
_FORCED_LOG_FILE=""
|
||||
_QUIET_MODE=false
|
||||
_VERBOSE_MODE=false
|
||||
_SHOW_PROGRESS=false
|
||||
_DRY_RUN=false
|
||||
_FORCE_RUN=false
|
||||
_PRE_HOOK=""
|
||||
_PRE_HOOK_RUN=false
|
||||
_POST_HOOK=""
|
||||
_POST_HOOK_RUN=false
|
||||
_FORCED_POST_HOOK=""
|
||||
_FORCED_POST_HOOK_RUN=false
|
||||
_ERROR_COUNT=0
|
||||
|
||||
if [ $(id -u) -eq 0 ]; then
|
||||
|
@ -101,12 +109,24 @@ Options:
|
|||
performed, no additional home directories will be
|
||||
backed up
|
||||
-l, --log-level=NUM Set log level to NUM (between 0 and 4)
|
||||
--log-file=FILE Set a different log file location
|
||||
--log-file=FILE Log to this file instead of syslog
|
||||
-f, --force-run Force rs-backup to run, even if a lock file exists
|
||||
-q, --quiet Don't print any error messages or warnings to the
|
||||
screen (only write to log file)
|
||||
-v, --verbose Print all messages of the current debug level
|
||||
-p, --progress Print file transfer information to the terminal
|
||||
--pre-hook=CMD Command to be run before the backup. Will only be run
|
||||
once for multi-user / global system backup. The hook
|
||||
command will be executed as the user who started the
|
||||
backup command
|
||||
--post-hook=CMD Similar to --pre-hook, but run after the backup
|
||||
has successfully finished. If an error occurred
|
||||
during the backup, the post hook will not be run.
|
||||
--forced-post-hook=CMD Same as --post-hook, but will always be run, regardless
|
||||
of wether an error occurred or not. Will also be run
|
||||
if the backup was interrupted by SIGINT or SIGTERM.
|
||||
If both --post-hook and --forced-post-hook are specified,
|
||||
--post-hook is run first
|
||||
-h, --help Print this help and exit
|
||||
HELP
|
||||
}
|
||||
|
@ -116,43 +136,62 @@ HELP
|
|||
# Usage: write_log <log level> <log message>
|
||||
#
|
||||
write_log() {
|
||||
local log_msg
|
||||
local log_date
|
||||
local log_msg="${2}"
|
||||
local log_date="[$(date)]"
|
||||
local log_dest
|
||||
local use_syslog=false
|
||||
local logger="logger -t $(basename $0)"
|
||||
|
||||
command -v logger > /dev/null 2>&1
|
||||
if [ $? -eq 0 ] && [ "${_FORCED_LOG_FILE}" == "" ]; then
|
||||
use_syslog=true
|
||||
fi
|
||||
|
||||
if [ $1 -gt 0 ] && [ $1 -le $LOG_LEVEL ]; then
|
||||
if $use_syslog; then
|
||||
case $1 in
|
||||
1) log_msg="ERROR: ${2}" ;;
|
||||
2) log_msg="WARNING: ${2}" ;;
|
||||
3) log_msg="INFO: ${2}" ;;
|
||||
*) log_msg="DEBUG: ${2}" ;;
|
||||
1) $logger -p err "${log_msg}" ;;
|
||||
2) $logger -p warning "${log_msg}" ;;
|
||||
3) $logger -p info "${log_msg}" ;;
|
||||
*) $logger -p debug "${log_msg}" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# prepend priority prefixes to message for further logging output
|
||||
case $1 in
|
||||
1) log_msg="ERROR: ${log_msg}" ;;
|
||||
2) log_msg="WARNING: ${log_msg}" ;;
|
||||
3) log_msg="INFO: ${log_msg}" ;;
|
||||
*) log_msg="DEBUG: ${log_msg}" ;;
|
||||
esac
|
||||
|
||||
log_date="[$(date)]"
|
||||
full_log_msg="${log_date} ${log_msg}"
|
||||
|
||||
# if no syslog facility exists, go the cumbersome way...
|
||||
if ! $use_syslog || [ "${_FORCED_LOG_FILE}" != "" ]; then
|
||||
if [ "${_FORCED_LOG_FILE}" != "" ]; then
|
||||
log_dest=${_FORCED_LOG_FILE}
|
||||
elif [ $(id -u) -eq 0 ]; then
|
||||
log_dest=${LOG_FILE}
|
||||
elif [ "${HOME}" != "" ] && [ "${USER_LOG_FILE}" != "" ]; then
|
||||
log_dest=${HOME}/${USER_LOG_FILE}
|
||||
log_dest=${_FALLBACK_LOG_FILE}
|
||||
elif [ "${HOME}" != "" ] && [ "${_FALLBACK_USER_LOG_FILE}" != "" ]; then
|
||||
log_dest=${HOME}/${_FALLBACK_USER_LOG_FILE}
|
||||
else
|
||||
echo "WARNING: Couldn't determine valid log file location, using '/var/tmp'..." >&2
|
||||
log_dest="/var/tmp/${LOG_FILE}"
|
||||
echo -e "\e[1mWARNING: Couldn't determine valid log file location, using '/var/tmp'...\e[0m" >&2
|
||||
log_dest="/var/tmp/$(basename ${LOG_FILE})"
|
||||
fi
|
||||
|
||||
touch "${log_dest}" 2> /dev/null
|
||||
if ! test_file_perms "w" "${log_dest}"; then
|
||||
echo "ERROR: Couldn't open log file for writing, redirecting to STDOUT!" >&2
|
||||
echo -e "\e[1m\e[91mERROR: Couldn't open log file for writing, redirecting to STDOUT!\e[0m" >&2
|
||||
echo "${log_date} ${log_msg}" >&1
|
||||
else
|
||||
echo "${log_date} ${log_msg}" >> "${log_dest}"
|
||||
fi
|
||||
fi
|
||||
|
||||
# after logging stuff, print it to the screen if we're not in quiet mode
|
||||
if ! $_QUIET_MODE && [ $1 -eq 1 ]; then
|
||||
$_VERBOSE_MODE || $PRINT_ERRORS && echo "${log_msg}" >&2
|
||||
$_VERBOSE_MODE || $PRINT_ERRORS && echo -e "\e[1m\e[91m${log_msg}\e[0m" >&2
|
||||
elif ! $_QUIET_MODE && [ $1 -le 2 ]; then
|
||||
$_VERBOSE_MODE || $PRINT_WARNINGS && echo "${log_msg}" >&2
|
||||
$_VERBOSE_MODE || $PRINT_WARNINGS && echo -e "\e[1m${log_msg}\e[0m" >&2
|
||||
elif ! $_QUIET_MODE && [ $1 -gt 2 ]; then
|
||||
$_VERBOSE_MODE && echo "${log_msg}" >&1
|
||||
fi
|
||||
|
@ -190,14 +229,57 @@ remove_runfile() {
|
|||
rmdir "$(dirname $_RUNFILE)" > /dev/null 2>&1
|
||||
}
|
||||
|
||||
# Run the user-specified pre hook
|
||||
#
|
||||
# Usage: run_pre_hook
|
||||
#
|
||||
run_pre_hook() {
|
||||
if ! $_PRE_HOOK_RUN && [ "" != "$_PRE_HOOK" ]; then
|
||||
$SHELL -c "$_PRE_HOOK"
|
||||
_PRE_HOOK_RUN=true
|
||||
fi
|
||||
}
|
||||
|
||||
# Run the user-specified post hook
|
||||
#
|
||||
# Usage: run_post_hook
|
||||
#
|
||||
run_post_hook() {
|
||||
if ! $_POST_HOOK_RUN && [ "" != "$_POST_HOOK" ]; then
|
||||
$SHELL -c "$_POST_HOOK"
|
||||
_POST_HOOK_RUN=true
|
||||
fi
|
||||
}
|
||||
|
||||
# Run the user-specified forced post hook
|
||||
#
|
||||
# Usage: run_forced_post_hook
|
||||
#
|
||||
run_forced_post_hook() {
|
||||
if ! $_FORCED_POST_HOOK_RUN && [ "" != "$_FORCED_POST_HOOK" ]; then
|
||||
$SHELL -c "$_FORCED_POST_HOOK"
|
||||
_FORCED_POST_HOOK_RUN=true
|
||||
fi
|
||||
}
|
||||
|
||||
# Exit cleanly with given exit code.
|
||||
# Removes any run files and runs the forced post hook.
|
||||
#
|
||||
# Usage clean_exit <exit_code>
|
||||
#
|
||||
clean_exit() {
|
||||
remove_runfile
|
||||
run_forced_post_hook
|
||||
exit $@
|
||||
}
|
||||
|
||||
# Handle script termination by external signals.
|
||||
#
|
||||
# Usage: handle_signals
|
||||
#
|
||||
handle_exit_signal() {
|
||||
write_log 1 "Program terminated upon user request."
|
||||
remove_runfile
|
||||
exit 1
|
||||
clean_exit 1
|
||||
}
|
||||
|
||||
# Show a desktop notification using notify-send
|
||||
|
@ -241,7 +323,7 @@ desktop_notify() {
|
|||
urgency="normal"
|
||||
;;
|
||||
"SUCCESS")
|
||||
icon="task-complete.png"
|
||||
icon="dialog-ok.png"
|
||||
urgency="low"
|
||||
;;
|
||||
*)
|
||||
|
@ -251,7 +333,9 @@ desktop_notify() {
|
|||
esac
|
||||
|
||||
if [[ "$user" != "" ]]; then
|
||||
sudo -u "$user" DISPLAY=":0.0" notify-send -i "$icon" -u "$urgency" "rs-backup: $2" "$3"
|
||||
dbus_pid=$(pgrep -u "$user" dbus-daemon | head -n1)
|
||||
environment=$(xargs --null < /proc/$dbus_pid/environ)
|
||||
sudo -u "$user" $environment notify-send -i "$icon" -u "$urgency" "rs-backup: $2" "$3"
|
||||
fi
|
||||
}
|
||||
|
||||
|
@ -388,7 +472,6 @@ perform_backup() {
|
|||
--exclude=\"${LOG_FILE}\" \
|
||||
--exclude=\"${USER_LOG_FILE}\" \
|
||||
--include-from=\"${inclusion_pattern_file}\" \
|
||||
--exclude=\"*\" \
|
||||
${rsync_opts} \
|
||||
/ \
|
||||
\"${destination}\""
|
||||
|
@ -503,16 +586,15 @@ parse_cmd_args() {
|
|||
getopt -T > /dev/null
|
||||
if [ $? -ne 4 ]; then
|
||||
write_log 1 "Need GNU getopt for command line parameter parsing!"
|
||||
exit 1;
|
||||
exit 1
|
||||
fi
|
||||
|
||||
args=$(getopt \
|
||||
-s sh \
|
||||
-o "r:o:nsi:l:fqvph" \
|
||||
-l "remote-host:,remote-user:,push-module:,ssh-options:,rsync-options:,dry-run,no-home-dirs,include-from:,log-level:,log-file:,force-run,quiet,verbose,progress,help" \
|
||||
-n "${name}" \
|
||||
-- "${@}")
|
||||
short_opts="r:o:nsi:l:fqvph"
|
||||
long_opts="remote-host:,remote-user:,push-module:,ssh-options:,rsync-options:,"
|
||||
long_opts+="dry-run,no-home-dirs,include-from:,log-level:,log-file:,force-run"
|
||||
long_opts+="quiet,verbose,progress,pre-hook:,post-hook:,forced-post-hook:,help"
|
||||
|
||||
args=$(getopt -s sh -o "$short_opts" -l "$long_opts" -n "${name}" -- "${@}")
|
||||
if [ $? -ne 0 ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
@ -549,12 +631,12 @@ parse_cmd_args() {
|
|||
_SKIP_HOME_DIRS=true
|
||||
shift 2 ;;
|
||||
"-l"|"--log-level")
|
||||
LOG_LEVEL=$2;
|
||||
LOG_LEVEL="$2"
|
||||
shift 2 ;;
|
||||
"--log-file")
|
||||
# Test if file is writeable
|
||||
! test_file_perms "w" "${2}" && echo "$name: '${2}' is not writeable!" >&2 && exit 1
|
||||
_FORCED_LOG_FILE=$2
|
||||
_FORCED_LOG_FILE="$2"
|
||||
shift 2 ;;
|
||||
"-f"|"--force-run")
|
||||
_FORCE_RUN=true
|
||||
|
@ -568,6 +650,15 @@ parse_cmd_args() {
|
|||
"-p"|"--progress")
|
||||
! $_QUIET_MODE && _SHOW_PROGRESS=true
|
||||
shift ;;
|
||||
"--pre-hook")
|
||||
_PRE_HOOK="$2"
|
||||
shift 2 ;;
|
||||
"--post-hook")
|
||||
_POST_HOOK="$2"
|
||||
shift 2 ;;
|
||||
"--forced-post-hook")
|
||||
_FORCED_POST_HOOK="$2"
|
||||
shift 2 ;;
|
||||
"-h"|"--help")
|
||||
print_help
|
||||
exit ;;
|
||||
|
@ -602,6 +693,7 @@ elif $_FORCE_RUN; then
|
|||
write_log 4 "Backup already running as PID $(<$_RUNFILE), forcing parallel backup..."
|
||||
fi
|
||||
|
||||
run_pre_hook
|
||||
create_runfile
|
||||
|
||||
# Backup exit code (0 if all backups have finished successfully)
|
||||
|
@ -640,5 +732,8 @@ remove_runfile
|
|||
write_log 4 "Done."
|
||||
|
||||
if [ $_ERROR_COUNT -gt 0 ]; then
|
||||
exit 1
|
||||
clean_exit 1
|
||||
fi
|
||||
|
||||
run_post_hook
|
||||
run_forced_post_hook
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
#!/bin/sh
|
||||
##
|
||||
# Copyright (C) 2013-2016 Janek Bevendorff
|
||||
# Website: http://www.refining-linux.org/
|
||||
#
|
||||
# Install script for installing server and client script files
|
||||
#
|
||||
# The MIT License (MIT)
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
##
|
||||
|
||||
if [[ "$1" != "all" ]] && [[ "$1" != "client" ]] && [[ "$1" != "server" ]]; then
|
||||
./server/usr/bin/rs-version headline "rs-backup-suite installer"
|
||||
./server/usr/bin/rs-version copyright
|
||||
echo
|
||||
echo "Usage: $(basename $0) [all|server|client]"
|
||||
exit
|
||||
fi
|
||||
|
||||
if [ $(id -u) -ne 0 ] && [[ "$(uname -o)" != "Cygwin" ]]; then
|
||||
echo "ERROR: This script must be run as root."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Global variables
|
||||
###############################################################################
|
||||
DISTRIBUTION="$(./server/usr/bin/rs-detect-distribution)"
|
||||
COMPONENT="$1"
|
||||
MODE="install"
|
||||
if [[ "$(basename $0)" == "uninstall.sh" ]]; then
|
||||
MODE="uninstall"
|
||||
fi
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Command aliases
|
||||
###############################################################################
|
||||
CP="cp -vr --preserve=mode,timestamps,links"
|
||||
RM="rm -Rvf"
|
||||
MKDIR="mkdir -pv"
|
||||
|
||||
|
||||
# Client component
|
||||
echo "Installing client component..."
|
||||
|
||||
$CP ./client/usr/bin/* /usr/bin/
|
||||
$CP ./server/usr/bin/rs-version /usr/bin/
|
||||
|
||||
if [ -d /etc/systemd/system ]; then
|
||||
echo 'Detected systemd. Run `systemctl enable rs-backup-run.timer` to enable daily backups.'
|
||||
$CP ./client/etc/systemd/system/* /etc/systemd/system
|
||||
fi
|
||||
|
||||
# Do not overwrite existing config
|
||||
if [ ! -e /etc/rs-backup/client-config ]; then
|
||||
$CP ./client/etc/rs-backup /etc/
|
||||
elif ! $(cmp --silent ./client/etc/rs-backup/client-config /etc/rs-backup/client-config); then
|
||||
$CP ./client/etc/rs-backup/client-config /etc/rs-backup/client-config.new
|
||||
fi
|
||||
|
||||
echo "Done."
|
21
install.sh
21
install.sh
|
@ -1,6 +1,6 @@
|
|||
#!/bin/sh
|
||||
##
|
||||
# Copyright (C) 2013-2015 Janek Bevendorff
|
||||
# Copyright (C) 2013-2016 Janek Bevendorff
|
||||
# Website: http://www.refining-linux.org/
|
||||
#
|
||||
# Install script for installing server and client script files
|
||||
|
@ -143,7 +143,7 @@ if [[ $MODE == "install" ]]; then
|
|||
$MKDIR "$BKP_DIR"/usr/share/perl5
|
||||
fi
|
||||
|
||||
# Append fstab entries
|
||||
# Apply distro-specific configurations
|
||||
if [[ "$DISTRIBUTION" == "Synology" ]]; then
|
||||
# Synology DSM restores default /etc/fstab upon reboot,
|
||||
# so we better put mount commands in /etc/rc
|
||||
|
@ -156,6 +156,11 @@ if [[ $MODE == "install" ]]; then
|
|||
cat $tmp_name > /etc/rc
|
||||
rm $tmp_name
|
||||
fi
|
||||
|
||||
# Add our own syslog template
|
||||
if ! grep -q "^# rs-backup-suite$" /usr/syno/synosdk/texts/enu/events; then
|
||||
cat ./server/etc/events_synology >> /usr/syno/synosdk/texts/enu/events
|
||||
fi
|
||||
else
|
||||
if ! grep -q "^# BEGIN: rs-backup-suite" /etc/fstab; then
|
||||
if [[ "$DISTRIBUTION" == "Ubuntu" ]]; then
|
||||
|
@ -175,8 +180,13 @@ if [[ $MODE == "install" ]]; then
|
|||
$CP ./server/bkp/etc/* "$BKP_DIR"/etc/
|
||||
# Correct command paths in rsnapshot config for Synology DSM
|
||||
if [[ "$DISTRIBUTION" == "Synology" ]]; then
|
||||
sed -i "s#/usr/bin/\(cp\|rm\|rsync\|logger\)\$#/opt/bin/\1#" "$BKP_DIR"/etc/rsnapshot.global.conf
|
||||
sed -i "s#/usr/bin/\(rsync\|logger\)\$#/opt/bin/\1#" "$BKP_DIR"/etc/rsnapshot.global.conf
|
||||
fi
|
||||
else
|
||||
# Update command paths if upgrading from earlier version
|
||||
echo "Updating cp and rm command paths..."
|
||||
sed -i "s#/opt/bin/cp\$#/usr/bin/cp#" "$BKP_DIR"/etc/rsnapshot.global.conf
|
||||
sed -i "s#/opt/bin/rm\$#/usr/bin/rs-rm#" "$BKP_DIR"/etc/rsnapshot.global.conf
|
||||
fi
|
||||
|
||||
# Create symlink for chroot
|
||||
|
@ -207,6 +217,11 @@ if [[ $MODE == "install" ]]; then
|
|||
$CP ./client/usr/bin/* /usr/bin/
|
||||
$CP ./server/usr/bin/rs-version /usr/bin/
|
||||
|
||||
if [ -d /etc/systemd/system ]; then
|
||||
echo 'Detected systemd. Run `systemctl enable rs-backup-run.timer` to enable daily backups.'
|
||||
$CP ./client/etc/systemd/system/* /etc/systemd/system
|
||||
fi
|
||||
|
||||
# Do not overwrite existing config
|
||||
if [ ! -e /etc/rs-backup/client-config ]; then
|
||||
$CP ./client/etc/rs-backup /etc/
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
config_version 1.2
|
||||
|
||||
cmd_cp /usr/bin/cp
|
||||
cmd_rm /usr/bin/rm
|
||||
cmd_rm /usr/bin/rs-rm
|
||||
cmd_rsync /usr/bin/rsync
|
||||
cmd_logger /usr/bin/logger
|
||||
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
|
||||
[99000000]
|
||||
# rs-backup-suite
|
||||
99000001 = "@1"
|
||||
|
|
@ -1,14 +1,14 @@
|
|||
# BEGIN: rs-backup-suite
|
||||
#/bin ::BACKUP_ROOT::/bin none bind 0 0
|
||||
#/bin ::BACKUP_ROOT::/bin none remount,ro 0 0
|
||||
#/bin ::BACKUP_ROOT::/bin none remount,ro,bind 0 0
|
||||
#/lib ::BACKUP_ROOT::/lib none bind 0 0
|
||||
#/lib ::BACKUP_ROOT::/lib none remount,ro 0 0
|
||||
#/lib ::BACKUP_ROOT::/lib none remount,ro,bind 0 0
|
||||
#/dev ::BACKUP_ROOT::/dev none bind 0 0
|
||||
#/dev ::BACKUP_ROOT::/dev none remount,ro 0 0
|
||||
#/dev ::BACKUP_ROOT::/dev none remount,ro,bind 0 0
|
||||
#/usr/bin ::BACKUP_ROOT::/usr/bin none bind 0 0
|
||||
#/usr/bin ::BACKUP_ROOT::/usr/bin none remount,ro 0 0
|
||||
#/usr/bin ::BACKUP_ROOT::/usr/bin none remount,ro,bind 0 0
|
||||
#/usr/lib ::BACKUP_ROOT::/usr/lib none bind 0 0
|
||||
#/usr/lib ::BACKUP_ROOT::/usr/lib none remount,ro 0 0
|
||||
#/usr/lib ::BACKUP_ROOT::/usr/lib none remount,ro,bind 0 0
|
||||
#/usr/share/perl5 ::BACKUP_ROOT::/usr/share/perl5 none bind 0 0
|
||||
#/usr/share/perl5 ::BACKUP_ROOT::/usr/share/perl5 none remount,ro 0 0
|
||||
#/usr/share/perl5 ::BACKUP_ROOT::/usr/share/perl5 none remount,ro,bind 0 0
|
||||
# END: rs-backup-suite
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
# BEGIN: rs-backup-suite
|
||||
#mount -o bind /bin ::BACKUP_ROOT::/bin
|
||||
#mount -o remount,ro ::BACKUP_ROOT::/bin
|
||||
#mount -o remount,ro,bind ::BACKUP_ROOT::/bin
|
||||
#mount -o bind /lib ::BACKUP_ROOT::/lib
|
||||
#mount -o remount,ro ::BACKUP_ROOT::/lib
|
||||
#mount -o remount,ro,bind ::BACKUP_ROOT::/lib
|
||||
#mount -o bind /dev ::BACKUP_ROOT::/dev
|
||||
#mount -o remount,ro ::BACKUP_ROOT::/dev
|
||||
#mount -o remount,ro,bind ::BACKUP_ROOT::/dev
|
||||
#mount -o bind /usr/bin ::BACKUP_ROOT::/usr/bin
|
||||
#mount -o remount,ro ::BACKUP_ROOT::/usr/bin
|
||||
#mount -o remount,ro,bind ::BACKUP_ROOT::/usr/bin
|
||||
#mount -o bind /opt/bin ::BACKUP_ROOT::/opt/bin
|
||||
#mount -o remount,ro ::BACKUP_ROOT::/opt/bin
|
||||
#mount -o remount,ro,bind ::BACKUP_ROOT::/opt/bin
|
||||
#mount -o bind /opt/lib ::BACKUP_ROOT::/opt/lib
|
||||
#mount -o remount,ro ::BACKUP_ROOT::/opt/lib
|
||||
#mount -o remount,ro,bind ::BACKUP_ROOT::/opt/lib
|
||||
#mount -o bind /opt/libexec ::BACKUP_ROOT::/opt/libexec
|
||||
#mount -o remount,ro ::BACKUP_ROOT::/opt/libexec
|
||||
#mount -o remount,ro,bind ::BACKUP_ROOT::/opt/libexec
|
||||
# END: rs-backup-suite
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
# BEGIN: rs-backup-suite
|
||||
#/bin ::BACKUP_ROOT::/bin none bind 0 0
|
||||
#/bin ::BACKUP_ROOT::/bin none remount,ro 0 0
|
||||
#/bin ::BACKUP_ROOT::/bin none remount,ro,bind 0 0
|
||||
#/lib ::BACKUP_ROOT::/lib none bind 0 0
|
||||
#/lib ::BACKUP_ROOT::/lib none remount,ro 0 0
|
||||
#/lib ::BACKUP_ROOT::/lib none remount,ro,bind 0 0
|
||||
#/dev ::BACKUP_ROOT::/dev none bind 0 0
|
||||
#/dev ::BACKUP_ROOT::/dev none remount,ro 0 0
|
||||
#/dev ::BACKUP_ROOT::/dev none remount,ro,bind 0 0
|
||||
#/usr/bin ::BACKUP_ROOT::/usr/bin none bind 0 0
|
||||
#/usr/bin ::BACKUP_ROOT::/usr/bin none remount,ro 0 0
|
||||
#/usr/bin ::BACKUP_ROOT::/usr/bin none remount,ro,bind 0 0
|
||||
#/usr/lib ::BACKUP_ROOT::/usr/lib none bind 0 0
|
||||
#/usr/lib ::BACKUP_ROOT::/usr/lib none remount,ro 0 0
|
||||
#/usr/lib ::BACKUP_ROOT::/usr/lib none remount,ro,bind 0 0
|
||||
#/usr/share/perl ::BACKUP_ROOT::/usr/share/perl none bind 0 0
|
||||
#/usr/share/perl ::BACKUP_ROOT::/usr/share/perl none remount,ro 0 0
|
||||
#/usr/share/perl ::BACKUP_ROOT::/usr/share/perl none remount,ro,bind 0 0
|
||||
# END: rs-backup-suite
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#!/bin/sh
|
||||
#!/usr/bin/env bash
|
||||
##
|
||||
# Copyright (C) 2013-2014 Janek Bevendorff
|
||||
# Copyright (C) 2013-2016 Janek Bevendorff
|
||||
# Website: http://www.refining-linux.org/
|
||||
#
|
||||
# Print out Linux distribution identification.
|
||||
|
@ -31,7 +31,7 @@ command -v lsb_release > /dev/null 2>&1
|
|||
|
||||
if [ $? -eq 0 ]; then
|
||||
lsb_release -is
|
||||
elif [ -e /etc/synoinfo.conf ] || [ -e /usr/lib/libsynoutils.so ]; then
|
||||
elif [ -e /etc/synoinfo.conf ] || [ -e /lib/$(ls /lib | grep libsynosdk | head -n1) ]; then
|
||||
echo "Synology"
|
||||
else
|
||||
echo "unknown"
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
#!/usr/bin/env bash
|
||||
##
|
||||
# Copyright (C) 2013-2016 Janek Bevendorff
|
||||
# Website: http://www.refining-linux.org/
|
||||
#
|
||||
# Log to appropriate syslog facility.
|
||||
#
|
||||
# The MIT License (MIT)
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
##
|
||||
|
||||
if [ "$2" == "" ] ; then
|
||||
echo "Usage: $(basename $0) <info|warn|err> <message>"
|
||||
exit
|
||||
fi
|
||||
|
||||
if [ "$1" != "info" ] && [ "$1" != "warn" ] && [ "$1" != "err" ]; then
|
||||
echo "Invalid log priority '$1'. Choose from <info|warn|err>."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
distribution=$(rs-detect-distribution)
|
||||
if [[ "Synology" == "${distribution}" ]]; then
|
||||
# Use Synology's crappy synologd if we're on DSM
|
||||
/usr/syno/bin/synologset1 sys $1 0x99000001 "[rs-backup-server] $2"
|
||||
else
|
||||
# Any other distribution
|
||||
command -v logger > /dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
logger -p $1 -t rs-backup-server "$2"
|
||||
else
|
||||
# Log to STDOUT/STDERR if we have no syslog facility
|
||||
prefix="$(date) [rs-backup-server]"
|
||||
if [ "$1" == "err" ]; then
|
||||
echo "$prefix ERROR: $2" >&2
|
||||
elif [ "$1" == "warn" ]; then
|
||||
echo "$prefix WARNING: $2" >&2
|
||||
else
|
||||
echo "$prefix INFO: $2"
|
||||
fi
|
||||
fi
|
||||
fi
|
|
@ -0,0 +1,37 @@
|
|||
#!/usr/bin/env bash
|
||||
##
|
||||
# Copyright (C) 2013-2016 Janek Bevendorff
|
||||
# Website: http://www.refining-linux.org/
|
||||
#
|
||||
# Recursively adjust permissions of given file or directory and remove it.
|
||||
#
|
||||
# The MIT License (MIT)
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
##
|
||||
|
||||
if [ "$1" == "" ]; then
|
||||
. rs-version
|
||||
echo "Usage: $(basename $0) [flags] <file>"
|
||||
exit
|
||||
fi
|
||||
|
||||
chmod -R +w "${@: -1}"
|
||||
rm ${@}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
#!/bin/sh
|
||||
#!/usr/bin/env bash
|
||||
##
|
||||
# Copyright (C) 2013-2014 Janek Bevendorff
|
||||
# Copyright (C) 2013-2016 Janek Bevendorff
|
||||
# Website: http://www.refining-linux.org/
|
||||
#
|
||||
# Rotate backup revisions. Intended for use with cron.
|
||||
|
@ -36,7 +36,35 @@ if [ "$RSYNC_EXIT_STATUS" == "" ]; then
|
|||
exit 1
|
||||
fi
|
||||
|
||||
# rsync exit code descriptions found at
|
||||
# <https://lxadm.com/Rsync_exit_codes>
|
||||
msg="unknown code"
|
||||
case $RSYNC_EXIT_STATUS in
|
||||
0) msg="Success" ;;
|
||||
1) msg="Syntax or usage error" ;;
|
||||
2) msg="Protocol incompatibility" ;;
|
||||
3) msg="Errors selecting input/output files, dirs" ;;
|
||||
4) msg="Requested action not supported: an attempt was made to manipulate 64-bit files on a platformi " \
|
||||
"that cannot support them; or an option was specified that is supported by the client and not by the server" ;;
|
||||
5) msg="Error starting client-server protocol" ;;
|
||||
6) msg="Daemon unable to append to log-file" ;;
|
||||
10) msg="Error in socket I/O" ;;
|
||||
11) msg="Error in file I/O" ;;
|
||||
12) msg="Error in rsync protocol data stream" ;;
|
||||
13) msg="Errors with program diagnostics" ;;
|
||||
14) msg="Error in IPC code" ;;
|
||||
20) msg="Received SIGUSR1 or SIGINT" ;;
|
||||
21) msg="Some error returned by waitpid()" ;;
|
||||
22) msg="Error allocating core memory buffers" ;;
|
||||
23) msg="Partial transfer due to error" ;;
|
||||
24) msg="Partial transfer due to vanished source files" ;;
|
||||
25) msg="The --max-delete limit stopped deletions" ;;
|
||||
30) msg="Timeout in data send/receive" ;;
|
||||
35) msg="Timeout waiting for daemon connection" ;;
|
||||
esac
|
||||
|
||||
if [ $RSYNC_EXIT_STATUS -eq 0 ] || [ $RSYNC_EXIT_STATUS -eq 24 ]; then
|
||||
rs-logger info "Backup for user '$(id -un)' finished with exit code ${RSYNC_EXIT_STATUS} (${msg})"
|
||||
RSNAPSHOT="rsnapshot"
|
||||
if [ -x /usr/bin/rsnapshot ]; then
|
||||
RSNAPSHOT="/usr/bin/rsnapshot"
|
||||
|
@ -44,4 +72,14 @@ if [ $RSYNC_EXIT_STATUS -eq 0 ] || [ $RSYNC_EXIT_STATUS -eq 24 ]; then
|
|||
RSNAPSHOT="/opt/bin/rsnapshot"
|
||||
fi
|
||||
$RSNAPSHOT -c "$1" push
|
||||
rsnapshot_exit_code=$?
|
||||
if [ $rsnapshot_exit_code -eq 1 ]; then
|
||||
rs-logger err "Backup rotation for level 'push' of user '$(id -un)' failed."
|
||||
elif [ $rsnapshot_exit_code -eq 2 ]; then
|
||||
rs-logger warn "Backup rotation for level 'push' of user '$(id -un)' finished with warnings."
|
||||
else
|
||||
rs-logger info "Backup rotation for level 'push' of user '$(id -un)' finished."
|
||||
fi
|
||||
else
|
||||
rs-logger err "Backup for user '$(id -un)' failed with exit code ${RSYNC_EXIT_STATUS} (${msg})"
|
||||
fi
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#!/bin/sh
|
||||
#!/usr/bin/env bash
|
||||
##
|
||||
# Copyright (C) 2013-2014 Janek Bevendorff
|
||||
# Copyright (C) 2013-2016 Janek Bevendorff
|
||||
# Website: http://www.refining-linux.org/
|
||||
#
|
||||
# Run a restricted command in an SSH session.
|
||||
|
@ -27,19 +27,19 @@
|
|||
##
|
||||
|
||||
home_dir=$1
|
||||
|
||||
if $(echo "${SSH_ORIGINAL_COMMAND}" | grep -q "^\(internal-sftp\|.*/sftp-server\)"); then
|
||||
export HOME="${home_dir}/files"
|
||||
cd $HOME
|
||||
|
||||
if $(echo "${SSH_ORIGINAL_COMMAND}" | grep -q "^\(internal-sftp\|.*/sftp-server\)"); then
|
||||
[ -x /usr/lib/openssh/sftp-server ] && exec /usr/lib/openssh/sftp-server -R
|
||||
[ -x /usr/lib/ssh/sftp-server ] && exec /usr/lib/ssh/sftp-server -R
|
||||
[ -x /usr/libexec/sftp-server ] && exec /usr/libexec/sftp-server -R
|
||||
[ -x /opt/libexec/sftp-server ] && exec /opt/libexec/sftp-server -R
|
||||
else
|
||||
RSYNC=/usr/bin/rsync
|
||||
rs-logger info "Starting backup for user '$(id -un)'."
|
||||
RSYNC_OPTS="--server --daemon --config='$home_dir/rsync.conf' ."
|
||||
[ -x $RSYNC ] && exec $RSYNC $(eval echo $RSYNC_OPTS)
|
||||
RSYNC=/opt/bin/rsync
|
||||
[ -x $RSYNC ] && exec $RSYNC $(eval echo $RSYNC_OPTS)
|
||||
[ -x /usr/bin/rsync ] && exec /usr/bin/rsync $(eval echo $RSYNC_OPTS)
|
||||
[ -x /opt/bin/rsync ] && exec /opt/bin/rsync $(eval echo $RSYNC_OPTS)
|
||||
fi
|
||||
|
||||
echo "Session failed." >&2
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#!/bin/sh
|
||||
#!/usr/bin/env bash
|
||||
##
|
||||
# Copyright (C) 2013-2015 Janek Bevendorff
|
||||
# Copyright (C) 2013-2016 Janek Bevendorff
|
||||
# Website: http://www.refining-linux.org/
|
||||
#
|
||||
# Print out version and copyright information for rs-backup.
|
||||
|
@ -26,7 +26,7 @@
|
|||
# THE SOFTWARE.
|
||||
##
|
||||
|
||||
_VERSION="0.2.4"
|
||||
_VERSION="0.3.0"
|
||||
|
||||
headline() {
|
||||
if [ "$1" != "" ]; then
|
||||
|
@ -38,7 +38,7 @@ headline() {
|
|||
}
|
||||
|
||||
copyright() {
|
||||
echo "Copyright (C) 2013-2015 Janek Bevendorff"
|
||||
echo "Copyright (C) 2013-2016 Janek Bevendorff"
|
||||
echo "Website: https://github.com/Manko10/rs-backup-suite"
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#!/bin/sh
|
||||
#!/usr/bin/env bash
|
||||
##
|
||||
# Copyright (C) 2013-2014 Janek Bevendorff
|
||||
# Copyright (C) 2013-2016 Janek Bevendorff
|
||||
# Website: http://www.refining-linux.org/
|
||||
#
|
||||
# Add SSH key to a backup user for passwordless login
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#!/bin/sh
|
||||
#!/usr/bin/env bash
|
||||
##
|
||||
# Copyright (C) 2013-2014 Janek Bevendorff
|
||||
# Copyright (C) 2013-2016 Janek Bevendorff
|
||||
# Website: http://www.refining-linux.org/
|
||||
#
|
||||
# Set up a backup user.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#!/bin/sh
|
||||
#!/usr/bin/env bash
|
||||
##
|
||||
# Copyright (C) 2013-2014 Janek Bevendorff
|
||||
# Copyright (C) 2013-2016 Janek Bevendorff
|
||||
# Website: http://www.refining-linux.org/
|
||||
#
|
||||
# Create daily, weekly or monthly snapshots from manual push backups
|
||||
|
@ -63,5 +63,13 @@ for home_dir in "${BACKUP_ROOT}"/*; do
|
|||
owner=$(${stat_cmd} -c '%U' .)
|
||||
|
||||
su - "${owner}" -c "rsnapshot -c '${home_dir}/rsnapshot.conf' '$1'"
|
||||
rsnapshot_exit_code=$?
|
||||
if [ $rsnapshot_exit_code -eq 1 ]; then
|
||||
rs-logger err "Backup rotation for level '$1' of user '$(id -un)' failed."
|
||||
elif [ $rsnapshot_exit_code -eq 2 ]; then
|
||||
rs-logger warn "Backup rotation for level '$1' of user '$(id -un)' finished with warnings."
|
||||
else
|
||||
rs-logger info "Backup rotation for level '$1' of user '$(id -un)' finished."
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#!/bin/sh
|
||||
#!/usr/bin/env bash
|
||||
##
|
||||
# Copyright (C) 2013-2014 Janek Bevendorff
|
||||
# Copyright (C) 2013-2016 Janek Bevendorff
|
||||
# Website: http://www.refining-linux.org/
|
||||
#
|
||||
# Set quota for user
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#!/bin/sh
|
||||
#!/usr/bin/env bash
|
||||
##
|
||||
# Copyright (C) 2013-2014 Janek Bevendorff
|
||||
# Copyright (C) 2013-2016 Janek Bevendorff
|
||||
# Website: http://www.refining-linux.org/
|
||||
#
|
||||
# Update passwd file in chroot folder based on the contents of /etc/passwd.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#!/bin/sh
|
||||
#!/usr/bin/env bash
|
||||
##
|
||||
# Copyright (C) 2013-2014 Janek Bevendorff
|
||||
# Copyright (C) 2013-2016 Janek Bevendorff
|
||||
# Website: http://www.refining-linux.org/
|
||||
#
|
||||
# Utility program. Check if disk has been used since last check and spin it down if not.
|
||||
|
|
Loading…
Reference in New Issue