diff options
author | Toshiki Sonoda <sonoda.toshiki@fujitsu.com> | 2022-07-20 19:30:11 +0900 |
---|---|---|
committer | Toshiki Sonoda <sonoda.toshiki@fujitsu.com> | 2022-07-20 19:30:11 +0900 |
commit | 9b152ef20e9cadf61547897ae21071098256bf79 (patch) | |
tree | c44dcb3afbf32da6a7400716595d171bb9467410 | |
parent | 8c9eff5b12eebe318be1f905562be6a236285caa (diff) | |
download | podman-9b152ef20e9cadf61547897ae21071098256bf79.tar.gz podman-9b152ef20e9cadf61547897ae21071098256bf79.tar.bz2 podman-9b152ef20e9cadf61547897ae21071098256bf79.zip |
Add pause/unpause --latest, --cidfile, --filter
--latest : pause/unpause the latest container.
--filter : pause/unpause the filtered container.
--cidfile : Read container ID from the specified file and pause/unpause the container.
Signed-off-by: Toshiki Sonoda <sonoda.toshiki@fujitsu.com>
-rw-r--r-- | cmd/podman/containers/pause.go | 83 | ||||
-rw-r--r-- | cmd/podman/containers/unpause.go | 86 | ||||
-rw-r--r-- | docs/source/markdown/podman-pause.1.md | 50 | ||||
-rw-r--r-- | docs/source/markdown/podman-unpause.1.md | 50 | ||||
-rw-r--r-- | pkg/domain/entities/containers.go | 9 | ||||
-rw-r--r-- | pkg/domain/infra/abi/containers.go | 41 | ||||
-rw-r--r-- | pkg/domain/infra/tunnel/containers.go | 26 | ||||
-rw-r--r-- | test/e2e/pause_test.go | 177 |
8 files changed, 458 insertions, 64 deletions
diff --git a/cmd/podman/containers/pause.go b/cmd/podman/containers/pause.go index af6f740f2..53aa423ac 100644 --- a/cmd/podman/containers/pause.go +++ b/cmd/podman/containers/pause.go @@ -2,61 +2,88 @@ package containers import ( "context" - "errors" "fmt" + "io/ioutil" + "strings" + "github.com/containers/common/pkg/completion" "github.com/containers/podman/v4/cmd/podman/common" "github.com/containers/podman/v4/cmd/podman/registry" "github.com/containers/podman/v4/cmd/podman/utils" + "github.com/containers/podman/v4/cmd/podman/validate" "github.com/containers/podman/v4/pkg/domain/entities" "github.com/spf13/cobra" - "github.com/spf13/pflag" ) var ( pauseDescription = `Pauses one or more running containers. The container name or ID can be used.` pauseCommand = &cobra.Command{ - Use: "pause [options] CONTAINER [CONTAINER...]", - Short: "Pause all the processes in one or more containers", - Long: pauseDescription, - RunE: pause, + Use: "pause [options] CONTAINER [CONTAINER...]", + Short: "Pause all the processes in one or more containers", + Long: pauseDescription, + RunE: pause, + Args: func(cmd *cobra.Command, args []string) error { + return validate.CheckAllLatestAndIDFile(cmd, args, false, "cidfile") + }, ValidArgsFunction: common.AutocompleteContainersRunning, Example: `podman pause mywebserver podman pause 860a4b23 - podman pause -a`, + podman pause --all`, } containerPauseCommand = &cobra.Command{ - Use: pauseCommand.Use, - Short: pauseCommand.Short, - Long: pauseCommand.Long, - RunE: pauseCommand.RunE, + Use: pauseCommand.Use, + Short: pauseCommand.Short, + Long: pauseCommand.Long, + RunE: pauseCommand.RunE, + Args: func(cmd *cobra.Command, args []string) error { + return validate.CheckAllLatestAndIDFile(cmd, args, false, "cidfile") + }, ValidArgsFunction: pauseCommand.ValidArgsFunction, Example: `podman container pause mywebserver podman container pause 860a4b23 - podman container pause -a`, + podman container pause --all`, } +) - pauseOpts = entities.PauseUnPauseOptions{} +var ( + pauseOpts = entities.PauseUnPauseOptions{ + Filters: make(map[string][]string), + } + pauseCidFiles = []string{} ) -func pauseFlags(flags *pflag.FlagSet) { +func pauseFlags(cmd *cobra.Command) { + flags := cmd.Flags() + flags.BoolVarP(&pauseOpts.All, "all", "a", false, "Pause all running containers") + + cidfileFlagName := "cidfile" + flags.StringArrayVar(&pauseCidFiles, cidfileFlagName, nil, "Read the container ID from the file") + _ = cmd.RegisterFlagCompletionFunc(cidfileFlagName, completion.AutocompleteDefault) + + filterFlagName := "filter" + flags.StringSliceVarP(&filters, filterFlagName, "f", []string{}, "Filter output based on conditions given") + _ = cmd.RegisterFlagCompletionFunc(filterFlagName, common.AutocompletePsFilters) + + if registry.IsRemote() { + _ = flags.MarkHidden("cidfile") + } } func init() { registry.Commands = append(registry.Commands, registry.CliCommand{ Command: pauseCommand, }) - flags := pauseCommand.Flags() - pauseFlags(flags) + pauseFlags(pauseCommand) + validate.AddLatestFlag(pauseCommand, &pauseOpts.Latest) registry.Commands = append(registry.Commands, registry.CliCommand{ Command: containerPauseCommand, Parent: containerCmd, }) - containerPauseFlags := containerPauseCommand.Flags() - pauseFlags(containerPauseFlags) + pauseFlags(containerPauseCommand) + validate.AddLatestFlag(containerPauseCommand, &pauseOpts.Latest) } func pause(cmd *cobra.Command, args []string) error { @@ -64,16 +91,30 @@ func pause(cmd *cobra.Command, args []string) error { errs utils.OutputErrors ) - if len(args) < 1 && !pauseOpts.All { - return errors.New("you must provide at least one container name or id") + for _, cidFile := range pauseCidFiles { + content, err := ioutil.ReadFile(cidFile) + if err != nil { + return fmt.Errorf("error reading CIDFile: %w", err) + } + id := strings.Split(string(content), "\n")[0] + args = append(args, id) + } + + for _, f := range filters { + split := strings.SplitN(f, "=", 2) + if len(split) < 2 { + return fmt.Errorf("invalid filter %q", f) + } + pauseOpts.Filters[split[0]] = append(pauseOpts.Filters[split[0]], split[1]) } + responses, err := registry.ContainerEngine().ContainerPause(context.Background(), args, pauseOpts) if err != nil { return err } for _, r := range responses { if r.Err == nil { - fmt.Println(r.Id) + fmt.Println(r.RawInput) } else { errs = append(errs, r.Err) } diff --git a/cmd/podman/containers/unpause.go b/cmd/podman/containers/unpause.go index a5375e737..4282e490e 100644 --- a/cmd/podman/containers/unpause.go +++ b/cmd/podman/containers/unpause.go @@ -4,59 +4,87 @@ import ( "context" "errors" "fmt" + "io/ioutil" + "strings" "github.com/containers/common/pkg/cgroups" + "github.com/containers/common/pkg/completion" "github.com/containers/podman/v4/cmd/podman/common" "github.com/containers/podman/v4/cmd/podman/registry" "github.com/containers/podman/v4/cmd/podman/utils" + "github.com/containers/podman/v4/cmd/podman/validate" "github.com/containers/podman/v4/pkg/domain/entities" "github.com/containers/podman/v4/pkg/rootless" "github.com/spf13/cobra" - "github.com/spf13/pflag" ) var ( unpauseDescription = `Unpauses one or more previously paused containers. The container name or ID can be used.` unpauseCommand = &cobra.Command{ - Use: "unpause [options] CONTAINER [CONTAINER...]", - Short: "Unpause the processes in one or more containers", - Long: unpauseDescription, - RunE: unpause, + Use: "unpause [options] CONTAINER [CONTAINER...]", + Short: "Unpause the processes in one or more containers", + Long: unpauseDescription, + RunE: unpause, + Args: func(cmd *cobra.Command, args []string) error { + return validate.CheckAllLatestAndIDFile(cmd, args, false, "cidfile") + }, ValidArgsFunction: common.AutocompleteContainersPaused, Example: `podman unpause ctrID podman unpause --all`, } - unPauseOptions = entities.PauseUnPauseOptions{} containerUnpauseCommand = &cobra.Command{ - Use: unpauseCommand.Use, - Short: unpauseCommand.Short, - Long: unpauseCommand.Long, - RunE: unpauseCommand.RunE, + Use: unpauseCommand.Use, + Short: unpauseCommand.Short, + Long: unpauseCommand.Long, + RunE: unpauseCommand.RunE, + Args: func(cmd *cobra.Command, args []string) error { + return validate.CheckAllLatestAndIDFile(cmd, args, false, "cidfile") + }, ValidArgsFunction: unpauseCommand.ValidArgsFunction, Example: `podman container unpause ctrID podman container unpause --all`, } ) -func unpauseFlags(flags *pflag.FlagSet) { - flags.BoolVarP(&unPauseOptions.All, "all", "a", false, "Pause all running containers") +var ( + unpauseOpts = entities.PauseUnPauseOptions{ + Filters: make(map[string][]string), + } + unpauseCidFiles = []string{} +) + +func unpauseFlags(cmd *cobra.Command) { + flags := cmd.Flags() + + flags.BoolVarP(&unpauseOpts.All, "all", "a", false, "Unpause all paused containers") + + cidfileFlagName := "cidfile" + flags.StringArrayVar(&unpauseCidFiles, cidfileFlagName, nil, "Read the container ID from the file") + _ = cmd.RegisterFlagCompletionFunc(cidfileFlagName, completion.AutocompleteDefault) + + filterFlagName := "filter" + flags.StringSliceVarP(&filters, filterFlagName, "f", []string{}, "Filter output based on conditions given") + _ = cmd.RegisterFlagCompletionFunc(filterFlagName, common.AutocompletePsFilters) + + if registry.IsRemote() { + _ = flags.MarkHidden("cidfile") + } } func init() { registry.Commands = append(registry.Commands, registry.CliCommand{ Command: unpauseCommand, }) - flags := unpauseCommand.Flags() - unpauseFlags(flags) + unpauseFlags(unpauseCommand) + validate.AddLatestFlag(unpauseCommand, &unpauseOpts.Latest) registry.Commands = append(registry.Commands, registry.CliCommand{ Command: containerUnpauseCommand, Parent: containerCmd, }) - - unpauseCommandFlags := containerUnpauseCommand.Flags() - unpauseFlags(unpauseCommandFlags) + unpauseFlags(containerUnpauseCommand) + validate.AddLatestFlag(containerUnpauseCommand, &unpauseOpts.Latest) } func unpause(cmd *cobra.Command, args []string) error { @@ -69,16 +97,32 @@ func unpause(cmd *cobra.Command, args []string) error { return errors.New("unpause is not supported for cgroupv1 rootless containers") } } - if len(args) < 1 && !unPauseOptions.All { - return errors.New("you must provide at least one container name or id") + + for _, cidFile := range unpauseCidFiles { + content, err := ioutil.ReadFile(cidFile) + if err != nil { + return fmt.Errorf("error reading CIDFile: %w", err) + } + id := strings.Split(string(content), "\n")[0] + args = append(args, id) + } + + for _, f := range filters { + split := strings.SplitN(f, "=", 2) + if len(split) < 2 { + return fmt.Errorf("invalid filter %q", f) + } + unpauseOpts.Filters[split[0]] = append(unpauseOpts.Filters[split[0]], split[1]) } - responses, err := registry.ContainerEngine().ContainerUnpause(context.Background(), args, unPauseOptions) + + responses, err := registry.ContainerEngine().ContainerUnpause(context.Background(), args, unpauseOpts) if err != nil { return err } + for _, r := range responses { if r.Err == nil { - fmt.Println(r.Id) + fmt.Println(r.RawInput) } else { errs = append(errs, r.Err) } diff --git a/docs/source/markdown/podman-pause.1.md b/docs/source/markdown/podman-pause.1.md index 863be9ed4..f374d96f3 100644 --- a/docs/source/markdown/podman-pause.1.md +++ b/docs/source/markdown/podman-pause.1.md @@ -17,21 +17,65 @@ Pauses all the processes in one or more containers. You may use container IDs o Pause all running containers. +#### **--cidfile** + +Read container ID from the specified file and pause the container. Can be specified multiple times. + +#### **--filter**, **-f**=*filter* + +Filter what containers pause. +Multiple filters can be given with multiple uses of the --filter flag. +Filters with the same key work inclusive with the only exception being +`label` which is exclusive. Filters with different keys always work exclusive. + +Valid filters are listed below: + +| **Filter** | **Description** | +| --------------- | -------------------------------------------------------------------------------- | +| id | [ID] Container's ID (accepts regex) | +| name | [Name] Container's name (accepts regex) | +| label | [Key] or [Key=Value] Label assigned to a container | +| exited | [Int] Container's exit code | +| status | [Status] Container's status: 'created', 'exited', 'paused', 'running', 'unknown' | +| ancestor | [ImageName] Image or descendant used to create container | +| before | [ID] or [Name] Containers created before this container | +| since | [ID] or [Name] Containers created since this container | +| volume | [VolumeName] or [MountpointDestination] Volume mounted in container | +| health | [Status] healthy or unhealthy | +| pod | [Pod] name or full or partial ID of pod | +| network | [Network] name or full ID of network | + +#### **--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. (This option is not available with the remote Podman client, including Mac and Windows (excluding WSL2) machines) + ## EXAMPLE -Pause a container named 'mywebserver' +Pause container named 'mywebserver' ``` podman pause mywebserver ``` -Pause a container by partial container ID. +Pause container by partial container ID. ``` podman pause 860a4b23 ``` Pause all **running** containers. ``` -podman pause -a +podman pause --all +``` + +Pause container using ID specified in a given files. +``` +podman pause --cidfile /home/user/cidfile-1 +podman pause --cidfile /home/user/cidfile-1 --cidfile ./cidfile-2 +``` + +Pause the latest container created by Podman. +``` +podman pause --latest ``` ## SEE ALSO diff --git a/docs/source/markdown/podman-unpause.1.md b/docs/source/markdown/podman-unpause.1.md index 4f66bf393..b94ace89e 100644 --- a/docs/source/markdown/podman-unpause.1.md +++ b/docs/source/markdown/podman-unpause.1.md @@ -17,21 +17,65 @@ Unpauses the processes in one or more containers. You may use container IDs or Unpause all paused containers. +#### **--cidfile** + +Read container ID from the specified file and unpause the container. Can be specified multiple times. + +#### **--filter**, **-f**=*filter* + +Filter what containers unpause. +Multiple filters can be given with multiple uses of the --filter flag. +Filters with the same key work inclusive with the only exception being +`label` which is exclusive. Filters with different keys always work exclusive. + +Valid filters are listed below: + +| **Filter** | **Description** | +| --------------- | -------------------------------------------------------------------------------- | +| id | [ID] Container's ID (accepts regex) | +| name | [Name] Container's name (accepts regex) | +| label | [Key] or [Key=Value] Label assigned to a container | +| exited | [Int] Container's exit code | +| status | [Status] Container's status: 'created', 'exited', 'paused', 'running', 'unknown' | +| ancestor | [ImageName] Image or descendant used to create container | +| before | [ID] or [Name] Containers created before this container | +| since | [ID] or [Name] Containers created since this container | +| volume | [VolumeName] or [MountpointDestination] Volume mounted in container | +| health | [Status] healthy or unhealthy | +| pod | [Pod] name or full or partial ID of pod | +| network | [Network] name or full ID of network | + +#### **--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. (This option is not available with the remote Podman client, including Mac and Windows (excluding WSL2) machines) + ## EXAMPLE -Unpause a container called 'mywebserver' +Unpause container called 'mywebserver' ``` podman unpause mywebserver ``` -Unpause a container by a partial container ID. +Unpause container by a partial container ID. ``` podman unpause 860a4b23 ``` Unpause all **paused** containers. ``` -podman unpause -a +podman unpause --all +``` + +Unpause container using ID specified in a given files. +``` +podman unpause --cidfile /home/user/cidfile-1 +podman unpause --cidfile /home/user/cidfile-1 --cidfile ./cidfile-2 +``` + +Unpause the latest container created by Podman. +``` +podman unpause --latest ``` ## SEE ALSO diff --git a/pkg/domain/entities/containers.go b/pkg/domain/entities/containers.go index 934a7cbdc..df793034b 100644 --- a/pkg/domain/entities/containers.go +++ b/pkg/domain/entities/containers.go @@ -71,12 +71,15 @@ type StringSliceReport struct { } type PauseUnPauseOptions struct { - All bool + Filters map[string][]string + All bool + Latest bool } type PauseUnpauseReport struct { - Err error - Id string //nolint:revive,stylecheck + Err error + Id string //nolint:revive,stylecheck + RawInput string } type StopOptions struct { diff --git a/pkg/domain/infra/abi/containers.go b/pkg/domain/infra/abi/containers.go index 04eb85504..dd7053a23 100644 --- a/pkg/domain/infra/abi/containers.go +++ b/pkg/domain/infra/abi/containers.go @@ -62,6 +62,11 @@ func getContainersAndInputByContext(all, latest bool, names []string, filters ma } case all: ctrs, err = runtime.GetAllContainers() + if err == nil { + for _, ctr := range ctrs { + rawInput = append(rawInput, ctr.ID()) + } + } case latest: ctr, err = runtime.GetLatestContainer() if err == nil { @@ -133,37 +138,57 @@ func (ic *ContainerEngine) ContainerWait(ctx context.Context, namesOrIds []strin } func (ic *ContainerEngine) ContainerPause(ctx context.Context, namesOrIds []string, options entities.PauseUnPauseOptions) ([]*entities.PauseUnpauseReport, error) { - ctrs, err := getContainersByContext(options.All, false, namesOrIds, ic.Libpod) + ctrs, rawInputs, err := getContainersAndInputByContext(options.All, options.Latest, namesOrIds, options.Filters, ic.Libpod) if err != nil { return nil, err } - report := make([]*entities.PauseUnpauseReport, 0, len(ctrs)) + ctrMap := map[string]string{} + if len(rawInputs) == len(ctrs) { + for i := range ctrs { + ctrMap[ctrs[i].ID()] = rawInputs[i] + } + } + reports := make([]*entities.PauseUnpauseReport, 0, len(ctrs)) for _, c := range ctrs { err := c.Pause() if err != nil && options.All && errors.Is(err, define.ErrCtrStateInvalid) { logrus.Debugf("Container %s is not running", c.ID()) continue } - report = append(report, &entities.PauseUnpauseReport{Id: c.ID(), Err: err}) + reports = append(reports, &entities.PauseUnpauseReport{ + Id: c.ID(), + Err: err, + RawInput: ctrMap[c.ID()], + }) } - return report, nil + return reports, nil } func (ic *ContainerEngine) ContainerUnpause(ctx context.Context, namesOrIds []string, options entities.PauseUnPauseOptions) ([]*entities.PauseUnpauseReport, error) { - ctrs, err := getContainersByContext(options.All, false, namesOrIds, ic.Libpod) + ctrs, rawInputs, err := getContainersAndInputByContext(options.All, options.Latest, namesOrIds, options.Filters, ic.Libpod) if err != nil { return nil, err } - report := make([]*entities.PauseUnpauseReport, 0, len(ctrs)) + ctrMap := map[string]string{} + if len(rawInputs) == len(ctrs) { + for i := range ctrs { + ctrMap[ctrs[i].ID()] = rawInputs[i] + } + } + reports := make([]*entities.PauseUnpauseReport, 0, len(ctrs)) for _, c := range ctrs { err := c.Unpause() if err != nil && options.All && errors.Is(err, define.ErrCtrStateInvalid) { logrus.Debugf("Container %s is not paused", c.ID()) continue } - report = append(report, &entities.PauseUnpauseReport{Id: c.ID(), Err: err}) + reports = append(reports, &entities.PauseUnpauseReport{ + Id: c.ID(), + Err: err, + RawInput: ctrMap[c.ID()], + }) } - return report, nil + return reports, nil } func (ic *ContainerEngine) ContainerStop(ctx context.Context, namesOrIds []string, options entities.StopOptions) ([]*entities.StopReport, error) { names := namesOrIds diff --git a/pkg/domain/infra/tunnel/containers.go b/pkg/domain/infra/tunnel/containers.go index fcabff7c4..272c23268 100644 --- a/pkg/domain/infra/tunnel/containers.go +++ b/pkg/domain/infra/tunnel/containers.go @@ -57,10 +57,14 @@ func (ic *ContainerEngine) ContainerWait(ctx context.Context, namesOrIds []strin } func (ic *ContainerEngine) ContainerPause(ctx context.Context, namesOrIds []string, options entities.PauseUnPauseOptions) ([]*entities.PauseUnpauseReport, error) { - ctrs, err := getContainersByContext(ic.ClientCtx, options.All, false, namesOrIds) + ctrs, rawInputs, err := getContainersAndInputByContext(ic.ClientCtx, options.All, false, namesOrIds, options.Filters) if err != nil { return nil, err } + ctrMap := map[string]string{} + for i := range ctrs { + ctrMap[ctrs[i].ID] = rawInputs[i] + } reports := make([]*entities.PauseUnpauseReport, 0, len(ctrs)) for _, c := range ctrs { err := containers.Pause(ic.ClientCtx, c.ID, nil) @@ -68,24 +72,36 @@ func (ic *ContainerEngine) ContainerPause(ctx context.Context, namesOrIds []stri logrus.Debugf("Container %s is not running", c.ID) continue } - reports = append(reports, &entities.PauseUnpauseReport{Id: c.ID, Err: err}) + reports = append(reports, &entities.PauseUnpauseReport{ + Id: c.ID, + Err: err, + RawInput: ctrMap[c.ID], + }) } return reports, nil } func (ic *ContainerEngine) ContainerUnpause(ctx context.Context, namesOrIds []string, options entities.PauseUnPauseOptions) ([]*entities.PauseUnpauseReport, error) { - reports := []*entities.PauseUnpauseReport{} - ctrs, err := getContainersByContext(ic.ClientCtx, options.All, false, namesOrIds) + ctrs, rawInputs, err := getContainersAndInputByContext(ic.ClientCtx, options.All, false, namesOrIds, options.Filters) if err != nil { return nil, err } + ctrMap := map[string]string{} + for i := range ctrs { + ctrMap[ctrs[i].ID] = rawInputs[i] + } + reports := make([]*entities.PauseUnpauseReport, 0, len(ctrs)) for _, c := range ctrs { err := containers.Unpause(ic.ClientCtx, c.ID, nil) if err != nil && options.All && strings.Contains(err.Error(), define.ErrCtrStateInvalid.Error()) { logrus.Debugf("Container %s is not paused", c.ID) continue } - reports = append(reports, &entities.PauseUnpauseReport{Id: c.ID, Err: err}) + reports = append(reports, &entities.PauseUnpauseReport{ + Id: c.ID, + Err: err, + RawInput: ctrMap[c.ID], + }) } return reports, nil } diff --git a/test/e2e/pause_test.go b/test/e2e/pause_test.go index d677eddb0..363df2624 100644 --- a/test/e2e/pause_test.go +++ b/test/e2e/pause_test.go @@ -319,4 +319,181 @@ var _ = Describe("Podman pause", func() { Expect(running.OutputToStringArray()).To(HaveLen(3)) }) + It("podman pause --latest", func() { + SkipIfRemote("--latest flag n/a") + session := podmanTest.RunTopContainer("") + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + result := podmanTest.Podman([]string{"pause", "-l"}) + result.WaitWithDefaultTimeout() + + Expect(session).Should(Exit(0)) + Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) + Expect(strings.ToLower(podmanTest.GetContainerStatus())).To(ContainSubstring(pausedState)) + + result = podmanTest.Podman([]string{"unpause", "-l"}) + result.WaitWithDefaultTimeout() + }) + + It("podman pause --cidfile", func() { + tmpDir, err := ioutil.TempDir("", "") + Expect(err).To(BeNil()) + tmpFile := tmpDir + "cid" + + defer os.RemoveAll(tmpDir) + + session := podmanTest.Podman([]string{"create", "--cidfile", tmpFile, ALPINE, "top"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + cid := session.OutputToStringArray()[0] + + session = podmanTest.Podman([]string{"start", cid}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + + result := podmanTest.Podman([]string{"pause", "--cidfile", tmpFile}) + result.WaitWithDefaultTimeout() + Expect(result).Should(Exit(0)) + output := result.OutputToString() + Expect(output).To(ContainSubstring(cid)) + + result = podmanTest.Podman([]string{"unpause", "--cidfile", tmpFile}) + result.WaitWithDefaultTimeout() + Expect(result).Should(Exit(0)) + output = result.OutputToString() + Expect(output).To(ContainSubstring(cid)) + }) + + It("podman pause multiple --cidfile", func() { + tmpDir, err := ioutil.TempDir("", "") + Expect(err).To(BeNil()) + tmpFile1 := tmpDir + "cid-1" + tmpFile2 := tmpDir + "cid-2" + + defer os.RemoveAll(tmpDir) + + session := podmanTest.Podman([]string{"run", "--cidfile", tmpFile1, "-d", ALPINE, "top"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + cid1 := session.OutputToStringArray()[0] + Expect(podmanTest.NumberOfContainers()).To(Equal(1)) + + session = podmanTest.Podman([]string{"run", "--cidfile", tmpFile2, "-d", ALPINE, "top"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + cid2 := session.OutputToStringArray()[0] + Expect(podmanTest.NumberOfContainers()).To(Equal(2)) + + result := podmanTest.Podman([]string{"pause", "--cidfile", tmpFile1, "--cidfile", tmpFile2}) + result.WaitWithDefaultTimeout() + Expect(result).Should(Exit(0)) + output := result.OutputToString() + Expect(output).To(ContainSubstring(cid1)) + Expect(output).To(ContainSubstring(cid2)) + Expect(podmanTest.NumberOfContainers()).To(Equal(2)) + + result = podmanTest.Podman([]string{"unpause", "--cidfile", tmpFile1, "--cidfile", tmpFile2}) + result.WaitWithDefaultTimeout() + Expect(result).Should(Exit(0)) + output = result.OutputToString() + Expect(output).To(ContainSubstring(cid1)) + Expect(output).To(ContainSubstring(cid2)) + Expect(podmanTest.NumberOfContainers()).To(Equal(2)) + }) + + It("podman pause invalid --latest and --cidfile and --all", func() { + SkipIfRemote("--latest flag n/a") + result := podmanTest.Podman([]string{"pause", "--cidfile", "foobar", "--latest"}) + result.WaitWithDefaultTimeout() + Expect(result).Should(Exit(125)) + Expect(result.ErrorToString()).To(ContainSubstring("cannot be used together")) + result = podmanTest.Podman([]string{"pause", "--cidfile", "foobar", "--all"}) + result.WaitWithDefaultTimeout() + Expect(result).Should(Exit(125)) + Expect(result.ErrorToString()).To(ContainSubstring("cannot be used together")) + result = podmanTest.Podman([]string{"pause", "--cidfile", "foobar", "--all", "--latest"}) + result.WaitWithDefaultTimeout() + Expect(result).Should(Exit(125)) + Expect(result.ErrorToString()).To(ContainSubstring("cannot be used together")) + result = podmanTest.Podman([]string{"pause", "--latest", "--all"}) + result.WaitWithDefaultTimeout() + Expect(result).Should(Exit(125)) + Expect(result.ErrorToString()).To(ContainSubstring("cannot be used together")) + }) + + It("podman unpause invalid --latest and --cidfile and --all", func() { + SkipIfRemote("--latest flag n/a") + result := podmanTest.Podman([]string{"unpause", "--cidfile", "foobar", "--latest"}) + result.WaitWithDefaultTimeout() + Expect(result).Should(Exit(125)) + Expect(result.ErrorToString()).To(ContainSubstring("cannot be used together")) + result = podmanTest.Podman([]string{"unpause", "--cidfile", "foobar", "--all"}) + result.WaitWithDefaultTimeout() + Expect(result).Should(Exit(125)) + Expect(result.ErrorToString()).To(ContainSubstring("cannot be used together")) + result = podmanTest.Podman([]string{"unpause", "--cidfile", "foobar", "--all", "--latest"}) + result.WaitWithDefaultTimeout() + Expect(result).Should(Exit(125)) + Expect(result.ErrorToString()).To(ContainSubstring("cannot be used together")) + result = podmanTest.Podman([]string{"unpause", "--latest", "--all"}) + result.WaitWithDefaultTimeout() + Expect(result).Should(Exit(125)) + Expect(result.ErrorToString()).To(ContainSubstring("cannot be used together")) + }) + + It("podman pause --filter", func() { + session1 := podmanTest.RunTopContainer("") + session1.WaitWithDefaultTimeout() + Expect(session1).Should(Exit(0)) + cid1 := session1.OutputToString() + + session1 = podmanTest.RunTopContainer("") + session1.WaitWithDefaultTimeout() + Expect(session1).Should(Exit(0)) + cid2 := session1.OutputToString() + + session1 = podmanTest.RunTopContainer("") + session1.WaitWithDefaultTimeout() + Expect(session1).Should(Exit(0)) + cid3 := session1.OutputToString() + shortCid3 := cid3[0:5] + + session1 = podmanTest.Podman([]string{"pause", cid1, "-f", "status=test"}) + session1.WaitWithDefaultTimeout() + Expect(session1).Should(Exit(125)) + + session1 = podmanTest.Podman([]string{"unpause", cid1, "-f", "status=paused"}) + session1.WaitWithDefaultTimeout() + Expect(session1).Should(Exit(125)) + + session1 = podmanTest.Podman([]string{"pause", "-a", "--filter", fmt.Sprintf("id=%swrongid", shortCid3)}) + session1.WaitWithDefaultTimeout() + Expect(session1).Should(Exit(0)) + Expect(session1.OutputToString()).To(HaveLen(0)) + + session1 = podmanTest.Podman([]string{"pause", "-a", "--filter", fmt.Sprintf("id=%s", shortCid3)}) + session1.WaitWithDefaultTimeout() + Expect(session1).Should(Exit(0)) + Expect(session1.OutputToString()).To(BeEquivalentTo(cid3)) + + session1 = podmanTest.Podman([]string{"unpause", "-a", "--filter", fmt.Sprintf("id=%swrongid", shortCid3)}) + session1.WaitWithDefaultTimeout() + Expect(session1).Should(Exit(0)) + Expect(session1.OutputToString()).To(HaveLen(0)) + + session1 = podmanTest.Podman([]string{"unpause", "-a", "--filter", fmt.Sprintf("id=%s", shortCid3)}) + session1.WaitWithDefaultTimeout() + Expect(session1).Should(Exit(0)) + Expect(session1.OutputToString()).To(BeEquivalentTo(cid3)) + + session1 = podmanTest.Podman([]string{"pause", "-f", fmt.Sprintf("id=%s", cid2)}) + session1.WaitWithDefaultTimeout() + Expect(session1).Should(Exit(0)) + Expect(session1.OutputToString()).To(BeEquivalentTo(cid2)) + + session1 = podmanTest.Podman([]string{"unpause", "-f", fmt.Sprintf("id=%s", cid2)}) + session1.WaitWithDefaultTimeout() + Expect(session1).Should(Exit(0)) + Expect(session1.OutputToString()).To(BeEquivalentTo(cid2)) + }) }) |