Add backend code for pod network options

This adds network-related options to the pod in the database. We
are going to add the CLI frontend in further patches.

In short, this should greatly improve the ability of pods to
configure networking, once the CLI parsing is added.

Signed-off-by: Matthew Heon <matthew.heon@pm.me>
This commit is contained in:
Matthew Heon 2020-02-03 11:17:32 -05:00 committed by Matthew Heon
parent 28eb296653
commit 07a8ab09e0
3 changed files with 191 additions and 4 deletions

View File

@ -1784,3 +1784,156 @@ func WithInfraContainerPorts(bindings []ocicni.PortMapping) PodCreateOption {
return nil
}
}
// WithPodStaticIP sets a static IP for the pod.
func WithPodStaticIP(ip net.IP) PodCreateOption {
return func(pod *Pod) error {
if pod.valid {
return define.ErrPodFinalized
}
if len(pod.config.InfraContainer.Networks) > 1 {
return errors.Wrapf(define.ErrInvalidArg, "cannot set a static IP if joining more than 1 CNI network")
}
pod.config.InfraContainer.StaticIP = ip
return nil
}
}
// WithPodStaticMAC sets a static MAC address for the pod.
func WithPodStaticMAC(mac net.HardwareAddr) PodCreateOption {
return func(pod *Pod) error {
if pod.valid {
return define.ErrPodFinalized
}
if len(pod.config.InfraContainer.Networks) > 1 {
return errors.Wrapf(define.ErrInvalidArg, "cannot set a static MAC if joining more than 1 CNI network")
}
pod.config.InfraContainer.StaticMAC = mac
return nil
}
}
// WithPodUseImageResolvConf sets a pod to use an image's resolv.conf and not
// create its own.
func WithPodUseImageResolvConf() PodCreateOption {
return func(pod *Pod) error {
if pod.valid {
return define.ErrPodFinalized
}
if len(pod.config.InfraContainer.DNSServer) != 0 ||
len(pod.config.InfraContainer.DNSSearch) != 0 ||
len(pod.config.InfraContainer.DNSOption) != 0 {
return errors.Wrapf(define.ErrInvalidArg, "requested use of image resolv.conf conflicts with already-configured DNS settings")
}
pod.config.InfraContainer.UseImageResolvConf = true
return nil
}
}
// WithPodDNS sets the DNS Servers for a pod.
func WithPodDNS(dnsServer []string) PodCreateOption {
return func(pod *Pod) error {
if pod.valid {
return define.ErrPodFinalized
}
if pod.config.InfraContainer.UseImageResolvConf {
return errors.Wrapf(define.ErrInvalidArg, "cannot add DNS servers if pod will not create /etc/resolv.conf")
}
pod.config.InfraContainer.DNSServer = dnsServer
return nil
}
}
// WithPodDNSSearch sets the DNS Search domains for a pod.
func WithPodDNSSearch(dnsSearch []string) PodCreateOption {
return func(pod *Pod) error {
if pod.valid {
return define.ErrPodFinalized
}
if pod.config.InfraContainer.UseImageResolvConf {
return errors.Wrapf(define.ErrInvalidArg, "cannot add DNS search domains if pod will not create /etc/resolv.conf")
}
pod.config.InfraContainer.DNSSearch = dnsSearch
return nil
}
}
// WithPodDNSOption sets DNS Options for a pod.
func WithPodDNSOption(dnsOption []string) PodCreateOption {
return func(pod *Pod) error {
if pod.valid {
return define.ErrPodFinalized
}
if pod.config.InfraContainer.UseImageResolvConf {
return errors.Wrapf(define.ErrInvalidArg, "cannot add DNS options if pod will not create /etc/resolv.conf")
}
pod.config.InfraContainer.DNSOption = dnsOption
return nil
}
}
// WithPodUseImageHosts tells the pod not to create /etc/hosts and instead to
// use the one provided by the image.
func WithPodUseImageHosts() PodCreateOption {
return func(pod *Pod) error {
if pod.valid {
return define.ErrPodFinalized
}
if len(pod.config.InfraContainer.HostAdd) != 0 {
return errors.Wrapf(define.ErrInvalidArg, "not creating /etc/hosts conflicts with adding to the hosts file")
}
pod.config.InfraContainer.UseImageHosts = true
return nil
}
}
// WithPodHosts adds additional entries to the pod's /etc/hosts
func WithPodHosts(hosts []string) PodCreateOption {
return func(pod *Pod) error {
if pod.valid {
return define.ErrPodFinalized
}
if pod.config.InfraContainer.UseImageHosts {
return errors.Wrapf(define.ErrInvalidArg, "cannot add to /etc/hosts if container is using image hosts")
}
pod.config.InfraContainer.HostAdd = hosts
return nil
}
}
// WithPodNetworks sets additional CNI networks for the pod to join.
func WithPodNetworks(networks []string) PodCreateOption {
return func(pod *Pod) error {
if pod.valid {
return define.ErrPodFinalized
}
pod.config.InfraContainer.Networks = networks
return nil
}
}

View File

@ -1,6 +1,7 @@
package libpod
import (
"net"
"time"
"github.com/containers/libpod/libpod/define"
@ -97,8 +98,17 @@ type PodContainerInfo struct {
// InfraContainerConfig is the configuration for the pod's infra container
type InfraContainerConfig struct {
HasInfraContainer bool `json:"makeInfraContainer"`
PortBindings []ocicni.PortMapping `json:"infraPortBindings"`
HasInfraContainer bool `json:"makeInfraContainer"`
PortBindings []ocicni.PortMapping `json:"infraPortBindings"`
StaticIP net.IP `json:"staticIP,omitempty"`
StaticMAC net.HardwareAddr `json:"staticMAC,omitempty"`
UseImageResolvConf bool `json:"useImageResolvConf,omitempty"`
DNSServer []string `json:"dnsServer,omitempty"`
DNSSearch []string `json:"dnsSearch,omitempty"`
DNSOption []string `json:"dnsOption,omitempty"`
UseImageHosts bool `json:"useImageHosts,omitempty"`
HostAdd []string `json:"hostsAdd,omitempty"`
Networks []string `json:"networks,omitempty"`
}
// ID retrieves the pod's ID

View File

@ -94,14 +94,38 @@ func (r *Runtime) makeInfraContainer(ctx context.Context, p *Pod, imgName, imgID
options = append(options, withIsInfra())
// Since user namespace sharing is not implemented, we only need to check if it's rootless
networks := make([]string, 0)
netmode := "bridge"
if isRootless {
netmode = "slirp4netns"
}
// PostConfigureNetNS should not be set since user namespace sharing is not implemented
// and rootless networking no longer supports post configuration setup
options = append(options, WithNetNS(p.config.InfraContainer.PortBindings, false, netmode, networks))
options = append(options, WithNetNS(p.config.InfraContainer.PortBindings, false, netmode, p.config.InfraContainer.Networks))
if p.config.InfraContainer.StaticIP != nil {
options = append(options, WithStaticIP(p.config.InfraContainer.StaticIP))
}
if p.config.InfraContainer.StaticMAC != nil {
options = append(options, WithStaticMAC(p.config.InfraContainer.StaticMAC))
}
if p.config.InfraContainer.UseImageResolvConf {
options = append(options, WithUseImageResolvConf())
}
if len(p.config.InfraContainer.DNSServer) > 0 {
options = append(options, WithDNS(p.config.InfraContainer.DNSServer))
}
if len(p.config.InfraContainer.DNSSearch) > 0 {
options = append(options, WithDNSSearch(p.config.InfraContainer.DNSSearch))
}
if len(p.config.InfraContainer.DNSOption) > 0 {
options = append(options, WithDNSOption(p.config.InfraContainer.DNSOption))
}
if p.config.InfraContainer.UseImageHosts {
options = append(options, WithUseImageHosts())
}
if len(p.config.InfraContainer.HostAdd) > 0 {
options = append(options, WithHosts(p.config.InfraContainer.HostAdd))
}
return r.newContainer(ctx, g.Config, options...)
}