#! /usr/bin/env python # Copyright (c) Members of the EGEE Collaboration. 2004. # See http://www.eu-egee.org/partners/ for details on the copyright # holders. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """ *************************************************************************** filename : glite-wms-job-status author : Alessandro Maraschini, Alvise Dorigo email : alvise.dorigo@pd.infn.it copyright : (C) 2004 by DATAMAT *************************************************************************** // // $Id$ // """ # Initial Check: try to find UI configuration file path import sys import os.path import os import re try: path=os.environ['EMI_UI_CONF']+"/usr" except: path="/usr" # append lib/lib64 directories to search path for app in ["lib","lib64"]: for bpp in ["",os.sep+"python"]: libPath=path+os.sep+app+bpp sys.path.append(libPath) import wmsui_utils import wmsui_checks import time #common methods from glite_wmsui_LbWrapper import Status import wmsui_api from wmsui_utils import errMsg from wmsui_utils import dbgMsg from wmsui_utils import exit from signal import * # Catch user interrupt ^C signal(SIGINT, wmsui_utils.ctc) def checkExclude(includes, excludes): if includes and excludes: errMsg('Error','UI_ARG_EXCLUSIVE', "--status" , "--exclude") return [1,0,0] OPT= "--status" #index of lud in the actual list for ludes in [includes , excludes]: i = 0 for lud in ludes: try: ludes[i]= int(lud) if ludes[i] >=wmsui_api.STATE_CODE_MAX: errMsg ( "Error" , "UI_ARG_OUT_OF_LIMIT" , OPT ) return [1,0,0] except ValueError: try: #Is not an integer, could be a string repr ludes[i] =wmsui_api.states_codes.index(lud.capitalize()) except ValueError: errMsg('Error', "UI_ARG_MISMATCH" , OPT) return [1,0,0] i+=1 OPT= "--exclude" return 0 , includes ,excludes ############################################ # I PART: INIZIALIZING VARIABLES AND CHECKS ############################################ #initialize some usefull variable json = False; sys_exit =0 prgname="glite-wms-job-status" wmsui_utils.err_log_clean(prgname) wmsui_checks.check_prefix() MSG_STATUS="=status=" MSG_EXCLUDE="=exclude=" error_message= wmsui_utils.createErrMsg( prgname , "job Id(s)",["help","version","@","all", "=input$","verbosity=","from=","to=",\ "=config$" ,"user-tag=", MSG_STATUS , MSG_EXCLUDE, "vo=","=output$","noint","nonodes" , "debug", "logfile$","json"]) argv=sys.argv wmsui_checks.check_noint(sys.argv) #================================= # Option check #================================= if (len(argv) < 2): wmsui_utils.print_help(error_message) exit(1) err, options,values,extra = wmsui_checks.checkOpt(argv[1:] , "i:c:o:v:s:e:" ,["help","version","all", "input=","verbosity=", \ "from=","to=","config=" ,"user-tag=", "status=","exclude=","vo=","output=","noint","nonodes" , "debug" , "logfile=","json"] ) if ("--json" in options): json = True; if ("--help" in options): print "\n" + prgname +" full help" wmsui_utils.printFullHelp(error_message, wmsui_checks.info.noint) exit(0) elif ("--version" in options): print "Job Submission User Interface version " + wmsui_utils.info.version exit(0) elif err: wmsui_utils.print_help(error_message) exit(1) #Checking option syntax """ -input/jobId sintax: """ ext= (len(extra) >0) res=( "--vo" in options or "--all" in options or "--from" in options or "--to" in options or "--user-tag" in options \ or "-s" in options or "-e" in options \ or "--status" in options or "--exclude" in options )\ + ext + ( ("-i" in options) or ("--input" in options) ) if res == 0: #no input/job/all specified wmsui_utils.print_help(error_message) exit(1) #Valued Option check: noNodes = ("--nonodes" in options) try: inFile = wmsui_utils.findVal( ["--input" , "-i" ], options, values) outFile = wmsui_utils.findVal(["--output" , "-o" ], options, values) gname = wmsui_utils.findVal(["--config" , "-c" ], options, values) virtualOrg = wmsui_utils.findVal(["--vo" ], options, values) logpath = wmsui_utils.findVal( ["--logfile"], options, values) level = wmsui_utils.findVal(["--verbosity", "-v"], options, values) fromT= wmsui_utils.findVal( ["--from"], options, values) toT= wmsui_utils.findVal( ["--to"], options, values) userTags = wmsui_utils.findVal(["--user-tag"], options, values, 1) includes = wmsui_utils.findVal(["--status", "-s"], options, values, 1) excludes = wmsui_utils.findVal(["--exclude","-e"], options, values, 1) except SyntaxError,rep: errMsg('Error','UI_REPEATED_OPT',rep[0]) wmsui_utils.print_help(error_message) exit(1) # UI Configuration file Check voName = wmsui_checks.checkConf (gname, virtualOrg, logpath) err ,includes , excludes = checkExclude (includes , excludes) if err: wmsui_utils.print_help(error_message) exit(1) if level: try: level = int(level) except: errMsg('Error','UI_ARG_MISMATCH', level) wmsui_utils.print_help(error_message) exit(1) if (level >3): errMsg('Error','UI_ARG_OUT_OF_LIMIT', level) wmsui_utils.print_help(error_message) exit(1) else: level = wmsui_utils.info.confAd.getIntValue ("DefaultStatusLevel") if level: try: level = int( level[0] ) except: level=1 else: level = 1 try: fromT , toT = wmsui_checks.checkFromTo (fromT , toT) except: wmsui_utils.print_help(error_message) wmsui_utils.exit(1) #================================= # USER TAGS #================================= uTags ={} if userTags: try: for tag in userTags: attr , value = tag.split("=") if uTags.has_key(attr): errMsg('Error','UI_REPEATED_OPT',"--user-tag ("+attr +")" ) wmsui_utils.print_help(error_message) exit(1) uTags[attr]=value except ValueError: errMsg('Error','UI_ARG_MISMATCH', "--user-tag") wmsui_utils.print_help(error_message) exit(1) #================================= # jobID check #================================= if json == True: print "{ \"result\": \"success\"", jobs= [] if extra: jobs = wmsui_api.getJobIdfromList ( json, extra ) if len (jobs) != len(extra): sys_exit= -1 elif inFile : sys_exit , jobs, strjobs =wmsui_api.getJobIdfromFile( json, inFile ) if sys_exit and jobs and (not wmsui_utils.info.noint): answ=wmsui_utils.questionYN("Do you wish to continue?") if not answ: print "bye" exit(1) if jobs and (not wmsui_utils.info.noint): jobs = wmsui_api.selectJobId( jobs, strjobs) if not jobs: if sys_exit: # Unable to parse /find specified JobId if json == False: errMsg('Error','UI_WRONG_JOBID_ALL') else: print "}" exit(1) #Define the error/warning message: em="Error" # check -output option TBremoved = 0 if (outFile): err,outFile,TBremoved=wmsui_checks.check_outFile(outFile) if err or (not outFile): exit(err) # Check if an output file has been specified and if it already exists if outFile and TBremoved: # The file has to be removed os.remove(outFile) #Check proxy if wmsui_checks.check_proxy(): exit(1) atLeastOneSuccess = 0 st = 0 #================================= # --all check #================================= if "--all" in options: issuer = wmsui_utils.info.issuer else: issuer = "" # Initialise the output message message = "" # Check if LB Query has been requested LBapproach = includes or excludes or userTags or issuer or fromT or toT # Retrieve the results according to the parameters if LBapproach: print "\n*** LB APPROACH\n" # Query all the status statesArray = wmsui_api.queryStates(jobs, voName, includes, excludes, uTags, issuer, fromT, toT, level) if statesArray: # If this flag is set to 1 then the query might haven't found any results (but nevertheless no exception raised) atLeastOneSuccess = 1 for job in jobs: #print "**** CHECKING JOB [" + job.jobid + "]" if job.jobid in statesArray: wmsui_utils.print_message(False, outFile, statesArray[job.jobid].printStatus(json, noNodes)) st+=1 else: wmsui_utils.print_message(False, wmsui_utils.info.logFile, "Warning: no matching information for job id: " + job.jobid) else: # //print "\n*** NO LB APPROACH\n" # Set the error level to warning in case of more than one job if len (jobs)>1: em="Warning" # Get the status for all the Job ID # if json == True: # print "{ \"result\": \"success\", ", messageList = list() for jobid in jobs: #print "**** CHECKING JOB [" + jobid.jobid + "]" p = re.compile('^https://.+:[0-9]+/.+'); m = p.match(jobid.jobid) if not m: #print "DONT MATCH!!!" messageList.append("\"" + jobid.jobid + "\": \"JOBID CONTAINS WRONG FORMAT: SHOULD BE https://:/\"" ) pass else: #print "GETTING STATUS..." dbgMsg ("Job::getStatus" , jobid.jobid, level) apiMsg = "" try: # Get the status of the current Job jobStatus = wmsui_api.getStatus(jobid, level) # Check if a status has been found if jobStatus: # Print the Status #wmsui_utils.print_message(json, outFile, jobStatus.printStatus(json, noNodes)) messageList.append( jobStatus.printStatus(json, noNodes) ) atLeastOneSuccess = 1 st+=1 except Exception, apiMsg: # Print the error message on log file #wmsui_utils.print_message(json, wmsui_utils.info.logFile , "\n") if json == True: errmex = apiMsg.args[0].lower() print "\n\n********** errmex=["+errmex+"]\n\n" if errmex.find("no matching jobs found") > -1: messageList.append( "\"" + jobid.jobid + "\": \"JOB NOT FOUND\"" ) if errmex.find("no route to host") > -1: messageList.append( "\"" + jobid.jobid + "\": \"JOBID CONTAINS WRONG ENDPOINT OR ENDPOINT CANNOT BE CONTACTED\"" ) if errmex.find("connection timed out") > -1: messageList.append( "\"" + jobid.jobid + "\": \"JOBID CONTAINS WRONG ENDPOINT OR ENDPOINT CANNOT BE CONTACTED (CONNECTION TIMEOUT)\"" ) if errmex.find("connection refused") > -1: messageList.append( "\"" + jobid.jobid + "\": \"JOBID CONTAINS WRONG ENDPOINT OR ENDPOINT CANNOT BE CONTACTED (CONNECTION REFUSED)\"" ) if errmex.find("unknown host") > -1: messageList.append( "\"" + jobid.jobid + "\": \"JOBID CONTAINS UNKNOWN ENDPOINT\"" ) if errmex.find("jobID is not in a valid format") != -1: messageList.append( "\"" + jobid.jobid + "\": \"JOBID FORMAT NOT VALID\"" ) if errmex.find("bad argument") != -1: messageList.append( "\"" + jobid.jobid + "\": \"BAD ARGUMENT\"" ) # Show on screen the error if json == False: pieces = apiMsg[0].split('\n') print "*** Warning: " + pieces[0] + "\n" cause = pieces[1] print cause.split(": ")[2] + " - " + cause.split(": ")[3] + "\n\n" #errMsg ( em , "API_NATIVE_ERROR" , "Job:getStatus" , apiMsg.args[0] ) # Set the exit code if json == False: sys_exit= -1 #wmsui_utils.print_message(json, outFile, ",".join( messageList ) ) if json == True: wmsui_utils.print_message(json, outFile, ", " + ", ".join( messageList ) ) print " }" else: wmsui_utils.print_message(json, outFile, "\n".join( messageList ) ) if level==0 and atLeastOneSuccess : if json == False: wmsui_utils.print_message(json, outFile,"==========================================================================\n") #Final error Check if not st: #No information got if jobs: # JOBID SPECIFICATED if len(jobs) !=1: #not only 1 JobId: Warning Message only printed so far. print the last message print ""#errMsg('Error','LB_API_OPEN_ALL') elif atLeastOneSuccess: # query on LB server performed but no job found print ""#errMsg("Error","UI_NO_JOB_FOUND") else: # All LB Queries went wrong (only warning so far) print ""#errMsg('Error','LB_API_OPEN_ALL') exit(1) else: if outFile: message='======================== glite-wms-job-status success ========================\n' message=message + " Bookkeeping information has been found and stored in the file:\n" message=message+ " "+ outFile message=message+'\n==========================================================================\n' wmsui_utils.print_message(False, wmsui_utils.info.logFile,message) exit(sys_exit)