mirror of https://github.com/containers/podman.git
libpod: pass down network options
do not pass network specific options through the network namespace. Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
This commit is contained in:
parent
8d12f19371
commit
9be7029cdd
|
@ -2,6 +2,7 @@ package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net"
|
"net"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/containers/libpod/v2/cmd/podman/parse"
|
"github.com/containers/libpod/v2/cmd/podman/parse"
|
||||||
"github.com/containers/libpod/v2/libpod/define"
|
"github.com/containers/libpod/v2/libpod/define"
|
||||||
|
@ -164,11 +165,18 @@ func NetFlagsToNetOptions(cmd *cobra.Command) (*entities.NetOptions, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
parts := strings.SplitN(network, ":", 2)
|
||||||
|
|
||||||
ns, cniNets, err := specgen.ParseNetworkNamespace(network)
|
ns, cniNets, err := specgen.ParseNetworkNamespace(network)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
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.Network = ns
|
||||||
opts.CNINetworks = cniNets
|
opts.CNINetworks = cniNets
|
||||||
}
|
}
|
||||||
|
|
|
@ -417,6 +417,7 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *ContainerCLIOpts, args []string
|
||||||
s.DNSOptions = c.Net.DNSOptions
|
s.DNSOptions = c.Net.DNSOptions
|
||||||
s.StaticIP = c.Net.StaticIP
|
s.StaticIP = c.Net.StaticIP
|
||||||
s.StaticMAC = c.Net.StaticMAC
|
s.StaticMAC = c.Net.StaticMAC
|
||||||
|
s.NetworkOptions = c.Net.NetworkOptions
|
||||||
s.UseImageHosts = c.Net.NoHosts
|
s.UseImageHosts = c.Net.NoHosts
|
||||||
|
|
||||||
s.ImageVolumeMode = c.ImageVolume
|
s.ImageVolumeMode = c.ImageVolume
|
||||||
|
|
|
@ -341,6 +341,8 @@ type ContainerConfig struct {
|
||||||
Networks []string `json:"networks,omitempty"`
|
Networks []string `json:"networks,omitempty"`
|
||||||
// Network mode specified for the default network.
|
// Network mode specified for the default network.
|
||||||
NetMode namespaces.NetworkMode `json:"networkMode,omitempty"`
|
NetMode namespaces.NetworkMode `json:"networkMode,omitempty"`
|
||||||
|
// NetworkOptions are additional options for each network
|
||||||
|
NetworkOptions map[string][]string `json:"network_options,omitempty"`
|
||||||
|
|
||||||
// Image Config
|
// Image Config
|
||||||
|
|
||||||
|
|
|
@ -223,6 +223,22 @@ func (r *Runtime) setupRootlessNetNS(ctr *Container) error {
|
||||||
havePortMapping := len(ctr.Config().PortMappings) > 0
|
havePortMapping := len(ctr.Config().PortMappings) > 0
|
||||||
logPath := filepath.Join(ctr.runtime.config.Engine.TmpDir, fmt.Sprintf("slirp4netns-%s.log", ctr.config.ID))
|
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{}
|
cmdArgs := []string{}
|
||||||
slirpFeatures, err := checkSlirpFlags(path)
|
slirpFeatures, err := checkSlirpFlags(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -242,7 +258,7 @@ func (r *Runtime) setupRootlessNetNS(ctr *Container) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
var apiSocket string
|
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))
|
apiSocket = filepath.Join(ctr.runtime.config.Engine.TmpDir, fmt.Sprintf("%s.net", ctr.config.ID))
|
||||||
cmdArgs = append(cmdArgs, "--api-socket", apiSocket)
|
cmdArgs = append(cmdArgs, "--api-socket", apiSocket)
|
||||||
}
|
}
|
||||||
|
@ -310,7 +326,7 @@ func (r *Runtime) setupRootlessNetNS(ctr *Container) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if havePortMapping {
|
if havePortMapping {
|
||||||
if ctr.config.NetMode.IsPortForwardViaSlirpHostFwd() {
|
if isSlirpHostForward {
|
||||||
return r.setupRootlessPortMappingViaSlirp(ctr, cmd, apiSocket)
|
return r.setupRootlessPortMappingViaSlirp(ctr, cmd, apiSocket)
|
||||||
} else {
|
} else {
|
||||||
return r.setupRootlessPortMappingViaRLK(ctr, netnsPath)
|
return r.setupRootlessPortMappingViaRLK(ctr, netnsPath)
|
||||||
|
|
|
@ -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
|
// WithStaticMAC indicates that the container should request a static MAC from
|
||||||
// the CNI plugins.
|
// the CNI plugins.
|
||||||
// It cannot be set unless WithNetNS has already been passed.
|
// It cannot be set unless WithNetNS has already been passed.
|
||||||
|
|
|
@ -42,6 +42,8 @@ type NetOptions struct {
|
||||||
PublishPorts []specgen.PortMapping
|
PublishPorts []specgen.PortMapping
|
||||||
StaticIP *net.IP
|
StaticIP *net.IP
|
||||||
StaticMAC *net.HardwareAddr
|
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
|
// All CLI inspect commands and inspect sub-commands use the same options
|
||||||
|
|
|
@ -17,9 +17,7 @@ const (
|
||||||
nsType = "ns"
|
nsType = "ns"
|
||||||
podType = "pod"
|
podType = "pod"
|
||||||
privateType = "private"
|
privateType = "private"
|
||||||
rlkFwdType = "port_handler=rootlesskit"
|
|
||||||
shareableType = "shareable"
|
shareableType = "shareable"
|
||||||
slirpFwdType = "port_handler=slirp4netns"
|
|
||||||
slirpType = "slirp4netns"
|
slirpType = "slirp4netns"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -390,28 +388,6 @@ func (n NetworkMode) IsSlirp4netns() bool {
|
||||||
return n == slirpType || strings.HasPrefix(string(n), slirpType+":")
|
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>)
|
// IsNS indicates a network namespace passed in by path (ns:<path>)
|
||||||
func (n NetworkMode) IsNS() bool {
|
func (n NetworkMode) IsNS() bool {
|
||||||
return strings.HasPrefix(string(n), nsType)
|
return strings.HasPrefix(string(n), nsType)
|
||||||
|
|
|
@ -266,6 +266,9 @@ func namespaceOptions(ctx context.Context, s *specgen.SpecGenerator, rt *libpod.
|
||||||
if s.StaticMAC != nil {
|
if s.StaticMAC != nil {
|
||||||
toReturn = append(toReturn, libpod.WithStaticMAC(*s.StaticMAC))
|
toReturn = append(toReturn, libpod.WithStaticMAC(*s.StaticMAC))
|
||||||
}
|
}
|
||||||
|
if s.NetworkOptions != nil {
|
||||||
|
toReturn = append(toReturn, libpod.WithNetworkOptions(s.NetworkOptions))
|
||||||
|
}
|
||||||
|
|
||||||
return toReturn, nil
|
return toReturn, nil
|
||||||
}
|
}
|
||||||
|
@ -470,7 +473,7 @@ func GetNamespaceOptions(ns []string) ([]libpod.PodCreateOption, error) {
|
||||||
case "pid":
|
case "pid":
|
||||||
options = append(options, libpod.WithPodPID())
|
options = append(options, libpod.WithPodPID())
|
||||||
case "user":
|
case "user":
|
||||||
return erroredOptions, errors.Errorf("User sharing functionality not supported on pod level")
|
continue
|
||||||
case "ipc":
|
case "ipc":
|
||||||
options = append(options, libpod.WithPodIPC())
|
options = append(options, libpod.WithPodIPC())
|
||||||
case "uts":
|
case "uts":
|
||||||
|
|
|
@ -109,16 +109,6 @@ func validateNetNS(n *Namespace) error {
|
||||||
}
|
}
|
||||||
switch n.NSMode {
|
switch n.NSMode {
|
||||||
case Slirp:
|
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
|
break
|
||||||
case "", Default, Host, Path, FromContainer, FromPod, Private, NoNetwork, Bridge:
|
case "", Default, Host, Path, FromContainer, FromPod, Private, NoNetwork, Bridge:
|
||||||
break
|
break
|
||||||
|
@ -263,11 +253,7 @@ func ParseNetworkNamespace(ns string) (Namespace, []string, error) {
|
||||||
// Net defaults to Slirp on rootless
|
// Net defaults to Slirp on rootless
|
||||||
switch {
|
switch {
|
||||||
case ns == "slirp4netns", strings.HasPrefix(ns, "slirp4netns:"):
|
case ns == "slirp4netns", strings.HasPrefix(ns, "slirp4netns:"):
|
||||||
split := strings.SplitN(ns, ":", 2)
|
|
||||||
toReturn.NSMode = Slirp
|
toReturn.NSMode = Slirp
|
||||||
if len(split) > 1 {
|
|
||||||
toReturn.Value = split[1]
|
|
||||||
}
|
|
||||||
case ns == "pod":
|
case ns == "pod":
|
||||||
toReturn.NSMode = FromPod
|
toReturn.NSMode = FromPod
|
||||||
case ns == "":
|
case ns == "":
|
||||||
|
|
|
@ -378,6 +378,9 @@ type ContainerNetworkConfig struct {
|
||||||
// Conflicts with UseImageHosts.
|
// Conflicts with UseImageHosts.
|
||||||
// Optional.
|
// Optional.
|
||||||
HostAdd []string `json:"hostadd,omitempty"`
|
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.
|
// ContainerResourceConfig contains information on container resource limits.
|
||||||
|
|
|
@ -221,6 +221,29 @@ var _ = Describe("Podman run networking", func() {
|
||||||
Expect(ncBusy).To(ExitWithError())
|
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() {
|
It("podman run network expose ports in image metadata", func() {
|
||||||
session := podmanTest.Podman([]string{"create", "-dt", "-P", nginx})
|
session := podmanTest.Podman([]string{"create", "-dt", "-P", nginx})
|
||||||
session.Wait(90)
|
session.Wait(90)
|
||||||
|
|
Loading…
Reference in New Issue