Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 23 additions & 8 deletions internal/registry/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"net"
"net/http"
"strings"
"time"

"github.com/bootc-dev/bink/internal/config"
"github.com/bootc-dev/bink/internal/podman"
Expand Down Expand Up @@ -120,6 +121,10 @@ func (m *Manager) ensureExistingContainer(ctx context.Context, name, label strin

logrus.Infof("%s container is %s, starting it", label, status)
if err := m.podman.ContainerStart(ctx, name); err != nil {
if s, e := m.podman.ContainerStatus(ctx, name); e == nil && s == define.ContainerStateRunning.String() {
logrus.Infof("%s already running", label)
return nil
}
return fmt.Errorf("starting %s: %w", strings.ToLower(label), err)
}
logrus.Infof("%s started", label)
Expand Down Expand Up @@ -349,18 +354,28 @@ func isPodmanNotFound(err error) bool {
// recoverFromConcurrentCreate handles parallel EnsureRegistry/EnsureAuthRegistry calls
// where two processes both attempt to create the same named container.
func (m *Manager) recoverFromConcurrentCreate(ctx context.Context, name string, createErr error, ensure func(context.Context) error) error {
var isConcurrent bool
if isContainerAlreadyExists(createErr) {
logrus.Infof("%s was created concurrently", name)
return ensure(ctx)
isConcurrent = true
} else {
exists, checkErr := m.podman.ContainerExists(ctx, name)
if checkErr != nil {
return errors.Join(createErr, fmt.Errorf("checking %s after create failure: %w", name, checkErr))
}
isConcurrent = exists
}

exists, checkErr := m.podman.ContainerExists(ctx, name)
if checkErr != nil {
return errors.Join(createErr, fmt.Errorf("checking %s after create failure: %w", name, checkErr))
}
if exists {
if isConcurrent {
logrus.Infof("%s was created concurrently", name)
return ensure(ctx)
var err error
for attempts := 0; attempts < 3; attempts++ {
err = ensure(ctx)
if err == nil {
return nil
}
time.Sleep(200 * time.Millisecond)
}
return err
}
return createErr
}
Expand Down
5 changes: 5 additions & 0 deletions test/integration/integration_suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package integration_test

import (
"testing"
"time"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
Expand All @@ -23,6 +24,10 @@ var _ = SynchronizedBeforeSuite(func() {
helpers.RequireCommand("podman")
helpers.RequireBink()

cmd := helpers.BinkCmd("registry", "start")
session := helpers.RunCommand(cmd, 2*time.Minute)
Expect(session.ExitCode()).To(Equal(0), "Failed to start registry: %s", string(session.Err.Contents()))

GinkgoWriter.Println("✓ All prerequisites verified")
}, func() {})

Expand Down
Loading