// stateServerAddresses returns the list of internal addresses of the state // server machines. func (st *State) stateServerAddresses() ([]string, error) { type addressMachine struct { Addresses []address } var allAddresses []addressMachine // TODO(rog) 2013/10/14 index machines on jobs. err := st.machines.Find(bson.D{{"jobs", JobManageEnviron}}).All(&allAddresses) if err != nil { return nil, err } if len(allAddresses) == 0 { return nil, fmt.Errorf("no state server machines found") } apiAddrs := make([]string, 0, len(allAddresses)) for _, addrs := range allAddresses { instAddrs := addressesToInstanceAddresses(addrs.Addresses) addr := network.SelectInternalAddress(instAddrs, false) if addr != "" { apiAddrs = append(apiAddrs, addr) } } if len(apiAddrs) == 0 { return nil, fmt.Errorf("no state server machines with addresses found") } return apiAddrs, nil }
// PrivateAddress implements the server side of Client.PrivateAddress. func (c *Client) PrivateAddress(p params.PrivateAddress) (results params.PrivateAddressResults, err error) { switch { case names.IsValidMachine(p.Target): machine, err := c.api.state.Machine(p.Target) if err != nil { return results, err } addr := network.SelectInternalAddress(machine.Addresses(), false) if addr == "" { return results, fmt.Errorf("machine %q has no internal address", machine) } return params.PrivateAddressResults{PrivateAddress: addr}, nil case names.IsValidUnit(p.Target): unit, err := c.api.state.Unit(p.Target) if err != nil { return results, err } addr, ok := unit.PrivateAddress() if !ok { return results, fmt.Errorf("unit %q has no internal address", unit) } return params.PrivateAddressResults{PrivateAddress: addr}, nil } return results, fmt.Errorf("unknown unit or machine %q", p.Target) }
func (st *State) machineDocForTemplate(template MachineTemplate, id string) *machineDoc { // We ignore the error from Select*Address as an error indicates // no address is available, in which case the empty address is returned // and setting the preferred address to an empty one is the correct // thing to do when none is available. privateAddr, _ := network.SelectInternalAddress(template.Addresses, false) publicAddr, _ := network.SelectPublicAddress(template.Addresses) logger.Infof( "new machine %q has preferred addresses: private %q, public %q", id, privateAddr, publicAddr, ) return &machineDoc{ DocID: st.docID(id), Id: id, ModelUUID: st.ModelUUID(), Series: template.Series, Jobs: template.Jobs, Clean: !template.Dirty, Principals: template.principals, Life: Alive, Nonce: template.Nonce, Addresses: fromNetworkAddresses(template.Addresses, OriginMachine), PreferredPrivateAddress: fromNetworkAddress(privateAddr, OriginMachine), PreferredPublicAddress: fromNetworkAddress(publicAddr, OriginMachine), NoVote: template.NoVote, Placement: template.Placement, } }
// Restore implements the server side of Backups.Restore. func (a *API) Restore(p params.RestoreArgs) error { // Get hold of a backup file Reader backup, closer := newBackups(a.st) defer closer.Close() // Obtain the address of current machine, where we will be performing restore. machine, err := a.st.Machine(a.machineID) if err != nil { return errors.Trace(err) } addr := network.SelectInternalAddress(machine.Addresses(), false) if addr == "" { return errors.Errorf("machine %q has no internal address", machine) } publicAddress := network.SelectPublicAddress(machine.Addresses()) if publicAddress == "" { return errors.Errorf("machine %q has no public address", machine) } info, err := a.st.RestoreInfoSetter() if err != nil { return errors.Trace(err) } // Signal to current state and api server that restore will begin err = info.SetStatus(state.RestoreInProgress) if err != nil { return errors.Annotatef(err, "cannot set the server to %q mode", state.RestoreInProgress) } // Any abnormal termination of this function will mark restore as failed, // succesful termination will call Exit and never run this. defer info.SetStatus(state.RestoreFailed) instanceId, err := machine.InstanceId() if err != nil { return errors.Annotate(err, "cannot obtain instance id for machine to be restored") } logger.Infof("beginning server side restore of backup %q", p.BackupId) // Restore restoreArgs := backups.RestoreArgs{ PrivateAddress: addr, PublicAddress: publicAddress, NewInstId: instanceId, NewInstTag: machine.Tag(), NewInstSeries: machine.Series(), } if err := backup.Restore(p.BackupId, restoreArgs); err != nil { return errors.Annotate(err, "restore failed") } // After restoring, the api server needs a forced restart, tomb will not work // this is because we change all of juju configuration files and mongo too. // Exiting with 0 would prevent upstart to respawn the process os.Exit(1) return nil }
// PrivateAddress returns the private address of the unit and whether it is valid. func (u *Unit) PrivateAddress() (string, bool) { var privateAddress string addresses := u.addressesOfMachine() if len(addresses) > 0 { privateAddress = network.SelectInternalAddress(addresses, false) } return privateAddress, privateAddress != "" }
func (s *AddressSuite) TestSelectInternalMachineAddress(c *gc.C) { for i, t := range selectInternalMachineTests { c.Logf("test %d: %s", i, t.about) network.PreferIPv6 = t.preferIPv6 c.Check(network.SelectInternalAddress(t.addresses, true), gc.Equals, t.expected()) } network.PreferIPv6 = false }
func (s *AddressSuite) TestSelectInternalMachineAddress(c *gc.C) { for i, t := range selectInternalMachineTests { c.Logf("test %d: %s", i, t.about) expectAddr, expectOK := t.expected() actualAddr, actualOK := network.SelectInternalAddress(t.addresses, true) c.Check(actualOK, gc.Equals, expectOK) c.Check(actualAddr, gc.Equals, expectAddr) } }
func (s *AddressSuite) TestSelectInternalMachineAddress(c *gc.C) { oldValue := network.GetPreferIPv6() defer func() { network.SetPreferIPv6(oldValue) }() for i, t := range selectInternalMachineTests { c.Logf("test %d: %s", i, t.about) network.SetPreferIPv6(t.preferIPv6) c.Check(network.SelectInternalAddress(t.addresses, true), gc.Equals, t.expected()) } }
func (s *AddressSuite) TestSelectInternalAddress(c *gc.C) { oldValue := network.PreferIPv6() defer func() { network.SetPreferIPv6(oldValue) }() for i, t := range selectInternalTests { c.Logf("test %d: %s", i, t.about) network.SetPreferIPv6(t.preferIPv6) expectAddr, expectOK := t.expected() actualAddr, actualOK := network.SelectInternalAddress(t.addresses, false) c.Check(actualOK, gc.Equals, expectOK) c.Check(actualAddr, gc.Equals, expectAddr) } }
// remoteParamsForMachine returns a filled in RemoteExec instance // based on the machine, command and timeout params. If the machine // does not have an internal address, the Host is empty. This is caught // by the function that actually tries to execute the command. func remoteParamsForMachine(machine *state.Machine, command string, timeout time.Duration) *RemoteExec { // magic boolean parameters are bad :-( address, ok := network.SelectInternalAddress(machine.Addresses(), false) execParams := &RemoteExec{ ExecParams: ssh.ExecParams{ Command: command, Timeout: timeout, }, MachineId: machine.Id(), } if ok { execParams.Host = fmt.Sprintf("ubuntu@%s", address.Value) } return execParams }
// stateServerAddresses returns the list of internal addresses of the state // server machines. func (st *State) stateServerAddresses() ([]string, error) { ssState := st env, err := st.StateServerEnvironment() if err != nil { return nil, errors.Trace(err) } if st.EnvironTag() != env.EnvironTag() { // We are not using the state server environment, so get one. logger.Debugf("getting a state server state connection, current env: %s", st.EnvironTag()) ssState, err = st.ForEnviron(env.EnvironTag()) if err != nil { return nil, errors.Trace(err) } defer ssState.Close() logger.Debugf("ssState env: %s", ssState.EnvironTag()) } type addressMachine struct { Addresses []address } var allAddresses []addressMachine // TODO(rog) 2013/10/14 index machines on jobs. machines, closer := ssState.getCollection(machinesC) defer closer() err = machines.Find(bson.D{{"jobs", JobManageEnviron}}).All(&allAddresses) if err != nil { return nil, err } if len(allAddresses) == 0 { return nil, errors.New("no state server machines found") } apiAddrs := make([]string, 0, len(allAddresses)) for _, addrs := range allAddresses { naddrs := networkAddresses(addrs.Addresses) addr := network.SelectInternalAddress(naddrs, false) if addr != "" { apiAddrs = append(apiAddrs, addr) } } if len(apiAddrs) == 0 { return nil, errors.New("no state server machines with addresses found") } return apiAddrs, nil }
// controllerAddresses returns the list of internal addresses of the state // server machines. func (st *State) controllerAddresses() ([]string, error) { ssState := st model, err := st.ControllerModel() if err != nil { return nil, errors.Trace(err) } if st.ModelTag() != model.ModelTag() { // We are not using the controller model, so get one. logger.Debugf("getting a controller state connection, current env: %s", st.ModelTag()) ssState, err = st.ForModel(model.ModelTag()) if err != nil { return nil, errors.Trace(err) } defer ssState.Close() logger.Debugf("ssState env: %s", ssState.ModelTag()) } type addressMachine struct { Addresses []address } var allAddresses []addressMachine // TODO(rog) 2013/10/14 index machines on jobs. machines, closer := ssState.getCollection(machinesC) defer closer() err = machines.Find(bson.D{{"jobs", JobManageModel}}).All(&allAddresses) if err != nil { return nil, err } if len(allAddresses) == 0 { return nil, errors.New("no controller machines found") } apiAddrs := make([]string, 0, len(allAddresses)) for _, addrs := range allAddresses { naddrs := networkAddresses(addrs.Addresses) addr, ok := network.SelectInternalAddress(naddrs, false) if ok { apiAddrs = append(apiAddrs, addr.Value) } } if len(apiAddrs) == 0 { return nil, errors.New("no controller machines with addresses found") } return apiAddrs, nil }
// SelectPeerAddress returns the address to use as the // mongo replica set peer address by selecting it from the given addresses. func SelectPeerAddress(addrs []network.Address) string { return network.SelectInternalAddress(addrs, false) }
// SelectPeerAddress returns the address to use as the // mongo replica set peer address by selecting it from the given addresses. If // no addresses are available an empty string is returned. func SelectPeerAddress(addrs []network.Address) string { addr, _ := network.SelectInternalAddress(addrs, true) return addr.Value }
func (s *AddressSuite) TestSelectInternalAddress(c *gc.C) { for i, t := range selectInternalTests { c.Logf("test %d: %s", i, t.about) c.Check(network.SelectInternalAddress(t.addresses, false), gc.Equals, t.expected()) } }