Skip to content

Commit

Permalink
composeService to use dockerCli's In/Out/Err streams
Browse files Browse the repository at this point in the history
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
  • Loading branch information
ndeloof committed Feb 23, 2022
1 parent 981aea6 commit 44a4c2c
Show file tree
Hide file tree
Showing 31 changed files with 125 additions and 138 deletions.
23 changes: 0 additions & 23 deletions cmd/compose/exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,7 @@ package compose

import (
"context"
"fmt"
"os"

"github.com/compose-spec/compose-go/types"
"github.com/containerd/console"
"github.com/docker/cli/cli"
"github.com/docker/compose/v2/pkg/api"
"github.com/docker/compose/v2/pkg/compose"
Expand Down Expand Up @@ -100,27 +96,8 @@ func runExec(ctx context.Context, backend api.Service, opts execOpts) error {
Index: opts.index,
Detach: opts.detach,
WorkingDir: opts.workingDir,

Stdin: os.Stdin,
Stdout: os.Stdout,
Stderr: os.Stderr,
}

if execOpts.Tty {
con := console.Current()
if err := con.SetRaw(); err != nil {
return err
}
defer func() {
if err := con.Reset(); err != nil {
fmt.Println("Unable to close the console")
}
}()

execOpts.Stdin = con
execOpts.Stdout = con
execOpts.Stderr = con
}
exitCode, err := backend.Exec(ctx, projectName, execOpts)
if exitCode != 0 {
errMsg := ""
Expand Down
4 changes: 0 additions & 4 deletions cmd/compose/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ package compose
import (
"context"
"fmt"
"os"
"strings"

cgo "github.com/compose-spec/compose-go/cli"
Expand Down Expand Up @@ -199,9 +198,6 @@ func runRun(ctx context.Context, backend api.Service, project *types.Project, op
Command: opts.Command,
Detach: opts.Detach,
AutoRemove: opts.Remove,
Stdin: os.Stdin,
Stdout: os.Stdout,
Stderr: os.Stderr,
Tty: !opts.noTty,
WorkingDir: opts.workdir,
User: opts.user,
Expand Down
2 changes: 1 addition & 1 deletion cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ func pluginMain() {
if err := plugin.PersistentPreRunE(cmd, args); err != nil {
return err
}
lazyInit.WithService(compose.NewComposeService(dockerCli.Client(), dockerCli.ConfigFile()))
lazyInit.WithService(compose.NewComposeService(dockerCli))
if originalPreRun != nil {
return originalPreRun(cmd, args)
}
Expand Down
4 changes: 0 additions & 4 deletions pkg/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ package api
import (
"context"
"fmt"
"io"
"strings"
"time"

Expand Down Expand Up @@ -216,9 +215,6 @@ type RunOptions struct {
Entrypoint []string
Detach bool
AutoRemove bool
Stdin io.ReadCloser
Stdout io.WriteCloser
Stderr io.WriteCloser
Tty bool
WorkingDir string
User string
Expand Down
4 changes: 2 additions & 2 deletions pkg/compose/attach.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ func (s *composeService) attachContainerStreams(ctx context.Context, container s
func (s *composeService) getContainerStreams(ctx context.Context, container string) (io.WriteCloser, io.ReadCloser, error) {
var stdout io.ReadCloser
var stdin io.WriteCloser
cnx, err := s.apiClient.ContainerAttach(ctx, container, moby.ContainerAttachOptions{
cnx, err := s.apiClient().ContainerAttach(ctx, container, moby.ContainerAttachOptions{
Stream: true,
Stdin: true,
Stdout: true,
Expand All @@ -151,7 +151,7 @@ func (s *composeService) getContainerStreams(ctx context.Context, container stri
}

// Fallback to logs API
logs, err := s.apiClient.ContainerLogs(ctx, container, moby.ContainerLogsOptions{
logs, err := s.apiClient().ContainerLogs(ctx, container, moby.ContainerLogsOptions{
ShowStdout: true,
ShowStderr: true,
Follow: true,
Expand Down
5 changes: 2 additions & 3 deletions pkg/compose/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ package compose
import (
"context"
"fmt"
"os"
"path/filepath"

"github.com/compose-spec/compose-go/types"
Expand Down Expand Up @@ -193,7 +192,7 @@ func (s *composeService) getLocalImagesDigests(ctx context.Context, project *typ
}

func (s *composeService) serverInfo(ctx context.Context) (command.ServerInfo, error) {
ping, err := s.apiClient.Ping(ctx)
ping, err := s.apiClient().Ping(ctx)
if err != nil {
return command.ServerInfo{}, err
}
Expand Down Expand Up @@ -258,7 +257,7 @@ func (s *composeService) toBuildOptions(project *types.Project, service types.Se
NetworkMode: service.Build.Network,
ExtraHosts: service.Build.ExtraHosts,
Session: []session.Attachable{
authprovider.NewDockerAuthProvider(os.Stderr),
authprovider.NewDockerAuthProvider(s.stderr()),
},
}, nil
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/compose/build_buildkit.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import (

func (s *composeService) doBuildBuildkit(ctx context.Context, project *types.Project, opts map[string]build.Options, mode string) (map[string]string, error) {
const drivername = "default"
d, err := driver.GetDriver(ctx, drivername, nil, s.apiClient, s.configFile, nil, nil, nil, nil, nil, project.WorkingDir)
d, err := driver.GetDriver(ctx, drivername, nil, s.apiClient(), s.configFile(), nil, nil, nil, nil, nil, project.WorkingDir)
if err != nil {
return nil, err
}
Expand All @@ -48,7 +48,7 @@ func (s *composeService) doBuildBuildkit(ctx context.Context, project *types.Pro
w := xprogress.NewPrinter(progressCtx, os.Stdout, mode)

// We rely on buildx "docker" builder integrated in docker engine, so don't need a DockerAPI here
response, err := build.Build(ctx, driverInfo, opts, nil, filepath.Dir(s.configFile.Filename), w)
response, err := build.Build(ctx, driverInfo, opts, nil, filepath.Dir(s.configFile().Filename), w)
errW := w.Wait()
if err == nil {
err = errW
Expand Down
14 changes: 7 additions & 7 deletions pkg/compose/build_classic.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ func (s *composeService) doBuildClassicSimpleImage(ctx context.Context, options

dockerfileName := options.Inputs.DockerfilePath
specifiedContext := options.Inputs.ContextPath
progBuff := os.Stdout
buildBuff := os.Stdout
progBuff := s.stdout()
buildBuff := s.stdout()
if options.ImageIDFile != "" {
// Avoid leaving a stale file if we eventually fail
if err := os.Remove(options.ImageIDFile); err != nil && !os.IsNotExist(err) {
Expand Down Expand Up @@ -155,7 +155,7 @@ func (s *composeService) doBuildClassicSimpleImage(ctx context.Context, options
body = progress.NewProgressReader(buildCtx, progressOutput, 0, "", "Sending build context to Docker daemon")
}

configFile := s.configFile
configFile := s.configFile()
creds, err := configFile.GetAllCredentials()
if err != nil {
return "", err
Expand All @@ -171,7 +171,7 @@ func (s *composeService) doBuildClassicSimpleImage(ctx context.Context, options

ctx, cancel := context.WithCancel(ctx)
defer cancel()
response, err := s.apiClient.ImageBuild(ctx, body, buildOptions)
response, err := s.apiClient().ImageBuild(ctx, body, buildOptions)
if err != nil {
return "", err
}
Expand All @@ -181,13 +181,13 @@ func (s *composeService) doBuildClassicSimpleImage(ctx context.Context, options
aux := func(msg jsonmessage.JSONMessage) {
var result dockertypes.BuildResult
if err := json.Unmarshal(*msg.Aux, &result); err != nil {
fmt.Fprintf(os.Stderr, "Failed to parse aux message: %s", err)
fmt.Fprintf(s.stderr(), "Failed to parse aux message: %s", err)
} else {
imageID = result.ID
}
}

err = jsonmessage.DisplayJSONMessagesStream(response.Body, buildBuff, progBuff.Fd(), true, aux)
err = jsonmessage.DisplayJSONMessagesStream(response.Body, buildBuff, progBuff.FD(), true, aux)
if err != nil {
if jerr, ok := err.(*jsonmessage.JSONError); ok {
// If no error code is set, default to 1
Expand All @@ -203,7 +203,7 @@ func (s *composeService) doBuildClassicSimpleImage(ctx context.Context, options
// daemon isn't running Windows.
if response.OSType != "windows" && runtime.GOOS == "windows" {
// if response.OSType != "windows" && runtime.GOOS == "windows" && !options.quiet {
fmt.Fprintln(os.Stdout, "SECURITY WARNING: You are building a Docker "+
fmt.Fprintln(s.stdout(), "SECURITY WARNING: You are building a Docker "+
"image from Windows against a non-Windows Docker host. All files and "+
"directories added to build context will have '-rwxr-xr-x' permissions. "+
"It is recommended to double check and reset permissions for sensitive "+
Expand Down
31 changes: 26 additions & 5 deletions pkg/compose/compose.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,15 @@ import (
"context"
"encoding/json"
"fmt"
"io"
"strings"

"github.com/docker/compose/v2/pkg/api"

"github.com/compose-spec/compose-go/types"
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/config/configfile"
"github.com/docker/cli/cli/streams"
moby "github.com/docker/docker/api/types"
"github.com/docker/docker/client"
"github.com/sanathkr/go-yaml"
Expand All @@ -36,16 +39,34 @@ import (
var Separator = "-"

// NewComposeService create a local implementation of the compose.Service API
func NewComposeService(apiClient client.APIClient, configFile *configfile.ConfigFile) api.Service {
func NewComposeService(dockerCli command.Cli) api.Service {
return &composeService{
apiClient: apiClient,
configFile: configFile,
dockerCli: dockerCli,
}
}

type composeService struct {
apiClient client.APIClient
configFile *configfile.ConfigFile
dockerCli command.Cli
}

func (s *composeService) apiClient() client.APIClient {
return s.dockerCli.Client()
}

func (s *composeService) configFile() *configfile.ConfigFile {
return s.dockerCli.ConfigFile()
}

func (s *composeService) stdout() *streams.Out {
return s.dockerCli.Out()
}

func (s *composeService) stdin() *streams.In {
return s.dockerCli.In()
}

func (s *composeService) stderr() io.Writer {
return s.dockerCli.Err()
}

func getCanonicalContainerName(c moby.Container) string {
Expand Down
2 changes: 1 addition & 1 deletion pkg/compose/containers.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func (s *composeService) getContainers(ctx context.Context, project string, oneO
f = append(f, oneOffFilter(false))
case oneOffInclude:
}
containers, err := s.apiClient.ContainerList(ctx, moby.ContainerListOptions{
containers, err := s.apiClient().ContainerList(ctx, moby.ContainerListOptions{
Filters: filters.NewArgs(f...),
All: stopped,
})
Expand Down
28 changes: 14 additions & 14 deletions pkg/compose/convergence.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,11 +180,11 @@ func (c *convergence) ensureService(ctx context.Context, project *types.Project,
// Scale Down
container := container
eg.Go(func() error {
err := c.service.apiClient.ContainerStop(ctx, container.ID, timeout)
err := c.service.apiClient().ContainerStop(ctx, container.ID, timeout)
if err != nil {
return err
}
return c.service.apiClient.ContainerRemove(ctx, container.ID, moby.ContainerRemoveOptions{})
return c.service.apiClient().ContainerRemove(ctx, container.ID, moby.ContainerRemoveOptions{})
})
continue
}
Expand Down Expand Up @@ -380,13 +380,13 @@ func (s *composeService) recreateContainer(ctx context.Context, project *types.P
var created moby.Container
w := progress.ContextWriter(ctx)
w.Event(progress.NewEvent(getContainerProgressName(replaced), progress.Working, "Recreate"))
err := s.apiClient.ContainerStop(ctx, replaced.ID, timeout)
err := s.apiClient().ContainerStop(ctx, replaced.ID, timeout)
if err != nil {
return created, err
}
name := getCanonicalContainerName(replaced)
tmpName := fmt.Sprintf("%s_%s", replaced.ID[:12], name)
err = s.apiClient.ContainerRename(ctx, replaced.ID, tmpName)
err = s.apiClient().ContainerRename(ctx, replaced.ID, tmpName)
if err != nil {
return created, err
}
Expand All @@ -404,7 +404,7 @@ func (s *composeService) recreateContainer(ctx context.Context, project *types.P
if err != nil {
return created, err
}
err = s.apiClient.ContainerRemove(ctx, replaced.ID, moby.ContainerRemoveOptions{})
err = s.apiClient().ContainerRemove(ctx, replaced.ID, moby.ContainerRemoveOptions{})
if err != nil {
return created, err
}
Expand All @@ -429,7 +429,7 @@ func setDependentLifecycle(project *types.Project, service string, strategy stri
func (s *composeService) startContainer(ctx context.Context, container moby.Container) error {
w := progress.ContextWriter(ctx)
w.Event(progress.NewEvent(getContainerProgressName(container), progress.Working, "Restart"))
err := s.apiClient.ContainerStart(ctx, container.ID, moby.ContainerStartOptions{})
err := s.apiClient().ContainerStart(ctx, container.ID, moby.ContainerStartOptions{})
if err != nil {
return err
}
Expand All @@ -453,11 +453,11 @@ func (s *composeService) createMobyContainer(ctx context.Context, project *types
}
plat = &p
}
response, err := s.apiClient.ContainerCreate(ctx, containerConfig, hostConfig, networkingConfig, plat, name)
response, err := s.apiClient().ContainerCreate(ctx, containerConfig, hostConfig, networkingConfig, plat, name)
if err != nil {
return created, err
}
inspectedContainer, err := s.apiClient.ContainerInspect(ctx, response.ID)
inspectedContainer, err := s.apiClient().ContainerInspect(ctx, response.ID)
if err != nil {
return created, err
}
Expand Down Expand Up @@ -487,7 +487,7 @@ func (s *composeService) createMobyContainer(ctx context.Context, project *types
if shortIDAliasExists(created.ID, val.Aliases...) {
continue
}
err = s.apiClient.NetworkDisconnect(ctx, netwrk.Name, created.ID, false)
err = s.apiClient().NetworkDisconnect(ctx, netwrk.Name, created.ID, false)
if err != nil {
return created, err
}
Expand Down Expand Up @@ -581,7 +581,7 @@ func (s *composeService) connectContainerToNetwork(ctx context.Context, id strin
IPv6Address: ipv6Address,
}
}
err := s.apiClient.NetworkConnect(ctx, netwrk, id, &network.EndpointSettings{
err := s.apiClient().NetworkConnect(ctx, netwrk, id, &network.EndpointSettings{
Aliases: aliases,
IPAddress: ipv4Address,
GlobalIPv6Address: ipv6Address,
Expand All @@ -604,7 +604,7 @@ func (s *composeService) isServiceHealthy(ctx context.Context, project *types.Pr
return false, nil
}
for _, c := range containers {
container, err := s.apiClient.ContainerInspect(ctx, c.ID)
container, err := s.apiClient().ContainerInspect(ctx, c.ID)
if err != nil {
return false, err
}
Expand Down Expand Up @@ -636,7 +636,7 @@ func (s *composeService) isServiceCompleted(ctx context.Context, project *types.
return false, 0, err
}
for _, c := range containers {
container, err := s.apiClient.ContainerInspect(ctx, c.ID)
container, err := s.apiClient().ContainerInspect(ctx, c.ID)
if err != nil {
return false, 0, err
}
Expand All @@ -656,7 +656,7 @@ func (s *composeService) startService(ctx context.Context, project *types.Projec
if err != nil {
return err
}
containers, err := s.apiClient.ContainerList(ctx, moby.ContainerListOptions{
containers, err := s.apiClient().ContainerList(ctx, moby.ContainerListOptions{
Filters: filters.NewArgs(
projectFilter(project.Name),
serviceFilter(service.Name),
Expand Down Expand Up @@ -685,7 +685,7 @@ func (s *composeService) startService(ctx context.Context, project *types.Projec
eg.Go(func() error {
eventName := getContainerProgressName(container)
w.Event(progress.StartingEvent(eventName))
err := s.apiClient.ContainerStart(ctx, container.ID, moby.ContainerStartOptions{})
err := s.apiClient().ContainerStart(ctx, container.ID, moby.ContainerStartOptions{})
if err == nil {
w.Event(progress.StartedEvent(eventName))
}
Expand Down
Loading

0 comments on commit 44a4c2c

Please sign in to comment.