// upgradeWaiterWorker runs the specified worker after upgrades have completed. func (a *MachineAgent) upgradeWaiterWorker(start func() (worker.Worker, error)) worker.Worker { return worker.NewSimpleWorker(func(stop <-chan struct{}) error { // wait for the upgrade to complete (or for us to be stopped) select { case <-stop: return nil case <-a.upgradeComplete: } w, err := start() if err != nil { return err } waitCh := make(chan error) go func() { waitCh <- w.Wait() }() select { case err := <-waitCh: return err case <-stop: w.Kill() } return <-waitCh }) }
// upgradeWorker runs the required upgrade operations to upgrade to the current Juju version. func (a *MachineAgent) upgradeWorker( apiState *api.State, jobs []params.MachineJob, agentConfig agent.Config, ) worker.Worker { return worker.NewSimpleWorker(func(stop <-chan struct{}) error { select { case <-a.upgradeComplete: // Our work is already done (we're probably being restarted // because the API connection has gone down), so do nothing. <-stop return nil default: } // If the machine agent is a state server, wait until state is opened. needsState := false for _, job := range jobs { if job == params.JobManageEnviron { needsState = true } } // We need a *state.State for upgrades. We open it independently // of StateWorker, because we have no guarantees about when // and how often StateWorker might run. var st *state.State if needsState { var err error info, ok := agentConfig.StateInfo() if !ok { return fmt.Errorf("no state info available") } st, err = state.Open(info, state.DialOpts{}, environs.NewStatePolicy()) if err != nil { return err } defer st.Close() } err := a.runUpgrades(st, apiState, jobs, agentConfig) if err != nil { return err } logger.Infof("upgrade to %v completed.", version.Current) close(a.upgradeComplete) <-stop return nil }) }
func newDummyWorker() worker.Worker { return worker.NewSimpleWorker(func(stop <-chan struct{}) error { <-stop return nil }) }
// newStateStarterWorker wraps stateStarter in a simple worker for use in // a.runner.StartWorker. func (a *MachineAgent) newStateStarterWorker() (worker.Worker, error) { return worker.NewSimpleWorker(a.stateStarter), nil }