aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd/podman/common/create_opts.go70
-rw-r--r--cmd/podman/common/create_test.go2
-rw-r--r--cmd/podman/common/netflags.go74
-rw-r--r--libpod/options.go3
-rw-r--r--pkg/domain/entities/pods.go6
-rw-r--r--pkg/domain/entities/types.go22
-rw-r--r--pkg/domain/infra/abi/play.go38
-rw-r--r--pkg/specgen/container_validate.go17
-rw-r--r--pkg/specgen/generate/namespaces.go38
-rw-r--r--pkg/specgen/generate/pod_create.go18
-rw-r--r--pkg/specgen/namespaces.go21
-rw-r--r--pkg/specgen/pod_validate.go20
-rw-r--r--pkg/specgen/podspecgen.go35
-rw-r--r--pkg/specgen/specgen.go24
-rw-r--r--pkg/specgenutil/specgen.go18
15 files changed, 181 insertions, 225 deletions
diff --git a/cmd/podman/common/create_opts.go b/cmd/podman/common/create_opts.go
index 7d6471fd4..8f0cd1be6 100644
--- a/cmd/podman/common/create_opts.go
+++ b/cmd/podman/common/create_opts.go
@@ -184,52 +184,56 @@ func ContainerCreateToContainerCLIOpts(cc handlers.CreateContainerConfig, rtc *c
// network names
switch {
case len(cc.NetworkingConfig.EndpointsConfig) > 0:
- var aliases []string
-
endpointsConfig := cc.NetworkingConfig.EndpointsConfig
- cniNetworks := make([]string, 0, len(endpointsConfig))
+ networks := make(map[string]types.PerNetworkOptions, len(endpointsConfig))
for netName, endpoint := range endpointsConfig {
- cniNetworks = append(cniNetworks, netName)
-
- if endpoint == nil {
- continue
- }
- if len(endpoint.Aliases) > 0 {
- aliases = append(aliases, endpoint.Aliases...)
- }
- }
+ netOpts := types.PerNetworkOptions{}
+ if endpoint != nil {
+ netOpts.Aliases = endpoint.Aliases
- // static IP and MAC
- if len(endpointsConfig) == 1 {
- for _, ep := range endpointsConfig {
- if ep == nil {
- continue
- }
// if IP address is provided
- if len(ep.IPAddress) > 0 {
- staticIP := net.ParseIP(ep.IPAddress)
- netInfo.StaticIP = &staticIP
+ if len(endpoint.IPAddress) > 0 {
+ staticIP := net.ParseIP(endpoint.IPAddress)
+ if staticIP == nil {
+ return nil, nil, errors.Errorf("failed to parse the ip address %q", endpoint.IPAddress)
+ }
+ netOpts.StaticIPs = append(netOpts.StaticIPs, staticIP)
}
- // if IPAMConfig.IPv4Address is provided
- if ep.IPAMConfig != nil && ep.IPAMConfig.IPv4Address != "" {
- staticIP := net.ParseIP(ep.IPAMConfig.IPv4Address)
- netInfo.StaticIP = &staticIP
+
+ if endpoint.IPAMConfig != nil {
+ // if IPAMConfig.IPv4Address is provided
+ if len(endpoint.IPAMConfig.IPv4Address) > 0 {
+ staticIP := net.ParseIP(endpoint.IPAMConfig.IPv4Address)
+ if staticIP == nil {
+ return nil, nil, errors.Errorf("failed to parse the ipv4 address %q", endpoint.IPAMConfig.IPv4Address)
+ }
+ netOpts.StaticIPs = append(netOpts.StaticIPs, staticIP)
+ }
+ // if IPAMConfig.IPv6Address is provided
+ if len(endpoint.IPAMConfig.IPv6Address) > 0 {
+ staticIP := net.ParseIP(endpoint.IPAMConfig.IPv6Address)
+ if staticIP == nil {
+ return nil, nil, errors.Errorf("failed to parse the ipv6 address %q", endpoint.IPAMConfig.IPv6Address)
+ }
+ netOpts.StaticIPs = append(netOpts.StaticIPs, staticIP)
+ }
}
// If MAC address is provided
- if len(ep.MacAddress) > 0 {
- staticMac, err := net.ParseMAC(ep.MacAddress)
+ if len(endpoint.MacAddress) > 0 {
+ staticMac, err := net.ParseMAC(endpoint.MacAddress)
if err != nil {
- return nil, nil, err
+ return nil, nil, errors.Errorf("failed to parse the mac address %q", endpoint.MacAddress)
}
- netInfo.StaticMAC = &staticMac
+ netOpts.StaticMAC = types.HardwareAddr(staticMac)
}
- break
}
+
+ networks[netName] = netOpts
}
- netInfo.Aliases = aliases
- netInfo.CNINetworks = cniNetworks
+
+ netInfo.Networks = networks
case len(cc.HostConfig.NetworkMode) > 0:
- netInfo.CNINetworks = networks
+ netInfo.Networks = networks
}
parsedTmp := make([]string, 0, len(cc.HostConfig.Tmpfs))
diff --git a/cmd/podman/common/create_test.go b/cmd/podman/common/create_test.go
index 17b47dd16..601078b61 100644
--- a/cmd/podman/common/create_test.go
+++ b/cmd/podman/common/create_test.go
@@ -12,7 +12,7 @@ import (
func TestPodOptions(t *testing.T) {
entry := "/test1"
- exampleOptions := entities.ContainerCreateOptions{CPUS: 5.5, CPUSetCPUs: "0-4", Entrypoint: &entry, Hostname: "foo", Name: "testing123", Volume: []string{"/fakeVol1", "/fakeVol2"}, Net: &entities.NetOptions{CNINetworks: []string{"FakeNetwork"}}, PID: "ns:/proc/self/ns"}
+ exampleOptions := entities.ContainerCreateOptions{CPUS: 5.5, CPUSetCPUs: "0-4", Entrypoint: &entry, Hostname: "foo", Name: "testing123", Volume: []string{"/fakeVol1", "/fakeVol2"}, Net: &entities.NetOptions{DNSSearch: []string{"search"}}, PID: "ns:/proc/self/ns"}
podOptions := entities.PodCreateOptions{}
err := common.ContainerToPodOptions(&exampleOptions, &podOptions)
diff --git a/cmd/podman/common/netflags.go b/cmd/podman/common/netflags.go
index d11f3c9d2..f79a9fd88 100644
--- a/cmd/podman/common/netflags.go
+++ b/cmd/podman/common/netflags.go
@@ -6,6 +6,7 @@ import (
"github.com/containers/common/pkg/completion"
"github.com/containers/podman/v3/cmd/podman/parse"
"github.com/containers/podman/v3/libpod/define"
+ "github.com/containers/podman/v3/libpod/network/types"
"github.com/containers/podman/v3/pkg/domain/entities"
"github.com/containers/podman/v3/pkg/specgen"
"github.com/containers/podman/v3/pkg/specgenutil"
@@ -151,27 +152,40 @@ func NetFlagsToNetOptions(opts *entities.NetOptions, flags pflag.FlagSet, netnsF
}
opts.DNSSearch = dnsSearches
- m, err := flags.GetString("mac-address")
+ inputPorts, err := flags.GetStringSlice("publish")
if err != nil {
return nil, err
}
- if len(m) > 0 {
- mac, err := net.ParseMAC(m)
+ if len(inputPorts) > 0 {
+ opts.PublishPorts, err = specgenutil.CreatePortBindings(inputPorts)
if err != nil {
return nil, err
}
- opts.StaticMAC = &mac
}
- inputPorts, err := flags.GetStringSlice("publish")
+ opts.NoHosts, err = flags.GetBool("no-hosts")
if err != nil {
return nil, err
}
- if len(inputPorts) > 0 {
- opts.PublishPorts, err = specgenutil.CreatePortBindings(inputPorts)
+
+ // parse the --network value only when the flag is set or we need to use
+ // the netns config value, e.g. when --pod is not used
+ if netnsFromConfig || flags.Changed("network") {
+ network, err := flags.GetString("network")
if err != nil {
return nil, err
}
+
+ ns, networks, options, err := specgen.ParseNetworkString(network)
+ if err != nil {
+ return nil, err
+ }
+
+ if len(options) > 0 {
+ opts.NetworkOptions = options
+ }
+ opts.Network = ns
+ opts.Networks = networks
}
ip, err := flags.GetString("ip")
@@ -183,35 +197,37 @@ func NetFlagsToNetOptions(opts *entities.NetOptions, flags pflag.FlagSet, netnsF
if staticIP == nil {
return nil, errors.Errorf("%s is not an ip address", ip)
}
- if staticIP.To4() == nil {
- return nil, errors.Wrapf(define.ErrInvalidArg, "%s is not an IPv4 address", ip)
+ if !opts.Network.IsBridge() {
+ return nil, errors.Wrap(define.ErrInvalidArg, "--ip can only be set when the network mode is bridge")
+ }
+ if len(opts.Networks) != 1 {
+ return nil, errors.Wrap(define.ErrInvalidArg, "--ip can only be set for a single network")
+ }
+ for name, netOpts := range opts.Networks {
+ netOpts.StaticIPs = append(netOpts.StaticIPs, staticIP)
+ opts.Networks[name] = netOpts
}
- opts.StaticIP = &staticIP
}
- opts.NoHosts, err = flags.GetBool("no-hosts")
+ m, err := flags.GetString("mac-address")
if err != nil {
return nil, err
}
-
- // parse the --network value only when the flag is set or we need to use
- // the netns config value, e.g. when --pod is not used
- if netnsFromConfig || flags.Changed("network") {
- network, err := flags.GetString("network")
+ if len(m) > 0 {
+ mac, err := net.ParseMAC(m)
if err != nil {
return nil, err
}
-
- ns, cniNets, options, err := specgen.ParseNetworkString(network)
- if err != nil {
- return nil, err
+ if !opts.Network.IsBridge() {
+ return nil, errors.Wrap(define.ErrInvalidArg, "--mac-address can only be set when the network mode is bridge")
}
-
- if len(options) > 0 {
- opts.NetworkOptions = options
+ if len(opts.Networks) != 1 {
+ return nil, errors.Wrap(define.ErrInvalidArg, "--mac-address can only be set for a single network")
+ }
+ for name, netOpts := range opts.Networks {
+ netOpts.StaticMAC = types.HardwareAddr(mac)
+ opts.Networks[name] = netOpts
}
- opts.Network = ns
- opts.CNINetworks = cniNets
}
aliases, err := flags.GetStringSlice("network-alias")
@@ -219,7 +235,13 @@ func NetFlagsToNetOptions(opts *entities.NetOptions, flags pflag.FlagSet, netnsF
return nil, err
}
if len(aliases) > 0 {
- opts.Aliases = aliases
+ if !opts.Network.IsBridge() {
+ return nil, errors.Wrap(define.ErrInvalidArg, "--network-alias can only be set when the network mode is bridge")
+ }
+ for name, netOpts := range opts.Networks {
+ netOpts.Aliases = aliases
+ opts.Networks[name] = netOpts
+ }
}
return opts, err
diff --git a/libpod/options.go b/libpod/options.go
index dbcc50741..e6fa987a8 100644
--- a/libpod/options.go
+++ b/libpod/options.go
@@ -1070,6 +1070,9 @@ func WithNetNS(portMappings []nettypes.PortMapping, exposedPorts map[uint16][]st
ctr.config.PortMappings = portMappings
ctr.config.ExposedPorts = exposedPorts
+ if !ctr.config.NetMode.IsBridge() && len(networks) > 0 {
+ return errors.New("cannot use networks when network mode is not bridge")
+ }
ctr.config.Networks = networks
return nil
diff --git a/pkg/domain/entities/pods.go b/pkg/domain/entities/pods.go
index b255785c2..14127e468 100644
--- a/pkg/domain/entities/pods.go
+++ b/pkg/domain/entities/pods.go
@@ -7,7 +7,6 @@ import (
commonFlag "github.com/containers/common/pkg/flag"
"github.com/containers/podman/v3/libpod/define"
- "github.com/containers/podman/v3/libpod/network/types"
"github.com/containers/podman/v3/pkg/specgen"
"github.com/containers/podman/v3/pkg/util"
"github.com/opencontainers/runtime-spec/specs-go"
@@ -329,11 +328,8 @@ func ToPodSpecGen(s specgen.PodSpecGenerator, p *PodCreateOptions) (*specgen.Pod
if p.Net != nil {
s.NetNS = p.Net.Network
- s.StaticIP = p.Net.StaticIP
- // type cast to types.HardwareAddr
- s.StaticMAC = (*types.HardwareAddr)(p.Net.StaticMAC)
s.PortMappings = p.Net.PublishPorts
- s.CNINetworks = p.Net.CNINetworks
+ s.Networks = p.Net.Networks
s.NetworkOptions = p.Net.NetworkOptions
if p.Net.UseImageResolvConf {
s.NoManageResolvConf = true
diff --git a/pkg/domain/entities/types.go b/pkg/domain/entities/types.go
index e062b9442..0348c0af5 100644
--- a/pkg/domain/entities/types.go
+++ b/pkg/domain/entities/types.go
@@ -45,18 +45,16 @@ type NetFlags struct {
// NetOptions reflect the shared network options between
// pods and containers
type NetOptions struct {
- AddHosts []string `json:"hostadd,omitempty"`
- Aliases []string `json:"network_alias,omitempty"`
- CNINetworks []string `json:"cni_networks,omitempty"`
- UseImageResolvConf bool `json:"no_manage_resolv_conf,omitempty"`
- DNSOptions []string `json:"dns_option,omitempty"`
- DNSSearch []string `json:"dns_search,omitempty"`
- DNSServers []net.IP `json:"dns_server,omitempty"`
- Network specgen.Namespace `json:"netns,omitempty"`
- NoHosts bool `json:"no_manage_hosts,omitempty"`
- PublishPorts []types.PortMapping `json:"portmappings,omitempty"`
- StaticIP *net.IP `json:"static_ip,omitempty"`
- StaticMAC *net.HardwareAddr `json:"static_mac,omitempty"`
+ AddHosts []string `json:"hostadd,omitempty"`
+ Aliases []string `json:"network_alias,omitempty"`
+ Networks map[string]types.PerNetworkOptions `json:"networks,omitempty"`
+ UseImageResolvConf bool `json:"no_manage_resolv_conf,omitempty"`
+ DNSOptions []string `json:"dns_option,omitempty"`
+ DNSSearch []string `json:"dns_search,omitempty"`
+ DNSServers []net.IP `json:"dns_server,omitempty"`
+ Network specgen.Namespace `json:"netns,omitempty"`
+ NoHosts bool `json:"no_manage_hosts,omitempty"`
+ PublishPorts []types.PortMapping `json:"portmappings,omitempty"`
// NetworkOptions are additional options for each network
NetworkOptions map[string][]string `json:"network_options,omitempty"`
}
diff --git a/pkg/domain/infra/abi/play.go b/pkg/domain/infra/abi/play.go
index 4c024a3d8..b0b68567a 100644
--- a/pkg/domain/infra/abi/play.go
+++ b/pkg/domain/infra/abi/play.go
@@ -6,7 +6,6 @@ import (
"fmt"
"io"
"io/ioutil"
- "net"
"os"
"path/filepath"
"strconv"
@@ -190,44 +189,45 @@ func (ic *ContainerEngine) playKubePod(ctx context.Context, podName string, podY
}
}
- podOpt := entities.PodCreateOptions{Infra: true, Net: &entities.NetOptions{StaticIP: &net.IP{}, StaticMAC: &net.HardwareAddr{}, NoHosts: options.NoHosts}}
+ podOpt := entities.PodCreateOptions{Infra: true, Net: &entities.NetOptions{NoHosts: options.NoHosts}}
podOpt, err = kube.ToPodOpt(ctx, podName, podOpt, podYAML)
if err != nil {
return nil, err
}
if options.Network != "" {
- ns, cniNets, netOpts, err := specgen.ParseNetworkString(options.Network)
+ ns, networks, netOpts, err := specgen.ParseNetworkString(options.Network)
if err != nil {
return nil, err
}
- if (ns.IsBridge() && len(cniNets) == 0) || ns.IsHost() {
+ if (ns.IsBridge() && len(networks) == 0) || ns.IsHost() {
return nil, errors.Errorf("invalid value passed to --network: bridge or host networking must be configured in YAML")
}
podOpt.Net.Network = ns
- if len(cniNets) > 0 {
- podOpt.Net.CNINetworks = append(podOpt.Net.CNINetworks, cniNets...)
+ if len(networks) > 0 {
+ podOpt.Net.Networks = networks
}
if len(netOpts) > 0 {
podOpt.Net.NetworkOptions = netOpts
}
}
- if len(options.StaticIPs) > *ipIndex {
- podOpt.Net.StaticIP = &options.StaticIPs[*ipIndex]
- } else if len(options.StaticIPs) > 0 {
- // only warn if the user has set at least one ip
- logrus.Warn("No more static ips left using a random one")
- }
- if len(options.StaticMACs) > *ipIndex {
- podOpt.Net.StaticMAC = &options.StaticMACs[*ipIndex]
- } else if len(options.StaticIPs) > 0 {
- // only warn if the user has set at least one mac
- logrus.Warn("No more static macs left using a random one")
- }
- *ipIndex++
+ // FIXME This is very hard to support properly
+ // if len(options.StaticIPs) > *ipIndex {
+ // podOpt.Net.StaticIP = &options.StaticIPs[*ipIndex]
+ // } else if len(options.StaticIPs) > 0 {
+ // // only warn if the user has set at least one ip
+ // logrus.Warn("No more static ips left using a random one")
+ // }
+ // if len(options.StaticMACs) > *ipIndex {
+ // podOpt.Net.StaticMAC = &options.StaticMACs[*ipIndex]
+ // } else if len(options.StaticIPs) > 0 {
+ // // only warn if the user has set at least one mac
+ // logrus.Warn("No more static macs left using a random one")
+ // }
+ // *ipIndex++
p := specgen.NewPodSpecGenerator()
if err != nil {
diff --git a/pkg/specgen/container_validate.go b/pkg/specgen/container_validate.go
index caea51ea8..cae231f0e 100644
--- a/pkg/specgen/container_validate.go
+++ b/pkg/specgen/container_validate.go
@@ -29,25 +29,10 @@ func exclusiveOptions(opt1, opt2 string) error {
// Validate verifies that the given SpecGenerator is valid and satisfies required
// input for creating a container.
func (s *SpecGenerator) Validate() error {
- if rootless.IsRootless() && len(s.CNINetworks) == 0 {
- if s.StaticIP != nil || s.StaticIPv6 != nil {
- return ErrNoStaticIPRootless
- }
- if s.StaticMAC != nil {
- return ErrNoStaticMACRootless
- }
- }
-
// Containers being added to a pod cannot have certain network attributes
// associated with them because those should be on the infra container.
if len(s.Pod) > 0 && s.NetNS.NSMode == FromPod {
- if s.StaticIP != nil || s.StaticIPv6 != nil {
- return errors.Wrap(define.ErrNetworkOnPodContainer, "static ip addresses must be defined when the pod is created")
- }
- if s.StaticMAC != nil {
- return errors.Wrap(define.ErrNetworkOnPodContainer, "MAC addresses must be defined when the pod is created")
- }
- if len(s.CNINetworks) > 0 {
+ if len(s.Networks) > 0 {
return errors.Wrap(define.ErrNetworkOnPodContainer, "networks must be defined when the pod is created")
}
if len(s.PortMappings) > 0 || s.PublishExposedPorts {
diff --git a/pkg/specgen/generate/namespaces.go b/pkg/specgen/generate/namespaces.go
index ebdd2abd0..782156663 100644
--- a/pkg/specgen/generate/namespaces.go
+++ b/pkg/specgen/generate/namespaces.go
@@ -259,32 +259,28 @@ func namespaceOptions(ctx context.Context, s *specgen.SpecGenerator, rt *libpod.
if err != nil {
return nil, err
}
- if len(s.CNINetworks) == 0 {
- rtConfig, err := rt.GetConfigNoCopy()
- if err != nil {
- return nil, err
- }
- s.CNINetworks = append(s.CNINetworks, rtConfig.Network.DefaultNetwork)
- }
- networks := make(map[string]types.PerNetworkOptions, len(s.CNINetworks))
- for i, netName := range s.CNINetworks {
- opts := types.PerNetworkOptions{}
- opts.Aliases = s.Aliases[netName]
- if i == 0 {
- if s.StaticIP != nil {
- opts.StaticIPs = append(opts.StaticIPs, *s.StaticIP)
+ // if no network was specified use add the default
+ if len(s.Networks) == 0 {
+ // backwards config still allow the old cni networks list and convert to new format
+ if len(s.CNINetworks) > 0 {
+ logrus.Warn(`specgen "cni_networks" option is deprecated use the "networks" map instead`)
+ networks := make(map[string]types.PerNetworkOptions, len(s.CNINetworks))
+ for _, net := range s.CNINetworks {
+ networks[net] = types.PerNetworkOptions{}
}
- if s.StaticIPv6 != nil {
- opts.StaticIPs = append(opts.StaticIPs, *s.StaticIPv6)
+ s.Networks = networks
+ } else {
+ // no networks given but bridge is set so use default network
+ rtConfig, err := rt.GetConfigNoCopy()
+ if err != nil {
+ return nil, err
}
- if s.StaticMAC != nil {
- opts.StaticMAC = *s.StaticMAC
+ s.Networks = map[string]types.PerNetworkOptions{
+ rtConfig.Network.DefaultNetwork: {},
}
}
- networks[netName] = opts
}
-
- toReturn = append(toReturn, libpod.WithNetNS(portMappings, expose, postConfigureNetNS, "bridge", networks))
+ toReturn = append(toReturn, libpod.WithNetNS(portMappings, expose, postConfigureNetNS, "bridge", s.Networks))
}
if s.UseImageHosts {
diff --git a/pkg/specgen/generate/pod_create.go b/pkg/specgen/generate/pod_create.go
index 72dd249e7..0a797c571 100644
--- a/pkg/specgen/generate/pod_create.go
+++ b/pkg/specgen/generate/pod_create.go
@@ -218,9 +218,7 @@ func MapSpec(p *specgen.PodSpecGenerator) (*specgen.SpecGenerator, error) {
case specgen.Host:
logrus.Debugf("Pod will use host networking")
if len(p.InfraContainerSpec.PortMappings) > 0 ||
- p.InfraContainerSpec.StaticIP != nil ||
- p.InfraContainerSpec.StaticMAC != nil ||
- len(p.InfraContainerSpec.CNINetworks) > 0 ||
+ len(p.InfraContainerSpec.Networks) > 0 ||
p.InfraContainerSpec.NetNS.NSMode == specgen.NoNetwork {
return nil, errors.Wrapf(define.ErrInvalidArg, "cannot set host network if network-related configuration is specified")
}
@@ -234,9 +232,7 @@ func MapSpec(p *specgen.PodSpecGenerator) (*specgen.SpecGenerator, error) {
case specgen.NoNetwork:
logrus.Debugf("Pod will not use networking")
if len(p.InfraContainerSpec.PortMappings) > 0 ||
- p.InfraContainerSpec.StaticIP != nil ||
- p.InfraContainerSpec.StaticMAC != nil ||
- len(p.InfraContainerSpec.CNINetworks) > 0 ||
+ len(p.InfraContainerSpec.Networks) > 0 ||
p.InfraContainerSpec.NetNS.NSMode == "host" {
return nil, errors.Wrapf(define.ErrInvalidArg, "cannot disable pod network if network-related configuration is specified")
}
@@ -264,15 +260,13 @@ func MapSpec(p *specgen.PodSpecGenerator) (*specgen.SpecGenerator, error) {
if len(p.DNSSearch) > 0 {
p.InfraContainerSpec.DNSSearch = p.DNSSearch
}
- if p.StaticIP != nil {
- p.InfraContainerSpec.StaticIP = p.StaticIP
- }
- if p.StaticMAC != nil {
- p.InfraContainerSpec.StaticMAC = p.StaticMAC
- }
if p.NoManageResolvConf {
p.InfraContainerSpec.UseImageResolvConf = true
}
+ if len(p.Networks) > 0 {
+ p.InfraContainerSpec.Networks = p.Networks
+ }
+ // deprecated cni networks for api users
if len(p.CNINetworks) > 0 {
p.InfraContainerSpec.CNINetworks = p.CNINetworks
}
diff --git a/pkg/specgen/namespaces.go b/pkg/specgen/namespaces.go
index bb5385ef1..121e1ecf7 100644
--- a/pkg/specgen/namespaces.go
+++ b/pkg/specgen/namespaces.go
@@ -6,6 +6,7 @@ import (
"strings"
"github.com/containers/common/pkg/cgroups"
+ "github.com/containers/podman/v3/libpod/network/types"
"github.com/containers/podman/v3/pkg/rootless"
"github.com/containers/podman/v3/pkg/util"
"github.com/containers/storage"
@@ -271,9 +272,9 @@ func ParseUserNamespace(ns string) (Namespace, error) {
// ParseNetworkNamespace parses a network namespace specification in string
// form.
// Returns a namespace and (optionally) a list of CNI networks to join.
-func ParseNetworkNamespace(ns string, rootlessDefaultCNI bool) (Namespace, []string, error) {
+func ParseNetworkNamespace(ns string, rootlessDefaultCNI bool) (Namespace, map[string]types.PerNetworkOptions, error) {
toReturn := Namespace{}
- var cniNetworks []string
+ networks := make(map[string]types.PerNetworkOptions)
// Net defaults to Slirp on rootless
switch {
case ns == string(Slirp), strings.HasPrefix(ns, string(Slirp)+":"):
@@ -313,18 +314,22 @@ func ParseNetworkNamespace(ns string, rootlessDefaultCNI bool) (Namespace, []str
default:
// Assume we have been given a list of CNI networks.
// Which only works in bridge mode, so set that.
- cniNetworks = strings.Split(ns, ",")
+ networkList := strings.Split(ns, ",")
+ for _, net := range networkList {
+ networks[net] = types.PerNetworkOptions{}
+ }
+
toReturn.NSMode = Bridge
}
- return toReturn, cniNetworks, nil
+ return toReturn, networks, nil
}
-func ParseNetworkString(network string) (Namespace, []string, map[string][]string, error) {
+func ParseNetworkString(network string) (Namespace, map[string]types.PerNetworkOptions, map[string][]string, error) {
var networkOptions map[string][]string
parts := strings.SplitN(network, ":", 2)
- ns, cniNets, err := ParseNetworkNamespace(network, containerConfig.Containers.RootlessNetworking == "cni")
+ ns, nets, err := ParseNetworkNamespace(network, containerConfig.Containers.RootlessNetworking == "cni")
if err != nil {
return Namespace{}, nil, nil, err
}
@@ -332,9 +337,9 @@ func ParseNetworkString(network string) (Namespace, []string, map[string][]strin
if len(parts) > 1 {
networkOptions = make(map[string][]string)
networkOptions[parts[0]] = strings.Split(parts[1], ",")
- cniNets = nil
+ nets = nil
}
- return ns, cniNets, networkOptions, nil
+ return ns, nets, networkOptions, nil
}
func SetupUserNS(idmappings *storage.IDMappingOptions, userns Namespace, g *generate.Generator) (string, error) {
diff --git a/pkg/specgen/pod_validate.go b/pkg/specgen/pod_validate.go
index bca7b6dbe..32c1159c6 100644
--- a/pkg/specgen/pod_validate.go
+++ b/pkg/specgen/pod_validate.go
@@ -1,7 +1,6 @@
package specgen
import (
- "github.com/containers/podman/v3/pkg/rootless"
"github.com/containers/podman/v3/pkg/util"
"github.com/pkg/errors"
)
@@ -19,15 +18,6 @@ func exclusivePodOptions(opt1, opt2 string) error {
// Validate verifies the input is valid
func (p *PodSpecGenerator) Validate() error {
- if rootless.IsRootless() && len(p.CNINetworks) == 0 {
- if p.StaticIP != nil {
- return ErrNoStaticIPRootless
- }
- if p.StaticMAC != nil {
- return ErrNoStaticMACRootless
- }
- }
-
// PodBasicConfig
if p.NoInfra {
if len(p.InfraCommand) > 0 {
@@ -52,12 +42,6 @@ func (p *PodSpecGenerator) Validate() error {
if p.NetNS.NSMode != Default && p.NetNS.NSMode != "" {
return errors.New("NoInfra and network modes cannot be used together")
}
- if p.StaticIP != nil {
- return exclusivePodOptions("NoInfra", "StaticIP")
- }
- if p.StaticMAC != nil {
- return exclusivePodOptions("NoInfra", "StaticMAC")
- }
if len(p.DNSOption) > 0 {
return exclusivePodOptions("NoInfra", "DNSOption")
}
@@ -78,8 +62,8 @@ func (p *PodSpecGenerator) Validate() error {
if len(p.PortMappings) > 0 {
return errors.New("PortMappings can only be used with Bridge or slirp4netns networking")
}
- if len(p.CNINetworks) > 0 {
- return errors.New("CNINetworks can only be used with Bridge mode networking")
+ if len(p.Networks) > 0 {
+ return errors.New("Networks can only be used with Bridge mode networking")
}
}
if p.NoManageResolvConf {
diff --git a/pkg/specgen/podspecgen.go b/pkg/specgen/podspecgen.go
index 948fb990c..e59d11c0a 100644
--- a/pkg/specgen/podspecgen.go
+++ b/pkg/specgen/podspecgen.go
@@ -86,33 +86,26 @@ type PodNetworkConfig struct {
// Defaults to Bridge as root and Slirp as rootless.
// Mandatory.
NetNS Namespace `json:"netns,omitempty"`
- // StaticIP sets a static IP for the infra container. As the infra
- // container's network is used for the entire pod by default, this will
- // thus be a static IP for the whole pod.
- // Only available if NetNS is set to Bridge (the default for root).
- // As such, conflicts with NoInfra=true by proxy.
- // Optional.
- StaticIP *net.IP `json:"static_ip,omitempty"`
- // StaticMAC sets a static MAC for the infra container. As the infra
- // container's network is used for the entire pod by default, this will
- // thus be a static MAC for the entire pod.
- // Only available if NetNS is set to Bridge (the default for root).
- // As such, conflicts with NoInfra=true by proxy.
- // Optional.
- // swagger:strfmt string
- StaticMAC *types.HardwareAddr `json:"static_mac,omitempty"`
// PortMappings is a set of ports to map into the infra container.
// As, by default, containers share their network with the infra
// container, this will forward the ports to the entire pod.
// Only available if NetNS is set to Bridge or Slirp.
// Optional.
PortMappings []types.PortMapping `json:"portmappings,omitempty"`
- // CNINetworks is a list of CNI networks that the infra container will
- // join. As, by default, containers share their network with the infra
- // container, these networks will effectively be joined by the
- // entire pod.
- // Only available when NetNS is set to Bridge, the default for root.
- // Optional.
+ // Map of networks names ot ids the container should join to.
+ // You can request additional settings for each network, you can
+ // set network aliases, static ips, static mac address and the
+ // network interface name for this container on the specifc network.
+ // If the map is empty and the bridge network mode is set the container
+ // will be joined to the default network.
+ Networks map[string]types.PerNetworkOptions
+ // CNINetworks is a list of CNI networks to join the container to.
+ // If this list is empty, the default CNI network will be joined
+ // instead. If at least one entry is present, we will not join the
+ // default network (unless it is part of this list).
+ // Only available if NetNS is set to bridge.
+ // Optional.
+ // Deprecated: as of podman 4.0 use "Networks" instead.
CNINetworks []string `json:"cni_networks,omitempty"`
// NoManageResolvConf indicates that /etc/resolv.conf should not be
// managed by the pod. Instead, each container will create and manage a
diff --git a/pkg/specgen/specgen.go b/pkg/specgen/specgen.go
index 0e257ad4c..e650c1966 100644
--- a/pkg/specgen/specgen.go
+++ b/pkg/specgen/specgen.go
@@ -394,26 +394,10 @@ type ContainerCgroupConfig struct {
// ContainerNetworkConfig contains information on a container's network
// configuration.
type ContainerNetworkConfig struct {
- // Aliases are a list of network-scoped aliases for container
- // Optional
- Aliases map[string][]string `json:"aliases"`
// NetNS is the configuration to use for the container's network
// namespace.
// Mandatory.
NetNS Namespace `json:"netns,omitempty"`
- // StaticIP is the a IPv4 address of the container.
- // Only available if NetNS is set to Bridge.
- // Optional.
- StaticIP *net.IP `json:"static_ip,omitempty"`
- // StaticIPv6 is a static IPv6 address to set in the container.
- // Only available if NetNS is set to Bridge.
- // Optional.
- StaticIPv6 *net.IP `json:"static_ipv6,omitempty"`
- // StaticMAC is a static MAC address to set in the container.
- // Only available if NetNS is set to bridge.
- // Optional.
- // swagger:strfmt string
- StaticMAC *nettypes.HardwareAddr `json:"static_mac,omitempty"`
// PortBindings is a set of ports to map into the container.
// Only available if NetNS is set to bridge or slirp.
// Optional.
@@ -434,12 +418,20 @@ type ContainerNetworkConfig struct {
// PublishExposedPorts is set.
// Optional.
Expose map[uint16]string `json:"expose,omitempty"`
+ // Map of networks names ot ids the container should join to.
+ // You can request additional settings for each network, you can
+ // set network aliases, static ips, static mac address and the
+ // network interface name for this container on the specifc network.
+ // If the map is empty and the bridge network mode is set the container
+ // will be joined to the default network.
+ Networks map[string]nettypes.PerNetworkOptions
// CNINetworks is a list of CNI networks to join the container to.
// If this list is empty, the default CNI network will be joined
// instead. If at least one entry is present, we will not join the
// default network (unless it is part of this list).
// Only available if NetNS is set to bridge.
// Optional.
+ // Deprecated: as of podman 4.0 use "Networks" instead.
CNINetworks []string `json:"cni_networks,omitempty"`
// UseImageResolvConf indicates that resolv.conf should not be managed
// by Podman, but instead sourced from the image.
diff --git a/pkg/specgenutil/specgen.go b/pkg/specgenutil/specgen.go
index 5e4bd2f65..123c0073b 100644
--- a/pkg/specgenutil/specgen.go
+++ b/pkg/specgenutil/specgen.go
@@ -11,7 +11,6 @@ import (
"github.com/containers/image/v5/manifest"
"github.com/containers/podman/v3/cmd/podman/parse"
"github.com/containers/podman/v3/libpod/define"
- "github.com/containers/podman/v3/libpod/network/types"
ann "github.com/containers/podman/v3/pkg/annotations"
"github.com/containers/podman/v3/pkg/domain/entities"
envLib "github.com/containers/podman/v3/pkg/env"
@@ -434,19 +433,7 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *entities.ContainerCreateOptions
}
if c.Net != nil {
- s.CNINetworks = c.Net.CNINetworks
- }
-
- // Network aliases
- if c.Net != nil {
- if len(c.Net.Aliases) > 0 {
- // build a map of aliases where key=cniName
- aliases := make(map[string][]string, len(s.CNINetworks))
- for _, cniNetwork := range s.CNINetworks {
- aliases[cniNetwork] = c.Net.Aliases
- }
- s.Aliases = aliases
- }
+ s.Networks = c.Net.Networks
}
if c.Net != nil {
@@ -455,9 +442,6 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *entities.ContainerCreateOptions
s.DNSServers = c.Net.DNSServers
s.DNSSearch = c.Net.DNSSearch
s.DNSOptions = c.Net.DNSOptions
- s.StaticIP = c.Net.StaticIP
- // type cast to types.HardwareAddr
- s.StaticMAC = (*types.HardwareAddr)(c.Net.StaticMAC)
s.NetworkOptions = c.Net.NetworkOptions
s.UseImageHosts = c.Net.NoHosts
}