mirror of
https://github.com/containers/podman.git
synced 2025-08-06 19:44:14 +08:00
wait: add --ignore option
In the recent past, I met the frequent need to wait for a container to exist that, at the same time, may get removed (e.g., system tests in [1]). Add an `--ignore` option to podman-wait which will ignore errors when a specified container is missing and mark its exit code as -1. Also remove ID fields from the WaitReport. It is actually not used by callers and removing it makes the code simpler and faster. Once merged, we can go over the tests and simplify them. [1] github.com/containers/podman/pull/16852 Signed-off-by: Valentin Rothberg <vrothberg@redhat.com>
This commit is contained in:
@ -53,6 +53,8 @@ func waitFlags(cmd *cobra.Command) {
|
||||
flags.StringVarP(&waitInterval, intervalFlagName, "i", "250ms", "Time Interval to wait before polling for completion")
|
||||
_ = cmd.RegisterFlagCompletionFunc(intervalFlagName, completion.AutocompleteNone)
|
||||
|
||||
flags.BoolVarP(&waitOptions.Ignore, "ignore", "", false, "Ignore if a container does not exist")
|
||||
|
||||
conditionFlagName := "condition"
|
||||
flags.StringSliceVar(&waitConditions, conditionFlagName, []string{}, "Condition to wait on")
|
||||
_ = cmd.RegisterFlagCompletionFunc(conditionFlagName, common.AutocompleteWaitCondition)
|
||||
|
@ -23,6 +23,10 @@ Condition to wait on (default "stopped")
|
||||
|
||||
Print usage statement
|
||||
|
||||
|
||||
#### **--ignore**
|
||||
Ignore errors when a specified container is missing and mark its return code as -1.
|
||||
|
||||
#### **--interval**, **-i**=*duration*
|
||||
Time interval to wait before polling for completion. A duration string is a sequence of decimal numbers, each with optional fraction and a unit suffix, such as "300ms", "-1.5h" or "2h45m". Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". Time unit defaults to "ms".
|
||||
|
||||
@ -46,6 +50,9 @@ $ podman wait 860a4b23
|
||||
$ podman wait mywebserver myftpserver
|
||||
0
|
||||
125
|
||||
|
||||
$ podman wait --ignore does-not-exist
|
||||
-1
|
||||
```
|
||||
|
||||
## SEE ALSO
|
||||
|
@ -52,11 +52,11 @@ type ContainerRunlabelReport struct{}
|
||||
type WaitOptions struct {
|
||||
Condition []define.ContainerStatus
|
||||
Interval time.Duration
|
||||
Ignore bool
|
||||
Latest bool
|
||||
}
|
||||
|
||||
type WaitReport struct {
|
||||
Id string //nolint:revive,stylecheck
|
||||
Error error
|
||||
ExitCode int32
|
||||
}
|
||||
|
@ -139,13 +139,29 @@ func (ic *ContainerEngine) ContainerExists(ctx context.Context, nameOrID string,
|
||||
}
|
||||
|
||||
func (ic *ContainerEngine) ContainerWait(ctx context.Context, namesOrIds []string, options entities.WaitOptions) ([]entities.WaitReport, error) {
|
||||
ctrs, err := getContainersByContext(false, options.Latest, false, namesOrIds, ic.Libpod)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
responses := make([]entities.WaitReport, 0, len(namesOrIds))
|
||||
if options.Latest {
|
||||
ctr, err := ic.Libpod.GetLatestContainer()
|
||||
if err != nil {
|
||||
if options.Ignore && errors.Is(err, define.ErrNoSuchCtr) {
|
||||
responses = append(responses, entities.WaitReport{ExitCode: -1})
|
||||
return responses, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
namesOrIds = append(namesOrIds, ctr.ID())
|
||||
}
|
||||
responses := make([]entities.WaitReport, 0, len(ctrs))
|
||||
for _, c := range ctrs {
|
||||
response := entities.WaitReport{Id: c.ID()}
|
||||
for _, n := range namesOrIds {
|
||||
c, err := ic.Libpod.LookupContainer(n)
|
||||
if err != nil {
|
||||
if options.Ignore && errors.Is(err, define.ErrNoSuchCtr) {
|
||||
responses = append(responses, entities.WaitReport{ExitCode: -1})
|
||||
continue
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
response := entities.WaitReport{}
|
||||
if options.Condition == nil {
|
||||
options.Condition = []define.ContainerStatus{define.ContainerStateStopped, define.ContainerStateExited}
|
||||
}
|
||||
|
@ -38,17 +38,17 @@ func (ic *ContainerEngine) ContainerExists(ctx context.Context, nameOrID string,
|
||||
}
|
||||
|
||||
func (ic *ContainerEngine) ContainerWait(ctx context.Context, namesOrIds []string, opts entities.WaitOptions) ([]entities.WaitReport, error) {
|
||||
cons, err := getContainersByContext(ic.ClientCtx, false, false, namesOrIds)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
responses := make([]entities.WaitReport, 0, len(cons))
|
||||
responses := make([]entities.WaitReport, 0, len(namesOrIds))
|
||||
options := new(containers.WaitOptions).WithCondition(opts.Condition).WithInterval(opts.Interval.String())
|
||||
for _, c := range cons {
|
||||
response := entities.WaitReport{Id: c.ID}
|
||||
exitCode, err := containers.Wait(ic.ClientCtx, c.ID, options)
|
||||
for _, n := range namesOrIds {
|
||||
response := entities.WaitReport{}
|
||||
exitCode, err := containers.Wait(ic.ClientCtx, n, options)
|
||||
if err != nil {
|
||||
response.Error = err
|
||||
if opts.Ignore && errorhandling.Contains(err, define.ErrNoSuchCtr) {
|
||||
response.ExitCode = -1
|
||||
} else {
|
||||
response.Error = err
|
||||
}
|
||||
} else {
|
||||
response.ExitCode = exitCode
|
||||
}
|
||||
|
@ -20,6 +20,15 @@ load helpers
|
||||
run_podman rm $rand
|
||||
is "$output" "$rand" "display raw input"
|
||||
run_podman 125 inspect $rand
|
||||
run_podman 125 wait $rand
|
||||
run_podman wait --ignore $rand
|
||||
is "$output" "-1" "wait --ignore will mark missing containers with -1"
|
||||
|
||||
if !is_remote; then
|
||||
# remote does not support the --latest flag
|
||||
run_podman wait --ignore --latest
|
||||
is "$output" "-1" "wait --ignore will mark missing containers with -1"
|
||||
fi
|
||||
}
|
||||
|
||||
@test "podman rm - running container, w/o and w/ force" {
|
||||
|
Reference in New Issue
Block a user