Get gerrit watching thread working as expected

This watcher addition can be tested standalone
by running.

$ python nerdreviewer/watcher.py \
  "review.openstack.org" "$USER"

Change-Id: I91142dd8d6be7649894320489c4ed3083723652a
This commit is contained in:
Joshua Harlow 2016-01-16 23:14:49 -08:00 committed by Joshua Harlow
parent b1ae45c46c
commit 1157e84e79
2 changed files with 85 additions and 0 deletions

83
nerdreviewer/watcher.py Normal file
View File

@ -0,0 +1,83 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import json
import logging
import select
import threading
import notifier
import paramiko
LOG = logging.getLogger(__name__)
class Watcher(threading.Thread):
GERRIT_ACTIVITY = "GERRIT_ACTIVITY"
def __init__(self, hostname, username, port=29418, keyfile=None):
super(Watcher, self).__init__()
self.dead = threading.Event()
self.notifier = notifier.Notifier()
self._keyfile = keyfile
self._hostname = hostname
self._username = username
self._port = port
self._client = None
def connect(self):
self._client = paramiko.SSHClient()
self._client.load_system_host_keys()
self._client.set_missing_host_key_policy(paramiko.WarningPolicy())
self._client.connect(self._hostname,
username=self._username,
port=self._port,
key_filename=self._keyfile)
def run(self):
client = self._client
if not client:
raise RuntimeError("Connect must be called before run")
_stdin, stdout, _stderr = client.exec_command("gerrit stream-events")
poll = select.poll()
poll.register(stdout.channel)
while not self.dead.is_set():
for (fd, event) in poll.poll(0.1):
if fd == stdout.channel.fileno():
if event == select.POLLIN:
event_data = {"event": json.loads(stdout.readline())}
self.notifier.notify(self.GERRIT_ACTIVITY, event_data)
else:
LOG.warn("Unknown event %s received on stdout"
" descriptor %s [%s]", event, stdout, fd)
if __name__ == "__main__":
import sys
import time
def on_event(event_type, details):
print("Received event %s with details %s" % (event_type, details))
logging.basicConfig(level=logging.DEBUG)
w = Watcher(sys.argv[1], sys.argv[2])
w.connect()
w.notifier.register(Watcher.GERRIT_ACTIVITY, on_event)
w.run()
try:
while True:
time.sleep(0.5)
except KeyboardInterrupt:
w.dead.set()
w.join()

View File

@ -3,8 +3,10 @@
# process, which may cause wedges in the gate later. # process, which may cause wedges in the gate later.
pbr>=1.6 # Apache-2.0 pbr>=1.6 # Apache-2.0
paramiko>=1.13.0 # LGPL
jsonschema>=2.0.0,<3.0.0,!=2.5.0 # MIT jsonschema>=2.0.0,<3.0.0,!=2.5.0 # MIT
netaddr>=0.7.12,!=0.7.16 # BSD netaddr>=0.7.12,!=0.7.16 # BSD
notifier>=1.0.3 # Apache-2.0
PyYAML>=3.1.0 PyYAML>=3.1.0
sphinx>=1.1.2,!=1.2.0,!=1.3b1,<1.3 # BSD sphinx>=1.1.2,!=1.2.0,!=1.3b1,<1.3 # BSD
six>=1.9.0 six>=1.9.0