diff options
Diffstat (limited to 'pkg/specgen/generate')
-rw-r--r-- | pkg/specgen/generate/config_linux.go | 3 | ||||
-rw-r--r-- | pkg/specgen/generate/container.go | 30 | ||||
-rw-r--r-- | pkg/specgen/generate/kube/kube.go | 21 | ||||
-rw-r--r-- | pkg/specgen/generate/kube/volume.go | 2 | ||||
-rw-r--r-- | pkg/specgen/generate/namespaces.go | 7 | ||||
-rw-r--r-- | pkg/specgen/generate/oci.go | 41 | ||||
-rw-r--r-- | pkg/specgen/generate/security.go | 15 | ||||
-rw-r--r-- | pkg/specgen/generate/storage.go | 8 | ||||
-rw-r--r-- | pkg/specgen/generate/validate.go | 2 |
9 files changed, 65 insertions, 64 deletions
diff --git a/pkg/specgen/generate/config_linux.go b/pkg/specgen/generate/config_linux.go index e0b039fb7..1290a8eb6 100644 --- a/pkg/specgen/generate/config_linux.go +++ b/pkg/specgen/generate/config_linux.go @@ -21,9 +21,6 @@ var ( errNotADevice = errors.New("not a device node") ) -func u32Ptr(i int64) *uint32 { u := uint32(i); return &u } -func fmPtr(i int64) *os.FileMode { fm := os.FileMode(i); return &fm } - func addPrivilegedDevices(g *generate.Generator) error { hostDevices, err := getDevices("/dev") if err != nil { diff --git a/pkg/specgen/generate/container.go b/pkg/specgen/generate/container.go index 42fea0277..2feb1d3b2 100644 --- a/pkg/specgen/generate/container.go +++ b/pkg/specgen/generate/container.go @@ -100,15 +100,9 @@ func CompleteSpec(ctx context.Context, r *libpod.Runtime, s *specgen.SpecGenerat if err != nil { return nil, err } - // First transform the os env into a map. We need it for the labels later in - // any case. - osEnv, err := envLib.ParseSlice(os.Environ()) - if err != nil { - return nil, errors.Wrap(err, "error parsing host environment variables") - } // Get Default Environment from containers.conf - defaultEnvs, err := envLib.ParseSlice(rtc.GetDefaultEnv()) + defaultEnvs, err := envLib.ParseSlice(rtc.GetDefaultEnvEx(s.EnvHost, s.HTTPProxy)) if err != nil { return nil, errors.Wrap(err, "error parsing fields in containers.conf") } @@ -133,6 +127,12 @@ func CompleteSpec(ctx context.Context, r *libpod.Runtime, s *specgen.SpecGenerat defaultEnvs = envLib.Join(defaultEnvs, envs) } + // First transform the os env into a map. We need it for the labels later in + // any case. + osEnv, err := envLib.ParseSlice(os.Environ()) + if err != nil { + return nil, errors.Wrap(err, "error parsing host environment variables") + } // Caller Specified defaults if s.EnvHost { defaultEnvs = envLib.Join(defaultEnvs, osEnv) @@ -282,8 +282,8 @@ func finishThrottleDevices(s *specgen.SpecGenerator) error { if err := unix.Stat(k, &statT); err != nil { return err } - v.Major = (int64(unix.Major(statT.Rdev))) - v.Minor = (int64(unix.Minor(statT.Rdev))) + v.Major = (int64(unix.Major(uint64(statT.Rdev)))) + v.Minor = (int64(unix.Minor(uint64(statT.Rdev)))) s.ResourceLimits.BlockIO.ThrottleReadBpsDevice = append(s.ResourceLimits.BlockIO.ThrottleReadBpsDevice, v) } } @@ -293,8 +293,8 @@ func finishThrottleDevices(s *specgen.SpecGenerator) error { if err := unix.Stat(k, &statT); err != nil { return err } - v.Major = (int64(unix.Major(statT.Rdev))) - v.Minor = (int64(unix.Minor(statT.Rdev))) + v.Major = (int64(unix.Major(uint64(statT.Rdev)))) + v.Minor = (int64(unix.Minor(uint64(statT.Rdev)))) s.ResourceLimits.BlockIO.ThrottleWriteBpsDevice = append(s.ResourceLimits.BlockIO.ThrottleWriteBpsDevice, v) } } @@ -304,8 +304,8 @@ func finishThrottleDevices(s *specgen.SpecGenerator) error { if err := unix.Stat(k, &statT); err != nil { return err } - v.Major = (int64(unix.Major(statT.Rdev))) - v.Minor = (int64(unix.Minor(statT.Rdev))) + v.Major = (int64(unix.Major(uint64(statT.Rdev)))) + v.Minor = (int64(unix.Minor(uint64(statT.Rdev)))) s.ResourceLimits.BlockIO.ThrottleReadIOPSDevice = append(s.ResourceLimits.BlockIO.ThrottleReadIOPSDevice, v) } } @@ -315,8 +315,8 @@ func finishThrottleDevices(s *specgen.SpecGenerator) error { if err := unix.Stat(k, &statT); err != nil { return err } - v.Major = (int64(unix.Major(statT.Rdev))) - v.Minor = (int64(unix.Minor(statT.Rdev))) + v.Major = (int64(unix.Major(uint64(statT.Rdev)))) + v.Minor = (int64(unix.Minor(uint64(statT.Rdev)))) s.ResourceLimits.BlockIO.ThrottleWriteIOPSDevice = append(s.ResourceLimits.BlockIO.ThrottleWriteIOPSDevice, v) } } diff --git a/pkg/specgen/generate/kube/kube.go b/pkg/specgen/generate/kube/kube.go index e5b09dcd8..e39a700eb 100644 --- a/pkg/specgen/generate/kube/kube.go +++ b/pkg/specgen/generate/kube/kube.go @@ -5,7 +5,7 @@ import ( "fmt" "strings" - "github.com/containers/buildah/pkg/parse" + "github.com/containers/common/pkg/parse" "github.com/containers/podman/v2/libpod/image" ann "github.com/containers/podman/v2/pkg/annotations" "github.com/containers/podman/v2/pkg/specgen" @@ -129,24 +129,20 @@ func ToSpecGen(ctx context.Context, opts *CtrSpecGenOptions) (*specgen.SpecGener // TODO: We don't understand why specgen does not take of this, but // integration tests clearly pointed out that it was required. - s.Command = []string{} imageData, err := opts.Image.Inspect(ctx) if err != nil { return nil, err } s.WorkDir = "/" - // We will use "Docker field name" internally here to avoid confusion - // and reference the "Kubernetes field name" when referencing the YAML - // ref: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#notes - entrypoint := []string{} - cmd := []string{} + // Entrypoint/Command handling is based off of + // https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#notes if imageData != nil && imageData.Config != nil { if imageData.Config.WorkingDir != "" { s.WorkDir = imageData.Config.WorkingDir } // Pull entrypoint and cmd from image - entrypoint = imageData.Config.Entrypoint - cmd = imageData.Config.Cmd + s.Entrypoint = imageData.Config.Entrypoint + s.Command = imageData.Config.Cmd s.Labels = imageData.Config.Labels if len(imageData.Config.StopSignal) > 0 { stopSignal, err := util.ParseSignal(imageData.Config.StopSignal) @@ -158,16 +154,15 @@ func ToSpecGen(ctx context.Context, opts *CtrSpecGenOptions) (*specgen.SpecGener } // If only the yaml.Command is specified, set it as the entrypoint and drop the image Cmd if len(opts.Container.Command) != 0 { - entrypoint = opts.Container.Command - cmd = []string{} + s.Entrypoint = opts.Container.Command + s.Command = []string{} } // Only override the cmd field if yaml.Args is specified // Keep the image entrypoint, or the yaml.command if specified if len(opts.Container.Args) != 0 { - cmd = opts.Container.Args + s.Command = opts.Container.Args } - s.Command = append(entrypoint, cmd...) // FIXME, // we are currently ignoring imageData.Config.ExposedPorts if opts.Container.WorkingDir != "" { diff --git a/pkg/specgen/generate/kube/volume.go b/pkg/specgen/generate/kube/volume.go index bb8edabb7..f5687f60d 100644 --- a/pkg/specgen/generate/kube/volume.go +++ b/pkg/specgen/generate/kube/volume.go @@ -3,7 +3,7 @@ package kube import ( "os" - "github.com/containers/buildah/pkg/parse" + "github.com/containers/common/pkg/parse" "github.com/containers/podman/v2/libpod" "github.com/pkg/errors" "github.com/sirupsen/logrus" diff --git a/pkg/specgen/generate/namespaces.go b/pkg/specgen/generate/namespaces.go index 036c7b7a1..f66ad6101 100644 --- a/pkg/specgen/generate/namespaces.go +++ b/pkg/specgen/generate/namespaces.go @@ -236,6 +236,9 @@ func namespaceOptions(ctx context.Context, s *specgen.SpecGenerator, rt *libpod. case specgen.Private: fallthrough case specgen.Bridge: + if postConfigureNetNS && rootless.IsRootless() { + return nil, errors.New("CNI networks not supported with user namespaces") + } portMappings, err := createPortMappings(ctx, s, img) if err != nil { return nil, err @@ -364,7 +367,9 @@ func specConfigureNamespaces(s *specgen.SpecGenerator, g *generate.Generator, rt // namespaces? g.SetHostname(hostname) } - g.AddProcessEnv("HOSTNAME", hostname) + if _, ok := s.Env["HOSTNAME"]; !ok && s.Hostname != "" { + g.AddProcessEnv("HOSTNAME", hostname) + } // User switch s.UserNS.NSMode { diff --git a/pkg/specgen/generate/oci.go b/pkg/specgen/generate/oci.go index ba68de6fd..e62131244 100644 --- a/pkg/specgen/generate/oci.go +++ b/pkg/specgen/generate/oci.go @@ -110,7 +110,7 @@ func makeCommand(ctx context.Context, s *specgen.SpecGenerator, img *image.Image // Only use image command if the user did not manually set an // entrypoint. command := s.Command - if (command == nil || len(command) == 0) && img != nil && (s.Entrypoint == nil || len(s.Entrypoint) == 0) { + if len(command) == 0 && img != nil && len(s.Entrypoint) == 0 { newCmd, err := img.Cmd(ctx) if err != nil { return nil, err @@ -138,10 +138,23 @@ func makeCommand(ctx context.Context, s *specgen.SpecGenerator, img *image.Image return finalCommand, nil } +// canMountSys is a best-effort heuristic to detect whether mounting a new sysfs is permitted in the container +func canMountSys(isRootless, isNewUserns bool, s *specgen.SpecGenerator) bool { + if s.NetNS.IsHost() && (isRootless || isNewUserns) { + return false + } + if isNewUserns { + switch s.NetNS.NSMode { + case specgen.Slirp, specgen.Private, specgen.NoNetwork, specgen.Bridge: + return true + default: + return false + } + } + return true +} + func SpecGenToOCI(ctx context.Context, s *specgen.SpecGenerator, rt *libpod.Runtime, rtc *config.Config, newImage *image.Image, mounts []spec.Mount, pod *libpod.Pod, finalCmd []string) (*spec.Spec, error) { - var ( - inUserNS bool - ) cgroupPerm := "ro" g, err := generate.New("linux") if err != nil { @@ -151,23 +164,11 @@ func SpecGenToOCI(ctx context.Context, s *specgen.SpecGenerator, rt *libpod.Runt g.RemoveMount("/dev/shm") g.HostSpecific = true addCgroup := true - canMountSys := true isRootless := rootless.IsRootless() - if isRootless { - inUserNS = true - } - if !s.UserNS.IsHost() { - if s.UserNS.IsContainer() || s.UserNS.IsPath() { - inUserNS = true - } - if s.UserNS.IsPrivate() { - inUserNS = true - } - } - if inUserNS && s.NetNS.NSMode != specgen.NoNetwork { - canMountSys = false - } + isNewUserns := s.UserNS.IsContainer() || s.UserNS.IsPath() || s.UserNS.IsPrivate() + + canMountSys := canMountSys(isRootless, isNewUserns, s) if s.Privileged && canMountSys { cgroupPerm = "rw" @@ -232,6 +233,8 @@ func SpecGenToOCI(ctx context.Context, s *specgen.SpecGenerator, rt *libpod.Runt g.AddMount(devPts) } + inUserNS := isRootless || isNewUserns + if inUserNS && s.IpcNS.IsHost() { g.RemoveMount("/dev/mqueue") devMqueue := spec.Mount{ diff --git a/pkg/specgen/generate/security.go b/pkg/specgen/generate/security.go index 0c97dc496..390b19beb 100644 --- a/pkg/specgen/generate/security.go +++ b/pkg/specgen/generate/security.go @@ -133,13 +133,13 @@ func securityConfigureGenerator(s *specgen.SpecGenerator, g *generate.Generator, configSpec := g.Config configSpec.Process.Capabilities.Ambient = []string{} configSpec.Process.Capabilities.Bounding = caplist - configSpec.Process.Capabilities.Inheritable = caplist user := strings.Split(s.User, ":")[0] if (user == "" && s.UserNS.NSMode != specgen.KeepID) || user == "root" || user == "0" { configSpec.Process.Capabilities.Effective = caplist configSpec.Process.Capabilities.Permitted = caplist + configSpec.Process.Capabilities.Inheritable = caplist } else { userCaps, err := capabilities.MergeCapabilities(nil, s.CapAdd, nil) if err != nil { @@ -147,6 +147,7 @@ func securityConfigureGenerator(s *specgen.SpecGenerator, g *generate.Generator, } configSpec.Process.Capabilities.Effective = userCaps configSpec.Process.Capabilities.Permitted = userCaps + configSpec.Process.Capabilities.Inheritable = userCaps // Ambient capabilities were added to Linux 4.3. Set ambient // capabilities only when the kernel supports them. @@ -172,12 +173,16 @@ func securityConfigureGenerator(s *specgen.SpecGenerator, g *generate.Generator, // Clear default Seccomp profile from Generator for unconfined containers // and privileged containers which do not specify a seccomp profile. - if s.SeccompProfilePath == "unconfined" || (s.Privileged && (s.SeccompProfilePath == config.SeccompOverridePath || s.SeccompProfilePath == config.SeccompDefaultPath)) { + if s.SeccompProfilePath == "unconfined" || (s.Privileged && (s.SeccompProfilePath == "" || s.SeccompProfilePath == config.SeccompOverridePath || s.SeccompProfilePath == config.SeccompDefaultPath)) { configSpec.Linux.Seccomp = nil } g.SetRootReadonly(s.ReadOnlyFilesystem) + noUseIPC := s.IpcNS.NSMode == specgen.FromContainer || s.IpcNS.NSMode == specgen.FromPod || s.IpcNS.NSMode == specgen.Host + noUseNet := s.NetNS.NSMode == specgen.FromContainer || s.NetNS.NSMode == specgen.FromPod || s.NetNS.NSMode == specgen.Host + noUseUTS := s.UtsNS.NSMode == specgen.FromContainer || s.UtsNS.NSMode == specgen.FromPod || s.UtsNS.NSMode == specgen.Host + // Add default sysctls defaultSysctls, err := util.ValidateSysctls(rtc.Sysctls()) if err != nil { @@ -186,20 +191,20 @@ func securityConfigureGenerator(s *specgen.SpecGenerator, g *generate.Generator, for sysctlKey, sysctlVal := range defaultSysctls { // Ignore mqueue sysctls if --ipc=host - if s.IpcNS.IsHost() && strings.HasPrefix(sysctlKey, "fs.mqueue.") { + if noUseIPC && strings.HasPrefix(sysctlKey, "fs.mqueue.") { logrus.Infof("Sysctl %s=%s ignored in containers.conf, since IPC Namespace set to host", sysctlKey, sysctlVal) continue } // Ignore net sysctls if --net=host - if s.NetNS.IsHost() && strings.HasPrefix(sysctlKey, "net.") { + if noUseNet && strings.HasPrefix(sysctlKey, "net.") { logrus.Infof("Sysctl %s=%s ignored in containers.conf, since Network Namespace set to host", sysctlKey, sysctlVal) continue } // Ignore uts sysctls if --uts=host - if s.UtsNS.IsHost() && (strings.HasPrefix(sysctlKey, "kernel.domainname") || strings.HasPrefix(sysctlKey, "kernel.hostname")) { + if noUseUTS && (strings.HasPrefix(sysctlKey, "kernel.domainname") || strings.HasPrefix(sysctlKey, "kernel.hostname")) { logrus.Infof("Sysctl %s=%s ignored in containers.conf, since UTS Namespace set to host", sysctlKey, sysctlVal) continue } diff --git a/pkg/specgen/generate/storage.go b/pkg/specgen/generate/storage.go index f523ac5bf..63713726e 100644 --- a/pkg/specgen/generate/storage.go +++ b/pkg/specgen/generate/storage.go @@ -124,14 +124,10 @@ func finalizeMounts(ctx context.Context, s *specgen.SpecGenerator, rt *libpod.Ru // named volumes, and vice versa. // We'll delete the conflicts here as we supersede. for dest := range unifiedMounts { - if _, ok := baseVolumes[dest]; ok { - delete(baseVolumes, dest) - } + delete(baseVolumes, dest) } for dest := range unifiedVolumes { - if _, ok := baseMounts[dest]; ok { - delete(baseMounts, dest) - } + delete(baseMounts, dest) } // Supersede volumes-from/image volumes with unified volumes from above. diff --git a/pkg/specgen/generate/validate.go b/pkg/specgen/generate/validate.go index f0ab4b994..77cccad3e 100644 --- a/pkg/specgen/generate/validate.go +++ b/pkg/specgen/generate/validate.go @@ -48,7 +48,7 @@ func verifyContainerResourcesCgroupV1(s *specgen.SpecGenerator) ([]string, error warnings = append(warnings, "Your kernel does not support memory swappiness capabilities, or the cgroup is not mounted. Memory swappiness discarded.") memory.Swappiness = nil } else { - if *memory.Swappiness < 0 || *memory.Swappiness > 100 { + if *memory.Swappiness > 100 { return warnings, errors.Errorf("invalid value: %v, valid memory swappiness range is 0-100", *memory.Swappiness) } } |