[libvirt] [PATCH sandbox 24/24] image: add 'list' command for viewing local templates

Daniel P. Berrange berrange at redhat.com
Fri Jul 15 13:08:16 UTC 2016


Introduce a command able to list locally stored image
templates:

  $ virt-sandbox-image list
  docker:library/ubuntu?tag=14.04.1
  docker:library/ubuntu?tag=14.04.2
  virt-builder:/fedora-23

or restrict to a single source type

  $ virt-sandbox-image list --source docker
  docker:library/ubuntu?tag=14.04.1
  docker:library/ubuntu?tag=14.04.2

Signed-off-by: Daniel P. Berrange <berrange at redhat.com>
---
 libvirt-sandbox/image/cli.py                 | 24 ++++++++++++++++++++++
 libvirt-sandbox/image/sources/base.py        | 10 ++++++++++
 libvirt-sandbox/image/sources/docker.py      | 22 ++++++++++++++++++++
 libvirt-sandbox/image/sources/virtbuilder.py | 18 +++++++++++++++++
 libvirt-sandbox/image/template.py            | 30 +++++++++++++++++++---------
 5 files changed, 95 insertions(+), 9 deletions(-)

diff --git a/libvirt-sandbox/image/cli.py b/libvirt-sandbox/image/cli.py
index b0d864f..66854e4 100644
--- a/libvirt-sandbox/image/cli.py
+++ b/libvirt-sandbox/image/cli.py
@@ -135,6 +135,18 @@ def run(args):
     os.unlink(diskfile)
     source.post_run(tmpl, template_dir, name)
 
+def list_cached(args):
+    tmpls = []
+    if args.source is not None:
+        tmpls.extend(template.Template.get_all(args.source,
+                                               "%s/%s" % (args.template_dir, args.source)))
+    else:
+        for source in ["docker", "virt-builder"]:
+            tmpls.extend(template.Template.get_all(source,
+                                                   "%s/%s" % (args.template_dir, source)))
+    for tmpl in tmpls:
+        print tmpl
+
 def requires_template(parser):
     parser.add_argument("template",
                         help=_("URI of the template"))
@@ -221,6 +233,17 @@ def gen_run_args(subparser):
 
     parser.set_defaults(func=run)
 
+def gen_list_args(subparser):
+    parser = gen_command_parser(subparser, "list",
+                                _("List locally cached images"))
+    requires_debug(parser)
+    requires_template_dir(parser)
+
+    parser.add_argument("-s","--source",
+                        help=_("Name of the template source"))
+
+    parser.set_defaults(func=list_cached)
+
 def main():
     parser = argparse.ArgumentParser(description="Sandbox Container Image Tool")
 
@@ -228,6 +251,7 @@ def main():
     gen_delete_args(subparser)
     gen_create_args(subparser)
     gen_run_args(subparser)
+    gen_list_args(subparser)
 
     args = parser.parse_args()
     if args.debug:
diff --git a/libvirt-sandbox/image/sources/base.py b/libvirt-sandbox/image/sources/base.py
index f70551d..e4e4e41 100644
--- a/libvirt-sandbox/image/sources/base.py
+++ b/libvirt-sandbox/image/sources/base.py
@@ -34,6 +34,16 @@ class Source():
     def __init__(self):
         pass
 
+    @abstractmethod
+    def list_templates(self, templatedir):
+        """
+        :param templatedir: local directory path in which to store the template
+
+        Get a list of all templates that are locally cached
+
+        :returns: a list of libvirt_sandbox.template.Template objects
+        """
+        pass
 
     @abstractmethod
     def has_template(self, template, templatedir):
diff --git a/libvirt-sandbox/image/sources/docker.py b/libvirt-sandbox/image/sources/docker.py
index 291a305..dd72db7 100644
--- a/libvirt-sandbox/image/sources/docker.py
+++ b/libvirt-sandbox/image/sources/docker.py
@@ -32,6 +32,7 @@ import urlparse
 import hashlib
 from abc import ABCMeta, abstractmethod
 import copy
+from libvirt_sandbox.image.template import Template
 
 from . import base
 
@@ -360,6 +361,27 @@ class DockerSource(base.Source):
         except Exception:
             return False
 
+    def list_templates(self, templatedir):
+        indexes = []
+        imagedirs = os.listdir(templatedir)
+        for imagetagid in imagedirs:
+            indexfile = templatedir + "/" + imagetagid + "/index.json"
+            if os.path.exists(indexfile):
+                with open(indexfile,"r") as f:
+                    index = json.load(f)
+                    indexes.append(index)
+
+        return [
+            Template(source="docker",
+                     protocol=None,
+                     hostname=None,
+                     port=None,
+                     username=None,
+                     password=None,
+                     path="/%s/%s" % (index.get("repo", "library"), index["name"]),
+                     params={
+                         "tag": index.get("tag", "latest"),
+                     }) for index in indexes]
 
     def has_template(self, template, templatedir):
         try:
diff --git a/libvirt-sandbox/image/sources/virtbuilder.py b/libvirt-sandbox/image/sources/virtbuilder.py
index 6e71b36..fefe0dd 100644
--- a/libvirt-sandbox/image/sources/virtbuilder.py
+++ b/libvirt-sandbox/image/sources/virtbuilder.py
@@ -24,6 +24,7 @@ import os.path
 import subprocess
 
 from . import base
+from libvirt_sandbox.image.template import Template
 
 
 class VirtBuilderSource(base.Source):
@@ -65,6 +66,23 @@ class VirtBuilderSource(base.Source):
             os.unlink(imagepath_original)
             os.unlink(tarfile)
 
+    def list_templates(self, templatedir):
+        files = []
+        imagefiles = os.listdir(templatedir)
+        for filename in imagefiles:
+            if not filename.endswith(".qcow2"):
+                continue
+            files.append(filename[0:-6])
+
+        return [
+            Template(source="virt-builder",
+                     protocol=None,
+                     hostname=None,
+                     port=None,
+                     username=None,
+                     password=None,
+                     path="/%s" % filename,
+                     params={}) for filename in files]
 
     def delete_template(self, template, templatedir):
         os.unlink("%s/%s.qcow2" % (templatedir, self._get_template_name(template)))
diff --git a/libvirt-sandbox/image/template.py b/libvirt-sandbox/image/template.py
index 751cd4b..79dc33d 100644
--- a/libvirt-sandbox/image/template.py
+++ b/libvirt-sandbox/image/template.py
@@ -58,22 +58,27 @@ class Template(object):
         if self.params is None:
             self.params = {}
 
-    def get_source_impl(self):
-        if self.source == "":
-            raise Exception("Missing scheme in image URI")
-
+    @classmethod
+    def _get_source_impl(klass, source):
         try:
             p = re.compile("\W")
-            sourcemod = "".join(p.split(self.source))
-            sourcename = "".join([i.capitalize() for i in p.split(self.source)])
+            sourcemod = "".join(p.split(source))
+            sourcename = "".join([i.capitalize() for i in p.split(source)])
 
             mod = importlib.import_module(
                 "libvirt_sandbox.image.sources." + sourcemod)
             classname = sourcename + "Source"
             classimpl = getattr(mod, classname)
             return classimpl()
-        except Exception:
-            raise Exception("Invalid source: '%s'" % self.source)
+        except Exception as e:
+            print e
+            raise Exception("Invalid source: '%s'" % source)
+
+    def get_source_impl(self):
+        if self.source == "":
+            raise Exception("Missing scheme in image URI")
+
+        return self._get_source_impl(self.source)
 
     def __repr__(self):
         if self.protocol is not None:
@@ -96,7 +101,8 @@ class Template(object):
             netloc = None
 
         query = "&".join([key + "=" + self.params[key] for key in self.params.keys()])
-        return urlparse.urlunparse((scheme, netloc, self.path, None, query, None))
+        ret = urlparse.urlunparse((scheme, netloc, self.path, None, query, None))
+        return ret
 
     @classmethod
     def from_uri(klass, uri):
@@ -119,3 +125,9 @@ class Template(object):
                      o.hostname, o.port,
                      o.username, o.password,
                      o.path, query)
+
+    @classmethod
+    def get_all(klass, source, templatedir):
+        impl = klass._get_source_impl(source)
+
+        return impl.list_templates(templatedir)
-- 
2.7.4




More information about the libvir-list mailing list