From: Michael Tremer Date: Thu, 22 Apr 2010 17:12:14 +0000 (+0200) Subject: naoki: Naoki will be able to send mails on errors. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4be1f1154da036b9f4f443ceb11cdad6b10fb3cd;p=ipfire-3.x.git naoki: Naoki will be able to send mails on errors. You need to configure: [smtp] server = 1.2.3.4 user = me # Optional login user password = *** # Password that belongs to user [error_report] recipient = @ipfire.org --- diff --git a/naoki/backend.py b/naoki/backend.py index 4005f1e89..9129cc333 100644 --- a/naoki/backend.py +++ b/naoki/backend.py @@ -1,7 +1,10 @@ #!/usr/bin/python +import email.mime.multipart +import email.mime.text import os import shutil +import smtplib import urlgrabber import urlgrabber.progress import urllib @@ -259,6 +262,7 @@ class PackageInfo(object): "fingerprint" : self.fingerprint, "files" : self.package_files, "group" : self.group, + "id" : self.id, "license" : self.license, "maintainer" : self.maintainer, "name" : self.name, @@ -553,3 +557,81 @@ class BinaryRepository(object): @property def path(self): return os.path.join(REPOSDIR, self.name, self.arch["name"]) + +def report_error_by_mail(package): + log = package.naoki.log + + # Do not send a report if no recipient is configured + if not config["error_report_recipient"]: + return + + try: + connection = smtplib.SMTP(config["smtp_server"]) + #connection.set_debuglevel(1) + + if config["smtp_user"] and config["smtp_password"]: + connection.login(config["smtp_user"], config["smtp_password"]) + + except SMTPConnectError, e: + log.error("Could not establish a connection to the smtp server: %s" % e) + return + except SMTPAuthenticationError, e: + log.error("Could not successfully login to the smtp server: %s" % e) + return + + msg = email.mime.multipart.MIMEMultipart() + msg["From"] = config["error_report_sender"] + msg["To"] = config["error_report_recipient"] + msg["Subject"] = config["error_report_subject"] % package.all + msg.preamble = 'You will not see this in a MIME-aware mail reader.\n' + + body = """\ +The package %(name)s had a difficulty to build itself. +This email will give you a short report about the error. + +Package information: + Name : %(name)s - %(summary)s + Version : %(version)s + Release : %(release)s + + This package in maintained by %(maintainer)s. + + +A detailed logfile is attached. + +Sincerely, + Naoki + """ % package.all + + msg.attach(email.mime.text.MIMEText(body)) + + # Read log and append it to mail + logfile = os.path.join(LOGDIR, package.id + ".log") + if os.path.exists(logfile): + log = [] + f = open(logfile) + line = f.readline() + while line: + line = line.rstrip("\n") + if line.endswith(LOG_MARKER): + # Reset log + log = [] + + log.append(line) + line = f.readline() + + f.close() + + log = email.mime.text.MIMEText("\n".join(log), _subtype="plain") + log.add_header('Content-Disposition', 'attachment', + filename="%s.log" % package.id) + msg.attach(log) + + try: + connection.sendmail(config["error_report_sender"], + config["error_report_recipient"], msg.as_string()) + except Exception, e: + log.error("Could not send error report: %s: %s" % (e.__class__.__name__, e)) + return + + connection.quit() diff --git a/naoki/chroot.py b/naoki/chroot.py index 35c01b00d..a1888fd9c 100644 --- a/naoki/chroot.py +++ b/naoki/chroot.py @@ -333,6 +333,8 @@ class PackageEnvironment(Environment): Environment.__init__(self, naoki=package.naoki, *args, **kwargs) def build(self): + self.log.debug(LOG_MARKER) + self.package.download() # Save start time @@ -343,6 +345,7 @@ class PackageEnvironment(Environment): except Error: if config["cleanup_on_failure"]: self.clean() + backend.report_error_by_mail(self.package) raise time_end = time.time() diff --git a/naoki/constants.py b/naoki/constants.py index 48238aa26..f77b00c4a 100644 --- a/naoki/constants.py +++ b/naoki/constants.py @@ -3,6 +3,7 @@ import ConfigParser import math import os +import socket BASEDIR = os.getcwd() @@ -26,6 +27,8 @@ CONFIGFILE = os.path.join(CONFIGDIR, "naoki.conf") CHROOT_PATH = "/sbin:/bin:/usr/sbin:/usr/bin" +LOG_MARKER = "### LOG MARKER ###" + def calc_parallelism(): """ Calculate how many processes to run @@ -67,6 +70,16 @@ class Config(object): # Logging "log_config_file" : os.path.join(CONFIGDIR, "logging.ini"), "log_file" : os.path.join(LOGDIR, "naoki.log"), + # + # Reporting + "error_report_recipient" : None, + "error_report_sender" : "buildsystem@%s" % socket.gethostname(), + "error_report_subject" : "[NAOKI] %(id)s got a build failure", + # + # SMTP + "smtp_server" : None, + "smtp_user" : None, + "smtp_password" : None, } def __init__(self):