aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd/podman/common/netflags.go8
-rw-r--r--cmd/podman/common/specgen.go1
-rw-r--r--libpod/container.go2
-rw-r--r--libpod/networking_linux.go20
-rw-r--r--libpod/options.go13
-rw-r--r--pkg/domain/entities/types.go2
-rw-r--r--pkg/namespaces/namespaces.go24
-rw-r--r--pkg/specgen/generate/namespaces.go5
-rw-r--r--pkg/specgen/namespaces.go14
-rw-r--r--pkg/specgen/specgen.go3
-rw-r--r--test/e2e/run_networking_test.go23
11 files changed, 74 insertions, 41 deletions
diff --git a/cmd/podman/common/netflags.go b/cmd/podman/common/netflags.go
index 5c83a3c9c..82a82b310 100644
--- a/cmd/podman/common/netflags.go
+++ b/cmd/podman/common/netflags.go
@@ -2,6 +2,7 @@ package common
import (
"net"
+ "strings"
"github.com/containers/libpod/v2/cmd/podman/parse"
"github.com/containers/libpod/v2/libpod/define"
@@ -164,11 +165,18 @@ func NetFlagsToNetOptions(cmd *cobra.Command) (*entities.NetOptions, error) {
return nil, err
}
+ parts := strings.SplitN(network, ":", 2)
+
ns, cniNets, err := specgen.ParseNetworkNamespace(network)
if err != nil {
return nil, err
}
+ if len(parts) > 1 {
+ opts.NetworkOptions = make(map[string][]string)
+ opts.NetworkOptions[parts[0]] = strings.Split(parts[1], ",")
+ cniNets = nil
+ }
opts.Network = ns
opts.CNINetworks = cniNets
}
diff --git a/cmd/podman/common/specgen.go b/cmd/podman/common/specgen.go
index 8a265cedf..08099da4b 100644
--- a/cmd/podman/common/specgen.go
+++ b/cmd/podman/common/specgen.go
@@ -417,6 +417,7 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *ContainerCLIOpts, args []string
s.DNSOptions = c.Net.DNSOptions
s.StaticIP = c.Net.StaticIP
s.StaticMAC = c.Net.StaticMAC
+ s.NetworkOptions = c.Net.NetworkOptions
s.UseImageHosts = c.Net.NoHosts
s.ImageVolumeMode = c.ImageVolume
diff --git a/libpod/container.go b/libpod/container.go
index f7abfb005..1ca38ae7e 100644
--- a/libpod/container.go
+++ b/libpod/container.go
@@ -341,6 +341,8 @@ type ContainerConfig struct {
Networks []string `json:"networks,omitempty"`
// Network mode specified for the default network.
NetMode namespaces.NetworkMode `json:"networkMode,omitempty"`
+ // NetworkOptions are additional options for each network
+ NetworkOptions map[string][]string `json:"network_options,omitempty"`
// Image Config
diff --git a/libpod/networking_linux.go b/libpod/networking_linux.go
index db8aa219b..9be8e0b14 100644
--- a/libpod/networking_linux.go
+++ b/libpod/networking_linux.go
@@ -223,6 +223,22 @@ func (r *Runtime) setupRootlessNetNS(ctr *Container) error {
havePortMapping := len(ctr.Config().PortMappings) > 0
logPath := filepath.Join(ctr.runtime.config.Engine.TmpDir, fmt.Sprintf("slirp4netns-%s.log", ctr.config.ID))
+ isSlirpHostForward := false
+ if ctr.config.NetworkOptions != nil {
+ slirpOptions := ctr.config.NetworkOptions["slirp4netns"]
+ for _, o := range slirpOptions {
+ switch o {
+ case "port_handler=slirp4netns":
+ isSlirpHostForward = true
+ case "port_handler=rootlesskit":
+ isSlirpHostForward = false
+ default:
+ return errors.Errorf("unknown option for slirp4netns: %q", o)
+
+ }
+ }
+ }
+
cmdArgs := []string{}
slirpFeatures, err := checkSlirpFlags(path)
if err != nil {
@@ -242,7 +258,7 @@ func (r *Runtime) setupRootlessNetNS(ctr *Container) error {
}
var apiSocket string
- if havePortMapping && ctr.config.NetMode.IsPortForwardViaSlirpHostFwd() {
+ if havePortMapping && isSlirpHostForward {
apiSocket = filepath.Join(ctr.runtime.config.Engine.TmpDir, fmt.Sprintf("%s.net", ctr.config.ID))
cmdArgs = append(cmdArgs, "--api-socket", apiSocket)
}
@@ -310,7 +326,7 @@ func (r *Runtime) setupRootlessNetNS(ctr *Container) error {
}
if havePortMapping {
- if ctr.config.NetMode.IsPortForwardViaSlirpHostFwd() {
+ if isSlirpHostForward {
return r.setupRootlessPortMappingViaSlirp(ctr, cmd, apiSocket)
} else {
return r.setupRootlessPortMappingViaRLK(ctr, netnsPath)
diff --git a/libpod/options.go b/libpod/options.go
index b3c11ebc1..32748a3c1 100644
--- a/libpod/options.go
+++ b/libpod/options.go
@@ -1003,6 +1003,19 @@ func WithStaticIP(ip net.IP) CtrCreateOption {
}
}
+// WithNetworkOptions sets additional options for the networks.
+func WithNetworkOptions(options map[string][]string) CtrCreateOption {
+ return func(ctr *Container) error {
+ if ctr.valid {
+ return define.ErrCtrFinalized
+ }
+
+ ctr.config.NetworkOptions = options
+
+ return nil
+ }
+}
+
// WithStaticMAC indicates that the container should request a static MAC from
// the CNI plugins.
// It cannot be set unless WithNetNS has already been passed.
diff --git a/pkg/domain/entities/types.go b/pkg/domain/entities/types.go
index 7e910ff61..b313e5f8b 100644
--- a/pkg/domain/entities/types.go
+++ b/pkg/domain/entities/types.go
@@ -42,6 +42,8 @@ type NetOptions struct {
PublishPorts []specgen.PortMapping
StaticIP *net.IP
StaticMAC *net.HardwareAddr
+ // NetworkOptions are additional options for each network
+ NetworkOptions map[string][]string
}
// All CLI inspect commands and inspect sub-commands use the same options
diff --git a/pkg/namespaces/namespaces.go b/pkg/namespaces/namespaces.go
index b4ec04699..7831af8f9 100644
--- a/pkg/namespaces/namespaces.go
+++ b/pkg/namespaces/namespaces.go
@@ -17,9 +17,7 @@ const (
nsType = "ns"
podType = "pod"
privateType = "private"
- rlkFwdType = "port_handler=rootlesskit"
shareableType = "shareable"
- slirpFwdType = "port_handler=slirp4netns"
slirpType = "slirp4netns"
)
@@ -390,28 +388,6 @@ func (n NetworkMode) IsSlirp4netns() bool {
return n == slirpType || strings.HasPrefix(string(n), slirpType+":")
}
-// IsPortForwardViaRootlessKit indicates if we are doing rootless port-forwarding via rootlesskit/rootlessport
-func (n NetworkMode) IsPortForwardViaRootlessKit() bool {
- if !n.IsSlirp4netns() {
- return false
- }
- parts := strings.SplitN(string(n), ":", 2)
- if len(parts) == 2 {
- return parts[1] == rlkFwdType
- }
- return true
-}
-
-// IsPortForwardViaSlirpHostFwd indicates if we are doing rootless port-forwarding via slirp4netns add_hostfwd()
-func (n NetworkMode) IsPortForwardViaSlirpHostFwd() bool {
- if !n.IsSlirp4netns() {
- return false
- }
- // below here, implied IsSlirp4netns() == true
- parts := strings.SplitN(string(n), ":", 2)
- return len(parts) > 1 && parts[1] == slirpFwdType
-}
-
// IsNS indicates a network namespace passed in by path (ns:<path>)
func (n NetworkMode) IsNS() bool {
return strings.HasPrefix(string(n), nsType)
diff --git a/pkg/specgen/generate/namespaces.go b/pkg/specgen/generate/namespaces.go
index e038fc84e..a19009bc2 100644
--- a/pkg/specgen/generate/namespaces.go
+++ b/pkg/specgen/generate/namespaces.go
@@ -266,6 +266,9 @@ func namespaceOptions(ctx context.Context, s *specgen.SpecGenerator, rt *libpod.
if s.StaticMAC != nil {
toReturn = append(toReturn, libpod.WithStaticMAC(*s.StaticMAC))
}
+ if s.NetworkOptions != nil {
+ toReturn = append(toReturn, libpod.WithNetworkOptions(s.NetworkOptions))
+ }
return toReturn, nil
}
@@ -470,7 +473,7 @@ func GetNamespaceOptions(ns []string) ([]libpod.PodCreateOption, error) {
case "pid":
options = append(options, libpod.WithPodPID())
case "user":
- return erroredOptions, errors.Errorf("User sharing functionality not supported on pod level")
+ continue
case "ipc":
options = append(options, libpod.WithPodIPC())
case "uts":
diff --git a/pkg/specgen/namespaces.go b/pkg/specgen/namespaces.go
index e62c8b709..9bf2c5d05 100644
--- a/pkg/specgen/namespaces.go
+++ b/pkg/specgen/namespaces.go
@@ -109,16 +109,6 @@ func validateNetNS(n *Namespace) error {
}
switch n.NSMode {
case Slirp:
- if n.Value != "" {
- parts := strings.Split(n.Value, ",")
- for _, p := range parts {
- switch p {
- case "port_handler=slirp4netns", "port_handler=rootlesskit":
- default:
- return errors.Errorf("invalid value for slirp %q", n.Value)
- }
- }
- }
break
case "", Default, Host, Path, FromContainer, FromPod, Private, NoNetwork, Bridge:
break
@@ -263,11 +253,7 @@ func ParseNetworkNamespace(ns string) (Namespace, []string, error) {
// Net defaults to Slirp on rootless
switch {
case ns == "slirp4netns", strings.HasPrefix(ns, "slirp4netns:"):
- split := strings.SplitN(ns, ":", 2)
toReturn.NSMode = Slirp
- if len(split) > 1 {
- toReturn.Value = split[1]
- }
case ns == "pod":
toReturn.NSMode = FromPod
case ns == "":
diff --git a/pkg/specgen/specgen.go b/pkg/specgen/specgen.go
index 16d4b7c8c..3331bf8c8 100644
--- a/pkg/specgen/specgen.go
+++ b/pkg/specgen/specgen.go
@@ -378,6 +378,9 @@ type ContainerNetworkConfig struct {
// Conflicts with UseImageHosts.
// Optional.
HostAdd []string `json:"hostadd,omitempty"`
+ // NetworkOptions are additional options for each network
+ // Optional.
+ NetworkOptions map[string][]string `json:"network_options,omitempty"`
}
// ContainerResourceConfig contains information on container resource limits.
diff --git a/test/e2e/run_networking_test.go b/test/e2e/run_networking_test.go
index 5a463d46f..50937a10b 100644
--- a/test/e2e/run_networking_test.go
+++ b/test/e2e/run_networking_test.go
@@ -221,6 +221,29 @@ var _ = Describe("Podman run networking", func() {
Expect(ncBusy).To(ExitWithError())
})
+ It("podman run network expose host port 8081 to container port 8000 using rootlesskit port handler", func() {
+ session := podmanTest.Podman([]string{"run", "--network", "slirp4netns:port_handler=rootlesskit", "-dt", "-p", "8081:8000", ALPINE, "/bin/sh"})
+ session.Wait(30)
+ Expect(session.ExitCode()).To(Equal(0))
+
+ ncBusy := SystemExec("nc", []string{"-l", "-p", "8081"})
+ Expect(ncBusy).To(ExitWithError())
+ })
+
+ It("podman run network expose host port 8082 to container port 8000 using slirp4netns port handler", func() {
+ session := podmanTest.Podman([]string{"run", "--network", "slirp4netns:port_handler=slirp4netns", "-dt", "-p", "8082:8000", ALPINE, "/bin/sh"})
+ session.Wait(30)
+ Expect(session.ExitCode()).To(Equal(0))
+ ncBusy := SystemExec("nc", []string{"-l", "-p", "8082"})
+ Expect(ncBusy).To(ExitWithError())
+ })
+
+ It("podman run network expose host port 8080 to container port 8000 using invalid port handler", func() {
+ session := podmanTest.Podman([]string{"run", "--network", "slirp4netns:port_handler=invalid", "-dt", "-p", "8080:8000", ALPINE, "/bin/sh"})
+ session.Wait(30)
+ Expect(session.ExitCode()).To(Not(Equal(0)))
+ })
+
It("podman run network expose ports in image metadata", func() {
session := podmanTest.Podman([]string{"create", "-dt", "-P", nginx})
session.Wait(90)