Example #1
0
// APIWorker returns a Worker that connects to the API and starts any
// workers that need an API connection.
//
// If a state worker is necessary, APIWorker calls ensureStateWorker.
func (a *MachineAgent) APIWorker(ensureStateWorker func()) (worker.Worker, error) {
	st, entity, err := openAPIState(a.Conf.Conf, a)
	if err != nil {
		// There was an error connecting to the API,
		// https://launchpad.net/bugs/1199915 means that we may just
		// not have an API password set. So force a state connection at
		// this point.
		// TODO(jam): Once we can reliably trust that we have API
		//            passwords set, and we no longer need state
		//            connections (and possibly agents will be blocked
		//            from connecting directly to state) we can remove
		//            this. Currently needed because 1.10 does not set
		//            the API password and 1.11 requires it
		ensureStateWorker()
		return nil, err
	}
	needsStateWorker := false
	for _, job := range entity.Jobs() {
		needsStateWorker = needsStateWorker || stateJobs[job]
	}
	if needsStateWorker {
		ensureStateWorker()
	}
	runner := worker.NewRunner(allFatal, moreImportant)
	// Only the machiner currently connects to the API.
	// Add other workers here as they are ready.
	runner.StartWorker("machiner", func() (worker.Worker, error) {
		return machiner.NewMachiner(st.Machiner(), a.Tag()), nil
	})
	runner.StartWorker("upgrader", func() (worker.Worker, error) {
		// TODO(rog) use id instead of *Machine (or introduce Clone method)
		return upgrader.New(st.Upgrader(), a.Tag(), a.Conf.DataDir), nil
	})
	for _, job := range entity.Jobs() {
		switch job {
		case params.JobHostUnits:
			deployerTask, err := newDeployer(st.Deployer(), a.Tag(), a.Conf.DataDir)
			if err != nil {
				return nil, err
			}
			runner.StartWorker("deployer", func() (worker.Worker, error) {
				return deployerTask, nil
			})
		case params.JobManageEnviron:
			// Not yet implemented with the API.
		case params.JobManageState:
			// Not yet implemented with the API.
		default:
			// TODO(dimitern): Once all workers moved over to using
			// the API, report "unknown job type" here.
		}
	}
	return newCloseWorker(runner, st), nil // Note: a worker.Runner is itself a worker.Worker.
}
Example #2
0
func (a *UnitAgent) APIWorkers() (worker.Worker, error) {
	st, entity, err := openAPIState(a.Conf.Conf, a)
	if err != nil {
		return nil, err
	}
	dataDir := a.Conf.DataDir
	runner := worker.NewRunner(allFatal, moreImportant)
	runner.StartWorker("upgrader", func() (worker.Worker, error) {
		return upgrader.New(st.Upgrader(), entity.Tag(), dataDir), nil
	})
	return newCloseWorker(runner, st), nil
}
Example #3
0
func (s *UpgraderSuite) TestUpgraderRetryAndChanged(c *gc.C) {
	oldTools := s.primeTools(c, version.MustParseBinary("5.4.3-foo-bar"))
	newTools := s.uploadTools(c, version.MustParseBinary("5.4.5-foo-bar"))

	err := statetesting.SetAgentVersion(s.State, newTools.Version.Number)
	c.Assert(err, gc.IsNil)

	retryc := make(chan time.Time)
	*upgrader.RetryAfter = func() <-chan time.Time {
		c.Logf("replacement retry after")
		return retryc
	}
	dummy.Poison(s.Conn.Environ.Storage(), tools.StorageName(newTools.Version), fmt.Errorf("a non-fatal dose"))
	u := upgrader.New(s.state.Upgrader(), s.machine.Tag(), s.DataDir())
	defer u.Stop()

	for i := 0; i < 3; i++ {
		select {
		case retryc <- time.Now():
		case <-time.After(coretesting.LongWait):
			c.Fatalf("upgrader did not retry (attempt %d)", i)
		}
	}

	// Make it upgrade to some newer tools that can be
	// downloaded ok; it should stop retrying, download
	// the newer tools and exit.
	newerTools := s.uploadTools(c, version.MustParseBinary("5.4.6-foo-bar"))
	err = statetesting.SetAgentVersion(s.State, newerTools.Version.Number)
	c.Assert(err, gc.IsNil)

	s.BackingState.Sync()
	done := make(chan error)
	go func() {
		done <- u.Wait()
	}()
	select {
	case err := <-done:
		c.Assert(err, gc.DeepEquals, &upgrader.UpgradeReadyError{
			AgentName: s.machine.Tag(),
			OldTools:  oldTools,
			NewTools:  newerTools,
			DataDir:   s.DataDir(),
		})
	case <-time.After(coretesting.LongWait):
		c.Fatalf("upgrader did not quit after upgrading")
	}
}
Example #4
0
func (s *UpgraderSuite) TestUpgraderSetsTools(c *gc.C) {
	vers := version.MustParseBinary("5.4.3-foo-bar")
	err := statetesting.SetAgentVersion(s.State, vers.Number)
	c.Assert(err, gc.IsNil)
	agentTools := s.primeTools(c, vers)

	_, err = s.machine.AgentTools()
	c.Assert(err, jc.Satisfies, errors.IsNotFoundError)

	u := upgrader.New(s.state.Upgrader(), s.machine.Tag(), s.DataDir())
	statetesting.AssertStop(c, u)
	s.machine.Refresh()
	gotTools, err := s.machine.AgentTools()
	c.Assert(err, gc.IsNil)
	c.Assert(gotTools, gc.DeepEquals, agentTools)
}
Example #5
0
func (s *UpgraderSuite) TestUpgraderSetToolsEvenWithNoToolsToRead(c *gc.C) {
	vers := version.MustParseBinary("5.4.3-foo-bar")
	s.primeTools(c, vers)
	err := os.RemoveAll(filepath.Join(s.DataDir(), "tools"))
	c.Assert(err, gc.IsNil)

	_, err = s.machine.AgentTools()
	c.Assert(err, jc.Satisfies, errors.IsNotFoundError)
	err = statetesting.SetAgentVersion(s.State, vers.Number)
	c.Assert(err, gc.IsNil)

	u := upgrader.New(s.state.Upgrader(), s.machine.Tag(), s.DataDir())
	statetesting.AssertStop(c, u)
	s.machine.Refresh()
	gotTools, err := s.machine.AgentTools()
	c.Assert(err, gc.IsNil)
	c.Assert(gotTools, gc.DeepEquals, &tools.Tools{Version: version.Current})
}
Example #6
0
func (s *UpgraderSuite) TestUpgraderUpgradesImmediately(c *gc.C) {
	oldTools := s.primeTools(c, version.MustParseBinary("5.4.3-foo-bar"))
	newTools := s.uploadTools(c, version.MustParseBinary("5.4.5-foo-bar"))

	err := statetesting.SetAgentVersion(s.State, newTools.Version.Number)
	c.Assert(err, gc.IsNil)

	// Make the download take a while so that we verify that
	// the download happens before the upgrader checks if
	// it's been stopped.
	dummy.SetStorageDelay(coretesting.ShortWait)

	u := upgrader.New(s.state.Upgrader(), s.machine.Tag(), s.DataDir())
	err = u.Stop()
	c.Assert(err, gc.DeepEquals, &upgrader.UpgradeReadyError{
		AgentName: s.machine.Tag(),
		OldTools:  oldTools,
		NewTools:  newTools,
		DataDir:   s.DataDir(),
	})
	foundTools, err := tools.ReadTools(s.DataDir(), newTools.Version)
	c.Assert(err, gc.IsNil)
	c.Assert(foundTools, gc.DeepEquals, newTools)
}