CMS 3D CMS Logo

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