| ... | ... |
@@ -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 |