Skip to content

Commit ca1bfbc

Browse files
author
zhangyue
committed
feature: addd publish-all cli flag
Signed-off-by: zhangyue <[email protected]>
1 parent 7101cf2 commit ca1bfbc

File tree

6 files changed

+135
-20
lines changed

6 files changed

+135
-20
lines changed

cli/common_flags.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ func addCommonFlags(flagSet *pflag.FlagSet) *container {
7171
flagSet.StringSliceVar(&c.networks, "net", nil, "Set networks to container")
7272
flagSet.StringSliceVarP(&c.ports, "publish", "p", nil, "Set container ports mapping")
7373
flagSet.StringSliceVar(&c.expose, "expose", nil, "Set expose container's ports")
74+
flagSet.BoolVarP(&c.publishAll, "publish-all", "P", false, "Publish all exposed ports to random ports")
7475

7576
flagSet.StringVar(&c.pidMode, "pid", "", "PID namespace to use")
7677
flagSet.BoolVar(&c.privileged, "privileged", false, "Give extended privileges to the container")

cli/container.go

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -239,23 +239,24 @@ func (c *container) config() (*types.ContainerCreateConfig, error) {
239239
Ulimits: c.ulimit.Value(),
240240
PidsLimit: c.pidsLimit,
241241
},
242-
DNS: c.dns,
243-
DNSOptions: c.dnsOptions,
244-
DNSSearch: c.dnsSearch,
245-
EnableLxcfs: c.enableLxcfs,
246-
Privileged: c.privileged,
247-
RestartPolicy: restartPolicy,
248-
IpcMode: c.ipcMode,
249-
PidMode: c.pidMode,
250-
UTSMode: c.utsMode,
251-
GroupAdd: c.groupAdd,
252-
Sysctls: sysctls,
253-
SecurityOpt: c.securityOpt,
254-
NetworkMode: networkMode,
255-
CapAdd: c.capAdd,
256-
CapDrop: c.capDrop,
257-
PortBindings: portBindings,
258-
OomScoreAdj: c.oomScoreAdj,
242+
DNS: c.dns,
243+
DNSOptions: c.dnsOptions,
244+
DNSSearch: c.dnsSearch,
245+
EnableLxcfs: c.enableLxcfs,
246+
Privileged: c.privileged,
247+
RestartPolicy: restartPolicy,
248+
IpcMode: c.ipcMode,
249+
PidMode: c.pidMode,
250+
UTSMode: c.utsMode,
251+
GroupAdd: c.groupAdd,
252+
Sysctls: sysctls,
253+
SecurityOpt: c.securityOpt,
254+
NetworkMode: networkMode,
255+
PublishAllPorts: c.publishAll,
256+
CapAdd: c.capAdd,
257+
CapDrop: c.capDrop,
258+
PortBindings: portBindings,
259+
OomScoreAdj: c.oomScoreAdj,
259260
LogConfig: &types.LogConfig{
260261
LogDriver: c.logDriver,
261262
LogOpts: logOpts,

daemon/mgr/container.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -650,6 +650,15 @@ func (mgr *ContainerManager) prepareContainerNetwork(ctx context.Context, c *Con
650650
}
651651
}
652652

653+
sb, err := mgr.NetworkMgr.Controller().SandboxByID(c.NetworkSettings.SandboxID)
654+
if err != nil {
655+
//sandbox not found, maybe caused by disconnect network or no endpoint
656+
logrus.Warnf("failed to get sandbox by id(%s)", c.NetworkSettings.SandboxID)
657+
c.NetworkSettings.Ports = types.PortMap{}
658+
return nil
659+
}
660+
661+
c.NetworkSettings.Ports = getSandboxPortMapInfo(sb)
653662
return nil
654663
}
655664

@@ -1461,7 +1470,7 @@ func (mgr *ContainerManager) Disconnect(ctx context.Context, containerName, netw
14611470
c.Unlock()
14621471
endpoint.EndpointConfig = epConfig
14631472
if err := mgr.NetworkMgr.EndpointRemove(ctx, endpoint); err != nil {
1464-
// TODO(ziren): it is a trick, we should wrapper sanbox
1473+
// TODO(ziren): it is a trick, we should wrapper sandbox
14651474
// not found as an error type
14661475
if !strings.Contains(err.Error(), "not found") {
14671476
logrus.Errorf("failed to remove endpoint: %v", err)

daemon/mgr/network.go

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"fmt"
66
"net"
77
"path"
8+
"strconv"
89
"strings"
910

1011
apitypes "github.com/alibaba/pouch/apis/types"
@@ -662,7 +663,6 @@ func buildSandboxOptions(config network.Config, endpoint *types.Endpoint) ([]lib
662663

663664
// TODO: secondary ip address
664665
// TODO: parse extra hosts
665-
// TODO: port mapping
666666
var bindings = make(nat.PortMap)
667667
if endpoint.PortBindings != nil {
668668
for p, b := range endpoint.PortBindings {
@@ -744,3 +744,66 @@ func joinOptions(endpoint *types.Endpoint) ([]libnetwork.EndpointOption, error)
744744
joinOptions = append(joinOptions, libnetwork.JoinOptionPriority(nil, endpoint.Priority))
745745
return joinOptions, nil
746746
}
747+
748+
// getSandboxPortMapInfo retrieves the current port-mapping programmed for the given sandbox.
749+
func getSandboxPortMapInfo(sb libnetwork.Sandbox) apitypes.PortMap {
750+
pm := apitypes.PortMap{}
751+
if sb == nil {
752+
return pm
753+
}
754+
755+
for _, ep := range sb.Endpoints() {
756+
pm, _ = getEndpointPortMapInfo(ep)
757+
if len(pm) > 0 {
758+
break
759+
}
760+
}
761+
return pm
762+
}
763+
764+
func getEndpointPortMapInfo(ep libnetwork.Endpoint) (apitypes.PortMap, error) {
765+
pm := apitypes.PortMap{}
766+
driverInfo, err := ep.DriverInfo()
767+
if err != nil {
768+
return pm, err
769+
}
770+
771+
if driverInfo == nil {
772+
return pm, nil
773+
}
774+
775+
// get exposedPorts from driverInfo, which was open by --expose and so on
776+
if expData, ok := driverInfo[netlabel.ExposedPorts]; ok {
777+
if exposedPorts, ok := expData.([]networktypes.TransportPort); ok {
778+
for _, tp := range exposedPorts {
779+
natPort, err := nat.NewPort(tp.Proto.String(), strconv.Itoa(int(tp.Port)))
780+
if err != nil {
781+
return pm, fmt.Errorf("failed to parse Port value(%v):%v", tp.Port, err)
782+
}
783+
pm[string(natPort)] = nil
784+
}
785+
}
786+
}
787+
788+
mapData, ok := driverInfo[netlabel.PortMap]
789+
if !ok {
790+
return pm, nil
791+
}
792+
793+
// get the port-mapping from driverInfo, which was open by -p HostPort:port
794+
portMapping, ok := mapData.([]networktypes.PortBinding)
795+
if !ok {
796+
return pm, nil
797+
}
798+
799+
for _, pp := range portMapping {
800+
natPort, err := nat.NewPort(pp.Proto.String(), strconv.Itoa(int(pp.Port)))
801+
if err != nil {
802+
return pm, err
803+
}
804+
natBndg := apitypes.PortBinding{HostIP: pp.HostIP.String(), HostPort: strconv.Itoa(int(pp.HostPort))}
805+
pm[string(natPort)] = append(pm[string(natPort)], natBndg)
806+
}
807+
808+
return pm, nil
809+
}

test/cli_inspect_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,5 +205,5 @@ func (suite *PouchInspectSuite) TestContainerInspectPorts(c *check.C) {
205205
c.Fatal("fail to format container json")
206206
}
207207
data, _ := json.Marshal(containers[0].NetworkSettings.Ports)
208-
c.Assert(string(data), check.Equals, "{\"80/tcp\":[{\"HostPort\":\"8080\"}]}")
208+
c.Assert(string(data), check.Equals, "{\"80/tcp\":[{\"HostIp\":\"0.0.0.0\",\"HostPort\":\"8080\"}]}")
209209
}

test/cli_run_network_test.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package main
22

33
import (
4+
"encoding/json"
5+
6+
"github.com/alibaba/pouch/apis/types"
47
"github.com/alibaba/pouch/test/command"
58
"github.com/alibaba/pouch/test/environment"
69

@@ -33,3 +36,41 @@ func (suite *PouchRunNetworkSuite) TestRunWithPing(c *check.C) {
3336
defer DelContainerForceMultyTime(c, name)
3437
res.Assert(c, icmd.Success)
3538
}
39+
40+
// TestRunWithPublicAll is to verify run container with publish-all flag
41+
func (suite *PouchRunNetworkSuite) TestRunWithPublishAll(c *check.C) {
42+
name := "TestRunWithPublishAll"
43+
44+
command.PouchRun("run", "--name", name, "--expose", "8080", "-P", busyboxImage).Assert(c, icmd.Success)
45+
defer DelContainerForceMultyTime(c, name)
46+
47+
output := command.PouchRun("inspect", name).Stdout()
48+
containers := make([]types.ContainerJSON, 1)
49+
err := json.Unmarshal([]byte(output), &containers)
50+
if err != nil || len(containers) == 0 {
51+
c.Fatal("fail to format container json")
52+
}
53+
c.Assert(len(containers[0].NetworkSettings.Ports), check.Equals, 1)
54+
checkPortMapExists(c, containers[0].NetworkSettings.Ports, "8080/tcp")
55+
56+
// multiple expose port case
57+
name1 := "TestRunMultipleWithPublishAll"
58+
command.PouchRun("run", "--name", name1, "--expose", "8081", "--expose", "8082", "-P", busyboxImage).Assert(c, icmd.Success)
59+
defer DelContainerForceMultyTime(c, name1)
60+
61+
output = command.PouchRun("inspect", name1).Stdout()
62+
containers = make([]types.ContainerJSON, 1)
63+
err = json.Unmarshal([]byte(output), &containers)
64+
if err != nil || len(containers) == 0 {
65+
c.Fatal("fail to format container json")
66+
}
67+
c.Assert(len(containers[0].NetworkSettings.Ports), check.Equals, 2)
68+
checkPortMapExists(c, containers[0].NetworkSettings.Ports, "8081/tcp")
69+
checkPortMapExists(c, containers[0].NetworkSettings.Ports, "8082/tcp")
70+
}
71+
72+
func checkPortMapExists(c *check.C, portMap types.PortMap, port string) {
73+
portBs, ok := portMap[port]
74+
c.Assert(ok, check.Equals, true)
75+
c.Assert(len(portBs), check.Equals, 1)
76+
}

0 commit comments

Comments
 (0)