22699868 _fetch_image method can try and build from partial image download
authorDrew Fisher <drew.fisher@oracle.com>
Mon, 12 Sep 2016 09:26:27 -0700
changeset 6901 2c7a24ff439f
parent 6900 7563855115a6
child 6902 f851e05a0783
22699868 _fetch_image method can try and build from partial image download
components/openstack/nova/files/solariszones/driver.py
--- a/components/openstack/nova/files/solariszones/driver.py	Tue Sep 13 16:49:46 2016 -0600
+++ b/components/openstack/nova/files/solariszones/driver.py	Mon Sep 12 09:26:27 2016 -0700
@@ -40,7 +40,7 @@
 from eventlet import greenthread
 from keystoneclient import exceptions as keystone_exception
 from lxml import etree
-from oslo_concurrency import processutils
+from oslo_concurrency import lockutils, processutils
 from oslo_config import cfg
 from oslo_log import log as logging
 from oslo_serialization import jsonutils
@@ -1063,23 +1063,36 @@
         """Fetch an image using Glance given the instance's image_ref."""
         glancecache_dirname = CONF.solariszones.glancecache_dirname
         fileutils.ensure_tree(glancecache_dirname)
-        image = ''.join([glancecache_dirname, '/', instance['image_ref']])
-        if os.path.exists(image):
-            LOG.debug(_("Using existing, cached Glance image: id %s")
-                      % instance['image_ref'])
-            return image
-
-        LOG.debug(_("Fetching new Glance image: id %s")
-                  % instance['image_ref'])
-        try:
-            images.fetch(context, instance['image_ref'], image,
-                         instance['user_id'], instance['project_id'])
-        except Exception as reason:
-            LOG.error(_("Unable to fetch Glance image: id %s: %s")
-                      % (instance['image_ref'], reason))
-            raise
-        return image
-
+        iref = instance['image_ref']
+        image = os.path.join(glancecache_dirname, iref)
+        downloading = image + '.downloading'
+
+        with lockutils.lock('glance-image-%s' % iref):
+            if os.path.isfile(downloading):
+                LOG.debug(_('Cleaning partial download of %s' % iref))
+                os.unlink(image)
+                os.unlink(downloading)
+
+            elif os.path.exists(image):
+                LOG.debug(_("Using existing, cached Glance image: id %s")
+                          % iref)
+                return image
+
+            LOG.debug(_("Fetching new Glance image: id %s") % iref)
+            try:
+                # touch the empty .downloading file
+                with open(downloading, 'w'):
+                    pass
+                images.fetch(context, iref, image, instance['user_id'],
+                             instance['project_id'])
+                os.unlink(downloading)
+                return image
+            except Exception as reason:
+                LOG.error(_("Unable to fetch Glance image: id %s: %s")
+                          % (iref, reason))
+                raise
+
+    @lockutils.synchronized('validate_image')
     def _validate_image(self, context, image, instance):
         """Validate a glance image for compatibility with the instance."""
         # Skip if the image was already checked and confirmed as valid.
@@ -1119,7 +1132,7 @@
             image_meta = glanceapi.get(context, instance['image_ref'])
             image_properties = image_meta.get('properties')
             if image_properties.get('architecture') is None:
-                reason = reason + (_(" The 'architecture' property is not set "
+                reason = reason + (_("The 'architecture' property is not set "
                                      "on the Glance image."))
 
             raise exception.ImageUnacceptable(image_id=instance['image_ref'],