[libvirt] [PATCH sandbox 24/24] image: add 'list' command for viewing local templates
Cedric Bosdonnat
cbosdonnat at suse.com
Mon Jul 18 09:26:53 UTC 2016
On Fri, 2016-07-15 at 14:08 +0100, Daniel P. Berrange wrote:
> 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)
The whole series looks good to me. ACK.
--
Cedric
More information about the libvir-list
mailing list