[virt-tools-list] [virt-bootstrap] [PATCH 6/9] sources: Add support for virt-builder
Radostin Stoyanov
rstoyanov1 at gmail.com
Fri Jul 28 09:21:44 UTC 2017
Create container root file system from VM image build with virt-builder
---
src/virtBootstrap/sources.py | 100 +++++++++++++++++++++++++++++++++++-
src/virtBootstrap/utils.py | 9 ++++
src/virtBootstrap/virt_bootstrap.py | 2 +-
3 files changed, 109 insertions(+), 2 deletions(-)
diff --git a/src/virtBootstrap/sources.py b/src/virtBootstrap/sources.py
index 673e68c..3f06f96 100644
--- a/src/virtBootstrap/sources.py
+++ b/src/virtBootstrap/sources.py
@@ -25,7 +25,7 @@ import shutil
import getpass
import os
import logging
-from subprocess import CalledProcessError, PIPE, Popen
+from subprocess import CalledProcessError, PIPE, Popen, check_call
from virtBootstrap import utils
@@ -328,3 +328,101 @@ class DockerSource(object):
# Clean up
if self.no_cache and self.images_dir != utils.DEFAULT_IMG_DIR:
shutil.rmtree(self.images_dir)
+
+
+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.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/^/#/']
+ 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 aadc393..499cc0b 100644
--- a/src/virtBootstrap/utils.py
+++ b/src/virtBootstrap/utils.py
@@ -429,3 +429,12 @@ def write_progress(prog):
# Write message to console
sys.stdout.write(msg)
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)
diff --git a/src/virtBootstrap/virt_bootstrap.py b/src/virtBootstrap/virt_bootstrap.py
index 029cee2..b8c3e29 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.9.4
More information about the virt-tools-list
mailing list