cmd, commit: register shutdown handler to unpause container

When --pause defaults to true, a Ctrl-C during commit would leave the
container paused.  Register a shutdown handler that unpauses the
container on SIGINT/SIGTERM so it is always restored to its running
state.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
This commit is contained in:
Giuseppe Scrivano 2026-05-27 09:30:33 +00:00
parent db804fb1b9
commit 1c2a2ffe87
No known key found for this signature in database
GPG key ID: 67E38F7A8BA21772

View file

@ -6,6 +6,7 @@ import (
"context"
"errors"
"fmt"
"os"
"slices"
"strings"
@ -16,6 +17,7 @@ import (
"go.podman.io/image/v5/types"
"go.podman.io/podman/v6/libpod/define"
"go.podman.io/podman/v6/libpod/events"
"go.podman.io/podman/v6/libpod/shutdown"
)
// ContainerCommitOptions is a struct used to commit a container to an image
@ -49,10 +51,21 @@ func (c *Container) Commit(ctx context.Context, destImage string, options Contai
}
if (c.state.State == define.ContainerStateRunning || c.state.State == define.ContainerStateStopping) && options.Pause {
// The container lock is held, so no concurrent Commit can
// register a handler with the same name.
handlerName := fmt.Sprintf("commit-unpause-%s", c.ID())
if err := shutdown.Register(handlerName, func(sig os.Signal) error {
logrus.Debugf("Received %v, unpausing container %q", sig, c.ID())
return c.unpause()
}); err != nil && !errors.Is(err, shutdown.ErrHandlerExists) {
logrus.Errorf("Registering shutdown handler for container %q: %v", c.ID(), err)
}
if err := c.pause(); err != nil {
_ = shutdown.Unregister(handlerName)
return nil, fmt.Errorf("pausing container %q to commit: %w", c.ID(), err)
}
defer func() {
_ = shutdown.Unregister(handlerName)
if err := c.unpause(); err != nil {
logrus.Errorf("Unpausing container %q: %v", c.ID(), err)
}