示例#1
0
    def create(self):
        """
        _create_

        Create the couch document for this object.
        """
        if not self.couch.documentExists(self.document_id):
            couchDoc =  CMSCouch.Document(self.document_id, { self.cdb_document_data : dict(self)})
            self.couch.commitOne(couchDoc)
示例#2
0
 def __init__(self, couchUrl, couchDatabase):
     self.cdb_url = couchUrl
     self.cdb_database = couchDatabase
     try:
         self.cdb_server = CMSCouch.CouchServer(self.cdb_url)
         self.couch = self.cdb_server.connectDatabase(self.cdb_database)
     except Exception as ex:
         msg = "Exception instantiating couch services for :\n"
         msg += " url = %s\n database = %s\n" % (self.cdb_url, self.cdb_database)
         msg += " Exception: %s" % str(ex)
         print(msg)
         raise CouchConnectionError(msg)
示例#3
0
 def publicationStatus(self, workflow, asourl):
     publication_info = {}
     if not asourl:
         raise ExecutionError("This CRAB server is not configured to publish; no publication status is available.")
     server = CMSCouch.CouchServer(dburl=asourl, ckey=self.serverKey, cert=self.serverCert)
     try:
         db = server.connectDatabase('asynctransfer')
     except Exception, ex:
         msg =  "Error while connecting to asynctransfer CouchDB"
         self.logger.exception(msg)
         publication_info = {'error' : msg}
         return  publication_info
    def publicationStatusCouch(self, workflow, asourl, asodb):
        publicationInfo = {'status': {}, 'failure_reasons': {}}
        if not asourl:
            raise ExecutionError("This CRAB server is not configured to publish; no publication status is available.")
        server = CMSCouch.CouchServer(dburl=asourl, ckey=self.serverKey, cert=self.serverCert)
        try:
            db = server.connectDatabase(asodb)
        except Exception:
            msg = "Error while connecting to asynctransfer CouchDB for workflow %s " % workflow
            msg += "\n asourl=%s asodb=%s" % (asourl, asodb)
            self.logger.exception(msg)
            publicationInfo['status'] = {'error': msg}
            return publicationInfo
        # Get the publication status for the given workflow. The next query to the
        # CouchDB view returns a list of 1 dictionary (row) with:
        # 'key'   : workflow,
        # 'value' : a dictionary with possible publication statuses as keys and the
        #           counts as values.
        query = {'reduce': True, 'key': workflow, 'stale': 'update_after'}
        try:
            publicationList = db.loadView('AsyncTransfer', 'PublicationStateByWorkflow', query)['rows']
        except Exception:
            msg = "Error while querying CouchDB for publication status information for workflow %s " % workflow
            self.logger.exception(msg)
            publicationInfo['status'] = {'error': msg}
            return publicationInfo
        if publicationList:
            publicationStatusDict = publicationList[0]['value']
            publicationInfo['status'] = publicationStatusDict
            # Get the publication failure reasons for the given workflow. The next query to
            # the CouchDB view returns a list of N_different_publication_failures
            # dictionaries (rows) with:
            # 'key'   : [workflow, publication failure],
            # 'value' : count.
            numFailedPublications = publicationStatusDict['publication_failed']
            if numFailedPublications:
                query = {'group': True, 'startkey': [workflow], 'endkey': [workflow, {}], 'stale': 'update_after'}
                try:
                    publicationFailedList = db.loadView('DBSPublisher', 'PublicationFailedByWorkflow', query)['rows']
                except Exception:
                    msg = "Error while querying CouchDB for publication failures information for workflow %s " % workflow
                    self.logger.exception(msg)
                    publicationInfo['failure_reasons']['error'] = msg
                    return publicationInfo
                publicationInfo['failure_reasons']['result'] = []
                for publicationFailed in publicationFailedList:
                    failureReason = publicationFailed['key'][1]
                    numFailedFiles = publicationFailed['value']
                    publicationInfo['failure_reasons']['result'].append((failureReason, numFailedFiles))

        return publicationInfo
示例#5
0
    def makeFilelist(self, files={}):
        """
        _makeFilelist_

        Create a new filelist document containing the id
        """
        input = {
            "collection_name": self.collectionName,
            "collection_type": self.collectionType,
            "fileset_name": self["name"],
            "files": files
        }

        document = CMSCouch.Document(None, input)
        self.owner.ownThis(document)

        commitInfo = self.couchdb.commitOne(document)
        document['_id'] = commitInfo[0]['id']
        document['_rev'] = commitInfo[0]['rev']
        return document
示例#6
0
def initialiseCouch(objectRef):
    if objectRef.couchdb != None:
        return
    if objectRef.url == None:
        msg = "url for couch service not provided"
        raise CouchConnectionError(msg)
    if objectRef.database == None:
        msg = "database name for couch service not provided"
        raise CouchConnectionError(msg)
    try:
        objectRef.server = CMSCouch.CouchServer(objectRef.url)
        objectRef.couchdb = objectRef.server.connectDatabase(
            objectRef.database)
    except Exception as e:
        msg = "Exception instantiating couch services for :\n"
        msg += " url = %s\n database = %s\n" % (objectRef.url,
                                                objectRef.database)
        msg += " Exception: %s" % str(e)
        print msg
        raise CouchConnectionError(msg)
示例#7
0
    def removeOwner(self, owner):
        """
        _removeOwner_

        Remove an owner and all the associated collections and filesets

        """
        result = self.couchdb.loadView(
            "GroupUser", 'owner_group_user', {
                'startkey': [owner.group.name, owner.name],
                'endkey': [owner.group.name, owner.name]
            }, [])
        for row in result[u'rows']:
            deleteMe = CMSCouch.Document()
            deleteMe[u'_id'] = row[u'value'][u'id']
            deleteMe[u'_rev'] = row[u'value'][u'rev']
            deleteMe.delete()
            self.couchdb.queue(deleteMe)
        self.couchdb.commit()
        owner.drop()
        return
示例#8
0
    def killTransfers(self, apmon):
        self.logger.info("About to kill transfers from workflow %s." %
                         self.workflow)
        ASOURL = self.task.get('tm_asourl', None)
        if not ASOURL:
            self.logger.info("ASO URL not set; will not kill transfers")
            return False

        try:
            hostname = socket.getfqdn()
        except:
            hostname = ''

        server = CMSCouch.CouchServer(dburl=ASOURL,
                                      ckey=self.proxy,
                                      cert=self.proxy)
        try:
            db = server.connectDatabase('asynctransfer')
        except Exception, ex:
            msg = "Error while connecting to asynctransfer CouchDB"
            self.logger.exception(msg)
            raise TaskWorkerException(msg)
示例#9
0
    def makeFilelist(self, files=None):
        """
        _makeFilelist_

        Create a new filelist document containing the id
        """
        files = files or {}
        # add a version to each of these ACDC docs such that we can properly
        # parse them and avoid issues between ACDC docs and agent base code
        input = {
            "collection_name": self.collectionName,
            "collection_type": self.collectionType,
            "fileset_name": self["name"],
            "files": files,
            "acdc_version": 2,
            "timestamp": time.time()
        }

        document = CMSCouch.Document(None, input)

        commitInfo = self.couchdb.commitOne(document)
        document['_id'] = commitInfo[0]['id']
        if 'rev' in commitInfo[0]:
            document['_rev'] = commitInfo[0]['rev']
        else:
            if commitInfo[0]['reason'].find('{exit_status,0}') != -1:
                # TODO: in this case actually insert succeeded but return error
                # due to the bug
                # https://issues.apache.org/jira/browse/COUCHDB-893
                # if rev is needed to proceed need to get by
                # self.couchdb.documentExist(document['_id'])
                # but that function need to be changed to return _rev
                document['_rev'] = "NeedToGet"
            else:
                msg = "Unable to insert document: check acdc server doc id: %s" % document[
                    '_id']
                raise RuntimeError(msg)
        return document
示例#10
0
    def connect(self):
        """
        _connect_

        Initialise the couch database connection for this object.
        This gets called automagically by the requireConnected decorator
        """
        if self.connected:
            return
        if self.cdb_url == None:
            msg = "url for couch service not provided"
            raise CouchConnectionError(msg)
        if self.cdb_database == None:
            msg = "database name for couch service not provided"
            raise CouchConnectionError(msg)
        try:
            self.cdb_server = CMSCouch.CouchServer(self.cdb_url)
            self.couch = self.cdb_server.connectDatabase(self.cdb_database)
        except Exception as ex:
            msg = "Exception instantiating couch services for :\n"
            msg += " url = %s\n database = %s\n" % (self.cdb_url, self.cdb_database)
            msg += " Exception: %s" % str(ex)
            print msg
            raise CouchConnectionError(msg)
示例#11
0
    def killTransfers(self, apmon):
        self.logger.info("About to kill transfers from workflow %s." % self.workflow)
        ASOURL = self.task.get('tm_asourl', None)
        if not ASOURL:
            self.logger.info("ASO URL not set; will not kill transfers")
            return False

        try:
            hostname = socket.getfqdn()
        except:
            hostname = ''

        server = CMSCouch.CouchServer(dburl=ASOURL, ckey=self.proxy, cert=self.proxy)
        try:
            db = server.connectDatabase('asynctransfer')
        except Exception as ex:
            msg =  "Error while connecting to asynctransfer CouchDB"
            self.logger.exception(msg)
            raise TaskWorkerException(msg)
        self.queryKill = {'reduce':False, 'key':self.workflow, 'include_docs': True}
        try:
            filesKill = db.loadView('AsyncTransfer', 'forKill', self.queryKill)['rows']
        except Exception as ex:
            msg =  "Error while connecting to asynctransfer CouchDB"
            self.logger.exception(msg)
            raise TaskWorkerException(msg)
        if len(filesKill) == 0:
            self.logger.warning('No files to kill found')
        for idt in filesKill:
            now = str(datetime.datetime.now())
            id = idt['value']
            data = {
                'end_time': now,
                'state': 'killed',
                'last_update': time.time(),
                'retry': now,
               }
            updateUri = "/%s/_design/AsyncTransfer/_update/updateJobs/%s?%s" % (db.name, id, urllib.urlencode(data))
            jobid = idt.get('jobid')
            jobretry = idt.get('job_retry_count')
            if not self.task['kill_all']:
                if idt.get("jobid") not in self.task['kill_ids']:
                    continue
            self.logger.info("Killing transfer %s (job ID %s; job retry %s)." % (id, str(jobid), str(jobretry)))
            jobid = str(jobid)
            jobretry = str(jobretry)
            if jobid and jobretry != None:
                jinfo = {'broker': hostname,
                         'bossId': jobid,
                         'StatusValue': 'killed',
                        }
                insertJobIdSid(jinfo, jobid, self.workflow, jobretry)
                self.logger.info("Sending kill info to Dashboard: %s" % str(jinfo))
                apmon.sendToML(jinfo)
            try:
                db.makeRequest(uri = updateUri, type = "PUT", decode = False)
            except Exception as ex:
                msg =  "Error updating document in couch"
                msg += str(ex)
                msg += str(traceback.format_exc())
                raise TaskWorkerException(msg)
        return True