diff options
Diffstat (limited to 'libpod')
-rw-r--r-- | libpod/container_internal_linux.go | 23 | ||||
-rw-r--r-- | libpod/options.go | 96 | ||||
-rw-r--r-- | libpod/pod.go | 1 | ||||
-rw-r--r-- | libpod/runtime_pod_infra_linux.go | 74 |
4 files changed, 139 insertions, 55 deletions
diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go index 561dbdc1c..739026264 100644 --- a/libpod/container_internal_linux.go +++ b/libpod/container_internal_linux.go @@ -1114,22 +1114,17 @@ func (c *Container) makeBindMounts() error { return errors.Wrapf(err, "error fetching bind mounts from dependency %s of container %s", depCtr.ID(), c.ID()) } - if !c.config.UseImageResolvConf { - // The other container may not have a resolv.conf or /etc/hosts - // If it doesn't, don't copy them - resolvPath, exists := bindMounts["/etc/resolv.conf"] - if exists { - c.state.BindMounts["/etc/resolv.conf"] = resolvPath - } + // The other container may not have a resolv.conf or /etc/hosts + // If it doesn't, don't copy them + resolvPath, exists := bindMounts["/etc/resolv.conf"] + if !c.config.UseImageResolvConf && exists { + c.state.BindMounts["/etc/resolv.conf"] = resolvPath } - if !c.config.UseImageHosts { - // check if dependency container has an /etc/hosts file - hostsPath, exists := bindMounts["/etc/hosts"] - if !exists { - return errors.Errorf("error finding hosts file of dependency container %s for container %s", depCtr.ID(), c.ID()) - } - + // check if dependency container has an /etc/hosts file. + // It may not have one, so only use it if it does. + hostsPath, exists := bindMounts["/etc/hosts"] + if !c.config.UseImageHosts && exists { depCtr.lock.Lock() // generate a hosts file for the dependency container, // based on either its old hosts file, or the default, diff --git a/libpod/options.go b/libpod/options.go index 4957f822d..1fd588867 100644 --- a/libpod/options.go +++ b/libpod/options.go @@ -953,6 +953,16 @@ func WithNetNS(portMappings []ocicni.PortMapping, postConfigureNetNS bool, netmo return define.ErrCtrFinalized } + if rootless.IsRootless() { + if len(networks) > 0 { + return errors.Wrapf(define.ErrInvalidArg, "cannot use CNI networks with rootless containers") + } + } + + if len(networks) > 1 && (ctr.config.StaticIP != nil || ctr.config.StaticMAC != nil) { + return errors.Wrapf(define.ErrInvalidArg, "cannot join more than one CNI network if configuring a static IP or MAC address") + } + if ctr.config.NetNsCtr != "" { return errors.Wrapf(define.ErrInvalidArg, "container is already set to join another container's net ns, cannot create a new net ns") } @@ -962,12 +972,6 @@ func WithNetNS(portMappings []ocicni.PortMapping, postConfigureNetNS bool, netmo ctr.config.CreateNetNS = true ctr.config.PortMappings = portMappings - if rootless.IsRootless() { - if len(networks) > 0 { - return errors.New("cannot use CNI networks with rootless containers") - } - } - ctr.config.Networks = networks return nil @@ -1780,6 +1784,9 @@ func WithInfraContainerPorts(bindings []ocicni.PortMapping) PodCreateOption { if pod.valid { return define.ErrPodFinalized } + if !pod.config.InfraContainer.HasInfraContainer { + return errors.Wrapf(define.ErrInvalidArg, "cannot set pod ports as no infra container is being created") + } pod.config.InfraContainer.PortBindings = bindings return nil } @@ -1792,6 +1799,14 @@ func WithPodStaticIP(ip net.IP) PodCreateOption { return define.ErrPodFinalized } + if !pod.config.InfraContainer.HasInfraContainer { + return errors.Wrapf(define.ErrInvalidArg, "cannot set pod static IP as no infra container is being created") + } + + if pod.config.InfraContainer.HostNetwork { + return errors.Wrapf(define.ErrInvalidArg, "cannot set static IP if host network is specified") + } + if len(pod.config.InfraContainer.Networks) > 1 { return errors.Wrapf(define.ErrInvalidArg, "cannot set a static IP if joining more than 1 CNI network") } @@ -1809,6 +1824,14 @@ func WithPodStaticMAC(mac net.HardwareAddr) PodCreateOption { return define.ErrPodFinalized } + if !pod.config.InfraContainer.HasInfraContainer { + return errors.Wrapf(define.ErrInvalidArg, "cannot set pod static MAC as no infra container is being created") + } + + if pod.config.InfraContainer.HostNetwork { + return errors.Wrapf(define.ErrInvalidArg, "cannot set static MAC if host network is specified") + } + if len(pod.config.InfraContainer.Networks) > 1 { return errors.Wrapf(define.ErrInvalidArg, "cannot set a static MAC if joining more than 1 CNI network") } @@ -1827,6 +1850,10 @@ func WithPodUseImageResolvConf() PodCreateOption { return define.ErrPodFinalized } + if !pod.config.InfraContainer.HasInfraContainer { + return errors.Wrapf(define.ErrInvalidArg, "cannot configure pod DNS as no infra container is being created") + } + if len(pod.config.InfraContainer.DNSServer) != 0 || len(pod.config.InfraContainer.DNSSearch) != 0 || len(pod.config.InfraContainer.DNSOption) != 0 { @@ -1846,6 +1873,10 @@ func WithPodDNS(dnsServer []string) PodCreateOption { return define.ErrPodFinalized } + if !pod.config.InfraContainer.HasInfraContainer { + return errors.Wrapf(define.ErrInvalidArg, "cannot configure pod DNS as no infra container is being created") + } + if pod.config.InfraContainer.UseImageResolvConf { return errors.Wrapf(define.ErrInvalidArg, "cannot add DNS servers if pod will not create /etc/resolv.conf") } @@ -1863,6 +1894,10 @@ func WithPodDNSSearch(dnsSearch []string) PodCreateOption { return define.ErrPodFinalized } + if !pod.config.InfraContainer.HasInfraContainer { + return errors.Wrapf(define.ErrInvalidArg, "cannot configure pod DNS as no infra container is being created") + } + if pod.config.InfraContainer.UseImageResolvConf { return errors.Wrapf(define.ErrInvalidArg, "cannot add DNS search domains if pod will not create /etc/resolv.conf") } @@ -1880,6 +1915,10 @@ func WithPodDNSOption(dnsOption []string) PodCreateOption { return define.ErrPodFinalized } + if !pod.config.InfraContainer.HasInfraContainer { + return errors.Wrapf(define.ErrInvalidArg, "cannot configure pod DNS as no infra container is being created") + } + if pod.config.InfraContainer.UseImageResolvConf { return errors.Wrapf(define.ErrInvalidArg, "cannot add DNS options if pod will not create /etc/resolv.conf") } @@ -1898,6 +1937,10 @@ func WithPodUseImageHosts() PodCreateOption { return define.ErrPodFinalized } + if !pod.config.InfraContainer.HasInfraContainer { + return errors.Wrapf(define.ErrInvalidArg, "cannot configure pod hosts as no infra container is being created") + } + if len(pod.config.InfraContainer.HostAdd) != 0 { return errors.Wrapf(define.ErrInvalidArg, "not creating /etc/hosts conflicts with adding to the hosts file") } @@ -1915,6 +1958,10 @@ func WithPodHosts(hosts []string) PodCreateOption { return define.ErrPodFinalized } + if !pod.config.InfraContainer.HasInfraContainer { + return errors.Wrapf(define.ErrInvalidArg, "cannot configure pod hosts as no infra container is being created") + } + if pod.config.InfraContainer.UseImageHosts { return errors.Wrapf(define.ErrInvalidArg, "cannot add to /etc/hosts if container is using image hosts") } @@ -1932,8 +1979,45 @@ func WithPodNetworks(networks []string) PodCreateOption { return define.ErrPodFinalized } + if !pod.config.InfraContainer.HasInfraContainer { + return errors.Wrapf(define.ErrInvalidArg, "cannot configure pod CNI networks as no infra container is being created") + } + + if (pod.config.InfraContainer.StaticIP != nil || pod.config.InfraContainer.StaticMAC != nil) && + len(networks) > 1 { + return errors.Wrapf(define.ErrInvalidArg, "cannot join more than one CNI network if setting a static IP or MAC address") + } + + if pod.config.InfraContainer.HostNetwork { + return errors.Wrapf(define.ErrInvalidArg, "cannot join pod to CNI networks if host network is specified") + } + pod.config.InfraContainer.Networks = networks return nil } } + +// WithPodHostNetwork tells the pod to use the host's network namespace. +func WithPodHostNetwork() PodCreateOption { + return func(pod *Pod) error { + if pod.valid { + return define.ErrPodFinalized + } + + if !pod.config.InfraContainer.HasInfraContainer { + return errors.Wrapf(define.ErrInvalidArg, "cannot configure pod host networking as no infra container is being created") + } + + if len(pod.config.InfraContainer.PortBindings) > 0 || + pod.config.InfraContainer.StaticIP != nil || + pod.config.InfraContainer.StaticMAC != nil || + len(pod.config.InfraContainer.Networks) > 0 { + return errors.Wrapf(define.ErrInvalidArg, "cannot set host network if network-related configuration is specified") + } + + pod.config.InfraContainer.HostNetwork = true + + return nil + } +} diff --git a/libpod/pod.go b/libpod/pod.go index 4f85caf08..1b4c06c9d 100644 --- a/libpod/pod.go +++ b/libpod/pod.go @@ -99,6 +99,7 @@ type PodContainerInfo struct { // InfraContainerConfig is the configuration for the pod's infra container type InfraContainerConfig struct { HasInfraContainer bool `json:"makeInfraContainer"` + HostNetwork bool `json:"infraHostNetwork,omitempty"` PortBindings []ocicni.PortMapping `json:"infraPortBindings"` StaticIP net.IP `json:"staticIP,omitempty"` StaticMAC net.HardwareAddr `json:"staticMAC,omitempty"` diff --git a/libpod/runtime_pod_infra_linux.go b/libpod/runtime_pod_infra_linux.go index 1b1421ca8..a6cac2b72 100644 --- a/libpod/runtime_pod_infra_linux.go +++ b/libpod/runtime_pod_infra_linux.go @@ -37,6 +37,7 @@ func (r *Runtime) makeInfraContainer(ctx context.Context, p *Pod, imgName, imgID isRootless := rootless.IsRootless() entryCmd := []string{r.config.InfraCommand} + var options []CtrCreateOption // I've seen circumstances where config is being passed as nil. // Let's err on the side of safety and make sure it's safe to use. if config != nil { @@ -68,6 +69,44 @@ func (r *Runtime) makeInfraContainer(ctx context.Context, p *Pod, imgName, imgID g.AddProcessEnv(nameValSlice[0], nameValSlice[1]) } } + + // Since user namespace sharing is not implemented, we only need to check if it's rootless + if !p.config.InfraContainer.HostNetwork { + 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, p.config.InfraContainer.Networks)) + } else if err := g.RemoveLinuxNamespace(string(spec.NetworkNamespace)); err != nil { + return nil, errors.Wrapf(err, "error removing network namespace from pod %s infra container", p.ID()) + } + + 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)) + } } g.SetRootReadonly(true) @@ -87,46 +126,11 @@ func (r *Runtime) makeInfraContainer(ctx context.Context, p *Pod, imgName, imgID } containerName := p.ID()[:IDTruncLength] + "-infra" - var options []CtrCreateOption options = append(options, r.WithPod(p)) options = append(options, WithRootFSFromImage(imgID, imgName, false)) options = append(options, WithName(containerName)) options = append(options, withIsInfra()) - // Since user namespace sharing is not implemented, we only need to check if it's rootless - 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, 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...) } |