[libvirt] [PATCH sandbox v5 07/20] Image: Refactor create function

Daniel P. Berrange berrange at redhat.com
Tue Sep 8 16:29:38 UTC 2015


From: Eren Yagdiran <erenyagdiran at gmail.com>

Move the docker-related code to the DockerSource and use
the Source mechanism

Signed-off-by: Daniel P. Berrange <berrange at redhat.com>
---
 libvirt-sandbox/image/cli.py                  | 76 +++++-----------------
 libvirt-sandbox/image/sources/DockerSource.py | 90 +++++++++++++++++++++++++++
 libvirt-sandbox/image/sources/Source.py       | 15 +++++
 3 files changed, 122 insertions(+), 59 deletions(-)

diff --git a/libvirt-sandbox/image/cli.py b/libvirt-sandbox/image/cli.py
index 7af617e..f3c0ab7 100755
--- a/libvirt-sandbox/image/cli.py
+++ b/libvirt-sandbox/image/cli.py
@@ -118,59 +118,6 @@ def delete_template(name, destdir):
                 parent = None
         imagetagid = parent
 
-
-def get_image_list(name, destdir):
-    imageparent = {}
-    imagenames = {}
-    imagedirs = os.listdir(destdir)
-    for imagetagid in imagedirs:
-        indexfile = destdir + "/" + imagetagid + "/index.json"
-        if os.path.exists(indexfile):
-            with open(indexfile, "r") as f:
-                index = json.load(f)
-            imagenames[index["name"]] = imagetagid
-        jsonfile = destdir + "/" + imagetagid + "/template.json"
-        if os.path.exists(jsonfile):
-            with open(jsonfile, "r") as f:
-                template = json.load(f)
-
-            parent = template.get("parent", None)
-            if parent:
-                imageparent[imagetagid] = parent
-
-    if not name in imagenames:
-        raise ValueError(["Image %s does not exist locally" % name])
-
-    imagetagid = imagenames[name]
-    imagelist = []
-    while imagetagid != None:
-        imagelist.append(imagetagid)
-        parent = imageparent.get(imagetagid, None)
-        imagetagid = parent
-
-    return imagelist
-
-def create_template(name, imagepath, format, destdir):
-    if not format in ["qcow2"]:
-        raise ValueError(["Unsupported image format %s" % format])
-
-    imagelist = get_image_list(name, destdir)
-    imagelist.reverse()
-
-    parentImage = None
-    for imagetagid in imagelist:
-        templateImage = destdir + "/" + imagetagid + "/template." + format
-        cmd = ["qemu-img", "create", "-f", "qcow2"]
-        if parentImage is not None:
-            cmd.append("-o")
-            cmd.append("backing_fmt=qcow2,backing_file=%s" % parentImage)
-        cmd.append(templateImage)
-        if parentImage is None:
-            cmd.append("10G")
-        debug("Run %s\n" % " ".join(cmd))
-        subprocess.call(cmd)
-        parentImage = templateImage
-
 def download(args):
     try:
         dynamic_source_loader(args.source).download_template(templatename=args.template,
@@ -188,8 +135,13 @@ def delete(args):
     delete_template(args.template, default_template_dir)
 
 def create(args):
-    info("Creating %s from %s in format %s\n" % (args.imagepath, args.template, args.format))
-    create_template(args.template, args.imagepath, args.format, default_template_dir)
+    try:
+        dynamic_source_loader(args.source).create_template(templatename=args.template,
+                                                           templatedir=args.template_dir,
+                                                           connect=args.connect,
+                                                           format=args.format)
+    except Exception,e:
+        print "Create Error %s" % str(e)
 
 def requires_template(parser):
     parser.add_argument("template",
@@ -200,6 +152,10 @@ def requires_source(parser):
                         default="docker",
                         help=_("name of the template"))
 
+def requires_connect(parser):
+    parser.add_argument("-c","--connect",
+                        help=_("Connect string for libvirt"))
+
 def requires_auth_conn(parser):
     parser.add_argument("-r","--registry",
                         help=_("Url of the custom registry"))
@@ -233,10 +189,12 @@ def gen_create_args(subparser):
     parser = subparser.add_parser("create",
                                    help=_("Create image from template data"))
     requires_template(parser)
-    parser.add_argument("imagepath",
-                        help=_("path for image"))
-    parser.add_argument("format",
-                        help=_("format"))
+    requires_source(parser)
+    requires_connect(parser)
+    requires_template_dir(parser)
+    parser.add_argument("-f","--format",
+                        default="qcow2",
+                        help=_("format format for image"))
     parser.set_defaults(func=create)
 
 def main():
diff --git a/libvirt-sandbox/image/sources/DockerSource.py b/libvirt-sandbox/image/sources/DockerSource.py
index 37b40dc..c1c8a7d 100644
--- a/libvirt-sandbox/image/sources/DockerSource.py
+++ b/libvirt-sandbox/image/sources/DockerSource.py
@@ -205,5 +205,95 @@ class DockerSource(Source):
             debug("FAIL %s\n" % str(e))
             raise
 
+    def create_template(self, templatename, templatedir, connect=None, format=None):
+        if format is None:
+            format = self.default_disk_format
+        self._check_disk_format(format)
+        imagelist = self._get_image_list(templatename,templatedir)
+        imagelist.reverse()
+
+        parentImage = None
+        for imagetagid in imagelist:
+            templateImage = templatedir + "/" + imagetagid + "/template." + format
+            cmd = ["qemu-img","create","-f","qcow2"]
+            if parentImage is not None:
+                cmd.append("-o")
+                cmd.append("backing_fmt=qcow2,backing_file=%s" % parentImage)
+            cmd.append(templateImage)
+            if parentImage is None:
+                cmd.append("10G")
+            subprocess.call(cmd)
+
+            if parentImage is None:
+                self._format_disk(templateImage,format,connect)
+
+            self._extract_tarballs(templatedir + "/" + imagetagid + "/template.",format,connect)
+            parentImage = templateImage
+
+
+    def _check_disk_format(self,format):
+        supportedFormats = ['qcow2']
+        if not format in supportedFormats:
+            raise ValueError(["Unsupported image format %s" % format])
+
+    def _get_image_list(self,templatename,destdir):
+        imageparent = {}
+        imagenames = {}
+        imagedirs = os.listdir(destdir)
+        for imagetagid in imagedirs:
+            indexfile = destdir + "/" + imagetagid + "/index.json"
+            if os.path.exists(indexfile):
+                with open(indexfile,"r") as f:
+                    index = json.load(f)
+                imagenames[index["name"]] = imagetagid
+            jsonfile = destdir + "/" + imagetagid + "/template.json"
+            if os.path.exists(jsonfile):
+                with open(jsonfile,"r") as f:
+                    template = json.load(f)
+                parent = template.get("parent",None)
+                if parent:
+                    imageparent[imagetagid] = parent
+        if not templatename in imagenames:
+            raise ValueError(["Image %s does not exist locally" %templatename])
+        imagetagid = imagenames[templatename]
+        imagelist = []
+        while imagetagid != None:
+            imagelist.append(imagetagid)
+            parent = imageparent.get(imagetagid,None)
+            imagetagid = parent
+        return imagelist
+
+    def _format_disk(self,disk,format,connect):
+        cmd = ['virt-sandbox']
+        if connect is not None:
+            cmd.append("-c")
+            cmd.append(connect)
+        cmd.append("-p")
+        params = ['--disk=file:disk_image=%s,format=%s' %(disk,format),
+                  '/sbin/mkfs.ext3',
+                  '/dev/disk/by-tag/disk_image']
+        cmd = cmd + params
+        subprocess.call(cmd)
+
+    def _extract_tarballs(self,directory,format,connect):
+        tempdir = "/mnt"
+        tarfile = directory + "tar.gz"
+        diskfile = directory + "qcow2"
+        cmd = ['virt-sandbox']
+        if connect is not None:
+            cmd.append("-c")
+            cmd.append(connect)
+        cmd.append("-p")
+        params = ['-m',
+                  'host-image:/mnt=%s,format=%s' %(diskfile,format),
+                  '--',
+                  '/bin/tar',
+                  'zxf',
+                  '%s' %tarfile,
+                  '-C',
+                  '/mnt']
+        cmd = cmd + params
+        subprocess.call(cmd)
+
 def debug(msg):
     sys.stderr.write(msg)
diff --git a/libvirt-sandbox/image/sources/Source.py b/libvirt-sandbox/image/sources/Source.py
index 81f5176..436eef6 100644
--- a/libvirt-sandbox/image/sources/Source.py
+++ b/libvirt-sandbox/image/sources/Source.py
@@ -46,3 +46,18 @@ class Source():
         filesystem
         """
         pass
+
+    @abstractmethod
+    def create_template(self, templatename, templatedir,
+                        connect=None, format=None):
+        """
+        :param templatename: name of the template image to create
+        :param templatedir: local directory path in which to store the template
+        :param connect: libvirt connection URI
+        :param format: disk image format
+
+        Create a set of local disk images populated with the content
+        of a template. The images creation process will be isolated
+        inside a sandbox using the requested libvirt connection URI.
+        """
+        pass
-- 
2.4.3




More information about the libvir-list mailing list