Browse Source

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
Joshua Harlow 3 years ago
parent
commit
1157e84e79
2 changed files with 85 additions and 0 deletions
  1. 83
    0
      nerdreviewer/watcher.py
  2. 2
    0
      requirements.txt

+ 83
- 0
nerdreviewer/watcher.py View File

@@ -0,0 +1,83 @@
1
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
2
+#    not use this file except in compliance with the License. You may obtain
3
+#    a copy of the License at
4
+#
5
+#         http://www.apache.org/licenses/LICENSE-2.0
6
+#
7
+#    Unless required by applicable law or agreed to in writing, software
8
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10
+#    License for the specific language governing permissions and limitations
11
+#    under the License.
12
+
13
+import json
14
+import logging
15
+import select
16
+import threading
17
+
18
+import notifier
19
+import paramiko
20
+
21
+LOG = logging.getLogger(__name__)
22
+
23
+
24
+class Watcher(threading.Thread):
25
+
26
+    GERRIT_ACTIVITY = "GERRIT_ACTIVITY"
27
+
28
+    def __init__(self, hostname, username, port=29418, keyfile=None):
29
+        super(Watcher, self).__init__()
30
+        self.dead = threading.Event()
31
+        self.notifier = notifier.Notifier()
32
+        self._keyfile = keyfile
33
+        self._hostname = hostname
34
+        self._username = username
35
+        self._port = port
36
+        self._client = None
37
+
38
+    def connect(self):
39
+        self._client = paramiko.SSHClient()
40
+        self._client.load_system_host_keys()
41
+        self._client.set_missing_host_key_policy(paramiko.WarningPolicy())
42
+        self._client.connect(self._hostname,
43
+                             username=self._username,
44
+                             port=self._port,
45
+                             key_filename=self._keyfile)
46
+
47
+    def run(self):
48
+        client = self._client
49
+        if not client:
50
+            raise RuntimeError("Connect must be called before run")
51
+        _stdin, stdout, _stderr = client.exec_command("gerrit stream-events")
52
+        poll = select.poll()
53
+        poll.register(stdout.channel)
54
+        while not self.dead.is_set():
55
+            for (fd, event) in poll.poll(0.1):
56
+                if fd == stdout.channel.fileno():
57
+                    if event == select.POLLIN:
58
+                        event_data = {"event": json.loads(stdout.readline())}
59
+                        self.notifier.notify(self.GERRIT_ACTIVITY, event_data)
60
+                    else:
61
+                        LOG.warn("Unknown event %s received on stdout"
62
+                                 " descriptor %s [%s]", event, stdout, fd)
63
+
64
+
65
+if __name__ == "__main__":
66
+    import sys
67
+    import time
68
+
69
+    def on_event(event_type, details):
70
+        print("Received event %s with details %s" % (event_type, details))
71
+
72
+    logging.basicConfig(level=logging.DEBUG)
73
+    w = Watcher(sys.argv[1], sys.argv[2])
74
+    w.connect()
75
+    w.notifier.register(Watcher.GERRIT_ACTIVITY, on_event)
76
+    w.run()
77
+
78
+    try:
79
+        while True:
80
+            time.sleep(0.5)
81
+    except KeyboardInterrupt:
82
+        w.dead.set()
83
+        w.join()

+ 2
- 0
requirements.txt View File

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

Loading…
Cancel
Save