mirror of https://github.com/docker/cli.git
Merge pull request #5404 from corhere/backport-23.0/golang-1.22.6
[23.0] Update to go1.22.6
This commit is contained in:
commit
a34ca56d30
|
@ -63,7 +63,7 @@ jobs:
|
||||||
name: Set up Go
|
name: Set up Go
|
||||||
uses: actions/setup-go@v3
|
uses: actions/setup-go@v3
|
||||||
with:
|
with:
|
||||||
go-version: 1.20.13
|
go-version: 1.22.6
|
||||||
-
|
-
|
||||||
name: Test
|
name: Test
|
||||||
run: |
|
run: |
|
||||||
|
@ -77,3 +77,4 @@ jobs:
|
||||||
with:
|
with:
|
||||||
file: /tmp/coverage.txt
|
file: /tmp/coverage.txt
|
||||||
working-directory: ${{ env.GOPATH }}/src/github.com/docker/cli
|
working-directory: ${{ env.GOPATH }}/src/github.com/docker/cli
|
||||||
|
version: v0.7.3 # Work around https://github.com/codecov/uploader/issues/1687 -- uploader v0.8.0 for mac is built for arm64, not x86_64
|
||||||
|
|
|
@ -26,27 +26,26 @@ linters:
|
||||||
|
|
||||||
run:
|
run:
|
||||||
timeout: 5m
|
timeout: 5m
|
||||||
skip-files:
|
|
||||||
- cli/compose/schema/bindata.go
|
|
||||||
- .*generated.*
|
|
||||||
|
|
||||||
linters-settings:
|
linters-settings:
|
||||||
depguard:
|
depguard:
|
||||||
list-type: blacklist
|
rules:
|
||||||
include-go-root: true
|
main:
|
||||||
packages:
|
deny:
|
||||||
# The io/ioutil package has been deprecated.
|
- pkg: io/ioutil
|
||||||
# https://go.dev/doc/go1.16#ioutil
|
desc: The io/ioutil package has been deprecated, see https://go.dev/doc/go1.16#ioutil
|
||||||
- io/ioutil
|
|
||||||
gocyclo:
|
gocyclo:
|
||||||
min-complexity: 16
|
min-complexity: 16
|
||||||
govet:
|
|
||||||
check-shadowing: false
|
|
||||||
lll:
|
lll:
|
||||||
line-length: 200
|
line-length: 200
|
||||||
nakedret:
|
nakedret:
|
||||||
command: nakedret
|
command: nakedret
|
||||||
pattern: ^(?P<path>.*?\\.go):(?P<line>\\d+)\\s*(?P<message>.*)$
|
pattern: ^(?P<path>.*?\\.go):(?P<line>\\d+)\\s*(?P<message>.*)$
|
||||||
|
revive:
|
||||||
|
rules:
|
||||||
|
- name: unused-parameter
|
||||||
|
severity: warning
|
||||||
|
disabled: true
|
||||||
|
|
||||||
issues:
|
issues:
|
||||||
# The default exclusion rules are a bit too permissive, so copying the relevant ones below
|
# The default exclusion rules are a bit too permissive, so copying the relevant ones below
|
||||||
|
@ -55,6 +54,10 @@ issues:
|
||||||
exclude:
|
exclude:
|
||||||
- parameter .* always receives
|
- parameter .* always receives
|
||||||
|
|
||||||
|
exclude-files:
|
||||||
|
- cli/compose/schema/bindata.go
|
||||||
|
- .*generated.*
|
||||||
|
|
||||||
exclude-rules:
|
exclude-rules:
|
||||||
# We prefer to use an "exclude-list" so that new "default" exclusions are not
|
# We prefer to use an "exclude-list" so that new "default" exclusions are not
|
||||||
# automatically inherited. We can decide whether or not to follow upstream
|
# automatically inherited. We can decide whether or not to follow upstream
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
# syntax=docker/dockerfile:1
|
# syntax=docker/dockerfile:1
|
||||||
|
|
||||||
ARG BASE_VARIANT=alpine
|
ARG BASE_VARIANT=alpine
|
||||||
ARG GO_VERSION=1.20.13
|
ARG GO_VERSION=1.22.6
|
||||||
ARG ALPINE_VERSION=3.18
|
ARG ALPINE_VERSION=3.20
|
||||||
ARG XX_VERSION=1.1.1
|
ARG XX_VERSION=1.1.1
|
||||||
ARG GOVERSIONINFO_VERSION=v1.3.0
|
ARG GOVERSIONINFO_VERSION=v1.3.0
|
||||||
ARG GOTESTSUM_VERSION=v1.10.0
|
ARG GOTESTSUM_VERSION=v1.10.0
|
||||||
|
|
|
@ -2,7 +2,7 @@ package manager
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"errors"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"gotest.tools/v3/assert"
|
"gotest.tools/v3/assert"
|
||||||
|
@ -13,7 +13,7 @@ func TestPluginError(t *testing.T) {
|
||||||
err := NewPluginError("new error")
|
err := NewPluginError("new error")
|
||||||
assert.Check(t, is.Error(err, "new error"))
|
assert.Check(t, is.Error(err, "new error"))
|
||||||
|
|
||||||
inner := fmt.Errorf("testing")
|
inner := errors.New("testing")
|
||||||
err = wrapAsPluginError(inner, "wrapping")
|
err = wrapAsPluginError(inner, "wrapping")
|
||||||
assert.Check(t, is.Error(err, "wrapping: testing"))
|
assert.Check(t, is.Error(err, "wrapping: testing"))
|
||||||
assert.Check(t, is.ErrorIs(err, inner))
|
assert.Check(t, is.ErrorIs(err, inner))
|
||||||
|
|
|
@ -278,7 +278,7 @@ func newAPIClientFromEndpoint(ep docker.Endpoint, configFile *configfile.ConfigF
|
||||||
|
|
||||||
func resolveDockerEndpoint(s store.Reader, contextName string) (docker.Endpoint, error) {
|
func resolveDockerEndpoint(s store.Reader, contextName string) (docker.Endpoint, error) {
|
||||||
if s == nil {
|
if s == nil {
|
||||||
return docker.Endpoint{}, fmt.Errorf("no context store initialized")
|
return docker.Endpoint{}, errors.New("no context store initialized")
|
||||||
}
|
}
|
||||||
ctxMeta, err := s.GetMetadata(contextName)
|
ctxMeta, err := s.GetMetadata(contextName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -192,7 +192,7 @@ func TestInitializeFromClientHangs(t *testing.T) {
|
||||||
ts.Start()
|
ts.Start()
|
||||||
defer ts.Close()
|
defer ts.Close()
|
||||||
|
|
||||||
opts := &flags.ClientOptions{Hosts: []string{fmt.Sprintf("unix://%s", socket)}}
|
opts := &flags.ClientOptions{Hosts: []string{"unix://" + socket}}
|
||||||
configFile := &configfile.ConfigFile{}
|
configFile := &configfile.ConfigFile{}
|
||||||
apiClient, err := NewAPIClientFromFlags(opts, configFile)
|
apiClient, err := NewAPIClientFromFlags(opts, configFile)
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
|
|
|
@ -8,7 +8,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/docker/cli/internal/test"
|
"github.com/docker/cli/internal/test"
|
||||||
. "github.com/docker/cli/internal/test/builders" // Import builders to get the builder function as package function
|
"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"
|
"github.com/pkg/errors"
|
||||||
"gotest.tools/v3/assert"
|
"gotest.tools/v3/assert"
|
||||||
|
@ -43,7 +43,7 @@ func TestConfigInspectErrors(t *testing.T) {
|
||||||
args: []string{"foo", "bar"},
|
args: []string{"foo", "bar"},
|
||||||
configInspectFunc: func(_ context.Context, configID string) (swarm.Config, []byte, error) {
|
configInspectFunc: func(_ context.Context, configID string) (swarm.Config, []byte, error) {
|
||||||
if configID == "foo" {
|
if configID == "foo" {
|
||||||
return *Config(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, errors.Errorf("error while inspecting the config")
|
||||||
},
|
},
|
||||||
|
@ -58,7 +58,7 @@ func TestConfigInspectErrors(t *testing.T) {
|
||||||
)
|
)
|
||||||
cmd.SetArgs(tc.args)
|
cmd.SetArgs(tc.args)
|
||||||
for key, value := range tc.flags {
|
for key, value := range tc.flags {
|
||||||
cmd.Flags().Set(key, value)
|
assert.Check(t, cmd.Flags().Set(key, value))
|
||||||
}
|
}
|
||||||
cmd.SetOut(io.Discard)
|
cmd.SetOut(io.Discard)
|
||||||
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
|
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
|
||||||
|
@ -78,14 +78,14 @@ func TestConfigInspectWithoutFormat(t *testing.T) {
|
||||||
if name != "foo" {
|
if name != "foo" {
|
||||||
return swarm.Config{}, nil, errors.Errorf("Invalid name, expected %s, got %s", "foo", name)
|
return swarm.Config{}, nil, errors.Errorf("Invalid name, expected %s, got %s", "foo", name)
|
||||||
}
|
}
|
||||||
return *Config(ConfigID("ID-foo"), ConfigName("foo")), nil, nil
|
return *builders.Config(builders.ConfigID("ID-foo"), builders.ConfigName("foo")), nil, nil
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "multiple-configs-with-labels",
|
name: "multiple-configs-with-labels",
|
||||||
args: []string{"foo", "bar"},
|
args: []string{"foo", "bar"},
|
||||||
configInspectFunc: func(_ context.Context, name string) (swarm.Config, []byte, error) {
|
configInspectFunc: func(_ context.Context, name string) (swarm.Config, []byte, error) {
|
||||||
return *Config(ConfigID("ID-"+name), ConfigName(name), ConfigLabels(map[string]string{
|
return *builders.Config(builders.ConfigID("ID-"+name), builders.ConfigName(name), builders.ConfigLabels(map[string]string{
|
||||||
"label1": "label-foo",
|
"label1": "label-foo",
|
||||||
})), nil, nil
|
})), nil, nil
|
||||||
},
|
},
|
||||||
|
@ -102,7 +102,7 @@ func TestConfigInspectWithoutFormat(t *testing.T) {
|
||||||
|
|
||||||
func TestConfigInspectWithFormat(t *testing.T) {
|
func TestConfigInspectWithFormat(t *testing.T) {
|
||||||
configInspectFunc := func(_ context.Context, name string) (swarm.Config, []byte, error) {
|
configInspectFunc := func(_ context.Context, name string) (swarm.Config, []byte, error) {
|
||||||
return *Config(ConfigName("foo"), ConfigLabels(map[string]string{
|
return *builders.Config(builders.ConfigName("foo"), builders.ConfigLabels(map[string]string{
|
||||||
"label1": "label-foo",
|
"label1": "label-foo",
|
||||||
})), nil, nil
|
})), nil, nil
|
||||||
}
|
}
|
||||||
|
@ -131,7 +131,7 @@ func TestConfigInspectWithFormat(t *testing.T) {
|
||||||
})
|
})
|
||||||
cmd := newConfigInspectCommand(cli)
|
cmd := newConfigInspectCommand(cli)
|
||||||
cmd.SetArgs(tc.args)
|
cmd.SetArgs(tc.args)
|
||||||
cmd.Flags().Set("format", tc.format)
|
assert.Check(t, cmd.Flags().Set("format", tc.format))
|
||||||
assert.NilError(t, cmd.Execute())
|
assert.NilError(t, cmd.Execute())
|
||||||
golden.Assert(t, cli.OutBuffer().String(), fmt.Sprintf("config-inspect-with-format.%s.golden", tc.name))
|
golden.Assert(t, cli.OutBuffer().String(), fmt.Sprintf("config-inspect-with-format.%s.golden", tc.name))
|
||||||
}
|
}
|
||||||
|
@ -145,15 +145,15 @@ func TestConfigInspectPretty(t *testing.T) {
|
||||||
{
|
{
|
||||||
name: "simple",
|
name: "simple",
|
||||||
configInspectFunc: func(_ context.Context, id string) (swarm.Config, []byte, error) {
|
configInspectFunc: func(_ context.Context, id string) (swarm.Config, []byte, error) {
|
||||||
return *Config(
|
return *builders.Config(
|
||||||
ConfigLabels(map[string]string{
|
builders.ConfigLabels(map[string]string{
|
||||||
"lbl1": "value1",
|
"lbl1": "value1",
|
||||||
}),
|
}),
|
||||||
ConfigID("configID"),
|
builders.ConfigID("configID"),
|
||||||
ConfigName("configName"),
|
builders.ConfigName("configName"),
|
||||||
ConfigCreatedAt(time.Time{}),
|
builders.ConfigCreatedAt(time.Time{}),
|
||||||
ConfigUpdatedAt(time.Time{}),
|
builders.ConfigUpdatedAt(time.Time{}),
|
||||||
ConfigData([]byte("payload here")),
|
builders.ConfigData([]byte("payload here")),
|
||||||
), []byte{}, nil
|
), []byte{}, nil
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -165,7 +165,7 @@ func TestConfigInspectPretty(t *testing.T) {
|
||||||
cmd := newConfigInspectCommand(cli)
|
cmd := newConfigInspectCommand(cli)
|
||||||
|
|
||||||
cmd.SetArgs([]string{"configID"})
|
cmd.SetArgs([]string{"configID"})
|
||||||
cmd.Flags().Set("pretty", "true")
|
assert.Check(t, cmd.Flags().Set("pretty", "true"))
|
||||||
assert.NilError(t, cmd.Execute())
|
assert.NilError(t, cmd.Execute())
|
||||||
golden.Assert(t, cli.OutBuffer().String(), fmt.Sprintf("config-inspect-pretty.%s.golden", tc.name))
|
golden.Assert(t, cli.OutBuffer().String(), fmt.Sprintf("config-inspect-pretty.%s.golden", tc.name))
|
||||||
}
|
}
|
||||||
|
|
|
@ -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/cli/internal/test/builders" // Import builders to get the builder function as package function
|
"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"
|
"github.com/pkg/errors"
|
||||||
|
@ -50,23 +50,23 @@ func TestConfigList(t *testing.T) {
|
||||||
cli := test.NewFakeCli(&fakeClient{
|
cli := test.NewFakeCli(&fakeClient{
|
||||||
configListFunc: func(_ context.Context, options types.ConfigListOptions) ([]swarm.Config, error) {
|
configListFunc: func(_ context.Context, options types.ConfigListOptions) ([]swarm.Config, error) {
|
||||||
return []swarm.Config{
|
return []swarm.Config{
|
||||||
*Config(ConfigID("ID-1-foo"),
|
*builders.Config(builders.ConfigID("ID-1-foo"),
|
||||||
ConfigName("1-foo"),
|
builders.ConfigName("1-foo"),
|
||||||
ConfigVersion(swarm.Version{Index: 10}),
|
builders.ConfigVersion(swarm.Version{Index: 10}),
|
||||||
ConfigCreatedAt(time.Now().Add(-2*time.Hour)),
|
builders.ConfigCreatedAt(time.Now().Add(-2*time.Hour)),
|
||||||
ConfigUpdatedAt(time.Now().Add(-1*time.Hour)),
|
builders.ConfigUpdatedAt(time.Now().Add(-1*time.Hour)),
|
||||||
),
|
),
|
||||||
*Config(ConfigID("ID-10-foo"),
|
*builders.Config(builders.ConfigID("ID-10-foo"),
|
||||||
ConfigName("10-foo"),
|
builders.ConfigName("10-foo"),
|
||||||
ConfigVersion(swarm.Version{Index: 11}),
|
builders.ConfigVersion(swarm.Version{Index: 11}),
|
||||||
ConfigCreatedAt(time.Now().Add(-2*time.Hour)),
|
builders.ConfigCreatedAt(time.Now().Add(-2*time.Hour)),
|
||||||
ConfigUpdatedAt(time.Now().Add(-1*time.Hour)),
|
builders.ConfigUpdatedAt(time.Now().Add(-1*time.Hour)),
|
||||||
),
|
),
|
||||||
*Config(ConfigID("ID-2-foo"),
|
*builders.Config(builders.ConfigID("ID-2-foo"),
|
||||||
ConfigName("2-foo"),
|
builders.ConfigName("2-foo"),
|
||||||
ConfigVersion(swarm.Version{Index: 11}),
|
builders.ConfigVersion(swarm.Version{Index: 11}),
|
||||||
ConfigCreatedAt(time.Now().Add(-2*time.Hour)),
|
builders.ConfigCreatedAt(time.Now().Add(-2*time.Hour)),
|
||||||
ConfigUpdatedAt(time.Now().Add(-1*time.Hour)),
|
builders.ConfigUpdatedAt(time.Now().Add(-1*time.Hour)),
|
||||||
),
|
),
|
||||||
}, nil
|
}, nil
|
||||||
},
|
},
|
||||||
|
@ -80,15 +80,15 @@ func TestConfigListWithQuietOption(t *testing.T) {
|
||||||
cli := test.NewFakeCli(&fakeClient{
|
cli := test.NewFakeCli(&fakeClient{
|
||||||
configListFunc: func(_ context.Context, options types.ConfigListOptions) ([]swarm.Config, error) {
|
configListFunc: func(_ context.Context, options types.ConfigListOptions) ([]swarm.Config, error) {
|
||||||
return []swarm.Config{
|
return []swarm.Config{
|
||||||
*Config(ConfigID("ID-foo"), ConfigName("foo")),
|
*builders.Config(builders.ConfigID("ID-foo"), builders.ConfigName("foo")),
|
||||||
*Config(ConfigID("ID-bar"), ConfigName("bar"), ConfigLabels(map[string]string{
|
*builders.Config(builders.ConfigID("ID-bar"), builders.ConfigName("bar"), builders.ConfigLabels(map[string]string{
|
||||||
"label": "label-bar",
|
"label": "label-bar",
|
||||||
})),
|
})),
|
||||||
}, nil
|
}, nil
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
cmd := newConfigListCommand(cli)
|
cmd := newConfigListCommand(cli)
|
||||||
cmd.Flags().Set("quiet", "true")
|
assert.Check(t, cmd.Flags().Set("quiet", "true"))
|
||||||
assert.NilError(t, cmd.Execute())
|
assert.NilError(t, cmd.Execute())
|
||||||
golden.Assert(t, cli.OutBuffer().String(), "config-list-with-quiet-option.golden")
|
golden.Assert(t, cli.OutBuffer().String(), "config-list-with-quiet-option.golden")
|
||||||
}
|
}
|
||||||
|
@ -97,8 +97,8 @@ func TestConfigListWithConfigFormat(t *testing.T) {
|
||||||
cli := test.NewFakeCli(&fakeClient{
|
cli := test.NewFakeCli(&fakeClient{
|
||||||
configListFunc: func(_ context.Context, options types.ConfigListOptions) ([]swarm.Config, error) {
|
configListFunc: func(_ context.Context, options types.ConfigListOptions) ([]swarm.Config, error) {
|
||||||
return []swarm.Config{
|
return []swarm.Config{
|
||||||
*Config(ConfigID("ID-foo"), ConfigName("foo")),
|
*builders.Config(builders.ConfigID("ID-foo"), builders.ConfigName("foo")),
|
||||||
*Config(ConfigID("ID-bar"), ConfigName("bar"), ConfigLabels(map[string]string{
|
*builders.Config(builders.ConfigID("ID-bar"), builders.ConfigName("bar"), builders.ConfigLabels(map[string]string{
|
||||||
"label": "label-bar",
|
"label": "label-bar",
|
||||||
})),
|
})),
|
||||||
}, nil
|
}, nil
|
||||||
|
@ -116,15 +116,15 @@ func TestConfigListWithFormat(t *testing.T) {
|
||||||
cli := test.NewFakeCli(&fakeClient{
|
cli := test.NewFakeCli(&fakeClient{
|
||||||
configListFunc: func(_ context.Context, options types.ConfigListOptions) ([]swarm.Config, error) {
|
configListFunc: func(_ context.Context, options types.ConfigListOptions) ([]swarm.Config, error) {
|
||||||
return []swarm.Config{
|
return []swarm.Config{
|
||||||
*Config(ConfigID("ID-foo"), ConfigName("foo")),
|
*builders.Config(builders.ConfigID("ID-foo"), builders.ConfigName("foo")),
|
||||||
*Config(ConfigID("ID-bar"), ConfigName("bar"), ConfigLabels(map[string]string{
|
*builders.Config(builders.ConfigID("ID-bar"), builders.ConfigName("bar"), builders.ConfigLabels(map[string]string{
|
||||||
"label": "label-bar",
|
"label": "label-bar",
|
||||||
})),
|
})),
|
||||||
}, nil
|
}, nil
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
cmd := newConfigListCommand(cli)
|
cmd := newConfigListCommand(cli)
|
||||||
cmd.Flags().Set("format", "{{ .Name }} {{ .Labels }}")
|
assert.Check(t, cmd.Flags().Set("format", "{{ .Name }} {{ .Labels }}"))
|
||||||
assert.NilError(t, cmd.Execute())
|
assert.NilError(t, cmd.Execute())
|
||||||
golden.Assert(t, cli.OutBuffer().String(), "config-list-with-format.golden")
|
golden.Assert(t, cli.OutBuffer().String(), "config-list-with-format.golden")
|
||||||
}
|
}
|
||||||
|
@ -135,24 +135,24 @@ func TestConfigListWithFilter(t *testing.T) {
|
||||||
assert.Check(t, is.Equal("foo", options.Filters.Get("name")[0]))
|
assert.Check(t, is.Equal("foo", options.Filters.Get("name")[0]))
|
||||||
assert.Check(t, is.Equal("lbl1=Label-bar", options.Filters.Get("label")[0]))
|
assert.Check(t, is.Equal("lbl1=Label-bar", options.Filters.Get("label")[0]))
|
||||||
return []swarm.Config{
|
return []swarm.Config{
|
||||||
*Config(ConfigID("ID-foo"),
|
*builders.Config(builders.ConfigID("ID-foo"),
|
||||||
ConfigName("foo"),
|
builders.ConfigName("foo"),
|
||||||
ConfigVersion(swarm.Version{Index: 10}),
|
builders.ConfigVersion(swarm.Version{Index: 10}),
|
||||||
ConfigCreatedAt(time.Now().Add(-2*time.Hour)),
|
builders.ConfigCreatedAt(time.Now().Add(-2*time.Hour)),
|
||||||
ConfigUpdatedAt(time.Now().Add(-1*time.Hour)),
|
builders.ConfigUpdatedAt(time.Now().Add(-1*time.Hour)),
|
||||||
),
|
),
|
||||||
*Config(ConfigID("ID-bar"),
|
*builders.Config(builders.ConfigID("ID-bar"),
|
||||||
ConfigName("bar"),
|
builders.ConfigName("bar"),
|
||||||
ConfigVersion(swarm.Version{Index: 11}),
|
builders.ConfigVersion(swarm.Version{Index: 11}),
|
||||||
ConfigCreatedAt(time.Now().Add(-2*time.Hour)),
|
builders.ConfigCreatedAt(time.Now().Add(-2*time.Hour)),
|
||||||
ConfigUpdatedAt(time.Now().Add(-1*time.Hour)),
|
builders.ConfigUpdatedAt(time.Now().Add(-1*time.Hour)),
|
||||||
),
|
),
|
||||||
}, nil
|
}, nil
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
cmd := newConfigListCommand(cli)
|
cmd := newConfigListCommand(cli)
|
||||||
cmd.Flags().Set("filter", "name=foo")
|
assert.Check(t, cmd.Flags().Set("filter", "name=foo"))
|
||||||
cmd.Flags().Set("filter", "label=lbl1=Label-bar")
|
assert.Check(t, cmd.Flags().Set("filter", "label=lbl1=Label-bar"))
|
||||||
assert.NilError(t, cmd.Execute())
|
assert.NilError(t, cmd.Execute())
|
||||||
golden.Assert(t, cli.OutBuffer().String(), "config-list-with-filter.golden")
|
golden.Assert(t, cli.OutBuffer().String(), "config-list-with-filter.golden")
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@ package container
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/docker/cli/cli"
|
"github.com/docker/cli/cli"
|
||||||
|
@ -153,7 +152,7 @@ func getExitStatus(errC <-chan error, resultC <-chan container.WaitResponse) err
|
||||||
select {
|
select {
|
||||||
case result := <-resultC:
|
case result := <-resultC:
|
||||||
if result.Error != nil {
|
if result.Error != nil {
|
||||||
return fmt.Errorf(result.Error.Message)
|
return errors.New(result.Error.Message)
|
||||||
}
|
}
|
||||||
if result.StatusCode != 0 {
|
if result.StatusCode != 0 {
|
||||||
return cli.StatusError{StatusCode: int(result.StatusCode)}
|
return cli.StatusError{StatusCode: int(result.StatusCode)}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package container
|
package container
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"io"
|
"io"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
@ -79,7 +78,7 @@ func TestNewAttachCommandErrors(t *testing.T) {
|
||||||
|
|
||||||
func TestGetExitStatus(t *testing.T) {
|
func TestGetExitStatus(t *testing.T) {
|
||||||
var (
|
var (
|
||||||
expectedErr = fmt.Errorf("unexpected error")
|
expectedErr = errors.New("unexpected error")
|
||||||
errC = make(chan error, 1)
|
errC = make(chan error, 1)
|
||||||
resultC = make(chan container.WaitResponse, 1)
|
resultC = make(chan container.WaitResponse, 1)
|
||||||
)
|
)
|
||||||
|
|
|
@ -3,7 +3,6 @@ package container
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
@ -225,7 +224,7 @@ func TestNewCreateCommandWithContentTrustErrors(t *testing.T) {
|
||||||
platform *specs.Platform,
|
platform *specs.Platform,
|
||||||
containerName string,
|
containerName string,
|
||||||
) (container.CreateResponse, error) {
|
) (container.CreateResponse, error) {
|
||||||
return container.CreateResponse{}, fmt.Errorf("shouldn't try to pull image")
|
return container.CreateResponse{}, errors.New("shouldn't try to pull image")
|
||||||
},
|
},
|
||||||
}, test.EnableContentTrust)
|
}, test.EnableContentTrust)
|
||||||
cli.SetNotaryClient(tc.notaryFunc)
|
cli.SetNotaryClient(tc.notaryFunc)
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
package container
|
package container
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"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/cli/internal/test/builders" // Import builders to get the builder function as package function
|
"github.com/docker/cli/internal/test/builders"
|
||||||
"github.com/docker/cli/opts"
|
"github.com/docker/cli/opts"
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
"gotest.tools/v3/assert"
|
"gotest.tools/v3/assert"
|
||||||
|
@ -146,7 +146,7 @@ func TestContainerListErrors(t *testing.T) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
containerListFunc: func(_ types.ContainerListOptions) ([]types.Container, error) {
|
containerListFunc: func(_ types.ContainerListOptions) ([]types.Container, error) {
|
||||||
return nil, fmt.Errorf("error listing containers")
|
return nil, errors.New("error listing containers")
|
||||||
},
|
},
|
||||||
expectedError: "error listing containers",
|
expectedError: "error listing containers",
|
||||||
},
|
},
|
||||||
|
@ -159,7 +159,7 @@ func TestContainerListErrors(t *testing.T) {
|
||||||
)
|
)
|
||||||
cmd.SetArgs(tc.args)
|
cmd.SetArgs(tc.args)
|
||||||
for key, value := range tc.flags {
|
for key, value := range tc.flags {
|
||||||
cmd.Flags().Set(key, value)
|
assert.Check(t, cmd.Flags().Set(key, value))
|
||||||
}
|
}
|
||||||
cmd.SetOut(io.Discard)
|
cmd.SetOut(io.Discard)
|
||||||
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
|
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
|
||||||
|
@ -170,11 +170,11 @@ func TestContainerListWithoutFormat(t *testing.T) {
|
||||||
cli := test.NewFakeCli(&fakeClient{
|
cli := test.NewFakeCli(&fakeClient{
|
||||||
containerListFunc: func(_ types.ContainerListOptions) ([]types.Container, error) {
|
containerListFunc: func(_ types.ContainerListOptions) ([]types.Container, error) {
|
||||||
return []types.Container{
|
return []types.Container{
|
||||||
*Container("c1"),
|
*builders.Container("c1"),
|
||||||
*Container("c2", WithName("foo")),
|
*builders.Container("c2", builders.WithName("foo")),
|
||||||
*Container("c3", WithPort(80, 80, TCP), WithPort(81, 81, TCP), WithPort(82, 82, TCP)),
|
*builders.Container("c3", builders.WithPort(80, 80, builders.TCP), builders.WithPort(81, 81, builders.TCP), builders.WithPort(82, 82, builders.TCP)),
|
||||||
*Container("c4", WithPort(81, 81, UDP)),
|
*builders.Container("c4", builders.WithPort(81, 81, builders.UDP)),
|
||||||
*Container("c5", WithPort(82, 82, IP("8.8.8.8"), TCP)),
|
*builders.Container("c5", builders.WithPort(82, 82, builders.IP("8.8.8.8"), builders.TCP)),
|
||||||
}, nil
|
}, nil
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
@ -187,13 +187,13 @@ func TestContainerListNoTrunc(t *testing.T) {
|
||||||
cli := test.NewFakeCli(&fakeClient{
|
cli := test.NewFakeCli(&fakeClient{
|
||||||
containerListFunc: func(_ types.ContainerListOptions) ([]types.Container, error) {
|
containerListFunc: func(_ types.ContainerListOptions) ([]types.Container, error) {
|
||||||
return []types.Container{
|
return []types.Container{
|
||||||
*Container("c1"),
|
*builders.Container("c1"),
|
||||||
*Container("c2", WithName("foo/bar")),
|
*builders.Container("c2", builders.WithName("foo/bar")),
|
||||||
}, nil
|
}, nil
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
cmd := newListCommand(cli)
|
cmd := newListCommand(cli)
|
||||||
cmd.Flags().Set("no-trunc", "true")
|
assert.Check(t, cmd.Flags().Set("no-trunc", "true"))
|
||||||
assert.NilError(t, cmd.Execute())
|
assert.NilError(t, cmd.Execute())
|
||||||
golden.Assert(t, cli.OutBuffer().String(), "container-list-without-format-no-trunc.golden")
|
golden.Assert(t, cli.OutBuffer().String(), "container-list-without-format-no-trunc.golden")
|
||||||
}
|
}
|
||||||
|
@ -203,13 +203,13 @@ func TestContainerListNamesMultipleTime(t *testing.T) {
|
||||||
cli := test.NewFakeCli(&fakeClient{
|
cli := test.NewFakeCli(&fakeClient{
|
||||||
containerListFunc: func(_ types.ContainerListOptions) ([]types.Container, error) {
|
containerListFunc: func(_ types.ContainerListOptions) ([]types.Container, error) {
|
||||||
return []types.Container{
|
return []types.Container{
|
||||||
*Container("c1"),
|
*builders.Container("c1"),
|
||||||
*Container("c2", WithName("foo/bar")),
|
*builders.Container("c2", builders.WithName("foo/bar")),
|
||||||
}, nil
|
}, nil
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
cmd := newListCommand(cli)
|
cmd := newListCommand(cli)
|
||||||
cmd.Flags().Set("format", "{{.Names}} {{.Names}}")
|
assert.Check(t, cmd.Flags().Set("format", "{{.Names}} {{.Names}}"))
|
||||||
assert.NilError(t, cmd.Execute())
|
assert.NilError(t, cmd.Execute())
|
||||||
golden.Assert(t, cli.OutBuffer().String(), "container-list-format-name-name.golden")
|
golden.Assert(t, cli.OutBuffer().String(), "container-list-format-name-name.golden")
|
||||||
}
|
}
|
||||||
|
@ -219,13 +219,13 @@ func TestContainerListFormatTemplateWithArg(t *testing.T) {
|
||||||
cli := test.NewFakeCli(&fakeClient{
|
cli := test.NewFakeCli(&fakeClient{
|
||||||
containerListFunc: func(_ types.ContainerListOptions) ([]types.Container, error) {
|
containerListFunc: func(_ types.ContainerListOptions) ([]types.Container, error) {
|
||||||
return []types.Container{
|
return []types.Container{
|
||||||
*Container("c1", WithLabel("some.label", "value")),
|
*builders.Container("c1", builders.WithLabel("some.label", "value")),
|
||||||
*Container("c2", WithName("foo/bar"), WithLabel("foo", "bar")),
|
*builders.Container("c2", builders.WithName("foo/bar"), builders.WithLabel("foo", "bar")),
|
||||||
}, nil
|
}, nil
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
cmd := newListCommand(cli)
|
cmd := newListCommand(cli)
|
||||||
cmd.Flags().Set("format", `{{.Names}} {{.Label "some.label"}}`)
|
assert.Check(t, cmd.Flags().Set("format", `{{.Names}} {{.Label "some.label"}}`))
|
||||||
assert.NilError(t, cmd.Execute())
|
assert.NilError(t, cmd.Execute())
|
||||||
golden.Assert(t, cli.OutBuffer().String(), "container-list-format-with-arg.golden")
|
golden.Assert(t, cli.OutBuffer().String(), "container-list-format-with-arg.golden")
|
||||||
}
|
}
|
||||||
|
@ -274,9 +274,9 @@ func TestContainerListFormatSizeSetsOption(t *testing.T) {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
cmd := newListCommand(cli)
|
cmd := newListCommand(cli)
|
||||||
cmd.Flags().Set("format", tc.format)
|
assert.Check(t, cmd.Flags().Set("format", tc.format))
|
||||||
if tc.sizeFlag != "" {
|
if tc.sizeFlag != "" {
|
||||||
cmd.Flags().Set("size", tc.sizeFlag)
|
assert.Check(t, cmd.Flags().Set("size", tc.sizeFlag))
|
||||||
}
|
}
|
||||||
assert.NilError(t, cmd.Execute())
|
assert.NilError(t, cmd.Execute())
|
||||||
})
|
})
|
||||||
|
@ -287,8 +287,8 @@ func TestContainerListWithConfigFormat(t *testing.T) {
|
||||||
cli := test.NewFakeCli(&fakeClient{
|
cli := test.NewFakeCli(&fakeClient{
|
||||||
containerListFunc: func(_ types.ContainerListOptions) ([]types.Container, error) {
|
containerListFunc: func(_ types.ContainerListOptions) ([]types.Container, error) {
|
||||||
return []types.Container{
|
return []types.Container{
|
||||||
*Container("c1", WithLabel("some.label", "value"), WithSize(10700000)),
|
*builders.Container("c1", builders.WithLabel("some.label", "value"), builders.WithSize(10700000)),
|
||||||
*Container("c2", WithName("foo/bar"), WithLabel("foo", "bar"), WithSize(3200000)),
|
*builders.Container("c2", builders.WithName("foo/bar"), builders.WithLabel("foo", "bar"), builders.WithSize(3200000)),
|
||||||
}, nil
|
}, nil
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
@ -304,8 +304,8 @@ func TestContainerListWithFormat(t *testing.T) {
|
||||||
cli := test.NewFakeCli(&fakeClient{
|
cli := test.NewFakeCli(&fakeClient{
|
||||||
containerListFunc: func(_ types.ContainerListOptions) ([]types.Container, error) {
|
containerListFunc: func(_ types.ContainerListOptions) ([]types.Container, error) {
|
||||||
return []types.Container{
|
return []types.Container{
|
||||||
*Container("c1", WithLabel("some.label", "value")),
|
*builders.Container("c1", builders.WithLabel("some.label", "value")),
|
||||||
*Container("c2", WithName("foo/bar"), WithLabel("foo", "bar")),
|
*builders.Container("c2", builders.WithName("foo/bar"), builders.WithLabel("foo", "bar")),
|
||||||
}, nil
|
}, nil
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
|
@ -541,7 +541,7 @@ func parse(flags *pflag.FlagSet, copts *containerOptions, serverOS string) (*con
|
||||||
return nil, errors.Errorf("--health-retries cannot be negative")
|
return nil, errors.Errorf("--health-retries cannot be negative")
|
||||||
}
|
}
|
||||||
if copts.healthStartPeriod < 0 {
|
if copts.healthStartPeriod < 0 {
|
||||||
return nil, fmt.Errorf("--health-start-period cannot be negative")
|
return nil, errors.New("--health-start-period cannot be negative")
|
||||||
}
|
}
|
||||||
|
|
||||||
healthConfig = &container.HealthConfig{
|
healthConfig = &container.HealthConfig{
|
||||||
|
|
|
@ -329,7 +329,7 @@ func TestParseHostname(t *testing.T) {
|
||||||
hostnameWithDomain := "--hostname=hostname.domainname"
|
hostnameWithDomain := "--hostname=hostname.domainname"
|
||||||
hostnameWithDomainTld := "--hostname=hostname.domainname.tld"
|
hostnameWithDomainTld := "--hostname=hostname.domainname.tld"
|
||||||
for hostname, expectedHostname := range validHostnames {
|
for hostname, expectedHostname := range validHostnames {
|
||||||
if config, _ := mustParse(t, fmt.Sprintf("--hostname=%s", hostname)); config.Hostname != expectedHostname {
|
if config, _ := mustParse(t, "--hostname="+hostname); config.Hostname != expectedHostname {
|
||||||
t.Fatalf("Expected the config to have 'hostname' as %q, got %q", expectedHostname, config.Hostname)
|
t.Fatalf("Expected the config to have 'hostname' as %q, got %q", expectedHostname, config.Hostname)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ package container
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"sort"
|
"sort"
|
||||||
"sync"
|
"sync"
|
||||||
|
@ -37,7 +37,7 @@ func TestRemoveForce(t *testing.T) {
|
||||||
mutex.Unlock()
|
mutex.Unlock()
|
||||||
|
|
||||||
if container == "nosuchcontainer" {
|
if container == "nosuchcontainer" {
|
||||||
return errdefs.NotFound(fmt.Errorf("Error: no such container: " + container))
|
return errdefs.NotFound(errors.New("Error: no such container: " + container))
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
|
|
|
@ -2,7 +2,6 @@ package container
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
"io"
|
"io"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
@ -65,7 +64,7 @@ func TestRunCommandWithContentTrustErrors(t *testing.T) {
|
||||||
platform *specs.Platform,
|
platform *specs.Platform,
|
||||||
containerName string,
|
containerName string,
|
||||||
) (container.CreateResponse, error) {
|
) (container.CreateResponse, error) {
|
||||||
return container.CreateResponse{}, fmt.Errorf("shouldn't try to pull image")
|
return container.CreateResponse{}, errors.New("shouldn't try to pull image")
|
||||||
},
|
},
|
||||||
}, test.EnableContentTrust)
|
}, test.EnableContentTrust)
|
||||||
cli.SetNotaryClient(tc.notaryFunc)
|
cli.SetNotaryClient(tc.notaryFunc)
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package context
|
package context
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
@ -77,7 +76,7 @@ func validateConfig(config map[string]string, allowedKeys map[string]struct{}) e
|
||||||
var errs []string
|
var errs []string
|
||||||
for k := range config {
|
for k := range config {
|
||||||
if _, ok := allowedKeys[k]; !ok {
|
if _, ok := allowedKeys[k]; !ok {
|
||||||
errs = append(errs, fmt.Sprintf("%s: unrecognized config key", k))
|
errs = append(errs, "unrecognized config key: "+k)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(errs) == 0 {
|
if len(errs) == 0 {
|
||||||
|
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
. "github.com/docker/cli/internal/test/builders" // Import builders to get the builder function as package function
|
"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"
|
"github.com/pkg/errors"
|
||||||
"gotest.tools/v3/assert"
|
"gotest.tools/v3/assert"
|
||||||
|
@ -50,7 +50,7 @@ func TestResolveWithCache(t *testing.T) {
|
||||||
cli := &fakeClient{
|
cli := &fakeClient{
|
||||||
nodeInspectFunc: func(nodeID string) (swarm.Node, []byte, error) {
|
nodeInspectFunc: func(nodeID string) (swarm.Node, []byte, error) {
|
||||||
inspectCounter++
|
inspectCounter++
|
||||||
return *Node(NodeName("node-foo")), []byte{}, nil
|
return *builders.Node(builders.NodeName("node-foo")), []byte{}, nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,14 +82,14 @@ func TestResolveNode(t *testing.T) {
|
||||||
{
|
{
|
||||||
nodeID: "nodeID",
|
nodeID: "nodeID",
|
||||||
nodeInspectFunc: func(string) (swarm.Node, []byte, error) {
|
nodeInspectFunc: func(string) (swarm.Node, []byte, error) {
|
||||||
return *Node(NodeName("node-foo")), []byte{}, nil
|
return *builders.Node(builders.NodeName("node-foo")), []byte{}, nil
|
||||||
},
|
},
|
||||||
expectedID: "node-foo",
|
expectedID: "node-foo",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
nodeID: "nodeID",
|
nodeID: "nodeID",
|
||||||
nodeInspectFunc: func(string) (swarm.Node, []byte, error) {
|
nodeInspectFunc: func(string) (swarm.Node, []byte, error) {
|
||||||
return *Node(NodeName(""), Hostname("node-hostname")), []byte{}, nil
|
return *builders.Node(builders.NodeName(""), builders.Hostname("node-hostname")), []byte{}, nil
|
||||||
},
|
},
|
||||||
expectedID: "node-hostname",
|
expectedID: "node-hostname",
|
||||||
},
|
},
|
||||||
|
@ -124,7 +124,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 *Service(ServiceName("service-foo")), []byte{}, nil
|
return *builders.Service(builders.ServiceName("service-foo")), []byte{}, nil
|
||||||
},
|
},
|
||||||
expectedID: "service-foo",
|
expectedID: "service-foo",
|
||||||
},
|
},
|
||||||
|
|
|
@ -459,7 +459,7 @@ func rewriteDockerfileFromForContentTrust(ctx context.Context, dockerfile io.Rea
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
line = dockerfileFromLinePattern.ReplaceAllLiteralString(line, fmt.Sprintf("FROM %s", reference.FamiliarString(trustedRef)))
|
line = dockerfileFromLinePattern.ReplaceAllLiteralString(line, "FROM "+reference.FamiliarString(trustedRef))
|
||||||
resolvedTags = append(resolvedTags, &resolvedTag{
|
resolvedTags = append(resolvedTags, &resolvedTag{
|
||||||
digestRef: trustedRef,
|
digestRef: trustedRef,
|
||||||
tagRef: ref,
|
tagRef: ref,
|
||||||
|
|
|
@ -223,7 +223,7 @@ func GetContextFromURL(out io.Writer, remoteURL, dockerfileName string) (io.Read
|
||||||
progressOutput := streamformatter.NewProgressOutput(out)
|
progressOutput := streamformatter.NewProgressOutput(out)
|
||||||
|
|
||||||
// Pass the response body through a progress reader.
|
// Pass the response body through a progress reader.
|
||||||
progReader := progress.NewProgressReader(response.Body, progressOutput, response.ContentLength, "", fmt.Sprintf("Downloading build context from remote url: %s", remoteURL))
|
progReader := progress.NewProgressReader(response.Body, progressOutput, response.ContentLength, "", "Downloading build context from remote url: "+remoteURL)
|
||||||
|
|
||||||
return GetContextFromReader(ioutils.NewReadCloserWrapper(progReader, func() error { return response.Body.Close() }), dockerfileName)
|
return GetContextFromReader(ioutils.NewReadCloserWrapper(progReader, func() error { return response.Body.Close() }), dockerfileName)
|
||||||
}
|
}
|
||||||
|
@ -231,7 +231,7 @@ func GetContextFromURL(out io.Writer, remoteURL, dockerfileName string) (io.Read
|
||||||
// getWithStatusError does an http.Get() and returns an error if the
|
// getWithStatusError does an http.Get() and returns an error if the
|
||||||
// status code is 4xx or 5xx.
|
// status code is 4xx or 5xx.
|
||||||
func getWithStatusError(url string) (resp *http.Response, err error) {
|
func getWithStatusError(url string) (resp *http.Response, err error) {
|
||||||
// #nosec G107
|
//nolint:gosec // Ignore G107: Potential HTTP request made with variable url
|
||||||
if resp, err = http.Get(url); err != nil {
|
if resp, err = http.Get(url); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -126,7 +126,6 @@ func TestGetContextFromReaderString(t *testing.T) {
|
||||||
tarReader := tar.NewReader(tarArchive)
|
tarReader := tar.NewReader(tarArchive)
|
||||||
|
|
||||||
_, err = tarReader.Next()
|
_, err = tarReader.Next()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Error when reading tar archive: %s", err)
|
t.Fatalf("Error when reading tar archive: %s", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package image
|
package image
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -112,7 +113,7 @@ func TestNewPullCommandWithContentTrustErrors(t *testing.T) {
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
cli := test.NewFakeCli(&fakeClient{
|
cli := test.NewFakeCli(&fakeClient{
|
||||||
imagePullFunc: func(ref string, options types.ImagePullOptions) (io.ReadCloser, error) {
|
imagePullFunc: func(ref string, options types.ImagePullOptions) (io.ReadCloser, error) {
|
||||||
return io.NopCloser(strings.NewReader("")), fmt.Errorf("shouldn't try to pull image")
|
return io.NopCloser(strings.NewReader("")), errors.New("shouldn't try to pull image")
|
||||||
},
|
},
|
||||||
}, test.EnableContentTrust)
|
}, test.EnableContentTrust)
|
||||||
cli.SetNotaryClient(tc.notaryFunc)
|
cli.SetNotaryClient(tc.notaryFunc)
|
||||||
|
|
|
@ -18,7 +18,7 @@ type notFound struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n notFound) Error() string {
|
func (n notFound) Error() string {
|
||||||
return fmt.Sprintf("Error: No such image: %s", n.imageID)
|
return "Error: No such image: " + n.imageID
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n notFound) NotFound() bool {
|
func (n notFound) NotFound() bool {
|
||||||
|
|
|
@ -2,7 +2,7 @@ package network
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"errors"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/docker/cli/cli"
|
"github.com/docker/cli/cli"
|
||||||
|
@ -10,6 +10,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"
|
||||||
"github.com/docker/docker/api/types/network"
|
"github.com/docker/docker/api/types/network"
|
||||||
|
"github.com/docker/docker/client"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -36,14 +37,14 @@ func newConnectCommand(dockerCli command.Cli) *cobra.Command {
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
options.network = args[0]
|
options.network = args[0]
|
||||||
options.container = args[1]
|
options.container = args[1]
|
||||||
return runConnect(dockerCli, options)
|
return runConnect(cmd.Context(), dockerCli.Client(), options)
|
||||||
},
|
},
|
||||||
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||||
if len(args) == 0 {
|
if len(args) == 0 {
|
||||||
return completion.NetworkNames(dockerCli)(cmd, args, toComplete)
|
return completion.NetworkNames(dockerCli)(cmd, args, toComplete)
|
||||||
}
|
}
|
||||||
network := args[0]
|
nw := args[0]
|
||||||
return completion.ContainerNames(dockerCli, true, not(isConnected(network)))(cmd, args, toComplete)
|
return completion.ContainerNames(dockerCli, true, not(isConnected(nw)))(cmd, args, toComplete)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,14 +58,13 @@ func newConnectCommand(dockerCli command.Cli) *cobra.Command {
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func runConnect(dockerCli command.Cli, options connectOptions) error {
|
func runConnect(ctx context.Context, apiClient client.NetworkAPIClient, options connectOptions) error {
|
||||||
client := dockerCli.Client()
|
|
||||||
|
|
||||||
driverOpts, err := convertDriverOpt(options.driverOpts)
|
driverOpts, err := convertDriverOpt(options.driverOpts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
epConfig := &network.EndpointSettings{
|
|
||||||
|
return apiClient.NetworkConnect(ctx, options.network, options.container, &network.EndpointSettings{
|
||||||
IPAMConfig: &network.EndpointIPAMConfig{
|
IPAMConfig: &network.EndpointIPAMConfig{
|
||||||
IPv4Address: options.ipaddress,
|
IPv4Address: options.ipaddress,
|
||||||
IPv6Address: options.ipv6address,
|
IPv6Address: options.ipv6address,
|
||||||
|
@ -73,9 +73,7 @@ func runConnect(dockerCli command.Cli, options connectOptions) error {
|
||||||
Links: options.links.GetAll(),
|
Links: options.links.GetAll(),
|
||||||
Aliases: options.aliases,
|
Aliases: options.aliases,
|
||||||
DriverOpts: driverOpts,
|
DriverOpts: driverOpts,
|
||||||
}
|
})
|
||||||
|
|
||||||
return client.NetworkConnect(context.Background(), options.network, options.container, epConfig)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func convertDriverOpt(opts []string) (map[string]string, error) {
|
func convertDriverOpt(opts []string) (map[string]string, error) {
|
||||||
|
@ -85,7 +83,7 @@ func convertDriverOpt(opts []string) (map[string]string, error) {
|
||||||
// TODO(thaJeztah): we should probably not accept whitespace here (both for key and value).
|
// TODO(thaJeztah): we should probably not accept whitespace here (both for key and value).
|
||||||
k = strings.TrimSpace(k)
|
k = strings.TrimSpace(k)
|
||||||
if !ok || k == "" {
|
if !ok || k == "" {
|
||||||
return nil, fmt.Errorf("invalid key/value pair format in driver options")
|
return nil, errors.New("invalid key/value pair format in driver options")
|
||||||
}
|
}
|
||||||
driverOpt[k] = strings.TrimSpace(v)
|
driverOpt[k] = strings.TrimSpace(v)
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ import (
|
||||||
"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"
|
"github.com/docker/docker/api/types"
|
||||||
"github.com/docker/docker/api/types/filters"
|
"github.com/docker/docker/api/types/filters"
|
||||||
"github.com/google/go-cmp/cmp"
|
"github.com/google/go-cmp/cmp"
|
||||||
|
@ -59,10 +59,10 @@ func TestNetworkList(t *testing.T) {
|
||||||
}
|
}
|
||||||
assert.Check(t, is.DeepEqual(expectedOpts, options, cmp.AllowUnexported(filters.Args{})))
|
assert.Check(t, is.DeepEqual(expectedOpts, options, cmp.AllowUnexported(filters.Args{})))
|
||||||
|
|
||||||
return []types.NetworkResource{*NetworkResource(NetworkResourceID("123454321"),
|
return []types.NetworkResource{*builders.NetworkResource(builders.NetworkResourceID("123454321"),
|
||||||
NetworkResourceName("network_1"),
|
builders.NetworkResourceName("network_1"),
|
||||||
NetworkResourceDriver("09.7.01"),
|
builders.NetworkResourceDriver("09.7.01"),
|
||||||
NetworkResourceScope("global"))}, nil
|
builders.NetworkResourceScope("global"))}, nil
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -73,9 +73,9 @@ func TestNetworkList(t *testing.T) {
|
||||||
golden: "network-list-sort.golden",
|
golden: "network-list-sort.golden",
|
||||||
networkListFunc: func(ctx context.Context, options types.NetworkListOptions) ([]types.NetworkResource, error) {
|
networkListFunc: func(ctx context.Context, options types.NetworkListOptions) ([]types.NetworkResource, error) {
|
||||||
return []types.NetworkResource{
|
return []types.NetworkResource{
|
||||||
*NetworkResource(NetworkResourceName("network-2-foo")),
|
*builders.NetworkResource(builders.NetworkResourceName("network-2-foo")),
|
||||||
*NetworkResource(NetworkResourceName("network-1-foo")),
|
*builders.NetworkResource(builders.NetworkResourceName("network-1-foo")),
|
||||||
*NetworkResource(NetworkResourceName("network-10-foo")),
|
*builders.NetworkResource(builders.NetworkResourceName("network-10-foo")),
|
||||||
}, nil
|
}, nil
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -86,7 +86,7 @@ func TestNetworkList(t *testing.T) {
|
||||||
cli := test.NewFakeCli(&fakeClient{networkListFunc: tc.networkListFunc})
|
cli := test.NewFakeCli(&fakeClient{networkListFunc: tc.networkListFunc})
|
||||||
cmd := newListCommand(cli)
|
cmd := newListCommand(cli)
|
||||||
for key, value := range tc.flags {
|
for key, value := range tc.flags {
|
||||||
cmd.Flags().Set(key, value)
|
assert.Check(t, cmd.Flags().Set(key, value))
|
||||||
}
|
}
|
||||||
assert.NilError(t, cmd.Execute())
|
assert.NilError(t, cmd.Execute())
|
||||||
golden.Assert(t, cli.OutBuffer().String(), tc.golden)
|
golden.Assert(t, cli.OutBuffer().String(), tc.golden)
|
||||||
|
|
|
@ -5,7 +5,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/docker/cli/internal/test"
|
"github.com/docker/cli/internal/test"
|
||||||
. "github.com/docker/cli/internal/test/builders" // Import builders to get the builder function as package functions
|
"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"
|
"github.com/pkg/errors"
|
||||||
"gotest.tools/v3/assert"
|
"gotest.tools/v3/assert"
|
||||||
|
@ -52,7 +52,7 @@ func TestNodeDemoteNoChange(t *testing.T) {
|
||||||
cmd := newDemoteCommand(
|
cmd := newDemoteCommand(
|
||||||
test.NewFakeCli(&fakeClient{
|
test.NewFakeCli(&fakeClient{
|
||||||
nodeInspectFunc: func() (swarm.Node, []byte, error) {
|
nodeInspectFunc: func() (swarm.Node, []byte, error) {
|
||||||
return *Node(), []byte{}, nil
|
return *builders.Node(), []byte{}, nil
|
||||||
},
|
},
|
||||||
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 {
|
||||||
|
@ -69,7 +69,7 @@ func TestNodeDemoteMultipleNode(t *testing.T) {
|
||||||
cmd := newDemoteCommand(
|
cmd := newDemoteCommand(
|
||||||
test.NewFakeCli(&fakeClient{
|
test.NewFakeCli(&fakeClient{
|
||||||
nodeInspectFunc: func() (swarm.Node, []byte, error) {
|
nodeInspectFunc: func() (swarm.Node, []byte, error) {
|
||||||
return *Node(Manager()), []byte{}, nil
|
return *builders.Node(builders.Manager()), []byte{}, nil
|
||||||
},
|
},
|
||||||
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 {
|
||||||
|
|
|
@ -6,7 +6,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/docker/cli/internal/test"
|
"github.com/docker/cli/internal/test"
|
||||||
. "github.com/docker/cli/internal/test/builders" // Import builders to get the builder function as package functions
|
"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"
|
"github.com/pkg/errors"
|
||||||
|
@ -71,7 +71,7 @@ func TestNodeInspectErrors(t *testing.T) {
|
||||||
}))
|
}))
|
||||||
cmd.SetArgs(tc.args)
|
cmd.SetArgs(tc.args)
|
||||||
for key, value := range tc.flags {
|
for key, value := range tc.flags {
|
||||||
cmd.Flags().Set(key, value)
|
assert.Check(t, cmd.Flags().Set(key, value))
|
||||||
}
|
}
|
||||||
cmd.SetOut(io.Discard)
|
cmd.SetOut(io.Discard)
|
||||||
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
|
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
|
||||||
|
@ -86,7 +86,7 @@ func TestNodeInspectPretty(t *testing.T) {
|
||||||
{
|
{
|
||||||
name: "simple",
|
name: "simple",
|
||||||
nodeInspectFunc: func() (swarm.Node, []byte, error) {
|
nodeInspectFunc: func() (swarm.Node, []byte, error) {
|
||||||
return *Node(NodeLabels(map[string]string{
|
return *builders.Node(builders.NodeLabels(map[string]string{
|
||||||
"lbl1": "value1",
|
"lbl1": "value1",
|
||||||
})), []byte{}, nil
|
})), []byte{}, nil
|
||||||
},
|
},
|
||||||
|
@ -94,13 +94,13 @@ func TestNodeInspectPretty(t *testing.T) {
|
||||||
{
|
{
|
||||||
name: "manager",
|
name: "manager",
|
||||||
nodeInspectFunc: func() (swarm.Node, []byte, error) {
|
nodeInspectFunc: func() (swarm.Node, []byte, error) {
|
||||||
return *Node(Manager()), []byte{}, nil
|
return *builders.Node(builders.Manager()), []byte{}, nil
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "manager-leader",
|
name: "manager-leader",
|
||||||
nodeInspectFunc: func() (swarm.Node, []byte, error) {
|
nodeInspectFunc: func() (swarm.Node, []byte, error) {
|
||||||
return *Node(Manager(Leader())), []byte{}, nil
|
return *builders.Node(builders.Manager(builders.Leader())), []byte{}, nil
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -110,7 +110,7 @@ func TestNodeInspectPretty(t *testing.T) {
|
||||||
})
|
})
|
||||||
cmd := newInspectCommand(cli)
|
cmd := newInspectCommand(cli)
|
||||||
cmd.SetArgs([]string{"nodeID"})
|
cmd.SetArgs([]string{"nodeID"})
|
||||||
cmd.Flags().Set("pretty", "true")
|
assert.Check(t, cmd.Flags().Set("pretty", "true"))
|
||||||
assert.NilError(t, cmd.Execute())
|
assert.NilError(t, cmd.Execute())
|
||||||
golden.Assert(t, cli.OutBuffer().String(), fmt.Sprintf("node-inspect-pretty.%s.golden", tc.name))
|
golden.Assert(t, cli.OutBuffer().String(), fmt.Sprintf("node-inspect-pretty.%s.golden", tc.name))
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,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/cli/internal/test/builders" // Import builders to get the builder function as package function
|
"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"
|
"github.com/pkg/errors"
|
||||||
|
@ -56,9 +56,9 @@ func TestNodeList(t *testing.T) {
|
||||||
cli := test.NewFakeCli(&fakeClient{
|
cli := test.NewFakeCli(&fakeClient{
|
||||||
nodeListFunc: func() ([]swarm.Node, error) {
|
nodeListFunc: func() ([]swarm.Node, error) {
|
||||||
return []swarm.Node{
|
return []swarm.Node{
|
||||||
*Node(NodeID("nodeID1"), Hostname("node-2-foo"), Manager(Leader()), EngineVersion(".")),
|
*builders.Node(builders.NodeID("nodeID1"), builders.Hostname("node-2-foo"), builders.Manager(builders.Leader()), builders.EngineVersion(".")),
|
||||||
*Node(NodeID("nodeID2"), Hostname("node-10-foo"), Manager(), EngineVersion("18.03.0-ce")),
|
*builders.Node(builders.NodeID("nodeID2"), builders.Hostname("node-10-foo"), builders.Manager(), builders.EngineVersion("18.03.0-ce")),
|
||||||
*Node(NodeID("nodeID3"), Hostname("node-1-foo")),
|
*builders.Node(builders.NodeID("nodeID3"), builders.Hostname("node-1-foo")),
|
||||||
}, nil
|
}, nil
|
||||||
},
|
},
|
||||||
infoFunc: func() (types.Info, error) {
|
infoFunc: func() (types.Info, error) {
|
||||||
|
@ -79,12 +79,12 @@ func TestNodeListQuietShouldOnlyPrintIDs(t *testing.T) {
|
||||||
cli := test.NewFakeCli(&fakeClient{
|
cli := test.NewFakeCli(&fakeClient{
|
||||||
nodeListFunc: func() ([]swarm.Node, error) {
|
nodeListFunc: func() ([]swarm.Node, error) {
|
||||||
return []swarm.Node{
|
return []swarm.Node{
|
||||||
*Node(NodeID("nodeID1")),
|
*builders.Node(builders.NodeID("nodeID1")),
|
||||||
}, nil
|
}, nil
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
cmd := newListCommand(cli)
|
cmd := newListCommand(cli)
|
||||||
cmd.Flags().Set("quiet", "true")
|
assert.Check(t, cmd.Flags().Set("quiet", "true"))
|
||||||
assert.NilError(t, cmd.Execute())
|
assert.NilError(t, cmd.Execute())
|
||||||
assert.Check(t, is.Equal(cli.OutBuffer().String(), "nodeID1\n"))
|
assert.Check(t, is.Equal(cli.OutBuffer().String(), "nodeID1\n"))
|
||||||
}
|
}
|
||||||
|
@ -93,9 +93,9 @@ func TestNodeListDefaultFormatFromConfig(t *testing.T) {
|
||||||
cli := test.NewFakeCli(&fakeClient{
|
cli := test.NewFakeCli(&fakeClient{
|
||||||
nodeListFunc: func() ([]swarm.Node, error) {
|
nodeListFunc: func() ([]swarm.Node, error) {
|
||||||
return []swarm.Node{
|
return []swarm.Node{
|
||||||
*Node(NodeID("nodeID1"), Hostname("nodeHostname1"), Manager(Leader())),
|
*builders.Node(builders.NodeID("nodeID1"), builders.Hostname("nodeHostname1"), builders.Manager(builders.Leader())),
|
||||||
*Node(NodeID("nodeID2"), Hostname("nodeHostname2"), Manager()),
|
*builders.Node(builders.NodeID("nodeID2"), builders.Hostname("nodeHostname2"), builders.Manager()),
|
||||||
*Node(NodeID("nodeID3"), Hostname("nodeHostname3")),
|
*builders.Node(builders.NodeID("nodeID3"), builders.Hostname("nodeHostname3")),
|
||||||
}, nil
|
}, nil
|
||||||
},
|
},
|
||||||
infoFunc: func() (types.Info, error) {
|
infoFunc: func() (types.Info, error) {
|
||||||
|
@ -118,8 +118,8 @@ func TestNodeListFormat(t *testing.T) {
|
||||||
cli := test.NewFakeCli(&fakeClient{
|
cli := test.NewFakeCli(&fakeClient{
|
||||||
nodeListFunc: func() ([]swarm.Node, error) {
|
nodeListFunc: func() ([]swarm.Node, error) {
|
||||||
return []swarm.Node{
|
return []swarm.Node{
|
||||||
*Node(NodeID("nodeID1"), Hostname("nodeHostname1"), Manager(Leader())),
|
*builders.Node(builders.NodeID("nodeID1"), builders.Hostname("nodeHostname1"), builders.Manager(builders.Leader())),
|
||||||
*Node(NodeID("nodeID2"), Hostname("nodeHostname2"), Manager()),
|
*builders.Node(builders.NodeID("nodeID2"), builders.Hostname("nodeHostname2"), builders.Manager()),
|
||||||
}, nil
|
}, nil
|
||||||
},
|
},
|
||||||
infoFunc: func() (types.Info, error) {
|
infoFunc: func() (types.Info, error) {
|
||||||
|
@ -134,7 +134,7 @@ func TestNodeListFormat(t *testing.T) {
|
||||||
NodesFormat: "{{.ID}}: {{.Hostname}} {{.Status}}/{{.ManagerStatus}}",
|
NodesFormat: "{{.ID}}: {{.Hostname}} {{.Status}}/{{.ManagerStatus}}",
|
||||||
})
|
})
|
||||||
cmd := newListCommand(cli)
|
cmd := newListCommand(cli)
|
||||||
cmd.Flags().Set("format", "{{.Hostname}}: {{.ManagerStatus}}")
|
assert.Check(t, cmd.Flags().Set("format", "{{.Hostname}}: {{.ManagerStatus}}"))
|
||||||
assert.NilError(t, cmd.Execute())
|
assert.NilError(t, cmd.Execute())
|
||||||
golden.Assert(t, cli.OutBuffer().String(), "node-list-format-flag.golden")
|
golden.Assert(t, cli.OutBuffer().String(), "node-list-format-flag.golden")
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/docker/cli/internal/test"
|
"github.com/docker/cli/internal/test"
|
||||||
. "github.com/docker/cli/internal/test/builders" // Import builders to get the builder function as package function
|
"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"
|
"github.com/pkg/errors"
|
||||||
"gotest.tools/v3/assert"
|
"gotest.tools/v3/assert"
|
||||||
|
@ -52,7 +52,7 @@ func TestNodePromoteNoChange(t *testing.T) {
|
||||||
cmd := newPromoteCommand(
|
cmd := newPromoteCommand(
|
||||||
test.NewFakeCli(&fakeClient{
|
test.NewFakeCli(&fakeClient{
|
||||||
nodeInspectFunc: func() (swarm.Node, []byte, error) {
|
nodeInspectFunc: func() (swarm.Node, []byte, error) {
|
||||||
return *Node(Manager()), []byte{}, nil
|
return *builders.Node(builders.Manager()), []byte{}, nil
|
||||||
},
|
},
|
||||||
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 {
|
||||||
|
@ -69,7 +69,7 @@ func TestNodePromoteMultipleNode(t *testing.T) {
|
||||||
cmd := newPromoteCommand(
|
cmd := newPromoteCommand(
|
||||||
test.NewFakeCli(&fakeClient{
|
test.NewFakeCli(&fakeClient{
|
||||||
nodeInspectFunc: func() (swarm.Node, []byte, error) {
|
nodeInspectFunc: func() (swarm.Node, []byte, error) {
|
||||||
return *Node(), []byte{}, nil
|
return *builders.Node(), []byte{}, nil
|
||||||
},
|
},
|
||||||
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 {
|
||||||
|
|
|
@ -8,7 +8,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/docker/cli/internal/test"
|
"github.com/docker/cli/internal/test"
|
||||||
. "github.com/docker/cli/internal/test/builders" // Import builders to get the builder function as package function
|
"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"
|
"github.com/pkg/errors"
|
||||||
|
@ -57,7 +57,7 @@ func TestNodePsErrors(t *testing.T) {
|
||||||
cmd := newPsCommand(cli)
|
cmd := newPsCommand(cli)
|
||||||
cmd.SetArgs(tc.args)
|
cmd.SetArgs(tc.args)
|
||||||
for key, value := range tc.flags {
|
for key, value := range tc.flags {
|
||||||
cmd.Flags().Set(key, value)
|
assert.Check(t, cmd.Flags().Set(key, value))
|
||||||
}
|
}
|
||||||
cmd.SetOut(io.Discard)
|
cmd.SetOut(io.Discard)
|
||||||
assert.Error(t, cmd.Execute(), tc.expectedError)
|
assert.Error(t, cmd.Execute(), tc.expectedError)
|
||||||
|
@ -79,11 +79,11 @@ func TestNodePs(t *testing.T) {
|
||||||
name: "simple",
|
name: "simple",
|
||||||
args: []string{"nodeID"},
|
args: []string{"nodeID"},
|
||||||
nodeInspectFunc: func() (swarm.Node, []byte, error) {
|
nodeInspectFunc: func() (swarm.Node, []byte, error) {
|
||||||
return *Node(), []byte{}, nil
|
return *builders.Node(), []byte{}, nil
|
||||||
},
|
},
|
||||||
taskListFunc: func(options types.TaskListOptions) ([]swarm.Task, error) {
|
taskListFunc: func(options types.TaskListOptions) ([]swarm.Task, error) {
|
||||||
return []swarm.Task{
|
return []swarm.Task{
|
||||||
*Task(WithStatus(Timestamp(time.Now().Add(-2*time.Hour)), PortStatus([]swarm.PortConfig{
|
*builders.Task(builders.WithStatus(builders.Timestamp(time.Now().Add(-2*time.Hour)), builders.PortStatus([]swarm.PortConfig{
|
||||||
{
|
{
|
||||||
TargetPort: 80,
|
TargetPort: 80,
|
||||||
PublishedPort: 80,
|
PublishedPort: 80,
|
||||||
|
@ -107,16 +107,16 @@ func TestNodePs(t *testing.T) {
|
||||||
name: "with-errors",
|
name: "with-errors",
|
||||||
args: []string{"nodeID"},
|
args: []string{"nodeID"},
|
||||||
nodeInspectFunc: func() (swarm.Node, []byte, error) {
|
nodeInspectFunc: func() (swarm.Node, []byte, error) {
|
||||||
return *Node(), []byte{}, nil
|
return *builders.Node(), []byte{}, nil
|
||||||
},
|
},
|
||||||
taskListFunc: func(options types.TaskListOptions) ([]swarm.Task, error) {
|
taskListFunc: func(options types.TaskListOptions) ([]swarm.Task, error) {
|
||||||
return []swarm.Task{
|
return []swarm.Task{
|
||||||
*Task(TaskID("taskID1"), TaskServiceID("failure"),
|
*builders.Task(builders.TaskID("taskID1"), builders.TaskServiceID("failure"),
|
||||||
WithStatus(Timestamp(time.Now().Add(-2*time.Hour)), StatusErr("a task error"))),
|
builders.WithStatus(builders.Timestamp(time.Now().Add(-2*time.Hour)), builders.StatusErr("a task error"))),
|
||||||
*Task(TaskID("taskID2"), TaskServiceID("failure"),
|
*builders.Task(builders.TaskID("taskID2"), builders.TaskServiceID("failure"),
|
||||||
WithStatus(Timestamp(time.Now().Add(-3*time.Hour)), StatusErr("a task error"))),
|
builders.WithStatus(builders.Timestamp(time.Now().Add(-3*time.Hour)), builders.StatusErr("a task error"))),
|
||||||
*Task(TaskID("taskID3"), TaskServiceID("failure"),
|
*builders.Task(builders.TaskID("taskID3"), builders.TaskServiceID("failure"),
|
||||||
WithStatus(Timestamp(time.Now().Add(-4*time.Hour)), StatusErr("a task error"))),
|
builders.WithStatus(builders.Timestamp(time.Now().Add(-4*time.Hour)), builders.StatusErr("a task error"))),
|
||||||
}, nil
|
}, nil
|
||||||
},
|
},
|
||||||
serviceInspectFunc: func(ctx context.Context, serviceID string, opts types.ServiceInspectOptions) (swarm.Service, []byte, error) {
|
serviceInspectFunc: func(ctx context.Context, serviceID string, opts types.ServiceInspectOptions) (swarm.Service, []byte, error) {
|
||||||
|
@ -142,7 +142,7 @@ func TestNodePs(t *testing.T) {
|
||||||
cmd := newPsCommand(cli)
|
cmd := newPsCommand(cli)
|
||||||
cmd.SetArgs(tc.args)
|
cmd.SetArgs(tc.args)
|
||||||
for key, value := range tc.flags {
|
for key, value := range tc.flags {
|
||||||
cmd.Flags().Set(key, value)
|
assert.Check(t, cmd.Flags().Set(key, value))
|
||||||
}
|
}
|
||||||
assert.NilError(t, cmd.Execute())
|
assert.NilError(t, cmd.Execute())
|
||||||
golden.Assert(t, cli.OutBuffer().String(), fmt.Sprintf("node-ps.%s.golden", tc.name))
|
golden.Assert(t, cli.OutBuffer().String(), fmt.Sprintf("node-ps.%s.golden", tc.name))
|
||||||
|
|
|
@ -5,7 +5,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/docker/cli/internal/test"
|
"github.com/docker/cli/internal/test"
|
||||||
. "github.com/docker/cli/internal/test/builders" // Import builders to get the builder function as package function
|
"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"
|
"github.com/pkg/errors"
|
||||||
"gotest.tools/v3/assert"
|
"gotest.tools/v3/assert"
|
||||||
|
@ -43,7 +43,7 @@ func TestNodeUpdateErrors(t *testing.T) {
|
||||||
{
|
{
|
||||||
args: []string{"nodeID"},
|
args: []string{"nodeID"},
|
||||||
nodeInspectFunc: func() (swarm.Node, []byte, error) {
|
nodeInspectFunc: func() (swarm.Node, []byte, error) {
|
||||||
return *Node(NodeLabels(map[string]string{
|
return *builders.Node(builders.NodeLabels(map[string]string{
|
||||||
"key": "value",
|
"key": "value",
|
||||||
})), []byte{}, nil
|
})), []byte{}, nil
|
||||||
},
|
},
|
||||||
|
@ -61,7 +61,7 @@ func TestNodeUpdateErrors(t *testing.T) {
|
||||||
}))
|
}))
|
||||||
cmd.SetArgs(tc.args)
|
cmd.SetArgs(tc.args)
|
||||||
for key, value := range tc.flags {
|
for key, value := range tc.flags {
|
||||||
cmd.Flags().Set(key, value)
|
assert.Check(t, cmd.Flags().Set(key, value))
|
||||||
}
|
}
|
||||||
cmd.SetOut(io.Discard)
|
cmd.SetOut(io.Discard)
|
||||||
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
|
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
|
||||||
|
@ -81,7 +81,7 @@ func TestNodeUpdate(t *testing.T) {
|
||||||
"role": "manager",
|
"role": "manager",
|
||||||
},
|
},
|
||||||
nodeInspectFunc: func() (swarm.Node, []byte, error) {
|
nodeInspectFunc: func() (swarm.Node, []byte, error) {
|
||||||
return *Node(), []byte{}, nil
|
return *builders.Node(), []byte{}, nil
|
||||||
},
|
},
|
||||||
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 {
|
||||||
|
@ -96,7 +96,7 @@ func TestNodeUpdate(t *testing.T) {
|
||||||
"availability": "drain",
|
"availability": "drain",
|
||||||
},
|
},
|
||||||
nodeInspectFunc: func() (swarm.Node, []byte, error) {
|
nodeInspectFunc: func() (swarm.Node, []byte, error) {
|
||||||
return *Node(), []byte{}, nil
|
return *builders.Node(), []byte{}, nil
|
||||||
},
|
},
|
||||||
nodeUpdateFunc: func(nodeID string, version swarm.Version, node swarm.NodeSpec) error {
|
nodeUpdateFunc: func(nodeID string, version swarm.Version, node swarm.NodeSpec) error {
|
||||||
if node.Availability != swarm.NodeAvailabilityDrain {
|
if node.Availability != swarm.NodeAvailabilityDrain {
|
||||||
|
@ -111,7 +111,7 @@ func TestNodeUpdate(t *testing.T) {
|
||||||
"label-add": "lbl",
|
"label-add": "lbl",
|
||||||
},
|
},
|
||||||
nodeInspectFunc: func() (swarm.Node, []byte, error) {
|
nodeInspectFunc: func() (swarm.Node, []byte, error) {
|
||||||
return *Node(), []byte{}, nil
|
return *builders.Node(), []byte{}, nil
|
||||||
},
|
},
|
||||||
nodeUpdateFunc: func(nodeID string, version swarm.Version, node swarm.NodeSpec) error {
|
nodeUpdateFunc: func(nodeID string, version swarm.Version, node swarm.NodeSpec) error {
|
||||||
if _, present := node.Annotations.Labels["lbl"]; !present {
|
if _, present := node.Annotations.Labels["lbl"]; !present {
|
||||||
|
@ -126,7 +126,7 @@ func TestNodeUpdate(t *testing.T) {
|
||||||
"label-add": "key=value",
|
"label-add": "key=value",
|
||||||
},
|
},
|
||||||
nodeInspectFunc: func() (swarm.Node, []byte, error) {
|
nodeInspectFunc: func() (swarm.Node, []byte, error) {
|
||||||
return *Node(), []byte{}, nil
|
return *builders.Node(), []byte{}, nil
|
||||||
},
|
},
|
||||||
nodeUpdateFunc: func(nodeID string, version swarm.Version, node swarm.NodeSpec) error {
|
nodeUpdateFunc: func(nodeID string, version swarm.Version, node swarm.NodeSpec) error {
|
||||||
if value, present := node.Annotations.Labels["key"]; !present || value != "value" {
|
if value, present := node.Annotations.Labels["key"]; !present || value != "value" {
|
||||||
|
@ -141,7 +141,7 @@ func TestNodeUpdate(t *testing.T) {
|
||||||
"label-rm": "key",
|
"label-rm": "key",
|
||||||
},
|
},
|
||||||
nodeInspectFunc: func() (swarm.Node, []byte, error) {
|
nodeInspectFunc: func() (swarm.Node, []byte, error) {
|
||||||
return *Node(NodeLabels(map[string]string{
|
return *builders.Node(builders.NodeLabels(map[string]string{
|
||||||
"key": "value",
|
"key": "value",
|
||||||
})), []byte{}, nil
|
})), []byte{}, nil
|
||||||
},
|
},
|
||||||
|
@ -161,7 +161,7 @@ func TestNodeUpdate(t *testing.T) {
|
||||||
}))
|
}))
|
||||||
cmd.SetArgs(tc.args)
|
cmd.SetArgs(tc.args)
|
||||||
for key, value := range tc.flags {
|
for key, value := range tc.flags {
|
||||||
cmd.Flags().Set(key, value)
|
assert.Check(t, cmd.Flags().Set(key, value))
|
||||||
}
|
}
|
||||||
assert.NilError(t, cmd.Execute())
|
assert.NilError(t, cmd.Execute())
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,7 +114,6 @@ func runCreate(dockerCli command.Cli, options pluginCreateOptions) error {
|
||||||
createCtx, err = archive.TarWithOptions(absContextDir, &archive.TarOptions{
|
createCtx, err = archive.TarWithOptions(absContextDir, &archive.TarOptions{
|
||||||
Compression: compression,
|
Compression: compression,
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package plugin
|
package plugin
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"runtime"
|
"runtime"
|
||||||
"testing"
|
"testing"
|
||||||
|
@ -91,16 +91,14 @@ func TestCreateErrorFromDaemon(t *testing.T) {
|
||||||
fs.WithFile("config.json", `{ "Name": "plugin-foo" }`))
|
fs.WithFile("config.json", `{ "Name": "plugin-foo" }`))
|
||||||
defer tmpDir.Remove()
|
defer tmpDir.Remove()
|
||||||
|
|
||||||
cli := test.NewFakeCli(&fakeClient{
|
cmd := newCreateCommand(test.NewFakeCli(&fakeClient{
|
||||||
pluginCreateFunc: func(createContext io.Reader, createOptions types.PluginCreateOptions) error {
|
pluginCreateFunc: func(createContext io.Reader, createOptions types.PluginCreateOptions) error {
|
||||||
return fmt.Errorf("Error creating plugin")
|
return errors.New("error creating plugin")
|
||||||
},
|
},
|
||||||
})
|
}))
|
||||||
|
|
||||||
cmd := newCreateCommand(cli)
|
|
||||||
cmd.SetArgs([]string{"plugin-foo", tmpDir.Path()})
|
cmd.SetArgs([]string{"plugin-foo", tmpDir.Path()})
|
||||||
cmd.SetOut(io.Discard)
|
cmd.SetOut(io.Discard)
|
||||||
assert.ErrorContains(t, cmd.Execute(), "Error creating plugin")
|
assert.ErrorContains(t, cmd.Execute(), "error creating plugin")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCreatePlugin(t *testing.T) {
|
func TestCreatePlugin(t *testing.T) {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package plugin
|
package plugin
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
@ -27,9 +27,9 @@ func TestPluginDisableErrors(t *testing.T) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
args: []string{"plugin-foo"},
|
args: []string{"plugin-foo"},
|
||||||
expectedError: "Error disabling plugin",
|
expectedError: "error disabling plugin",
|
||||||
pluginDisableFunc: func(name string, disableOptions types.PluginDisableOptions) error {
|
pluginDisableFunc: func(name string, disableOptions types.PluginDisableOptions) error {
|
||||||
return fmt.Errorf("Error disabling plugin")
|
return errors.New("error disabling plugin")
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package plugin
|
package plugin
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ func TestPluginEnableErrors(t *testing.T) {
|
||||||
{
|
{
|
||||||
args: []string{"plugin-foo"},
|
args: []string{"plugin-foo"},
|
||||||
pluginEnableFunc: func(name string, options types.PluginEnableOptions) error {
|
pluginEnableFunc: func(name string, options types.PluginEnableOptions) error {
|
||||||
return fmt.Errorf("failed to enable plugin")
|
return errors.New("failed to enable plugin")
|
||||||
},
|
},
|
||||||
expectedError: "failed to enable plugin",
|
expectedError: "failed to enable plugin",
|
||||||
},
|
},
|
||||||
|
@ -43,8 +43,7 @@ func TestPluginEnableErrors(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
cmd := newEnableCommand(
|
cmd := newEnableCommand(test.NewFakeCli(&fakeClient{
|
||||||
test.NewFakeCli(&fakeClient{
|
|
||||||
pluginEnableFunc: tc.pluginEnableFunc,
|
pluginEnableFunc: tc.pluginEnableFunc,
|
||||||
}))
|
}))
|
||||||
cmd.SetArgs(tc.args)
|
cmd.SetArgs(tc.args)
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
package plugin
|
package plugin
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"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"
|
||||||
|
|
||||||
"gotest.tools/v3/assert"
|
"gotest.tools/v3/assert"
|
||||||
"gotest.tools/v3/golden"
|
"gotest.tools/v3/golden"
|
||||||
)
|
)
|
||||||
|
@ -52,7 +52,7 @@ func TestInspectErrors(t *testing.T) {
|
||||||
args: []string{"foo"},
|
args: []string{"foo"},
|
||||||
expectedError: "error inspecting plugin",
|
expectedError: "error inspecting plugin",
|
||||||
inspectFunc: func(name string) (*types.Plugin, []byte, error) {
|
inspectFunc: func(name string) (*types.Plugin, []byte, error) {
|
||||||
return nil, nil, fmt.Errorf("error inspecting plugin")
|
return nil, nil, errors.New("error inspecting plugin")
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package plugin
|
package plugin
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
@ -38,9 +38,9 @@ func TestInstallErrors(t *testing.T) {
|
||||||
{
|
{
|
||||||
description: "installation error",
|
description: "installation error",
|
||||||
args: []string{"foo"},
|
args: []string{"foo"},
|
||||||
expectedError: "Error installing plugin",
|
expectedError: "error installing plugin",
|
||||||
installFunc: func(name string, options types.PluginInstallOptions) (io.ReadCloser, error) {
|
installFunc: func(name string, options types.PluginInstallOptions) (io.ReadCloser, error) {
|
||||||
return nil, fmt.Errorf("Error installing plugin")
|
return nil, errors.New("error installing plugin")
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -48,7 +48,7 @@ func TestInstallErrors(t *testing.T) {
|
||||||
args: []string{"foo"},
|
args: []string{"foo"},
|
||||||
expectedError: "docker image pull",
|
expectedError: "docker image pull",
|
||||||
installFunc: func(name string, options types.PluginInstallOptions) (io.ReadCloser, error) {
|
installFunc: func(name string, options types.PluginInstallOptions) (io.ReadCloser, error) {
|
||||||
return nil, fmt.Errorf("(image) when fetching")
|
return nil, errors.New("(image) when fetching")
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -92,7 +92,7 @@ func TestInstallContentTrustErrors(t *testing.T) {
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
cli := test.NewFakeCli(&fakeClient{
|
cli := test.NewFakeCli(&fakeClient{
|
||||||
pluginInstallFunc: func(name string, options types.PluginInstallOptions) (io.ReadCloser, error) {
|
pluginInstallFunc: func(name string, options types.PluginInstallOptions) (io.ReadCloser, error) {
|
||||||
return nil, fmt.Errorf("should not try to install plugin")
|
return nil, errors.New("should not try to install plugin")
|
||||||
},
|
},
|
||||||
}, test.EnableContentTrust)
|
}, test.EnableContentTrust)
|
||||||
cli.SetNotaryClient(tc.notaryFunc)
|
cli.SetNotaryClient(tc.notaryFunc)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package plugin
|
package plugin
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ func TestListErrors(t *testing.T) {
|
||||||
args: []string{},
|
args: []string{},
|
||||||
expectedError: "error listing plugins",
|
expectedError: "error listing plugins",
|
||||||
listFunc: func(filter filters.Args) (types.PluginsListResponse, error) {
|
listFunc: func(filter filters.Args) (types.PluginsListResponse, error) {
|
||||||
return types.PluginsListResponse{}, fmt.Errorf("error listing plugins")
|
return types.PluginsListResponse{}, errors.New("error listing plugins")
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package plugin
|
package plugin
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
@ -24,9 +24,9 @@ func TestRemoveErrors(t *testing.T) {
|
||||||
{
|
{
|
||||||
args: []string{"plugin-foo"},
|
args: []string{"plugin-foo"},
|
||||||
pluginRemoveFunc: func(name string, options types.PluginRemoveOptions) error {
|
pluginRemoveFunc: func(name string, options types.PluginRemoveOptions) error {
|
||||||
return fmt.Errorf("Error removing plugin")
|
return errors.New("error removing plugin")
|
||||||
},
|
},
|
||||||
expectedError: "Error removing plugin",
|
expectedError: "error removing plugin",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ package registry
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
@ -40,7 +41,7 @@ func (c fakeClient) Info(context.Context) (types.Info, error) {
|
||||||
|
|
||||||
func (c fakeClient) RegistryLogin(_ context.Context, auth types.AuthConfig) (registrytypes.AuthenticateOKBody, error) {
|
func (c fakeClient) RegistryLogin(_ context.Context, auth types.AuthConfig) (registrytypes.AuthenticateOKBody, error) {
|
||||||
if auth.Password == expiredPassword {
|
if auth.Password == expiredPassword {
|
||||||
return registrytypes.AuthenticateOKBody{}, fmt.Errorf("Invalid Username or Password")
|
return registrytypes.AuthenticateOKBody{}, errors.New("Invalid Username or Password")
|
||||||
}
|
}
|
||||||
if auth.Password == useToken {
|
if auth.Password == useToken {
|
||||||
return registrytypes.AuthenticateOKBody{
|
return registrytypes.AuthenticateOKBody{
|
||||||
|
|
|
@ -3,10 +3,10 @@ package command_test
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
. "github.com/docker/cli/cli/command" // Prevents a circular import with "github.com/docker/cli/internal/test"
|
"github.com/docker/cli/cli/command"
|
||||||
configtypes "github.com/docker/cli/cli/config/types"
|
configtypes "github.com/docker/cli/cli/config/types"
|
||||||
"github.com/docker/cli/internal/test"
|
"github.com/docker/cli/internal/test"
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
|
@ -44,13 +44,11 @@ func TestGetDefaultAuthConfig(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
checkCredStore bool
|
checkCredStore bool
|
||||||
inputServerAddress string
|
inputServerAddress string
|
||||||
expectedErr string
|
|
||||||
expectedAuthConfig types.AuthConfig
|
expectedAuthConfig types.AuthConfig
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
checkCredStore: false,
|
checkCredStore: false,
|
||||||
inputServerAddress: "",
|
inputServerAddress: "",
|
||||||
expectedErr: "",
|
|
||||||
expectedAuthConfig: types.AuthConfig{
|
expectedAuthConfig: types.AuthConfig{
|
||||||
ServerAddress: "",
|
ServerAddress: "",
|
||||||
Username: "",
|
Username: "",
|
||||||
|
@ -60,39 +58,32 @@ func TestGetDefaultAuthConfig(t *testing.T) {
|
||||||
{
|
{
|
||||||
checkCredStore: true,
|
checkCredStore: true,
|
||||||
inputServerAddress: testAuthConfigs[0].ServerAddress,
|
inputServerAddress: testAuthConfigs[0].ServerAddress,
|
||||||
expectedErr: "",
|
|
||||||
expectedAuthConfig: testAuthConfigs[0],
|
expectedAuthConfig: testAuthConfigs[0],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
checkCredStore: true,
|
checkCredStore: true,
|
||||||
inputServerAddress: testAuthConfigs[1].ServerAddress,
|
inputServerAddress: testAuthConfigs[1].ServerAddress,
|
||||||
expectedErr: "",
|
|
||||||
expectedAuthConfig: testAuthConfigs[1],
|
expectedAuthConfig: testAuthConfigs[1],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
checkCredStore: true,
|
checkCredStore: true,
|
||||||
inputServerAddress: fmt.Sprintf("https://%s", testAuthConfigs[1].ServerAddress),
|
inputServerAddress: "https://" + testAuthConfigs[1].ServerAddress,
|
||||||
expectedErr: "",
|
|
||||||
expectedAuthConfig: testAuthConfigs[1],
|
expectedAuthConfig: testAuthConfigs[1],
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
cli := test.NewFakeCli(&fakeClient{})
|
cli := test.NewFakeCli(&fakeClient{})
|
||||||
errBuf := new(bytes.Buffer)
|
errBuf := new(bytes.Buffer)
|
||||||
cli.SetErr(errBuf)
|
cli.SetErr(errBuf)
|
||||||
|
cli.ConfigFile().Filename = filepath.Join(t.TempDir(), "config")
|
||||||
for _, authconfig := range testAuthConfigs {
|
for _, authconfig := range testAuthConfigs {
|
||||||
cli.ConfigFile().GetCredentialsStore(authconfig.ServerAddress).Store(configtypes.AuthConfig(authconfig))
|
assert.Check(t, cli.ConfigFile().GetCredentialsStore(authconfig.ServerAddress).Store(configtypes.AuthConfig(authconfig)))
|
||||||
}
|
}
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
serverAddress := tc.inputServerAddress
|
serverAddress := tc.inputServerAddress
|
||||||
authconfig, err := GetDefaultAuthConfig(cli, tc.checkCredStore, serverAddress, serverAddress == "https://index.docker.io/v1/")
|
authconfig, err := command.GetDefaultAuthConfig(cli, tc.checkCredStore, serverAddress, serverAddress == "https://index.docker.io/v1/")
|
||||||
if tc.expectedErr != "" {
|
|
||||||
assert.Check(t, err != nil)
|
|
||||||
assert.Check(t, is.Equal(tc.expectedErr, err.Error()))
|
|
||||||
} else {
|
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
assert.Check(t, is.DeepEqual(tc.expectedAuthConfig, authconfig))
|
assert.Check(t, is.DeepEqual(tc.expectedAuthConfig, authconfig))
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetDefaultAuthConfig_HelperError(t *testing.T) {
|
func TestGetDefaultAuthConfig_HelperError(t *testing.T) {
|
||||||
|
@ -104,7 +95,8 @@ func TestGetDefaultAuthConfig_HelperError(t *testing.T) {
|
||||||
expectedAuthConfig := types.AuthConfig{
|
expectedAuthConfig := types.AuthConfig{
|
||||||
ServerAddress: serverAddress,
|
ServerAddress: serverAddress,
|
||||||
}
|
}
|
||||||
authconfig, err := GetDefaultAuthConfig(cli, true, serverAddress, serverAddress == "https://index.docker.io/v1/")
|
const isDefaultRegistry = false // registry is not "https://index.docker.io/v1/"
|
||||||
|
authconfig, err := command.GetDefaultAuthConfig(cli, true, serverAddress, isDefaultRegistry)
|
||||||
assert.Check(t, is.DeepEqual(expectedAuthConfig, authconfig))
|
assert.Check(t, is.DeepEqual(expectedAuthConfig, authconfig))
|
||||||
assert.Check(t, is.ErrorContains(err, "docker-credential-fake-does-not-exist"))
|
assert.Check(t, is.ErrorContains(err, "docker-credential-fake-does-not-exist"))
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/docker/cli/internal/test"
|
"github.com/docker/cli/internal/test"
|
||||||
. "github.com/docker/cli/internal/test/builders" // Import builders to get the builder function as package function
|
"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"
|
"github.com/pkg/errors"
|
||||||
"gotest.tools/v3/assert"
|
"gotest.tools/v3/assert"
|
||||||
|
@ -43,7 +43,7 @@ func TestSecretInspectErrors(t *testing.T) {
|
||||||
args: []string{"foo", "bar"},
|
args: []string{"foo", "bar"},
|
||||||
secretInspectFunc: func(_ context.Context, secretID string) (swarm.Secret, []byte, error) {
|
secretInspectFunc: func(_ context.Context, secretID string) (swarm.Secret, []byte, error) {
|
||||||
if secretID == "foo" {
|
if secretID == "foo" {
|
||||||
return *Secret(SecretName("foo")), nil, nil
|
return *builders.Secret(builders.SecretName("foo")), nil, nil
|
||||||
}
|
}
|
||||||
return swarm.Secret{}, nil, errors.Errorf("error while inspecting the secret")
|
return swarm.Secret{}, nil, errors.Errorf("error while inspecting the secret")
|
||||||
},
|
},
|
||||||
|
@ -58,7 +58,7 @@ func TestSecretInspectErrors(t *testing.T) {
|
||||||
)
|
)
|
||||||
cmd.SetArgs(tc.args)
|
cmd.SetArgs(tc.args)
|
||||||
for key, value := range tc.flags {
|
for key, value := range tc.flags {
|
||||||
cmd.Flags().Set(key, value)
|
assert.Check(t, cmd.Flags().Set(key, value))
|
||||||
}
|
}
|
||||||
cmd.SetOut(io.Discard)
|
cmd.SetOut(io.Discard)
|
||||||
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
|
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
|
||||||
|
@ -78,14 +78,14 @@ func TestSecretInspectWithoutFormat(t *testing.T) {
|
||||||
if name != "foo" {
|
if name != "foo" {
|
||||||
return swarm.Secret{}, nil, errors.Errorf("Invalid name, expected %s, got %s", "foo", name)
|
return swarm.Secret{}, nil, errors.Errorf("Invalid name, expected %s, got %s", "foo", name)
|
||||||
}
|
}
|
||||||
return *Secret(SecretID("ID-foo"), SecretName("foo")), nil, nil
|
return *builders.Secret(builders.SecretID("ID-foo"), builders.SecretName("foo")), nil, nil
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "multiple-secrets-with-labels",
|
name: "multiple-secrets-with-labels",
|
||||||
args: []string{"foo", "bar"},
|
args: []string{"foo", "bar"},
|
||||||
secretInspectFunc: func(_ context.Context, name string) (swarm.Secret, []byte, error) {
|
secretInspectFunc: func(_ context.Context, name string) (swarm.Secret, []byte, error) {
|
||||||
return *Secret(SecretID("ID-"+name), SecretName(name), SecretLabels(map[string]string{
|
return *builders.Secret(builders.SecretID("ID-"+name), builders.SecretName(name), builders.SecretLabels(map[string]string{
|
||||||
"label1": "label-foo",
|
"label1": "label-foo",
|
||||||
})), nil, nil
|
})), nil, nil
|
||||||
},
|
},
|
||||||
|
@ -104,7 +104,7 @@ func TestSecretInspectWithoutFormat(t *testing.T) {
|
||||||
|
|
||||||
func TestSecretInspectWithFormat(t *testing.T) {
|
func TestSecretInspectWithFormat(t *testing.T) {
|
||||||
secretInspectFunc := func(_ context.Context, name string) (swarm.Secret, []byte, error) {
|
secretInspectFunc := func(_ context.Context, name string) (swarm.Secret, []byte, error) {
|
||||||
return *Secret(SecretName("foo"), SecretLabels(map[string]string{
|
return *builders.Secret(builders.SecretName("foo"), builders.SecretLabels(map[string]string{
|
||||||
"label1": "label-foo",
|
"label1": "label-foo",
|
||||||
})), nil, nil
|
})), nil, nil
|
||||||
}
|
}
|
||||||
|
@ -133,7 +133,7 @@ func TestSecretInspectWithFormat(t *testing.T) {
|
||||||
})
|
})
|
||||||
cmd := newSecretInspectCommand(cli)
|
cmd := newSecretInspectCommand(cli)
|
||||||
cmd.SetArgs(tc.args)
|
cmd.SetArgs(tc.args)
|
||||||
cmd.Flags().Set("format", tc.format)
|
assert.Check(t, cmd.Flags().Set("format", tc.format))
|
||||||
assert.NilError(t, cmd.Execute())
|
assert.NilError(t, cmd.Execute())
|
||||||
golden.Assert(t, cli.OutBuffer().String(), fmt.Sprintf("secret-inspect-with-format.%s.golden", tc.name))
|
golden.Assert(t, cli.OutBuffer().String(), fmt.Sprintf("secret-inspect-with-format.%s.golden", tc.name))
|
||||||
}
|
}
|
||||||
|
@ -147,15 +147,15 @@ func TestSecretInspectPretty(t *testing.T) {
|
||||||
{
|
{
|
||||||
name: "simple",
|
name: "simple",
|
||||||
secretInspectFunc: func(_ context.Context, id string) (swarm.Secret, []byte, error) {
|
secretInspectFunc: func(_ context.Context, id string) (swarm.Secret, []byte, error) {
|
||||||
return *Secret(
|
return *builders.Secret(
|
||||||
SecretLabels(map[string]string{
|
builders.SecretLabels(map[string]string{
|
||||||
"lbl1": "value1",
|
"lbl1": "value1",
|
||||||
}),
|
}),
|
||||||
SecretID("secretID"),
|
builders.SecretID("secretID"),
|
||||||
SecretName("secretName"),
|
builders.SecretName("secretName"),
|
||||||
SecretDriver("driver"),
|
builders.SecretDriver("driver"),
|
||||||
SecretCreatedAt(time.Time{}),
|
builders.SecretCreatedAt(time.Time{}),
|
||||||
SecretUpdatedAt(time.Time{}),
|
builders.SecretUpdatedAt(time.Time{}),
|
||||||
), []byte{}, nil
|
), []byte{}, nil
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -166,7 +166,7 @@ func TestSecretInspectPretty(t *testing.T) {
|
||||||
})
|
})
|
||||||
cmd := newSecretInspectCommand(cli)
|
cmd := newSecretInspectCommand(cli)
|
||||||
cmd.SetArgs([]string{"secretID"})
|
cmd.SetArgs([]string{"secretID"})
|
||||||
cmd.Flags().Set("pretty", "true")
|
assert.Check(t, cmd.Flags().Set("pretty", "true"))
|
||||||
assert.NilError(t, cmd.Execute())
|
assert.NilError(t, cmd.Execute())
|
||||||
golden.Assert(t, cli.OutBuffer().String(), fmt.Sprintf("secret-inspect-pretty.%s.golden", tc.name))
|
golden.Assert(t, cli.OutBuffer().String(), fmt.Sprintf("secret-inspect-pretty.%s.golden", tc.name))
|
||||||
}
|
}
|
||||||
|
|
|
@ -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/cli/internal/test/builders" // Import builders to get the builder function as package function
|
"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"
|
"github.com/pkg/errors"
|
||||||
|
@ -50,25 +50,25 @@ func TestSecretList(t *testing.T) {
|
||||||
cli := test.NewFakeCli(&fakeClient{
|
cli := test.NewFakeCli(&fakeClient{
|
||||||
secretListFunc: func(_ context.Context, options types.SecretListOptions) ([]swarm.Secret, error) {
|
secretListFunc: func(_ context.Context, options types.SecretListOptions) ([]swarm.Secret, error) {
|
||||||
return []swarm.Secret{
|
return []swarm.Secret{
|
||||||
*Secret(SecretID("ID-1-foo"),
|
*builders.Secret(builders.SecretID("ID-1-foo"),
|
||||||
SecretName("1-foo"),
|
builders.SecretName("1-foo"),
|
||||||
SecretVersion(swarm.Version{Index: 10}),
|
builders.SecretVersion(swarm.Version{Index: 10}),
|
||||||
SecretCreatedAt(time.Now().Add(-2*time.Hour)),
|
builders.SecretCreatedAt(time.Now().Add(-2*time.Hour)),
|
||||||
SecretUpdatedAt(time.Now().Add(-1*time.Hour)),
|
builders.SecretUpdatedAt(time.Now().Add(-1*time.Hour)),
|
||||||
),
|
),
|
||||||
*Secret(SecretID("ID-10-foo"),
|
*builders.Secret(builders.SecretID("ID-10-foo"),
|
||||||
SecretName("10-foo"),
|
builders.SecretName("10-foo"),
|
||||||
SecretVersion(swarm.Version{Index: 11}),
|
builders.SecretVersion(swarm.Version{Index: 11}),
|
||||||
SecretCreatedAt(time.Now().Add(-2*time.Hour)),
|
builders.SecretCreatedAt(time.Now().Add(-2*time.Hour)),
|
||||||
SecretUpdatedAt(time.Now().Add(-1*time.Hour)),
|
builders.SecretUpdatedAt(time.Now().Add(-1*time.Hour)),
|
||||||
SecretDriver("driver"),
|
builders.SecretDriver("driver"),
|
||||||
),
|
),
|
||||||
*Secret(SecretID("ID-2-foo"),
|
*builders.Secret(builders.SecretID("ID-2-foo"),
|
||||||
SecretName("2-foo"),
|
builders.SecretName("2-foo"),
|
||||||
SecretVersion(swarm.Version{Index: 11}),
|
builders.SecretVersion(swarm.Version{Index: 11}),
|
||||||
SecretCreatedAt(time.Now().Add(-2*time.Hour)),
|
builders.SecretCreatedAt(time.Now().Add(-2*time.Hour)),
|
||||||
SecretUpdatedAt(time.Now().Add(-1*time.Hour)),
|
builders.SecretUpdatedAt(time.Now().Add(-1*time.Hour)),
|
||||||
SecretDriver("driver"),
|
builders.SecretDriver("driver"),
|
||||||
),
|
),
|
||||||
}, nil
|
}, nil
|
||||||
},
|
},
|
||||||
|
@ -82,15 +82,15 @@ func TestSecretListWithQuietOption(t *testing.T) {
|
||||||
cli := test.NewFakeCli(&fakeClient{
|
cli := test.NewFakeCli(&fakeClient{
|
||||||
secretListFunc: func(_ context.Context, options types.SecretListOptions) ([]swarm.Secret, error) {
|
secretListFunc: func(_ context.Context, options types.SecretListOptions) ([]swarm.Secret, error) {
|
||||||
return []swarm.Secret{
|
return []swarm.Secret{
|
||||||
*Secret(SecretID("ID-foo"), SecretName("foo")),
|
*builders.Secret(builders.SecretID("ID-foo"), builders.SecretName("foo")),
|
||||||
*Secret(SecretID("ID-bar"), SecretName("bar"), SecretLabels(map[string]string{
|
*builders.Secret(builders.SecretID("ID-bar"), builders.SecretName("bar"), builders.SecretLabels(map[string]string{
|
||||||
"label": "label-bar",
|
"label": "label-bar",
|
||||||
})),
|
})),
|
||||||
}, nil
|
}, nil
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
cmd := newSecretListCommand(cli)
|
cmd := newSecretListCommand(cli)
|
||||||
cmd.Flags().Set("quiet", "true")
|
assert.Check(t, cmd.Flags().Set("quiet", "true"))
|
||||||
assert.NilError(t, cmd.Execute())
|
assert.NilError(t, cmd.Execute())
|
||||||
golden.Assert(t, cli.OutBuffer().String(), "secret-list-with-quiet-option.golden")
|
golden.Assert(t, cli.OutBuffer().String(), "secret-list-with-quiet-option.golden")
|
||||||
}
|
}
|
||||||
|
@ -99,8 +99,8 @@ func TestSecretListWithConfigFormat(t *testing.T) {
|
||||||
cli := test.NewFakeCli(&fakeClient{
|
cli := test.NewFakeCli(&fakeClient{
|
||||||
secretListFunc: func(_ context.Context, options types.SecretListOptions) ([]swarm.Secret, error) {
|
secretListFunc: func(_ context.Context, options types.SecretListOptions) ([]swarm.Secret, error) {
|
||||||
return []swarm.Secret{
|
return []swarm.Secret{
|
||||||
*Secret(SecretID("ID-foo"), SecretName("foo")),
|
*builders.Secret(builders.SecretID("ID-foo"), builders.SecretName("foo")),
|
||||||
*Secret(SecretID("ID-bar"), SecretName("bar"), SecretLabels(map[string]string{
|
*builders.Secret(builders.SecretID("ID-bar"), builders.SecretName("bar"), builders.SecretLabels(map[string]string{
|
||||||
"label": "label-bar",
|
"label": "label-bar",
|
||||||
})),
|
})),
|
||||||
}, nil
|
}, nil
|
||||||
|
@ -118,15 +118,15 @@ func TestSecretListWithFormat(t *testing.T) {
|
||||||
cli := test.NewFakeCli(&fakeClient{
|
cli := test.NewFakeCli(&fakeClient{
|
||||||
secretListFunc: func(_ context.Context, options types.SecretListOptions) ([]swarm.Secret, error) {
|
secretListFunc: func(_ context.Context, options types.SecretListOptions) ([]swarm.Secret, error) {
|
||||||
return []swarm.Secret{
|
return []swarm.Secret{
|
||||||
*Secret(SecretID("ID-foo"), SecretName("foo")),
|
*builders.Secret(builders.SecretID("ID-foo"), builders.SecretName("foo")),
|
||||||
*Secret(SecretID("ID-bar"), SecretName("bar"), SecretLabels(map[string]string{
|
*builders.Secret(builders.SecretID("ID-bar"), builders.SecretName("bar"), builders.SecretLabels(map[string]string{
|
||||||
"label": "label-bar",
|
"label": "label-bar",
|
||||||
})),
|
})),
|
||||||
}, nil
|
}, nil
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
cmd := newSecretListCommand(cli)
|
cmd := newSecretListCommand(cli)
|
||||||
cmd.Flags().Set("format", "{{ .Name }} {{ .Labels }}")
|
assert.Check(t, cmd.Flags().Set("format", "{{ .Name }} {{ .Labels }}"))
|
||||||
assert.NilError(t, cmd.Execute())
|
assert.NilError(t, cmd.Execute())
|
||||||
golden.Assert(t, cli.OutBuffer().String(), "secret-list-with-format.golden")
|
golden.Assert(t, cli.OutBuffer().String(), "secret-list-with-format.golden")
|
||||||
}
|
}
|
||||||
|
@ -137,24 +137,24 @@ func TestSecretListWithFilter(t *testing.T) {
|
||||||
assert.Check(t, is.Equal("foo", options.Filters.Get("name")[0]), "foo")
|
assert.Check(t, is.Equal("foo", options.Filters.Get("name")[0]), "foo")
|
||||||
assert.Check(t, is.Equal("lbl1=Label-bar", options.Filters.Get("label")[0]))
|
assert.Check(t, is.Equal("lbl1=Label-bar", options.Filters.Get("label")[0]))
|
||||||
return []swarm.Secret{
|
return []swarm.Secret{
|
||||||
*Secret(SecretID("ID-foo"),
|
*builders.Secret(builders.SecretID("ID-foo"),
|
||||||
SecretName("foo"),
|
builders.SecretName("foo"),
|
||||||
SecretVersion(swarm.Version{Index: 10}),
|
builders.SecretVersion(swarm.Version{Index: 10}),
|
||||||
SecretCreatedAt(time.Now().Add(-2*time.Hour)),
|
builders.SecretCreatedAt(time.Now().Add(-2*time.Hour)),
|
||||||
SecretUpdatedAt(time.Now().Add(-1*time.Hour)),
|
builders.SecretUpdatedAt(time.Now().Add(-1*time.Hour)),
|
||||||
),
|
),
|
||||||
*Secret(SecretID("ID-bar"),
|
*builders.Secret(builders.SecretID("ID-bar"),
|
||||||
SecretName("bar"),
|
builders.SecretName("bar"),
|
||||||
SecretVersion(swarm.Version{Index: 11}),
|
builders.SecretVersion(swarm.Version{Index: 11}),
|
||||||
SecretCreatedAt(time.Now().Add(-2*time.Hour)),
|
builders.SecretCreatedAt(time.Now().Add(-2*time.Hour)),
|
||||||
SecretUpdatedAt(time.Now().Add(-1*time.Hour)),
|
builders.SecretUpdatedAt(time.Now().Add(-1*time.Hour)),
|
||||||
),
|
),
|
||||||
}, nil
|
}, nil
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
cmd := newSecretListCommand(cli)
|
cmd := newSecretListCommand(cli)
|
||||||
cmd.Flags().Set("filter", "name=foo")
|
assert.Check(t, cmd.Flags().Set("filter", "name=foo"))
|
||||||
cmd.Flags().Set("filter", "label=lbl1=Label-bar")
|
assert.Check(t, cmd.Flags().Set("filter", "label=lbl1=Label-bar"))
|
||||||
assert.NilError(t, cmd.Execute())
|
assert.NilError(t, cmd.Execute())
|
||||||
golden.Assert(t, cli.OutBuffer().String(), "secret-list-with-filter.golden")
|
golden.Assert(t, cli.OutBuffer().String(), "secret-list-with-filter.golden")
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ package service
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
. "github.com/docker/cli/internal/test/builders" // Import builders to get the builder function as package function
|
"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/docker/docker/client"
|
"github.com/docker/docker/client"
|
||||||
|
@ -39,7 +39,7 @@ func (f *fakeClient) ServiceInspectWithRaw(ctx context.Context, serviceID string
|
||||||
return f.serviceInspectWithRawFunc(ctx, serviceID, options)
|
return f.serviceInspectWithRawFunc(ctx, serviceID, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
return *Service(ServiceID(serviceID)), []byte{}, nil
|
return *builders.Service(builders.ServiceID(serviceID)), []byte{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *fakeClient) ServiceList(ctx context.Context, options types.ServiceListOptions) ([]swarm.Service, error) {
|
func (f *fakeClient) ServiceList(ctx context.Context, options types.ServiceListOptions) ([]swarm.Service, error) {
|
||||||
|
@ -73,5 +73,5 @@ func (f *fakeClient) NetworkInspect(ctx context.Context, networkID string, optio
|
||||||
}
|
}
|
||||||
|
|
||||||
func newService(id string, name string) swarm.Service {
|
func newService(id string, name string) swarm.Service {
|
||||||
return *Service(ServiceID(id), ServiceName(name))
|
return *builders.Service(builders.ServiceID(id), builders.ServiceName(name))
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,8 +8,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/docker/cli/internal/test"
|
"github.com/docker/cli/internal/test"
|
||||||
// Import builders to get the builder function as package function
|
"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/docker/docker/api/types/versions"
|
"github.com/docker/docker/api/types/versions"
|
||||||
|
@ -30,7 +29,7 @@ func TestServiceListOrder(t *testing.T) {
|
||||||
})
|
})
|
||||||
cmd := newListCommand(cli)
|
cmd := newListCommand(cli)
|
||||||
cmd.SetArgs([]string{})
|
cmd.SetArgs([]string{})
|
||||||
cmd.Flags().Set("format", "{{.Name}}")
|
assert.Check(t, cmd.Flags().Set("format", "{{.Name}}"))
|
||||||
assert.NilError(t, cmd.Execute())
|
assert.NilError(t, cmd.Execute())
|
||||||
golden.Assert(t, cli.OutBuffer().String(), "service-list-sort.golden")
|
golden.Assert(t, cli.OutBuffer().String(), "service-list-sort.golden")
|
||||||
}
|
}
|
||||||
|
@ -248,21 +247,21 @@ func generateServices(t *testing.T, opts clusterOpts) []swarm.Service {
|
||||||
}
|
}
|
||||||
|
|
||||||
return []swarm.Service{
|
return []swarm.Service{
|
||||||
*Service(
|
*builders.Service(
|
||||||
ServiceID("replicated"),
|
builders.ServiceID("replicated"),
|
||||||
ServiceName("01-replicated-service"),
|
builders.ServiceName("01-replicated-service"),
|
||||||
ReplicatedService(opts.desiredTasks),
|
builders.ReplicatedService(opts.desiredTasks),
|
||||||
ServiceStatus(opts.desiredTasks, opts.runningTasks),
|
builders.ServiceStatus(opts.desiredTasks, opts.runningTasks),
|
||||||
),
|
),
|
||||||
*Service(
|
*builders.Service(
|
||||||
ServiceID("global"),
|
builders.ServiceID("global"),
|
||||||
ServiceName("02-global-service"),
|
builders.ServiceName("02-global-service"),
|
||||||
GlobalService(),
|
builders.GlobalService(),
|
||||||
ServiceStatus(opts.activeNodes, globalTasks),
|
builders.ServiceStatus(opts.activeNodes, globalTasks),
|
||||||
),
|
),
|
||||||
*Service(
|
*builders.Service(
|
||||||
ServiceID("none-id"),
|
builders.ServiceID("none-id"),
|
||||||
ServiceName("03-none-service"),
|
builders.ServiceName("03-none-service"),
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -214,9 +214,9 @@ func (f *taskFormatter) format(ctx context.Context, logCtx logContext) (string,
|
||||||
taskName := fmt.Sprintf("%s.%d", serviceName, task.Slot)
|
taskName := fmt.Sprintf("%s.%d", serviceName, task.Slot)
|
||||||
if !f.opts.noTaskIDs {
|
if !f.opts.noTaskIDs {
|
||||||
if f.opts.noTrunc {
|
if f.opts.noTrunc {
|
||||||
taskName += fmt.Sprintf(".%s", task.ID)
|
taskName += "." + task.ID
|
||||||
} else {
|
} else {
|
||||||
taskName += fmt.Sprintf(".%s", stringid.TruncateID(task.ID))
|
taskName += "." + stringid.TruncateID(task.ID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1001,7 +1001,7 @@ const (
|
||||||
flagTTY = "tty"
|
flagTTY = "tty"
|
||||||
flagUpdateDelay = "update-delay"
|
flagUpdateDelay = "update-delay"
|
||||||
flagUpdateFailureAction = "update-failure-action"
|
flagUpdateFailureAction = "update-failure-action"
|
||||||
flagUpdateMaxFailureRatio = "update-max-failure-ratio"
|
flagUpdateMaxFailureRatio = "update-max-failure-ratio" // #nosec G101 -- ignoring: Potential hardcoded credentials (gosec)
|
||||||
flagUpdateMonitor = "update-monitor"
|
flagUpdateMonitor = "update-monitor"
|
||||||
flagUpdateOrder = "update-order"
|
flagUpdateOrder = "update-order"
|
||||||
flagUpdateParallelism = "update-parallelism"
|
flagUpdateParallelism = "update-parallelism"
|
||||||
|
|
|
@ -874,7 +874,7 @@ func TestGlobalJobProgressUpdaterLarge(t *testing.T) {
|
||||||
tasks := []swarm.Task{}
|
tasks := []swarm.Task{}
|
||||||
for nodeID := range activeNodes {
|
for nodeID := range activeNodes {
|
||||||
tasks = append(tasks, swarm.Task{
|
tasks = append(tasks, swarm.Task{
|
||||||
ID: fmt.Sprintf("task%s", nodeID),
|
ID: "task" + nodeID,
|
||||||
NodeID: nodeID,
|
NodeID: nodeID,
|
||||||
DesiredState: swarm.TaskStateComplete,
|
DesiredState: swarm.TaskStateComplete,
|
||||||
Status: swarm.TaskStatus{
|
Status: swarm.TaskStatus{
|
||||||
|
|
|
@ -5,7 +5,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/docker/cli/internal/test"
|
"github.com/docker/cli/internal/test"
|
||||||
. "github.com/docker/cli/internal/test/builders" // Import builders to get the builder function as package function
|
"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"
|
"github.com/pkg/errors"
|
||||||
|
@ -38,7 +38,7 @@ func TestListErrors(t *testing.T) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
serviceListFunc: func(options types.ServiceListOptions) ([]swarm.Service, error) {
|
serviceListFunc: func(options types.ServiceListOptions) ([]swarm.Service, error) {
|
||||||
return []swarm.Service{*Service()}, nil
|
return []swarm.Service{*builders.Service()}, nil
|
||||||
},
|
},
|
||||||
expectedError: "cannot get label",
|
expectedError: "cannot get label",
|
||||||
},
|
},
|
||||||
|
@ -51,7 +51,7 @@ func TestListErrors(t *testing.T) {
|
||||||
cmd.SetArgs(tc.args)
|
cmd.SetArgs(tc.args)
|
||||||
cmd.SetOut(io.Discard)
|
cmd.SetOut(io.Discard)
|
||||||
for key, value := range tc.flags {
|
for key, value := range tc.flags {
|
||||||
cmd.Flags().Set(key, value)
|
assert.Check(t, cmd.Flags().Set(key, value))
|
||||||
}
|
}
|
||||||
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
|
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
|
||||||
}
|
}
|
||||||
|
@ -101,8 +101,8 @@ func TestStackList(t *testing.T) {
|
||||||
var services []swarm.Service
|
var services []swarm.Service
|
||||||
for _, name := range tc.serviceNames {
|
for _, name := range tc.serviceNames {
|
||||||
services = append(services,
|
services = append(services,
|
||||||
*Service(
|
*builders.Service(
|
||||||
ServiceLabels(map[string]string{
|
builders.ServiceLabels(map[string]string{
|
||||||
"com.docker.stack.namespace": name,
|
"com.docker.stack.namespace": name,
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
|
@ -115,7 +115,7 @@ func TestStackList(t *testing.T) {
|
||||||
})
|
})
|
||||||
cmd := newListCommand(cli)
|
cmd := newListCommand(cli)
|
||||||
for key, value := range tc.flags {
|
for key, value := range tc.flags {
|
||||||
cmd.Flags().Set(key, value)
|
assert.Check(t, cmd.Flags().Set(key, value))
|
||||||
}
|
}
|
||||||
assert.NilError(t, cmd.Execute())
|
assert.NilError(t, cmd.Execute())
|
||||||
golden.Assert(t, cli.OutBuffer().String(), tc.golden)
|
golden.Assert(t, cli.OutBuffer().String(), tc.golden)
|
||||||
|
|
|
@ -7,7 +7,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/cli/internal/test/builders" // Import builders to get the builder function as package function
|
"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"
|
"github.com/pkg/errors"
|
||||||
|
@ -76,7 +76,7 @@ func TestStackPs(t *testing.T) {
|
||||||
{
|
{
|
||||||
doc: "WithQuietOption",
|
doc: "WithQuietOption",
|
||||||
taskListFunc: func(options types.TaskListOptions) ([]swarm.Task, error) {
|
taskListFunc: func(options types.TaskListOptions) ([]swarm.Task, error) {
|
||||||
return []swarm.Task{*Task(TaskID("id-foo"))}, nil
|
return []swarm.Task{*builders.Task(builders.TaskID("id-foo"))}, nil
|
||||||
},
|
},
|
||||||
args: []string{"foo"},
|
args: []string{"foo"},
|
||||||
flags: map[string]string{
|
flags: map[string]string{
|
||||||
|
@ -87,7 +87,7 @@ func TestStackPs(t *testing.T) {
|
||||||
{
|
{
|
||||||
doc: "WithNoTruncOption",
|
doc: "WithNoTruncOption",
|
||||||
taskListFunc: func(options types.TaskListOptions) ([]swarm.Task, error) {
|
taskListFunc: func(options types.TaskListOptions) ([]swarm.Task, error) {
|
||||||
return []swarm.Task{*Task(TaskID("xn4cypcov06f2w8gsbaf2lst3"))}, nil
|
return []swarm.Task{*builders.Task(builders.TaskID("xn4cypcov06f2w8gsbaf2lst3"))}, nil
|
||||||
},
|
},
|
||||||
args: []string{"foo"},
|
args: []string{"foo"},
|
||||||
flags: map[string]string{
|
flags: map[string]string{
|
||||||
|
@ -99,12 +99,12 @@ func TestStackPs(t *testing.T) {
|
||||||
{
|
{
|
||||||
doc: "WithNoResolveOption",
|
doc: "WithNoResolveOption",
|
||||||
taskListFunc: func(options types.TaskListOptions) ([]swarm.Task, error) {
|
taskListFunc: func(options types.TaskListOptions) ([]swarm.Task, error) {
|
||||||
return []swarm.Task{*Task(
|
return []swarm.Task{*builders.Task(
|
||||||
TaskNodeID("id-node-foo"),
|
builders.TaskNodeID("id-node-foo"),
|
||||||
)}, nil
|
)}, nil
|
||||||
},
|
},
|
||||||
nodeInspectWithRaw: func(ref string) (swarm.Node, []byte, error) {
|
nodeInspectWithRaw: func(ref string) (swarm.Node, []byte, error) {
|
||||||
return *Node(NodeName("node-name-bar")), nil, nil
|
return *builders.Node(builders.NodeName("node-name-bar")), nil, nil
|
||||||
},
|
},
|
||||||
args: []string{"foo"},
|
args: []string{"foo"},
|
||||||
flags: map[string]string{
|
flags: map[string]string{
|
||||||
|
@ -116,7 +116,7 @@ func TestStackPs(t *testing.T) {
|
||||||
{
|
{
|
||||||
doc: "WithFormat",
|
doc: "WithFormat",
|
||||||
taskListFunc: func(options types.TaskListOptions) ([]swarm.Task, error) {
|
taskListFunc: func(options types.TaskListOptions) ([]swarm.Task, error) {
|
||||||
return []swarm.Task{*Task(TaskServiceID("service-id-foo"))}, nil
|
return []swarm.Task{*builders.Task(builders.TaskServiceID("service-id-foo"))}, nil
|
||||||
},
|
},
|
||||||
args: []string{"foo"},
|
args: []string{"foo"},
|
||||||
flags: map[string]string{
|
flags: map[string]string{
|
||||||
|
@ -127,7 +127,7 @@ func TestStackPs(t *testing.T) {
|
||||||
{
|
{
|
||||||
doc: "WithConfigFormat",
|
doc: "WithConfigFormat",
|
||||||
taskListFunc: func(options types.TaskListOptions) ([]swarm.Task, error) {
|
taskListFunc: func(options types.TaskListOptions) ([]swarm.Task, error) {
|
||||||
return []swarm.Task{*Task(TaskServiceID("service-id-foo"))}, nil
|
return []swarm.Task{*builders.Task(builders.TaskServiceID("service-id-foo"))}, nil
|
||||||
},
|
},
|
||||||
config: configfile.ConfigFile{
|
config: configfile.ConfigFile{
|
||||||
TasksFormat: "{{ .Name }}",
|
TasksFormat: "{{ .Name }}",
|
||||||
|
@ -138,17 +138,17 @@ func TestStackPs(t *testing.T) {
|
||||||
{
|
{
|
||||||
doc: "WithoutFormat",
|
doc: "WithoutFormat",
|
||||||
taskListFunc: func(options types.TaskListOptions) ([]swarm.Task, error) {
|
taskListFunc: func(options types.TaskListOptions) ([]swarm.Task, error) {
|
||||||
return []swarm.Task{*Task(
|
return []swarm.Task{*builders.Task(
|
||||||
TaskID("id-foo"),
|
builders.TaskID("id-foo"),
|
||||||
TaskServiceID("service-id-foo"),
|
builders.TaskServiceID("service-id-foo"),
|
||||||
TaskNodeID("id-node"),
|
builders.TaskNodeID("id-node"),
|
||||||
WithTaskSpec(TaskImage("myimage:mytag")),
|
builders.WithTaskSpec(builders.TaskImage("myimage:mytag")),
|
||||||
TaskDesiredState(swarm.TaskStateReady),
|
builders.TaskDesiredState(swarm.TaskStateReady),
|
||||||
WithStatus(TaskState(swarm.TaskStateFailed), Timestamp(time.Now().Add(-2*time.Hour))),
|
builders.WithStatus(builders.TaskState(swarm.TaskStateFailed), builders.Timestamp(time.Now().Add(-2*time.Hour))),
|
||||||
)}, nil
|
)}, nil
|
||||||
},
|
},
|
||||||
nodeInspectWithRaw: func(ref string) (swarm.Node, []byte, error) {
|
nodeInspectWithRaw: func(ref string) (swarm.Node, []byte, error) {
|
||||||
return *Node(NodeName("node-name-bar")), nil, nil
|
return *builders.Node(builders.NodeName("node-name-bar")), nil, nil
|
||||||
},
|
},
|
||||||
args: []string{"foo"},
|
args: []string{"foo"},
|
||||||
golden: "stack-ps-without-format.golden",
|
golden: "stack-ps-without-format.golden",
|
||||||
|
@ -166,7 +166,7 @@ func TestStackPs(t *testing.T) {
|
||||||
cmd := newPsCommand(cli)
|
cmd := newPsCommand(cli)
|
||||||
cmd.SetArgs(tc.args)
|
cmd.SetArgs(tc.args)
|
||||||
for key, value := range tc.flags {
|
for key, value := range tc.flags {
|
||||||
cmd.Flags().Set(key, value)
|
assert.Check(t, cmd.Flags().Set(key, value))
|
||||||
}
|
}
|
||||||
cmd.SetOut(io.Discard)
|
cmd.SetOut(io.Discard)
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,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/cli/internal/test/builders" // Import builders to get the builder function as package function
|
"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"
|
"github.com/pkg/errors"
|
||||||
|
@ -34,20 +34,20 @@ func TestStackServicesErrors(t *testing.T) {
|
||||||
{
|
{
|
||||||
args: []string{"foo"},
|
args: []string{"foo"},
|
||||||
serviceListFunc: func(options types.ServiceListOptions) ([]swarm.Service, error) {
|
serviceListFunc: func(options types.ServiceListOptions) ([]swarm.Service, error) {
|
||||||
return []swarm.Service{*Service(GlobalService())}, nil
|
return []swarm.Service{*builders.Service(builders.GlobalService())}, nil
|
||||||
},
|
},
|
||||||
nodeListFunc: func(options types.NodeListOptions) ([]swarm.Node, error) {
|
nodeListFunc: func(options types.NodeListOptions) ([]swarm.Node, error) {
|
||||||
return nil, errors.Errorf("error getting nodes")
|
return nil, errors.Errorf("error getting nodes")
|
||||||
},
|
},
|
||||||
taskListFunc: func(options types.TaskListOptions) ([]swarm.Task, error) {
|
taskListFunc: func(options types.TaskListOptions) ([]swarm.Task, error) {
|
||||||
return []swarm.Task{*Task()}, nil
|
return []swarm.Task{*builders.Task()}, nil
|
||||||
},
|
},
|
||||||
expectedError: "error getting nodes",
|
expectedError: "error getting nodes",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
args: []string{"foo"},
|
args: []string{"foo"},
|
||||||
serviceListFunc: func(options types.ServiceListOptions) ([]swarm.Service, error) {
|
serviceListFunc: func(options types.ServiceListOptions) ([]swarm.Service, error) {
|
||||||
return []swarm.Service{*Service(GlobalService())}, nil
|
return []swarm.Service{*builders.Service(builders.GlobalService())}, nil
|
||||||
},
|
},
|
||||||
taskListFunc: func(options types.TaskListOptions) ([]swarm.Task, error) {
|
taskListFunc: func(options types.TaskListOptions) ([]swarm.Task, error) {
|
||||||
return nil, errors.Errorf("error getting tasks")
|
return nil, errors.Errorf("error getting tasks")
|
||||||
|
@ -60,7 +60,7 @@ func TestStackServicesErrors(t *testing.T) {
|
||||||
"format": "{{invalid format}}",
|
"format": "{{invalid format}}",
|
||||||
},
|
},
|
||||||
serviceListFunc: func(options types.ServiceListOptions) ([]swarm.Service, error) {
|
serviceListFunc: func(options types.ServiceListOptions) ([]swarm.Service, error) {
|
||||||
return []swarm.Service{*Service()}, nil
|
return []swarm.Service{*builders.Service()}, nil
|
||||||
},
|
},
|
||||||
expectedError: "template parsing error",
|
expectedError: "template parsing error",
|
||||||
},
|
},
|
||||||
|
@ -77,7 +77,7 @@ func TestStackServicesErrors(t *testing.T) {
|
||||||
cmd := newServicesCommand(cli)
|
cmd := newServicesCommand(cli)
|
||||||
cmd.SetArgs(tc.args)
|
cmd.SetArgs(tc.args)
|
||||||
for key, value := range tc.flags {
|
for key, value := range tc.flags {
|
||||||
cmd.Flags().Set(key, value)
|
assert.Check(t, cmd.Flags().Set(key, value))
|
||||||
}
|
}
|
||||||
cmd.SetOut(io.Discard)
|
cmd.SetOut(io.Discard)
|
||||||
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
|
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
|
||||||
|
@ -109,11 +109,11 @@ func TestStackServicesEmptyServiceList(t *testing.T) {
|
||||||
func TestStackServicesWithQuietOption(t *testing.T) {
|
func TestStackServicesWithQuietOption(t *testing.T) {
|
||||||
cli := test.NewFakeCli(&fakeClient{
|
cli := test.NewFakeCli(&fakeClient{
|
||||||
serviceListFunc: func(options types.ServiceListOptions) ([]swarm.Service, error) {
|
serviceListFunc: func(options types.ServiceListOptions) ([]swarm.Service, error) {
|
||||||
return []swarm.Service{*Service(ServiceID("id-foo"))}, nil
|
return []swarm.Service{*builders.Service(builders.ServiceID("id-foo"))}, nil
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
cmd := newServicesCommand(cli)
|
cmd := newServicesCommand(cli)
|
||||||
cmd.Flags().Set("quiet", "true")
|
assert.Check(t, cmd.Flags().Set("quiet", "true"))
|
||||||
cmd.SetArgs([]string{"foo"})
|
cmd.SetArgs([]string{"foo"})
|
||||||
assert.NilError(t, cmd.Execute())
|
assert.NilError(t, cmd.Execute())
|
||||||
golden.Assert(t, cli.OutBuffer().String(), "stack-services-with-quiet-option.golden")
|
golden.Assert(t, cli.OutBuffer().String(), "stack-services-with-quiet-option.golden")
|
||||||
|
@ -123,13 +123,13 @@ func TestStackServicesWithFormat(t *testing.T) {
|
||||||
cli := test.NewFakeCli(&fakeClient{
|
cli := test.NewFakeCli(&fakeClient{
|
||||||
serviceListFunc: func(options types.ServiceListOptions) ([]swarm.Service, error) {
|
serviceListFunc: func(options types.ServiceListOptions) ([]swarm.Service, error) {
|
||||||
return []swarm.Service{
|
return []swarm.Service{
|
||||||
*Service(ServiceName("service-name-foo")),
|
*builders.Service(builders.ServiceName("service-name-foo")),
|
||||||
}, nil
|
}, nil
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
cmd := newServicesCommand(cli)
|
cmd := newServicesCommand(cli)
|
||||||
cmd.SetArgs([]string{"foo"})
|
cmd.SetArgs([]string{"foo"})
|
||||||
cmd.Flags().Set("format", "{{ .Name }}")
|
assert.Check(t, cmd.Flags().Set("format", "{{ .Name }}"))
|
||||||
assert.NilError(t, cmd.Execute())
|
assert.NilError(t, cmd.Execute())
|
||||||
golden.Assert(t, cli.OutBuffer().String(), "stack-services-with-format.golden")
|
golden.Assert(t, cli.OutBuffer().String(), "stack-services-with-format.golden")
|
||||||
}
|
}
|
||||||
|
@ -138,7 +138,7 @@ func TestStackServicesWithConfigFormat(t *testing.T) {
|
||||||
cli := test.NewFakeCli(&fakeClient{
|
cli := test.NewFakeCli(&fakeClient{
|
||||||
serviceListFunc: func(options types.ServiceListOptions) ([]swarm.Service, error) {
|
serviceListFunc: func(options types.ServiceListOptions) ([]swarm.Service, error) {
|
||||||
return []swarm.Service{
|
return []swarm.Service{
|
||||||
*Service(ServiceName("service-name-foo")),
|
*builders.Service(builders.ServiceName("service-name-foo")),
|
||||||
}, nil
|
}, nil
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
@ -154,12 +154,12 @@ func TestStackServicesWithConfigFormat(t *testing.T) {
|
||||||
func TestStackServicesWithoutFormat(t *testing.T) {
|
func TestStackServicesWithoutFormat(t *testing.T) {
|
||||||
cli := test.NewFakeCli(&fakeClient{
|
cli := test.NewFakeCli(&fakeClient{
|
||||||
serviceListFunc: func(options types.ServiceListOptions) ([]swarm.Service, error) {
|
serviceListFunc: func(options types.ServiceListOptions) ([]swarm.Service, error) {
|
||||||
return []swarm.Service{*Service(
|
return []swarm.Service{*builders.Service(
|
||||||
ServiceName("name-foo"),
|
builders.ServiceName("name-foo"),
|
||||||
ServiceID("id-foo"),
|
builders.ServiceID("id-foo"),
|
||||||
ReplicatedService(2),
|
builders.ReplicatedService(2),
|
||||||
ServiceImage("busybox:latest"),
|
builders.ServiceImage("busybox:latest"),
|
||||||
ServicePort(swarm.PortConfig{
|
builders.ServicePort(swarm.PortConfig{
|
||||||
PublishMode: swarm.PortConfigPublishModeIngress,
|
PublishMode: swarm.PortConfigPublishModeIngress,
|
||||||
PublishedPort: 0,
|
PublishedPort: 0,
|
||||||
TargetPort: 3232,
|
TargetPort: 3232,
|
||||||
|
|
|
@ -58,7 +58,7 @@ func RunRemove(dockerCli command.Cli, opts options.Remove) error {
|
||||||
hasError = removeNetworks(ctx, dockerCli, networks) || hasError
|
hasError = removeNetworks(ctx, dockerCli, networks) || hasError
|
||||||
|
|
||||||
if hasError {
|
if hasError {
|
||||||
errs = append(errs, fmt.Sprintf("Failed to remove some resources from stack: %s", namespace))
|
errs = append(errs, "Failed to remove some resources from stack: "+namespace)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ func TestIPNets(t *testing.T) {
|
||||||
f := setUpIPNetFlagSet(&ips)
|
f := setUpIPNetFlagSet(&ips)
|
||||||
|
|
||||||
vals := []string{"192.168.1.1/24", "10.0.0.1/16", "fd00:0:0:0:0:0:0:2/64"}
|
vals := []string{"192.168.1.1/24", "10.0.0.1/16", "fd00:0:0:0:0:0:0:2/64"}
|
||||||
arg := fmt.Sprintf("--cidrs=%s", strings.Join(vals, ","))
|
arg := "--cidrs=" + strings.Join(vals, ",")
|
||||||
err := f.Parse([]string{arg})
|
err := f.Parse([]string{arg})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("expected no error; got", err)
|
t.Fatal("expected no error; got", err)
|
||||||
|
@ -135,7 +135,7 @@ func TestIPNetBadQuoting(t *testing.T) {
|
||||||
var cidrs []net.IPNet
|
var cidrs []net.IPNet
|
||||||
f := setUpIPNetFlagSet(&cidrs)
|
f := setUpIPNetFlagSet(&cidrs)
|
||||||
|
|
||||||
if err := f.Parse([]string{fmt.Sprintf("--cidrs=%s", strings.Join(test.FlagArg, ","))}); err != nil {
|
if err := f.Parse([]string{"--cidrs=" + strings.Join(test.FlagArg, ",")}); err != nil {
|
||||||
t.Fatalf("flag parsing failed with error: %s\nparsing:\t%#v\nwant:\t\t%s",
|
t.Fatalf("flag parsing failed with error: %s\nparsing:\t%#v\nwant:\t\t%s",
|
||||||
err, test.FlagArg, test.Want[i])
|
err, test.FlagArg, test.Want[i])
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/docker/cli/internal/test"
|
"github.com/docker/cli/internal/test"
|
||||||
. "github.com/docker/cli/internal/test/builders" // Import builders to get the builder function as package function
|
"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"
|
"github.com/pkg/errors"
|
||||||
|
@ -96,7 +96,7 @@ func TestSwarmJoinTokenErrors(t *testing.T) {
|
||||||
cmd := newJoinTokenCommand(cli)
|
cmd := newJoinTokenCommand(cli)
|
||||||
cmd.SetArgs(tc.args)
|
cmd.SetArgs(tc.args)
|
||||||
for key, value := range tc.flags {
|
for key, value := range tc.flags {
|
||||||
cmd.Flags().Set(key, value)
|
assert.Check(t, cmd.Flags().Set(key, value))
|
||||||
}
|
}
|
||||||
cmd.SetOut(io.Discard)
|
cmd.SetOut(io.Discard)
|
||||||
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
|
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
|
||||||
|
@ -123,10 +123,10 @@ func TestSwarmJoinToken(t *testing.T) {
|
||||||
}, nil
|
}, nil
|
||||||
},
|
},
|
||||||
nodeInspectFunc: func() (swarm.Node, []byte, error) {
|
nodeInspectFunc: func() (swarm.Node, []byte, error) {
|
||||||
return *Node(Manager()), []byte{}, nil
|
return *builders.Node(builders.Manager()), []byte{}, nil
|
||||||
},
|
},
|
||||||
swarmInspectFunc: func() (swarm.Swarm, error) {
|
swarmInspectFunc: func() (swarm.Swarm, error) {
|
||||||
return *Swarm(), nil
|
return *builders.Swarm(), nil
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -140,10 +140,10 @@ func TestSwarmJoinToken(t *testing.T) {
|
||||||
}, nil
|
}, nil
|
||||||
},
|
},
|
||||||
nodeInspectFunc: func() (swarm.Node, []byte, error) {
|
nodeInspectFunc: func() (swarm.Node, []byte, error) {
|
||||||
return *Node(Manager()), []byte{}, nil
|
return *builders.Node(builders.Manager()), []byte{}, nil
|
||||||
},
|
},
|
||||||
swarmInspectFunc: func() (swarm.Swarm, error) {
|
swarmInspectFunc: func() (swarm.Swarm, error) {
|
||||||
return *Swarm(), nil
|
return *builders.Swarm(), nil
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -160,10 +160,10 @@ func TestSwarmJoinToken(t *testing.T) {
|
||||||
}, nil
|
}, nil
|
||||||
},
|
},
|
||||||
nodeInspectFunc: func() (swarm.Node, []byte, error) {
|
nodeInspectFunc: func() (swarm.Node, []byte, error) {
|
||||||
return *Node(Manager()), []byte{}, nil
|
return *builders.Node(builders.Manager()), []byte{}, nil
|
||||||
},
|
},
|
||||||
swarmInspectFunc: func() (swarm.Swarm, error) {
|
swarmInspectFunc: func() (swarm.Swarm, error) {
|
||||||
return *Swarm(), nil
|
return *builders.Swarm(), nil
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -173,10 +173,10 @@ func TestSwarmJoinToken(t *testing.T) {
|
||||||
flagQuiet: "true",
|
flagQuiet: "true",
|
||||||
},
|
},
|
||||||
nodeInspectFunc: func() (swarm.Node, []byte, error) {
|
nodeInspectFunc: func() (swarm.Node, []byte, error) {
|
||||||
return *Node(Manager()), []byte{}, nil
|
return *builders.Node(builders.Manager()), []byte{}, nil
|
||||||
},
|
},
|
||||||
swarmInspectFunc: func() (swarm.Swarm, error) {
|
swarmInspectFunc: func() (swarm.Swarm, error) {
|
||||||
return *Swarm(), nil
|
return *builders.Swarm(), nil
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -186,10 +186,10 @@ func TestSwarmJoinToken(t *testing.T) {
|
||||||
flagQuiet: "true",
|
flagQuiet: "true",
|
||||||
},
|
},
|
||||||
nodeInspectFunc: func() (swarm.Node, []byte, error) {
|
nodeInspectFunc: func() (swarm.Node, []byte, error) {
|
||||||
return *Node(Manager()), []byte{}, nil
|
return *builders.Node(builders.Manager()), []byte{}, nil
|
||||||
},
|
},
|
||||||
swarmInspectFunc: func() (swarm.Swarm, error) {
|
swarmInspectFunc: func() (swarm.Swarm, error) {
|
||||||
return *Swarm(), nil
|
return *builders.Swarm(), nil
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -202,7 +202,7 @@ func TestSwarmJoinToken(t *testing.T) {
|
||||||
cmd := newJoinTokenCommand(cli)
|
cmd := newJoinTokenCommand(cli)
|
||||||
cmd.SetArgs(tc.args)
|
cmd.SetArgs(tc.args)
|
||||||
for key, value := range tc.flags {
|
for key, value := range tc.flags {
|
||||||
cmd.Flags().Set(key, value)
|
assert.Check(t, cmd.Flags().Set(key, value))
|
||||||
}
|
}
|
||||||
assert.NilError(t, cmd.Execute())
|
assert.NilError(t, cmd.Execute())
|
||||||
golden.Assert(t, cli.OutBuffer().String(), fmt.Sprintf("jointoken-%s.golden", tc.name))
|
golden.Assert(t, cli.OutBuffer().String(), fmt.Sprintf("jointoken-%s.golden", tc.name))
|
||||||
|
|
|
@ -6,7 +6,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/docker/cli/internal/test"
|
"github.com/docker/cli/internal/test"
|
||||||
. "github.com/docker/cli/internal/test/builders" // Import builders to get the builder function as package function
|
"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"
|
"github.com/pkg/errors"
|
||||||
|
@ -45,7 +45,7 @@ func TestSwarmUnlockKeyErrors(t *testing.T) {
|
||||||
flagRotate: "true",
|
flagRotate: "true",
|
||||||
},
|
},
|
||||||
swarmInspectFunc: func() (swarm.Swarm, error) {
|
swarmInspectFunc: func() (swarm.Swarm, error) {
|
||||||
return *Swarm(), nil
|
return *builders.Swarm(), nil
|
||||||
},
|
},
|
||||||
expectedError: "cannot rotate because autolock is not turned on",
|
expectedError: "cannot rotate because autolock is not turned on",
|
||||||
},
|
},
|
||||||
|
@ -55,7 +55,7 @@ func TestSwarmUnlockKeyErrors(t *testing.T) {
|
||||||
flagRotate: "true",
|
flagRotate: "true",
|
||||||
},
|
},
|
||||||
swarmInspectFunc: func() (swarm.Swarm, error) {
|
swarmInspectFunc: func() (swarm.Swarm, error) {
|
||||||
return *Swarm(Autolock()), nil
|
return *builders.Swarm(builders.Autolock()), nil
|
||||||
},
|
},
|
||||||
swarmUpdateFunc: func(swarm swarm.Spec, flags swarm.UpdateFlags) error {
|
swarmUpdateFunc: func(swarm swarm.Spec, flags swarm.UpdateFlags) error {
|
||||||
return errors.Errorf("error updating the swarm")
|
return errors.Errorf("error updating the swarm")
|
||||||
|
@ -88,7 +88,7 @@ func TestSwarmUnlockKeyErrors(t *testing.T) {
|
||||||
}))
|
}))
|
||||||
cmd.SetArgs(tc.args)
|
cmd.SetArgs(tc.args)
|
||||||
for key, value := range tc.flags {
|
for key, value := range tc.flags {
|
||||||
cmd.Flags().Set(key, value)
|
assert.Check(t, cmd.Flags().Set(key, value))
|
||||||
}
|
}
|
||||||
cmd.SetOut(io.Discard)
|
cmd.SetOut(io.Discard)
|
||||||
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
|
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
|
||||||
|
@ -129,7 +129,7 @@ func TestSwarmUnlockKey(t *testing.T) {
|
||||||
flagRotate: "true",
|
flagRotate: "true",
|
||||||
},
|
},
|
||||||
swarmInspectFunc: func() (swarm.Swarm, error) {
|
swarmInspectFunc: func() (swarm.Swarm, error) {
|
||||||
return *Swarm(Autolock()), nil
|
return *builders.Swarm(builders.Autolock()), nil
|
||||||
},
|
},
|
||||||
swarmGetUnlockKeyFunc: func() (types.SwarmUnlockKeyResponse, error) {
|
swarmGetUnlockKeyFunc: func() (types.SwarmUnlockKeyResponse, error) {
|
||||||
return types.SwarmUnlockKeyResponse{
|
return types.SwarmUnlockKeyResponse{
|
||||||
|
@ -144,7 +144,7 @@ func TestSwarmUnlockKey(t *testing.T) {
|
||||||
flagRotate: "true",
|
flagRotate: "true",
|
||||||
},
|
},
|
||||||
swarmInspectFunc: func() (swarm.Swarm, error) {
|
swarmInspectFunc: func() (swarm.Swarm, error) {
|
||||||
return *Swarm(Autolock()), nil
|
return *builders.Swarm(builders.Autolock()), nil
|
||||||
},
|
},
|
||||||
swarmGetUnlockKeyFunc: func() (types.SwarmUnlockKeyResponse, error) {
|
swarmGetUnlockKeyFunc: func() (types.SwarmUnlockKeyResponse, error) {
|
||||||
return types.SwarmUnlockKeyResponse{
|
return types.SwarmUnlockKeyResponse{
|
||||||
|
@ -162,7 +162,7 @@ func TestSwarmUnlockKey(t *testing.T) {
|
||||||
cmd := newUnlockKeyCommand(cli)
|
cmd := newUnlockKeyCommand(cli)
|
||||||
cmd.SetArgs(tc.args)
|
cmd.SetArgs(tc.args)
|
||||||
for key, value := range tc.flags {
|
for key, value := range tc.flags {
|
||||||
cmd.Flags().Set(key, value)
|
assert.Check(t, cmd.Flags().Set(key, value))
|
||||||
}
|
}
|
||||||
assert.NilError(t, cmd.Execute())
|
assert.NilError(t, cmd.Execute())
|
||||||
golden.Assert(t, cli.OutBuffer().String(), fmt.Sprintf("unlockkeys-%s.golden", tc.name))
|
golden.Assert(t, cli.OutBuffer().String(), fmt.Sprintf("unlockkeys-%s.golden", tc.name))
|
||||||
|
|
|
@ -7,7 +7,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/docker/cli/internal/test"
|
"github.com/docker/cli/internal/test"
|
||||||
. "github.com/docker/cli/internal/test/builders" // Import builders to get the builder function as package function
|
"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"
|
"github.com/pkg/errors"
|
||||||
|
@ -56,7 +56,7 @@ func TestSwarmUpdateErrors(t *testing.T) {
|
||||||
flagAutolock: "true",
|
flagAutolock: "true",
|
||||||
},
|
},
|
||||||
swarmInspectFunc: func() (swarm.Swarm, error) {
|
swarmInspectFunc: func() (swarm.Swarm, error) {
|
||||||
return *Swarm(), nil
|
return *builders.Swarm(), nil
|
||||||
},
|
},
|
||||||
swarmGetUnlockKeyFunc: func() (types.SwarmUnlockKeyResponse, error) {
|
swarmGetUnlockKeyFunc: func() (types.SwarmUnlockKeyResponse, error) {
|
||||||
return types.SwarmUnlockKeyResponse{}, errors.Errorf("error getting unlock key")
|
return types.SwarmUnlockKeyResponse{}, errors.Errorf("error getting unlock key")
|
||||||
|
@ -73,7 +73,7 @@ func TestSwarmUpdateErrors(t *testing.T) {
|
||||||
}))
|
}))
|
||||||
cmd.SetArgs(tc.args)
|
cmd.SetArgs(tc.args)
|
||||||
for key, value := range tc.flags {
|
for key, value := range tc.flags {
|
||||||
cmd.Flags().Set(key, value)
|
assert.Check(t, cmd.Flags().Set(key, value))
|
||||||
}
|
}
|
||||||
cmd.SetOut(io.Discard)
|
cmd.SetOut(io.Discard)
|
||||||
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
|
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
|
||||||
|
@ -81,7 +81,7 @@ func TestSwarmUpdateErrors(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSwarmUpdate(t *testing.T) {
|
func TestSwarmUpdate(t *testing.T) {
|
||||||
swarmInfo := Swarm()
|
swarmInfo := builders.Swarm()
|
||||||
swarmInfo.ClusterInfo.TLSInfo.TrustRoot = "trustroot"
|
swarmInfo.ClusterInfo.TLSInfo.TrustRoot = "trustroot"
|
||||||
|
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
|
@ -105,7 +105,6 @@ func TestSwarmUpdate(t *testing.T) {
|
||||||
flagMaxSnapshots: "10",
|
flagMaxSnapshots: "10",
|
||||||
flagSnapshotInterval: "100",
|
flagSnapshotInterval: "100",
|
||||||
flagAutolock: "true",
|
flagAutolock: "true",
|
||||||
flagQuiet: "true",
|
|
||||||
},
|
},
|
||||||
swarmInspectFunc: func() (swarm.Swarm, error) {
|
swarmInspectFunc: func() (swarm.Swarm, error) {
|
||||||
return *swarmInfo, nil
|
return *swarmInfo, nil
|
||||||
|
@ -156,7 +155,7 @@ func TestSwarmUpdate(t *testing.T) {
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
swarmInspectFunc: func() (swarm.Swarm, error) {
|
swarmInspectFunc: func() (swarm.Swarm, error) {
|
||||||
return *Swarm(), nil
|
return *builders.Swarm(), nil
|
||||||
},
|
},
|
||||||
swarmGetUnlockKeyFunc: func() (types.SwarmUnlockKeyResponse, error) {
|
swarmGetUnlockKeyFunc: func() (types.SwarmUnlockKeyResponse, error) {
|
||||||
return types.SwarmUnlockKeyResponse{
|
return types.SwarmUnlockKeyResponse{
|
||||||
|
@ -174,7 +173,7 @@ func TestSwarmUpdate(t *testing.T) {
|
||||||
cmd := newUpdateCommand(cli)
|
cmd := newUpdateCommand(cli)
|
||||||
cmd.SetArgs(tc.args)
|
cmd.SetArgs(tc.args)
|
||||||
for key, value := range tc.flags {
|
for key, value := range tc.flags {
|
||||||
cmd.Flags().Set(key, value)
|
assert.Check(t, cmd.Flags().Set(key, value))
|
||||||
}
|
}
|
||||||
cmd.SetOut(cli.OutBuffer())
|
cmd.SetOut(cli.OutBuffer())
|
||||||
assert.NilError(t, cmd.Execute())
|
assert.NilError(t, cmd.Execute())
|
||||||
|
|
|
@ -2,6 +2,7 @@ package system
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
@ -167,7 +168,7 @@ func prettyPrintInfo(dockerCli command.Cli, info info) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(info.ServerErrors) > 0 || len(info.ClientErrors) > 0 {
|
if len(info.ServerErrors) > 0 || len(info.ClientErrors) > 0 {
|
||||||
return fmt.Errorf("errors pretty printing info")
|
return errors.New("errors pretty printing info")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package system
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"sort"
|
"sort"
|
||||||
"text/template"
|
"text/template"
|
||||||
|
@ -71,7 +72,7 @@ Are you sure you want to continue?`
|
||||||
func runPrune(dockerCli command.Cli, options pruneOptions) error {
|
func runPrune(dockerCli command.Cli, options pruneOptions) error {
|
||||||
// TODO version this once "until" filter is supported for volumes
|
// TODO version this once "until" filter is supported for volumes
|
||||||
if options.pruneVolumes && options.filter.Value().Contains("until") {
|
if options.pruneVolumes && options.filter.Value().Contains("until") {
|
||||||
return fmt.Errorf(`ERROR: The "until" filter is not supported with "--volumes"`)
|
return errors.New(`ERROR: The "until" filter is not supported with "--volumes"`)
|
||||||
}
|
}
|
||||||
if !options.force && !command.PromptForConfirmation(dockerCli.In(), dockerCli.Out(), confirmationMessage(dockerCli, options)) {
|
if !options.force && !command.PromptForConfirmation(dockerCli.In(), dockerCli.Out(), confirmationMessage(dockerCli, options)) {
|
||||||
return nil
|
return nil
|
||||||
|
@ -96,11 +97,11 @@ func runPrune(dockerCli command.Cli, options pruneOptions) error {
|
||||||
}
|
}
|
||||||
spaceReclaimed += spc
|
spaceReclaimed += spc
|
||||||
if output != "" {
|
if output != "" {
|
||||||
fmt.Fprintln(dockerCli.Out(), output)
|
_, _ = fmt.Fprintln(dockerCli.Out(), output)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Fprintln(dockerCli.Out(), "Total reclaimed space:", units.HumanSize(float64(spaceReclaimed)))
|
_, _ = fmt.Fprintln(dockerCli.Out(), "Total reclaimed space:", units.HumanSize(float64(spaceReclaimed)))
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ package system
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"errors"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ import (
|
||||||
func TestVersionWithoutServer(t *testing.T) {
|
func TestVersionWithoutServer(t *testing.T) {
|
||||||
cli := test.NewFakeCli(&fakeClient{
|
cli := test.NewFakeCli(&fakeClient{
|
||||||
serverVersion: func(ctx context.Context) (types.Version, error) {
|
serverVersion: func(ctx context.Context) (types.Version, error) {
|
||||||
return types.Version{}, fmt.Errorf("no server")
|
return types.Version{}, errors.New("no server")
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
cmd := NewVersionCommand(cli)
|
cmd := NewVersionCommand(cli)
|
||||||
|
|
|
@ -8,7 +8,7 @@ import (
|
||||||
"github.com/docker/cli/cli/command/formatter"
|
"github.com/docker/cli/cli/command/formatter"
|
||||||
"github.com/docker/cli/cli/command/idresolver"
|
"github.com/docker/cli/cli/command/idresolver"
|
||||||
"github.com/docker/cli/internal/test"
|
"github.com/docker/cli/internal/test"
|
||||||
. "github.com/docker/cli/internal/test/builders" // Import builders to get the builder function as package function
|
"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"
|
||||||
"gotest.tools/v3/assert"
|
"gotest.tools/v3/assert"
|
||||||
|
@ -19,29 +19,29 @@ func TestTaskPrintSorted(t *testing.T) {
|
||||||
apiClient := &fakeClient{
|
apiClient := &fakeClient{
|
||||||
serviceInspectWithRaw: func(ref string, options types.ServiceInspectOptions) (swarm.Service, []byte, error) {
|
serviceInspectWithRaw: func(ref string, options types.ServiceInspectOptions) (swarm.Service, []byte, error) {
|
||||||
if ref == "service-id-one" {
|
if ref == "service-id-one" {
|
||||||
return *Service(ServiceName("service-name-1")), nil, nil
|
return *builders.Service(builders.ServiceName("service-name-1")), nil, nil
|
||||||
}
|
}
|
||||||
return *Service(ServiceName("service-name-10")), nil, nil
|
return *builders.Service(builders.ServiceName("service-name-10")), nil, nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
cli := test.NewFakeCli(apiClient)
|
cli := test.NewFakeCli(apiClient)
|
||||||
tasks := []swarm.Task{
|
tasks := []swarm.Task{
|
||||||
*Task(
|
*builders.Task(
|
||||||
TaskID("id-foo"),
|
builders.TaskID("id-foo"),
|
||||||
TaskServiceID("service-id-ten"),
|
builders.TaskServiceID("service-id-ten"),
|
||||||
TaskNodeID("id-node"),
|
builders.TaskNodeID("id-node"),
|
||||||
WithTaskSpec(TaskImage("myimage:mytag")),
|
builders.WithTaskSpec(builders.TaskImage("myimage:mytag")),
|
||||||
TaskDesiredState(swarm.TaskStateReady),
|
builders.TaskDesiredState(swarm.TaskStateReady),
|
||||||
WithStatus(TaskState(swarm.TaskStateFailed), Timestamp(time.Now().Add(-2*time.Hour))),
|
builders.WithStatus(builders.TaskState(swarm.TaskStateFailed), builders.Timestamp(time.Now().Add(-2*time.Hour))),
|
||||||
),
|
),
|
||||||
*Task(
|
*builders.Task(
|
||||||
TaskID("id-bar"),
|
builders.TaskID("id-bar"),
|
||||||
TaskServiceID("service-id-one"),
|
builders.TaskServiceID("service-id-one"),
|
||||||
TaskNodeID("id-node"),
|
builders.TaskNodeID("id-node"),
|
||||||
WithTaskSpec(TaskImage("myimage:mytag")),
|
builders.WithTaskSpec(builders.TaskImage("myimage:mytag")),
|
||||||
TaskDesiredState(swarm.TaskStateReady),
|
builders.TaskDesiredState(swarm.TaskStateReady),
|
||||||
WithStatus(TaskState(swarm.TaskStateFailed), Timestamp(time.Now().Add(-2*time.Hour))),
|
builders.WithStatus(builders.TaskState(swarm.TaskStateFailed), builders.Timestamp(time.Now().Add(-2*time.Hour))),
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,25 +51,25 @@ func TestTaskPrintSorted(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTaskPrintWithQuietOption(t *testing.T) {
|
func TestTaskPrintWithQuietOption(t *testing.T) {
|
||||||
quiet := true
|
const quiet = true
|
||||||
trunc := false
|
const trunc = false
|
||||||
noResolve := true
|
const noResolve = true
|
||||||
apiClient := &fakeClient{}
|
apiClient := &fakeClient{}
|
||||||
cli := test.NewFakeCli(apiClient)
|
cli := test.NewFakeCli(apiClient)
|
||||||
tasks := []swarm.Task{*Task(TaskID("id-foo"))}
|
tasks := []swarm.Task{*builders.Task(builders.TaskID("id-foo"))}
|
||||||
err := Print(context.Background(), cli, tasks, idresolver.New(apiClient, noResolve), trunc, quiet, formatter.TableFormatKey)
|
err := Print(context.Background(), cli, tasks, idresolver.New(apiClient, noResolve), trunc, quiet, formatter.TableFormatKey)
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
golden.Assert(t, cli.OutBuffer().String(), "task-print-with-quiet-option.golden")
|
golden.Assert(t, cli.OutBuffer().String(), "task-print-with-quiet-option.golden")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTaskPrintWithNoTruncOption(t *testing.T) {
|
func TestTaskPrintWithNoTruncOption(t *testing.T) {
|
||||||
quiet := false
|
const quiet = false
|
||||||
trunc := false
|
const trunc = false
|
||||||
noResolve := true
|
const noResolve = true
|
||||||
apiClient := &fakeClient{}
|
apiClient := &fakeClient{}
|
||||||
cli := test.NewFakeCli(apiClient)
|
cli := test.NewFakeCli(apiClient)
|
||||||
tasks := []swarm.Task{
|
tasks := []swarm.Task{
|
||||||
*Task(TaskID("id-foo-yov6omdek8fg3k5stosyp2m50")),
|
*builders.Task(builders.TaskID("id-foo-yov6omdek8fg3k5stosyp2m50")),
|
||||||
}
|
}
|
||||||
err := Print(context.Background(), cli, tasks, idresolver.New(apiClient, noResolve), trunc, quiet, "{{ .ID }}")
|
err := Print(context.Background(), cli, tasks, idresolver.New(apiClient, noResolve), trunc, quiet, "{{ .ID }}")
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
|
@ -77,13 +77,13 @@ func TestTaskPrintWithNoTruncOption(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTaskPrintWithGlobalService(t *testing.T) {
|
func TestTaskPrintWithGlobalService(t *testing.T) {
|
||||||
quiet := false
|
const quiet = false
|
||||||
trunc := false
|
const trunc = false
|
||||||
noResolve := true
|
const noResolve = true
|
||||||
apiClient := &fakeClient{}
|
apiClient := &fakeClient{}
|
||||||
cli := test.NewFakeCli(apiClient)
|
cli := test.NewFakeCli(apiClient)
|
||||||
tasks := []swarm.Task{
|
tasks := []swarm.Task{
|
||||||
*Task(TaskServiceID("service-id-foo"), TaskNodeID("node-id-bar"), TaskSlot(0)),
|
*builders.Task(builders.TaskServiceID("service-id-foo"), builders.TaskNodeID("node-id-bar"), builders.TaskSlot(0)),
|
||||||
}
|
}
|
||||||
err := Print(context.Background(), cli, tasks, idresolver.New(apiClient, noResolve), trunc, quiet, "{{ .Name }}")
|
err := Print(context.Background(), cli, tasks, idresolver.New(apiClient, noResolve), trunc, quiet, "{{ .Name }}")
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
|
@ -91,13 +91,13 @@ func TestTaskPrintWithGlobalService(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTaskPrintWithReplicatedService(t *testing.T) {
|
func TestTaskPrintWithReplicatedService(t *testing.T) {
|
||||||
quiet := false
|
const quiet = false
|
||||||
trunc := false
|
const trunc = false
|
||||||
noResolve := true
|
const noResolve = true
|
||||||
apiClient := &fakeClient{}
|
apiClient := &fakeClient{}
|
||||||
cli := test.NewFakeCli(apiClient)
|
cli := test.NewFakeCli(apiClient)
|
||||||
tasks := []swarm.Task{
|
tasks := []swarm.Task{
|
||||||
*Task(TaskServiceID("service-id-foo"), TaskSlot(1)),
|
*builders.Task(builders.TaskServiceID("service-id-foo"), builders.TaskSlot(1)),
|
||||||
}
|
}
|
||||||
err := Print(context.Background(), cli, tasks, idresolver.New(apiClient, noResolve), trunc, quiet, "{{ .Name }}")
|
err := Print(context.Background(), cli, tasks, idresolver.New(apiClient, noResolve), trunc, quiet, "{{ .Name }}")
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
|
@ -105,34 +105,34 @@ func TestTaskPrintWithReplicatedService(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTaskPrintWithIndentation(t *testing.T) {
|
func TestTaskPrintWithIndentation(t *testing.T) {
|
||||||
quiet := false
|
const quiet = false
|
||||||
trunc := false
|
const trunc = false
|
||||||
noResolve := false
|
const noResolve = false
|
||||||
apiClient := &fakeClient{
|
apiClient := &fakeClient{
|
||||||
serviceInspectWithRaw: func(ref string, options types.ServiceInspectOptions) (swarm.Service, []byte, error) {
|
serviceInspectWithRaw: func(ref string, options types.ServiceInspectOptions) (swarm.Service, []byte, error) {
|
||||||
return *Service(ServiceName("service-name-foo")), nil, nil
|
return *builders.Service(builders.ServiceName("service-name-foo")), nil, nil
|
||||||
},
|
},
|
||||||
nodeInspectWithRaw: func(ref string) (swarm.Node, []byte, error) {
|
nodeInspectWithRaw: func(ref string) (swarm.Node, []byte, error) {
|
||||||
return *Node(NodeName("node-name-bar")), nil, nil
|
return *builders.Node(builders.NodeName("node-name-bar")), nil, nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
cli := test.NewFakeCli(apiClient)
|
cli := test.NewFakeCli(apiClient)
|
||||||
tasks := []swarm.Task{
|
tasks := []swarm.Task{
|
||||||
*Task(
|
*builders.Task(
|
||||||
TaskID("id-foo"),
|
builders.TaskID("id-foo"),
|
||||||
TaskServiceID("service-id-foo"),
|
builders.TaskServiceID("service-id-foo"),
|
||||||
TaskNodeID("id-node"),
|
builders.TaskNodeID("id-node"),
|
||||||
WithTaskSpec(TaskImage("myimage:mytag")),
|
builders.WithTaskSpec(builders.TaskImage("myimage:mytag")),
|
||||||
TaskDesiredState(swarm.TaskStateReady),
|
builders.TaskDesiredState(swarm.TaskStateReady),
|
||||||
WithStatus(TaskState(swarm.TaskStateFailed), Timestamp(time.Now().Add(-2*time.Hour))),
|
builders.WithStatus(builders.TaskState(swarm.TaskStateFailed), builders.Timestamp(time.Now().Add(-2*time.Hour))),
|
||||||
),
|
),
|
||||||
*Task(
|
*builders.Task(
|
||||||
TaskID("id-bar"),
|
builders.TaskID("id-bar"),
|
||||||
TaskServiceID("service-id-foo"),
|
builders.TaskServiceID("service-id-foo"),
|
||||||
TaskNodeID("id-node"),
|
builders.TaskNodeID("id-node"),
|
||||||
WithTaskSpec(TaskImage("myimage:mytag")),
|
builders.WithTaskSpec(builders.TaskImage("myimage:mytag")),
|
||||||
TaskDesiredState(swarm.TaskStateReady),
|
builders.TaskDesiredState(swarm.TaskStateReady),
|
||||||
WithStatus(TaskState(swarm.TaskStateFailed), Timestamp(time.Now().Add(-2*time.Hour))),
|
builders.WithStatus(builders.TaskState(swarm.TaskStateFailed), builders.Timestamp(time.Now().Add(-2*time.Hour))),
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
err := Print(context.Background(), cli, tasks, idresolver.New(apiClient, noResolve), trunc, quiet, formatter.TableFormatKey)
|
err := Print(context.Background(), cli, tasks, idresolver.New(apiClient, noResolve), trunc, quiet, formatter.TableFormatKey)
|
||||||
|
@ -141,20 +141,20 @@ func TestTaskPrintWithIndentation(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTaskPrintWithResolution(t *testing.T) {
|
func TestTaskPrintWithResolution(t *testing.T) {
|
||||||
quiet := false
|
const quiet = false
|
||||||
trunc := false
|
const trunc = false
|
||||||
noResolve := false
|
const noResolve = false
|
||||||
apiClient := &fakeClient{
|
apiClient := &fakeClient{
|
||||||
serviceInspectWithRaw: func(ref string, options types.ServiceInspectOptions) (swarm.Service, []byte, error) {
|
serviceInspectWithRaw: func(ref string, options types.ServiceInspectOptions) (swarm.Service, []byte, error) {
|
||||||
return *Service(ServiceName("service-name-foo")), nil, nil
|
return *builders.Service(builders.ServiceName("service-name-foo")), nil, nil
|
||||||
},
|
},
|
||||||
nodeInspectWithRaw: func(ref string) (swarm.Node, []byte, error) {
|
nodeInspectWithRaw: func(ref string) (swarm.Node, []byte, error) {
|
||||||
return *Node(NodeName("node-name-bar")), nil, nil
|
return *builders.Node(builders.NodeName("node-name-bar")), nil, nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
cli := test.NewFakeCli(apiClient)
|
cli := test.NewFakeCli(apiClient)
|
||||||
tasks := []swarm.Task{
|
tasks := []swarm.Task{
|
||||||
*Task(TaskServiceID("service-id-foo"), TaskSlot(1)),
|
*builders.Task(builders.TaskServiceID("service-id-foo"), builders.TaskSlot(1)),
|
||||||
}
|
}
|
||||||
err := Print(context.Background(), cli, tasks, idresolver.New(apiClient, noResolve), trunc, quiet, "{{ .Name }} {{ .Node }}")
|
err := Print(context.Background(), cli, tasks, idresolver.New(apiClient, noResolve), trunc, quiet, "{{ .Name }} {{ .Node }}")
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
|
|
|
@ -109,7 +109,7 @@ func decodePrivKeyIfNecessary(privPemBytes []byte, passRet notary.PassRetriever)
|
||||||
if _, ok := pemBlock.Headers["path"]; !ok {
|
if _, ok := pemBlock.Headers["path"]; !ok {
|
||||||
privKey, _, err := trustmanager.GetPasswdDecryptBytes(passRet, privPemBytes, "", "encrypted")
|
privKey, _, err := trustmanager.GetPasswdDecryptBytes(passRet, privPemBytes, "", "encrypted")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return []byte{}, fmt.Errorf("could not decrypt key")
|
return []byte{}, errors.New("could not decrypt key")
|
||||||
}
|
}
|
||||||
privPemBytes = privKey.Private()
|
privPemBytes = privKey.Private()
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,7 @@ func revokeTrust(cli command.Cli, remote string, options revokeOptions) error {
|
||||||
}
|
}
|
||||||
tag := imgRefAndAuth.Tag()
|
tag := imgRefAndAuth.Tag()
|
||||||
if imgRefAndAuth.Tag() == "" && imgRefAndAuth.Digest() != "" {
|
if imgRefAndAuth.Tag() == "" && imgRefAndAuth.Digest() != "" {
|
||||||
return fmt.Errorf("cannot use a digest reference for IMAGE:TAG")
|
return errors.New("cannot use a digest reference for IMAGE:TAG")
|
||||||
}
|
}
|
||||||
if imgRefAndAuth.Tag() == "" && !options.forceYes {
|
if imgRefAndAuth.Tag() == "" && !options.forceYes {
|
||||||
deleteRemote := command.PromptForConfirmation(os.Stdin, cli.Out(), fmt.Sprintf("Please confirm you would like to delete all signature data for %s?", remote))
|
deleteRemote := command.PromptForConfirmation(os.Stdin, cli.Out(), fmt.Sprintf("Please confirm you would like to delete all signature data for %s?", remote))
|
||||||
|
@ -64,7 +64,7 @@ func revokeTrust(cli command.Cli, remote string, options revokeOptions) error {
|
||||||
if err := revokeSignature(notaryRepo, tag); err != nil {
|
if err := revokeSignature(notaryRepo, tag); err != nil {
|
||||||
return errors.Wrapf(err, "could not remove signature for %s", remote)
|
return errors.Wrapf(err, "could not remove signature for %s", remote)
|
||||||
}
|
}
|
||||||
fmt.Fprintf(cli.Out(), "Successfully deleted signature for %s\n", remote)
|
_, _ = fmt.Fprintf(cli.Out(), "Successfully deleted signature for %s\n", remote)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,7 +101,7 @@ func revokeAllSigs(notaryRepo client.Repository) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(releasedTargetWithRoleList) == 0 {
|
if len(releasedTargetWithRoleList) == 0 {
|
||||||
return fmt.Errorf("no signed tags to remove")
|
return errors.New("no signed tags to remove")
|
||||||
}
|
}
|
||||||
|
|
||||||
// we need all the roles that signed each released target so we can remove from all roles.
|
// we need all the roles that signed each released target so we can remove from all roles.
|
||||||
|
|
|
@ -53,11 +53,11 @@ func addSigner(cli command.Cli, options signerAddOptions) error {
|
||||||
return fmt.Errorf("signer name \"%s\" must start with lowercase alphanumeric characters and can include \"-\" or \"_\" after the first character", signerName)
|
return fmt.Errorf("signer name \"%s\" must start with lowercase alphanumeric characters and can include \"-\" or \"_\" after the first character", signerName)
|
||||||
}
|
}
|
||||||
if signerName == "releases" {
|
if signerName == "releases" {
|
||||||
return fmt.Errorf("releases is a reserved keyword, please use a different signer name")
|
return errors.New("releases is a reserved keyword, please use a different signer name")
|
||||||
}
|
}
|
||||||
|
|
||||||
if options.keys.Len() == 0 {
|
if options.keys.Len() == 0 {
|
||||||
return fmt.Errorf("path to a public key must be provided using the `--key` flag")
|
return errors.New("path to a public key must be provided using the `--key` flag")
|
||||||
}
|
}
|
||||||
signerPubKeys, err := ingestPublicKeys(options.keys.GetAll())
|
signerPubKeys, err := ingestPublicKeys(options.keys.GetAll())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -6,7 +6,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/docker/cli/internal/test"
|
"github.com/docker/cli/internal/test"
|
||||||
. "github.com/docker/cli/internal/test/builders" // Import builders to get the builder function as package function
|
"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/volume"
|
"github.com/docker/docker/api/types/volume"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
@ -59,7 +59,7 @@ func TestVolumeInspectErrors(t *testing.T) {
|
||||||
)
|
)
|
||||||
cmd.SetArgs(tc.args)
|
cmd.SetArgs(tc.args)
|
||||||
for key, value := range tc.flags {
|
for key, value := range tc.flags {
|
||||||
cmd.Flags().Set(key, value)
|
assert.Check(t, cmd.Flags().Set(key, value))
|
||||||
}
|
}
|
||||||
cmd.SetOut(io.Discard)
|
cmd.SetOut(io.Discard)
|
||||||
cmd.SetErr(io.Discard)
|
cmd.SetErr(io.Discard)
|
||||||
|
@ -80,14 +80,14 @@ func TestVolumeInspectWithoutFormat(t *testing.T) {
|
||||||
if volumeID != "foo" {
|
if volumeID != "foo" {
|
||||||
return volume.Volume{}, errors.Errorf("Invalid volumeID, expected %s, got %s", "foo", volumeID)
|
return volume.Volume{}, errors.Errorf("Invalid volumeID, expected %s, got %s", "foo", volumeID)
|
||||||
}
|
}
|
||||||
return *Volume(), nil
|
return *builders.Volume(), nil
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "multiple-volume-with-labels",
|
name: "multiple-volume-with-labels",
|
||||||
args: []string{"foo", "bar"},
|
args: []string{"foo", "bar"},
|
||||||
volumeInspectFunc: func(volumeID string) (volume.Volume, error) {
|
volumeInspectFunc: func(volumeID string) (volume.Volume, error) {
|
||||||
return *Volume(VolumeName(volumeID), VolumeLabels(map[string]string{
|
return *builders.Volume(builders.VolumeName(volumeID), builders.VolumeLabels(map[string]string{
|
||||||
"foo": "bar",
|
"foo": "bar",
|
||||||
})), nil
|
})), nil
|
||||||
},
|
},
|
||||||
|
@ -106,7 +106,7 @@ func TestVolumeInspectWithoutFormat(t *testing.T) {
|
||||||
|
|
||||||
func TestVolumeInspectWithFormat(t *testing.T) {
|
func TestVolumeInspectWithFormat(t *testing.T) {
|
||||||
volumeInspectFunc := func(volumeID string) (volume.Volume, error) {
|
volumeInspectFunc := func(volumeID string) (volume.Volume, error) {
|
||||||
return *Volume(VolumeLabels(map[string]string{
|
return *builders.Volume(builders.VolumeLabels(map[string]string{
|
||||||
"foo": "bar",
|
"foo": "bar",
|
||||||
})), nil
|
})), nil
|
||||||
}
|
}
|
||||||
|
@ -135,7 +135,7 @@ func TestVolumeInspectWithFormat(t *testing.T) {
|
||||||
})
|
})
|
||||||
cmd := newInspectCommand(cli)
|
cmd := newInspectCommand(cli)
|
||||||
cmd.SetArgs(tc.args)
|
cmd.SetArgs(tc.args)
|
||||||
cmd.Flags().Set("format", tc.format)
|
assert.Check(t, cmd.Flags().Set("format", tc.format))
|
||||||
assert.NilError(t, cmd.Execute())
|
assert.NilError(t, cmd.Execute())
|
||||||
golden.Assert(t, cli.OutBuffer().String(), fmt.Sprintf("volume-inspect-with-format.%s.golden", tc.name))
|
golden.Assert(t, cli.OutBuffer().String(), fmt.Sprintf("volume-inspect-with-format.%s.golden", tc.name))
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,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/cli/internal/test/builders" // Import builders to get the builder function as package function
|
"github.com/docker/cli/internal/test/builders"
|
||||||
"github.com/docker/docker/api/types/filters"
|
"github.com/docker/docker/api/types/filters"
|
||||||
"github.com/docker/docker/api/types/volume"
|
"github.com/docker/docker/api/types/volume"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
@ -40,7 +40,7 @@ func TestVolumeListErrors(t *testing.T) {
|
||||||
)
|
)
|
||||||
cmd.SetArgs(tc.args)
|
cmd.SetArgs(tc.args)
|
||||||
for key, value := range tc.flags {
|
for key, value := range tc.flags {
|
||||||
cmd.Flags().Set(key, value)
|
assert.Check(t, cmd.Flags().Set(key, value))
|
||||||
}
|
}
|
||||||
cmd.SetOut(io.Discard)
|
cmd.SetOut(io.Discard)
|
||||||
cmd.SetErr(io.Discard)
|
cmd.SetErr(io.Discard)
|
||||||
|
@ -53,9 +53,9 @@ func TestVolumeListWithoutFormat(t *testing.T) {
|
||||||
volumeListFunc: func(filter filters.Args) (volume.ListResponse, error) {
|
volumeListFunc: func(filter filters.Args) (volume.ListResponse, error) {
|
||||||
return volume.ListResponse{
|
return volume.ListResponse{
|
||||||
Volumes: []*volume.Volume{
|
Volumes: []*volume.Volume{
|
||||||
Volume(),
|
builders.Volume(),
|
||||||
Volume(VolumeName("foo"), VolumeDriver("bar")),
|
builders.Volume(builders.VolumeName("foo"), builders.VolumeDriver("bar")),
|
||||||
Volume(VolumeName("baz"), VolumeLabels(map[string]string{
|
builders.Volume(builders.VolumeName("baz"), builders.VolumeLabels(map[string]string{
|
||||||
"foo": "bar",
|
"foo": "bar",
|
||||||
})),
|
})),
|
||||||
},
|
},
|
||||||
|
@ -72,9 +72,9 @@ func TestVolumeListWithConfigFormat(t *testing.T) {
|
||||||
volumeListFunc: func(filter filters.Args) (volume.ListResponse, error) {
|
volumeListFunc: func(filter filters.Args) (volume.ListResponse, error) {
|
||||||
return volume.ListResponse{
|
return volume.ListResponse{
|
||||||
Volumes: []*volume.Volume{
|
Volumes: []*volume.Volume{
|
||||||
Volume(),
|
builders.Volume(),
|
||||||
Volume(VolumeName("foo"), VolumeDriver("bar")),
|
builders.Volume(builders.VolumeName("foo"), builders.VolumeDriver("bar")),
|
||||||
Volume(VolumeName("baz"), VolumeLabels(map[string]string{
|
builders.Volume(builders.VolumeName("baz"), builders.VolumeLabels(map[string]string{
|
||||||
"foo": "bar",
|
"foo": "bar",
|
||||||
})),
|
})),
|
||||||
},
|
},
|
||||||
|
@ -94,9 +94,9 @@ func TestVolumeListWithFormat(t *testing.T) {
|
||||||
volumeListFunc: func(filter filters.Args) (volume.ListResponse, error) {
|
volumeListFunc: func(filter filters.Args) (volume.ListResponse, error) {
|
||||||
return volume.ListResponse{
|
return volume.ListResponse{
|
||||||
Volumes: []*volume.Volume{
|
Volumes: []*volume.Volume{
|
||||||
Volume(),
|
builders.Volume(),
|
||||||
Volume(VolumeName("foo"), VolumeDriver("bar")),
|
builders.Volume(builders.VolumeName("foo"), builders.VolumeDriver("bar")),
|
||||||
Volume(VolumeName("baz"), VolumeLabels(map[string]string{
|
builders.Volume(builders.VolumeName("baz"), builders.VolumeLabels(map[string]string{
|
||||||
"foo": "bar",
|
"foo": "bar",
|
||||||
})),
|
})),
|
||||||
},
|
},
|
||||||
|
@ -104,7 +104,7 @@ func TestVolumeListWithFormat(t *testing.T) {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
cmd := newListCommand(cli)
|
cmd := newListCommand(cli)
|
||||||
cmd.Flags().Set("format", "{{ .Name }} {{ .Driver }} {{ .Labels }}")
|
assert.Check(t, cmd.Flags().Set("format", "{{ .Name }} {{ .Driver }} {{ .Labels }}"))
|
||||||
assert.NilError(t, cmd.Execute())
|
assert.NilError(t, cmd.Execute())
|
||||||
golden.Assert(t, cli.OutBuffer().String(), "volume-list-with-format.golden")
|
golden.Assert(t, cli.OutBuffer().String(), "volume-list-with-format.golden")
|
||||||
}
|
}
|
||||||
|
@ -114,15 +114,15 @@ func TestVolumeListSortOrder(t *testing.T) {
|
||||||
volumeListFunc: func(filter filters.Args) (volume.ListResponse, error) {
|
volumeListFunc: func(filter filters.Args) (volume.ListResponse, error) {
|
||||||
return volume.ListResponse{
|
return volume.ListResponse{
|
||||||
Volumes: []*volume.Volume{
|
Volumes: []*volume.Volume{
|
||||||
Volume(VolumeName("volume-2-foo")),
|
builders.Volume(builders.VolumeName("volume-2-foo")),
|
||||||
Volume(VolumeName("volume-10-foo")),
|
builders.Volume(builders.VolumeName("volume-10-foo")),
|
||||||
Volume(VolumeName("volume-1-foo")),
|
builders.Volume(builders.VolumeName("volume-1-foo")),
|
||||||
},
|
},
|
||||||
}, nil
|
}, nil
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
cmd := newListCommand(cli)
|
cmd := newListCommand(cli)
|
||||||
cmd.Flags().Set("format", "{{ .Name }}")
|
assert.Check(t, cmd.Flags().Set("format", "{{ .Name }}"))
|
||||||
assert.NilError(t, cmd.Execute())
|
assert.NilError(t, cmd.Execute())
|
||||||
golden.Assert(t, cli.OutBuffer().String(), "volume-list-sort.golden")
|
golden.Assert(t, cli.OutBuffer().String(), "volume-list-sort.golden")
|
||||||
}
|
}
|
||||||
|
@ -223,14 +223,14 @@ func TestClusterVolumeList(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Volume(VolumeName("volume-local-1")),
|
builders.Volume(builders.VolumeName("volume-local-1")),
|
||||||
},
|
},
|
||||||
}, nil
|
}, nil
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
cmd := newListCommand(cli)
|
cmd := newListCommand(cli)
|
||||||
cmd.Flags().Set("cluster", "true")
|
assert.Check(t, cmd.Flags().Set("cluster", "true"))
|
||||||
assert.NilError(t, cmd.Execute())
|
assert.NilError(t, cmd.Execute())
|
||||||
golden.Assert(t, cli.OutBuffer().String(), "volume-cluster-volume-list.golden")
|
golden.Assert(t, cli.OutBuffer().String(), "volume-cluster-volume-list.golden")
|
||||||
}
|
}
|
||||||
|
|
|
@ -99,7 +99,7 @@ func getDescription(err validationError) string {
|
||||||
switch err.parent.Type() {
|
switch err.parent.Type() {
|
||||||
case "invalid_type":
|
case "invalid_type":
|
||||||
if expectedType, ok := err.parent.Details()["expected"].(string); ok {
|
if expectedType, ok := err.parent.Details()["expected"].(string); ok {
|
||||||
return fmt.Sprintf("must be a %s", humanReadableType(expectedType))
|
return "must be a " + humanReadableType(expectedType)
|
||||||
}
|
}
|
||||||
case jsonschemaOneOf, jsonschemaAnyOf:
|
case jsonschemaOneOf, jsonschemaAnyOf:
|
||||||
if err.child == nil {
|
if err.child == nil {
|
||||||
|
|
|
@ -2,7 +2,6 @@ package store
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -162,7 +161,7 @@ func newNotFoundError(ref string) *notFoundError {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *notFoundError) Error() string {
|
func (n *notFoundError) Error() string {
|
||||||
return fmt.Sprintf("No such manifest: %s", n.object)
|
return "No such manifest: " + n.object
|
||||||
}
|
}
|
||||||
|
|
||||||
// NotFound interface
|
// NotFound interface
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package client
|
package client
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
@ -126,7 +125,7 @@ type existingTokenHandler struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (th *existingTokenHandler) AuthorizeRequest(req *http.Request, _ map[string]string) error {
|
func (th *existingTokenHandler) AuthorizeRequest(req *http.Request, _ map[string]string) error {
|
||||||
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", th.token))
|
req.Header.Set("Authorization", "Bearer "+th.token)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -202,7 +202,8 @@ func pullManifestList(ctx context.Context, ref reference.Named, repo distributio
|
||||||
}
|
}
|
||||||
|
|
||||||
// Replace platform from config
|
// Replace platform from config
|
||||||
imageManifest.Descriptor.Platform = types.OCIPlatform(&manifestDescriptor.Platform)
|
p := manifestDescriptor.Platform
|
||||||
|
imageManifest.Descriptor.Platform = types.OCIPlatform(&p)
|
||||||
|
|
||||||
infos = append(infos, imageManifest)
|
infos = append(infos, imageManifest)
|
||||||
}
|
}
|
||||||
|
@ -242,11 +243,6 @@ func (c *client) iterateEndpoints(ctx context.Context, namedRef reference.Named,
|
||||||
|
|
||||||
confirmedTLSRegistries := make(map[string]bool)
|
confirmedTLSRegistries := make(map[string]bool)
|
||||||
for _, endpoint := range endpoints {
|
for _, endpoint := range endpoints {
|
||||||
if endpoint.Version == registry.APIVersion1 {
|
|
||||||
logrus.Debugf("skipping v1 endpoint %s", endpoint.URL)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if endpoint.URL.Scheme != "https" {
|
if endpoint.URL.Scheme != "https" {
|
||||||
if _, confirmedTLS := confirmedTLSRegistries[endpoint.URL.Host]; confirmedTLS {
|
if _, confirmedTLS := confirmedTLSRegistries[endpoint.URL.Host]; confirmedTLS {
|
||||||
logrus.Debugf("skipping non-TLS endpoint %s for host/port that appears to use TLS", endpoint.URL)
|
logrus.Debugf("skipping non-TLS endpoint %s for host/port that appears to use TLS", endpoint.URL)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
variable "GO_VERSION" {
|
variable "GO_VERSION" {
|
||||||
default = "1.20.13"
|
default = "1.22.6"
|
||||||
}
|
}
|
||||||
variable "VERSION" {
|
variable "VERSION" {
|
||||||
default = ""
|
default = ""
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# syntax=docker/dockerfile:1
|
# syntax=docker/dockerfile:1
|
||||||
|
|
||||||
ARG ALPINE_VERSION=3.18
|
ARG ALPINE_VERSION=3.20
|
||||||
|
|
||||||
FROM alpine:${ALPINE_VERSION} AS gen
|
FROM alpine:${ALPINE_VERSION} AS gen
|
||||||
RUN apk add --no-cache bash git
|
RUN apk add --no-cache bash git
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# syntax=docker/dockerfile:1
|
# syntax=docker/dockerfile:1
|
||||||
|
|
||||||
ARG GO_VERSION=1.20.13
|
ARG GO_VERSION=1.22.6
|
||||||
ARG ALPINE_VERSION=3.18
|
ARG ALPINE_VERSION=3.20
|
||||||
|
|
||||||
ARG BUILDX_VERSION=0.11.2
|
ARG BUILDX_VERSION=0.11.2
|
||||||
FROM docker/buildx-bin:${BUILDX_VERSION} AS buildx
|
FROM docker/buildx-bin:${BUILDX_VERSION} AS buildx
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
# syntax=docker/dockerfile:1
|
# syntax=docker/dockerfile:1
|
||||||
|
|
||||||
ARG GO_VERSION=1.20.13
|
ARG GO_VERSION=1.22.6
|
||||||
ARG ALPINE_VERSION=3.18
|
ARG ALPINE_VERSION=3.20
|
||||||
ARG GOLANGCI_LINT_VERSION=v1.52.2
|
ARG GOLANGCI_LINT_VERSION=v1.59.1
|
||||||
|
|
||||||
FROM golangci/golangci-lint:${GOLANGCI_LINT_VERSION}-alpine AS golangci-lint
|
FROM golangci/golangci-lint:${GOLANGCI_LINT_VERSION}-alpine AS golangci-lint
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# syntax=docker/dockerfile:1
|
# syntax=docker/dockerfile:1
|
||||||
|
|
||||||
ARG GO_VERSION=1.20.13
|
ARG GO_VERSION=1.22.6
|
||||||
ARG ALPINE_VERSION=3.18
|
ARG ALPINE_VERSION=3.20
|
||||||
ARG MODOUTDATED_VERSION=v0.8.0
|
ARG MODOUTDATED_VERSION=v0.8.0
|
||||||
|
|
||||||
FROM golang:${GO_VERSION}-alpine${ALPINE_VERSION} AS base
|
FROM golang:${GO_VERSION}-alpine${ALPINE_VERSION} AS base
|
||||||
|
|
|
@ -329,10 +329,10 @@ func createImage(t *testing.T, repo string, tags ...string) string {
|
||||||
func withNotaryPassphrase(pwd string) func(*icmd.Cmd) {
|
func withNotaryPassphrase(pwd string) func(*icmd.Cmd) {
|
||||||
return func(c *icmd.Cmd) {
|
return func(c *icmd.Cmd) {
|
||||||
c.Env = append(c.Env, []string{
|
c.Env = append(c.Env, []string{
|
||||||
fmt.Sprintf("NOTARY_ROOT_PASSPHRASE=%s", pwd),
|
"NOTARY_ROOT_PASSPHRASE=" + pwd,
|
||||||
fmt.Sprintf("NOTARY_TARGETS_PASSPHRASE=%s", pwd),
|
"NOTARY_TARGETS_PASSPHRASE=" + pwd,
|
||||||
fmt.Sprintf("NOTARY_SNAPSHOT_PASSPHRASE=%s", pwd),
|
"NOTARY_SNAPSHOT_PASSPHRASE=" + pwd,
|
||||||
fmt.Sprintf("NOTARY_DELEGATION_PASSPHRASE=%s", pwd),
|
"NOTARY_DELEGATION_PASSPHRASE=" + pwd,
|
||||||
}...)
|
}...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,11 +17,11 @@ const (
|
||||||
// AlpineImage is an image in the test registry
|
// AlpineImage is an image in the test registry
|
||||||
AlpineImage = "registry:5000/alpine:3.6"
|
AlpineImage = "registry:5000/alpine:3.6"
|
||||||
// AlpineSha is the sha of the alpine image
|
// AlpineSha is the sha of the alpine image
|
||||||
AlpineSha = "641b95ddb2ea9dc2af1a0113b6b348ebc20872ba615204fbe12148e98fd6f23d"
|
AlpineSha = "641b95ddb2ea9dc2af1a0113b6b348ebc20872ba615204fbe12148e98fd6f23d" // #nosec G101 -- ignoring: Potential hardcoded credentials (gosec)
|
||||||
// BusyboxImage is an image in the test registry
|
// BusyboxImage is an image in the test registry
|
||||||
BusyboxImage = "registry:5000/busybox:1.27.2"
|
BusyboxImage = "registry:5000/busybox:1.27.2"
|
||||||
// BusyboxSha is the sha of the busybox image
|
// BusyboxSha is the sha of the busybox image
|
||||||
BusyboxSha = "030fcb92e1487b18c974784dcc110a93147c9fc402188370fbfd17efabffc6af"
|
BusyboxSha = "030fcb92e1487b18c974784dcc110a93147c9fc402188370fbfd17efabffc6af" // #nosec G101 -- ignoring: Potential hardcoded credentials (gosec)
|
||||||
)
|
)
|
||||||
|
|
||||||
// SetupConfigFile creates a config.json file for testing
|
// SetupConfigFile creates a config.json file for testing
|
||||||
|
|
|
@ -2,7 +2,6 @@ package plugin
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
@ -23,7 +22,7 @@ const registryPrefix = "registry:5000"
|
||||||
func TestInstallWithContentTrust(t *testing.T) {
|
func TestInstallWithContentTrust(t *testing.T) {
|
||||||
skip.If(t, environment.SkipPluginTests())
|
skip.If(t, environment.SkipPluginTests())
|
||||||
|
|
||||||
pluginName := fmt.Sprintf("%s/plugin-content-trust", registryPrefix)
|
const pluginName = registryPrefix + "/plugin-content-trust"
|
||||||
|
|
||||||
dir := fixtures.SetupConfigFile(t)
|
dir := fixtures.SetupConfigFile(t)
|
||||||
defer dir.Remove()
|
defer dir.Remove()
|
||||||
|
@ -50,7 +49,7 @@ func TestInstallWithContentTrust(t *testing.T) {
|
||||||
fixtures.WithNotary,
|
fixtures.WithNotary,
|
||||||
)
|
)
|
||||||
result.Assert(t, icmd.Expected{
|
result.Assert(t, icmd.Expected{
|
||||||
Out: fmt.Sprintf("Status: Downloaded newer image for %s@sha", pluginName),
|
Out: "Status: Downloaded newer image for " + pluginName + "@sha",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# syntax=docker/dockerfile:1
|
# syntax=docker/dockerfile:1
|
||||||
|
|
||||||
ARG GO_VERSION=1.20.13
|
ARG GO_VERSION=1.22.6
|
||||||
|
|
||||||
FROM golang:${GO_VERSION}-alpine AS generated
|
FROM golang:${GO_VERSION}-alpine AS generated
|
||||||
RUN go install github.com/dmcgowan/quicktls@master
|
RUN go install github.com/dmcgowan/quicktls@master
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package trust
|
package trust
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/docker/cli/e2e/internal/fixtures"
|
"github.com/docker/cli/e2e/internal/fixtures"
|
||||||
|
@ -57,15 +56,15 @@ func setupTrustedImagesForRevoke(t *testing.T, dir fs.Dir) {
|
||||||
|
|
||||||
func setupTrustedImagesForRevokeRepo(t *testing.T, dir fs.Dir) {
|
func setupTrustedImagesForRevokeRepo(t *testing.T, dir fs.Dir) {
|
||||||
icmd.RunCmd(icmd.Command("docker", "pull", fixtures.AlpineImage)).Assert(t, icmd.Success)
|
icmd.RunCmd(icmd.Command("docker", "pull", fixtures.AlpineImage)).Assert(t, icmd.Success)
|
||||||
icmd.RunCommand("docker", "tag", fixtures.AlpineImage, fmt.Sprintf("%s:v1", revokeRepo)).Assert(t, icmd.Success)
|
icmd.RunCommand("docker", "tag", fixtures.AlpineImage, revokeRepo+":v1").Assert(t, icmd.Success)
|
||||||
icmd.RunCmd(
|
icmd.RunCmd(
|
||||||
icmd.Command("docker", "-D", "trust", "sign", fmt.Sprintf("%s:v1", revokeRepo)),
|
icmd.Command("docker", "-D", "trust", "sign", revokeRepo+":v1"),
|
||||||
fixtures.WithPassphrase("root_password", "repo_password"),
|
fixtures.WithPassphrase("root_password", "repo_password"),
|
||||||
fixtures.WithConfig(dir.Path()), fixtures.WithNotary).Assert(t, icmd.Success)
|
fixtures.WithConfig(dir.Path()), fixtures.WithNotary).Assert(t, icmd.Success)
|
||||||
icmd.RunCmd(icmd.Command("docker", "pull", fixtures.BusyboxImage)).Assert(t, icmd.Success)
|
icmd.RunCmd(icmd.Command("docker", "pull", fixtures.BusyboxImage)).Assert(t, icmd.Success)
|
||||||
icmd.RunCommand("docker", "tag", fixtures.BusyboxImage, fmt.Sprintf("%s:v2", revokeRepo)).Assert(t, icmd.Success)
|
icmd.RunCommand("docker", "tag", fixtures.BusyboxImage, revokeRepo+":v2").Assert(t, icmd.Success)
|
||||||
icmd.RunCmd(
|
icmd.RunCmd(
|
||||||
icmd.Command("docker", "-D", "trust", "sign", fmt.Sprintf("%s:v2", revokeRepo)),
|
icmd.Command("docker", "-D", "trust", "sign", revokeRepo+":v2"),
|
||||||
fixtures.WithPassphrase("root_password", "repo_password"),
|
fixtures.WithPassphrase("root_password", "repo_password"),
|
||||||
fixtures.WithConfig(dir.Path()), fixtures.WithNotary).Assert(t, icmd.Success)
|
fixtures.WithConfig(dir.Path()), fixtures.WithNotary).Assert(t, icmd.Success)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package trust
|
package trust
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/docker/cli/e2e/internal/fixtures"
|
"github.com/docker/cli/e2e/internal/fixtures"
|
||||||
|
@ -30,7 +29,7 @@ func TestSignLocalImage(t *testing.T) {
|
||||||
fixtures.WithPassphrase("root_password", "repo_password"),
|
fixtures.WithPassphrase("root_password", "repo_password"),
|
||||||
fixtures.WithConfig(dir.Path()), fixtures.WithNotary)
|
fixtures.WithConfig(dir.Path()), fixtures.WithNotary)
|
||||||
result.Assert(t, icmd.Success)
|
result.Assert(t, icmd.Success)
|
||||||
assert.Check(t, is.Contains(result.Stdout(), fmt.Sprintf("v1: digest: sha256:%s", fixtures.AlpineSha)))
|
assert.Check(t, is.Contains(result.Stdout(), "v1: digest: sha256:"+fixtures.AlpineSha))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSignWithLocalFlag(t *testing.T) {
|
func TestSignWithLocalFlag(t *testing.T) {
|
||||||
|
@ -44,7 +43,7 @@ func TestSignWithLocalFlag(t *testing.T) {
|
||||||
fixtures.WithPassphrase("root_password", "repo_password"),
|
fixtures.WithPassphrase("root_password", "repo_password"),
|
||||||
fixtures.WithConfig(dir.Path()), fixtures.WithNotary)
|
fixtures.WithConfig(dir.Path()), fixtures.WithNotary)
|
||||||
result.Assert(t, icmd.Success)
|
result.Assert(t, icmd.Success)
|
||||||
assert.Check(t, is.Contains(result.Stdout(), fmt.Sprintf("v1: digest: sha256:%s", fixtures.BusyboxSha)))
|
assert.Check(t, is.Contains(result.Stdout(), "v1: digest: sha256:"+fixtures.BusyboxSha))
|
||||||
}
|
}
|
||||||
|
|
||||||
func setupTrustedImageForOverwrite(t *testing.T, dir fs.Dir) {
|
func setupTrustedImageForOverwrite(t *testing.T, dir fs.Dir) {
|
||||||
|
@ -55,7 +54,7 @@ func setupTrustedImageForOverwrite(t *testing.T, dir fs.Dir) {
|
||||||
fixtures.WithPassphrase("root_password", "repo_password"),
|
fixtures.WithPassphrase("root_password", "repo_password"),
|
||||||
fixtures.WithConfig(dir.Path()), fixtures.WithNotary)
|
fixtures.WithConfig(dir.Path()), fixtures.WithNotary)
|
||||||
result.Assert(t, icmd.Success)
|
result.Assert(t, icmd.Success)
|
||||||
assert.Check(t, is.Contains(result.Stdout(), fmt.Sprintf("v1: digest: sha256:%s", fixtures.AlpineSha)))
|
assert.Check(t, is.Contains(result.Stdout(), "v1: digest: sha256:"+fixtures.AlpineSha))
|
||||||
icmd.RunCmd(icmd.Command("docker", "pull", fixtures.BusyboxImage)).Assert(t, icmd.Success)
|
icmd.RunCmd(icmd.Command("docker", "pull", fixtures.BusyboxImage)).Assert(t, icmd.Success)
|
||||||
icmd.RunCommand("docker", "tag", fixtures.BusyboxImage, localImage).Assert(t, icmd.Success)
|
icmd.RunCommand("docker", "tag", fixtures.BusyboxImage, localImage).Assert(t, icmd.Success)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ package test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
@ -172,7 +172,7 @@ func (c *FakeCli) NotaryClient(imgRefAndAuth trust.ImageRefAndAuth, actions []st
|
||||||
if c.notaryClientFunc != nil {
|
if c.notaryClientFunc != nil {
|
||||||
return c.notaryClientFunc(imgRefAndAuth, actions)
|
return c.notaryClientFunc(imgRefAndAuth, actions)
|
||||||
}
|
}
|
||||||
return nil, fmt.Errorf("no notary client available unless defined")
|
return nil, errors.New("no notary client available unless defined")
|
||||||
}
|
}
|
||||||
|
|
||||||
// ManifestStore returns a fake store used for testing
|
// ManifestStore returns a fake store used for testing
|
||||||
|
|
|
@ -2,6 +2,7 @@ package opts
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/csv"
|
"encoding/csv"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
@ -68,7 +69,7 @@ func (o *ConfigOpt) Set(value string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if options.ConfigName == "" {
|
if options.ConfigName == "" {
|
||||||
return fmt.Errorf("source is required")
|
return errors.New("source is required")
|
||||||
}
|
}
|
||||||
if options.File.Name == "" {
|
if options.File.Name == "" {
|
||||||
options.File.Name = options.ConfigName
|
options.File.Name = options.ConfigName
|
||||||
|
|
|
@ -13,7 +13,7 @@ func TestValidateEnv(t *testing.T) {
|
||||||
type testCase struct {
|
type testCase struct {
|
||||||
value string
|
value string
|
||||||
expected string
|
expected string
|
||||||
err error
|
expectedErr string
|
||||||
}
|
}
|
||||||
tests := []testCase{
|
tests := []testCase{
|
||||||
{
|
{
|
||||||
|
@ -54,7 +54,7 @@ func TestValidateEnv(t *testing.T) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: "=a",
|
value: "=a",
|
||||||
err: fmt.Errorf("invalid environment variable: =a"),
|
expectedErr: "invalid environment variable: =a",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: "PATH=",
|
value: "PATH=",
|
||||||
|
@ -90,7 +90,7 @@ func TestValidateEnv(t *testing.T) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: "=",
|
value: "=",
|
||||||
err: fmt.Errorf("invalid environment variable: ="),
|
expectedErr: "invalid environment variable: =",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ func TestValidateEnv(t *testing.T) {
|
||||||
tests = append(tests, testCase{
|
tests = append(tests, testCase{
|
||||||
value: "PaTh",
|
value: "PaTh",
|
||||||
expected: fmt.Sprintf("PaTh=%v", os.Getenv("PATH")),
|
expected: fmt.Sprintf("PaTh=%v", os.Getenv("PATH")),
|
||||||
err: nil,
|
expectedErr: "",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,10 +108,10 @@ func TestValidateEnv(t *testing.T) {
|
||||||
t.Run(tc.value, func(t *testing.T) {
|
t.Run(tc.value, func(t *testing.T) {
|
||||||
actual, err := ValidateEnv(tc.value)
|
actual, err := ValidateEnv(tc.value)
|
||||||
|
|
||||||
if tc.err == nil {
|
if tc.expectedErr == "" {
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
} else {
|
} else {
|
||||||
assert.Error(t, err, tc.err.Error())
|
assert.Error(t, err, tc.expectedErr)
|
||||||
}
|
}
|
||||||
assert.Equal(t, actual, tc.expected)
|
assert.Equal(t, actual, tc.expected)
|
||||||
})
|
})
|
||||||
|
|
|
@ -18,7 +18,7 @@ type ErrBadKey struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e ErrBadKey) Error() string {
|
func (e ErrBadKey) Error() string {
|
||||||
return fmt.Sprintf("poorly formatted environment: %s", e.msg)
|
return "poorly formatted environment: " + e.msg
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseKeyValueFile(filename string, emptyFn func(string) (string, bool)) ([]string, error) {
|
func parseKeyValueFile(filename string, emptyFn func(string) (string, bool)) ([]string, error) {
|
||||||
|
|
|
@ -21,7 +21,7 @@ func TestParseHost(t *testing.T) {
|
||||||
" ": defaultHost,
|
" ": defaultHost,
|
||||||
"fd://": "fd://",
|
"fd://": "fd://",
|
||||||
"fd://something": "fd://something",
|
"fd://something": "fd://something",
|
||||||
"tcp://host:": fmt.Sprintf("tcp://host:%s", defaultHTTPPort),
|
"tcp://host:": "tcp://host:" + defaultHTTPPort,
|
||||||
"tcp://": defaultTCPHost,
|
"tcp://": defaultTCPHost,
|
||||||
"tcp://:2375": fmt.Sprintf("tcp://%s:%s", defaultHTTPHost, defaultHTTPPort),
|
"tcp://:2375": fmt.Sprintf("tcp://%s:%s", defaultHTTPHost, defaultHTTPPort),
|
||||||
"tcp://:2376": fmt.Sprintf("tcp://%s:%s", defaultHTTPHost, defaultTLSHTTPPort),
|
"tcp://:2376": fmt.Sprintf("tcp://%s:%s", defaultHTTPHost, defaultTLSHTTPPort),
|
||||||
|
|
|
@ -2,6 +2,7 @@ package opts
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/csv"
|
"encoding/csv"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
@ -144,11 +145,11 @@ func (m *MountOpt) Set(value string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if mount.Type == "" {
|
if mount.Type == "" {
|
||||||
return fmt.Errorf("type is required")
|
return errors.New("type is required")
|
||||||
}
|
}
|
||||||
|
|
||||||
if mount.Target == "" {
|
if mount.Target == "" {
|
||||||
return fmt.Errorf("target is required")
|
return errors.New("target is required")
|
||||||
}
|
}
|
||||||
|
|
||||||
if mount.VolumeOptions != nil && mount.Type != mounttypes.TypeVolume {
|
if mount.VolumeOptions != nil && mount.Type != mounttypes.TypeVolume {
|
||||||
|
|
|
@ -2,6 +2,7 @@ package opts
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/csv"
|
"encoding/csv"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -76,11 +77,11 @@ func (n *NetworkOpt) Set(value string) error {
|
||||||
}
|
}
|
||||||
netOpt.DriverOpts[key] = val
|
netOpt.DriverOpts[key] = val
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("invalid field key %s", key)
|
return errors.New("invalid field key " + key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(netOpt.Target) == 0 {
|
if len(netOpt.Target) == 0 {
|
||||||
return fmt.Errorf("network name/id is not specified")
|
return errors.New("network name/id is not specified")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
netOpt.Target = value
|
netOpt.Target = value
|
||||||
|
@ -119,7 +120,7 @@ func parseDriverOpt(driverOpt string) (string, string, error) {
|
||||||
// TODO(thaJeztah): should value be converted to lowercase as well, or only the key?
|
// TODO(thaJeztah): should value be converted to lowercase as well, or only the key?
|
||||||
key, value, ok := strings.Cut(strings.ToLower(driverOpt), "=")
|
key, value, ok := strings.Cut(strings.ToLower(driverOpt), "=")
|
||||||
if !ok || key == "" {
|
if !ok || key == "" {
|
||||||
return "", "", fmt.Errorf("invalid key value pair format in driver options")
|
return "", "", errors.New("invalid key value pair format in driver options")
|
||||||
}
|
}
|
||||||
key = strings.TrimSpace(key)
|
key = strings.TrimSpace(key)
|
||||||
value = strings.TrimSpace(value)
|
value = strings.TrimSpace(value)
|
||||||
|
|
|
@ -397,7 +397,7 @@ func ParseCPUs(value string) (int64, error) {
|
||||||
}
|
}
|
||||||
nano := cpu.Mul(cpu, big.NewRat(1e9, 1))
|
nano := cpu.Mul(cpu, big.NewRat(1e9, 1))
|
||||||
if !nano.IsInt() {
|
if !nano.IsInt() {
|
||||||
return 0, fmt.Errorf("value is too precise")
|
return 0, errors.New("value is too precise")
|
||||||
}
|
}
|
||||||
return nano.Num().Int64(), nil
|
return nano.Num().Int64(), nil
|
||||||
}
|
}
|
||||||
|
@ -405,14 +405,14 @@ func ParseCPUs(value string) (int64, error) {
|
||||||
// ParseLink parses and validates the specified string as a link format (name:alias)
|
// ParseLink parses and validates the specified string as a link format (name:alias)
|
||||||
func ParseLink(val string) (string, string, error) {
|
func ParseLink(val string) (string, string, error) {
|
||||||
if val == "" {
|
if val == "" {
|
||||||
return "", "", fmt.Errorf("empty string specified for links")
|
return "", "", errors.New("empty string specified for links")
|
||||||
}
|
}
|
||||||
// We expect two parts, but restrict to three to allow detecting invalid formats.
|
// We expect two parts, but restrict to three to allow detecting invalid formats.
|
||||||
arr := strings.SplitN(val, ":", 3)
|
arr := strings.SplitN(val, ":", 3)
|
||||||
|
|
||||||
// TODO(thaJeztah): clean up this logic!!
|
// TODO(thaJeztah): clean up this logic!!
|
||||||
if len(arr) > 2 {
|
if len(arr) > 2 {
|
||||||
return "", "", fmt.Errorf("bad format for links: %s", val)
|
return "", "", errors.New("bad format for links: " + val)
|
||||||
}
|
}
|
||||||
// TODO(thaJeztah): this should trim the "/" prefix as well??
|
// TODO(thaJeztah): this should trim the "/" prefix as well??
|
||||||
if len(arr) == 1 {
|
if len(arr) == 1 {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package opts
|
package opts
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"errors"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -81,7 +81,7 @@ func ParseRestartPolicy(policy string) (container.RestartPolicy, error) {
|
||||||
if v != "" {
|
if v != "" {
|
||||||
count, err := strconv.Atoi(v)
|
count, err := strconv.Atoi(v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return p, fmt.Errorf("invalid restart policy format: maximum retry count must be an integer")
|
return p, errors.New("invalid restart policy format: maximum retry count must be an integer")
|
||||||
}
|
}
|
||||||
p.MaximumRetryCount = count
|
p.MaximumRetryCount = count
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package opts
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/csv"
|
"encoding/csv"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
@ -102,7 +103,7 @@ func (p *PortOpt) Set(value string) error {
|
||||||
for _, portBindings := range portBindingMap {
|
for _, portBindings := range portBindingMap {
|
||||||
for _, portBinding := range portBindings {
|
for _, portBinding := range portBindings {
|
||||||
if portBinding.HostIP != "" {
|
if portBinding.HostIP != "" {
|
||||||
return fmt.Errorf("hostip is not supported")
|
return errors.New("hostip is not supported")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package opts
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/csv"
|
"encoding/csv"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
@ -62,12 +63,12 @@ func (o *SecretOpt) Set(value string) error {
|
||||||
|
|
||||||
options.File.Mode = os.FileMode(m)
|
options.File.Mode = os.FileMode(m)
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("invalid field in secret request: %s", key)
|
return errors.New("invalid field in secret request: " + key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if options.SecretName == "" {
|
if options.SecretName == "" {
|
||||||
return fmt.Errorf("source is required")
|
return errors.New("source is required")
|
||||||
}
|
}
|
||||||
if options.File.Name == "" {
|
if options.File.Name == "" {
|
||||||
options.File.Name = options.SecretName
|
options.File.Name = options.SecretName
|
||||||
|
|
|
@ -5,6 +5,12 @@
|
||||||
|
|
||||||
set -eu -o pipefail
|
set -eu -o pipefail
|
||||||
|
|
||||||
|
# Disable CGO - we don't need it for these plugins.
|
||||||
|
#
|
||||||
|
# Important: this must be done before sourcing "./scripts/build/.variables",
|
||||||
|
# because some other variables are conditionally set whether CGO is enabled.
|
||||||
|
export CGO_ENABLED=0
|
||||||
|
|
||||||
source ./scripts/build/.variables
|
source ./scripts/build/.variables
|
||||||
|
|
||||||
for p in cli-plugins/examples/* "$@" ; do
|
for p in cli-plugins/examples/* "$@" ; do
|
||||||
|
@ -15,5 +21,5 @@ for p in cli-plugins/examples/* "$@" ; do
|
||||||
mkdir -p "$(dirname "${TARGET_PLUGIN}")"
|
mkdir -p "$(dirname "${TARGET_PLUGIN}")"
|
||||||
|
|
||||||
echo "Building $GO_LINKMODE $(basename "${TARGET_PLUGIN}")"
|
echo "Building $GO_LINKMODE $(basename "${TARGET_PLUGIN}")"
|
||||||
(set -x ; CGO_ENABLED=0 GO111MODULE=auto go build -o "${TARGET_PLUGIN}" -tags "${GO_BUILDTAGS}" -ldflags "${GO_LDFLAGS}" ${GO_BUILDMODE} "github.com/docker/cli/${p}")
|
(set -x ; GO111MODULE=auto go build -o "${TARGET_PLUGIN}" -tags "${GO_BUILDTAGS}" -ldflags "${GO_LDFLAGS}" ${GO_BUILDMODE} "github.com/docker/cli/${p}")
|
||||||
done
|
done
|
||||||
|
|
Loading…
Reference in New Issue