diff options
| author | Pierre-Yves Chibon <pingou@pingoured.fr> | 2015-03-06 09:30:58 +0100 |
|---|---|---|
| committer | Pierre-Yves Chibon <pingou@pingoured.fr> | 2015-03-06 09:31:11 +0100 |
| commit | 2198e5709cf3b0954da2cc36e3061a7870b8456c (patch) | |
| tree | 66fdd8f74f466b0317dd7a60858238c5238253d8 /roles/pkgdb2/files | |
| parent | 3cba755812d8fe1a3f4e57a35caaba735b3f5d9e (diff) | |
| download | ansible-2198e5709cf3b0954da2cc36e3061a7870b8456c.tar.gz ansible-2198e5709cf3b0954da2cc36e3061a7870b8456c.tar.xz ansible-2198e5709cf3b0954da2cc36e3061a7870b8456c.zip | |
Hotfix pkgdb-sync-bugzilla to automatically send notifications
Diffstat (limited to 'roles/pkgdb2/files')
| -rwxr-xr-x | roles/pkgdb2/files/pkgdb-sync-bugzilla | 81 |
1 files changed, 76 insertions, 5 deletions
diff --git a/roles/pkgdb2/files/pkgdb-sync-bugzilla b/roles/pkgdb2/files/pkgdb-sync-bugzilla index 408019a7d..03091d2a2 100755 --- a/roles/pkgdb2/files/pkgdb-sync-bugzilla +++ b/roles/pkgdb2/files/pkgdb-sync-bugzilla @@ -32,9 +32,12 @@ __requires__ = ['SQLAlchemy >= 0.7', 'jinja2 >= 2.4'] import pkg_resources import argparse +import datetime +import time import sys import os import itertools +import json import xmlrpclib import codecs import smtplib @@ -70,18 +73,24 @@ NOTIFYEMAIL = pkgdb2.APP.config.get('PKGDB2_BUGZILLA_NOTIFY_EMAIL') PKGDBSERVER = pkgdb2.APP.config.get('SITE_URL') DRY_RUN = pkgdb2.APP.config.get('PKGDB2_BUGZILLA_DRY_RUN', False) +EMAIL_FROM = 'accounts@fedoraproject.org' +DATA_CACHE = '/var/tmp/pkgdb_sync_bz.json' + # When querying for current info, take segments of 1000 packages a time BZ_PKG_SEGMENT = 1000 + class DataChangedError(Exception): '''Raised when data we are manipulating changes while we're modifying it.''' pass + def segment(iterable, chunk, fill=None): '''Collect data into `chunk` sized block''' args = [iter(iterable)] * chunk return itertools.izip_longest(*args, fillvalue=fill) + class ProductCache(dict): def __init__(self, bz, acls): self.bz = bz @@ -284,7 +293,7 @@ class Bugzilla(object): raise -def send_email(fromAddress, toAddress, subject, message): +def send_email(fromAddress, toAddress, subject, message, ccAddress=None): '''Send an email if there's an error. This will be replaced by sending messages to a log later. @@ -293,12 +302,70 @@ def send_email(fromAddress, toAddress, subject, message): msg.add_header('To', ','.join(toAddress)) msg.add_header('From', fromAddress) msg.add_header('Subject', subject) + if ccAddress is not None: + msg.add_header('Cc', ','.join(ccAddress)) msg.set_payload(message) smtp = smtplib.SMTP('bastion') smtp.sendmail(fromAddress, toAddress, msg.as_string()) smtp.quit() +def notify_users(errors): + ''' Browse the list of errors and when we can retrieve the email + address, use it to notify the user about the issue. + ''' + tmpl_email = pkgdb2.APP.config.get('PKGDB_SYNC_BUGZILLA_EMAIL', None) + if not tmpl_email: + print 'No template email configured in the configuration file, '\ + 'no notification sent to the users' + return + + data = {} + if os.path.exists(DATA_CACHE): + try: + with open(DATA_CACHE) as stream: + data = json.load(stream) + except Exception as err: + print 'Could not read the json file at %s: \nError: %s' % ( + DATA_CACHE, err) + + new_data = {} + for error in errors: + notify_user = False + if 'The name ' in error and ' is not a valid username' in error: + user_email = error.split(' is not a valid username')[0].split( + 'The name ')[1].strip() + now = datetime.datetime.utcnow() + + # See if we already know about this user + if user_email in data and data[user_email]['last_update']: + last_update = datetime.datetime.fromtimestamp( + int(data[user_email]['last_update'])) + # Only notify users once per hour + if (now - last_update).seconds >= 3600: + notify_user = True + else: + new_data[user_email] = data[user_email] + elif not data or user_email not in data: + notify_user = True + + if notify_user: + send_email( + EMAIL_FROM, + [user_email], + subject='Please fix your bugzilla.redhat.com account', + message=tmpl_email, + ccAddress=NOTIFYEMAIL, + ) + + new_data[user_email] = { + 'last_update': time.mktime(now.timetuple()) + } + + with open(DATA_CACHE, 'w') as stream: + json.dump(new_data, stream) + + if __name__ == '__main__': sys.stdout = codecs.getwriter('utf-8')(sys.stdout) @@ -328,7 +395,7 @@ if __name__ == '__main__': for product in acls.keys(): if product not in ('Fedora', 'Fedora EPEL'): continue - for pkg in acls[product]: + for pkg in sorted(acls[product]): if DRY_RUN: print pkg pkgInfo = acls[product][pkg] @@ -355,12 +422,16 @@ if __name__ == '__main__': except xmlrpclib.Error, e: # An error occurred in the xmlrpc call. Shouldn't happen but # we better see what it is - errors.append(str(e.args)) + errors.append('%s -- %s' % (pkg, e.args[-1])) # Send notification of errors if errors: - #print '[DEBUG]', '\n'.join(errors) - send_email('accounts@fedoraproject.org', + if DRY_RUN: + print '[DEBUG]', '\n'.join(errors) + else: + notify_users(errors) + send_email( + EMAIL_FROM, NOTIFYEMAIL, 'Errors while syncing bugzilla with the PackageDB', ''' |
