When using this flag with format='dir' the overhead when extracting the root file system of container image will be reduce by running `tar` on the host instead of in sandbox. --- src/virtBootstrap/sources/docker_source.py | 9 ++++++++- src/virtBootstrap/sources/file_source.py | 4 +++- src/virtBootstrap/utils.py | 29 ++++++++++++++++++----------- src/virtBootstrap/virt_bootstrap.py | 6 ++++++ 4 files changed, 35 insertions(+), 13 deletions(-) diff --git a/src/virtBootstrap/sources/docker_source.py b/src/virtBootstrap/sources/docker_source.py index d990b89..d979a14 100644 --- a/src/virtBootstrap/sources/docker_source.py +++ b/src/virtBootstrap/sources/docker_source.py @@ -51,6 +51,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 faster: Reduce the overhead when untar images to rootfs @param no_cache: Whether to store downloaded images or not @param progress: Instance of the progress module """ @@ -63,6 +64,7 @@ class DockerSource(object): self.root_password = kwargs.get('root_password', None) self.output_format = kwargs.get('fmt', utils.DEFAULT_OUTPUT_FORMAT) self.insecure = kwargs.get('not_secure', False) + self.faster = kwargs.get('faster', False) self.no_cache = kwargs.get('no_cache', False) self.progress = kwargs['progress'].update_progress self.images_dir = utils.get_image_dir(self.no_cache) @@ -261,7 +263,12 @@ 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.faster + ) elif self.output_format == 'qcow2': self.progress("Extracting container layers into qcow2 images", value=50, logger=logger) diff --git a/src/virtBootstrap/sources/file_source.py b/src/virtBootstrap/sources/file_source.py index 2a7617c..f80bb6b 100644 --- a/src/virtBootstrap/sources/file_source.py +++ b/src/virtBootstrap/sources/file_source.py @@ -40,6 +40,7 @@ class FileSource(object): @param uri: Path to tar archive file. @param fmt: Format used to store image [dir, qcow2] + @param faster: Reduce the overhead when untar images to rootfs @param progress: Instance of the progress module """ self.path = kwargs['uri'].path @@ -47,6 +48,7 @@ class FileSource(object): self.uid_map = kwargs.get('uid_map', None) self.gid_map = kwargs.get('gid_map', None) self.root_password = kwargs.get('root_password', None) + self.faster = kwargs.get('faster', False) self.progress = kwargs['progress'].update_progress def unpack(self, dest): @@ -62,7 +64,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.faster) elif self.output_format == 'qcow2': self.progress("Extracting files into qcow2 image", value=0, logger=logger) diff --git a/src/virtBootstrap/utils.py b/src/virtBootstrap/utils.py index 578c776..3b7758f 100644 --- a/src/virtBootstrap/utils.py +++ b/src/virtBootstrap/utils.py @@ -289,18 +289,25 @@ def execute(cmd): raise CalledProcessError(proc.returncode, cmd_str) -def safe_untar(src, dest): +def untar(src, dest, faster=False): """ - Extract tarball within LXC container for safety. + Extract tarball to destination path. + + @param faster: If True reduce the overhead by running tar on the host """ - virt_sandbox = ['virt-sandbox', - '-c', LIBVIRT_CONN, - '-m', 'host-bind:/mnt=' + dest] # Bind destination folder + cmd = ['/bin/tar', + 'xf', src, + '-C', dest if faster else '/mnt', + '--exclude', 'dev/*'] - # 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) + if not faster: + cmd = ['virt-sandbox', + # Set connection + '-c', LIBVIRT_CONN, + # Bind destination folder + '-m', 'host-bind:/mnt=' + dest, + '--'] + cmd + execute(cmd) def bytes_to_size(number): @@ -355,7 +362,7 @@ def get_mime_type(path): .stdout.read().decode('utf-8').split()[1]) -def untar_layers(layers_list, dest_dir, progress): +def untar_layers(layers_list, dest_dir, progress, faster=False): """ Untar each of layers from container image. """ @@ -365,7 +372,7 @@ def untar_layers(layers_list, dest_dir, progress): layer_file = layer[2] # Extract layer tarball into destination directory - safe_untar(layer_file, dest_dir) + untar(layer_file, dest_dir, faster) # 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 cbd9f0c..e465fb2 100755 --- a/src/virtBootstrap/virt_bootstrap.py +++ b/src/virtBootstrap/virt_bootstrap.py @@ -100,6 +100,7 @@ def bootstrap(uri, dest, uid_map=None, gid_map=None, not_secure=False, + faster=None, no_cache=False, progress_cb=None): """ @@ -127,6 +128,7 @@ def bootstrap(uri, dest, uid_map=uid_map, gid_map=gid_map, not_secure=not_secure, + faster=faster, no_cache=no_cache, root_password=root_password, progress=prog).unpack(dest) @@ -210,6 +212,9 @@ def main(): parser.add_argument("--status-only", action="store_const", const=utils.write_progress, help=_("Show only progress information")) + parser.add_argument("--faster", action="store_true", + help=_("Reduce the overhead when extracting layers " + "(use this option only for trusted images)")) try: args = parser.parse_args() @@ -235,6 +240,7 @@ def main(): uid_map=uid_map, gid_map=gid_map, not_secure=args.not_secure, + faster=args.faster, no_cache=args.no_cache, progress_cb=args.status_only) -- 2.13.3 _______________________________________________ virt-tools-list mailing list virt-tools-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/virt-tools-list