build_status_server 0.8 → 0.9
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +2 -1
- data/Gemfile.lock +5 -1
- data/build_status_server.gemspec +1 -1
- data/config/config-example.yml +1 -0
- data/lib/build_status_server.html +118 -0
- data/lib/build_status_server/config.html +157 -0
- data/lib/build_status_server/config.rb +4 -0
- data/lib/build_status_server/server.html +202 -0
- data/lib/build_status_server/server.rb +52 -53
- data/lib/build_status_server/version.html +32 -0
- data/lib/build_status_server/version.rb +1 -1
- data/spec/lib/build_status_server/config_spec.rb +7 -7
- data/spec/lib/build_status_server/server_spec.rb +288 -11
- metadata +8 -7
- data/lib/build_status_server.rb~ +0 -10
- data/lib/build_status_server/server.rb~ +0 -162
- data/lib/build_status_server/version.rb~ +0 -3
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,12 +1,15 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
build_status_server (0.
|
4
|
+
build_status_server (0.8)
|
5
5
|
json
|
6
6
|
|
7
7
|
GEM
|
8
8
|
remote: http://rubygems.org/
|
9
9
|
specs:
|
10
|
+
builder (3.0.0)
|
11
|
+
ci_reporter (1.7.0)
|
12
|
+
builder (>= 2.1.2)
|
10
13
|
columnize (0.3.6)
|
11
14
|
diff-lcs (1.1.3)
|
12
15
|
json (1.6.5)
|
@@ -41,6 +44,7 @@ PLATFORMS
|
|
41
44
|
|
42
45
|
DEPENDENCIES
|
43
46
|
build_status_server!
|
47
|
+
ci_reporter
|
44
48
|
json
|
45
49
|
rake
|
46
50
|
rspec
|
data/build_status_server.gemspec
CHANGED
@@ -19,7 +19,7 @@ Notification Plugin)) and an Arduino powered Traffic Light controller
|
|
19
19
|
EOS
|
20
20
|
s.description = "A build notifier server for Jenkins CI that controls an XFD over HTTP"
|
21
21
|
|
22
|
-
s.files = Dir["{lib/**/*,spec
|
22
|
+
s.files = Dir["{lib/**/*,spec/**/*.rb,spec/support/*}"] + %w(
|
23
23
|
Gemfile
|
24
24
|
Gemfile.lock
|
25
25
|
LICENSE
|
data/config/config-example.yml
CHANGED
@@ -0,0 +1,118 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta http-equiv="content-type" content="text/html;charset=utf-8">
|
5
|
+
<title>build_status_server.rb</title>
|
6
|
+
<link rel="stylesheet" href="http://jashkenas.github.com/docco/resources/docco.css">
|
7
|
+
</head>
|
8
|
+
<body>
|
9
|
+
<div id='container'>
|
10
|
+
<div id="background"></div>
|
11
|
+
<div id="jump_to">
|
12
|
+
Jump To …
|
13
|
+
<div id="jump_wrapper">
|
14
|
+
<div id="jump_page">
|
15
|
+
<a class="source" href="build_status_server.html">build_status_server.rb</a>
|
16
|
+
<a class="source" href="build_status_server/config.html">config.rb</a>
|
17
|
+
<a class="source" href="build_status_server/server.html">server.rb</a>
|
18
|
+
<a class="source" href="build_status_server/version.html">version.rb</a>
|
19
|
+
</div>
|
20
|
+
</div>
|
21
|
+
</div>
|
22
|
+
<table cellspacing=0 cellpadding=0>
|
23
|
+
<thead>
|
24
|
+
<tr>
|
25
|
+
<th class=docs><h1>build_status_server.rb</h1></th>
|
26
|
+
<th class=code></th>
|
27
|
+
</tr>
|
28
|
+
</thead>
|
29
|
+
<tbody>
|
30
|
+
<tr id='section-Installation'>
|
31
|
+
<td class=docs>
|
32
|
+
<div class="pilwrap">
|
33
|
+
<a class="pilcrow" href="#section-Installation">¶</a>
|
34
|
+
</div>
|
35
|
+
<p><strong>Build Notifier</strong></p>
|
36
|
+
|
37
|
+
<p>This utility is part of an XFD (eXtreeme Feedback Device) solution designed and
|
38
|
+
built for my employer <a href="http://challengepost.com">ChallengePost</a>. It works in
|
39
|
+
conjunction with our <a href="http://jenkins-ci.org">Jenkins</a> Continuous Integration
|
40
|
+
server (and its
|
41
|
+
<a href="https://wiki.jenkins-ci.org/display/JENKINS/Notification+Plugin">Notification Plugin</a>)
|
42
|
+
and an <a href="http://arduino.cc">Arduino</a> powered
|
43
|
+
<a href="https://github.com/jcmuller/TrafficLightController">Traffic Light controller</a>
|
44
|
+
with a
|
45
|
+
pseudo-<a href="http://en.wikipedia.org/wiki/Representational_state_transfer">REST</a>ful
|
46
|
+
API.</p>
|
47
|
+
|
48
|
+
<p>To run, you need to create a <code>config.yml</code> file. The first time you run the
|
49
|
+
application without any arguments, you will get a sample.</p>
|
50
|
+
|
51
|
+
<h1>Installation</h1>
|
52
|
+
|
53
|
+
<p>$ gem install build<em>status</em>server</p>
|
54
|
+
|
55
|
+
<h1>Execution</h1>
|
56
|
+
|
57
|
+
<p>See the options you can pass in by:</p>
|
58
|
+
|
59
|
+
<p>$ build<em>status</em>server -h</p>
|
60
|
+
|
61
|
+
<h1>Configuration file</h1>
|
62
|
+
|
63
|
+
<h2>UDP Server</h2>
|
64
|
+
|
65
|
+
<p>This section defines what interface and port should the UDP server listen at.
|
66
|
+
The Jenkins' Notification Plugin should be set to this parameters as well.</p>
|
67
|
+
|
68
|
+
<h2>TCP Client</h2>
|
69
|
+
|
70
|
+
<p>This section is where we tell the server how to communicate with the web
|
71
|
+
enabled XFD. In the example case, there is a web server running somewhere
|
72
|
+
listening on port 4567 that responds to <code>/green</code> and <code>/red</code>.</p>
|
73
|
+
|
74
|
+
<p>On our installation, this represents the Traffic Light's Arduino web server.</p>
|
75
|
+
|
76
|
+
<h2>Store</h2>
|
77
|
+
|
78
|
+
<p>Where the persistent state will be stored.</p>
|
79
|
+
|
80
|
+
<h2>Mask (optional)</h2>
|
81
|
+
|
82
|
+
<p>You can decide to either include or ignore certain builds whose names match a
|
83
|
+
given <a href="http://en.wikipedia.org/wiki/Regular_expression">Regular Expression</a>.</p>
|
84
|
+
|
85
|
+
<h2>Verbose</h2>
|
86
|
+
|
87
|
+
<p>Whether to display informative output messages.</p>
|
88
|
+
|
89
|
+
<h1>Development</h1>
|
90
|
+
|
91
|
+
<p><code>bin/build_status_server_traffic_light_mock</code> is provided for development
|
92
|
+
purposes only.</p>
|
93
|
+
|
94
|
+
<h1>Finished product</h1>
|
95
|
+
|
96
|
+
<p><img src="http://i.imgur.com/aK5rs.jpg" alt="my image"></p>
|
97
|
+
|
98
|
+
<h1>Wiring the traffic light</h1>
|
99
|
+
|
100
|
+
<p><img src="http://i.imgur.com/gUpWe.jpg" alt="my image"></p>
|
101
|
+
|
102
|
+
</td>
|
103
|
+
<td class=code>
|
104
|
+
<div class='highlight'><pre><span class="nb">require</span> <span class="s2">"rubygems"</span>
|
105
|
+
<span class="nb">require</span> <span class="s2">"json"</span>
|
106
|
+
<span class="nb">require</span> <span class="s2">"socket"</span>
|
107
|
+
<span class="nb">require</span> <span class="s2">"timeout"</span>
|
108
|
+
<span class="nb">require</span> <span class="s2">"yaml"</span>
|
109
|
+
|
110
|
+
<span class="k">module</span> <span class="nn">BuildStatusServer</span>
|
111
|
+
<span class="nb">autoload</span> <span class="ss">:Config</span><span class="p">,</span> <span class="s1">'build_status_server/config'</span>
|
112
|
+
<span class="nb">autoload</span> <span class="ss">:Server</span><span class="p">,</span> <span class="s1">'build_status_server/server'</span>
|
113
|
+
<span class="k">end</span></pre></div>
|
114
|
+
</td>
|
115
|
+
</tr>
|
116
|
+
</table>
|
117
|
+
</div>
|
118
|
+
</body>
|
@@ -0,0 +1,157 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta http-equiv="content-type" content="text/html;charset=utf-8">
|
5
|
+
<title>config.rb</title>
|
6
|
+
<link rel="stylesheet" href="http://jashkenas.github.com/docco/resources/docco.css">
|
7
|
+
</head>
|
8
|
+
<body>
|
9
|
+
<div id='container'>
|
10
|
+
<div id="background"></div>
|
11
|
+
<div id="jump_to">
|
12
|
+
Jump To …
|
13
|
+
<div id="jump_wrapper">
|
14
|
+
<div id="jump_page">
|
15
|
+
<a class="source" href="../build_status_server.html">build_status_server.rb</a>
|
16
|
+
<a class="source" href="config.html">config.rb</a>
|
17
|
+
<a class="source" href="server.html">server.rb</a>
|
18
|
+
<a class="source" href="version.html">version.rb</a>
|
19
|
+
</div>
|
20
|
+
</div>
|
21
|
+
</div>
|
22
|
+
<table cellspacing=0 cellpadding=0>
|
23
|
+
<thead>
|
24
|
+
<tr>
|
25
|
+
<th class=docs><h1>config.rb</h1></th>
|
26
|
+
<th class=code></th>
|
27
|
+
</tr>
|
28
|
+
</thead>
|
29
|
+
<tbody>
|
30
|
+
<tr id='section-1'>
|
31
|
+
<td class=docs>
|
32
|
+
<div class="pilwrap">
|
33
|
+
<a class="pilcrow" href="#section-1">¶</a>
|
34
|
+
</div>
|
35
|
+
|
36
|
+
</td>
|
37
|
+
<td class=code>
|
38
|
+
<div class='highlight'><pre><span class="k">module</span> <span class="nn">BuildStatusServer</span>
|
39
|
+
<span class="k">class</span> <span class="nc">Config</span>
|
40
|
+
<span class="kp">attr_reader</span> <span class="ss">:config</span>
|
41
|
+
|
42
|
+
<span class="k">def</span> <span class="nf">initialize</span>
|
43
|
+
<span class="vi">@config</span> <span class="o">=</span> <span class="p">{}</span>
|
44
|
+
<span class="k">end</span></pre></div>
|
45
|
+
</td>
|
46
|
+
</tr>
|
47
|
+
<tr id='section-2'>
|
48
|
+
<td class=docs>
|
49
|
+
<div class="pilwrap">
|
50
|
+
<a class="pilcrow" href="#section-2">¶</a>
|
51
|
+
</div>
|
52
|
+
<p>This is responsible of loading the config object</p>
|
53
|
+
</td>
|
54
|
+
<td class=code>
|
55
|
+
<div class='highlight'><pre> <span class="k">def</span> <span class="nf">load</span><span class="p">(</span><span class="n">options</span> <span class="o">=</span> <span class="p">{})</span>
|
56
|
+
<span class="n">config</span> <span class="o">=</span> <span class="n">load_config_file</span><span class="p">(</span><span class="n">options</span><span class="o">[</span><span class="ss">:config</span><span class="o">]</span><span class="p">)</span>
|
57
|
+
<span class="n">import_config</span><span class="p">(</span><span class="n">config</span><span class="p">,</span> <span class="n">options</span><span class="p">)</span>
|
58
|
+
<span class="k">end</span>
|
59
|
+
|
60
|
+
<span class="k">def</span> <span class="nf">method_missing</span><span class="p">(</span><span class="n">meth</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">&</span><span class="n">block</span><span class="p">)</span>
|
61
|
+
<span class="k">return</span> <span class="n">config</span><span class="o">[</span><span class="n">meth</span><span class="o">.</span><span class="n">to_s</span><span class="o">]</span> <span class="k">if</span> <span class="n">config</span><span class="o">.</span><span class="n">has_key?</span><span class="p">(</span><span class="n">meth</span><span class="o">.</span><span class="n">to_s</span><span class="p">)</span>
|
62
|
+
<span class="k">super</span>
|
63
|
+
<span class="k">end</span>
|
64
|
+
|
65
|
+
<span class="k">def</span> <span class="nf">store_file</span>
|
66
|
+
<span class="k">return</span> <span class="no">File</span><span class="o">.</span><span class="n">expand_path</span><span class="p">(</span><span class="s2">"."</span><span class="p">,</span> <span class="n">store</span><span class="o">[</span><span class="s2">"filename"</span><span class="o">]</span><span class="p">)</span> <span class="k">if</span> <span class="n">store</span>
|
67
|
+
<span class="kp">nil</span>
|
68
|
+
<span class="k">end</span>
|
69
|
+
|
70
|
+
<span class="kp">private</span></pre></div>
|
71
|
+
</td>
|
72
|
+
</tr>
|
73
|
+
<tr id='section-3'>
|
74
|
+
<td class=docs>
|
75
|
+
<div class="pilwrap">
|
76
|
+
<a class="pilcrow" href="#section-3">¶</a>
|
77
|
+
</div>
|
78
|
+
<p>This will load the passed in config object into the config attribute</p>
|
79
|
+
</td>
|
80
|
+
<td class=code>
|
81
|
+
<div class='highlight'><pre> <span class="k">def</span> <span class="nf">import_config</span><span class="p">(</span><span class="n">config</span> <span class="o">=</span> <span class="p">{},</span> <span class="n">options</span> <span class="o">=</span> <span class="p">{})</span>
|
82
|
+
<span class="n">config</span><span class="o">[</span><span class="s2">"verbose"</span><span class="o">]</span> <span class="o">=</span> <span class="n">options</span><span class="o">[</span><span class="ss">:verbose</span><span class="o">]</span> <span class="k">unless</span> <span class="n">options</span><span class="o">[</span><span class="ss">:verbose</span><span class="o">].</span><span class="n">nil?</span>
|
83
|
+
<span class="vi">@config</span> <span class="o">=</span> <span class="n">config</span>
|
84
|
+
<span class="k">end</span></pre></div>
|
85
|
+
</td>
|
86
|
+
</tr>
|
87
|
+
<tr id='section-4'>
|
88
|
+
<td class=docs>
|
89
|
+
<div class="pilwrap">
|
90
|
+
<a class="pilcrow" href="#section-4">¶</a>
|
91
|
+
</div>
|
92
|
+
<p>This is responsible to return a hash with the contents of a YAML file</p>
|
93
|
+
|
94
|
+
</td>
|
95
|
+
<td class=code>
|
96
|
+
<div class='highlight'><pre> <span class="k">def</span> <span class="nf">load_config_file</span><span class="p">(</span><span class="n">config_file</span> <span class="o">=</span> <span class="kp">nil</span><span class="p">)</span>
|
97
|
+
<span class="n">curated_file</span> <span class="o">=</span> <span class="kp">nil</span>
|
98
|
+
|
99
|
+
<span class="k">if</span> <span class="n">config_file</span>
|
100
|
+
<span class="n">f</span> <span class="o">=</span> <span class="no">File</span><span class="o">.</span><span class="n">expand_path</span><span class="p">(</span><span class="n">config_file</span><span class="p">)</span>
|
101
|
+
<span class="k">if</span> <span class="no">File</span><span class="o">.</span><span class="n">exists?</span><span class="p">(</span><span class="n">f</span><span class="p">)</span>
|
102
|
+
<span class="n">curated_file</span> <span class="o">=</span> <span class="n">f</span>
|
103
|
+
<span class="k">else</span>
|
104
|
+
<span class="k">raise</span> <span class="s2">"Supplied config file (</span><span class="si">#{</span><span class="n">config_file</span><span class="si">}</span><span class="s2">) doesn't seem to exist"</span>
|
105
|
+
<span class="k">end</span>
|
106
|
+
<span class="k">else</span>
|
107
|
+
<span class="n">locations_to_try</span><span class="o">.</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">possible_conf_file</span><span class="o">|</span>
|
108
|
+
<span class="n">f</span> <span class="o">=</span> <span class="no">File</span><span class="o">.</span><span class="n">expand_path</span><span class="p">(</span><span class="n">possible_conf_file</span><span class="p">)</span>
|
109
|
+
<span class="k">if</span> <span class="no">File</span><span class="o">.</span><span class="n">exists?</span><span class="p">(</span><span class="n">f</span><span class="p">)</span>
|
110
|
+
<span class="n">curated_file</span> <span class="o">=</span> <span class="n">f</span>
|
111
|
+
<span class="k">break</span>
|
112
|
+
<span class="k">end</span>
|
113
|
+
<span class="k">end</span>
|
114
|
+
|
115
|
+
<span class="k">if</span> <span class="n">curated_file</span><span class="o">.</span><span class="n">nil?</span>
|
116
|
+
<span class="no">STDERR</span><span class="o">.</span><span class="n">puts</span> <span class="o"><<-</span><span class="no">EOT</span>
|
117
|
+
<span class="sh">Looks like there isn't an available configuration file for this program.</span>
|
118
|
+
<span class="sh">We're very diligently going to use some sensible defaults, but you're</span>
|
119
|
+
<span class="sh">strongly recommended to create one in any of the following locations:</span>
|
120
|
+
|
121
|
+
<span class="sh"> #{locations_to_try.join("\n ")}</span>
|
122
|
+
|
123
|
+
<span class="sh"> Here is a sample of the contents for that file (and the settings we're going</span>
|
124
|
+
<span class="sh"> to use):</span>
|
125
|
+
|
126
|
+
<span class="sh">#{get_example_config}</span>
|
127
|
+
<span class="no"> EOT</span>
|
128
|
+
|
129
|
+
<span class="k">return</span> <span class="no">YAML</span><span class="o">.</span><span class="n">load</span><span class="p">(</span><span class="n">get_example_config</span><span class="p">)</span>
|
130
|
+
<span class="k">end</span>
|
131
|
+
<span class="k">end</span>
|
132
|
+
|
133
|
+
<span class="no">YAML</span><span class="o">.</span><span class="n">load_file</span><span class="p">(</span><span class="n">curated_file</span><span class="p">)</span><span class="o">.</span><span class="n">tap</span> <span class="k">do</span> <span class="o">|</span><span class="n">config</span><span class="o">|</span>
|
134
|
+
<span class="k">raise</span> <span class="s2">"This is an invalid configuration file!"</span> <span class="k">unless</span> <span class="n">config</span><span class="o">.</span><span class="n">class</span> <span class="o">==</span> <span class="no">Hash</span>
|
135
|
+
<span class="k">end</span>
|
136
|
+
<span class="k">end</span>
|
137
|
+
|
138
|
+
<span class="k">def</span> <span class="nf">locations_to_try</span>
|
139
|
+
<span class="sx">%w(</span>
|
140
|
+
<span class="sx"> ~/.config/build_status_server/config.yml</span>
|
141
|
+
<span class="sx"> ./config/config.yml</span>
|
142
|
+
<span class="sx"> /etc/build_status_server/config.yml</span>
|
143
|
+
<span class="sx"> /usr/local/etc/build_status_server/config.yml</span>
|
144
|
+
<span class="sx"> )</span>
|
145
|
+
<span class="k">end</span>
|
146
|
+
|
147
|
+
<span class="k">def</span> <span class="nf">get_example_config</span>
|
148
|
+
<span class="n">filename</span> <span class="o">=</span> <span class="s2">"</span><span class="si">#{</span><span class="no">File</span><span class="o">.</span><span class="n">dirname</span><span class="p">(</span><span class="no">File</span><span class="o">.</span><span class="n">expand_path</span><span class="p">(</span><span class="bp">__FILE__</span><span class="p">))</span><span class="si">}</span><span class="s2">/../../config/config-example.yml"</span>
|
149
|
+
<span class="no">File</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="n">filename</span><span class="p">)</span><span class="o">.</span><span class="n">read</span>
|
150
|
+
<span class="k">end</span>
|
151
|
+
<span class="k">end</span>
|
152
|
+
<span class="k">end</span></pre></div>
|
153
|
+
</td>
|
154
|
+
</tr>
|
155
|
+
</table>
|
156
|
+
</div>
|
157
|
+
</body>
|
@@ -0,0 +1,202 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta http-equiv="content-type" content="text/html;charset=utf-8">
|
5
|
+
<title>server.rb</title>
|
6
|
+
<link rel="stylesheet" href="http://jashkenas.github.com/docco/resources/docco.css">
|
7
|
+
</head>
|
8
|
+
<body>
|
9
|
+
<div id='container'>
|
10
|
+
<div id="background"></div>
|
11
|
+
<div id="jump_to">
|
12
|
+
Jump To …
|
13
|
+
<div id="jump_wrapper">
|
14
|
+
<div id="jump_page">
|
15
|
+
<a class="source" href="../build_status_server.html">build_status_server.rb</a>
|
16
|
+
<a class="source" href="config.html">config.rb</a>
|
17
|
+
<a class="source" href="server.html">server.rb</a>
|
18
|
+
<a class="source" href="version.html">version.rb</a>
|
19
|
+
</div>
|
20
|
+
</div>
|
21
|
+
</div>
|
22
|
+
<table cellspacing=0 cellpadding=0>
|
23
|
+
<thead>
|
24
|
+
<tr>
|
25
|
+
<th class=docs><h1>server.rb</h1></th>
|
26
|
+
<th class=code></th>
|
27
|
+
</tr>
|
28
|
+
</thead>
|
29
|
+
<tbody>
|
30
|
+
<tr id='section-1'>
|
31
|
+
<td class=docs>
|
32
|
+
<div class="pilwrap">
|
33
|
+
<a class="pilcrow" href="#section-1">¶</a>
|
34
|
+
</div>
|
35
|
+
<p>TODO
|
36
|
+
move all configuration stuff to Config
|
37
|
+
and just call config[:blaj] instead of if blah</p>
|
38
|
+
|
39
|
+
</td>
|
40
|
+
<td class=code>
|
41
|
+
<div class='highlight'><pre><span class="k">module</span> <span class="nn">BuildStatusServer</span>
|
42
|
+
<span class="k">class</span> <span class="nc">Server</span>
|
43
|
+
<span class="kp">attr_reader</span> <span class="ss">:config</span><span class="p">,</span> <span class="ss">:store</span>
|
44
|
+
|
45
|
+
<span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="n">options</span> <span class="o">=</span> <span class="p">{})</span>
|
46
|
+
<span class="vi">@config</span> <span class="o">=</span> <span class="no">Config</span><span class="o">.</span><span class="n">new</span>
|
47
|
+
<span class="n">config</span><span class="o">.</span><span class="n">load</span><span class="p">(</span><span class="n">options</span><span class="p">)</span>
|
48
|
+
<span class="k">end</span>
|
49
|
+
|
50
|
+
<span class="k">def</span> <span class="nf">listen</span>
|
51
|
+
<span class="n">sock</span> <span class="o">=</span> <span class="no">UDPSocket</span><span class="o">.</span><span class="n">new</span>
|
52
|
+
<span class="n">udp_server</span> <span class="o">=</span> <span class="n">config</span><span class="o">.</span><span class="n">udp_server</span>
|
53
|
+
|
54
|
+
<span class="k">begin</span>
|
55
|
+
<span class="n">sock</span><span class="o">.</span><span class="n">bind</span><span class="p">(</span><span class="n">udp_server</span><span class="o">[</span><span class="s2">"address"</span><span class="o">]</span><span class="p">,</span> <span class="n">udp_server</span><span class="o">[</span><span class="s2">"port"</span><span class="o">]</span><span class="p">)</span>
|
56
|
+
<span class="k">rescue</span> <span class="no">Errno</span><span class="o">::</span><span class="no">EADDRINUSE</span>
|
57
|
+
<span class="no">STDERR</span><span class="o">.</span><span class="n">puts</span> <span class="o"><<-</span><span class="no">EOT</span>
|
58
|
+
<span class="sh">There appears that another instance is running, or another process</span>
|
59
|
+
<span class="sh">is listening at the same port (#{udp_server["address"]}:#{udp_server["port"]}</span>
|
60
|
+
|
61
|
+
<span class="no"> EOT</span>
|
62
|
+
<span class="nb">exit</span>
|
63
|
+
<span class="k">end</span>
|
64
|
+
|
65
|
+
<span class="nb">puts</span> <span class="s2">"Listening on UDP </span><span class="si">#{</span><span class="n">udp_server</span><span class="o">[</span><span class="s2">"address"</span><span class="o">]</span><span class="si">}</span><span class="s2">:</span><span class="si">#{</span><span class="n">udp_server</span><span class="o">[</span><span class="s2">"port"</span><span class="o">]</span><span class="si">}</span><span class="s2">"</span> <span class="k">if</span> <span class="n">config</span><span class="o">.</span><span class="n">verbose</span>
|
66
|
+
|
67
|
+
<span class="k">begin</span>
|
68
|
+
<span class="k">while</span> <span class="kp">true</span>
|
69
|
+
<span class="n">data</span><span class="p">,</span> <span class="n">addr</span> <span class="o">=</span> <span class="n">sock</span><span class="o">.</span><span class="n">recvfrom</span><span class="p">(</span><span class="mi">2048</span><span class="p">)</span>
|
70
|
+
|
71
|
+
<span class="k">if</span> <span class="n">process_job</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
|
72
|
+
<span class="n">status</span> <span class="o">=</span> <span class="n">process_all_statuses</span>
|
73
|
+
<span class="n">notify</span><span class="p">(</span><span class="n">status</span><span class="p">)</span>
|
74
|
+
<span class="k">end</span>
|
75
|
+
<span class="k">end</span>
|
76
|
+
<span class="k">rescue</span> <span class="no">Interrupt</span>
|
77
|
+
<span class="nb">puts</span> <span class="s2">"Good bye."</span>
|
78
|
+
<span class="n">sock</span><span class="o">.</span><span class="n">close</span>
|
79
|
+
<span class="nb">exit</span>
|
80
|
+
<span class="k">end</span>
|
81
|
+
<span class="k">end</span>
|
82
|
+
|
83
|
+
<span class="kp">private</span>
|
84
|
+
|
85
|
+
<span class="k">def</span> <span class="nf">load_store</span>
|
86
|
+
<span class="vi">@store</span> <span class="o">=</span> <span class="k">begin</span>
|
87
|
+
<span class="no">YAML</span><span class="o">.</span><span class="n">load_file</span><span class="p">(</span><span class="n">config</span><span class="o">.</span><span class="n">store_file</span><span class="p">)</span>
|
88
|
+
<span class="k">rescue</span>
|
89
|
+
<span class="p">{}</span>
|
90
|
+
<span class="k">end</span>
|
91
|
+
<span class="vi">@store</span> <span class="o">=</span> <span class="p">{}</span> <span class="k">unless</span> <span class="n">store</span><span class="o">.</span><span class="n">class</span> <span class="o">==</span> <span class="no">Hash</span>
|
92
|
+
<span class="k">end</span>
|
93
|
+
|
94
|
+
|
95
|
+
<span class="k">def</span> <span class="nf">process_job</span><span class="p">(</span><span class="n">data</span> <span class="o">=</span> <span class="s2">"{}"</span><span class="p">)</span>
|
96
|
+
<span class="n">job</span> <span class="o">=</span> <span class="no">JSON</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
|
97
|
+
|
98
|
+
<span class="n">build_name</span> <span class="o">=</span> <span class="n">job</span><span class="o">[</span><span class="s2">"name"</span><span class="o">]</span>
|
99
|
+
|
100
|
+
<span class="k">unless</span> <span class="n">should_process_build</span><span class="p">(</span><span class="n">build_name</span><span class="p">)</span>
|
101
|
+
<span class="no">STDOUT</span><span class="o">.</span><span class="n">puts</span> <span class="s2">"Ignoring </span><span class="si">#{</span><span class="n">build_name</span><span class="si">}</span><span class="s2"> (</span><span class="si">#{</span><span class="n">config</span><span class="o">.</span><span class="n">mask</span><span class="o">[</span><span class="s2">"regex"</span><span class="o">]</span><span class="si">}</span><span class="s2">--</span><span class="si">#{</span><span class="n">config</span><span class="o">.</span><span class="n">mask</span><span class="o">[</span><span class="s2">"policy"</span><span class="o">]</span><span class="si">}</span><span class="s2">)"</span> <span class="k">if</span> <span class="n">config</span><span class="o">.</span><span class="n">verbose</span>
|
102
|
+
<span class="k">return</span> <span class="kp">false</span>
|
103
|
+
<span class="k">end</span>
|
104
|
+
|
105
|
+
<span class="k">if</span> <span class="n">job</span><span class="o">.</span><span class="n">class</span> <span class="o">!=</span> <span class="no">Hash</span> <span class="ow">or</span>
|
106
|
+
<span class="n">job</span><span class="o">[</span><span class="s2">"build"</span><span class="o">].</span><span class="n">class</span> <span class="o">!=</span> <span class="no">Hash</span>
|
107
|
+
<span class="no">STDERR</span><span class="o">.</span><span class="n">puts</span> <span class="s2">"Pinged with an invalid payload"</span>
|
108
|
+
<span class="k">return</span> <span class="kp">false</span>
|
109
|
+
<span class="k">end</span>
|
110
|
+
|
111
|
+
<span class="n">phase</span> <span class="o">=</span> <span class="n">job</span><span class="o">[</span><span class="s2">"build"</span><span class="o">][</span><span class="s2">"phase"</span><span class="o">]</span>
|
112
|
+
<span class="n">status</span> <span class="o">=</span> <span class="n">job</span><span class="o">[</span><span class="s2">"build"</span><span class="o">][</span><span class="s2">"status"</span><span class="o">]</span>
|
113
|
+
|
114
|
+
<span class="k">if</span> <span class="n">phase</span> <span class="o">==</span> <span class="s2">"FINISHED"</span>
|
115
|
+
<span class="no">STDOUT</span><span class="o">.</span><span class="n">puts</span> <span class="s2">"Got </span><span class="si">#{</span><span class="n">status</span><span class="si">}</span><span class="s2"> for </span><span class="si">#{</span><span class="n">build_name</span><span class="si">}</span><span class="s2"> on </span><span class="si">#{</span><span class="no">Time</span><span class="o">.</span><span class="n">now</span><span class="si">}</span><span class="s2"> [</span><span class="si">#{</span><span class="n">job</span><span class="o">.</span><span class="n">inspect</span><span class="si">}</span><span class="s2">]"</span> <span class="k">if</span> <span class="n">config</span><span class="o">.</span><span class="n">verbose</span>
|
116
|
+
<span class="k">case</span> <span class="n">status</span>
|
117
|
+
<span class="k">when</span> <span class="s2">"SUCCESS"</span><span class="p">,</span> <span class="s2">"FAILURE"</span>
|
118
|
+
<span class="n">load_store</span>
|
119
|
+
<span class="n">store</span><span class="o">[</span><span class="n">build_name</span><span class="o">]</span> <span class="o">=</span> <span class="n">status</span>
|
120
|
+
<span class="no">File</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="n">config</span><span class="o">.</span><span class="n">store_file</span><span class="p">,</span> <span class="s2">"w"</span><span class="p">)</span> <span class="p">{</span> <span class="o">|</span><span class="n">file</span><span class="o">|</span> <span class="no">YAML</span><span class="o">.</span><span class="n">dump</span><span class="p">(</span><span class="n">store</span><span class="p">,</span> <span class="n">file</span><span class="p">)</span> <span class="p">}</span>
|
121
|
+
<span class="k">return</span> <span class="kp">true</span>
|
122
|
+
<span class="k">end</span>
|
123
|
+
<span class="k">else</span>
|
124
|
+
<span class="no">STDOUT</span><span class="o">.</span><span class="n">puts</span> <span class="s2">"Started for </span><span class="si">#{</span><span class="n">build_name</span><span class="si">}</span><span class="s2"> on </span><span class="si">#{</span><span class="no">Time</span><span class="o">.</span><span class="n">now</span><span class="si">}</span><span class="s2"> [</span><span class="si">#{</span><span class="n">job</span><span class="o">.</span><span class="n">inspect</span><span class="si">}</span><span class="s2">]"</span> <span class="k">if</span> <span class="n">config</span><span class="o">.</span><span class="n">verbose</span>
|
125
|
+
<span class="k">end</span>
|
126
|
+
|
127
|
+
<span class="k">return</span> <span class="kp">false</span>
|
128
|
+
<span class="k">end</span>
|
129
|
+
|
130
|
+
<span class="k">def</span> <span class="nf">should_process_build</span><span class="p">(</span><span class="n">build_name</span><span class="p">)</span>
|
131
|
+
<span class="c1"># If mask exists, then ...</span>
|
132
|
+
<span class="o">!</span> <span class="p">(</span>
|
133
|
+
<span class="o">!!</span><span class="n">config</span><span class="o">.</span><span class="n">mask</span> <span class="o">&&</span>
|
134
|
+
<span class="o">!!</span><span class="n">config</span><span class="o">.</span><span class="n">mask</span><span class="o">[</span><span class="s2">"regex"</span><span class="o">]</span> <span class="o">&&</span>
|
135
|
+
<span class="p">((</span><span class="n">config</span><span class="o">.</span><span class="n">mask</span><span class="o">[</span><span class="s2">"policy"</span><span class="o">]</span> <span class="o">==</span> <span class="s2">"include"</span> <span class="o">&&</span> <span class="n">build_name</span> <span class="o">!~</span> <span class="n">config</span><span class="o">.</span><span class="n">mask</span><span class="o">[</span><span class="s2">"regex"</span><span class="o">]</span><span class="p">)</span> <span class="o">||</span>
|
136
|
+
<span class="p">(</span><span class="n">config</span><span class="o">.</span><span class="n">mask</span><span class="o">[</span><span class="s2">"policy"</span><span class="o">]</span> <span class="o">!=</span> <span class="s2">"include"</span> <span class="o">&&</span> <span class="n">build_name</span> <span class="o">=~</span> <span class="n">config</span><span class="o">.</span><span class="n">mask</span><span class="o">[</span><span class="s2">"regex"</span><span class="o">]</span><span class="p">)</span>
|
137
|
+
<span class="p">))</span>
|
138
|
+
<span class="k">end</span>
|
139
|
+
|
140
|
+
<span class="k">def</span> <span class="nf">process_all_statuses</span>
|
141
|
+
<span class="n">pass</span> <span class="o">=</span> <span class="kp">true</span>
|
142
|
+
|
143
|
+
<span class="vi">@store</span><span class="o">.</span><span class="n">values</span><span class="o">.</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">val</span><span class="o">|</span>
|
144
|
+
<span class="n">pass</span> <span class="o">&&=</span> <span class="p">(</span><span class="n">val</span> <span class="o">==</span> <span class="s2">"pass"</span> <span class="o">||</span> <span class="n">val</span> <span class="o">==</span> <span class="s2">"SUCCESS"</span><span class="p">)</span>
|
145
|
+
<span class="k">end</span>
|
146
|
+
|
147
|
+
<span class="n">pass</span>
|
148
|
+
<span class="k">end</span>
|
149
|
+
|
150
|
+
<span class="k">def</span> <span class="nf">notify</span><span class="p">(</span><span class="n">status</span><span class="p">)</span>
|
151
|
+
<span class="n">tcp_client</span> <span class="o">=</span> <span class="n">config</span><span class="o">.</span><span class="n">tcp_client</span>
|
152
|
+
|
153
|
+
<span class="n">attempts</span> <span class="o">=</span> <span class="mi">0</span>
|
154
|
+
<span class="n">light</span> <span class="o">=</span> <span class="n">status</span> <span class="p">?</span> <span class="n">tcp_client</span><span class="o">[</span><span class="s2">"pass"</span><span class="o">]</span> <span class="p">:</span> <span class="n">tcp_client</span><span class="o">[</span><span class="s2">"fail"</span><span class="o">]</span>
|
155
|
+
|
156
|
+
<span class="k">begin</span>
|
157
|
+
<span class="n">timeout</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span> <span class="k">do</span>
|
158
|
+
<span class="n">attempts</span> <span class="o">+=</span> <span class="mi">1</span>
|
159
|
+
<span class="n">client</span> <span class="o">=</span> <span class="no">TCPSocket</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="n">tcp_client</span><span class="o">[</span><span class="s2">"host"</span><span class="o">]</span><span class="p">,</span> <span class="n">tcp_client</span><span class="o">[</span><span class="s2">"port"</span><span class="o">]</span><span class="p">)</span>
|
160
|
+
<span class="n">client</span><span class="o">.</span><span class="n">print</span> <span class="s2">"GET </span><span class="si">#{</span><span class="n">light</span><span class="si">}</span><span class="s2"> HTTP/1.0</span><span class="se">\n\n</span><span class="s2">"</span>
|
161
|
+
<span class="n">answer</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="n">gets</span><span class="p">(</span><span class="kp">nil</span><span class="p">)</span>
|
162
|
+
<span class="no">STDOUT</span><span class="o">.</span><span class="n">puts</span> <span class="n">answer</span> <span class="k">if</span> <span class="n">config</span><span class="o">.</span><span class="n">verbose</span>
|
163
|
+
<span class="n">client</span><span class="o">.</span><span class="n">close</span>
|
164
|
+
<span class="k">end</span>
|
165
|
+
<span class="k">rescue</span> <span class="no">Timeout</span><span class="o">::</span><span class="no">Error</span> <span class="o">=></span> <span class="n">ex</span>
|
166
|
+
<span class="no">STDERR</span><span class="o">.</span><span class="n">puts</span> <span class="s2">"Error: </span><span class="si">#{</span><span class="n">ex</span><span class="si">}</span><span class="s2"> while trying to send </span><span class="si">#{</span><span class="n">light</span><span class="si">}</span><span class="s2">"</span>
|
167
|
+
<span class="k">retry</span> <span class="k">unless</span> <span class="n">attempts</span> <span class="o">></span> <span class="mi">2</span>
|
168
|
+
<span class="k">rescue</span> <span class="no">Errno</span><span class="o">::</span><span class="no">ECONNREFUSED</span><span class="p">,</span> <span class="no">Errno</span><span class="o">::</span><span class="no">EHOSTUNREACH</span> <span class="o">=></span> <span class="n">ex</span>
|
169
|
+
<span class="no">STDERR</span><span class="o">.</span><span class="n">puts</span> <span class="s2">"Error: </span><span class="si">#{</span><span class="n">ex</span><span class="si">}</span><span class="s2"> while trying to send </span><span class="si">#{</span><span class="n">light</span><span class="si">}</span><span class="s2">"</span>
|
170
|
+
<span class="no">STDERR</span><span class="o">.</span><span class="n">puts</span> <span class="s2">"Will wait for 2 seconds and try again..."</span>
|
171
|
+
<span class="nb">sleep</span> <span class="mi">2</span>
|
172
|
+
<span class="k">retry</span> <span class="k">unless</span> <span class="n">attempts</span> <span class="o">></span> <span class="mi">2</span>
|
173
|
+
<span class="k">end</span>
|
174
|
+
<span class="k">end</span>
|
175
|
+
<span class="k">end</span>
|
176
|
+
<span class="k">end</span>
|
177
|
+
|
178
|
+
<span class="cp">__END__</span>
|
179
|
+
|
180
|
+
<span class="cp">Example payload:</span>
|
181
|
+
<span class="cp">{</span>
|
182
|
+
<span class="cp"> "name":"test",</span>
|
183
|
+
<span class="cp"> "url":"job/test/",</span>
|
184
|
+
<span class="cp"> "build":{</span>
|
185
|
+
<span class="cp"> "full_url":"http://cronus.local:3001/job/test/20/",</span>
|
186
|
+
<span class="cp"> "number":20,</span>
|
187
|
+
<span class="cp"> "phase":"FINISHED",</span>
|
188
|
+
<span class="cp"> "status":"SUCCESS",</span>
|
189
|
+
<span class="cp"> "url":"job/test/20/"</span>
|
190
|
+
<span class="cp"> }</span>
|
191
|
+
<span class="cp">}</span>
|
192
|
+
|
193
|
+
<span class="cp">We're getting this error once in a while:</span>
|
194
|
+
<span class="cp">/usr/local/lib/ruby/1.8/timeout.rb:64:in `notify': execution expired (Timeout::Error)</span>
|
195
|
+
<span class="cp"> from /home/jcmuller/build_notifier/lib/server.rb:102:in `notify'</span>
|
196
|
+
<span class="cp"> from /home/jcmuller/build_notifier/lib/server.rb:33:in `listen'</span>
|
197
|
+
<span class="cp"> from bin/server:5</span></pre></div>
|
198
|
+
</td>
|
199
|
+
</tr>
|
200
|
+
</table>
|
201
|
+
</div>
|
202
|
+
</body>
|