Left: | ||
Right: |
OLD | NEW |
---|---|
1 package main | 1 package main |
2 | 2 |
3 import ( | 3 import ( |
4 "encoding/json" | 4 "encoding/json" |
5 "fmt" | 5 "fmt" |
6 "launchpad.net/gnuflag" | 6 "launchpad.net/gnuflag" |
7 "launchpad.net/juju-core/charm" | 7 "launchpad.net/juju-core/charm" |
8 "launchpad.net/juju-core/cmd" | 8 "launchpad.net/juju-core/cmd" |
9 "launchpad.net/juju-core/environs" | 9 "launchpad.net/juju-core/environs" |
10 "launchpad.net/juju-core/juju" | 10 "launchpad.net/juju-core/juju" |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
127 | 127 |
128 func (ctxt *statusContext) processMachines() map[string]machineStatus { | 128 func (ctxt *statusContext) processMachines() map[string]machineStatus { |
129 machinesMap := make(map[string]machineStatus) | 129 machinesMap := make(map[string]machineStatus) |
130 for _, m := range ctxt.machines { | 130 for _, m := range ctxt.machines { |
131 machinesMap[m.Id()] = ctxt.processMachine(m) | 131 machinesMap[m.Id()] = ctxt.processMachine(m) |
132 } | 132 } |
133 return machinesMap | 133 return machinesMap |
134 } | 134 } |
135 | 135 |
136 func (ctxt *statusContext) processMachine(machine *state.Machine) (status machin eStatus) { | 136 func (ctxt *statusContext) processMachine(machine *state.Machine) (status machin eStatus) { |
137 status.Life, | |
dimitern
2013/04/18 12:34:34
did gofmt do that? it looks surprisingly ugly..
| |
138 status.AgentVersion, | |
139 status.AgentState, | |
140 status.AgentStateInfo, | |
fwereade
2013/04/18 12:37:09
I don't really feel this is a win over the out par
rog
2013/04/18 12:58:02
i think it wins *just*
better would be to have an
| |
141 status.Err = processAgent(machine) | |
137 instid, ok := machine.InstanceId() | 142 instid, ok := machine.InstanceId() |
138 » if !ok { | 143 » if ok { |
144 » » instance, ok := ctxt.instances[instid] | |
145 » » if ok { | |
146 » » » status.InstanceId = instance.Id() | |
fwereade
2013/04/18 12:37:09
Why don't we set the instance id in the other bran
rog
2013/04/18 12:58:02
Done.
| |
147 » » » status.DNSName, _ = instance.DNSName() | |
148 » » } else { | |
149 » » » // Double plus ungood. There is an instance id recorded | |
150 » » » // for this machine in the state, yet the environ cannot | |
151 » » » // find that id. | |
152 » » » status.InstanceState = "missing" | |
153 » » } | |
154 » } else { | |
139 status.InstanceId = "pending" | 155 status.InstanceId = "pending" |
140 » » return | 156 » » // There's no point in reporting a pending agent state |
157 » » // if the instance hasn't even started yet. This | |
fwereade
2013/04/18 12:37:09
There is no instance. "if no instance has been pro
rog
2013/04/18 12:58:02
Done.
| |
158 » » // also gives a visually distinction to unprovisioned machines | |
fwereade
2013/04/18 12:37:09
also makes unprovisioned machines visually distinc
rog
2013/04/18 12:58:02
Done.
| |
159 » » // in the status. | |
160 » » status.AgentState = "" | |
141 } | 161 } |
142 instance, ok := ctxt.instances[instid] | |
143 if !ok { | |
144 // Double plus ungood. There is an instance id recorded | |
145 // for this machine in the state, yet the environ cannot | |
146 // find that id. | |
147 status.InstanceState = "missing" | |
148 return | |
149 } | |
150 status.InstanceId = instance.Id() | |
151 status.DNSName, _ = instance.DNSName() | |
152 status.Err = processAgent(&status.AgentVersion, &status.AgentState, &sta tus.AgentStateInfo, machine) | |
153 return | 162 return |
154 } | 163 } |
155 | 164 |
156 func (ctxt *statusContext) processServices() map[string]serviceStatus { | 165 func (ctxt *statusContext) processServices() map[string]serviceStatus { |
157 servicesMap := make(map[string]serviceStatus) | 166 servicesMap := make(map[string]serviceStatus) |
158 for _, s := range ctxt.services { | 167 for _, s := range ctxt.services { |
159 servicesMap[s.Name()] = ctxt.processService(s) | 168 servicesMap[s.Name()] = ctxt.processService(s) |
160 } | 169 } |
161 return servicesMap | 170 return servicesMap |
162 } | 171 } |
(...skipping 20 matching lines...) Expand all Loading... | |
183 unitsMap[unit.Name()] = ctxt.processUnit(unit) | 192 unitsMap[unit.Name()] = ctxt.processUnit(unit) |
184 } | 193 } |
185 return unitsMap | 194 return unitsMap |
186 } | 195 } |
187 | 196 |
188 func (ctxt *statusContext) processUnit(unit *state.Unit) (status unitStatus) { | 197 func (ctxt *statusContext) processUnit(unit *state.Unit) (status unitStatus) { |
189 status.PublicAddress, _ = unit.PublicAddress() | 198 status.PublicAddress, _ = unit.PublicAddress() |
190 if unit.IsPrincipal() { | 199 if unit.IsPrincipal() { |
191 status.Machine, _ = unit.AssignedMachineId() | 200 status.Machine, _ = unit.AssignedMachineId() |
192 } | 201 } |
193 » if err := processAgent(&status.AgentVersion, &status.AgentState, &status .AgentStateInfo, unit); err != nil { | 202 » status.Life, |
194 » » status.Err = err | 203 » » status.AgentVersion, |
195 » » return | 204 » » status.AgentState, |
196 » } | 205 » » status.AgentStateInfo, |
206 » » status.Err = processAgent(unit) | |
197 if subUnits := unit.SubordinateNames(); len(subUnits) > 0 { | 207 if subUnits := unit.SubordinateNames(); len(subUnits) > 0 { |
198 status.Subordinates = make(map[string]unitStatus) | 208 status.Subordinates = make(map[string]unitStatus) |
199 for _, name := range subUnits { | 209 for _, name := range subUnits { |
200 subUnit := ctxt.unitByName(name) | 210 subUnit := ctxt.unitByName(name) |
201 status.Subordinates[name] = ctxt.processUnit(subUnit) | 211 status.Subordinates[name] = ctxt.processUnit(subUnit) |
202 } | 212 } |
203 } | 213 } |
204 return | 214 return |
205 } | 215 } |
206 | 216 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
245 | 255 |
246 type stateAgent interface { | 256 type stateAgent interface { |
247 Life() state.Life | 257 Life() state.Life |
248 AgentAlive() (bool, error) | 258 AgentAlive() (bool, error) |
249 AgentTools() (*state.Tools, error) | 259 AgentTools() (*state.Tools, error) |
250 Status() (params.Status, string, error) | 260 Status() (params.Status, string, error) |
251 } | 261 } |
252 | 262 |
253 // processAgent retrieves version and status information from the given entity | 263 // processAgent retrieves version and status information from the given entity |
254 // and sets the destination version, status and info values accordingly. | 264 // and sets the destination version, status and info values accordingly. |
255 func processAgent(dstVersion *string, dstStatus *params.Status, dstInfo *string, entity stateAgent) error { | 265 func processAgent(entity stateAgent) (life string, version string, status params .Status, info string, err error) { |
266 » if elife := entity.Life(); elife != state.Alive { | |
267 » » // alive is the usual state so omit it by default. | |
268 » » life = elife.String() | |
269 » } | |
256 if t, err := entity.AgentTools(); err == nil { | 270 if t, err := entity.AgentTools(); err == nil { |
fwereade
2013/04/18 12:37:09
This should be a `, ok`, shouldn't it. Ah well, no
| |
257 » » *dstVersion = t.Binary.Number.String() | 271 » » version = t.Binary.Number.String() |
272 » } | |
273 » status, info, err = entity.Status() | |
274 » if err != nil { | |
275 » » return | |
fwereade
2013/04/18 12:37:09
Why hide errors?
rog
2013/04/18 12:58:02
we don't. the error is returned.
| |
276 » } | |
277 » if status == params.StatusPending { | |
278 » » // The status is pending - there's no point | |
279 » » // in enquiring about the agent liveness. | |
fwereade
2013/04/18 12:37:09
"We don't bother to check agent liveness, even tho
rog
2013/04/18 12:58:02
is it really useful and relevant?
if the status is
| |
280 » » return | |
258 } | 281 } |
259 agentAlive, err := entity.AgentAlive() | 282 agentAlive, err := entity.AgentAlive() |
260 if err != nil { | 283 if err != nil { |
261 » » return err | 284 » » return |
fwereade
2013/04/18 12:37:09
I'd rather see 100x "watcher is dying" errors than
rog
2013/04/18 12:58:02
we're not skipping it. it gets returned and put in
| |
262 } | 285 } |
263 » entityDead := entity.Life() == state.Dead | 286 » if entity.Life() != state.Dead && !agentAlive { |
264 » status, info, err := entity.Status() | 287 » » // The agent *should* be alive but is not. |
265 » if err != nil { | |
266 » » return err | |
267 » } | |
268 » if status != params.StatusPending && !agentAlive && !entityDead { | |
269 // Add the original status to the info, so it's not lost. | 288 // Add the original status to the info, so it's not lost. |
270 if info != "" { | 289 if info != "" { |
271 info = fmt.Sprintf("(%s: %s)", status, info) | 290 info = fmt.Sprintf("(%s: %s)", status, info) |
272 } else { | 291 } else { |
273 info = fmt.Sprintf("(%s)", status) | 292 info = fmt.Sprintf("(%s)", status) |
274 } | 293 } |
275 // Agent should be running but it's not. | |
276 status = params.StatusDown | 294 status = params.StatusDown |
277 } | 295 } |
278 » *dstStatus = status | 296 » return |
279 » *dstInfo = info | |
280 » return nil | |
281 } | 297 } |
282 | 298 |
283 type machineStatus struct { | 299 type machineStatus struct { |
284 Err error `json:"-" yaml:",omitempty"` | 300 Err error `json:"-" yaml:",omitempty"` |
285 InstanceId state.InstanceId `json:"instance-id,omitempty" yaml:"inst ance-id,omitempty"` | 301 InstanceId state.InstanceId `json:"instance-id,omitempty" yaml:"inst ance-id,omitempty"` |
286 DNSName string `json:"dns-name,omitempty" yaml:"dns-nam e,omitempty"` | 302 DNSName string `json:"dns-name,omitempty" yaml:"dns-nam e,omitempty"` |
303 Life string `json:"life,omitempty" yaml:"life,omitem pty"` | |
287 AgentVersion string `json:"agent-version,omitempty" yaml:"ag ent-version,omitempty"` | 304 AgentVersion string `json:"agent-version,omitempty" yaml:"ag ent-version,omitempty"` |
288 AgentState params.Status `json:"agent-state,omitempty" yaml:"agen t-state,omitempty"` | 305 AgentState params.Status `json:"agent-state,omitempty" yaml:"agen t-state,omitempty"` |
289 AgentStateInfo string `json:"agent-state-info,omitempty" yaml: "agent-state-info,omitempty"` | 306 AgentStateInfo string `json:"agent-state-info,omitempty" yaml: "agent-state-info,omitempty"` |
290 InstanceState string `json:"instance-state,omitempty" yaml:"i nstance-state,omitempty"` | 307 InstanceState string `json:"instance-state,omitempty" yaml:"i nstance-state,omitempty"` |
291 } | 308 } |
292 | 309 |
293 // A goyaml bug means we can't declare these types | 310 // A goyaml bug means we can't declare these types |
294 // locally to the GetYAML methods. | 311 // locally to the GetYAML methods. |
295 type machineStatusNoMarshal machineStatus | 312 type machineStatusNoMarshal machineStatus |
296 | 313 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
339 return "", errorStatus{s.Err.Error()} | 356 return "", errorStatus{s.Err.Error()} |
340 } | 357 } |
341 type sNoMethods serviceStatus | 358 type sNoMethods serviceStatus |
342 return "", sNoMethods(s) | 359 return "", sNoMethods(s) |
343 } | 360 } |
344 | 361 |
345 type unitStatus struct { | 362 type unitStatus struct { |
346 Err error `json:"-" yaml:",omitempty"` | 363 Err error `json:"-" yaml:",omitempty"` |
347 PublicAddress string `json:"public-address,omitempty" ya ml:"public-address,omitempty"` | 364 PublicAddress string `json:"public-address,omitempty" ya ml:"public-address,omitempty"` |
348 Machine string `json:"machine,omitempty" yaml:"mac hine,omitempty"` | 365 Machine string `json:"machine,omitempty" yaml:"mac hine,omitempty"` |
366 Life string `json:"life,omitempty" yaml:"life,o mitempty"` | |
349 AgentVersion string `json:"agent-version,omitempty" yam l:"agent-version,omitempty"` | 367 AgentVersion string `json:"agent-version,omitempty" yam l:"agent-version,omitempty"` |
350 AgentState params.Status `json:"agent-state,omitempty" yaml: "agent-state,omitempty"` | 368 AgentState params.Status `json:"agent-state,omitempty" yaml: "agent-state,omitempty"` |
351 AgentStateInfo string `json:"agent-state-info,omitempty" yaml:"agent-state-info,omitempty"` | 369 AgentStateInfo string `json:"agent-state-info,omitempty" yaml:"agent-state-info,omitempty"` |
352 Subordinates map[string]unitStatus `json:"subordinates,omitempty" yaml :"subordinates,omitempty"` | 370 Subordinates map[string]unitStatus `json:"subordinates,omitempty" yaml :"subordinates,omitempty"` |
353 } | 371 } |
354 | 372 |
355 type unitStatusNoMarshal unitStatus | 373 type unitStatusNoMarshal unitStatus |
356 | 374 |
357 func (s unitStatus) MarshalJSON() ([]byte, error) { | 375 func (s unitStatus) MarshalJSON() ([]byte, error) { |
358 if s.Err != nil { | 376 if s.Err != nil { |
359 return json.Marshal(errorStatus{s.Err.Error()}) | 377 return json.Marshal(errorStatus{s.Err.Error()}) |
360 } | 378 } |
361 return json.Marshal(unitStatusNoMarshal(s)) | 379 return json.Marshal(unitStatusNoMarshal(s)) |
362 } | 380 } |
363 | 381 |
364 func (s unitStatus) GetYAML() (tag string, value interface{}) { | 382 func (s unitStatus) GetYAML() (tag string, value interface{}) { |
365 if s.Err != nil { | 383 if s.Err != nil { |
366 return "", errorStatus{s.Err.Error()} | 384 return "", errorStatus{s.Err.Error()} |
367 } | 385 } |
368 type uNoMethods unitStatus | 386 type uNoMethods unitStatus |
369 return "", unitStatusNoMarshal(s) | 387 return "", unitStatusNoMarshal(s) |
370 } | 388 } |
OLD | NEW |