Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(91)

Side by Side Diff: cmd/juju/status.go

Issue 8852043: cmd/juju: implement life in status
Patch Set: Created 10 years, 11 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « [revision details] ('k') | cmd/juju/status_test.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « [revision details] ('k') | cmd/juju/status_test.go » ('j') | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b