From d7e72167ae957089538954df27e8eca222d9d480 Mon Sep 17 00:00:00 2001 From: wangchong1995924 <15229716099@163.com> Date: Wed, 19 May 2021 10:08:10 +0800 Subject: [PATCH] add obs mail notice function and update releasenode --- core/obs_mail_notice.py | 141 ++++++++++++++++++++++++++++++++++++++++ core/runner.py | 12 +++- openeuler_obs.py | 15 ++++- releasenode.txt | 4 +- 4 files changed, 168 insertions(+), 4 deletions(-) create mode 100644 core/obs_mail_notice.py diff --git a/core/obs_mail_notice.py b/core/obs_mail_notice.py new file mode 100644 index 0000000..f7dc40d --- /dev/null +++ b/core/obs_mail_notice.py @@ -0,0 +1,141 @@ +#!/bin/env python3 +# -*- encoding=utf8 -*- +#****************************************************************************** +# Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved. +# licensed under the Mulan PSL v2. +# You can use this software according to the terms and conditions of the Mulan PSL v2. +# You may obtain a copy of Mulan PSL v2 at: +# http://license.coscl.org.cn/MulanPSL2 +# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR +# PURPOSE. +# See the Mulan PSL v2 for more details. +# Author: wangchong +# Create: 2021-05-19 +# ****************************************************************************** + +""" +OBS mail notice +""" +import os +import re +import sys +import shutil +import smtplib +from email.mime.text import MIMEText +from email.header import Header +from concurrent.futures import ThreadPoolExecutor +from common.log_obs import log + +class ObsMailNotice(object): + """ + check obs proj pkg results and email notification + """ + def __init__(self, **kwargs): + """ + from_addr: email sender + from_addr_pwd: email sender password + cc_addr: cc's email + proj: obs project name + """ + self.kwargs = kwargs + self.from_addr = self.kwargs["from_addr"] + self.from_addr_pwd = self.kwargs["from_addr_pwd"] + self.cc_addr = self.kwargs["cc_addr"] + self.proj = self.kwargs["project"] + self.failed_pkglist = [] + self.to_addr = "" + + def send_email(self, pkg): + """ + send a email + """ + proj_url = "https://build.openeuler.org/project/show/%s" % self.proj + pkg_url = "https://build.openeuler.org/package/show/%s/%s" % (self.proj, pkg) + message = ''' + +

Hello:

+ + + +
OBS_PROJECTPACKAGEBUILD_RESULT
%s%sfailed
+

Please solve it as soon as possible.

+

Thanks !!!

+ ''' % (proj_url, self.proj, pkg_url, pkg) + msg = MIMEText(message, 'html') + msg['Subject'] = Header("OBS Package Build Failed Notice", "utf-8") + msg["From"] = Header(self.from_addr) + msg["To"] = Header(self.to_addr) + msg["Cc"] = Header(self.cc_addr) + smtp_server = "smtp.163.com" + try: + server = smtplib.SMTP(smtp_server, 25) + server.login(self.from_addr, self.from_addr_pwd) + server.sendmail(self.from_addr, self.to_addr.split(',') + self.cc_addr.split(','), msg.as_string()) + server.quit() + return 0 + except smtplib.SMTPException as e: + return e + + def get_proj_status(self): + """ + get proj build results + """ + cmd = "osc r --csv %s 2>/dev/null | grep failed | awk -F ';' '{print $1}'" % self.proj + self.failed_pkglist = [x for x in os.popen(cmd).read().split('\n') if x != ''] + log.info("%s build failed packages:%s" % (self.proj, self.failed_pkglist)) + + def get_pkg_owner_email(self, pkg): + """ + get the email address of the package owner + """ + log.info("Begin to get package %s owner email..." % pkg) + _tmpdir = os.popen("mktemp -d").read().strip('\n') + pkg_path = os.path.join(_tmpdir, self.proj, pkg) + cmd = "cd %s && osc co %s %s &>/dev/null && cd %s && osc up -S &>/dev/null" % ( + _tmpdir, self.proj, pkg, pkg_path) + if os.system(cmd) == 0: + cmd = "cd {0} && grep -A 1 \"%changelog\" *.spec | grep \"@\" && cd -".format( + pkg_path) + email = os.popen(cmd).read() + if email: + try: + self.to_addr = re.findall(r"<(.+?)>", email)[0] + except IndexError: + self.to_addr = self.cc_addr.split(',')[0] + else: + self.to_addr = self.cc_addr.split(',')[0] + log.info("Get package %s email succeed!" % pkg) + shutil.rmtree(_tmpdir) + else: + log.info("osc co %s %s failed!" % (self.proj, pkg)) + self.to_addr = self.cc_addr.split(',')[0] + log.info("Get package %s email failed, will use leader email." % pkg) + shutil.rmtree(_tmpdir) + + def notify_respon_person(self, pkg): + """ + notice a package to person + """ + self.get_pkg_owner_email(pkg) + ret = self.send_email(pkg) + if ret == 0: + log.info("send %s email succeed !" % pkg) + else: + log.error("send %s email failed, Error:%s" % (pkg, ret)) + + def notify_all_respon_person(self): + """ + notice all packages to person + """ + self.get_proj_status() + with ThreadPoolExecutor(10) as executor: + for pkg in self.failed_pkglist: + executor.submit(self.notify_respon_person, pkg) + + +if __name__ == "__main__": + kw = {"from_addr":sys.argv[1], "from_addr_pwd":sys.argv[2], + "cc_addr":sys.argv[3], "project":sys.argv[4]} + omn = ObsMailNotice(**kw) + omn.notify_all_respon_person() diff --git a/core/runner.py b/core/runner.py index eb96220..2d36e63 100644 --- a/core/runner.py +++ b/core/runner.py @@ -27,6 +27,7 @@ from core.getdate import GETDate from core.check_meta_service import CheckMetaPull from core.package_manager import OBSPkgManager from core.update_obs_repos import RPMManager +from core.obs_mail_notice import ObsMailNotice import os class Runner(object): @@ -110,6 +111,14 @@ class Runner(object): get_date = GETDate(**self.kwargs) get_date.update_to_obs_pkg_rpms() + def _mail_notice(self): + """ + send mail to the package owner + """ + log.debug("OBS Mail Notice") + mail_notice = ObsMailNotice(**self.kwargs) + mail_notice.notify_all_respon_person() + def run(self): """ run main @@ -137,4 +146,5 @@ class Runner(object): check.do_all() elif self.kwargs["get_latest_date"] == "true" and self.kwargs["branch"]: self._get_latest_date() - + elif self.kwargs["obs_mail_notice"] == "true": + self._mail_notice() diff --git a/openeuler_obs.py b/openeuler_obs.py index 6ee2db0..570647f 100644 --- a/openeuler_obs.py +++ b/openeuler_obs.py @@ -93,7 +93,14 @@ par.add_argument("-sgo", "--sync_gitee_to_obs", default=None, par.add_argument("-gld", "--get_latest_date", default=None, help="get the latest git date to obs_pkg_rpms --get_latest_date=true", required=False) - +par.add_argument("-omn", "--obs_mail_notice", default=False, + help="obs mail notice to package owner --obs_mail_notice=true", required=False) +par.add_argument("-fa", "--from_addr", default=None, + help="email sender", required=False) +par.add_argument("-fap", "--from_addr_pwd", default=None, + help="email sender password", required=False) +par.add_argument("-ca", "--cc_addr", default=None, + help="cc's email", required=False) par.add_argument("-a", "--ALL_", default=False, help="update all obs repo rpms", required=False) args = par.parse_args() @@ -130,7 +137,11 @@ kw = { "sync_code": args.sync_code, "all": args.ALL_, "sync_gitee_to_obs": args.sync_gitee_to_obs, - "get_latest_date": args.get_latest_date + "get_latest_date": args.get_latest_date, + "from_addr": args.from_addr, + "from_addr_pwd": args.from_addr_pwd, + "cc_addr": args.cc_addr, + "obs_mail_notice": args.obs_mail_notice } run = Runner(**kw) diff --git a/releasenode.txt b/releasenode.txt index 66050a4..56f1d3c 100644 --- a/releasenode.txt +++ b/releasenode.txt @@ -3,4 +3,6 @@ support multi_version v1.2.7: use multithreading to manipulate packages and add Rename-pkg-name type v1.2.8: -Added the ablility to get the latest repository code time and synchronize to obs_pkg_rpms +Added the ablility to get the latest repository code time and synchronize to obs_pkg_rpms +v1.2.9: +Added OBS package build failed email notification -- Gitee