func (s *ContainerSetupSuite) setupContainerWorker(c *gc.C, tag string) { runner := worker.NewRunner(allFatal, noImportance) pr := s.st.Provisioner() machine, err := pr.Machine(tag) c.Assert(err, gc.IsNil) err = machine.SetSupportedContainers(instance.ContainerTypes...) c.Assert(err, gc.IsNil) cfg := s.AgentConfigForTag(c, tag) watcherName := fmt.Sprintf("%s-container-watcher", machine.Id()) handler := provisioner.NewContainerSetupHandler(runner, watcherName, instance.ContainerTypes, machine, pr, cfg) runner.StartWorker(watcherName, func() (worker.Worker, error) { return worker.NewStringsWorker(handler), nil }) go func() { runner.Wait() }() }
// updateSupportedContainers records in state that a machine can run the specified containers. // It starts a watcher and when a container of a given type is first added to the machine, // the watcher is killed, the machine is set up to be able to start containers of the given type, // and a suitable provisioner is started. func (a *MachineAgent) updateSupportedContainers( runner worker.Runner, st *api.State, tag string, containers []instance.ContainerType, agentConfig agent.Config, ) error { pr := st.Provisioner() machine, err := pr.Machine(tag) if err != nil { return fmt.Errorf("%s is not in state: %v", tag, err) } if len(containers) == 0 { if err := machine.SupportsNoContainers(); err != nil { return fmt.Errorf("clearing supported containers for %s: %v", tag, err) } return nil } if err := machine.SetSupportedContainers(containers...); err != nil { return fmt.Errorf("setting supported containers for %s: %v", tag, err) } // Start the watcher to fire when a container is first requested on the machine. watcherName := fmt.Sprintf("%s-container-watcher", machine.Id()) handler := provisioner.NewContainerSetupHandler( runner, watcherName, containers, machine, pr, agentConfig, ) a.startWorkerAfterUpgrade(runner, watcherName, func() (worker.Worker, error) { return worker.NewStringsWorker(handler), nil }) return nil }