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
15 changes: 1 addition & 14 deletions pkg/compose/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ import (

"github.com/compose-spec/compose-go/v2/types"
"github.com/docker/docker/api/types/filters"
"golang.org/x/sync/errgroup"
)

func (s *composeService) Start(ctx context.Context, projectName string, options api.StartOptions) error {
Expand All @@ -52,18 +51,6 @@ func (s *composeService) start(ctx context.Context, projectName string, options
}
}

// use an independent context tied to the errgroup for background attach operations
// the primary context is still used for other operations
// this means that once any attach operation fails, all other attaches are cancelled,
// but an attach failing won't interfere with the rest of the start
eg, attachCtx := errgroup.WithContext(ctx)
if listener != nil {
_, err := s.attach(attachCtx, project, listener, options.AttachTo)
if err != nil {
return err
}
}

var containers Containers
containers, err := s.apiClient().ContainerList(ctx, containerType.ListOptions{
Filters: filters.NewArgs(
Expand Down Expand Up @@ -111,7 +98,7 @@ func (s *composeService) start(ctx context.Context, projectName string, options
}
}

return eg.Wait()
return nil
}

// getDependencyCondition checks if service is depended on by other services
Expand Down
51 changes: 34 additions & 17 deletions pkg/compose/up.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"fmt"
"os"
"os/signal"
"slices"
"sync/atomic"
"syscall"

Expand All @@ -34,6 +35,7 @@ import (
"github.com/eiannone/keyboard"
"github.com/hashicorp/go-multierror"
"github.com/sirupsen/logrus"
"golang.org/x/sync/errgroup"
)

func (s *composeService) Up(ctx context.Context, project *types.Project, options api.UpOptions) error { //nolint:gocyclo
Expand Down Expand Up @@ -205,29 +207,44 @@ func (s *composeService) Up(ctx context.Context, project *types.Project, options
})
}

// use an independent context tied to the errgroup for background attach operations
// the primary context is still used for other operations
// this means that once any attach operation fails, all other attaches are cancelled,
// but an attach failing won't interfere with the rest of the start
_, attachCtx := errgroup.WithContext(ctx)
containers, err := s.attach(attachCtx, project, printer.HandleEvent, options.Start.AttachTo)
if err != nil {
return err
}
attached := make([]string, len(containers))
for i, ctr := range containers {
attached[i] = ctr.ID
}

monitor.withListener(func(event api.ContainerEvent) {
if event.Type != api.ContainerEventStarted {
return
}
if event.Restarting || event.Container.Labels[api.ContainerReplaceLabel] != "" {
eg.Go(func() error {
ctr, err := s.apiClient().ContainerInspect(ctx, event.ID)
if err != nil {
return err
}

err = s.doLogContainer(ctx, options.Start.Attach, event.Source, ctr, api.LogOptions{
Follow: true,
Since: ctr.State.StartedAt,
})
if errdefs.IsNotImplemented(err) {
// container may be configured with logging_driver: none
// as container already started, we might miss the very first logs. But still better than none
return s.doAttachContainer(ctx, event.Service, event.ID, event.Source, printer.HandleEvent)
}
if slices.Contains(attached, event.ID) {
return
}
eg.Go(func() error {
ctr, err := s.apiClient().ContainerInspect(ctx, event.ID)
if err != nil {
return err
}

err = s.doLogContainer(ctx, options.Start.Attach, event.Source, ctr, api.LogOptions{
Follow: true,
Since: ctr.State.StartedAt,
})
}
if errdefs.IsNotImplemented(err) {
// container may be configured with logging_driver: none
// as container already started, we might miss the very first logs. But still better than none
return s.doAttachContainer(ctx, event.Service, event.ID, event.Source, printer.HandleEvent)
}
return err
})
})

eg.Go(func() error {
Expand Down