podman wait: allow waiting for removal of containers

By default wait only waits for the exit of a container, there is really
no way to make it wait for the removal too when the container was
created with --rm. I though I found a clever way in 8a943311db but this
is not working race free. While it works most of the time any other
parallel process might call syncContainer() before the cleanup process
holds the lock until it removes it. As such the wait hack to only update
the state and not sync the exit file did not work so we can drop that.

However the test wants to wait for the removal to happen by the cleanup
process and we can already say --condition=removing to do this but this
will throw an error if the ctr was removed instead of counting this as
success so fix that as well.

Fixes #23640

Signed-off-by: Paul Holzinger <pholzing@redhat.com>
This commit is contained in:
Paul Holzinger
2024-08-16 15:44:02 +02:00
parent e8410b8395
commit 80639df27a
3 changed files with 12 additions and 7 deletions

View File

@ -546,10 +546,7 @@ func (c *Container) WaitForExit(ctx context.Context, pollInterval time.Duration)
c.lock.Lock()
defer c.lock.Unlock()
// Note this is one of the rare cases where we do not like to use syncContainer() as it does read the exit file
// We like to avoid that here because that means we might read it before container cleanup run and possible
// removed the container
if err := c.runtime.state.UpdateContainer(c); err != nil {
if err := c.syncContainer(); err != nil {
if errors.Is(err, define.ErrNoSuchCtr) {
// if the container is not valid at this point as it was deleted,
// check if the exit code was recorded in the db.
@ -705,6 +702,13 @@ func (c *Container) WaitForConditionWithInterval(ctx context.Context, waitTimeou
if len(wantedStates) > 0 {
state, err := c.State()
if err != nil {
// If the we wait for removing and the container is removed do not return this as error.
// This allows callers to actually wait for the ctr to be removed.
if wantedStates[define.ContainerStateRemoving] &&
(errors.Is(err, define.ErrNoSuchCtr) || errors.Is(err, define.ErrCtrRemoved)) {
trySend(-1, nil)
return
}
trySend(-1, err)
return
}