diff options
Diffstat (limited to 'libpod')
-rw-r--r-- | libpod/container.go | 4 | ||||
-rw-r--r-- | libpod/container_internal.go | 6 | ||||
-rw-r--r-- | libpod/container_internal_linux.go | 4 | ||||
-rw-r--r-- | libpod/define/pod_inspect.go | 2 | ||||
-rw-r--r-- | libpod/info.go | 29 | ||||
-rw-r--r-- | libpod/options.go | 24 | ||||
-rw-r--r-- | libpod/pod.go | 1 | ||||
-rw-r--r-- | libpod/pod_api.go | 1 | ||||
-rw-r--r-- | libpod/runtime_pod_infra_linux.go | 37 |
9 files changed, 85 insertions, 23 deletions
diff --git a/libpod/container.go b/libpod/container.go index f3f4b27b7..d5d5ef1a5 100644 --- a/libpod/container.go +++ b/libpod/container.go @@ -1020,8 +1020,8 @@ func (c *Container) RWSize() (int64, error) { } // IDMappings returns the UID/GID mapping used for the container -func (c *Container) IDMappings() (storage.IDMappingOptions, error) { - return c.config.IDMappings, nil +func (c *Container) IDMappings() storage.IDMappingOptions { + return c.config.IDMappings } // RootUID returns the root user mapping from container diff --git a/libpod/container_internal.go b/libpod/container_internal.go index 8ffcccf4c..3f7a4807d 100644 --- a/libpod/container_internal.go +++ b/libpod/container_internal.go @@ -367,6 +367,12 @@ func (c *Container) setupStorageMapping(dest, from *storage.IDMappingOptions) { return } *dest = *from + // If we are creating a container inside a pod, we always want to inherit the + // userns settings from the infra container. So clear the auto userns settings + // so that we don't request storage for a new uid/gid map. + if c.PodID() != "" && !c.IsInfra() { + dest.AutoUserNs = false + } if dest.AutoUserNs { overrides := c.getUserOverrides() dest.AutoUserNsOpts.PasswdFile = overrides.ContainerEtcPasswdPath diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go index f30f622ac..6d2f7bddc 100644 --- a/libpod/container_internal_linux.go +++ b/libpod/container_internal_linux.go @@ -659,7 +659,7 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) { } } - if c.config.IDMappings.AutoUserNs { + if c.config.UserNsCtr == "" && c.config.IDMappings.AutoUserNs { if err := g.AddOrReplaceLinuxNamespace(string(spec.UserNamespace), ""); err != nil { return nil, err } @@ -1884,7 +1884,7 @@ func (c *Container) generateResolvConf() (string, error) { return "", err } - return filepath.Join(c.state.RunDir, "resolv.conf"), nil + return destPath, nil } // generateHosts creates a containers hosts file diff --git a/libpod/define/pod_inspect.go b/libpod/define/pod_inspect.go index a17304875..f91fd198d 100644 --- a/libpod/define/pod_inspect.go +++ b/libpod/define/pod_inspect.go @@ -105,6 +105,8 @@ type InspectPodInfraConfig struct { CPUSetCPUs string `json:"cpuset_cpus,omitempty"` // Pid is the PID namespace mode of the pod's infra container PidNS string `json:"pid_ns,omitempty"` + // UserNS is the usernamespace that all the containers in the pod will join. + UserNS string `json:"userns,omitempty"` } // InspectPodContainerInfo contains information on a container in a pod. diff --git a/libpod/info.go b/libpod/info.go index cdc73780f..2b48ea590 100644 --- a/libpod/info.go +++ b/libpod/info.go @@ -141,19 +141,24 @@ func (r *Runtime) hostInfo() (*define.HostInfo, error) { } info.CGroupsVersion = cgroupVersion - if rootless.IsRootless() { - if path, err := exec.LookPath("slirp4netns"); err == nil { - version, err := programVersion(path) - if err != nil { - logrus.Warnf("Failed to retrieve program version for %s: %v", path, err) - } - program := define.SlirpInfo{ - Executable: path, - Package: packageVersion(path), - Version: version, - } - info.Slirp4NetNS = program + slirp4netnsPath := r.config.Engine.NetworkCmdPath + if slirp4netnsPath == "" { + slirp4netnsPath, _ = exec.LookPath("slirp4netns") + } + if slirp4netnsPath != "" { + version, err := programVersion(slirp4netnsPath) + if err != nil { + logrus.Warnf("Failed to retrieve program version for %s: %v", slirp4netnsPath, err) + } + program := define.SlirpInfo{ + Executable: slirp4netnsPath, + Package: packageVersion(slirp4netnsPath), + Version: version, } + info.Slirp4NetNS = program + } + + if rootless.IsRootless() { uidmappings, err := rootless.ReadMappingsProc("/proc/self/uid_map") if err != nil { return nil, errors.Wrapf(err, "error reading uid mappings") diff --git a/libpod/options.go b/libpod/options.go index 071b085e7..b94ef88ba 100644 --- a/libpod/options.go +++ b/libpod/options.go @@ -956,8 +956,9 @@ func WithUserNSFrom(nsCtr *Container) CtrCreateOption { } ctr.config.UserNsCtr = nsCtr.ID() - ctr.config.IDMappings = nsCtr.config.IDMappings - + if err := JSONDeepCopy(nsCtr.IDMappings(), &ctr.config.IDMappings); err != nil { + return err + } g := generate.Generator{Config: ctr.config.Spec} g.ClearLinuxUIDMappings() @@ -968,7 +969,6 @@ func WithUserNSFrom(nsCtr *Container) CtrCreateOption { for _, gidmap := range nsCtr.config.IDMappings.GIDMap { g.AddLinuxGIDMapping(uint32(gidmap.HostID), uint32(gidmap.ContainerID), uint32(gidmap.Size)) } - ctr.config.IDMappings = nsCtr.config.IDMappings return nil } } @@ -2423,6 +2423,24 @@ func WithVolatile() CtrCreateOption { } ctr.config.Volatile = true + + return nil + } +} + +// WithPodUserns sets the userns for the infra container in a pod. +func WithPodUserns(userns specgen.Namespace) 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 userns as no infra container is being created") + } + + pod.config.InfraContainer.Userns = userns + return nil } } diff --git a/libpod/pod.go b/libpod/pod.go index 0fef7f6f3..7df15df7b 100644 --- a/libpod/pod.go +++ b/libpod/pod.go @@ -117,6 +117,7 @@ type InfraContainerConfig struct { Slirp4netns bool `json:"slirp4netns,omitempty"` NetworkOptions map[string][]string `json:"network_options,omitempty"` ResourceLimits *specs.LinuxResources `json:"resource_limits,omitempty"` + Userns specgen.Namespace `json:"userns,omitempty"` } // ID retrieves the pod's ID diff --git a/libpod/pod_api.go b/libpod/pod_api.go index 90d67dbb0..6fea2dfd8 100644 --- a/libpod/pod_api.go +++ b/libpod/pod_api.go @@ -593,6 +593,7 @@ func (p *Pod) Inspect() (*define.InspectPodData, error) { infraConfig.CPUQuota = p.CPUQuota() infraConfig.CPUSetCPUs = p.ResourceLim().CPU.Cpus infraConfig.PidNS = p.PidMode() + infraConfig.UserNS = p.config.InfraContainer.Userns.String() if len(p.config.InfraContainer.DNSServer) > 0 { infraConfig.DNSServer = make([]string, 0, len(p.config.InfraContainer.DNSServer)) diff --git a/libpod/runtime_pod_infra_linux.go b/libpod/runtime_pod_infra_linux.go index d4f861118..49213032e 100644 --- a/libpod/runtime_pod_infra_linux.go +++ b/libpod/runtime_pod_infra_linux.go @@ -8,7 +8,9 @@ import ( "github.com/containers/common/pkg/config" "github.com/containers/podman/v3/libpod/define" + "github.com/containers/podman/v3/pkg/namespaces" "github.com/containers/podman/v3/pkg/rootless" + "github.com/containers/podman/v3/pkg/specgen" "github.com/containers/podman/v3/pkg/util" v1 "github.com/opencontainers/image-spec/specs-go/v1" spec "github.com/opencontainers/runtime-spec/specs-go" @@ -110,9 +112,7 @@ func (r *Runtime) makeInfraContainer(ctx context.Context, p *Pod, imgName, rawIm options = append(options, WithNetworkOptions(p.config.InfraContainer.NetworkOptions)) } } - // 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)) + options = append(options, WithNetNS(p.config.InfraContainer.PortBindings, !p.config.InfraContainer.Userns.IsHost(), netmode, p.config.InfraContainer.Networks)) } // For each option in InfraContainerConfig - if set, pass into @@ -158,11 +158,39 @@ func (r *Runtime) makeInfraContainer(ctx context.Context, p *Pod, imgName, rawIm g.Config.Linux.Namespaces = newNS } } + + for _, ctl := range r.config.Containers.DefaultSysctls { + sysctl := strings.SplitN(ctl, "=", 2) + if len(sysctl) < 2 { + return nil, errors.Errorf("invalid default sysctl %s", ctl) + } + + // Ignore net sysctls if --net=host + if p.config.InfraContainer.HostNetwork && strings.HasPrefix(sysctl[0], "net.") { + logrus.Infof("Sysctl %s=%s ignored in containers.conf, since Network Namespace set to host", sysctl[0], sysctl[1]) + continue + } + + g.AddLinuxSysctl(sysctl[0], sysctl[1]) + } + g.SetRootReadonly(true) g.SetProcessArgs(infraCtrCommand) logrus.Debugf("Using %q as infra container command", infraCtrCommand) + mapopt, err := util.ParseIDMapping(namespaces.UsernsMode(p.config.InfraContainer.Userns.String()), []string{}, []string{}, "", "") + if err != nil { + return nil, err + } + user, err := specgen.SetupUserNS(mapopt, p.config.InfraContainer.Userns, &g) + if err != nil { + return nil, err + } + if user != "" { + options = append(options, WithUser(user)) + } + g.RemoveMount("/dev/shm") if isRootless { g.RemoveMount("/dev/pts") @@ -210,14 +238,15 @@ func (r *Runtime) makeInfraContainer(ctx context.Context, p *Pod, imgName, rawIm options = append(options, WithRootFSFromImage(imgID, imgName, rawImageName)) options = append(options, WithName(containerName)) options = append(options, withIsInfra()) + options = append(options, WithIDMappings(*mapopt)) if len(p.config.InfraContainer.ConmonPidFile) > 0 { options = append(options, WithConmonPidFile(p.config.InfraContainer.ConmonPidFile)) } newRes := new(spec.LinuxResources) newRes.CPU = new(spec.LinuxCPU) newRes.CPU = p.ResourceLim().CPU - g.Config.Linux.Resources.CPU = newRes.CPU + return r.newContainer(ctx, g.Config, options...) } |