CMS 3D CMS Logo

o2o_helper.py
Go to the documentation of this file.
1 '''
2 Helper Script for StripO2O
3 @author: Huilin Qu
4 '''
5 
6 import os
7 import subprocess
8 import logging
9 import json
10 import smtplib
11 from email.mime.multipart import MIMEMultipart
12 from email.mime.text import MIMEText
13 import sqlite3
14 import six
15 
17  '''Kill a subprocess without throwing OSError.
18  Used for cleaning up subprocesses when the main script crashes.'''
19  try:
20  p.terminate()
21  except OSError:
22  pass
23 
24 
25 def configLogger(logfile,loglevel=logging.INFO):
26  '''Setting up logging to both file and console.
27  @see: https://docs.python.org/2/howto/logging-cookbook.html
28  '''
29  # set up logging to file
30  logging.basicConfig(level=loglevel,
31  format='[%(asctime)s] %(levelname)s: %(message)s',
32  filename=logfile,
33  filemode='w')
34  # define a Handler which writes INFO messages or higher to the sys.stderr
35  console = logging.StreamHandler()
36  console.setLevel(loglevel)
37  # set a format which is simpler for console use
38  formatter = logging.Formatter('[%(levelname)s] %(message)s')
39  # tell the handler to use this format
40  console.setFormatter(formatter)
41  # add the handler to the root logger
42  logging.getLogger('').addHandler(console)
43 
44 def insert_to_file(template, target, replace_dict):
45  '''Update the template file based on the replace_dict, and write to the target.'''
46  logging.debug('Creating "%s" from template "%s" using dictionary:'%(target, template))
47  logging.debug(replace_dict)
48  with open(template, 'r') as input_file:
49  config=input_file.read()
50  with open(target, 'w') as output_file:
51  for key, value in six.iteritems(replace_dict):
52  config = config.replace(key, value)
53  output_file.write(config)
54  return config
55 
56 def create_metadata(metadataFilename, inputTag, destTags, destDb, since, userText):
57  '''Create metadata file for the conditionsUpload service.
58  @see: uploadConditions.runWizard()
59  @see: https://twiki.cern.ch/twiki/bin/view/CMS/DropBox
60 
61  Keyword arguments:
62  metadataFilename -- output metadata filename
63  inputTag -- input tag name
64  destTags -- a list of destination tags
65  destDb -- [destinationDatabase] in metadata
66  since -- [since] in metadata
67  userText -- [userText] in metadata
68  '''
69  if isinstance(destTags, str):
70  destTags = [destTags]
71  if since:
72  since = int(since) # convert to int if since is not None (input since can be a str)
73  destinationTags = {}
74  for destinationTag in destTags:
75  destinationTags[destinationTag] = {}
76  metadata = {
77  'destinationDatabase': destDb,
78  'destinationTags': destinationTags,
79  'inputTag': inputTag,
80  'since': since,
81  'userText': userText,
82  }
83  logging.info('Writing metadata in %s', metadataFilename)
84  logging.debug(metadata)
85  with open(metadataFilename, 'wb') as metadataFile:
86  metadataFile.write(json.dumps(metadata, sort_keys=True, indent=4))
87 
88 def upload_payload(dbFile, inputTag, destTags, destDb, since, userText):
89  '''Upload payload using conditionUploader. '''
90  if isinstance(destTags, str):
91  destTags = [destTags]
92  metadataFilename = dbFile.replace('.db', '.txt')
93  create_metadata(metadataFilename, inputTag, destTags, destDb, since, userText)
94  logging.info('Uploading tag [%s] from %s to [%s] in %s:' % (inputTag, dbFile, ','.join(destTags), destDb))
95  command = "uploadConditions.py %s" % dbFile
96  pipe = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
97  out = pipe.communicate()[0]
98  logging.info(out)
99  logging.info('@@@Upload return code = %d@@@' % pipe.returncode)
100  if pipe.returncode != 0:
101  raise RuntimeError('Upload FAILED!')
102 
103 
104 def copy_payload(dbFile, inputTag, destTags, destDb, since, userText):
105  '''Upload payload using conddb copy.'''
106  if isinstance(destTags, str):
107  destTags = [destTags]
108  if destDb.lower() == 'oracle://cms_orcon_prod/cms_conditions':
109  copyDestDb = 'onlineorapro'
110  elif destDb.lower() == 'oracle://cms_orcoff_prep/cms_conditions':
111  copyDestDb = 'oradev'
112  else:
113  copyDestDb = destDb
114  success = 0
115  def copy(dest):
116  command = 'conddb --force --yes --db {db} copy {inputTag} {destTag} --destdb {destDb} --synchronize --note "{note}"'.format(
117  db=dbFile, inputTag=inputTag, destTag=dest, destDb=copyDestDb, note=userText)
118  logging.info('Copy tag [%s] from %s to [%s] in %s:' % (inputTag, dbFile, dest, destDb))
119  logging.debug(command)
120  pipe = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
121  out = pipe.communicate()[0]
122  logging.info(out)
123  return pipe.returncode
124  for dest in destTags:
125  returncode = copy(dest)
126  if returncode == 0: success += 1
127  logging.info('@@@Upload return code = %d@@@' % (success - len(destTags)))
128  if success != len(destTags):
129  raise RuntimeError('Upload FAILED!')
130 
131 
132 def send_mail(subject, message, send_to, send_from, text_attachments=[]):
133  '''Send an email. [send_to] needs to be a list.'''
134  msg = MIMEMultipart()
135  msg['Subject'] = subject
136  msg['From'] = send_from
137  msg['To'] = ','.join(send_to)
138  msg.attach(MIMEText(message))
139 
140  for fn in text_attachments:
141  with open(fn, 'rb') as txtfile:
142  attachment = MIMEText(txtfile.read())
143  attachment.add_header('Content-Disposition', 'attachment', filename=os.path.basename(fn))
144  msg.attach(attachment)
145 
146  s = smtplib.SMTP('localhost')
147  s.sendmail(send_from, send_to, msg.as_string())
148  s.quit()
149 
150 def exists_iov(dbFile, tag):
151  '''Check if there exists any IOV for a specific tag in the given sqlite file.'''
152  dataConnection = sqlite3.connect(dbFile)
153  dataCursor = dataConnection.cursor()
154  dataCursor.execute('select SINCE from IOV where TAG_NAME=:tag_name', {'tag_name' : tag})
155  return len(dataCursor.fetchall()) > 0
def create_metadata(metadataFilename, inputTag, destTags, destDb, since, userText)
Definition: o2o_helper.py:56
def exists_iov(dbFile, tag)
Definition: o2o_helper.py:150
def configLogger(logfile, loglevel=logging.INFO)
Definition: o2o_helper.py:25
def send_mail(subject, message, send_to, send_from, text_attachments=[])
Definition: o2o_helper.py:132
static std::string join(char **cmd)
Definition: RemoteFile.cc:17
def insert_to_file(template, target, replace_dict)
Definition: o2o_helper.py:44
def upload_payload(dbFile, inputTag, destTags, destDb, since, userText)
Definition: o2o_helper.py:88
def copy_payload(dbFile, inputTag, destTags, destDb, since, userText)
Definition: o2o_helper.py:104
def kill_subproc_noexcept(p)
Definition: o2o_helper.py:16