示例#1
0
func (s *WaitSuite) TestConfigError(c *gc.C) {
	fix := &fixture{
		observerErrs: []error{
			errors.New("biff zonk"),
		},
	}
	fix.Run(c, func(context *runContext) {
		abort := make(chan struct{})
		defer close(abort)

		done := make(chan struct{})
		go func() {
			defer close(done)
			env, err := environ.WaitForEnviron(context.watcher, context, nil, abort)
			c.Check(env, gc.IsNil)
			c.Check(err, gc.ErrorMatches, "cannot read environ config: biff zonk")
		}()

		context.SendNotify()
		select {
		case <-done:
		case <-time.After(coretesting.LongWait):
			c.Errorf("timed out waiting for failure")
		}
		workertest.CheckAlive(c, context.watcher)
	})
}
示例#2
0
func (fw *Firewaller) setUp() error {
	var err error
	fw.modelWatcher, err = fw.st.WatchForModelConfigChanges()
	if err != nil {
		return errors.Trace(err)
	}
	if err := fw.catacomb.Add(fw.modelWatcher); err != nil {
		return errors.Trace(err)
	}

	// We won't "wait" actually, because the environ is already
	// available and has a guaranteed valid config, but until
	// WaitForEnviron goes away, this code needs to stay.
	fw.environ, err = environ.WaitForEnviron(fw.modelWatcher, fw.st, environs.New, fw.catacomb.Dying())
	if err != nil {
		if err == environ.ErrWaitAborted {
			return fw.catacomb.ErrDying()
		}
		return errors.Trace(err)
	}
	switch fw.environ.Config().FirewallMode() {
	case config.FwInstance:
	case config.FwGlobal:
		fw.globalMode = true
		fw.globalPortRef = make(map[network.PortRange]int)
	case config.FwNone:
		logger.Infof("stopping firewaller (not required)")
		fw.Kill()
		return fw.catacomb.ErrDying()
	default:
		return errors.Errorf("unknown firewall-mode %q", config.FwNone)
	}

	fw.machinesWatcher, err = fw.st.WatchModelMachines()
	if err != nil {
		return errors.Trace(err)
	}
	if err := fw.catacomb.Add(fw.machinesWatcher); err != nil {
		return errors.Trace(err)
	}

	fw.portsWatcher, err = fw.st.WatchOpenedPorts()
	if err != nil {
		return errors.Annotatef(err, "failed to start ports watcher")
	}
	if err := fw.catacomb.Add(fw.portsWatcher); err != nil {
		return errors.Trace(err)
	}

	logger.Debugf("started watching opened port ranges for the environment")
	return nil
}
示例#3
0
func (fw *Firewaller) setUp() error {
	var err error
	fw.modelWatcher, err = fw.st.WatchForModelConfigChanges()
	if err != nil {
		return errors.Trace(err)
	}
	if err := fw.catacomb.Add(fw.modelWatcher); err != nil {
		return errors.Trace(err)
	}

	// We won't "wait" actually, because the environ is already
	// available and has a guaranteed valid config, but until
	// WaitForEnviron goes away, this code needs to stay.
	fw.environ, err = environ.WaitForEnviron(fw.modelWatcher, fw.st, fw.catacomb.Dying())
	if err != nil {
		if err == environ.ErrWaitAborted {
			return fw.catacomb.ErrDying()
		}
		return errors.Trace(err)
	}
	switch fw.environ.Config().FirewallMode() {
	case config.FwGlobal:
		fw.globalMode = true
		fw.globalPortRef = make(map[network.PortRange]int)
	case config.FwNone:
		logger.Warningf("stopping firewaller - firewall-mode is %q", config.FwNone)
		// XXX(fwereade): shouldn't this be nil? Nothing wrong, nothing to do,
		// now that we've logged there's no further reason to complain or retry.
		return errors.Errorf("firewaller is disabled when firewall-mode is %q", config.FwNone)
	}

	fw.machinesWatcher, err = fw.st.WatchModelMachines()
	if err != nil {
		return errors.Trace(err)
	}
	if err := fw.catacomb.Add(fw.machinesWatcher); err != nil {
		return errors.Trace(err)
	}

	fw.portsWatcher, err = fw.st.WatchOpenedPorts()
	if err != nil {
		return errors.Annotatef(err, "failed to start ports watcher")
	}
	if err := fw.catacomb.Add(fw.portsWatcher); err != nil {
		return errors.Trace(err)
	}

	logger.Debugf("started watching opened port ranges for the environment")
	return nil
}
示例#4
0
func (p *environProvisioner) loop() error {
	var environConfigChanges <-chan struct{}
	environWatcher, err := p.st.WatchForEnvironConfigChanges()
	if err != nil {
		return loggedErrorStack(errors.Trace(err))
	}
	if err := p.catacomb.Add(environWatcher); err != nil {
		return errors.Trace(err)
	}
	environConfigChanges = environWatcher.Changes()

	p.environ, err = environ.WaitForEnviron(environWatcher, p.st, p.catacomb.Dying())
	if err != nil {
		if err == environ.ErrWaitAborted {
			return p.catacomb.ErrDying()
		}
		return loggedErrorStack(errors.Trace(err))
	}
	p.broker = p.environ

	harvestMode := p.environ.Config().ProvisionerHarvestMode()
	task, err := p.getStartTask(harvestMode)
	if err != nil {
		return loggedErrorStack(errors.Trace(err))
	}
	if err := p.catacomb.Add(task); err != nil {
		return errors.Trace(err)
	}

	for {
		select {
		case <-p.catacomb.Dying():
			return p.catacomb.ErrDying()
		case _, ok := <-environConfigChanges:
			if !ok {
				return errors.New("environment configuration watcher closed")
			}
			environConfig, err := p.st.EnvironConfig()
			if err != nil {
				return errors.Annotate(err, "cannot load environment configuration")
			}
			if err := p.setConfig(environConfig); err != nil {
				return errors.Annotate(err, "loaded invalid environment configuration")
			}
			task.SetHarvestMode(environConfig.ProvisionerHarvestMode())
		}
	}
}
示例#5
0
func (s *WaitSuite) TestIgnoresBadConfig(c *gc.C) {
	fix := &fixture{
		initialConfig: coretesting.Attrs{
			"type": "unknown",
		},
	}
	newEnvironFunc := func(cfg *config.Config) (environs.Environ, error) {
		if cfg.Type() == "unknown" {
			return nil, errors.NotValidf("config")
		}
		return &mockEnviron{cfg: cfg}, nil
	}
	fix.Run(c, func(context *runContext) {
		abort := make(chan struct{})
		defer close(abort)

		done := make(chan struct{})
		go func() {
			defer close(done)
			env, err := environ.WaitForEnviron(context.watcher, context, newEnvironFunc, abort)
			if c.Check(err, jc.ErrorIsNil) {
				c.Check(env.Config().Name(), gc.Equals, "expected-name")
			}
		}()

		context.SendNotify()
		select {
		case <-time.After(coretesting.ShortWait):
		case <-done:
			c.Errorf("completed unexpectedly")
		}

		context.SetConfig(c, coretesting.Attrs{
			"name": "expected-name",
		})
		context.SendNotify()
		select {
		case <-done:
		case <-time.After(coretesting.LongWait):
			c.Errorf("timed out waiting for success")
		}
		workertest.CheckAlive(c, context.watcher)
	})
}
示例#6
0
func (s *WaitSuite) TestWaitAborted(c *gc.C) {
	fix := &fixture{}
	fix.Run(c, func(context *runContext) {
		abort := make(chan struct{})
		done := make(chan struct{})
		go func() {
			defer close(done)
			env, err := environ.WaitForEnviron(context.watcher, nil, nil, abort)
			c.Check(env, gc.IsNil)
			c.Check(err, gc.Equals, environ.ErrWaitAborted)
		}()

		close(abort)
		select {
		case <-done:
		case <-time.After(coretesting.LongWait):
			c.Errorf("timed out waiting for abort")
		}
		workertest.CheckAlive(c, context.watcher)
	})
}