Add implementation for virt-builder source. The aim is to create a container root file system from VM image build with virt-builder. --- src/virtBootstrap/sources/__init__.py | 1 + src/virtBootstrap/sources/virt_builder_source.py | 134 +++++++++++++++++++++++ src/virtBootstrap/utils.py | 9 ++ src/virtBootstrap/virt_bootstrap.py | 2 +- 4 files changed, 145 insertions(+), 1 deletion(-) create mode 100644 src/virtBootstrap/sources/virt_builder_source.py diff --git a/src/virtBootstrap/sources/__init__.py b/src/virtBootstrap/sources/__init__.py index e891e9b..be6b25c 100644 --- a/src/virtBootstrap/sources/__init__.py +++ b/src/virtBootstrap/sources/__init__.py @@ -24,3 +24,4 @@ sources - Class definitions which process container image or from virtBootstrap.sources.file_source import FileSource from virtBootstrap.sources.docker_source import DockerSource +from virtBootstrap.sources.virt_builder_source import VirtBuilderSource diff --git a/src/virtBootstrap/sources/virt_builder_source.py b/src/virtBootstrap/sources/virt_builder_source.py new file mode 100644 index 0000000..f55668e --- /dev/null +++ b/src/virtBootstrap/sources/virt_builder_source.py @@ -0,0 +1,134 @@ +# Authors: Radostin Stoyanov <rstoyanov1@xxxxxxxxx> +# +# Copyright (C) 2017 Radostin Stoyanov +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +""" +VirtBuilderSource aim is to extract the root file system from VM image +build with virt-builder from template. +""" + +import os +import logging +import subprocess +import shutil + +from virtBootstrap import utils + + +# pylint: disable=invalid-name +# Create logger +logger = logging.getLogger(__name__) + + +class VirtBuilderSource(object): + """ + Extract root file system from image build with virt-builder. + """ + def __init__(self, **kwargs): + """ + Create container rootfs by building VM from virt-builder template + and extract the rootfs. + + @param uri: Template name + @param fmt: Format used to store the output [dir, qcow2] + @param progress: Instance of the progress module + """ + # Parsed URIs: + # - "virt-builder:///<template>" + # - "virt-builder://<template>" + # - "virt-builder:/<template>" + self.template = kwargs['uri'].netloc or kwargs['uri'].path[1:] + self.output_format = kwargs.get('fmt', utils.DEFAULT_OUTPUT_FORMAT) + self.root_password = kwargs.get('root_password', None) + self.progress = kwargs['progress'].update_progress + + def build_image(self, output_file): + """ + Build VM from virt-builder template + """ + cmd = ['virt-builder', self.template, + '-o', output_file, + '--no-network', + '--delete', '/dev/*', + '--delete', '/boot/*', + # Comment out every line in fstab + '--edit', '/etc/fstab:s/^/#/'] + if self.root_password is not None: + cmd += ['--root-password', "password:%s" % self.root_password] + subprocess.check_call(cmd) + + def unpack(self, dest): + """ + Build image and extract root file system + + @param dest: Directory path where output files will be stored. + """ + + tmp_dir = utils.get_image_dir(no_cache=True) + tmp_image_file = os.path.join(tmp_dir, self.template + '.img') + + try: + if self.output_format == 'dir': + + self.progress("Building image", value=0, logger=logger) + self.build_image(tmp_image_file) + + self.progress("Extracting file system", + value=50, logger=logger) + utils.execute(['virt-copy-out', + '-a', tmp_image_file, '/', dest]) + + self.progress("Extraction completed successfully!", + value=100, logger=logger) + logger.info("Files are stored in: %s", dest) + + elif self.output_format == 'qcow2': + # Use templete name as name for the output image + image_file = os.path.join(dest, self.template + '.qcow2') + utils.show_error_if_file_exits(image_file) + + # Create temporary directory to extract file system + tmp_tar_file = os.path.join(tmp_dir, 'filesystem.tar') + + self.progress("Building image", value=0, logger=logger) + self.build_image(tmp_image_file) + + self.progress("Extracting file system", value=33, + logger=logger) + utils.execute(['virt-tar-out', + '-a', tmp_image_file, '/', tmp_tar_file]) + + self.progress("Creating qcow2 image with single partition", + value=66, logger=logger) + utils.execute(['virt-make-fs', + '--type=ext3', + '--format=qcow2', + '--size=+200M', + tmp_tar_file, image_file]) + + self.progress("Extraction completed successfully!", value=100, + logger=logger) + logger.info("Image is stored in: %s", image_file) + + else: + raise Exception("Unknown format:" + self.output_format) + + except Exception: + raise + + finally: + # Clean up + shutil.rmtree(tmp_dir) diff --git a/src/virtBootstrap/utils.py b/src/virtBootstrap/utils.py index 3b7758f..3f8c606 100644 --- a/src/virtBootstrap/utils.py +++ b/src/virtBootstrap/utils.py @@ -538,6 +538,15 @@ def write_progress(prog): sys.stdout.flush() +def show_error_if_file_exits(path): + """ + Show error message if path exist and exit + """ + if os.path.exists(path): + logger.error("File already exist '%s'", path) + sys.exit(1) + + # The implementation for remapping ownership of all files inside a # container's rootfs is inspired by the tool uidmapshift: # diff --git a/src/virtBootstrap/virt_bootstrap.py b/src/virtBootstrap/virt_bootstrap.py index e465fb2..8c19f29 100755 --- a/src/virtBootstrap/virt_bootstrap.py +++ b/src/virtBootstrap/virt_bootstrap.py @@ -62,7 +62,7 @@ def get_source(source_type): Get object which match the source type """ try: - class_name = "%sSource" % source_type.capitalize() + class_name = "%sSource" % source_type.title().replace('-', '') clazz = getattr(sources, class_name) return clazz except Exception: -- 2.13.3 _______________________________________________ virt-tools-list mailing list virt-tools-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/virt-tools-list