summaryrefslogtreecommitdiffstats
path: root/roles/pkgdb2
diff options
context:
space:
mode:
authorPierre-Yves Chibon <pingou@pingoured.fr>2015-03-31 16:15:30 +0200
committerPierre-Yves Chibon <pingou@pingoured.fr>2015-03-31 16:15:59 +0200
commit15d220a17cb6c50dafaf9bd6829747adc1253805 (patch)
tree0ccf144d4faeb6e3c39acccf99583d7ea68fb392 /roles/pkgdb2
parent2982ddf5904e668edf2d27d829e270f12ff95ac4 (diff)
downloadansible-15d220a17cb6c50dafaf9bd6829747adc1253805.tar.gz
ansible-15d220a17cb6c50dafaf9bd6829747adc1253805.tar.xz
ansible-15d220a17cb6c50dafaf9bd6829747adc1253805.zip
Drop the hotfix of pkgdb-sync-bugzilla now that 1.24 is out and running
Diffstat (limited to 'roles/pkgdb2')
-rwxr-xr-xroles/pkgdb2/files/pkgdb-sync-bugzilla444
-rw-r--r--roles/pkgdb2/tasks/main.yml6
2 files changed, 0 insertions, 450 deletions
diff --git a/roles/pkgdb2/files/pkgdb-sync-bugzilla b/roles/pkgdb2/files/pkgdb-sync-bugzilla
deleted file mode 100755
index 03091d2a2..000000000
--- a/roles/pkgdb2/files/pkgdb-sync-bugzilla
+++ /dev/null
@@ -1,444 +0,0 @@
-#!/usr/bin/python -tt
-# -*- coding: utf-8 -*-
-#
-# Copyright © 2013-2014 Red Hat, Inc.
-#
-# This copyrighted material is made available to anyone wishing to use, modify,
-# copy, or redistribute it subject to the terms and conditions of the GNU
-# General Public License v.2, or (at your option) any later version. This
-# program is distributed in the hope that it will be useful, but WITHOUT ANY
-# WARRANTY expressed or implied, including the implied warranties of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
-# Public License for more details. You should have received a copy of the GNU
-# General Public License along with this program; if not, write to the Free
-# Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301, USA. Any Red Hat trademarks that are incorporated in the source
-# code or documentation are not subject to the GNU General Public License and
-# may only be used or replicated with the express permission of Red Hat, Inc.
-#
-# Red Hat Author(s): Toshio Kuratomi <tkuratom@redhat.com>
-# Author(s): Mike Watters <valholla75@fedoraproject.org>
-# Author(s): Pierre-Yves Chibon <pingou@pingoured.fr>
-#
-'''
-sync information from the packagedb into bugzilla
-
-This short script takes information about package onwership and imports it
-into bugzilla.
-'''
-
-## These two lines are needed to run on EL6
-__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
-import bugzilla
-import requests
-from email.Message import Message
-from fedora.client.fas2 import AccountSystem
-
-
-if 'PKGDB2_CONFIG' not in os.environ \
- and os.path.exists('/etc/pkgdb2/pkgdb2.cfg'):
- print 'Using configuration file `/etc/pkgdb2/pkgdb2.cfg`'
- os.environ['PKGDB2_CONFIG'] = '/etc/pkgdb2/pkgdb2.cfg'
-
-
-try:
- import pkgdb2
-except ImportError:
- sys.path.insert(
- 0, os.path.join(os.path.dirname(os.path.realpath(__file__)), '..'))
- import pkgdb2
-
-
-BZSERVER = pkgdb2.APP.config.get('PKGDB2_BUGZILLA_URL')
-BZUSER = pkgdb2.APP.config.get('PKGDB2_BUGZILLA_NOTIFY_USER')
-BZPASS = pkgdb2.APP.config.get('PKGDB2_BUGZILLA_NOTIFY_PASSWORD')
-BZCOMPAPI = pkgdb2.APP.config.get('BUGZILLA_COMPONENT_API')
-FASURL = pkgdb2.APP.config.get('PKGDB2_FAS_URL')
-FASUSER = pkgdb2.APP.config.get('PKGDB2_FAS_USER')
-FASPASS = pkgdb2.APP.config.get('PKGDB2_FAS_PASSWORD')
-FASINSECURE = pkgdb2.APP.config.get('PKGDB2_FAS_INSECURE')
-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
- self.acls = acls
-
- # Ask bugzilla for a section of the pkglist.
- # Save the information from the section that we want.
- def __getitem__(self, key):
- try:
- return super(ProductCache, self).__getitem__(key)
- except KeyError:
- # We can only cache products we have pkgdb information for
- if key not in self.acls:
- raise
-
- if BZCOMPAPI == 'getcomponentsdetails':
- # Old API -- in python-bugzilla. But with current server, this
- # gives ProxyError
- products = self.server.getcomponentsdetails(key)
- elif BZCOMPAPI == 'component.get':
- # Way that's undocumented in the partner-bugzilla api but works
- # currently
- pkglist = acls[key].keys()
- products = {}
- for pkg_segment in segment(pkglist, BZ_PKG_SEGMENT):
- # Format that bugzilla will understand. Strip None's that segment() pads
- # out the final data segment() with
- query = [dict(product=key, component=p) for p in pkg_segment if p is not None]
- raw_data = self.bz._proxy.Component.get(dict(names=query))
- for package in raw_data['components']:
- # Reformat data to be the same as what's returned from
- # getcomponentsdetails
- product = dict(initialowner=package['default_assignee'],
- description=package['description'],
- initialqacontact=package['default_qa_contact'],
- initialcclist=package['default_cc'])
- products[package['name'].lower()] = product
- self[key] = products
-
- return super(ProductCache, self).__getitem__(key)
-
-
-class Bugzilla(object):
-
- def __init__(self, bzServer, username, password, acls):
- self.bzXmlRpcServer = bzServer
- self.username = username
- self.password = password
-
- self.server = bugzilla.Bugzilla(
- url=self.bzXmlRpcServer,
- user=self.username,
- password=self.password)
- self.productCache = ProductCache(self.server, acls)
-
- # Connect to the fedora account system
- self.fas = AccountSystem(
- base_url=FASURL,
- username=FASUSER,
- password=FASPASS)
- self.userCache = self.fas.people_by_key(
- key='username',
- fields=['bugzilla_email'])
-
- def _get_bugzilla_email(self, username):
- '''Return the bugzilla email address for a user.
-
- First looks in a cache for a username => bugzilla email. If not found,
- reloads the cache from fas and tries again.
- '''
- try:
- return self.userCache[username]['bugzilla_email'].lower()
- except KeyError:
- if username.startswith('@'):
- group = self.fas.group_by_name(username[1:])
- self.userCache[username] = {
- 'bugzilla_email': group.mailing_list}
- else:
- person = self.fas.person_by_username(username)
- bz_email = person.get('bugzilla_email', None)
- if bz_email is None:
- print '%s has no bugzilla email, valid account?' % username
- else:
- self.userCache[username] = {'bugzilla_email': bz_email}
- return self.userCache[username]['bugzilla_email'].lower()
-
- def add_edit_component(self, package, collection, owner, description,
- qacontact=None, cclist=None):
- '''Add or update a component to have the values specified.
- '''
- # Turn the cclist into something usable by bugzilla
- if not cclist or 'people' not in cclist:
- initialCCList = list()
- else:
- initialCCList = [
- self._get_bugzilla_email(cc) for cc in cclist['people']]
- if 'groups' in cclist:
- group_cc = [
- self._get_bugzilla_email(cc) for cc in cclist['groups']]
- initialCCList.extend(group_cc)
-
- # Add owner to the cclist so comaintainers taking over a bug don't
- # have to do this manually
- owner = self._get_bugzilla_email(owner)
- if owner not in initialCCList:
- initialCCList.append(owner)
-
- # Lookup product
- try:
- product = self.productCache[collection]
- except xmlrpclib.Fault as e:
- # Output something useful in args
- e.args = (e.faultCode, e.faultString)
- raise
- except xmlrpclib.ProtocolError as e:
- e.args = ('ProtocolError', e.errcode, e.errmsg)
- raise
-
- pkgKey = package.lower()
- if pkgKey in product:
- # edit the package information
- data = {}
-
- # Grab bugzilla email for things changable via xmlrpc
- if qacontact:
- qacontact = self._get_bugzilla_email(qacontact)
- else:
- qacontact = 'extras-qa@fedoraproject.org'
-
- # Check for changes to the owner, qacontact, or description
- if product[pkgKey]['initialowner'] != owner:
- data['initialowner'] = owner
-
- if product[pkgKey]['description'] != description:
- data['description'] = description
- if product[pkgKey]['initialqacontact'] != qacontact and (
- qacontact or product[pkgKey]['initialqacontact']):
- data['initialqacontact'] = qacontact
-
- if len(product[pkgKey]['initialcclist']) != len(initialCCList):
- data['initialcclist'] = initialCCList
- else:
- for ccMember in product[pkgKey]['initialcclist']:
- if ccMember not in initialCCList:
- data['initialcclist'] = initialCCList
- break
-
- if data:
- ### FIXME: initialowner has been made mandatory for some
- # reason. Asking dkl why.
- data['initialowner'] = owner
-
- # Changes occurred. Submit a request to change via xmlrpc
- data['product'] = collection
- data['component'] = package
- if DRY_RUN:
- print '[EDITCOMP] Changing via editComponent(' \
- '%s, %s, "xxxxx")' % (data, self.username)
- print '[EDITCOMP] Former values: %s|%s|%s|%s' % (
- product[pkgKey]['initialowner'],
- product[pkgKey]['description'],
- product[pkgKey]['initialqacontact'],
- product[pkgKey]['initialcclist'])
- else:
- try:
- self.server.editcomponent(data)
- except xmlrpclib.Fault, e:
- # Output something useful in args
- e.args = (data, e.faultCode, e.faultString)
- raise
- except xmlrpclib.ProtocolError, e:
- e.args = ('ProtocolError', e.errcode, e.errmsg)
- raise
- else:
- # Add component
- if qacontact:
- qacontact = self._get_bugzilla_email(qacontact)
- else:
- qacontact = 'extras-qa@fedoraproject.org'
-
- data = {
- 'product': collection,
- 'component': package,
- 'description': description,
- 'initialowner': owner,
- 'initialqacontact': qacontact
- }
- if initialCCList:
- data['initialcclist'] = initialCCList
-
- if DRY_RUN:
- print '[ADDCOMP] Adding new component AddComponent:(' \
- '%s, %s, "xxxxx")' % (data, self.username)
- else:
- try:
- self.server.addcomponent(data)
- except xmlrpclib.Fault, e:
- # Output something useful in args
- e.args = (data, e.faultCode, e.faultString)
- raise
-
-
-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.
- '''
- msg = 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)
-
-
- parser = argparse.ArgumentParser(
- description='Script syncing information between pkgdb and bugzilla'
- )
- parser.add_argument(
- '--debug', dest='debug', action='store_true', default=False,
- help='Print the changes instead of making them in bugzilla')
-
- args = parser.parse_args()
-
- if args.debug:
- DRY_RUN = True
-
- # Non-fatal errors to alert people about
- errors = []
-
- # Get bugzilla information from the package database
- req = requests.get('%s/api/bugzilla/?format=json' % PKGDBSERVER)
- acls = req.json()['bugzillaAcls']
-
- # Initialize the connection to bugzilla
- bugzilla = Bugzilla(BZSERVER, BZUSER, BZPASS, acls)
-
- for product in acls.keys():
- if product not in ('Fedora', 'Fedora EPEL'):
- continue
- for pkg in sorted(acls[product]):
- if DRY_RUN:
- print pkg
- pkgInfo = acls[product][pkg]
- try:
- bugzilla.add_edit_component(
- pkg,
- product,
- pkgInfo['owner'],
- pkgInfo['summary'],
- pkgInfo['qacontact'],
- pkgInfo['cclist'])
- except ValueError, e:
- # A username didn't have a bugzilla address
- errors.append(str(e.args))
- except DataChangedError, e:
- # A Package or Collection was returned via xmlrpc but wasn't
- # present when we tried to change it
- errors.append(str(e.args))
- except xmlrpclib.ProtocolError, e:
- # Unrecoverable and likely means that nothing is going to
- # succeed.
- errors.append(str(e.args))
- break
- except xmlrpclib.Error, e:
- # An error occurred in the xmlrpc call. Shouldn't happen but
- # we better see what it is
- errors.append('%s -- %s' % (pkg, e.args[-1]))
-
- # Send notification of errors
- if errors:
- if DRY_RUN:
- print '[DEBUG]', '\n'.join(errors)
- else:
- notify_users(errors)
- send_email(
- EMAIL_FROM,
- NOTIFYEMAIL,
- 'Errors while syncing bugzilla with the PackageDB',
-'''
-The following errors were encountered while updating bugzilla with information
-from the Package Database. Please have the problems taken care of:
-
-%s
-''' % ('\n'.join(errors),))
-
- sys.exit(0)
diff --git a/roles/pkgdb2/tasks/main.yml b/roles/pkgdb2/tasks/main.yml
index 507b9357d..4f882c252 100644
--- a/roles/pkgdb2/tasks/main.yml
+++ b/roles/pkgdb2/tasks/main.yml
@@ -52,12 +52,6 @@
notify:
- restart apache
-- name: HOTFIX pkgdb-sync-bugzilla script to notify the users
- when: inventory_hostname.startswith('pkgdb02')
- copy: src=pkgdb-sync-bugzilla dest=/usr/bin/pkgdb-sync-bugzilla mode=755
- tags:
- - config
-
- name: Install the pkgdb cron jobs - sync bugzilla, update pkg info
when: inventory_hostname.startswith('pkgdb02')
template: src={{ item.file }}