refactor bot to be based on argparse

this makes the bot based on argparse, and provides a tox job that
makes running the bot in test mode a little more sane. It also
provides for a new '-n' nocomment item so you can run the bot
and not be worried that it will report to gerrit with findings.

Change-Id: If9d6a7e72dd8d9338f2dd3283cf9a761488122de
This commit is contained in:
Sean Dague 2014-01-13 14:23:00 -05:00
parent 7f42043155
commit 7f785589a6
2 changed files with 34 additions and 13 deletions

View File

@ -37,14 +37,13 @@ openstack-qa:
- negative - negative
""" """
import argparse
import ConfigParser import ConfigParser
import daemon import daemon
import irc.bot import irc.bot
import logging import logging
import logging.config import logging.config
import os import os
import sys
import threading import threading
import time import time
import yaml import yaml
@ -95,7 +94,8 @@ class RecheckWatchBot(irc.bot.SingleServerIRCBot):
class RecheckWatch(threading.Thread): class RecheckWatch(threading.Thread):
def __init__(self, ircbot, channel_config, username, queries, host, key): def __init__(self, ircbot, channel_config, username,
queries, host, key, commenting=True):
threading.Thread.__init__(self) threading.Thread.__init__(self)
self.ircbot = ircbot self.ircbot = ircbot
self.channel_config = channel_config self.channel_config = channel_config
@ -104,6 +104,7 @@ class RecheckWatch(threading.Thread):
self.queries = queries self.queries = queries
self.host = host self.host = host
self.connected = False self.connected = False
self.commenting = commenting
self.key = key self.key = key
def new_error(self, channel, data): def new_error(self, channel, data):
@ -150,7 +151,8 @@ class RecheckWatch(threading.Thread):
else: else:
event['bug_numbers'] = bug_numbers event['bug_numbers'] = bug_numbers
self._read(event) self._read(event)
stream.leave_comment(project, change_id, bug_numbers) if self.commenting:
stream.leave_comment(project, change_id, bug_numbers)
except Exception: except Exception:
self.log.exception("Uncaught exception processing event.") self.log.exception("Uncaught exception processing event.")
@ -171,7 +173,22 @@ class ChannelConfig(object):
self.events[event] = event_set self.events[event] = event_set
def _main(config): def get_options():
parser = argparse.ArgumentParser(
description="IRC bot for elastic recheck bug reporting")
parser.add_argument('-f', '--foreground',
default=False,
action='store_true',
help="Run in foreground")
parser.add_argument('-n', '--nocomment',
default=False,
action='store_true',
help="Don't comment in gerrit. Useful in testing.")
parser.add_argument('conffile', nargs=1, help="Configuration file")
return parser.parse_args()
def _main(args, config):
setup_logging(config) setup_logging(config)
fp = config.get('ircbot', 'channel_config') fp = config.get('ircbot', 'channel_config')
@ -198,31 +215,31 @@ def _main(config):
config.get('gerrit', 'user'), config.get('gerrit', 'user'),
config.get('gerrit', 'query_file'), config.get('gerrit', 'query_file'),
config.get('gerrit', 'host', 'review.openstack.org'), config.get('gerrit', 'host', 'review.openstack.org'),
config.get('gerrit', 'key')) config.get('gerrit', 'key'),
not args.nocomment
)
recheck.start() recheck.start()
bot.start() bot.start()
def main(): def main():
if len(sys.argv) < 2: args = get_options()
print "Usage: %s CONFIGFILE" % sys.argv[0]
sys.exit(1)
config = ConfigParser.ConfigParser({'server_password': None}) config = ConfigParser.ConfigParser({'server_password': None})
config.read(sys.argv[1]) config.read(args.conffile)
if config.has_option('ircbot', 'pidfile'): if config.has_option('ircbot', 'pidfile'):
pid_fn = os.path.expanduser(config.get('ircbot', 'pidfile')) pid_fn = os.path.expanduser(config.get('ircbot', 'pidfile'))
else: else:
pid_fn = '/var/run/elastic-recheck/elastic-recheck.pid' pid_fn = '/var/run/elastic-recheck/elastic-recheck.pid'
if '-d' in sys.argv: if args.foreground:
_main(config) _main(args, config)
else: else:
pid = pid_file_module.TimeoutPIDLockFile(pid_fn, 10) pid = pid_file_module.TimeoutPIDLockFile(pid_fn, 10)
with daemon.DaemonContext(pidfile=pid): with daemon.DaemonContext(pidfile=pid):
_main(config) _main(args, config)
def setup_logging(config): def setup_logging(config):

View File

@ -27,6 +27,10 @@ commands = {posargs}
[testenv:cover] [testenv:cover]
commands = python setup.py testr --coverage --testr-args='{posargs}' commands = python setup.py testr --coverage --testr-args='{posargs}'
[testenv:run]
# test to run the bot as a non voting foreground process
commands = python elastic_recheck/bot.py -f -n elasticRecheck.conf
[flake8] [flake8]
# H803 Skipped on purpose # H803 Skipped on purpose
# E125 Skipped because it's an overreach (and anti-emacs) # E125 Skipped because it's an overreach (and anti-emacs)