Skip to content

Commit

Permalink
Signed-off-by: fahed dorgaa <[email protected]>
Browse files Browse the repository at this point in the history
setup ipv6 for nerdctl
  • Loading branch information
fahedouch committed Mar 30, 2021
1 parent 655eb5b commit 436fce9
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 37 deletions.
95 changes: 61 additions & 34 deletions pkg/portutil/portutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,24 @@ import (
"github.com/pkg/errors"
)

func ParseFlagP(s string) (*gocni.PortMapping, error) {
func splitParts(rawport string) (string, string, string) {
parts := strings.Split(rawport, ":")
n := len(parts)
containerport := parts[n-1]

switch n {
case 1:
return "", "", containerport
case 2:
return "", parts[0], containerport
case 3:
return parts[0], parts[1], containerport
default:
return strings.Join(parts[:n-2], ":"), parts[n-2], containerport
}
}

func ParseFlagP(s string) ([]gocni.PortMapping, error) {
proto := "tcp"
splitBySlash := strings.Split(s, "/")
switch len(splitBySlash) {
Expand All @@ -42,44 +59,54 @@ func ParseFlagP(s string) (*gocni.PortMapping, error) {
return nil, errors.Errorf("failed to parse %q, unexpected slashes", s)
}

res := &gocni.PortMapping{
res := gocni.PortMapping{
Protocol: proto,
HostIP: "0.0.0.0",
}

splitByColon := strings.Split(splitBySlash[0], ":")
switch len(splitByColon) {
case 1:
multi_res := []gocni.PortMapping{}

ip, hostPort, containerPort := splitParts(splitBySlash[0])

if containerPort == "" {
return nil, errors.Errorf("No port specified: %s<empty>", splitBySlash[0])
}

if hostPort == "" {
return nil, errors.Errorf("automatic host port assignment is not supported yet (FIXME)")
case 2:
i, err := strconv.Atoi(splitByColon[0])
if err != nil {
return nil, err
}
res.HostPort = int32(i)
i, err = strconv.Atoi(splitByColon[1])
if err != nil {
return nil, err
}
res.ContainerPort = int32(i)
return res, nil
case 3:
res.HostIP = splitByColon[0]
if net.ParseIP(res.HostIP) == nil {
return nil, errors.Errorf("invalid IP %q", res.HostIP)
}
i, err := strconv.Atoi(splitByColon[1])
if err != nil {
return nil, err
}

i, err := strconv.Atoi(hostPort)
if err != nil {
return nil, err
}
res.HostPort = int32(i)

i, err = strconv.Atoi(containerPort)
if err != nil {
return nil, err
}
res.ContainerPort = int32(i)

if ip == "" {
res.HostIP = "0.0.0.0"
multi_res = append(multi_res, res)
res.HostIP = "::"
multi_res = append(multi_res, res)
} else {
if ip[0] == '[' {
// Strip [] from IPV6 addresses
rawIP, _, err := net.SplitHostPort(ip + ":")
if err != nil {
return nil, errors.Errorf("Invalid ip address %v: %s", ip, err)
}
ip = rawIP
}
res.HostPort = int32(i)
i, err = strconv.Atoi(splitByColon[2])
if err != nil {
return nil, err

if net.ParseIP(ip) == nil {
return nil, errors.Errorf("Invalid ip address: %s", ip)
}
res.ContainerPort = int32(i)
return res, nil
default:
return nil, errors.Errorf("failed to parse %q, unexpected colons", s)
res.HostIP = ip
multi_res = append(multi_res, res)
}
return multi_res, nil
}
6 changes: 3 additions & 3 deletions run.go
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ func runAction(clicontext *cli.Context) error {
portSlice := strutil.DedupeStrSlice(clicontext.StringSlice("p"))
netSlice := strutil.DedupeStrSlice(clicontext.StringSlice("net"))

ports := make([]gocni.PortMapping, len(portSlice))
ports := make([]gocni.PortMapping, 0)
if len(netSlice) != 1 {
return errors.New("currently, number of networks must be 1")
}
Expand Down Expand Up @@ -369,12 +369,12 @@ func runAction(clicontext *cli.Context) error {
return err
}
opts = append(opts, withCustomResolvConf(resolvConfPath), withCustomHosts(etcHostsPath))
for i, p := range portSlice {
for _, p := range portSlice {
pm, err := portutil.ParseFlagP(p)
if err != nil {
return err
}
ports[i] = *pm
ports = append(ports, pm...)
}
}

Expand Down
17 changes: 17 additions & 0 deletions run_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,3 +137,20 @@ func TestRunExitCode(t *testing.T) {
assert.Equal(base.T, "exited", inspect123.State.Status)
assert.Equal(base.T, 123, inspect123.State.ExitCode)
}

func TestRunPortMappingWithEmptyIP(t *testing.T) {
base := testutil.NewBase(t)
defer base.Cmd("rm", "-f", "testPortMappingWithEmptyIP").Run()
const expected = `80/tcp -> 0.0.0.0:80
80/tcp -> :::80`
base.Cmd("run", "-d", "--name", "testPortMappingWithEmptyIP", "-p", "80:80", testutil.NginxAlpineImage).Run()
base.Cmd("port", "testPortMappingWithEmptyIP").AssertOut(expected)
}

func TestRunPortMappingWithIPv6(t *testing.T) {
base := testutil.NewBase(t)
defer base.Cmd("rm", "-f", "testPortMappingWithIPv6").Run()
base.Cmd("run", "-d", "--name", "testPortMappingWithIPv6", "-p", ":::80:80", testutil.NginxAlpineImage).Run()
const expected = `80/tcp -> :::80`
base.Cmd("port", "testPortMappingWithIPv6").AssertOut(expected)
}

0 comments on commit 436fce9

Please sign in to comment.