[Pkg-libvirt-commits] [libvirt-sandbox] 26/42: docker: introduce a DockerImage class

Guido Guenther agx at moszumanska.debian.org
Sat May 27 16:27:09 UTC 2017


This is an automated email from the git hooks/post-receive script.

agx pushed a commit to branch debian/experimental
in repository libvirt-sandbox.

commit 3d559de0cc41226154e90018513bdc46d66c79f5
Author: Daniel P. Berrange <berrange at redhat.com>
Date:   Thu Jul 14 09:31:27 2016 +0100

    docker: introduce a DockerImage class
    
    Instead of directly using the Template class in docker code,
    introduce a DockerImage class which represents the data in a
    more convenient manner. In particular it will canonicalize
    the image names eg a bare image name with no "/", like "ubuntu",
    should be "library/ubuntu"
    
    The index.json file now stores the repo name, image name and tag
    so we resolve the correct matching image where there are multiple
    versions of the same image stored locally.
    
    Signed-off-by: Daniel P. Berrange <berrange at redhat.com>
---
 libvirt-sandbox/image/sources/docker.py | 110 +++++++++++++++++++++++---------
 1 file changed, 81 insertions(+), 29 deletions(-)

diff --git a/libvirt-sandbox/image/sources/docker.py b/libvirt-sandbox/image/sources/docker.py
index c989662..01cf498 100644
--- a/libvirt-sandbox/image/sources/docker.py
+++ b/libvirt-sandbox/image/sources/docker.py
@@ -49,6 +49,39 @@ class DockerConfParser():
         else:
           return []
 
+class DockerImage():
+
+    def __init__(self, repo, name, tag=None):
+
+        self.repo = repo
+        self.name = name
+        self.tag = tag
+
+        if self.tag is None:
+            self.tag = "latest"
+
+        if self.repo is None:
+            self.repo = "library"
+
+    def __repr__(self):
+        return "%s/%s,tag=%s" % (self.repo, self.name, self.tag)
+
+    @classmethod
+    def from_template(cls, template):
+        bits = template.path[1:].split("/")
+        if len(bits) == 1:
+            return cls(repo=None,
+                       name=bits[0],
+                       tag=template.params.get("tag"))
+        elif len(bits) == 2:
+            return cls(repo=bits[0],
+                       name=bits[1],
+                       tag=template.params.get("tag"))
+        else:
+            raise Exception("Expected image name, or repo & image name for path, not '%s'",
+                            template.path)
+
+
 class DockerSource(base.Source):
 
     def _check_cert_validate(self):
@@ -60,9 +93,9 @@ class DockerSource(base.Source):
         if  (major == 2 and sys.hexversion < py2_7_9_hexversion) or (major == 3 and sys.hexversion < py3_4_3_hexversion):
             sys.stderr.write(SSL_WARNING)
 
-    def _was_downloaded(self, template, templatedir):
+    def _was_downloaded(self, image, templatedir):
         try:
-            self._get_image_list(template, templatedir)
+            self._get_image_list(image, templatedir)
             return True
         except Exception:
             return False
@@ -70,19 +103,22 @@ class DockerSource(base.Source):
 
     def has_template(self, template, templatedir):
         try:
-            configfile, diskfile = self._get_template_data(template, templatedir)
+            image = DockerImage.from_template(template)
+            configfile, diskfile = self._get_template_data(image, templatedir)
             return os.path.exists(diskfile)
         except Exception:
             return False
 
 
-    def download_template(self, template, templatedir):
+    def download_template(self, image, template, templatedir):
         self._check_cert_validate()
 
         try:
             (data, res) = self._get_json(template,
                                          None,
-                                         "/v1/repositories" + template.path + "/images",
+                                         "/v1/repositories/%s/%s/images" % (
+                                             image.repo, image.name,
+                                         ),
                                          {"X-Docker-Token": "true"})
         except urllib2.HTTPError, e:
             raise ValueError(["Image '%s' does not exist" % template])
@@ -95,13 +131,15 @@ class DockerSource(base.Source):
             headers["Authorization"] = "Token " + token
         (data, res) = self._get_json(template,
                                      registryendpoint,
-                                     "/v1/repositories" + template.path + "/tags",
+                                     "/v1/repositories/%s/%s/tags" %(
+                                         image.repo, image.name
+                                     ),
                                      headers)
 
-        tag = template.params.get("tag", "latest")
-        if not tag in data:
-            raise ValueError(["Tag '%s' does not exist for image '%s'" % (tag, template)])
-        imagetagid = data[tag]
+        if image.tag not in data:
+            raise ValueError(["Tag '%s' does not exist for image '%s'" %
+                              (image.tag, template)])
+        imagetagid = data[image.tag]
 
         (data, res) = self._get_json(template,
                                      registryendpoint,
@@ -141,7 +179,9 @@ class DockerSource(base.Source):
                     createdFiles.append(datafile)
 
             index = {
-                "name": template.path,
+                "repo": image.repo,
+                "name": image.name,
+                "tag": image.tag,
             }
 
             indexfile = templatedir + "/" + imagetagid + "/index.json"
@@ -252,10 +292,12 @@ class DockerSource(base.Source):
             raise
 
     def create_template(self, template, templatedir, connect=None):
-        if not self._was_downloaded(template, templatedir):
-            self.download_template(template, templatedir)
+        image = DockerImage.from_template(template)
 
-        imagelist = self._get_image_list(template, templatedir)
+        if not self._was_downloaded(image, templatedir):
+            self.download_template(image, template, templatedir)
+
+        imagelist = self._get_image_list(image, templatedir)
         imagelist.reverse()
 
         parentImage = None
@@ -280,7 +322,7 @@ class DockerSource(base.Source):
                                  connect)
             parentImage = templateImage
 
-    def _get_image_list(self, template, templatedir):
+    def _get_image_list(self, image, templatedir):
         imageparent = {}
         imagenames = {}
         imagedirs = os.listdir(templatedir)
@@ -289,7 +331,10 @@ class DockerSource(base.Source):
             if os.path.exists(indexfile):
                 with open(indexfile,"r") as f:
                     index = json.load(f)
-                imagenames[index["name"]] = imagetagid
+                thisimage = DockerImage(index.get("repo"),
+                                        index["name"],
+                                        index.get("tag"))
+                imagenames[str(thisimage)] = imagetagid
             jsonfile = templatedir + "/" + imagetagid + "/template.json"
             if os.path.exists(jsonfile):
                 with open(jsonfile,"r") as f:
@@ -297,9 +342,9 @@ class DockerSource(base.Source):
                 parent = data.get("parent",None)
                 if parent:
                     imageparent[imagetagid] = parent
-        if not template.path in imagenames:
-            raise ValueError(["Image %s does not exist locally" % template.path])
-        imagetagid = imagenames[template.path]
+        if str(image) not in imagenames:
+            raise ValueError(["Image %s does not exist locally" % image])
+        imagetagid = imagenames[str(image)]
         imagelist = []
         while imagetagid != None:
             imagelist.append(imagetagid)
@@ -308,6 +353,8 @@ class DockerSource(base.Source):
         return imagelist
 
     def delete_template(self, template, templatedir):
+        image = DockerImage.from_template(template)
+
         imageusage = {}
         imageparent = {}
         imagenames = {}
@@ -317,7 +364,10 @@ class DockerSource(base.Source):
             if os.path.exists(indexfile):
                 with open(indexfile,"r") as f:
                     index = json.load(f)
-                imagenames[index["name"]] = imagetagid
+                thisimage = DockerImage(index.get("repo"),
+                                        index["name"],
+                                        index.get("tag"))
+                imagenames[str(thisimage)] = imagetagid
             jsonfile = templatedir + "/" + imagetagid + "/template.json"
             if os.path.exists(jsonfile):
                 with open(jsonfile,"r") as f:
@@ -331,10 +381,9 @@ class DockerSource(base.Source):
                     imageparent[imagetagid] = parent
 
 
-        if not template.path in imagenames:
-            raise ValueError(["Image %s does not exist locally" % template.path])
-
-        imagetagid = imagenames[template.path]
+        if str(image) not in imagenames:
+            raise ValueError(["Image %s does not exist locally" % image])
+        imagetagid = imagenames[str(image)]
         while imagetagid != None:
             debug("Remove %s\n" % imagetagid)
             parent = imageparent.get(imagetagid,None)
@@ -357,15 +406,16 @@ class DockerSource(base.Source):
                     parent = None
             imagetagid = parent
 
-    def _get_template_data(self, template, templatedir):
-        imageList = self._get_image_list(template, templatedir)
+    def _get_template_data(self, image, templatedir):
+        imageList = self._get_image_list(image, templatedir)
         toplayer = imageList[0]
         diskfile = templatedir + "/" + toplayer + "/template.qcow2"
         configfile = templatedir + "/" + toplayer + "/template.json"
         return configfile, diskfile
 
     def get_disk(self, template, templatedir, imagedir, sandboxname):
-        configfile, diskfile = self._get_template_data(template, templatedir)
+        image = DockerImage.from_template(template)
+        configfile, diskfile = self._get_template_data(image, templatedir)
         tempfile = imagedir + "/" + sandboxname + ".qcow2"
         if not os.path.exists(imagedir):
             os.makedirs(imagedir)
@@ -377,7 +427,8 @@ class DockerSource(base.Source):
         return tempfile
 
     def get_command(self, template, templatedir, userargs):
-        configfile, diskfile = self._get_template_data(template, templatedir)
+        image = DockerImage.from_template(template)
+        configfile, diskfile = self._get_template_data(image, templatedir)
         configParser = DockerConfParser(configfile)
         cmd = configParser.getCommand()
         entrypoint = configParser.getEntrypoint()
@@ -391,7 +442,8 @@ class DockerSource(base.Source):
             return entrypoint + cmd
 
     def get_env(self, template, templatedir):
-        configfile, diskfile = self._get_template_data(template, templatedir)
+        image = DockerImage.from_template(template)
+        configfile, diskfile = self._get_template_data(image, templatedir)
         configParser = DockerConfParser(configfile)
         return configParser.getEnvs()
 

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-libvirt/libvirt-sandbox.git



More information about the Pkg-libvirt-commits mailing list