Пример #1
0
    def retrieveShortLogs(self, webdir, proxyfilename):
        self.logger.info("Retrieving...")
        success = []
        failed = []
        for _, jobid in self.options.jobids:
            # We don't know a priori how many retries the job had. So we start with retry 0
            # and increase it by 1 until we are unable to retrieve a log file (interpreting
            # this as the fact that we reached the highest retry already).
            retry = 0
            succeded = True
            while succeded:
                filename = 'job_out.%s.%s.txt' % (jobid, retry)
                url = webdir + '/' + filename
                httpCode = curlGetFileFromURL(url, self.dest + '/' + filename, proxyfilename, logger=self.logger)
                if httpCode == 200:
                    self.logger.info('Retrieved %s' % (filename))
                    success.append(filename)
                    retry += 1  # To retrieve retried job log, if there is any.
                elif httpCode == 404:
                    succeded = False
                    # Ignore the exception if the HTTP status code is 404. Status 404 means file
                    # not found (see http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html). File
                    # not found error is expected, since we try all the job retries.
                else:
                    # something went wront in trying to retrieve a file which was expected to be there
                    succeded = False
                    failed.append(filename)

        return failed, success
Пример #2
0
    def getInputFiles(self):
        """ Get the InputFiles.tar.gz and extract the necessary files
        """
        taskname = self.cachedinfo['RequestName']

        #Get task status from the task DB
        self.logger.debug("Getting status from he DB")
        server = self.crabserver
        crabDBInfo, _, _ = server.get(api='task',
                                      data={
                                          'subresource': 'search',
                                          'workflow': taskname
                                      })
        status = getColumn(crabDBInfo, 'tm_task_status')
        self.destination = getColumn(crabDBInfo, 'tm_asyncdest')

        inputsFilename = os.path.join(os.getcwd(), 'InputFiles.tar.gz')
        if status == 'UPLOADED':
            filecacheurl = getColumn(crabDBInfo, 'tm_cache_url')
            ufc = CRABClient.Emulator.getEmulator('ufc')({
                'endpoint': filecacheurl,
                "pycurl": True
            })
            self.logger.debug(
                "Downloading and extracting 'dry-run-sandbox.tar.gz' from %s" %
                filecacheurl)
            ufc.downloadLog('dry-run-sandbox.tar.gz',
                            output=os.path.join(os.getcwd(),
                                                'dry-run-sandbox.tar.gz'))
            with tarfile.open('dry-run-sandbox.tar.gz') as tf:
                tf.extractall()
        elif status == 'SUBMITTED':
            webdir = getProxiedWebDir(crabserver=self.crabserver,
                                      task=taskname,
                                      logFunction=self.logger.debug)
            if not webdir:
                webdir = getColumn(crabDBInfo, 'tm_user_webdir')
            self.logger.debug("Downloading 'InputFiles.tar.gz' from %s" %
                              webdir)
            httpCode = curlGetFileFromURL(webdir + '/InputFiles.tar.gz',
                                          inputsFilename,
                                          self.proxyfilename,
                                          logger=self.logger)
            if httpCode != 200:
                self.logger.errror(
                    "Failed to download 'InputFiles.tar.gz' from %s", webdir)
        else:
            raise ClientException(
                'Can only execute jobs from tasks in status SUBMITTED or UPLOADED. Current status is %s'
                % status)

        for name in [
                inputsFilename, 'CMSRunAnalysis.tar.gz', 'sandbox.tar.gz'
        ]:
            with tarfile.open(name) as tf:
                tf.extractall()
Пример #3
0
    def getInputDatasetLumis(self, inputDataset, userWebDirURL):
        """
        What the input dataset had in DBS when the task was submitted

        Get the lumis (and the lumis split across files) in the input dataset. Files
        containing this information were created at data discovery time and then
        copied to the schedd.
        """
        res = {}
        res['inputDataset'] = {'lumis': {}, 'duplicateLumis': {}}
        if inputDataset and userWebDirURL:
            url = userWebDirURL + "/input_dataset_lumis.json"
            filename = os.path.join(self.requestarea,
                                    'results/input_dataset_lumis.json')
            ## Retrieve the lumis in the input dataset.
            httpCode = curlGetFileFromURL(url,
                                          filename,
                                          self.proxyfilename,
                                          logger=self.logger)
            if httpCode == 200:
                with open(filename) as fd:
                    res['inputDataset']['lumis'] = json.load(fd)
            else:
                self.logger.error("Failed to retrieve input dataset lumis.")

            url = userWebDirURL + "/input_dataset_duplicate_lumis.json"
            filename = os.path.join(
                self.requestarea, 'results/input_dataset_duplicate_lumis.json')
            ## Retrieve the lumis split across files in the input dataset.
            httpCode = curlGetFileFromURL(url,
                                          filename,
                                          self.proxyfilename,
                                          logger=self.logger)
            if httpCode == 200:
                with open(filename) as fd:
                    res['inputDataset']['duplicateLumis'] = json.load(fd)
            else:
                self.logger.error(
                    "Failed to retrieve input dataset duplicate lumis.")

        return res
Пример #4
0
    def getLumisToProcess(self, userWebDirURL, jobs, workflow):
        """
        What each job was requested to process

        Get the lumis to process by each job in the workflow.
        """
        res = {}
        if userWebDirURL:
            url = userWebDirURL + "/run_and_lumis.tar.gz"
            tarFilename = os.path.join(self.requestarea,
                                       'results/run_and_lumis.tar.gz')
            httpCode = curlGetFileFromURL(url,
                                          tarFilename,
                                          self.proxyfilename,
                                          logger=self.logger)
            if httpCode == 200:
                # Not using 'with tarfile.open(..) as t:' syntax because
                # the tarfile module only received context manager protocol support
                # in python 2.7, whereas CMSSW_5_* uses python 2.6 and breaks here.
                tarball = tarfile.open(tarFilename)
                for jobid in jobs:
                    filename = "job_lumis_%s.json" % (jobid)
                    try:
                        member = tarball.getmember(filename)
                    except KeyError:
                        self.logger.warning(
                            "File %s not found in run_and_lumis.tar.gz for task %s"
                            % (filename, workflow))
                    else:
                        fd = tarball.extractfile(member)
                        try:
                            res[str(jobid)] = json.load(fd)
                        finally:
                            fd.close()
                tarball.close()
            else:
                self.logger.error(
                    "Failed to retrieve input dataset duplicate lumis.")

        return res
Пример #5
0
    def run(self, filecacheurl=None):
        """
        Override run() for JobType
        """

        taskDict, webdir = self.getTaskDict()
        addoutputfiles = literal_eval(getColumn(taskDict, 'tm_outfiles'))
        tfileoutfiles = literal_eval(getColumn(taskDict, 'tm_tfile_outfiles'))
        edmoutfiles = literal_eval(getColumn(taskDict, 'tm_edm_outfiles'))
        jobarch = getColumn(taskDict, 'tm_job_arch')
        jobsw = getColumn(taskDict, 'tm_job_sw')

        sandboxFilename = os.path.join(self.workdir, 'sandbox.tar.gz')
        curlGetFileFromURL(webdir + '/sandbox.tar.gz', sandboxFilename,
                           self.proxyfilename)

        configArguments = {
            'addoutputfiles': addoutputfiles,
            'tfileoutfiles': tfileoutfiles,
            'edmoutfiles': edmoutfiles,
            'jobarch': jobarch,
            'jobsw': jobsw,
        }

        # Maybe the user wnat to change the dataset
        if getattr(self.config.Data, 'inputDataset', None):
            configArguments['inputdata'] = self.config.Data.inputDataset

        ufc = CRABClient.Emulator.getEmulator('ufc')({
            'endpoint': filecacheurl,
            "pycurl": True
        })
        result = ufc.upload(sandboxFilename,
                            excludeList=NEW_USER_SANDBOX_EXCLUSIONS)
        if 'hashkey' not in result:
            self.logger.error("Failed to upload source files: %s" %
                              str(result))
            raise CachefileNotFoundException

        configArguments['cacheurl'] = filecacheurl
        configArguments['cachefilename'] = "%s.tar.gz" % str(result['hashkey'])

        # Upload list of user-defined input files to process as the primary input
        userFilesList = getattr(self.config.Data, 'userInputFiles', None)
        if userFilesList:
            self.logger.debug(
                "Attaching list of user-specified primary input files.")
            userFilesList = map(string.strip, userFilesList)
            userFilesList = [file for file in userFilesList if file]
            if len(userFilesList) != len(set(userFilesList)):
                msg = "%sWarning%s:" % (colors.RED, colors.NORMAL)
                msg += " CRAB configuration parameter Data.userInputFiles contains duplicated entries."
                msg += " Duplicated entries will be removed."
                self.logger.warning(msg)
            configArguments['userfiles'] = set(userFilesList)
            configArguments['primarydataset'] = getattr(
                self.config.Data, 'outputPrimaryDataset', 'CRAB_UserFiles')

        lumi_mask_name = getattr(self.config.Data, 'lumiMask', None)
        lumi_list = None
        if lumi_mask_name:
            self.logger.debug("Attaching lumi mask %s to the request" %
                              (lumi_mask_name))
            try:
                lumi_list = getLumiList(lumi_mask_name, logger=self.logger)
            except ValueError as ex:
                msg = "%sError%s:" % (colors.RED, colors.NORMAL)
                msg += " Failed to load lumi mask %s : %s" % (lumi_mask_name,
                                                              ex)
                raise ConfigurationException(msg)
        run_ranges = getattr(self.config.Data, 'runRange', None)
        if run_ranges:
            run_ranges_is_valid = re.match('^\d+((?!(-\d+-))(\,|\-)\d+)*$',
                                           run_ranges)
            if run_ranges_is_valid:
                run_list = getRunList(run_ranges)
                if lumi_list:
                    lumi_list.selectRuns(run_list)
                    if not lumi_list:
                        msg = "Invalid CRAB configuration: The intersection between the lumi mask and the run range is null."
                        raise ConfigurationException(msg)
                else:
                    if len(run_list) > 50000:
                        msg = "CRAB configuration parameter Data.runRange includes %s runs." % str(
                            len(run_list))
                        msg += " When Data.lumiMask is not specified, Data.runRange can not include more than 50000 runs."
                        raise ConfigurationException(msg)
                    lumi_list = LumiList(runs=run_list)
            else:
                msg = "Invalid CRAB configuration: Parameter Data.runRange should be a comma separated list of integers or (inclusive) ranges. Example: '12345,99900-99910'"
                raise ConfigurationException(msg)
        if lumi_list:
            configArguments['runs'] = lumi_list.getRuns()
            ## For each run we encode the lumis as a string representing a list of integers: [[1,2],[5,5]] ==> '1,2,5,5'
            lumi_mask = lumi_list.getCompactList()
            configArguments['lumis'] = [
                str(reduce(lambda x, y: x + y,
                           lumi_mask[run]))[1:-1].replace(' ', '')
                for run in configArguments['runs']
            ]

        configArguments['jobtype'] = 'Analysis'

        return sandboxFilename, configArguments