Add a test for loading expanded mount format.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
| ... | ... |
@@ -251,6 +251,8 @@ func transformHook( |
| 251 | 251 |
return transformMappingOrList(data, "="), nil |
| 252 | 252 |
case reflect.TypeOf(types.MappingWithColon{}):
|
| 253 | 253 |
return transformMappingOrList(data, ":"), nil |
| 254 |
+ case reflect.TypeOf(types.ServiceVolumeConfig{}):
|
|
| 255 |
+ return transformServiceVolumeConfig(data) |
|
| 254 | 256 |
} |
| 255 | 257 |
return data, nil |
| 256 | 258 |
} |
| ... | ... |
@@ -329,10 +331,7 @@ func loadService(name string, serviceDict types.Dict, workingDir string) (*types |
| 329 | 329 |
return nil, err |
| 330 | 330 |
} |
| 331 | 331 |
|
| 332 |
- if err := resolveVolumePaths(serviceConfig.Volumes, workingDir); err != nil {
|
|
| 333 |
- return nil, err |
|
| 334 |
- } |
|
| 335 |
- |
|
| 332 |
+ resolveVolumePaths(serviceConfig.Volumes, workingDir) |
|
| 336 | 333 |
return serviceConfig, nil |
| 337 | 334 |
} |
| 338 | 335 |
|
| ... | ... |
@@ -365,22 +364,15 @@ func resolveEnvironment(serviceConfig *types.ServiceConfig, workingDir string) e |
| 365 | 365 |
return nil |
| 366 | 366 |
} |
| 367 | 367 |
|
| 368 |
-func resolveVolumePaths(volumes []string, workingDir string) error {
|
|
| 369 |
- for i, mapping := range volumes {
|
|
| 370 |
- parts := strings.SplitN(mapping, ":", 2) |
|
| 371 |
- if len(parts) == 1 {
|
|
| 368 |
+func resolveVolumePaths(volumes []types.ServiceVolumeConfig, workingDir string) {
|
|
| 369 |
+ for i, volume := range volumes {
|
|
| 370 |
+ if volume.Type != "bind" {
|
|
| 372 | 371 |
continue |
| 373 | 372 |
} |
| 374 | 373 |
|
| 375 |
- if strings.HasPrefix(parts[0], ".") {
|
|
| 376 |
- parts[0] = absPath(workingDir, parts[0]) |
|
| 377 |
- } |
|
| 378 |
- parts[0] = expandUser(parts[0]) |
|
| 379 |
- |
|
| 380 |
- volumes[i] = strings.Join(parts, ":") |
|
| 374 |
+ volume.Source = absPath(workingDir, expandUser(volume.Source)) |
|
| 375 |
+ volumes[i] = volume |
|
| 381 | 376 |
} |
| 382 |
- |
|
| 383 |
- return nil |
|
| 384 | 377 |
} |
| 385 | 378 |
|
| 386 | 379 |
// TODO: make this more robust |
| ... | ... |
@@ -533,6 +525,20 @@ func transformServiceSecret(data interface{}) (interface{}, error) {
|
| 533 | 533 |
} |
| 534 | 534 |
} |
| 535 | 535 |
|
| 536 |
+func transformServiceVolumeConfig(data interface{}) (interface{}, error) {
|
|
| 537 |
+ switch value := data.(type) {
|
|
| 538 |
+ case string: |
|
| 539 |
+ return parseVolume(value) |
|
| 540 |
+ case types.Dict: |
|
| 541 |
+ return data, nil |
|
| 542 |
+ case map[string]interface{}:
|
|
| 543 |
+ return data, nil |
|
| 544 |
+ default: |
|
| 545 |
+ return data, fmt.Errorf("invalid type %T for service volume", value)
|
|
| 546 |
+ } |
|
| 547 |
+ |
|
| 548 |
+} |
|
| 549 |
+ |
|
| 536 | 550 |
func transformServiceNetworkMap(value interface{}) (interface{}, error) {
|
| 537 | 551 |
if list, ok := value.([]interface{}); ok {
|
| 538 | 552 |
mapValue := map[interface{}]interface{}{}
|
| ... | ... |
@@ -837,13 +837,13 @@ func TestFullExample(t *testing.T) {
|
| 837 | 837 |
}, |
| 838 | 838 |
}, |
| 839 | 839 |
User: "someone", |
| 840 |
- Volumes: []string{
|
|
| 841 |
- "/var/lib/mysql", |
|
| 842 |
- "/opt/data:/var/lib/mysql", |
|
| 843 |
- fmt.Sprintf("%s:/code", workingDir),
|
|
| 844 |
- fmt.Sprintf("%s/static:/var/www/html", workingDir),
|
|
| 845 |
- fmt.Sprintf("%s/configs:/etc/configs/:ro", homeDir),
|
|
| 846 |
- "datavolume:/var/lib/mysql", |
|
| 840 |
+ Volumes: []types.ServiceVolumeConfig{
|
|
| 841 |
+ {Target: "/var/lib/mysql", Type: "volume"},
|
|
| 842 |
+ {Source: "/opt/data", Target: "/var/lib/mysql", Type: "bind"},
|
|
| 843 |
+ {Source: workingDir, Target: "/code", Type: "bind"},
|
|
| 844 |
+ {Source: workingDir + "/static", Target: "/var/www/html", Type: "bind"},
|
|
| 845 |
+ {Source: homeDir + "/configs", Target: "/etc/configs/", Type: "bind", ReadOnly: true},
|
|
| 846 |
+ {Source: "datavolume", Target: "/var/lib/mysql", Type: "volume"},
|
|
| 847 | 847 |
}, |
| 848 | 848 |
WorkingDir: "/code", |
| 849 | 849 |
} |
| ... | ... |
@@ -1041,3 +1041,31 @@ services: |
| 1041 | 1041 |
assert.Equal(t, 1, len(config.Services)) |
| 1042 | 1042 |
assert.Equal(t, expected, config.Services[0].Ports) |
| 1043 | 1043 |
} |
| 1044 |
+ |
|
| 1045 |
+func TestLoadExpandedMountFormat(t *testing.T) {
|
|
| 1046 |
+ config, err := loadYAML(` |
|
| 1047 |
+version: "3.1" |
|
| 1048 |
+services: |
|
| 1049 |
+ web: |
|
| 1050 |
+ image: busybox |
|
| 1051 |
+ volumes: |
|
| 1052 |
+ - type: volume |
|
| 1053 |
+ source: foo |
|
| 1054 |
+ target: /target |
|
| 1055 |
+ read_only: true |
|
| 1056 |
+volumes: |
|
| 1057 |
+ foo: {}
|
|
| 1058 |
+`) |
|
| 1059 |
+ assert.NoError(t, err) |
|
| 1060 |
+ |
|
| 1061 |
+ expected := types.ServiceVolumeConfig{
|
|
| 1062 |
+ Type: "volume", |
|
| 1063 |
+ Source: "foo", |
|
| 1064 |
+ Target: "/target", |
|
| 1065 |
+ ReadOnly: true, |
|
| 1066 |
+ } |
|
| 1067 |
+ |
|
| 1068 |
+ assert.Equal(t, 1, len(config.Services)) |
|
| 1069 |
+ assert.Equal(t, 1, len(config.Services[0].Volumes)) |
|
| 1070 |
+ assert.Equal(t, expected, config.Services[0].Volumes[0]) |
|
| 1071 |
+} |