--- a/bin/pvl.backup-rsync Sat Feb 16 21:41:42 2013 +0200
+++ b/bin/pvl.backup-rsync Sat Feb 16 21:42:10 2013 +0200
@@ -50,23 +50,26 @@
#
parser.add_option('-c', '--command', metavar='CMD', default=os.environ.get('SSH_ORIGINAL_COMMAND'),
- help="rsync command to execute")
+ help="Rsync command to execute")
parser.add_option('-C', '--given-command', action='store_true', default=False,
- help="use given command in `rsync -e '%prog -C --' ...` format")
+ help="Use given command in `rsync -e '%prog -C --' ...` format")
parser.add_option('-n', '--noop', action='store_true', default=False,
help="Parse command, but do not execute")
parser.add_option('-R', '--readonly', action='store_true', default=False,
- help="restrict to read/source mode")
+ help="Restrict to read/source mode")
parser.add_option('-P', '--restrict-path', metavar='PATH', action='append',
- help="restrict to given path prefix")
+ help="Restrict to given path prefix")
parser.add_option('--allow-remote', action='store_true', default=False,
help="Allow remote rsync sources")
+ parser.add_option('--sudo', action='store_true',
+ help="Execute rsync under sudo")
+
# lvm options
parser.add_option('-L', '--snapshot-size', metavar='SIZE', default=lvm.LVM_SNAPSHOT_SIZE,
help="create snapshot with given LV size (used to store writes during backup)")
@@ -130,6 +133,7 @@
restrict_paths = options.restrict_path,
allow_remote = options.allow_remote,
lvm_opts = dict(
+ sudo = options.sudo,
size = options.snapshot_size,
wait = options.snapshot_wait,
retry = options.snapshot_retry,
@@ -148,7 +152,9 @@
# execute
try :
# run rsync within the source (may perform additional stuff like snapshot...)
- source.execute(rsync_options, srcdst)
+ source.execute(rsync_options, srcdst,
+ sudo = options.sudo,
+ )
except InvokeError, e:
log.error("%s failed: %d", e.cmd, e.exit)
--- a/pvl/backup/rsync.py Sat Feb 16 21:41:42 2013 +0200
+++ b/pvl/backup/rsync.py Sat Feb 16 21:42:10 2013 +0200
@@ -14,7 +14,6 @@
log = logging.getLogger('pvl.backup.rsync')
-# Path to rsync binary
RSYNC = '/usr/bin/rsync'
def rsync (source, dest, **opts) :
@@ -52,13 +51,15 @@
rsync server-mode execution.
"""
- def _execute (self, options, srcdst, path) :
+ def _execute (self, options, srcdst, path, sudo=False) :
"""
Underlying rsync just reads from filesystem.
options - list of rsync options
srcdst - the (source, dest) pair with None placeholder, as returned by parse_command
path - the real path to replace None with
+
+ sudo - execute rsync using sudo
"""
# one of this will be None
@@ -69,10 +70,10 @@
dst = dst or path
log.info("rsync %s %s %s", ' '.join(options), src, dst)
-
+
try :
- # invoke directly, no option-handling, nor stdin/out redirection
- invoke.invoke(RSYNC, options + [ src, dst ], data=False)
+ # invoke directly; no option-handling, nor stdin/out redirection
+ invoke.invoke(RSYNC, options + [ src, dst ], data=False, sudo=sudo)
except invoke.InvokeError as ex :
raise RsyncError(ex)
@@ -87,13 +88,13 @@
self.path = path
- def execute (self, options, srcdst) :
+ def execute (self, options, srcdst, **opts) :
"""
options - list of rsync options
srcdst - the (source, dest) pair with None placeholder, as returned by parse_command
"""
- return self._execute(options, srcdst, self.path)
+ return self._execute(options, srcdst, self.path, **opts)
def __str__ (self) :
return self.path
@@ -114,13 +115,13 @@
# glue
self.path = host + ':' + path
- def execute (self, options, srcdst) :
+ def execute (self, options, srcdst, **opts) :
"""
options - list of rsync options
srcdst - the (source, dest) pair with None placeholder, as returned by parse_command
"""
- return self._execute(options, srcdst, self.path)
+ return self._execute(options, srcdst, self.path, **opts)
def __str__ (self) :
return self.path
@@ -130,18 +131,21 @@
Backup LVM LV by snapshotting + mounting it.
"""
- def __init__ (self, volume, **opts) :
+ def __init__ (self, vg, lv, sudo=None, **opts) :
"""
- volume - the LVMVolume to snapshot
**opts - options for LVM.snapshot
"""
RSyncServer.__init__(self)
+
+ # lvm
+ self.lvm = LVM(vg, sudo=sudo)
+ self.volume = self.lvm.volume(lv)
- self.volume = volume
+ self.sudo = sudo
self.snapshot_opts = opts
- def execute (self, options, srcdst) :
+ def execute (self, options, srcdst, sudo=False, **opts) :
"""
Snapshot, mount, execute
@@ -161,12 +165,12 @@
# mount
log.info("Mounting snapshot: %s", snapshot)
- with mount(snapshot.dev_path, name_hint=('lvm_' + snapshot.name + '_'), readonly=True) as mountpoint:
+ with mount(snapshot.dev_path, name_hint=('lvm_' + snapshot.name + '_'), readonly=True, sudo=sudo) as mountpoint:
# rsync!
log.info("Running rsync: %s", mountpoint)
# with trailing slash
- return self._execute(options, srcdst, mountpoint.path + '/')
+ return self._execute(options, srcdst, mountpoint.path + '/', sudo=sudo, **opts)
# cleanup
# cleanup
@@ -322,10 +326,7 @@
log.debug("LVM: %s/%s", vg, lv)
# open
- lvm = LVM(vg)
- volume = lvm.volume(lv)
-
- return RSyncLVMServer(volume, **lvm_opts)
+ return RSyncLVMServer(vg, lv, **lvm_opts)
elif ':' in path and allow_remote :
host, path = path.split(':', 1)