// EnsureAvailabilitySingle applies a single StateServersSpec specification to the current environment. // Exported so it can be called by the legacy client API in the client package. func EnsureAvailabilitySingle(st *state.State, spec params.StateServersSpec) (params.StateServersChanges, error) { if !st.IsStateServer() { return params.StateServersChanges{}, errors.New("unsupported with hosted environments") } // Check if changes are allowed and the command may proceed. blockChecker := common.NewBlockChecker(st) if err := blockChecker.ChangeAllowed(); err != nil { return params.StateServersChanges{}, errors.Trace(err) } // Validate the environment tag if present. if spec.EnvironTag != "" { tag, err := names.ParseEnvironTag(spec.EnvironTag) if err != nil { return params.StateServersChanges{}, errors.Errorf("invalid environment tag: %v", err) } if _, err := st.FindEntity(tag); err != nil { return params.StateServersChanges{}, err } } series := spec.Series if series == "" { ssi, err := st.StateServerInfo() if err != nil { return params.StateServersChanges{}, err } // We should always have at least one voting machine // If we *really* wanted we could just pick whatever series is // in the majority, but really, if we always copy the value of // the first one, then they'll stay in sync. if len(ssi.VotingMachineIds) == 0 { // Better than a panic()? return params.StateServersChanges{}, fmt.Errorf("internal error, failed to find any voting machines") } templateMachine, err := st.Machine(ssi.VotingMachineIds[0]) if err != nil { return params.StateServersChanges{}, err } series = templateMachine.Series() } changes, err := st.EnsureAvailability(spec.NumStateServers, spec.Constraints, series, spec.Placement) if err != nil { return params.StateServersChanges{}, err } return stateServersChanges(changes), nil }
// environManagerInstances returns all environ manager instances. func environManagerInstances(st *state.State) ([]instance.Id, error) { info, err := st.StateServerInfo() if err != nil { return nil, err } instances := make([]instance.Id, 0, len(info.MachineIds)) for _, id := range info.MachineIds { machine, err := st.Machine(id) if err != nil { return nil, err } instanceId, err := machine.InstanceId() if err == nil { instances = append(instances, instanceId) } else if !state.IsNotProvisionedError(err) { return nil, err } } return instances, nil }