SR-SYNC: requests changes 12/143312/2
authorhyokeun <hyokeun.jeon@samsung.com>
Wed, 9 Aug 2017 08:37:26 +0000 (17:37 +0900)
committerhyokeun <hyokeun.jeon@samsung.com>
Mon, 21 Aug 2017 01:06:42 +0000 (10:06 +0900)
1. Add submissions field into OBS description
2. Handle all submit entries rather than first item in the request info
3. Trash _link file if _service exists for all the accepted packages

Change-Id: Id7b9b78d8b4e7911bf7c844b3251af1eff3aecb0

common/buildservice.py
job_request.py

index 8436edd..6b438a4 100644 (file)
@@ -186,10 +186,12 @@ class BuildService(OSC):
             'sender': 'Admin',
            }
         """
-        node_xml = {'sourceproject':['action', 'source', 'project'], \
-            'targetproject':['action', 'target', 'project'],
-            'comment': ['state', 'comment'],
-            'sender': ['state', 'who'],
+        node_xml = {'sourceproject':['action', 'source', 'project', str], \
+            'targetproject':['action', 'target', 'project', str],
+            'sourcepackagelist':['action', 'source', 'package', list],
+            'targetpackagelist':['action', 'target', 'package', list],
+            'comment': ['state', 'comment', str],
+            'sender': ['state', 'who', str],
            }
         def _get_node_data(nodes, xml_info):
             """Get node data from xml_info
@@ -197,14 +199,17 @@ class BuildService(OSC):
             """
             try:
                 data = xml_info[nodes[0]]
-                _data = data
-                if isinstance(_data, list):
-                    _data = data[0]
-                for node in nodes[1:]:
-                    _data = _data[node]
-                return _data
+                ret_data = []
+                if not isinstance(data, list):
+                    data = [data]
+                for d in data:
+                    _data = d
+                    for node in nodes[1:]:
+                        _data = _data[node]
+                    ret_data.append(_data)
+                return ret_data
             except (AttributeError, ValueError):
-                return ''
+                return []
 
         sr_info = {}
         # get the SR xml string by reqid
@@ -213,7 +218,13 @@ class BuildService(OSC):
             # parse the SR xml
             xml_info = xml_to_obj(xml_root)
             for name, nodes in node_xml.items():
-                sr_info[name] = _get_node_data(nodes, xml_info)
+                if nodes[-1] == list:
+                    if name not in sr_info:
+                        sr_info[name] = []
+                    sr_info[name].extend(_get_node_data(nodes[:-1], xml_info))
+                else:
+                    sr_info[name] = _get_node_data(nodes[:-1], xml_info)[0]
+
         return sr_info
 
 
@@ -674,8 +685,9 @@ class BuildService(OSC):
         projects = saved_info.get('projects') or []
         packages = saved_info.get('packages') or []
         images = saved_info.get('images') or []
-        submitter = saved_info.get('submitter') or []
+        submitter = saved_info.get('submitter') or ''
         download_num = saved_info.get('download_num') or int(0)
+        submissions = saved_info.get('submissions') or []
         saved_info.update(info)
         if 'projects' in info:
             saved_info['projects'] = list(set(projects + info['projects']))
@@ -705,7 +717,11 @@ class BuildService(OSC):
                 saved_info['chksnap'] = info['chksnap']
         if 'download_num' in info:
             saved_info['download_num'] = int(download_num) + int(info['download_num'])
-        
+        if 'submissions' in info:
+            for s in info['submissions']:
+                submissions = filter(lambda a: a != s, submissions)
+            saved_info['submissions'] = submissions + info['submissions']
+
         self.set_description(json.dumps(saved_info), prj, pkg)
 
     def get_info(self, prj, pkg=None):
index 2e50f40..0d8dd89 100644 (file)
@@ -43,6 +43,10 @@ import xml.etree.cElementTree as ElementTree
 reload(sys)
 sys.setdefaultencoding('utf-8') # pylint: disable-msg=E1101
 
+HIGHLIGHT = '+'
+GREYEDOUT = '-'
+REPAIR_COMMENT = 'accepted request %s (%s/request/show/%s)\n\n%s'
+
 def request_url(request_id):
     """Get request url"""
 
@@ -170,30 +174,37 @@ def obs_git_data(event_fields):
     print ppt.pprint(ret_data)
     return ret_data, projects_list
 
-def delete_from_obs(prj, pkg, target_project=None, comments=None):
+def delete_from_obs(prj, pkg, handle_link=None):
     """
     Delete package from OBS.
     Delete project if it's prerelease project
     """
 
+    # Control flag for deleting useless _link file.
+    global is_link_visited
+    is_link_visited = False
+
     _bs = BuildService(os.getenv('OBS_API_URL'),
                       os.getenv('OBS_API_USERNAME'),
                       os.getenv('OBS_API_PASSWD'))
 
     # If selected package have both _link and _service file, delete _link.
-    if target_project is not None:
+    if is_link_visited == False and handle_link.get('target_project', None) is not None:
         try:
-            viewinfo = _bs.get_source_viewinfo(target_project, pkg, parse=0, nofilename=0)
-            viewroot = ElementTree.parse(viewinfo).getroot()
-            if viewroot.find('filename').text.startswith('_service:'):
-                if viewroot.find('linked') is not None:
-                    print 'Found conflicting LINK %s/%s' % (viewroot.find('linked').get('project'), \
-                                                            viewroot.find('linked').get('package'))
-                    _comments = 'revision %d is the same as revision %d w/o link. </br>\n%s' % \
-                                (int(viewroot.get('rev')) + 1, int(viewroot.get('rev')), \
-                                comments.replace('<','&lt;').replace('>','&gt;').replace('\n',' </br>\n'))
-                    _bs.delete_file(target_project, viewroot.get('package'), ['_link'], \
-                                    _comments, purge_comments=True)
+            for _pkg in handle_link.get('target_packages', []):
+                print 'Check link for %s' % _pkg
+                viewinfo = _bs.get_source_viewinfo(handle_link.get('target_project'), _pkg, parse=0, nofilename=0)
+                viewroot = ElementTree.parse(viewinfo).getroot()
+                if viewroot.find('filename').text.startswith('_service:'):
+                    if viewroot.find('linked') is not None:
+                        print 'Found conflicting LINK %s/%s' % (viewroot.find('linked').get('project'), \
+                                                                viewroot.find('linked').get('package'))
+                        _comments = 'revision %d is the same as revision %d w/o link. </br>\n%s' % \
+                                    (int(viewroot.get('rev')) + 1, int(viewroot.get('rev')), \
+                                    handle_link.get('comments').replace('<','&lt;').replace('>','&gt;').replace('\n',' </br>\n'))
+                        _bs.delete_file(handle_link.get('target_project'), viewroot.get('package'), ['_link'], \
+                                        _comments, purge_comments=True)
+                is_link_visited = True
         except Exception as err:
             print repr(err)
 
@@ -201,6 +212,7 @@ def delete_from_obs(prj, pkg, target_project=None, comments=None):
         if 'home:prerelease:' in prj:
             print 'Removing %s' % prj
             _bs.cleanup(prj, "This project has expired")
+            return
     except ObsError, error:
         print error
         if 'HTTP Error 404' in str(error):
@@ -208,11 +220,11 @@ def delete_from_obs(prj, pkg, target_project=None, comments=None):
         else:
             return False
 
-    if not _bs.exists(prj, pkg):
+    if pkg and not _bs.exists(prj, pkg):
         print '[Warning]:buildservice cannot find prj %s: pkg %s' % (prj, pkg)
         return True
 
-    if _bs.get_package_real_project_name(prj, pkg) == prj:
+    if pkg and _bs.get_package_real_project_name(prj, pkg) == prj:
         try:
             if True:
                 print 'Removing %s:%s' % (prj, pkg)
@@ -226,7 +238,7 @@ def delete_from_obs(prj, pkg, target_project=None, comments=None):
 
     return True
 
-def request_accepted(data, gerrit, gitprj):
+def request_accepted(data, gerrit, gitprj, targetpackagelist=[]):
     """Do lots of things when request accepted"""
 
     print '====request accepted===================================='
@@ -281,11 +293,13 @@ def request_accepted(data, gerrit, gitprj):
         print gre
         return 1
 
-    additional_comment = 'accepted request %s (%s/request/show/%s)\n\n%s' \
-                     % (data['OBS_REQ_ID'], os.getenv('OBS_URL'), data['OBS_REQ_ID'], \
+    additional_comment = REPAIR_COMMENT \
+                     % (data['OBS_REQ_ID'], os.getenv('OBS_URL_EXTERNAL'), data['OBS_REQ_ID'], \
                         data['OBS_REQ_DESP'])
     delete_from_obs(data['OBS_REQ_PRJ_SRC'], data['OBS_REQ_PKG_SRC'], \
-                    target_project=data['OBS_REQ_PRJ'], comments=additional_comment)
+                    handle_link={'target_project': data['OBS_REQ_PRJ'], \
+                                 'comments': additional_comment, \
+                                 'target_packages': targetpackagelist})
 
     # Disable triggerring make_dep_graph.
     # Code remained to enable it in the future
@@ -401,9 +415,14 @@ def main():
     if 'sourceproject' not in event_fields and 'sourceproject' in reqinfo:
         event_fields['sourceproject'] = reqinfo['sourceproject']
 
+    submissions = []
     try:
+        saved_info = build.get_info(event_fields['sourceproject'])
         event_fields['packages'] = \
-                    unicode_to_str(build.get_info(event_fields['sourceproject'])['packages'])
+                    unicode_to_str(saved_info['packages'])
+        # SR-SYNC: SR listing and its pure git repos.
+        if 'submissions' in saved_info:
+            submissions = unicode_to_str(saved_info['submissions'])
     except Exception as err:
         print 'Not able to fetch package list from OBS %s' % err
         event_fields['packages'] = []
@@ -482,16 +501,33 @@ def main():
             elif event_fields['state'] == 'revoked':
                 request_revoked(data)
             elif event_fields['state'] == 'accepted':
-                request_accepted(data, gerrit, gitprj)
+                print 'From accept'
+                request_accepted(data, gerrit, gitprj, reqinfo.get('targetpackagelist', None))
 
         elif event_type == 'OBS_SRCSRV_REQUEST_CREATE':
             request_created(data)
 
         elif event_type == 'OBS_SRCSRV_REQUEST_ACCEPTED':
-            request_accepted(data, gerrit, gitprj)
+            request_accepted(data, gerrit, gitprj, reqinfo.get('targetpackagelist', None))
         elif event_type == 'OBS_SRCSRV_REQUEST_REVOKED':
             request_revoked(data)
 
+    # Deleting project for SR-SYNC
+    if submissions and len(submissions) >= 1:
+        if (event_type == 'OBS_SRCSRV_REQUEST_STATECHANGE') and \
+            (event_fields['state'] == 'accepted'):
+            additional_comment = REPAIR_COMMENT \
+                             % (data['OBS_REQ_ID'], os.getenv('OBS_URL_EXTERNAL'), data['OBS_REQ_ID'], \
+                                data['OBS_REQ_DESP'])
+            delete_from_obs(data['OBS_REQ_PRJ_SRC'], None, \
+                            handle_link={'target_project': data['OBS_REQ_PRJ'], \
+                                         'comments': additional_comment, \
+                                         'target_packages': reqinfo.get('targetpackagelist', None)})
+        elif (event_type == 'OBS_SRCSRV_REQUEST_STATECHANGE') and \
+              (event_fields['state'] == 'revoked' or \
+               event_fields['state'] == 'declined'):
+             delete_from_obs(data['OBS_REQ_PRJ_SRC'], None)
+
     if buildmonitor_enabled and event_type == 'OBS_SRCSRV_REQUEST_STATECHANGE':
         bm_end_datetime = datetime.datetime.now()
         #buildmonitor.sr_accept_reject_for_sr_status_detail(event_fields,
@@ -504,6 +540,7 @@ def main():
                    "bm_start_datetime" : str(bm_start_datetime),
                    "bm_end_datetime" : str(bm_end_datetime),
                    "bm_git_tag" : data["GIT_TAG"],
+                   "submissions" : submissions,
                   }
         trigger_next("BUILD-MONITOR", bm_data)
 
@@ -511,3 +548,4 @@ def main():
 
 if __name__ == '__main__':
     sys.exit(main())
+