CMS 3D CMS Logo

cmsLHEtoEOSManager.py
Go to the documentation of this file.
1 #!/bin/sh
2 
3 """:"
4 
5 python_cmd="python"
6 python3 -c "from FWCore.PythonFramework.CmsRun import CmsRun" 2>/dev/null && python_cmd="python3"
7 exec ${python_cmd} $0 ${1+"$@"}
8 
9 """
10 
11 from __future__ import print_function
12 print('Starting cmsLHEtoEOSManager.py')
13 
14 __version__ = "$Revision: 1.13 $"
15 
16 import os
17 import subprocess
18 import time
19 import re
20 
21 defaultEOSRootPath = '/eos/cms/store/lhe'
22 if "CMSEOS_LHE_ROOT_DIRECTORY" in os.environ:
23  defaultEOSRootPath = os.environ["CMSEOS_LHE_ROOT_DIRECTORY"]
24 defaultEOSLoadPath = 'root://eoscms.cern.ch/'
25 defaultEOSlistCommand = 'xrdfs '+defaultEOSLoadPath+' ls '
26 defaultEOSmkdirCommand = 'xrdfs '+defaultEOSLoadPath+' mkdir '
27 defaultEOSfeCommand = 'xrdfs '+defaultEOSLoadPath+' stat -q IsReadable '
28 defaultEOSchecksumCommand = 'xrdfs '+defaultEOSLoadPath+' query checksum '
29 defaultEOScpCommand = 'xrdcp -np '
30 
31 def findXrdDir(theDirRecord):
32 
33  elements = theDirRecord.split(' ')
34  if len(elements):
35  return elements[-1].rstrip('\n').split('/')[-1]
36  else:
37  return None
38 
39 def articleExist(artId):
40 
41  itExists = False
42  theCommand = defaultEOSlistCommand+' '+defaultEOSRootPath
43  dirList = subprocess.Popen(["/bin/sh","-c",theCommand], stdout=subprocess.PIPE, universal_newlines=True)
44  for line in dirList.stdout.readlines():
45  if findXrdDir(line) == str(artId):
46  itExists = True
47 
48  return itExists
49 
51 
52  artList = [0]
53 
54  theCommand = defaultEOSlistCommand+' '+defaultEOSRootPath
55  dirList = subprocess.Popen(["/bin/sh","-c",theCommand], stdout=subprocess.PIPE, universal_newlines=True)
56  for line in dirList.stdout.readlines():
57  try:
58  if line.rstrip('\n') != '':
59  artList.append(int(findXrdDir(line)))
60  except:
61  break
62 
63  return max(artList)
64 
65 
66 def fileUpload(uploadPath,lheList, checkSumList, reallyDoIt, force=False):
67 
68  inUploadScript = ''
69  index = 0
70  for f in lheList:
71  realFileName = f.split('/')[-1]
72  # Check the file existence
73  newFileName = uploadPath+'/'+str(realFileName)
74  addFile = True
75  additionalOption = ''
76  theCommand = defaultEOSfeCommand+' '+newFileName
77  exeFullList = subprocess.Popen(["/bin/sh","-c",theCommand], stdout=subprocess.PIPE, universal_newlines=True)
78  result = exeFullList.stdout.readlines()
79  if [line for line in result if ("flags:" in line.lower()) and ("isreadable" in line.lower())] and (not force):
80  addFile = False
81  print('File '+newFileName+' already exists: do you want to overwrite? [y/n]')
82  reply = raw_input()
83  if reply == 'y' or reply == 'Y':
84  addFile = True
85  additionalOption = ' -f '
86  print('')
87  print('Overwriting file '+newFileName+'\n')
88  # add the file
89  if addFile:
90 # print 'Adding file '+str(f)+'\n'
91  inUploadScript = defaultEOScpCommand + additionalOption + ' ' + str(f) + ' ' + defaultEOSLoadPath+uploadPath + '/' + str(realFileName)
92  print('Uploading file %s...' % str(f))
93  if reallyDoIt:
94  exeRealUpload = subprocess.Popen(["/bin/sh","-c",inUploadScript])
95  exeRealUpload.communicate()
96  eosCheckSumCommand = defaultEOSchecksumCommand + uploadPath + '/' + str(realFileName) + ' | awk \'{print $2}\' | cut -d= -f2'
97  exeEosCheckSum = subprocess.Popen(eosCheckSumCommand ,shell=True, stdout=subprocess.PIPE, universal_newlines=True)
98  EosCheckSum = exeEosCheckSum.stdout.read()
99  assert exeEosCheckSum.wait() == 0
100  # print 'checksum: eos = ' + EosCheckSum + 'orig file = ' + checkSumList[index] + '\n'
101  if checkSumList[index] not in EosCheckSum:
102  print('WARNING! The checksum for file ' + str(realFileName) + ' in EOS\n')
103  print(EosCheckSum + '\n')
104  print('does not match the checksum of the original one\n')
105  print(checkSumList[index] + '\n')
106  print('please try to re-upload file ' + str(realFileName) + ' to EOS.\n')
107  else:
108  print('Checksum OK for file ' + str(realFileName))
109  index = index+1
110 
111 # launch the upload shell script
112 
113 # print '\n Launching upload script \n'+inUploadScript+'\n at '+time.asctime(time.localtime(time.time()))+' ...\n'
114 # if reallyDoIt:
115 # exeRealUpload = subprocess.Popen(["/bin/sh","-c",inUploadScript])
116 # exeRealUpload.communicate()
117  print('\n Upload ended at '+time.asctime(time.localtime(time.time())))
118 
119 
120 
121 if __name__ == '__main__':
122 
123  import optparse
124 
125  # Here we define an option parser to handle commandline options..
126  usage='cmsLHEtoEOSManager.py <options>'
127  parser = optparse.OptionParser(usage)
128  parser.add_option('-f', '--file',
129  help='LHE local file list to be uploaded, separated by ","' ,
130  default='',
131  dest='fileList')
132 
133  parser.add_option('-F', '--files-from', metavar = 'FILE',
134  help='File containing the list of LHE local files be uploaded, one file per line')
135 
136  parser.add_option('-n', '--new',
137  help='Create a new article' ,
138  action='store_true',
139  default=False,
140  dest='newId')
141 
142  parser.add_option('-u', '--update',
143  help='Update the article <Id>' ,
144  default=0,
145  type=int,
146  dest='artIdUp')
147 
148  parser.add_option('-l', '--list',
149  help='List the files in article <Id>' ,
150  default=0,
151  type=int,
152  dest='artIdLi')
153 
154  parser.add_option('-d', '--dry-run',
155  help='dry run, it does nothing, but you can see what it would do',
156  action='store_true',
157  default=False,
158  dest='dryRun')
159 
160  parser.add_option('-c', '--compress',
161  help='compress the local .lhe file with xz before upload',
162  action='store_true',
163  default=False,
164  dest='compress')
165 
166  parser.add_option('--force',
167  help='Force update if file already exists.',
168  action='store_true',
169  default=False,
170  dest='force')
171 
172  (options,args) = parser.parse_args()
173 
174  # print banner
175 
176  print('')
177  print('cmsLHEtoEOSmanager '+__version__[1:-1])
178  print('')
179  print('Running on ',time.asctime(time.localtime(time.time())))
180  print('')
181 
182  reallyDoIt = not options.dryRun
183 
184  # Now some fault control. If an error is found we raise an exception
185  if not options.newId and options.artIdUp==0 and options.artIdLi==0:
186  raise Exception('Please specify the action to be taken, either "-n", "-u" or "-l"!')
187 
188  if options.fileList == '' and not options.files_from and (options.newId or options.artIdUp!=0):
189  raise Exception('Please provide the input file list!')
190 
191  if (options.newId and (options.artIdUp != 0 or options.artIdLi != 0)) or (options.artIdUp != 0 and options.artIdLi != 0):
192  raise Exception('Options "-n", "-u" and "-l" are mutually exclusive, please choose only one!')
193 
194  if options.newId:
195  print('Action: create new article\n')
196  elif options.artIdUp != 0:
197  print('Action: update article '+str(options.artIdUp)+'\n')
198  elif options.artIdLi != 0:
199  print('Action: list content of article '+str(options.artIdLi)+'\n')
200 
201  if options.artIdLi==0:
202  theList = []
203  if len(options.fileList) > 0:
204  theList=(options.fileList.split(','))
205 
206  if options.files_from:
207  try:
208  f = open(options.files_from)
209  except IOError:
210  raise Exception('Cannot open the file list, \'%s\'' % options.files_from)
211  for l in f:
212  l = l.strip()
213  if len(l) == 0 or l[0] == '#':
214  continue
215  theList.append(l)
216 
217  theCompressedFilesList = []
218  theCheckSumList = []
219  for f in theList:
220  # Check the file name extension
221  print(f)
222  if not ( f.lower().endswith(".lhe") or f.lower().endswith(".lhe.xz") ):
223  raise Exception('Input file name must have the "lhe" or "lhe.xz" final extension!')
224  if( f.lower().endswith(".lhe.xz") ):
225  print("Important! Input file "+f+" is already zipped: please make sure you verified its integrity with xmllint before zipping it. You can do it with:\n")
226  print("xmllint file.lhe\n")
227  print("Otherwise it is best to pass the unzipped file to this script and let it check its integrity and compress the file with the --compress option\n")
228  # Check the local file existence
229  if not os.path.exists(f):
230  raise Exception('Input file '+f+' does not exists')
231  if( f.lower().endswith(".lhe") ):
232  theCheckIntegrityCommand = 'xmllint -noout '+f
233  exeCheckIntegrity = subprocess.Popen(["/bin/sh","-c", theCheckIntegrityCommand])
234  intCode = exeCheckIntegrity.wait()
235  if(intCode != 0):
236  raise Exception('Input file '+f+ ' is corrupted')
237  if reallyDoIt and options.compress:
238  print("Compressing file",f)
239  if( f.lower().endswith(".lhe.xz") ):
240  raise Exception('Input file '+f+' is already compressed! This is inconsistent with the --compress option!')
241  theCompressionCommand = 'xz '+f
242  exeCompression = subprocess.Popen(["/bin/sh","-c",theCompressionCommand])
243  exeCompression.communicate()
244  theCompressedFilesList.append(f+'.xz')
245  if reallyDoIt and options.compress:
246  theList = theCompressedFilesList
247  for f in theList:
248  try:
249  exeCheckSum = subprocess.Popen(["/afs/cern.ch/cms/caf/bin/cms_adler32",f], stdout=subprocess.PIPE, universal_newlines=True)
250  getCheckSum = subprocess.Popen(["awk", "{print $1}"], stdin=exeCheckSum.stdout, stdout=subprocess.PIPE, universal_newlines=True)
251  exeCheckSum.stdout.close()
252  output,err = getCheckSum.communicate()
253  theCheckSumList.append(output.strip())
254  except:
255  theCheckSumList.append("missing-adler32")
256 
257  newArt = 0
258  uploadPath = ''
259 
260 # new article
261 
262  if options.newId:
263  oldArt = lastArticle()
264  newArt = oldArt+1
265  print('Creating new article with identifier '+str(newArt)+' ...\n')
266  uploadPath = defaultEOSRootPath+'/'+str(newArt)
267  theCommand = defaultEOSmkdirCommand+' '+uploadPath
268  if reallyDoIt:
269  exeUpload = subprocess.Popen(["/bin/sh","-c",theCommand])
270  exeUpload.communicate()
271 
272 # update article
273 
274  elif options.artIdUp != 0:
275  newArt = options.artIdUp
276  if articleExist(newArt):
277  uploadPath = defaultEOSRootPath+'/'+str(newArt)
278  else:
279  raise Exception('Article '+str(newArt)+' to be updated does not exist!')
280 
281 # list article
282 
283  elif options.artIdLi !=0:
284  listPath = defaultEOSRootPath+'/'+str(options.artIdLi)
285  theCommand = defaultEOSlistCommand+' '+listPath
286  exeList = subprocess.Popen(["/bin/sh","-c",theCommand], stdout=subprocess.PIPE, universal_newlines=True)
287  for line in exeList.stdout.readlines():
288  if findXrdDir(line) != None:
289  print(findXrdDir(line))
290 
291 
292  if newArt > 0:
293  fileUpload(uploadPath,theList, theCheckSumList, reallyDoIt, options.force)
294  listPath = defaultEOSRootPath+'/'+str(newArt)
295  print('')
296  print('Listing the '+str(newArt)+' article content after upload:')
297  theCommand = defaultEOSlistCommand+' '+listPath
298  if reallyDoIt:
299  exeFullList = subprocess.Popen(["/bin/sh","-c",theCommand])
300  exeFullList.communicate()
301  else:
302  print('Dry run, nothing was done')
303 
def findXrdDir(theDirRecord)
void print(TMatrixD &m, const char *label=nullptr, bool mathematicaFormat=false)
Definition: Utilities.cc:47
def fileUpload(uploadPath, lheList, checkSumList, reallyDoIt, force=False)
#define str(s)