summaryrefslogtreecommitdiff
path: root/cmd/podman
diff options
context:
space:
mode:
Diffstat (limited to 'cmd/podman')
-rw-r--r--cmd/podman/common/specgen.go52
-rw-r--r--cmd/podman/containers/create.go30
-rw-r--r--cmd/podman/containers/diff.go6
-rw-r--r--cmd/podman/containers/run.go21
-rw-r--r--cmd/podman/diff.go14
-rw-r--r--cmd/podman/images/diff.go12
-rw-r--r--cmd/podman/images/inspect.go26
-rw-r--r--cmd/podman/images/tree.go40
-rw-r--r--cmd/podman/inspect.go31
-rw-r--r--cmd/podman/system/service.go27
10 files changed, 185 insertions, 74 deletions
diff --git a/cmd/podman/common/specgen.go b/cmd/podman/common/specgen.go
index 85b344b3c..7550bf784 100644
--- a/cmd/podman/common/specgen.go
+++ b/cmd/podman/common/specgen.go
@@ -47,6 +47,12 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *ContainerCLIOpts, args []string
if err != nil {
return err
}
+ if s.ResourceLimits == nil {
+ s.ResourceLimits = &specs.LinuxResources{}
+ }
+ if s.ResourceLimits.Memory == nil {
+ s.ResourceLimits.Memory = &specs.LinuxMemory{}
+ }
if m := c.Memory; len(m) > 0 {
ml, err := units.RAMInBytes(m)
if err != nil {
@@ -81,6 +87,9 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *ContainerCLIOpts, args []string
}
s.ResourceLimits.Memory.Kernel = &mk
}
+ if s.ResourceLimits.BlockIO == nil {
+ s.ResourceLimits.BlockIO = &specs.LinuxBlockIO{}
+ }
if b := c.BlkIOWeight; len(b) > 0 {
u, err := strconv.ParseUint(b, 10, 16)
if err != nil {
@@ -313,14 +322,16 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *ContainerCLIOpts, args []string
s.StopSignal = &stopSignal
}
}
- swappiness := uint64(c.MemorySwappiness)
if s.ResourceLimits == nil {
s.ResourceLimits = &specs.LinuxResources{}
}
if s.ResourceLimits.Memory == nil {
s.ResourceLimits.Memory = &specs.LinuxMemory{}
}
- s.ResourceLimits.Memory.Swappiness = &swappiness
+ if c.MemorySwappiness >= 0 {
+ swappiness := uint64(c.MemorySwappiness)
+ s.ResourceLimits.Memory.Swappiness = &swappiness
+ }
if s.LogConfiguration == nil {
s.LogConfiguration = &specgen.LogConfig{}
@@ -332,7 +343,9 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *ContainerCLIOpts, args []string
if s.ResourceLimits.Pids == nil {
s.ResourceLimits.Pids = &specs.LinuxPids{}
}
- s.ResourceLimits.Pids.Limit = c.PIDsLimit
+ if c.PIDsLimit > 0 {
+ s.ResourceLimits.Pids.Limit = c.PIDsLimit
+ }
if c.CGroups == "disabled" && c.PIDsLimit > 0 {
s.ResourceLimits.Pids.Limit = -1
}
@@ -411,6 +424,7 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *ContainerCLIOpts, args []string
}
}
+ s.SeccompPolicy = c.SeccompPolicy
// TODO any idea why this was done
// storage.go from spec/
// grab it
@@ -507,18 +521,28 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *ContainerCLIOpts, args []string
if s.ResourceLimits.CPU == nil {
s.ResourceLimits.CPU = &specs.LinuxCPU{}
}
- s.ResourceLimits.CPU.Shares = &c.CPUShares
- s.ResourceLimits.CPU.Period = &c.CPUPeriod
-
- // TODO research these
- //s.ResourceLimits.CPU.Cpus = c.CPUS
- //s.ResourceLimits.CPU.Cpus = c.CPUSetCPUs
+ if c.CPUShares > 0 {
+ s.ResourceLimits.CPU.Shares = &c.CPUShares
+ }
+ if c.CPUPeriod > 0 {
+ s.ResourceLimits.CPU.Period = &c.CPUPeriod
+ }
- //s.ResourceLimits.CPU. = c.CPUSetCPUs
- s.ResourceLimits.CPU.Mems = c.CPUSetMems
- s.ResourceLimits.CPU.Quota = &c.CPUQuota
- s.ResourceLimits.CPU.RealtimePeriod = &c.CPURTPeriod
- s.ResourceLimits.CPU.RealtimeRuntime = &c.CPURTRuntime
+ if c.CPUSetCPUs != "" {
+ s.ResourceLimits.CPU.Cpus = c.CPUSetCPUs
+ }
+ if c.CPUSetMems != "" {
+ s.ResourceLimits.CPU.Mems = c.CPUSetMems
+ }
+ if c.CPUQuota > 0 {
+ s.ResourceLimits.CPU.Quota = &c.CPUQuota
+ }
+ if c.CPURTPeriod > 0 {
+ s.ResourceLimits.CPU.RealtimePeriod = &c.CPURTPeriod
+ }
+ if c.CPURTRuntime > 0 {
+ s.ResourceLimits.CPU.RealtimeRuntime = &c.CPURTRuntime
+ }
s.OOMScoreAdj = &c.OOMScoreAdj
s.RestartPolicy = c.Restart
s.Remove = c.Rm
diff --git a/cmd/podman/containers/create.go b/cmd/podman/containers/create.go
index 292d5c1ad..0843789eb 100644
--- a/cmd/podman/containers/create.go
+++ b/cmd/podman/containers/create.go
@@ -3,6 +3,7 @@ package containers
import (
"fmt"
+ "github.com/containers/common/pkg/config"
"github.com/containers/libpod/cmd/podman/common"
"github.com/containers/libpod/cmd/podman/registry"
"github.com/containers/libpod/pkg/domain/entities"
@@ -61,6 +62,11 @@ func create(cmd *cobra.Command, args []string) error {
if err := createInit(cmd); err != nil {
return err
}
+
+ if err := pullImage(args[0]); err != nil {
+ return err
+ }
+
//TODO rootfs still
s := specgen.NewSpecGenerator(rawImageInput)
if err := common.FillOutSpecGen(s, &cliVals, args); err != nil {
@@ -100,3 +106,27 @@ func createInit(c *cobra.Command) error {
return nil
}
+
+func pullImage(imageName string) error {
+ br, err := registry.ImageEngine().Exists(registry.GetContext(), imageName)
+ if err != nil {
+ return err
+ }
+ pullPolicy, err := config.ValidatePullPolicy(cliVals.Pull)
+ if err != nil {
+ return err
+ }
+ if !br.Value || pullPolicy == config.PullImageAlways {
+ if pullPolicy == config.PullImageNever {
+ return errors.New("unable to find a name and tag match for busybox in repotags: no such image")
+ }
+ _, pullErr := registry.ImageEngine().Pull(registry.GetContext(), imageName, entities.ImagePullOptions{
+ Authfile: cliVals.Authfile,
+ Quiet: cliVals.Quiet,
+ })
+ if pullErr != nil {
+ return pullErr
+ }
+ }
+ return nil
+}
diff --git a/cmd/podman/containers/diff.go b/cmd/podman/containers/diff.go
index ebc0d8ea1..046dac53e 100644
--- a/cmd/podman/containers/diff.go
+++ b/cmd/podman/containers/diff.go
@@ -45,7 +45,11 @@ func diff(cmd *cobra.Command, args []string) error {
return errors.New("container must be specified: podman container diff [options [...]] ID-NAME")
}
- results, err := registry.ContainerEngine().ContainerDiff(registry.GetContext(), args[0], entities.DiffOptions{})
+ var id string
+ if len(args) > 0 {
+ id = args[0]
+ }
+ results, err := registry.ContainerEngine().ContainerDiff(registry.GetContext(), id, *diffOpts)
if err != nil {
return err
}
diff --git a/cmd/podman/containers/run.go b/cmd/podman/containers/run.go
index 151f71885..9d222e44d 100644
--- a/cmd/podman/containers/run.go
+++ b/cmd/podman/containers/run.go
@@ -5,7 +5,6 @@ import (
"os"
"strings"
- "github.com/containers/common/pkg/config"
"github.com/containers/libpod/cmd/podman/common"
"github.com/containers/libpod/cmd/podman/registry"
"github.com/containers/libpod/libpod/define"
@@ -72,26 +71,10 @@ func run(cmd *cobra.Command, args []string) error {
return err
}
- br, err := registry.ImageEngine().Exists(registry.GetContext(), args[0])
- if err != nil {
- return err
- }
- pullPolicy, err := config.ValidatePullPolicy(cliVals.Pull)
- if err != nil {
+ if err := pullImage(args[0]); err != nil {
return err
}
- if !br.Value || pullPolicy == config.PullImageAlways {
- if pullPolicy == config.PullImageNever {
- return errors.New("unable to find a name and tag match for busybox in repotags: no such image")
- }
- _, pullErr := registry.ImageEngine().Pull(registry.GetContext(), args[0], entities.ImagePullOptions{
- Authfile: cliVals.Authfile,
- Quiet: cliVals.Quiet,
- })
- if pullErr != nil {
- return pullErr
- }
- }
+
// If -i is not set, clear stdin
if !cliVals.Interactive {
runOpts.InputStream = nil
diff --git a/cmd/podman/diff.go b/cmd/podman/diff.go
index 8db76e8af..ec94c0918 100644
--- a/cmd/podman/diff.go
+++ b/cmd/podman/diff.go
@@ -46,10 +46,9 @@ func init() {
}
func diff(cmd *cobra.Command, args []string) error {
- if found, err := registry.ImageEngine().Exists(registry.GetContext(), args[0]); err != nil {
- return err
- } else if found.Value {
- return images.Diff(cmd, args, diffOpts)
+ // Latest implies looking for a container
+ if diffOpts.Latest {
+ return containers.Diff(cmd, args, diffOpts)
}
if found, err := registry.ContainerEngine().ContainerExists(registry.GetContext(), args[0]); err != nil {
@@ -57,5 +56,12 @@ func diff(cmd *cobra.Command, args []string) error {
} else if found.Value {
return containers.Diff(cmd, args, diffOpts)
}
+
+ if found, err := registry.ImageEngine().Exists(registry.GetContext(), args[0]); err != nil {
+ return err
+ } else if found.Value {
+ return images.Diff(cmd, args, diffOpts)
+ }
+
return fmt.Errorf("%s not found on system", args[0])
}
diff --git a/cmd/podman/images/diff.go b/cmd/podman/images/diff.go
index dd98dc4d6..7cfacfc6c 100644
--- a/cmd/podman/images/diff.go
+++ b/cmd/podman/images/diff.go
@@ -11,8 +11,8 @@ import (
var (
// podman container _inspect_
diffCmd = &cobra.Command{
- Use: "diff [flags] CONTAINER",
- Args: registry.IdOrLatestArgs,
+ Use: "diff [flags] IMAGE",
+ Args: cobra.ExactArgs(1),
Short: "Inspect changes on image's file systems",
Long: `Displays changes on a image's filesystem. The image will be compared to its parent layer.`,
RunE: diff,
@@ -32,16 +32,16 @@ func init() {
diffOpts = &entities.DiffOptions{}
flags := diffCmd.Flags()
flags.BoolVar(&diffOpts.Archive, "archive", true, "Save the diff as a tar archive")
- _ = flags.MarkHidden("archive")
+ _ = flags.MarkDeprecated("archive", "Provided for backwards compatibility, has no impact on output.")
flags.StringVar(&diffOpts.Format, "format", "", "Change the output format")
}
func diff(cmd *cobra.Command, args []string) error {
- if len(args) == 0 && !diffOpts.Latest {
- return errors.New("image must be specified: podman image diff [options [...]] ID-NAME")
+ if diffOpts.Latest {
+ return errors.New("image diff does not support --latest")
}
- results, err := registry.ImageEngine().Diff(registry.GetContext(), args[0], entities.DiffOptions{})
+ results, err := registry.ImageEngine().Diff(registry.GetContext(), args[0], *diffOpts)
if err != nil {
return err
}
diff --git a/cmd/podman/images/inspect.go b/cmd/podman/images/inspect.go
index 4482ceee5..11bef02ba 100644
--- a/cmd/podman/images/inspect.go
+++ b/cmd/podman/images/inspect.go
@@ -20,11 +20,13 @@ import (
var (
// Command: podman image _inspect_
inspectCmd = &cobra.Command{
- Use: "inspect [flags] IMAGE",
- Short: "Display the configuration of an image",
- Long: `Displays the low-level information on an image identified by name or ID.`,
- RunE: inspect,
- Example: `podman image inspect alpine`,
+ Use: "inspect [flags] IMAGE",
+ Short: "Display the configuration of an image",
+ Long: `Displays the low-level information on an image identified by name or ID.`,
+ RunE: inspect,
+ Example: `podman inspect alpine
+ podman inspect --format "imageId: {{.Id}} size: {{.Size}}" alpine
+ podman inspect --format "image: {{.ImageName}} driver: {{.Driver}}" myctr`,
}
inspectOpts *entities.InspectOptions
)
@@ -39,14 +41,14 @@ func init() {
}
func inspect(cmd *cobra.Command, args []string) error {
- latestContainer := inspectOpts.Latest
-
- if len(args) == 0 && !latestContainer {
- return errors.Errorf("container or image name must be specified: podman inspect [options [...]] name")
+ if inspectOpts.Size {
+ return fmt.Errorf("--size can only be used for containers")
}
-
- if len(args) > 0 && latestContainer {
- return errors.Errorf("you cannot provide additional arguments with --latest")
+ if inspectOpts.Latest {
+ return fmt.Errorf("--latest can only be used for containers")
+ }
+ if len(args) == 0 {
+ return errors.Errorf("image name must be specified: podman image inspect [options [...]] name")
}
results, err := registry.ImageEngine().Inspect(context.Background(), args, *inspectOpts)
diff --git a/cmd/podman/images/tree.go b/cmd/podman/images/tree.go
new file mode 100644
index 000000000..5e82e9dea
--- /dev/null
+++ b/cmd/podman/images/tree.go
@@ -0,0 +1,40 @@
+package images
+
+import (
+ "fmt"
+
+ "github.com/containers/libpod/cmd/podman/registry"
+ "github.com/containers/libpod/pkg/domain/entities"
+ "github.com/spf13/cobra"
+)
+
+var (
+ treeDescription = "Prints layer hierarchy of an image in a tree format"
+ treeCmd = &cobra.Command{
+ Use: "tree [flags] IMAGE",
+ Args: cobra.ExactArgs(1),
+ Short: treeDescription,
+ Long: treeDescription,
+ RunE: tree,
+ Example: "podman image tree alpine:latest",
+ }
+ treeOpts entities.ImageTreeOptions
+)
+
+func init() {
+ registry.Commands = append(registry.Commands, registry.CliCommand{
+ Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode},
+ Command: treeCmd,
+ Parent: imageCmd,
+ })
+ treeCmd.Flags().BoolVar(&treeOpts.WhatRequires, "whatrequires", false, "Show all child images and layers of the specified image")
+}
+
+func tree(_ *cobra.Command, args []string) error {
+ results, err := registry.ImageEngine().Tree(registry.Context(), args[0], treeOpts)
+ if err != nil {
+ return err
+ }
+ fmt.Println(results.Tree)
+ return nil
+}
diff --git a/cmd/podman/inspect.go b/cmd/podman/inspect.go
index e67bc326b..93bf58bdd 100644
--- a/cmd/podman/inspect.go
+++ b/cmd/podman/inspect.go
@@ -1,10 +1,8 @@
package main
import (
- "context"
"fmt"
- "github.com/containers/image/v5/docker/reference"
"github.com/containers/libpod/cmd/podman/common"
"github.com/containers/libpod/cmd/podman/containers"
"github.com/containers/libpod/cmd/podman/images"
@@ -21,11 +19,12 @@ var (
// Command: podman _inspect_ Object_ID
inspectCmd = &cobra.Command{
Use: "inspect [flags] {CONTAINER_ID | IMAGE_ID}",
- Args: cobra.ExactArgs(1),
Short: "Display the configuration of object denoted by ID",
Long: "Displays the low-level information on an object identified by name or ID",
TraverseChildren: true,
RunE: inspect,
+ Example: `podman inspect alpine
+ podman inspect --format "imageId: {{.Id}} size: {{.Size}}" alpine`,
}
)
@@ -35,21 +34,25 @@ func init() {
Command: inspectCmd,
})
inspectOpts = common.AddInspectFlagSet(inspectCmd)
+ flags := inspectCmd.Flags()
+ flags.StringVarP(&inspectOpts.Type, "type", "t", "", "Return JSON for specified type, (image or container) (default \"all\")")
+ if !registry.IsRemote() {
+ flags.BoolVarP(&inspectOpts.Latest, "latest", "l", false, "Act on the latest container podman is aware of (containers only)")
+ }
}
func inspect(cmd *cobra.Command, args []string) error {
- // First check if the input is even valid for an image
- if _, err := reference.Parse(args[0]); err == nil {
- if found, err := registry.ImageEngine().Exists(context.Background(), args[0]); err != nil {
- return err
- } else if found.Value {
- return images.Inspect(cmd, args, inspectOpts)
+ switch inspectOpts.Type {
+ case "image":
+ return images.Inspect(cmd, args, inspectOpts)
+ case "container":
+ return containers.Inspect(cmd, args, inspectOpts)
+ case "":
+ if err := images.Inspect(cmd, args, inspectOpts); err == nil {
+ return nil
}
- }
- if found, err := registry.ContainerEngine().ContainerExists(context.Background(), args[0]); err != nil {
- return err
- } else if found.Value {
return containers.Inspect(cmd, args, inspectOpts)
+ default:
+ return fmt.Errorf("invalid type %q is must be 'container' or 'image'", inspectOpts.Type)
}
- return fmt.Errorf("%s not found on system", args[0])
}
diff --git a/cmd/podman/system/service.go b/cmd/podman/system/service.go
index fa1a33faa..e09107b53 100644
--- a/cmd/podman/system/service.go
+++ b/cmd/podman/system/service.go
@@ -2,8 +2,10 @@ package system
import (
"fmt"
+ "net/url"
"os"
"path/filepath"
+ "syscall"
"time"
"github.com/containers/libpod/cmd/podman/registry"
@@ -57,7 +59,24 @@ func service(cmd *cobra.Command, args []string) error {
if err != nil {
return err
}
- logrus.Infof("using API endpoint: \"%s\"", apiURI)
+ logrus.Infof("using API endpoint: '%s'", apiURI)
+
+ // Clean up any old existing unix domain socket
+ if len(apiURI) > 0 {
+ uri, err := url.Parse(apiURI)
+ if err != nil {
+ return err
+ }
+
+ // socket activation uses a unix:// socket in the shipped unit files but apiURI is coded as "" at this layer.
+ if "unix" == uri.Scheme && !registry.IsRemote() {
+ if err := syscall.Unlink(uri.Path); err != nil && !os.IsNotExist(err) {
+ return err
+ }
+ mask := syscall.Umask(0177)
+ defer syscall.Umask(mask)
+ }
+ }
opts := entities.ServiceOptions{
URI: apiURI,
@@ -75,7 +94,6 @@ func service(cmd *cobra.Command, args []string) error {
}
func resolveApiURI(_url []string) (string, error) {
-
// When determining _*THE*_ listening endpoint --
// 1) User input wins always
// 2) systemd socket activation
@@ -83,14 +101,15 @@ func resolveApiURI(_url []string) (string, error) {
// 4) if varlink -- adapter.DefaultVarlinkAddress
// 5) lastly adapter.DefaultAPIAddress
- if _url == nil {
+ if len(_url) == 0 {
if v, found := os.LookupEnv("PODMAN_SOCKET"); found {
+ logrus.Debugf("PODMAN_SOCKET='%s' used to determine API endpoint", v)
_url = []string{v}
}
}
switch {
- case len(_url) > 0:
+ case len(_url) > 0 && _url[0] != "":
return _url[0], nil
case systemd.SocketActivated():
logrus.Info("using systemd socket activation to determine API endpoint")