mirror of https://github.com/docker/cli.git
Compare commits
23 Commits
876e879809
...
dcfb8df16f
Author | SHA1 | Date |
---|---|---|
Laura Brehm | dcfb8df16f | |
Sebastiaan van Stijn | 9861ce90fd | |
Sebastiaan van Stijn | d1d5353269 | |
Sebastiaan van Stijn | 4adbb18f1c | |
Sebastiaan van Stijn | e00ed82399 | |
Sebastiaan van Stijn | 3dd7621240 | |
Sebastiaan van Stijn | 4242cda826 | |
Harald Albers | 06260e68f3 | |
Harald Albers | 4525fe37b4 | |
Harald Albers | db0ed1e216 | |
Harald Albers | 2915749279 | |
Harald Albers | 3a2503fa43 | |
Harald Albers | 9a9ae231a9 | |
Harald Albers | 5f7c43e5e6 | |
Harald Albers | 3292afe6e6 | |
Harald Albers | 5d709a8d9f | |
Harald Albers | 2d89339b34 | |
Harald Albers | ac7bde6f64 | |
Harald Albers | e513454244 | |
Harald Albers | c555327f0b | |
Harald Albers | b598ec8cdb | |
Harald Albers | 761d76750c | |
Laura Brehm | 508337b62e |
|
@ -8,8 +8,8 @@ ARG GO_VERSION=1.23.3
|
|||
ARG XX_VERSION=1.5.0
|
||||
ARG GOVERSIONINFO_VERSION=v1.3.0
|
||||
ARG GOTESTSUM_VERSION=v1.10.0
|
||||
ARG BUILDX_VERSION=0.17.1
|
||||
ARG COMPOSE_VERSION=v2.29.7
|
||||
ARG BUILDX_VERSION=0.18.0
|
||||
ARG COMPOSE_VERSION=v2.30.3
|
||||
|
||||
FROM --platform=$BUILDPLATFORM tonistiigi/xx:${XX_VERSION} AS xx
|
||||
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
package manager
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"gotest.tools/v3/assert"
|
||||
"gotest.tools/v3/assert/cmp"
|
||||
)
|
||||
|
||||
type fakeCandidate struct {
|
||||
|
@ -80,7 +79,8 @@ func TestValidateCandidate(t *testing.T) {
|
|||
assert.ErrorContains(t, err, tc.err)
|
||||
case tc.invalid != "":
|
||||
assert.NilError(t, err)
|
||||
assert.Assert(t, cmp.ErrorType(p.Err, reflect.TypeOf(&pluginError{})))
|
||||
var expectedError *pluginError
|
||||
assert.Check(t, errors.As(p.Err, &expectedError))
|
||||
assert.ErrorContains(t, p.Err, tc.invalid)
|
||||
default:
|
||||
assert.NilError(t, err)
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
|
||||
//go:build go1.22
|
||||
// +build go1.22
|
||||
|
||||
package container
|
||||
|
||||
import (
|
||||
|
@ -44,6 +48,65 @@ var allLinuxCapabilities = sync.OnceValue(func() []string {
|
|||
return out
|
||||
})
|
||||
|
||||
// logDriverOptions provides the options for each built-in logging driver.
|
||||
var logDriverOptions = map[string][]string{
|
||||
"awslogs": {
|
||||
"max-buffer-size", "mode", "awslogs-create-group", "awslogs-credentials-endpoint", "awslogs-datetime-format",
|
||||
"awslogs-group", "awslogs-multiline-pattern", "awslogs-region", "awslogs-stream", "tag",
|
||||
},
|
||||
"fluentd": {
|
||||
"max-buffer-size", "mode", "env", "env-regex", "labels", "fluentd-address", "fluentd-async",
|
||||
"fluentd-buffer-limit", "fluentd-request-ack", "fluentd-retry-wait", "fluentd-max-retries",
|
||||
"fluentd-sub-second-precision", "tag",
|
||||
},
|
||||
"gcplogs": {
|
||||
"max-buffer-size", "mode", "env", "env-regex", "labels", "gcp-log-cmd", "gcp-meta-id", "gcp-meta-name",
|
||||
"gcp-meta-zone", "gcp-project",
|
||||
},
|
||||
"gelf": {
|
||||
"max-buffer-size", "mode", "env", "env-regex", "labels", "gelf-address", "gelf-compression-level",
|
||||
"gelf-compression-type", "gelf-tcp-max-reconnect", "gelf-tcp-reconnect-delay", "tag",
|
||||
},
|
||||
"journald": {"max-buffer-size", "mode", "env", "env-regex", "labels", "tag"},
|
||||
"json-file": {"max-buffer-size", "mode", "env", "env-regex", "labels", "compress", "max-file", "max-size"},
|
||||
"local": {"max-buffer-size", "mode", "compress", "max-file", "max-size"},
|
||||
"none": {},
|
||||
"splunk": {
|
||||
"max-buffer-size", "mode", "env", "env-regex", "labels", "splunk-caname", "splunk-capath", "splunk-format",
|
||||
"splunk-gzip", "splunk-gzip-level", "splunk-index", "splunk-insecureskipverify", "splunk-source",
|
||||
"splunk-sourcetype", "splunk-token", "splunk-url", "splunk-verify-connection", "tag",
|
||||
},
|
||||
"syslog": {
|
||||
"max-buffer-size", "mode", "env", "env-regex", "labels", "syslog-address", "syslog-facility", "syslog-format",
|
||||
"syslog-tls-ca-cert", "syslog-tls-cert", "syslog-tls-key", "syslog-tls-skip-verify", "tag",
|
||||
},
|
||||
}
|
||||
|
||||
// builtInLogDrivers provides a list of the built-in logging drivers.
|
||||
var builtInLogDrivers = sync.OnceValue(func() []string {
|
||||
drivers := make([]string, 0, len(logDriverOptions))
|
||||
for driver := range logDriverOptions {
|
||||
drivers = append(drivers, driver)
|
||||
}
|
||||
return drivers
|
||||
})
|
||||
|
||||
// allLogDriverOptions provides all options of the built-in logging drivers.
|
||||
// The list does not contain duplicates.
|
||||
var allLogDriverOptions = sync.OnceValue(func() []string {
|
||||
var result []string
|
||||
seen := make(map[string]bool)
|
||||
for driver := range logDriverOptions {
|
||||
for _, opt := range logDriverOptions[driver] {
|
||||
if !seen[opt] {
|
||||
seen[opt] = true
|
||||
result = append(result, opt)
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
})
|
||||
|
||||
// restartPolicies is a list of all valid restart-policies..
|
||||
//
|
||||
// TODO(thaJeztah): add descriptions, and enable descriptions for our completion scripts (cobra.CompletionOptions.DisableDescriptions is currently set to "true")
|
||||
|
@ -54,6 +117,207 @@ var restartPolicies = []string{
|
|||
string(container.RestartPolicyUnlessStopped),
|
||||
}
|
||||
|
||||
// addCompletions adds the completions that `run` and `create` have in common.
|
||||
func addCompletions(cmd *cobra.Command, dockerCLI completion.APIClientProvider) {
|
||||
_ = cmd.RegisterFlagCompletionFunc("attach", completion.FromList("stderr", "stdin", "stdout"))
|
||||
_ = cmd.RegisterFlagCompletionFunc("cap-add", completeLinuxCapabilityNames)
|
||||
_ = cmd.RegisterFlagCompletionFunc("cap-drop", completeLinuxCapabilityNames)
|
||||
_ = cmd.RegisterFlagCompletionFunc("cgroupns", completeCgroupns())
|
||||
_ = cmd.RegisterFlagCompletionFunc("env", completion.EnvVarNames)
|
||||
_ = cmd.RegisterFlagCompletionFunc("env-file", completion.FileNames)
|
||||
_ = cmd.RegisterFlagCompletionFunc("ipc", completeIpc(dockerCLI))
|
||||
_ = cmd.RegisterFlagCompletionFunc("link", completeLink(dockerCLI))
|
||||
_ = cmd.RegisterFlagCompletionFunc("log-driver", completeLogDriver(dockerCLI))
|
||||
_ = cmd.RegisterFlagCompletionFunc("log-opt", completeLogOpt)
|
||||
_ = cmd.RegisterFlagCompletionFunc("network", completion.NetworkNames(dockerCLI))
|
||||
_ = cmd.RegisterFlagCompletionFunc("pid", completePid(dockerCLI))
|
||||
_ = cmd.RegisterFlagCompletionFunc("platform", completion.Platforms)
|
||||
_ = cmd.RegisterFlagCompletionFunc("pull", completion.FromList(PullImageAlways, PullImageMissing, PullImageNever))
|
||||
_ = cmd.RegisterFlagCompletionFunc("restart", completeRestartPolicies)
|
||||
_ = cmd.RegisterFlagCompletionFunc("security-opt", completeSecurityOpt)
|
||||
_ = cmd.RegisterFlagCompletionFunc("stop-signal", completeSignals)
|
||||
_ = cmd.RegisterFlagCompletionFunc("storage-opt", completeStorageOpt)
|
||||
_ = cmd.RegisterFlagCompletionFunc("ulimit", completeUlimit)
|
||||
_ = cmd.RegisterFlagCompletionFunc("userns", completion.FromList("host"))
|
||||
_ = cmd.RegisterFlagCompletionFunc("uts", completion.FromList("host"))
|
||||
_ = cmd.RegisterFlagCompletionFunc("volume-driver", completeVolumeDriver(dockerCLI))
|
||||
_ = cmd.RegisterFlagCompletionFunc("volumes-from", completion.ContainerNames(dockerCLI, true))
|
||||
}
|
||||
|
||||
// completeCgroupns implements shell completion for the `--cgroupns` option of `run` and `create`.
|
||||
func completeCgroupns() completion.ValidArgsFn {
|
||||
return completion.FromList(string(container.CgroupnsModeHost), string(container.CgroupnsModePrivate))
|
||||
}
|
||||
|
||||
// completeDetachKeys implements shell completion for the `--detach-keys` option of `run` and `create`.
|
||||
func completeDetachKeys(_ *cobra.Command, _ []string, _ string) ([]string, cobra.ShellCompDirective) {
|
||||
return []string{"ctrl-"}, cobra.ShellCompDirectiveNoSpace
|
||||
}
|
||||
|
||||
// completeIpc implements shell completion for the `--ipc` option of `run` and `create`.
|
||||
// The completion is partly composite.
|
||||
func completeIpc(dockerCLI completion.APIClientProvider) func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||
return func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||
if len(toComplete) > 0 && strings.HasPrefix("container", toComplete) { //nolint:gocritic // not swapped, matches partly typed "container"
|
||||
return []string{"container:"}, cobra.ShellCompDirectiveNoSpace
|
||||
}
|
||||
if strings.HasPrefix(toComplete, "container:") {
|
||||
names, _ := completion.ContainerNames(dockerCLI, true)(cmd, args, toComplete)
|
||||
return prefixWith("container:", names), cobra.ShellCompDirectiveNoFileComp
|
||||
}
|
||||
return []string{
|
||||
string(container.IPCModeContainer + ":"),
|
||||
string(container.IPCModeHost),
|
||||
string(container.IPCModeNone),
|
||||
string(container.IPCModePrivate),
|
||||
string(container.IPCModeShareable),
|
||||
}, cobra.ShellCompDirectiveNoFileComp
|
||||
}
|
||||
}
|
||||
|
||||
// completeLink implements shell completion for the `--link` option of `run` and `create`.
|
||||
func completeLink(dockerCLI completion.APIClientProvider) func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||
return func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||
return postfixWith(":", containerNames(dockerCLI, cmd, args, toComplete)), cobra.ShellCompDirectiveNoSpace
|
||||
}
|
||||
}
|
||||
|
||||
// completeLogDriver implements shell completion for the `--log-driver` option of `run` and `create`.
|
||||
// The log drivers are collected from a call to the Info endpoint with a fallback to a hard-coded list
|
||||
// of the build-in log drivers.
|
||||
func completeLogDriver(dockerCLI completion.APIClientProvider) completion.ValidArgsFn {
|
||||
return func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||
info, err := dockerCLI.Client().Info(cmd.Context())
|
||||
if err != nil {
|
||||
return builtInLogDrivers(), cobra.ShellCompDirectiveNoFileComp
|
||||
}
|
||||
drivers := info.Plugins.Log
|
||||
return drivers, cobra.ShellCompDirectiveNoFileComp
|
||||
}
|
||||
}
|
||||
|
||||
// completeLogOpt implements shell completion for the `--log-opt` option of `run` and `create`.
|
||||
// If the user supplied a log-driver, only options for that driver are returned.
|
||||
func completeLogOpt(cmd *cobra.Command, _ []string, _ string) ([]string, cobra.ShellCompDirective) {
|
||||
driver, _ := cmd.Flags().GetString("log-driver")
|
||||
if options, exists := logDriverOptions[driver]; exists {
|
||||
return postfixWith("=", options), cobra.ShellCompDirectiveNoSpace | cobra.ShellCompDirectiveNoFileComp
|
||||
}
|
||||
return postfixWith("=", allLogDriverOptions()), cobra.ShellCompDirectiveNoSpace
|
||||
}
|
||||
|
||||
// completePid implements shell completion for the `--pid` option of `run` and `create`.
|
||||
func completePid(dockerCLI completion.APIClientProvider) func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||
return func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||
if len(toComplete) > 0 && strings.HasPrefix("container", toComplete) { //nolint:gocritic // not swapped, matches partly typed "container"
|
||||
return []string{"container:"}, cobra.ShellCompDirectiveNoSpace
|
||||
}
|
||||
if strings.HasPrefix(toComplete, "container:") {
|
||||
names, _ := completion.ContainerNames(dockerCLI, true)(cmd, args, toComplete)
|
||||
return prefixWith("container:", names), cobra.ShellCompDirectiveNoFileComp
|
||||
}
|
||||
return []string{"container:", "host"}, cobra.ShellCompDirectiveNoFileComp
|
||||
}
|
||||
}
|
||||
|
||||
// completeSecurityOpt implements shell completion for the `--security-opt` option of `run` and `create`.
|
||||
// The completion is partly composite.
|
||||
func completeSecurityOpt(_ *cobra.Command, _ []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||
if len(toComplete) > 0 && strings.HasPrefix("apparmor=", toComplete) { //nolint:gocritic // not swapped, matches partly typed "apparmor="
|
||||
return []string{"apparmor="}, cobra.ShellCompDirectiveNoSpace
|
||||
}
|
||||
if len(toComplete) > 0 && strings.HasPrefix("label", toComplete) { //nolint:gocritic // not swapped, matches partly typed "label"
|
||||
return []string{"label="}, cobra.ShellCompDirectiveNoSpace
|
||||
}
|
||||
if strings.HasPrefix(toComplete, "label=") {
|
||||
if strings.HasPrefix(toComplete, "label=d") {
|
||||
return []string{"label=disable"}, cobra.ShellCompDirectiveNoFileComp
|
||||
}
|
||||
labels := []string{"disable", "level:", "role:", "type:", "user:"}
|
||||
return prefixWith("label=", labels), cobra.ShellCompDirectiveNoSpace | cobra.ShellCompDirectiveNoFileComp
|
||||
}
|
||||
// length must be > 1 here so that completion of "s" falls through.
|
||||
if len(toComplete) > 1 && strings.HasPrefix("seccomp", toComplete) { //nolint:gocritic // not swapped, matches partly typed "seccomp"
|
||||
return []string{"seccomp="}, cobra.ShellCompDirectiveNoSpace
|
||||
}
|
||||
if strings.HasPrefix(toComplete, "seccomp=") {
|
||||
return []string{"seccomp=unconfined"}, cobra.ShellCompDirectiveNoFileComp
|
||||
}
|
||||
return []string{"apparmor=", "label=", "no-new-privileges", "seccomp=", "systempaths=unconfined"}, cobra.ShellCompDirectiveNoFileComp
|
||||
}
|
||||
|
||||
// completeStorageOpt implements shell completion for the `--storage-opt` option of `run` and `create`.
|
||||
func completeStorageOpt(_ *cobra.Command, _ []string, _ string) ([]string, cobra.ShellCompDirective) {
|
||||
return []string{"size="}, cobra.ShellCompDirectiveNoSpace
|
||||
}
|
||||
|
||||
// completeUlimit implements shell completion for the `--ulimit` option of `run` and `create`.
|
||||
func completeUlimit(_ *cobra.Command, _ []string, _ string) ([]string, cobra.ShellCompDirective) {
|
||||
limits := []string{
|
||||
"as",
|
||||
"chroot",
|
||||
"core",
|
||||
"cpu",
|
||||
"data",
|
||||
"fsize",
|
||||
"locks",
|
||||
"maxlogins",
|
||||
"maxsyslogins",
|
||||
"memlock",
|
||||
"msgqueue",
|
||||
"nice",
|
||||
"nofile",
|
||||
"nproc",
|
||||
"priority",
|
||||
"rss",
|
||||
"rtprio",
|
||||
"sigpending",
|
||||
"stack",
|
||||
}
|
||||
return postfixWith("=", limits), cobra.ShellCompDirectiveNoSpace
|
||||
}
|
||||
|
||||
// completeVolumeDriver contacts the API to get the built-in and installed volume drivers.
|
||||
func completeVolumeDriver(dockerCLI completion.APIClientProvider) completion.ValidArgsFn {
|
||||
return func(cmd *cobra.Command, _ []string, _ string) ([]string, cobra.ShellCompDirective) {
|
||||
info, err := dockerCLI.Client().Info(cmd.Context())
|
||||
if err != nil {
|
||||
// fallback: the built-in drivers
|
||||
return []string{"local"}, cobra.ShellCompDirectiveNoFileComp
|
||||
}
|
||||
drivers := info.Plugins.Volume
|
||||
return drivers, cobra.ShellCompDirectiveNoFileComp
|
||||
}
|
||||
}
|
||||
|
||||
// containerNames contacts the API to get names and optionally IDs of containers.
|
||||
// In case of an error, an empty list is returned.
|
||||
func containerNames(dockerCLI completion.APIClientProvider, cmd *cobra.Command, args []string, toComplete string) []string {
|
||||
names, _ := completion.ContainerNames(dockerCLI, true)(cmd, args, toComplete)
|
||||
if names == nil {
|
||||
return []string{}
|
||||
}
|
||||
return names
|
||||
}
|
||||
|
||||
// prefixWith prefixes every element in the slice with the given prefix.
|
||||
func prefixWith(prefix string, values []string) []string {
|
||||
result := make([]string, len(values))
|
||||
for i, v := range values {
|
||||
result[i] = prefix + v
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// postfixWith appends postfix to every element in the slice.
|
||||
func postfixWith(postfix string, values []string) []string {
|
||||
result := make([]string, len(values))
|
||||
for i, v := range values {
|
||||
result[i] = v + postfix
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func completeLinuxCapabilityNames(cmd *cobra.Command, args []string, toComplete string) (names []string, _ cobra.ShellCompDirective) {
|
||||
return completion.FromList(allLinuxCapabilities()...)(cmd, args, toComplete)
|
||||
}
|
||||
|
|
|
@ -4,6 +4,9 @@ import (
|
|||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/cli/internal/test"
|
||||
"github.com/docker/cli/internal/test/builders"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/moby/sys/signal"
|
||||
"github.com/spf13/cobra"
|
||||
"gotest.tools/v3/assert"
|
||||
|
@ -21,6 +24,48 @@ func TestCompleteLinuxCapabilityNames(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestCompletePid(t *testing.T) {
|
||||
tests := []struct {
|
||||
containerListFunc func(container.ListOptions) ([]container.Summary, error)
|
||||
toComplete string
|
||||
expectedCompletions []string
|
||||
expectedDirective cobra.ShellCompDirective
|
||||
}{
|
||||
{
|
||||
toComplete: "",
|
||||
expectedCompletions: []string{"container:", "host"},
|
||||
expectedDirective: cobra.ShellCompDirectiveNoFileComp,
|
||||
},
|
||||
{
|
||||
toComplete: "c",
|
||||
expectedCompletions: []string{"container:"},
|
||||
expectedDirective: cobra.ShellCompDirectiveNoSpace,
|
||||
},
|
||||
{
|
||||
containerListFunc: func(container.ListOptions) ([]container.Summary, error) {
|
||||
return []container.Summary{
|
||||
*builders.Container("c1"),
|
||||
*builders.Container("c2"),
|
||||
}, nil
|
||||
},
|
||||
toComplete: "container:",
|
||||
expectedCompletions: []string{"container:c1", "container:c2"},
|
||||
expectedDirective: cobra.ShellCompDirectiveNoFileComp,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.toComplete, func(t *testing.T) {
|
||||
cli := test.NewFakeCli(&fakeClient{
|
||||
containerListFunc: tc.containerListFunc,
|
||||
})
|
||||
completions, directive := completePid(cli)(NewRunCommand(cli), nil, tc.toComplete)
|
||||
assert.Check(t, is.DeepEqual(completions, tc.expectedCompletions))
|
||||
assert.Check(t, is.Equal(directive, tc.expectedDirective))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestCompleteRestartPolicies(t *testing.T) {
|
||||
values, directives := completeRestartPolicies(nil, nil, "")
|
||||
assert.Check(t, is.Equal(directives&cobra.ShellCompDirectiveNoFileComp, cobra.ShellCompDirectiveNoFileComp), "Should not perform file completion")
|
||||
|
@ -28,6 +73,59 @@ func TestCompleteRestartPolicies(t *testing.T) {
|
|||
assert.Check(t, is.DeepEqual(values, expected))
|
||||
}
|
||||
|
||||
func TestCompleteSecurityOpt(t *testing.T) {
|
||||
tests := []struct {
|
||||
toComplete string
|
||||
expectedCompletions []string
|
||||
expectedDirective cobra.ShellCompDirective
|
||||
}{
|
||||
{
|
||||
toComplete: "",
|
||||
expectedCompletions: []string{"apparmor=", "label=", "no-new-privileges", "seccomp=", "systempaths=unconfined"},
|
||||
expectedDirective: cobra.ShellCompDirectiveNoFileComp,
|
||||
},
|
||||
{
|
||||
toComplete: "apparmor=",
|
||||
expectedCompletions: []string{"apparmor="},
|
||||
expectedDirective: cobra.ShellCompDirectiveNoSpace,
|
||||
},
|
||||
{
|
||||
toComplete: "label=",
|
||||
expectedCompletions: []string{"label=disable", "label=level:", "label=role:", "label=type:", "label=user:"},
|
||||
expectedDirective: cobra.ShellCompDirectiveNoSpace | cobra.ShellCompDirectiveNoFileComp,
|
||||
},
|
||||
{
|
||||
toComplete: "s",
|
||||
// We do not filter matching completions but delegate this task to the shell script.
|
||||
expectedCompletions: []string{"apparmor=", "label=", "no-new-privileges", "seccomp=", "systempaths=unconfined"},
|
||||
expectedDirective: cobra.ShellCompDirectiveNoFileComp,
|
||||
},
|
||||
{
|
||||
toComplete: "se",
|
||||
expectedCompletions: []string{"seccomp="},
|
||||
expectedDirective: cobra.ShellCompDirectiveNoSpace,
|
||||
},
|
||||
{
|
||||
toComplete: "seccomp=",
|
||||
expectedCompletions: []string{"seccomp=unconfined"},
|
||||
expectedDirective: cobra.ShellCompDirectiveNoFileComp,
|
||||
},
|
||||
{
|
||||
toComplete: "sy",
|
||||
expectedCompletions: []string{"apparmor=", "label=", "no-new-privileges", "seccomp=", "systempaths=unconfined"},
|
||||
expectedDirective: cobra.ShellCompDirectiveNoFileComp,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.toComplete, func(t *testing.T) {
|
||||
completions, directive := completeSecurityOpt(nil, nil, tc.toComplete)
|
||||
assert.Check(t, is.DeepEqual(completions, tc.expectedCompletions))
|
||||
assert.Check(t, is.Equal(directive, tc.expectedDirective))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestCompleteSignals(t *testing.T) {
|
||||
values, directives := completeSignals(nil, nil, "")
|
||||
assert.Check(t, is.Equal(directives&cobra.ShellCompDirectiveNoFileComp, cobra.ShellCompDirectiveNoFileComp), "Should not perform file completion")
|
||||
|
|
|
@ -78,16 +78,15 @@ func NewCreateCommand(dockerCli command.Cli) *cobra.Command {
|
|||
command.AddTrustVerificationFlags(flags, &options.untrusted, dockerCli.ContentTrustEnabled())
|
||||
copts = addFlags(flags)
|
||||
|
||||
_ = cmd.RegisterFlagCompletionFunc("cap-add", completeLinuxCapabilityNames)
|
||||
_ = cmd.RegisterFlagCompletionFunc("cap-drop", completeLinuxCapabilityNames)
|
||||
_ = cmd.RegisterFlagCompletionFunc("env", completion.EnvVarNames)
|
||||
_ = cmd.RegisterFlagCompletionFunc("env-file", completion.FileNames)
|
||||
_ = cmd.RegisterFlagCompletionFunc("network", completion.NetworkNames(dockerCli))
|
||||
_ = cmd.RegisterFlagCompletionFunc("platform", completion.Platforms)
|
||||
_ = cmd.RegisterFlagCompletionFunc("pull", completion.FromList(PullImageAlways, PullImageMissing, PullImageNever))
|
||||
_ = cmd.RegisterFlagCompletionFunc("restart", completeRestartPolicies)
|
||||
_ = cmd.RegisterFlagCompletionFunc("stop-signal", completeSignals)
|
||||
_ = cmd.RegisterFlagCompletionFunc("volumes-from", completion.ContainerNames(dockerCli, true))
|
||||
addCompletions(cmd, dockerCli)
|
||||
|
||||
flags.VisitAll(func(flag *pflag.Flag) {
|
||||
// Set a default completion function if none was set. We don't look
|
||||
// up if it does already have one set, because Cobra does this for
|
||||
// us, and returns an error (which we ignore for this reason).
|
||||
_ = cmd.RegisterFlagCompletionFunc(flag.Name, completion.NoComplete)
|
||||
})
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
|
|
|
@ -69,16 +69,16 @@ func NewRunCommand(dockerCli command.Cli) *cobra.Command {
|
|||
command.AddTrustVerificationFlags(flags, &options.untrusted, dockerCli.ContentTrustEnabled())
|
||||
copts = addFlags(flags)
|
||||
|
||||
_ = cmd.RegisterFlagCompletionFunc("cap-add", completeLinuxCapabilityNames)
|
||||
_ = cmd.RegisterFlagCompletionFunc("cap-drop", completeLinuxCapabilityNames)
|
||||
_ = cmd.RegisterFlagCompletionFunc("env", completion.EnvVarNames)
|
||||
_ = cmd.RegisterFlagCompletionFunc("env-file", completion.FileNames)
|
||||
_ = cmd.RegisterFlagCompletionFunc("network", completion.NetworkNames(dockerCli))
|
||||
_ = cmd.RegisterFlagCompletionFunc("platform", completion.Platforms)
|
||||
_ = cmd.RegisterFlagCompletionFunc("pull", completion.FromList(PullImageAlways, PullImageMissing, PullImageNever))
|
||||
_ = cmd.RegisterFlagCompletionFunc("restart", completeRestartPolicies)
|
||||
_ = cmd.RegisterFlagCompletionFunc("stop-signal", completeSignals)
|
||||
_ = cmd.RegisterFlagCompletionFunc("volumes-from", completion.ContainerNames(dockerCli, true))
|
||||
_ = cmd.RegisterFlagCompletionFunc("detach-keys", completeDetachKeys)
|
||||
addCompletions(cmd, dockerCli)
|
||||
|
||||
flags.VisitAll(func(flag *pflag.Flag) {
|
||||
// Set a default completion function if none was set. We don't look
|
||||
// up if it does already have one set, because Cobra does this for
|
||||
// us, and returns an error (which we ignore for this reason).
|
||||
_ = cmd.RegisterFlagCompletionFunc(flag.Name, completion.NoComplete)
|
||||
})
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@ import (
|
|||
"github.com/docker/cli/cli/config/configfile"
|
||||
"github.com/docker/docker/errdefs"
|
||||
"gotest.tools/v3/assert"
|
||||
is "gotest.tools/v3/assert/cmp"
|
||||
)
|
||||
|
||||
func TestRemove(t *testing.T) {
|
||||
|
@ -18,7 +17,7 @@ func TestRemove(t *testing.T) {
|
|||
_, err := cli.ContextStore().GetMetadata("current")
|
||||
assert.NilError(t, err)
|
||||
_, err = cli.ContextStore().GetMetadata("other")
|
||||
assert.Check(t, is.ErrorType(err, errdefs.IsNotFound))
|
||||
assert.Check(t, errdefs.IsNotFound(err))
|
||||
}
|
||||
|
||||
func TestRemoveNotAContext(t *testing.T) {
|
||||
|
|
|
@ -47,7 +47,7 @@ func TestUse(t *testing.T) {
|
|||
func TestUseNoExist(t *testing.T) {
|
||||
cli := makeFakeCli(t)
|
||||
err := newUseCommand(cli).RunE(nil, []string{"test"})
|
||||
assert.Check(t, is.ErrorType(err, errdefs.IsNotFound))
|
||||
assert.Check(t, errdefs.IsNotFound(err))
|
||||
}
|
||||
|
||||
// TestUseDefaultWithoutConfigFile verifies that the CLI does not create
|
||||
|
|
|
@ -14,7 +14,6 @@ import (
|
|||
"github.com/docker/docker/errdefs"
|
||||
"github.com/docker/go-connections/tlsconfig"
|
||||
"gotest.tools/v3/assert"
|
||||
is "gotest.tools/v3/assert/cmp"
|
||||
"gotest.tools/v3/golden"
|
||||
)
|
||||
|
||||
|
@ -158,7 +157,7 @@ func TestErrCreateDefault(t *testing.T) {
|
|||
Metadata: testContext{Bar: "baz"},
|
||||
Name: "default",
|
||||
})
|
||||
assert.Check(t, is.ErrorType(err, errdefs.IsInvalidParameter))
|
||||
assert.Check(t, errdefs.IsInvalidParameter(err))
|
||||
assert.Error(t, err, "default context cannot be created nor updated")
|
||||
}
|
||||
|
||||
|
@ -166,7 +165,7 @@ func TestErrRemoveDefault(t *testing.T) {
|
|||
meta := testDefaultMetadata()
|
||||
s := testStore(t, meta, store.ContextTLSData{})
|
||||
err := s.Remove("default")
|
||||
assert.Check(t, is.ErrorType(err, errdefs.IsInvalidParameter))
|
||||
assert.Check(t, errdefs.IsInvalidParameter(err))
|
||||
assert.Error(t, err, "default context cannot be removed")
|
||||
}
|
||||
|
||||
|
@ -174,5 +173,5 @@ func TestErrTLSDataError(t *testing.T) {
|
|||
meta := testDefaultMetadata()
|
||||
s := testStore(t, meta, store.ContextTLSData{})
|
||||
_, err := s.GetTLSData("default", "noop", "noop")
|
||||
assert.Check(t, is.ErrorType(err, errdefs.IsNotFound))
|
||||
assert.Check(t, errdefs.IsNotFound(err))
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ package loader
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"os"
|
||||
"runtime"
|
||||
"sort"
|
||||
|
@ -878,7 +879,8 @@ services:
|
|||
service: foo
|
||||
`)
|
||||
|
||||
assert.ErrorType(t, err, &ForbiddenPropertiesError{})
|
||||
var expectedErr *ForbiddenPropertiesError
|
||||
assert.Check(t, errors.As(err, &expectedErr))
|
||||
|
||||
props := err.(*ForbiddenPropertiesError).Properties
|
||||
assert.Check(t, is.Len(props, 2))
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
package template
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
|
@ -128,7 +129,8 @@ func TestMandatoryVariableErrors(t *testing.T) {
|
|||
for _, tc := range testCases {
|
||||
_, err := Substitute(tc.template, defaultMapping)
|
||||
assert.Check(t, is.ErrorContains(err, tc.expectedError))
|
||||
assert.Check(t, is.ErrorType(err, &InvalidTemplateError{}))
|
||||
var expectedError *InvalidTemplateError
|
||||
assert.Check(t, errors.As(err, &expectedError))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ func testMetadata(name string) Metadata {
|
|||
func TestMetadataGetNotExisting(t *testing.T) {
|
||||
testee := metadataStore{root: t.TempDir(), config: testCfg}
|
||||
_, err := testee.get("noexist")
|
||||
assert.ErrorType(t, err, errdefs.IsNotFound)
|
||||
assert.Check(t, errdefs.IsNotFound(err))
|
||||
}
|
||||
|
||||
func TestMetadataCreateGetRemove(t *testing.T) {
|
||||
|
@ -60,7 +60,7 @@ func TestMetadataCreateGetRemove(t *testing.T) {
|
|||
assert.NilError(t, testee.remove("test-context"))
|
||||
assert.NilError(t, testee.remove("test-context")) // support duplicate remove
|
||||
_, err = testee.get("test-context")
|
||||
assert.ErrorType(t, err, errdefs.IsNotFound)
|
||||
assert.Check(t, errdefs.IsNotFound(err))
|
||||
}
|
||||
|
||||
func TestMetadataRespectJsonAnnotation(t *testing.T) {
|
||||
|
|
|
@ -107,7 +107,7 @@ func TestRemove(t *testing.T) {
|
|||
}))
|
||||
assert.NilError(t, s.Remove("source"))
|
||||
_, err = s.GetMetadata("source")
|
||||
assert.Check(t, is.ErrorType(err, errdefs.IsNotFound))
|
||||
assert.Check(t, errdefs.IsNotFound(err))
|
||||
f, err := s.ListTLSFiles("source")
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, 0, len(f))
|
||||
|
@ -122,7 +122,7 @@ func TestListEmptyStore(t *testing.T) {
|
|||
func TestErrHasCorrectContext(t *testing.T) {
|
||||
_, err := New(t.TempDir(), testCfg).GetMetadata("no-exists")
|
||||
assert.ErrorContains(t, err, "no-exists")
|
||||
assert.Check(t, is.ErrorType(err, errdefs.IsNotFound))
|
||||
assert.Check(t, errdefs.IsNotFound(err))
|
||||
}
|
||||
|
||||
func TestDetectImportContentType(t *testing.T) {
|
||||
|
|
|
@ -13,7 +13,7 @@ func TestTlsCreateUpdateGetRemove(t *testing.T) {
|
|||
const contextName = "test-ctx"
|
||||
|
||||
_, err := testee.getData(contextName, "test-ep", "test-data")
|
||||
assert.ErrorType(t, err, errdefs.IsNotFound)
|
||||
assert.Check(t, errdefs.IsNotFound(err))
|
||||
|
||||
err = testee.createOrUpdate(contextName, "test-ep", "test-data", []byte("data"))
|
||||
assert.NilError(t, err)
|
||||
|
@ -29,7 +29,7 @@ func TestTlsCreateUpdateGetRemove(t *testing.T) {
|
|||
err = testee.removeEndpoint(contextName, "test-ep")
|
||||
assert.NilError(t, err)
|
||||
_, err = testee.getData(contextName, "test-ep", "test-data")
|
||||
assert.ErrorType(t, err, errdefs.IsNotFound)
|
||||
assert.Check(t, errdefs.IsNotFound(err))
|
||||
}
|
||||
|
||||
func TestTlsListAndBatchRemove(t *testing.T) {
|
||||
|
|
Loading…
Reference in New Issue