func (s *MachineSuite) TestMachineAgentRunsAPIAddressUpdaterWorker(c *gc.C) { // Start the machine agent. m, _, _ := s.primeAgent(c, version.Current, state.JobHostUnits) a := s.newAgent(c, m) go func() { c.Check(a.Run(nil), gc.IsNil) }() defer func() { c.Check(a.Stop(), gc.IsNil) }() // Update the API addresses. updatedServers := [][]instance.HostPort{instance.AddressesWithPort( instance.NewAddresses("localhost"), 1234, )} err := s.BackingState.SetAPIHostPorts(updatedServers) c.Assert(err, gc.IsNil) // Wait for config to be updated. s.BackingState.StartSync() for attempt := coretesting.LongAttempt.Start(); attempt.Next(); { addrs, err := a.CurrentConfig().APIAddresses() c.Assert(err, gc.IsNil) if reflect.DeepEqual(addrs, []string{"localhost:1234"}) { return } } c.Fatalf("timeout while waiting for agent config to change") }
func (s *APIAddressUpdaterSuite) TestAddressChange(c *gc.C) { setter := &apiAddressSetter{servers: make(chan [][]instance.HostPort, 1)} st, _ := s.OpenAPIAsNewMachine(c, state.JobHostUnits) worker := apiaddressupdater.NewAPIAddressUpdater(st.Machiner(), setter) defer func() { c.Assert(worker.Wait(), gc.IsNil) }() defer worker.Kill() s.BackingState.StartSync() updatedServers := [][]instance.HostPort{instance.AddressesWithPort( instance.NewAddresses("localhost", "127.0.0.1"), 1234, )} // SetAPIHostPorts should be called with the initial value (empty), // and then the updated value. select { case <-time.After(coretesting.LongWait): c.Fatalf("timed out waiting for SetAPIHostPorts to be called first") case servers := <-setter.servers: c.Assert(servers, gc.HasLen, 0) } err := s.State.SetAPIHostPorts(updatedServers) c.Assert(err, gc.IsNil) s.BackingState.StartSync() select { case <-time.After(coretesting.LongWait): c.Fatalf("timed out waiting for SetAPIHostPorts to be called second") case servers := <-setter.servers: c.Assert(servers, gc.DeepEquals, updatedServers) } }
// testNamespace starts a worker and ensures that // the rsyslog config file has the expected filename, // and the appropriate log dir is used. func (s *RsyslogSuite) testNamespace(c *gc.C, st *api.State, tag, namespace, expectedFilename, expectedLogDir string) { restarted := make(chan struct{}, 2) // once for create, once for teardown s.PatchValue(rsyslog.RestartRsyslog, func() error { restarted <- struct{}{} return nil }) err := os.MkdirAll(expectedLogDir, 0755) c.Assert(err, gc.IsNil) worker, err := rsyslog.NewRsyslogConfigWorker(st.Rsyslog(), rsyslog.RsyslogModeForwarding, tag, namespace, []string{"0.1.2.3"}) c.Assert(err, gc.IsNil) defer func() { c.Assert(worker.Wait(), gc.IsNil) }() defer worker.Kill() // change the API HostPorts to trigger an rsyslog restart newHostPorts := instance.AddressesWithPort(instance.NewAddresses("127.0.0.1"), 6541) err = s.State.SetAPIHostPorts([][]instance.HostPort{newHostPorts}) c.Assert(err, gc.IsNil) // Wait for rsyslog to be restarted, so we can check to see // what the name of the config file is. waitForRestart(c, restarted) // Ensure that ca-cert.pem gets written to the expected log dir. waitForFile(c, filepath.Join(expectedLogDir, "ca-cert.pem")) dir, err := os.Open(*rsyslog.RsyslogConfDir) c.Assert(err, gc.IsNil) names, err := dir.Readdirnames(-1) dir.Close() c.Assert(err, gc.IsNil) c.Assert(names, gc.HasLen, 1) c.Assert(names[0], gc.Equals, expectedFilename) }
func parseHostPort(s string) (instance.HostPort, error) { addr, port, err := net.SplitHostPort(s) if err != nil { return instance.HostPort{}, err } portNum, err := strconv.Atoi(port) if err != nil { return instance.HostPort{}, fmt.Errorf("bad port number %q", port) } addrs := instance.NewAddresses(addr) hostPorts := instance.AddressesWithPort(addrs, portNum) return hostPorts[0], nil }
func (m *fakeMachine) setStateHostPort(hostPort string) { var mongoHostPorts []instance.HostPort if hostPort != "" { host, portStr, err := net.SplitHostPort(hostPort) if err != nil { panic(err) } port, err := strconv.Atoi(portStr) if err != nil { panic(err) } mongoHostPorts = instance.AddressesWithPort(instance.NewAddresses(host), port) mongoHostPorts[0].NetworkScope = instance.NetworkCloudLocal } m.mutate(func(doc *machineDoc) { doc.mongoHostPorts = mongoHostPorts }) }
// newRsyslogConfig creates a new instance of the RsyslogConfig. func newRsyslogConfig(envCfg *config.Config, api *RsyslogAPI) (*apirsyslog.RsyslogConfig, error) { stateAddrsResult, err := api.StateAddresser.StateAddresses() if err != nil { return nil, err } port := envCfg.SyslogPort() var bareAddrs []string for _, addr := range stateAddrsResult.Result { hostOnly, _, err := net.SplitHostPort(addr) if err != nil { return nil, err } bareAddrs = append(bareAddrs, hostOnly) } apiAddresses := instance.NewAddresses(bareAddrs...) return &apirsyslog.RsyslogConfig{ CACert: envCfg.RsyslogCACert(), Port: port, HostPorts: instance.AddressesWithPort(apiAddresses, port), }, nil }
// StartInstance is specified in the InstanceBroker interface. func (e *environ) StartInstance(args environs.StartInstanceParams) (instance.Instance, *instance.HardwareCharacteristics, []network.Info, error) { defer delay() machineId := args.MachineConfig.MachineId logger.Infof("dummy startinstance, machine %s", machineId) if err := e.checkBroken("StartInstance"); err != nil { return nil, nil, nil, err } estate, err := e.state() if err != nil { return nil, nil, nil, err } estate.mu.Lock() defer estate.mu.Unlock() if args.MachineConfig.MachineNonce == "" { return nil, nil, nil, fmt.Errorf("cannot start instance: missing machine nonce") } if _, ok := e.Config().CACert(); !ok { return nil, nil, nil, fmt.Errorf("no CA certificate in environment configuration") } if args.MachineConfig.StateInfo.Tag != names.MachineTag(machineId) { return nil, nil, nil, fmt.Errorf("entity tag must match started machine") } if args.MachineConfig.APIInfo.Tag != names.MachineTag(machineId) { return nil, nil, nil, fmt.Errorf("entity tag must match started machine") } logger.Infof("would pick tools from %s", args.Tools) series := args.Tools.OneSeries() idString := fmt.Sprintf("%s-%d", e.name, estate.maxId) i := &dummyInstance{ id: instance.Id(idString), addresses: instance.NewAddresses(idString + ".dns"), ports: make(map[instance.Port]bool), machineId: machineId, series: series, firewallMode: e.Config().FirewallMode(), state: estate, } var hc *instance.HardwareCharacteristics // To match current system capability, only provide hardware characteristics for // environ machines, not containers. if state.ParentId(machineId) == "" { // We will just assume the instance hardware characteristics exactly matches // the supplied constraints (if specified). hc = &instance.HardwareCharacteristics{ Arch: args.Constraints.Arch, Mem: args.Constraints.Mem, RootDisk: args.Constraints.RootDisk, CpuCores: args.Constraints.CpuCores, CpuPower: args.Constraints.CpuPower, Tags: args.Constraints.Tags, } // Fill in some expected instance hardware characteristics if constraints not specified. if hc.Arch == nil { arch := "amd64" hc.Arch = &arch } if hc.Mem == nil { mem := uint64(1024) hc.Mem = &mem } if hc.RootDisk == nil { disk := uint64(8192) hc.RootDisk = &disk } if hc.CpuCores == nil { cores := uint64(1) hc.CpuCores = &cores } } // Simulate networks added when requested. networkInfo := make([]network.Info, len(args.MachineConfig.IncludeNetworks)) for i, netName := range args.MachineConfig.IncludeNetworks { if strings.HasPrefix(netName, "bad-") { // Simulate we didn't get correct information for the network. networkInfo[i] = network.Info{ ProviderId: network.Id(netName), NetworkName: netName, CIDR: "invalid", } } else { networkInfo[i] = network.Info{ ProviderId: network.Id(netName), NetworkName: netName, CIDR: fmt.Sprintf("0.%d.2.0/24", i+1), InterfaceName: fmt.Sprintf("eth%d", i), VLANTag: i, MACAddress: fmt.Sprintf("aa:bb:cc:dd:ee:f%d", i), IsVirtual: i > 0, } } } estate.insts[i.id] = i estate.maxId++ estate.ops <- OpStartInstance{ Env: e.name, MachineId: machineId, MachineNonce: args.MachineConfig.MachineNonce, Constraints: args.Constraints, IncludeNetworks: args.MachineConfig.IncludeNetworks, ExcludeNetworks: args.MachineConfig.ExcludeNetworks, NetworkInfo: networkInfo, Instance: i, Info: args.MachineConfig.StateInfo, APIInfo: args.MachineConfig.APIInfo, Secret: e.ecfg().secret(), } return i, hc, networkInfo, nil }
func addressesWithPort(port int, addrs ...string) []instance.HostPort { return instance.AddressesWithPort(instance.NewAddresses(addrs...), port) }
func newTestInstance(status string, addresses []string) *testInstance { thisInstance := testInstance{status: status} thisInstance.addresses = instance.NewAddresses(addresses...) return &thisInstance }