aboutsummaryrefslogtreecommitdiff
path: root/cmd/podman
diff options
context:
space:
mode:
authorbaude <bbaude@redhat.com>2018-01-02 16:29:43 -0600
committerAtomic Bot <atomic-devel@projectatomic.io>2018-01-08 19:12:17 +0000
commit7b08aa78e4ede4c54fda6cd9917bb62e18d0d634 (patch)
tree1c480d9dfb8db3268dc3fdcca827792278a3ae47 /cmd/podman
parent6baf6e461de6e560cc48d35239e7c392bec4481c (diff)
downloadpodman-7b08aa78e4ede4c54fda6cd9917bb62e18d0d634.tar.gz
podman-7b08aa78e4ede4c54fda6cd9917bb62e18d0d634.tar.bz2
podman-7b08aa78e4ede4c54fda6cd9917bb62e18d0d634.zip
Shortcut for most recent container
It is desirable to have a shortcut for the most recently created container. We can now use "**latest" to represent the most recent container instead of its container ID or name. For example: Signed-off-by: baude <bbaude@redhat.com> Closes: #179 Approved by: baude
Diffstat (limited to 'cmd/podman')
-rw-r--r--cmd/podman/attach.go13
-rw-r--r--cmd/podman/common.go8
-rw-r--r--cmd/podman/exec.go19
-rw-r--r--cmd/podman/inspect.go27
-rw-r--r--cmd/podman/kill.go31
-rw-r--r--cmd/podman/logs.go11
-rw-r--r--cmd/podman/rm.go13
-rw-r--r--cmd/podman/start.go11
-rw-r--r--cmd/podman/stats.go19
-rw-r--r--cmd/podman/stop.go17
-rw-r--r--cmd/podman/top.go13
11 files changed, 144 insertions, 38 deletions
diff --git a/cmd/podman/attach.go b/cmd/podman/attach.go
index 8c2c99fd5..e468964f6 100644
--- a/cmd/podman/attach.go
+++ b/cmd/podman/attach.go
@@ -19,6 +19,7 @@ var (
Name: "no-stdin",
Usage: "Do not attach STDIN. The default is false.",
},
+ LatestFlag,
}
attachDescription = "The podman attach command allows you to attach to a running container using the container's ID or name, either to view its ongoing output or to control it interactively."
attachCommand = cli.Command{
@@ -33,12 +34,12 @@ var (
func attachCmd(c *cli.Context) error {
args := c.Args()
+ var ctr *libpod.Container
if err := validateFlags(c, attachFlags); err != nil {
return err
}
-
- if len(c.Args()) < 1 || len(c.Args()) > 1 {
- return errors.Errorf("attach requires the name or id of one running container")
+ if len(c.Args()) > 1 || (len(c.Args()) == 0 && !c.Bool("latest")) {
+ return errors.Errorf("attach requires the name or id of one running container or the latest flag")
}
runtime, err := getRuntime(c)
@@ -47,7 +48,11 @@ func attachCmd(c *cli.Context) error {
}
defer runtime.Shutdown(false)
- ctr, err := runtime.LookupContainer(args[0])
+ if c.Bool("latest") {
+ ctr, err = runtime.GetLatestContainer()
+ } else {
+ ctr, err = runtime.LookupContainer(args[0])
+ }
if err != nil {
return errors.Wrapf(err, "unable to exec into %s", args[0])
diff --git a/cmd/podman/common.go b/cmd/podman/common.go
index 5e670dcc8..e3997539a 100644
--- a/cmd/podman/common.go
+++ b/cmd/podman/common.go
@@ -14,6 +14,14 @@ import (
"github.com/urfave/cli"
)
+var (
+ stores = make(map[storage.Store]struct{})
+ LatestFlag = cli.BoolFlag{
+ Name: "latest, l",
+ Usage: "act on the latest container podman is aware of",
+ }
+)
+
const crioConfigPath = "/etc/crio/crio.conf"
func getRuntime(c *cli.Context) (*libpod.Runtime, error) {
diff --git a/cmd/podman/exec.go b/cmd/podman/exec.go
index 7a0bab617..07ef3a0cd 100644
--- a/cmd/podman/exec.go
+++ b/cmd/podman/exec.go
@@ -27,6 +27,7 @@ var (
Name: "user, u",
Usage: "Sets the username or UID used and optionally the groupname or GID for the specified command",
},
+ LatestFlag,
}
execDescription = `
podman exec
@@ -48,20 +49,30 @@ var (
func execCmd(c *cli.Context) error {
var envs []string
args := c.Args()
- if len(args) < 1 {
+ var ctr *libpod.Container
+ var err error
+ argStart := 1
+ if len(args) < 1 && !c.Bool("latest") {
return errors.Errorf("you must provide one container name or id")
}
- if len(args) < 2 {
+ if len(args) < 2 && !c.Bool("latest") {
return errors.Errorf("you must provide a command to exec")
}
- cmd := args[1:]
+ if c.Bool("latest") {
+ argStart = 0
+ }
+ cmd := args[argStart:]
runtime, err := getRuntime(c)
if err != nil {
return errors.Wrapf(err, "error creating libpod runtime")
}
defer runtime.Shutdown(false)
- ctr, err := runtime.LookupContainer(args[0])
+ if c.Bool("latest") {
+ ctr, err = runtime.GetLatestContainer()
+ } else {
+ ctr, err = runtime.LookupContainer(args[0])
+ }
if err != nil {
return errors.Wrapf(err, "unable to exec into %s", args[0])
}
diff --git a/cmd/podman/inspect.go b/cmd/podman/inspect.go
index 869d16911..dc5810492 100644
--- a/cmd/podman/inspect.go
+++ b/cmd/podman/inspect.go
@@ -33,6 +33,7 @@ var (
Name: "size",
Usage: "Display total file size if the type is container",
},
+ LatestFlag,
}
inspectDescription = "This displays the low-level information on containers and images identified by name or ID. By default, this will render all results in a JSON array. If the container and image have the same name, this will return container JSON for unspecified type."
inspectCommand = cli.Command{
@@ -47,7 +48,10 @@ var (
func inspectCmd(c *cli.Context) error {
args := c.Args()
- if len(args) == 0 {
+ inspectType := c.String("type")
+ latestContainer := c.Bool("latest")
+ var name string
+ if len(args) == 0 && !latestContainer {
return errors.Errorf("container or image name must be specified: podman inspect [options [...]] name")
}
if len(args) > 1 {
@@ -63,17 +67,26 @@ func inspectCmd(c *cli.Context) error {
}
defer runtime.Shutdown(false)
- if c.String("type") != inspectTypeContainer && c.String("type") != inspectTypeImage && c.String("type") != inspectAll {
+ if !libpod.StringInSlice(inspectType, []string{inspectTypeContainer, inspectTypeImage, inspectAll}) {
return errors.Errorf("the only recognized types are %q, %q, and %q", inspectTypeContainer, inspectTypeImage, inspectAll)
}
-
- name := args[0]
-
+ if !latestContainer {
+ name = args[0]
+ }
+ if latestContainer {
+ inspectType = inspectTypeContainer
+ }
outputFormat := c.String("format")
var data interface{}
- switch c.String("type") {
+ switch inspectType {
case inspectTypeContainer:
- ctr, err := runtime.LookupContainer(name)
+ var ctr *libpod.Container
+ var err error
+ if latestContainer {
+ ctr, err = runtime.GetLatestContainer()
+ } else {
+ ctr, err = runtime.LookupContainer(name)
+ }
if err != nil {
return errors.Wrapf(err, "error looking up container %q", name)
}
diff --git a/cmd/podman/kill.go b/cmd/podman/kill.go
index 776c7ef20..c24e68c54 100644
--- a/cmd/podman/kill.go
+++ b/cmd/podman/kill.go
@@ -1,10 +1,10 @@
package main
import (
- "fmt"
"os"
"syscall"
+ "fmt"
"github.com/docker/docker/pkg/signal"
"github.com/pkg/errors"
"github.com/urfave/cli"
@@ -17,24 +17,29 @@ var (
Usage: "Signal to send to the container",
Value: "KILL",
},
+ LatestFlag,
}
killDescription = "The main process inside each container specified will be sent SIGKILL, or any signal specified with option --signal."
killCommand = cli.Command{
- Name: "kill",
- Usage: "Kill one or more running containers with a specific signal",
- Description: killDescription,
- Flags: killFlags,
- Action: killCmd,
- ArgsUsage: "[CONTAINER_NAME_OR_ID]",
+ Name: "kill",
+ Usage: "Kill one or more running containers with a specific signal",
+ Description: killDescription,
+ Flags: killFlags,
+ Action: killCmd,
+ ArgsUsage: "[CONTAINER_NAME_OR_ID]",
+ UseShortOptionHandling: true,
}
)
// killCmd kills one or more containers with a signal
func killCmd(c *cli.Context) error {
args := c.Args()
- if len(args) == 0 {
+ if len(args) == 0 && !c.Bool("latest") {
return errors.Errorf("specify one or more containers to kill")
}
+ if len(args) > 0 && c.Bool("latest") {
+ return errors.Errorf("you cannot specific any containers to kill with --latest")
+ }
if err := validateFlags(c, killFlags); err != nil {
return err
}
@@ -56,8 +61,16 @@ func killCmd(c *cli.Context) error {
killSignal = uint(sysSignal)
}
+ if c.Bool("latest") {
+ latestCtr, err := runtime.GetLatestContainer()
+ if err != nil {
+ return errors.Wrapf(err, "unable to get latest container")
+ }
+ args = append(args, latestCtr.ID())
+ }
+
var lastError error
- for _, container := range c.Args() {
+ for _, container := range args {
ctr, err := runtime.LookupContainer(container)
if err != nil {
if lastError != nil {
diff --git a/cmd/podman/logs.go b/cmd/podman/logs.go
index 8745d5d7f..b31dce2d3 100644
--- a/cmd/podman/logs.go
+++ b/cmd/podman/logs.go
@@ -37,6 +37,7 @@ var (
Name: "tail",
Usage: "Output the specified number of LINES at the end of the logs. Defaults to 0, which prints all lines",
},
+ LatestFlag,
}
logsDescription = "The podman logs command batch-retrieves whatever logs are present for a container at the time of execution. This does not guarantee execution" +
"order when combined with podman run (i.e. your run may not have generated any logs at the time you execute podman logs"
@@ -51,6 +52,8 @@ var (
)
func logsCmd(c *cli.Context) error {
+ var ctr *libpod.Container
+ var err error
if err := validateFlags(c, logsFlags); err != nil {
return err
}
@@ -62,7 +65,7 @@ func logsCmd(c *cli.Context) error {
defer runtime.Shutdown(false)
args := c.Args()
- if len(args) != 1 {
+ if len(args) != 1 && !c.Bool("latest") {
return errors.Errorf("'podman logs' requires exactly one container name/ID")
}
@@ -83,7 +86,11 @@ func logsCmd(c *cli.Context) error {
tail: c.Uint64("tail"),
}
- ctr, err := runtime.LookupContainer(args[0])
+ if c.Bool("latest") {
+ ctr, err = runtime.GetLatestContainer()
+ } else {
+ ctr, err = runtime.LookupContainer(args[0])
+ }
if err != nil {
return err
}
diff --git a/cmd/podman/rm.go b/cmd/podman/rm.go
index dcb8fac57..8dd3475c0 100644
--- a/cmd/podman/rm.go
+++ b/cmd/podman/rm.go
@@ -19,6 +19,7 @@ var (
Name: "all, a",
Usage: "Remove all containers",
},
+ LatestFlag,
}
rmDescription = "Remove one or more containers"
rmCommand = cli.Command{
@@ -46,7 +47,11 @@ func rmCmd(c *cli.Context) error {
defer runtime.Shutdown(false)
args := c.Args()
- if len(args) == 0 && !c.Bool("all") {
+ if c.Bool("latest") && c.Bool("all") {
+ return errors.Errorf("--all and --latest cannot be used together")
+ }
+
+ if len(args) == 0 && !c.Bool("all") && !c.Bool("latest") {
return errors.Errorf("specify one or more containers to remove")
}
@@ -57,6 +62,12 @@ func rmCmd(c *cli.Context) error {
if err != nil {
return errors.Wrapf(err, "unable to get container list")
}
+ } else if c.Bool("latest") {
+ lastCtr, err := runtime.GetLatestContainer()
+ if err != nil {
+ return errors.Wrapf(err, "unable to get latest container")
+ }
+ delContainers = append(delContainers, lastCtr)
} else {
for _, i := range args {
container, err := runtime.LookupContainer(i)
diff --git a/cmd/podman/start.go b/cmd/podman/start.go
index d4ddfbbe7..0dad5e237 100644
--- a/cmd/podman/start.go
+++ b/cmd/podman/start.go
@@ -26,6 +26,7 @@ var (
Name: "interactive, i",
Usage: "Keep STDIN open even if not attached",
},
+ LatestFlag,
}
startDescription = `
podman start
@@ -46,7 +47,7 @@ var (
func startCmd(c *cli.Context) error {
args := c.Args()
- if len(args) < 1 {
+ if len(args) < 1 && !c.Bool("latest") {
return errors.Errorf("you must provide at least one container name or id")
}
@@ -65,7 +66,13 @@ func startCmd(c *cli.Context) error {
return errors.Wrapf(err, "error creating libpod runtime")
}
defer runtime.Shutdown(false)
-
+ if c.Bool("latest") {
+ lastCtr, err := runtime.GetLatestContainer()
+ if err != nil {
+ return errors.Wrapf(err, "unable to get latest container")
+ }
+ args = append(args, lastCtr.ID())
+ }
var lastError error
for _, container := range args {
// Create a bool channel to track that the console socket attach
diff --git a/cmd/podman/stats.go b/cmd/podman/stats.go
index cf54a8bfe..d2ffd8a75 100644
--- a/cmd/podman/stats.go
+++ b/cmd/podman/stats.go
@@ -42,7 +42,7 @@ var (
cli.BoolFlag{
Name: "no-reset",
Usage: "disable resetting the screen between intervals",
- },
+ }, LatestFlag,
}
statsDescription = "display a live stream of one or more containers' resource usage statistics"
@@ -61,6 +61,15 @@ func statsCmd(c *cli.Context) error {
return err
}
+ all := c.Bool("all")
+
+ if c.Bool("latest") && all {
+ return errors.Errorf("--all and --latest cannot be used together")
+ }
+
+ if c.Bool("latest") && len(c.Args()) > 0 {
+ return errors.Errorf("no container names are allowed with --latest")
+ }
runtime, err := getRuntime(c)
if err != nil {
return errors.Wrapf(err, "could not get runtime")
@@ -75,7 +84,6 @@ func statsCmd(c *cli.Context) error {
var format string
var ctrs []*libpod.Container
var containerFunc func() ([]*libpod.Container, error)
- all := c.Bool("all")
if c.IsSet("format") {
format = c.String("format")
@@ -85,6 +93,13 @@ func statsCmd(c *cli.Context) error {
if len(c.Args()) > 0 {
containerFunc = func() ([]*libpod.Container, error) { return runtime.GetContainersByList(c.Args()) }
+ } else if c.Bool("latest") {
+ containerFunc = func() ([]*libpod.Container, error) {
+ var ctrs []*libpod.Container
+ lastCtr, err := runtime.GetLatestContainer()
+ ctrs = append(ctrs, lastCtr)
+ return ctrs, err
+ }
} else if all {
containerFunc = runtime.GetAllContainers
} else {
diff --git a/cmd/podman/stop.go b/cmd/podman/stop.go
index f85512d47..d18a05bd4 100644
--- a/cmd/podman/stop.go
+++ b/cmd/podman/stop.go
@@ -19,7 +19,7 @@ var (
cli.BoolFlag{
Name: "all, a",
Usage: "stop all running containers",
- },
+ }, LatestFlag,
}
stopDescription = `
podman stop
@@ -41,10 +41,13 @@ var (
func stopCmd(c *cli.Context) error {
args := c.Args()
- if c.Bool("all") && len(args) > 0 {
- return errors.Errorf("no arguments are needed with -a")
+ if (c.Bool("all") || c.Bool("latest")) && len(args) > 0 {
+ return errors.Errorf("no arguments are needed with --all or --latest")
+ }
+ if c.Bool("all") && c.Bool("latest") {
+ return errors.Errorf("--all and --latest cannot be used together")
}
- if len(args) < 1 && !c.Bool("all") {
+ if len(args) < 1 && !c.Bool("all") && !c.Bool("latest") {
return errors.Errorf("you must provide at least one container name or id")
}
if err := validateFlags(c, stopFlags); err != nil {
@@ -71,6 +74,12 @@ func stopCmd(c *cli.Context) error {
if err != nil {
return errors.Wrapf(err, "unable to get running containers")
}
+ } else if c.Bool("latest") {
+ lastCtr, err := runtime.GetLatestContainer()
+ if err != nil {
+ return errors.Wrapf(err, "unable to get last created container")
+ }
+ containers = append(containers, lastCtr)
} else {
for _, i := range args {
container, err := runtime.LookupContainer(i)
diff --git a/cmd/podman/top.go b/cmd/podman/top.go
index 796b31c1d..5b1dbd05c 100644
--- a/cmd/podman/top.go
+++ b/cmd/podman/top.go
@@ -16,7 +16,7 @@ var (
cli.StringFlag{
Name: "format",
Usage: "Change the output to JSON",
- },
+ }, LatestFlag,
}
topDescription = `
podman top
@@ -36,6 +36,8 @@ var (
)
func topCmd(c *cli.Context) error {
+ var container *libpod.Container
+ var err error
doJSON := false
if c.IsSet("format") {
if strings.ToUpper(c.String("format")) == "JSON" {
@@ -47,7 +49,7 @@ func topCmd(c *cli.Context) error {
args := c.Args()
var psArgs []string
psOpts := []string{"-o", "uid,pid,ppid,c,stime,tname,time,cmd"}
- if len(args) < 1 {
+ if len(args) < 1 && !c.Bool("latest") {
return errors.Errorf("you must provide the name or id of a running container")
}
if err := validateFlags(c, topFlags); err != nil {
@@ -63,7 +65,12 @@ func topCmd(c *cli.Context) error {
psOpts = args[1:]
}
- container, err := runtime.LookupContainer(args[0])
+ if c.Bool("latest") {
+ container, err = runtime.GetLatestContainer()
+ } else {
+ container, err = runtime.LookupContainer(args[0])
+ }
+
if err != nil {
return errors.Wrapf(err, "unable to lookup %s", args[0])
}