From d85d6703b503b4a2d5af37e6205a16f05530600a Mon Sep 17 00:00:00 2001 From: Rudy Zhang Date: Mon, 6 May 2019 20:41:58 +0800 Subject: [PATCH] feature: support set ipv4 or ipv6 when create container support set ipv4 or ipv6 to container when create new container. Signed-off-by: Rudy Zhang --- apis/opts/networks.go | 31 ++++++++++++++++++++++++- cli/common_flags.go | 14 +++++++----- cli/container.go | 44 +++++++++++++++++++++--------------- test/cli_run_network_test.go | 24 ++++++++++++++++++++ 4 files changed, 88 insertions(+), 25 deletions(-) diff --git a/apis/opts/networks.go b/apis/opts/networks.go index f80205c7c..e3c0af5a5 100644 --- a/apis/opts/networks.go +++ b/apis/opts/networks.go @@ -109,9 +109,38 @@ func ValidateNetworks(nwConfig *types.NetworkingConfig) error { if v.IPAMConfig.IPV4Address != "" && net.ParseIP(v.IPAMConfig.IPV4Address).To4() == nil { return fmt.Errorf("invalid IPv4 address: %s", v.IPAMConfig.IPV4Address) } - // TODO: check IPv6Address + if v.IPAMConfig.IPV6Address != "" && net.ParseIP(v.IPAMConfig.IPV6Address).To16() == nil { + return fmt.Errorf("invalid IPv6 addresss: %s", v.IPAMConfig.IPV6Address) + } } } return nil } + +// SetEndpointIPAddress set the ip address of the endpoint when network is bridge. +func SetEndpointIPAddress(nwConfig *types.NetworkingConfig, mode, ipv4, ipv6 string) error { + if nwConfig == nil || mode == "" { + return nil + } + + if nwConfig.EndpointsConfig != nil { + nwConfig.EndpointsConfig = make(map[string]*types.EndpointSettings) + } + + epConfig := nwConfig.EndpointsConfig[mode] + if epConfig == nil { + epConfig = &types.EndpointSettings{} + } + + if epConfig.IPAMConfig == nil { + epConfig.IPAMConfig = &types.EndpointIPAMConfig{} + } + + epConfig.IPAMConfig.IPV4Address = ipv4 + epConfig.IPAMConfig.IPV6Address = ipv6 + + nwConfig.EndpointsConfig[mode] = epConfig + + return nil +} diff --git a/cli/common_flags.go b/cli/common_flags.go index 8ac20d328..94dd1a599 100644 --- a/cli/common_flags.go +++ b/cli/common_flags.go @@ -33,11 +33,6 @@ func addCommonFlags(flagSet *pflag.FlagSet) *container { // device related options flagSet.StringSliceVarP(&c.devices, "device", "", nil, "Add a host device to the container") - // dns - flagSet.StringArrayVar(&c.dns, "dns", nil, "Set DNS servers") - flagSet.StringSliceVar(&c.dnsOptions, "dns-option", nil, "Set DNS options") - flagSet.StringArrayVar(&c.dnsSearch, "dns-search", nil, "Set DNS search domains") - flagSet.BoolVar(&c.enableLxcfs, "enableLxcfs", false, "Enable lxcfs for the container, only effective when enable-lxcfs switched on in Pouchd") flagSet.StringVar(&c.entrypoint, "entrypoint", "", "Overwrite the default ENTRYPOINT of the image") flagSet.StringArrayVarP(&c.env, "env", "e", nil, "Set environment variables for container('--env A=' means setting env A to empty, '--env B' means removing env B from container env inherited from image)") @@ -66,11 +61,19 @@ func addCommonFlags(flagSet *pflag.FlagSet) *container { flagSet.StringVar(&c.name, "name", "", "Specify name of container") flagSet.StringVar(&c.specificID, "specific-id", "", "Specify id of container, length of id should be 64, characters of id should be in '0123456789abcdef'") + // network flagSet.StringSliceVar(&c.networks, "net", nil, "Set networks to container") flagSet.StringSliceVarP(&c.ports, "publish", "p", nil, "Set container ports mapping") flagSet.StringSliceVar(&c.expose, "expose", nil, "Set expose container's ports") flagSet.BoolVarP(&c.publishAll, "publish-all", "P", false, "Publish all exposed ports to random ports") flagSet.StringVar(&c.macAddress, "mac-address", "", "Set mac address of container endpoint") + flagSet.StringVar(&c.ip, "ip", "", "Set IPv4 address of container endpoint") + flagSet.StringVar(&c.ipv6, "ip6", "", "Set IPv6 address of container endpoint") + flagSet.Int64Var(&c.netPriority, "net-priority", 0, "net priority") + // dns + flagSet.StringArrayVar(&c.dns, "dns", nil, "Set DNS servers") + flagSet.StringSliceVar(&c.dnsOptions, "dns-option", nil, "Set DNS options") + flagSet.StringArrayVar(&c.dnsSearch, "dns-search", nil, "Set DNS search domains") flagSet.StringVar(&c.pidMode, "pid", "", "PID namespace to use") flagSet.BoolVar(&c.privileged, "privileged", false, "Give extended privileges to the container") @@ -101,7 +104,6 @@ func addCommonFlags(flagSet *pflag.FlagSet) *container { flagSet.StringVar(&c.richMode, "rich-mode", "", "Choose one rich container mode. dumb-init(default), systemd, sbin-init") flagSet.StringVar(&c.initScript, "initscript", "", "Initial script executed in container") flagSet.StringVar(&c.shmSize, "shm-size", "", "Size of /dev/shm, default value is 64MB") - flagSet.Int64Var(&c.netPriority, "net-priority", 0, "net priority") // cgroup flagSet.StringVarP(&c.cgroupParent, "cgroup-parent", "", "", "Optional parent cgroup for the container") diff --git a/cli/container.go b/cli/container.go index 881a7e012..daee025c5 100644 --- a/cli/container.go +++ b/cli/container.go @@ -51,23 +51,28 @@ type container struct { scheLatSwitch int64 oomKillDisable bool - dns []string - dnsOptions []string - dnsSearch []string - - devices []string - enableLxcfs bool - privileged bool - restartPolicy string - ipcMode string - pidMode string - utsMode string - sysctls []string - networks []string - ports []string - expose []string - publishAll bool - macAddress string + devices []string + enableLxcfs bool + privileged bool + restartPolicy string + ipcMode string + pidMode string + utsMode string + sysctls []string + + // set network options + networks []string + ports []string + expose []string + publishAll bool + ip string + ipv6 string + macAddress string + netPriority int64 + dns []string + dnsOptions []string + dnsSearch []string + securityOpt []string capAdd []string capDrop []string @@ -80,7 +85,6 @@ type container struct { ulimit config.Ulimit pidsLimit int64 shmSize string - netPriority int64 // log driver and log option logDriver string @@ -162,6 +166,10 @@ func (c *container) config() (*types.ContainerCreateConfig, error) { return nil, err } + if err := opts.SetEndpointIPAddress(networkingConfig, networkMode, c.ip, c.ipv6); err != nil { + return nil, err + } + if err := opts.ValidateNetworks(networkingConfig); err != nil { return nil, err } diff --git a/test/cli_run_network_test.go b/test/cli_run_network_test.go index a827f8c94..b63a783d0 100644 --- a/test/cli_run_network_test.go +++ b/test/cli_run_network_test.go @@ -98,3 +98,27 @@ func (suite *PouchRunNetworkSuite) TestRunWithMacAddress(c *check.C) { c.Assert(found, check.Equals, true) } + +// TestRunWithIP is to verify run container with ipv4 address +func (suite *PouchRunNetworkSuite) TestRunWithIP(c *check.C) { + cname := "TestRunWithIP" + // TODO: add ipv6 address + ipv4 := "192.168.5.100" + + command.PouchRun("run", "-d", "--name", cname, "--ip", ipv4, busyboxImage, "sleep", "1000").Assert(c, icmd.Success) + defer command.PouchRun("rm", "-vf", cname) + + res := command.PouchRun("exec", cname, "ip", "addr", "show") + res.Assert(c, icmd.Success) + + stdout := res.Stdout() + found := false + for _, line := range strings.Split(stdout, "\n") { + if strings.Contains(line, ipv4) { + found = true + break + } + } + + c.Assert(found, check.Equals, true) +}