[Treepkg-commits] r24 - in trunk: . bin treepkg

scm-commit@wald.intevation.org scm-commit at wald.intevation.org
Tue Feb 19 20:19:24 CET 2008


Author: bh
Date: 2008-02-19 20:19:23 +0100 (Tue, 19 Feb 2008)
New Revision: 24

Added:
   trunk/bin/listpendingnotifications.py
   trunk/bin/sendnotificationmails.py
   trunk/demonotification.cfg
   trunk/notification-template.txt
Modified:
   trunk/treepkg/packager.py
   trunk/treepkg/status.py
Log:
Add support for notification mails in case of build errors

This involves a new status field notification_mail to keep track of
whether a notification has been sent for a particular build attempt and
two programs to list the pending notifications and to send the pending
notifications (similar to how the static web pages are published) as
well as the corresponding configuration files.


Added: trunk/bin/listpendingnotifications.py
===================================================================
--- trunk/bin/listpendingnotifications.py	2007-11-26 15:17:04 UTC (rev 23)
+++ trunk/bin/listpendingnotifications.py	2008-02-19 19:19:23 UTC (rev 24)
@@ -0,0 +1,32 @@
+#! /usr/bin/python2.4
+# Copyright (C) 2008 by Intevation GmbH
+# Authors:
+# Bernhard Herzog <bh at intevation.de>
+#
+# This program is free software under the GPL (>=v2)
+# Read the file COPYING coming with the software for details.
+
+"""List tracks and revisions where notifications are pending"""
+
+import treepkgcmd
+from treepkg.options import create_parser
+from treepkg.report import get_packager_group
+
+def parse_commandline():
+    return create_parser().parse_args()
+
+def list_notifications(config_file):
+    group = get_packager_group(config_file)
+    for track in group.get_package_tracks():
+        for revision in track.get_revisions():
+            if revision.status.notification_mail.name == "notification_pending":
+                print "%s %s %d" % (revision.status.status.name,
+                                    track.name, revision.revision)
+                revision.status.notification_sent()
+
+
+def main():
+    options, args = parse_commandline()
+    list_notifications(options.config_file)
+
+main()


Property changes on: trunk/bin/listpendingnotifications.py
___________________________________________________________________
Name: svn:executable
   + *
Name: svn:keywords
   + Id Revision
Name: svn:eol-style
   + native

Added: trunk/bin/sendnotificationmails.py
===================================================================
--- trunk/bin/sendnotificationmails.py	2007-11-26 15:17:04 UTC (rev 23)
+++ trunk/bin/sendnotificationmails.py	2008-02-19 19:19:23 UTC (rev 24)
@@ -0,0 +1,75 @@
+#! /usr/bin/python2.4
+# Copyright (C) 2008 by Intevation GmbH
+# Authors:
+# Bernhard Herzog <bh at intevation.de>
+#
+# This program is free software under the GPL (>=v2)
+# Read the file COPYING coming with the software for details.
+
+"""Send pending notification mails"""
+
+import os
+import smtplib
+import email
+import email.Utils
+from optparse import OptionParser
+from ConfigParser import SafeConfigParser
+
+import treepkgcmd
+from treepkg.readconfig import read_config_section
+from treepkg.run import capture_output
+from treepkg.cmdexpand import cmdexpand
+
+notification_desc = ["build_user", "build_host", "build_listpending",
+                     "notification_template", "base_url",
+                     "smtp_host", ("smtp_port", int),
+                     ]
+
+def read_config(filename):
+    parser = SafeConfigParser()
+    parser.read([filename])
+    return read_config_section(parser, "notification", notification_desc)
+
+def parse_commandline():
+    parser = OptionParser()
+    parser.set_defaults(config_file=os.path.join(treepkgcmd.topdir,
+                                                 "notification.cfg"))
+    parser.add_option("--config-file",
+                      help=("The configuration file."
+                            " Default notification.cfg"))
+    return parser.parse_args()
+
+
+def send_mail(config, raw_message):
+    msg = email.message_from_string(raw_message)
+    sender = email.Utils.parseaddr(msg["From"])[1]
+    recipients = [addr[1] for addr
+                  in email.Utils.getaddresses(msg.get_all("To", [])
+                                              + msg.get_all("Cc", []))]
+    server = smtplib.SMTP(config["smtp_host"], config["smtp_port"])
+    server.sendmail(sender, recipients, raw_message)
+    server.quit()
+
+
+def send_notification_mails(config_filename):
+    config = read_config(config_filename)
+
+    template = open(config["notification_template"]).read()
+
+    lines = capture_output(cmdexpand("ssh $build_user$@$build_host"
+                                     " $build_listpending",
+                                     **config))
+    for line in lines.splitlines():
+        words = line.split()
+        if len(words) == 3:
+            status, track, revision = words
+            values = config.copy()
+            values.update(locals())
+            send_mail(config, template % values)
+
+
+def main():
+    options, args = parse_commandline()
+    send_notification_mails(options.config_file)
+
+main()


Property changes on: trunk/bin/sendnotificationmails.py
___________________________________________________________________
Name: svn:executable
   + *
Name: svn:keywords
   + Id Revision
Name: svn:eol-style
   + native

Added: trunk/demonotification.cfg
===================================================================
--- trunk/demonotification.cfg	2007-11-26 15:17:04 UTC (rev 23)
+++ trunk/demonotification.cfg	2008-02-19 19:19:23 UTC (rev 24)
@@ -0,0 +1,38 @@
+# Demo config file for sendnotificationmails.py.  The default config
+# file used by sendnotificationmails.py is notification.cfg, so to use
+# this file as the basis for your configuration, copy or rename this
+# file and adapt it to your needs.
+
+[notification]
+
+# Username and host on which the treepackager runs.
+# sendnotificationmails.py has to be able to connect to that host as the
+# builduser via ssh without knowning the password.  This is best
+# achieved with the ssh-agent.
+build_user: builder
+build_host: localhost
+
+# the program to run on build_host to list the pending notifications
+# currently sendnotificationmails.py assumes that the default
+# configuration for that program works.
+build_listpending: ~/treepkg/bin/listpendingnotifications.py
+
+
+# Template of the notification email.  The expanded text is sent as the
+# entire email.  This means that the file should contain both the
+# headers and the body of the email.  The recipients of the mail are
+# taken from the expanded template's To: and CC: headers.  The smtp
+# envelope sender is taken from the From: header.
+#
+#  Substitutions have the form %(NAME)s where NAME can be one of these:
+#
+#  track       The name of the package track
+#
+#  revision    The revision number for which the notification has to be sent
+#
+#
+notification_template: notification_template.txt
+
+# host/port of the smtp server to use
+smtp_host: localhost
+smtp_port: 25

Added: trunk/notification-template.txt
===================================================================
--- trunk/notification-template.txt	2007-11-26 15:17:04 UTC (rev 23)
+++ trunk/notification-template.txt	2008-02-19 19:19:23 UTC (rev 24)
@@ -0,0 +1,16 @@
+From: TreePackager <treepkg at example.com>
+To: Project Developemen List <project-devel at example.com>
+Subject: TreePackager: error builder %(track)s rev. %(revision)s
+MIME-Version: 1.0
+Content-type: text/plain
+
+Hello,
+
+an error occurred while building the %(track)s packages for revision
+%(revision)s.  Details are available in the build log:
+
+  http://example.com/treepkg/%(track)s/%(revision)s/build_log.txt
+
+General information about the status of the packages is available at
+
+  http://example.com/treepkg/


Property changes on: trunk/notification-template.txt
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Revision
Name: svn:eol-style
   + native

Modified: trunk/treepkg/packager.py
===================================================================
--- trunk/treepkg/packager.py	2007-11-26 15:17:04 UTC (rev 23)
+++ trunk/treepkg/packager.py	2008-02-19 19:19:23 UTC (rev 24)
@@ -1,4 +1,4 @@
-# Copyright (C) 2007 by Intevation GmbH
+# Copyright (C) 2007, 2008 by Intevation GmbH
 # Authors:
 # Bernhard Herzog <bh at intevation.de>
 #
@@ -264,6 +264,12 @@
         except:
             self.status.error()
             self.status.stop = datetime.datetime.utcnow()
+            # set the notification status last to avoid race conditions.
+            # The pending notification is for now the only situation
+            # where another process might modify the status file (the
+            # listpendingnotifications program will set it to
+            # "notification_sent")
+            self.status.notification_pending()
             raise
 
     def remove_package_dir(self):

Modified: trunk/treepkg/status.py
===================================================================
--- trunk/treepkg/status.py	2007-11-26 15:17:04 UTC (rev 23)
+++ trunk/treepkg/status.py	2008-02-19 19:19:23 UTC (rev 24)
@@ -1,4 +1,4 @@
-# Copyright (C) 2007 by Intevation GmbH
+# Copyright (C) 2007, 2008 by Intevation GmbH
 # Authors:
 # Bernhard Herzog <bh at intevation.de>
 #
@@ -187,3 +187,9 @@
 
     start = DateFieldDesc(default=None)
     stop = DateFieldDesc(default=None)
+
+    notification_mail = EnumFieldDesc()
+    notification_mail.add("notification_sent",
+                          "notification mail has been sent", default=True)
+    notification_mail.add("notification_pending",
+                          "notification mail still needs to be sent")



More information about the Treepkg-commits mailing list