mirror of https://github.com/docker/cli.git
feat(service): support comma-separated values for host-to-IP mappings
This commit is contained in:
parent
abe4aa7893
commit
e05f348fa3
|
|
@ -95,7 +95,7 @@ func newUpdateCommand(dockerCLI command.Cli) *cobra.Command {
|
|||
flags.SetAnnotation(flagDNSOptionAdd, "version", []string{"1.25"})
|
||||
flags.Var(&options.dnsSearch, flagDNSSearchAdd, "Add or update a custom DNS search domain")
|
||||
flags.SetAnnotation(flagDNSSearchAdd, "version", []string{"1.25"})
|
||||
flags.Var(&options.hosts, flagHostAdd, `Add a custom host-to-IP mapping ("host:ip")`)
|
||||
flags.Var(opts.NewListOptsCSV(&options.hosts), flagHostAdd, `Add a custom host-to-IP mapping ("host:ip")`)
|
||||
flags.SetAnnotation(flagHostAdd, "version", []string{"1.25"})
|
||||
flags.BoolVar(&options.init, flagInit, false, "Use an init inside each service container to forward signals and reap processes")
|
||||
flags.SetAnnotation(flagInit, "version", []string{"1.37"})
|
||||
|
|
@ -1235,7 +1235,7 @@ func updateHosts(flags *pflag.FlagSet, hosts *[]string) error {
|
|||
|
||||
// Append new hosts (in SwarmKit format)
|
||||
if flags.Changed(flagHostAdd) {
|
||||
values := convertExtraHostsToSwarmHosts(flags.Lookup(flagHostAdd).Value.(*opts.ListOpts).GetSlice())
|
||||
values := convertExtraHostsToSwarmHosts(flags.Lookup(flagHostAdd).Value.(pflag.SliceValue).GetSlice())
|
||||
newHosts = append(newHosts, values...)
|
||||
}
|
||||
*hosts = removeDuplicates(newHosts)
|
||||
|
|
|
|||
|
|
@ -388,6 +388,7 @@ func TestUpdateHealthcheckTable(t *testing.T) {
|
|||
|
||||
func TestUpdateHosts(t *testing.T) {
|
||||
flags := newUpdateCommand(nil).Flags()
|
||||
flags.Set("host-add", "a:1.1.1.1,b:2.2.2.2")
|
||||
flags.Set("host-add", "example.net:2.2.2.2")
|
||||
flags.Set("host-add", "ipv6.net:2001:db8:abc8::1")
|
||||
// adding the special "host-gateway" target should work
|
||||
|
|
@ -402,7 +403,7 @@ func TestUpdateHosts(t *testing.T) {
|
|||
assert.ErrorContains(t, flags.Set("host-add", "$example.com$"), `bad format for add-host: "$example.com$"`)
|
||||
|
||||
hosts := []string{"1.2.3.4 example.com", "4.3.2.1 example.org", "2001:db8:abc8::1 example.net", "gateway.docker.internal:host-gateway"}
|
||||
expected := []string{"1.2.3.4 example.com", "4.3.2.1 example.org", "2.2.2.2 example.net", "2001:db8:abc8::1 ipv6.net", "host-gateway host.docker.internal"}
|
||||
expected := []string{"1.2.3.4 example.com", "4.3.2.1 example.org", "1.1.1.1 a", "2.2.2.2 b", "2.2.2.2 example.net", "2001:db8:abc8::1 ipv6.net", "host-gateway host.docker.internal"}
|
||||
|
||||
err := updateHosts(flags, &hosts)
|
||||
assert.NilError(t, err)
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ Update a service
|
|||
| `--health-start-interval` | `duration` | | Time between running the check during the start period (ms\|s\|m\|h) |
|
||||
| `--health-start-period` | `duration` | | Start period for the container to initialize before counting retries towards unstable (ms\|s\|m\|h) |
|
||||
| `--health-timeout` | `duration` | | Maximum time to allow one check to run (ms\|s\|m\|h) |
|
||||
| `--host-add` | `list` | | Add a custom host-to-IP mapping (`host:ip`) |
|
||||
| `--host-add` | `list` | | Add a custom host-to-IP mapping (`host:ip`). Multiple entries can be separated by comma |
|
||||
| `--host-rm` | `list` | | Remove a custom host-to-IP mapping (`host:ip`) |
|
||||
| `--hostname` | `string` | | Container hostname |
|
||||
| `--image` | `string` | | Service image tag |
|
||||
|
|
|
|||
45
opts/opts.go
45
opts/opts.go
|
|
@ -125,6 +125,51 @@ func (opts *ListOpts) WithValidator(validator ValidatorFctType) *ListOpts {
|
|||
return opts
|
||||
}
|
||||
|
||||
// ListOptsCSV wraps a ListOpts and implements [pflag.SliceValue], allowing
|
||||
// comma-separated values to be parsed in a single flag instance.
|
||||
//
|
||||
// Values passed to Set are split on commas before being validated using the
|
||||
// wrapped ListOpts' validator (for example, [ValidateExtraHost]).
|
||||
//
|
||||
// [pflag.SliceValue]: https://pkg.go.dev/github.com/spf13/pflag#SliceValue
|
||||
type ListOptsCSV struct{ *ListOpts }
|
||||
|
||||
// NewListOptsCSV returns a new ListOptsCSV using the provided ListOpts.
|
||||
func NewListOptsCSV(opts *ListOpts) *ListOptsCSV {
|
||||
return &ListOptsCSV{ListOpts: opts}
|
||||
}
|
||||
|
||||
// Set splits the value on commas and validates each item using the wrapped
|
||||
// ListOpts.
|
||||
func (opts *ListOptsCSV) Set(value string) error {
|
||||
for _, v := range strings.Split(value, ",") {
|
||||
v = strings.TrimSpace(v)
|
||||
if v == "" {
|
||||
continue
|
||||
}
|
||||
if err := opts.ListOpts.Set(v); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Append implements pflag.SliceValue.
|
||||
func (opts *ListOptsCSV) Append(value string) error {
|
||||
return opts.Set(value)
|
||||
}
|
||||
|
||||
// Replace implements pflag.SliceValue.
|
||||
func (opts *ListOptsCSV) Replace(values []string) error {
|
||||
*opts.ListOpts.values = (*opts.ListOpts.values)[:0]
|
||||
for _, v := range values {
|
||||
if err := opts.Set(v); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// MapOpts holds a map of values and a validation function.
|
||||
type MapOpts struct {
|
||||
values map[string]string
|
||||
|
|
|
|||
Loading…
Reference in New Issue