[yocto] [AUH][PATCH v3 1/2] Send emails for a list of recipes
Marius Avram
marius.avram at intel.com
Fri Aug 22 02:08:38 PDT 2014
If the --send-emails or -e command line argument is active and a single
or a list of recipes are given to the script, emails with the results
and patches will be sent to their maintainers or to the overriden
addresses from the configuration file.
Also the status email will be sent in the case a selection of
at least two recipes has been given to the script for upgrading.
Signed-off-by: Marius Avram <marius.avram at intel.com>
---
upgradehelper.py | 202 +++++++++++++++++++++++++++---------------------------
1 file changed, 101 insertions(+), 101 deletions(-)
diff --git a/upgradehelper.py b/upgradehelper.py
index cc90958..658ec43 100755
--- a/upgradehelper.py
+++ b/upgradehelper.py
@@ -71,6 +71,8 @@ def parse_cmdline():
help="disable interactive mode")
parser.add_argument("-d", "--debug-level", type=int, default=4, choices=range(1, 6),
help="set the debug level: CRITICAL=1, ERROR=2, WARNING=3, INFO=4, DEBUG=5")
+ parser.add_argument("-e", "--send-emails", action="store_true", default=False,
+ help="send emails to recipe maintainers")
parser.add_argument("-s", "--skip-compilation", action="store_true", default=False,
help="do not compile, just change the checksums, remove PR, and commit")
parser.add_argument("-c", "--config-file", default=None,
@@ -116,7 +118,27 @@ def parse_config_file(config_file):
return (settings, maintainer_override)
class Updater(object):
- def __init__(self, auto_mode=False, skip_compilation=False):
+ mail_header = \
+ "Hello,\n\nYou are receiving this email because you are the maintainer\n" \
+ "of *%s* recipe and this is to let you know that the automatic attempt\n" \
+ "to upgrade the recipe to *%s* has %s.\n\n"
+
+ next_steps_info = \
+ "The recipe has been successfully compiled for all major architectures.\n\n" \
+ "Next steps:\n" \
+ " - apply the patch: git am %s\n" \
+ " - check that required patches have not been removed from the recipe\n" \
+ " - compile an image that contains the package\n" \
+ " - perform some basic sanity tests\n" \
+ " - amend the patch and sign it off: git commit -s --reset-author --amend\n" \
+ " - send it to the list\n\n" \
+
+ mail_footer = \
+ "Attached are the patch and the logs (+ license file diff) in case of failure.\n\n" \
+ "Regards,\nThe Upgrade Helper"
+
+
+ def __init__(self, auto_mode=False, send_email=False, skip_compilation=False):
self.uh_dir = get_build_dir() + "/upgrade-helper"
if not os.path.exists(self.uh_dir):
@@ -125,10 +147,13 @@ class Updater(object):
self.bb = Bitbake(get_build_dir())
self.buildhistory = BuildHistory(get_build_dir())
self.git = None
-
- self.author = None
+ if send_email:
+ self.author = "Upgrade Helper <uh at not.set>"
+ else:
+ self.author = None
self.skip_compilation = skip_compilation
self.interactive = not auto_mode
+ self.send_email = send_email
self.machines = ["qemux86", "qemux86-64", "qemuarm", "qemumips", "qemuppc"]
@@ -144,6 +169,7 @@ class Updater(object):
(self._compile, None)
]
+ self.email_handler = Email(settings)
self.statistics = Statistics()
@@ -307,8 +333,9 @@ class Updater(object):
# this function will be called at the end of each recipe upgrade
def pkg_upgrade_handler(self, err):
- if err is not None and self.patch_file is not None:
+ if err and self.patch_file:
answer = "N"
+ status_msg = str(err)
if self.interactive:
I(" %s: Do you want to keep the changes? (y/N)" % self.pn)
answer = sys.stdin.readline().strip().upper()
@@ -317,6 +344,53 @@ class Updater(object):
I(" %s: Dropping changes from git ..." % self.pn)
self.git.reset_hard(1)
self.git.clean_untracked()
+ return
+ elif not err:
+ status_msg = "Succeeded"
+
+ status = type(err).__name__
+
+ # drop last upgrade from git. It's safer this way if the upgrade has
+ # problems and other recipes depend on it. Give the other recipes a
+ # chance...
+ if ("drop_previous_commits" in settings and
+ settings["drop_previous_commits"] == "yes" and
+ err) or (err and self.patch_file):
+ I(" %s: Dropping changes from git ..." % self.pn)
+ self.git.reset_hard(1)
+ self.git.clean_untracked()
+
+ if self.send_email:
+ # don't bother maintainer with mail if the recipe is already up to date
+ if status == "UpgradeNotNeededError":
+ return
+
+ if self.maintainer in maintainer_override:
+ to_addr = maintainer_override[self.maintainer]
+ else:
+ to_addr = self.maintainer
+
+ subject = "[AUH] " + self.pn + ": upgrading to " + self.new_ver
+ if err is None:
+ subject += " SUCCEEDED"
+ else:
+ subject += " FAILED"
+
+ msg_body = self.mail_header % (self.pn, self.new_ver, status_msg)
+
+ if err is None:
+ msg_body += self.next_steps_info % os.path.basename(self.patch_file)
+
+ msg_body += self.mail_footer
+
+ # Add possible attachments to email
+ attachments = []
+ for attachment in os.listdir(self.workdir):
+ attachment_fullpath = os.path.join(self.workdir, attachment)
+ if os.path.isfile(attachment_fullpath):
+ attachments.append(attachment_fullpath)
+
+ self.email_handler.send_email(to_addr, subject, msg_body, attachments)
def _commit_changes(self):
try:
@@ -355,6 +429,22 @@ class Updater(object):
return ordered_list
+ def send_status_mail(self):
+ if "status_recipients" not in settings:
+ E("Could not send status email, no recipients set!")
+ return -1
+
+ to_list = settings["status_recipients"].split()
+
+ subject = "[AUH] Upgrade status: " + date.isoformat(date.today())
+
+ msg = self.statistics.pkg_stats() + self.statistics.maintainer_stats()
+
+ if self.statistics.total_attempted:
+ self.email_handler.send_email(to_list, subject, msg)
+ else:
+ W("No recipes attempted, not sending status mail!")
+
def run(self, package_list=None):
#[lp] pkgs_to_upgrade = self._order_list(self._get_packages_to_upgrade(package_list))
pkgs_to_upgrade = self._get_packages_to_upgrade(package_list)
@@ -399,32 +489,12 @@ class Updater(object):
if (attempted_pkgs > 1):
print("%s" % self.statistics.pkg_stats())
+ if self.send_email:
+ self.send_status_mail()
-
-class UniverseUpdater(Updater, Email):
- mail_header = \
- "Hello,\n\nYou are receiving this email because you are the maintainer\n" \
- "of *%s* recipe and this is to let you know that the automatic attempt\n" \
- "to upgrade the recipe to *%s* has %s.\n\n"
-
- next_steps_info = \
- "The recipe has been successfully compiled for all major architectures.\n\n" \
- "Next steps:\n" \
- " - apply the patch: git am %s\n" \
- " - check that required patches have not been removed from the recipe\n" \
- " - compile an image that contains the package\n" \
- " - perform some basic sanity tests\n" \
- " - amend the patch and sign it off: git commit -s --reset-author --amend\n" \
- " - send it to the list\n\n" \
-
- mail_footer = \
- "Attached are the patch and the logs (+ license file diff) in case of failure.\n\n" \
- "Regards,\nThe Upgrade Helper"
-
+class UniverseUpdater(Updater):
def __init__(self):
- Updater.__init__(self, True)
- Email.__init__(self, settings)
- self.author = "Upgrade Helper <uh at not.set>"
+ Updater.__init__(self, True, True)
self.git = Git(os.path.dirname(os.getenv('PATH', False).split(':')[0]))
# read history file
@@ -570,84 +640,14 @@ class UniverseUpdater(Updater, Email):
# overriding the base method
def pkg_upgrade_handler(self, err):
- if err is None:
- status_msg = "Succeeded"
- else:
- status_msg = str(err)
-
- status = type(err).__name__
-
- # drop last upgrade from git. It's safer this way if the upgrade has
- # problems and other recipes depend on it. Give the other recipes a
- # chance...
- if ("drop_previous_commits" in settings and
- settings["drop_previous_commits"] == "yes" and
- err is None) or (err is not None and self.patch_file is not None):
- I(" %s: Dropping changes from git ..." % self.pn)
- self.git.reset_hard(1)
- self.git.clean_untracked()
-
- self.update_history(self.pn, self.new_ver, self.maintainer,
- status_msg)
-
- # don't bother maintainer with mails for unknown errors, unsuported
- # protocol or if the recipe is already up to date
- if status == "Error" or status == "UnsupportedProtocolError" or \
- status == "UpgradeNotNeededError":
- return
-
- if self.maintainer in maintainer_override:
- to_addr = maintainer_override[self.maintainer]
- else:
- to_addr = self.maintainer
-
- subject = "[AUH] " + self.pn + ": upgrading to " + self.new_ver
- if err is None:
- subject += " SUCCEEDED"
- else:
- subject += " FAILED"
-
- msg_body = self.mail_header % (self.pn, self.new_ver, status_msg)
-
- if err is None:
- msg_body += self.next_steps_info % os.path.basename(self.patch_file)
-
- msg_body += self.mail_footer
-
- # Add possible attachments to list
- attachments = []
- for attachment in os.listdir(self.workdir):
- attachment_fullpath = os.path.join(self.workdir, attachment)
- if os.path.isfile(attachment_fullpath):
- attachments.append(attachment_fullpath)
-
- self.send_email(to_addr, subject, msg_body, attachments)
-
- def send_status_mail(self):
- if "status_recipients" not in settings:
- E("Could not send status email, no recipients set!")
- return -1
-
- to_list = settings["status_recipients"].split()
-
- subject = "[AUH] Upgrade status: " + date.isoformat(date.today())
-
- msg = self.statistics.pkg_stats() + self.statistics.maintainer_stats()
-
- if self.statistics.total_attempted:
- self.send_email(to_list, subject, msg)
- else:
- W("No recipes attempted, not sending status mail!")
+ super(UniverseUpdater, self).pkg_upgrade_handler(self)
+ self.update_history(self.pn, self.new_ver, self.maintainer, status_msg)
def run(self):
self.update_master()
-
self.prepare()
-
super(UniverseUpdater, self).run()
- self.send_status_mail()
-
if __name__ == "__main__":
global settings
@@ -675,5 +675,5 @@ if __name__ == "__main__":
for pkg in args.recipe:
pkg_list.append((pkg, None, None))
- updater = Updater(args.auto_mode, args.skip_compilation)
+ updater = Updater(args.auto_mode, args.send_emails, args.skip_compilation)
updater.run(pkg_list)
--
1.7.9.5
More information about the yocto
mailing list