mirror of https://github.com/docker/cli.git
Switch from pkg/errors to %w part 2
The github.com/pkg/errors is mostly obsoleted since Go 1.13 introduced %w-style error wrapping. It is also not maintained and is now archived by the owner. Let's switch to %s-style error wrapping. Generated by git ls-files *.go | grep -v '^vendor/' | xargs go-wrap-to-percent-w -w using https://github.com/AkihiroSuda/go-wrap-to-percent-w tool. Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
This commit is contained in:
parent
d4600627b8
commit
fa30284bd4
|
@ -4,7 +4,7 @@
|
||||||
package manager
|
package manager
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/pkg/errors"
|
"fmt"
|
||||||
)
|
)
|
||||||
|
|
||||||
// pluginError is set as Plugin.Err by NewPlugin if the plugin
|
// pluginError is set as Plugin.Err by NewPlugin if the plugin
|
||||||
|
@ -44,11 +44,11 @@ func wrapAsPluginError(err error, msg string) error {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return &pluginError{cause: errors.Wrap(err, msg)}
|
return &pluginError{cause: fmt.Errorf(msg+": %w", err)}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewPluginError creates a new pluginError, analogous to
|
// NewPluginError creates a new pluginError, analogous to
|
||||||
// errors.Errorf.
|
// errors.Errorf.
|
||||||
func NewPluginError(msg string, args ...any) error {
|
func NewPluginError(msg string, args ...any) error {
|
||||||
return &pluginError{cause: errors.Errorf(msg, args...)}
|
return &pluginError{cause: fmt.Errorf(msg, args...)}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,13 +3,14 @@ package manager
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -44,14 +45,14 @@ func newPlugin(c Candidate, cmds []*cobra.Command) (Plugin, error) {
|
||||||
// which would fail here, so there are all real errors.
|
// which would fail here, so there are all real errors.
|
||||||
fullname := filepath.Base(path)
|
fullname := filepath.Base(path)
|
||||||
if fullname == "." {
|
if fullname == "." {
|
||||||
return Plugin{}, errors.Errorf("unable to determine basename of plugin candidate %q", path)
|
return Plugin{}, fmt.Errorf("unable to determine basename of plugin candidate %q", path)
|
||||||
}
|
}
|
||||||
var err error
|
var err error
|
||||||
if fullname, err = trimExeSuffix(fullname); err != nil {
|
if fullname, err = trimExeSuffix(fullname); err != nil {
|
||||||
return Plugin{}, errors.Wrapf(err, "plugin candidate %q", path)
|
return Plugin{}, fmt.Errorf("plugin candidate %q: %w", path, err)
|
||||||
}
|
}
|
||||||
if !strings.HasPrefix(fullname, NamePrefix) {
|
if !strings.HasPrefix(fullname, NamePrefix) {
|
||||||
return Plugin{}, errors.Errorf("plugin candidate %q: does not have %q prefix", path, NamePrefix)
|
return Plugin{}, fmt.Errorf("plugin candidate %q: does not have %q prefix", path, NamePrefix)
|
||||||
}
|
}
|
||||||
|
|
||||||
p := Plugin{
|
p := Plugin{
|
||||||
|
|
|
@ -1,22 +1,21 @@
|
||||||
package manager
|
package manager
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// This is made slightly more complex due to needing to be case insensitive.
|
// This is made slightly more complex due to needing to be case insensitive.
|
||||||
func trimExeSuffix(s string) (string, error) {
|
func trimExeSuffix(s string) (string, error) {
|
||||||
ext := filepath.Ext(s)
|
ext := filepath.Ext(s)
|
||||||
if ext == "" {
|
if ext == "" {
|
||||||
return "", errors.Errorf("path %q lacks required file extension", s)
|
return "", fmt.Errorf("path %q lacks required file extension", s)
|
||||||
}
|
}
|
||||||
|
|
||||||
exe := ".exe"
|
exe := ".exe"
|
||||||
if !strings.EqualFold(ext, exe) {
|
if !strings.EqualFold(ext, exe) {
|
||||||
return "", errors.Errorf("path %q lacks required %q suffix", s, exe)
|
return "", fmt.Errorf("path %q lacks required %q suffix", s, exe)
|
||||||
}
|
}
|
||||||
return strings.TrimSuffix(s, ext), nil
|
return strings.TrimSuffix(s, ext), nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ import (
|
||||||
"github.com/fvbommel/sortorder"
|
"github.com/fvbommel/sortorder"
|
||||||
"github.com/moby/term"
|
"github.com/moby/term"
|
||||||
"github.com/morikuni/aec"
|
"github.com/morikuni/aec"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/pflag"
|
"github.com/spf13/pflag"
|
||||||
)
|
)
|
||||||
|
@ -214,7 +214,7 @@ var helpCommand = &cobra.Command{
|
||||||
RunE: func(c *cobra.Command, args []string) error {
|
RunE: func(c *cobra.Command, args []string) error {
|
||||||
cmd, args, e := c.Root().Find(args)
|
cmd, args, e := c.Root().Find(args)
|
||||||
if cmd == nil || e != nil || len(args) > 0 {
|
if cmd == nil || e != nil || len(args) > 0 {
|
||||||
return errors.Errorf("unknown help topic: %v", strings.Join(args, " "))
|
return fmt.Errorf("unknown help topic: %v", strings.Join(args, " "))
|
||||||
}
|
}
|
||||||
helpFunc := cmd.HelpFunc()
|
helpFunc := cmd.HelpFunc()
|
||||||
helpFunc(cmd, args)
|
helpFunc(cmd, args)
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
package checkpoint
|
package checkpoint
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/docker/cli/internal/test"
|
"github.com/docker/cli/internal/test"
|
||||||
"github.com/docker/docker/api/types/checkpoint"
|
"github.com/docker/docker/api/types/checkpoint"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"gotest.tools/v3/assert"
|
"gotest.tools/v3/assert"
|
||||||
is "gotest.tools/v3/assert/cmp"
|
is "gotest.tools/v3/assert/cmp"
|
||||||
)
|
)
|
||||||
|
@ -29,7 +30,7 @@ func TestCheckpointCreateErrors(t *testing.T) {
|
||||||
{
|
{
|
||||||
args: []string{"foo", "bar"},
|
args: []string{"foo", "bar"},
|
||||||
checkpointCreateFunc: func(container string, options checkpoint.CreateOptions) error {
|
checkpointCreateFunc: func(container string, options checkpoint.CreateOptions) error {
|
||||||
return errors.Errorf("error creating checkpoint for container foo")
|
return fmt.Errorf("error creating checkpoint for container foo")
|
||||||
},
|
},
|
||||||
expectedError: "error creating checkpoint for container foo",
|
expectedError: "error creating checkpoint for container foo",
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
package checkpoint
|
package checkpoint
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/docker/cli/internal/test"
|
"github.com/docker/cli/internal/test"
|
||||||
"github.com/docker/docker/api/types/checkpoint"
|
"github.com/docker/docker/api/types/checkpoint"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"gotest.tools/v3/assert"
|
"gotest.tools/v3/assert"
|
||||||
is "gotest.tools/v3/assert/cmp"
|
is "gotest.tools/v3/assert/cmp"
|
||||||
"gotest.tools/v3/golden"
|
"gotest.tools/v3/golden"
|
||||||
|
@ -29,7 +30,7 @@ func TestCheckpointListErrors(t *testing.T) {
|
||||||
{
|
{
|
||||||
args: []string{"foo"},
|
args: []string{"foo"},
|
||||||
checkpointListFunc: func(container string, options checkpoint.ListOptions) ([]checkpoint.Summary, error) {
|
checkpointListFunc: func(container string, options checkpoint.ListOptions) ([]checkpoint.Summary, error) {
|
||||||
return []checkpoint.Summary{}, errors.Errorf("error getting checkpoints for container foo")
|
return []checkpoint.Summary{}, fmt.Errorf("error getting checkpoints for container foo")
|
||||||
},
|
},
|
||||||
expectedError: "error getting checkpoints for container foo",
|
expectedError: "error getting checkpoints for container foo",
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
package checkpoint
|
package checkpoint
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/docker/cli/internal/test"
|
"github.com/docker/cli/internal/test"
|
||||||
"github.com/docker/docker/api/types/checkpoint"
|
"github.com/docker/docker/api/types/checkpoint"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"gotest.tools/v3/assert"
|
"gotest.tools/v3/assert"
|
||||||
is "gotest.tools/v3/assert/cmp"
|
is "gotest.tools/v3/assert/cmp"
|
||||||
)
|
)
|
||||||
|
@ -28,7 +29,7 @@ func TestCheckpointRemoveErrors(t *testing.T) {
|
||||||
{
|
{
|
||||||
args: []string{"foo", "bar"},
|
args: []string{"foo", "bar"},
|
||||||
checkpointDeleteFunc: func(container string, options checkpoint.DeleteOptions) error {
|
checkpointDeleteFunc: func(container string, options checkpoint.DeleteOptions) error {
|
||||||
return errors.Errorf("error deleting checkpoint")
|
return fmt.Errorf("error deleting checkpoint")
|
||||||
},
|
},
|
||||||
expectedError: "error deleting checkpoint",
|
expectedError: "error deleting checkpoint",
|
||||||
},
|
},
|
||||||
|
|
|
@ -5,6 +5,7 @@ package command
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
@ -33,7 +34,7 @@ import (
|
||||||
"github.com/docker/docker/api/types/swarm"
|
"github.com/docker/docker/api/types/swarm"
|
||||||
"github.com/docker/docker/client"
|
"github.com/docker/docker/client"
|
||||||
"github.com/docker/go-connections/tlsconfig"
|
"github.com/docker/go-connections/tlsconfig"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
notaryclient "github.com/theupdateframework/notary/client"
|
notaryclient "github.com/theupdateframework/notary/client"
|
||||||
)
|
)
|
||||||
|
@ -177,7 +178,7 @@ func (cli *DockerCli) BuildKitEnabled() (bool, error) {
|
||||||
if v := os.Getenv("DOCKER_BUILDKIT"); v != "" {
|
if v := os.Getenv("DOCKER_BUILDKIT"); v != "" {
|
||||||
enabled, err := strconv.ParseBool(v)
|
enabled, err := strconv.ParseBool(v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, errors.Wrap(err, "DOCKER_BUILDKIT environment variable expects boolean value")
|
return false, fmt.Errorf("DOCKER_BUILDKIT environment variable expects boolean value: %w", err)
|
||||||
}
|
}
|
||||||
return enabled, nil
|
return enabled, nil
|
||||||
}
|
}
|
||||||
|
@ -311,7 +312,7 @@ func NewAPIClientFromFlags(opts *cliflags.ClientOptions, configFile *configfile.
|
||||||
}
|
}
|
||||||
endpoint, err := resolveDockerEndpoint(contextStore, resolveContextName(opts, configFile))
|
endpoint, err := resolveDockerEndpoint(contextStore, resolveContextName(opts, configFile))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "unable to resolve docker endpoint")
|
return nil, fmt.Errorf("unable to resolve docker endpoint: %w", err)
|
||||||
}
|
}
|
||||||
return newAPIClientFromEndpoint(endpoint, configFile)
|
return newAPIClientFromEndpoint(endpoint, configFile)
|
||||||
}
|
}
|
||||||
|
@ -492,7 +493,7 @@ func (cli *DockerCli) initialize() error {
|
||||||
cli.init.Do(func() {
|
cli.init.Do(func() {
|
||||||
cli.dockerEndpoint, cli.initErr = cli.getDockerEndPoint()
|
cli.dockerEndpoint, cli.initErr = cli.getDockerEndPoint()
|
||||||
if cli.initErr != nil {
|
if cli.initErr != nil {
|
||||||
cli.initErr = errors.Wrap(cli.initErr, "unable to resolve docker endpoint")
|
cli.initErr = fmt.Errorf("unable to resolve docker endpoint: %w", cli.initErr)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if cli.client == nil {
|
if cli.client == nil {
|
||||||
|
|
|
@ -3,6 +3,7 @@ package command
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/csv"
|
"encoding/csv"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
@ -13,7 +14,6 @@ import (
|
||||||
"github.com/docker/docker/client"
|
"github.com/docker/docker/client"
|
||||||
"github.com/docker/docker/errdefs"
|
"github.com/docker/docker/errdefs"
|
||||||
"github.com/moby/term"
|
"github.com/moby/term"
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// CLIOption is a functional argument to apply options to a [DockerCli]. These
|
// CLIOption is a functional argument to apply options to a [DockerCli]. These
|
||||||
|
@ -177,7 +177,7 @@ func withCustomHeadersFromEnv() client.Opt {
|
||||||
csvReader := csv.NewReader(strings.NewReader(value))
|
csvReader := csv.NewReader(strings.NewReader(value))
|
||||||
fields, err := csvReader.Read()
|
fields, err := csvReader.Read()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errdefs.InvalidParameter(errors.Errorf("failed to parse custom headers from %s environment variable: value must be formatted as comma-separated key=value pairs", envOverrideHTTPHeaders))
|
return errdefs.InvalidParameter(fmt.Errorf("failed to parse custom headers from %s environment variable: value must be formatted as comma-separated key=value pairs", envOverrideHTTPHeaders))
|
||||||
}
|
}
|
||||||
if len(fields) == 0 {
|
if len(fields) == 0 {
|
||||||
return nil
|
return nil
|
||||||
|
@ -191,7 +191,7 @@ func withCustomHeadersFromEnv() client.Opt {
|
||||||
k = strings.TrimSpace(k)
|
k = strings.TrimSpace(k)
|
||||||
|
|
||||||
if k == "" {
|
if k == "" {
|
||||||
return errdefs.InvalidParameter(errors.Errorf(`failed to set custom headers from %s environment variable: value contains a key=value pair with an empty key: '%s'`, envOverrideHTTPHeaders, kv))
|
return errdefs.InvalidParameter(fmt.Errorf(`failed to set custom headers from %s environment variable: value contains a key=value pair with an empty key: '%s'`, envOverrideHTTPHeaders, kv))
|
||||||
}
|
}
|
||||||
|
|
||||||
// We don't currently allow empty key=value pairs, and produce an error.
|
// We don't currently allow empty key=value pairs, and produce an error.
|
||||||
|
@ -199,7 +199,7 @@ func withCustomHeadersFromEnv() client.Opt {
|
||||||
// from an environment variable with the same name). In the meantime,
|
// from an environment variable with the same name). In the meantime,
|
||||||
// produce an error to prevent users from depending on this.
|
// produce an error to prevent users from depending on this.
|
||||||
if !hasValue {
|
if !hasValue {
|
||||||
return errdefs.InvalidParameter(errors.Errorf(`failed to set custom headers from %s environment variable: missing "=" in key=value pair: '%s'`, envOverrideHTTPHeaders, kv))
|
return errdefs.InvalidParameter(fmt.Errorf(`failed to set custom headers from %s environment variable: missing "=" in key=value pair: '%s'`, envOverrideHTTPHeaders, kv))
|
||||||
}
|
}
|
||||||
|
|
||||||
env[http.CanonicalHeaderKey(k)] = v
|
env[http.CanonicalHeaderKey(k)] = v
|
||||||
|
|
|
@ -3,6 +3,7 @@ package command
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
|
@ -22,7 +23,7 @@ import (
|
||||||
"github.com/docker/docker/api"
|
"github.com/docker/docker/api"
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
"github.com/docker/docker/client"
|
"github.com/docker/docker/client"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"gotest.tools/v3/assert"
|
"gotest.tools/v3/assert"
|
||||||
"gotest.tools/v3/fs"
|
"gotest.tools/v3/fs"
|
||||||
)
|
)
|
||||||
|
|
|
@ -11,7 +11,7 @@ import (
|
||||||
"github.com/docker/cli/opts"
|
"github.com/docker/cli/opts"
|
||||||
"github.com/docker/docker/api/types/swarm"
|
"github.com/docker/docker/api/types/swarm"
|
||||||
"github.com/moby/sys/sequential"
|
"github.com/moby/sys/sequential"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ func RunConfigCreate(ctx context.Context, dockerCli command.Cli, options CreateO
|
||||||
|
|
||||||
configData, err := io.ReadAll(in)
|
configData, err := io.ReadAll(in)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Errorf("Error reading content from %q: %v", options.File, err)
|
return fmt.Errorf("Error reading content from %q: %v", options.File, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
spec := swarm.ConfigSpec{
|
spec := swarm.ConfigSpec{
|
||||||
|
|
|
@ -2,6 +2,7 @@ package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
@ -12,7 +13,7 @@ import (
|
||||||
"github.com/docker/cli/internal/test"
|
"github.com/docker/cli/internal/test"
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
"github.com/docker/docker/api/types/swarm"
|
"github.com/docker/docker/api/types/swarm"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"gotest.tools/v3/assert"
|
"gotest.tools/v3/assert"
|
||||||
is "gotest.tools/v3/assert/cmp"
|
is "gotest.tools/v3/assert/cmp"
|
||||||
"gotest.tools/v3/golden"
|
"gotest.tools/v3/golden"
|
||||||
|
@ -37,7 +38,7 @@ func TestConfigCreateErrors(t *testing.T) {
|
||||||
{
|
{
|
||||||
args: []string{"name", filepath.Join("testdata", configDataFile)},
|
args: []string{"name", filepath.Join("testdata", configDataFile)},
|
||||||
configCreateFunc: func(_ context.Context, configSpec swarm.ConfigSpec) (types.ConfigCreateResponse, error) {
|
configCreateFunc: func(_ context.Context, configSpec swarm.ConfigSpec) (types.ConfigCreateResponse, error) {
|
||||||
return types.ConfigCreateResponse{}, errors.Errorf("error creating config")
|
return types.ConfigCreateResponse{}, fmt.Errorf("error creating config")
|
||||||
},
|
},
|
||||||
expectedError: "error creating config",
|
expectedError: "error creating config",
|
||||||
},
|
},
|
||||||
|
@ -64,7 +65,7 @@ func TestConfigCreateWithName(t *testing.T) {
|
||||||
cli := test.NewFakeCli(&fakeClient{
|
cli := test.NewFakeCli(&fakeClient{
|
||||||
configCreateFunc: func(_ context.Context, spec swarm.ConfigSpec) (types.ConfigCreateResponse, error) {
|
configCreateFunc: func(_ context.Context, spec swarm.ConfigSpec) (types.ConfigCreateResponse, error) {
|
||||||
if spec.Name != name {
|
if spec.Name != name {
|
||||||
return types.ConfigCreateResponse{}, errors.Errorf("expected name %q, got %q", name, spec.Name)
|
return types.ConfigCreateResponse{}, fmt.Errorf("expected name %q, got %q", name, spec.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
actual = spec.Data
|
actual = spec.Data
|
||||||
|
@ -103,7 +104,7 @@ func TestConfigCreateWithLabels(t *testing.T) {
|
||||||
cli := test.NewFakeCli(&fakeClient{
|
cli := test.NewFakeCli(&fakeClient{
|
||||||
configCreateFunc: func(_ context.Context, spec swarm.ConfigSpec) (types.ConfigCreateResponse, error) {
|
configCreateFunc: func(_ context.Context, spec swarm.ConfigSpec) (types.ConfigCreateResponse, error) {
|
||||||
if !reflect.DeepEqual(spec, expected) {
|
if !reflect.DeepEqual(spec, expected) {
|
||||||
return types.ConfigCreateResponse{}, errors.Errorf("expected %+v, got %+v", expected, spec)
|
return types.ConfigCreateResponse{}, fmt.Errorf("expected %+v, got %+v", expected, spec)
|
||||||
}
|
}
|
||||||
|
|
||||||
return types.ConfigCreateResponse{
|
return types.ConfigCreateResponse{
|
||||||
|
@ -129,11 +130,11 @@ func TestConfigCreateWithTemplatingDriver(t *testing.T) {
|
||||||
cli := test.NewFakeCli(&fakeClient{
|
cli := test.NewFakeCli(&fakeClient{
|
||||||
configCreateFunc: func(_ context.Context, spec swarm.ConfigSpec) (types.ConfigCreateResponse, error) {
|
configCreateFunc: func(_ context.Context, spec swarm.ConfigSpec) (types.ConfigCreateResponse, error) {
|
||||||
if spec.Name != name {
|
if spec.Name != name {
|
||||||
return types.ConfigCreateResponse{}, errors.Errorf("expected name %q, got %q", name, spec.Name)
|
return types.ConfigCreateResponse{}, fmt.Errorf("expected name %q, got %q", name, spec.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if spec.Templating.Name != expectedDriver.Name {
|
if spec.Templating.Name != expectedDriver.Name {
|
||||||
return types.ConfigCreateResponse{}, errors.Errorf("expected driver %v, got %v", expectedDriver, spec.Labels)
|
return types.ConfigCreateResponse{}, fmt.Errorf("expected driver %v, got %v", expectedDriver, spec.Labels)
|
||||||
}
|
}
|
||||||
|
|
||||||
return types.ConfigCreateResponse{
|
return types.ConfigCreateResponse{
|
||||||
|
|
|
@ -10,7 +10,7 @@ import (
|
||||||
"github.com/docker/cli/internal/test"
|
"github.com/docker/cli/internal/test"
|
||||||
"github.com/docker/cli/internal/test/builders"
|
"github.com/docker/cli/internal/test/builders"
|
||||||
"github.com/docker/docker/api/types/swarm"
|
"github.com/docker/docker/api/types/swarm"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"gotest.tools/v3/assert"
|
"gotest.tools/v3/assert"
|
||||||
"gotest.tools/v3/golden"
|
"gotest.tools/v3/golden"
|
||||||
)
|
)
|
||||||
|
@ -28,7 +28,7 @@ func TestConfigInspectErrors(t *testing.T) {
|
||||||
{
|
{
|
||||||
args: []string{"foo"},
|
args: []string{"foo"},
|
||||||
configInspectFunc: func(_ context.Context, configID string) (swarm.Config, []byte, error) {
|
configInspectFunc: func(_ context.Context, configID string) (swarm.Config, []byte, error) {
|
||||||
return swarm.Config{}, nil, errors.Errorf("error while inspecting the config")
|
return swarm.Config{}, nil, fmt.Errorf("error while inspecting the config")
|
||||||
},
|
},
|
||||||
expectedError: "error while inspecting the config",
|
expectedError: "error while inspecting the config",
|
||||||
},
|
},
|
||||||
|
@ -45,7 +45,7 @@ func TestConfigInspectErrors(t *testing.T) {
|
||||||
if configID == "foo" {
|
if configID == "foo" {
|
||||||
return *builders.Config(builders.ConfigName("foo")), nil, nil
|
return *builders.Config(builders.ConfigName("foo")), nil, nil
|
||||||
}
|
}
|
||||||
return swarm.Config{}, nil, errors.Errorf("error while inspecting the config")
|
return swarm.Config{}, nil, fmt.Errorf("error while inspecting the config")
|
||||||
},
|
},
|
||||||
expectedError: "error while inspecting the config",
|
expectedError: "error while inspecting the config",
|
||||||
},
|
},
|
||||||
|
@ -77,7 +77,7 @@ func TestConfigInspectWithoutFormat(t *testing.T) {
|
||||||
args: []string{"foo"},
|
args: []string{"foo"},
|
||||||
configInspectFunc: func(_ context.Context, name string) (swarm.Config, []byte, error) {
|
configInspectFunc: func(_ context.Context, name string) (swarm.Config, []byte, error) {
|
||||||
if name != "foo" {
|
if name != "foo" {
|
||||||
return swarm.Config{}, nil, errors.Errorf("Invalid name, expected %s, got %s", "foo", name)
|
return swarm.Config{}, nil, fmt.Errorf("Invalid name, expected %s, got %s", "foo", name)
|
||||||
}
|
}
|
||||||
return *builders.Config(builders.ConfigID("ID-foo"), builders.ConfigName("foo")), nil, nil
|
return *builders.Config(builders.ConfigID("ID-foo"), builders.ConfigName("foo")), nil, nil
|
||||||
},
|
},
|
||||||
|
|
|
@ -2,6 +2,7 @@ package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
@ -11,7 +12,7 @@ import (
|
||||||
"github.com/docker/cli/internal/test/builders"
|
"github.com/docker/cli/internal/test/builders"
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
"github.com/docker/docker/api/types/swarm"
|
"github.com/docker/docker/api/types/swarm"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"gotest.tools/v3/assert"
|
"gotest.tools/v3/assert"
|
||||||
is "gotest.tools/v3/assert/cmp"
|
is "gotest.tools/v3/assert/cmp"
|
||||||
"gotest.tools/v3/golden"
|
"gotest.tools/v3/golden"
|
||||||
|
@ -29,7 +30,7 @@ func TestConfigListErrors(t *testing.T) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
configListFunc: func(_ context.Context, options types.ConfigListOptions) ([]swarm.Config, error) {
|
configListFunc: func(_ context.Context, options types.ConfigListOptions) ([]swarm.Config, error) {
|
||||||
return []swarm.Config{}, errors.Errorf("error listing configs")
|
return []swarm.Config{}, fmt.Errorf("error listing configs")
|
||||||
},
|
},
|
||||||
expectedError: "error listing configs",
|
expectedError: "error listing configs",
|
||||||
},
|
},
|
||||||
|
|
|
@ -7,7 +7,7 @@ import (
|
||||||
|
|
||||||
"github.com/docker/cli/cli"
|
"github.com/docker/cli/cli"
|
||||||
"github.com/docker/cli/cli/command"
|
"github.com/docker/cli/cli/command"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ func RunConfigRemove(ctx context.Context, dockerCli command.Cli, opts RemoveOpti
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(errs) > 0 {
|
if len(errs) > 0 {
|
||||||
return errors.Errorf("%s", strings.Join(errs, "\n"))
|
return fmt.Errorf("%s", strings.Join(errs, "\n"))
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/docker/cli/internal/test"
|
"github.com/docker/cli/internal/test"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"gotest.tools/v3/assert"
|
"gotest.tools/v3/assert"
|
||||||
is "gotest.tools/v3/assert/cmp"
|
is "gotest.tools/v3/assert/cmp"
|
||||||
)
|
)
|
||||||
|
@ -24,7 +25,7 @@ func TestConfigRemoveErrors(t *testing.T) {
|
||||||
{
|
{
|
||||||
args: []string{"foo"},
|
args: []string{"foo"},
|
||||||
configRemoveFunc: func(name string) error {
|
configRemoveFunc: func(name string) error {
|
||||||
return errors.Errorf("error removing config")
|
return fmt.Errorf("error removing config")
|
||||||
},
|
},
|
||||||
expectedError: "error removing config",
|
expectedError: "error removing config",
|
||||||
},
|
},
|
||||||
|
@ -66,7 +67,7 @@ func TestConfigRemoveContinueAfterError(t *testing.T) {
|
||||||
configRemoveFunc: func(name string) error {
|
configRemoveFunc: func(name string) error {
|
||||||
removedConfigs = append(removedConfigs, name)
|
removedConfigs = append(removedConfigs, name)
|
||||||
if name == "foo" {
|
if name == "foo" {
|
||||||
return errors.Errorf("error removing config: %s", name)
|
return fmt.Errorf("error removing config: %s", name)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
|
|
|
@ -2,6 +2,7 @@ package container
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/docker/cli/cli"
|
"github.com/docker/cli/cli"
|
||||||
|
@ -10,7 +11,7 @@ import (
|
||||||
"github.com/docker/docker/api/types/container"
|
"github.com/docker/docker/api/types/container"
|
||||||
"github.com/docker/docker/client"
|
"github.com/docker/docker/client"
|
||||||
"github.com/moby/sys/signal"
|
"github.com/moby/sys/signal"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,13 +1,15 @@
|
||||||
package container
|
package container
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/docker/cli/cli"
|
"github.com/docker/cli/cli"
|
||||||
"github.com/docker/cli/internal/test"
|
"github.com/docker/cli/internal/test"
|
||||||
"github.com/docker/docker/api/types/container"
|
"github.com/docker/docker/api/types/container"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"gotest.tools/v3/assert"
|
"gotest.tools/v3/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -23,7 +25,7 @@ func TestNewAttachCommandErrors(t *testing.T) {
|
||||||
args: []string{"5cb5bb5e4a3b"},
|
args: []string{"5cb5bb5e4a3b"},
|
||||||
expectedError: "something went wrong",
|
expectedError: "something went wrong",
|
||||||
containerInspectFunc: func(containerID string) (container.InspectResponse, error) {
|
containerInspectFunc: func(containerID string) (container.InspectResponse, error) {
|
||||||
return container.InspectResponse{}, errors.Errorf("something went wrong")
|
return container.InspectResponse{}, fmt.Errorf("something went wrong")
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,13 +2,14 @@ package container
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/docker/cli/internal/test"
|
"github.com/docker/cli/internal/test"
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
"github.com/docker/docker/api/types/container"
|
"github.com/docker/docker/api/types/container"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"gotest.tools/v3/assert"
|
"gotest.tools/v3/assert"
|
||||||
is "gotest.tools/v3/assert/cmp"
|
is "gotest.tools/v3/assert/cmp"
|
||||||
)
|
)
|
||||||
|
|
|
@ -3,6 +3,7 @@ package container
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
@ -20,7 +21,7 @@ import (
|
||||||
"github.com/docker/docker/pkg/system"
|
"github.com/docker/docker/pkg/system"
|
||||||
units "github.com/docker/go-units"
|
units "github.com/docker/go-units"
|
||||||
"github.com/morikuni/aec"
|
"github.com/morikuni/aec"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -331,7 +332,7 @@ func copyToContainer(ctx context.Context, dockerCli command.Cli, copyConfig cpCo
|
||||||
|
|
||||||
// Validate the destination path
|
// Validate the destination path
|
||||||
if err := command.ValidateOutputPathFileMode(dstStat.Mode); err != nil {
|
if err := command.ValidateOutputPathFileMode(dstStat.Mode); err != nil {
|
||||||
return errors.Wrapf(err, `destination "%s:%s" must be a directory or a regular file`, copyConfig.container, dstPath)
|
return fmt.Errorf("destination \"%s:%s\" must be a directory or a regular file: %w", copyConfig.container, dstPath, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ignore any error and assume that the parent directory of the destination
|
// Ignore any error and assume that the parent directory of the destination
|
||||||
|
@ -354,7 +355,7 @@ func copyToContainer(ctx context.Context, dockerCli command.Cli, copyConfig cpCo
|
||||||
content = os.Stdin
|
content = os.Stdin
|
||||||
resolvedDstPath = dstInfo.Path
|
resolvedDstPath = dstInfo.Path
|
||||||
if !dstInfo.IsDir {
|
if !dstInfo.IsDir {
|
||||||
return errors.Errorf("destination \"%s:%s\" must be a directory", copyConfig.container, dstPath)
|
return fmt.Errorf("destination \"%s:%s\" must be a directory", copyConfig.container, dstPath)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Prepare source copy info.
|
// Prepare source copy info.
|
||||||
|
|
|
@ -21,7 +21,7 @@ import (
|
||||||
"github.com/docker/docker/errdefs"
|
"github.com/docker/docker/errdefs"
|
||||||
"github.com/docker/docker/pkg/jsonmessage"
|
"github.com/docker/docker/pkg/jsonmessage"
|
||||||
specs "github.com/opencontainers/image-spec/specs-go/v1"
|
specs "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/pflag"
|
"github.com/spf13/pflag"
|
||||||
)
|
)
|
||||||
|
@ -168,7 +168,7 @@ func (cid *cidFile) Close() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if err := os.Remove(cid.path); err != nil {
|
if err := os.Remove(cid.path); err != nil {
|
||||||
return errors.Wrapf(err, "failed to remove the CID file '%s'", cid.path)
|
return fmt.Errorf("failed to remove the CID file '%s': %w", cid.path, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -179,7 +179,7 @@ func (cid *cidFile) Write(id string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if _, err := cid.file.Write([]byte(id)); err != nil {
|
if _, err := cid.file.Write([]byte(id)); err != nil {
|
||||||
return errors.Wrap(err, "failed to write the container ID to the file")
|
return fmt.Errorf("failed to write the container ID to the file: %w", err)
|
||||||
}
|
}
|
||||||
cid.written = true
|
cid.written = true
|
||||||
return nil
|
return nil
|
||||||
|
@ -190,12 +190,12 @@ func newCIDFile(path string) (*cidFile, error) {
|
||||||
return &cidFile{}, nil
|
return &cidFile{}, nil
|
||||||
}
|
}
|
||||||
if _, err := os.Stat(path); err == nil {
|
if _, err := os.Stat(path); err == nil {
|
||||||
return nil, errors.Errorf("container ID file found, make sure the other container isn't running or delete %s", path)
|
return nil, fmt.Errorf("container ID file found, make sure the other container isn't running or delete %s", path)
|
||||||
}
|
}
|
||||||
|
|
||||||
f, err := os.Create(path)
|
f, err := os.Create(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "failed to create the container ID file")
|
return nil, fmt.Errorf("failed to create the container ID file: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &cidFile{path: path, file: f}, nil
|
return &cidFile{path: path, file: f}, nil
|
||||||
|
@ -256,7 +256,7 @@ func createContainer(ctx context.Context, dockerCli command.Cli, containerCfg *c
|
||||||
if options.platform != "" && versions.GreaterThanOrEqualTo(dockerCli.Client().ClientVersion(), "1.41") {
|
if options.platform != "" && versions.GreaterThanOrEqualTo(dockerCli.Client().ClientVersion(), "1.41") {
|
||||||
p, err := platforms.Parse(options.platform)
|
p, err := platforms.Parse(options.platform)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", errors.Wrap(errdefs.InvalidParameter(err), "error parsing specified platform")
|
return "", fmt.Errorf("error parsing specified platform: %w", errdefs.InvalidParameter(err))
|
||||||
}
|
}
|
||||||
platform = &p
|
platform = &p
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,12 +2,13 @@ package container
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
|
|
||||||
"github.com/docker/cli/cli"
|
"github.com/docker/cli/cli"
|
||||||
"github.com/docker/cli/cli/command"
|
"github.com/docker/cli/cli/command"
|
||||||
"github.com/docker/cli/cli/command/completion"
|
"github.com/docker/cli/cli/command/completion"
|
||||||
"github.com/docker/cli/cli/command/formatter"
|
"github.com/docker/cli/cli/command/formatter"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -2,13 +2,14 @@ package container
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/docker/cli/internal/test"
|
"github.com/docker/cli/internal/test"
|
||||||
"github.com/docker/docker/api/types/container"
|
"github.com/docker/docker/api/types/container"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"gotest.tools/v3/assert"
|
"gotest.tools/v3/assert"
|
||||||
is "gotest.tools/v3/assert/cmp"
|
is "gotest.tools/v3/assert/cmp"
|
||||||
)
|
)
|
||||||
|
|
|
@ -2,6 +2,7 @@ package container
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
|
@ -12,7 +13,7 @@ import (
|
||||||
"github.com/docker/cli/opts"
|
"github.com/docker/cli/opts"
|
||||||
"github.com/docker/docker/api/types/container"
|
"github.com/docker/docker/api/types/container"
|
||||||
"github.com/docker/docker/client"
|
"github.com/docker/docker/client"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
|
@ -2,6 +2,8 @@ package container
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
@ -12,7 +14,7 @@ import (
|
||||||
"github.com/docker/cli/opts"
|
"github.com/docker/cli/opts"
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
"github.com/docker/docker/api/types/container"
|
"github.com/docker/docker/api/types/container"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"gotest.tools/v3/assert"
|
"gotest.tools/v3/assert"
|
||||||
is "gotest.tools/v3/assert/cmp"
|
is "gotest.tools/v3/assert/cmp"
|
||||||
"gotest.tools/v3/fs"
|
"gotest.tools/v3/fs"
|
||||||
|
@ -259,7 +261,7 @@ func TestNewExecCommandErrors(t *testing.T) {
|
||||||
args: []string{"5cb5bb5e4a3b", "-t", "-i", "bash"},
|
args: []string{"5cb5bb5e4a3b", "-t", "-i", "bash"},
|
||||||
expectedError: "something went wrong",
|
expectedError: "something went wrong",
|
||||||
containerInspectFunc: func(containerID string) (container.InspectResponse, error) {
|
containerInspectFunc: func(containerID string) (container.InspectResponse, error) {
|
||||||
return container.InspectResponse{}, errors.Errorf("something went wrong")
|
return container.InspectResponse{}, fmt.Errorf("something went wrong")
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,12 +2,14 @@ package container
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/docker/cli/cli"
|
"github.com/docker/cli/cli"
|
||||||
"github.com/docker/cli/cli/command"
|
"github.com/docker/cli/cli/command"
|
||||||
"github.com/docker/cli/cli/command/completion"
|
"github.com/docker/cli/cli/command/completion"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -47,7 +49,7 @@ func runExport(ctx context.Context, dockerCli command.Cli, opts exportOptions) e
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := command.ValidateOutputPath(opts.output); err != nil {
|
if err := command.ValidateOutputPath(opts.output); err != nil {
|
||||||
return errors.Wrap(err, "failed to export container")
|
return fmt.Errorf("failed to export container: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
clnt := dockerCli.Client()
|
clnt := dockerCli.Client()
|
||||||
|
|
|
@ -2,13 +2,14 @@ package container
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/docker/cli/cli"
|
"github.com/docker/cli/cli"
|
||||||
"github.com/docker/cli/cli/command"
|
"github.com/docker/cli/cli/command"
|
||||||
"github.com/docker/cli/cli/command/completion"
|
"github.com/docker/cli/cli/command/completion"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ package container
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/docker/cli/cli"
|
"github.com/docker/cli/cli"
|
||||||
|
@ -12,7 +13,7 @@ import (
|
||||||
"github.com/docker/cli/opts"
|
"github.com/docker/cli/opts"
|
||||||
"github.com/docker/cli/templates"
|
"github.com/docker/cli/templates"
|
||||||
"github.com/docker/docker/api/types/container"
|
"github.com/docker/docker/api/types/container"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -84,7 +85,7 @@ func buildContainerListOptions(options *psOptions) (*container.ListOptions, erro
|
||||||
if len(options.format) > 0 {
|
if len(options.format) > 0 {
|
||||||
tmpl, err := templates.NewParse("", options.format)
|
tmpl, err := templates.NewParse("", options.format)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "failed to parse template")
|
return nil, fmt.Errorf("failed to parse template: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
optionsProcessor := formatter.NewContainerContext()
|
optionsProcessor := formatter.NewContainerContext()
|
||||||
|
@ -92,7 +93,7 @@ func buildContainerListOptions(options *psOptions) (*container.ListOptions, erro
|
||||||
// This shouldn't error out but swallowing the error makes it harder
|
// This shouldn't error out but swallowing the error makes it harder
|
||||||
// to track down if preProcessor issues come up.
|
// to track down if preProcessor issues come up.
|
||||||
if err := tmpl.Execute(io.Discard, optionsProcessor); err != nil {
|
if err := tmpl.Execute(io.Discard, optionsProcessor); err != nil {
|
||||||
return nil, errors.Wrap(err, "failed to execute template")
|
return nil, fmt.Errorf("failed to execute template: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// if `size` was not explicitly set to false (with `--size=false`)
|
// if `size` was not explicitly set to false (with `--size=false`)
|
||||||
|
|
|
@ -3,6 +3,7 @@ package container
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
|
@ -22,7 +23,7 @@ import (
|
||||||
"github.com/docker/docker/api/types/strslice"
|
"github.com/docker/docker/api/types/strslice"
|
||||||
"github.com/docker/docker/errdefs"
|
"github.com/docker/docker/errdefs"
|
||||||
"github.com/docker/go-connections/nat"
|
"github.com/docker/go-connections/nat"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/spf13/pflag"
|
"github.com/spf13/pflag"
|
||||||
cdi "tags.cncf.io/container-device-interface/pkg/parser"
|
cdi "tags.cncf.io/container-device-interface/pkg/parser"
|
||||||
|
@ -345,7 +346,7 @@ func parse(flags *pflag.FlagSet, copts *containerOptions, serverOS string) (*con
|
||||||
// Validate the input mac address
|
// Validate the input mac address
|
||||||
if copts.macAddress != "" {
|
if copts.macAddress != "" {
|
||||||
if _, err := opts.ValidateMACAddress(copts.macAddress); err != nil {
|
if _, err := opts.ValidateMACAddress(copts.macAddress); err != nil {
|
||||||
return nil, errors.Errorf("%s is not a valid mac address", copts.macAddress)
|
return nil, fmt.Errorf("%s is not a valid mac address", copts.macAddress)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if copts.stdin {
|
if copts.stdin {
|
||||||
|
@ -361,7 +362,7 @@ func parse(flags *pflag.FlagSet, copts *containerOptions, serverOS string) (*con
|
||||||
|
|
||||||
swappiness := copts.swappiness
|
swappiness := copts.swappiness
|
||||||
if swappiness != -1 && (swappiness < 0 || swappiness > 100) {
|
if swappiness != -1 && (swappiness < 0 || swappiness > 100) {
|
||||||
return nil, errors.Errorf("invalid value: %d. Valid memory swappiness range is 0-100", swappiness)
|
return nil, fmt.Errorf("invalid value: %d. Valid memory swappiness range is 0-100", swappiness)
|
||||||
}
|
}
|
||||||
|
|
||||||
mounts := copts.mounts.Value()
|
mounts := copts.mounts.Value()
|
||||||
|
@ -443,7 +444,7 @@ func parse(flags *pflag.FlagSet, copts *containerOptions, serverOS string) (*con
|
||||||
// Merge in exposed ports to the map of published ports
|
// Merge in exposed ports to the map of published ports
|
||||||
for _, e := range copts.expose.GetAll() {
|
for _, e := range copts.expose.GetAll() {
|
||||||
if strings.Contains(e, ":") {
|
if strings.Contains(e, ":") {
|
||||||
return nil, errors.Errorf("invalid port format for --expose: %s", e)
|
return nil, fmt.Errorf("invalid port format for --expose: %s", e)
|
||||||
}
|
}
|
||||||
// support two formats for expose, original format <portnum>/[<proto>]
|
// support two formats for expose, original format <portnum>/[<proto>]
|
||||||
// or <startport-endport>/[<proto>]
|
// or <startport-endport>/[<proto>]
|
||||||
|
@ -452,7 +453,7 @@ func parse(flags *pflag.FlagSet, copts *containerOptions, serverOS string) (*con
|
||||||
// if expose a port, the start and end port are the same
|
// if expose a port, the start and end port are the same
|
||||||
start, end, err := nat.ParsePortRange(port)
|
start, end, err := nat.ParsePortRange(port)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Errorf("invalid range format for --expose: %s, error: %s", e, err)
|
return nil, fmt.Errorf("invalid range format for --expose: %s, error: %s", e, err)
|
||||||
}
|
}
|
||||||
for i := start; i <= end; i++ {
|
for i := start; i <= end; i++ {
|
||||||
p, err := nat.NewPort(proto, strconv.FormatUint(i, 10))
|
p, err := nat.NewPort(proto, strconv.FormatUint(i, 10))
|
||||||
|
@ -506,22 +507,22 @@ func parse(flags *pflag.FlagSet, copts *containerOptions, serverOS string) (*con
|
||||||
|
|
||||||
pidMode := container.PidMode(copts.pidMode)
|
pidMode := container.PidMode(copts.pidMode)
|
||||||
if !pidMode.Valid() {
|
if !pidMode.Valid() {
|
||||||
return nil, errors.Errorf("--pid: invalid PID mode")
|
return nil, fmt.Errorf("--pid: invalid PID mode")
|
||||||
}
|
}
|
||||||
|
|
||||||
utsMode := container.UTSMode(copts.utsMode)
|
utsMode := container.UTSMode(copts.utsMode)
|
||||||
if !utsMode.Valid() {
|
if !utsMode.Valid() {
|
||||||
return nil, errors.Errorf("--uts: invalid UTS mode")
|
return nil, fmt.Errorf("--uts: invalid UTS mode")
|
||||||
}
|
}
|
||||||
|
|
||||||
usernsMode := container.UsernsMode(copts.usernsMode)
|
usernsMode := container.UsernsMode(copts.usernsMode)
|
||||||
if !usernsMode.Valid() {
|
if !usernsMode.Valid() {
|
||||||
return nil, errors.Errorf("--userns: invalid USER mode")
|
return nil, fmt.Errorf("--userns: invalid USER mode")
|
||||||
}
|
}
|
||||||
|
|
||||||
cgroupnsMode := container.CgroupnsMode(copts.cgroupnsMode)
|
cgroupnsMode := container.CgroupnsMode(copts.cgroupnsMode)
|
||||||
if !cgroupnsMode.Valid() {
|
if !cgroupnsMode.Valid() {
|
||||||
return nil, errors.Errorf("--cgroupns: invalid CGROUP mode")
|
return nil, fmt.Errorf("--cgroupns: invalid CGROUP mode")
|
||||||
}
|
}
|
||||||
|
|
||||||
restartPolicy, err := opts.ParseRestartPolicy(copts.restartPolicy)
|
restartPolicy, err := opts.ParseRestartPolicy(copts.restartPolicy)
|
||||||
|
@ -556,7 +557,7 @@ func parse(flags *pflag.FlagSet, copts *containerOptions, serverOS string) (*con
|
||||||
copts.healthStartInterval != 0
|
copts.healthStartInterval != 0
|
||||||
if copts.noHealthcheck {
|
if copts.noHealthcheck {
|
||||||
if haveHealthSettings {
|
if haveHealthSettings {
|
||||||
return nil, errors.Errorf("--no-healthcheck conflicts with --health-* options")
|
return nil, fmt.Errorf("--no-healthcheck conflicts with --health-* options")
|
||||||
}
|
}
|
||||||
healthConfig = &container.HealthConfig{Test: strslice.StrSlice{"NONE"}}
|
healthConfig = &container.HealthConfig{Test: strslice.StrSlice{"NONE"}}
|
||||||
} else if haveHealthSettings {
|
} else if haveHealthSettings {
|
||||||
|
@ -565,13 +566,13 @@ func parse(flags *pflag.FlagSet, copts *containerOptions, serverOS string) (*con
|
||||||
probe = []string{"CMD-SHELL", copts.healthCmd}
|
probe = []string{"CMD-SHELL", copts.healthCmd}
|
||||||
}
|
}
|
||||||
if copts.healthInterval < 0 {
|
if copts.healthInterval < 0 {
|
||||||
return nil, errors.Errorf("--health-interval cannot be negative")
|
return nil, fmt.Errorf("--health-interval cannot be negative")
|
||||||
}
|
}
|
||||||
if copts.healthTimeout < 0 {
|
if copts.healthTimeout < 0 {
|
||||||
return nil, errors.Errorf("--health-timeout cannot be negative")
|
return nil, fmt.Errorf("--health-timeout cannot be negative")
|
||||||
}
|
}
|
||||||
if copts.healthRetries < 0 {
|
if copts.healthRetries < 0 {
|
||||||
return nil, errors.Errorf("--health-retries cannot be negative")
|
return nil, fmt.Errorf("--health-retries cannot be negative")
|
||||||
}
|
}
|
||||||
if copts.healthStartPeriod < 0 {
|
if copts.healthStartPeriod < 0 {
|
||||||
return nil, errors.New("--health-start-period cannot be negative")
|
return nil, errors.New("--health-start-period cannot be negative")
|
||||||
|
@ -704,7 +705,7 @@ func parse(flags *pflag.FlagSet, copts *containerOptions, serverOS string) (*con
|
||||||
}
|
}
|
||||||
|
|
||||||
if copts.autoRemove && !hostConfig.RestartPolicy.IsNone() {
|
if copts.autoRemove && !hostConfig.RestartPolicy.IsNone() {
|
||||||
return nil, errors.Errorf("conflicting options: cannot specify both --restart and --rm")
|
return nil, fmt.Errorf("conflicting options: cannot specify both --restart and --rm")
|
||||||
}
|
}
|
||||||
|
|
||||||
// only set this value if the user provided the flag, else it should default to nil
|
// only set this value if the user provided the flag, else it should default to nil
|
||||||
|
@ -788,7 +789,7 @@ func parseNetworkOpts(copts *containerOptions) (map[string]*networktypes.Endpoin
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if _, ok := endpoints[n.Target]; ok {
|
if _, ok := endpoints[n.Target]; ok {
|
||||||
return nil, errdefs.InvalidParameter(errors.Errorf("network %q is specified multiple times", n.Target))
|
return nil, errdefs.InvalidParameter(fmt.Errorf("network %q is specified multiple times", n.Target))
|
||||||
}
|
}
|
||||||
|
|
||||||
// For backward compatibility: if no custom options are provided for the network,
|
// For backward compatibility: if no custom options are provided for the network,
|
||||||
|
@ -882,7 +883,7 @@ func parseNetworkAttachmentOpt(ep opts.NetworkAttachmentOpts) (*networktypes.End
|
||||||
}
|
}
|
||||||
if ep.MacAddress != "" {
|
if ep.MacAddress != "" {
|
||||||
if _, err := opts.ValidateMACAddress(ep.MacAddress); err != nil {
|
if _, err := opts.ValidateMACAddress(ep.MacAddress); err != nil {
|
||||||
return nil, errors.Errorf("%s is not a valid mac address", ep.MacAddress)
|
return nil, fmt.Errorf("%s is not a valid mac address", ep.MacAddress)
|
||||||
}
|
}
|
||||||
epConfig.MacAddress = ep.MacAddress
|
epConfig.MacAddress = ep.MacAddress
|
||||||
}
|
}
|
||||||
|
@ -897,7 +898,7 @@ func convertToStandardNotation(ports []string) ([]string, error) {
|
||||||
for _, param := range strings.Split(publish, ",") {
|
for _, param := range strings.Split(publish, ",") {
|
||||||
k, v, ok := strings.Cut(param, "=")
|
k, v, ok := strings.Cut(param, "=")
|
||||||
if !ok || k == "" {
|
if !ok || k == "" {
|
||||||
return optsList, errors.Errorf("invalid publish opts format (should be name=value but got '%s')", param)
|
return optsList, fmt.Errorf("invalid publish opts format (should be name=value but got '%s')", param)
|
||||||
}
|
}
|
||||||
params[k] = v
|
params[k] = v
|
||||||
}
|
}
|
||||||
|
@ -912,7 +913,7 @@ func convertToStandardNotation(ports []string) ([]string, error) {
|
||||||
func parseLoggingOpts(loggingDriver string, loggingOpts []string) (map[string]string, error) {
|
func parseLoggingOpts(loggingDriver string, loggingOpts []string) (map[string]string, error) {
|
||||||
loggingOptsMap := opts.ConvertKVStringsToMap(loggingOpts)
|
loggingOptsMap := opts.ConvertKVStringsToMap(loggingOpts)
|
||||||
if loggingDriver == "none" && len(loggingOpts) > 0 {
|
if loggingDriver == "none" && len(loggingOpts) > 0 {
|
||||||
return map[string]string{}, errors.Errorf("invalid logging opts for driver %s", loggingDriver)
|
return map[string]string{}, fmt.Errorf("invalid logging opts for driver %s", loggingDriver)
|
||||||
}
|
}
|
||||||
return loggingOptsMap, nil
|
return loggingOptsMap, nil
|
||||||
}
|
}
|
||||||
|
@ -926,7 +927,7 @@ func parseSecurityOpts(securityOpts []string) ([]string, error) {
|
||||||
}
|
}
|
||||||
if (!ok || v == "") && k != "no-new-privileges" {
|
if (!ok || v == "") && k != "no-new-privileges" {
|
||||||
// "no-new-privileges" is the only option that does not require a value.
|
// "no-new-privileges" is the only option that does not require a value.
|
||||||
return securityOpts, errors.Errorf("Invalid --security-opt: %q", opt)
|
return securityOpts, fmt.Errorf("Invalid --security-opt: %q", opt)
|
||||||
}
|
}
|
||||||
if k == "seccomp" {
|
if k == "seccomp" {
|
||||||
switch v {
|
switch v {
|
||||||
|
@ -937,11 +938,11 @@ func parseSecurityOpts(securityOpts []string) ([]string, error) {
|
||||||
// content if it's valid JSON.
|
// content if it's valid JSON.
|
||||||
f, err := os.ReadFile(v)
|
f, err := os.ReadFile(v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return securityOpts, errors.Errorf("opening seccomp profile (%s) failed: %v", v, err)
|
return securityOpts, fmt.Errorf("opening seccomp profile (%s) failed: %v", v, err)
|
||||||
}
|
}
|
||||||
b := bytes.NewBuffer(nil)
|
b := bytes.NewBuffer(nil)
|
||||||
if err := json.Compact(b, f); err != nil {
|
if err := json.Compact(b, f); err != nil {
|
||||||
return securityOpts, errors.Errorf("compacting json for seccomp profile (%s) failed: %v", v, err)
|
return securityOpts, fmt.Errorf("compacting json for seccomp profile (%s) failed: %v", v, err)
|
||||||
}
|
}
|
||||||
securityOpts[key] = fmt.Sprintf("seccomp=%s", b.Bytes())
|
securityOpts[key] = fmt.Sprintf("seccomp=%s", b.Bytes())
|
||||||
}
|
}
|
||||||
|
@ -976,7 +977,7 @@ func parseStorageOpts(storageOpts []string) (map[string]string, error) {
|
||||||
for _, option := range storageOpts {
|
for _, option := range storageOpts {
|
||||||
k, v, ok := strings.Cut(option, "=")
|
k, v, ok := strings.Cut(option, "=")
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, errors.Errorf("invalid storage option")
|
return nil, fmt.Errorf("invalid storage option")
|
||||||
}
|
}
|
||||||
m[k] = v
|
m[k] = v
|
||||||
}
|
}
|
||||||
|
@ -991,7 +992,7 @@ func parseDevice(device, serverOS string) (container.DeviceMapping, error) {
|
||||||
case "windows":
|
case "windows":
|
||||||
return parseWindowsDevice(device)
|
return parseWindowsDevice(device)
|
||||||
}
|
}
|
||||||
return container.DeviceMapping{}, errors.Errorf("unknown server OS: %s", serverOS)
|
return container.DeviceMapping{}, fmt.Errorf("unknown server OS: %s", serverOS)
|
||||||
}
|
}
|
||||||
|
|
||||||
// parseLinuxDevice parses a device mapping string to a container.DeviceMapping struct
|
// parseLinuxDevice parses a device mapping string to a container.DeviceMapping struct
|
||||||
|
@ -1015,7 +1016,7 @@ func parseLinuxDevice(device string) (container.DeviceMapping, error) {
|
||||||
case 1:
|
case 1:
|
||||||
src = arr[0]
|
src = arr[0]
|
||||||
default:
|
default:
|
||||||
return container.DeviceMapping{}, errors.Errorf("invalid device specification: %s", device)
|
return container.DeviceMapping{}, fmt.Errorf("invalid device specification: %s", device)
|
||||||
}
|
}
|
||||||
|
|
||||||
if dst == "" {
|
if dst == "" {
|
||||||
|
@ -1045,7 +1046,7 @@ func validateDeviceCgroupRule(val string) (string, error) {
|
||||||
return val, nil
|
return val, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return val, errors.Errorf("invalid device cgroup format '%s'", val)
|
return val, fmt.Errorf("invalid device cgroup format '%s'", val)
|
||||||
}
|
}
|
||||||
|
|
||||||
// validDeviceMode checks if the mode for device is valid or not.
|
// validDeviceMode checks if the mode for device is valid or not.
|
||||||
|
@ -1077,7 +1078,7 @@ func validateDevice(val string, serverOS string) (string, error) {
|
||||||
// Windows does validation entirely server-side
|
// Windows does validation entirely server-side
|
||||||
return val, nil
|
return val, nil
|
||||||
}
|
}
|
||||||
return "", errors.Errorf("unknown server OS: %s", serverOS)
|
return "", fmt.Errorf("unknown server OS: %s", serverOS)
|
||||||
}
|
}
|
||||||
|
|
||||||
// validateLinuxPath is the implementation of validateDevice knowing that the
|
// validateLinuxPath is the implementation of validateDevice knowing that the
|
||||||
|
@ -1092,12 +1093,12 @@ func validateLinuxPath(val string, validator func(string) bool) (string, error)
|
||||||
var mode string
|
var mode string
|
||||||
|
|
||||||
if strings.Count(val, ":") > 2 {
|
if strings.Count(val, ":") > 2 {
|
||||||
return val, errors.Errorf("bad format for path: %s", val)
|
return val, fmt.Errorf("bad format for path: %s", val)
|
||||||
}
|
}
|
||||||
|
|
||||||
split := strings.SplitN(val, ":", 3)
|
split := strings.SplitN(val, ":", 3)
|
||||||
if split[0] == "" {
|
if split[0] == "" {
|
||||||
return val, errors.Errorf("bad format for path: %s", val)
|
return val, fmt.Errorf("bad format for path: %s", val)
|
||||||
}
|
}
|
||||||
switch len(split) {
|
switch len(split) {
|
||||||
case 1:
|
case 1:
|
||||||
|
@ -1116,13 +1117,13 @@ func validateLinuxPath(val string, validator func(string) bool) (string, error)
|
||||||
containerPath = split[1]
|
containerPath = split[1]
|
||||||
mode = split[2]
|
mode = split[2]
|
||||||
if isValid := validator(split[2]); !isValid {
|
if isValid := validator(split[2]); !isValid {
|
||||||
return val, errors.Errorf("bad mode specified: %s", mode)
|
return val, fmt.Errorf("bad mode specified: %s", mode)
|
||||||
}
|
}
|
||||||
val = fmt.Sprintf("%s:%s:%s", split[0], containerPath, mode)
|
val = fmt.Sprintf("%s:%s:%s", split[0], containerPath, mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !path.IsAbs(containerPath) {
|
if !path.IsAbs(containerPath) {
|
||||||
return val, errors.Errorf("%s is not an absolute path", containerPath)
|
return val, fmt.Errorf("%s is not an absolute path", containerPath)
|
||||||
}
|
}
|
||||||
return val, nil
|
return val, nil
|
||||||
}
|
}
|
||||||
|
@ -1135,7 +1136,7 @@ func validateAttach(val string) (string, error) {
|
||||||
return s, nil
|
return s, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return val, errors.Errorf("valid streams are STDIN, STDOUT and STDERR")
|
return val, fmt.Errorf("valid streams are STDIN, STDOUT and STDERR")
|
||||||
}
|
}
|
||||||
|
|
||||||
func validateAPIVersion(c *containerConfig, serverAPIVersion string) error {
|
func validateAPIVersion(c *containerConfig, serverAPIVersion string) error {
|
||||||
|
|
|
@ -12,7 +12,7 @@ import (
|
||||||
"github.com/docker/docker/api/types/container"
|
"github.com/docker/docker/api/types/container"
|
||||||
networktypes "github.com/docker/docker/api/types/network"
|
networktypes "github.com/docker/docker/api/types/network"
|
||||||
"github.com/docker/go-connections/nat"
|
"github.com/docker/go-connections/nat"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/spf13/pflag"
|
"github.com/spf13/pflag"
|
||||||
"gotest.tools/v3/assert"
|
"gotest.tools/v3/assert"
|
||||||
is "gotest.tools/v3/assert/cmp"
|
is "gotest.tools/v3/assert/cmp"
|
||||||
|
@ -280,7 +280,7 @@ func compareRandomizedStrings(a, b, c, d string) error {
|
||||||
if a == d && b == c {
|
if a == d && b == c {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return errors.Errorf("strings don't match")
|
return fmt.Errorf("strings don't match")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Simple parse with MacAddress validation
|
// Simple parse with MacAddress validation
|
||||||
|
|
|
@ -2,6 +2,7 @@ package container
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
@ -9,7 +10,7 @@ import (
|
||||||
"github.com/docker/cli/cli/command"
|
"github.com/docker/cli/cli/command"
|
||||||
"github.com/docker/cli/cli/command/completion"
|
"github.com/docker/cli/cli/command/completion"
|
||||||
"github.com/docker/docker/api/types/container"
|
"github.com/docker/docker/api/types/container"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ import (
|
||||||
"github.com/docker/cli/cli/command/completion"
|
"github.com/docker/cli/cli/command/completion"
|
||||||
"github.com/docker/go-connections/nat"
|
"github.com/docker/go-connections/nat"
|
||||||
"github.com/fvbommel/sortorder"
|
"github.com/fvbommel/sortorder"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -65,11 +65,11 @@ func runPort(ctx context.Context, dockerCli command.Cli, opts *portOptions) erro
|
||||||
proto = "tcp"
|
proto = "tcp"
|
||||||
}
|
}
|
||||||
if _, err = strconv.ParseUint(port, 10, 16); err != nil {
|
if _, err = strconv.ParseUint(port, 10, 16); err != nil {
|
||||||
return errors.Wrapf(err, "Error: invalid port (%s)", port)
|
return fmt.Errorf("Error: invalid port (%s): %w", port, err)
|
||||||
}
|
}
|
||||||
frontends, exists := c.NetworkSettings.Ports[nat.Port(port+"/"+proto)]
|
frontends, exists := c.NetworkSettings.Ports[nat.Port(port+"/"+proto)]
|
||||||
if !exists || frontends == nil {
|
if !exists || frontends == nil {
|
||||||
return errors.Errorf("Error: No public port '%s' published for %s", opts.port, opts.container)
|
return fmt.Errorf("Error: No public port '%s' published for %s", opts.port, opts.container)
|
||||||
}
|
}
|
||||||
for _, frontend := range frontends {
|
for _, frontend := range frontends {
|
||||||
out = append(out, net.JoinHostPort(frontend.HostIP, frontend.HostPort))
|
out = append(out, net.JoinHostPort(frontend.HostIP, frontend.HostPort))
|
||||||
|
|
|
@ -2,6 +2,7 @@ package container
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/docker/cli/cli"
|
"github.com/docker/cli/cli"
|
||||||
|
@ -10,7 +11,7 @@ import (
|
||||||
"github.com/docker/cli/opts"
|
"github.com/docker/cli/opts"
|
||||||
"github.com/docker/docker/errdefs"
|
"github.com/docker/docker/errdefs"
|
||||||
units "github.com/docker/go-units"
|
units "github.com/docker/go-units"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -2,13 +2,13 @@ package container
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/docker/cli/internal/test"
|
"github.com/docker/cli/internal/test"
|
||||||
"github.com/docker/docker/api/types/container"
|
"github.com/docker/docker/api/types/container"
|
||||||
"github.com/docker/docker/api/types/filters"
|
"github.com/docker/docker/api/types/filters"
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestContainerPrunePromptTermination(t *testing.T) {
|
func TestContainerPrunePromptTermination(t *testing.T) {
|
||||||
|
|
|
@ -2,13 +2,14 @@ package container
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/docker/cli/cli"
|
"github.com/docker/cli/cli"
|
||||||
"github.com/docker/cli/cli/command"
|
"github.com/docker/cli/cli/command"
|
||||||
"github.com/docker/cli/cli/command/completion"
|
"github.com/docker/cli/cli/command/completion"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -48,7 +49,7 @@ func runRename(ctx context.Context, dockerCli command.Cli, opts *renameOptions)
|
||||||
|
|
||||||
if err := dockerCli.Client().ContainerRename(ctx, oldName, newName); err != nil {
|
if err := dockerCli.Client().ContainerRename(ctx, oldName, newName); err != nil {
|
||||||
fmt.Fprintln(dockerCli.Err(), err)
|
fmt.Fprintln(dockerCli.Err(), err)
|
||||||
return errors.Errorf("Error: failed to rename container named %s", oldName)
|
return fmt.Errorf("Error: failed to rename container named %s", oldName)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,11 +2,12 @@ package container
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/docker/cli/internal/test"
|
"github.com/docker/cli/internal/test"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"gotest.tools/v3/assert"
|
"gotest.tools/v3/assert"
|
||||||
is "gotest.tools/v3/assert/cmp"
|
is "gotest.tools/v3/assert/cmp"
|
||||||
)
|
)
|
||||||
|
|
|
@ -2,6 +2,7 @@ package container
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
@ -9,7 +10,7 @@ import (
|
||||||
"github.com/docker/cli/cli/command"
|
"github.com/docker/cli/cli/command"
|
||||||
"github.com/docker/cli/cli/command/completion"
|
"github.com/docker/cli/cli/command/completion"
|
||||||
"github.com/docker/docker/api/types/container"
|
"github.com/docker/docker/api/types/container"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ package container
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"sort"
|
"sort"
|
||||||
"sync"
|
"sync"
|
||||||
|
@ -10,7 +11,7 @@ import (
|
||||||
"github.com/docker/cli/internal/test"
|
"github.com/docker/cli/internal/test"
|
||||||
"github.com/docker/docker/api/types/container"
|
"github.com/docker/docker/api/types/container"
|
||||||
"github.com/docker/docker/errdefs"
|
"github.com/docker/docker/errdefs"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"gotest.tools/v3/assert"
|
"gotest.tools/v3/assert"
|
||||||
is "gotest.tools/v3/assert/cmp"
|
is "gotest.tools/v3/assert/cmp"
|
||||||
)
|
)
|
||||||
|
|
|
@ -2,6 +2,7 @@ package container
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
@ -10,7 +11,7 @@ import (
|
||||||
"github.com/docker/cli/cli/command/completion"
|
"github.com/docker/cli/cli/command/completion"
|
||||||
"github.com/docker/docker/api/types/container"
|
"github.com/docker/docker/api/types/container"
|
||||||
"github.com/docker/docker/errdefs"
|
"github.com/docker/docker/errdefs"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ package container
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -14,7 +15,7 @@ import (
|
||||||
"github.com/docker/docker/api/types/container"
|
"github.com/docker/docker/api/types/container"
|
||||||
"github.com/moby/sys/signal"
|
"github.com/moby/sys/signal"
|
||||||
"github.com/moby/term"
|
"github.com/moby/term"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/pflag"
|
"github.com/spf13/pflag"
|
||||||
|
|
|
@ -2,6 +2,7 @@ package container
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -12,7 +13,7 @@ import (
|
||||||
"github.com/docker/docker/api/types/container"
|
"github.com/docker/docker/api/types/container"
|
||||||
"github.com/moby/sys/signal"
|
"github.com/moby/sys/signal"
|
||||||
"github.com/moby/term"
|
"github.com/moby/term"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -203,7 +204,7 @@ func startContainersWithoutAttachments(ctx context.Context, dockerCli command.Cl
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(failedContainers) > 0 {
|
if len(failedContainers) > 0 {
|
||||||
return errors.Errorf("Error: failed to start containers: %s", strings.Join(failedContainers, ", "))
|
return fmt.Errorf("Error: failed to start containers: %s", strings.Join(failedContainers, ", "))
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package container
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -16,7 +17,7 @@ import (
|
||||||
"github.com/docker/docker/api/types/container"
|
"github.com/docker/docker/api/types/container"
|
||||||
"github.com/docker/docker/api/types/events"
|
"github.com/docker/docker/api/types/events"
|
||||||
"github.com/docker/docker/api/types/filters"
|
"github.com/docker/docker/api/types/filters"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
|
@ -3,13 +3,14 @@ package container
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/docker/docker/api/types/container"
|
"github.com/docker/docker/api/types/container"
|
||||||
"github.com/docker/docker/client"
|
"github.com/docker/docker/client"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ package container
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
@ -9,7 +10,7 @@ import (
|
||||||
"github.com/docker/cli/cli/command"
|
"github.com/docker/cli/cli/command"
|
||||||
"github.com/docker/cli/cli/command/completion"
|
"github.com/docker/cli/cli/command/completion"
|
||||||
"github.com/docker/docker/api/types/container"
|
"github.com/docker/docker/api/types/container"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ package container
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"sort"
|
"sort"
|
||||||
"sync"
|
"sync"
|
||||||
|
@ -10,7 +11,7 @@ import (
|
||||||
"github.com/docker/cli/internal/test"
|
"github.com/docker/cli/internal/test"
|
||||||
"github.com/docker/docker/api/types/container"
|
"github.com/docker/docker/api/types/container"
|
||||||
"github.com/docker/docker/errdefs"
|
"github.com/docker/docker/errdefs"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"gotest.tools/v3/assert"
|
"gotest.tools/v3/assert"
|
||||||
is "gotest.tools/v3/assert/cmp"
|
is "gotest.tools/v3/assert/cmp"
|
||||||
)
|
)
|
||||||
|
|
|
@ -2,13 +2,14 @@ package container
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/docker/cli/cli/command"
|
"github.com/docker/cli/cli/command"
|
||||||
"github.com/docker/cli/internal/test"
|
"github.com/docker/cli/internal/test"
|
||||||
"github.com/docker/docker/api/types/container"
|
"github.com/docker/docker/api/types/container"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"gotest.tools/v3/assert"
|
"gotest.tools/v3/assert"
|
||||||
is "gotest.tools/v3/assert/cmp"
|
is "gotest.tools/v3/assert/cmp"
|
||||||
)
|
)
|
||||||
|
@ -16,7 +17,7 @@ import (
|
||||||
func TestInitTtySizeErrors(t *testing.T) {
|
func TestInitTtySizeErrors(t *testing.T) {
|
||||||
expectedError := "failed to resize tty, using default size\n"
|
expectedError := "failed to resize tty, using default size\n"
|
||||||
fakeContainerExecResizeFunc := func(id string, options container.ResizeOptions) error {
|
fakeContainerExecResizeFunc := func(id string, options container.ResizeOptions) error {
|
||||||
return errors.Errorf("Error response from daemon: no such exec")
|
return fmt.Errorf("Error response from daemon: no such exec")
|
||||||
}
|
}
|
||||||
fakeResizeTtyFunc := func(ctx context.Context, cli command.Cli, id string, isExec bool) error {
|
fakeResizeTtyFunc := func(ctx context.Context, cli command.Cli, id string, isExec bool) error {
|
||||||
height, width := uint(1024), uint(768)
|
height, width := uint(1024), uint(768)
|
||||||
|
|
|
@ -2,6 +2,7 @@ package container
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
@ -9,7 +10,7 @@ import (
|
||||||
"github.com/docker/cli/cli/command"
|
"github.com/docker/cli/cli/command"
|
||||||
"github.com/docker/cli/cli/command/completion"
|
"github.com/docker/cli/cli/command/completion"
|
||||||
"github.com/docker/docker/api/types/container"
|
"github.com/docker/docker/api/types/container"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ package container
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
@ -10,7 +11,7 @@ import (
|
||||||
"github.com/docker/cli/cli/command/completion"
|
"github.com/docker/cli/cli/command/completion"
|
||||||
"github.com/docker/cli/opts"
|
"github.com/docker/cli/opts"
|
||||||
containertypes "github.com/docker/docker/api/types/container"
|
containertypes "github.com/docker/docker/api/types/container"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -2,13 +2,14 @@ package container
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/docker/cli/cli"
|
"github.com/docker/cli/cli"
|
||||||
"github.com/docker/cli/cli/command"
|
"github.com/docker/cli/cli/command"
|
||||||
"github.com/docker/cli/cli/command/completion"
|
"github.com/docker/cli/cli/command/completion"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ package context
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/docker/cli/cli"
|
"github.com/docker/cli/cli"
|
||||||
|
@ -14,7 +15,7 @@ import (
|
||||||
"github.com/docker/cli/cli/context/docker"
|
"github.com/docker/cli/cli/context/docker"
|
||||||
"github.com/docker/cli/cli/context/store"
|
"github.com/docker/cli/cli/context/store"
|
||||||
"github.com/docker/docker/errdefs"
|
"github.com/docker/docker/errdefs"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -91,7 +92,7 @@ func createNewContext(contextStore store.ReaderWriter, o *CreateOptions) error {
|
||||||
}
|
}
|
||||||
dockerEP, dockerTLS, err := getDockerEndpointMetadataAndTLS(contextStore, o.Docker)
|
dockerEP, dockerTLS, err := getDockerEndpointMetadataAndTLS(contextStore, o.Docker)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "unable to create docker endpoint config")
|
return fmt.Errorf("unable to create docker endpoint config: %w", err)
|
||||||
}
|
}
|
||||||
contextMetadata := store.Metadata{
|
contextMetadata := store.Metadata{
|
||||||
Endpoints: map[string]any{
|
Endpoints: map[string]any{
|
||||||
|
@ -124,9 +125,9 @@ func checkContextNameForCreation(s store.Reader, name string) error {
|
||||||
}
|
}
|
||||||
if _, err := s.GetMetadata(name); !errdefs.IsNotFound(err) {
|
if _, err := s.GetMetadata(name); !errdefs.IsNotFound(err) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "error while getting existing contexts")
|
return fmt.Errorf("error while getting existing contexts: %w", err)
|
||||||
}
|
}
|
||||||
return errors.Errorf("context %q already exists", name)
|
return fmt.Errorf("context %q already exists", name)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package context
|
package context
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -9,7 +10,6 @@ import (
|
||||||
"github.com/docker/cli/cli/context/docker"
|
"github.com/docker/cli/cli/context/docker"
|
||||||
"github.com/docker/cli/cli/context/store"
|
"github.com/docker/cli/cli/context/store"
|
||||||
"github.com/docker/docker/client"
|
"github.com/docker/docker/client"
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -100,7 +100,7 @@ func getDockerEndpoint(contextStore store.Reader, config map[string]string) (doc
|
||||||
if ep, ok := metadata.Endpoints[docker.DockerEndpoint].(docker.EndpointMeta); ok {
|
if ep, ok := metadata.Endpoints[docker.DockerEndpoint].(docker.EndpointMeta); ok {
|
||||||
return docker.Endpoint{EndpointMeta: ep}, nil
|
return docker.Endpoint{EndpointMeta: ep}, nil
|
||||||
}
|
}
|
||||||
return docker.Endpoint{}, errors.Errorf("unable to get endpoint from context %q", contextName)
|
return docker.Endpoint{}, fmt.Errorf("unable to get endpoint from context %q", contextName)
|
||||||
}
|
}
|
||||||
tlsData, err := context.TLSDataFromFiles(config[keyCA], config[keyCert], config[keyKey])
|
tlsData, err := context.TLSDataFromFiles(config[keyCA], config[keyCert], config[keyKey])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -120,10 +120,10 @@ func getDockerEndpoint(contextStore store.Reader, config map[string]string) (doc
|
||||||
// try to resolve a docker client, validating the configuration
|
// try to resolve a docker client, validating the configuration
|
||||||
opts, err := ep.ClientOpts()
|
opts, err := ep.ClientOpts()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return docker.Endpoint{}, errors.Wrap(err, "invalid docker endpoint options")
|
return docker.Endpoint{}, fmt.Errorf("invalid docker endpoint options: %w", err)
|
||||||
}
|
}
|
||||||
if _, err := client.NewClientWithOpts(opts...); err != nil {
|
if _, err := client.NewClientWithOpts(opts...); err != nil {
|
||||||
return docker.Endpoint{}, errors.Wrap(err, "unable to apply docker endpoint options")
|
return docker.Endpoint{}, fmt.Errorf("unable to apply docker endpoint options: %w", err)
|
||||||
}
|
}
|
||||||
return ep, nil
|
return ep, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package context
|
package context
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -8,7 +9,7 @@ import (
|
||||||
"github.com/docker/cli/cli"
|
"github.com/docker/cli/cli"
|
||||||
"github.com/docker/cli/cli/command"
|
"github.com/docker/cli/cli/command"
|
||||||
"github.com/docker/docker/errdefs"
|
"github.com/docker/docker/errdefs"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -54,7 +55,7 @@ func RunRemove(dockerCli command.Cli, opts RemoveOptions, names []string) error
|
||||||
func doRemove(dockerCli command.Cli, name string, isCurrent, force bool) error {
|
func doRemove(dockerCli command.Cli, name string, isCurrent, force bool) error {
|
||||||
if isCurrent {
|
if isCurrent {
|
||||||
if !force {
|
if !force {
|
||||||
return errors.Errorf("context %q is in use, set -f flag to force remove", name)
|
return fmt.Errorf("context %q is in use, set -f flag to force remove", name)
|
||||||
}
|
}
|
||||||
// fallback to DOCKER_HOST
|
// fallback to DOCKER_HOST
|
||||||
cfg := dockerCli.ConfigFile()
|
cfg := dockerCli.ConfigFile()
|
||||||
|
@ -77,7 +78,7 @@ func checkContextExists(dockerCli command.Cli, name string) error {
|
||||||
contextDir := dockerCli.ContextStore().GetStorageInfo(name).MetadataPath
|
contextDir := dockerCli.ContextStore().GetStorageInfo(name).MetadataPath
|
||||||
_, err := os.Stat(contextDir)
|
_, err := os.Stat(contextDir)
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
return errdefs.NotFound(errors.Errorf("context %q does not exist", name))
|
return errdefs.NotFound(fmt.Errorf("context %q does not exist", name))
|
||||||
}
|
}
|
||||||
// Ignore other errors; if relevant, they will produce an error when
|
// Ignore other errors; if relevant, they will produce an error when
|
||||||
// performing the actual delete.
|
// performing the actual delete.
|
||||||
|
|
|
@ -9,7 +9,7 @@ import (
|
||||||
"github.com/docker/cli/cli/command/formatter/tabwriter"
|
"github.com/docker/cli/cli/command/formatter/tabwriter"
|
||||||
"github.com/docker/cli/cli/context/docker"
|
"github.com/docker/cli/cli/context/docker"
|
||||||
"github.com/docker/cli/cli/context/store"
|
"github.com/docker/cli/cli/context/store"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -76,7 +76,7 @@ func RunUpdate(dockerCLI command.Cli, o *UpdateOptions) error {
|
||||||
if o.Docker != nil {
|
if o.Docker != nil {
|
||||||
dockerEP, dockerTLS, err := getDockerEndpointMetadataAndTLS(s, o.Docker)
|
dockerEP, dockerTLS, err := getDockerEndpointMetadataAndTLS(s, o.Docker)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "unable to create docker endpoint config")
|
return fmt.Errorf("unable to create docker endpoint config: %w", err)
|
||||||
}
|
}
|
||||||
c.Endpoints[docker.DockerEndpoint] = dockerEP
|
c.Endpoints[docker.DockerEndpoint] = dockerEP
|
||||||
tlsDataToReset[docker.DockerEndpoint] = dockerTLS
|
tlsDataToReset[docker.DockerEndpoint] = dockerTLS
|
||||||
|
|
|
@ -4,11 +4,12 @@
|
||||||
package command
|
package command
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
"github.com/docker/cli/cli/context/docker"
|
"github.com/docker/cli/cli/context/docker"
|
||||||
"github.com/docker/cli/cli/context/store"
|
"github.com/docker/cli/cli/context/store"
|
||||||
cliflags "github.com/docker/cli/cli/flags"
|
cliflags "github.com/docker/cli/cli/flags"
|
||||||
"github.com/docker/docker/errdefs"
|
"github.com/docker/docker/errdefs"
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -186,7 +187,7 @@ func (s *ContextStoreWithDefault) GetTLSData(contextName, endpointName, fileName
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if defaultContext.TLS.Endpoints[endpointName].Files[fileName] == nil {
|
if defaultContext.TLS.Endpoints[endpointName].Files[fileName] == nil {
|
||||||
return nil, errdefs.NotFound(errors.Errorf("TLS data for %s/%s/%s does not exist", DefaultContextName, endpointName, fileName))
|
return nil, errdefs.NotFound(fmt.Errorf("TLS data for %s/%s/%s does not exist", DefaultContextName, endpointName, fileName))
|
||||||
}
|
}
|
||||||
return defaultContext.TLS.Endpoints[endpointName].Files[fileName], nil
|
return defaultContext.TLS.Endpoints[endpointName].Files[fileName], nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,13 +5,13 @@ package formatter
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"strings"
|
"strings"
|
||||||
"text/template"
|
"text/template"
|
||||||
|
|
||||||
"github.com/docker/cli/cli/command/formatter/tabwriter"
|
"github.com/docker/cli/cli/command/formatter/tabwriter"
|
||||||
"github.com/docker/cli/templates"
|
"github.com/docker/cli/templates"
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Format keys used to specify certain kinds of output formats
|
// Format keys used to specify certain kinds of output formats
|
||||||
|
@ -76,7 +76,7 @@ func (c *Context) preFormat() {
|
||||||
func (c *Context) parseFormat() (*template.Template, error) {
|
func (c *Context) parseFormat() (*template.Template, error) {
|
||||||
tmpl, err := templates.Parse(c.finalFormat)
|
tmpl, err := templates.Parse(c.finalFormat)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return tmpl, errors.Wrap(err, "template parsing error")
|
return tmpl, fmt.Errorf("template parsing error: %w", err)
|
||||||
}
|
}
|
||||||
return tmpl, err
|
return tmpl, err
|
||||||
}
|
}
|
||||||
|
@ -97,7 +97,7 @@ func (c *Context) postFormat(tmpl *template.Template, subContext SubContext) {
|
||||||
|
|
||||||
func (c *Context) contextFormat(tmpl *template.Template, subContext SubContext) error {
|
func (c *Context) contextFormat(tmpl *template.Template, subContext SubContext) error {
|
||||||
if err := tmpl.Execute(c.buffer, subContext); err != nil {
|
if err := tmpl.Execute(c.buffer, subContext); err != nil {
|
||||||
return errors.Wrap(err, "template parsing error")
|
return fmt.Errorf("template parsing error: %w", err)
|
||||||
}
|
}
|
||||||
if c.Format.IsTable() && c.header != nil {
|
if c.Format.IsTable() && c.header != nil {
|
||||||
c.header = subContext.FullHeader()
|
c.header = subContext.FullHeader()
|
||||||
|
|
|
@ -5,10 +5,9 @@ package formatter
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
"unicode"
|
"unicode"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// MarshalJSON marshals x into json
|
// MarshalJSON marshals x into json
|
||||||
|
@ -25,14 +24,14 @@ func MarshalJSON(x any) ([]byte, error) {
|
||||||
func marshalMap(x any) (map[string]any, error) {
|
func marshalMap(x any) (map[string]any, error) {
|
||||||
val := reflect.ValueOf(x)
|
val := reflect.ValueOf(x)
|
||||||
if val.Kind() != reflect.Ptr {
|
if val.Kind() != reflect.Ptr {
|
||||||
return nil, errors.Errorf("expected a pointer to a struct, got %v", val.Kind())
|
return nil, fmt.Errorf("expected a pointer to a struct, got %v", val.Kind())
|
||||||
}
|
}
|
||||||
if val.IsNil() {
|
if val.IsNil() {
|
||||||
return nil, errors.Errorf("expected a pointer to a struct, got nil pointer")
|
return nil, fmt.Errorf("expected a pointer to a struct, got nil pointer")
|
||||||
}
|
}
|
||||||
valElem := val.Elem()
|
valElem := val.Elem()
|
||||||
if valElem.Kind() != reflect.Struct {
|
if valElem.Kind() != reflect.Struct {
|
||||||
return nil, errors.Errorf("expected a pointer to a struct, got a pointer to %v", valElem.Kind())
|
return nil, fmt.Errorf("expected a pointer to a struct, got a pointer to %v", valElem.Kind())
|
||||||
}
|
}
|
||||||
typ := val.Type()
|
typ := val.Type()
|
||||||
m := make(map[string]any)
|
m := make(map[string]any)
|
||||||
|
@ -54,7 +53,7 @@ var unmarshallableNames = map[string]struct{}{"FullHeader": {}}
|
||||||
// It returns ("", nil, nil) for valid but non-marshallable parameter. (e.g. "unexportedFunc()")
|
// It returns ("", nil, nil) for valid but non-marshallable parameter. (e.g. "unexportedFunc()")
|
||||||
func marshalForMethod(typ reflect.Method, val reflect.Value) (string, any, error) {
|
func marshalForMethod(typ reflect.Method, val reflect.Value) (string, any, error) {
|
||||||
if val.Kind() != reflect.Func {
|
if val.Kind() != reflect.Func {
|
||||||
return "", nil, errors.Errorf("expected func, got %v", val.Kind())
|
return "", nil, fmt.Errorf("expected func, got %v", val.Kind())
|
||||||
}
|
}
|
||||||
name, numIn, numOut := typ.Name, val.Type().NumIn(), val.Type().NumOut()
|
name, numIn, numOut := typ.Name, val.Type().NumIn(), val.Type().NumOut()
|
||||||
_, blackListed := unmarshallableNames[name]
|
_, blackListed := unmarshallableNames[name]
|
||||||
|
|
|
@ -5,11 +5,11 @@ package idresolver
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
"github.com/docker/docker/api/types/swarm"
|
"github.com/docker/docker/api/types/swarm"
|
||||||
"github.com/docker/docker/client"
|
"github.com/docker/docker/client"
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// IDResolver provides ID to Name resolution.
|
// IDResolver provides ID to Name resolution.
|
||||||
|
@ -51,7 +51,7 @@ func (r *IDResolver) get(ctx context.Context, t any, id string) (string, error)
|
||||||
}
|
}
|
||||||
return service.Spec.Annotations.Name, nil
|
return service.Spec.Annotations.Name, nil
|
||||||
default:
|
default:
|
||||||
return "", errors.Errorf("unsupported type")
|
return "", fmt.Errorf("unsupported type")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,11 +2,12 @@ package idresolver
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/docker/cli/internal/test/builders"
|
"github.com/docker/cli/internal/test/builders"
|
||||||
"github.com/docker/docker/api/types/swarm"
|
"github.com/docker/docker/api/types/swarm"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"gotest.tools/v3/assert"
|
"gotest.tools/v3/assert"
|
||||||
is "gotest.tools/v3/assert/cmp"
|
is "gotest.tools/v3/assert/cmp"
|
||||||
)
|
)
|
||||||
|
@ -14,7 +15,7 @@ import (
|
||||||
func TestResolveError(t *testing.T) {
|
func TestResolveError(t *testing.T) {
|
||||||
cli := &fakeClient{
|
cli := &fakeClient{
|
||||||
nodeInspectFunc: func(nodeID string) (swarm.Node, []byte, error) {
|
nodeInspectFunc: func(nodeID string) (swarm.Node, []byte, error) {
|
||||||
return swarm.Node{}, []byte{}, errors.Errorf("error inspecting node")
|
return swarm.Node{}, []byte{}, fmt.Errorf("error inspecting node")
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,7 +76,7 @@ func TestResolveNode(t *testing.T) {
|
||||||
{
|
{
|
||||||
nodeID: "nodeID",
|
nodeID: "nodeID",
|
||||||
nodeInspectFunc: func(string) (swarm.Node, []byte, error) {
|
nodeInspectFunc: func(string) (swarm.Node, []byte, error) {
|
||||||
return swarm.Node{}, []byte{}, errors.Errorf("error inspecting node")
|
return swarm.Node{}, []byte{}, fmt.Errorf("error inspecting node")
|
||||||
},
|
},
|
||||||
expectedID: "nodeID",
|
expectedID: "nodeID",
|
||||||
},
|
},
|
||||||
|
@ -117,7 +118,7 @@ func TestResolveService(t *testing.T) {
|
||||||
{
|
{
|
||||||
serviceID: "serviceID",
|
serviceID: "serviceID",
|
||||||
serviceInspectFunc: func(string) (swarm.Service, []byte, error) {
|
serviceInspectFunc: func(string) (swarm.Service, []byte, error) {
|
||||||
return swarm.Service{}, []byte{}, errors.Errorf("error inspecting service")
|
return swarm.Service{}, []byte{}, fmt.Errorf("error inspecting service")
|
||||||
},
|
},
|
||||||
expectedID: "serviceID",
|
expectedID: "serviceID",
|
||||||
},
|
},
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
@ -31,7 +32,7 @@ import (
|
||||||
"github.com/docker/docker/pkg/jsonmessage"
|
"github.com/docker/docker/pkg/jsonmessage"
|
||||||
"github.com/docker/docker/pkg/progress"
|
"github.com/docker/docker/pkg/progress"
|
||||||
"github.com/docker/docker/pkg/streamformatter"
|
"github.com/docker/docker/pkg/streamformatter"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -212,7 +213,7 @@ func runBuild(ctx context.Context, dockerCli command.Cli, options buildOptions)
|
||||||
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) {
|
||||||
return errors.Wrap(err, "Removing image ID file")
|
return fmt.Errorf("Removing image ID file: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -226,7 +227,7 @@ func runBuild(ctx context.Context, dockerCli command.Cli, options buildOptions)
|
||||||
// Dockerfile is outside of build-context; read the Dockerfile and pass it as dockerfileCtx
|
// Dockerfile is outside of build-context; read the Dockerfile and pass it as dockerfileCtx
|
||||||
dockerfileCtx, err = os.Open(options.dockerfileName)
|
dockerfileCtx, err = os.Open(options.dockerfileName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Errorf("unable to open Dockerfile: %v", err)
|
return fmt.Errorf("unable to open Dockerfile: %v", err)
|
||||||
}
|
}
|
||||||
defer dockerfileCtx.Close()
|
defer dockerfileCtx.Close()
|
||||||
}
|
}
|
||||||
|
@ -235,14 +236,14 @@ func runBuild(ctx context.Context, dockerCli command.Cli, options buildOptions)
|
||||||
case urlutil.IsURL(specifiedContext):
|
case urlutil.IsURL(specifiedContext):
|
||||||
buildCtx, relDockerfile, err = build.GetContextFromURL(progBuff, specifiedContext, options.dockerfileName)
|
buildCtx, relDockerfile, err = build.GetContextFromURL(progBuff, specifiedContext, options.dockerfileName)
|
||||||
default:
|
default:
|
||||||
return errors.Errorf("unable to prepare context: path %q not found", specifiedContext)
|
return fmt.Errorf("unable to prepare context: path %q not found", specifiedContext)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if options.quiet && urlutil.IsURL(specifiedContext) {
|
if options.quiet && urlutil.IsURL(specifiedContext) {
|
||||||
fmt.Fprintln(dockerCli.Err(), progBuff)
|
fmt.Fprintln(dockerCli.Err(), progBuff)
|
||||||
}
|
}
|
||||||
return errors.Errorf("unable to prepare context: %s", err)
|
return fmt.Errorf("unable to prepare context: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if tempDir != "" {
|
if tempDir != "" {
|
||||||
|
@ -258,7 +259,7 @@ func runBuild(ctx context.Context, dockerCli command.Cli, options buildOptions)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := build.ValidateContextDirectory(contextDir, excludes); err != nil {
|
if err := build.ValidateContextDirectory(contextDir, excludes); err != nil {
|
||||||
return errors.Wrap(err, "error checking context")
|
return fmt.Errorf("error checking context: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// And canonicalize dockerfile name to a platform-independent one
|
// And canonicalize dockerfile name to a platform-independent one
|
||||||
|
@ -395,7 +396,7 @@ func runBuild(ctx context.Context, dockerCli command.Cli, options buildOptions)
|
||||||
|
|
||||||
if options.imageIDFile != "" {
|
if options.imageIDFile != "" {
|
||||||
if imageID == "" {
|
if imageID == "" {
|
||||||
return errors.Errorf("Server did not provide an image ID. Cannot write %s", options.imageIDFile)
|
return fmt.Errorf("Server did not provide an image ID. Cannot write %s", options.imageIDFile)
|
||||||
}
|
}
|
||||||
if err := os.WriteFile(options.imageIDFile, []byte(imageID), 0o666); err != nil {
|
if err := os.WriteFile(options.imageIDFile, []byte(imageID), 0o666); err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"archive/tar"
|
"archive/tar"
|
||||||
"bufio"
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
@ -22,7 +23,6 @@ import (
|
||||||
"github.com/docker/docker/pkg/streamformatter"
|
"github.com/docker/docker/pkg/streamformatter"
|
||||||
"github.com/docker/docker/pkg/stringid"
|
"github.com/docker/docker/pkg/stringid"
|
||||||
"github.com/moby/patternmatcher"
|
"github.com/moby/patternmatcher"
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -49,10 +49,10 @@ func ValidateContextDirectory(srcPath string, excludes []string) error {
|
||||||
return filepath.Walk(contextRoot, func(filePath string, f os.FileInfo, err error) error {
|
return filepath.Walk(contextRoot, func(filePath string, f os.FileInfo, err error) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if os.IsPermission(err) {
|
if os.IsPermission(err) {
|
||||||
return errors.Errorf("can't stat '%s'", filePath)
|
return fmt.Errorf("can't stat '%s'", filePath)
|
||||||
}
|
}
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
return errors.Errorf("file ('%s') not found or excluded by .dockerignore", filePath)
|
return fmt.Errorf("file ('%s') not found or excluded by .dockerignore", filePath)
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -78,7 +78,7 @@ func ValidateContextDirectory(srcPath string, excludes []string) error {
|
||||||
if !f.IsDir() {
|
if !f.IsDir() {
|
||||||
currentFile, err := os.Open(filePath)
|
currentFile, err := os.Open(filePath)
|
||||||
if err != nil && os.IsPermission(err) {
|
if err != nil && os.IsPermission(err) {
|
||||||
return errors.Errorf("no permission to read from '%s'", filePath)
|
return fmt.Errorf("no permission to read from '%s'", filePath)
|
||||||
}
|
}
|
||||||
currentFile.Close()
|
currentFile.Close()
|
||||||
}
|
}
|
||||||
|
@ -105,7 +105,7 @@ func DetectArchiveReader(input io.ReadCloser) (rc io.ReadCloser, isArchive bool,
|
||||||
|
|
||||||
magic, err := buf.Peek(archiveHeaderSize * 2)
|
magic, err := buf.Peek(archiveHeaderSize * 2)
|
||||||
if err != nil && err != io.EOF {
|
if err != nil && err != io.EOF {
|
||||||
return nil, false, errors.Errorf("failed to peek context header from STDIN: %v", err)
|
return nil, false, fmt.Errorf("failed to peek context header from STDIN: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return ioutils.NewReadCloserWrapper(buf, func() error { return input.Close() }), IsArchive(magic), nil
|
return ioutils.NewReadCloserWrapper(buf, func() error { return input.Close() }), IsArchive(magic), nil
|
||||||
|
@ -118,7 +118,7 @@ func WriteTempDockerfile(rc io.ReadCloser) (dockerfileDir string, err error) {
|
||||||
// err is a named return value, due to the defer call below.
|
// err is a named return value, due to the defer call below.
|
||||||
dockerfileDir, err = os.MkdirTemp("", "docker-build-tempdockerfile-")
|
dockerfileDir, err = os.MkdirTemp("", "docker-build-tempdockerfile-")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", errors.Errorf("unable to create temporary context directory: %v", err)
|
return "", fmt.Errorf("unable to create temporary context directory: %v", err)
|
||||||
}
|
}
|
||||||
defer func() {
|
defer func() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -195,11 +195,11 @@ func IsArchive(header []byte) bool {
|
||||||
// success.
|
// success.
|
||||||
func GetContextFromGitURL(gitURL, dockerfileName string) (string, string, error) {
|
func GetContextFromGitURL(gitURL, dockerfileName string) (string, string, error) {
|
||||||
if _, err := exec.LookPath("git"); err != nil {
|
if _, err := exec.LookPath("git"); err != nil {
|
||||||
return "", "", errors.Wrapf(err, "unable to find 'git'")
|
return "", "", fmt.Errorf("unable to find 'git': %w", err)
|
||||||
}
|
}
|
||||||
absContextDir, err := git.Clone(gitURL)
|
absContextDir, err := git.Clone(gitURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", errors.Wrapf(err, "unable to 'git clone' to temporary context directory")
|
return "", "", fmt.Errorf("unable to 'git clone' to temporary context directory: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
absContextDir, err = ResolveAndValidateContextPath(absContextDir)
|
absContextDir, err = ResolveAndValidateContextPath(absContextDir)
|
||||||
|
@ -208,7 +208,7 @@ func GetContextFromGitURL(gitURL, dockerfileName string) (string, string, error)
|
||||||
}
|
}
|
||||||
relDockerfile, err := getDockerfileRelPath(absContextDir, dockerfileName)
|
relDockerfile, err := getDockerfileRelPath(absContextDir, dockerfileName)
|
||||||
if err == nil && strings.HasPrefix(relDockerfile, ".."+string(filepath.Separator)) {
|
if err == nil && strings.HasPrefix(relDockerfile, ".."+string(filepath.Separator)) {
|
||||||
return "", "", errors.Errorf("the Dockerfile (%s) must be within the build context", dockerfileName)
|
return "", "", fmt.Errorf("the Dockerfile (%s) must be within the build context", dockerfileName)
|
||||||
}
|
}
|
||||||
|
|
||||||
return absContextDir, relDockerfile, err
|
return absContextDir, relDockerfile, err
|
||||||
|
@ -221,7 +221,7 @@ func GetContextFromGitURL(gitURL, dockerfileName string) (string, string, error)
|
||||||
func GetContextFromURL(out io.Writer, remoteURL, dockerfileName string) (io.ReadCloser, string, error) {
|
func GetContextFromURL(out io.Writer, remoteURL, dockerfileName string) (io.ReadCloser, string, error) {
|
||||||
response, err := getWithStatusError(remoteURL)
|
response, err := getWithStatusError(remoteURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, "", errors.Errorf("unable to download remote context %s: %v", remoteURL, err)
|
return nil, "", fmt.Errorf("unable to download remote context %s: %v", remoteURL, err)
|
||||||
}
|
}
|
||||||
progressOutput := streamformatter.NewProgressOutput(out)
|
progressOutput := streamformatter.NewProgressOutput(out)
|
||||||
|
|
||||||
|
@ -245,9 +245,9 @@ func getWithStatusError(url string) (resp *http.Response, err error) {
|
||||||
body, err := io.ReadAll(resp.Body)
|
body, err := io.ReadAll(resp.Body)
|
||||||
resp.Body.Close()
|
resp.Body.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "%s: error reading body", msg)
|
return nil, fmt.Errorf("%s: error reading body: %w", msg, err)
|
||||||
}
|
}
|
||||||
return nil, errors.Errorf("%s: %s", msg, bytes.TrimSpace(body))
|
return nil, fmt.Errorf("%s: %s", msg, bytes.TrimSpace(body))
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetContextFromLocalDir uses the given local directory as context for a
|
// GetContextFromLocalDir uses the given local directory as context for a
|
||||||
|
@ -265,7 +265,7 @@ func GetContextFromLocalDir(localDir, dockerfileName string) (string, string, er
|
||||||
// current directory and not the context directory.
|
// current directory and not the context directory.
|
||||||
if dockerfileName != "" && dockerfileName != "-" {
|
if dockerfileName != "" && dockerfileName != "-" {
|
||||||
if dockerfileName, err = filepath.Abs(dockerfileName); err != nil {
|
if dockerfileName, err = filepath.Abs(dockerfileName); err != nil {
|
||||||
return "", "", errors.Errorf("unable to get absolute path to Dockerfile: %v", err)
|
return "", "", fmt.Errorf("unable to get absolute path to Dockerfile: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -278,7 +278,7 @@ func GetContextFromLocalDir(localDir, dockerfileName string) (string, string, er
|
||||||
func ResolveAndValidateContextPath(givenContextDir string) (string, error) {
|
func ResolveAndValidateContextPath(givenContextDir string) (string, error) {
|
||||||
absContextDir, err := filepath.Abs(givenContextDir)
|
absContextDir, err := filepath.Abs(givenContextDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", errors.Errorf("unable to get absolute context directory of given context directory %q: %v", givenContextDir, err)
|
return "", fmt.Errorf("unable to get absolute context directory of given context directory %q: %v", givenContextDir, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// The context dir might be a symbolic link, so follow it to the actual
|
// The context dir might be a symbolic link, so follow it to the actual
|
||||||
|
@ -291,17 +291,17 @@ func ResolveAndValidateContextPath(givenContextDir string) (string, error) {
|
||||||
if !isUNC(absContextDir) {
|
if !isUNC(absContextDir) {
|
||||||
absContextDir, err = filepath.EvalSymlinks(absContextDir)
|
absContextDir, err = filepath.EvalSymlinks(absContextDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", errors.Errorf("unable to evaluate symlinks in context path: %v", err)
|
return "", fmt.Errorf("unable to evaluate symlinks in context path: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stat, err := os.Lstat(absContextDir)
|
stat, err := os.Lstat(absContextDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", errors.Errorf("unable to stat context directory %q: %v", absContextDir, err)
|
return "", fmt.Errorf("unable to stat context directory %q: %v", absContextDir, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !stat.IsDir() {
|
if !stat.IsDir() {
|
||||||
return "", errors.Errorf("context must be a directory: %s", absContextDir)
|
return "", fmt.Errorf("context must be a directory: %s", absContextDir)
|
||||||
}
|
}
|
||||||
return absContextDir, err
|
return absContextDir, err
|
||||||
}
|
}
|
||||||
|
@ -346,20 +346,20 @@ func getDockerfileRelPath(absContextDir, givenDockerfile string) (string, error)
|
||||||
if !isUNC(absDockerfile) {
|
if !isUNC(absDockerfile) {
|
||||||
absDockerfile, err = filepath.EvalSymlinks(absDockerfile)
|
absDockerfile, err = filepath.EvalSymlinks(absDockerfile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", errors.Errorf("unable to evaluate symlinks in Dockerfile path: %v", err)
|
return "", fmt.Errorf("unable to evaluate symlinks in Dockerfile path: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := os.Lstat(absDockerfile); err != nil {
|
if _, err := os.Lstat(absDockerfile); err != nil {
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
return "", errors.Errorf("Cannot locate Dockerfile: %q", absDockerfile)
|
return "", fmt.Errorf("Cannot locate Dockerfile: %q", absDockerfile)
|
||||||
}
|
}
|
||||||
return "", errors.Errorf("unable to stat Dockerfile: %v", err)
|
return "", fmt.Errorf("unable to stat Dockerfile: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
relDockerfile, err := filepath.Rel(absContextDir, absDockerfile)
|
relDockerfile, err := filepath.Rel(absContextDir, absDockerfile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", errors.Errorf("unable to get relative Dockerfile path: %v", err)
|
return "", fmt.Errorf("unable to get relative Dockerfile path: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return relDockerfile, nil
|
return relDockerfile, nil
|
||||||
|
@ -435,7 +435,7 @@ func Compress(buildCtx io.ReadCloser) (io.ReadCloser, error) {
|
||||||
defer buildCtx.Close()
|
defer buildCtx.Close()
|
||||||
|
|
||||||
if _, err := pools.Copy(compressWriter, buildCtx); err != nil {
|
if _, err := pools.Copy(compressWriter, buildCtx); err != nil {
|
||||||
pipeWriter.CloseWithError(errors.Wrap(err, "failed to compress context"))
|
pipeWriter.CloseWithError(fmt.Errorf("failed to compress context: %w", err))
|
||||||
compressWriter.Close()
|
compressWriter.Close()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ import (
|
||||||
|
|
||||||
"github.com/docker/cli/internal/test"
|
"github.com/docker/cli/internal/test"
|
||||||
"github.com/docker/docker/api/types/image"
|
"github.com/docker/docker/api/types/image"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"gotest.tools/v3/assert"
|
"gotest.tools/v3/assert"
|
||||||
"gotest.tools/v3/golden"
|
"gotest.tools/v3/golden"
|
||||||
)
|
)
|
||||||
|
@ -30,7 +30,7 @@ func TestNewHistoryCommandErrors(t *testing.T) {
|
||||||
args: []string{"image:tag"},
|
args: []string{"image:tag"},
|
||||||
expectedError: "something went wrong",
|
expectedError: "something went wrong",
|
||||||
imageHistoryFunc: func(img string, options image.HistoryOptions) ([]image.HistoryResponseItem, error) {
|
imageHistoryFunc: func(img string, options image.HistoryOptions) ([]image.HistoryResponseItem, error) {
|
||||||
return []image.HistoryResponseItem{{}}, errors.Errorf("something went wrong")
|
return []image.HistoryResponseItem{{}}, fmt.Errorf("something went wrong")
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
package image
|
package image
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/docker/cli/internal/test"
|
"github.com/docker/cli/internal/test"
|
||||||
"github.com/docker/docker/api/types/image"
|
"github.com/docker/docker/api/types/image"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"gotest.tools/v3/assert"
|
"gotest.tools/v3/assert"
|
||||||
is "gotest.tools/v3/assert/cmp"
|
is "gotest.tools/v3/assert/cmp"
|
||||||
)
|
)
|
||||||
|
@ -29,7 +30,7 @@ func TestNewImportCommandErrors(t *testing.T) {
|
||||||
args: []string{"testdata/import-command-success.input.txt"},
|
args: []string{"testdata/import-command-success.input.txt"},
|
||||||
expectedError: "something went wrong",
|
expectedError: "something went wrong",
|
||||||
imageImportFunc: func(source image.ImportSource, ref string, options image.ImportOptions) (io.ReadCloser, error) {
|
imageImportFunc: func(source image.ImportSource, ref string, options image.ImportOptions) (io.ReadCloser, error) {
|
||||||
return nil, errors.Errorf("something went wrong")
|
return nil, fmt.Errorf("something went wrong")
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ import (
|
||||||
"github.com/docker/cli/cli/config/configfile"
|
"github.com/docker/cli/cli/config/configfile"
|
||||||
"github.com/docker/cli/internal/test"
|
"github.com/docker/cli/internal/test"
|
||||||
"github.com/docker/docker/api/types/image"
|
"github.com/docker/docker/api/types/image"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"gotest.tools/v3/assert"
|
"gotest.tools/v3/assert"
|
||||||
is "gotest.tools/v3/assert/cmp"
|
is "gotest.tools/v3/assert/cmp"
|
||||||
"gotest.tools/v3/golden"
|
"gotest.tools/v3/golden"
|
||||||
|
@ -30,7 +30,7 @@ func TestNewImagesCommandErrors(t *testing.T) {
|
||||||
name: "failed-list",
|
name: "failed-list",
|
||||||
expectedError: "something went wrong",
|
expectedError: "something went wrong",
|
||||||
imageListFunc: func(options image.ListOptions) ([]image.Summary, error) {
|
imageListFunc: func(options image.ListOptions) ([]image.Summary, error) {
|
||||||
return []image.Summary{}, errors.Errorf("something went wrong")
|
return []image.Summary{}, fmt.Errorf("something went wrong")
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package image
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/docker/cli/cli"
|
"github.com/docker/cli/cli"
|
||||||
|
@ -10,7 +11,7 @@ import (
|
||||||
"github.com/docker/docker/api/types/image"
|
"github.com/docker/docker/api/types/image"
|
||||||
"github.com/docker/docker/pkg/jsonmessage"
|
"github.com/docker/docker/pkg/jsonmessage"
|
||||||
"github.com/moby/sys/sequential"
|
"github.com/moby/sys/sequential"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -60,7 +61,7 @@ func runLoad(ctx context.Context, dockerCli command.Cli, opts loadOptions) error
|
||||||
// To avoid getting stuck, verify that a tar file is given either in
|
// To avoid getting stuck, verify that a tar file is given either in
|
||||||
// the input flag or through stdin and if not display an error message and exit.
|
// the input flag or through stdin and if not display an error message and exit.
|
||||||
if opts.input == "" && dockerCli.In().IsTerminal() {
|
if opts.input == "" && dockerCli.In().IsTerminal() {
|
||||||
return errors.Errorf("requested load from stdin, but stdin is empty")
|
return fmt.Errorf("requested load from stdin, but stdin is empty")
|
||||||
}
|
}
|
||||||
|
|
||||||
var loadOpts image.LoadOptions
|
var loadOpts image.LoadOptions
|
||||||
|
|
|
@ -8,7 +8,7 @@ import (
|
||||||
|
|
||||||
"github.com/docker/cli/internal/test"
|
"github.com/docker/cli/internal/test"
|
||||||
"github.com/docker/docker/api/types/image"
|
"github.com/docker/docker/api/types/image"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"gotest.tools/v3/assert"
|
"gotest.tools/v3/assert"
|
||||||
"gotest.tools/v3/golden"
|
"gotest.tools/v3/golden"
|
||||||
)
|
)
|
||||||
|
@ -37,7 +37,7 @@ func TestNewLoadCommandErrors(t *testing.T) {
|
||||||
args: []string{},
|
args: []string{},
|
||||||
expectedError: "something went wrong",
|
expectedError: "something went wrong",
|
||||||
imageLoadFunc: func(input io.Reader, options image.LoadOptions) (image.LoadResponse, error) {
|
imageLoadFunc: func(input io.Reader, options image.LoadOptions) (image.LoadResponse, error) {
|
||||||
return image.LoadResponse{}, errors.Errorf("something went wrong")
|
return image.LoadResponse{}, fmt.Errorf("something went wrong")
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package image
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -12,7 +13,7 @@ import (
|
||||||
"github.com/docker/cli/opts"
|
"github.com/docker/cli/opts"
|
||||||
"github.com/docker/docker/errdefs"
|
"github.com/docker/docker/errdefs"
|
||||||
units "github.com/docker/go-units"
|
units "github.com/docker/go-units"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ package image
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -11,7 +12,7 @@ import (
|
||||||
"github.com/docker/cli/internal/test"
|
"github.com/docker/cli/internal/test"
|
||||||
"github.com/docker/docker/api/types/filters"
|
"github.com/docker/docker/api/types/filters"
|
||||||
"github.com/docker/docker/api/types/image"
|
"github.com/docker/docker/api/types/image"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"gotest.tools/v3/assert"
|
"gotest.tools/v3/assert"
|
||||||
is "gotest.tools/v3/assert/cmp"
|
is "gotest.tools/v3/assert/cmp"
|
||||||
"gotest.tools/v3/golden"
|
"gotest.tools/v3/golden"
|
||||||
|
@ -34,7 +35,7 @@ func TestNewPruneCommandErrors(t *testing.T) {
|
||||||
args: []string{"--force"},
|
args: []string{"--force"},
|
||||||
expectedError: "something went wrong",
|
expectedError: "something went wrong",
|
||||||
imagesPruneFunc: func(pruneFilter filters.Args) (image.PruneReport, error) {
|
imagesPruneFunc: func(pruneFilter filters.Args) (image.PruneReport, error) {
|
||||||
return image.PruneReport{}, errors.Errorf("something went wrong")
|
return image.PruneReport{}, fmt.Errorf("something went wrong")
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package image
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
@ -10,7 +11,7 @@ import (
|
||||||
"github.com/docker/cli/cli/command"
|
"github.com/docker/cli/cli/command"
|
||||||
"github.com/docker/cli/cli/command/completion"
|
"github.com/docker/cli/cli/command/completion"
|
||||||
"github.com/docker/cli/cli/trust"
|
"github.com/docker/cli/cli/trust"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ package image
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -23,7 +24,7 @@ import (
|
||||||
"github.com/docker/docker/registry"
|
"github.com/docker/docker/registry"
|
||||||
"github.com/morikuni/aec"
|
"github.com/morikuni/aec"
|
||||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
package image
|
package image
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/docker/cli/internal/test"
|
"github.com/docker/cli/internal/test"
|
||||||
"github.com/docker/docker/api/types/image"
|
"github.com/docker/docker/api/types/image"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"gotest.tools/v3/assert"
|
"gotest.tools/v3/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -33,7 +34,7 @@ func TestNewPushCommandErrors(t *testing.T) {
|
||||||
args: []string{"image:repo"},
|
args: []string{"image:repo"},
|
||||||
expectedError: "Failed to push",
|
expectedError: "Failed to push",
|
||||||
imagePushFunc: func(ref string, options image.PushOptions) (io.ReadCloser, error) {
|
imagePushFunc: func(ref string, options image.PushOptions) (io.ReadCloser, error) {
|
||||||
return io.NopCloser(strings.NewReader("")), errors.Errorf("Failed to push")
|
return io.NopCloser(strings.NewReader("")), fmt.Errorf("Failed to push")
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package image
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
@ -10,7 +11,7 @@ import (
|
||||||
"github.com/docker/cli/cli/command/completion"
|
"github.com/docker/cli/cli/command/completion"
|
||||||
"github.com/docker/docker/api/types/image"
|
"github.com/docker/docker/api/types/image"
|
||||||
"github.com/docker/docker/errdefs"
|
"github.com/docker/docker/errdefs"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ import (
|
||||||
|
|
||||||
"github.com/docker/cli/internal/test"
|
"github.com/docker/cli/internal/test"
|
||||||
"github.com/docker/docker/api/types/image"
|
"github.com/docker/docker/api/types/image"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"gotest.tools/v3/assert"
|
"gotest.tools/v3/assert"
|
||||||
is "gotest.tools/v3/assert/cmp"
|
is "gotest.tools/v3/assert/cmp"
|
||||||
"gotest.tools/v3/golden"
|
"gotest.tools/v3/golden"
|
||||||
|
@ -47,7 +47,7 @@ func TestNewRemoveCommandErrors(t *testing.T) {
|
||||||
expectedError: "error removing image",
|
expectedError: "error removing image",
|
||||||
imageRemoveFunc: func(img string, options image.RemoveOptions) ([]image.DeleteResponse, error) {
|
imageRemoveFunc: func(img string, options image.RemoveOptions) ([]image.DeleteResponse, error) {
|
||||||
assert.Check(t, is.Equal("image1", img))
|
assert.Check(t, is.Equal("image1", img))
|
||||||
return []image.DeleteResponse{}, errors.Errorf("error removing image")
|
return []image.DeleteResponse{}, fmt.Errorf("error removing image")
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -57,7 +57,7 @@ func TestNewRemoveCommandErrors(t *testing.T) {
|
||||||
imageRemoveFunc: func(img string, options image.RemoveOptions) ([]image.DeleteResponse, error) {
|
imageRemoveFunc: func(img string, options image.RemoveOptions) ([]image.DeleteResponse, error) {
|
||||||
assert.Check(t, !options.Force)
|
assert.Check(t, !options.Force)
|
||||||
assert.Check(t, options.PruneChildren)
|
assert.Check(t, options.PruneChildren)
|
||||||
return []image.DeleteResponse{}, errors.Errorf("error removing image")
|
return []image.DeleteResponse{}, fmt.Errorf("error removing image")
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,13 +2,15 @@ package image
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/docker/cli/cli"
|
"github.com/docker/cli/cli"
|
||||||
"github.com/docker/cli/cli/command"
|
"github.com/docker/cli/cli/command"
|
||||||
"github.com/docker/cli/cli/command/completion"
|
"github.com/docker/cli/cli/command/completion"
|
||||||
"github.com/docker/docker/api/types/image"
|
"github.com/docker/docker/api/types/image"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -49,7 +51,7 @@ func RunSave(ctx context.Context, dockerCli command.Cli, opts saveOptions) error
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := command.ValidateOutputPath(opts.output); err != nil {
|
if err := command.ValidateOutputPath(opts.output); err != nil {
|
||||||
return errors.Wrap(err, "failed to save image")
|
return fmt.Errorf("failed to save image: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
responseBody, err := dockerCli.Client().ImageSave(ctx, opts.images, image.SaveOptions{})
|
responseBody, err := dockerCli.Client().ImageSave(ctx, opts.images, image.SaveOptions{})
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package image
|
package image
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -8,7 +9,7 @@ import (
|
||||||
|
|
||||||
"github.com/docker/cli/internal/test"
|
"github.com/docker/cli/internal/test"
|
||||||
"github.com/docker/docker/api/types/image"
|
"github.com/docker/docker/api/types/image"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"gotest.tools/v3/assert"
|
"gotest.tools/v3/assert"
|
||||||
is "gotest.tools/v3/assert/cmp"
|
is "gotest.tools/v3/assert/cmp"
|
||||||
)
|
)
|
||||||
|
@ -38,7 +39,7 @@ func TestNewSaveCommandErrors(t *testing.T) {
|
||||||
isTerminal: false,
|
isTerminal: false,
|
||||||
expectedError: "error saving image",
|
expectedError: "error saving image",
|
||||||
imageSaveFunc: func(images []string, options image.SaveOptions) (io.ReadCloser, error) {
|
imageSaveFunc: func(images []string, options image.SaveOptions) (io.ReadCloser, error) {
|
||||||
return io.NopCloser(strings.NewReader("")), errors.Errorf("error saving image")
|
return io.NopCloser(strings.NewReader("")), fmt.Errorf("error saving image")
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"sort"
|
"sort"
|
||||||
|
@ -18,7 +19,7 @@ import (
|
||||||
"github.com/docker/docker/pkg/jsonmessage"
|
"github.com/docker/docker/pkg/jsonmessage"
|
||||||
"github.com/docker/docker/registry"
|
"github.com/docker/docker/registry"
|
||||||
"github.com/opencontainers/go-digest"
|
"github.com/opencontainers/go-digest"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/theupdateframework/notary/client"
|
"github.com/theupdateframework/notary/client"
|
||||||
"github.com/theupdateframework/notary/tuf/data"
|
"github.com/theupdateframework/notary/tuf/data"
|
||||||
|
@ -96,18 +97,18 @@ func PushTrustedReference(ioStreams command.Streams, repoInfo *registry.Reposito
|
||||||
}
|
}
|
||||||
|
|
||||||
if cnt > 1 {
|
if cnt > 1 {
|
||||||
return errors.Errorf("internal error: only one call to handleTarget expected")
|
return fmt.Errorf("internal error: only one call to handleTarget expected")
|
||||||
}
|
}
|
||||||
|
|
||||||
if target == nil {
|
if target == nil {
|
||||||
return errors.Errorf("no targets found, provide a specific tag in order to sign it")
|
return fmt.Errorf("no targets found, provide a specific tag in order to sign it")
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Fprintln(ioStreams.Out(), "Signing and pushing trust metadata")
|
fmt.Fprintln(ioStreams.Out(), "Signing and pushing trust metadata")
|
||||||
|
|
||||||
repo, err := trust.GetNotaryRepository(ioStreams.In(), ioStreams.Out(), command.UserAgent(), repoInfo, &authConfig, "push", "pull")
|
repo, err := trust.GetNotaryRepository(ioStreams.In(), ioStreams.Out(), command.UserAgent(), repoInfo, &authConfig, "push", "pull")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "error establishing connection to trust repository")
|
return fmt.Errorf("error establishing connection to trust repository: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the latest repository metadata so we can figure out which roles to sign
|
// get the latest repository metadata so we can figure out which roles to sign
|
||||||
|
@ -147,7 +148,7 @@ func PushTrustedReference(ioStreams command.Streams, repoInfo *registry.Reposito
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = errors.Wrapf(err, "failed to sign %s:%s", repoInfo.Name.Name(), tag)
|
err = fmt.Errorf("failed to sign %s:%s: %w", repoInfo.Name.Name(), tag, err)
|
||||||
return trust.NotaryError(repoInfo.Name.Name(), err)
|
return trust.NotaryError(repoInfo.Name.Name(), err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -215,7 +216,7 @@ func trustedPull(ctx context.Context, cli command.Cli, imgRefAndAuth trust.Image
|
||||||
func getTrustedPullTargets(cli command.Cli, imgRefAndAuth trust.ImageRefAndAuth) ([]target, error) {
|
func getTrustedPullTargets(cli command.Cli, imgRefAndAuth trust.ImageRefAndAuth) ([]target, error) {
|
||||||
notaryRepo, err := cli.NotaryClient(imgRefAndAuth, trust.ActionsPullOnly)
|
notaryRepo, err := cli.NotaryClient(imgRefAndAuth, trust.ActionsPullOnly)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "error establishing connection to trust repository")
|
return nil, fmt.Errorf("error establishing connection to trust repository: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
ref := imgRefAndAuth.Reference()
|
ref := imgRefAndAuth.Reference()
|
||||||
|
@ -241,7 +242,7 @@ func getTrustedPullTargets(cli command.Cli, imgRefAndAuth trust.ImageRefAndAuth)
|
||||||
refs = append(refs, t)
|
refs = append(refs, t)
|
||||||
}
|
}
|
||||||
if len(refs) == 0 {
|
if len(refs) == 0 {
|
||||||
return nil, trust.NotaryError(ref.Name(), errors.Errorf("No trusted tags for %s", ref.Name()))
|
return nil, trust.NotaryError(ref.Name(), fmt.Errorf("No trusted tags for %s", ref.Name()))
|
||||||
}
|
}
|
||||||
return refs, nil
|
return refs, nil
|
||||||
}
|
}
|
||||||
|
@ -253,7 +254,7 @@ func getTrustedPullTargets(cli command.Cli, imgRefAndAuth trust.ImageRefAndAuth)
|
||||||
// Only get the tag if it's in the top level targets role or the releases delegation role
|
// Only get the tag if it's in the top level targets role or the releases delegation role
|
||||||
// ignore it if it's in any other delegation roles
|
// ignore it if it's in any other delegation roles
|
||||||
if t.Role != trust.ReleasesRole && t.Role != data.CanonicalTargetsRole {
|
if t.Role != trust.ReleasesRole && t.Role != data.CanonicalTargetsRole {
|
||||||
return nil, trust.NotaryError(ref.Name(), errors.Errorf("No trust data for %s", tagged.Tag()))
|
return nil, trust.NotaryError(ref.Name(), fmt.Errorf("No trust data for %s", tagged.Tag()))
|
||||||
}
|
}
|
||||||
|
|
||||||
logrus.Debugf("retrieving target for %s role", t.Role)
|
logrus.Debugf("retrieving target for %s role", t.Role)
|
||||||
|
@ -295,7 +296,7 @@ func TrustedReference(ctx context.Context, cli command.Cli, ref reference.NamedT
|
||||||
|
|
||||||
notaryRepo, err := cli.NotaryClient(imgRefAndAuth, []string{"pull"})
|
notaryRepo, err := cli.NotaryClient(imgRefAndAuth, []string{"pull"})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "error establishing connection to trust repository")
|
return nil, fmt.Errorf("error establishing connection to trust repository: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
t, err := notaryRepo.GetTargetByName(ref.Tag(), trust.ReleasesRole, data.CanonicalTargetsRole)
|
t, err := notaryRepo.GetTargetByName(ref.Tag(), trust.ReleasesRole, data.CanonicalTargetsRole)
|
||||||
|
|
|
@ -6,13 +6,14 @@ package inspect
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"strings"
|
"strings"
|
||||||
"text/template"
|
"text/template"
|
||||||
|
|
||||||
"github.com/docker/cli/cli"
|
"github.com/docker/cli/cli"
|
||||||
"github.com/docker/cli/templates"
|
"github.com/docker/cli/templates"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -53,7 +54,7 @@ func NewTemplateInspectorFromString(out io.Writer, tmplStr string) (Inspector, e
|
||||||
|
|
||||||
tmpl, err := templates.Parse(tmplStr)
|
tmpl, err := templates.Parse(tmplStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Errorf("template parsing error: %s", err)
|
return nil, fmt.Errorf("template parsing error: %s", err)
|
||||||
}
|
}
|
||||||
return NewTemplateInspector(out, tmpl), nil
|
return NewTemplateInspector(out, tmpl), nil
|
||||||
}
|
}
|
||||||
|
@ -103,7 +104,7 @@ func (i *TemplateInspector) Inspect(typedElement any, rawElement []byte) error {
|
||||||
buffer := new(bytes.Buffer)
|
buffer := new(bytes.Buffer)
|
||||||
if err := i.tmpl.Execute(buffer, typedElement); err != nil {
|
if err := i.tmpl.Execute(buffer, typedElement); err != nil {
|
||||||
if rawElement == nil {
|
if rawElement == nil {
|
||||||
return errors.Errorf("template parsing error: %v", err)
|
return fmt.Errorf("template parsing error: %v", err)
|
||||||
}
|
}
|
||||||
return i.tryRawInspectFallback(rawElement)
|
return i.tryRawInspectFallback(rawElement)
|
||||||
}
|
}
|
||||||
|
@ -122,12 +123,12 @@ func (i *TemplateInspector) tryRawInspectFallback(rawElement []byte) error {
|
||||||
dec.UseNumber()
|
dec.UseNumber()
|
||||||
|
|
||||||
if rawErr := dec.Decode(&raw); rawErr != nil {
|
if rawErr := dec.Decode(&raw); rawErr != nil {
|
||||||
return errors.Errorf("unable to read inspect data: %v", rawErr)
|
return fmt.Errorf("unable to read inspect data: %v", rawErr)
|
||||||
}
|
}
|
||||||
|
|
||||||
tmplMissingKey := i.tmpl.Option("missingkey=error")
|
tmplMissingKey := i.tmpl.Option("missingkey=error")
|
||||||
if rawErr := tmplMissingKey.Execute(buffer, raw); rawErr != nil {
|
if rawErr := tmplMissingKey.Execute(buffer, raw); rawErr != nil {
|
||||||
return errors.Errorf("template parsing error: %v", rawErr)
|
return fmt.Errorf("template parsing error: %v", rawErr)
|
||||||
}
|
}
|
||||||
|
|
||||||
i.buffer.Write(buffer.Bytes())
|
i.buffer.Write(buffer.Bytes())
|
||||||
|
|
|
@ -7,7 +7,7 @@ import (
|
||||||
"github.com/docker/cli/cli/command"
|
"github.com/docker/cli/cli/command"
|
||||||
"github.com/docker/cli/cli/manifest/store"
|
"github.com/docker/cli/cli/manifest/store"
|
||||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -50,11 +50,11 @@ func newAnnotateCommand(dockerCli command.Cli) *cobra.Command {
|
||||||
func runManifestAnnotate(dockerCli command.Cli, opts annotateOptions) error {
|
func runManifestAnnotate(dockerCli command.Cli, opts annotateOptions) error {
|
||||||
targetRef, err := normalizeReference(opts.target)
|
targetRef, err := normalizeReference(opts.target)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrapf(err, "annotate: error parsing name for manifest list %s", opts.target)
|
return fmt.Errorf("annotate: error parsing name for manifest list %s: %w", opts.target, err)
|
||||||
}
|
}
|
||||||
imgRef, err := normalizeReference(opts.image)
|
imgRef, err := normalizeReference(opts.image)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrapf(err, "annotate: error parsing name for manifest %s", opts.image)
|
return fmt.Errorf("annotate: error parsing name for manifest %s: %w", opts.image, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
manifestStore := dockerCli.ManifestStore()
|
manifestStore := dockerCli.ManifestStore()
|
||||||
|
@ -87,7 +87,7 @@ func runManifestAnnotate(dockerCli command.Cli, opts annotateOptions) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if !isValidOSArch(imageManifest.Descriptor.Platform.OS, imageManifest.Descriptor.Platform.Architecture) {
|
if !isValidOSArch(imageManifest.Descriptor.Platform.OS, imageManifest.Descriptor.Platform.Architecture) {
|
||||||
return errors.Errorf("manifest entry for image has unsupported os/arch combination: %s/%s", opts.os, opts.arch)
|
return fmt.Errorf("manifest entry for image has unsupported os/arch combination: %s/%s", opts.os, opts.arch)
|
||||||
}
|
}
|
||||||
return manifestStore.Save(targetRef, imgRef, imageManifest)
|
return manifestStore.Save(targetRef, imgRef, imageManifest)
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ import (
|
||||||
"github.com/docker/cli/cli/command"
|
"github.com/docker/cli/cli/command"
|
||||||
"github.com/docker/cli/cli/manifest/store"
|
"github.com/docker/cli/cli/manifest/store"
|
||||||
"github.com/docker/docker/registry"
|
"github.com/docker/docker/registry"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -39,12 +39,12 @@ func createManifestList(ctx context.Context, dockerCli command.Cli, args []strin
|
||||||
newRef := args[0]
|
newRef := args[0]
|
||||||
targetRef, err := normalizeReference(newRef)
|
targetRef, err := normalizeReference(newRef)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrapf(err, "error parsing name for manifest list %s", newRef)
|
return fmt.Errorf("error parsing name for manifest list %s: %w", newRef, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = registry.ParseRepositoryInfo(targetRef)
|
_, err = registry.ParseRepositoryInfo(targetRef)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrapf(err, "error parsing repository name for manifest list %s", newRef)
|
return fmt.Errorf("error parsing repository name for manifest list %s: %w", newRef, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
manifestStore := dockerCli.ManifestStore()
|
manifestStore := dockerCli.ManifestStore()
|
||||||
|
@ -55,7 +55,7 @@ func createManifestList(ctx context.Context, dockerCli command.Cli, args []strin
|
||||||
case err != nil:
|
case err != nil:
|
||||||
return err
|
return err
|
||||||
case !opts.amend:
|
case !opts.amend:
|
||||||
return errors.Errorf("refusing to amend an existing manifest list with no --amend flag")
|
return fmt.Errorf("refusing to amend an existing manifest list with no --amend flag")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now create the local manifest list transaction by looking up the manifest schemas
|
// Now create the local manifest list transaction by looking up the manifest schemas
|
||||||
|
|
|
@ -2,6 +2,7 @@ package manifest
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
@ -9,7 +10,7 @@ import (
|
||||||
"github.com/docker/cli/cli/manifest/store"
|
"github.com/docker/cli/cli/manifest/store"
|
||||||
manifesttypes "github.com/docker/cli/cli/manifest/types"
|
manifesttypes "github.com/docker/cli/cli/manifest/types"
|
||||||
"github.com/docker/cli/internal/test"
|
"github.com/docker/cli/internal/test"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"gotest.tools/v3/assert"
|
"gotest.tools/v3/assert"
|
||||||
is "gotest.tools/v3/assert/cmp"
|
is "gotest.tools/v3/assert/cmp"
|
||||||
"gotest.tools/v3/golden"
|
"gotest.tools/v3/golden"
|
||||||
|
@ -104,10 +105,10 @@ func TestManifestCreateNoManifest(t *testing.T) {
|
||||||
cli.SetManifestStore(manifestStore)
|
cli.SetManifestStore(manifestStore)
|
||||||
cli.SetRegistryClient(&fakeRegistryClient{
|
cli.SetRegistryClient(&fakeRegistryClient{
|
||||||
getManifestFunc: func(_ context.Context, ref reference.Named) (manifesttypes.ImageManifest, error) {
|
getManifestFunc: func(_ context.Context, ref reference.Named) (manifesttypes.ImageManifest, error) {
|
||||||
return manifesttypes.ImageManifest{}, errors.Errorf("No such image: %v", ref)
|
return manifesttypes.ImageManifest{}, fmt.Errorf("No such image: %v", ref)
|
||||||
},
|
},
|
||||||
getManifestListFunc: func(ctx context.Context, ref reference.Named) ([]manifesttypes.ImageManifest, error) {
|
getManifestListFunc: func(ctx context.Context, ref reference.Named) ([]manifesttypes.ImageManifest, error) {
|
||||||
return nil, errors.Errorf("No such manifest: %s", ref)
|
return nil, fmt.Errorf("No such manifest: %s", ref)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ import (
|
||||||
"github.com/docker/cli/cli/manifest/types"
|
"github.com/docker/cli/cli/manifest/types"
|
||||||
"github.com/docker/distribution/manifest/manifestlist"
|
"github.com/docker/distribution/manifest/manifestlist"
|
||||||
"github.com/docker/docker/registry"
|
"github.com/docker/docker/registry"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -123,7 +123,7 @@ func printManifestList(dockerCli command.Cli, namedRef reference.Named, list []t
|
||||||
for _, img := range list {
|
for _, img := range list {
|
||||||
mfd, err := buildManifestDescriptor(targetRepo, img)
|
mfd, err := buildManifestDescriptor(targetRepo, img)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "failed to assemble ManifestDescriptor")
|
return fmt.Errorf("failed to assemble ManifestDescriptor: %w", err)
|
||||||
}
|
}
|
||||||
manifests = append(manifests, mfd)
|
manifests = append(manifests, mfd)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,8 @@ package manifest
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
@ -13,7 +15,7 @@ import (
|
||||||
"github.com/docker/distribution/manifest/schema2"
|
"github.com/docker/distribution/manifest/schema2"
|
||||||
"github.com/opencontainers/go-digest"
|
"github.com/opencontainers/go-digest"
|
||||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"gotest.tools/v3/assert"
|
"gotest.tools/v3/assert"
|
||||||
is "gotest.tools/v3/assert/cmp"
|
is "gotest.tools/v3/assert/cmp"
|
||||||
"gotest.tools/v3/golden"
|
"gotest.tools/v3/golden"
|
||||||
|
@ -86,7 +88,7 @@ func TestInspectCommandNotFound(t *testing.T) {
|
||||||
return types.ImageManifest{}, errors.New("missing")
|
return types.ImageManifest{}, errors.New("missing")
|
||||||
},
|
},
|
||||||
getManifestListFunc: func(ctx context.Context, ref reference.Named) ([]types.ImageManifest, error) {
|
getManifestListFunc: func(ctx context.Context, ref reference.Named) ([]types.ImageManifest, error) {
|
||||||
return nil, errors.Errorf("No such manifest: %s", ref)
|
return nil, fmt.Errorf("No such manifest: %s", ref)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ import (
|
||||||
"github.com/docker/distribution/manifest/ocischema"
|
"github.com/docker/distribution/manifest/ocischema"
|
||||||
"github.com/docker/distribution/manifest/schema2"
|
"github.com/docker/distribution/manifest/schema2"
|
||||||
"github.com/docker/docker/registry"
|
"github.com/docker/docker/registry"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ func runPush(ctx context.Context, dockerCli command.Cli, opts pushOpts) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if len(manifests) == 0 {
|
if len(manifests) == 0 {
|
||||||
return errors.Errorf("%s not found", targetRef)
|
return fmt.Errorf("%s not found", targetRef)
|
||||||
}
|
}
|
||||||
|
|
||||||
req, err := buildPushRequest(manifests, targetRef, opts.insecure)
|
req, err := buildPushRequest(manifests, targetRef, opts.insecure)
|
||||||
|
@ -144,7 +144,7 @@ func buildManifestList(manifests []types.ImageManifest, targetRef reference.Name
|
||||||
if imageManifest.Descriptor.Platform == nil ||
|
if imageManifest.Descriptor.Platform == nil ||
|
||||||
imageManifest.Descriptor.Platform.Architecture == "" ||
|
imageManifest.Descriptor.Platform.Architecture == "" ||
|
||||||
imageManifest.Descriptor.Platform.OS == "" {
|
imageManifest.Descriptor.Platform.OS == "" {
|
||||||
return nil, errors.Errorf(
|
return nil, fmt.Errorf(
|
||||||
"manifest %s must have an OS and Architecture to be pushed to a registry", imageManifest.Ref)
|
"manifest %s must have an OS and Architecture to be pushed to a registry", imageManifest.Ref)
|
||||||
}
|
}
|
||||||
descriptor, err := buildManifestDescriptor(targetRepoInfo, imageManifest)
|
descriptor, err := buildManifestDescriptor(targetRepoInfo, imageManifest)
|
||||||
|
@ -166,7 +166,7 @@ func buildManifestDescriptor(targetRepo *registry.RepositoryInfo, imageManifest
|
||||||
manifestRepoHostname := reference.Domain(repoInfo.Name)
|
manifestRepoHostname := reference.Domain(repoInfo.Name)
|
||||||
targetRepoHostname := reference.Domain(targetRepo.Name)
|
targetRepoHostname := reference.Domain(targetRepo.Name)
|
||||||
if manifestRepoHostname != targetRepoHostname {
|
if manifestRepoHostname != targetRepoHostname {
|
||||||
return manifestlist.ManifestDescriptor{}, errors.Errorf("cannot use source images from a different registry than the target image: %s != %s", manifestRepoHostname, targetRepoHostname)
|
return manifestlist.ManifestDescriptor{}, fmt.Errorf("cannot use source images from a different registry than the target image: %s != %s", manifestRepoHostname, targetRepoHostname)
|
||||||
}
|
}
|
||||||
|
|
||||||
manifest := manifestlist.ManifestDescriptor{
|
manifest := manifestlist.ManifestDescriptor{
|
||||||
|
@ -183,8 +183,9 @@ func buildManifestDescriptor(targetRepo *registry.RepositoryInfo, imageManifest
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = manifest.Descriptor.Digest.Validate(); err != nil {
|
if err = manifest.Descriptor.Digest.Validate(); err != nil {
|
||||||
return manifestlist.ManifestDescriptor{}, errors.Wrapf(err,
|
return manifestlist.ManifestDescriptor{}, fmt.Errorf(
|
||||||
"digest parse of image %q failed", imageManifest.Ref)
|
"digest parse of image %q failed: %w", imageManifest.Ref, err,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return manifest, nil
|
return manifest, nil
|
||||||
|
@ -236,7 +237,7 @@ func buildPutManifestRequest(imageManifest types.ImageManifest, targetRef refere
|
||||||
|
|
||||||
dig := imageManifest.Descriptor.Digest
|
dig := imageManifest.Descriptor.Digest
|
||||||
if dig2 := dig.Algorithm().FromBytes(dt); dig != dig2 {
|
if dig2 := dig.Algorithm().FromBytes(dt); dig != dig2 {
|
||||||
return mountRequest{}, errors.Errorf("internal digest mismatch for %s: expected %s, got %s", imageManifest.Ref, dig, dig2)
|
return mountRequest{}, fmt.Errorf("internal digest mismatch for %s: expected %s, got %s", imageManifest.Ref, dig, dig2)
|
||||||
}
|
}
|
||||||
|
|
||||||
var manifest schema2.DeserializedManifest
|
var manifest schema2.DeserializedManifest
|
||||||
|
@ -255,7 +256,7 @@ func buildPutManifestRequest(imageManifest types.ImageManifest, targetRef refere
|
||||||
|
|
||||||
dig := imageManifest.Descriptor.Digest
|
dig := imageManifest.Descriptor.Digest
|
||||||
if dig2 := dig.Algorithm().FromBytes(dt); dig != dig2 {
|
if dig2 := dig.Algorithm().FromBytes(dt); dig != dig2 {
|
||||||
return mountRequest{}, errors.Errorf("internal digest mismatch for %s: expected %s, got %s", imageManifest.Ref, dig, dig2)
|
return mountRequest{}, fmt.Errorf("internal digest mismatch for %s: expected %s, got %s", imageManifest.Ref, dig, dig2)
|
||||||
}
|
}
|
||||||
|
|
||||||
var manifest ocischema.DeserializedManifest
|
var manifest ocischema.DeserializedManifest
|
||||||
|
|
|
@ -2,6 +2,8 @@ package manifest
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
@ -9,7 +11,7 @@ import (
|
||||||
"github.com/docker/cli/cli/manifest/store"
|
"github.com/docker/cli/cli/manifest/store"
|
||||||
manifesttypes "github.com/docker/cli/cli/manifest/types"
|
manifesttypes "github.com/docker/cli/cli/manifest/types"
|
||||||
"github.com/docker/cli/internal/test"
|
"github.com/docker/cli/internal/test"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"gotest.tools/v3/assert"
|
"gotest.tools/v3/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -19,7 +21,7 @@ func newFakeRegistryClient() *fakeRegistryClient {
|
||||||
return manifesttypes.ImageManifest{}, errors.New("")
|
return manifesttypes.ImageManifest{}, errors.New("")
|
||||||
},
|
},
|
||||||
getManifestListFunc: func(_ context.Context, _ reference.Named) ([]manifesttypes.ImageManifest, error) {
|
getManifestListFunc: func(_ context.Context, _ reference.Named) ([]manifesttypes.ImageManifest, error) {
|
||||||
return nil, errors.Errorf("")
|
return nil, fmt.Errorf("")
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,11 +2,12 @@ package manifest
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/docker/cli/cli"
|
"github.com/docker/cli/cli"
|
||||||
"github.com/docker/cli/cli/command"
|
"github.com/docker/cli/cli/command"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -2,12 +2,13 @@ package network
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/docker/cli/internal/test"
|
"github.com/docker/cli/internal/test"
|
||||||
"github.com/docker/docker/api/types/network"
|
"github.com/docker/docker/api/types/network"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"gotest.tools/v3/assert"
|
"gotest.tools/v3/assert"
|
||||||
is "gotest.tools/v3/assert/cmp"
|
is "gotest.tools/v3/assert/cmp"
|
||||||
)
|
)
|
||||||
|
@ -24,7 +25,7 @@ func TestNetworkConnectErrors(t *testing.T) {
|
||||||
{
|
{
|
||||||
args: []string{"toto", "titi"},
|
args: []string{"toto", "titi"},
|
||||||
networkConnectFunc: func(ctx context.Context, networkID, container string, config *network.EndpointSettings) error {
|
networkConnectFunc: func(ctx context.Context, networkID, container string, config *network.EndpointSettings) error {
|
||||||
return errors.Errorf("error connecting network")
|
return fmt.Errorf("error connecting network")
|
||||||
},
|
},
|
||||||
expectedError: "error connecting network",
|
expectedError: "error connecting network",
|
||||||
},
|
},
|
||||||
|
|
|
@ -13,7 +13,7 @@ import (
|
||||||
"github.com/docker/cli/opts"
|
"github.com/docker/cli/opts"
|
||||||
"github.com/docker/docker/api/types/network"
|
"github.com/docker/docker/api/types/network"
|
||||||
"github.com/docker/docker/client"
|
"github.com/docker/docker/client"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -137,7 +137,7 @@ func runCreate(ctx context.Context, apiClient client.NetworkAPIClient, output io
|
||||||
//nolint:gocyclo
|
//nolint:gocyclo
|
||||||
func createIPAMConfig(options ipamOptions) (*network.IPAM, error) {
|
func createIPAMConfig(options ipamOptions) (*network.IPAM, error) {
|
||||||
if len(options.subnets) < len(options.ipRanges) || len(options.subnets) < len(options.gateways) {
|
if len(options.subnets) < len(options.ipRanges) || len(options.subnets) < len(options.gateways) {
|
||||||
return nil, errors.Errorf("every ip-range or gateway must have a corresponding subnet")
|
return nil, fmt.Errorf("every ip-range or gateway must have a corresponding subnet")
|
||||||
}
|
}
|
||||||
iData := map[string]*network.IPAMConfig{}
|
iData := map[string]*network.IPAMConfig{}
|
||||||
|
|
||||||
|
@ -153,7 +153,7 @@ func createIPAMConfig(options ipamOptions) (*network.IPAM, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if ok1 || ok2 {
|
if ok1 || ok2 {
|
||||||
return nil, errors.Errorf("multiple overlapping subnet configuration is not supported")
|
return nil, fmt.Errorf("multiple overlapping subnet configuration is not supported")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
iData[s] = &network.IPAMConfig{Subnet: s, AuxAddress: map[string]string{}}
|
iData[s] = &network.IPAMConfig{Subnet: s, AuxAddress: map[string]string{}}
|
||||||
|
@ -174,14 +174,14 @@ func createIPAMConfig(options ipamOptions) (*network.IPAM, error) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if iData[s].IPRange != "" {
|
if iData[s].IPRange != "" {
|
||||||
return nil, errors.Errorf("cannot configure multiple ranges (%s, %s) on the same subnet (%s)", r, iData[s].IPRange, s)
|
return nil, fmt.Errorf("cannot configure multiple ranges (%s, %s) on the same subnet (%s)", r, iData[s].IPRange, s)
|
||||||
}
|
}
|
||||||
d := iData[s]
|
d := iData[s]
|
||||||
d.IPRange = r
|
d.IPRange = r
|
||||||
match = true
|
match = true
|
||||||
}
|
}
|
||||||
if !match {
|
if !match {
|
||||||
return nil, errors.Errorf("no matching subnet for range %s", r)
|
return nil, fmt.Errorf("no matching subnet for range %s", r)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,14 +197,14 @@ func createIPAMConfig(options ipamOptions) (*network.IPAM, error) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if iData[s].Gateway != "" {
|
if iData[s].Gateway != "" {
|
||||||
return nil, errors.Errorf("cannot configure multiple gateways (%s, %s) for the same subnet (%s)", g, iData[s].Gateway, s)
|
return nil, fmt.Errorf("cannot configure multiple gateways (%s, %s) for the same subnet (%s)", g, iData[s].Gateway, s)
|
||||||
}
|
}
|
||||||
d := iData[s]
|
d := iData[s]
|
||||||
d.Gateway = g
|
d.Gateway = g
|
||||||
match = true
|
match = true
|
||||||
}
|
}
|
||||||
if !match {
|
if !match {
|
||||||
return nil, errors.Errorf("no matching subnet for gateway %s", g)
|
return nil, fmt.Errorf("no matching subnet for gateway %s", g)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,7 +223,7 @@ func createIPAMConfig(options ipamOptions) (*network.IPAM, error) {
|
||||||
match = true
|
match = true
|
||||||
}
|
}
|
||||||
if !match {
|
if !match {
|
||||||
return nil, errors.Errorf("no matching subnet for aux-address %s", aa)
|
return nil, fmt.Errorf("no matching subnet for aux-address %s", aa)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -244,7 +244,7 @@ func subnetMatches(subnet, data string) (bool, error) {
|
||||||
|
|
||||||
_, s, err := net.ParseCIDR(subnet)
|
_, s, err := net.ParseCIDR(subnet)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, errors.Wrap(err, "invalid subnet")
|
return false, fmt.Errorf("invalid subnet: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if strings.Contains(data, "/") {
|
if strings.Contains(data, "/") {
|
||||||
|
|
|
@ -2,13 +2,14 @@ package network
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/docker/cli/internal/test"
|
"github.com/docker/cli/internal/test"
|
||||||
"github.com/docker/docker/api/types/network"
|
"github.com/docker/docker/api/types/network"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"gotest.tools/v3/assert"
|
"gotest.tools/v3/assert"
|
||||||
is "gotest.tools/v3/assert/cmp"
|
is "gotest.tools/v3/assert/cmp"
|
||||||
)
|
)
|
||||||
|
@ -26,7 +27,7 @@ func TestNetworkCreateErrors(t *testing.T) {
|
||||||
{
|
{
|
||||||
args: []string{"toto"},
|
args: []string{"toto"},
|
||||||
networkCreateFunc: func(ctx context.Context, name string, createBody network.CreateOptions) (network.CreateResponse, error) {
|
networkCreateFunc: func(ctx context.Context, name string, createBody network.CreateOptions) (network.CreateResponse, error) {
|
||||||
return network.CreateResponse{}, errors.Errorf("error creating network")
|
return network.CreateResponse{}, fmt.Errorf("error creating network")
|
||||||
},
|
},
|
||||||
expectedError: "error creating network",
|
expectedError: "error creating network",
|
||||||
},
|
},
|
||||||
|
|
|
@ -2,11 +2,12 @@ package network
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/docker/cli/internal/test"
|
"github.com/docker/cli/internal/test"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"gotest.tools/v3/assert"
|
"gotest.tools/v3/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -22,7 +23,7 @@ func TestNetworkDisconnectErrors(t *testing.T) {
|
||||||
{
|
{
|
||||||
args: []string{"toto", "titi"},
|
args: []string{"toto", "titi"},
|
||||||
networkDisconnectFunc: func(ctx context.Context, networkID, container string, force bool) error {
|
networkDisconnectFunc: func(ctx context.Context, networkID, container string, force bool) error {
|
||||||
return errors.Errorf("error disconnecting network")
|
return fmt.Errorf("error disconnecting network")
|
||||||
},
|
},
|
||||||
expectedError: "error disconnecting network",
|
expectedError: "error disconnecting network",
|
||||||
},
|
},
|
||||||
|
|
|
@ -2,6 +2,7 @@ package network
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
@ -10,7 +11,7 @@ import (
|
||||||
"github.com/docker/docker/api/types/filters"
|
"github.com/docker/docker/api/types/filters"
|
||||||
"github.com/docker/docker/api/types/network"
|
"github.com/docker/docker/api/types/network"
|
||||||
"github.com/google/go-cmp/cmp"
|
"github.com/google/go-cmp/cmp"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"gotest.tools/v3/assert"
|
"gotest.tools/v3/assert"
|
||||||
is "gotest.tools/v3/assert/cmp"
|
is "gotest.tools/v3/assert/cmp"
|
||||||
"gotest.tools/v3/golden"
|
"gotest.tools/v3/golden"
|
||||||
|
@ -23,7 +24,7 @@ func TestNetworkListErrors(t *testing.T) {
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
networkListFunc: func(ctx context.Context, options network.ListOptions) ([]network.Summary, error) {
|
networkListFunc: func(ctx context.Context, options network.ListOptions) ([]network.Summary, error) {
|
||||||
return []network.Summary{}, errors.Errorf("error creating network")
|
return []network.Summary{}, fmt.Errorf("error creating network")
|
||||||
},
|
},
|
||||||
expectedError: "error creating network",
|
expectedError: "error creating network",
|
||||||
},
|
},
|
||||||
|
|
|
@ -2,13 +2,14 @@ package network
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/docker/cli/cli"
|
"github.com/docker/cli/cli"
|
||||||
"github.com/docker/cli/cli/command"
|
"github.com/docker/cli/cli/command"
|
||||||
"github.com/docker/cli/opts"
|
"github.com/docker/cli/opts"
|
||||||
"github.com/docker/docker/errdefs"
|
"github.com/docker/docker/errdefs"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -2,13 +2,13 @@ package network
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/docker/cli/internal/test"
|
"github.com/docker/cli/internal/test"
|
||||||
"github.com/docker/docker/api/types/filters"
|
"github.com/docker/docker/api/types/filters"
|
||||||
"github.com/docker/docker/api/types/network"
|
"github.com/docker/docker/api/types/network"
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestNetworkPrunePromptTermination(t *testing.T) {
|
func TestNetworkPrunePromptTermination(t *testing.T) {
|
||||||
|
|
|
@ -2,13 +2,14 @@ package network
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/docker/cli/internal/test"
|
"github.com/docker/cli/internal/test"
|
||||||
"github.com/docker/docker/api/types/network"
|
"github.com/docker/docker/api/types/network"
|
||||||
"github.com/docker/docker/errdefs"
|
"github.com/docker/docker/errdefs"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"gotest.tools/v3/assert"
|
"gotest.tools/v3/assert"
|
||||||
is "gotest.tools/v3/assert/cmp"
|
is "gotest.tools/v3/assert/cmp"
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
package node
|
package node
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/docker/cli/internal/test"
|
"github.com/docker/cli/internal/test"
|
||||||
"github.com/docker/cli/internal/test/builders"
|
"github.com/docker/cli/internal/test/builders"
|
||||||
"github.com/docker/docker/api/types/swarm"
|
"github.com/docker/docker/api/types/swarm"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"gotest.tools/v3/assert"
|
"gotest.tools/v3/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -24,14 +25,14 @@ func TestNodeDemoteErrors(t *testing.T) {
|
||||||
{
|
{
|
||||||
args: []string{"nodeID"},
|
args: []string{"nodeID"},
|
||||||
nodeInspectFunc: func() (swarm.Node, []byte, error) {
|
nodeInspectFunc: func() (swarm.Node, []byte, error) {
|
||||||
return swarm.Node{}, []byte{}, errors.Errorf("error inspecting the node")
|
return swarm.Node{}, []byte{}, fmt.Errorf("error inspecting the node")
|
||||||
},
|
},
|
||||||
expectedError: "error inspecting the node",
|
expectedError: "error inspecting the node",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
args: []string{"nodeID"},
|
args: []string{"nodeID"},
|
||||||
nodeUpdateFunc: func(nodeID string, version swarm.Version, node swarm.NodeSpec) error {
|
nodeUpdateFunc: func(nodeID string, version swarm.Version, node swarm.NodeSpec) error {
|
||||||
return errors.Errorf("error updating the node")
|
return fmt.Errorf("error updating the node")
|
||||||
},
|
},
|
||||||
expectedError: "error updating the node",
|
expectedError: "error updating the node",
|
||||||
},
|
},
|
||||||
|
@ -57,7 +58,7 @@ func TestNodeDemoteNoChange(t *testing.T) {
|
||||||
},
|
},
|
||||||
nodeUpdateFunc: func(nodeID string, version swarm.Version, node swarm.NodeSpec) error {
|
nodeUpdateFunc: func(nodeID string, version swarm.Version, node swarm.NodeSpec) error {
|
||||||
if node.Role != swarm.NodeRoleWorker {
|
if node.Role != swarm.NodeRoleWorker {
|
||||||
return errors.Errorf("expected role worker, got %s", node.Role)
|
return fmt.Errorf("expected role worker, got %s", node.Role)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
|
@ -74,7 +75,7 @@ func TestNodeDemoteMultipleNode(t *testing.T) {
|
||||||
},
|
},
|
||||||
nodeUpdateFunc: func(nodeID string, version swarm.Version, node swarm.NodeSpec) error {
|
nodeUpdateFunc: func(nodeID string, version swarm.Version, node swarm.NodeSpec) error {
|
||||||
if node.Role != swarm.NodeRoleWorker {
|
if node.Role != swarm.NodeRoleWorker {
|
||||||
return errors.Errorf("expected role worker, got %s", node.Role)
|
return fmt.Errorf("expected role worker, got %s", node.Role)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
|
|
|
@ -9,7 +9,7 @@ import (
|
||||||
"github.com/docker/cli/internal/test/builders"
|
"github.com/docker/cli/internal/test/builders"
|
||||||
"github.com/docker/docker/api/types/swarm"
|
"github.com/docker/docker/api/types/swarm"
|
||||||
"github.com/docker/docker/api/types/system"
|
"github.com/docker/docker/api/types/system"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"gotest.tools/v3/assert"
|
"gotest.tools/v3/assert"
|
||||||
"gotest.tools/v3/golden"
|
"gotest.tools/v3/golden"
|
||||||
)
|
)
|
||||||
|
@ -28,24 +28,24 @@ func TestNodeInspectErrors(t *testing.T) {
|
||||||
{
|
{
|
||||||
args: []string{"self"},
|
args: []string{"self"},
|
||||||
infoFunc: func() (system.Info, error) {
|
infoFunc: func() (system.Info, error) {
|
||||||
return system.Info{}, errors.Errorf("error asking for node info")
|
return system.Info{}, fmt.Errorf("error asking for node info")
|
||||||
},
|
},
|
||||||
expectedError: "error asking for node info",
|
expectedError: "error asking for node info",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
args: []string{"nodeID"},
|
args: []string{"nodeID"},
|
||||||
nodeInspectFunc: func() (swarm.Node, []byte, error) {
|
nodeInspectFunc: func() (swarm.Node, []byte, error) {
|
||||||
return swarm.Node{}, []byte{}, errors.Errorf("error inspecting the node")
|
return swarm.Node{}, []byte{}, fmt.Errorf("error inspecting the node")
|
||||||
},
|
},
|
||||||
infoFunc: func() (system.Info, error) {
|
infoFunc: func() (system.Info, error) {
|
||||||
return system.Info{}, errors.Errorf("error asking for node info")
|
return system.Info{}, fmt.Errorf("error asking for node info")
|
||||||
},
|
},
|
||||||
expectedError: "error inspecting the node",
|
expectedError: "error inspecting the node",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
args: []string{"self"},
|
args: []string{"self"},
|
||||||
nodeInspectFunc: func() (swarm.Node, []byte, error) {
|
nodeInspectFunc: func() (swarm.Node, []byte, error) {
|
||||||
return swarm.Node{}, []byte{}, errors.Errorf("error inspecting the node")
|
return swarm.Node{}, []byte{}, fmt.Errorf("error inspecting the node")
|
||||||
},
|
},
|
||||||
infoFunc: func() (system.Info, error) {
|
infoFunc: func() (system.Info, error) {
|
||||||
return system.Info{Swarm: swarm.Info{NodeID: "abc"}}, nil
|
return system.Info{Swarm: swarm.Info{NodeID: "abc"}}, nil
|
||||||
|
@ -58,7 +58,7 @@ func TestNodeInspectErrors(t *testing.T) {
|
||||||
"pretty": "true",
|
"pretty": "true",
|
||||||
},
|
},
|
||||||
infoFunc: func() (system.Info, error) {
|
infoFunc: func() (system.Info, error) {
|
||||||
return system.Info{}, errors.Errorf("error asking for node info")
|
return system.Info{}, fmt.Errorf("error asking for node info")
|
||||||
},
|
},
|
||||||
expectedError: "error asking for node info",
|
expectedError: "error asking for node info",
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package node
|
package node
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
@ -9,7 +10,7 @@ import (
|
||||||
"github.com/docker/cli/internal/test/builders"
|
"github.com/docker/cli/internal/test/builders"
|
||||||
"github.com/docker/docker/api/types/swarm"
|
"github.com/docker/docker/api/types/swarm"
|
||||||
"github.com/docker/docker/api/types/system"
|
"github.com/docker/docker/api/types/system"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"gotest.tools/v3/assert"
|
"gotest.tools/v3/assert"
|
||||||
is "gotest.tools/v3/assert/cmp"
|
is "gotest.tools/v3/assert/cmp"
|
||||||
"gotest.tools/v3/golden"
|
"gotest.tools/v3/golden"
|
||||||
|
@ -23,7 +24,7 @@ func TestNodeListErrorOnAPIFailure(t *testing.T) {
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
nodeListFunc: func() ([]swarm.Node, error) {
|
nodeListFunc: func() ([]swarm.Node, error) {
|
||||||
return []swarm.Node{}, errors.Errorf("error listing nodes")
|
return []swarm.Node{}, fmt.Errorf("error listing nodes")
|
||||||
},
|
},
|
||||||
expectedError: "error listing nodes",
|
expectedError: "error listing nodes",
|
||||||
},
|
},
|
||||||
|
@ -36,7 +37,7 @@ func TestNodeListErrorOnAPIFailure(t *testing.T) {
|
||||||
}, nil
|
}, nil
|
||||||
},
|
},
|
||||||
infoFunc: func() (system.Info, error) {
|
infoFunc: func() (system.Info, error) {
|
||||||
return system.Info{}, errors.Errorf("error asking for node info")
|
return system.Info{}, fmt.Errorf("error asking for node info")
|
||||||
},
|
},
|
||||||
expectedError: "error asking for node info",
|
expectedError: "error asking for node info",
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
package node
|
package node
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/docker/cli/internal/test"
|
"github.com/docker/cli/internal/test"
|
||||||
"github.com/docker/cli/internal/test/builders"
|
"github.com/docker/cli/internal/test/builders"
|
||||||
"github.com/docker/docker/api/types/swarm"
|
"github.com/docker/docker/api/types/swarm"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"gotest.tools/v3/assert"
|
"gotest.tools/v3/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -24,14 +25,14 @@ func TestNodePromoteErrors(t *testing.T) {
|
||||||
{
|
{
|
||||||
args: []string{"nodeID"},
|
args: []string{"nodeID"},
|
||||||
nodeInspectFunc: func() (swarm.Node, []byte, error) {
|
nodeInspectFunc: func() (swarm.Node, []byte, error) {
|
||||||
return swarm.Node{}, []byte{}, errors.Errorf("error inspecting the node")
|
return swarm.Node{}, []byte{}, fmt.Errorf("error inspecting the node")
|
||||||
},
|
},
|
||||||
expectedError: "error inspecting the node",
|
expectedError: "error inspecting the node",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
args: []string{"nodeID"},
|
args: []string{"nodeID"},
|
||||||
nodeUpdateFunc: func(nodeID string, version swarm.Version, node swarm.NodeSpec) error {
|
nodeUpdateFunc: func(nodeID string, version swarm.Version, node swarm.NodeSpec) error {
|
||||||
return errors.Errorf("error updating the node")
|
return fmt.Errorf("error updating the node")
|
||||||
},
|
},
|
||||||
expectedError: "error updating the node",
|
expectedError: "error updating the node",
|
||||||
},
|
},
|
||||||
|
@ -57,7 +58,7 @@ func TestNodePromoteNoChange(t *testing.T) {
|
||||||
},
|
},
|
||||||
nodeUpdateFunc: func(nodeID string, version swarm.Version, node swarm.NodeSpec) error {
|
nodeUpdateFunc: func(nodeID string, version swarm.Version, node swarm.NodeSpec) error {
|
||||||
if node.Role != swarm.NodeRoleManager {
|
if node.Role != swarm.NodeRoleManager {
|
||||||
return errors.Errorf("expected role manager, got %s", node.Role)
|
return fmt.Errorf("expected role manager, got %s", node.Role)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
|
@ -74,7 +75,7 @@ func TestNodePromoteMultipleNode(t *testing.T) {
|
||||||
},
|
},
|
||||||
nodeUpdateFunc: func(nodeID string, version swarm.Version, node swarm.NodeSpec) error {
|
nodeUpdateFunc: func(nodeID string, version swarm.Version, node swarm.NodeSpec) error {
|
||||||
if node.Role != swarm.NodeRoleManager {
|
if node.Role != swarm.NodeRoleManager {
|
||||||
return errors.Errorf("expected role manager, got %s", node.Role)
|
return fmt.Errorf("expected role manager, got %s", node.Role)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
|
|
|
@ -2,6 +2,7 @@ package node
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/docker/cli/cli"
|
"github.com/docker/cli/cli"
|
||||||
|
@ -12,7 +13,7 @@ import (
|
||||||
"github.com/docker/cli/opts"
|
"github.com/docker/cli/opts"
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
"github.com/docker/docker/api/types/swarm"
|
"github.com/docker/docker/api/types/swarm"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -98,7 +99,7 @@ func runPs(ctx context.Context, dockerCli command.Cli, options psOptions) error
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(errs) > 0 {
|
if len(errs) > 0 {
|
||||||
return errors.Errorf("%s", strings.Join(errs, "\n"))
|
return fmt.Errorf("%s", strings.Join(errs, "\n"))
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -12,7 +12,7 @@ import (
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
"github.com/docker/docker/api/types/swarm"
|
"github.com/docker/docker/api/types/swarm"
|
||||||
"github.com/docker/docker/api/types/system"
|
"github.com/docker/docker/api/types/system"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"gotest.tools/v3/assert"
|
"gotest.tools/v3/assert"
|
||||||
"gotest.tools/v3/golden"
|
"gotest.tools/v3/golden"
|
||||||
)
|
)
|
||||||
|
@ -29,21 +29,21 @@ func TestNodePsErrors(t *testing.T) {
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
infoFunc: func() (system.Info, error) {
|
infoFunc: func() (system.Info, error) {
|
||||||
return system.Info{}, errors.Errorf("error asking for node info")
|
return system.Info{}, fmt.Errorf("error asking for node info")
|
||||||
},
|
},
|
||||||
expectedError: "error asking for node info",
|
expectedError: "error asking for node info",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
args: []string{"nodeID"},
|
args: []string{"nodeID"},
|
||||||
nodeInspectFunc: func() (swarm.Node, []byte, error) {
|
nodeInspectFunc: func() (swarm.Node, []byte, error) {
|
||||||
return swarm.Node{}, []byte{}, errors.Errorf("error inspecting the node")
|
return swarm.Node{}, []byte{}, fmt.Errorf("error inspecting the node")
|
||||||
},
|
},
|
||||||
expectedError: "error inspecting the node",
|
expectedError: "error inspecting the node",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
args: []string{"nodeID"},
|
args: []string{"nodeID"},
|
||||||
taskListFunc: func(options types.TaskListOptions) ([]swarm.Task, error) {
|
taskListFunc: func(options types.TaskListOptions) ([]swarm.Task, error) {
|
||||||
return []swarm.Task{}, errors.Errorf("error returning the task list")
|
return []swarm.Task{}, fmt.Errorf("error returning the task list")
|
||||||
},
|
},
|
||||||
expectedError: "error returning the task list",
|
expectedError: "error returning the task list",
|
||||||
},
|
},
|
||||||
|
|
|
@ -8,7 +8,7 @@ import (
|
||||||
"github.com/docker/cli/cli"
|
"github.com/docker/cli/cli"
|
||||||
"github.com/docker/cli/cli/command"
|
"github.com/docker/cli/cli/command"
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ func runRemove(ctx context.Context, dockerCli command.Cli, args []string, opts r
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(errs) > 0 {
|
if len(errs) > 0 {
|
||||||
return errors.Errorf("%s", strings.Join(errs, "\n"))
|
return fmt.Errorf("%s", strings.Join(errs, "\n"))
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
package node
|
package node
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/docker/cli/internal/test"
|
"github.com/docker/cli/internal/test"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"gotest.tools/v3/assert"
|
"gotest.tools/v3/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -21,7 +22,7 @@ func TestNodeRemoveErrors(t *testing.T) {
|
||||||
{
|
{
|
||||||
args: []string{"nodeID"},
|
args: []string{"nodeID"},
|
||||||
nodeRemoveFunc: func() error {
|
nodeRemoveFunc: func() error {
|
||||||
return errors.Errorf("error removing the node")
|
return fmt.Errorf("error removing the node")
|
||||||
},
|
},
|
||||||
expectedError: "error removing the node",
|
expectedError: "error removing the node",
|
||||||
},
|
},
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue