Make bot.py behave like a daemon
This includes a number of changes to prevent printing to stdout and enable using daemonContext so that we can run bot.py as a daemon.
This commit is contained in:
parent
b0b024e080
commit
545012839a
28
bot.py
28
bot.py
@ -25,7 +25,6 @@ openstack-qa:
|
|||||||
|
|
||||||
import ConfigParser
|
import ConfigParser
|
||||||
import daemon
|
import daemon
|
||||||
import lockfile
|
|
||||||
import irc.bot
|
import irc.bot
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
@ -37,6 +36,14 @@ import logging
|
|||||||
from elasticRecheck import Stream
|
from elasticRecheck import Stream
|
||||||
from elasticRecheck import Classifier
|
from elasticRecheck import Classifier
|
||||||
|
|
||||||
|
try:
|
||||||
|
import daemon.pidlockfile
|
||||||
|
pid_file_module = daemon.pidlockfile
|
||||||
|
except Exception:
|
||||||
|
# as of python-daemon 1.6 it doesn't bundle pidlockfile anymore
|
||||||
|
# instead it depends on lockfile-0.9.1
|
||||||
|
import daemon.pidfile
|
||||||
|
pid_file_module = daemon.pidfile
|
||||||
|
|
||||||
|
|
||||||
class RecheckWatchBot(irc.bot.SingleServerIRCBot):
|
class RecheckWatchBot(irc.bot.SingleServerIRCBot):
|
||||||
@ -47,7 +54,7 @@ class RecheckWatchBot(irc.bot.SingleServerIRCBot):
|
|||||||
self.channel_list = channels
|
self.channel_list = channels
|
||||||
self.nickname = nickname
|
self.nickname = nickname
|
||||||
self.password = password
|
self.password = password
|
||||||
self.log = logging.getLogger('gerritbot')
|
self.log = logging.getLogger('recheckwatchbot')
|
||||||
|
|
||||||
def on_nicknameinuse(self, c, e):
|
def on_nicknameinuse(self, c, e):
|
||||||
self.log.info('Nick previously in use, recovering.')
|
self.log.info('Nick previously in use, recovering.')
|
||||||
@ -73,13 +80,15 @@ class RecheckWatchBot(irc.bot.SingleServerIRCBot):
|
|||||||
self.connection.privmsg(channel, msg)
|
self.connection.privmsg(channel, msg)
|
||||||
time.sleep(0.5)
|
time.sleep(0.5)
|
||||||
|
|
||||||
|
|
||||||
class RecheckWatch(threading.Thread):
|
class RecheckWatch(threading.Thread):
|
||||||
def __init__(self, ircbot, channel_config, username):
|
def __init__(self, ircbot, channel_config, username, queries):
|
||||||
threading.Thread.__init__(self)
|
threading.Thread.__init__(self)
|
||||||
self.ircbot = ircbot
|
self.ircbot = ircbot
|
||||||
self.channel_config = channel_config
|
self.channel_config = channel_config
|
||||||
self.log = logging.getLogger('recheckwatchbot')
|
self.log = logging.getLogger('recheckwatchbot')
|
||||||
self.username = username
|
self.username = username
|
||||||
|
self.queries = queries
|
||||||
self.connected = False
|
self.connected = False
|
||||||
|
|
||||||
def new_error(self, channel, data):
|
def new_error(self, channel, data):
|
||||||
@ -108,7 +117,7 @@ class RecheckWatch(threading.Thread):
|
|||||||
self.new_error(channel, data)
|
self.new_error(channel, data)
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
classifier = Classifier()
|
classifier = Classifier(self.queries)
|
||||||
stream = Stream(self.username)
|
stream = Stream(self.username)
|
||||||
while True:
|
while True:
|
||||||
event = stream.get_failed_tempest()
|
event = stream.get_failed_tempest()
|
||||||
@ -122,7 +131,6 @@ class RecheckWatch(threading.Thread):
|
|||||||
self._read(event)
|
self._read(event)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class ChannelConfig(object):
|
class ChannelConfig(object):
|
||||||
def __init__(self, data):
|
def __init__(self, data):
|
||||||
self.data = data
|
self.data = data
|
||||||
@ -160,7 +168,9 @@ def _main():
|
|||||||
config.get('ircbot', 'server'),
|
config.get('ircbot', 'server'),
|
||||||
config.getint('ircbot', 'port'),
|
config.getint('ircbot', 'port'),
|
||||||
config.get('ircbot', 'server_password'))
|
config.get('ircbot', 'server_password'))
|
||||||
recheck = RecheckWatch(bot, channel_config, config.get('gerrit', 'user'))
|
recheck = RecheckWatch(bot, channel_config,
|
||||||
|
config.get('gerrit', 'user'),
|
||||||
|
config.get('gerrit', 'query_file'))
|
||||||
|
|
||||||
recheck.start()
|
recheck.start()
|
||||||
bot.start()
|
bot.start()
|
||||||
@ -171,9 +181,9 @@ def main():
|
|||||||
print "Usage: %s CONFIGFILE" % sys.argv[0]
|
print "Usage: %s CONFIGFILE" % sys.argv[0]
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
pid = lockfile.FileLock(
|
pid = pid_file_module.TimeoutPIDLockFile(
|
||||||
"/var/run/recheckwatchbot/recheckwatchbot.pid", 10)
|
"/tmp/recheckwatchbot.pid", 10)
|
||||||
# with daemon.DaemonContext(pidfile=pid):
|
with daemon.DaemonContext(pidfile=pid):
|
||||||
_main()
|
_main()
|
||||||
|
|
||||||
|
|
||||||
|
@ -3,7 +3,8 @@ nick=RecheckWatchBot
|
|||||||
pass=
|
pass=
|
||||||
server=irc.freenode.net
|
server=irc.freenode.net
|
||||||
port=6667
|
port=6667
|
||||||
channel_config=recheckwatchbot.yaml
|
channel_config=/home/mtreinish/elasticRecheck/recheckwatchbot.yaml
|
||||||
|
|
||||||
[gerrit]
|
[gerrit]
|
||||||
user=jogo
|
user=treinish
|
||||||
|
query_file=/home/mtreinish/elasticRecheck/queries.json
|
||||||
|
@ -104,9 +104,10 @@ class Classifier():
|
|||||||
|
|
||||||
queries = None
|
queries = None
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self, queries):
|
||||||
self.es = ElasticSearch(self.ES_URL)
|
self.es = ElasticSearch(self.ES_URL)
|
||||||
self.queries = json.loads(open('queries.json').read())
|
self.queries = json.loads(open(queries).read())
|
||||||
|
self.log = logging.getLogger("recheckwatchbot")
|
||||||
|
|
||||||
def _apply_template(self, template, values):
|
def _apply_template(self, template, values):
|
||||||
query = copy.deepcopy(template)
|
query = copy.deepcopy(template)
|
||||||
@ -121,7 +122,7 @@ class Classifier():
|
|||||||
|
|
||||||
def last_failures(self):
|
def last_failures(self):
|
||||||
for x in self.queries:
|
for x in self.queries:
|
||||||
print "Looking for bug: https://bugs.launchpad.net/bugs/%s" % x['bug']
|
self.log.debug("Looking for bug: https://bugs.launchpad.net/bugs/%s" % x['bug'])
|
||||||
query = self._apply_template(self.general_template, x['query'])
|
query = self._apply_template(self.general_template, x['query'])
|
||||||
results = self.es.search(query, size='10')
|
results = self.es.search(query, size='10')
|
||||||
self._parse_results(results)
|
self._parse_results(results)
|
||||||
@ -131,10 +132,10 @@ class Classifier():
|
|||||||
try:
|
try:
|
||||||
change = x["_source"]['@fields']['build_change']
|
change = x["_source"]['@fields']['build_change']
|
||||||
patchset = x["_source"]['@fields']['build_patchset']
|
patchset = x["_source"]['@fields']['build_patchset']
|
||||||
print "build_name %s" % x["_source"]['@fields']['build_name']
|
self.log.debug("build_name %s" % x["_source"]['@fields']['build_name'])
|
||||||
print "https://review.openstack.org/#/c/%(change)s/%(patchset)s" % locals()
|
self.log.debug("https://review.openstack.org/#/c/%(change)s/%(patchset)s" % locals())
|
||||||
except KeyError:
|
except KeyError:
|
||||||
print "build_name %s" % x["_source"]['@fields']['build_name']
|
self.log.debug("build_name %s" % x["_source"]['@fields']['build_name'])
|
||||||
|
|
||||||
def classify(self, change_number, patch_number, comment):
|
def classify(self, change_number, patch_number, comment):
|
||||||
"""Returns either None or a bug number"""
|
"""Returns either None or a bug number"""
|
||||||
@ -143,7 +144,7 @@ class Classifier():
|
|||||||
#Wait till Elastic search is ready
|
#Wait till Elastic search is ready
|
||||||
self._wait_till_ready(change_number, patch_number, comment)
|
self._wait_till_ready(change_number, patch_number, comment)
|
||||||
for x in self.queries:
|
for x in self.queries:
|
||||||
print "Looking for bug: https://bugs.launchpad.net/bugs/%s" % x['bug']
|
self.log.debug("Looking for bug: https://bugs.launchpad.net/bugs/%s" % x['bug'])
|
||||||
query = self._apply_template(self.targeted_template, (x['query'],
|
query = self._apply_template(self.targeted_template, (x['query'],
|
||||||
change_number, patch_number))
|
change_number, patch_number))
|
||||||
results = self.es.search(query, size='10')
|
results = self.es.search(query, size='10')
|
||||||
@ -201,7 +202,7 @@ class Classifier():
|
|||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
classifier = Classifier()
|
|
||||||
#classifier.test()
|
#classifier.test()
|
||||||
config = ConfigParser.ConfigParser()
|
config = ConfigParser.ConfigParser()
|
||||||
if len(sys.argv) is 2:
|
if len(sys.argv) is 2:
|
||||||
@ -210,6 +211,8 @@ def main():
|
|||||||
config_path = 'elasticRecheck.conf'
|
config_path = 'elasticRecheck.conf'
|
||||||
config.read(config_path)
|
config.read(config_path)
|
||||||
user = config.get('gerrit', 'user', 'jogo')
|
user = config.get('gerrit', 'user', 'jogo')
|
||||||
|
queries = config.get('gerrit', 'query_file', 'queries.json')
|
||||||
|
classifier = Classifier(queries)
|
||||||
stream = Stream(user)
|
stream = Stream(user)
|
||||||
while True:
|
while True:
|
||||||
event = stream.get_failed_tempest()
|
event = stream.get_failed_tempest()
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
openstack-recheck-watch-test:
|
openstack-qa:
|
||||||
events:
|
events:
|
||||||
- positive
|
- positive
|
||||||
- negative
|
- negative
|
||||||
|
Loading…
Reference in New Issue
Block a user