summaryrefslogtreecommitdiff
path: root/pkg
diff options
context:
space:
mode:
authorOpenShift Merge Robot <openshift-merge-robot@users.noreply.github.com>2018-12-21 12:09:46 -0800
committerGitHub <noreply@github.com>2018-12-21 12:09:46 -0800
commitfe186c6ebba95db89463f38c6aa0f0dcc104a249 (patch)
treed2a815c62bae205b0ea80ac72ec72542c98131ce /pkg
parentfa568e04d6b6032ca3bdf39ee4fd1ca1856be85a (diff)
parent1ad6f9af1552cbe2119af6cda83db5b3908556db (diff)
downloadpodman-fe186c6ebba95db89463f38c6aa0f0dcc104a249.tar.gz
podman-fe186c6ebba95db89463f38c6aa0f0dcc104a249.tar.bz2
podman-fe186c6ebba95db89463f38c6aa0f0dcc104a249.zip
Merge pull request #2033 from rhatdan/devices
Allow users to specify a directory for additonal devices
Diffstat (limited to 'pkg')
-rw-r--r--pkg/namespaces/namespaces.go2
-rw-r--r--pkg/spec/config_linux.go50
-rw-r--r--pkg/spec/parse.go2
-rw-r--r--pkg/spec/spec.go4
4 files changed, 54 insertions, 4 deletions
diff --git a/pkg/namespaces/namespaces.go b/pkg/namespaces/namespaces.go
index 832efd554..11b47fec4 100644
--- a/pkg/namespaces/namespaces.go
+++ b/pkg/namespaces/namespaces.go
@@ -84,7 +84,7 @@ func (n UTSMode) Valid() bool {
// IpcMode represents the container ipc stack.
type IpcMode string
-// IsPrivate indicates whether the container uses its own private ipc namespace which can not be shared.
+// IsPrivate indicates whether the container uses its own private ipc namespace which cannot be shared.
func (n IpcMode) IsPrivate() bool {
return n == "private"
}
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/parse.go b/pkg/spec/parse.go
index 4d20e35d4..d688b8d1b 100644
--- a/pkg/spec/parse.go
+++ b/pkg/spec/parse.go
@@ -166,7 +166,7 @@ func ParseDevice(device string) (string, string, string, error) { //nolint
permissions = arr[1]
} else {
if arr[1][0] != '/' {
- return "", "", "", fmt.Errorf("invalid device mode: %s", arr[2])
+ return "", "", "", fmt.Errorf("invalid device mode: %s", arr[1])
}
dst = arr[1]
}
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
}
}