func (context *statusContext) processApplication(service *state.Application) params.ApplicationStatus { serviceCharm, _, err := service.Charm() if err != nil { return params.ApplicationStatus{Err: common.ServerError(err)} } var processedStatus = params.ApplicationStatus{ Charm: serviceCharm.URL().String(), Series: service.Series(), Exposed: service.IsExposed(), Life: processLife(service), } if latestCharm, ok := context.latestCharms[*serviceCharm.URL().WithRevision(-1)]; ok && latestCharm != nil { if latestCharm.Revision() > serviceCharm.URL().Revision { processedStatus.CanUpgradeTo = latestCharm.String() } } processedStatus.Relations, processedStatus.SubordinateTo, err = context.processServiceRelations(service) if err != nil { processedStatus.Err = common.ServerError(err) return processedStatus } units := context.units[service.Name()] if service.IsPrincipal() { processedStatus.Units = context.processUnits(units, serviceCharm.URL().String()) } applicationStatus, err := service.Status() if err != nil { processedStatus.Err = common.ServerError(err) return processedStatus } processedStatus.Status.Status = applicationStatus.Status.String() processedStatus.Status.Info = applicationStatus.Message processedStatus.Status.Data = applicationStatus.Data processedStatus.Status.Since = applicationStatus.Since metrics := serviceCharm.Metrics() planRequired := metrics != nil && metrics.Plan != nil && metrics.Plan.Required if planRequired || len(service.MetricCredentials()) > 0 { processedStatus.MeterStatuses = context.processUnitMeterStatuses(units) } versions := make([]status.StatusInfo, 0, len(units)) for _, unit := range units { statuses, err := unit.WorkloadVersionHistory().StatusHistory( status.StatusHistoryFilter{Size: 1}, ) if err != nil { processedStatus.Err = common.ServerError(err) return processedStatus } // Even though we fully expect there to be historical values there, // even the first should be the empty string, the status history // collection is not added to in a transactional manner, so it may be // not there even though we'd really like it to be. Such is mongo. if len(statuses) > 0 { versions = append(versions, statuses[0]) } } if len(versions) > 0 { sort.Sort(bySinceDescending(versions)) processedStatus.WorkloadVersion = versions[0].Message } return processedStatus }
func isSubordinate(ep *state.Endpoint, service *state.Application) bool { return ep.Scope == charm.ScopeContainer && !service.IsPrincipal() }