func (s *DeployLocalSuite) assertMachines(c *gc.C, service *state.Service, 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 (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.Service switch entity := unitOrService.(type) { case *state.Service: service = entity case *state.Unit: service, err = entity.Service() 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.Service) *state.Unit { unit, err := service.AddUnit() c.Assert(err, jc.ErrorIsNil) err = unit.AssignToNewMachine() c.Assert(err, jc.ErrorIsNil) return unit }
// AddUnits starts n units of the given service using the specified placement // directives to allocate the machines. func AddUnits(st *state.State, svc *state.Service, n int, placement []*instance.Placement) ([]*state.Unit, error) { units := make([]*state.Unit, n) // Hard code for now till we implement a different approach. policy := state.AssignCleanEmpty // TODO what do we do if we fail half-way through this process? for i := 0; i < n; i++ { unit, err := svc.AddUnit() if err != nil { return nil, errors.Annotatef(err, "cannot add unit %d/%d to service %q", i+1, n, svc.Name()) } // Are there still placement directives to use? if i > len(placement)-1 { if err := st.AssignUnit(unit, policy); err != nil { return nil, errors.Trace(err) } units[i] = unit continue } if err := st.AssignUnitWithPlacement(unit, placement[i]); err != nil { return nil, errors.Annotatef(err, "adding new machine to host unit %q", unit.Name()) } units[i] = unit } return units, nil }
func buildServiceMatcherShims(s *state.Service, 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 }
// serviceSetSettingsYAML updates the settings for the given service, // taking the configuration from a YAML string. func serviceSetSettingsYAML(service *state.Service, settings string) error { b := []byte(settings) var all map[string]interface{} if err := goyaml.Unmarshal(b, &all); err != nil { return errors.Annotate(err, "parsing settings data") } // The file is already in the right format. if _, ok := all[service.Name()]; !ok { changes, err := settingsFromGetYaml(all) if err != nil { return errors.Annotate(err, "processing YAML generated by get") } return errors.Annotate(service.UpdateConfigSettings(changes), "updating settings with service YAML") } ch, _, err := service.Charm() if err != nil { return errors.Annotate(err, "obtaining charm for this service") } changes, err := ch.Config().ParseSettingsYAML(b, service.Name()) if err != nil { return errors.Annotate(err, "creating config from YAML") } return errors.Annotate(service.UpdateConfigSettings(changes), "updating settings") }
func (s *ContextSuite) AddUnit(c *gc.C, svc *state.Service) *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 }
// assertSetSuccess sets configuration options and checks the expected settings. func assertSetSuccess(c *gc.C, dir string, svc *state.Service, args []string, expect charm.Settings) { ctx := coretesting.ContextForDir(c, dir) code := cmd.Main(envcmd.Wrap(&SetCommand{}), ctx, append([]string{"dummy-service"}, args...)) c.Check(code, gc.Equals, 0) settings, err := svc.ConfigSettings() c.Assert(err, gc.IsNil) c.Assert(settings, gc.DeepEquals, expect) }
func matchExposure(patterns []string, s *state.Service) (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 }
// assertForceMachine ensures that the result of assigning a unit with --to // is as expected. func (s *AddUnitSuite) assertForceMachine(c *gc.C, svc *state.Service, expectedNumMachines, unitNum int, machineId string) { units, err := svc.AllUnits() c.Assert(err, gc.IsNil) c.Assert(units, gc.HasLen, expectedNumMachines) mid, err := units[unitNum].AssignedMachineId() c.Assert(err, gc.IsNil) c.Assert(mid, gc.Equals, machineId) }
func (s *BaseUpgradeCharmSuite) assertUpgraded(c *gc.C, riak *state.Service, 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 removeAllUnits(c *gc.C, s *state.Service) { us, err := s.AllUnits() c.Assert(err, gc.IsNil) for _, u := range us { err = u.EnsureDead() c.Assert(err, gc.IsNil) err = u.Remove() c.Assert(err, gc.IsNil) } }
// serviceSetCharm sets the charm for the given service. func (api *API) serviceSetCharm(service *state.Service, url string, forceSeries, forceUnits bool) error { curl, err := charm.ParseURL(url) if err != nil { return errors.Trace(err) } sch, err := api.state.Charm(curl) if err != nil { return errors.Trace(err) } return service.SetCharm(sch, forceSeries, forceUnits) }
// serviceSetSettingsYAML updates the settings for the given service, // taking the configuration from a YAML string. func serviceSetSettingsYAML(service *state.Service, settings string) error { ch, _, err := service.Charm() if err != nil { return err } changes, err := ch.Config().ParseSettingsYAML([]byte(settings), service.Name()) if err != nil { return err } return service.UpdateConfigSettings(changes) }
// ServiceSetSettingsStrings updates the settings for the given service, // taking the configuration from a map of strings. func ServiceSetSettingsStrings(service *state.Service, settings map[string]string) error { ch, _, err := service.Charm() if err != nil { return errors.Trace(err) } // Parse config in a compatible way (see function comment). changes, err := parseSettingsCompatible(ch, settings) if err != nil { return errors.Trace(err) } return service.UpdateConfigSettings(changes) }
func (s *runSuite) addUnit(c *gc.C, service *state.Service) *state.Unit { unit, err := service.AddUnit() c.Assert(err, jc.ErrorIsNil) err = unit.AssignToNewMachine() c.Assert(err, jc.ErrorIsNil) mId, err := unit.AssignedMachineId() c.Assert(err, jc.ErrorIsNil) machine, err := s.State.Machine(mId) c.Assert(err, jc.ErrorIsNil) machine.SetProviderAddresses(network.NewAddress("10.3.2.1")) return unit }
func (s *runSuite) addUnit(c *gc.C, service *state.Service) *state.Unit { unit, err := service.AddUnit() c.Assert(err, gc.IsNil) err = unit.AssignToNewMachine() c.Assert(err, gc.IsNil) mId, err := unit.AssignedMachineId() c.Assert(err, gc.IsNil) machine, err := s.State.Machine(mId) c.Assert(err, gc.IsNil) machine.SetAddresses(network.NewAddress("10.3.2.1", network.ScopeUnknown)) return unit }
func (s *HookContextSuite) AddUnit(c *gc.C, svc *state.Service) *state.Unit { unit, err := svc.AddUnit() c.Assert(err, gc.IsNil) s.machine, err = s.State.AddMachine("quantal", state.JobHostUnits) c.Assert(err, gc.IsNil) err = unit.AssignToMachine(s.machine) c.Assert(err, gc.IsNil) name := strings.Replace(unit.Name(), "/", "-", 1) privateAddr := network.NewAddress(name+".testing.invalid", network.ScopeCloudLocal) err = s.machine.SetAddresses(privateAddr) c.Assert(err, gc.IsNil) return unit }
// newServiceSetSettingsStringsForClientAPI updates the settings for the given // service, taking the configuration from a map of strings. // // TODO(Nate): replace serviceSetSettingsStrings with this onces the GUI no // longer expects to be able to unset values by sending an empty string. func newServiceSetSettingsStringsForClientAPI(service *state.Service, settings map[string]string) error { ch, _, err := service.Charm() if err != nil { return err } // Validate the settings. changes, err := ch.Config().ParseSettingsStrings(settings) if err != nil { return err } return service.UpdateConfigSettings(changes) }
func (s *ServiceSuite) assertServiceRelations(c *gc.C, svc *state.Service, expectedKeys ...string) []*state.Relation { rels, err := svc.Relations() c.Assert(err, gc.IsNil) if len(rels) == 0 { return nil } relKeys := make([]string, len(expectedKeys)) for i, rel := range rels { relKeys[i] = rel.String() } sort.Strings(relKeys) c.Assert(relKeys, gc.DeepEquals, expectedKeys) return rels }
// serviceSetCharm1dot16 sets the charm for the given service in 1.16 // compatibility mode. Remove this when support for 1.16 is dropped. func (c *Client) serviceSetCharm1dot16(service *state.Service, curl *charm.URL, force bool) error { if curl.Schema != "cs" { return fmt.Errorf(`charm url has unsupported schema %q`, curl.Schema) } if curl.Revision < 0 { return fmt.Errorf("charm url must include revision") } err := c.AddCharm(params.CharmURL{curl.String()}) if err != nil { return err } ch, err := c.api.state.Charm(curl) if err != nil { return err } return service.SetCharm(ch, force) }
// serviceSetCharm sets the charm for the given service. func (c *Client) serviceSetCharm(service *state.Service, url string, force bool) error { curl, err := charm.ParseURL(url) if err != nil { return err } sch, err := c.api.state.Charm(curl) if errors.IsNotFound(err) { // Charms should be added before trying to use them, with // AddCharm or AddLocalCharm API calls. When they're not, // we're reverting to 1.16 compatibility mode. return c.serviceSetCharm1dot16(service, curl, force) } if err != nil { return err } return service.SetCharm(sch, force) }
func (s *DeployLocalSuite) assertMachines(c *gc.C, service *state.Service, expectCons constraints.Value, expectIds ...string) { units, err := service.AllUnits() c.Assert(err, gc.IsNil) c.Assert(units, gc.HasLen, len(expectIds)) unseenIds := set.NewStrings(expectIds...) for _, unit := range units { id, err := unit.AssignedMachineId() c.Assert(err, gc.IsNil) unseenIds.Remove(id) machine, err := s.State.Machine(id) c.Assert(err, gc.IsNil) cons, err := machine.Constraints() c.Assert(err, gc.IsNil) c.Assert(cons, gc.DeepEquals, expectCons) } c.Assert(unseenIds, gc.DeepEquals, set.NewStrings()) }
// serviceSetCharm sets the charm for the given service. func (api *API) serviceSetCharm(service *state.Service, url string, channel csparams.Channel, forceSeries, forceUnits bool, resourceIDs map[string]string) error { curl, err := charm.ParseURL(url) if err != nil { return errors.Trace(err) } sch, err := api.state.Charm(curl) if err != nil { return errors.Trace(err) } cfg := state.SetCharmConfig{ Charm: sch, Channel: channel, ForceSeries: forceSeries, ForceUnits: forceUnits, ResourceIDs: resourceIDs, } return service.SetCharm(cfg) }
// GetExposed returns the exposed flag value for each given service. func (f *FirewallerAPI) GetExposed(args params.Entities) (params.BoolResults, error) { result := params.BoolResults{ Results: make([]params.BoolResult, len(args.Entities)), } canAccess, err := f.accessService() if err != nil { return params.BoolResults{}, err } for i, entity := range args.Entities { var service *state.Service service, err = f.getService(canAccess, entity.Tag) if err == nil { result.Results[i].Result = service.IsExposed() } result.Results[i].Error = common.ServerError(err) } return result, nil }
func (context *statusContext) processServiceRelations(service *state.Service) (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.ServiceName) } related[relationName] = append(related[relationName], ep.ServiceName) } } for relationName, serviceNames := range related { sn := set.NewStrings(serviceNames...) related[relationName] = sn.SortedValues() } return related, subordSet.SortedValues(), nil }
func (s *HookContextSuite) addUnit(c *gc.C, svc *state.Service) *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 assertOneRelation(c *gc.C, srv *state.Service, relId int, endpoints ...state.Endpoint) *state.Relation { rels, err := srv.Relations() c.Assert(err, gc.IsNil) 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, gc.IsNil) c.Assert(ep, gc.DeepEquals, expectEp) if len(endpoints) == 2 { expectEp = endpoints[1] } eps, err := rel.RelatedEndpoints(name) c.Assert(err, gc.IsNil) c.Assert(eps, gc.DeepEquals, []state.Endpoint{expectEp}) return rel }
func NewProReqRelation(c *gc.C, s *ConnSuite, scope charm.RelationScope) *ProReqRelation { psvc := s.AddTestingService(c, "mysql", s.AddTestingCharm(c, "mysql")) var rsvc *state.Service 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.Service) { // Destroy all units for the service. 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) }