func (s *CommonProvisionerSuite) assertProvisionerObservesConfigChanges(c *gc.C, p provisioner.Provisioner) { // Inject our observer into the provisioner cfgObserver := make(chan *config.Config, 1) provisioner.SetObserver(p, cfgObserver) // Switch to reaping on All machines. attrs := map[string]interface{}{ config.ProvisionerHarvestModeKey: config.HarvestAll.String(), } err := s.State.UpdateEnvironConfig(attrs, nil, nil) c.Assert(err, jc.ErrorIsNil) s.BackingState.StartSync() // Wait for the PA to load the new configuration. We wait for the change we expect // like this because sometimes we pick up the initial harvest config (destroyed) // rather than the one we change to (all). received := []string{} for { select { case newCfg := <-cfgObserver: if newCfg.ProvisionerHarvestMode().String() == config.HarvestAll.String() { return } received = append(received, newCfg.ProvisionerHarvestMode().String()) case <-time.After(coretesting.LongWait): if len(received) == 0 { c.Fatalf("PA did not action config change") } else { c.Fatalf("timed out waiting for config to change to '%s', received %+v", config.HarvestAll.String(), received) } } } }
func (s *ProvisionerSuite) TestProvisionerObservesConfigChanges(c *gc.C) { p := s.newEnvironProvisioner(c) defer stop(c, p) // create a machine m0, err := s.addMachine() c.Assert(err, gc.IsNil) i0 := s.checkStartInstance(c, m0) // create a second machine m1, err := s.addMachine() c.Assert(err, gc.IsNil) i1 := s.checkStartInstance(c, m1) // mark the first machine as dead c.Assert(m0.EnsureDead(), gc.IsNil) // remove the second machine entirely from state c.Assert(m1.EnsureDead(), gc.IsNil) c.Assert(m1.Remove(), gc.IsNil) // We default to the destroyed method. Only the one we know is // dead should be stopped; not the unknown instance. s.checkStopSomeInstances(c, []instance.Instance{i0}, []instance.Instance{i1}) s.waitRemoved(c, m0) // insert our observer cfgObserver := make(chan *config.Config, 1) provisioner.SetObserver(p, cfgObserver) // Switch to reaping on Destroyed machines. attrs := map[string]interface{}{ "provisioner-harvest-mode": config.HarvestDestroyed.String(), } err = s.State.UpdateEnvironConfig(attrs, nil, nil) c.Assert(err, gc.IsNil) s.BackingState.StartSync() // wait for the PA to load the new configuration select { case newCfg := <-cfgObserver: c.Assert( newCfg.ProvisionerHarvestMode().String(), gc.Equals, config.HarvestDestroyed.String(), ) case <-time.After(coretesting.LongWait): c.Fatalf("PA did not action config change") } m3, err := s.addMachine() c.Assert(err, gc.IsNil) s.checkStartInstance(c, m3) }
func (s *ProvisionerSuite) TestProvisioningRecoversAfterInvalidEnvironmentPublished(c *gc.C) { s.PatchValue(provisioner.GetToolsFinder, func(*apiprovisioner.State) provisioner.ToolsFinder { return mockToolsFinder{} }) p := s.newEnvironProvisioner(c) defer stop(c, p) // place a new machine into the state m, err := s.addMachine() c.Assert(err, gc.IsNil) s.checkStartInstance(c, m) s.invalidateEnvironment(c) s.BackingState.StartSync() // create a second machine m, err = s.addMachine() c.Assert(err, gc.IsNil) // the PA should create it using the old environment s.checkStartInstance(c, m) err = s.fixEnvironment(c) c.Assert(err, gc.IsNil) // insert our observer cfgObserver := make(chan *config.Config, 1) provisioner.SetObserver(p, cfgObserver) err = s.State.UpdateEnvironConfig(map[string]interface{}{"secret": "beef"}, nil, nil) c.Assert(err, gc.IsNil) s.BackingState.StartSync() // wait for the PA to load the new configuration select { case <-cfgObserver: case <-time.After(coretesting.LongWait): c.Fatalf("PA did not action config change") } // create a third machine m, err = s.addMachine() c.Assert(err, gc.IsNil) // the PA should create it using the new environment s.checkStartInstanceCustom(c, m, "beef", s.defaultConstraints, nil, nil, nil, true) }
func (s *ProvisionerSuite) TestProvisioningSafeModeChange(c *gc.C) { p := s.newEnvironProvisioner(c) defer stop(c, p) // First check that safe mode is initially off. // create a machine m0, err := s.addMachine() c.Assert(err, gc.IsNil) i0 := s.checkStartInstance(c, m0) // create a second machine m1, err := s.addMachine() c.Assert(err, gc.IsNil) i1 := s.checkStartInstance(c, m1) // mark the first machine as dead c.Assert(m0.EnsureDead(), gc.IsNil) // remove the second machine entirely from state c.Assert(m1.EnsureDead(), gc.IsNil) c.Assert(m1.Remove(), gc.IsNil) s.checkStopInstances(c, i0, i1) s.waitRemoved(c, m0) // insert our observer cfgObserver := make(chan *config.Config, 1) provisioner.SetObserver(p, cfgObserver) // turn on safe mode attrs := map[string]interface{}{"provisioner-safe-mode": true} err = s.State.UpdateEnvironConfig(attrs, nil, nil) c.Assert(err, gc.IsNil) s.BackingState.StartSync() // wait for the PA to load the new configuration select { case <-cfgObserver: case <-time.After(coretesting.LongWait): c.Fatalf("PA did not action config change") } // Now check that the provisioner has noticed safe mode is on. // create a machine m3, err := s.addMachine() c.Assert(err, gc.IsNil) i3 := s.checkStartInstance(c, m3) // create an instance out of band i4 := s.startUnknownInstance(c, "999") // mark the machine as dead c.Assert(m3.EnsureDead(), gc.IsNil) // check the machine's instance is stopped, and the other isn't s.checkStopSomeInstances(c, []instance.Instance{i3}, []instance.Instance{i4}) s.waitRemoved(c, m3) }