1*4882a593Smuzhiyun#!/usr/bin/python3 2*4882a593Smuzhiyun# 3*4882a593Smuzhiyun# Send build performance test report emails 4*4882a593Smuzhiyun# 5*4882a593Smuzhiyun# Copyright (c) 2017, Intel Corporation. 6*4882a593Smuzhiyun# 7*4882a593Smuzhiyun# SPDX-License-Identifier: GPL-2.0-only 8*4882a593Smuzhiyun# 9*4882a593Smuzhiyun 10*4882a593Smuzhiyunimport argparse 11*4882a593Smuzhiyunimport base64 12*4882a593Smuzhiyunimport logging 13*4882a593Smuzhiyunimport os 14*4882a593Smuzhiyunimport pwd 15*4882a593Smuzhiyunimport re 16*4882a593Smuzhiyunimport shutil 17*4882a593Smuzhiyunimport smtplib 18*4882a593Smuzhiyunimport socket 19*4882a593Smuzhiyunimport subprocess 20*4882a593Smuzhiyunimport sys 21*4882a593Smuzhiyunimport tempfile 22*4882a593Smuzhiyunfrom email.mime.text import MIMEText 23*4882a593Smuzhiyun 24*4882a593Smuzhiyun 25*4882a593Smuzhiyun# Setup logging 26*4882a593Smuzhiyunlogging.basicConfig(level=logging.INFO, format="%(levelname)s: %(message)s") 27*4882a593Smuzhiyunlog = logging.getLogger('oe-build-perf-report') 28*4882a593Smuzhiyun 29*4882a593Smuzhiyun 30*4882a593Smuzhiyundef parse_args(argv): 31*4882a593Smuzhiyun """Parse command line arguments""" 32*4882a593Smuzhiyun description = """Email build perf test report""" 33*4882a593Smuzhiyun parser = argparse.ArgumentParser( 34*4882a593Smuzhiyun formatter_class=argparse.ArgumentDefaultsHelpFormatter, 35*4882a593Smuzhiyun description=description) 36*4882a593Smuzhiyun 37*4882a593Smuzhiyun parser.add_argument('--debug', '-d', action='store_true', 38*4882a593Smuzhiyun help="Verbose logging") 39*4882a593Smuzhiyun parser.add_argument('--quiet', '-q', action='store_true', 40*4882a593Smuzhiyun help="Only print errors") 41*4882a593Smuzhiyun parser.add_argument('--to', action='append', 42*4882a593Smuzhiyun help="Recipients of the email") 43*4882a593Smuzhiyun parser.add_argument('--cc', action='append', 44*4882a593Smuzhiyun help="Carbon copy recipients of the email") 45*4882a593Smuzhiyun parser.add_argument('--bcc', action='append', 46*4882a593Smuzhiyun help="Blind carbon copy recipients of the email") 47*4882a593Smuzhiyun parser.add_argument('--subject', default="Yocto build perf test report", 48*4882a593Smuzhiyun help="Email subject") 49*4882a593Smuzhiyun parser.add_argument('--outdir', '-o', 50*4882a593Smuzhiyun help="Store files in OUTDIR. Can be used to preserve " 51*4882a593Smuzhiyun "the email parts") 52*4882a593Smuzhiyun parser.add_argument('--text', 53*4882a593Smuzhiyun help="Plain text message") 54*4882a593Smuzhiyun 55*4882a593Smuzhiyun args = parser.parse_args(argv) 56*4882a593Smuzhiyun 57*4882a593Smuzhiyun if not args.text: 58*4882a593Smuzhiyun parser.error("Please specify --text") 59*4882a593Smuzhiyun 60*4882a593Smuzhiyun return args 61*4882a593Smuzhiyun 62*4882a593Smuzhiyun 63*4882a593Smuzhiyundef send_email(text_fn, subject, recipients, copy=[], blind_copy=[]): 64*4882a593Smuzhiyun # Generate email message 65*4882a593Smuzhiyun with open(text_fn) as f: 66*4882a593Smuzhiyun msg = MIMEText("Yocto build performance test report.\n" + f.read(), 'plain') 67*4882a593Smuzhiyun 68*4882a593Smuzhiyun pw_data = pwd.getpwuid(os.getuid()) 69*4882a593Smuzhiyun full_name = pw_data.pw_gecos.split(',')[0] 70*4882a593Smuzhiyun email = os.environ.get('EMAIL', 71*4882a593Smuzhiyun '{}@{}'.format(pw_data.pw_name, socket.getfqdn())) 72*4882a593Smuzhiyun msg['From'] = "{} <{}>".format(full_name, email) 73*4882a593Smuzhiyun msg['To'] = ', '.join(recipients) 74*4882a593Smuzhiyun if copy: 75*4882a593Smuzhiyun msg['Cc'] = ', '.join(copy) 76*4882a593Smuzhiyun if blind_copy: 77*4882a593Smuzhiyun msg['Bcc'] = ', '.join(blind_copy) 78*4882a593Smuzhiyun msg['Subject'] = subject 79*4882a593Smuzhiyun 80*4882a593Smuzhiyun # Send email 81*4882a593Smuzhiyun with smtplib.SMTP('localhost') as smtp: 82*4882a593Smuzhiyun smtp.send_message(msg) 83*4882a593Smuzhiyun 84*4882a593Smuzhiyun 85*4882a593Smuzhiyundef main(argv=None): 86*4882a593Smuzhiyun """Script entry point""" 87*4882a593Smuzhiyun args = parse_args(argv) 88*4882a593Smuzhiyun if args.quiet: 89*4882a593Smuzhiyun log.setLevel(logging.ERROR) 90*4882a593Smuzhiyun if args.debug: 91*4882a593Smuzhiyun log.setLevel(logging.DEBUG) 92*4882a593Smuzhiyun 93*4882a593Smuzhiyun if args.outdir: 94*4882a593Smuzhiyun outdir = args.outdir 95*4882a593Smuzhiyun if not os.path.exists(outdir): 96*4882a593Smuzhiyun os.mkdir(outdir) 97*4882a593Smuzhiyun else: 98*4882a593Smuzhiyun outdir = tempfile.mkdtemp(dir='.') 99*4882a593Smuzhiyun 100*4882a593Smuzhiyun try: 101*4882a593Smuzhiyun log.debug("Storing email parts in %s", outdir) 102*4882a593Smuzhiyun if args.to: 103*4882a593Smuzhiyun log.info("Sending email to %s", ', '.join(args.to)) 104*4882a593Smuzhiyun if args.cc: 105*4882a593Smuzhiyun log.info("Copying to %s", ', '.join(args.cc)) 106*4882a593Smuzhiyun if args.bcc: 107*4882a593Smuzhiyun log.info("Blind copying to %s", ', '.join(args.bcc)) 108*4882a593Smuzhiyun send_email(args.text, args.subject, args.to, args.cc, args.bcc) 109*4882a593Smuzhiyun except subprocess.CalledProcessError as err: 110*4882a593Smuzhiyun log.error("%s, with output:\n%s", str(err), err.output.decode()) 111*4882a593Smuzhiyun return 1 112*4882a593Smuzhiyun finally: 113*4882a593Smuzhiyun if not args.outdir: 114*4882a593Smuzhiyun log.debug("Wiping %s", outdir) 115*4882a593Smuzhiyun shutil.rmtree(outdir) 116*4882a593Smuzhiyun 117*4882a593Smuzhiyun return 0 118*4882a593Smuzhiyun 119*4882a593Smuzhiyun 120*4882a593Smuzhiyunif __name__ == "__main__": 121*4882a593Smuzhiyun sys.exit(main()) 122