diff --git a/components/cli/cli/command/cli.go b/components/cli/cli/command/cli.go index 8203095682..344fddd61e 100644 --- a/components/cli/cli/command/cli.go +++ b/components/cli/cli/command/cli.go @@ -166,7 +166,10 @@ func (cli *DockerCli) Initialize(opts *cliflags.ClientOptions) error { if err != nil { return errors.Wrap(err, "Experimental field") } - orchestrator := GetOrchestrator(hasExperimental, opts.Common.Orchestrator, cli.configFile.Orchestrator) + orchestrator, err := GetOrchestrator(hasExperimental, opts.Common.Orchestrator, cli.configFile.Orchestrator) + if err != nil { + return err + } cli.clientInfo = ClientInfo{ DefaultVersion: cli.client.ClientVersion(), HasExperimental: hasExperimental, diff --git a/components/cli/cli/command/formatter/service.go b/components/cli/cli/command/formatter/service.go index 760bd03e79..697d6be4c0 100644 --- a/components/cli/cli/command/formatter/service.go +++ b/components/cli/cli/command/formatter/service.go @@ -92,10 +92,10 @@ ContainerSpec: Mounts: {{- end }} {{- range $mount := .ContainerMounts }} - Target = {{ $mount.Target }} - Source = {{ $mount.Source }} - ReadOnly = {{ $mount.ReadOnly }} - Type = {{ $mount.Type }} + Target: {{ $mount.Target }} + Source: {{ $mount.Source }} + ReadOnly: {{ $mount.ReadOnly }} + Type: {{ $mount.Type }} {{- end -}} {{- if .Configs}} Configs: diff --git a/components/cli/cli/command/orchestrator.go b/components/cli/cli/command/orchestrator.go index d27bd6c1fa..b15c8f41bf 100644 --- a/components/cli/cli/command/orchestrator.go +++ b/components/cli/cli/command/orchestrator.go @@ -19,41 +19,39 @@ const ( envVarDockerOrchestrator = "DOCKER_ORCHESTRATOR" ) -func normalize(flag string) Orchestrator { - switch flag { +func normalize(value string) (Orchestrator, error) { + switch value { case "kubernetes": - return OrchestratorKubernetes + return OrchestratorKubernetes, nil case "swarm": - return OrchestratorSwarm + return OrchestratorSwarm, nil + case "": + return orchestratorUnset, nil default: - return orchestratorUnset + return defaultOrchestrator, fmt.Errorf("specified orchestrator %q is invalid, please use either kubernetes or swarm", value) } } // GetOrchestrator checks DOCKER_ORCHESTRATOR environment variable and configuration file // orchestrator value and returns user defined Orchestrator. -func GetOrchestrator(isExperimental bool, flagValue, value string) Orchestrator { +func GetOrchestrator(isExperimental bool, flagValue, value string) (Orchestrator, error) { // Non experimental CLI has kubernetes disabled if !isExperimental { - return defaultOrchestrator + return defaultOrchestrator, nil } // Check flag - if o := normalize(flagValue); o != orchestratorUnset { - return o + if o, err := normalize(flagValue); o != orchestratorUnset { + return o, err } // Check environment variable env := os.Getenv(envVarDockerOrchestrator) - if o := normalize(env); o != orchestratorUnset { - return o + if o, err := normalize(env); o != orchestratorUnset { + return o, err } // Check specified orchestrator - if o := normalize(value); o != orchestratorUnset { - return o - } - - if value != "" { - fmt.Fprintf(os.Stderr, "Specified orchestrator %q is invalid. Please use either kubernetes or swarm\n", value) + if o, err := normalize(value); o != orchestratorUnset { + return o, err } // Nothing set, use default orchestrator - return defaultOrchestrator + return defaultOrchestrator, nil } diff --git a/components/cli/cli/command/service/opts.go b/components/cli/cli/command/service/opts.go index 69cecbbf02..6d42745156 100644 --- a/components/cli/cli/command/service/opts.go +++ b/components/cli/cli/command/service/opts.go @@ -645,7 +645,7 @@ func (options *serviceOptions) ToService(ctx context.Context, apiClient client.N }, Mode: serviceMode, UpdateConfig: options.update.updateConfig(flags), - RollbackConfig: options.update.rollbackConfig(flags), + RollbackConfig: options.rollback.rollbackConfig(flags), EndpointSpec: options.endpoint.ToEndpointSpec(), } diff --git a/components/cli/cli/command/service/opts_test.go b/components/cli/cli/command/service/opts_test.go index 0ef8ff9e2f..0cacffec93 100644 --- a/components/cli/cli/command/service/opts_test.go +++ b/components/cli/cli/command/service/opts_test.go @@ -162,3 +162,65 @@ func TestToServiceNetwork(t *testing.T) { assert.NilError(t, err) assert.Check(t, is.DeepEqual([]swarm.NetworkAttachmentConfig{{Target: "id111"}, {Target: "id555"}, {Target: "id999"}}, service.TaskTemplate.Networks)) } + +func TestToServiceUpdateRollback(t *testing.T) { + expected := swarm.ServiceSpec{ + UpdateConfig: &swarm.UpdateConfig{ + Parallelism: 23, + Delay: 34 * time.Second, + Monitor: 54321 * time.Nanosecond, + FailureAction: "pause", + MaxFailureRatio: 0.6, + Order: "stop-first", + }, + RollbackConfig: &swarm.UpdateConfig{ + Parallelism: 12, + Delay: 23 * time.Second, + Monitor: 12345 * time.Nanosecond, + FailureAction: "continue", + MaxFailureRatio: 0.5, + Order: "start-first", + }, + } + + // Note: in test-situation, the flags are only used to detect if an option + // was set; the actual value itself is read from the serviceOptions below. + flags := newCreateCommand(nil).Flags() + flags.Set("update-parallelism", "23") + flags.Set("update-delay", "34s") + flags.Set("update-monitor", "54321ns") + flags.Set("update-failure-action", "pause") + flags.Set("update-max-failure-ratio", "0.6") + flags.Set("update-order", "stop-first") + + flags.Set("rollback-parallelism", "12") + flags.Set("rollback-delay", "23s") + flags.Set("rollback-monitor", "12345ns") + flags.Set("rollback-failure-action", "continue") + flags.Set("rollback-max-failure-ratio", "0.5") + flags.Set("rollback-order", "start-first") + + o := newServiceOptions() + o.mode = "replicated" + o.update = updateOptions{ + parallelism: 23, + delay: 34 * time.Second, + monitor: 54321 * time.Nanosecond, + onFailure: "pause", + maxFailureRatio: 0.6, + order: "stop-first", + } + o.rollback = updateOptions{ + parallelism: 12, + delay: 23 * time.Second, + monitor: 12345 * time.Nanosecond, + onFailure: "continue", + maxFailureRatio: 0.5, + order: "start-first", + } + + service, err := o.ToService(context.Background(), &fakeClient{}, flags) + assert.NilError(t, err) + assert.Check(t, is.DeepEqual(service.UpdateConfig, expected.UpdateConfig)) + assert.Check(t, is.DeepEqual(service.RollbackConfig, expected.RollbackConfig)) +} diff --git a/components/cli/dockerfiles/Dockerfile.binary-native b/components/cli/dockerfiles/Dockerfile.binary-native index 151aea1ac3..ea76ce5fb5 100644 --- a/components/cli/dockerfiles/Dockerfile.binary-native +++ b/components/cli/dockerfiles/Dockerfile.binary-native @@ -1,4 +1,4 @@ -FROM golang:1.9.5-alpine3.6 +FROM golang:1.10.2-alpine RUN apk add -U git bash coreutils gcc musl-dev diff --git a/components/cli/dockerfiles/Dockerfile.cross b/components/cli/dockerfiles/Dockerfile.cross index d639c2de7f..8bc5c2ea4e 100644 --- a/components/cli/dockerfiles/Dockerfile.cross +++ b/components/cli/dockerfiles/Dockerfile.cross @@ -1,3 +1,3 @@ -FROM dockercore/golang-cross:1.9.5@sha256:4d090b8c2e6d369a48254c882a4e653ba90caaa0b758105da772d9110394d958 +FROM dockercore/golang-cross:1.10.2@sha256:297fa4bc113facd7a528699919f86009420a6b5bedbdc89da35c14f7fee047e1 ENV DISABLE_WARN_OUTSIDE_CONTAINER=1 WORKDIR /go/src/github.com/docker/cli diff --git a/components/cli/dockerfiles/Dockerfile.dev b/components/cli/dockerfiles/Dockerfile.dev index dde0027d82..0ca807870d 100644 --- a/components/cli/dockerfiles/Dockerfile.dev +++ b/components/cli/dockerfiles/Dockerfile.dev @@ -1,5 +1,5 @@ -FROM golang:1.9.5-alpine3.6 +FROM golang:1.10.2-alpine RUN apk add -U git make bash coreutils ca-certificates curl diff --git a/components/cli/dockerfiles/Dockerfile.lint b/components/cli/dockerfiles/Dockerfile.lint index f4c2fe106c..7113062c65 100644 --- a/components/cli/dockerfiles/Dockerfile.lint +++ b/components/cli/dockerfiles/Dockerfile.lint @@ -1,4 +1,4 @@ -FROM golang:1.9.5-alpine3.6 +FROM golang:1.10.2-alpine RUN apk add -U git diff --git a/components/cli/docs/reference/commandline/stats.md b/components/cli/docs/reference/commandline/stats.md index d8d86da6a9..702e99a92c 100644 --- a/components/cli/docs/reference/commandline/stats.md +++ b/components/cli/docs/reference/commandline/stats.md @@ -36,6 +36,8 @@ If you want more detailed information about a container's resource usage, use th > **Note**: On Linux, the Docker CLI reports memory usage by subtracting page cache usage from the total memory usage. The API does not perform such a calculation but rather provides the total memory usage and the amount from the page cache so that clients can use the data as needed. +> **Note**: The `PIDS` column contains the number of processes and kernel threads created by that container. Threads is the term used by Linux kernel. Other equivalent terms are "lightweight process" or "kernel task", etc. A large number in the `PIDS` column combined with a small number of processes (as reported by `ps` or `top`) may indicate that something in the container is creating many threads. + ## Examples Running `docker stats` on all running containers against a Linux daemon.