Fail the image_present state for non-active images

this will ensure we are not making any changes to the image in a
non-termial state, and also avoid silently pretending that everything is
OK when there are no changes to make.

Change-Id: I264a89d6e0ccb88a56ed1a58e332701bedc09de2
Related-prod: PROD-31069
(cherry picked from commit bab584dc63874210c1bd3e42bcca8fd06d06ed30)
diff --git a/_states/glancev2.py b/_states/glancev2.py
index 5b149f2..6664b7e 100644
--- a/_states/glancev2.py
+++ b/_states/glancev2.py
@@ -52,7 +52,8 @@
            :param visibility: Scope of image accessibility.
                               Valid values: public, private, community, shared
     :param import_from_format: (optional) Format to import the image from
-    :param timeout: (optional) Time for task to download image
+    :param timeout: (optional) Time for task to download image or wait
+            until it becomes active if it is already present
     :param sleep_time: (optional) Timer countdown
     :param checksum: (optional) checksum of the image to verify it
     :param volume_name: (optional) name of the volume if specified the command
@@ -94,7 +95,7 @@
                 while timeout > 0 and image_status != 'active':
                     try:
                         image = _glancev2_call('image_get_details', name=name,
-                                                   cloud_name=cloud_name)
+                                               cloud_name=cloud_name)
                     except Exception as e:
                         if 'ResourceNotFound' in repr(e):
                             timeout -= sleep_time
@@ -188,15 +189,32 @@
                             return _failed('create', name, 'image')
 
                     elif image['status'] in ['saving', 'queued']:
-                        resp['comment'] = resp['comment'] \
-                                          + " checksum couldn't be verified, " \
-                                            "since status is not active"
+                        resp['comment'] += (" checksum couldn't be verified, "
+                                            "since status is not active")
                 return resp
         elif 'MultipleResourcesFound' in repr(e):
             return _failed('find', name, 'image')
         else:
             raise
 
+    # NOTE(pas-ha) fail the salt state if existing image is not in active state
+    image_status = exact_image['status'].copy()
+    while timeout > 0 and image_status != 'active':
+        log.warning("Image {name} is not ACTIVE in state, waiting..".format(
+            name=exact_image['name']))
+        timeout -= sleep_time
+        time.sleep(sleep_time)
+        try:
+            image = _glancev2_call('image_get_details', name=name,
+                                   cloud_name=cloud_name)
+        except Exception:
+            raise
+        image_status = image['status']
+    if image_status != 'active':
+        log.error("Image {name} failed to reach ACTIVE in state".format(
+            name=exact_image['name']))
+        return _failed('present', name, 'image')
+
     to_change = []
     for prop in image_properties:
         path = prop.replace('~', '~0').replace('/', '~1')
@@ -259,6 +277,7 @@
     }
     return changes_dict
 
+
 def _failed(op, name, resource):
     msg_map = {
         'create': '{0} {1} failed to create',
@@ -274,4 +293,4 @@
         'comment': msg_map[op].format(resource, name),
         'changes': {},
     }
-    return changes_dict
\ No newline at end of file
+    return changes_dict