summaryrefslogtreecommitdiff
path: root/pkg/spec
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/spec')
-rw-r--r--pkg/spec/config_linux.go3
-rw-r--r--pkg/spec/createconfig.go112
-rw-r--r--pkg/spec/spec.go59
3 files changed, 101 insertions, 73 deletions
diff --git a/pkg/spec/config_linux.go b/pkg/spec/config_linux.go
index ea04b95bd..6c0a99419 100644
--- a/pkg/spec/config_linux.go
+++ b/pkg/spec/config_linux.go
@@ -60,6 +60,9 @@ func (c *CreateConfig) addPrivilegedDevices(g *generate.Generator) error {
for _, d := range hostDevices {
g.AddDevice(Device(d))
}
+
+ // Add resources device - need to clear the existing one first.
+ g.Spec().Linux.Resources.Devices = nil
g.AddLinuxResourcesDevice(true, "", nil, nil, "rwm")
return nil
}
diff --git a/pkg/spec/createconfig.go b/pkg/spec/createconfig.go
index a441b4019..887ef8e95 100644
--- a/pkg/spec/createconfig.go
+++ b/pkg/spec/createconfig.go
@@ -15,7 +15,6 @@ import (
"github.com/docker/go-connections/nat"
spec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/opencontainers/runtime-tools/generate"
- "github.com/opencontainers/selinux/go-selinux/label"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"golang.org/x/sys/unix"
@@ -113,8 +112,7 @@ type CreateConfig struct {
Quiet bool //quiet
ReadOnlyRootfs bool //read-only
Resources CreateResourceConfig
- Rm bool //rm
- ShmDir string
+ Rm bool //rm
StopSignal syscall.Signal // stop-signal
StopTimeout uint // stop-timeout
Sysctl map[string]string //sysctl
@@ -124,14 +122,14 @@ type CreateConfig struct {
UsernsMode namespaces.UsernsMode //userns
User string //user
UtsMode namespaces.UTSMode //uts
+ Mounts []spec.Mount //mounts
Volumes []string //volume
VolumesFrom []string
- WorkDir string //workdir
- MountLabel string //SecurityOpts
- ProcessLabel string //SecurityOpts
- NoNewPrivs bool //SecurityOpts
- ApparmorProfile string //SecurityOpts
- SeccompProfilePath string //SecurityOpts
+ WorkDir string //workdir
+ LabelOpts []string //SecurityOpts
+ NoNewPrivs bool //SecurityOpts
+ ApparmorProfile string //SecurityOpts
+ SeccompProfilePath string //SecurityOpts
SecurityOpts []string
Rootfs string
LocalVolumes []string //Keeps track of the built-in volumes of container used in the --volumes-from flag
@@ -145,58 +143,59 @@ func (c *CreateConfig) CreateBlockIO() (*spec.LinuxBlockIO, error) {
return c.createBlockIO()
}
+func processOptions(options []string) []string {
+ var (
+ foundrw, foundro bool
+ rootProp string
+ )
+ options = append(options, "rbind")
+ for _, opt := range options {
+ switch opt {
+ case "rw":
+ foundrw = true
+ case "ro":
+ foundro = true
+ case "private", "rprivate", "slave", "rslave", "shared", "rshared":
+ rootProp = opt
+ }
+ }
+ if !foundrw && !foundro {
+ options = append(options, "rw")
+ }
+ if rootProp == "" {
+ options = append(options, "rprivate")
+ }
+ return options
+}
+
+func (c *CreateConfig) initFSMounts() []spec.Mount {
+ var mounts []spec.Mount
+ for _, m := range c.Mounts {
+ m.Options = processOptions(m.Options)
+ if m.Type == "tmpfs" {
+ m.Options = append(m.Options, "tmpcopyup")
+ } else {
+ mounts = append(mounts, m)
+ }
+ }
+ return mounts
+}
+
//GetVolumeMounts takes user provided input for bind mounts and creates Mount structs
func (c *CreateConfig) GetVolumeMounts(specMounts []spec.Mount) ([]spec.Mount, error) {
var m []spec.Mount
for _, i := range c.Volumes {
- var (
- options []string
- foundrw, foundro, foundz, foundZ bool
- rootProp string
- )
-
- // We need to handle SELinux options better here, specifically :Z
+ var options []string
spliti := strings.Split(i, ":")
if len(spliti) > 2 {
options = strings.Split(spliti[2], ",")
}
- options = append(options, "rbind")
- for _, opt := range options {
- switch opt {
- case "rw":
- foundrw = true
- case "ro":
- foundro = true
- case "z":
- foundz = true
- case "Z":
- foundZ = true
- case "private", "rprivate", "slave", "rslave", "shared", "rshared":
- rootProp = opt
- }
- }
- if !foundrw && !foundro {
- options = append(options, "rw")
- }
- if foundz {
- if err := label.Relabel(spliti[0], c.MountLabel, true); err != nil {
- return nil, errors.Wrapf(err, "relabel failed %q", spliti[0])
- }
- }
- if foundZ {
- if err := label.Relabel(spliti[0], c.MountLabel, false); err != nil {
- return nil, errors.Wrapf(err, "relabel failed %q", spliti[0])
- }
- }
- if rootProp == "" {
- options = append(options, "rprivate")
- }
m = append(m, spec.Mount{
Destination: spliti[1],
Type: string(TypeBind),
Source: spliti[0],
- Options: options,
+ Options: processOptions(options),
})
logrus.Debugf("User mount %s:%s options %v", spliti[0], spliti[1], options)
@@ -380,9 +379,9 @@ func (c *CreateConfig) GetContainerCreateOptions(runtime *libpod.Runtime) ([]lib
if IsNS(string(c.NetMode)) {
// pass
} else if c.NetMode.IsContainer() {
- connectedCtr, err := c.Runtime.LookupContainer(c.NetMode.ConnectedContainer())
+ connectedCtr, err := c.Runtime.LookupContainer(c.NetMode.Container())
if err != nil {
- return nil, errors.Wrapf(err, "container %q not found", c.NetMode.ConnectedContainer())
+ return nil, errors.Wrapf(err, "container %q not found", c.NetMode.Container())
}
options = append(options, libpod.WithNetNSFrom(connectedCtr))
} else if !c.NetMode.IsHost() && !c.NetMode.IsNone() {
@@ -449,11 +448,20 @@ func (c *CreateConfig) GetContainerCreateOptions(runtime *libpod.Runtime) ([]lib
useImageVolumes := c.ImageVolumeType == "bind"
// Gather up the options for NewContainer which consist of With... funcs
options = append(options, libpod.WithRootFSFromImage(c.ImageID, c.Image, useImageVolumes))
- options = append(options, libpod.WithSELinuxLabels(c.ProcessLabel, c.MountLabel))
+ options = append(options, libpod.WithSecLabels(c.LabelOpts))
options = append(options, libpod.WithConmonPidFile(c.ConmonPidFile))
options = append(options, libpod.WithLabels(c.Labels))
options = append(options, libpod.WithUser(c.User))
- options = append(options, libpod.WithShmDir(c.ShmDir))
+ if c.IpcMode.IsHost() {
+ options = append(options, libpod.WithShmDir("/dev/shm"))
+
+ } else if c.IpcMode.IsContainer() {
+ ctr, err := runtime.LookupContainer(c.IpcMode.Container())
+ if err != nil {
+ return nil, errors.Wrapf(err, "container %q not found", c.IpcMode.Container())
+ }
+ options = append(options, libpod.WithShmDir(ctr.ShmDir()))
+ }
options = append(options, libpod.WithShmSize(c.Resources.ShmSize))
options = append(options, libpod.WithGroups(c.GroupAdd))
options = append(options, libpod.WithIDMappings(*c.IDMappings))
diff --git a/pkg/spec/spec.go b/pkg/spec/spec.go
index cc3501e1e..ad14ea65d 100644
--- a/pkg/spec/spec.go
+++ b/pkg/spec/spec.go
@@ -18,6 +18,34 @@ import (
const cpuPeriod = 100000
+func supercedeUserMounts(mounts []spec.Mount, configMount []spec.Mount) []spec.Mount {
+ if len(mounts) > 0 {
+ // If we have overlappings mounts, remove them from the spec in favor of
+ // the user-added volume mounts
+ destinations := make(map[string]bool)
+ for _, mount := range mounts {
+ destinations[path.Clean(mount.Destination)] = true
+ }
+ // Copy all mounts from spec to defaultMounts, except for
+ // - mounts overridden by a user supplied mount;
+ // - all mounts under /dev if a user supplied /dev is present;
+ mountDev := destinations["/dev"]
+ for _, mount := range configMount {
+ if _, ok := destinations[path.Clean(mount.Destination)]; !ok {
+ if mountDev && strings.HasPrefix(mount.Destination, "/dev/") {
+ // filter out everything under /dev if /dev is user-mounted
+ continue
+ }
+
+ logrus.Debugf("Adding mount %s", mount.Destination)
+ mounts = append(mounts, mount)
+ }
+ }
+ return mounts
+ }
+ return configMount
+}
+
// CreateConfigToOCISpec parses information needed to create a container into an OCI runtime spec
func CreateConfigToOCISpec(config *CreateConfig) (*spec.Spec, error) { //nolint
cgroupPerm := "ro"
@@ -211,8 +239,6 @@ func CreateConfigToOCISpec(config *CreateConfig) (*spec.Spec, error) { //nolint
// SECURITY OPTS
g.SetProcessNoNewPrivileges(config.NoNewPrivs)
g.SetProcessApparmorProfile(config.ApparmorProfile)
- g.SetProcessSelinuxLabel(config.ProcessLabel)
- g.SetLinuxMountLabel(config.MountLabel)
if canAddResources {
blockAccessToKernelFilesystems(config, &g)
@@ -248,6 +274,12 @@ func CreateConfigToOCISpec(config *CreateConfig) (*spec.Spec, error) { //nolint
g.AddMount(tmpfsMnt)
}
+ for _, m := range config.Mounts {
+ if m.Type == "tmpfs" {
+ g.AddMount(m)
+ }
+ }
+
for name, val := range config.Env {
g.AddProcessEnv(name, val)
}
@@ -307,29 +339,14 @@ func CreateConfigToOCISpec(config *CreateConfig) (*spec.Spec, error) { //nolint
return nil, errors.Wrap(err, "error getting volume mounts from --volumes-from flag")
}
- mounts, err := config.GetVolumeMounts(configSpec.Mounts)
+ volumeMounts, err := config.GetVolumeMounts(configSpec.Mounts)
if err != nil {
return nil, errors.Wrapf(err, "error getting volume mounts")
}
- if len(mounts) > 0 {
- // If we have overlappings mounts, remove them from the spec in favor of
- // the user-added volume mounts
- destinations := make(map[string]bool)
- for _, mount := range mounts {
- destinations[path.Clean(mount.Destination)] = true
- }
- for _, mount := range configSpec.Mounts {
- if _, ok := destinations[path.Clean(mount.Destination)]; !ok {
- logrus.Debugf("Adding mount %s", mount.Destination)
- mounts = append(mounts, mount)
- }
- }
- configSpec.Mounts = mounts
- }
- if err := g.SetLinuxRootPropagation("shared"); err != nil {
- return nil, errors.Wrapf(err, "failed to set propagation to rslave")
- }
+ configSpec.Mounts = supercedeUserMounts(volumeMounts, configSpec.Mounts)
+ //--mount
+ configSpec.Mounts = supercedeUserMounts(config.initFSMounts(), configSpec.Mounts)
if canAddResources {
// BLOCK IO
blkio, err := config.CreateBlockIO()