diff options
author | OpenShift Merge Robot <openshift-merge-robot@users.noreply.github.com> | 2019-09-02 11:06:04 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-09-02 11:06:04 -0700 |
commit | 099549bd38c2b39fb884c8e9aecdf4e44c90b484 (patch) | |
tree | cab48d4d0b099a60268968e5f6e2f887477de593 | |
parent | 03344fff1cd41c8a1cc8cec2ac3877b25505fb0c (diff) | |
parent | 759ca2cfc66c372dd197b4a2b6cf2b454b497d00 (diff) | |
download | podman-099549bd38c2b39fb884c8e9aecdf4e44c90b484.tar.gz podman-099549bd38c2b39fb884c8e9aecdf4e44c90b484.tar.bz2 podman-099549bd38c2b39fb884c8e9aecdf4e44c90b484.zip |
Merge pull request #3909 from giuseppe/rootless-bind-mount-dev
rootless: bind mount devices instead of creating them
-rw-r--r-- | pkg/spec/config_linux.go | 75 | ||||
-rw-r--r-- | test/e2e/run_device_test.go | 16 |
2 files changed, 77 insertions, 14 deletions
diff --git a/pkg/spec/config_linux.go b/pkg/spec/config_linux.go index 60d31d78e..32d8cb4de 100644 --- a/pkg/spec/config_linux.go +++ b/pkg/spec/config_linux.go @@ -4,6 +4,7 @@ package createconfig import ( "fmt" + "io/ioutil" "os" "path/filepath" "strings" @@ -98,6 +99,26 @@ func addDevice(g *generate.Generator, device string) error { if err != nil { return errors.Wrapf(err, "%s is not a valid device", src) } + if rootless.IsRootless() { + if _, err := os.Stat(src); err != nil { + if os.IsNotExist(err) { + return errors.Wrapf(err, "the specified device %s doesn't exist", src) + } + return errors.Wrapf(err, "stat device %s exist", src) + } + perm := "ro" + if strings.Contains(permissions, "w") { + perm = "rw" + } + devMnt := spec.Mount{ + Destination: dst, + Type: TypeBind, + Source: src, + Options: []string{"slave", "nosuid", "noexec", perm, "rbind"}, + } + g.Config.Mounts = append(g.Config.Mounts, devMnt) + return nil + } dev.Path = dst linuxdev := spec.LinuxDevice{ Path: dev.Path, @@ -113,8 +134,53 @@ func addDevice(g *generate.Generator, device string) error { return nil } +// based on getDevices from runc (libcontainer/devices/devices.go) +func getDevices(path string) ([]*configs.Device, error) { + files, err := ioutil.ReadDir(path) + if err != nil { + if rootless.IsRootless() && os.IsPermission(err) { + return nil, nil + } + return nil, err + } + out := []*configs.Device{} + for _, f := range files { + switch { + case f.IsDir(): + switch f.Name() { + // ".lxc" & ".lxd-mounts" added to address https://github.com/lxc/lxd/issues/2825 + case "pts", "shm", "fd", "mqueue", ".lxc", ".lxd-mounts": + continue + default: + sub, err := getDevices(filepath.Join(path, f.Name())) + if err != nil { + return nil, err + } + if sub != nil { + out = append(out, sub...) + } + continue + } + case f.Name() == "console": + continue + } + device, err := devices.DeviceFromPath(filepath.Join(path, f.Name()), "rwm") + if err != nil { + if err == devices.ErrNotADevice { + continue + } + if os.IsNotExist(err) { + continue + } + return nil, err + } + out = append(out, device) + } + return out, nil +} + func (c *CreateConfig) addPrivilegedDevices(g *generate.Generator) error { - hostDevices, err := devices.HostDevices() + hostDevices, err := getDevices("/dev") if err != nil { return err } @@ -153,15 +219,16 @@ func (c *CreateConfig) addPrivilegedDevices(g *generate.Generator) error { newMounts = append(newMounts, devMnt) } g.Config.Mounts = append(newMounts, g.Config.Mounts...) + g.Config.Linux.Resources.Devices = nil } else { for _, d := range hostDevices { g.AddDevice(Device(d)) } + // Add resources device - need to clear the existing one first. + g.Config.Linux.Resources.Devices = nil + g.AddLinuxResourcesDevice(true, "", nil, nil, "rwm") } - // Add resources device - need to clear the existing one first. - g.Config.Linux.Resources.Devices = nil - g.AddLinuxResourcesDevice(true, "", nil, nil, "rwm") return nil } diff --git a/test/e2e/run_device_test.go b/test/e2e/run_device_test.go index cf7ce9cdf..d3b4b0e32 100644 --- a/test/e2e/run_device_test.go +++ b/test/e2e/run_device_test.go @@ -35,44 +35,40 @@ var _ = Describe("Podman run device", func() { }) It("podman run bad device test", func() { - session := podmanTest.Podman([]string{"run", "-q", "--device", "/dev/baddevice", ALPINE, "ls", "/dev/kmsg"}) + session := podmanTest.Podman([]string{"run", "-q", "--device", "/dev/baddevice", ALPINE, "true"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Not(Equal(0))) }) It("podman run device test", func() { - SkipIfRootless() - session := podmanTest.Podman([]string{"run", "-q", "--device", "/dev/kmsg", ALPINE, "ls", "--color=never", "/dev/kmsg"}) + session := podmanTest.Podman([]string{"run", "-q", "--security-opt", "label=disable", "--device", "/dev/kmsg", ALPINE, "ls", "--color=never", "/dev/kmsg"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) Expect(session.OutputToString()).To(Equal("/dev/kmsg")) }) It("podman run device rename test", func() { - SkipIfRootless() - session := podmanTest.Podman([]string{"run", "-q", "--device", "/dev/kmsg:/dev/kmsg1", ALPINE, "ls", "--color=never", "/dev/kmsg1"}) + session := podmanTest.Podman([]string{"run", "-q", "--security-opt", "label=disable", "--device", "/dev/kmsg:/dev/kmsg1", ALPINE, "ls", "--color=never", "/dev/kmsg1"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) Expect(session.OutputToString()).To(Equal("/dev/kmsg1")) }) It("podman run device permission test", func() { - SkipIfRootless() - session := podmanTest.Podman([]string{"run", "-q", "--device", "/dev/kmsg:r", ALPINE, "ls", "--color=never", "/dev/kmsg"}) + session := podmanTest.Podman([]string{"run", "-q", "--security-opt", "label=disable", "--device", "/dev/kmsg:r", ALPINE, "ls", "--color=never", "/dev/kmsg"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) Expect(session.OutputToString()).To(Equal("/dev/kmsg")) }) It("podman run device rename and permission test", func() { - SkipIfRootless() - session := podmanTest.Podman([]string{"run", "-q", "--device", "/dev/kmsg:/dev/kmsg1:r", ALPINE, "ls", "--color=never", "/dev/kmsg1"}) + session := podmanTest.Podman([]string{"run", "-q", "--security-opt", "label=disable", "--device", "/dev/kmsg:/dev/kmsg1:r", ALPINE, "ls", "--color=never", "/dev/kmsg1"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) Expect(session.OutputToString()).To(Equal("/dev/kmsg1")) }) It("podman run device rename and bad permission test", func() { - session := podmanTest.Podman([]string{"run", "-q", "--device", "/dev/kmsg:/dev/kmsg1:rd", ALPINE, "ls", "--color=never", "/dev/kmsg1"}) + session := podmanTest.Podman([]string{"run", "-q", "--security-opt", "label=disable", "--device", "/dev/kmsg:/dev/kmsg1:rd", ALPINE, "ls", "--color=never", "/dev/kmsg1"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Not(Equal(0))) }) |