func buildServiceMatcherShims(s *state.Application, patterns ...string) (shims []closurePredicate, _ error) { // Match on name. shims = append(shims, func() (bool, bool, error) { for _, p := range patterns { if strings.ToLower(s.Name()) == strings.ToLower(p) { return true, true, nil } } return false, false, nil }) // Match on exposure. shims = append(shims, func() (bool, bool, error) { return matchExposure(patterns, s) }) // If the service has an unit instance that matches any of the // given criteria, consider the service a match as well. unitShims, err := buildShimsForUnit(s.AllUnits, patterns...) if err != nil { return nil, err } shims = append(shims, unitShims...) // Units may be able to match the pattern. Ultimately defer to // that logic, and guard against breaking the predicate-chain. if len(unitShims) <= 0 { shims = append(shims, func() (bool, bool, error) { return false, true, nil }) } return shims, nil }
func (u *UniterAPIV3) charmModifiedVersion(tagStr string, canAccess func(names.Tag) bool) (int, error) { tag, err := names.ParseTag(tagStr) if err != nil { return -1, common.ErrPerm } if !canAccess(tag) { return -1, common.ErrPerm } unitOrService, err := u.st.FindEntity(tag) if err != nil { return -1, err } var service *state.Application switch entity := unitOrService.(type) { case *state.Application: service = entity case *state.Unit: service, err = entity.Application() if err != nil { return -1, err } default: return -1, errors.BadRequestf("type %T does not have a CharmModifiedVersion", entity) } return service.CharmModifiedVersion(), nil }
func (s *runSuite) addUnit(c *gc.C, service *state.Application) *state.Unit { unit, err := service.AddUnit() c.Assert(err, jc.ErrorIsNil) err = unit.AssignToNewMachine() c.Assert(err, jc.ErrorIsNil) return unit }
func (s *ContextSuite) AddUnit(c *gc.C, svc *state.Application) *state.Unit { unit, err := svc.AddUnit() c.Assert(err, jc.ErrorIsNil) if s.machine != nil { err = unit.AssignToMachine(s.machine) c.Assert(err, jc.ErrorIsNil) return unit } err = s.State.AssignUnit(unit, state.AssignCleanEmpty) c.Assert(err, jc.ErrorIsNil) machineId, err := unit.AssignedMachineId() c.Assert(err, jc.ErrorIsNil) s.machine, err = s.State.Machine(machineId) c.Assert(err, jc.ErrorIsNil) zone := "a-zone" hwc := instance.HardwareCharacteristics{ AvailabilityZone: &zone, } err = s.machine.SetProvisioned("i-exist", "fake_nonce", &hwc) c.Assert(err, jc.ErrorIsNil) name := strings.Replace(unit.Name(), "/", "-", 1) privateAddr := network.NewScopedAddress(name+".testing.invalid", network.ScopeCloudLocal) err = s.machine.SetProviderAddresses(privateAddr) c.Assert(err, jc.ErrorIsNil) return unit }
func (s *DeployLocalSuite) assertMachines(c *gc.C, service *state.Application, expectCons constraints.Value, expectIds ...string) { units, err := service.AllUnits() c.Assert(err, jc.ErrorIsNil) c.Assert(units, gc.HasLen, len(expectIds)) // first manually tell state to assign all the units for _, unit := range units { id := unit.Tag().Id() res, err := s.State.AssignStagedUnits([]string{id}) c.Assert(err, jc.ErrorIsNil) c.Assert(res[0].Error, jc.ErrorIsNil) c.Assert(res[0].Unit, gc.Equals, id) } // refresh the list of units from state units, err = service.AllUnits() c.Assert(err, jc.ErrorIsNil) c.Assert(units, gc.HasLen, len(expectIds)) unseenIds := set.NewStrings(expectIds...) for _, unit := range units { id, err := unit.AssignedMachineId() c.Assert(err, jc.ErrorIsNil) unseenIds.Remove(id) machine, err := s.State.Machine(id) c.Assert(err, jc.ErrorIsNil) cons, err := machine.Constraints() c.Assert(err, jc.ErrorIsNil) c.Assert(cons, gc.DeepEquals, expectCons) } c.Assert(unseenIds, gc.DeepEquals, set.NewStrings()) }
func matchExposure(patterns []string, s *state.Application) (bool, bool, error) { if len(patterns) >= 1 && patterns[0] == "exposed" { return s.IsExposed(), true, nil } else if len(patterns) >= 2 && patterns[0] == "not" && patterns[1] == "exposed" { return !s.IsExposed(), true, nil } return false, false, nil }
func (s *BaseUpgradeCharmStateSuite) assertUpgraded(c *gc.C, riak *state.Application, revision int, forced bool) *charm.URL { err := riak.Refresh() c.Assert(err, jc.ErrorIsNil) ch, force, err := riak.Charm() c.Assert(err, jc.ErrorIsNil) c.Assert(ch.Revision(), gc.Equals, revision) c.Assert(force, gc.Equals, forced) return ch.URL() }
func (s *statusUnitTestSuite) checkAppVersion(c *gc.C, application *state.Application, expectedVersion string) params.ApplicationStatus { client := s.APIState.Client() status, err := client.Status(nil) c.Assert(err, jc.ErrorIsNil) appStatus, found := status.Applications[application.Name()] c.Assert(found, jc.IsTrue) c.Check(appStatus.WorkloadVersion, gc.Equals, expectedVersion) return appStatus }
func addUnitWithVersion(c *gc.C, application *state.Application, version string) *state.Unit { unit, err := application.AddUnit() c.Assert(err, jc.ErrorIsNil) // Ensure that the timestamp on this version record is different // from the previous one. // TODO(babbageclunk): when Application and Unit have clocks, change // that instead of sleeping (lp:1558657) time.Sleep(time.Millisecond * 1) err = unit.SetWorkloadVersion(version) c.Assert(err, jc.ErrorIsNil) return unit }
func (context *statusContext) processServiceRelations(service *state.Application) (related map[string][]string, subord []string, err error) { subordSet := make(set.Strings) related = make(map[string][]string) relations := context.relations[service.Name()] for _, relation := range relations { ep, err := relation.Endpoint(service.Name()) if err != nil { return nil, nil, err } relationName := ep.Relation.Name eps, err := relation.RelatedEndpoints(service.Name()) if err != nil { return nil, nil, err } for _, ep := range eps { if isSubordinate(&ep, service) { subordSet.Add(ep.ApplicationName) } related[relationName] = append(related[relationName], ep.ApplicationName) } } for relationName, serviceNames := range related { sn := set.NewStrings(serviceNames...) related[relationName] = sn.SortedValues() } return related, subordSet.SortedValues(), nil }
func assertOneRelation(c *gc.C, srv *state.Application, relId int, endpoints ...state.Endpoint) *state.Relation { rels, err := srv.Relations() c.Assert(err, jc.ErrorIsNil) c.Assert(rels, gc.HasLen, 1) rel := rels[0] c.Assert(rel.Id(), gc.Equals, relId) c.Assert(rel.Endpoints(), jc.SameContents, endpoints) name := srv.Name() expectEp := endpoints[0] ep, err := rel.Endpoint(name) c.Assert(err, jc.ErrorIsNil) c.Assert(ep, gc.DeepEquals, expectEp) if len(endpoints) == 2 { expectEp = endpoints[1] } eps, err := rel.RelatedEndpoints(name) c.Assert(err, jc.ErrorIsNil) c.Assert(eps, gc.DeepEquals, []state.Endpoint{expectEp}) return rel }
func (s *HookContextSuite) addUnit(c *gc.C, svc *state.Application) *state.Unit { unit, err := svc.AddUnit() c.Assert(err, jc.ErrorIsNil) if s.machine != nil { err = unit.AssignToMachine(s.machine) c.Assert(err, jc.ErrorIsNil) return unit } err = s.State.AssignUnit(unit, state.AssignCleanEmpty) c.Assert(err, jc.ErrorIsNil) machineId, err := unit.AssignedMachineId() c.Assert(err, jc.ErrorIsNil) s.machine, err = s.State.Machine(machineId) c.Assert(err, jc.ErrorIsNil) zone := "a-zone" hwc := instance.HardwareCharacteristics{ AvailabilityZone: &zone, } err = s.machine.SetProvisioned("i-exist", "fake_nonce", &hwc) c.Assert(err, jc.ErrorIsNil) return unit }
func NewProReqRelation(c *gc.C, s *ConnSuite, scope charm.RelationScope) *ProReqRelation { psvc := s.AddTestingService(c, "mysql", s.AddTestingCharm(c, "mysql")) var rsvc *state.Application if scope == charm.ScopeGlobal { rsvc = s.AddTestingService(c, "wordpress", s.AddTestingCharm(c, "wordpress")) } else { rsvc = s.AddTestingService(c, "logging", s.AddTestingCharm(c, "logging")) } eps, err := s.State.InferEndpoints("mysql", rsvc.Name()) c.Assert(err, jc.ErrorIsNil) rel, err := s.State.AddRelation(eps...) c.Assert(err, jc.ErrorIsNil) prr := &ProReqRelation{rel: rel, psvc: psvc, rsvc: rsvc} prr.pu0, prr.pru0 = addRU(c, psvc, rel, nil) prr.pu1, prr.pru1 = addRU(c, psvc, rel, nil) if scope == charm.ScopeGlobal { prr.ru0, prr.rru0 = addRU(c, rsvc, rel, nil) prr.ru1, prr.rru1 = addRU(c, rsvc, rel, nil) } else { prr.ru0, prr.rru0 = addRU(c, rsvc, rel, prr.pu0) prr.ru1, prr.rru1 = addRU(c, rsvc, rel, prr.pu1) } return prr }
func removeServiceAndUnits(c *gc.C, service *state.Application) { // Destroy all units for the application. units, err := service.AllUnits() c.Assert(err, jc.ErrorIsNil) for _, unit := range units { err = unit.EnsureDead() c.Assert(err, jc.ErrorIsNil) err = unit.Remove() c.Assert(err, jc.ErrorIsNil) } err = service.Destroy() c.Assert(err, jc.ErrorIsNil) err = service.Refresh() c.Assert(err, jc.Satisfies, errors.IsNotFound) }
func addRU(c *gc.C, svc *state.Application, rel *state.Relation, principal *state.Unit) (*state.Unit, *state.RelationUnit) { // Given the service svc in the relation rel, add a unit of svc and create // a RelationUnit with rel. If principal is supplied, svc is assumed to be // subordinate and the unit will be created by temporarily entering the // relation's scope as the principal. var u *state.Unit if principal == nil { unit, err := svc.AddUnit() c.Assert(err, jc.ErrorIsNil) u = unit } else { origUnits, err := svc.AllUnits() c.Assert(err, jc.ErrorIsNil) pru, err := rel.Unit(principal) c.Assert(err, jc.ErrorIsNil) err = pru.EnterScope(nil) // to create the subordinate c.Assert(err, jc.ErrorIsNil) err = pru.LeaveScope() // to reset to initial expected state c.Assert(err, jc.ErrorIsNil) newUnits, err := svc.AllUnits() c.Assert(err, jc.ErrorIsNil) for _, unit := range newUnits { found := false for _, old := range origUnits { if unit.Name() == old.Name() { found = true break } } if !found { u = unit break } } c.Assert(u, gc.NotNil) } preventUnitDestroyRemove(c, u) ru, err := rel.Unit(u) c.Assert(err, jc.ErrorIsNil) return u, ru }
func (s *DeployLocalSuite) assertConstraints(c *gc.C, service *state.Application, expect constraints.Value) { cons, err := service.Constraints() c.Assert(err, jc.ErrorIsNil) c.Assert(cons, gc.DeepEquals, expect) }
func assertNoRelations(c *gc.C, srv *state.Application) { rels, err := srv.Relations() c.Assert(err, jc.ErrorIsNil) c.Assert(rels, gc.HasLen, 0) }
func (s *DeployLocalSuite) assertCharm(c *gc.C, service *state.Application, expect *charm.URL) { curl, force := service.CharmURL() c.Assert(curl, gc.DeepEquals, expect) c.Assert(force, jc.IsFalse) }
func (s *DeployLocalSuite) assertSettings(c *gc.C, service *state.Application, expect charm.Settings) { settings, err := service.ConfigSettings() c.Assert(err, jc.ErrorIsNil) c.Assert(settings, gc.DeepEquals, expect) }
func (s *DeployLocalSuite) assertBindings(c *gc.C, service *state.Application, expected map[string]string) { bindings, err := service.EndpointBindings() c.Assert(err, jc.ErrorIsNil) c.Assert(bindings, jc.DeepEquals, expected) }
func (s *serviceSuite) claimLeadership(c *gc.C, unit *state.Unit, service *state.Application) { claimer := s.State.LeadershipClaimer() err := claimer.ClaimLeadership(service.Name(), unit.Name(), time.Minute) c.Assert(err, jc.ErrorIsNil) }
func assertAllUnits(c *gc.C, service *state.Application, expected int) { units, err := service.AllUnits() c.Assert(err, jc.ErrorIsNil) c.Assert(units, gc.HasLen, expected) }
func isSubordinate(ep *state.Endpoint, service *state.Application) bool { return ep.Scope == charm.ScopeContainer && !service.IsPrincipal() }
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 }