summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel J Walsh <dwalsh@redhat.com>2017-12-19 09:07:49 -0500
committerAtomic Bot <atomic-devel@projectatomic.io>2017-12-19 18:51:52 +0000
commit94a810751539afeb1590ccc1a9745f1d5767fda2 (patch)
tree0e143bd90c976c60db4f0435d12c6266e0fe3e72
parentc0432eb0e8a2c777a5c6d8caa01475c06553594c (diff)
downloadpodman-94a810751539afeb1590ccc1a9745f1d5767fda2.tar.gz
podman-94a810751539afeb1590ccc1a9745f1d5767fda2.tar.bz2
podman-94a810751539afeb1590ccc1a9745f1d5767fda2.zip
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
-rw-r--r--cmd/podman/common.go4
-rw-r--r--cmd/podman/create.go14
-rw-r--r--cmd/podman/run.go8
-rw-r--r--cmd/podman/spec.go29
-rw-r--r--completions/bash/podman1
-rw-r--r--docs/podman-create.1.md4
-rw-r--r--docs/podman-run.1.md4
-rw-r--r--libpod/runtime_img.go4
-rw-r--r--test/podman_run_device.bats27
-rw-r--r--vendor.conf9
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/devices/devices_linux.go100
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/devices/devices_unsupported.go3
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/devices/number.go24
13 files changed, 219 insertions, 12 deletions
diff --git a/cmd/podman/common.go b/cmd/podman/common.go
index 99685107b..57e2ff717 100644
--- a/cmd/podman/common.go
+++ b/cmd/podman/common.go
@@ -363,6 +363,10 @@ var createFlags = []cli.Flag{
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{
Name: "read-only",
Usage: "Make containers root filesystem read-only",
},
diff --git a/cmd/podman/create.go b/cmd/podman/create.go
index f65bc49c6..79f08220d 100644
--- a/cmd/podman/create.go
+++ b/cmd/podman/create.go
@@ -3,6 +3,7 @@ package main
import (
"encoding/json"
"fmt"
+ "io"
"os"
"strconv"
"strings"
@@ -14,7 +15,6 @@ import (
"github.com/projectatomic/libpod/libpod"
"github.com/sirupsen/logrus"
"github.com/urfave/cli"
- pb "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime"
)
type mountType string
@@ -72,7 +72,7 @@ type createConfig struct {
CgroupParent string // cgroup-parent
Command []string
Detach bool // detach
- Devices []*pb.Device // device
+ Devices []string // device
DNSOpt []string //dns-opt
DNSSearch []string //dns-search
DNSServers []string //dns
@@ -101,6 +101,7 @@ type createConfig struct {
Privileged bool //privileged
Publish []string //publish
PublishAll bool //publish-all
+ Quiet bool //quiet
ReadOnlyRootfs bool //read-only
Resources createResourceConfig
Rm bool //rm
@@ -167,8 +168,11 @@ func createCmd(c *cli.Context) error {
if createImage.LocalName == "" {
// The image wasnt found by the user input'd name or its fqname
// Pull the image
- fmt.Printf("Trying to pull %s...", createImage.PullName)
- createImage.Pull()
+ var writer io.Writer
+ if !createConfig.Quiet {
+ writer = os.Stdout
+ }
+ createImage.Pull(writer)
}
runtimeSpec, err := createConfigToOCISpec(createConfig)
@@ -419,6 +423,7 @@ func parseCreateOpts(c *cli.Context, runtime *libpod.Runtime) (*createConfig, er
CgroupParent: c.String("cgroup-parent"),
Command: command,
Detach: c.Bool("detach"),
+ Devices: c.StringSlice("device"),
DNSOpt: c.StringSlice("dns-opt"),
DNSSearch: c.StringSlice("dns-search"),
DNSServers: c.StringSlice("dns"),
@@ -447,6 +452,7 @@ func parseCreateOpts(c *cli.Context, runtime *libpod.Runtime) (*createConfig, er
Privileged: c.Bool("privileged"),
Publish: c.StringSlice("publish"),
PublishAll: c.Bool("publish-all"),
+ Quiet: c.Bool("quiet"),
ReadOnlyRootfs: c.Bool("read-only"),
Resources: createResourceConfig{
BlkioWeight: blkioWeight,
diff --git a/cmd/podman/run.go b/cmd/podman/run.go
index 6ba501c76..bc93459ad 100644
--- a/cmd/podman/run.go
+++ b/cmd/podman/run.go
@@ -2,6 +2,8 @@ package main
import (
"fmt"
+ "io"
+ "os"
"sync"
"github.com/pkg/errors"
@@ -44,7 +46,11 @@ func runCmd(c *cli.Context) error {
if createImage.LocalName == "" {
// The image wasnt found by the user input'd name or its fqname
// Pull the image
- createImage.Pull()
+ var writer io.Writer
+ if !createConfig.Quiet {
+ writer = os.Stdout
+ }
+ createImage.Pull(writer)
}
runtimeSpec, err := createConfigToOCISpec(createConfig)
diff --git a/cmd/podman/spec.go b/cmd/podman/spec.go
index b13556d93..550f74218 100644
--- a/cmd/podman/spec.go
+++ b/cmd/podman/spec.go
@@ -10,6 +10,7 @@ import (
"github.com/docker/docker/daemon/caps"
"github.com/docker/docker/pkg/mount"
"github.com/docker/go-units"
+ "github.com/opencontainers/runc/libcontainer/devices"
spec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/opencontainers/runtime-tools/generate"
"github.com/opencontainers/selinux/go-selinux/label"
@@ -163,6 +164,25 @@ func setupCapabilities(config *createConfig, configSpec *spec.Spec) error {
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
func createConfigToOCISpec(config *createConfig) (*spec.Spec, error) {
g := generate.New()
@@ -233,6 +253,13 @@ func createConfigToOCISpec(config *createConfig) (*spec.Spec, error) {
g.SetLinuxResourcesCPUMems(config.Resources.CPUsetMems)
}
+ // Devices
+ for _, device := range config.Devices {
+ if err := addDevice(&g, device); err != nil {
+ return nil, err
+ }
+ }
+
// SECURITY OPTS
g.SetProcessNoNewPrivileges(config.NoNewPrivileges)
g.SetProcessApparmorProfile(config.ApparmorProfile)
@@ -321,7 +348,6 @@ func createConfigToOCISpec(config *createConfig) (*spec.Spec, error) {
Hooks: &configSpec.Hooks{},
//Annotations
Resources: &configSpec.LinuxResources{
- Devices: config.GetDefaultDevices(),
BlockIO: &blkio,
//HugepageLimits:
Network: &configSpec.LinuxNetwork{
@@ -331,7 +357,6 @@ func createConfigToOCISpec(config *createConfig) (*spec.Spec, error) {
},
//CgroupsPath:
//Namespaces: []LinuxNamespace
- //Devices
// DefaultAction:
// Architectures
// Syscalls:
diff --git a/completions/bash/podman b/completions/bash/podman
index 9a5351ade..ecf752de9 100644
--- a/completions/bash/podman
+++ b/completions/bash/podman
@@ -1018,6 +1018,7 @@ _podman_container_run() {
--oom-kill-disable
--privileged
--publish-all -P
+ --quiet
--read-only
--tty -t
"
diff --git a/docs/podman-create.1.md b/docs/podman-create.1.md
index 9deeb8149..117a076a6 100644
--- a/docs/podman-create.1.md
+++ b/docs/podman-create.1.md
@@ -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
ports and the exposed ports, use `podman port`.
+**--quiet, -q**
+
+Suppress output information when pulling images
+
**--read-only**=*true*|*false*
Mount the container's root filesystem as read only.
diff --git a/docs/podman-run.1.md b/docs/podman-run.1.md
index 36efc2a2e..19e73aea2 100644
--- a/docs/podman-run.1.md
+++ b/docs/podman-run.1.md
@@ -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
ports and the exposed ports, use `podman port`.
+**--quiet, -q**
+
+Suppress output information when pulling images
+
**--read-only**=*true*|*false*
Mount the container's root filesystem as read only.
diff --git a/libpod/runtime_img.go b/libpod/runtime_img.go
index 6107c2fdb..53211ff54 100644
--- a/libpod/runtime_img.go
+++ b/libpod/runtime_img.go
@@ -397,7 +397,7 @@ func (k *Image) HasLatest() (bool, error) {
}
// 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 !k.beenDecomposed {
err := k.Decompose()
@@ -405,7 +405,7 @@ func (k *Image) Pull() error {
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
}
diff --git a/test/podman_run_device.bats b/test/podman_run_device.bats
new file mode 100644
index 000000000..98d6833eb
--- /dev/null
+++ b/test/podman_run_device.bats
@@ -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" ]
+}
diff --git a/vendor.conf b/vendor.conf
index cc335f7ea..8450dfbc1 100644
--- a/vendor.conf
+++ b/vendor.conf
@@ -1,14 +1,14 @@
#
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/ostreedev/ostree-go master
-github.com/containers/storage 9e0c323a4b425557f8310ee8d125634acd39d8f5
+github.com/containers/storage 1824cf917a6b42d8c41179e807bb20a5fd6c0f0a
github.com/containernetworking/cni v0.4.0
google.golang.org/grpc v1.0.4 https://github.com/grpc/grpc-go
github.com/opencontainers/selinux b29023b86e4a69d1b46b7e7b4e2b6fda03f0b9cd
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/mrunalp/fileutils master
github.com/vishvananda/netlink master
@@ -97,3 +97,6 @@ github.com/pquerna/ffjson d49c2bc1aa135aad0c6f4fc2056623ec78f5d5ac
github.com/stretchr/testify 4d4bfba8f1d1027c4fdbe371823030df51419987
github.com/pmezard/go-difflib 792786c7400a136282c1664665ae0a8db921c6c2
github.com/containerd/continuity master
+github.com/xeipuuv/gojsonschema master
+github.com/xeipuuv/gojsonreference master
+github.com/xeipuuv/gojsonpointer master
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/devices/devices_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/devices/devices_linux.go
new file mode 100644
index 000000000..461dc097c
--- /dev/null
+++ b/vendor/github.com/opencontainers/runc/libcontainer/devices/devices_linux.go
@@ -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
+}
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/devices/devices_unsupported.go b/vendor/github.com/opencontainers/runc/libcontainer/devices/devices_unsupported.go
new file mode 100644
index 000000000..6649b9f2d
--- /dev/null
+++ b/vendor/github.com/opencontainers/runc/libcontainer/devices/devices_unsupported.go
@@ -0,0 +1,3 @@
+// +build !linux
+
+package devices
diff --git a/vendor/github.com/opencontainers/runc/libcontainer/devices/number.go b/vendor/github.com/opencontainers/runc/libcontainer/devices/number.go
new file mode 100644
index 000000000..885b6e5dd
--- /dev/null
+++ b/vendor/github.com/opencontainers/runc/libcontainer/devices/number.go
@@ -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))
+}