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
3 changes: 2 additions & 1 deletion cmd/compose/logs.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,12 @@ func runLogs(ctx context.Context, dockerCli command.Cli, backendOptions *Backend
}
}

consumer := formatter.NewLogConsumer(ctx, dockerCli.Out(), dockerCli.Err(), !opts.noColor, !opts.noPrefix, false)
backend, err := compose.NewComposeService(dockerCli, backendOptions.Options...)
if err != nil {
return err
}
outStream, errStream, _ := backend.GetConfiguredStreams()
consumer := formatter.NewLogConsumer(ctx, outStream, errStream, !opts.noColor, !opts.noPrefix, false)
return backend.Logs(ctx, name, consumer, api.LogOptions{
Project: project,
Services: services,
Expand Down
3 changes: 2 additions & 1 deletion cmd/compose/up.go
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,8 @@ func runUp(
var consumer api.LogConsumer
var attach []string
if !upOptions.Detach {
consumer = formatter.NewLogConsumer(ctx, dockerCli.Out(), dockerCli.Err(), !upOptions.noColor, !upOptions.noPrefix, upOptions.timestamp)
outStream, errStream, _ := backend.GetConfiguredStreams()
consumer = formatter.NewLogConsumer(ctx, outStream, errStream, !upOptions.noColor, !upOptions.noPrefix, upOptions.timestamp)

var attachSet utils.Set[string]
if len(upOptions.attach) != 0 {
Expand Down
3 changes: 2 additions & 1 deletion cmd/compose/watch.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,11 +121,12 @@ func runWatch(ctx context.Context, dockerCli command.Cli, backendOptions *Backen
}
}

consumer := formatter.NewLogConsumer(ctx, dockerCli.Out(), dockerCli.Err(), false, false, false)
backend, err := compose.NewComposeService(dockerCli, backendOptions.Options...)
if err != nil {
return err
}
outStream, errStream, _ := backend.GetConfiguredStreams()
consumer := formatter.NewLogConsumer(ctx, outStream, errStream, false, false, false)
return backend.Watch(ctx, project, api.WatchOptions{
Build: &build,
LogTo: consumer,
Expand Down
3 changes: 3 additions & 0 deletions pkg/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,9 @@ type Compose interface {
Generate(ctx context.Context, options GenerateOptions) (*types.Project, error)
// Volumes executes the equivalent to a `docker volume ls`
Volumes(ctx context.Context, project string, options VolumesOptions) ([]VolumesSummary, error)
// GetConfiguredStreams returns the configured I/O streams (stdout, stderr, stdin).
// If no custom streams were configured, it returns the dockerCli streams.
GetConfiguredStreams() (stdout io.Writer, stderr io.Writer, stdin io.Reader)
}

type VolumesOptions struct {
Expand Down
32 changes: 32 additions & 0 deletions pkg/api/context.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
Copyright 2020 Docker Compose CLI authors

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package api

// ContextInfo provides Docker context information for advanced scenarios
type ContextInfo interface {
// CurrentContext returns the name of the current Docker context
// Returns "default" for simple clients without context support
CurrentContext() string

// ServerOSType returns the Docker daemon's operating system (linux/windows/darwin)
// Used for OS-specific compatibility checks
ServerOSType() string

// BuildKitEnabled determines whether BuildKit should be used for builds
// Checks DOCKER_BUILDKIT env var, config, and daemon capabilities
BuildKitEnabled() (bool, error)
}
27 changes: 21 additions & 6 deletions pkg/api/io.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,27 @@
package api

import (
"github.com/docker/cli/cli/streams"
"io"
)

// Streams defines the standard streams (stdin, stdout, stderr) used by the CLI.
type Streams interface {
Out() *streams.Out
Err() *streams.Out
In() *streams.In
// OutputStream is a writable stream with terminal detection capabilities
type OutputStream interface {
io.Writer

// IsTerminal returns true if the stream is connected to a terminal
IsTerminal() bool

// FD returns the file descriptor for the stream
FD() uintptr
}

// InputStream is a readable stream with terminal detection capabilities
type InputStream interface {
io.Reader

// IsTerminal returns true if the stream is connected to a terminal
IsTerminal() bool

// FD returns the file descriptor for the stream
FD() uintptr
}
3 changes: 2 additions & 1 deletion pkg/compose/apiSocket.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,15 @@ func (s *composeService) useAPISocket(project *types.Project) (*types.Project, e
return project, nil
}

if s.dockerCli.ServerInfo().OSType == "windows" {
if s.getContextInfo().ServerOSType() == "windows" {
return nil, errors.New("use_api_socket can't be used with a Windows Docker Engine")
}

creds, err := s.configFile().GetAllCredentials()
if err != nil {
return nil, fmt.Errorf("resolving credentials failed: %w", err)
}

newConfig := &configfile.ConfigFile{
AuthConfigs: creds,
}
Expand Down
12 changes: 5 additions & 7 deletions pkg/compose/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,8 @@ import (
"github.com/containerd/platforms"
"github.com/docker/buildx/build"
"github.com/docker/buildx/builder"
"github.com/docker/buildx/store/storeutil"
"github.com/docker/buildx/util/buildflags"
xprogress "github.com/docker/buildx/util/progress"
"github.com/docker/cli/cli/command"
cliopts "github.com/docker/cli/opts"
"github.com/docker/compose/v2/internal/tracing"
"github.com/docker/compose/v2/pkg/api"
Expand Down Expand Up @@ -143,7 +141,7 @@ func (s *composeService) build(ctx context.Context, project *types.Project, opti
}

// Initialize buildkit nodes
buildkitEnabled, err := s.dockerCli.BuildKitEnabled()
buildkitEnabled, err := s.getContextInfo().BuildKitEnabled()
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -179,7 +177,7 @@ func (s *composeService) build(ctx context.Context, project *types.Project, opti
if options.Progress == progress.ModeAuto {
options.Progress = os.Getenv("BUILDKIT_PROGRESS")
}
w, err = xprogress.NewPrinter(progressCtx, os.Stdout, progressui.DisplayMode(options.Progress),
w, err = xprogress.NewPrinter(progressCtx, s.stdout(), progressui.DisplayMode(options.Progress),
xprogress.WithDesc(
fmt.Sprintf("building with %q instance using %s driver", b.Name, b.Driver),
fmt.Sprintf("%s:%s", b.Driver, b.Name),
Expand Down Expand Up @@ -384,15 +382,15 @@ func (s *composeService) getLocalImagesDigests(ctx context.Context, project *typ
//
// Finally, standard proxy variables based on the Docker client configuration are added, but will not overwrite
// any values if already present.
func resolveAndMergeBuildArgs(dockerCli command.Cli, project *types.Project, service types.ServiceConfig, opts api.BuildOptions) types.MappingWithEquals {
func resolveAndMergeBuildArgs(proxyConfig map[string]string, project *types.Project, service types.ServiceConfig, opts api.BuildOptions) types.MappingWithEquals {
result := make(types.MappingWithEquals).
OverrideBy(service.Build.Args).
OverrideBy(opts.Args).
Resolve(envResolver(project.Environment))

// proxy arguments do NOT override and should NOT have env resolution applied,
// so they're handled last
for k, v := range storeutil.GetProxyConfig(dockerCli) {
for k, v := range proxyConfig {
if _, ok := result[k]; !ok {
v := v
result[k] = &v
Expand Down Expand Up @@ -502,7 +500,7 @@ func (s *composeService) toBuildOptions(project *types.Project, service types.Se
CacheTo: build.CreateCaches(cacheTo),
NoCache: service.Build.NoCache,
Pull: service.Build.Pull,
BuildArgs: flatten(resolveAndMergeBuildArgs(s.dockerCli, project, service, options)),
BuildArgs: flatten(resolveAndMergeBuildArgs(s.getProxyConfig(), project, service, options)),
Tags: tags,
Target: service.Build.Target,
Exports: exports,
Expand Down
6 changes: 3 additions & 3 deletions pkg/compose/build_bake.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,10 +139,10 @@ func (s *composeService) doBuildBake(ctx context.Context, project *types.Project
displayMode := progressui.DisplayMode(options.Progress)
out := options.Out
if out == nil {
if displayMode == progress.ModeAuto && !s.dockerCli.Out().IsTerminal() {
if displayMode == progress.ModeAuto && !s.stdout().IsTerminal() {
displayMode = progressui.PlainMode
}
out = os.Stdout // should be s.dockerCli.Out(), but NewDisplay require access to the underlying *File
out = s.stdout()
}
display, err := progressui.NewDisplay(out, displayMode)
if err != nil {
Expand Down Expand Up @@ -185,7 +185,7 @@ func (s *composeService) doBuildBake(ctx context.Context, project *types.Project
build := *service.Build
labels := getImageBuildLabels(project, service)

args := resolveAndMergeBuildArgs(s.dockerCli, project, service, options).ToMapping()
args := resolveAndMergeBuildArgs(s.getProxyConfig(), project, service, options).ToMapping()
for k, v := range args {
args[k] = strings.ReplaceAll(v, "${", "$${")
}
Expand Down
7 changes: 3 additions & 4 deletions pkg/compose/build_classic.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/cli/cli"
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/command/image/build"
"github.com/docker/compose/v2/pkg/api"
buildtypes "github.com/docker/docker/api/types/build"
Expand Down Expand Up @@ -175,7 +174,7 @@ func (s *composeService) doBuildClassic(ctx context.Context, project *types.Proj
RegistryToken: authConfig.RegistryToken,
}
}
buildOpts := imageBuildOptions(s.dockerCli, project, service, options)
buildOpts := imageBuildOptions(s.getProxyConfig(), project, service, options)
imageName := api.GetImageNameOrDefault(service, project.Name)
buildOpts.Tags = append(buildOpts.Tags, imageName)
buildOpts.Dockerfile = relDockerfile
Expand Down Expand Up @@ -215,15 +214,15 @@ func (s *composeService) doBuildClassic(ctx context.Context, project *types.Proj
return imageID, nil
}

func imageBuildOptions(dockerCli command.Cli, project *types.Project, service types.ServiceConfig, options api.BuildOptions) buildtypes.ImageBuildOptions {
func imageBuildOptions(proxyConfigs map[string]string, project *types.Project, service types.ServiceConfig, options api.BuildOptions) buildtypes.ImageBuildOptions {
config := service.Build
return buildtypes.ImageBuildOptions{
Version: buildtypes.BuilderV1,
Tags: config.Tags,
NoCache: config.NoCache,
Remove: true,
PullParent: config.Pull,
BuildArgs: resolveAndMergeBuildArgs(dockerCli, project, service, options),
BuildArgs: resolveAndMergeBuildArgs(proxyConfigs, project, service, options),
Labels: config.Labels,
NetworkMode: config.Network,
ExtraHosts: config.ExtraHosts.AsList(":"),
Expand Down
4 changes: 1 addition & 3 deletions pkg/compose/commit.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,6 @@ func (s *composeService) commit(ctx context.Context, projectName string, options
return err
}

clnt := s.apiClient()

w := progress.ContextWriter(ctx)

name := getCanonicalContainerName(ctr)
Expand All @@ -65,7 +63,7 @@ func (s *composeService) commit(ctx context.Context, projectName string, options
return nil
}

response, err := clnt.ContainerCommit(ctx, ctr.ID, container.CommitOptions{
response, err := s.apiClient().ContainerCommit(ctx, ctr.ID, container.CommitOptions{
Reference: options.Reference,
Comment: options.Comment,
Author: options.Author,
Expand Down
Loading