Merge lp:~hatch/juju-gui/inspector-relation-status into lp:juju-gui/experimental
- inspector-relation-status
- Merge into trunk
Status: | Merged |
---|---|
Merged at revision: | 1212 |
Proposed branch: | lp:~hatch/juju-gui/inspector-relation-status |
Merge into: | lp:juju-gui/experimental |
Diff against target: |
306 lines (+82/-88) 8 files modified
app/models/models.js (+31/-22) app/templates/service-relations-list.handlebars (+1/-1) app/templates/service-relations-viewlet.handlebars (+1/-1) app/templates/service-relations.handlebars (+0/-40) app/views/utils.js (+6/-0) app/views/viewlets/service-relations.js (+3/-7) lib/views/juju-inspector.less (+11/-0) test/test_model.js (+29/-17) |
To merge this branch: | bzr merge lp:~hatch/juju-gui/inspector-relation-status |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Juju GUI Hackers | Pending | ||
Review via email: mp+196770@code.launchpad.net |
Commit message
Description of the change
Adds relation status to inspector relation panel
The overall relation status is now indicated on the inspector relation
panel using the same icons as the unit status. If any unit has a relation
error the entire relation is shown as in error.
Jeff Pihach (hatch) wrote : | # |
Jeff Pihach (hatch) wrote : | # |
reviewer notes
https:/
File app/templates/
https:/
app/templates/
Template from old inspector
Jeff Pihach (hatch) wrote : | # |
Please take a look.
- 1214. By Jeff Pihach
-
fixed issue where the first error status delta would get ignored for relation errors
Jeff Pihach (hatch) wrote : | # |
reviewer notes v2
https:/
File app/models/
https:/
app/models/
Fix for bug from first rev (see test_model)
https:/
File test/test_model.js (right):
https:/
test/test_
The order of these is important to make sure that the first unit error,
if it's a relation error gets caught properly (bug from first rev)
Gary Poster (gary) wrote : | # |
LGTM with trivials and sandbox QA good. waiting on QA on ec2.
https:/
File app/models/
https:/
app/models/
and relation errors
Thank you for improving names and docs. Nice.
https:/
app/models/
this code fixes peer relation issues?
https:/
File test/test_model.js (right):
https:/
test/test_
On 2013/11/26 20:42:45, jeff.pihach wrote:
> The order of these is important to make sure that the first unit
error, if it's
> a relation error gets caught properly (bug from first rev)
In that case could you elaborate in a code comment what's going on? All
I see in the code is "one of these has a relation error and one has an
install error," not something subtle about ordering.
Gary Poster (gary) wrote : | # |
QA OK on real environment also. Thanks! These are really cool changes
you are making.
Jeff Pihach (hatch) wrote : | # |
Thanks for the review! Changes landing
https:/
File test/test_model.js (right):
https:/
test/test_
good call, done
Jeff Pihach (hatch) wrote : | # |
*** Submitted:
Adds relation status to inspector relation panel
The overall relation status is now indicated on the inspector relation
panel using the same icons as the unit status. If any unit has a
relation
error the entire relation is shown as in error.
R=gary.poster
CC=
https:/
Preview Diff
1 | === modified file 'app/models/models.js' |
2 | --- app/models/models.js 2013-11-21 23:21:49 +0000 |
3 | +++ app/models/models.js 2013-11-26 20:42:30 +0000 |
4 | @@ -186,7 +186,7 @@ |
5 | this._events.push( |
6 | this.get('relations').on( |
7 | ['*:change', '*:add', '*:remove'], function(e) { |
8 | - this.set('aggregateRelations', e); |
9 | + this.set('relationChangeTrigger', e); |
10 | }, this)); |
11 | }, |
12 | |
13 | @@ -340,14 +340,16 @@ |
14 | relations: {}, |
15 | |
16 | /** |
17 | - An aggregate of the relations statuses that we use to trigger |
18 | - databinding changes |
19 | + When there is a change to the relation or to any units in the relation |
20 | + this value is changed to trigger changes in the inspector. |
21 | |
22 | - @attribute aggregateRelations |
23 | + @attribute relationChangeTrigger |
24 | @default {} |
25 | @type {Object} |
26 | */ |
27 | - aggregateRelations: {}, |
28 | + relationChangeTrigger: { |
29 | + value: {} |
30 | + }, |
31 | |
32 | /** |
33 | An aggregate of the relation errors that we use to trigger |
34 | @@ -580,11 +582,14 @@ |
35 | return result; |
36 | }, |
37 | |
38 | - /* |
39 | - * Return information about the state of the set of units for a |
40 | - * given service in the form of a map of agent states: |
41 | - * state => number of units in that state |
42 | - */ |
43 | + /** |
44 | + Returns information about the state of the set of units for a given |
45 | + service in the form of a map of agent states. |
46 | + |
47 | + @method get_informative_states_for_service |
48 | + @param {Object} service The service model. |
49 | + @return {Array} An array of the aggregate map and relation errors |
50 | + */ |
51 | get_informative_states_for_service: function(service) { |
52 | var aggregate_map = {}, |
53 | relationError = {}, |
54 | @@ -596,22 +601,24 @@ |
55 | aggregate_map[state] = 1; |
56 | } else { |
57 | aggregate_map[state] += 1; |
58 | - if (state === 'error') { |
59 | - // If in error status then we need to parse out why it's in error. |
60 | - var info = unit.agent_state_info; |
61 | - if (info !== undefined && info.indexOf('failed') > -1) { |
62 | - // If we parse more than the relation info then split this out |
63 | - if (info.indexOf('relation') > -1) { |
64 | - var hook = info.split(':')[1].split('-'), |
65 | - interfaceName = hook.slice(0, hook.length - 2)[0].trim(); |
66 | - relationError[unit.service] = interfaceName; |
67 | + } |
68 | + if (state === 'error') { |
69 | + // If in error status then we need to parse out why it's in error. |
70 | + var info = unit.agent_state_info; |
71 | + if (info !== undefined && info.indexOf('failed') > -1) { |
72 | + // If we parse more than the relation info then split this out |
73 | + if (info.indexOf('relation') > -1) { |
74 | + var stateData = unit.agent_state_data; |
75 | + if (stateData) { |
76 | + var farService = stateData['remote-unit'].split('/')[0]; |
77 | + if (farService) { |
78 | + relationError[farService] = stateData.hook; |
79 | + } |
80 | } |
81 | } |
82 | } |
83 | } |
84 | - |
85 | }); |
86 | - |
87 | return [aggregate_map, relationError]; |
88 | }, |
89 | |
90 | @@ -626,7 +633,9 @@ |
91 | var previous_unit_count = service.get('unit_count'); |
92 | service.set('unit_count', sum); |
93 | service.set('aggregated_status', aggregate[0]); |
94 | - service.set('aggregateRelationError', aggregate[1]); |
95 | + |
96 | + service.set('relationChangeTrigger', { error: aggregate[1] }); |
97 | + |
98 | // Set Google Analytics tracking event. |
99 | if (previous_unit_count !== sum && window._gaq) { |
100 | window._gaq.push(['_trackEvent', 'Service Stats', 'Update', |
101 | |
102 | === modified file 'app/templates/service-relations-list.handlebars' |
103 | --- app/templates/service-relations-list.handlebars 2013-09-19 20:11:53 +0000 |
104 | +++ app/templates/service-relations-list.handlebars 2013-11-26 20:42:30 +0000 |
105 | @@ -4,7 +4,7 @@ |
106 | </div> |
107 | {{/unless}} |
108 | {{#relations}} |
109 | - <h3>{{far.service}}</h3> |
110 | + <div class="relation-label {{relationStatus far.service ../errors}}"><h3>{{far.service}}</h3></div> |
111 | <h4>Interface: {{interface}}</h4> |
112 | <h4>Name: {{near.name}}</h4> |
113 | <h4>Role: {{near.role}}</h4> |
114 | |
115 | === modified file 'app/templates/service-relations-viewlet.handlebars' |
116 | --- app/templates/service-relations-viewlet.handlebars 2013-09-16 20:09:02 +0000 |
117 | +++ app/templates/service-relations-viewlet.handlebars 2013-11-26 20:42:30 +0000 |
118 | @@ -1,4 +1,4 @@ |
119 | <div class="view-container settings-config"> |
120 | <h2>Relations</h2> |
121 | - <div data-bind="aggregateRelations"></div> |
122 | + <div data-bind="relationChangeTrigger"></div> |
123 | </div> |
124 | |
125 | === removed file 'app/templates/service-relations.handlebars' |
126 | --- app/templates/service-relations.handlebars 2013-04-11 16:16:12 +0000 |
127 | +++ app/templates/service-relations.handlebars 1970-01-01 00:00:00 +0000 |
128 | @@ -1,40 +0,0 @@ |
129 | -{{> service-header}} |
130 | -<div class="view-container"> |
131 | - <div> |
132 | - <h5>Service Relations</h5> |
133 | - <form id="service-relations"> |
134 | - <table class="table table-striped table-bordered"> |
135 | - <thead> |
136 | - <tr> |
137 | - <th>Id</th> |
138 | - <th>Role</th> |
139 | - <th>Remote</th> |
140 | - <th>Scope</th> |
141 | - </thead> |
142 | - |
143 | - <tbody> |
144 | - {{#relations}} |
145 | - <tr {{#if highlight}}class="highlighted"{{/if}}> |
146 | - <td> |
147 | - {{ident}} |
148 | - <button type="submit" class="btn" id="{{elementId}}" value="{{relation_id}}"> |
149 | - Remove |
150 | - </button> |
151 | - </td> |
152 | - <td>{{near.role}}</td> |
153 | - <td> |
154 | - {{#if far}} |
155 | - <a href="{{../../serviceRemoteUri}}{{far.service}}/">{{far.service}}</a> |
156 | - {{/if}} |
157 | - </td> |
158 | - <td>{{scope}}</td> |
159 | - </tr> |
160 | - {{/relations}} |
161 | - </tbody> |
162 | - </table> |
163 | - </form> |
164 | - </div> |
165 | -</div> |
166 | -<div id="remove-modal-panel"></div> |
167 | -{{> service-footer}} |
168 | - |
169 | |
170 | === modified file 'app/views/utils.js' |
171 | --- app/views/utils.js 2013-11-21 22:42:48 +0000 |
172 | +++ app/views/utils.js 2013-11-26 20:42:30 +0000 |
173 | @@ -1686,6 +1686,12 @@ |
174 | /*jshint debug:false */ |
175 | }); |
176 | |
177 | + Y.Handlebars.registerHelper('relationStatus', function(value, errors) { |
178 | + if (errors[value]) { |
179 | + return 'error'; |
180 | + } |
181 | + }); |
182 | + |
183 | /* |
184 | * Extension for views to provide an apiFailure method. |
185 | * |
186 | |
187 | === modified file 'app/views/viewlets/service-relations.js' |
188 | --- app/views/viewlets/service-relations.js 2013-09-10 14:53:01 +0000 |
189 | +++ app/views/viewlets/service-relations.js 2013-11-26 20:42:30 +0000 |
190 | @@ -33,20 +33,16 @@ |
191 | template: templates['service-relations-viewlet'], |
192 | |
193 | bindings: { |
194 | - aggregateRelations: { |
195 | + relationChangeTrigger: { |
196 | 'update': function(node, value) { |
197 | var db = this.viewlet.options.db; |
198 | var service = this.viewlet.model; |
199 | var relations = utils.getRelationDataForService(db, service); |
200 | node.setHTML(templates['service-relations-list']({ |
201 | - relations: relations |
202 | + relations: relations, |
203 | + errors: value && value.error |
204 | })); |
205 | } |
206 | - }, |
207 | - aggregateRelationError: { |
208 | - 'update': function(node, value) { |
209 | - // Aggregate the unit statuses here to display the relation status |
210 | - } |
211 | } |
212 | } |
213 | }; |
214 | |
215 | === modified file 'lib/views/juju-inspector.less' |
216 | --- lib/views/juju-inspector.less 2013-11-25 21:18:53 +0000 |
217 | +++ lib/views/juju-inspector.less 2013-11-26 20:42:30 +0000 |
218 | @@ -776,6 +776,17 @@ |
219 | .transition(none); |
220 | } |
221 | } |
222 | + |
223 | + .relation-label { |
224 | + padding-left: 10px; |
225 | + background-repeat: no-repeat; |
226 | + background-position: 10px 17px; |
227 | + background-image: url("/juju-ui/assets/images/inspector-charm-running.png"); |
228 | + |
229 | + &.error { |
230 | + background-image: url("/juju-ui/assets/images/inspector-charm-error.png"); |
231 | + } |
232 | + } |
233 | } |
234 | .status { |
235 | display: inline-block; |
236 | |
237 | === modified file 'test/test_model.js' |
238 | --- test/test_model.js 2013-11-05 18:10:05 +0000 |
239 | +++ test/test_model.js 2013-11-26 20:42:30 +0000 |
240 | @@ -133,16 +133,26 @@ |
241 | id: 'wordpress/0', |
242 | agent_state: 'pending'}); |
243 | var wp1 = new models.ServiceUnit({ |
244 | + id: 'wordpress/2', |
245 | + agent_state: 'error', |
246 | + agent_state_info: 'hook failed: "db-relation-changed"', |
247 | + agent_state_data: { |
248 | + hook: 'db-relation-changed', |
249 | + 'relation-id': 1, |
250 | + 'remote-unit': 'mysql/0' |
251 | + }}); |
252 | + var wp2 = new models.ServiceUnit({ |
253 | id: 'wordpress/1', |
254 | - agent_state: 'error'}); |
255 | - wordpress.get('units').add([wp0, wp1]); |
256 | + agent_state: 'error', |
257 | + agent_state_info: 'hook failed: "install"'}); |
258 | + wordpress.get('units').add([wp0, wp1, wp2]); |
259 | |
260 | assert.deepEqual(mysql.get('units') |
261 | .get_informative_states_for_service(mysql), |
262 | [{'pending': 2}, {}]); |
263 | assert.deepEqual(wordpress.get('units') |
264 | .get_informative_states_for_service(wordpress), |
265 | - [{'pending': 1, 'error': 1}, {}]); |
266 | + [{'pending': 1, 'error': 2}, { mysql: 'db-relation-changed'}]); |
267 | }); |
268 | |
269 | it('service unit list should update analytics when units are added', |
270 | @@ -178,20 +188,22 @@ |
271 | models.RelationList, true); |
272 | }); |
273 | |
274 | - it('relation changes on service update aggregateRelations', function(done) { |
275 | - var service = new models.Service(); |
276 | - var relations = service.get('relations'); |
277 | - var handler = relations.on( |
278 | - '*:add', function() { |
279 | - // This means that it will update the aggregate |
280 | - // relations for databinding |
281 | - handler.detach(); |
282 | - var isObject = yui.Lang.isObject; |
283 | - assert.equal(isObject(service.get('aggregateRelations')), true); |
284 | - done(); |
285 | - }); |
286 | - relations.add(new models.Relation()); |
287 | - }); |
288 | + it('relation changes on service update relationChangeTrigger', |
289 | + function(done) { |
290 | + var service = new models.Service(); |
291 | + var relations = service.get('relations'); |
292 | + var handler = relations.on( |
293 | + '*:add', function() { |
294 | + // This means that it will update the aggregate |
295 | + // relations for databinding |
296 | + handler.detach(); |
297 | + var isObject = yui.Lang.isObject; |
298 | + assert.equal( |
299 | + isObject(service.get('relationChangeTrigger')), true); |
300 | + done(); |
301 | + }); |
302 | + relations.add(new models.Relation()); |
303 | + }); |
304 | |
305 | it('service unit objects should parse the service name from unit id', |
306 | function() { |
Reviewers: mp+196770_ code.launchpad. net,
Message:
Please take a look.
Description:
Adds relation status to inspector relation panel
The overall relation status is now indicated on the inspector relation
panel using the same icons as the unit status. If any unit has a
relation
error the entire relation is shown as in error.
To QA:
Sandbox:
Deploy Mysql & Wordpress with 50 units each
Relate them
See the inspector relations panel, there should be a green icon
Wait for a relation error
See the inspector relations panel, there should be a red icon
Reduce the units on your inspector to 1
See the inspector relations panel, there should be a green icon
because it's very likely the unit in error is gone
LXC
Deploy two instances of failtester
set ones relation fail setting to true
relate them
the inspector relations panel should show an error
resolve the error
the inspector relations panel should show green
https:/ /code.launchpad .net/~hatch/ juju-gui/ inspector- relation- status/ +merge/ 196770
(do not edit description out of merge proposal)
Please review this at https:/ /codereview. appspot. com/33130043/
Affected files (+77, -82 lines): models. js service- relations- list.handlebars service- relations- viewlet. handlebars service- relations. handlebars viewlets/ service- relations. js juju-inspector. less
A [revision details]
M app/models/
M app/templates/
M app/templates/
D app/templates/
M app/views/utils.js
M app/views/
M lib/views/
M test/test_model.js