Skip to content
Closed
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
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ require (
github.com/spf13/cobra v1.3.0
github.com/spf13/pflag v1.0.5
github.com/stretchr/testify v1.7.0
github.com/theupdateframework/notary v0.6.1
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
gotest.tools v2.2.0+incompatible
gotest.tools/v3 v3.1.0
Expand Down Expand Up @@ -93,7 +94,6 @@ require (
github.com/qri-io/jsonpointer v0.1.0 // indirect
github.com/qri-io/jsonschema v0.1.1 // indirect
github.com/sergi/go-diff v1.1.0 // indirect
github.com/theupdateframework/notary v0.6.1 // indirect
github.com/tonistiigi/fsutil v0.0.0-20210818161904-4442383b5028 // indirect
github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea // indirect
github.com/tonistiigi/vt100 v0.0.0-20210615222946-8066bb97264f // indirect
Expand Down Expand Up @@ -135,7 +135,7 @@ require (

// (for buildx)
replace (
github.com/docker/cli => github.com/docker/cli v20.10.3-0.20210702143511-f782d1355eff+incompatible
github.com/docker/cli => github.com/ndeloof/cli v0.0.0-20220222095154-9145a1b2e6a6
github.com/docker/docker => github.com/docker/docker v20.10.3-0.20220121014307-40bb9831756f+incompatible
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc => github.com/tonistiigi/opentelemetry-go-contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.0.0-20210714055410-d010b05b4939
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace => github.com/tonistiigi/opentelemetry-go-contrib/instrumentation/net/http/httptrace/otelhttptrace v0.0.0-20210714055410-d010b05b4939
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -467,8 +467,6 @@ github.com/distribution/distribution/v3 v3.0.0-20210316161203-a01c71e2477e/go.mo
github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=
github.com/docker/buildx v0.7.1 h1:l2DlW8YDbB3pH2bUFY5Q9pPQdhd42wqlnO5hoyWrjYM=
github.com/docker/buildx v0.7.1/go.mod h1:PzxALHhYWPNhw/8JajPOJBkvx1w2tgOnppL4ESg0wOY=
github.com/docker/cli v20.10.3-0.20210702143511-f782d1355eff+incompatible h1:CaaxCD/l9Dxogu6lxf7AQautlv3sHULrasPadayp0fM=
github.com/docker/cli v20.10.3-0.20210702143511-f782d1355eff+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/cli-docs-tool v0.2.1 h1:ffZhhdws6kE+dCKHLMlYROZz8z01RtWbz+g4xz0eBIU=
github.com/docker/cli-docs-tool v0.2.1/go.mod h1:rgW5KKdNpLMBIuH4WQ/1RNh38nH+/Ay5jgL4P0ZMPpY=
github.com/docker/compose-on-kubernetes v0.4.19-0.20190128150448-356b2919c496/go.mod h1:iT2pYfi580XlpaV4KmK0T6+4/9+XoKmk/fhoDod1emE=
Expand Down Expand Up @@ -1086,6 +1084,8 @@ github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+
github.com/nakabonne/nestif v0.3.0/go.mod h1:dI314BppzXjJ4HsCnbo7XzrJHPszZsjnk5wEBSYHI2c=
github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU=
github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM=
github.com/ndeloof/cli v0.0.0-20220222095154-9145a1b2e6a6 h1:PSmURWsOn7VfWBafKAISoFgPQKDvQ2/YL+X9YXpD6ek=
github.com/ndeloof/cli v0.0.0-20220222095154-9145a1b2e6a6/go.mod h1:wxmb4t3v3ZwISBr3B/B631+3VJe+erAxkl3vXQwXj2c=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229/go.mod h1:0aYXnNPJ8l7uZxf45rWW1a/uME32OF0rhiYGNQ2oF2E=
Expand Down
21 changes: 0 additions & 21 deletions pkg/compose/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ import (
_ "github.com/docker/buildx/driver/docker" // required to get default driver registered
"github.com/docker/buildx/util/buildflags"
xprogress "github.com/docker/buildx/util/progress"
"github.com/docker/cli/cli/command"
"github.com/docker/docker/pkg/urlutil"
bclient "github.com/moby/buildkit/client"
"github.com/moby/buildkit/session"
Expand Down Expand Up @@ -192,30 +191,10 @@ func (s *composeService) getLocalImagesDigests(ctx context.Context, project *typ
return images, nil
}

func (s *composeService) serverInfo(ctx context.Context) (command.ServerInfo, error) {
ping, err := s.apiClient.Ping(ctx)
if err != nil {
return command.ServerInfo{}, err
}
serverInfo := command.ServerInfo{
HasExperimental: ping.Experimental,
OSType: ping.OSType,
BuildkitVersion: ping.BuilderVersion,
}
return serverInfo, err
}

func (s *composeService) doBuild(ctx context.Context, project *types.Project, opts map[string]build.Options, mode string) (map[string]string, error) {
if len(opts) == 0 {
return nil, nil
}
serverInfo, err := s.serverInfo(ctx)
if err != nil {
return nil, err
}
if buildkitEnabled, err := command.BuildKitEnabled(serverInfo); err != nil || !buildkitEnabled {
return s.doBuildClassic(ctx, opts)
}
return s.doBuildBuildkit(ctx, project, opts, mode)
}

Expand Down
130 changes: 130 additions & 0 deletions pkg/compose/cli.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
/*
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 compose

import (
"io"
"os"

"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/config/configfile"
"github.com/docker/cli/cli/context/docker"
"github.com/docker/cli/cli/context/store"
manifeststore "github.com/docker/cli/cli/manifest/store"
client2 "github.com/docker/cli/cli/registry/client"
"github.com/docker/cli/cli/streams"
"github.com/docker/cli/cli/trust"
"github.com/docker/docker/client"
notaryclient "github.com/theupdateframework/notary/client"
)

// dockerCli creates a (partial) command.Cli so we can use docker/cli commands
func (s *composeService) dockerCli() command.Cli {
return dockerCli{
apiClient: s.apiClient,
configFile: s.configFile,
}
}

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

func (d dockerCli) Client() client.APIClient {
return d.apiClient
}

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

func (d dockerCli) Out() *streams.Out {
return streams.NewOut(os.Stdout)
}

func (d dockerCli) Err() io.Writer {
return os.Stderr
}

func (d dockerCli) In() *streams.In {
return streams.NewIn(os.Stdin)
}

func (d dockerCli) NotaryClient(imgRefAndAuth trust.ImageRefAndAuth, actions []string) (notaryclient.Repository, error) {
//TODO implement me
panic("implement me")
}

func (d dockerCli) DefaultVersion() string {
//TODO implement me
panic("implement me")
}

func (d dockerCli) ManifestStore() manifeststore.Store {
//TODO implement me
panic("implement me")
}

func (d dockerCli) RegistryClient(b bool) client2.RegistryClient {
//TODO implement me
panic("implement me")
}

func (d dockerCli) ContentTrustEnabled() bool {
//TODO implement me
panic("implement me")
}

func (d dockerCli) ContextStore() store.Store {
//TODO implement me
panic("implement me")
}

func (d dockerCli) CurrentContext() string {
//TODO implement me
panic("implement me")
}

func (d dockerCli) StackOrchestrator(flagValue string) (command.Orchestrator, error) {
//TODO implement me
panic("implement me")
}

func (d dockerCli) DockerEndpoint() docker.Endpoint {
//TODO implement me
panic("implement me")
}

func (d dockerCli) SetIn(in *streams.In) {
// Nop
}

func (d dockerCli) Apply(ops ...command.DockerCliOption) error {
// Nop
return nil
}

func (d dockerCli) ServerInfo() command.ServerInfo {
panic("implement me")
}

func (d dockerCli) ClientInfo() command.ClientInfo {
panic("implement me")
}

var _ command.Cli = dockerCli{}
135 changes: 22 additions & 113 deletions pkg/compose/exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,124 +19,41 @@ package compose
import (
"context"
"fmt"
"io"

"github.com/docker/cli/cli/streams"
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command/container"
cliopts "github.com/docker/cli/opts"
"github.com/docker/compose/v2/pkg/api"
moby "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/pkg/stdcopy"
"github.com/moby/term"

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

func (s *composeService) Exec(ctx context.Context, project string, opts api.RunOptions) (int, error) {
container, err := s.getExecTarget(ctx, project, opts)
if err != nil {
return 0, err
}

exec, err := s.apiClient.ContainerExecCreate(ctx, container.ID, moby.ExecConfig{
Cmd: opts.Command,
Env: opts.Environment,
User: opts.User,
Privileged: opts.Privileged,
Tty: opts.Tty,
Detach: opts.Detach,
WorkingDir: opts.WorkingDir,

AttachStdin: true,
AttachStdout: true,
AttachStderr: true,
})
target, err := s.getExecTarget(ctx, project, opts)
if err != nil {
return 0, err
}

if opts.Detach {
return 0, s.apiClient.ContainerExecStart(ctx, exec.ID, moby.ExecStartCheck{
Detach: true,
Tty: opts.Tty,
})
env := cliopts.NewListOpts(nil)
for _, s := range opts.Environment {
env.Set(s) // nolint:errcheck - ListOpts has no validator
}

resp, err := s.apiClient.ContainerExecAttach(ctx, exec.ID, moby.ExecStartCheck{
Tty: opts.Tty,
err = container.RunExec(s.dockerCli(), container.ExecOptions{
Interactive: true,
Tty: opts.Tty,
Detach: opts.Detach,
User: opts.User,
Privileged: opts.Privileged,
Env: env,
EnvFile: cliopts.NewListOpts(nil),
Workdir: opts.WorkingDir,
Container: target.ID,
Command: opts.Command,
})
if err != nil {
return 0, err
}
defer resp.Close() //nolint:errcheck

if opts.Tty {
s.monitorTTySize(ctx, exec.ID, s.apiClient.ContainerExecResize)
if err != nil {
return 0, err
}
}

err = s.interactiveExec(ctx, opts, resp)
if err != nil {
return 0, err
}

return s.getExecExitStatus(ctx, exec.ID)
}

// inspired by https://github.com/docker/cli/blob/master/cli/command/container/exec.go#L116
func (s *composeService) interactiveExec(ctx context.Context, opts api.RunOptions, resp moby.HijackedResponse) error {
outputDone := make(chan error)
inputDone := make(chan error)

stdout := ContainerStdout{HijackedResponse: resp}
stdin := ContainerStdin{HijackedResponse: resp}
r, err := s.getEscapeKeyProxy(opts.Stdin, opts.Tty)
if err != nil {
return err
}

in := streams.NewIn(opts.Stdin)
if in.IsTerminal() && opts.Tty {
state, err := term.SetRawTerminal(in.FD())
if err != nil {
return err
}
defer term.RestoreTerminal(in.FD(), state) //nolint:errcheck
}

go func() {
if opts.Tty {
_, err := io.Copy(opts.Stdout, stdout)
outputDone <- err
} else {
_, err := stdcopy.StdCopy(opts.Stdout, opts.Stderr, stdout)
outputDone <- err
}
stdout.Close() //nolint:errcheck
}()

go func() {
_, err := io.Copy(stdin, r)
inputDone <- err
stdin.Close() //nolint:errcheck
}()

for {
select {
case err := <-outputDone:
return err
case err := <-inputDone:
if _, ok := err.(term.EscapeError); ok {
return nil
}
if err != nil {
return err
}
// Wait for output to complete streaming
case <-ctx.Done():
return ctx.Err()
}
if sterr, ok := err.(cli.StatusError); ok {
return sterr.StatusCode, nil
}
return 0, err
}

func (s *composeService) getExecTarget(ctx context.Context, projectName string, opts api.RunOptions) (moby.Container, error) {
Expand All @@ -156,11 +73,3 @@ func (s *composeService) getExecTarget(ctx context.Context, projectName string,
container := containers[0]
return container, nil
}

func (s *composeService) getExecExitStatus(ctx context.Context, execID string) (int, error) {
resp, err := s.apiClient.ContainerExecInspect(ctx, execID)
if err != nil {
return 0, err
}
return resp.ExitCode, nil
}