func (s *uniterSuite) TestRelationById(c *gc.C) { rel := s.addRelation(c, "wordpress", "mysql") c.Assert(rel.Id(), gc.Equals, 0) wpEp, err := rel.Endpoint("wordpress") c.Assert(err, gc.IsNil) // Add another relation to mysql service, so we can see we can't // get it. otherRel, _, _ := s.addRelatedService(c, "mysql", "logging", s.mysqlUnit) args := params.RelationIds{ RelationIds: []int{-1, rel.Id(), otherRel.Id(), 42, 234}, } result, err := s.uniter.RelationById(args) c.Assert(err, gc.IsNil) c.Assert(result, gc.DeepEquals, params.RelationResults{ Results: []params.RelationResult{ {Error: apiservertesting.ErrUnauthorized}, { Id: rel.Id(), Key: rel.String(), Life: params.Life(rel.Life().String()), Endpoint: params.Endpoint{ ServiceName: wpEp.ServiceName, Relation: wpEp.Relation, }, }, {Error: apiservertesting.ErrUnauthorized}, {Error: apiservertesting.ErrUnauthorized}, {Error: apiservertesting.ErrUnauthorized}, }, }) }
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 (svc *backingService) updated(st *State, store *multiwatcher.Store, id interface{}) error { info := ¶ms.ServiceInfo{ Name: svc.Name, Exposed: svc.Exposed, CharmURL: svc.CharmURL.String(), OwnerTag: svc.fixOwnerTag(), 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 (u *UniterAPI) prepareRelationResult(rel *state.Relation, unit *state.Unit) (params.RelationResult, error) { nothing := params.RelationResult{} ep, err := rel.Endpoint(unit.ServiceName()) if err != nil { // An error here means the unit's service is not part of the // relation. return nothing, err } return params.RelationResult{ Id: rel.Id(), Key: rel.String(), Life: params.Life(rel.Life().String()), Endpoint: params.Endpoint{ ServiceName: ep.ServiceName, Relation: ep.Relation, }, }, nil }
func (m *backingMachine) updated(st *State, store *multiwatcher.Store, id interface{}) error { info := ¶ms.MachineInfo{ Id: m.Id, Life: params.Life(m.Life.String()), Series: m.Series, Jobs: paramsJobsFromJobs(m.Jobs), Addresses: mergedAddresses(m.MachineAddresses, m.Addresses), SupportedContainers: m.SupportedContainers, SupportedContainersKnown: m.SupportedContainersKnown, } oldInfo := store.Get(info.EntityId()) if oldInfo == nil { // We're adding the entry for the first time, // so fetch the associated machine status. sdoc, err := getStatus(st, machineGlobalKey(m.Id)) if err != nil { return err } info.Status = sdoc.Status info.StatusInfo = sdoc.StatusInfo } else { // The entry already exists, so preserve the current status and // instance data. oldInfo := oldInfo.(*params.MachineInfo) info.Status = oldInfo.Status info.StatusInfo = oldInfo.StatusInfo info.InstanceId = oldInfo.InstanceId info.HardwareCharacteristics = oldInfo.HardwareCharacteristics } // If the machine is been provisioned, fetch the instance id as required, // and set instance id and hardware characteristics. if m.Nonce != "" && info.InstanceId == "" { instanceData, err := getInstanceData(st, m.Id) if err == nil { info.InstanceId = string(instanceData.InstanceId) info.HardwareCharacteristics = hardwareCharacteristics(instanceData) } else if !errors.IsNotFound(err) { return err } } store.Update(info) return nil }
func (s *uniterSuite) TestRelation(c *gc.C) { rel := s.addRelation(c, "wordpress", "mysql") wpEp, err := rel.Endpoint("wordpress") c.Assert(err, gc.IsNil) args := params.RelationUnits{RelationUnits: []params.RelationUnit{ {Relation: "relation-42", Unit: "unit-foo-0"}, {Relation: rel.Tag(), Unit: "unit-wordpress-0"}, {Relation: rel.Tag(), Unit: "unit-mysql-0"}, {Relation: rel.Tag(), Unit: "unit-foo-0"}, {Relation: "relation-blah", Unit: "unit-wordpress-0"}, {Relation: "service-foo", Unit: "user-admin"}, {Relation: "foo", Unit: "bar"}, {Relation: "unit-wordpress-0", Unit: rel.Tag()}, }} result, err := s.uniter.Relation(args) c.Assert(err, gc.IsNil) c.Assert(result, gc.DeepEquals, params.RelationResults{ Results: []params.RelationResult{ {Error: apiservertesting.ErrUnauthorized}, { Id: rel.Id(), Key: rel.String(), Life: params.Life(rel.Life().String()), Endpoint: params.Endpoint{ ServiceName: wpEp.ServiceName, Relation: wpEp.Relation, }, }, {Error: apiservertesting.ErrUnauthorized}, {Error: apiservertesting.ErrUnauthorized}, {Error: apiservertesting.ErrUnauthorized}, {Error: apiservertesting.ErrUnauthorized}, {Error: apiservertesting.ErrUnauthorized}, {Error: apiservertesting.ErrUnauthorized}, }, }) }
// MachinesWithTransientErrors returns status data for machines with provisioning // errors which are transient. func (p *ProvisionerAPI) MachinesWithTransientErrors() (params.StatusResults, error) { results := params.StatusResults{} canAccessFunc, err := p.getAuthFunc() if err != nil { return results, err } // TODO (wallyworld) - add state.State API for more efficient machines query machines, err := p.st.AllMachines() if err != nil { return results, err } for _, machine := range machines { if !canAccessFunc(machine.Tag()) { continue } if _, provisionedErr := machine.InstanceId(); provisionedErr == nil { // Machine may have been provisioned but machiner hasn't set the // status to Started yet. continue } result := params.StatusResult{} if result.Status, result.Info, result.Data, err = machine.Status(); err != nil { continue } if result.Status != params.StatusError { continue } // Transient errors are marked as such in the status data. if transient, ok := result.Data["transient"].(bool); !ok || !transient { continue } result.Id = machine.Id() result.Life = params.Life(machine.Life().String()) results.Results = append(results.Results, result) } return results, 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()) result.ContainerType = machine.ContainerType() } return }