Browse Source

Merge pull request #2775 from daniel-garcia/2671-bindmount_files

fixes #2671, add support for bind mounting individual files in to contai...
Guillaume J. Charmes 11 years ago
parent
commit
d6cdbca6c1
2 changed files with 42 additions and 2 deletions
  1. 35 2
      container.go
  2. 7 0
      integration/container_test.go

+ 35 - 2
container.go

@@ -624,6 +624,7 @@ func (container *Container) Start() (err error) {
 	// Create the requested volumes if they don't exist
 	for volPath := range container.Config.Volumes {
 		volPath = path.Clean(volPath)
+		volIsDir := true
 		// Skip existing volumes
 		if _, exists := container.Volumes[volPath]; exists {
 			continue
@@ -638,6 +639,16 @@ func (container *Container) Start() (err error) {
 			if strings.ToLower(bindMap.Mode) == "rw" {
 				srcRW = true
 			}
+			if file, err := os.Open(bindMap.SrcPath); err != nil {
+				return err
+			} else {
+				defer file.Close()
+				if stat, err := file.Stat(); err != nil {
+					return err
+				} else {
+					volIsDir = stat.IsDir()
+				}
+			}
 			// Otherwise create an directory in $ROOT/volumes/ and use that
 		} else {
 
@@ -658,8 +669,30 @@ func (container *Container) Start() (err error) {
 		container.VolumesRW[volPath] = srcRW
 		// Create the mountpoint
 		rootVolPath := path.Join(container.RootfsPath(), volPath)
-		if err := os.MkdirAll(rootVolPath, 0755); err != nil {
-			return err
+		if volIsDir {
+			if err := os.MkdirAll(rootVolPath, 0755); err != nil {
+				return err
+			}
+		}
+
+		volPath = path.Join(container.RootfsPath(), volPath)
+		if _, err := os.Stat(volPath); err != nil {
+			if os.IsNotExist(err) {
+				if volIsDir {
+					if err := os.MkdirAll(volPath, 0755); err != nil {
+						return err
+					}
+				} else {
+					if err := os.MkdirAll(path.Dir(volPath), 0755); err != nil {
+						return err
+					}
+					if f, err := os.OpenFile(volPath, os.O_CREATE, 0755); err != nil {
+						return err
+					} else {
+						f.Close()
+					}
+				}
+			}
 		}
 
 		// Do not copy or change permissions if we are mounting from the host

+ 7 - 0
integration/container_test.go

@@ -1257,6 +1257,13 @@ func TestBindMounts(t *testing.T) {
 	if _, err := runContainer(eng, r, []string{"-v", fmt.Sprintf("%s:.", tmpDir), "_", "ls", "."}, nil); err == nil {
 		t.Fatal("Container bind mounted illegal directory")
 	}
+
+	// test mount a file
+	runContainer(eng, r, []string{"-v", fmt.Sprintf("%s/holla:/tmp/holla:rw", tmpDir), "_", "sh", "-c", "echo -n 'yotta' > /tmp/holla"}, t)
+	content := readFile(path.Join(tmpDir, "holla"), t) // Will fail if the file doesn't exist
+	if content != "yotta" {
+		t.Fatal("Container failed to write to bind mount file")
+	}
 }
 
 // Test that -volumes-from supports both read-only mounts