From fb76fb87b97f5be72e3371c1d4c8529222b1b4d3 Mon Sep 17 00:00:00 2001 From: Jimmy Berry Date: Wed, 31 May 2017 10:10:22 +0200 Subject: [PATCH] stagingapi: rework supersede logic to handle different request types. Additionally, this treats revoked or superseded requests as always to be replaced if a new requests is available. --- osclib/stagingapi.py | 55 +++++++++++++++++++++++++++++-------- osclib/supersede_command.py | 3 ++ 2 files changed, 47 insertions(+), 11 deletions(-) diff --git a/osclib/stagingapi.py b/osclib/stagingapi.py index ad163401..7d3bd82a 100644 --- a/osclib/stagingapi.py +++ b/osclib/stagingapi.py @@ -491,16 +491,48 @@ class StagingAPI(object): if stage_info and stage_info['rq_id'] != request_id: request_old = get_request(self.apiurl, str(stage_info['rq_id'])).to_xml() request_new = request + replace_old = request_old.find('state').get('name') in ['revoked', 'superseded'] - # If both are submits from different source projects then check + if (request_new.find('action').get('type') == 'delete' and + request_old.find('action').get('type') == 'delete'): + # Both delete requests. + if replace_old: + # Pointless since identical requests, but user desires. + return stage_info, None + else: + # Keep the original request and decline this identical one. + message = 'sr#{} is an identical delete and is already staged'.format( + request_old.get('id')) + self.do_change_review_state(request_id, 'declined', + by_group=self.cstaging_group, message=message) + return stage_info, True + + if (request_new.find('action').get('type') != + request_old.find('action').get('type')): + # One delete and one submit. + if replace_old: + if self.ring_packages.get(target_package): + # Since deletes are considered ring then both requests are ring and a + # supersede is fine. + return stage_info, None + else: + # Unselect old request and do no stage the new request to allow it to be + # staged via the normal process to find the appropriate staging project. + return stage_info, 'unstage' + else: + # Decline new type and indicate that old request should be revoked first. + message = 'sr#{} of a different type should be revoked first'.format( + request_old.get('id')) + self.do_change_review_state(request_id, 'declined', + by_group=self.cstaging_group, message=message) + return stage_info, True + + # If both submits are from different source projects then check # the source info and proceed accordingly, otherwise supersede. # A targeted package overrides this condition. - if is_targeted or not( - request_new.find('action').get('type') == 'submit' and - request_old.find('action').get('type') == 'submit' and - request_new.find('action/source').get('project') != - request_old.find('action/source').get('project') - ): + if (is_targeted or replace_old or + (request_new.find('action/source').get('project') == + request_old.find('action/source').get('project'))): return stage_info, None source_info_new = self.source_info_request(request_new) @@ -533,15 +565,16 @@ class StagingAPI(object): stage_info, code = self.superseded_request(request, target_requests) request_id = int(request.get('id')) - if stage_info and code is None: + if stage_info and (code is None or code == 'unstage'): # Remove the old request self.rm_from_prj(stage_info['prj'], request_id=stage_info['rq_id'], msg='Replaced by sr#{}'.format(request_id), review='declined') - # Add the new one that should be replacing it - self.rq_to_prj(request_id, stage_info['prj']) - self._invalidate_get_open_requests() + if code is None: + # Add the new request that should be replacing the old one. + self.rq_to_prj(request_id, stage_info['prj']) + self._invalidate_get_open_requests() return stage_info, code diff --git a/osclib/supersede_command.py b/osclib/supersede_command.py index a13e3bd2..23df0284 100644 --- a/osclib/supersede_command.py +++ b/osclib/supersede_command.py @@ -15,6 +15,9 @@ class SupersedeCommand(object): for stage_info, code, request in self.api.dispatch_open_requests(requests): action = request.find('action') target_package = action.find('target').get('package') + if code == 'unstage': + # Technically, the new request has not been staged, but superseded the old one. + code = None verbage = self.CODE_MAP[code] if code is not None: verbage += ' in favor of'