Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-11-25 02:29:10

0001 #!/usr/bin/env python3
0002 
0003 import sys, os, os.path, re, string, httplib, mimetypes, urllib, urllib2, httplib, gzip, md5
0004 from cStringIO import StringIO
0005 from stat import *
0006 import optparse
0007 
0008 try:
0009     import hashlib
0010 except:
0011     pass
0012 
0013 HTTPS = httplib.HTTPS
0014 if sys.version_info[:3] >= (2, 4, 0):
0015   HTTPS = httplib.HTTPSConnection
0016 
0017 ssl_key_file = None
0018 ssl_cert_file = None
0019 
0020 class HTTPSCertAuth(HTTPS):
0021   def __init__(self, host, *args, **kwargs):
0022     HTTPS.__init__(self, host, key_file = ssl_key_file, cert_file = ssl_cert_file, **kwargs)
0023 
0024 class HTTPSCertAuthenticate(urllib2.AbstractHTTPHandler):
0025   def default_open(self, req):
0026     return self.do_open(HTTPSCertAuth, req)
0027 
0028 def filetype(filename):
0029   return mimetypes.guess_type(filename)[0] or 'application/octet-stream'
0030 
0031 def encode(args, files):
0032   """
0033     Encode form (name, value) and (name, filename, type) elements into
0034     multi-part/form-data. We don't actually need to know what we are
0035     uploading here, so just claim it's all text/plain.
0036   """
0037   boundary = '----------=_DQM_FILE_BOUNDARY_=-----------'
0038   (body, crlf) = ('', '\r\n')
0039   for (key, value) in args.items():
0040     body += '--' + boundary + crlf
0041     body += ('Content-disposition: form-data; name="%s"' % key) + crlf
0042     body += crlf + str(value) + crlf
0043   for (key, filename) in files.items():
0044     body += '--' + boundary + crlf
0045     body += ('Content-Disposition: form-data; name="%s"; filename="%s"'
0046              % (key, os.path.basename(filename))) + crlf
0047     body += ('Content-Type: %s' % filetype(filename)) + crlf
0048     body += crlf + open(filename, "r").read() + crlf
0049   body += '--' + boundary + '--' + crlf + crlf
0050   return ('multipart/form-data; boundary=' + boundary, body)
0051 
0052 def marshall(args, files, request):
0053   """
0054     Marshalls the arguments to the CGI script as multi-part/form-data,
0055     not the default application/x-www-form-url-encoded.  This improves
0056     the transfer of the large inputs and eases command line invocation
0057     of the CGI script.
0058   """
0059   (type, body) = encode(args, files)
0060   request.add_header('Content-type', type)
0061   request.add_header('Content-length', str(len(body)))
0062   request.add_data(body)
0063 
0064 def upload(url, args, files):
0065   ident = "visDQMUpload DQMGUI/%s CMSSW/%s python/%s" % \
0066     (os.getenv('DQMGUI_VERSION', '?'),
0067      os.getenv('DQM_CMSSW_VERSION', os.getenv('CMSSW_VERSION', '?')),
0068      "%d.%d.%d" % sys.version_info[:3])
0069   cookie = None
0070   if url.startswith("https:"):
0071     authreq = urllib2.Request(url + '/authenticate')
0072     authreq.add_header('User-agent', ident)
0073     result = urllib2.build_opener(HTTPSCertAuthenticate()).open(authreq)
0074     cookie = result.headers.get('Set-Cookie')
0075     if not cookie:
0076       raise RuntimeError("Did not receive authentication cookie")
0077     cookie = cookie.split(";")[0]
0078 
0079   datareq = urllib2.Request(url + '/data/put')
0080   datareq.add_header('Accept-encoding', 'gzip')
0081   datareq.add_header('User-agent', ident)
0082   if cookie:
0083     datareq.add_header('Cookie', cookie)
0084   marshall(args, files, datareq)
0085   result = urllib2.build_opener().open(datareq)
0086   data = result.read()
0087   if result.headers.get ('Content-encoding', '') == 'gzip':
0088     data = gzip.GzipFile (fileobj=StringIO(data)).read ()
0089   return (result.headers, data)
0090 
0091 def print_help(*args):
0092     sys.stdout.write("\n")
0093     sys.stdout.write("This scripts intends to do the upload of files to the DQM server. It\n")
0094     sys.stdout.write("runs some basic checks on the file name as it is crucial to follow\n")
0095     sys.stdout.write("the naming convention.\n")
0096     sys.stdout.write("\n")
0097     sys.stdout.write("Mandatory Option\n")
0098     sys.stdout.write("    -d, --destination parameter to specify the DQM server\n")
0099     sys.stdout.write("\n")
0100     sys.stdout.write("  Proxy Options\n")
0101     sys.stdout.write("  The script will try to find your grid proxy automatically. To\n")
0102     sys.stdout.write("  do so, it checks $X509_* environment variables and your globus\n")
0103     sys.stdout.write("  directory (~/.globus). To override this automatism, you can use\n")
0104     sys.stdout.write("  the following two options:\n")
0105     sys.stdout.write("    --ssl-key-file          location of your private key\n")
0106     sys.stdout.write("    --ssl-cert-file         location of your public key\n")
0107     sys.stdout.write("\n")
0108     sys.stdout.write("Other Options\n")
0109     sys.stdout.write("    -h, --help                show this help message\n")
0110     sys.stdout.write("    -s, --no-submission       suppress the submission\n")
0111     sys.stdout.write("    -r, --no-registration     suppress the submission\n")
0112     sys.stdout.write("    --no-filename-check       omit the file name check\n")
0113     sys.stdout.write("\n")
0114     sys.exit(0)
0115 
0116 def checkSSL(opts):
0117     global ssl_key_file
0118     global ssl_cert_file
0119     
0120     if opts.ssl_key_file and os.path.exists(opts.ssl_key_file):
0121         ssl_key_file = opts.ssl_key_file
0122     if opts.ssl_cert_file and os.path.exists(opts.ssl_cert_file):
0123         ssl_cert_file = opts.ssl_cert_file
0124 
0125     if not ssl_key_file:
0126         x509_path = os.getenv("X509_USER_PROXY", None)
0127         if x509_path and os.path.exists(x509_path):
0128             ssl_key_file = ssl_cert_file = x509_path
0129 
0130     if not ssl_key_file:
0131         x509_path = os.getenv("X509_USER_KEY", None)
0132         if x509_path and os.path.exists(x509_path):
0133             ssl_key_file = x509_path
0134 
0135     if not ssl_cert_file:
0136         x509_path = os.getenv("X509_USER_CERT", None)
0137         if x509_path and os.path.exists(x509_path):
0138             ssl_cert_file = x509_path
0139     
0140     if not ssl_key_file:
0141         x509_path = os.getenv("HOME") + "/.globus/userkey.pem"
0142         if os.path.exists(x509_path):
0143             ssl_key_file = x509_path
0144 
0145     if not ssl_cert_file:
0146         x509_path = os.getenv("HOME") + "/.globus/usercert.pem"
0147         if os.path.exists(x509_path):
0148             ssl_cert_file = x509_path
0149     
0150     if not ssl_key_file or not os.path.exists(ssl_key_file):
0151         sys.stderr.write("no certificate private key file found, please specify one via $X509_USER_PROXY, $X509_USER_KEY or --ssl-key-file\n")
0152         sys.exit(2)
0153                   
0154     if not ssl_cert_file or not os.path.exists(ssl_cert_file):
0155         sys.stderr.write("no certificate public key file found, please specify one via $X509_USER_CERT or --ssl-cert-file\n")
0156         sys.exit(3)
0157 
0158     print("Using SSL private key", ssl_key_file)
0159     print("Using SSL public key", ssl_cert_file)
0160 
0161                                                                                   
0162 def checkFileName(fileName):
0163     regWhitespace = re.compile('.*\s.*')
0164     if regWhitespace.match(fileName):
0165         sys.stderr.write("whitespace detected!\n")
0166         return False
0167             
0168     regRelval=re.compile('.*relval.*')
0169     regCMSSW=re.compile('.*CMSSW_[0-9]+_[0-9]+_[0-9]+_.*')
0170     regCMSSWpre=re.compile('.*CMSSW_[0-9]+_[0-9]+_[0-9]+_pre[0-9]+_.*')
0171     if regRelval.match(fileName):
0172         # TODO check for pre-versions
0173         if not regCMSSW.match(fileName):
0174             print("no CMSSW")
0175     return True
0176     # DQM stuff
0177 
0178 def startUpload(url, filename):
0179     global ssl_key_file
0180     global ssl_cert_file
0181 
0182     print(url, filename)
0183     try:
0184         (headers, data) = \
0185                   upload(url,
0186                      { 'size': os.stat(filename).st_size,
0187                        'checksum': "md5:%s" % md5.new(file(filename).read()).hexdigest() },
0188                      { 'file': filename })
0189         print('Status code: ', headers.get("Dqm-Status-Code", "None"))
0190         print('Message:     ', headers.get("Dqm-Status-Message", "None"))
0191         print('Detail:      ', headers.get("Dqm-Status-Detail", "None"))
0192         print(data)
0193     except urllib2.HTTPError as e:
0194         print("ERROR", e)
0195         print('Status code: ', e.hdrs.get("Dqm-Status-Code", "None"))
0196         print('Message:     ', e.hdrs.get("Dqm-Status-Message", "None"))
0197         print('Detail:      ', e.hdrs.get("Dqm-Status-Detail", "None"))
0198         sys.exit(1)
0199 
0200 def getURL(filename, destination):
0201     filename = filename.split("/")[-1]
0202     regMC=re.compile('.*_R([0-9]*)__*')
0203     if regMC.match(filename):
0204         m = re.search('.*_R([0-9]*)(__.*).root',filename)
0205         runNr = m.group(1)
0206         dataset = m.group(2).replace("__","/")
0207     else:
0208         m = re.search('.*_R([0-9]*)(_?.*).root',filename)
0209         runNr = m.group(1)
0210         dataset = m.group(2).replace("__","/")
0211         if dataset=="":
0212             dataset="/Global/Online/ALL"
0213     if not runNr:
0214         runNr="1"
0215     if (int(runNr)==1):
0216         return destination+"start?workspace=summary;dataset="+dataset+";sampletype=offline_data"
0217     else:
0218         return destination+"start?workspace=summary;runnr="+runNr+";dataset="+dataset+";sampletype=online_data"
0219     
0220 def registerFileAtLogServer(filename, destination, tags):
0221     filename = filename.split("/")[-1]
0222     regMC=re.compile('.*_R([0-9]*)__*')
0223     if regMC.match(filename):
0224         m = re.search('.*_R([0-9]*)(__.*).root',filename)
0225         runNr = m.group(1)
0226         dataset = m.group(2).replace("__","/")
0227     else:
0228         m = re.search('.*_R([0-9]*)(_?.*).root',filename)
0229         runNr = m.group(1)
0230         dataset = m.group(2).replace("__","/")
0231         if dataset=="":
0232             dataset="/Global/Online/ALL"
0233     tempurl = "https://www-ekp.physik.uni-karlsruhe.de/~zeise/cgi-bin/register.py?run="+runNr+"&dataset="+dataset+"&filename="+filename+"&tags="+tags+"&instance="+destination
0234     print("Link that is used to register: ", tempurl)
0235     urllib.urlopen(tempurl)
0236 
0237 def main(args):
0238     global opts
0239     parser = optparse.OptionParser(add_help_option=False)
0240     parser.add_option("-h", "--help",          action="callback", callback=print_help),
0241     parser.add_option("",   "--no-filename-check", dest="no_filename_check",  default=False, action="store_true")
0242     parser.add_option("-d", "--destination", dest="destination", default="",  action="store")
0243     parser.add_option("-t", "--tags", dest="tags", default="",  action="store")
0244     parser.add_option("-s", "--no-submission", dest="submission", default=True,  action="store_false")
0245     parser.add_option("-r", "--no-registration", dest="registration", default=True,  action="store_false")
0246     parser.add_option("","--ssl-key-file", dest="ssl_key_file", default="", action="store")
0247     parser.add_option("","--ssl-cert-file", dest="ssl_cert_file", default="", action="store")
0248     (opts, args) = parser.parse_args()
0249     opts.abort = False
0250 
0251     if not opts.destination:
0252         sys.stderr.write("no destination specified\n")
0253         sys.exit(4)
0254     checkSSL(opts)
0255 
0256     if len(args)==0:
0257         sys.stderr.write("no input files specified\n")
0258         sys.exit(1)
0259     for fileName in args:
0260         fileName=fileName.strip()
0261         if not os.path.exists(fileName):
0262             sys.stderr.write("file '%s' doesn't exist!\n" % fileName)
0263             continue
0264         if not opts.no_filename_check and not checkFileName(fileName):
0265             continue
0266         sys.stderr.write("file '%s' passed name check, upload will follow!\n" % fileName)
0267         if opts.submission:
0268           startUpload(opts.destination, fileName)
0269         else:
0270           sys.stdout.write("file '%s' would be uploaded to '%s'\n" % (fileName, opts.destination))
0271         if opts.registration:
0272           registerFileAtLogServer(fileName, opts.destination, opts.tags)       
0273         print("You should see the plots here: "+getURL(fileName, opts.destination))
0274 
0275 if __name__ == '__main__':
0276     sys.exit(main(sys.argv[1:]))
0277     
0278