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

Cedric Bosdonnat cbosdonnat at suse.com
Wed Sep 9 11:53:06 UTC 2015


On Tue, 2015-09-08 at 17:29 +0100, Daniel P. Berrange wrote:
> 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"

Is it safe to assume we'll be able to use /mnt as a temporary mount
folder? I'ld be more inclined in using a really temporary folder.

--
Cedric

> +        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





More information about the libvir-list mailing list