diff options
Diffstat (limited to 'nixops/modules/buildbot/common')
-rw-r--r-- | nixops/modules/buildbot/common/build_helpers.py | 69 |
1 files changed, 67 insertions, 2 deletions
diff --git a/nixops/modules/buildbot/common/build_helpers.py b/nixops/modules/buildbot/common/build_helpers.py index f51de54..63733e7 100644 --- a/nixops/modules/buildbot/common/build_helpers.py +++ b/nixops/modules/buildbot/common/build_helpers.py | |||
@@ -3,7 +3,8 @@ from buildbot_buildslist import BuildsList | |||
3 | 3 | ||
4 | __all__ = [ | 4 | __all__ = [ |
5 | "force_scheduler", "deploy_scheduler", "hook_scheduler", | 5 | "force_scheduler", "deploy_scheduler", "hook_scheduler", |
6 | "clean_branch", "package_and_upload", "SlackStatusPush" | 6 | "clean_branch", "package_and_upload", "SlackStatusPush", |
7 | "XMPPStatusPush" | ||
7 | ] | 8 | ] |
8 | 9 | ||
9 | # Small helpers" | 10 | # Small helpers" |
@@ -71,13 +72,16 @@ def hook_scheduler(project, timer=10): | |||
71 | change_filter=util.ChangeFilter(category="hooks", project=project), | 72 | change_filter=util.ChangeFilter(category="hooks", project=project), |
72 | name=project, treeStableTimer=timer, builderNames=["{}_build".format(project)]) | 73 | name=project, treeStableTimer=timer, builderNames=["{}_build".format(project)]) |
73 | 74 | ||
74 | # Slack status push | 75 | # Slack/XMPP status push |
75 | from buildbot.reporters.http import HttpStatusPushBase | 76 | from buildbot.reporters.http import HttpStatusPushBase |
76 | from twisted.internet import defer | 77 | from twisted.internet import defer |
77 | from twisted.python import log | 78 | from twisted.python import log |
78 | from buildbot.util import httpclientservice | 79 | from buildbot.util import httpclientservice |
79 | from buildbot.reporters import utils | 80 | from buildbot.reporters import utils |
80 | from buildbot.process import results | 81 | from buildbot.process import results |
82 | from twisted.words.protocols.jabber.jid import JID | ||
83 | from wokkel import client, xmppim | ||
84 | |||
81 | 85 | ||
82 | class SlackStatusPush(HttpStatusPushBase): | 86 | class SlackStatusPush(HttpStatusPushBase): |
83 | name = "SlackStatusPush" | 87 | name = "SlackStatusPush" |
@@ -188,5 +192,66 @@ class SlackStatusPush(HttpStatusPushBase): | |||
188 | "attachments": attachments, | 192 | "attachments": attachments, |
189 | } | 193 | } |
190 | 194 | ||
195 | class XMPPStatusPush(HttpStatusPushBase): | ||
196 | name = "XMPPStatusPush" | ||
197 | |||
198 | @defer.inlineCallbacks | ||
199 | def reconfigService(self, password, recipients, **kwargs): | ||
200 | yield HttpStatusPushBase.reconfigService(self, **kwargs) | ||
201 | self.password = password | ||
202 | self.recipients = recipients | ||
203 | |||
204 | @defer.inlineCallbacks | ||
205 | def send(self, build): | ||
206 | yield utils.getDetailsForBuild(self.master, build, wantProperties=True) | ||
207 | body = self.format(build) | ||
208 | factory = client.DeferredClientFactory(JID("notify_bot@immae.fr/buildbot"), self.password) | ||
209 | factory.streamManager.logTraffic = True | ||
210 | d = client.clientCreator(factory) | ||
211 | def send_message(stream): | ||
212 | message = xmppim.Message(recipient=JID(recipient), body=body) | ||
213 | message.stanzaType = 'chat' | ||
214 | stream.send(message.toElement()) | ||
215 | # To allow chaining | ||
216 | return stream | ||
217 | for recipient in self.recipients: | ||
218 | d.addCallback(send_message) | ||
219 | d.addCallback(lambda _: factory.streamManager.xmlstream.sendFooter()) | ||
220 | d.addErrback(log.err) | ||
221 | |||
222 | def format(self, build): | ||
223 | if "environment" in build["properties"]: | ||
224 | msg = "{} environment".format(build["properties"]["environment"][0]) | ||
225 | if "build" in build["properties"]: | ||
226 | msg = "of archive {} in ".format(build["properties"]["build"][0]) + msg | ||
227 | elif len(build["buildset"]["sourcestamps"][0]["branch"]) > 0: | ||
228 | msg = "revision {}".format(build["buildset"]["sourcestamps"][0]["branch"]) | ||
229 | else: | ||
230 | msg = "build" | ||
231 | |||
232 | if build["complete"]: | ||
233 | timedelta = int((build["complete_at"] - build["started_at"]).total_seconds()) | ||
234 | hours, rest = divmod(timedelta, 3600) | ||
235 | minutes, seconds = divmod(rest, 60) | ||
236 | if hours > 0: | ||
237 | duration = "{}h {}min {}s".format(hours, minutes, seconds) | ||
238 | elif minutes > 0: | ||
239 | duration = "{}min {}s".format(minutes, seconds) | ||
240 | else: | ||
241 | duration = "{}s".format(seconds) | ||
191 | 242 | ||
243 | text = "Build {} ( {} ) of {}'s {} was {} in {}.".format( | ||
244 | build["buildid"], build["url"], | ||
245 | build["builder"]["name"], | ||
246 | msg, | ||
247 | results.Results[build["results"]], | ||
248 | duration, | ||
249 | ) | ||
250 | else: | ||
251 | text = "Build {} ( {} ) of {}'s {} started.".format( | ||
252 | build["buildid"], build["url"], | ||
253 | build["builder"]["name"], | ||
254 | msg, | ||
255 | ) | ||
192 | 256 | ||
257 | return text | ||