Support expanded mounts in Compose loader

Add a test for loading expanded mount format.

Signed-off-by: Daniel Nephin <dnephin@docker.com>
This commit is contained in:
Daniel Nephin 2017-01-24 12:09:53 -05:00
parent a442213b92
commit 29f39ea244
3 changed files with 58 additions and 24 deletions

View File

@ -251,6 +251,8 @@ func transformHook(
return transformMappingOrList(data, "="), nil return transformMappingOrList(data, "="), nil
case reflect.TypeOf(types.MappingWithColon{}): case reflect.TypeOf(types.MappingWithColon{}):
return transformMappingOrList(data, ":"), nil return transformMappingOrList(data, ":"), nil
case reflect.TypeOf(types.ServiceVolumeConfig{}):
return transformServiceVolumeConfig(data)
} }
return data, nil return data, nil
} }
@ -329,10 +331,7 @@ func loadService(name string, serviceDict types.Dict, workingDir string) (*types
return nil, err return nil, err
} }
if err := resolveVolumePaths(serviceConfig.Volumes, workingDir); err != nil { resolveVolumePaths(serviceConfig.Volumes, workingDir)
return nil, err
}
return serviceConfig, nil return serviceConfig, nil
} }
@ -365,22 +364,15 @@ func resolveEnvironment(serviceConfig *types.ServiceConfig, workingDir string) e
return nil return nil
} }
func resolveVolumePaths(volumes []string, workingDir string) error { func resolveVolumePaths(volumes []types.ServiceVolumeConfig, workingDir string) {
for i, mapping := range volumes { for i, volume := range volumes {
parts := strings.SplitN(mapping, ":", 2) if volume.Type != "bind" {
if len(parts) == 1 {
continue continue
} }
if strings.HasPrefix(parts[0], ".") { volume.Source = absPath(workingDir, expandUser(volume.Source))
parts[0] = absPath(workingDir, parts[0]) volumes[i] = volume
} }
parts[0] = expandUser(parts[0])
volumes[i] = strings.Join(parts, ":")
}
return nil
} }
// TODO: make this more robust // TODO: make this more robust
@ -533,6 +525,20 @@ func transformServiceSecret(data interface{}) (interface{}, error) {
} }
} }
func transformServiceVolumeConfig(data interface{}) (interface{}, error) {
switch value := data.(type) {
case string:
return parseVolume(value)
case types.Dict:
return data, nil
case map[string]interface{}:
return data, nil
default:
return data, fmt.Errorf("invalid type %T for service volume", value)
}
}
func transformServiceNetworkMap(value interface{}) (interface{}, error) { func transformServiceNetworkMap(value interface{}) (interface{}, error) {
if list, ok := value.([]interface{}); ok { if list, ok := value.([]interface{}); ok {
mapValue := map[interface{}]interface{}{} mapValue := map[interface{}]interface{}{}

View File

@ -837,13 +837,13 @@ func TestFullExample(t *testing.T) {
}, },
}, },
User: "someone", User: "someone",
Volumes: []string{ Volumes: []types.ServiceVolumeConfig{
"/var/lib/mysql", {Target: "/var/lib/mysql", Type: "volume"},
"/opt/data:/var/lib/mysql", {Source: "/opt/data", Target: "/var/lib/mysql", Type: "bind"},
fmt.Sprintf("%s:/code", workingDir), {Source: workingDir, Target: "/code", Type: "bind"},
fmt.Sprintf("%s/static:/var/www/html", workingDir), {Source: workingDir + "/static", Target: "/var/www/html", Type: "bind"},
fmt.Sprintf("%s/configs:/etc/configs/:ro", homeDir), {Source: homeDir + "/configs", Target: "/etc/configs/", Type: "bind", ReadOnly: true},
"datavolume:/var/lib/mysql", {Source: "datavolume", Target: "/var/lib/mysql", Type: "volume"},
}, },
WorkingDir: "/code", WorkingDir: "/code",
} }
@ -1041,3 +1041,31 @@ services:
assert.Equal(t, 1, len(config.Services)) assert.Equal(t, 1, len(config.Services))
assert.Equal(t, expected, config.Services[0].Ports) assert.Equal(t, expected, config.Services[0].Ports)
} }
func TestLoadExpandedMountFormat(t *testing.T) {
config, err := loadYAML(`
version: "3.1"
services:
web:
image: busybox
volumes:
- type: volume
source: foo
target: /target
read_only: true
volumes:
foo: {}
`)
assert.NoError(t, err)
expected := types.ServiceVolumeConfig{
Type: "volume",
Source: "foo",
Target: "/target",
ReadOnly: true,
}
assert.Equal(t, 1, len(config.Services))
assert.Equal(t, 1, len(config.Services[0].Volumes))
assert.Equal(t, expected, config.Services[0].Volumes[0])
}

View File

@ -228,7 +228,7 @@ type ServiceVolumeConfig struct {
Type string Type string
Source string Source string
Target string Target string
ReadOnly string `mapstructure:"read_only"` ReadOnly bool `mapstructure:"read_only"`
Bind *ServiceVolumeBind Bind *ServiceVolumeBind
Volume *ServiceVolumeVolume Volume *ServiceVolumeVolume
} }