[BuildMonitor] add the defensive code to update the img info on OBS desc properly 12/120812/1
authorSungHun Hwang <sh0924.hwang@samsung.com>
Thu, 23 Mar 2017 06:41:17 +0000 (15:41 +0900)
committerSungHun Hwang <sh0924.hwang@samsung.com>
Fri, 24 Mar 2017 08:35:06 +0000 (17:35 +0900)
PROBLEM:
  Occasionally, at the step of 'post-image-creation'
    1. [Tizen:Wearable]
       If the exist image name on the OBS desc and the new image name are same
       then the old one is removed. In this case, BUILD-MONITOR(Post-image) is
       not triggered bcz the total image count is insufficient.

    2. [Tizen:Common]
       When using the OBS API to update the created image information simultaneously
       it does not work properly something like that among 19 images,
       only one image is missing on OBS desc.
       Same as above, the total iamge count is insufficient.

  These problems caused that the status stays 'Imaging' not to turn 'Succeeded'

SOLUTION:
1. add the 'repo' data to check not only the device name but also the image repo
2. add the polling count to retry the routine if failed to update_info

Change-Id: I8478af2a74b67fb3b7bb534bff70a4f6fe025fcb
Signed-off-by: SungHun Hwang <sh0924.hwang@samsung.com>
common/buildservice.py
job_imager.py
job_post_image.py

index 0f2a58c..7ef38ea 100755 (executable)
@@ -642,7 +642,8 @@ class BuildService(OSC):
             if info['images']:
                 # remove the old one if already exist
                 for image in images:
-                    if info['images'][0]['name'] == image['name']:
+                    if info['images'][0]['name'] == image['name'] and \
+                       info['images'][0]['repo'] == image['repo']:
                         images.remove(image)
 
                 saved_info['images'] = images + info['images']
index c1481cb..5e20ece 100755 (executable)
@@ -241,7 +241,9 @@ def main():
             "name": fields['name'],
             "project": fields.get('project', ''),
             "status": "failed",
-            "url": url
+            "url": url,
+            "build_id": build_id,
+            "repo": fields['repo'],
             }
     if "download_num" in fields:
         data["download_num"] = int(fields['download_num'])
@@ -324,7 +326,9 @@ def main():
             "name": fields['name'],
             "project": fields.get('project', ''),
             "status": status,
-            "url": url
+            "url": url,
+            "build_id": build_id,
+            "repo": fields['repo'],
             }
     if "download_num" in fields:
         data["download_num"] = int(fields['download_num'])
index 20acaca..ab1b593 100755 (executable)
@@ -23,6 +23,7 @@ import sys
 import base64
 import datetime
 
+from time import sleep
 from common.buildtrigger import trigger_info, trigger_next
 from common.buildservice import BuildService
 from common.prerelease import is_prerelease_project
@@ -46,6 +47,7 @@ def main():
     status = content.get('status', '')
     url = content.get('url', '')
     build_id = content.get('build_id', '')
+    repo = content.get('repo', '')
     # add image_created log for iris
     pub_enabled = os.getenv("IRIS_PUB_ENABLED", "0") != "0"
     if pub_enabled:
@@ -64,34 +66,66 @@ def main():
     if is_prerelease_project(project):
         build = BuildService(obs_api, obs_user, obs_passwd)
 
-        saveinfo = build.get_info(project)
-        if saveinfo.get('download_num', 0) != content.get('download_num', 1):
-            print 'EXCEPTION* mismatch download_num current:%s, obs:%s' \
-                  % (content.get('download_num'), saveinfo.get('download_num'))
-            print 'SKIP UPDATING BUILD INFO'
-            return
+        # get env
+        if not os.getenv("POST_IMAGE_POLL_CNT") or not os.getenv("POST_IMAGE_POLL_SEC"):
+            print '[%s] POST_IMAGE_POLL_CNT or POLL_SEC does not exist!!\n' % (__file__)
+            poll_cnt = int(3)
+            poll_sec = int(10)
+        else:
+            poll_cnt = int(os.getenv("POST_IMAGE_POLL_CNT"))
+            poll_sec = int(os.getenv("POST_IMAGE_POLL_SEC"))
+        print '[%s] poll_cnt(%s), poll_sec(%s)\n' \
+              % (__file__, poll_cnt, poll_sec)
 
-        info = {"images":
-                    [{"name": name,
-                     "status": status,
-                     "url": url}]
-                }
-        build.update_info(info, project)
-
-        if buildmonitor_enabled:
+        # do polling
+        while poll_cnt > 0:
             saveinfo = build.get_info(project)
-            if len(saveinfo['images']) == saveinfo['images_count']:
-                print '[%s] last image(%s)\n' \
-                      % (__file__, len(saveinfo['images']))
-                #buildmonitor.end_create_image_for_sr_stage(bm_start_datetime,
-                #                                           project)
-                bm_stage = 'Post_Image'
-                bm_data = {"bm_stage" : bm_stage,
-                           "bm_start_datetime" : str(bm_start_datetime),
-                           "project" : project,
-                           "bm_snapshot_name" : build_id,
-                          }
-                trigger_next("BUILD-MONITOR", bm_data)
+            if saveinfo.get('download_num', 0) != content.get('download_num', 1):
+                print 'EXCEPTION* mismatch download_num current:%s, obs:%s' \
+                      % (content.get('download_num'), saveinfo.get('download_num'))
+                print 'SKIP UPDATING BUILD INFO'
+                return
+
+            info = {"images":
+                        [{"name": name,
+                          "status": status,
+                          "repo": repo,
+                          "url": url}]
+                   }
+
+            before_update_img_cnt = len(saveinfo['images'])
+            build.update_info(info, project)
+
+            # for check
+            checkinfo = build.get_info(project)
+            after_update_img_cnt = len(checkinfo['images'])
+            target_img_cnt = saveinfo['images_count']
+            print '[%s] before_update_img_cnt(%s), after_update_img_cnt(%s) / target_img_cnt(%s)\n' \
+                  % (__file__, before_update_img_cnt, after_update_img_cnt, target_img_cnt)
+            poll_cnt -= 1
+
+            if after_update_img_cnt == target_img_cnt:
+                print '[%s] reached the target_img_cnt(%s)!! trigger BUILD-MONITOR(Post_Image)\n' \
+                      % (__file__, target_img_cnt)
+                if buildmonitor_enabled:
+                    #buildmonitor.end_create_image_for_sr_stage(bm_start_datetime,
+                    #                                           project)
+                    bm_stage = 'Post_Image'
+                    bm_data = {"bm_stage" : bm_stage,
+                               "bm_start_datetime" : str(bm_start_datetime),
+                               "project" : project,
+                               "bm_snapshot_name" : build_id,
+                              }
+                    trigger_next("BUILD-MONITOR", bm_data)
+                break
+            elif before_update_img_cnt == after_update_img_cnt:
+                print '[%s] update_info failed!! wait %s sec, remaining poll_cnt is (%s)\n' \
+                      % (__file__, poll_sec, poll_cnt)
+                sleep(poll_sec)
+                continue
+            else:
+                print '[%s] update_info succeeded!! keep going\n' % (__file__)
+                break
 
 if __name__ == "__main__":
     sys.exit(main())