func NewProReqRelation(c *C, s *ConnSuite, scope charm.RelationScope) *ProReqRelation { psvc, err := s.State.AddService("mysql", s.AddTestingCharm(c, "mysql")) c.Assert(err, IsNil) var rsvc *state.Service if scope == charm.ScopeGlobal { rsvc, err = s.State.AddService("wordpress", s.AddTestingCharm(c, "wordpress")) } else { rsvc, err = s.State.AddService("logging", s.AddTestingCharm(c, "logging")) } c.Assert(err, IsNil) eps, err := s.State.InferEndpoints([]string{"mysql", rsvc.Name()}) c.Assert(err, IsNil) rel, err := s.State.AddRelation(eps...) c.Assert(err, IsNil) 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 }
// assertForceMachine ensures that the result of assigning a unit with --to // is as expected. func (s *AddUnitSuite) assertForceMachine(c *C, svc *state.Service, expectedNumMachines, unitNum int, machineId string) { units, err := svc.AllUnits() c.Assert(err, IsNil) c.Assert(units, HasLen, expectedNumMachines) mid, err := units[unitNum].AssignedMachineId() c.Assert(err, IsNil) c.Assert(mid, Equals, machineId) }
func (s *HookContextSuite) AddUnit(c *C, svc *state.Service) *state.Unit { unit, err := svc.AddUnit() c.Assert(err, IsNil) name := strings.Replace(unit.Name(), "/", "-", 1) err = unit.SetPrivateAddress(name + ".testing.invalid") c.Assert(err, IsNil) return unit }
func removeAllUnits(c *C, s *state.Service) { us, err := s.AllUnits() c.Assert(err, IsNil) for _, u := range us { err = u.EnsureDead() c.Assert(err, IsNil) err = u.Remove() c.Assert(err, IsNil) } }
// startService creates a new data value for tracking details of the // service and starts watching the service for exposure changes. func (fw *Firewaller) startService(service *state.Service) error { serviced := &serviceData{ fw: fw, service: service, exposed: service.IsExposed(), unitds: make(map[string]*unitData), } fw.serviceds[service.Name()] = serviced go serviced.watchLoop(serviced.exposed) return nil }
// 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 err } changes, err := ch.Config().ParseSettingsStrings(settings) if err != nil { return err } return service.UpdateConfigSettings(changes) }
func (*statusContext) processRelations(service *state.Service) (related map[string][]string, subord []string, err error) { // TODO(mue) This way the same relation is read twice (for each service). // Maybe add Relations() to state, read them only once and pass them to each // call of this function. relations, err := service.Relations() if err != nil { return nil, nil, err } var subordSet set.Strings related = make(map[string][]string) 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 ep.Scope == charm.ScopeContainer && !service.IsPrincipal() { 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 *ServiceSuite) assertServiceRelations(c *C, svc *state.Service, expectedKeys ...string) []*state.Relation { rels, err := svc.Relations() c.Assert(err, 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, DeepEquals, expectedKeys) return rels }
func (s *SSHCommonSuite) addUnit(srv *state.Service, m *state.Machine, c *C) { u, err := srv.AddUnit() c.Assert(err, IsNil) err = u.AssignToMachine(m) c.Assert(err, IsNil) // fudge unit.SetPublicAddress id, err := m.InstanceId() c.Assert(err, IsNil) insts, err := s.Conn.Environ.Instances([]state.InstanceId{id}) c.Assert(err, IsNil) addr, err := insts[0].WaitDNSName() c.Assert(err, IsNil) err = u.SetPublicAddress(addr) c.Assert(err, IsNil) }
// AddUnits starts n units of the given service and allocates machines // to them as necessary. func (conn *Conn) AddUnits(svc *state.Service, n int) ([]*state.Unit, error) { units := make([]*state.Unit, n) // TODO what do we do if we fail half-way through this process? for i := 0; i < n; i++ { policy := conn.Environ.AssignmentPolicy() unit, err := svc.AddUnit() if err != nil { return nil, fmt.Errorf("cannot add unit %d/%d to service %q: %v", i+1, n, svc.Name(), err) } if err := conn.State.AssignUnit(unit, policy); err != nil { return nil, err } units[i] = unit } return units, nil }
func (s *DeployLocalSuite) assertMachines(c *C, service *state.Service, expectCons constraints.Value, expectIds ...string) { units, err := service.AllUnits() c.Assert(err, IsNil) c.Assert(units, HasLen, len(expectIds)) unseenIds := set.NewStrings(expectIds...) for _, unit := range units { id, err := unit.AssignedMachineId() c.Assert(err, IsNil) unseenIds.Remove(id) machine, err := s.State.Machine(id) c.Assert(err, IsNil) cons, err := machine.Constraints() c.Assert(err, IsNil) c.Assert(cons, DeepEquals, expectCons) } c.Assert(unseenIds, DeepEquals, set.NewStrings()) }
func assertOneRelation(c *C, srv *state.Service, relId int, endpoints ...state.Endpoint) { rels, err := srv.Relations() c.Assert(err, IsNil) c.Assert(rels, HasLen, 1) rel := rels[0] c.Assert(rel.Id(), Equals, relId) name := srv.Name() expectEp := endpoints[0] ep, err := rel.Endpoint(name) c.Assert(err, IsNil) c.Assert(ep, DeepEquals, expectEp) if len(endpoints) == 2 { expectEp = endpoints[1] } eps, err := rel.RelatedEndpoints(name) c.Assert(err, IsNil) c.Assert(eps, DeepEquals, []state.Endpoint{expectEp}) }
// serviceSetCharm sets the charm for the given service. func serviceSetCharm(state *state.State, service *state.Service, url string, force bool) error { curl, err := charm.ParseURL(url) if err != nil { return err } 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") } conn, err := juju.NewConnFromState(state) if err != nil { return err } ch, err := conn.PutCharm(curl, CharmStore, false) if err != nil { return err } return service.SetCharm(ch, force) }
func (context *statusContext) processService(service *state.Service) (status serviceStatus) { url, _ := service.CharmURL() status.Charm = url.String() status.Exposed = service.IsExposed() status.Life = processLife(service) var err error status.Relations, status.SubordinateTo, err = context.processRelations(service) if err != nil { status.Err = err return } if service.IsPrincipal() { status.Units = context.processUnits(context.units[service.Name()]) } return status }
// 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) }
func removeServiceAndUnits(c *C, service *state.Service) { // Destroy all units for the service. units, err := service.AllUnits() c.Assert(err, IsNil) for _, unit := range units { err = unit.EnsureDead() c.Assert(err, IsNil) err = unit.Remove() c.Assert(err, IsNil) } err = service.Destroy() c.Assert(err, IsNil) err = service.Refresh() c.Assert(err, checkers.Satisfies, errors.IsNotFoundError) }
func addRU(c *C, svc *state.Service, 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, IsNil) u = unit } else { origUnits, err := svc.AllUnits() c.Assert(err, IsNil) pru, err := rel.Unit(principal) c.Assert(err, IsNil) err = pru.EnterScope(nil) // to create the subordinate c.Assert(err, IsNil) err = pru.LeaveScope() // to reset to initial expected state c.Assert(err, IsNil) newUnits, err := svc.AllUnits() c.Assert(err, IsNil) 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, NotNil) } preventUnitDestroyRemove(c, u) ru, err := rel.Unit(u) c.Assert(err, IsNil) return u, ru }
func processService(service *state.Service) (map[string]interface{}, error) { r := m() ch, _, err := service.Charm() if err != nil { return nil, err } r["charm"] = ch.String() r["exposed"] = service.IsExposed() // TODO(dfc) service.IsSubordinate() ? units, err := service.AllUnits() if err != nil { return nil, err } u := checkError(processUnits(units)) if len(u) > 0 { r["units"] = u } // TODO(dfc) process relations return r, nil }
func assertNoRelations(c *C, srv *state.Service) { rels, err := srv.Relations() c.Assert(err, IsNil) c.Assert(rels, HasLen, 0) }
func assertAllUnits(c *C, service *state.Service, expected int) { units, err := service.AllUnits() c.Assert(err, IsNil) c.Assert(units, HasLen, expected) }
func (s *DeployLocalSuite) assertConstraints(c *C, service *state.Service, expect constraints.Value) { cons, err := service.Constraints() c.Assert(err, IsNil) c.Assert(cons, DeepEquals, expect) }
func (s *DeployLocalSuite) assertSettings(c *C, service *state.Service, expect charm.Settings) { settings, err := service.ConfigSettings() c.Assert(err, IsNil) c.Assert(settings, DeepEquals, expect) }
func (s *DeployLocalSuite) assertCharm(c *C, service *state.Service, expect *charm.URL) { curl, force := service.CharmURL() c.Assert(curl, DeepEquals, expect) c.Assert(force, Equals, false) }
// AddUnits starts n units of the given service and allocates machines // to them as necessary. func (conn *Conn) AddUnits(svc *state.Service, n int, machineIdSpec string) ([]*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, fmt.Errorf("cannot add unit %d/%d to service %q: %v", i+1, n, svc.Name(), err) } if machineIdSpec != "" { if n != 1 { return nil, fmt.Errorf("cannot add multiple units of service %q to a single machine", svc.Name()) } // machineIdSpec may be an existing machine or container, eg 3/lxc/2 // or a new container on a machine, eg lxc:3 mid := machineIdSpec var containerType instance.ContainerType specParts := strings.Split(machineIdSpec, ":") if len(specParts) > 1 { firstPart := specParts[0] var err error if containerType, err = instance.ParseSupportedContainerType(firstPart); err == nil { mid = strings.Join(specParts[1:], "/") } else { mid = machineIdSpec } } if !names.IsMachine(mid) { return nil, fmt.Errorf("invalid force machine id %q", mid) } var err error var m *state.Machine // If a container is to be used, create it. if containerType != "" { params := state.AddMachineParams{ Series: unit.Series(), ParentId: mid, ContainerType: containerType, Jobs: []state.MachineJob{state.JobHostUnits}, } m, err = conn.State.AddMachineWithConstraints(¶ms) } else { m, err = conn.State.Machine(mid) } if err != nil { return nil, fmt.Errorf("cannot assign unit %q to machine: %v", unit.Name(), err) } err = unit.AssignToMachine(m) if err != nil { return nil, err } } else if err := conn.State.AssignUnit(unit, policy); err != nil { return nil, err } units[i] = unit } return units, nil }