mirror of
https://github.com/docker/compose.git
synced 2025-07-23 13:45:00 +02:00
port: improve error-handling if port not found (#10039)
This method looked slightly incomplete. If the port wasn't found, it'd return `err`, but that was always `nil`, so we'd print out `:0`. Now, we construct a nice error message with the targeted port and the ones we found. The `--protocol` flag is also now case-insensitive to prevent any weirdness/confusion there. Co-authored-by: Nick Sieger <nicksieger@gmail.com> Signed-off-by: Milas Bowman <milas.bowman@docker.com>
This commit is contained in:
parent
6ed9a7928f
commit
053f20edab
1
Makefile
1
Makefile
@ -77,6 +77,7 @@ build-and-e2e-compose-standalone: build e2e-compose-standalone ## Compile the co
|
|||||||
|
|
||||||
.PHONY: mocks
|
.PHONY: mocks
|
||||||
mocks:
|
mocks:
|
||||||
|
mockgen --version >/dev/null 2>&1 || go install github.com/golang/mock/mockgen@v1.6.0
|
||||||
mockgen -destination pkg/mocks/mock_docker_cli.go -package mocks github.com/docker/cli/cli/command Cli
|
mockgen -destination pkg/mocks/mock_docker_cli.go -package mocks github.com/docker/cli/cli/command Cli
|
||||||
mockgen -destination pkg/mocks/mock_docker_api.go -package mocks github.com/docker/docker/client APIClient
|
mockgen -destination pkg/mocks/mock_docker_api.go -package mocks github.com/docker/docker/client APIClient
|
||||||
mockgen -destination pkg/mocks/mock_docker_compose_api.go -package mocks -source=./pkg/api/api.go Service
|
mockgen -destination pkg/mocks/mock_docker_compose_api.go -package mocks -source=./pkg/api/api.go Service
|
||||||
|
@ -20,6 +20,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
@ -28,7 +29,7 @@ import (
|
|||||||
|
|
||||||
type portOptions struct {
|
type portOptions struct {
|
||||||
*projectOptions
|
*projectOptions
|
||||||
port int
|
port uint16
|
||||||
protocol string
|
protocol string
|
||||||
index int
|
index int
|
||||||
}
|
}
|
||||||
@ -42,11 +43,12 @@ func portCommand(p *projectOptions, backend api.Service) *cobra.Command {
|
|||||||
Short: "Print the public port for a port binding.",
|
Short: "Print the public port for a port binding.",
|
||||||
Args: cobra.MinimumNArgs(2),
|
Args: cobra.MinimumNArgs(2),
|
||||||
PreRunE: Adapt(func(ctx context.Context, args []string) error {
|
PreRunE: Adapt(func(ctx context.Context, args []string) error {
|
||||||
port, err := strconv.Atoi(args[1])
|
port, err := strconv.ParseUint(args[1], 10, 16)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
opts.port = port
|
opts.port = uint16(port)
|
||||||
|
opts.protocol = strings.ToLower(opts.protocol)
|
||||||
return nil
|
return nil
|
||||||
}),
|
}),
|
||||||
RunE: Adapt(func(ctx context.Context, args []string) error {
|
RunE: Adapt(func(ctx context.Context, args []string) error {
|
||||||
|
@ -72,7 +72,7 @@ type Service interface {
|
|||||||
// Events executes the equivalent to a `compose events`
|
// Events executes the equivalent to a `compose events`
|
||||||
Events(ctx context.Context, projectName string, options EventsOptions) error
|
Events(ctx context.Context, projectName string, options EventsOptions) error
|
||||||
// Port executes the equivalent to a `compose port`
|
// Port executes the equivalent to a `compose port`
|
||||||
Port(ctx context.Context, projectName string, service string, port int, options PortOptions) (string, int, error)
|
Port(ctx context.Context, projectName string, service string, port uint16, options PortOptions) (string, int, error)
|
||||||
// Images executes the equivalent of a `compose images`
|
// Images executes the equivalent of a `compose images`
|
||||||
Images(ctx context.Context, projectName string, options ImagesOptions) ([]ImageSummary, error)
|
Images(ctx context.Context, projectName string, options ImagesOptions) ([]ImageSummary, error)
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ type ServiceProxy struct {
|
|||||||
UnPauseFn func(ctx context.Context, project string, options PauseOptions) error
|
UnPauseFn func(ctx context.Context, project string, options PauseOptions) error
|
||||||
TopFn func(ctx context.Context, projectName string, services []string) ([]ContainerProcSummary, error)
|
TopFn func(ctx context.Context, projectName string, services []string) ([]ContainerProcSummary, error)
|
||||||
EventsFn func(ctx context.Context, project string, options EventsOptions) error
|
EventsFn func(ctx context.Context, project string, options EventsOptions) error
|
||||||
PortFn func(ctx context.Context, project string, service string, port int, options PortOptions) (string, int, error)
|
PortFn func(ctx context.Context, project string, service string, port uint16, options PortOptions) (string, int, error)
|
||||||
ImagesFn func(ctx context.Context, projectName string, options ImagesOptions) ([]ImageSummary, error)
|
ImagesFn func(ctx context.Context, projectName string, options ImagesOptions) ([]ImageSummary, error)
|
||||||
interceptors []Interceptor
|
interceptors []Interceptor
|
||||||
}
|
}
|
||||||
@ -294,7 +294,7 @@ func (s *ServiceProxy) Events(ctx context.Context, projectName string, options E
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Port implements Service interface
|
// Port implements Service interface
|
||||||
func (s *ServiceProxy) Port(ctx context.Context, projectName string, service string, port int, options PortOptions) (string, int, error) {
|
func (s *ServiceProxy) Port(ctx context.Context, projectName string, service string, port uint16, options PortOptions) (string, int, error) {
|
||||||
if s.PortFn == nil {
|
if s.PortFn == nil {
|
||||||
return "", 0, ErrNotImplemented
|
return "", 0, ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ import (
|
|||||||
"github.com/docker/docker/api/types/filters"
|
"github.com/docker/docker/api/types/filters"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *composeService) Port(ctx context.Context, projectName string, service string, port int, options api.PortOptions) (string, int, error) {
|
func (s *composeService) Port(ctx context.Context, projectName string, service string, port uint16, options api.PortOptions) (string, int, error) {
|
||||||
projectName = strings.ToLower(projectName)
|
projectName = strings.ToLower(projectName)
|
||||||
list, err := s.apiClient().ContainerList(ctx, moby.ContainerListOptions{
|
list, err := s.apiClient().ContainerList(ctx, moby.ContainerListOptions{
|
||||||
Filters: filters.NewArgs(
|
Filters: filters.NewArgs(
|
||||||
@ -44,9 +44,23 @@ func (s *composeService) Port(ctx context.Context, projectName string, service s
|
|||||||
}
|
}
|
||||||
container := list[0]
|
container := list[0]
|
||||||
for _, p := range container.Ports {
|
for _, p := range container.Ports {
|
||||||
if p.PrivatePort == uint16(port) && p.Type == options.Protocol {
|
if p.PrivatePort == port && p.Type == options.Protocol {
|
||||||
return p.IP, int(p.PublicPort), nil
|
return p.IP, int(p.PublicPort), nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return "", 0, err
|
return "", 0, portNotFoundError(options.Protocol, port, container)
|
||||||
|
}
|
||||||
|
|
||||||
|
func portNotFoundError(protocol string, port uint16, ctr moby.Container) error {
|
||||||
|
formatPort := func(protocol string, port uint16) string {
|
||||||
|
return fmt.Sprintf("%d/%s", port, protocol)
|
||||||
|
}
|
||||||
|
|
||||||
|
var containerPorts []string
|
||||||
|
for _, p := range ctr.Ports {
|
||||||
|
containerPorts = append(containerPorts, formatPort(p.Type, p.PublicPort))
|
||||||
|
}
|
||||||
|
|
||||||
|
name := strings.TrimPrefix(ctr.Names[0], "/")
|
||||||
|
return fmt.Errorf("no port %s for container %s: %s", formatPort(protocol, port), name, strings.Join(containerPorts, ", "))
|
||||||
}
|
}
|
||||||
|
@ -209,7 +209,7 @@ func (mr *MockServiceMockRecorder) Pause(ctx, projectName, options interface{})
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Port mocks base method.
|
// Port mocks base method.
|
||||||
func (m *MockService) Port(ctx context.Context, projectName, service string, port int, options api.PortOptions) (string, int, error) {
|
func (m *MockService) Port(ctx context.Context, projectName, service string, port uint16, options api.PortOptions) (string, int, error) {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
ret := m.ctrl.Call(m, "Port", ctx, projectName, service, port, options)
|
ret := m.ctrl.Call(m, "Port", ctx, projectName, service, port, options)
|
||||||
ret0, _ := ret[0].(string)
|
ret0, _ := ret[0].(string)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user