diff options
Diffstat (limited to 'cmd')
-rw-r--r-- | cmd/podman/common.go | 3 | ||||
-rw-r--r-- | cmd/podman/create.go | 45 | ||||
-rw-r--r-- | cmd/podman/inspect.go | 2 | ||||
-rw-r--r-- | cmd/podman/run.go | 19 | ||||
-rw-r--r-- | cmd/podman/run_test.go | 82 | ||||
-rw-r--r-- | cmd/podman/spec.go | 18 |
6 files changed, 145 insertions, 24 deletions
diff --git a/cmd/podman/common.go b/cmd/podman/common.go index e3997539a..e0ef43782 100644 --- a/cmd/podman/common.go +++ b/cmd/podman/common.go @@ -377,7 +377,8 @@ var createFlags = []cli.Flag{ }, cli.StringFlag{ Name: "shm-size", - Usage: "Size of `/dev/shm`. The format is `<number><unit>`. default is 64 MB", + Usage: "Size of `/dev/shm`. The format is `<number><unit>`.", + Value: "65536k", }, cli.BoolFlag{ Name: "sig-proxy", diff --git a/cmd/podman/create.go b/cmd/podman/create.go index bb9a31467..ead2f6735 100644 --- a/cmd/podman/create.go +++ b/cmd/podman/create.go @@ -62,7 +62,7 @@ type createResourceConfig struct { MemorySwappiness int // memory-swappiness OomScoreAdj int //oom-score-adj PidsLimit int64 // pids-limit - ShmSize string + ShmSize int64 Ulimit []string //ulimit } @@ -154,13 +154,24 @@ func createCmd(c *cli.Context) error { return err } + if c.String("cidfile") != "" { + if err := libpod.WriteFile("", c.String("cidfile")); err != nil { + return errors.Wrapf(err, "unable to write cidfile %s", c.String("cidfile")) + } + } + + if len(c.Args()) < 1 { + return errors.Errorf("image name or ID is required") + } + runtime, err := getRuntime(c) if err != nil { return errors.Wrapf(err, "error creating libpod runtime") } defer runtime.Shutdown(false) - createConfig, err := parseCreateOpts(c, runtime) + imageName, _, data, err := imageData(c, runtime, c.Args()[0]) + createConfig, err := parseCreateOpts(c, runtime, imageName, data) if err != nil { return err } @@ -179,6 +190,7 @@ func createCmd(c *cli.Context) error { options = append(options, libpod.WithLabels(createConfig.Labels)) options = append(options, libpod.WithUser(createConfig.User)) options = append(options, libpod.WithShmDir(createConfig.ShmDir)) + options = append(options, libpod.WithShmSize(createConfig.Resources.ShmSize)) ctr, err := runtime.NewContainer(runtimeSpec, options...) if err != nil { return err @@ -195,11 +207,12 @@ func createCmd(c *cli.Context) error { logrus.Debug("new container created ", ctr.ID()) if c.String("cidfile") != "" { - libpod.WriteFile(ctr.ID(), c.String("cidfile")) - } else { - fmt.Printf("%s\n", ctr.ID()) + err := libpod.WriteFile(ctr.ID(), c.String("cidfile")) + if err != nil { + logrus.Error(err) + } } - + fmt.Printf("%s\n", ctr.ID()) return nil } @@ -357,15 +370,13 @@ func imageData(c *cli.Context, runtime *libpod.Runtime, image string) (string, s // Parses CLI options related to container creation into a config which can be // parsed into an OCI runtime spec -func parseCreateOpts(c *cli.Context, runtime *libpod.Runtime) (*createConfig, error) { +func parseCreateOpts(c *cli.Context, runtime *libpod.Runtime, imageName string, data *libpod.ImageData) (*createConfig, error) { + //imageName, imageID, data, err := imageData(c, runtime, image) var command []string var memoryLimit, memoryReservation, memorySwap, memoryKernel int64 var blkioWeight uint16 - if len(c.Args()) < 1 { - return nil, errors.Errorf("image name or ID is required") - } - image := c.Args()[0] + imageID := data.ID if len(c.Args()) > 1 { command = c.Args()[1:] @@ -452,10 +463,6 @@ func parseCreateOpts(c *cli.Context, runtime *libpod.Runtime) (*createConfig, er } shmDir = ctr.ShmDir() } - imageName, imageID, data, err := imageData(c, runtime, image) - if err != nil { - return nil, err - } // USER user := c.String("user") @@ -524,6 +531,12 @@ func parseCreateOpts(c *cli.Context, runtime *libpod.Runtime) (*createConfig, er return nil, err } + // SHM SIze + shmSize, err := units.FromHumanSize(c.String("shm-size")) + if err != nil { + return nil, errors.Wrapf(err, "unable to translate --shm-size") + } + config := &createConfig{ Runtime: runtime, CapAdd: c.StringSlice("cap-add"), @@ -580,7 +593,7 @@ func parseCreateOpts(c *cli.Context, runtime *libpod.Runtime) (*createConfig, er DeviceWriteBps: c.StringSlice("device-write-bps"), DeviceWriteIOps: c.StringSlice("device-write-iops"), DisableOomKiller: c.Bool("oom-kill-disable"), - ShmSize: c.String("shm-size"), + ShmSize: shmSize, Memory: memoryLimit, MemoryReservation: memoryReservation, MemorySwap: memorySwap, diff --git a/cmd/podman/inspect.go b/cmd/podman/inspect.go index dc5810492..5e9fc53bb 100644 --- a/cmd/podman/inspect.go +++ b/cmd/podman/inspect.go @@ -320,7 +320,7 @@ type HostConfig struct { SecurityOpt []string `json:"SecurityOpt"` UTSMode string `json:"UTSMode"` UsernsMode string `json:"UsernsMode"` - ShmSize string `json:"ShmSize"` + ShmSize int64 `json:"ShmSize"` Runtime string `json:"Runtime"` ConsoleSize *specs.Box `json:"ConsoleSize"` Isolation string `json:"Isolation"` //TODO diff --git a/cmd/podman/run.go b/cmd/podman/run.go index 45a428f39..eecfe87b3 100644 --- a/cmd/podman/run.go +++ b/cmd/podman/run.go @@ -29,13 +29,24 @@ func runCmd(c *cli.Context) error { if err := validateFlags(c, createFlags); err != nil { return err } + + if c.String("cidfile") != "" { + if err := libpod.WriteFile("", c.String("cidfile")); err != nil { + return errors.Wrapf(err, "unable to write cidfile %s", c.String("cidfile")) + } + } + runtime, err := getRuntime(c) if err != nil { return errors.Wrapf(err, "error creating libpod runtime") } defer runtime.Shutdown(false) + if len(c.Args()) < 1 { + return errors.Errorf("image name or ID is required") + } - createConfig, err := parseCreateOpts(c, runtime) + imageName, _, data, err := imageData(c, runtime, c.Args()[0]) + createConfig, err := parseCreateOpts(c, runtime, imageName, data) if err != nil { return err } @@ -56,6 +67,7 @@ func runCmd(c *cli.Context) error { options = append(options, libpod.WithLabels(createConfig.Labels)) options = append(options, libpod.WithUser(createConfig.User)) options = append(options, libpod.WithShmDir(createConfig.ShmDir)) + options = append(options, libpod.WithShmSize(createConfig.Resources.ShmSize)) ctr, err := runtime.NewContainer(runtimeSpec, options...) if err != nil { return err @@ -83,8 +95,9 @@ func runCmd(c *cli.Context) error { logrus.Debug("new container created ", ctr.ID()) if c.String("cidfile") != "" { - libpod.WriteFile(ctr.ID(), c.String("cidfile")) - return nil + if err := libpod.WriteFile(ctr.ID(), c.String("cidfile")); err != nil { + logrus.Error(err) + } } // Create a bool channel to track that the console socket attach diff --git a/cmd/podman/run_test.go b/cmd/podman/run_test.go new file mode 100644 index 000000000..622e75d3e --- /dev/null +++ b/cmd/podman/run_test.go @@ -0,0 +1,82 @@ +package main + +import ( + "testing" + + ociv1 "github.com/opencontainers/image-spec/specs-go/v1" + spec "github.com/opencontainers/runtime-spec/specs-go" + "github.com/projectatomic/libpod/libpod" + "github.com/stretchr/testify/assert" + "github.com/urfave/cli" +) + +var ( + cmd = []string{"podman", "test", "alpine"} + CLI *cli.Context + testCommand = cli.Command{ + Name: "test", + Flags: createFlags, + Action: testCmd, + } +) + +// generates a mocked ImageData structure based on alpine +func generateAlpineImageData() *libpod.ImageData { + config := &ociv1.ImageConfig{ + User: "", + ExposedPorts: nil, + Env: []string{"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}, + Entrypoint: []string{}, + Cmd: []string{"/bin/sh"}, + Volumes: nil, + WorkingDir: "", + Labels: nil, + StopSignal: "", + } + + data := &libpod.ImageData{ + ID: "e21c333399e0aeedfd70e8827c9fba3f8e9b170ef8a48a29945eb7702bf6aa5f", + RepoTags: []string{"docker.io/library/alpine:latest"}, + RepoDigests: []string{"docker.io/library/alpine@sha256:5cb04fce748f576d7b72a37850641de8bd725365519673c643ef2d14819b42c6"}, + Comment: "Created:2017-12-01 18:48:48.949613376 +0000", + Author: "", + Architecture: "amd64", + Os: "linux", + Version: "17.06.2-ce", + Config: config, + } + return data +} + +// sets a global CLI +func testCmd(c *cli.Context) error { + CLI = c + return nil +} + +// creates the mocked cli pointing to our create flags +// global flags like log-level are not implemented +func createCLI() cli.App { + a := cli.App{ + Commands: []cli.Command{ + testCommand, + }, + } + return a +} + +func getRuntimeSpec(c *cli.Context) *spec.Spec { + runtime, _ := getRuntime(c) + createConfig, _ := parseCreateOpts(c, runtime, "alpine", generateAlpineImageData()) + runtimeSpec, _ := createConfigToOCISpec(createConfig) + return runtimeSpec +} + +// TestPIDsLimit verifies the inputed pid-limit is correctly defined in the spec +func TestPIDsLimit(t *testing.T) { + a := createCLI() + args := []string{"--pids-limit", "22"} + a.Run(append(cmd, args...)) + runtimeSpec := getRuntimeSpec(CLI) + assert.Equal(t, runtimeSpec.Linux.Resources.Pids.Limit, int64(22)) +} diff --git a/cmd/podman/spec.go b/cmd/podman/spec.go index 342b80d9e..d630b2f50 100644 --- a/cmd/podman/spec.go +++ b/cmd/podman/spec.go @@ -189,7 +189,13 @@ func addDevice(g *generate.Generator, device string) error { // Parses information needed to create a container into an OCI runtime spec func createConfigToOCISpec(config *createConfig) (*spec.Spec, error) { g := generate.New() - g.AddCgroupsMount("ro") + cgroupMnt := spec.Mount{ + Destination: "/sys/fs/cgroup", + Type: "cgroup", + Source: "cgroup", + Options: []string{"nosuid", "noexec", "nodev", "relatime", "ro"}, + } + g.AddMount(cgroupMnt) g.SetProcessCwd(config.WorkDir) g.SetProcessArgs(config.Command) g.SetProcessTerminal(config.Tty) @@ -273,6 +279,7 @@ func createConfigToOCISpec(config *createConfig) (*spec.Spec, error) { } for _, i := range config.Tmpfs { + // Default options if nothing passed options := []string{"rw", "noexec", "nosuid", "nodev", "size=65536k"} spliti := strings.SplitN(i, ":", 2) if len(spliti) > 1 { @@ -281,8 +288,13 @@ func createConfigToOCISpec(config *createConfig) (*spec.Spec, error) { } options = strings.Split(spliti[1], ",") } - // Default options if nothing passed - g.AddTmpfsMount(spliti[0], append(options, "tmpcopyup")) + tmpfsMnt := spec.Mount{ + Destination: spliti[0], + Type: "tmpfs", + Source: "tmpfs", + Options: append(options, "tmpcopyup"), + } + g.AddMount(tmpfsMnt) } for name, val := range config.Env { |