// newAgent returns a new MachineAgent instance func (s *commonMachineSuite) newAgent(c *gc.C, m *state.Machine) *MachineAgent { a := &MachineAgent{} s.initAgent(c, a, "--machine-id", m.Id()) err := a.ReadConfig(m.Tag()) c.Assert(err, gc.IsNil) return a }
// waitRemoved waits for the supplied machine to be removed from state. func (s *CommonProvisionerSuite) waitRemoved(c *gc.C, m *state.Machine) { s.waitMachine(c, m, func() bool { err := m.Refresh() if errors.IsNotFound(err) { return true } c.Assert(err, gc.IsNil) c.Logf("machine %v is still %s", m, m.Life()) return false }) }
func (s *lxcProvisionerSuite) expectStarted(c *gc.C, machine *state.Machine) string { s.State.StartSync() event := <-s.events c.Assert(event.Action, gc.Equals, mock.Created) event = <-s.events c.Assert(event.Action, gc.Equals, mock.Started) err := machine.Refresh() c.Assert(err, gc.IsNil) s.waitInstanceId(c, machine, instance.Id(event.InstanceId)) return event.InstanceId }
// waitInstanceId waits until the supplied machine has an instance id, then // asserts it is as expected. func (s *CommonProvisionerSuite) waitInstanceId(c *gc.C, m *state.Machine, expect instance.Id) { s.waitHardwareCharacteristics(c, m, func() bool { if actual, err := m.InstanceId(); err == nil { c.Assert(actual, gc.Equals, expect) return true } else if !state.IsNotProvisionedError(err) { // We don't expect any errors. panic(err) } c.Logf("machine %v is still unprovisioned", m) return false }) }
func (s *CommonProvisionerSuite) checkStartInstanceCustom(c *gc.C, m *state.Machine, secret string, cons constraints.Value, includeNetworks, excludeNetworks []string, networkInfo []network.Info, waitInstanceId bool) (inst instance.Instance) { s.BackingState.StartSync() for { select { case o := <-s.op: switch o := o.(type) { case dummy.OpStartInstance: inst = o.Instance if waitInstanceId { s.waitInstanceId(c, m, inst.Id()) } // Check the instance was started with the expected params. c.Assert(o.MachineId, gc.Equals, m.Id()) nonceParts := strings.SplitN(o.MachineNonce, ":", 2) c.Assert(nonceParts, gc.HasLen, 2) c.Assert(nonceParts[0], gc.Equals, names.MachineTag("0")) c.Assert(nonceParts[1], jc.Satisfies, utils.IsValidUUIDString) c.Assert(o.Secret, gc.Equals, secret) c.Assert(o.IncludeNetworks, jc.DeepEquals, includeNetworks) c.Assert(o.ExcludeNetworks, jc.DeepEquals, excludeNetworks) c.Assert(o.NetworkInfo, jc.DeepEquals, networkInfo) // All provisioned machines in this test suite have // their hardware characteristics attributes set to // the same values as the constraints due to the dummy // environment being used. if !constraints.IsEmpty(&cons) { c.Assert(o.Constraints, gc.DeepEquals, cons) hc, err := m.HardwareCharacteristics() c.Assert(err, gc.IsNil) c.Assert(*hc, gc.DeepEquals, instance.HardwareCharacteristics{ Arch: cons.Arch, Mem: cons.Mem, RootDisk: cons.RootDisk, CpuCores: cons.CpuCores, CpuPower: cons.CpuPower, Tags: cons.Tags, }) } return default: c.Logf("ignoring unexpected operation %#v", o) } case <-time.After(2 * time.Second): c.Fatalf("provisioner did not start an instance") return } } return }
func (s *commonMachineSuite) setFakeMachineAddresses(c *gc.C, machine *state.Machine) { addrs := []instance.Address{ instance.NewAddress("0.1.2.3", instance.NetworkUnknown), } err := machine.SetAddresses(addrs...) c.Assert(err, gc.IsNil) // Set the addresses in the environ instance as well so that if the instance poller // runs it won't overwrite them. instId, err := machine.InstanceId() c.Assert(err, gc.IsNil) insts, err := s.Conn.Environ.Instances([]instance.Id{instId}) c.Assert(err, gc.IsNil) dummy.SetInstanceAddresses(insts[0], addrs) }
func newMachineToolWaiter(m *state.Machine) *toolsWaiter { w := m.Watch() waiter := &toolsWaiter{ changes: make(chan struct{}, 1), watcher: w, tooler: m, } go func() { for _ = range w.Changes() { waiter.changes <- struct{}{} } close(waiter.changes) }() return waiter }
func (t *LiveTests) assertStartInstance(c *gc.C, m *state.Machine) { // Wait for machine to get an instance id. for a := waitAgent.Start(); a.Next(); { err := m.Refresh() c.Assert(err, gc.IsNil) instId, err := m.InstanceId() if err != nil { c.Assert(err, jc.Satisfies, state.IsNotProvisionedError) continue } _, err = t.Env.Instances([]instance.Id{instId}) c.Assert(err, gc.IsNil) return } c.Fatalf("provisioner failed to start machine after %v", waitAgent.Total) }
func (s *CommonProvisionerSuite) waitHardwareCharacteristics(c *gc.C, m *state.Machine, check func() bool) { w := m.WatchHardwareCharacteristics() defer stop(c, w) timeout := time.After(coretesting.LongWait) resync := time.After(0) for { select { case <-w.Changes(): if check() { return } case <-resync: resync = time.After(coretesting.ShortWait) s.BackingState.StartSync() case <-timeout: c.Fatalf("hardware characteristics for machine %v wait timed out", m) } } }
// assertInstanceId asserts that the machine has an instance id // that matches that of the given instance. If the instance is nil, // It asserts that the instance id is unset. func assertInstanceId(c *gc.C, m *state.Machine, inst instance.Instance) { var wantId, gotId instance.Id var err error if inst != nil { wantId = inst.Id() } for a := waitAgent.Start(); a.Next(); { err := m.Refresh() c.Assert(err, gc.IsNil) gotId, err = m.InstanceId() if err != nil { c.Assert(err, jc.Satisfies, state.IsNotProvisionedError) if inst == nil { return } continue } break } c.Assert(err, gc.IsNil) c.Assert(gotId, gc.Equals, wantId) }
func (s *CommonProvisionerSuite) APILogin(c *gc.C, machine *state.Machine) { if s.st != nil { c.Assert(s.st.Close(), gc.IsNil) } password, err := utils.RandomPassword() c.Assert(err, gc.IsNil) err = machine.SetPassword(password) c.Assert(err, gc.IsNil) err = machine.SetProvisioned("i-fake", "fake_nonce", nil) c.Assert(err, gc.IsNil) s.st = s.OpenAPIAsMachine(c, machine.Tag(), password, "fake_nonce") c.Assert(s.st, gc.NotNil) c.Logf("API: login as %q successful", machine.Tag()) s.provisioner = s.st.Provisioner() c.Assert(s.provisioner, gc.NotNil) }
func (s *CommonProvisionerSuite) waitMachine(c *gc.C, m *state.Machine, check func() bool) { // TODO(jam): We need to grow a new method on NotifyWatcherC // that calls StartSync while waiting for changes, then // waitMachine and waitHardwareCharacteristics can use that // instead w := m.Watch() defer stop(c, w) timeout := time.After(coretesting.LongWait) resync := time.After(0) for { select { case <-w.Changes(): if check() { return } case <-resync: resync = time.After(coretesting.ShortWait) s.BackingState.StartSync() case <-timeout: c.Fatalf("machine %v wait timed out", m) } } }
// startInstance starts a new instance for the given machine. func (s *FirewallerSuite) startInstance(c *gc.C, m *state.Machine) instance.Instance { inst, hc := testing.AssertStartInstance(c, s.Conn.Environ, m.Id()) err := m.SetProvisioned(inst.Id(), "fake_nonce", hc) c.Assert(err, gc.IsNil) return inst }
func (s *SSHCommonSuite) setAddresses(m *state.Machine, c *gc.C) { addrPub := instance.NewAddress(fmt.Sprintf("dummyenv-%s.dns", m.Id()), instance.NetworkPublic) addrPriv := instance.NewAddress(fmt.Sprintf("dummyenv-%s.internal", m.Id()), instance.NetworkCloudLocal) err := m.SetAddresses(addrPub, addrPriv) c.Assert(err, gc.IsNil) }
// Run initializes state for an environment. func (c *BootstrapCommand) Run(_ *cmd.Context) error { envCfg, err := config.New(config.NoDefaults, c.EnvConfig) if err != nil { return err } err = c.ReadConfig("machine-0") if err != nil { return err } agentConfig := c.CurrentConfig() // agent.Jobs is an optional field in the agent config, and was // introduced after 1.17.2. We default to allowing units on // machine-0 if missing. jobs := agentConfig.Jobs() if len(jobs) == 0 { jobs = []params.MachineJob{ params.JobManageEnviron, params.JobHostUnits, } } // Get the bootstrap machine's addresses from the provider. env, err := environs.New(envCfg) if err != nil { return err } instanceId := instance.Id(c.InstanceId) instances, err := env.Instances([]instance.Id{instanceId}) if err != nil { return err } addrs, err := instances[0].Addresses() if err != nil { return err } // Create system-identity file if err := agent.WriteSystemIdentityFile(agentConfig); err != nil { return err } // Generate a shared secret for the Mongo replica set, and write it out. sharedSecret, err := mongo.GenerateSharedSecret() if err != nil { return err } info, ok := agentConfig.StateServingInfo() if !ok { return fmt.Errorf("bootstrap machine config has no state serving info") } info.SharedSecret = sharedSecret err = c.ChangeConfig(func(agentConfig agent.ConfigSetter) { agentConfig.SetStateServingInfo(info) }) if err != nil { return fmt.Errorf("cannot write agent config: %v", err) } agentConfig = c.CurrentConfig() if err := c.startMongo(addrs, agentConfig); err != nil { return err } logger.Infof("started mongo") // Initialise state, and store any agent config (e.g. password) changes. var st *state.State var m *state.Machine err = nil writeErr := c.ChangeConfig(func(agentConfig agent.ConfigSetter) { st, m, err = agent.InitializeState( agentConfig, envCfg, agent.BootstrapMachineConfig{ Addresses: addrs, Constraints: c.Constraints, Jobs: jobs, InstanceId: instanceId, Characteristics: c.Hardware, SharedSecret: sharedSecret, }, state.DefaultDialOpts(), environs.NewStatePolicy(), ) }) if writeErr != nil { return fmt.Errorf("cannot write initial configuration: %v", err) } if err != nil { return err } defer st.Close() // bootstrap machine always gets the vote return m.SetHasVote(true) }