Compare commits

...

29 Commits

Author SHA1 Message Date
d3cb89ee53 Merge pull request #2957 from thaJeztah/20.10_backport_docs_fixes
[20.10 backport] documentation and completion-script fixes
2021-02-18 12:03:39 +01:00
433014bcfb Merge pull request #2959 from thaJeztah/20.10_backport_fix_login_panic
[20.10 backport] Fix panic when failing to get DefaultAuthConfig
2021-02-18 12:02:41 +01:00
61cb016851 Merge pull request #2961 from thaJeztah/20.10_backport_fix_context_dockerfile_from_stdin_with_buildkit
[20.10 backport] Fix reading context and dockerfile from stdin with BuildKit
2021-02-18 12:02:09 +01:00
53c4602909 Merge pull request #2962 from thaJeztah/20.10_backport_go_md2man_binary_name
[20.10 backport] Rename bin/md2man to bin/go-md2man
2021-02-18 11:58:57 +01:00
830d6595e7 Merge pull request #2963 from thaJeztah/20.10_backport_fix_update_rollback_order
[20.10 backport] fix --update-order and --rollback-order flags
2021-02-18 11:58:23 +01:00
13048444cc Merge pull request #2964 from thaJeztah/20.10_backport_fix_swarm_rollback_exitcode
[20.10 backport] Fix swarm rollback exitcode, and fix skipping verify step
2021-02-18 11:55:40 +01:00
3e293e6bd1 Merge pull request #2958 from thaJeztah/20.10_backport_fix_homedir_warning
[20.10 backport] cli/config: prevent warning if HOME is not set
2021-02-12 10:27:24 +01:00
41b3ea7e47 Merge pull request #2960 from thaJeztah/20.10_backport_ignore_sigurg 2021-02-04 07:36:47 -08:00
d6eeeb6259 service rollback: always verify state
Prior to this change, progressbars would sometimes be hidden, and the function
would return early. In addition, the direction of the progressbars would sometimes
be "incrementing" (similar to "docker service update"), and sometimes be "decrementing"
(to indicate a "rollback" is being performed).

This fix makes sure that we always proceed with the "verifying" step, and now
prints a message _after_ the verifying stage was completed;

    $ docker service rollback foo
    foo
    overall progress: rolling back update: 5 out of 5 tasks
    1/5: running   [>                                                  ]
    2/5: starting  [===========>                                       ]
    3/5: starting  [===========>                                       ]
    4/5: running   [>                                                  ]
    5/5: running   [>                                                  ]
    verify: Service converged
    rollback: rollback completed

    $ docker service rollback foo
    foo
    overall progress: rolling back update: 1 out of 1 tasks
    1/1: running   [>                                                  ]
    verify: Service converged
    rollback: rollback completed

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 104469be0b)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2021-02-04 14:55:51 +01:00
3e157d5293 docker service rollback: fix non-zero exit code in some cases
Before this change:
--------------------------------------------

    $ docker service create --replicas=1 --name foo -p 8080:80 nginx:alpine
    t33qvykv8y0zbz266rxynsbo3
    overall progress: 1 out of 1 tasks
    1/1: running   [==================================================>]
    verify: Service converged

    $ echo $?
    0

    $ docker service update --replicas=5 foo
    foo
    overall progress: 5 out of 5 tasks
    1/5: running   [==================================================>]
    2/5: running   [==================================================>]
    3/5: running   [==================================================>]
    4/5: running   [==================================================>]
    5/5: running   [==================================================>]
    verify: Service converged

    $ echo $?
    0

    $ docker service rollback foo
    foo
    rollback: manually requested rollback
    overall progress: rolling back update: 1 out of 1 tasks
    1/1: running   [>                                                  ]
    verify: Service converged

    $ echo $?
    0

    $ docker service rollback foo
    foo
    service rolled back: rollback completed

    $ echo $?
    1

After this change:
--------------------------------------------

    $ docker service create --replicas=1 --name foo -p 8080:80 nginx:alpine
    t33qvykv8y0zbz266rxynsbo3
    overall progress: 1 out of 1 tasks
    1/1: running   [==================================================>]
    verify: Service converged

    $ echo $?
    0

    $ docker service update --replicas=5 foo
    foo
    overall progress: 5 out of 5 tasks
    1/5: running   [==================================================>]
    2/5: running   [==================================================>]
    3/5: running   [==================================================>]
    4/5: running   [==================================================>]
    5/5: running   [==================================================>]
    verify: Waiting 1 seconds to verify that tasks are stable...

    $ echo $?
    0

    $ docker service rollback foo
    foo
    rollback: manually requested rollback
    overall progress: rolling back update: 1 out of 1 tasks
    1/1: running   [>                                                  ]
    verify: Service converged

    $ echo $?
    0

    $ docker service rollback foo
    foo
    service rolled back: rollback completed

    $ echo $?
    0

    $ docker service ps foo
    ID             NAME      IMAGE          NODE             DESIRED STATE   CURRENT STATE           ERROR     PORTS
    4dt4ms4c5qfb   foo.1     nginx:alpine   docker-desktop   Running         Running 2 minutes ago

Remaining issues with reconciliation
--------------------------------------------

Note that both before, and after this change, the command sometimes terminates
early, and does not wait for the service to reconcile; this is most apparent
when rolling back is scaling up (so more tasks are deployed);

    $ docker service rollback foo
    foo
    service rolled back: rollback completed

    $ docker service rollback foo
    foo
    rollback: manually requested rollback
    overall progress: rolling back update: 1 out of 5 tasks
    1/5: pending   [=================================>                 ]
    2/5: running   [>                                                  ]
    3/5: pending   [=================================>                 ]
    4/5: pending   [=================================>                 ]
    5/5: pending   [=================================>                 ]
    service rolled back: rollback completed

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit ce26a165b0)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2021-02-04 14:55:49 +01:00
1fdf84b8e9 fix --update-order and --rollback-order flags
Signed-off-by: Jim Lin <b04705003@ntu.edu.tw>
(cherry picked from commit 26a6a724aa)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2021-02-04 14:53:34 +01:00
376b99c6d6 Rename bin/md2man to bin/go-md2man
In the recent PR !2877, some code was added to check if md2man is
already installed in the build environment. This is to cater to the
needs of Linux distributions.

However it turns out that Linux distributions install md2man as
bin/go-md2man instead of bin/md2man, hence the PR !2877 doesn't help
much.

This commit fixes it by settling on using the binary name go-md2man.

For reference, here the file list of the package go-md2man in several
distributions:

- Debian: <https://packages.debian.org/sid/amd64/go-md2man/filelist>
- Ubuntu: <https://packages.ubuntu.com/hirsute/amd64/go-md2man/filelist>
- Fedora: <https://fedora.pkgs.org/31/fedora-x86_64/golang-github-cpuguy83-md2man-2.0.0-0.4.20190624gitf79a8a8.fc31.x86_64.rpm.html>
- ArchLinux: <https://www.archlinux.org/packages/community/x86_64/go-md2man/>

Signed-off-by: Arnaud Rebillout <elboulangero@gmail.com>
(cherry picked from commit 6e2607c6a6)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2021-02-04 14:50:45 +01:00
0de4e6e9a7 Fix reading context and dockerfile from stdin with BuildKit
Signed-off-by: Alexey Igrychev <alexey.igrychev@flant.com>
(cherry picked from commit fc9ca9a94a)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2021-02-04 14:48:19 +01:00
3c87f01b18 Ignore SIGURG on Linux.
In go1.14+, SIGURG is used by the runtime to handle preemtable system
calls.
In practice this signal caught *frequently*.

For reference:

https://go.googlesource.com/proposal/+/master/design/24543-non-cooperative-preemption.md
https://github.com/golang/go/issues/37942

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
(cherry picked from commit fff164c22e)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2021-02-04 14:44:39 +01:00
de40c2b172 Fix panic when failing to get DefaultAuthConfig
Commit f32731f902 fixed a potential panic
when an error was returned while trying to get existing credentials.

However, other code paths currently use the result of `GetDefaultAuthConfig()`
even in an error condition; this resulted in a panic, because a `nil` was
returned.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit c2820a7e3b)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2021-02-04 14:42:06 +01:00
d513e46bfc cli/config: prevent warning if HOME is not set
commit c2626a8270 replaced the use of
github.com/docker/docker/pkg/homedir with Golang's os.UserHomeDir().

This change was partially reverted in 7a279af43d
to account for situations where `$HOME` is not set.

In  situations where no configuration file is present in `~/.config/`, the CLI
falls back to looking for the (deprecated) `~/.dockercfg` configuration file,
which was still using `os.UserHomeDir()`, which produces an error/warning if
`$HOME` is not set.

This patch introduces a helper function and a global variable to get the user's
home-directory. The global variable is used to prevent repeatedly looking up
the user's information (which, depending on the setup can be a costly operation).

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit c85a37dbb4)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2021-02-04 14:38:27 +01:00
2b74b90efb Add docs and completion for docker node ls --filter node.label
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit f52a9e2fef)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2021-02-04 14:33:15 +01:00
05343b36a2 fix docker-run man page table formatting
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit c0b7b58134)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2021-02-04 14:33:10 +01:00
f90db254d7 docs: Fix wrong variable name
Signed-off-by: LeeDongGeon <secmatth1996@gmail.com>
(cherry picked from commit 852fe05991)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2021-02-04 14:33:06 +01:00
0dcfdde336 Removed format flag for inspect
Signed-off-by: Christopher Svensson <stoffus@stoffus.com>
(cherry picked from commit b04241d95a)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2021-02-04 14:33:01 +01:00
03cd1dc50a Added zsh completion for docker context subcommands
Signed-off-by: Christopher Svensson <stoffus@stoffus.com>
(cherry picked from commit 584c08e1fe)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2021-02-04 14:32:59 +01:00
42811a7eb9 docs: add redirect for old reference URL
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit a4fb01f957)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2021-02-04 14:32:54 +01:00
be966aa194 docs: fix typo in deprecated.md
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 697c3a5b48)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2021-02-04 14:32:49 +01:00
b22fe0fb14 deprecate blkio-weight options with cgroups v1
These options were deprecated and removed in the Linux kernel v5.0 and up in;

- f382fb0bce
- fb5772cbfe
- 23aa16489c

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit fb2ea098a9)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2021-02-04 14:32:44 +01:00
4eb050071e Update bash completion for fluentd --log-options
Signed-off-by: Harald Albers <github@albersweb.de>
(cherry picked from commit 5a252fb3ad)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2021-02-04 14:32:39 +01:00
08c4fdfa7a Add bash completion for dockerd --ip6tables
Signed-off-by: Harald Albers <github@albersweb.de>
(cherry picked from commit ba2fef9bcb)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2021-02-04 14:32:34 +01:00
6aa1b37c8d Add bash completion for docker run|create --pull
Signed-off-by: Harald Albers <github@albersweb.de>
(cherry picked from commit 8242fe1fcc)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2021-02-04 14:32:29 +01:00
e82920d76d Remove duplicate word in push.md
Signed-off-by: Roch Feuillade <roch.feuillade@pandobac.com>
(cherry picked from commit 69b5487e39)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2021-02-04 14:32:24 +01:00
82123939f7 Add bash completion for jobs
Signed-off-by: Harald Albers <github@albersweb.de>
(cherry picked from commit a4e86b5433)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2021-02-04 14:32:17 +01:00
27 changed files with 423 additions and 65 deletions

View File

@ -97,7 +97,8 @@ func runAttach(dockerCli command.Cli, opts *attachOptions) error {
}
if opts.proxy && !c.Config.Tty {
sigc := ForwardAllSignals(ctx, dockerCli, opts.container)
sigc := notfiyAllSignals()
go ForwardAllSignals(ctx, dockerCli, opts.container, sigc)
defer signal.StopCatch(sigc)
}

View File

@ -32,6 +32,7 @@ type fakeClient struct {
containerExportFunc func(string) (io.ReadCloser, error)
containerExecResizeFunc func(id string, options types.ResizeOptions) error
containerRemoveFunc func(ctx context.Context, container string, options types.ContainerRemoveOptions) error
containerKillFunc func(ctx context.Context, container, signal string) error
Version string
}
@ -154,3 +155,10 @@ func (f *fakeClient) ContainerExecResize(_ context.Context, id string, options t
}
return nil
}
func (f *fakeClient) ContainerKill(ctx context.Context, container, signal string) error {
if f.containerKillFunc != nil {
return f.containerKillFunc(ctx, container, signal)
}
return nil
}

View File

@ -131,7 +131,8 @@ func runContainer(dockerCli command.Cli, opts *runOptions, copts *containerOptio
return runStartContainerErr(err)
}
if opts.sigProxy {
sigc := ForwardAllSignals(ctx, dockerCli, createResponse.ID)
sigc := notfiyAllSignals()
go ForwardAllSignals(ctx, dockerCli, createResponse.ID, sigc)
defer signal.StopCatch(sigc)
}

View File

@ -0,0 +1,57 @@
package container
import (
"context"
"fmt"
"os"
gosignal "os/signal"
"github.com/docker/cli/cli/command"
"github.com/docker/docker/pkg/signal"
"github.com/sirupsen/logrus"
)
// ForwardAllSignals forwards signals to the container
//
// The channel you pass in must already be setup to receive any signals you want to forward.
func ForwardAllSignals(ctx context.Context, cli command.Cli, cid string, sigc <-chan os.Signal) {
var s os.Signal
for {
select {
case s = <-sigc:
case <-ctx.Done():
return
}
if s == signal.SIGCHLD || s == signal.SIGPIPE {
continue
}
// In go1.14+, the go runtime issues SIGURG as an interrupt to support pre-emptable system calls on Linux.
// Since we can't forward that along we'll check that here.
if isRuntimeSig(s) {
continue
}
var sig string
for sigStr, sigN := range signal.SignalMap {
if sigN == s {
sig = sigStr
break
}
}
if sig == "" {
fmt.Fprintf(cli.Err(), "Unsupported signal: %v. Discarding.\n", s)
continue
}
if err := cli.Client().ContainerKill(ctx, cid, sig); err != nil {
logrus.Debugf("Error sending signal: %s", err)
}
}
}
func notfiyAllSignals() chan os.Signal {
sigc := make(chan os.Signal, 128)
gosignal.Notify(sigc)
return sigc
}

View File

@ -0,0 +1,11 @@
package container
import (
"os"
"golang.org/x/sys/unix"
)
func isRuntimeSig(s os.Signal) bool {
return s == unix.SIGURG
}

View File

@ -0,0 +1,57 @@
package container
import (
"context"
"os"
"syscall"
"testing"
"time"
"github.com/docker/cli/internal/test"
"golang.org/x/sys/unix"
"gotest.tools/v3/assert"
)
func TestIgnoredSignals(t *testing.T) {
ignoredSignals := []syscall.Signal{unix.SIGPIPE, unix.SIGCHLD, unix.SIGURG}
for _, s := range ignoredSignals {
t.Run(unix.SignalName(s), func(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
var called bool
client := &fakeClient{containerKillFunc: func(ctx context.Context, container, signal string) error {
called = true
return nil
}}
cli := test.NewFakeCli(client)
sigc := make(chan os.Signal)
defer close(sigc)
done := make(chan struct{})
go func() {
ForwardAllSignals(ctx, cli, t.Name(), sigc)
close(done)
}()
timer := time.NewTimer(30 * time.Second)
defer timer.Stop()
select {
case <-timer.C:
t.Fatal("timeout waiting to send signal")
case sigc <- s:
case <-done:
}
// cancel the context so ForwardAllSignals will exit after it has processed the signal we sent.
// This is how we know the signal was actually processed and are not introducing a flakey test.
cancel()
<-done
assert.Assert(t, !called, "kill was called")
})
}
}

View File

@ -0,0 +1,9 @@
// +build !linux
package container
import "os"
func isRuntimeSig(_ os.Signal) bool {
return false
}

View File

@ -0,0 +1,48 @@
package container
import (
"context"
"os"
"testing"
"time"
"github.com/docker/cli/internal/test"
"github.com/docker/docker/pkg/signal"
)
func TestForwardSignals(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
called := make(chan struct{})
client := &fakeClient{containerKillFunc: func(ctx context.Context, container, signal string) error {
close(called)
return nil
}}
cli := test.NewFakeCli(client)
sigc := make(chan os.Signal)
defer close(sigc)
go ForwardAllSignals(ctx, cli, t.Name(), sigc)
timer := time.NewTimer(30 * time.Second)
defer timer.Stop()
select {
case <-timer.C:
t.Fatal("timeout waiting to send signal")
case sigc <- signal.SignalMap["TERM"]:
}
if !timer.Stop() {
<-timer.C
}
timer.Reset(30 * time.Second)
select {
case <-called:
case <-timer.C:
t.Fatal("timeout waiting for signal to be processed")
}
}

View File

@ -74,7 +74,8 @@ func runStart(dockerCli command.Cli, opts *startOptions) error {
// We always use c.ID instead of container to maintain consistency during `docker start`
if !c.Config.Tty {
sigc := ForwardAllSignals(ctx, dockerCli, c.ID)
sigc := notfiyAllSignals()
ForwardAllSignals(ctx, dockerCli, c.ID, sigc)
defer signal.StopCatch(sigc)
}

View File

@ -95,32 +95,3 @@ func MonitorTtySize(ctx context.Context, cli command.Cli, id string, isExec bool
}
return nil
}
// ForwardAllSignals forwards signals to the container
func ForwardAllSignals(ctx context.Context, cli command.Cli, cid string) chan os.Signal {
sigc := make(chan os.Signal, 128)
signal.CatchAll(sigc)
go func() {
for s := range sigc {
if s == signal.SIGCHLD || s == signal.SIGPIPE {
continue
}
var sig string
for sigStr, sigN := range signal.SignalMap {
if sigN == s {
sig = sigStr
break
}
}
if sig == "" {
fmt.Fprintf(cli.Err(), "Unsupported signal: %v. Discarding.\n", s)
continue
}
if err := cli.Client().ContainerKill(ctx, cid, sig); err != nil {
logrus.Debugf("Error sending signal: %s", err)
}
}
}()
return sigc
}

View File

@ -78,7 +78,7 @@ func runBuildBuildKit(dockerCli command.Cli, options buildOptions) error {
if options.dockerfileFromStdin() {
return errStdinConflict
}
rc, isArchive, err := build.DetectArchiveReader(os.Stdin)
rc, isArchive, err := build.DetectArchiveReader(dockerCli.In())
if err != nil {
return err
}
@ -98,7 +98,7 @@ func runBuildBuildKit(dockerCli command.Cli, options buildOptions) error {
case isLocalDir(options.context):
contextDir = options.context
if options.dockerfileFromStdin() {
dockerfileReader = os.Stdin
dockerfileReader = dockerCli.In()
} else if options.dockerfileName != "" {
dockerfileName = filepath.Base(options.dockerfileName)
dockerfileDir = filepath.Dir(options.dockerfileName)

View File

@ -63,6 +63,9 @@ func RegistryAuthenticationPrivilegedFunc(cli Cli, index *registrytypes.IndexInf
indexServer := registry.GetAuthConfigKey(index)
isDefaultRegistry := indexServer == ElectAuthServer(context.Background(), cli)
authConfig, err := GetDefaultAuthConfig(cli, true, indexServer, isDefaultRegistry)
if authConfig == nil {
authConfig = &types.AuthConfig{}
}
if err != nil {
fmt.Fprintf(cli.Err(), "Unable to retrieve stored credentials for %s, error: %s.\n", indexServer, err)
}

View File

@ -111,11 +111,12 @@ func runLogin(dockerCli command.Cli, opts loginOptions) error { //nolint: gocycl
serverAddress = authServer
}
var err error
var authConfig *types.AuthConfig
var response registrytypes.AuthenticateOKBody
isDefaultRegistry := serverAddress == authServer
authConfig, err = command.GetDefaultAuthConfig(dockerCli, opts.user == "" && opts.password == "", serverAddress, isDefaultRegistry)
authConfig, err := command.GetDefaultAuthConfig(dockerCli, opts.user == "" && opts.password == "", serverAddress, isDefaultRegistry)
if authConfig == nil {
authConfig = &types.AuthConfig{}
}
if err == nil && authConfig.Username != "" && authConfig.Password != "" {
response, err = loginWithCredStoreCreds(ctx, dockerCli, authConfig)
}

View File

@ -165,7 +165,7 @@ func updateConfigFromDefaults(defaultUpdateConfig *api.UpdateConfig) *swarm.Upda
}
func (opts updateOptions) updateConfig(flags *pflag.FlagSet) *swarm.UpdateConfig {
if !anyChanged(flags, flagUpdateParallelism, flagUpdateDelay, flagUpdateMonitor, flagUpdateFailureAction, flagUpdateMaxFailureRatio) {
if !anyChanged(flags, flagUpdateParallelism, flagUpdateDelay, flagUpdateMonitor, flagUpdateFailureAction, flagUpdateMaxFailureRatio, flagUpdateOrder) {
return nil
}
@ -194,7 +194,7 @@ func (opts updateOptions) updateConfig(flags *pflag.FlagSet) *swarm.UpdateConfig
}
func (opts updateOptions) rollbackConfig(flags *pflag.FlagSet) *swarm.UpdateConfig {
if !anyChanged(flags, flagRollbackParallelism, flagRollbackDelay, flagRollbackMonitor, flagRollbackFailureAction, flagRollbackMaxFailureRatio) {
if !anyChanged(flags, flagRollbackParallelism, flagRollbackDelay, flagRollbackMonitor, flagRollbackFailureAction, flagRollbackMaxFailureRatio, flagRollbackOrder) {
return nil
}

View File

@ -289,6 +289,22 @@ func TestToServiceUpdateRollback(t *testing.T) {
assert.Check(t, is.DeepEqual(service.RollbackConfig, expected.RollbackConfig))
}
func TestToServiceUpdateRollbackOrder(t *testing.T) {
flags := newCreateCommand(nil).Flags()
flags.Set("update-order", "start-first")
flags.Set("rollback-order", "start-first")
o := newServiceOptions()
o.mode = "replicated"
o.update = updateOptions{order: "start-first"}
o.rollback = updateOptions{order: "start-first"}
service, err := o.ToService(context.Background(), &fakeClient{}, flags)
assert.NilError(t, err)
assert.Check(t, is.Equal(service.UpdateConfig.Order, o.update.order))
assert.Check(t, is.Equal(service.RollbackConfig.Order, o.rollback.order))
}
func TestToServiceMaxReplicasGlobalModeConflict(t *testing.T) {
opt := serviceOptions{
mode: "global",

View File

@ -99,6 +99,7 @@ func ServiceProgress(ctx context.Context, client client.APIClient, serviceID str
convergedAt time.Time
monitor = 5 * time.Second
rollback bool
message *progress.Progress
)
for {
@ -140,8 +141,9 @@ func ServiceProgress(ctx context.Context, client client.APIClient, serviceID str
return fmt.Errorf("service rollback paused: %s", service.UpdateStatus.Message)
case swarm.UpdateStateRollbackCompleted:
if !converged {
return fmt.Errorf("service rolled back: %s", service.UpdateStatus.Message)
message = &progress.Progress{ID: "rollback", Message: service.UpdateStatus.Message}
}
rollback = true
}
}
if converged && time.Since(convergedAt) >= monitor {
@ -149,7 +151,9 @@ func ServiceProgress(ctx context.Context, client client.APIClient, serviceID str
ID: "verify",
Action: "Service converged",
})
if message != nil {
progressOut.WriteProgress(*message)
}
return nil
}

View File

@ -26,15 +26,29 @@ const (
var (
initConfigDir sync.Once
configDir string
homeDir string
)
// resetHomeDir is used in testing to resets the "homeDir" package variable to
// force re-lookup of the home directory between tests.
func resetHomeDir() {
homeDir = ""
}
func getHomeDir() string {
if homeDir == "" {
homeDir = homedir.Get()
}
return homeDir
}
func setConfigDir() {
if configDir != "" {
return
}
configDir = os.Getenv("DOCKER_CONFIG")
if configDir == "" {
configDir = filepath.Join(homedir.Get(), configFileDir)
configDir = filepath.Join(getHomeDir(), configFileDir)
}
}
@ -109,11 +123,7 @@ func Load(configDir string) (*configfile.ConfigFile, error) {
}
// Can't find latest config file so check for the old one
home, err := os.UserHomeDir()
if err != nil {
return configFile, errors.Wrap(err, oldConfigfile)
}
filename = filepath.Join(home, oldConfigfile)
filename = filepath.Join(getHomeDir(), oldConfigfile)
if file, err := os.Open(filename); err == nil {
defer file.Close()
if err := configFile.LegacyLoadFromReader(file); err != nil {

View File

@ -115,6 +115,7 @@ password`: "Invalid Auth config file",
email`: "Invalid auth configuration file",
}
resetHomeDir()
tmpHome, err := ioutil.TempDir("", "config-test")
assert.NilError(t, err)
defer os.RemoveAll(tmpHome)
@ -131,6 +132,7 @@ email`: "Invalid auth configuration file",
}
func TestOldValidAuth(t *testing.T) {
resetHomeDir()
tmpHome, err := ioutil.TempDir("", "config-test")
assert.NilError(t, err)
defer os.RemoveAll(tmpHome)
@ -165,6 +167,7 @@ func TestOldValidAuth(t *testing.T) {
}
func TestOldJSONInvalid(t *testing.T) {
resetHomeDir()
tmpHome, err := ioutil.TempDir("", "config-test")
assert.NilError(t, err)
defer os.RemoveAll(tmpHome)
@ -184,6 +187,7 @@ func TestOldJSONInvalid(t *testing.T) {
}
func TestOldJSON(t *testing.T) {
resetHomeDir()
tmpHome, err := ioutil.TempDir("", "config-test")
assert.NilError(t, err)
defer os.RemoveAll(tmpHome)

View File

@ -935,7 +935,7 @@ __docker_complete_log_options() {
# awslogs does not implement the $common_options2.
local awslogs_options="$common_options1 awslogs-create-group awslogs-credentials-endpoint awslogs-datetime-format awslogs-group awslogs-multiline-pattern awslogs-region awslogs-stream tag"
local fluentd_options="$common_options1 $common_options2 fluentd-address fluentd-async-connect fluentd-buffer-limit fluentd-retry-wait fluentd-max-retries fluentd-sub-second-precision tag"
local fluentd_options="$common_options1 $common_options2 fluentd-address fluentd-async fluentd-buffer-limit fluentd-request-ack fluentd-retry-wait fluentd-max-retries fluentd-sub-second-precision tag"
local gcplogs_options="$common_options1 $common_options2 gcp-log-cmd gcp-meta-id gcp-meta-name gcp-meta-zone gcp-project"
local gelf_options="$common_options1 $common_options2 gelf-address gelf-compression-level gelf-compression-type gelf-tcp-max-reconnect gelf-tcp-reconnect-delay tag"
local journald_options="$common_options1 $common_options2 tag"
@ -1955,6 +1955,7 @@ _docker_container_run_and_create() {
--pid
--pids-limit
--publish -p
--pull
--restart
--runtime
--security-opt
@ -2153,6 +2154,10 @@ _docker_container_run_and_create() {
esac
return
;;
--pull)
COMPREPLY=( $( compgen -W 'always missing never' -- "$cur" ) )
return
;;
--runtime)
__docker_complete_runtimes
return
@ -2548,6 +2553,7 @@ _docker_daemon() {
--ip-forward=false
--ip-masq=false
--iptables=false
--ip6tables
--ipv6
--live-restore
--no-new-privileges
@ -3601,7 +3607,7 @@ _docker_service_ls() {
return
;;
mode)
COMPREPLY=( $( compgen -W "global replicated" -- "${cur##*=}" ) )
COMPREPLY=( $( compgen -W "global global-job replicated replicated-job" -- "${cur##*=}" ) )
return
;;
name)
@ -3731,6 +3737,7 @@ _docker_service_update_and_create() {
--limit-pids
--log-driver
--log-opt
--max-replicas
--replicas
--replicas-max-per-node
--reserve-cpu
@ -3804,7 +3811,7 @@ _docker_service_update_and_create() {
return
;;
--mode)
COMPREPLY=( $( compgen -W "global replicated" -- "$cur" ) )
COMPREPLY=( $( compgen -W "global global-job replicated replicated-job" -- "$cur" ) )
return
;;
esac
@ -4348,6 +4355,9 @@ _docker_node_ls() {
__docker_complete_nodes --cur "${cur##*=}" --id
return
;;
label|node.label)
return
;;
membership)
COMPREPLY=( $( compgen -W "accepted pending" -- "${cur##*=}" ) )
return
@ -4364,7 +4374,7 @@ _docker_node_ls() {
case "$prev" in
--filter|-f)
COMPREPLY=( $( compgen -W "id label membership name role" -S = -- "$cur" ) )
COMPREPLY=( $( compgen -W "id label membership name node.label role" -S = -- "$cur" ) )
__docker_nospace
return
;;

View File

@ -1343,7 +1343,7 @@ __docker_node_complete_ls_filters() {
;;
esac
else
opts=('id' 'label' 'membership' 'name' 'role')
opts=('id' 'label' 'membership' 'name' 'node.label' 'role')
_describe -t filter-opts "filter options" opts -qS "=" && ret=0
fi
@ -2544,6 +2544,82 @@ __docker_volume_subcommand() {
# EO volume
# BO context
__docker_complete_contexts() {
[[ $PREFIX = -* ]] && return 1
integer ret=1
declare -a contexts
contexts=(${(f)${:-"$(_call_program commands docker $docker_options context ls -q)"$'\n'}})
_describe -t context-list "context" contexts && ret=0
return ret
}
__docker_context_commands() {
local -a _docker_context_subcommands
_docker_context_subcommands=(
"create:Create new context"
"inspect:Display detailed information on one or more contexts"
"list:List available contexts"
"rm:Remove one or more contexts"
"show:Print the current context"
"update:Update a context"
"use:Set the default context"
)
_describe -t docker-context-commands "docker context command" _docker_context_subcommands
}
__docker_context_subcommand() {
local -a _command_args opts_help
local expl help="--help"
integer ret=1
opts_help=("(: -)--help[Print usage]")
case "$words[1]" in
(create)
_arguments $(__docker_arguments) \
$opts_help \
"($help)--default-stack-orchestrator=[Default orchestrator for stack operations to use with this context]:default-stack-orchestrator:(swarm kubernetes all)" \
"($help)--description=[Description of the context]:description:" \
"($help)--docker=[Set the docker endpoint]:docker:" \
"($help)--kubernetes=[Set the kubernetes endpoint]:kubernetes:" \
"($help)--from=[Create context from a named context]:from:__docker_complete_contexts" \
"($help -):name: " && ret=0
;;
(use)
_arguments $(__docker_arguments) \
$opts_help \
"($help -)1:context:__docker_complete_contexts" && ret=0
;;
(inspect)
_arguments $(__docker_arguments) \
$opts_help \
"($help -)1:context:__docker_complete_contexts" && ret=0
;;
(rm)
_arguments $(__docker_arguments) \
$opts_help \
"($help -)1:context:__docker_complete_contexts" && ret=0
;;
(update)
_arguments $(__docker_arguments) \
$opts_help \
"($help)--default-stack-orchestrator=[Default orchestrator for stack operations to use with this context]:default-stack-orchestrator:(swarm kubernetes all)" \
"($help)--description=[Description of the context]:description:" \
"($help)--docker=[Set the docker endpoint]:docker:" \
"($help)--kubernetes=[Set the kubernetes endpoint]:kubernetes:" \
"($help -):name:" && ret=0
;;
esac
return ret
}
# EO context
__docker_caching_policy() {
oldp=( "$1"(Nmh+1) ) # 1 hour
(( $#oldp ))
@ -2631,6 +2707,23 @@ __docker_subcommand() {
;;
esac
;;
(context)
local curcontext="$curcontext" state
_arguments $(__docker_arguments) \
$opts_help \
"($help -): :->command" \
"($help -)*:: :->option-or-argument" && ret=0
case $state in
(command)
__docker_context_commands && ret=0
;;
(option-or-argument)
curcontext=${curcontext%:*:*}:docker-${words[-1]}:
__docker_context_subcommand && ret=0
;;
esac
;;
(daemon)
_arguments $(__docker_arguments) \
$opts_help \

View File

@ -52,6 +52,7 @@ Status | Feature
-----------|------------------------------------------------------------------------------------------------------------------------------------|------------|------------
Deprecated | [Pulling images from non-compliant image registries](#pulling-images-from-non-compliant-image-registries) | v20.10 | -
Deprecated | [Linux containers on Windows (LCOW)](#linux-containers-on-windows-lcow-experimental) | v20.10 | -
Deprecated | [BLKIO weight options with cgroups v1](#blkio-weight-optionswith-cgroups-v1) | v20.10 | -
Deprecated | [Kernel memory limit](#kernel-memory-limit) | v20.10 | -
Deprecated | [Classic Swarm and overlay networks using external key/value stores](#classic-swarm-and-overlay-networks-using-cluster-store) | v20.10 | -
Deprecated | [Support for the legacy `~/.dockercfg` configuration file for authentication](#support-for-legacy-dockercfg-configuration-files) | v20.10 | -
@ -140,6 +141,16 @@ now stopped in favor of running docker natively on Linux in WSL2.
Developers who want to run Linux workloads on a Windows host are encouraged to use
[Docker Desktop with WSL2](https://docs.docker.com/docker-for-windows/wsl/) instead.
### BLKIO weight options with cgroups v1
**Deprecated in Release: v20.10**
Specifying blkio weight (`docker run --blkio-weight` and `docker run --blkio-weight-device`)
is now marked as deprecated when using cgroups v1 because the corresponding features
were [removed in Linux kernel v5.0 and up](https://github.com/torvalds/linux/commit/f382fb0bcef4c37dc049e9f6963e3baf204d815c).
When using cgroups v2, the `--blkio-weight` options are implemented using
[`io.weight](https://github.com/torvalds/linux/blob/v5.0/Documentation/admin-guide/cgroup-v2.rst#io).
### Kernel memory limit
**Deprecated in Release: v20.10**

View File

@ -60,6 +60,7 @@ The currently supported filters are:
* [id](#id)
* [label](#label)
* [node.label](#nodelabel)
* [membership](#membership)
* [name](#name)
* [role](#role)
@ -77,7 +78,10 @@ ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
#### label
The `label` filter matches nodes based on engine labels and on the presence of a `label` alone or a `label` and a value. Node labels are currently not used for filtering.
The `label` filter matches nodes based on engine labels and on the presence of a
`label` alone or a `label` and a value. Engine labels are configured in
the [daemon configuration](dockerd.md#daemon-configuration-file). To filter on
Swarm `node` labels, use [`node.label` instead](#nodelabel).
The following filter matches nodes with the `foo` label regardless of its value.
@ -88,6 +92,42 @@ ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
1bcef6utixb0l0ca7gxuivsj0 swarm-worker2 Ready Active
```
#### node.label
The `node.label` filter matches nodes based on node labels and on the presence
of a `node.label` alone or a `node.label` and a value.
The following filter updates nodes to have a `region` node label:
```console
$ docker node update --label-add region=region-a swarm-test-01
$ docker node update --label-add region=region-a swarm-test-02
$ docker node update --label-add region=region-b swarm-test-03
$ docker node update --label-add region=region-b swarm-test-04
```
Show all nodes that have a `region` node label set:
```console
$ docker node ls --filter node.label=region
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
yg550ettvsjn6g6t840iaiwgb * swarm-test-01 Ready Active Leader 20.10.2
2lm9w9kbepgvkzkkeyku40e65 swarm-test-02 Ready Active Reachable 20.10.2
hc0pu7ntc7s4uvj4pv7z7pz15 swarm-test-03 Ready Active Reachable 20.10.2
n41b2cijmhifxxvz56vwrs12q swarm-test-04 Ready Active 20.10.2
```
Show all nodes that have a `region` node label, with value `region-a`:
```console
$ docker node ls --filter node.label=region=region-a
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
yg550ettvsjn6g6t840iaiwgb * swarm-test-01 Ready Active Leader 20.10.2
2lm9w9kbepgvkzkkeyku40e65 swarm-test-02 Ready Active Reachable 20.10.2
```
#### membership
The `membership` filter matches nodes based on the presence of a `membership` and a value

View File

@ -76,7 +76,7 @@ listed.
### Push all tags of an image
Use the `-a` (or `--all-tags`) option to push To push all tags of a local image.
Use the `-a` (or `--all-tags`) option to push all tags of a local image.
The following example creates multiple tags for an image, and pushes all those
tags to Docker Hub.

View File

@ -1,6 +1,8 @@
---
description: "Configure containers at runtime"
keywords: "docker, run, configure, runtime"
redirect_from:
- /reference/run/
---
<!-- This file is maintained within the docker/cli GitHub
@ -1738,7 +1740,7 @@ volume mounted on the host).
The `container-dest` must always be an absolute path such as `/src/docs`.
The `host-src` can either be an absolute path or a `name` value. If you
supply an absolute path for the `host-dir`, Docker bind-mounts to the path
supply an absolute path for the `host-src`, Docker bind-mounts to the path
you specify. If you supply a `name`, Docker creates a named volume by that `name`.
A `name` value must start with an alphanumeric character,

View File

@ -504,13 +504,13 @@ and foreground Docker containers.
**--network**=*type*
Set the Network mode for the container. Supported values are:
| Value | Description |
|:----------------------------|:-----------------------------------------------------------------------------------------|
| **none** | No networking in the container. |
| **bridge** | Connect the container to the default Docker bridge via veth interfaces. |
| **host** | Use the host's network stack inside the container. |
| **container:**_name_|_id_ | Use the network stack of another container, specified via its _name_ or _id_. |
| _network-name_|_network-id_ | Connects the container to a user created network (using `docker network create` command) |
| Value | Description |
|:-----------------------------|:-----------------------------------------------------------------------------------------|
| **none** | No networking in the container. |
| **bridge** | Connect the container to the default Docker bridge via veth interfaces. |
| **host** | Use the host's network stack inside the container. |
| **container:**_name_\|_id_ | Use the network stack of another container, specified via its _name_ or _id_. |
| _network-name_\|_network-id_ | Connects the container to a user created network (using `docker network create` command) |
Default is **bridge**.

View File

@ -18,5 +18,5 @@ for FILE in *.md; do
continue
fi
mkdir -p "./man${num}"
md2man -in "$FILE" -out "./man${num}/${name}"
go-md2man -in "$FILE" -out "./man${num}/${name}"
done

View File

@ -4,9 +4,9 @@ set -eu -o pipefail
mkdir -p ./man/man1
if ! command -v md2man &> /dev/null; then
if ! command -v go-md2man &> /dev/null; then
# yay, go install creates a binary named "v2" ¯\_(ツ)_/¯
go build -o "/go/bin/md2man" ./vendor/github.com/cpuguy83/go-md2man/v2
go build -o "/go/bin/go-md2man" ./vendor/github.com/cpuguy83/go-md2man/v2
fi
# Generate man pages from cobra commands