mirror of
https://github.com/containers/podman.git
synced 2025-07-01 00:01:02 +08:00
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>
This commit is contained in:
@ -3,7 +3,11 @@
|
|||||||
package createconfig
|
package createconfig
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/docker/docker/profiles/seccomp"
|
"github.com/docker/docker/profiles/seccomp"
|
||||||
"github.com/opencontainers/runc/libcontainer/configs"
|
"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 {
|
func addDevice(g *generate.Generator, device string) error {
|
||||||
src, dst, permissions, err := ParseDevice(device)
|
src, dst, permissions, err := ParseDevice(device)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -235,8 +235,8 @@ func CreateConfigToOCISpec(config *CreateConfig) (*spec.Spec, error) { //nolint
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for _, device := range config.Devices {
|
for _, devicePath := range config.Devices {
|
||||||
if err := addDevice(&g, device); err != nil {
|
if err := devicesFromPath(&g, devicePath); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user