From 01ae532a899997cb4c930003d4f2f5d5820ba7d7 Mon Sep 17 00:00:00 2001 From: Matthew Heon Date: Wed, 20 Nov 2019 12:48:30 -0500 Subject: Allow --ip and --mac to be set when joining a CNI net These only conflict when joining more than one network. We can still set a single CNI network and set a static IP and/or static MAC. Fixes #4500 Signed-off-by: Matthew Heon --- libpod/networking_linux.go | 34 +++++++++++++++++++++++++--------- libpod/options.go | 8 ++++---- test/e2e/run_networking_test.go | 14 ++++++++++++++ 3 files changed, 43 insertions(+), 13 deletions(-) diff --git a/libpod/networking_linux.go b/libpod/networking_linux.go index cba7b636a..a68338dbb 100644 --- a/libpod/networking_linux.go +++ b/libpod/networking_linux.go @@ -29,19 +29,40 @@ import ( // Get an OCICNI network config func (r *Runtime) getPodNetwork(id, name, nsPath string, networks []string, ports []ocicni.PortMapping, staticIP net.IP, staticMAC net.HardwareAddr) ocicni.PodNetwork { - defaultNetwork := r.netPlugin.GetDefaultNetworkName() + var networkKey string + if len(networks) > 0 { + // This is inconsistent for >1 network, but it's probably the + // best we can do. + networkKey = networks[0] + } else { + networkKey = r.netPlugin.GetDefaultNetworkName() + } network := ocicni.PodNetwork{ Name: name, Namespace: name, // TODO is there something else we should put here? We don't know about Kube namespaces ID: id, NetNS: nsPath, RuntimeConfig: map[string]ocicni.RuntimeConfig{ - defaultNetwork: {PortMappings: ports}, + networkKey: {PortMappings: ports}, }, } + // If we have extra networks, add them + if len(networks) > 0 { + network.Networks = make([]ocicni.NetAttachment, len(networks)) + for i, netName := range networks { + network.Networks[i].Name = netName + } + } + if staticIP != nil || staticMAC != nil { - network.Networks = []ocicni.NetAttachment{{Name: defaultNetwork}} + // For static IP or MAC, we need to populate networks even if + // it's just the default. + if len(networks) == 0 { + // If len(networks) == 0 this is guaranteed to be the + // default network. + network.Networks = []ocicni.NetAttachment{{Name: networkKey}} + } var rt ocicni.RuntimeConfig = ocicni.RuntimeConfig{PortMappings: ports} if staticIP != nil { rt.IP = staticIP.String() @@ -50,12 +71,7 @@ func (r *Runtime) getPodNetwork(id, name, nsPath string, networks []string, port rt.MAC = staticMAC.String() } network.RuntimeConfig = map[string]ocicni.RuntimeConfig{ - defaultNetwork: rt, - } - } else { - network.Networks = make([]ocicni.NetAttachment, len(networks)) - for i, netName := range networks { - network.Networks[i].Name = netName + networkKey: rt, } } diff --git a/libpod/options.go b/libpod/options.go index bfbbb9e2d..f7f14eb26 100644 --- a/libpod/options.go +++ b/libpod/options.go @@ -1041,8 +1041,8 @@ func WithStaticIP(ip net.IP) CtrCreateOption { return errors.Wrapf(define.ErrInvalidArg, "cannot set a static IP if the container is not creating a network namespace") } - if len(ctr.config.Networks) != 0 { - return errors.Wrapf(define.ErrInvalidArg, "cannot set a static IP if joining additional CNI networks") + if len(ctr.config.Networks) > 1 { + return errors.Wrapf(define.ErrInvalidArg, "cannot set a static IP if joining more than 1 CNI network") } ctr.config.StaticIP = ip @@ -1066,8 +1066,8 @@ func WithStaticMAC(mac net.HardwareAddr) CtrCreateOption { return errors.Wrapf(define.ErrInvalidArg, "cannot set a static MAC if the container is not creating a network namespace") } - if len(ctr.config.Networks) != 0 { - return errors.Wrapf(define.ErrInvalidArg, "cannot set a static MAC if joining additional CNI networks") + if len(ctr.config.Networks) > 1 { + return errors.Wrapf(define.ErrInvalidArg, "cannot set a static MAC if joining more than 1 CNI network") } ctr.config.StaticMAC = mac diff --git a/test/e2e/run_networking_test.go b/test/e2e/run_networking_test.go index ec12f709a..5e587b198 100644 --- a/test/e2e/run_networking_test.go +++ b/test/e2e/run_networking_test.go @@ -232,4 +232,18 @@ var _ = Describe("Podman run networking", func() { Expect(session).To(ExitWithError()) Expect(session.ErrorToString()).To(ContainSubstring("stat /run/netns/xxy: no such file or directory")) }) + + It("podman run in custom CNI network with --static-ip", func() { + SkipIfRootless() + netName := "podmantestnetwork" + ipAddr := "10.20.30.128" + create := podmanTest.Podman([]string{"network", "create", "--subnet", "10.20.30.0/24", netName}) + create.WaitWithDefaultTimeout() + Expect(create.ExitCode()).To(BeZero()) + + run := podmanTest.Podman([]string{"run", "-t", "-i", "--rm", "--net", netName, "--ip", ipAddr, ALPINE, "ip", "addr"}) + run.WaitWithDefaultTimeout() + Expect(run.ExitCode()).To(BeZero()) + Expect(run.OutputToString()).To(ContainSubstring(ipAddr)) + }) }) -- cgit v1.2.3-54-g00ecf