From 056e7449039af522fa0a1567ef67916eaa0de93e Mon Sep 17 00:00:00 2001 From: David Calavera Date: Fri, 18 Dec 2015 12:58:48 -0500 Subject: [PATCH] Replace usage of pkg/nat with go-connections/nat. Signed-off-by: David Calavera --- api/client/port.go | 2 +- api/types/types.go | 2 +- api/types/versions/v1p19/types.go | 2 +- api/types/versions/v1p20/types.go | 2 +- builder/dockerfile/dispatchers.go | 2 +- container/container.go | 2 +- container/container_unix.go | 2 +- daemon/daemon.go | 2 +- daemon/execdriver/driver_windows.go | 2 +- daemon/links/links.go | 2 +- daemon/links/links_test.go | 2 +- daemon/list.go | 2 +- daemon/network/settings.go | 2 +- integration-cli/docker_cli_create_test.go | 2 +- integration-cli/docker_cli_run_test.go | 2 +- pkg/nat/nat.go | 227 ---------- pkg/nat/nat_test.go | 525 ---------------------- pkg/nat/sort.go | 98 ---- pkg/nat/sort_test.go | 85 ---- runconfig/compare_test.go | 2 +- runconfig/config.go | 2 +- runconfig/hostconfig.go | 2 +- runconfig/merge.go | 2 +- runconfig/merge_test.go | 2 +- runconfig/parse.go | 2 +- runconfig/parse_test.go | 2 +- 26 files changed, 22 insertions(+), 957 deletions(-) delete mode 100644 pkg/nat/nat.go delete mode 100644 pkg/nat/nat_test.go delete mode 100644 pkg/nat/sort.go delete mode 100644 pkg/nat/sort_test.go diff --git a/api/client/port.go b/api/client/port.go index ac673267ea..0dd3da4517 100644 --- a/api/client/port.go +++ b/api/client/port.go @@ -6,7 +6,7 @@ import ( Cli "github.com/docker/docker/cli" flag "github.com/docker/docker/pkg/mflag" - "github.com/docker/docker/pkg/nat" + "github.com/docker/go-connections/nat" ) // CmdPort lists port mappings for a container. diff --git a/api/types/types.go b/api/types/types.go index 3a8870cee3..8cc73ef7a7 100644 --- a/api/types/types.go +++ b/api/types/types.go @@ -6,9 +6,9 @@ import ( "github.com/docker/docker/api/types/network" "github.com/docker/docker/api/types/registry" - "github.com/docker/docker/pkg/nat" "github.com/docker/docker/pkg/version" "github.com/docker/docker/runconfig" + "github.com/docker/go-connections/nat" ) // ContainerCreateResponse contains the information returned to a client on the diff --git a/api/types/versions/v1p19/types.go b/api/types/versions/v1p19/types.go index a66aa9d5e5..66777bf2c5 100644 --- a/api/types/versions/v1p19/types.go +++ b/api/types/versions/v1p19/types.go @@ -4,8 +4,8 @@ package v1p19 import ( "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/versions/v1p20" - "github.com/docker/docker/pkg/nat" "github.com/docker/docker/runconfig" + "github.com/docker/go-connections/nat" ) // ContainerJSON is a backcompatibility struct for APIs prior to 1.20. diff --git a/api/types/versions/v1p20/types.go b/api/types/versions/v1p20/types.go index 0facbb66ca..6579dcfb7e 100644 --- a/api/types/versions/v1p20/types.go +++ b/api/types/versions/v1p20/types.go @@ -3,8 +3,8 @@ package v1p20 import ( "github.com/docker/docker/api/types" - "github.com/docker/docker/pkg/nat" "github.com/docker/docker/runconfig" + "github.com/docker/go-connections/nat" ) // ContainerJSON is a backcompatibility struct for the API 1.20 diff --git a/builder/dockerfile/dispatchers.go b/builder/dockerfile/dispatchers.go index 7a1d9e3238..03849fcc94 100644 --- a/builder/dockerfile/dispatchers.go +++ b/builder/dockerfile/dispatchers.go @@ -22,10 +22,10 @@ import ( "github.com/docker/docker/builder" derr "github.com/docker/docker/errors" flag "github.com/docker/docker/pkg/mflag" - "github.com/docker/docker/pkg/nat" "github.com/docker/docker/pkg/signal" "github.com/docker/docker/pkg/system" "github.com/docker/docker/runconfig" + "github.com/docker/go-connections/nat" ) const ( diff --git a/container/container.go b/container/container.go index 8285d3196e..cc0ca97f2a 100644 --- a/container/container.go +++ b/container/container.go @@ -19,12 +19,12 @@ import ( derr "github.com/docker/docker/errors" "github.com/docker/docker/image" "github.com/docker/docker/layer" - "github.com/docker/docker/pkg/nat" "github.com/docker/docker/pkg/promise" "github.com/docker/docker/pkg/signal" "github.com/docker/docker/pkg/symlink" "github.com/docker/docker/runconfig" "github.com/docker/docker/volume" + "github.com/docker/go-connections/nat" "github.com/opencontainers/runc/libcontainer/label" ) diff --git a/container/container_unix.go b/container/container_unix.go index 1740c536c5..f775871669 100644 --- a/container/container_unix.go +++ b/container/container_unix.go @@ -17,11 +17,11 @@ import ( "github.com/docker/docker/daemon/execdriver" derr "github.com/docker/docker/errors" "github.com/docker/docker/pkg/chrootarchive" - "github.com/docker/docker/pkg/nat" "github.com/docker/docker/pkg/symlink" "github.com/docker/docker/pkg/system" "github.com/docker/docker/utils" "github.com/docker/docker/volume" + "github.com/docker/go-connections/nat" "github.com/docker/libnetwork" "github.com/docker/libnetwork/netlabel" "github.com/docker/libnetwork/options" diff --git a/daemon/daemon.go b/daemon/daemon.go index 57ab271768..1df4cb80c9 100644 --- a/daemon/daemon.go +++ b/daemon/daemon.go @@ -49,7 +49,6 @@ import ( "github.com/docker/docker/pkg/jsonmessage" "github.com/docker/docker/pkg/mount" "github.com/docker/docker/pkg/namesgenerator" - "github.com/docker/docker/pkg/nat" "github.com/docker/docker/pkg/progress" "github.com/docker/docker/pkg/signal" "github.com/docker/docker/pkg/streamformatter" @@ -64,6 +63,7 @@ import ( volumedrivers "github.com/docker/docker/volume/drivers" "github.com/docker/docker/volume/local" "github.com/docker/docker/volume/store" + "github.com/docker/go-connections/nat" "github.com/docker/libnetwork" lntypes "github.com/docker/libnetwork/types" "github.com/docker/libtrust" diff --git a/daemon/execdriver/driver_windows.go b/daemon/execdriver/driver_windows.go index dcd9d36df3..5ea52d0675 100644 --- a/daemon/execdriver/driver_windows.go +++ b/daemon/execdriver/driver_windows.go @@ -1,8 +1,8 @@ package execdriver import ( - "github.com/docker/docker/pkg/nat" "github.com/docker/docker/runconfig" + "github.com/docker/go-connections/nat" ) // Mount contains information for a mount operation. diff --git a/daemon/links/links.go b/daemon/links/links.go index e513fe06e7..af15de046d 100644 --- a/daemon/links/links.go +++ b/daemon/links/links.go @@ -5,7 +5,7 @@ import ( "path" "strings" - "github.com/docker/docker/pkg/nat" + "github.com/docker/go-connections/nat" ) // Link struct holds informations about parent/child linked container diff --git a/daemon/links/links_test.go b/daemon/links/links_test.go index 3d0fb6d7c6..0273f13cf0 100644 --- a/daemon/links/links_test.go +++ b/daemon/links/links_test.go @@ -5,7 +5,7 @@ import ( "strings" "testing" - "github.com/docker/docker/pkg/nat" + "github.com/docker/go-connections/nat" ) // Just to make life easier diff --git a/daemon/list.go b/daemon/list.go index 26632c3ce8..68944d6598 100644 --- a/daemon/list.go +++ b/daemon/list.go @@ -12,7 +12,7 @@ import ( "github.com/docker/docker/container" "github.com/docker/docker/image" "github.com/docker/docker/pkg/graphdb" - "github.com/docker/docker/pkg/nat" + "github.com/docker/go-connections/nat" ) // iterationAction represents possible outcomes happening during the container iteration. diff --git a/daemon/network/settings.go b/daemon/network/settings.go index 293ffc7056..1bf4b5a672 100644 --- a/daemon/network/settings.go +++ b/daemon/network/settings.go @@ -2,7 +2,7 @@ package network import ( networktypes "github.com/docker/docker/api/types/network" - "github.com/docker/docker/pkg/nat" + "github.com/docker/go-connections/nat" ) // Settings stores configuration details about the daemon network config diff --git a/integration-cli/docker_cli_create_test.go b/integration-cli/docker_cli_create_test.go index a2d47cf595..bbd1eb6df1 100644 --- a/integration-cli/docker_cli_create_test.go +++ b/integration-cli/docker_cli_create_test.go @@ -13,8 +13,8 @@ import ( "io/ioutil" "github.com/docker/docker/pkg/integration/checker" - "github.com/docker/docker/pkg/nat" "github.com/docker/docker/pkg/stringid" + "github.com/docker/go-connections/nat" "github.com/go-check/check" ) diff --git a/integration-cli/docker_cli_run_test.go b/integration-cli/docker_cli_run_test.go index 399dce27cb..e696078950 100644 --- a/integration-cli/docker_cli_run_test.go +++ b/integration-cli/docker_cli_run_test.go @@ -20,8 +20,8 @@ import ( "github.com/docker/docker/pkg/integration/checker" "github.com/docker/docker/pkg/mount" - "github.com/docker/docker/pkg/nat" "github.com/docker/docker/runconfig" + "github.com/docker/go-connections/nat" "github.com/docker/libnetwork/resolvconf" "github.com/go-check/check" ) diff --git a/pkg/nat/nat.go b/pkg/nat/nat.go deleted file mode 100644 index 6595feb055..0000000000 --- a/pkg/nat/nat.go +++ /dev/null @@ -1,227 +0,0 @@ -package nat - -// nat is a convenience package for docker's manipulation of strings describing -// network ports. - -import ( - "fmt" - "net" - "strconv" - "strings" - - "github.com/docker/docker/pkg/parsers" -) - -const ( - // portSpecTemplate is the expected format for port specifications - portSpecTemplate = "ip:hostPort:containerPort" -) - -// PortBinding represents a binding between a Host IP address and a Host Port -type PortBinding struct { - // HostIP is the host IP Address - HostIP string `json:"HostIp"` - // HostPort is the host port number - HostPort string -} - -// PortMap is a collection of PortBinding indexed by Port -type PortMap map[Port][]PortBinding - -// PortSet is a collection of structs indexed by Port -type PortSet map[Port]struct{} - -// Port is a string containing port number and protocol in the format "80/tcp" -type Port string - -// NewPort creates a new instance of a Port given a protocol and port number or port range -func NewPort(proto, port string) (Port, error) { - // Check for parsing issues on "port" now so we can avoid having - // to check it later on. - - portStartInt, portEndInt, err := ParsePortRange(port) - if err != nil { - return "", err - } - - if portStartInt == portEndInt { - return Port(fmt.Sprintf("%d/%s", portStartInt, proto)), nil - } - return Port(fmt.Sprintf("%d-%d/%s", portStartInt, portEndInt, proto)), nil -} - -// ParsePort parses the port number string and returns an int -func ParsePort(rawPort string) (int, error) { - if len(rawPort) == 0 { - return 0, nil - } - port, err := strconv.ParseUint(rawPort, 10, 16) - if err != nil { - return 0, err - } - return int(port), nil -} - -// ParsePortRange parses the port range string and returns start/end ints -func ParsePortRange(rawPort string) (int, int, error) { - if len(rawPort) == 0 { - return 0, 0, nil - } - start, end, err := parsers.ParsePortRange(rawPort) - if err != nil { - return 0, 0, err - } - return int(start), int(end), nil -} - -// Proto returns the protocol of a Port -func (p Port) Proto() string { - proto, _ := SplitProtoPort(string(p)) - return proto -} - -// Port returns the port number of a Port -func (p Port) Port() string { - _, port := SplitProtoPort(string(p)) - return port -} - -// Int returns the port number of a Port as an int -func (p Port) Int() int { - portStr := p.Port() - if len(portStr) == 0 { - return 0 - } - - // We don't need to check for an error because we're going to - // assume that any error would have been found, and reported, in NewPort() - port, _ := strconv.ParseUint(portStr, 10, 16) - return int(port) -} - -// Range returns the start/end port numbers of a Port range as ints -func (p Port) Range() (int, int, error) { - return ParsePortRange(p.Port()) -} - -// SplitProtoPort splits a port in the format of proto/port -func SplitProtoPort(rawPort string) (string, string) { - parts := strings.Split(rawPort, "/") - l := len(parts) - if len(rawPort) == 0 || l == 0 || len(parts[0]) == 0 { - return "", "" - } - if l == 1 { - return "tcp", rawPort - } - if len(parts[1]) == 0 { - return "tcp", parts[0] - } - return parts[1], parts[0] -} - -func validateProto(proto string) bool { - for _, availableProto := range []string{"tcp", "udp"} { - if availableProto == proto { - return true - } - } - return false -} - -// ParsePortSpecs receives port specs in the format of ip:public:private/proto and parses -// these in to the internal types -func ParsePortSpecs(ports []string) (map[Port]struct{}, map[Port][]PortBinding, error) { - var ( - exposedPorts = make(map[Port]struct{}, len(ports)) - bindings = make(map[Port][]PortBinding) - ) - - for _, rawPort := range ports { - proto := "tcp" - - if i := strings.LastIndex(rawPort, "/"); i != -1 { - proto = rawPort[i+1:] - rawPort = rawPort[:i] - } - if !strings.Contains(rawPort, ":") { - rawPort = fmt.Sprintf("::%s", rawPort) - } else if len(strings.Split(rawPort, ":")) == 2 { - rawPort = fmt.Sprintf(":%s", rawPort) - } - - parts, err := parsers.PartParser(portSpecTemplate, rawPort) - if err != nil { - return nil, nil, err - } - - var ( - containerPort = parts["containerPort"] - rawIP = parts["ip"] - hostPort = parts["hostPort"] - ) - - if rawIP != "" && net.ParseIP(rawIP) == nil { - return nil, nil, fmt.Errorf("Invalid ip address: %s", rawIP) - } - if containerPort == "" { - return nil, nil, fmt.Errorf("No port specified: %s", rawPort) - } - - startPort, endPort, err := parsers.ParsePortRange(containerPort) - if err != nil { - return nil, nil, fmt.Errorf("Invalid containerPort: %s", containerPort) - } - - var startHostPort, endHostPort uint64 = 0, 0 - if len(hostPort) > 0 { - startHostPort, endHostPort, err = parsers.ParsePortRange(hostPort) - if err != nil { - return nil, nil, fmt.Errorf("Invalid hostPort: %s", hostPort) - } - } - - if hostPort != "" && (endPort-startPort) != (endHostPort-startHostPort) { - // Allow host port range iff containerPort is not a range. - // In this case, use the host port range as the dynamic - // host port range to allocate into. - if endPort != startPort { - return nil, nil, fmt.Errorf("Invalid ranges specified for container and host Ports: %s and %s", containerPort, hostPort) - } - } - - if !validateProto(strings.ToLower(proto)) { - return nil, nil, fmt.Errorf("Invalid proto: %s", proto) - } - - for i := uint64(0); i <= (endPort - startPort); i++ { - containerPort = strconv.FormatUint(startPort+i, 10) - if len(hostPort) > 0 { - hostPort = strconv.FormatUint(startHostPort+i, 10) - } - // Set hostPort to a range only if there is a single container port - // and a dynamic host port. - if startPort == endPort && startHostPort != endHostPort { - hostPort = fmt.Sprintf("%s-%s", hostPort, strconv.FormatUint(endHostPort, 10)) - } - port, err := NewPort(strings.ToLower(proto), containerPort) - if err != nil { - return nil, nil, err - } - if _, exists := exposedPorts[port]; !exists { - exposedPorts[port] = struct{}{} - } - - binding := PortBinding{ - HostIP: rawIP, - HostPort: hostPort, - } - bslice, exists := bindings[port] - if !exists { - bslice = []PortBinding{} - } - bindings[port] = append(bslice, binding) - } - } - return exposedPorts, bindings, nil -} diff --git a/pkg/nat/nat_test.go b/pkg/nat/nat_test.go deleted file mode 100644 index 2c71142bad..0000000000 --- a/pkg/nat/nat_test.go +++ /dev/null @@ -1,525 +0,0 @@ -package nat - -import ( - "testing" -) - -func TestParsePort(t *testing.T) { - var ( - p int - err error - ) - - p, err = ParsePort("1234") - - if err != nil || p != 1234 { - t.Fatal("Parsing '1234' did not succeed") - } - - // FIXME currently this is a valid port. I don't think it should be. - // I'm leaving this test commented out until we make a decision. - // - erikh - - /* - p, err = ParsePort("0123") - - if err != nil { - t.Fatal("Successfully parsed port '0123' to '123'") - } - */ - - p, err = ParsePort("asdf") - - if err == nil || p != 0 { - t.Fatal("Parsing port 'asdf' succeeded") - } - - p, err = ParsePort("1asdf") - - if err == nil || p != 0 { - t.Fatal("Parsing port '1asdf' succeeded") - } -} - -func TestParsePortRange(t *testing.T) { - var ( - begin int - end int - err error - ) - - type TestRange struct { - Range string - Begin int - End int - } - validRanges := []TestRange{ - {"1234", 1234, 1234}, - {"1234-1234", 1234, 1234}, - {"1234-1235", 1234, 1235}, - {"8000-9000", 8000, 9000}, - {"0", 0, 0}, - {"0-0", 0, 0}, - } - - for _, r := range validRanges { - begin, end, err = ParsePortRange(r.Range) - - if err != nil || begin != r.Begin { - t.Fatalf("Parsing port range '%s' did not succeed. Expected begin %d, got %d", r.Range, r.Begin, begin) - } - if err != nil || end != r.End { - t.Fatalf("Parsing port range '%s' did not succeed. Expected end %d, got %d", r.Range, r.End, end) - } - } - - invalidRanges := []string{ - "asdf", - "1asdf", - "9000-8000", - "9000-", - "-8000", - "-8000-", - } - - for _, r := range invalidRanges { - begin, end, err = ParsePortRange(r) - - if err == nil || begin != 0 || end != 0 { - t.Fatalf("Parsing port range '%s' succeeded", r) - } - } -} - -func TestPort(t *testing.T) { - p, err := NewPort("tcp", "1234") - - if err != nil { - t.Fatalf("tcp, 1234 had a parsing issue: %v", err) - } - - if string(p) != "1234/tcp" { - t.Fatal("tcp, 1234 did not result in the string 1234/tcp") - } - - if p.Proto() != "tcp" { - t.Fatal("protocol was not tcp") - } - - if p.Port() != "1234" { - t.Fatal("port string value was not 1234") - } - - if p.Int() != 1234 { - t.Fatal("port int value was not 1234") - } - - p, err = NewPort("tcp", "asd1234") - if err == nil { - t.Fatal("tcp, asd1234 was supposed to fail") - } - - p, err = NewPort("tcp", "1234-1230") - if err == nil { - t.Fatal("tcp, 1234-1230 was supposed to fail") - } - - p, err = NewPort("tcp", "1234-1242") - if err != nil { - t.Fatalf("tcp, 1234-1242 had a parsing issue: %v", err) - } - - if string(p) != "1234-1242/tcp" { - t.Fatal("tcp, 1234-1242 did not result in the string 1234-1242/tcp") - } -} - -func TestSplitProtoPort(t *testing.T) { - var ( - proto string - port string - ) - - proto, port = SplitProtoPort("1234/tcp") - - if proto != "tcp" || port != "1234" { - t.Fatal("Could not split 1234/tcp properly") - } - - proto, port = SplitProtoPort("") - - if proto != "" || port != "" { - t.Fatal("parsing an empty string yielded surprising results", proto, port) - } - - proto, port = SplitProtoPort("1234") - - if proto != "tcp" || port != "1234" { - t.Fatal("tcp is not the default protocol for portspec '1234'", proto, port) - } - - proto, port = SplitProtoPort("1234/") - - if proto != "tcp" || port != "1234" { - t.Fatal("parsing '1234/' yielded:" + port + "/" + proto) - } - - proto, port = SplitProtoPort("/tcp") - - if proto != "" || port != "" { - t.Fatal("parsing '/tcp' yielded:" + port + "/" + proto) - } -} - -func TestParsePortSpecs(t *testing.T) { - var ( - portMap map[Port]struct{} - bindingMap map[Port][]PortBinding - err error - ) - - portMap, bindingMap, err = ParsePortSpecs([]string{"1234/tcp", "2345/udp"}) - - if err != nil { - t.Fatalf("Error while processing ParsePortSpecs: %s", err) - } - - if _, ok := portMap[Port("1234/tcp")]; !ok { - t.Fatal("1234/tcp was not parsed properly") - } - - if _, ok := portMap[Port("2345/udp")]; !ok { - t.Fatal("2345/udp was not parsed properly") - } - - for portspec, bindings := range bindingMap { - if len(bindings) != 1 { - t.Fatalf("%s should have exactly one binding", portspec) - } - - if bindings[0].HostIP != "" { - t.Fatalf("HostIP should not be set for %s", portspec) - } - - if bindings[0].HostPort != "" { - t.Fatalf("HostPort should not be set for %s", portspec) - } - } - - portMap, bindingMap, err = ParsePortSpecs([]string{"1234:1234/tcp", "2345:2345/udp"}) - - if err != nil { - t.Fatalf("Error while processing ParsePortSpecs: %s", err) - } - - if _, ok := portMap[Port("1234/tcp")]; !ok { - t.Fatal("1234/tcp was not parsed properly") - } - - if _, ok := portMap[Port("2345/udp")]; !ok { - t.Fatal("2345/udp was not parsed properly") - } - - for portspec, bindings := range bindingMap { - _, port := SplitProtoPort(string(portspec)) - - if len(bindings) != 1 { - t.Fatalf("%s should have exactly one binding", portspec) - } - - if bindings[0].HostIP != "" { - t.Fatalf("HostIP should not be set for %s", portspec) - } - - if bindings[0].HostPort != port { - t.Fatalf("HostPort should be %s for %s", port, portspec) - } - } - - portMap, bindingMap, err = ParsePortSpecs([]string{"0.0.0.0:1234:1234/tcp", "0.0.0.0:2345:2345/udp"}) - - if err != nil { - t.Fatalf("Error while processing ParsePortSpecs: %s", err) - } - - if _, ok := portMap[Port("1234/tcp")]; !ok { - t.Fatal("1234/tcp was not parsed properly") - } - - if _, ok := portMap[Port("2345/udp")]; !ok { - t.Fatal("2345/udp was not parsed properly") - } - - for portspec, bindings := range bindingMap { - _, port := SplitProtoPort(string(portspec)) - - if len(bindings) != 1 { - t.Fatalf("%s should have exactly one binding", portspec) - } - - if bindings[0].HostIP != "0.0.0.0" { - t.Fatalf("HostIP is not 0.0.0.0 for %s", portspec) - } - - if bindings[0].HostPort != port { - t.Fatalf("HostPort should be %s for %s", port, portspec) - } - } - - _, _, err = ParsePortSpecs([]string{"localhost:1234:1234/tcp"}) - - if err == nil { - t.Fatal("Received no error while trying to parse a hostname instead of ip") - } -} - -func TestParsePortSpecsWithRange(t *testing.T) { - var ( - portMap map[Port]struct{} - bindingMap map[Port][]PortBinding - err error - ) - - portMap, bindingMap, err = ParsePortSpecs([]string{"1234-1236/tcp", "2345-2347/udp"}) - - if err != nil { - t.Fatalf("Error while processing ParsePortSpecs: %s", err) - } - - if _, ok := portMap[Port("1235/tcp")]; !ok { - t.Fatal("1234/tcp was not parsed properly") - } - - if _, ok := portMap[Port("2346/udp")]; !ok { - t.Fatal("2345/udp was not parsed properly") - } - - for portspec, bindings := range bindingMap { - if len(bindings) != 1 { - t.Fatalf("%s should have exactly one binding", portspec) - } - - if bindings[0].HostIP != "" { - t.Fatalf("HostIP should not be set for %s", portspec) - } - - if bindings[0].HostPort != "" { - t.Fatalf("HostPort should not be set for %s", portspec) - } - } - - portMap, bindingMap, err = ParsePortSpecs([]string{"1234-1236:1234-1236/tcp", "2345-2347:2345-2347/udp"}) - - if err != nil { - t.Fatalf("Error while processing ParsePortSpecs: %s", err) - } - - if _, ok := portMap[Port("1235/tcp")]; !ok { - t.Fatal("1234/tcp was not parsed properly") - } - - if _, ok := portMap[Port("2346/udp")]; !ok { - t.Fatal("2345/udp was not parsed properly") - } - - for portspec, bindings := range bindingMap { - _, port := SplitProtoPort(string(portspec)) - if len(bindings) != 1 { - t.Fatalf("%s should have exactly one binding", portspec) - } - - if bindings[0].HostIP != "" { - t.Fatalf("HostIP should not be set for %s", portspec) - } - - if bindings[0].HostPort != port { - t.Fatalf("HostPort should be %s for %s", port, portspec) - } - } - - portMap, bindingMap, err = ParsePortSpecs([]string{"0.0.0.0:1234-1236:1234-1236/tcp", "0.0.0.0:2345-2347:2345-2347/udp"}) - - if err != nil { - t.Fatalf("Error while processing ParsePortSpecs: %s", err) - } - - if _, ok := portMap[Port("1235/tcp")]; !ok { - t.Fatal("1234/tcp was not parsed properly") - } - - if _, ok := portMap[Port("2346/udp")]; !ok { - t.Fatal("2345/udp was not parsed properly") - } - - for portspec, bindings := range bindingMap { - _, port := SplitProtoPort(string(portspec)) - if len(bindings) != 1 || bindings[0].HostIP != "0.0.0.0" || bindings[0].HostPort != port { - t.Fatalf("Expect single binding to port %s but found %s", port, bindings) - } - } - - _, _, err = ParsePortSpecs([]string{"localhost:1234-1236:1234-1236/tcp"}) - - if err == nil { - t.Fatal("Received no error while trying to parse a hostname instead of ip") - } -} - -func TestParseNetworkOptsPrivateOnly(t *testing.T) { - ports, bindings, err := ParsePortSpecs([]string{"192.168.1.100::80"}) - if err != nil { - t.Fatal(err) - } - if len(ports) != 1 { - t.Logf("Expected 1 got %d", len(ports)) - t.FailNow() - } - if len(bindings) != 1 { - t.Logf("Expected 1 got %d", len(bindings)) - t.FailNow() - } - for k := range ports { - if k.Proto() != "tcp" { - t.Logf("Expected tcp got %s", k.Proto()) - t.Fail() - } - if k.Port() != "80" { - t.Logf("Expected 80 got %s", k.Port()) - t.Fail() - } - b, exists := bindings[k] - if !exists { - t.Log("Binding does not exist") - t.FailNow() - } - if len(b) != 1 { - t.Logf("Expected 1 got %d", len(b)) - t.FailNow() - } - s := b[0] - if s.HostPort != "" { - t.Logf("Expected \"\" got %s", s.HostPort) - t.Fail() - } - if s.HostIP != "192.168.1.100" { - t.Fail() - } - } -} - -func TestParseNetworkOptsPublic(t *testing.T) { - ports, bindings, err := ParsePortSpecs([]string{"192.168.1.100:8080:80"}) - if err != nil { - t.Fatal(err) - } - if len(ports) != 1 { - t.Logf("Expected 1 got %d", len(ports)) - t.FailNow() - } - if len(bindings) != 1 { - t.Logf("Expected 1 got %d", len(bindings)) - t.FailNow() - } - for k := range ports { - if k.Proto() != "tcp" { - t.Logf("Expected tcp got %s", k.Proto()) - t.Fail() - } - if k.Port() != "80" { - t.Logf("Expected 80 got %s", k.Port()) - t.Fail() - } - b, exists := bindings[k] - if !exists { - t.Log("Binding does not exist") - t.FailNow() - } - if len(b) != 1 { - t.Logf("Expected 1 got %d", len(b)) - t.FailNow() - } - s := b[0] - if s.HostPort != "8080" { - t.Logf("Expected 8080 got %s", s.HostPort) - t.Fail() - } - if s.HostIP != "192.168.1.100" { - t.Fail() - } - } -} - -func TestParseNetworkOptsPublicNoPort(t *testing.T) { - ports, bindings, err := ParsePortSpecs([]string{"192.168.1.100"}) - - if err == nil { - t.Logf("Expected error Invalid containerPort") - t.Fail() - } - if ports != nil { - t.Logf("Expected nil got %s", ports) - t.Fail() - } - if bindings != nil { - t.Logf("Expected nil got %s", bindings) - t.Fail() - } -} - -func TestParseNetworkOptsNegativePorts(t *testing.T) { - ports, bindings, err := ParsePortSpecs([]string{"192.168.1.100:-1:-1"}) - - if err == nil { - t.Fail() - } - if len(ports) != 0 { - t.Logf("Expected nil got %d", len(ports)) - t.Fail() - } - if len(bindings) != 0 { - t.Logf("Expected 0 got %d", len(bindings)) - t.Fail() - } -} - -func TestParseNetworkOptsUdp(t *testing.T) { - ports, bindings, err := ParsePortSpecs([]string{"192.168.1.100::6000/udp"}) - if err != nil { - t.Fatal(err) - } - if len(ports) != 1 { - t.Logf("Expected 1 got %d", len(ports)) - t.FailNow() - } - if len(bindings) != 1 { - t.Logf("Expected 1 got %d", len(bindings)) - t.FailNow() - } - for k := range ports { - if k.Proto() != "udp" { - t.Logf("Expected udp got %s", k.Proto()) - t.Fail() - } - if k.Port() != "6000" { - t.Logf("Expected 6000 got %s", k.Port()) - t.Fail() - } - b, exists := bindings[k] - if !exists { - t.Log("Binding does not exist") - t.FailNow() - } - if len(b) != 1 { - t.Logf("Expected 1 got %d", len(b)) - t.FailNow() - } - s := b[0] - if s.HostPort != "" { - t.Logf("Expected \"\" got %s", s.HostPort) - t.Fail() - } - if s.HostIP != "192.168.1.100" { - t.Fail() - } - } -} diff --git a/pkg/nat/sort.go b/pkg/nat/sort.go deleted file mode 100644 index 1eb0fedda5..0000000000 --- a/pkg/nat/sort.go +++ /dev/null @@ -1,98 +0,0 @@ -package nat - -import ( - "sort" - "strings" - - "github.com/docker/docker/pkg/parsers" -) - -type portSorter struct { - ports []Port - by func(i, j Port) bool -} - -func (s *portSorter) Len() int { - return len(s.ports) -} - -func (s *portSorter) Swap(i, j int) { - s.ports[i], s.ports[j] = s.ports[j], s.ports[i] -} - -func (s *portSorter) Less(i, j int) bool { - ip := s.ports[i] - jp := s.ports[j] - - return s.by(ip, jp) -} - -// Sort sorts a list of ports using the provided predicate -// This function should compare `i` and `j`, returning true if `i` is -// considered to be less than `j` -func Sort(ports []Port, predicate func(i, j Port) bool) { - s := &portSorter{ports, predicate} - sort.Sort(s) -} - -type portMapEntry struct { - port Port - binding PortBinding -} - -type portMapSorter []portMapEntry - -func (s portMapSorter) Len() int { return len(s) } -func (s portMapSorter) Swap(i, j int) { s[i], s[j] = s[j], s[i] } - -// sort the port so that the order is: -// 1. port with larger specified bindings -// 2. larger port -// 3. port with tcp protocol -func (s portMapSorter) Less(i, j int) bool { - pi, pj := s[i].port, s[j].port - hpi, hpj := toInt(s[i].binding.HostPort), toInt(s[j].binding.HostPort) - return hpi > hpj || pi.Int() > pj.Int() || (pi.Int() == pj.Int() && strings.ToLower(pi.Proto()) == "tcp") -} - -// SortPortMap sorts the list of ports and their respected mapping. The ports -// will explicit HostPort will be placed first. -func SortPortMap(ports []Port, bindings PortMap) { - s := portMapSorter{} - for _, p := range ports { - if binding, ok := bindings[p]; ok { - for _, b := range binding { - s = append(s, portMapEntry{port: p, binding: b}) - } - bindings[p] = []PortBinding{} - } else { - s = append(s, portMapEntry{port: p}) - } - } - - sort.Sort(s) - var ( - i int - pm = make(map[Port]struct{}) - ) - // reorder ports - for _, entry := range s { - if _, ok := pm[entry.port]; !ok { - ports[i] = entry.port - pm[entry.port] = struct{}{} - i++ - } - // reorder bindings for this port - if _, ok := bindings[entry.port]; ok { - bindings[entry.port] = append(bindings[entry.port], entry.binding) - } - } -} - -func toInt(s string) uint64 { - i, _, err := parsers.ParsePortRange(s) - if err != nil { - i = 0 - } - return i -} diff --git a/pkg/nat/sort_test.go b/pkg/nat/sort_test.go deleted file mode 100644 index 88ed911156..0000000000 --- a/pkg/nat/sort_test.go +++ /dev/null @@ -1,85 +0,0 @@ -package nat - -import ( - "fmt" - "reflect" - "testing" -) - -func TestSortUniquePorts(t *testing.T) { - ports := []Port{ - Port("6379/tcp"), - Port("22/tcp"), - } - - Sort(ports, func(ip, jp Port) bool { - return ip.Int() < jp.Int() || (ip.Int() == jp.Int() && ip.Proto() == "tcp") - }) - - first := ports[0] - if fmt.Sprint(first) != "22/tcp" { - t.Log(fmt.Sprint(first)) - t.Fail() - } -} - -func TestSortSamePortWithDifferentProto(t *testing.T) { - ports := []Port{ - Port("8888/tcp"), - Port("8888/udp"), - Port("6379/tcp"), - Port("6379/udp"), - } - - Sort(ports, func(ip, jp Port) bool { - return ip.Int() < jp.Int() || (ip.Int() == jp.Int() && ip.Proto() == "tcp") - }) - - first := ports[0] - if fmt.Sprint(first) != "6379/tcp" { - t.Fail() - } -} - -func TestSortPortMap(t *testing.T) { - ports := []Port{ - Port("22/tcp"), - Port("22/udp"), - Port("8000/tcp"), - Port("6379/tcp"), - Port("9999/tcp"), - } - - portMap := PortMap{ - Port("22/tcp"): []PortBinding{ - {}, - }, - Port("8000/tcp"): []PortBinding{ - {}, - }, - Port("6379/tcp"): []PortBinding{ - {}, - {HostIP: "0.0.0.0", HostPort: "32749"}, - }, - Port("9999/tcp"): []PortBinding{ - {HostIP: "0.0.0.0", HostPort: "40000"}, - }, - } - - SortPortMap(ports, portMap) - if !reflect.DeepEqual(ports, []Port{ - Port("9999/tcp"), - Port("6379/tcp"), - Port("8000/tcp"), - Port("22/tcp"), - Port("22/udp"), - }) { - t.Errorf("failed to prioritize port with explicit mappings, got %v", ports) - } - if pm := portMap[Port("6379/tcp")]; !reflect.DeepEqual(pm, []PortBinding{ - {HostIP: "0.0.0.0", HostPort: "32749"}, - {}, - }) { - t.Errorf("failed to prioritize bindings with explicit mappings, got %v", pm) - } -} diff --git a/runconfig/compare_test.go b/runconfig/compare_test.go index 373b59bb50..25f2d34df0 100644 --- a/runconfig/compare_test.go +++ b/runconfig/compare_test.go @@ -4,7 +4,7 @@ import ( "testing" "github.com/docker/docker/api/types/strslice" - "github.com/docker/docker/pkg/nat" + "github.com/docker/go-connections/nat" ) // Just to make life easier diff --git a/runconfig/config.go b/runconfig/config.go index e77c2c2010..d162126509 100644 --- a/runconfig/config.go +++ b/runconfig/config.go @@ -6,8 +6,8 @@ import ( "io" "github.com/docker/docker/api/types/strslice" - "github.com/docker/docker/pkg/nat" "github.com/docker/docker/volume" + "github.com/docker/go-connections/nat" ) // Config contains the configuration data about a container. diff --git a/runconfig/hostconfig.go b/runconfig/hostconfig.go index 462502a2f6..3b9cf226f3 100644 --- a/runconfig/hostconfig.go +++ b/runconfig/hostconfig.go @@ -7,8 +7,8 @@ import ( "github.com/docker/docker/api/types/blkiodev" "github.com/docker/docker/api/types/strslice" - "github.com/docker/docker/pkg/nat" "github.com/docker/docker/pkg/ulimit" + "github.com/docker/go-connections/nat" ) // KeyValuePair is a structure that hold a value for a key. diff --git a/runconfig/merge.go b/runconfig/merge.go index 0106c7ea11..6dfd646a7c 100644 --- a/runconfig/merge.go +++ b/runconfig/merge.go @@ -3,7 +3,7 @@ package runconfig import ( "strings" - "github.com/docker/docker/pkg/nat" + "github.com/docker/go-connections/nat" ) // Merge merges two Config, the image container configuration (defaults values), diff --git a/runconfig/merge_test.go b/runconfig/merge_test.go index 6237ee9df0..fe2022de80 100644 --- a/runconfig/merge_test.go +++ b/runconfig/merge_test.go @@ -3,7 +3,7 @@ package runconfig import ( "testing" - "github.com/docker/docker/pkg/nat" + "github.com/docker/go-connections/nat" ) func TestMerge(t *testing.T) { diff --git a/runconfig/parse.go b/runconfig/parse.go index a9bbe8c4c0..4d7927f105 100644 --- a/runconfig/parse.go +++ b/runconfig/parse.go @@ -10,10 +10,10 @@ import ( "github.com/docker/docker/opts" flag "github.com/docker/docker/pkg/mflag" "github.com/docker/docker/pkg/mount" - "github.com/docker/docker/pkg/nat" "github.com/docker/docker/pkg/parsers" "github.com/docker/docker/pkg/signal" "github.com/docker/docker/volume" + "github.com/docker/go-connections/nat" "github.com/docker/go-units" ) diff --git a/runconfig/parse_test.go b/runconfig/parse_test.go index 9abbe86460..437d1393b9 100644 --- a/runconfig/parse_test.go +++ b/runconfig/parse_test.go @@ -11,7 +11,7 @@ import ( "testing" flag "github.com/docker/docker/pkg/mflag" - "github.com/docker/docker/pkg/nat" + "github.com/docker/go-connections/nat" ) func parseRun(args []string) (*Config, *HostConfig, *flag.FlagSet, error) {