mirror of https://github.com/docker/cli.git
Change merge strategy for service volumes
Signed-off-by: Stoica-Marcu Floris-Andrei <floris.sm@gmail.com>
This commit is contained in:
parent
dfc214115b
commit
fbea85d472
|
@ -58,6 +58,7 @@ func mergeServices(base, override []types.ServiceConfig) ([]types.ServiceConfig,
|
||||||
reflect.TypeOf([]types.ServiceSecretConfig{}): mergeSlice(toServiceSecretConfigsMap, toServiceSecretConfigsSlice),
|
reflect.TypeOf([]types.ServiceSecretConfig{}): mergeSlice(toServiceSecretConfigsMap, toServiceSecretConfigsSlice),
|
||||||
reflect.TypeOf([]types.ServiceConfigObjConfig{}): mergeSlice(toServiceConfigObjConfigsMap, toSServiceConfigObjConfigsSlice),
|
reflect.TypeOf([]types.ServiceConfigObjConfig{}): mergeSlice(toServiceConfigObjConfigsMap, toSServiceConfigObjConfigsSlice),
|
||||||
reflect.TypeOf(&types.UlimitsConfig{}): mergeUlimitsConfig,
|
reflect.TypeOf(&types.UlimitsConfig{}): mergeUlimitsConfig,
|
||||||
|
reflect.TypeOf([]types.ServiceVolumeConfig{}): mergeSlice(toServiceVolumeConfigsMap, toServiceVolumeConfigsSlice),
|
||||||
reflect.TypeOf(&types.ServiceNetworkConfig{}): mergeServiceNetworkConfig,
|
reflect.TypeOf(&types.ServiceNetworkConfig{}): mergeServiceNetworkConfig,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -116,6 +117,18 @@ func toServicePortConfigsMap(s interface{}) (map[interface{}]interface{}, error)
|
||||||
return m, nil
|
return m, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func toServiceVolumeConfigsMap(s interface{}) (map[interface{}]interface{}, error) {
|
||||||
|
volumes, ok := s.([]types.ServiceVolumeConfig)
|
||||||
|
if !ok {
|
||||||
|
return nil, errors.Errorf("not a serviceVolumeConfig slice: %v", s)
|
||||||
|
}
|
||||||
|
m := map[interface{}]interface{}{}
|
||||||
|
for _, v := range volumes {
|
||||||
|
m[v.Target] = v
|
||||||
|
}
|
||||||
|
return m, nil
|
||||||
|
}
|
||||||
|
|
||||||
func toServiceSecretConfigsSlice(dst reflect.Value, m map[interface{}]interface{}) error {
|
func toServiceSecretConfigsSlice(dst reflect.Value, m map[interface{}]interface{}) error {
|
||||||
s := []types.ServiceSecretConfig{}
|
s := []types.ServiceSecretConfig{}
|
||||||
for _, v := range m {
|
for _, v := range m {
|
||||||
|
@ -146,6 +159,16 @@ func toServicePortConfigsSlice(dst reflect.Value, m map[interface{}]interface{})
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func toServiceVolumeConfigsSlice(dst reflect.Value, m map[interface{}]interface{}) error {
|
||||||
|
s := []types.ServiceVolumeConfig{}
|
||||||
|
for _, v := range m {
|
||||||
|
s = append(s, v.(types.ServiceVolumeConfig))
|
||||||
|
}
|
||||||
|
sort.Slice(s, func(i, j int) bool { return s[i].Target < s[j].Target })
|
||||||
|
dst.Set(reflect.ValueOf(s))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type tomapFn func(s interface{}) (map[interface{}]interface{}, error)
|
type tomapFn func(s interface{}) (map[interface{}]interface{}, error)
|
||||||
type writeValueFromMapFn func(reflect.Value, map[interface{}]interface{}) error
|
type writeValueFromMapFn func(reflect.Value, map[interface{}]interface{}) error
|
||||||
|
|
||||||
|
@ -211,6 +234,14 @@ func mergeUlimitsConfig(dst, src reflect.Value) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//nolint: unparam
|
||||||
|
func mergeServiceVolumeConfig(dst, src reflect.Value) error {
|
||||||
|
if dst.Elem().FieldByName("target").String() == src.Elem().FieldByName("target").String() {
|
||||||
|
dst.Set(src.Elem())
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
//nolint: unparam
|
//nolint: unparam
|
||||||
func mergeServiceNetworkConfig(dst, src reflect.Value) error {
|
func mergeServiceNetworkConfig(dst, src reflect.Value) error {
|
||||||
if src.Interface() != reflect.Zero(reflect.TypeOf(src.Interface())).Interface() {
|
if src.Interface() != reflect.Zero(reflect.TypeOf(src.Interface())).Interface() {
|
||||||
|
|
|
@ -1017,6 +1017,81 @@ func TestLoadMultipleNetworks(t *testing.T) {
|
||||||
}, config)
|
}, config)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestLoadMultipleServiceVolumes(t *testing.T) {
|
||||||
|
base := map[string]interface{}{
|
||||||
|
"version": "3.7",
|
||||||
|
"services": map[string]interface{}{
|
||||||
|
"foo": map[string]interface{}{
|
||||||
|
"image": "baz",
|
||||||
|
"volumes": []interface{}{
|
||||||
|
map[string]interface{}{
|
||||||
|
"type": "volume",
|
||||||
|
"source": "sourceVolume",
|
||||||
|
"target": "/var/app",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"volumes": map[string]interface{}{
|
||||||
|
"sourceVolume": map[string]interface{}{},
|
||||||
|
},
|
||||||
|
"networks": map[string]interface{}{},
|
||||||
|
"secrets": map[string]interface{}{},
|
||||||
|
"configs": map[string]interface{}{},
|
||||||
|
}
|
||||||
|
override := map[string]interface{}{
|
||||||
|
"version": "3.7",
|
||||||
|
"services": map[string]interface{}{
|
||||||
|
"foo": map[string]interface{}{
|
||||||
|
"image": "baz",
|
||||||
|
"volumes": []interface{}{
|
||||||
|
map[string]interface{}{
|
||||||
|
"type": "volume",
|
||||||
|
"source": "/local",
|
||||||
|
"target": "/var/app",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"volumes": map[string]interface{}{},
|
||||||
|
"networks": map[string]interface{}{},
|
||||||
|
"secrets": map[string]interface{}{},
|
||||||
|
"configs": map[string]interface{}{},
|
||||||
|
}
|
||||||
|
configDetails := types.ConfigDetails{
|
||||||
|
ConfigFiles: []types.ConfigFile{
|
||||||
|
{Filename: "base.yml", Config: base},
|
||||||
|
{Filename: "override.yml", Config: override},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
config, err := Load(configDetails)
|
||||||
|
assert.NilError(t, err)
|
||||||
|
assert.DeepEqual(t, &types.Config{
|
||||||
|
Filename: "base.yml",
|
||||||
|
Version: "3.7",
|
||||||
|
Services: []types.ServiceConfig{
|
||||||
|
{
|
||||||
|
Name: "foo",
|
||||||
|
Image: "baz",
|
||||||
|
Environment: types.MappingWithEquals{},
|
||||||
|
Volumes: []types.ServiceVolumeConfig{
|
||||||
|
{
|
||||||
|
Type: "volume",
|
||||||
|
Source: "/local",
|
||||||
|
Target: "/var/app",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Volumes: map[string]types.VolumeConfig{
|
||||||
|
"sourceVolume": {},
|
||||||
|
},
|
||||||
|
Secrets: map[string]types.SecretConfig{},
|
||||||
|
Configs: map[string]types.ConfigObjConfig{},
|
||||||
|
Networks: map[string]types.NetworkConfig{},
|
||||||
|
}, config)
|
||||||
|
}
|
||||||
|
|
||||||
func TestMergeUlimitsConfig(t *testing.T) {
|
func TestMergeUlimitsConfig(t *testing.T) {
|
||||||
specials := &specials{
|
specials := &specials{
|
||||||
m: map[reflect.Type]func(dst, src reflect.Value) error{
|
m: map[reflect.Type]func(dst, src reflect.Value) error{
|
||||||
|
|
Loading…
Reference in New Issue