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@xxxxxxxxxx> --- 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list