func (s *networkerSuite) TestNewNetworkerReturnsErrorWithoutConfig(c *gc.C) { _, err := os.Stat(networker.ConfigFileName) c.Assert(err, jc.Satisfies, os.IsNotExist) nw, err := networker.NewNetworker(s.networkerState, agentConfig(s.machine.Tag())) c.Assert(err, gc.ErrorMatches, `missing ".*" config file`) c.Assert(nw, gc.IsNil) }
func (s *MachineSuite) TestMachineAgentRunsSafeNetworkerWhenNetworkManagementIsDisabled(c *gc.C) { attrs := coretesting.Attrs{"disable-network-management": true} err := s.BackingState.UpdateEnvironConfig(attrs, nil, nil) c.Assert(err, gc.IsNil) started := make(chan struct{}, 1) nonSafeStarted := make(chan struct{}, 1) s.agentSuite.PatchValue(&newSafeNetworker, func(st *apinetworker.State, conf agent.Config, confDir string) (*networker.Networker, error) { select { case started <- struct{}{}: default: } return networker.NewSafeNetworker(st, conf, confDir) }) s.agentSuite.PatchValue(&newNetworker, func(st *apinetworker.State, conf agent.Config, confDir string) (*networker.Networker, error) { select { case nonSafeStarted <- struct{}{}: default: } return networker.NewNetworker(st, conf, confDir) }) m, _, _ := s.primeAgent(c, version.Current, state.JobHostUnits) a := s.newAgent(c, m) defer a.Stop() go func() { c.Check(a.Run(nil), gc.IsNil) }() select { case <-started: case <-nonSafeStarted: c.Fatalf("expected to start safe networker, but started a normal one") case <-time.After(coretesting.LongWait): c.Fatalf("timed out waiting for the safe networker worker to be started") } }
func (s *networkerSuite) newCustomNetworker( c *gc.C, facade apinetworker.State, machineId string, intrusiveMode bool, initInterfaces bool, ) (*networker.Networker, string) { if initInterfaces { s.upInterfaces = set.NewStrings("lo", "eth0") s.interfacesWithAddress = set.NewStrings("lo", "eth0") } s.lastCommands = make(chan []string) s.vlanModuleLoaded = false configDir := c.MkDir() nw, err := networker.NewNetworker(facade, agentConfig(machineId), intrusiveMode, configDir) c.Assert(err, jc.ErrorIsNil) c.Assert(nw, gc.NotNil) return nw, configDir }
func (s *networkerSuite) newCustomNetworker(c *gc.C, facade *apinetworker.State, machineId string, canWriteConfig, initInterfaces bool) (*networker.Networker, string) { if initInterfaces { s.upInterfaces = set.NewStrings("lo", "eth0") s.interfacesWithAddress = set.NewStrings("lo", "eth0") } s.lastCommands = make(chan []string) s.vlanModuleLoaded = false configDir := c.MkDir() var nw *networker.Networker var err error if canWriteConfig { nw, err = networker.NewNetworker(facade, agentConfig(machineId), configDir) } else { nw, err = networker.NewSafeNetworker(facade, agentConfig(machineId), configDir) } c.Assert(err, gc.IsNil) c.Assert(nw, gc.NotNil) return nw, configDir }
func (s *networkerSuite) TestNetworker(c *gc.C) { // Create a sample interfaces file (MAAS configuration) interfacesFileContents := fmt.Sprintf(sampleInterfacesFile, networker.ConfigDirName) err := utils.AtomicWriteFile(networker.ConfigFileName, []byte(interfacesFileContents), 0644) c.Assert(err, gc.IsNil) err = utils.AtomicWriteFile(filepath.Join(networker.ConfigDirName, "eth0.config"), []byte(sampleEth0DotConfigFile), 0644) c.Assert(err, gc.IsNil) // Patch the network interface functions s.PatchValue(&networker.InterfaceIsUp, func(name string) bool { return readyInterfaces.Contains(name) }) s.PatchValue(&networker.InterfaceHasAddress, func(name string) bool { return interfacesWithAddress.Contains(name) }) // Patch the command executor function s.configStates = []*configState{} s.PatchValue(&networker.ExecuteCommands, func(commands []string) error { return executeCommandsHook(c, s, commands) }, ) // Create and setup networker. s.executed = make(chan bool) nw, err := networker.NewNetworker(s.networkerState, agentConfig(s.machine.Tag())) c.Assert(err, gc.IsNil) defer func() { c.Assert(worker.Stop(nw), gc.IsNil) }() executeCount := 0 loop: for { select { case <-s.executed: executeCount++ if executeCount == 3 { break loop } case <-time.After(coretesting.ShortWait): fmt.Printf("%#v\n", s.configStates) c.Fatalf("command not executed") } } // Verify the executed commands from SetUp() expectedConfigFiles := networker.ConfigFiles{ networker.ConfigFileName: { Data: fmt.Sprintf(expectedInterfacesFile, networker.ConfigSubDirName, networker.ConfigSubDirName, networker.ConfigSubDirName, networker.ConfigSubDirName), }, networker.IfaceConfigFileName("br0"): { Data: "auto br0\niface br0 inet dhcp\n bridge_ports eth0\n", }, networker.IfaceConfigFileName("eth0"): { Data: "auto eth0\niface eth0 inet manual\n", }, networker.IfaceConfigFileName("wlan0"): { Data: "auto wlan0\niface wlan0 inet dhcp\n", }, } c.Assert(s.configStates[0].files, gc.DeepEquals, expectedConfigFiles) expectedCommands := []string(nil) c.Assert(s.configStates[0].commands, gc.DeepEquals, expectedCommands) c.Assert(s.configStates[0].readyInterfaces, gc.DeepEquals, []string{"br0", "eth0", "wlan0"}) c.Assert(s.configStates[0].interfacesWithAddress, gc.DeepEquals, []string{"br0", "wlan0"}) // Verify the executed commands from Handle() c.Assert(s.configStates[1].files, gc.DeepEquals, expectedConfigFiles) expectedCommands = []string(nil) c.Assert(s.configStates[1].commands, gc.DeepEquals, expectedCommands) c.Assert(s.configStates[1].readyInterfaces, gc.DeepEquals, []string{"br0", "eth0", "wlan0"}) c.Assert(s.configStates[1].interfacesWithAddress, gc.DeepEquals, []string{"br0", "wlan0"}) // Verify the executed commands from Handle() expectedConfigFiles[networker.IfaceConfigFileName("eth0.69")] = &networker.ConfigFile{ Data: "# Managed by Juju, don't change.\nauto eth0.69\niface eth0.69 inet dhcp\n\tvlan-raw-device eth0\n", } expectedConfigFiles[networker.IfaceConfigFileName("eth1")] = &networker.ConfigFile{ Data: "# Managed by Juju, don't change.\nauto eth1\niface eth1 inet dhcp\n", } expectedConfigFiles[networker.IfaceConfigFileName("eth1.42")] = &networker.ConfigFile{ Data: "# Managed by Juju, don't change.\nauto eth1.42\niface eth1.42 inet dhcp\n\tvlan-raw-device eth1\n", } expectedConfigFiles[networker.IfaceConfigFileName("eth2")] = &networker.ConfigFile{ Data: "# Managed by Juju, don't change.\nauto eth2\niface eth2 inet dhcp\n", } for k, _ := range s.configStates[2].files { c.Check(s.configStates[2].files[k], gc.DeepEquals, expectedConfigFiles[k]) } c.Assert(s.configStates[2].files, gc.DeepEquals, expectedConfigFiles) expectedCommands = []string{ "dpkg-query -s vlan || apt-get --option Dpkg::Options::=--force-confold --assume-yes install vlan", "lsmod | grep -q 8021q || modprobe 8021q", "grep -q 8021q /etc/modules || echo 8021q >> /etc/modules", "vconfig set_name_type DEV_PLUS_VID_NO_PAD", "ifup eth0.69", "ifup eth1", "ifup eth1.42", "ifup eth2", } c.Assert(s.configStates[2].commands, gc.DeepEquals, expectedCommands) c.Assert(s.configStates[2].readyInterfaces, gc.DeepEquals, []string{"br0", "eth0", "eth0.69", "eth1", "eth1.42", "eth2", "wlan0"}) c.Assert(s.configStates[2].interfacesWithAddress, gc.DeepEquals, []string{"br0", "eth0.69", "eth1", "eth1.42", "eth2", "wlan0"}) }
// APIWorker returns a Worker that connects to the API and starts any // workers that need an API connection. func (a *MachineAgent) APIWorker() (worker.Worker, error) { agentConfig := a.CurrentConfig() st, entity, err := openAPIState(agentConfig, a) if err != nil { return nil, err } reportOpenedAPI(st) // Refresh the configuration, since it may have been updated after opening state. agentConfig = a.CurrentConfig() for _, job := range entity.Jobs() { if job.NeedsState() { info, err := st.Agent().StateServingInfo() if err != nil { return nil, fmt.Errorf("cannot get state serving info: %v", err) } err = a.ChangeConfig(func(config agent.ConfigSetter) error { config.SetStateServingInfo(info) return nil }) if err != nil { return nil, err } agentConfig = a.CurrentConfig() break } } rsyslogMode := rsyslog.RsyslogModeForwarding runner := newRunner(connectionIsFatal(st), moreImportant) var singularRunner worker.Runner for _, job := range entity.Jobs() { if job == params.JobManageEnviron { rsyslogMode = rsyslog.RsyslogModeAccumulate conn := singularAPIConn{st, st.Agent()} singularRunner, err = newSingularRunner(runner, conn) if err != nil { return nil, fmt.Errorf("cannot make singular API Runner: %v", err) } break } } // Run the upgrader and the upgrade-steps worker without waiting for // the upgrade steps to complete. runner.StartWorker("upgrader", func() (worker.Worker, error) { return upgrader.NewUpgrader(st.Upgrader(), agentConfig), nil }) runner.StartWorker("upgrade-steps", func() (worker.Worker, error) { return a.upgradeWorkerContext.Worker(a, st, entity.Jobs()), nil }) // All other workers must wait for the upgrade steps to complete // before starting. a.startWorkerAfterUpgrade(runner, "machiner", func() (worker.Worker, error) { return machiner.NewMachiner(st.Machiner(), agentConfig), nil }) a.startWorkerAfterUpgrade(runner, "apiaddressupdater", func() (worker.Worker, error) { return apiaddressupdater.NewAPIAddressUpdater(st.Machiner(), a), nil }) a.startWorkerAfterUpgrade(runner, "logger", func() (worker.Worker, error) { return workerlogger.NewLogger(st.Logger(), agentConfig), nil }) a.startWorkerAfterUpgrade(runner, "machineenvironmentworker", func() (worker.Worker, error) { return machineenvironmentworker.NewMachineEnvironmentWorker(st.Environment(), agentConfig), nil }) a.startWorkerAfterUpgrade(runner, "rsyslog", func() (worker.Worker, error) { return newRsyslogConfigWorker(st.Rsyslog(), agentConfig, rsyslogMode) }) if networker.CanStart() { a.startWorkerAfterUpgrade(runner, "networker", func() (worker.Worker, error) { return networker.NewNetworker(st.Networker(), agentConfig) }) } else { logger.Infof("not starting networker - missing /etc/network/interfaces") } // If not a local provider bootstrap machine, start the worker to // manage SSH keys. providerType := agentConfig.Value(agent.ProviderType) if providerType != provider.Local || a.MachineId != bootstrapMachineId { a.startWorkerAfterUpgrade(runner, "authenticationworker", func() (worker.Worker, error) { return authenticationworker.NewWorker(st.KeyUpdater(), agentConfig), nil }) } // Perform the operations needed to set up hosting for containers. if err := a.setupContainerSupport(runner, st, entity, agentConfig); err != nil { return nil, fmt.Errorf("setting up container support: %v", err) } for _, job := range entity.Jobs() { switch job { case params.JobHostUnits: a.startWorkerAfterUpgrade(runner, "deployer", func() (worker.Worker, error) { apiDeployer := st.Deployer() context := newDeployContext(apiDeployer, agentConfig) return deployer.NewDeployer(apiDeployer, context), nil }) case params.JobManageEnviron: a.startWorkerAfterUpgrade(singularRunner, "environ-provisioner", func() (worker.Worker, error) { return provisioner.NewEnvironProvisioner(st.Provisioner(), agentConfig), nil }) // TODO(axw) 2013-09-24 bug #1229506 // Make another job to enable the firewaller. Not all // environments are capable of managing ports // centrally. a.startWorkerAfterUpgrade(singularRunner, "firewaller", func() (worker.Worker, error) { return firewaller.NewFirewaller(st.Firewaller()) }) a.startWorkerAfterUpgrade(singularRunner, "charm-revision-updater", func() (worker.Worker, error) { return charmrevisionworker.NewRevisionUpdateWorker(st.CharmRevisionUpdater()), nil }) case params.JobManageStateDeprecated: // Legacy environments may set this, but we ignore it. 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. }