diff options
Diffstat (limited to 'pkg/spec')
-rw-r--r-- | pkg/spec/createconfig.go | 72 | ||||
-rw-r--r-- | pkg/spec/spec.go | 58 |
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 |