Compare commits
24 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 068a01ea94 | |||
| d75f8d83d3 | |||
| ffdfc5f94d | |||
| 6bd9908388 | |||
| 75595836f2 | |||
| 41277f53d5 | |||
| 4e7497e9cf | |||
| be669099cb | |||
| 111468ccd6 | |||
| 427c1361c5 | |||
| 656523e20d | |||
| aad2ae50e8 | |||
| 8a1b096e76 | |||
| c99d3312eb | |||
| 77a8a8c6ca | |||
| 0cff340983 | |||
| eb48cad302 | |||
| 2493a96027 | |||
| 8f55738579 | |||
| 768d10767f | |||
| d5e6e2ec6e | |||
| 7e71782ba6 | |||
| 762d59359e | |||
| 48dbdc6f2d |
9
.github/workflows/e2e.yml
vendored
9
.github/workflows/e2e.yml
vendored
@ -38,11 +38,10 @@ jobs:
|
||||
- alpine
|
||||
- debian
|
||||
engine-version:
|
||||
- 27.0 # latest
|
||||
- 26.1 # latest - 1
|
||||
- 23.0 # mirantis lts
|
||||
# TODO(krissetto) 19.03 needs a look, doesn't work ubuntu 22.04 (cgroup errors).
|
||||
# we could have a separate job that tests it against ubuntu 20.04
|
||||
- 28 # latest
|
||||
- 27 # latest - 1
|
||||
- 26 # github actions default
|
||||
- 23 # mirantis lts
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
|
||||
@ -59,42 +59,87 @@ func TestCreate(t *testing.T) {
|
||||
cli := makeFakeCli(t)
|
||||
assert.NilError(t, cli.ContextStore().CreateOrUpdate(store.Metadata{Name: "existing-context"}))
|
||||
tests := []struct {
|
||||
doc string
|
||||
options CreateOptions
|
||||
expecterErr string
|
||||
}{
|
||||
{
|
||||
doc: "empty name",
|
||||
expecterErr: `context name cannot be empty`,
|
||||
},
|
||||
{
|
||||
doc: "reserved name",
|
||||
options: CreateOptions{
|
||||
Name: "default",
|
||||
},
|
||||
expecterErr: `"default" is a reserved context name`,
|
||||
},
|
||||
{
|
||||
doc: "whitespace-only name",
|
||||
options: CreateOptions{
|
||||
Name: " ",
|
||||
},
|
||||
expecterErr: `context name " " is invalid`,
|
||||
},
|
||||
{
|
||||
doc: "existing context",
|
||||
options: CreateOptions{
|
||||
Name: "existing-context",
|
||||
},
|
||||
expecterErr: `context "existing-context" already exists`,
|
||||
},
|
||||
{
|
||||
doc: "invalid docker host",
|
||||
options: CreateOptions{
|
||||
Name: "invalid-docker-host",
|
||||
Docker: map[string]string{
|
||||
keyHost: "some///invalid/host",
|
||||
"host": "some///invalid/host",
|
||||
},
|
||||
},
|
||||
expecterErr: `unable to parse docker host`,
|
||||
},
|
||||
{
|
||||
doc: "ssh host with skip-tls-verify=false",
|
||||
options: CreateOptions{
|
||||
Name: "skip-tls-verify-false",
|
||||
Docker: map[string]string{
|
||||
"host": "ssh://example.com,skip-tls-verify=false",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
doc: "ssh host with skip-tls-verify=true",
|
||||
options: CreateOptions{
|
||||
Name: "skip-tls-verify-true",
|
||||
Docker: map[string]string{
|
||||
"host": "ssh://example.com,skip-tls-verify=true",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
doc: "ssh host with skip-tls-verify=INVALID",
|
||||
options: CreateOptions{
|
||||
Name: "skip-tls-verify-invalid",
|
||||
Docker: map[string]string{
|
||||
"host": "ssh://example.com",
|
||||
"skip-tls-verify": "INVALID",
|
||||
},
|
||||
},
|
||||
expecterErr: `unable to create docker endpoint config: skip-tls-verify: parsing "INVALID": invalid syntax`,
|
||||
},
|
||||
{
|
||||
doc: "unknown option",
|
||||
options: CreateOptions{
|
||||
Name: "unknown-option",
|
||||
Docker: map[string]string{
|
||||
"UNKNOWN": "value",
|
||||
},
|
||||
},
|
||||
expecterErr: `unable to create docker endpoint config: unrecognized config key: UNKNOWN`,
|
||||
},
|
||||
}
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.options.Name, func(t *testing.T) {
|
||||
t.Run(tc.doc, func(t *testing.T) {
|
||||
err := RunCreate(cli, &tc.options)
|
||||
if tc.expecterErr == "" {
|
||||
assert.NilError(t, err)
|
||||
|
||||
@ -68,7 +68,14 @@ func parseBool(config map[string]string, name string) (bool, error) {
|
||||
return false, nil
|
||||
}
|
||||
res, err := strconv.ParseBool(strVal)
|
||||
return res, fmt.Errorf("name: %w", err)
|
||||
if err != nil {
|
||||
var nErr *strconv.NumError
|
||||
if errors.As(err, &nErr) {
|
||||
return res, fmt.Errorf("%s: parsing %q: %w", name, nErr.Num, nErr.Err)
|
||||
}
|
||||
return res, fmt.Errorf("%s: %w", name, err)
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func validateConfig(config map[string]string, allowedKeys map[string]struct{}) error {
|
||||
|
||||
@ -3,6 +3,7 @@ package network
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/docker/cli/cli"
|
||||
"github.com/docker/cli/cli/command"
|
||||
@ -68,7 +69,7 @@ func runRemove(ctx context.Context, dockerCLI command.Cli, networks []string, op
|
||||
}
|
||||
|
||||
if status != 0 {
|
||||
return cli.StatusError{StatusCode: status}
|
||||
return cli.StatusError{StatusCode: status, Status: "exit status " + strconv.Itoa(status)}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
37
cli/command/node/completion.go
Normal file
37
cli/command/node/completion.go
Normal file
@ -0,0 +1,37 @@
|
||||
package node
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/docker/cli/cli/command/completion"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// completeNodeNames offers completion for swarm node (host)names and optional IDs.
|
||||
// By default, only names are returned.
|
||||
// Set DOCKER_COMPLETION_SHOW_NODE_IDS=yes to also complete IDs.
|
||||
//
|
||||
// TODO(thaJeztah): add support for filters.
|
||||
func completeNodeNames(dockerCLI completion.APIClientProvider) completion.ValidArgsFn {
|
||||
// https://github.com/docker/cli/blob/f9ced58158d5e0b358052432244b483774a1983d/contrib/completion/bash/docker#L41-L43
|
||||
showIDs := os.Getenv("DOCKER_COMPLETION_SHOW_NODE_IDS") == "yes"
|
||||
return func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||
list, err := dockerCLI.Client().NodeList(cmd.Context(), types.NodeListOptions{})
|
||||
if err != nil {
|
||||
return nil, cobra.ShellCompDirectiveError
|
||||
}
|
||||
|
||||
names := make([]string, 0, len(list)+1)
|
||||
for _, node := range list {
|
||||
if showIDs {
|
||||
names = append(names, node.Description.Hostname, node.ID)
|
||||
} else {
|
||||
names = append(names, node.Description.Hostname)
|
||||
}
|
||||
}
|
||||
// Nodes allow "self" as magic word for the current node.
|
||||
names = append(names, "self")
|
||||
return names, cobra.ShellCompDirectiveNoFileComp
|
||||
}
|
||||
}
|
||||
@ -18,6 +18,7 @@ func newDemoteCommand(dockerCli command.Cli) *cobra.Command {
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
return runDemote(cmd.Context(), dockerCli, args)
|
||||
},
|
||||
ValidArgsFunction: completeNodeNames(dockerCli),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -32,6 +32,7 @@ func newInspectCommand(dockerCli command.Cli) *cobra.Command {
|
||||
opts.nodeIds = args
|
||||
return runInspect(cmd.Context(), dockerCli, opts)
|
||||
},
|
||||
ValidArgsFunction: completeNodeNames(dockerCli),
|
||||
}
|
||||
|
||||
flags := cmd.Flags()
|
||||
|
||||
@ -14,6 +14,7 @@ import (
|
||||
"github.com/docker/docker/api/types/system"
|
||||
"github.com/fvbommel/sortorder"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
type listOptions struct {
|
||||
@ -40,6 +41,12 @@ func newListCommand(dockerCli command.Cli) *cobra.Command {
|
||||
flags.StringVar(&options.format, "format", "", flagsHelper.FormatHelp)
|
||||
flags.VarP(&options.filter, "filter", "f", "Filter output based on conditions provided")
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
@ -18,6 +18,7 @@ func newPromoteCommand(dockerCli command.Cli) *cobra.Command {
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
return runPromote(cmd.Context(), dockerCli, args)
|
||||
},
|
||||
ValidArgsFunction: completeNodeNames(dockerCli),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -14,6 +14,7 @@ import (
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
type psOptions struct {
|
||||
@ -41,7 +42,7 @@ func newPsCommand(dockerCli command.Cli) *cobra.Command {
|
||||
|
||||
return runPs(cmd.Context(), dockerCli, options)
|
||||
},
|
||||
ValidArgsFunction: completion.NoComplete,
|
||||
ValidArgsFunction: completeNodeNames(dockerCli),
|
||||
}
|
||||
flags := cmd.Flags()
|
||||
flags.BoolVar(&options.noTrunc, "no-trunc", false, "Do not truncate output")
|
||||
@ -50,6 +51,12 @@ func newPsCommand(dockerCli command.Cli) *cobra.Command {
|
||||
flags.StringVar(&options.format, "format", "", "Pretty-print tasks using a Go template")
|
||||
flags.BoolVarP(&options.quiet, "quiet", "q", false, "Only display task IDs")
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
@ -26,6 +26,7 @@ func newRemoveCommand(dockerCli command.Cli) *cobra.Command {
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
return runRemove(cmd.Context(), dockerCli, args, opts)
|
||||
},
|
||||
ValidArgsFunction: completeNodeNames(dockerCli),
|
||||
}
|
||||
flags := cmd.Flags()
|
||||
flags.BoolVarP(&opts.force, "force", "f", false, "Force remove a node from the swarm")
|
||||
|
||||
@ -6,6 +6,7 @@ import (
|
||||
|
||||
"github.com/docker/cli/cli"
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/docker/cli/cli/command/completion"
|
||||
"github.com/docker/cli/opts"
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
"github.com/pkg/errors"
|
||||
@ -25,6 +26,7 @@ func newUpdateCommand(dockerCli command.Cli) *cobra.Command {
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
return runUpdate(cmd.Context(), dockerCli, cmd.Flags(), args[0])
|
||||
},
|
||||
ValidArgsFunction: completeNodeNames(dockerCli),
|
||||
}
|
||||
|
||||
flags := cmd.Flags()
|
||||
@ -33,6 +35,15 @@ func newUpdateCommand(dockerCli command.Cli) *cobra.Command {
|
||||
flags.Var(&options.annotations.labels, flagLabelAdd, `Add or update a node label ("key=value")`)
|
||||
labelKeys := opts.NewListOpts(nil)
|
||||
flags.Var(&labelKeys, flagLabelRemove, "Remove a node label if exists")
|
||||
|
||||
_ = cmd.RegisterFlagCompletionFunc(flagRole, completion.FromList("worker", "manager"))
|
||||
_ = cmd.RegisterFlagCompletionFunc(flagAvailability, completion.FromList("active", "pause", "drain"))
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/docker/cli/cli"
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/docker/cli/cli/command/completion"
|
||||
@ -34,16 +36,25 @@ func NewServiceCommand(dockerCli command.Cli) *cobra.Command {
|
||||
return cmd
|
||||
}
|
||||
|
||||
// CompletionFn offers completion for swarm services
|
||||
// CompletionFn offers completion for swarm service names and optional IDs.
|
||||
// By default, only names are returned.
|
||||
// Set DOCKER_COMPLETION_SHOW_SERVICE_IDS=yes to also complete IDs.
|
||||
func CompletionFn(dockerCLI completion.APIClientProvider) completion.ValidArgsFn {
|
||||
// https://github.com/docker/cli/blob/f9ced58158d5e0b358052432244b483774a1983d/contrib/completion/bash/docker#L41-L43
|
||||
showIDs := os.Getenv("DOCKER_COMPLETION_SHOW_SERVICE_IDS") == "yes"
|
||||
return func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||
list, err := dockerCLI.Client().ServiceList(cmd.Context(), types.ServiceListOptions{})
|
||||
if err != nil {
|
||||
return nil, cobra.ShellCompDirectiveError
|
||||
}
|
||||
var names []string
|
||||
|
||||
names := make([]string, 0, len(list))
|
||||
for _, service := range list {
|
||||
names = append(names, service.ID)
|
||||
if showIDs {
|
||||
names = append(names, service.Spec.Name, service.ID)
|
||||
} else {
|
||||
names = append(names, service.Spec.Name)
|
||||
}
|
||||
}
|
||||
return names, cobra.ShellCompDirectiveNoFileComp
|
||||
}
|
||||
|
||||
@ -16,7 +16,7 @@ import (
|
||||
"github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
func newCreateCommand(dockerCli command.Cli) *cobra.Command {
|
||||
func newCreateCommand(dockerCLI command.Cli) *cobra.Command {
|
||||
opts := newServiceOptions()
|
||||
|
||||
cmd := &cobra.Command{
|
||||
@ -28,7 +28,7 @@ func newCreateCommand(dockerCli command.Cli) *cobra.Command {
|
||||
if len(args) > 1 {
|
||||
opts.args = args[1:]
|
||||
}
|
||||
return runCreate(cmd.Context(), dockerCli, cmd.Flags(), opts)
|
||||
return runCreate(cmd.Context(), dockerCLI, cmd.Flags(), opts)
|
||||
},
|
||||
ValidArgsFunction: completion.NoComplete,
|
||||
}
|
||||
@ -75,6 +75,28 @@ func newCreateCommand(dockerCli command.Cli) *cobra.Command {
|
||||
flags.SetAnnotation(flagHostAdd, "version", []string{"1.32"})
|
||||
|
||||
flags.SetInterspersed(false)
|
||||
|
||||
// TODO(thaJeztah): add completion for capabilities, stop-signal (currently non-exported in container package)
|
||||
// _ = cmd.RegisterFlagCompletionFunc(flagCapAdd, completeLinuxCapabilityNames)
|
||||
// _ = cmd.RegisterFlagCompletionFunc(flagCapDrop, completeLinuxCapabilityNames)
|
||||
// _ = cmd.RegisterFlagCompletionFunc(flagStopSignal, completeSignals)
|
||||
|
||||
_ = cmd.RegisterFlagCompletionFunc(flagMode, completion.FromList("replicated", "global", "replicated-job", "global-job"))
|
||||
_ = cmd.RegisterFlagCompletionFunc(flagEnv, completion.EnvVarNames) // TODO(thaJeztah): flagEnvRemove (needs to read current env-vars on the service)
|
||||
_ = cmd.RegisterFlagCompletionFunc(flagEnvFile, completion.FileNames)
|
||||
_ = cmd.RegisterFlagCompletionFunc(flagNetwork, completion.NetworkNames(dockerCLI))
|
||||
_ = cmd.RegisterFlagCompletionFunc(flagRestartCondition, completion.FromList("none", "on-failure", "any"))
|
||||
_ = cmd.RegisterFlagCompletionFunc(flagRollbackOrder, completion.FromList("start-first", "stop-first"))
|
||||
_ = cmd.RegisterFlagCompletionFunc(flagRollbackFailureAction, completion.FromList("pause", "continue"))
|
||||
_ = cmd.RegisterFlagCompletionFunc(flagUpdateOrder, completion.FromList("start-first", "stop-first"))
|
||||
_ = cmd.RegisterFlagCompletionFunc(flagUpdateFailureAction, completion.FromList("pause", "continue", "rollback"))
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
@ -9,6 +9,7 @@ import (
|
||||
|
||||
"github.com/docker/cli/cli"
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/docker/cli/cli/command/completion"
|
||||
"github.com/docker/cli/cli/command/formatter"
|
||||
flagsHelper "github.com/docker/cli/cli/flags"
|
||||
"github.com/docker/docker/api/types"
|
||||
@ -16,6 +17,7 @@ import (
|
||||
"github.com/docker/docker/errdefs"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
type inspectOptions struct {
|
||||
@ -47,6 +49,13 @@ func newInspectCommand(dockerCli command.Cli) *cobra.Command {
|
||||
flags := cmd.Flags()
|
||||
flags.StringVarP(&opts.format, "format", "f", "", flagsHelper.InspectFormatHelp)
|
||||
flags.BoolVar(&opts.pretty, "pretty", false, "Print the information in a human friendly format")
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
@ -14,6 +14,7 @@ import (
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
"github.com/docker/docker/client"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
type listOptions struct {
|
||||
@ -41,6 +42,12 @@ func newListCommand(dockerCLI command.Cli) *cobra.Command {
|
||||
flags.StringVar(&options.format, "format", "", flagsHelper.FormatHelp)
|
||||
flags.VarP(&options.filter, "filter", "f", "Filter output based on conditions provided")
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
@ -11,6 +11,7 @@ import (
|
||||
|
||||
"github.com/docker/cli/cli"
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/docker/cli/cli/command/completion"
|
||||
"github.com/docker/cli/cli/command/idresolver"
|
||||
"github.com/docker/cli/service/logs"
|
||||
"github.com/docker/docker/api/types"
|
||||
@ -22,6 +23,7 @@ import (
|
||||
"github.com/docker/docker/pkg/stringid"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
type logsOptions struct {
|
||||
@ -69,6 +71,13 @@ func newLogsCommand(dockerCli command.Cli) *cobra.Command {
|
||||
flags.BoolVar(&opts.details, "details", false, "Show extra details provided to logs")
|
||||
flags.SetAnnotation("details", "version", []string{"1.30"})
|
||||
flags.StringVarP(&opts.tail, "tail", "n", "all", "Number of lines to show from the end of the logs")
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
@ -6,6 +6,7 @@ import (
|
||||
|
||||
"github.com/docker/cli/cli"
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/docker/cli/cli/command/completion"
|
||||
"github.com/docker/cli/cli/command/idresolver"
|
||||
"github.com/docker/cli/cli/command/node"
|
||||
"github.com/docker/cli/cli/command/task"
|
||||
@ -15,6 +16,7 @@ import (
|
||||
"github.com/docker/docker/client"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
type psOptions struct {
|
||||
@ -48,6 +50,12 @@ func newPsCommand(dockerCli command.Cli) *cobra.Command {
|
||||
flags.StringVar(&options.format, "format", "", "Pretty-print tasks using a Go template")
|
||||
flags.VarP(&options.filter, "filter", "f", "Filter output based on conditions provided")
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
@ -6,9 +6,11 @@ import (
|
||||
|
||||
"github.com/docker/cli/cli"
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/docker/cli/cli/command/completion"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/versions"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
func newRollbackCommand(dockerCli command.Cli) *cobra.Command {
|
||||
@ -31,6 +33,12 @@ func newRollbackCommand(dockerCli command.Cli) *cobra.Command {
|
||||
flags.BoolVarP(&options.quiet, flagQuiet, "q", false, "Suppress progress output")
|
||||
addDetachFlag(flags, &options.detach)
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
@ -9,6 +9,7 @@ import (
|
||||
|
||||
"github.com/docker/cli/cli"
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/docker/cli/cli/command/completion"
|
||||
"github.com/docker/cli/opts"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
@ -23,7 +24,7 @@ import (
|
||||
"github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
func newUpdateCommand(dockerCli command.Cli) *cobra.Command {
|
||||
func newUpdateCommand(dockerCLI command.Cli) *cobra.Command {
|
||||
options := newServiceOptions()
|
||||
|
||||
cmd := &cobra.Command{
|
||||
@ -31,10 +32,10 @@ func newUpdateCommand(dockerCli command.Cli) *cobra.Command {
|
||||
Short: "Update a service",
|
||||
Args: cli.ExactArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
return runUpdate(cmd.Context(), dockerCli, cmd.Flags(), options, args[0])
|
||||
return runUpdate(cmd.Context(), dockerCLI, cmd.Flags(), options, args[0])
|
||||
},
|
||||
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||
return CompletionFn(dockerCli)(cmd, args, toComplete)
|
||||
return CompletionFn(dockerCLI)(cmd, args, toComplete)
|
||||
},
|
||||
}
|
||||
|
||||
@ -117,6 +118,30 @@ func newUpdateCommand(dockerCli command.Cli) *cobra.Command {
|
||||
flags.Var(newListOptsVarWithValidator(ValidateSingleGenericResource), flagGenericResourcesAdd, "Add a Generic resource")
|
||||
flags.SetAnnotation(flagHostAdd, "version", []string{"1.32"})
|
||||
|
||||
// TODO(thaJeztah): add completion for capabilities, stop-signal (currently non-exported in container package)
|
||||
// _ = cmd.RegisterFlagCompletionFunc(flagCapAdd, completeLinuxCapabilityNames)
|
||||
// _ = cmd.RegisterFlagCompletionFunc(flagCapDrop, completeLinuxCapabilityNames)
|
||||
// _ = cmd.RegisterFlagCompletionFunc(flagStopSignal, completeSignals)
|
||||
|
||||
_ = cmd.RegisterFlagCompletionFunc(flagEnvAdd, completion.EnvVarNames)
|
||||
// TODO(thaJeztah): flagEnvRemove (needs to read current env-vars on the service)
|
||||
_ = cmd.RegisterFlagCompletionFunc("image", completion.ImageNames(dockerCLI, -1))
|
||||
_ = cmd.RegisterFlagCompletionFunc(flagNetworkAdd, completion.NetworkNames(dockerCLI))
|
||||
// TODO(thaJeztha): flagNetworkRemove (needs to read current list of networks from the service)
|
||||
_ = cmd.RegisterFlagCompletionFunc(flagRestartCondition, completion.FromList("none", "on-failure", "any"))
|
||||
_ = cmd.RegisterFlagCompletionFunc(flagRollbackOrder, completion.FromList("start-first", "stop-first"))
|
||||
_ = cmd.RegisterFlagCompletionFunc(flagRollbackFailureAction, completion.FromList("pause", "continue"))
|
||||
_ = cmd.RegisterFlagCompletionFunc(flagUpdateOrder, completion.FromList("start-first", "stop-first"))
|
||||
_ = cmd.RegisterFlagCompletionFunc(flagUpdateFailureAction, completion.FromList("pause", "continue", "rollback"))
|
||||
|
||||
completion.ImageNames(dockerCLI, -1)
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
@ -1,9 +1,5 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// StatusError reports an unsuccessful exit by a command.
|
||||
type StatusError struct {
|
||||
Cause error
|
||||
@ -21,7 +17,9 @@ func (e StatusError) Error() string {
|
||||
if e.Cause != nil {
|
||||
return e.Cause.Error()
|
||||
}
|
||||
return "exit status " + strconv.Itoa(e.StatusCode)
|
||||
// we don't want to set a default message here,
|
||||
// some commands might want to be explicit about the error message
|
||||
return ""
|
||||
}
|
||||
|
||||
func (e StatusError) Unwrap() error {
|
||||
|
||||
@ -43,7 +43,9 @@ func main() {
|
||||
}
|
||||
|
||||
if err != nil && !errdefs.IsCancelled(err) {
|
||||
_, _ = fmt.Fprintln(os.Stderr, err)
|
||||
if err.Error() != "" {
|
||||
_, _ = fmt.Fprintln(os.Stderr, err)
|
||||
}
|
||||
os.Exit(getExitCode(err))
|
||||
}
|
||||
}
|
||||
|
||||
@ -50,7 +50,7 @@ RUN apk add --no-cache \
|
||||
RUN echo -e "\nYou are now in a development container. Run '\e\033[1mmake help\e\033[0m' to learn about\navailable make targets.\n" > /etc/motd \
|
||||
&& echo -e "cat /etc/motd\nPS1=\"\e[0;32m\u@docker-cli-dev\\$ \e[0m\"" >> /root/.bashrc \
|
||||
&& echo -e "source /etc/bash/bash_completion.sh" >> /root/.bashrc
|
||||
CMD bash
|
||||
CMD ["/bin/bash"]
|
||||
ENV DISABLE_WARN_OUTSIDE_CONTAINER=1
|
||||
ENV PATH=$PATH:/go/src/github.com/docker/cli/build
|
||||
|
||||
|
||||
@ -42,7 +42,7 @@ container, `SIGTERM` is used as default.
|
||||
### <a name="timeout"></a> Stop container with timeout (-t, --timeout)
|
||||
|
||||
The `--timeout` flag sets the number of seconds to wait for the container
|
||||
to stop after sending the pre-defined (see [`--signal`]{#signal)) system call signal.
|
||||
to stop after sending the pre-defined (see [`--signal`](#signal)) system call signal.
|
||||
If the container does not exit after the timeout elapses, it's forcibly killed
|
||||
with a `SIGKILL` signal.
|
||||
|
||||
|
||||
@ -1349,6 +1349,26 @@ $ docker run --ulimit nofile=1024:1024 --rm debian sh -c "ulimit -n"
|
||||
> $ docker run -it --ulimit as=1024 fedora /bin/bash
|
||||
> ```
|
||||
|
||||
#### Supported options for `--ulimit`:
|
||||
|
||||
| Option | Description |
|
||||
|:-------------|:----------------------------------------------------------|
|
||||
| `core` | Maximum size of core files created (`RLIMIT_CORE`) |
|
||||
| `cpu` | CPU time limit in seconds (`RLIMIT_CPU`) |
|
||||
| `data` | Maximum data segment size (`RLIMIT_DATA`) |
|
||||
| `fsize` | Maximum file size (`RLIMIT_FSIZE`) |
|
||||
| `locks` | Maximum number of file locks (`RLIMIT_LOCKS`) |
|
||||
| `memlock` | Maximum locked-in-memory address space (`RLIMIT_MEMLOCK`) |
|
||||
| `msgqueue` | Maximum bytes in POSIX message queues (`RLIMIT_MSGQUEUE`) |
|
||||
| `nice` | Maximum nice priority adjustment (`RLIMIT_NICE`) |
|
||||
| `nofile` | Maximum number of open file descriptors (`RLIMIT_NOFILE`) |
|
||||
| `nproc` | Maximum number of processes available (`RLIMIT_NPROC`) |
|
||||
| `rss` | Maximum resident set size (`RLIMIT_RSS`) |
|
||||
| `rtprio` | Maximum real-time scheduling priority (`RLIMIT_RTPRIO`) |
|
||||
| `rttime` | Maximum real-time execution time (`RLIMIT_RTTIME`) |
|
||||
| `sigpending` | Maximum number of pending signals (`RLIMIT_SIGPENDING`) |
|
||||
| `stack` | Maximum stack size (`RLIMIT_STACK`) |
|
||||
|
||||
Docker sends the values to the appropriate OS `syscall` and doesn't perform any byte conversion.
|
||||
Take this into account when setting the values.
|
||||
|
||||
|
||||
@ -13,7 +13,7 @@ List networks
|
||||
|:---------------------------------------|:---------|:--------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| [`-f`](#filter), [`--filter`](#filter) | `filter` | | Provide filter values (e.g. `driver=bridge`) |
|
||||
| [`--format`](#format) | `string` | | Format output using a custom template:<br>'table': Print output in table format with column headers (default)<br>'table TEMPLATE': Print output in table format using the given Go template<br>'json': Print in JSON format<br>'TEMPLATE': Print output using the given Go template.<br>Refer to https://docs.docker.com/go/formatting/ for more information about formatting output with templates |
|
||||
| `--no-trunc` | `bool` | | Do not truncate the output |
|
||||
| [`--no-trunc`](#no-trunc) | `bool` | | Do not truncate the output |
|
||||
| `-q`, `--quiet` | `bool` | | Only display network IDs |
|
||||
|
||||
|
||||
@ -37,6 +37,8 @@ cf03ee007fb4 host host local
|
||||
78b03ee04fc4 multi-host overlay swarm
|
||||
```
|
||||
|
||||
### <a name="no-trunc"></a> List networks without truncating the ID column (--no-trun)
|
||||
|
||||
Use the `--no-trunc` option to display the full network id:
|
||||
|
||||
```console
|
||||
|
||||
@ -5,10 +5,10 @@ Manage join tokens
|
||||
|
||||
### Options
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
|:----------------|:-------|:--------|:-------------------|
|
||||
| `-q`, `--quiet` | `bool` | | Only display token |
|
||||
| `--rotate` | `bool` | | Rotate join token |
|
||||
| Name | Type | Default | Description |
|
||||
|:------------------------------------|:-------|:--------|:-------------------|
|
||||
| [`-q`](#quiet), [`--quiet`](#quiet) | `bool` | | Only display token |
|
||||
| [`--rotate`](#rotate) | `bool` | | Rotate join token |
|
||||
|
||||
|
||||
<!---MARKER_GEN_END-->
|
||||
@ -77,7 +77,7 @@ $ docker swarm join-token -q worker
|
||||
SWMTKN-1-3pu6hszjas19xyp7ghgosyx9k8atbfcr8p2is99znpy26u2lkl-b30ljddcqhef9b9v4rs7mel7t
|
||||
```
|
||||
|
||||
### `--rotate`
|
||||
### <a name="rotate"></a> `--rotate`
|
||||
|
||||
Because tokens allow new nodes to join the swarm, you should keep them secret.
|
||||
Be particularly careful with manager tokens since they allow new manager nodes
|
||||
@ -96,7 +96,7 @@ Rotating a join-token means that no new nodes will be able to join the swarm
|
||||
using the old token. Rotation does not affect existing nodes in the swarm
|
||||
because the join token is only used for authorizing new nodes joining the swarm.
|
||||
|
||||
### `--quiet`
|
||||
### <a name="quiet"></a> `--quiet`
|
||||
|
||||
Only print the token. Do not print a complete command for joining.
|
||||
|
||||
|
||||
@ -5,13 +5,13 @@ Join a swarm as a node and/or manager
|
||||
|
||||
### Options
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
|:-------------------|:------------|:---------------|:------------------------------------------------------------------------------|
|
||||
| `--advertise-addr` | `string` | | Advertised address (format: `<ip\|interface>[:port]`) |
|
||||
| `--availability` | `string` | `active` | Availability of the node (`active`, `pause`, `drain`) |
|
||||
| `--data-path-addr` | `string` | | Address or interface to use for data path traffic (format: `<ip\|interface>`) |
|
||||
| `--listen-addr` | `node-addr` | `0.0.0.0:2377` | Listen address (format: `<ip\|interface>[:port]`) |
|
||||
| `--token` | `string` | | Token for entry into the swarm |
|
||||
| Name | Type | Default | Description |
|
||||
|:--------------------------------------|:------------|:---------------|:------------------------------------------------------------------------------|
|
||||
| [`--advertise-addr`](#advertise-addr) | `string` | | Advertised address (format: `<ip\|interface>[:port]`) |
|
||||
| [`--availability`](#availability) | `string` | `active` | Availability of the node (`active`, `pause`, `drain`) |
|
||||
| [`--data-path-addr`](#data-path-addr) | `string` | | Address or interface to use for data path traffic (format: `<ip\|interface>`) |
|
||||
| [`--listen-addr`](#listen-addr) | `node-addr` | `0.0.0.0:2377` | Listen address (format: `<ip\|interface>[:port]`) |
|
||||
| [`--token`](#token) | `string` | | Token for entry into the swarm |
|
||||
|
||||
|
||||
<!---MARKER_GEN_END-->
|
||||
@ -57,7 +57,7 @@ dkp8vy1dq1kxleu9g4u78tlag worker1 Ready Active Reachable
|
||||
dvfxp4zseq4s0rih1selh0d20 * manager1 Ready Active Leader
|
||||
```
|
||||
|
||||
### `--listen-addr value`
|
||||
### <a name="listen-addr"></a> `--listen-addr value`
|
||||
|
||||
If the node is a manager, it will listen for inbound swarm manager traffic on this
|
||||
address. The default is to listen on 0.0.0.0:2377. It is also possible to specify a
|
||||
@ -68,7 +68,7 @@ name, the default port 2377 will be used.
|
||||
|
||||
This flag is generally not necessary when joining an existing swarm.
|
||||
|
||||
### `--advertise-addr value`
|
||||
### <a name="advertise-addr"></a> `--advertise-addr value`
|
||||
|
||||
This flag specifies the address that will be advertised to other members of the
|
||||
swarm for API access. If unspecified, Docker will check if the system has a
|
||||
@ -88,7 +88,7 @@ you're joining new nodes through a load balancer, you should use this flag to
|
||||
ensure the node advertises its IP address and not the IP address of the load
|
||||
balancer.
|
||||
|
||||
### `--data-path-addr`
|
||||
### <a name="data-path-addr"></a> `--data-path-addr`
|
||||
|
||||
This flag specifies the address that global scope network drivers will publish towards
|
||||
other nodes in order to reach the containers running on this node.
|
||||
@ -97,11 +97,11 @@ management traffic of the cluster.
|
||||
If unspecified, Docker will use the same IP address or interface that is used for the
|
||||
advertise address.
|
||||
|
||||
### `--token string`
|
||||
### <a name="token"></a> `--token string`
|
||||
|
||||
Secret value required for nodes to join the swarm
|
||||
|
||||
### `--availability`
|
||||
### <a name="availability"></a> `--availability`
|
||||
|
||||
This flag specifies the availability of the node at the time the node joins a master.
|
||||
Possible availability values are `active`, `pause`, or `drain`.
|
||||
|
||||
@ -5,10 +5,10 @@ Manage the unlock key
|
||||
|
||||
### Options
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
|:----------------|:-------|:--------|:-------------------|
|
||||
| `-q`, `--quiet` | `bool` | | Only display token |
|
||||
| `--rotate` | `bool` | | Rotate unlock key |
|
||||
| Name | Type | Default | Description |
|
||||
|:------------------------------------|:-------|:--------|:-------------------|
|
||||
| [`-q`](#quiet), [`--quiet`](#quiet) | `bool` | | Only display token |
|
||||
| [`--rotate`](#rotate) | `bool` | | Rotate unlock key |
|
||||
|
||||
|
||||
<!---MARKER_GEN_END-->
|
||||
@ -67,12 +67,12 @@ $ docker swarm unlock-key -q
|
||||
SWMKEY-1-7c37Cc8654o6p38HnroywCi19pllOnGtbdZEgtKxZu8
|
||||
```
|
||||
|
||||
### `--rotate`
|
||||
### <a name="rotate"></a> `--rotate`
|
||||
|
||||
This flag rotates the unlock key, replacing it with a new randomly-generated
|
||||
key. The old unlock key will no longer be accepted.
|
||||
|
||||
### `--quiet`
|
||||
### <a name="quiet"></a> `--quiet`
|
||||
|
||||
Only print the unlock key, without instructions.
|
||||
|
||||
|
||||
@ -18,15 +18,15 @@ aliases:
|
||||
# daemon
|
||||
|
||||
```markdown
|
||||
Usage: dockerd [OPTIONS]
|
||||
Usage: dockerd [OPTIONS]
|
||||
|
||||
A self-sufficient runtime for containers.
|
||||
|
||||
Options:
|
||||
--add-runtime runtime Register an additional OCI compatible runtime (default [])
|
||||
--authorization-plugin list Authorization plugins to load
|
||||
--bip string Specify default-bridge IPv4 network
|
||||
--bip6 string Specify default-bridge IPv6 network
|
||||
--bip string IPv4 address for the default bridge
|
||||
--bip6 string IPv6 address for the default bridge
|
||||
-b, --bridge string Attach containers to a network bridge
|
||||
--cdi-spec-dir list CDI specification directories to use
|
||||
--cgroup-parent string Set parent cgroup for all containers
|
||||
@ -43,8 +43,8 @@ Options:
|
||||
-D, --debug Enable debug mode
|
||||
--default-address-pool pool-options Default address pools for node specific local networks
|
||||
--default-cgroupns-mode string Default mode for containers cgroup namespace ("host" | "private") (default "private")
|
||||
--default-gateway ip Container default gateway IPv4 address
|
||||
--default-gateway-v6 ip Container default gateway IPv6 address
|
||||
--default-gateway ip Default gateway IPv4 address for the default bridge network
|
||||
--default-gateway-v6 ip Default gateway IPv6 address for the default bridge network
|
||||
--default-ipc-mode string Default mode for containers ipc ("shareable" | "private") (default "private")
|
||||
--default-network-opt mapmap Default network options (default map[])
|
||||
--default-runtime string Default OCI runtime for containers (default "runc")
|
||||
@ -57,8 +57,8 @@ Options:
|
||||
--exec-root string Root directory for execution state files (default "/var/run/docker")
|
||||
--experimental Enable experimental features
|
||||
--feature map Enable feature in the daemon
|
||||
--fixed-cidr string IPv4 subnet for fixed IPs
|
||||
--fixed-cidr-v6 string IPv6 subnet for fixed IPs
|
||||
--fixed-cidr string IPv4 subnet for the default bridge network
|
||||
--fixed-cidr-v6 string IPv6 subnet for the default bridge network
|
||||
-G, --group string Group for the unix socket (default "docker")
|
||||
--help Print usage
|
||||
-H, --host list Daemon socket(s) to connect to
|
||||
@ -66,17 +66,17 @@ Options:
|
||||
Defaults to the IP addresses of the default bridge
|
||||
--http-proxy string HTTP proxy URL to use for outgoing traffic
|
||||
--https-proxy string HTTPS proxy URL to use for outgoing traffic
|
||||
--icc Enable inter-container communication (default true)
|
||||
--icc Enable inter-container communication for the default bridge network (default true)
|
||||
--init Run an init in the container to forward signals and reap processes
|
||||
--init-path string Path to the docker-init binary
|
||||
--insecure-registry list Enable insecure registry communication
|
||||
--ip ip Default IP when binding container ports (default 0.0.0.0)
|
||||
--ip ip Host IP for port publishing from the default bridge network (default 0.0.0.0)
|
||||
--ip-forward Enable IP forwarding in system configuration (default true)
|
||||
--ip-forward-no-drop Do not set the filter-FORWARD policy to DROP when enabling IP forwarding
|
||||
--ip-masq Enable IP masquerading (default true)
|
||||
--ip6tables Enable addition of ip6tables rules (experimental)
|
||||
--ip-masq Enable IP masquerading for the default bridge network (default true)
|
||||
--ip6tables Enable addition of ip6tables rules (default true)
|
||||
--iptables Enable addition of iptables rules (default true)
|
||||
--ipv6 Enable IPv6 networking
|
||||
--ipv6 Enable IPv6 networking for the default bridge network
|
||||
--label list Set key=value labels to the daemon
|
||||
--live-restore Enable live restore of docker when containers are still running
|
||||
--log-driver string Default driver for container logs (default "json-file")
|
||||
@ -87,7 +87,7 @@ Options:
|
||||
--max-concurrent-uploads int Set the max concurrent uploads (default 5)
|
||||
--max-download-attempts int Set the max download attempts for each pull (default 5)
|
||||
--metrics-addr string Set default address and port to serve the metrics api on
|
||||
--mtu int Set the containers network MTU (default 1500)
|
||||
--mtu int Set the MTU for the default "bridge" network (default 1500)
|
||||
--network-control-plane-mtu int Network Control plane MTU (default 1500)
|
||||
--no-new-privileges Set no-new-privileges by default for new containers
|
||||
--no-proxy string Comma-separated list of hosts or IP addresses for which the proxy is skipped
|
||||
@ -96,7 +96,7 @@ Options:
|
||||
--raw-logs Full timestamps without ANSI coloring
|
||||
--registry-mirror list Preferred registry mirror
|
||||
--rootless Enable rootless mode; typically used with RootlessKit
|
||||
--seccomp-profile string Path to seccomp profile. Use "unconfined" to disable the default seccomp profile (default "builtin")
|
||||
--seccomp-profile string Path to seccomp profile. Set to "unconfined" to disable the default seccomp profile (default "builtin")
|
||||
--selinux-enabled Enable selinux support
|
||||
--shutdown-timeout int Set the default shutdown timeout (default 15)
|
||||
-s, --storage-driver string Storage driver to use
|
||||
|
||||
@ -137,7 +137,6 @@ func TestPluginSocketBackwardsCompatible(t *testing.T) {
|
||||
assert.Assert(t, errors.As(err, &exitError))
|
||||
assert.Check(t, exitError.Exited())
|
||||
assert.Check(t, is.Equal(exitError.ExitCode(), 1))
|
||||
assert.Check(t, is.ErrorContains(err, "exit status 1"))
|
||||
|
||||
// the plugin process does not receive a SIGINT and does
|
||||
// the CLI cannot cancel it over the socket, so it kills
|
||||
@ -199,11 +198,10 @@ func TestPluginSocketCommunication(t *testing.T) {
|
||||
assert.Assert(t, errors.As(err, &exitError))
|
||||
assert.Check(t, exitError.Exited())
|
||||
assert.Check(t, is.Equal(exitError.ExitCode(), 2))
|
||||
assert.Check(t, is.ErrorContains(err, "exit status 2"))
|
||||
|
||||
// the plugin does not get signalled, but it does get its
|
||||
// context canceled by the CLI through the socket
|
||||
const expected = "test-socket: exiting after context was done\nexit status 2"
|
||||
const expected = "test-socket: exiting after context was done"
|
||||
actual := strings.TrimSpace(string(out))
|
||||
assert.Check(t, is.Equal(actual, expected))
|
||||
})
|
||||
@ -238,7 +236,6 @@ func TestPluginSocketCommunication(t *testing.T) {
|
||||
assert.Assert(t, errors.As(err, &exitError))
|
||||
assert.Check(t, exitError.Exited())
|
||||
assert.Check(t, is.Equal(exitError.ExitCode(), 1))
|
||||
assert.Check(t, is.ErrorContains(err, "exit status 1"))
|
||||
|
||||
// the plugin process does not receive a SIGINT and does
|
||||
// not exit after having it's context canceled, so the CLI
|
||||
|
||||
@ -4,7 +4,7 @@ services:
|
||||
image: 'registry:2'
|
||||
|
||||
engine:
|
||||
image: 'docker:${ENGINE_VERSION:-26.1}-dind'
|
||||
image: 'docker:${ENGINE_VERSION:-28}-dind'
|
||||
privileged: true
|
||||
command: ['--insecure-registry=registry:5000']
|
||||
environment:
|
||||
|
||||
@ -58,5 +58,4 @@ func TestAttachInterrupt(t *testing.T) {
|
||||
// the CLI should exit with 33 (the SIGINT was forwarded to the container), and the
|
||||
// CLI process waited for the container exit and properly captured/set the exit code
|
||||
assert.Equal(t, c.ProcessState.ExitCode(), 33)
|
||||
assert.Equal(t, d.String(), "exit status 33\n")
|
||||
}
|
||||
|
||||
@ -68,7 +68,6 @@ func TestRunAttach(t *testing.T) {
|
||||
}
|
||||
|
||||
assert.Equal(t, c.ProcessState.ExitCode(), 7)
|
||||
assert.Check(t, is.Contains(d.String(), "exit status 7"))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
2
e2e/testdata/Dockerfile.connhelper-ssh
vendored
2
e2e/testdata/Dockerfile.connhelper-ssh
vendored
@ -2,7 +2,7 @@
|
||||
|
||||
# ENGINE_VERSION is the version of the (docker-in-docker) Docker Engine to
|
||||
# test against.
|
||||
ARG ENGINE_VERSION=26.1
|
||||
ARG ENGINE_VERSION=28
|
||||
|
||||
FROM docker:${ENGINE_VERSION}-dind
|
||||
|
||||
|
||||
@ -18,7 +18,7 @@ require (
|
||||
github.com/docker/go-connections v0.5.0
|
||||
github.com/docker/go-units v0.5.0
|
||||
github.com/fvbommel/sortorder v1.1.0
|
||||
github.com/go-jose/go-jose/v4 v4.0.4
|
||||
github.com/go-jose/go-jose/v4 v4.0.5
|
||||
github.com/go-viper/mapstructure/v2 v2.2.1
|
||||
github.com/gogo/protobuf v1.3.2
|
||||
github.com/google/go-cmp v0.6.0
|
||||
@ -50,7 +50,7 @@ require (
|
||||
go.opentelemetry.io/otel/trace v1.31.0
|
||||
golang.org/x/sync v0.10.0
|
||||
golang.org/x/sys v0.29.0
|
||||
golang.org/x/term v0.27.0
|
||||
golang.org/x/term v0.28.0
|
||||
golang.org/x/text v0.21.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
gotest.tools/v3 v3.5.2
|
||||
@ -95,7 +95,7 @@ require (
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.31.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.31.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.3.1 // indirect
|
||||
golang.org/x/crypto v0.31.0 // indirect
|
||||
golang.org/x/crypto v0.32.0 // indirect
|
||||
golang.org/x/net v0.33.0 // indirect
|
||||
golang.org/x/time v0.6.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241021214115-324edc3d5d38 // indirect
|
||||
|
||||
16
vendor.sum
16
vendor.sum
@ -76,8 +76,8 @@ github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSw
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fvbommel/sortorder v1.1.0 h1:fUmoe+HLsBTctBDoaBwpQo5N+nrCp8g/BjKb/6ZQmYw=
|
||||
github.com/fvbommel/sortorder v1.1.0/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0=
|
||||
github.com/go-jose/go-jose/v4 v4.0.4 h1:VsjPI33J0SB9vQM6PLmNjoHqMQNGPiZ0rHL7Ni7Q6/E=
|
||||
github.com/go-jose/go-jose/v4 v4.0.4/go.mod h1:NKb5HO1EZccyMpiZNbdUw/14tiXNyUJh188dfnMCAfc=
|
||||
github.com/go-jose/go-jose/v4 v4.0.5 h1:M6T8+mKZl/+fNNuFHvGIzDz7BTLQPIounk/b9dw3AaE=
|
||||
github.com/go-jose/go-jose/v4 v4.0.5/go.mod h1:s3P1lRrkT8igV8D9OjyL4WRyHvjB6a4JSllnOrmmBOA=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
@ -263,8 +263,8 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/theupdateframework/notary v0.7.1-0.20210315103452-bf96a202a09a h1:tlJ7tGUHvcvL1v3yR6NcCc9nOqh2L+CG6HWrYQtwzQ0=
|
||||
github.com/theupdateframework/notary v0.7.1-0.20210315103452-bf96a202a09a/go.mod h1:Y94A6rPp2OwNfP/7vmf8O2xx2IykP8pPXQ1DLouGnEw=
|
||||
github.com/tonistiigi/go-rosetta v0.0.0-20220804170347-3f4430f2d346 h1:TvtdmeYsYEij78hS4oxnwikoiLdIrgav3BA+CbhaDAI=
|
||||
@ -317,8 +317,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
|
||||
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201117144127-c1f2f97bffc9/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
|
||||
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
|
||||
golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc=
|
||||
golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@ -353,8 +353,8 @@ golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
|
||||
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q=
|
||||
golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM=
|
||||
golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg=
|
||||
golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
|
||||
|
||||
6
vendor/github.com/go-jose/go-jose/v4/CONTRIBUTING.md
generated
vendored
6
vendor/github.com/go-jose/go-jose/v4/CONTRIBUTING.md
generated
vendored
@ -7,9 +7,3 @@ When submitting code, please make every effort to follow existing conventions
|
||||
and style in order to keep the code as readable as possible. Please also make
|
||||
sure all tests pass by running `go test`, and format your code with `go fmt`.
|
||||
We also recommend using `golint` and `errcheck`.
|
||||
|
||||
Before your code can be accepted into the project you must also sign the
|
||||
Individual Contributor License Agreement. We use [cla-assistant.io][1] and you
|
||||
will be prompted to sign once a pull request is opened.
|
||||
|
||||
[1]: https://cla-assistant.io/
|
||||
|
||||
10
vendor/github.com/go-jose/go-jose/v4/README.md
generated
vendored
10
vendor/github.com/go-jose/go-jose/v4/README.md
generated
vendored
@ -9,14 +9,6 @@ Package jose aims to provide an implementation of the Javascript Object Signing
|
||||
and Encryption set of standards. This includes support for JSON Web Encryption,
|
||||
JSON Web Signature, and JSON Web Token standards.
|
||||
|
||||
**Disclaimer**: This library contains encryption software that is subject to
|
||||
the U.S. Export Administration Regulations. You may not export, re-export,
|
||||
transfer or download this code or any part of it in violation of any United
|
||||
States law, directive or regulation. In particular this software may not be
|
||||
exported or re-exported in any form or on any media to Iran, North Sudan,
|
||||
Syria, Cuba, or North Korea, or to denied persons or entities mentioned on any
|
||||
US maintained blocked list.
|
||||
|
||||
## Overview
|
||||
|
||||
The implementation follows the
|
||||
@ -109,6 +101,6 @@ allows attaching a key id.
|
||||
|
||||
Examples can be found in the Godoc
|
||||
reference for this package. The
|
||||
[`jose-util`](https://github.com/go-jose/go-jose/tree/v4/jose-util)
|
||||
[`jose-util`](https://github.com/go-jose/go-jose/tree/main/jose-util)
|
||||
subdirectory also contains a small command-line utility which might be useful
|
||||
as an example as well.
|
||||
|
||||
5
vendor/github.com/go-jose/go-jose/v4/jwe.go
generated
vendored
5
vendor/github.com/go-jose/go-jose/v4/jwe.go
generated
vendored
@ -288,10 +288,11 @@ func ParseEncryptedCompact(
|
||||
keyAlgorithms []KeyAlgorithm,
|
||||
contentEncryption []ContentEncryption,
|
||||
) (*JSONWebEncryption, error) {
|
||||
parts := strings.Split(input, ".")
|
||||
if len(parts) != 5 {
|
||||
// Five parts is four separators
|
||||
if strings.Count(input, ".") != 4 {
|
||||
return nil, fmt.Errorf("go-jose/go-jose: compact JWE format must have five parts")
|
||||
}
|
||||
parts := strings.SplitN(input, ".", 5)
|
||||
|
||||
rawProtected, err := base64.RawURLEncoding.DecodeString(parts[0])
|
||||
if err != nil {
|
||||
|
||||
4
vendor/github.com/go-jose/go-jose/v4/jwk.go
generated
vendored
4
vendor/github.com/go-jose/go-jose/v4/jwk.go
generated
vendored
@ -239,10 +239,10 @@ func (k *JSONWebKey) UnmarshalJSON(data []byte) (err error) {
|
||||
keyPub = key
|
||||
}
|
||||
} else {
|
||||
err = fmt.Errorf("go-jose/go-jose: unknown curve %s'", raw.Crv)
|
||||
return fmt.Errorf("go-jose/go-jose: unknown curve %s'", raw.Crv)
|
||||
}
|
||||
default:
|
||||
err = fmt.Errorf("go-jose/go-jose: unknown json web key type '%s'", raw.Kty)
|
||||
return fmt.Errorf("go-jose/go-jose: unknown json web key type '%s'", raw.Kty)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
|
||||
5
vendor/github.com/go-jose/go-jose/v4/jws.go
generated
vendored
5
vendor/github.com/go-jose/go-jose/v4/jws.go
generated
vendored
@ -327,10 +327,11 @@ func parseSignedCompact(
|
||||
payload []byte,
|
||||
signatureAlgorithms []SignatureAlgorithm,
|
||||
) (*JSONWebSignature, error) {
|
||||
parts := strings.Split(input, ".")
|
||||
if len(parts) != 3 {
|
||||
// Three parts is two separators
|
||||
if strings.Count(input, ".") != 2 {
|
||||
return nil, fmt.Errorf("go-jose/go-jose: compact JWS format must have three parts")
|
||||
}
|
||||
parts := strings.SplitN(input, ".", 3)
|
||||
|
||||
if parts[1] != "" && payload != nil {
|
||||
return nil, fmt.Errorf("go-jose/go-jose: payload is not detached")
|
||||
|
||||
6
vendor/modules.txt
vendored
6
vendor/modules.txt
vendored
@ -124,7 +124,7 @@ github.com/felixge/httpsnoop
|
||||
# github.com/fvbommel/sortorder v1.1.0
|
||||
## explicit; go 1.13
|
||||
github.com/fvbommel/sortorder
|
||||
# github.com/go-jose/go-jose/v4 v4.0.4
|
||||
# github.com/go-jose/go-jose/v4 v4.0.5
|
||||
## explicit; go 1.21
|
||||
github.com/go-jose/go-jose/v4
|
||||
github.com/go-jose/go-jose/v4/cipher
|
||||
@ -383,7 +383,7 @@ go.opentelemetry.io/proto/otlp/common/v1
|
||||
go.opentelemetry.io/proto/otlp/metrics/v1
|
||||
go.opentelemetry.io/proto/otlp/resource/v1
|
||||
go.opentelemetry.io/proto/otlp/trace/v1
|
||||
# golang.org/x/crypto v0.31.0
|
||||
# golang.org/x/crypto v0.32.0
|
||||
## explicit; go 1.20
|
||||
golang.org/x/crypto/ed25519
|
||||
golang.org/x/crypto/pbkdf2
|
||||
@ -404,7 +404,7 @@ golang.org/x/sys/plan9
|
||||
golang.org/x/sys/unix
|
||||
golang.org/x/sys/windows
|
||||
golang.org/x/sys/windows/registry
|
||||
# golang.org/x/term v0.27.0
|
||||
# golang.org/x/term v0.28.0
|
||||
## explicit; go 1.18
|
||||
golang.org/x/term
|
||||
# golang.org/x/text v0.21.0
|
||||
|
||||
Reference in New Issue
Block a user