Exemplo n.º 1
0
def validateOutputDatasets(outDsets, dbsUrl):
    """
    Validate output datasets after all the other arguments have been
    locally update during assignment.
    """
    if len(outDsets) != len(set(outDsets)):
        msg = "Output dataset contains duplicates and it has to be fixed! %s" % outDsets
        raise InvalidSpecParameterValue(msg)

    datatier = []
    for dataset in outDsets:
        procds, tier = dataset.split("/")[2:]
        datatier.append(tier)
        try:
            procdataset(procds)
        except AssertionError as ex:
            msg = "Bad output dataset name, check the processed dataset name.\n %s" % str(
                ex)
            raise InvalidSpecParameterValue(msg)

    # TODO: this url conversion below can be removed in one year from now, thus March 2022
    dbsUrl = dbsUrl.replace("cmsweb.cern.ch", "cmsweb-prod.cern.ch")

    # Verify whether the output datatiers are available in DBS
    _validateDatatier(datatier, dbsUrl)
Exemplo n.º 2
0
    def _handleAssignmentStateTransition(self, workload, request_args, dn):
        if ('SoftTimeout' in request_args) and ('GracePeriod' in request_args):
            request_args['HardTimeout'] = request_args['SoftTimeout'] + request_args['GracePeriod']

        # Only allow extra value update for assigned status
        cherrypy.log("INFO: Assign request %s, input args: %s ..." % (workload.name(), request_args))
        try:
            workload.updateArguments(request_args)
        except Exception as ex:
            msg = traceback.format_exc()
            cherrypy.log("Error for request args %s: %s" % (request_args, msg))
            raise InvalidSpecParameterValue(str(ex))

        # validate/update OutputDatasets after ProcessingString and AcquisionEra is updated
        request_args['OutputDatasets'] = workload.listOutputDatasets()
        validateOutputDatasets(request_args['OutputDatasets'], workload.getDbsUrl())

        # by default, it contains all unmerged LFNs (used by sites to protect the unmerged area)
        request_args['OutputModulesLFNBases'] = workload.listAllOutputModulesLFNBases()

        # FIXME: remove it on HG1710, when this #7355 is complete fixed
        if not request_args['Team'] or not isinstance(request_args['Team'], basestring):
            raise InvalidSpecParameterValue("Team MUST be a non-empty string")

        # legacy update schema to support ops script
        loadRequestSchema(workload, request_args)
        # save the spec first before update the reqmgr request status to prevent race condition
        # when workflow is pulled to GQ before site white list is updated
        workload.saveCouch(self.config.couch_host, self.config.couch_reqmgr_db)
        report = self.reqmgr_db_service.updateRequestProperty(workload.name(), request_args, dn)

        return report
Exemplo n.º 3
0
    def _handleAssignmentStateTransition(self, workload, request_args, dn):

        req_status = request_args["RequestStatus"]
        if req_status == "assigned" and not request_args.get('Team',
                                                             '').strip():
            raise InvalidSpecParameterValue(
                "Team must be set during workflow assignment: %s" %
                request_args)

        if ('SoftTimeout' in request_args) and ('GracePeriod' in request_args):
            request_args['SoftTimeout'] = int(request_args['SoftTimeout'])
            #TODO: not sure why GracePeriod when passed from web ingerface but convert here
            request_args['GracePeriod'] = int(request_args['GracePeriod'])
            request_args['HardTimeout'] = request_args[
                'SoftTimeout'] + request_args['GracePeriod']

        #Only allow extra value update for assigned status
        try:
            workload.updateArguments(request_args)
        except Exception as ex:
            msg = traceback.format_exc()
            cherrypy.log("Error for request args %s: %s" % (request_args, msg))
            raise InvalidSpecParameterValue(str(ex))

        # legacy update schema to support ops script
        loadRequestSchema(workload, request_args)
        #update OutputDatasets after ProcessingString and AcquisionEra is updated
        request_args['OutputDatasets'] = workload.listOutputDatasets()
        report = self.reqmgr_db_service.updateRequestProperty(
            workload.name(), request_args, dn)
        workload.saveCouch(self.config.couch_host, self.config.couch_reqmgr_db)
        return report
Exemplo n.º 4
0
    def _updateRequest(self, workload, request_args):

        if workload == None:
            (workload, request_args) = self.initialize_clone(
                request_args["OriginalRequestName"])
            return self.post(workload, request_args)

        dn = cherrypy.request.user.get("dn", "unknown")

        if "total_jobs" in request_args:
            # only GQ update this stats
            # request_args should contain only 4 keys 'total_jobs', 'input_lumis', 'input_events', 'input_num_files'}
            report = self.reqmgr_db_service.updateRequestStats(
                workload.name(), request_args)
        # if is not just updating status
        else:
            if len(request_args) > 1 or "RequestStatus" not in request_args:
                try:
                    workload.updateArguments(request_args)
                except Exception as ex:
                    msg = traceback.format_exc()
                    cherrypy.log("Error for request args %s: %s" %
                                 (request_args, msg))
                    raise InvalidSpecParameterValue(str(ex))

                # trailing / is needed for the savecouchUrl function
                workload.saveCouch(self.config.couch_host,
                                   self.config.couch_reqmgr_db)

            report = self.reqmgr_db_service.updateRequestProperty(
                workload.name(), request_args, dn)
        return report
Exemplo n.º 5
0
    def _updateRequest(self, workload, request_args):
        dn = cherrypy.request.user.get("dn", "unknown")

        if "RequestStatus" not in request_args:
            report = self._handleNoStatusUpdate(workload, request_args)
        else:
            req_status = request_args["RequestStatus"]
            # assignment-approved only allow Priority update
            if len(request_args) == 2 and req_status == "assignment-approved":
                report = self._handleAssignmentApprovedTransition(
                    workload, request_args, dn)
            elif len(request_args) > 1 and req_status == "assigned":
                report = self._handleAssignmentStateTransition(
                    workload, request_args, dn)
            elif len(request_args) == 1 or (len(request_args) == 2
                                            and "cascade" in request_args):
                report = self._handleOnlyStateTransition(
                    workload, request_args, dn)
            else:
                raise InvalidSpecParameterValue(
                    "can't update value except transition to assigned status: %s"
                    % request_args)

        if report == 'OK':
            return {workload.name(): "OK"}
        else:
            return {workload.name(): "ERROR"}
Exemplo n.º 6
0
    def _updateRequest(self, workload, request_args):
        dn = cherrypy.request.user.get("dn", "unknown")

        if workload is None:
            (workload, request_args) = self.initialize_clone(
                request_args["OriginalRequestName"])
            return self.post([workload, request_args])

        if "RequestStatus" not in request_args:
            report = self._handleNoStatusUpdate(workload, request_args)

        else:
            req_status = request_args["RequestStatus"]
            if len(request_args) > 1 and req_status == "assigned":
                report = self._handleAssignmentStateTransition(
                    workload, request_args, dn)
            elif len(request_args) == 2 and req_status in ["closed-out", "announced"] and \
                "cascade" in request_args:
                report = self._handleCascadeUpdate(workload, request_args, dn)

            elif len(request_args) == 1:
                report = self._handleOnlyStateTransition(
                    workload, req_status, dn)
            else:
                raise InvalidSpecParameterValue(
                    "can't update value except transition to assigned status: %s"
                    % request_args)

        if report == 'OK':
            return {workload.name(): "OK"}
        else:
            return {workload.name(): "ERROR"}
Exemplo n.º 7
0
    def _handleNoStatusUpdate(self, workload, request_args, dn):
        """
        For no-status update, we only support the following parameters:
         1. RequestPriority
         2. Global workqueue statistics, while acquiring a workflow
        """
        if 'RequestPriority' in request_args:
            # Yes, we completely ignore any other arguments posted by the user (web UI case)
            request_args = {'RequestPriority': request_args['RequestPriority']}
            # must update three places: GQ elements, workload_cache and workload spec
            self.gq_service.updatePriority(workload.name(),
                                           request_args['RequestPriority'])
            report = self.reqmgr_db_service.updateRequestProperty(
                workload.name(), request_args, dn)
            workload.setPriority(request_args['RequestPriority'])
            workload.saveCouchUrl(workload.specUrl())
            cherrypy.log('Updated priority of "%s" to %s' %
                         (workload.name(), request_args['RequestPriority']))
        elif workqueue_stat_validation(request_args):
            report = self.reqmgr_db_service.updateRequestStats(
                workload.name(), request_args)
        else:
            msg = "There are invalid arguments for no-status update: %s" % request_args
            raise InvalidSpecParameterValue(msg)

        return report
Exemplo n.º 8
0
def generateRequestName(request):
    currentTime = time.strftime('%y%m%d_%H%M%S', time.localtime(time.time()))
    seconds = int(10000 * (time.time() % 1.0))

    if "RequestString" not in request:
        raise InvalidSpecParameterValue("RequestString need to be specified")

    # TODO change to lexicon when we have exact format of RequestString
    if '@' in request["RequestString"]:
        raise InvalidSpecParameterValue("RequestString cannot contain @: %s" %
                                        request["RequestString"])

    request["RequestName"] = "%s_%s" % (request["Requestor"],
                                        request["RequestString"])
    # add time info
    request["RequestName"] += "_%s_%s" % (currentTime, seconds)
Exemplo n.º 9
0
    def _updateRequest(self, workload, request_args):
        dn = get_user_info().get("dn", "unknown")

        if "RequestStatus" not in request_args:
            report = self._handleNoStatusUpdate(workload, request_args, dn)
        else:
            req_status = request_args["RequestStatus"]
            if len(request_args) == 2 and req_status == "assignment-approved":
                report = self._handleAssignmentApprovedTransition(
                    workload, request_args, dn)
            elif len(request_args) > 1 and req_status == "assigned":
                report = self._handleAssignmentStateTransition(
                    workload, request_args, dn)
            elif len(request_args) == 1 or (len(request_args) == 2
                                            and "cascade" in request_args):
                report = self._handleOnlyStateTransition(
                    workload, request_args, dn)
            else:
                msg = "There are invalid arguments with this status transition: %s" % request_args
                raise InvalidSpecParameterValue(msg)

        if report == 'OK':
            return {workload.name(): "OK"}
        else:
            return {workload.name(): "ERROR"}
Exemplo n.º 10
0
def validate_request_priority(reqArgs):
    """
    Validate the RequestPriority argument against its definition
    in StdBase
    :param reqArgs: dictionary of user request arguments
    :return: nothing, but raises an exception in case of an invalid value
    """
    if 'RequestPriority' in reqArgs:
        reqPrioDefin = StdBase.getWorkloadCreateArgs()['RequestPriority']
        if not isinstance(reqArgs['RequestPriority'], reqPrioDefin['type']):
            msg = "RequestPriority must be of integer type, not: {}".format(
                type(reqArgs['RequestPriority']))
            raise InvalidSpecParameterValue(msg)
        if reqPrioDefin['validate'](reqArgs['RequestPriority']) is False:
            raise InvalidSpecParameterValue(
                "RequestPriority must be an integer between 0 and 999999")
Exemplo n.º 11
0
    def _validateGET(self, param, safe):
        # TODO: need proper validation but for now pass everything
        args_length = len(param.args)
        if args_length == 1:
            safe.kwargs["name"] = param.args[0]
            param.args.pop()
            return

        if "status" in param.kwargs and isinstance(param.kwargs["status"],
                                                   basestring):
            param.kwargs["status"] = [param.kwargs["status"]]
        if "status" in param.kwargs:
            for status in param.kwargs["status"]:
                if status.endswith("-archived"):
                    raise InvalidSpecParameterValue(
                        "Can't retrieve bulk archived status requests, use other search arguments"
                    )

        for prop in param.kwargs:
            safe.kwargs[prop] = param.kwargs[prop]

        for prop in safe.kwargs:
            del param.kwargs[prop]

        return
Exemplo n.º 12
0
    def _validateGET(self, param, safe):
        # TODO: need proper validation but for now pass everything
        args_length = len(param.args)
        if args_length == 1:
            safe.kwargs["name"] = param.args[0]
            param.args.pop()
            return

        no_multi_key = ["detail", "_nostale", "date_range", "common_dict"]
        for key, value in param.kwargs.items():
            # convert string to list
            if key not in no_multi_key and isinstance(value, basestring):
                param.kwargs[key] = [value]

        detail = param.kwargs.get('detail', True)
        if detail in (False, "false", "False", "FALSE"):
            detail = False

        if "status" in param.kwargs and detail:
            for status in param.kwargs["status"]:
                if status.endswith("-archived"):
                    raise InvalidSpecParameterValue(
                        """Can't retrieve bulk archived status requests with detail option True,
                           set detail=false or use other search arguments""")

        for prop in param.kwargs.keys():
            safe.kwargs[prop] = param.kwargs.pop(prop)
        return
Exemplo n.º 13
0
    def _handleAssignmentStateTransition(self, workload, request_args, dn):
        if ('SoftTimeout' in request_args) and ('GracePeriod' in request_args):
            request_args['HardTimeout'] = request_args['SoftTimeout'] + request_args['GracePeriod']

        # Only allow extra value update for assigned status
        cherrypy.log("Assign request %s, input args: %s ..." % (workload.name(), request_args))
        try:
            workload.updateArguments(request_args)
        except Exception as ex:
            msg = traceback.format_exc()
            cherrypy.log("Error for request args %s: %s" % (request_args, msg))
            raise InvalidSpecParameterValue(str(ex))

        # validate/update OutputDatasets after ProcessingString and AcquisionEra is updated
        request_args['OutputDatasets'] = workload.listOutputDatasets()
        validateOutputDatasets(request_args['OutputDatasets'], workload.getDbsUrl())

        # by default, it contains all unmerged LFNs (used by sites to protect the unmerged area)
        request_args['OutputModulesLFNBases'] = workload.listAllOutputModulesLFNBases()

        # Add parentage relation for step chain, task chain:
        chainMap = workload.getChainParentageSimpleMapping()
        if chainMap:
            request_args["ChainParentageMap"] = chainMap

        # save the spec first before update the reqmgr request status to prevent race condition
        # when workflow is pulled to GQ before site white list is updated
        workload.saveCouch(self.config.couch_host, self.config.couch_reqmgr_db)
        report = self.reqmgr_db_service.updateRequestProperty(workload.name(), request_args, dn)

        return report
Exemplo n.º 14
0
    def validate(self, apiobj, method, api, param, safe):
        """
        Validate request input data.
        Has to be implemented, otherwise the service fails to start.
        If it's not implemented correctly (e.g. just pass), the arguments
        are not passed in the method at all.

        """
        try:
            if method == 'GET':
                self._validate_get_args(param, safe)

            if method == 'POST':
                args_length = len(param.args)
                if args_length == 1:
                    safe.kwargs["name"] = param.args[0]
                    param.args.pop()
        except InvalidSpecParameterValue as ex:
            raise ex
        except Exception as ex:
            msg = traceback.format_exc()
            cherrypy.log("Error: %s" % msg)
            if hasattr(ex, "message"):
                if hasattr(ex.message, '__call__'):
                    msg = ex.message()
                else:
                    msg = str(ex)
            else:
                msg = str(ex)
            raise InvalidSpecParameterValue(msg)
Exemplo n.º 15
0
    def _updateRequest(self, workload, request_args):

        if workload == None:
            (workload, request_args) = self.initialize_clone(
                request_args["OriginalRequestName"])
            return self.post(workload, request_args)

        dn = cherrypy.request.user.get("dn", "unknown")

        if ('SoftTimeout' in request_args) and ('GracePeriod' in request_args):
            request_args['HardTimeout'] = request_args[
                'SoftTimeout'] + request_args['GracePeriod']

        if 'RequestPriority' in request_args:
            self.gq_service.updatePriority(workload.name(),
                                           request_args['RequestPriority'])

        if "total_jobs" in request_args:
            # only GQ update this stats
            # request_args should contain only 4 keys 'total_jobs', 'input_lumis', 'input_events', 'input_num_files'}
            report = self.reqmgr_db_service.updateRequestStats(
                workload.name(), request_args)
        # if is not just updating status
        else:
            req_status = request_args.get("RequestStatus", None)

            if len(request_args) >= 1 and req_status == None:
                try:
                    workload.updateArguments(request_args)
                except Exception as ex:
                    msg = traceback.format_exc()
                    cherrypy.log("Error for request args %s: %s" %
                                 (request_args, msg))
                    raise InvalidSpecParameterValue(str(ex))

                # trailing / is needed for the savecouchUrl function
                workload.saveCouch(self.config.couch_host,
                                   self.config.couch_reqmgr_db)

            elif (req_status in ["closed-out"
                                 "announced"]) and request_args.get(
                                     "cascade", False):
                cascade_list = self._retrieveResubmissionChildren(
                    workload.name)
                for req_name in cascade_list:
                    report = self.reqmgr_db_service.updateRequestStatus(
                        req_name, req_status)

            # If it is aborted or force-complete transition call workqueue to cancel the request
            else:
                if req_status == "aborted" or req_status == "force-complete":
                    self.gq_service.cancelWorkflow(workload.name())
                report = self.reqmgr_db_service.updateRequestProperty(
                    workload.name(), request_args, dn)

        if report == 'OK':
            return {workload.name(): "OK"}
        else:
            return {workload.name(): "ERROR"}
Exemplo n.º 16
0
    def validate(self, apiobj, method, api, param, safe):
        # to make validate successful
        # move the validated argument to safe
        # make param empty
        # other wise raise the error
        try:
            if method == 'GET':
                self._validateGET(param, safe)

            elif method == 'PUT':
                args_length = len(param.args)

                if args_length == 1:
                    requestName = param.args[0]
                    param.args.pop()
                else:
                    requestName = None
                self._validateRequestBase(param, safe,
                                          validate_request_update_args,
                                          requestName)

            elif method == 'POST':
                args_length = len(param.args)
                if args_length == 2 and param.args[0] == "clone":
                    # handles clone workflow.- don't validtate args here
                    param.kwargs['OriginalRequestName'] = param.args[1]
                    param.args.pop()
                    param.args.pop()
                    self._validateRequestBase(param, safe,
                                              validate_clone_create_args)
                elif args_length == 1 and param.args[0] == "multi_update":
                    # special case for multi update from browser.
                    param.args.pop()
                    self._validateMultiRequests(param, safe,
                                                validate_request_update_args)
                elif args_length == 1 and param.args[0] == "bynames":
                    # special case for multi update from browser.
                    param.args.pop()
                    self._getRequestNamesFromBody(safe)
                else:
                    self._validateRequestBase(param, safe,
                                              validate_request_create_args)
        except InvalidSpecParameterValue as ex:
            raise ex
        except Exception as ex:
            # TODO add proper error message instead of trace back
            msg = traceback.format_exc()
            cherrypy.log("Error: %s" % msg)
            if hasattr(ex, "message"):
                if hasattr(ex.message, '__call__'):
                    msg = ex.message()
                else:
                    msg = str(ex)
            else:
                msg = str(ex)
            raise InvalidSpecParameterValue(msg)
Exemplo n.º 17
0
    def _handleAssignmentApprovedTransition(self, workload, request_args, dn):
        """
        Allows only two arguments: RequestStatus and RequestPriority
        """
        if "RequestPriority" not in request_args:
            msg = "There are invalid arguments for assignment-approved transition: %s" % request_args
            raise InvalidSpecParameterValue(msg)

        report = self.reqmgr_db_service.updateRequestProperty(workload.name(), request_args, dn)
        return report
Exemplo n.º 18
0
def _validateDatatier(datatier, dbsUrl):
    """
    _validateDatatier_

    Provided a list of datatiers extracted from the outputDatasets, checks
    whether they all exist in DBS already.
    """
    dbsTiers = DBSReader.listDatatiers(dbsUrl)
    badTiers = list(set(datatier) - set(dbsTiers))
    if badTiers:
        raise InvalidSpecParameterValue("Bad datatier(s): %s not available in DBS." % badTiers)
Exemplo n.º 19
0
def validateOutputDatasets(outDsets, dbsUrl):
    """
    Validate output datasets after all the other arguments have been
    locally update during assignment.
    """
    if len(outDsets) != len(set(outDsets)):
        msg = "Output dataset contains duplicates and it has to be fixed! %s" % outDsets
        raise InvalidSpecParameterValue(msg)

    datatier = []
    for dataset in outDsets:
        procds, tier = dataset.split("/")[2:]
        datatier.append(tier)
        try:
            procdataset(procds)
        except AssertionError as ex:
            msg = "Bad output dataset name, check the processed dataset name.\n %s" % str(ex)
            raise InvalidSpecParameterValue(msg)

    # Verify whether the output datatiers are available in DBS
    _validateDatatier(datatier, dbsUrl)
Exemplo n.º 20
0
def validate_request_update_args(request_args, config, reqmgr_db_service,
                                 param):
    """
    param and safe structure is RESTArgs structure: named tuple
    RESTArgs(args=[], kwargs={})

    validate post/put request
    1. read data from body
    2. validate the permission (authentication)
    3. validate state transition (against previous state from couchdb)
    2. validate using workload validation
    3. convert data from body to arguments (spec instance, argument with default setting)

    TODO: raise right kind of error with clear message
    """
    # this needs to be deleted for validation
    request_name = request_args.pop("RequestName")
    couchurl = '%s/%s' % (config.couch_host, config.couch_reqmgr_db)
    workload = WMWorkloadHelper()
    workload.loadSpecFromCouch(couchurl, request_name)

    # first validate the permission by status and request type.
    # if the status is not set only ReqMgr Admin can change the values
    # TODO for each step, assigned, approved, announce find out what other values
    # can be set
    request_args["RequestType"] = workload.requestType()
    permission = getWritePermission(request_args)
    authz_match(permission['role'], permission['group'])
    del request_args["RequestType"]

    # validate the status
    if "RequestStatus" in request_args:
        validate_state_transition(reqmgr_db_service, request_name,
                                  request_args["RequestStatus"])
        if request_args["RequestStatus"] in STATES_ALLOW_ONLY_STATE_TRANSITION:
            # if state change doesn't allow other transition nothing else to validate
            args_only_status = {}
            args_only_status["RequestStatus"] = request_args["RequestStatus"]
            args_only_status["cascade"] = request_args.get("cascade", False)
            return workload, args_only_status
        elif request_args["RequestStatus"] == 'assigned':
            workload.validateArgumentForAssignment(request_args)

    # TODO: fetch it from the assignment arg definition
    if 'RequestPriority' in request_args:
        request_args['RequestPriority'] = int(request_args['RequestPriority'])
        if (lambda x:
            (x >= 0 and x < 1e6))(request_args['RequestPriority']) is False:
            raise InvalidSpecParameterValue(
                "RequestPriority must be an integer between 0 and 1e6")

    return workload, request_args
Exemplo n.º 21
0
def generateRequestName(request):
    currentTime = time.strftime('%y%m%d_%H%M%S', time.localtime(time.time()))
    seconds = int(10000 * (time.time() % 1.0))

    if "RequestString" not in request:
        raise InvalidSpecParameterValue("RequestString need to be specified")

    request["RequestName"] = "%s_%s" % (request["Requestor"],
                                        request["RequestString"])
    # add time info
    request["RequestName"] += "_%s_%s" % (currentTime, seconds)
    # then validate the final request name
    identifier(request["RequestName"])
Exemplo n.º 22
0
    def validate(self, apiobj, method, api, param, safe):
        # to make validate successful
        # move the validated argument to safe
        # make param empty
        # other wise raise the error
        try:
            if method in ['GET']:
                self._validateGET(param, safe)

            if method == 'PUT':
                args_length = len(param.args)
                if args_length == 1:
                    requestName = param.args[0]
                    param.args.pop()
                else:
                    requestName = None
                self._validateRequestBase(param, safe,
                                          validate_request_update_args,
                                          requestName)
                #TO: handle multiple clone


#                 if len(param.args) == 2:
#                     #validate clone case
#                     if param.args[0] == "clone":
#                         param.args.pop()
#                         return None, request_args

            if method == 'POST':
                args_length = len(param.args)
                if args_length == 1 and param.args[0] == "multi_update":
                    #special case for multi update from browser.
                    param.args.pop()
                    self._validateMultiRequests(param, safe,
                                                validate_request_update_args)
                else:
                    self._validateRequestBase(param, safe,
                                              validate_request_create_args)

        except Exception as ex:
            #TODO add proper error message instead of trace back
            msg = traceback.format_exc()
            cherrypy.log("Error: %s" % msg)
            if hasattr(ex, "message"):
                if hasattr(ex.message, '__call__'):
                    msg = ex.message()
                else:
                    msg = str(ex)
            else:
                msg = str(ex)
            raise InvalidSpecParameterValue(msg)
Exemplo n.º 23
0
def validateOutputDatasets(outDsets, dbsUrl):
    """
    Validate output datasets after all the other arguments have been
    locally update during assignment
    """
    datatier = []
    for dataset in outDsets:
        tokens = dataset.split("/")
        procds = tokens[2]
        datatier.append(tokens[3])
        try:
            procdataset(procds)
        except AssertionError as ex:
            msg = "Bad output dataset name, check the processed dataset.\n %s" % str(ex)
            raise InvalidSpecParameterValue(msg)

    # Verify whether the output datatiers are available in DBS
    _validateDatatier(datatier, dbsUrl)
Exemplo n.º 24
0
    def _handleNoStatusUpdate(self, workload, request_args):
        """
        only few values can be updated without state transition involved
        currently 'RequestPriority' and 'total_jobs', 'input_lumis', 'input_events', 'input_num_files'
        """
        if 'RequestPriority' in request_args:
            # must update three places: GQ elements, workload_cache and workload spec
            self.gq_service.updatePriority(workload.name(), request_args['RequestPriority'])
            report = self.reqmgr_db_service.updateRequestProperty(workload.name(), request_args)
            workload.setPriority(request_args['RequestPriority'])
            workload.saveCouchUrl(workload.specUrl())
        elif "total_jobs" in request_args:
            # only GQ update this stats
            # request_args should contain only 4 keys 'total_jobs', 'input_lumis', 'input_events', 'input_num_files'}
            report = self.reqmgr_db_service.updateRequestStats(workload.name(), request_args)
        else:
            raise InvalidSpecParameterValue("can't update value without state transition: %s" % request_args)

        return report
Exemplo n.º 25
0
def _validateDatatier(datatier, dbsUrl, expiration=3600):
    """
    _validateDatatier_

    Provided a list of datatiers extracted from the outputDatasets, checks
    whether they all exist in DBS.
    """
    cacheName = "dataTierList_" + md5(dbsUrl).hexdigest()
    if not GenericDataCache.cacheExists(cacheName):
        mc = MemoryCacheStruct(expiration,
                               getDataTiers,
                               kwargs={'dbsUrl': dbsUrl})
        GenericDataCache.registerCache(cacheName, mc)

    cacheData = GenericDataCache.getCacheData(cacheName)
    dbsTiers = cacheData.getData()
    badTiers = list(set(datatier) - set(dbsTiers))
    if badTiers:
        raise InvalidSpecParameterValue(
            "Bad datatier(s): %s not available in DBS." % badTiers)
Exemplo n.º 26
0
def validate_request_update_args(request_args, config, reqmgr_db_service,
                                 param):
    """
    param and safe structure is RESTArgs structure: named tuple
    RESTArgs(args=[], kwargs={})
    
    validate post/put request
    1. read data from body
    2. validate the permission (authentication)
    3. validate state transition (against previous state from couchdb)
    2. validate using workload validation
    3. convert data from body to arguments (spec instance, argument with default setting)
    
    TODO: rasie right kind of error with clear message 
    """
    # this needs to be deleted for validation
    request_name = request_args.pop("RequestName")
    couchurl = '%s/%s' % (config.couch_host, config.couch_reqmgr_db)
    workload = WMWorkloadHelper()
    workload.loadSpecFromCouch(couchurl, request_name)

    # first validate the permission by status and request type.
    # if the status is not set only ReqMgr Admin can change the values
    # TODO for each step, assigned, approved, announce find out what other values
    # can be set
    request_args["RequestType"] = workload.requestType()
    permission = getWritePermission(request_args)
    authz_match(permission['role'], permission['group'])
    del request_args["RequestType"]

    #validate the status
    if "RequestStatus" in request_args:
        validate_state_transition(reqmgr_db_service, request_name,
                                  request_args["RequestStatus"])
        # delete request_args since it is not part of spec argument and validation
        args_without_status = {}
        args_without_status.update(request_args)
        del args_without_status["RequestStatus"]
    else:
        args_without_status = request_args

    if len(args_without_status) == 1:
        if 'RequestPriority' in args_without_status:
            args_without_status['RequestPriority'] = int(
                args_without_status['RequestPriority'])
            if (lambda x: (x >= 0 and x < 1e6))(
                    args_without_status['RequestPriority']) is False:
                raise InvalidSpecParameterValue(
                    "RequestPriority must be an integer between 0 and 1e6")
            return workload, args_without_status
        elif 'cascade' in args_without_status:
            # status was already validated
            return workload, request_args
    elif len(args_without_status) > 0 and not workqueue_stat_validation(
            args_without_status):
        # validate the arguments against the spec argumentSpecdefinition
        #TODO: currently only assigned status allows any update other then Status update
        workload.validateArgumentForAssignment(args_without_status)

    # to update request_args with type conversion
    request_args.update(args_without_status)
    return workload, request_args