func (s *UserDataSuite) TestCloudInitUserDataFallbackConfigWithContainerHostname(c *gc.C) { instanceConfig, err := containertesting.MockMachineConfig("1/lxd/0") instanceConfig.MachineContainerHostname = "lxdhostname" c.Assert(err, jc.ErrorIsNil) networkConfig := container.BridgeNetworkConfig("foo", 0, nil) data, err := containerinit.CloudInitUserData(instanceConfig, networkConfig) c.Assert(err, jc.ErrorIsNil) c.Assert(data, gc.NotNil) linesToMatch := CloudInitDataExcludingOutputSection(string(data)) expected := fmt.Sprintf(s.expectedFallbackUserData, s.networkInterfacesFile, s.systemNetworkInterfacesFile) var expectedLinesToMatch []string for _, line := range strings.Split(expected, "\n") { if strings.HasPrefix(line, "runcmd:") { break } expectedLinesToMatch = append(expectedLinesToMatch, line) } expectedLinesToMatch = append(expectedLinesToMatch, "hostname: lxdhostname") expectedLinesToMatch = append(expectedLinesToMatch, "manage_etc_hosts: true") c.Assert(strings.Join(linesToMatch, "\n")+"\n", gc.Equals, strings.Join(expectedLinesToMatch, "\n")+"\n") }
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 *UserDataSuite) TestCloudInitUserData(c *gc.C) { instanceConfig, err := containertesting.MockMachineConfig("1/lxc/0") c.Assert(err, jc.ErrorIsNil) networkConfig := container.BridgeNetworkConfig("foo", 0, nil) data, err := containerinit.CloudInitUserData(instanceConfig, networkConfig) c.Assert(err, jc.ErrorIsNil) // No need to test the exact contents here, as they are already // tested separately. c.Assert(string(data), jc.HasPrefix, "#cloud-config\n") }
// TestCloudInitUserDataNoNetworkConfig tests that no network-interfaces, or // related data, appear in user-data when no networkConfig is passed to // CloudInitUserData. func (s *UserDataSuite) TestCloudInitUserDataNoNetworkConfig(c *gc.C) { instanceConfig, err := containertesting.MockMachineConfig("1/lxd/0") c.Assert(err, jc.ErrorIsNil) data, err := containerinit.CloudInitUserData(instanceConfig, nil) c.Assert(err, jc.ErrorIsNil) c.Assert(data, gc.NotNil) linesToMatch := CloudInitDataExcludingOutputSection(string(data)) c.Assert(strings.Join(linesToMatch, "\n"), gc.Equals, "#cloud-config") }
// Test that CreateContainer creates proper startParams. func (s *KVMSuite) TestCreateContainerUtilizesReleaseSimpleStream(c *gc.C) { // Mock machineConfig with a mocked simple stream URL. instanceConfig, err := containertesting.MockMachineConfig("1/kvm/0") c.Assert(err, jc.ErrorIsNil) // CreateContainer sets TestStartParams internally; we call this // purely for the side-effect. containertesting.CreateContainerWithMachineConfig(c, s.manager, instanceConfig) c.Assert(kvm.TestStartParams.ImageDownloadURL, gc.Equals, "") }
// Test that CreateContainer creates proper startParams. func (s *KVMSuite) TestCreateContainerUtilizesDailySimpleStream(c *gc.C) { // Mock machineConfig with a mocked simple stream URL. instanceConfig, err := containertesting.MockMachineConfig("1/kvm/0") c.Assert(err, jc.ErrorIsNil) instanceConfig.ImageStream = "daily" // CreateContainer sets TestStartParams internally; we call this // purely for the side-effect. containertesting.CreateContainerWithMachineConfig(c, s.manager, instanceConfig) c.Assert(kvm.TestStartParams.ImageDownloadUrl, gc.Equals, "http://cloud-images.ubuntu.com/daily") }
func (s *UserDataSuite) TestCloudInitUserDataFallbackConfig(c *gc.C) { instanceConfig, err := containertesting.MockMachineConfig("1/lxd/0") c.Assert(err, jc.ErrorIsNil) networkConfig := container.BridgeNetworkConfig("foo", 0, nil) data, err := containerinit.CloudInitUserData(instanceConfig, networkConfig) c.Assert(err, jc.ErrorIsNil) c.Assert(data, gc.NotNil) // Extract the "#cloud-config" header and all lines between // from the "bootcmd" section up to (but not including) the // "output" sections to match against expected. But we cannot // possibly handle all the /other/ output that may be added by // CloudInitUserData() in the future, so we also truncate at // the first runcmd which now happens to include the runcmd's // added for raising the network interfaces captured in // expectedFallbackUserData. However, the other tests above do // check for that output. var linesToMatch []string seenBootcmd := false for _, line := range strings.Split(string(data), "\n") { if strings.HasPrefix(line, "#cloud-config") { linesToMatch = append(linesToMatch, line) continue } if strings.HasPrefix(line, "bootcmd:") { seenBootcmd = true } if strings.HasPrefix(line, "output:") && seenBootcmd { break } if seenBootcmd { linesToMatch = append(linesToMatch, line) } } expected := fmt.Sprintf(s.expectedFallbackUserData, s.networkInterfacesFile, s.systemNetworkInterfacesFile) var expectedLinesToMatch []string for _, line := range strings.Split(expected, "\n") { if strings.HasPrefix(line, "runcmd:") { break } expectedLinesToMatch = append(expectedLinesToMatch, line) } c.Assert(strings.Join(linesToMatch, "\n")+"\n", gc.Equals, strings.Join(expectedLinesToMatch, "\n")+"\n") }
func (t *LxdSuite) TestNotAllContainersAreDeleted(c *gc.C) { c.Skip("Test skipped because it talks directly to LXD agent.") lxdClient, err := lxd.ConnectLocal("") c.Assert(err, jc.ErrorIsNil) /* create a container to make sure isn't deleted */ instanceSpec := lxdclient.InstanceSpec{ Name: "juju-lxd-tests", Image: "ubuntu-xenial", } _, err = lxdClient.AddInstance(instanceSpec) c.Assert(err, jc.ErrorIsNil) defer lxdClient.RemoveInstances("", "juju-lxd-tests") instanceConfig, err := containertesting.MockMachineConfig("1/lxd/0") c.Assert(err, jc.ErrorIsNil) envConfig, err := config.New(config.NoDefaults, dummy.SampleConfig()) c.Assert(err, jc.ErrorIsNil) instanceConfig.Config = envConfig storageConfig := &container.StorageConfig{} networkConfig := container.BridgeNetworkConfig("nic42", 4321, nil) manager := t.makeManager(c, "manager") callback := func(settableStatus status.Status, info string, data map[string]interface{}) error { return nil } _, _, err = manager.CreateContainer( instanceConfig, "xenial", networkConfig, storageConfig, callback, ) c.Assert(err, jc.ErrorIsNil) instances, err := manager.ListContainers() c.Assert(err, jc.ErrorIsNil) for _, inst := range instances { err = manager.DestroyContainer(inst.Id()) c.Assert(err, jc.ErrorIsNil) } }
// Test that CreateContainer creates proper startParams. func (s *KVMSuite) TestCreateContainerUtilizesReleaseSimpleStream(c *gc.C) { envCfg, err := config.New( config.NoDefaults, dummy.SampleConfig().Merge( coretesting.Attrs{"image-stream": "released"}, ), ) c.Assert(err, jc.ErrorIsNil) // Mock machineConfig with a mocked simple stream URL. instanceConfig, err := containertesting.MockMachineConfig("1/kvm/0") c.Assert(err, jc.ErrorIsNil) instanceConfig.Config = envCfg // CreateContainer sets TestStartParams internally; we call this // purely for the side-effect. containertesting.CreateContainerWithMachineConfig(c, s.manager, instanceConfig) c.Assert(kvm.TestStartParams.ImageDownloadUrl, gc.Equals, "") }
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) }