Only copy files and change permissions with non bindmount
| ... | ... |
@@ -671,9 +671,11 @@ func (container *Container) Start(hostConfig *HostConfig) error {
|
| 671 | 671 |
continue |
| 672 | 672 |
} |
| 673 | 673 |
var srcPath string |
| 674 |
+ var isBindMount bool |
|
| 674 | 675 |
srcRW := false |
| 675 | 676 |
// If an external bind is defined for this volume, use that as a source |
| 676 | 677 |
if bindMap, exists := binds[volPath]; exists {
|
| 678 |
+ isBindMount = true |
|
| 677 | 679 |
srcPath = bindMap.SrcPath |
| 678 | 680 |
if strings.ToLower(bindMap.Mode) == "rw" {
|
| 679 | 681 |
srcRW = true |
| ... | ... |
@@ -697,7 +699,9 @@ func (container *Container) Start(hostConfig *HostConfig) error {
|
| 697 | 697 |
if err := os.MkdirAll(rootVolPath, 0755); err != nil {
|
| 698 | 698 |
return nil |
| 699 | 699 |
} |
| 700 |
- if srcRW {
|
|
| 700 |
+ |
|
| 701 |
+ // Do not copy or change permissions if we are mounting from the host |
|
| 702 |
+ if srcRW && !isBindMount {
|
|
| 701 | 703 |
volList, err := ioutil.ReadDir(rootVolPath) |
| 702 | 704 |
if err != nil {
|
| 703 | 705 |
return err |
| ... | ... |
@@ -708,22 +712,26 @@ func (container *Container) Start(hostConfig *HostConfig) error {
|
| 708 | 708 |
return err |
| 709 | 709 |
} |
| 710 | 710 |
if len(srcList) == 0 {
|
| 711 |
+ // If the source volume is empty copy files from the root into the volume |
|
| 711 | 712 |
if err := CopyWithTar(rootVolPath, srcPath); err != nil {
|
| 712 | 713 |
return err |
| 713 | 714 |
} |
| 714 |
- } |
|
| 715 |
- } |
|
| 716 |
- var stat syscall.Stat_t |
|
| 717 |
- if err := syscall.Stat(rootVolPath, &stat); err != nil {
|
|
| 718 |
- return err |
|
| 719 |
- } |
|
| 720 |
- var srcStat syscall.Stat_t |
|
| 721 |
- if err := syscall.Stat(srcPath, &srcStat); err != nil {
|
|
| 722 |
- return err |
|
| 723 |
- } |
|
| 724 |
- if stat.Uid != srcStat.Uid || stat.Gid != srcStat.Gid {
|
|
| 725 |
- if err := os.Chown(srcPath, int(stat.Uid), int(stat.Gid)); err != nil {
|
|
| 726 |
- return err |
|
| 715 |
+ |
|
| 716 |
+ var stat syscall.Stat_t |
|
| 717 |
+ if err := syscall.Stat(rootVolPath, &stat); err != nil {
|
|
| 718 |
+ return err |
|
| 719 |
+ } |
|
| 720 |
+ var srcStat syscall.Stat_t |
|
| 721 |
+ if err := syscall.Stat(srcPath, &srcStat); err != nil {
|
|
| 722 |
+ return err |
|
| 723 |
+ } |
|
| 724 |
+ // Change the source volume's ownership if it differs from the root |
|
| 725 |
+ // files that where just copied |
|
| 726 |
+ if stat.Uid != srcStat.Uid || stat.Gid != srcStat.Gid {
|
|
| 727 |
+ if err := os.Chown(srcPath, int(stat.Uid), int(stat.Gid)); err != nil {
|
|
| 728 |
+ return err |
|
| 729 |
+ } |
|
| 730 |
+ } |
|
| 727 | 731 |
} |
| 728 | 732 |
} |
| 729 | 733 |
} |
| ... | ... |
@@ -1202,7 +1202,7 @@ func TestCopyVolumeUidGid(t *testing.T) {
|
| 1202 | 1202 |
defer nuke(r) |
| 1203 | 1203 |
|
| 1204 | 1204 |
// Add directory not owned by root |
| 1205 |
- container1, _, _ := mkContainer(r, []string{"_", "/bin/sh", "-c", "mkdir -p /hello && chown daemon.daemon /hello"}, t)
|
|
| 1205 |
+ container1, _, _ := mkContainer(r, []string{"_", "/bin/sh", "-c", "mkdir -p /hello && touch /hello/test.txt && chown daemon.daemon /hello"}, t)
|
|
| 1206 | 1206 |
defer r.Destroy(container1) |
| 1207 | 1207 |
|
| 1208 | 1208 |
if container1.State.Running {
|
| ... | ... |
@@ -1227,18 +1227,10 @@ func TestCopyVolumeUidGid(t *testing.T) {
|
| 1227 | 1227 |
// Test that the uid and gid is copied from the image to the volume |
| 1228 | 1228 |
tmpDir1 := tempDir(t) |
| 1229 | 1229 |
defer os.RemoveAll(tmpDir1) |
| 1230 |
- stdout1, _ := runContainer(r, []string{"-v", fmt.Sprintf("%s:/hello", tmpDir1), img.ID, "stat", "-c", "%U %G", "/hello"}, t)
|
|
| 1230 |
+ stdout1, _ := runContainer(r, []string{"-v", "/hello", img.ID, "stat", "-c", "%U %G", "/hello"}, t)
|
|
| 1231 | 1231 |
if !strings.Contains(stdout1, "daemon daemon") {
|
| 1232 | 1232 |
t.Fatal("Container failed to transfer uid and gid to volume")
|
| 1233 | 1233 |
} |
| 1234 |
- |
|
| 1235 |
- // Test that the uid and gid is not copied from the image when the volume is read only |
|
| 1236 |
- tmpDir2 := tempDir(t) |
|
| 1237 |
- defer os.RemoveAll(tmpDir1) |
|
| 1238 |
- stdout2, _ := runContainer(r, []string{"-v", fmt.Sprintf("%s:/hello:ro", tmpDir2), img.ID, "stat", "-c", "%U %G", "/hello"}, t)
|
|
| 1239 |
- if strings.Contains(stdout2, "daemon daemon") {
|
|
| 1240 |
- t.Fatal("Container transfered uid and gid to volume")
|
|
| 1241 |
- } |
|
| 1242 | 1234 |
} |
| 1243 | 1235 |
|
| 1244 | 1236 |
// Test for #1582 |
| ... | ... |
@@ -1272,27 +1264,10 @@ func TestCopyVolumeContent(t *testing.T) {
|
| 1272 | 1272 |
// Test that the content is copied from the image to the volume |
| 1273 | 1273 |
tmpDir1 := tempDir(t) |
| 1274 | 1274 |
defer os.RemoveAll(tmpDir1) |
| 1275 |
- stdout1, _ := runContainer(r, []string{"-v", fmt.Sprintf("%s:/hello", tmpDir1), img.ID, "find", "/hello"}, t)
|
|
| 1275 |
+ stdout1, _ := runContainer(r, []string{"-v", "/hello", img.ID, "find", "/hello"}, t)
|
|
| 1276 | 1276 |
if !(strings.Contains(stdout1, "/hello/local/world") && strings.Contains(stdout1, "/hello/local")) {
|
| 1277 | 1277 |
t.Fatal("Container failed to transfer content to volume")
|
| 1278 | 1278 |
} |
| 1279 |
- |
|
| 1280 |
- // Test that the content is not copied when the volume is readonly |
|
| 1281 |
- tmpDir2 := tempDir(t) |
|
| 1282 |
- defer os.RemoveAll(tmpDir2) |
|
| 1283 |
- stdout2, _ := runContainer(r, []string{"-v", fmt.Sprintf("%s:/hello:ro", tmpDir2), img.ID, "find", "/hello"}, t)
|
|
| 1284 |
- if strings.Contains(stdout2, "/hello/local/world") || strings.Contains(stdout2, "/hello/local") {
|
|
| 1285 |
- t.Fatal("Container transfered content to readonly volume")
|
|
| 1286 |
- } |
|
| 1287 |
- |
|
| 1288 |
- // Test that the content is not copied when the volume is non-empty |
|
| 1289 |
- tmpDir3 := tempDir(t) |
|
| 1290 |
- defer os.RemoveAll(tmpDir3) |
|
| 1291 |
- writeFile(path.Join(tmpDir3, "touch-me"), "", t) |
|
| 1292 |
- stdout3, _ := runContainer(r, []string{"-v", fmt.Sprintf("%s:/hello:rw", tmpDir3), img.ID, "find", "/hello"}, t)
|
|
| 1293 |
- if strings.Contains(stdout3, "/hello/local/world") || strings.Contains(stdout3, "/hello/local") || !strings.Contains(stdout3, "/hello/touch-me") {
|
|
| 1294 |
- t.Fatal("Container transfered content to non-empty volume")
|
|
| 1295 |
- } |
|
| 1296 | 1279 |
} |
| 1297 | 1280 |
|
| 1298 | 1281 |
func TestBindMounts(t *testing.T) {
|