func (s *environSuite) TestInvalidConfig(c *gc.C) { var oldType string oldType = s.Conn.Environ.Config().AllAttrs()["type"].(string) // Create an invalid config by taking the current config and // tweaking the provider type. info := s.StateInfo(c) opts := state.DefaultDialOpts() st2, err := state.Open(info, opts, state.Policy(nil)) c.Assert(err, gc.IsNil) defer st2.Close() err = st2.UpdateEnvironConfig(map[string]interface{}{"type": "unknown"}, nil, nil) c.Assert(err, gc.IsNil) w := st2.WatchForEnvironConfigChanges() defer stopWatcher(c, w) done := make(chan environs.Environ) go func() { env, err := worker.WaitForEnviron(w, st2, nil) c.Check(err, gc.IsNil) done <- env }() // Wait for the loop to process the invalid configuratrion <-worker.LoadedInvalid st2.UpdateEnvironConfig(map[string]interface{}{ "type": oldType, "secret": "environ_test", }, nil, nil) env := <-done c.Assert(env, gc.NotNil) c.Assert(env.Config().AllAttrs()["secret"], gc.Equals, "environ_test") }
func (s *environSuite) TestStop(c *gc.C) { w := s.State.WatchForEnvironConfigChanges() defer stopWatcher(c, w) stop := make(chan struct{}) done := make(chan error) go func() { env, err := worker.WaitForEnviron(w, s.State, stop) c.Check(env, gc.IsNil) done <- err }() close(stop) c.Assert(<-done, gc.Equals, tomb.ErrDying) }
func (p *environProvisioner) loop() error { var environConfigChanges <-chan struct{} environWatcher, err := p.st.WatchForEnvironConfigChanges() if err != nil { return err } environConfigChanges = environWatcher.Changes() defer watcher.Stop(environWatcher, &p.tomb) p.environ, err = worker.WaitForEnviron(environWatcher, p.st, p.tomb.Dying()) if err != nil { return err } p.broker = p.environ safeMode := p.environ.Config().ProvisionerSafeMode() task, err := p.getStartTask(safeMode) if err != nil { return err } defer watcher.Stop(task, &p.tomb) for { select { case <-p.tomb.Dying(): return tomb.ErrDying case <-task.Dying(): err := task.Err() logger.Errorf("environ provisioner died: %v", err) return err case _, ok := <-environConfigChanges: if !ok { return watcher.MustErr(environWatcher) } environConfig, err := p.st.EnvironConfig() if err != nil { logger.Errorf("cannot load environment configuration: %v", err) return err } if err := p.setConfig(environConfig); err != nil { logger.Errorf("loaded invalid environment configuration: %v", err) } task.SetSafeMode(environConfig.ProvisionerSafeMode()) } } }
func (fw *Firewaller) loop() error { defer fw.stopWatchers() var err error var reconciled bool fw.environ, err = worker.WaitForEnviron(fw.environWatcher, fw.st, fw.tomb.Dying()) if err != nil { return err } if fw.environ.Config().FirewallMode() == config.FwGlobal { fw.globalMode = true fw.globalPortRef = make(map[instance.Port]int) } for { select { case <-fw.tomb.Dying(): return tomb.ErrDying case _, ok := <-fw.environWatcher.Changes(): if !ok { return watcher.MustErr(fw.environWatcher) } config, err := fw.st.EnvironConfig() if err != nil { return err } if err := fw.environ.SetConfig(config); err != nil { logger.Errorf("loaded invalid environment configuration: %v", err) } case change, ok := <-fw.machinesWatcher.Changes(): if !ok { return watcher.MustErr(fw.machinesWatcher) } for _, machineId := range change { fw.machineLifeChanged(names.MachineTag(machineId)) } if !reconciled { reconciled = true var err error if fw.globalMode { err = fw.reconcileGlobal() } else { err = fw.reconcileInstances() } if err != nil { return err } } case change := <-fw.unitsChange: if err := fw.unitsChanged(change); err != nil { return err } case change := <-fw.portsChange: change.unitd.ports = change.ports if err := fw.flushUnits([]*unitData{change.unitd}); err != nil { return errgo.Annotate(err, "cannot change firewall ports") } case change := <-fw.exposedChange: change.serviced.exposed = change.exposed unitds := []*unitData{} for _, unitd := range change.serviced.unitds { unitds = append(unitds, unitd) } if err := fw.flushUnits(unitds); err != nil { return errgo.Annotate(err, "cannot change firewall ports") } } } }