[virt-tools-list] [virt-bootstrap] [PATCH 4/9] Add flag --use-sandbox
Radostin Stoyanov
rstoyanov1 at gmail.com
Fri Jul 28 09:21:42 UTC 2017
Add flag --use-sandbox which indicates wheter the extraction of
container root file system to be performed within VM/Container using
virt-sandbox or not.
If virt-sandbox is not installed this flag is ignored.
---
src/virtBootstrap/sources.py | 9 +++++++--
src/virtBootstrap/utils.py | 40 ++++++++++++++++++++++++++++---------
src/virtBootstrap/virt_bootstrap.py | 12 ++++++++---
3 files changed, 47 insertions(+), 14 deletions(-)
diff --git a/src/virtBootstrap/sources.py b/src/virtBootstrap/sources.py
index f4bae72..673e68c 100644
--- a/src/virtBootstrap/sources.py
+++ b/src/virtBootstrap/sources.py
@@ -45,10 +45,12 @@ class FileSource(object):
@param uri: Path to tar archive file.
@param fmt: Format used to store image [dir, qcow2]
+ @param use_sandbox: Run the untar within VM/container
@param progress: Instance of the progress module
"""
self.path = kwargs['uri'].path
self.output_format = kwargs.get('fmt', utils.DEFAULT_OUTPUT_FORMAT)
+ self.use_sandbox = kwargs.get('use_sandbox', False)
self.progress = kwargs['progress'].update_progress
def unpack(self, dest):
@@ -64,7 +66,7 @@ class FileSource(object):
if self.output_format == 'dir':
self.progress("Extracting files into destination directory",
value=0, logger=logger)
- utils.safe_untar(self.path, dest)
+ utils.untar(self.path, dest, self.use_sandbox)
elif self.output_format == 'qcow2':
# Remove the old path
@@ -98,6 +100,7 @@ class DockerSource(object):
@param password: Password to access source registry
@param fmt: Format used to store image [dir, qcow2]
@param not_secure: Do not require HTTPS and certificate verification
+ @param use_sandbox: Run the untar within VM/container
@param no_cache: Whether to store downloaded images or not
@param progress: Instance of the progress module
"""
@@ -108,6 +111,7 @@ class DockerSource(object):
self.output_format = kwargs.get('fmt', utils.DEFAULT_OUTPUT_FORMAT)
self.insecure = kwargs.get('not_secure', False)
self.no_cache = kwargs.get('no_cache', False)
+ self.use_sandbox = kwargs.get('use_sandbox', False)
self.progress = kwargs['progress'].update_progress
self.images_dir = utils.get_image_dir(self.no_cache)
self.manifest = None
@@ -303,7 +307,8 @@ class DockerSource(object):
if self.output_format == 'dir':
self.progress("Extracting container layers", value=50,
logger=logger)
- utils.untar_layers(self.layers, dest, self.progress)
+ utils.untar_layers(self.layers, dest, self.progress,
+ self.use_sandbox)
elif self.output_format == 'qcow2':
self.progress("Extracting container layers into qcow2 images",
value=50, logger=logger)
diff --git a/src/virtBootstrap/utils.py b/src/virtBootstrap/utils.py
index dbe4677..aadc393 100644
--- a/src/virtBootstrap/utils.py
+++ b/src/virtBootstrap/utils.py
@@ -33,6 +33,7 @@ import logging
import re
from subprocess import CalledProcessError, PIPE, Popen
+import distutils.spawn
import passlib.hosts
# pylint: disable=invalid-name
@@ -92,18 +93,30 @@ def execute(cmd):
raise CalledProcessError(proc.returncode, cmd_str)
-def safe_untar(src, dest):
+def untar(src, dest, use_sandbox=False):
"""
- Extract tarball within LXC container for safety.
+ Extract tarball to destination path.
+
+ @param use_sandbox: If True run tar command in VM or LXC container
+ using virt-sandbox.
"""
- virt_sandbox = ['virt-sandbox',
- '-c', LIBVIRT_CONN,
- '-m', 'host-bind:/mnt=' + dest] # Bind destination folder
# Compression type is auto detected from tar
# Exclude files under /dev to avoid "Cannot mknod: Operation not permitted"
- params = ['--', '/bin/tar', 'xf', src, '-C', '/mnt', '--exclude', 'dev/*']
- execute(virt_sandbox + params)
+ cmd = ['/bin/tar',
+ 'xf', src,
+ '-C', '/mnt' if use_sandbox else dest,
+ '--exclude', 'dev/*']
+
+ if use_sandbox:
+ cmd = ['virt-sandbox',
+ # Set connection
+ '-c', LIBVIRT_CONN,
+ # Bind destination folder
+ '-m', 'host-bind:/mnt=' + dest,
+ '--'] + cmd
+
+ execute(cmd)
def bytes_to_size(number):
@@ -150,17 +163,26 @@ def log_layer_extract(layer, current, total, progress):
logger.debug('Untar layer: (%s:%s) %s', sum_type, sum_value, layer_file)
-def untar_layers(layers_list, dest_dir, progress):
+def is_installed(program):
+ """
+ Return True/False is executable is found the in the PATH env variable
+ """
+ return bool(distutils.spawn.find_executable(program))
+
+
+def untar_layers(layers_list, dest_dir, progress, use_sandbox=False):
"""
Untar each of layers from container image.
"""
nlayers = len(layers_list)
+ use_sandbox = use_sandbox and is_installed('virt-sandbox')
+
for index, layer in enumerate(layers_list):
log_layer_extract(layer, index + 1, nlayers, progress)
layer_file = layer[2]
# Extract layer tarball into destination directory
- safe_untar(layer_file, dest_dir)
+ untar(layer_file, dest_dir, use_sandbox)
# Update progress value
progress(value=(float(index + 1) / nlayers * 50) + 50)
diff --git a/src/virtBootstrap/virt_bootstrap.py b/src/virtBootstrap/virt_bootstrap.py
index ddc5456..029cee2 100755
--- a/src/virtBootstrap/virt_bootstrap.py
+++ b/src/virtBootstrap/virt_bootstrap.py
@@ -173,7 +173,8 @@ def bootstrap(uri, dest,
gid_map=None,
not_secure=False,
no_cache=False,
- progress_cb=None):
+ progress_cb=None,
+ use_sandbox=None):
"""
Get source object and call unpack method
"""
@@ -198,7 +199,8 @@ def bootstrap(uri, dest,
password=password,
not_secure=not_secure,
no_cache=no_cache,
- progress=prog).unpack(dest)
+ progress=prog,
+ use_sandbox=use_sandbox).unpack(dest)
if root_password is not None:
logger.info("Setting password of the root account")
@@ -278,6 +280,9 @@ def main():
parser.add_argument("--status-only", action="store_const",
const=utils.write_progress,
help=_("Show only progress information"))
+ parser.add_argument("--use-sandbox", action="store_true",
+ help=_("Run the untar command within VM/container "
+ "for extra security (requires virt-sandbox)"))
try:
args = parser.parse_args()
@@ -304,7 +309,8 @@ def main():
gid_map=gid_map,
not_secure=args.not_secure,
no_cache=args.no_cache,
- progress_cb=args.status_only)
+ progress_cb=args.status_only,
+ use_sandbox=args.use_sandbox)
sys.exit(0)
except KeyboardInterrupt:
--
2.9.4
More information about the virt-tools-list
mailing list