Browse code

fixes #2671, add support for bind mounting individual files in to containers, rebases of #1757 #2301

daniel-garcia authored on 2013/11/20 08:27:01
Showing 2 changed files
... ...
@@ -610,6 +610,7 @@ func (container *Container) Start() (err error) {
610 610
 	// Create the requested volumes if they don't exist
611 611
 	for volPath := range container.Config.Volumes {
612 612
 		volPath = path.Clean(volPath)
613
+		volIsDir := true
613 614
 		// Skip existing volumes
614 615
 		if _, exists := container.Volumes[volPath]; exists {
615 616
 			continue
... ...
@@ -624,6 +625,16 @@ func (container *Container) Start() (err error) {
624 624
 			if strings.ToLower(bindMap.Mode) == "rw" {
625 625
 				srcRW = true
626 626
 			}
627
+			if file, err := os.Open(bindMap.SrcPath); err != nil {
628
+				return err
629
+			} else {
630
+				defer file.Close()
631
+				if stat, err := file.Stat(); err != nil {
632
+					return err
633
+				} else {
634
+					volIsDir = stat.IsDir()
635
+				}
636
+			}
627 637
 			// Otherwise create an directory in $ROOT/volumes/ and use that
628 638
 		} else {
629 639
 			c, err := container.runtime.volumes.Create(nil, container, "", "", nil)
... ...
@@ -640,8 +651,30 @@ func (container *Container) Start() (err error) {
640 640
 		container.VolumesRW[volPath] = srcRW
641 641
 		// Create the mountpoint
642 642
 		rootVolPath := path.Join(container.RootfsPath(), volPath)
643
-		if err := os.MkdirAll(rootVolPath, 0755); err != nil {
644
-			return err
643
+		if volIsDir {
644
+			if err := os.MkdirAll(rootVolPath, 0755); err != nil {
645
+				return err
646
+			}
647
+		}
648
+
649
+		volPath = path.Join(container.RootfsPath(), volPath)
650
+		if _, err := os.Stat(volPath); err != nil {
651
+			if os.IsNotExist(err) {
652
+				if volIsDir {
653
+					if err := os.MkdirAll(volPath, 0755); err != nil {
654
+						return err
655
+					}
656
+				} else {
657
+					if err := os.MkdirAll(path.Dir(volPath), 0755); err != nil {
658
+						return err
659
+					}
660
+					if f, err := os.OpenFile(volPath, os.O_CREATE, 0755); err != nil {
661
+						return err
662
+					} else {
663
+						f.Close()
664
+					}
665
+				}
666
+			}
645 667
 		}
646 668
 
647 669
 		// Do not copy or change permissions if we are mounting from the host
... ...
@@ -1257,6 +1257,13 @@ func TestBindMounts(t *testing.T) {
1257 1257
 	if _, err := runContainer(eng, r, []string{"-v", fmt.Sprintf("%s:.", tmpDir), "_", "ls", "."}, nil); err == nil {
1258 1258
 		t.Fatal("Container bind mounted illegal directory")
1259 1259
 	}
1260
+
1261
+	// test mount a file
1262
+	runContainer(eng, r, []string{"-v", fmt.Sprintf("%s/holla:/tmp/holla:rw", tmpDir), "_", "sh", "-c", "echo -n 'yotta' > /tmp/holla"}, t)
1263
+	content := readFile(path.Join(tmpDir, "holla"), t) // Will fail if the file doesn't exist
1264
+	if content != "yotta" {
1265
+		t.Fatal("Container failed to write to bind mount file")
1266
+	}
1260 1267
 }
1261 1268
 
1262 1269
 // Test that -volumes-from supports both read-only mounts