diff options
Diffstat (limited to 'libpod')
-rw-r--r-- | libpod/container_internal.go | 12 | ||||
-rw-r--r-- | libpod/container_internal_linux.go | 2 | ||||
-rw-r--r-- | libpod/kube.go | 64 | ||||
-rw-r--r-- | libpod/options.go | 19 |
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 } } |