summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd/podman/utils.go29
-rw-r--r--libpod/container_internal_linux.go10
-rw-r--r--libpod/oci_linux.go17
-rw-r--r--libpod/runtime_ctr.go5
-rw-r--r--test/e2e/run_userns_test.go15
5 files changed, 45 insertions, 31 deletions
diff --git a/cmd/podman/utils.go b/cmd/podman/utils.go
index 4ec0f8a13..45d081512 100644
--- a/cmd/podman/utils.go
+++ b/cmd/podman/utils.go
@@ -200,35 +200,6 @@ func getPodsFromContext(c *cliconfig.PodmanCommand, r *libpod.Runtime) ([]*libpo
return pods, lastError
}
-func getVolumesFromContext(c *cliconfig.PodmanCommand, r *libpod.Runtime) ([]*libpod.Volume, error) {
- args := c.InputArgs
- var (
- vols []*libpod.Volume
- lastError error
- err error
- )
-
- if c.Bool("all") {
- vols, err = r.Volumes()
- if err != nil {
- return nil, errors.Wrapf(err, "unable to get all volumes")
- }
- }
-
- for _, i := range args {
- vol, err := r.GetVolume(i)
- if err != nil {
- if lastError != nil {
- logrus.Errorf("%q", lastError)
- }
- lastError = errors.Wrapf(err, "unable to find volume %s", i)
- continue
- }
- vols = append(vols, vol)
- }
- return vols, lastError
-}
-
//printParallelOutput takes the map of parallel worker results and outputs them
// to stdout
func printParallelOutput(m map[string]error, errCount int) error {
diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go
index 2a7808bdf..c6c9ceb0c 100644
--- a/libpod/container_internal_linux.go
+++ b/libpod/container_internal_linux.go
@@ -203,7 +203,8 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) {
}
// Check if the spec file mounts contain the label Relabel flags z or Z.
// If they do, relabel the source directory and then remove the option.
- for _, m := range g.Mounts() {
+ for i := range g.Config.Mounts {
+ m := &g.Config.Mounts[i]
var options []string
for _, o := range m.Options {
switch o {
@@ -219,6 +220,13 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) {
}
}
m.Options = options
+
+ // If we are using a user namespace, we will use an intermediate
+ // directory to bind mount volumes
+ if c.state.UserNSRoot != "" && strings.HasPrefix(m.Source, c.runtime.config.VolumePath) {
+ newSourceDir := filepath.Join(c.state.UserNSRoot, "volumes")
+ m.Source = strings.Replace(m.Source, c.runtime.config.VolumePath, newSourceDir, 1)
+ }
}
g.SetProcessSelinuxLabel(c.ProcessLabel())
diff --git a/libpod/oci_linux.go b/libpod/oci_linux.go
index 2737a641e..f85c5ee62 100644
--- a/libpod/oci_linux.go
+++ b/libpod/oci_linux.go
@@ -106,6 +106,23 @@ func (r *OCIRuntime) createContainer(ctr *Container, cgroupParent string, restor
if err != nil {
return
}
+
+ if ctr.state.UserNSRoot != "" {
+ _, err := os.Stat(ctr.runtime.config.VolumePath)
+ if err != nil && !os.IsNotExist(err) {
+ return
+ }
+ if err == nil {
+ volumesTarget := filepath.Join(ctr.state.UserNSRoot, "volumes")
+ if err := idtools.MkdirAs(volumesTarget, 0700, ctr.RootUID(), ctr.RootGID()); err != nil {
+ return
+ }
+ if err = unix.Mount(ctr.runtime.config.VolumePath, volumesTarget, "none", unix.MS_BIND, ""); err != nil {
+ return
+ }
+ }
+ }
+
err = r.createOCIContainer(ctr, cgroupParent, restoreOptions)
}()
wg.Wait()
diff --git a/libpod/runtime_ctr.go b/libpod/runtime_ctr.go
index 3b74a65dd..f23dc86dd 100644
--- a/libpod/runtime_ctr.go
+++ b/libpod/runtime_ctr.go
@@ -186,8 +186,11 @@ func (r *Runtime) newContainer(ctx context.Context, rSpec *spec.Spec, options ..
return nil, errors.Wrapf(err, "error creating named volume %q", vol.Source)
}
ctr.config.Spec.Mounts[i].Source = newVol.MountPoint()
+ if err := os.Chown(ctr.config.Spec.Mounts[i].Source, ctr.RootUID(), ctr.RootGID()); err != nil {
+ return nil, errors.Wrapf(err, "cannot chown %q to %d:%d", ctr.config.Spec.Mounts[i].Source, ctr.RootUID(), ctr.RootGID())
+ }
if err := ctr.copyWithTarFromImage(ctr.config.Spec.Mounts[i].Destination, ctr.config.Spec.Mounts[i].Source); err != nil && !os.IsNotExist(err) {
- return nil, errors.Wrapf(err, "Failed to copy content into new volume mount %q", vol.Source)
+ return nil, errors.Wrapf(err, "failed to copy content into new volume mount %q", vol.Source)
}
continue
}
diff --git a/test/e2e/run_userns_test.go b/test/e2e/run_userns_test.go
index c6c94d2f6..5c38a8950 100644
--- a/test/e2e/run_userns_test.go
+++ b/test/e2e/run_userns_test.go
@@ -69,6 +69,21 @@ var _ = Describe("Podman UserNS support", func() {
Expect(ok).To(BeTrue())
})
+ It("podman uidmapping and gidmapping with a volume", func() {
+ if os.Getenv("SKIP_USERNS") != "" {
+ Skip("Skip userns tests.")
+ }
+ if _, err := os.Stat("/proc/self/uid_map"); err != nil {
+ Skip("User namespaces not supported.")
+ }
+
+ session := podmanTest.Podman([]string{"run", "--uidmap=0:1:70000", "--gidmap=0:20000:70000", "-v", "my-foo-volume:/foo:Z", "busybox", "echo", "hello"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ ok, _ := session.GrepString("hello")
+ Expect(ok).To(BeTrue())
+ })
+
It("podman uidmapping and gidmapping --net=host", func() {
if os.Getenv("SKIP_USERNS") != "" {
Skip("Skip userns tests.")