diff options
Diffstat (limited to 'pkg/spec')
-rw-r--r-- | pkg/spec/createconfig.go | 32 | ||||
-rw-r--r-- | pkg/spec/security.go | 45 | ||||
-rw-r--r-- | pkg/spec/spec.go | 73 | ||||
-rw-r--r-- | pkg/spec/storage.go | 2 |
4 files changed, 112 insertions, 40 deletions
diff --git a/pkg/spec/createconfig.go b/pkg/spec/createconfig.go index 02678a687..daa997104 100644 --- a/pkg/spec/createconfig.go +++ b/pkg/spec/createconfig.go @@ -112,6 +112,7 @@ type NetworkConfig struct { type SecurityConfig struct { CapAdd []string // cap-add CapDrop []string // cap-drop + CapRequired []string // cap-required LabelOpts []string //SecurityOpts NoNewPrivs bool //SecurityOpts ApparmorProfile string //SecurityOpts @@ -143,6 +144,7 @@ type CreateConfig struct { InitPath string //init-path Image string ImageID string + RawImageName string BuiltinImgVolumes map[string]struct{} // volumes defined in the image config ImageVolumeType string // how to handle the image volume, either bind, tmpfs, or ignore Interactive bool //interactive @@ -156,6 +158,7 @@ type CreateConfig struct { Resources CreateResourceConfig RestartPolicy string Rm bool //rm + Rmi bool //rmi StopSignal syscall.Signal // stop-signal StopTimeout uint // stop-timeout Systemd bool @@ -193,6 +196,7 @@ func (c *CreateConfig) createExitCommand(runtime *libpod.Runtime) ([]string, err if err != nil { return nil, err } + storageConfig := runtime.StorageConfig() // We need a cleanup process for containers in the current model. // But we can't assume that the caller is Podman - it could be another @@ -205,23 +209,23 @@ func (c *CreateConfig) createExitCommand(runtime *libpod.Runtime) ([]string, err } command := []string{cmd, - "--root", config.StorageConfig.GraphRoot, - "--runroot", config.StorageConfig.RunRoot, + "--root", storageConfig.GraphRoot, + "--runroot", storageConfig.RunRoot, "--log-level", logrus.GetLevel().String(), - "--cgroup-manager", config.CgroupManager, - "--tmpdir", config.TmpDir, + "--cgroup-manager", config.Engine.CgroupManager, + "--tmpdir", config.Engine.TmpDir, } - if config.OCIRuntime != "" { - command = append(command, []string{"--runtime", config.OCIRuntime}...) + if config.Engine.OCIRuntime != "" { + command = append(command, []string{"--runtime", config.Engine.OCIRuntime}...) } - if config.StorageConfig.GraphDriverName != "" { - command = append(command, []string{"--storage-driver", config.StorageConfig.GraphDriverName}...) + if storageConfig.GraphDriverName != "" { + command = append(command, []string{"--storage-driver", storageConfig.GraphDriverName}...) } - for _, opt := range config.StorageConfig.GraphDriverOptions { + for _, opt := range storageConfig.GraphDriverOptions { command = append(command, []string{"--storage-opt", opt}...) } - if config.EventsLogger != "" { - command = append(command, []string{"--events-backend", config.EventsLogger}...) + if config.Engine.EventsLogger != "" { + command = append(command, []string{"--events-backend", config.Engine.EventsLogger}...) } if c.Syslog { @@ -233,6 +237,10 @@ func (c *CreateConfig) createExitCommand(runtime *libpod.Runtime) ([]string, err command = append(command, "--rm") } + if c.Rmi { + command = append(command, "--rmi") + } + return command, nil } @@ -342,7 +350,7 @@ func (c *CreateConfig) getContainerCreateOptions(runtime *libpod.Runtime, pod *l options = append(options, nsOpts...) // Gather up the options for NewContainer which consist of With... funcs - options = append(options, libpod.WithRootFSFromImage(c.ImageID, c.Image)) + options = append(options, libpod.WithRootFSFromImage(c.ImageID, c.Image, c.RawImageName)) options = append(options, libpod.WithConmonPidFile(c.ConmonPidFile)) options = append(options, libpod.WithLabels(c.Labels)) options = append(options, libpod.WithShmSize(c.Resources.ShmSize)) diff --git a/pkg/spec/security.go b/pkg/spec/security.go index 3bad9f97a..0f8d36f00 100644 --- a/pkg/spec/security.go +++ b/pkg/spec/security.go @@ -4,11 +4,13 @@ import ( "fmt" "strings" + "github.com/containers/common/pkg/capabilities" "github.com/containers/libpod/libpod" - "github.com/containers/libpod/pkg/capabilities" + "github.com/containers/libpod/pkg/util" "github.com/opencontainers/runtime-tools/generate" "github.com/opencontainers/selinux/go-selinux/label" "github.com/pkg/errors" + "github.com/sirupsen/logrus" ) // ToCreateOptions convert the SecurityConfig to a slice of container create @@ -113,28 +115,49 @@ func (c *SecurityConfig) ConfigureGenerator(g *generate.Generator, user *UserCon configSpec := g.Config var err error - var caplist []string + var defaultCaplist []string bounding := configSpec.Process.Capabilities.Bounding if useNotRoot(user.User) { - configSpec.Process.Capabilities.Bounding = caplist + configSpec.Process.Capabilities.Bounding = defaultCaplist } - caplist, err = capabilities.MergeCapabilities(configSpec.Process.Capabilities.Bounding, c.CapAdd, c.CapDrop) + defaultCaplist, err = capabilities.MergeCapabilities(configSpec.Process.Capabilities.Bounding, c.CapAdd, c.CapDrop) if err != nil { return err } - configSpec.Process.Capabilities.Bounding = caplist - configSpec.Process.Capabilities.Permitted = caplist - configSpec.Process.Capabilities.Inheritable = caplist - configSpec.Process.Capabilities.Effective = caplist - configSpec.Process.Capabilities.Ambient = caplist + privCapRequired := []string{} + + if !c.Privileged && len(c.CapRequired) > 0 { + // Pass CapRequired in CapAdd field to normalize capabilities names + capRequired, err := capabilities.MergeCapabilities(nil, c.CapRequired, nil) + if err != nil { + logrus.Errorf("capabilities requested by user or image are not valid: %q", strings.Join(c.CapRequired, ",")) + } else { + // Verify all capRequiered are in the defaultCapList + for _, cap := range capRequired { + if !util.StringInSlice(cap, defaultCaplist) { + privCapRequired = append(privCapRequired, cap) + } + } + } + if len(privCapRequired) == 0 { + defaultCaplist = capRequired + } else { + logrus.Errorf("capabilities requested by user or image are not allowed by default: %q", strings.Join(privCapRequired, ",")) + } + } + configSpec.Process.Capabilities.Bounding = defaultCaplist + configSpec.Process.Capabilities.Permitted = defaultCaplist + configSpec.Process.Capabilities.Inheritable = defaultCaplist + configSpec.Process.Capabilities.Effective = defaultCaplist + configSpec.Process.Capabilities.Ambient = defaultCaplist if useNotRoot(user.User) { - caplist, err = capabilities.MergeCapabilities(bounding, c.CapAdd, c.CapDrop) + defaultCaplist, err = capabilities.MergeCapabilities(bounding, c.CapAdd, c.CapDrop) if err != nil { return err } } - configSpec.Process.Capabilities.Bounding = caplist + configSpec.Process.Capabilities.Bounding = defaultCaplist // HANDLE SECCOMP if c.SeccompProfilePath != "unconfined" { diff --git a/pkg/spec/spec.go b/pkg/spec/spec.go index a4ae22efd..d4fd5976f 100644 --- a/pkg/spec/spec.go +++ b/pkg/spec/spec.go @@ -3,12 +3,14 @@ package createconfig import ( "strings" + "github.com/containers/common/pkg/capabilities" + cconfig "github.com/containers/common/pkg/config" "github.com/containers/libpod/libpod" - libpodconfig "github.com/containers/libpod/libpod/config" - "github.com/containers/libpod/libpod/define" "github.com/containers/libpod/pkg/cgroups" + "github.com/containers/libpod/pkg/env" "github.com/containers/libpod/pkg/rootless" "github.com/containers/libpod/pkg/sysinfo" + "github.com/containers/libpod/pkg/util" "github.com/docker/go-units" "github.com/opencontainers/runc/libcontainer/user" spec "github.com/opencontainers/runtime-spec/specs-go" @@ -78,6 +80,37 @@ func (config *CreateConfig) createConfigToOCISpec(runtime *libpod.Runtime, userM g.AddLinuxMaskedPaths("/sys/kernel") } } + var runtimeConfig *cconfig.Config + + if runtime != nil { + runtimeConfig, err = runtime.GetConfig() + if err != nil { + return nil, err + } + g.Config.Process.Capabilities.Bounding = runtimeConfig.Containers.DefaultCapabilities + sysctls, err := util.ValidateSysctls(runtimeConfig.Containers.DefaultSysctls) + if err != nil { + return nil, err + } + + for name, val := range config.Security.Sysctl { + sysctls[name] = val + } + config.Security.Sysctl = sysctls + if !util.StringInSlice("host", config.Resources.Ulimit) { + config.Resources.Ulimit = append(runtimeConfig.Containers.DefaultUlimits, config.Resources.Ulimit...) + } + if config.Resources.PidsLimit < 0 && !config.cgroupDisabled() { + config.Resources.PidsLimit = runtimeConfig.Containers.PidsLimit + } + + } else { + g.Config.Process.Capabilities.Bounding = cconfig.DefaultCapabilities + if config.Resources.PidsLimit < 0 && !config.cgroupDisabled() { + config.Resources.PidsLimit = cconfig.DefaultPidsLimit + } + } + gid5Available := true if isRootless { nGids, err := GetAvailableGids() @@ -150,7 +183,6 @@ func (config *CreateConfig) createConfigToOCISpec(runtime *libpod.Runtime, userM for key, val := range config.Annotations { g.AddAnnotation(key, val) } - g.AddProcessEnv("container", "podman") addedResources := false @@ -240,16 +272,6 @@ func (config *CreateConfig) createConfigToOCISpec(runtime *libpod.Runtime, userM } } - // SECURITY OPTS - var runtimeConfig *libpodconfig.Config - - if runtime != nil { - runtimeConfig, err = runtime.GetConfig() - if err != nil { - return nil, err - } - } - g.SetProcessNoNewPrivileges(config.Security.NoNewPrivs) if !config.Security.Privileged { @@ -259,7 +281,7 @@ func (config *CreateConfig) createConfigToOCISpec(runtime *libpod.Runtime, userM // Unless already set via the CLI, check if we need to disable process // labels or set the defaults. if len(config.Security.LabelOpts) == 0 && runtimeConfig != nil { - if !runtimeConfig.EnableLabeling { + if !runtimeConfig.Containers.EnableLabeling { // Disabled in the config. config.Security.LabelOpts = append(config.Security.LabelOpts, "disable") } else if err := config.Security.SetLabelOpts(runtime, &config.Pid, &config.Ipc); err != nil { @@ -282,7 +304,7 @@ func (config *CreateConfig) createConfigToOCISpec(runtime *libpod.Runtime, userM if err != nil { return nil, err } - if (!cgroup2 || (runtimeConfig != nil && runtimeConfig.CgroupManager != define.SystemdCgroupsManager)) && config.Resources.PidsLimit == sysinfo.GetDefaultPidsLimit() { + if (!cgroup2 || (runtimeConfig != nil && runtimeConfig.Engine.CgroupManager != cconfig.SystemdCgroupsManager)) && config.Resources.PidsLimit == sysinfo.GetDefaultPidsLimit() { setPidLimit = false } } @@ -292,6 +314,9 @@ func (config *CreateConfig) createConfigToOCISpec(runtime *libpod.Runtime, userM } } + // Make sure to always set the default variables unless overridden in the + // config. + config.Env = env.Join(env.DefaultEnvVariables, config.Env) for name, val := range config.Env { g.AddProcessEnv(name, val) } @@ -327,6 +352,18 @@ func (config *CreateConfig) createConfigToOCISpec(runtime *libpod.Runtime, userM } configSpec := g.Config + // If the container image specifies an label with a + // capabilities.ContainerImageLabel then split the comma separated list + // of capabilities and record them. This list indicates the only + // capabilities, required to run the container. + var capRequired []string + for key, val := range config.Labels { + if util.StringInSlice(key, capabilities.ContainerImageLabels) { + capRequired = strings.Split(val, ",") + } + } + config.Security.CapRequired = capRequired + if err := config.Security.ConfigureGenerator(&g, &config.User); err != nil { return nil, err } @@ -359,7 +396,7 @@ func (config *CreateConfig) createConfigToOCISpec(runtime *libpod.Runtime, userM configSpec.Linux.Resources = &spec.LinuxResources{} } - canUseResources := cgroup2 && runtimeConfig != nil && (runtimeConfig.CgroupManager == define.SystemdCgroupsManager) + canUseResources := cgroup2 && runtimeConfig != nil && (runtimeConfig.Engine.CgroupManager == cconfig.SystemdCgroupsManager) if addedResources && !canUseResources { return nil, errors.New("invalid configuration, cannot specify resource limits without cgroups v2 and --cgroup-manager=systemd") @@ -416,6 +453,10 @@ func (config *CreateConfig) createConfigToOCISpec(runtime *libpod.Runtime, userM return configSpec, nil } +func (config *CreateConfig) cgroupDisabled() bool { + return config.Cgroup.Cgroups == "disabled" +} + func BlockAccessToKernelFilesystems(privileged, pidModeIsHost bool, g *generate.Generator) { if !privileged { for _, mp := range []string{ diff --git a/pkg/spec/storage.go b/pkg/spec/storage.go index c365701de..b0687b4c2 100644 --- a/pkg/spec/storage.go +++ b/pkg/spec/storage.go @@ -124,7 +124,7 @@ func (config *CreateConfig) parseVolumes(runtime *libpod.Runtime) ([]spec.Mount, if err != nil { return nil, nil, err } - initPath = rtc.InitPath + initPath = rtc.Engine.InitPath } initMount, err := config.addContainerInitBinary(initPath) if err != nil { |