summaryrefslogtreecommitdiff
path: root/pkg
diff options
context:
space:
mode:
Diffstat (limited to 'pkg')
-rw-r--r--pkg/spec/config_linux.go9
-rw-r--r--pkg/spec/parse.go55
2 files changed, 62 insertions, 2 deletions
diff --git a/pkg/spec/config_linux.go b/pkg/spec/config_linux.go
index cd633bc69..ea04b95bd 100644
--- a/pkg/spec/config_linux.go
+++ b/pkg/spec/config_linux.go
@@ -28,10 +28,15 @@ func Device(d *configs.Device) spec.LinuxDevice {
}
func addDevice(g *generate.Generator, device string) error {
- dev, err := devices.DeviceFromPath(device, "rwm")
+ src, dst, permissions, err := parseDevice(device)
if err != nil {
- return errors.Wrapf(err, "%s is not a valid device", device)
+ return err
+ }
+ dev, err := devices.DeviceFromPath(src, permissions)
+ if err != nil {
+ return errors.Wrapf(err, "%s is not a valid device", src)
}
+ dev.Path = dst
linuxdev := spec.LinuxDevice{
Path: dev.Path,
Type: string(dev.Type),
diff --git a/pkg/spec/parse.go b/pkg/spec/parse.go
index d4a655e4f..d34e10760 100644
--- a/pkg/spec/parse.go
+++ b/pkg/spec/parse.go
@@ -126,3 +126,58 @@ func getLoggingPath(opts []string) string {
}
return ""
}
+
+// parseDevice parses device mapping string to a src, dest & permissions string
+func parseDevice(device string) (string, string, string, error) { //nolint
+ src := ""
+ dst := ""
+ permissions := "rwm"
+ arr := strings.Split(device, ":")
+ switch len(arr) {
+ case 3:
+ if !validDeviceMode(arr[2]) {
+ return "", "", "", fmt.Errorf("invalid device mode: %s", arr[2])
+ }
+ permissions = arr[2]
+ fallthrough
+ case 2:
+ if validDeviceMode(arr[1]) {
+ permissions = arr[1]
+ } else {
+ if arr[1][0] != '/' {
+ return "", "", "", fmt.Errorf("invalid device mode: %s", arr[2])
+ }
+ dst = arr[1]
+ }
+ fallthrough
+ case 1:
+ src = arr[0]
+ default:
+ return "", "", "", fmt.Errorf("invalid device specification: %s", device)
+ }
+
+ if dst == "" {
+ dst = src
+ }
+ return src, dst, permissions, nil
+}
+
+// validDeviceMode checks if the mode for device is valid or not.
+// Valid mode is a composition of r (read), w (write), and m (mknod).
+func validDeviceMode(mode string) bool {
+ var legalDeviceMode = map[rune]bool{
+ 'r': true,
+ 'w': true,
+ 'm': true,
+ }
+ if mode == "" {
+ return false
+ }
+ for _, c := range mode {
+ if !legalDeviceMode[c] {
+ return false
+ }
+ legalDeviceMode[c] = false
+ }
+ return true
+}