func (s *LxcSuite) TestCreateContainerWithBlockStorage(c *gc.C) { err := os.Remove(s.RestartDir) c.Assert(err, jc.ErrorIsNil) manager := s.makeManager(c, "test") machineConfig, err := containertesting.MockMachineConfig("1/lxc/0") c.Assert(err, jc.ErrorIsNil) storageConfig := &container.StorageConfig{AllowMount: true} networkConfig := container.BridgeNetworkConfig("nic42", 4321, nil) instance := containertesting.CreateContainerWithMachineAndNetworkAndStorageConfig(c, manager, machineConfig, networkConfig, storageConfig) name := string(instance.Id()) autostartLink := lxc.RestartSymlink(name) config, err := ioutil.ReadFile(lxc.ContainerConfigFilename(name)) c.Assert(err, jc.ErrorIsNil) expected := fmt.Sprintf(` # network config # interface "eth0" lxc.network.type = veth lxc.network.link = nic42 lxc.network.flags = up lxc.network.mtu = 4321 lxc.start.auto = 1 lxc.mount.entry = %s var/log/juju none defaults,bind 0 0 lxc.aa_profile = lxc-container-default-with-mounting lxc.cgroup.devices.allow = b 7:* rwm lxc.cgroup.devices.allow = c 10:237 rwm `, s.logDir) c.Assert(string(config), gc.Equals, expected) c.Assert(autostartLink, jc.DoesNotExist) }
func (s *LxcSuite) createTemplate(c *gc.C) golxc.Container { name := "juju-series-template" ch := s.ensureTemplateStopped(name) defer func() { <-ch }() network := container.BridgeNetworkConfig("nic42") authorizedKeys := "authorized keys list" aptProxy := proxy.Settings{} template, err := lxc.EnsureCloneTemplate( "ext4", "series", network, authorizedKeys, aptProxy) c.Assert(err, gc.IsNil) c.Assert(template.Name(), gc.Equals, name) s.AssertEvent(c, <-s.events, mock.Created, name) s.AssertEvent(c, <-s.events, mock.Started, name) s.AssertEvent(c, <-s.events, mock.Stopped, name) autostartLink := lxc.RestartSymlink(name) config, err := ioutil.ReadFile(lxc.ContainerConfigFilename(name)) c.Assert(err, gc.IsNil) expected := ` lxc.network.type = veth lxc.network.link = nic42 lxc.network.flags = up ` // NOTE: no autostart, no mounting the log dir c.Assert(string(config), gc.Equals, expected) c.Assert(autostartLink, jc.DoesNotExist) return template }
func (s *LxcSuite) createTemplate(c *gc.C) golxc.Container { name := "juju-quantal-lxc-template" ch := s.ensureTemplateStopped(name) defer func() { <-ch }() network := container.BridgeNetworkConfig("nic42", 4321, nil) authorizedKeys := "authorized keys list" aptProxy := proxy.Settings{} aptMirror := "http://my.archive.ubuntu.com/ubuntu" callback := func(containerStatus status.Status, info string, data map[string]interface{}) error { return nil } template, err := lxc.EnsureCloneTemplate( "ext4", "quantal", network, authorizedKeys, aptProxy, aptMirror, true, true, &containertesting.MockURLGetter{}, false, callback, ) c.Assert(err, jc.ErrorIsNil) c.Assert(template.Name(), gc.Equals, name) createEvent := <-s.events c.Assert(createEvent.Action, gc.Equals, mock.Created) c.Assert(createEvent.InstanceId, gc.Equals, name) argsSet := set.NewStrings(createEvent.TemplateArgs...) c.Assert(argsSet.Contains("imageURL"), jc.IsTrue) s.AssertEvent(c, <-s.events, mock.Started, name) s.AssertEvent(c, <-s.events, mock.Stopped, name) autostartLink := lxc.RestartSymlink(name) config, err := ioutil.ReadFile(lxc.ContainerConfigFilename(name)) c.Assert(err, jc.ErrorIsNil) expected := ` # network config # interface "eth0" lxc.network.type = veth lxc.network.link = nic42 lxc.network.flags = up lxc.network.mtu = 4321 ` // NOTE: no autostart, no mounting the log dir c.Assert(string(config), gc.Equals, expected) c.Assert(autostartLink, jc.DoesNotExist) return template }
func (s *LxcSuite) TestCreateContainerWithCloneMountsAndAutostarts(c *gc.C) { s.createTemplate(c) s.PatchValue(&s.useClone, true) manager := s.makeManager(c, "test") instance := containertesting.CreateContainer(c, manager, "1") name := string(instance.Id()) autostartLink := lxc.RestartSymlink(name) config, err := ioutil.ReadFile(lxc.ContainerConfigFilename(name)) c.Assert(err, gc.IsNil) mountLine := "lxc.mount.entry=/var/log/juju var/log/juju none defaults,bind 0 0" c.Assert(string(config), jc.Contains, mountLine) c.Assert(autostartLink, jc.IsSymlink) }
func (s *LxcSuite) TestCreateContainer(c *gc.C) { manager := s.makeManager(c, "test") instance := containertesting.CreateContainer(c, manager, "1/lxc/0") name := string(instance.Id()) // Check our container config files: initial lxc.conf, the // run-time effective config, and cloud-init userdata. lxcConfContents, err := ioutil.ReadFile(filepath.Join(s.ContainerDir, name, "lxc.conf")) c.Assert(err, jc.ErrorIsNil) c.Assert(string(lxcConfContents), jc.Contains, "lxc.network.link = nic42") lxcConfContents, err = ioutil.ReadFile(lxc.ContainerConfigFilename(name)) c.Assert(err, jc.ErrorIsNil) c.Assert(string(lxcConfContents), jc.Contains, "lxc.network.link = nic42") cloudInitFilename := filepath.Join(s.ContainerDir, name, "cloud-init") data := containertesting.AssertCloudInit(c, cloudInitFilename) x := make(map[interface{}]interface{}) err = goyaml.Unmarshal(data, &x) c.Assert(err, jc.ErrorIsNil) var scripts []string for _, s := range x["runcmd"].([]interface{}) { scripts = append(scripts, s.(string)) } c.Assert(scripts[len(scripts)-3:], gc.DeepEquals, []string{ "start jujud-machine-1-lxc-0", "rm $bin/tools.tar.gz && rm $bin/juju2.3.4-quantal-amd64.sha256", "ifconfig", }) // Check the mount point has been created inside the container. c.Assert(filepath.Join(s.LxcDir, name, "rootfs", agent.DefaultPaths.LogDir), 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, jc.ErrorIsNil) c.Assert(linkInfo.Mode()&os.ModeSymlink, gc.Equals, os.ModeSymlink) location, err := symlink.Read(expectedLinkLocation) c.Assert(err, jc.ErrorIsNil) c.Assert(location, gc.Equals, expectedTarget) }
func (s *LxcSuite) TestCreateContainerNoRestartDir(c *gc.C) { err := os.Remove(s.RestartDir) c.Assert(err, gc.IsNil) manager := s.makeManager(c, "test") instance := containertesting.CreateContainer(c, manager, "1/lxc/0") name := string(instance.Id()) autostartLink := lxc.RestartSymlink(name) config, err := ioutil.ReadFile(lxc.ContainerConfigFilename(name)) c.Assert(err, gc.IsNil) expected := ` lxc.network.type = veth lxc.network.link = nic42 lxc.network.flags = up lxc.start.auto = 1 lxc.mount.entry=/var/log/juju var/log/juju none defaults,bind 0 0 ` c.Assert(string(config), gc.Equals, expected) c.Assert(autostartLink, jc.DoesNotExist) }
func (s *LxcSuite) TestUpdateContainerConfig(c *gc.C) { networkConfig := container.BridgeNetworkConfig("nic42", 4321, []network.InterfaceInfo{{ DeviceIndex: 0, CIDR: "0.1.2.0/20", InterfaceName: "eth0", MACAddress: "aa:bb:cc:dd:ee:f0", Address: network.NewAddress("0.1.2.3"), GatewayAddress: network.NewAddress("0.1.2.1"), }, { DeviceIndex: 1, InterfaceName: "eth1", }}) storageConfig := &container.StorageConfig{ AllowMount: true, } manager := s.makeManager(c, "test") instanceConfig, err := containertesting.MockMachineConfig("1/lxc/0") c.Assert(err, jc.ErrorIsNil) envConfig, err := config.New(config.NoDefaults, dummy.SampleConfig()) c.Assert(err, jc.ErrorIsNil) instanceConfig.Config = envConfig instance := containertesting.CreateContainerWithMachineAndNetworkAndStorageConfig( c, manager, instanceConfig, networkConfig, storageConfig, ) name := string(instance.Id()) // Append a few extra lines to the config. extraLines := []string{ " lxc.rootfs = /some/thing # else ", "", " # just comment", "lxc.network.vlan.id=42", "something else # ignore", "lxc.network.type=veth", "lxc.network.link = foo # comment", "lxc.network.hwaddr = bar", } configPath := lxc.ContainerConfigFilename(name) configFile, err := os.OpenFile(configPath, os.O_RDWR|os.O_APPEND, 0644) c.Assert(err, jc.ErrorIsNil) _, err = configFile.WriteString(strings.Join(extraLines, "\n") + "\n") c.Assert(err, jc.ErrorIsNil) err = configFile.Close() c.Assert(err, jc.ErrorIsNil) expectedConf := fmt.Sprintf(` # network config # interface "eth0" lxc.network.type = veth lxc.network.link = nic42 lxc.network.flags = up lxc.network.name = eth0 lxc.network.hwaddr = aa:bb:cc:dd:ee:f0 lxc.network.ipv4 = 0.1.2.3/20 lxc.network.ipv4.gateway = 0.1.2.1 # interface "eth1" lxc.network.type = veth lxc.network.link = nic42 lxc.network.flags = up lxc.network.name = eth1 lxc.mount.entry = %s var/log/juju none defaults,bind 0 0 lxc.aa_profile = lxc-container-default-with-mounting lxc.cgroup.devices.allow = b 7:* rwm lxc.cgroup.devices.allow = c 10:237 rwm `, s.logDir) + strings.Join(extraLines, "\n") + "\n" lxcConfContents, err := ioutil.ReadFile(configPath) c.Assert(err, jc.ErrorIsNil) c.Assert(string(lxcConfContents), gc.Equals, expectedConf) linesToReplace := []string{ "", // empty lines are ignored " lxc.network.type = bar # free drinks !! ", // formatting is sanitized. " # comments are ignored", "lxc.network.type=foo", // replace the second "type". "lxc.network.name = em0 # renamed now", // replace the first "name" "lxc.network.name = em1", // replace the second "name" "lxc.network.mtu = 1234", // replace only the first "mtu". "lxc.network.hwaddr = ff:ee:dd:cc:bb:aa", // replace the first "hwaddr". "lxc.network.hwaddr=deadbeef", // replace second "hwaddr". "lxc.network.hwaddr=nonsense", // no third "hwaddr", so append. "lxc.network.hwaddr = ", // no fourth "hwaddr" to remove - ignored. "lxc.network.link=", // remove only the first "link" "lxc.network.vlan.id=69", // replace. "lxc.missing = appended", // missing - appended. "lxc.network.type = phys", // replace the third "type". "lxc.mount.entry=", // delete existing "entry". "lxc.rootfs = /foo/bar", // replace first "rootfs". "lxc.rootfs = /bar/foo", // append new. } newConfig := strings.Join(linesToReplace, "\n") updatedConfig := ` # network config # interface "eth0" lxc.network.type = bar lxc.network.flags = up lxc.network.name = em0 lxc.network.hwaddr = ff:ee:dd:cc:bb:aa lxc.network.ipv4 = 0.1.2.3/20 lxc.network.ipv4.gateway = 0.1.2.1 # interface "eth1" lxc.network.type = foo lxc.network.link = nic42 lxc.network.flags = up lxc.network.name = em1 lxc.aa_profile = lxc-container-default-with-mounting lxc.cgroup.devices.allow = b 7:* rwm lxc.cgroup.devices.allow = c 10:237 rwm lxc.rootfs = /foo/bar # just comment lxc.network.vlan.id = 69 something else # ignore lxc.network.type = phys lxc.network.link = foo # comment lxc.network.hwaddr = deadbeef lxc.network.mtu = 1234 lxc.network.hwaddr = nonsense lxc.missing = appended lxc.rootfs = /bar/foo ` err = lxc.UpdateContainerConfig(name, newConfig) c.Assert(err, jc.ErrorIsNil) lxcConfContents, err = ioutil.ReadFile(configPath) c.Assert(err, jc.ErrorIsNil) c.Assert(string(lxcConfContents), gc.Equals, updatedConfig) // Now test the example in updateContainerConfig's doc string. oldConfig := ` lxc.foo = off lxc.bar=42 ` newConfig = ` lxc.bar= lxc.foo = bar lxc.foo = baz # xx ` updatedConfig = ` lxc.foo = bar lxc.foo = baz ` err = ioutil.WriteFile(configPath, []byte(oldConfig), 0644) c.Assert(err, jc.ErrorIsNil) err = lxc.UpdateContainerConfig(name, newConfig) c.Assert(err, jc.ErrorIsNil) lxcConfContents, err = ioutil.ReadFile(configPath) c.Assert(err, jc.ErrorIsNil) c.Assert(string(lxcConfContents), gc.Equals, updatedConfig) }