summaryrefslogtreecommitdiff
path: root/libpod
diff options
context:
space:
mode:
Diffstat (limited to 'libpod')
-rw-r--r--libpod/container_internal.go12
-rw-r--r--libpod/container_internal_linux.go2
-rw-r--r--libpod/kube.go64
-rw-r--r--libpod/options.go19
4 files changed, 81 insertions, 16 deletions
diff --git a/libpod/container_internal.go b/libpod/container_internal.go
index f69acb33b..af17d8495 100644
--- a/libpod/container_internal.go
+++ b/libpod/container_internal.go
@@ -18,12 +18,12 @@ import (
"github.com/containers/libpod/pkg/ctime"
"github.com/containers/libpod/pkg/hooks"
"github.com/containers/libpod/pkg/hooks/exec"
- "github.com/containers/libpod/pkg/lookup"
"github.com/containers/libpod/pkg/rootless"
"github.com/containers/storage"
"github.com/containers/storage/pkg/archive"
"github.com/containers/storage/pkg/chrootarchive"
"github.com/containers/storage/pkg/mount"
+ "github.com/opencontainers/runc/libcontainer/user"
spec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/opencontainers/runtime-tools/generate"
"github.com/opencontainers/selinux/go-selinux/label"
@@ -1027,7 +1027,7 @@ func (c *Container) writeStringToRundir(destFile, output string) (string, error)
return filepath.Join(c.state.DestinationRunDir, destFile), nil
}
-func (c *Container) addLocalVolumes(ctx context.Context, g *generate.Generator) error {
+func (c *Container) addLocalVolumes(ctx context.Context, g *generate.Generator, execUser *user.ExecUser) error {
var uid, gid int
mountPoint := c.state.Mountpoint
if !c.state.Mounted {
@@ -1053,12 +1053,8 @@ func (c *Container) addLocalVolumes(ctx context.Context, g *generate.Generator)
}
if c.config.User != "" {
- if !c.state.Mounted {
- return errors.Wrapf(ErrCtrStateInvalid, "container %s must be mounted in order to translate User field", c.ID())
- }
- execUser, err := lookup.GetUserGroupInfo(c.state.Mountpoint, c.config.User, nil)
- if err != nil {
- return err
+ if execUser == nil {
+ return errors.Wrapf(ErrInternal, "nil pointer passed to addLocalVolumes for execUser")
}
uid = execUser.Uid
gid = execUser.Gid
diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go
index f9b0592f9..4f2955110 100644
--- a/libpod/container_internal_linux.go
+++ b/libpod/container_internal_linux.go
@@ -236,7 +236,7 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) {
// Bind builtin image volumes
if c.config.Rootfs == "" && c.config.ImageVolumes {
- if err := c.addLocalVolumes(ctx, &g); err != nil {
+ if err := c.addLocalVolumes(ctx, &g, execUser); err != nil {
return nil, errors.Wrapf(err, "error mounting image volumes")
}
}
diff --git a/libpod/kube.go b/libpod/kube.go
index 05a6537c4..c164ca0c5 100644
--- a/libpod/kube.go
+++ b/libpod/kube.go
@@ -11,6 +11,7 @@ import (
"github.com/containers/libpod/pkg/util"
"github.com/cri-o/ocicni/pkg/ocicni"
"github.com/opencontainers/runtime-spec/specs-go"
+ "github.com/opencontainers/runtime-tools/generate"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"k8s.io/api/core/v1"
@@ -335,20 +336,69 @@ func libpodMountsToKubeVolumeMounts(c *Container) ([]v1.VolumeMount, error) {
return vms, nil
}
+func determineCapAddDropFromCapabilities(defaultCaps, containerCaps []string) *v1.Capabilities {
+ var (
+ drop []v1.Capability
+ add []v1.Capability
+ )
+ // Find caps in the defaultCaps but not in the container's
+ // those indicate a dropped cap
+ for _, capability := range defaultCaps {
+ if !util.StringInSlice(capability, containerCaps) {
+ cap := v1.Capability(capability)
+ drop = append(drop, cap)
+ }
+ }
+ // Find caps in the container but not in the defaults; those indicate
+ // an added cap
+ for _, capability := range containerCaps {
+ if !util.StringInSlice(capability, defaultCaps) {
+ cap := v1.Capability(capability)
+ add = append(add, cap)
+ }
+ }
+
+ return &v1.Capabilities{
+ Add: add,
+ Drop: drop,
+ }
+}
+
+func capAddDrop(caps *specs.LinuxCapabilities) (*v1.Capabilities, error) {
+ g, err := generate.New("linux")
+ if err != nil {
+ return nil, err
+ }
+ // Combine all the default capabilities into a slice
+ defaultCaps := append(g.Config.Process.Capabilities.Ambient, g.Config.Process.Capabilities.Bounding...)
+ defaultCaps = append(defaultCaps, g.Config.Process.Capabilities.Effective...)
+ defaultCaps = append(defaultCaps, g.Config.Process.Capabilities.Inheritable...)
+ defaultCaps = append(defaultCaps, g.Config.Process.Capabilities.Permitted...)
+
+ // Combine all the container's capabilities into a slic
+ containerCaps := append(caps.Ambient, caps.Bounding...)
+ containerCaps = append(containerCaps, caps.Effective...)
+ containerCaps = append(containerCaps, caps.Inheritable...)
+ containerCaps = append(containerCaps, caps.Permitted...)
+
+ calculatedCaps := determineCapAddDropFromCapabilities(defaultCaps, containerCaps)
+ return calculatedCaps, nil
+}
+
// generateKubeSecurityContext generates a securityContext based on the existing container
func generateKubeSecurityContext(c *Container) (*v1.SecurityContext, error) {
priv := c.Privileged()
ro := c.IsReadOnly()
allowPrivEscalation := !c.Spec().Process.NoNewPrivileges
- // TODO enable use of capabilities when we can figure out how to extract cap-add|remove
- //caps := v1.Capabilities{
- // //Add: c.config.Spec.Process.Capabilities
- //}
+ newCaps, err := capAddDrop(c.config.Spec.Process.Capabilities)
+ if err != nil {
+ return nil, err
+ }
+
sc := v1.SecurityContext{
- // TODO enable use of capabilities when we can figure out how to extract cap-add|remove
- //Capabilities: &caps,
- Privileged: &priv,
+ Capabilities: newCaps,
+ Privileged: &priv,
// TODO How do we know if selinux were passed into podman
//SELinuxOptions:
// RunAsNonRoot is an optional parameter; our first implementations should be root only; however
diff --git a/libpod/options.go b/libpod/options.go
index 352e6a506..9aa657ddd 100644
--- a/libpod/options.go
+++ b/libpod/options.go
@@ -29,9 +29,12 @@ func WithStorageConfig(config storage.StoreOptions) RuntimeOption {
return ErrRuntimeFinalized
}
+ setField := false
+
if config.RunRoot != "" {
rt.config.StorageConfig.RunRoot = config.RunRoot
rt.configuredFrom.storageRunRootSet = true
+ setField = true
}
if config.GraphRoot != "" {
@@ -42,16 +45,20 @@ func WithStorageConfig(config storage.StoreOptions) RuntimeOption {
// of the c/storage store by default
rt.config.StaticDir = filepath.Join(config.GraphRoot, "libpod")
rt.configuredFrom.libpodStaticDirSet = true
+
+ setField = true
}
if config.GraphDriverName != "" {
rt.config.StorageConfig.GraphDriverName = config.GraphDriverName
rt.configuredFrom.storageGraphDriverSet = true
+ setField = true
}
if config.GraphDriverOptions != nil {
rt.config.StorageConfig.GraphDriverOptions = make([]string, len(config.GraphDriverOptions))
copy(rt.config.StorageConfig.GraphDriverOptions, config.GraphDriverOptions)
+ setField = true
}
if config.UIDMap != nil {
@@ -64,6 +71,18 @@ func WithStorageConfig(config storage.StoreOptions) RuntimeOption {
copy(rt.config.StorageConfig.GIDMap, config.GIDMap)
}
+ // If any one of runroot, graphroot, graphdrivername,
+ // or graphdriveroptions are set, then GraphRoot and RunRoot
+ // must be set
+ if setField {
+ if rt.config.StorageConfig.GraphRoot == "" {
+ rt.config.StorageConfig.GraphRoot = storage.DefaultStoreOptions.GraphRoot
+ }
+ if rt.config.StorageConfig.RunRoot == "" {
+ rt.config.StorageConfig.RunRoot = storage.DefaultStoreOptions.RunRoot
+ }
+ }
+
return nil
}
}