mirror of
https://github.com/containers/podman.git
synced 2025-10-19 20:23:08 +08:00
Allow containers/storage to handle on SELinux labeling
Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
This commit is contained in:
@ -243,6 +243,8 @@ type ContainerConfig struct {
|
|||||||
ProcessLabel string `json:"ProcessLabel,omitempty"`
|
ProcessLabel string `json:"ProcessLabel,omitempty"`
|
||||||
// SELinux mount label for root filesystem
|
// SELinux mount label for root filesystem
|
||||||
MountLabel string `json:"MountLabel,omitempty"`
|
MountLabel string `json:"MountLabel,omitempty"`
|
||||||
|
// LabelOpts are options passed in by the user to setup SELinux labels
|
||||||
|
LabelOpts []string `json:"labelopts,omitempty"`
|
||||||
// User and group to use in the container
|
// User and group to use in the container
|
||||||
// Can be specified by name or UID/GID
|
// Can be specified by name or UID/GID
|
||||||
User string `json:"user,omitempty"`
|
User string `json:"user,omitempty"`
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -79,9 +79,9 @@ func (c *Container) getContainerInspectData(size bool, driverData *inspect.Data)
|
|||||||
Name: config.Name,
|
Name: config.Name,
|
||||||
Driver: driverData.Name,
|
Driver: driverData.Name,
|
||||||
MountLabel: config.MountLabel,
|
MountLabel: config.MountLabel,
|
||||||
|
ProcessLabel: config.ProcessLabel,
|
||||||
EffectiveCaps: spec.Process.Capabilities.Effective,
|
EffectiveCaps: spec.Process.Capabilities.Effective,
|
||||||
BoundingCaps: spec.Process.Capabilities.Bounding,
|
BoundingCaps: spec.Process.Capabilities.Bounding,
|
||||||
ProcessLabel: spec.Process.SelinuxLabel,
|
|
||||||
AppArmorProfile: spec.Process.ApparmorProfile,
|
AppArmorProfile: spec.Process.ApparmorProfile,
|
||||||
ExecIDs: execIDs,
|
ExecIDs: execIDs,
|
||||||
GraphDriver: driverData,
|
GraphDriver: driverData,
|
||||||
@ -93,6 +93,7 @@ func (c *Container) getContainerInspectData(size bool, driverData *inspect.Data)
|
|||||||
HairpinMode: false, // TODO
|
HairpinMode: false, // TODO
|
||||||
LinkLocalIPv6Address: "", // TODO - do we even support IPv6?
|
LinkLocalIPv6Address: "", // TODO - do we even support IPv6?
|
||||||
LinkLocalIPv6PrefixLen: 0, // TODO - do we even support IPv6?
|
LinkLocalIPv6PrefixLen: 0, // TODO - do we even support IPv6?
|
||||||
|
|
||||||
Ports: []ocicni.PortMapping{}, // TODO - maybe worth it to put this in Docker format?
|
Ports: []ocicni.PortMapping{}, // TODO - maybe worth it to put this in Docker format?
|
||||||
SandboxKey: "", // Network namespace path
|
SandboxKey: "", // Network namespace path
|
||||||
SecondaryIPAddresses: nil, // TODO - do we support this?
|
SecondaryIPAddresses: nil, // TODO - do we support this?
|
||||||
|
@ -194,12 +194,18 @@ func (c *Container) setupStorage(ctx context.Context) error {
|
|||||||
return errors.Wrapf(ErrInvalidArg, "must provide image ID and image name to use an image")
|
return errors.Wrapf(ErrInvalidArg, "must provide image ID and image name to use an image")
|
||||||
}
|
}
|
||||||
|
|
||||||
var options *storage.ContainerOptions
|
options := storage.ContainerOptions{
|
||||||
if c.config.Rootfs == "" {
|
IDMappingOptions: storage.IDMappingOptions{
|
||||||
options = &storage.ContainerOptions{c.config.IDMappings}
|
HostUIDMapping: true,
|
||||||
|
HostGIDMapping: true,
|
||||||
|
},
|
||||||
|
LabelOpts: c.config.LabelOpts,
|
||||||
}
|
}
|
||||||
containerInfo, err := c.runtime.storageService.CreateContainerStorage(ctx, c.runtime.imageContext, c.config.RootfsImageName, c.config.RootfsImageID, c.config.Name, c.config.ID, c.config.MountLabel, options)
|
|
||||||
|
if c.config.Rootfs == "" {
|
||||||
|
options.IDMappingOptions = c.config.IDMappings
|
||||||
|
}
|
||||||
|
containerInfo, err := c.runtime.storageService.CreateContainerStorage(ctx, c.runtime.imageContext, c.config.RootfsImageName, c.config.RootfsImageID, c.config.Name, c.config.ID, options)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrapf(err, "error creating container storage")
|
return errors.Wrapf(err, "error creating container storage")
|
||||||
}
|
}
|
||||||
@ -225,6 +231,8 @@ func (c *Container) setupStorage(ctx context.Context) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c.config.ProcessLabel = containerInfo.ProcessLabel
|
||||||
|
c.config.MountLabel = containerInfo.MountLabel
|
||||||
c.config.StaticDir = containerInfo.Dir
|
c.config.StaticDir = containerInfo.Dir
|
||||||
c.state.RunDir = containerInfo.RunDir
|
c.state.RunDir = containerInfo.RunDir
|
||||||
c.state.DestinationRunDir = c.state.RunDir
|
c.state.DestinationRunDir = c.state.RunDir
|
||||||
|
@ -391,11 +391,7 @@ func WithSecLabels(labelOpts []string) CtrCreateOption {
|
|||||||
if ctr.valid {
|
if ctr.valid {
|
||||||
return ErrCtrFinalized
|
return ErrCtrFinalized
|
||||||
}
|
}
|
||||||
var err error
|
ctr.config.LabelOpts = labelOpts
|
||||||
ctr.config.ProcessLabel, ctr.config.MountLabel, err = ctr.runtime.initLabels(labelOpts)
|
|
||||||
if err != nil {
|
|
||||||
return errors.Wrapf(err, "failed to init labels")
|
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,6 @@ import (
|
|||||||
"github.com/containers/storage"
|
"github.com/containers/storage"
|
||||||
"github.com/containers/storage/pkg/stringid"
|
"github.com/containers/storage/pkg/stringid"
|
||||||
spec "github.com/opencontainers/runtime-spec/specs-go"
|
spec "github.com/opencontainers/runtime-spec/specs-go"
|
||||||
"github.com/opencontainers/selinux/go-selinux/label"
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/ulule/deepcopier"
|
"github.com/ulule/deepcopier"
|
||||||
@ -329,10 +328,6 @@ func (r *Runtime) removeContainer(ctx context.Context, c *Container, force bool)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if r.config.EnableLabeling {
|
|
||||||
label.ReleaseLabel(c.ProcessLabel())
|
|
||||||
r.reserveLabels()
|
|
||||||
}
|
|
||||||
// Delete the container.
|
// Delete the container.
|
||||||
// Not needed in Configured and Exited states, where the container
|
// Not needed in Configured and Exited states, where the container
|
||||||
// doesn't exist in the runtime
|
// doesn't exist in the runtime
|
||||||
@ -467,28 +462,3 @@ func (r *Runtime) GetLatestContainer() (*Container, error) {
|
|||||||
}
|
}
|
||||||
return ctrs[lastCreatedIndex], nil
|
return ctrs[lastCreatedIndex], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// reserveLabels walks the list o fcontainers and reserves the label, so new containers will not
|
|
||||||
// get them.
|
|
||||||
// TODO Performance wise this should only run if the state has changed since the last time it was run.
|
|
||||||
func (r *Runtime) reserveLabels() error {
|
|
||||||
containers, err := r.state.AllContainers()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
for _, ctr := range containers {
|
|
||||||
label.ReserveLabel(ctr.ProcessLabel())
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// initLabels allocates an new label to return to the caller
|
|
||||||
func (r *Runtime) initLabels(labelOpts []string) (string, string, error) {
|
|
||||||
if !r.config.EnableLabeling {
|
|
||||||
return "", "", nil
|
|
||||||
}
|
|
||||||
if err := r.reserveLabels(); err != nil {
|
|
||||||
return "", "", errors.Wrapf(err, "unable to reserve labels")
|
|
||||||
}
|
|
||||||
return label.InitLabels(labelOpts)
|
|
||||||
}
|
|
||||||
|
@ -27,10 +27,13 @@ func getStorageService(store storage.Store) (*storageService, error) {
|
|||||||
// of its nonvolatile and volatile per-container directories, along with a copy
|
// of its nonvolatile and volatile per-container directories, along with a copy
|
||||||
// of the configuration blob from the image that was used to create the
|
// of the configuration blob from the image that was used to create the
|
||||||
// container, if the image had a configuration.
|
// container, if the image had a configuration.
|
||||||
|
// It also returns the ProcessLabel and MountLabel selected for the container
|
||||||
type ContainerInfo struct {
|
type ContainerInfo struct {
|
||||||
Dir string
|
Dir string
|
||||||
RunDir string
|
RunDir string
|
||||||
Config *v1.Image
|
Config *v1.Image
|
||||||
|
ProcessLabel string
|
||||||
|
MountLabel string
|
||||||
}
|
}
|
||||||
|
|
||||||
// RuntimeContainerMetadata is the structure that we encode as JSON and store
|
// RuntimeContainerMetadata is the structure that we encode as JSON and store
|
||||||
@ -59,7 +62,7 @@ func (metadata *RuntimeContainerMetadata) SetMountLabel(mountLabel string) {
|
|||||||
|
|
||||||
// CreateContainerStorage creates the storage end of things. We already have the container spec created
|
// CreateContainerStorage creates the storage end of things. We already have the container spec created
|
||||||
// TO-DO We should be passing in an Image object in the future.
|
// TO-DO We should be passing in an Image object in the future.
|
||||||
func (r *storageService) CreateContainerStorage(ctx context.Context, systemContext *types.SystemContext, imageName, imageID, containerName, containerID, mountLabel string, options *storage.ContainerOptions) (cinfo ContainerInfo, err error) {
|
func (r *storageService) CreateContainerStorage(ctx context.Context, systemContext *types.SystemContext, imageName, imageID, containerName, containerID string, options storage.ContainerOptions) (cinfo ContainerInfo, err error) {
|
||||||
var imageConfig *v1.Image
|
var imageConfig *v1.Image
|
||||||
if imageName != "" {
|
if imageName != "" {
|
||||||
var ref types.ImageReference
|
var ref types.ImageReference
|
||||||
@ -101,7 +104,6 @@ func (r *storageService) CreateContainerStorage(ctx context.Context, systemConte
|
|||||||
ImageID: imageID,
|
ImageID: imageID,
|
||||||
ContainerName: containerName,
|
ContainerName: containerName,
|
||||||
CreatedAt: time.Now().Unix(),
|
CreatedAt: time.Now().Unix(),
|
||||||
MountLabel: mountLabel,
|
|
||||||
}
|
}
|
||||||
mdata, err := json.Marshal(&metadata)
|
mdata, err := json.Marshal(&metadata)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -111,15 +113,7 @@ func (r *storageService) CreateContainerStorage(ctx context.Context, systemConte
|
|||||||
// Build the container.
|
// Build the container.
|
||||||
names := []string{containerName}
|
names := []string{containerName}
|
||||||
|
|
||||||
if options == nil {
|
container, err := r.store.CreateContainer(containerID, names, imageID, "", string(mdata), &options)
|
||||||
options = &storage.ContainerOptions{
|
|
||||||
IDMappingOptions: storage.IDMappingOptions{
|
|
||||||
HostUIDMapping: true,
|
|
||||||
HostGIDMapping: true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
container, err := r.store.CreateContainer(containerID, names, imageID, "", string(mdata), options)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Debugf("failed to create container %s(%s): %v", metadata.ContainerName, containerID, err)
|
logrus.Debugf("failed to create container %s(%s): %v", metadata.ContainerName, containerID, err)
|
||||||
|
|
||||||
@ -170,6 +164,8 @@ func (r *storageService) CreateContainerStorage(ctx context.Context, systemConte
|
|||||||
Dir: containerDir,
|
Dir: containerDir,
|
||||||
RunDir: containerRunDir,
|
RunDir: containerRunDir,
|
||||||
Config: imageConfig,
|
Config: imageConfig,
|
||||||
|
ProcessLabel: container.ProcessLabel(),
|
||||||
|
MountLabel: container.MountLabel(),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user