compose icon indicating copy to clipboard operation
compose copied to clipboard

[BUG] (*composeService).DryRunMode does not inherit output streams

Open ngicks opened this issue 2 years ago • 1 comments

Description

When compose is used from go code, DryRunMode ignores options which have been applied to *command.DockerCli,. since it uses new instance.

https://github.com/docker/compose/blob/main/pkg/compose/compose.go#L85-L104

It ignores output destination once overridden by (*command.DockerCli).Apply(command.WithOutputStream(bufOut), command.WithErrorStream(bufErr)).

I'm not sure if it is a feature or a bug. At least it is not noted in doc comments.

Steps To Reproduce

Save code below as main.go, then run go mod init with whatever name. Then run go mod tidy, then go run main.go.

The system running this code must have docker socket file at default location, or otherwise needs tweeks.

package main

import (
	"bytes"
	"context"
	"fmt"
	"os"

	"github.com/compose-spec/compose-go/loader"
	"github.com/compose-spec/compose-go/types"
	"github.com/docker/cli/cli/command"
	"github.com/docker/cli/cli/flags"
	"github.com/docker/compose/v2/pkg/api"
	"github.com/docker/compose/v2/pkg/compose"
)

const composeYml = `services:
  sample_service:
    image: ubuntu:jammy-20230624
`

func main() {
	dockerCli, _ := command.NewDockerCli()

	bufOut, bufErr := new(bytes.Buffer), new(bytes.Buffer)
	_ = dockerCli.Apply(command.WithOutputStream(bufOut), command.WithErrorStream(bufErr))
	_ = dockerCli.Initialize(&flags.ClientOptions{
		Context: "default",
	})
	_ = dockerCli.Client()

	project, err := loader.LoadWithContext(
		context.Background(),
		types.ConfigDetails{
			WorkingDir: ".",
			ConfigFiles: []types.ConfigFile{
				{
					Filename: "whatever.yml",
					Content:  []byte(composeYml),
				},
			},
			Environment: types.NewMapping(os.Environ()),
		},
		func(o *loader.Options) {
			o.SetProjectName("whatever", true)
		},
	)
	if err != nil {
		panic(err)
	}

	composeService := compose.NewComposeService(dockerCli)
	ctx, err := composeService.DryRunMode(context.Background(), true)
	if err != nil {
		panic(err)
	}

	err = composeService.Up(ctx, project, api.UpOptions{Start: api.StartOptions{Project: project}})
	if err != nil {
		panic(err)
	}

	fmt.Printf("out buf = %s, err buf = %s\n", bufOut.String(), bufErr.String())

}

executing this prints:

# go run main.go 
[+] Running 2/0
 ✔ DRY-RUN MODE -  Network whatever_default             Created                                                                                                                                      0.0s 
 ✔ DRY-RUN MODE -  Container whatever-sample_service-1  Created                                                                                                                                      0.0s 
out buf = , err buf = 

Compose Version

github.com/docker/cli v24.0.6+incompatible
github.com/docker/compose/v2 v2.21.0
github.com/docker/docker v24.0.5+incompatible

Docker Environment

Client:
 Version:    24.0.5
 Context:    default
 Debug Mode: false
 Plugins:
  buildx: Docker Buildx (Docker Inc.)
    Version:  v0.11.2
    Path:     /usr/libexec/docker/cli-plugins/docker-buildx
  compose: Docker Compose (Docker Inc.)
    Version:  v2.20.2
    Path:     /usr/libexec/docker/cli-plugins/docker-compose

Server:
 Containers: 15
  Running: 3
  Paused: 0
  Stopped: 12
 Images: 20
 Server Version: 24.0.5
 Storage Driver: overlay2
  Backing Filesystem: extfs
  Supports d_type: true
  Using metacopy: false
  Native Overlay Diff: true
  userxattr: false
 Logging Driver: json-file
 Cgroup Driver: cgroupfs
 Cgroup Version: 1
 Plugins:
  Volume: local
  Network: bridge host ipvlan macvlan null overlay
  Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
 Swarm: inactive
 Runtimes: runc io.containerd.runc.v2
 Default Runtime: runc
 Init Binary: docker-init
 containerd version: 3dce8eb055cbb6872793272b4f20ed16117344f8
 runc version: v1.1.7-0-g860f061
 init version: de40ad0
 Security Options:
  seccomp
   Profile: unconfined
 Kernel Version: 5.15.90.1-microsoft-standard-WSL2
 Operating System: Docker Desktop
 OSType: linux
 Architecture: x86_64
 CPUs: 24
 Total Memory: 30.92GiB
 Name: docker-desktop
 ID: afb0dc76-536b-415a-bda0-4df62190dad8
 Docker Root Dir: /var/lib/docker
 Debug Mode: false
 HTTP Proxy: http.docker.internal:3128
 HTTPS Proxy: http.docker.internal:3128
 No Proxy: hubproxy.docker.internal
 Experimental: false
 Insecure Registries:
  hubproxy.docker.internal:5555
  127.0.0.0/8
 Live Restore Enabled: false

WARNING: No blkio throttle.read_bps_device support
WARNING: No blkio throttle.write_bps_device support
WARNING: No blkio throttle.read_iops_device support
WARNING: No blkio throttle.write_iops_device support
WARNING: daemon is not using the default seccomp profile

Anything else?

No response

ngicks avatar Sep 20 '23 16:09 ngicks

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

github-actions[bot] avatar Jul 31 '24 00:07 github-actions[bot]