summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lbup/targets.py29
1 files changed, 15 insertions, 14 deletions
diff --git a/lbup/targets.py b/lbup/targets.py
index 3473ed1..4127b47 100644
--- a/lbup/targets.py
+++ b/lbup/targets.py
@@ -5,6 +5,7 @@ import errno
import logging
import re
import secrets
+import shlex
import socket
import subprocess
@@ -172,6 +173,7 @@ class TargetSSH(Target):
return "%s{SSH:%s}" % (super().__str__(), str(self._remote))
def _paramiko_exec_cmd(self, client, cmd, decode = True):
+ cmd = shlex.join(map(str, cmd))
self._logger.debug('Client %s: executing command: %s' % (client, cmd))
res = client.exec_command(cmd)
@@ -197,7 +199,7 @@ class TargetSSH(Target):
return out
def _resolve_remote_path(self, ssh, path):
- path = self._paramiko_exec_cmd(ssh, 'realpath -e %s' % path).splitlines()
+ path = self._paramiko_exec_cmd(ssh, ['realpath', '-e', path]).splitlines()
if len(path) != 1:
raise BackupException('Expected exactly one path from realpath', path)
return AbsPath(path[0])
@@ -242,8 +244,8 @@ class TargetSSHLVM(TargetSSH):
major = devnum >> 8
minor = devnum & 255
res = self._paramiko_exec_cmd(ssh,
- 'lvs --select "kernel_major={major}&&kernel_minor={minor}" '
- '--noheadings -o lv_full_name'.format(major = major, minor = minor))
+ ['lvs', '--select', 'kernel_major=%d&&kernel_minor=%d' % (major, minor),
+ '--noheadings', '-o', 'lv_full_name'])
lv_name = res.strip()
# valid LV paths are volname/lvname, each non-empty alphanumeric+_
@@ -268,14 +270,14 @@ class TargetSSHLVM(TargetSSH):
snapshot_name = 'a' + secrets.token_urlsafe()
snapshot_fullname = '%s/%s' % (vg_name, snapshot_name)
self._paramiko_exec_cmd(ssh,
- 'lvcreate --permission r --snapshot -L {size} -n {name} {origin}'
- .format(size = self._snapshot_size, name = snapshot_name,
- origin = lv_fullname))
+ ['lvcreate', '--permission', 'r', '--snapshot', '-L', self._snapshot_size,
+ '-n', snapshot_name, lv_fullname])
try:
# get the path to the snapshot device node
res = self._paramiko_exec_cmd(ssh,
- 'lvs --select "lv_full_name=%s" --noheadings -o lv_path' % snapshot_fullname)
+ ['lvs', '--select', 'lv_full_name=%s' % snapshot_fullname,
+ '--noheadings', '-o', 'lv_path'])
lv_path = res.strip()
if not lv_path.startswith('/'):
raise BackupException('Got invalid snapshot LV path', lv_path)
@@ -284,7 +286,7 @@ class TargetSSHLVM(TargetSSH):
yield lv_path
finally:
- self._paramiko_exec_cmd(ssh, 'lvremove -f %s' % snapshot_fullname)
+ self._paramiko_exec_cmd(ssh, ['lvremove', '-f', snapshot_fullname])
self._logger.debug('Removed snapshot %s', snapshot_fullname)
@contextlib.contextmanager
@@ -295,13 +297,11 @@ class TargetSSHLVM(TargetSSH):
then unmounts and destroys it at exit.
"""
with self._snapshot_lv(ssh, devnum) as lv_path:
- self._paramiko_exec_cmd(ssh,
- 'mount -t{fstype} -oro {lv_path} {mount_path}'.format(
- fstype = fstype, lv_path = lv_path, mount_path = mount_path))
+ self._paramiko_exec_cmd(ssh, ['mount', '-t', fstype, '-oro', lv_path, mount_path])
try:
yield None
finally:
- self._paramiko_exec_cmd(ssh, 'umount %s' % mount_path)
+ self._paramiko_exec_cmd(ssh, ['umount', mount_path])
def save(self, dry_run = False):
@@ -322,11 +322,12 @@ class TargetSSHLVM(TargetSSH):
# same for each backup
# we use BUP_DIR/lbup_mount
snapshot_root = bupdir + 'lbup_mount'
- self._paramiko_exec_cmd(conn_tgt, 'mkdir -p -m 700 ' + str(snapshot_root))
+ self._paramiko_exec_cmd(conn_tgt,
+ ['mkdir', '-p', '-m', '700', str(snapshot_root)])
# read and parse the mountinfo table
mntinfo = MountInfo(
- self._paramiko_exec_cmd(conn_root, 'cat /proc/1/mountinfo', decode = False))
+ self._paramiko_exec_cmd(conn_root, ['cat', '/proc/1/mountinfo'], decode = False))
mounts = _mounts_for_dirs(mntinfo, dirs)