diff --git a/components/cli/.github/CODEOWNERS b/components/cli/.github/CODEOWNERS new file mode 100644 index 0000000000..855eff98ab --- /dev/null +++ b/components/cli/.github/CODEOWNERS @@ -0,0 +1,8 @@ +# Github code owners +# See https://github.com/blog/2392-introducing-code-owners + +cli/compose/* @dnephin @vdemeester +contrib/completion/bash/* @albers +contrib/completion/zsh/* @sdurrheimer +docs/* @mstanleyjones @vdemeester @thaJeztah +scripts/* @dnephin diff --git a/components/cli/circle.yml b/components/cli/circle.yml index 2035a25f54..4552ee6dd9 100644 --- a/components/cli/circle.yml +++ b/components/cli/circle.yml @@ -7,7 +7,9 @@ jobs: docker: [{image: 'docker:17.05-git'}] steps: - checkout - - setup_remote_docker + - setup_remote_docker: + reusable: true + exclusive: false - run: command: docker version - run: @@ -15,23 +17,32 @@ jobs: command: | dockerfile=dockerfiles/Dockerfile.lint echo "COPY . ." >> $dockerfile - docker build -f $dockerfile --tag cli-linter . - docker run cli-linter + docker build -f $dockerfile --tag cli-linter:$CIRCLE_BUILD_NUM . + docker run --rm cli-linter:$CIRCLE_BUILD_NUM cross: working_directory: /work docker: [{image: 'docker:17.05-git'}] + parallelism: 3 steps: - checkout - - setup_remote_docker + - setup_remote_docker: + reusable: true + exclusive: false - run: name: "Cross" command: | dockerfile=dockerfiles/Dockerfile.cross echo "COPY . ." >> $dockerfile - docker build -f $dockerfile --tag cli-builder . - docker run --name cross cli-builder make cross - docker cp cross:/go/src/github.com/docker/cli/build /work/build + docker build -f $dockerfile --tag cli-builder:$CIRCLE_BUILD_NUM . + name=cross-$CIRCLE_BUILD_NUM-$CIRCLE_NODE_INDEX + docker run \ + -e CROSS_GROUP=$CIRCLE_NODE_INDEX \ + --name $name cli-builder:$CIRCLE_BUILD_NUM \ + make cross + docker cp \ + $name:/go/src/github.com/docker/cli/build \ + /work/build - store_artifacts: path: /work/build @@ -40,19 +51,25 @@ jobs: docker: [{image: 'docker:17.05-git'}] steps: - checkout - - setup_remote_docker + - setup_remote_docker: + reusable: true + exclusive: false - run: name: "Unit Test with Coverage" command: | dockerfile=dockerfiles/Dockerfile.dev echo "COPY . ." >> $dockerfile - docker build -f $dockerfile --tag cli-builder . - docker run --name test cli-builder make test-coverage + docker build -f $dockerfile --tag cli-builder:$CIRCLE_BUILD_NUM . + docker run --name \ + test-$CIRCLE_BUILD_NUM cli-builder:$CIRCLE_BUILD_NUM \ + make test-coverage - run: name: "Upload to Codecov" command: | - docker cp test:/go/src/github.com/docker/cli/coverage.txt coverage.txt + docker cp \ + test-$CIRCLE_BUILD_NUM:/go/src/github.com/docker/cli/coverage.txt \ + coverage.txt apk add -U bash curl curl -s https://codecov.io/bash | bash @@ -60,16 +77,20 @@ jobs: working_directory: /work docker: [{image: 'docker:17.05-git'}] steps: + - run: apk add -U git openssh - checkout - - setup_remote_docker + - setup_remote_docker: + reusable: true + exclusive: false - run: name: "Validate Vendor, Docs, and Code Generation" command: | dockerfile=dockerfiles/Dockerfile.dev echo "COPY . ." >> $dockerfile rm -f .dockerignore # include .git - docker build -f $dockerfile --tag cli-builder . - docker run cli-builder make -B vendor compose-jsonschema manpages yamldocs + docker build -f $dockerfile --tag cli-builder-with-git:$CIRCLE_BUILD_NUM . + docker run --rm cli-builder-with-git:$CIRCLE_BUILD_NUM \ + make -B vendor compose-jsonschema manpages yamldocs workflows: version: 2 diff --git a/components/cli/cli/command/checkpoint/client_test.go b/components/cli/cli/command/checkpoint/client_test.go new file mode 100644 index 0000000000..ca91719617 --- /dev/null +++ b/components/cli/cli/command/checkpoint/client_test.go @@ -0,0 +1,35 @@ +package checkpoint + +import ( + "github.com/docker/docker/api/types" + "github.com/docker/docker/client" + "golang.org/x/net/context" +) + +type fakeClient struct { + client.Client + checkpointCreateFunc func(container string, options types.CheckpointCreateOptions) error + checkpointDeleteFunc func(container string, options types.CheckpointDeleteOptions) error + checkpointListFunc func(container string, options types.CheckpointListOptions) ([]types.Checkpoint, error) +} + +func (cli *fakeClient) CheckpointCreate(ctx context.Context, container string, options types.CheckpointCreateOptions) error { + if cli.checkpointCreateFunc != nil { + return cli.checkpointCreateFunc(container, options) + } + return nil +} + +func (cli *fakeClient) CheckpointDelete(ctx context.Context, container string, options types.CheckpointDeleteOptions) error { + if cli.checkpointDeleteFunc != nil { + return cli.checkpointDeleteFunc(container, options) + } + return nil +} + +func (cli *fakeClient) CheckpointList(ctx context.Context, container string, options types.CheckpointListOptions) ([]types.Checkpoint, error) { + if cli.checkpointListFunc != nil { + return cli.checkpointListFunc(container, options) + } + return []types.Checkpoint{}, nil +} diff --git a/components/cli/cli/command/checkpoint/create_test.go b/components/cli/cli/command/checkpoint/create_test.go new file mode 100644 index 0000000000..d0d47f456a --- /dev/null +++ b/components/cli/cli/command/checkpoint/create_test.go @@ -0,0 +1,72 @@ +package checkpoint + +import ( + "io/ioutil" + "strings" + "testing" + + "github.com/docker/cli/cli/internal/test" + "github.com/docker/docker/api/types" + "github.com/docker/docker/pkg/testutil" + "github.com/pkg/errors" + "github.com/stretchr/testify/assert" +) + +func TestCheckpointCreateErrors(t *testing.T) { + testCases := []struct { + args []string + checkpointCreateFunc func(container string, options types.CheckpointCreateOptions) error + expectedError string + }{ + { + args: []string{"too-few-arguments"}, + expectedError: "requires exactly 2 argument(s)", + }, + { + args: []string{"too", "many", "arguments"}, + expectedError: "requires exactly 2 argument(s)", + }, + { + args: []string{"foo", "bar"}, + checkpointCreateFunc: func(container string, options types.CheckpointCreateOptions) error { + return errors.Errorf("error creating checkpoint for container foo") + }, + expectedError: "error creating checkpoint for container foo", + }, + } + + for _, tc := range testCases { + cli := test.NewFakeCli(&fakeClient{ + checkpointCreateFunc: tc.checkpointCreateFunc, + }) + cmd := newCreateCommand(cli) + cmd.SetArgs(tc.args) + cmd.SetOutput(ioutil.Discard) + testutil.ErrorContains(t, cmd.Execute(), tc.expectedError) + } +} + +func TestCheckpointCreateWithOptions(t *testing.T) { + var containerID, checkpointID, checkpointDir string + var exit bool + cli := test.NewFakeCli(&fakeClient{ + checkpointCreateFunc: func(container string, options types.CheckpointCreateOptions) error { + containerID = container + checkpointID = options.CheckpointID + checkpointDir = options.CheckpointDir + exit = options.Exit + return nil + }, + }) + cmd := newCreateCommand(cli) + checkpoint := "checkpoint-bar" + cmd.SetArgs([]string{"container-foo", checkpoint}) + cmd.Flags().Set("leave-running", "true") + cmd.Flags().Set("checkpoint-dir", "/dir/foo") + assert.NoError(t, cmd.Execute()) + assert.Equal(t, "container-foo", containerID) + assert.Equal(t, checkpoint, checkpointID) + assert.Equal(t, "/dir/foo", checkpointDir) + assert.Equal(t, false, exit) + assert.Equal(t, checkpoint, strings.TrimSpace(cli.OutBuffer().String())) +} diff --git a/components/cli/cli/command/checkpoint/list_test.go b/components/cli/cli/command/checkpoint/list_test.go new file mode 100644 index 0000000000..1c13f27755 --- /dev/null +++ b/components/cli/cli/command/checkpoint/list_test.go @@ -0,0 +1,71 @@ +package checkpoint + +import ( + "bytes" + "io/ioutil" + "testing" + + "github.com/docker/cli/cli/internal/test" + "github.com/docker/docker/api/types" + "github.com/docker/docker/pkg/testutil" + "github.com/docker/docker/pkg/testutil/golden" + "github.com/pkg/errors" + "github.com/stretchr/testify/assert" +) + +func TestCheckpointListErrors(t *testing.T) { + testCases := []struct { + args []string + checkpointListFunc func(container string, options types.CheckpointListOptions) ([]types.Checkpoint, error) + expectedError string + }{ + { + args: []string{}, + expectedError: "requires exactly 1 argument", + }, + { + args: []string{"too", "many", "arguments"}, + expectedError: "requires exactly 1 argument", + }, + { + args: []string{"foo"}, + checkpointListFunc: func(container string, options types.CheckpointListOptions) ([]types.Checkpoint, error) { + return []types.Checkpoint{}, errors.Errorf("error getting checkpoints for container foo") + }, + expectedError: "error getting checkpoints for container foo", + }, + } + + for _, tc := range testCases { + cli := test.NewFakeCliWithOutput(&fakeClient{ + checkpointListFunc: tc.checkpointListFunc, + }, &bytes.Buffer{}) + cmd := newListCommand(cli) + cmd.SetArgs(tc.args) + cmd.SetOutput(ioutil.Discard) + testutil.ErrorContains(t, cmd.Execute(), tc.expectedError) + } +} + +func TestCheckpointListWithOptions(t *testing.T) { + var containerID, checkpointDir string + buf := new(bytes.Buffer) + cli := test.NewFakeCliWithOutput(&fakeClient{ + checkpointListFunc: func(container string, options types.CheckpointListOptions) ([]types.Checkpoint, error) { + containerID = container + checkpointDir = options.CheckpointDir + return []types.Checkpoint{ + {Name: "checkpoint-foo"}, + }, nil + }, + }, buf) + cmd := newListCommand(cli) + cmd.SetArgs([]string{"container-foo"}) + cmd.Flags().Set("checkpoint-dir", "/dir/foo") + assert.NoError(t, cmd.Execute()) + assert.Equal(t, "container-foo", containerID) + assert.Equal(t, "/dir/foo", checkpointDir) + actual := buf.String() + expected := golden.Get(t, []byte(actual), "checkpoint-list-with-options.golden") + testutil.EqualNormalizedString(t, testutil.RemoveSpace, actual, string(expected)) +} diff --git a/components/cli/cli/command/checkpoint/remove_test.go b/components/cli/cli/command/checkpoint/remove_test.go new file mode 100644 index 0000000000..ecc66d8be5 --- /dev/null +++ b/components/cli/cli/command/checkpoint/remove_test.go @@ -0,0 +1,66 @@ +package checkpoint + +import ( + "bytes" + "io/ioutil" + "testing" + + "github.com/docker/cli/cli/internal/test" + "github.com/docker/docker/api/types" + "github.com/docker/docker/pkg/testutil" + "github.com/pkg/errors" + "github.com/stretchr/testify/assert" +) + +func TestCheckpointRemoveErrors(t *testing.T) { + testCases := []struct { + args []string + checkpointDeleteFunc func(container string, options types.CheckpointDeleteOptions) error + expectedError string + }{ + { + args: []string{"too-few-arguments"}, + expectedError: "requires exactly 2 argument(s)", + }, + { + args: []string{"too", "many", "arguments"}, + expectedError: "requires exactly 2 argument(s)", + }, + { + args: []string{"foo", "bar"}, + checkpointDeleteFunc: func(container string, options types.CheckpointDeleteOptions) error { + return errors.Errorf("error deleting checkpoint") + }, + expectedError: "error deleting checkpoint", + }, + } + + for _, tc := range testCases { + cli := test.NewFakeCliWithOutput(&fakeClient{ + checkpointDeleteFunc: tc.checkpointDeleteFunc, + }, &bytes.Buffer{}) + cmd := newRemoveCommand(cli) + cmd.SetArgs(tc.args) + cmd.SetOutput(ioutil.Discard) + testutil.ErrorContains(t, cmd.Execute(), tc.expectedError) + } +} + +func TestCheckpointRemoveWithOptions(t *testing.T) { + var containerID, checkpointID, checkpointDir string + cli := test.NewFakeCliWithOutput(&fakeClient{ + checkpointDeleteFunc: func(container string, options types.CheckpointDeleteOptions) error { + containerID = container + checkpointID = options.CheckpointID + checkpointDir = options.CheckpointDir + return nil + }, + }, &bytes.Buffer{}) + cmd := newRemoveCommand(cli) + cmd.SetArgs([]string{"container-foo", "checkpoint-bar"}) + cmd.Flags().Set("checkpoint-dir", "/dir/foo") + assert.NoError(t, cmd.Execute()) + assert.Equal(t, "container-foo", containerID) + assert.Equal(t, "checkpoint-bar", checkpointID) + assert.Equal(t, "/dir/foo", checkpointDir) +} diff --git a/components/cli/cli/command/checkpoint/testdata/checkpoint-list-with-options.golden b/components/cli/cli/command/checkpoint/testdata/checkpoint-list-with-options.golden new file mode 100644 index 0000000000..f53f016ae9 --- /dev/null +++ b/components/cli/cli/command/checkpoint/testdata/checkpoint-list-with-options.golden @@ -0,0 +1,2 @@ +CHECKPOINT NAME +checkpoint-foo diff --git a/components/cli/cli/command/config/create_test.go b/components/cli/cli/command/config/create_test.go index 25b133836f..5cdafbdbf4 100644 --- a/components/cli/cli/command/config/create_test.go +++ b/components/cli/cli/command/config/create_test.go @@ -1,7 +1,6 @@ package config import ( - "bytes" "io/ioutil" "path/filepath" "reflect" @@ -41,11 +40,10 @@ func TestConfigCreateErrors(t *testing.T) { }, } for _, tc := range testCases { - buf := new(bytes.Buffer) cmd := newConfigCreateCommand( test.NewFakeCli(&fakeClient{ configCreateFunc: tc.configCreateFunc, - }, buf), + }), ) cmd.SetArgs(tc.args) cmd.SetOutput(ioutil.Discard) @@ -55,7 +53,6 @@ func TestConfigCreateErrors(t *testing.T) { func TestConfigCreateWithName(t *testing.T) { name := "foo" - buf := new(bytes.Buffer) var actual []byte cli := test.NewFakeCli(&fakeClient{ configCreateFunc: func(spec swarm.ConfigSpec) (types.ConfigCreateResponse, error) { @@ -69,14 +66,14 @@ func TestConfigCreateWithName(t *testing.T) { ID: "ID-" + spec.Name, }, nil }, - }, buf) + }) cmd := newConfigCreateCommand(cli) cmd.SetArgs([]string{name, filepath.Join("testdata", configDataFile)}) assert.NoError(t, cmd.Execute()) expected := golden.Get(t, actual, configDataFile) assert.Equal(t, string(expected), string(actual)) - assert.Equal(t, "ID-"+name, strings.TrimSpace(buf.String())) + assert.Equal(t, "ID-"+name, strings.TrimSpace(cli.OutBuffer().String())) } func TestConfigCreateWithLabels(t *testing.T) { @@ -86,7 +83,6 @@ func TestConfigCreateWithLabels(t *testing.T) { } name := "foo" - buf := new(bytes.Buffer) cli := test.NewFakeCli(&fakeClient{ configCreateFunc: func(spec swarm.ConfigSpec) (types.ConfigCreateResponse, error) { if spec.Name != name { @@ -101,12 +97,12 @@ func TestConfigCreateWithLabels(t *testing.T) { ID: "ID-" + spec.Name, }, nil }, - }, buf) + }) cmd := newConfigCreateCommand(cli) cmd.SetArgs([]string{name, filepath.Join("testdata", configDataFile)}) cmd.Flags().Set("label", "lbl1=Label-foo") cmd.Flags().Set("label", "lbl2=Label-bar") assert.NoError(t, cmd.Execute()) - assert.Equal(t, "ID-"+name, strings.TrimSpace(buf.String())) + assert.Equal(t, "ID-"+name, strings.TrimSpace(cli.OutBuffer().String())) } diff --git a/components/cli/cli/command/config/inspect_test.go b/components/cli/cli/command/config/inspect_test.go index 69d36cb7ad..e1af0b6b09 100644 --- a/components/cli/cli/command/config/inspect_test.go +++ b/components/cli/cli/command/config/inspect_test.go @@ -55,7 +55,7 @@ func TestConfigInspectErrors(t *testing.T) { for _, tc := range testCases { buf := new(bytes.Buffer) cmd := newConfigInspectCommand( - test.NewFakeCli(&fakeClient{ + test.NewFakeCliWithOutput(&fakeClient{ configInspectFunc: tc.configInspectFunc, }, buf), ) @@ -97,7 +97,7 @@ func TestConfigInspectWithoutFormat(t *testing.T) { for _, tc := range testCases { buf := new(bytes.Buffer) cmd := newConfigInspectCommand( - test.NewFakeCli(&fakeClient{ + test.NewFakeCliWithOutput(&fakeClient{ configInspectFunc: tc.configInspectFunc, }, buf), ) @@ -137,7 +137,7 @@ func TestConfigInspectWithFormat(t *testing.T) { for _, tc := range testCases { buf := new(bytes.Buffer) cmd := newConfigInspectCommand( - test.NewFakeCli(&fakeClient{ + test.NewFakeCliWithOutput(&fakeClient{ configInspectFunc: tc.configInspectFunc, }, buf), ) @@ -174,7 +174,7 @@ func TestConfigInspectPretty(t *testing.T) { for _, tc := range testCases { buf := new(bytes.Buffer) cmd := newConfigInspectCommand( - test.NewFakeCli(&fakeClient{ + test.NewFakeCliWithOutput(&fakeClient{ configInspectFunc: tc.configInspectFunc, }, buf)) cmd.SetArgs([]string{"configID"}) diff --git a/components/cli/cli/command/config/ls_test.go b/components/cli/cli/command/config/ls_test.go index b43c764a4d..c8393caca5 100644 --- a/components/cli/cli/command/config/ls_test.go +++ b/components/cli/cli/command/config/ls_test.go @@ -1,7 +1,6 @@ package config import ( - "bytes" "io/ioutil" "testing" "time" @@ -36,11 +35,10 @@ func TestConfigListErrors(t *testing.T) { }, } for _, tc := range testCases { - buf := new(bytes.Buffer) cmd := newConfigListCommand( test.NewFakeCli(&fakeClient{ configListFunc: tc.configListFunc, - }, buf), + }), ) cmd.SetArgs(tc.args) cmd.SetOutput(ioutil.Discard) @@ -49,7 +47,6 @@ func TestConfigListErrors(t *testing.T) { } func TestConfigList(t *testing.T) { - buf := new(bytes.Buffer) cli := test.NewFakeCli(&fakeClient{ configListFunc: func(options types.ConfigListOptions) ([]swarm.Config, error) { return []swarm.Config{ @@ -67,18 +64,16 @@ func TestConfigList(t *testing.T) { ), }, nil }, - }, buf) - cli.SetConfigfile(&configfile.ConfigFile{}) + }) cmd := newConfigListCommand(cli) - cmd.SetOutput(buf) + cmd.SetOutput(cli.OutBuffer()) assert.NoError(t, cmd.Execute()) - actual := buf.String() + actual := cli.OutBuffer().String() expected := golden.Get(t, []byte(actual), "config-list.golden") testutil.EqualNormalizedString(t, testutil.RemoveSpace, actual, string(expected)) } func TestConfigListWithQuietOption(t *testing.T) { - buf := new(bytes.Buffer) cli := test.NewFakeCli(&fakeClient{ configListFunc: func(options types.ConfigListOptions) ([]swarm.Config, error) { return []swarm.Config{ @@ -88,18 +83,16 @@ func TestConfigListWithQuietOption(t *testing.T) { })), }, nil }, - }, buf) - cli.SetConfigfile(&configfile.ConfigFile{}) + }) cmd := newConfigListCommand(cli) cmd.Flags().Set("quiet", "true") assert.NoError(t, cmd.Execute()) - actual := buf.String() + actual := cli.OutBuffer().String() expected := golden.Get(t, []byte(actual), "config-list-with-quiet-option.golden") testutil.EqualNormalizedString(t, testutil.RemoveSpace, actual, string(expected)) } func TestConfigListWithConfigFormat(t *testing.T) { - buf := new(bytes.Buffer) cli := test.NewFakeCli(&fakeClient{ configListFunc: func(options types.ConfigListOptions) ([]swarm.Config, error) { return []swarm.Config{ @@ -109,19 +102,18 @@ func TestConfigListWithConfigFormat(t *testing.T) { })), }, nil }, - }, buf) - cli.SetConfigfile(&configfile.ConfigFile{ + }) + cli.SetConfigFile(&configfile.ConfigFile{ ConfigFormat: "{{ .Name }} {{ .Labels }}", }) cmd := newConfigListCommand(cli) assert.NoError(t, cmd.Execute()) - actual := buf.String() + actual := cli.OutBuffer().String() expected := golden.Get(t, []byte(actual), "config-list-with-config-format.golden") testutil.EqualNormalizedString(t, testutil.RemoveSpace, actual, string(expected)) } func TestConfigListWithFormat(t *testing.T) { - buf := new(bytes.Buffer) cli := test.NewFakeCli(&fakeClient{ configListFunc: func(options types.ConfigListOptions) ([]swarm.Config, error) { return []swarm.Config{ @@ -131,17 +123,16 @@ func TestConfigListWithFormat(t *testing.T) { })), }, nil }, - }, buf) + }) cmd := newConfigListCommand(cli) cmd.Flags().Set("format", "{{ .Name }} {{ .Labels }}") assert.NoError(t, cmd.Execute()) - actual := buf.String() + actual := cli.OutBuffer().String() expected := golden.Get(t, []byte(actual), "config-list-with-format.golden") testutil.EqualNormalizedString(t, testutil.RemoveSpace, actual, string(expected)) } func TestConfigListWithFilter(t *testing.T) { - buf := new(bytes.Buffer) cli := test.NewFakeCli(&fakeClient{ configListFunc: func(options types.ConfigListOptions) ([]swarm.Config, error) { assert.Equal(t, "foo", options.Filters.Get("name")[0]) @@ -161,13 +152,12 @@ func TestConfigListWithFilter(t *testing.T) { ), }, nil }, - }, buf) - cli.SetConfigfile(&configfile.ConfigFile{}) + }) cmd := newConfigListCommand(cli) cmd.Flags().Set("filter", "name=foo") cmd.Flags().Set("filter", "label=lbl1=Label-bar") assert.NoError(t, cmd.Execute()) - actual := buf.String() + actual := cli.OutBuffer().String() expected := golden.Get(t, []byte(actual), "config-list-with-filter.golden") testutil.EqualNormalizedString(t, testutil.RemoveSpace, actual, string(expected)) } diff --git a/components/cli/cli/command/config/remove_test.go b/components/cli/cli/command/config/remove_test.go index c183a93c8b..85b188c41d 100644 --- a/components/cli/cli/command/config/remove_test.go +++ b/components/cli/cli/command/config/remove_test.go @@ -33,7 +33,7 @@ func TestConfigRemoveErrors(t *testing.T) { for _, tc := range testCases { buf := new(bytes.Buffer) cmd := newConfigRemoveCommand( - test.NewFakeCli(&fakeClient{ + test.NewFakeCliWithOutput(&fakeClient{ configRemoveFunc: tc.configRemoveFunc, }, buf), ) @@ -47,7 +47,7 @@ func TestConfigRemoveWithName(t *testing.T) { names := []string{"foo", "bar"} buf := new(bytes.Buffer) var removedConfigs []string - cli := test.NewFakeCli(&fakeClient{ + cli := test.NewFakeCliWithOutput(&fakeClient{ configRemoveFunc: func(name string) error { removedConfigs = append(removedConfigs, name) return nil @@ -65,7 +65,7 @@ func TestConfigRemoveContinueAfterError(t *testing.T) { buf := new(bytes.Buffer) var removedConfigs []string - cli := test.NewFakeCli(&fakeClient{ + cli := test.NewFakeCliWithOutput(&fakeClient{ configRemoveFunc: func(name string) error { removedConfigs = append(removedConfigs, name) if name == "foo" { diff --git a/components/cli/cli/command/container/attach_test.go b/components/cli/cli/command/container/attach_test.go index 14b8137dae..a33eeeeb54 100644 --- a/components/cli/cli/command/container/attach_test.go +++ b/components/cli/cli/command/container/attach_test.go @@ -1,7 +1,6 @@ package container import ( - "bytes" "io/ioutil" "testing" @@ -68,8 +67,7 @@ func TestNewAttachCommandErrors(t *testing.T) { }, } for _, tc := range testCases { - buf := new(bytes.Buffer) - cmd := NewAttachCommand(test.NewFakeCli(&fakeClient{containerInspectFunc: tc.containerInspectFunc}, buf)) + cmd := NewAttachCommand(test.NewFakeCli(&fakeClient{containerInspectFunc: tc.containerInspectFunc})) cmd.SetOutput(ioutil.Discard) cmd.SetArgs(tc.args) testutil.ErrorContains(t, cmd.Execute(), tc.expectedError) diff --git a/components/cli/cli/command/container/exec_test.go b/components/cli/cli/command/container/exec_test.go index b2df1c2b0c..0eed2ff0f7 100644 --- a/components/cli/cli/command/container/exec_test.go +++ b/components/cli/cli/command/container/exec_test.go @@ -1,15 +1,14 @@ package container import ( - "bytes" "io/ioutil" "testing" - "github.com/docker/cli/cli/config/configfile" "github.com/docker/cli/cli/internal/test" "github.com/docker/docker/api/types" "github.com/docker/docker/pkg/testutil" "github.com/pkg/errors" + "github.com/stretchr/testify/require" ) type arguments struct { @@ -79,9 +78,7 @@ func TestParseExec(t *testing.T) { for valid, expectedExecConfig := range valids { execConfig, err := parseExec(&valid.options, valid.execCmd) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) if !compareExecConfig(expectedExecConfig, execConfig) { t.Fatalf("Expected [%v] for %v, got [%v]", expectedExecConfig, valid, execConfig) } @@ -138,10 +135,7 @@ func TestNewExecCommandErrors(t *testing.T) { }, } for _, tc := range testCases { - buf := new(bytes.Buffer) - conf := configfile.ConfigFile{} - cli := test.NewFakeCli(&fakeClient{containerInspectFunc: tc.containerInspectFunc}, buf) - cli.SetConfigfile(&conf) + cli := test.NewFakeCli(&fakeClient{containerInspectFunc: tc.containerInspectFunc}) cmd := NewExecCommand(cli) cmd.SetOutput(ioutil.Discard) cmd.SetArgs(tc.args) diff --git a/components/cli/cli/command/container/run.go b/components/cli/cli/command/container/run.go index 56f0d0d57b..695a5cf9ae 100644 --- a/components/cli/cli/command/container/run.go +++ b/components/cli/cli/command/container/run.go @@ -190,10 +190,11 @@ func runContainer(dockerCli *command.DockerCli, opts *runOptions, copts *contain } close, err := attachContainer(ctx, dockerCli, &errCh, config, createResponse.ID) - defer close() + if err != nil { return err } + defer close() } statusChan := waitExitOrRemoved(ctx, dockerCli, createResponse.ID, copts.autoRemove) diff --git a/components/cli/cli/command/formatter/disk_usage.go b/components/cli/cli/command/formatter/disk_usage.go index 2c73d82987..5681f296cb 100644 --- a/components/cli/cli/command/formatter/disk_usage.go +++ b/components/cli/cli/command/formatter/disk_usage.go @@ -243,7 +243,7 @@ func (c *diskUsageImagesContext) Reclaimable() string { if c.totalSize > 0 { return fmt.Sprintf("%s (%v%%)", units.HumanSize(float64(reclaimable)), (reclaimable*100)/c.totalSize) } - return fmt.Sprintf("%s", units.HumanSize(float64(reclaimable))) + return units.HumanSize(float64(reclaimable)) } type diskUsageContainersContext struct { @@ -305,7 +305,7 @@ func (c *diskUsageContainersContext) Reclaimable() string { return fmt.Sprintf("%s (%v%%)", units.HumanSize(float64(reclaimable)), (reclaimable*100)/totalSize) } - return fmt.Sprintf("%s", units.HumanSize(float64(reclaimable))) + return units.HumanSize(float64(reclaimable)) } type diskUsageVolumesContext struct { @@ -366,7 +366,7 @@ func (c *diskUsageVolumesContext) Reclaimable() string { return fmt.Sprintf("%s (%v%%)", units.HumanSize(float64(reclaimable)), (reclaimable*100)/totalSize) } - return fmt.Sprintf("%s", units.HumanSize(float64(reclaimable))) + return units.HumanSize(float64(reclaimable)) } type diskUsageBuilderContext struct { diff --git a/components/cli/cli/command/formatter/stats.go b/components/cli/cli/command/formatter/stats.go index f53387e90a..06eedc7158 100644 --- a/components/cli/cli/command/formatter/stats.go +++ b/components/cli/cli/command/formatter/stats.go @@ -184,7 +184,7 @@ func (c *containerStatsContext) MemUsage() string { return fmt.Sprintf("-- / --") } if c.os == winOSType { - return fmt.Sprintf("%s", units.BytesSize(c.s.Memory)) + return units.BytesSize(c.s.Memory) } return fmt.Sprintf("%s / %s", units.BytesSize(c.s.Memory), units.BytesSize(c.s.MemoryLimit)) } diff --git a/components/cli/cli/command/image/build_test.go b/components/cli/cli/command/image/build_test.go index bf77292a85..b3fb3c6834 100644 --- a/components/cli/cli/command/image/build_test.go +++ b/components/cli/cli/command/image/build_test.go @@ -38,7 +38,7 @@ func TestRunBuildDockerfileFromStdinWithCompress(t *testing.T) { return types.ImageBuildResponse{Body: ioutil.NopCloser(body)}, nil } - cli := test.NewFakeCli(&fakeClient{imageBuildFunc: fakeImageBuild}, ioutil.Discard) + cli := test.NewFakeCli(&fakeClient{imageBuildFunc: fakeImageBuild}) dockerfile := bytes.NewBufferString(` FROM alpine:3.6 COPY foo / diff --git a/components/cli/cli/command/image/history_test.go b/components/cli/cli/command/image/history_test.go index 8582c09b62..b3abd0bef7 100644 --- a/components/cli/cli/command/image/history_test.go +++ b/components/cli/cli/command/image/history_test.go @@ -1,7 +1,6 @@ package image import ( - "bytes" "fmt" "io/ioutil" "regexp" @@ -38,8 +37,7 @@ func TestNewHistoryCommandErrors(t *testing.T) { }, } for _, tc := range testCases { - buf := new(bytes.Buffer) - cmd := NewHistoryCommand(test.NewFakeCli(&fakeClient{imageHistoryFunc: tc.imageHistoryFunc}, buf)) + cmd := NewHistoryCommand(test.NewFakeCli(&fakeClient{imageHistoryFunc: tc.imageHistoryFunc})) cmd.SetOutput(ioutil.Discard) cmd.SetArgs(tc.args) testutil.ErrorContains(t, cmd.Execute(), tc.expectedError) @@ -90,13 +88,13 @@ func TestNewHistoryCommandSuccess(t *testing.T) { }, } for _, tc := range testCases { - buf := new(bytes.Buffer) - cmd := NewHistoryCommand(test.NewFakeCli(&fakeClient{imageHistoryFunc: tc.imageHistoryFunc}, buf)) + cli := test.NewFakeCli(&fakeClient{imageHistoryFunc: tc.imageHistoryFunc}) + cmd := NewHistoryCommand(cli) cmd.SetOutput(ioutil.Discard) cmd.SetArgs(tc.args) err := cmd.Execute() assert.NoError(t, err) - actual := buf.String() + actual := cli.OutBuffer().String() if tc.outputRegex == "" { expected := string(golden.Get(t, []byte(actual), fmt.Sprintf("history-command-success.%s.golden", tc.name))[:]) testutil.EqualNormalizedString(t, testutil.RemoveSpace, actual, expected) diff --git a/components/cli/cli/command/image/import_test.go b/components/cli/cli/command/image/import_test.go index 134722f0f1..6a8e2e0fd1 100644 --- a/components/cli/cli/command/image/import_test.go +++ b/components/cli/cli/command/image/import_test.go @@ -37,7 +37,7 @@ func TestNewImportCommandErrors(t *testing.T) { } for _, tc := range testCases { buf := new(bytes.Buffer) - cmd := NewImportCommand(test.NewFakeCli(&fakeClient{imageImportFunc: tc.imageImportFunc}, buf)) + cmd := NewImportCommand(test.NewFakeCliWithOutput(&fakeClient{imageImportFunc: tc.imageImportFunc}, buf)) cmd.SetOutput(ioutil.Discard) cmd.SetArgs(tc.args) testutil.ErrorContains(t, cmd.Execute(), tc.expectedError) @@ -45,7 +45,7 @@ func TestNewImportCommandErrors(t *testing.T) { } func TestNewImportCommandInvalidFile(t *testing.T) { - cmd := NewImportCommand(test.NewFakeCli(&fakeClient{}, new(bytes.Buffer))) + cmd := NewImportCommand(test.NewFakeCli(&fakeClient{})) cmd.SetOutput(ioutil.Discard) cmd.SetArgs([]string{"testdata/import-command-success.unexistent-file"}) testutil.ErrorContains(t, cmd.Execute(), "testdata/import-command-success.unexistent-file") @@ -92,7 +92,7 @@ func TestNewImportCommandSuccess(t *testing.T) { } for _, tc := range testCases { buf := new(bytes.Buffer) - cmd := NewImportCommand(test.NewFakeCli(&fakeClient{imageImportFunc: tc.imageImportFunc}, buf)) + cmd := NewImportCommand(test.NewFakeCliWithOutput(&fakeClient{imageImportFunc: tc.imageImportFunc}, buf)) cmd.SetOutput(ioutil.Discard) cmd.SetArgs(tc.args) assert.NoError(t, cmd.Execute()) diff --git a/components/cli/cli/command/image/inspect_test.go b/components/cli/cli/command/image/inspect_test.go index b3a2c2f5f5..2f336bdbad 100644 --- a/components/cli/cli/command/image/inspect_test.go +++ b/components/cli/cli/command/image/inspect_test.go @@ -27,7 +27,7 @@ func TestNewInspectCommandErrors(t *testing.T) { } for _, tc := range testCases { buf := new(bytes.Buffer) - cmd := newInspectCommand(test.NewFakeCli(&fakeClient{}, buf)) + cmd := newInspectCommand(test.NewFakeCliWithOutput(&fakeClient{}, buf)) cmd.SetOutput(ioutil.Discard) cmd.SetArgs(tc.args) testutil.ErrorContains(t, cmd.Execute(), tc.expectedError) @@ -79,7 +79,7 @@ func TestNewInspectCommandSuccess(t *testing.T) { for _, tc := range testCases { imageInspectInvocationCount = 0 buf := new(bytes.Buffer) - cmd := newInspectCommand(test.NewFakeCli(&fakeClient{imageInspectFunc: tc.imageInspectFunc}, buf)) + cmd := newInspectCommand(test.NewFakeCliWithOutput(&fakeClient{imageInspectFunc: tc.imageInspectFunc}, buf)) cmd.SetOutput(ioutil.Discard) cmd.SetArgs(tc.args) err := cmd.Execute() diff --git a/components/cli/cli/command/image/list_test.go b/components/cli/cli/command/image/list_test.go index 070b19efb1..b367ef1de1 100644 --- a/components/cli/cli/command/image/list_test.go +++ b/components/cli/cli/command/image/list_test.go @@ -36,7 +36,7 @@ func TestNewImagesCommandErrors(t *testing.T) { }, } for _, tc := range testCases { - cmd := NewImagesCommand(test.NewFakeCli(&fakeClient{imageListFunc: tc.imageListFunc}, new(bytes.Buffer))) + cmd := NewImagesCommand(test.NewFakeCli(&fakeClient{imageListFunc: tc.imageListFunc})) cmd.SetOutput(ioutil.Discard) cmd.SetArgs(tc.args) testutil.ErrorContains(t, cmd.Execute(), tc.expectedError) @@ -81,8 +81,8 @@ func TestNewImagesCommandSuccess(t *testing.T) { } for _, tc := range testCases { buf := new(bytes.Buffer) - cli := test.NewFakeCli(&fakeClient{imageListFunc: tc.imageListFunc}, buf) - cli.SetConfigfile(&configfile.ConfigFile{ImagesFormat: tc.imageFormat}) + cli := test.NewFakeCliWithOutput(&fakeClient{imageListFunc: tc.imageListFunc}, buf) + cli.SetConfigFile(&configfile.ConfigFile{ImagesFormat: tc.imageFormat}) cmd := NewImagesCommand(cli) cmd.SetOutput(ioutil.Discard) cmd.SetArgs(tc.args) @@ -95,7 +95,7 @@ func TestNewImagesCommandSuccess(t *testing.T) { } func TestNewListCommandAlias(t *testing.T) { - cmd := newListCommand(test.NewFakeCli(&fakeClient{}, new(bytes.Buffer))) + cmd := newListCommand(test.NewFakeCli(&fakeClient{})) assert.True(t, cmd.HasAlias("images")) assert.True(t, cmd.HasAlias("list")) assert.False(t, cmd.HasAlias("other")) diff --git a/components/cli/cli/command/image/load_test.go b/components/cli/cli/command/image/load_test.go index ebe1a0c7e3..06446bf650 100644 --- a/components/cli/cli/command/image/load_test.go +++ b/components/cli/cli/command/image/load_test.go @@ -43,7 +43,7 @@ func TestNewLoadCommandErrors(t *testing.T) { }, } for _, tc := range testCases { - cli := test.NewFakeCli(&fakeClient{imageLoadFunc: tc.imageLoadFunc}, new(bytes.Buffer)) + cli := test.NewFakeCli(&fakeClient{imageLoadFunc: tc.imageLoadFunc}) cli.In().SetIsTerminal(tc.isTerminalIn) cmd := NewLoadCommand(cli) cmd.SetOutput(ioutil.Discard) @@ -54,7 +54,7 @@ func TestNewLoadCommandErrors(t *testing.T) { func TestNewLoadCommandInvalidInput(t *testing.T) { expectedError := "open *" - cmd := NewLoadCommand(test.NewFakeCli(&fakeClient{}, new(bytes.Buffer))) + cmd := NewLoadCommand(test.NewFakeCli(&fakeClient{})) cmd.SetOutput(ioutil.Discard) cmd.SetArgs([]string{"--input", "*"}) err := cmd.Execute() @@ -93,7 +93,7 @@ func TestNewLoadCommandSuccess(t *testing.T) { } for _, tc := range testCases { buf := new(bytes.Buffer) - cmd := NewLoadCommand(test.NewFakeCli(&fakeClient{imageLoadFunc: tc.imageLoadFunc}, buf)) + cmd := NewLoadCommand(test.NewFakeCliWithOutput(&fakeClient{imageLoadFunc: tc.imageLoadFunc}, buf)) cmd.SetOutput(ioutil.Discard) cmd.SetArgs(tc.args) err := cmd.Execute() diff --git a/components/cli/cli/command/image/prune_test.go b/components/cli/cli/command/image/prune_test.go index c17a75d224..be25826df0 100644 --- a/components/cli/cli/command/image/prune_test.go +++ b/components/cli/cli/command/image/prune_test.go @@ -38,7 +38,7 @@ func TestNewPruneCommandErrors(t *testing.T) { } for _, tc := range testCases { buf := new(bytes.Buffer) - cmd := NewPruneCommand(test.NewFakeCli(&fakeClient{ + cmd := NewPruneCommand(test.NewFakeCliWithOutput(&fakeClient{ imagesPruneFunc: tc.imagesPruneFunc, }, buf)) cmd.SetOutput(ioutil.Discard) @@ -86,7 +86,7 @@ func TestNewPruneCommandSuccess(t *testing.T) { } for _, tc := range testCases { buf := new(bytes.Buffer) - cmd := NewPruneCommand(test.NewFakeCli(&fakeClient{ + cmd := NewPruneCommand(test.NewFakeCliWithOutput(&fakeClient{ imagesPruneFunc: tc.imagesPruneFunc, }, buf)) cmd.SetOutput(ioutil.Discard) diff --git a/components/cli/cli/command/image/pull_test.go b/components/cli/cli/command/image/pull_test.go index 690e6222eb..c23484f832 100644 --- a/components/cli/cli/command/image/pull_test.go +++ b/components/cli/cli/command/image/pull_test.go @@ -1,12 +1,10 @@ package image import ( - "bytes" "fmt" "io/ioutil" "testing" - "github.com/docker/cli/cli/config/configfile" "github.com/docker/cli/cli/internal/test" "github.com/docker/docker/pkg/testutil" "github.com/docker/docker/pkg/testutil/golden" @@ -41,9 +39,7 @@ func TestNewPullCommandErrors(t *testing.T) { }, } for _, tc := range testCases { - buf := new(bytes.Buffer) - cli := test.NewFakeCli(&fakeClient{}, buf) - cli.SetConfigfile(configfile.New("filename")) + cli := test.NewFakeCli(&fakeClient{}) cmd := NewPullCommand(cli) cmd.SetOutput(ioutil.Discard) cmd.SetArgs(tc.args) @@ -66,15 +62,13 @@ func TestNewPullCommandSuccess(t *testing.T) { }, } for _, tc := range testCases { - buf := new(bytes.Buffer) - cli := test.NewFakeCli(&fakeClient{}, buf) - cli.SetConfigfile(configfile.New("filename")) + cli := test.NewFakeCli(&fakeClient{}) cmd := NewPullCommand(cli) cmd.SetOutput(ioutil.Discard) cmd.SetArgs(tc.args) err := cmd.Execute() assert.NoError(t, err) - actual := buf.String() + actual := cli.OutBuffer().String() expected := string(golden.Get(t, []byte(actual), fmt.Sprintf("pull-command-success.%s.golden", tc.name))[:]) testutil.EqualNormalizedString(t, testutil.RemoveSpace, actual, expected) } diff --git a/components/cli/cli/command/image/push_test.go b/components/cli/cli/command/image/push_test.go index f2c35dee21..2c824c46e2 100644 --- a/components/cli/cli/command/image/push_test.go +++ b/components/cli/cli/command/image/push_test.go @@ -1,13 +1,11 @@ package image import ( - "bytes" "io" "io/ioutil" "strings" "testing" - "github.com/docker/cli/cli/config/configfile" "github.com/docker/cli/cli/internal/test" "github.com/docker/docker/api/types" "github.com/docker/docker/pkg/testutil" @@ -47,9 +45,7 @@ func TestNewPushCommandErrors(t *testing.T) { }, } for _, tc := range testCases { - buf := new(bytes.Buffer) - cli := test.NewFakeCli(&fakeClient{imagePushFunc: tc.imagePushFunc}, buf) - cli.SetConfigfile(configfile.New("filename")) + cli := test.NewFakeCli(&fakeClient{imagePushFunc: tc.imagePushFunc}) cmd := NewPushCommand(cli) cmd.SetOutput(ioutil.Discard) cmd.SetArgs(tc.args) @@ -68,13 +64,11 @@ func TestNewPushCommandSuccess(t *testing.T) { }, } for _, tc := range testCases { - buf := new(bytes.Buffer) cli := test.NewFakeCli(&fakeClient{ imagePushFunc: func(ref string, options types.ImagePushOptions) (io.ReadCloser, error) { return ioutil.NopCloser(strings.NewReader("")), nil }, - }, buf) - cli.SetConfigfile(configfile.New("filename")) + }) cmd := NewPushCommand(cli) cmd.SetOutput(ioutil.Discard) cmd.SetArgs(tc.args) diff --git a/components/cli/cli/command/image/remove_test.go b/components/cli/cli/command/image/remove_test.go index 9b02b24a90..559427247d 100644 --- a/components/cli/cli/command/image/remove_test.go +++ b/components/cli/cli/command/image/remove_test.go @@ -1,7 +1,6 @@ package image import ( - "bytes" "fmt" "io/ioutil" "testing" @@ -15,7 +14,7 @@ import ( ) func TestNewRemoveCommandAlias(t *testing.T) { - cmd := newRemoveCommand(test.NewFakeCli(&fakeClient{}, new(bytes.Buffer))) + cmd := newRemoveCommand(test.NewFakeCli(&fakeClient{})) assert.True(t, cmd.HasAlias("rmi")) assert.True(t, cmd.HasAlias("remove")) assert.False(t, cmd.HasAlias("other")) @@ -46,7 +45,7 @@ func TestNewRemoveCommandErrors(t *testing.T) { for _, tc := range testCases { cmd := NewRemoveCommand(test.NewFakeCli(&fakeClient{ imageRemoveFunc: tc.imageRemoveFunc, - }, new(bytes.Buffer))) + })) cmd.SetOutput(ioutil.Discard) cmd.SetArgs(tc.args) testutil.ErrorContains(t, cmd.Execute(), tc.expectedError) @@ -97,18 +96,15 @@ func TestNewRemoveCommandSuccess(t *testing.T) { }, } for _, tc := range testCases { - buf := new(bytes.Buffer) - errBuf := new(bytes.Buffer) - fakeCli := test.NewFakeCli(&fakeClient{imageRemoveFunc: tc.imageRemoveFunc}, buf) - fakeCli.SetErr(errBuf) + fakeCli := test.NewFakeCli(&fakeClient{imageRemoveFunc: tc.imageRemoveFunc}) cmd := NewRemoveCommand(fakeCli) cmd.SetOutput(ioutil.Discard) cmd.SetArgs(tc.args) assert.NoError(t, cmd.Execute()) if tc.expectedErrMsg != "" { - assert.Equal(t, tc.expectedErrMsg, errBuf.String()) + assert.Equal(t, tc.expectedErrMsg, fakeCli.ErrBuffer().String()) } - actual := buf.String() + actual := fakeCli.OutBuffer().String() expected := string(golden.Get(t, []byte(actual), fmt.Sprintf("remove-command-success.%s.golden", tc.name))[:]) testutil.EqualNormalizedString(t, testutil.RemoveSpace, actual, expected) } diff --git a/components/cli/cli/command/image/save_test.go b/components/cli/cli/command/image/save_test.go index d137dc92f9..c63eeef41c 100644 --- a/components/cli/cli/command/image/save_test.go +++ b/components/cli/cli/command/image/save_test.go @@ -45,7 +45,7 @@ func TestNewSaveCommandErrors(t *testing.T) { }, } for _, tc := range testCases { - cli := test.NewFakeCli(&fakeClient{imageSaveFunc: tc.imageSaveFunc}, new(bytes.Buffer)) + cli := test.NewFakeCli(&fakeClient{imageSaveFunc: tc.imageSaveFunc}) cli.Out().SetIsTerminal(tc.isTerminal) cmd := NewSaveCommand(cli) cmd.SetOutput(ioutil.Discard) @@ -85,7 +85,7 @@ func TestNewSaveCommandSuccess(t *testing.T) { }, } for _, tc := range testCases { - cmd := NewSaveCommand(test.NewFakeCli(&fakeClient{ + cmd := NewSaveCommand(test.NewFakeCliWithOutput(&fakeClient{ imageSaveFunc: func(images []string) (io.ReadCloser, error) { return ioutil.NopCloser(strings.NewReader("")), nil }, diff --git a/components/cli/cli/command/image/tag_test.go b/components/cli/cli/command/image/tag_test.go index 8cf0c534b8..b537f9d627 100644 --- a/components/cli/cli/command/image/tag_test.go +++ b/components/cli/cli/command/image/tag_test.go @@ -1,7 +1,6 @@ package image import ( - "bytes" "io/ioutil" "testing" @@ -17,9 +16,8 @@ func TestCliNewTagCommandErrors(t *testing.T) { {"image1", "image2", "image3"}, } expectedError := "\"tag\" requires exactly 2 argument(s)." - buf := new(bytes.Buffer) for _, args := range testCases { - cmd := NewTagCommand(test.NewFakeCli(&fakeClient{}, buf)) + cmd := NewTagCommand(test.NewFakeCli(&fakeClient{})) cmd.SetArgs(args) cmd.SetOutput(ioutil.Discard) testutil.ErrorContains(t, cmd.Execute(), expectedError) @@ -27,7 +25,6 @@ func TestCliNewTagCommandErrors(t *testing.T) { } func TestCliNewTagCommand(t *testing.T) { - buf := new(bytes.Buffer) cmd := NewTagCommand( test.NewFakeCli(&fakeClient{ imageTagFunc: func(image string, ref string) error { @@ -35,7 +32,7 @@ func TestCliNewTagCommand(t *testing.T) { assert.Equal(t, "image2", ref) return nil }, - }, buf)) + })) cmd.SetArgs([]string{"image1", "image2"}) cmd.SetOutput(ioutil.Discard) assert.NoError(t, cmd.Execute()) diff --git a/components/cli/cli/command/image/testdata/inspect-command-success.simple-many.golden b/components/cli/cli/command/image/testdata/inspect-command-success.simple-many.golden index d4042589f8..f72c96f74e 100644 --- a/components/cli/cli/command/image/testdata/inspect-command-success.simple-many.golden +++ b/components/cli/cli/command/image/testdata/inspect-command-success.simple-many.golden @@ -21,6 +21,9 @@ }, "RootFS": { "Type": "" + }, + "Metadata": { + "LastTagTime": "0001-01-01T00:00:00Z" } }, { @@ -45,6 +48,9 @@ }, "RootFS": { "Type": "" + }, + "Metadata": { + "LastTagTime": "0001-01-01T00:00:00Z" } } ] diff --git a/components/cli/cli/command/image/testdata/inspect-command-success.simple.golden b/components/cli/cli/command/image/testdata/inspect-command-success.simple.golden index 802c52469b..878463ffc4 100644 --- a/components/cli/cli/command/image/testdata/inspect-command-success.simple.golden +++ b/components/cli/cli/command/image/testdata/inspect-command-success.simple.golden @@ -21,6 +21,9 @@ }, "RootFS": { "Type": "" + }, + "Metadata": { + "LastTagTime": "0001-01-01T00:00:00Z" } } ] diff --git a/components/cli/cli/command/network/client_test.go b/components/cli/cli/command/network/client_test.go new file mode 100644 index 0000000000..1a5ee4ed81 --- /dev/null +++ b/components/cli/cli/command/network/client_test.go @@ -0,0 +1,19 @@ +package network + +import ( + "github.com/docker/docker/api/types" + "github.com/docker/docker/client" + "golang.org/x/net/context" +) + +type fakeClient struct { + client.Client + networkCreateFunc func(ctx context.Context, name string, options types.NetworkCreate) (types.NetworkCreateResponse, error) +} + +func (c *fakeClient) NetworkCreate(ctx context.Context, name string, options types.NetworkCreate) (types.NetworkCreateResponse, error) { + if c.networkCreateFunc != nil { + return c.networkCreateFunc(ctx, name, options) + } + return types.NetworkCreateResponse{}, nil +} diff --git a/components/cli/cli/command/network/cmd.go b/components/cli/cli/command/network/cmd.go index 97bcca2a8d..48edf1c4e3 100644 --- a/components/cli/cli/command/network/cmd.go +++ b/components/cli/cli/command/network/cmd.go @@ -8,8 +8,7 @@ import ( ) // NewNetworkCommand returns a cobra command for `network` subcommands -// nolint: interfacer -func NewNetworkCommand(dockerCli *command.DockerCli) *cobra.Command { +func NewNetworkCommand(dockerCli command.Cli) *cobra.Command { cmd := &cobra.Command{ Use: "network", Short: "Manage networks", diff --git a/components/cli/cli/command/network/connect.go b/components/cli/cli/command/network/connect.go index 19bd3c56aa..9e925c3444 100644 --- a/components/cli/cli/command/network/connect.go +++ b/components/cli/cli/command/network/connect.go @@ -19,7 +19,7 @@ type connectOptions struct { linklocalips []string } -func newConnectCommand(dockerCli *command.DockerCli) *cobra.Command { +func newConnectCommand(dockerCli command.Cli) *cobra.Command { options := connectOptions{ links: opts.NewListOpts(opts.ValidateLink), } @@ -45,7 +45,7 @@ func newConnectCommand(dockerCli *command.DockerCli) *cobra.Command { return cmd } -func runConnect(dockerCli *command.DockerCli, options connectOptions) error { +func runConnect(dockerCli command.Cli, options connectOptions) error { client := dockerCli.Client() epConfig := &network.EndpointSettings{ diff --git a/components/cli/cli/command/network/create.go b/components/cli/cli/command/network/create.go index ed6d2de7bd..33bbdef5be 100644 --- a/components/cli/cli/command/network/create.go +++ b/components/cli/cli/command/network/create.go @@ -36,7 +36,7 @@ type createOptions struct { ipamOpt opts.MapOpts } -func newCreateCommand(dockerCli *command.DockerCli) *cobra.Command { +func newCreateCommand(dockerCli command.Cli) *cobra.Command { options := createOptions{ driverOpts: *opts.NewMapOpts(nil, nil), labels: opts.NewListOpts(opts.ValidateEnv), @@ -82,7 +82,7 @@ func newCreateCommand(dockerCli *command.DockerCli) *cobra.Command { return cmd } -func runCreate(dockerCli *command.DockerCli, options createOptions) error { +func runCreate(dockerCli command.Cli, options createOptions) error { client := dockerCli.Client() ipamCfg, err := consolidateIpam(options.ipamSubnet, options.ipamIPRange, options.ipamGateway, options.ipamAux.GetAll()) @@ -232,13 +232,13 @@ func subnetMatches(subnet, data string) (bool, error) { _, s, err := net.ParseCIDR(subnet) if err != nil { - return false, errors.Errorf("Invalid subnet %s : %v", s, err) + return false, errors.Wrap(err, "invalid subnet") } if strings.Contains(data, "/") { ip, _, err = net.ParseCIDR(data) if err != nil { - return false, errors.Errorf("Invalid cidr %s : %v", data, err) + return false, err } } else { ip = net.ParseIP(data) diff --git a/components/cli/cli/command/network/create_test.go b/components/cli/cli/command/network/create_test.go new file mode 100644 index 0000000000..76c760d0ad --- /dev/null +++ b/components/cli/cli/command/network/create_test.go @@ -0,0 +1,175 @@ +package network + +import ( + "io/ioutil" + "strings" + "testing" + + "github.com/docker/cli/cli/internal/test" + "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/network" + "github.com/docker/docker/pkg/testutil" + "github.com/pkg/errors" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "golang.org/x/net/context" +) + +func TestNetworkCreateErrors(t *testing.T) { + testCases := []struct { + args []string + flags map[string]string + networkCreateFunc func(ctx context.Context, name string, options types.NetworkCreate) (types.NetworkCreateResponse, error) + expectedError string + }{ + { + expectedError: "exactly 1 argument", + }, + { + args: []string{"toto"}, + networkCreateFunc: func(ctx context.Context, name string, createBody types.NetworkCreate) (types.NetworkCreateResponse, error) { + return types.NetworkCreateResponse{}, errors.Errorf("error creating network") + }, + expectedError: "error creating network", + }, + { + args: []string{"toto"}, + flags: map[string]string{ + "ip-range": "255.255.0.0/24", + "gateway": "255.0.255.0/24", + "subnet": "10.1.2.0.30.50", + }, + expectedError: "invalid CIDR address: 10.1.2.0.30.50", + }, + { + args: []string{"toto"}, + flags: map[string]string{ + "ip-range": "255.255.0.0.30/24", + "gateway": "255.0.255.0/24", + "subnet": "255.0.0.0/24", + }, + expectedError: "invalid CIDR address: 255.255.0.0.30/24", + }, + { + args: []string{"toto"}, + flags: map[string]string{ + "gateway": "255.0.0.0/24", + }, + expectedError: "every ip-range or gateway must have a corresponding subnet", + }, + { + args: []string{"toto"}, + flags: map[string]string{ + "ip-range": "255.0.0.0/24", + }, + expectedError: "every ip-range or gateway must have a corresponding subnet", + }, + { + args: []string{"toto"}, + flags: map[string]string{ + "ip-range": "255.0.0.0/24", + "gateway": "255.0.0.0/24", + }, + expectedError: "every ip-range or gateway must have a corresponding subnet", + }, + { + args: []string{"toto"}, + flags: map[string]string{ + "ip-range": "255.255.0.0/24", + "gateway": "255.0.255.0/24", + "subnet": "10.1.2.0/23,10.1.3.248/30", + }, + expectedError: "multiple overlapping subnet configuration is not supported", + }, + { + args: []string{"toto"}, + flags: map[string]string{ + "ip-range": "192.168.1.0/24,192.168.1.200/24", + "gateway": "192.168.1.1,192.168.1.4", + "subnet": "192.168.2.0/24,192.168.1.250/24", + }, + expectedError: "cannot configure multiple ranges (192.168.1.200/24, 192.168.1.0/24) on the same subnet (192.168.1.250/24)", + }, + { + args: []string{"toto"}, + flags: map[string]string{ + "ip-range": "255.255.200.0/24,255.255.120.0/24", + "gateway": "255.0.255.0/24", + "subnet": "255.255.255.0/24,255.255.0.255/24", + }, + expectedError: "no matching subnet for range 255.255.200.0/24", + }, + { + args: []string{"toto"}, + flags: map[string]string{ + "ip-range": "192.168.1.0/24", + "gateway": "192.168.1.1,192.168.1.4", + "subnet": "192.168.2.0/24,192.168.1.250/24", + }, + expectedError: "cannot configure multiple gateways (192.168.1.4, 192.168.1.1) for the same subnet (192.168.1.250/24)", + }, + { + args: []string{"toto"}, + flags: map[string]string{ + "ip-range": "192.168.1.0/24", + "gateway": "192.168.4.1,192.168.5.4", + "subnet": "192.168.2.0/24,192.168.1.250/24", + }, + expectedError: "no matching subnet for gateway 192.168.4.1", + }, + { + args: []string{"toto"}, + flags: map[string]string{ + "gateway": "255.255.0.0/24", + "subnet": "255.255.0.0/24", + "aux-address": "255.255.0.30/24", + }, + expectedError: "no matching subnet for aux-address", + }, + } + + for _, tc := range testCases { + cmd := newCreateCommand( + test.NewFakeCli(&fakeClient{ + networkCreateFunc: tc.networkCreateFunc, + }), + ) + cmd.SetArgs(tc.args) + for key, value := range tc.flags { + require.NoError(t, cmd.Flags().Set(key, value)) + } + cmd.SetOutput(ioutil.Discard) + testutil.ErrorContains(t, cmd.Execute(), tc.expectedError) + + } +} +func TestNetworkCreateWithFlags(t *testing.T) { + expectedDriver := "foo" + expectedOpts := []network.IPAMConfig{ + { + "192.168.4.0/24", + "192.168.4.0/24", + "192.168.4.1/24", + map[string]string{}, + }, + } + cli := test.NewFakeCli(&fakeClient{ + networkCreateFunc: func(ctx context.Context, name string, createBody types.NetworkCreate) (types.NetworkCreateResponse, error) { + assert.Equal(t, expectedDriver, createBody.Driver, "not expected driver error") + assert.Equal(t, expectedOpts, createBody.IPAM.Config, "not expected driver error") + return types.NetworkCreateResponse{ + ID: name, + }, nil + }, + }) + args := []string{"banana"} + cmd := newCreateCommand(cli) + + cmd.SetArgs(args) + cmd.Flags().Set("driver", "foo") + cmd.Flags().Set("ip-range", "192.168.4.0/24") + cmd.Flags().Set("gateway", "192.168.4.1/24") + cmd.Flags().Set("subnet", "192.168.4.0/24") + assert.NoError(t, cmd.Execute()) + assert.Equal(t, "banana", strings.TrimSpace(cli.OutBuffer().String())) +} diff --git a/components/cli/cli/command/network/disconnect.go b/components/cli/cli/command/network/disconnect.go index 0f7d7c2b98..ab866cf2c1 100644 --- a/components/cli/cli/command/network/disconnect.go +++ b/components/cli/cli/command/network/disconnect.go @@ -14,7 +14,7 @@ type disconnectOptions struct { force bool } -func newDisconnectCommand(dockerCli *command.DockerCli) *cobra.Command { +func newDisconnectCommand(dockerCli command.Cli) *cobra.Command { opts := disconnectOptions{} cmd := &cobra.Command{ @@ -34,7 +34,7 @@ func newDisconnectCommand(dockerCli *command.DockerCli) *cobra.Command { return cmd } -func runDisconnect(dockerCli *command.DockerCli, opts disconnectOptions) error { +func runDisconnect(dockerCli command.Cli, opts disconnectOptions) error { client := dockerCli.Client() return client.NetworkDisconnect(context.Background(), opts.network, opts.container, opts.force) diff --git a/components/cli/cli/command/network/inspect.go b/components/cli/cli/command/network/inspect.go index 9856c04e4c..e4c2e5fb89 100644 --- a/components/cli/cli/command/network/inspect.go +++ b/components/cli/cli/command/network/inspect.go @@ -16,7 +16,7 @@ type inspectOptions struct { verbose bool } -func newInspectCommand(dockerCli *command.DockerCli) *cobra.Command { +func newInspectCommand(dockerCli command.Cli) *cobra.Command { var opts inspectOptions cmd := &cobra.Command{ @@ -35,7 +35,7 @@ func newInspectCommand(dockerCli *command.DockerCli) *cobra.Command { return cmd } -func runInspect(dockerCli *command.DockerCli, opts inspectOptions) error { +func runInspect(dockerCli command.Cli, opts inspectOptions) error { client := dockerCli.Client() ctx := context.Background() diff --git a/components/cli/cli/command/network/list.go b/components/cli/cli/command/network/list.go index 79a860f9b3..8a7c1f261d 100644 --- a/components/cli/cli/command/network/list.go +++ b/components/cli/cli/command/network/list.go @@ -25,7 +25,7 @@ type listOptions struct { filter opts.FilterOpt } -func newListCommand(dockerCli *command.DockerCli) *cobra.Command { +func newListCommand(dockerCli command.Cli) *cobra.Command { options := listOptions{filter: opts.NewFilterOpt()} cmd := &cobra.Command{ @@ -47,7 +47,7 @@ func newListCommand(dockerCli *command.DockerCli) *cobra.Command { return cmd } -func runList(dockerCli *command.DockerCli, options listOptions) error { +func runList(dockerCli command.Cli, options listOptions) error { client := dockerCli.Client() listOptions := types.NetworkListOptions{Filters: options.filter.Value()} networkResources, err := client.NetworkList(context.Background(), listOptions) diff --git a/components/cli/cli/command/network/remove.go b/components/cli/cli/command/network/remove.go index 7dfe8da2f7..3de7bdad38 100644 --- a/components/cli/cli/command/network/remove.go +++ b/components/cli/cli/command/network/remove.go @@ -11,7 +11,7 @@ import ( "github.com/spf13/cobra" ) -func newRemoveCommand(dockerCli *command.DockerCli) *cobra.Command { +func newRemoveCommand(dockerCli command.Cli) *cobra.Command { return &cobra.Command{ Use: "rm NETWORK [NETWORK...]", Aliases: []string{"remove"}, @@ -28,7 +28,7 @@ const ingressWarning = "WARNING! Before removing the routing-mesh network, " + "Otherwise, removal may not be effective and functionality of newly create " + "ingress networks will be impaired.\nAre you sure you want to continue?" -func runRemove(dockerCli *command.DockerCli, networks []string) error { +func runRemove(dockerCli command.Cli, networks []string) error { client := dockerCli.Client() ctx := context.Background() status := 0 diff --git a/components/cli/cli/command/node/demote_test.go b/components/cli/cli/command/node/demote_test.go index 7126dddd13..d786cd47a2 100644 --- a/components/cli/cli/command/node/demote_test.go +++ b/components/cli/cli/command/node/demote_test.go @@ -1,7 +1,6 @@ package node import ( - "bytes" "io/ioutil" "testing" @@ -40,12 +39,11 @@ func TestNodeDemoteErrors(t *testing.T) { }, } for _, tc := range testCases { - buf := new(bytes.Buffer) cmd := newDemoteCommand( test.NewFakeCli(&fakeClient{ nodeInspectFunc: tc.nodeInspectFunc, nodeUpdateFunc: tc.nodeUpdateFunc, - }, buf)) + })) cmd.SetArgs(tc.args) cmd.SetOutput(ioutil.Discard) testutil.ErrorContains(t, cmd.Execute(), tc.expectedError) @@ -53,7 +51,6 @@ func TestNodeDemoteErrors(t *testing.T) { } func TestNodeDemoteNoChange(t *testing.T) { - buf := new(bytes.Buffer) cmd := newDemoteCommand( test.NewFakeCli(&fakeClient{ nodeInspectFunc: func() (swarm.Node, []byte, error) { @@ -65,13 +62,12 @@ func TestNodeDemoteNoChange(t *testing.T) { } return nil }, - }, buf)) + })) cmd.SetArgs([]string{"nodeID"}) assert.NoError(t, cmd.Execute()) } func TestNodeDemoteMultipleNode(t *testing.T) { - buf := new(bytes.Buffer) cmd := newDemoteCommand( test.NewFakeCli(&fakeClient{ nodeInspectFunc: func() (swarm.Node, []byte, error) { @@ -83,7 +79,7 @@ func TestNodeDemoteMultipleNode(t *testing.T) { } return nil }, - }, buf)) + })) cmd.SetArgs([]string{"nodeID1", "nodeID2"}) assert.NoError(t, cmd.Execute()) } diff --git a/components/cli/cli/command/node/inspect_test.go b/components/cli/cli/command/node/inspect_test.go index 2a21e12a28..ca88371f8a 100644 --- a/components/cli/cli/command/node/inspect_test.go +++ b/components/cli/cli/command/node/inspect_test.go @@ -69,7 +69,7 @@ func TestNodeInspectErrors(t *testing.T) { for _, tc := range testCases { buf := new(bytes.Buffer) cmd := newInspectCommand( - test.NewFakeCli(&fakeClient{ + test.NewFakeCliWithOutput(&fakeClient{ nodeInspectFunc: tc.nodeInspectFunc, infoFunc: tc.infoFunc, }, buf)) @@ -111,7 +111,7 @@ func TestNodeInspectPretty(t *testing.T) { for _, tc := range testCases { buf := new(bytes.Buffer) cmd := newInspectCommand( - test.NewFakeCli(&fakeClient{ + test.NewFakeCliWithOutput(&fakeClient{ nodeInspectFunc: tc.nodeInspectFunc, }, buf)) cmd.SetArgs([]string{"nodeID"}) diff --git a/components/cli/cli/command/node/list_test.go b/components/cli/cli/command/node/list_test.go index c4538ba141..eb58d7709e 100644 --- a/components/cli/cli/command/node/list_test.go +++ b/components/cli/cli/command/node/list_test.go @@ -42,12 +42,10 @@ func TestNodeListErrorOnAPIFailure(t *testing.T) { }, } for _, tc := range testCases { - buf := new(bytes.Buffer) cli := test.NewFakeCli(&fakeClient{ nodeListFunc: tc.nodeListFunc, infoFunc: tc.infoFunc, - }, buf) - cli.SetConfigfile(&configfile.ConfigFile{}) + }) cmd := newListCommand(cli) cmd.SetOutput(ioutil.Discard) assert.EqualError(t, cmd.Execute(), tc.expectedError) @@ -55,7 +53,6 @@ func TestNodeListErrorOnAPIFailure(t *testing.T) { } func TestNodeList(t *testing.T) { - buf := new(bytes.Buffer) cli := test.NewFakeCli(&fakeClient{ nodeListFunc: func() ([]swarm.Node, error) { return []swarm.Node{ @@ -71,25 +68,25 @@ func TestNodeList(t *testing.T) { }, }, nil }, - }, buf) - cli.SetConfigfile(&configfile.ConfigFile{}) + }) + cmd := newListCommand(cli) assert.NoError(t, cmd.Execute()) - assert.Contains(t, buf.String(), `nodeID1 * nodeHostname1 Ready Active Leader`) - assert.Contains(t, buf.String(), `nodeID2 nodeHostname2 Ready Active Reachable`) - assert.Contains(t, buf.String(), `nodeID3 nodeHostname3 Ready Active`) + out := cli.OutBuffer().String() + assert.Contains(t, out, `nodeID1 * nodeHostname1 Ready Active Leader`) + assert.Contains(t, out, `nodeID2 nodeHostname2 Ready Active Reachable`) + assert.Contains(t, out, `nodeID3 nodeHostname3 Ready Active`) } func TestNodeListQuietShouldOnlyPrintIDs(t *testing.T) { buf := new(bytes.Buffer) - cli := test.NewFakeCli(&fakeClient{ + cli := test.NewFakeCliWithOutput(&fakeClient{ nodeListFunc: func() ([]swarm.Node, error) { return []swarm.Node{ *Node(), }, nil }, }, buf) - cli.SetConfigfile(&configfile.ConfigFile{}) cmd := newListCommand(cli) cmd.Flags().Set("quiet", "true") assert.NoError(t, cmd.Execute()) @@ -99,8 +96,7 @@ func TestNodeListQuietShouldOnlyPrintIDs(t *testing.T) { // Test case for #24090 func TestNodeListContainsHostname(t *testing.T) { buf := new(bytes.Buffer) - cli := test.NewFakeCli(&fakeClient{}, buf) - cli.SetConfigfile(&configfile.ConfigFile{}) + cli := test.NewFakeCliWithOutput(&fakeClient{}, buf) cmd := newListCommand(cli) assert.NoError(t, cmd.Execute()) assert.Contains(t, buf.String(), "HOSTNAME") @@ -108,7 +104,7 @@ func TestNodeListContainsHostname(t *testing.T) { func TestNodeListDefaultFormat(t *testing.T) { buf := new(bytes.Buffer) - cli := test.NewFakeCli(&fakeClient{ + cli := test.NewFakeCliWithOutput(&fakeClient{ nodeListFunc: func() ([]swarm.Node, error) { return []swarm.Node{ *Node(NodeID("nodeID1"), Hostname("nodeHostname1"), Manager(Leader())), @@ -124,7 +120,7 @@ func TestNodeListDefaultFormat(t *testing.T) { }, nil }, }, buf) - cli.SetConfigfile(&configfile.ConfigFile{ + cli.SetConfigFile(&configfile.ConfigFile{ NodesFormat: "{{.ID}}: {{.Hostname}} {{.Status}}/{{.ManagerStatus}}", }) cmd := newListCommand(cli) @@ -136,7 +132,7 @@ func TestNodeListDefaultFormat(t *testing.T) { func TestNodeListFormat(t *testing.T) { buf := new(bytes.Buffer) - cli := test.NewFakeCli(&fakeClient{ + cli := test.NewFakeCliWithOutput(&fakeClient{ nodeListFunc: func() ([]swarm.Node, error) { return []swarm.Node{ *Node(NodeID("nodeID1"), Hostname("nodeHostname1"), Manager(Leader())), @@ -151,7 +147,7 @@ func TestNodeListFormat(t *testing.T) { }, nil }, }, buf) - cli.SetConfigfile(&configfile.ConfigFile{ + cli.SetConfigFile(&configfile.ConfigFile{ NodesFormat: "{{.ID}}: {{.Hostname}} {{.Status}}/{{.ManagerStatus}}", }) cmd := newListCommand(cli) diff --git a/components/cli/cli/command/node/promote_test.go b/components/cli/cli/command/node/promote_test.go index 495bdfe60d..95e067eb15 100644 --- a/components/cli/cli/command/node/promote_test.go +++ b/components/cli/cli/command/node/promote_test.go @@ -42,7 +42,7 @@ func TestNodePromoteErrors(t *testing.T) { for _, tc := range testCases { buf := new(bytes.Buffer) cmd := newPromoteCommand( - test.NewFakeCli(&fakeClient{ + test.NewFakeCliWithOutput(&fakeClient{ nodeInspectFunc: tc.nodeInspectFunc, nodeUpdateFunc: tc.nodeUpdateFunc, }, buf)) @@ -55,7 +55,7 @@ func TestNodePromoteErrors(t *testing.T) { func TestNodePromoteNoChange(t *testing.T) { buf := new(bytes.Buffer) cmd := newPromoteCommand( - test.NewFakeCli(&fakeClient{ + test.NewFakeCliWithOutput(&fakeClient{ nodeInspectFunc: func() (swarm.Node, []byte, error) { return *Node(Manager()), []byte{}, nil }, @@ -73,7 +73,7 @@ func TestNodePromoteNoChange(t *testing.T) { func TestNodePromoteMultipleNode(t *testing.T) { buf := new(bytes.Buffer) cmd := newPromoteCommand( - test.NewFakeCli(&fakeClient{ + test.NewFakeCliWithOutput(&fakeClient{ nodeInspectFunc: func() (swarm.Node, []byte, error) { return *Node(), []byte{}, nil }, diff --git a/components/cli/cli/command/node/ps.go b/components/cli/cli/command/node/ps.go index 6a586a3bcc..5212e596f3 100644 --- a/components/cli/cli/command/node/ps.go +++ b/components/cli/cli/command/node/ps.go @@ -5,7 +5,6 @@ import ( "github.com/docker/cli/cli" "github.com/docker/cli/cli/command" - "github.com/docker/cli/cli/command/formatter" "github.com/docker/cli/cli/command/idresolver" "github.com/docker/cli/cli/command/task" "github.com/docker/cli/opts" @@ -88,11 +87,7 @@ func runPs(dockerCli command.Cli, options psOptions) error { format := options.format if len(format) == 0 { - if dockerCli.ConfigFile() != nil && len(dockerCli.ConfigFile().TasksFormat) > 0 && !options.quiet { - format = dockerCli.ConfigFile().TasksFormat - } else { - format = formatter.TableFormatKey - } + format = task.DefaultFormat(dockerCli.ConfigFile(), options.quiet) } if len(errs) == 0 || len(tasks) != 0 { diff --git a/components/cli/cli/command/node/ps_test.go b/components/cli/cli/command/node/ps_test.go index d25a55f0cf..d3ef6f30a2 100644 --- a/components/cli/cli/command/node/ps_test.go +++ b/components/cli/cli/command/node/ps_test.go @@ -52,7 +52,7 @@ func TestNodePsErrors(t *testing.T) { for _, tc := range testCases { buf := new(bytes.Buffer) cmd := newPsCommand( - test.NewFakeCli(&fakeClient{ + test.NewFakeCliWithOutput(&fakeClient{ infoFunc: tc.infoFunc, nodeInspectFunc: tc.nodeInspectFunc, taskInspectFunc: tc.taskInspectFunc, @@ -116,7 +116,7 @@ func TestNodePs(t *testing.T) { for _, tc := range testCases { buf := new(bytes.Buffer) cmd := newPsCommand( - test.NewFakeCli(&fakeClient{ + test.NewFakeCliWithOutput(&fakeClient{ infoFunc: tc.infoFunc, nodeInspectFunc: tc.nodeInspectFunc, taskInspectFunc: tc.taskInspectFunc, diff --git a/components/cli/cli/command/node/remove_test.go b/components/cli/cli/command/node/remove_test.go index 7123288f47..81daa2f025 100644 --- a/components/cli/cli/command/node/remove_test.go +++ b/components/cli/cli/command/node/remove_test.go @@ -31,7 +31,7 @@ func TestNodeRemoveErrors(t *testing.T) { for _, tc := range testCases { buf := new(bytes.Buffer) cmd := newRemoveCommand( - test.NewFakeCli(&fakeClient{ + test.NewFakeCliWithOutput(&fakeClient{ nodeRemoveFunc: tc.nodeRemoveFunc, }, buf)) cmd.SetArgs(tc.args) @@ -42,7 +42,7 @@ func TestNodeRemoveErrors(t *testing.T) { func TestNodeRemoveMultiple(t *testing.T) { buf := new(bytes.Buffer) - cmd := newRemoveCommand(test.NewFakeCli(&fakeClient{}, buf)) + cmd := newRemoveCommand(test.NewFakeCliWithOutput(&fakeClient{}, buf)) cmd.SetArgs([]string{"nodeID1", "nodeID2"}) assert.NoError(t, cmd.Execute()) } diff --git a/components/cli/cli/command/node/update_test.go b/components/cli/cli/command/node/update_test.go index 0085934b9c..3abb720c1c 100644 --- a/components/cli/cli/command/node/update_test.go +++ b/components/cli/cli/command/node/update_test.go @@ -1,7 +1,6 @@ package node import ( - "bytes" "io/ioutil" "testing" @@ -57,12 +56,11 @@ func TestNodeUpdateErrors(t *testing.T) { }, } for _, tc := range testCases { - buf := new(bytes.Buffer) cmd := newUpdateCommand( test.NewFakeCli(&fakeClient{ nodeInspectFunc: tc.nodeInspectFunc, nodeUpdateFunc: tc.nodeUpdateFunc, - }, buf)) + })) cmd.SetArgs(tc.args) for key, value := range tc.flags { cmd.Flags().Set(key, value) @@ -158,12 +156,11 @@ func TestNodeUpdate(t *testing.T) { }, } for _, tc := range testCases { - buf := new(bytes.Buffer) cmd := newUpdateCommand( test.NewFakeCli(&fakeClient{ nodeInspectFunc: tc.nodeInspectFunc, nodeUpdateFunc: tc.nodeUpdateFunc, - }, buf)) + })) cmd.SetArgs(tc.args) for key, value := range tc.flags { cmd.Flags().Set(key, value) diff --git a/components/cli/cli/command/prune/prune.go b/components/cli/cli/command/prune/prune.go index e916a8283e..12429da907 100644 --- a/components/cli/cli/command/prune/prune.go +++ b/components/cli/cli/command/prune/prune.go @@ -7,29 +7,8 @@ import ( "github.com/docker/cli/cli/command/network" "github.com/docker/cli/cli/command/volume" "github.com/docker/cli/opts" - "github.com/spf13/cobra" ) -// NewContainerPruneCommand returns a cobra prune command for containers -func NewContainerPruneCommand(dockerCli command.Cli) *cobra.Command { - return container.NewPruneCommand(dockerCli) -} - -// NewVolumePruneCommand returns a cobra prune command for volumes -func NewVolumePruneCommand(dockerCli command.Cli) *cobra.Command { - return volume.NewPruneCommand(dockerCli) -} - -// NewImagePruneCommand returns a cobra prune command for images -func NewImagePruneCommand(dockerCli command.Cli) *cobra.Command { - return image.NewPruneCommand(dockerCli) -} - -// NewNetworkPruneCommand returns a cobra prune command for Networks -func NewNetworkPruneCommand(dockerCli command.Cli) *cobra.Command { - return network.NewPruneCommand(dockerCli) -} - // RunContainerPrune executes a prune command for containers func RunContainerPrune(dockerCli command.Cli, filter opts.FilterOpt) (uint64, string, error) { return container.RunPrune(dockerCli, filter) diff --git a/components/cli/cli/command/registry/login.go b/components/cli/cli/command/registry/login.go index 4ffca2bed2..938fef8ab7 100644 --- a/components/cli/cli/command/registry/login.go +++ b/components/cli/cli/command/registry/login.go @@ -2,6 +2,8 @@ package registry import ( "fmt" + "io/ioutil" + "strings" "golang.org/x/net/context" @@ -16,6 +18,7 @@ type loginOptions struct { serverAddress string user string password string + passwordStdin bool } // NewLoginCommand creates a new `docker login` command @@ -39,6 +42,7 @@ func NewLoginCommand(dockerCli command.Cli) *cobra.Command { flags.StringVarP(&opts.user, "username", "u", "", "Username") flags.StringVarP(&opts.password, "password", "p", "", "Password") + flags.BoolVarP(&opts.passwordStdin, "password-stdin", "", false, "Take the password from stdin") return cmd } @@ -47,6 +51,27 @@ func runLogin(dockerCli command.Cli, opts loginOptions) error { ctx := context.Background() clnt := dockerCli.Client() + if opts.password != "" { + fmt.Fprintln(dockerCli.Err(), "WARNING! Using --password via the CLI is insecure. Use --password-stdin.") + if opts.passwordStdin { + return errors.New("--password and --password-stdin are mutually exclusive") + } + } + + if opts.passwordStdin { + if opts.user == "" { + return errors.New("Must provide --username with --password-stdin") + } + + contents, err := ioutil.ReadAll(dockerCli.In()) + if err != nil { + return err + } + + opts.password = strings.TrimSuffix(string(contents), "\n") + opts.password = strings.TrimSuffix(opts.password, "\r") + } + var ( serverAddress string authServer = command.ElectAuthServer(ctx, dockerCli) diff --git a/components/cli/cli/command/registry_test.go b/components/cli/cli/command/registry_test.go index f6adeb49f4..5e52e470a1 100644 --- a/components/cli/cli/command/registry_test.go +++ b/components/cli/cli/command/registry_test.go @@ -1,7 +1,6 @@ package command_test import ( - "bytes" "testing" "github.com/pkg/errors" @@ -63,13 +62,10 @@ func TestElectAuthServer(t *testing.T) { }, } for _, tc := range testCases { - buf := new(bytes.Buffer) - cli := test.NewFakeCli(&fakeClient{infoFunc: tc.infoFunc}, buf) - errBuf := new(bytes.Buffer) - cli.SetErr(errBuf) + cli := test.NewFakeCli(&fakeClient{infoFunc: tc.infoFunc}) server := ElectAuthServer(context.Background(), cli) assert.Equal(t, tc.expectedAuthServer, server) - actual := errBuf.String() + actual := cli.ErrBuffer().String() if tc.expectedWarning == "" { assert.Empty(t, actual) } else { diff --git a/components/cli/cli/command/secret/create_test.go b/components/cli/cli/command/secret/create_test.go index 197483cf70..2c4f9f5d9c 100644 --- a/components/cli/cli/command/secret/create_test.go +++ b/components/cli/cli/command/secret/create_test.go @@ -41,11 +41,10 @@ func TestSecretCreateErrors(t *testing.T) { }, } for _, tc := range testCases { - buf := new(bytes.Buffer) cmd := newSecretCreateCommand( test.NewFakeCli(&fakeClient{ secretCreateFunc: tc.secretCreateFunc, - }, buf), + }), ) cmd.SetArgs(tc.args) cmd.SetOutput(ioutil.Discard) @@ -57,7 +56,7 @@ func TestSecretCreateWithName(t *testing.T) { name := "foo" buf := new(bytes.Buffer) var actual []byte - cli := test.NewFakeCli(&fakeClient{ + cli := test.NewFakeCliWithOutput(&fakeClient{ secretCreateFunc: func(spec swarm.SecretSpec) (types.SecretCreateResponse, error) { if spec.Name != name { return types.SecretCreateResponse{}, errors.Errorf("expected name %q, got %q", name, spec.Name) @@ -87,7 +86,7 @@ func TestSecretCreateWithLabels(t *testing.T) { name := "foo" buf := new(bytes.Buffer) - cli := test.NewFakeCli(&fakeClient{ + cli := test.NewFakeCliWithOutput(&fakeClient{ secretCreateFunc: func(spec swarm.SecretSpec) (types.SecretCreateResponse, error) { if spec.Name != name { return types.SecretCreateResponse{}, errors.Errorf("expected name %q, got %q", name, spec.Name) diff --git a/components/cli/cli/command/secret/inspect_test.go b/components/cli/cli/command/secret/inspect_test.go index 07a3d7a313..093624ddfe 100644 --- a/components/cli/cli/command/secret/inspect_test.go +++ b/components/cli/cli/command/secret/inspect_test.go @@ -55,7 +55,7 @@ func TestSecretInspectErrors(t *testing.T) { for _, tc := range testCases { buf := new(bytes.Buffer) cmd := newSecretInspectCommand( - test.NewFakeCli(&fakeClient{ + test.NewFakeCliWithOutput(&fakeClient{ secretInspectFunc: tc.secretInspectFunc, }, buf), ) @@ -97,7 +97,7 @@ func TestSecretInspectWithoutFormat(t *testing.T) { for _, tc := range testCases { buf := new(bytes.Buffer) cmd := newSecretInspectCommand( - test.NewFakeCli(&fakeClient{ + test.NewFakeCliWithOutput(&fakeClient{ secretInspectFunc: tc.secretInspectFunc, }, buf), ) @@ -137,7 +137,7 @@ func TestSecretInspectWithFormat(t *testing.T) { for _, tc := range testCases { buf := new(bytes.Buffer) cmd := newSecretInspectCommand( - test.NewFakeCli(&fakeClient{ + test.NewFakeCliWithOutput(&fakeClient{ secretInspectFunc: tc.secretInspectFunc, }, buf), ) @@ -173,7 +173,7 @@ func TestSecretInspectPretty(t *testing.T) { for _, tc := range testCases { buf := new(bytes.Buffer) cmd := newSecretInspectCommand( - test.NewFakeCli(&fakeClient{ + test.NewFakeCliWithOutput(&fakeClient{ secretInspectFunc: tc.secretInspectFunc, }, buf)) cmd.SetArgs([]string{"secretID"}) diff --git a/components/cli/cli/command/secret/ls_test.go b/components/cli/cli/command/secret/ls_test.go index 5d2103cb2a..fb033efea6 100644 --- a/components/cli/cli/command/secret/ls_test.go +++ b/components/cli/cli/command/secret/ls_test.go @@ -38,7 +38,7 @@ func TestSecretListErrors(t *testing.T) { for _, tc := range testCases { buf := new(bytes.Buffer) cmd := newSecretListCommand( - test.NewFakeCli(&fakeClient{ + test.NewFakeCliWithOutput(&fakeClient{ secretListFunc: tc.secretListFunc, }, buf), ) @@ -50,7 +50,7 @@ func TestSecretListErrors(t *testing.T) { func TestSecretList(t *testing.T) { buf := new(bytes.Buffer) - cli := test.NewFakeCli(&fakeClient{ + cli := test.NewFakeCliWithOutput(&fakeClient{ secretListFunc: func(options types.SecretListOptions) ([]swarm.Secret, error) { return []swarm.Secret{ *Secret(SecretID("ID-foo"), @@ -68,7 +68,6 @@ func TestSecretList(t *testing.T) { }, nil }, }, buf) - cli.SetConfigfile(&configfile.ConfigFile{}) cmd := newSecretListCommand(cli) cmd.SetOutput(buf) assert.NoError(t, cmd.Execute()) @@ -79,7 +78,7 @@ func TestSecretList(t *testing.T) { func TestSecretListWithQuietOption(t *testing.T) { buf := new(bytes.Buffer) - cli := test.NewFakeCli(&fakeClient{ + cli := test.NewFakeCliWithOutput(&fakeClient{ secretListFunc: func(options types.SecretListOptions) ([]swarm.Secret, error) { return []swarm.Secret{ *Secret(SecretID("ID-foo"), SecretName("foo")), @@ -89,7 +88,6 @@ func TestSecretListWithQuietOption(t *testing.T) { }, nil }, }, buf) - cli.SetConfigfile(&configfile.ConfigFile{}) cmd := newSecretListCommand(cli) cmd.Flags().Set("quiet", "true") assert.NoError(t, cmd.Execute()) @@ -100,7 +98,7 @@ func TestSecretListWithQuietOption(t *testing.T) { func TestSecretListWithConfigFormat(t *testing.T) { buf := new(bytes.Buffer) - cli := test.NewFakeCli(&fakeClient{ + cli := test.NewFakeCliWithOutput(&fakeClient{ secretListFunc: func(options types.SecretListOptions) ([]swarm.Secret, error) { return []swarm.Secret{ *Secret(SecretID("ID-foo"), SecretName("foo")), @@ -110,7 +108,7 @@ func TestSecretListWithConfigFormat(t *testing.T) { }, nil }, }, buf) - cli.SetConfigfile(&configfile.ConfigFile{ + cli.SetConfigFile(&configfile.ConfigFile{ SecretFormat: "{{ .Name }} {{ .Labels }}", }) cmd := newSecretListCommand(cli) @@ -122,7 +120,7 @@ func TestSecretListWithConfigFormat(t *testing.T) { func TestSecretListWithFormat(t *testing.T) { buf := new(bytes.Buffer) - cli := test.NewFakeCli(&fakeClient{ + cli := test.NewFakeCliWithOutput(&fakeClient{ secretListFunc: func(options types.SecretListOptions) ([]swarm.Secret, error) { return []swarm.Secret{ *Secret(SecretID("ID-foo"), SecretName("foo")), @@ -142,7 +140,7 @@ func TestSecretListWithFormat(t *testing.T) { func TestSecretListWithFilter(t *testing.T) { buf := new(bytes.Buffer) - cli := test.NewFakeCli(&fakeClient{ + cli := test.NewFakeCliWithOutput(&fakeClient{ secretListFunc: func(options types.SecretListOptions) ([]swarm.Secret, error) { assert.Equal(t, "foo", options.Filters.Get("name")[0], "foo") assert.Equal(t, "lbl1=Label-bar", options.Filters.Get("label")[0]) @@ -162,7 +160,6 @@ func TestSecretListWithFilter(t *testing.T) { }, nil }, }, buf) - cli.SetConfigfile(&configfile.ConfigFile{}) cmd := newSecretListCommand(cli) cmd.Flags().Set("filter", "name=foo") cmd.Flags().Set("filter", "label=lbl1=Label-bar") diff --git a/components/cli/cli/command/secret/remove_test.go b/components/cli/cli/command/secret/remove_test.go index 08443ec9ae..6e5ab5fb6c 100644 --- a/components/cli/cli/command/secret/remove_test.go +++ b/components/cli/cli/command/secret/remove_test.go @@ -33,7 +33,7 @@ func TestSecretRemoveErrors(t *testing.T) { for _, tc := range testCases { buf := new(bytes.Buffer) cmd := newSecretRemoveCommand( - test.NewFakeCli(&fakeClient{ + test.NewFakeCliWithOutput(&fakeClient{ secretRemoveFunc: tc.secretRemoveFunc, }, buf), ) @@ -47,7 +47,7 @@ func TestSecretRemoveWithName(t *testing.T) { names := []string{"foo", "bar"} buf := new(bytes.Buffer) var removedSecrets []string - cli := test.NewFakeCli(&fakeClient{ + cli := test.NewFakeCliWithOutput(&fakeClient{ secretRemoveFunc: func(name string) error { removedSecrets = append(removedSecrets, name) return nil @@ -65,7 +65,7 @@ func TestSecretRemoveContinueAfterError(t *testing.T) { buf := new(bytes.Buffer) var removedSecrets []string - cli := test.NewFakeCli(&fakeClient{ + cli := test.NewFakeCliWithOutput(&fakeClient{ secretRemoveFunc: func(name string) error { removedSecrets = append(removedSecrets, name) if name == "foo" { diff --git a/components/cli/cli/command/service/progress/progress.go b/components/cli/cli/command/service/progress/progress.go index d522fc08b4..adff486848 100644 --- a/components/cli/cli/command/service/progress/progress.go +++ b/components/cli/cli/command/service/progress/progress.go @@ -6,6 +6,7 @@ import ( "io" "os" "os/signal" + "strings" "time" "github.com/docker/docker/api/types" @@ -29,6 +30,13 @@ var ( swarm.TaskStateReady: 7, swarm.TaskStateStarting: 8, swarm.TaskStateRunning: 9, + + // The following states are not actually shown in progress + // output, but are used internally for ordering. + swarm.TaskStateComplete: 10, + swarm.TaskStateShutdown: 11, + swarm.TaskStateFailed: 12, + swarm.TaskStateRejected: 13, } longestState int @@ -40,22 +48,26 @@ const ( ) type progressUpdater interface { - update(service swarm.Service, tasks []swarm.Task, activeNodes map[string]swarm.Node, rollback bool) (bool, error) + update(service swarm.Service, tasks []swarm.Task, activeNodes map[string]struct{}, rollback bool) (bool, error) } func init() { for state := range numberedStates { - if len(state) > longestState { + if !terminalState(state) && len(state) > longestState { longestState = len(state) } } } +func terminalState(state swarm.TaskState) bool { + return numberedStates[state] > numberedStates[swarm.TaskStateRunning] +} + func stateToProgress(state swarm.TaskState, rollback bool) int64 { if !rollback { return numberedStates[state] } - return int64(len(numberedStates)) - numberedStates[state] + return numberedStates[swarm.TaskStateRunning] - numberedStates[state] } // ServiceProgress outputs progress information for convergence of a service. @@ -192,16 +204,16 @@ func ServiceProgress(ctx context.Context, client client.APIClient, serviceID str } } -func getActiveNodes(ctx context.Context, client client.APIClient) (map[string]swarm.Node, error) { +func getActiveNodes(ctx context.Context, client client.APIClient) (map[string]struct{}, error) { nodes, err := client.NodeList(ctx, types.NodeListOptions{}) if err != nil { return nil, err } - activeNodes := make(map[string]swarm.Node) + activeNodes := make(map[string]struct{}) for _, n := range nodes { if n.Status.State != swarm.NodeStateDown { - activeNodes[n.ID] = n + activeNodes[n.ID] = struct{}{} } } return activeNodes, nil @@ -235,6 +247,18 @@ func writeOverallProgress(progressOut progress.Output, numerator, denominator in }) } +func truncError(errMsg string) string { + // Remove newlines from the error, which corrupt the output. + errMsg = strings.Replace(errMsg, "\n", " ", -1) + + // Limit the length to 75 characters, so that even on narrow terminals + // this will not overflow to the next line. + if len(errMsg) > 75 { + errMsg = errMsg[:74] + "…" + } + return errMsg +} + type replicatedProgressUpdater struct { progressOut progress.Output @@ -246,8 +270,7 @@ type replicatedProgressUpdater struct { done bool } -// nolint: gocyclo -func (u *replicatedProgressUpdater) update(service swarm.Service, tasks []swarm.Task, activeNodes map[string]swarm.Node, rollback bool) (bool, error) { +func (u *replicatedProgressUpdater) update(service swarm.Service, tasks []swarm.Task, activeNodes map[string]struct{}, rollback bool) (bool, error) { if service.Spec.Mode.Replicated == nil || service.Spec.Mode.Replicated.Replicas == nil { return false, errors.New("no replica count") } @@ -267,27 +290,7 @@ func (u *replicatedProgressUpdater) update(service swarm.Service, tasks []swarm. u.initialized = true } - // If there are multiple tasks with the same slot number, favor the one - // with the *lowest* desired state. This can happen in restart - // scenarios. - tasksBySlot := make(map[int]swarm.Task) - for _, task := range tasks { - if numberedStates[task.DesiredState] == 0 { - continue - } - if existingTask, ok := tasksBySlot[task.Slot]; ok { - if numberedStates[existingTask.DesiredState] <= numberedStates[task.DesiredState] { - continue - } - } - if task.NodeID != "" { - if _, nodeActive := activeNodes[task.NodeID]; nodeActive { - tasksBySlot[task.Slot] = task - } - } else { - tasksBySlot[task.Slot] = task - } - } + tasksBySlot := u.tasksBySlot(tasks, activeNodes) // If we had reached a converged state, check if we are still converged. if u.done { @@ -308,18 +311,11 @@ func (u *replicatedProgressUpdater) update(service swarm.Service, tasks []swarm. u.slotMap[task.Slot] = mappedSlot } - if !u.done && replicas <= maxProgressBars && uint64(mappedSlot) <= replicas { - u.progressOut.WriteProgress(progress.Progress{ - ID: fmt.Sprintf("%d/%d", mappedSlot, replicas), - Action: fmt.Sprintf("%-[1]*s", longestState, task.Status.State), - Current: stateToProgress(task.Status.State, rollback), - Total: maxProgress, - HideCounts: true, - }) - } - if task.Status.State == swarm.TaskStateRunning { + if !terminalState(task.DesiredState) && task.Status.State == swarm.TaskStateRunning { running++ } + + u.writeTaskProgress(task, mappedSlot, replicas, rollback) } if !u.done { @@ -333,6 +329,62 @@ func (u *replicatedProgressUpdater) update(service swarm.Service, tasks []swarm. return running == replicas, nil } +func (u *replicatedProgressUpdater) tasksBySlot(tasks []swarm.Task, activeNodes map[string]struct{}) map[int]swarm.Task { + // If there are multiple tasks with the same slot number, favor the one + // with the *lowest* desired state. This can happen in restart + // scenarios. + tasksBySlot := make(map[int]swarm.Task) + for _, task := range tasks { + if numberedStates[task.DesiredState] == 0 || numberedStates[task.Status.State] == 0 { + continue + } + if existingTask, ok := tasksBySlot[task.Slot]; ok { + if numberedStates[existingTask.DesiredState] < numberedStates[task.DesiredState] { + continue + } + // If the desired states match, observed state breaks + // ties. This can happen with the "start first" service + // update mode. + if numberedStates[existingTask.DesiredState] == numberedStates[task.DesiredState] && + numberedStates[existingTask.Status.State] <= numberedStates[task.Status.State] { + continue + } + } + if task.NodeID != "" { + if _, nodeActive := activeNodes[task.NodeID]; !nodeActive { + continue + } + } + tasksBySlot[task.Slot] = task + } + + return tasksBySlot +} + +func (u *replicatedProgressUpdater) writeTaskProgress(task swarm.Task, mappedSlot int, replicas uint64, rollback bool) { + if u.done || replicas > maxProgressBars || uint64(mappedSlot) > replicas { + return + } + + if task.Status.Err != "" { + u.progressOut.WriteProgress(progress.Progress{ + ID: fmt.Sprintf("%d/%d", mappedSlot, replicas), + Action: truncError(task.Status.Err), + }) + return + } + + if !terminalState(task.DesiredState) && !terminalState(task.Status.State) { + u.progressOut.WriteProgress(progress.Progress{ + ID: fmt.Sprintf("%d/%d", mappedSlot, replicas), + Action: fmt.Sprintf("%-[1]*s", longestState, task.Status.State), + Current: stateToProgress(task.Status.State, rollback), + Total: maxProgress, + HideCounts: true, + }) + } +} + type globalProgressUpdater struct { progressOut progress.Output @@ -340,22 +392,8 @@ type globalProgressUpdater struct { done bool } -func (u *globalProgressUpdater) update(service swarm.Service, tasks []swarm.Task, activeNodes map[string]swarm.Node, rollback bool) (bool, error) { - // If there are multiple tasks with the same node ID, favor the one - // with the *lowest* desired state. This can happen in restart - // scenarios. - tasksByNode := make(map[string]swarm.Task) - for _, task := range tasks { - if numberedStates[task.DesiredState] == 0 { - continue - } - if existingTask, ok := tasksByNode[task.NodeID]; ok { - if numberedStates[existingTask.DesiredState] <= numberedStates[task.DesiredState] { - continue - } - } - tasksByNode[task.NodeID] = task - } +func (u *globalProgressUpdater) update(service swarm.Service, tasks []swarm.Task, activeNodes map[string]struct{}, rollback bool) (bool, error) { + tasksByNode := u.tasksByNode(tasks) // We don't have perfect knowledge of how many nodes meet the // constraints for this service. But the orchestrator creates tasks @@ -392,19 +430,12 @@ func (u *globalProgressUpdater) update(service swarm.Service, tasks []swarm.Task running := 0 for _, task := range tasksByNode { - if node, nodeActive := activeNodes[task.NodeID]; nodeActive { - if !u.done && nodeCount <= maxProgressBars { - u.progressOut.WriteProgress(progress.Progress{ - ID: stringid.TruncateID(node.ID), - Action: fmt.Sprintf("%-[1]*s", longestState, task.Status.State), - Current: stateToProgress(task.Status.State, rollback), - Total: maxProgress, - HideCounts: true, - }) - } - if task.Status.State == swarm.TaskStateRunning { + if _, nodeActive := activeNodes[task.NodeID]; nodeActive { + if !terminalState(task.DesiredState) && task.Status.State == swarm.TaskStateRunning { running++ } + + u.writeTaskProgress(task, nodeCount, rollback) } } @@ -418,3 +449,56 @@ func (u *globalProgressUpdater) update(service swarm.Service, tasks []swarm.Task return running == nodeCount, nil } + +func (u *globalProgressUpdater) tasksByNode(tasks []swarm.Task) map[string]swarm.Task { + // If there are multiple tasks with the same node ID, favor the one + // with the *lowest* desired state. This can happen in restart + // scenarios. + tasksByNode := make(map[string]swarm.Task) + for _, task := range tasks { + if numberedStates[task.DesiredState] == 0 || numberedStates[task.Status.State] == 0 { + continue + } + if existingTask, ok := tasksByNode[task.NodeID]; ok { + if numberedStates[existingTask.DesiredState] < numberedStates[task.DesiredState] { + continue + } + + // If the desired states match, observed state breaks + // ties. This can happen with the "start first" service + // update mode. + if numberedStates[existingTask.DesiredState] == numberedStates[task.DesiredState] && + numberedStates[existingTask.Status.State] <= numberedStates[task.Status.State] { + continue + } + + } + tasksByNode[task.NodeID] = task + } + + return tasksByNode +} + +func (u *globalProgressUpdater) writeTaskProgress(task swarm.Task, nodeCount int, rollback bool) { + if u.done || nodeCount > maxProgressBars { + return + } + + if task.Status.Err != "" { + u.progressOut.WriteProgress(progress.Progress{ + ID: stringid.TruncateID(task.NodeID), + Action: truncError(task.Status.Err), + }) + return + } + + if !terminalState(task.DesiredState) && !terminalState(task.Status.State) { + u.progressOut.WriteProgress(progress.Progress{ + ID: stringid.TruncateID(task.NodeID), + Action: fmt.Sprintf("%-[1]*s", longestState, task.Status.State), + Current: stateToProgress(task.Status.State, rollback), + Total: maxProgress, + HideCounts: true, + }) + } +} diff --git a/components/cli/cli/command/service/progress/progress_test.go b/components/cli/cli/command/service/progress/progress_test.go new file mode 100644 index 0000000000..d1c118f7d7 --- /dev/null +++ b/components/cli/cli/command/service/progress/progress_test.go @@ -0,0 +1,374 @@ +package progress + +import ( + "fmt" + "strconv" + "testing" + + "github.com/docker/docker/api/types/swarm" + "github.com/docker/docker/pkg/progress" + "github.com/stretchr/testify/assert" +) + +type mockProgress struct { + p []progress.Progress +} + +func (mp *mockProgress) WriteProgress(p progress.Progress) error { + mp.p = append(mp.p, p) + return nil +} + +func (mp *mockProgress) clear() { + mp.p = nil +} + +type updaterTester struct { + t *testing.T + updater progressUpdater + p *mockProgress + service swarm.Service + activeNodes map[string]struct{} + rollback bool +} + +func (u updaterTester) testUpdater(tasks []swarm.Task, expectedConvergence bool, expectedProgress []progress.Progress) { + u.p.clear() + + converged, err := u.updater.update(u.service, tasks, u.activeNodes, u.rollback) + assert.NoError(u.t, err) + assert.Equal(u.t, expectedConvergence, converged) + assert.Equal(u.t, expectedProgress, u.p.p) +} + +func TestReplicatedProgressUpdaterOneReplica(t *testing.T) { + replicas := uint64(1) + + service := swarm.Service{ + Spec: swarm.ServiceSpec{ + Mode: swarm.ServiceMode{ + Replicated: &swarm.ReplicatedService{ + Replicas: &replicas, + }, + }, + }, + } + + p := &mockProgress{} + updaterTester := updaterTester{ + t: t, + updater: &replicatedProgressUpdater{ + progressOut: p, + }, + p: p, + activeNodes: map[string]struct{}{"a": {}, "b": {}}, + service: service, + } + + tasks := []swarm.Task{} + + updaterTester.testUpdater(tasks, false, + []progress.Progress{ + {ID: "overall progress", Action: "0 out of 1 tasks"}, + {ID: "1/1", Action: " "}, + {ID: "overall progress", Action: "0 out of 1 tasks"}, + }) + + // Task with DesiredState beyond Running is ignored + tasks = append(tasks, + swarm.Task{ID: "1", + NodeID: "a", + DesiredState: swarm.TaskStateShutdown, + Status: swarm.TaskStatus{State: swarm.TaskStateNew}, + }) + updaterTester.testUpdater(tasks, false, + []progress.Progress{ + {ID: "overall progress", Action: "0 out of 1 tasks"}, + }) + + // Task with valid DesiredState and State updates progress bar + tasks[0].DesiredState = swarm.TaskStateRunning + updaterTester.testUpdater(tasks, false, + []progress.Progress{ + {ID: "1/1", Action: "new ", Current: 1, Total: 9, HideCounts: true}, + {ID: "overall progress", Action: "0 out of 1 tasks"}, + }) + + // If the task exposes an error, we should show that instead of the + // progress bar. + tasks[0].Status.Err = "something is wrong" + updaterTester.testUpdater(tasks, false, + []progress.Progress{ + {ID: "1/1", Action: "something is wrong"}, + {ID: "overall progress", Action: "0 out of 1 tasks"}, + }) + + // When the task reaches running, update should return true + tasks[0].Status.Err = "" + tasks[0].Status.State = swarm.TaskStateRunning + updaterTester.testUpdater(tasks, true, + []progress.Progress{ + {ID: "1/1", Action: "running ", Current: 9, Total: 9, HideCounts: true}, + {ID: "overall progress", Action: "1 out of 1 tasks"}, + }) + + // If the task fails, update should return false again + tasks[0].Status.Err = "task failed" + tasks[0].Status.State = swarm.TaskStateFailed + updaterTester.testUpdater(tasks, false, + []progress.Progress{ + {ID: "1/1", Action: "task failed"}, + {ID: "overall progress", Action: "0 out of 1 tasks"}, + }) + + // If the task is restarted, progress output should be shown for the + // replacement task, not the old task. + tasks[0].DesiredState = swarm.TaskStateShutdown + tasks = append(tasks, + swarm.Task{ID: "2", + NodeID: "b", + DesiredState: swarm.TaskStateRunning, + Status: swarm.TaskStatus{State: swarm.TaskStateRunning}, + }) + updaterTester.testUpdater(tasks, true, + []progress.Progress{ + {ID: "1/1", Action: "running ", Current: 9, Total: 9, HideCounts: true}, + {ID: "overall progress", Action: "1 out of 1 tasks"}, + }) + + // Add a new task while the current one is still running, to simulate + // "start-then-stop" updates. + tasks = append(tasks, + swarm.Task{ID: "3", + NodeID: "b", + DesiredState: swarm.TaskStateRunning, + Status: swarm.TaskStatus{State: swarm.TaskStatePreparing}, + }) + updaterTester.testUpdater(tasks, false, + []progress.Progress{ + {ID: "1/1", Action: "preparing", Current: 6, Total: 9, HideCounts: true}, + {ID: "overall progress", Action: "0 out of 1 tasks"}, + }) +} + +func TestReplicatedProgressUpdaterManyReplicas(t *testing.T) { + replicas := uint64(50) + + service := swarm.Service{ + Spec: swarm.ServiceSpec{ + Mode: swarm.ServiceMode{ + Replicated: &swarm.ReplicatedService{ + Replicas: &replicas, + }, + }, + }, + } + + p := &mockProgress{} + updaterTester := updaterTester{ + t: t, + updater: &replicatedProgressUpdater{ + progressOut: p, + }, + p: p, + activeNodes: map[string]struct{}{"a": {}, "b": {}}, + service: service, + } + + tasks := []swarm.Task{} + + // No per-task progress bars because there are too many replicas + updaterTester.testUpdater(tasks, false, + []progress.Progress{ + {ID: "overall progress", Action: fmt.Sprintf("0 out of %d tasks", replicas)}, + {ID: "overall progress", Action: fmt.Sprintf("0 out of %d tasks", replicas)}, + }) + + for i := 0; i != int(replicas); i++ { + tasks = append(tasks, + swarm.Task{ + ID: strconv.Itoa(i), + Slot: i + 1, + NodeID: "a", + DesiredState: swarm.TaskStateRunning, + Status: swarm.TaskStatus{State: swarm.TaskStateNew}, + }) + + if i%2 == 1 { + tasks[i].NodeID = "b" + } + updaterTester.testUpdater(tasks, false, + []progress.Progress{ + {ID: "overall progress", Action: fmt.Sprintf("%d out of %d tasks", i, replicas)}, + }) + + tasks[i].Status.State = swarm.TaskStateRunning + updaterTester.testUpdater(tasks, uint64(i) == replicas-1, + []progress.Progress{ + {ID: "overall progress", Action: fmt.Sprintf("%d out of %d tasks", i+1, replicas)}, + }) + } +} + +func TestGlobalProgressUpdaterOneNode(t *testing.T) { + service := swarm.Service{ + Spec: swarm.ServiceSpec{ + Mode: swarm.ServiceMode{ + Global: &swarm.GlobalService{}, + }, + }, + } + + p := &mockProgress{} + updaterTester := updaterTester{ + t: t, + updater: &globalProgressUpdater{ + progressOut: p, + }, + p: p, + activeNodes: map[string]struct{}{"a": {}, "b": {}}, + service: service, + } + + tasks := []swarm.Task{} + + updaterTester.testUpdater(tasks, false, + []progress.Progress{ + {ID: "overall progress", Action: "waiting for new tasks"}, + }) + + // Task with DesiredState beyond Running is ignored + tasks = append(tasks, + swarm.Task{ID: "1", + NodeID: "a", + DesiredState: swarm.TaskStateShutdown, + Status: swarm.TaskStatus{State: swarm.TaskStateNew}, + }) + updaterTester.testUpdater(tasks, false, + []progress.Progress{ + {ID: "overall progress", Action: "0 out of 1 tasks"}, + {ID: "overall progress", Action: "0 out of 1 tasks"}, + }) + + // Task with valid DesiredState and State updates progress bar + tasks[0].DesiredState = swarm.TaskStateRunning + updaterTester.testUpdater(tasks, false, + []progress.Progress{ + {ID: "a", Action: "new ", Current: 1, Total: 9, HideCounts: true}, + {ID: "overall progress", Action: "0 out of 1 tasks"}, + }) + + // If the task exposes an error, we should show that instead of the + // progress bar. + tasks[0].Status.Err = "something is wrong" + updaterTester.testUpdater(tasks, false, + []progress.Progress{ + {ID: "a", Action: "something is wrong"}, + {ID: "overall progress", Action: "0 out of 1 tasks"}, + }) + + // When the task reaches running, update should return true + tasks[0].Status.Err = "" + tasks[0].Status.State = swarm.TaskStateRunning + updaterTester.testUpdater(tasks, true, + []progress.Progress{ + {ID: "a", Action: "running ", Current: 9, Total: 9, HideCounts: true}, + {ID: "overall progress", Action: "1 out of 1 tasks"}, + }) + + // If the task fails, update should return false again + tasks[0].Status.Err = "task failed" + tasks[0].Status.State = swarm.TaskStateFailed + updaterTester.testUpdater(tasks, false, + []progress.Progress{ + {ID: "a", Action: "task failed"}, + {ID: "overall progress", Action: "0 out of 1 tasks"}, + }) + + // If the task is restarted, progress output should be shown for the + // replacement task, not the old task. + tasks[0].DesiredState = swarm.TaskStateShutdown + tasks = append(tasks, + swarm.Task{ID: "2", + NodeID: "a", + DesiredState: swarm.TaskStateRunning, + Status: swarm.TaskStatus{State: swarm.TaskStateRunning}, + }) + updaterTester.testUpdater(tasks, true, + []progress.Progress{ + {ID: "a", Action: "running ", Current: 9, Total: 9, HideCounts: true}, + {ID: "overall progress", Action: "1 out of 1 tasks"}, + }) + + // Add a new task while the current one is still running, to simulate + // "start-then-stop" updates. + tasks = append(tasks, + swarm.Task{ID: "3", + NodeID: "a", + DesiredState: swarm.TaskStateRunning, + Status: swarm.TaskStatus{State: swarm.TaskStatePreparing}, + }) + updaterTester.testUpdater(tasks, false, + []progress.Progress{ + {ID: "a", Action: "preparing", Current: 6, Total: 9, HideCounts: true}, + {ID: "overall progress", Action: "0 out of 1 tasks"}, + }) +} + +func TestGlobalProgressUpdaterManyNodes(t *testing.T) { + nodes := 50 + + service := swarm.Service{ + Spec: swarm.ServiceSpec{ + Mode: swarm.ServiceMode{ + Global: &swarm.GlobalService{}, + }, + }, + } + + p := &mockProgress{} + updaterTester := updaterTester{ + t: t, + updater: &globalProgressUpdater{ + progressOut: p, + }, + p: p, + activeNodes: map[string]struct{}{}, + service: service, + } + + for i := 0; i != nodes; i++ { + updaterTester.activeNodes[strconv.Itoa(i)] = struct{}{} + } + + tasks := []swarm.Task{} + + updaterTester.testUpdater(tasks, false, + []progress.Progress{ + {ID: "overall progress", Action: "waiting for new tasks"}, + }) + + for i := 0; i != nodes; i++ { + tasks = append(tasks, + swarm.Task{ + ID: "task" + strconv.Itoa(i), + NodeID: strconv.Itoa(i), + DesiredState: swarm.TaskStateRunning, + Status: swarm.TaskStatus{State: swarm.TaskStateNew}, + }) + } + + updaterTester.testUpdater(tasks, false, + []progress.Progress{ + {ID: "overall progress", Action: fmt.Sprintf("0 out of %d tasks", nodes)}, + {ID: "overall progress", Action: fmt.Sprintf("0 out of %d tasks", nodes)}, + }) + + for i := 0; i != nodes; i++ { + tasks[i].Status.State = swarm.TaskStateRunning + updaterTester.testUpdater(tasks, i == nodes-1, + []progress.Progress{ + {ID: "overall progress", Action: fmt.Sprintf("%d out of %d tasks", i+1, nodes)}, + }) + } +} diff --git a/components/cli/cli/command/service/ps.go b/components/cli/cli/command/service/ps.go index 741f6b589f..07dbba7230 100644 --- a/components/cli/cli/command/service/ps.go +++ b/components/cli/cli/command/service/ps.go @@ -5,7 +5,6 @@ import ( "github.com/docker/cli/cli" "github.com/docker/cli/cli/command" - "github.com/docker/cli/cli/command/formatter" "github.com/docker/cli/cli/command/idresolver" "github.com/docker/cli/cli/command/node" "github.com/docker/cli/cli/command/task" @@ -65,11 +64,7 @@ func runPS(dockerCli command.Cli, options psOptions) error { format := options.format if len(format) == 0 { - if len(dockerCli.ConfigFile().TasksFormat) > 0 && !options.quiet { - format = dockerCli.ConfigFile().TasksFormat - } else { - format = formatter.TableFormatKey - } + format = task.DefaultFormat(dockerCli.ConfigFile(), options.quiet) } if err := task.Print(ctx, dockerCli, tasks, idresolver.New(client, options.noResolve), !options.noTrunc, options.quiet, format); err != nil { return err diff --git a/components/cli/cli/command/service/ps_test.go b/components/cli/cli/command/service/ps_test.go index a53748d6d3..0e1bcb438b 100644 --- a/components/cli/cli/command/service/ps_test.go +++ b/components/cli/cli/command/service/ps_test.go @@ -107,7 +107,7 @@ func TestRunPSWarnsOnNotFound(t *testing.T) { } out := new(bytes.Buffer) - cli := test.NewFakeCli(client, out) + cli := test.NewFakeCliWithOutput(client, out) options := psOptions{ services: []string{"foo", "bar"}, filter: opts.NewFilterOpt(), diff --git a/components/cli/cli/command/service/scale.go b/components/cli/cli/command/service/scale.go index 397fe1800c..f58786156a 100644 --- a/components/cli/cli/command/service/scale.go +++ b/components/cli/cli/command/service/scale.go @@ -12,17 +12,28 @@ import ( "github.com/docker/docker/api/types" "github.com/pkg/errors" "github.com/spf13/cobra" + "github.com/spf13/pflag" ) +type scaleOptions struct { + detach bool +} + func newScaleCommand(dockerCli *command.DockerCli) *cobra.Command { - return &cobra.Command{ + options := &scaleOptions{} + + cmd := &cobra.Command{ Use: "scale SERVICE=REPLICAS [SERVICE=REPLICAS...]", Short: "Scale one or multiple replicated services", Args: scaleArgs, RunE: func(cmd *cobra.Command, args []string) error { - return runScale(dockerCli, args) + return runScale(dockerCli, cmd.Flags(), options, args) }, } + + flags := cmd.Flags() + addDetachFlag(flags, &options.detach) + return cmd } func scaleArgs(cmd *cobra.Command, args []string) error { @@ -43,8 +54,11 @@ func scaleArgs(cmd *cobra.Command, args []string) error { return nil } -func runScale(dockerCli *command.DockerCli, args []string) error { +func runScale(dockerCli *command.DockerCli, flags *pflag.FlagSet, options *scaleOptions, args []string) error { var errs []string + var serviceIDs []string + ctx := context.Background() + for _, arg := range args { parts := strings.SplitN(arg, "=", 2) serviceID, scaleStr := parts[0], parts[1] @@ -56,8 +70,23 @@ func runScale(dockerCli *command.DockerCli, args []string) error { continue } - if err := runServiceScale(dockerCli, serviceID, scale); err != nil { + if err := runServiceScale(ctx, dockerCli, serviceID, scale); err != nil { errs = append(errs, fmt.Sprintf("%s: %v", serviceID, err)) + } else { + serviceIDs = append(serviceIDs, serviceID) + } + + } + + if len(serviceIDs) > 0 { + if options.detach { + warnDetachDefault(dockerCli.Err(), dockerCli.Client().ClientVersion(), flags, "scaled") + } else { + for _, serviceID := range serviceIDs { + if err := waitOnService(ctx, dockerCli, serviceID, false); err != nil { + errs = append(errs, fmt.Sprintf("%s: %v", serviceID, err)) + } + } } } @@ -67,9 +96,8 @@ func runScale(dockerCli *command.DockerCli, args []string) error { return errors.Errorf(strings.Join(errs, "\n")) } -func runServiceScale(dockerCli *command.DockerCli, serviceID string, scale uint64) error { +func runServiceScale(ctx context.Context, dockerCli *command.DockerCli, serviceID string, scale uint64) error { client := dockerCli.Client() - ctx := context.Background() service, _, err := client.ServiceInspectWithRaw(ctx, serviceID, types.ServiceInspectOptions{}) if err != nil { diff --git a/components/cli/cli/command/stack/client_test.go b/components/cli/cli/command/stack/client_test.go index 50442783fa..d1d85193e7 100644 --- a/components/cli/cli/command/stack/client_test.go +++ b/components/cli/cli/command/stack/client_test.go @@ -15,6 +15,8 @@ import ( type fakeClient struct { client.Client + version string + services []string networks []string secrets []string @@ -45,6 +47,10 @@ func (cli *fakeClient) ServerVersion(ctx context.Context) (types.Version, error) }, nil } +func (cli *fakeClient) ClientVersion() string { + return cli.version +} + func (cli *fakeClient) ServiceList(ctx context.Context, options types.ServiceListOptions) ([]swarm.Service, error) { if cli.serviceListFunc != nil { return cli.serviceListFunc(options) diff --git a/components/cli/cli/command/stack/deploy_test.go b/components/cli/cli/command/stack/deploy_test.go index ffdd759699..c04f86c251 100644 --- a/components/cli/cli/command/stack/deploy_test.go +++ b/components/cli/cli/command/stack/deploy_test.go @@ -1,7 +1,6 @@ package stack import ( - "bytes" "testing" "github.com/docker/cli/cli/compose/convert" @@ -18,10 +17,8 @@ func TestPruneServices(t *testing.T) { "keep": {}, } client := &fakeClient{services: []string{objectName("foo", "keep"), objectName("foo", "remove")}} - dockerCli := test.NewFakeCli(client, &bytes.Buffer{}) - dockerCli.SetErr(&bytes.Buffer{}) + dockerCli := test.NewFakeCli(client) pruneServices(ctx, dockerCli, namespace, services) - assert.Equal(t, buildObjectIDs([]string{objectName("foo", "remove")}), client.removedServices) } diff --git a/components/cli/cli/command/stack/list_test.go b/components/cli/cli/command/stack/list_test.go index 4f258977ed..de1aa02365 100644 --- a/components/cli/cli/command/stack/list_test.go +++ b/components/cli/cli/command/stack/list_test.go @@ -50,7 +50,7 @@ func TestListErrors(t *testing.T) { for _, tc := range testCases { cmd := newListCommand(test.NewFakeCli(&fakeClient{ serviceListFunc: tc.serviceListFunc, - }, &bytes.Buffer{})) + })) cmd.SetArgs(tc.args) cmd.SetOutput(ioutil.Discard) for key, value := range tc.flags { @@ -62,7 +62,7 @@ func TestListErrors(t *testing.T) { func TestListWithFormat(t *testing.T) { buf := new(bytes.Buffer) - cmd := newListCommand(test.NewFakeCli(&fakeClient{ + cmd := newListCommand(test.NewFakeCliWithOutput(&fakeClient{ serviceListFunc: func(options types.ServiceListOptions) ([]swarm.Service, error) { return []swarm.Service{ *Service( @@ -81,7 +81,7 @@ func TestListWithFormat(t *testing.T) { func TestListWithoutFormat(t *testing.T) { buf := new(bytes.Buffer) - cmd := newListCommand(test.NewFakeCli(&fakeClient{ + cmd := newListCommand(test.NewFakeCliWithOutput(&fakeClient{ serviceListFunc: func(options types.ServiceListOptions) ([]swarm.Service, error) { return []swarm.Service{ *Service( @@ -99,7 +99,7 @@ func TestListWithoutFormat(t *testing.T) { func TestListOrder(t *testing.T) { buf := new(bytes.Buffer) - cmd := newListCommand(test.NewFakeCli(&fakeClient{ + cmd := newListCommand(test.NewFakeCliWithOutput(&fakeClient{ serviceListFunc: func(options types.ServiceListOptions) ([]swarm.Service, error) { return []swarm.Service{ *Service( diff --git a/components/cli/cli/command/stack/ps.go b/components/cli/cli/command/stack/ps.go index ae9ed0f70a..25bd1eee10 100644 --- a/components/cli/cli/command/stack/ps.go +++ b/components/cli/cli/command/stack/ps.go @@ -5,7 +5,6 @@ import ( "github.com/docker/cli/cli" "github.com/docker/cli/cli/command" - "github.com/docker/cli/cli/command/formatter" "github.com/docker/cli/cli/command/idresolver" "github.com/docker/cli/cli/command/task" "github.com/docker/cli/opts" @@ -58,17 +57,13 @@ func runPS(dockerCli command.Cli, options psOptions) error { } if len(tasks) == 0 { - fmt.Fprintf(dockerCli.Out(), "Nothing found in stack: %s\n", namespace) + fmt.Fprintf(dockerCli.Err(), "Nothing found in stack: %s\n", namespace) return nil } format := options.format if len(format) == 0 { - if len(dockerCli.ConfigFile().TasksFormat) > 0 && !options.quiet { - format = dockerCli.ConfigFile().TasksFormat - } else { - format = formatter.TableFormatKey - } + format = task.DefaultFormat(dockerCli.ConfigFile(), options.quiet) } return task.Print(ctx, dockerCli, tasks, idresolver.New(client, options.noResolve), !options.noTrunc, options.quiet, format) diff --git a/components/cli/cli/command/stack/ps_test.go b/components/cli/cli/command/stack/ps_test.go index afda419eb4..5387dd0347 100644 --- a/components/cli/cli/command/stack/ps_test.go +++ b/components/cli/cli/command/stack/ps_test.go @@ -1,7 +1,6 @@ package stack import ( - "bytes" "io/ioutil" "testing" "time" @@ -45,7 +44,7 @@ func TestStackPsErrors(t *testing.T) { for _, tc := range testCases { cmd := newPsCommand(test.NewFakeCli(&fakeClient{ taskListFunc: tc.taskListFunc, - }, &bytes.Buffer{})) + })) cmd.SetArgs(tc.args) cmd.SetOutput(ioutil.Discard) testutil.ErrorContains(t, cmd.Execute(), tc.expectedError) @@ -53,55 +52,52 @@ func TestStackPsErrors(t *testing.T) { } func TestStackPsEmptyStack(t *testing.T) { - buf := new(bytes.Buffer) - cmd := newPsCommand(test.NewFakeCli(&fakeClient{ + fakeCli := test.NewFakeCli(&fakeClient{ taskListFunc: func(options types.TaskListOptions) ([]swarm.Task, error) { return []swarm.Task{}, nil }, - }, buf)) + }) + cmd := newPsCommand(fakeCli) cmd.SetArgs([]string{"foo"}) + assert.NoError(t, cmd.Execute()) - testutil.EqualNormalizedString(t, testutil.RemoveSpace, buf.String(), "Nothing found in stack: foo") + assert.Equal(t, "", fakeCli.OutBuffer().String()) + assert.Equal(t, "Nothing found in stack: foo\n", fakeCli.ErrBuffer().String()) } func TestStackPsWithQuietOption(t *testing.T) { - buf := new(bytes.Buffer) cli := test.NewFakeCli(&fakeClient{ taskListFunc: func(options types.TaskListOptions) ([]swarm.Task, error) { return []swarm.Task{*Task(TaskID("id-foo"))}, nil }, - }, buf) - cli.SetConfigfile(&configfile.ConfigFile{}) + }) cmd := newPsCommand(cli) cmd.SetArgs([]string{"foo"}) cmd.Flags().Set("quiet", "true") assert.NoError(t, cmd.Execute()) - actual := buf.String() + actual := cli.OutBuffer().String() expected := golden.Get(t, []byte(actual), "stack-ps-with-quiet-option.golden") testutil.EqualNormalizedString(t, testutil.RemoveSpace, actual, string(expected)) } func TestStackPsWithNoTruncOption(t *testing.T) { - buf := new(bytes.Buffer) cli := test.NewFakeCli(&fakeClient{ taskListFunc: func(options types.TaskListOptions) ([]swarm.Task, error) { return []swarm.Task{*Task(TaskID("xn4cypcov06f2w8gsbaf2lst3"))}, nil }, - }, buf) - cli.SetConfigfile(&configfile.ConfigFile{}) + }) cmd := newPsCommand(cli) cmd.SetArgs([]string{"foo"}) cmd.Flags().Set("no-trunc", "true") cmd.Flags().Set("format", "{{ .ID }}") assert.NoError(t, cmd.Execute()) - actual := buf.String() + actual := cli.OutBuffer().String() expected := golden.Get(t, []byte(actual), "stack-ps-with-no-trunc-option.golden") testutil.EqualNormalizedString(t, testutil.RemoveSpace, actual, string(expected)) } func TestStackPsWithNoResolveOption(t *testing.T) { - buf := new(bytes.Buffer) cli := test.NewFakeCli(&fakeClient{ taskListFunc: func(options types.TaskListOptions) ([]swarm.Task, error) { return []swarm.Task{*Task( @@ -111,55 +107,50 @@ func TestStackPsWithNoResolveOption(t *testing.T) { nodeInspectWithRaw: func(ref string) (swarm.Node, []byte, error) { return *Node(NodeName("node-name-bar")), nil, nil }, - }, buf) - cli.SetConfigfile(&configfile.ConfigFile{}) + }) cmd := newPsCommand(cli) cmd.SetArgs([]string{"foo"}) cmd.Flags().Set("no-resolve", "true") cmd.Flags().Set("format", "{{ .Node }}") assert.NoError(t, cmd.Execute()) - actual := buf.String() + actual := cli.OutBuffer().String() expected := golden.Get(t, []byte(actual), "stack-ps-with-no-resolve-option.golden") testutil.EqualNormalizedString(t, testutil.RemoveSpace, actual, string(expected)) } func TestStackPsWithFormat(t *testing.T) { - buf := new(bytes.Buffer) cli := test.NewFakeCli(&fakeClient{ taskListFunc: func(options types.TaskListOptions) ([]swarm.Task, error) { return []swarm.Task{*Task(TaskServiceID("service-id-foo"))}, nil }, - }, buf) - cli.SetConfigfile(&configfile.ConfigFile{}) + }) cmd := newPsCommand(cli) cmd.SetArgs([]string{"foo"}) cmd.Flags().Set("format", "{{ .Name }}") assert.NoError(t, cmd.Execute()) - actual := buf.String() + actual := cli.OutBuffer().String() expected := golden.Get(t, []byte(actual), "stack-ps-with-format.golden") testutil.EqualNormalizedString(t, testutil.RemoveSpace, actual, string(expected)) } func TestStackPsWithConfigFormat(t *testing.T) { - buf := new(bytes.Buffer) cli := test.NewFakeCli(&fakeClient{ taskListFunc: func(options types.TaskListOptions) ([]swarm.Task, error) { return []swarm.Task{*Task(TaskServiceID("service-id-foo"))}, nil }, - }, buf) - cli.SetConfigfile(&configfile.ConfigFile{ + }) + cli.SetConfigFile(&configfile.ConfigFile{ TasksFormat: "{{ .Name }}", }) cmd := newPsCommand(cli) cmd.SetArgs([]string{"foo"}) assert.NoError(t, cmd.Execute()) - actual := buf.String() + actual := cli.OutBuffer().String() expected := golden.Get(t, []byte(actual), "stack-ps-with-config-format.golden") testutil.EqualNormalizedString(t, testutil.RemoveSpace, actual, string(expected)) } func TestStackPsWithoutFormat(t *testing.T) { - buf := new(bytes.Buffer) cli := test.NewFakeCli(&fakeClient{ taskListFunc: func(options types.TaskListOptions) ([]swarm.Task, error) { return []swarm.Task{*Task( @@ -174,12 +165,11 @@ func TestStackPsWithoutFormat(t *testing.T) { nodeInspectWithRaw: func(ref string) (swarm.Node, []byte, error) { return *Node(NodeName("node-name-bar")), nil, nil }, - }, buf) - cli.SetConfigfile(&configfile.ConfigFile{}) + }) cmd := newPsCommand(cli) cmd.SetArgs([]string{"foo"}) assert.NoError(t, cmd.Execute()) - actual := buf.String() + actual := cli.OutBuffer().String() expected := golden.Get(t, []byte(actual), "stack-ps-without-format.golden") testutil.EqualNormalizedString(t, testutil.RemoveSpace, actual, string(expected)) } diff --git a/components/cli/cli/command/stack/remove.go b/components/cli/cli/command/stack/remove.go index 20d3ee71db..d95171aabf 100644 --- a/components/cli/cli/command/stack/remove.go +++ b/components/cli/cli/command/stack/remove.go @@ -51,20 +51,16 @@ func runRemove(dockerCli command.Cli, opts removeOptions) error { return err } - secrets, err := getStackSecrets(ctx, client, namespace) - if err != nil { - return err + var secrets []swarm.Secret + if versions.GreaterThanOrEqualTo(client.ClientVersion(), "1.25") { + secrets, err = getStackSecrets(ctx, client, namespace) + if err != nil { + return err + } } var configs []swarm.Config - - version, err := client.ServerVersion(ctx) - if err != nil { - return err - } - if versions.LessThan(version.APIVersion, "1.30") { - fmt.Fprintf(dockerCli.Err(), "WARNING: ignoring \"configs\" (requires API version 1.30, but the Docker daemon API version is %s)\n", version.APIVersion) - } else { + if versions.GreaterThanOrEqualTo(client.ClientVersion(), "1.30") { configs, err = getStackConfigs(ctx, client, namespace) if err != nil { return err @@ -72,7 +68,7 @@ func runRemove(dockerCli command.Cli, opts removeOptions) error { } if len(services)+len(networks)+len(secrets)+len(configs) == 0 { - fmt.Fprintf(dockerCli.Out(), "Nothing found in stack: %s\n", namespace) + fmt.Fprintf(dockerCli.Err(), "Nothing found in stack: %s\n", namespace) continue } @@ -97,14 +93,15 @@ func removeServices( dockerCli command.Cli, services []swarm.Service, ) bool { - var err error + var hasError bool for _, service := range services { fmt.Fprintf(dockerCli.Err(), "Removing service %s\n", service.Spec.Name) - if err = dockerCli.Client().ServiceRemove(ctx, service.ID); err != nil { + if err := dockerCli.Client().ServiceRemove(ctx, service.ID); err != nil { + hasError = true fmt.Fprintf(dockerCli.Err(), "Failed to remove service %s: %s", service.ID, err) } } - return err != nil + return hasError } func removeNetworks( @@ -112,14 +109,15 @@ func removeNetworks( dockerCli command.Cli, networks []types.NetworkResource, ) bool { - var err error + var hasError bool for _, network := range networks { fmt.Fprintf(dockerCli.Err(), "Removing network %s\n", network.Name) - if err = dockerCli.Client().NetworkRemove(ctx, network.ID); err != nil { + if err := dockerCli.Client().NetworkRemove(ctx, network.ID); err != nil { + hasError = true fmt.Fprintf(dockerCli.Err(), "Failed to remove network %s: %s", network.ID, err) } } - return err != nil + return hasError } func removeSecrets( @@ -127,14 +125,15 @@ func removeSecrets( dockerCli command.Cli, secrets []swarm.Secret, ) bool { - var err error + var hasError bool for _, secret := range secrets { fmt.Fprintf(dockerCli.Err(), "Removing secret %s\n", secret.Spec.Name) - if err = dockerCli.Client().SecretRemove(ctx, secret.ID); err != nil { + if err := dockerCli.Client().SecretRemove(ctx, secret.ID); err != nil { + hasError = true fmt.Fprintf(dockerCli.Err(), "Failed to remove secret %s: %s", secret.ID, err) } } - return err != nil + return hasError } func removeConfigs( @@ -142,12 +141,13 @@ func removeConfigs( dockerCli command.Cli, configs []swarm.Config, ) bool { - var err error + var hasError bool for _, config := range configs { fmt.Fprintf(dockerCli.Err(), "Removing config %s\n", config.Spec.Name) - if err = dockerCli.Client().ConfigRemove(ctx, config.ID); err != nil { + if err := dockerCli.Client().ConfigRemove(ctx, config.ID); err != nil { + hasError = true fmt.Fprintf(dockerCli.Err(), "Failed to remove config %s: %s", config.ID, err) } } - return err != nil + return hasError } diff --git a/components/cli/cli/command/stack/remove_test.go b/components/cli/cli/command/stack/remove_test.go index 498416ebe8..88ad8a07d3 100644 --- a/components/cli/cli/command/stack/remove_test.go +++ b/components/cli/cli/command/stack/remove_test.go @@ -1,7 +1,6 @@ package stack import ( - "bytes" "errors" "io/ioutil" "strings" @@ -11,53 +10,73 @@ import ( "github.com/stretchr/testify/assert" ) -func TestRemoveStack(t *testing.T) { +func fakeClientForRemoveStackTest(version string) *fakeClient { allServices := []string{ objectName("foo", "service1"), objectName("foo", "service2"), objectName("bar", "service1"), objectName("bar", "service2"), } - allServiceIDs := buildObjectIDs(allServices) - allNetworks := []string{ objectName("foo", "network1"), objectName("bar", "network1"), } - allNetworkIDs := buildObjectIDs(allNetworks) - allSecrets := []string{ objectName("foo", "secret1"), objectName("foo", "secret2"), objectName("bar", "secret1"), } - allSecretIDs := buildObjectIDs(allSecrets) - allConfigs := []string{ objectName("foo", "config1"), objectName("foo", "config2"), objectName("bar", "config1"), } - allConfigIDs := buildObjectIDs(allConfigs) - - cli := &fakeClient{ + return &fakeClient{ + version: version, services: allServices, networks: allNetworks, secrets: allSecrets, configs: allConfigs, } - cmd := newRemoveCommand(test.NewFakeCli(cli, &bytes.Buffer{})) +} + +func TestRemoveStackVersion124DoesNotRemoveConfigsOrSecrets(t *testing.T) { + client := fakeClientForRemoveStackTest("1.24") + cmd := newRemoveCommand(test.NewFakeCli(client)) cmd.SetArgs([]string{"foo", "bar"}) assert.NoError(t, cmd.Execute()) - assert.Equal(t, allServiceIDs, cli.removedServices) - assert.Equal(t, allNetworkIDs, cli.removedNetworks) - assert.Equal(t, allSecretIDs, cli.removedSecrets) - assert.Equal(t, allConfigIDs, cli.removedConfigs) + assert.Equal(t, buildObjectIDs(client.services), client.removedServices) + assert.Equal(t, buildObjectIDs(client.networks), client.removedNetworks) + assert.Nil(t, client.removedSecrets) + assert.Nil(t, client.removedConfigs) } -func TestSkipEmptyStack(t *testing.T) { - buf := new(bytes.Buffer) +func TestRemoveStackVersion125DoesNotRemoveConfigs(t *testing.T) { + client := fakeClientForRemoveStackTest("1.25") + cmd := newRemoveCommand(test.NewFakeCli(client)) + cmd.SetArgs([]string{"foo", "bar"}) + + assert.NoError(t, cmd.Execute()) + assert.Equal(t, buildObjectIDs(client.services), client.removedServices) + assert.Equal(t, buildObjectIDs(client.networks), client.removedNetworks) + assert.Equal(t, buildObjectIDs(client.secrets), client.removedSecrets) + assert.Nil(t, client.removedConfigs) +} + +func TestRemoveStackVersion130RemovesEverything(t *testing.T) { + client := fakeClientForRemoveStackTest("1.30") + cmd := newRemoveCommand(test.NewFakeCli(client)) + cmd.SetArgs([]string{"foo", "bar"}) + + assert.NoError(t, cmd.Execute()) + assert.Equal(t, buildObjectIDs(client.services), client.removedServices) + assert.Equal(t, buildObjectIDs(client.networks), client.removedNetworks) + assert.Equal(t, buildObjectIDs(client.secrets), client.removedSecrets) + assert.Equal(t, buildObjectIDs(client.configs), client.removedConfigs) +} + +func TestRemoveStackSkipEmpty(t *testing.T) { allServices := []string{objectName("bar", "service1"), objectName("bar", "service2")} allServiceIDs := buildObjectIDs(allServices) @@ -70,21 +89,24 @@ func TestSkipEmptyStack(t *testing.T) { allConfigs := []string{objectName("bar", "config1")} allConfigIDs := buildObjectIDs(allConfigs) - cli := &fakeClient{ + fakeClient := &fakeClient{ + version: "1.30", services: allServices, networks: allNetworks, secrets: allSecrets, configs: allConfigs, } - cmd := newRemoveCommand(test.NewFakeCli(cli, buf)) + fakeCli := test.NewFakeCli(fakeClient) + cmd := newRemoveCommand(fakeCli) cmd.SetArgs([]string{"foo", "bar"}) assert.NoError(t, cmd.Execute()) - assert.Contains(t, buf.String(), "Nothing found in stack: foo") - assert.Equal(t, allServiceIDs, cli.removedServices) - assert.Equal(t, allNetworkIDs, cli.removedNetworks) - assert.Equal(t, allSecretIDs, cli.removedSecrets) - assert.Equal(t, allConfigIDs, cli.removedConfigs) + assert.Equal(t, "", fakeCli.OutBuffer().String()) + assert.Contains(t, fakeCli.ErrBuffer().String(), "Nothing found in stack: foo\n") + assert.Equal(t, allServiceIDs, fakeClient.removedServices) + assert.Equal(t, allNetworkIDs, fakeClient.removedNetworks) + assert.Equal(t, allSecretIDs, fakeClient.removedSecrets) + assert.Equal(t, allConfigIDs, fakeClient.removedConfigs) } func TestRemoveContinueAfterError(t *testing.T) { @@ -102,6 +124,7 @@ func TestRemoveContinueAfterError(t *testing.T) { removedServices := []string{} cli := &fakeClient{ + version: "1.30", services: allServices, networks: allNetworks, secrets: allSecrets, @@ -116,7 +139,7 @@ func TestRemoveContinueAfterError(t *testing.T) { return nil }, } - cmd := newRemoveCommand(test.NewFakeCli(cli, &bytes.Buffer{})) + cmd := newRemoveCommand(test.NewFakeCli(cli)) cmd.SetOutput(ioutil.Discard) cmd.SetArgs([]string{"foo", "bar"}) diff --git a/components/cli/cli/command/stack/services.go b/components/cli/cli/command/stack/services.go index 5b59c479c6..94fcb8bded 100644 --- a/components/cli/cli/command/stack/services.go +++ b/components/cli/cli/command/stack/services.go @@ -51,11 +51,9 @@ func runServices(dockerCli command.Cli, options servicesOptions) error { return err } - out := dockerCli.Out() - // if no services in this stack, print message and exit 0 if len(services) == 0 { - fmt.Fprintf(out, "Nothing found in stack: %s\n", options.namespace) + fmt.Fprintf(dockerCli.Err(), "Nothing found in stack: %s\n", options.namespace) return nil } diff --git a/components/cli/cli/command/stack/services_test.go b/components/cli/cli/command/stack/services_test.go index a87174a14d..822660fbc2 100644 --- a/components/cli/cli/command/stack/services_test.go +++ b/components/cli/cli/command/stack/services_test.go @@ -1,7 +1,6 @@ package stack import ( - "bytes" "io/ioutil" "testing" @@ -70,8 +69,7 @@ func TestStackServicesErrors(t *testing.T) { serviceListFunc: tc.serviceListFunc, nodeListFunc: tc.nodeListFunc, taskListFunc: tc.taskListFunc, - }, &bytes.Buffer{}) - cli.SetConfigfile(&configfile.ConfigFile{}) + }) cmd := newServicesCommand(cli) cmd.SetArgs(tc.args) for key, value := range tc.flags { @@ -83,77 +81,70 @@ func TestStackServicesErrors(t *testing.T) { } func TestStackServicesEmptyServiceList(t *testing.T) { - buf := new(bytes.Buffer) - cmd := newServicesCommand( - test.NewFakeCli(&fakeClient{ - serviceListFunc: func(options types.ServiceListOptions) ([]swarm.Service, error) { - return []swarm.Service{}, nil - }, - }, buf), - ) + fakeCli := test.NewFakeCli(&fakeClient{ + serviceListFunc: func(options types.ServiceListOptions) ([]swarm.Service, error) { + return []swarm.Service{}, nil + }, + }) + cmd := newServicesCommand(fakeCli) cmd.SetArgs([]string{"foo"}) assert.NoError(t, cmd.Execute()) - testutil.EqualNormalizedString(t, testutil.RemoveSpace, buf.String(), "Nothing found in stack: foo") + assert.Equal(t, "", fakeCli.OutBuffer().String()) + assert.Equal(t, "Nothing found in stack: foo\n", fakeCli.ErrBuffer().String()) } func TestStackServicesWithQuietOption(t *testing.T) { - buf := new(bytes.Buffer) cli := test.NewFakeCli(&fakeClient{ serviceListFunc: func(options types.ServiceListOptions) ([]swarm.Service, error) { return []swarm.Service{*Service(ServiceID("id-foo"))}, nil }, - }, buf) - cli.SetConfigfile(&configfile.ConfigFile{}) + }) cmd := newServicesCommand(cli) cmd.Flags().Set("quiet", "true") cmd.SetArgs([]string{"foo"}) assert.NoError(t, cmd.Execute()) - actual := buf.String() + actual := cli.OutBuffer().String() expected := golden.Get(t, []byte(actual), "stack-services-with-quiet-option.golden") testutil.EqualNormalizedString(t, testutil.RemoveSpace, actual, string(expected)) } func TestStackServicesWithFormat(t *testing.T) { - buf := new(bytes.Buffer) cli := test.NewFakeCli(&fakeClient{ serviceListFunc: func(options types.ServiceListOptions) ([]swarm.Service, error) { return []swarm.Service{ *Service(ServiceName("service-name-foo")), }, nil }, - }, buf) - cli.SetConfigfile(&configfile.ConfigFile{}) + }) cmd := newServicesCommand(cli) cmd.SetArgs([]string{"foo"}) cmd.Flags().Set("format", "{{ .Name }}") assert.NoError(t, cmd.Execute()) - actual := buf.String() + actual := cli.OutBuffer().String() expected := golden.Get(t, []byte(actual), "stack-services-with-format.golden") testutil.EqualNormalizedString(t, testutil.RemoveSpace, actual, string(expected)) } func TestStackServicesWithConfigFormat(t *testing.T) { - buf := new(bytes.Buffer) cli := test.NewFakeCli(&fakeClient{ serviceListFunc: func(options types.ServiceListOptions) ([]swarm.Service, error) { return []swarm.Service{ *Service(ServiceName("service-name-foo")), }, nil }, - }, buf) - cli.SetConfigfile(&configfile.ConfigFile{ + }) + cli.SetConfigFile(&configfile.ConfigFile{ ServicesFormat: "{{ .Name }}", }) cmd := newServicesCommand(cli) cmd.SetArgs([]string{"foo"}) assert.NoError(t, cmd.Execute()) - actual := buf.String() + actual := cli.OutBuffer().String() expected := golden.Get(t, []byte(actual), "stack-services-with-config-format.golden") testutil.EqualNormalizedString(t, testutil.RemoveSpace, actual, string(expected)) } func TestStackServicesWithoutFormat(t *testing.T) { - buf := new(bytes.Buffer) cli := test.NewFakeCli(&fakeClient{ serviceListFunc: func(options types.ServiceListOptions) ([]swarm.Service, error) { return []swarm.Service{*Service( @@ -169,12 +160,11 @@ func TestStackServicesWithoutFormat(t *testing.T) { }), )}, nil }, - }, buf) - cli.SetConfigfile(&configfile.ConfigFile{}) + }) cmd := newServicesCommand(cli) cmd.SetArgs([]string{"foo"}) assert.NoError(t, cmd.Execute()) - actual := buf.String() + actual := cli.OutBuffer().String() expected := golden.Get(t, []byte(actual), "stack-services-without-format.golden") testutil.EqualNormalizedString(t, testutil.RemoveSpace, actual, string(expected)) } diff --git a/components/cli/cli/command/swarm/ca.go b/components/cli/cli/command/swarm/ca.go index 83ac02e776..1c2f2d268b 100644 --- a/components/cli/cli/command/swarm/ca.go +++ b/components/cli/cli/command/swarm/ca.go @@ -60,7 +60,7 @@ func runCA(dockerCli command.Cli, flags *pflag.FlagSet, opts caOptions) error { } if !opts.rotate { - for _, f := range []string{flagCACert, flagCAKey, flagCACert, flagExternalCA} { + for _, f := range []string{flagCACert, flagCAKey, flagCertExpiry, flagExternalCA} { if flags.Changed(f) { return fmt.Errorf("`--%s` flag requires the `--rotate` flag to update the CA", f) } diff --git a/components/cli/cli/command/swarm/ca_test.go b/components/cli/cli/command/swarm/ca_test.go index f122567c47..a1a77d59c2 100644 --- a/components/cli/cli/command/swarm/ca_test.go +++ b/components/cli/cli/command/swarm/ca_test.go @@ -2,10 +2,14 @@ package swarm import ( "bytes" + "io/ioutil" + "os" "testing" "time" + "github.com/docker/cli/cli/internal/test" "github.com/docker/docker/api/types/swarm" + "github.com/docker/docker/pkg/testutil" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -34,6 +38,69 @@ func TestDisplayTrustRootNoRoot(t *testing.T) { assert.EqualError(t, err, "No CA information available") } +func TestDisplayTrustRootInvalidFlags(t *testing.T) { + // we need an actual PEMfile to test + tmpfile, err := ioutil.TempFile("", "pemfile") + assert.NoError(t, err) + defer os.Remove(tmpfile.Name()) + tmpfile.Write([]byte(` +-----BEGIN CERTIFICATE----- +MIIBajCCARCgAwIBAgIUe0+jYWhxN8fFOByC7yveIYgvx1kwCgYIKoZIzj0EAwIw +EzERMA8GA1UEAxMIc3dhcm0tY2EwHhcNMTcwNjI3MTUxNDAwWhcNMzcwNjIyMTUx +NDAwWjATMREwDwYDVQQDEwhzd2FybS1jYTBZMBMGByqGSM49AgEGCCqGSM49AwEH +A0IABGgbOZLd7b4b262+6m4ignIecbAZKim6djNiIS1Kl5IHciXYn7gnSpsayjn7 +GQABpgkdPeM9TEQowmtR1qSnORujQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMB +Af8EBTADAQH/MB0GA1UdDgQWBBQ6Rtcn823/fxRZyheRDFpDzuBMpTAKBggqhkjO +PQQDAgNIADBFAiEAqD3Kb2rgsy6NoTk+zEgcUi/aGBCsvQDG3vML1PXN8j0CIBjj +4nDj+GmHXcnKa8wXx70Z8OZEpRQIiKDDLmcXuslp +-----END CERTIFICATE----- +`)) + tmpfile.Close() + + errorTestCases := [][]string{ + { + "--ca-cert=" + tmpfile.Name(), + }, + { + "--ca-key=" + tmpfile.Name(), + }, + { // to make sure we're not erroring because we didn't provide a CA key along with the CA cert + + "--ca-cert=" + tmpfile.Name(), + "--ca-key=" + tmpfile.Name(), + }, + { + "--cert-expiry=2160h0m0s", + }, + { + "--external-ca=protocol=cfssl,url=https://some.com/https/url", + }, + { // to make sure we're not erroring because we didn't provide a CA cert and external CA + + "--ca-cert=" + tmpfile.Name(), + "--external-ca=protocol=cfssl,url=https://some.com/https/url", + }, + } + + for _, args := range errorTestCases { + cmd := newCACommand( + test.NewFakeCli(&fakeClient{ + swarmInspectFunc: func() (swarm.Swarm, error) { + return swarm.Swarm{ + ClusterInfo: swarm.ClusterInfo{ + TLSInfo: swarm.TLSInfo{ + TrustRoot: "root", + }, + }, + }, nil + }, + })) + assert.NoError(t, cmd.Flags().Parse(args)) + cmd.SetOutput(ioutil.Discard) + testutil.ErrorContains(t, cmd.Execute(), "flag requires the `--rotate` flag to update the CA") + } +} + func TestDisplayTrustRoot(t *testing.T) { buffer := new(bytes.Buffer) trustRoot := "trustme" diff --git a/components/cli/cli/command/swarm/init_test.go b/components/cli/cli/command/swarm/init_test.go index 0fcdbb786d..f6969d1b0e 100644 --- a/components/cli/cli/command/swarm/init_test.go +++ b/components/cli/cli/command/swarm/init_test.go @@ -67,7 +67,7 @@ func TestSwarmInitErrorOnAPIFailure(t *testing.T) { for _, tc := range testCases { buf := new(bytes.Buffer) cmd := newInitCommand( - test.NewFakeCli(&fakeClient{ + test.NewFakeCliWithOutput(&fakeClient{ swarmInitFunc: tc.swarmInitFunc, swarmInspectFunc: tc.swarmInspectFunc, swarmGetUnlockKeyFunc: tc.swarmGetUnlockKeyFunc, @@ -114,7 +114,7 @@ func TestSwarmInit(t *testing.T) { for _, tc := range testCases { buf := new(bytes.Buffer) cmd := newInitCommand( - test.NewFakeCli(&fakeClient{ + test.NewFakeCliWithOutput(&fakeClient{ swarmInitFunc: tc.swarmInitFunc, swarmInspectFunc: tc.swarmInspectFunc, swarmGetUnlockKeyFunc: tc.swarmGetUnlockKeyFunc, diff --git a/components/cli/cli/command/swarm/join_test.go b/components/cli/cli/command/swarm/join_test.go index d4f1098ff9..331f2c1753 100644 --- a/components/cli/cli/command/swarm/join_test.go +++ b/components/cli/cli/command/swarm/join_test.go @@ -51,7 +51,7 @@ func TestSwarmJoinErrors(t *testing.T) { for _, tc := range testCases { buf := new(bytes.Buffer) cmd := newJoinCommand( - test.NewFakeCli(&fakeClient{ + test.NewFakeCliWithOutput(&fakeClient{ swarmJoinFunc: tc.swarmJoinFunc, infoFunc: tc.infoFunc, }, buf)) @@ -93,7 +93,7 @@ func TestSwarmJoin(t *testing.T) { for _, tc := range testCases { buf := new(bytes.Buffer) cmd := newJoinCommand( - test.NewFakeCli(&fakeClient{ + test.NewFakeCliWithOutput(&fakeClient{ infoFunc: tc.infoFunc, }, buf)) cmd.SetArgs([]string{"remote"}) diff --git a/components/cli/cli/command/swarm/join_token_test.go b/components/cli/cli/command/swarm/join_token_test.go index 5c095b4156..f8619a4bd6 100644 --- a/components/cli/cli/command/swarm/join_token_test.go +++ b/components/cli/cli/command/swarm/join_token_test.go @@ -92,7 +92,7 @@ func TestSwarmJoinTokenErrors(t *testing.T) { for _, tc := range testCases { buf := new(bytes.Buffer) cmd := newJoinTokenCommand( - test.NewFakeCli(&fakeClient{ + test.NewFakeCliWithOutput(&fakeClient{ swarmInspectFunc: tc.swarmInspectFunc, swarmUpdateFunc: tc.swarmUpdateFunc, infoFunc: tc.infoFunc, @@ -200,7 +200,7 @@ func TestSwarmJoinToken(t *testing.T) { for _, tc := range testCases { buf := new(bytes.Buffer) cmd := newJoinTokenCommand( - test.NewFakeCli(&fakeClient{ + test.NewFakeCliWithOutput(&fakeClient{ swarmInspectFunc: tc.swarmInspectFunc, infoFunc: tc.infoFunc, nodeInspectFunc: tc.nodeInspectFunc, diff --git a/components/cli/cli/command/swarm/leave_test.go b/components/cli/cli/command/swarm/leave_test.go index dd7597efb5..aecac28430 100644 --- a/components/cli/cli/command/swarm/leave_test.go +++ b/components/cli/cli/command/swarm/leave_test.go @@ -1,7 +1,6 @@ package swarm import ( - "bytes" "io/ioutil" "strings" "testing" @@ -33,11 +32,10 @@ func TestSwarmLeaveErrors(t *testing.T) { }, } for _, tc := range testCases { - buf := new(bytes.Buffer) cmd := newLeaveCommand( test.NewFakeCli(&fakeClient{ swarmLeaveFunc: tc.swarmLeaveFunc, - }, buf)) + })) cmd.SetArgs(tc.args) cmd.SetOutput(ioutil.Discard) testutil.ErrorContains(t, cmd.Execute(), tc.expectedError) @@ -45,9 +43,8 @@ func TestSwarmLeaveErrors(t *testing.T) { } func TestSwarmLeave(t *testing.T) { - buf := new(bytes.Buffer) - cmd := newLeaveCommand( - test.NewFakeCli(&fakeClient{}, buf)) + cli := test.NewFakeCli(&fakeClient{}) + cmd := newLeaveCommand(cli) assert.NoError(t, cmd.Execute()) - assert.Equal(t, "Node left the swarm.", strings.TrimSpace(buf.String())) + assert.Equal(t, "Node left the swarm.", strings.TrimSpace(cli.OutBuffer().String())) } diff --git a/components/cli/cli/command/swarm/unlock_key_test.go b/components/cli/cli/command/swarm/unlock_key_test.go index 6b0246b199..9289a151f8 100644 --- a/components/cli/cli/command/swarm/unlock_key_test.go +++ b/components/cli/cli/command/swarm/unlock_key_test.go @@ -1,7 +1,6 @@ package swarm import ( - "bytes" "fmt" "io/ioutil" "testing" @@ -83,13 +82,12 @@ func TestSwarmUnlockKeyErrors(t *testing.T) { }, } for _, tc := range testCases { - buf := new(bytes.Buffer) cmd := newUnlockKeyCommand( test.NewFakeCli(&fakeClient{ swarmInspectFunc: tc.swarmInspectFunc, swarmUpdateFunc: tc.swarmUpdateFunc, swarmGetUnlockKeyFunc: tc.swarmGetUnlockKeyFunc, - }, buf)) + })) cmd.SetArgs(tc.args) for key, value := range tc.flags { cmd.Flags().Set(key, value) @@ -158,19 +156,18 @@ func TestSwarmUnlockKey(t *testing.T) { }, } for _, tc := range testCases { - buf := new(bytes.Buffer) - cmd := newUnlockKeyCommand( - test.NewFakeCli(&fakeClient{ - swarmInspectFunc: tc.swarmInspectFunc, - swarmUpdateFunc: tc.swarmUpdateFunc, - swarmGetUnlockKeyFunc: tc.swarmGetUnlockKeyFunc, - }, buf)) + cli := test.NewFakeCli(&fakeClient{ + swarmInspectFunc: tc.swarmInspectFunc, + swarmUpdateFunc: tc.swarmUpdateFunc, + swarmGetUnlockKeyFunc: tc.swarmGetUnlockKeyFunc, + }) + cmd := newUnlockKeyCommand(cli) cmd.SetArgs(tc.args) for key, value := range tc.flags { cmd.Flags().Set(key, value) } assert.NoError(t, cmd.Execute()) - actual := buf.String() + actual := cli.OutBuffer().String() expected := golden.Get(t, []byte(actual), fmt.Sprintf("unlockkeys-%s.golden", tc.name)) testutil.EqualNormalizedString(t, testutil.RemoveSpace, actual, string(expected)) } diff --git a/components/cli/cli/command/swarm/unlock_test.go b/components/cli/cli/command/swarm/unlock_test.go index 3dae5239f5..bf339faaf1 100644 --- a/components/cli/cli/command/swarm/unlock_test.go +++ b/components/cli/cli/command/swarm/unlock_test.go @@ -1,7 +1,6 @@ package swarm import ( - "bytes" "io/ioutil" "strings" "testing" @@ -66,12 +65,11 @@ func TestSwarmUnlockErrors(t *testing.T) { }, } for _, tc := range testCases { - buf := new(bytes.Buffer) cmd := newUnlockCommand( test.NewFakeCli(&fakeClient{ infoFunc: tc.infoFunc, swarmUnlockFunc: tc.swarmUnlockFunc, - }, buf)) + })) cmd.SetArgs(tc.args) cmd.SetOutput(ioutil.Discard) testutil.ErrorContains(t, cmd.Execute(), tc.expectedError) @@ -80,7 +78,6 @@ func TestSwarmUnlockErrors(t *testing.T) { func TestSwarmUnlock(t *testing.T) { input := "unlockKey" - buf := new(bytes.Buffer) dockerCli := test.NewFakeCli(&fakeClient{ infoFunc: func() (types.Info, error) { return types.Info{ @@ -95,7 +92,7 @@ func TestSwarmUnlock(t *testing.T) { } return nil }, - }, buf) + }) dockerCli.SetIn(command.NewInStream(ioutil.NopCloser(strings.NewReader(input)))) cmd := newUnlockCommand(dockerCli) assert.NoError(t, cmd.Execute()) diff --git a/components/cli/cli/command/swarm/update_test.go b/components/cli/cli/command/swarm/update_test.go index a6372cfee9..2b8c4a8af8 100644 --- a/components/cli/cli/command/swarm/update_test.go +++ b/components/cli/cli/command/swarm/update_test.go @@ -1,7 +1,6 @@ package swarm import ( - "bytes" "fmt" "io/ioutil" "testing" @@ -68,13 +67,12 @@ func TestSwarmUpdateErrors(t *testing.T) { }, } for _, tc := range testCases { - buf := new(bytes.Buffer) cmd := newUpdateCommand( test.NewFakeCli(&fakeClient{ swarmInspectFunc: tc.swarmInspectFunc, swarmUpdateFunc: tc.swarmUpdateFunc, swarmGetUnlockKeyFunc: tc.swarmGetUnlockKeyFunc, - }, buf)) + })) cmd.SetArgs(tc.args) for key, value := range tc.flags { cmd.Flags().Set(key, value) @@ -164,20 +162,19 @@ func TestSwarmUpdate(t *testing.T) { }, } for _, tc := range testCases { - buf := new(bytes.Buffer) - cmd := newUpdateCommand( - test.NewFakeCli(&fakeClient{ - swarmInspectFunc: tc.swarmInspectFunc, - swarmUpdateFunc: tc.swarmUpdateFunc, - swarmGetUnlockKeyFunc: tc.swarmGetUnlockKeyFunc, - }, buf)) + cli := test.NewFakeCli(&fakeClient{ + swarmInspectFunc: tc.swarmInspectFunc, + swarmUpdateFunc: tc.swarmUpdateFunc, + swarmGetUnlockKeyFunc: tc.swarmGetUnlockKeyFunc, + }) + cmd := newUpdateCommand(cli) cmd.SetArgs(tc.args) for key, value := range tc.flags { cmd.Flags().Set(key, value) } - cmd.SetOutput(buf) + cmd.SetOutput(cli.OutBuffer()) assert.NoError(t, cmd.Execute()) - actual := buf.String() + actual := cli.OutBuffer().String() expected := golden.Get(t, []byte(actual), fmt.Sprintf("update-%s.golden", tc.name)) testutil.EqualNormalizedString(t, testutil.RemoveSpace, actual, string(expected)) } diff --git a/components/cli/cli/command/task/print.go b/components/cli/cli/command/task/print.go index 2376ecf803..6526c28beb 100644 --- a/components/cli/cli/command/task/print.go +++ b/components/cli/cli/command/task/print.go @@ -4,12 +4,12 @@ import ( "fmt" "sort" - "golang.org/x/net/context" - "github.com/docker/cli/cli/command" "github.com/docker/cli/cli/command/formatter" "github.com/docker/cli/cli/command/idresolver" + "github.com/docker/cli/cli/config/configfile" "github.com/docker/docker/api/types/swarm" + "golang.org/x/net/context" ) type tasksBySlot []swarm.Task @@ -82,3 +82,12 @@ func Print(ctx context.Context, dockerCli command.Cli, tasks []swarm.Task, resol return formatter.TaskWrite(tasksCtx, tasks, names, nodes) } + +// DefaultFormat returns the default format from the config file, or table +// format if nothing is set in the config. +func DefaultFormat(configFile *configfile.ConfigFile, quiet bool) string { + if len(configFile.TasksFormat) > 0 && !quiet { + return configFile.TasksFormat + } + return formatter.TableFormatKey +} diff --git a/components/cli/cli/command/task/print_test.go b/components/cli/cli/command/task/print_test.go index 93171016f2..174ad72cd7 100644 --- a/components/cli/cli/command/task/print_test.go +++ b/components/cli/cli/command/task/print_test.go @@ -24,7 +24,7 @@ func TestTaskPrintWithQuietOption(t *testing.T) { noResolve := true buf := new(bytes.Buffer) apiClient := &fakeClient{} - cli := test.NewFakeCli(apiClient, buf) + cli := test.NewFakeCliWithOutput(apiClient, buf) tasks := []swarm.Task{ *Task(TaskID("id-foo")), } @@ -41,7 +41,7 @@ func TestTaskPrintWithNoTruncOption(t *testing.T) { noResolve := true buf := new(bytes.Buffer) apiClient := &fakeClient{} - cli := test.NewFakeCli(apiClient, buf) + cli := test.NewFakeCliWithOutput(apiClient, buf) tasks := []swarm.Task{ *Task(TaskID("id-foo-yov6omdek8fg3k5stosyp2m50")), } @@ -58,7 +58,7 @@ func TestTaskPrintWithGlobalService(t *testing.T) { noResolve := true buf := new(bytes.Buffer) apiClient := &fakeClient{} - cli := test.NewFakeCli(apiClient, buf) + cli := test.NewFakeCliWithOutput(apiClient, buf) tasks := []swarm.Task{ *Task(TaskServiceID("service-id-foo"), TaskNodeID("node-id-bar"), TaskSlot(0)), } @@ -75,7 +75,7 @@ func TestTaskPrintWithReplicatedService(t *testing.T) { noResolve := true buf := new(bytes.Buffer) apiClient := &fakeClient{} - cli := test.NewFakeCli(apiClient, buf) + cli := test.NewFakeCliWithOutput(apiClient, buf) tasks := []swarm.Task{ *Task(TaskServiceID("service-id-foo"), TaskSlot(1)), } @@ -99,7 +99,7 @@ func TestTaskPrintWithIndentation(t *testing.T) { return *Node(NodeName("node-name-bar")), nil, nil }, } - cli := test.NewFakeCli(apiClient, buf) + cli := test.NewFakeCliWithOutput(apiClient, buf) tasks := []swarm.Task{ *Task( TaskID("id-foo"), @@ -138,7 +138,7 @@ func TestTaskPrintWithResolution(t *testing.T) { return *Node(NodeName("node-name-bar")), nil, nil }, } - cli := test.NewFakeCli(apiClient, buf) + cli := test.NewFakeCliWithOutput(apiClient, buf) tasks := []swarm.Task{ *Task(TaskServiceID("service-id-foo"), TaskSlot(1)), } diff --git a/components/cli/cli/command/volume/create_test.go b/components/cli/cli/command/volume/create_test.go index 74c81aba1f..05b17eccdf 100644 --- a/components/cli/cli/command/volume/create_test.go +++ b/components/cli/cli/command/volume/create_test.go @@ -41,11 +41,10 @@ func TestVolumeCreateErrors(t *testing.T) { }, } for _, tc := range testCases { - buf := new(bytes.Buffer) cmd := newCreateCommand( test.NewFakeCli(&fakeClient{ volumeCreateFunc: tc.volumeCreateFunc, - }, buf), + }), ) cmd.SetArgs(tc.args) for key, value := range tc.flags { @@ -59,7 +58,7 @@ func TestVolumeCreateErrors(t *testing.T) { func TestVolumeCreateWithName(t *testing.T) { name := "foo" buf := new(bytes.Buffer) - cli := test.NewFakeCli(&fakeClient{ + cli := test.NewFakeCliWithOutput(&fakeClient{ volumeCreateFunc: func(body volumetypes.VolumesCreateBody) (types.Volume, error) { if body.Name != name { return types.Volume{}, errors.Errorf("expected name %q, got %q", name, body.Name) @@ -97,7 +96,7 @@ func TestVolumeCreateWithFlags(t *testing.T) { name := "banana" buf := new(bytes.Buffer) - cli := test.NewFakeCli(&fakeClient{ + cli := test.NewFakeCliWithOutput(&fakeClient{ volumeCreateFunc: func(body volumetypes.VolumesCreateBody) (types.Volume, error) { if body.Name != "" { return types.Volume{}, errors.Errorf("expected empty name, got %q", body.Name) diff --git a/components/cli/cli/command/volume/inspect_test.go b/components/cli/cli/command/volume/inspect_test.go index 3c16f125ab..8f452d7dee 100644 --- a/components/cli/cli/command/volume/inspect_test.go +++ b/components/cli/cli/command/volume/inspect_test.go @@ -56,7 +56,7 @@ func TestVolumeInspectErrors(t *testing.T) { for _, tc := range testCases { buf := new(bytes.Buffer) cmd := newInspectCommand( - test.NewFakeCli(&fakeClient{ + test.NewFakeCliWithOutput(&fakeClient{ volumeInspectFunc: tc.volumeInspectFunc, }, buf), ) @@ -98,7 +98,7 @@ func TestVolumeInspectWithoutFormat(t *testing.T) { for _, tc := range testCases { buf := new(bytes.Buffer) cmd := newInspectCommand( - test.NewFakeCli(&fakeClient{ + test.NewFakeCliWithOutput(&fakeClient{ volumeInspectFunc: tc.volumeInspectFunc, }, buf), ) @@ -138,7 +138,7 @@ func TestVolumeInspectWithFormat(t *testing.T) { for _, tc := range testCases { buf := new(bytes.Buffer) cmd := newInspectCommand( - test.NewFakeCli(&fakeClient{ + test.NewFakeCliWithOutput(&fakeClient{ volumeInspectFunc: tc.volumeInspectFunc, }, buf), ) diff --git a/components/cli/cli/command/volume/list_test.go b/components/cli/cli/command/volume/list_test.go index 2dc11a8b8e..92cd62b597 100644 --- a/components/cli/cli/command/volume/list_test.go +++ b/components/cli/cli/command/volume/list_test.go @@ -39,7 +39,7 @@ func TestVolumeListErrors(t *testing.T) { for _, tc := range testCases { buf := new(bytes.Buffer) cmd := newListCommand( - test.NewFakeCli(&fakeClient{ + test.NewFakeCliWithOutput(&fakeClient{ volumeListFunc: tc.volumeListFunc, }, buf), ) @@ -54,7 +54,7 @@ func TestVolumeListErrors(t *testing.T) { func TestVolumeListWithoutFormat(t *testing.T) { buf := new(bytes.Buffer) - cli := test.NewFakeCli(&fakeClient{ + cli := test.NewFakeCliWithOutput(&fakeClient{ volumeListFunc: func(filter filters.Args) (volumetypes.VolumesListOKBody, error) { return volumetypes.VolumesListOKBody{ Volumes: []*types.Volume{ @@ -67,7 +67,6 @@ func TestVolumeListWithoutFormat(t *testing.T) { }, nil }, }, buf) - cli.SetConfigfile(&configfile.ConfigFile{}) cmd := newListCommand(cli) assert.NoError(t, cmd.Execute()) actual := buf.String() @@ -77,7 +76,7 @@ func TestVolumeListWithoutFormat(t *testing.T) { func TestVolumeListWithConfigFormat(t *testing.T) { buf := new(bytes.Buffer) - cli := test.NewFakeCli(&fakeClient{ + cli := test.NewFakeCliWithOutput(&fakeClient{ volumeListFunc: func(filter filters.Args) (volumetypes.VolumesListOKBody, error) { return volumetypes.VolumesListOKBody{ Volumes: []*types.Volume{ @@ -90,7 +89,7 @@ func TestVolumeListWithConfigFormat(t *testing.T) { }, nil }, }, buf) - cli.SetConfigfile(&configfile.ConfigFile{ + cli.SetConfigFile(&configfile.ConfigFile{ VolumesFormat: "{{ .Name }} {{ .Driver }} {{ .Labels }}", }) cmd := newListCommand(cli) @@ -102,7 +101,7 @@ func TestVolumeListWithConfigFormat(t *testing.T) { func TestVolumeListWithFormat(t *testing.T) { buf := new(bytes.Buffer) - cli := test.NewFakeCli(&fakeClient{ + cli := test.NewFakeCliWithOutput(&fakeClient{ volumeListFunc: func(filter filters.Args) (volumetypes.VolumesListOKBody, error) { return volumetypes.VolumesListOKBody{ Volumes: []*types.Volume{ @@ -115,7 +114,6 @@ func TestVolumeListWithFormat(t *testing.T) { }, nil }, }, buf) - cli.SetConfigfile(&configfile.ConfigFile{}) cmd := newListCommand(cli) cmd.Flags().Set("format", "{{ .Name }} {{ .Driver }} {{ .Labels }}") assert.NoError(t, cmd.Execute()) diff --git a/components/cli/cli/command/volume/prune_test.go b/components/cli/cli/command/volume/prune_test.go index 33a8d5dc19..cf26d283f4 100644 --- a/components/cli/cli/command/volume/prune_test.go +++ b/components/cli/cli/command/volume/prune_test.go @@ -41,7 +41,7 @@ func TestVolumePruneErrors(t *testing.T) { } for _, tc := range testCases { cmd := NewPruneCommand( - test.NewFakeCli(&fakeClient{ + test.NewFakeCliWithOutput(&fakeClient{ volumePruneFunc: tc.volumePruneFunc, }, ioutil.Discard), ) @@ -70,7 +70,7 @@ func TestVolumePruneForce(t *testing.T) { for _, tc := range testCases { buf := new(bytes.Buffer) cmd := NewPruneCommand( - test.NewFakeCli(&fakeClient{ + test.NewFakeCliWithOutput(&fakeClient{ volumePruneFunc: tc.volumePruneFunc, }, buf), ) @@ -88,7 +88,7 @@ func TestVolumePrunePromptYes(t *testing.T) { } for _, input := range []string{"y", "Y"} { buf := new(bytes.Buffer) - cli := test.NewFakeCli(&fakeClient{ + cli := test.NewFakeCliWithOutput(&fakeClient{ volumePruneFunc: simplePruneFunc, }, buf) @@ -110,7 +110,7 @@ func TestVolumePrunePromptNo(t *testing.T) { } for _, input := range []string{"n", "N", "no", "anything", "really"} { buf := new(bytes.Buffer) - cli := test.NewFakeCli(&fakeClient{ + cli := test.NewFakeCliWithOutput(&fakeClient{ volumePruneFunc: simplePruneFunc, }, buf) diff --git a/components/cli/cli/command/volume/remove_test.go b/components/cli/cli/command/volume/remove_test.go index 8916700cc6..3d01905681 100644 --- a/components/cli/cli/command/volume/remove_test.go +++ b/components/cli/cli/command/volume/remove_test.go @@ -31,7 +31,7 @@ func TestVolumeRemoveErrors(t *testing.T) { for _, tc := range testCases { buf := new(bytes.Buffer) cmd := newRemoveCommand( - test.NewFakeCli(&fakeClient{ + test.NewFakeCliWithOutput(&fakeClient{ volumeRemoveFunc: tc.volumeRemoveFunc, }, buf)) cmd.SetArgs(tc.args) @@ -42,7 +42,7 @@ func TestVolumeRemoveErrors(t *testing.T) { func TestNodeRemoveMultiple(t *testing.T) { buf := new(bytes.Buffer) - cmd := newRemoveCommand(test.NewFakeCli(&fakeClient{}, buf)) + cmd := newRemoveCommand(test.NewFakeCliWithOutput(&fakeClient{}, buf)) cmd.SetArgs([]string{"volume1", "volume2"}) assert.NoError(t, cmd.Execute()) } diff --git a/components/cli/cli/internal/test/cli.go b/components/cli/cli/internal/test/cli.go index 378ee9cdc2..54b3bc83b1 100644 --- a/components/cli/cli/internal/test/cli.go +++ b/components/cli/cli/internal/test/cli.go @@ -1,6 +1,7 @@ package test import ( + "bytes" "io" "io/ioutil" "strings" @@ -16,17 +17,29 @@ type FakeCli struct { client client.APIClient configfile *configfile.ConfigFile out *command.OutStream - err io.Writer + outBuffer *bytes.Buffer + err *bytes.Buffer in *command.InStream server command.ServerInfo } -// NewFakeCli returns a Cli backed by the fakeCli -func NewFakeCli(client client.APIClient, out io.Writer) *FakeCli { +// NewFakeCliWithOutput returns a Cli backed by the fakeCli +// Deprecated: Use NewFakeCli +func NewFakeCliWithOutput(client client.APIClient, out io.Writer) *FakeCli { + cli := NewFakeCli(client) + cli.out = command.NewOutStream(out) + return cli +} + +// NewFakeCli returns a fake for the command.Cli interface +func NewFakeCli(client client.APIClient) *FakeCli { + outBuffer := new(bytes.Buffer) + errBuffer := new(bytes.Buffer) return &FakeCli{ client: client, - out: command.NewOutStream(out), - err: ioutil.Discard, + out: command.NewOutStream(outBuffer), + outBuffer: outBuffer, + err: errBuffer, in: command.NewInStream(ioutil.NopCloser(strings.NewReader(""))), configfile: configfile.New("configfile"), } @@ -38,12 +51,12 @@ func (c *FakeCli) SetIn(in *command.InStream) { } // SetErr sets the stderr stream for the cli to the specified io.Writer -func (c *FakeCli) SetErr(err io.Writer) { +func (c *FakeCli) SetErr(err *bytes.Buffer) { c.err = err } -// SetConfigfile sets the "fake" config file -func (c *FakeCli) SetConfigfile(configfile *configfile.ConfigFile) { +// SetConfigFile sets the "fake" config file +func (c *FakeCli) SetConfigFile(configfile *configfile.ConfigFile) { c.configfile = configfile } @@ -76,3 +89,13 @@ func (c *FakeCli) ConfigFile() *configfile.ConfigFile { func (c *FakeCli) ServerInfo() command.ServerInfo { return c.server } + +// OutBuffer returns the stdout buffer +func (c *FakeCli) OutBuffer() *bytes.Buffer { + return c.outBuffer +} + +// ErrBuffer Buffer returns the stderr buffer +func (c *FakeCli) ErrBuffer() *bytes.Buffer { + return c.err +} diff --git a/components/cli/contrib/completion/bash/docker b/components/cli/contrib/completion/bash/docker index 33ada275b1..95cc588ca0 100644 --- a/components/cli/contrib/completion/bash/docker +++ b/components/cli/contrib/completion/bash/docker @@ -636,18 +636,40 @@ __docker_complete_resolved_hostname() { COMPREPLY=( $(host 2>/dev/null "${cur%:}" | awk '/has address/ {print $4}') ) } +# __docker_local_interfaces returns a list of the names and addresses of all +# local network interfaces. +# If `--ip-only` is passed as a first argument, only addresses are returned. __docker_local_interfaces() { command -v ip >/dev/null 2>&1 || return - ip addr show scope global 2>/dev/null | sed -n 's| \+inet \([0-9.]\+\).* \([^ ]\+\)|\1 \2|p' + + local format + if [ "$1" = "--ip-only" ] ; then + format='\1' + shift + else + format='\1 \2' + fi + + ip addr show scope global 2>/dev/null | sed -n "s| \+inet \([0-9.]\+\).* \([^ ]\+\)|$format|p" } +# __docker_complete_local_interfaces applies completion of the names and addresses of all +# local network interfaces based on the current value of `$cur`. +# An additional value can be added to the possible completions with an `--add` argument. __docker_complete_local_interfaces() { local additional_interface if [ "$1" = "--add" ] ; then additional_interface="$2" + shift 2 fi - COMPREPLY=( $( compgen -W "$(__docker_local_interfaces) $additional_interface" -- "$cur" ) ) + COMPREPLY=( $( compgen -W "$(__docker_local_interfaces "$@") $additional_interface" -- "$cur" ) ) +} + +# __docker_complete_local_ips applies completion of the addresses of all local network +# interfaces based on the current value of `$cur`. +__docker_complete_local_ips() { + __docker_complete_local_interfaces --ip-only } # __docker_complete_capabilities_addable completes Linux capabilities which are @@ -1413,7 +1435,7 @@ _docker_container_port() { _docker_container_prune() { case "$prev" in --filter) - COMPREPLY=( $( compgen -W "until" -S = -- "$cur" ) ) + COMPREPLY=( $( compgen -W "label label! until" -S = -- "$cur" ) ) __docker_nospace return ;; @@ -1962,9 +1984,11 @@ _docker_daemon() { --iptables=false --ipv6 --live-restore + --no-new-privileges --raw-logs --selinux-enabled --userland-proxy=false + --version -v " local options_with_args=" $global_options_with_args @@ -1980,9 +2004,12 @@ _docker_daemon() { --cluster-store-opt --config-file --containerd + --cpu-rt-period + --cpu-rt-runtime --data-root --default-gateway --default-gateway-v6 + --default-runtime --default-shm-size --default-ulimit --dns @@ -2001,6 +2028,7 @@ _docker_daemon() { --log-opt --max-concurrent-downloads --max-concurrent-uploads + --metrics-addr --mtu --oom-score-adjust --pidfile -p @@ -2009,6 +2037,7 @@ _docker_daemon() { --shutdown-timeout --storage-driver -s --storage-opt + --swarm-default-advertise-addr --userland-proxy-path --userns-remap " @@ -2069,7 +2098,7 @@ _docker_daemon() { return ;; --storage-driver|-s) - COMPREPLY=( $( compgen -W "aufs btrfs devicemapper overlay overlay2 vfs zfs" -- "$(echo $cur | tr '[:upper:]' '[:lower:]')" ) ) + COMPREPLY=( $( compgen -W "aufs btrfs devicemapper overlay overlay2 vfs zfs" -- "$(echo $cur | tr '[:upper:]' '[:lower:]')" ) ) return ;; --storage-opt) @@ -2094,11 +2123,14 @@ _docker_daemon() { dm.use_deferred_deletion dm.use_deferred_removal " + local overlay2_options="overlay2.size" local zfs_options="zfs.fsname" + local all_options="$btrfs_options $devicemapper_options $overlay2_options $zfs_options" + case $(__docker_value_of_option '--storage-driver|-s') in '') - COMPREPLY=( $( compgen -W "$btrfs_options $devicemapper_options $zfs_options" -S = -- "$cur" ) ) + COMPREPLY=( $( compgen -W "$all_options" -S = -- "$cur" ) ) ;; btrfs) COMPREPLY=( $( compgen -W "$btrfs_options" -S = -- "$cur" ) ) @@ -2106,6 +2138,9 @@ _docker_daemon() { devicemapper) COMPREPLY=( $( compgen -W "$devicemapper_options" -S = -- "$cur" ) ) ;; + overlay2) + COMPREPLY=( $( compgen -W "$overlay2_options" -S = -- "$cur" ) ) + ;; zfs) COMPREPLY=( $( compgen -W "$zfs_options" -S = -- "$cur" ) ) ;; @@ -2124,10 +2159,20 @@ _docker_daemon() { __docker_complete_log_options return ;; + --metrics-addr) + __docker_complete_local_ips + __docker_append_to_completions ":" + __docker_nospace + return + ;; --seccomp-profile) _filedir json return ;; + --swarm-default-advertise-addr) + __docker_complete_local_interfaces + return + ;; --userns-remap) __docker_complete_user_group return @@ -2428,7 +2473,7 @@ _docker_image_ls() { _docker_image_prune() { case "$prev" in --filter) - COMPREPLY=( $( compgen -W "until" -S = -- "$cur" ) ) + COMPREPLY=( $( compgen -W "label label! until" -S = -- "$cur" ) ) __docker_nospace return ;; @@ -2707,8 +2752,8 @@ _docker_network_create() { --aux-address|--gateway|--ip-range|--ipam-opt|--ipv6|--opt|-o|--subnet) return ;; - --ipam-driver) - COMPREPLY=( $( compgen -W "default" -- "$cur" ) ) + --config-from) + __docker_complete_networks return ;; --driver|-d) @@ -2716,14 +2761,22 @@ _docker_network_create() { __docker_complete_plugins_bundled --type Network --remove host --remove null --add macvlan return ;; + --ipam-driver) + COMPREPLY=( $( compgen -W "default" -- "$cur" ) ) + return + ;; --label) return ;; + --scope) + COMPREPLY=( $( compgen -W "local swarm" -- "$cur" ) ) + return + ;; esac case "$cur" in -*) - COMPREPLY=( $( compgen -W "--attachable --aux-address --driver -d --gateway --help --ingress --internal --ip-range --ipam-driver --ipam-opt --ipv6 --label --opt -o --subnet" -- "$cur" ) ) + COMPREPLY=( $( compgen -W "--attachable --aux-address --config-from --config-only --driver -d --gateway --help --ingress --internal --ip-range --ipam-driver --ipam-opt --ipv6 --label --opt -o --scope --subnet" -- "$cur" ) ) ;; esac } @@ -2806,7 +2859,7 @@ _docker_network_ls() { _docker_network_prune() { case "$prev" in --filter) - COMPREPLY=( $( compgen -W "until" -S = -- "$cur" ) ) + COMPREPLY=( $( compgen -W "label label! until" -S = -- "$cur" ) ) __docker_nospace return ;; @@ -3054,7 +3107,6 @@ _docker_service_update_and_create() { --log-driver --log-opt --mount - --network --replicas --reserve-cpu --reserve-memory @@ -3103,6 +3155,7 @@ _docker_service_update_and_create() { --host --mode --name + --network --placement-pref --publish -p --secret @@ -4359,7 +4412,7 @@ _docker_system_info() { _docker_system_prune() { case "$prev" in --filter) - COMPREPLY=( $( compgen -W "until" -S = -- "$cur" ) ) + COMPREPLY=( $( compgen -W "label label! until" -S = -- "$cur" ) ) __docker_nospace return ;; @@ -4478,9 +4531,17 @@ _docker_volume_ls() { } _docker_volume_prune() { + case "$prev" in + --filter) + COMPREPLY=( $( compgen -W "label label!" -S = -- "$cur" ) ) + __docker_nospace + return + ;; + esac + case "$cur" in -*) - COMPREPLY=( $( compgen -W "--force -f --help" -- "$cur" ) ) + COMPREPLY=( $( compgen -W "--filter --force -f --help" -- "$cur" ) ) ;; esac } diff --git a/components/cli/docker.Makefile b/components/cli/docker.Makefile index ef8dbfb926..2d7474b583 100644 --- a/components/cli/docker.Makefile +++ b/components/cli/docker.Makefile @@ -14,16 +14,16 @@ ENVVARS = -e VERSION=$(VERSION) -e GITCOMMIT # build docker image (dockerfiles/Dockerfile.build) .PHONY: build_docker_image build_docker_image: - docker build -t $(DEV_DOCKER_IMAGE_NAME) -f ./dockerfiles/Dockerfile.dev . + docker build ${DOCKER_BUILD_ARGS} -t $(DEV_DOCKER_IMAGE_NAME) -f ./dockerfiles/Dockerfile.dev . # build docker image having the linting tools (dockerfiles/Dockerfile.lint) .PHONY: build_linter_image build_linter_image: - docker build -t $(LINTER_IMAGE_NAME) -f ./dockerfiles/Dockerfile.lint . + docker build ${DOCKER_BUILD_ARGS} -t $(LINTER_IMAGE_NAME) -f ./dockerfiles/Dockerfile.lint . .PHONY: build_cross_image build_cross_image: - docker build -t $(CROSS_IMAGE_NAME) -f ./dockerfiles/Dockerfile.cross . + docker build ${DOCKER_BUILD_ARGS} -t $(CROSS_IMAGE_NAME) -f ./dockerfiles/Dockerfile.cross . # build executable using a container diff --git a/components/cli/dockerfiles/Dockerfile.cross b/components/cli/dockerfiles/Dockerfile.cross index 19907ced49..60487dca90 100644 --- a/components/cli/dockerfiles/Dockerfile.cross +++ b/components/cli/dockerfiles/Dockerfile.cross @@ -1,18 +1,2 @@ - -FROM golang:1.8.3 - -# allow replacing httpredir or deb mirror -ARG APT_MIRROR=deb.debian.org -RUN sed -ri "s/(httpredir|deb).debian.org/$APT_MIRROR/g" /etc/apt/sources.list - -RUN apt-get update -qq && apt-get install -y -q \ - libltdl-dev \ - gcc-mingw-w64 \ - parallel \ - ; - -COPY dockerfiles/osx-cross.sh /tmp/ -RUN /tmp/osx-cross.sh -ENV PATH /osxcross/target/bin:$PATH - +FROM dockercore/golang-cross@sha256:d24e7affa3a85d460d2303c2549f03fc866f2b97d771ccf07b0e6e2b411dd207 WORKDIR /go/src/github.com/docker/cli diff --git a/components/cli/dockerfiles/Dockerfile.dev b/components/cli/dockerfiles/Dockerfile.dev index aef37382c8..a80d3418f1 100644 --- a/components/cli/dockerfiles/Dockerfile.dev +++ b/components/cli/dockerfiles/Dockerfile.dev @@ -3,16 +3,25 @@ FROM golang:1.8.3-alpine RUN apk add -U git make bash coreutils +ARG VNDR_SHA=9909bb2b8a0b7ea464527b376dc50389c90df587 RUN go get github.com/LK4D4/vndr && \ - cp /go/bin/vndr /usr/bin && \ + cd /go/src/github.com/LK4D4/vndr && \ + git checkout -q "$VNDR_SHA" && \ + go build -v -o /usr/bin/vndr . && \ rm -rf /go/src/* /go/pkg/* /go/bin/* +ARG BINDATA_SHA=a0ff2567cfb70903282db057e799fd826784d41d RUN go get github.com/jteeuwen/go-bindata/go-bindata && \ - cp /go/bin/go-bindata /usr/bin && \ + cd /go/src/github.com/jteeuwen/go-bindata/go-bindata && \ + git checkout -q "$BINDATA_SHA" && \ + go build -v -o /usr/bin/go-bindata . && \ rm -rf /go/src/* /go/pkg/* /go/bin/* +ARG FILEWATCHER_SHA=2e12ea42f6c8c089b19e992145bb94e8adaecedb RUN go get github.com/dnephin/filewatcher && \ - cp /go/bin/filewatcher /usr/bin/ && \ + cd /go/src/github.com/dnephin/filewatcher && \ + git checkout -q "$FILEWATCHER_SHA" && \ + go build -v -o /usr/bin/filewatcher . && \ rm -rf /go/src/* /go/pkg/* /go/bin/* ENV CGO_ENABLED=0 diff --git a/components/cli/dockerfiles/Dockerfile.lint b/components/cli/dockerfiles/Dockerfile.lint index 240af474c5..0b9385e0d1 100644 --- a/components/cli/dockerfiles/Dockerfile.lint +++ b/components/cli/dockerfiles/Dockerfile.lint @@ -2,9 +2,13 @@ FROM golang:1.8.3-alpine RUN apk add -U git -RUN go get -u gopkg.in/dnephin/gometalinter.v1 && \ - mv /go/bin/gometalinter.v1 /usr/local/bin/gometalinter && \ - gometalinter --install +ARG GOMETALINTER_SHA=4306381615a2ba2a207f8fcea02c08c6b2b0803f +RUN go get github.com/alecthomas/gometalinter && \ + cd /go/src/github.com/alecthomas/gometalinter && \ + git checkout -q "$GOMETALINTER_SHA" && \ + go build -v -o /usr/local/bin/gometalinter . && \ + gometalinter --install && \ + rm -rf /go/src/* /go/pkg/* WORKDIR /go/src/github.com/docker/cli ENV CGO_ENABLED=0 diff --git a/components/cli/dockerfiles/osx-cross.sh b/components/cli/dockerfiles/osx-cross.sh deleted file mode 100755 index 840334a135..0000000000 --- a/components/cli/dockerfiles/osx-cross.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env bash -# -# Install dependencies required to cross compile osx, then cleanup -# -# TODO: this should be a separate build stage when CI supports it - - -set -eu -o pipefail - -PKG_DEPS="patch xz-utils clang" - -apt-get update -qq -apt-get install -y -q $PKG_DEPS - -OSX_SDK=MacOSX10.11.sdk -OSX_CROSS_COMMIT=a9317c18a3a457ca0a657f08cc4d0d43c6cf8953 -OSXCROSS_PATH="/osxcross" - -echo "Cloning osxcross" -time git clone https://github.com/tpoechtrager/osxcross.git $OSXCROSS_PATH -cd $OSXCROSS_PATH -git checkout -q $OSX_CROSS_COMMIT - -echo "Downloading OSX SDK" -time curl -sSL https://s3.dockerproject.org/darwin/v2/${OSX_SDK}.tar.xz \ - -o "${OSXCROSS_PATH}/tarballs/${OSX_SDK}.tar.xz" - -echo "Building osxcross" -UNATTENDED=yes OSX_VERSION_MIN=10.6 ${OSXCROSS_PATH}/build.sh > /dev/null diff --git a/components/cli/docs/reference/builder.md b/components/cli/docs/reference/builder.md index d6274407e6..65f6e05f04 100644 --- a/components/cli/docs/reference/builder.md +++ b/components/cli/docs/reference/builder.md @@ -138,7 +138,7 @@ be UPPERCASE to distinguish them from arguments more easily. Docker runs instructions in a `Dockerfile` in order. A `Dockerfile` **must start with a \`FROM\` instruction**. The `FROM` instruction specifies the [*Base Image*](glossary.md#base-image) from which you are building. `FROM` may only be -proceeded by one or more `ARG` instructions, which declare arguments that are used +preceded by one or more `ARG` instructions, which declare arguments that are used in `FROM` lines in the `Dockerfile`. Docker treats lines that *begin* with `#` as a comment, unless the line is @@ -499,7 +499,7 @@ valid `Dockerfile` must start with a `FROM` instruction. The image can be any valid image – it is especially easy to start by **pulling an image** from the [*Public Repositories*](https://docs.docker.com/engine/tutorials/dockerrepos/). -- `ARG` is the only instruction that may proceed `FROM` in the `Dockerfile`. +- `ARG` is the only instruction that may precede `FROM` in the `Dockerfile`. See [Understand how ARG and FROM interact](#understand-how-arg-and-from-interact). - `FROM` can appear multiple times within a single `Dockerfile` to diff --git a/components/cli/docs/reference/commandline/dockerd.md b/components/cli/docs/reference/commandline/dockerd.md index 3e2d434974..676da28df8 100644 --- a/components/cli/docs/reference/commandline/dockerd.md +++ b/components/cli/docs/reference/commandline/dockerd.md @@ -700,6 +700,34 @@ ENOSPC and will shutdown filesystem. $ sudo dockerd --storage-opt dm.xfs_nospace_max_retries=0 ``` +##### `dm.libdm_log_level` + +Specifies the maxmimum `libdm` log level that will be forwarded to the +`dockerd` log (as specified by `--log-level`). This option is primarily +intended for debugging problems involving `libdm`. Using values other than the +defaults may cause false-positive warnings to be logged. + +Values specified must fall within the range of valid `libdm` log levels. At the +time of writing, the following is the list of `libdm` log levels as well as +their corresponding levels when output by `dockerd`. + +| `libdm` Level | Value | `--log-level` | +| ------------- | -----:| ------------- | +| `_LOG_FATAL` | 2 | error | +| `_LOG_ERR` | 3 | error | +| `_LOG_WARN` | 4 | warn | +| `_LOG_NOTICE` | 5 | info | +| `_LOG_INFO` | 6 | info | +| `_LOG_DEBUG` | 7 | debug | + +###### Example + +```bash +$ sudo dockerd \ + --log-level debug \ + --storage-opt dm.libdm_log_level=7 +``` + #### ZFS options ##### `zfs.fsname` diff --git a/components/cli/docs/reference/commandline/service_create.md b/components/cli/docs/reference/commandline/service_create.md index 78faa98bf7..a1b6d18f9d 100644 --- a/components/cli/docs/reference/commandline/service_create.md +++ b/components/cli/docs/reference/commandline/service_create.md @@ -167,6 +167,8 @@ $ docker service create --name redis \ 4cdgfyky7ozwh3htjfw0d12qv ``` +To grant a service access to multiple secrets, use multiple `--secret` flags. + Secrets are located in `/run/secrets` in the container. If no target is specified, the name of the secret will be used as the in memory file in the container. If a target is specified, that will be the filename. In the @@ -191,10 +193,26 @@ tutorial](https://docs.docker.com/engine/swarm/swarm-tutorial/rolling-update/). ### Set environment variables (-e, --env) -This sets environmental variables for all tasks in a service. For example: +This sets an environmental variable for all tasks in a service. For example: ```bash -$ docker service create --name redis_2 --replicas 5 --env MYVAR=foo redis:3.0.6 +$ docker service create \ + --name redis_2 \ + --replicas 5 \ + --env MYVAR=foo \ + redis:3.0.6 +``` + +To specify multiple environment variables, specify multiple `--env` flags, each +with a separate key-value pair. + +```bash +$ docker service create \ + --name redis_2 \ + --replicas 5 \ + --env MYVAR=foo \ + --env MYVAR2=bar \ + redis:3.0.6 ``` ### Create a service with specific hostname (--hostname) diff --git a/components/cli/docs/reference/commandline/service_scale.md b/components/cli/docs/reference/commandline/service_scale.md index a3aef5fd34..47d49faa25 100644 --- a/components/cli/docs/reference/commandline/service_scale.md +++ b/components/cli/docs/reference/commandline/service_scale.md @@ -16,11 +16,12 @@ keywords: "service, scale" # service scale ```markdown -Usage: docker service scale SERVICE=REPLICAS [SERVICE=REPLICAS...] +Usage: docker service scale [OPTIONS] SERVICE=REPLICAS [SERVICE=REPLICAS...] Scale one or multiple replicated services Options: + -d, --detach Exit immediately instead of waiting for the service to converge (default true) --help Print usage ``` diff --git a/components/cli/docs/reference/run.md b/components/cli/docs/reference/run.md index 817c20c969..4932a530cf 100644 --- a/components/cli/docs/reference/run.md +++ b/components/cli/docs/reference/run.md @@ -87,8 +87,9 @@ default foreground mode: To start a container in detached mode, you use `-d=true` or just `-d` option. By design, containers started in detached mode exit when the root process used to -run the container exits. A container in detached mode cannot be automatically -removed when it stops, this means you cannot use the `--rm` option with `-d` option. +run the container exits, unless you also specify the `--rm` option. If you use +`-d` with `--rm`, the container is removed when it exits **or** when the daemon +exits, whichever happens first. Do not pass a `service x start` command to a detached container. For example, this command attempts to start the `nginx` service. @@ -149,7 +150,7 @@ is receiving its standard input from a pipe, as in: The operator can identify a container in three ways: | Identifier type | Example value | -| --------------------- | ------------------------------------------------------------------ | +|:----------------------|:-------------------------------------------------------------------| | UUID long identifier | "f78375b1c487e03c9438c729345e54db9d20cfa2ac1fc3494b6eb60872e74778" | | UUID short identifier | "f78375b1c487" | | Name | "evil_ptolemy" | @@ -686,29 +687,29 @@ parent group. The operator can also adjust the performance parameters of the container: -| Option | Description | -| -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | -| `-m`, `--memory=""` | Memory limit (format: `[]`). Number is a positive integer. Unit can be one of `b`, `k`, `m`, or `g`. Minimum is 4M. | -| `--memory-swap=""` | Total memory limit (memory + swap, format: `[]`). Number is a positive integer. Unit can be one of `b`, `k`, `m`, or `g`. | -| `--memory-reservation=""` | Memory soft limit (format: `[]`). Number is a positive integer. Unit can be one of `b`, `k`, `m`, or `g`. | -| `--kernel-memory=""` | Kernel memory limit (format: `[]`). Number is a positive integer. Unit can be one of `b`, `k`, `m`, or `g`. Minimum is 4M. | -| `-c`, `--cpu-shares=0` | CPU shares (relative weight) | -| `--cpus=0.000` | Number of CPUs. Number is a fractional number. 0.000 means no limit. | -| `--cpu-period=0` | Limit the CPU CFS (Completely Fair Scheduler) period | -| `--cpuset-cpus=""` | CPUs in which to allow execution (0-3, 0,1) | -| `--cpuset-mems=""` | Memory nodes (MEMs) in which to allow execution (0-3, 0,1). Only effective on NUMA systems. | -| `--cpu-quota=0` | Limit the CPU CFS (Completely Fair Scheduler) quota | -| `--cpu-rt-period=0` | Limit the CPU real-time period. In microseconds. Requires parent cgroups be set and cannot be higher than parent. Also check rtprio ulimits. | -| `--cpu-rt-runtime=0` | Limit the CPU real-time runtime. In microseconds. Requires parent cgroups be set and cannot be higher than parent. Also check rtprio ulimits. | -| `--blkio-weight=0` | Block IO weight (relative weight) accepts a weight value between 10 and 1000. | -| `--blkio-weight-device=""` | Block IO weight (relative device weight, format: `DEVICE_NAME:WEIGHT`) | -| `--device-read-bps=""` | Limit read rate from a device (format: `:[]`). Number is a positive integer. Unit can be one of `kb`, `mb`, or `gb`. | -| `--device-write-bps=""` | Limit write rate to a device (format: `:[]`). Number is a positive integer. Unit can be one of `kb`, `mb`, or `gb`. | -| `--device-read-iops="" ` | Limit read rate (IO per second) from a device (format: `:`). Number is a positive integer. | -| `--device-write-iops="" ` | Limit write rate (IO per second) to a device (format: `:`). Number is a positive integer. | -| `--oom-kill-disable=false` | Whether to disable OOM Killer for the container or not. | -| `--oom-score-adj=0` | Tune container's OOM preferences (-1000 to 1000) | -| `--memory-swappiness=""` | Tune a container's memory swappiness behavior. Accepts an integer between 0 and 100. | +| Option | Description | +|:---------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `-m`, `--memory=""` | Memory limit (format: `[]`). Number is a positive integer. Unit can be one of `b`, `k`, `m`, or `g`. Minimum is 4M. | +| `--memory-swap=""` | Total memory limit (memory + swap, format: `[]`). Number is a positive integer. Unit can be one of `b`, `k`, `m`, or `g`. | +| `--memory-reservation=""` | Memory soft limit (format: `[]`). Number is a positive integer. Unit can be one of `b`, `k`, `m`, or `g`. | +| `--kernel-memory=""` | Kernel memory limit (format: `[]`). Number is a positive integer. Unit can be one of `b`, `k`, `m`, or `g`. Minimum is 4M. | +| `-c`, `--cpu-shares=0` | CPU shares (relative weight) | +| `--cpus=0.000` | Number of CPUs. Number is a fractional number. 0.000 means no limit. | +| `--cpu-period=0` | Limit the CPU CFS (Completely Fair Scheduler) period | +| `--cpuset-cpus=""` | CPUs in which to allow execution (0-3, 0,1) | +| `--cpuset-mems=""` | Memory nodes (MEMs) in which to allow execution (0-3, 0,1). Only effective on NUMA systems. | +| `--cpu-quota=0` | Limit the CPU CFS (Completely Fair Scheduler) quota | +| `--cpu-rt-period=0` | Limit the CPU real-time period. In microseconds. Requires parent cgroups be set and cannot be higher than parent. Also check rtprio ulimits. | +| `--cpu-rt-runtime=0` | Limit the CPU real-time runtime. In microseconds. Requires parent cgroups be set and cannot be higher than parent. Also check rtprio ulimits. | +| `--blkio-weight=0` | Block IO weight (relative weight) accepts a weight value between 10 and 1000. | +| `--blkio-weight-device=""` | Block IO weight (relative device weight, format: `DEVICE_NAME:WEIGHT`) | +| `--device-read-bps=""` | Limit read rate from a device (format: `:[]`). Number is a positive integer. Unit can be one of `kb`, `mb`, or `gb`. | +| `--device-write-bps=""` | Limit write rate to a device (format: `:[]`). Number is a positive integer. Unit can be one of `kb`, `mb`, or `gb`. | +| `--device-read-iops="" ` | Limit read rate (IO per second) from a device (format: `:`). Number is a positive integer. | +| `--device-write-iops="" ` | Limit write rate (IO per second) to a device (format: `:`). Number is a positive integer. | +| `--oom-kill-disable=false` | Whether to disable OOM Killer for the container or not. | +| `--oom-score-adj=0` | Tune container's OOM preferences (-1000 to 1000) | +| `--memory-swappiness=""` | Tune a container's memory swappiness behavior. Accepts an integer between 0 and 100. | | `--shm-size=""` | Size of `/dev/shm`. The format is ``. `number` must be greater than `0`. Unit is optional and can be `b` (bytes), `k` (kilobytes), `m` (megabytes), or `g` (gigabytes). If you omit the unit, the system uses bytes. If you omit the size entirely, the system uses `64m`. | ### User memory constraints @@ -1158,7 +1159,7 @@ list of capabilities that are kept. The following table lists the Linux capabili options which are allowed by default and can be dropped. | Capability Key | Capability Description | -| ---------------- | ----------------------------------------------------------------------------------------------------------------------------- | +|:-----------------|:------------------------------------------------------------------------------------------------------------------------------| | SETPCAP | Modify process capabilities. | | MKNOD | Create special files using mknod(2). | | AUDIT_WRITE | Write records to kernel auditing log. | @@ -1176,31 +1177,31 @@ options which are allowed by default and can be dropped. The next table shows the capabilities which are not granted by default and may be added. -| Capability Key | Capability Description | -| ---------------- | ----------------------------------------------------------------------------------------------------------------------------- | -| SYS_MODULE | Load and unload kernel modules. | -| SYS_RAWIO | Perform I/O port operations (iopl(2) and ioperm(2)). | -| SYS_PACCT | Use acct(2), switch process accounting on or off. | -| SYS_ADMIN | Perform a range of system administration operations. | -| SYS_NICE | Raise process nice value (nice(2), setpriority(2)) and change the nice value for arbitrary processes. | -| SYS_RESOURCE | Override resource Limits. | -| SYS_TIME | Set system clock (settimeofday(2), stime(2), adjtimex(2)); set real-time (hardware) clock. | -| SYS_TTY_CONFIG | Use vhangup(2); employ various privileged ioctl(2) operations on virtual terminals. | -| AUDIT_CONTROL | Enable and disable kernel auditing; change auditing filter rules; retrieve auditing status and filtering rules. | -| MAC_OVERRIDE | Allow MAC configuration or state changes. Implemented for the Smack LSM. | -| MAC_ADMIN | Override Mandatory Access Control (MAC). Implemented for the Smack Linux Security Module (LSM). | -| NET_ADMIN | Perform various network-related operations. | -| SYSLOG | Perform privileged syslog(2) operations. | -| DAC_READ_SEARCH | Bypass file read permission checks and directory read and execute permission checks. | -| LINUX_IMMUTABLE | Set the FS_APPEND_FL and FS_IMMUTABLE_FL i-node flags. | -| NET_BROADCAST | Make socket broadcasts, and listen to multicasts. | -| IPC_LOCK | Lock memory (mlock(2), mlockall(2), mmap(2), shmctl(2)). | -| IPC_OWNER | Bypass permission checks for operations on System V IPC objects. | -| SYS_PTRACE | Trace arbitrary processes using ptrace(2). | -| SYS_BOOT | Use reboot(2) and kexec_load(2), reboot and load a new kernel for later execution. | -| LEASE | Establish leases on arbitrary files (see fcntl(2)). | -| WAKE_ALARM | Trigger something that will wake up the system. | -| BLOCK_SUSPEND | Employ features that can block system suspend. | +| Capability Key | Capability Description | +|:----------------|:----------------------------------------------------------------------------------------------------------------| +| SYS_MODULE | Load and unload kernel modules. | +| SYS_RAWIO | Perform I/O port operations (iopl(2) and ioperm(2)). | +| SYS_PACCT | Use acct(2), switch process accounting on or off. | +| SYS_ADMIN | Perform a range of system administration operations. | +| SYS_NICE | Raise process nice value (nice(2), setpriority(2)) and change the nice value for arbitrary processes. | +| SYS_RESOURCE | Override resource Limits. | +| SYS_TIME | Set system clock (settimeofday(2), stime(2), adjtimex(2)); set real-time (hardware) clock. | +| SYS_TTY_CONFIG | Use vhangup(2); employ various privileged ioctl(2) operations on virtual terminals. | +| AUDIT_CONTROL | Enable and disable kernel auditing; change auditing filter rules; retrieve auditing status and filtering rules. | +| MAC_OVERRIDE | Allow MAC configuration or state changes. Implemented for the Smack LSM. | +| MAC_ADMIN | Override Mandatory Access Control (MAC). Implemented for the Smack Linux Security Module (LSM). | +| NET_ADMIN | Perform various network-related operations. | +| SYSLOG | Perform privileged syslog(2) operations. | +| DAC_READ_SEARCH | Bypass file read permission checks and directory read and execute permission checks. | +| LINUX_IMMUTABLE | Set the FS_APPEND_FL and FS_IMMUTABLE_FL i-node flags. | +| NET_BROADCAST | Make socket broadcasts, and listen to multicasts. | +| IPC_LOCK | Lock memory (mlock(2), mlockall(2), mmap(2), shmctl(2)). | +| IPC_OWNER | Bypass permission checks for operations on System V IPC objects. | +| SYS_PTRACE | Trace arbitrary processes using ptrace(2). | +| SYS_BOOT | Use reboot(2) and kexec_load(2), reboot and load a new kernel for later execution. | +| LEASE | Establish leases on arbitrary files (see fcntl(2)). | +| WAKE_ALARM | Trigger something that will wake up the system. | +| BLOCK_SUSPEND | Employ features that can block system suspend. | Further reference information is available on the [capabilities(7) - Linux man page](http://man7.org/linux/man-pages/man7/capabilities.7.html) @@ -1252,7 +1253,7 @@ the `--log-driver=VALUE` with the `docker run` command to configure the container's logging driver. The following options are supported: | Driver | Description | -| ----------- | ----------------------------------------------------------------------------------------------------------------------------- | +|:------------|:------------------------------------------------------------------------------------------------------------------------------| | `none` | Disables any logging for the container. `docker logs` won't be available with this driver. | | `json-file` | Default logging driver for Docker. Writes JSON messages to file. No logging options are supported for this driver. | | `syslog` | Syslog logging driver for Docker. Writes log messages to syslog. | @@ -1398,12 +1399,12 @@ container. The following environment variables are set for Linux containers: -| Variable | Value | -| -------- | ----- | -| `HOME` | Set based on the value of `USER` | -| `HOSTNAME` | The hostname associated with the container | -| `PATH` | Includes popular directories, such as `/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin` | -| `TERM` | `xterm` if the container is allocated a pseudo-TTY | +| Variable | Value | +|:-----------|:-----------------------------------------------------------------------------------------------------| +| `HOME` | Set based on the value of `USER` | +| `HOSTNAME` | The hostname associated with the container | +| `PATH` | Includes popular directories, such as `/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin` | +| `TERM` | `xterm` if the container is allocated a pseudo-TTY | Additionally, the operator can **set any environment variable** in the diff --git a/components/cli/man/dockerd.8.md b/components/cli/man/dockerd.8.md index e9d7e68739..8a7619ca2c 100644 --- a/components/cli/man/dockerd.8.md +++ b/components/cli/man/dockerd.8.md @@ -703,6 +703,31 @@ Example use: $ sudo dockerd --storage-opt dm.xfs_nospace_max_retries=0 +##### dm.libdm_log_level + +Specifies the maxmimum libdm log level that will be forwarded to the dockerd +log (as specified by --log-level). This option is primarily intended for +debugging problems involving libdm. Using values other than the defaults may +cause false-positive warnings to be logged. + +Values specified must fall within the range of valid libdm log levels. At the +time of writing, the following is the list of libdm log levels as well as their +corresponding levels when output by dockerd. + +| libdm Level | Value | --log-level | +| ----------- | -----:| ----------- | +| _LOG_FATAL | 2 | error | +| _LOG_ERR | 3 | error | +| _LOG_WARN | 4 | warn | +| _LOG_NOTICE | 5 | info | +| _LOG_INFO | 6 | info | +| _LOG_DEBUG | 7 | debug | + +Example use: + + $ sudo dockerd \ + --log-level debug \ + --storage-opt dm.libdm_log_level=7 ## ZFS options diff --git a/components/cli/scripts/build/cross b/components/cli/scripts/build/cross index 9e7bfb35b8..39dcee4162 100755 --- a/components/cli/scripts/build/cross +++ b/components/cli/scripts/build/cross @@ -6,13 +6,28 @@ set -eu -o pipefail BUILDDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +export SHELL=bash -echo "Building binaries for all platforms" -SHELL=/bin/bash parallel ::: \ +jobs=( "$BUILDDIR/windows" \ "$BUILDDIR/osx" \ "GOOS=linux GOARCH=amd64 $BUILDDIR/binary" \ "GOOS=linux GOARCH=arm $BUILDDIR/binary" \ "GOOS=linux GOARCH=ppc64le $BUILDDIR/binary" \ "GOOS=linux GOARCH=s390x $BUILDDIR/binary" \ - ; +) + +# Outside of circleCI run all at once. On circleCI run two at a time because +# each continer has access to two cores. +group=${CROSS_GROUP-"all"} + +if [ "$group" == "all" ]; then + + echo "Building binaries for all platforms" + parallel ::: "${jobs[@]}" + exit 0 + +fi + +declare -i start=$group*2 +parallel ::: "${jobs[@]:$start:2}" diff --git a/components/cli/scripts/test/watch b/components/cli/scripts/test/watch index 3c2b46bea1..a63b94d32a 100755 --- a/components/cli/scripts/test/watch +++ b/components/cli/scripts/test/watch @@ -1,12 +1,2 @@ #!/bin/sh - -set -e - -filewatcher \ - -L 6 \ - -x '**/*.swp' \ - -x .git \ - -x build \ - -x .idea \ - -- \ - sh -c 'go test -timeout 10s -v ./${dir} || ( echo; echo; exit 1 )' +exec filewatcher -L 6 -x build -x script go test -timeout 10s -v './${dir}' diff --git a/components/cli/vendor.conf b/components/cli/vendor.conf index 9e7742e658..a212dd0a3a 100755 --- a/components/cli/vendor.conf +++ b/components/cli/vendor.conf @@ -1,5 +1,5 @@ github.com/Azure/go-ansiterm 388960b655244e76e24c75f48631564eaefade62 -github.com/Microsoft/go-winio v0.4.1 +github.com/Microsoft/go-winio v0.4.2 github.com/Nvveen/Gotty a8b993ba6abdb0e0c12b0125c603323a71c7790c https://github.com/ijc25/Gotty github.com/Sirupsen/logrus v0.11.0 github.com/agl/ed25519 d2b94fd789ea21d12fac1a4443dd3a3f79cda72c @@ -7,9 +7,12 @@ github.com/coreos/etcd 824277cb3a577a0e8c829ca9ec557b973fe06d20 github.com/cpuguy83/go-md2man a65d4d2de4d5f7c74868dfa9b202a3c8be315aaa github.com/davecgh/go-spew 346938d642f2ec3594ed81d874461961cd0faa76 github.com/docker/distribution b38e5838b7b2f2ad48e06ec4b500011976080621 -github.com/docker/docker 050c1bb17bd033e909cb653f5449b683608293d6 +github.com/docker/docker 87df0e533b619c088091fd1e2310e92bb9a24822 github.com/docker/docker-credential-helpers v0.5.1 -github.com/docker/go d30aec9fd63c35133f8f79c3412ad91a3b08be06 #? + +# the docker/go package contains a customized version of canonical/json +# and is used by Notary. The package is periodically rebased on current Go versions. +github.com/docker/go d30aec9fd63c35133f8f79c3412ad91a3b08be06 github.com/docker/go-connections 3ede32e2033de7505e6500d6c868c2b9ed9f169d github.com/docker/go-events 18b43f1bc85d9cdd42c05a6cd2d444c7a200a894 github.com/docker/go-units 9e638d38cf6977a37a8ea0078f3ee75a7cdb2dd1 @@ -30,7 +33,7 @@ github.com/opencontainers/image-spec f03dbe35d449c54915d235f1a3cf8f585a24babe github.com/opencontainers/runc 9c2d8d184e5da67c95d601382adf14862e4f2228 https://github.com/docker/runc.git github.com/opencontainers/selinux v1.0.0-rc1 github.com/pkg/errors 839d9e913e063e28dfd0e6c7b7512793e0a48be9 -github.com/pmezard/go-difflib 792786c7400a136282c1664665ae0a8db921c6c2 +github.com/pmezard/go-difflib v1.0.0 github.com/russross/blackfriday 1d6b8e9301e720b08a8938b8c25c018285885438 github.com/shurcooL/sanitized_anchor_name 10ef21a441db47d8b13ebcc5fd2310f636973c77 github.com/spf13/cobra v1.5.1 https://github.com/dnephin/cobra.git diff --git a/components/cli/vendor/github.com/Microsoft/go-winio/pipe.go b/components/cli/vendor/github.com/Microsoft/go-winio/pipe.go index fa270a310f..da706cc8a7 100644 --- a/components/cli/vendor/github.com/Microsoft/go-winio/pipe.go +++ b/components/cli/vendor/github.com/Microsoft/go-winio/pipe.go @@ -13,19 +13,12 @@ import ( ) //sys connectNamedPipe(pipe syscall.Handle, o *syscall.Overlapped) (err error) = ConnectNamedPipe -//sys createNamedPipe(name string, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *securityAttributes) (handle syscall.Handle, err error) [failretval==syscall.InvalidHandle] = CreateNamedPipeW -//sys createFile(name string, access uint32, mode uint32, sa *securityAttributes, createmode uint32, attrs uint32, templatefile syscall.Handle) (handle syscall.Handle, err error) [failretval==syscall.InvalidHandle] = CreateFileW +//sys createNamedPipe(name string, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *syscall.SecurityAttributes) (handle syscall.Handle, err error) [failretval==syscall.InvalidHandle] = CreateNamedPipeW +//sys createFile(name string, access uint32, mode uint32, sa *syscall.SecurityAttributes, createmode uint32, attrs uint32, templatefile syscall.Handle) (handle syscall.Handle, err error) [failretval==syscall.InvalidHandle] = CreateFileW //sys waitNamedPipe(name string, timeout uint32) (err error) = WaitNamedPipeW //sys getNamedPipeInfo(pipe syscall.Handle, flags *uint32, outSize *uint32, inSize *uint32, maxInstances *uint32) (err error) = GetNamedPipeInfo //sys getNamedPipeHandleState(pipe syscall.Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) = GetNamedPipeHandleStateW //sys localAlloc(uFlags uint32, length uint32) (ptr uintptr) = LocalAlloc -//sys copyMemory(dst uintptr, src uintptr, length uint32) = RtlCopyMemory - -type securityAttributes struct { - Length uint32 - SecurityDescriptor uintptr - InheritHandle uint32 -} const ( cERROR_PIPE_BUSY = syscall.Errno(231) @@ -233,13 +226,13 @@ func makeServerPipeHandle(path string, securityDescriptor []byte, c *PipeConfig, mode |= cPIPE_TYPE_MESSAGE } - sa := &securityAttributes{} + sa := &syscall.SecurityAttributes{} sa.Length = uint32(unsafe.Sizeof(*sa)) if securityDescriptor != nil { len := uint32(len(securityDescriptor)) sa.SecurityDescriptor = localAlloc(0, len) defer localFree(sa.SecurityDescriptor) - copyMemory(sa.SecurityDescriptor, uintptr(unsafe.Pointer(&securityDescriptor[0])), len) + copy((*[0xffff]byte)(unsafe.Pointer(sa.SecurityDescriptor))[:], securityDescriptor) } h, err := createNamedPipe(path, flags, mode, cPIPE_UNLIMITED_INSTANCES, uint32(c.OutputBufferSize), uint32(c.InputBufferSize), 0, sa) if err != nil { diff --git a/components/cli/vendor/github.com/Microsoft/go-winio/zsyscall_windows.go b/components/cli/vendor/github.com/Microsoft/go-winio/zsyscall_windows.go index 857122a3e8..4f7a52eeb7 100644 --- a/components/cli/vendor/github.com/Microsoft/go-winio/zsyscall_windows.go +++ b/components/cli/vendor/github.com/Microsoft/go-winio/zsyscall_windows.go @@ -53,7 +53,6 @@ var ( procGetNamedPipeInfo = modkernel32.NewProc("GetNamedPipeInfo") procGetNamedPipeHandleStateW = modkernel32.NewProc("GetNamedPipeHandleStateW") procLocalAlloc = modkernel32.NewProc("LocalAlloc") - procRtlCopyMemory = modkernel32.NewProc("RtlCopyMemory") procLookupAccountNameW = modadvapi32.NewProc("LookupAccountNameW") procConvertSidToStringSidW = modadvapi32.NewProc("ConvertSidToStringSidW") procConvertStringSecurityDescriptorToSecurityDescriptorW = modadvapi32.NewProc("ConvertStringSecurityDescriptorToSecurityDescriptorW") @@ -141,7 +140,7 @@ func connectNamedPipe(pipe syscall.Handle, o *syscall.Overlapped) (err error) { return } -func createNamedPipe(name string, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *securityAttributes) (handle syscall.Handle, err error) { +func createNamedPipe(name string, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *syscall.SecurityAttributes) (handle syscall.Handle, err error) { var _p0 *uint16 _p0, err = syscall.UTF16PtrFromString(name) if err != nil { @@ -150,7 +149,7 @@ func createNamedPipe(name string, flags uint32, pipeMode uint32, maxInstances ui return _createNamedPipe(_p0, flags, pipeMode, maxInstances, outSize, inSize, defaultTimeout, sa) } -func _createNamedPipe(name *uint16, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *securityAttributes) (handle syscall.Handle, err error) { +func _createNamedPipe(name *uint16, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *syscall.SecurityAttributes) (handle syscall.Handle, err error) { r0, _, e1 := syscall.Syscall9(procCreateNamedPipeW.Addr(), 8, uintptr(unsafe.Pointer(name)), uintptr(flags), uintptr(pipeMode), uintptr(maxInstances), uintptr(outSize), uintptr(inSize), uintptr(defaultTimeout), uintptr(unsafe.Pointer(sa)), 0) handle = syscall.Handle(r0) if handle == syscall.InvalidHandle { @@ -163,7 +162,7 @@ func _createNamedPipe(name *uint16, flags uint32, pipeMode uint32, maxInstances return } -func createFile(name string, access uint32, mode uint32, sa *securityAttributes, createmode uint32, attrs uint32, templatefile syscall.Handle) (handle syscall.Handle, err error) { +func createFile(name string, access uint32, mode uint32, sa *syscall.SecurityAttributes, createmode uint32, attrs uint32, templatefile syscall.Handle) (handle syscall.Handle, err error) { var _p0 *uint16 _p0, err = syscall.UTF16PtrFromString(name) if err != nil { @@ -172,7 +171,7 @@ func createFile(name string, access uint32, mode uint32, sa *securityAttributes, return _createFile(_p0, access, mode, sa, createmode, attrs, templatefile) } -func _createFile(name *uint16, access uint32, mode uint32, sa *securityAttributes, createmode uint32, attrs uint32, templatefile syscall.Handle) (handle syscall.Handle, err error) { +func _createFile(name *uint16, access uint32, mode uint32, sa *syscall.SecurityAttributes, createmode uint32, attrs uint32, templatefile syscall.Handle) (handle syscall.Handle, err error) { r0, _, e1 := syscall.Syscall9(procCreateFileW.Addr(), 7, uintptr(unsafe.Pointer(name)), uintptr(access), uintptr(mode), uintptr(unsafe.Pointer(sa)), uintptr(createmode), uintptr(attrs), uintptr(templatefile), 0, 0) handle = syscall.Handle(r0) if handle == syscall.InvalidHandle { @@ -236,11 +235,6 @@ func localAlloc(uFlags uint32, length uint32) (ptr uintptr) { return } -func copyMemory(dst uintptr, src uintptr, length uint32) { - syscall.Syscall(procRtlCopyMemory.Addr(), 3, uintptr(dst), uintptr(src), uintptr(length)) - return -} - func lookupAccountName(systemName *uint16, accountName string, sid *byte, sidSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) { var _p0 *uint16 _p0, err = syscall.UTF16PtrFromString(accountName) diff --git a/components/cli/vendor/github.com/docker/docker/api/common.go b/components/cli/vendor/github.com/docker/docker/api/common.go index 61a3692de1..859daf602c 100644 --- a/components/cli/vendor/github.com/docker/docker/api/common.go +++ b/components/cli/vendor/github.com/docker/docker/api/common.go @@ -4,15 +4,9 @@ import ( "encoding/json" "encoding/pem" "fmt" - "mime" "os" "path/filepath" - "sort" - "strconv" - "strings" - "github.com/Sirupsen/logrus" - "github.com/docker/docker/api/types" "github.com/docker/docker/pkg/ioutils" "github.com/docker/docker/pkg/system" "github.com/docker/libtrust" @@ -28,101 +22,6 @@ const ( NoBaseImageSpecifier string = "scratch" ) -// byPortInfo is a temporary type used to sort types.Port by its fields -type byPortInfo []types.Port - -func (r byPortInfo) Len() int { return len(r) } -func (r byPortInfo) Swap(i, j int) { r[i], r[j] = r[j], r[i] } -func (r byPortInfo) Less(i, j int) bool { - if r[i].PrivatePort != r[j].PrivatePort { - return r[i].PrivatePort < r[j].PrivatePort - } - - if r[i].IP != r[j].IP { - return r[i].IP < r[j].IP - } - - if r[i].PublicPort != r[j].PublicPort { - return r[i].PublicPort < r[j].PublicPort - } - - return r[i].Type < r[j].Type -} - -// DisplayablePorts returns formatted string representing open ports of container -// e.g. "0.0.0.0:80->9090/tcp, 9988/tcp" -// it's used by command 'docker ps' -func DisplayablePorts(ports []types.Port) string { - type portGroup struct { - first uint16 - last uint16 - } - groupMap := make(map[string]*portGroup) - var result []string - var hostMappings []string - var groupMapKeys []string - sort.Sort(byPortInfo(ports)) - for _, port := range ports { - current := port.PrivatePort - portKey := port.Type - if port.IP != "" { - if port.PublicPort != current { - hostMappings = append(hostMappings, fmt.Sprintf("%s:%d->%d/%s", port.IP, port.PublicPort, port.PrivatePort, port.Type)) - continue - } - portKey = fmt.Sprintf("%s/%s", port.IP, port.Type) - } - group := groupMap[portKey] - - if group == nil { - groupMap[portKey] = &portGroup{first: current, last: current} - // record order that groupMap keys are created - groupMapKeys = append(groupMapKeys, portKey) - continue - } - if current == (group.last + 1) { - group.last = current - continue - } - - result = append(result, formGroup(portKey, group.first, group.last)) - groupMap[portKey] = &portGroup{first: current, last: current} - } - for _, portKey := range groupMapKeys { - g := groupMap[portKey] - result = append(result, formGroup(portKey, g.first, g.last)) - } - result = append(result, hostMappings...) - return strings.Join(result, ", ") -} - -func formGroup(key string, start, last uint16) string { - parts := strings.Split(key, "/") - groupType := parts[0] - var ip string - if len(parts) > 1 { - ip = parts[0] - groupType = parts[1] - } - group := strconv.Itoa(int(start)) - if start != last { - group = fmt.Sprintf("%s-%d", group, last) - } - if ip != "" { - group = fmt.Sprintf("%s:%s->%s", ip, group, group) - } - return fmt.Sprintf("%s/%s", group, groupType) -} - -// MatchesContentType validates the content type against the expected one -func MatchesContentType(contentType, expectedType string) bool { - mimetype, _, err := mime.ParseMediaType(contentType) - if err != nil { - logrus.Errorf("Error parsing media type: %s error: %v", contentType, err) - } - return err == nil && mimetype == expectedType -} - // LoadOrCreateTrustKey attempts to load the libtrust key at the given path, // otherwise generates a new one func LoadOrCreateTrustKey(trustKeyPath string) (libtrust.PrivateKey, error) { diff --git a/components/cli/vendor/github.com/docker/docker/api/types/types.go b/components/cli/vendor/github.com/docker/docker/api/types/types.go index 2473497c89..c96df27332 100644 --- a/components/cli/vendor/github.com/docker/docker/api/types/types.go +++ b/components/cli/vendor/github.com/docker/docker/api/types/types.go @@ -45,6 +45,12 @@ type ImageInspect struct { VirtualSize int64 GraphDriver GraphDriverData RootFS RootFS + Metadata ImageMetadata +} + +// ImageMetadata contains engine-local data about the image +type ImageMetadata struct { + LastTagTime time.Time `json:",omitempty"` } // Container contains response of Engine API: diff --git a/components/cli/vendor/github.com/docker/docker/builder/remotecontext/git/gitutils.go b/components/cli/vendor/github.com/docker/docker/builder/remotecontext/git/gitutils.go index fd8250dbc3..b94d462cd5 100644 --- a/components/cli/vendor/github.com/docker/docker/builder/remotecontext/git/gitutils.go +++ b/components/cli/vendor/github.com/docker/docker/builder/remotecontext/git/gitutils.go @@ -15,18 +15,24 @@ import ( "github.com/pkg/errors" ) +type gitRepo struct { + remote string + ref string + subdir string +} + // Clone clones a repository into a newly created directory which // will be under "docker-build-git" func Clone(remoteURL string) (string, error) { - if !urlutil.IsGitTransport(remoteURL) { - remoteURL = "https://" + remoteURL - } - root, err := ioutil.TempDir("", "docker-build-git") + repo, err := parseRemoteURL(remoteURL) + if err != nil { return "", err } - u, err := url.Parse(remoteURL) + fetch := fetchArgs(repo.remote, repo.ref) + + root, err := ioutil.TempDir("", "docker-build-git") if err != nil { return "", err } @@ -35,22 +41,47 @@ func Clone(remoteURL string) (string, error) { return "", errors.Wrapf(err, "failed to init repo at %s: %s", root, out) } - ref, subdir := getRefAndSubdir(u.Fragment) - fetch := fetchArgs(u, ref) - - u.Fragment = "" - // Add origin remote for compatibility with previous implementation that // used "git clone" and also to make sure local refs are created for branches - if out, err := gitWithinDir(root, "remote", "add", "origin", u.String()); err != nil { - return "", errors.Wrapf(err, "failed add origin repo at %s: %s", u.String(), out) + if out, err := gitWithinDir(root, "remote", "add", "origin", repo.remote); err != nil { + return "", errors.Wrapf(err, "failed add origin repo at %s: %s", repo.remote, out) } if output, err := gitWithinDir(root, fetch...); err != nil { return "", errors.Wrapf(err, "error fetching: %s", output) } - return checkoutGit(root, ref, subdir) + return checkoutGit(root, repo.ref, repo.subdir) +} + +func parseRemoteURL(remoteURL string) (gitRepo, error) { + repo := gitRepo{} + + if !isGitTransport(remoteURL) { + remoteURL = "https://" + remoteURL + } + + var fragment string + if strings.HasPrefix(remoteURL, "git@") { + // git@.. is not an URL, so cannot be parsed as URL + parts := strings.SplitN(remoteURL, "#", 2) + + repo.remote = parts[0] + if len(parts) == 2 { + fragment = parts[1] + } + repo.ref, repo.subdir = getRefAndSubdir(fragment) + } else { + u, err := url.Parse(remoteURL) + if err != nil { + return repo, err + } + + repo.ref, repo.subdir = getRefAndSubdir(u.Fragment) + u.Fragment = "" + repo.remote = u.String() + } + return repo, nil } func getRefAndSubdir(fragment string) (ref string, subdir string) { @@ -65,11 +96,11 @@ func getRefAndSubdir(fragment string) (ref string, subdir string) { return } -func fetchArgs(remoteURL *url.URL, ref string) []string { +func fetchArgs(remoteURL string, ref string) []string { args := []string{"fetch", "--recurse-submodules=yes"} shallow := true - if strings.HasPrefix(remoteURL.Scheme, "http") { + if urlutil.IsURL(remoteURL) { res, err := http.Head(fmt.Sprintf("%s/info/refs?service=git-upload-pack", remoteURL)) if err != nil || res.Header.Get("Content-Type") != "application/x-git-upload-pack-advertisement" { shallow = false @@ -120,3 +151,9 @@ func gitWithinDir(dir string, args ...string) ([]byte, error) { func git(args ...string) ([]byte, error) { return exec.Command("git", args...).CombinedOutput() } + +// isGitTransport returns true if the provided str is a git transport by inspecting +// the prefix of the string for known protocols used in git. +func isGitTransport(str string) bool { + return urlutil.IsURL(str) || strings.HasPrefix(str, "git://") || strings.HasPrefix(str, "git@") +} diff --git a/components/cli/vendor/github.com/docker/docker/client/container_copy.go b/components/cli/vendor/github.com/docker/docker/client/container_copy.go index 66ee5c1b3b..30ba6803f0 100644 --- a/components/cli/vendor/github.com/docker/docker/client/container_copy.go +++ b/components/cli/vendor/github.com/docker/docker/client/container_copy.go @@ -30,6 +30,7 @@ func (cli *Client) ContainerStatPath(ctx context.Context, containerID, path stri } // CopyToContainer copies content into the container filesystem. +// Note that `content` must be a Reader for a TAR func (cli *Client) CopyToContainer(ctx context.Context, container, path string, content io.Reader, options types.CopyToContainerOptions) error { query := url.Values{} query.Set("path", filepath.ToSlash(path)) // Normalize the paths used in the API. diff --git a/components/cli/vendor/github.com/docker/docker/client/ping.go b/components/cli/vendor/github.com/docker/docker/client/ping.go index 631ed02005..a4c2e2c4dd 100644 --- a/components/cli/vendor/github.com/docker/docker/client/ping.go +++ b/components/cli/vendor/github.com/docker/docker/client/ping.go @@ -18,13 +18,15 @@ func (cli *Client) Ping(ctx context.Context) (types.Ping, error) { } defer ensureReaderClosed(serverResp) - ping.APIVersion = serverResp.header.Get("API-Version") + if serverResp.header != nil { + ping.APIVersion = serverResp.header.Get("API-Version") - if serverResp.header.Get("Docker-Experimental") == "true" { - ping.Experimental = true + if serverResp.header.Get("Docker-Experimental") == "true" { + ping.Experimental = true + } + ping.OSType = serverResp.header.Get("OSType") } - ping.OSType = serverResp.header.Get("OSType") - - return ping, nil + err = cli.checkResponseErr(serverResp) + return ping, err } diff --git a/components/cli/vendor/github.com/docker/docker/client/request.go b/components/cli/vendor/github.com/docker/docker/client/request.go index 6457b316a3..3e7d43feac 100644 --- a/components/cli/vendor/github.com/docker/docker/client/request.go +++ b/components/cli/vendor/github.com/docker/docker/client/request.go @@ -24,6 +24,7 @@ type serverResponse struct { body io.ReadCloser header http.Header statusCode int + reqURL *url.URL } // head sends an http request to the docker API using the method HEAD. @@ -118,11 +119,18 @@ func (cli *Client) sendRequest(ctx context.Context, method, path string, query u if err != nil { return serverResponse{}, err } - return cli.doRequest(ctx, req) + resp, err := cli.doRequest(ctx, req) + if err != nil { + return resp, err + } + if err := cli.checkResponseErr(resp); err != nil { + return resp, err + } + return resp, nil } func (cli *Client) doRequest(ctx context.Context, req *http.Request) (serverResponse, error) { - serverResp := serverResponse{statusCode: -1} + serverResp := serverResponse{statusCode: -1, reqURL: req.URL} resp, err := ctxhttp.Do(ctx, cli.client, req) if err != nil { @@ -179,37 +187,44 @@ func (cli *Client) doRequest(ctx context.Context, req *http.Request) (serverResp if resp != nil { serverResp.statusCode = resp.StatusCode + serverResp.body = resp.Body + serverResp.header = resp.Header } - - if serverResp.statusCode < 200 || serverResp.statusCode >= 400 { - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return serverResp, err - } - if len(body) == 0 { - return serverResp, fmt.Errorf("Error: request returned %s for API route and version %s, check if the server supports the requested API version", http.StatusText(serverResp.statusCode), req.URL) - } - - var errorMessage string - if (cli.version == "" || versions.GreaterThan(cli.version, "1.23")) && - resp.Header.Get("Content-Type") == "application/json" { - var errorResponse types.ErrorResponse - if err := json.Unmarshal(body, &errorResponse); err != nil { - return serverResp, fmt.Errorf("Error reading JSON: %v", err) - } - errorMessage = errorResponse.Message - } else { - errorMessage = string(body) - } - - return serverResp, fmt.Errorf("Error response from daemon: %s", strings.TrimSpace(errorMessage)) - } - - serverResp.body = resp.Body - serverResp.header = resp.Header return serverResp, nil } +func (cli *Client) checkResponseErr(serverResp serverResponse) error { + if serverResp.statusCode >= 200 && serverResp.statusCode < 400 { + return nil + } + + body, err := ioutil.ReadAll(serverResp.body) + if err != nil { + return err + } + if len(body) == 0 { + return fmt.Errorf("Error: request returned %s for API route and version %s, check if the server supports the requested API version", http.StatusText(serverResp.statusCode), serverResp.reqURL) + } + + var ct string + if serverResp.header != nil { + ct = serverResp.header.Get("Content-Type") + } + + var errorMessage string + if (cli.version == "" || versions.GreaterThan(cli.version, "1.23")) && ct == "application/json" { + var errorResponse types.ErrorResponse + if err := json.Unmarshal(body, &errorResponse); err != nil { + return fmt.Errorf("Error reading JSON: %v", err) + } + errorMessage = errorResponse.Message + } else { + errorMessage = string(body) + } + + return fmt.Errorf("Error response from daemon: %s", strings.TrimSpace(errorMessage)) +} + func (cli *Client) addHeaders(req *http.Request, headers headers) *http.Request { // Add CLI Config's HTTP Headers BEFORE we set the Docker headers // then the user can't change OUR headers @@ -239,9 +254,9 @@ func encodeData(data interface{}) (*bytes.Buffer, error) { } func ensureReaderClosed(response serverResponse) { - if body := response.body; body != nil { + if response.body != nil { // Drain up to 512 bytes and close the body to let the Transport reuse the connection - io.CopyN(ioutil.Discard, body, 512) + io.CopyN(ioutil.Discard, response.body, 512) response.body.Close() } } diff --git a/components/cli/vendor/github.com/docker/docker/client/service_create.go b/components/cli/vendor/github.com/docker/docker/client/service_create.go index 71a7583e86..c2fc2776a8 100644 --- a/components/cli/vendor/github.com/docker/docker/client/service_create.go +++ b/components/cli/vendor/github.com/docker/docker/client/service_create.go @@ -39,7 +39,7 @@ func (cli *Client) ServiceCreate(ctx context.Context, service swarm.ServiceSpec, service.TaskTemplate.ContainerSpec.Image = img } // add platforms that are compatible with the service - service.TaskTemplate.Placement = updateServicePlatforms(service.TaskTemplate.Placement, distributionInspect) + service.TaskTemplate.Placement = setServicePlatforms(service.TaskTemplate.Placement, distributionInspect) } } var response types.ServiceCreateResponse @@ -86,13 +86,15 @@ func imageWithTagString(image string) string { return "" } -// updateServicePlatforms updates the Platforms in swarm.Placement to list -// all compatible platforms for the service, as found in distributionInspect -// and returns a pointer to the new or updated swarm.Placement struct -func updateServicePlatforms(placement *swarm.Placement, distributionInspect registrytypes.DistributionInspect) *swarm.Placement { +// setServicePlatforms sets Platforms in swarm.Placement to list all +// compatible platforms for the service, as found in distributionInspect +// and returns a pointer to the new or updated swarm.Placement struct. +func setServicePlatforms(placement *swarm.Placement, distributionInspect registrytypes.DistributionInspect) *swarm.Placement { if placement == nil { placement = &swarm.Placement{} } + // reset any existing listed platforms + placement.Platforms = []swarm.Platform{} for _, p := range distributionInspect.Platforms { placement.Platforms = append(placement.Platforms, swarm.Platform{ Architecture: p.Architecture, diff --git a/components/cli/vendor/github.com/docker/docker/client/service_update.go b/components/cli/vendor/github.com/docker/docker/client/service_update.go index 412790b5dd..a72adc997c 100644 --- a/components/cli/vendor/github.com/docker/docker/client/service_update.go +++ b/components/cli/vendor/github.com/docker/docker/client/service_update.go @@ -51,7 +51,7 @@ func (cli *Client) ServiceUpdate(ctx context.Context, serviceID string, version service.TaskTemplate.ContainerSpec.Image = img } // add platforms that are compatible with the service - service.TaskTemplate.Placement = updateServicePlatforms(service.TaskTemplate.Placement, distributionInspect) + service.TaskTemplate.Placement = setServicePlatforms(service.TaskTemplate.Placement, distributionInspect) } } diff --git a/components/cli/vendor/github.com/docker/docker/pkg/archive/example_changes.go b/components/cli/vendor/github.com/docker/docker/pkg/archive/example_changes.go deleted file mode 100644 index cedd46a408..0000000000 --- a/components/cli/vendor/github.com/docker/docker/pkg/archive/example_changes.go +++ /dev/null @@ -1,97 +0,0 @@ -// +build ignore - -// Simple tool to create an archive stream from an old and new directory -// -// By default it will stream the comparison of two temporary directories with junk files -package main - -import ( - "flag" - "fmt" - "io" - "io/ioutil" - "os" - "path" - - "github.com/Sirupsen/logrus" - "github.com/docker/docker/pkg/archive" -) - -var ( - flDebug = flag.Bool("D", false, "debugging output") - flNewDir = flag.String("newdir", "", "") - flOldDir = flag.String("olddir", "", "") - log = logrus.New() -) - -func main() { - flag.Usage = func() { - fmt.Println("Produce a tar from comparing two directory paths. By default a demo tar is created of around 200 files (including hardlinks)") - fmt.Printf("%s [OPTIONS]\n", os.Args[0]) - flag.PrintDefaults() - } - flag.Parse() - log.Out = os.Stderr - if (len(os.Getenv("DEBUG")) > 0) || *flDebug { - logrus.SetLevel(logrus.DebugLevel) - } - var newDir, oldDir string - - if len(*flNewDir) == 0 { - var err error - newDir, err = ioutil.TempDir("", "docker-test-newDir") - if err != nil { - log.Fatal(err) - } - defer os.RemoveAll(newDir) - if _, err := prepareUntarSourceDirectory(100, newDir, true); err != nil { - log.Fatal(err) - } - } else { - newDir = *flNewDir - } - - if len(*flOldDir) == 0 { - oldDir, err := ioutil.TempDir("", "docker-test-oldDir") - if err != nil { - log.Fatal(err) - } - defer os.RemoveAll(oldDir) - } else { - oldDir = *flOldDir - } - - changes, err := archive.ChangesDirs(newDir, oldDir) - if err != nil { - log.Fatal(err) - } - - a, err := archive.ExportChanges(newDir, changes) - if err != nil { - log.Fatal(err) - } - defer a.Close() - - i, err := io.Copy(os.Stdout, a) - if err != nil && err != io.EOF { - log.Fatal(err) - } - fmt.Fprintf(os.Stderr, "wrote archive of %d bytes", i) -} - -func prepareUntarSourceDirectory(numberOfFiles int, targetPath string, makeLinks bool) (int, error) { - fileData := []byte("fooo") - for n := 0; n < numberOfFiles; n++ { - fileName := fmt.Sprintf("file-%d", n) - if err := ioutil.WriteFile(path.Join(targetPath, fileName), fileData, 0700); err != nil { - return 0, err - } - if makeLinks { - if err := os.Link(path.Join(targetPath, fileName), path.Join(targetPath, fileName+"-link")); err != nil { - return 0, err - } - } - } - totalSize := numberOfFiles * len(fileData) - return totalSize, nil -} diff --git a/components/cli/vendor/github.com/docker/docker/pkg/urlutil/urlutil.go b/components/cli/vendor/github.com/docker/docker/pkg/urlutil/urlutil.go index 44152873b1..cfcd582036 100644 --- a/components/cli/vendor/github.com/docker/docker/pkg/urlutil/urlutil.go +++ b/components/cli/vendor/github.com/docker/docker/pkg/urlutil/urlutil.go @@ -29,12 +29,6 @@ func IsGitURL(str string) bool { return checkURL(str, "git") } -// IsGitTransport returns true if the provided str is a git transport by inspecting -// the prefix of the string for known protocols used in git. -func IsGitTransport(str string) bool { - return IsURL(str) || strings.HasPrefix(str, "git://") || strings.HasPrefix(str, "git@") -} - // IsTransportURL returns true if the provided str is a transport (tcp, tcp+tls, udp, unix) URL. func IsTransportURL(str string) bool { return checkURL(str, "transport") diff --git a/components/cli/vendor/github.com/docker/docker/vendor.conf b/components/cli/vendor/github.com/docker/docker/vendor.conf index 83cedfd52b..bad511c4d4 100644 --- a/components/cli/vendor/github.com/docker/docker/vendor.conf +++ b/components/cli/vendor/github.com/docker/docker/vendor.conf @@ -1,6 +1,6 @@ # the following lines are in sorted order, FYI github.com/Azure/go-ansiterm 388960b655244e76e24c75f48631564eaefade62 -github.com/Microsoft/hcsshim v0.5.23 +github.com/Microsoft/hcsshim v0.5.25 github.com/Microsoft/go-winio v0.4.2 github.com/Sirupsen/logrus v0.11.0 github.com/davecgh/go-spew 346938d642f2ec3594ed81d874461961cd0faa76 @@ -8,7 +8,7 @@ github.com/docker/libtrust 9cbd2a1374f46905c68a4eb3694a130610adc62a github.com/go-check/check 4ed411733c5785b40214c70bce814c3a3a689609 https://github.com/cpuguy83/check.git github.com/gorilla/context v1.1 github.com/gorilla/mux v1.1 -github.com/jhowardmsft/opengcs v0.0.3 +github.com/jhowardmsft/opengcs v0.0.7 github.com/kr/pty 5cf931ef8f github.com/mattn/go-shellwords v1.0.3 github.com/tchap/go-patricia v2.2.6 @@ -17,7 +17,7 @@ github.com/vdemeester/shakers 24d7f1d6a71aa5d9cbe7390e4afb66b7eef9e1b3 golang.org/x/net 7dcfb8076726a3fdd9353b6b8a1f1b6be6811bd6 golang.org/x/sys 8f0908ab3b2457e2e15403d3697c9ef5cb4b57a9 github.com/docker/go-units 9e638d38cf6977a37a8ea0078f3ee75a7cdb2dd1 -github.com/docker/go-connections e15c02316c12de00874640cd76311849de2aeed5 +github.com/docker/go-connections 3ede32e2033de7505e6500d6c868c2b9ed9f169d golang.org/x/text f72d8390a633d5dfb0cc84043294db9f6c935756 github.com/stretchr/testify 4d4bfba8f1d1027c4fdbe371823030df51419987 github.com/pmezard/go-difflib v1.0.0 @@ -27,7 +27,7 @@ github.com/imdario/mergo 0.2.1 golang.org/x/sync de49d9dcd27d4f764488181bea099dfe6179bcf0 #get libnetwork packages -github.com/docker/libnetwork f4a15a0890383619ad797b3bd2481cc6f46a978d +github.com/docker/libnetwork 6426d1e66f33c0b0c8bb135b7ee547447f54d043 github.com/docker/go-events 18b43f1bc85d9cdd42c05a6cd2d444c7a200a894 github.com/armon/go-radix e39d623f12e8e41c7b5529e9a9dd67a1e2261f80 github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec @@ -106,7 +106,7 @@ github.com/stevvooe/continuity cd7a8e21e2b6f84799f5dd4b65faf49c8d3ee02d github.com/tonistiigi/fsutil 0ac4c11b053b9c5c7c47558f81f96c7100ce50fb # cluster -github.com/docker/swarmkit a4bf0135f63fb60f0e76ae81579cde87f580db6e +github.com/docker/swarmkit 79381d0840be27f8b3f5c667b348a4467d866eeb github.com/gogo/protobuf v0.4 github.com/cloudflare/cfssl 7fb22c8cba7ecaf98e4082d22d65800cf45e042a github.com/google/certificate-transparency d90e65c3a07988180c5b1ece71791c0b6506826e diff --git a/components/cli/vendor/github.com/docker/docker/volume/volume.go b/components/cli/vendor/github.com/docker/docker/volume/volume.go index 2abfcc7b58..2de248aa5f 100644 --- a/components/cli/vendor/github.com/docker/docker/volume/volume.go +++ b/components/cli/vendor/github.com/docker/docker/volume/volume.go @@ -153,16 +153,18 @@ func (m *MountPoint) Cleanup() error { // before creating the source directory on the host. func (m *MountPoint) Setup(mountLabel string, rootIDs idtools.IDPair, checkFun func(m *MountPoint) error) (path string, err error) { defer func() { - if err == nil { - if label.RelabelNeeded(m.Mode) { - if err = label.Relabel(m.Source, mountLabel, label.IsShared(m.Mode)); err != nil { - path = "" - err = errors.Wrapf(err, "error setting label on mount source '%s'", m.Source) - return - } - } + if err != nil || !label.RelabelNeeded(m.Mode) { + return + } + + err = label.Relabel(m.Source, mountLabel, label.IsShared(m.Mode)) + if err == syscall.ENOTSUP { + err = nil + } + if err != nil { + path = "" + err = errors.Wrapf(err, "error setting label on mount source '%s'", m.Source) } - return }() if m.Volume != nil { diff --git a/components/cli/vendor/golang.org/x/sys/unix/mkpost.go b/components/cli/vendor/golang.org/x/sys/unix/mkpost.go deleted file mode 100644 index ed50d902af..0000000000 --- a/components/cli/vendor/golang.org/x/sys/unix/mkpost.go +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build ignore - -// mkpost processes the output of cgo -godefs to -// modify the generated types. It is used to clean up -// the sys API in an architecture specific manner. -// -// mkpost is run after cgo -godefs by mkall.sh. -package main - -import ( - "fmt" - "go/format" - "io/ioutil" - "log" - "os" - "regexp" -) - -func main() { - b, err := ioutil.ReadAll(os.Stdin) - if err != nil { - log.Fatal(err) - } - s := string(b) - - goarch := os.Getenv("GOARCH") - goos := os.Getenv("GOOS") - if goarch == "s390x" && goos == "linux" { - // Export the types of PtraceRegs fields. - re := regexp.MustCompile("ptrace(Psw|Fpregs|Per)") - s = re.ReplaceAllString(s, "Ptrace$1") - - // Replace padding fields inserted by cgo with blank identifiers. - re = regexp.MustCompile("Pad_cgo[A-Za-z0-9_]*") - s = re.ReplaceAllString(s, "_") - - // Replace other unwanted fields with blank identifiers. - re = regexp.MustCompile("X_[A-Za-z0-9_]*") - s = re.ReplaceAllString(s, "_") - - // Replace the control_regs union with a blank identifier for now. - re = regexp.MustCompile("(Control_regs)\\s+\\[0\\]uint64") - s = re.ReplaceAllString(s, "_ [0]uint64") - } - - // gofmt - b, err = format.Source([]byte(s)) - if err != nil { - log.Fatal(err) - } - - // Append this command to the header to show where the new file - // came from. - re := regexp.MustCompile("(cgo -godefs [a-zA-Z0-9_]+\\.go.*)") - b = re.ReplaceAll(b, []byte("$1 | go run mkpost.go")) - - fmt.Printf("%s", b) -} diff --git a/components/cli/vendor/golang.org/x/sys/unix/types_darwin.go b/components/cli/vendor/golang.org/x/sys/unix/types_darwin.go deleted file mode 100644 index 1153261822..0000000000 --- a/components/cli/vendor/golang.org/x/sys/unix/types_darwin.go +++ /dev/null @@ -1,250 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build ignore - -/* -Input to cgo -godefs. See also mkerrors.sh and mkall.sh -*/ - -// +godefs map struct_in_addr [4]byte /* in_addr */ -// +godefs map struct_in6_addr [16]byte /* in6_addr */ - -package unix - -/* -#define __DARWIN_UNIX03 0 -#define KERNEL -#define _DARWIN_USE_64_BIT_INODE -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -enum { - sizeofPtr = sizeof(void*), -}; - -union sockaddr_all { - struct sockaddr s1; // this one gets used for fields - struct sockaddr_in s2; // these pad it out - struct sockaddr_in6 s3; - struct sockaddr_un s4; - struct sockaddr_dl s5; -}; - -struct sockaddr_any { - struct sockaddr addr; - char pad[sizeof(union sockaddr_all) - sizeof(struct sockaddr)]; -}; - -*/ -import "C" - -// Machine characteristics; for internal use. - -const ( - sizeofPtr = C.sizeofPtr - sizeofShort = C.sizeof_short - sizeofInt = C.sizeof_int - sizeofLong = C.sizeof_long - sizeofLongLong = C.sizeof_longlong -) - -// Basic types - -type ( - _C_short C.short - _C_int C.int - _C_long C.long - _C_long_long C.longlong -) - -// Time - -type Timespec C.struct_timespec - -type Timeval C.struct_timeval - -type Timeval32 C.struct_timeval32 - -// Processes - -type Rusage C.struct_rusage - -type Rlimit C.struct_rlimit - -type _Gid_t C.gid_t - -// Files - -type Stat_t C.struct_stat64 - -type Statfs_t C.struct_statfs64 - -type Flock_t C.struct_flock - -type Fstore_t C.struct_fstore - -type Radvisory_t C.struct_radvisory - -type Fbootstraptransfer_t C.struct_fbootstraptransfer - -type Log2phys_t C.struct_log2phys - -type Fsid C.struct_fsid - -type Dirent C.struct_dirent - -// Sockets - -type RawSockaddrInet4 C.struct_sockaddr_in - -type RawSockaddrInet6 C.struct_sockaddr_in6 - -type RawSockaddrUnix C.struct_sockaddr_un - -type RawSockaddrDatalink C.struct_sockaddr_dl - -type RawSockaddr C.struct_sockaddr - -type RawSockaddrAny C.struct_sockaddr_any - -type _Socklen C.socklen_t - -type Linger C.struct_linger - -type Iovec C.struct_iovec - -type IPMreq C.struct_ip_mreq - -type IPv6Mreq C.struct_ipv6_mreq - -type Msghdr C.struct_msghdr - -type Cmsghdr C.struct_cmsghdr - -type Inet4Pktinfo C.struct_in_pktinfo - -type Inet6Pktinfo C.struct_in6_pktinfo - -type IPv6MTUInfo C.struct_ip6_mtuinfo - -type ICMPv6Filter C.struct_icmp6_filter - -const ( - SizeofSockaddrInet4 = C.sizeof_struct_sockaddr_in - SizeofSockaddrInet6 = C.sizeof_struct_sockaddr_in6 - SizeofSockaddrAny = C.sizeof_struct_sockaddr_any - SizeofSockaddrUnix = C.sizeof_struct_sockaddr_un - SizeofSockaddrDatalink = C.sizeof_struct_sockaddr_dl - SizeofLinger = C.sizeof_struct_linger - SizeofIPMreq = C.sizeof_struct_ip_mreq - SizeofIPv6Mreq = C.sizeof_struct_ipv6_mreq - SizeofMsghdr = C.sizeof_struct_msghdr - SizeofCmsghdr = C.sizeof_struct_cmsghdr - SizeofInet4Pktinfo = C.sizeof_struct_in_pktinfo - SizeofInet6Pktinfo = C.sizeof_struct_in6_pktinfo - SizeofIPv6MTUInfo = C.sizeof_struct_ip6_mtuinfo - SizeofICMPv6Filter = C.sizeof_struct_icmp6_filter -) - -// Ptrace requests - -const ( - PTRACE_TRACEME = C.PT_TRACE_ME - PTRACE_CONT = C.PT_CONTINUE - PTRACE_KILL = C.PT_KILL -) - -// Events (kqueue, kevent) - -type Kevent_t C.struct_kevent - -// Select - -type FdSet C.fd_set - -// Routing and interface messages - -const ( - SizeofIfMsghdr = C.sizeof_struct_if_msghdr - SizeofIfData = C.sizeof_struct_if_data - SizeofIfaMsghdr = C.sizeof_struct_ifa_msghdr - SizeofIfmaMsghdr = C.sizeof_struct_ifma_msghdr - SizeofIfmaMsghdr2 = C.sizeof_struct_ifma_msghdr2 - SizeofRtMsghdr = C.sizeof_struct_rt_msghdr - SizeofRtMetrics = C.sizeof_struct_rt_metrics -) - -type IfMsghdr C.struct_if_msghdr - -type IfData C.struct_if_data - -type IfaMsghdr C.struct_ifa_msghdr - -type IfmaMsghdr C.struct_ifma_msghdr - -type IfmaMsghdr2 C.struct_ifma_msghdr2 - -type RtMsghdr C.struct_rt_msghdr - -type RtMetrics C.struct_rt_metrics - -// Berkeley packet filter - -const ( - SizeofBpfVersion = C.sizeof_struct_bpf_version - SizeofBpfStat = C.sizeof_struct_bpf_stat - SizeofBpfProgram = C.sizeof_struct_bpf_program - SizeofBpfInsn = C.sizeof_struct_bpf_insn - SizeofBpfHdr = C.sizeof_struct_bpf_hdr -) - -type BpfVersion C.struct_bpf_version - -type BpfStat C.struct_bpf_stat - -type BpfProgram C.struct_bpf_program - -type BpfInsn C.struct_bpf_insn - -type BpfHdr C.struct_bpf_hdr - -// Terminal handling - -type Termios C.struct_termios - -// fchmodat-like syscalls. - -const ( - AT_FDCWD = C.AT_FDCWD - AT_SYMLINK_NOFOLLOW = C.AT_SYMLINK_NOFOLLOW -) diff --git a/components/cli/vendor/golang.org/x/sys/unix/types_dragonfly.go b/components/cli/vendor/golang.org/x/sys/unix/types_dragonfly.go deleted file mode 100644 index f3c971dffd..0000000000 --- a/components/cli/vendor/golang.org/x/sys/unix/types_dragonfly.go +++ /dev/null @@ -1,242 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build ignore - -/* -Input to cgo -godefs. See also mkerrors.sh and mkall.sh -*/ - -// +godefs map struct_in_addr [4]byte /* in_addr */ -// +godefs map struct_in6_addr [16]byte /* in6_addr */ - -package unix - -/* -#define KERNEL -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -enum { - sizeofPtr = sizeof(void*), -}; - -union sockaddr_all { - struct sockaddr s1; // this one gets used for fields - struct sockaddr_in s2; // these pad it out - struct sockaddr_in6 s3; - struct sockaddr_un s4; - struct sockaddr_dl s5; -}; - -struct sockaddr_any { - struct sockaddr addr; - char pad[sizeof(union sockaddr_all) - sizeof(struct sockaddr)]; -}; - -*/ -import "C" - -// Machine characteristics; for internal use. - -const ( - sizeofPtr = C.sizeofPtr - sizeofShort = C.sizeof_short - sizeofInt = C.sizeof_int - sizeofLong = C.sizeof_long - sizeofLongLong = C.sizeof_longlong -) - -// Basic types - -type ( - _C_short C.short - _C_int C.int - _C_long C.long - _C_long_long C.longlong -) - -// Time - -type Timespec C.struct_timespec - -type Timeval C.struct_timeval - -// Processes - -type Rusage C.struct_rusage - -type Rlimit C.struct_rlimit - -type _Gid_t C.gid_t - -// Files - -const ( // Directory mode bits - S_IFMT = C.S_IFMT - S_IFIFO = C.S_IFIFO - S_IFCHR = C.S_IFCHR - S_IFDIR = C.S_IFDIR - S_IFBLK = C.S_IFBLK - S_IFREG = C.S_IFREG - S_IFLNK = C.S_IFLNK - S_IFSOCK = C.S_IFSOCK - S_ISUID = C.S_ISUID - S_ISGID = C.S_ISGID - S_ISVTX = C.S_ISVTX - S_IRUSR = C.S_IRUSR - S_IWUSR = C.S_IWUSR - S_IXUSR = C.S_IXUSR -) - -type Stat_t C.struct_stat - -type Statfs_t C.struct_statfs - -type Flock_t C.struct_flock - -type Dirent C.struct_dirent - -type Fsid C.struct_fsid - -// Sockets - -type RawSockaddrInet4 C.struct_sockaddr_in - -type RawSockaddrInet6 C.struct_sockaddr_in6 - -type RawSockaddrUnix C.struct_sockaddr_un - -type RawSockaddrDatalink C.struct_sockaddr_dl - -type RawSockaddr C.struct_sockaddr - -type RawSockaddrAny C.struct_sockaddr_any - -type _Socklen C.socklen_t - -type Linger C.struct_linger - -type Iovec C.struct_iovec - -type IPMreq C.struct_ip_mreq - -type IPv6Mreq C.struct_ipv6_mreq - -type Msghdr C.struct_msghdr - -type Cmsghdr C.struct_cmsghdr - -type Inet6Pktinfo C.struct_in6_pktinfo - -type IPv6MTUInfo C.struct_ip6_mtuinfo - -type ICMPv6Filter C.struct_icmp6_filter - -const ( - SizeofSockaddrInet4 = C.sizeof_struct_sockaddr_in - SizeofSockaddrInet6 = C.sizeof_struct_sockaddr_in6 - SizeofSockaddrAny = C.sizeof_struct_sockaddr_any - SizeofSockaddrUnix = C.sizeof_struct_sockaddr_un - SizeofSockaddrDatalink = C.sizeof_struct_sockaddr_dl - SizeofLinger = C.sizeof_struct_linger - SizeofIPMreq = C.sizeof_struct_ip_mreq - SizeofIPv6Mreq = C.sizeof_struct_ipv6_mreq - SizeofMsghdr = C.sizeof_struct_msghdr - SizeofCmsghdr = C.sizeof_struct_cmsghdr - SizeofInet6Pktinfo = C.sizeof_struct_in6_pktinfo - SizeofIPv6MTUInfo = C.sizeof_struct_ip6_mtuinfo - SizeofICMPv6Filter = C.sizeof_struct_icmp6_filter -) - -// Ptrace requests - -const ( - PTRACE_TRACEME = C.PT_TRACE_ME - PTRACE_CONT = C.PT_CONTINUE - PTRACE_KILL = C.PT_KILL -) - -// Events (kqueue, kevent) - -type Kevent_t C.struct_kevent - -// Select - -type FdSet C.fd_set - -// Routing and interface messages - -const ( - SizeofIfMsghdr = C.sizeof_struct_if_msghdr - SizeofIfData = C.sizeof_struct_if_data - SizeofIfaMsghdr = C.sizeof_struct_ifa_msghdr - SizeofIfmaMsghdr = C.sizeof_struct_ifma_msghdr - SizeofIfAnnounceMsghdr = C.sizeof_struct_if_announcemsghdr - SizeofRtMsghdr = C.sizeof_struct_rt_msghdr - SizeofRtMetrics = C.sizeof_struct_rt_metrics -) - -type IfMsghdr C.struct_if_msghdr - -type IfData C.struct_if_data - -type IfaMsghdr C.struct_ifa_msghdr - -type IfmaMsghdr C.struct_ifma_msghdr - -type IfAnnounceMsghdr C.struct_if_announcemsghdr - -type RtMsghdr C.struct_rt_msghdr - -type RtMetrics C.struct_rt_metrics - -// Berkeley packet filter - -const ( - SizeofBpfVersion = C.sizeof_struct_bpf_version - SizeofBpfStat = C.sizeof_struct_bpf_stat - SizeofBpfProgram = C.sizeof_struct_bpf_program - SizeofBpfInsn = C.sizeof_struct_bpf_insn - SizeofBpfHdr = C.sizeof_struct_bpf_hdr -) - -type BpfVersion C.struct_bpf_version - -type BpfStat C.struct_bpf_stat - -type BpfProgram C.struct_bpf_program - -type BpfInsn C.struct_bpf_insn - -type BpfHdr C.struct_bpf_hdr - -// Terminal handling - -type Termios C.struct_termios diff --git a/components/cli/vendor/golang.org/x/sys/unix/types_freebsd.go b/components/cli/vendor/golang.org/x/sys/unix/types_freebsd.go deleted file mode 100644 index ae24557ad1..0000000000 --- a/components/cli/vendor/golang.org/x/sys/unix/types_freebsd.go +++ /dev/null @@ -1,353 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build ignore - -/* -Input to cgo -godefs. See also mkerrors.sh and mkall.sh -*/ - -// +godefs map struct_in_addr [4]byte /* in_addr */ -// +godefs map struct_in6_addr [16]byte /* in6_addr */ - -package unix - -/* -#define KERNEL -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -enum { - sizeofPtr = sizeof(void*), -}; - -union sockaddr_all { - struct sockaddr s1; // this one gets used for fields - struct sockaddr_in s2; // these pad it out - struct sockaddr_in6 s3; - struct sockaddr_un s4; - struct sockaddr_dl s5; -}; - -struct sockaddr_any { - struct sockaddr addr; - char pad[sizeof(union sockaddr_all) - sizeof(struct sockaddr)]; -}; - -// This structure is a duplicate of stat on FreeBSD 8-STABLE. -// See /usr/include/sys/stat.h. -struct stat8 { -#undef st_atimespec st_atim -#undef st_mtimespec st_mtim -#undef st_ctimespec st_ctim -#undef st_birthtimespec st_birthtim - __dev_t st_dev; - ino_t st_ino; - mode_t st_mode; - nlink_t st_nlink; - uid_t st_uid; - gid_t st_gid; - __dev_t st_rdev; -#if __BSD_VISIBLE - struct timespec st_atimespec; - struct timespec st_mtimespec; - struct timespec st_ctimespec; -#else - time_t st_atime; - long __st_atimensec; - time_t st_mtime; - long __st_mtimensec; - time_t st_ctime; - long __st_ctimensec; -#endif - off_t st_size; - blkcnt_t st_blocks; - blksize_t st_blksize; - fflags_t st_flags; - __uint32_t st_gen; - __int32_t st_lspare; -#if __BSD_VISIBLE - struct timespec st_birthtimespec; - unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec)); - unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec)); -#else - time_t st_birthtime; - long st_birthtimensec; - unsigned int :(8 / 2) * (16 - (int)sizeof(struct __timespec)); - unsigned int :(8 / 2) * (16 - (int)sizeof(struct __timespec)); -#endif -}; - -// This structure is a duplicate of if_data on FreeBSD 8-STABLE. -// See /usr/include/net/if.h. -struct if_data8 { - u_char ifi_type; - u_char ifi_physical; - u_char ifi_addrlen; - u_char ifi_hdrlen; - u_char ifi_link_state; - u_char ifi_spare_char1; - u_char ifi_spare_char2; - u_char ifi_datalen; - u_long ifi_mtu; - u_long ifi_metric; - u_long ifi_baudrate; - u_long ifi_ipackets; - u_long ifi_ierrors; - u_long ifi_opackets; - u_long ifi_oerrors; - u_long ifi_collisions; - u_long ifi_ibytes; - u_long ifi_obytes; - u_long ifi_imcasts; - u_long ifi_omcasts; - u_long ifi_iqdrops; - u_long ifi_noproto; - u_long ifi_hwassist; - time_t ifi_epoch; - struct timeval ifi_lastchange; -}; - -// This structure is a duplicate of if_msghdr on FreeBSD 8-STABLE. -// See /usr/include/net/if.h. -struct if_msghdr8 { - u_short ifm_msglen; - u_char ifm_version; - u_char ifm_type; - int ifm_addrs; - int ifm_flags; - u_short ifm_index; - struct if_data8 ifm_data; -}; -*/ -import "C" - -// Machine characteristics; for internal use. - -const ( - sizeofPtr = C.sizeofPtr - sizeofShort = C.sizeof_short - sizeofInt = C.sizeof_int - sizeofLong = C.sizeof_long - sizeofLongLong = C.sizeof_longlong -) - -// Basic types - -type ( - _C_short C.short - _C_int C.int - _C_long C.long - _C_long_long C.longlong -) - -// Time - -type Timespec C.struct_timespec - -type Timeval C.struct_timeval - -// Processes - -type Rusage C.struct_rusage - -type Rlimit C.struct_rlimit - -type _Gid_t C.gid_t - -// Files - -const ( // Directory mode bits - S_IFMT = C.S_IFMT - S_IFIFO = C.S_IFIFO - S_IFCHR = C.S_IFCHR - S_IFDIR = C.S_IFDIR - S_IFBLK = C.S_IFBLK - S_IFREG = C.S_IFREG - S_IFLNK = C.S_IFLNK - S_IFSOCK = C.S_IFSOCK - S_ISUID = C.S_ISUID - S_ISGID = C.S_ISGID - S_ISVTX = C.S_ISVTX - S_IRUSR = C.S_IRUSR - S_IWUSR = C.S_IWUSR - S_IXUSR = C.S_IXUSR -) - -type Stat_t C.struct_stat8 - -type Statfs_t C.struct_statfs - -type Flock_t C.struct_flock - -type Dirent C.struct_dirent - -type Fsid C.struct_fsid - -// Advice to Fadvise - -const ( - FADV_NORMAL = C.POSIX_FADV_NORMAL - FADV_RANDOM = C.POSIX_FADV_RANDOM - FADV_SEQUENTIAL = C.POSIX_FADV_SEQUENTIAL - FADV_WILLNEED = C.POSIX_FADV_WILLNEED - FADV_DONTNEED = C.POSIX_FADV_DONTNEED - FADV_NOREUSE = C.POSIX_FADV_NOREUSE -) - -// Sockets - -type RawSockaddrInet4 C.struct_sockaddr_in - -type RawSockaddrInet6 C.struct_sockaddr_in6 - -type RawSockaddrUnix C.struct_sockaddr_un - -type RawSockaddrDatalink C.struct_sockaddr_dl - -type RawSockaddr C.struct_sockaddr - -type RawSockaddrAny C.struct_sockaddr_any - -type _Socklen C.socklen_t - -type Linger C.struct_linger - -type Iovec C.struct_iovec - -type IPMreq C.struct_ip_mreq - -type IPMreqn C.struct_ip_mreqn - -type IPv6Mreq C.struct_ipv6_mreq - -type Msghdr C.struct_msghdr - -type Cmsghdr C.struct_cmsghdr - -type Inet6Pktinfo C.struct_in6_pktinfo - -type IPv6MTUInfo C.struct_ip6_mtuinfo - -type ICMPv6Filter C.struct_icmp6_filter - -const ( - SizeofSockaddrInet4 = C.sizeof_struct_sockaddr_in - SizeofSockaddrInet6 = C.sizeof_struct_sockaddr_in6 - SizeofSockaddrAny = C.sizeof_struct_sockaddr_any - SizeofSockaddrUnix = C.sizeof_struct_sockaddr_un - SizeofSockaddrDatalink = C.sizeof_struct_sockaddr_dl - SizeofLinger = C.sizeof_struct_linger - SizeofIPMreq = C.sizeof_struct_ip_mreq - SizeofIPMreqn = C.sizeof_struct_ip_mreqn - SizeofIPv6Mreq = C.sizeof_struct_ipv6_mreq - SizeofMsghdr = C.sizeof_struct_msghdr - SizeofCmsghdr = C.sizeof_struct_cmsghdr - SizeofInet6Pktinfo = C.sizeof_struct_in6_pktinfo - SizeofIPv6MTUInfo = C.sizeof_struct_ip6_mtuinfo - SizeofICMPv6Filter = C.sizeof_struct_icmp6_filter -) - -// Ptrace requests - -const ( - PTRACE_TRACEME = C.PT_TRACE_ME - PTRACE_CONT = C.PT_CONTINUE - PTRACE_KILL = C.PT_KILL -) - -// Events (kqueue, kevent) - -type Kevent_t C.struct_kevent - -// Select - -type FdSet C.fd_set - -// Routing and interface messages - -const ( - sizeofIfMsghdr = C.sizeof_struct_if_msghdr - SizeofIfMsghdr = C.sizeof_struct_if_msghdr8 - sizeofIfData = C.sizeof_struct_if_data - SizeofIfData = C.sizeof_struct_if_data8 - SizeofIfaMsghdr = C.sizeof_struct_ifa_msghdr - SizeofIfmaMsghdr = C.sizeof_struct_ifma_msghdr - SizeofIfAnnounceMsghdr = C.sizeof_struct_if_announcemsghdr - SizeofRtMsghdr = C.sizeof_struct_rt_msghdr - SizeofRtMetrics = C.sizeof_struct_rt_metrics -) - -type ifMsghdr C.struct_if_msghdr - -type IfMsghdr C.struct_if_msghdr8 - -type ifData C.struct_if_data - -type IfData C.struct_if_data8 - -type IfaMsghdr C.struct_ifa_msghdr - -type IfmaMsghdr C.struct_ifma_msghdr - -type IfAnnounceMsghdr C.struct_if_announcemsghdr - -type RtMsghdr C.struct_rt_msghdr - -type RtMetrics C.struct_rt_metrics - -// Berkeley packet filter - -const ( - SizeofBpfVersion = C.sizeof_struct_bpf_version - SizeofBpfStat = C.sizeof_struct_bpf_stat - SizeofBpfZbuf = C.sizeof_struct_bpf_zbuf - SizeofBpfProgram = C.sizeof_struct_bpf_program - SizeofBpfInsn = C.sizeof_struct_bpf_insn - SizeofBpfHdr = C.sizeof_struct_bpf_hdr - SizeofBpfZbufHeader = C.sizeof_struct_bpf_zbuf_header -) - -type BpfVersion C.struct_bpf_version - -type BpfStat C.struct_bpf_stat - -type BpfZbuf C.struct_bpf_zbuf - -type BpfProgram C.struct_bpf_program - -type BpfInsn C.struct_bpf_insn - -type BpfHdr C.struct_bpf_hdr - -type BpfZbufHeader C.struct_bpf_zbuf_header - -// Terminal handling - -type Termios C.struct_termios diff --git a/components/cli/vendor/golang.org/x/sys/unix/types_linux.go b/components/cli/vendor/golang.org/x/sys/unix/types_linux.go deleted file mode 100644 index 7dea79a8ef..0000000000 --- a/components/cli/vendor/golang.org/x/sys/unix/types_linux.go +++ /dev/null @@ -1,450 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build ignore - -/* -Input to cgo -godefs. See also mkerrors.sh and mkall.sh -*/ - -// +godefs map struct_in_addr [4]byte /* in_addr */ -// +godefs map struct_in6_addr [16]byte /* in6_addr */ - -package unix - -/* -#define _LARGEFILE_SOURCE -#define _LARGEFILE64_SOURCE -#define _FILE_OFFSET_BITS 64 -#define _GNU_SOURCE - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef TCSETS2 -// On systems that have "struct termios2" use this as type Termios. -typedef struct termios2 termios_t; -#else -typedef struct termios termios_t; -#endif - -enum { - sizeofPtr = sizeof(void*), -}; - -union sockaddr_all { - struct sockaddr s1; // this one gets used for fields - struct sockaddr_in s2; // these pad it out - struct sockaddr_in6 s3; - struct sockaddr_un s4; - struct sockaddr_ll s5; - struct sockaddr_nl s6; -}; - -struct sockaddr_any { - struct sockaddr addr; - char pad[sizeof(union sockaddr_all) - sizeof(struct sockaddr)]; -}; - -// copied from /usr/include/linux/un.h -struct my_sockaddr_un { - sa_family_t sun_family; -#if defined(__ARM_EABI__) || defined(__powerpc64__) - // on ARM char is by default unsigned - signed char sun_path[108]; -#else - char sun_path[108]; -#endif -}; - -#ifdef __ARM_EABI__ -typedef struct user_regs PtraceRegs; -#elif defined(__aarch64__) -typedef struct user_pt_regs PtraceRegs; -#elif defined(__powerpc64__) -typedef struct pt_regs PtraceRegs; -#elif defined(__mips__) -typedef struct user PtraceRegs; -#elif defined(__s390x__) -typedef struct _user_regs_struct PtraceRegs; -#else -typedef struct user_regs_struct PtraceRegs; -#endif - -#if defined(__s390x__) -typedef struct _user_psw_struct ptracePsw; -typedef struct _user_fpregs_struct ptraceFpregs; -typedef struct _user_per_struct ptracePer; -#else -typedef struct {} ptracePsw; -typedef struct {} ptraceFpregs; -typedef struct {} ptracePer; -#endif - -// The real epoll_event is a union, and godefs doesn't handle it well. -struct my_epoll_event { - uint32_t events; -#if defined(__ARM_EABI__) || defined(__aarch64__) - // padding is not specified in linux/eventpoll.h but added to conform to the - // alignment requirements of EABI - int32_t padFd; -#elif defined(__powerpc64__) || defined(__s390x__) - int32_t _padFd; -#endif - int32_t fd; - int32_t pad; -}; - -*/ -import "C" - -// Machine characteristics; for internal use. - -const ( - sizeofPtr = C.sizeofPtr - sizeofShort = C.sizeof_short - sizeofInt = C.sizeof_int - sizeofLong = C.sizeof_long - sizeofLongLong = C.sizeof_longlong - PathMax = C.PATH_MAX -) - -// Basic types - -type ( - _C_short C.short - _C_int C.int - _C_long C.long - _C_long_long C.longlong -) - -// Time - -type Timespec C.struct_timespec - -type Timeval C.struct_timeval - -type Timex C.struct_timex - -type Time_t C.time_t - -type Tms C.struct_tms - -type Utimbuf C.struct_utimbuf - -// Processes - -type Rusage C.struct_rusage - -type Rlimit C.struct_rlimit - -type _Gid_t C.gid_t - -// Files - -type Stat_t C.struct_stat - -type Statfs_t C.struct_statfs - -type Dirent C.struct_dirent - -type Fsid C.fsid_t - -type Flock_t C.struct_flock - -// Advice to Fadvise - -const ( - FADV_NORMAL = C.POSIX_FADV_NORMAL - FADV_RANDOM = C.POSIX_FADV_RANDOM - FADV_SEQUENTIAL = C.POSIX_FADV_SEQUENTIAL - FADV_WILLNEED = C.POSIX_FADV_WILLNEED - FADV_DONTNEED = C.POSIX_FADV_DONTNEED - FADV_NOREUSE = C.POSIX_FADV_NOREUSE -) - -// Sockets - -type RawSockaddrInet4 C.struct_sockaddr_in - -type RawSockaddrInet6 C.struct_sockaddr_in6 - -type RawSockaddrUnix C.struct_my_sockaddr_un - -type RawSockaddrLinklayer C.struct_sockaddr_ll - -type RawSockaddrNetlink C.struct_sockaddr_nl - -type RawSockaddrHCI C.struct_sockaddr_hci - -type RawSockaddr C.struct_sockaddr - -type RawSockaddrAny C.struct_sockaddr_any - -type _Socklen C.socklen_t - -type Linger C.struct_linger - -type Iovec C.struct_iovec - -type IPMreq C.struct_ip_mreq - -type IPMreqn C.struct_ip_mreqn - -type IPv6Mreq C.struct_ipv6_mreq - -type Msghdr C.struct_msghdr - -type Cmsghdr C.struct_cmsghdr - -type Inet4Pktinfo C.struct_in_pktinfo - -type Inet6Pktinfo C.struct_in6_pktinfo - -type IPv6MTUInfo C.struct_ip6_mtuinfo - -type ICMPv6Filter C.struct_icmp6_filter - -type Ucred C.struct_ucred - -type TCPInfo C.struct_tcp_info - -const ( - SizeofSockaddrInet4 = C.sizeof_struct_sockaddr_in - SizeofSockaddrInet6 = C.sizeof_struct_sockaddr_in6 - SizeofSockaddrAny = C.sizeof_struct_sockaddr_any - SizeofSockaddrUnix = C.sizeof_struct_sockaddr_un - SizeofSockaddrLinklayer = C.sizeof_struct_sockaddr_ll - SizeofSockaddrNetlink = C.sizeof_struct_sockaddr_nl - SizeofSockaddrHCI = C.sizeof_struct_sockaddr_hci - SizeofLinger = C.sizeof_struct_linger - SizeofIPMreq = C.sizeof_struct_ip_mreq - SizeofIPMreqn = C.sizeof_struct_ip_mreqn - SizeofIPv6Mreq = C.sizeof_struct_ipv6_mreq - SizeofMsghdr = C.sizeof_struct_msghdr - SizeofCmsghdr = C.sizeof_struct_cmsghdr - SizeofInet4Pktinfo = C.sizeof_struct_in_pktinfo - SizeofInet6Pktinfo = C.sizeof_struct_in6_pktinfo - SizeofIPv6MTUInfo = C.sizeof_struct_ip6_mtuinfo - SizeofICMPv6Filter = C.sizeof_struct_icmp6_filter - SizeofUcred = C.sizeof_struct_ucred - SizeofTCPInfo = C.sizeof_struct_tcp_info -) - -// Netlink routing and interface messages - -const ( - IFA_UNSPEC = C.IFA_UNSPEC - IFA_ADDRESS = C.IFA_ADDRESS - IFA_LOCAL = C.IFA_LOCAL - IFA_LABEL = C.IFA_LABEL - IFA_BROADCAST = C.IFA_BROADCAST - IFA_ANYCAST = C.IFA_ANYCAST - IFA_CACHEINFO = C.IFA_CACHEINFO - IFA_MULTICAST = C.IFA_MULTICAST - IFLA_UNSPEC = C.IFLA_UNSPEC - IFLA_ADDRESS = C.IFLA_ADDRESS - IFLA_BROADCAST = C.IFLA_BROADCAST - IFLA_IFNAME = C.IFLA_IFNAME - IFLA_MTU = C.IFLA_MTU - IFLA_LINK = C.IFLA_LINK - IFLA_QDISC = C.IFLA_QDISC - IFLA_STATS = C.IFLA_STATS - IFLA_COST = C.IFLA_COST - IFLA_PRIORITY = C.IFLA_PRIORITY - IFLA_MASTER = C.IFLA_MASTER - IFLA_WIRELESS = C.IFLA_WIRELESS - IFLA_PROTINFO = C.IFLA_PROTINFO - IFLA_TXQLEN = C.IFLA_TXQLEN - IFLA_MAP = C.IFLA_MAP - IFLA_WEIGHT = C.IFLA_WEIGHT - IFLA_OPERSTATE = C.IFLA_OPERSTATE - IFLA_LINKMODE = C.IFLA_LINKMODE - IFLA_LINKINFO = C.IFLA_LINKINFO - IFLA_NET_NS_PID = C.IFLA_NET_NS_PID - IFLA_IFALIAS = C.IFLA_IFALIAS - IFLA_MAX = C.IFLA_MAX - RT_SCOPE_UNIVERSE = C.RT_SCOPE_UNIVERSE - RT_SCOPE_SITE = C.RT_SCOPE_SITE - RT_SCOPE_LINK = C.RT_SCOPE_LINK - RT_SCOPE_HOST = C.RT_SCOPE_HOST - RT_SCOPE_NOWHERE = C.RT_SCOPE_NOWHERE - RT_TABLE_UNSPEC = C.RT_TABLE_UNSPEC - RT_TABLE_COMPAT = C.RT_TABLE_COMPAT - RT_TABLE_DEFAULT = C.RT_TABLE_DEFAULT - RT_TABLE_MAIN = C.RT_TABLE_MAIN - RT_TABLE_LOCAL = C.RT_TABLE_LOCAL - RT_TABLE_MAX = C.RT_TABLE_MAX - RTA_UNSPEC = C.RTA_UNSPEC - RTA_DST = C.RTA_DST - RTA_SRC = C.RTA_SRC - RTA_IIF = C.RTA_IIF - RTA_OIF = C.RTA_OIF - RTA_GATEWAY = C.RTA_GATEWAY - RTA_PRIORITY = C.RTA_PRIORITY - RTA_PREFSRC = C.RTA_PREFSRC - RTA_METRICS = C.RTA_METRICS - RTA_MULTIPATH = C.RTA_MULTIPATH - RTA_FLOW = C.RTA_FLOW - RTA_CACHEINFO = C.RTA_CACHEINFO - RTA_TABLE = C.RTA_TABLE - RTN_UNSPEC = C.RTN_UNSPEC - RTN_UNICAST = C.RTN_UNICAST - RTN_LOCAL = C.RTN_LOCAL - RTN_BROADCAST = C.RTN_BROADCAST - RTN_ANYCAST = C.RTN_ANYCAST - RTN_MULTICAST = C.RTN_MULTICAST - RTN_BLACKHOLE = C.RTN_BLACKHOLE - RTN_UNREACHABLE = C.RTN_UNREACHABLE - RTN_PROHIBIT = C.RTN_PROHIBIT - RTN_THROW = C.RTN_THROW - RTN_NAT = C.RTN_NAT - RTN_XRESOLVE = C.RTN_XRESOLVE - RTNLGRP_NONE = C.RTNLGRP_NONE - RTNLGRP_LINK = C.RTNLGRP_LINK - RTNLGRP_NOTIFY = C.RTNLGRP_NOTIFY - RTNLGRP_NEIGH = C.RTNLGRP_NEIGH - RTNLGRP_TC = C.RTNLGRP_TC - RTNLGRP_IPV4_IFADDR = C.RTNLGRP_IPV4_IFADDR - RTNLGRP_IPV4_MROUTE = C.RTNLGRP_IPV4_MROUTE - RTNLGRP_IPV4_ROUTE = C.RTNLGRP_IPV4_ROUTE - RTNLGRP_IPV4_RULE = C.RTNLGRP_IPV4_RULE - RTNLGRP_IPV6_IFADDR = C.RTNLGRP_IPV6_IFADDR - RTNLGRP_IPV6_MROUTE = C.RTNLGRP_IPV6_MROUTE - RTNLGRP_IPV6_ROUTE = C.RTNLGRP_IPV6_ROUTE - RTNLGRP_IPV6_IFINFO = C.RTNLGRP_IPV6_IFINFO - RTNLGRP_IPV6_PREFIX = C.RTNLGRP_IPV6_PREFIX - RTNLGRP_IPV6_RULE = C.RTNLGRP_IPV6_RULE - RTNLGRP_ND_USEROPT = C.RTNLGRP_ND_USEROPT - SizeofNlMsghdr = C.sizeof_struct_nlmsghdr - SizeofNlMsgerr = C.sizeof_struct_nlmsgerr - SizeofRtGenmsg = C.sizeof_struct_rtgenmsg - SizeofNlAttr = C.sizeof_struct_nlattr - SizeofRtAttr = C.sizeof_struct_rtattr - SizeofIfInfomsg = C.sizeof_struct_ifinfomsg - SizeofIfAddrmsg = C.sizeof_struct_ifaddrmsg - SizeofRtMsg = C.sizeof_struct_rtmsg - SizeofRtNexthop = C.sizeof_struct_rtnexthop -) - -type NlMsghdr C.struct_nlmsghdr - -type NlMsgerr C.struct_nlmsgerr - -type RtGenmsg C.struct_rtgenmsg - -type NlAttr C.struct_nlattr - -type RtAttr C.struct_rtattr - -type IfInfomsg C.struct_ifinfomsg - -type IfAddrmsg C.struct_ifaddrmsg - -type RtMsg C.struct_rtmsg - -type RtNexthop C.struct_rtnexthop - -// Linux socket filter - -const ( - SizeofSockFilter = C.sizeof_struct_sock_filter - SizeofSockFprog = C.sizeof_struct_sock_fprog -) - -type SockFilter C.struct_sock_filter - -type SockFprog C.struct_sock_fprog - -// Inotify - -type InotifyEvent C.struct_inotify_event - -const SizeofInotifyEvent = C.sizeof_struct_inotify_event - -// Ptrace - -// Register structures -type PtraceRegs C.PtraceRegs - -// Structures contained in PtraceRegs on s390x (exported by mkpost.go) -type ptracePsw C.ptracePsw - -type ptraceFpregs C.ptraceFpregs - -type ptracePer C.ptracePer - -// Misc - -type FdSet C.fd_set - -type Sysinfo_t C.struct_sysinfo - -type Utsname C.struct_utsname - -type Ustat_t C.struct_ustat - -type EpollEvent C.struct_my_epoll_event - -const ( - AT_FDCWD = C.AT_FDCWD - AT_REMOVEDIR = C.AT_REMOVEDIR - AT_SYMLINK_FOLLOW = C.AT_SYMLINK_FOLLOW - AT_SYMLINK_NOFOLLOW = C.AT_SYMLINK_NOFOLLOW -) - -type PollFd C.struct_pollfd - -const ( - POLLIN = C.POLLIN - POLLPRI = C.POLLPRI - POLLOUT = C.POLLOUT - POLLRDHUP = C.POLLRDHUP - POLLERR = C.POLLERR - POLLHUP = C.POLLHUP - POLLNVAL = C.POLLNVAL -) - -type Sigset_t C.sigset_t - -// Terminal handling - -type Termios C.termios_t diff --git a/components/cli/vendor/golang.org/x/sys/unix/types_netbsd.go b/components/cli/vendor/golang.org/x/sys/unix/types_netbsd.go deleted file mode 100644 index d15f93d192..0000000000 --- a/components/cli/vendor/golang.org/x/sys/unix/types_netbsd.go +++ /dev/null @@ -1,232 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build ignore - -/* -Input to cgo -godefs. See also mkerrors.sh and mkall.sh -*/ - -// +godefs map struct_in_addr [4]byte /* in_addr */ -// +godefs map struct_in6_addr [16]byte /* in6_addr */ - -package unix - -/* -#define KERNEL -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -enum { - sizeofPtr = sizeof(void*), -}; - -union sockaddr_all { - struct sockaddr s1; // this one gets used for fields - struct sockaddr_in s2; // these pad it out - struct sockaddr_in6 s3; - struct sockaddr_un s4; - struct sockaddr_dl s5; -}; - -struct sockaddr_any { - struct sockaddr addr; - char pad[sizeof(union sockaddr_all) - sizeof(struct sockaddr)]; -}; - -*/ -import "C" - -// Machine characteristics; for internal use. - -const ( - sizeofPtr = C.sizeofPtr - sizeofShort = C.sizeof_short - sizeofInt = C.sizeof_int - sizeofLong = C.sizeof_long - sizeofLongLong = C.sizeof_longlong -) - -// Basic types - -type ( - _C_short C.short - _C_int C.int - _C_long C.long - _C_long_long C.longlong -) - -// Time - -type Timespec C.struct_timespec - -type Timeval C.struct_timeval - -// Processes - -type Rusage C.struct_rusage - -type Rlimit C.struct_rlimit - -type _Gid_t C.gid_t - -// Files - -type Stat_t C.struct_stat - -type Statfs_t C.struct_statfs - -type Flock_t C.struct_flock - -type Dirent C.struct_dirent - -type Fsid C.fsid_t - -// Sockets - -type RawSockaddrInet4 C.struct_sockaddr_in - -type RawSockaddrInet6 C.struct_sockaddr_in6 - -type RawSockaddrUnix C.struct_sockaddr_un - -type RawSockaddrDatalink C.struct_sockaddr_dl - -type RawSockaddr C.struct_sockaddr - -type RawSockaddrAny C.struct_sockaddr_any - -type _Socklen C.socklen_t - -type Linger C.struct_linger - -type Iovec C.struct_iovec - -type IPMreq C.struct_ip_mreq - -type IPv6Mreq C.struct_ipv6_mreq - -type Msghdr C.struct_msghdr - -type Cmsghdr C.struct_cmsghdr - -type Inet6Pktinfo C.struct_in6_pktinfo - -type IPv6MTUInfo C.struct_ip6_mtuinfo - -type ICMPv6Filter C.struct_icmp6_filter - -const ( - SizeofSockaddrInet4 = C.sizeof_struct_sockaddr_in - SizeofSockaddrInet6 = C.sizeof_struct_sockaddr_in6 - SizeofSockaddrAny = C.sizeof_struct_sockaddr_any - SizeofSockaddrUnix = C.sizeof_struct_sockaddr_un - SizeofSockaddrDatalink = C.sizeof_struct_sockaddr_dl - SizeofLinger = C.sizeof_struct_linger - SizeofIPMreq = C.sizeof_struct_ip_mreq - SizeofIPv6Mreq = C.sizeof_struct_ipv6_mreq - SizeofMsghdr = C.sizeof_struct_msghdr - SizeofCmsghdr = C.sizeof_struct_cmsghdr - SizeofInet6Pktinfo = C.sizeof_struct_in6_pktinfo - SizeofIPv6MTUInfo = C.sizeof_struct_ip6_mtuinfo - SizeofICMPv6Filter = C.sizeof_struct_icmp6_filter -) - -// Ptrace requests - -const ( - PTRACE_TRACEME = C.PT_TRACE_ME - PTRACE_CONT = C.PT_CONTINUE - PTRACE_KILL = C.PT_KILL -) - -// Events (kqueue, kevent) - -type Kevent_t C.struct_kevent - -// Select - -type FdSet C.fd_set - -// Routing and interface messages - -const ( - SizeofIfMsghdr = C.sizeof_struct_if_msghdr - SizeofIfData = C.sizeof_struct_if_data - SizeofIfaMsghdr = C.sizeof_struct_ifa_msghdr - SizeofIfAnnounceMsghdr = C.sizeof_struct_if_announcemsghdr - SizeofRtMsghdr = C.sizeof_struct_rt_msghdr - SizeofRtMetrics = C.sizeof_struct_rt_metrics -) - -type IfMsghdr C.struct_if_msghdr - -type IfData C.struct_if_data - -type IfaMsghdr C.struct_ifa_msghdr - -type IfAnnounceMsghdr C.struct_if_announcemsghdr - -type RtMsghdr C.struct_rt_msghdr - -type RtMetrics C.struct_rt_metrics - -type Mclpool C.struct_mclpool - -// Berkeley packet filter - -const ( - SizeofBpfVersion = C.sizeof_struct_bpf_version - SizeofBpfStat = C.sizeof_struct_bpf_stat - SizeofBpfProgram = C.sizeof_struct_bpf_program - SizeofBpfInsn = C.sizeof_struct_bpf_insn - SizeofBpfHdr = C.sizeof_struct_bpf_hdr -) - -type BpfVersion C.struct_bpf_version - -type BpfStat C.struct_bpf_stat - -type BpfProgram C.struct_bpf_program - -type BpfInsn C.struct_bpf_insn - -type BpfHdr C.struct_bpf_hdr - -type BpfTimeval C.struct_bpf_timeval - -// Terminal handling - -type Termios C.struct_termios - -// Sysctl - -type Sysctlnode C.struct_sysctlnode diff --git a/components/cli/vendor/golang.org/x/sys/unix/types_openbsd.go b/components/cli/vendor/golang.org/x/sys/unix/types_openbsd.go deleted file mode 100644 index b66fe25f73..0000000000 --- a/components/cli/vendor/golang.org/x/sys/unix/types_openbsd.go +++ /dev/null @@ -1,244 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build ignore - -/* -Input to cgo -godefs. See also mkerrors.sh and mkall.sh -*/ - -// +godefs map struct_in_addr [4]byte /* in_addr */ -// +godefs map struct_in6_addr [16]byte /* in6_addr */ - -package unix - -/* -#define KERNEL -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -enum { - sizeofPtr = sizeof(void*), -}; - -union sockaddr_all { - struct sockaddr s1; // this one gets used for fields - struct sockaddr_in s2; // these pad it out - struct sockaddr_in6 s3; - struct sockaddr_un s4; - struct sockaddr_dl s5; -}; - -struct sockaddr_any { - struct sockaddr addr; - char pad[sizeof(union sockaddr_all) - sizeof(struct sockaddr)]; -}; - -*/ -import "C" - -// Machine characteristics; for internal use. - -const ( - sizeofPtr = C.sizeofPtr - sizeofShort = C.sizeof_short - sizeofInt = C.sizeof_int - sizeofLong = C.sizeof_long - sizeofLongLong = C.sizeof_longlong -) - -// Basic types - -type ( - _C_short C.short - _C_int C.int - _C_long C.long - _C_long_long C.longlong -) - -// Time - -type Timespec C.struct_timespec - -type Timeval C.struct_timeval - -// Processes - -type Rusage C.struct_rusage - -type Rlimit C.struct_rlimit - -type _Gid_t C.gid_t - -// Files - -const ( // Directory mode bits - S_IFMT = C.S_IFMT - S_IFIFO = C.S_IFIFO - S_IFCHR = C.S_IFCHR - S_IFDIR = C.S_IFDIR - S_IFBLK = C.S_IFBLK - S_IFREG = C.S_IFREG - S_IFLNK = C.S_IFLNK - S_IFSOCK = C.S_IFSOCK - S_ISUID = C.S_ISUID - S_ISGID = C.S_ISGID - S_ISVTX = C.S_ISVTX - S_IRUSR = C.S_IRUSR - S_IWUSR = C.S_IWUSR - S_IXUSR = C.S_IXUSR -) - -type Stat_t C.struct_stat - -type Statfs_t C.struct_statfs - -type Flock_t C.struct_flock - -type Dirent C.struct_dirent - -type Fsid C.fsid_t - -// Sockets - -type RawSockaddrInet4 C.struct_sockaddr_in - -type RawSockaddrInet6 C.struct_sockaddr_in6 - -type RawSockaddrUnix C.struct_sockaddr_un - -type RawSockaddrDatalink C.struct_sockaddr_dl - -type RawSockaddr C.struct_sockaddr - -type RawSockaddrAny C.struct_sockaddr_any - -type _Socklen C.socklen_t - -type Linger C.struct_linger - -type Iovec C.struct_iovec - -type IPMreq C.struct_ip_mreq - -type IPv6Mreq C.struct_ipv6_mreq - -type Msghdr C.struct_msghdr - -type Cmsghdr C.struct_cmsghdr - -type Inet6Pktinfo C.struct_in6_pktinfo - -type IPv6MTUInfo C.struct_ip6_mtuinfo - -type ICMPv6Filter C.struct_icmp6_filter - -const ( - SizeofSockaddrInet4 = C.sizeof_struct_sockaddr_in - SizeofSockaddrInet6 = C.sizeof_struct_sockaddr_in6 - SizeofSockaddrAny = C.sizeof_struct_sockaddr_any - SizeofSockaddrUnix = C.sizeof_struct_sockaddr_un - SizeofSockaddrDatalink = C.sizeof_struct_sockaddr_dl - SizeofLinger = C.sizeof_struct_linger - SizeofIPMreq = C.sizeof_struct_ip_mreq - SizeofIPv6Mreq = C.sizeof_struct_ipv6_mreq - SizeofMsghdr = C.sizeof_struct_msghdr - SizeofCmsghdr = C.sizeof_struct_cmsghdr - SizeofInet6Pktinfo = C.sizeof_struct_in6_pktinfo - SizeofIPv6MTUInfo = C.sizeof_struct_ip6_mtuinfo - SizeofICMPv6Filter = C.sizeof_struct_icmp6_filter -) - -// Ptrace requests - -const ( - PTRACE_TRACEME = C.PT_TRACE_ME - PTRACE_CONT = C.PT_CONTINUE - PTRACE_KILL = C.PT_KILL -) - -// Events (kqueue, kevent) - -type Kevent_t C.struct_kevent - -// Select - -type FdSet C.fd_set - -// Routing and interface messages - -const ( - SizeofIfMsghdr = C.sizeof_struct_if_msghdr - SizeofIfData = C.sizeof_struct_if_data - SizeofIfaMsghdr = C.sizeof_struct_ifa_msghdr - SizeofIfAnnounceMsghdr = C.sizeof_struct_if_announcemsghdr - SizeofRtMsghdr = C.sizeof_struct_rt_msghdr - SizeofRtMetrics = C.sizeof_struct_rt_metrics -) - -type IfMsghdr C.struct_if_msghdr - -type IfData C.struct_if_data - -type IfaMsghdr C.struct_ifa_msghdr - -type IfAnnounceMsghdr C.struct_if_announcemsghdr - -type RtMsghdr C.struct_rt_msghdr - -type RtMetrics C.struct_rt_metrics - -type Mclpool C.struct_mclpool - -// Berkeley packet filter - -const ( - SizeofBpfVersion = C.sizeof_struct_bpf_version - SizeofBpfStat = C.sizeof_struct_bpf_stat - SizeofBpfProgram = C.sizeof_struct_bpf_program - SizeofBpfInsn = C.sizeof_struct_bpf_insn - SizeofBpfHdr = C.sizeof_struct_bpf_hdr -) - -type BpfVersion C.struct_bpf_version - -type BpfStat C.struct_bpf_stat - -type BpfProgram C.struct_bpf_program - -type BpfInsn C.struct_bpf_insn - -type BpfHdr C.struct_bpf_hdr - -type BpfTimeval C.struct_bpf_timeval - -// Terminal handling - -type Termios C.struct_termios diff --git a/components/cli/vendor/golang.org/x/sys/unix/types_solaris.go b/components/cli/vendor/golang.org/x/sys/unix/types_solaris.go deleted file mode 100644 index c5d5c8f16a..0000000000 --- a/components/cli/vendor/golang.org/x/sys/unix/types_solaris.go +++ /dev/null @@ -1,262 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build ignore - -/* -Input to cgo -godefs. See also mkerrors.sh and mkall.sh -*/ - -// +godefs map struct_in_addr [4]byte /* in_addr */ -// +godefs map struct_in6_addr [16]byte /* in6_addr */ - -package unix - -/* -#define KERNEL -// These defines ensure that builds done on newer versions of Solaris are -// backwards-compatible with older versions of Solaris and -// OpenSolaris-based derivatives. -#define __USE_SUNOS_SOCKETS__ // msghdr -#define __USE_LEGACY_PROTOTYPES__ // iovec -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -enum { - sizeofPtr = sizeof(void*), -}; - -union sockaddr_all { - struct sockaddr s1; // this one gets used for fields - struct sockaddr_in s2; // these pad it out - struct sockaddr_in6 s3; - struct sockaddr_un s4; - struct sockaddr_dl s5; -}; - -struct sockaddr_any { - struct sockaddr addr; - char pad[sizeof(union sockaddr_all) - sizeof(struct sockaddr)]; -}; - -*/ -import "C" - -// Machine characteristics; for internal use. - -const ( - sizeofPtr = C.sizeofPtr - sizeofShort = C.sizeof_short - sizeofInt = C.sizeof_int - sizeofLong = C.sizeof_long - sizeofLongLong = C.sizeof_longlong - PathMax = C.PATH_MAX - MaxHostNameLen = C.MAXHOSTNAMELEN -) - -// Basic types - -type ( - _C_short C.short - _C_int C.int - _C_long C.long - _C_long_long C.longlong -) - -// Time - -type Timespec C.struct_timespec - -type Timeval C.struct_timeval - -type Timeval32 C.struct_timeval32 - -type Tms C.struct_tms - -type Utimbuf C.struct_utimbuf - -// Processes - -type Rusage C.struct_rusage - -type Rlimit C.struct_rlimit - -type _Gid_t C.gid_t - -// Files - -const ( // Directory mode bits - S_IFMT = C.S_IFMT - S_IFIFO = C.S_IFIFO - S_IFCHR = C.S_IFCHR - S_IFDIR = C.S_IFDIR - S_IFBLK = C.S_IFBLK - S_IFREG = C.S_IFREG - S_IFLNK = C.S_IFLNK - S_IFSOCK = C.S_IFSOCK - S_ISUID = C.S_ISUID - S_ISGID = C.S_ISGID - S_ISVTX = C.S_ISVTX - S_IRUSR = C.S_IRUSR - S_IWUSR = C.S_IWUSR - S_IXUSR = C.S_IXUSR -) - -type Stat_t C.struct_stat - -type Flock_t C.struct_flock - -type Dirent C.struct_dirent - -// Sockets - -type RawSockaddrInet4 C.struct_sockaddr_in - -type RawSockaddrInet6 C.struct_sockaddr_in6 - -type RawSockaddrUnix C.struct_sockaddr_un - -type RawSockaddrDatalink C.struct_sockaddr_dl - -type RawSockaddr C.struct_sockaddr - -type RawSockaddrAny C.struct_sockaddr_any - -type _Socklen C.socklen_t - -type Linger C.struct_linger - -type Iovec C.struct_iovec - -type IPMreq C.struct_ip_mreq - -type IPv6Mreq C.struct_ipv6_mreq - -type Msghdr C.struct_msghdr - -type Cmsghdr C.struct_cmsghdr - -type Inet6Pktinfo C.struct_in6_pktinfo - -type IPv6MTUInfo C.struct_ip6_mtuinfo - -type ICMPv6Filter C.struct_icmp6_filter - -const ( - SizeofSockaddrInet4 = C.sizeof_struct_sockaddr_in - SizeofSockaddrInet6 = C.sizeof_struct_sockaddr_in6 - SizeofSockaddrAny = C.sizeof_struct_sockaddr_any - SizeofSockaddrUnix = C.sizeof_struct_sockaddr_un - SizeofSockaddrDatalink = C.sizeof_struct_sockaddr_dl - SizeofLinger = C.sizeof_struct_linger - SizeofIPMreq = C.sizeof_struct_ip_mreq - SizeofIPv6Mreq = C.sizeof_struct_ipv6_mreq - SizeofMsghdr = C.sizeof_struct_msghdr - SizeofCmsghdr = C.sizeof_struct_cmsghdr - SizeofInet6Pktinfo = C.sizeof_struct_in6_pktinfo - SizeofIPv6MTUInfo = C.sizeof_struct_ip6_mtuinfo - SizeofICMPv6Filter = C.sizeof_struct_icmp6_filter -) - -// Select - -type FdSet C.fd_set - -// Misc - -type Utsname C.struct_utsname - -type Ustat_t C.struct_ustat - -const ( - AT_FDCWD = C.AT_FDCWD - AT_SYMLINK_NOFOLLOW = C.AT_SYMLINK_NOFOLLOW - AT_SYMLINK_FOLLOW = C.AT_SYMLINK_FOLLOW - AT_REMOVEDIR = C.AT_REMOVEDIR - AT_EACCESS = C.AT_EACCESS -) - -// Routing and interface messages - -const ( - SizeofIfMsghdr = C.sizeof_struct_if_msghdr - SizeofIfData = C.sizeof_struct_if_data - SizeofIfaMsghdr = C.sizeof_struct_ifa_msghdr - SizeofRtMsghdr = C.sizeof_struct_rt_msghdr - SizeofRtMetrics = C.sizeof_struct_rt_metrics -) - -type IfMsghdr C.struct_if_msghdr - -type IfData C.struct_if_data - -type IfaMsghdr C.struct_ifa_msghdr - -type RtMsghdr C.struct_rt_msghdr - -type RtMetrics C.struct_rt_metrics - -// Berkeley packet filter - -const ( - SizeofBpfVersion = C.sizeof_struct_bpf_version - SizeofBpfStat = C.sizeof_struct_bpf_stat - SizeofBpfProgram = C.sizeof_struct_bpf_program - SizeofBpfInsn = C.sizeof_struct_bpf_insn - SizeofBpfHdr = C.sizeof_struct_bpf_hdr -) - -type BpfVersion C.struct_bpf_version - -type BpfStat C.struct_bpf_stat - -type BpfProgram C.struct_bpf_program - -type BpfInsn C.struct_bpf_insn - -type BpfTimeval C.struct_bpf_timeval - -type BpfHdr C.struct_bpf_hdr - -// sysconf information - -const _SC_PAGESIZE = C._SC_PAGESIZE - -// Terminal handling - -type Termios C.struct_termios - -type Termio C.struct_termio - -type Winsize C.struct_winsize diff --git a/components/cli/vendor/golang.org/x/text/internal/gen/code.go b/components/cli/vendor/golang.org/x/text/internal/gen/code.go deleted file mode 100644 index d7031b6945..0000000000 --- a/components/cli/vendor/golang.org/x/text/internal/gen/code.go +++ /dev/null @@ -1,351 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package gen - -import ( - "bytes" - "encoding/gob" - "fmt" - "hash" - "hash/fnv" - "io" - "log" - "os" - "reflect" - "strings" - "unicode" - "unicode/utf8" -) - -// This file contains utilities for generating code. - -// TODO: other write methods like: -// - slices, maps, types, etc. - -// CodeWriter is a utility for writing structured code. It computes the content -// hash and size of written content. It ensures there are newlines between -// written code blocks. -type CodeWriter struct { - buf bytes.Buffer - Size int - Hash hash.Hash32 // content hash - gob *gob.Encoder - // For comments we skip the usual one-line separator if they are followed by - // a code block. - skipSep bool -} - -func (w *CodeWriter) Write(p []byte) (n int, err error) { - return w.buf.Write(p) -} - -// NewCodeWriter returns a new CodeWriter. -func NewCodeWriter() *CodeWriter { - h := fnv.New32() - return &CodeWriter{Hash: h, gob: gob.NewEncoder(h)} -} - -// WriteGoFile appends the buffer with the total size of all created structures -// and writes it as a Go file to the the given file with the given package name. -func (w *CodeWriter) WriteGoFile(filename, pkg string) { - f, err := os.Create(filename) - if err != nil { - log.Fatalf("Could not create file %s: %v", filename, err) - } - defer f.Close() - if _, err = w.WriteGo(f, pkg); err != nil { - log.Fatalf("Error writing file %s: %v", filename, err) - } -} - -// WriteGo appends the buffer with the total size of all created structures and -// writes it as a Go file to the the given writer with the given package name. -func (w *CodeWriter) WriteGo(out io.Writer, pkg string) (n int, err error) { - sz := w.Size - w.WriteComment("Total table size %d bytes (%dKiB); checksum: %X\n", sz, sz/1024, w.Hash.Sum32()) - defer w.buf.Reset() - return WriteGo(out, pkg, w.buf.Bytes()) -} - -func (w *CodeWriter) printf(f string, x ...interface{}) { - fmt.Fprintf(w, f, x...) -} - -func (w *CodeWriter) insertSep() { - if w.skipSep { - w.skipSep = false - return - } - // Use at least two newlines to ensure a blank space between the previous - // block. WriteGoFile will remove extraneous newlines. - w.printf("\n\n") -} - -// WriteComment writes a comment block. All line starts are prefixed with "//". -// Initial empty lines are gobbled. The indentation for the first line is -// stripped from consecutive lines. -func (w *CodeWriter) WriteComment(comment string, args ...interface{}) { - s := fmt.Sprintf(comment, args...) - s = strings.Trim(s, "\n") - - // Use at least two newlines to ensure a blank space between the previous - // block. WriteGoFile will remove extraneous newlines. - w.printf("\n\n// ") - w.skipSep = true - - // strip first indent level. - sep := "\n" - for ; len(s) > 0 && (s[0] == '\t' || s[0] == ' '); s = s[1:] { - sep += s[:1] - } - - strings.NewReplacer(sep, "\n// ", "\n", "\n// ").WriteString(w, s) - - w.printf("\n") -} - -func (w *CodeWriter) writeSizeInfo(size int) { - w.printf("// Size: %d bytes\n", size) -} - -// WriteConst writes a constant of the given name and value. -func (w *CodeWriter) WriteConst(name string, x interface{}) { - w.insertSep() - v := reflect.ValueOf(x) - - switch v.Type().Kind() { - case reflect.String: - w.printf("const %s %s = ", name, typeName(x)) - w.WriteString(v.String()) - w.printf("\n") - default: - w.printf("const %s = %#v\n", name, x) - } -} - -// WriteVar writes a variable of the given name and value. -func (w *CodeWriter) WriteVar(name string, x interface{}) { - w.insertSep() - v := reflect.ValueOf(x) - oldSize := w.Size - sz := int(v.Type().Size()) - w.Size += sz - - switch v.Type().Kind() { - case reflect.String: - w.printf("var %s %s = ", name, typeName(x)) - w.WriteString(v.String()) - case reflect.Struct: - w.gob.Encode(x) - fallthrough - case reflect.Slice, reflect.Array: - w.printf("var %s = ", name) - w.writeValue(v) - w.writeSizeInfo(w.Size - oldSize) - default: - w.printf("var %s %s = ", name, typeName(x)) - w.gob.Encode(x) - w.writeValue(v) - w.writeSizeInfo(w.Size - oldSize) - } - w.printf("\n") -} - -func (w *CodeWriter) writeValue(v reflect.Value) { - x := v.Interface() - switch v.Kind() { - case reflect.String: - w.WriteString(v.String()) - case reflect.Array: - // Don't double count: callers of WriteArray count on the size being - // added, so we need to discount it here. - w.Size -= int(v.Type().Size()) - w.writeSlice(x, true) - case reflect.Slice: - w.writeSlice(x, false) - case reflect.Struct: - w.printf("%s{\n", typeName(v.Interface())) - t := v.Type() - for i := 0; i < v.NumField(); i++ { - w.printf("%s: ", t.Field(i).Name) - w.writeValue(v.Field(i)) - w.printf(",\n") - } - w.printf("}") - default: - w.printf("%#v", x) - } -} - -// WriteString writes a string literal. -func (w *CodeWriter) WriteString(s string) { - s = strings.Replace(s, `\`, `\\`, -1) - io.WriteString(w.Hash, s) // content hash - w.Size += len(s) - - const maxInline = 40 - if len(s) <= maxInline { - w.printf("%q", s) - return - } - - // We will render the string as a multi-line string. - const maxWidth = 80 - 4 - len(`"`) - len(`" +`) - - // When starting on its own line, go fmt indents line 2+ an extra level. - n, max := maxWidth, maxWidth-4 - - // As per https://golang.org/issue/18078, the compiler has trouble - // compiling the concatenation of many strings, s0 + s1 + s2 + ... + sN, - // for large N. We insert redundant, explicit parentheses to work around - // that, lowering the N at any given step: (s0 + s1 + ... + s63) + (s64 + - // ... + s127) + etc + (etc + ... + sN). - explicitParens, extraComment := len(s) > 128*1024, "" - if explicitParens { - w.printf(`(`) - extraComment = "; the redundant, explicit parens are for https://golang.org/issue/18078" - } - - // Print "" +\n, if a string does not start on its own line. - b := w.buf.Bytes() - if p := len(bytes.TrimRight(b, " \t")); p > 0 && b[p-1] != '\n' { - w.printf("\"\" + // Size: %d bytes%s\n", len(s), extraComment) - n, max = maxWidth, maxWidth - } - - w.printf(`"`) - - for sz, p, nLines := 0, 0, 0; p < len(s); { - var r rune - r, sz = utf8.DecodeRuneInString(s[p:]) - out := s[p : p+sz] - chars := 1 - if !unicode.IsPrint(r) || r == utf8.RuneError || r == '"' { - switch sz { - case 1: - out = fmt.Sprintf("\\x%02x", s[p]) - case 2, 3: - out = fmt.Sprintf("\\u%04x", r) - case 4: - out = fmt.Sprintf("\\U%08x", r) - } - chars = len(out) - } - if n -= chars; n < 0 { - nLines++ - if explicitParens && nLines&63 == 63 { - w.printf("\") + (\"") - } - w.printf("\" +\n\"") - n = max - len(out) - } - w.printf("%s", out) - p += sz - } - w.printf(`"`) - if explicitParens { - w.printf(`)`) - } -} - -// WriteSlice writes a slice value. -func (w *CodeWriter) WriteSlice(x interface{}) { - w.writeSlice(x, false) -} - -// WriteArray writes an array value. -func (w *CodeWriter) WriteArray(x interface{}) { - w.writeSlice(x, true) -} - -func (w *CodeWriter) writeSlice(x interface{}, isArray bool) { - v := reflect.ValueOf(x) - w.gob.Encode(v.Len()) - w.Size += v.Len() * int(v.Type().Elem().Size()) - name := typeName(x) - if isArray { - name = fmt.Sprintf("[%d]%s", v.Len(), name[strings.Index(name, "]")+1:]) - } - if isArray { - w.printf("%s{\n", name) - } else { - w.printf("%s{ // %d elements\n", name, v.Len()) - } - - switch kind := v.Type().Elem().Kind(); kind { - case reflect.String: - for _, s := range x.([]string) { - w.WriteString(s) - w.printf(",\n") - } - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, - reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: - // nLine and nBlock are the number of elements per line and block. - nLine, nBlock, format := 8, 64, "%d," - switch kind { - case reflect.Uint8: - format = "%#02x," - case reflect.Uint16: - format = "%#04x," - case reflect.Uint32: - nLine, nBlock, format = 4, 32, "%#08x," - case reflect.Uint, reflect.Uint64: - nLine, nBlock, format = 4, 32, "%#016x," - case reflect.Int8: - nLine = 16 - } - n := nLine - for i := 0; i < v.Len(); i++ { - if i%nBlock == 0 && v.Len() > nBlock { - w.printf("// Entry %X - %X\n", i, i+nBlock-1) - } - x := v.Index(i).Interface() - w.gob.Encode(x) - w.printf(format, x) - if n--; n == 0 { - n = nLine - w.printf("\n") - } - } - w.printf("\n") - case reflect.Struct: - zero := reflect.Zero(v.Type().Elem()).Interface() - for i := 0; i < v.Len(); i++ { - x := v.Index(i).Interface() - w.gob.EncodeValue(v) - if !reflect.DeepEqual(zero, x) { - line := fmt.Sprintf("%#v,\n", x) - line = line[strings.IndexByte(line, '{'):] - w.printf("%d: ", i) - w.printf(line) - } - } - case reflect.Array: - for i := 0; i < v.Len(); i++ { - w.printf("%d: %#v,\n", i, v.Index(i).Interface()) - } - default: - panic("gen: slice elem type not supported") - } - w.printf("}") -} - -// WriteType writes a definition of the type of the given value and returns the -// type name. -func (w *CodeWriter) WriteType(x interface{}) string { - t := reflect.TypeOf(x) - w.printf("type %s struct {\n", t.Name()) - for i := 0; i < t.NumField(); i++ { - w.printf("\t%s %s\n", t.Field(i).Name, t.Field(i).Type) - } - w.printf("}\n") - return t.Name() -} - -// typeName returns the name of the go type of x. -func typeName(x interface{}) string { - t := reflect.ValueOf(x).Type() - return strings.Replace(fmt.Sprint(t), "main.", "", 1) -} diff --git a/components/cli/vendor/golang.org/x/text/internal/gen/gen.go b/components/cli/vendor/golang.org/x/text/internal/gen/gen.go deleted file mode 100644 index 84c699faa9..0000000000 --- a/components/cli/vendor/golang.org/x/text/internal/gen/gen.go +++ /dev/null @@ -1,281 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package gen contains common code for the various code generation tools in the -// text repository. Its usage ensures consistency between tools. -// -// This package defines command line flags that are common to most generation -// tools. The flags allow for specifying specific Unicode and CLDR versions -// in the public Unicode data repository (http://www.unicode.org/Public). -// -// A local Unicode data mirror can be set through the flag -local or the -// environment variable UNICODE_DIR. The former takes precedence. The local -// directory should follow the same structure as the public repository. -// -// IANA data can also optionally be mirrored by putting it in the iana directory -// rooted at the top of the local mirror. Beware, though, that IANA data is not -// versioned. So it is up to the developer to use the right version. -package gen // import "golang.org/x/text/internal/gen" - -import ( - "bytes" - "flag" - "fmt" - "go/build" - "go/format" - "io" - "io/ioutil" - "log" - "net/http" - "os" - "path" - "path/filepath" - "sync" - "unicode" - - "golang.org/x/text/unicode/cldr" -) - -var ( - url = flag.String("url", - "http://www.unicode.org/Public", - "URL of Unicode database directory") - iana = flag.String("iana", - "http://www.iana.org", - "URL of the IANA repository") - unicodeVersion = flag.String("unicode", - getEnv("UNICODE_VERSION", unicode.Version), - "unicode version to use") - cldrVersion = flag.String("cldr", - getEnv("CLDR_VERSION", cldr.Version), - "cldr version to use") -) - -func getEnv(name, def string) string { - if v := os.Getenv(name); v != "" { - return v - } - return def -} - -// Init performs common initialization for a gen command. It parses the flags -// and sets up the standard logging parameters. -func Init() { - log.SetPrefix("") - log.SetFlags(log.Lshortfile) - flag.Parse() -} - -const header = `// This file was generated by go generate; DO NOT EDIT - -package %s - -` - -// UnicodeVersion reports the requested Unicode version. -func UnicodeVersion() string { - return *unicodeVersion -} - -// UnicodeVersion reports the requested CLDR version. -func CLDRVersion() string { - return *cldrVersion -} - -// IsLocal reports whether data files are available locally. -func IsLocal() bool { - dir, err := localReadmeFile() - if err != nil { - return false - } - if _, err = os.Stat(dir); err != nil { - return false - } - return true -} - -// OpenUCDFile opens the requested UCD file. The file is specified relative to -// the public Unicode root directory. It will call log.Fatal if there are any -// errors. -func OpenUCDFile(file string) io.ReadCloser { - return openUnicode(path.Join(*unicodeVersion, "ucd", file)) -} - -// OpenCLDRCoreZip opens the CLDR core zip file. It will call log.Fatal if there -// are any errors. -func OpenCLDRCoreZip() io.ReadCloser { - return OpenUnicodeFile("cldr", *cldrVersion, "core.zip") -} - -// OpenUnicodeFile opens the requested file of the requested category from the -// root of the Unicode data archive. The file is specified relative to the -// public Unicode root directory. If version is "", it will use the default -// Unicode version. It will call log.Fatal if there are any errors. -func OpenUnicodeFile(category, version, file string) io.ReadCloser { - if version == "" { - version = UnicodeVersion() - } - return openUnicode(path.Join(category, version, file)) -} - -// OpenIANAFile opens the requested IANA file. The file is specified relative -// to the IANA root, which is typically either http://www.iana.org or the -// iana directory in the local mirror. It will call log.Fatal if there are any -// errors. -func OpenIANAFile(path string) io.ReadCloser { - return Open(*iana, "iana", path) -} - -var ( - dirMutex sync.Mutex - localDir string -) - -const permissions = 0755 - -func localReadmeFile() (string, error) { - p, err := build.Import("golang.org/x/text", "", build.FindOnly) - if err != nil { - return "", fmt.Errorf("Could not locate package: %v", err) - } - return filepath.Join(p.Dir, "DATA", "README"), nil -} - -func getLocalDir() string { - dirMutex.Lock() - defer dirMutex.Unlock() - - readme, err := localReadmeFile() - if err != nil { - log.Fatal(err) - } - dir := filepath.Dir(readme) - if _, err := os.Stat(readme); err != nil { - if err := os.MkdirAll(dir, permissions); err != nil { - log.Fatalf("Could not create directory: %v", err) - } - ioutil.WriteFile(readme, []byte(readmeTxt), permissions) - } - return dir -} - -const readmeTxt = `Generated by golang.org/x/text/internal/gen. DO NOT EDIT. - -This directory contains downloaded files used to generate the various tables -in the golang.org/x/text subrepo. - -Note that the language subtag repo (iana/assignments/language-subtag-registry) -and all other times in the iana subdirectory are not versioned and will need -to be periodically manually updated. The easiest way to do this is to remove -the entire iana directory. This is mostly of concern when updating the language -package. -` - -// Open opens subdir/path if a local directory is specified and the file exists, -// where subdir is a directory relative to the local root, or fetches it from -// urlRoot/path otherwise. It will call log.Fatal if there are any errors. -func Open(urlRoot, subdir, path string) io.ReadCloser { - file := filepath.Join(getLocalDir(), subdir, filepath.FromSlash(path)) - return open(file, urlRoot, path) -} - -func openUnicode(path string) io.ReadCloser { - file := filepath.Join(getLocalDir(), filepath.FromSlash(path)) - return open(file, *url, path) -} - -// TODO: automatically periodically update non-versioned files. - -func open(file, urlRoot, path string) io.ReadCloser { - if f, err := os.Open(file); err == nil { - return f - } - r := get(urlRoot, path) - defer r.Close() - b, err := ioutil.ReadAll(r) - if err != nil { - log.Fatalf("Could not download file: %v", err) - } - os.MkdirAll(filepath.Dir(file), permissions) - if err := ioutil.WriteFile(file, b, permissions); err != nil { - log.Fatalf("Could not create file: %v", err) - } - return ioutil.NopCloser(bytes.NewReader(b)) -} - -func get(root, path string) io.ReadCloser { - url := root + "/" + path - fmt.Printf("Fetching %s...", url) - defer fmt.Println(" done.") - resp, err := http.Get(url) - if err != nil { - log.Fatalf("HTTP GET: %v", err) - } - if resp.StatusCode != 200 { - log.Fatalf("Bad GET status for %q: %q", url, resp.Status) - } - return resp.Body -} - -// TODO: use Write*Version in all applicable packages. - -// WriteUnicodeVersion writes a constant for the Unicode version from which the -// tables are generated. -func WriteUnicodeVersion(w io.Writer) { - fmt.Fprintf(w, "// UnicodeVersion is the Unicode version from which the tables in this package are derived.\n") - fmt.Fprintf(w, "const UnicodeVersion = %q\n\n", UnicodeVersion()) -} - -// WriteCLDRVersion writes a constant for the CLDR version from which the -// tables are generated. -func WriteCLDRVersion(w io.Writer) { - fmt.Fprintf(w, "// CLDRVersion is the CLDR version from which the tables in this package are derived.\n") - fmt.Fprintf(w, "const CLDRVersion = %q\n\n", CLDRVersion()) -} - -// WriteGoFile prepends a standard file comment and package statement to the -// given bytes, applies gofmt, and writes them to a file with the given name. -// It will call log.Fatal if there are any errors. -func WriteGoFile(filename, pkg string, b []byte) { - w, err := os.Create(filename) - if err != nil { - log.Fatalf("Could not create file %s: %v", filename, err) - } - defer w.Close() - if _, err = WriteGo(w, pkg, b); err != nil { - log.Fatalf("Error writing file %s: %v", filename, err) - } -} - -// WriteGo prepends a standard file comment and package statement to the given -// bytes, applies gofmt, and writes them to w. -func WriteGo(w io.Writer, pkg string, b []byte) (n int, err error) { - src := []byte(fmt.Sprintf(header, pkg)) - src = append(src, b...) - formatted, err := format.Source(src) - if err != nil { - // Print the generated code even in case of an error so that the - // returned error can be meaningfully interpreted. - n, _ = w.Write(src) - return n, err - } - return w.Write(formatted) -} - -// Repackage rewrites a Go file from belonging to package main to belonging to -// the given package. -func Repackage(inFile, outFile, pkg string) { - src, err := ioutil.ReadFile(inFile) - if err != nil { - log.Fatalf("reading %s: %v", inFile, err) - } - const toDelete = "package main\n\n" - i := bytes.Index(src, []byte(toDelete)) - if i < 0 { - log.Fatalf("Could not find %q in %s.", toDelete, inFile) - } - w := &bytes.Buffer{} - w.Write(src[i+len(toDelete):]) - WriteGoFile(outFile, pkg, w.Bytes()) -} diff --git a/components/cli/vendor/golang.org/x/text/internal/triegen/compact.go b/components/cli/vendor/golang.org/x/text/internal/triegen/compact.go deleted file mode 100644 index 397b975c1b..0000000000 --- a/components/cli/vendor/golang.org/x/text/internal/triegen/compact.go +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package triegen - -// This file defines Compacter and its implementations. - -import "io" - -// A Compacter generates an alternative, more space-efficient way to store a -// trie value block. A trie value block holds all possible values for the last -// byte of a UTF-8 encoded rune. Excluding ASCII characters, a trie value block -// always has 64 values, as a UTF-8 encoding ends with a byte in [0x80, 0xC0). -type Compacter interface { - // Size returns whether the Compacter could encode the given block as well - // as its size in case it can. len(v) is always 64. - Size(v []uint64) (sz int, ok bool) - - // Store stores the block using the Compacter's compression method. - // It returns a handle with which the block can be retrieved. - // len(v) is always 64. - Store(v []uint64) uint32 - - // Print writes the data structures associated to the given store to w. - Print(w io.Writer) error - - // Handler returns the name of a function that gets called during trie - // lookup for blocks generated by the Compacter. The function should be of - // the form func (n uint32, b byte) uint64, where n is the index returned by - // the Compacter's Store method and b is the last byte of the UTF-8 - // encoding, where 0x80 <= b < 0xC0, for which to do the lookup in the - // block. - Handler() string -} - -// simpleCompacter is the default Compacter used by builder. It implements a -// normal trie block. -type simpleCompacter builder - -func (b *simpleCompacter) Size([]uint64) (sz int, ok bool) { - return blockSize * b.ValueSize, true -} - -func (b *simpleCompacter) Store(v []uint64) uint32 { - h := uint32(len(b.ValueBlocks) - blockOffset) - b.ValueBlocks = append(b.ValueBlocks, v) - return h -} - -func (b *simpleCompacter) Print(io.Writer) error { - // Structures are printed in print.go. - return nil -} - -func (b *simpleCompacter) Handler() string { - panic("Handler should be special-cased for this Compacter") -} diff --git a/components/cli/vendor/golang.org/x/text/internal/triegen/print.go b/components/cli/vendor/golang.org/x/text/internal/triegen/print.go deleted file mode 100644 index 8d9f120bcd..0000000000 --- a/components/cli/vendor/golang.org/x/text/internal/triegen/print.go +++ /dev/null @@ -1,251 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package triegen - -import ( - "bytes" - "fmt" - "io" - "strings" - "text/template" -) - -// print writes all the data structures as well as the code necessary to use the -// trie to w. -func (b *builder) print(w io.Writer) error { - b.Stats.NValueEntries = len(b.ValueBlocks) * blockSize - b.Stats.NValueBytes = len(b.ValueBlocks) * blockSize * b.ValueSize - b.Stats.NIndexEntries = len(b.IndexBlocks) * blockSize - b.Stats.NIndexBytes = len(b.IndexBlocks) * blockSize * b.IndexSize - b.Stats.NHandleBytes = len(b.Trie) * 2 * b.IndexSize - - // If we only have one root trie, all starter blocks are at position 0 and - // we can access the arrays directly. - if len(b.Trie) == 1 { - // At this point we cannot refer to the generated tables directly. - b.ASCIIBlock = b.Name + "Values" - b.StarterBlock = b.Name + "Index" - } else { - // Otherwise we need to have explicit starter indexes in the trie - // structure. - b.ASCIIBlock = "t.ascii" - b.StarterBlock = "t.utf8Start" - } - - b.SourceType = "[]byte" - if err := lookupGen.Execute(w, b); err != nil { - return err - } - - b.SourceType = "string" - if err := lookupGen.Execute(w, b); err != nil { - return err - } - - if err := trieGen.Execute(w, b); err != nil { - return err - } - - for _, c := range b.Compactions { - if err := c.c.Print(w); err != nil { - return err - } - } - - return nil -} - -func printValues(n int, values []uint64) string { - w := &bytes.Buffer{} - boff := n * blockSize - fmt.Fprintf(w, "\t// Block %#x, offset %#x", n, boff) - var newline bool - for i, v := range values { - if i%6 == 0 { - newline = true - } - if v != 0 { - if newline { - fmt.Fprintf(w, "\n") - newline = false - } - fmt.Fprintf(w, "\t%#02x:%#04x, ", boff+i, v) - } - } - return w.String() -} - -func printIndex(b *builder, nr int, n *node) string { - w := &bytes.Buffer{} - boff := nr * blockSize - fmt.Fprintf(w, "\t// Block %#x, offset %#x", nr, boff) - var newline bool - for i, c := range n.children { - if i%8 == 0 { - newline = true - } - if c != nil { - v := b.Compactions[c.index.compaction].Offset + uint32(c.index.index) - if v != 0 { - if newline { - fmt.Fprintf(w, "\n") - newline = false - } - fmt.Fprintf(w, "\t%#02x:%#02x, ", boff+i, v) - } - } - } - return w.String() -} - -var ( - trieGen = template.Must(template.New("trie").Funcs(template.FuncMap{ - "printValues": printValues, - "printIndex": printIndex, - "title": strings.Title, - "dec": func(x int) int { return x - 1 }, - "psize": func(n int) string { - return fmt.Sprintf("%d bytes (%.2f KiB)", n, float64(n)/1024) - }, - }).Parse(trieTemplate)) - lookupGen = template.Must(template.New("lookup").Parse(lookupTemplate)) -) - -// TODO: consider the return type of lookup. It could be uint64, even if the -// internal value type is smaller. We will have to verify this with the -// performance of unicode/norm, which is very sensitive to such changes. -const trieTemplate = `{{$b := .}}{{$multi := gt (len .Trie) 1}} -// {{.Name}}Trie. Total size: {{psize .Size}}. Checksum: {{printf "%08x" .Checksum}}. -type {{.Name}}Trie struct { {{if $multi}} - ascii []{{.ValueType}} // index for ASCII bytes - utf8Start []{{.IndexType}} // index for UTF-8 bytes >= 0xC0 -{{end}}} - -func new{{title .Name}}Trie(i int) *{{.Name}}Trie { {{if $multi}} - h := {{.Name}}TrieHandles[i] - return &{{.Name}}Trie{ {{.Name}}Values[uint32(h.ascii)<<6:], {{.Name}}Index[uint32(h.multi)<<6:] } -} - -type {{.Name}}TrieHandle struct { - ascii, multi {{.IndexType}} -} - -// {{.Name}}TrieHandles: {{len .Trie}} handles, {{.Stats.NHandleBytes}} bytes -var {{.Name}}TrieHandles = [{{len .Trie}}]{{.Name}}TrieHandle{ -{{range .Trie}} { {{.ASCIIIndex}}, {{.StarterIndex}} }, // {{printf "%08x" .Checksum}}: {{.Name}} -{{end}}}{{else}} - return &{{.Name}}Trie{} -} -{{end}} -// lookupValue determines the type of block n and looks up the value for b. -func (t *{{.Name}}Trie) lookupValue(n uint32, b byte) {{.ValueType}}{{$last := dec (len .Compactions)}} { - switch { {{range $i, $c := .Compactions}} - {{if eq $i $last}}default{{else}}case n < {{$c.Cutoff}}{{end}}:{{if ne $i 0}} - n -= {{$c.Offset}}{{end}} - return {{print $b.ValueType}}({{$c.Handler}}){{end}} - } -} - -// {{.Name}}Values: {{len .ValueBlocks}} blocks, {{.Stats.NValueEntries}} entries, {{.Stats.NValueBytes}} bytes -// The third block is the zero block. -var {{.Name}}Values = [{{.Stats.NValueEntries}}]{{.ValueType}} { -{{range $i, $v := .ValueBlocks}}{{printValues $i $v}} -{{end}}} - -// {{.Name}}Index: {{len .IndexBlocks}} blocks, {{.Stats.NIndexEntries}} entries, {{.Stats.NIndexBytes}} bytes -// Block 0 is the zero block. -var {{.Name}}Index = [{{.Stats.NIndexEntries}}]{{.IndexType}} { -{{range $i, $v := .IndexBlocks}}{{printIndex $b $i $v}} -{{end}}} -` - -// TODO: consider allowing zero-length strings after evaluating performance with -// unicode/norm. -const lookupTemplate = ` -// lookup{{if eq .SourceType "string"}}String{{end}} returns the trie value for the first UTF-8 encoding in s and -// the width in bytes of this encoding. The size will be 0 if s does not -// hold enough bytes to complete the encoding. len(s) must be greater than 0. -func (t *{{.Name}}Trie) lookup{{if eq .SourceType "string"}}String{{end}}(s {{.SourceType}}) (v {{.ValueType}}, sz int) { - c0 := s[0] - switch { - case c0 < 0x80: // is ASCII - return {{.ASCIIBlock}}[c0], 1 - case c0 < 0xC2: - return 0, 1 // Illegal UTF-8: not a starter, not ASCII. - case c0 < 0xE0: // 2-byte UTF-8 - if len(s) < 2 { - return 0, 0 - } - i := {{.StarterBlock}}[c0] - c1 := s[1] - if c1 < 0x80 || 0xC0 <= c1 { - return 0, 1 // Illegal UTF-8: not a continuation byte. - } - return t.lookupValue(uint32(i), c1), 2 - case c0 < 0xF0: // 3-byte UTF-8 - if len(s) < 3 { - return 0, 0 - } - i := {{.StarterBlock}}[c0] - c1 := s[1] - if c1 < 0x80 || 0xC0 <= c1 { - return 0, 1 // Illegal UTF-8: not a continuation byte. - } - o := uint32(i)<<6 + uint32(c1) - i = {{.Name}}Index[o] - c2 := s[2] - if c2 < 0x80 || 0xC0 <= c2 { - return 0, 2 // Illegal UTF-8: not a continuation byte. - } - return t.lookupValue(uint32(i), c2), 3 - case c0 < 0xF8: // 4-byte UTF-8 - if len(s) < 4 { - return 0, 0 - } - i := {{.StarterBlock}}[c0] - c1 := s[1] - if c1 < 0x80 || 0xC0 <= c1 { - return 0, 1 // Illegal UTF-8: not a continuation byte. - } - o := uint32(i)<<6 + uint32(c1) - i = {{.Name}}Index[o] - c2 := s[2] - if c2 < 0x80 || 0xC0 <= c2 { - return 0, 2 // Illegal UTF-8: not a continuation byte. - } - o = uint32(i)<<6 + uint32(c2) - i = {{.Name}}Index[o] - c3 := s[3] - if c3 < 0x80 || 0xC0 <= c3 { - return 0, 3 // Illegal UTF-8: not a continuation byte. - } - return t.lookupValue(uint32(i), c3), 4 - } - // Illegal rune - return 0, 1 -} - -// lookup{{if eq .SourceType "string"}}String{{end}}Unsafe returns the trie value for the first UTF-8 encoding in s. -// s must start with a full and valid UTF-8 encoded rune. -func (t *{{.Name}}Trie) lookup{{if eq .SourceType "string"}}String{{end}}Unsafe(s {{.SourceType}}) {{.ValueType}} { - c0 := s[0] - if c0 < 0x80 { // is ASCII - return {{.ASCIIBlock}}[c0] - } - i := {{.StarterBlock}}[c0] - if c0 < 0xE0 { // 2-byte UTF-8 - return t.lookupValue(uint32(i), s[1]) - } - i = {{.Name}}Index[uint32(i)<<6+uint32(s[1])] - if c0 < 0xF0 { // 3-byte UTF-8 - return t.lookupValue(uint32(i), s[2]) - } - i = {{.Name}}Index[uint32(i)<<6+uint32(s[2])] - if c0 < 0xF8 { // 4-byte UTF-8 - return t.lookupValue(uint32(i), s[3]) - } - return 0 -} -` diff --git a/components/cli/vendor/golang.org/x/text/internal/triegen/triegen.go b/components/cli/vendor/golang.org/x/text/internal/triegen/triegen.go deleted file mode 100644 index adb0108124..0000000000 --- a/components/cli/vendor/golang.org/x/text/internal/triegen/triegen.go +++ /dev/null @@ -1,494 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package triegen implements a code generator for a trie for associating -// unsigned integer values with UTF-8 encoded runes. -// -// Many of the go.text packages use tries for storing per-rune information. A -// trie is especially useful if many of the runes have the same value. If this -// is the case, many blocks can be expected to be shared allowing for -// information on many runes to be stored in little space. -// -// As most of the lookups are done directly on []byte slices, the tries use the -// UTF-8 bytes directly for the lookup. This saves a conversion from UTF-8 to -// runes and contributes a little bit to better performance. It also naturally -// provides a fast path for ASCII. -// -// Space is also an issue. There are many code points defined in Unicode and as -// a result tables can get quite large. So every byte counts. The triegen -// package automatically chooses the smallest integer values to represent the -// tables. Compacters allow further compression of the trie by allowing for -// alternative representations of individual trie blocks. -// -// triegen allows generating multiple tries as a single structure. This is -// useful when, for example, one wants to generate tries for several languages -// that have a lot of values in common. Some existing libraries for -// internationalization store all per-language data as a dynamically loadable -// chunk. The go.text packages are designed with the assumption that the user -// typically wants to compile in support for all supported languages, in line -// with the approach common to Go to create a single standalone binary. The -// multi-root trie approach can give significant storage savings in this -// scenario. -// -// triegen generates both tables and code. The code is optimized to use the -// automatically chosen data types. The following code is generated for a Trie -// or multiple Tries named "foo": -// - type fooTrie -// The trie type. -// -// - func newFooTrie(x int) *fooTrie -// Trie constructor, where x is the index of the trie passed to Gen. -// -// - func (t *fooTrie) lookup(s []byte) (v uintX, sz int) -// The lookup method, where uintX is automatically chosen. -// -// - func lookupString, lookupUnsafe and lookupStringUnsafe -// Variants of the above. -// -// - var fooValues and fooIndex and any tables generated by Compacters. -// The core trie data. -// -// - var fooTrieHandles -// Indexes of starter blocks in case of multiple trie roots. -// -// It is recommended that users test the generated trie by checking the returned -// value for every rune. Such exhaustive tests are possible as the the number of -// runes in Unicode is limited. -package triegen // import "golang.org/x/text/internal/triegen" - -// TODO: Arguably, the internally optimized data types would not have to be -// exposed in the generated API. We could also investigate not generating the -// code, but using it through a package. We would have to investigate the impact -// on performance of making such change, though. For packages like unicode/norm, -// small changes like this could tank performance. - -import ( - "encoding/binary" - "fmt" - "hash/crc64" - "io" - "log" - "unicode/utf8" -) - -// builder builds a set of tries for associating values with runes. The set of -// tries can share common index and value blocks. -type builder struct { - Name string - - // ValueType is the type of the trie values looked up. - ValueType string - - // ValueSize is the byte size of the ValueType. - ValueSize int - - // IndexType is the type of trie index values used for all UTF-8 bytes of - // a rune except the last one. - IndexType string - - // IndexSize is the byte size of the IndexType. - IndexSize int - - // SourceType is used when generating the lookup functions. If the user - // requests StringSupport, all lookup functions will be generated for - // string input as well. - SourceType string - - Trie []*Trie - - IndexBlocks []*node - ValueBlocks [][]uint64 - Compactions []compaction - Checksum uint64 - - ASCIIBlock string - StarterBlock string - - indexBlockIdx map[uint64]int - valueBlockIdx map[uint64]nodeIndex - asciiBlockIdx map[uint64]int - - // Stats are used to fill out the template. - Stats struct { - NValueEntries int - NValueBytes int - NIndexEntries int - NIndexBytes int - NHandleBytes int - } - - err error -} - -// A nodeIndex encodes the index of a node, which is defined by the compaction -// which stores it and an index within the compaction. For internal nodes, the -// compaction is always 0. -type nodeIndex struct { - compaction int - index int -} - -// compaction keeps track of stats used for the compaction. -type compaction struct { - c Compacter - blocks []*node - maxHandle uint32 - totalSize int - - // Used by template-based generator and thus exported. - Cutoff uint32 - Offset uint32 - Handler string -} - -func (b *builder) setError(err error) { - if b.err == nil { - b.err = err - } -} - -// An Option can be passed to Gen. -type Option func(b *builder) error - -// Compact configures the trie generator to use the given Compacter. -func Compact(c Compacter) Option { - return func(b *builder) error { - b.Compactions = append(b.Compactions, compaction{ - c: c, - Handler: c.Handler() + "(n, b)"}) - return nil - } -} - -// Gen writes Go code for a shared trie lookup structure to w for the given -// Tries. The generated trie type will be called nameTrie. newNameTrie(x) will -// return the *nameTrie for tries[x]. A value can be looked up by using one of -// the various lookup methods defined on nameTrie. It returns the table size of -// the generated trie. -func Gen(w io.Writer, name string, tries []*Trie, opts ...Option) (sz int, err error) { - // The index contains two dummy blocks, followed by the zero block. The zero - // block is at offset 0x80, so that the offset for the zero block for - // continuation bytes is 0. - b := &builder{ - Name: name, - Trie: tries, - IndexBlocks: []*node{{}, {}, {}}, - Compactions: []compaction{{ - Handler: name + "Values[n<<6+uint32(b)]", - }}, - // The 0 key in indexBlockIdx and valueBlockIdx is the hash of the zero - // block. - indexBlockIdx: map[uint64]int{0: 0}, - valueBlockIdx: map[uint64]nodeIndex{0: {}}, - asciiBlockIdx: map[uint64]int{}, - } - b.Compactions[0].c = (*simpleCompacter)(b) - - for _, f := range opts { - if err := f(b); err != nil { - return 0, err - } - } - b.build() - if b.err != nil { - return 0, b.err - } - if err = b.print(w); err != nil { - return 0, err - } - return b.Size(), nil -} - -// A Trie represents a single root node of a trie. A builder may build several -// overlapping tries at once. -type Trie struct { - root *node - - hiddenTrie -} - -// hiddenTrie contains values we want to be visible to the template generator, -// but hidden from the API documentation. -type hiddenTrie struct { - Name string - Checksum uint64 - ASCIIIndex int - StarterIndex int -} - -// NewTrie returns a new trie root. -func NewTrie(name string) *Trie { - return &Trie{ - &node{ - children: make([]*node, blockSize), - values: make([]uint64, utf8.RuneSelf), - }, - hiddenTrie{Name: name}, - } -} - -// Gen is a convenience wrapper around the Gen func passing t as the only trie -// and uses the name passed to NewTrie. It returns the size of the generated -// tables. -func (t *Trie) Gen(w io.Writer, opts ...Option) (sz int, err error) { - return Gen(w, t.Name, []*Trie{t}, opts...) -} - -// node is a node of the intermediate trie structure. -type node struct { - // children holds this node's children. It is always of length 64. - // A child node may be nil. - children []*node - - // values contains the values of this node. If it is non-nil, this node is - // either a root or leaf node: - // For root nodes, len(values) == 128 and it maps the bytes in [0x00, 0x7F]. - // For leaf nodes, len(values) == 64 and it maps the bytes in [0x80, 0xBF]. - values []uint64 - - index nodeIndex -} - -// Insert associates value with the given rune. Insert will panic if a non-zero -// value is passed for an invalid rune. -func (t *Trie) Insert(r rune, value uint64) { - if value == 0 { - return - } - s := string(r) - if []rune(s)[0] != r && value != 0 { - // Note: The UCD tables will always assign what amounts to a zero value - // to a surrogate. Allowing a zero value for an illegal rune allows - // users to iterate over [0..MaxRune] without having to explicitly - // exclude surrogates, which would be tedious. - panic(fmt.Sprintf("triegen: non-zero value for invalid rune %U", r)) - } - if len(s) == 1 { - // It is a root node value (ASCII). - t.root.values[s[0]] = value - return - } - - n := t.root - for ; len(s) > 1; s = s[1:] { - if n.children == nil { - n.children = make([]*node, blockSize) - } - p := s[0] % blockSize - c := n.children[p] - if c == nil { - c = &node{} - n.children[p] = c - } - if len(s) > 2 && c.values != nil { - log.Fatalf("triegen: insert(%U): found internal node with values", r) - } - n = c - } - if n.values == nil { - n.values = make([]uint64, blockSize) - } - if n.children != nil { - log.Fatalf("triegen: insert(%U): found leaf node that also has child nodes", r) - } - n.values[s[0]-0x80] = value -} - -// Size returns the number of bytes the generated trie will take to store. It -// needs to be exported as it is used in the templates. -func (b *builder) Size() int { - // Index blocks. - sz := len(b.IndexBlocks) * blockSize * b.IndexSize - - // Skip the first compaction, which represents the normal value blocks, as - // its totalSize does not account for the ASCII blocks, which are managed - // separately. - sz += len(b.ValueBlocks) * blockSize * b.ValueSize - for _, c := range b.Compactions[1:] { - sz += c.totalSize - } - - // TODO: this computation does not account for the fixed overhead of a using - // a compaction, either code or data. As for data, though, the typical - // overhead of data is in the order of bytes (2 bytes for cases). Further, - // the savings of using a compaction should anyway be substantial for it to - // be worth it. - - // For multi-root tries, we also need to account for the handles. - if len(b.Trie) > 1 { - sz += 2 * b.IndexSize * len(b.Trie) - } - return sz -} - -func (b *builder) build() { - // Compute the sizes of the values. - var vmax uint64 - for _, t := range b.Trie { - vmax = maxValue(t.root, vmax) - } - b.ValueType, b.ValueSize = getIntType(vmax) - - // Compute all block allocations. - // TODO: first compute the ASCII blocks for all tries and then the other - // nodes. ASCII blocks are more restricted in placement, as they require two - // blocks to be placed consecutively. Processing them first may improve - // sharing (at least one zero block can be expected to be saved.) - for _, t := range b.Trie { - b.Checksum += b.buildTrie(t) - } - - // Compute the offsets for all the Compacters. - offset := uint32(0) - for i := range b.Compactions { - c := &b.Compactions[i] - c.Offset = offset - offset += c.maxHandle + 1 - c.Cutoff = offset - } - - // Compute the sizes of indexes. - // TODO: different byte positions could have different sizes. So far we have - // not found a case where this is beneficial. - imax := uint64(b.Compactions[len(b.Compactions)-1].Cutoff) - for _, ib := range b.IndexBlocks { - if x := uint64(ib.index.index); x > imax { - imax = x - } - } - b.IndexType, b.IndexSize = getIntType(imax) -} - -func maxValue(n *node, max uint64) uint64 { - if n == nil { - return max - } - for _, c := range n.children { - max = maxValue(c, max) - } - for _, v := range n.values { - if max < v { - max = v - } - } - return max -} - -func getIntType(v uint64) (string, int) { - switch { - case v < 1<<8: - return "uint8", 1 - case v < 1<<16: - return "uint16", 2 - case v < 1<<32: - return "uint32", 4 - } - return "uint64", 8 -} - -const ( - blockSize = 64 - - // Subtract two blocks to offset 0x80, the first continuation byte. - blockOffset = 2 - - // Subtract three blocks to offset 0xC0, the first non-ASCII starter. - rootBlockOffset = 3 -) - -var crcTable = crc64.MakeTable(crc64.ISO) - -func (b *builder) buildTrie(t *Trie) uint64 { - n := t.root - - // Get the ASCII offset. For the first trie, the ASCII block will be at - // position 0. - hasher := crc64.New(crcTable) - binary.Write(hasher, binary.BigEndian, n.values) - hash := hasher.Sum64() - - v, ok := b.asciiBlockIdx[hash] - if !ok { - v = len(b.ValueBlocks) - b.asciiBlockIdx[hash] = v - - b.ValueBlocks = append(b.ValueBlocks, n.values[:blockSize], n.values[blockSize:]) - if v == 0 { - // Add the zero block at position 2 so that it will be assigned a - // zero reference in the lookup blocks. - // TODO: always do this? This would allow us to remove a check from - // the trie lookup, but at the expense of extra space. Analyze - // performance for unicode/norm. - b.ValueBlocks = append(b.ValueBlocks, make([]uint64, blockSize)) - } - } - t.ASCIIIndex = v - - // Compute remaining offsets. - t.Checksum = b.computeOffsets(n, true) - // We already subtracted the normal blockOffset from the index. Subtract the - // difference for starter bytes. - t.StarterIndex = n.index.index - (rootBlockOffset - blockOffset) - return t.Checksum -} - -func (b *builder) computeOffsets(n *node, root bool) uint64 { - // For the first trie, the root lookup block will be at position 3, which is - // the offset for UTF-8 non-ASCII starter bytes. - first := len(b.IndexBlocks) == rootBlockOffset - if first { - b.IndexBlocks = append(b.IndexBlocks, n) - } - - // We special-case the cases where all values recursively are 0. This allows - // for the use of a zero block to which all such values can be directed. - hash := uint64(0) - if n.children != nil || n.values != nil { - hasher := crc64.New(crcTable) - for _, c := range n.children { - var v uint64 - if c != nil { - v = b.computeOffsets(c, false) - } - binary.Write(hasher, binary.BigEndian, v) - } - binary.Write(hasher, binary.BigEndian, n.values) - hash = hasher.Sum64() - } - - if first { - b.indexBlockIdx[hash] = rootBlockOffset - blockOffset - } - - // Compacters don't apply to internal nodes. - if n.children != nil { - v, ok := b.indexBlockIdx[hash] - if !ok { - v = len(b.IndexBlocks) - blockOffset - b.IndexBlocks = append(b.IndexBlocks, n) - b.indexBlockIdx[hash] = v - } - n.index = nodeIndex{0, v} - } else { - h, ok := b.valueBlockIdx[hash] - if !ok { - bestI, bestSize := 0, blockSize*b.ValueSize - for i, c := range b.Compactions[1:] { - if sz, ok := c.c.Size(n.values); ok && bestSize > sz { - bestI, bestSize = i+1, sz - } - } - c := &b.Compactions[bestI] - c.totalSize += bestSize - v := c.c.Store(n.values) - if c.maxHandle < v { - c.maxHandle = v - } - h = nodeIndex{bestI, int(v)} - b.valueBlockIdx[hash] = h - } - n.index = h - } - return hash -} diff --git a/components/cli/vendor/golang.org/x/text/internal/ucd/ucd.go b/components/cli/vendor/golang.org/x/text/internal/ucd/ucd.go deleted file mode 100644 index 309e8d8b16..0000000000 --- a/components/cli/vendor/golang.org/x/text/internal/ucd/ucd.go +++ /dev/null @@ -1,376 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package ucd provides a parser for Unicode Character Database files, the -// format of which is defined in http://www.unicode.org/reports/tr44/. See -// http://www.unicode.org/Public/UCD/latest/ucd/ for example files. -// -// It currently does not support substitutions of missing fields. -package ucd // import "golang.org/x/text/internal/ucd" - -import ( - "bufio" - "bytes" - "errors" - "io" - "log" - "regexp" - "strconv" - "strings" -) - -// UnicodeData.txt fields. -const ( - CodePoint = iota - Name - GeneralCategory - CanonicalCombiningClass - BidiClass - DecompMapping - DecimalValue - DigitValue - NumericValue - BidiMirrored - Unicode1Name - ISOComment - SimpleUppercaseMapping - SimpleLowercaseMapping - SimpleTitlecaseMapping -) - -// Parse calls f for each entry in the given reader of a UCD file. It will close -// the reader upon return. It will call log.Fatal if any error occurred. -// -// This implements the most common usage pattern of using Parser. -func Parse(r io.ReadCloser, f func(p *Parser)) { - defer r.Close() - - p := New(r) - for p.Next() { - f(p) - } - if err := p.Err(); err != nil { - r.Close() // os.Exit will cause defers not to be called. - log.Fatal(err) - } -} - -// An Option is used to configure a Parser. -type Option func(p *Parser) - -func keepRanges(p *Parser) { - p.keepRanges = true -} - -var ( - // KeepRanges prevents the expansion of ranges. The raw ranges can be - // obtained by calling Range(0) on the parser. - KeepRanges Option = keepRanges -) - -// The Part option register a handler for lines starting with a '@'. The text -// after a '@' is available as the first field. Comments are handled as usual. -func Part(f func(p *Parser)) Option { - return func(p *Parser) { - p.partHandler = f - } -} - -// The CommentHandler option passes comments that are on a line by itself to -// a given handler. -func CommentHandler(f func(s string)) Option { - return func(p *Parser) { - p.commentHandler = f - } -} - -// A Parser parses Unicode Character Database (UCD) files. -type Parser struct { - scanner *bufio.Scanner - - keepRanges bool // Don't expand rune ranges in field 0. - - err error - comment []byte - field [][]byte - // parsedRange is needed in case Range(0) is called more than once for one - // field. In some cases this requires scanning ahead. - parsedRange bool - rangeStart, rangeEnd rune - - partHandler func(p *Parser) - commentHandler func(s string) -} - -func (p *Parser) setError(err error) { - if p.err == nil { - p.err = err - } -} - -func (p *Parser) getField(i int) []byte { - if i >= len(p.field) { - return nil - } - return p.field[i] -} - -// Err returns a non-nil error if any error occurred during parsing. -func (p *Parser) Err() error { - return p.err -} - -// New returns a Parser for the given Reader. -func New(r io.Reader, o ...Option) *Parser { - p := &Parser{ - scanner: bufio.NewScanner(r), - } - for _, f := range o { - f(p) - } - return p -} - -// Next parses the next line in the file. It returns true if a line was parsed -// and false if it reached the end of the file. -func (p *Parser) Next() bool { - if !p.keepRanges && p.rangeStart < p.rangeEnd { - p.rangeStart++ - return true - } - p.comment = nil - p.field = p.field[:0] - p.parsedRange = false - - for p.scanner.Scan() { - b := p.scanner.Bytes() - if len(b) == 0 { - continue - } - if b[0] == '#' { - if p.commentHandler != nil { - p.commentHandler(strings.TrimSpace(string(b[1:]))) - } - continue - } - - // Parse line - if i := bytes.IndexByte(b, '#'); i != -1 { - p.comment = bytes.TrimSpace(b[i+1:]) - b = b[:i] - } - if b[0] == '@' { - if p.partHandler != nil { - p.field = append(p.field, bytes.TrimSpace(b[1:])) - p.partHandler(p) - p.field = p.field[:0] - } - p.comment = nil - continue - } - for { - i := bytes.IndexByte(b, ';') - if i == -1 { - p.field = append(p.field, bytes.TrimSpace(b)) - break - } - p.field = append(p.field, bytes.TrimSpace(b[:i])) - b = b[i+1:] - } - if !p.keepRanges { - p.rangeStart, p.rangeEnd = p.getRange(0) - } - return true - } - p.setError(p.scanner.Err()) - return false -} - -func parseRune(b []byte) (rune, error) { - if len(b) > 2 && b[0] == 'U' && b[1] == '+' { - b = b[2:] - } - x, err := strconv.ParseUint(string(b), 16, 32) - return rune(x), err -} - -func (p *Parser) parseRune(b []byte) rune { - x, err := parseRune(b) - p.setError(err) - return x -} - -// Rune parses and returns field i as a rune. -func (p *Parser) Rune(i int) rune { - if i > 0 || p.keepRanges { - return p.parseRune(p.getField(i)) - } - return p.rangeStart -} - -// Runes interprets and returns field i as a sequence of runes. -func (p *Parser) Runes(i int) (runes []rune) { - add := func(b []byte) { - if b = bytes.TrimSpace(b); len(b) > 0 { - runes = append(runes, p.parseRune(b)) - } - } - for b := p.getField(i); ; { - i := bytes.IndexByte(b, ' ') - if i == -1 { - add(b) - break - } - add(b[:i]) - b = b[i+1:] - } - return -} - -var ( - errIncorrectLegacyRange = errors.New("ucd: unmatched <* First>") - - // reRange matches one line of a legacy rune range. - reRange = regexp.MustCompile("^([0-9A-F]*);<([^,]*), ([^>]*)>(.*)$") -) - -// Range parses and returns field i as a rune range. A range is inclusive at -// both ends. If the field only has one rune, first and last will be identical. -// It supports the legacy format for ranges used in UnicodeData.txt. -func (p *Parser) Range(i int) (first, last rune) { - if !p.keepRanges { - return p.rangeStart, p.rangeStart - } - return p.getRange(i) -} - -func (p *Parser) getRange(i int) (first, last rune) { - b := p.getField(i) - if k := bytes.Index(b, []byte("..")); k != -1 { - return p.parseRune(b[:k]), p.parseRune(b[k+2:]) - } - // The first field may not be a rune, in which case we may ignore any error - // and set the range as 0..0. - x, err := parseRune(b) - if err != nil { - // Disable range parsing henceforth. This ensures that an error will be - // returned if the user subsequently will try to parse this field as - // a Rune. - p.keepRanges = true - } - // Special case for UnicodeData that was retained for backwards compatibility. - if i == 0 && len(p.field) > 1 && bytes.HasSuffix(p.field[1], []byte("First>")) { - if p.parsedRange { - return p.rangeStart, p.rangeEnd - } - mf := reRange.FindStringSubmatch(p.scanner.Text()) - if mf == nil || !p.scanner.Scan() { - p.setError(errIncorrectLegacyRange) - return x, x - } - // Using Bytes would be more efficient here, but Text is a lot easier - // and this is not a frequent case. - ml := reRange.FindStringSubmatch(p.scanner.Text()) - if ml == nil || mf[2] != ml[2] || ml[3] != "Last" || mf[4] != ml[4] { - p.setError(errIncorrectLegacyRange) - return x, x - } - p.rangeStart, p.rangeEnd = x, p.parseRune(p.scanner.Bytes()[:len(ml[1])]) - p.parsedRange = true - return p.rangeStart, p.rangeEnd - } - return x, x -} - -// bools recognizes all valid UCD boolean values. -var bools = map[string]bool{ - "": false, - "N": false, - "No": false, - "F": false, - "False": false, - "Y": true, - "Yes": true, - "T": true, - "True": true, -} - -// Bool parses and returns field i as a boolean value. -func (p *Parser) Bool(i int) bool { - b := p.getField(i) - for s, v := range bools { - if bstrEq(b, s) { - return v - } - } - p.setError(strconv.ErrSyntax) - return false -} - -// Int parses and returns field i as an integer value. -func (p *Parser) Int(i int) int { - x, err := strconv.ParseInt(string(p.getField(i)), 10, 64) - p.setError(err) - return int(x) -} - -// Uint parses and returns field i as an unsigned integer value. -func (p *Parser) Uint(i int) uint { - x, err := strconv.ParseUint(string(p.getField(i)), 10, 64) - p.setError(err) - return uint(x) -} - -// Float parses and returns field i as a decimal value. -func (p *Parser) Float(i int) float64 { - x, err := strconv.ParseFloat(string(p.getField(i)), 64) - p.setError(err) - return x -} - -// String parses and returns field i as a string value. -func (p *Parser) String(i int) string { - return string(p.getField(i)) -} - -// Strings parses and returns field i as a space-separated list of strings. -func (p *Parser) Strings(i int) []string { - ss := strings.Split(string(p.getField(i)), " ") - for i, s := range ss { - ss[i] = strings.TrimSpace(s) - } - return ss -} - -// Comment returns the comments for the current line. -func (p *Parser) Comment() string { - return string(p.comment) -} - -var errUndefinedEnum = errors.New("ucd: undefined enum value") - -// Enum interprets and returns field i as a value that must be one of the values -// in enum. -func (p *Parser) Enum(i int, enum ...string) string { - b := p.getField(i) - for _, s := range enum { - if bstrEq(b, s) { - return s - } - } - p.setError(errUndefinedEnum) - return "" -} - -func bstrEq(b []byte, s string) bool { - if len(b) != len(s) { - return false - } - for i, c := range b { - if c != s[i] { - return false - } - } - return true -} diff --git a/components/cli/vendor/golang.org/x/text/unicode/bidi/gen.go b/components/cli/vendor/golang.org/x/text/unicode/bidi/gen.go deleted file mode 100644 index 040f3013d5..0000000000 --- a/components/cli/vendor/golang.org/x/text/unicode/bidi/gen.go +++ /dev/null @@ -1,133 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build ignore - -package main - -import ( - "flag" - "log" - - "golang.org/x/text/internal/gen" - "golang.org/x/text/internal/triegen" - "golang.org/x/text/internal/ucd" -) - -var outputFile = flag.String("out", "tables.go", "output file") - -func main() { - gen.Init() - gen.Repackage("gen_trieval.go", "trieval.go", "bidi") - gen.Repackage("gen_ranges.go", "ranges_test.go", "bidi") - - genTables() -} - -// bidiClass names and codes taken from class "bc" in -// http://www.unicode.org/Public/8.0.0/ucd/PropertyValueAliases.txt -var bidiClass = map[string]Class{ - "AL": AL, // ArabicLetter - "AN": AN, // ArabicNumber - "B": B, // ParagraphSeparator - "BN": BN, // BoundaryNeutral - "CS": CS, // CommonSeparator - "EN": EN, // EuropeanNumber - "ES": ES, // EuropeanSeparator - "ET": ET, // EuropeanTerminator - "L": L, // LeftToRight - "NSM": NSM, // NonspacingMark - "ON": ON, // OtherNeutral - "R": R, // RightToLeft - "S": S, // SegmentSeparator - "WS": WS, // WhiteSpace - - "FSI": Control, - "PDF": Control, - "PDI": Control, - "LRE": Control, - "LRI": Control, - "LRO": Control, - "RLE": Control, - "RLI": Control, - "RLO": Control, -} - -func genTables() { - if numClass > 0x0F { - log.Fatalf("Too many Class constants (%#x > 0x0F).", numClass) - } - w := gen.NewCodeWriter() - defer w.WriteGoFile(*outputFile, "bidi") - - gen.WriteUnicodeVersion(w) - - t := triegen.NewTrie("bidi") - - // Build data about bracket mapping. These bits need to be or-ed with - // any other bits. - orMask := map[rune]uint64{} - - xorMap := map[rune]int{} - xorMasks := []rune{0} // First value is no-op. - - ucd.Parse(gen.OpenUCDFile("BidiBrackets.txt"), func(p *ucd.Parser) { - r1 := p.Rune(0) - r2 := p.Rune(1) - xor := r1 ^ r2 - if _, ok := xorMap[xor]; !ok { - xorMap[xor] = len(xorMasks) - xorMasks = append(xorMasks, xor) - } - entry := uint64(xorMap[xor]) << xorMaskShift - switch p.String(2) { - case "o": - entry |= openMask - case "c", "n": - default: - log.Fatalf("Unknown bracket class %q.", p.String(2)) - } - orMask[r1] = entry - }) - - w.WriteComment(` - xorMasks contains masks to be xor-ed with brackets to get the reverse - version.`) - w.WriteVar("xorMasks", xorMasks) - - done := map[rune]bool{} - - insert := func(r rune, c Class) { - if !done[r] { - t.Insert(r, orMask[r]|uint64(c)) - done[r] = true - } - } - - // Insert the derived BiDi properties. - ucd.Parse(gen.OpenUCDFile("extracted/DerivedBidiClass.txt"), func(p *ucd.Parser) { - r := p.Rune(0) - class, ok := bidiClass[p.String(1)] - if !ok { - log.Fatalf("%U: Unknown BiDi class %q", r, p.String(1)) - } - insert(r, class) - }) - visitDefaults(insert) - - // TODO: use sparse blocks. This would reduce table size considerably - // from the looks of it. - - sz, err := t.Gen(w) - if err != nil { - log.Fatal(err) - } - w.Size += sz -} - -// dummy values to make methods in gen_common compile. The real versions -// will be generated by this file to tables.go. -var ( - xorMasks []rune -) diff --git a/components/cli/vendor/golang.org/x/text/unicode/bidi/gen_ranges.go b/components/cli/vendor/golang.org/x/text/unicode/bidi/gen_ranges.go deleted file mode 100644 index 51bd68fa7f..0000000000 --- a/components/cli/vendor/golang.org/x/text/unicode/bidi/gen_ranges.go +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build ignore - -package main - -import ( - "unicode" - - "golang.org/x/text/internal/gen" - "golang.org/x/text/internal/ucd" - "golang.org/x/text/unicode/rangetable" -) - -// These tables are hand-extracted from: -// http://www.unicode.org/Public/8.0.0/ucd/extracted/DerivedBidiClass.txt -func visitDefaults(fn func(r rune, c Class)) { - // first write default values for ranges listed above. - visitRunes(fn, AL, []rune{ - 0x0600, 0x07BF, // Arabic - 0x08A0, 0x08FF, // Arabic Extended-A - 0xFB50, 0xFDCF, // Arabic Presentation Forms - 0xFDF0, 0xFDFF, - 0xFE70, 0xFEFF, - 0x0001EE00, 0x0001EEFF, // Arabic Mathematical Alpha Symbols - }) - visitRunes(fn, R, []rune{ - 0x0590, 0x05FF, // Hebrew - 0x07C0, 0x089F, // Nko et al. - 0xFB1D, 0xFB4F, - 0x00010800, 0x00010FFF, // Cypriot Syllabary et. al. - 0x0001E800, 0x0001EDFF, - 0x0001EF00, 0x0001EFFF, - }) - visitRunes(fn, ET, []rune{ // European Terminator - 0x20A0, 0x20Cf, // Currency symbols - }) - rangetable.Visit(unicode.Noncharacter_Code_Point, func(r rune) { - fn(r, BN) // Boundary Neutral - }) - ucd.Parse(gen.OpenUCDFile("DerivedCoreProperties.txt"), func(p *ucd.Parser) { - if p.String(1) == "Default_Ignorable_Code_Point" { - fn(p.Rune(0), BN) // Boundary Neutral - } - }) -} - -func visitRunes(fn func(r rune, c Class), c Class, runes []rune) { - for i := 0; i < len(runes); i += 2 { - lo, hi := runes[i], runes[i+1] - for j := lo; j <= hi; j++ { - fn(j, c) - } - } -} diff --git a/components/cli/vendor/golang.org/x/text/unicode/bidi/gen_trieval.go b/components/cli/vendor/golang.org/x/text/unicode/bidi/gen_trieval.go deleted file mode 100644 index 9cb9942894..0000000000 --- a/components/cli/vendor/golang.org/x/text/unicode/bidi/gen_trieval.go +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build ignore - -package main - -// Class is the Unicode BiDi class. Each rune has a single class. -type Class uint - -const ( - L Class = iota // LeftToRight - R // RightToLeft - EN // EuropeanNumber - ES // EuropeanSeparator - ET // EuropeanTerminator - AN // ArabicNumber - CS // CommonSeparator - B // ParagraphSeparator - S // SegmentSeparator - WS // WhiteSpace - ON // OtherNeutral - BN // BoundaryNeutral - NSM // NonspacingMark - AL // ArabicLetter - Control // Control LRO - PDI - - numClass - - LRO // LeftToRightOverride - RLO // RightToLeftOverride - LRE // LeftToRightEmbedding - RLE // RightToLeftEmbedding - PDF // PopDirectionalFormat - LRI // LeftToRightIsolate - RLI // RightToLeftIsolate - FSI // FirstStrongIsolate - PDI // PopDirectionalIsolate - - unknownClass = ^Class(0) -) - -var controlToClass = map[rune]Class{ - 0x202D: LRO, // LeftToRightOverride, - 0x202E: RLO, // RightToLeftOverride, - 0x202A: LRE, // LeftToRightEmbedding, - 0x202B: RLE, // RightToLeftEmbedding, - 0x202C: PDF, // PopDirectionalFormat, - 0x2066: LRI, // LeftToRightIsolate, - 0x2067: RLI, // RightToLeftIsolate, - 0x2068: FSI, // FirstStrongIsolate, - 0x2069: PDI, // PopDirectionalIsolate, -} - -// A trie entry has the following bits: -// 7..5 XOR mask for brackets -// 4 1: Bracket open, 0: Bracket close -// 3..0 Class type - -const ( - openMask = 0x10 - xorMaskShift = 5 -) diff --git a/components/cli/vendor/golang.org/x/text/unicode/cldr/base.go b/components/cli/vendor/golang.org/x/text/unicode/cldr/base.go deleted file mode 100644 index 2382f4d6da..0000000000 --- a/components/cli/vendor/golang.org/x/text/unicode/cldr/base.go +++ /dev/null @@ -1,100 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cldr - -import ( - "encoding/xml" - "regexp" - "strconv" -) - -// Elem is implemented by every XML element. -type Elem interface { - setEnclosing(Elem) - setName(string) - enclosing() Elem - - GetCommon() *Common -} - -type hidden struct { - CharData string `xml:",chardata"` - Alias *struct { - Common - Source string `xml:"source,attr"` - Path string `xml:"path,attr"` - } `xml:"alias"` - Def *struct { - Common - Choice string `xml:"choice,attr,omitempty"` - Type string `xml:"type,attr,omitempty"` - } `xml:"default"` -} - -// Common holds several of the most common attributes and sub elements -// of an XML element. -type Common struct { - XMLName xml.Name - name string - enclElem Elem - Type string `xml:"type,attr,omitempty"` - Reference string `xml:"reference,attr,omitempty"` - Alt string `xml:"alt,attr,omitempty"` - ValidSubLocales string `xml:"validSubLocales,attr,omitempty"` - Draft string `xml:"draft,attr,omitempty"` - hidden -} - -// Default returns the default type to select from the enclosed list -// or "" if no default value is specified. -func (e *Common) Default() string { - if e.Def == nil { - return "" - } - if e.Def.Choice != "" { - return e.Def.Choice - } else if e.Def.Type != "" { - // Type is still used by the default element in collation. - return e.Def.Type - } - return "" -} - -// GetCommon returns e. It is provided such that Common implements Elem. -func (e *Common) GetCommon() *Common { - return e -} - -// Data returns the character data accumulated for this element. -func (e *Common) Data() string { - e.CharData = charRe.ReplaceAllStringFunc(e.CharData, replaceUnicode) - return e.CharData -} - -func (e *Common) setName(s string) { - e.name = s -} - -func (e *Common) enclosing() Elem { - return e.enclElem -} - -func (e *Common) setEnclosing(en Elem) { - e.enclElem = en -} - -// Escape characters that can be escaped without further escaping the string. -var charRe = regexp.MustCompile(`&#x[0-9a-fA-F]*;|\\u[0-9a-fA-F]{4}|\\U[0-9a-fA-F]{8}|\\x[0-9a-fA-F]{2}|\\[0-7]{3}|\\[abtnvfr]`) - -// replaceUnicode converts hexadecimal Unicode codepoint notations to a one-rune string. -// It assumes the input string is correctly formatted. -func replaceUnicode(s string) string { - if s[1] == '#' { - r, _ := strconv.ParseInt(s[3:len(s)-1], 16, 32) - return string(r) - } - r, _, _, _ := strconv.UnquoteChar(s, 0) - return string(r) -} diff --git a/components/cli/vendor/golang.org/x/text/unicode/cldr/cldr.go b/components/cli/vendor/golang.org/x/text/unicode/cldr/cldr.go deleted file mode 100644 index 2197f8ac26..0000000000 --- a/components/cli/vendor/golang.org/x/text/unicode/cldr/cldr.go +++ /dev/null @@ -1,130 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:generate go run makexml.go -output xml.go - -// Package cldr provides a parser for LDML and related XML formats. -// This package is intended to be used by the table generation tools -// for the various internationalization-related packages. -// As the XML types are generated from the CLDR DTD, and as the CLDR standard -// is periodically amended, this package may change considerably over time. -// This mostly means that data may appear and disappear between versions. -// That is, old code should keep compiling for newer versions, but data -// may have moved or changed. -// CLDR version 22 is the first version supported by this package. -// Older versions may not work. -package cldr // import "golang.org/x/text/unicode/cldr" - -import ( - "fmt" - "sort" -) - -// CLDR provides access to parsed data of the Unicode Common Locale Data Repository. -type CLDR struct { - parent map[string][]string - locale map[string]*LDML - resolved map[string]*LDML - bcp47 *LDMLBCP47 - supp *SupplementalData -} - -func makeCLDR() *CLDR { - return &CLDR{ - parent: make(map[string][]string), - locale: make(map[string]*LDML), - resolved: make(map[string]*LDML), - bcp47: &LDMLBCP47{}, - supp: &SupplementalData{}, - } -} - -// BCP47 returns the parsed BCP47 LDML data. If no such data was parsed, nil is returned. -func (cldr *CLDR) BCP47() *LDMLBCP47 { - return nil -} - -// Draft indicates the draft level of an element. -type Draft int - -const ( - Approved Draft = iota - Contributed - Provisional - Unconfirmed -) - -var drafts = []string{"unconfirmed", "provisional", "contributed", "approved", ""} - -// ParseDraft returns the Draft value corresponding to the given string. The -// empty string corresponds to Approved. -func ParseDraft(level string) (Draft, error) { - if level == "" { - return Approved, nil - } - for i, s := range drafts { - if level == s { - return Unconfirmed - Draft(i), nil - } - } - return Approved, fmt.Errorf("cldr: unknown draft level %q", level) -} - -func (d Draft) String() string { - return drafts[len(drafts)-1-int(d)] -} - -// SetDraftLevel sets which draft levels to include in the evaluated LDML. -// Any draft element for which the draft level is higher than lev will be excluded. -// If multiple draft levels are available for a single element, the one with the -// lowest draft level will be selected, unless preferDraft is true, in which case -// the highest draft will be chosen. -// It is assumed that the underlying LDML is canonicalized. -func (cldr *CLDR) SetDraftLevel(lev Draft, preferDraft bool) { - // TODO: implement - cldr.resolved = make(map[string]*LDML) -} - -// RawLDML returns the LDML XML for id in unresolved form. -// id must be one of the strings returned by Locales. -func (cldr *CLDR) RawLDML(loc string) *LDML { - return cldr.locale[loc] -} - -// LDML returns the fully resolved LDML XML for loc, which must be one of -// the strings returned by Locales. -func (cldr *CLDR) LDML(loc string) (*LDML, error) { - return cldr.resolve(loc) -} - -// Supplemental returns the parsed supplemental data. If no such data was parsed, -// nil is returned. -func (cldr *CLDR) Supplemental() *SupplementalData { - return cldr.supp -} - -// Locales returns the locales for which there exist files. -// Valid sublocales for which there is no file are not included. -// The root locale is always sorted first. -func (cldr *CLDR) Locales() []string { - loc := []string{"root"} - hasRoot := false - for l, _ := range cldr.locale { - if l == "root" { - hasRoot = true - continue - } - loc = append(loc, l) - } - sort.Strings(loc[1:]) - if !hasRoot { - return loc[1:] - } - return loc -} - -// Get fills in the fields of x based on the XPath path. -func Get(e Elem, path string) (res Elem, err error) { - return walkXPath(e, path) -} diff --git a/components/cli/vendor/golang.org/x/text/unicode/cldr/collate.go b/components/cli/vendor/golang.org/x/text/unicode/cldr/collate.go deleted file mode 100644 index 80ee28d795..0000000000 --- a/components/cli/vendor/golang.org/x/text/unicode/cldr/collate.go +++ /dev/null @@ -1,359 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cldr - -import ( - "bufio" - "encoding/xml" - "errors" - "fmt" - "strconv" - "strings" - "unicode" - "unicode/utf8" -) - -// RuleProcessor can be passed to Collator's Process method, which -// parses the rules and calls the respective method for each rule found. -type RuleProcessor interface { - Reset(anchor string, before int) error - Insert(level int, str, context, extend string) error - Index(id string) -} - -const ( - // cldrIndex is a Unicode-reserved sentinel value used to mark the start - // of a grouping within an index. - // We ignore any rule that starts with this rune. - // See http://unicode.org/reports/tr35/#Collation_Elements for details. - cldrIndex = "\uFDD0" - - // specialAnchor is the format in which to represent logical reset positions, - // such as "first tertiary ignorable". - specialAnchor = "<%s/>" -) - -// Process parses the rules for the tailorings of this collation -// and calls the respective methods of p for each rule found. -func (c Collation) Process(p RuleProcessor) (err error) { - if len(c.Cr) > 0 { - if len(c.Cr) > 1 { - return fmt.Errorf("multiple cr elements, want 0 or 1") - } - return processRules(p, c.Cr[0].Data()) - } - if c.Rules.Any != nil { - return c.processXML(p) - } - return errors.New("no tailoring data") -} - -// processRules parses rules in the Collation Rule Syntax defined in -// http://www.unicode.org/reports/tr35/tr35-collation.html#Collation_Tailorings. -func processRules(p RuleProcessor, s string) (err error) { - chk := func(s string, e error) string { - if err == nil { - err = e - } - return s - } - i := 0 // Save the line number for use after the loop. - scanner := bufio.NewScanner(strings.NewReader(s)) - for ; scanner.Scan() && err == nil; i++ { - for s := skipSpace(scanner.Text()); s != "" && s[0] != '#'; s = skipSpace(s) { - level := 5 - var ch byte - switch ch, s = s[0], s[1:]; ch { - case '&': // followed by or '[' ']' - if s = skipSpace(s); consume(&s, '[') { - s = chk(parseSpecialAnchor(p, s)) - } else { - s = chk(parseAnchor(p, 0, s)) - } - case '<': // sort relation '<'{1,4}, optionally followed by '*'. - for level = 1; consume(&s, '<'); level++ { - } - if level > 4 { - err = fmt.Errorf("level %d > 4", level) - } - fallthrough - case '=': // identity relation, optionally followed by *. - if consume(&s, '*') { - s = chk(parseSequence(p, level, s)) - } else { - s = chk(parseOrder(p, level, s)) - } - default: - chk("", fmt.Errorf("illegal operator %q", ch)) - break - } - } - } - if chk("", scanner.Err()); err != nil { - return fmt.Errorf("%d: %v", i, err) - } - return nil -} - -// parseSpecialAnchor parses the anchor syntax which is either of the form -// ['before' ] -// or -// [