From 7b08aa78e4ede4c54fda6cd9917bb62e18d0d634 Mon Sep 17 00:00:00 2001 From: baude Date: Tue, 2 Jan 2018 16:29:43 -0600 Subject: 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 Closes: #179 Approved by: baude --- cmd/podman/attach.go | 13 +++++++++---- cmd/podman/common.go | 8 ++++++++ cmd/podman/exec.go | 19 +++++++++++++++---- cmd/podman/inspect.go | 27 ++++++++++++++++++++------- cmd/podman/kill.go | 31 ++++++++++++++++++++++--------- cmd/podman/logs.go | 11 +++++++++-- cmd/podman/rm.go | 13 ++++++++++++- cmd/podman/start.go | 11 +++++++++-- cmd/podman/stats.go | 19 +++++++++++++++++-- cmd/podman/stop.go | 17 +++++++++++++---- cmd/podman/top.go | 13 ++++++++++--- completions/bash/podman | 30 ++++++++++++++++++++++++++---- docs/podman-attach.1.md | 8 ++++++++ docs/podman-exec.1.md | 4 ++++ docs/podman-inspect.1.md | 4 ++++ docs/podman-kill.1.md | 5 +++++ docs/podman-rm.1.md | 5 +++++ docs/podman-start.1.md | 5 +++++ docs/podman-stats.1.md | 4 ++++ docs/podman-stop.1.md | 5 +++++ docs/podman-top.1.md | 4 ++++ libpod/runtime_ctr.go | 20 +++++++++++++++++++- test/podman_exec.bats | 7 +++++++ test/podman_inspect.bats | 3 +-- test/podman_kill.bats | 7 +++++++ test/podman_logs.bats | 5 ++--- test/podman_stop.bats | 7 +++++++ 27 files changed, 257 insertions(+), 48 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]) } diff --git a/completions/bash/podman b/completions/bash/podman index abb629bc9..a552f19d1 100644 --- a/completions/bash/podman +++ b/completions/bash/podman @@ -653,7 +653,10 @@ _podman_attach() { local boolean_options=" --help -h - --no-stdin" + --latest + -l + --no-stdin + " _complete_ "$options_with_args" "$boolean_options" } @@ -752,6 +755,8 @@ _podman_exec() { -u " local boolean_options=" + --latest + -l --privileged --tty -t @@ -875,6 +880,8 @@ _podman_inspect() { local boolean_options=" --help -h + --latest + -l " local options_with_args=" --format @@ -898,7 +905,10 @@ _podman_kill() { " local boolean_options=" --help - -h" + -h + --latest + -l + " _complete_ "$options_with_args" "$boolean_options" } @@ -910,6 +920,8 @@ _podman_logs() { local boolean_options=" --follow -f + --latest + -l " _complete_ "$options_with_args" "$boolean_options" @@ -1286,6 +1298,8 @@ _podman_rm() { -a --force -f + --latest + -l " local options_with_args=" @@ -1355,6 +1369,10 @@ podman_top() { local options_with_args=" " local boolean_options=" + --help + -h + --latest + -l " _complete_ "$options_with_args" "$boolean_options" } @@ -1424,7 +1442,9 @@ _podman_start() { -a --attach -i - --interactive" + --interactive + --latest + -l" _complete_ "$options_with_args" "$boolean_options" } _podman_stop() { @@ -1433,7 +1453,9 @@ _podman_stop() { " local boolean_options=" --all - -a" + -a + --latest + -l" _complete_ "$options_with_args" "$boolean_options" } diff --git a/docs/podman-attach.1.md b/docs/podman-attach.1.md index 4d8b803c8..64163b340 100644 --- a/docs/podman-attach.1.md +++ b/docs/podman-attach.1.md @@ -20,6 +20,10 @@ sequence is CTRL-p CTRL-q. You configure the key sequence using the --detach-key Override the key sequence for detaching a container. Format is a single character [a-Z] or ctrl- where is one of: a-z, @, ^, [, , or _. +**--latest, -l** +Instead of providing the container name or ID, use the last created container. If you use methods other than Podman +to run containers such as CRI-O, the last started container could be from either of those methods. + **--no-stdin** Do not attach STDIN. The default is false. @@ -30,6 +34,10 @@ podman attach foobar [root@localhost /]# ``` ``` +podman attach --latest +[root@localhost /]# +``` +``` podman attach 1234 [root@localhost /]# ``` diff --git a/docs/podman-exec.1.md b/docs/podman-exec.1.md index a9795002e..3c501b169 100644 --- a/docs/podman-exec.1.md +++ b/docs/podman-exec.1.md @@ -22,6 +22,10 @@ command to be executed. **--interactive, -i** Not supported. All exec commands are interactive by default. +**--latest, -l** +Instead of providing the container name or ID, use the last created container. If you use methods other than Podman +to run containers such as CRI-O, the last started container could be from either of those methods. + **--privileged** Give the process extended Linux capabilities when running the command in container. diff --git a/docs/podman-inspect.1.md b/docs/podman-inspect.1.md index c2edf896d..5b8a344d7 100644 --- a/docs/podman-inspect.1.md +++ b/docs/podman-inspect.1.md @@ -21,6 +21,10 @@ Return data on items of the specified type. Type can be 'container', 'image' or Format the output using the given Go template +**--latest, -l** +Instead of providing the container name or ID, use the last created container. If you use methods other than Podman +to run containers such as CRI-O, the last started container could be from either of those methods. + **--size** Display the total file size if the type is a container diff --git a/docs/podman-kill.1.md b/docs/podman-kill.1.md index e254f2af3..62cb39db4 100644 --- a/docs/podman-kill.1.md +++ b/docs/podman-kill.1.md @@ -12,6 +12,9 @@ podman kill - Kills one or more containers with a signal The main process inside each container specified will be sent SIGKILL, or any signal specified with option --signal. ## OPTIONS +**--latest, -l** +Instead of providing the container name or ID, use the last created container. If you use methods other than Podman +to run containers such as CRI-O, the last started container could be from either of those methods. **--signal, s** @@ -26,6 +29,8 @@ podman kill 860a4b23 podman kill --signal TERM 860a4b23 +podman kill --latest + ## SEE ALSO podman(1), podman-stop(1) diff --git a/docs/podman-rm.1.md b/docs/podman-rm.1.md index 0d86dae1c..1047c7fc7 100644 --- a/docs/podman-rm.1.md +++ b/docs/podman-rm.1.md @@ -21,6 +21,9 @@ Force the removal of a running container Remove all containers. Can be used in conjunction with -f as well. +**--latest, -l** +Instead of providing the container name or ID, use the last created container. If you use methods other than Podman +to run containers such as CRI-O, the last started container could be from either of those methods. ## EXAMPLE podman rm mywebserver @@ -31,6 +34,8 @@ podman rm -f 860a4b23 podman rm -f -a +podman rm -f --latest + ## SEE ALSO podman(1), podman-rmi(1) diff --git a/docs/podman-start.1.md b/docs/podman-start.1.md index a6791127a..492787e6c 100644 --- a/docs/podman-start.1.md +++ b/docs/podman-start.1.md @@ -29,6 +29,9 @@ ctrl- where is one of: a-z, @, ^, [, , or _. Attach container's STDIN. The default is false. +**--latest, -l** +Instead of providing the container name or ID, use the last created container. If you use methods other than Podman +to run containers such as CRI-O, the last started container could be from either of those methods. ## EXAMPLE @@ -38,6 +41,8 @@ podman start 860a4b23 5421ab4 podman start -i -a 860a4b23 +podman start -i -l + ## SEE ALSO podman(1), podman-create(1) diff --git a/docs/podman-stats.1.md b/docs/podman-stats.1.md index 6d050b485..b071a27fa 100644 --- a/docs/podman-stats.1.md +++ b/docs/podman-stats.1.md @@ -17,6 +17,10 @@ Display a live stream of one or more containers' resource usage statistics Show all containers. Only running containers are shown by default +**--latest, -l** +Instead of providing the container name or ID, use the last created container. If you use methods other than Podman +to run containers such as CRI-O, the last started container could be from either of those methods. + **--no-reset** Do not clear the terminal/screen in between reporting intervals diff --git a/docs/podman-stop.1.md b/docs/podman-stop.1.md index ad15b9117..f4372be5f 100644 --- a/docs/podman-stop.1.md +++ b/docs/podman-stop.1.md @@ -23,6 +23,9 @@ Timeout to wait before forcibly stopping the container Stop all running containers. This does not include paused containers. +**--latest, -l** +Instead of providing the container name or ID, use the last created container. If you use methods other than Podman +to run containers such as CRI-O, the last started container could be from either of those methods. ## EXAMPLE @@ -36,6 +39,8 @@ podman stop --timeout 2 860a4b23 podman stop -a +podman stop --latest + ## SEE ALSO podman(1), podman-rm(1) diff --git a/docs/podman-top.1.md b/docs/podman-top.1.md index 1067cdc52..eed15c584 100644 --- a/docs/podman-top.1.md +++ b/docs/podman-top.1.md @@ -21,6 +21,10 @@ Display the running process of the container. ps-OPTION can be any of the option **--format** Display the output in an alternate format. The only supported format is **JSON**. +**--latest, -l** +Instead of providing the container name or ID, use the last created container. If you use methods other than Podman +to run containers such as CRI-O, the last started container could be from either of those methods. + ## EXAMPLES ``` diff --git a/libpod/runtime_ctr.go b/libpod/runtime_ctr.go index 914d457a0..0f39ead35 100644 --- a/libpod/runtime_ctr.go +++ b/libpod/runtime_ctr.go @@ -3,6 +3,7 @@ package libpod import ( "os" "path/filepath" + "time" spec "github.com/opencontainers/runtime-spec/specs-go" "github.com/pkg/errors" @@ -204,7 +205,6 @@ func (r *Runtime) LookupContainer(idOrName string) (*Container, error) { if !r.valid { return nil, ErrRuntimeStopped } - return r.state.LookupContainer(idOrName) } @@ -268,3 +268,21 @@ func (r *Runtime) GetContainersByList(containers []string) ([]*Container, error) } return ctrs, nil } + +// GetLatestContainer returns a container object of the latest created container. +func (r *Runtime) GetLatestContainer() (*Container, error) { + var lastCreatedIndex int + var lastCreatedTime time.Time + ctrs, err := r.GetAllContainers() + if err != nil { + return nil, errors.Wrapf(err, "unable to find latest container") + } + for containerIndex, ctr := range ctrs { + createdTime := ctr.config.CreatedTime + if createdTime.After(lastCreatedTime) { + lastCreatedTime = createdTime + lastCreatedIndex = containerIndex + } + } + return ctrs[lastCreatedIndex], nil +} diff --git a/test/podman_exec.bats b/test/podman_exec.bats index 2d6a42704..f62da59a3 100644 --- a/test/podman_exec.bats +++ b/test/podman_exec.bats @@ -28,3 +28,10 @@ function setup() { echo "$output" [ "$status" -eq 0 ] } + +@test "exec simple command using latest" { + ${PODMAN_BINARY} ${PODMAN_OPTIONS} run -d -t ${ALPINE} sleep 60 + run ${PODMAN_BINARY} ${PODMAN_OPTIONS} exec -l ls + echo "$output" + [ "$status" -eq 0 ] +} diff --git a/test/podman_inspect.bats b/test/podman_inspect.bats index 5c353aae8..9f9336f48 100644 --- a/test/podman_inspect.bats +++ b/test/podman_inspect.bats @@ -45,8 +45,7 @@ function setup() { run bash -c "${PODMAN_BINARY} ${PODMAN_OPTIONS} create ${BB} ls" echo "$output" [ "$status" -eq 0 ] - ctr_id="$output" - run bash -c "${PODMAN_BINARY} $PODMAN_OPTIONS inspect --size $ctr_id | python -m json.tool | grep SizeRootFs" + run bash -c "${PODMAN_BINARY} $PODMAN_OPTIONS inspect --size -l | python -m json.tool | grep SizeRootFs" echo "$output" [ "$status" -eq 0 ] } diff --git a/test/podman_kill.bats b/test/podman_kill.bats index 1ccf373bb..bb55ed31d 100644 --- a/test/podman_kill.bats +++ b/test/podman_kill.bats @@ -62,3 +62,10 @@ function setup() { run bash -c "${PODMAN_BINARY} ${PODMAN_OPTIONS} ps --no-trunc" [ "$status" -eq 0 ] } + +@test "kill the latest container run" { + ${PODMAN_BINARY} ${PODMAN_OPTIONS} run -d ${ALPINE} sleep 9999 + run bash -c "${PODMAN_BINARY} ${PODMAN_OPTIONS} kill -l" + echo "$output" + [ "$status" -eq 0 ] +} diff --git a/test/podman_logs.bats b/test/podman_logs.bats index 4c20654a7..342ffac5e 100644 --- a/test/podman_logs.bats +++ b/test/podman_logs.bats @@ -42,11 +42,10 @@ function setup() { run bash -c "${PODMAN_BINARY} ${PODMAN_OPTIONS} run -d $BB ls" echo "$output" [ "$status" -eq 0 ] - ctr_id="$output" - run bash -c "${PODMAN_BINARY} ${PODMAN_OPTIONS} logs --since 2017-08-07T10:10:09.056611202-04:00 $ctr_id" + run bash -c "${PODMAN_BINARY} ${PODMAN_OPTIONS} logs --since 2017-08-07T10:10:09.056611202-04:00 -l" echo "$output" [ "$status" -eq 0 ] - run bash -c "${PODMAN_BINARY} ${PODMAN_OPTIONS} rm $ctr_id" + run bash -c "${PODMAN_BINARY} ${PODMAN_OPTIONS} rm -l" echo "$output" [ "$status" -eq 0 ] } diff --git a/test/podman_stop.bats b/test/podman_stop.bats index 498d71838..839301435 100644 --- a/test/podman_stop.bats +++ b/test/podman_stop.bats @@ -47,3 +47,10 @@ function setup() { echo "$output" [ "$status" -eq 0 ] } + +@test "stop a container with latest" { + ${PODMAN_BINARY} ${PODMAN_OPTIONS} run -d ${ALPINE} sleep 9999 + run bash -c "${PODMAN_BINARY} ${PODMAN_OPTIONS} stop -t 1 -l" + echo "$output" + [ "$status" -eq 0 ] +} -- cgit v1.2.3-54-g00ecf