libpod: cleanup after failed container init

Fixes: #26143

Signed-off-by: Jiwoo Ahn <ikwydls1314@gmail.com>
This commit is contained in:
Jiwoo Ahn 2026-07-23 16:30:37 +09:00
parent 94a98b18cb
commit f85047302c
2 changed files with 38 additions and 4 deletions

View file

@ -42,7 +42,7 @@ func (c *Container) Init(ctx context.Context, recursive bool) error {
return c.initUnlocked(ctx, recursive)
}
func (c *Container) initUnlocked(ctx context.Context, recursive bool) error {
func (c *Container) initUnlocked(ctx context.Context, recursive bool) (retErr error) {
if !c.ensureState(define.ContainerStateConfigured, define.ContainerStateStopped, define.ContainerStateExited) {
return fmt.Errorf("container %s has already been created in runtime: %w", c.ID(), define.ErrCtrStateInvalid)
}
@ -57,10 +57,15 @@ func (c *Container) initUnlocked(ctx context.Context, recursive bool) error {
}
}
if err := c.prepare(); err != nil {
if err2 := c.cleanup(ctx); err2 != nil {
logrus.Errorf("Cleaning up container %s: %v", c.ID(), err2)
defer func() {
if retErr != nil {
if err := c.cleanup(ctx); err != nil {
logrus.Errorf("Cleaning up container %s: %v", c.ID(), err)
}
}
}()
if err := c.prepare(); err != nil {
return err
}

View file

@ -4,6 +4,8 @@ package integration
import (
"fmt"
"os"
"path/filepath"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
@ -118,4 +120,31 @@ var _ = Describe("Podman init", func() {
init.WaitWithDefaultTimeout()
Expect(init).Should(ExitWithError(125, fmt.Sprintf("Error: container %s has already been created in runtime: container state improper", cid)))
})
It("podman init cleans up after initialization failure", func() {
SkipIfRemote("requires local containers.conf configuration")
confPath := filepath.Join(podmanTest.TempDir, "containers.conf")
err := os.WriteFile(confPath, []byte("[containers]\nhost_containers_internal_ip = \"none\"\n"), 0o644)
Expect(err).ToNot(HaveOccurred())
err = os.Setenv("CONTAINERS_CONF_OVERRIDE", confPath)
Expect(err).ToNot(HaveOccurred())
name := "init-failure-cleanup"
podmanTest.PodmanExitCleanly("create", "--name", name, "--add-host", "host.docker.internal:host-gateway", ALPINE, "top")
init := podmanTest.Podman([]string{"init", name})
init.WaitWithDefaultTimeout()
Expect(init).Should(ExitWithError(125, "host containers internal IP address is empty"))
inspect := podmanTest.PodmanExitCleanly("inspect", "--format", "{{.State.Status}}", name)
Expect(inspect.OutputToString()).To(Equal("created"))
// Verify that start retries initialization instead of starting a partially initialized container.
start := podmanTest.Podman([]string{"start", name})
start.WaitWithDefaultTimeout()
Expect(start).Should(ExitWithError(125, "host containers internal IP address is empty"))
})
})