From 6756e786ac36d4e5cda46541b5d6e0b2913b6997 Mon Sep 17 00:00:00 2001 From: Brian Olsen Date: Fri, 30 Aug 2013 02:49:11 +0200 Subject: [PATCH 1/2] Just fixing gofmt issues in other people's code. --- container.go | 10 +++++----- network.go | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/container.go b/container.go index 39c19c53d..5799fa4e1 100644 --- a/container.go +++ b/container.go @@ -11,6 +11,7 @@ import ( "io" "io/ioutil" "log" + "net" "os" "os/exec" "path" @@ -20,7 +21,6 @@ import ( "strings" "syscall" "time" - "net" ) type Container struct { @@ -813,10 +813,10 @@ func (container *Container) allocateNetwork() error { iface = &NetworkInterface{disabled: true} } else { iface = &NetworkInterface{ - IPNet: net.IPNet{IP: net.ParseIP(container.NetworkSettings.IPAddress), Mask: manager.bridgeNetwork.Mask}, + IPNet: net.IPNet{IP: net.ParseIP(container.NetworkSettings.IPAddress), Mask: manager.bridgeNetwork.Mask}, Gateway: manager.bridgeNetwork.IP, manager: manager, - } + } ipNum := ipToInt(iface.IPNet.IP) manager.ipAllocator.inUse[ipNum] = struct{}{} } @@ -827,10 +827,10 @@ func (container *Container) allocateNetwork() error { portSpecs = container.Config.PortSpecs } else { for backend, frontend := range container.NetworkSettings.PortMapping["Tcp"] { - portSpecs = append(portSpecs, fmt.Sprintf("%s:%s/tcp",frontend, backend)) + portSpecs = append(portSpecs, fmt.Sprintf("%s:%s/tcp", frontend, backend)) } for backend, frontend := range container.NetworkSettings.PortMapping["Udp"] { - portSpecs = append(portSpecs, fmt.Sprintf("%s:%s/udp",frontend, backend)) + portSpecs = append(portSpecs, fmt.Sprintf("%s:%s/udp", frontend, backend)) } } diff --git a/network.go b/network.go index c2673bd80..b55291925 100644 --- a/network.go +++ b/network.go @@ -642,7 +642,7 @@ func (manager *NetworkManager) Allocate() (*NetworkInterface, error) { if err != nil { return nil, err } - // avoid duplicate IP + // avoid duplicate IP ipNum := ipToInt(ip) firstIP := manager.ipAllocator.network.IP.To4().Mask(manager.ipAllocator.network.Mask) firstIPNum := ipToInt(firstIP) + 1 From 7a9c71183212a40fdd10369d009a9f97b56fe359 Mon Sep 17 00:00:00 2001 From: Brian Olsen Date: Fri, 30 Aug 2013 02:29:35 +0200 Subject: [PATCH 2/2] Copies content from image to volumne if non-empty. Fixes #1582. --- container.go | 33 +++++++++++++++++++++++------ container_test.go | 54 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 6 deletions(-) diff --git a/container.go b/container.go index 5799fa4e1..6b52983b0 100644 --- a/container.go +++ b/container.go @@ -642,11 +642,13 @@ func (container *Container) Start(hostConfig *HostConfig) error { if _, exists := container.Volumes[volPath]; exists { continue } + var srcPath string + srcRW := false // If an external bind is defined for this volume, use that as a source if bindMap, exists := binds[volPath]; exists { - container.Volumes[volPath] = bindMap.SrcPath + srcPath = bindMap.SrcPath if strings.ToLower(bindMap.Mode) == "rw" { - container.VolumesRW[volPath] = true + srcRW = true } // Otherwise create an directory in $ROOT/volumes/ and use that } else { @@ -654,17 +656,36 @@ func (container *Container) Start(hostConfig *HostConfig) error { if err != nil { return err } - srcPath, err := c.layer() + srcPath, err = c.layer() if err != nil { return err } - container.Volumes[volPath] = srcPath - container.VolumesRW[volPath] = true // RW by default + srcRW = true // RW by default } + container.Volumes[volPath] = srcPath + container.VolumesRW[volPath] = srcRW // Create the mountpoint - if err := os.MkdirAll(path.Join(container.RootfsPath(), volPath), 0755); err != nil { + rootVolPath := path.Join(container.RootfsPath(), volPath) + if err := os.MkdirAll(rootVolPath, 0755); err != nil { return nil } + if srcRW { + volList, err := ioutil.ReadDir(rootVolPath) + if err != nil { + return err + } + if len(volList) > 0 { + srcList, err := ioutil.ReadDir(srcPath) + if err != nil { + return err + } + if len(srcList) == 0 { + if err := CopyWithTar(rootVolPath, srcPath); err != nil { + return err + } + } + } + } } if err := container.generateLXCConfig(hostConfig); err != nil { diff --git a/container_test.go b/container_test.go index ba48ceb47..9b6b56304 100644 --- a/container_test.go +++ b/container_test.go @@ -1193,6 +1193,60 @@ func tempDir(t *testing.T) string { return tmpDir } +// Test for #1582 +func TestCopyVolumeContent(t *testing.T) { + r := mkRuntime(t) + defer nuke(r) + + // Put some content in a directory of a container and commit it + container1, _, _ := mkContainer(r, []string{"_", "/bin/sh", "-c", "mkdir -p /hello/local && echo hello > /hello/local/world"}, t) + defer r.Destroy(container1) + + if container1.State.Running { + t.Errorf("Container shouldn't be running") + } + if err := container1.Run(); err != nil { + t.Fatal(err) + } + if container1.State.Running { + t.Errorf("Container shouldn't be running") + } + + rwTar, err := container1.ExportRw() + if err != nil { + t.Error(err) + } + img, err := r.graph.Create(rwTar, container1, "unit test commited image", "", nil) + if err != nil { + t.Error(err) + } + + // Test that the content is copied from the image to the volume + tmpDir1 := tempDir(t) + defer os.RemoveAll(tmpDir1) + stdout1, _ := runContainer(r, []string{"-v", fmt.Sprintf("%s:/hello", tmpDir1), img.ID, "find", "/hello"}, t) + if !(strings.Contains(stdout1, "/hello/local/world") && strings.Contains(stdout1, "/hello/local")) { + t.Fatal("Container failed to transfer content to volume") + } + + // Test that the content is not copied when the volume is readonly + tmpDir2 := tempDir(t) + defer os.RemoveAll(tmpDir2) + stdout2, _ := runContainer(r, []string{"-v", fmt.Sprintf("%s:/hello:ro", tmpDir2), img.ID, "find", "/hello"}, t) + if strings.Contains(stdout2, "/hello/local/world") || strings.Contains(stdout2, "/hello/local") { + t.Fatal("Container transfered content to readonly volume") + } + + // Test that the content is not copied when the volume is non-empty + tmpDir3 := tempDir(t) + defer os.RemoveAll(tmpDir3) + writeFile(path.Join(tmpDir3, "touch-me"), "", t) + stdout3, _ := runContainer(r, []string{"-v", fmt.Sprintf("%s:/hello:rw", tmpDir3), img.ID, "find", "/hello"}, t) + if strings.Contains(stdout3, "/hello/local/world") || strings.Contains(stdout3, "/hello/local") || !strings.Contains(stdout3, "/hello/touch-me") { + t.Fatal("Container transfered content to non-empty volume") + } +} + func TestBindMounts(t *testing.T) { r := mkRuntime(t) defer nuke(r)