def fileinfo(self, **kwargs): """Retrieve the file summary information. The caller needs to be a CMS user with a valid CMS x509 cert/proxy. :arg str hashkey: the sha256 hexdigest of the file, calculated over the tuple (name, size, mtime, uname) of all the tarball members :return: hashkey, name, size of the requested file""" hashkey = kwargs['hashkey'] result = {} filename = None infilepath = filepath(self.cachedir, kwargs['username']) # defining the path/name from the hash of the file filename = os.path.join(infilepath, hashkey[0:2], hashkey) result['hashkey'] = hashkey if not os.path.isfile(filename): raise MissingObject("Not such file") result['exists'] = True result['size'] = os.path.getsize(filename) result['accessed'] = os.path.getctime(filename) result['changed'] = os.path.getctime(filename) result['modified'] = os.path.getmtime(filename) touch(filename) return [result]
def authz_owner_match(dbapi, workflows, Task): """Match user against authorisation requirements to modify an existing resource. Allows to cache couchdb fetched documents if the caller needs them. :arg WMCore.CMSCouch.Database database: database connection to retrieve the docs :arg str list workflows: a list of workflows unique name as positive check :return: in case retrieve_docs is not false the list of couchdb documents.""" user = cherrypy.request.user log = cherrypy.log alldocs = [] for wf in workflows: wfrow = None try: wfrow = dbapi.query(None, None, Task.GetUserFromID_sql, taskname=wf).next() except Exception, ex: excauthz = RuntimeError( "The document '%s' is not retrievable '%s'" % (wf, str(ex))) raise MissingObject("The resource requested does not exist", trace=traceback.format_exc(), errobj=excauthz) if wfrow[0] == cherrypy.request.user['login']: alldocs.append(wfrow) continue log("ERROR: authz denied for user '%s' to the resource '%s. Resource belong to %s'" % (user, wf, wfrow[0])) raise cherrypy.HTTPError( 403, "You are not allowed to access this resource.")
def authz_owner_match(dbapi, workflows, Task): """ Match user against authorization requirements to modify an existing (list of) workflows. Either the user is the one who submitted the workflow, or it is an operator. :arg str list workflows: a list of workflows unique name as positive check """ user = cherrypy.request.user log = cherrypy.log #if the user trying to access the resource is an operator just exit to allow access if 'crab3' in cherrypy.request.user.get('roles', {}).get('operator', {}).get('group', set()): log("DEBUG: authz operator %s to access resources %s" % (user, workflows)) return alldocs = [] for wf in workflows: wfrow = None try: wfrow = next(dbapi.query(None, None, Task.GetUserFromID_sql, taskname = wf)) except Exception as ex: excauthz = RuntimeError("The document '%s' is not retrievable '%s'" % (wf, str(ex))) raise MissingObject("The resource requested does not exist", trace=traceback.format_exc(), errobj = excauthz) if wfrow[0] == cherrypy.request.user['login']: alldocs.append(wfrow) continue log("ERROR: authz denied for user '%s' to the resource '%s. Resource belong to %s'" % (user, wf, wfrow[0])) raise cherrypy.HTTPError(403, "You are not allowed to access this resource.") if len(workflows) == len(alldocs): log("DEBUG: authz user %s to access resources %s" % (user, workflows)) return log("ERROR: authz denied for user '%s' to resource '%s'" % (user, str(workflows))) raise cherrypy.HTTPError(403, "You are not allowed to access this resource.")
def logs(self, campaign, limit): """Returns the campaign log archive PFN. It takes care of the LFN - PFN conversion too. :arg str campaign: a campaign name :arg int limit: the limit on the number of PFN to return :return: an object with the list of log pfns""" workflows = self.getCampaignWorkflows(campaign) if not workflows: raise MissingObject("Cannot find workflows in campaign") yield self.userworkflow.log(workflows, limit)
def validate(self, apiobj, method, api, param, safe): if not param.args: raise InvalidParameter("Path required") for name in param.args: if not RX_PATH.match(name): raise InvalidParameter("Invalid path") item = self._prefix + tuple(param.args) if not self.api.scraper.exists(item, lambda v: bool(v.data)): raise MissingObject("No such image") safe.kwargs["item"] = item param.args[:] = []
def resubmit(self, campaign, workflows=None): """Resubmit all the unfinished workflows in the campaign. :arg str campaign: the unique campaign name :arg list str workflows: the list of workflows part of the campaign :return: the workflows unique names.""" workflows = self.getCampaignWorkflows(campaign) if not workflows: raise MissingObject("Cannot find workflows in campaign") for workflow in workflows: yield self.userworkflow.resubmit(workflow)
def kill(self, campaign, force, workflows=None): """Cancel all the unfinished workflows in the campaign. :arg str campaign: the unique campaign name :arg int force: in case the workflow has to be forced when deleted :arg list str workflows: the list of workflows part of the campaign :return: potentially nothing""" workflows = self.getCampaignWorkflows(campaign) if not workflows: raise MissingObject("Cannot find workflows in campaign") for workflow in workflows: yield self.userworkflow.kill(workflow)
def campaignSummary(self, campaign, workflows=None): """Provide the campaign status summary. This method iterates on all the workflows part of the campaign starting from the oldest one, and counts the number of jobs in each state. Then it returns a list where the first element is the campaign name, the second element is the campaign status, the third is a dict where keys are the 'main' states and values are number of jobs, the fourth is the breakdown of the 'main' states, and finally a dict containing the same information grouped by site :arg str campaign: the unique campaign name :arg list str workflows: the list of workflows part of the campaign :return: the campaign status summary""" workflows = self.getCampaignWorkflows(campaign) if not workflows: raise MissingObject("Cannot find workflows in campaign") for workflow in workflows: yield self.userworkflow.status(workflow)
def get(self, hashkey, username): """Retrieve a file previously uploaded to the local filesystem. The base path on the local filesystem is configurable. The caller needs to be a CMS user with a valid CMS x509 cert/proxy. :arg str hashkey: the sha256 hexdigest of the file, calculated over the tuple (name, size, mtime, uname) of all the tarball members :return: the raw file""" filename = None infilepath = filepath(self.cachedir, username) # defining the path/name from the hash of the file filename = os.path.join(infilepath, hashkey[0:2], hashkey) if not os.path.isfile(filename): raise MissingObject("Not such file") touch(filename) return serve_file(filename, "application/octet-stream", "attachment")
def fileremove(self, **kwargs): """Remove the file with the specified hashkey. The caller needs to be a CMS user with a valid CMS x509 cert/proxy. Users can only delete their own files :arg str hashkey: the sha256 hexdigest of the file, calculated over the tuple (name, size, mtime, uname) of all the tarball members """ hashkey = kwargs['hashkey'] infilepath = filepath(self.cachedir) # defining the path/name from the hash of the file filename = os.path.join(infilepath, hashkey[0:2], hashkey) if not os.path.isfile(filename): raise MissingObject("Not such file") try: os.remove(filename) except Exception as ex: raise ExecutionError("Impossible to remove the file: %s" % str(ex))
from WMCore.REST.Error import NoSuchInstance from WMCore.REST.Error import DatabaseError from WMCore.REST.Error import DatabaseUnavailable from WMCore.REST.Error import DatabaseConnectionError from WMCore.REST.Error import DatabaseExecutionError from WMCore.REST.Error import MissingParameter from WMCore.REST.Error import InvalidParameter from WMCore.REST.Error import MissingObject from WMCore.REST.Error import TooManyObjects from WMCore.REST.Error import ObjectAlreadyExists from WMCore.REST.Error import InvalidObject from WMCore.REST.Error import ExecutionError RESTError() NotAcceptable() UnsupportedMethod() MethodWithoutQueryString() APIMethodMismatch() APINotSpecified() NoSuchInstance() DatabaseError() DatabaseUnavailable() DatabaseConnectionError() DatabaseExecutionError() MissingParameter() InvalidParameter() MissingObject() TooManyObjects() ObjectAlreadyExists() InvalidObject() ExecutionError()