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 |
|
|
crabs=[]
|
29 |
|
|
|
30 |
|
|
def processContinueOption_(self,opts):
|
31 |
|
|
|
32 |
|
|
# Look for the '-continue' option.
|
33 |
|
|
|
34 |
|
|
for opt in opts.keys():
|
35 |
|
|
if ( opt in ('-continue','-c') ):
|
36 |
|
|
self.flag_continue = 1
|
37 |
|
|
val = opts[opt]
|
38 |
|
|
if val:
|
39 |
|
|
if val[0] == '/': self.continue_dir = val # abs path
|
40 |
|
|
else: self.continue_dir = os.getcwd() + '/' + val # rel path
|
41 |
|
|
pass
|
42 |
|
|
break
|
43 |
|
|
pass
|
44 |
|
|
|
45 |
|
|
# Look for actions which has sense only with '-continue'
|
46 |
|
|
|
47 |
|
|
if "-create" not in opts.keys() :
|
48 |
|
|
self.flag_continue = 1
|
49 |
|
|
|
50 |
|
|
if not self.flag_continue: return
|
51 |
|
|
|
52 |
|
|
if not self.continue_dir:
|
53 |
|
|
prefix = self.prog_name + '_'
|
54 |
|
|
self.continue_dir = findLastWorkDir(prefix)
|
55 |
|
|
pass
|
56 |
|
|
|
57 |
|
|
if not self.continue_dir:
|
58 |
|
|
raise CrabException('Cannot find last working directory.')
|
59 |
|
|
|
60 |
|
|
if not os.path.exists(self.continue_dir):
|
61 |
|
|
msg = 'Cannot continue because the working directory <'
|
62 |
|
|
msg += self.continue_dir
|
63 |
|
|
msg += '> does not exist.'
|
64 |
|
|
raise CrabException(msg)
|
65 |
|
|
|
66 |
|
|
return
|
67 |
|
|
|
68 |
|
|
def createWorkSpace(self):
|
69 |
|
|
# create WorkingDir for Multicrab
|
70 |
|
|
if 'MULTICRAB.working_dir' in self.opts.keys():
|
71 |
|
|
self.continue_dir = os.path.abspath(self.opts['MULTICRAB.working_dir'])
|
72 |
|
|
else:
|
73 |
|
|
current_time = time.strftime('%y%m%d_%H%M%S', time.localtime(time.time()))
|
74 |
|
|
self.continue_dir = os.getcwd() + '/' + self.prog_name + '_' + current_time
|
75 |
|
|
|
76 |
|
|
if self.continue_dir and not os.path.exists(self.continue_dir):
|
77 |
|
|
try:
|
78 |
|
|
os.mkdir(self.continue_dir)
|
79 |
|
|
except OSError:
|
80 |
|
|
msg = 'Cannot create '+str(self.continue_dir) +' directory.\n'
|
81 |
|
|
raise CrabException(msg)
|
82 |
|
|
pass
|
83 |
|
|
else:
|
84 |
|
|
msg = 'Directory '+str(self.continue_dir) +' already exist.\n'
|
85 |
|
|
raise CrabException(msg)
|
86 |
|
|
|
87 |
|
|
shutil.copyfile('multicrab.cfg',self.continue_dir+'/multicrab.cfg')
|
88 |
|
|
|
89 |
|
|
return
|
90 |
|
|
|
91 |
|
|
def processIniFile_(self, opts):
|
92 |
|
|
"""
|
93 |
|
|
Processes a configuration INI-file.
|
94 |
|
|
"""
|
95 |
|
|
|
96 |
|
|
# Extract cfg-file name from the cmd-line options.
|
97 |
|
|
|
98 |
|
|
for opt in opts.keys():
|
99 |
|
|
if ( opt == '-cfg' ):
|
100 |
|
|
if self.flag_continue:
|
101 |
|
|
raise CrabException('-continue and -cfg cannot coexist.')
|
102 |
slacapra |
1.8 |
if opts[opt] :
|
103 |
|
|
self.cfg_fname = opts[opt]
|
104 |
slacapra |
1.11 |
del opts[opt] # do not pass cfg further on
|
105 |
slacapra |
1.1 |
else : processHelpOptions()
|
106 |
|
|
pass
|
107 |
|
|
pass
|
108 |
|
|
|
109 |
|
|
# Set default cfg-fname
|
110 |
|
|
|
111 |
|
|
if self.cfg_fname == None:
|
112 |
|
|
if self.flag_continue:
|
113 |
|
|
self.cfg_fname = self.continue_dir + '/multicrab.cfg'
|
114 |
|
|
else:
|
115 |
|
|
self.cfg_fname = 'multicrab.cfg'
|
116 |
|
|
pass
|
117 |
|
|
pass
|
118 |
|
|
|
119 |
|
|
# Load cfg-file
|
120 |
|
|
|
121 |
slacapra |
1.7 |
cfg_params = {}
|
122 |
slacapra |
1.1 |
if self.cfg_fname != None:
|
123 |
|
|
if os.path.exists(self.cfg_fname):
|
124 |
slacapra |
1.7 |
cfg_params = self.loadMultiConfig(self.cfg_fname)
|
125 |
slacapra |
1.1 |
pass
|
126 |
|
|
else:
|
127 |
|
|
msg = 'cfg-file '+self.cfg_fname+' not found.'
|
128 |
|
|
raise CrabException(msg)
|
129 |
|
|
pass
|
130 |
|
|
pass
|
131 |
|
|
|
132 |
|
|
# process the [CRAB] section
|
133 |
|
|
|
134 |
|
|
lhp = len('MULTICRAB.')
|
135 |
slacapra |
1.7 |
for k in cfg_params.keys():
|
136 |
slacapra |
1.1 |
if len(k) >= lhp and k[:lhp] == 'MULTICRAB.':
|
137 |
|
|
opt = '-'+k[lhp:]
|
138 |
|
|
if len(opt) >= 3 and opt[:3] == '-__': continue
|
139 |
|
|
if opt not in opts.keys():
|
140 |
slacapra |
1.7 |
opts[opt] = cfg_params[k]
|
141 |
slacapra |
1.1 |
pass
|
142 |
|
|
pass
|
143 |
|
|
pass
|
144 |
|
|
|
145 |
|
|
self.cfg_params_dataset = {}
|
146 |
slacapra |
1.3 |
common_opts = {}
|
147 |
slacapra |
1.1 |
# first get common sections
|
148 |
slacapra |
1.7 |
for sec in cfg_params:
|
149 |
slacapra |
1.1 |
if sec in ['MULTICRAB']:
|
150 |
slacapra |
1.8 |
if 'cfg' in cfg_params[sec]:
|
151 |
|
|
common_opts['cfg']=cfg_params[sec]['cfg']
|
152 |
slacapra |
1.1 |
continue
|
153 |
|
|
if sec in ['COMMON']:
|
154 |
slacapra |
1.8 |
common_opts.update(cfg_params[sec])
|
155 |
slacapra |
1.1 |
continue
|
156 |
|
|
pass
|
157 |
|
|
|
158 |
slacapra |
1.8 |
crab_cfg='crab.cfg'
|
159 |
|
|
if common_opts.has_key('cfg') : crab_cfg=common_opts['cfg']
|
160 |
|
|
|
161 |
slacapra |
1.1 |
# then Dataset's specific
|
162 |
slacapra |
1.7 |
for sec in cfg_params:
|
163 |
slacapra |
1.1 |
if sec in ['MULTICRAB', 'COMMON']: continue
|
164 |
slacapra |
1.7 |
self.cfg_params_dataset[sec]=cfg_params[sec]
|
165 |
slacapra |
1.1 |
# add common to all dataset
|
166 |
slacapra |
1.3 |
for key in common_opts:
|
167 |
|
|
self.cfg_params_dataset[sec][key]=common_opts[key]
|
168 |
slacapra |
1.1 |
pass
|
169 |
|
|
|
170 |
slacapra |
1.2 |
# read crab.cfg file and search for storage_path
|
171 |
slacapra |
1.8 |
crab_cfg_params = loadConfig(crab_cfg,{})
|
172 |
slacapra |
1.7 |
if cfg_params.has_key("COMMON"):
|
173 |
|
|
self.user_remote_dir = cfg_params["COMMON"].get("user.user_remote_dir", crab_cfg_params.get("USER.user_remote_dir",None))
|
174 |
slacapra |
1.6 |
else:
|
175 |
slacapra |
1.7 |
self.user_remote_dir = crab_cfg_params.get("USER.user_remote_dir",None)
|
176 |
slacapra |
1.1 |
return
|
177 |
|
|
|
178 |
|
|
def loadMultiConfig(self, file):
|
179 |
|
|
"""
|
180 |
|
|
returns a dictionary with keys of the form
|
181 |
|
|
<section>.<option> and the corresponding values
|
182 |
|
|
"""
|
183 |
|
|
config={}
|
184 |
|
|
cp = ConfigParser.ConfigParser()
|
185 |
|
|
cp.read(file)
|
186 |
|
|
for sec in cp.sections():
|
187 |
|
|
# print 'Section',sec
|
188 |
|
|
config[sec]={}
|
189 |
|
|
for opt in cp.options(sec):
|
190 |
|
|
#print 'config['+sec+'.'+opt+'] = '+string.strip(cp.get(sec,opt))
|
191 |
|
|
config[sec][opt] = string.strip(cp.get(sec,opt))
|
192 |
|
|
return config
|
193 |
|
|
|
194 |
|
|
def run(self):
|
195 |
|
|
#run crabs
|
196 |
|
|
for sec in self.cfg_params_dataset:
|
197 |
|
|
options={}
|
198 |
|
|
if self.flag_continue:
|
199 |
|
|
options['-c']=sec
|
200 |
|
|
# DatasetName to be used
|
201 |
|
|
options['-USER.ui_working_dir']=sec
|
202 |
|
|
# options from multicrab.cfg
|
203 |
|
|
for opt in self.cfg_params_dataset[sec]:
|
204 |
slacapra |
1.8 |
tmp = "-"+str(opt)
|
205 |
|
|
if len(opt.split("."))==2:
|
206 |
|
|
tmp="-"+string.upper(opt.split(".")[0])+"."+opt.split(".")[1]
|
207 |
|
|
|
208 |
slacapra |
1.1 |
options[tmp]=self.cfg_params_dataset[sec][opt]
|
209 |
slacapra |
1.2 |
# add section to storage_path if exist in crab.cfg
|
210 |
slacapra |
1.6 |
if not self.cfg_params_dataset.has_key("USER.user_remote_dir") and self.user_remote_dir:
|
211 |
slacapra |
1.5 |
options["-USER.user_remote_dir"]=self.user_remote_dir+"/"+sec
|
212 |
slacapra |
1.1 |
# Input options (command)
|
213 |
|
|
for opt in self.opts:
|
214 |
|
|
options[opt]=self.opts[opt]
|
215 |
slacapra |
1.9 |
if self.flag_continue and options.has_key("-cfg"):
|
216 |
|
|
del options['-cfg']
|
217 |
slacapra |
1.1 |
try:
|
218 |
|
|
crab = Crab(options)
|
219 |
|
|
crab.run()
|
220 |
|
|
common.apmon.free()
|
221 |
slacapra |
1.5 |
del crab
|
222 |
slacapra |
1.10 |
print '\n############################## E N D ####################################\n'
|
223 |
slacapra |
1.1 |
except CrabException, e:
|
224 |
|
|
print '\n' + common.prog_name + ': ' + str(e) + '\n'
|
225 |
|
|
if common.logger:
|
226 |
|
|
common.logger.write('ERROR: '+str(e)+'\n')
|
227 |
|
|
pass
|
228 |
|
|
pass
|
229 |
|
|
pass
|
230 |
|
|
pass
|
231 |
|
|
|
232 |
|
|
#common.apmon.free()
|
233 |
|
|
|
234 |
|
|
###########################################################################
|
235 |
|
|
if __name__ == '__main__':
|
236 |
|
|
## Get rid of some useless warning
|
237 |
|
|
try:
|
238 |
|
|
import warnings
|
239 |
|
|
warnings.simplefilter("ignore", RuntimeWarning)
|
240 |
|
|
except ImportError:
|
241 |
|
|
pass # too bad, you'll get the warning
|
242 |
|
|
|
243 |
|
|
# Parse command-line options and create a dictionary with
|
244 |
|
|
# key-value pairs.
|
245 |
|
|
options = parseOptions(sys.argv[1:])
|
246 |
|
|
|
247 |
|
|
# Process "help" options, such as '-help', '-version'
|
248 |
|
|
if processHelpOptions(options) : sys.exit(0)
|
249 |
|
|
|
250 |
|
|
# Create, initialize, and run a Crab object
|
251 |
|
|
try:
|
252 |
|
|
multicrab = MultiCrab(options)
|
253 |
|
|
multicrab.run()
|
254 |
|
|
except CrabException, e:
|
255 |
|
|
print '\n' + common.prog_name + ': ' + str(e) + '\n'
|
256 |
|
|
|
257 |
|
|
pass
|