Skip to content

Commit

Permalink
Allow --ip and --mac to be set when joining a CNI net
Browse files Browse the repository at this point in the history
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 containers#4500

Signed-off-by: Matthew Heon <[email protected]>
  • Loading branch information
mheon committed Nov 26, 2019
1 parent aef3858 commit 01ae532
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 13 deletions.
34 changes: 25 additions & 9 deletions libpod/networking_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand All @@ -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,
}
}

Expand Down
8 changes: 4 additions & 4 deletions libpod/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
14 changes: 14 additions & 0 deletions test/e2e/run_networking_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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))
})
})

0 comments on commit 01ae532

Please sign in to comment.