From fbd0b8742caa0c03dec294e64fdddf28fdf05aff Mon Sep 17 00:00:00 2001 From: Micah Anderson Date: Thu, 27 Aug 2009 16:53:43 -0400 Subject: [PATCH 01/16] Standardize the example file format. Making the comments have the same number of hash marks, clearly specify example settings and what the defaults are set to. --- examples/example.dup | 234 +++++++++++++++++++++++++---------------- examples/example.rdiff | 171 +++++++++++++++++++----------- 2 files changed, 253 insertions(+), 152 deletions(-) diff --git a/examples/example.dup b/examples/example.dup index 830a47d..2b59fe5 100644 --- a/examples/example.dup +++ b/examples/example.dup @@ -1,16 +1,32 @@ +## This is an example duplicity configuration file. +## +## Here you can find all the possible duplicity options, details of +## what the options provide and possible settings. The defaults are set +## as the commented out option, uncomment and change when +## necessary. Options which are uncommented in this example do not have +## defaults, and the settings provided are recommended. + +## passed directly to duplicity, e.g. to increase verbosity set this to: +## options = --verbosity 8 +## +## Default: +# options = -# passed directly to duplicity -#options = --verbosity 8 - -# default is 0, but set to 19 if you want to lower the priority. -nicelevel = 19 +## default is 0, but set to something like 19 if you want to lower the priority. +## +## Default: +# nicelevel = 0 -# default is yes. set to no to skip the test if the remote host is alive -#testconnect = no +## test the connection? set to no to skip the test if the remote host is alive +## +## Default: +# testconnect = yes -# temporary directory used by duplicity -# (default = /tmp or /usr/tmp, depending on the system) -#tmpdir = /var/tmp/duplicity +## temporary directory used by duplicity, set to some other location if your /tmp is small +## default is either /tmp or /usr/tmp, depending on the system +## +## Default: +# tmpdir = /tmp ###################################################### ## gpg section @@ -35,23 +51,36 @@ nicelevel = 19 [gpg] -# when set to yes, encryptkey variable must be set below; if you want to use -# two different keys for encryption and signing, you must also set the signkey -# variable below. -# default is no, for backwards compatibility with backupninja <= 0.5. -sign = yes - -# ID of the GnuPG public key used for data encryption. -# if not set, symmetric encryption is used, and data signing is not possible. -encryptkey = 04D9EA79 - -# ID of the GnuPG private key used for data signing. -# if not set, encryptkey will be used. -#signkey = 04D9EA79 +## when set to yes, encryptkey variable must be set below; if you want to use +## two different keys for encryption and signing, you must also set the signkey +## variable below. +## default is set to no, for backwards compatibility with backupninja <= 0.5. +## +## Default: +# sign = no -# password -# NB: neither quote this, nor should it contain any quotes -password = a_very_complicated_passphrase +## ID of the GnuPG public key used for data encryption. +## if not set, symmetric encryption is used, and data signing is not possible. +## an example setting would be: +## encryptkey = 04D9EA79 +## +## Default: +# encryptkey = + +## ID of the GnuPG private key used for data signing. +## if not set, encryptkey will be used, an example setting would be: +## signkey = 04D9EA79 +## +## Default: +# signkey = + +## password +## NB: neither quote this, nor should it contain any quotes, +## an example setting would be: +## password = a_very_complicated_passphrase +## +## Default: +# password = ###################################################### ## source section @@ -59,23 +88,23 @@ password = a_very_complicated_passphrase [source] -# A few notes about includes and excludes: -# 1. include, exclude and vsinclude statements support globbing with '*' -# 2. Symlinks are not dereferenced. Moreover, an include line whose path -# contains, at any level, a symlink to a directory, will only have the -# symlink backed-up, not the target directory's content. Yes, you have to -# dereference yourself the symlinks, or to use 'mount --bind' instead. -# Example: let's say /home is a symlink to /mnt/crypt/home ; the following -# line will only backup a "/home" symlink ; neither /home/user nor -# /home/user/Mail will be backed-up : -# include = /home/user/Mail -# A workaround is to 'mount --bind /mnt/crypt/home /home' ; another one is to -# write : -# include = /mnt/crypt/home/user/Mail -# 3. All the excludes come after all the includes. The order is not otherwise -# taken into account. - -# files to include in the backup +## A few notes about includes and excludes: +## 1. include, exclude and vsinclude statements support globbing with '*' +## 2. Symlinks are not dereferenced. Moreover, an include line whose path +## contains, at any level, a symlink to a directory, will only have the +## symlink backed-up, not the target directory's content. Yes, you have to +## dereference yourself the symlinks, or to use 'mount --bind' instead. +## Example: let's say /home is a symlink to /mnt/crypt/home ; the following +## line will only backup a "/home" symlink ; neither /home/user nor +## /home/user/Mail will be backed-up : +## include = /home/user/Mail +## A workaround is to 'mount --bind /mnt/crypt/home /home' ; another one is to +## write : +## include = /mnt/crypt/home/user/Mail +## 3. All the excludes come after all the includes. The order is not otherwise +## taken into account. + +## files to include in the backup include = /var/spool/cron/crontabs include = /var/backups include = /etc @@ -86,20 +115,20 @@ include = /usr/local/sbin include = /var/lib/dpkg/status include = /var/lib/dpkg/status-old -# If vservers = yes in /etc/backupninja.conf then the following variables can -# be used: -# vsnames = all | ... (default = all) -# vsinclude = -# vsinclude = -# ... -# Any path specified in vsinclude is added to the include list for each vserver -# listed in vsnames (or all if vsnames = all, which is the default). -# -# For example, vsinclude = /home will backup the /home directory in every -# vserver listed in vsnames. If you have 'vsnames = foo bar baz', this -# vsinclude will add to the include list /vservers/foo/home, /vservers/bar/home -# and /vservers/baz/home. -# Vservers paths are derived from $VROOTDIR. +## If vservers = yes in /etc/backupninja.conf then the following variables can +## be used: +## vsnames = all | ... (default = all) +## vsinclude = +## vsinclude = +## ... +## Any path specified in vsinclude is added to the include list for each vserver +## listed in vsnames (or all if vsnames = all, which is the default). +## +## For example, vsinclude = /home will backup the /home directory in every +## vserver listed in vsnames. If you have 'vsnames = foo bar baz', this +## vsinclude will add to the include list /vservers/foo/home, /vservers/bar/home +## and /vservers/baz/home. +## Vservers paths are derived from $VROOTDIR. # files to exclude from the backup exclude = /home/*/.gnupg @@ -110,38 +139,67 @@ exclude = /home/*/.gnupg [dest] -# perform an incremental backup? (default = yes) -# if incremental = no, perform a full backup in order to start a new backup set -#incremental = yes - -# how many days of data to keep ; default is 60 days. -# (you can also use the time format of duplicity) -# 'keep = yes' means : do not delete old data, the remote host will take care of this -#keep = 60 -#keep = yes - -# full destination URL, in duplicity format; if set, desturl overrides -# sshoptions, destdir, desthost and destuser; it also disables testconnect and -# bandwithlimit. For details, see duplicity manpage, section "URL FORMAT". -#desturl = file:///usr/local/backup -#desturl = rsync://user@other.host//var/backup/bla - -# bandwith limit, in kbit/s ; default is 0, i.e. no limit -#bandwidthlimit = 128 - -# passed directly to ssh, scp (and sftp in duplicity >=0.4.2) -# warning: sftp does not support all scp options, especially -i; as -# a workaround, you can use "-o " -sshoptions = -o IdentityFile=/root/.ssh/id_dsa_duplicity +## perform an incremental backup? (default = yes) +## if incremental = no, perform a full backup in order to start a new backup set +## +## Default: +# incremental = yes -# put the backups under this directory -destdir = /backups +## how many days of data to keep ; default is 60 days. +## (you can also use the time format of duplicity) +## 'keep = yes' means : do not delete old data, the remote host will take care of this +## +## Default: +# keep = 60 + +## full destination URL, in duplicity format; if set, desturl overrides +## sshoptions, destdir, desthost and destuser; it also disables testconnect and +## bandwithlimit. For details, see duplicity manpage, section "URL FORMAT", some +## examples include: +## desturl = file:///usr/local/backup +## desturl = rsync://user@other.host//var/backup/bla +## the default value of this configuration option is not set: +## +## Default: +# desturl = -# the machine which will receive the backups -desthost = backuphost +## bandwith limit, in kbit/s ; default is 0, i.e. no limit an example +## setting would be: +## bandwidthlimit = 128 +## +## Default: +# bandwidthlimit = 0 + +## passed directly to ssh, scp (and sftp in duplicity >=0.4.2) +## warning: sftp does not support all scp options, especially -i; as +## a workaround, you can use "-o " +## an example setting would be: +## sshoptions = -o IdentityFile=/root/.ssh/id_dsa_duplicity +## +## Default: +# sshoptions = + +## put the backups under this directory, this must be set! +## an example setting would be: +## destdir = /backups +## +## Default: +# destdir = + +## the machine which will receive the backups, this must be set! +## an example setting would be: +## desthost = backuphost +## +## Default: +# desthost = + +## make the files owned by this user +## note: you must be able to ssh backupuser@backhost +## without specifying a password (if type = remote). +## an example setting would be: +## destuser = backupuser +## +## Default: +# destuser = -# make the files owned by this user -# note: you must be able to ssh backupuser@backhost -# without specifying a password (if type = remote). -destuser = backupuser diff --git a/examples/example.rdiff b/examples/example.rdiff index 3767f9b..903fd19 100644 --- a/examples/example.rdiff +++ b/examples/example.rdiff @@ -1,16 +1,33 @@ ## ## This is an example rdiff-backup configuration file. -## The defaults are useful in most cases, just make sure -## to configure the destination host and user. +## +## Here you can find all the possible duplicity options, details of +## what the options provide and possible settings. The defaults are set +## as the commented out option, uncomment and change when +## necessary. Options which are uncommented in this example do not have +## defaults, and the settings provided are recommended. +## +## The defaults are useful in most cases, just make sure to configure the +## destination host and user. ## ## passed directly to rdiff-backup -# options = --force +## an example setting would be: +## options = --force +## +## Default: +# options = ## default is 0, but set to 19 if you want to lower the priority. -# nicelevel = 19 +## an example setting would be: +## nicelevel = 19 +## +## Default +# nicelevel = 0 ## default is yes. set to no to skip the test if the remote host is alive +## +## Default: # testconnect = no ## default is not to limit bandwidth. @@ -18,7 +35,11 @@ ## number to set a limit that will never be exceeded, or a positive number ## to set a target average bandwidth use. cstream is required. See cstream's ## -t option for more information. 62500 bytes = 500 Kb (.5 Mb) -# bwlimit = 62500 +## an example setting would be: +## bwlimit = 62500 +## +## Default: +# bwlimit = 0 ## should backupninja ignore the version differences between source and remote ## rdiff-backup? (default: no) @@ -28,6 +49,8 @@ ## An example usage could be the remote side has its authorized_keys configured ## with command="rdiff-backup --server" to allow for restricted yet automated ## password-less backups +## +## Default: # ignore_version = no ###################################################### @@ -36,39 +59,42 @@ [source] -# an optional subdirectory below 'directory' (see [dest]) +## an optional subdirectory below 'directory' (see [dest]) label = thishostname -# type can be "local" or "remote" +## type can be "local" or "remote" type = local -# only use if '[source] type = remote' -#host = srchost -#user = srcuser - -# how many days of data to keep -# (you can also use the time format of rdiff-backup, e.g. 6D5h) -# (to keep everything, set this to yes) -#keep = yes -keep = 60 - -# A few notes about includes and excludes: -# 1. include, exclude and vsinclude statements support globbing with '*' -# 2. Symlinks are not dereferenced. Moreover, an include line whose path -# contains, at any level, a symlink to a directory, will only have the -# symlink backed-up, not the target directory's content. Yes, you have to -# dereference yourself the symlinks, or to use 'mount --bind' instead. -# Example: let's say /home is a symlink to /mnt/crypt/home ; the following -# line will only backup a "/home" symlink ; neither /home/user nor -# /home/user/Mail will be backed-up : -# include = /home/user/Mail -# A workaround is to 'mount --bind /mnt/crypt/home /home' ; another one is to -# write : -# include = /mnt/crypt/home/user/Mail -# 3. All the excludes come after all the includes. The order is not otherwise -# taken into account. - -# files to include in the backup +## only use if '[source] type = remote' +# host = srchost +# user = srcuser + +## how many days of data to keep +## (you can also use the time format of rdiff-backup, e.g. 6D5h) +## (to keep everything, set this to yes) +## an example setting would be: +##keep = yes +## +## Default: +# keep = 60 + +## A few notes about includes and excludes: +## 1. include, exclude and vsinclude statements support globbing with '*' +## 2. Symlinks are not dereferenced. Moreover, an include line whose path +## contains, at any level, a symlink to a directory, will only have the +## symlink backed-up, not the target directory's content. Yes, you have to +## dereference yourself the symlinks, or to use 'mount --bind' instead. +## Example: let's say /home is a symlink to /mnt/crypt/home ; the following +## line will only backup a "/home" symlink ; neither /home/user nor +## /home/user/Mail will be backed-up : +## include = /home/user/Mail +## A workaround is to 'mount --bind /mnt/crypt/home /home' ; another one is to +## write : +## include = /mnt/crypt/home/user/Mail +## 3. All the excludes come after all the includes. The order is not otherwise +## taken into account. + +## files to include in the backup include = /var/spool/cron/crontabs include = /var/backups include = /etc @@ -79,23 +105,23 @@ include = /usr/local/sbin include = /var/lib/dpkg/status include = /var/lib/dpkg/status-old -# If vservers = yes in /etc/backupninja.conf then the following variables can -# be used: -# vsnames = all | ... (default = all) -# vsinclude = -# vsinclude = -# ... -# Any path specified in vsinclude is added to the include list for each vserver -# listed in vsnames (or all if vsnames = all, which is the default). -# -# For example, vsinclude = /home will backup the /home directory in every -# vserver listed in vsnames. If you have 'vsnames = foo bar baz', this -# vsinclude will add to the include list /vservers/foo/home, /vservers/bar/home -# and /vservers/baz/home. -# Vservers paths are derived from $VROOTDIR. - -# files to exclude from the backup -#exclude = /home/*/.gnupg +## If vservers = yes in /etc/backupninja.conf then the following variables can +## be used: +## vsnames = all | ... (default = all) +## vsinclude = +## vsinclude = +## ... +## Any path specified in vsinclude is added to the include list for each vserver +## listed in vsnames (or all if vsnames = all, which is the default). +## +## For example, vsinclude = /home will backup the /home directory in every +## vserver listed in vsnames. If you have 'vsnames = foo bar baz', this +## vsinclude will add to the include list /vservers/foo/home, /vservers/bar/home +## and /vservers/baz/home. +## Vservers paths are derived from $VROOTDIR. + +## files to exclude from the backup +exclude = /home/*/.gnupg ###################################################### ## destination section @@ -103,18 +129,35 @@ include = /var/lib/dpkg/status-old [dest] -# type can be "local" or "remote" -type = remote - -# put the backups under this directory -directory = /backups - -# the machine which will receive the backups. -# only use if "[dest] type = remote" -host = backuphost +## type can be "local" or "remote", this must be set! +## an example configuration would be: +## type = remote +## +## Default: +# type = + +## put the backups under this directory, this must be set! +## an example setting would be: +## directory = /backups +## +## Default: +# directory = + +## the machine which will receive the backups. +## only use if "[dest] type = remote" +## an example setting would be: +## host = backuphost +## +## Default +# host = + +## make the files owned by this user. you must be able to +## `su -c "ssh backupuser@backhost"` without specifying a password. +## only use if "[dest] type = remote" +## an example setting would be: +## user = backupuser +## +## Default: +# user = -# make the files owned by this user. you must be able to -# `su -c "ssh backupuser@backhost"` without specifying a password. -# only use if "[dest] type = remote" -user = backupuser -- 2.30.2 From f549dc44f65919dde9429f25e0e9de941ff3cebb Mon Sep 17 00:00:00 2001 From: Micah Anderson Date: Wed, 23 Sep 2009 16:07:58 -0400 Subject: [PATCH 02/16] Fix missing $ in variable name, fixes: #1239 --- handlers/rdiff.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/handlers/rdiff.in b/handlers/rdiff.in index f59d56a..45d5096 100644 --- a/handlers/rdiff.in +++ b/handlers/rdiff.in @@ -59,7 +59,7 @@ function check_consistency() { if [ "$user" == "" ]; then fatal "User must be specified for remote $section." fi - if [ "host" == "" ]; then + if [ "$host" == "" ]; then fatal "Host must be specifed for remote $section." fi fi -- 2.30.2 From 75d17d06f276ad1aa435d7dc31777677b10917b4 Mon Sep 17 00:00:00 2001 From: Silvio Rhatto Date: Mon, 15 Jun 2009 12:14:01 -0300 Subject: [PATCH 03/16] Enhanced rsync handler. - Added support for: - Remote destinations - Long rotation format similar to maildir handler - Batch files through --read-batch and --write-batch - Custom file list using --files-from - SSH persistent connection using ControlMaster - The rsync:// protocol - Metadata folder for each backup folder - General refactoring - Code cleanup Not all options were tested and it might contain bugs. Tests, comments and patches are welcome. :) --- handlers/rsync.in | 1176 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 952 insertions(+), 224 deletions(-) diff --git a/handlers/rsync.in b/handlers/rsync.in index 072f2a6..829f148 100644 --- a/handlers/rsync.in +++ b/handlers/rsync.in @@ -1,13 +1,26 @@ -# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*- -# vim: set filetype=sh sw=3 sts=3 expandtab autoindent: # -# backupninja handler to do incremental backups using -# rsync and hardlinks, based on +# backupninja handler for incremental backups using rsync and hardlinks +# feedback: rhatto at riseup.net # -# http://www.mikerubel.org/computers/rsync_snapshots/ +# rsync handler is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 2 of the License, or any later version. # -# feedback: rhatto at riseup.net | gpl -# lot of enhancements grabbed from "rsnap" handler by paulv at bikkel.org +# rsync handler is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Software Foundation, Inc., 59 Temple +# Place - Suite 330, Boston, MA 02111-1307, USA +# +# Inspiration +# ----------- +# +# - http://www.mikerubel.org/computers/rsync_snapshots/ +# - rsnap handler by paulv at bikkel.org +# - maildir handler from backupninja # # Config file options # ------------------- @@ -17,21 +30,29 @@ # partition = partition where the backup lives # fscheck = set to 1 if fsck should run on $partition after the backup is made # read_only = set to 1 if $partition is mounted read-only -# mountpoint = backup partition mountpoint or backup main folder -# backupdir = folder relative do $mountpoint where the backup should be stored -# days = number of backup increments (min = 5) +# mountpoint = backup partition mountpoint or backup main folder (either local or remote) +# backupdir = folder relative do $mountpoint where the backup should be stored (local or remote) +# format = specify backup storage format: short, long or mirror (i.e, no rotations) +# days = for short storage format, specify the number of backup increments (min = 5) +# keepdaily = for long storage format, specify the number of daily backup increments +# keepweekly = for long storage format, specify the number of weekly backup increments +# keepmonthly = for long storage format, specify the number of monthly backup increments # lockfile = lockfile to be kept during backup execution # nicelevel = rsync command nice level # enable_mv_timestamp_bug = set to "yes" if your system isnt handling timestamps correctly # tmp = temp folder +# multiconnection = set to "yes" if you want to use multiconnection ssh support # # [source] # from = local or remote # host = source hostname or ip, if remote backup +# port = remote port number (remote source only) +# user = remote user name (remote source only) # testconnect = when "yes", test the connection for a remote source before backup # include = include folder on backup # exclude = exclude folder on backup -# ssh = ssh command line (remote only) +# ssh = ssh command line (remote source only) +# protocol = ssh or rsync (remote source only) # rsync = rsync program # rsync_options = rsync command options # exclude_vserver = vserver-name (valid only if vservers = yes on backupninja.conf) @@ -39,6 +60,28 @@ # compress = if set to 1, compress data on rsync (remote source only) # bandwidthlimit = set a badnwidth limit in kbps (remote source only) # remote_rsync = remote rsync program (remote source only) +# id_file = ssh key file (remote source only) +# batch = set to "yes" to rsync use a batch file as source +# batchbase = folder where the batch file is located +# filelist = set yes if you want rsync to use a file list source +# filelistbase = folder where the file list is placed +# +# [dest] +# dest = backup destination type (local or remote) +# testconnect = when "yes", test the connection for a remote source before backup +# ssh = ssh command line (remote dest only) +# protocol = ssh or rsync (remote dest only) +# numericids = when set to 1, use numeric ids instead of user/group mappings on rsync +# compress = if set to 1, compress data on rsync (remote source only) +# host = destination host name (remote destination only) +# port = remote port number (remote destination only) +# user = remote user name (remote destination only) +# id_file = ssh key file (remote destination only) +# bandwidthlimit = set a badnwidth limit in kbps (remote destination only) +# remote_rsync = remote rsync program (remote dest only) +# batch = set to "yes" to rsync write a batch file from the changes +# batchbase = folder where the batch file should be written +# fakesuper = set to yes so rsync use the --fake-super flag (remote destination only) # # [services] # initscripts = absolute path where scripts are located @@ -56,297 +99,982 @@ # You dont need to manually specify vservers using "include = /vservers". # They are automatically backuped if vserver is set to "yes" on you backupninja.conf. # - -# config file evaluation - -setsection system -getconf rm rm -getconf cp cp -getconf touch touch -getconf mv mv -getconf fsck fsck - -setsection general -getconf log /var/log/backup/rsync.log -getconf partition -getconf fscheck -getconf read_only -getconf mountpoint -getconf backupdir -getconf rotate -getconf days -getconf lockfile -getconf nicelevel 0 -getconf enable_mv_timestamp_bug no -getconf tmp /tmp - -setsection source -getconf from local -getconf testconnect no -getconf rsync $RSYNC -getconf rsync_options "-av --delete" -getconf ssh ssh -getconf user -getconf host -getconf include -getconf exclude -getconf exclude_vserver -getconf numericids 0 -getconf compress 0 -getconf bandwidthlimit -getconf remote_rsync rsync - -setsection services -getconf initscripts -getconf service +# Changelog +# --------- +# +# 20090329 - rhatto at riseup.net +# +# - Added support for: +# - Remote destinations +# - Long rotation format similar to maildir handler +# - Batch files through --read-batch and --write-batch +# - Custom file list using --files-from +# - SSH persistent connection using ControlMaster +# - The rsync:// protocol +# - Metadata folder for each backup folder +# - General refactoring +# - Code cleanup +# # function definitions -function rotate { +function eval_config { + + # system section + + setsection system + getconf rm rm + getconf cp cp + getconf touch touch + getconf mv mv + getconf fsck fsck + + # general section + + setsection general + getconf log /var/log/backup/rsync.log + getconf partition + getconf fscheck + getconf read_only + getconf mountpoint + getconf backupdir + getconf format short + getconf days + getconf keepdaily 5 + getconf keepweekly 3 + getconf keepmonthly 1 + getconf lockfile + getconf nicelevel 0 + getconf enable_mv_timestamp_bug no + getconf tmp /tmp + getconf multiconnection no + + # source section + + setsection source + getconf from local + getconf rsync $RSYNC + getconf rsync_options "-av --delete --recursive" + + if [ "$from" == "remote" ]; then + getconf testconnect no + getconf protocol ssh + getconf ssh ssh + getconf host + + if [ "$protocol" == "ssh" ]; then + # sshd default listen port + getconf port 22 + else + # rsyncd default listen port + getconf port 873 + fi + + getconf user + getconf bandwidthlimit + getconf remote_rsync rsync + getconf id_file /root/.ssh/id_dsa + fi + + getconf batch no + + if [ "$batch" == "yes" ]; then + getconf batchbase + if [ ! -z "$batchbase" ]; then + batch="read" + fi + fi + + getconf filelist no + getconf filelistbase + getconf include + getconf exclude + getconf exclude_vserver + getconf numericids 0 + getconf compress 0 + + # dest section + + setsection dest + getconf dest local + getconf fakesuper no + + if [ "$dest" == "remote" ]; then + getconf testconnect no + getconf protocol ssh + getconf ssh ssh + getconf host + + if [ "$protocol" == "ssh" ]; then + # sshd default listen port + getconf port 22 + else + # rsyncd default listen port + getconf port 873 + fi + + getconf user + getconf bandwidthlimit + getconf remote_rsync rsync + getconf id_file /root/.ssh/id_dsa + fi + + getconf batch no + + if [ "$batch" != "yes" ]; then + getconf batch no + if [ "$batch" == "yes" ]; then + getconf batchbase + if [ ! -z "$batchbase" ]; then + batch="write" + fi + fi + fi + + getconf numericids 0 + getconf compress 0 + + # services section + + setsection services + getconf initscripts /etc/init.d + getconf service + + # config check + + if [ "$dest" != "local" ] && [ "$from" == "remote" ]; then + fatal "When source is remote, destination should be local." + exit 1 + fi + + if [ "$from" != "local" ] && [ "$from" != "remote" ]; then + fatal "Invalid source $from" + exit 1 + fi + + backupdir="$mountpoint/$backupdir" + + if [ "$dest" == "local" ] && [ ! -d "$backupdir" ]; then + error "Backupdir $backupdir does not exist" + exit 1 + fi + + if [ ! -z "$log" ]; then + mkdir -p `dirname $log` + fi + + if [ "$format" == "short" ]; then + if [ -z "$days" ]; then + keep="4" + else + keep="`echo $days - 1 | bc -l`" + fi + fi + + if [ ! -z "$nicelevel" ]; then + nice="nice -n $nicelevel" + else + nice="" + fi + + ssh_cmd="ssh -T -o PasswordAuthentication=no $host -p $port -l $user -i $id_file" + + if [ "$from" == "remote" ] || [ "$dest" == "remote" ]; then + if [ "$testconnect" == "yes" ] && [ "$protocol" == "ssh" ]; then + test_connect $host $port $user $id_file + fi + fi + + if [ "$multiconnection" == "yes" ]; then + ssh_cmd="$ssh_cmd -S $tmp/%r@%h:%p" + fi + + if [ $enable_mv_timestamp_bug == "yes" ]; then + mv=move_files + fi + + for path in $exclude; do + excludes="$excludes --exclude=$path" + done - if [[ "$2" < 4 ]]; then - error "Rotate: minimum of 4 rotations" - exit 1 - fi +} + +function rotate_short { + + local dest + local folder="$1" + local keep="$2" + local metadata="`dirname $folder`/metadata" + + if [[ "$keep" < 4 ]]; then + error "Rotate: minimum of 4 rotations" + exit 1 + fi - if [ -d $1.$2 ]; then - $nice $mv /$1.$2 /$1.tmp - fi + if [ -d $folder.$keep ]; then + $nice $mv /$folder.$keep /$folder.tmp + fi - for ((n=`echo "$2 - 1" | bc`; n >= 0; n--)); do - if [ -d $1.$n ]; then - dest=`echo "$n + 1" | bc` - $nice $mv /$1.$n /$1.$dest - $touch /$1.$dest + for ((n=`echo "$keep - 1" | bc`; n >= 0; n--)); do + if [ -d $folder.$n ]; then + dest=`echo "$n + 1" | bc` + $nice $mv /$folder.$n /$folder.$dest + $touch /$folder.$dest + mkdir -p $metadata/`basename $folder`.$dest + date +%c%n%s > $metadata/`basename $folder`.$dest/rotated + fi + done + + if [ -d $folder.tmp ]; then + $nice $mv /$folder.tmp /$folder.0 + fi + + if [ -d $folder.1 ]; then + $nice $cp -alf /$folder.1/. /$folder.0 + fi + +} + +function rotate_short_remote { + + local folder="$1" + local metadata="`dirname $folder`/metadata" + local keep="$2" + + if [[ "$2" < 4 ]]; then + error "Rotate: minimum of 4 rotations" + exit 1 + fi + +( + $ssh_cmd <= 0; n--)); do + if [ -d $folder.\$n ]; then + dest=\$((\$n + 1)) + $nice mv /$folder.\$n /$folder.\$dest + touch /$folder.\$dest + mkdir -p $metadata/`basename $folder`.\$dest + date +%c%n%s > $metadata/`basename $folder`.\$dest/rotated + fi + done + + if [ -d $folder.tmp ]; then + $nice mv /$folder.tmp /$folder.0 + fi + + if [ -d $folder.1 ]; then + $nice $cp -alf /$folder.1/. /$folder.0 + fi + ##### END REMOTE SCRIPT ####### +EOF +) | (while read a; do passthru $a; done) + +} + +function rotate_long { + + backuproot="$1" + seconds_daily=86400 + seconds_weekly=604800 + seconds_monthly=2628000 + keepdaily=$keepdaily + keepweekly=$keepweekly + keepmonthly=$keepmonthly + now=`date +%s` + + local metadata + + if [ ! -d "$backuproot" ]; then + echo "Debug: skipping rotate of $backuproot as it doesn't exist." + exit + fi + + for rottype in daily weekly monthly; do + seconds=$((seconds_${rottype})) + + dir="$backuproot/$rottype" + metadata="$backuproot/metadata/$rottype.1" + mkdir -p $metadata + if [ ! -d $dir.1 ]; then + echo "Debug: $dir.1 does not exist, skipping." + continue 1 + elif [ ! -f $metadata/created ] && [ ! -f $metadata/rotated ]; then + echo "Warning: metadata does not exist for $dir.1. This backup may be only partially completed. Skipping rotation." + continue 1 + fi + + # Rotate the current list of backups, if we can. + oldest=`find $backuproot -maxdepth 1 -type d -name $rottype'.*' | @SED@ 's/^.*\.//' | sort -n | tail -1` + [ "$oldest" == "" ] && oldest=0 + for (( i=$oldest; i > 0; i-- )); do + if [ -d $dir.$i ]; then + if [ -f $metadata/created ]; then + created=`tail -1 $metadata/created` + elif [ -f $metadata/rotated ]; then + created=`tail -1 $metadata/rotated` + else + created=0 + fi + cutoff_time=$(( now - (seconds*(i-1)) )) + if [ ! $created -gt $cutoff_time ]; then + next=$(( i + 1 )) + if [ ! -d $dir.$next ]; then + echo "Debug: $rottype.$i --> $rottype.$next" + $nice mv $dir.$i $dir.$next + mkdir -p $backuproot/metadata/$rottype.$next + date +%c%n%s > $backuproot/metadata/$rottype.$next/rotated + else + echo "Debug: skipping rotation of $dir.$i because $dir.$next already exists." + fi + else + echo "Debug: skipping rotation of $dir.$i because it was created" $(( (now-created)/86400)) "days ago ("$(( (now-cutoff_time)/86400))" needed)." + fi fi - done + done + done + + max=$((keepdaily+1)) + if [ $keepweekly -gt 0 -a -d $backuproot/daily.$max -a ! -d $backuproot/weekly.1 ]; then + echo "Debug: daily.$max --> weekly.1" + $nice mv $backuproot/daily.$max $backuproot/weekly.1 + mkdir -p $backuproot/metadata/weekly.1 + date +%c%n%s > $backuproot/metadata/weekly.1/rotated + fi + + max=$((keepweekly+1)) + if [ $keepmonthly -gt 0 -a -d $backuproot/weekly.$max -a ! -d $backuproot/monthly.1 ]; then + echo "Debug: weekly.$max --> monthly.1" + $nice mv $backuproot/weekly.$max $backuproot/monthly.1 + mkdir -p $backuproot/metadata/monthly.1 + date +%c%n%s > $backuproot/metadata/monthly.1/rotated + fi + + for rottype in daily weekly monthly; do + max=$((keep${rottype}+1)) + dir="$backuproot/$rottype" + oldest=`find $backuproot -maxdepth 1 -type d -name $rottype'.*' | @SED@ 's/^.*\.//' | sort -n | tail -1` + [ "$oldest" == "" ] && oldest=0 + # if we've rotated the last backup off the stack, remove it. + for (( i=$oldest; i >= $max; i-- )); do + if [ -d $dir.$i ]; then + if [ -d $backuproot/rotate.tmp ]; then + echo "Debug: removing rotate.tmp" + $nice rm -rf $backuproot/rotate.tmp + fi + echo "Debug: moving $rottype.$i to rotate.tmp" + $nice mv $dir.$i $backuproot/rotate.tmp + fi + done + done - if [ -d $1.tmp ]; then - $nice $mv /$1.tmp /$1.0 - fi +} - if [ -d $1.1 ]; then - $nice $cp -alf /$1.1/. /$1.0 - fi +function rotate_long_remote { + + local backuproot="$1" + +( + $ssh_cmd < 0; i-- )); do + if [ -d \$dir.\$i ]; then + if [ -f \$metadata/created ]; then + created=\`tail -1 \$metadata/created\` + elif [ -f \$metadata/rotated ]; then + created=\`tail -1 \$metadata/rotated\` + else + created=0 + fi + cutoff_time=\$(( now - (seconds*(i-1)) )) + if [ ! \$created -gt \$cutoff_time ]; then + next=\$(( i + 1 )) + if [ ! -d \$dir.\$next ]; then + echo "Debug: \$rottype.\$i --> \$rottype.\$next" + $nice mv \$dir.\$i \$dir.\$next + mkdir -p $backuproot/metadata/\$rottype.\$next + date +%c%n%s > $backuproot/metadata/\$rottype.\$next/rotated + else + echo "Debug: skipping rotation of \$dir.\$i because \$dir.\$next already exists." + fi + else + echo "Debug: skipping rotation of \$dir.\$i because it was created" \$(( (now-created)/86400)) "days ago ("\$(( (now-cutoff_time)/86400))" needed)." + fi + fi + done + done + + max=\$((keepdaily+1)) + if [ \$keepweekly -gt 0 -a -d $backuproot/daily.\$max -a ! -d \$backuproot/weekly.1 ]; then + echo "Debug: daily.\$max --> weekly.1" + $nice mv $backuproot/daily.\$max $backuproot/weekly.1 + mkdir -p $backuproot/metadata/weekly.1 + date +%c%n%s > $backuproot/metadata/weekly.1/rotated + fi + + max=\$((keepweekly+1)) + if [ \$keepmonthly -gt 0 -a -d $backuproot/weekly.\$max -a ! -d $backuproot/monthly.1 ]; then + echo "Debug: weekly.\$max --> monthly.1" + $nice mv $backuproot/weekly.\$max $backuproot/monthly.1 + mkdir -p $backuproot/metadata/monthly.1 + date +%c%n%s > $backuproot/metadata/monthly.1/rotated + fi + + for rottype in daily weekly monthly; do + max=\$((keep\${rottype}+1)) + dir="$backuproot/\$rottype" + oldest=\`find $backuproot -maxdepth 1 -type d -name \$rottype'.*' | @SED@ 's/^.*\.//' | sort -n | tail -1\` + [ "\$oldest" == "" ] && oldest=0 + # if we've rotated the last backup off the stack, remove it. + for (( i=\$oldest; i >= \$max; i-- )); do + if [ -d \$dir.\$i ]; then + if [ -d $backuproot/rotate.tmp ]; then + echo "Debug: removing rotate.tmp" + $nice rm -rf $backuproot/rotate.tmp + fi + echo "Debug: moving \$rottype.\$i to rotate.tmp" + $nice mv \$dir.\$i $backuproot/rotate.tmp + fi + done + done + ##### END REMOTE SCRIPT ####### +EOF +) | (while read a; do passthru $a; done) + +} + +function setup_long_dirs { + + local destdir=$1 + local backuptype=$2 + local dir="$destdir/$backuptype" + local tmpdir="$destdir/rotate.tmp" + local metadata="$destdir/metadata/$backuptype.1" + + if [ ! -d $destdir ]; then + echo "Creating destination directory $destdir..." + mkdir -p $destdir + fi + + if [ -d $dir.1 ]; then + if [ -f $metadata/created ]; then + echo "Warning: $dir.1 already exists. Overwriting contents." + else + echo "Warning: we seem to be resuming a partially written $dir.1" + fi + else + if [ -d $tmpdir ]; then + mv $tmpdir $dir.1 + if [ $? == 1 ]; then + echo "Fatal: could mv $destdir/rotate.tmp $dir.1 on host $host" + exit 1 + fi + else + mkdir --parents $dir.1 + if [ $? == 1 ]; then + echo "Fatal: could not create directory $dir.1 on host $host" + exit 1 + fi + fi + if [ -d $dir.2 ]; then + echo "Debug: update links $backuptype.2 --> $backuptype.1" + cp -alf $dir.2/. $dir.1 + #if [ $? == 1 ]; then + # echo "Fatal: could not create hard links to $dir.1 on host $host" + # exit 1 + #fi + fi + fi + [ -f $metadata/created ] && rm $metadata/created + [ -f $metadata/rotated ] && rm $metadata/rotated + +} + +function setup_long_dirs_remote { + + local destdir=$1 + local backuptype=$2 + local dir="$destdir/$backuptype" + local tmpdir="$destdir/rotate.tmp" + local metadata="$destdir/metadata/$backuptype.1" + +( + $ssh_cmd < $backuptype.1" + cp -alf $dir.2/. $dir.1 + #if [ \$? == 1 ]; then + # echo "Fatal: could not create hard links to $dir.1 on host $host" + # exit 1 + #fi + fi + fi + [ -f $metadata/created ] && rm $metadata/created + [ -f $metadata/rotated ] && rm $metadata/rotated + ##### END REMOTE SCRIPT ####### +EOF +) | (while read a; do passthru $a; done) } function move_files { - ref=$tmp/makesnapshot-mymv-$$; - $touch -r $1 $ref; - $mv $1 $2; - $touch -r $ref $2; - $rm $ref; + ref=$tmp/makesnapshot-mymv-$$; + $touch -r $1 $ref; + $mv $1 $2; + $touch -r $ref $2; + $rm $ref; + +} + +function prepare_storage { + + section="`basename $SECTION`" + + if [ "$format" == "short" ]; then + + suffix="$section.0" + info "Rotating $backupdir/$SECTION..." + echo "Rotating $backupdir/$SECTION..." >> $log + + if [ "$dest" == "remote" ]; then + rotate_short_remote $backupdir/$SECTION/$section $keep + else + rotate_short $backupdir/$SECTION/$section $keep + if [ ! -d "$backupdir/$SECTION/$section.0" ]; then + mkdir -p $backupdir/$SECTION/$section.0 + fi + fi + + elif [ "$format" == "long" ]; then + + if [ $keepdaily -gt 0 ]; then + btype=daily + elif [ $keepweekly -gt 0 ]; then + btype=weekly + elif [ $keepmonthly -gt 0 ]; then + btype=monthly + else + fatal "keeping no backups"; + exit 1 + fi + + suffix="$btype.1" + info "Rotating $backupdir/$SECTION/..." + echo "Rotating $backupdir/$SECTION/..." >> $log + + if [ "$dest" == "remote" ]; then + rotate_long_remote $backupdir/$SECTION + setup_long_dirs_remote $backupdir/$SECTION $btype + else + rotate_long $backupdir/$SECTION + setup_long_dirs $backupdir/$SECTION $btype + fi + + elif [ "$format" == "mirror" ]; then + suffix="" + else + fatal "Invalid backup format $format" + exit 1 + fi + +} + +function set_orig { + + if [ "$from" == "local" ]; then + orig="/$SECTION/" + elif [ "$from" == "remote" ]; then + if [ "$protocol" == "rsync" ]; then + orig="rsync://$user@$host:$port/$SECTION/" + else + orig="$user@$host:/$SECTION/" + fi + fi } -backupdir="$mountpoint/$backupdir" +function set_dest { -# does $backupdir exists? + if [ "$dest" == "local" ]; then + dest_path="$backupdir/$SECTION/$suffix/" + else + if [ "$protocol" == "rsync" ]; then + dest_path="rsync://$user@$host:$port/$backupdir/$SECTION/$suffix/" + else + dest_path="$user@$host:$backupdir/$SECTION/$suffix/" + fi + fi -if [ ! -d "$backupdir" ]; then - error "Backupdir $backupdir does not exist" - exit 1 -fi +} -# setup number of increments +function set_batch_mode { -if [ -z "$days" ]; then - keep="4" -else - keep="`echo $days - 1 | bc -l`" -fi + local batch_file="$batchbase/$SECTION/$suffix" -# lockfile setup + if [ "$batch" == "read" ]; then + if [ -e "$batch_file" ]; then + orig="" + excludes="" + batch_option="--read-batch=$batch_file" + else + fatal "Batch file not found: $batch_file" + exit 1 + fi + elif [ "$batch" == "write" ]; then + mkdir -p `dirname $batch_file` + batch_option="--write-batch=$batch_file" + fi -if [ ! -z "$lockfile" ]; then - $touch $lockfile || warning "Could not create lockfile $lockfile" -fi +} -# nicelevel setup +function update_metadata { -if [ ! -z "$nicelevel" ]; then - nice="nice -n $nicelevel" -else - nice="" -fi + local metadata + local folder -# connection test + if [ "$dest" == "local" ]; then + metadata="`dirname $dest_path`/metadata/`basename $dest_path`" + mkdir -p $metadata + date +%c%n%s > $metadata/created + $touch $backupdir/$SECTION/$suffix + else + folder="`echo $dest_path | cut -d : -f 2`" + metadata="`dirname $folder`/metadata/`basename $folder`" -if [ "$from" == "remote" ] && [ "$testconnect" == "yes" ]; then - debug "$ssh -o PasswordAuthentication=no $user@$host 'echo -n 1'" - result=`ssh -o PasswordAuthentication=no $user@$host 'echo -n 1'` - if [ "$result" != "1" ]; then - fatal "Can't connect to $host as $user." - else - debug "Connected to $srchost successfully" - fi -fi +( + $ssh_cmd < $metadata/created + ##### END REMOTE SCRIPT ####### +EOF +) | (while read a; do passthru $a; done) -# rsync options for local sources + fi -if [ "$from" == "local" ]; then +} - rsync_local_options="$rsync_options" +function test_connect { - if [ ! -z "$numericids" ]; then - rsync_local_options="$rsync_local_options --numeric-ids " - fi + local host="$1" + local port="$2" + local user="$3" + local id_file="$4" -fi + if [ -z "$host" ] || [ -z "$user" ]; then + fatal "Remote host or user not set" + exit 1 + fi -# rsync options for remote sources + debug "$ssh_cmd 'echo -n 1'" + result=`$ssh_cmd 'echo -n 1'` -if [ "$from" == "remote" ]; then + if [ "$result" != "1" ]; then + fatal "Can't connect to $host as $user." + exit 1 + else + debug "Connected to $host successfully" + fi - rsync_remote_options="$rsync_options --rsync-path=$remote_rsync" +} - if [ "$compress" == "1" ]; then - rsync_remote_options="$rsync_remote_options --compress" - fi +function set_lockfile { - if [ ! -z "$bandwidthlimit" ]; then - rsync_remote_options="$rsync_remote_options --bwlimit=$bandwidthlimit" - fi + if [ ! -z "$lockfile" ]; then + $touch $lockfile || warning "Could not create lockfile $lockfile" + fi - if [ ! -z "$numericids" ]; then - rsync_remote_options="$rsync_remote_options --numeric-ids" - fi +} -fi +function unset_lockfile { -# set mv procedure + if [ ! -z "$lockfile" ]; then + $rm $lockfile || warning "Could not remove lockfile $lockfile" + fi -if [ $enable_mv_timestamp_bug == "yes" ]; then - mv=move_files -fi +} -# set excludes +function set_filelist { -for path in $exclude; do - EXCLUDES="$EXCLUDES --exclude=$path" -done + filelist_flag="" -# stop services + if [ "$filelist" == "yes" ]; then + if [ ! -z "$filelistbase" ]; then + if [ -e "$filelistbase/$SECTION/$suffix" ]; then + filelist_flag="--files-from=$filelistbase/$SECTION/$suffix" + else + warning "File list $filelistbase/$SECTION/$suffix not found." + fi + else + warning "No filelistbase set." + fi + fi -if [ ! -z "$service" ]; then - for daemon in $service; do +} + +function set_rsync_options { + + if [ ! -z "$numericids" ]; then + rsync_options="$rsync_options --numeric-ids" + fi + + if [ "$from" == "local" ] || [ "$dest" == "local" ]; then + # rsync options for local sources or destinations + rsync_options="$rsync_options" + fi + + if [ "$from" == "remote" ] || [ "$dest" == "remote" ]; then + + # rsync options for remote sources or destinations + + if [ "$compress" == "1" ]; then + rsync_options="$rsync_options --compress" + fi + + if [ ! -z "$bandwidthlimit" ]; then + rsync_options="$rsync_options --bwlimit=$bandwidthlimit" + fi + + if [ "$fakesuper" == "yes" ]; then + remote_rsync="$remote_rsync --fake-super" + fi + + rsync_options=($rsync_options --rsync-path="$remote_rsync") + + if [ "$protocol" == "ssh" ]; then + if [ ! -e "$id_file" ]; then + fatal "SSH Identity file $id_file not found" + exit 1 + else + debug RSYNC_RSH=\"$ssh_cmd\" + echo RSYNC_RSH=\"$ssh_cmd\" >> $log + RSYNC_RSH="$ssh_cmd" + fi + fi + + fi + + include_vservers + +} + +function stop_services { + + if [ ! -z "$service" ]; then + for daemon in $service; do info "Stopping service $daemon..." $initscripts/$daemon stop - done -fi + done + fi -echo "Starting backup at `date`" >> $log +} + +function start_services { + + # restart services + + if [ ! -z "$service" ]; then + for daemon in $service; do + info "Starting service $daemon..." + $initscripts/$daemon start + done + fi + +} + +function mount_rw { + + # mount backup destination folder as read-write + + if [ "$dest" == "local" ]; then + if [ "$read_only" == "1" ] || [ "$read_only" == "yes" ]; then + if [ -d "$mountpoint" ]; then + mount -o remount,rw $mountpoint + if (($?)); then + error "Could not mount $mountpoint" + exit 1 + fi + fi + fi + fi + +} + +function mount_ro { + + # remount backup destination as read-only + + if [ "$dest" == "local" ]; then + if [ "$read_only" == "1" ] || [ "$read_only" == "yes" ]; then + mount -o remount,ro $mountpoint + fi + fi + +} -# mount backup destination folder as read-write +function run_fsck { -if [ "$read_only" == "1" ] || [ "$read_only" == "yes" ]; then - if [ -d "$mountpoint" ]; then - mount -o remount,rw $mountpoint + # check partition for errors + + if [ "$dest" == "local" ]; then + if [ "$fscheck" == "1" ] || [ "$fscheck" == "yes" ]; then + umount $mountpoint if (($?)); then - error "Could not mount $mountpoint" - exit 1 + warning "Could not umount $mountpoint to run fsck" + else + $nice $fsck -v -y $partition >> $log + mount $mountpoint fi - fi -fi + fi + fi + +} -# add vservers to included folders +function include_vservers { -if [ "$vservers_are_available" == "yes" ]; then + # add vservers to included folders - # sane permission on backup - mkdir -p $backupdir/$VROOTDIR - chmod 000 $backupdir/$VROOTDIR + if [ "$vservers_are_available" == "yes" ]; then - for candidate in $found_vservers; do + # sane permission on backup + mkdir -p $backupdir/$VROOTDIR + chmod 000 $backupdir/$VROOTDIR + + for candidate in $found_vservers; do candidate="`basename $candidate`" found_excluded_vserver="0" for excluded_vserver in $exclude_vserver; do - if [ "$excluded_vserver" == "$candidate" ]; then - found_excluded_vserver="1" - break - fi + if [ "$excluded_vserver" == "$candidate" ]; then + found_excluded_vserver="1" + break + fi done if [ "$found_excluded_vserver" == "0" ]; then - include="$include $VROOTDIR/$candidate" + include="$include $VROOTDIR/$candidate" fi - done -fi + done + fi -# the backup procedure +} -for SECTION in $include; do +function start_mux { - section="`basename $SECTION`" + if [ "$multiconnection" == "yes" ]; then + debug "Starting master ssh connection" + $ssh_cmd -M sleep 1d & + sleep 1 + fi - if [ ! -d "$backupdir/$SECTION/$section.0" ]; then - mkdir -p $backupdir/$SECTION/$section.0 - fi +} - info "Rotating $backupdir/$SECTION/$section..." - echo "Rotating $backupdir/$SECTION/$section..." >> $log - rotate $backupdir/$SECTION/$section $keep - info "Syncing $SECTION on $backupdir/$SECTION/$section.0..." +function end_mux { - if [ "$from" == "local" ]; then - debug $rsync $rsync_local_options $EXCLUDES /$SECTION/ $backupdir/$SECTION/$section.0/ - $nice $rsync $rsync_local_options $EXCLUDES /$SECTION/ $backupdir/$SECTION/$section.0/ >> $log - if [ "$?" != "0" ]; then - warning "Rsync error when trying to transfer $SECTION" - fi - elif [ "$from" == "remote" ]; then - if [ -z "$user" ] || [ -z "$host" ]; then - error "Config file error: either user or host was not specified" - exit 1 - else - debug $nice $rsync $rsync_remote_options $EXCLUDES -e "$ssh" $user@$host:/$SECTION/ $backupdir/$SECTION/$section.0 - $nice $rsync $rsync_remote_options $EXCLUDES -e "$ssh" $user@$host:/$SECTION/ $backupdir/$SECTION/$section.0 >> $log - if [ "$?" != "0" ]; then - warning "Rsync error when trying to transfer $SECTION" - fi - fi - else - error "Invalid source $from" - exit 1 - fi + if [ "$multiconnection" == "yes" ]; then + debug "Stopping master ssh connection" + $ssh_cmd pkill sleep + fi - $touch $backupdir/$SECTION/$section.0 +} -done +# the backup procedure -# remount backup destination as read-only +eval_config +set_lockfile +set_rsync_options +start_mux +stop_services +mount_rw -if [ "$read_only" == "1" ] || [ "$read_only" == "yes" ]; then - mount -o remount,ro $mountpoint -fi +echo "Starting backup at `date`" >> $log -# check partition for errors +for SECTION in $include; do -if [ "$fscheck" == "1" ] || [ "$fscheck" == "yes" ]; then - umount $mountpoint - if (($?)); then - warning "Could not umount $mountpoint to run fsck" - else - $nice $fsck -v -y $partition >> $log - mount $mountpoint - fi -fi + prepare_storage + set_orig + set_batch_mode + set_filelist + set_dest -# restart services + info "Syncing $SECTION on $dest_path..." + debug $nice $rsync "${rsync_options[@]}" $filelist_flag $excludes $batch_option $orig $dest_path + $nice $rsync "${rsync_options[@]}" $filelist_flag $excludes $batch_option $orig $dest_path >> $log -if [ ! -z "$service" ]; then - for daemon in $service; do - info "Starting service $daemon..." - $initscripts/$daemon start - done -fi + if [ "$?" != "0" ]; then + warning "Rsync error when trying to transfer $SECTION" + fi + + update_metadata -# removes the lockfile +done -if [ ! -z "$lockfile" ]; then - $rm $lockfile || warning "Could not remove lockfile $lockfile" -fi +mount_ro +run_fsck +start_services +unset_lockfile +end_mux echo "Finnishing backup at `date`" >> $log -- 2.30.2 From f9672647177f771270f40a858fb94283ff1ebcdf Mon Sep 17 00:00:00 2001 From: intrigeri Date: Thu, 19 Nov 2009 20:27:46 +0100 Subject: [PATCH 04/16] ldap, mysql, pgsql: use gzip's --rsyncable option --- ChangeLog | 5 +++++ handlers/ldap.in | 2 +- handlers/mysql.in | 4 ++-- handlers/pgsql.in | 8 ++++---- 4 files changed, 12 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index c91ca38..4a4a3b1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -6,6 +6,8 @@ version 0.9.7 -- UNRELEASED file or in a given backup action file. Thanks Tuomas Jormola for the preliminary patch (Closes: #511299) handler changes + ldap: + . Use gzip's --rsyncable option. maildir: . fix location of deleted_on file . add missing destid_file options to ssh connections @@ -20,6 +22,9 @@ version 0.9.7 -- UNRELEASED does not prevent mysqldump to work. . Fix the error message displayed when mysqld is not running: mysqladmin ping indeed returns 0 when authentication fails. + . Use gzip's --rsyncable option. + pgsql: + . Use gzip's --rsyncable option. sys: . New luksheaders option (default=disabled) to backup the Luks header of every Luks device. diff --git a/handlers/ldap.in b/handlers/ldap.in index 5f402c7..853cefb 100644 --- a/handlers/ldap.in +++ b/handlers/ldap.in @@ -86,7 +86,7 @@ if [ "$ldif" == "yes" ]; then fi if [ "$compress" == "yes" ]; then - execstr="$execstr | $GZIP > $dumpdir/$dbsuffix.ldif.gz" + execstr="$execstr | $GZIP --rsyncable > $dumpdir/$dbsuffix.ldif.gz" else execstr="$execstr > $dumpdir/$dbsuffix.ldif" fi diff --git a/handlers/mysql.in b/handlers/mysql.in index 88ffb1a..e1e89b0 100644 --- a/handlers/mysql.in +++ b/handlers/mysql.in @@ -272,7 +272,7 @@ then fatal "mysqld doesn't appear to be running!" fi if [ "$compress" == "yes" ]; then - execstr="$VSERVER $vsname exec $DUMP | $GZIP > $vroot$dumpdir/${db}.sql.gz" + execstr="$VSERVER $vsname exec $DUMP | $GZIP --rsyncable > $vroot$dumpdir/${db}.sql.gz" else execstr="$VSERVER $vsname exec $DUMP -r $vroot$dumpdir/${db}.sql" fi @@ -283,7 +283,7 @@ then fatal "mysqld doesn't appear to be running!" fi if [ "$compress" == "yes" ]; then - execstr="$DUMP | $GZIP > $dumpdir/${db}.sql.gz" + execstr="$DUMP | $GZIP --rsyncable > $dumpdir/${db}.sql.gz" else execstr="$DUMP -r $dumpdir/${db}.sql" fi diff --git a/handlers/pgsql.in b/handlers/pgsql.in index ff5f7ba..a7e3ec2 100644 --- a/handlers/pgsql.in +++ b/handlers/pgsql.in @@ -75,13 +75,13 @@ chmod 700 $vroot$backupdir if [ "$databases" == "all" ]; then if [ $usevserver = yes ]; then if [ "$compress" == "yes" ]; then - execstr="$VSERVER $vsname exec su - $PGSQLUSER -c \"$PGSQLDUMPALL | $GZIP > $backupdir/${vsname}.sql.gz\"" + execstr="$VSERVER $vsname exec su - $PGSQLUSER -c \"$PGSQLDUMPALL | $GZIP --rsyncable > $backupdir/${vsname}.sql.gz\"" else execstr="$VSERVER $vsname exec su - $PGSQLUSER -c \"$PGSQLDUMPALL > $backupdir/${vsname}.sql\"" fi else if [ "$compress" == "yes" ]; then - execstr="su - $PGSQLUSER -c \"$PGSQLDUMPALL | $GZIP > $backupdir/${localhost}-all.sql.gz\"" + execstr="su - $PGSQLUSER -c \"$PGSQLDUMPALL | $GZIP --rsyncable > $backupdir/${localhost}-all.sql.gz\"" else execstr="su - $PGSQLUSER -c \"$PGSQLDUMPALL > $backupdir/${localhost}-all.sql\"" fi @@ -104,13 +104,13 @@ else for db in $databases; do if [ $usevserver = yes ]; then if [ "$compress" == "yes" ]; then - execstr="$VSERVER $vsname exec su - $PGSQLUSER -c \"$PGSQLDUMP $db | $GZIP > $backupdir/${db}.sql.gz\"" + execstr="$VSERVER $vsname exec su - $PGSQLUSER -c \"$PGSQLDUMP $db | $GZIP --rsyncable > $backupdir/${db}.sql.gz\"" else execstr="$VSERVER $vsname exec su - $PGSQLUSER -c \"$PGSQLDUMP $db | > $backupdir/${db}.sql\"" fi else if [ "$compress" == "yes" ]; then - execstr="su - $PGSQLUSER -c \"$PGSQLDUMP $db | $GZIP > $backupdir/${db}.sql.gz\"" + execstr="su - $PGSQLUSER -c \"$PGSQLDUMP $db | $GZIP --rsyncable > $backupdir/${db}.sql.gz\"" else execstr="su - $PGSQLUSER -c \"$PGSQLDUMP $db > $backupdir/${db}.sql\"" fi -- 2.30.2 From 34d0d30593e09a6d0af06e2f201b879cc391c6af Mon Sep 17 00:00:00 2001 From: Micah Anderson Date: Wed, 2 Dec 2009 17:09:16 -0500 Subject: [PATCH 05/16] adjust the comparison operators in the rsync handler, fixes #1473 --- handlers/rsync.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/handlers/rsync.in b/handlers/rsync.in index 829f148..9e04efe 100644 --- a/handlers/rsync.in +++ b/handlers/rsync.in @@ -306,7 +306,7 @@ function rotate_short { local keep="$2" local metadata="`dirname $folder`/metadata" - if [[ "$keep" < 4 ]]; then + if [[ "$keep" -lt 4 ]]; then error "Rotate: minimum of 4 rotations" exit 1 fi @@ -341,7 +341,7 @@ function rotate_short_remote { local metadata="`dirname $folder`/metadata" local keep="$2" - if [[ "$2" < 4 ]]; then + if [[ "$2" -lt 4 ]]; then error "Rotate: minimum of 4 rotations" exit 1 fi -- 2.30.2 From 6606cce4454fc040c60889db82c274704d840ec8 Mon Sep 17 00:00:00 2001 From: intrigeri Date: Thu, 24 Dec 2009 16:57:31 +0100 Subject: [PATCH 06/16] easydialog: allow form fields input to grow up to 100 chars (Closes: #562249) --- ChangeLog | 3 +++ lib/easydialog.in | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 4a4a3b1..9a6ccaa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5,6 +5,9 @@ version 0.9.7 -- UNRELEASED . add 'when = manual' option, that can be used in the global config file or in a given backup action file. Thanks Tuomas Jormola for the preliminary patch (Closes: #511299) + lib changes + easydialog: + . Allow form fields input to grow up to 100 chars (Closes: #562249) handler changes ldap: . Use gzip's --rsyncable option. diff --git a/lib/easydialog.in b/lib/easydialog.in index c41e6f7..6b41e1b 100644 --- a/lib/easydialog.in +++ b/lib/easydialog.in @@ -240,7 +240,7 @@ formDisplay() { for ((i=0; i < $_form_items ; i++)); do label=${_form_labels[$i]} text=${_form_text[$i]} - echo -n -e " $label $xpos 1 '$text' $xpos $max_length 30 30" + echo -n -e " $label $xpos 1 '$text' $xpos $max_length 30 100" let "xpos += _form_gap" done ) | xargs $DIALOG 2> $temp -- 2.30.2 From 8d10a6555c8806857bad8accb329f3282836afdb Mon Sep 17 00:00:00 2001 From: intrigeri Date: Fri, 25 Dec 2009 01:30:11 +0100 Subject: [PATCH 07/16] fix copy'n'paste doc error --- examples/example.rdiff | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/example.rdiff b/examples/example.rdiff index 903fd19..08e8869 100644 --- a/examples/example.rdiff +++ b/examples/example.rdiff @@ -1,7 +1,7 @@ ## ## This is an example rdiff-backup configuration file. ## -## Here you can find all the possible duplicity options, details of +## Here you can find all the possible rdiff-backup options, details of ## what the options provide and possible settings. The defaults are set ## as the commented out option, uncomment and change when ## necessary. Options which are uncommented in this example do not have -- 2.30.2 From 5da707b309c08de3fa7d3792d98f337eb5169141 Mon Sep 17 00:00:00 2001 From: intrigeri Date: Fri, 25 Dec 2009 02:28:55 +0100 Subject: [PATCH 08/16] rsync: added vim and Emacs modelines for consistency's sake --- handlers/rsync.in | 2 ++ 1 file changed, 2 insertions(+) diff --git a/handlers/rsync.in b/handlers/rsync.in index 9e04efe..8f638d7 100644 --- a/handlers/rsync.in +++ b/handlers/rsync.in @@ -1,3 +1,5 @@ +# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*- +# vim: set filetype=sh sw=3 sts=3 expandtab autoindent: # # backupninja handler for incremental backups using rsync and hardlinks # feedback: rhatto at riseup.net -- 2.30.2 From f4ab3148f175f8ac415b01fea61d14a80f4de969 Mon Sep 17 00:00:00 2001 From: intrigeri Date: Fri, 25 Dec 2009 02:33:13 +0100 Subject: [PATCH 09/16] mysql, pgsql: Quote output filenames ... to support shell meta-characters in database names. Closes Redmine bug #617. --- ChangeLog | 4 ++++ NEWS | 9 +++++++++ handlers/mysql.in | 8 ++++---- handlers/pgsql.in | 16 ++++++++-------- 4 files changed, 25 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9a6ccaa..97d4353 100644 --- a/ChangeLog +++ b/ChangeLog @@ -26,8 +26,12 @@ version 0.9.7 -- UNRELEASED . Fix the error message displayed when mysqld is not running: mysqladmin ping indeed returns 0 when authentication fails. . Use gzip's --rsyncable option. + . Quote output filenames to support shell meta-characters in + database names. pgsql: . Use gzip's --rsyncable option. + . Quote output filenames to support shell meta-characters in + database names. sys: . New luksheaders option (default=disabled) to backup the Luks header of every Luks device. diff --git a/NEWS b/NEWS index 361cf3c..ef8592e 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,12 @@ +backupninja (0.9.7-1) UNRELEASED + + * mysql: output filenames to support shell meta-characters in + database names. This change was not heavily tested, please + report any breakage. + * pgsql: output filenames to support shell meta-characters in + database names. This change was not heavily tested, please + report any breakage. + backupninja (0.9.4-1) UNRELEASED * duplicity: Old (pre-0.9.4) example.dup file used to give false diff --git a/handlers/mysql.in b/handlers/mysql.in index e1e89b0..0aa3abb 100644 --- a/handlers/mysql.in +++ b/handlers/mysql.in @@ -272,9 +272,9 @@ then fatal "mysqld doesn't appear to be running!" fi if [ "$compress" == "yes" ]; then - execstr="$VSERVER $vsname exec $DUMP | $GZIP --rsyncable > $vroot$dumpdir/${db}.sql.gz" + execstr="$VSERVER $vsname exec $DUMP | $GZIP --rsyncable > '$vroot$dumpdir/${db}.sql.gz'" else - execstr="$VSERVER $vsname exec $DUMP -r $vroot$dumpdir/${db}.sql" + execstr="$VSERVER $vsname exec $DUMP -r '$vroot$dumpdir/${db}.sql'" fi else # Test to make sure mysqld is running, if it is not sqldump will not work @@ -283,9 +283,9 @@ then fatal "mysqld doesn't appear to be running!" fi if [ "$compress" == "yes" ]; then - execstr="$DUMP | $GZIP --rsyncable > $dumpdir/${db}.sql.gz" + execstr="$DUMP | $GZIP --rsyncable > '$dumpdir/${db}.sql.gz'" else - execstr="$DUMP -r $dumpdir/${db}.sql" + execstr="$DUMP -r '$dumpdir/${db}.sql'" fi fi debug "su $user -c \"$execstr\"" diff --git a/handlers/pgsql.in b/handlers/pgsql.in index a7e3ec2..d7839fb 100644 --- a/handlers/pgsql.in +++ b/handlers/pgsql.in @@ -75,15 +75,15 @@ chmod 700 $vroot$backupdir if [ "$databases" == "all" ]; then if [ $usevserver = yes ]; then if [ "$compress" == "yes" ]; then - execstr="$VSERVER $vsname exec su - $PGSQLUSER -c \"$PGSQLDUMPALL | $GZIP --rsyncable > $backupdir/${vsname}.sql.gz\"" + execstr="$VSERVER $vsname exec su - $PGSQLUSER -c \"$PGSQLDUMPALL | $GZIP --rsyncable > '$backupdir/${vsname}.sql.gz'\"" else - execstr="$VSERVER $vsname exec su - $PGSQLUSER -c \"$PGSQLDUMPALL > $backupdir/${vsname}.sql\"" + execstr="$VSERVER $vsname exec su - $PGSQLUSER -c \"$PGSQLDUMPALL > '$backupdir/${vsname}.sql'\"" fi else if [ "$compress" == "yes" ]; then - execstr="su - $PGSQLUSER -c \"$PGSQLDUMPALL | $GZIP --rsyncable > $backupdir/${localhost}-all.sql.gz\"" + execstr="su - $PGSQLUSER -c \"$PGSQLDUMPALL | $GZIP --rsyncable > '$backupdir/${localhost}-all.sql.gz'\"" else - execstr="su - $PGSQLUSER -c \"$PGSQLDUMPALL > $backupdir/${localhost}-all.sql\"" + execstr="su - $PGSQLUSER -c \"$PGSQLDUMPALL > '$backupdir/${localhost}-all.sql'\"" fi fi debug "$execstr" @@ -104,15 +104,15 @@ else for db in $databases; do if [ $usevserver = yes ]; then if [ "$compress" == "yes" ]; then - execstr="$VSERVER $vsname exec su - $PGSQLUSER -c \"$PGSQLDUMP $db | $GZIP --rsyncable > $backupdir/${db}.sql.gz\"" + execstr="$VSERVER $vsname exec su - $PGSQLUSER -c \"$PGSQLDUMP $db | $GZIP --rsyncable > '$backupdir/${db}.sql.gz'\"" else - execstr="$VSERVER $vsname exec su - $PGSQLUSER -c \"$PGSQLDUMP $db | > $backupdir/${db}.sql\"" + execstr="$VSERVER $vsname exec su - $PGSQLUSER -c \"$PGSQLDUMP $db | > '$backupdir/${db}.sql'\"" fi else if [ "$compress" == "yes" ]; then - execstr="su - $PGSQLUSER -c \"$PGSQLDUMP $db | $GZIP --rsyncable > $backupdir/${db}.sql.gz\"" + execstr="su - $PGSQLUSER -c \"$PGSQLDUMP $db | $GZIP --rsyncable > '$backupdir/${db}.sql.gz'\"" else - execstr="su - $PGSQLUSER -c \"$PGSQLDUMP $db > $backupdir/${db}.sql\"" + execstr="su - $PGSQLUSER -c \"$PGSQLDUMP $db > '$backupdir/${db}.sql'\"" fi fi debug "$execstr" -- 2.30.2 From 4996d8deb7fcf366f5c012ae919b1245db3d7b6a Mon Sep 17 00:00:00 2001 From: intrigeri Date: Fri, 25 Dec 2009 04:09:29 +0100 Subject: [PATCH 10/16] autotools: added the stat command to the automagically replaced ones ... hoping it will help supporting *BSD some day. --- ChangeLog | 3 +++ configure.in | 7 +++++++ src/Makefile.am | 1 + src/backupninja.in | 4 ++-- 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 97d4353..d0f7011 100644 --- a/ChangeLog +++ b/ChangeLog @@ -41,6 +41,9 @@ version 0.9.7 -- UNRELEASED dup: . Fixed bandwidthlimit syntax error. Thanks to Ian Beckwith for the patch. + autotools + . Added the stat command to the automagically replaced ones, hoping it + will help supporting *BSD some day. version 0.9.6 -- July 21, 2008 backupninja changes diff --git a/configure.in b/configure.in index 26e95be..174399d 100644 --- a/configure.in +++ b/configure.in @@ -36,6 +36,13 @@ if test x$MKTEMPT = "xno"; then AC_MSG_ERROR([mktemp is required]) fi +AC_PATH_PROGS(STAT, stat, "no") +if test x$STAT = "xno"; then + AC_MSG_ERROR([stat is required]) +else + export STAT +fi + AC_CHECK_PROG(ac_cv_have_rpm, rpm, "yes", "no") if test "x$ac_cv_have_rpm" = "xyes"; then rpm --define '_topdir /tmp' > /dev/null 2>&1 diff --git a/src/Makefile.am b/src/Makefile.am index 3d5bdb8..5694e9a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -11,6 +11,7 @@ edit = sed \ -e "s,@BASH\@,$(BASH),g" \ -e "s,@AWK\@,$(AWK),g" \ -e "s,@SED\@,$(SED),g" \ + -e "s,@STAT\@,$(STAT),g" \ -e 's,@datadir\@,$(pkgdatadir),g' \ -e "s,@libdir\@,$(pkglibdir),g" \ -e 's,@localstatedir\@,$(localstatedir),g' \ diff --git a/src/backupninja.in b/src/backupninja.in index a158715..a991f58 100755 --- a/src/backupninja.in +++ b/src/backupninja.in @@ -143,14 +143,14 @@ function check_perms() { local perms local owners - perms=($(stat -L --format='%A' $file)) + perms=($(@STAT@ -L --format='%A' $file)) debug "perms: $perms" local gperm=${perms:4:3} debug "gperm: $gperm" local wperm=${perms:7:3} debug "wperm: $wperm" - owners=($(stat -L --format='%g %G %u %U' $file)) + owners=($(@STAT@ -L --format='%g %G %u %U' $file)) local gid=${owners[0]} local group=${owners[1]} local owner=${owners[2]} -- 2.30.2 From 9400bd0098b6aa103d818d2d3d78f555c6e72bf2 Mon Sep 17 00:00:00 2001 From: intrigeri Date: Fri, 25 Dec 2009 04:25:44 +0100 Subject: [PATCH 11/16] Fixed remaining pointers to our deprecated Trac instance. --- TODO | 4 ++-- backupninja.spec.in | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/TODO b/TODO index 16ee78c..db8c2d6 100644 --- a/TODO +++ b/TODO @@ -5,8 +5,8 @@ you are working on it! . Fix all bugs reported on the Debian BTS: http://bugs.debian.org/cgi-bin/pkgreport.cgi?which=pkg&data=backupninja&archive=no -. Fix all bugs reported on our Trac: - https://code.autistici.org/trac/backupninja/report/3 +. Fix all bugs reported on our Redmine instance: + https://labs.riseup.net/code/projects/backupninja/issues . Make ninjahelper allow you to pick what type of backup you want (instead of just assuming you want local-to-remote, or push backups. Some people diff --git a/backupninja.spec.in b/backupninja.spec.in index 917e4de..8a62023 100644 --- a/backupninja.spec.in +++ b/backupninja.spec.in @@ -7,7 +7,7 @@ Version: %{version} Release: 1 License: GPL Group: Applications/System -URL: http://dev.riseup.net/backupninja/ +URL: https://labs.riseup.net/code/projects/show/backupninja Source: %{name}-%{version}.tar.gz Requires: bash, gawk, rdiff-backup, gzip Provides: %{name} -- 2.30.2 From 29b86fdfb88ab8aff53b2464dbd9961506d701fa Mon Sep 17 00:00:00 2001 From: intrigeri Date: Fri, 25 Dec 2009 04:27:21 +0100 Subject: [PATCH 12/16] TODO: removed issues that are resolved or tracked in Redmine --- TODO | 5 ----- 1 file changed, 5 deletions(-) diff --git a/TODO b/TODO index db8c2d6..b826d0d 100644 --- a/TODO +++ b/TODO @@ -13,9 +13,6 @@ you are working on it! want local-to-local, or remote-to-local, or pull backups). This has been reported for the duplicity handler as Debian bug #346040. -. Make it so backupninja can be run as a regular user, instead of requiring - root - . Allow vsnames "all" in the msyql handler. . Factorize the rdiff.helper's connection-related functions into a lib, so @@ -25,5 +22,3 @@ you are working on it! . Add an exclude option to database handlers so you can configure it to backup all databases, except for the excluded ones - -. Consolidate the 'rsnap' and 'rub' handlers into one rsync snapshot handler -- 2.30.2 From d4c5f73ad70bedbf54ee86dcbafead39f6318d55 Mon Sep 17 00:00:00 2001 From: intrigeri Date: Thu, 31 Dec 2009 17:05:47 +0100 Subject: [PATCH 13/16] dup.helper: do not propose to exclude /home/*/.gnupg twice anymore (Closes: #563044) --- ChangeLog | 4 ++++ handlers/dup.helper.in | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index d0f7011..5f6d51b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -41,6 +41,10 @@ version 0.9.7 -- UNRELEASED dup: . Fixed bandwidthlimit syntax error. Thanks to Ian Beckwith for the patch. + helper changes + dup: + . Do not propose to exclude /home/*/.gnupg twice anymore + (Closes: #563044) autotools . Added the stat command to the automagically replaced ones, hoping it will help supporting *BSD some day. diff --git a/handlers/dup.helper.in b/handlers/dup.helper.in index 3c08a2f..2fafb99 100644 --- a/handlers/dup.helper.in +++ b/handlers/dup.helper.in @@ -508,7 +508,7 @@ dup_wizard() { # Global variables whose '*' shall not be expanded set -o noglob dup_default_includes="/var/spool/cron/crontabs /var/backups /etc /root /home /usr/local/*bin /var/lib/dpkg/status*" - dup_default_excludes="/home/*/.gnupg /home/*/.gnupg /home/*/.local/share/Trash /home/*/.Trash /home/*/.thumbnails /home/*/.beagle /home/*/.aMule /home/*/gtk-gnutella-downloads" + dup_default_excludes="/home/*/.gnupg /home/*/.local/share/Trash /home/*/.Trash /home/*/.thumbnails /home/*/.beagle /home/*/.aMule /home/*/gtk-gnutella-downloads" set +o noglob dup_main_menu -- 2.30.2 From d65fa0c058b6a2e91126e1634aafd130807f58bd Mon Sep 17 00:00:00 2001 From: intrigeri Date: Tue, 5 Jan 2010 13:09:38 +0100 Subject: [PATCH 14/16] Cherry-picked "fixes for mysql handler for mysqld inside a vserver" This commit (64edfccf7684d9c080e734b25fa9361f0190afec) was wrongly committed to the debian branch. Conflicts: handlers/mysql.in --- handlers/mysql.in | 119 ++++++++++++++++++++++++---------------------- 1 file changed, 63 insertions(+), 56 deletions(-) diff --git a/handlers/mysql.in b/handlers/mysql.in index 0aa3abb..3b7423f 100644 --- a/handlers/mysql.in +++ b/handlers/mysql.in @@ -88,29 +88,35 @@ defaultsfile="" if [ "$dbusername" != "" -a "$dbpassword" != "" ] then - if [ $usevserver = yes ] - then - vhome=`$VSERVER $vsname exec getent passwd "root" | @AWK@ -F: '{print $6}'` - home="$vroot$vhome" - else - home=`getent passwd "root" | @AWK@ -F: '{print $6}'` - fi + if [ $usevserver = yes ] + then + home=`$VSERVER $vsname exec getent passwd "root" | @AWK@ -F: '{print $6}'` + else + home=`getent passwd "root" | @AWK@ -F: '{print $6}'` + fi - [ -d $home ] || fatal "Can't find root's home directory ($home)." + [ -d $home ] || fatal "Can't find root's home directory ($home)." + + mycnf="$home/.my.cnf" - mycnf="$home/.my.cnf" - - if [ -f $mycnf ] - then - # rename temporarily - tmpcnf="$home/my.cnf.disable" - debug "mv $mycnf $tmpcnf" - mv $mycnf $tmpcnf - fi + if [ $usevserver = yes ] + then + workcnf="$vroot$mycnf" + else + workcnf="$mycnf" + fi - oldmask=`umask` - umask 077 - cat > $mycnf < $workcnf < Date: Tue, 5 Jan 2010 13:11:57 +0100 Subject: [PATCH 15/16] Fix indentation of previously cherry-picked patch --- handlers/mysql.in | 98 +++++++++++++++++++++++------------------------ 1 file changed, 49 insertions(+), 49 deletions(-) diff --git a/handlers/mysql.in b/handlers/mysql.in index 3b7423f..f3230ad 100644 --- a/handlers/mysql.in +++ b/handlers/mysql.in @@ -88,35 +88,35 @@ defaultsfile="" if [ "$dbusername" != "" -a "$dbpassword" != "" ] then - if [ $usevserver = yes ] - then - home=`$VSERVER $vsname exec getent passwd "root" | @AWK@ -F: '{print $6}'` - else - home=`getent passwd "root" | @AWK@ -F: '{print $6}'` - fi + if [ $usevserver = yes ] + then + home=`$VSERVER $vsname exec getent passwd "root" | @AWK@ -F: '{print $6}'` + else + home=`getent passwd "root" | @AWK@ -F: '{print $6}'` + fi - [ -d $home ] || fatal "Can't find root's home directory ($home)." + [ -d $home ] || fatal "Can't find root's home directory ($home)." - mycnf="$home/.my.cnf" + mycnf="$home/.my.cnf" - if [ $usevserver = yes ] - then + if [ $usevserver = yes ] + then workcnf="$vroot$mycnf" - else + else workcnf="$mycnf" - fi + fi - if [ -f $workcnf ] - then + if [ -f $workcnf ] + then # rename temporarily tmpcnf="$workcnf.disable" debug "mv $workcnf $tmpcnf" mv $workcnf $tmpcnf - fi + fi - oldmask=`umask` - umask 077 - cat > $workcnf < $workcnf < Date: Tue, 5 Jan 2010 06:44:36 +0100 Subject: [PATCH 16/16] Add duplicity output line by line instead of with a whole at one time. Should help fix #536360 --- handlers/dup.in | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/handlers/dup.in b/handlers/dup.in index 59aa90a..198eef7 100644 --- a/handlers/dup.in +++ b/handlers/dup.in @@ -263,18 +263,23 @@ fi ### Backup command debug "$precmd duplicity $execstr_command $execstr_options $execstr_source --exclude '**' / $execstr_serverpart" if [ ! $test ]; then + outputfile=`maketemp backupout` export PASSPHRASE=$password output=`nice -n $nicelevel \ su -c \ - "$precmd duplicity $execstr_command $execstr_options $execstr_source --exclude '**' / $execstr_serverpart 2>&1"` + "$precmd duplicity $execstr_command $execstr_options $execstr_source --exclude '**' / $execstr_serverpart >$outputfile 2>&1"` exit_code=$? + debug $output + cat $outputfile | (while read output ; do + debug $output + done + ) if [ $exit_code -eq 0 ]; then - debug $output info "Duplicity finished successfully." else - debug $output fatal "Duplicity failed." fi + rm $outputfile fi return 0 -- 2.30.2