mirror of https://github.com/docker/compose.git
composeService to use dockerCli's In/Out/Err streams
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
This commit is contained in:
parent
bf5785307b
commit
f86f252a66
|
@ -18,11 +18,8 @@ package compose
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/compose-spec/compose-go/types"
|
"github.com/compose-spec/compose-go/types"
|
||||||
"github.com/containerd/console"
|
|
||||||
"github.com/docker/cli/cli"
|
"github.com/docker/cli/cli"
|
||||||
"github.com/docker/compose/v2/pkg/api"
|
"github.com/docker/compose/v2/pkg/api"
|
||||||
"github.com/docker/compose/v2/pkg/compose"
|
"github.com/docker/compose/v2/pkg/compose"
|
||||||
|
@ -100,27 +97,8 @@ func runExec(ctx context.Context, backend api.Service, opts execOpts) error {
|
||||||
Index: opts.index,
|
Index: opts.index,
|
||||||
Detach: opts.detach,
|
Detach: opts.detach,
|
||||||
WorkingDir: opts.workingDir,
|
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)
|
exitCode, err := backend.Exec(ctx, projectName, execOpts)
|
||||||
if exitCode != 0 {
|
if exitCode != 0 {
|
||||||
errMsg := ""
|
errMsg := ""
|
||||||
|
|
|
@ -19,7 +19,6 @@ package compose
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
cgo "github.com/compose-spec/compose-go/cli"
|
cgo "github.com/compose-spec/compose-go/cli"
|
||||||
|
@ -199,9 +198,6 @@ func runRun(ctx context.Context, backend api.Service, project *types.Project, op
|
||||||
Command: opts.Command,
|
Command: opts.Command,
|
||||||
Detach: opts.Detach,
|
Detach: opts.Detach,
|
||||||
AutoRemove: opts.Remove,
|
AutoRemove: opts.Remove,
|
||||||
Stdin: os.Stdin,
|
|
||||||
Stdout: os.Stdout,
|
|
||||||
Stderr: os.Stderr,
|
|
||||||
Tty: !opts.noTty,
|
Tty: !opts.noTty,
|
||||||
WorkingDir: opts.workdir,
|
WorkingDir: opts.workdir,
|
||||||
User: opts.user,
|
User: opts.user,
|
||||||
|
|
|
@ -46,7 +46,7 @@ func pluginMain() {
|
||||||
if err := plugin.PersistentPreRunE(cmd, args); err != nil {
|
if err := plugin.PersistentPreRunE(cmd, args); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
lazyInit.WithService(compose.NewComposeService(dockerCli.Client(), dockerCli.ConfigFile()))
|
lazyInit.WithService(compose.NewComposeService(dockerCli))
|
||||||
if originalPreRun != nil {
|
if originalPreRun != nil {
|
||||||
return originalPreRun(cmd, args)
|
return originalPreRun(cmd, args)
|
||||||
}
|
}
|
||||||
|
|
2
go.mod
2
go.mod
|
@ -32,6 +32,7 @@ require (
|
||||||
github.com/spf13/cobra v1.3.0
|
github.com/spf13/cobra v1.3.0
|
||||||
github.com/spf13/pflag v1.0.5
|
github.com/spf13/pflag v1.0.5
|
||||||
github.com/stretchr/testify v1.7.0
|
github.com/stretchr/testify v1.7.0
|
||||||
|
github.com/theupdateframework/notary v0.6.1
|
||||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
|
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
|
||||||
gotest.tools v2.2.0+incompatible
|
gotest.tools v2.2.0+incompatible
|
||||||
gotest.tools/v3 v3.1.0
|
gotest.tools/v3 v3.1.0
|
||||||
|
@ -94,7 +95,6 @@ require (
|
||||||
github.com/qri-io/jsonpointer v0.1.0 // indirect
|
github.com/qri-io/jsonpointer v0.1.0 // indirect
|
||||||
github.com/qri-io/jsonschema v0.1.1 // indirect
|
github.com/qri-io/jsonschema v0.1.1 // indirect
|
||||||
github.com/sergi/go-diff v1.1.0 // 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/fsutil v0.0.0-20210818161904-4442383b5028 // indirect
|
||||||
github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea // indirect
|
github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea // indirect
|
||||||
github.com/tonistiigi/vt100 v0.0.0-20210615222946-8066bb97264f // indirect
|
github.com/tonistiigi/vt100 v0.0.0-20210615222946-8066bb97264f // indirect
|
||||||
|
|
|
@ -19,7 +19,6 @@ package api
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -216,9 +215,6 @@ type RunOptions struct {
|
||||||
Entrypoint []string
|
Entrypoint []string
|
||||||
Detach bool
|
Detach bool
|
||||||
AutoRemove bool
|
AutoRemove bool
|
||||||
Stdin io.ReadCloser
|
|
||||||
Stdout io.WriteCloser
|
|
||||||
Stderr io.WriteCloser
|
|
||||||
Tty bool
|
Tty bool
|
||||||
WorkingDir string
|
WorkingDir string
|
||||||
User string
|
User string
|
||||||
|
|
|
@ -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) {
|
func (s *composeService) getContainerStreams(ctx context.Context, container string) (io.WriteCloser, io.ReadCloser, error) {
|
||||||
var stdout io.ReadCloser
|
var stdout io.ReadCloser
|
||||||
var stdin io.WriteCloser
|
var stdin io.WriteCloser
|
||||||
cnx, err := s.apiClient.ContainerAttach(ctx, container, moby.ContainerAttachOptions{
|
cnx, err := s.apiClient().ContainerAttach(ctx, container, moby.ContainerAttachOptions{
|
||||||
Stream: true,
|
Stream: true,
|
||||||
Stdin: true,
|
Stdin: true,
|
||||||
Stdout: true,
|
Stdout: true,
|
||||||
|
@ -151,7 +151,7 @@ func (s *composeService) getContainerStreams(ctx context.Context, container stri
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fallback to logs API
|
// Fallback to logs API
|
||||||
logs, err := s.apiClient.ContainerLogs(ctx, container, moby.ContainerLogsOptions{
|
logs, err := s.apiClient().ContainerLogs(ctx, container, moby.ContainerLogsOptions{
|
||||||
ShowStdout: true,
|
ShowStdout: true,
|
||||||
ShowStderr: true,
|
ShowStderr: true,
|
||||||
Follow: true,
|
Follow: true,
|
||||||
|
|
|
@ -19,7 +19,6 @@ package compose
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/compose-spec/compose-go/types"
|
"github.com/compose-spec/compose-go/types"
|
||||||
|
@ -193,7 +192,7 @@ func (s *composeService) getLocalImagesDigests(ctx context.Context, project *typ
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *composeService) serverInfo(ctx context.Context) (command.ServerInfo, error) {
|
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 {
|
if err != nil {
|
||||||
return command.ServerInfo{}, err
|
return command.ServerInfo{}, err
|
||||||
}
|
}
|
||||||
|
@ -258,7 +257,7 @@ func (s *composeService) toBuildOptions(project *types.Project, service types.Se
|
||||||
NetworkMode: service.Build.Network,
|
NetworkMode: service.Build.Network,
|
||||||
ExtraHosts: service.Build.ExtraHosts,
|
ExtraHosts: service.Build.ExtraHosts,
|
||||||
Session: []session.Attachable{
|
Session: []session.Attachable{
|
||||||
authprovider.NewDockerAuthProvider(os.Stderr),
|
authprovider.NewDockerAuthProvider(s.stderr()),
|
||||||
},
|
},
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
func (s *composeService) doBuildBuildkit(ctx context.Context, project *types.Project, opts map[string]build.Options, mode string) (map[string]string, error) {
|
||||||
const drivername = "default"
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ func (s *composeService) doBuildBuildkit(ctx context.Context, project *types.Pro
|
||||||
w := xprogress.NewPrinter(progressCtx, os.Stdout, mode)
|
w := xprogress.NewPrinter(progressCtx, os.Stdout, mode)
|
||||||
|
|
||||||
// We rely on buildx "docker" builder integrated in docker engine, so don't need a DockerAPI here
|
// 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()
|
errW := w.Wait()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
err = errW
|
err = errW
|
||||||
|
|
|
@ -69,8 +69,8 @@ func (s *composeService) doBuildClassicSimpleImage(ctx context.Context, options
|
||||||
|
|
||||||
dockerfileName := options.Inputs.DockerfilePath
|
dockerfileName := options.Inputs.DockerfilePath
|
||||||
specifiedContext := options.Inputs.ContextPath
|
specifiedContext := options.Inputs.ContextPath
|
||||||
progBuff := os.Stdout
|
progBuff := s.stdout()
|
||||||
buildBuff := os.Stdout
|
buildBuff := s.stdout()
|
||||||
if options.ImageIDFile != "" {
|
if options.ImageIDFile != "" {
|
||||||
// Avoid leaving a stale file if we eventually fail
|
// Avoid leaving a stale file if we eventually fail
|
||||||
if err := os.Remove(options.ImageIDFile); err != nil && !os.IsNotExist(err) {
|
if err := os.Remove(options.ImageIDFile); err != nil && !os.IsNotExist(err) {
|
||||||
|
@ -155,7 +155,7 @@ func (s *composeService) doBuildClassicSimpleImage(ctx context.Context, options
|
||||||
body = progress.NewProgressReader(buildCtx, progressOutput, 0, "", "Sending build context to Docker daemon")
|
body = progress.NewProgressReader(buildCtx, progressOutput, 0, "", "Sending build context to Docker daemon")
|
||||||
}
|
}
|
||||||
|
|
||||||
configFile := s.configFile
|
configFile := s.configFile()
|
||||||
creds, err := configFile.GetAllCredentials()
|
creds, err := configFile.GetAllCredentials()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
|
@ -171,7 +171,7 @@ func (s *composeService) doBuildClassicSimpleImage(ctx context.Context, options
|
||||||
|
|
||||||
ctx, cancel := context.WithCancel(ctx)
|
ctx, cancel := context.WithCancel(ctx)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
response, err := s.apiClient.ImageBuild(ctx, body, buildOptions)
|
response, err := s.apiClient().ImageBuild(ctx, body, buildOptions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
@ -181,13 +181,13 @@ func (s *composeService) doBuildClassicSimpleImage(ctx context.Context, options
|
||||||
aux := func(msg jsonmessage.JSONMessage) {
|
aux := func(msg jsonmessage.JSONMessage) {
|
||||||
var result dockertypes.BuildResult
|
var result dockertypes.BuildResult
|
||||||
if err := json.Unmarshal(*msg.Aux, &result); err != nil {
|
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 {
|
} else {
|
||||||
imageID = result.ID
|
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 err != nil {
|
||||||
if jerr, ok := err.(*jsonmessage.JSONError); ok {
|
if jerr, ok := err.(*jsonmessage.JSONError); ok {
|
||||||
// If no error code is set, default to 1
|
// If no error code is set, default to 1
|
||||||
|
@ -203,7 +203,7 @@ func (s *composeService) doBuildClassicSimpleImage(ctx context.Context, options
|
||||||
// daemon isn't running Windows.
|
// daemon isn't running Windows.
|
||||||
if response.OSType != "windows" && runtime.GOOS == "windows" {
|
if response.OSType != "windows" && runtime.GOOS == "windows" {
|
||||||
// if response.OSType != "windows" && runtime.GOOS == "windows" && !options.quiet {
|
// 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 "+
|
"image from Windows against a non-Windows Docker host. All files and "+
|
||||||
"directories added to build context will have '-rwxr-xr-x' permissions. "+
|
"directories added to build context will have '-rwxr-xr-x' permissions. "+
|
||||||
"It is recommended to double check and reset permissions for sensitive "+
|
"It is recommended to double check and reset permissions for sensitive "+
|
||||||
|
|
|
@ -21,13 +21,16 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/docker/compose/v2/pkg/api"
|
"github.com/docker/compose/v2/pkg/api"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
"github.com/compose-spec/compose-go/types"
|
"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/config/configfile"
|
||||||
|
"github.com/docker/cli/cli/streams"
|
||||||
moby "github.com/docker/docker/api/types"
|
moby "github.com/docker/docker/api/types"
|
||||||
"github.com/docker/docker/client"
|
"github.com/docker/docker/client"
|
||||||
"github.com/sanathkr/go-yaml"
|
"github.com/sanathkr/go-yaml"
|
||||||
|
@ -37,16 +40,34 @@ import (
|
||||||
var Separator = "-"
|
var Separator = "-"
|
||||||
|
|
||||||
// NewComposeService create a local implementation of the compose.Service API
|
// 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{
|
return &composeService{
|
||||||
apiClient: apiClient,
|
dockerCli: dockerCli,
|
||||||
configFile: configFile,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type composeService struct {
|
type composeService struct {
|
||||||
apiClient client.APIClient
|
dockerCli command.Cli
|
||||||
configFile *configfile.ConfigFile
|
}
|
||||||
|
|
||||||
|
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 {
|
func getCanonicalContainerName(c moby.Container) string {
|
||||||
|
|
|
@ -52,7 +52,7 @@ func (s *composeService) getContainers(ctx context.Context, project string, oneO
|
||||||
f = append(f, oneOffFilter(false))
|
f = append(f, oneOffFilter(false))
|
||||||
case oneOffInclude:
|
case oneOffInclude:
|
||||||
}
|
}
|
||||||
containers, err := s.apiClient.ContainerList(ctx, moby.ContainerListOptions{
|
containers, err := s.apiClient().ContainerList(ctx, moby.ContainerListOptions{
|
||||||
Filters: filters.NewArgs(f...),
|
Filters: filters.NewArgs(f...),
|
||||||
All: stopped,
|
All: stopped,
|
||||||
})
|
})
|
||||||
|
|
|
@ -180,11 +180,11 @@ func (c *convergence) ensureService(ctx context.Context, project *types.Project,
|
||||||
// Scale Down
|
// Scale Down
|
||||||
container := container
|
container := container
|
||||||
eg.Go(func() error {
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return c.service.apiClient.ContainerRemove(ctx, container.ID, moby.ContainerRemoveOptions{})
|
return c.service.apiClient().ContainerRemove(ctx, container.ID, moby.ContainerRemoveOptions{})
|
||||||
})
|
})
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -395,13 +395,13 @@ func (s *composeService) recreateContainer(ctx context.Context, project *types.P
|
||||||
var created moby.Container
|
var created moby.Container
|
||||||
w := progress.ContextWriter(ctx)
|
w := progress.ContextWriter(ctx)
|
||||||
w.Event(progress.NewEvent(getContainerProgressName(replaced), progress.Working, "Recreate"))
|
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 {
|
if err != nil {
|
||||||
return created, err
|
return created, err
|
||||||
}
|
}
|
||||||
name := getCanonicalContainerName(replaced)
|
name := getCanonicalContainerName(replaced)
|
||||||
tmpName := fmt.Sprintf("%s_%s", replaced.ID[:12], name)
|
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 {
|
if err != nil {
|
||||||
return created, err
|
return created, err
|
||||||
}
|
}
|
||||||
|
@ -419,7 +419,7 @@ func (s *composeService) recreateContainer(ctx context.Context, project *types.P
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return created, err
|
return created, err
|
||||||
}
|
}
|
||||||
err = s.apiClient.ContainerRemove(ctx, replaced.ID, moby.ContainerRemoveOptions{})
|
err = s.apiClient().ContainerRemove(ctx, replaced.ID, moby.ContainerRemoveOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return created, err
|
return created, err
|
||||||
}
|
}
|
||||||
|
@ -444,7 +444,7 @@ func setDependentLifecycle(project *types.Project, service string, strategy stri
|
||||||
func (s *composeService) startContainer(ctx context.Context, container moby.Container) error {
|
func (s *composeService) startContainer(ctx context.Context, container moby.Container) error {
|
||||||
w := progress.ContextWriter(ctx)
|
w := progress.ContextWriter(ctx)
|
||||||
w.Event(progress.NewEvent(getContainerProgressName(container), progress.Working, "Restart"))
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -468,11 +468,11 @@ func (s *composeService) createMobyContainer(ctx context.Context, project *types
|
||||||
}
|
}
|
||||||
plat = &p
|
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 {
|
if err != nil {
|
||||||
return created, err
|
return created, err
|
||||||
}
|
}
|
||||||
inspectedContainer, err := s.apiClient.ContainerInspect(ctx, response.ID)
|
inspectedContainer, err := s.apiClient().ContainerInspect(ctx, response.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return created, err
|
return created, err
|
||||||
}
|
}
|
||||||
|
@ -502,7 +502,7 @@ func (s *composeService) createMobyContainer(ctx context.Context, project *types
|
||||||
if shortIDAliasExists(created.ID, val.Aliases...) {
|
if shortIDAliasExists(created.ID, val.Aliases...) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
err = s.apiClient.NetworkDisconnect(ctx, netwrk.Name, created.ID, false)
|
err = s.apiClient().NetworkDisconnect(ctx, netwrk.Name, created.ID, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return created, err
|
return created, err
|
||||||
}
|
}
|
||||||
|
@ -596,7 +596,7 @@ func (s *composeService) connectContainerToNetwork(ctx context.Context, id strin
|
||||||
IPv6Address: ipv6Address,
|
IPv6Address: ipv6Address,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
err := s.apiClient.NetworkConnect(ctx, netwrk, id, &network.EndpointSettings{
|
err := s.apiClient().NetworkConnect(ctx, netwrk, id, &network.EndpointSettings{
|
||||||
Aliases: aliases,
|
Aliases: aliases,
|
||||||
IPAddress: ipv4Address,
|
IPAddress: ipv4Address,
|
||||||
GlobalIPv6Address: ipv6Address,
|
GlobalIPv6Address: ipv6Address,
|
||||||
|
@ -619,7 +619,7 @@ func (s *composeService) isServiceHealthy(ctx context.Context, project *types.Pr
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
for _, c := range containers {
|
for _, c := range containers {
|
||||||
container, err := s.apiClient.ContainerInspect(ctx, c.ID)
|
container, err := s.apiClient().ContainerInspect(ctx, c.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
@ -651,7 +651,7 @@ func (s *composeService) isServiceCompleted(ctx context.Context, project *types.
|
||||||
return false, 0, err
|
return false, 0, err
|
||||||
}
|
}
|
||||||
for _, c := range containers {
|
for _, c := range containers {
|
||||||
container, err := s.apiClient.ContainerInspect(ctx, c.ID)
|
container, err := s.apiClient().ContainerInspect(ctx, c.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, 0, err
|
return false, 0, err
|
||||||
}
|
}
|
||||||
|
@ -671,7 +671,7 @@ func (s *composeService) startService(ctx context.Context, project *types.Projec
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
containers, err := s.apiClient.ContainerList(ctx, moby.ContainerListOptions{
|
containers, err := s.apiClient().ContainerList(ctx, moby.ContainerListOptions{
|
||||||
Filters: filters.NewArgs(
|
Filters: filters.NewArgs(
|
||||||
projectFilter(project.Name),
|
projectFilter(project.Name),
|
||||||
serviceFilter(service.Name),
|
serviceFilter(service.Name),
|
||||||
|
@ -700,7 +700,7 @@ func (s *composeService) startService(ctx context.Context, project *types.Projec
|
||||||
eg.Go(func() error {
|
eg.Go(func() error {
|
||||||
eventName := getContainerProgressName(container)
|
eventName := getContainerProgressName(container)
|
||||||
w.Event(progress.StartingEvent(eventName))
|
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 {
|
if err == nil {
|
||||||
w.Event(progress.StartedEvent(eventName))
|
w.Event(progress.StartedEvent(eventName))
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,8 +74,11 @@ func TestServiceLinks(t *testing.T) {
|
||||||
t.Run("service links default", func(t *testing.T) {
|
t.Run("service links default", func(t *testing.T) {
|
||||||
mockCtrl := gomock.NewController(t)
|
mockCtrl := gomock.NewController(t)
|
||||||
defer mockCtrl.Finish()
|
defer mockCtrl.Finish()
|
||||||
|
|
||||||
apiClient := mocks.NewMockAPIClient(mockCtrl)
|
apiClient := mocks.NewMockAPIClient(mockCtrl)
|
||||||
tested.apiClient = apiClient
|
cli := mocks.NewMockCli(mockCtrl)
|
||||||
|
tested.dockerCli = cli
|
||||||
|
cli.EXPECT().Client().Return(apiClient)
|
||||||
|
|
||||||
s.Links = []string{"db"}
|
s.Links = []string{"db"}
|
||||||
|
|
||||||
|
@ -95,7 +98,9 @@ func TestServiceLinks(t *testing.T) {
|
||||||
mockCtrl := gomock.NewController(t)
|
mockCtrl := gomock.NewController(t)
|
||||||
defer mockCtrl.Finish()
|
defer mockCtrl.Finish()
|
||||||
apiClient := mocks.NewMockAPIClient(mockCtrl)
|
apiClient := mocks.NewMockAPIClient(mockCtrl)
|
||||||
tested.apiClient = apiClient
|
cli := mocks.NewMockCli(mockCtrl)
|
||||||
|
tested.dockerCli = cli
|
||||||
|
cli.EXPECT().Client().Return(apiClient)
|
||||||
|
|
||||||
s.Links = []string{"db:db"}
|
s.Links = []string{"db:db"}
|
||||||
|
|
||||||
|
@ -115,7 +120,9 @@ func TestServiceLinks(t *testing.T) {
|
||||||
mockCtrl := gomock.NewController(t)
|
mockCtrl := gomock.NewController(t)
|
||||||
defer mockCtrl.Finish()
|
defer mockCtrl.Finish()
|
||||||
apiClient := mocks.NewMockAPIClient(mockCtrl)
|
apiClient := mocks.NewMockAPIClient(mockCtrl)
|
||||||
tested.apiClient = apiClient
|
cli := mocks.NewMockCli(mockCtrl)
|
||||||
|
tested.dockerCli = cli
|
||||||
|
cli.EXPECT().Client().Return(apiClient)
|
||||||
|
|
||||||
s.Links = []string{"db:dbname"}
|
s.Links = []string{"db:dbname"}
|
||||||
|
|
||||||
|
@ -135,7 +142,9 @@ func TestServiceLinks(t *testing.T) {
|
||||||
mockCtrl := gomock.NewController(t)
|
mockCtrl := gomock.NewController(t)
|
||||||
defer mockCtrl.Finish()
|
defer mockCtrl.Finish()
|
||||||
apiClient := mocks.NewMockAPIClient(mockCtrl)
|
apiClient := mocks.NewMockAPIClient(mockCtrl)
|
||||||
tested.apiClient = apiClient
|
cli := mocks.NewMockCli(mockCtrl)
|
||||||
|
tested.dockerCli = cli
|
||||||
|
cli.EXPECT().Client().Return(apiClient)
|
||||||
|
|
||||||
s.Links = []string{"db:dbname"}
|
s.Links = []string{"db:dbname"}
|
||||||
s.ExternalLinks = []string{"db1:db2"}
|
s.ExternalLinks = []string{"db1:db2"}
|
||||||
|
@ -159,7 +168,9 @@ func TestServiceLinks(t *testing.T) {
|
||||||
mockCtrl := gomock.NewController(t)
|
mockCtrl := gomock.NewController(t)
|
||||||
defer mockCtrl.Finish()
|
defer mockCtrl.Finish()
|
||||||
apiClient := mocks.NewMockAPIClient(mockCtrl)
|
apiClient := mocks.NewMockAPIClient(mockCtrl)
|
||||||
tested.apiClient = apiClient
|
cli := mocks.NewMockCli(mockCtrl)
|
||||||
|
tested.dockerCli = cli
|
||||||
|
cli.EXPECT().Client().Return(apiClient)
|
||||||
|
|
||||||
s.Links = []string{}
|
s.Links = []string{}
|
||||||
s.ExternalLinks = []string{}
|
s.ExternalLinks = []string{}
|
||||||
|
|
|
@ -107,7 +107,7 @@ func (s *composeService) copyToContainer(ctx context.Context, containerID string
|
||||||
|
|
||||||
// Prepare destination copy info by stat-ing the container path.
|
// Prepare destination copy info by stat-ing the container path.
|
||||||
dstInfo := archive.CopyInfo{Path: dstPath}
|
dstInfo := archive.CopyInfo{Path: dstPath}
|
||||||
dstStat, err := s.apiClient.ContainerStatPath(ctx, containerID, dstPath)
|
dstStat, err := s.apiClient().ContainerStatPath(ctx, containerID, dstPath)
|
||||||
|
|
||||||
// If the destination is a symbolic link, we should evaluate it.
|
// If the destination is a symbolic link, we should evaluate it.
|
||||||
if err == nil && dstStat.Mode&os.ModeSymlink != 0 {
|
if err == nil && dstStat.Mode&os.ModeSymlink != 0 {
|
||||||
|
@ -119,7 +119,7 @@ func (s *composeService) copyToContainer(ctx context.Context, containerID string
|
||||||
}
|
}
|
||||||
|
|
||||||
dstInfo.Path = linkTarget
|
dstInfo.Path = linkTarget
|
||||||
dstStat, err = s.apiClient.ContainerStatPath(ctx, containerID, linkTarget)
|
dstStat, err = s.apiClient().ContainerStatPath(ctx, containerID, linkTarget)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate the destination path
|
// Validate the destination path
|
||||||
|
@ -143,7 +143,7 @@ func (s *composeService) copyToContainer(ctx context.Context, containerID string
|
||||||
)
|
)
|
||||||
|
|
||||||
if srcPath == "-" {
|
if srcPath == "-" {
|
||||||
content = os.Stdin
|
content = s.stdin()
|
||||||
resolvedDstPath = dstInfo.Path
|
resolvedDstPath = dstInfo.Path
|
||||||
if !dstInfo.IsDir {
|
if !dstInfo.IsDir {
|
||||||
return errors.Errorf("destination \"%s:%s\" must be a directory", containerID, dstPath)
|
return errors.Errorf("destination \"%s:%s\" must be a directory", containerID, dstPath)
|
||||||
|
@ -187,7 +187,7 @@ func (s *composeService) copyToContainer(ctx context.Context, containerID string
|
||||||
AllowOverwriteDirWithFile: false,
|
AllowOverwriteDirWithFile: false,
|
||||||
CopyUIDGID: opts.CopyUIDGID,
|
CopyUIDGID: opts.CopyUIDGID,
|
||||||
}
|
}
|
||||||
return s.apiClient.CopyToContainer(ctx, containerID, resolvedDstPath, content, options)
|
return s.apiClient().CopyToContainer(ctx, containerID, resolvedDstPath, content, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *composeService) copyFromContainer(ctx context.Context, containerID, srcPath, dstPath string, opts api.CopyOptions) error {
|
func (s *composeService) copyFromContainer(ctx context.Context, containerID, srcPath, dstPath string, opts api.CopyOptions) error {
|
||||||
|
@ -207,7 +207,7 @@ func (s *composeService) copyFromContainer(ctx context.Context, containerID, src
|
||||||
// if client requests to follow symbol link, then must decide target file to be copied
|
// if client requests to follow symbol link, then must decide target file to be copied
|
||||||
var rebaseName string
|
var rebaseName string
|
||||||
if opts.FollowLink {
|
if opts.FollowLink {
|
||||||
srcStat, err := s.apiClient.ContainerStatPath(ctx, containerID, srcPath)
|
srcStat, err := s.apiClient().ContainerStatPath(ctx, containerID, srcPath)
|
||||||
|
|
||||||
// If the destination is a symbolic link, we should follow it.
|
// If the destination is a symbolic link, we should follow it.
|
||||||
if err == nil && srcStat.Mode&os.ModeSymlink != 0 {
|
if err == nil && srcStat.Mode&os.ModeSymlink != 0 {
|
||||||
|
@ -223,14 +223,14 @@ func (s *composeService) copyFromContainer(ctx context.Context, containerID, src
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
content, stat, err := s.apiClient.CopyFromContainer(ctx, containerID, srcPath)
|
content, stat, err := s.apiClient().CopyFromContainer(ctx, containerID, srcPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer content.Close() //nolint:errcheck
|
defer content.Close() //nolint:errcheck
|
||||||
|
|
||||||
if dstPath == "-" {
|
if dstPath == "-" {
|
||||||
_, err = io.Copy(os.Stdout, content)
|
_, err = io.Copy(s.stdout(), content)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -255,7 +255,7 @@ func (s *composeService) getCreateOptions(ctx context.Context, p *types.Project,
|
||||||
return nil, nil, nil, err
|
return nil, nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
proxyConfig := types.MappingWithEquals(s.configFile.ParseProxyConfig(s.apiClient.DaemonHost(), nil))
|
proxyConfig := types.MappingWithEquals(s.configFile().ParseProxyConfig(s.apiClient().DaemonHost(), nil))
|
||||||
env := proxyConfig.OverrideBy(service.Environment)
|
env := proxyConfig.OverrideBy(service.Environment)
|
||||||
|
|
||||||
containerConfig := container.Config{
|
containerConfig := container.Config{
|
||||||
|
@ -693,7 +693,7 @@ func (s *composeService) buildContainerVolumes(ctx context.Context, p types.Proj
|
||||||
var mounts = []mount.Mount{}
|
var mounts = []mount.Mount{}
|
||||||
|
|
||||||
image := getImageName(service, p.Name)
|
image := getImageName(service, p.Name)
|
||||||
imgInspect, _, err := s.apiClient.ImageInspectWithRaw(ctx, image)
|
imgInspect, _, err := s.apiClient().ImageInspectWithRaw(ctx, image)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, nil, err
|
return nil, nil, nil, err
|
||||||
}
|
}
|
||||||
|
@ -1007,7 +1007,7 @@ func getAliases(s types.ServiceConfig, c *types.ServiceNetworkConfig) []string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *composeService) ensureNetwork(ctx context.Context, n types.NetworkConfig) error {
|
func (s *composeService) ensureNetwork(ctx context.Context, n types.NetworkConfig) error {
|
||||||
_, err := s.apiClient.NetworkInspect(ctx, n.Name, moby.NetworkInspectOptions{})
|
_, err := s.apiClient().NetworkInspect(ctx, n.Name, moby.NetworkInspectOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errdefs.IsNotFound(err) {
|
if errdefs.IsNotFound(err) {
|
||||||
if n.External.External {
|
if n.External.External {
|
||||||
|
@ -1065,7 +1065,7 @@ func (s *composeService) ensureNetwork(ctx context.Context, n types.NetworkConfi
|
||||||
networkEventName := fmt.Sprintf("Network %s", n.Name)
|
networkEventName := fmt.Sprintf("Network %s", n.Name)
|
||||||
w := progress.ContextWriter(ctx)
|
w := progress.ContextWriter(ctx)
|
||||||
w.Event(progress.CreatingEvent(networkEventName))
|
w.Event(progress.CreatingEvent(networkEventName))
|
||||||
if _, err := s.apiClient.NetworkCreate(ctx, n.Name, createOpts); err != nil {
|
if _, err := s.apiClient().NetworkCreate(ctx, n.Name, createOpts); err != nil {
|
||||||
w.Event(progress.ErrorEvent(networkEventName))
|
w.Event(progress.ErrorEvent(networkEventName))
|
||||||
return errors.Wrapf(err, "failed to create network %s", n.Name)
|
return errors.Wrapf(err, "failed to create network %s", n.Name)
|
||||||
}
|
}
|
||||||
|
@ -1082,7 +1082,7 @@ func (s *composeService) removeNetwork(ctx context.Context, networkID string, ne
|
||||||
eventName := fmt.Sprintf("Network %s", networkName)
|
eventName := fmt.Sprintf("Network %s", networkName)
|
||||||
w.Event(progress.RemovingEvent(eventName))
|
w.Event(progress.RemovingEvent(eventName))
|
||||||
|
|
||||||
if err := s.apiClient.NetworkRemove(ctx, networkID); err != nil {
|
if err := s.apiClient().NetworkRemove(ctx, networkID); err != nil {
|
||||||
w.Event(progress.ErrorEvent(eventName))
|
w.Event(progress.ErrorEvent(eventName))
|
||||||
return errors.Wrapf(err, fmt.Sprintf("failed to remove network %s", networkID))
|
return errors.Wrapf(err, fmt.Sprintf("failed to remove network %s", networkID))
|
||||||
}
|
}
|
||||||
|
@ -1092,7 +1092,7 @@ func (s *composeService) removeNetwork(ctx context.Context, networkID string, ne
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *composeService) ensureVolume(ctx context.Context, volume types.VolumeConfig, project string) error {
|
func (s *composeService) ensureVolume(ctx context.Context, volume types.VolumeConfig, project string) error {
|
||||||
inspected, err := s.apiClient.VolumeInspect(ctx, volume.Name)
|
inspected, err := s.apiClient().VolumeInspect(ctx, volume.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if !errdefs.IsNotFound(err) {
|
if !errdefs.IsNotFound(err) {
|
||||||
return err
|
return err
|
||||||
|
@ -1123,7 +1123,7 @@ func (s *composeService) createVolume(ctx context.Context, volume types.VolumeCo
|
||||||
eventName := fmt.Sprintf("Volume %q", volume.Name)
|
eventName := fmt.Sprintf("Volume %q", volume.Name)
|
||||||
w := progress.ContextWriter(ctx)
|
w := progress.ContextWriter(ctx)
|
||||||
w.Event(progress.CreatingEvent(eventName))
|
w.Event(progress.CreatingEvent(eventName))
|
||||||
_, err := s.apiClient.VolumeCreate(ctx, volume_api.VolumeCreateBody{
|
_, err := s.apiClient().VolumeCreate(ctx, volume_api.VolumeCreateBody{
|
||||||
Labels: volume.Labels,
|
Labels: volume.Labels,
|
||||||
Name: volume.Name,
|
Name: volume.Name,
|
||||||
Driver: volume.Driver,
|
Driver: volume.Driver,
|
||||||
|
|
|
@ -127,7 +127,7 @@ func (s *composeService) ensureImagesDown(ctx context.Context, projectName strin
|
||||||
|
|
||||||
func (s *composeService) ensureNetworksDown(ctx context.Context, projectName string) ([]downOp, error) {
|
func (s *composeService) ensureNetworksDown(ctx context.Context, projectName string) ([]downOp, error) {
|
||||||
var ops []downOp
|
var ops []downOp
|
||||||
networks, err := s.apiClient.NetworkList(ctx, moby.NetworkListOptions{Filters: filters.NewArgs(projectFilter(projectName))})
|
networks, err := s.apiClient().NetworkList(ctx, moby.NetworkListOptions{Filters: filters.NewArgs(projectFilter(projectName))})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ops, err
|
return ops, err
|
||||||
}
|
}
|
||||||
|
@ -159,7 +159,7 @@ func (s *composeService) getServiceImages(options api.DownOptions, projectName s
|
||||||
func (s *composeService) removeImage(ctx context.Context, image string, w progress.Writer) error {
|
func (s *composeService) removeImage(ctx context.Context, image string, w progress.Writer) error {
|
||||||
id := fmt.Sprintf("Image %s", image)
|
id := fmt.Sprintf("Image %s", image)
|
||||||
w.Event(progress.NewEvent(id, progress.Working, "Removing"))
|
w.Event(progress.NewEvent(id, progress.Working, "Removing"))
|
||||||
_, err := s.apiClient.ImageRemove(ctx, image, moby.ImageRemoveOptions{})
|
_, err := s.apiClient().ImageRemove(ctx, image, moby.ImageRemoveOptions{})
|
||||||
if err == nil {
|
if err == nil {
|
||||||
w.Event(progress.NewEvent(id, progress.Done, "Removed"))
|
w.Event(progress.NewEvent(id, progress.Done, "Removed"))
|
||||||
return nil
|
return nil
|
||||||
|
@ -174,7 +174,7 @@ func (s *composeService) removeImage(ctx context.Context, image string, w progre
|
||||||
func (s *composeService) removeVolume(ctx context.Context, id string, w progress.Writer) error {
|
func (s *composeService) removeVolume(ctx context.Context, id string, w progress.Writer) error {
|
||||||
resource := fmt.Sprintf("Volume %s", id)
|
resource := fmt.Sprintf("Volume %s", id)
|
||||||
w.Event(progress.NewEvent(resource, progress.Working, "Removing"))
|
w.Event(progress.NewEvent(resource, progress.Working, "Removing"))
|
||||||
err := s.apiClient.VolumeRemove(ctx, id, true)
|
err := s.apiClient().VolumeRemove(ctx, id, true)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
w.Event(progress.NewEvent(resource, progress.Done, "Removed"))
|
w.Event(progress.NewEvent(resource, progress.Done, "Removed"))
|
||||||
return nil
|
return nil
|
||||||
|
@ -193,7 +193,7 @@ func (s *composeService) stopContainers(ctx context.Context, w progress.Writer,
|
||||||
eg.Go(func() error {
|
eg.Go(func() error {
|
||||||
eventName := getContainerProgressName(container)
|
eventName := getContainerProgressName(container)
|
||||||
w.Event(progress.StoppingEvent(eventName))
|
w.Event(progress.StoppingEvent(eventName))
|
||||||
err := s.apiClient.ContainerStop(ctx, container.ID, timeout)
|
err := s.apiClient().ContainerStop(ctx, container.ID, timeout)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.Event(progress.ErrorMessageEvent(eventName, "Error while Stopping"))
|
w.Event(progress.ErrorMessageEvent(eventName, "Error while Stopping"))
|
||||||
return err
|
return err
|
||||||
|
@ -218,7 +218,7 @@ func (s *composeService) removeContainers(ctx context.Context, w progress.Writer
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
w.Event(progress.RemovingEvent(eventName))
|
w.Event(progress.RemovingEvent(eventName))
|
||||||
err = s.apiClient.ContainerRemove(ctx, container.ID, moby.ContainerRemoveOptions{
|
err = s.apiClient().ContainerRemove(ctx, container.ID, moby.ContainerRemoveOptions{
|
||||||
Force: true,
|
Force: true,
|
||||||
RemoveVolumes: volumes,
|
RemoveVolumes: volumes,
|
||||||
})
|
})
|
||||||
|
@ -236,7 +236,7 @@ func (s *composeService) removeContainers(ctx context.Context, w progress.Writer
|
||||||
func (s *composeService) getProjectWithVolumes(ctx context.Context, containers Containers, projectName string) (*types.Project, error) {
|
func (s *composeService) getProjectWithVolumes(ctx context.Context, containers Containers, projectName string) (*types.Project, error) {
|
||||||
containers = containers.filter(isNotOneOff)
|
containers = containers.filter(isNotOneOff)
|
||||||
project, _ := s.projectFromName(containers, projectName)
|
project, _ := s.projectFromName(containers, projectName)
|
||||||
volumes, err := s.apiClient.VolumeList(ctx, filters.NewArgs(projectFilter(projectName)))
|
volumes, err := s.apiClient().VolumeList(ctx, filters.NewArgs(projectFilter(projectName)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *composeService) Events(ctx context.Context, project string, options api.EventsOptions) error {
|
func (s *composeService) Events(ctx context.Context, project string, options api.EventsOptions) error {
|
||||||
events, errors := s.apiClient.Events(ctx, moby.EventsOptions{
|
events, errors := s.apiClient().Events(ctx, moby.EventsOptions{
|
||||||
Filters: filters.NewArgs(projectFilter(project)),
|
Filters: filters.NewArgs(projectFilter(project)),
|
||||||
})
|
})
|
||||||
for {
|
for {
|
||||||
|
|
|
@ -21,7 +21,6 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/docker/cli/cli/streams"
|
|
||||||
moby "github.com/docker/docker/api/types"
|
moby "github.com/docker/docker/api/types"
|
||||||
"github.com/docker/docker/api/types/filters"
|
"github.com/docker/docker/api/types/filters"
|
||||||
"github.com/docker/docker/pkg/stdcopy"
|
"github.com/docker/docker/pkg/stdcopy"
|
||||||
|
@ -36,7 +35,7 @@ func (s *composeService) Exec(ctx context.Context, project string, opts api.RunO
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
exec, err := s.apiClient.ContainerExecCreate(ctx, container.ID, moby.ExecConfig{
|
exec, err := s.apiClient().ContainerExecCreate(ctx, container.ID, moby.ExecConfig{
|
||||||
Cmd: opts.Command,
|
Cmd: opts.Command,
|
||||||
Env: opts.Environment,
|
Env: opts.Environment,
|
||||||
User: opts.User,
|
User: opts.User,
|
||||||
|
@ -54,13 +53,13 @@ func (s *composeService) Exec(ctx context.Context, project string, opts api.RunO
|
||||||
}
|
}
|
||||||
|
|
||||||
if opts.Detach {
|
if opts.Detach {
|
||||||
return 0, s.apiClient.ContainerExecStart(ctx, exec.ID, moby.ExecStartCheck{
|
return 0, s.apiClient().ContainerExecStart(ctx, exec.ID, moby.ExecStartCheck{
|
||||||
Detach: true,
|
Detach: true,
|
||||||
Tty: opts.Tty,
|
Tty: opts.Tty,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := s.apiClient.ContainerExecAttach(ctx, exec.ID, moby.ExecStartCheck{
|
resp, err := s.apiClient().ContainerExecAttach(ctx, exec.ID, moby.ExecStartCheck{
|
||||||
Tty: opts.Tty,
|
Tty: opts.Tty,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -69,7 +68,7 @@ func (s *composeService) Exec(ctx context.Context, project string, opts api.RunO
|
||||||
defer resp.Close() //nolint:errcheck
|
defer resp.Close() //nolint:errcheck
|
||||||
|
|
||||||
if opts.Tty {
|
if opts.Tty {
|
||||||
s.monitorTTySize(ctx, exec.ID, s.apiClient.ContainerExecResize)
|
s.monitorTTySize(ctx, exec.ID, s.apiClient().ContainerExecResize)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
@ -90,12 +89,12 @@ func (s *composeService) interactiveExec(ctx context.Context, opts api.RunOption
|
||||||
|
|
||||||
stdout := ContainerStdout{HijackedResponse: resp}
|
stdout := ContainerStdout{HijackedResponse: resp}
|
||||||
stdin := ContainerStdin{HijackedResponse: resp}
|
stdin := ContainerStdin{HijackedResponse: resp}
|
||||||
r, err := s.getEscapeKeyProxy(opts.Stdin, opts.Tty)
|
r, err := s.getEscapeKeyProxy(s.stdin(), opts.Tty)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
in := streams.NewIn(opts.Stdin)
|
in := s.stdin()
|
||||||
if in.IsTerminal() && opts.Tty {
|
if in.IsTerminal() && opts.Tty {
|
||||||
state, err := term.SetRawTerminal(in.FD())
|
state, err := term.SetRawTerminal(in.FD())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -106,10 +105,10 @@ func (s *composeService) interactiveExec(ctx context.Context, opts api.RunOption
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
if opts.Tty {
|
if opts.Tty {
|
||||||
_, err := io.Copy(opts.Stdout, stdout)
|
_, err := io.Copy(s.stdout(), stdout)
|
||||||
outputDone <- err
|
outputDone <- err
|
||||||
} else {
|
} else {
|
||||||
_, err := stdcopy.StdCopy(opts.Stdout, opts.Stderr, stdout)
|
_, err := stdcopy.StdCopy(s.stdout(), s.stderr(), stdout)
|
||||||
outputDone <- err
|
outputDone <- err
|
||||||
}
|
}
|
||||||
stdout.Close() //nolint:errcheck
|
stdout.Close() //nolint:errcheck
|
||||||
|
@ -140,7 +139,7 @@ func (s *composeService) interactiveExec(ctx context.Context, opts api.RunOption
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *composeService) getExecTarget(ctx context.Context, projectName string, opts api.RunOptions) (moby.Container, error) {
|
func (s *composeService) getExecTarget(ctx context.Context, projectName string, opts api.RunOptions) (moby.Container, error) {
|
||||||
containers, err := s.apiClient.ContainerList(ctx, moby.ContainerListOptions{
|
containers, err := s.apiClient().ContainerList(ctx, moby.ContainerListOptions{
|
||||||
Filters: filters.NewArgs(
|
Filters: filters.NewArgs(
|
||||||
projectFilter(projectName),
|
projectFilter(projectName),
|
||||||
serviceFilter(opts.Service),
|
serviceFilter(opts.Service),
|
||||||
|
@ -158,7 +157,7 @@ func (s *composeService) getExecTarget(ctx context.Context, projectName string,
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *composeService) getExecExitStatus(ctx context.Context, execID string) (int, error) {
|
func (s *composeService) getExecExitStatus(ctx context.Context, execID string) (int, error) {
|
||||||
resp, err := s.apiClient.ContainerExecInspect(ctx, execID)
|
resp, err := s.apiClient().ContainerExecInspect(ctx, execID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *composeService) Images(ctx context.Context, projectName string, options api.ImagesOptions) ([]api.ImageSummary, error) {
|
func (s *composeService) Images(ctx context.Context, projectName string, options api.ImagesOptions) ([]api.ImageSummary, error) {
|
||||||
allContainers, err := s.apiClient.ContainerList(ctx, moby.ContainerListOptions{
|
allContainers, err := s.apiClient().ContainerList(ctx, moby.ContainerListOptions{
|
||||||
All: true,
|
All: true,
|
||||||
Filters: filters.NewArgs(projectFilter(projectName)),
|
Filters: filters.NewArgs(projectFilter(projectName)),
|
||||||
})
|
})
|
||||||
|
@ -83,7 +83,7 @@ func (s *composeService) getImages(ctx context.Context, images []string) (map[st
|
||||||
for _, img := range images {
|
for _, img := range images {
|
||||||
img := img
|
img := img
|
||||||
eg.Go(func() error {
|
eg.Go(func() error {
|
||||||
inspect, _, err := s.apiClient.ImageInspectWithRaw(ctx, img)
|
inspect, _, err := s.apiClient().ImageInspectWithRaw(ctx, img)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errdefs.IsNotFound(err) {
|
if errdefs.IsNotFound(err) {
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -54,7 +54,7 @@ func (s *composeService) kill(ctx context.Context, project *types.Project, optio
|
||||||
eg.Go(func() error {
|
eg.Go(func() error {
|
||||||
eventName := getContainerProgressName(container)
|
eventName := getContainerProgressName(container)
|
||||||
w.Event(progress.KillingEvent(eventName))
|
w.Event(progress.KillingEvent(eventName))
|
||||||
err := s.apiClient.ContainerKill(ctx, container.ID, options.Signal)
|
err := s.apiClient().ContainerKill(ctx, container.ID, options.Signal)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.Event(progress.ErrorMessageEvent(eventName, "Error while Killing"))
|
w.Event(progress.ErrorMessageEvent(eventName, "Error while Killing"))
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -75,13 +75,13 @@ func (s *composeService) Logs(ctx context.Context, projectName string, consumer
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *composeService) logContainers(ctx context.Context, consumer api.LogConsumer, c types.Container, options api.LogOptions) error {
|
func (s *composeService) logContainers(ctx context.Context, consumer api.LogConsumer, c types.Container, options api.LogOptions) error {
|
||||||
cnt, err := s.apiClient.ContainerInspect(ctx, c.ID)
|
cnt, err := s.apiClient().ContainerInspect(ctx, c.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
service := c.Labels[api.ServiceLabel]
|
service := c.Labels[api.ServiceLabel]
|
||||||
r, err := s.apiClient.ContainerLogs(ctx, cnt.ID, types.ContainerLogsOptions{
|
r, err := s.apiClient().ContainerLogs(ctx, cnt.ID, types.ContainerLogsOptions{
|
||||||
ShowStdout: true,
|
ShowStdout: true,
|
||||||
ShowStderr: true,
|
ShowStderr: true,
|
||||||
Follow: options.Follow,
|
Follow: options.Follow,
|
||||||
|
|
|
@ -30,7 +30,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *composeService) List(ctx context.Context, opts api.ListOptions) ([]api.Stack, error) {
|
func (s *composeService) List(ctx context.Context, opts api.ListOptions) ([]api.Stack, error) {
|
||||||
list, err := s.apiClient.ContainerList(ctx, moby.ContainerListOptions{
|
list, err := s.apiClient().ContainerList(ctx, moby.ContainerListOptions{
|
||||||
Filters: filters.NewArgs(hasProjectLabelFilter()),
|
Filters: filters.NewArgs(hasProjectLabelFilter()),
|
||||||
All: opts.All,
|
All: opts.All,
|
||||||
})
|
})
|
||||||
|
|
|
@ -42,7 +42,7 @@ func (s *composeService) pause(ctx context.Context, project string, options api.
|
||||||
eg, ctx := errgroup.WithContext(ctx)
|
eg, ctx := errgroup.WithContext(ctx)
|
||||||
containers.forEach(func(container moby.Container) {
|
containers.forEach(func(container moby.Container) {
|
||||||
eg.Go(func() error {
|
eg.Go(func() error {
|
||||||
err := s.apiClient.ContainerPause(ctx, container.ID)
|
err := s.apiClient().ContainerPause(ctx, container.ID)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
eventName := getContainerProgressName(container)
|
eventName := getContainerProgressName(container)
|
||||||
w.Event(progress.NewEvent(eventName, progress.Done, "Paused"))
|
w.Event(progress.NewEvent(eventName, progress.Done, "Paused"))
|
||||||
|
@ -70,7 +70,7 @@ func (s *composeService) unPause(ctx context.Context, project string, options ap
|
||||||
eg, ctx := errgroup.WithContext(ctx)
|
eg, ctx := errgroup.WithContext(ctx)
|
||||||
containers.forEach(func(container moby.Container) {
|
containers.forEach(func(container moby.Container) {
|
||||||
eg.Go(func() error {
|
eg.Go(func() error {
|
||||||
err = s.apiClient.ContainerUnpause(ctx, container.ID)
|
err = s.apiClient().ContainerUnpause(ctx, container.ID)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
eventName := getContainerProgressName(container)
|
eventName := getContainerProgressName(container)
|
||||||
w.Event(progress.NewEvent(eventName, progress.Done, "Unpaused"))
|
w.Event(progress.NewEvent(eventName, progress.Done, "Unpaused"))
|
||||||
|
|
|
@ -27,7 +27,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *composeService) Port(ctx context.Context, project string, service string, port int, options api.PortOptions) (string, int, error) {
|
func (s *composeService) Port(ctx context.Context, project string, service string, port int, options api.PortOptions) (string, int, error) {
|
||||||
list, err := s.apiClient.ContainerList(ctx, moby.ContainerListOptions{
|
list, err := s.apiClient().ContainerList(ctx, moby.ContainerListOptions{
|
||||||
Filters: filters.NewArgs(
|
Filters: filters.NewArgs(
|
||||||
projectFilter(project),
|
projectFilter(project),
|
||||||
serviceFilter(service),
|
serviceFilter(service),
|
||||||
|
|
|
@ -53,7 +53,7 @@ func (s *composeService) Ps(ctx context.Context, projectName string, options api
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
inspect, err := s.apiClient.ContainerInspect(ctx, container.ID)
|
inspect, err := s.apiClient().ContainerInspect(ctx, container.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,7 @@ func (s *composeService) Pull(ctx context.Context, project *types.Project, opts
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *composeService) pull(ctx context.Context, project *types.Project, opts api.PullOptions) error {
|
func (s *composeService) pull(ctx context.Context, project *types.Project, opts api.PullOptions) error {
|
||||||
info, err := s.apiClient.Info(ctx)
|
info, err := s.apiClient().Info(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -70,7 +70,7 @@ func (s *composeService) pull(ctx context.Context, project *types.Project, opts
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
eg.Go(func() error {
|
eg.Go(func() error {
|
||||||
err := s.pullServiceImage(ctx, service, info, s.configFile, w, false)
|
err := s.pullServiceImage(ctx, service, info, s.configFile(), w, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if !opts.IgnoreFailures {
|
if !opts.IgnoreFailures {
|
||||||
if service.Build != nil {
|
if service.Build != nil {
|
||||||
|
@ -124,7 +124,7 @@ func (s *composeService) pullServiceImage(ctx context.Context, service types.Ser
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
stream, err := s.apiClient.ImagePull(ctx, service.Image, moby.ImagePullOptions{
|
stream, err := s.apiClient().ImagePull(ctx, service.Image, moby.ImagePullOptions{
|
||||||
RegistryAuth: base64.URLEncoding.EncodeToString(buf),
|
RegistryAuth: base64.URLEncoding.EncodeToString(buf),
|
||||||
Platform: service.Platform,
|
Platform: service.Platform,
|
||||||
})
|
})
|
||||||
|
@ -162,7 +162,7 @@ func (s *composeService) pullServiceImage(ctx context.Context, service types.Ser
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *composeService) pullRequiredImages(ctx context.Context, project *types.Project, images map[string]string, quietPull bool) error {
|
func (s *composeService) pullRequiredImages(ctx context.Context, project *types.Project, images map[string]string, quietPull bool) error {
|
||||||
info, err := s.apiClient.Info(ctx)
|
info, err := s.apiClient().Info(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -198,7 +198,7 @@ func (s *composeService) pullRequiredImages(ctx context.Context, project *types.
|
||||||
for _, service := range needPull {
|
for _, service := range needPull {
|
||||||
service := service
|
service := service
|
||||||
eg.Go(func() error {
|
eg.Go(func() error {
|
||||||
err := s.pullServiceImage(ctx, service, info, s.configFile, w, quietPull)
|
err := s.pullServiceImage(ctx, service, info, s.configFile(), w, quietPull)
|
||||||
if err != nil && service.Build != nil {
|
if err != nil && service.Build != nil {
|
||||||
// image can be built, so we can ignore pull failure
|
// image can be built, so we can ignore pull failure
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -45,7 +45,7 @@ func (s *composeService) Push(ctx context.Context, project *types.Project, optio
|
||||||
func (s *composeService) push(ctx context.Context, project *types.Project, options api.PushOptions) error {
|
func (s *composeService) push(ctx context.Context, project *types.Project, options api.PushOptions) error {
|
||||||
eg, ctx := errgroup.WithContext(ctx)
|
eg, ctx := errgroup.WithContext(ctx)
|
||||||
|
|
||||||
info, err := s.apiClient.Info(ctx)
|
info, err := s.apiClient().Info(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -65,7 +65,7 @@ func (s *composeService) push(ctx context.Context, project *types.Project, optio
|
||||||
}
|
}
|
||||||
service := service
|
service := service
|
||||||
eg.Go(func() error {
|
eg.Go(func() error {
|
||||||
err := s.pushServiceImage(ctx, service, info, s.configFile, w)
|
err := s.pushServiceImage(ctx, service, info, s.configFile(), w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if !options.IgnoreFailures {
|
if !options.IgnoreFailures {
|
||||||
return err
|
return err
|
||||||
|
@ -103,7 +103,7 @@ func (s *composeService) pushServiceImage(ctx context.Context, service types.Ser
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
stream, err := s.apiClient.ImagePush(ctx, service.Image, moby.ImagePushOptions{
|
stream, err := s.apiClient().ImagePush(ctx, service.Image, moby.ImagePushOptions{
|
||||||
RegistryAuth: base64.URLEncoding.EncodeToString(buf),
|
RegistryAuth: base64.URLEncoding.EncodeToString(buf),
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -79,7 +79,7 @@ func (s *composeService) remove(ctx context.Context, containers Containers, opti
|
||||||
eg.Go(func() error {
|
eg.Go(func() error {
|
||||||
eventName := getContainerProgressName(container)
|
eventName := getContainerProgressName(container)
|
||||||
w.Event(progress.RemovingEvent(eventName))
|
w.Event(progress.RemovingEvent(eventName))
|
||||||
err := s.apiClient.ContainerRemove(ctx, container.ID, moby.ContainerRemoveOptions{
|
err := s.apiClient().ContainerRemove(ctx, container.ID, moby.ContainerRemoveOptions{
|
||||||
RemoveVolumes: options.Volumes,
|
RemoveVolumes: options.Volumes,
|
||||||
Force: options.Force,
|
Force: options.Force,
|
||||||
})
|
})
|
||||||
|
|
|
@ -59,7 +59,7 @@ func (s *composeService) restart(ctx context.Context, projectName string, option
|
||||||
eg.Go(func() error {
|
eg.Go(func() error {
|
||||||
eventName := getContainerProgressName(container)
|
eventName := getContainerProgressName(container)
|
||||||
w.Event(progress.RestartingEvent(eventName))
|
w.Event(progress.RestartingEvent(eventName))
|
||||||
err := s.apiClient.ContainerRestart(ctx, container.ID, options.Timeout)
|
err := s.apiClient().ContainerRestart(ctx, container.ID, options.Timeout)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
w.Event(progress.StartedEvent(eventName))
|
w.Event(progress.StartedEvent(eventName))
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,6 @@ import (
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/compose-spec/compose-go/types"
|
"github.com/compose-spec/compose-go/types"
|
||||||
"github.com/docker/cli/cli/streams"
|
|
||||||
"github.com/docker/compose/v2/pkg/api"
|
"github.com/docker/compose/v2/pkg/api"
|
||||||
moby "github.com/docker/docker/api/types"
|
moby "github.com/docker/docker/api/types"
|
||||||
"github.com/docker/docker/api/types/container"
|
"github.com/docker/docker/api/types/container"
|
||||||
|
@ -39,11 +38,11 @@ func (s *composeService) RunOneOffContainer(ctx context.Context, project *types.
|
||||||
}
|
}
|
||||||
|
|
||||||
if opts.Detach {
|
if opts.Detach {
|
||||||
err := s.apiClient.ContainerStart(ctx, containerID, moby.ContainerStartOptions{})
|
err := s.apiClient().ContainerStart(ctx, containerID, moby.ContainerStartOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
fmt.Fprintln(opts.Stdout, containerID)
|
fmt.Fprintln(s.stdout(), containerID)
|
||||||
return 0, nil
|
return 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,7 +50,8 @@ func (s *composeService) RunOneOffContainer(ctx context.Context, project *types.
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *composeService) runInteractive(ctx context.Context, containerID string, opts api.RunOptions) (int, error) {
|
func (s *composeService) runInteractive(ctx context.Context, containerID string, opts api.RunOptions) (int, error) {
|
||||||
r, err := s.getEscapeKeyProxy(opts.Stdin, opts.Tty)
|
in := s.stdin()
|
||||||
|
r, err := s.getEscapeKeyProxy(in, opts.Tty)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
@ -61,7 +61,6 @@ func (s *composeService) runInteractive(ctx context.Context, containerID string,
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
in := streams.NewIn(opts.Stdin)
|
|
||||||
if in.IsTerminal() && opts.Tty {
|
if in.IsTerminal() && opts.Tty {
|
||||||
state, err := term.SetRawTerminal(in.FD())
|
state, err := term.SetRawTerminal(in.FD())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -75,10 +74,10 @@ func (s *composeService) runInteractive(ctx context.Context, containerID string,
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
if opts.Tty {
|
if opts.Tty {
|
||||||
_, err := io.Copy(opts.Stdout, stdout) //nolint:errcheck
|
_, err := io.Copy(s.stdout(), stdout) //nolint:errcheck
|
||||||
outputDone <- err
|
outputDone <- err
|
||||||
} else {
|
} else {
|
||||||
_, err := stdcopy.StdCopy(opts.Stdout, opts.Stderr, stdout) //nolint:errcheck
|
_, err := stdcopy.StdCopy(s.stdout(), s.stderr(), stdout) //nolint:errcheck
|
||||||
outputDone <- err
|
outputDone <- err
|
||||||
}
|
}
|
||||||
stdout.Close() //nolint:errcheck
|
stdout.Close() //nolint:errcheck
|
||||||
|
@ -90,12 +89,12 @@ func (s *composeService) runInteractive(ctx context.Context, containerID string,
|
||||||
stdin.Close() //nolint:errcheck
|
stdin.Close() //nolint:errcheck
|
||||||
}()
|
}()
|
||||||
|
|
||||||
err = s.apiClient.ContainerStart(ctx, containerID, moby.ContainerStartOptions{})
|
err = s.apiClient().ContainerStart(ctx, containerID, moby.ContainerStartOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
s.monitorTTySize(ctx, containerID, s.apiClient.ContainerResize)
|
s.monitorTTySize(ctx, containerID, s.apiClient().ContainerResize)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
|
@ -119,7 +118,7 @@ func (s *composeService) runInteractive(ctx context.Context, containerID string,
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *composeService) terminateRun(ctx context.Context, containerID string, opts api.RunOptions) (exitCode int, err error) {
|
func (s *composeService) terminateRun(ctx context.Context, containerID string, opts api.RunOptions) (exitCode int, err error) {
|
||||||
exitCh, errCh := s.apiClient.ContainerWait(ctx, containerID, container.WaitConditionNotRunning)
|
exitCh, errCh := s.apiClient().ContainerWait(ctx, containerID, container.WaitConditionNotRunning)
|
||||||
select {
|
select {
|
||||||
case exit := <-exitCh:
|
case exit := <-exitCh:
|
||||||
exitCode = int(exit.StatusCode)
|
exitCode = int(exit.StatusCode)
|
||||||
|
@ -127,7 +126,7 @@ func (s *composeService) terminateRun(ctx context.Context, containerID string, o
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if opts.AutoRemove {
|
if opts.AutoRemove {
|
||||||
err = s.apiClient.ContainerRemove(ctx, containerID, moby.ContainerRemoveOptions{})
|
err = s.apiClient().ContainerRemove(ctx, containerID, moby.ContainerRemoveOptions{})
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -185,8 +184,8 @@ func (s *composeService) getEscapeKeyProxy(r io.ReadCloser, isTty bool) (io.Read
|
||||||
return r, nil
|
return r, nil
|
||||||
}
|
}
|
||||||
var escapeKeys = []byte{16, 17}
|
var escapeKeys = []byte{16, 17}
|
||||||
if s.configFile.DetachKeys != "" {
|
if s.configFile().DetachKeys != "" {
|
||||||
customEscapeKeys, err := term.ToBytes(s.configFile.DetachKeys)
|
customEscapeKeys, err := term.ToBytes(s.configFile().DetachKeys)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -107,7 +107,7 @@ func (s *composeService) watchContainers(ctx context.Context, projectName string
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
inspected, err := s.apiClient.ContainerInspect(ctx, event.Container)
|
inspected, err := s.apiClient().ContainerInspect(ctx, event.Container)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@ func (s *composeService) Top(ctx context.Context, projectName string, services [
|
||||||
for i, container := range containers {
|
for i, container := range containers {
|
||||||
i, container := i, container
|
i, container := i, container
|
||||||
eg.Go(func() error {
|
eg.Go(func() error {
|
||||||
topContent, err := s.apiClient.ContainerTop(ctx, container.ID, []string{})
|
topContent, err := s.apiClient().ContainerTop(ctx, container.ID, []string{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,301 @@
|
||||||
|
// Code generated by MockGen. DO NOT EDIT.
|
||||||
|
// Source: github.com/docker/cli/cli/command (interfaces: Cli)
|
||||||
|
|
||||||
|
// Package mocks is a generated GoMock package.
|
||||||
|
package mocks
|
||||||
|
|
||||||
|
import (
|
||||||
|
io "io"
|
||||||
|
reflect "reflect"
|
||||||
|
|
||||||
|
command "github.com/docker/cli/cli/command"
|
||||||
|
configfile "github.com/docker/cli/cli/config/configfile"
|
||||||
|
docker "github.com/docker/cli/cli/context/docker"
|
||||||
|
store "github.com/docker/cli/cli/context/store"
|
||||||
|
store0 "github.com/docker/cli/cli/manifest/store"
|
||||||
|
client "github.com/docker/cli/cli/registry/client"
|
||||||
|
streams "github.com/docker/cli/cli/streams"
|
||||||
|
trust "github.com/docker/cli/cli/trust"
|
||||||
|
client0 "github.com/docker/docker/client"
|
||||||
|
gomock "github.com/golang/mock/gomock"
|
||||||
|
client1 "github.com/theupdateframework/notary/client"
|
||||||
|
)
|
||||||
|
|
||||||
|
// MockCli is a mock of Cli interface.
|
||||||
|
type MockCli struct {
|
||||||
|
ctrl *gomock.Controller
|
||||||
|
recorder *MockCliMockRecorder
|
||||||
|
}
|
||||||
|
|
||||||
|
// MockCliMockRecorder is the mock recorder for MockCli.
|
||||||
|
type MockCliMockRecorder struct {
|
||||||
|
mock *MockCli
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewMockCli creates a new mock instance.
|
||||||
|
func NewMockCli(ctrl *gomock.Controller) *MockCli {
|
||||||
|
mock := &MockCli{ctrl: ctrl}
|
||||||
|
mock.recorder = &MockCliMockRecorder{mock}
|
||||||
|
return mock
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||||
|
func (m *MockCli) EXPECT() *MockCliMockRecorder {
|
||||||
|
return m.recorder
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply mocks base method.
|
||||||
|
func (m *MockCli) Apply(arg0 ...command.DockerCliOption) error {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
varargs := []interface{}{}
|
||||||
|
for _, a := range arg0 {
|
||||||
|
varargs = append(varargs, a)
|
||||||
|
}
|
||||||
|
ret := m.ctrl.Call(m, "Apply", varargs...)
|
||||||
|
ret0, _ := ret[0].(error)
|
||||||
|
return ret0
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply indicates an expected call of Apply.
|
||||||
|
func (mr *MockCliMockRecorder) Apply(arg0 ...interface{}) *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Apply", reflect.TypeOf((*MockCli)(nil).Apply), arg0...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Client mocks base method.
|
||||||
|
func (m *MockCli) Client() client0.APIClient {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "Client")
|
||||||
|
ret0, _ := ret[0].(client0.APIClient)
|
||||||
|
return ret0
|
||||||
|
}
|
||||||
|
|
||||||
|
// Client indicates an expected call of Client.
|
||||||
|
func (mr *MockCliMockRecorder) Client() *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Client", reflect.TypeOf((*MockCli)(nil).Client))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClientInfo mocks base method.
|
||||||
|
func (m *MockCli) ClientInfo() command.ClientInfo {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "ClientInfo")
|
||||||
|
ret0, _ := ret[0].(command.ClientInfo)
|
||||||
|
return ret0
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClientInfo indicates an expected call of ClientInfo.
|
||||||
|
func (mr *MockCliMockRecorder) ClientInfo() *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientInfo", reflect.TypeOf((*MockCli)(nil).ClientInfo))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConfigFile mocks base method.
|
||||||
|
func (m *MockCli) ConfigFile() *configfile.ConfigFile {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "ConfigFile")
|
||||||
|
ret0, _ := ret[0].(*configfile.ConfigFile)
|
||||||
|
return ret0
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConfigFile indicates an expected call of ConfigFile.
|
||||||
|
func (mr *MockCliMockRecorder) ConfigFile() *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ConfigFile", reflect.TypeOf((*MockCli)(nil).ConfigFile))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ContentTrustEnabled mocks base method.
|
||||||
|
func (m *MockCli) ContentTrustEnabled() bool {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "ContentTrustEnabled")
|
||||||
|
ret0, _ := ret[0].(bool)
|
||||||
|
return ret0
|
||||||
|
}
|
||||||
|
|
||||||
|
// ContentTrustEnabled indicates an expected call of ContentTrustEnabled.
|
||||||
|
func (mr *MockCliMockRecorder) ContentTrustEnabled() *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ContentTrustEnabled", reflect.TypeOf((*MockCli)(nil).ContentTrustEnabled))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ContextStore mocks base method.
|
||||||
|
func (m *MockCli) ContextStore() store.Store {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "ContextStore")
|
||||||
|
ret0, _ := ret[0].(store.Store)
|
||||||
|
return ret0
|
||||||
|
}
|
||||||
|
|
||||||
|
// ContextStore indicates an expected call of ContextStore.
|
||||||
|
func (mr *MockCliMockRecorder) ContextStore() *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ContextStore", reflect.TypeOf((*MockCli)(nil).ContextStore))
|
||||||
|
}
|
||||||
|
|
||||||
|
// CurrentContext mocks base method.
|
||||||
|
func (m *MockCli) CurrentContext() string {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "CurrentContext")
|
||||||
|
ret0, _ := ret[0].(string)
|
||||||
|
return ret0
|
||||||
|
}
|
||||||
|
|
||||||
|
// CurrentContext indicates an expected call of CurrentContext.
|
||||||
|
func (mr *MockCliMockRecorder) CurrentContext() *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CurrentContext", reflect.TypeOf((*MockCli)(nil).CurrentContext))
|
||||||
|
}
|
||||||
|
|
||||||
|
// DefaultVersion mocks base method.
|
||||||
|
func (m *MockCli) DefaultVersion() string {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "DefaultVersion")
|
||||||
|
ret0, _ := ret[0].(string)
|
||||||
|
return ret0
|
||||||
|
}
|
||||||
|
|
||||||
|
// DefaultVersion indicates an expected call of DefaultVersion.
|
||||||
|
func (mr *MockCliMockRecorder) DefaultVersion() *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DefaultVersion", reflect.TypeOf((*MockCli)(nil).DefaultVersion))
|
||||||
|
}
|
||||||
|
|
||||||
|
// DockerEndpoint mocks base method.
|
||||||
|
func (m *MockCli) DockerEndpoint() docker.Endpoint {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "DockerEndpoint")
|
||||||
|
ret0, _ := ret[0].(docker.Endpoint)
|
||||||
|
return ret0
|
||||||
|
}
|
||||||
|
|
||||||
|
// DockerEndpoint indicates an expected call of DockerEndpoint.
|
||||||
|
func (mr *MockCliMockRecorder) DockerEndpoint() *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DockerEndpoint", reflect.TypeOf((*MockCli)(nil).DockerEndpoint))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Err mocks base method.
|
||||||
|
func (m *MockCli) Err() io.Writer {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "Err")
|
||||||
|
ret0, _ := ret[0].(io.Writer)
|
||||||
|
return ret0
|
||||||
|
}
|
||||||
|
|
||||||
|
// Err indicates an expected call of Err.
|
||||||
|
func (mr *MockCliMockRecorder) Err() *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Err", reflect.TypeOf((*MockCli)(nil).Err))
|
||||||
|
}
|
||||||
|
|
||||||
|
// In mocks base method.
|
||||||
|
func (m *MockCli) In() *streams.In {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "In")
|
||||||
|
ret0, _ := ret[0].(*streams.In)
|
||||||
|
return ret0
|
||||||
|
}
|
||||||
|
|
||||||
|
// In indicates an expected call of In.
|
||||||
|
func (mr *MockCliMockRecorder) In() *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "In", reflect.TypeOf((*MockCli)(nil).In))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ManifestStore mocks base method.
|
||||||
|
func (m *MockCli) ManifestStore() store0.Store {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "ManifestStore")
|
||||||
|
ret0, _ := ret[0].(store0.Store)
|
||||||
|
return ret0
|
||||||
|
}
|
||||||
|
|
||||||
|
// ManifestStore indicates an expected call of ManifestStore.
|
||||||
|
func (mr *MockCliMockRecorder) ManifestStore() *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ManifestStore", reflect.TypeOf((*MockCli)(nil).ManifestStore))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NotaryClient mocks base method.
|
||||||
|
func (m *MockCli) NotaryClient(arg0 trust.ImageRefAndAuth, arg1 []string) (client1.Repository, error) {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "NotaryClient", arg0, arg1)
|
||||||
|
ret0, _ := ret[0].(client1.Repository)
|
||||||
|
ret1, _ := ret[1].(error)
|
||||||
|
return ret0, ret1
|
||||||
|
}
|
||||||
|
|
||||||
|
// NotaryClient indicates an expected call of NotaryClient.
|
||||||
|
func (mr *MockCliMockRecorder) NotaryClient(arg0, arg1 interface{}) *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NotaryClient", reflect.TypeOf((*MockCli)(nil).NotaryClient), arg0, arg1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Out mocks base method.
|
||||||
|
func (m *MockCli) Out() *streams.Out {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "Out")
|
||||||
|
ret0, _ := ret[0].(*streams.Out)
|
||||||
|
return ret0
|
||||||
|
}
|
||||||
|
|
||||||
|
// Out indicates an expected call of Out.
|
||||||
|
func (mr *MockCliMockRecorder) Out() *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Out", reflect.TypeOf((*MockCli)(nil).Out))
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegistryClient mocks base method.
|
||||||
|
func (m *MockCli) RegistryClient(arg0 bool) client.RegistryClient {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "RegistryClient", arg0)
|
||||||
|
ret0, _ := ret[0].(client.RegistryClient)
|
||||||
|
return ret0
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegistryClient indicates an expected call of RegistryClient.
|
||||||
|
func (mr *MockCliMockRecorder) RegistryClient(arg0 interface{}) *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegistryClient", reflect.TypeOf((*MockCli)(nil).RegistryClient), arg0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ServerInfo mocks base method.
|
||||||
|
func (m *MockCli) ServerInfo() command.ServerInfo {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "ServerInfo")
|
||||||
|
ret0, _ := ret[0].(command.ServerInfo)
|
||||||
|
return ret0
|
||||||
|
}
|
||||||
|
|
||||||
|
// ServerInfo indicates an expected call of ServerInfo.
|
||||||
|
func (mr *MockCliMockRecorder) ServerInfo() *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ServerInfo", reflect.TypeOf((*MockCli)(nil).ServerInfo))
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetIn mocks base method.
|
||||||
|
func (m *MockCli) SetIn(arg0 *streams.In) {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
m.ctrl.Call(m, "SetIn", arg0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetIn indicates an expected call of SetIn.
|
||||||
|
func (mr *MockCliMockRecorder) SetIn(arg0 interface{}) *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetIn", reflect.TypeOf((*MockCli)(nil).SetIn), arg0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// StackOrchestrator mocks base method.
|
||||||
|
func (m *MockCli) StackOrchestrator(arg0 string) (command.Orchestrator, error) {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "StackOrchestrator", arg0)
|
||||||
|
ret0, _ := ret[0].(command.Orchestrator)
|
||||||
|
ret1, _ := ret[1].(error)
|
||||||
|
return ret0, ret1
|
||||||
|
}
|
||||||
|
|
||||||
|
// StackOrchestrator indicates an expected call of StackOrchestrator.
|
||||||
|
func (mr *MockCliMockRecorder) StackOrchestrator(arg0 interface{}) *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StackOrchestrator", reflect.TypeOf((*MockCli)(nil).StackOrchestrator), arg0)
|
||||||
|
}
|
Loading…
Reference in New Issue