diff --git a/pkg/daemons/config/types.go b/pkg/daemons/config/types.go index 0ee3861b22..f40648bd91 100644 --- a/pkg/daemons/config/types.go +++ b/pkg/daemons/config/types.go @@ -283,24 +283,78 @@ func (a ArgString) String() string { return b.String() } -// GetArgs appends extra arguments to existing arguments overriding any default options. -func GetArgs(argsMap map[string]string, extraArgs []string) []string { +// GetArgs appends extra arguments to existing arguments with logic to override any default +// arguments whilst also allowing to prefix and suffix default string slice arguments. +func GetArgs(initialArgs map[string]string, extraArgs []string) []string { const hyphens = "--" - // add extra args to args map to override any default option - for _, arg := range extraArgs { - splitArg := strings.SplitN(strings.TrimPrefix(arg, hyphens), "=", 2) - if len(splitArg) < 2 { - argsMap[splitArg[0]] = "true" - continue + multiArgs := make(map[string][]string) + + for _, unsplitArg := range extraArgs { + splitArg := strings.SplitN(strings.TrimPrefix(unsplitArg, hyphens), "=", 2) + arg := splitArg[0] + value := "true" + if len(splitArg) > 1 { + value = splitArg[1] } - argsMap[splitArg[0]] = splitArg[1] + + // After the first iteration, initial args will be empty when handling + // duplicate arguments as they will form part of existingValues + cleanedArg := strings.TrimRight(arg, "-+") + initialValue, initialValueExists := initialArgs[cleanedArg] + existingValues, existingValuesFound := multiArgs[cleanedArg] + + newValues := make([]string, 0) + if strings.HasSuffix(arg, "+") { // Append value to initial args + if initialValueExists { + newValues = append(newValues, initialValue) + } + if existingValuesFound { + newValues = append(newValues, existingValues...) + } + newValues = append(newValues, value) + + } else if strings.HasSuffix(arg, "-") { // Prepend value to initial args + newValues = append(newValues, value) + if initialValueExists { + newValues = append(newValues, initialValue) + } + if existingValuesFound { + newValues = append(newValues, existingValues...) + } + } else { // Append value ignoring initial args + if existingValuesFound { + newValues = append(newValues, existingValues...) + } + newValues = append(newValues, value) + } + + delete(initialArgs, cleanedArg) + multiArgs[cleanedArg] = newValues + } + + // Add any remaining initial args to the map + for arg, value := range initialArgs { + multiArgs[arg] = []string{value} + } + + // Get args so we can output them sorted whilst preserving the order of + // repeated keys + var keys []string + for arg := range multiArgs { + keys = append(keys, arg) + } + sort.Strings(keys) + var args []string - for arg, value := range argsMap { - cmd := fmt.Sprintf("%s%s=%s", hyphens, strings.TrimPrefix(arg, hyphens), value) - args = append(args, cmd) + for _, arg := range keys { + values := multiArgs[arg] + for _, value := range values { + cmd := fmt.Sprintf("%s%s=%s", hyphens, strings.TrimPrefix(arg, hyphens), value) + args = append(args, cmd) + } } - sort.Strings(args) + return args } diff --git a/pkg/daemons/config/types_test.go b/pkg/daemons/config/types_test.go index f94d6093b7..9744abe2b7 100644 --- a/pkg/daemons/config/types_test.go +++ b/pkg/daemons/config/types_test.go @@ -79,6 +79,67 @@ func Test_UnitGetArgs(t *testing.T) { "--iii=II", }, }, + { + name: "Multiple args with defaults Test", + args: args{ + argsMap: map[string]string{ + "aaa": "A", + "bbb": "B", + }, + extraArgs: []string{ + "--ccc=C", + "--bbb=DD", + "--bbb=AA", + }, + }, + + want: []string{ + "--aaa=A", + "--bbb=DD", + "--bbb=AA", + "--ccc=C", + }, + }, + { + name: "Multiple args with defaults and prefix", + args: args{ + argsMap: map[string]string{ + "aaa": "A", + "bbb": "B", + }, + extraArgs: []string{ + "--ccc=C", + "--bbb-=DD", + }, + }, + + want: []string{ + "--aaa=A", + "--bbb=DD", + "--bbb=B", + "--ccc=C", + }, + }, + { + name: "Multiple args with defaults and suffix", + args: args{ + argsMap: map[string]string{ + "aaa": "A", + "bbb": "B", + }, + extraArgs: []string{ + "--ccc=C", + "--bbb+=DD", + }, + }, + + want: []string{ + "--aaa=A", + "--bbb=B", + "--bbb=DD", + "--ccc=C", + }, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) {