mirror of
https://github.com/containers/podman
synced 2024-10-22 02:03:38 +00:00
kube: Add support for podman pod logs
Following PR adds support for `kubectl` like `pod logs` to podman. Usage `podman pod logs <podIDorName` gives a stream of logs for all the containers within the pod with **containername** as a field. Just like **`kubectl`** also supports `podman pod logs -c ctrIDorName podIDorName` to limit the log stream to any of the specificied container which belongs to pod. Signed-off-by: Aditya Rajan <arajan@redhat.com>
This commit is contained in:
parent
858d3e47c2
commit
11fc0e5540
140
cmd/podman/pods/logs.go
Normal file
140
cmd/podman/pods/logs.go
Normal file
|
@ -0,0 +1,140 @@
|
||||||
|
package pods
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/containers/common/pkg/completion"
|
||||||
|
"github.com/containers/podman/v3/cmd/podman/common"
|
||||||
|
"github.com/containers/podman/v3/cmd/podman/registry"
|
||||||
|
"github.com/containers/podman/v3/cmd/podman/validate"
|
||||||
|
"github.com/containers/podman/v3/libpod/define"
|
||||||
|
"github.com/containers/podman/v3/pkg/domain/entities"
|
||||||
|
"github.com/containers/podman/v3/pkg/util"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
// logsOptionsWrapper wraps entities.LogsOptions and prevents leaking
|
||||||
|
// CLI-only fields into the API types.
|
||||||
|
type logsOptionsWrapper struct {
|
||||||
|
entities.PodLogsOptions
|
||||||
|
|
||||||
|
SinceRaw string
|
||||||
|
|
||||||
|
UntilRaw string
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
logsPodOptions logsOptionsWrapper
|
||||||
|
logsPodDescription = `Displays logs for pod with one or more containers.`
|
||||||
|
logsPodCommand = &cobra.Command{
|
||||||
|
Use: "logs [options] POD",
|
||||||
|
Short: "Fetch logs for pod with one or more containers",
|
||||||
|
Long: logsPodDescription,
|
||||||
|
// We dont want users to invoke latest and pod togather
|
||||||
|
Args: func(cmd *cobra.Command, args []string) error {
|
||||||
|
switch {
|
||||||
|
case registry.IsRemote() && logsPodOptions.Latest:
|
||||||
|
return errors.New(cmd.Name() + " does not support 'latest' when run remotely")
|
||||||
|
case len(args) > 1:
|
||||||
|
return errors.New("requires exactly 1 arg")
|
||||||
|
case logsPodOptions.Latest && len(args) > 0:
|
||||||
|
return errors.New("--latest and pods cannot be used together")
|
||||||
|
case !logsPodOptions.Latest && len(args) < 1:
|
||||||
|
return errors.New("specify at least one pod name or ID to log")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
RunE: logs,
|
||||||
|
ValidArgsFunction: common.AutocompletePods,
|
||||||
|
Example: `podman pod logs podID
|
||||||
|
podman pod logs -c ctrname podName
|
||||||
|
podman pod logs --tail 2 mywebserver
|
||||||
|
podman pod logs --follow=true --since 10m podID
|
||||||
|
podman pod logs mywebserver`,
|
||||||
|
}
|
||||||
|
|
||||||
|
containerLogsCommand = &cobra.Command{
|
||||||
|
Use: logsPodCommand.Use,
|
||||||
|
Short: logsPodCommand.Short,
|
||||||
|
Long: logsPodCommand.Long,
|
||||||
|
Args: logsPodCommand.Args,
|
||||||
|
RunE: logsPodCommand.RunE,
|
||||||
|
ValidArgsFunction: logsPodCommand.ValidArgsFunction,
|
||||||
|
Example: `podman pod logs podId
|
||||||
|
podman pod logs -c ctrname podName
|
||||||
|
podman pod logs --tail 2 mywebserver
|
||||||
|
podman pod logs --follow=true --since 10m podID`,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
registry.Commands = append(registry.Commands, registry.CliCommand{
|
||||||
|
Command: logsPodCommand,
|
||||||
|
})
|
||||||
|
logsFlags(logsPodCommand)
|
||||||
|
validate.AddLatestFlag(logsPodCommand, &logsPodOptions.Latest)
|
||||||
|
|
||||||
|
// container logs
|
||||||
|
registry.Commands = append(registry.Commands, registry.CliCommand{
|
||||||
|
Command: containerLogsCommand,
|
||||||
|
Parent: podCmd,
|
||||||
|
})
|
||||||
|
logsFlags(containerLogsCommand)
|
||||||
|
validate.AddLatestFlag(containerLogsCommand, &logsPodOptions.Latest)
|
||||||
|
}
|
||||||
|
|
||||||
|
func logsFlags(cmd *cobra.Command) {
|
||||||
|
flags := cmd.Flags()
|
||||||
|
|
||||||
|
flags.BoolVar(&logsPodOptions.Details, "details", false, "Show extra details provided to the logs")
|
||||||
|
flags.BoolVarP(&logsPodOptions.Follow, "follow", "f", false, "Follow log output.")
|
||||||
|
|
||||||
|
containerNameFlag := "container"
|
||||||
|
flags.StringVarP(&logsPodOptions.ContainerName, containerNameFlag, "c", "", "Filter logs by container name or id which belongs to pod")
|
||||||
|
_ = cmd.RegisterFlagCompletionFunc(containerNameFlag, common.AutocompleteContainers)
|
||||||
|
|
||||||
|
sinceFlagName := "since"
|
||||||
|
flags.StringVar(&logsPodOptions.SinceRaw, sinceFlagName, "", "Show logs since TIMESTAMP")
|
||||||
|
_ = cmd.RegisterFlagCompletionFunc(sinceFlagName, completion.AutocompleteNone)
|
||||||
|
|
||||||
|
untilFlagName := "until"
|
||||||
|
flags.StringVar(&logsPodOptions.UntilRaw, untilFlagName, "", "Show logs until TIMESTAMP")
|
||||||
|
_ = cmd.RegisterFlagCompletionFunc(untilFlagName, completion.AutocompleteNone)
|
||||||
|
|
||||||
|
tailFlagName := "tail"
|
||||||
|
flags.Int64Var(&logsPodOptions.Tail, tailFlagName, -1, "Output the specified number of LINES at the end of the logs.")
|
||||||
|
_ = cmd.RegisterFlagCompletionFunc(tailFlagName, completion.AutocompleteNone)
|
||||||
|
|
||||||
|
flags.BoolVarP(&logsPodOptions.Timestamps, "timestamps", "t", false, "Output the timestamps in the log")
|
||||||
|
flags.SetInterspersed(false)
|
||||||
|
_ = flags.MarkHidden("details")
|
||||||
|
}
|
||||||
|
|
||||||
|
func logs(_ *cobra.Command, args []string) error {
|
||||||
|
if logsPodOptions.SinceRaw != "" {
|
||||||
|
// parse time, error out if something is wrong
|
||||||
|
since, err := util.ParseInputTime(logsPodOptions.SinceRaw, true)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrapf(err, "error parsing --since %q", logsPodOptions.SinceRaw)
|
||||||
|
}
|
||||||
|
logsPodOptions.Since = since
|
||||||
|
}
|
||||||
|
if logsPodOptions.UntilRaw != "" {
|
||||||
|
// parse time, error out if something is wrong
|
||||||
|
until, err := util.ParseInputTime(logsPodOptions.UntilRaw, false)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrapf(err, "error parsing --until %q", logsPodOptions.UntilRaw)
|
||||||
|
}
|
||||||
|
logsPodOptions.Until = until
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remote can only process one container at a time
|
||||||
|
if registry.IsRemote() && logsPodOptions.ContainerName == "" {
|
||||||
|
return errors.Wrapf(define.ErrInvalidArg, "-c or --container cannot be empty")
|
||||||
|
}
|
||||||
|
|
||||||
|
logsPodOptions.StdoutWriter = os.Stdout
|
||||||
|
logsPodOptions.StderrWriter = os.Stderr
|
||||||
|
return registry.ContainerEngine().PodLogs(registry.GetContext(), args[0], logsPodOptions.PodLogsOptions)
|
||||||
|
}
|
88
docs/source/markdown/podman-pod-logs.1.md
Normal file
88
docs/source/markdown/podman-pod-logs.1.md
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
% podman-pod-logs(1)
|
||||||
|
|
||||||
|
## NAME
|
||||||
|
podman\-pod\-logs - Displays logs for pod with one or more containers
|
||||||
|
|
||||||
|
## SYNOPSIS
|
||||||
|
**podman pod logs** [*options*] *pod*
|
||||||
|
|
||||||
|
## DESCRIPTION
|
||||||
|
The podman pod logs command batch-retrieves whatever logs are present with all the containers of a pod. Pod logs can be filtered by container name or id using flag **-c** or **--container** if needed.
|
||||||
|
|
||||||
|
Note: Long running command of `podman pod log` with a `-f` or `--follow` needs to be reinvoked if new container is added to the pod dynamically otherwise logs of newly added containers would not be visible in log stream.
|
||||||
|
|
||||||
|
## OPTIONS
|
||||||
|
|
||||||
|
#### **--container**, **-c**
|
||||||
|
|
||||||
|
By default `podman pod logs` retrives logs for all the containers available within the pod differentiate by field `container`. However there are use-cases where user would want to limit the log stream only to a particular container of a pod for such cases `-c` can be used like `podman pod logs -c ctrNameorID podname`.
|
||||||
|
|
||||||
|
#### **--follow**, **-f**
|
||||||
|
|
||||||
|
Follow log output. Default is false.
|
||||||
|
|
||||||
|
Note: If you are following a pod which is removed `podman pod rm`, then there is a
|
||||||
|
chance the the log file will be removed before `podman pod logs` reads the final content.
|
||||||
|
|
||||||
|
#### **--latest**, **-l**
|
||||||
|
|
||||||
|
Instead of providing the pod name or id, get logs of the last created pod. (This option is not available with the remote Podman client)
|
||||||
|
|
||||||
|
#### **--since**=*TIMESTAMP*
|
||||||
|
|
||||||
|
Show logs since TIMESTAMP. The --since option can be Unix timestamps, date formatted timestamps, or Go duration
|
||||||
|
strings (e.g. 10m, 1h30m) computed relative to the client machine's time. Supported formats for date formatted
|
||||||
|
time stamps include RFC3339Nano, RFC3339, 2006-01-02T15:04:05, 2006-01-02T15:04:05.999999999, 2006-01-02Z07:00,
|
||||||
|
and 2006-01-02.
|
||||||
|
|
||||||
|
#### **--until**=*TIMESTAMP*
|
||||||
|
|
||||||
|
Show logs until TIMESTAMP. The --until option can be Unix timestamps, date formatted timestamps, or Go duration
|
||||||
|
strings (e.g. 10m, 1h30m) computed relative to the client machine's time. Supported formats for date formatted
|
||||||
|
time stamps include RFC3339Nano, RFC3339, 2006-01-02T15:04:05, 2006-01-02T15:04:05.999999999, 2006-01-02Z07:00,
|
||||||
|
and 2006-01-02.
|
||||||
|
|
||||||
|
|
||||||
|
#### **--tail**=*LINES*
|
||||||
|
|
||||||
|
Output the specified number of LINES at the end of the logs. LINES must be an integer. Defaults to -1,
|
||||||
|
which prints all lines
|
||||||
|
|
||||||
|
#### **--timestamps**, **-t**
|
||||||
|
|
||||||
|
Show timestamps in the log outputs. The default is false
|
||||||
|
|
||||||
|
## EXAMPLE
|
||||||
|
|
||||||
|
To view a pod's logs:
|
||||||
|
```
|
||||||
|
podman pod logs -t podIdorName
|
||||||
|
```
|
||||||
|
|
||||||
|
To view logs of a specific container on the pod
|
||||||
|
```
|
||||||
|
podman pod logs -c ctrIdOrName podIdOrName
|
||||||
|
```
|
||||||
|
|
||||||
|
To view all pod logs:
|
||||||
|
```
|
||||||
|
podman pod logs -t --since 0 myserver-pod-1
|
||||||
|
```
|
||||||
|
|
||||||
|
To view a pod's logs since a certain time:
|
||||||
|
```
|
||||||
|
podman pod logs -t --since 2017-08-07T10:10:09.055837383-04:00 myserver-pod-1
|
||||||
|
```
|
||||||
|
|
||||||
|
To view a pod's logs generated in the last 10 minutes:
|
||||||
|
```
|
||||||
|
podman pod logs --since 10m myserver-pod-1
|
||||||
|
```
|
||||||
|
|
||||||
|
To view a pod's logs until 30 minutes ago:
|
||||||
|
```
|
||||||
|
podman pod logs --until 30m myserver-pod-1
|
||||||
|
```
|
||||||
|
|
||||||
|
## SEE ALSO
|
||||||
|
podman(1), podman-pod-start(1), podman-pod-rm(1), podman-logs(1)
|
|
@ -17,11 +17,12 @@ podman pod is a set of subcommands that manage pods, or groups of containers.
|
||||||
| exists | [podman-pod-exists(1)](podman-pod-exists.1.md) | Check if a pod exists in local storage. |
|
| exists | [podman-pod-exists(1)](podman-pod-exists.1.md) | Check if a pod exists in local storage. |
|
||||||
| inspect | [podman-pod-inspect(1)](podman-pod-inspect.1.md) | Displays information describing a pod. |
|
| inspect | [podman-pod-inspect(1)](podman-pod-inspect.1.md) | Displays information describing a pod. |
|
||||||
| kill | [podman-pod-kill(1)](podman-pod-kill.1.md) | Kill the main process of each container in one or more pods. |
|
| kill | [podman-pod-kill(1)](podman-pod-kill.1.md) | Kill the main process of each container in one or more pods. |
|
||||||
|
| logs | [podman-pod-logs(1)](podman-pod-logs.1.md) | Displays logs for pod with one or more containers. |
|
||||||
| pause | [podman-pod-pause(1)](podman-pod-pause.1.md) | Pause one or more pods. |
|
| pause | [podman-pod-pause(1)](podman-pod-pause.1.md) | Pause one or more pods. |
|
||||||
| prune | [podman-pod-prune(1)](podman-pod-prune.1.md) | Remove all stopped pods and their containers. |
|
| prune | [podman-pod-prune(1)](podman-pod-prune.1.md) | Remove all stopped pods and their containers. |
|
||||||
| ps | [podman-pod-ps(1)](podman-pod-ps.1.md) | Prints out information about pods. |
|
| ps | [podman-pod-ps(1)](podman-pod-ps.1.md) | Prints out information about pods. |
|
||||||
| restart | [podman-pod-restart(1)](podman-pod-restart.1.md) | Restart one or more pods. |
|
| restart | [podman-pod-restart(1)](podman-pod-restart.1.md) | Restart one or more pods. |
|
||||||
| rm | [podman-pod-rm(1)](podman-pod-rm.1.md) | Remove one or more stopped pods and containers. |
|
| rm | [podman-pod-rm(1)](podman-pod-rm.1.md) | Remove one or more stopped pods and containers. |
|
||||||
| start | [podman-pod-start(1)](podman-pod-start.1.md) | Start one or more pods. |
|
| start | [podman-pod-start(1)](podman-pod-start.1.md) | Start one or more pods. |
|
||||||
| stats | [podman-pod-stats(1)](podman-pod-stats.1.md) | Display a live stream of resource usage stats for containers in one or more pods. |
|
| stats | [podman-pod-stats(1)](podman-pod-stats.1.md) | Display a live stream of resource usage stats for containers in one or more pods. |
|
||||||
| stop | [podman-pod-stop(1)](podman-pod-stop.1.md) | Stop one or more pods. |
|
| stop | [podman-pod-stop(1)](podman-pod-stop.1.md) | Stop one or more pods. |
|
||||||
|
|
|
@ -9,6 +9,8 @@ Pod
|
||||||
|
|
||||||
:doc:`kill <markdown/podman-pod-kill.1>` Send the specified signal or SIGKILL to containers in pod
|
:doc:`kill <markdown/podman-pod-kill.1>` Send the specified signal or SIGKILL to containers in pod
|
||||||
|
|
||||||
|
:doc:`logs <markdown/podman-pod-logs.1>` Displays logs for pod with one or more containers
|
||||||
|
|
||||||
:doc:`pause <markdown/podman-pause.1>` Pause one or more pods
|
:doc:`pause <markdown/podman-pause.1>` Pause one or more pods
|
||||||
|
|
||||||
:doc:`prune <markdown/podman-pod-prune.1>` Remove all stopped pods and their containers
|
:doc:`prune <markdown/podman-pod-prune.1>` Remove all stopped pods and their containers
|
||||||
|
|
|
@ -72,6 +72,7 @@ type ContainerEngine interface {
|
||||||
PodExists(ctx context.Context, nameOrID string) (*BoolReport, error)
|
PodExists(ctx context.Context, nameOrID string) (*BoolReport, error)
|
||||||
PodInspect(ctx context.Context, options PodInspectOptions) (*PodInspectReport, error)
|
PodInspect(ctx context.Context, options PodInspectOptions) (*PodInspectReport, error)
|
||||||
PodKill(ctx context.Context, namesOrIds []string, options PodKillOptions) ([]*PodKillReport, error)
|
PodKill(ctx context.Context, namesOrIds []string, options PodKillOptions) ([]*PodKillReport, error)
|
||||||
|
PodLogs(ctx context.Context, pod string, options PodLogsOptions) error
|
||||||
PodPause(ctx context.Context, namesOrIds []string, options PodPauseOptions) ([]*PodPauseReport, error)
|
PodPause(ctx context.Context, namesOrIds []string, options PodPauseOptions) ([]*PodPauseReport, error)
|
||||||
PodPrune(ctx context.Context, options PodPruneOptions) ([]*PodPruneReport, error)
|
PodPrune(ctx context.Context, options PodPruneOptions) ([]*PodPruneReport, error)
|
||||||
PodPs(ctx context.Context, options PodPSOptions) ([]*ListPodsReport, error)
|
PodPs(ctx context.Context, options PodPSOptions) ([]*ListPodsReport, error)
|
||||||
|
|
|
@ -133,6 +133,14 @@ type PodCreateOptions struct {
|
||||||
Userns specgen.Namespace
|
Userns specgen.Namespace
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PodLogsOptions describes the options to extract pod logs.
|
||||||
|
type PodLogsOptions struct {
|
||||||
|
// Other fields are exactly same as ContainerLogOpts
|
||||||
|
ContainerLogsOptions
|
||||||
|
// If specified will only fetch the logs of specified container
|
||||||
|
ContainerName string
|
||||||
|
}
|
||||||
|
|
||||||
type ContainerCreateOptions struct {
|
type ContainerCreateOptions struct {
|
||||||
Annotation []string
|
Annotation []string
|
||||||
Attach []string
|
Attach []string
|
||||||
|
@ -426,3 +434,22 @@ func ValidatePodStatsOptions(args []string, options *PodStatsOptions) error {
|
||||||
return errors.New("--all, --latest and arguments cannot be used together")
|
return errors.New("--all, --latest and arguments cannot be used together")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Converts PodLogOptions to ContainerLogOptions
|
||||||
|
func PodLogsOptionsToContainerLogsOptions(options PodLogsOptions) ContainerLogsOptions {
|
||||||
|
// PodLogsOptions are similar but contains few extra fields like ctrName
|
||||||
|
// So cast other values as is so we can re-use the code
|
||||||
|
containerLogsOpts := ContainerLogsOptions{
|
||||||
|
Details: options.Details,
|
||||||
|
Latest: options.Latest,
|
||||||
|
Follow: options.Follow,
|
||||||
|
Names: options.Names,
|
||||||
|
Since: options.Since,
|
||||||
|
Until: options.Until,
|
||||||
|
Tail: options.Tail,
|
||||||
|
Timestamps: options.Timestamps,
|
||||||
|
StdoutWriter: options.StdoutWriter,
|
||||||
|
StderrWriter: options.StderrWriter,
|
||||||
|
}
|
||||||
|
return containerLogsOpts
|
||||||
|
}
|
||||||
|
|
|
@ -83,6 +83,46 @@ func (ic *ContainerEngine) PodKill(ctx context.Context, namesOrIds []string, opt
|
||||||
return reports, nil
|
return reports, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ic *ContainerEngine) PodLogs(ctx context.Context, nameOrID string, options entities.PodLogsOptions) error {
|
||||||
|
// Implementation accepts slice
|
||||||
|
podName := []string{nameOrID}
|
||||||
|
pod, err := getPodsByContext(false, options.Latest, podName, ic.Libpod)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// Get pod containers
|
||||||
|
podCtrs, err := pod[0].AllContainers()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
ctrNames := []string{}
|
||||||
|
// Check if `kubectl pod logs -c ctrname <podname>` alike command is used
|
||||||
|
if options.ContainerName != "" {
|
||||||
|
ctrFound := false
|
||||||
|
for _, ctr := range podCtrs {
|
||||||
|
if ctr.ID() == options.ContainerName || ctr.Name() == options.ContainerName {
|
||||||
|
ctrNames = append(ctrNames, options.ContainerName)
|
||||||
|
ctrFound = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !ctrFound {
|
||||||
|
return errors.Wrapf(define.ErrNoSuchCtr, "container %s is not in pod %s", options.ContainerName, nameOrID)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// No container name specified select all containers
|
||||||
|
for _, ctr := range podCtrs {
|
||||||
|
ctrNames = append(ctrNames, ctr.Name())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PodLogsOptions are similar but contains few extra fields like ctrName
|
||||||
|
// So cast other values as is so we can re-use the code
|
||||||
|
containerLogsOpts := entities.PodLogsOptionsToContainerLogsOptions(options)
|
||||||
|
|
||||||
|
return ic.ContainerLogs(ctx, ctrNames, containerLogsOpts)
|
||||||
|
}
|
||||||
|
|
||||||
func (ic *ContainerEngine) PodPause(ctx context.Context, namesOrIds []string, options entities.PodPauseOptions) ([]*entities.PodPauseReport, error) {
|
func (ic *ContainerEngine) PodPause(ctx context.Context, namesOrIds []string, options entities.PodPauseOptions) ([]*entities.PodPauseReport, error) {
|
||||||
reports := []*entities.PodPauseReport{}
|
reports := []*entities.PodPauseReport{}
|
||||||
pods, err := getPodsByContext(options.All, options.Latest, namesOrIds, ic.Libpod)
|
pods, err := getPodsByContext(options.All, options.Latest, namesOrIds, ic.Libpod)
|
||||||
|
|
|
@ -42,6 +42,16 @@ func (ic *ContainerEngine) PodKill(ctx context.Context, namesOrIds []string, opt
|
||||||
return reports, nil
|
return reports, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ic *ContainerEngine) PodLogs(_ context.Context, nameOrIDs string, options entities.PodLogsOptions) error {
|
||||||
|
// PodLogsOptions are similar but contains few extra fields like ctrName
|
||||||
|
// So cast other values as is so we can re-use the code
|
||||||
|
containerLogsOpts := entities.PodLogsOptionsToContainerLogsOptions(options)
|
||||||
|
|
||||||
|
// interface only accepts slice, keep everything consistent
|
||||||
|
name := []string{options.ContainerName}
|
||||||
|
return ic.ContainerLogs(nil, name, containerLogsOpts)
|
||||||
|
}
|
||||||
|
|
||||||
func (ic *ContainerEngine) PodPause(ctx context.Context, namesOrIds []string, options entities.PodPauseOptions) ([]*entities.PodPauseReport, error) {
|
func (ic *ContainerEngine) PodPause(ctx context.Context, namesOrIds []string, options entities.PodPauseOptions) ([]*entities.PodPauseReport, error) {
|
||||||
foundPods, err := getPodsByContext(ic.ClientCtx, options.All, namesOrIds)
|
foundPods, err := getPodsByContext(ic.ClientCtx, options.All, namesOrIds)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -1289,6 +1289,40 @@ var _ = Describe("Podman play kube", func() {
|
||||||
Expect(logs.OutputToString()).To(ContainSubstring("hello world"))
|
Expect(logs.OutputToString()).To(ContainSubstring("hello world"))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
It("podman pod logs test", func() {
|
||||||
|
SkipIfRemote("podman-remote pod logs -c is mandatory for remote machine")
|
||||||
|
p := getPod(withCtr(getCtr(withCmd([]string{"echo", "hello"}), withArg([]string{"world"}))))
|
||||||
|
|
||||||
|
err := generateKubeYaml("pod", p, kubeYaml)
|
||||||
|
Expect(err).To(BeNil())
|
||||||
|
|
||||||
|
kube := podmanTest.Podman([]string{"play", "kube", kubeYaml})
|
||||||
|
kube.WaitWithDefaultTimeout()
|
||||||
|
Expect(kube).Should(Exit(0))
|
||||||
|
|
||||||
|
logs := podmanTest.Podman([]string{"pod", "logs", p.Name})
|
||||||
|
logs.WaitWithDefaultTimeout()
|
||||||
|
Expect(logs).Should(Exit(0))
|
||||||
|
Expect(logs.OutputToString()).To(ContainSubstring("hello world"))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("podman-remote pod logs test", func() {
|
||||||
|
// -c or --container is required in podman-remote due to api limitation.
|
||||||
|
p := getPod(withCtr(getCtr(withCmd([]string{"echo", "hello"}), withArg([]string{"world"}))))
|
||||||
|
|
||||||
|
err := generateKubeYaml("pod", p, kubeYaml)
|
||||||
|
Expect(err).To(BeNil())
|
||||||
|
|
||||||
|
kube := podmanTest.Podman([]string{"play", "kube", kubeYaml})
|
||||||
|
kube.WaitWithDefaultTimeout()
|
||||||
|
Expect(kube).Should(Exit(0))
|
||||||
|
|
||||||
|
logs := podmanTest.Podman([]string{"pod", "logs", "-c", getCtrNameInPod(p), p.Name})
|
||||||
|
logs.WaitWithDefaultTimeout()
|
||||||
|
Expect(logs).Should(Exit(0))
|
||||||
|
Expect(logs.OutputToString()).To(ContainSubstring("hello world"))
|
||||||
|
})
|
||||||
|
|
||||||
It("podman play kube test restartPolicy", func() {
|
It("podman play kube test restartPolicy", func() {
|
||||||
// podName, set, expect
|
// podName, set, expect
|
||||||
testSli := [][]string{
|
testSli := [][]string{
|
||||||
|
|
Loading…
Reference in a new issue