2 '''Script that uploads to the new CMS conditions uploader. 3 Adapted to the new infrastructure from v6 of the upload.py script for the DropBox from Miguel Ojeda. 6 __author__ =
'Andreas Pfeiffer' 7 __copyright__ =
'Copyright 2015, CERN CMS' 8 __credits__ = [
'Giacomo Govi',
'Salvatore Di Guida',
'Miguel Ojeda',
'Andreas Pfeiffer']
9 __license__ =
'Unknown' 10 __maintainer__ =
'Giacomo Govi' 11 __email__ =
'giacomo.govi@cern.ch' 27 from datetime
import datetime
29 defaultBackend =
'online' 30 defaultHostname =
'cms-conddb-prod.cern.ch' 31 defaultDevHostname =
'cms-conddb-dev.cern.ch' 32 defaultUrlTemplate =
'https://%s/cmsDbUpload/' 33 defaultTemporaryFile =
'upload.tar.bz2' 34 defaultNetrcHost =
'ConditionUploader' 35 defaultWorkflow =
'offline' 36 prodLogDbSrv =
'cms_orcoff_prod' 37 devLogDbSrv =
'cms_orcoff_prep' 38 logDbSchema =
'CMS_COND_DROPBOX' 39 authPathEnvVar =
'COND_AUTH_PATH' 52 '''Like raw_input() but with a default and automatic strip(). 55 answer = raw_input(prompt)
59 return default.strip()
63 '''Like getInput() but tailored to get target workflows (synchronization options). 67 workflow =
getInput(defaultWorkflow, prompt)
69 if workflow
in frozenset([
'offline',
'hlt',
'express',
'prompt',
'pcl']):
72 logging.error(
'Please specify one of the allowed workflows. See above for the explanation on each of them.')
76 '''Makes the user choose from a list of options. 83 return optionsList[
int(index)]
85 logging.error(
'Please specify an index of the list (i.e. integer).')
87 logging.error(
'The index you provided is not in the given list.')
91 '''Like raw_input() but repeats if nothing is provided and automatic strip(). 95 answer = raw_input(prompt)
99 logging.error(
'You need to provide a value.')
102 def runWizard(basename, dataFilename, metadataFilename):
104 print '''\nWizard for metadata for %s 106 I will ask you some questions to fill the metadata file. For some of the questions there are defaults between square brackets (i.e. []), leave empty (i.e. hit Enter) to use them.''' % basename
110 dataConnection = sqlite3.connect(dataFilename)
111 dataCursor = dataConnection.cursor()
112 dataCursor.execute(
'select name from sqlite_master where type == "table"')
113 tables = set(
zip(*dataCursor.fetchall())[0])
117 dataCursor.execute(
'select NAME from TAG')
122 inputTags = dataCursor.fetchall()
123 if len(inputTags) == 0:
125 inputTags =
zip(*inputTags)[0]
130 if len(inputTags) == 0:
131 print '\nI could not find any input tag in your data file, but you can still specify one manually.' 134 '\nWhich is the input tag (i.e. the tag to be read from the SQLite data file)?\ne.g. BeamSpotObject_ByRun\ninputTag: ')
137 print '\nI found the following input tags in your SQLite data file:' 138 for (index, inputTag)
in enumerate(inputTags):
139 print ' %s) %s' % (index, inputTag)
142 '\nWhich is the input tag (i.e. the tag to be read from the SQLite data file)?\ne.g. 0 (you select the first in the list)\ninputTag [0]: ')
144 destinationDatabase =
'' 146 while ( destinationDatabase !=
'oracle://cms_orcon_prod/CMS_CONDITIONS' and destinationDatabase !=
'oracle://cms_orcoff_prep/CMS_CONDITIONS' ):
149 '\nWhich is the destination database where the tags should be exported? \nPossible choices: oracle://cms_orcon_prod/CMS_CONDITIONS (for prod) or oracle://cms_orcoff_prep/CMS_CONDITIONS (for prep) \ndestinationDatabase: ' 152 '\nPlease choose one of the two valid destinations: \noracle://cms_orcon_prod/CMS_CONDITIONS (for prod) or oracle://cms_orcoff_prep/CMS_CONDITIONS (for prep) \ 153 \ndestinationDatabase: ' 155 raise Exception(
'No valid destination chosen. Bailing out...')
161 '\nWhich is the given since? (if not specified, the one from the SQLite data file will be taken -- note that even if specified, still this may not be the final since, depending on the synchronization options you select later: if the synchronization target is not offline, and the since you give is smaller than the next possible one (i.e. you give a run number earlier than the one which will be started/processed next in prompt/hlt/express), the DropBox will move the since ahead to go to the first safe run instead of the value you gave)\ne.g. 1234\nsince []: ')
170 logging.error(
'The since value has to be an integer or empty (null).')
173 '\nWrite any comments/text you may want to describe your request\ne.g. Muon alignment scenario for...\nuserText []: ')
178 '\nWhich is the next destination tag to be added (leave empty to stop)?\ne.g. BeamSpotObjects_PCL_byRun_v0_offline\ndestinationTag []: ')
179 if not destinationTag:
180 if len(destinationTags) == 0:
181 logging.error(
'There must be at least one destination tag.')
185 if destinationTag
in destinationTags:
187 'You already added this destination tag. Overwriting the previous one with this new one.')
189 destinationTags[destinationTag] = {
193 'destinationDatabase': destinationDatabase,
194 'destinationTags': destinationTags,
195 'inputTag': inputTag,
197 'userText': userText,
200 metadata = json.dumps(metadata, sort_keys=
True, indent=4)
201 print '\nThis is the generated metadata:\n%s' % metadata
204 '\nIs it fine (i.e. save in %s and *upload* the conditions if this is the latest file)?\nAnswer [n]: ' % metadataFilename).lower() ==
'y':
206 logging.info(
'Saving generated metadata in %s...', metadataFilename)
207 with open(metadataFilename,
'wb')
as metadataFile:
208 metadataFile.write(metadata)
211 '''A common HTTP exception. 213 self.code is the response HTTP code as an integer. 214 self.response is the response body (i.e. page). 223 self.
args = (response.split(
'<p>')[1].
split(
'</p>')[0], )
228 CERN_SSO_CURL_CAPATH =
'/etc/pki/tls/certs' 231 '''Class used for querying URLs using the HTTP protocol. 234 retryCodes = frozenset([502, 503])
241 self.curl.setopt(self.curl.COOKIEFILE,
'')
246 self.curl.setopt(self.curl.SSL_VERIFYPEER, 0)
247 self.curl.setopt(self.curl.SSL_VERIFYHOST, 2)
254 '''Returns the list of cookies. 256 return self.curl.getinfo(self.curl.INFO_COOKIELIST)
261 self.curl.setopt(self.curl.COOKIELIST,
'ALL')
265 '''Allows to set a base URL which will be prefixed to all the URLs 266 that will be queried later. 272 '''Allows to set a proxy. 274 self.curl.setopt(self.curl.PROXY, proxy)
278 '''Allows to set a timeout. 280 self.curl.setopt(self.curl.TIMEOUT, timeout)
284 '''Allows to set retries. 286 The retries are a sequence of the seconds to wait per retry. 288 The retries are done on: 289 * PyCurl errors (includes network problems, e.g. not being able 290 to connect to the host). 291 * 502 Bad Gateway (for the moment, to avoid temporary 292 Apache-CherryPy issues). 293 * 503 Service Temporarily Unavailable (for when we update 302 self.curl.setopt(pycurl.URL, url)
303 self.curl.setopt(pycurl.VERBOSE, 0)
312 self.curl.setopt(pycurl.HTTPHEADER, [
'Accept: application/json'])
314 self.curl.setopt(self.curl.HTTPGET, 0)
316 response = cStringIO.StringIO()
317 self.curl.setopt(pycurl.WRITEFUNCTION, response.write)
318 self.curl.setopt(pycurl.USERPWD,
'%s:%s' % (username, password) )
319 logging.debug(
'going to connect to server at: %s' % url )
322 code = self.curl.getinfo(pycurl.RESPONSE_CODE)
323 logging.debug(
'got: %s ',
str(code))
324 if code
in ( 502,503,504 ):
325 logging.debug(
'Trying again after %d seconds...', waitForRetry)
326 time.sleep( waitForRetry )
327 response = cStringIO.StringIO()
328 self.curl.setopt(pycurl.WRITEFUNCTION, response.write)
329 self.curl.setopt(pycurl.USERPWD,
'%s:%s' % (username, password) )
331 code = self.curl.getinfo(pycurl.RESPONSE_CODE)
332 resp = response.getvalue()
334 if code==500
and not resp.find(
"INVALID_CREDENTIALS")==-1:
335 logging.error(
"Invalid credentials provided.")
337 if code==403
and not resp.find(
"Unauthorized access")==-1:
338 logging.error(
"Unauthorized access. Please check the membership of group 'cms-cond-dropbox'")
342 self.
token = json.loads( resp )[
'token']
343 except Exception
as e:
344 errorMsg =
'Error while decoding returned json string' 345 logging.debug(
'http::getToken> error while decoding json: %s ',
str(resp) )
346 logging.debug(
"error getting token: %s",
str(e))
349 errorMsg =
'HTTP Error code %s ' %code
350 logging.debug(
'got: %s ',
str(code))
351 logging.debug(
'http::getToken> got error from server: %s ',
str(resp) )
356 logging.debug(
'token: %s', self.
token)
357 logging.debug(
'returning: %s', response.getvalue())
361 def query(self, url, data = None, files = None, keepCookies = True):
362 '''Queries a URL, optionally with some data (dictionary). 364 If no data is specified, a GET request will be used. 365 If some data is specified, a POST request will be used. 367 If files is specified, it must be a dictionary like data but 368 the values are filenames. 370 By default, cookies are kept in-between requests. 372 A HTTPError exception is raised if the response's HTTP code is not 200. 381 data4log = copy.copy(data)
383 if 'password' in data4log.keys():
384 data4log[
'password'] =
'*' 389 logging.debug(
'Querying %s with data %s and files %s (retries left: %s, current sleep: %s)...', url, data4log, files, len(retries), retries[0])
391 time.sleep(retries.pop(0))
394 self.curl.setopt(self.curl.URL, url)
395 self.curl.setopt(self.curl.HTTPGET, 1)
398 self.curl.setopt(pycurl.USERPWD,
'%s:""' % (
str(self.
token), ) )
399 self.curl.setopt(pycurl.HTTPHEADER, [
'Accept: application/json'])
401 if data
is not None or files
is not None:
407 finalData.update(data)
409 if files
is not None:
410 for (key, fileName)
in files.items():
411 finalData[key] = (self.curl.FORM_FILE, fileName)
412 self.curl.setopt( self.curl.HTTPPOST, finalData.items() )
414 self.curl.setopt(pycurl.VERBOSE, 0)
416 response = cStringIO.StringIO()
417 self.curl.setopt(self.curl.WRITEFUNCTION, response.write)
420 code = self.curl.getinfo(self.curl.RESPONSE_CODE)
422 if code
in self.retryCodes
and len(retries) > 0:
423 logging.debug(
'Retrying since we got the %s error code...', code)
427 raise HTTPError(code, response.getvalue())
429 return response.getvalue()
431 except pycurl.error
as e:
432 if len(retries) == 0:
434 logging.debug(
'Retrying since we got the %s pycurl exception...',
str(e))
439 tarInfo = tarFile.gettarinfo(fileobj = fileobj, arcname = arcname)
441 tarInfo.uid = tarInfo.gid = tarInfo.mtime = 0
442 tarInfo.uname = tarInfo.gname =
'root' 443 tarFile.addfile(tarInfo, fileobj)
446 '''Upload conditions to the CMS conditions uploader service. 449 def __init__(self, hostname = defaultHostname, urlTemplate = defaultUrlTemplate):
463 if self.
token is None:
464 logging.debug(
"Initializing connection with server %s",self.
hostname)
468 if socket.getfqdn().
strip().endswith(
'.cms'):
469 self.http.setProxy(
'https://cmsproxy.cms:3128/')
471 '''Signs in the server. 474 logging.info(
'%s: Signing in user %s ...', self.
hostname, username)
476 self.
token = self.http.getToken(username, password)
477 except Exception
as e:
483 logging.error(
"Caught exception when trying to connect to %s: %s" % (self.
hostname,
str(e)) )
487 logging.error(
"could not get token for user %s from %s" % (username, self.
hostname) )
490 logging.debug(
"got: '%s'",
str(self.
token) )
494 logging.debug(
"User %s has been already authenticated." %username)
498 '''Signs out the server. 501 logging.info(
'%s: Signing out...', self.
hostname)
507 '''Updates this script, if a new version is found. 510 logging.debug(
'%s: Checking if a newer version of this script is available ...', self.
hostname)
511 version =
int(self.http.query(
'getUploadScriptVersion'))
513 if version <= __version__:
514 logging.debug(
'%s: Script is up-to-date.', self.
hostname)
517 logging.info(
'%s: Updating to a newer version (%s) than the current one (%s): downloading ...', self.
hostname, version, __version__)
519 uploadScript = self.http.query(
'getUploadScript')
523 logging.info(
'%s: ... saving the new version ...', self.
hostname)
524 with open(sys.argv[0],
'wb')
as f:
525 f.write(uploadScript)
527 logging.info(
'%s: ... executing the new version...', self.
hostname)
528 os.execl(sys.executable, *([sys.executable] + sys.argv))
531 def uploadFile(self, filename, backend = defaultBackend, temporaryFile = defaultTemporaryFile):
532 '''Uploads a file to the dropBox. 534 The filename can be without extension, with .db or with .txt extension. 535 It will be stripped and then both .db and .txt files are used. 538 basepath = filename.rsplit(
'.db', 1)[0].rsplit(
'.txt', 1)[0]
539 basename = os.path.basename(basepath)
541 logging.debug(
'%s: %s: Creating tar file for upload ...', self.
hostname, basename)
544 tarFile = tarfile.open(temporaryFile,
'w:bz2')
546 with open(
'%s.db' % basepath,
'rb')
as data:
548 except Exception
as e:
549 msg =
'Error when creating tar file. \n' 550 msg +=
'Please check that you have write access to the directory you are running,\n' 551 msg +=
'and that you have enough space on this disk (df -h .)\n' 555 with tempfile.NamedTemporaryFile()
as metadata:
556 with open(
'%s.txt' % basepath,
'rb')
as originalMetadata:
557 json.dump(json.load(originalMetadata), metadata, sort_keys =
True, indent = 4)
564 logging.debug(
'%s: %s: Calculating hash...', self.
hostname, basename)
566 fileHash = hashlib.sha1()
567 with open(temporaryFile,
'rb')
as f:
569 data = f.read(4 * 1024 * 1024)
572 fileHash.update(data)
574 fileHash = fileHash.hexdigest()
575 fileInfo = os.stat(temporaryFile)
576 fileSize = fileInfo.st_size
578 logging.debug(
'%s: %s: Hash: %s', self.
hostname, basename, fileHash)
580 logging.info(
'%s: %s: Uploading file (%s, size %s) to the %s backend...', self.
hostname, basename, fileHash, fileSize, backend)
581 os.rename(temporaryFile, fileHash)
583 ret = self.http.query(
'uploadFile',
586 'fileName': basename,
590 'uploadedFile': fileHash,
593 except Exception
as e:
594 logging.error(
'Error from uploading: %s' %
str(e))
595 ret = json.dumps( {
"status": -1,
"upload" : {
'itemStatus' : { basename : {
'status':
'failed',
'info':
str(e)}}},
"error" :
str(e)} )
599 statusInfo = json.loads(ret)[
'upload']
600 logging.debug(
'upload returned: %s', statusInfo )
605 for tag, info
in statusInfo[
'itemStatus'].
items():
606 logging.debug(
'checking tag %s, info %s', tag,
str(json.dumps(info, indent=4,sort_keys=
True)) )
607 if 'ok' in info[
'status'].lower() :
609 logging.info(
'tag %s successfully uploaded', tag)
610 if 'skip' in info[
'status'].lower() :
611 skippedTags.append( tag )
612 logging.warning(
'found tag %s to be skipped. reason: \n ... \t%s ', tag, info[
'info'])
613 if 'fail' in info[
'status'].lower() :
614 failedTags.append( tag )
615 logging.error(
'found tag %s failed to upload. reason: \n ... \t%s ', tag, info[
'info'])
617 if len(okTags) > 0: logging.info (
"tags sucessfully uploaded: %s ",
str(okTags) )
618 if len(skippedTags) > 0: logging.warning(
"tags SKIPped to upload : %s ",
str(skippedTags) )
619 if len(failedTags) > 0: logging.error (
"tags FAILed to upload : %s ",
str(failedTags) )
621 fileLogURL =
'https://%s/logs/dropBox/getFileLog?fileHash=%s' 622 logging.info(
'file log at: %s', fileLogURL % (self.
hostname,fileHash))
631 if authPathEnvVar
in os.environ:
632 authPath = os.environ[authPathEnvVar]
633 netrcPath = os.path.join(authPath,
'.netrc')
634 if options.authPath
is not None:
635 netrcPath = os.path.join( options.authPath,
'.netrc' )
638 (username, account, password) = netrc.netrc( netrcPath ).authenticators(options.netrcHost)
642 'netrc entry "%s" not found: if you wish not to have to retype your password, you can add an entry in your .netrc file. However, beware of the risks of having your password stored as plaintext. Instead.',
646 defaultUsername = getpass.getuser()
647 if defaultUsername
is None:
648 defaultUsername =
'(not found)' 650 username =
getInput(defaultUsername,
'\nUsername [%s]: ' % defaultUsername)
651 password = getpass.getpass(
'Password: ')
653 return username, password
663 for filename
in arguments:
664 basepath = filename.rsplit(
'.db', 1)[0].rsplit(
'.txt', 1)[0]
665 basename = os.path.basename(basepath)
666 dataFilename =
'%s.db' % basepath
667 metadataFilename =
'%s.txt' % basepath
669 logging.info(
'Checking %s...', basename)
673 with open(dataFilename,
'rb')
as dataFile:
676 errMsg =
'Impossible to open SQLite data file %s' %dataFilename
677 logging.error( errMsg )
679 ret[
'error'] = errMsg
685 dbcon = sqlite3.connect( dataFilename )
686 dbcur = dbcon.cursor()
687 dbcur.execute(
'SELECT * FROM IOV')
688 rows = dbcur.fetchall()
693 errMsg =
'The input SQLite data file %s contains no data.' %dataFilename
694 logging.error( errMsg )
696 ret[
'error'] = errMsg
698 except Exception
as e:
699 errMsg =
'Check on input SQLite data file %s failed: %s' %(dataFilename,
str(e))
700 logging.error( errMsg )
702 ret[
'error'] = errMsg
707 with open(metadataFilename,
'rb')
as metadataFile:
710 if e.errno != errno.ENOENT:
711 errMsg =
'Impossible to open file %s (for other reason than not existing)' %metadataFilename
712 logging.error( errMsg )
714 ret[
'error'] = errMsg
717 if getInput(
'y',
'\nIt looks like the metadata file %s does not exist. Do you want me to create it and help you fill it?\nAnswer [y]: ' % metadataFilename).lower() !=
'y':
718 errMsg =
'Metadata file %s does not exist' %metadataFilename
719 logging.error( errMsg )
721 ret[
'error'] = errMsg
724 runWizard(basename, dataFilename, metadataFilename)
734 for filename
in arguments:
735 backend = options.backend
736 basepath = filename.rsplit(
'.db', 1)[0].rsplit(
'.txt', 1)[0]
737 metadataFilename =
'%s.txt' % basepath
738 with open(metadataFilename,
'rb')
as metadataFile:
739 metadata = json.load( metadataFile )
742 destDb = metadata[
'destinationDatabase']
743 if destDb.startswith(
'oracle://cms_orcon_prod')
or destDb.startswith(
'oracle://cms_orcoff_prep'):
744 hostName = defaultHostname
745 if destDb.startswith(
'oracle://cms_orcoff_prep'):
746 hostName = defaultDevHostname
747 dropBox.setHost( hostName )
748 authRet = dropBox.signIn( username, password )
750 msg =
"Error trying to connect to the server. Aborting." 752 msg =
"Error while signin in. Aborting." 754 return {
'status' : authRet,
'error' : msg }
755 results[filename] = dropBox.uploadFile(filename, options.backend, options.temporaryFile)
757 results[filename] =
False 758 logging.error(
"DestinationDatabase %s is not valid. Skipping the upload." %destDb)
759 if not results[filename]:
763 ret[
'files'] = results
764 logging.debug(
"all files processed, logging out now.")
768 except HTTPError
as e:
769 logging.error(
'got HTTP error: %s',
str(e))
770 return {
'status' : -1,
'error' :
str(e) }
775 '''Uploads a bunch of files coming from Tier0. 776 This has the following requirements: 777 * Username/Password based authentication. 778 * Uses the online backend. 779 * Ignores errors related to the upload/content (e.g. duplicated file). 784 dropBox.signIn(username, password)
786 for filename
in filenames:
788 result = dropBox.uploadFile(filename, backend =
'test')
789 except HTTPError
as e:
794 logging.error(
'HTTP Exception 400 Bad Request: Upload-related, skipping. Message: %s', e)
806 logging.error(
'Error from dropbox, upload-related, skipping.')
813 logDbSrv = prodLogDbSrv
814 if options.hostname == defaultDevHostname:
815 logDbSrv = devLogDbSrv
816 if options.authPath
is not None:
817 netrcPath = os.path.join( options.authPath,
'.netrc' )
819 netrcKey =
'%s/%s' %(logDbSrv,logDbSchema)
820 print '#netrc key=%s' %netrcKey
822 (username, account, password) = netrc.netrc( netrcPath ).authenticators( netrcKey )
824 logging.error(
'Cannot access netrc file.')
826 except Exception
as e:
827 logging.error(
'Netrc file is invalid: %s' %
str(e))
829 conStr =
'%s/%s@%s' %(username,password,logDbSrv)
830 con = cx_Oracle.connect( conStr )
832 fh = options.reUpload
833 cur.execute(
'SELECT FILECONTENT, STATE FROM FILES WHERE FILEHASH = :HASH',{
'HASH':fh})
839 logging.info(
"Found file %s in state '%s;" %(fh,r[1]))
840 fdata = r[0].read().
decode(
'bz2')
843 logging.error(
"No file uploaded found with hash %s" %fh)
847 with open(fname,
"wb" )
as f:
849 rname =
'reupload_%s' %fh
850 with tarfile.open(fname)
as tar:
854 mdfile =
'metadata.txt' 855 if os.path.exists(dfile):
857 os.chmod(dfile,0o755)
858 os.rename(dfile,
'%s.db' %rname)
860 logging.error(
'Tar file does not contain the data file')
862 if os.path.exists(mdfile):
863 os.utime(mdfile,
None)
864 os.chmod(mdfile,0o755)
866 with open(mdfile)
as md:
867 mdata = json.load(md)
868 datelabel = datetime.now().strftime(
"%y-%m-%d %H:%M:%S")
870 logging.error(
'Metadata file is empty.')
872 logging.debug(
'Preparing new metadata file...')
873 mdata[
'userText'] =
'reupload %s : %s' %(datelabel,mdata[
'userText'])
874 with open(
'%s.txt' %rname,
'wb')
as jf:
875 jf.write( json.dumps( mdata, sort_keys=
True, indent = 2 ) )
879 logging.error(
'Tar file does not contain the metadata file')
881 logging.info(
'Files %s prepared for the upload.' %rname)
883 return upload(options, arguments)
888 if 'status' not in results:
889 print 'Unexpected error.' 891 ret = results[
'status']
893 print "upload ended with code: %s" %ret
900 parser = optparse.OptionParser(usage =
901 'Usage: %prog [options] <file> [<file> ...]\n' 904 parser.add_option(
'-d',
'--debug',
908 help =
'Switch on printing debug information. Default: %default',
911 parser.add_option(
'-b',
'--backend',
913 default = defaultBackend,
914 help =
'dropBox\'s backend to upload to. Default: %default',
917 parser.add_option(
'-H',
'--hostname',
919 default = defaultHostname,
920 help =
'dropBox\'s hostname. Default: %default',
923 parser.add_option(
'-u',
'--urlTemplate',
924 dest =
'urlTemplate',
925 default = defaultUrlTemplate,
926 help =
'dropBox\'s URL template. Default: %default',
929 parser.add_option(
'-f',
'--temporaryFile',
930 dest =
'temporaryFile',
931 default = defaultTemporaryFile,
932 help =
'Temporary file that will be used to store the first tar file. Note that it then will be moved to a file with the hash of the file as its name, so there will be two temporary files created in fact. Default: %default',
935 parser.add_option(
'-n',
'--netrcHost',
937 default = defaultNetrcHost,
938 help =
'The netrc host (machine) from where the username and password will be read. Default: %default',
941 parser.add_option(
'-a',
'--authPath',
944 help =
'The path of the .netrc file for the authentication. Default: $HOME',
947 parser.add_option(
'-r',
'--reUpload',
950 help =
'The hash of the file to upload again.',
953 (options, arguments) = parser.parse_args()
955 logLevel = logging.INFO
957 logLevel = logging.DEBUG
959 format =
'[%(asctime)s] %(levelname)s: %(message)s',
963 if len(arguments) < 1:
964 if options.reUpload
is None:
969 if options.reUpload
is not None:
970 print "ERROR: options -r can't be specified on a new file upload." 973 return upload(options, arguments)
977 global defaultNetrcHost
979 (username, account, password) = netrc.netrc().authenticators(defaultNetrcHost)
981 filenames = [
'testFiles/localSqlite-top2']
986 if __name__ ==
'__main__':
def setRetries(self, retries=())
def _checkForUpdates(self)
def __init__(self, hostname=defaultHostname, urlTemplate=defaultUrlTemplate)
def uploadFile(self, filename, backend=defaultBackend, temporaryFile=defaultTemporaryFile)
def setBaseUrl(self, baseUrl='')
def getToken(self, username, password)
def addToTarFile(tarFile, fileobj, arcname)
def runWizard(basename, dataFilename, metadataFilename)
def query(self, url, data=None, files=None, keepCookies=True)
def setProxy(self, proxy='')
def getCredentials(options)
def upload(options, arguments)
def setTimeout(self, timeout=0)
def uploadTier0Files(filenames, username, password, cookieFileName=None)
def __init__(self, code, response)
OutputIterator zip(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp)
bool decode(bool &, std::string const &)
def signIn(self, username, password)
def uploadAllFiles(options, arguments)
def getInputRepeat(prompt='')
def getInputChoose(optionsList, default, prompt='')
def getInput(default, prompt='')
def getInputWorkflow(prompt='')
def setHost(self, hostname)
How EventSelector::AcceptEvent() decides whether to accept an event for output otherwise it is excluding the probing of A single or multiple positive and the trigger will pass if any such matching triggers are PASS or EXCEPTION[A criterion thatmatches no triggers at all is detected and causes a throw.] A single negative with an expectation of appropriate bit checking in the decision and the trigger will pass if any such matching triggers are FAIL or EXCEPTION A wildcarded negative criterion that matches more than one trigger in the trigger list("!*","!HLTx*"if it matches 2 triggers or more) will accept the event if all the matching triggers are FAIL.It will reject the event if any of the triggers are PASS or EXCEPTION(this matches the behavior of"!*"before the partial wildcard feature was incorporated).Triggers which are in the READY state are completely ignored.(READY should never be returned since the trigger paths have been run