~rogpeppe/juju-core/themue-058-debug-log-api

« back to all changes in this revision

Viewing changes to state/statecmd/status.go

  • Committer: Frank Mueller
  • Date: 2014-01-21 08:46:24 UTC
  • mfrom: (2152.1.76 juju-core)
  • Revision ID: frank.mueller@canonical.com-20140121084624-rv32dv6ufzul9h1b
debugger: merged trunk and added access to debugger API facade

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
)
23
23
 
24
24
func Status(conn *juju.Conn, patterns []string) (*api.Status, error) {
 
25
        var nilStatus api.Status
25
26
        var context statusContext
26
27
        unitMatcher, err := NewUnitMatcher(patterns)
27
28
        if err != nil {
28
 
                return nil, err
 
29
                return &nilStatus, err
29
30
        }
30
 
        if context.services, context.units, err = fetchAllServicesAndUnits(conn.State, unitMatcher); err != nil {
31
 
                return nil, err
 
31
        if context.services,
 
32
                context.units, context.latestCharms, err = fetchAllServicesAndUnits(conn.State, unitMatcher); err != nil {
 
33
                return &nilStatus, err
32
34
        }
33
35
 
34
36
        // Filter machines by units in scope.
36
38
        if !unitMatcher.matchesAny() {
37
39
                machineIds, err = fetchUnitMachineIds(context.units)
38
40
                if err != nil {
39
 
                        return nil, err
 
41
                        return &nilStatus, err
40
42
                }
41
43
        }
42
44
        if context.machines, err = fetchMachines(conn.State, machineIds); err != nil {
43
 
                return nil, err
 
45
                return &nilStatus, err
44
46
        }
45
47
 
46
48
        context.instances, err = fetchAllInstances(conn.Environ)
56
58
}
57
59
 
58
60
type statusContext struct {
59
 
        instances map[instance.Id]instance.Instance
60
 
        machines  map[string][]*state.Machine
61
 
        services  map[string]*state.Service
62
 
        units     map[string]map[string]*state.Unit
 
61
        instances    map[instance.Id]instance.Instance
 
62
        machines     map[string][]*state.Machine
 
63
        services     map[string]*state.Service
 
64
        units        map[string]map[string]*state.Unit
 
65
        latestCharms map[charm.URL]string
63
66
}
64
67
 
65
68
type unitMatcher struct {
196
199
        return v, nil
197
200
}
198
201
 
199
 
// fetchAllServicesAndUnits returns a map from service name to service
200
 
// and a map from service name to unit name to unit.
201
 
func fetchAllServicesAndUnits(st *state.State, unitMatcher unitMatcher) (map[string]*state.Service, map[string]map[string]*state.Unit, error) {
 
202
// fetchAllServicesAndUnits returns a map from service name to service,
 
203
// a map from service name to unit name to unit, and a map from base charm URL to latest URL.
 
204
func fetchAllServicesAndUnits(
 
205
        st *state.State, unitMatcher unitMatcher) (
 
206
        map[string]*state.Service, map[string]map[string]*state.Unit, map[charm.URL]string, error) {
 
207
 
202
208
        svcMap := make(map[string]*state.Service)
203
209
        unitMap := make(map[string]map[string]*state.Unit)
 
210
        latestCharms := make(map[charm.URL]string)
204
211
        services, err := st.AllServices()
205
212
        if err != nil {
206
 
                return nil, nil, err
 
213
                return nil, nil, nil, err
207
214
        }
208
215
        for _, s := range services {
209
216
                units, err := s.AllUnits()
210
217
                if err != nil {
211
 
                        return nil, nil, err
 
218
                        return nil, nil, nil, err
212
219
                }
213
220
                svcUnitMap := make(map[string]*state.Unit)
214
221
                for _, u := range units {
220
227
                if unitMatcher.matchesAny() || len(svcUnitMap) > 0 {
221
228
                        unitMap[s.Name()] = svcUnitMap
222
229
                        svcMap[s.Name()] = s
223
 
                }
224
 
        }
225
 
        return svcMap, unitMap, nil
 
230
                        // Record the base URL for the service's charm so that
 
231
                        // the latest store revision can be looked up.
 
232
                        charmURL, _ := s.CharmURL()
 
233
                        if charmURL.Schema == "cs" {
 
234
                                latestCharms[*charmURL.WithRevision(-1)] = ""
 
235
                        }
 
236
                }
 
237
        }
 
238
        for baseURL, _ := range latestCharms {
 
239
                ch, err := st.LatestPlaceholderCharm(&baseURL)
 
240
                if errors.IsNotFoundError(err) {
 
241
                        continue
 
242
                }
 
243
                if err != nil {
 
244
                        return nil, nil, nil, err
 
245
                }
 
246
                latestCharms[baseURL] = ch.String()
 
247
        }
 
248
        return svcMap, unitMap, latestCharms, nil
226
249
}
227
250
 
228
251
// fetchUnitMachineIds returns a set of IDs for machines that
292
315
                status.InstanceId = instid
293
316
                inst, ok := context.instances[instid]
294
317
                if ok {
295
 
                        status.DNSName, _ = inst.DNSName()
 
318
                        status.DNSName = instance.SelectPublicAddress(machine.Addresses())
296
319
                        status.InstanceState = inst.Status()
297
320
                } else {
298
321
                        // Double plus ungood.  There is an instance id recorded
333
356
}
334
357
 
335
358
func (context *statusContext) processService(service *state.Service) (status api.ServiceStatus) {
336
 
        url, _ := service.CharmURL()
337
 
        status.Charm = url.String()
 
359
        serviceCharmURL, _ := service.CharmURL()
 
360
        status.Charm = serviceCharmURL.String()
338
361
        status.Exposed = service.IsExposed()
339
362
        status.Life = processLife(service)
 
363
 
 
364
        latestCharm, ok := context.latestCharms[*serviceCharmURL.WithRevision(-1)]
 
365
        if ok && latestCharm != serviceCharmURL.String() {
 
366
                status.CanUpgradeTo = latestCharm
 
367
        }
340
368
        var err error
341
369
        status.Relations, status.SubordinateTo, err = context.processRelations(service)
342
370
        if err != nil {
344
372
                return
345
373
        }
346
374
        if service.IsPrincipal() {
347
 
                status.Units = context.processUnits(context.units[service.Name()])
 
375
                status.Units = context.processUnits(context.units[service.Name()], serviceCharmURL.String())
348
376
        }
349
377
        return status
350
378
}
351
379
 
352
 
func (context *statusContext) processUnits(units map[string]*state.Unit) map[string]api.UnitStatus {
 
380
func (context *statusContext) processUnits(units map[string]*state.Unit, serviceCharm string) map[string]api.UnitStatus {
353
381
        unitsMap := make(map[string]api.UnitStatus)
354
382
        for _, unit := range units {
355
 
                unitsMap[unit.Name()] = context.processUnit(unit)
 
383
                unitsMap[unit.Name()] = context.processUnit(unit, serviceCharm)
356
384
        }
357
385
        return unitsMap
358
386
}
359
387
 
360
 
func (context *statusContext) processUnit(unit *state.Unit) (status api.UnitStatus) {
 
388
func (context *statusContext) processUnit(unit *state.Unit, serviceCharm string) (status api.UnitStatus) {
361
389
        status.PublicAddress, _ = unit.PublicAddress()
362
390
        for _, port := range unit.OpenedPorts() {
363
391
                status.OpenedPorts = append(status.OpenedPorts, port.String())
365
393
        if unit.IsPrincipal() {
366
394
                status.Machine, _ = unit.AssignedMachineId()
367
395
        }
 
396
        curl, _ := unit.CharmURL()
 
397
        if serviceCharm != "" && curl != nil && curl.String() != serviceCharm {
 
398
                status.Charm = curl.String()
 
399
        }
368
400
        status.Life,
369
401
                status.AgentVersion,
370
402
                status.AgentState,
376
408
                        subUnit := context.unitByName(name)
377
409
                        // subUnit may be nil if subordinate was filtered out.
378
410
                        if subUnit != nil {
379
 
                                status.Subordinates[name] = context.processUnit(subUnit)
 
411
                                status.Subordinates[name] = context.processUnit(subUnit, serviceCharm)
380
412
                        }
381
413
                }
382
414
        }