diff options
author | Daniel J Walsh <dwalsh@redhat.com> | 2018-12-19 15:26:08 -0500 |
---|---|---|
committer | Daniel J Walsh <dwalsh@redhat.com> | 2018-12-21 10:28:14 -0500 |
commit | 1ad6f9af1552cbe2119af6cda83db5b3908556db (patch) | |
tree | 5dea01af8daf2f9a4017de2acff506e170508be0 /pkg/spec | |
parent | 4d1326240501312d60bce184db7f63d9e5cfae49 (diff) | |
download | podman-1ad6f9af1552cbe2119af6cda83db5b3908556db.tar.gz podman-1ad6f9af1552cbe2119af6cda83db5b3908556db.tar.bz2 podman-1ad6f9af1552cbe2119af6cda83db5b3908556db.zip |
Allow users to specify a directory for additonal devices
Podman will search through the directory and will add any device
nodes that it finds. If no devices are found we return an error.
Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
Diffstat (limited to 'pkg/spec')
-rw-r--r-- | pkg/spec/config_linux.go | 50 | ||||
-rw-r--r-- | pkg/spec/spec.go | 4 |
2 files changed, 52 insertions, 2 deletions
diff --git a/pkg/spec/config_linux.go b/pkg/spec/config_linux.go index 5bf8eff43..f3e200262 100644 --- a/pkg/spec/config_linux.go +++ b/pkg/spec/config_linux.go @@ -3,7 +3,11 @@ package createconfig import ( + "fmt" "io/ioutil" + "os" + "path/filepath" + "strings" "github.com/docker/docker/profiles/seccomp" "github.com/opencontainers/runc/libcontainer/configs" @@ -27,6 +31,52 @@ func Device(d *configs.Device) spec.LinuxDevice { } } +// devicesFromPath computes a list of devices +func devicesFromPath(g *generate.Generator, devicePath string) error { + devs := strings.Split(devicePath, ":") + resolvedDevicePath := devs[0] + // check if it is a symbolic link + if src, err := os.Lstat(resolvedDevicePath); err == nil && src.Mode()&os.ModeSymlink == os.ModeSymlink { + if linkedPathOnHost, err := filepath.EvalSymlinks(resolvedDevicePath); err == nil { + resolvedDevicePath = linkedPathOnHost + } + } + st, err := os.Stat(resolvedDevicePath) + if err != nil { + return errors.Wrapf(err, "cannot stat %s", devicePath) + } + if st.IsDir() { + if len(devs) > 2 { + return errors.Wrapf(unix.EINVAL, "not allowed to specify destination with a directory %s", devicePath) + } + found := false + // mount the internal devices recursively + if err := filepath.Walk(resolvedDevicePath, func(dpath string, f os.FileInfo, e error) error { + + if f.Mode()&os.ModeDevice == os.ModeDevice { + found = true + device := dpath + + if len(devs) > 1 { + device = fmt.Sprintf("%s:%s", dpath, devs[1]) + } + if err := addDevice(g, device); err != nil { + return errors.Wrapf(err, "failed to add %s device", dpath) + } + } + return nil + }); err != nil { + return err + } + if !found { + return errors.Wrapf(unix.EINVAL, "no devices found in %s", devicePath) + } + return nil + } + + return addDevice(g, devicePath) +} + func addDevice(g *generate.Generator, device string) error { src, dst, permissions, err := ParseDevice(device) if err != nil { diff --git a/pkg/spec/spec.go b/pkg/spec/spec.go index 05be00864..c90f16f7c 100644 --- a/pkg/spec/spec.go +++ b/pkg/spec/spec.go @@ -235,8 +235,8 @@ func CreateConfigToOCISpec(config *CreateConfig) (*spec.Spec, error) { //nolint } } } else { - for _, device := range config.Devices { - if err := addDevice(&g, device); err != nil { + for _, devicePath := range config.Devices { + if err := devicesFromPath(&g, devicePath); err != nil { return nil, err } } |