diff --git a/cmd/podman/common/netflags.go b/cmd/podman/common/netflags.go index 78cfe2f13a..aa8714b50e 100644 --- a/cmd/podman/common/netflags.go +++ b/cmd/podman/common/netflags.go @@ -2,7 +2,6 @@ package common import ( "net" - "strings" "github.com/containers/common/pkg/completion" "github.com/containers/podman/v3/cmd/podman/parse" @@ -204,17 +203,13 @@ func NetFlagsToNetOptions(cmd *cobra.Command, netnsFromConfig bool) (*entities.N return nil, err } - parts := strings.SplitN(network, ":", 2) - - ns, cniNets, err := specgen.ParseNetworkNamespace(network, containerConfig.Containers.RootlessNetworking == "cni") + ns, cniNets, options, err := specgen.ParseNetworkString(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 + if len(options) > 0 { + opts.NetworkOptions = options } opts.Network = ns opts.CNINetworks = cniNets diff --git a/pkg/domain/infra/abi/play.go b/pkg/domain/infra/abi/play.go index 0ac9b5d8d7..4782f0d01a 100644 --- a/pkg/domain/infra/abi/play.go +++ b/pkg/domain/infra/abi/play.go @@ -182,20 +182,22 @@ func (ic *ContainerEngine) playKubePod(ctx context.Context, podName string, podY return nil, err } if options.Network != "" { - switch strings.ToLower(options.Network) { - case "bridge", "host": + ns, cniNets, netOpts, err := specgen.ParseNetworkString(options.Network) + if err != nil { + return nil, err + } + + if (ns.IsBridge() && len(cniNets) == 0) || ns.IsHost() { return nil, errors.Errorf("invalid value passed to --network: bridge or host networking must be configured in YAML") - case "": - return nil, errors.Errorf("invalid value passed to --network: must provide a comma-separated list of CNI networks") - default: - // We'll assume this is a comma-separated list of CNI - // networks. - networks := strings.Split(options.Network, ",") - logrus.Debugf("Pod joining CNI networks: %v", networks) - p.NetNS.NSMode = specgen.Bridge - p.CNINetworks = append(p.CNINetworks, networks...) + } + logrus.Debugf("Pod %q joining CNI networks: %v", podName, cniNets) + p.NetNS.NSMode = specgen.Bridge + p.CNINetworks = append(p.CNINetworks, cniNets...) + if len(netOpts) > 0 { + p.NetworkOptions = netOpts } } + if len(options.StaticIPs) > *ipIndex { p.StaticIP = &options.StaticIPs[*ipIndex] } else if len(options.StaticIPs) > 0 { diff --git a/pkg/specgen/namespaces.go b/pkg/specgen/namespaces.go index 80852930a2..76fa66bc72 100644 --- a/pkg/specgen/namespaces.go +++ b/pkg/specgen/namespaces.go @@ -68,6 +68,11 @@ func (n *Namespace) IsHost() bool { return n.NSMode == Host } +// IsBridge returns a bool if the namespace is a Bridge +func (n *Namespace) IsBridge() bool { + return n.NSMode == Bridge +} + // IsPath indicates via bool if the namespace is based on a path func (n *Namespace) IsPath() bool { return n.NSMode == Path @@ -301,3 +306,20 @@ func ParseNetworkNamespace(ns string, rootlessDefaultCNI bool) (Namespace, []str return toReturn, cniNetworks, nil } + +func ParseNetworkString(network string) (Namespace, []string, map[string][]string, error) { + var networkOptions map[string][]string + parts := strings.SplitN(network, ":", 2) + + ns, cniNets, err := ParseNetworkNamespace(network, containerConfig.Containers.RootlessNetworking == "cni") + if err != nil { + return Namespace{}, nil, nil, err + } + + if len(parts) > 1 { + networkOptions = make(map[string][]string) + networkOptions[parts[0]] = strings.Split(parts[1], ",") + cniNets = nil + } + return ns, cniNets, networkOptions, nil +} diff --git a/test/system/700-play.bats b/test/system/700-play.bats index 15f3e240a0..3e6961b085 100644 --- a/test/system/700-play.bats +++ b/test/system/700-play.bats @@ -89,6 +89,18 @@ RELABEL="system_u:object_r:container_file_t:s0" run_podman pod rm -f test_pod } +@test "podman play --network" { + TESTDIR=$PODMAN_TMPDIR/testdir + mkdir -p $TESTDIR + echo "$testYaml" | sed "s|TESTDIR|${TESTDIR}|g" > $PODMAN_TMPDIR/test.yaml + run_podman 125 play kube --network bridge $PODMAN_TMPDIR/test.yaml + is "$output" ".*invalid value passed to --network: bridge or host networking must be configured in YAML" "podman plan-network should fail wth --network host" + run_podman 125 play kube --network host $PODMAN_TMPDIR/test.yaml + is "$output" ".*invalid value passed to --network: bridge or host networking must be configured in YAML" "podman plan-network should fail wth --network host" + run_podman play kube --network slirp4netns:port_handler=slirp4netns $PODMAN_TMPDIR/test.yaml + run_podman pod rm -f test_pod +} + @test "podman play with user from image" { TESTDIR=$PODMAN_TMPDIR/testdir mkdir -p $TESTDIR