[virt-tools-list] [virt-bootstrap] [PATCH 4/9] Add flag --use-sandbox
Cedric Bosdonnat
cbosdonnat at suse.com
Mon Jul 31 07:41:44 UTC 2017
On Fri, 2017-07-28 at 10:21 +0100, Radostin Stoyanov wrote:
> 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.
What is the use case for this? The interest to get rid of virt-sandbox
dependency would be to reduce the number of packages installed when
installing virt-bootstrap... If we have to keep it for security reasons
then better enforce it, unless I'm overseeing something
--
Cedric
> ---
> 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:
More information about the virt-tools-list
mailing list