summaryrefslogtreecommitdiff
path: root/pkg/spec
diff options
context:
space:
mode:
authorDaniel J Walsh <dwalsh@redhat.com>2018-12-19 15:26:08 -0500
committerDaniel J Walsh <dwalsh@redhat.com>2018-12-21 10:28:14 -0500
commit1ad6f9af1552cbe2119af6cda83db5b3908556db (patch)
tree5dea01af8daf2f9a4017de2acff506e170508be0 /pkg/spec
parent4d1326240501312d60bce184db7f63d9e5cfae49 (diff)
downloadpodman-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.go50
-rw-r--r--pkg/spec/spec.go4
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
}
}