Fix: a failed Start() breaks --volumes-from on subsequent Start()'s
| ... | ... |
@@ -204,15 +204,20 @@ func parseBindMountSpec(spec string) (string, string, bool, error) {
|
| 204 | 204 |
func (container *Container) applyVolumesFrom() error {
|
| 205 | 205 |
volumesFrom := container.hostConfig.VolumesFrom |
| 206 | 206 |
|
| 207 |
+ mountGroups := make([]map[string]*Mount, 0, len(volumesFrom)) |
|
| 208 |
+ |
|
| 207 | 209 |
for _, spec := range volumesFrom {
|
| 208 |
- mounts, err := parseVolumesFromSpec(container.daemon, spec) |
|
| 210 |
+ mountGroup, err := parseVolumesFromSpec(container.daemon, spec) |
|
| 209 | 211 |
if err != nil {
|
| 210 | 212 |
return err |
| 211 | 213 |
} |
| 214 |
+ mountGroups = append(mountGroups, mountGroup) |
|
| 215 |
+ } |
|
| 212 | 216 |
|
| 217 |
+ for _, mounts := range mountGroups {
|
|
| 213 | 218 |
for _, mnt := range mounts {
|
| 214 | 219 |
mnt.container = container |
| 215 |
- if err = mnt.initialize(); err != nil {
|
|
| 220 |
+ if err := mnt.initialize(); err != nil {
|
|
| 216 | 221 |
return err |
| 217 | 222 |
} |
| 218 | 223 |
} |
| ... | ... |
@@ -109,3 +109,31 @@ func TestStartRecordError(t *testing.T) {
|
| 109 | 109 |
|
| 110 | 110 |
logDone("start - set state error when start fails")
|
| 111 | 111 |
} |
| 112 |
+ |
|
| 113 |
+// gh#8726: a failed Start() breaks --volumes-from on subsequent Start()'s |
|
| 114 |
+func TestStartVolumesFromFailsCleanly(t *testing.T) {
|
|
| 115 |
+ defer deleteAllContainers() |
|
| 116 |
+ |
|
| 117 |
+ // Create the first data volume |
|
| 118 |
+ cmd(t, "run", "-d", "--name", "data_before", "-v", "/foo", "busybox") |
|
| 119 |
+ |
|
| 120 |
+ // Expect this to fail because the data test after contaienr doesn't exist yet |
|
| 121 |
+ if _, err := runCommand(exec.Command(dockerBinary, "run", "-d", "--name", "consumer", "--volumes-from", "data_before", "--volumes-from", "data_after", "busybox")); err == nil {
|
|
| 122 |
+ t.Fatal("Expected error but got none")
|
|
| 123 |
+ } |
|
| 124 |
+ |
|
| 125 |
+ // Create the second data volume |
|
| 126 |
+ cmd(t, "run", "-d", "--name", "data_after", "-v", "/bar", "busybox") |
|
| 127 |
+ |
|
| 128 |
+ // Now, all the volumes should be there |
|
| 129 |
+ cmd(t, "start", "consumer") |
|
| 130 |
+ |
|
| 131 |
+ // Check that we have the volumes we want |
|
| 132 |
+ out, _, _ := cmd(t, "inspect", "--format='{{ len .Volumes }}'", "consumer")
|
|
| 133 |
+ n_volumes := strings.Trim(out, " \r\n'") |
|
| 134 |
+ if n_volumes != "2" {
|
|
| 135 |
+ t.Fatalf("Missing volumes: expected 2, got %s", n_volumes)
|
|
| 136 |
+ } |
|
| 137 |
+ |
|
| 138 |
+ logDone("start - missing containers in --volumes-from did not affect subsequent runs")
|
|
| 139 |
+} |