Change to enable volume name can be customized.

Signed-off-by: Liping Xue <lipingxue@gmail.com>
Change to enable volume name can be customized.
Signed-off-by: Liping Xue <lipingxue@gmail.com>

Change to enable volume name can be customized.

Remove unused debug info.

Address comments from Daniel and solve the lint error.
Signed-off-by: Liping Xue <lipingxue@gmail.com>

Address Daniel's comments to print warning message when name of external volume is set in loader code.
Signed-off-by: Liping Xue <lipingxue@gmail.com>

Address Daniel's comments to return error when external volume is set in loader code.
Signed-off-by: Liping Xue <lipingxue@gmail.com>

Address Daniel's comments to return error when external volume is set in loader code.
Signed-off-by: Liping Xue <lipingxue@gmail.com>

Remove the case that specifying external volume name in full-example.yml.

More fix.

Add unit test.
Signed-off-by: Liping Xue <lipingxue@gmail.com>

Address comments from Daniel, move the schema change to v3.4.
Signed-off-by: Liping Xue <lipingxue@gmail.com>

Address comments from Sebastiaan. Signed-off-by: Liping Xue <lipingxue@gmail.com>

Address comments from Misty.
Signed-off-by: Liping Xue <lipingxue@gmail.com>
This commit is contained in:
Liping Xue 2017-06-29 16:25:50 -07:00
parent 0adccacb38
commit 27a3080825
8 changed files with 109 additions and 2 deletions

View File

@ -74,6 +74,10 @@ func convertVolumeToMount(
return result, nil return result, nil
} }
if stackVolume.Name != "" {
result.Source = stackVolume.Name
}
result.VolumeOptions.Labels = AddStackLabel(namespace, stackVolume.Labels) result.VolumeOptions.Labels = AddStackLabel(namespace, stackVolume.Labels)
if stackVolume.Driver != "" || stackVolume.DriverOpts != nil { if stackVolume.Driver != "" || stackVolume.DriverOpts != nil {
result.VolumeOptions.DriverConfig = &mount.Driver{ result.VolumeOptions.DriverConfig = &mount.Driver{

View File

@ -98,6 +98,53 @@ func TestConvertVolumeToMountNamedVolume(t *testing.T) {
assert.Equal(t, expected, mount) assert.Equal(t, expected, mount)
} }
func TestConvertVolumeToMountNamedVolumeWithNameCustomizd(t *testing.T) {
stackVolumes := volumes{
"normal": composetypes.VolumeConfig{
Name: "user_specified_name",
Driver: "vsphere",
DriverOpts: map[string]string{
"opt": "value",
},
Labels: map[string]string{
"something": "labeled",
},
},
}
namespace := NewNamespace("foo")
expected := mount.Mount{
Type: mount.TypeVolume,
Source: "user_specified_name",
Target: "/foo",
ReadOnly: true,
VolumeOptions: &mount.VolumeOptions{
Labels: map[string]string{
LabelNamespace: "foo",
"something": "labeled",
},
DriverConfig: &mount.Driver{
Name: "vsphere",
Options: map[string]string{
"opt": "value",
},
},
NoCopy: true,
},
}
config := composetypes.ServiceVolumeConfig{
Type: "volume",
Source: "normal",
Target: "/foo",
ReadOnly: true,
Volume: &composetypes.ServiceVolumeVolume{
NoCopy: true,
},
}
mount, err := convertVolumeToMount(config, stackVolumes, namespace)
assert.NoError(t, err)
assert.Equal(t, expected, mount)
}
func TestConvertVolumeToMountNamedVolumeExternal(t *testing.T) { func TestConvertVolumeToMountNamedVolumeExternal(t *testing.T) {
stackVolumes := volumes{ stackVolumes := volumes{
"outside": composetypes.VolumeConfig{ "outside": composetypes.VolumeConfig{

View File

@ -1,4 +1,4 @@
version: "3.3" version: "3.4"
services: services:
foo: foo:
@ -280,6 +280,15 @@ volumes:
foo: "bar" foo: "bar"
baz: 1 baz: 1
another-volume:
name: "user_specified_name"
driver: vsphere
driver_opts:
# Values can be strings or numbers
foo: "bar"
baz: 1
external-volume: external-volume:
# Specifies that a pre-existing volume called "external-volume" # Specifies that a pre-existing volume called "external-volume"
# can be referred to within this file as "external-volume" # can be referred to within this file as "external-volume"
@ -288,5 +297,12 @@ volumes:
other-external-volume: other-external-volume:
# Specifies that a pre-existing volume called "my-cool-volume" # Specifies that a pre-existing volume called "my-cool-volume"
# can be referred to within this file as "other-external-volume" # can be referred to within this file as "other-external-volume"
# This example uses the deprecated "volume.external.name" (replaced by "volume.name")
external: external:
name: my-cool-volume name: my-cool-volume
external-volume3:
# Specifies that a pre-existing volume called "this-is-volume3"
# can be referred to within this file as "external-volume3"
name: this-is-volume3
external: true

View File

@ -444,6 +444,12 @@ func LoadVolumes(source map[string]interface{}) (map[string]types.VolumeConfig,
if volume.External.Name == "" { if volume.External.Name == "" {
volume.External.Name = name volume.External.Name = name
volumes[name] = volume volumes[name] = volume
} else {
logrus.Warnf("volume %s: volume.external.name is deprecated in favor of volume.name", name)
if volume.Name != "" {
return nil, errors.Errorf("volume %s: volume.external.name and volume.name conflict; only use volume.name", name)
}
} }
} }
} }

View File

@ -628,6 +628,22 @@ volumes:
assert.Contains(t, err.Error(), "external_volume") assert.Contains(t, err.Error(), "external_volume")
} }
func TestInvalidExternalNameAndNameCombination(t *testing.T) {
_, err := loadYAML(`
version: "3.4"
volumes:
external_volume:
name: user_specified_name
external:
name: external_name
`)
assert.Error(t, err)
fmt.Println(err)
assert.Contains(t, err.Error(), "volume.external.name and volume.name conflict; only use volume.name")
assert.Contains(t, err.Error(), "external_volume")
}
func durationPtr(value time.Duration) *time.Duration { func durationPtr(value time.Duration) *time.Duration {
return &value return &value
} }
@ -983,6 +999,14 @@ func TestFullExample(t *testing.T) {
"baz": "1", "baz": "1",
}, },
}, },
"another-volume": {
Name: "user_specified_name",
Driver: "vsphere",
DriverOpts: map[string]string{
"foo": "bar",
"baz": "1",
},
},
"external-volume": { "external-volume": {
External: types.External{ External: types.External{
Name: "external-volume", Name: "external-volume",
@ -995,6 +1019,13 @@ func TestFullExample(t *testing.T) {
External: true, External: true,
}, },
}, },
"external-volume3": {
Name: "this-is-volume3",
External: types.External{
Name: "external-volume3",
External: true,
},
},
} }
assert.Equal(t, expectedVolumeConfig, config.Volumes) assert.Equal(t, expectedVolumeConfig, config.Volumes)

File diff suppressed because one or more lines are too long

View File

@ -437,6 +437,7 @@
"id": "#/definitions/volume", "id": "#/definitions/volume",
"type": ["object", "null"], "type": ["object", "null"],
"properties": { "properties": {
"name": {"type": "string"},
"driver": {"type": "string"}, "driver": {"type": "string"},
"driver_opts": { "driver_opts": {
"type": "object", "type": "object",

View File

@ -305,6 +305,7 @@ type IPAMPool struct {
// VolumeConfig for a volume // VolumeConfig for a volume
type VolumeConfig struct { type VolumeConfig struct {
Name string
Driver string Driver string
DriverOpts map[string]string `mapstructure:"driver_opts"` DriverOpts map[string]string `mapstructure:"driver_opts"`
External External External External
@ -313,6 +314,7 @@ type VolumeConfig struct {
// External identifies a Volume or Network as a reference to a resource that is // External identifies a Volume or Network as a reference to a resource that is
// not managed, and should already exist. // not managed, and should already exist.
// External.name is deprecated and replaced by Volume.name
type External struct { type External struct {
Name string Name string
External bool External bool