mirror of
https://github.com/containers/podman.git
synced 2025-06-19 00:06:43 +08:00
Merge pull request #2033 from rhatdan/devices
Allow users to specify a directory for additonal devices
This commit is contained in:
@ -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 {
|
||||
|
@ -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]
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user