Add support for adding devices to container
Also add --quiet option to kpod create/run since this will help with writing tests. Signed-off-by: Daniel J Walsh <dwalsh@redhat.com> Closes: #140 Approved by: TomSweeneyRedHat
This commit is contained in:
		
							parent
							
								
									c0432eb0e8
								
							
						
					
					
						commit
						94a8107515
					
				|  | @ -362,6 +362,10 @@ var createFlags = []cli.Flag{ | ||||||
| 		Name:  "publish-all, P", | 		Name:  "publish-all, P", | ||||||
| 		Usage: "Publish all exposed ports to random ports on the host interface", | 		Usage: "Publish all exposed ports to random ports on the host interface", | ||||||
| 	}, | 	}, | ||||||
|  | 	cli.BoolFlag{ | ||||||
|  | 		Name:  "quiet, q", | ||||||
|  | 		Usage: "Suppress output information when pulling images", | ||||||
|  | 	}, | ||||||
| 	cli.BoolFlag{ | 	cli.BoolFlag{ | ||||||
| 		Name:  "read-only", | 		Name:  "read-only", | ||||||
| 		Usage: "Make containers root filesystem read-only", | 		Usage: "Make containers root filesystem read-only", | ||||||
|  |  | ||||||
|  | @ -3,6 +3,7 @@ package main | ||||||
| import ( | import ( | ||||||
| 	"encoding/json" | 	"encoding/json" | ||||||
| 	"fmt" | 	"fmt" | ||||||
|  | 	"io" | ||||||
| 	"os" | 	"os" | ||||||
| 	"strconv" | 	"strconv" | ||||||
| 	"strings" | 	"strings" | ||||||
|  | @ -14,7 +15,6 @@ import ( | ||||||
| 	"github.com/projectatomic/libpod/libpod" | 	"github.com/projectatomic/libpod/libpod" | ||||||
| 	"github.com/sirupsen/logrus" | 	"github.com/sirupsen/logrus" | ||||||
| 	"github.com/urfave/cli" | 	"github.com/urfave/cli" | ||||||
| 	pb "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime" |  | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| type mountType string | type mountType string | ||||||
|  | @ -72,7 +72,7 @@ type createConfig struct { | ||||||
| 	CgroupParent       string // cgroup-parent
 | 	CgroupParent       string // cgroup-parent
 | ||||||
| 	Command            []string | 	Command            []string | ||||||
| 	Detach             bool              // detach
 | 	Detach             bool              // detach
 | ||||||
| 	Devices            []*pb.Device      // device
 | 	Devices            []string          // device
 | ||||||
| 	DNSOpt             []string          //dns-opt
 | 	DNSOpt             []string          //dns-opt
 | ||||||
| 	DNSSearch          []string          //dns-search
 | 	DNSSearch          []string          //dns-search
 | ||||||
| 	DNSServers         []string          //dns
 | 	DNSServers         []string          //dns
 | ||||||
|  | @ -101,6 +101,7 @@ type createConfig struct { | ||||||
| 	Privileged         bool     //privileged
 | 	Privileged         bool     //privileged
 | ||||||
| 	Publish            []string //publish
 | 	Publish            []string //publish
 | ||||||
| 	PublishAll         bool     //publish-all
 | 	PublishAll         bool     //publish-all
 | ||||||
|  | 	Quiet              bool     //quiet
 | ||||||
| 	ReadOnlyRootfs     bool     //read-only
 | 	ReadOnlyRootfs     bool     //read-only
 | ||||||
| 	Resources          createResourceConfig | 	Resources          createResourceConfig | ||||||
| 	Rm                 bool //rm
 | 	Rm                 bool //rm
 | ||||||
|  | @ -167,8 +168,11 @@ func createCmd(c *cli.Context) error { | ||||||
| 	if createImage.LocalName == "" { | 	if createImage.LocalName == "" { | ||||||
| 		// The image wasnt found by the user input'd name or its fqname
 | 		// The image wasnt found by the user input'd name or its fqname
 | ||||||
| 		// Pull the image
 | 		// Pull the image
 | ||||||
| 		fmt.Printf("Trying to pull %s...", createImage.PullName) | 		var writer io.Writer | ||||||
| 		createImage.Pull() | 		if !createConfig.Quiet { | ||||||
|  | 			writer = os.Stdout | ||||||
|  | 		} | ||||||
|  | 		createImage.Pull(writer) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	runtimeSpec, err := createConfigToOCISpec(createConfig) | 	runtimeSpec, err := createConfigToOCISpec(createConfig) | ||||||
|  | @ -419,6 +423,7 @@ func parseCreateOpts(c *cli.Context, runtime *libpod.Runtime) (*createConfig, er | ||||||
| 		CgroupParent:   c.String("cgroup-parent"), | 		CgroupParent:   c.String("cgroup-parent"), | ||||||
| 		Command:        command, | 		Command:        command, | ||||||
| 		Detach:         c.Bool("detach"), | 		Detach:         c.Bool("detach"), | ||||||
|  | 		Devices:        c.StringSlice("device"), | ||||||
| 		DNSOpt:         c.StringSlice("dns-opt"), | 		DNSOpt:         c.StringSlice("dns-opt"), | ||||||
| 		DNSSearch:      c.StringSlice("dns-search"), | 		DNSSearch:      c.StringSlice("dns-search"), | ||||||
| 		DNSServers:     c.StringSlice("dns"), | 		DNSServers:     c.StringSlice("dns"), | ||||||
|  | @ -447,6 +452,7 @@ func parseCreateOpts(c *cli.Context, runtime *libpod.Runtime) (*createConfig, er | ||||||
| 		Privileged:     c.Bool("privileged"), | 		Privileged:     c.Bool("privileged"), | ||||||
| 		Publish:        c.StringSlice("publish"), | 		Publish:        c.StringSlice("publish"), | ||||||
| 		PublishAll:     c.Bool("publish-all"), | 		PublishAll:     c.Bool("publish-all"), | ||||||
|  | 		Quiet:          c.Bool("quiet"), | ||||||
| 		ReadOnlyRootfs: c.Bool("read-only"), | 		ReadOnlyRootfs: c.Bool("read-only"), | ||||||
| 		Resources: createResourceConfig{ | 		Resources: createResourceConfig{ | ||||||
| 			BlkioWeight:       blkioWeight, | 			BlkioWeight:       blkioWeight, | ||||||
|  |  | ||||||
|  | @ -2,6 +2,8 @@ package main | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"fmt" | 	"fmt" | ||||||
|  | 	"io" | ||||||
|  | 	"os" | ||||||
| 	"sync" | 	"sync" | ||||||
| 
 | 
 | ||||||
| 	"github.com/pkg/errors" | 	"github.com/pkg/errors" | ||||||
|  | @ -44,7 +46,11 @@ func runCmd(c *cli.Context) error { | ||||||
| 	if createImage.LocalName == "" { | 	if createImage.LocalName == "" { | ||||||
| 		// The image wasnt found by the user input'd name or its fqname
 | 		// The image wasnt found by the user input'd name or its fqname
 | ||||||
| 		// Pull the image
 | 		// Pull the image
 | ||||||
| 		createImage.Pull() | 		var writer io.Writer | ||||||
|  | 		if !createConfig.Quiet { | ||||||
|  | 			writer = os.Stdout | ||||||
|  | 		} | ||||||
|  | 		createImage.Pull(writer) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	runtimeSpec, err := createConfigToOCISpec(createConfig) | 	runtimeSpec, err := createConfigToOCISpec(createConfig) | ||||||
|  |  | ||||||
|  | @ -10,6 +10,7 @@ import ( | ||||||
| 	"github.com/docker/docker/daemon/caps" | 	"github.com/docker/docker/daemon/caps" | ||||||
| 	"github.com/docker/docker/pkg/mount" | 	"github.com/docker/docker/pkg/mount" | ||||||
| 	"github.com/docker/go-units" | 	"github.com/docker/go-units" | ||||||
|  | 	"github.com/opencontainers/runc/libcontainer/devices" | ||||||
| 	spec "github.com/opencontainers/runtime-spec/specs-go" | 	spec "github.com/opencontainers/runtime-spec/specs-go" | ||||||
| 	"github.com/opencontainers/runtime-tools/generate" | 	"github.com/opencontainers/runtime-tools/generate" | ||||||
| 	"github.com/opencontainers/selinux/go-selinux/label" | 	"github.com/opencontainers/selinux/go-selinux/label" | ||||||
|  | @ -163,6 +164,25 @@ func setupCapabilities(config *createConfig, configSpec *spec.Spec) error { | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func addDevice(g *generate.Generator, device string) error { | ||||||
|  | 	dev, err := devices.DeviceFromPath(device, "rwm") | ||||||
|  | 	if err != nil { | ||||||
|  | 		return errors.Wrapf(err, "%s is not a valid device", device) | ||||||
|  | 	} | ||||||
|  | 	linuxdev := spec.LinuxDevice{ | ||||||
|  | 		Path:     dev.Path, | ||||||
|  | 		Type:     string(dev.Type), | ||||||
|  | 		Major:    dev.Major, | ||||||
|  | 		Minor:    dev.Minor, | ||||||
|  | 		FileMode: &dev.FileMode, | ||||||
|  | 		UID:      &dev.Uid, | ||||||
|  | 		GID:      &dev.Gid, | ||||||
|  | 	} | ||||||
|  | 	g.AddDevice(linuxdev) | ||||||
|  | 	g.AddLinuxResourcesDevice(true, string(dev.Type), &dev.Major, &dev.Minor, dev.Permissions) | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // Parses information needed to create a container into an OCI runtime spec
 | // Parses information needed to create a container into an OCI runtime spec
 | ||||||
| func createConfigToOCISpec(config *createConfig) (*spec.Spec, error) { | func createConfigToOCISpec(config *createConfig) (*spec.Spec, error) { | ||||||
| 	g := generate.New() | 	g := generate.New() | ||||||
|  | @ -233,6 +253,13 @@ func createConfigToOCISpec(config *createConfig) (*spec.Spec, error) { | ||||||
| 		g.SetLinuxResourcesCPUMems(config.Resources.CPUsetMems) | 		g.SetLinuxResourcesCPUMems(config.Resources.CPUsetMems) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	// Devices
 | ||||||
|  | 	for _, device := range config.Devices { | ||||||
|  | 		if err := addDevice(&g, device); err != nil { | ||||||
|  | 			return nil, err | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	// SECURITY OPTS
 | 	// SECURITY OPTS
 | ||||||
| 	g.SetProcessNoNewPrivileges(config.NoNewPrivileges) | 	g.SetProcessNoNewPrivileges(config.NoNewPrivileges) | ||||||
| 	g.SetProcessApparmorProfile(config.ApparmorProfile) | 	g.SetProcessApparmorProfile(config.ApparmorProfile) | ||||||
|  | @ -321,7 +348,6 @@ func createConfigToOCISpec(config *createConfig) (*spec.Spec, error) { | ||||||
| 			Hooks: &configSpec.Hooks{}, | 			Hooks: &configSpec.Hooks{}, | ||||||
| 			//Annotations
 | 			//Annotations
 | ||||||
| 				Resources: &configSpec.LinuxResources{ | 				Resources: &configSpec.LinuxResources{ | ||||||
| 					Devices: config.GetDefaultDevices(), |  | ||||||
| 					BlockIO: &blkio, | 					BlockIO: &blkio, | ||||||
| 					//HugepageLimits:
 | 					//HugepageLimits:
 | ||||||
| 					Network: &configSpec.LinuxNetwork{ | 					Network: &configSpec.LinuxNetwork{ | ||||||
|  | @ -331,7 +357,6 @@ func createConfigToOCISpec(config *createConfig) (*spec.Spec, error) { | ||||||
| 				}, | 				}, | ||||||
| 				//CgroupsPath:
 | 				//CgroupsPath:
 | ||||||
| 				//Namespaces: []LinuxNamespace
 | 				//Namespaces: []LinuxNamespace
 | ||||||
| 				//Devices
 |  | ||||||
| 				// DefaultAction:
 | 				// DefaultAction:
 | ||||||
| 				// Architectures
 | 				// Architectures
 | ||||||
| 				// Syscalls:
 | 				// Syscalls:
 | ||||||
|  |  | ||||||
|  | @ -1018,6 +1018,7 @@ _podman_container_run() { | ||||||
| 		--oom-kill-disable | 		--oom-kill-disable | ||||||
| 		--privileged | 		--privileged | ||||||
| 		--publish-all -P | 		--publish-all -P | ||||||
|  | 		--quiet | ||||||
| 		--read-only | 		--read-only | ||||||
| 		--tty -t | 		--tty -t | ||||||
| 	" | 	" | ||||||
|  |  | ||||||
|  | @ -373,6 +373,10 @@ port to a random port on the host within an *ephemeral port range* defined by | ||||||
| `/proc/sys/net/ipv4/ip_local_port_range`. To find the mapping between the host | `/proc/sys/net/ipv4/ip_local_port_range`. To find the mapping between the host | ||||||
| ports and the exposed ports, use `podman port`. | ports and the exposed ports, use `podman port`. | ||||||
| 
 | 
 | ||||||
|  | **--quiet, -q** | ||||||
|  | 
 | ||||||
|  | Suppress output information when pulling images | ||||||
|  | 
 | ||||||
| **--read-only**=*true*|*false* | **--read-only**=*true*|*false* | ||||||
|    Mount the container's root filesystem as read only. |    Mount the container's root filesystem as read only. | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -379,6 +379,10 @@ port to a random port on the host within an *ephemeral port range* defined by | ||||||
| `/proc/sys/net/ipv4/ip_local_port_range`. To find the mapping between the host | `/proc/sys/net/ipv4/ip_local_port_range`. To find the mapping between the host | ||||||
| ports and the exposed ports, use `podman port`. | ports and the exposed ports, use `podman port`. | ||||||
| 
 | 
 | ||||||
|  | **--quiet, -q** | ||||||
|  | 
 | ||||||
|  | Suppress output information when pulling images | ||||||
|  | 
 | ||||||
| **--read-only**=*true*|*false* | **--read-only**=*true*|*false* | ||||||
|    Mount the container's root filesystem as read only. |    Mount the container's root filesystem as read only. | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -397,7 +397,7 @@ func (k *Image) HasLatest() (bool, error) { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Pull is a wrapper function to pull and image
 | // Pull is a wrapper function to pull and image
 | ||||||
| func (k *Image) Pull() error { | func (k *Image) Pull(writer io.Writer) error { | ||||||
| 	// If the image hasn't been decomposed yet
 | 	// If the image hasn't been decomposed yet
 | ||||||
| 	if !k.beenDecomposed { | 	if !k.beenDecomposed { | ||||||
| 		err := k.Decompose() | 		err := k.Decompose() | ||||||
|  | @ -405,7 +405,7 @@ func (k *Image) Pull() error { | ||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	k.runtime.PullImage(k.PullName, CopyOptions{Writer: os.Stdout, SignaturePolicyPath: k.runtime.config.SignaturePolicyPath}) | 	k.runtime.PullImage(k.PullName, CopyOptions{Writer: writer, SignaturePolicyPath: k.runtime.config.SignaturePolicyPath}) | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -0,0 +1,27 @@ | ||||||
|  | #!/usr/bin/env bats | ||||||
|  | 
 | ||||||
|  | load helpers | ||||||
|  | 
 | ||||||
|  | function teardown() { | ||||||
|  |     cleanup_test | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function setup() { | ||||||
|  |     prepare_network_conf | ||||||
|  |     copy_images | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @test "run baddevice test" { | ||||||
|  |     run ${PODMAN_BINARY} ${PODMAN_OPTIONS} run -q --device /dev/baddevice ${ALPINE}  ls /dev/kmsg | ||||||
|  |     echo $output | ||||||
|  |     [ "$status" -ne 0 ] | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @test "run device test" { | ||||||
|  |     run ${PODMAN_BINARY} ${PODMAN_OPTIONS} run -q --device /dev/kmsg ${ALPINE}  ls --color=never /dev/kmsg | ||||||
|  |     echo "$output" | ||||||
|  |     [ "$status" -eq 0 ] | ||||||
|  |     device=$(echo $output | tr -d '\r') | ||||||
|  |     echo "<$device>" | ||||||
|  |     [ "$device" = "/dev/kmsg" ] | ||||||
|  | } | ||||||
|  | @ -1,14 +1,14 @@ | ||||||
| # | # | ||||||
| github.com/sirupsen/logrus v1.0.0 | github.com/sirupsen/logrus v1.0.0 | ||||||
| github.com/containers/image c8bcd6aa11c62637c5a7da1420f43dd6a15f0e8d | github.com/containers/image 9b4510f6d1627c8e53c3303a8fe48ca7842c2ace | ||||||
| github.com/docker/docker-credential-helpers d68f9aeca33f5fd3f08eeae5e9d175edf4e731d1 | github.com/docker/docker-credential-helpers d68f9aeca33f5fd3f08eeae5e9d175edf4e731d1 | ||||||
| github.com/ostreedev/ostree-go master | github.com/ostreedev/ostree-go master | ||||||
| github.com/containers/storage 9e0c323a4b425557f8310ee8d125634acd39d8f5 | github.com/containers/storage 1824cf917a6b42d8c41179e807bb20a5fd6c0f0a | ||||||
| github.com/containernetworking/cni v0.4.0 | github.com/containernetworking/cni v0.4.0 | ||||||
| google.golang.org/grpc v1.0.4 https://github.com/grpc/grpc-go | google.golang.org/grpc v1.0.4 https://github.com/grpc/grpc-go | ||||||
| github.com/opencontainers/selinux b29023b86e4a69d1b46b7e7b4e2b6fda03f0b9cd | github.com/opencontainers/selinux b29023b86e4a69d1b46b7e7b4e2b6fda03f0b9cd | ||||||
| github.com/opencontainers/go-digest v1.0.0-rc0 | github.com/opencontainers/go-digest v1.0.0-rc0 | ||||||
| github.com/opencontainers/runtime-tools d3f7e9e9e631c7e87552d67dc7c86de33c3fb68a | github.com/opencontainers/runtime-tools v0.3.0 | ||||||
| github.com/opencontainers/runc 45bde006ca8c90e089894508708bcf0e2cdf9e13 | github.com/opencontainers/runc 45bde006ca8c90e089894508708bcf0e2cdf9e13 | ||||||
| github.com/mrunalp/fileutils master | github.com/mrunalp/fileutils master | ||||||
| github.com/vishvananda/netlink master | github.com/vishvananda/netlink master | ||||||
|  | @ -97,3 +97,6 @@ github.com/pquerna/ffjson d49c2bc1aa135aad0c6f4fc2056623ec78f5d5ac | ||||||
| github.com/stretchr/testify 4d4bfba8f1d1027c4fdbe371823030df51419987 | github.com/stretchr/testify 4d4bfba8f1d1027c4fdbe371823030df51419987 | ||||||
| github.com/pmezard/go-difflib 792786c7400a136282c1664665ae0a8db921c6c2 | github.com/pmezard/go-difflib 792786c7400a136282c1664665ae0a8db921c6c2 | ||||||
| github.com/containerd/continuity master | github.com/containerd/continuity master | ||||||
|  | github.com/xeipuuv/gojsonschema  master | ||||||
|  | github.com/xeipuuv/gojsonreference master | ||||||
|  | github.com/xeipuuv/gojsonpointer master | ||||||
|  |  | ||||||
							
								
								
									
										100
									
								
								vendor/github.com/opencontainers/runc/libcontainer/devices/devices_linux.go
								
								
									generated
								
								
									vendored
								
								
									Normal file
								
							
							
						
						
									
										100
									
								
								vendor/github.com/opencontainers/runc/libcontainer/devices/devices_linux.go
								
								
									generated
								
								
									vendored
								
								
									Normal file
								
							|  | @ -0,0 +1,100 @@ | ||||||
|  | package devices | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"errors" | ||||||
|  | 	"io/ioutil" | ||||||
|  | 	"os" | ||||||
|  | 	"path/filepath" | ||||||
|  | 
 | ||||||
|  | 	"github.com/opencontainers/runc/libcontainer/configs" | ||||||
|  | 
 | ||||||
|  | 	"golang.org/x/sys/unix" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | var ( | ||||||
|  | 	ErrNotADevice = errors.New("not a device node") | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // Testing dependencies
 | ||||||
|  | var ( | ||||||
|  | 	unixLstat     = unix.Lstat | ||||||
|  | 	ioutilReadDir = ioutil.ReadDir | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // Given the path to a device and its cgroup_permissions(which cannot be easily queried) look up the information about a linux device and return that information as a Device struct.
 | ||||||
|  | func DeviceFromPath(path, permissions string) (*configs.Device, error) { | ||||||
|  | 	var stat unix.Stat_t | ||||||
|  | 	err := unixLstat(path, &stat) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	var ( | ||||||
|  | 		devType rune | ||||||
|  | 		mode    = stat.Mode | ||||||
|  | 	) | ||||||
|  | 	switch { | ||||||
|  | 	case mode&unix.S_IFBLK == unix.S_IFBLK: | ||||||
|  | 		devType = 'b' | ||||||
|  | 	case mode&unix.S_IFCHR == unix.S_IFCHR: | ||||||
|  | 		devType = 'c' | ||||||
|  | 	default: | ||||||
|  | 		return nil, ErrNotADevice | ||||||
|  | 	} | ||||||
|  | 	devNumber := int(stat.Rdev) | ||||||
|  | 	uid := stat.Uid | ||||||
|  | 	gid := stat.Gid | ||||||
|  | 	return &configs.Device{ | ||||||
|  | 		Type:        devType, | ||||||
|  | 		Path:        path, | ||||||
|  | 		Major:       Major(devNumber), | ||||||
|  | 		Minor:       Minor(devNumber), | ||||||
|  | 		Permissions: permissions, | ||||||
|  | 		FileMode:    os.FileMode(mode), | ||||||
|  | 		Uid:         uid, | ||||||
|  | 		Gid:         gid, | ||||||
|  | 	}, nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func HostDevices() ([]*configs.Device, error) { | ||||||
|  | 	return getDevices("/dev") | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func getDevices(path string) ([]*configs.Device, error) { | ||||||
|  | 	files, err := ioutilReadDir(path) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	out := []*configs.Device{} | ||||||
|  | 	for _, f := range files { | ||||||
|  | 		switch { | ||||||
|  | 		case f.IsDir(): | ||||||
|  | 			switch f.Name() { | ||||||
|  | 			// ".lxc" & ".lxd-mounts" added to address https://github.com/lxc/lxd/issues/2825
 | ||||||
|  | 			case "pts", "shm", "fd", "mqueue", ".lxc", ".lxd-mounts": | ||||||
|  | 				continue | ||||||
|  | 			default: | ||||||
|  | 				sub, err := getDevices(filepath.Join(path, f.Name())) | ||||||
|  | 				if err != nil { | ||||||
|  | 					return nil, err | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
|  | 				out = append(out, sub...) | ||||||
|  | 				continue | ||||||
|  | 			} | ||||||
|  | 		case f.Name() == "console": | ||||||
|  | 			continue | ||||||
|  | 		} | ||||||
|  | 		device, err := DeviceFromPath(filepath.Join(path, f.Name()), "rwm") | ||||||
|  | 		if err != nil { | ||||||
|  | 			if err == ErrNotADevice { | ||||||
|  | 				continue | ||||||
|  | 			} | ||||||
|  | 			if os.IsNotExist(err) { | ||||||
|  | 				continue | ||||||
|  | 			} | ||||||
|  | 			return nil, err | ||||||
|  | 		} | ||||||
|  | 		out = append(out, device) | ||||||
|  | 	} | ||||||
|  | 	return out, nil | ||||||
|  | } | ||||||
							
								
								
									
										3
									
								
								vendor/github.com/opencontainers/runc/libcontainer/devices/devices_unsupported.go
								
								
									generated
								
								
									vendored
								
								
									Normal file
								
							
							
						
						
									
										3
									
								
								vendor/github.com/opencontainers/runc/libcontainer/devices/devices_unsupported.go
								
								
									generated
								
								
									vendored
								
								
									Normal file
								
							|  | @ -0,0 +1,3 @@ | ||||||
|  | // +build !linux
 | ||||||
|  | 
 | ||||||
|  | package devices | ||||||
							
								
								
									
										24
									
								
								vendor/github.com/opencontainers/runc/libcontainer/devices/number.go
								
								
									generated
								
								
									vendored
								
								
									Normal file
								
							
							
						
						
									
										24
									
								
								vendor/github.com/opencontainers/runc/libcontainer/devices/number.go
								
								
									generated
								
								
									vendored
								
								
									Normal file
								
							|  | @ -0,0 +1,24 @@ | ||||||
|  | // +build linux freebsd
 | ||||||
|  | 
 | ||||||
|  | package devices | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  | 
 | ||||||
|  | This code provides support for manipulating linux device numbers.  It should be replaced by normal syscall functions once http://code.google.com/p/go/issues/detail?id=8106 is solved.
 | ||||||
|  | 
 | ||||||
|  | You can read what they are here: | ||||||
|  | 
 | ||||||
|  |  - http://www.makelinux.net/ldd3/chp-3-sect-2
 | ||||||
|  |  - http://www.linux-tutorial.info/modules.php?name=MContent&pageid=94
 | ||||||
|  | 
 | ||||||
|  | Note! These are NOT the same as the MAJOR(dev_t device);, MINOR(dev_t device); and MKDEV(int major, int minor); functions as defined in <linux/kdev_t.h> as the representation of device numbers used by go is different than the one used internally to the kernel! - https://github.com/torvalds/linux/blob/master/include/linux/kdev_t.h#L9
 | ||||||
|  | 
 | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | func Major(devNumber int) int64 { | ||||||
|  | 	return int64((devNumber >> 8) & 0xfff) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func Minor(devNumber int) int64 { | ||||||
|  | 	return int64((devNumber & 0xff) | ((devNumber >> 12) & 0xfff00)) | ||||||
|  | } | ||||||
		Loading…
	
		Reference in New Issue