ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/CRAB/python/multicrab.py
Revision: 1.34
Committed: Sat Oct 5 08:21:33 2013 UTC (11 years, 6 months ago) by belforte
Content type: text/x-python
Branch: MAIN
CVS Tags: HEAD
Changes since 1.33: +5 -2 lines
Log Message:
better handle spaces between args. for multicrab: https://savannah.cern.ch/bugs/index.php?102780

File Contents

# User Rev Content
1 slacapra 1.1 #!/usr/bin/env python
2     import sys, os, time, string, shutil
3     from crab_util import *
4     from crab import *
5     import common
6    
7     ###########################################################################
8     class MultiCrab:
9     def __init__(self, opts):
10     self.prog_name='multicrab'
11     # Configuration file
12     self.cfg_fname = None
13     # Continuation flag
14     self.flag_continue = 0
15     self.continue_dir = None
16     self.processContinueOption_(opts)
17    
18     self.processIniFile_(opts)
19     # configuration
20     self.opts=opts
21    
22     if not self.flag_continue:
23     self.createWorkSpace()
24    
25     print self.prog_name + ' running on ' + time.ctime(time.time())
26     print ' working directory ' + self.continue_dir
27    
28    
29     def processContinueOption_(self,opts):
30    
31     # Look for the '-continue' option.
32    
33     for opt in opts.keys():
34     if ( opt in ('-continue','-c') ):
35     self.flag_continue = 1
36     val = opts[opt]
37     if val:
38     if val[0] == '/': self.continue_dir = val # abs path
39     else: self.continue_dir = os.getcwd() + '/' + val # rel path
40     pass
41     break
42     pass
43    
44     # Look for actions which has sense only with '-continue'
45    
46     if "-create" not in opts.keys() :
47     self.flag_continue = 1
48    
49     if not self.flag_continue: return
50    
51     if not self.continue_dir:
52     prefix = self.prog_name + '_'
53     self.continue_dir = findLastWorkDir(prefix)
54     pass
55    
56     if not self.continue_dir:
57     raise CrabException('Cannot find last working directory.')
58    
59     if not os.path.exists(self.continue_dir):
60     msg = 'Cannot continue because the working directory <'
61     msg += self.continue_dir
62     msg += '> does not exist.'
63     raise CrabException(msg)
64    
65     return
66    
67     def createWorkSpace(self):
68     # create WorkingDir for Multicrab
69 slacapra 1.29 import os
70     if not self.continue_dir:
71     prefix = self.prog_name + '_'
72     self.continue_dir = findLastWorkDir(prefix)
73     pass
74     # if 'MULTICRAB.working_dir' in self.opts.keys():
75     # self.continue_dir = os.path.abspath(self.opts['MULTICRAB.working_dir'])
76     if self.ui_working_dir:
77     self.continue_dir = os.path.abspath(self.ui_working_dir)
78 slacapra 1.1 else:
79     current_time = time.strftime('%y%m%d_%H%M%S', time.localtime(time.time()))
80     self.continue_dir = os.getcwd() + '/' + self.prog_name + '_' + current_time
81    
82     if self.continue_dir and not os.path.exists(self.continue_dir):
83     try:
84     os.mkdir(self.continue_dir)
85     except OSError:
86 slacapra 1.31 msg = 'ERROR: Cannot create '+str(self.continue_dir) +' directory.\n'
87 slacapra 1.1 raise CrabException(msg)
88     pass
89     else:
90 slacapra 1.31 msg = 'ERROR: Directory '+str(self.continue_dir) +' already exist.\n'
91 slacapra 1.1 raise CrabException(msg)
92    
93 slacapra 1.29 os.putenv("MULTICRAB_WORKDIR",self.continue_dir)
94     shutil.copyfile(self.cfg_fname,self.continue_dir+'/multicrab.cfg')
95 slacapra 1.1
96     return
97    
98     def processIniFile_(self, opts):
99     """
100     Processes a configuration INI-file.
101     """
102    
103     # Extract cfg-file name from the cmd-line options.
104    
105     for opt in opts.keys():
106     if ( opt == '-cfg' ):
107     if self.flag_continue:
108     raise CrabException('-continue and -cfg cannot coexist.')
109 slacapra 1.8 if opts[opt] :
110     self.cfg_fname = opts[opt]
111 slacapra 1.11 del opts[opt] # do not pass cfg further on
112 slacapra 1.1 else : processHelpOptions()
113     pass
114     pass
115    
116     # Set default cfg-fname
117    
118     if self.cfg_fname == None:
119     if self.flag_continue:
120     self.cfg_fname = self.continue_dir + '/multicrab.cfg'
121     else:
122     self.cfg_fname = 'multicrab.cfg'
123     pass
124     pass
125    
126     # Load cfg-file
127    
128 slacapra 1.7 cfg_params = {}
129 slacapra 1.1 if self.cfg_fname != None:
130     if os.path.exists(self.cfg_fname):
131 slacapra 1.7 cfg_params = self.loadMultiConfig(self.cfg_fname)
132 slacapra 1.1 pass
133     else:
134 slacapra 1.31 msg = 'ERROR: cfg-file '+self.cfg_fname+' not found.'
135 slacapra 1.1 raise CrabException(msg)
136     pass
137     pass
138    
139     # process the [CRAB] section
140    
141     lhp = len('MULTICRAB.')
142 slacapra 1.7 for k in cfg_params.keys():
143 slacapra 1.1 if len(k) >= lhp and k[:lhp] == 'MULTICRAB.':
144     opt = '-'+k[lhp:]
145     if len(opt) >= 3 and opt[:3] == '-__': continue
146     if opt not in opts.keys():
147 slacapra 1.7 opts[opt] = cfg_params[k]
148 slacapra 1.1 pass
149     pass
150     pass
151    
152     self.cfg_params_dataset = {}
153 slacapra 1.3 common_opts = {}
154 slacapra 1.1 # first get common sections
155 slacapra 1.33 crab_cfg='crab.cfg' # this is the default
156 slacapra 1.7 for sec in cfg_params:
157 slacapra 1.1 if sec in ['MULTICRAB']:
158 slacapra 1.8 if 'cfg' in cfg_params[sec]:
159     common_opts['cfg']=cfg_params[sec]['cfg']
160 slacapra 1.33 crab_cfg=common_opts['cfg'];
161 slacapra 1.1 continue
162     if sec in ['COMMON']:
163 slacapra 1.8 common_opts.update(cfg_params[sec])
164 slacapra 1.1 continue
165     pass
166    
167 slacapra 1.2 # read crab.cfg file and search for storage_path
168 slacapra 1.8 crab_cfg_params = loadConfig(crab_cfg,{})
169 slacapra 1.16 # also USER.ui_working_dir USER.outputdir and USER.logdir need special treatment
170 slacapra 1.7 if cfg_params.has_key("COMMON"):
171     self.user_remote_dir = cfg_params["COMMON"].get("user.user_remote_dir", crab_cfg_params.get("USER.user_remote_dir",None))
172 slacapra 1.16 self.outputdir = cfg_params["COMMON"].get("user.outputdir", crab_cfg_params.get("USER.outputdir",None))
173     self.logdir = cfg_params["COMMON"].get("user.logdir", crab_cfg_params.get("USER.logdir",None))
174     self.ui_working_dir = cfg_params["COMMON"].get("user.ui_working_dir", crab_cfg_params.get("USER.ui_working_dir",None))
175 slacapra 1.29 self.publish_data_name = cfg_params["COMMON"].get("user.publish_data_name", crab_cfg_params.get("USER.publish_data_name",None))
176 slacapra 1.6 else:
177 slacapra 1.32 self.user_remote_dir = crab_cfg_params.get("USER.user_remote_dir","./")
178 slacapra 1.16 self.outputdir = crab_cfg_params.get("USER.outputdir",None)
179     self.logdir = crab_cfg_params.get("USER.logdir",None)
180     self.ui_working_dir = crab_cfg_params.get("USER.ui_working_dir",None)
181 slacapra 1.29 self.publish_data_name = crab_cfg_params.get("USER.publish_data_name",None)
182 slacapra 1.32
183     if common_opts.has_key('cfg') : crab_cfg=common_opts['cfg']
184    
185     # then Dataset's specific
186     for sec in cfg_params:
187     if sec in ['MULTICRAB', 'COMMON']: continue
188     # add common to all dataset
189     self.cfg_params_dataset[sec]=cfg_params[sec]
190     # special tratment for some parameter
191     if not self.cfg_params_dataset[sec].has_key("user.publish_data_name") and self.publish_data_name:
192     self.cfg_params_dataset[sec]["user.publish_data_name"]=self.publish_data_name+"_"+sec
193     if not self.cfg_params_dataset[sec].has_key("user.user_remote_dir") and self.user_remote_dir:
194     self.cfg_params_dataset[sec]["user.user_remote_dir"]=self.user_remote_dir+"/"+sec
195     if not self.cfg_params_dataset[sec].has_key("user.ui_working_dir") and self.ui_working_dir:
196     self.cfg_params_dataset[sec]["user.ui_working_dir"]=self.ui_working_dir+"/"+sec
197     if not self.cfg_params_dataset[sec].has_key("user.logdir") and self.logdir:
198     self.cfg_params_dataset[sec]["user.logdir"]=self.logdir+"/"+sec
199     if not self.cfg_params_dataset[sec].has_key("user.outputdir") and self.outputdir:
200     self.cfg_params_dataset[sec]["user.outputdir"]=self.outputdir+"/"+sec
201     for key in common_opts:
202     if not self.cfg_params_dataset[sec].has_key(key):
203     self.cfg_params_dataset[sec][key]=common_opts[key]
204     pass
205    
206 slacapra 1.1 return
207    
208     def loadMultiConfig(self, file):
209     """
210     returns a dictionary with keys of the form
211     <section>.<option> and the corresponding values
212     """
213     config={}
214     cp = ConfigParser.ConfigParser()
215     cp.read(file)
216     for sec in cp.sections():
217     # print 'Section',sec
218     config[sec]={}
219     for opt in cp.options(sec):
220 slacapra 1.32 # print 'config['+sec+'.'+opt+'] = '+string.strip(cp.get(sec,opt))
221 slacapra 1.1 config[sec][opt] = string.strip(cp.get(sec,opt))
222     return config
223    
224     def run(self):
225     #run crabs
226 slacapra 1.29 runFileName = self.continue_dir+'/multicrab.exe'
227 slacapra 1.16 runFile = open(runFileName,"w")
228 slacapra 1.1 for sec in self.cfg_params_dataset:
229     options={}
230     if self.flag_continue:
231     options['-c']=sec
232     # DatasetName to be used
233     options['-USER.ui_working_dir']=sec
234     # options from multicrab.cfg
235     for opt in self.cfg_params_dataset[sec]:
236 slacapra 1.8 tmp = "-"+str(opt)
237     if len(opt.split("."))==2:
238     tmp="-"+string.upper(opt.split(".")[0])+"."+opt.split(".")[1]
239    
240 slacapra 1.1 options[tmp]=self.cfg_params_dataset[sec][opt]
241 slacapra 1.16
242 slacapra 1.32 # if ui_working_dir is set, change -c dir accordnigly
243     if not self.cfg_params_dataset.has_key("USER.ui_working_dir") and self.ui_working_dir:
244     if self.flag_continue:
245     options['-c']=self.ui_working_dir+"/"+sec
246    
247 slacapra 1.23 # check if user_remote_dir is set in multicrab.cfg
248 spiga 1.24 # protect against no user_remote_dir
249 slacapra 1.32 # self.user_remote_dir =self.cfg_params_dataset[sec].get("user.user_remote_dir",self.user_remote_dir)
250     # if not self.user_remote_dir:
251     # self.user_remote_dir = "./"
252 slacapra 1.2 # add section to storage_path if exist in crab.cfg
253 slacapra 1.32 # if not self.cfg_params_dataset.has_key("USER.user_remote_dir") and self.user_remote_dir:
254     # options["-USER.user_remote_dir"]=self.user_remote_dir+"/"+sec
255 slacapra 1.27 # print options["-USER.user_remote_dir"]
256 slacapra 1.16 # also for ui_working_dir
257 slacapra 1.32 # if not self.cfg_params_dataset.has_key("USER.ui_working_dir") and self.ui_working_dir:
258     # options["-USER.ui_working_dir"]=self.ui_working_dir+"/"+sec
259 slacapra 1.16 # also for logDir
260 slacapra 1.32 # if not self.cfg_params_dataset.has_key("USER.logdir") and self.logdir:
261     # options["-USER.logdir"]=self.logdir+"/"+sec
262     # # also for outputdir
263     # if not self.cfg_params_dataset.has_key("USER.outputdir") and self.outputdir:
264     # options["-USER.outputdir"]=self.outputdir+"/"+sec
265 slacapra 1.29 # also for publish_data_name
266 slacapra 1.32 # print sec," ",self.cfg_params_dataset[sec], self.cfg_params_dataset[sec].has_key("user.publish_data_name")
267     # if not self.cfg_params_dataset[sec].has_key("user.publish_data_name") and self.publish_data_name:
268     # options["-USER.publish_data_name"]=self.publish_data_name+"_"+sec
269     # print "adding user.publish_data_name", self.cfg_params_dataset.has_key("user.publish_data_name")
270 slacapra 1.16
271 slacapra 1.1 # Input options (command)
272     for opt in self.opts:
273 slacapra 1.29 if opt != '-c':
274     options[opt]=self.opts[opt]
275     # options[opt]=self.opts[opt]
276     if self.flag_continue and options.has_key("-cfg"):
277     del options['-cfg']
278     pass
279 slacapra 1.20
280 slacapra 1.32
281 slacapra 1.20 # write crab command to be executed later...
282     cmd='crab '
283     for o in options:
284     if options[o]==None:
285     cmd+=str(o)+' '
286     else:
287 belforte 1.34 if (len(options[o].split())>1):
288     cmd+='"'+str(o)+'='+str(options[o])+'" '
289     else:
290     options[o] = ''.join(options[o].split())
291     cmd+=str(o)+'='+str(options[o])+' '
292 slacapra 1.20 pass
293     cmd+="\n"
294     #print cmd
295    
296     runFile.write(cmd)
297    
298     # SL this does not work for complex, multi include pset.py
299    
300     # crab = Crab()
301     # try:
302     # crab.initialize_(options)
303     # crab.run()
304     # del crab
305     # print 'Log file is %s%s.log'%(common.work_space.logDir(),common.prog_name)
306     # print '\n############################## E N D ####################################\n'
307     # except CrabException, e:
308     # del crab
309     # print '\n' + common.prog_name + ': ' + str(e) + '\n'
310     # pass
311     # pass
312     # if (common.logger): common.logger.delete()
313 slacapra 1.1 pass
314 slacapra 1.29 return self.continue_dir
315 slacapra 1.1
316    
317     ###########################################################################
318     if __name__ == '__main__':
319     ## Get rid of some useless warning
320     try:
321     import warnings
322     warnings.simplefilter("ignore", RuntimeWarning)
323     except ImportError:
324     pass # too bad, you'll get the warning
325    
326     # Parse command-line options and create a dictionary with
327     # key-value pairs.
328     options = parseOptions(sys.argv[1:])
329    
330     # Process "help" options, such as '-help', '-version'
331     if processHelpOptions(options) : sys.exit(0)
332    
333     # Create, initialize, and run a Crab object
334     try:
335     multicrab = MultiCrab(options)
336 slacapra 1.29 continue_dir = multicrab.run()
337     import os
338     sys.exit(continue_dir)
339 slacapra 1.1 except CrabException, e:
340     print '\n' + common.prog_name + ': ' + str(e) + '\n'
341    
342     pass