ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/CRAB/python/crab_util.py
Revision: 1.122
Committed: Mon Oct 29 22:13:51 2012 UTC (12 years, 6 months ago) by belforte
Content type: text/x-python
Branch: MAIN
CVS Tags: CRAB_2_8_4_patch1, CRAB_2_8_4, CRAB_2_8_4_pre5, CRAB_2_8_4_pre4, CRAB_2_8_4_pre3, CRAB_2_8_4_pre2, CRAB_2_8_4_pre1
Changes since 1.121: +4 -4 lines
Log Message:
less verbose. fix https://savannah.cern.ch/bugs/index.php?98216

File Contents

# User Rev Content
1 spiga 1.80 ##########################################################################
2 nsmirnov 1.1 #
3     # C O N V E N I E N C E F U N C T I O N S
4     #
5     ###########################################################################
6    
7 spiga 1.113 import string, sys, os, time, signal
8 spiga 1.100 import ConfigParser, re, select, fcntl
9 ewv 1.89 import statvfs
10 spiga 1.100 from subprocess import Popen, PIPE, STDOUT
11 nsmirnov 1.1
12 nsmirnov 1.2 import common
13 slacapra 1.30 from crab_exceptions import CrabException
14 spiga 1.42 from ServerConfig import *
15 nsmirnov 1.1
16     ###########################################################################
17     def parseOptions(argv):
18     """
19     Parses command-line options.
20     Returns a dictionary with specified options as keys:
21     -opt1 --> 'opt1' : None
22     -opt2 val --> 'opt2' : 'val'
23     -opt3=val --> 'opt3' : 'val'
24     Usually called as
25     options = parseOptions(sys.argv[1:])
26     """
27     options = {}
28     argc = len(argv)
29     i = 0
30     while ( i < argc ):
31     if argv[i][0] != '-':
32     i = i + 1
33     continue
34     eq = string.find(argv[i], '=')
35     if eq > 0 :
36     opt = argv[i][:eq]
37     val = argv[i][eq+1:]
38     pass
39     else:
40     opt = argv[i]
41     val = None
42     if ( i+1 < argc and argv[i+1][0] != '-' ):
43     i = i + 1
44     val = argv[i]
45     pass
46     pass
47     options[opt] = val
48     i = i + 1
49     pass
50     return options
51    
52 slacapra 1.47 def loadConfig(file, config):
53 nsmirnov 1.1 """
54     returns a dictionary with keys of the form
55     <section>.<option> and the corresponding values
56     """
57 slacapra 1.47 #config={}
58 nsmirnov 1.1 cp = ConfigParser.ConfigParser()
59     cp.read(file)
60     for sec in cp.sections():
61     for opt in cp.options(sec):
62 spiga 1.79 ## temporary check. Allow compatibility
63 ewv 1.89 new_sec = sec
64 spiga 1.79 if sec == 'EDG':
65 spiga 1.80 print ('\tWARNING: The [EDG] section is now deprecated.\n\tPlease remove it and use [GRID] instead.\n')
66 ewv 1.89 new_sec = 'GRID'
67 spiga 1.79 config[new_sec+'.'+opt] = string.strip(cp.get(sec,opt))
68 nsmirnov 1.1 return config
69    
70     ###########################################################################
71     def isInt(str):
72     """ Is the given string an integer ?"""
73     try: int(str)
74     except ValueError: return 0
75     return 1
76    
77     ###########################################################################
78     def isBool(str):
79     """ Is the given string 0 or 1 ?"""
80     if (str in ('0','1')): return 1
81     return 0
82    
83     ###########################################################################
84 nsmirnov 1.3 def parseRange(range):
85     """
86     Takes as the input a string with two integers separated by
87     the minus sign and returns the tuple with these numbers:
88     'n1-n2' -> (n1, n2)
89     'n1' -> (n1, n1)
90     """
91     start = None
92     end = None
93     minus = string.find(range, '-')
94     if ( minus < 0 ):
95     if isInt(range):
96     start = int(range)
97     end = start
98     pass
99     pass
100     else:
101     if isInt(range[:minus]) and isInt(range[minus+1:]):
102     start = int(range[:minus])
103     end = int(range[minus+1:])
104     pass
105     pass
106     return (start, end)
107    
108     ###########################################################################
109 nsmirnov 1.4 def parseRange2(range):
110     """
111     Takes as the input a string in the form of a comma-separated
112     numbers and ranges
113     and returns a list with all specified numbers:
114     'n1' -> [n1]
115     'n1-n2' -> [n1, n1+1, ..., n2]
116     'n1,n2-n3,n4' -> [n1, n2, n2+1, ..., n3, n4]
117     """
118 slacapra 1.30 result = []
119     if not range: return result
120 nsmirnov 1.4
121     comma = string.find(range, ',')
122     if comma == -1: left = range
123     else: left = range[:comma]
124    
125     (n1, n2) = parseRange(left)
126     while ( n1 <= n2 ):
127 slacapra 1.11 try:
128 slacapra 1.30 result.append(n1)
129 slacapra 1.11 n1 += 1
130     pass
131     except:
132     msg = 'Syntax error in range <'+range+'>'
133     raise CrabException(msg)
134 nsmirnov 1.4
135     if comma != -1:
136 slacapra 1.11 try:
137 slacapra 1.30 result.extend(parseRange2(range[comma+1:]))
138 slacapra 1.11 pass
139     except:
140     msg = 'Syntax error in range <'+range+'>'
141     raise CrabException(msg)
142 nsmirnov 1.4
143 slacapra 1.30 return result
144 nsmirnov 1.4
145     ###########################################################################
146 nsmirnov 1.1 def findLastWorkDir(dir_prefix, where = None):
147    
148     if not where: where = os.getcwd() + '/'
149     # dir_prefix usually has the form 'crab_0_'
150     pattern = re.compile(dir_prefix)
151    
152 slacapra 1.76 file_list = [f for f in os.listdir(where) if os.path.isdir(f) and pattern.match(f)]
153 nsmirnov 1.1
154     if len(file_list) == 0: return None
155    
156     file_list.sort()
157    
158 slacapra 1.76 wdir = where + file_list[-1]
159 nsmirnov 1.1 return wdir
160    
161     ###########################################################################
162 mcinquil 1.99 def checkCRABVersion(current, url = "http://cmsdoc.cern.ch/cms/LCG/crab/config/", fileName = "allowed_releases.conf"):
163 mcinquil 1.98 """
164     _checkCRABVersion_
165    
166     compare current release with allowed releases
167     format of allowed release: ['2.6.5','2.6.6','2.7.*']
168     """
169 spiga 1.111 result=[]
170 mcinquil 1.98 match_result = False
171     from Downloader import Downloader
172 spiga 1.107 blacklist = Downloader(url)
173 spiga 1.111 try:
174     result =eval(blacklist.config(fileName))
175     except:
176     common.logger.info("ERROR: Problem reading allowed releases file...")
177 mcinquil 1.98 current_dot = current.split('.')
178     for version in result:
179     if version.find('.') != -1:
180     version_dot = version.split('.')
181 mcinquil 1.116 temp = False
182 mcinquil 1.98 for compare in map(None, current_dot, version_dot):
183     if compare[1].find('*') != -1:
184     return True
185     elif int(compare[0]) != int(compare[1]):
186 mcinquil 1.116 temp = False
187 mcinquil 1.98 break
188 mcinquil 1.116 else:
189     temp = True
190     if temp:
191     return temp
192 mcinquil 1.98 elif version == '*':
193     return True
194     return False
195    
196     ###########################################################################
197 mcinquil 1.115 def getCentralConfigLink(linkname, url = "http://cmsdoc.cern.ch/cms/LCG/crab/config/", fileName = "URLs.conf"):
198     """
199     _getCentralConfigLink_
200    
201     This retrieves the remote URLs file containing a dictionary of a central manager URLs
202     {
203     'reportLogURL': 'http://gangamon.cern.ch/django/cmserrorreports/',
204     'dashbTaskMon': 'http://dashb-cms-job-task.cern.ch/taskmon.html#task=',
205     'servTaskMon' : 'http://glidein-mon.t2.ucsd.edu:8080/dashboard/ajaxproxy.jsp?p='
206     }
207     """
208     result = {}
209     from Downloader import Downloader
210     links = Downloader(url)
211     try:
212     result = eval(links.config(fileName))
213     common.logger.debug(str(result))
214     except:
215     common.logger.info("ERROR: Problem reading URLs releases file...")
216     if result.has_key(linkname):
217     return result[linkname]
218     common.logger.info("ERROR: Problem reading URLs releases file: no %s present!" % linkname)
219     return ''
220    
221     ###########################################################################
222 nsmirnov 1.1 def importName(module_name, name):
223     """
224     Import a named object from a Python module,
225     i.e., it is an equivalent of 'from module_name import name'.
226     """
227     module = __import__(module_name, globals(), locals(), [name])
228     return vars(module)[name]
229    
230     ###########################################################################
231 slacapra 1.16 def readable(fd):
232 ewv 1.44 return bool(select.select([fd], [], [], 0))
233 slacapra 1.16
234     ###########################################################################
235     def makeNonBlocking(fd):
236     fl = fcntl.fcntl(fd, fcntl.F_GETFL)
237     try:
238     fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NDELAY)
239     except AttributeError:
240     fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.FNDELAY)
241    
242     ###########################################################################
243 spiga 1.100 def setPgid():
244 nsmirnov 1.1 """
245 spiga 1.100 preexec_fn for Popen to set subprocess pgid
246    
247     """
248    
249     os.setpgid( os.getpid(), 0 )
250    
251 belforte 1.119 def runCommand(command, printout=0, timeout=30.,errorCode=False):
252 spiga 1.100 """
253     _executeCommand_
254    
255     Util it execute the command provided in a popen object with a timeout
256 nsmirnov 1.1 """
257 fanzago 1.15
258 spiga 1.100 start = time.time()
259     p = Popen( command, shell=True, \
260     stdin=PIPE, stdout=PIPE, stderr=STDOUT, \
261     close_fds=True, preexec_fn=setPgid )
262    
263     # playing with fd
264     fd = p.stdout.fileno()
265     flags = fcntl.fcntl(fd, fcntl.F_GETFL)
266     fcntl.fcntl(fd, fcntl.F_SETFL, flags | os.O_NONBLOCK)
267    
268     # return values
269     timedOut = False
270     outc = []
271    
272     while 1:
273     (r, w, e) = select.select([fd], [], [], timeout)
274    
275     if fd not in r :
276     timedOut = True
277     break
278 slacapra 1.11
279 spiga 1.100 read = p.stdout.read()
280     if read != '' :
281     outc.append( read )
282     else :
283 slacapra 1.16 break
284 spiga 1.100
285     if timedOut :
286 belforte 1.119 common.logger.info('Command %s timed out after %d sec' % (command, int(timeout)))
287 spiga 1.100 stop = time.time()
288     try:
289     os.killpg( os.getpgid(p.pid), signal.SIGTERM)
290     os.kill( p.pid, signal.SIGKILL)
291     p.wait()
292     p.stdout.close()
293     except OSError, err :
294 spiga 1.101 common.logger.info(
295 spiga 1.100 'Warning: an error occurred killing subprocess [%s]' \
296     % str(err) )
297    
298 belforte 1.119 raise CrabException("Timeout")
299 spiga 1.100
300     try:
301     p.wait()
302     p.stdout.close()
303     except OSError, err:
304 spiga 1.101 common.logger.info( 'Warning: an error occurred closing subprocess [%s] %s %s' \
305 spiga 1.100 % (str(err), ''.join(outc), p.returncode ))
306    
307     returncode = p.returncode
308     if returncode != 0 :
309     msg = 'Command: %s \n failed with exit code %s \n'%(command,returncode)
310 edelmann 1.105 msg += str(''.join(outc))
311 spiga 1.109 if not errorCode:
312     common.logger.info( msg )
313     return None
314     if errorCode:
315     if returncode is None :returncode=-66666
316     return returncode,''.join(outc)
317 belforte 1.119
318 spiga 1.100 return ''.join(outc)
319    
320 nsmirnov 1.4
321 slacapra 1.11 ####################################
322 gutsche 1.20 def makeCksum(filename) :
323     """
324 ewv 1.44 make check sum using filename and content of file
325 gutsche 1.20 """
326    
327 ewv 1.44 from zlib import crc32
328     hashString = filename
329 gutsche 1.20
330 ewv 1.44 inFile = open(filename, 'r')
331     hashString += inFile.read()
332     inFile.close()
333 gutsche 1.20
334 ewv 1.44 cksum = str(crc32(hashString))
335 gutsche 1.20 return cksum
336    
337 ewv 1.52
338 gutsche 1.32 def spanRanges(jobArray):
339     """
340     take array of job numbers and concatenate 1,2,3 to 1-3
341     return string
342     """
343    
344     output = ""
345 mcinquil 1.35 jobArray.sort()
346 ewv 1.44
347 gutsche 1.32 previous = jobArray[0]-1
348     for job in jobArray:
349     if previous+1 == job:
350     previous = job
351     if len(output) > 0 :
352     if output[-1] != "-":
353     output += "-"
354     else :
355     output += str(previous)
356     else:
357     output += str(previous) + "," + str(job)
358 mcinquil 1.35 #output += "," + str(job)
359 gutsche 1.32 previous = job
360     if len(jobArray) > 1 :
361     output += str(previous)
362    
363     return output
364    
365 spiga 1.40 def displayReport(self, header, lines, xml=''):
366 ewv 1.44
367 belforte 1.117 horizontalRuler=''
368     for i in range(80):
369     horizontalRuler+='-'
370     horizontalRuler+='\n'
371 spiga 1.49 counter = 0
372     printline = ''
373     printline+= header
374 spiga 1.87 msg = '\n%s'%printline
375 spiga 1.49
376     for i in range(len(lines)):
377     if counter != 0 and counter%10 == 0 :
378 belforte 1.117 msg += horizontalRuler
379 spiga 1.82 msg+= '%s\n'%lines[i]
380 spiga 1.49 counter += 1
381     if xml != '' :
382 spiga 1.40 fileName = common.work_space.shareDir() + xml
383     task = common._db.getTask()
384     taskXML = common._db.serializeTask(task)
385 spiga 1.87 common.logger.log(10-1, taskXML)
386 spiga 1.40 f = open(fileName, 'w')
387     f.write(taskXML)
388     f.close()
389     pass
390 spiga 1.82 common.logger.info(msg)
391 spiga 1.39
392 spiga 1.42 def CliServerParams(self):
393 slacapra 1.45 """
394     Init client-server interactions
395     """
396     self.srvCfg = {}
397 slacapra 1.63 ## First I have to check if the decision has been already taken...
398     task = common._db.getTask()
399 slacapra 1.81 if task['serverName']!=None and task['serverName']!="":
400 slacapra 1.63 self.cfg_params['CRAB.server_name']=task['serverName']
401 slacapra 1.81
402     if self.cfg_params.has_key('CRAB.server_name'):
403     self.srvCfg = ServerConfig(self.cfg_params['CRAB.server_name']).config()
404     elif self.cfg_params.has_key('CRAB.use_server'):
405 slacapra 1.77 serverName=self.cfg_params.get('CRAB.server_name','default')
406 slacapra 1.62 if self.cfg_params.has_key('CRAB.server_name'):
407     serverName=self.cfg_params['CRAB.server_name']
408     else:
409     serverName='default'
410     self.srvCfg = ServerConfig(serverName).config()
411 slacapra 1.61 else:
412     msg = 'No server selected or port specified.\n'
413     msg += 'Please specify a server in the crab cfg file'
414     raise CrabException(msg)
415     return
416 slacapra 1.81 # save the serverName for future use
417     opsToBeSaved={}
418     opsToBeSaved['serverName']=self.srvCfg['serverGenericName']
419     common._db.updateTask_(opsToBeSaved)
420 slacapra 1.45
421 slacapra 1.61 self.server_admin = str(self.srvCfg['serverAdmin'])
422     self.server_dn = str(self.srvCfg['serverDN'])
423 spiga 1.58
424 slacapra 1.61 self.server_name = str(self.srvCfg['serverName'])
425     self.server_port = int(self.srvCfg['serverPort'])
426 slacapra 1.45
427 slacapra 1.61 self.storage_name = str(self.srvCfg['storageName'])
428     self.storage_path = str(self.srvCfg['storagePath'])
429 mcinquil 1.97
430 riahi 1.114 if self.srvCfg.has_key('proxyPath'):
431     self.proxy_path = str(self.srvCfg['proxyPath'])
432     else:
433     self.proxy_path = os.path.dirname(str(self.srvCfg['storagePath'])) + '/proxyCache'
434    
435 slacapra 1.61 self.storage_proto = str(self.srvCfg['storageProtocol'])
436 mcinquil 1.97 if self.cfg_params.has_key('USER.client'):
437     self.storage_proto = self.cfg_params['USER.client'].lower()
438    
439 slacapra 1.61 self.storage_port = str(self.srvCfg['storagePort'])
440 spiga 1.39
441 ewv 1.44 def bulkControl(self,list):
442 slacapra 1.45 """
443     Check the BULK size and reduce collection ...if needed
444     """
445     max_size = 400
446     sub_bulk = []
447     if len(list) > int(max_size):
448     n_sub_bulk = int( int(len(list) ) / int(max_size) )
449 mcinquil 1.53 for n in xrange(n_sub_bulk):
450 slacapra 1.45 first =n*int(max_size)
451     last = (n+1)*int(max_size)
452     sub_bulk.append(list[first:last])
453 belforte 1.118 if len(list[last:]) < 50:
454     for pp in list[last:]:
455 slacapra 1.45 sub_bulk[n_sub_bulk-1].append(pp)
456 spiga 1.43 else:
457 mcinquil 1.53 sub_bulk.append(list[last:])
458 slacapra 1.45 else:
459     sub_bulk.append(list)
460    
461     return sub_bulk
462 ewv 1.89
463 slacapra 1.45
464 spiga 1.69 def getUserName():
465 spiga 1.66 """
466     extract user name from either SiteDB or Unix
467     """
468 mcinquil 1.96 if common.scheduler.name().upper() in ['LSF', 'CAF', 'SGE', 'PBS']:
469 ewv 1.89 common.logger.log(10-1, "Using as username the Unix user name")
470     userName = unixUserName()
471 spiga 1.66 else :
472 ewv 1.89 userName = gethnUserNameFromSiteDB()
473    
474     return userName
475 spiga 1.66
476 spiga 1.58
477 ewv 1.89 def unixUserName():
478 spiga 1.58 """
479     extract username from whoami
480     """
481     try:
482 ewv 1.89 userName = runCommand("whoami")
483     userName = string.strip(userName)
484 spiga 1.58 except:
485     msg = "Error. Problem with whoami command"
486     raise CrabException(msg)
487 ewv 1.89 return userName
488    
489 spiga 1.66
490 spiga 1.69 def getDN():
491 spiga 1.66 """
492     extract DN from user proxy's identity
493     """
494     try:
495     userdn = runCommand("voms-proxy-info -identity")
496     userdn = string.strip(userdn)
497 farinafa 1.112 #remove /CN=proxy that could cause problems with siteDB check at server-side
498     userdn = userdn.replace('/CN=proxy','')
499 spiga 1.66 #search for a / to avoid picking up warning messages
500     userdn = userdn[userdn.find('/'):]
501     except:
502     msg = "Error. Problem with voms-proxy-info -identity command"
503     raise CrabException(msg)
504     return userdn.split('\n')[0]
505    
506 ewv 1.89
507 spiga 1.69 def gethnUserNameFromSiteDB():
508 spiga 1.66 """
509     extract user name from SiteDB
510     """
511     from WMCore.Services.SiteDB.SiteDB import SiteDBJSON
512     hnUserName = None
513 spiga 1.69 userdn = getDN()
514 ewv 1.89 params = { 'cacheduration' : 24,
515     'logger' : common.logger() }
516     mySiteDB = SiteDBJSON(params)
517 ewv 1.90 msg_ = "there is no user name associated to DN %s in SiteDB.\n" % userdn
518     msg_ += "You need to register in SiteDB with the instructions at https://twiki.cern.ch/twiki/bin/view/CMS/SiteDBForCRAB"
519 spiga 1.66 try:
520     hnUserName = mySiteDB.dnUserName(dn=userdn)
521 ewv 1.89 except Exception, text:
522     msg = "Error extracting user name from SiteDB: %s\n" % text
523     msg += " Check that you are registered in SiteDB, see https://twiki.cern.ch/twiki/bin/view/CMS/SiteDBForCRAB\n"
524     msg += ' or %s' % msg_
525 spiga 1.66 raise CrabException(msg)
526     if not hnUserName:
527 ewv 1.89 msg = "Error. %s" % msg_
528 spiga 1.66 raise CrabException(msg)
529     return hnUserName
530    
531    
532 slacapra 1.45 def numberFile(file, txt):
533     """
534     append _'txt' before last extension of a file
535     """
536     txt=str(txt)
537     p = string.split(file,".")
538     # take away last extension
539     name = p[0]
540     for x in p[1:-1]:
541     name=name+"."+x
542     # add "_txt"
543     if len(p)>1:
544     ext = p[len(p)-1]
545     result = name + '_' + txt + "." + ext
546     else:
547     result = name + '_' + txt
548 spiga 1.43
549 slacapra 1.45 return result
550 spiga 1.46
551     def readTXTfile(self,inFileName):
552     """
553     read file and return a list with the content
554     """
555     out_list=[]
556     if os.path.exists(inFileName):
557     f = open(inFileName, 'r')
558     for line in f.readlines():
559 ewv 1.52 out_list.append(string.strip(line))
560 spiga 1.46 f.close()
561     else:
562     msg = ' file '+str(inFileName)+' not found.'
563 ewv 1.52 raise CrabException(msg)
564 spiga 1.46 return out_list
565    
566     def writeTXTfile(self, outFileName, args):
567     """
568     write a file with the given content ( args )
569     """
570     outFile = open(outFileName,"a")
571     outFile.write(str(args))
572     outFile.close()
573     return
574    
575 spiga 1.54 def readableList(self,rawList):
576 ewv 1.64 """
577     Turn a list of numbers into a string like 1-5,7,9,12-20
578     """
579     if not rawList:
580     return ''
581    
582 slacapra 1.56 listString = str(rawList[0])
583     endRange = ''
584     for i in range(1,len(rawList)):
585     if rawList[i] == rawList[i-1]+1:
586     endRange = str(rawList[i])
587     else:
588     if endRange:
589     listString += '-' + endRange + ',' + str(rawList[i])
590     endRange = ''
591     else:
592     listString += ',' + str(rawList[i])
593     if endRange:
594     listString += '-' + endRange
595     endRange = ''
596 ewv 1.64
597 slacapra 1.56 return listString
598 spiga 1.54
599 spiga 1.51 def getLocalDomain(self):
600 ewv 1.52 """
601 slacapra 1.56 Get local domain name
602 ewv 1.52 """
603 spiga 1.51 import socket
604 slacapra 1.88 tmp=socket.getfqdn()
605 spiga 1.51 dot=string.find(tmp,'.')
606     if (dot==-1):
607     msg='Unkown domain name. Cannot use local scheduler'
608     raise CrabException(msg)
609     localDomainName = string.split(tmp,'.',1)[-1]
610 ewv 1.52 return localDomainName
611 spiga 1.51
612 slacapra 1.56 #######################################################
613     # Brian Bockelman bbockelm@cse.unl.edu
614     # Module to check the avaialble disk space on a specified directory.
615     #
616    
617     def has_freespace(dir_name, needed_space_kilobytes):
618 belforte 1.119
619 slacapra 1.56 enough_unix_quota = False
620     enough_quota = False
621     enough_partition = False
622     enough_mount = False
623     try:
624 spiga 1.109 enough_mount = check_mount(dir_name, needed_space_kilobytes)
625     except Exception,e :
626 belforte 1.122 common.logger.debug(str(e)+" while checking mount. Treat as check OK")
627 spiga 1.109 common.logger.log(10-1,e)
628 slacapra 1.56 enough_mount = True
629     try:
630     enough_quota = check_quota(dir_name, needed_space_kilobytes)
631 spiga 1.109 except Exception, e:
632 belforte 1.122 common.logger.debug(str(e)+" while checking AFS quota. Treat as check OK")
633 spiga 1.109 common.logger.log(10-1,e)
634 slacapra 1.56 enough_quota = True
635     try:
636     enough_partition = check_partition(dir_name,
637     needed_space_kilobytes)
638 spiga 1.109 except Exception, e:
639 belforte 1.122 common.logger.debug(str(e)+" while checking partition. Treat as check OK")
640 spiga 1.109 common.logger.log(10-1,e)
641 slacapra 1.56 enough_partition = True
642     try:
643     enough_unix_quota = check_unix_quota(dir_name,
644     needed_space_kilobytes)
645 spiga 1.109 except Exception, e:
646 belforte 1.122 common.logger.debug(str(e)+" while checking unix_quota. Treat as check OK")
647 spiga 1.109 common.logger.log(10-1,e)
648 slacapra 1.56 enough_unix_quota = True
649 belforte 1.119
650 slacapra 1.56 return enough_mount and enough_quota and enough_partition \
651     and enough_unix_quota
652    
653     def check_mount(dir_name, needed_space_kilobytes):
654     try:
655     vfs = os.statvfs(dir_name)
656     except:
657     raise Exception("Unable to query VFS for %s." % dir_name)
658     dev_free = vfs[statvfs.F_FRSIZE] * vfs[statvfs.F_BAVAIL]
659     return dev_free/1024 > needed_space_kilobytes
660    
661     def check_quota(dir_name, needed_space_kilobytes):
662 spiga 1.109 err,results = runCommand("/usr/bin/fs lq %s" % dir_name,errorCode=True)
663     if results and err == 0 :
664     try:
665     results = results.split('\n')[1].split()
666     quota, used = results[1:3]
667     avail = int(quota) - int(used)
668     return avail > needed_space_kilobytes
669     except:
670     raise Exception("Unable to parse AFS output.")
671     elif results and err !=0:
672     raise Exception(results)
673 slacapra 1.56
674     def check_partition(dir_name, needed_space_kilobytes):
675 spiga 1.109 err,results = runCommand("/usr/bin/fs diskfree %s" % dir_name,errorCode=True)
676     if results and err==0:
677     try:
678     results = results.split('\n')[1].split()
679     avail = results[3]
680     return int(avail) > needed_space_kilobytes
681     except:
682     raise Exception("Unable to parse AFS output.")
683     elif results and err !=0:
684     raise Exception(results)
685 slacapra 1.56
686     def check_unix_quota(dir_name, needed_space_kilobytes):
687 spiga 1.109 err0, results0 = runCommand("df %s" % dir_name,errorCode=True)
688     if results0 and err0==0:
689     fs = results0.split('\n')[1].split()[0]
690 belforte 1.120 err,results = runCommand("quota -Q -u -g",errorCode=True)
691 spiga 1.109 if err != 0:
692     raise Exception(results)
693     has_info = False
694     for line in results.splitlines():
695     info = line.split()
696     if info[0] in ['Filesystem', 'Disk']:
697     continue
698     if len(info) == 1:
699     filesystem = info[0]
700     has_info = False
701     if len(info) == 6:
702     used, limit = info[0], max(info[1], info[2])
703     has_info = True
704     if len(info) == 7:
705     filesystem, used, limit = info[0], info[1], max(info[2], info[3])
706     has_info = True
707     if has_info:
708     if filesystem != fs:
709     continue
710     avail = int(limit) - int(used)
711     if avail < needed_space_kilobytes:
712     return False
713     elif results0 and err0 !=0:
714     raise Exception(results0)
715 slacapra 1.56 return True
716 spiga 1.54
717 slacapra 1.57 def getGZSize(gzipfile):
718     # return the uncompressed size of a gzipped file
719     import struct
720     f = open(gzipfile, "rb")
721     if f.read(2) != "\x1f\x8b":
722     raise IOError("not a gzip file")
723     f.seek(-4, 2)
724 ewv 1.64 return struct.unpack("<i", f.read())[0]
725 slacapra 1.57
726 spiga 1.60 def showWebMon(server_name):
727 spiga 1.72 taskName = common._db.queryTask('name')
728 spiga 1.60 msg = ''
729 spiga 1.71 msg +='You can also follow the status of this task on :\n'
730 spiga 1.72 msg +='\tCMS Dashboard: http://dashb-cms-job-task.cern.ch/taskmon.html#task=%s\n'%(taskName)
731 ewv 1.64 if server_name != '' :
732 spiga 1.71 msg += '\tServer page: http://%s:8888/logginfo\n'%server_name
733 spiga 1.72 msg += '\tYour task name is: %s \n'%taskName
734 spiga 1.60 return msg
735    
736 slacapra 1.86 def SE2CMS(dests):
737 slacapra 1.85 """
738     Trasnsform a list of SE grid name into a list SE according to CMS naming convention
739     input: array of SE grid names
740     output: array of SE CMS names
741     """
742     from ProdCommon.SiteDB.CmsSiteMapper import SECmsMap
743     se_cms = SECmsMap()
744     SEDestination = [se_cms[d] for d in dests]
745     return SEDestination
746 spiga 1.60
747 slacapra 1.86 def CE2CMS(dests):
748     """
749     Trasnsform a list of CE grid name into a list SE according to CMS naming convention
750     input: array of CE grid names
751     output: array of CE CMS names
752     """
753     from ProdCommon.SiteDB.CmsSiteMapper import CECmsMap
754     ce_cms = CECmsMap()
755     CEDestination = [ce_cms[d] for d in dests]
756     return CEDestination
757    
758 spiga 1.95 def checkLcgUtils( ):
759 mcinquil 1.94 """
760     _checkLcgUtils_
761     check the lcg-utils version and report
762     """
763     import commands
764     cmd = "lcg-cp --version | grep lcg_util"
765     status, output = commands.getstatusoutput( cmd )
766     num_ver = -1
767     if output.find("not found") == -1 or status == 0:
768     temp = output.split("-")
769     version = ""
770     if len(temp) >= 2:
771     version = output.split("-")[1]
772     temp = version.split(".")
773     if len(temp) >= 1:
774     num_ver = int(temp[0])*10
775     num_ver += int(temp[1])
776     return num_ver
777    
778 spiga 1.95 def setLcgTimeout( ):
779     """
780     """
781     opt = ' -t 600 '
782     if checkLcgUtils() >= 17: opt=' --connect-timeout 600 '
783     return opt
784    
785 spiga 1.110 def schedulerGlite():
786    
787     scheduler = None
788     err, out = runCommand('glite-version',errorCode=True)
789     if err==0:
790     if out.strip().startswith('3.1'):
791     scheduler = 'SchedulerGLiteAPI'
792     else:
793     scheduler = 'SchedulerGLite'
794     else:
795     common.logger.info("error detecting glite version ")
796    
797     return scheduler
798 spiga 1.101
799 gutsche 1.20 ####################################
800 nsmirnov 1.4 if __name__ == '__main__':
801     print 'sys.argv[1] =',sys.argv[1]
802     list = parseRange2(sys.argv[1])
803     print list
804 slacapra 1.29 cksum = makeCksum("crab_util.py")
805     print cksum
806 ewv 1.44