Пример #1
0
    def updateEventRanges(self, event_ranges):
        """ Update an event range on the Event Server """
        pUtil.tolog("Updating event ranges..")

        message = ""
        #url = "https://aipanda007.cern.ch:25443/server/panda"
        url = "https://pandaserver.cern.ch:25443/server/panda"
        # eventRanges = [{'eventRangeID': '4001396-1800223966-4426028-1-2', 'eventStatus':'running'}, {'eventRangeID': '4001396-1800223966-4426028-2-2','eventStatus':'running'}]

        node={}
        node['eventRanges']=json.dumps(event_ranges)

        # open connection
        ret = pUtil.httpConnect(node, url, path=self.__updateEventRangesDir, mode="UPDATEEVENTRANGES")
        # response = json.loads(ret[1])

        status = ret[0]
        if ret[0]: # non-zero return code
            message = "Failed to update event range - error code = %d, error: " % (ret[0], ret[1])
        else:
            response = json.loads(json.dumps(ret[1]))
            status = int(response['StatusCode'])
            message = json.dumps(response['Returns'])

        return status, message
Пример #2
0
def downloadEventRanges(jobId, jobsetID):
    """ Download event ranges from the Event Server """

    # Return the server response (instruction to AthenaMP)
    # Note: the returned message is a string (of a list of dictionaries). If it needs to be converted back to a list, use json.loads(message)

    tolog("Downloading new event ranges for jobId=%s and jobsetID=%s" % (jobId, jobsetID))

    # message = "[{u'lastEvent': 2, u'LFN': u'mu_E50_eta0-25.evgen.pool.root',u'eventRangeID': u'130-2068634812-21368-1-1', u'startEvent': 2, u'GUID':u'74DFB3ED-DAA7-E011-8954-001E4F3D9CB1'}]"

    message = ""
#    url = "https://aipanda007.cern.ch:25443/server/panda"
    url = "https://pandaserver.cern.ch:25443/server/panda"
    node = {}
    node['pandaID'] = jobId
    node['jobsetID'] = jobsetID

    # open connection
    ret = httpConnect(node, url, path=os.getcwd(), mode="GETEVENTRANGES")
    response = ret[1]

    if ret[0]: # non-zero return code
        message = "Failed to download event range - error code = %d" % (ret[0])
    else:
        message = response['eventRanges']

    if message == "" or message == "[]":
        message = "No more events"

    return message
Пример #3
0
    def updateEventRange(self, event_range_id, status='finished'):
        """ Update an event range on the Event Server """
        pUtil.tolog("Updating an event range..")

        message = ""
        # url = "https://aipanda007.cern.ch:25443/server/panda"
        url = "https://pandaserver.cern.ch:25443/server/panda"
        node = {}
        node['eventRangeID'] = event_range_id

        # node['cpu'] =  eventRangeList[1]
        # node['wall'] = eventRangeList[2]
        node['eventStatus'] = status
        # tolog("node = %s" % str(node))

        # open connection
        ret = pUtil.httpConnect(node, url, path=self.__updateEventRangesDir, mode="UPDATEEVENTRANGE")
        # response = ret[1]

        if ret[0]: # non-zero return code
            message = "Failed to update event range - error code = %d" % (ret[0])
        else:
            message = ""

        return ret[0], message
Пример #4
0
def downloadEventRanges(jobId, jobsetID, taskID, numRanges=10):
    """ Download event ranges from the Event Server """

    # Return the server response (instruction to AthenaMP)
    # Note: the returned message is a string (of a list of dictionaries). If it needs to be converted back to a list, use json.loads(message)

    tolog(
        "Downloading new event ranges for jobId=%s, taskID=%s and jobsetID=%s"
        % (jobId, taskID, jobsetID))

    # message = "[{u'lastEvent': 2, u'LFN': u'mu_E50_eta0-25.evgen.pool.root',u'eventRangeID': u'130-2068634812-21368-1-1', u'startEvent': 2, u'GUID':u'74DFB3ED-DAA7-E011-8954-001E4F3D9CB1'}]"

    message = ""
    #    url = "https://aipanda007.cern.ch:25443/server/panda"
    url = "https://pandaserver.cern.ch:25443/server/panda"
    node = {}
    node['pandaID'] = jobId
    node['jobsetID'] = jobsetID
    node['taskID'] = taskID
    node['nRanges'] = numRanges

    # open connection
    ret = httpConnect(node, url, path=os.getcwd(), mode="GETEVENTRANGES")
    response = ret[1]

    if ret[0]:  # non-zero return code
        message = "Failed to download event range - error code = %d" % (ret[0])
    else:
        message = response['eventRanges']

    if message == "" or message == "[]":
        message = "No more events"

    return message
Пример #5
0
    def getEventRanges(self, numRanges=2):
        """ Download event ranges from the Event Server """
        tolog("Server: Downloading new event ranges..")

        message = ""
        # url = "https://aipanda007.cern.ch:25443/server/panda"
        url = "https://pandaserver.cern.ch:25443/server/panda"

        node = {}
        node['pandaID'] = self.__job.jobId
        node['jobsetID'] = self.__job.jobsetID
        node['nRanges'] = numRanges

        # open connection
        ret = httpConnect(node, url, path=os.getcwd(), mode="GETEVENTRANGES")
        response = ret[1]

        if ret[0]:  # non-zero return code
            message = "Failed to download event range - error code = %d" % (
                ret[0])
            tolog(message)
            return []
        else:
            message = response['eventRanges']
            return json.loads(message)
Пример #6
0
def updateEventRange(event_range_id, eventRangeList, status='finished'):
    """ Update an event range on the Event Server """

    tolog("Updating an event range..")

    # PanDA dev server: url = "https://aipanda007.cern.ch:25443/server/panda"
    url = "https://pandaserver.cern.ch:25443/server/panda"
    node = {}
    node['eventRangeID'] = event_range_id

    if eventRangeList != []:
        pass
        # node['cpu'] =  eventRangeList[1]
        # node['wall'] = eventRangeList[2]
    node['eventStatus'] = status

    # open connection
    ret = httpConnect(node, url, path=os.getcwd(), mode="UPDATEEVENTRANGE")
    # response = ret[1]

    if ret[0]: # non-zero return code
        message = "Server responded with error code = %d" % (ret[0])
    else:
        message = ""

    return message
Пример #7
0
def updateEventRanges(event_ranges, pandaProxySecretKey=None, jobId=None, url="https://pandaserver.cern.ch:25443/server/panda", version=0):
    """ Update an event range on the Event Server """
    tolog("Updating event ranges...")

    try:
        if pandaProxySecretKey is not None and pandaProxySecretKey != "" :
            return  updateEventRangesPandaProxy(event_ranges, pandaProxySecretKey, jobId)
        message = ""

        # eventRanges = [{'eventRangeID': '4001396-1800223966-4426028-1-2', 'eventStatus':'running'}, {'eventRangeID': '4001396-1800223966-4426028-2-2','eventStatus':'running'}]

        node={}
        node['eventRanges']=json.dumps(event_ranges)
        if version:
            node['version'] = 1

        # open connection
        ret = httpConnect(node, url, path=os.getcwd(), mode="UPDATEEVENTRANGES")
        # response = json.loads(ret[1])

        status = ret[0]
        if ret[0]: # non-zero return code
            message = "Failed to update event range - error code = %d, error: %s" % (ret[0], ret[1])
        else:
            response = json.loads(json.dumps(ret[1]))
            status = int(response['StatusCode'])
            message = json.dumps(response['Returns'])

        return status, message
    except:
        tolog("Failed to update event ranges: %s" % traceback.format_exc())
    return -1, None
Пример #8
0
def updateEventRange(event_range_id, eventRangeList, jobId, status='finished', os_bucket_id=-1):
    """ Update an event range on the Event Server """

    tolog("Updating an event range..")

    # PanDA dev server: url = "https://aipanda007.cern.ch:25443/server/panda"
    url = "https://pandaserver.cern.ch:25443/server/panda"
    node = {}
    node['eventRangeID'] = event_range_id

    if os_bucket_id != -1:
        node['objstoreID'] = os_bucket_id
    if eventRangeList != []:
        pass
        # node['cpu'] =  eventRangeList[1]
        # node['wall'] = eventRangeList[2]
    node['eventStatus'] = status

    # open connection
    ret = httpConnect(node, url, path=os.getcwd(), mode="UPDATEEVENTRANGE")
    # response = ret[1]

    if ret[0]: # non-zero return code
        message = "Server responded with error code = %d" % (ret[0])
    else:
        # is there an instruction in the back channel?
        data = ret[1]
        tolog("data=%s"%str(data))
        from json import loads
        try:
            d = loads(data['Command'])
        except Exception, e:
            tolog("No message found in updateEventRange back channel: %s" % (e))
            message = ""
        else:
Пример #9
0
def downloadEventRanges(jobId,
                        jobsetID,
                        taskID,
                        numRanges=10,
                        url="https://pandaserver.cern.ch:25443/server/panda"):
    """ Download event ranges from the Event Server """

    try:
        # url should be '%s:%s/server/panda' % (env['pshttpurl'], str(env['psport']))

        if os.environ.has_key('EventRanges') and os.path.exists(
                os.environ['EventRanges']):
            try:
                with open(os.environ['EventRanges']) as json_file:
                    events = json.load(json_file)
                os.rename(os.environ['EventRanges'],
                          os.environ['EventRanges'] + ".loaded")
                tolog(events)
                return json.dumps(events)
            except:
                tolog('Failed to open event ranges json file: %s' %
                      traceback.format_exc())

        # Return the server response (instruction to AthenaMP)
        # Note: the returned message is a string (of a list of dictionaries). If it needs to be converted back to a list, use json.loads(message)

        tolog(
            "Downloading new event ranges for jobId=%s, taskID=%s and jobsetID=%s"
            % (jobId, taskID, jobsetID))

        # message = "[{u'lastEvent': 2, u'LFN': u'mu_E50_eta0-25.evgen.pool.root',u'eventRangeID': u'130-2068634812-21368-1-1', u'startEvent': 2, u'GUID':u'74DFB3ED-DAA7-E011-8954-001E4F3D9CB1'}]"

        if numRanges < 8:
            numRanges = 8
        message = ""

        node = {}
        node['pandaID'] = jobId
        node['jobsetID'] = jobsetID
        node['taskID'] = taskID
        node['nRanges'] = numRanges

        # open connection
        ret = httpConnect(node, url, path=os.getcwd(), mode="GETEVENTRANGES")
        response = ret[1]

        if ret[0]:  # non-zero return code
            message = "Failed to download event range - error code = %d" % (
                ret[0])
        else:
            message = response['eventRanges']

        if message == "" or message == "[]":
            message = "No more events"

        return message
    except:
        tolog("Failed to download event ranges: %s" % traceback.format_exc())
    return None
Пример #10
0
    def getSecurityKey(self, privateKeyName, publicKeyName):
        """ Return the key pair """

        keyName = privateKeyName + "_" + publicKeyName
        if keyName in self.__securityKeys.keys():
            return self.__securityKeys[keyName]
        else:
            try:
                node={}
                node['privateKeyName'] = privateKeyName
                node['publicKeyName'] = publicKeyName
                #host = '%s:%s' % (env['pshttpurl'], str(env['psport'])) # The key pair is not set on other panda server
                url = 'https://pandaserver.cern.ch:25443/server/panda'

                ret = httpConnect(node, url, mode = "GETKEYPAIR", path=os.getcwd())

                StatusCode = str(ret[0])
                data = ret[1] # dictionary
                response = ret[2] # text

                if StatusCode == "0":
                    self.__securityKeys[keyName] = {"publicKey": data["publicKey"], "privateKey": data["privateKey"]}
                    return self.__securityKeys[keyName]

                tolog("!!WARNING!!4444!! Failed to get key from PanDA server:")
                tolog("data = %s" % str(data))

            except:
                _type, value, traceBack = sys.exc_info()
                tolog("!!WARNING!!4445!! Failed to getKeyPair for (%s, %s)" % (privateKeyName, publicKeyName))
                tolog("ERROR: %s %s" % (_type, value))

            tolog("Try to use requests to get key pair")
            try:
                sslCert = self.getSSLCertificate()
                sslKey = sslCert
                host = 'pandaserver.cern.ch:25443'
                path = '/server/panda/getKeyPair'

                import requests
                r = requests.post('https://%s%s' % (host, path),
                                  verify=False,
                                  cert=(sslCert, sslKey),
                                  data=urllib.urlencode(node),
                                  timeout=120)
                if r and r.status_code == 200:
                    dic = cgi.parse_qs(r.text)
                    if dic["StatusCode"][0] == "0":
                        self.__securityKeys[keyName] = {"publicKey": dic["publicKey"][0], "privateKey": dic["privateKey"][0]}
                        return self.__securityKeys[keyName]
            except:
                _type, value, traceBack = sys.exc_info()
                tolog("!!WARNING!!4445!! Failed to getKeyPair for (%s, %s)" % (privateKeyName, publicKeyName))
                tolog("ERROR: %s %s" % (_type, value))

        return {"publicKey": None, "privateKey": None}
Пример #11
0
    def getSecurityKey(self, privateKeyName, publicKeyName):
        """ Return the key pair """

        keyName = privateKeyName + "_" + publicKeyName
        if keyName in self.__securityKeys.keys():
            return self.__securityKeys[keyName]
        else:
            try:
                node={}
                node['privateKeyName'] = privateKeyName
                node['publicKeyName'] = publicKeyName
                #host = '%s:%s' % (env['pshttpurl'], str(env['psport'])) # The key pair is not set on other panda server
                url = 'https://pandaserver.cern.ch:25443/server/panda'

                ret = httpConnect(node, url, mode = "GETKEYPAIR", path=os.getcwd())

                StatusCode = str(ret[0])
                data = ret[1] # dictionary
                response = ret[2] # text

                if StatusCode == "0":
                    self.__securityKeys[keyName] = {"publicKey": data["publicKey"], "privateKey": data["privateKey"]}
                    return self.__securityKeys[keyName]

                tolog("!!WARNING!!4444!! Failed to get key from PanDA server:")
                tolog("data = %s" % str(data))

            except:
                _type, value, traceBack = sys.exc_info()
                tolog("!!WARNING!!4445!! Failed to getKeyPair for (%s, %s)" % (privateKeyName, publicKeyName))
                tolog("ERROR: %s %s" % (_type, value))

            tolog("Try to use requests to get key pair")
            try:
                sslCert = self.getSSLCertificate()
                sslKey = sslCert
                host = 'pandaserver.cern.ch:25443'
                path = '/server/panda/getKeyPair'

                import requests
                r = requests.post('https://%s%s' % (host, path),
                                  verify=False,
                                  cert=(sslCert, sslKey),
                                  data=urllib.urlencode(node),
                                  timeout=120)
                if r and r.status_code == 200:
                    dic = cgi.parse_qs(r.text)
                    if dic["StatusCode"][0] == "0":
                        self.__securityKeys[keyName] = {"publicKey": dic["publicKey"][0], "privateKey": dic["privateKey"][0]}
                        return self.__securityKeys[keyName]
            except:
                _type, value, traceBack = sys.exc_info()
                tolog("!!WARNING!!4445!! Failed to getKeyPair for (%s, %s)" % (privateKeyName, publicKeyName))
                tolog("ERROR: %s %s" % (_type, value))

        return {"publicKey": None, "privateKey": None}
Пример #12
0
    def getNewJob(self, tofile=True):
        try:
            _maxinputsize = pUtil.getMaxInputSize(MB=True)
            _disk = self.__node.disk
            pUtil.tolog("Available WN disk space: %d MB" % (_disk))
            _diskSpace = min(_disk, _maxinputsize)
            pUtil.tolog("Sending disk space %d MB to dispatcher" % (_diskSpace))

            # construct a dictionary for passing to jobDispatcher and get the prodSourceLabel
            jNode, prodSourceLabel, pilotErrorDiag = self.getDispatcherDictionary(_diskSpace, tofile)
            if jNode == {}:
                errorText = "!!FAILED!!1200!! %s" % (pilotErrorDiag)
                pUtil.tolog(errorText, tofile=tofile)
                # send to stderr
                print >> sys.stderr, errorText
                return None, None, pilotErrorDiag

            # get a random server
            url = '%s:%s/server/panda' % (self.__env['pshttpurl'], str(self.__env['psport']))
            pUtil.tolog("Looking for a primary job (contacting server at %s)" % (url), tofile=tofile)

            # make http connection to jobdispatcher
            # format: status, parsed response (data), response
            ret = pUtil.httpConnect(jNode, url, mode = "GETJOB", path = self.__pilotWorkingDir, experiment = self.__thisExperiment) # connection mode is GETJOB

            # get and write the dispatcher status code to file
            StatusCode = str(ret[0])

            # the original response will be put in a file in this function
            data = ret[1] # dictionary
            response = ret[2] # text

            # write the dispatcher exit code to file
            self.writeDispatcherEC(StatusCode)

            if ret[0]: # non-zero return
                return None, None, pUtil.getDispatcherErrorDiag(ret[0])

            if StatusCode != '0':
                pilotErrorDiag = "No job received from jobDispatcher, StatusCode: %s" % (StatusCode)
                pUtil.tolog("%s" % (pilotErrorDiag), tofile=tofile)
                return None, None, pilotErrorDiag

            # test if he attempt number was sent
            try:
                attemptNr = int(data['attemptNr'])
            except Exception,e:
                pUtil.tolog("!!WARNING!!1200!! Failed to get attempt number from server: %s" % str(e), tofile=tofile)
            else:
Пример #13
0
def downloadEventRanges(jobId, jobsetID, taskID, pandaProxySecretKey=None, numRanges=10, url="https://pandaserver.cern.ch:25443/server/panda"):
    """ Download event ranges from the Event Server """

    try:
        # url should be '%s:%s/server/panda' % (env['pshttpurl'], str(env['psport']))

        if os.environ.has_key('EventRanges') and os.path.exists(os.environ['EventRanges']):
            try:
                with open(os.environ['EventRanges']) as json_file:
                    events = json.load(json_file)
                os.rename(os.environ['EventRanges'], os.environ['EventRanges'] + ".loaded")
                tolog(events)
                return json.dumps(events)
            except:
                tolog('Failed to open event ranges json file: %s' % traceback.format_exc())

        # Return the server response (instruction to AthenaMP)
        # Note: the returned message is a string (of a list of dictionaries). If it needs to be converted back to a list, use json.loads(message)

        tolog("Downloading new event ranges for jobId=%s, taskID=%s and jobsetID=%s" % (jobId, taskID, jobsetID))
                
        if pandaProxySecretKey is not None and pandaProxySecretKey != "" :
            return  downloadEventRangesPandaProxy(jobId, jobsetID, pandaProxySecretKey)

        # message = "[{u'lastEvent': 2, u'LFN': u'mu_E50_eta0-25.evgen.pool.root',u'eventRangeID': u'130-2068634812-21368-1-1', u'startEvent': 2, u'GUID':u'74DFB3ED-DAA7-E011-8954-001E4F3D9CB1'}]"

        message = ""

        node = {}
        node['pandaID'] = jobId
        node['jobsetID'] = jobsetID
        node['taskID'] = taskID 
        node['nRanges'] = numRanges

        # open connection
        ret = httpConnect(node, url, path=os.getcwd(), mode="GETEVENTRANGES")
        response = ret[1]

        if ret[0]: # non-zero return code
            message = "Failed to download event range - error code = %d" % (ret[0])
        else:
            message = response['eventRanges']

        if message == "" or message == "[]":
            message = "No more events"

        return message
    except Exception, e:
        tolog("Failed to download event ranges: %s: %s" % (str(e), traceback.format_exc()))
Пример #14
0
def updateEventRange(event_range_id,
                     eventRangeList,
                     jobId,
                     status='finished',
                     os_bucket_id=-1):
    """ Update an list of event ranges on the Event Server """

    tolog("Updating an event range..")

    # PanDA dev server: url = "https://aipanda007.cern.ch:25443/server/panda"
    url = "https://pandaserver.cern.ch:25443/server/panda"
    node = {}
    node['eventRangeID'] = event_range_id

    if os_bucket_id != -1:
        node['objstoreID'] = os_bucket_id
    if eventRangeList != []:
        pass
        # node['cpu'] =  eventRangeList[1]
        # node['wall'] = eventRangeList[2]
    node['eventStatus'] = status

    # open connection
    ret = httpConnect(node, url, path=os.getcwd(), mode="UPDATEEVENTRANGE")
    # response = ret[1]

    if ret[0]:  # non-zero return code
        message = "Server responded with error code = %d" % (ret[0])
    else:
        # is there an instruction in the back channel?
        data = ret[1]
        tolog("data=%s" % str(data))
        from json import loads
        try:
            d = loads(data['Command'])
        except Exception, e:
            tolog("No message found in updateEventRange back channel: %s" %
                  (e))
            message = ""
        else:
Пример #15
0
    def getEventRanges(self, numRanges=2):
        """ Download event ranges from the Event Server """
        tolog("Server: Downloading new event ranges..")

        message = ""
        # url = "https://aipanda007.cern.ch:25443/server/panda"
        url = "https://pandaserver.cern.ch:25443/server/panda"

        node = {}
        node['pandaID'] = self.__job.jobId
        node['jobsetID'] = self.__job.jobsetID
        node['nRanges'] = numRanges

        # open connection
        ret = httpConnect(node, url, path=os.getcwd(), mode="GETEVENTRANGES")
        response = ret[1]

        if ret[0]: # non-zero return code
            message = "Failed to download event range - error code = %d" % (ret[0])
            tolog(message)
            return []
        else:
            message = response['eventRanges']
            return json.loads(message)
Пример #16
0
    def getNewJob(self, tofile=True, nJobs=1):
        try:
            _maxinputsize = pUtil.getMaxInputSize(MB=True)
            _disk = self.__node.disk
            pUtil.tolog("Available WN disk space: %d MB" % (_disk))
            _diskSpace = min(_disk, _maxinputsize)
            pUtil.tolog("Sending disk space %d MB to dispatcher" % (_diskSpace))

            # construct a dictionary for passing to jobDispatcher and get the prodSourceLabel
            jNode, prodSourceLabel, pilotErrorDiag = self.getDispatcherDictionary(_diskSpace, tofile, nJobs)
            if jNode == {}:
                errorText = "!!FAILED!!1200!! %s" % (pilotErrorDiag)
                pUtil.tolog(errorText, tofile=tofile)
                # send to stderr
                print >> sys.stderr, errorText
                return None, None, pilotErrorDiag

            # get a random server
            url = '%s:%s/server/panda' % (self.__env['pshttpurl'], str(self.__env['psport']))
            pUtil.tolog("Looking for a primary job (contacting server at %s)" % (url), tofile=tofile)

            # make http connection to jobdispatcher
            # format: status, parsed response (data), response
            ret = pUtil.httpConnect(jNode, url, mode = "GETJOB", path = self.__pilotWorkingDir, experiment = self.__thisExperiment) # connection mode is GETJOB

            # get and write the dispatcher status code to file
            StatusCode = str(ret[0])

            # the original response will be put in a file in this function
            data = ret[1] # dictionary
            response = ret[2] # text

            # write the dispatcher exit code to file
            self.writeDispatcherEC(StatusCode)

            if ret[0]: # non-zero return
                return None, None, pUtil.getDispatcherErrorDiag(ret[0])

            if StatusCode != '0':
                pilotErrorDiag = "No job received from jobDispatcher, StatusCode: %s" % (StatusCode)
                pUtil.tolog("%s" % (pilotErrorDiag), tofile=tofile)
                return None, None, pilotErrorDiag

            # backup response (will be copied to workdir later)
            self.backupDispatcherResponse(response, tofile)

            if not data.has_key("jobs"):
                jobs = [data]
            else:
                jobs = data['jobs']

            newJobs = []
            newJobsData = {}
            for job in jobs:
                # test if he attempt number was sent
                try:
                    attemptNr = int(job['attemptNr'])
                except Exception,e:
                    pUtil.tolog("!!WARNING!!1200!! Failed to get attempt number from server: %s" % str(e), tofile=tofile)
                else:
                    pUtil.tolog("Attempt number from server: %d" % attemptNr)

                # should there be a delay before setting running state?
                try:
                    nSent = int(job['nSent'])
                except Exception,e:
                    nSent = 0
                else: