summaryrefslogtreecommitdiff
path: root/pkg/spec
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/spec')
-rw-r--r--pkg/spec/createconfig.go72
-rw-r--r--pkg/spec/spec.go58
2 files changed, 113 insertions, 17 deletions
diff --git a/pkg/spec/createconfig.go b/pkg/spec/createconfig.go
index 344f4afb9..50e07ee74 100644
--- a/pkg/spec/createconfig.go
+++ b/pkg/spec/createconfig.go
@@ -13,6 +13,7 @@ import (
"github.com/containers/libpod/pkg/namespaces"
"github.com/containers/libpod/pkg/rootless"
"github.com/containers/storage"
+ "github.com/containers/storage/pkg/stringid"
"github.com/cri-o/ocicni/pkg/ocicni"
"github.com/docker/go-connections/nat"
spec "github.com/opencontainers/runtime-spec/specs-go"
@@ -134,8 +135,8 @@ type CreateConfig struct {
SeccompProfilePath string //SecurityOpts
SecurityOpts []string
Rootfs string
- LocalVolumes []string //Keeps track of the built-in volumes of container used in the --volumes-from flag
- Syslog bool // Whether to enable syslog on exit commands
+ LocalVolumes []spec.Mount //Keeps track of the built-in volumes of container used in the --volumes-from flag
+ Syslog bool // Whether to enable syslog on exit commands
}
func u32Ptr(i int64) *uint32 { u := uint32(i); return &u }
@@ -216,7 +217,7 @@ func (c *CreateConfig) initFSMounts() []spec.Mount {
//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
+ m := c.LocalVolumes
for _, i := range c.Volumes {
var options []string
spliti := strings.Split(i, ":")
@@ -234,22 +235,31 @@ func (c *CreateConfig) GetVolumeMounts(specMounts []spec.Mount) ([]spec.Mount, e
logrus.Debugf("User mount %s:%s options %v", spliti[0], spliti[1], options)
}
- // volumes from image config
- if c.ImageVolumeType != "tmpfs" {
+ if c.ImageVolumeType == "ignore" {
return m, nil
}
+
for vol := range c.BuiltinImgVolumes {
if libpod.MountExists(specMounts, vol) {
continue
}
+
mount := spec.Mount{
Destination: vol,
- Type: string(TypeTmpfs),
- Source: string(TypeTmpfs),
- Options: []string{"rprivate", "rw", "noexec", "nosuid", "nodev", "tmpcopyup"},
+ Type: c.ImageVolumeType,
+ Options: []string{"rprivate", "rw", "nodev"},
+ }
+ if c.ImageVolumeType == "tmpfs" {
+ mount.Source = "tmpfs"
+ mount.Options = append(mount.Options, "tmpcopyup")
+ } else {
+ // This will cause a new local Volume to be created on your system
+ mount.Source = stringid.GenerateNonCryptoID()
+ mount.Options = append(mount.Options, "bind")
}
m = append(m, mount)
}
+
return m, nil
}
@@ -257,6 +267,11 @@ func (c *CreateConfig) GetVolumeMounts(specMounts []spec.Mount) ([]spec.Mount, e
// and adds it to c.Volumes of the current container.
func (c *CreateConfig) GetVolumesFrom() error {
var options string
+
+ if rootless.SkipStorageSetup() {
+ return nil
+ }
+
for _, vol := range c.VolumesFrom {
splitVol := strings.SplitN(vol, ":", 2)
if len(splitVol) == 2 {
@@ -266,6 +281,10 @@ func (c *CreateConfig) GetVolumesFrom() error {
if err != nil {
return errors.Wrapf(err, "error looking up container %q", splitVol[0])
}
+ inspect, err := ctr.Inspect(false)
+ if err != nil {
+ return errors.Wrapf(err, "error inspecting %q", splitVol[0])
+ }
var createArtifact CreateConfig
artifact, err := ctr.GetArtifact("create-config")
if err != nil {
@@ -274,9 +293,13 @@ func (c *CreateConfig) GetVolumesFrom() error {
if err := json.Unmarshal(artifact, &createArtifact); err != nil {
return err
}
-
for key := range createArtifact.BuiltinImgVolumes {
- c.LocalVolumes = append(c.LocalVolumes, key)
+ for _, m := range inspect.Mounts {
+ if m.Destination == key {
+ c.LocalVolumes = append(c.LocalVolumes, m)
+ break
+ }
+ }
}
for _, i := range createArtifact.Volumes {
@@ -331,13 +354,22 @@ func (c *CreateConfig) createExitCommand() []string {
"--cgroup-manager", config.CgroupManager,
"--tmpdir", config.TmpDir,
}
+ if config.OCIRuntime != "" {
+ command = append(command, []string{"--runtime", config.OCIRuntime}...)
+ }
if config.StorageConfig.GraphDriverName != "" {
command = append(command, []string{"--storage-driver", config.StorageConfig.GraphDriverName}...)
}
if c.Syslog {
command = append(command, "--syslog")
}
- return append(command, []string{"container", "cleanup"}...)
+ command = append(command, []string{"container", "cleanup"}...)
+
+ if c.Rm {
+ command = append(command, "--rm")
+ }
+
+ return command
}
// GetContainerCreateOptions takes a CreateConfig and returns a slice of CtrCreateOptions
@@ -414,7 +446,15 @@ func (c *CreateConfig) GetContainerCreateOptions(runtime *libpod.Runtime, pod *l
}
if IsNS(string(c.NetMode)) {
- // pass
+ split := strings.SplitN(string(c.NetMode), ":", 2)
+ if len(split[0]) != 2 {
+ return nil, errors.Errorf("invalid user defined network namespace %q", c.NetMode.UserDefined())
+ }
+ _, err := os.Stat(split[1])
+ if err != nil {
+ return nil, err
+ }
+ options = append(options, libpod.WithNetNS(portBindings, false, string(c.NetMode), networks))
} else if c.NetMode.IsContainer() {
connectedCtr, err := c.Runtime.LookupContainer(c.NetMode.Container())
if err != nil {
@@ -515,11 +555,9 @@ func (c *CreateConfig) GetContainerCreateOptions(runtime *libpod.Runtime, pod *l
if c.CgroupParent != "" {
options = append(options, libpod.WithCgroupParent(c.CgroupParent))
}
- // For a rootless container always cleanup the storage/network as they
- // run in a different namespace thus not reusable when we restart.
- if c.Detach || rootless.IsRootless() {
- options = append(options, libpod.WithExitCommand(c.createExitCommand()))
- }
+
+ // Always use a cleanup process to clean up Podman after termination
+ options = append(options, libpod.WithExitCommand(c.createExitCommand()))
return options, nil
}
diff --git a/pkg/spec/spec.go b/pkg/spec/spec.go
index 76b8963ff..28a636fa6 100644
--- a/pkg/spec/spec.go
+++ b/pkg/spec/spec.go
@@ -3,10 +3,12 @@ package createconfig
import (
"os"
"path"
+ "path/filepath"
"strings"
"github.com/containers/libpod/pkg/rootless"
"github.com/containers/storage/pkg/mount"
+ pmount "github.com/containers/storage/pkg/mount"
"github.com/docker/docker/daemon/caps"
"github.com/docker/go-units"
"github.com/opencontainers/runc/libcontainer/user"
@@ -392,9 +394,65 @@ func CreateConfigToOCISpec(config *CreateConfig) (*spec.Spec, error) { //nolint
configSpec.Linux.Resources = &spec.LinuxResources{}
}
+ // Make sure that the bind mounts keep options like nosuid, noexec, nodev.
+ mounts, err := pmount.GetMounts()
+ if err != nil {
+ return nil, err
+ }
+ for i := range configSpec.Mounts {
+ m := &configSpec.Mounts[i]
+ isBind := false
+ for _, o := range m.Options {
+ if o == "bind" || o == "rbind" {
+ isBind = true
+ break
+ }
+ }
+ if !isBind {
+ continue
+ }
+ mount, err := findMount(m.Source, mounts)
+ if err != nil {
+ return nil, err
+ }
+ if mount == nil {
+ continue
+ }
+ next_option:
+ for _, o := range strings.Split(mount.Opts, ",") {
+ if o == "nosuid" || o == "noexec" || o == "nodev" {
+ for _, e := range m.Options {
+ if e == o {
+ continue next_option
+ }
+ }
+ m.Options = append(m.Options, o)
+ }
+ }
+ }
+
return configSpec, nil
}
+func findMount(target string, mounts []*pmount.Info) (*pmount.Info, error) {
+ var err error
+ target, err = filepath.Abs(target)
+ if err != nil {
+ return nil, errors.Wrapf(err, "cannot resolve %s", target)
+ }
+ var bestSoFar *pmount.Info
+ for _, i := range mounts {
+ if bestSoFar != nil && len(bestSoFar.Mountpoint) > len(i.Mountpoint) {
+ // Won't be better than what we have already found
+ continue
+ }
+ if strings.HasPrefix(target, i.Mountpoint) {
+ bestSoFar = i
+ }
+ }
+ return bestSoFar, nil
+}
+
func blockAccessToKernelFilesystems(config *CreateConfig, g *generate.Generator) {
if config.PidMode.IsHost() && rootless.IsRootless() {
return