From 9ce6b64133bc37433efac391bcaf9234c3890fc5 Mon Sep 17 00:00:00 2001 From: Paul Holzinger Date: Tue, 7 Dec 2021 23:04:47 +0100 Subject: network db: add new strucutre to container create Make sure we create new containers in the db with the correct structure. Also remove some unneeded code for alias handling. We no longer need this functions. The specgen format has not been changed for now. Signed-off-by: Paul Holzinger --- libpod/options.go | 50 +------------------------------------------------- 1 file changed, 1 insertion(+), 49 deletions(-) (limited to 'libpod/options.go') diff --git a/libpod/options.go b/libpod/options.go index 8f2d5cb15..dbcc50741 100644 --- a/libpod/options.go +++ b/libpod/options.go @@ -1058,7 +1058,7 @@ func WithDependencyCtrs(ctrs []*Container) CtrCreateOption { // namespace with a minimal configuration. // An optional array of port mappings can be provided. // Conflicts with WithNetNSFrom(). -func WithNetNS(portMappings []nettypes.PortMapping, exposedPorts map[uint16][]string, postConfigureNetNS bool, netmode string, networks []string) CtrCreateOption { +func WithNetNS(portMappings []nettypes.PortMapping, exposedPorts map[uint16][]string, postConfigureNetNS bool, netmode string, networks map[string]nettypes.PerNetworkOptions) CtrCreateOption { return func(ctr *Container) error { if ctr.valid { return define.ErrCtrFinalized @@ -1076,23 +1076,6 @@ func WithNetNS(portMappings []nettypes.PortMapping, exposedPorts map[uint16][]st } } -// WithStaticIP indicates that the container should request a static IP from -// the CNI plugins. -// It cannot be set unless WithNetNS has already been passed. -// Further, it cannot be set if additional CNI networks to join have been -// specified. -func WithStaticIP(ip net.IP) CtrCreateOption { - return func(ctr *Container) error { - if ctr.valid { - return define.ErrCtrFinalized - } - - ctr.config.StaticIP = ip - - return nil - } -} - // WithNetworkOptions sets additional options for the networks. func WithNetworkOptions(options map[string][]string) CtrCreateOption { return func(ctr *Container) error { @@ -1106,23 +1089,6 @@ func WithNetworkOptions(options map[string][]string) CtrCreateOption { } } -// WithStaticMAC indicates that the container should request a static MAC from -// the CNI plugins. -// It cannot be set unless WithNetNS has already been passed. -// Further, it cannot be set if additional CNI networks to join have been -// specified. -func WithStaticMAC(mac nettypes.HardwareAddr) CtrCreateOption { - return func(ctr *Container) error { - if ctr.valid { - return define.ErrCtrFinalized - } - - ctr.config.StaticMAC = mac - - return nil - } -} - // WithLogDriver sets the log driver for the container func WithLogDriver(driver string) CtrCreateOption { return func(ctr *Container) error { @@ -1572,20 +1538,6 @@ func WithCreateWorkingDir() CtrCreateOption { } } -// WithNetworkAliases sets network aliases for the container. -// Accepts a map of network name to aliases. -func WithNetworkAliases(aliases map[string][]string) CtrCreateOption { - return func(ctr *Container) error { - if ctr.valid { - return define.ErrCtrFinalized - } - - ctr.config.NetworkAliases = aliases - - return nil - } -} - // Volume Creation Options // WithVolumeName sets the name of the volume. -- cgit v1.2.3-54-g00ecf From d072167fe2f75db9648bf1be4181b42e9b7db9a4 Mon Sep 17 00:00:00 2001 From: Paul Holzinger Date: Thu, 9 Dec 2021 15:59:54 +0100 Subject: Add new networks format to spegecen Add the new networks format to specgen. For api users cni_networks is still supported to make migration easier however the static ip and mac fields are removed. Signed-off-by: Paul Holzinger --- cmd/podman/common/create_opts.go | 70 +++++++++++++++++++----------------- cmd/podman/common/create_test.go | 2 +- cmd/podman/common/netflags.go | 74 ++++++++++++++++++++++++-------------- libpod/options.go | 3 ++ pkg/domain/entities/pods.go | 6 +--- pkg/domain/entities/types.go | 22 ++++++------ pkg/domain/infra/abi/play.go | 38 ++++++++++---------- pkg/specgen/container_validate.go | 17 +-------- pkg/specgen/generate/namespaces.go | 38 +++++++++----------- pkg/specgen/generate/pod_create.go | 18 ++++------ pkg/specgen/namespaces.go | 21 ++++++----- pkg/specgen/pod_validate.go | 20 ++--------- pkg/specgen/podspecgen.go | 35 ++++++++---------- pkg/specgen/specgen.go | 24 +++++-------- pkg/specgenutil/specgen.go | 18 +--------- 15 files changed, 181 insertions(+), 225 deletions(-) (limited to 'libpod/options.go') 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 } -- cgit v1.2.3-54-g00ecf