-
Notifications
You must be signed in to change notification settings - Fork 285
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use : as a config --set slice separator #484
Conversation
I glanced through the linked issue but its still not clear to me why |
@klueska they behaviour for There may be a more invasive change that I could make here, but I thought allowing the separator to be customized was a low-risk change. |
Do you mean |
cmd/nvidia-ctk/config/config.go
Outdated
@@ -72,9 +76,16 @@ func (m command) build() *cli.Command { | |||
}, | |||
&cli.StringSliceFlag{ | |||
Name: "set", | |||
Usage: "Set a config value using the pattern key=value. If value is empty, this is equivalent to specifying the same key in unset. This flag can be specified multiple times", | |||
Usage: "Set a config value using the pattern key=value. If value is empty, this is equivalent to specifying the same key in unset. This flag can be specified multiple times. If the setting represents a slice, the elements are semi-colon-separated.", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Usage: "Set a config value using the pattern key=value. If value is empty, this is equivalent to specifying the same key in unset. This flag can be specified multiple times. If the setting represents a slice, the elements are semi-colon-separated.", | |
Usage: "Set a config value using the pattern key=value. If value is empty, this is equivalent to specifying the same key in unset. This flag can be specified multiple times. If the setting represents a list, the elements are semi-colon-separated.", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was semicolon the default previously? I'm still trying to wrap my head around the previous behaviour vs. the new behaviour.
What I think you are saying in another comment is that we previously we always interpreted every input as a single string, and if it was supposed to be slice, we did the separation ourselves. What's not clear (assuming I got this right) is whether we previously did the separation with semicolons or commas, and (if it was commas), why we con't continue to use commas now instead of semilcolons.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, we were previously treating a comma-separated argument as a single string (due to a bug in urfave) and we were splitting this by commas ourselves to construct a slice to insert into the config file. We can't continue to use commas now because this urfave already assumes commas as the separator for repeated args. We could consider overriding this instead, but we can only do this at an Application level and not at a Command level. It may be possible with the alpha v3.0.0 release, but I didn't want to rely on an unstable dependency.
Consider the following code:
package main
import (
"fmt"
"os"
"github.com/urfave/cli/v2"
)
func main() {
var slice cli.StringSlice
c := cli.NewApp()
c.Flags = []cli.Flag{
&cli.StringSliceFlag{
Name: "slice-flag",
Destination: &slice,
},
}
c.Action = func(ctx *cli.Context) error {
fmt.Printf("slice=%q\n", slice.Value())
return nil
}
c.Run(os.Args)
}
When using v2.5.0
we get:
$ go run ./main.go --slice-flag=foo,bar,baz
slice=["foo,bar,baz"]
$ go run ./main.go --slice-flag=foo,bar,baz --slice-flag=boom
slice=["foo,bar,baz" "boom"]
When updating to v2.5.1
we get:
$ go run ./main.go --slice-flag=foo,bar,baz
slice=["foo" "bar" "baz"]
$ go run ./main.go --slice-flag=foo,bar,baz --slice-flag=boom
slice=["foo" "bar" "baz" "boom"]
clearly indicating that a bug was fixed for handling comma-separated repeated arguments when updating to at least v2.5.1
.
We were however depending on the broken behaviour, meaning that when a user ran:
nvidia-ctk config --set nvidia-container-runtime.runtimes=crun,runc
we had a slice with the following contents:
[]string{"nvidia-container-runtime.runtimes=crun,runc"}
When we could process -- first splitting by =
and then the second argument by ,
to generate the eventually slice []string{"crun", "runc"}
.
With the update to v2.27.1
when a user runs:
nvidia-ctk config --set nvidia-container-runtime.runtimes=crun,runc
we have a slice with the following contents:
[]string{"nvidia-container-runtime.runtimes=crun" ,"runc"}
Which we cannot effectively parse.
With the switch to ;
as our own separator, we no have the inputs:
nvidia-ctk config --set nvidia-container-runtime.runtimes=crun;runc
which would be parsed to:
[]string{"nvidia-container-runtime.runtimes=crun;runc"}
meaning that we can do the same processing as before.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, so this is defining the separator we want to use to break apart elements of an embedded list of strings that we don't want to become elements of the overall StringSlice
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Meaning that ,
is still the default for the top-level separator, and we now defining ;
as the embedded separator.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is fine then -- my only worry would be if / where else we rely on this "bug". I seem to remember relying on this functionality in the device-plugin as well, for example.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From my knowledge of our code bases, I would say that this is the only place that we're relying on the broken behaviour since this is the only place we have logic in place to further separate strings that we were expecting to be parsed as different arguments.
I would also futher suggest using :
as the separator to match the path-list-separator
in linux.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems reasonable to me
cmd/nvidia-ctk/config/config.go
Outdated
Name: "set-slice-separator", | ||
Usage: "Specify a separator for slices applied using the set command.", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Name: "set-slice-separator", | |
Usage: "Specify a separator for slices applied using the set command.", | |
Name: "set-list-separator", | |
Usage: "Specify a separator for lists applied using the set command.", |
No, I mean |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PR now looks ok to me, and addresses @klueska comments.
Only comment please update the PR description which still uses ;
cmd/nvidia-ctk/config/config.go
Outdated
Usage: "Specify a separator for lists applied using the set command.", | ||
Hidden: true, | ||
Value: ":", | ||
Destination: &opts.setSliceSeparator, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we change the variable to match the flag name?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure. Will update.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
cmd/nvidia-ctk/config/config.go
Outdated
@@ -96,6 +111,13 @@ func (m command) build() *cli.Command { | |||
return &c | |||
} | |||
|
|||
func validateFlags(c *cli.Context, opts *options) error { | |||
if opts.setSliceSeparator == "" { | |||
return fmt.Errorf("set-slice-separator must be set") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return fmt.Errorf("set-slice-separator must be set") | |
return fmt.Errorf("set-list-separator must be set") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor comments. LGTM otherwise
This allows settings such as: nvidia-ctk config --set nvidia-container-runtime.runtimes=crun:runc to be applied correctly. Signed-off-by: Evan Lezar <elezar@nvidia.com>
This change switches to using
:
as the separator for slices when callingnvidia-ctk config --set
. This works around an issue with the handling of string-slice arguments in theurfave/cli
module.For example, running:
yields:
Fixes #466