func NewLxcBroker(config *config.Config, tools *state.Tools) Broker { return &lxcBroker{ manager: lxc.NewContainerManager(lxc.ManagerConfig{Name: "juju"}), config: config, tools: tools, } }
func (s *LxcSuite) TestListContainers(c *gc.C) { foo := lxc.NewContainerManager(lxc.ManagerConfig{Name: "foo"}) bar := lxc.NewContainerManager(lxc.ManagerConfig{Name: "bar"}) foo1 := StartContainer(c, foo, "1/lxc/0") foo2 := StartContainer(c, foo, "1/lxc/1") foo3 := StartContainer(c, foo, "1/lxc/2") bar1 := StartContainer(c, bar, "1/lxc/0") bar2 := StartContainer(c, bar, "1/lxc/1") result, err := foo.ListContainers() c.Assert(err, gc.IsNil) testing.MatchInstances(c, result, foo1, foo2, foo3) result, err = bar.ListContainers() c.Assert(err, gc.IsNil) testing.MatchInstances(c, result, bar1, bar2) }
func (s *LxcSuite) TestStopContainer(c *gc.C) { manager := lxc.NewContainerManager(lxc.ManagerConfig{}) instance := StartContainer(c, manager, "1/lxc/0") err := manager.StopContainer(instance) c.Assert(err, gc.IsNil) name := string(instance.Id()) // Check that the container dir is no longer in the container dir c.Assert(filepath.Join(s.ContainerDir, name), jc.DoesNotExist) // but instead, in the removed container dir c.Assert(filepath.Join(s.RemovedDir, name), jc.IsDirectory) }
func (s *LxcSuite) TestStartContainer(c *gc.C) { manager := lxc.NewContainerManager(lxc.ManagerConfig{}) instance := StartContainer(c, manager, "1/lxc/0") name := string(instance.Id()) // Check our container config files. lxcConfContents, err := ioutil.ReadFile(filepath.Join(s.ContainerDir, name, "lxc.conf")) c.Assert(err, gc.IsNil) c.Assert(string(lxcConfContents), jc.Contains, "lxc.network.link = nic42") cloudInitFilename := filepath.Join(s.ContainerDir, name, "cloud-init") c.Assert(cloudInitFilename, jc.IsNonEmptyFile) data, err := ioutil.ReadFile(cloudInitFilename) c.Assert(err, gc.IsNil) c.Assert(string(data), jc.HasPrefix, "#cloud-config\n") x := make(map[interface{}]interface{}) err = goyaml.Unmarshal(data, &x) c.Assert(err, gc.IsNil) c.Assert(x["apt_proxy"], gc.Equals, aptHTTPProxy) var scripts []string for _, s := range x["runcmd"].([]interface{}) { scripts = append(scripts, s.(string)) } c.Assert(scripts[len(scripts)-4:], gc.DeepEquals, []string{ "start jujud-machine-1-lxc-0", "install -m 644 /dev/null '/etc/apt/apt.conf.d/99proxy-extra'", fmt.Sprintf("echo '%s' > '/etc/apt/apt.conf.d/99proxy-extra'", configProxyExtra), "ifconfig", }) // Check the mount point has been created inside the container. c.Assert(filepath.Join(s.LxcDir, name, "rootfs/var/log/juju"), jc.IsDirectory) // Check that the config file is linked in the restart dir. expectedLinkLocation := filepath.Join(s.RestartDir, name+".conf") expectedTarget := filepath.Join(s.LxcDir, name, "config") linkInfo, err := os.Lstat(expectedLinkLocation) c.Assert(err, gc.IsNil) c.Assert(linkInfo.Mode()&os.ModeSymlink, gc.Equals, os.ModeSymlink) location, err := os.Readlink(expectedLinkLocation) c.Assert(err, gc.IsNil) c.Assert(location, gc.Equals, expectedTarget) }
func (s *LxcSuite) TestStopContainerNameClash(c *gc.C) { manager := lxc.NewContainerManager(lxc.ManagerConfig{}) instance := StartContainer(c, manager, "1/lxc/0") name := string(instance.Id()) targetDir := filepath.Join(s.RemovedDir, name) err := os.MkdirAll(targetDir, 0755) c.Assert(err, gc.IsNil) err = manager.StopContainer(instance) c.Assert(err, gc.IsNil) // Check that the container dir is no longer in the container dir c.Assert(filepath.Join(s.ContainerDir, name), jc.DoesNotExist) // but instead, in the removed container dir with a ".1" suffix as there was already a directory there. c.Assert(filepath.Join(s.RemovedDir, fmt.Sprintf("%s.1", name)), jc.IsDirectory) }
// EnsureWeHaveLXC checks if we have lxc installed, and installs it if we // don't. Juju 1.11 added the ability to deploy into LXC containers, and uses // functionality from the lxc package in order to do so. Juju 1.10 did not // install lxc, so we ensure it is installed. // See http://bugs.launchpad.net/bug/1199913 // dataDir is the root location where data files are put. It is used to grab // the uniter-hook-execution lock so that we don't try run to apt-get at the // same time that a hook might want to run it. func EnsureWeHaveLXC(dataDir, machineTag string) error { // We need to short circuit this in two places: // 1. if we are running a local provider, then the machines are lxc // containers, and if we install lxc on them, it adds an lxc bridge // network device with the same ip address as the hosts bridge. This // screws up all the networking routes. // 2. if the machine is an lxc container, we need to avoid installing lxc // package for exactly the same reasons. // Later, post-precise LTS, when we have updated lxc, we can bring this // back in to have nested lxc, but until then, we have to avoid it. containerType := state.ContainerTypeFromId(state.MachineIdFromTag(machineTag)) providerType := os.Getenv("JUJU_PROVIDER_TYPE") if providerType == provider.Local || containerType == instance.LXC { return nil } manager := lxc.NewContainerManager(lxc.ManagerConfig{Name: "lxc-test"}) if _, err := manager.ListContainers(); err == nil { validationLogger.Debugf("found lxc, not installing") // We already have it, nothing more to do return nil } validationLogger.Debugf("got error looking for lxc, attempting to install") if dataDir != "" { lock, err := getUniterLock(dataDir, "apt-get install lxc for juju 1.11 upgrade") if err == nil { defer lock.Unlock() } else { validationLogger.Warningf("Failed to acquire lock: %v, will try to install lxc anyway", lock) } // If we got an error trying to acquire the lock, we try to install // lxc anyway. Worst case the install will fail, which is where we // are already } // TODO: This is not platform independent. If jujud is running on // something other than a debian-based Linux, and we are missing // lxc, this call will always fail. However, in juju 1.11+ we // install lxc via cloud-init or whatever bootstrap code we use. // So this is really only upgrade compatibility and juju 1.10 // only supports debian-based anyway return utils.AptGetInstall("lxc") }
// SetConfig is specified in the Environ interface. func (env *localEnviron) SetConfig(cfg *config.Config) error { config, err := provider.newConfig(cfg) if err != nil { logger.Errorf("failed to create new environ config: %v", err) return err } env.localMutex.Lock() defer env.localMutex.Unlock() env.config = config env.name = config.Name() env.containerManager = lxc.NewContainerManager( lxc.ManagerConfig{ Name: env.config.namespace(), LogDir: env.config.logDir(), }) // Here is the end of normal config setting. if config.bootstrapped() { return nil } return env.bootstrapAddressAndStorage(cfg) }
func (s *LxcSuite) TestStartContainer(c *gc.C) { manager := lxc.NewContainerManager(lxc.ManagerConfig{}) instance := StartContainer(c, manager, "1/lxc/0") name := string(instance.Id()) // Check our container config files. c.Assert(filepath.Join(s.ContainerDir, name, "lxc.conf"), jc.IsNonEmptyFile) cloudInitFilename := filepath.Join(s.ContainerDir, name, "cloud-init") c.Assert(cloudInitFilename, jc.IsNonEmptyFile) data, err := ioutil.ReadFile(cloudInitFilename) c.Assert(err, gc.IsNil) c.Assert(string(data), jc.HasPrefix, "#cloud-config\n") x := make(map[interface{}]interface{}) err = goyaml.Unmarshal(data, &x) c.Assert(err, gc.IsNil) var scripts []string for _, s := range x["runcmd"].([]interface{}) { scripts = append(scripts, s.(string)) } c.Assert(scripts[len(scripts)-1], gc.Equals, "start jujud-machine-1-lxc-0") // Check the mount point has been created inside the container. c.Assert(filepath.Join(s.LxcDir, name, "rootfs/var/log/juju"), jc.IsDirectory) // Check that the config file is linked in the restart dir. expectedLinkLocation := filepath.Join(s.RestartDir, name+".conf") expectedTarget := filepath.Join(s.LxcDir, name, "config") linkInfo, err := os.Lstat(expectedLinkLocation) c.Assert(err, gc.IsNil) c.Assert(linkInfo.Mode()&os.ModeSymlink, gc.Equals, os.ModeSymlink) location, err := os.Readlink(expectedLinkLocation) c.Assert(err, gc.IsNil) c.Assert(location, gc.Equals, expectedTarget) }
func (s *LxcSuite) TestNamedManagerPrefix(c *gc.C) { manager := lxc.NewContainerManager(lxc.ManagerConfig{Name: "eric"}) instance := StartContainer(c, manager, "1/lxc/0") c.Assert(string(instance.Id()), gc.Equals, "eric-machine-1-lxc-0") }