1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

Handle bind options and volume options

Signed-off-by: Daniel Nephin <dnephin@docker.com>
This commit is contained in:
Daniel Nephin 2016-11-10 11:33:00 -05:00
parent bd8de8d8be
commit ef90081d44

View file

@ -259,70 +259,107 @@ func convertVolumes(
) ([]mount.Mount, error) { ) ([]mount.Mount, error) {
var mounts []mount.Mount var mounts []mount.Mount
for _, volumeString := range serviceVolumes { for _, volumeSpec := range serviceVolumes {
var ( mount, err := convertVolumeToMount(volumeSpec, stackVolumes, namespace)
source, target string if err != nil {
mountType mount.Type return nil, err
readOnly bool
volumeOptions *mount.VolumeOptions
)
// TODO: split Windows path mappings properly
parts := strings.SplitN(volumeString, ":", 3)
if len(parts) == 3 {
source = parts[0]
target = parts[1]
if parts[2] == "ro" {
readOnly = true
}
} else if len(parts) == 2 {
source = parts[0]
target = parts[1]
} else if len(parts) == 1 {
target = parts[0]
} }
mounts = append(mounts, mount)
}
return mounts, nil
}
// TODO: catch Windows paths here func convertVolumeToMount(
if strings.HasPrefix(source, "/") { volumeSpec string,
mountType = mount.TypeBind stackVolumes map[string]composetypes.VolumeConfig,
} else { namespace namespace,
mountType = mount.TypeVolume ) (mount.Mount, error) {
var source, target string
var mode []string
stackVolume, exists := stackVolumes[source] // TODO: split Windows path mappings properly
if !exists { parts := strings.SplitN(volumeSpec, ":", 3)
// TODO: better error message (include service name)
return nil, fmt.Errorf("Undefined volume: %s", source)
}
if stackVolume.External.Name != "" { switch len(parts) {
source = stackVolume.External.Name case 3:
} else { source = parts[0]
volumeOptions = &mount.VolumeOptions{ target = parts[1]
Labels: stackVolume.Labels, mode = strings.Split(parts[2], ",")
} case 2:
source = parts[0]
if stackVolume.Driver != "" { target = parts[1]
volumeOptions.DriverConfig = &mount.Driver{ case 1:
Name: stackVolume.Driver, target = parts[0]
Options: stackVolume.DriverOpts, default:
} return mount.Mount{}, fmt.Errorf("invald volume: %s", volumeSpec)
}
source = namespace.scope(source)
}
}
mounts = append(mounts, mount.Mount{
Type: mountType,
Source: source,
Target: target,
ReadOnly: readOnly,
VolumeOptions: volumeOptions,
})
} }
return mounts, nil // TODO: catch Windows paths here
if strings.HasPrefix(source, "/") {
return mount.Mount{
Type: mount.TypeBind,
Source: source,
Target: target,
ReadOnly: isReadOnly(mode),
BindOptions: getBindOptions(mode),
}, nil
}
stackVolume, exists := stackVolumes[source]
if !exists {
return mount.Mount{}, fmt.Errorf("undefined volume: %s", source)
}
var volumeOptions *mount.VolumeOptions
if stackVolume.External.Name != "" {
source = stackVolume.External.Name
} else {
volumeOptions = &mount.VolumeOptions{
Labels: stackVolume.Labels,
NoCopy: isNoCopy(mode),
}
if stackVolume.Driver != "" {
volumeOptions.DriverConfig = &mount.Driver{
Name: stackVolume.Driver,
Options: stackVolume.DriverOpts,
}
}
source = namespace.scope(source)
}
return mount.Mount{
Type: mount.TypeVolume,
Source: source,
Target: target,
ReadOnly: isReadOnly(mode),
VolumeOptions: volumeOptions,
}, nil
}
func modeHas(mode []string, field string) bool {
for _, item := range mode {
if item == field {
return true
}
}
return false
}
func isReadOnly(mode []string) bool {
return modeHas(mode, "ro")
}
func isNoCopy(mode []string) bool {
return modeHas(mode, "nocopy")
}
func getBindOptions(mode []string) *mount.BindOptions {
for _, item := range mode {
if strings.Contains(item, "private") || strings.Contains(item, "shared") || strings.Contains(item, "slave") {
return &mount.BindOptions{Propagation: mount.Propagation(item)}
}
}
return nil
} }
func deployServices( func deployServices(
@ -429,6 +466,7 @@ func convertService(
mounts, err := convertVolumes(service.Volumes, volumes, namespace) mounts, err := convertVolumes(service.Volumes, volumes, namespace)
if err != nil { if err != nil {
// TODO: better error message (include service name)
return swarm.ServiceSpec{}, err return swarm.ServiceSpec{}, err
} }