Skip to content

Commit

Permalink
Allow pods to use --net=none
Browse files Browse the repository at this point in the history
We need an extra field in the pod infra container config. We may
want to reevaluate that struct at some point, as storing network
modes as bools will rapidly become unsustainable, but that's a
discussion for another time. Otherwise, straightforward plumbing.

Fixes containers#9165

Signed-off-by: Matthew Heon <[email protected]>
  • Loading branch information
mheon committed Feb 4, 2021
1 parent b576ddd commit 6bd3a6b
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 12 deletions.
29 changes: 27 additions & 2 deletions libpod/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -2190,21 +2190,46 @@ func WithPodNetworks(networks []string) PodCreateOption {
}
}

// WithPodNoNetwork tells the pod to disable external networking.
func WithPodNoNetwork() PodCreateOption {
return func(pod *Pod) error {
if pod.valid {
return define.ErrPodFinalized
}

if !pod.config.InfraContainer.HasInfraContainer {
return errors.Wrapf(define.ErrInvalidArg, "cannot disable pod networking as no infra container is being created")
}

if len(pod.config.InfraContainer.PortBindings) > 0 ||
pod.config.InfraContainer.StaticIP != nil ||
pod.config.InfraContainer.StaticMAC != nil ||
len(pod.config.InfraContainer.Networks) > 0 ||
pod.config.InfraContainer.HostNetwork {
return errors.Wrapf(define.ErrInvalidArg, "cannot disable pod network if network-related configuration is specified")
}

pod.config.InfraContainer.NoNetwork = true

return nil
}
}

// WithPodHostNetwork tells the pod to use the host's network namespace.
func WithPodHostNetwork() PodCreateOption {
return func(pod *Pod) error {
if pod.valid {
return define.ErrPodFinalized
}

if !pod.config.InfraContainer.HasInfraContainer {
return errors.Wrapf(define.ErrInvalidArg, "cannot configure pod host networking as no infra container is being created")
}

if len(pod.config.InfraContainer.PortBindings) > 0 ||
pod.config.InfraContainer.StaticIP != nil ||
pod.config.InfraContainer.StaticMAC != nil ||
len(pod.config.InfraContainer.Networks) > 0 {
len(pod.config.InfraContainer.Networks) > 0 ||
pod.config.InfraContainer.NoNetwork {
return errors.Wrapf(define.ErrInvalidArg, "cannot set host network if network-related configuration is specified")
}

Expand Down
1 change: 1 addition & 0 deletions libpod/pod.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ type podState struct {
type InfraContainerConfig struct {
ConmonPidFile string `json:"conmonPidFile"`
HasInfraContainer bool `json:"makeInfraContainer"`
NoNetwork bool `json:"noNetwork,omitempty"`
HostNetwork bool `json:"infraHostNetwork,omitempty"`
PortBindings []ocicni.PortMapping `json:"infraPortBindings"`
StaticIP net.IP `json:"staticIP,omitempty"`
Expand Down
14 changes: 10 additions & 4 deletions libpod/runtime_pod_infra_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,16 @@ func (r *Runtime) makeInfraContainer(ctx context.Context, p *Pod, imgName, rawIm
}
}

// Since user namespace sharing is not implemented, we only need to check if it's rootless
if !p.config.InfraContainer.HostNetwork {
switch {
case p.config.InfraContainer.HostNetwork:
if err := g.RemoveLinuxNamespace(string(spec.NetworkNamespace)); err != nil {
return nil, errors.Wrapf(err, "error removing network namespace from pod %s infra container", p.ID())
}
case p.config.InfraContainer.NoNetwork:
// Do nothing - we have a network namespace by default,
// but should not configure slirp.
default:
// Since user namespace sharing is not implemented, we only need to check if it's rootless
netmode := "bridge"
if isRootless || p.config.InfraContainer.Slirp4netns {
netmode = "slirp4netns"
Expand All @@ -106,8 +114,6 @@ func (r *Runtime) makeInfraContainer(ctx context.Context, p *Pod, imgName, rawIm
// PostConfigureNetNS should not be set since user namespace sharing is not implemented
// and rootless networking no longer supports post configuration setup
options = append(options, WithNetNS(p.config.InfraContainer.PortBindings, false, netmode, p.config.InfraContainer.Networks))
} else if err := g.RemoveLinuxNamespace(string(spec.NetworkNamespace)); err != nil {
return nil, errors.Wrapf(err, "error removing network namespace from pod %s infra container", p.ID())
}

// For each option in InfraContainerConfig - if set, pass into
Expand Down
3 changes: 3 additions & 0 deletions pkg/specgen/generate/pod_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,9 @@ func createPodOptions(p *specgen.PodSpecGenerator, rt *libpod.Runtime) ([]libpod
case specgen.Slirp:
logrus.Debugf("Pod will use slirp4netns")
options = append(options, libpod.WithPodSlirp4netns(p.NetworkOptions))
case specgen.NoNetwork:
logrus.Debugf("Pod will not use networking")
options = append(options, libpod.WithPodNoNetwork())
default:
return nil, errors.Errorf("pods presently do not support network mode %s", p.NetNS.NSMode)
}
Expand Down
20 changes: 14 additions & 6 deletions test/e2e/pod_create_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -478,12 +478,7 @@ entrypoint ["/fromimage"]
})

It("podman create with unsupported network options", func() {
podCreate := podmanTest.Podman([]string{"pod", "create", "--network", "none"})
podCreate.WaitWithDefaultTimeout()
Expect(podCreate.ExitCode()).To(Equal(125))
Expect(podCreate.ErrorToString()).To(ContainSubstring("pods presently do not support network mode none"))

podCreate = podmanTest.Podman([]string{"pod", "create", "--network", "container:doesnotmatter"})
podCreate := podmanTest.Podman([]string{"pod", "create", "--network", "container:doesnotmatter"})
podCreate.WaitWithDefaultTimeout()
Expect(podCreate.ExitCode()).To(Equal(125))
Expect(podCreate.ErrorToString()).To(ContainSubstring("pods presently do not support network mode container"))
Expand All @@ -493,4 +488,17 @@ entrypoint ["/fromimage"]
Expect(podCreate.ExitCode()).To(Equal(125))
Expect(podCreate.ErrorToString()).To(ContainSubstring("pods presently do not support network mode path"))
})

It("podman pod create with --net=none", func() {
podName := "testPod"
podCreate := podmanTest.Podman([]string{"pod", "create", "--network", "none", "--name", podName})
podCreate.WaitWithDefaultTimeout()
Expect(podCreate.ExitCode()).To(Equal(0))

session := podmanTest.Podman([]string{"run", "--pod", podName, ALPINE, "ip", "-o", "-4", "addr"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(session.OutputToString()).To(ContainSubstring("inet 127.0.0.1/8 scope host lo"))
Expect(len(session.OutputToStringArray())).To(Equal(1))
})
})

0 comments on commit 6bd3a6b

Please sign in to comment.