1 # Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
5 """Chromite email utility functions."""
7 from __future__ import print_function
10 from email.mime.application import MIMEApplication
11 from email.mime.multipart import MIMEMultipart
12 from email.mime.text import MIMEText
19 # Note: When importing this module from cbuildbot code that will run on
20 # a builder in the golo, set this to constants.GOLO_SMTP_SERVER
21 DEFAULT_SMTP_SERVER = 'localhost'
24 def _SendEmailHelper(smtp_server, sender, email_recipients, msg):
28 smtp_server: The server with which to send the message.
29 sender: The from address of the sender of the email.
30 email_recipients: The recipients of the message.
31 msg: A MIMEMultipart() object containing the body of the message.
33 smtp_client = smtplib.SMTP(smtp_server)
34 smtp_client.sendmail(sender, email_recipients, msg.as_string())
38 def SendEmail(subject, recipients, smtp_server=None, message='',
39 attachment=None, extra_fields=None):
40 """Send an e-mail job notification with the given message in the body.
43 subject: E-mail subject.
44 recipients: list of e-mail recipients.
45 smtp_server: (optional) Hostname[:port] of smtp server to use to send
46 email. Defaults to DEFAULT_SMTP_SERVER.
47 message: (optional) Message to put in the e-mail body.
48 attachment: (optional) text to attach.
49 extra_fields: (optional) A dictionary of additional message header fields
50 to be added to the message. Custom fields names should begin
53 # Ignore if the list of recipients is empty.
57 extra_fields = extra_fields or {}
60 smtp_server = DEFAULT_SMTP_SERVER
62 sender = socket.getfqdn()
63 email_recipients = recipients
65 for key, val in extra_fields.iteritems():
68 msg['Subject'] = subject
69 msg['To'] = ', '.join(recipients)
71 msg.attach(MIMEText(message))
73 s = cStringIO.StringIO()
74 with gzip.GzipFile(fileobj=s, mode='w') as f:
76 part = MIMEApplication(s.getvalue(), _subtype='x-gzip')
78 part.add_header('Content-Disposition', 'attachment', filename='logs.txt.gz')
81 _SendEmailHelper(smtp_server, sender, email_recipients, msg)
84 def SendEmailLog(subject, recipients, smtp_server=None, message='',
85 inc_trace=True, log=None, extra_fields=None):
86 """Send an e-mail with a stack trace and log snippets.
89 subject: E-mail subject.
90 recipients: list of e-mail recipients.
91 smtp_server: (optional) Hostname(:port) of smtp server to use to send
92 email. Defaults to DEFAULT_SMTP_SERVER.
93 message: Message to put at the top of the e-mail body.
94 inc_trace: Append a backtrace of the current stack.
95 log: List of lines (log data) to include in the notice.
96 extra_fields: (optional) A dictionary of additional message header fields
97 to be added to the message. Custom fields names should begin
105 if sys.exc_info() != (None, None, None):
106 trace = traceback.format_exc()
107 message += '\n\n' + trace
112 '***************************\n' +
113 'Last log messages:\n' +
114 '***************************\n' +
116 attachment = ''.join(log)
118 SendEmail(subject, recipients, smtp_server, message=message,
119 attachment=attachment, extra_fields=extra_fields)