releases/openstack_releases/cmds/mail.py
Sean McGinnis c5545ee077
Add retries to sending emails
We have occasional release announcement job failures due to network
issues or other SMTP errors sending the announcement. Most of these
appear to be temporary failures that would be resolved with another
attempt.

This patch adds exponential backoff retries to the sending process to
try to get around these failures.

Change-Id: I70bb470639385caecee7ccfc0e449449bfc9b871
Signed-off-by: Sean McGinnis <sean.mcginnis@gmail.com>
2020-04-27 11:23:28 -05:00

68 lines
2.3 KiB
Python

#!/usr/bin/python3
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
"""Read an email message and send it through localhost.
This is a separate script from the release notes email generator
because it might be used for other things and it might not be used
when notes are being send from a developer's system.
"""
import argparse
import email
import smtplib
import tenacity
def main():
parser = argparse.ArgumentParser()
parser.add_argument('--server', default='lists.openstack.org',
help=('the SMTP server Valid forms are: server, '
'server:port, user:pw@server or '
'user:pw@server:port. Default: %(default)s'))
parser.add_argument('-v', dest='verbose',
action='store_true', default=False,
help='turn on extra debugging output')
parser.add_argument('infile', help='the file containing the email')
args = parser.parse_args()
user = None
pw = None
server = args.server
if '@' in server:
creds, _, server = args.server.partition('@')
user, _, pw = creds.partition(':')
with open(args.infile, 'r') as f:
msg = email.message_from_file(f)
tolist = [address.strip() for address in msg['to'].split(",")]
send_email(server, msg, tolist, user=user, pw=pw, debug=args.verbose)
@tenacity.retry(wait=tenacity.wait_exponential,
stop=tenacity.stop_after_attempt(4))
def send_email(smtp_server, msg, tolist, user=None, pw=None, debug=False):
server = smtplib.SMTP(smtp_server)
if debug:
server.set_debuglevel(True)
try:
if pw:
server.starttls()
server.login(user, pw)
server.sendmail(msg['from'], tolist, msg.as_string().encode('utf-8'))
finally:
server.quit()