DPDK patches and discussions
 help / color / mirror / Atom feed
From: Ray Kinsella <mdr@ashroe.eu>
To: dev@dpdk.org
Cc: bruce.richardson@intel.com, stephen@networkplumber.org,
	ferruh.yigit@intel.com, thomas@monjalon.net, ktraynor@redhat.com,
	mdr@ashroe.eu
Subject: [dpdk-dev] [PATCH v8 2/2] devtools: script to send notifications of expired symbols
Date: Fri,  6 Aug 2021 18:54:12 +0100	[thread overview]
Message-ID: <20210806175412.872237-3-mdr@ashroe.eu> (raw)
In-Reply-To: <20210806175412.872237-1-mdr@ashroe.eu>

Use this script with the output of the DPDK symbol tool, to notify
maintainers of expired symbols by email. You need to define the environment
variable DPDK_GETMAINTAINER_PATH, for this tool to work.

Use terminal output to review the emails before sending.
e.g.
$ devtools/symbol-tool.py list-expired --format-output csv \
| DPDK_GETMAINTAINER_PATH=<somewhere>/get_maintainer.pl \
devtools/notify_expired_symbols.py --format-output terminal

Then use email output to send the emails to the maintainers.
e.g.
$ devtools/symbol-tool.py list-expired --format-output csv \
| DPDK_GETMAINTAINER_PATH=<somewhere>/get_maintainer.pl \
--smtp-server <server> --sender <someone@somewhere.com> \
--password <password>

Signed-off-by: Ray Kinsella <mdr@ashroe.eu>
---
 devtools/notify-symbol-maintainers.py | 224 ++++++++++++++++++++++++++
 1 file changed, 224 insertions(+)
 create mode 100755 devtools/notify-symbol-maintainers.py

diff --git a/devtools/notify-symbol-maintainers.py b/devtools/notify-symbol-maintainers.py
new file mode 100755
index 0000000000..447f88bb03
--- /dev/null
+++ b/devtools/notify-symbol-maintainers.py
@@ -0,0 +1,224 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2021 Intel Corporation
+'''Tool to notify maintainers of expired symbols'''
+import smtplib
+import ssl
+import sys
+import subprocess
+import argparse
+from argparse import RawTextHelpFormatter
+import time
+from email.message import EmailMessage
+
+DESCRIPTION = '''
+Use this script with the output of the DPDK symbol tool, to notify maintainers
+of expired symbols by email. You need to define the environment variable
+DPDK_GETMAINTAINER_PATH, for this tool to work.
+
+Use terminal output to review the emails before sending.
+e.g.
+$ devtools/symbol-tool.py list-expired --format-output csv \\
+| DPDK_GETMAINTAINER_PATH=<somewhere>/get_maintainer.pl \\
+devtools/notify_expired_symbols.py --format-output terminal
+
+Then use email output to send the emails to the maintainers.
+e.g.
+$ devtools/symbol-tool.py list-expired --format-output csv \\
+| DPDK_GETMAINTAINER_PATH=<somewhere>/get_maintainer.pl \\
+--smtp-server <server> --sender <someone@somewhere.com> --password <password>
+'''
+
+EMAIL_TEMPLATE = '''Hi there,
+
+Please note the symbols listed below have expired. In line with the DPDK ABI
+policy, they should be scheduled for removal, in the next DPDK release.
+
+For more information, please see the DPDK ABI Policy, section 3.5.3.
+https://doc.dpdk.org/guides/contributing/abi_policy.html
+
+Thanks,
+
+The DPDK Symbol Bot
+
+'''
+
+default_maintainers = ['Ray Kinsella <mdr@ashroe.eu>', \
+                       'Thomas Monjalon <thomas@monjalon.net>']
+get_maintainer = ['devtools/get-maintainer.sh', \
+                  '--email', '-f']
+
+def get_maintainers(libpath):
+    '''Get the maintainers for given library'''
+    try:
+        cmd = get_maintainer + [libpath]
+        result = subprocess.run(cmd, \
+                                stdout=subprocess.PIPE, \
+                                stderr=subprocess.PIPE,
+                                check=True)
+    except subprocess.CalledProcessError:
+        result = None
+
+    if result is not None:
+        email = result.stdout.decode('utf-8')
+        if email == '':
+            email = default_maintainers
+        else:
+            email = list(filter(None,email.split('\n')))
+    else:
+        email = default_maintainers
+
+    return email
+
+def get_message(library, symbols):
+    '''Build email message from symbols, config and maintainers'''
+    message = {}
+    maintainers = get_maintainers(library)
+
+    message['To'] = maintainers
+    if maintainers != default_maintainers:
+        message['CC'] = default_maintainers
+
+    message['Subject'] = 'Expired symbols in {}\n'.format(library)
+
+    body = EMAIL_TEMPLATE
+    for sym in symbols:
+        body += ('{}\n'.format(sym))
+
+    message['Body'] = body
+
+    return message
+
+class OutputEmail():
+    '''Format the output for email'''
+    def __init__(self, config):
+        self.config = config
+
+        self.terminal = OutputTerminal(config)
+        context = ssl.create_default_context()
+
+        # Try to log in to server and send email
+        try:
+            self.server = smtplib.SMTP(config['smtp_server'], 587)
+            self.server.starttls(context=context) # Secure the connection
+            self.server.login(config['sender'], config['password'])
+        except Exception as exception:
+            print(exception)
+            raise exception
+
+    def message(self,message):
+        '''send email'''
+        self.terminal.message(message)
+
+        msg = EmailMessage()
+        msg.set_content(message.pop('Body'))
+
+        for key in message.keys():
+            msg[key] = message[key]
+
+        msg['From'] = self.config['sender']
+        msg['Reply-To'] = 'no-reply@dpdk.org'
+
+        self.server.send_message(msg)
+
+        time.sleep(1)
+
+    def __del__(self):
+        self.server.quit()
+
+class OutputTerminal(): # pylint: disable=too-few-public-methods
+    '''Format the output for the terminal'''
+    def __init__(self, config):
+        self.config = config
+
+    def message(self,message):
+        '''Print email to terminal'''
+        terminal = 'To:' + ', '.join(message['To']) + '\n'
+        if 'sender' in self.config.keys():
+            terminal += 'From:' + self.config['sender'] + '\n'
+
+        terminal += 'Reply-To:' + 'no-reply@dpdk.org' + '\n'
+        if 'CC' in message.keys():
+            terminal += 'CC:' + ', '.join(message['CC']) + '\n'
+
+        terminal += 'Subject:' + message['Subject'] + '\n'
+        terminal += 'Body:' + message['Body'] + '\n'
+
+        print(terminal)
+        print('-' * 80)
+
+def parse_config(args):
+    '''put the command line args in the right places'''
+    config = {}
+    error_msg = None
+
+    outputs = {
+        None : OutputTerminal,
+        'terminal' : OutputTerminal,
+        'email' : OutputEmail
+    }
+
+    if args.format_output == 'email':
+        if args.smtp_server is None:
+            error_msg = 'SMTP server'
+        else:
+            config['smtp_server'] = args.smtp_server
+
+        if args.sender is None:
+            error_msg = 'sender'
+        else:
+            config['sender'] = args.sender
+
+        if args.password is None:
+            error_msg = 'password'
+        else:
+            config['password'] = args.password
+
+    if error_msg is not None:
+        print('Please specify a {} for email output'.format(error_msg))
+        return None
+
+    config['output'] = outputs[args.format_output]
+    return config
+
+def main():
+    '''Main entry point'''
+    parser = argparse.ArgumentParser(description=DESCRIPTION, \
+                                     formatter_class=RawTextHelpFormatter)
+    parser.add_argument('--format-output', choices=['terminal','email'], \
+                        default='terminal')
+    parser.add_argument('--smtp-server')
+    parser.add_argument('--password')
+    parser.add_argument('--sender')
+
+    args = parser.parse_args()
+    config = parse_config(args)
+    if config is None:
+        return
+
+    symbols = []
+    lastlib = library = ''
+
+    output = config['output'](config)
+
+    for line in sys.stdin:
+        line = line.rstrip('\n')
+        library, symbol = [line[:line.find(',')], \
+                           line[line.find(',') + 1: len(line)]]
+        if library == 'mapfile':
+            continue
+
+        if library != lastlib:
+            message = get_message(lastlib, symbols)
+            output.message(message)
+            symbols = []
+
+        lastlib = library
+        symbols = symbols + [symbol]
+
+    #print the last library
+    message = get_message(lastlib, symbols)
+    output.message(message)
+
+if __name__ == '__main__':
+    main()
-- 
2.26.2


  parent reply	other threads:[~2021-08-06 17:56 UTC|newest]

Thread overview: 50+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-06-18 16:36 [dpdk-dev] [PATCH] devtools: script to track map symbols Ray Kinsella
2021-06-18 19:40 ` Stephen Hemminger
2021-06-21  9:18   ` Kinsella, Ray
2021-06-21 15:11     ` Ray Kinsella
2021-06-21 15:25 ` [dpdk-dev] [PATCH v3] " Ray Kinsella
2021-06-21 15:35 ` [dpdk-dev] [PATCH v4] " Ray Kinsella
2021-06-21 18:14   ` Stephen Hemminger
2021-06-22 10:19 ` [dpdk-dev] [PATCH v5] " Ray Kinsella
2021-08-04 16:23 ` [dpdk-dev] [PATCH v6] " Ray Kinsella
2021-08-04 16:27 ` [dpdk-dev] [PATCH v7] " Ray Kinsella
2021-08-06 17:54 ` [dpdk-dev] [PATCH v8 0/2] devtools: scripts to count and track symbols Ray Kinsella
2021-08-06 17:54   ` [dpdk-dev] [PATCH v8 1/2] devtools: script to track map symbols Ray Kinsella
2021-08-06 17:54   ` Ray Kinsella [this message]
2021-08-09 12:53 ` [dpdk-dev] [PATCH v9 0/2] devtools: scripts to count and track symbols Ray Kinsella
2021-08-09 12:53   ` [dpdk-dev] [PATCH v9 1/2] devtools: script to track symbols over releases Ray Kinsella
2021-08-09 12:53   ` [dpdk-dev] [PATCH v9 2/2] devtools: script to send notifications of expired symbols Ray Kinsella
2021-08-31 14:50 ` [dpdk-dev] [PATCH v10 0/3] devtools: scripts to count and track symbols Ray Kinsella
2021-08-31 14:50   ` [dpdk-dev] [PATCH v10 1/3] devtools: script to track symbols over releases Ray Kinsella
2021-08-31 14:50   ` [dpdk-dev] [PATCH v10 2/3] devtools: script to send notifications of expired symbols Ray Kinsella
2021-09-01 12:46     ` Aaron Conole
2021-09-03 11:15       ` Kinsella, Ray
2021-09-03 13:32       ` Kinsella, Ray
2021-09-01 13:01     ` David Marchand
2021-09-03 13:28       ` Kinsella, Ray
2021-09-03 13:34       ` Kinsella, Ray
2021-08-31 14:50   ` [dpdk-dev] [PATCH v10 3/3] maintainers: add new abi scripts Ray Kinsella
2021-09-01 12:31   ` [dpdk-dev] [PATCH v10 0/3] devtools: scripts to count and track symbols Aaron Conole
2021-09-01 17:17     ` Stephen Hemminger
2021-09-01 19:04       ` Aaron Conole
2021-09-03 11:17         ` Kinsella, Ray
2021-09-03 13:23 ` [dpdk-dev] [PATCH v11 " Ray Kinsella
2021-09-03 13:23   ` [dpdk-dev] [PATCH v11 1/3] devtools: script to track symbols over releases Ray Kinsella
2021-09-03 13:23   ` [dpdk-dev] [PATCH v11 2/3] devtools: script to send notifications of expired symbols Ray Kinsella
2021-09-03 13:23   ` [dpdk-dev] [PATCH v11 3/3] maintainers: add new abi scripts Ray Kinsella
2021-09-08 15:12 ` [dpdk-dev] [PATCH v11 0/3] devtools: scripts to count and track symbols Ray Kinsella
2021-09-08 15:12   ` [dpdk-dev] [PATCH v11 1/3] devtools: script to track symbols over releases Ray Kinsella
2021-09-08 15:12   ` [dpdk-dev] [PATCH v11 2/3] devtools: script to send notifications of expired symbols Ray Kinsella
2021-09-08 15:12   ` [dpdk-dev] [PATCH v11 3/3] maintainers: add new abi scripts Ray Kinsella
2021-09-08 15:13 ` [dpdk-dev] [PATCH v12 0/4] devtools: scripts to count and track symbols Ray Kinsella
2021-09-08 15:13   ` [dpdk-dev] [PATCH v12 1/4] devtools: script to track symbols over releases Ray Kinsella
2021-09-08 15:13   ` [dpdk-dev] [PATCH v12 2/4] devtools: script to send notifications of expired symbols Ray Kinsella
2021-09-08 15:13   ` [dpdk-dev] [PATCH v12 3/4] maintainers: add new abi scripts Ray Kinsella
2021-09-08 15:13   ` [dpdk-dev] [PATCH v12 4/4] devtools: add asym crypto to symbol-tool ignore Ray Kinsella
2021-09-08 15:23     ` [dpdk-dev] [EXT] " Akhil Goyal
2021-09-09 13:48 ` [dpdk-dev] [PATCH v13 0/4] devtools: scripts to count and track symbols Ray Kinsella
2021-09-09 13:48   ` [dpdk-dev] [PATCH v13 1/4] devtools: script to track symbols over releases Ray Kinsella
2021-09-09 13:48   ` [dpdk-dev] [PATCH v13 2/4] devtools: script to send notifications of expired symbols Ray Kinsella
2021-09-09 13:48   ` [dpdk-dev] [PATCH v13 3/4] maintainers: add new abi scripts Ray Kinsella
2021-09-09 13:48   ` [dpdk-dev] [PATCH v13 4/4] devtools: add asym crypto to symbol-tool ignore Ray Kinsella
2023-07-06 19:13   ` [dpdk-dev] [PATCH v13 0/4] devtools: scripts to count and track symbols Stephen Hemminger

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210806175412.872237-3-mdr@ashroe.eu \
    --to=mdr@ashroe.eu \
    --cc=bruce.richardson@intel.com \
    --cc=dev@dpdk.org \
    --cc=ferruh.yigit@intel.com \
    --cc=ktraynor@redhat.com \
    --cc=stephen@networkplumber.org \
    --cc=thomas@monjalon.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).