Skip to content

Commit af97464

Browse files
committed
Move volumesfrom to hostconfig
This also migrates the volumes from integration tests into the new cli integration test framework. Docker-DCO-1.1-Signed-off-by: Michael Crosby <[email protected]> (github: crosbymichael)
1 parent a10c17a commit af97464

9 files changed

Lines changed: 92 additions & 302 deletions

File tree

integration-cli/docker_cli_run_test.go

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,3 +312,75 @@ func TestVolumesMountedAsReadonly(t *testing.T) {
312312

313313
logDone("run - volumes as readonly mount")
314314
}
315+
316+
func TestVolumesFromInReadonlyMode(t *testing.T) {
317+
cmd := exec.Command(dockerBinary, "run", "--name", "parent", "-v", "/test", "busybox", "true")
318+
if _, err := runCommand(cmd); err != nil {
319+
t.Fatal(err)
320+
}
321+
322+
cmd = exec.Command(dockerBinary, "run", "--volumes-from", "parent:ro", "busybox", "touch", "/test/file")
323+
if code, err := runCommand(cmd); err == nil || code == 0 {
324+
t.Fatalf("run should fail because volume is ro: exit code %d", code)
325+
}
326+
327+
deleteAllContainers()
328+
329+
logDone("run - volumes from as readonly mount")
330+
}
331+
332+
// Regression test for #1201
333+
func TestVolumesFromInReadWriteMode(t *testing.T) {
334+
cmd := exec.Command(dockerBinary, "run", "--name", "parent", "-v", "/test", "busybox", "true")
335+
if _, err := runCommand(cmd); err != nil {
336+
t.Fatal(err)
337+
}
338+
339+
cmd = exec.Command(dockerBinary, "run", "--volumes-from", "parent", "busybox", "touch", "/test/file")
340+
if _, err := runCommand(cmd); err != nil {
341+
t.Fatal(err)
342+
}
343+
344+
deleteAllContainers()
345+
346+
logDone("run - volumes from as read write mount")
347+
}
348+
349+
// Test for #1351
350+
func TestApplyVolumesFromBeforeVolumes(t *testing.T) {
351+
cmd := exec.Command(dockerBinary, "run", "--name", "parent", "-v", "/test", "busybox", "touch", "/test/foo")
352+
if _, err := runCommand(cmd); err != nil {
353+
t.Fatal(err)
354+
}
355+
356+
cmd = exec.Command(dockerBinary, "run", "--volumes-from", "parent", "-v", "/test", "busybox", "cat", "/test/foo")
357+
if _, err := runCommand(cmd); err != nil {
358+
t.Fatal(err)
359+
}
360+
361+
deleteAllContainers()
362+
363+
logDone("run - volumes from mounted first")
364+
}
365+
366+
func TestMultipleVolumesFrom(t *testing.T) {
367+
cmd := exec.Command(dockerBinary, "run", "--name", "parent1", "-v", "/test", "busybox", "touch", "/test/foo")
368+
if _, err := runCommand(cmd); err != nil {
369+
t.Fatal(err)
370+
}
371+
372+
cmd = exec.Command(dockerBinary, "run", "--name", "parent2", "-v", "/other", "busybox", "touch", "/other/bar")
373+
if _, err := runCommand(cmd); err != nil {
374+
t.Fatal(err)
375+
}
376+
377+
cmd = exec.Command(dockerBinary, "run", "--volumes-from", "parent1", "--volumes-from", "parent2",
378+
"busybox", "sh", "-c", "cat /test/foo && cat /other/bar")
379+
if _, err := runCommand(cmd); err != nil {
380+
t.Fatal(err)
381+
}
382+
383+
deleteAllContainers()
384+
385+
logDone("run - multiple volumes from")
386+
}

integration/container_test.go

Lines changed: 0 additions & 262 deletions
Original file line numberDiff line numberDiff line change
@@ -1273,123 +1273,6 @@ func TestBindMounts(t *testing.T) {
12731273
}
12741274
}
12751275

1276-
// Test that -volumes-from supports both read-only mounts
1277-
func TestFromVolumesInReadonlyMode(t *testing.T) {
1278-
runtime := mkRuntime(t)
1279-
defer nuke(runtime)
1280-
container, _, err := runtime.Create(
1281-
&runconfig.Config{
1282-
Image: GetTestImage(runtime).ID,
1283-
Cmd: []string{"/bin/echo", "-n", "foobar"},
1284-
Volumes: map[string]struct{}{"/test": {}},
1285-
},
1286-
"",
1287-
)
1288-
if err != nil {
1289-
t.Fatal(err)
1290-
}
1291-
defer runtime.Destroy(container)
1292-
_, err = container.Output()
1293-
if err != nil {
1294-
t.Fatal(err)
1295-
}
1296-
if !container.VolumesRW["/test"] {
1297-
t.Fail()
1298-
}
1299-
1300-
container2, _, err := runtime.Create(
1301-
&runconfig.Config{
1302-
Image: GetTestImage(runtime).ID,
1303-
Cmd: []string{"/bin/echo", "-n", "foobar"},
1304-
VolumesFrom: container.ID + ":ro",
1305-
},
1306-
"",
1307-
)
1308-
if err != nil {
1309-
t.Fatal(err)
1310-
}
1311-
defer runtime.Destroy(container2)
1312-
1313-
_, err = container2.Output()
1314-
if err != nil {
1315-
t.Fatal(err)
1316-
}
1317-
1318-
if container.Volumes["/test"] != container2.Volumes["/test"] {
1319-
t.Logf("container volumes do not match: %s | %s ",
1320-
container.Volumes["/test"],
1321-
container2.Volumes["/test"])
1322-
t.Fail()
1323-
}
1324-
1325-
_, exists := container2.VolumesRW["/test"]
1326-
if !exists {
1327-
t.Logf("container2 is missing '/test' volume: %s", container2.VolumesRW)
1328-
t.Fail()
1329-
}
1330-
1331-
if container2.VolumesRW["/test"] != false {
1332-
t.Log("'/test' volume mounted in read-write mode, expected read-only")
1333-
t.Fail()
1334-
}
1335-
}
1336-
1337-
// Test that VolumesRW values are copied to the new container. Regression test for #1201
1338-
func TestVolumesFromReadonlyMount(t *testing.T) {
1339-
runtime := mkRuntime(t)
1340-
defer nuke(runtime)
1341-
container, _, err := runtime.Create(
1342-
&runconfig.Config{
1343-
Image: GetTestImage(runtime).ID,
1344-
Cmd: []string{"/bin/echo", "-n", "foobar"},
1345-
Volumes: map[string]struct{}{"/test": {}},
1346-
},
1347-
"",
1348-
)
1349-
if err != nil {
1350-
t.Fatal(err)
1351-
}
1352-
defer runtime.Destroy(container)
1353-
_, err = container.Output()
1354-
if err != nil {
1355-
t.Fatal(err)
1356-
}
1357-
if !container.VolumesRW["/test"] {
1358-
t.Fail()
1359-
}
1360-
1361-
container2, _, err := runtime.Create(
1362-
&runconfig.Config{
1363-
Image: GetTestImage(runtime).ID,
1364-
Cmd: []string{"/bin/echo", "-n", "foobar"},
1365-
VolumesFrom: container.ID,
1366-
},
1367-
"",
1368-
)
1369-
if err != nil {
1370-
t.Fatal(err)
1371-
}
1372-
defer runtime.Destroy(container2)
1373-
1374-
_, err = container2.Output()
1375-
if err != nil {
1376-
t.Fatal(err)
1377-
}
1378-
1379-
if container.Volumes["/test"] != container2.Volumes["/test"] {
1380-
t.Fail()
1381-
}
1382-
1383-
actual, exists := container2.VolumesRW["/test"]
1384-
if !exists {
1385-
t.Fail()
1386-
}
1387-
1388-
if container.VolumesRW["/test"] != actual {
1389-
t.Fail()
1390-
}
1391-
}
1392-
13931276
// Test that restarting a container with a volume does not create a new volume on restart. Regression test for #819.
13941277
func TestRestartWithVolumes(t *testing.T) {
13951278
runtime := mkRuntime(t)
@@ -1434,73 +1317,6 @@ func TestRestartWithVolumes(t *testing.T) {
14341317
}
14351318
}
14361319

1437-
// Test for #1351
1438-
func TestVolumesFromWithVolumes(t *testing.T) {
1439-
runtime := mkRuntime(t)
1440-
defer nuke(runtime)
1441-
1442-
container, _, err := runtime.Create(&runconfig.Config{
1443-
Image: GetTestImage(runtime).ID,
1444-
Cmd: []string{"sh", "-c", "echo -n bar > /test/foo"},
1445-
Volumes: map[string]struct{}{"/test": {}},
1446-
},
1447-
"",
1448-
)
1449-
if err != nil {
1450-
t.Fatal(err)
1451-
}
1452-
defer runtime.Destroy(container)
1453-
1454-
for key := range container.Config.Volumes {
1455-
if key != "/test" {
1456-
t.Fail()
1457-
}
1458-
}
1459-
1460-
_, err = container.Output()
1461-
if err != nil {
1462-
t.Fatal(err)
1463-
}
1464-
1465-
expected := container.Volumes["/test"]
1466-
if expected == "" {
1467-
t.Fail()
1468-
}
1469-
1470-
container2, _, err := runtime.Create(
1471-
&runconfig.Config{
1472-
Image: GetTestImage(runtime).ID,
1473-
Cmd: []string{"cat", "/test/foo"},
1474-
VolumesFrom: container.ID,
1475-
Volumes: map[string]struct{}{"/test": {}},
1476-
},
1477-
"",
1478-
)
1479-
if err != nil {
1480-
t.Fatal(err)
1481-
}
1482-
defer runtime.Destroy(container2)
1483-
1484-
output, err := container2.Output()
1485-
if err != nil {
1486-
t.Fatal(err)
1487-
}
1488-
1489-
if string(output) != "bar" {
1490-
t.Fail()
1491-
}
1492-
1493-
if container.Volumes["/test"] != container2.Volumes["/test"] {
1494-
t.Fail()
1495-
}
1496-
1497-
// Ensure it restarts successfully
1498-
_, err = container2.Output()
1499-
if err != nil {
1500-
t.Fatal(err)
1501-
}
1502-
}
1503-
15041320
func TestContainerNetwork(t *testing.T) {
15051321
runtime := mkRuntime(t)
15061322
defer nuke(runtime)
@@ -1636,81 +1452,3 @@ func TestUnprivilegedCannotMount(t *testing.T) {
16361452
t.Fatal("Could mount into secure container")
16371453
}
16381454
}
1639-
1640-
func TestMultipleVolumesFrom(t *testing.T) {
1641-
runtime := mkRuntime(t)
1642-
defer nuke(runtime)
1643-
1644-
container, _, err := runtime.Create(&runconfig.Config{
1645-
Image: GetTestImage(runtime).ID,
1646-
Cmd: []string{"sh", "-c", "echo -n bar > /test/foo"},
1647-
Volumes: map[string]struct{}{"/test": {}},
1648-
},
1649-
"",
1650-
)
1651-
if err != nil {
1652-
t.Fatal(err)
1653-
}
1654-
defer runtime.Destroy(container)
1655-
1656-
for key := range container.Config.Volumes {
1657-
if key != "/test" {
1658-
t.Fail()
1659-
}
1660-
}
1661-
1662-
_, err = container.Output()
1663-
if err != nil {
1664-
t.Fatal(err)
1665-
}
1666-
1667-
expected := container.Volumes["/test"]
1668-
if expected == "" {
1669-
t.Fail()
1670-
}
1671-
1672-
container2, _, err := runtime.Create(
1673-
&runconfig.Config{
1674-
Image: GetTestImage(runtime).ID,
1675-
Cmd: []string{"sh", "-c", "echo -n bar > /other/foo"},
1676-
Volumes: map[string]struct{}{"/other": {}},
1677-
},
1678-
"",
1679-
)
1680-
if err != nil {
1681-
t.Fatal(err)
1682-
}
1683-
defer runtime.Destroy(container2)
1684-
1685-
for key := range container2.Config.Volumes {
1686-
if key != "/other" {
1687-
t.FailNow()
1688-
}
1689-
}
1690-
if _, err := container2.Output(); err != nil {
1691-
t.Fatal(err)
1692-
}
1693-
1694-
container3, _, err := runtime.Create(
1695-
&runconfig.Config{
1696-
Image: GetTestImage(runtime).ID,
1697-
Cmd: []string{"/bin/echo", "-n", "foobar"},
1698-
VolumesFrom: strings.Join([]string{container.ID, container2.ID}, ","),
1699-
}, "")
1700-
1701-
if err != nil {
1702-
t.Fatal(err)
1703-
}
1704-
defer runtime.Destroy(container3)
1705-
1706-
if _, err := container3.Output(); err != nil {
1707-
t.Fatal(err)
1708-
}
1709-
1710-
if container3.Volumes["/test"] != container.Volumes["/test"] {
1711-
t.Fail()
1712-
}
1713-
if container3.Volumes["/other"] != container2.Volumes["/other"] {
1714-
t.Fail()
1715-
}
1716-
}

runconfig/compare.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@ func Compare(a, b *Config) bool {
1414
a.MemorySwap != b.MemorySwap ||
1515
a.CpuShares != b.CpuShares ||
1616
a.OpenStdin != b.OpenStdin ||
17-
a.Tty != b.Tty ||
18-
a.VolumesFrom != b.VolumesFrom {
17+
a.Tty != b.Tty {
1918
return false
2019
}
2120
if len(a.Cmd) != len(b.Cmd) ||

runconfig/config.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ type Config struct {
2727
Cmd []string
2828
Image string // Name of the image as it was passed by the operator (eg. could be symbolic)
2929
Volumes map[string]struct{}
30-
VolumesFrom string
3130
WorkingDir string
3231
Entrypoint []string
3332
NetworkDisabled bool
@@ -49,7 +48,6 @@ func ContainerConfigFromJob(job *engine.Job) *Config {
4948
OpenStdin: job.GetenvBool("OpenStdin"),
5049
StdinOnce: job.GetenvBool("StdinOnce"),
5150
Image: job.Getenv("Image"),
52-
VolumesFrom: job.Getenv("VolumesFrom"),
5351
WorkingDir: job.Getenv("WorkingDir"),
5452
NetworkDisabled: job.GetenvBool("NetworkDisabled"),
5553
}

0 commit comments

Comments
 (0)