func (lg *LifeGetter) oneLife(tag string) (params.Life, error) { entity0, err := lg.st.FindEntity(tag) if err != nil { return "", err } entity, ok := entity0.(state.Lifer) if !ok { return "", NotSupportedError(tag, "life cycles") } return params.Life(entity.Life().String()), nil }
func (api *AgentAPI) getMachine(tag string) (result params.MachineAgentGetMachinesResult, err error) { // Allow only for the owner agent. // Note: having a bulk API call for this is utter madness, given that // this check means we can only ever return a single object. if !api.auth.AuthOwner(tag) { err = common.ErrPerm return } machine, err := api.st.Machine(state.MachineIdFromTag(tag)) if err != nil { return } result.Life = params.Life(machine.Life().String()) result.Jobs = stateJobsToAPIParamsJobs(machine.Jobs()) return }
func (svc *backingService) updated(st *State, store *multiwatcher.Store, id interface{}) error { info := ¶ms.ServiceInfo{ Name: svc.Name, Exposed: svc.Exposed, CharmURL: svc.CharmURL.String(), Life: params.Life(svc.Life.String()), MinUnits: svc.MinUnits, } oldInfo := store.Get(info.EntityId()) needConfig := false if oldInfo == nil { // We're adding the entry for the first time, // so fetch the associated child documents. c, err := readConstraints(st, serviceGlobalKey(svc.Name)) if err != nil { return err } info.Constraints = c needConfig = true } else { // The entry already exists, so preserve the current status. oldInfo := oldInfo.(*params.ServiceInfo) info.Constraints = oldInfo.Constraints if info.CharmURL == oldInfo.CharmURL { // The charm URL remains the same - we can continue to // use the same config settings. info.Config = oldInfo.Config } else { // The charm URL has changed - we need to fetch the // settings from the new charm's settings doc. needConfig = true } } if needConfig { var err error info.Config, _, err = readSettingsDoc(st, serviceSettingsKey(svc.Name, svc.CharmURL)) if err != nil { return err } } store.Update(info) return nil }
func (api *API) getEntity(tag string) (result params.AgentGetEntitiesResult, err error) { // Allow only for the owner agent. // Note: having a bulk API call for this is utter madness, given that // this check means we can only ever return a single object. if !api.auth.AuthOwner(tag) { err = common.ErrPerm return } entity0, err := api.st.FindEntity(tag) if err != nil { return } entity, ok := entity0.(state.Lifer) if !ok { err = common.NotSupportedError(tag, "life cycles") return } result.Life = params.Life(entity.Life().String()) if machine, ok := entity.(*state.Machine); ok { result.Jobs = stateJobsToAPIParamsJobs(machine.Jobs()) } return }
// Life returns the life status of every supplied entity, where available. func (lg *LifeGetter) Life(args params.Entities) (params.LifeResults, error) { result := params.LifeResults{ Results: make([]params.LifeResult, len(args.Entities)), } if len(args.Entities) == 0 { return result, nil } canRead, err := lg.getCanRead() if err != nil { return params.LifeResults{}, err } for i, entity := range args.Entities { err := ErrPerm if canRead(entity.Tag) { var lifer state.Lifer lifer, err = lg.st.Lifer(entity.Tag) if err == nil { result.Results[i].Life = params.Life(lifer.Life().String()) } } result.Results[i].Error = ServerError(err) } return result, nil }
// setUpScenario adds some entities to the state so that // we can check that they all get pulled in by // allWatcherStateBacking.getAll. func (s *storeManagerStateSuite) setUpScenario(c *C) (entities entityInfoSlice) { add := func(e params.EntityInfo) { entities = append(entities, e) } m, err := s.State.AddMachine("series", JobManageEnviron) c.Assert(err, IsNil) c.Assert(m.Tag(), Equals, "machine-0") err = m.SetProvisioned(instance.Id("i-"+m.Tag()), "fake_nonce", nil) c.Assert(err, IsNil) add(¶ms.MachineInfo{ Id: "0", InstanceId: "i-machine-0", Status: params.StatusPending, }) wordpress, err := s.State.AddService("wordpress", AddTestingCharm(c, s.State, "wordpress")) c.Assert(err, IsNil) err = wordpress.SetExposed() c.Assert(err, IsNil) err = wordpress.SetMinUnits(3) c.Assert(err, IsNil) err = wordpress.SetConstraints(constraints.MustParse("mem=100M")) c.Assert(err, IsNil) setServiceConfigAttr(c, wordpress, "blog-title", "boring") add(¶ms.ServiceInfo{ Name: "wordpress", Exposed: true, CharmURL: serviceCharmURL(wordpress).String(), Life: params.Life(Alive.String()), MinUnits: 3, Constraints: constraints.MustParse("mem=100M"), Config: charm.Settings{"blog-title": "boring"}, }) pairs := map[string]string{"x": "12", "y": "99"} err = wordpress.SetAnnotations(pairs) c.Assert(err, IsNil) add(¶ms.AnnotationInfo{ Tag: "service-wordpress", Annotations: pairs, }) logging, err := s.State.AddService("logging", AddTestingCharm(c, s.State, "logging")) c.Assert(err, IsNil) add(¶ms.ServiceInfo{ Name: "logging", CharmURL: serviceCharmURL(logging).String(), Life: params.Life(Alive.String()), Config: charm.Settings{}, }) eps, err := s.State.InferEndpoints([]string{"logging", "wordpress"}) c.Assert(err, IsNil) rel, err := s.State.AddRelation(eps...) c.Assert(err, IsNil) add(¶ms.RelationInfo{ Key: "logging:logging-directory wordpress:logging-dir", Endpoints: []params.Endpoint{ {ServiceName: "logging", Relation: charm.Relation{Name: "logging-directory", Role: "requirer", Interface: "logging", Optional: false, Limit: 1, Scope: "container"}}, {ServiceName: "wordpress", Relation: charm.Relation{Name: "logging-dir", Role: "provider", Interface: "logging", Optional: false, Limit: 0, Scope: "container"}}}, }) for i := 0; i < 2; i++ { wu, err := wordpress.AddUnit() c.Assert(err, IsNil) c.Assert(wu.Tag(), Equals, fmt.Sprintf("unit-wordpress-%d", i)) m, err := s.State.AddMachine("series", JobHostUnits) c.Assert(err, IsNil) c.Assert(m.Tag(), Equals, fmt.Sprintf("machine-%d", i+1)) add(¶ms.UnitInfo{ Name: fmt.Sprintf("wordpress/%d", i), Service: wordpress.Name(), Series: m.Series(), MachineId: m.Id(), Ports: []instance.Port{}, Status: params.StatusPending, }) pairs := map[string]string{"name": fmt.Sprintf("bar %d", i)} err = wu.SetAnnotations(pairs) c.Assert(err, IsNil) add(¶ms.AnnotationInfo{ Tag: fmt.Sprintf("unit-wordpress-%d", i), Annotations: pairs, }) err = m.SetProvisioned(instance.Id("i-"+m.Tag()), "fake_nonce", nil) c.Assert(err, IsNil) err = m.SetStatus(params.StatusError, m.Tag()) c.Assert(err, IsNil) add(¶ms.MachineInfo{ Id: fmt.Sprint(i + 1), InstanceId: "i-" + m.Tag(), Status: params.StatusError, StatusInfo: m.Tag(), }) err = wu.AssignToMachine(m) c.Assert(err, IsNil) deployer, ok := wu.DeployerTag() c.Assert(ok, Equals, true) c.Assert(deployer, Equals, fmt.Sprintf("machine-%d", i+1)) wru, err := rel.Unit(wu) c.Assert(err, IsNil) // Create the subordinate unit as a side-effect of entering // scope in the principal's relation-unit. err = wru.EnterScope(nil) c.Assert(err, IsNil) lu, err := s.State.Unit(fmt.Sprintf("logging/%d", i)) c.Assert(err, IsNil) c.Assert(lu.IsPrincipal(), Equals, false) deployer, ok = lu.DeployerTag() c.Assert(ok, Equals, true) c.Assert(deployer, Equals, fmt.Sprintf("unit-wordpress-%d", i)) add(¶ms.UnitInfo{ Name: fmt.Sprintf("logging/%d", i), Service: "logging", Series: "series", Ports: []instance.Port{}, Status: params.StatusPending, }) } return }
c.Assert(err, IsNil) err = wordpress.SetExposed() c.Assert(err, IsNil) err = wordpress.SetMinUnits(42) c.Assert(err, IsNil) }, change: watcher.Change{ C: "services", Id: "wordpress", }, expectContents: []params.EntityInfo{ ¶ms.ServiceInfo{ Name: "wordpress", Exposed: true, CharmURL: "local:series/series-wordpress-3", Life: params.Life(Alive.String()), MinUnits: 42, Config: charm.Settings{}, }, }, }, { about: "service is updated if it's in backing and in multiwatcher.Store", add: []params.EntityInfo{¶ms.ServiceInfo{ Name: "wordpress", Exposed: true, CharmURL: "local:series/series-wordpress-3", MinUnits: 47, Constraints: constraints.MustParse("mem=99M"), Config: charm.Settings{"blog-title": "boring"}, }}, setUp: func(c *C, st *State) {
Entity: ¶ms.MachineInfo{ Id: "Benji", InstanceId: "Shazam", Status: "error", StatusInfo: "foo", }, }, json: `["machine","change",{"Id":"Benji","InstanceId":"Shazam","Status":"error","StatusInfo":"foo"}]`, }, { about: "ServiceInfo Delta", value: params.Delta{ Entity: ¶ms.ServiceInfo{ Name: "Benji", Exposed: true, CharmURL: "cs:series/name", Life: params.Life(state.Dying.String()), Constraints: constraints.MustParse("arch=arm mem=1024M"), Config: charm.Settings{ "hello": "goodbye", "foo": false, }, }, }, json: `["service","change",{"CharmURL": "cs:series/name","Name":"Benji","Exposed":true,"Life":"dying","Constraints":{"arch":"arm", "mem": 1024},"Config": {"hello":"goodbye","foo":false}}]`, }, { about: "UnitInfo Delta", value: params.Delta{ Entity: ¶ms.UnitInfo{ Name: "Benji", Service: "Shazam", Series: "precise",