Esempio n. 1
0
def getIDs():
    """
    Get IDs from current request context.

    IDs are taken from 'id' url parameter. Exceptions for getJobsFromList
    are handled by callers so they can generate appropriate responses.
    """
    ids = request.args.get('id', default=[])
    if ids:
        return jobmgr.getIDsFromList(ids)
    else:
        return []
Esempio n. 2
0
def main():
    # parse arguments
    parser = argparse.ArgumentParser(description='Get jobs from aCT')
    parser.add_argument('-a',
                        '--all',
                        action='store_true',
                        help='all jobs that match other criteria')
    parser.add_argument('-j',
                        '--jobs',
                        default='',
                        help='comma separated list of job IDs or ranges')
    parser.add_argument(
        '-f',
        '--find',
        default='',
        help='get only jobs with matching (sub)string in their name')
    parser.add_argument('-s',
                        '--state',
                        default='',
                        help='get only jobs with certain state')
    parser.add_argument('-v',
                        '--verbose',
                        action='store_true',
                        help='show more information')
    parser.add_argument('-p',
                        '--proxy',
                        default=None,
                        help='custom path to proxy certificate')
    parser.add_argument('-n',
                        '--no-clean',
                        action='store_true',
                        help='do not clean jobs')

    clicommon.showHelpOnCommandOnly(parser)

    args = parser.parse_args()

    # logging
    logFormat = "[%(asctime)s] [%(filename)s:%(lineno)d] [%(levelname)s] - %(message)s"
    if args.verbose:
        logging.basicConfig(format=logFormat,
                            level=logging.DEBUG,
                            stream=sys.stdout)
    else:
        logging.basicConfig(format=logFormat,
                            level=logging.DEBUG,
                            filename=os.devnull)

    # create a list of jobs to work on
    if args.all:
        jobs = []  # empty means all jobs
    elif args.jobs:
        try:
            jobs = jobmgr.getIDsFromList(args.jobs)
        except InvalidJobRangeError as e:
            print("error: range '{}' is not a valid range".format(e.jobRange))
            sys.exit(2)
        except InvalidJobIDError as e:
            print("error: ID '{}' is not a valid ID".format(e.jobid))
            sys.exit(3)
    else:
        print("error: no jobs specified (use -a or -j)")
        sys.exit(10)

    # get proxy ID given proxy
    proxyid = clicommon.getProxyIdFromProxy(args.proxy)

    # get job info
    manager = jobmgr.JobManager()
    try:
        results = manager.getJobs(proxyid, jobs, args.state, args.find)
    except TmpConfigurationError:
        print('error: tmp directory not configured')
        sys.exit(5)

    if not results.jobdicts:
        print('no jobs to get')
        sys.exit(0)

    # copy job results
    dontRemove = []
    for result in results.jobdicts:
        try:
            if result['dir']:  # if there are job results in tmp
                dst_dirname = os.path.basename(os.path.normpath(
                    result['name']))
                dstdir = getLocalDir(dst_dirname)
                shutil.copytree(result['dir'], dstdir)
                print('Results stored at: {}'.format(dstdir))
            else:
                raise NoJobDirectoryError(result['dir'])

        except NoJobDirectoryError as e:
            print('error: tmp results directory {} does not exist'.format(
                e.jobdir))
        except TargetDirExistsError as e:
            print('error: job destination {} already exists'.format(e.dstdir))
            # don't clean job that could not be removed
            dontRemove.append(result['id'])

    # delete jobs that should not be removed from results
    for jobid in dontRemove:
        for result in results.jobdicts:
            if result['id'] == jobid:
                jobix = results.clientIDs.index(result['id'])
                del results.clientIDs[jobix]
                del results.arcIDs[jobix]
                del results.jobdicts[jobix]

    # clean jobs
    if not args.no_clean:
        manager.forceCleanJobs(results)
Esempio n. 3
0
def main():
    # parse arguments
    parser = argparse.ArgumentParser(description='Kill jobs')
    parser.add_argument('-a',
                        '--all',
                        action='store_true',
                        help='all jobs that match other criteria')
    parser.add_argument('-j',
                        '--jobs',
                        default='',
                        help='comma separated list of job IDs or ranges')
    parser.add_argument(
        '-f',
        '--find',
        default='',
        help='get only jobs with matching (sub)string in their name')
    parser.add_argument('-s',
                        '--state',
                        default='',
                        help='get only jobs with certain state')
    parser.add_argument('-v',
                        '--verbose',
                        action='store_true',
                        help='show more information')
    parser.add_argument('-p',
                        '--proxy',
                        default=None,
                        help='custom path to proxy certificate')

    clicommon.showHelpOnCommandOnly(parser)

    args = parser.parse_args()

    # logging
    logFormat = "[%(asctime)s] [%(filename)s:%(lineno)d] [%(levelname)s] - %(message)s"
    if args.verbose:
        logging.basicConfig(format=logFormat,
                            level=logging.DEBUG,
                            stream=sys.stdout)
    else:
        logging.basicConfig(format=logFormat,
                            level=logging.DEBUG,
                            filename=os.devnull)

    # create a list of jobs to work on
    if args.all:
        jobs = []  # empty means all jobs
    elif args.jobs:
        try:
            jobs = jobmgr.getIDsFromList(args.jobs)
        except InvalidJobRangeError as e:
            print("error: range '{}' is not a valid range".format(e.jobRange))
            sys.exit(2)
        except InvalidJobIDError as e:
            print("error: ID '{}' is not a valid ID".format(e.jobid))
            sys.exit(3)
    else:
        print("error: no jobs specified (use -a or -j)")
        sys.exit(10)

    # get proxy ID given proxy
    proxyid = clicommon.getProxyIdFromProxy(args.proxy)

    # kill jobs
    manager = jobmgr.JobManager()
    numKilled = manager.killJobs(proxyid, jobs, args.state, args.find)
    print('Jobs killed: {}'.format(numKilled))
Esempio n. 4
0
def main():
    # parse arguments
    parser = argparse.ArgumentParser(description='Get job info from aCT')
    parser.add_argument('-a',
                        '--all',
                        action='store_true',
                        help='all jobs that match other criteria')
    parser.add_argument(
        '-j',
        '--jobs',
        default='',
        help='ID/range(id1-id2;id1<id2)/comma separated list of IDs/ranges')
    parser.add_argument(
        '-f',
        '--find',
        default='',
        help='get only jobs with matching (sub)string in their name')
    parser.add_argument('-s',
                        '--state',
                        default='',
                        help='get only jobs with certain state')
    parser.add_argument('-n',
                        '--name',
                        default='',
                        help='get only jobs with given name')
    parser.add_argument('-v',
                        '--verbose',
                        action='store_true',
                        help='show more information')
    parser.add_argument('-p',
                        '--proxy',
                        default=None,
                        help='custom path to proxy certificate')

    # arguments passed directly to arccat
    parser.add_argument('-o',
                        '--stdout',
                        action='store_true',
                        help='show the stdout of the job (default)',
                        default=True)
    parser.add_argument('-e',
                        '--stderr',
                        action='store_true',
                        help='show the stderr of the job')
    #parser.add_argument('-l', '--joblog', action='store_true',
    #        help='show A-REX\'s error log of the job')
    #parser.add_argument('-P', '--listplugins', action='store_true',
    #        help='list the available plugins')
    #parser.add_argument('-t', '--timeout', type=int, nargs=1,
    #        help='timeout in seconds (default 20)', default=20)

    clicommon.showHelpOnCommandOnly(parser)

    args = parser.parse_args()

    # logging
    logFormat = "[%(asctime)s] [%(filename)s:%(lineno)d] [%(levelname)s] - %(message)s"
    if args.verbose:
        logging.basicConfig(format=logFormat,
                            level=logging.DEBUG,
                            stream=sys.stdout)
    else:
        logging.basicConfig(format=logFormat,
                            level=logging.DEBUG,
                            filename=os.devnull)

    # get column names from database
    manager = jobmgr.JobManager()

    # create a list of jobs to work on
    if args.all:
        jobs = []  # empty means all jobs
    elif args.jobs:
        try:
            jobs = jobmgr.getIDsFromList(args.jobs)
        except InvalidJobRangeError as e:
            print("error: range '{}' is not a valid range".format(e.jobRange))
            sys.exit(2)
        except InvalidJobIDError as e:
            print("error: ID '{}' is not a valid ID".format(e.jobid))
            sys.exit(3)
    else:
        print("error: no jobs specified (use -a or -j)")
        sys.exit(10)

    proxyid = clicommon.getProxyIdFromProxy(args.proxy)

    # get ARC job IDs of jobs that match filters
    try:
        jobdicts = manager.getJobStats(proxyid,
                                       jobs,
                                       args.state,
                                       args.find,
                                       clicols=[],
                                       arccols=["JobID", "StdOut", "StdErr"],
                                       jobname=args.name)
    except Exception as e:
        print('error: {}'.format(str(e)))
        sys.exit(9)

    if not jobdicts:  # no jobs so just exit
        print('no jobs found that fit given filters')
        sys.exit(0)

    for job in jobdicts:
        url = job["a_JobID"] + "/"
        if args.stderr:
            url += job["a_StdErr"]
        elif args.stdout:
            url += job["a_StdOut"]
        subprocess.run(["arccp", url, "-"])
Esempio n. 5
0
def main():
    # parse arguments
    parser = argparse.ArgumentParser(description='Get job info from aCT')
    parser.add_argument('-a',
                        '--all',
                        action='store_true',
                        help='all jobs that match other criteria')
    parser.add_argument(
        '-j',
        '--jobs',
        default='',
        help='ID/range(id1-id2;id1<id2)/comma separated list of IDs/ranges')
    parser.add_argument(
        '-f',
        '--find',
        default='',
        help='get only jobs with matching (sub)string in their name')
    parser.add_argument('-s',
                        '--state',
                        default='',
                        help='get only jobs with certain state')
    parser.add_argument('-v',
                        '--verbose',
                        action='store_true',
                        help='show more information')
    parser.add_argument('-p',
                        '--proxy',
                        default=None,
                        help='custom path to proxy certificate')
    parser.add_argument('--arc-cols',
                        default='JobID,State,arcstate',
                        help='columns from ARC table that should be fetched')
    parser.add_argument(
        '--client-cols',
        default='id,jobname',
        help='columns from client table that should be fetched')
    parser.add_argument('--get-cols',
                        action='store_true',
                        help='print all available column names')

    clicommon.showHelpOnCommandOnly(parser)

    args = parser.parse_args()

    # logging
    logFormat = "[%(asctime)s] [%(filename)s:%(lineno)d] [%(levelname)s] - %(message)s"
    if args.verbose:
        logging.basicConfig(format=logFormat,
                            level=logging.DEBUG,
                            stream=sys.stdout)
    else:
        logging.basicConfig(format=logFormat,
                            level=logging.DEBUG,
                            filename=os.devnull)

    # get column names from database
    manager = jobmgr.JobManager()
    if args.get_cols:
        clientCols = manager.getClientColumns()
        arcCols = manager.getArcColumns()
        print('client cols:', end=' ')
        for col in clientCols:
            print(col, end=' ')
        print()
        print('arc cols:', end=' ')
        for col in arcCols:
            print(col, end=' ')
        print()
        sys.exit(0)

    # create a list of jobs to work on
    if args.all:
        jobs = []  # empty means all jobs
    elif args.jobs:
        try:
            jobs = jobmgr.getIDsFromList(args.jobs)
        except InvalidJobRangeError as e:
            print("error: range '{}' is not a valid range".format(e.jobRange))
            sys.exit(2)
        except InvalidJobIDError as e:
            print("error: ID '{}' is not a valid ID".format(e.jobid))
            sys.exit(3)
    else:
        print("error: no jobs specified (use -a or -j)")
        sys.exit(10)

    # create column lists
    if not args.client_cols:
        clicols = []
    else:
        clicols = args.client_cols.split(',')
    if not args.arc_cols:
        arccols = []
    else:
        arccols = args.arc_cols.split(',')

    # get proxy ID given proxy
    proxyid = clicommon.getProxyIdFromProxy(args.proxy)

    # get information
    try:
        jobdicts = manager.getJobStats(proxyid,
                                       jobs,
                                       args.state,
                                       args.find,
                                       clicols=clicols,
                                       arccols=arccols)
    except Exception as e:
        print('error: {}'.format(str(e)))
        sys.exit(9)

    if not jobdicts:  # no jobs so just exit
        sys.exit(0)

    # For each column, determine biggest sized value so that output can
    # be nicely formatted.
    colsizes = {}
    for job in jobdicts:
        for key, value in job.items():
            # All keys have a letter and underscore prepended, which is not
            # used when printing
            colsize = max(len(str(key[2:])), len(str(value)))
            try:
                if colsize > colsizes[key]:
                    colsizes[key] = colsize
            except KeyError:
                colsizes[key] = colsize

    # Print table header
    for col in clicols:
        print('{:<{width}}'.format(col, width=colsizes['c_' + col]), end=' ')
    for col in arccols:
        print('{:<{width}}'.format(col, width=colsizes['a_' + col]), end=' ')
    print()
    line = ''
    for value in colsizes.values():
        line += '-' * value
    line += '-' * (len(colsizes) - 1)
    print(line)

    # Print jobs
    for job in jobdicts:
        for col in clicols:
            fullKey = 'c_' + col
            txt = job.get(fullKey)
            # just in case the value is a bunch of whitespace
            # TODO: This (str(txt)) might not be a general fix; it is a direct
            #       fix for the problem encountered with
            #       datetime.datetime object for 'created' field that
            #       has to be converted to a string.
            #       The same fix is used for arccols below.
            # TODO: This fix assumes that all job fields are properly
            #       convertible to string. Is that really so?
            if not txt or str(txt).strip() == '':  # short circuit important!
                txt = "''"
            print('{:<{width}}'.format(txt, width=colsizes[fullKey]), end=' ')
        for col in arccols:
            fullKey = 'a_' + col
            txt = job.get(fullKey)
            # just in case the value is a bunch of whitespace
            if not txt or str(txt).strip() == '':  # short circuit important!
                txt = "''"
            print('{:<{width}}'.format(str(txt), width=colsizes[fullKey]),
                  end=' ')
        print()