blob: c900720f6e1af7dee2ecbe57e497f6867e64d097 [file] [log] [blame]
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001#!/usr/bin/python3
2#
3# Send build performance test report emails
4#
5# Copyright (c) 2017, Intel Corporation.
6#
Brad Bishopc342db32019-05-15 21:57:59 -04007# SPDX-License-Identifier: GPL-2.0-only
Brad Bishop6e60e8b2018-02-01 10:27:11 -05008#
Brad Bishopc342db32019-05-15 21:57:59 -04009
Brad Bishop6e60e8b2018-02-01 10:27:11 -050010import argparse
11import base64
12import logging
13import os
14import pwd
15import re
16import shutil
17import smtplib
18import socket
19import subprocess
20import sys
21import tempfile
Brad Bishop6e60e8b2018-02-01 10:27:11 -050022from email.mime.text import MIMEText
23
24
25# Setup logging
26logging.basicConfig(level=logging.INFO, format="%(levelname)s: %(message)s")
27log = logging.getLogger('oe-build-perf-report')
28
29
Brad Bishop6e60e8b2018-02-01 10:27:11 -050030def check_utils():
31 """Check that all needed utils are installed in the system"""
32 missing = []
33 for cmd in ('phantomjs', 'optipng'):
34 if not shutil.which(cmd):
35 missing.append(cmd)
36 if missing:
37 log.error("The following tools are missing: %s", ' '.join(missing))
38 sys.exit(1)
39
40
41def parse_args(argv):
42 """Parse command line arguments"""
43 description = """Email build perf test report"""
44 parser = argparse.ArgumentParser(
45 formatter_class=argparse.ArgumentDefaultsHelpFormatter,
46 description=description)
47
48 parser.add_argument('--debug', '-d', action='store_true',
49 help="Verbose logging")
50 parser.add_argument('--quiet', '-q', action='store_true',
51 help="Only print errors")
52 parser.add_argument('--to', action='append',
53 help="Recipients of the email")
Brad Bishopd7bf8c12018-02-25 22:55:05 -050054 parser.add_argument('--cc', action='append',
55 help="Carbon copy recipients of the email")
56 parser.add_argument('--bcc', action='append',
57 help="Blind carbon copy recipients of the email")
Brad Bishop6e60e8b2018-02-01 10:27:11 -050058 parser.add_argument('--subject', default="Yocto build perf test report",
59 help="Email subject")
60 parser.add_argument('--outdir', '-o',
61 help="Store files in OUTDIR. Can be used to preserve "
62 "the email parts")
63 parser.add_argument('--text',
64 help="Plain text message")
Brad Bishop6e60e8b2018-02-01 10:27:11 -050065
66 args = parser.parse_args(argv)
67
Andrew Geissler9aee5002022-03-30 16:27:02 +000068 if not args.text:
69 parser.error("Please specify --text")
Brad Bishop6e60e8b2018-02-01 10:27:11 -050070
71 return args
72
73
Andrew Geissler9aee5002022-03-30 16:27:02 +000074def send_email(text_fn, subject, recipients, copy=[], blind_copy=[]):
Brad Bishop6e60e8b2018-02-01 10:27:11 -050075 # Generate email message
Andrew Geissler9aee5002022-03-30 16:27:02 +000076 with open(text_fn) as f:
77 msg = MIMEText("Yocto build performance test report.\n" + f.read(), 'plain')
Brad Bishop6e60e8b2018-02-01 10:27:11 -050078
79 pw_data = pwd.getpwuid(os.getuid())
80 full_name = pw_data.pw_gecos.split(',')[0]
81 email = os.environ.get('EMAIL',
82 '{}@{}'.format(pw_data.pw_name, socket.getfqdn()))
83 msg['From'] = "{} <{}>".format(full_name, email)
84 msg['To'] = ', '.join(recipients)
Brad Bishopd7bf8c12018-02-25 22:55:05 -050085 if copy:
86 msg['Cc'] = ', '.join(copy)
87 if blind_copy:
88 msg['Bcc'] = ', '.join(blind_copy)
Brad Bishop6e60e8b2018-02-01 10:27:11 -050089 msg['Subject'] = subject
90
91 # Send email
92 with smtplib.SMTP('localhost') as smtp:
93 smtp.send_message(msg)
94
95
96def main(argv=None):
97 """Script entry point"""
98 args = parse_args(argv)
99 if args.quiet:
100 log.setLevel(logging.ERROR)
101 if args.debug:
102 log.setLevel(logging.DEBUG)
103
104 check_utils()
105
106 if args.outdir:
107 outdir = args.outdir
108 if not os.path.exists(outdir):
109 os.mkdir(outdir)
110 else:
111 outdir = tempfile.mkdtemp(dir='.')
112
113 try:
114 log.debug("Storing email parts in %s", outdir)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500115 if args.to:
116 log.info("Sending email to %s", ', '.join(args.to))
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500117 if args.cc:
118 log.info("Copying to %s", ', '.join(args.cc))
119 if args.bcc:
120 log.info("Blind copying to %s", ', '.join(args.bcc))
Andrew Geissler9aee5002022-03-30 16:27:02 +0000121 send_email(args.text, args.subject, args.to, args.cc, args.bcc)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500122 except subprocess.CalledProcessError as err:
123 log.error("%s, with output:\n%s", str(err), err.output.decode())
124 return 1
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500125 finally:
126 if not args.outdir:
127 log.debug("Wiping %s", outdir)
128 shutil.rmtree(outdir)
129
130 return 0
131
132
133if __name__ == "__main__":
134 sys.exit(main())