From 9c10a9c9ac62137d24d65ba39eb54a16f4259c8e Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Fri, 28 Nov 2025 14:59:19 +0100 Subject: [PATCH 1/2] opts/swarmopts: remove use of nat.ParsePortRange Signed-off-by: Sebastiaan van Stijn --- opts/swarmopts/port.go | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/opts/swarmopts/port.go b/opts/swarmopts/port.go index ac38e3bcd772..9aec79662d36 100644 --- a/opts/swarmopts/port.go +++ b/opts/swarmopts/port.go @@ -162,18 +162,17 @@ func ConvertPortToPortConfig( logrus.Warnf("ignoring IP-address (%s:%s) service will listen on '0.0.0.0'", net.JoinHostPort(binding.HostIP, binding.HostPort), portProto.String()) } - startHostPort, endHostPort, err := nat.ParsePortRange(binding.HostPort) - + pr, err := network.ParsePortRange(binding.HostPort) if err != nil && binding.HostPort != "" { return nil, fmt.Errorf("invalid hostport binding (%s) for port (%d)", binding.HostPort, portProto.Num()) } - for i := startHostPort; i <= endHostPort; i++ { + for p := range pr.All() { ports = append(ports, swarm.PortConfig{ // TODO Name: ? Protocol: portProto.Proto(), TargetPort: uint32(portProto.Num()), - PublishedPort: uint32(i), + PublishedPort: uint32(p.Num()), PublishMode: swarm.PortConfigPublishModeIngress, }) } From 6f75c0c8e2f3b3ef05c8d06854d107d1670f4ac5 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Fri, 28 Nov 2025 14:59:56 +0100 Subject: [PATCH 2/2] add TODOs for replacing nat.ParsePortSpecs Signed-off-by: Sebastiaan van Stijn --- cli/command/container/opts.go | 3 +++ cli/compose/loader/loader.go | 6 ++++-- opts/swarmopts/port.go | 4 +++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/cli/command/container/opts.go b/cli/command/container/opts.go index 7cddf8f784b3..a0cc1cb8f9d3 100644 --- a/cli/command/container/opts.go +++ b/cli/command/container/opts.go @@ -426,6 +426,9 @@ func parse(flags *pflag.FlagSet, copts *containerOptions, serverOS string) (*con return nil, err } + // short syntax ([ip:]public:private[/proto]) + // + // TODO(thaJeztah): we need an equivalent that handles the "ip-address" part without depending on the nat package. ports, natPortBindings, err := nat.ParsePortSpecs(convertedOpts) if err != nil { return nil, err diff --git a/cli/compose/loader/loader.go b/cli/compose/loader/loader.go index 844ce8c93d71..edc79430b676 100644 --- a/cli/compose/loader/loader.go +++ b/cli/compose/loader/loader.go @@ -918,8 +918,9 @@ var transformStringToDuration TransformerFunc = func(value any) (any, error) { } func toServicePortConfigs(value string) ([]any, error) { - var portConfigs []any - + // short syntax ([ip:]public:private[/proto]) + // + // TODO(thaJeztah): we need an equivalent that handles the "ip-address" part without depending on the nat package. ports, portBindings, err := nat.ParsePortSpecs([]string{value}) if err != nil { return nil, err @@ -931,6 +932,7 @@ func toServicePortConfigs(value string) ([]any, error) { } sort.Strings(keys) + var portConfigs []any for _, key := range keys { // Reuse ConvertPortToPortConfig so that it is consistent port, err := network.ParsePort(key) diff --git a/opts/swarmopts/port.go b/opts/swarmopts/port.go index 9aec79662d36..2a8c2b71c039 100644 --- a/opts/swarmopts/port.go +++ b/opts/swarmopts/port.go @@ -100,7 +100,9 @@ func (p *PortOpt) Set(value string) error { p.ports = append(p.ports, pConfig) } else { - // short syntax + // short syntax ([ip:]public:private[/proto]) + // + // TODO(thaJeztah): we need an equivalent that handles the "ip-address" part without depending on the nat package. ports, portBindingMap, err := nat.ParsePortSpecs([]string{value}) if err != nil { return err