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
case reflect.TypeOf(types.MappingWithColon{}):
return transformMappingOrList(data, ":"), nil
case reflect.TypeOf(types.ServiceVolumeConfig{}):
return transformServiceVolumeConfig(data)
}
return data, nil
}
@ -329,10 +331,7 @@ func loadService(name string, serviceDict types.Dict, workingDir string) (*types
return nil, err
}
if err := resolveVolumePaths(serviceConfig.Volumes, workingDir); err != nil {
return nil, err
}
resolveVolumePaths(serviceConfig.Volumes, workingDir)
return serviceConfig, nil
}
@ -365,22 +364,15 @@ func resolveEnvironment(serviceConfig *types.ServiceConfig, workingDir string) e
return nil
}
func resolveVolumePaths(volumes []string, workingDir string) error {
for i, mapping := range volumes {
parts := strings.SplitN(mapping, ":", 2)
if len(parts) == 1 {
func resolveVolumePaths(volumes []types.ServiceVolumeConfig, workingDir string) {
for i, volume := range volumes {
if volume.Type != "bind" {
continue
}
if strings.HasPrefix(parts[0], ".") {
parts[0] = absPath(workingDir, parts[0])
}
parts[0] = expandUser(parts[0])
volumes[i] = strings.Join(parts, ":")
volume.Source = absPath(workingDir, expandUser(volume.Source))
volumes[i] = volume
}
return nil
}
// 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) {
if list, ok := value.([]interface{}); ok {
mapValue := map[interface{}]interface{}{}

View File

@ -837,13 +837,13 @@ func TestFullExample(t *testing.T) {
},
},
User: "someone",
Volumes: []string{
"/var/lib/mysql",
"/opt/data:/var/lib/mysql",
fmt.Sprintf("%s:/code", workingDir),
fmt.Sprintf("%s/static:/var/www/html", workingDir),
fmt.Sprintf("%s/configs:/etc/configs/:ro", homeDir),
"datavolume:/var/lib/mysql",
Volumes: []types.ServiceVolumeConfig{
{Target: "/var/lib/mysql", Type: "volume"},
{Source: "/opt/data", Target: "/var/lib/mysql", Type: "bind"},
{Source: workingDir, Target: "/code", Type: "bind"},
{Source: workingDir + "/static", Target: "/var/www/html", Type: "bind"},
{Source: homeDir + "/configs", Target: "/etc/configs/", Type: "bind", ReadOnly: true},
{Source: "datavolume", Target: "/var/lib/mysql", Type: "volume"},
},
WorkingDir: "/code",
}
@ -1041,3 +1041,31 @@ services:
assert.Equal(t, 1, len(config.Services))
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
Source string
Target string
ReadOnly string `mapstructure:"read_only"`
ReadOnly bool `mapstructure:"read_only"`
Bind *ServiceVolumeBind
Volume *ServiceVolumeVolume
}