CMS 3D CMS Logo

visDQMUpload.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 
3 from __future__ import print_function
4 import sys
5 import os
6 import re
7 import string
8 import mimetypes
9 import http.client as httplib
10 import gzip
11 import hashlib
12 from stat import *
13 
14 try:
15  import urllib.request as urllib2
16 except ImportError:
17  import urllib2
18 
19 try:
20  from commands import getstatusoutput
21 except ImportError:
22  from subprocess import getstatusoutput
23 
24 try:
25  from Monitoring.DQM import visDQMUtils
26 except:
27  from DQMServices.FileIO import visDQMUtils
28 
29 if sys.version_info[:3] >= (2, 4, 0):
30  HTTPS = httplib.HTTPSConnection
31 else:
32  HTTPS = httplib.HTTPS
33 
34 ssl_key_file = None
35 ssl_cert_file = None
36 
38  def __init__(self, host, *args, **kwargs):
39  HTTPS.__init__(self, host, key_file = ssl_key_file, cert_file = ssl_cert_file, **kwargs)
40 
41 class HTTPSCertAuthenticate(urllib2.AbstractHTTPHandler):
42  def default_open(self, req):
43  return self.do_open(HTTPSCertAuth, req)
44 
45 def filetype(filename):
46  return mimetypes.guess_type(filename)[0] or 'application/octet-stream'
47 
48 def encode(args, files):
49  """
50  Encode form (name, value) and (name, filename, type) elements into
51  multi-part/form-data. We don't actually need to know what we are
52  uploading here, so just claim it's all text/plain.
53  """
54  boundary = b'----------=_DQM_FILE_BOUNDARY_=-----------'
55  (body, crlf) = (b'', b'\r\n')
56  for (key, value) in args.items():
57  payload = str(value).encode('utf-8')
58  body += b'--' + boundary + crlf
59  body += (b'Content-Disposition: form-data; name="%s"' % key.encode('utf-8')) + crlf
60  body += crlf + payload + crlf
61  for (key, filename) in files.items():
62  body += b'--' + boundary + crlf
63  body += (b'Content-Disposition: form-data; name="%s"; filename="%s"'
64  % (key.encode('utf-8'), os.path.basename(filename).encode('utf-8'))) + crlf
65  body += (b'Content-Type: %s' % filetype(filename).encode('utf-8')) + crlf
66  body += (b'Content-Length: %d' % os.stat(filename)[ST_SIZE]) + crlf
67  with open(filename, 'rb') as file:
68  body += crlf + file.read() + crlf
69  body += b'--' + boundary + b'--' + crlf + crlf
70  return (b'multipart/form-data; boundary=' + boundary, body)
71 
72 def marshall(args, files, request):
73  """
74  Marshalls the arguments to the CGI script as multi-part/form-data,
75  not the default application/x-www-form-url-encoded. This improves
76  the transfer of the large inputs and eases command line invocation
77  of the CGI script.
78  """
79  (type, body) = encode(args, files)
80  request.add_header('Content-Type', type)
81  request.add_header('Content-Length', str(len(body)))
82  request.data = body
83 
84 def upload(url, args, files):
85  ident = "visDQMUpload DQMGUI/%s python/%s" % \
86  (os.getenv('DQMGUI_VERSION', '?'), "%d.%d.%d" % sys.version_info[:3])
87  datareq = urllib2.Request(url + '/data/put')
88  datareq.add_header('Accept-encoding', 'gzip')
89  datareq.add_header('User-agent', ident)
90  marshall(args, files, datareq)
91  if 'https://' in url:
92  result = urllib2.build_opener(HTTPSCertAuthenticate()).open(datareq)
93  else:
94  result = urllib2.build_opener(urllib2.ProxyHandler({})).open(datareq)
95 
96  data = result.read()
97  if result.headers.get ('Content-encoding', '') == 'gzip':
98  data = gzip.GzipFile (fileobj=StringIO(data)).read ()
99  return (result.headers, data)
100 
101 x509_path = os.getenv("X509_USER_PROXY", None)
102 if x509_path and os.path.exists(x509_path):
103  ssl_key_file = ssl_cert_file = x509_path
104 
105 if not ssl_key_file:
106  x509_path = os.getenv("X509_USER_KEY", None)
107  if x509_path and os.path.exists(x509_path):
108  ssl_key_file = x509_path
109 
110 if not ssl_cert_file:
111  x509_path = os.getenv("X509_USER_CERT", None)
112  if x509_path and os.path.exists(x509_path):
113  ssl_cert_file = x509_path
114 
115 if not ssl_key_file and not ssl_cert_file:
116  (status, uid) = getstatusoutput("id -u")
117  if os.path.exists("/tmp/x509up_u%s" % uid):
118  ssl_key_file = ssl_cert_file = "/tmp/x509up_u%s" % uid
119 
120 if not ssl_key_file:
121  x509_path = os.getenv("HOME") + "/.globus/userkey.pem"
122  if os.path.exists(x509_path):
123  ssl_key_file = x509_path
124 
125 if not ssl_cert_file:
126  x509_path = os.getenv("HOME") + "/.globus/usercert.pem"
127  if os.path.exists(x509_path):
128  ssl_cert_file = x509_path
129 
130 if 'https://' in sys.argv[1] and (not ssl_key_file or not os.path.exists(ssl_key_file)):
131  print("no certificate private key file found", file=sys.stderr)
132  sys.exit(1)
133 
134 if 'https://' in sys.argv[1] and (not ssl_cert_file or not os.path.exists(ssl_cert_file)):
135  print("no certificate public key file found", file=sys.stderr)
136  sys.exit(1)
137 
138 try:
139  for file_path in sys.argv[2:]:
140  # Before even trying to make a call to the other side, we first do a check on
141  # the filename:
142  classification_ok, classification_result = visDQMUtils.classifyDQMFile(file_path)
143  if not classification_ok:
144  print("Check of filename before upload failed with following message:")
145  print(classification_result)
146  sys.exit(1)
147  # If file check was fine, we continue with the upload method:
148  else:
149  print("Using SSL private key", ssl_key_file)
150  print("Using SSL public key", ssl_cert_file)
151 
152  hasher = hashlib.md5()
153  with open(sys.argv[2], 'rb') as file:
154  buf = file.read()
155  hasher.update(buf)
156 
157  (headers, data) = \
158  upload(sys.argv[1],
159  { 'size': os.stat(sys.argv[2])[ST_SIZE],
160  'checksum': 'md5:%s' % hasher.hexdigest() },
161  { 'file': file_path })
162  print('Status code: ', headers.get("Dqm-Status-Code", "None"))
163  print('Message: ', headers.get("Dqm-Status-Message", "None"))
164  print('Detail: ', headers.get("Dqm-Status-Detail", "None"))
165  print(data.decode('utf-8'))
166  sys.exit(0)
167 except urllib2.HTTPError as e:
168  print('ERROR', e)
169  print('Status code: ', e.hdrs.get("Dqm-Status-Code", "None"))
170  print('Message: ', e.hdrs.get("Dqm-Status-Message", "None"))
171  print('Detail: ', e.hdrs.get("Dqm-Status-Detail", "None"))
172  sys.exit(1)
visDQMUpload.HTTPSCertAuthenticate.default_open
def default_open(self, req)
Definition: visDQMUpload.py:42
visDQMUpload.HTTPSCertAuthenticate
Definition: visDQMUpload.py:41
visDQMUpload.HTTPSCertAuth
Definition: visDQMUpload.py:37
visDQMUpload.HTTPS
HTTPS
Definition: visDQMUpload.py:30
visDQMUpload.HTTPSCertAuth.__init__
def __init__(self, host, *args, **kwargs)
Definition: visDQMUpload.py:38
str
#define str(s)
Definition: TestProcessor.cc:48
visDQMUpload.encode
def encode(args, files)
Definition: visDQMUpload.py:48
visDQMUpload.marshall
def marshall(args, files, request)
Definition: visDQMUpload.py:72
visDQMUpload.upload
def upload(url, args, files)
Definition: visDQMUpload.py:84
visDQMUpload.filetype
def filetype(filename)
Definition: visDQMUpload.py:45
visDQMUtils.classifyDQMFile
def classifyDQMFile(path)
Definition: visDQMUtils.py:29
edm::print
S & print(S &os, JobReport::InputFile const &f)
Definition: JobReport.cc:66