diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 000000000000..a14fab44c34d --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,9 @@ +# Github code owners +# See https://github.com/blog/2392-introducing-code-owners + +cli/command/stack/** @dnephin @vdemeester +cli/compose/** @dnephin @vdemeester +contrib/completion/bash/** @albers +contrib/completion/zsh/** @sdurrheimer +docs/** @mstanleyjones @vdemeester @thaJeztah +scripts/** @dnephin diff --git a/Makefile b/Makefile index dbb3d3bfefc8..771f496abe11 100644 --- a/Makefile +++ b/Makefile @@ -3,57 +3,61 @@ # all: binary -# remove build artifacts + .PHONY: clean -clean: +clean: ## remove build artifacts rm -rf ./build/* cli/winresources/rsrc_* ./man/man[1-9] docs/yaml/gen -# run go test -# the "-tags daemon" part is temporary .PHONY: test -test: +test: ## run go test ./scripts/test/unit $(shell go list ./... | grep -v '/vendor/') .PHONY: test-coverage -test-coverage: +test-coverage: ## run test coverage ./scripts/test/unit-with-coverage $(shell go list ./... | grep -v '/vendor/') .PHONY: lint -lint: +lint: ## run all the lint tools gometalinter --config gometalinter.json ./... .PHONY: binary -binary: +binary: ## build executable for Linux @echo "WARNING: binary creates a Linux executable. Use cross for macOS or Windows." ./scripts/build/binary .PHONY: cross -cross: +cross: ## build executable for macOS and Windows ./scripts/build/cross .PHONY: dynbinary -dynbinary: +dynbinary: ## build dynamically linked binary ./scripts/build/dynbinary .PHONY: watch -watch: +watch: ## monitor file changes and run go test ./scripts/test/watch -# Check vendor matches vendor.conf -vendor: vendor.conf +vendor: vendor.conf ## check that vendor matches vendor.conf vndr 2> /dev/null scripts/validate/check-git-diff vendor -## generate man pages from go source and markdown .PHONY: manpages -manpages: +manpages: ## generate man pages from go source and markdown scripts/docs/generate-man.sh -## generate documentation YAML files consumed by docs repo .PHONY: yamldocs -yamldocs: +yamldocs: ## generate documentation YAML files consumed by docs repo scripts/docs/generate-yaml.sh +.PHONY: shellcheck +shellcheck: ## run shellcheck validation + scripts/validate/shellcheck + +.PHONY: help +help: ## print this help + @awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {sub("\\\\n",sprintf("\n%22c"," "), $$2);printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST) + + cli/compose/schema/bindata.go: cli/compose/schema/data/*.json go generate github.com/docker/cli/cli/compose/schema diff --git a/README.md b/README.md index 340556d8c77d..496d13f23c21 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,12 @@ Run all linting: $ make -f docker.Makefile lint ``` +List all the available targets: + +``` +$ make help +``` + ### In-container development environment Start an interactive development environment: diff --git a/VERSION b/VERSION index 3e9257aa26cf..fd2cab4039e4 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -17.07.0-dev +17.08.0-dev diff --git a/circle.yml b/circle.yml index 2035a25f5492..2a9c1967504b 100644 --- a/circle.yml +++ b/circle.yml @@ -4,10 +4,12 @@ jobs: lint: working_directory: /work - docker: [{image: 'docker:17.05-git'}] + docker: [{image: 'docker:17.06-git'}] steps: - checkout - - setup_remote_docker + - setup_remote_docker: + reusable: true + exclusive: false - run: command: docker version - run: @@ -15,62 +17,93 @@ 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'}] + docker: [{image: 'docker:17.06-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 test: working_directory: /work - docker: [{image: 'docker:17.05-git'}] + docker: [{image: 'docker:17.06-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 validate: working_directory: /work - docker: [{image: 'docker:17.05-git'}] + docker: [{image: 'docker:17.06-git'}] steps: - 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 + shellcheck: + working_directory: /work + docker: [{image: 'docker:17.06-git'}] + steps: + - checkout + - setup_remote_docker + - run: + name: "Run shellcheck" + command: | + dockerfile=dockerfiles/Dockerfile.shellcheck + echo "COPY . ." >> $dockerfile + docker build -f $dockerfile --tag cli-validator:$CIRCLE_BUILD_NUM . + docker run --rm cli-validator:$CIRCLE_BUILD_NUM \ + make -B shellcheck workflows: version: 2 ci: @@ -79,3 +112,4 @@ workflows: - cross - test - validate + - shellcheck diff --git a/cli/command/checkpoint/client_test.go b/cli/command/checkpoint/client_test.go new file mode 100644 index 000000000000..ca9171961755 --- /dev/null +++ b/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/cli/command/checkpoint/create_test.go b/cli/command/checkpoint/create_test.go new file mode 100644 index 000000000000..d0d47f456a9a --- /dev/null +++ b/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/cli/command/checkpoint/list_test.go b/cli/command/checkpoint/list_test.go new file mode 100644 index 000000000000..1c13f27755ed --- /dev/null +++ b/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/cli/command/checkpoint/remove_test.go b/cli/command/checkpoint/remove_test.go new file mode 100644 index 000000000000..ecc66d8be53d --- /dev/null +++ b/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/cli/command/checkpoint/testdata/checkpoint-list-with-options.golden b/cli/command/checkpoint/testdata/checkpoint-list-with-options.golden new file mode 100644 index 000000000000..f53f016ae9d6 --- /dev/null +++ b/cli/command/checkpoint/testdata/checkpoint-list-with-options.golden @@ -0,0 +1,2 @@ +CHECKPOINT NAME +checkpoint-foo diff --git a/cli/command/config/create_test.go b/cli/command/config/create_test.go index 25b133836f9a..5cdafbdbf4a4 100644 --- a/cli/command/config/create_test.go +++ b/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/cli/command/config/inspect_test.go b/cli/command/config/inspect_test.go index 69d36cb7ad62..e1af0b6b0977 100644 --- a/cli/command/config/inspect_test.go +++ b/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/cli/command/config/ls_test.go b/cli/command/config/ls_test.go index b43c764a4df9..c8393caca595 100644 --- a/cli/command/config/ls_test.go +++ b/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/cli/command/config/remove_test.go b/cli/command/config/remove_test.go index c183a93c8b0c..85b188c41d2f 100644 --- a/cli/command/config/remove_test.go +++ b/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/cli/command/container/attach_test.go b/cli/command/container/attach_test.go index 14b8137daee6..a33eeeeb5460 100644 --- a/cli/command/container/attach_test.go +++ b/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/cli/command/container/exec_test.go b/cli/command/container/exec_test.go index b2df1c2b0c75..0eed2ff0f7db 100644 --- a/cli/command/container/exec_test.go +++ b/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/cli/command/container/run.go b/cli/command/container/run.go index 56f0d0d57b16..695a5cf9ae56 100644 --- a/cli/command/container/run.go +++ b/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/cli/command/formatter/disk_usage.go b/cli/command/formatter/disk_usage.go index 2c73d8298792..5681f296cb35 100644 --- a/cli/command/formatter/disk_usage.go +++ b/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/cli/command/formatter/stats.go b/cli/command/formatter/stats.go index f53387e90a61..06eedc715873 100644 --- a/cli/command/formatter/stats.go +++ b/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/cli/command/image/build_test.go b/cli/command/image/build_test.go index bf77292a85e9..b3fb3c6834c9 100644 --- a/cli/command/image/build_test.go +++ b/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/cli/command/image/history_test.go b/cli/command/image/history_test.go index 8582c09b6219..b3abd0bef7d4 100644 --- a/cli/command/image/history_test.go +++ b/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/cli/command/image/import_test.go b/cli/command/image/import_test.go index 134722f0f1b1..6a8e2e0fd1de 100644 --- a/cli/command/image/import_test.go +++ b/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/cli/command/image/inspect_test.go b/cli/command/image/inspect_test.go index b3a2c2f5f5cf..2f336bdbad60 100644 --- a/cli/command/image/inspect_test.go +++ b/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/cli/command/image/list_test.go b/cli/command/image/list_test.go index 070b19efb1cd..b367ef1de15f 100644 --- a/cli/command/image/list_test.go +++ b/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/cli/command/image/load_test.go b/cli/command/image/load_test.go index ebe1a0c7e312..06446bf6501c 100644 --- a/cli/command/image/load_test.go +++ b/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/cli/command/image/prune_test.go b/cli/command/image/prune_test.go index c17a75d2243a..be25826df03c 100644 --- a/cli/command/image/prune_test.go +++ b/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/cli/command/image/pull_test.go b/cli/command/image/pull_test.go index 690e6222ebb1..c23484f832b7 100644 --- a/cli/command/image/pull_test.go +++ b/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/cli/command/image/push_test.go b/cli/command/image/push_test.go index f2c35dee21dc..2c824c46e2c3 100644 --- a/cli/command/image/push_test.go +++ b/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/cli/command/image/remove_test.go b/cli/command/image/remove_test.go index 9b02b24a908b..559427247d5a 100644 --- a/cli/command/image/remove_test.go +++ b/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/cli/command/image/save.go b/cli/command/image/save.go index ba666d274009..9cae97b3709c 100644 --- a/cli/command/image/save.go +++ b/cli/command/image/save.go @@ -2,6 +2,8 @@ package image import ( "io" + "os" + "path/filepath" "github.com/docker/cli/cli" "github.com/docker/cli/cli/command" @@ -41,6 +43,10 @@ func runSave(dockerCli command.Cli, opts saveOptions) error { return errors.New("cowardly refusing to save to a terminal. Use the -o flag or redirect") } + if err := validateOutputPath(opts.output); err != nil { + return errors.Wrap(err, "failed to save image") + } + responseBody, err := dockerCli.Client().ImageSave(context.Background(), opts.images) if err != nil { return err @@ -54,3 +60,13 @@ func runSave(dockerCli command.Cli, opts saveOptions) error { return command.CopyToFile(opts.output, responseBody) } + +func validateOutputPath(path string) error { + dir := filepath.Dir(path) + if dir != "" && dir != "." { + if _, err := os.Stat(dir); os.IsNotExist(err) { + return errors.Errorf("unable to validate output path: directory %q does not exist", dir) + } + } + return nil +} diff --git a/cli/command/image/save_test.go b/cli/command/image/save_test.go index d137dc92f9f9..1cac4c57498d 100644 --- a/cli/command/image/save_test.go +++ b/cli/command/image/save_test.go @@ -43,9 +43,14 @@ func TestNewSaveCommandErrors(t *testing.T) { return ioutil.NopCloser(strings.NewReader("")), errors.Errorf("error saving image") }, }, + { + name: "output directory does not exist", + args: []string{"-o", "fakedir/out.tar", "arg1"}, + expectedError: "failed to save image: unable to validate output path: directory \"fakedir\" does not exist", + }, } 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 +90,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/cli/command/image/tag_test.go b/cli/command/image/tag_test.go index 8cf0c534b88f..b537f9d627e4 100644 --- a/cli/command/image/tag_test.go +++ b/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/cli/command/image/testdata/inspect-command-success.simple-many.golden b/cli/command/image/testdata/inspect-command-success.simple-many.golden index d4042589f89b..f72c96f74e2c 100644 --- a/cli/command/image/testdata/inspect-command-success.simple-many.golden +++ b/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/cli/command/image/testdata/inspect-command-success.simple.golden b/cli/command/image/testdata/inspect-command-success.simple.golden index 802c52469b0a..878463ffc400 100644 --- a/cli/command/image/testdata/inspect-command-success.simple.golden +++ b/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/cli/command/network/client_test.go b/cli/command/network/client_test.go new file mode 100644 index 000000000000..722c72bd1856 --- /dev/null +++ b/cli/command/network/client_test.go @@ -0,0 +1,36 @@ +package network + +import ( + "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/network" + "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) + networkConnectFunc func(ctx context.Context, networkID, container string, config *network.EndpointSettings) error + networkDisconnectFunc func(ctx context.Context, networkID, container string, force bool) 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 +} + +func (c *fakeClient) NetworkConnect(ctx context.Context, networkID, container string, config *network.EndpointSettings) error { + if c.networkConnectFunc != nil { + return c.networkConnectFunc(ctx, networkID, container, config) + } + return nil +} + +func (c *fakeClient) NetworkDisconnect(ctx context.Context, networkID, container string, force bool) error { + if c.networkDisconnectFunc != nil { + return c.networkDisconnectFunc(ctx, networkID, container, force) + } + return nil +} diff --git a/cli/command/network/cmd.go b/cli/command/network/cmd.go index 97bcca2a8dec..48edf1c4e34e 100644 --- a/cli/command/network/cmd.go +++ b/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/cli/command/network/connect.go b/cli/command/network/connect.go index 19bd3c56aa06..9e925c344438 100644 --- a/cli/command/network/connect.go +++ b/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/cli/command/network/connect_test.go b/cli/command/network/connect_test.go new file mode 100644 index 000000000000..790ec25c21f7 --- /dev/null +++ b/cli/command/network/connect_test.go @@ -0,0 +1,70 @@ +package network + +import ( + "io/ioutil" + "testing" + + "github.com/docker/cli/cli/internal/test" + "github.com/docker/docker/api/types/network" + "github.com/docker/docker/pkg/testutil" + "github.com/pkg/errors" + "github.com/stretchr/testify/assert" + "golang.org/x/net/context" +) + +func TestNetworkConnectErrors(t *testing.T) { + testCases := []struct { + args []string + networkConnectFunc func(ctx context.Context, networkID, container string, config *network.EndpointSettings) error + expectedError string + }{ + { + expectedError: "requires exactly 2 argument(s)", + }, + { + args: []string{"toto", "titi"}, + networkConnectFunc: func(ctx context.Context, networkID, container string, config *network.EndpointSettings) error { + return errors.Errorf("error connecting network") + }, + expectedError: "error connecting network", + }, + } + + for _, tc := range testCases { + cmd := newConnectCommand( + test.NewFakeCli(&fakeClient{ + networkConnectFunc: tc.networkConnectFunc, + }), + ) + cmd.SetArgs(tc.args) + cmd.SetOutput(ioutil.Discard) + testutil.ErrorContains(t, cmd.Execute(), tc.expectedError) + + } +} + +func TestNetworkConnectWithFlags(t *testing.T) { + 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{ + networkConnectFunc: func(ctx context.Context, networkID, container string, config *network.EndpointSettings) error { + assert.Equal(t, expectedOpts, config.IPAMConfig, "not expected driver error") + return 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()) +} diff --git a/cli/command/network/create.go b/cli/command/network/create.go index ed6d2de7bdfa..33bbdef5bec8 100644 --- a/cli/command/network/create.go +++ b/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/cli/command/network/create_test.go b/cli/command/network/create_test.go new file mode 100644 index 000000000000..76c760d0adca --- /dev/null +++ b/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/cli/command/network/disconnect.go b/cli/command/network/disconnect.go index 0f7d7c2b98bf..ab866cf2c150 100644 --- a/cli/command/network/disconnect.go +++ b/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/cli/command/network/disconnect_test.go b/cli/command/network/disconnect_test.go new file mode 100644 index 000000000000..01cba2ff3662 --- /dev/null +++ b/cli/command/network/disconnect_test.go @@ -0,0 +1,41 @@ +package network + +import ( + "io/ioutil" + "testing" + + "github.com/docker/cli/cli/internal/test" + "github.com/docker/docker/pkg/testutil" + "github.com/pkg/errors" + "golang.org/x/net/context" +) + +func TestNetworkDisconnectErrors(t *testing.T) { + testCases := []struct { + args []string + networkDisconnectFunc func(ctx context.Context, networkID, container string, force bool) error + expectedError string + }{ + { + expectedError: "requires exactly 2 argument(s)", + }, + { + args: []string{"toto", "titi"}, + networkDisconnectFunc: func(ctx context.Context, networkID, container string, force bool) error { + return errors.Errorf("error disconnecting network") + }, + expectedError: "error disconnecting network", + }, + } + + for _, tc := range testCases { + cmd := newDisconnectCommand( + test.NewFakeCli(&fakeClient{ + networkDisconnectFunc: tc.networkDisconnectFunc, + }), + ) + cmd.SetArgs(tc.args) + cmd.SetOutput(ioutil.Discard) + testutil.ErrorContains(t, cmd.Execute(), tc.expectedError) + } +} diff --git a/cli/command/network/inspect.go b/cli/command/network/inspect.go index 9856c04e4cf8..e4c2e5fb8929 100644 --- a/cli/command/network/inspect.go +++ b/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/cli/command/network/list.go b/cli/command/network/list.go index 79a860f9b3f4..8a7c1f261d4a 100644 --- a/cli/command/network/list.go +++ b/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/cli/command/network/remove.go b/cli/command/network/remove.go index 7dfe8da2f764..3de7bdad3818 100644 --- a/cli/command/network/remove.go +++ b/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/cli/command/node/demote_test.go b/cli/command/node/demote_test.go index 7126dddd13b5..d786cd47a29d 100644 --- a/cli/command/node/demote_test.go +++ b/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/cli/command/node/inspect_test.go b/cli/command/node/inspect_test.go index 2a21e12a282a..ca88371f8a75 100644 --- a/cli/command/node/inspect_test.go +++ b/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/cli/command/node/list.go b/cli/command/node/list.go index 0c3d7e1abc1a..7dac795663df 100644 --- a/cli/command/node/list.go +++ b/cli/command/node/list.go @@ -1,15 +1,27 @@ package node import ( + "sort" + "github.com/docker/cli/cli" "github.com/docker/cli/cli/command" "github.com/docker/cli/cli/command/formatter" "github.com/docker/cli/opts" "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/swarm" "github.com/spf13/cobra" "golang.org/x/net/context" + "vbom.ml/util/sortorder" ) +type byHostname []swarm.Node + +func (n byHostname) Len() int { return len(n) } +func (n byHostname) Swap(i, j int) { n[i], n[j] = n[j], n[i] } +func (n byHostname) Less(i, j int) bool { + return sortorder.NaturalLess(n[i].Description.Hostname, n[j].Description.Hostname) +} + type listOptions struct { quiet bool format string @@ -68,5 +80,6 @@ func runList(dockerCli command.Cli, options listOptions) error { Output: dockerCli.Out(), Format: formatter.NewNodeFormat(format, options.quiet), } + sort.Sort(byHostname(nodes)) return formatter.NodeWrite(nodesCtx, nodes, info) } diff --git a/cli/command/node/list_test.go b/cli/command/node/list_test.go index c4538ba1413a..f579ebc88ac6 100644 --- a/cli/command/node/list_test.go +++ b/cli/command/node/list_test.go @@ -9,6 +9,8 @@ import ( "github.com/docker/cli/cli/internal/test" "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/swarm" + "github.com/docker/docker/pkg/testutil" + "github.com/docker/docker/pkg/testutil/golden" "github.com/pkg/errors" // Import builders to get the builder function as package function . "github.com/docker/cli/cli/internal/test/builders" @@ -42,12 +44,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 +55,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 +70,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 +98,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 +106,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 +122,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 +134,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 +149,7 @@ func TestNodeListFormat(t *testing.T) { }, nil }, }, buf) - cli.SetConfigfile(&configfile.ConfigFile{ + cli.SetConfigFile(&configfile.ConfigFile{ NodesFormat: "{{.ID}}: {{.Hostname}} {{.Status}}/{{.ManagerStatus}}", }) cmd := newListCommand(cli) @@ -160,3 +158,22 @@ func TestNodeListFormat(t *testing.T) { assert.Contains(t, buf.String(), `nodeHostname1: Leader`) assert.Contains(t, buf.String(), `nodeHostname2: Reachable`) } + +func TestNodeListOrder(t *testing.T) { + cli := test.NewFakeCli(&fakeClient{ + nodeListFunc: func() ([]swarm.Node, error) { + return []swarm.Node{ + *Node(Hostname("node-2-foo"), Manager(Leader())), + *Node(Hostname("node-10-foo"), Manager()), + *Node(Hostname("node-1-foo")), + }, nil + + }, + }) + cmd := newListCommand(cli) + cmd.Flags().Set("format", "{{.Hostname}}: {{.ManagerStatus}}") + assert.NoError(t, cmd.Execute()) + actual := cli.OutBuffer().String() + expected := golden.Get(t, []byte(actual), "node-list-sort.golden") + testutil.EqualNormalizedString(t, testutil.RemoveSpace, actual, string(expected)) +} diff --git a/cli/command/node/promote_test.go b/cli/command/node/promote_test.go index 495bdfe60d1b..95e067eb15cd 100644 --- a/cli/command/node/promote_test.go +++ b/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/cli/command/node/ps.go b/cli/command/node/ps.go index 6a586a3bcc62..5212e596f3a7 100644 --- a/cli/command/node/ps.go +++ b/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/cli/command/node/ps_test.go b/cli/command/node/ps_test.go index d25a55f0cfc0..d3ef6f30a2fe 100644 --- a/cli/command/node/ps_test.go +++ b/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/cli/command/node/remove_test.go b/cli/command/node/remove_test.go index 7123288f47b3..81daa2f02538 100644 --- a/cli/command/node/remove_test.go +++ b/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/cli/command/node/testdata/node-list-sort.golden b/cli/command/node/testdata/node-list-sort.golden new file mode 100644 index 000000000000..e2f28119946b --- /dev/null +++ b/cli/command/node/testdata/node-list-sort.golden @@ -0,0 +1,3 @@ +node-1-foo: +node-2-foo: Leader +node-10-foo: Reachable diff --git a/cli/command/node/update_test.go b/cli/command/node/update_test.go index 0085934b9c11..3abb720c1c19 100644 --- a/cli/command/node/update_test.go +++ b/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/cli/command/prune/prune.go b/cli/command/prune/prune.go deleted file mode 100644 index e916a8283eec..000000000000 --- a/cli/command/prune/prune.go +++ /dev/null @@ -1,51 +0,0 @@ -package prune - -import ( - "github.com/docker/cli/cli/command" - "github.com/docker/cli/cli/command/container" - "github.com/docker/cli/cli/command/image" - "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) -} - -// RunVolumePrune executes a prune command for volumes -func RunVolumePrune(dockerCli command.Cli, filter opts.FilterOpt) (uint64, string, error) { - return volume.RunPrune(dockerCli, filter) -} - -// RunImagePrune executes a prune command for images -func RunImagePrune(dockerCli command.Cli, all bool, filter opts.FilterOpt) (uint64, string, error) { - return image.RunPrune(dockerCli, all, filter) -} - -// RunNetworkPrune executes a prune command for networks -func RunNetworkPrune(dockerCli command.Cli, filter opts.FilterOpt) (uint64, string, error) { - return network.RunPrune(dockerCli, filter) -} diff --git a/cli/command/registry/login.go b/cli/command/registry/login.go index 4ffca2bed2cd..938fef8ab7d0 100644 --- a/cli/command/registry/login.go +++ b/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/cli/command/registry_test.go b/cli/command/registry_test.go index f6adeb49f44b..5e52e470a186 100644 --- a/cli/command/registry_test.go +++ b/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/cli/command/secret/create_test.go b/cli/command/secret/create_test.go index 197483cf706d..2c4f9f5d9cb5 100644 --- a/cli/command/secret/create_test.go +++ b/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/cli/command/secret/inspect_test.go b/cli/command/secret/inspect_test.go index 07a3d7a3137b..093624ddfed9 100644 --- a/cli/command/secret/inspect_test.go +++ b/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/cli/command/secret/ls_test.go b/cli/command/secret/ls_test.go index 5d2103cb2aa7..fb033efea6ec 100644 --- a/cli/command/secret/ls_test.go +++ b/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/cli/command/secret/remove_test.go b/cli/command/secret/remove_test.go index 08443ec9ae0f..6e5ab5fb6c36 100644 --- a/cli/command/secret/remove_test.go +++ b/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/cli/command/service/client_test.go b/cli/command/service/client_test.go new file mode 100644 index 000000000000..b4f890515978 --- /dev/null +++ b/cli/command/service/client_test.go @@ -0,0 +1,35 @@ +package service + +import ( + "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/swarm" + "github.com/docker/docker/client" + "golang.org/x/net/context" +) + +type fakeClient struct { + client.Client + serviceListFunc func(context.Context, types.ServiceListOptions) ([]swarm.Service, error) +} + +func (f *fakeClient) ServiceList(ctx context.Context, options types.ServiceListOptions) ([]swarm.Service, error) { + if f.serviceListFunc != nil { + return f.serviceListFunc(ctx, options) + } + return nil, nil +} + +func (f *fakeClient) TaskList(ctx context.Context, options types.TaskListOptions) ([]swarm.Task, error) { + return nil, nil +} + +func (f *fakeClient) NodeList(ctx context.Context, options types.NodeListOptions) ([]swarm.Node, error) { + return nil, nil +} + +func newService(id string, name string) swarm.Service { + return swarm.Service{ + ID: id, + Spec: swarm.ServiceSpec{Annotations: swarm.Annotations{Name: name}}, + } +} diff --git a/cli/command/service/list.go b/cli/command/service/list.go index 5b359d307a96..63adce1ec165 100644 --- a/cli/command/service/list.go +++ b/cli/command/service/list.go @@ -2,6 +2,9 @@ package service import ( "fmt" + "sort" + + "vbom.ml/util/sortorder" "github.com/docker/cli/cli" "github.com/docker/cli/cli/command" @@ -20,7 +23,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{ @@ -41,7 +44,13 @@ func newListCommand(dockerCli *command.DockerCli) *cobra.Command { return cmd } -func runList(dockerCli *command.DockerCli, options listOptions) error { +type byName []swarm.Service + +func (n byName) Len() int { return len(n) } +func (n byName) Swap(i, j int) { n[i], n[j] = n[j], n[i] } +func (n byName) Less(i, j int) bool { return sortorder.NaturalLess(n[i].Spec.Name, n[j].Spec.Name) } + +func runList(dockerCli command.Cli, options listOptions) error { ctx := context.Background() client := dockerCli.Client() @@ -51,6 +60,7 @@ func runList(dockerCli *command.DockerCli, options listOptions) error { return err } + sort.Sort(byName(services)) info := map[string]formatter.ServiceListInfo{} if len(services) > 0 && !options.quiet { // only non-empty services and not quiet, should we call TaskList and NodeList api diff --git a/cli/command/service/list_test.go b/cli/command/service/list_test.go new file mode 100644 index 000000000000..85ccd1fb7949 --- /dev/null +++ b/cli/command/service/list_test.go @@ -0,0 +1,32 @@ +package service + +import ( + "testing" + + "golang.org/x/net/context" + + "github.com/docker/cli/cli/internal/test" + "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/swarm" + "github.com/docker/docker/pkg/testutil" + "github.com/docker/docker/pkg/testutil/golden" + "github.com/stretchr/testify/assert" +) + +func TestServiceListOrder(t *testing.T) { + cli := test.NewFakeCli(&fakeClient{ + serviceListFunc: func(ctx context.Context, options types.ServiceListOptions) ([]swarm.Service, error) { + return []swarm.Service{ + newService("a57dbe8", "service-1-foo"), + newService("a57dbdd", "service-10-foo"), + newService("aaaaaaa", "service-2-foo"), + }, nil + }, + }) + cmd := newListCommand(cli) + cmd.Flags().Set("format", "{{.Name}}") + assert.NoError(t, cmd.Execute()) + actual := cli.OutBuffer().String() + expected := golden.Get(t, []byte(actual), "service-list-sort.golden") + testutil.EqualNormalizedString(t, testutil.RemoveSpace, actual, string(expected)) +} diff --git a/cli/command/service/progress/progress.go b/cli/command/service/progress/progress.go index d522fc08b44f..adff4868480c 100644 --- a/cli/command/service/progress/progress.go +++ b/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,30 +329,72 @@ func (u *replicatedProgressUpdater) update(service swarm.Service, tasks []swarm. return running == replicas, nil } -type globalProgressUpdater struct { - progressOut progress.Output - - initialized bool - 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 +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. - tasksByNode := make(map[string]swarm.Task) + tasksBySlot := make(map[int]swarm.Task) for _, task := range tasks { - if numberedStates[task.DesiredState] == 0 { + 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] { + 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 } } - tasksByNode[task.NodeID] = task + 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 + + initialized bool + done bool +} + +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 // for all eligible nodes at the same time, so we should see all those @@ -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/cli/command/service/progress/progress_test.go b/cli/command/service/progress/progress_test.go new file mode 100644 index 000000000000..d1c118f7d71a --- /dev/null +++ b/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/cli/command/service/ps.go b/cli/command/service/ps.go index 741f6b589f2b..07dbba72302d 100644 --- a/cli/command/service/ps.go +++ b/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/cli/command/service/ps_test.go b/cli/command/service/ps_test.go index a53748d6d3e9..dac79ab50ac5 100644 --- a/cli/command/service/ps_test.go +++ b/cli/command/service/ps_test.go @@ -10,35 +10,11 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/swarm" - "github.com/docker/docker/client" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "golang.org/x/net/context" ) -type fakeClient struct { - client.Client - serviceListFunc func(context.Context, types.ServiceListOptions) ([]swarm.Service, error) -} - -func (f *fakeClient) ServiceList(ctx context.Context, options types.ServiceListOptions) ([]swarm.Service, error) { - if f.serviceListFunc != nil { - return f.serviceListFunc(ctx, options) - } - return nil, nil -} - -func (f *fakeClient) TaskList(ctx context.Context, options types.TaskListOptions) ([]swarm.Task, error) { - return nil, nil -} - -func newService(id string, name string) swarm.Service { - return swarm.Service{ - ID: id, - Spec: swarm.ServiceSpec{Annotations: swarm.Annotations{Name: name}}, - } -} - func TestCreateFilter(t *testing.T) { client := &fakeClient{ serviceListFunc: func(ctx context.Context, options types.ServiceListOptions) ([]swarm.Service, error) { @@ -107,7 +83,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/cli/command/service/scale.go b/cli/command/service/scale.go index 397fe1800cb2..f58786156a7d 100644 --- a/cli/command/service/scale.go +++ b/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/cli/command/service/testdata/service-list-sort.golden b/cli/command/service/testdata/service-list-sort.golden new file mode 100644 index 000000000000..3b0cb2144d69 --- /dev/null +++ b/cli/command/service/testdata/service-list-sort.golden @@ -0,0 +1,3 @@ +service-1-foo +service-2-foo +service-10-foo diff --git a/cli/command/stack/client_test.go b/cli/command/stack/client_test.go index 50442783fa0a..d1d85193e756 100644 --- a/cli/command/stack/client_test.go +++ b/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/cli/command/stack/deploy_composefile.go b/cli/command/stack/deploy_composefile.go index 8e5dfed4d5e8..1f50ae1a1d82 100644 --- a/cli/command/stack/deploy_composefile.go +++ b/cli/command/stack/deploy_composefile.go @@ -171,13 +171,18 @@ func validateExternalNetworks( externalNetworks []string, ) error { for _, networkName := range externalNetworks { + if !container.NetworkMode(networkName).IsUserDefined() { + // Networks that are not user defined always exist on all nodes as + // local-scoped networks, so there's no need to inspect them. + continue + } network, err := client.NetworkInspect(ctx, networkName, types.NetworkInspectOptions{}) switch { case dockerclient.IsErrNotFound(err): return errors.Errorf("network %q is declared as external, but could not be found. You need to create a swarm-scoped network before the stack is deployed", networkName) case err != nil: return err - case container.NetworkMode(networkName).IsUserDefined() && network.Scope != "swarm": + case network.Scope != "swarm": return errors.Errorf("network %q is declared as external, but it is not in the right scope: %q instead of \"swarm\"", networkName, network.Scope) } } diff --git a/cli/command/stack/deploy_composefile_test.go b/cli/command/stack/deploy_composefile_test.go index 5d4813bc05b1..5d59ff7028e9 100644 --- a/cli/command/stack/deploy_composefile_test.go +++ b/cli/command/stack/deploy_composefile_test.go @@ -56,7 +56,8 @@ func TestValidateExternalNetworks(t *testing.T) { expectedMsg: "Unexpected", }, { - network: "host", + inspectError: errors.New("host net does not exist on swarm classic"), + network: "host", }, { network: "user", diff --git a/cli/command/stack/deploy_test.go b/cli/command/stack/deploy_test.go index ffdd7596994e..c04f86c25104 100644 --- a/cli/command/stack/deploy_test.go +++ b/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/cli/command/stack/list.go b/cli/command/stack/list.go index f3781d260c5e..24da30512fa0 100644 --- a/cli/command/stack/list.go +++ b/cli/command/stack/list.go @@ -12,6 +12,7 @@ import ( "github.com/pkg/errors" "github.com/spf13/cobra" "golang.org/x/net/context" + "vbom.ml/util/sortorder" ) type listOptions struct { @@ -60,7 +61,7 @@ type byName []*formatter.Stack func (n byName) Len() int { return len(n) } func (n byName) Swap(i, j int) { n[i], n[j] = n[j], n[i] } -func (n byName) Less(i, j int) bool { return n[i].Name < n[j].Name } +func (n byName) Less(i, j int) bool { return sortorder.NaturalLess(n[i].Name, n[j].Name) } func getStacks(ctx context.Context, apiclient client.APIClient) ([]*formatter.Stack, error) { services, err := apiclient.ServiceList( diff --git a/cli/command/stack/list_test.go b/cli/command/stack/list_test.go index 4f258977eda5..48b141653f5a 100644 --- a/cli/command/stack/list_test.go +++ b/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( @@ -98,10 +98,13 @@ func TestListWithoutFormat(t *testing.T) { } func TestListOrder(t *testing.T) { - buf := new(bytes.Buffer) - cmd := newListCommand(test.NewFakeCli(&fakeClient{ - serviceListFunc: func(options types.ServiceListOptions) ([]swarm.Service, error) { - return []swarm.Service{ + usecases := []struct { + golden string + swarmServices []swarm.Service + }{ + { + golden: "stack-list-sort.golden", + swarmServices: []swarm.Service{ *Service( ServiceLabels(map[string]string{ "com.docker.stack.namespace": "service-name-foo", @@ -112,11 +115,40 @@ func TestListOrder(t *testing.T) { "com.docker.stack.namespace": "service-name-bar", }), ), - }, nil + }, }, - }, buf)) - assert.NoError(t, cmd.Execute()) - actual := buf.String() - expected := golden.Get(t, []byte(actual), "stack-list-sort.golden") - testutil.EqualNormalizedString(t, testutil.RemoveSpace, actual, string(expected)) + { + golden: "stack-list-sort-natural.golden", + swarmServices: []swarm.Service{ + *Service( + ServiceLabels(map[string]string{ + "com.docker.stack.namespace": "service-name-1-foo", + }), + ), + *Service( + ServiceLabels(map[string]string{ + "com.docker.stack.namespace": "service-name-10-foo", + }), + ), + *Service( + ServiceLabels(map[string]string{ + "com.docker.stack.namespace": "service-name-2-foo", + }), + ), + }, + }, + } + + for _, uc := range usecases { + buf := new(bytes.Buffer) + cmd := newListCommand(test.NewFakeCliWithOutput(&fakeClient{ + serviceListFunc: func(options types.ServiceListOptions) ([]swarm.Service, error) { + return uc.swarmServices, nil + }, + }, buf)) + assert.NoError(t, cmd.Execute()) + actual := buf.String() + expected := golden.Get(t, []byte(actual), uc.golden) + testutil.EqualNormalizedString(t, testutil.RemoveSpace, actual, string(expected)) + } } diff --git a/cli/command/stack/ps.go b/cli/command/stack/ps.go index ae9ed0f70a1c..25bd1eee108f 100644 --- a/cli/command/stack/ps.go +++ b/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/cli/command/stack/ps_test.go b/cli/command/stack/ps_test.go index afda419eb492..5387dd034715 100644 --- a/cli/command/stack/ps_test.go +++ b/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/cli/command/stack/remove.go b/cli/command/stack/remove.go index 20d3ee71dbed..d95171aabf73 100644 --- a/cli/command/stack/remove.go +++ b/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/cli/command/stack/remove_test.go b/cli/command/stack/remove_test.go index 498416ebe86e..88ad8a07d3da 100644 --- a/cli/command/stack/remove_test.go +++ b/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/cli/command/stack/services.go b/cli/command/stack/services.go index 5b59c479c6f8..94fcb8bdedcb 100644 --- a/cli/command/stack/services.go +++ b/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/cli/command/stack/services_test.go b/cli/command/stack/services_test.go index a87174a14df3..822660fbc2df 100644 --- a/cli/command/stack/services_test.go +++ b/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/cli/command/stack/testdata/stack-list-sort-natural.golden b/cli/command/stack/testdata/stack-list-sort-natural.golden new file mode 100644 index 000000000000..09507fbf40ea --- /dev/null +++ b/cli/command/stack/testdata/stack-list-sort-natural.golden @@ -0,0 +1,4 @@ +NAME SERVICES +service-name-1-foo 1 +service-name-2-foo 1 +service-name-10-foo 1 diff --git a/cli/command/swarm/ca.go b/cli/command/swarm/ca.go index 2f01ab4da4cf..1c2f2d268b9e 100644 --- a/cli/command/swarm/ca.go +++ b/cli/command/swarm/ca.go @@ -3,23 +3,22 @@ package swarm import ( "fmt" "io" - "strings" - - "golang.org/x/net/context" - "io/ioutil" + "strings" "github.com/docker/cli/cli" "github.com/docker/cli/cli/command" "github.com/docker/cli/cli/command/swarm/progress" "github.com/docker/docker/api/types/swarm" "github.com/docker/docker/pkg/jsonmessage" + "github.com/pkg/errors" "github.com/spf13/cobra" "github.com/spf13/pflag" + "golang.org/x/net/context" ) type caOptions struct { - swarmOptions + swarmCAOptions rootCACert PEMFile rootCAKey PEMFile rotate bool @@ -27,21 +26,21 @@ type caOptions struct { quiet bool } -func newRotateCACommand(dockerCli command.Cli) *cobra.Command { +func newCACommand(dockerCli command.Cli) *cobra.Command { opts := caOptions{} cmd := &cobra.Command{ Use: "ca [OPTIONS]", - Short: "Manage root CA", + Short: "Display and rotate the root CA", Args: cli.NoArgs, RunE: func(cmd *cobra.Command, args []string) error { - return runRotateCA(dockerCli, cmd.Flags(), opts) + return runCA(dockerCli, cmd.Flags(), opts) }, Tags: map[string]string{"version": "1.30"}, } flags := cmd.Flags() - addSwarmCAFlags(flags, &opts.swarmOptions) + addSwarmCAFlags(flags, &opts.swarmCAOptions) flags.BoolVar(&opts.rotate, flagRotate, false, "Rotate the swarm CA - if no certificate or key are provided, new ones will be generated") flags.Var(&opts.rootCACert, flagCACert, "Path to the PEM-formatted root CA certificate to use for the new cluster") flags.Var(&opts.rootCAKey, flagCAKey, "Path to the PEM-formatted root CA key to use for the new cluster") @@ -51,7 +50,7 @@ func newRotateCACommand(dockerCli command.Cli) *cobra.Command { return cmd } -func runRotateCA(dockerCli command.Cli, flags *pflag.FlagSet, opts caOptions) error { +func runCA(dockerCli command.Cli, flags *pflag.FlagSet, opts caOptions) error { client := dockerCli.Client() ctx := context.Background() @@ -61,36 +60,15 @@ func runRotateCA(dockerCli command.Cli, flags *pflag.FlagSet, opts caOptions) er } 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) } } - if swarmInspect.ClusterInfo.TLSInfo.TrustRoot == "" { - fmt.Fprintln(dockerCli.Out(), "No CA information available") - } else { - fmt.Fprintln(dockerCli.Out(), strings.TrimSpace(swarmInspect.ClusterInfo.TLSInfo.TrustRoot)) - } - return nil - } - - genRootCA := true - spec := &swarmInspect.Spec - opts.mergeSwarmSpec(spec, flags) // updates the spec given the cert expiry or external CA flag - if flags.Changed(flagCACert) { - spec.CAConfig.SigningCACert = opts.rootCACert.Contents() - genRootCA = false - } - if flags.Changed(flagCAKey) { - spec.CAConfig.SigningCAKey = opts.rootCAKey.Contents() - genRootCA = false - } - if genRootCA { - spec.CAConfig.ForceRotate++ - spec.CAConfig.SigningCACert = "" - spec.CAConfig.SigningCAKey = "" + return displayTrustRoot(dockerCli.Out(), swarmInspect) } + updateSwarmSpec(&swarmInspect.Spec, flags, opts) if err := client.SwarmUpdate(ctx, swarmInspect.Version, swarmInspect.Spec, swarm.UpdateFlags{}); err != nil { return err } @@ -98,7 +76,29 @@ func runRotateCA(dockerCli command.Cli, flags *pflag.FlagSet, opts caOptions) er if opts.detach { return nil } + return attach(ctx, dockerCli, opts) +} + +func updateSwarmSpec(spec *swarm.Spec, flags *pflag.FlagSet, opts caOptions) { + opts.mergeSwarmSpecCAFlags(spec, flags) + caCert := opts.rootCACert.Contents() + caKey := opts.rootCAKey.Contents() + + if caCert != "" { + spec.CAConfig.SigningCACert = caCert + } + if caKey != "" { + spec.CAConfig.SigningCAKey = caKey + } + if caKey == "" && caCert == "" { + spec.CAConfig.ForceRotate++ + spec.CAConfig.SigningCACert = "" + spec.CAConfig.SigningCAKey = "" + } +} +func attach(ctx context.Context, dockerCli command.Cli, opts caOptions) error { + client := dockerCli.Client() errChan := make(chan error, 1) pipeReader, pipeWriter := io.Pipe() @@ -111,7 +111,7 @@ func runRotateCA(dockerCli command.Cli, flags *pflag.FlagSet, opts caOptions) er return <-errChan } - err = jsonmessage.DisplayJSONMessagesToStream(pipeReader, dockerCli.Out(), nil) + err := jsonmessage.DisplayJSONMessagesToStream(pipeReader, dockerCli.Out(), nil) if err == nil { err = <-errChan } @@ -119,15 +119,17 @@ func runRotateCA(dockerCli command.Cli, flags *pflag.FlagSet, opts caOptions) er return err } - swarmInspect, err = client.SwarmInspect(ctx) + swarmInspect, err := client.SwarmInspect(ctx) if err != nil { return err } + return displayTrustRoot(dockerCli.Out(), swarmInspect) +} - if swarmInspect.ClusterInfo.TLSInfo.TrustRoot == "" { - fmt.Fprintln(dockerCli.Out(), "No CA information available") - } else { - fmt.Fprintln(dockerCli.Out(), strings.TrimSpace(swarmInspect.ClusterInfo.TLSInfo.TrustRoot)) +func displayTrustRoot(out io.Writer, info swarm.Swarm) error { + if info.ClusterInfo.TLSInfo.TrustRoot == "" { + return errors.New("No CA information available") } + fmt.Fprintln(out, strings.TrimSpace(info.ClusterInfo.TLSInfo.TrustRoot)) return nil } diff --git a/cli/command/swarm/ca_test.go b/cli/command/swarm/ca_test.go new file mode 100644 index 000000000000..a1a77d59c22a --- /dev/null +++ b/cli/command/swarm/ca_test.go @@ -0,0 +1,155 @@ +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" +) + +func swarmSpecWithFullCAConfig() *swarm.Spec { + return &swarm.Spec{ + CAConfig: swarm.CAConfig{ + SigningCACert: "cacert", + SigningCAKey: "cakey", + ForceRotate: 1, + NodeCertExpiry: time.Duration(200), + ExternalCAs: []*swarm.ExternalCA{ + { + URL: "https://example.com/ca", + Protocol: swarm.ExternalCAProtocolCFSSL, + CACert: "excacert", + }, + }, + }, + } +} + +func TestDisplayTrustRootNoRoot(t *testing.T) { + buffer := new(bytes.Buffer) + err := displayTrustRoot(buffer, swarm.Swarm{}) + 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" + err := displayTrustRoot(buffer, swarm.Swarm{ + ClusterInfo: swarm.ClusterInfo{ + TLSInfo: swarm.TLSInfo{TrustRoot: trustRoot}, + }, + }) + require.NoError(t, err) + assert.Equal(t, trustRoot+"\n", buffer.String()) +} + +func TestUpdateSwarmSpecDefaultRotate(t *testing.T) { + spec := swarmSpecWithFullCAConfig() + flags := newCACommand(nil).Flags() + updateSwarmSpec(spec, flags, caOptions{}) + + expected := swarmSpecWithFullCAConfig() + expected.CAConfig.ForceRotate = 2 + expected.CAConfig.SigningCACert = "" + expected.CAConfig.SigningCAKey = "" + assert.Equal(t, expected, spec) +} + +func TestUpdateSwarmSpecPartial(t *testing.T) { + spec := swarmSpecWithFullCAConfig() + flags := newCACommand(nil).Flags() + updateSwarmSpec(spec, flags, caOptions{ + rootCACert: PEMFile{contents: "cacert"}, + }) + + expected := swarmSpecWithFullCAConfig() + expected.CAConfig.SigningCACert = "cacert" + assert.Equal(t, expected, spec) +} + +func TestUpdateSwarmSpecFullFlags(t *testing.T) { + flags := newCACommand(nil).Flags() + flags.Lookup(flagCertExpiry).Changed = true + spec := swarmSpecWithFullCAConfig() + updateSwarmSpec(spec, flags, caOptions{ + rootCACert: PEMFile{contents: "cacert"}, + rootCAKey: PEMFile{contents: "cakey"}, + swarmCAOptions: swarmCAOptions{nodeCertExpiry: 3 * time.Minute}, + }) + + expected := swarmSpecWithFullCAConfig() + expected.CAConfig.SigningCACert = "cacert" + expected.CAConfig.SigningCAKey = "cakey" + expected.CAConfig.NodeCertExpiry = 3 * time.Minute + assert.Equal(t, expected, spec) +} diff --git a/cli/command/swarm/cmd.go b/cli/command/swarm/cmd.go index b7e6dcfda2e6..d2793f6b91a1 100644 --- a/cli/command/swarm/cmd.go +++ b/cli/command/swarm/cmd.go @@ -25,7 +25,7 @@ func NewSwarmCommand(dockerCli command.Cli) *cobra.Command { newUpdateCommand(dockerCli), newLeaveCommand(dockerCli), newUnlockCommand(dockerCli), - newRotateCACommand(dockerCli), + newCACommand(dockerCli), ) return cmd } diff --git a/cli/command/swarm/init_test.go b/cli/command/swarm/init_test.go index 0fcdbb786d71..f6969d1b0ed3 100644 --- a/cli/command/swarm/init_test.go +++ b/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/cli/command/swarm/join_test.go b/cli/command/swarm/join_test.go index d4f1098ff925..331f2c175396 100644 --- a/cli/command/swarm/join_test.go +++ b/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/cli/command/swarm/join_token_test.go b/cli/command/swarm/join_token_test.go index 5c095b415673..f8619a4bd6cf 100644 --- a/cli/command/swarm/join_token_test.go +++ b/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/cli/command/swarm/leave_test.go b/cli/command/swarm/leave_test.go index dd7597efb504..aecac284309c 100644 --- a/cli/command/swarm/leave_test.go +++ b/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/cli/command/swarm/opts.go b/cli/command/swarm/opts.go index 0522f9fdfa23..b3baba273ea6 100644 --- a/cli/command/swarm/opts.go +++ b/cli/command/swarm/opts.go @@ -36,10 +36,9 @@ const ( ) type swarmOptions struct { + swarmCAOptions taskHistoryLimit int64 dispatcherHeartbeat time.Duration - nodeCertExpiry time.Duration - externalCA ExternalCAOption maxSnapshots uint64 snapshotInterval uint64 autolock bool @@ -216,7 +215,7 @@ func parseExternalCA(caSpec string) (*swarm.ExternalCA, error) { return &externalCA, nil } -func addSwarmCAFlags(flags *pflag.FlagSet, opts *swarmOptions) { +func addSwarmCAFlags(flags *pflag.FlagSet, opts *swarmCAOptions) { flags.DurationVar(&opts.nodeCertExpiry, flagCertExpiry, 90*24*time.Hour, "Validity period for node certificates (ns|us|ms|s|m|h)") flags.Var(&opts.externalCA, flagExternalCA, "Specifications of one or more certificate signing endpoints") } @@ -228,7 +227,7 @@ func addSwarmFlags(flags *pflag.FlagSet, opts *swarmOptions) { flags.SetAnnotation(flagMaxSnapshots, "version", []string{"1.25"}) flags.Uint64Var(&opts.snapshotInterval, flagSnapshotInterval, 10000, "Number of log entries between Raft snapshots") flags.SetAnnotation(flagSnapshotInterval, "version", []string{"1.25"}) - addSwarmCAFlags(flags, opts) + addSwarmCAFlags(flags, &opts.swarmCAOptions) } func (opts *swarmOptions) mergeSwarmSpec(spec *swarm.Spec, flags *pflag.FlagSet) { @@ -238,12 +237,6 @@ func (opts *swarmOptions) mergeSwarmSpec(spec *swarm.Spec, flags *pflag.FlagSet) if flags.Changed(flagDispatcherHeartbeat) { spec.Dispatcher.HeartbeatPeriod = opts.dispatcherHeartbeat } - if flags.Changed(flagCertExpiry) { - spec.CAConfig.NodeCertExpiry = opts.nodeCertExpiry - } - if flags.Changed(flagExternalCA) { - spec.CAConfig.ExternalCAs = opts.externalCA.Value() - } if flags.Changed(flagMaxSnapshots) { spec.Raft.KeepOldSnapshots = &opts.maxSnapshots } @@ -253,6 +246,21 @@ func (opts *swarmOptions) mergeSwarmSpec(spec *swarm.Spec, flags *pflag.FlagSet) if flags.Changed(flagAutolock) { spec.EncryptionConfig.AutoLockManagers = opts.autolock } + opts.mergeSwarmSpecCAFlags(spec, flags) +} + +type swarmCAOptions struct { + nodeCertExpiry time.Duration + externalCA ExternalCAOption +} + +func (opts *swarmCAOptions) mergeSwarmSpecCAFlags(spec *swarm.Spec, flags *pflag.FlagSet) { + if flags.Changed(flagCertExpiry) { + spec.CAConfig.NodeCertExpiry = opts.nodeCertExpiry + } + if flags.Changed(flagExternalCA) { + spec.CAConfig.ExternalCAs = opts.externalCA.Value() + } } func (opts *swarmOptions) ToSpec(flags *pflag.FlagSet) swarm.Spec { diff --git a/cli/command/swarm/unlock_key_test.go b/cli/command/swarm/unlock_key_test.go index 6b0246b199c3..9289a151f8bd 100644 --- a/cli/command/swarm/unlock_key_test.go +++ b/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/cli/command/swarm/unlock_test.go b/cli/command/swarm/unlock_test.go index 3dae5239f56f..bf339faaf133 100644 --- a/cli/command/swarm/unlock_test.go +++ b/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/cli/command/swarm/update_test.go b/cli/command/swarm/update_test.go index a6372cfee94a..2b8c4a8af875 100644 --- a/cli/command/swarm/update_test.go +++ b/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/cli/command/system/client_test.go b/cli/command/system/client_test.go new file mode 100644 index 000000000000..ed0e803ea80f --- /dev/null +++ b/cli/command/system/client_test.go @@ -0,0 +1,15 @@ +package system + +import ( + "github.com/docker/docker/client" +) + +type fakeClient struct { + client.Client + + version string +} + +func (cli *fakeClient) ClientVersion() string { + return cli.version +} diff --git a/cli/command/system/cmd.go b/cli/command/system/cmd.go index 455387cd46f7..60979e722476 100644 --- a/cli/command/system/cmd.go +++ b/cli/command/system/cmd.go @@ -18,8 +18,8 @@ func NewSystemCommand(dockerCli *command.DockerCli) *cobra.Command { cmd.AddCommand( NewEventsCommand(dockerCli), NewInfoCommand(dockerCli), - NewDiskUsageCommand(dockerCli), - NewPruneCommand(dockerCli), + newDiskUsageCommand(dockerCli), + newPruneCommand(dockerCli), ) return cmd diff --git a/cli/command/system/df.go b/cli/command/system/df.go index d8f9bdc0212a..5146482f0e62 100644 --- a/cli/command/system/df.go +++ b/cli/command/system/df.go @@ -15,8 +15,8 @@ type diskUsageOptions struct { format string } -// NewDiskUsageCommand creates a new cobra.Command for `docker df` -func NewDiskUsageCommand(dockerCli *command.DockerCli) *cobra.Command { +// newDiskUsageCommand creates a new cobra.Command for `docker df` +func newDiskUsageCommand(dockerCli *command.DockerCli) *cobra.Command { var opts diskUsageOptions cmd := &cobra.Command{ diff --git a/cli/command/system/prune.go b/cli/command/system/prune.go index e9383e43d332..d76d995e377e 100644 --- a/cli/command/system/prune.go +++ b/cli/command/system/prune.go @@ -7,23 +7,28 @@ import ( "github.com/docker/cli/cli" "github.com/docker/cli/cli/command" - "github.com/docker/cli/cli/command/prune" + "github.com/docker/cli/cli/command/container" + "github.com/docker/cli/cli/command/image" + "github.com/docker/cli/cli/command/network" + "github.com/docker/cli/cli/command/volume" "github.com/docker/cli/opts" + "github.com/docker/docker/api/types/versions" units "github.com/docker/go-units" "github.com/spf13/cobra" "golang.org/x/net/context" ) type pruneOptions struct { - force bool - all bool - pruneVolumes bool - filter opts.FilterOpt + force bool + all bool + pruneBuildCache bool + pruneVolumes bool + filter opts.FilterOpt } -// NewPruneCommand creates a new cobra.Command for `docker prune` -func NewPruneCommand(dockerCli command.Cli) *cobra.Command { - options := pruneOptions{filter: opts.NewFilterOpt()} +// newPruneCommand creates a new cobra.Command for `docker prune` +func newPruneCommand(dockerCli command.Cli) *cobra.Command { + options := pruneOptions{filter: opts.NewFilterOpt(), pruneBuildCache: true} cmd := &cobra.Command{ Use: "prune [OPTIONS]", @@ -52,20 +57,42 @@ const confirmationTemplate = `WARNING! This will remove: {{- end }} Are you sure you want to continue?` +// runBuildCachePrune executes a prune command for build cache +func runBuildCachePrune(dockerCli command.Cli, _ opts.FilterOpt) (uint64, string, error) { + report, err := dockerCli.Client().BuildCachePrune(context.Background()) + if err != nil { + return 0, "", err + } + return report.SpaceReclaimed, "", nil +} + func runPrune(dockerCli command.Cli, options pruneOptions) error { + // TODO version this once "until" filter is supported for volumes + if options.pruneVolumes && options.filter.Value().Include("until") { + return fmt.Errorf(`ERROR: The "until" filter is not supported with "--volumes"`) + } + if versions.LessThan(dockerCli.Client().ClientVersion(), "1.31") { + options.pruneBuildCache = false + } if !options.force && !command.PromptForConfirmation(dockerCli.In(), dockerCli.Out(), confirmationMessage(options)) { return nil } - - var spaceReclaimed uint64 + imagePrune := func(dockerCli command.Cli, filter opts.FilterOpt) (uint64, string, error) { + return image.RunPrune(dockerCli, options.all, options.filter) + } pruneFuncs := []func(dockerCli command.Cli, filter opts.FilterOpt) (uint64, string, error){ - prune.RunContainerPrune, - prune.RunNetworkPrune, + container.RunPrune, + network.RunPrune, } if options.pruneVolumes { - pruneFuncs = append(pruneFuncs, prune.RunVolumePrune) + pruneFuncs = append(pruneFuncs, volume.RunPrune) + } + pruneFuncs = append(pruneFuncs, imagePrune) + if options.pruneBuildCache { + pruneFuncs = append(pruneFuncs, runBuildCachePrune) } + var spaceReclaimed uint64 for _, pruneFn := range pruneFuncs { spc, output, err := pruneFn(dockerCli, options.filter) if err != nil { @@ -77,21 +104,6 @@ func runPrune(dockerCli command.Cli, options pruneOptions) error { } } - spc, output, err := prune.RunImagePrune(dockerCli, options.all, options.filter) - if err != nil { - return err - } - if spc > 0 { - spaceReclaimed += spc - fmt.Fprintln(dockerCli.Out(), output) - } - - report, err := dockerCli.Client().BuildCachePrune(context.Background()) - if err != nil { - return err - } - spaceReclaimed += report.SpaceReclaimed - fmt.Fprintln(dockerCli.Out(), "Total reclaimed space:", units.HumanSize(float64(spaceReclaimed))) return nil @@ -113,7 +125,9 @@ func confirmationMessage(options pruneOptions) string { } else { warnings = append(warnings, "all dangling images") } - warnings = append(warnings, "all build cache") + if options.pruneBuildCache { + warnings = append(warnings, "all build cache") + } var buffer bytes.Buffer t.Execute(&buffer, &warnings) diff --git a/cli/command/system/prune_test.go b/cli/command/system/prune_test.go new file mode 100644 index 000000000000..669166c99846 --- /dev/null +++ b/cli/command/system/prune_test.go @@ -0,0 +1,15 @@ +package system + +import ( + "testing" + + "github.com/docker/cli/cli/internal/test" + "github.com/stretchr/testify/assert" +) + +func TestPrunePromptPre131(t *testing.T) { + cli := test.NewFakeCli(&fakeClient{version: "1.30"}) + cmd := newPruneCommand(cli) + assert.NoError(t, cmd.Execute()) + assert.NotContains(t, cli.OutBuffer().String(), "all build cache") +} diff --git a/cli/command/task/print.go b/cli/command/task/print.go index 2376ecf8030e..6526c28bebe7 100644 --- a/cli/command/task/print.go +++ b/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/cli/command/task/print_test.go b/cli/command/task/print_test.go index 93171016f2ff..174ad72cd7d0 100644 --- a/cli/command/task/print_test.go +++ b/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/cli/command/volume/create_test.go b/cli/command/volume/create_test.go index 74c81aba1fee..05b17eccdf10 100644 --- a/cli/command/volume/create_test.go +++ b/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/cli/command/volume/inspect_test.go b/cli/command/volume/inspect_test.go index 3c16f125ab2e..8f452d7dee05 100644 --- a/cli/command/volume/inspect_test.go +++ b/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/cli/command/volume/list_test.go b/cli/command/volume/list_test.go index 2dc11a8b8ea9..92cd62b597c7 100644 --- a/cli/command/volume/list_test.go +++ b/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/cli/command/volume/prune_test.go b/cli/command/volume/prune_test.go index 33a8d5dc1986..cf26d283f4e1 100644 --- a/cli/command/volume/prune_test.go +++ b/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/cli/command/volume/remove_test.go b/cli/command/volume/remove_test.go index 8916700cc6cd..3d0190568169 100644 --- a/cli/command/volume/remove_test.go +++ b/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/cli/compose/convert/service.go b/cli/compose/convert/service.go index 730f5e1ee5b5..adbeadfa3628 100644 --- a/cli/compose/convert/service.go +++ b/cli/compose/convert/service.go @@ -157,9 +157,10 @@ func Service( Preferences: getPlacementPreference(service.Deploy.Placement.Preferences), }, }, - EndpointSpec: endpoint, - Mode: mode, - UpdateConfig: convertUpdateConfig(service.Deploy.UpdateConfig), + EndpointSpec: endpoint, + Mode: mode, + UpdateConfig: convertUpdateConfig(service.Deploy.UpdateConfig), + RollbackConfig: convertUpdateConfig(service.Deploy.RollbackConfig), } // add an image label to serviceSpec @@ -454,6 +455,7 @@ func convertUpdateConfig(source *composetypes.UpdateConfig) *swarm.UpdateConfig FailureAction: source.FailureAction, Monitor: source.Monitor, MaxFailureRatio: source.MaxFailureRatio, + Order: source.Order, } } diff --git a/cli/compose/convert/service_test.go b/cli/compose/convert/service_test.go index dd7f6ba25311..2b90d1658a72 100644 --- a/cli/compose/convert/service_test.go +++ b/cli/compose/convert/service_test.go @@ -342,4 +342,38 @@ func TestConvertCredentialSpec(t *testing.T) { }) assert.Error(t, err) assert.Nil(t, swarmSpec) + +} + +func TestConvertUpdateConfigOrder(t *testing.T) { + // test default behavior + updateConfig := convertUpdateConfig(&composetypes.UpdateConfig{}) + assert.Equal(t, "", updateConfig.Order) + + // test start-first + updateConfig = convertUpdateConfig(&composetypes.UpdateConfig{ + Order: "start-first", + }) + assert.Equal(t, updateConfig.Order, "start-first") + + // test stop-first + updateConfig = convertUpdateConfig(&composetypes.UpdateConfig{ + Order: "stop-first", + }) + assert.Equal(t, updateConfig.Order, "stop-first") +} + +func TestConvertUpdateConfigParallelism(t *testing.T) { + parallel := uint64(4) + + // test default behavior + updateConfig := convertUpdateConfig(&composetypes.UpdateConfig{}) + assert.Equal(t, uint64(1), updateConfig.Parallelism) + + // Non default value + updateConfig = convertUpdateConfig(&composetypes.UpdateConfig{ + Parallelism: ¶llel, + }) + assert.Equal(t, parallel, updateConfig.Parallelism) + } diff --git a/cli/compose/convert/volume.go b/cli/compose/convert/volume.go index e767b07ee988..8400f8d523e9 100644 --- a/cli/compose/convert/volume.go +++ b/cli/compose/convert/volume.go @@ -74,6 +74,10 @@ func convertVolumeToMount( return result, nil } + if stackVolume.Name != "" { + result.Source = stackVolume.Name + } + result.VolumeOptions.Labels = AddStackLabel(namespace, stackVolume.Labels) if stackVolume.Driver != "" || stackVolume.DriverOpts != nil { result.VolumeOptions.DriverConfig = &mount.Driver{ diff --git a/cli/compose/convert/volume_test.go b/cli/compose/convert/volume_test.go index c3d3c1d54e88..9e921701a0d7 100644 --- a/cli/compose/convert/volume_test.go +++ b/cli/compose/convert/volume_test.go @@ -98,6 +98,53 @@ func TestConvertVolumeToMountNamedVolume(t *testing.T) { assert.Equal(t, expected, mount) } +func TestConvertVolumeToMountNamedVolumeWithNameCustomizd(t *testing.T) { + stackVolumes := volumes{ + "normal": composetypes.VolumeConfig{ + Name: "user_specified_name", + Driver: "vsphere", + DriverOpts: map[string]string{ + "opt": "value", + }, + Labels: map[string]string{ + "something": "labeled", + }, + }, + } + namespace := NewNamespace("foo") + expected := mount.Mount{ + Type: mount.TypeVolume, + Source: "user_specified_name", + Target: "/foo", + ReadOnly: true, + VolumeOptions: &mount.VolumeOptions{ + Labels: map[string]string{ + LabelNamespace: "foo", + "something": "labeled", + }, + DriverConfig: &mount.Driver{ + Name: "vsphere", + Options: map[string]string{ + "opt": "value", + }, + }, + NoCopy: true, + }, + } + config := composetypes.ServiceVolumeConfig{ + Type: "volume", + Source: "normal", + Target: "/foo", + ReadOnly: true, + Volume: &composetypes.ServiceVolumeVolume{ + NoCopy: true, + }, + } + mount, err := convertVolumeToMount(config, stackVolumes, namespace) + assert.NoError(t, err) + assert.Equal(t, expected, mount) +} + func TestConvertVolumeToMountNamedVolumeExternal(t *testing.T) { stackVolumes := volumes{ "outside": composetypes.VolumeConfig{ diff --git a/cli/compose/loader/full-example.yml b/cli/compose/loader/full-example.yml index 76087c57ba68..dafdcd140150 100644 --- a/cli/compose/loader/full-example.yml +++ b/cli/compose/loader/full-example.yml @@ -1,4 +1,4 @@ -version: "3.3" +version: "3.4" services: foo: @@ -25,12 +25,20 @@ services: mode: replicated replicas: 6 labels: [FOO=BAR] + rollback_config: + parallelism: 3 + delay: 10s + failure_action: continue + monitor: 60s + max_failure_ratio: 0.3 + order: start-first update_config: parallelism: 3 delay: 10s failure_action: continue monitor: 60s max_failure_ratio: 0.3 + order: start-first resources: limits: cpus: '0.001' @@ -280,6 +288,15 @@ volumes: foo: "bar" baz: 1 + another-volume: + name: "user_specified_name" + driver: vsphere + + driver_opts: + # Values can be strings or numbers + foo: "bar" + baz: 1 + external-volume: # Specifies that a pre-existing volume called "external-volume" # can be referred to within this file as "external-volume" @@ -288,5 +305,12 @@ volumes: other-external-volume: # Specifies that a pre-existing volume called "my-cool-volume" # can be referred to within this file as "other-external-volume" + # This example uses the deprecated "volume.external.name" (replaced by "volume.name") external: name: my-cool-volume + + external-volume3: + # Specifies that a pre-existing volume called "this-is-volume3" + # can be referred to within this file as "external-volume3" + name: this-is-volume3 + external: true diff --git a/cli/compose/loader/loader.go b/cli/compose/loader/loader.go index b456e1824dc1..2fb2630087c0 100644 --- a/cli/compose/loader/loader.go +++ b/cli/compose/loader/loader.go @@ -444,6 +444,12 @@ func LoadVolumes(source map[string]interface{}) (map[string]types.VolumeConfig, if volume.External.Name == "" { volume.External.Name = name volumes[name] = volume + } else { + logrus.Warnf("volume %s: volume.external.name is deprecated in favor of volume.name", name) + + if volume.Name != "" { + return nil, errors.Errorf("volume %s: volume.external.name and volume.name conflict; only use volume.name", name) + } } } } diff --git a/cli/compose/loader/loader_test.go b/cli/compose/loader/loader_test.go index 6a43e52121a3..bad9599214ca 100644 --- a/cli/compose/loader/loader_test.go +++ b/cli/compose/loader/loader_test.go @@ -628,6 +628,22 @@ volumes: assert.Contains(t, err.Error(), "external_volume") } +func TestInvalidExternalNameAndNameCombination(t *testing.T) { + _, err := loadYAML(` +version: "3.4" +volumes: + external_volume: + name: user_specified_name + external: + name: external_name +`) + + assert.Error(t, err) + fmt.Println(err) + assert.Contains(t, err.Error(), "volume.external.name and volume.name conflict; only use volume.name") + assert.Contains(t, err.Error(), "external_volume") +} + func durationPtr(value time.Duration) *time.Duration { return &value } @@ -671,6 +687,15 @@ func TestFullExample(t *testing.T) { FailureAction: "continue", Monitor: time.Duration(60 * time.Second), MaxFailureRatio: 0.3, + Order: "start-first", + }, + RollbackConfig: &types.UpdateConfig{ + Parallelism: uint64Ptr(3), + Delay: time.Duration(10 * time.Second), + FailureAction: "continue", + Monitor: time.Duration(60 * time.Second), + MaxFailureRatio: 0.3, + Order: "start-first", }, Resources: types.Resources{ Limits: &types.Resource{ @@ -983,6 +1008,14 @@ func TestFullExample(t *testing.T) { "baz": "1", }, }, + "another-volume": { + Name: "user_specified_name", + Driver: "vsphere", + DriverOpts: map[string]string{ + "foo": "bar", + "baz": "1", + }, + }, "external-volume": { External: types.External{ Name: "external-volume", @@ -995,6 +1028,13 @@ func TestFullExample(t *testing.T) { External: true, }, }, + "external-volume3": { + Name: "this-is-volume3", + External: types.External{ + Name: "external-volume3", + External: true, + }, + }, } assert.Equal(t, expectedVolumeConfig, config.Volumes) diff --git a/cli/compose/schema/bindata.go b/cli/compose/schema/bindata.go index 06fcae3591b1..8e8bf60997c7 100644 --- a/cli/compose/schema/bindata.go +++ b/cli/compose/schema/bindata.go @@ -4,6 +4,7 @@ // data/config_schema_v3.1.json // data/config_schema_v3.2.json // data/config_schema_v3.3.json +// data/config_schema_v3.4.json // DO NOT EDIT! package schema @@ -151,6 +152,26 @@ func dataConfig_schema_v33Json() (*asset, error) { return a, nil } +var _dataConfig_schema_v34Json = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x5b\x4f\x73\xeb\x28\x12\xbf\xfb\x53\xa8\x34\x73\x1b\x27\x99\xaa\x7d\xb5\x55\xfb\x6e\x7b\xdc\xd3\xee\x79\x53\x1e\x15\x46\x6d\x9b\x09\x02\xa6\x41\x4e\x3c\xaf\xf2\xdd\xb7\xf4\xd7\x42\x02\x81\x6d\xe5\x25\x6f\x27\xa7\xc4\xd2\xaf\x81\xfe\xdf\x0d\xe8\xdb\x2a\x49\xd2\x9f\x35\x3d\x40\x41\xd2\xaf\x49\x7a\x30\x46\x7d\x7d\x78\xf8\x5d\x4b\x71\xd7\x3c\xbd\x97\xb8\x7f\xc8\x91\xec\xcc\xdd\xaf\x5f\x1e\x9a\x67\x3f\xa5\xeb\x8a\x8e\xe5\x15\x09\x95\x62\xc7\xf6\x59\xf3\x26\x3b\xfe\xed\xfe\xcb\x7d\x45\xde\x40\xcc\x49\x41\x05\x92\xdb\xdf\x81\x9a\xe6\x19\xc2\x1f\x25\x43\xa8\x88\x1f\xd3\x23\xa0\x66\x52\xa4\x9b\xf5\xaa\x7a\xa7\x50\x2a\x40\xc3\x40\xa7\x5f\x93\x6a\x71\x49\xd2\x43\xba\x07\x83\x61\xb5\x41\x26\xf6\x69\xfd\xf8\xb5\x1e\x21\x49\x52\x0d\x78\x64\x74\x30\x42\xbf\xd4\x9f\x1e\xce\xe3\x3f\xf4\xb0\xf5\x78\xd4\xc1\x62\xeb\xe7\x8a\x18\x03\x28\xfe\x33\x5d\x5b\xfd\xfa\xb7\x47\x72\xf7\xe7\x3f\xef\xfe\xfb\xeb\xdd\x3f\xee\xb3\xbb\xcd\x2f\x3f\x5b\xaf\x2b\xf9\x22\xec\x9a\xe9\x73\xd8\x31\xc1\x0c\x93\xa2\x9f\x3f\xed\x91\xaf\xed\x7f\xaf\xfd\xc4\x24\xcf\x6b\x30\xe1\xd6\xdc\x3b\xc2\x35\xd8\x3c\x0b\x30\xcf\x12\x9f\x42\x3c\xf7\xb0\x77\xe2\xb9\x9d\xdf\xc1\xb3\xcd\xce\x51\xf2\xb2\x08\x6a\xb0\x43\xbd\x13\x33\xcd\xf4\xcb\xe8\x4f\x03\x45\x30\x61\x93\x6d\x50\xef\x66\xb1\xd5\xf4\xcb\x30\xdc\x44\x8d\x10\xc3\x1d\xea\x9d\x18\x6e\xa6\xbf\x8d\xe1\x55\xc7\xf4\x2c\xb6\x41\x0c\xe6\xae\x17\x68\xc5\x33\x97\xa8\x5c\xf1\xc4\x2f\xab\x5e\x58\x1e\x29\xe5\xa0\xb8\x3c\x55\xcf\x3c\xf2\x68\x00\x05\x08\x93\xf6\x22\x48\x92\x74\x5b\x32\x9e\x8f\x25\x2a\x05\xfc\xbb\x1a\xe2\x71\xf0\x30\x49\xbe\x8d\x43\xf7\x60\x9c\xfa\xbd\xf5\xcb\xaf\xf0\xfe\xbd\x87\x97\xfe\x3d\x95\xc2\xc0\x8b\xa9\x99\x9a\x9f\xba\x11\x81\xa4\x4f\x80\x3b\xc6\x21\x96\x82\x60\x63\xc5\x1e\x91\x71\xa6\x4d\x26\x31\xcb\x19\x35\x4e\x7a\x4e\xb6\xc0\x6f\x1a\x81\x12\x7a\x80\x6c\x87\xb2\x08\x8e\xb2\xcb\x1a\x4e\x74\xfa\x3a\x1a\x67\x32\x70\xd8\xb4\x7b\xd2\xc1\xaf\xcd\xca\x31\x60\x4a\x89\xca\x48\x9e\x5b\x22\x25\x88\xe4\x94\xae\x93\x94\x19\x28\xb4\x5b\xda\x49\x5a\x0a\xf6\x47\x09\xff\x6a\x21\x06\x4b\x18\x8f\x9b\xa3\x54\xcb\x0f\xbc\x47\x59\xaa\x4c\x11\xac\x6c\x7d\xde\x12\x52\x2a\x8b\x82\x88\xa5\x1c\xe0\x12\x3e\x22\x24\x3f\x09\xb3\xc9\xd0\xab\xda\x39\x86\xaf\xfa\xd9\xac\x65\x79\xb8\x09\xf3\x33\x75\xe9\xb0\x53\x87\xdd\xba\x8a\x8a\xb2\x44\x1a\xeb\xa5\xd5\x9c\x04\xf7\x10\x1b\x07\x92\x24\x2d\x59\x1e\x0f\xde\x5f\x02\x2e\x64\x6e\xaf\x5b\x94\xc5\x16\x70\xe2\x92\xb6\x67\x4d\x7f\x6f\x56\xae\x37\x23\xed\x1b\xc2\x04\x60\x26\x48\x11\x92\x55\x4a\x11\x72\x10\x86\x11\x9e\x69\x05\xd4\x82\x77\x9a\x9a\xd1\x4c\x1a\x15\x35\x53\x84\x3d\xd3\x06\x4f\x4e\xe4\x99\x8b\xe1\xc2\x72\x50\x20\x72\x9d\x35\x3d\x40\x6c\x80\xb3\x06\xe8\x1b\x82\x45\xc3\x44\x2e\xe6\x02\x77\x33\x4c\x15\xba\xab\xb5\xa5\x23\xc2\x4c\x03\x41\x7a\xb8\x92\x5e\x16\x84\x89\x18\xa5\x82\x30\x78\x52\x92\x35\x61\xec\xc3\xc5\x27\x10\xc7\xac\xb7\x9b\x8b\xc5\x00\xe2\xc8\x50\x8a\xa2\x0b\xd2\x71\x09\x74\x40\xff\xa2\xa4\x86\xdb\x83\x63\x4b\xf1\xd8\x31\xbe\xee\x7d\x7a\x63\x4b\x2f\xdd\x49\x2c\x48\xb5\xd8\x6e\xee\xa1\x0f\x5b\x53\x4d\x2d\x6f\x28\xc0\x21\x0f\x55\xe1\x4b\x78\xc6\x99\x78\x5a\xde\xc4\xe1\xc5\x20\xc9\x0e\x52\x9b\x6b\x6a\x94\xf4\x00\x84\x9b\x03\x3d\x00\x7d\x9a\x21\x1f\xa2\x2c\x6a\xa9\x4d\x8c\x91\xb3\x82\xec\xc3\x20\x45\x43\x90\xab\x6b\xb1\x74\x51\xe1\x0f\x86\x95\xfb\x7d\x05\xf5\x59\xdc\xa4\xb6\x6f\x5f\x87\xaa\xe2\x1c\xd9\x11\x30\xb6\xc4\x95\xea\xdc\x92\x8c\x5f\xc6\x64\xf3\x60\x7f\x66\x41\x7f\xbb\x6f\xda\xb3\x19\xaf\xaa\xff\xe3\x3c\xdd\x4c\x53\xe6\x34\x69\x8e\x9f\x8c\x38\x8c\xab\x73\x2d\xad\x14\x84\x56\xe5\x2c\x82\xf6\xe8\xf5\x0c\x6d\x37\x3c\xb2\x49\xce\x3f\x63\x27\xe0\x49\x62\xf5\x45\xea\x8b\x13\x61\x72\x55\x87\x15\xa5\xba\x60\x8b\x1d\xe0\xc6\xb7\xbc\xd8\x65\x9e\x97\x1b\x36\xb1\x1a\x47\x38\x23\x1a\xc2\xce\xee\x15\xa4\x35\x1a\x53\xc7\x2f\x91\x36\xe1\xa2\xfd\xfb\x2c\xad\x87\xd4\x3b\x66\x7c\xeb\x16\x18\x6a\x58\xa2\x72\xee\x5c\xc8\x26\x5c\xb4\xbe\x65\x67\xa9\xec\xc2\xdb\x8e\x15\x75\x84\x18\x3a\x98\x92\x68\xbe\x4b\x2f\x74\x8e\x53\xe7\x84\xdf\x4c\x3e\x6d\x8f\xc6\xea\x8e\x22\x7a\x9b\x9e\x6a\x26\x4a\x39\xd0\x8e\x8e\x8a\x09\x03\xfb\xaa\x95\x71\x27\x81\x72\xcb\x99\x3e\x40\x7e\x09\x0d\x4a\x23\xa9\xe4\x71\x8e\xe1\xdc\xa0\x89\x77\x86\x99\xfe\xea\xaa\xda\x4c\x21\x3b\x32\x0e\xfb\x11\xc7\x5b\x29\x39\x10\x61\x25\x0a\x04\x92\x67\x52\xf0\x53\x04\x52\x1b\x82\xc1\x5d\x09\x0d\xb4\x44\x66\x4e\x99\x54\x66\xf1\xaa\x50\x1f\x8a\x4c\xb3\x3f\xc1\xf6\xbd\xb3\xd5\xb7\x03\x6d\x46\x0b\x1a\x6d\x71\x27\x9f\x5b\x11\x7f\x99\xad\x08\x7d\xd2\xd4\x5c\x57\x5b\x6b\x93\x33\x91\x49\x05\x22\xe8\x1b\xda\x48\x95\xed\x91\x50\xc8\x14\x20\x93\x4e\x51\x58\x01\x36\x2f\x91\x54\xf3\x4f\x87\xd1\x6c\x2f\x88\x3b\xee\x0c\xa0\xa6\x50\xbb\x2b\x37\x01\x8c\x09\x3b\x7b\xc9\x59\xc1\xfc\x4e\xe3\xb0\xda\x88\x7a\xad\xa9\xd5\xdc\x25\xda\x4c\x79\x16\x15\xb2\x67\x3a\x84\xf9\x06\x21\xa2\x33\x38\x10\xbc\x20\x75\xd4\x8e\xb9\xf3\xe4\x27\x57\xdf\xe0\x5c\x97\x75\x58\x5d\x8f\xb7\x6e\x17\xb2\x71\xe2\x2f\x2a\xbd\xc6\xcb\xd8\x78\xab\x1f\xb7\x53\x95\x3a\xd8\xc4\xd5\x18\xa1\xe7\x1a\x90\x1e\x3a\x3d\x75\x4d\x7e\x88\x08\x6d\xe9\xa8\x86\x3b\x74\x13\x11\xc7\xdb\x99\x22\x63\xe7\x5b\x47\xfd\xe8\x8a\x60\x40\x43\xa5\xd0\x4c\x1b\x10\xd4\xbd\xbf\xea\x24\xda\xb2\xc9\xe1\xc5\x54\x28\xf3\x7d\x57\x5c\xd7\x55\xa3\xc8\xbe\x89\xb7\xd1\x8d\x4e\xbc\xaf\xb6\x07\xf2\xdf\x85\x15\x21\xa9\x54\x1e\xd5\xc4\xb3\x71\x69\x9a\x1d\x6d\x5d\xcc\xd4\xa1\xbe\x90\xf1\x2c\xf1\xa9\x4a\x48\x39\x73\x47\x8e\xd5\x88\xe4\x82\x23\xfd\xd1\x5e\x5f\x37\x80\xeb\xac\x7a\x08\x0d\x9e\xed\xcf\x9f\x9b\xb7\x20\xef\x99\x36\xd3\x64\x3b\x3a\x97\x70\x25\xda\x2a\x33\xe0\x31\x9c\xef\x11\x0c\xb2\xd1\x51\x42\x57\x34\x0d\x73\x3b\xe8\x8f\xb9\xe1\x6e\x58\x01\xb2\x74\x87\xa1\xd5\xd0\x70\x5a\xa2\x74\x70\xe6\x1f\x50\xea\x00\x39\xd6\xe9\xe3\xe0\x00\xa9\xe9\xcb\x83\x8a\x8b\x49\x58\x20\xf2\xfa\x68\x23\x2a\xbb\x21\x28\xce\x28\xd1\xa1\x0a\xe2\x86\x5d\x60\x94\x9c\x6f\x09\x7d\xca\xda\x8b\x23\x97\x54\x6d\x33\xe5\x9a\x22\x48\x38\x07\xce\x74\x11\x53\xfe\xa4\x39\x70\xe2\x8c\xff\xc1\xca\xb7\x26\xdf\x11\xc6\x4b\x84\x8c\x50\x6f\xa0\x1e\x51\x14\x52\x30\x23\x9d\x01\x25\x6e\xca\x82\xbc\x64\xdd\xb4\x35\x24\xe0\x5f\x35\x91\xc4\xdc\x5d\xfe\xac\x2b\xcb\x28\x0b\x47\x01\x92\xd6\xad\xf3\xdd\x8e\xa1\x36\x4d\x9f\x2a\x55\xfb\xcb\x0e\xb4\xaf\xde\xde\x3f\x76\xbb\xb8\x27\x28\x55\x4e\x0c\x7c\x9a\xc4\xa7\x49\xf4\x04\x08\x4d\xf1\x78\x59\x5f\x37\x63\x0e\xe7\x2e\xd1\x13\xb2\xba\x19\x27\x12\x43\xd0\x55\xde\xeb\x0f\x78\x82\xf4\xc1\x0a\xa3\xdd\x9f\xca\x94\xe4\xac\x29\x43\x97\xe0\x90\x4a\xd1\x08\x39\xc6\xf8\x6e\xb4\xf6\xca\xf4\xaa\x26\xba\x50\x26\x98\x2d\x6a\x82\x67\x26\x72\xf9\x7c\xc1\x84\xcb\x99\x92\xe2\x84\xc2\x28\x3b\xdf\x2a\x68\x6d\x90\x30\x61\x2e\x3e\xcf\x1c\x8b\x45\x21\xec\x00\x41\x4c\x0d\x3d\x99\xef\x2b\x13\x7f\x6f\x19\xe2\x2d\xcc\x61\x8b\xd0\xaa\x6a\xb0\xde\x61\x5b\xf9\x56\xe5\xdf\x50\xa1\xf7\x5e\x1c\xa8\xe4\x7a\x5c\xb0\x36\xf7\x55\x6f\x54\x95\xc1\xb3\xd1\x02\x0a\x39\x7f\x0f\xe8\x86\x9b\xf0\x21\x16\x3b\xd8\x02\x95\x6a\xd4\x61\x7a\x8b\xca\xa4\x5a\x7e\x37\x2f\x7c\x60\xbe\x09\x87\x6d\xa6\x48\xb1\x54\x0c\x89\xbe\x5e\x90\x3a\xab\xa2\xe4\x03\x44\x87\x72\x2b\x3c\x9b\x35\x1f\x3b\x3a\x0c\xbb\xa3\xf6\x66\x90\x47\xab\x8f\x7d\x1f\xbc\xee\x65\xb5\x89\x56\xb1\xf7\x5a\xce\x72\xeb\xaf\x5b\xf2\xf1\x16\xbc\xab\x77\x27\xc6\x10\x7a\x88\x6a\xf3\x2f\xec\xed\x6e\x88\x43\x93\xcd\x28\x67\x18\x6a\x51\x0b\x44\xa1\x98\x7b\x52\xff\x1f\x91\xea\x47\xb7\xeb\xef\x67\x83\xed\x07\x3b\xc1\x0f\x47\x6a\xd4\xd5\xb9\x3e\xe2\xde\xef\x07\xd0\xd9\x3b\xab\x62\x92\xe8\x9c\xaa\x68\x51\x9f\xaa\x78\x53\xaf\xb0\x8f\x64\x07\x2a\x99\xee\xd0\xce\x49\xf2\xd2\x4f\x6d\x36\xf6\x32\xc6\x30\xc7\xe7\xad\x76\xed\x33\x77\x61\xa3\x83\x78\x4e\x04\x46\x93\xb6\x42\x9c\xe7\x7c\xc1\xb8\x7f\xff\xcb\x4c\x85\x37\x77\xbf\xf3\x8d\x4a\xa3\x05\x2e\xc3\xb8\x75\x3a\x6a\x9e\x3b\xe9\x4e\xbf\xe0\xf3\xfb\x7f\x47\x3f\xf9\x9e\xaf\xe2\x53\x9c\x26\x27\x08\xdf\xec\xe3\xcf\xe6\x5b\xbc\x8d\x25\x9f\x11\xa4\xb9\x2d\x3d\x48\xb4\x9b\xe1\x7e\x82\xf7\xf3\x0e\xd7\x57\x7e\xe3\xc3\xd7\xee\x6b\x3b\xcf\x7d\x90\xd5\xf0\x6f\xfd\x65\xe4\xea\x75\xf5\xbf\x00\x00\x00\xff\xff\x1d\x00\x4e\x52\x83\x3e\x00\x00") + +func dataConfig_schema_v34JsonBytes() ([]byte, error) { + return bindataRead( + _dataConfig_schema_v34Json, + "data/config_schema_v3.4.json", + ) +} + +func dataConfig_schema_v34Json() (*asset, error) { + bytes, err := dataConfig_schema_v34JsonBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "data/config_schema_v3.4.json", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + // Asset loads and returns the asset for the given name. // It returns an error if the asset could not be found or // could not be loaded. @@ -207,6 +228,7 @@ var _bindata = map[string]func() (*asset, error){ "data/config_schema_v3.1.json": dataConfig_schema_v31Json, "data/config_schema_v3.2.json": dataConfig_schema_v32Json, "data/config_schema_v3.3.json": dataConfig_schema_v33Json, + "data/config_schema_v3.4.json": dataConfig_schema_v34Json, } // AssetDir returns the file names below a certain @@ -254,6 +276,7 @@ var _bintree = &bintree{nil, map[string]*bintree{ "config_schema_v3.1.json": &bintree{dataConfig_schema_v31Json, map[string]*bintree{}}, "config_schema_v3.2.json": &bintree{dataConfig_schema_v32Json, map[string]*bintree{}}, "config_schema_v3.3.json": &bintree{dataConfig_schema_v33Json, map[string]*bintree{}}, + "config_schema_v3.4.json": &bintree{dataConfig_schema_v34Json, map[string]*bintree{}}, }}, }} diff --git a/cli/compose/schema/data/config_schema_v3.4.json b/cli/compose/schema/data/config_schema_v3.4.json new file mode 100644 index 000000000000..8dcd0a2e7581 --- /dev/null +++ b/cli/compose/schema/data/config_schema_v3.4.json @@ -0,0 +1,552 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "id": "config_schema_v3.4.json", + "type": "object", + "required": ["version"], + + "properties": { + "version": { + "type": "string" + }, + + "services": { + "id": "#/properties/services", + "type": "object", + "patternProperties": { + "^[a-zA-Z0-9._-]+$": { + "$ref": "#/definitions/service" + } + }, + "additionalProperties": false + }, + + "networks": { + "id": "#/properties/networks", + "type": "object", + "patternProperties": { + "^[a-zA-Z0-9._-]+$": { + "$ref": "#/definitions/network" + } + } + }, + + "volumes": { + "id": "#/properties/volumes", + "type": "object", + "patternProperties": { + "^[a-zA-Z0-9._-]+$": { + "$ref": "#/definitions/volume" + } + }, + "additionalProperties": false + }, + + "secrets": { + "id": "#/properties/secrets", + "type": "object", + "patternProperties": { + "^[a-zA-Z0-9._-]+$": { + "$ref": "#/definitions/secret" + } + }, + "additionalProperties": false + }, + + "configs": { + "id": "#/properties/configs", + "type": "object", + "patternProperties": { + "^[a-zA-Z0-9._-]+$": { + "$ref": "#/definitions/config" + } + }, + "additionalProperties": false + } + }, + + "additionalProperties": false, + + "definitions": { + + "service": { + "id": "#/definitions/service", + "type": "object", + + "properties": { + "deploy": {"$ref": "#/definitions/deployment"}, + "build": { + "oneOf": [ + {"type": "string"}, + { + "type": "object", + "properties": { + "context": {"type": "string"}, + "dockerfile": {"type": "string"}, + "args": {"$ref": "#/definitions/list_or_dict"}, + "labels": {"$ref": "#/definitions/list_or_dict"}, + "cache_from": {"$ref": "#/definitions/list_of_strings"} + }, + "additionalProperties": false + } + ] + }, + "cap_add": {"type": "array", "items": {"type": "string"}, "uniqueItems": true}, + "cap_drop": {"type": "array", "items": {"type": "string"}, "uniqueItems": true}, + "cgroup_parent": {"type": "string"}, + "command": { + "oneOf": [ + {"type": "string"}, + {"type": "array", "items": {"type": "string"}} + ] + }, + "configs": { + "type": "array", + "items": { + "oneOf": [ + {"type": "string"}, + { + "type": "object", + "properties": { + "source": {"type": "string"}, + "target": {"type": "string"}, + "uid": {"type": "string"}, + "gid": {"type": "string"}, + "mode": {"type": "number"} + } + } + ] + } + }, + "container_name": {"type": "string"}, + "credential_spec": {"type": "object", "properties": { + "file": {"type": "string"}, + "registry": {"type": "string"} + }}, + "depends_on": {"$ref": "#/definitions/list_of_strings"}, + "devices": {"type": "array", "items": {"type": "string"}, "uniqueItems": true}, + "dns": {"$ref": "#/definitions/string_or_list"}, + "dns_search": {"$ref": "#/definitions/string_or_list"}, + "domainname": {"type": "string"}, + "entrypoint": { + "oneOf": [ + {"type": "string"}, + {"type": "array", "items": {"type": "string"}} + ] + }, + "env_file": {"$ref": "#/definitions/string_or_list"}, + "environment": {"$ref": "#/definitions/list_or_dict"}, + + "expose": { + "type": "array", + "items": { + "type": ["string", "number"], + "format": "expose" + }, + "uniqueItems": true + }, + + "external_links": {"type": "array", "items": {"type": "string"}, "uniqueItems": true}, + "extra_hosts": {"$ref": "#/definitions/list_or_dict"}, + "healthcheck": {"$ref": "#/definitions/healthcheck"}, + "hostname": {"type": "string"}, + "image": {"type": "string"}, + "ipc": {"type": "string"}, + "labels": {"$ref": "#/definitions/list_or_dict"}, + "links": {"type": "array", "items": {"type": "string"}, "uniqueItems": true}, + + "logging": { + "type": "object", + + "properties": { + "driver": {"type": "string"}, + "options": { + "type": "object", + "patternProperties": { + "^.+$": {"type": ["string", "number", "null"]} + } + } + }, + "additionalProperties": false + }, + + "mac_address": {"type": "string"}, + "network_mode": {"type": "string"}, + + "networks": { + "oneOf": [ + {"$ref": "#/definitions/list_of_strings"}, + { + "type": "object", + "patternProperties": { + "^[a-zA-Z0-9._-]+$": { + "oneOf": [ + { + "type": "object", + "properties": { + "aliases": {"$ref": "#/definitions/list_of_strings"}, + "ipv4_address": {"type": "string"}, + "ipv6_address": {"type": "string"} + }, + "additionalProperties": false + }, + {"type": "null"} + ] + } + }, + "additionalProperties": false + } + ] + }, + "pid": {"type": ["string", "null"]}, + + "ports": { + "type": "array", + "items": { + "oneOf": [ + {"type": "number", "format": "ports"}, + {"type": "string", "format": "ports"}, + { + "type": "object", + "properties": { + "mode": {"type": "string"}, + "target": {"type": "integer"}, + "published": {"type": "integer"}, + "protocol": {"type": "string"} + }, + "additionalProperties": false + } + ] + }, + "uniqueItems": true + }, + + "privileged": {"type": "boolean"}, + "read_only": {"type": "boolean"}, + "restart": {"type": "string"}, + "security_opt": {"type": "array", "items": {"type": "string"}, "uniqueItems": true}, + "shm_size": {"type": ["number", "string"]}, + "secrets": { + "type": "array", + "items": { + "oneOf": [ + {"type": "string"}, + { + "type": "object", + "properties": { + "source": {"type": "string"}, + "target": {"type": "string"}, + "uid": {"type": "string"}, + "gid": {"type": "string"}, + "mode": {"type": "number"} + } + } + ] + } + }, + "sysctls": {"$ref": "#/definitions/list_or_dict"}, + "stdin_open": {"type": "boolean"}, + "stop_grace_period": {"type": "string", "format": "duration"}, + "stop_signal": {"type": "string"}, + "tmpfs": {"$ref": "#/definitions/string_or_list"}, + "tty": {"type": "boolean"}, + "ulimits": { + "type": "object", + "patternProperties": { + "^[a-z]+$": { + "oneOf": [ + {"type": "integer"}, + { + "type":"object", + "properties": { + "hard": {"type": "integer"}, + "soft": {"type": "integer"} + }, + "required": ["soft", "hard"], + "additionalProperties": false + } + ] + } + } + }, + "user": {"type": "string"}, + "userns_mode": {"type": "string"}, + "volumes": { + "type": "array", + "items": { + "oneOf": [ + {"type": "string"}, + { + "type": "object", + "required": ["type"], + "properties": { + "type": {"type": "string"}, + "source": {"type": "string"}, + "target": {"type": "string"}, + "read_only": {"type": "boolean"}, + "consistency": {"type": "string"}, + "bind": { + "type": "object", + "properties": { + "propagation": {"type": "string"} + } + }, + "volume": { + "type": "object", + "properties": { + "nocopy": {"type": "boolean"} + } + } + } + } + ], + "uniqueItems": true + } + }, + "working_dir": {"type": "string"} + }, + "additionalProperties": false + }, + + "healthcheck": { + "id": "#/definitions/healthcheck", + "type": "object", + "additionalProperties": false, + "properties": { + "disable": {"type": "boolean"}, + "interval": {"type": "string"}, + "retries": {"type": "number"}, + "test": { + "oneOf": [ + {"type": "string"}, + {"type": "array", "items": {"type": "string"}} + ] + }, + "timeout": {"type": "string"} + } + }, + "deployment": { + "id": "#/definitions/deployment", + "type": ["object", "null"], + "properties": { + "mode": {"type": "string"}, + "endpoint_mode": {"type": "string"}, + "replicas": {"type": "integer"}, + "labels": {"$ref": "#/definitions/list_or_dict"}, + "rollback_config": { + "type": "object", + "properties": { + "parallelism": {"type": "integer"}, + "delay": {"type": "string", "format": "duration"}, + "failure_action": {"type": "string"}, + "monitor": {"type": "string", "format": "duration"}, + "max_failure_ratio": {"type": "number"}, + "order": {"type": "string", "enum": [ + "start-first", "stop-first" + ]} + }, + "additionalProperties": false + }, + "update_config": { + "type": "object", + "properties": { + "parallelism": {"type": "integer"}, + "delay": {"type": "string", "format": "duration"}, + "failure_action": {"type": "string"}, + "monitor": {"type": "string", "format": "duration"}, + "max_failure_ratio": {"type": "number"}, + "order": {"type": "string", "enum": [ + "start-first", "stop-first" + ]} + }, + "additionalProperties": false + }, + "resources": { + "type": "object", + "properties": { + "limits": {"$ref": "#/definitions/resource"}, + "reservations": {"$ref": "#/definitions/resource"} + } + }, + "restart_policy": { + "type": "object", + "properties": { + "condition": {"type": "string"}, + "delay": {"type": "string", "format": "duration"}, + "max_attempts": {"type": "integer"}, + "window": {"type": "string", "format": "duration"} + }, + "additionalProperties": false + }, + "placement": { + "type": "object", + "properties": { + "constraints": {"type": "array", "items": {"type": "string"}}, + "preferences": { + "type": "array", + "items": { + "type": "object", + "properties": { + "spread": {"type": "string"} + }, + "additionalProperties": false + } + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + + "resource": { + "id": "#/definitions/resource", + "type": "object", + "properties": { + "cpus": {"type": "string"}, + "memory": {"type": "string"} + }, + "additionalProperties": false + }, + + "network": { + "id": "#/definitions/network", + "type": ["object", "null"], + "properties": { + "driver": {"type": "string"}, + "driver_opts": { + "type": "object", + "patternProperties": { + "^.+$": {"type": ["string", "number"]} + } + }, + "ipam": { + "type": "object", + "properties": { + "driver": {"type": "string"}, + "config": { + "type": "array", + "items": { + "type": "object", + "properties": { + "subnet": {"type": "string"} + }, + "additionalProperties": false + } + } + }, + "additionalProperties": false + }, + "external": { + "type": ["boolean", "object"], + "properties": { + "name": {"type": "string"} + }, + "additionalProperties": false + }, + "internal": {"type": "boolean"}, + "attachable": {"type": "boolean"}, + "labels": {"$ref": "#/definitions/list_or_dict"} + }, + "additionalProperties": false + }, + + "volume": { + "id": "#/definitions/volume", + "type": ["object", "null"], + "properties": { + "name": {"type": "string"}, + "driver": {"type": "string"}, + "driver_opts": { + "type": "object", + "patternProperties": { + "^.+$": {"type": ["string", "number"]} + } + }, + "external": { + "type": ["boolean", "object"], + "properties": { + "name": {"type": "string"} + }, + "additionalProperties": false + }, + "labels": {"$ref": "#/definitions/list_or_dict"} + }, + "additionalProperties": false + }, + + "secret": { + "id": "#/definitions/secret", + "type": "object", + "properties": { + "file": {"type": "string"}, + "external": { + "type": ["boolean", "object"], + "properties": { + "name": {"type": "string"} + } + }, + "labels": {"$ref": "#/definitions/list_or_dict"} + }, + "additionalProperties": false + }, + + "config": { + "id": "#/definitions/config", + "type": "object", + "properties": { + "file": {"type": "string"}, + "external": { + "type": ["boolean", "object"], + "properties": { + "name": {"type": "string"} + } + }, + "labels": {"$ref": "#/definitions/list_or_dict"} + }, + "additionalProperties": false + }, + + "string_or_list": { + "oneOf": [ + {"type": "string"}, + {"$ref": "#/definitions/list_of_strings"} + ] + }, + + "list_of_strings": { + "type": "array", + "items": {"type": "string"}, + "uniqueItems": true + }, + + "list_or_dict": { + "oneOf": [ + { + "type": "object", + "patternProperties": { + ".+": { + "type": ["string", "number", "null"] + } + }, + "additionalProperties": false + }, + {"type": "array", "items": {"type": "string"}, "uniqueItems": true} + ] + }, + + "constraints": { + "service": { + "id": "#/definitions/constraints/service", + "anyOf": [ + {"required": ["build"]}, + {"required": ["image"]} + ], + "properties": { + "build": { + "required": ["context"] + } + } + } + } + } +} diff --git a/cli/compose/schema/schema_test.go b/cli/compose/schema/schema_test.go index f293fe7f68f0..b69b2333d542 100644 --- a/cli/compose/schema/schema_test.go +++ b/cli/compose/schema/schema_test.go @@ -74,3 +74,92 @@ func TestValidatePlacement(t *testing.T) { assert.NoError(t, Validate(config, "3.3")) } + +func TestValidateRollbackConfig(t *testing.T) { + config := dict{ + "version": "3.4", + "services": dict{ + "foo": dict{ + "image": "busybox", + "deploy": dict{ + "rollback_config": dict{ + "parallelism": 1, + }, + }, + }, + }, + } + + assert.NoError(t, Validate(config, "3.4")) +} + +func TestValidateRollbackConfigWithOrder(t *testing.T) { + config := dict{ + "version": "3.4", + "services": dict{ + "foo": dict{ + "image": "busybox", + "deploy": dict{ + "rollback_config": dict{ + "parallelism": 1, + "order": "start-first", + }, + }, + }, + }, + } + + assert.NoError(t, Validate(config, "3.4")) +} + +func TestValidateRollbackConfigWithUpdateConfig(t *testing.T) { + config := dict{ + "version": "3.4", + "services": dict{ + "foo": dict{ + "image": "busybox", + "deploy": dict{ + "update_config": dict{ + "parallelism": 1, + "order": "start-first", + }, + "rollback_config": dict{ + "parallelism": 1, + "order": "start-first", + }, + }, + }, + }, + } + + assert.NoError(t, Validate(config, "3.4")) +} + +func TestValidateRollbackConfigWithUpdateConfigFull(t *testing.T) { + config := dict{ + "version": "3.4", + "services": dict{ + "foo": dict{ + "image": "busybox", + "deploy": dict{ + "update_config": dict{ + "parallelism": 1, + "order": "start-first", + "delay": "10s", + "failure_action": "pause", + "monitor": "10s", + }, + "rollback_config": dict{ + "parallelism": 1, + "order": "start-first", + "delay": "10s", + "failure_action": "pause", + "monitor": "10s", + }, + }, + }, + }, + } + + assert.NoError(t, Validate(config, "3.4")) +} diff --git a/cli/compose/types/types.go b/cli/compose/types/types.go index 1eecc124f6b1..52c6f8506998 100644 --- a/cli/compose/types/types.go +++ b/cli/compose/types/types.go @@ -157,14 +157,15 @@ type LoggingConfig struct { // DeployConfig the deployment configuration for a service type DeployConfig struct { - Mode string - Replicas *uint64 - Labels Labels - UpdateConfig *UpdateConfig `mapstructure:"update_config"` - Resources Resources - RestartPolicy *RestartPolicy `mapstructure:"restart_policy"` - Placement Placement - EndpointMode string `mapstructure:"endpoint_mode"` + Mode string + Replicas *uint64 + Labels Labels + UpdateConfig *UpdateConfig `mapstructure:"update_config"` + RollbackConfig *UpdateConfig `mapstructure:"rollback_config"` + Resources Resources + RestartPolicy *RestartPolicy `mapstructure:"restart_policy"` + Placement Placement + EndpointMode string `mapstructure:"endpoint_mode"` } // HealthCheckConfig the healthcheck configuration for a service @@ -187,6 +188,7 @@ type UpdateConfig struct { FailureAction string `mapstructure:"failure_action"` Monitor time.Duration MaxFailureRatio float32 `mapstructure:"max_failure_ratio"` + Order string } // Resources the resource limits and reservations @@ -305,6 +307,7 @@ type IPAMPool struct { // VolumeConfig for a volume type VolumeConfig struct { + Name string Driver string DriverOpts map[string]string `mapstructure:"driver_opts"` External External @@ -313,6 +316,7 @@ type VolumeConfig struct { // External identifies a Volume or Network as a reference to a resource that is // not managed, and should already exist. +// External.name is deprecated and replaced by Volume.name type External struct { Name string External bool diff --git a/cli/internal/test/cli.go b/cli/internal/test/cli.go index 378ee9cdc234..54b3bc83b1cd 100644 --- a/cli/internal/test/cli.go +++ b/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/contrib/completion/bash/docker b/contrib/completion/bash/docker index 33ada275b10a..66174729d0f1 100644 --- a/contrib/completion/bash/docker +++ b/contrib/completion/bash/docker @@ -1,4 +1,13 @@ #!/usr/bin/env bash +# shellcheck disable=SC2016,SC2119,SC2155 +# +# Shellcheck ignore list: +# - SC2016: Expressions don't expand in single quotes, use double quotes for that. +# - SC2119: Use foo "$@" if function's $1 should mean script's $1. +# - SC2155: Declare and assign separately to avoid masking return values. +# +# You can find more details for each warning at the following page: +# https://github.com/koalaman/shellcheck/wiki/ # # bash completion file for core docker commands # @@ -20,6 +29,7 @@ # For several commands, the amount of completions can be configured by # setting environment variables. # +# DOCKER_COMPLETION_SHOW_CONFIG_IDS # DOCKER_COMPLETION_SHOW_CONTAINER_IDS # DOCKER_COMPLETION_SHOW_NETWORK_IDS # DOCKER_COMPLETION_SHOW_NODE_IDS @@ -61,6 +71,42 @@ __docker_q() { docker ${host:+-H "$host"} ${config:+--config "$config"} 2>/dev/null "$@" } +# __docker_configs returns a list of configs. Additional options to +# `docker config ls` may be specified in order to filter the list, e.g. +# `__docker_configs --filter label=stage=production`. +# By default, only names are returned. +# Set DOCKER_COMPLETION_SHOW_CONFIG_IDS=yes to also complete IDs. +# An optional first option `--id|--name` may be used to limit the +# output to the IDs or names of matching items. This setting takes +# precedence over the environment setting. +__docker_configs() { + local format + if [ "$1" = "--id" ] ; then + format='{{.ID}}' + shift + elif [ "$1" = "--name" ] ; then + format='{{.Name}}' + shift + elif [ "$DOCKER_COMPLETION_SHOW_CONFIG_IDS" = yes ] ; then + format='{{.ID}} {{.Name}}' + else + format='{{.Name}}' + fi + + __docker_q config ls --format "$format" "$@" +} + +# __docker_complete_configs applies completion of configs based on the current value +# of `$cur` or the value of the optional first option `--cur`, if given. +__docker_complete_configs() { + local current="$cur" + if [ "$1" = "--cur" ] ; then + current="$2" + shift 2 + fi + COMPREPLY=( $(compgen -W "$(__docker_configs "$@")" -- "$current") ) +} + # __docker_containers returns a list of containers. Additional options to # `docker ps` may be specified in order to filter the list, e.g. # `__docker_containers --filter status=running` @@ -101,6 +147,7 @@ __docker_complete_containers_all() { __docker_complete_containers "$@" --all } +# shellcheck disable=SC2120 __docker_complete_containers_removable() { __docker_complete_containers "$@" --filter status=created --filter status=exited } @@ -109,10 +156,12 @@ __docker_complete_containers_running() { __docker_complete_containers "$@" --filter status=running } +# shellcheck disable=SC2120 __docker_complete_containers_stopped() { __docker_complete_containers "$@" --filter status=exited } +# shellcheck disable=SC2120 __docker_complete_containers_unpauseable() { __docker_complete_containers "$@" --filter status=paused } @@ -213,6 +262,7 @@ __docker_complete_networks() { COMPREPLY=( $(compgen -W "$(__docker_networks "$@")" -- "$current") ) } +# shellcheck disable=SC2128,SC2178 __docker_complete_containers_in_network() { local containers=$(__docker_q network inspect -f '{{range $i, $c := .Containers}}{{$i}} {{$c.Name}} {{end}}' "$1") COMPREPLY=( $(compgen -W "$containers" -- "$cur") ) @@ -271,6 +321,7 @@ __docker_plugins_bundled() { for del in "${remove[@]}" ; do plugins=(${plugins[@]/$del/}) done + # shellcheck disable=SC2145 echo "${plugins[@]} ${add[@]}" } @@ -414,7 +465,7 @@ __docker_nodes() { esac done - echo $(__docker_q node ls "$@" | tr -d '*' | awk "NR>1 {print $fields}") "${add[@]}" + echo "$(__docker_q node ls "$@" | tr -d '*' | awk "NR>1 {print $fields}")" "${add[@]}" } # __docker_complete_nodes applies completion of nodes based on the current @@ -469,6 +520,7 @@ __docker_tasks() { } # __docker_complete_services_and_tasks applies completion of services and task IDs. +# shellcheck disable=SC2120 __docker_complete_services_and_tasks() { COMPREPLY=( $(compgen -W "$(__docker_services "$@") $(__docker_tasks)" -- "$cur") ) } @@ -509,7 +561,7 @@ __docker_pos_first_nonflag() { local argument_flags=$1 local counter=$((${subcommand_pos:-${command_pos}} + 1)) - while [ $counter -le $cword ]; do + while [ "$counter" -le "$cword" ]; do if [ -n "$argument_flags" ] && eval "case '${words[$counter]}' in $argument_flags) true ;; *) false ;; esac"; then (( counter++ )) # eat "=" in case of --option=arg syntax @@ -569,10 +621,10 @@ __docker_value_of_option() { local option_extglob=$(__docker_to_extglob "$1") local counter=$((command_pos + 1)) - while [ $counter -lt $cword ]; do + while [ "$counter" -lt "$cword" ]; do case ${words[$counter]} in $option_extglob ) - echo ${words[$counter + 1]} + echo "${words[$counter + 1]}" break ;; esac @@ -609,14 +661,14 @@ __docker_to_extglob() { __docker_subcommands() { local subcommands="$1" - local counter=$(($command_pos + 1)) - while [ $counter -lt $cword ]; do + local counter=$((command_pos + 1)) + while [ "$counter" -lt "$cword" ]; do case "${words[$counter]}" in $(__docker_to_extglob "$subcommands") ) subcommand_pos=$counter local subcommand=${words[$counter]} local completions_func=_docker_${command}_${subcommand//-/_} - declare -F $completions_func >/dev/null && $completions_func + declare -F "$completions_func" >/dev/null && "$completions_func" return 0 ;; esac @@ -636,18 +688,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 @@ -754,7 +828,7 @@ __docker_complete_log_options() { local common_options2="env env-regex labels" # awslogs does not implement the $common_options2. - local awslogs_options="$common_options1 awslogs-create-group awslogs-group awslogs-region awslogs-stream tag" + local awslogs_options="$common_options1 awslogs-create-group awslogs-datetime-format awslogs-group awslogs-multiline-pattern awslogs-region awslogs-stream tag" local fluentd_options="$common_options1 $common_options2 fluentd-address fluentd-async-connect fluentd-buffer-limit fluentd-retry-wait fluentd-max-retries tag" local gcplogs_options="$common_options1 $common_options2 gcp-log-cmd gcp-meta-id gcp-meta-name gcp-meta-zone gcp-project" @@ -929,7 +1003,7 @@ __docker_complete_signals() { SIGUSR1 SIGUSR2 ) - COMPREPLY=( $( compgen -W "${signals[*]} ${signals[*]#SIG}" -- "$( echo $cur | tr '[:lower:]' '[:upper:]')" ) ) + COMPREPLY=( $( compgen -W "${signals[*]} ${signals[*]#SIG}" -- "$( echo "$cur" | tr '[:lower:]' '[:upper:]')" ) ) } __docker_complete_user_group() { @@ -969,7 +1043,7 @@ _docker_docker() { ;; *) local counter=$( __docker_pos_first_nonflag "$(__docker_to_extglob "$global_options_with_args")" ) - if [ $cword -eq $counter ]; then + if [ "$cword" -eq "$counter" ]; then __docker_daemon_is_experimental && commands+=(${experimental_commands[*]}) COMPREPLY=( $( compgen -W "${commands[*]} help" -- "$cur" ) ) fi @@ -1022,7 +1096,7 @@ _docker_checkpoint_create() { ;; *) local counter=$(__docker_pos_first_nonflag '--checkpoint-dir') - if [ $cword -eq $counter ]; then + if [ "$cword" -eq "$counter" ]; then __docker_complete_containers_running fi ;; @@ -1043,7 +1117,7 @@ _docker_checkpoint_ls() { ;; *) local counter=$(__docker_pos_first_nonflag '--checkpoint-dir') - if [ $cword -eq $counter ]; then + if [ "$cword" -eq "$counter" ]; then __docker_complete_containers_all fi ;; @@ -1064,9 +1138,9 @@ _docker_checkpoint_rm() { ;; *) local counter=$(__docker_pos_first_nonflag '--checkpoint-dir') - if [ $cword -eq $counter ]; then + if [ "$cword" -eq "$counter" ]; then __docker_complete_containers_all - elif [ $cword -eq $(($counter + 1)) ]; then + elif [ "$cword" -eq "$((counter + 1))" ]; then COMPREPLY=( $( compgen -W "$(__docker_q checkpoint ls "$prev" | sed 1d)" -- "$cur" ) ) fi ;; @@ -1074,6 +1148,117 @@ _docker_checkpoint_rm() { } +_docker_config() { + local subcommands=" + create + inspect + ls + rm + " + local aliases=" + list + remove + " + __docker_subcommands "$subcommands $aliases" && return + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) + ;; + esac +} + +_docker_config_create() { + case "$prev" in + --label|-l) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help --label -l" -- "$cur" ) ) + ;; + *) + local counter=$(__docker_pos_first_nonflag '--label|-l') + if [ "$cword" -eq $((counter + 1)) ]; then + _filedir + fi + ;; + esac +} + +_docker_config_inspect() { + case "$prev" in + --format|-f) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--format -f --help --pretty" -- "$cur" ) ) + ;; + *) + __docker_complete_configs + ;; + esac +} + +_docker_config_list() { + _docker_config_ls +} + +_docker_config_ls() { + local key=$(__docker_map_key_of_current_option '--filter|-f') + case "$key" in + id) + __docker_complete_configs --cur "${cur##*=}" --id + return + ;; + name) + __docker_complete_configs --cur "${cur##*=}" --name + return + ;; + esac + + case "$prev" in + --filter|-f) + COMPREPLY=( $( compgen -S = -W "id label name" -- "$cur" ) ) + __docker_nospace + return + ;; + --format) + return + ;; + esac + + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--format --filter -f --help --quiet -q" -- "$cur" ) ) + ;; + esac +} + +_docker_config_remove() { + _docker_config_rm +} + +_docker_config_rm() { + case "$cur" in + -*) + COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) + ;; + *) + __docker_complete_configs + ;; + esac +} + + _docker_container() { local subcommands=" attach @@ -1127,7 +1312,7 @@ _docker_container_attach() { ;; *) local counter=$(__docker_pos_first_nonflag '--detach-keys') - if [ $cword -eq $counter ]; then + if [ "$cword" -eq "$counter" ]; then __docker_complete_containers_running fi ;; @@ -1148,13 +1333,13 @@ _docker_container_commit() { *) local counter=$(__docker_pos_first_nonflag '--author|-a|--change|-c|--message|-m') - if [ $cword -eq $counter ]; then + if [ "$cword" -eq "$counter" ]; then __docker_complete_containers_all return fi (( counter++ )) - if [ $cword -eq $counter ]; then + if [ "$cword" -eq "$counter" ]; then __docker_complete_image_repos_and_tags return fi @@ -1169,7 +1354,7 @@ _docker_container_cp() { ;; *) local counter=$(__docker_pos_first_nonflag) - if [ $cword -eq $counter ]; then + if [ "$cword" -eq "$counter" ]; then case "$cur" in *:) return @@ -1184,6 +1369,7 @@ _docker_container_cp() { local containers=( ${COMPREPLY[@]} ) COMPREPLY=( $( compgen -W "${files[*]} ${containers[*]}" -- "$cur" ) ) + # shellcheck disable=SC2128 if [[ "$COMPREPLY" == *: ]]; then __docker_nospace fi @@ -1193,7 +1379,7 @@ _docker_container_cp() { fi (( counter++ )) - if [ $cword -eq $counter ]; then + if [ "$cword" -eq "$counter" ]; then if [ -e "$prev" ]; then __docker_complete_containers_all COMPREPLY=( $( compgen -W "${COMPREPLY[*]}" -S ':' ) ) @@ -1218,7 +1404,7 @@ _docker_container_diff() { ;; *) local counter=$(__docker_pos_first_nonflag) - if [ $cword -eq $counter ]; then + if [ "$cword" -eq "$counter" ]; then __docker_complete_containers_all fi ;; @@ -1230,7 +1416,7 @@ _docker_container_exec() { case "$prev" in --env|-e) - # we do not append a "=" here because "-e VARNAME" is legal systax, too + # we do not append a "=" here because "-e VARNAME" is legal syntax, too COMPREPLY=( $( compgen -e -- "$cur" ) ) __docker_nospace return @@ -1265,7 +1451,7 @@ _docker_container_export() { ;; *) local counter=$(__docker_pos_first_nonflag) - if [ $cword -eq $counter ]; then + if [ "$cword" -eq "$counter" ]; then __docker_complete_containers_all fi ;; @@ -1307,7 +1493,7 @@ _docker_container_logs() { ;; *) local counter=$(__docker_pos_first_nonflag '--since|--tail') - if [ $cword -eq $counter ]; then + if [ "$cword" -eq "$counter" ]; then __docker_complete_containers_all fi ;; @@ -1403,7 +1589,7 @@ _docker_container_port() { ;; *) local counter=$(__docker_pos_first_nonflag) - if [ $cword -eq $counter ]; then + if [ "$cword" -eq "$counter" ]; then __docker_complete_containers_all fi ;; @@ -1413,7 +1599,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 ;; @@ -1437,7 +1623,7 @@ _docker_container_rename() { ;; *) local counter=$(__docker_pos_first_nonflag) - if [ $cword -eq $counter ]; then + if [ "$cword" -eq "$counter" ]; then __docker_complete_containers_all fi ;; @@ -1586,7 +1772,7 @@ _docker_container_run_and_create() { --tty -t " - if [ "$command" = "run" -o "$subcommand" = "run" ] ; then + if [ "$command" = "run" ] || [ "$subcommand" = "run" ] ; then options_with_args="$options_with_args --detach-keys " @@ -1664,7 +1850,7 @@ _docker_container_run_and_create() { return ;; --env|-e) - # we do not append a "=" here because "-e VARNAME" is legal systax, too + # we do not append a "=" here because "-e VARNAME" is legal syntax, too COMPREPLY=( $( compgen -e -- "$cur" ) ) __docker_nospace return @@ -1677,6 +1863,7 @@ _docker_container_run_and_create() { ;; *) COMPREPLY=( $( compgen -W 'host container:' -- "$cur" ) ) + # shellcheck disable=SC2128 if [ "$COMPREPLY" = "container:" ]; then __docker_nospace fi @@ -1731,6 +1918,7 @@ _docker_container_run_and_create() { ;; *) COMPREPLY=( $( compgen -W 'host container:' -- "$cur" ) ) + # shellcheck disable=SC2128 if [ "$COMPREPLY" = "container:" ]; then __docker_nospace fi @@ -1784,8 +1972,8 @@ _docker_container_run_and_create() { COMPREPLY=( $( compgen -W "$all_options" -- "$cur" ) ) ;; *) - local counter=$( __docker_pos_first_nonflag $( __docker_to_alternatives "$options_with_args" ) ) - if [ $cword -eq $counter ]; then + local counter=$( __docker_pos_first_nonflag "$( __docker_to_alternatives "$options_with_args" )" ) + if [ "$cword" -eq "$counter" ]; then __docker_complete_images fi ;; @@ -1794,7 +1982,7 @@ _docker_container_run_and_create() { _docker_container_start() { __docker_complete_detach_keys && return - + # shellcheck disable=SC2078 case "$prev" in --checkpoint) if [ __docker_daemon_is_experimental ] ; then @@ -1862,7 +2050,7 @@ _docker_container_top() { ;; *) local counter=$(__docker_pos_first_nonflag) - if [ $cword -eq $counter ]; then + if [ "$cword" -eq "$counter" ]; then __docker_complete_containers_running fi ;; @@ -1876,7 +2064,7 @@ _docker_container_unpause() { ;; *) local counter=$(__docker_pos_first_nonflag) - if [ $cword -eq $counter ]; then + if [ "$cword" -eq "$counter" ]; then __docker_complete_containers_unpauseable fi ;; @@ -1962,9 +2150,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 +2170,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 +2194,7 @@ _docker_daemon() { --log-opt --max-concurrent-downloads --max-concurrent-uploads + --metrics-addr --mtu --oom-score-adjust --pidfile -p @@ -2009,6 +2203,7 @@ _docker_daemon() { --shutdown-timeout --storage-driver -s --storage-opt + --swarm-default-advertise-addr --userland-proxy-path --userns-remap " @@ -2069,7 +2264,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 +2289,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 +2304,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 +2325,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 @@ -2166,7 +2377,7 @@ _docker_export() { _docker_help() { local counter=$(__docker_pos_first_nonflag) - if [ $cword -eq $counter ]; then + if [ "$cword" -eq "$counter" ]; then COMPREPLY=( $( compgen -W "${commands[*]}" -- "$cur" ) ) fi } @@ -2221,6 +2432,7 @@ _docker_image_build() { --cpu-period --cpu-quota --file -f + --iidfile --label --memory -m --memory-swap @@ -2265,7 +2477,7 @@ _docker_image_build() { __docker_complete_image_repos_and_tags return ;; - --file|-f) + --file|-f|--iidfile) _filedir return ;; @@ -2303,8 +2515,8 @@ _docker_image_build() { COMPREPLY=( $( compgen -W "$all_options" -- "$cur" ) ) ;; *) - local counter=$( __docker_pos_first_nonflag $( __docker_to_alternatives "$options_with_args" ) ) - if [ $cword -eq $counter ]; then + local counter=$( __docker_pos_first_nonflag "$( __docker_to_alternatives "$options_with_args" )" ) + if [ "$cword" -eq "$counter" ]; then _filedir -d fi ;; @@ -2324,7 +2536,7 @@ _docker_image_history() { ;; *) local counter=$(__docker_pos_first_nonflag) - if [ $cword -eq $counter ]; then + if [ "$cword" -eq "$counter" ]; then __docker_complete_images fi ;; @@ -2348,12 +2560,12 @@ _docker_image_import() { ;; *) local counter=$(__docker_pos_first_nonflag '--change|-c|--message|-m') - if [ $cword -eq $counter ]; then + if [ "$cword" -eq "$counter" ]; then return fi (( counter++ )) - if [ $cword -eq $counter ]; then + if [ "$cword" -eq "$counter" ]; then __docker_complete_image_repos_and_tags return fi @@ -2428,7 +2640,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 ;; @@ -2448,7 +2660,7 @@ _docker_image_pull() { ;; *) local counter=$(__docker_pos_first_nonflag) - if [ $cword -eq $counter ]; then + if [ "$cword" -eq "$counter" ]; then for arg in "${COMP_WORDS[@]}"; do case "$arg" in --all-tags|-a) @@ -2470,7 +2682,7 @@ _docker_image_push() { ;; *) local counter=$(__docker_pos_first_nonflag) - if [ $cword -eq $counter ]; then + if [ "$cword" -eq "$counter" ]; then __docker_complete_image_repos_and_tags fi ;; @@ -2522,13 +2734,13 @@ _docker_image_tag() { *) local counter=$(__docker_pos_first_nonflag) - if [ $cword -eq $counter ]; then + if [ "$cword" -eq "$counter" ]; then __docker_complete_image_repos_and_tags return fi (( counter++ )) - if [ $cword -eq $counter ]; then + if [ "$cword" -eq "$counter" ]; then __docker_complete_image_repos_and_tags return fi @@ -2639,7 +2851,7 @@ _docker_login() { case "$cur" in -*) - COMPREPLY=( $( compgen -W "--help --password -p --username -u" -- "$cur" ) ) + COMPREPLY=( $( compgen -W "--help --password --password-stdin -p --username -u" -- "$cur" ) ) ;; esac } @@ -2692,10 +2904,10 @@ _docker_network_connect() { COMPREPLY=( $( compgen -W "$boolean_options $options_with_args" -- "$cur" ) ) ;; *) - local counter=$( __docker_pos_first_nonflag $( __docker_to_alternatives "$options_with_args" ) ) - if [ $cword -eq $counter ]; then + local counter=$( __docker_pos_first_nonflag "$( __docker_to_alternatives "$options_with_args" )" ) + if [ "$cword" -eq "$counter" ]; then __docker_complete_networks - elif [ $cword -eq $(($counter + 1)) ]; then + elif [ "$cword" -eq "$((counter + 1))" ]; then __docker_complete_containers_all fi ;; @@ -2707,8 +2919,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 +2928,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 } @@ -2735,9 +2955,9 @@ _docker_network_disconnect() { ;; *) local counter=$(__docker_pos_first_nonflag) - if [ $cword -eq $counter ]; then + if [ "$cword" -eq "$counter" ]; then __docker_complete_networks - elif [ $cword -eq $(($counter + 1)) ]; then + elif [ "$cword" -eq "$((counter + 1))" ]; then __docker_complete_containers_in_network "$prev" fi ;; @@ -2806,7 +3026,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 ;; @@ -2916,7 +3136,7 @@ _docker_service_logs() { ;; *) local counter=$(__docker_pos_first_nonflag '--since|--tail') - if [ $cword -eq $counter ]; then + if [ "$cword" -eq "$counter" ]; then __docker_complete_services_and_tasks fi ;; @@ -3023,7 +3243,7 @@ _docker_service_ps() { ;; *) local counter=$(__docker_pos_first_nonflag '--filter|-f') - if [ $cword -eq $counter ]; then + if [ "$cword" -eq "$counter" ]; then __docker_complete_services fi ;; @@ -3038,6 +3258,7 @@ _docker_service_update() { # and `docker service update` _docker_service_update_and_create() { local options_with_args=" + --credential-spec --endpoint-mode --entrypoint --env -e @@ -3054,7 +3275,6 @@ _docker_service_update_and_create() { --log-driver --log-opt --mount - --network --replicas --reserve-cpu --reserve-memory @@ -3081,7 +3301,7 @@ _docker_service_update_and_create() { " local boolean_options=" - --detach -d + --detach=false -d=false --help --no-healthcheck --read-only @@ -3093,6 +3313,7 @@ _docker_service_update_and_create() { if [ "$subcommand" = "create" ] ; then options_with_args="$options_with_args + --config --constraint --container-label --dns @@ -3103,12 +3324,17 @@ _docker_service_update_and_create() { --host --mode --name + --network --placement-pref --publish -p --secret " case "$prev" in + --config) + __docker_complete_configs + return + ;; --env-file) _filedir return @@ -3143,6 +3369,8 @@ _docker_service_update_and_create() { if [ "$subcommand" = "update" ] ; then options_with_args="$options_with_args --args + --config-add + --config-rm --constraint-add --constraint-rm --container-label-add @@ -3170,6 +3398,10 @@ _docker_service_update_and_create() { " case "$prev" in + --config-add|--config-rm) + __docker_complete_configs + return + ;; --group-add|--group-rm) COMPREPLY=( $(compgen -g -- "$cur") ) return @@ -3268,13 +3500,13 @@ _docker_service_update_and_create() { COMPREPLY=( $( compgen -W "$boolean_options $options_with_args" -- "$cur" ) ) ;; *) - local counter=$( __docker_pos_first_nonflag $( __docker_to_alternatives "$options_with_args" ) ) + local counter=$( __docker_pos_first_nonflag "$( __docker_to_alternatives "$options_with_args" )" ) if [ "$subcommand" = "update" ] ; then - if [ $cword -eq $counter ]; then + if [ "$cword" -eq "$counter" ]; then __docker_complete_services fi else - if [ $cword -eq $counter ]; then + if [ "$cword" -eq "$counter" ]; then __docker_complete_images fi fi @@ -3413,7 +3645,7 @@ _docker_swarm_join_token() { ;; *) local counter=$( __docker_pos_first_nonflag ) - if [ $cword -eq $counter ]; then + if [ "$cword" -eq "$counter" ]; then COMPREPLY=( $( compgen -W "manager worker" -- "$cur" ) ) fi ;; @@ -3632,7 +3864,7 @@ _docker_node_update() { ;; *) local counter=$(__docker_pos_first_nonflag '--availability|--label-add|--label-rm|--role') - if [ $cword -eq $counter ]; then + if [ "$cword" -eq "$counter" ]; then __docker_complete_nodes fi ;; @@ -3679,10 +3911,10 @@ _docker_plugin_create() { ;; *) local counter=$(__docker_pos_first_nonflag) - if [ $cword -eq $counter ]; then + if [ "$cword" -eq "$counter" ]; then # reponame return - elif [ $cword -eq $((counter + 1)) ]; then + elif [ "$cword" -eq "$((counter + 1))" ]; then _filedir -d fi ;; @@ -3696,7 +3928,7 @@ _docker_plugin_disable() { ;; *) local counter=$(__docker_pos_first_nonflag) - if [ $cword -eq $counter ]; then + if [ "$cword" -eq "$counter" ]; then __docker_complete_plugins_installed --filter enabled=true fi ;; @@ -3716,7 +3948,7 @@ _docker_plugin_enable() { ;; *) local counter=$(__docker_pos_first_nonflag '--timeout') - if [ $cword -eq $counter ]; then + if [ "$cword" -eq "$counter" ]; then __docker_complete_plugins_installed --filter enabled=false fi ;; @@ -3762,7 +3994,7 @@ _docker_plugin_ls() { local key=$(__docker_map_key_of_current_option '--filter|-f') case "$key" in capability) - COMPREPLY=( $( compgen -W "authz ipamdriver networkdriver volumedriver" -- "${cur##*=}" ) ) + COMPREPLY=( $( compgen -W "authz ipamdriver logdriver metricscollector networkdriver volumedriver" -- "${cur##*=}" ) ) return ;; enabled) @@ -3796,7 +4028,7 @@ _docker_plugin_push() { ;; *) local counter=$(__docker_pos_first_nonflag) - if [ $cword -eq $counter ]; then + if [ "$cword" -eq "$counter" ]; then __docker_complete_plugins_installed fi ;; @@ -3825,7 +4057,7 @@ _docker_plugin_set() { ;; *) local counter=$(__docker_pos_first_nonflag) - if [ $cword -eq $counter ]; then + if [ "$cword" -eq "$counter" ]; then __docker_complete_plugins_installed fi ;; @@ -3839,10 +4071,10 @@ _docker_plugin_upgrade() { ;; *) local counter=$(__docker_pos_first_nonflag) - if [ $cword -eq $counter ]; then + if [ "$cword" -eq "$counter" ]; then __docker_complete_plugins_installed __ltrim_colon_completions "$cur" - elif [ $cword -eq $((counter + 1)) ]; then + elif [ "$cword" -eq "$((counter + 1))" ]; then local plugin_images="$(__docker_plugins_installed)" COMPREPLY=( $(compgen -S : -W "${plugin_images%:*}" -- "$cur") ) __docker_nospace @@ -3939,7 +4171,7 @@ _docker_secret_inspect() { case "$cur" in -*) - COMPREPLY=( $( compgen -W "--format -f --help" -- "$cur" ) ) + COMPREPLY=( $( compgen -W "--format -f --help --pretty" -- "$cur" ) ) ;; *) __docker_complete_secrets @@ -3983,6 +4215,10 @@ _docker_secret_ls() { } _docker_secret_remove() { + _docker_secret_rm +} + +_docker_secret_rm() { case "$cur" in -*) COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) @@ -3993,10 +4229,6 @@ _docker_secret_remove() { esac } -_docker_secret_rm() { - _docker_secret_remove -} - _docker_search() { @@ -4136,7 +4368,7 @@ _docker_stack_ps() { ;; *) local counter=$(__docker_pos_first_nonflag '--filter|-f') - if [ $cword -eq $counter ]; then + if [ "$cword" -eq "$counter" ]; then __docker_complete_stacks fi ;; @@ -4190,7 +4422,7 @@ _docker_stack_services() { ;; *) local counter=$(__docker_pos_first_nonflag '--filter|-f|--format') - if [ $cword -eq $counter ]; then + if [ "$cword" -eq "$counter" ]; then __docker_complete_stacks fi ;; @@ -4359,7 +4591,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 +4710,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 } @@ -4533,6 +4773,7 @@ _docker() { shopt -s extglob local management_commands=( + config container image network @@ -4624,7 +4865,7 @@ _docker() { local command='docker' command_pos=0 subcommand_pos local counter=1 - while [ $counter -lt $cword ]; do + while [ "$counter" -lt "$cword" ]; do case "${words[$counter]}" in # save host so that completion can use custom daemon --host|-H) diff --git a/contrib/completion/fish/docker.fish b/contrib/completion/fish/docker.fish index 38957b8b77dd..d8259227764f 100644 --- a/contrib/completion/fish/docker.fish +++ b/contrib/completion/fish/docker.fish @@ -229,6 +229,7 @@ complete -c docker -A -f -n '__fish_seen_subcommand_from load' -s i -l input -d complete -c docker -f -n '__fish_docker_no_subcommand' -a login -d 'Log in to a Docker registry server' complete -c docker -A -f -n '__fish_seen_subcommand_from login' -l help -d 'Print usage' complete -c docker -A -f -n '__fish_seen_subcommand_from login' -s p -l password -d 'Password' +complete -c docker -A -f -n '__fish_seen_subcommand_from login' -l password-stdin -d 'Read password from stdin' complete -c docker -A -f -n '__fish_seen_subcommand_from login' -s u -l username -d 'Username' # logout diff --git a/contrib/completion/zsh/_docker b/contrib/completion/zsh/_docker index 4b0c1e25c70a..cf6cc795a6bc 100644 --- a/contrib/completion/zsh/_docker +++ b/contrib/completion/zsh/_docker @@ -221,18 +221,19 @@ __docker_get_log_options() { integer ret=1 local log_driver=${opt_args[--log-driver]:-"all"} - local -a common_options awslogs_options fluentd_options gelf_options journald_options json_file_options logentries_options syslog_options splunk_options + local -a common_options common_options2 awslogs_options fluentd_options gelf_options journald_options json_file_options logentries_options syslog_options splunk_options common_options=("max-buffer-size" "mode") - awslogs_options=($common_options "awslogs-region" "awslogs-group" "awslogs-stream" "awslogs-create-group") - fluentd_options=($common_options "env" "fluentd-address" "fluentd-async-connect" "fluentd-buffer-limit" "fluentd-retry-wait" "fluentd-max-retries" "labels" "tag") - gcplogs_options=($common_options "env" "gcp-log-cmd" "gcp-project" "labels") - gelf_options=($common_options "env" "gelf-address" "gelf-compression-level" "gelf-compression-type" "labels" "tag") - journald_options=($common_options "env" "labels" "tag") - json_file_options=($common_options "env" "labels" "max-file" "max-size") - logentries_options=($common_options "logentries-token") - syslog_options=($common_options "env" "labels" "syslog-address" "syslog-facility" "syslog-format" "syslog-tls-ca-cert" "syslog-tls-cert" "syslog-tls-key" "syslog-tls-skip-verify" "tag") - splunk_options=($common_options "env" "labels" "splunk-caname" "splunk-capath" "splunk-format" "splunk-gzip" "splunk-gzip-level" "splunk-index" "splunk-insecureskipverify" "splunk-source" "splunk-sourcetype" "splunk-token" "splunk-url" "splunk-verify-connection" "tag") + common_options2=("env" "env-regex" "labels") + awslogs_options=($common_options "awslogs-create-group" "awslogs-datetime-format" "awslogs-group" "awslogs-multiline-pattern" "awslogs-region" "awslogs-stream" "tag") + fluentd_options=($common_options $common_options2 "fluentd-address" "fluentd-async-connect" "fluentd-buffer-limit" "fluentd-retry-wait" "fluentd-max-retries" "tag") + gcplogs_options=($common_options $common_options2 "gcp-log-cmd" "gcp-meta-id" "gcp-meta-name" "gcp-meta-zone" "gcp-project") + gelf_options=($common_options $common_options2 "gelf-address" "gelf-compression-level" "gelf-compression-type" "tag") + journald_options=($common_options $common_options2 "tag") + json_file_options=($common_options $common_options2 "max-file" "max-size") + logentries_options=($common_options $common_options2 "logentries-token" "tag") + syslog_options=($common_options $common_options2 "syslog-address" "syslog-facility" "syslog-format" "syslog-tls-ca-cert" "syslog-tls-cert" "syslog-tls-key" "syslog-tls-skip-verify" "tag") + splunk_options=($common_options $common_options2 "splunk-caname" "splunk-capath" "splunk-format" "splunk-gzip" "splunk-gzip-level" "splunk-index" "splunk-insecureskipverify" "splunk-source" "splunk-sourcetype" "splunk-token" "splunk-url" "splunk-verify-connection" "tag") [[ $log_driver = (awslogs|all) ]] && _describe -t awslogs-options "awslogs options" awslogs_options "$@" && ret=0 [[ $log_driver = (fluentd|all) ]] && _describe -t fluentd-options "fluentd options" fluentd_options "$@" && ret=0 @@ -1520,7 +1521,7 @@ __docker_plugin_complete_ls_filters() { if compset -P '*='; then case "${${words[-1]%=*}#*=}" in (capability) - opts=('authz' 'ipamdriver' 'networkdriver' 'volumedriver') + opts=('authz' 'ipamdriver' 'logdriver' 'metricscollector' 'networkdriver' 'volumedriver') _describe -t capability-opts "capability options" opts && ret=0 ;; (enabled) @@ -1960,7 +1961,6 @@ __docker_service_subcommand() { "($help)*--mount=[Attach a filesystem mount to the service]:mount: " "($help)*--network=[Network attachments]:network: " "($help)--no-healthcheck[Disable any container-specified HEALTHCHECK]" - "($help)*"{-p=,--publish=}"[Publish a port as a node port]:port: " "($help)--read-only[Mount the container's root filesystem as read only]" "($help)--replicas=[Number of tasks]:replicas: " "($help)--reserve-cpu=[Reserve CPUs]:value: " @@ -2001,7 +2001,7 @@ __docker_service_subcommand() { "($help)--mode=[Service Mode]:mode:(global replicated)" \ "($help)--name=[Service name]:name: " \ "($help)*--placement-pref=[Add a placement preference]:pref:__docker_service_complete_placement_pref" \ - "($help)*--publish=[Publish a port]:port: " \ + "($help)*"{-p=,--publish=}"[Publish a port as a node port]:port: " \ "($help -): :__docker_complete_images" \ "($help -):command: _command_names -e" \ "($help -)*::arguments: _normal" && ret=0 @@ -2376,7 +2376,8 @@ __docker_system_subcommand() { $opts_help \ "($help -a --all)"{-a,--all}"[Remove all unused data, not just dangling ones]" \ "($help)*--filter=[Filter values]:filter:__docker_complete_prune_filters" \ - "($help -f --force)"{-f,--force}"[Do not prompt for confirmation]" && ret=0 + "($help -f --force)"{-f,--force}"[Do not prompt for confirmation]" \ + "($help)--volumes=[Remove all unused volumes]" && ret=0 ;; (help) _arguments $(__docker_arguments) ":subcommand:__docker_volume_commands" && ret=0 @@ -2761,6 +2762,7 @@ __docker_subcommand() { _arguments $(__docker_arguments) -A '-*' \ $opts_help \ "($help -p --password)"{-p=,--password=}"[Password]:password: " \ + "($help)--password-stdin[Read password from stdin]" \ "($help -u --user)"{-u=,--user=}"[Username]:username: " \ "($help -)1:server: " && ret=0 ;; diff --git a/docker.Makefile b/docker.Makefile index ef8dbfb926a7..9b958397a17a 100644 --- a/docker.Makefile +++ b/docker.Makefile @@ -7,6 +7,7 @@ DEV_DOCKER_IMAGE_NAME = docker-cli-dev LINTER_IMAGE_NAME = docker-cli-lint CROSS_IMAGE_NAME = docker-cli-cross +VALIDATE_IMAGE_NAME = docker-cli-shell-validate MOUNTS = -v "$(CURDIR)":/go/src/github.com/docker/cli VERSION = $(shell cat VERSION) ENVVARS = -e VERSION=$(VERSION) -e GITCOMMIT @@ -14,17 +15,20 @@ 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 . +.PHONY: build_shell_validate_image +build_shell_validate_image: + docker build -t $(VALIDATE_IMAGE_NAME) -f ./dockerfiles/Dockerfile.shellcheck . # build executable using a container binary: build_docker_image @@ -80,3 +84,7 @@ manpages: build_docker_image .PHONY: yamldocs yamldocs: build_docker_image docker run -ti --rm $(MOUNTS) $(DEV_DOCKER_IMAGE_NAME) make yamldocs + +.PHONY: shellcheck +shellcheck: build_shell_validate_image + docker run -ti --rm $(MOUNTS) $(VALIDATE_IMAGE_NAME) make shellcheck diff --git a/dockerfiles/Dockerfile.cross b/dockerfiles/Dockerfile.cross index 19907ced4914..60487dca90f1 100644 --- a/dockerfiles/Dockerfile.cross +++ b/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/dockerfiles/Dockerfile.dev b/dockerfiles/Dockerfile.dev index aef37382c871..7f9482e61255 100644 --- a/dockerfiles/Dockerfile.dev +++ b/dockerfiles/Dockerfile.dev @@ -3,16 +3,25 @@ FROM golang:1.8.3-alpine RUN apk add -U git make bash coreutils -RUN go get github.com/LK4D4/vndr && \ - cp /go/bin/vndr /usr/bin && \ +ARG VNDR_SHA=9909bb2b8a0b7ea464527b376dc50389c90df587 +RUN go get -d github.com/LK4D4/vndr && \ + 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/* -RUN go get github.com/jteeuwen/go-bindata/go-bindata && \ - cp /go/bin/go-bindata /usr/bin && \ +ARG BINDATA_SHA=a0ff2567cfb70903282db057e799fd826784d41d +RUN go get -d github.com/jteeuwen/go-bindata/go-bindata && \ + 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/* -RUN go get github.com/dnephin/filewatcher && \ - cp /go/bin/filewatcher /usr/bin/ && \ +ARG FILEWATCHER_SHA=2e12ea42f6c8c089b19e992145bb94e8adaecedb +RUN go get -d github.com/dnephin/filewatcher && \ + 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/dockerfiles/Dockerfile.lint b/dockerfiles/Dockerfile.lint index 240af474c54f..c981efbadc55 100644 --- a/dockerfiles/Dockerfile.lint +++ b/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 -d 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/dockerfiles/Dockerfile.shellcheck b/dockerfiles/Dockerfile.shellcheck new file mode 100644 index 000000000000..12f665f7a733 --- /dev/null +++ b/dockerfiles/Dockerfile.shellcheck @@ -0,0 +1,9 @@ +FROM debian:stretch-slim + +RUN apt-get update && \ + apt-get -y install make shellcheck && \ + apt-get clean + +WORKDIR /go/src/github.com/docker/cli + +CMD bash diff --git a/dockerfiles/osx-cross.sh b/dockerfiles/osx-cross.sh deleted file mode 100755 index 840334a135be..000000000000 --- a/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/docs/README.md b/docs/README.md index da9309307592..28d1f0e9a06c 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,7 +1,7 @@ # The non-reference docs have been moved! - Fail // C:\ --> \ diff --git a/vendor/github.com/docker/docker/pkg/system/rm.go b/vendor/github.com/docker/docker/pkg/system/rm.go index ca0621f04fac..101b569a5656 100644 --- a/vendor/github.com/docker/docker/pkg/system/rm.go +++ b/vendor/github.com/docker/docker/pkg/system/rm.go @@ -20,7 +20,7 @@ import ( // These types of errors do not need to be returned since it's ok for the dir to // be gone we can just retry the remove operation. // -// This should not return a `os.ErrNotExist` kind of error under any cirucmstances +// This should not return a `os.ErrNotExist` kind of error under any circumstances func EnsureRemoveAll(dir string) error { notExistErr := make(map[string]bool) diff --git a/vendor/github.com/docker/docker/pkg/templates/templates.go b/vendor/github.com/docker/docker/pkg/templates/templates.go index 75a3dd974eaf..d2d7e0c3d71e 100644 --- a/vendor/github.com/docker/docker/pkg/templates/templates.go +++ b/vendor/github.com/docker/docker/pkg/templates/templates.go @@ -30,7 +30,7 @@ var basicFunctions = template.FuncMap{ // HeaderFunctions are used to created headers of a table. // This is a replacement of basicFunctions for header generation // because we want the header to remain intact. -// Some functions like `split` are irrevelant so not added. +// Some functions like `split` are irrelevant so not added. var HeaderFunctions = template.FuncMap{ "json": func(v string) string { return v diff --git a/vendor/github.com/docker/docker/pkg/urlutil/urlutil.go b/vendor/github.com/docker/docker/pkg/urlutil/urlutil.go index 44152873b1f9..cfcd582036c2 100644 --- a/vendor/github.com/docker/docker/pkg/urlutil/urlutil.go +++ b/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/vendor/github.com/docker/docker/registry/config.go b/vendor/github.com/docker/docker/registry/config.go index 651bd730972b..182599e38dfd 100644 --- a/vendor/github.com/docker/docker/registry/config.go +++ b/vendor/github.com/docker/docker/registry/config.go @@ -252,7 +252,7 @@ skip: return nil } -// allowNondistributableArtifacts returns true if the provided hostname is part of the list of regsitries +// allowNondistributableArtifacts returns true if the provided hostname is part of the list of registries // that allow push of nondistributable artifacts. // // The list can contain elements with CIDR notation to specify a whole subnet. If the subnet contains an IP diff --git a/vendor/github.com/docker/docker/registry/endpoint_v1.go b/vendor/github.com/docker/docker/registry/endpoint_v1.go index 6bcf8c935d13..c5ca961dd420 100644 --- a/vendor/github.com/docker/docker/registry/endpoint_v1.go +++ b/vendor/github.com/docker/docker/registry/endpoint_v1.go @@ -175,7 +175,7 @@ func (e *V1Endpoint) Ping() (PingResult, error) { Standalone: true, } if err := json.Unmarshal(jsonString, &info); err != nil { - logrus.Debugf("Error unmarshalling the _ping PingResult: %s", err) + logrus.Debugf("Error unmarshaling the _ping PingResult: %s", err) // don't stop here. Just assume sane defaults } if hdr := resp.Header.Get("X-Docker-Registry-Version"); hdr != "" { diff --git a/vendor/github.com/docker/docker/vendor.conf b/vendor/github.com/docker/docker/vendor.conf index 83cedfd52bdf..20460d5cc9cd 100644 --- a/vendor/github.com/docker/docker/vendor.conf +++ b/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,16 +8,15 @@ 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 github.com/vdemeester/shakers 24d7f1d6a71aa5d9cbe7390e4afb66b7eef9e1b3 -# forked golang.org/x/net package includes a patch for lazy loading trace templates 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 +26,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 +105,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/vendor/github.com/docker/docker/volume/volume.go b/vendor/github.com/docker/docker/volume/volume.go index 2abfcc7b5883..8598d4cb8f8c 100644 --- a/vendor/github.com/docker/docker/volume/volume.go +++ b/vendor/github.com/docker/docker/volume/volume.go @@ -125,7 +125,7 @@ type MountPoint struct { Spec mounttypes.Mount // Track usage of this mountpoint - // Specicially needed for containers which are running and calls to `docker cp` + // Specifically needed for containers which are running and calls to `docker cp` // because both these actions require mounting the volumes. active int } @@ -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/vendor/github.com/docker/docker/volume/volume_linux.go b/vendor/github.com/docker/docker/volume/volume_linux.go index d4b4d800b223..fdf7b63e4b22 100644 --- a/vendor/github.com/docker/docker/volume/volume_linux.go +++ b/vendor/github.com/docker/docker/volume/volume_linux.go @@ -26,7 +26,7 @@ func ConvertTmpfsOptions(opt *mounttypes.TmpfsOptions, readOnly bool) (string, e // okay, since API is that way anyways. // we do this by finding the suffix that divides evenly into the - // value, returing the value itself, with no suffix, if it fails. + // value, returning the value itself, with no suffix, if it fails. // // For the most part, we don't enforce any semantic to this values. // The operating system will usually align this and enforce minimum diff --git a/vendor/github.com/docker/swarmkit/api/objects.pb.go b/vendor/github.com/docker/swarmkit/api/objects.pb.go index e9c2438502ce..b6a9389a6d78 100644 --- a/vendor/github.com/docker/swarmkit/api/objects.pb.go +++ b/vendor/github.com/docker/swarmkit/api/objects.pb.go @@ -198,7 +198,8 @@ type Task struct { // such a cluster default or policy-based value. // // If not present, the daemon's default will be used. - LogDriver *Driver `protobuf:"bytes,13,opt,name=log_driver,json=logDriver" json:"log_driver,omitempty"` + LogDriver *Driver `protobuf:"bytes,13,opt,name=log_driver,json=logDriver" json:"log_driver,omitempty"` + AssignedGenericResources []*GenericResource `protobuf:"bytes,15,rep,name=assigned_generic_resources,json=assignedGenericResources" json:"assigned_generic_resources,omitempty"` } func (m *Task) Reset() { *m = Task{} } @@ -529,6 +530,14 @@ func (m *Task) CopyFrom(src interface{}) { m.LogDriver = &Driver{} github_com_docker_swarmkit_api_deepcopy.Copy(m.LogDriver, o.LogDriver) } + if o.AssignedGenericResources != nil { + m.AssignedGenericResources = make([]*GenericResource, len(o.AssignedGenericResources)) + for i := range m.AssignedGenericResources { + m.AssignedGenericResources[i] = &GenericResource{} + github_com_docker_swarmkit_api_deepcopy.Copy(m.AssignedGenericResources[i], o.AssignedGenericResources[i]) + } + } + } func (m *NetworkAttachment) Copy() *NetworkAttachment { @@ -1140,6 +1149,18 @@ func (m *Task) MarshalTo(dAtA []byte) (int, error) { } i += n26 } + if len(m.AssignedGenericResources) > 0 { + for _, msg := range m.AssignedGenericResources { + dAtA[i] = 0x7a + i++ + i = encodeVarintObjects(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } + } return i, nil } @@ -1771,6 +1792,12 @@ func (m *Task) Size() (n int) { l = m.SpecVersion.Size() n += 1 + l + sovObjects(uint64(l)) } + if len(m.AssignedGenericResources) > 0 { + for _, e := range m.AssignedGenericResources { + l = e.Size() + n += 1 + l + sovObjects(uint64(l)) + } + } return n } @@ -4419,6 +4446,7 @@ func (this *Task) String() string { `Endpoint:` + strings.Replace(fmt.Sprintf("%v", this.Endpoint), "Endpoint", "Endpoint", 1) + `,`, `LogDriver:` + strings.Replace(fmt.Sprintf("%v", this.LogDriver), "Driver", "Driver", 1) + `,`, `SpecVersion:` + strings.Replace(fmt.Sprintf("%v", this.SpecVersion), "Version", "Version", 1) + `,`, + `AssignedGenericResources:` + strings.Replace(fmt.Sprintf("%v", this.AssignedGenericResources), "GenericResource", "GenericResource", 1) + `,`, `}`, }, "") return s @@ -6001,6 +6029,37 @@ func (m *Task) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 15: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AssignedGenericResources", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowObjects + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthObjects + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AssignedGenericResources = append(m.AssignedGenericResources, &GenericResource{}) + if err := m.AssignedGenericResources[len(m.AssignedGenericResources)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipObjects(dAtA[iNdEx:]) @@ -7630,96 +7689,99 @@ var ( func init() { proto.RegisterFile("objects.proto", fileDescriptorObjects) } var fileDescriptorObjects = []byte{ - // 1451 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x58, 0xcd, 0x6f, 0x1b, 0x45, - 0x14, 0xef, 0xda, 0x1b, 0x7f, 0x3c, 0x27, 0x56, 0x98, 0x86, 0xe0, 0x9a, 0x60, 0x07, 0x57, 0xa0, - 0x0a, 0x55, 0x4e, 0x09, 0x05, 0xa5, 0x81, 0xd2, 0xda, 0x49, 0xd4, 0x5a, 0xa5, 0x34, 0x9a, 0x96, - 0x96, 0x9b, 0x99, 0xec, 0x4e, 0xdd, 0xc5, 0xeb, 0x9d, 0xd5, 0xce, 0xd8, 0xc5, 0x37, 0xce, 0xf9, - 0x07, 0x72, 0xe3, 0xd0, 0x13, 0x77, 0xb8, 0x70, 0xe1, 0xc0, 0xa9, 0x47, 0x4e, 0x88, 0x53, 0x44, - 0xfd, 0x5f, 0x20, 0x71, 0x40, 0x33, 0x3b, 0x6b, 0x6f, 0xea, 0x75, 0x92, 0xa2, 0x2a, 0xe2, 0xe4, - 0xf9, 0xf8, 0xfd, 0xde, 0xd7, 0xbc, 0xf7, 0x66, 0xd6, 0xb0, 0xc0, 0xf6, 0xbe, 0xa5, 0x96, 0xe0, - 0x75, 0x3f, 0x60, 0x82, 0x21, 0x64, 0x33, 0xab, 0x4b, 0x83, 0x3a, 0x7f, 0x4a, 0x82, 0x5e, 0xd7, - 0x11, 0xf5, 0xc1, 0x87, 0xe5, 0x82, 0x18, 0xfa, 0x54, 0x03, 0xca, 0x05, 0xee, 0x53, 0x2b, 0x9a, - 0x54, 0x3b, 0x8c, 0x75, 0x5c, 0xba, 0xa6, 0x66, 0x7b, 0xfd, 0xc7, 0x6b, 0xc2, 0xe9, 0x51, 0x2e, - 0x48, 0xcf, 0xd7, 0x80, 0xa5, 0x0e, 0xeb, 0x30, 0x35, 0x5c, 0x93, 0x23, 0xbd, 0x7a, 0xe1, 0x65, - 0x1a, 0xf1, 0x86, 0x7a, 0xeb, 0xbc, 0xef, 0xf6, 0x3b, 0x8e, 0xb7, 0x16, 0xfe, 0x84, 0x8b, 0xb5, - 0x5f, 0x0c, 0x30, 0xef, 0x52, 0x41, 0xd0, 0xa7, 0x90, 0x1d, 0xd0, 0x80, 0x3b, 0xcc, 0x2b, 0x19, - 0xab, 0xc6, 0xa5, 0xc2, 0xfa, 0xdb, 0xf5, 0x69, 0x7b, 0xeb, 0x0f, 0x43, 0x48, 0xd3, 0x7c, 0x7e, - 0x58, 0x3d, 0x87, 0x23, 0x06, 0xba, 0x06, 0x60, 0x05, 0x94, 0x08, 0x6a, 0xb7, 0x89, 0x28, 0xa5, - 0x14, 0xbf, 0x5c, 0x0f, 0x4d, 0xa9, 0x47, 0xa6, 0xd4, 0x1f, 0x44, 0x1e, 0xe0, 0xbc, 0x46, 0x37, - 0x84, 0xa4, 0xf6, 0x7d, 0x3b, 0xa2, 0xa6, 0x4f, 0xa6, 0x6a, 0x74, 0x43, 0xd4, 0x7e, 0x32, 0xc1, - 0xfc, 0x92, 0xd9, 0x14, 0x2d, 0x43, 0xca, 0xb1, 0x95, 0xd9, 0xf9, 0x66, 0x66, 0x74, 0x58, 0x4d, - 0xb5, 0xb6, 0x71, 0xca, 0xb1, 0xd1, 0x3a, 0x98, 0x3d, 0x2a, 0x88, 0x36, 0xa8, 0x94, 0xe4, 0x90, - 0xf4, 0x5d, 0x7b, 0xa3, 0xb0, 0xe8, 0x13, 0x30, 0xe5, 0x31, 0x68, 0x4b, 0x56, 0x92, 0x38, 0x52, - 0xe7, 0x7d, 0x9f, 0x5a, 0x11, 0x4f, 0xe2, 0xd1, 0x0e, 0x14, 0x6c, 0xca, 0xad, 0xc0, 0xf1, 0x85, - 0x8c, 0xa1, 0xa9, 0xe8, 0x17, 0x67, 0xd1, 0xb7, 0x27, 0x50, 0x1c, 0xe7, 0xa1, 0xcf, 0x20, 0xc3, - 0x05, 0x11, 0x7d, 0x5e, 0x9a, 0x53, 0x12, 0x2a, 0x33, 0x0d, 0x50, 0x28, 0x6d, 0x82, 0xe6, 0xa0, - 0xdb, 0x50, 0xec, 0x11, 0x8f, 0x74, 0x68, 0xd0, 0xd6, 0x52, 0x32, 0x4a, 0xca, 0xbb, 0x89, 0xae, - 0x87, 0xc8, 0x50, 0x10, 0x5e, 0xe8, 0xc5, 0xa7, 0x68, 0x07, 0x80, 0x08, 0x41, 0xac, 0x27, 0x3d, - 0xea, 0x89, 0x52, 0x56, 0x49, 0x79, 0x2f, 0xd1, 0x16, 0x2a, 0x9e, 0xb2, 0xa0, 0xdb, 0x18, 0x83, - 0x71, 0x8c, 0x88, 0x6e, 0x41, 0xc1, 0xa2, 0x81, 0x70, 0x1e, 0x3b, 0x16, 0x11, 0xb4, 0x94, 0x53, - 0x72, 0xaa, 0x49, 0x72, 0xb6, 0x26, 0x30, 0xed, 0x54, 0x9c, 0x89, 0xae, 0x80, 0x19, 0x30, 0x97, - 0x96, 0xf2, 0xab, 0xc6, 0xa5, 0xe2, 0xec, 0x63, 0xc1, 0xcc, 0xa5, 0x58, 0x21, 0x37, 0x97, 0xf7, - 0x0f, 0x6a, 0x08, 0x16, 0x73, 0xc6, 0xa2, 0xa1, 0x52, 0xc3, 0xb8, 0x62, 0x7c, 0x6d, 0x7c, 0x63, - 0xd4, 0xfe, 0x49, 0x43, 0xf6, 0x3e, 0x0d, 0x06, 0x8e, 0xf5, 0x7a, 0x13, 0xe7, 0xda, 0x91, 0xc4, - 0x49, 0xf4, 0x51, 0xab, 0x9d, 0xca, 0x9d, 0x0d, 0xc8, 0x51, 0xcf, 0xf6, 0x99, 0xe3, 0x09, 0x9d, - 0x38, 0x89, 0x0e, 0xee, 0x68, 0x0c, 0x1e, 0xa3, 0xd1, 0x0e, 0x2c, 0x84, 0xf5, 0xd0, 0x3e, 0x92, - 0x35, 0xab, 0x49, 0xf4, 0xaf, 0x14, 0x50, 0x1f, 0xf7, 0x7c, 0x3f, 0x36, 0x43, 0xdb, 0xb0, 0xe0, - 0x07, 0x74, 0xe0, 0xb0, 0x3e, 0x6f, 0x2b, 0x27, 0x32, 0xa7, 0x72, 0x02, 0xcf, 0x47, 0x2c, 0x39, - 0x43, 0x9f, 0xc3, 0xbc, 0x24, 0xb7, 0xa3, 0x3e, 0x02, 0x27, 0xf6, 0x11, 0xac, 0x5a, 0x9e, 0x9e, - 0xa0, 0x7b, 0xf0, 0xe6, 0x11, 0x2b, 0xc6, 0x82, 0x0a, 0x27, 0x0b, 0x3a, 0x1f, 0xb7, 0x44, 0x2f, - 0x6e, 0xa2, 0xfd, 0x83, 0x5a, 0x11, 0xe6, 0xe3, 0x29, 0x50, 0xfb, 0x21, 0x05, 0xb9, 0x28, 0x90, - 0xe8, 0xaa, 0x3e, 0x33, 0x63, 0x76, 0xd4, 0x22, 0xac, 0xf2, 0x37, 0x3c, 0xae, 0xab, 0x30, 0xe7, - 0xb3, 0x40, 0xf0, 0x52, 0x6a, 0x35, 0x3d, 0xab, 0x44, 0x77, 0x59, 0x20, 0xb6, 0x98, 0xf7, 0xd8, - 0xe9, 0xe0, 0x10, 0x8c, 0x1e, 0x41, 0x61, 0xe0, 0x04, 0xa2, 0x4f, 0xdc, 0xb6, 0xe3, 0xf3, 0x52, - 0x5a, 0x71, 0xdf, 0x3f, 0x4e, 0x65, 0xfd, 0x61, 0x88, 0x6f, 0xed, 0x36, 0x8b, 0xa3, 0xc3, 0x2a, - 0x8c, 0xa7, 0x1c, 0x83, 0x16, 0xd5, 0xf2, 0x79, 0xf9, 0x2e, 0xe4, 0xc7, 0x3b, 0xe8, 0x32, 0x80, - 0x17, 0x56, 0x64, 0x7b, 0x9c, 0xd9, 0x0b, 0xa3, 0xc3, 0x6a, 0x5e, 0xd7, 0x69, 0x6b, 0x1b, 0xe7, - 0x35, 0xa0, 0x65, 0x23, 0x04, 0x26, 0xb1, 0xed, 0x40, 0xe5, 0x79, 0x1e, 0xab, 0x71, 0xed, 0xc7, - 0x0c, 0x98, 0x0f, 0x08, 0xef, 0x9e, 0x75, 0x57, 0x95, 0x3a, 0xa7, 0x2a, 0xe3, 0x32, 0x00, 0x0f, - 0xf3, 0x4d, 0xba, 0x63, 0x4e, 0xdc, 0xd1, 0x59, 0x28, 0xdd, 0xd1, 0x80, 0xd0, 0x1d, 0xee, 0x32, - 0xa1, 0x8a, 0xc0, 0xc4, 0x6a, 0x8c, 0x2e, 0x42, 0xd6, 0x63, 0xb6, 0xa2, 0x67, 0x14, 0x1d, 0x46, - 0x87, 0xd5, 0x8c, 0xec, 0x15, 0xad, 0x6d, 0x9c, 0x91, 0x5b, 0x2d, 0x5b, 0xb6, 0x29, 0xe2, 0x79, - 0x4c, 0x10, 0xd9, 0x83, 0xb9, 0x6e, 0x77, 0x89, 0xd9, 0xdf, 0x98, 0xc0, 0xa2, 0x36, 0x15, 0x63, - 0xa2, 0x87, 0x70, 0x3e, 0xb2, 0x37, 0x2e, 0x30, 0xf7, 0x2a, 0x02, 0x91, 0x96, 0x10, 0xdb, 0x89, - 0x5d, 0x0b, 0xf9, 0xd9, 0xd7, 0x82, 0x8a, 0x60, 0xd2, 0xb5, 0xd0, 0x84, 0x05, 0x9b, 0x72, 0x27, - 0xa0, 0xb6, 0x6a, 0x13, 0x54, 0x55, 0x66, 0x71, 0xfd, 0x9d, 0xe3, 0x84, 0x50, 0x3c, 0xaf, 0x39, - 0x6a, 0x86, 0x1a, 0x90, 0xd3, 0x79, 0xc3, 0x4b, 0x05, 0x95, 0xbb, 0xa7, 0xbc, 0x0e, 0xc6, 0xb4, - 0x23, 0x6d, 0x6e, 0xfe, 0x95, 0xda, 0xdc, 0x35, 0x00, 0x97, 0x75, 0xda, 0x76, 0xe0, 0x0c, 0x68, - 0x50, 0x5a, 0xd0, 0x8f, 0x84, 0x04, 0xee, 0xb6, 0x42, 0xe0, 0xbc, 0xcb, 0x3a, 0xe1, 0x70, 0xaa, - 0x29, 0x15, 0x5f, 0xad, 0x29, 0x6d, 0x96, 0xf7, 0x0f, 0x6a, 0xcb, 0xb0, 0x14, 0xef, 0x21, 0x1b, - 0xc6, 0x4d, 0xe3, 0xb6, 0xb1, 0x6b, 0xd4, 0x7e, 0x4b, 0xc1, 0x1b, 0x53, 0x0e, 0xa3, 0x8f, 0x21, - 0xab, 0x5d, 0x3e, 0xee, 0x25, 0xa5, 0x79, 0x38, 0xc2, 0xa2, 0x15, 0xc8, 0xcb, 0xfa, 0xa3, 0x9c, - 0xd3, 0xb0, 0xb3, 0xe4, 0xf1, 0x64, 0x01, 0x95, 0x20, 0x4b, 0x5c, 0x87, 0xc8, 0xbd, 0xb4, 0xda, - 0x8b, 0xa6, 0xa8, 0x0f, 0xcb, 0x61, 0x5c, 0xda, 0x93, 0x7b, 0xb7, 0xcd, 0x7c, 0xc1, 0x4b, 0xa6, - 0x3a, 0xa6, 0x1b, 0xa7, 0x3a, 0x26, 0x1d, 0xb9, 0xc9, 0xc2, 0x3d, 0x5f, 0xf0, 0x1d, 0x4f, 0x04, - 0x43, 0xbc, 0x64, 0x27, 0x6c, 0x95, 0x6f, 0xc1, 0x85, 0x99, 0x14, 0xb4, 0x08, 0xe9, 0x2e, 0x1d, - 0x86, 0xbd, 0x03, 0xcb, 0x21, 0x5a, 0x82, 0xb9, 0x01, 0x71, 0xfb, 0x54, 0xb7, 0x9a, 0x70, 0xb2, - 0x99, 0xda, 0x30, 0x6a, 0xcf, 0x52, 0x90, 0xd5, 0xe6, 0x9c, 0xf5, 0x7d, 0xac, 0xd5, 0x4e, 0x75, - 0x9d, 0xeb, 0x30, 0xaf, 0x43, 0x1a, 0x96, 0x8b, 0x79, 0x62, 0xc2, 0x15, 0x42, 0x7c, 0x58, 0x2a, - 0xd7, 0xc1, 0x74, 0x7c, 0xd2, 0xd3, 0x77, 0x71, 0xa2, 0xe6, 0xd6, 0x6e, 0xe3, 0xee, 0x3d, 0x3f, - 0xac, 0xfa, 0xdc, 0xe8, 0xb0, 0x6a, 0xca, 0x05, 0xac, 0x68, 0x89, 0xb7, 0xd6, 0xcf, 0x73, 0x90, - 0xdd, 0x72, 0xfb, 0x5c, 0xd0, 0xe0, 0xac, 0x83, 0xa4, 0xd5, 0x4e, 0x05, 0x69, 0x0b, 0xb2, 0x01, - 0x63, 0xa2, 0x6d, 0x91, 0xe3, 0xe2, 0x83, 0x19, 0x13, 0x5b, 0x8d, 0x66, 0x51, 0x12, 0x65, 0xe3, - 0x0d, 0xe7, 0x38, 0x23, 0xa9, 0x5b, 0x04, 0x3d, 0x82, 0xe5, 0xe8, 0xba, 0xda, 0x63, 0x4c, 0x70, - 0x11, 0x10, 0xbf, 0xdd, 0xa5, 0x43, 0xf9, 0x90, 0x49, 0xcf, 0x7a, 0xb8, 0xee, 0x78, 0x56, 0x30, - 0x54, 0xc1, 0xbb, 0x43, 0x87, 0x78, 0x49, 0x0b, 0x68, 0x46, 0xfc, 0x3b, 0x74, 0xc8, 0xd1, 0x0d, - 0x58, 0xa1, 0x63, 0x98, 0x94, 0xd8, 0x76, 0x49, 0x4f, 0x5e, 0xc4, 0x6d, 0xcb, 0x65, 0x56, 0x57, - 0xdd, 0x05, 0x26, 0xbe, 0x40, 0xe3, 0xa2, 0xbe, 0x08, 0x11, 0x5b, 0x12, 0x80, 0x38, 0x94, 0xf6, - 0x5c, 0x62, 0x75, 0x5d, 0x87, 0xcb, 0x6f, 0x93, 0xd8, 0x5b, 0x54, 0xb6, 0x73, 0x69, 0xdb, 0xc6, - 0x31, 0xd1, 0xaa, 0x37, 0x27, 0xdc, 0xd8, 0xcb, 0x56, 0x57, 0xd4, 0x5b, 0x7b, 0xc9, 0xbb, 0xa8, - 0x09, 0x85, 0xbe, 0x27, 0xd5, 0x87, 0x31, 0xc8, 0x9f, 0x36, 0x06, 0x10, 0xb2, 0xa4, 0xe7, 0xe5, - 0x01, 0xac, 0x1c, 0xa7, 0x3c, 0xa1, 0x36, 0x6f, 0xc6, 0x6b, 0xb3, 0xb0, 0xfe, 0x41, 0x92, 0xbe, - 0x64, 0x91, 0xb1, 0x3a, 0x4e, 0x4c, 0xdb, 0x5f, 0x0d, 0xc8, 0xdc, 0xa7, 0x56, 0x40, 0xc5, 0x6b, - 0xcd, 0xda, 0x8d, 0x23, 0x59, 0x5b, 0x49, 0x7e, 0xa5, 0x4a, 0xad, 0x53, 0x49, 0x5b, 0x86, 0x9c, - 0xe3, 0x09, 0x1a, 0x78, 0xc4, 0x55, 0x59, 0x9b, 0xc3, 0xe3, 0x79, 0xa2, 0x03, 0xcf, 0x0c, 0xc8, - 0x84, 0xcf, 0xb8, 0xb3, 0x76, 0x20, 0xd4, 0xfa, 0xb2, 0x03, 0x89, 0x46, 0xfe, 0x6d, 0x40, 0x0e, - 0x53, 0xce, 0xfa, 0xc1, 0x6b, 0xfe, 0xa4, 0x79, 0xe9, 0x59, 0x94, 0xfe, 0xcf, 0xcf, 0x22, 0x04, - 0x66, 0xd7, 0xf1, 0xf4, 0x03, 0x0e, 0xab, 0x31, 0xaa, 0x43, 0xd6, 0x27, 0x43, 0x97, 0x11, 0x5b, - 0x37, 0xca, 0xa5, 0xa9, 0xaf, 0xfe, 0x86, 0x37, 0xc4, 0x11, 0x68, 0x73, 0x69, 0xff, 0xa0, 0xb6, - 0x08, 0xc5, 0xb8, 0xe7, 0x4f, 0x8c, 0xda, 0x1f, 0x06, 0xe4, 0x77, 0xbe, 0x13, 0xd4, 0x53, 0x5f, - 0x10, 0xff, 0x4b, 0xe7, 0x57, 0xa7, 0xff, 0x19, 0xc8, 0x1f, 0xf9, 0xe8, 0x4f, 0x3a, 0xd4, 0x66, - 0xe9, 0xf9, 0x8b, 0xca, 0xb9, 0x3f, 0x5f, 0x54, 0xce, 0x7d, 0x3f, 0xaa, 0x18, 0xcf, 0x47, 0x15, - 0xe3, 0xf7, 0x51, 0xc5, 0xf8, 0x6b, 0x54, 0x31, 0xf6, 0x32, 0x2a, 0x3e, 0x1f, 0xfd, 0x1b, 0x00, - 0x00, 0xff, 0xff, 0x1b, 0x47, 0x17, 0xba, 0x5f, 0x12, 0x00, 0x00, + // 1491 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x58, 0xcf, 0x6f, 0x1b, 0x4f, + 0x15, 0xef, 0xda, 0x1b, 0xff, 0x78, 0x4e, 0x4c, 0x98, 0x86, 0xb0, 0x35, 0xc1, 0x0e, 0xae, 0x40, + 0x15, 0xaa, 0x9c, 0x12, 0x0a, 0x4a, 0x03, 0xa5, 0xb5, 0x93, 0xa8, 0xb5, 0x4a, 0x69, 0x34, 0x2d, + 0x2d, 0xb7, 0x65, 0xb2, 0x3b, 0x75, 0x17, 0xaf, 0x77, 0x56, 0x3b, 0x63, 0x17, 0xdf, 0x38, 0x87, + 0x3f, 0x20, 0x37, 0x0e, 0xfd, 0x17, 0xe0, 0xc2, 0x85, 0x03, 0xa7, 0x1e, 0x39, 0x21, 0x4e, 0x11, + 0xf5, 0x7f, 0x81, 0xc4, 0xe1, 0xab, 0x99, 0x9d, 0xb5, 0x37, 0xf1, 0x3a, 0x49, 0xbf, 0xaa, 0xa2, + 0xef, 0x29, 0x33, 0x3b, 0x9f, 0xcf, 0x9b, 0xf7, 0xde, 0xbc, 0x5f, 0x31, 0xac, 0xb0, 0xa3, 0x3f, + 0x50, 0x47, 0xf0, 0x56, 0x18, 0x31, 0xc1, 0x10, 0x72, 0x99, 0xd3, 0xa7, 0x51, 0x8b, 0xbf, 0x27, + 0xd1, 0xa0, 0xef, 0x89, 0xd6, 0xe8, 0x27, 0xb5, 0x8a, 0x18, 0x87, 0x54, 0x03, 0x6a, 0x15, 0x1e, + 0x52, 0x27, 0xd9, 0x34, 0x7a, 0x8c, 0xf5, 0x7c, 0xba, 0xa5, 0x76, 0x47, 0xc3, 0xb7, 0x5b, 0xc2, + 0x1b, 0x50, 0x2e, 0xc8, 0x20, 0xd4, 0x80, 0xb5, 0x1e, 0xeb, 0x31, 0xb5, 0xdc, 0x92, 0x2b, 0xfd, + 0xf5, 0xd6, 0x79, 0x1a, 0x09, 0xc6, 0xfa, 0xe8, 0x66, 0xe8, 0x0f, 0x7b, 0x5e, 0xb0, 0x15, 0xff, + 0x89, 0x3f, 0x36, 0xff, 0x6e, 0x80, 0xf9, 0x9c, 0x0a, 0x82, 0x7e, 0x01, 0xc5, 0x11, 0x8d, 0xb8, + 0xc7, 0x02, 0xcb, 0xd8, 0x34, 0xee, 0x54, 0xb6, 0xbf, 0xd7, 0x9a, 0xd7, 0xb7, 0xf5, 0x3a, 0x86, + 0x74, 0xcc, 0x8f, 0xa7, 0x8d, 0x1b, 0x38, 0x61, 0xa0, 0x07, 0x00, 0x4e, 0x44, 0x89, 0xa0, 0xae, + 0x4d, 0x84, 0x95, 0x53, 0xfc, 0x5a, 0x2b, 0x56, 0xa5, 0x95, 0xa8, 0xd2, 0x7a, 0x95, 0x58, 0x80, + 0xcb, 0x1a, 0xdd, 0x16, 0x92, 0x3a, 0x0c, 0xdd, 0x84, 0x9a, 0xbf, 0x9c, 0xaa, 0xd1, 0x6d, 0xd1, + 0xfc, 0xab, 0x09, 0xe6, 0x6f, 0x98, 0x4b, 0xd1, 0x3a, 0xe4, 0x3c, 0x57, 0xa9, 0x5d, 0xee, 0x14, + 0x26, 0xa7, 0x8d, 0x5c, 0x77, 0x1f, 0xe7, 0x3c, 0x17, 0x6d, 0x83, 0x39, 0xa0, 0x82, 0x68, 0x85, + 0xac, 0x2c, 0x83, 0xa4, 0xed, 0xda, 0x1a, 0x85, 0x45, 0x3f, 0x07, 0x53, 0x3e, 0x83, 0xd6, 0x64, + 0x23, 0x8b, 0x23, 0xef, 0x7c, 0x19, 0x52, 0x27, 0xe1, 0x49, 0x3c, 0x3a, 0x80, 0x8a, 0x4b, 0xb9, + 0x13, 0x79, 0xa1, 0x90, 0x3e, 0x34, 0x15, 0xfd, 0xf6, 0x22, 0xfa, 0xfe, 0x0c, 0x8a, 0xd3, 0x3c, + 0xf4, 0x4b, 0x28, 0x70, 0x41, 0xc4, 0x90, 0x5b, 0x4b, 0x4a, 0x42, 0x7d, 0xa1, 0x02, 0x0a, 0xa5, + 0x55, 0xd0, 0x1c, 0xf4, 0x14, 0xaa, 0x03, 0x12, 0x90, 0x1e, 0x8d, 0x6c, 0x2d, 0xa5, 0xa0, 0xa4, + 0xfc, 0x20, 0xd3, 0xf4, 0x18, 0x19, 0x0b, 0xc2, 0x2b, 0x83, 0xf4, 0x16, 0x1d, 0x00, 0x10, 0x21, + 0x88, 0xf3, 0x6e, 0x40, 0x03, 0x61, 0x15, 0x95, 0x94, 0x1f, 0x66, 0xea, 0x42, 0xc5, 0x7b, 0x16, + 0xf5, 0xdb, 0x53, 0x30, 0x4e, 0x11, 0xd1, 0x13, 0xa8, 0x38, 0x34, 0x12, 0xde, 0x5b, 0xcf, 0x21, + 0x82, 0x5a, 0x25, 0x25, 0xa7, 0x91, 0x25, 0x67, 0x6f, 0x06, 0xd3, 0x46, 0xa5, 0x99, 0xe8, 0x1e, + 0x98, 0x11, 0xf3, 0xa9, 0x55, 0xde, 0x34, 0xee, 0x54, 0x17, 0x3f, 0x0b, 0x66, 0x3e, 0xc5, 0x0a, + 0xb9, 0xbb, 0x7e, 0x7c, 0xd2, 0x44, 0xb0, 0x5a, 0x32, 0x56, 0x0d, 0x15, 0x1a, 0xc6, 0x3d, 0xe3, + 0x77, 0xc6, 0xef, 0x8d, 0xe6, 0xff, 0xf3, 0x50, 0x7c, 0x49, 0xa3, 0x91, 0xe7, 0x7c, 0xd9, 0xc0, + 0x79, 0x70, 0x26, 0x70, 0x32, 0x6d, 0xd4, 0xd7, 0xce, 0xc5, 0xce, 0x0e, 0x94, 0x68, 0xe0, 0x86, + 0xcc, 0x0b, 0x84, 0x0e, 0x9c, 0x4c, 0x03, 0x0f, 0x34, 0x06, 0x4f, 0xd1, 0xe8, 0x00, 0x56, 0xe2, + 0x7c, 0xb0, 0xcf, 0x44, 0xcd, 0x66, 0x16, 0xfd, 0xb7, 0x0a, 0xa8, 0x9f, 0x7b, 0x79, 0x98, 0xda, + 0xa1, 0x7d, 0x58, 0x09, 0x23, 0x3a, 0xf2, 0xd8, 0x90, 0xdb, 0xca, 0x88, 0xc2, 0x95, 0x8c, 0xc0, + 0xcb, 0x09, 0x4b, 0xee, 0xd0, 0xaf, 0x60, 0x59, 0x92, 0xed, 0xa4, 0x8e, 0xc0, 0xa5, 0x75, 0x04, + 0xab, 0x92, 0xa7, 0x37, 0xe8, 0x05, 0x7c, 0xe7, 0x8c, 0x16, 0x53, 0x41, 0x95, 0xcb, 0x05, 0xdd, + 0x4c, 0x6b, 0xa2, 0x3f, 0xee, 0xa2, 0xe3, 0x93, 0x66, 0x15, 0x96, 0xd3, 0x21, 0xd0, 0xfc, 0x4b, + 0x0e, 0x4a, 0x89, 0x23, 0xd1, 0x7d, 0xfd, 0x66, 0xc6, 0x62, 0xaf, 0x25, 0x58, 0x65, 0x6f, 0xfc, + 0x5c, 0xf7, 0x61, 0x29, 0x64, 0x91, 0xe0, 0x56, 0x6e, 0x33, 0xbf, 0x28, 0x45, 0x0f, 0x59, 0x24, + 0xf6, 0x58, 0xf0, 0xd6, 0xeb, 0xe1, 0x18, 0x8c, 0xde, 0x40, 0x65, 0xe4, 0x45, 0x62, 0x48, 0x7c, + 0xdb, 0x0b, 0xb9, 0x95, 0x57, 0xdc, 0x1f, 0x5d, 0x74, 0x65, 0xeb, 0x75, 0x8c, 0xef, 0x1e, 0x76, + 0xaa, 0x93, 0xd3, 0x06, 0x4c, 0xb7, 0x1c, 0x83, 0x16, 0xd5, 0x0d, 0x79, 0xed, 0x39, 0x94, 0xa7, + 0x27, 0xe8, 0x2e, 0x40, 0x10, 0x67, 0xa4, 0x3d, 0x8d, 0xec, 0x95, 0xc9, 0x69, 0xa3, 0xac, 0xf3, + 0xb4, 0xbb, 0x8f, 0xcb, 0x1a, 0xd0, 0x75, 0x11, 0x02, 0x93, 0xb8, 0x6e, 0xa4, 0xe2, 0xbc, 0x8c, + 0xd5, 0xba, 0xf9, 0xe7, 0x22, 0x98, 0xaf, 0x08, 0xef, 0x5f, 0x77, 0x55, 0x95, 0x77, 0xce, 0x65, + 0xc6, 0x5d, 0x00, 0x1e, 0xc7, 0x9b, 0x34, 0xc7, 0x9c, 0x99, 0xa3, 0xa3, 0x50, 0x9a, 0xa3, 0x01, + 0xb1, 0x39, 0xdc, 0x67, 0x42, 0x25, 0x81, 0x89, 0xd5, 0x1a, 0xdd, 0x86, 0x62, 0xc0, 0x5c, 0x45, + 0x2f, 0x28, 0x3a, 0x4c, 0x4e, 0x1b, 0x05, 0x59, 0x2b, 0xba, 0xfb, 0xb8, 0x20, 0x8f, 0xba, 0xae, + 0x2c, 0x53, 0x24, 0x08, 0x98, 0x20, 0xb2, 0x06, 0x73, 0x5d, 0xee, 0x32, 0xa3, 0xbf, 0x3d, 0x83, + 0x25, 0x65, 0x2a, 0xc5, 0x44, 0xaf, 0xe1, 0x66, 0xa2, 0x6f, 0x5a, 0x60, 0xe9, 0x73, 0x04, 0x22, + 0x2d, 0x21, 0x75, 0x92, 0x6a, 0x0b, 0xe5, 0xc5, 0x6d, 0x41, 0x79, 0x30, 0xab, 0x2d, 0x74, 0x60, + 0xc5, 0xa5, 0xdc, 0x8b, 0xa8, 0xab, 0xca, 0x04, 0x55, 0x99, 0x59, 0xdd, 0xfe, 0xfe, 0x45, 0x42, + 0x28, 0x5e, 0xd6, 0x1c, 0xb5, 0x43, 0x6d, 0x28, 0xe9, 0xb8, 0xe1, 0x56, 0x45, 0xc5, 0xee, 0x15, + 0xdb, 0xc1, 0x94, 0x76, 0xa6, 0xcc, 0x2d, 0x7f, 0x56, 0x99, 0x7b, 0x00, 0xe0, 0xb3, 0x9e, 0xed, + 0x46, 0xde, 0x88, 0x46, 0xd6, 0x8a, 0x1e, 0x12, 0x32, 0xb8, 0xfb, 0x0a, 0x81, 0xcb, 0x3e, 0xeb, + 0xc5, 0xcb, 0xb9, 0xa2, 0x54, 0xfd, 0xcc, 0xa2, 0x44, 0xa0, 0x46, 0x38, 0xf7, 0x7a, 0x01, 0x75, + 0xed, 0x1e, 0x0d, 0x68, 0xe4, 0x39, 0x76, 0x44, 0x39, 0x1b, 0x46, 0x0e, 0xe5, 0xd6, 0xb7, 0x94, + 0x27, 0x32, 0xdb, 0xfc, 0x93, 0x18, 0x8c, 0x35, 0x16, 0x5b, 0x89, 0x98, 0x73, 0x07, 0x7c, 0xb7, + 0x76, 0x7c, 0xd2, 0x5c, 0x87, 0xb5, 0x74, 0x99, 0xda, 0x31, 0x1e, 0x1b, 0x4f, 0x8d, 0x43, 0xa3, + 0xf9, 0xcf, 0x1c, 0x7c, 0x7b, 0xce, 0xa7, 0xe8, 0x67, 0x50, 0xd4, 0x5e, 0xbd, 0x68, 0x58, 0xd3, + 0x3c, 0x9c, 0x60, 0xd1, 0x06, 0x94, 0x65, 0x8a, 0x53, 0xce, 0x69, 0x5c, 0xbc, 0xca, 0x78, 0xf6, + 0x01, 0x59, 0x50, 0x24, 0xbe, 0x47, 0xe4, 0x59, 0x5e, 0x9d, 0x25, 0x5b, 0x34, 0x84, 0xf5, 0xd8, + 0xf5, 0xf6, 0xac, 0xb5, 0xdb, 0x2c, 0x14, 0xdc, 0x32, 0x95, 0xfd, 0x8f, 0xae, 0x14, 0x09, 0xfa, + 0x71, 0x66, 0x1f, 0x5e, 0x84, 0x82, 0x1f, 0x04, 0x22, 0x1a, 0xe3, 0x35, 0x37, 0xe3, 0xa8, 0xf6, + 0x04, 0x6e, 0x2d, 0xa4, 0xa0, 0x55, 0xc8, 0xf7, 0xe9, 0x38, 0x2e, 0x4f, 0x58, 0x2e, 0xd1, 0x1a, + 0x2c, 0x8d, 0x88, 0x3f, 0xa4, 0xba, 0x9a, 0xc5, 0x9b, 0xdd, 0xdc, 0x8e, 0xd1, 0xfc, 0x90, 0x83, + 0xa2, 0x56, 0xe7, 0xba, 0x5b, 0xbe, 0xbe, 0x76, 0xae, 0xb0, 0x3d, 0x84, 0x65, 0xed, 0xd2, 0x38, + 0x23, 0xcd, 0x4b, 0x63, 0xba, 0x12, 0xe3, 0xe3, 0x6c, 0x7c, 0x08, 0xa6, 0x17, 0x92, 0x81, 0x6e, + 0xf7, 0x99, 0x37, 0x77, 0x0f, 0xdb, 0xcf, 0x5f, 0x84, 0x71, 0x61, 0x29, 0x4d, 0x4e, 0x1b, 0xa6, + 0xfc, 0x80, 0x15, 0x2d, 0xb3, 0x31, 0xfe, 0x6d, 0x09, 0x8a, 0x7b, 0xfe, 0x90, 0x0b, 0x1a, 0x5d, + 0xb7, 0x93, 0xf4, 0xb5, 0x73, 0x4e, 0xda, 0x83, 0x62, 0xc4, 0x98, 0xb0, 0x1d, 0x72, 0x91, 0x7f, + 0x30, 0x63, 0x62, 0xaf, 0xdd, 0xa9, 0x4a, 0xa2, 0xac, 0xed, 0xf1, 0x1e, 0x17, 0x24, 0x75, 0x8f, + 0xa0, 0x37, 0xb0, 0x9e, 0x74, 0xc4, 0x23, 0xc6, 0x04, 0x17, 0x11, 0x09, 0xed, 0x3e, 0x1d, 0xcb, + 0x59, 0x29, 0xbf, 0x68, 0x36, 0x3e, 0x08, 0x9c, 0x68, 0xac, 0x9c, 0xf7, 0x8c, 0x8e, 0xf1, 0x9a, + 0x16, 0xd0, 0x49, 0xf8, 0xcf, 0xe8, 0x98, 0xa3, 0x47, 0xb0, 0x41, 0xa7, 0x30, 0x29, 0xd1, 0xf6, + 0xc9, 0x40, 0xf6, 0x7a, 0xdb, 0xf1, 0x99, 0xd3, 0x57, 0xed, 0xc6, 0xc4, 0xb7, 0x68, 0x5a, 0xd4, + 0xaf, 0x63, 0xc4, 0x9e, 0x04, 0x20, 0x0e, 0xd6, 0x91, 0x4f, 0x9c, 0xbe, 0xef, 0x71, 0xf9, 0xef, + 0x4f, 0x6a, 0xdc, 0x95, 0x1d, 0x43, 0xea, 0xb6, 0x73, 0x81, 0xb7, 0x5a, 0x9d, 0x19, 0x37, 0x35, + 0x3c, 0xeb, 0x8c, 0xfa, 0xee, 0x51, 0xf6, 0x29, 0xea, 0x40, 0x65, 0x18, 0xc8, 0xeb, 0x63, 0x1f, + 0x94, 0xaf, 0xea, 0x03, 0x88, 0x59, 0xd2, 0xf2, 0xda, 0x08, 0x36, 0x2e, 0xba, 0x3c, 0x23, 0x37, + 0x1f, 0xa7, 0x73, 0xb3, 0xb2, 0xfd, 0xe3, 0xac, 0xfb, 0xb2, 0x45, 0xa6, 0xf2, 0x38, 0x33, 0x6c, + 0xff, 0x61, 0x40, 0xe1, 0x25, 0x75, 0x22, 0x2a, 0xbe, 0x68, 0xd4, 0xee, 0x9c, 0x89, 0xda, 0x7a, + 0xf6, 0x20, 0x2c, 0x6f, 0x9d, 0x0b, 0xda, 0x1a, 0x94, 0xbc, 0x40, 0xd0, 0x28, 0x20, 0xbe, 0x8a, + 0xda, 0x12, 0x9e, 0xee, 0x33, 0x0d, 0xf8, 0x60, 0x40, 0x21, 0x9e, 0x14, 0xaf, 0xdb, 0x80, 0xf8, + 0xd6, 0xf3, 0x06, 0x64, 0x2a, 0xf9, 0x3f, 0x03, 0x4a, 0x49, 0xc3, 0xfa, 0xa2, 0x6a, 0x9e, 0x9b, + 0xbc, 0xf2, 0x5f, 0x7b, 0xf2, 0x42, 0x60, 0xf6, 0xbd, 0x40, 0xcf, 0x88, 0x58, 0xad, 0x51, 0x0b, + 0x8a, 0x21, 0x19, 0xfb, 0x8c, 0xb8, 0xba, 0x50, 0xae, 0xcd, 0xfd, 0xb0, 0xd0, 0x0e, 0xc6, 0x38, + 0x01, 0xed, 0xae, 0x1d, 0x9f, 0x34, 0x57, 0xa1, 0x9a, 0xb6, 0xfc, 0x9d, 0xd1, 0xfc, 0xb7, 0x01, + 0xe5, 0x83, 0x3f, 0x0a, 0x1a, 0xa8, 0x79, 0xe0, 0x1b, 0x69, 0xfc, 0xe6, 0xfc, 0x8f, 0x0f, 0xe5, + 0x33, 0xbf, 0x2b, 0x64, 0x3d, 0x6a, 0xc7, 0xfa, 0xf8, 0xa9, 0x7e, 0xe3, 0x3f, 0x9f, 0xea, 0x37, + 0xfe, 0x34, 0xa9, 0x1b, 0x1f, 0x27, 0x75, 0xe3, 0x5f, 0x93, 0xba, 0xf1, 0xdf, 0x49, 0xdd, 0x38, + 0x2a, 0x28, 0xff, 0xfc, 0xf4, 0xab, 0x00, 0x00, 0x00, 0xff, 0xff, 0xe4, 0x48, 0xcb, 0x39, 0xc2, + 0x12, 0x00, 0x00, } diff --git a/vendor/github.com/docker/swarmkit/api/objects.proto b/vendor/github.com/docker/swarmkit/api/objects.proto index 5f7cf26b7f96..311c1f2fb6eb 100644 --- a/vendor/github.com/docker/swarmkit/api/objects.proto +++ b/vendor/github.com/docker/swarmkit/api/objects.proto @@ -239,6 +239,8 @@ message Task { // // If not present, the daemon's default will be used. Driver log_driver = 13; + + repeated GenericResource assigned_generic_resources = 15; } // NetworkAttachment specifies the network parameters of attachment to diff --git a/vendor/github.com/docker/swarmkit/api/specs.pb.go b/vendor/github.com/docker/swarmkit/api/specs.pb.go index c9ea26046686..8578cf3849d4 100644 --- a/vendor/github.com/docker/swarmkit/api/specs.pb.go +++ b/vendor/github.com/docker/swarmkit/api/specs.pb.go @@ -642,16 +642,94 @@ type NetworkSpec struct { // swarm internally created only and it was identified by the name // "ingress" and the label "com.docker.swarm.internal": "true". Ingress bool `protobuf:"varint,7,opt,name=ingress,proto3" json:"ingress,omitempty"` - // ConfigFrom indicates that the network specific configuration - // for this network will be provided via another network, locally - // on the node where this network is being plumbed. - ConfigFrom string `protobuf:"bytes,8,opt,name=config_from,json=configFrom,proto3" json:"config_from,omitempty"` + // ConfigFrom is the source of the configuration for this network. + // + // Types that are valid to be assigned to ConfigFrom: + // *NetworkSpec_Network + ConfigFrom isNetworkSpec_ConfigFrom `protobuf_oneof:"config_from"` } func (m *NetworkSpec) Reset() { *m = NetworkSpec{} } func (*NetworkSpec) ProtoMessage() {} func (*NetworkSpec) Descriptor() ([]byte, []int) { return fileDescriptorSpecs, []int{9} } +type isNetworkSpec_ConfigFrom interface { + isNetworkSpec_ConfigFrom() + MarshalTo([]byte) (int, error) + Size() int +} + +type NetworkSpec_Network struct { + Network string `protobuf:"bytes,8,opt,name=network,proto3,oneof"` +} + +func (*NetworkSpec_Network) isNetworkSpec_ConfigFrom() {} + +func (m *NetworkSpec) GetConfigFrom() isNetworkSpec_ConfigFrom { + if m != nil { + return m.ConfigFrom + } + return nil +} + +func (m *NetworkSpec) GetNetwork() string { + if x, ok := m.GetConfigFrom().(*NetworkSpec_Network); ok { + return x.Network + } + return "" +} + +// XXX_OneofFuncs is for the internal use of the proto package. +func (*NetworkSpec) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) { + return _NetworkSpec_OneofMarshaler, _NetworkSpec_OneofUnmarshaler, _NetworkSpec_OneofSizer, []interface{}{ + (*NetworkSpec_Network)(nil), + } +} + +func _NetworkSpec_OneofMarshaler(msg proto.Message, b *proto.Buffer) error { + m := msg.(*NetworkSpec) + // config_from + switch x := m.ConfigFrom.(type) { + case *NetworkSpec_Network: + _ = b.EncodeVarint(8<<3 | proto.WireBytes) + _ = b.EncodeStringBytes(x.Network) + case nil: + default: + return fmt.Errorf("NetworkSpec.ConfigFrom has unexpected type %T", x) + } + return nil +} + +func _NetworkSpec_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) { + m := msg.(*NetworkSpec) + switch tag { + case 8: // config_from.network + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeStringBytes() + m.ConfigFrom = &NetworkSpec_Network{x} + return true, err + default: + return false, nil + } +} + +func _NetworkSpec_OneofSizer(msg proto.Message) (n int) { + m := msg.(*NetworkSpec) + // config_from + switch x := m.ConfigFrom.(type) { + case *NetworkSpec_Network: + n += proto.SizeVarint(8<<3 | proto.WireBytes) + n += proto.SizeVarint(uint64(len(x.Network))) + n += len(x.Network) + case nil: + default: + panic(fmt.Sprintf("proto: unexpected type %T in oneof", x)) + } + return n +} + // ClusterSpec specifies global cluster settings. type ClusterSpec struct { Annotations Annotations `protobuf:"bytes,1,opt,name=annotations" json:"annotations"` @@ -682,6 +760,12 @@ type SecretSpec struct { Annotations Annotations `protobuf:"bytes,1,opt,name=annotations" json:"annotations"` // Data is the secret payload - the maximum size is 500KB (that is, 500*1024 bytes) Data []byte `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"` + // Templating controls whether and how to evaluate the secret payload as + // a template. If it is not set, no templating is used. + // + // The currently recognized values are: + // - golang: Go templating + Templating *Driver `protobuf:"bytes,3,opt,name=templating" json:"templating,omitempty"` } func (m *SecretSpec) Reset() { *m = SecretSpec{} } @@ -695,6 +779,12 @@ type ConfigSpec struct { // TODO(aaronl): Do we want to revise this to include multiple payloads in a single // ConfigSpec? Define this to be a tar? etc... Data []byte `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"` + // Templating controls whether and how to evaluate the secret payload as + // a template. If it is not set, no templating is used. + // + // The currently recognized values are: + // - golang: Go templating + Templating *Driver `protobuf:"bytes,3,opt,name=templating" json:"templating,omitempty"` } func (m *ConfigSpec) Reset() { *m = ConfigSpec{} } @@ -1093,6 +1183,16 @@ func (m *NetworkSpec) CopyFrom(src interface{}) { m.IPAM = &IPAMOptions{} github_com_docker_swarmkit_api_deepcopy.Copy(m.IPAM, o.IPAM) } + if o.ConfigFrom != nil { + switch o.ConfigFrom.(type) { + case *NetworkSpec_Network: + v := NetworkSpec_Network{ + Network: o.GetNetwork(), + } + m.ConfigFrom = &v + } + } + } func (m *ClusterSpec) Copy() *ClusterSpec { @@ -1136,6 +1236,10 @@ func (m *SecretSpec) CopyFrom(src interface{}) { m.Data = make([]byte, len(o.Data)) copy(m.Data, o.Data) } + if o.Templating != nil { + m.Templating = &Driver{} + github_com_docker_swarmkit_api_deepcopy.Copy(m.Templating, o.Templating) + } } func (m *ConfigSpec) Copy() *ConfigSpec { @@ -1156,6 +1260,10 @@ func (m *ConfigSpec) CopyFrom(src interface{}) { m.Data = make([]byte, len(o.Data)) copy(m.Data, o.Data) } + if o.Templating != nil { + m.Templating = &Driver{} + github_com_docker_swarmkit_api_deepcopy.Copy(m.Templating, o.Templating) + } } func (m *NodeSpec) Marshal() (dAtA []byte, err error) { @@ -2010,15 +2118,24 @@ func (m *NetworkSpec) MarshalTo(dAtA []byte) (int, error) { } i++ } - if len(m.ConfigFrom) > 0 { - dAtA[i] = 0x42 - i++ - i = encodeVarintSpecs(dAtA, i, uint64(len(m.ConfigFrom))) - i += copy(dAtA[i:], m.ConfigFrom) + if m.ConfigFrom != nil { + nn27, err := m.ConfigFrom.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += nn27 } return i, nil } +func (m *NetworkSpec_Network) MarshalTo(dAtA []byte) (int, error) { + i := 0 + dAtA[i] = 0x42 + i++ + i = encodeVarintSpecs(dAtA, i, uint64(len(m.Network))) + i += copy(dAtA[i:], m.Network) + return i, nil +} func (m *ClusterSpec) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -2037,67 +2154,67 @@ func (m *ClusterSpec) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintSpecs(dAtA, i, uint64(m.Annotations.Size())) - n27, err := m.Annotations.MarshalTo(dAtA[i:]) + n28, err := m.Annotations.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n27 + i += n28 dAtA[i] = 0x12 i++ i = encodeVarintSpecs(dAtA, i, uint64(m.AcceptancePolicy.Size())) - n28, err := m.AcceptancePolicy.MarshalTo(dAtA[i:]) + n29, err := m.AcceptancePolicy.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n28 + i += n29 dAtA[i] = 0x1a i++ i = encodeVarintSpecs(dAtA, i, uint64(m.Orchestration.Size())) - n29, err := m.Orchestration.MarshalTo(dAtA[i:]) + n30, err := m.Orchestration.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n29 + i += n30 dAtA[i] = 0x22 i++ i = encodeVarintSpecs(dAtA, i, uint64(m.Raft.Size())) - n30, err := m.Raft.MarshalTo(dAtA[i:]) + n31, err := m.Raft.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n30 + i += n31 dAtA[i] = 0x2a i++ i = encodeVarintSpecs(dAtA, i, uint64(m.Dispatcher.Size())) - n31, err := m.Dispatcher.MarshalTo(dAtA[i:]) + n32, err := m.Dispatcher.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n31 + i += n32 dAtA[i] = 0x32 i++ i = encodeVarintSpecs(dAtA, i, uint64(m.CAConfig.Size())) - n32, err := m.CAConfig.MarshalTo(dAtA[i:]) + n33, err := m.CAConfig.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n32 + i += n33 dAtA[i] = 0x3a i++ i = encodeVarintSpecs(dAtA, i, uint64(m.TaskDefaults.Size())) - n33, err := m.TaskDefaults.MarshalTo(dAtA[i:]) + n34, err := m.TaskDefaults.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n33 + i += n34 dAtA[i] = 0x42 i++ i = encodeVarintSpecs(dAtA, i, uint64(m.EncryptionConfig.Size())) - n34, err := m.EncryptionConfig.MarshalTo(dAtA[i:]) + n35, err := m.EncryptionConfig.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n34 + i += n35 return i, nil } @@ -2119,17 +2236,27 @@ func (m *SecretSpec) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintSpecs(dAtA, i, uint64(m.Annotations.Size())) - n35, err := m.Annotations.MarshalTo(dAtA[i:]) + n36, err := m.Annotations.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n35 + i += n36 if len(m.Data) > 0 { dAtA[i] = 0x12 i++ i = encodeVarintSpecs(dAtA, i, uint64(len(m.Data))) i += copy(dAtA[i:], m.Data) } + if m.Templating != nil { + dAtA[i] = 0x1a + i++ + i = encodeVarintSpecs(dAtA, i, uint64(m.Templating.Size())) + n37, err := m.Templating.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n37 + } return i, nil } @@ -2151,17 +2278,27 @@ func (m *ConfigSpec) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintSpecs(dAtA, i, uint64(m.Annotations.Size())) - n36, err := m.Annotations.MarshalTo(dAtA[i:]) + n38, err := m.Annotations.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n36 + i += n38 if len(m.Data) > 0 { dAtA[i] = 0x12 i++ i = encodeVarintSpecs(dAtA, i, uint64(len(m.Data))) i += copy(dAtA[i:], m.Data) } + if m.Templating != nil { + dAtA[i] = 0x1a + i++ + i = encodeVarintSpecs(dAtA, i, uint64(m.Templating.Size())) + n39, err := m.Templating.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n39 + } return i, nil } @@ -2544,13 +2681,19 @@ func (m *NetworkSpec) Size() (n int) { if m.Ingress { n += 2 } - l = len(m.ConfigFrom) - if l > 0 { - n += 1 + l + sovSpecs(uint64(l)) + if m.ConfigFrom != nil { + n += m.ConfigFrom.Size() } return n } +func (m *NetworkSpec_Network) Size() (n int) { + var l int + _ = l + l = len(m.Network) + n += 1 + l + sovSpecs(uint64(l)) + return n +} func (m *ClusterSpec) Size() (n int) { var l int _ = l @@ -2582,6 +2725,10 @@ func (m *SecretSpec) Size() (n int) { if l > 0 { n += 1 + l + sovSpecs(uint64(l)) } + if m.Templating != nil { + l = m.Templating.Size() + n += 1 + l + sovSpecs(uint64(l)) + } return n } @@ -2594,6 +2741,10 @@ func (m *ConfigSpec) Size() (n int) { if l > 0 { n += 1 + l + sovSpecs(uint64(l)) } + if m.Templating != nil { + l = m.Templating.Size() + n += 1 + l + sovSpecs(uint64(l)) + } return n } @@ -2836,6 +2987,16 @@ func (this *NetworkSpec) String() string { }, "") return s } +func (this *NetworkSpec_Network) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&NetworkSpec_Network{`, + `Network:` + fmt.Sprintf("%v", this.Network) + `,`, + `}`, + }, "") + return s +} func (this *ClusterSpec) String() string { if this == nil { return "nil" @@ -2860,6 +3021,7 @@ func (this *SecretSpec) String() string { s := strings.Join([]string{`&SecretSpec{`, `Annotations:` + strings.Replace(strings.Replace(this.Annotations.String(), "Annotations", "Annotations", 1), `&`, ``, 1) + `,`, `Data:` + fmt.Sprintf("%v", this.Data) + `,`, + `Templating:` + strings.Replace(fmt.Sprintf("%v", this.Templating), "Driver", "Driver", 1) + `,`, `}`, }, "") return s @@ -2871,6 +3033,7 @@ func (this *ConfigSpec) String() string { s := strings.Join([]string{`&ConfigSpec{`, `Annotations:` + strings.Replace(strings.Replace(this.Annotations.String(), "Annotations", "Annotations", 1), `&`, ``, 1) + `,`, `Data:` + fmt.Sprintf("%v", this.Data) + `,`, + `Templating:` + strings.Replace(fmt.Sprintf("%v", this.Templating), "Driver", "Driver", 1) + `,`, `}`, }, "") return s @@ -5259,7 +5422,7 @@ func (m *NetworkSpec) Unmarshal(dAtA []byte) error { m.Ingress = bool(v != 0) case 8: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ConfigFrom", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Network", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -5284,7 +5447,7 @@ func (m *NetworkSpec) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ConfigFrom = string(dAtA[iNdEx:postIndex]) + m.ConfigFrom = &NetworkSpec_Network{string(dAtA[iNdEx:postIndex])} iNdEx = postIndex default: iNdEx = preIndex @@ -5687,6 +5850,39 @@ func (m *SecretSpec) Unmarshal(dAtA []byte) error { m.Data = []byte{} } iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Templating", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpecs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthSpecs + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Templating == nil { + m.Templating = &Driver{} + } + if err := m.Templating.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipSpecs(dAtA[iNdEx:]) @@ -5798,6 +5994,39 @@ func (m *ConfigSpec) Unmarshal(dAtA []byte) error { m.Data = []byte{} } iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Templating", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpecs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthSpecs + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Templating == nil { + m.Templating = &Driver{} + } + if err := m.Templating.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipSpecs(dAtA[iNdEx:]) @@ -5927,121 +6156,122 @@ var ( func init() { proto.RegisterFile("specs.proto", fileDescriptorSpecs) } var fileDescriptorSpecs = []byte{ - // 1844 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x57, 0x4f, 0x73, 0x1b, 0x49, - 0x15, 0xb7, 0x6c, 0x59, 0x7f, 0xde, 0xc8, 0x89, 0xdc, 0x24, 0x61, 0xac, 0xb0, 0xb2, 0xa2, 0x0d, - 0xc1, 0xcb, 0x16, 0x72, 0x61, 0xa8, 0x25, 0x4b, 0x58, 0x40, 0xb2, 0xb4, 0x8e, 0x31, 0x76, 0x54, - 0x6d, 0x6f, 0x20, 0x27, 0x55, 0x7b, 0xa6, 0x2d, 0x4d, 0x79, 0xd4, 0x3d, 0xf4, 0xf4, 0x68, 0x4b, - 0x37, 0x8e, 0x5b, 0xb9, 0x72, 0x76, 0x71, 0xe0, 0xcb, 0xe4, 0x48, 0x71, 0xe2, 0xe4, 0x62, 0xf5, - 0x09, 0xa8, 0xe2, 0x03, 0x40, 0x75, 0x4f, 0x8f, 0x34, 0x4a, 0xc6, 0x49, 0xaa, 0xc8, 0xde, 0xba, - 0xdf, 0xfc, 0x7e, 0xaf, 0x5f, 0xbf, 0xfe, 0x75, 0xbf, 0x37, 0x60, 0x85, 0x01, 0x75, 0xc2, 0x56, - 0x20, 0xb8, 0xe4, 0x08, 0xb9, 0xdc, 0xb9, 0xa4, 0xa2, 0x15, 0x7e, 0x4d, 0xc4, 0xf8, 0xd2, 0x93, - 0xad, 0xc9, 0x4f, 0x6b, 0x96, 0x9c, 0x06, 0xd4, 0x00, 0x6a, 0x77, 0x86, 0x7c, 0xc8, 0xf5, 0x70, - 0x57, 0x8d, 0x8c, 0xb5, 0x3e, 0xe4, 0x7c, 0xe8, 0xd3, 0x5d, 0x3d, 0x3b, 0x8f, 0x2e, 0x76, 0xdd, - 0x48, 0x10, 0xe9, 0x71, 0x66, 0xbe, 0x6f, 0xbd, 0xfe, 0x9d, 0xb0, 0x69, 0xfc, 0xa9, 0x79, 0x95, - 0x87, 0xd2, 0x09, 0x77, 0xe9, 0x69, 0x40, 0x1d, 0x74, 0x00, 0x16, 0x61, 0x8c, 0x4b, 0xcd, 0x0d, - 0xed, 0x5c, 0x23, 0xb7, 0x63, 0xed, 0x6d, 0xb7, 0xde, 0x0c, 0xaa, 0xd5, 0x5e, 0xc0, 0x3a, 0xf9, - 0x57, 0xd7, 0xdb, 0x2b, 0x38, 0xcd, 0x44, 0xbf, 0x81, 0x8a, 0x4b, 0x43, 0x4f, 0x50, 0x77, 0x20, - 0xb8, 0x4f, 0xed, 0xd5, 0x46, 0x6e, 0xe7, 0xd6, 0xde, 0x0f, 0xb2, 0x3c, 0xa9, 0xc5, 0x31, 0xf7, - 0x29, 0xb6, 0x0c, 0x43, 0x4d, 0xd0, 0x01, 0xc0, 0x98, 0x8e, 0xcf, 0xa9, 0x08, 0x47, 0x5e, 0x60, - 0xaf, 0x69, 0xfa, 0x8f, 0x6e, 0xa2, 0xab, 0xd8, 0x5b, 0xc7, 0x73, 0x38, 0x4e, 0x51, 0xd1, 0x31, - 0x54, 0xc8, 0x84, 0x78, 0x3e, 0x39, 0xf7, 0x7c, 0x4f, 0x4e, 0xed, 0xbc, 0x76, 0xf5, 0xc9, 0x5b, - 0x5d, 0xb5, 0x53, 0x04, 0xbc, 0x44, 0x6f, 0xba, 0x00, 0x8b, 0x85, 0xd0, 0x23, 0x28, 0xf6, 0x7b, - 0x27, 0xdd, 0xc3, 0x93, 0x83, 0xea, 0x4a, 0x6d, 0xeb, 0xe5, 0x55, 0xe3, 0xae, 0xf2, 0xb1, 0x00, - 0xf4, 0x29, 0x73, 0x3d, 0x36, 0x44, 0x3b, 0x50, 0x6a, 0xef, 0xef, 0xf7, 0xfa, 0x67, 0xbd, 0x6e, - 0x35, 0x57, 0xab, 0xbd, 0xbc, 0x6a, 0xdc, 0x5b, 0x06, 0xb6, 0x1d, 0x87, 0x06, 0x92, 0xba, 0xb5, - 0xfc, 0x37, 0x7f, 0xab, 0xaf, 0x34, 0xbf, 0xc9, 0x41, 0x25, 0x1d, 0x04, 0x7a, 0x04, 0x85, 0xf6, - 0xfe, 0xd9, 0xe1, 0xf3, 0x5e, 0x75, 0x65, 0x41, 0x4f, 0x23, 0xda, 0x8e, 0xf4, 0x26, 0x14, 0x3d, - 0x84, 0xf5, 0x7e, 0xfb, 0xab, 0xd3, 0x5e, 0x35, 0xb7, 0x08, 0x27, 0x0d, 0xeb, 0x93, 0x28, 0xd4, - 0xa8, 0x2e, 0x6e, 0x1f, 0x9e, 0x54, 0x57, 0xb3, 0x51, 0x5d, 0x41, 0x3c, 0x66, 0x42, 0xf9, 0x6b, - 0x1e, 0xac, 0x53, 0x2a, 0x26, 0x9e, 0xf3, 0x81, 0x25, 0xf2, 0x19, 0xe4, 0x25, 0x09, 0x2f, 0xb5, - 0x34, 0xac, 0x6c, 0x69, 0x9c, 0x91, 0xf0, 0x52, 0x2d, 0x6a, 0xe8, 0x1a, 0xaf, 0x94, 0x21, 0x68, - 0xe0, 0x7b, 0x0e, 0x91, 0xd4, 0xd5, 0xca, 0xb0, 0xf6, 0x7e, 0x98, 0xc5, 0xc6, 0x73, 0x94, 0x89, - 0xff, 0xe9, 0x0a, 0x4e, 0x51, 0xd1, 0x13, 0x28, 0x0c, 0x7d, 0x7e, 0x4e, 0x7c, 0xad, 0x09, 0x6b, - 0xef, 0x41, 0x96, 0x93, 0x03, 0x8d, 0x58, 0x38, 0x30, 0x14, 0xf4, 0x18, 0x0a, 0x51, 0xe0, 0x12, - 0x49, 0xed, 0x82, 0x26, 0x37, 0xb2, 0xc8, 0x5f, 0x69, 0xc4, 0x3e, 0x67, 0x17, 0xde, 0x10, 0x1b, - 0x3c, 0x3a, 0x82, 0x12, 0xa3, 0xf2, 0x6b, 0x2e, 0x2e, 0x43, 0xbb, 0xd8, 0x58, 0xdb, 0xb1, 0xf6, - 0x3e, 0xcd, 0x14, 0x63, 0x8c, 0x69, 0x4b, 0x49, 0x9c, 0xd1, 0x98, 0x32, 0x19, 0xbb, 0xe9, 0xac, - 0xda, 0x39, 0x3c, 0x77, 0x80, 0x7e, 0x05, 0x25, 0xca, 0xdc, 0x80, 0x7b, 0x4c, 0xda, 0xa5, 0x9b, - 0x03, 0xe9, 0x19, 0x8c, 0x4a, 0x26, 0x9e, 0x33, 0x14, 0x5b, 0x70, 0xdf, 0x3f, 0x27, 0xce, 0xa5, - 0x5d, 0x7e, 0xcf, 0x6d, 0xcc, 0x19, 0x9d, 0x02, 0xe4, 0xc7, 0xdc, 0xa5, 0xcd, 0x5d, 0xd8, 0x7c, - 0x23, 0xd5, 0xa8, 0x06, 0x25, 0x93, 0xea, 0x58, 0x23, 0x79, 0x3c, 0x9f, 0x37, 0x6f, 0xc3, 0xc6, - 0x52, 0x5a, 0x9b, 0xff, 0xc8, 0x43, 0x29, 0x39, 0x6b, 0xd4, 0x86, 0xb2, 0xc3, 0x99, 0x24, 0x1e, - 0xa3, 0xc2, 0xc8, 0x2b, 0xf3, 0x64, 0xf6, 0x13, 0x90, 0x62, 0x3d, 0x5d, 0xc1, 0x0b, 0x16, 0xfa, - 0x12, 0xca, 0x82, 0x86, 0x3c, 0x12, 0x0e, 0x0d, 0x8d, 0xbe, 0x76, 0xb2, 0x15, 0x12, 0x83, 0x30, - 0xfd, 0x53, 0xe4, 0x09, 0xaa, 0xb2, 0x1c, 0xe2, 0x05, 0x15, 0x3d, 0x81, 0xa2, 0xa0, 0xa1, 0x24, - 0x42, 0xbe, 0x4d, 0x22, 0x38, 0x86, 0xf4, 0xb9, 0xef, 0x39, 0x53, 0x9c, 0x30, 0xd0, 0x13, 0x28, - 0x07, 0x3e, 0x71, 0xb4, 0x57, 0x7b, 0x5d, 0xd3, 0x3f, 0xca, 0xa2, 0xf7, 0x13, 0x10, 0x5e, 0xe0, - 0xd1, 0xe7, 0x00, 0x3e, 0x1f, 0x0e, 0x5c, 0xe1, 0x4d, 0xa8, 0x30, 0x12, 0xab, 0x65, 0xb1, 0xbb, - 0x1a, 0x81, 0xcb, 0x3e, 0x1f, 0xc6, 0x43, 0x74, 0xf0, 0x7f, 0xe9, 0x2b, 0xa5, 0xad, 0x23, 0x00, - 0x32, 0xff, 0x6a, 0xd4, 0xf5, 0xc9, 0x7b, 0xb9, 0x32, 0x27, 0x92, 0xa2, 0xa3, 0x07, 0x50, 0xb9, - 0xe0, 0xc2, 0xa1, 0x03, 0x73, 0x6b, 0xca, 0x5a, 0x13, 0x96, 0xb6, 0xc5, 0xfa, 0x42, 0x1d, 0x28, - 0x0e, 0x29, 0xa3, 0xc2, 0x73, 0x6c, 0xd0, 0x8b, 0x3d, 0xca, 0xbc, 0x90, 0x31, 0x04, 0x47, 0x4c, - 0x7a, 0x63, 0x6a, 0x56, 0x4a, 0x88, 0x9d, 0x32, 0x14, 0x45, 0xfc, 0xa5, 0xf9, 0x47, 0x40, 0x6f, - 0x62, 0x11, 0x82, 0xfc, 0xa5, 0xc7, 0x5c, 0x2d, 0xac, 0x32, 0xd6, 0x63, 0xd4, 0x82, 0x62, 0x40, - 0xa6, 0x3e, 0x27, 0xae, 0x11, 0xcb, 0x9d, 0x56, 0x5c, 0x2f, 0x5b, 0x49, 0xbd, 0x6c, 0xb5, 0xd9, - 0x14, 0x27, 0xa0, 0xe6, 0x11, 0xdc, 0xcd, 0xdc, 0x32, 0xda, 0x83, 0xca, 0x5c, 0x84, 0x03, 0xcf, - 0x2c, 0xd2, 0xb9, 0x3d, 0xbb, 0xde, 0xb6, 0xe6, 0x6a, 0x3d, 0xec, 0x62, 0x6b, 0x0e, 0x3a, 0x74, - 0x9b, 0x7f, 0x29, 0xc3, 0xc6, 0x92, 0x94, 0xd1, 0x1d, 0x58, 0xf7, 0xc6, 0x64, 0x48, 0x4d, 0x8c, - 0xf1, 0x04, 0xf5, 0xa0, 0xe0, 0x93, 0x73, 0xea, 0x2b, 0x41, 0xab, 0x43, 0xfd, 0xc9, 0x3b, 0xef, - 0x44, 0xeb, 0xf7, 0x1a, 0xdf, 0x63, 0x52, 0x4c, 0xb1, 0x21, 0x23, 0x1b, 0x8a, 0x0e, 0x1f, 0x8f, - 0x09, 0x53, 0x4f, 0xe7, 0xda, 0x4e, 0x19, 0x27, 0x53, 0x95, 0x19, 0x22, 0x86, 0xa1, 0x9d, 0xd7, - 0x66, 0x3d, 0x46, 0x55, 0x58, 0xa3, 0x6c, 0x62, 0xaf, 0x6b, 0x93, 0x1a, 0x2a, 0x8b, 0xeb, 0xc5, - 0x8a, 0x2c, 0x63, 0x35, 0x54, 0xbc, 0x28, 0xa4, 0xc2, 0x2e, 0xc6, 0x19, 0x55, 0x63, 0xf4, 0x0b, - 0x28, 0x8c, 0x79, 0xc4, 0x64, 0x68, 0x97, 0x74, 0xb0, 0x5b, 0x59, 0xc1, 0x1e, 0x2b, 0x84, 0x79, - 0xda, 0x0d, 0x1c, 0xf5, 0x60, 0x33, 0x94, 0x3c, 0x18, 0x0c, 0x05, 0x71, 0xe8, 0x20, 0xa0, 0xc2, - 0xe3, 0xae, 0x79, 0x9a, 0xb6, 0xde, 0x38, 0x94, 0xae, 0x69, 0x72, 0xf0, 0x6d, 0xc5, 0x39, 0x50, - 0x94, 0xbe, 0x66, 0xa0, 0x3e, 0x54, 0x82, 0xc8, 0xf7, 0x07, 0x3c, 0x88, 0xab, 0x54, 0xac, 0xa7, - 0xf7, 0x48, 0x59, 0x3f, 0xf2, 0xfd, 0x67, 0x31, 0x09, 0x5b, 0xc1, 0x62, 0x82, 0xee, 0x41, 0x61, - 0x28, 0x78, 0x14, 0x84, 0xb6, 0xa5, 0x93, 0x61, 0x66, 0xe8, 0x0b, 0x28, 0x86, 0xd4, 0x11, 0x54, - 0x86, 0x76, 0x45, 0x6f, 0xf5, 0xe3, 0xac, 0x45, 0x4e, 0x35, 0x04, 0xd3, 0x0b, 0x2a, 0x28, 0x73, - 0x28, 0x4e, 0x38, 0x68, 0x0b, 0xd6, 0xa4, 0x9c, 0xda, 0x1b, 0x8d, 0xdc, 0x4e, 0xa9, 0x53, 0x9c, - 0x5d, 0x6f, 0xaf, 0x9d, 0x9d, 0xbd, 0xc0, 0xca, 0xa6, 0x5e, 0xd0, 0x11, 0x0f, 0x25, 0x23, 0x63, - 0x6a, 0xdf, 0xd2, 0xb9, 0x9d, 0xcf, 0xd1, 0x0b, 0x00, 0x97, 0x85, 0x03, 0x47, 0x5f, 0x59, 0xfb, - 0xb6, 0xde, 0xdd, 0xa7, 0xef, 0xde, 0x5d, 0xf7, 0xe4, 0xd4, 0x54, 0x91, 0x8d, 0xd9, 0xf5, 0x76, - 0x79, 0x3e, 0xc5, 0x65, 0x97, 0x85, 0xf1, 0x10, 0x75, 0xc0, 0x1a, 0x51, 0xe2, 0xcb, 0x91, 0x33, - 0xa2, 0xce, 0xa5, 0x5d, 0xbd, 0xb9, 0x2c, 0x3c, 0xd5, 0x30, 0xe3, 0x21, 0x4d, 0x52, 0x0a, 0x56, - 0xa1, 0x86, 0xf6, 0xa6, 0xce, 0x55, 0x3c, 0x41, 0x1f, 0x01, 0xf0, 0x80, 0xb2, 0x41, 0x28, 0x5d, - 0x8f, 0xd9, 0x48, 0x6d, 0x19, 0x97, 0x95, 0xe5, 0x54, 0x19, 0xd0, 0x7d, 0xf5, 0x68, 0x13, 0x77, - 0xc0, 0x99, 0x3f, 0xb5, 0xbf, 0xa7, 0xbf, 0x96, 0x94, 0xe1, 0x19, 0xf3, 0xa7, 0x68, 0x1b, 0x2c, - 0xad, 0x8b, 0xd0, 0x1b, 0x32, 0xe2, 0xdb, 0x77, 0x74, 0x3e, 0x40, 0x99, 0x4e, 0xb5, 0x45, 0x9d, - 0x43, 0x9c, 0x8d, 0xd0, 0xbe, 0x7b, 0xf3, 0x39, 0x98, 0x60, 0x17, 0xe7, 0x60, 0x38, 0xe8, 0xd7, - 0x00, 0x81, 0xf0, 0x26, 0x9e, 0x4f, 0x87, 0x34, 0xb4, 0xef, 0xe9, 0x4d, 0xd7, 0x33, 0x5f, 0xeb, - 0x39, 0x0a, 0xa7, 0x18, 0xb5, 0xcf, 0xc1, 0x4a, 0xdd, 0x36, 0x75, 0x4b, 0x2e, 0xe9, 0xd4, 0x5c, - 0x60, 0x35, 0x54, 0x29, 0x99, 0x10, 0x3f, 0x8a, 0x3b, 0xe1, 0x32, 0x8e, 0x27, 0xbf, 0x5c, 0x7d, - 0x9c, 0xab, 0xed, 0x81, 0x95, 0x52, 0x1d, 0xfa, 0x18, 0x36, 0x04, 0x1d, 0x7a, 0xa1, 0x14, 0xd3, - 0x01, 0x89, 0xe4, 0xc8, 0xfe, 0xad, 0x26, 0x54, 0x12, 0x63, 0x3b, 0x92, 0xa3, 0xda, 0x00, 0x16, - 0x87, 0x87, 0x1a, 0x60, 0x29, 0x51, 0x84, 0x54, 0x4c, 0xa8, 0x50, 0xd5, 0x56, 0xe5, 0x3c, 0x6d, - 0x52, 0xe2, 0x0d, 0x29, 0x11, 0xce, 0x48, 0xbf, 0x1d, 0x65, 0x6c, 0x66, 0xea, 0x31, 0x48, 0x6e, - 0x88, 0x79, 0x0c, 0xcc, 0xb4, 0xf9, 0x9f, 0x1c, 0x54, 0xd2, 0x4d, 0x03, 0xda, 0x8f, 0x8b, 0xbd, - 0xde, 0xd2, 0xad, 0xbd, 0xdd, 0x77, 0x35, 0x19, 0xba, 0xb4, 0xfa, 0x91, 0x72, 0x76, 0xac, 0xfa, - 0x7b, 0x4d, 0x46, 0x3f, 0x87, 0xf5, 0x80, 0x0b, 0x99, 0x3c, 0x61, 0xd9, 0x09, 0xe6, 0x22, 0x29, - 0x45, 0x31, 0xb8, 0x39, 0x82, 0x5b, 0xcb, 0xde, 0xd0, 0x43, 0x58, 0x7b, 0x7e, 0xd8, 0xaf, 0xae, - 0xd4, 0xee, 0xbf, 0xbc, 0x6a, 0x7c, 0x7f, 0xf9, 0xe3, 0x73, 0x4f, 0xc8, 0x88, 0xf8, 0x87, 0x7d, - 0xf4, 0x63, 0x58, 0xef, 0x9e, 0x9c, 0x62, 0x5c, 0xcd, 0xd5, 0xb6, 0x5f, 0x5e, 0x35, 0xee, 0x2f, - 0xe3, 0xd4, 0x27, 0x1e, 0x31, 0x17, 0xf3, 0xf3, 0x79, 0xaf, 0xfb, 0xef, 0x55, 0xb0, 0xcc, 0xcb, - 0xfe, 0xa1, 0x7f, 0x87, 0x36, 0xe2, 0x52, 0x9e, 0x5c, 0xd9, 0xd5, 0x77, 0x56, 0xf4, 0x4a, 0x4c, - 0x30, 0x67, 0xfc, 0x00, 0x2a, 0x5e, 0x30, 0xf9, 0x6c, 0x40, 0x19, 0x39, 0xf7, 0x4d, 0xdb, 0x5b, - 0xc2, 0x96, 0xb2, 0xf5, 0x62, 0x93, 0x7a, 0x2f, 0x3c, 0x26, 0xa9, 0x60, 0xa6, 0xa1, 0x2d, 0xe1, - 0xf9, 0x1c, 0x7d, 0x01, 0x79, 0x2f, 0x20, 0x63, 0xd3, 0x86, 0x64, 0xee, 0xe0, 0xb0, 0xdf, 0x3e, - 0x36, 0x1a, 0xec, 0x94, 0x66, 0xd7, 0xdb, 0x79, 0x65, 0xc0, 0x9a, 0x86, 0xea, 0x49, 0x27, 0xa0, - 0x56, 0xd2, 0x6f, 0x7f, 0x09, 0xa7, 0x2c, 0x4a, 0x47, 0x1e, 0x1b, 0x0a, 0x1a, 0x86, 0xba, 0x0a, - 0x94, 0x70, 0x32, 0x55, 0xf7, 0x36, 0xde, 0xf1, 0xe0, 0x42, 0xf0, 0xb1, 0x6e, 0x22, 0xca, 0x18, - 0x62, 0xd3, 0x97, 0x82, 0x8f, 0x9b, 0xff, 0xcd, 0x83, 0xb5, 0xef, 0x47, 0xa1, 0x34, 0xc5, 0xef, - 0x83, 0xa5, 0xfc, 0x05, 0x6c, 0x12, 0xfd, 0x53, 0x45, 0x98, 0xaa, 0x24, 0xba, 0x39, 0x33, 0x69, - 0x7f, 0x98, 0xe9, 0x6e, 0x0e, 0x8e, 0x1b, 0xb9, 0x4e, 0x41, 0xf9, 0xb4, 0x73, 0xb8, 0x4a, 0x5e, - 0xfb, 0x82, 0x4e, 0x61, 0x83, 0x0b, 0x67, 0x44, 0x43, 0x19, 0xd7, 0x1f, 0xf3, 0x13, 0x92, 0xf9, - 0x7b, 0xfa, 0x2c, 0x0d, 0x34, 0x8f, 0x6f, 0x1c, 0xed, 0xb2, 0x0f, 0xf4, 0x18, 0xf2, 0x82, 0x5c, - 0x24, 0x8d, 0x66, 0xe6, 0xd5, 0xc0, 0xe4, 0x42, 0x2e, 0xb9, 0xd0, 0x0c, 0xf4, 0x3b, 0x00, 0xd7, - 0x0b, 0x03, 0x22, 0x9d, 0x11, 0x15, 0xe6, 0x88, 0x33, 0xb7, 0xd8, 0x9d, 0xa3, 0x96, 0xbc, 0xa4, - 0xd8, 0xe8, 0x08, 0xca, 0x0e, 0x49, 0x44, 0x5a, 0xb8, 0xf9, 0xcf, 0x6c, 0xbf, 0x6d, 0x5c, 0x54, - 0x95, 0x8b, 0xd9, 0xf5, 0x76, 0x29, 0xb1, 0xe0, 0x92, 0x43, 0x8c, 0x68, 0x8f, 0x60, 0x43, 0xfd, - 0xb1, 0x0d, 0x5c, 0x7a, 0x41, 0x22, 0x5f, 0xc6, 0xe2, 0xb8, 0xa1, 0x98, 0xa8, 0xf6, 0xbf, 0x6b, - 0x70, 0x26, 0xae, 0x8a, 0x4c, 0xd9, 0xd0, 0x1f, 0x60, 0x93, 0x32, 0x47, 0x4c, 0xb5, 0x44, 0x93, - 0x08, 0x4b, 0x37, 0x6f, 0xb6, 0x37, 0x07, 0x2f, 0x6d, 0xb6, 0x4a, 0x5f, 0xb3, 0x37, 0x3d, 0x80, - 0xb8, 0x3c, 0x7f, 0x58, 0xfd, 0x21, 0xc8, 0xbb, 0x44, 0x12, 0x2d, 0xb9, 0x0a, 0xd6, 0x63, 0xb5, - 0x54, 0xbc, 0xe8, 0x77, 0xbe, 0x54, 0xc7, 0x7e, 0xf5, 0x6d, 0x7d, 0xe5, 0x9f, 0xdf, 0xd6, 0x57, - 0xfe, 0x3c, 0xab, 0xe7, 0x5e, 0xcd, 0xea, 0xb9, 0xbf, 0xcf, 0xea, 0xb9, 0x7f, 0xcd, 0xea, 0xb9, - 0xf3, 0x82, 0xee, 0x9f, 0x7e, 0xf6, 0xbf, 0x00, 0x00, 0x00, 0xff, 0xff, 0xa3, 0xb7, 0x5c, 0xc9, - 0x78, 0x12, 0x00, 0x00, + // 1867 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x57, 0xcf, 0x73, 0x1b, 0x49, + 0x15, 0xb6, 0x6c, 0x59, 0x3f, 0xde, 0xc8, 0x89, 0xd2, 0x24, 0x61, 0xa2, 0xb0, 0xb2, 0xa2, 0x0d, + 0xc1, 0xcb, 0x16, 0x72, 0x61, 0xa8, 0x25, 0xbb, 0x61, 0x01, 0xc9, 0x12, 0x8e, 0x31, 0x76, 0x54, + 0x6d, 0x6f, 0x20, 0x27, 0x55, 0x7b, 0xa6, 0x3d, 0x9a, 0xf2, 0xa8, 0x7b, 0xe8, 0xe9, 0xd1, 0x96, + 0x6e, 0x1c, 0xb7, 0x72, 0xe5, 0xec, 0xe2, 0x40, 0xf1, 0xbf, 0xe4, 0x48, 0x71, 0xe2, 0xe4, 0x62, + 0xfd, 0x2f, 0x70, 0xe3, 0x02, 0xd5, 0x3d, 0x3d, 0xd2, 0x28, 0x19, 0x27, 0xa9, 0x22, 0x07, 0x6e, + 0xdd, 0xaf, 0xbf, 0xef, 0xcd, 0xeb, 0xd7, 0x5f, 0xf7, 0x7b, 0x03, 0x56, 0x14, 0x52, 0x27, 0xea, + 0x84, 0x82, 0x4b, 0x8e, 0x90, 0xcb, 0x9d, 0x73, 0x2a, 0x3a, 0xd1, 0xd7, 0x44, 0x4c, 0xce, 0x7d, + 0xd9, 0x99, 0xfe, 0xb8, 0x61, 0xc9, 0x59, 0x48, 0x0d, 0xa0, 0x71, 0xdb, 0xe3, 0x1e, 0xd7, 0xc3, + 0x6d, 0x35, 0x32, 0xd6, 0xa6, 0xc7, 0xb9, 0x17, 0xd0, 0x6d, 0x3d, 0x3b, 0x8d, 0xcf, 0xb6, 0xdd, + 0x58, 0x10, 0xe9, 0x73, 0x66, 0xd6, 0xef, 0xbd, 0xbe, 0x4e, 0xd8, 0x2c, 0x59, 0x6a, 0x5f, 0x14, + 0xa1, 0x72, 0xc4, 0x5d, 0x7a, 0x1c, 0x52, 0x07, 0xed, 0x81, 0x45, 0x18, 0xe3, 0x52, 0x73, 0x23, + 0xbb, 0xd0, 0x2a, 0x6c, 0x59, 0x3b, 0x9b, 0x9d, 0x37, 0x83, 0xea, 0x74, 0x17, 0xb0, 0x5e, 0xf1, + 0xd5, 0xe5, 0xe6, 0x0a, 0xce, 0x32, 0xd1, 0x2f, 0xa1, 0xe6, 0xd2, 0xc8, 0x17, 0xd4, 0x1d, 0x09, + 0x1e, 0x50, 0x7b, 0xb5, 0x55, 0xd8, 0xba, 0xb1, 0xf3, 0xbd, 0x3c, 0x4f, 0xea, 0xe3, 0x98, 0x07, + 0x14, 0x5b, 0x86, 0xa1, 0x26, 0x68, 0x0f, 0x60, 0x42, 0x27, 0xa7, 0x54, 0x44, 0x63, 0x3f, 0xb4, + 0xd7, 0x34, 0xfd, 0x07, 0xd7, 0xd1, 0x55, 0xec, 0x9d, 0xc3, 0x39, 0x1c, 0x67, 0xa8, 0xe8, 0x10, + 0x6a, 0x64, 0x4a, 0xfc, 0x80, 0x9c, 0xfa, 0x81, 0x2f, 0x67, 0x76, 0x51, 0xbb, 0xfa, 0xe4, 0xad, + 0xae, 0xba, 0x19, 0x02, 0x5e, 0xa2, 0xb7, 0x5d, 0x80, 0xc5, 0x87, 0xd0, 0x23, 0x28, 0x0f, 0x07, + 0x47, 0xfd, 0xfd, 0xa3, 0xbd, 0xfa, 0x4a, 0xe3, 0xde, 0xcb, 0x8b, 0xd6, 0x1d, 0xe5, 0x63, 0x01, + 0x18, 0x52, 0xe6, 0xfa, 0xcc, 0x43, 0x5b, 0x50, 0xe9, 0xee, 0xee, 0x0e, 0x86, 0x27, 0x83, 0x7e, + 0xbd, 0xd0, 0x68, 0xbc, 0xbc, 0x68, 0xdd, 0x5d, 0x06, 0x76, 0x1d, 0x87, 0x86, 0x92, 0xba, 0x8d, + 0xe2, 0x37, 0x7f, 0x69, 0xae, 0xb4, 0xbf, 0x29, 0x40, 0x2d, 0x1b, 0x04, 0x7a, 0x04, 0xa5, 0xee, + 0xee, 0xc9, 0xfe, 0xf3, 0x41, 0x7d, 0x65, 0x41, 0xcf, 0x22, 0xba, 0x8e, 0xf4, 0xa7, 0x14, 0x3d, + 0x84, 0xf5, 0x61, 0xf7, 0xab, 0xe3, 0x41, 0xbd, 0xb0, 0x08, 0x27, 0x0b, 0x1b, 0x92, 0x38, 0xd2, + 0xa8, 0x3e, 0xee, 0xee, 0x1f, 0xd5, 0x57, 0xf3, 0x51, 0x7d, 0x41, 0x7c, 0x66, 0x42, 0xf9, 0x73, + 0x11, 0xac, 0x63, 0x2a, 0xa6, 0xbe, 0xf3, 0x81, 0x25, 0xf2, 0x19, 0x14, 0x25, 0x89, 0xce, 0xb5, + 0x34, 0xac, 0x7c, 0x69, 0x9c, 0x90, 0xe8, 0x5c, 0x7d, 0xd4, 0xd0, 0x35, 0x5e, 0x29, 0x43, 0xd0, + 0x30, 0xf0, 0x1d, 0x22, 0xa9, 0xab, 0x95, 0x61, 0xed, 0x7c, 0x3f, 0x8f, 0x8d, 0xe7, 0x28, 0x13, + 0xff, 0xd3, 0x15, 0x9c, 0xa1, 0xa2, 0x27, 0x50, 0xf2, 0x02, 0x7e, 0x4a, 0x02, 0xad, 0x09, 0x6b, + 0xe7, 0x41, 0x9e, 0x93, 0x3d, 0x8d, 0x58, 0x38, 0x30, 0x14, 0xf4, 0x18, 0x4a, 0x71, 0xe8, 0x12, + 0x49, 0xed, 0x92, 0x26, 0xb7, 0xf2, 0xc8, 0x5f, 0x69, 0xc4, 0x2e, 0x67, 0x67, 0xbe, 0x87, 0x0d, + 0x1e, 0x1d, 0x40, 0x85, 0x51, 0xf9, 0x35, 0x17, 0xe7, 0x91, 0x5d, 0x6e, 0xad, 0x6d, 0x59, 0x3b, + 0x9f, 0xe6, 0x8a, 0x31, 0xc1, 0x74, 0xa5, 0x24, 0xce, 0x78, 0x42, 0x99, 0x4c, 0xdc, 0xf4, 0x56, + 0xed, 0x02, 0x9e, 0x3b, 0x40, 0x3f, 0x87, 0x0a, 0x65, 0x6e, 0xc8, 0x7d, 0x26, 0xed, 0xca, 0xf5, + 0x81, 0x0c, 0x0c, 0x46, 0x25, 0x13, 0xcf, 0x19, 0x8a, 0x2d, 0x78, 0x10, 0x9c, 0x12, 0xe7, 0xdc, + 0xae, 0xbe, 0xe7, 0x36, 0xe6, 0x8c, 0x5e, 0x09, 0x8a, 0x13, 0xee, 0xd2, 0xf6, 0x36, 0xdc, 0x7a, + 0x23, 0xd5, 0xa8, 0x01, 0x15, 0x93, 0xea, 0x44, 0x23, 0x45, 0x3c, 0x9f, 0xb7, 0x6f, 0xc2, 0xc6, + 0x52, 0x5a, 0xdb, 0x7f, 0x2f, 0x42, 0x25, 0x3d, 0x6b, 0xd4, 0x85, 0xaa, 0xc3, 0x99, 0x24, 0x3e, + 0xa3, 0xc2, 0xc8, 0x2b, 0xf7, 0x64, 0x76, 0x53, 0x90, 0x62, 0x3d, 0x5d, 0xc1, 0x0b, 0x16, 0xfa, + 0x35, 0x54, 0x05, 0x8d, 0x78, 0x2c, 0x1c, 0x1a, 0x19, 0x7d, 0x6d, 0xe5, 0x2b, 0x24, 0x01, 0x61, + 0xfa, 0x87, 0xd8, 0x17, 0x54, 0x65, 0x39, 0xc2, 0x0b, 0x2a, 0x7a, 0x02, 0x65, 0x41, 0x23, 0x49, + 0x84, 0x7c, 0x9b, 0x44, 0x70, 0x02, 0x19, 0xf2, 0xc0, 0x77, 0x66, 0x38, 0x65, 0xa0, 0x27, 0x50, + 0x0d, 0x03, 0xe2, 0x68, 0xaf, 0xf6, 0xba, 0xa6, 0x7f, 0x94, 0x47, 0x1f, 0xa6, 0x20, 0xbc, 0xc0, + 0xa3, 0xcf, 0x01, 0x02, 0xee, 0x8d, 0x5c, 0xe1, 0x4f, 0xa9, 0x30, 0x12, 0x6b, 0xe4, 0xb1, 0xfb, + 0x1a, 0x81, 0xab, 0x01, 0xf7, 0x92, 0x21, 0xda, 0xfb, 0x9f, 0xf4, 0x95, 0xd1, 0xd6, 0x01, 0x00, + 0x99, 0xaf, 0x1a, 0x75, 0x7d, 0xf2, 0x5e, 0xae, 0xcc, 0x89, 0x64, 0xe8, 0xe8, 0x01, 0xd4, 0xce, + 0xb8, 0x70, 0xe8, 0xc8, 0xdc, 0x9a, 0xaa, 0xd6, 0x84, 0xa5, 0x6d, 0x89, 0xbe, 0x50, 0x0f, 0xca, + 0x1e, 0x65, 0x54, 0xf8, 0x8e, 0x0d, 0xfa, 0x63, 0x8f, 0x72, 0x2f, 0x64, 0x02, 0xc1, 0x31, 0x93, + 0xfe, 0x84, 0x9a, 0x2f, 0xa5, 0xc4, 0x5e, 0x15, 0xca, 0x22, 0x59, 0x69, 0xff, 0x1e, 0xd0, 0x9b, + 0x58, 0x84, 0xa0, 0x78, 0xee, 0x33, 0x57, 0x0b, 0xab, 0x8a, 0xf5, 0x18, 0x75, 0xa0, 0x1c, 0x92, + 0x59, 0xc0, 0x89, 0x6b, 0xc4, 0x72, 0xbb, 0x93, 0xd4, 0xcb, 0x4e, 0x5a, 0x2f, 0x3b, 0x5d, 0x36, + 0xc3, 0x29, 0xa8, 0x7d, 0x00, 0x77, 0x72, 0xb7, 0x8c, 0x76, 0xa0, 0x36, 0x17, 0xe1, 0xc8, 0x37, + 0x1f, 0xe9, 0xdd, 0xbc, 0xba, 0xdc, 0xb4, 0xe6, 0x6a, 0xdd, 0xef, 0x63, 0x6b, 0x0e, 0xda, 0x77, + 0xdb, 0x7f, 0xaa, 0xc2, 0xc6, 0x92, 0x94, 0xd1, 0x6d, 0x58, 0xf7, 0x27, 0xc4, 0xa3, 0x26, 0xc6, + 0x64, 0x82, 0x06, 0x50, 0x0a, 0xc8, 0x29, 0x0d, 0x94, 0xa0, 0xd5, 0xa1, 0xfe, 0xe8, 0x9d, 0x77, + 0xa2, 0xf3, 0x5b, 0x8d, 0x1f, 0x30, 0x29, 0x66, 0xd8, 0x90, 0x91, 0x0d, 0x65, 0x87, 0x4f, 0x26, + 0x84, 0xa9, 0xa7, 0x73, 0x6d, 0xab, 0x8a, 0xd3, 0xa9, 0xca, 0x0c, 0x11, 0x5e, 0x64, 0x17, 0xb5, + 0x59, 0x8f, 0x51, 0x1d, 0xd6, 0x28, 0x9b, 0xda, 0xeb, 0xda, 0xa4, 0x86, 0xca, 0xe2, 0xfa, 0x89, + 0x22, 0xab, 0x58, 0x0d, 0x15, 0x2f, 0x8e, 0xa8, 0xb0, 0xcb, 0x49, 0x46, 0xd5, 0x18, 0xfd, 0x0c, + 0x4a, 0x13, 0x1e, 0x33, 0x19, 0xd9, 0x15, 0x1d, 0xec, 0xbd, 0xbc, 0x60, 0x0f, 0x15, 0xc2, 0x3c, + 0xed, 0x06, 0x8e, 0x06, 0x70, 0x2b, 0x92, 0x3c, 0x1c, 0x79, 0x82, 0x38, 0x74, 0x14, 0x52, 0xe1, + 0x73, 0xd7, 0x3c, 0x4d, 0xf7, 0xde, 0x38, 0x94, 0xbe, 0x69, 0x72, 0xf0, 0x4d, 0xc5, 0xd9, 0x53, + 0x94, 0xa1, 0x66, 0xa0, 0x21, 0xd4, 0xc2, 0x38, 0x08, 0x46, 0x3c, 0x4c, 0xaa, 0x54, 0xa2, 0xa7, + 0xf7, 0x48, 0xd9, 0x30, 0x0e, 0x82, 0x67, 0x09, 0x09, 0x5b, 0xe1, 0x62, 0x82, 0xee, 0x42, 0xc9, + 0x13, 0x3c, 0x0e, 0x23, 0xdb, 0xd2, 0xc9, 0x30, 0x33, 0xf4, 0x25, 0x94, 0x23, 0xea, 0x08, 0x2a, + 0x23, 0xbb, 0xa6, 0xb7, 0xfa, 0x71, 0xde, 0x47, 0x8e, 0x35, 0x04, 0xd3, 0x33, 0x2a, 0x28, 0x73, + 0x28, 0x4e, 0x39, 0xe8, 0x1e, 0xac, 0x49, 0x39, 0xb3, 0x37, 0x5a, 0x85, 0xad, 0x4a, 0xaf, 0x7c, + 0x75, 0xb9, 0xb9, 0x76, 0x72, 0xf2, 0x02, 0x2b, 0x9b, 0x7a, 0x41, 0xc7, 0x3c, 0x92, 0x8c, 0x4c, + 0xa8, 0x7d, 0x43, 0xe7, 0x76, 0x3e, 0x47, 0x2f, 0x00, 0x5c, 0x16, 0x8d, 0x1c, 0x7d, 0x65, 0xed, + 0x9b, 0x7a, 0x77, 0x9f, 0xbe, 0x7b, 0x77, 0xfd, 0xa3, 0x63, 0x53, 0x45, 0x36, 0xae, 0x2e, 0x37, + 0xab, 0xf3, 0x29, 0xae, 0xba, 0x2c, 0x4a, 0x86, 0xa8, 0x07, 0xd6, 0x98, 0x92, 0x40, 0x8e, 0x9d, + 0x31, 0x75, 0xce, 0xed, 0xfa, 0xf5, 0x65, 0xe1, 0xa9, 0x86, 0x19, 0x0f, 0x59, 0x92, 0x52, 0xb0, + 0x0a, 0x35, 0xb2, 0x6f, 0xe9, 0x5c, 0x25, 0x13, 0xf4, 0x11, 0x00, 0x0f, 0x29, 0x1b, 0x45, 0xd2, + 0xf5, 0x99, 0x8d, 0xd4, 0x96, 0x71, 0x55, 0x59, 0x8e, 0x95, 0x01, 0xdd, 0x57, 0x8f, 0x36, 0x71, + 0x47, 0x9c, 0x05, 0x33, 0xfb, 0x3b, 0x7a, 0xb5, 0xa2, 0x0c, 0xcf, 0x58, 0x30, 0x43, 0x9b, 0x60, + 0x69, 0x5d, 0x44, 0xbe, 0xc7, 0x48, 0x60, 0xdf, 0xd6, 0xf9, 0x00, 0x65, 0x3a, 0xd6, 0x16, 0x75, + 0x0e, 0x49, 0x36, 0x22, 0xfb, 0xce, 0xf5, 0xe7, 0x60, 0x82, 0x5d, 0x9c, 0x83, 0xe1, 0xa0, 0x5f, + 0x00, 0x84, 0xc2, 0x9f, 0xfa, 0x01, 0xf5, 0x68, 0x64, 0xdf, 0xd5, 0x9b, 0x6e, 0xe6, 0xbe, 0xd6, + 0x73, 0x14, 0xce, 0x30, 0x1a, 0x9f, 0x83, 0x95, 0xb9, 0x6d, 0xea, 0x96, 0x9c, 0xd3, 0x99, 0xb9, + 0xc0, 0x6a, 0xa8, 0x52, 0x32, 0x25, 0x41, 0x9c, 0x74, 0xc2, 0x55, 0x9c, 0x4c, 0xbe, 0x58, 0x7d, + 0x5c, 0x68, 0xec, 0x80, 0x95, 0x51, 0x1d, 0xfa, 0x18, 0x36, 0x04, 0xf5, 0xfc, 0x48, 0x8a, 0xd9, + 0x88, 0xc4, 0x72, 0x6c, 0xff, 0x4a, 0x13, 0x6a, 0xa9, 0xb1, 0x1b, 0xcb, 0x71, 0x63, 0x04, 0x8b, + 0xc3, 0x43, 0x2d, 0xb0, 0x94, 0x28, 0x22, 0x2a, 0xa6, 0x54, 0xa8, 0x6a, 0xab, 0x72, 0x9e, 0x35, + 0x29, 0xf1, 0x46, 0x94, 0x08, 0x67, 0xac, 0xdf, 0x8e, 0x2a, 0x36, 0x33, 0xf5, 0x18, 0xa4, 0x37, + 0xc4, 0x3c, 0x06, 0x66, 0xda, 0xfe, 0x57, 0x01, 0x6a, 0xd9, 0xa6, 0x01, 0xed, 0x26, 0xc5, 0x5e, + 0x6f, 0xe9, 0xc6, 0xce, 0xf6, 0xbb, 0x9a, 0x0c, 0x5d, 0x5a, 0x83, 0x58, 0x39, 0x3b, 0x54, 0xfd, + 0xbd, 0x26, 0xa3, 0x9f, 0xc2, 0x7a, 0xc8, 0x85, 0x4c, 0x9f, 0xb0, 0xfc, 0x04, 0x73, 0x91, 0x96, + 0xa2, 0x04, 0xdc, 0x1e, 0xc3, 0x8d, 0x65, 0x6f, 0xe8, 0x21, 0xac, 0x3d, 0xdf, 0x1f, 0xd6, 0x57, + 0x1a, 0xf7, 0x5f, 0x5e, 0xb4, 0xbe, 0xbb, 0xbc, 0xf8, 0xdc, 0x17, 0x32, 0x26, 0xc1, 0xfe, 0x10, + 0xfd, 0x10, 0xd6, 0xfb, 0x47, 0xc7, 0x18, 0xd7, 0x0b, 0x8d, 0xcd, 0x97, 0x17, 0xad, 0xfb, 0xcb, + 0x38, 0xb5, 0xc4, 0x63, 0xe6, 0x62, 0x7e, 0x3a, 0xef, 0x75, 0xff, 0xbd, 0x0a, 0x96, 0x79, 0xd9, + 0x3f, 0xf4, 0xef, 0xd0, 0x46, 0x52, 0xca, 0xd3, 0x2b, 0xbb, 0xfa, 0xce, 0x8a, 0x5e, 0x4b, 0x08, + 0xe6, 0x8c, 0x1f, 0x40, 0xcd, 0x0f, 0xa7, 0x9f, 0x8d, 0x28, 0x23, 0xa7, 0x81, 0x69, 0x7b, 0x2b, + 0xd8, 0x52, 0xb6, 0x41, 0x62, 0x52, 0xef, 0x85, 0xcf, 0x24, 0x15, 0xcc, 0x34, 0xb4, 0x15, 0x3c, + 0x9f, 0xa3, 0x2f, 0xa1, 0xe8, 0x87, 0x64, 0x62, 0xda, 0x90, 0xdc, 0x1d, 0xec, 0x0f, 0xbb, 0x87, + 0x46, 0x83, 0xbd, 0xca, 0xd5, 0xe5, 0x66, 0x51, 0x19, 0xb0, 0xa6, 0xa1, 0x66, 0xda, 0x09, 0xa8, + 0x2f, 0xe9, 0xb7, 0xbf, 0x82, 0x33, 0x16, 0xa5, 0x23, 0x9f, 0x79, 0x82, 0x46, 0x91, 0xae, 0x02, + 0x15, 0x9c, 0x4e, 0x51, 0x03, 0xca, 0xa6, 0x9f, 0xd0, 0x0d, 0x44, 0x55, 0xd5, 0x6a, 0x63, 0xe8, + 0x6d, 0x80, 0x95, 0x64, 0x63, 0x74, 0x26, 0xf8, 0xa4, 0xfd, 0x9f, 0x22, 0x58, 0xbb, 0x41, 0x1c, + 0x49, 0x53, 0x06, 0x3f, 0x58, 0xf2, 0x5f, 0xc0, 0x2d, 0xa2, 0x7f, 0xaf, 0x08, 0x53, 0x35, 0x45, + 0xb7, 0x69, 0xe6, 0x00, 0x1e, 0xe6, 0xba, 0x9b, 0x83, 0x93, 0x96, 0xae, 0x57, 0x52, 0x3e, 0xed, + 0x02, 0xae, 0x93, 0xd7, 0x56, 0xd0, 0x31, 0x6c, 0x70, 0xe1, 0x8c, 0x69, 0x24, 0x93, 0x4a, 0x64, + 0x7e, 0x47, 0x72, 0x7f, 0x54, 0x9f, 0x65, 0x81, 0xe6, 0x19, 0x4e, 0xa2, 0x5d, 0xf6, 0x81, 0x1e, + 0x43, 0x51, 0x90, 0xb3, 0xb4, 0xe5, 0xcc, 0xbd, 0x24, 0x98, 0x9c, 0xc9, 0x25, 0x17, 0x9a, 0x81, + 0x7e, 0x03, 0xe0, 0xfa, 0x51, 0x48, 0xa4, 0x33, 0xa6, 0xc2, 0x1c, 0x76, 0xee, 0x16, 0xfb, 0x73, + 0xd4, 0x92, 0x97, 0x0c, 0x1b, 0x1d, 0x40, 0xd5, 0x21, 0xa9, 0x5c, 0x4b, 0xd7, 0xff, 0xa3, 0xed, + 0x76, 0x8d, 0x8b, 0xba, 0x72, 0x71, 0x75, 0xb9, 0x59, 0x49, 0x2d, 0xb8, 0xe2, 0x10, 0x23, 0xdf, + 0x03, 0xd8, 0x50, 0xff, 0x6e, 0x23, 0x97, 0x9e, 0x91, 0x38, 0x90, 0x89, 0x4c, 0xae, 0x29, 0x2b, + 0xea, 0x47, 0xa0, 0x6f, 0x70, 0x26, 0xae, 0x9a, 0xcc, 0xd8, 0xd0, 0xef, 0xe0, 0x16, 0x65, 0x8e, + 0x98, 0x69, 0xb1, 0xa6, 0x11, 0x56, 0xae, 0xdf, 0xec, 0x60, 0x0e, 0x5e, 0xda, 0x6c, 0x9d, 0xbe, + 0x66, 0x6f, 0xff, 0xb5, 0x00, 0x90, 0x54, 0xea, 0x0f, 0x2b, 0x40, 0x04, 0x45, 0x97, 0x48, 0xa2, + 0x35, 0x57, 0xc3, 0x7a, 0x8c, 0xbe, 0x00, 0x90, 0x74, 0x12, 0x06, 0x44, 0xfa, 0xcc, 0x33, 0xb2, + 0x79, 0xdb, 0x73, 0x90, 0x41, 0xeb, 0x38, 0x93, 0x90, 0xff, 0xaf, 0xe3, 0xec, 0xd9, 0xaf, 0xbe, + 0x6d, 0xae, 0xfc, 0xe3, 0xdb, 0xe6, 0xca, 0x1f, 0xaf, 0x9a, 0x85, 0x57, 0x57, 0xcd, 0xc2, 0xdf, + 0xae, 0x9a, 0x85, 0x7f, 0x5e, 0x35, 0x0b, 0xa7, 0x25, 0xdd, 0xc3, 0xfd, 0xe4, 0xbf, 0x01, 0x00, + 0x00, 0xff, 0xff, 0x06, 0x93, 0x6e, 0xba, 0xfc, 0x12, 0x00, 0x00, } diff --git a/vendor/github.com/docker/swarmkit/api/specs.proto b/vendor/github.com/docker/swarmkit/api/specs.proto index ba842660f21d..13b52d410510 100644 --- a/vendor/github.com/docker/swarmkit/api/specs.proto +++ b/vendor/github.com/docker/swarmkit/api/specs.proto @@ -342,10 +342,14 @@ message NetworkSpec { // "ingress" and the label "com.docker.swarm.internal": "true". bool ingress = 7; - // ConfigFrom indicates that the network specific configuration - // for this network will be provided via another network, locally - // on the node where this network is being plumbed. - string config_from = 8; + // ConfigFrom is the source of the configuration for this network. + oneof config_from { + // Network is the name of a network that provides the network + // specific configuration for this network, locally on the node + // where this network is being plumbed. + string network = 8; + } + } // ClusterSpec specifies global cluster settings. @@ -382,6 +386,13 @@ message SecretSpec { // Data is the secret payload - the maximum size is 500KB (that is, 500*1024 bytes) bytes data = 2; + + // Templating controls whether and how to evaluate the secret payload as + // a template. If it is not set, no templating is used. + // + // The currently recognized values are: + // - golang: Go templating + Driver templating = 3; } // ConfigSpec specifies user-provided configuration files. @@ -392,4 +403,11 @@ message ConfigSpec { // TODO(aaronl): Do we want to revise this to include multiple payloads in a single // ConfigSpec? Define this to be a tar? etc... bytes data = 2; + + // Templating controls whether and how to evaluate the secret payload as + // a template. If it is not set, no templating is used. + // + // The currently recognized values are: + // - golang: Go templating + Driver templating = 3; } diff --git a/vendor/github.com/docker/swarmkit/api/types.pb.go b/vendor/github.com/docker/swarmkit/api/types.pb.go index 7ff65e47caf0..2befc03577f2 100644 --- a/vendor/github.com/docker/swarmkit/api/types.pb.go +++ b/vendor/github.com/docker/swarmkit/api/types.pb.go @@ -23,6 +23,9 @@ Version IndexEntry Annotations + GenericString + GenericDiscrete + GenericResource Resources ResourceRequirements Platform @@ -354,7 +357,7 @@ func (x RaftMemberStatus_Reachability) String() string { return proto.EnumName(RaftMemberStatus_Reachability_name, int32(x)) } func (RaftMemberStatus_Reachability) EnumDescriptor() ([]byte, []int) { - return fileDescriptorTypes, []int{10, 0} + return fileDescriptorTypes, []int{13, 0} } // TODO(aluzzardi) These should be using `gogoproto.enumvalue_customname`. @@ -387,7 +390,7 @@ var NodeStatus_State_value = map[string]int32{ func (x NodeStatus_State) String() string { return proto.EnumName(NodeStatus_State_name, int32(x)) } -func (NodeStatus_State) EnumDescriptor() ([]byte, []int) { return fileDescriptorTypes, []int{11, 0} } +func (NodeStatus_State) EnumDescriptor() ([]byte, []int) { return fileDescriptorTypes, []int{14, 0} } type Mount_MountType int32 @@ -411,7 +414,7 @@ var Mount_MountType_value = map[string]int32{ func (x Mount_MountType) String() string { return proto.EnumName(Mount_MountType_name, int32(x)) } -func (Mount_MountType) EnumDescriptor() ([]byte, []int) { return fileDescriptorTypes, []int{13, 0} } +func (Mount_MountType) EnumDescriptor() ([]byte, []int) { return fileDescriptorTypes, []int{16, 0} } type Mount_BindOptions_MountPropagation int32 @@ -445,7 +448,7 @@ func (x Mount_BindOptions_MountPropagation) String() string { return proto.EnumName(Mount_BindOptions_MountPropagation_name, int32(x)) } func (Mount_BindOptions_MountPropagation) EnumDescriptor() ([]byte, []int) { - return fileDescriptorTypes, []int{13, 0, 0} + return fileDescriptorTypes, []int{16, 0, 0} } type RestartPolicy_RestartCondition int32 @@ -471,7 +474,7 @@ func (x RestartPolicy_RestartCondition) String() string { return proto.EnumName(RestartPolicy_RestartCondition_name, int32(x)) } func (RestartPolicy_RestartCondition) EnumDescriptor() ([]byte, []int) { - return fileDescriptorTypes, []int{14, 0} + return fileDescriptorTypes, []int{17, 0} } type UpdateConfig_FailureAction int32 @@ -497,7 +500,7 @@ func (x UpdateConfig_FailureAction) String() string { return proto.EnumName(UpdateConfig_FailureAction_name, int32(x)) } func (UpdateConfig_FailureAction) EnumDescriptor() ([]byte, []int) { - return fileDescriptorTypes, []int{15, 0} + return fileDescriptorTypes, []int{18, 0} } // UpdateOrder controls the order of operations when rolling out an @@ -524,7 +527,7 @@ func (x UpdateConfig_UpdateOrder) String() string { return proto.EnumName(UpdateConfig_UpdateOrder_name, int32(x)) } func (UpdateConfig_UpdateOrder) EnumDescriptor() ([]byte, []int) { - return fileDescriptorTypes, []int{15, 1} + return fileDescriptorTypes, []int{18, 1} } type UpdateStatus_UpdateState int32 @@ -562,7 +565,7 @@ func (x UpdateStatus_UpdateState) String() string { return proto.EnumName(UpdateStatus_UpdateState_name, int32(x)) } func (UpdateStatus_UpdateState) EnumDescriptor() ([]byte, []int) { - return fileDescriptorTypes, []int{16, 0} + return fileDescriptorTypes, []int{19, 0} } // AddressFamily specifies the network address family that @@ -590,7 +593,7 @@ func (x IPAMConfig_AddressFamily) String() string { return proto.EnumName(IPAMConfig_AddressFamily_name, int32(x)) } func (IPAMConfig_AddressFamily) EnumDescriptor() ([]byte, []int) { - return fileDescriptorTypes, []int{21, 0} + return fileDescriptorTypes, []int{24, 0} } type PortConfig_Protocol int32 @@ -612,7 +615,7 @@ var PortConfig_Protocol_value = map[string]int32{ func (x PortConfig_Protocol) String() string { return proto.EnumName(PortConfig_Protocol_name, int32(x)) } -func (PortConfig_Protocol) EnumDescriptor() ([]byte, []int) { return fileDescriptorTypes, []int{22, 0} } +func (PortConfig_Protocol) EnumDescriptor() ([]byte, []int) { return fileDescriptorTypes, []int{25, 0} } // PublishMode controls how ports are published on the swarm. type PortConfig_PublishMode int32 @@ -640,7 +643,7 @@ func (x PortConfig_PublishMode) String() string { return proto.EnumName(PortConfig_PublishMode_name, int32(x)) } func (PortConfig_PublishMode) EnumDescriptor() ([]byte, []int) { - return fileDescriptorTypes, []int{22, 1} + return fileDescriptorTypes, []int{25, 1} } type IssuanceStatus_State int32 @@ -680,7 +683,7 @@ var IssuanceStatus_State_value = map[string]int32{ func (x IssuanceStatus_State) String() string { return proto.EnumName(IssuanceStatus_State_name, int32(x)) } -func (IssuanceStatus_State) EnumDescriptor() ([]byte, []int) { return fileDescriptorTypes, []int{27, 0} } +func (IssuanceStatus_State) EnumDescriptor() ([]byte, []int) { return fileDescriptorTypes, []int{30, 0} } type ExternalCA_CAProtocol int32 @@ -699,7 +702,7 @@ func (x ExternalCA_CAProtocol) String() string { return proto.EnumName(ExternalCA_CAProtocol_name, int32(x)) } func (ExternalCA_CAProtocol) EnumDescriptor() ([]byte, []int) { - return fileDescriptorTypes, []int{29, 0} + return fileDescriptorTypes, []int{32, 0} } // Encryption algorithm that can implemented using this key @@ -720,7 +723,7 @@ func (x EncryptionKey_Algorithm) String() string { return proto.EnumName(EncryptionKey_Algorithm_name, int32(x)) } func (EncryptionKey_Algorithm) EnumDescriptor() ([]byte, []int) { - return fileDescriptorTypes, []int{42, 0} + return fileDescriptorTypes, []int{45, 0} } type MaybeEncryptedRecord_Algorithm int32 @@ -743,7 +746,7 @@ func (x MaybeEncryptedRecord_Algorithm) String() string { return proto.EnumName(MaybeEncryptedRecord_Algorithm_name, int32(x)) } func (MaybeEncryptedRecord_Algorithm) EnumDescriptor() ([]byte, []int) { - return fileDescriptorTypes, []int{49, 0} + return fileDescriptorTypes, []int{52, 0} } // Version tracks the last time an object in the store was updated. @@ -778,16 +781,158 @@ func (m *Annotations) Reset() { *m = Annotations{} } func (*Annotations) ProtoMessage() {} func (*Annotations) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{2} } +type GenericString struct { + Kind string `protobuf:"bytes,1,opt,name=kind,proto3" json:"kind,omitempty"` + Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` +} + +func (m *GenericString) Reset() { *m = GenericString{} } +func (*GenericString) ProtoMessage() {} +func (*GenericString) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{3} } + +type GenericDiscrete struct { + Kind string `protobuf:"bytes,1,opt,name=kind,proto3" json:"kind,omitempty"` + Value int64 `protobuf:"varint,2,opt,name=value,proto3" json:"value,omitempty"` +} + +func (m *GenericDiscrete) Reset() { *m = GenericDiscrete{} } +func (*GenericDiscrete) ProtoMessage() {} +func (*GenericDiscrete) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{4} } + +type GenericResource struct { + // Types that are valid to be assigned to Resource: + // *GenericResource_Str + // *GenericResource_Discrete + Resource isGenericResource_Resource `protobuf_oneof:"resource"` +} + +func (m *GenericResource) Reset() { *m = GenericResource{} } +func (*GenericResource) ProtoMessage() {} +func (*GenericResource) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{5} } + +type isGenericResource_Resource interface { + isGenericResource_Resource() + MarshalTo([]byte) (int, error) + Size() int +} + +type GenericResource_Str struct { + Str *GenericString `protobuf:"bytes,1,opt,name=str,oneof"` +} +type GenericResource_Discrete struct { + Discrete *GenericDiscrete `protobuf:"bytes,2,opt,name=discrete,oneof"` +} + +func (*GenericResource_Str) isGenericResource_Resource() {} +func (*GenericResource_Discrete) isGenericResource_Resource() {} + +func (m *GenericResource) GetResource() isGenericResource_Resource { + if m != nil { + return m.Resource + } + return nil +} + +func (m *GenericResource) GetStr() *GenericString { + if x, ok := m.GetResource().(*GenericResource_Str); ok { + return x.Str + } + return nil +} + +func (m *GenericResource) GetDiscrete() *GenericDiscrete { + if x, ok := m.GetResource().(*GenericResource_Discrete); ok { + return x.Discrete + } + return nil +} + +// XXX_OneofFuncs is for the internal use of the proto package. +func (*GenericResource) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) { + return _GenericResource_OneofMarshaler, _GenericResource_OneofUnmarshaler, _GenericResource_OneofSizer, []interface{}{ + (*GenericResource_Str)(nil), + (*GenericResource_Discrete)(nil), + } +} + +func _GenericResource_OneofMarshaler(msg proto.Message, b *proto.Buffer) error { + m := msg.(*GenericResource) + // resource + switch x := m.Resource.(type) { + case *GenericResource_Str: + _ = b.EncodeVarint(1<<3 | proto.WireBytes) + if err := b.EncodeMessage(x.Str); err != nil { + return err + } + case *GenericResource_Discrete: + _ = b.EncodeVarint(2<<3 | proto.WireBytes) + if err := b.EncodeMessage(x.Discrete); err != nil { + return err + } + case nil: + default: + return fmt.Errorf("GenericResource.Resource has unexpected type %T", x) + } + return nil +} + +func _GenericResource_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) { + m := msg.(*GenericResource) + switch tag { + case 1: // resource.str + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + msg := new(GenericString) + err := b.DecodeMessage(msg) + m.Resource = &GenericResource_Str{msg} + return true, err + case 2: // resource.discrete + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + msg := new(GenericDiscrete) + err := b.DecodeMessage(msg) + m.Resource = &GenericResource_Discrete{msg} + return true, err + default: + return false, nil + } +} + +func _GenericResource_OneofSizer(msg proto.Message) (n int) { + m := msg.(*GenericResource) + // resource + switch x := m.Resource.(type) { + case *GenericResource_Str: + s := proto.Size(x.Str) + n += proto.SizeVarint(1<<3 | proto.WireBytes) + n += proto.SizeVarint(uint64(s)) + n += s + case *GenericResource_Discrete: + s := proto.Size(x.Discrete) + n += proto.SizeVarint(2<<3 | proto.WireBytes) + n += proto.SizeVarint(uint64(s)) + n += s + case nil: + default: + panic(fmt.Sprintf("proto: unexpected type %T in oneof", x)) + } + return n +} + type Resources struct { // Amount of CPUs (e.g. 2000000000 = 2 CPU cores) NanoCPUs int64 `protobuf:"varint,1,opt,name=nano_cpus,json=nanoCpus,proto3" json:"nano_cpus,omitempty"` // Amount of memory in bytes. MemoryBytes int64 `protobuf:"varint,2,opt,name=memory_bytes,json=memoryBytes,proto3" json:"memory_bytes,omitempty"` + // User specified resource (e.g: bananas=2;apple={red,yellow,green}) + Generic []*GenericResource `protobuf:"bytes,3,rep,name=generic" json:"generic,omitempty"` } func (m *Resources) Reset() { *m = Resources{} } func (*Resources) ProtoMessage() {} -func (*Resources) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{3} } +func (*Resources) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{6} } type ResourceRequirements struct { Limits *Resources `protobuf:"bytes,1,opt,name=limits" json:"limits,omitempty"` @@ -796,7 +941,7 @@ type ResourceRequirements struct { func (m *ResourceRequirements) Reset() { *m = ResourceRequirements{} } func (*ResourceRequirements) ProtoMessage() {} -func (*ResourceRequirements) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{4} } +func (*ResourceRequirements) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{7} } type Platform struct { // Architecture (e.g. x86_64) @@ -807,7 +952,7 @@ type Platform struct { func (m *Platform) Reset() { *m = Platform{} } func (*Platform) ProtoMessage() {} -func (*Platform) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{5} } +func (*Platform) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{8} } // PluginDescription describes an engine plugin. type PluginDescription struct { @@ -821,7 +966,7 @@ type PluginDescription struct { func (m *PluginDescription) Reset() { *m = PluginDescription{} } func (*PluginDescription) ProtoMessage() {} -func (*PluginDescription) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{6} } +func (*PluginDescription) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{9} } type EngineDescription struct { // Docker daemon version running on the node. @@ -834,7 +979,7 @@ type EngineDescription struct { func (m *EngineDescription) Reset() { *m = EngineDescription{} } func (*EngineDescription) ProtoMessage() {} -func (*EngineDescription) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{7} } +func (*EngineDescription) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{10} } type NodeDescription struct { // Hostname of the node as reported by the agent. @@ -852,7 +997,7 @@ type NodeDescription struct { func (m *NodeDescription) Reset() { *m = NodeDescription{} } func (*NodeDescription) ProtoMessage() {} -func (*NodeDescription) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{8} } +func (*NodeDescription) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{11} } type NodeTLSInfo struct { // Information about which root certs the node trusts @@ -864,7 +1009,7 @@ type NodeTLSInfo struct { func (m *NodeTLSInfo) Reset() { *m = NodeTLSInfo{} } func (*NodeTLSInfo) ProtoMessage() {} -func (*NodeTLSInfo) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{9} } +func (*NodeTLSInfo) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{12} } type RaftMemberStatus struct { Leader bool `protobuf:"varint,1,opt,name=leader,proto3" json:"leader,omitempty"` @@ -874,7 +1019,7 @@ type RaftMemberStatus struct { func (m *RaftMemberStatus) Reset() { *m = RaftMemberStatus{} } func (*RaftMemberStatus) ProtoMessage() {} -func (*RaftMemberStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{10} } +func (*RaftMemberStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{13} } type NodeStatus struct { State NodeStatus_State `protobuf:"varint,1,opt,name=state,proto3,enum=docker.swarmkit.v1.NodeStatus_State" json:"state,omitempty"` @@ -885,7 +1030,7 @@ type NodeStatus struct { func (m *NodeStatus) Reset() { *m = NodeStatus{} } func (*NodeStatus) ProtoMessage() {} -func (*NodeStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{11} } +func (*NodeStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{14} } type Image struct { // reference is a docker image reference. This can include a rpository, tag @@ -896,7 +1041,7 @@ type Image struct { func (m *Image) Reset() { *m = Image{} } func (*Image) ProtoMessage() {} -func (*Image) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{12} } +func (*Image) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{15} } // Mount describes volume mounts for a container. // @@ -931,7 +1076,7 @@ type Mount struct { func (m *Mount) Reset() { *m = Mount{} } func (*Mount) ProtoMessage() {} -func (*Mount) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{13} } +func (*Mount) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{16} } // BindOptions specifies options that are specific to a bind mount. type Mount_BindOptions struct { @@ -941,7 +1086,7 @@ type Mount_BindOptions struct { func (m *Mount_BindOptions) Reset() { *m = Mount_BindOptions{} } func (*Mount_BindOptions) ProtoMessage() {} -func (*Mount_BindOptions) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{13, 0} } +func (*Mount_BindOptions) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{16, 0} } // VolumeOptions contains parameters for mounting the volume. type Mount_VolumeOptions struct { @@ -958,7 +1103,7 @@ type Mount_VolumeOptions struct { func (m *Mount_VolumeOptions) Reset() { *m = Mount_VolumeOptions{} } func (*Mount_VolumeOptions) ProtoMessage() {} -func (*Mount_VolumeOptions) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{13, 1} } +func (*Mount_VolumeOptions) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{16, 1} } type Mount_TmpfsOptions struct { // Size sets the size of the tmpfs, in bytes. @@ -976,7 +1121,7 @@ type Mount_TmpfsOptions struct { func (m *Mount_TmpfsOptions) Reset() { *m = Mount_TmpfsOptions{} } func (*Mount_TmpfsOptions) ProtoMessage() {} -func (*Mount_TmpfsOptions) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{13, 2} } +func (*Mount_TmpfsOptions) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{16, 2} } type RestartPolicy struct { Condition RestartPolicy_RestartCondition `protobuf:"varint,1,opt,name=condition,proto3,enum=docker.swarmkit.v1.RestartPolicy_RestartCondition" json:"condition,omitempty"` @@ -994,7 +1139,7 @@ type RestartPolicy struct { func (m *RestartPolicy) Reset() { *m = RestartPolicy{} } func (*RestartPolicy) ProtoMessage() {} -func (*RestartPolicy) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{14} } +func (*RestartPolicy) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{17} } // UpdateConfig specifies the rate and policy of updates. // TODO(aluzzardi): Consider making this a oneof with RollingStrategy and LockstepStrategy. @@ -1034,7 +1179,7 @@ type UpdateConfig struct { func (m *UpdateConfig) Reset() { *m = UpdateConfig{} } func (*UpdateConfig) ProtoMessage() {} -func (*UpdateConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{15} } +func (*UpdateConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{18} } // UpdateStatus is the status of an update in progress. type UpdateStatus struct { @@ -1058,7 +1203,7 @@ type UpdateStatus struct { func (m *UpdateStatus) Reset() { *m = UpdateStatus{} } func (*UpdateStatus) ProtoMessage() {} -func (*UpdateStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{16} } +func (*UpdateStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{19} } // Container specific status. type ContainerStatus struct { @@ -1069,7 +1214,7 @@ type ContainerStatus struct { func (m *ContainerStatus) Reset() { *m = ContainerStatus{} } func (*ContainerStatus) ProtoMessage() {} -func (*ContainerStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{17} } +func (*ContainerStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{20} } // PortStatus specifies the actual allocated runtime state of a list // of port configs. @@ -1079,7 +1224,7 @@ type PortStatus struct { func (m *PortStatus) Reset() { *m = PortStatus{} } func (*PortStatus) ProtoMessage() {} -func (*PortStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{18} } +func (*PortStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{21} } type TaskStatus struct { // Note: can't use stdtime because this field is nullable. @@ -1116,7 +1261,7 @@ type TaskStatus struct { func (m *TaskStatus) Reset() { *m = TaskStatus{} } func (*TaskStatus) ProtoMessage() {} -func (*TaskStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{19} } +func (*TaskStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{22} } type isTaskStatus_RuntimeStatus interface { isTaskStatus_RuntimeStatus() @@ -1220,7 +1365,7 @@ type NetworkAttachmentConfig struct { func (m *NetworkAttachmentConfig) Reset() { *m = NetworkAttachmentConfig{} } func (*NetworkAttachmentConfig) ProtoMessage() {} -func (*NetworkAttachmentConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{20} } +func (*NetworkAttachmentConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{23} } // IPAMConfig specifies parameters for IP Address Management. type IPAMConfig struct { @@ -1241,7 +1386,7 @@ type IPAMConfig struct { func (m *IPAMConfig) Reset() { *m = IPAMConfig{} } func (*IPAMConfig) ProtoMessage() {} -func (*IPAMConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{21} } +func (*IPAMConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{24} } // PortConfig specifies an exposed port which can be // addressed using the given name. This can be later queried @@ -1267,7 +1412,7 @@ type PortConfig struct { func (m *PortConfig) Reset() { *m = PortConfig{} } func (*PortConfig) ProtoMessage() {} -func (*PortConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{22} } +func (*PortConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{25} } // Driver is a generic driver type to be used throughout the API. For now, a // driver is simply a name and set of options. The field contents depend on the @@ -1280,7 +1425,7 @@ type Driver struct { func (m *Driver) Reset() { *m = Driver{} } func (*Driver) ProtoMessage() {} -func (*Driver) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{23} } +func (*Driver) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{26} } type IPAMOptions struct { Driver *Driver `protobuf:"bytes,1,opt,name=driver" json:"driver,omitempty"` @@ -1289,7 +1434,7 @@ type IPAMOptions struct { func (m *IPAMOptions) Reset() { *m = IPAMOptions{} } func (*IPAMOptions) ProtoMessage() {} -func (*IPAMOptions) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{24} } +func (*IPAMOptions) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{27} } // Peer should be used anywhere where we are describing a remote peer. type Peer struct { @@ -1299,7 +1444,7 @@ type Peer struct { func (m *Peer) Reset() { *m = Peer{} } func (*Peer) ProtoMessage() {} -func (*Peer) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{25} } +func (*Peer) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{28} } // WeightedPeer should be used anywhere where we are describing a remote peer // with a weight. @@ -1310,7 +1455,7 @@ type WeightedPeer struct { func (m *WeightedPeer) Reset() { *m = WeightedPeer{} } func (*WeightedPeer) ProtoMessage() {} -func (*WeightedPeer) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{26} } +func (*WeightedPeer) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{29} } type IssuanceStatus struct { State IssuanceStatus_State `protobuf:"varint,1,opt,name=state,proto3,enum=docker.swarmkit.v1.IssuanceStatus_State" json:"state,omitempty"` @@ -1322,7 +1467,7 @@ type IssuanceStatus struct { func (m *IssuanceStatus) Reset() { *m = IssuanceStatus{} } func (*IssuanceStatus) ProtoMessage() {} -func (*IssuanceStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{27} } +func (*IssuanceStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{30} } type AcceptancePolicy struct { Policies []*AcceptancePolicy_RoleAdmissionPolicy `protobuf:"bytes,1,rep,name=policies" json:"policies,omitempty"` @@ -1330,7 +1475,7 @@ type AcceptancePolicy struct { func (m *AcceptancePolicy) Reset() { *m = AcceptancePolicy{} } func (*AcceptancePolicy) ProtoMessage() {} -func (*AcceptancePolicy) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{28} } +func (*AcceptancePolicy) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{31} } type AcceptancePolicy_RoleAdmissionPolicy struct { Role NodeRole `protobuf:"varint,1,opt,name=role,proto3,enum=docker.swarmkit.v1.NodeRole" json:"role,omitempty"` @@ -1345,7 +1490,7 @@ type AcceptancePolicy_RoleAdmissionPolicy struct { func (m *AcceptancePolicy_RoleAdmissionPolicy) Reset() { *m = AcceptancePolicy_RoleAdmissionPolicy{} } func (*AcceptancePolicy_RoleAdmissionPolicy) ProtoMessage() {} func (*AcceptancePolicy_RoleAdmissionPolicy) Descriptor() ([]byte, []int) { - return fileDescriptorTypes, []int{28, 0} + return fileDescriptorTypes, []int{31, 0} } type AcceptancePolicy_RoleAdmissionPolicy_Secret struct { @@ -1360,7 +1505,7 @@ func (m *AcceptancePolicy_RoleAdmissionPolicy_Secret) Reset() { } func (*AcceptancePolicy_RoleAdmissionPolicy_Secret) ProtoMessage() {} func (*AcceptancePolicy_RoleAdmissionPolicy_Secret) Descriptor() ([]byte, []int) { - return fileDescriptorTypes, []int{28, 0, 0} + return fileDescriptorTypes, []int{31, 0, 0} } type ExternalCA struct { @@ -1377,7 +1522,7 @@ type ExternalCA struct { func (m *ExternalCA) Reset() { *m = ExternalCA{} } func (*ExternalCA) ProtoMessage() {} -func (*ExternalCA) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{29} } +func (*ExternalCA) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{32} } type CAConfig struct { // NodeCertExpiry is the duration certificates should be issued for @@ -1402,7 +1547,7 @@ type CAConfig struct { func (m *CAConfig) Reset() { *m = CAConfig{} } func (*CAConfig) ProtoMessage() {} -func (*CAConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{30} } +func (*CAConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{33} } // OrchestrationConfig defines cluster-level orchestration settings. type OrchestrationConfig struct { @@ -1413,7 +1558,7 @@ type OrchestrationConfig struct { func (m *OrchestrationConfig) Reset() { *m = OrchestrationConfig{} } func (*OrchestrationConfig) ProtoMessage() {} -func (*OrchestrationConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{31} } +func (*OrchestrationConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{34} } // TaskDefaults specifies default values for task creation. type TaskDefaults struct { @@ -1427,7 +1572,7 @@ type TaskDefaults struct { func (m *TaskDefaults) Reset() { *m = TaskDefaults{} } func (*TaskDefaults) ProtoMessage() {} -func (*TaskDefaults) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{32} } +func (*TaskDefaults) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{35} } // DispatcherConfig defines cluster-level dispatcher settings. type DispatcherConfig struct { @@ -1439,7 +1584,7 @@ type DispatcherConfig struct { func (m *DispatcherConfig) Reset() { *m = DispatcherConfig{} } func (*DispatcherConfig) ProtoMessage() {} -func (*DispatcherConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{33} } +func (*DispatcherConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{36} } // RaftConfig defines raft settings for the cluster. type RaftConfig struct { @@ -1461,7 +1606,7 @@ type RaftConfig struct { func (m *RaftConfig) Reset() { *m = RaftConfig{} } func (*RaftConfig) ProtoMessage() {} -func (*RaftConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{34} } +func (*RaftConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{37} } type EncryptionConfig struct { // AutoLockManagers specifies whether or not managers TLS keys and raft data @@ -1472,7 +1617,7 @@ type EncryptionConfig struct { func (m *EncryptionConfig) Reset() { *m = EncryptionConfig{} } func (*EncryptionConfig) ProtoMessage() {} -func (*EncryptionConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{35} } +func (*EncryptionConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{38} } type SpreadOver struct { SpreadDescriptor string `protobuf:"bytes,1,opt,name=spread_descriptor,json=spreadDescriptor,proto3" json:"spread_descriptor,omitempty"` @@ -1480,7 +1625,7 @@ type SpreadOver struct { func (m *SpreadOver) Reset() { *m = SpreadOver{} } func (*SpreadOver) ProtoMessage() {} -func (*SpreadOver) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{36} } +func (*SpreadOver) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{39} } type PlacementPreference struct { // Types that are valid to be assigned to Preference: @@ -1490,7 +1635,7 @@ type PlacementPreference struct { func (m *PlacementPreference) Reset() { *m = PlacementPreference{} } func (*PlacementPreference) ProtoMessage() {} -func (*PlacementPreference) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{37} } +func (*PlacementPreference) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{40} } type isPlacementPreference_Preference interface { isPlacementPreference_Preference() @@ -1589,7 +1734,7 @@ type Placement struct { func (m *Placement) Reset() { *m = Placement{} } func (*Placement) ProtoMessage() {} -func (*Placement) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{38} } +func (*Placement) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{41} } // JoinToken contains the join tokens for workers and managers. type JoinTokens struct { @@ -1601,7 +1746,7 @@ type JoinTokens struct { func (m *JoinTokens) Reset() { *m = JoinTokens{} } func (*JoinTokens) ProtoMessage() {} -func (*JoinTokens) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{39} } +func (*JoinTokens) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{42} } type RootCA struct { // CAKey is the root CA private key. @@ -1622,7 +1767,7 @@ type RootCA struct { func (m *RootCA) Reset() { *m = RootCA{} } func (*RootCA) ProtoMessage() {} -func (*RootCA) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{40} } +func (*RootCA) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{43} } type Certificate struct { Role NodeRole `protobuf:"varint,1,opt,name=role,proto3,enum=docker.swarmkit.v1.NodeRole" json:"role,omitempty"` @@ -1635,7 +1780,7 @@ type Certificate struct { func (m *Certificate) Reset() { *m = Certificate{} } func (*Certificate) ProtoMessage() {} -func (*Certificate) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{41} } +func (*Certificate) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{44} } // Symmetric keys to encrypt inter-agent communication. type EncryptionKey struct { @@ -1651,7 +1796,7 @@ type EncryptionKey struct { func (m *EncryptionKey) Reset() { *m = EncryptionKey{} } func (*EncryptionKey) ProtoMessage() {} -func (*EncryptionKey) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{42} } +func (*EncryptionKey) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{45} } // ManagerStatus provides informations about the state of a manager in the cluster. type ManagerStatus struct { @@ -1668,7 +1813,7 @@ type ManagerStatus struct { func (m *ManagerStatus) Reset() { *m = ManagerStatus{} } func (*ManagerStatus) ProtoMessage() {} -func (*ManagerStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{43} } +func (*ManagerStatus) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{46} } // FileTarget represents a specific target that is backed by a file type FileTarget struct { @@ -1684,7 +1829,7 @@ type FileTarget struct { func (m *FileTarget) Reset() { *m = FileTarget{} } func (*FileTarget) ProtoMessage() {} -func (*FileTarget) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{44} } +func (*FileTarget) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{47} } // SecretReference is the linkage between a service and a secret that it uses. type SecretReference struct { @@ -1704,7 +1849,7 @@ type SecretReference struct { func (m *SecretReference) Reset() { *m = SecretReference{} } func (*SecretReference) ProtoMessage() {} -func (*SecretReference) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{45} } +func (*SecretReference) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{48} } type isSecretReference_Target interface { isSecretReference_Target() @@ -1804,7 +1949,7 @@ type ConfigReference struct { func (m *ConfigReference) Reset() { *m = ConfigReference{} } func (*ConfigReference) ProtoMessage() {} -func (*ConfigReference) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{46} } +func (*ConfigReference) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{49} } type isConfigReference_Target interface { isConfigReference_Target() @@ -1898,7 +2043,7 @@ type BlacklistedCertificate struct { func (m *BlacklistedCertificate) Reset() { *m = BlacklistedCertificate{} } func (*BlacklistedCertificate) ProtoMessage() {} -func (*BlacklistedCertificate) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{47} } +func (*BlacklistedCertificate) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{50} } // HealthConfig holds configuration settings for the HEALTHCHECK feature. type HealthConfig struct { @@ -1928,7 +2073,7 @@ type HealthConfig struct { func (m *HealthConfig) Reset() { *m = HealthConfig{} } func (*HealthConfig) ProtoMessage() {} -func (*HealthConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{48} } +func (*HealthConfig) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{51} } type MaybeEncryptedRecord struct { Algorithm MaybeEncryptedRecord_Algorithm `protobuf:"varint,1,opt,name=algorithm,proto3,enum=docker.swarmkit.v1.MaybeEncryptedRecord_Algorithm" json:"algorithm,omitempty"` @@ -1938,7 +2083,7 @@ type MaybeEncryptedRecord struct { func (m *MaybeEncryptedRecord) Reset() { *m = MaybeEncryptedRecord{} } func (*MaybeEncryptedRecord) ProtoMessage() {} -func (*MaybeEncryptedRecord) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{49} } +func (*MaybeEncryptedRecord) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{52} } type RootRotation struct { CACert []byte `protobuf:"bytes,1,opt,name=ca_cert,json=caCert,proto3" json:"ca_cert,omitempty"` @@ -1949,7 +2094,7 @@ type RootRotation struct { func (m *RootRotation) Reset() { *m = RootRotation{} } func (*RootRotation) ProtoMessage() {} -func (*RootRotation) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{50} } +func (*RootRotation) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{53} } // Privileges specifies security configuration/permissions. type Privileges struct { @@ -1959,7 +2104,7 @@ type Privileges struct { func (m *Privileges) Reset() { *m = Privileges{} } func (*Privileges) ProtoMessage() {} -func (*Privileges) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{51} } +func (*Privileges) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{54} } // CredentialSpec for managed service account (Windows only). type Privileges_CredentialSpec struct { @@ -1972,7 +2117,7 @@ type Privileges_CredentialSpec struct { func (m *Privileges_CredentialSpec) Reset() { *m = Privileges_CredentialSpec{} } func (*Privileges_CredentialSpec) ProtoMessage() {} func (*Privileges_CredentialSpec) Descriptor() ([]byte, []int) { - return fileDescriptorTypes, []int{51, 0} + return fileDescriptorTypes, []int{54, 0} } type isPrivileges_CredentialSpec_Source interface { @@ -2090,13 +2235,16 @@ type Privileges_SELinuxContext struct { func (m *Privileges_SELinuxContext) Reset() { *m = Privileges_SELinuxContext{} } func (*Privileges_SELinuxContext) ProtoMessage() {} func (*Privileges_SELinuxContext) Descriptor() ([]byte, []int) { - return fileDescriptorTypes, []int{51, 1} + return fileDescriptorTypes, []int{54, 1} } func init() { proto.RegisterType((*Version)(nil), "docker.swarmkit.v1.Version") proto.RegisterType((*IndexEntry)(nil), "docker.swarmkit.v1.IndexEntry") proto.RegisterType((*Annotations)(nil), "docker.swarmkit.v1.Annotations") + proto.RegisterType((*GenericString)(nil), "docker.swarmkit.v1.GenericString") + proto.RegisterType((*GenericDiscrete)(nil), "docker.swarmkit.v1.GenericDiscrete") + proto.RegisterType((*GenericResource)(nil), "docker.swarmkit.v1.GenericResource") proto.RegisterType((*Resources)(nil), "docker.swarmkit.v1.Resources") proto.RegisterType((*ResourceRequirements)(nil), "docker.swarmkit.v1.ResourceRequirements") proto.RegisterType((*Platform)(nil), "docker.swarmkit.v1.Platform") @@ -2231,6 +2379,68 @@ func (m *Annotations) CopyFrom(src interface{}) { } +func (m *GenericString) Copy() *GenericString { + if m == nil { + return nil + } + o := &GenericString{} + o.CopyFrom(m) + return o +} + +func (m *GenericString) CopyFrom(src interface{}) { + + o := src.(*GenericString) + *m = *o +} + +func (m *GenericDiscrete) Copy() *GenericDiscrete { + if m == nil { + return nil + } + o := &GenericDiscrete{} + o.CopyFrom(m) + return o +} + +func (m *GenericDiscrete) CopyFrom(src interface{}) { + + o := src.(*GenericDiscrete) + *m = *o +} + +func (m *GenericResource) Copy() *GenericResource { + if m == nil { + return nil + } + o := &GenericResource{} + o.CopyFrom(m) + return o +} + +func (m *GenericResource) CopyFrom(src interface{}) { + + o := src.(*GenericResource) + *m = *o + if o.Resource != nil { + switch o.Resource.(type) { + case *GenericResource_Str: + v := GenericResource_Str{ + Str: &GenericString{}, + } + github_com_docker_swarmkit_api_deepcopy.Copy(v.Str, o.GetStr()) + m.Resource = &v + case *GenericResource_Discrete: + v := GenericResource_Discrete{ + Discrete: &GenericDiscrete{}, + } + github_com_docker_swarmkit_api_deepcopy.Copy(v.Discrete, o.GetDiscrete()) + m.Resource = &v + } + } + +} + func (m *Resources) Copy() *Resources { if m == nil { return nil @@ -2244,6 +2454,14 @@ func (m *Resources) CopyFrom(src interface{}) { o := src.(*Resources) *m = *o + if o.Generic != nil { + m.Generic = make([]*GenericResource, len(o.Generic)) + for i := range m.Generic { + m.Generic[i] = &GenericResource{} + github_com_docker_swarmkit_api_deepcopy.Copy(m.Generic[i], o.Generic[i]) + } + } + } func (m *ResourceRequirements) Copy() *ResourceRequirements { @@ -3544,6 +3762,118 @@ func (m *Annotations) MarshalTo(dAtA []byte) (int, error) { return i, nil } +func (m *GenericString) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *GenericString) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Kind) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintTypes(dAtA, i, uint64(len(m.Kind))) + i += copy(dAtA[i:], m.Kind) + } + if len(m.Value) > 0 { + dAtA[i] = 0x12 + i++ + i = encodeVarintTypes(dAtA, i, uint64(len(m.Value))) + i += copy(dAtA[i:], m.Value) + } + return i, nil +} + +func (m *GenericDiscrete) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *GenericDiscrete) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Kind) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintTypes(dAtA, i, uint64(len(m.Kind))) + i += copy(dAtA[i:], m.Kind) + } + if m.Value != 0 { + dAtA[i] = 0x10 + i++ + i = encodeVarintTypes(dAtA, i, uint64(m.Value)) + } + return i, nil +} + +func (m *GenericResource) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *GenericResource) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Resource != nil { + nn1, err := m.Resource.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += nn1 + } + return i, nil +} + +func (m *GenericResource_Str) MarshalTo(dAtA []byte) (int, error) { + i := 0 + if m.Str != nil { + dAtA[i] = 0xa + i++ + i = encodeVarintTypes(dAtA, i, uint64(m.Str.Size())) + n2, err := m.Str.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n2 + } + return i, nil +} +func (m *GenericResource_Discrete) MarshalTo(dAtA []byte) (int, error) { + i := 0 + if m.Discrete != nil { + dAtA[i] = 0x12 + i++ + i = encodeVarintTypes(dAtA, i, uint64(m.Discrete.Size())) + n3, err := m.Discrete.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n3 + } + return i, nil +} func (m *Resources) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -3569,6 +3899,18 @@ func (m *Resources) MarshalTo(dAtA []byte) (int, error) { i++ i = encodeVarintTypes(dAtA, i, uint64(m.MemoryBytes)) } + if len(m.Generic) > 0 { + for _, msg := range m.Generic { + dAtA[i] = 0x1a + i++ + i = encodeVarintTypes(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } + } return i, nil } @@ -3591,21 +3933,21 @@ func (m *ResourceRequirements) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintTypes(dAtA, i, uint64(m.Limits.Size())) - n1, err := m.Limits.MarshalTo(dAtA[i:]) + n4, err := m.Limits.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n1 + i += n4 } if m.Reservations != nil { dAtA[i] = 0x12 i++ i = encodeVarintTypes(dAtA, i, uint64(m.Reservations.Size())) - n2, err := m.Reservations.MarshalTo(dAtA[i:]) + n5, err := m.Reservations.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n2 + i += n5 } return i, nil } @@ -3748,41 +4090,41 @@ func (m *NodeDescription) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x12 i++ i = encodeVarintTypes(dAtA, i, uint64(m.Platform.Size())) - n3, err := m.Platform.MarshalTo(dAtA[i:]) + n6, err := m.Platform.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n3 + i += n6 } if m.Resources != nil { dAtA[i] = 0x1a i++ i = encodeVarintTypes(dAtA, i, uint64(m.Resources.Size())) - n4, err := m.Resources.MarshalTo(dAtA[i:]) + n7, err := m.Resources.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n4 + i += n7 } if m.Engine != nil { dAtA[i] = 0x22 i++ i = encodeVarintTypes(dAtA, i, uint64(m.Engine.Size())) - n5, err := m.Engine.MarshalTo(dAtA[i:]) + n8, err := m.Engine.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n5 + i += n8 } if m.TLSInfo != nil { dAtA[i] = 0x2a i++ i = encodeVarintTypes(dAtA, i, uint64(m.TLSInfo.Size())) - n6, err := m.TLSInfo.MarshalTo(dAtA[i:]) + n9, err := m.TLSInfo.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n6 + i += n9 } return i, nil } @@ -3967,31 +4309,31 @@ func (m *Mount) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x2a i++ i = encodeVarintTypes(dAtA, i, uint64(m.BindOptions.Size())) - n7, err := m.BindOptions.MarshalTo(dAtA[i:]) + n10, err := m.BindOptions.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n7 + i += n10 } if m.VolumeOptions != nil { dAtA[i] = 0x32 i++ i = encodeVarintTypes(dAtA, i, uint64(m.VolumeOptions.Size())) - n8, err := m.VolumeOptions.MarshalTo(dAtA[i:]) + n11, err := m.VolumeOptions.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n8 + i += n11 } if m.TmpfsOptions != nil { dAtA[i] = 0x3a i++ i = encodeVarintTypes(dAtA, i, uint64(m.TmpfsOptions.Size())) - n9, err := m.TmpfsOptions.MarshalTo(dAtA[i:]) + n12, err := m.TmpfsOptions.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n9 + i += n12 } return i, nil } @@ -4065,11 +4407,11 @@ func (m *Mount_VolumeOptions) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x1a i++ i = encodeVarintTypes(dAtA, i, uint64(m.DriverConfig.Size())) - n10, err := m.DriverConfig.MarshalTo(dAtA[i:]) + n13, err := m.DriverConfig.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n10 + i += n13 } return i, nil } @@ -4126,11 +4468,11 @@ func (m *RestartPolicy) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x12 i++ i = encodeVarintTypes(dAtA, i, uint64(m.Delay.Size())) - n11, err := m.Delay.MarshalTo(dAtA[i:]) + n14, err := m.Delay.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n11 + i += n14 } if m.MaxAttempts != 0 { dAtA[i] = 0x18 @@ -4141,11 +4483,11 @@ func (m *RestartPolicy) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x22 i++ i = encodeVarintTypes(dAtA, i, uint64(m.Window.Size())) - n12, err := m.Window.MarshalTo(dAtA[i:]) + n15, err := m.Window.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n12 + i += n15 } return i, nil } @@ -4173,11 +4515,11 @@ func (m *UpdateConfig) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x12 i++ i = encodeVarintTypes(dAtA, i, uint64(github_com_gogo_protobuf_types.SizeOfStdDuration(m.Delay))) - n13, err := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.Delay, dAtA[i:]) + n16, err := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.Delay, dAtA[i:]) if err != nil { return 0, err } - i += n13 + i += n16 if m.FailureAction != 0 { dAtA[i] = 0x18 i++ @@ -4187,11 +4529,11 @@ func (m *UpdateConfig) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x22 i++ i = encodeVarintTypes(dAtA, i, uint64(m.Monitor.Size())) - n14, err := m.Monitor.MarshalTo(dAtA[i:]) + n17, err := m.Monitor.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n14 + i += n17 } if m.MaxFailureRatio != 0 { dAtA[i] = 0x2d @@ -4230,21 +4572,21 @@ func (m *UpdateStatus) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x12 i++ i = encodeVarintTypes(dAtA, i, uint64(m.StartedAt.Size())) - n15, err := m.StartedAt.MarshalTo(dAtA[i:]) + n18, err := m.StartedAt.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n15 + i += n18 } if m.CompletedAt != nil { dAtA[i] = 0x1a i++ i = encodeVarintTypes(dAtA, i, uint64(m.CompletedAt.Size())) - n16, err := m.CompletedAt.MarshalTo(dAtA[i:]) + n19, err := m.CompletedAt.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n16 + i += n19 } if len(m.Message) > 0 { dAtA[i] = 0x22 @@ -4338,11 +4680,11 @@ func (m *TaskStatus) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintTypes(dAtA, i, uint64(m.Timestamp.Size())) - n17, err := m.Timestamp.MarshalTo(dAtA[i:]) + n20, err := m.Timestamp.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n17 + i += n20 } if m.State != 0 { dAtA[i] = 0x10 @@ -4362,21 +4704,21 @@ func (m *TaskStatus) MarshalTo(dAtA []byte) (int, error) { i += copy(dAtA[i:], m.Err) } if m.RuntimeStatus != nil { - nn18, err := m.RuntimeStatus.MarshalTo(dAtA[i:]) + nn21, err := m.RuntimeStatus.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += nn18 + i += nn21 } if m.PortStatus != nil { dAtA[i] = 0x32 i++ i = encodeVarintTypes(dAtA, i, uint64(m.PortStatus.Size())) - n19, err := m.PortStatus.MarshalTo(dAtA[i:]) + n22, err := m.PortStatus.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n19 + i += n22 } return i, nil } @@ -4387,11 +4729,11 @@ func (m *TaskStatus_Container) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x2a i++ i = encodeVarintTypes(dAtA, i, uint64(m.Container.Size())) - n20, err := m.Container.MarshalTo(dAtA[i:]) + n23, err := m.Container.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n20 + i += n23 } return i, nil } @@ -4628,11 +4970,11 @@ func (m *IPAMOptions) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintTypes(dAtA, i, uint64(m.Driver.Size())) - n21, err := m.Driver.MarshalTo(dAtA[i:]) + n24, err := m.Driver.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n21 + i += n24 } if len(m.Configs) > 0 { for _, msg := range m.Configs { @@ -4698,11 +5040,11 @@ func (m *WeightedPeer) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintTypes(dAtA, i, uint64(m.Peer.Size())) - n22, err := m.Peer.MarshalTo(dAtA[i:]) + n25, err := m.Peer.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n22 + i += n25 } if m.Weight != 0 { dAtA[i] = 0x10 @@ -4805,11 +5147,11 @@ func (m *AcceptancePolicy_RoleAdmissionPolicy) MarshalTo(dAtA []byte) (int, erro dAtA[i] = 0x1a i++ i = encodeVarintTypes(dAtA, i, uint64(m.Secret.Size())) - n23, err := m.Secret.MarshalTo(dAtA[i:]) + n26, err := m.Secret.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n23 + i += n26 } return i, nil } @@ -4915,11 +5257,11 @@ func (m *CAConfig) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintTypes(dAtA, i, uint64(m.NodeCertExpiry.Size())) - n24, err := m.NodeCertExpiry.MarshalTo(dAtA[i:]) + n27, err := m.NodeCertExpiry.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n24 + i += n27 } if len(m.ExternalCAs) > 0 { for _, msg := range m.ExternalCAs { @@ -4995,11 +5337,11 @@ func (m *TaskDefaults) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintTypes(dAtA, i, uint64(m.LogDriver.Size())) - n25, err := m.LogDriver.MarshalTo(dAtA[i:]) + n28, err := m.LogDriver.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n25 + i += n28 } return i, nil } @@ -5023,11 +5365,11 @@ func (m *DispatcherConfig) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintTypes(dAtA, i, uint64(m.HeartbeatPeriod.Size())) - n26, err := m.HeartbeatPeriod.MarshalTo(dAtA[i:]) + n29, err := m.HeartbeatPeriod.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n26 + i += n29 } return i, nil } @@ -5143,11 +5485,11 @@ func (m *PlacementPreference) MarshalTo(dAtA []byte) (int, error) { var l int _ = l if m.Preference != nil { - nn27, err := m.Preference.MarshalTo(dAtA[i:]) + nn30, err := m.Preference.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += nn27 + i += nn30 } return i, nil } @@ -5158,11 +5500,11 @@ func (m *PlacementPreference_Spread) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintTypes(dAtA, i, uint64(m.Spread.Size())) - n28, err := m.Spread.MarshalTo(dAtA[i:]) + n31, err := m.Spread.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n28 + i += n31 } return i, nil } @@ -5289,20 +5631,20 @@ func (m *RootCA) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x22 i++ i = encodeVarintTypes(dAtA, i, uint64(m.JoinTokens.Size())) - n29, err := m.JoinTokens.MarshalTo(dAtA[i:]) + n32, err := m.JoinTokens.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n29 + i += n32 if m.RootRotation != nil { dAtA[i] = 0x2a i++ i = encodeVarintTypes(dAtA, i, uint64(m.RootRotation.Size())) - n30, err := m.RootRotation.MarshalTo(dAtA[i:]) + n33, err := m.RootRotation.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n30 + i += n33 } if m.LastForcedRotation != 0 { dAtA[i] = 0x30 @@ -5341,11 +5683,11 @@ func (m *Certificate) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x1a i++ i = encodeVarintTypes(dAtA, i, uint64(m.Status.Size())) - n31, err := m.Status.MarshalTo(dAtA[i:]) + n34, err := m.Status.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n31 + i += n34 if len(m.Certificate) > 0 { dAtA[i] = 0x22 i++ @@ -5514,11 +5856,11 @@ func (m *SecretReference) MarshalTo(dAtA []byte) (int, error) { i += copy(dAtA[i:], m.SecretName) } if m.Target != nil { - nn32, err := m.Target.MarshalTo(dAtA[i:]) + nn35, err := m.Target.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += nn32 + i += nn35 } return i, nil } @@ -5529,11 +5871,11 @@ func (m *SecretReference_File) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x1a i++ i = encodeVarintTypes(dAtA, i, uint64(m.File.Size())) - n33, err := m.File.MarshalTo(dAtA[i:]) + n36, err := m.File.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n33 + i += n36 } return i, nil } @@ -5565,11 +5907,11 @@ func (m *ConfigReference) MarshalTo(dAtA []byte) (int, error) { i += copy(dAtA[i:], m.ConfigName) } if m.Target != nil { - nn34, err := m.Target.MarshalTo(dAtA[i:]) + nn37, err := m.Target.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += nn34 + i += nn37 } return i, nil } @@ -5580,11 +5922,11 @@ func (m *ConfigReference_File) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x1a i++ i = encodeVarintTypes(dAtA, i, uint64(m.File.Size())) - n35, err := m.File.MarshalTo(dAtA[i:]) + n38, err := m.File.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n35 + i += n38 } return i, nil } @@ -5607,11 +5949,11 @@ func (m *BlacklistedCertificate) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintTypes(dAtA, i, uint64(m.Expiry.Size())) - n36, err := m.Expiry.MarshalTo(dAtA[i:]) + n39, err := m.Expiry.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n36 + i += n39 } return i, nil } @@ -5650,21 +5992,21 @@ func (m *HealthConfig) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x12 i++ i = encodeVarintTypes(dAtA, i, uint64(m.Interval.Size())) - n37, err := m.Interval.MarshalTo(dAtA[i:]) + n40, err := m.Interval.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n37 + i += n40 } if m.Timeout != nil { dAtA[i] = 0x1a i++ i = encodeVarintTypes(dAtA, i, uint64(m.Timeout.Size())) - n38, err := m.Timeout.MarshalTo(dAtA[i:]) + n41, err := m.Timeout.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n38 + i += n41 } if m.Retries != 0 { dAtA[i] = 0x20 @@ -5675,11 +6017,11 @@ func (m *HealthConfig) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x2a i++ i = encodeVarintTypes(dAtA, i, uint64(m.StartPeriod.Size())) - n39, err := m.StartPeriod.MarshalTo(dAtA[i:]) + n42, err := m.StartPeriod.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n39 + i += n42 } return i, nil } @@ -5774,21 +6116,21 @@ func (m *Privileges) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintTypes(dAtA, i, uint64(m.CredentialSpec.Size())) - n40, err := m.CredentialSpec.MarshalTo(dAtA[i:]) + n43, err := m.CredentialSpec.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n40 + i += n43 } if m.SELinuxContext != nil { dAtA[i] = 0x12 i++ i = encodeVarintTypes(dAtA, i, uint64(m.SELinuxContext.Size())) - n41, err := m.SELinuxContext.MarshalTo(dAtA[i:]) + n44, err := m.SELinuxContext.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n41 + i += n44 } return i, nil } @@ -5809,11 +6151,11 @@ func (m *Privileges_CredentialSpec) MarshalTo(dAtA []byte) (int, error) { var l int _ = l if m.Source != nil { - nn42, err := m.Source.MarshalTo(dAtA[i:]) + nn45, err := m.Source.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += nn42 + i += nn45 } return i, nil } @@ -5961,6 +6303,60 @@ func (m *Annotations) Size() (n int) { return n } +func (m *GenericString) Size() (n int) { + var l int + _ = l + l = len(m.Kind) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + l = len(m.Value) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + return n +} + +func (m *GenericDiscrete) Size() (n int) { + var l int + _ = l + l = len(m.Kind) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + if m.Value != 0 { + n += 1 + sovTypes(uint64(m.Value)) + } + return n +} + +func (m *GenericResource) Size() (n int) { + var l int + _ = l + if m.Resource != nil { + n += m.Resource.Size() + } + return n +} + +func (m *GenericResource_Str) Size() (n int) { + var l int + _ = l + if m.Str != nil { + l = m.Str.Size() + n += 1 + l + sovTypes(uint64(l)) + } + return n +} +func (m *GenericResource_Discrete) Size() (n int) { + var l int + _ = l + if m.Discrete != nil { + l = m.Discrete.Size() + n += 1 + l + sovTypes(uint64(l)) + } + return n +} func (m *Resources) Size() (n int) { var l int _ = l @@ -5970,6 +6366,12 @@ func (m *Resources) Size() (n int) { if m.MemoryBytes != 0 { n += 1 + sovTypes(uint64(m.MemoryBytes)) } + if len(m.Generic) > 0 { + for _, e := range m.Generic { + l = e.Size() + n += 1 + l + sovTypes(uint64(l)) + } + } return n } @@ -7056,6 +7458,58 @@ func (this *Annotations) String() string { }, "") return s } +func (this *GenericString) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&GenericString{`, + `Kind:` + fmt.Sprintf("%v", this.Kind) + `,`, + `Value:` + fmt.Sprintf("%v", this.Value) + `,`, + `}`, + }, "") + return s +} +func (this *GenericDiscrete) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&GenericDiscrete{`, + `Kind:` + fmt.Sprintf("%v", this.Kind) + `,`, + `Value:` + fmt.Sprintf("%v", this.Value) + `,`, + `}`, + }, "") + return s +} +func (this *GenericResource) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&GenericResource{`, + `Resource:` + fmt.Sprintf("%v", this.Resource) + `,`, + `}`, + }, "") + return s +} +func (this *GenericResource_Str) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&GenericResource_Str{`, + `Str:` + strings.Replace(fmt.Sprintf("%v", this.Str), "GenericString", "GenericString", 1) + `,`, + `}`, + }, "") + return s +} +func (this *GenericResource_Discrete) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&GenericResource_Discrete{`, + `Discrete:` + strings.Replace(fmt.Sprintf("%v", this.Discrete), "GenericDiscrete", "GenericDiscrete", 1) + `,`, + `}`, + }, "") + return s +} func (this *Resources) String() string { if this == nil { return "nil" @@ -7063,6 +7517,7 @@ func (this *Resources) String() string { s := strings.Join([]string{`&Resources{`, `NanoCPUs:` + fmt.Sprintf("%v", this.NanoCPUs) + `,`, `MemoryBytes:` + fmt.Sprintf("%v", this.MemoryBytes) + `,`, + `Generic:` + strings.Replace(fmt.Sprintf("%v", this.Generic), "GenericResource", "GenericResource", 1) + `,`, `}`, }, "") return s @@ -8258,6 +8713,326 @@ func (m *Annotations) Unmarshal(dAtA []byte) error { } return nil } +func (m *GenericString) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GenericString: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GenericString: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Kind", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Kind = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Value = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *GenericDiscrete) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GenericDiscrete: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GenericDiscrete: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Kind", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Kind = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) + } + m.Value = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Value |= (int64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *GenericResource) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GenericResource: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GenericResource: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Str", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &GenericString{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Resource = &GenericResource_Str{v} + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Discrete", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &GenericDiscrete{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Resource = &GenericResource_Discrete{v} + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *Resources) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -8325,6 +9100,37 @@ func (m *Resources) Unmarshal(dAtA []byte) error { break } } + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Generic", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Generic = append(m.Generic, &GenericResource{}) + if err := m.Generic[len(m.Generic)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipTypes(dAtA[iNdEx:]) @@ -16245,300 +17051,306 @@ var ( func init() { proto.RegisterFile("types.proto", fileDescriptorTypes) } var fileDescriptorTypes = []byte{ - // 4705 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x7a, 0x4d, 0x6c, 0x24, 0xd7, - 0x56, 0xbf, 0xfb, 0xd3, 0xdd, 0xa7, 0xdb, 0x76, 0xf9, 0x8e, 0x33, 0xf1, 0x74, 0x26, 0x76, 0xa7, - 0x92, 0x79, 0xf9, 0x78, 0xf9, 0x77, 0x66, 0x3c, 0x49, 0x34, 0x49, 0xfe, 0x2f, 0x49, 0x7f, 0x79, - 0xdc, 0x6f, 0xec, 0xee, 0xd6, 0xed, 0xf6, 0xcc, 0xcb, 0x02, 0x4a, 0xe5, 0xaa, 0xeb, 0x76, 0xc5, - 0xd5, 0x75, 0x9b, 0xaa, 0x6a, 0x7b, 0x9a, 0x07, 0x62, 0xc4, 0x02, 0x90, 0x57, 0xb0, 0x43, 0x42, - 0x66, 0x03, 0x2b, 0x84, 0xc4, 0x02, 0x24, 0x04, 0x1b, 0x82, 0xc4, 0x22, 0x3b, 0x1e, 0x20, 0xa1, - 0x27, 0x90, 0x0c, 0xf1, 0x82, 0x1d, 0x82, 0xcd, 0x13, 0x1b, 0x90, 0xd0, 0xfd, 0xa8, 0xea, 0x6a, - 0x4f, 0xd9, 0x9e, 0x90, 0xb7, 0xb1, 0xeb, 0x9e, 0xf3, 0x3b, 0xe7, 0xde, 0x7b, 0xee, 0xb9, 0xe7, - 0x9e, 0x73, 0x6f, 0x43, 0xc1, 0x9f, 0x8c, 0x88, 0x57, 0x19, 0xb9, 0xd4, 0xa7, 0x08, 0x99, 0xd4, - 0x38, 0x24, 0x6e, 0xc5, 0x3b, 0xd6, 0xdd, 0xe1, 0xa1, 0xe5, 0x57, 0x8e, 0xee, 0x95, 0xd6, 0x07, - 0x94, 0x0e, 0x6c, 0xf2, 0x1e, 0x47, 0xec, 0x8d, 0xf7, 0xdf, 0xf3, 0xad, 0x21, 0xf1, 0x7c, 0x7d, - 0x38, 0x12, 0x42, 0xa5, 0xb5, 0x8b, 0x00, 0x73, 0xec, 0xea, 0xbe, 0x45, 0x1d, 0xc9, 0x5f, 0x19, - 0xd0, 0x01, 0xe5, 0x9f, 0xef, 0xb1, 0x2f, 0x41, 0x55, 0xd7, 0x61, 0xfe, 0x31, 0x71, 0x3d, 0x8b, - 0x3a, 0x68, 0x05, 0x32, 0x96, 0x63, 0x92, 0xa7, 0xab, 0x89, 0x72, 0xe2, 0xad, 0x34, 0x16, 0x0d, - 0xf5, 0x2e, 0x40, 0x8b, 0x7d, 0x34, 0x1d, 0xdf, 0x9d, 0x20, 0x05, 0x52, 0x87, 0x64, 0xc2, 0x11, - 0x79, 0xcc, 0x3e, 0x19, 0xe5, 0x48, 0xb7, 0x57, 0x93, 0x82, 0x72, 0xa4, 0xdb, 0xea, 0x37, 0x09, - 0x28, 0x54, 0x1d, 0x87, 0xfa, 0xbc, 0x77, 0x0f, 0x21, 0x48, 0x3b, 0xfa, 0x90, 0x48, 0x21, 0xfe, - 0x8d, 0xea, 0x90, 0xb5, 0xf5, 0x3d, 0x62, 0x7b, 0xab, 0xc9, 0x72, 0xea, 0xad, 0xc2, 0xc6, 0xf7, - 0x2b, 0xcf, 0x4f, 0xb9, 0x12, 0x51, 0x52, 0xd9, 0xe6, 0x68, 0x3e, 0x08, 0x2c, 0x45, 0xd1, 0xa7, - 0x30, 0x6f, 0x39, 0xa6, 0x65, 0x10, 0x6f, 0x35, 0xcd, 0xb5, 0xac, 0xc5, 0x69, 0x99, 0x8e, 0xbe, - 0x96, 0xfe, 0xfa, 0x6c, 0x7d, 0x0e, 0x07, 0x42, 0xa5, 0x8f, 0xa0, 0x10, 0x51, 0x1b, 0x33, 0xb7, - 0x15, 0xc8, 0x1c, 0xe9, 0xf6, 0x98, 0xc8, 0xd9, 0x89, 0xc6, 0xc7, 0xc9, 0x07, 0x09, 0xf5, 0x0b, - 0xc8, 0x63, 0xe2, 0xd1, 0xb1, 0x6b, 0x10, 0x0f, 0xbd, 0x0d, 0x79, 0x47, 0x77, 0xa8, 0x66, 0x8c, - 0xc6, 0x1e, 0x17, 0x4f, 0xd5, 0x8a, 0xe7, 0x67, 0xeb, 0xb9, 0xb6, 0xee, 0xd0, 0x7a, 0x77, 0xd7, - 0xc3, 0x39, 0xc6, 0xae, 0x8f, 0xc6, 0x1e, 0x7a, 0x0d, 0x8a, 0x43, 0x32, 0xa4, 0xee, 0x44, 0xdb, - 0x9b, 0xf8, 0xc4, 0xe3, 0x8a, 0x53, 0xb8, 0x20, 0x68, 0x35, 0x46, 0x52, 0x7f, 0x3b, 0x01, 0x2b, - 0x81, 0x6e, 0x4c, 0x7e, 0x69, 0x6c, 0xb9, 0x64, 0x48, 0x1c, 0xdf, 0x43, 0x1f, 0x40, 0xd6, 0xb6, - 0x86, 0x96, 0x2f, 0xfa, 0x28, 0x6c, 0xbc, 0x1a, 0x37, 0xdb, 0x70, 0x54, 0x58, 0x82, 0x51, 0x15, - 0x8a, 0x2e, 0xf1, 0x88, 0x7b, 0x24, 0x2c, 0xc9, 0xbb, 0xbc, 0x56, 0x78, 0x46, 0x44, 0xdd, 0x84, - 0x5c, 0xd7, 0xd6, 0xfd, 0x7d, 0xea, 0x0e, 0x91, 0x0a, 0x45, 0xdd, 0x35, 0x0e, 0x2c, 0x9f, 0x18, - 0xfe, 0xd8, 0x0d, 0x56, 0x75, 0x86, 0x86, 0x6e, 0x42, 0x92, 0x8a, 0x8e, 0xf2, 0xb5, 0xec, 0xf9, - 0xd9, 0x7a, 0xb2, 0xd3, 0xc3, 0x49, 0xea, 0xa9, 0x9f, 0xc0, 0x72, 0xd7, 0x1e, 0x0f, 0x2c, 0xa7, - 0x41, 0x3c, 0xc3, 0xb5, 0x46, 0x4c, 0x3b, 0x73, 0x0f, 0xe6, 0xfb, 0x81, 0x7b, 0xb0, 0xef, 0xd0, - 0x65, 0x92, 0x53, 0x97, 0x51, 0x7f, 0x33, 0x09, 0xcb, 0x4d, 0x67, 0x60, 0x39, 0x24, 0x2a, 0x7d, - 0x07, 0x16, 0x09, 0x27, 0x6a, 0x47, 0xc2, 0x8d, 0xa5, 0x9e, 0x05, 0x41, 0x0d, 0x7c, 0xbb, 0x75, - 0xc1, 0xdf, 0xee, 0xc5, 0x4d, 0xff, 0x39, 0xed, 0xb1, 0x5e, 0xd7, 0x84, 0xf9, 0x11, 0x9f, 0x84, - 0xb7, 0x9a, 0xe2, 0xba, 0xee, 0xc4, 0xe9, 0x7a, 0x6e, 0x9e, 0x81, 0xf3, 0x49, 0xd9, 0xef, 0xe2, - 0x7c, 0x7f, 0x9c, 0x84, 0xa5, 0x36, 0x35, 0x67, 0xec, 0x50, 0x82, 0xdc, 0x01, 0xf5, 0xfc, 0xc8, - 0x46, 0x0b, 0xdb, 0xe8, 0x01, 0xe4, 0x46, 0x72, 0xf9, 0xe4, 0xea, 0xdf, 0x8e, 0x1f, 0xb2, 0xc0, - 0xe0, 0x10, 0x8d, 0x3e, 0x81, 0xbc, 0x1b, 0xf8, 0xc4, 0x6a, 0xea, 0x45, 0x1c, 0x67, 0x8a, 0x47, - 0x3f, 0x80, 0xac, 0x58, 0x84, 0xd5, 0x34, 0x97, 0xbc, 0xf3, 0x42, 0x36, 0xc7, 0x52, 0x08, 0x3d, - 0x84, 0x9c, 0x6f, 0x7b, 0x9a, 0xe5, 0xec, 0xd3, 0xd5, 0x0c, 0x57, 0xb0, 0x1e, 0xa7, 0x80, 0x19, - 0xa2, 0xbf, 0xdd, 0x6b, 0x39, 0xfb, 0xb4, 0x56, 0x38, 0x3f, 0x5b, 0x9f, 0x97, 0x0d, 0x3c, 0xef, - 0xdb, 0x1e, 0xfb, 0x50, 0x7f, 0x27, 0x01, 0x85, 0x08, 0x0a, 0xbd, 0x0a, 0xe0, 0xbb, 0x63, 0xcf, - 0xd7, 0x5c, 0x4a, 0x7d, 0x6e, 0xac, 0x22, 0xce, 0x73, 0x0a, 0xa6, 0xd4, 0x47, 0x15, 0xb8, 0x61, - 0x10, 0xd7, 0xd7, 0x2c, 0xcf, 0x1b, 0x13, 0x57, 0xf3, 0xc6, 0x7b, 0x5f, 0x12, 0xc3, 0xe7, 0x86, - 0x2b, 0xe2, 0x65, 0xc6, 0x6a, 0x71, 0x4e, 0x4f, 0x30, 0xd0, 0x7d, 0xb8, 0x19, 0xc5, 0x8f, 0xc6, - 0x7b, 0xb6, 0x65, 0x68, 0x6c, 0x31, 0x53, 0x5c, 0xe4, 0xc6, 0x54, 0xa4, 0xcb, 0x79, 0x8f, 0xc8, - 0x44, 0xfd, 0x69, 0x02, 0x14, 0xac, 0xef, 0xfb, 0x3b, 0x64, 0xb8, 0x47, 0xdc, 0x9e, 0xaf, 0xfb, - 0x63, 0x0f, 0xdd, 0x84, 0xac, 0x4d, 0x74, 0x93, 0xb8, 0x7c, 0x50, 0x39, 0x2c, 0x5b, 0x68, 0x97, - 0xed, 0x60, 0xdd, 0x38, 0xd0, 0xf7, 0x2c, 0xdb, 0xf2, 0x27, 0x7c, 0x28, 0x8b, 0xf1, 0x2e, 0x7c, - 0x51, 0x67, 0x05, 0x47, 0x04, 0xf1, 0x8c, 0x1a, 0xb4, 0x0a, 0xf3, 0x43, 0xe2, 0x79, 0xfa, 0x80, - 0xf0, 0x91, 0xe6, 0x71, 0xd0, 0x54, 0x3f, 0x81, 0x62, 0x54, 0x0e, 0x15, 0x60, 0x7e, 0xb7, 0xfd, - 0xa8, 0xdd, 0x79, 0xd2, 0x56, 0xe6, 0xd0, 0x12, 0x14, 0x76, 0xdb, 0xb8, 0x59, 0xad, 0x6f, 0x55, - 0x6b, 0xdb, 0x4d, 0x25, 0x81, 0x16, 0x20, 0x3f, 0x6d, 0x26, 0xd5, 0x3f, 0x4d, 0x00, 0x30, 0x73, - 0xcb, 0x49, 0x7d, 0x0c, 0x19, 0xcf, 0xd7, 0x7d, 0xe1, 0x95, 0x8b, 0x1b, 0x6f, 0x5c, 0xb6, 0x86, - 0x72, 0xbc, 0xec, 0x1f, 0xc1, 0x42, 0x24, 0x3a, 0xc2, 0xe4, 0xcc, 0x08, 0x59, 0x80, 0xd0, 0x4d, - 0xd3, 0x95, 0x03, 0xe7, 0xdf, 0xea, 0x27, 0x90, 0xe1, 0xd2, 0xb3, 0xc3, 0xcd, 0x41, 0xba, 0xc1, - 0xbe, 0x12, 0x28, 0x0f, 0x19, 0xdc, 0xac, 0x36, 0xbe, 0x50, 0x92, 0x48, 0x81, 0x62, 0xa3, 0xd5, - 0xab, 0x77, 0xda, 0xed, 0x66, 0xbd, 0xdf, 0x6c, 0x28, 0x29, 0xf5, 0x0e, 0x64, 0x5a, 0x43, 0xa6, - 0xf9, 0x36, 0x73, 0xf9, 0x7d, 0xe2, 0x12, 0xc7, 0x08, 0x76, 0xd2, 0x94, 0xa0, 0xfe, 0x24, 0x0f, - 0x99, 0x1d, 0x3a, 0x76, 0x7c, 0xb4, 0x11, 0x09, 0x5b, 0x8b, 0xf1, 0x27, 0x0f, 0x07, 0x56, 0xfa, - 0x93, 0x11, 0x91, 0x61, 0xed, 0x26, 0x64, 0xc5, 0xe6, 0x90, 0xd3, 0x91, 0x2d, 0x46, 0xf7, 0x75, - 0x77, 0x40, 0x7c, 0x39, 0x1f, 0xd9, 0x42, 0x6f, 0x41, 0xce, 0x25, 0xba, 0x49, 0x1d, 0x7b, 0xc2, - 0xf7, 0x50, 0x4e, 0x9c, 0x2b, 0x98, 0xe8, 0x66, 0xc7, 0xb1, 0x27, 0x38, 0xe4, 0xa2, 0x2d, 0x28, - 0xee, 0x59, 0x8e, 0xa9, 0xd1, 0x91, 0x08, 0xf2, 0x99, 0xcb, 0x77, 0x9c, 0x18, 0x55, 0xcd, 0x72, - 0xcc, 0x8e, 0x00, 0xe3, 0xc2, 0xde, 0xb4, 0x81, 0xda, 0xb0, 0x78, 0x44, 0xed, 0xf1, 0x90, 0x84, - 0xba, 0xb2, 0x5c, 0xd7, 0x9b, 0x97, 0xeb, 0x7a, 0xcc, 0xf1, 0x81, 0xb6, 0x85, 0xa3, 0x68, 0x13, - 0x3d, 0x82, 0x05, 0x7f, 0x38, 0xda, 0xf7, 0x42, 0x75, 0xf3, 0x5c, 0xdd, 0xf7, 0xae, 0x30, 0x18, - 0x83, 0x07, 0xda, 0x8a, 0x7e, 0xa4, 0x55, 0xfa, 0xf5, 0x14, 0x14, 0x22, 0x23, 0x47, 0x3d, 0x28, - 0x8c, 0x5c, 0x3a, 0xd2, 0x07, 0xfc, 0xa0, 0x92, 0x6b, 0x71, 0xef, 0x85, 0x66, 0x5d, 0xe9, 0x4e, - 0x05, 0x71, 0x54, 0x8b, 0x7a, 0x9a, 0x84, 0x42, 0x84, 0x89, 0xde, 0x81, 0x1c, 0xee, 0xe2, 0xd6, - 0xe3, 0x6a, 0xbf, 0xa9, 0xcc, 0x95, 0x6e, 0x9f, 0x9c, 0x96, 0x57, 0xb9, 0xb6, 0xa8, 0x82, 0xae, - 0x6b, 0x1d, 0x31, 0xd7, 0x7b, 0x0b, 0xe6, 0x03, 0x68, 0xa2, 0xf4, 0xca, 0xc9, 0x69, 0xf9, 0xe5, - 0x8b, 0xd0, 0x08, 0x12, 0xf7, 0xb6, 0xaa, 0xb8, 0xd9, 0x50, 0x92, 0xf1, 0x48, 0xdc, 0x3b, 0xd0, - 0x5d, 0x62, 0xa2, 0xef, 0x41, 0x56, 0x02, 0x53, 0xa5, 0xd2, 0xc9, 0x69, 0xf9, 0xe6, 0x45, 0xe0, - 0x14, 0x87, 0x7b, 0xdb, 0xd5, 0xc7, 0x4d, 0x25, 0x1d, 0x8f, 0xc3, 0x3d, 0x5b, 0x3f, 0x22, 0xe8, - 0x0d, 0xc8, 0x08, 0x58, 0xa6, 0x74, 0xeb, 0xe4, 0xb4, 0xfc, 0xd2, 0x73, 0xea, 0x18, 0xaa, 0xb4, - 0xfa, 0x5b, 0x7f, 0xb0, 0x36, 0xf7, 0x97, 0x7f, 0xb8, 0xa6, 0x5c, 0x64, 0x97, 0xfe, 0x3b, 0x01, - 0x0b, 0x33, 0x4b, 0x8e, 0x54, 0xc8, 0x3a, 0xd4, 0xa0, 0x23, 0x71, 0x7e, 0xe5, 0x6a, 0x70, 0x7e, - 0xb6, 0x9e, 0x6d, 0xd3, 0x3a, 0x1d, 0x4d, 0xb0, 0xe4, 0xa0, 0x47, 0x17, 0x4e, 0xe0, 0xfb, 0x2f, - 0xe8, 0x4f, 0xb1, 0x67, 0xf0, 0x67, 0xb0, 0x60, 0xba, 0xd6, 0x11, 0x71, 0x35, 0x83, 0x3a, 0xfb, - 0xd6, 0x40, 0x9e, 0x4d, 0xa5, 0x38, 0x9d, 0x0d, 0x0e, 0xc4, 0x45, 0x21, 0x50, 0xe7, 0xf8, 0xef, - 0x70, 0xfa, 0x96, 0x1e, 0x43, 0x31, 0xea, 0xa1, 0xec, 0x38, 0xf1, 0xac, 0x5f, 0x26, 0x32, 0xa1, - 0xe3, 0xe9, 0x1f, 0xce, 0x33, 0x0a, 0x4f, 0xe7, 0xd0, 0x9b, 0x90, 0x1e, 0x52, 0x53, 0xe8, 0x59, - 0xa8, 0xdd, 0x60, 0x49, 0xc0, 0x3f, 0x9d, 0xad, 0x17, 0xa8, 0x57, 0xd9, 0xb4, 0x6c, 0xb2, 0x43, - 0x4d, 0x82, 0x39, 0x40, 0x3d, 0x82, 0x34, 0x0b, 0x15, 0xe8, 0x15, 0x48, 0xd7, 0x5a, 0xed, 0x86, - 0x32, 0x57, 0x5a, 0x3e, 0x39, 0x2d, 0x2f, 0x70, 0x93, 0x30, 0x06, 0xf3, 0x5d, 0xb4, 0x0e, 0xd9, - 0xc7, 0x9d, 0xed, 0xdd, 0x1d, 0xe6, 0x5e, 0x37, 0x4e, 0x4e, 0xcb, 0x4b, 0x21, 0x5b, 0x18, 0x0d, - 0xbd, 0x0a, 0x99, 0xfe, 0x4e, 0x77, 0xb3, 0xa7, 0x24, 0x4b, 0xe8, 0xe4, 0xb4, 0xbc, 0x18, 0xf2, - 0xf9, 0x98, 0x4b, 0xcb, 0x72, 0x55, 0xf3, 0x21, 0x5d, 0xfd, 0x59, 0x12, 0x16, 0x30, 0xab, 0x24, - 0x5c, 0xbf, 0x4b, 0x6d, 0xcb, 0x98, 0xa0, 0x2e, 0xe4, 0x0d, 0xea, 0x98, 0x56, 0x64, 0x4f, 0x6d, - 0x5c, 0x72, 0xea, 0x4f, 0xa5, 0x82, 0x56, 0x3d, 0x90, 0xc4, 0x53, 0x25, 0xe8, 0x3d, 0xc8, 0x98, - 0xc4, 0xd6, 0x27, 0x32, 0xfd, 0xb8, 0x55, 0x11, 0xb5, 0x4a, 0x25, 0xa8, 0x55, 0x2a, 0x0d, 0x59, - 0xab, 0x60, 0x81, 0xe3, 0x79, 0xb2, 0xfe, 0x54, 0xd3, 0x7d, 0x9f, 0x0c, 0x47, 0xbe, 0xc8, 0x3d, - 0xd2, 0xb8, 0x30, 0xd4, 0x9f, 0x56, 0x25, 0x09, 0xdd, 0x83, 0xec, 0xb1, 0xe5, 0x98, 0xf4, 0x58, - 0xa6, 0x17, 0x57, 0x28, 0x95, 0x40, 0xf5, 0x84, 0x9d, 0xba, 0x17, 0x86, 0xc9, 0xec, 0xdd, 0xee, - 0xb4, 0x9b, 0x81, 0xbd, 0x25, 0xbf, 0xe3, 0xb4, 0xa9, 0xc3, 0xf6, 0x0a, 0x74, 0xda, 0xda, 0x66, - 0xb5, 0xb5, 0xbd, 0x8b, 0x99, 0xcd, 0x57, 0x4e, 0x4e, 0xcb, 0x4a, 0x08, 0xd9, 0xd4, 0x2d, 0x9b, - 0xe5, 0xbb, 0xb7, 0x20, 0x55, 0x6d, 0x7f, 0xa1, 0x24, 0x4b, 0xca, 0xc9, 0x69, 0xb9, 0x18, 0xb2, - 0xab, 0xce, 0x64, 0xba, 0x8d, 0x2e, 0xf6, 0xab, 0xfe, 0x6d, 0x0a, 0x8a, 0xbb, 0x23, 0x53, 0xf7, - 0x89, 0xf0, 0x49, 0x54, 0x86, 0xc2, 0x48, 0x77, 0x75, 0xdb, 0x26, 0xb6, 0xe5, 0x0d, 0x65, 0x15, - 0x16, 0x25, 0xa1, 0x8f, 0x5e, 0xd4, 0x8c, 0xb5, 0x1c, 0xf3, 0xb3, 0xdf, 0xfd, 0x97, 0xf5, 0x44, - 0x60, 0xd0, 0x5d, 0x58, 0xdc, 0x17, 0xa3, 0xd5, 0x74, 0x83, 0x2f, 0x6c, 0x8a, 0x2f, 0x6c, 0x25, - 0x6e, 0x61, 0xa3, 0xc3, 0xaa, 0xc8, 0x49, 0x56, 0xb9, 0x14, 0x5e, 0xd8, 0x8f, 0x36, 0xd1, 0x7d, - 0x98, 0x1f, 0x52, 0xc7, 0xf2, 0xa9, 0x7b, 0xfd, 0x2a, 0x04, 0x48, 0xf4, 0x0e, 0x2c, 0xb3, 0xc5, - 0x0d, 0xc6, 0xc3, 0xd9, 0xfc, 0xc4, 0x4a, 0xe2, 0xa5, 0xa1, 0xfe, 0x54, 0x76, 0x88, 0x19, 0x19, - 0xd5, 0x20, 0x43, 0x5d, 0x96, 0x12, 0x65, 0xf9, 0x70, 0xdf, 0xbd, 0x76, 0xb8, 0xa2, 0xd1, 0x61, - 0x32, 0x58, 0x88, 0xaa, 0x1f, 0xc2, 0xc2, 0xcc, 0x24, 0x58, 0x26, 0xd0, 0xad, 0xee, 0xf6, 0x9a, - 0xca, 0x1c, 0x2a, 0x42, 0xae, 0xde, 0x69, 0xf7, 0x5b, 0xed, 0x5d, 0x96, 0xca, 0x14, 0x21, 0x87, - 0x3b, 0xdb, 0xdb, 0xb5, 0x6a, 0xfd, 0x91, 0x92, 0x54, 0x2b, 0x50, 0x88, 0x68, 0x43, 0x8b, 0x00, - 0xbd, 0x7e, 0xa7, 0xab, 0x6d, 0xb6, 0x70, 0xaf, 0x2f, 0x12, 0xa1, 0x5e, 0xbf, 0x8a, 0xfb, 0x92, - 0x90, 0x50, 0xff, 0x23, 0x19, 0xac, 0xa8, 0xcc, 0x7d, 0x6a, 0xb3, 0xb9, 0xcf, 0x15, 0x83, 0x97, - 0xd9, 0xcf, 0xb4, 0x11, 0xe6, 0x40, 0x1f, 0x01, 0x70, 0xc7, 0x21, 0xa6, 0xa6, 0xfb, 0x72, 0xe1, - 0x4b, 0xcf, 0x19, 0xb9, 0x1f, 0x5c, 0x06, 0xe0, 0xbc, 0x44, 0x57, 0x7d, 0xf4, 0x03, 0x28, 0x1a, - 0x74, 0x38, 0xb2, 0x89, 0x14, 0x4e, 0x5d, 0x2b, 0x5c, 0x08, 0xf1, 0x55, 0x3f, 0x9a, 0x7d, 0xa5, - 0x67, 0xf3, 0xc3, 0xdf, 0x48, 0x04, 0x96, 0x89, 0x49, 0xb8, 0x8a, 0x90, 0xdb, 0xed, 0x36, 0xaa, - 0xfd, 0x56, 0xfb, 0xa1, 0x92, 0x40, 0x00, 0x59, 0x6e, 0xea, 0x86, 0x92, 0x64, 0x89, 0x62, 0xbd, - 0xb3, 0xd3, 0xdd, 0x6e, 0xf2, 0x94, 0x0b, 0xad, 0x80, 0x12, 0x18, 0x5b, 0xe3, 0x86, 0x6c, 0x36, - 0x94, 0x34, 0xba, 0x01, 0x4b, 0x21, 0x55, 0x4a, 0x66, 0xd0, 0x4d, 0x40, 0x21, 0x71, 0xaa, 0x22, - 0xab, 0xfe, 0x2a, 0x2c, 0xd5, 0xa9, 0xe3, 0xeb, 0x96, 0x13, 0x26, 0xd1, 0x1b, 0x6c, 0xd2, 0x92, - 0xa4, 0x59, 0xa6, 0x88, 0xe9, 0xb5, 0xa5, 0xf3, 0xb3, 0xf5, 0x42, 0x08, 0x6d, 0x35, 0xd8, 0x4c, - 0x83, 0x86, 0xc9, 0xf6, 0xef, 0xc8, 0x32, 0xb9, 0x71, 0x33, 0xb5, 0xf9, 0xf3, 0xb3, 0xf5, 0x54, - 0xb7, 0xd5, 0xc0, 0x8c, 0x86, 0x5e, 0x81, 0x3c, 0x79, 0x6a, 0xf9, 0x9a, 0xc1, 0x62, 0x38, 0x33, - 0x60, 0x06, 0xe7, 0x18, 0xa1, 0xce, 0x42, 0x76, 0x0d, 0xa0, 0x4b, 0x5d, 0x5f, 0xf6, 0xfc, 0x3e, - 0x64, 0x46, 0xd4, 0xe5, 0xe5, 0xf9, 0xa5, 0x97, 0x11, 0x0c, 0x2e, 0x1c, 0x15, 0x0b, 0xb0, 0xfa, - 0x57, 0x49, 0x80, 0xbe, 0xee, 0x1d, 0x4a, 0x25, 0x0f, 0x20, 0x1f, 0x5e, 0xec, 0xc8, 0x3a, 0xff, - 0xca, 0xd5, 0x0e, 0xc1, 0xe8, 0x7e, 0xe0, 0x6c, 0xa2, 0x3c, 0x88, 0xad, 0xd3, 0x82, 0x8e, 0xe2, - 0x32, 0xec, 0xd9, 0x1a, 0x80, 0x1d, 0x89, 0xc4, 0x75, 0xe5, 0xca, 0xb3, 0x4f, 0x54, 0xe7, 0xc7, - 0x82, 0x30, 0x9a, 0x4c, 0x30, 0x5f, 0x8f, 0xeb, 0xe4, 0xc2, 0x8a, 0x6c, 0xcd, 0xe1, 0xa9, 0x1c, - 0xfa, 0x0c, 0x0a, 0x6c, 0xde, 0x9a, 0xc7, 0x79, 0x32, 0xb7, 0xbc, 0xd4, 0x54, 0x42, 0x03, 0x86, - 0x51, 0xf8, 0x5d, 0x53, 0x60, 0xd1, 0x1d, 0x3b, 0x6c, 0xda, 0x52, 0x87, 0xfa, 0x27, 0x49, 0x78, - 0xb9, 0x4d, 0xfc, 0x63, 0xea, 0x1e, 0x56, 0x7d, 0x5f, 0x37, 0x0e, 0x86, 0xc4, 0x91, 0x46, 0x8e, - 0x64, 0xd6, 0x89, 0x99, 0xcc, 0x7a, 0x15, 0xe6, 0x75, 0xdb, 0xd2, 0x3d, 0x22, 0xd2, 0x91, 0x3c, - 0x0e, 0x9a, 0x2c, 0xff, 0x67, 0xd5, 0x04, 0xf1, 0x3c, 0x22, 0x0a, 0xfc, 0x3c, 0x9e, 0x12, 0xd0, - 0x8f, 0xe1, 0xa6, 0x4c, 0x3c, 0xf4, 0xb0, 0x2b, 0x96, 0xd9, 0x06, 0x37, 0x50, 0xcd, 0xd8, 0xf2, - 0x26, 0x7e, 0x70, 0x32, 0x33, 0x99, 0x92, 0x3b, 0x23, 0x5f, 0xe6, 0x39, 0x2b, 0x66, 0x0c, 0xab, - 0xf4, 0x10, 0x6e, 0x5d, 0x2a, 0xf2, 0xad, 0x2e, 0x10, 0xfe, 0x21, 0x09, 0xd0, 0xea, 0x56, 0x77, - 0xa4, 0x91, 0x1a, 0x90, 0xdd, 0xd7, 0x87, 0x96, 0x3d, 0xb9, 0x2a, 0x4e, 0x4d, 0xf1, 0x95, 0xaa, - 0x30, 0xc7, 0x26, 0x97, 0xc1, 0x52, 0x96, 0x17, 0x37, 0xe3, 0x3d, 0x87, 0xf8, 0x61, 0x71, 0xc3, - 0x5b, 0x6c, 0x18, 0xae, 0xee, 0x84, 0x0e, 0x26, 0x1a, 0x6c, 0x01, 0x06, 0xba, 0x4f, 0x8e, 0xf5, - 0x49, 0x10, 0x5c, 0x64, 0x13, 0x6d, 0xb1, 0xa2, 0xc7, 0x23, 0xee, 0x11, 0x31, 0x57, 0x33, 0xdc, - 0xa8, 0xd7, 0x8d, 0x07, 0x4b, 0xb8, 0xb0, 0x5d, 0x28, 0x5d, 0xfa, 0x84, 0x27, 0x36, 0x53, 0xd6, - 0xb7, 0xb2, 0xd1, 0x5d, 0x58, 0x98, 0x99, 0xe7, 0x73, 0x55, 0x65, 0xab, 0xfb, 0xf8, 0x7d, 0x25, - 0x2d, 0xbf, 0x3e, 0x54, 0xb2, 0xea, 0x1f, 0xa5, 0x44, 0x38, 0x90, 0x56, 0x8d, 0xbf, 0xf6, 0xcc, - 0xf1, 0x4d, 0x6c, 0x50, 0x5b, 0x6e, 0xd3, 0x37, 0xaf, 0x8e, 0x12, 0xac, 0x4a, 0xe1, 0x70, 0x1c, - 0x0a, 0xa2, 0x75, 0x28, 0x08, 0x2f, 0xd6, 0xd8, 0xb6, 0xe0, 0x66, 0x5d, 0xc0, 0x20, 0x48, 0x4c, - 0x12, 0xdd, 0x81, 0x45, 0x7e, 0x0b, 0xe1, 0x1d, 0x10, 0x53, 0x60, 0xd2, 0x1c, 0xb3, 0x10, 0x52, - 0x39, 0x6c, 0x07, 0x8a, 0x92, 0xa0, 0xf1, 0x0c, 0x35, 0xc3, 0x07, 0xf4, 0xce, 0x75, 0x03, 0x12, - 0x22, 0x3c, 0x71, 0x2d, 0x8c, 0xa6, 0x0d, 0xb5, 0x01, 0xb9, 0x60, 0xb0, 0x68, 0x15, 0x52, 0xfd, - 0x7a, 0x57, 0x99, 0x2b, 0x2d, 0x9d, 0x9c, 0x96, 0x0b, 0x01, 0xb9, 0x5f, 0xef, 0x32, 0xce, 0x6e, - 0xa3, 0xab, 0x24, 0x66, 0x39, 0xbb, 0x8d, 0x6e, 0x29, 0xcd, 0x32, 0x25, 0x75, 0x1f, 0x0a, 0x91, - 0x1e, 0xd0, 0xeb, 0x30, 0xdf, 0x6a, 0x3f, 0xc4, 0xcd, 0x5e, 0x4f, 0x99, 0x2b, 0xdd, 0x3c, 0x39, - 0x2d, 0xa3, 0x08, 0xb7, 0xe5, 0x0c, 0xd8, 0xfa, 0xa0, 0x57, 0x21, 0xbd, 0xd5, 0x61, 0x27, 0xb0, - 0x48, 0x89, 0x23, 0x88, 0x2d, 0xea, 0xf9, 0xa5, 0x1b, 0x32, 0x05, 0x8b, 0x2a, 0x56, 0x7f, 0x2f, - 0x01, 0x59, 0xb1, 0x99, 0x62, 0x17, 0xaa, 0x0a, 0xf3, 0x41, 0xbd, 0x2a, 0xca, 0x95, 0x37, 0x2f, - 0x2f, 0x2d, 0x2a, 0xb2, 0x12, 0x10, 0xee, 0x17, 0xc8, 0x95, 0x3e, 0x86, 0x62, 0x94, 0xf1, 0xad, - 0x9c, 0xef, 0xc7, 0x50, 0x60, 0xfe, 0x1d, 0x94, 0x18, 0x1b, 0x90, 0x15, 0x01, 0x21, 0x3c, 0x11, - 0x2e, 0xaf, 0x73, 0x24, 0x12, 0x3d, 0x80, 0x79, 0x51, 0x1b, 0x05, 0xd7, 0x94, 0x6b, 0x57, 0xef, - 0x22, 0x1c, 0xc0, 0xd5, 0xcf, 0x20, 0xdd, 0x25, 0xc4, 0x65, 0xb6, 0x77, 0xa8, 0x49, 0xa6, 0x87, - 0xa8, 0x2c, 0xeb, 0x4c, 0xd2, 0x6a, 0xb0, 0xb2, 0xce, 0x24, 0x2d, 0x33, 0xbc, 0x88, 0x49, 0x46, - 0x2e, 0x62, 0xfa, 0x50, 0x7c, 0x42, 0xac, 0xc1, 0x81, 0x4f, 0x4c, 0xae, 0xe8, 0x5d, 0x48, 0x8f, - 0x48, 0x38, 0xf8, 0xd5, 0x58, 0x07, 0x23, 0xc4, 0xc5, 0x1c, 0xc5, 0xe2, 0xc8, 0x31, 0x97, 0x96, - 0x97, 0xe3, 0xb2, 0xa5, 0xfe, 0x7d, 0x12, 0x16, 0x5b, 0x9e, 0x37, 0xd6, 0x1d, 0x23, 0xc8, 0xaf, - 0x3e, 0x9d, 0xcd, 0xaf, 0xde, 0x8a, 0x9d, 0xe1, 0x8c, 0xc8, 0xec, 0xfd, 0x92, 0x3c, 0xe3, 0x92, - 0xe1, 0x19, 0xa7, 0xfe, 0x7b, 0x22, 0xb8, 0x44, 0xba, 0x13, 0xd9, 0xee, 0xa5, 0xd5, 0x93, 0xd3, - 0xf2, 0x4a, 0x54, 0x13, 0xd9, 0x75, 0x0e, 0x1d, 0x7a, 0xec, 0xa0, 0xd7, 0x20, 0x83, 0x9b, 0xed, - 0xe6, 0x13, 0x25, 0x21, 0xdc, 0x73, 0x06, 0x84, 0x89, 0x43, 0x8e, 0x99, 0xa6, 0x6e, 0xb3, 0xdd, - 0x60, 0xf9, 0x50, 0x32, 0x46, 0x53, 0x97, 0x38, 0xa6, 0xe5, 0x0c, 0xd0, 0xeb, 0x90, 0x6d, 0xf5, - 0x7a, 0xbb, 0xbc, 0xcc, 0x7f, 0xf9, 0xe4, 0xb4, 0x7c, 0x63, 0x06, 0xc5, 0x2f, 0x10, 0x4d, 0x06, - 0x62, 0xc5, 0x08, 0xcb, 0x94, 0x62, 0x40, 0x2c, 0xcb, 0x15, 0x20, 0xdc, 0xe9, 0x57, 0xfb, 0xac, - 0xc2, 0x7f, 0x1e, 0x84, 0x29, 0xfb, 0x2b, 0xb7, 0xdb, 0x3f, 0x27, 0x41, 0xa9, 0x1a, 0x06, 0x19, - 0xf9, 0x8c, 0x2f, 0xeb, 0xbf, 0x3e, 0xe4, 0x46, 0xec, 0xcb, 0x22, 0x41, 0x2e, 0xf3, 0x20, 0xf6, - 0x79, 0xe6, 0x82, 0x5c, 0x05, 0x53, 0x9b, 0x54, 0xcd, 0xa1, 0xe5, 0x79, 0x16, 0x75, 0x04, 0x0d, - 0x87, 0x9a, 0x4a, 0xff, 0x99, 0x80, 0x1b, 0x31, 0x08, 0x74, 0x17, 0xd2, 0x2e, 0xb5, 0x83, 0x35, - 0xbc, 0x7d, 0xd9, 0xfd, 0x20, 0x13, 0xc5, 0x1c, 0x89, 0xd6, 0x00, 0xf4, 0xb1, 0x4f, 0x75, 0xde, - 0x3f, 0x5f, 0xbd, 0x1c, 0x8e, 0x50, 0xd0, 0x13, 0xc8, 0x7a, 0xc4, 0x70, 0x49, 0x90, 0xf1, 0x7e, - 0xf6, 0x7f, 0x1d, 0x7d, 0xa5, 0xc7, 0xd5, 0x60, 0xa9, 0xae, 0x54, 0x81, 0xac, 0xa0, 0x30, 0xb7, - 0x37, 0x75, 0x5f, 0x97, 0xb7, 0xc7, 0xfc, 0x9b, 0x79, 0x93, 0x6e, 0x0f, 0x02, 0x6f, 0xd2, 0xed, - 0x81, 0xfa, 0x37, 0x49, 0x80, 0xe6, 0x53, 0x9f, 0xb8, 0x8e, 0x6e, 0xd7, 0xab, 0xa8, 0x19, 0x89, - 0xfe, 0x62, 0xb6, 0x6f, 0xc7, 0x5e, 0x89, 0x87, 0x12, 0x95, 0x7a, 0x35, 0x26, 0xfe, 0xdf, 0x82, - 0xd4, 0xd8, 0x95, 0x2f, 0x6e, 0x22, 0x5b, 0xdd, 0xc5, 0xdb, 0x98, 0xd1, 0x50, 0x73, 0x1a, 0xb6, - 0x52, 0x97, 0xbf, 0xab, 0x45, 0x3a, 0x88, 0x0d, 0x5d, 0x6c, 0xe7, 0x1b, 0xba, 0x66, 0x10, 0x79, - 0x72, 0x14, 0xc5, 0xce, 0xaf, 0x57, 0xeb, 0xc4, 0xf5, 0x71, 0xd6, 0xd0, 0xd9, 0xff, 0xef, 0x14, - 0xdf, 0xde, 0x05, 0x98, 0x4e, 0x0d, 0xad, 0x41, 0xa6, 0xbe, 0xd9, 0xeb, 0x6d, 0x2b, 0x73, 0x22, - 0x80, 0x4f, 0x59, 0x9c, 0xac, 0xfe, 0x45, 0x12, 0x72, 0xf5, 0xaa, 0x3c, 0x56, 0xeb, 0xa0, 0xf0, - 0xa8, 0xc4, 0xef, 0xdc, 0xc9, 0xd3, 0x91, 0xe5, 0x4e, 0x64, 0x60, 0xb9, 0xa2, 0xf4, 0x5c, 0x64, - 0x22, 0x6c, 0xd4, 0x4d, 0x2e, 0x80, 0x30, 0x14, 0x89, 0x34, 0x82, 0x66, 0xe8, 0x41, 0x8c, 0x5f, - 0xbb, 0xda, 0x58, 0xa2, 0x88, 0x98, 0xb6, 0x3d, 0x5c, 0x08, 0x94, 0xd4, 0x75, 0x0f, 0x7d, 0x04, - 0x4b, 0x9e, 0x35, 0x70, 0x2c, 0x67, 0xa0, 0x05, 0xc6, 0xe3, 0x0f, 0x00, 0xb5, 0xe5, 0xf3, 0xb3, - 0xf5, 0x85, 0x9e, 0x60, 0x49, 0x1b, 0x2e, 0x48, 0x64, 0x9d, 0x9b, 0x12, 0x7d, 0x08, 0x8b, 0x11, - 0x51, 0x66, 0x45, 0x61, 0x76, 0xe5, 0xfc, 0x6c, 0xbd, 0x18, 0x4a, 0x3e, 0x22, 0x13, 0x5c, 0x0c, - 0x05, 0x1f, 0x11, 0x7e, 0x4b, 0xb2, 0x4f, 0x5d, 0x83, 0x68, 0x2e, 0xdf, 0xd3, 0xfc, 0x04, 0x4f, - 0xe3, 0x02, 0xa7, 0x89, 0x6d, 0xae, 0x3e, 0x86, 0x1b, 0x1d, 0xd7, 0x38, 0x20, 0x9e, 0x2f, 0x4c, - 0x21, 0xad, 0xf8, 0x19, 0xdc, 0xf6, 0x75, 0xef, 0x50, 0x3b, 0xb0, 0x3c, 0x9f, 0xba, 0x13, 0xcd, - 0x25, 0x3e, 0x71, 0x18, 0x5f, 0xe3, 0xaf, 0x86, 0xf2, 0x1a, 0xeb, 0x16, 0xc3, 0x6c, 0x09, 0x08, - 0x0e, 0x10, 0xdb, 0x0c, 0xa0, 0xb6, 0xa0, 0xc8, 0x8a, 0x89, 0x06, 0xd9, 0xd7, 0xc7, 0xb6, 0xcf, - 0x66, 0x0f, 0x36, 0x1d, 0x68, 0x2f, 0x7c, 0x4c, 0xe5, 0x6d, 0x3a, 0x10, 0x9f, 0xea, 0x8f, 0x40, - 0x69, 0x58, 0xde, 0x48, 0xf7, 0x8d, 0x83, 0xe0, 0x7e, 0x0e, 0x35, 0x40, 0x39, 0x20, 0xba, 0xeb, - 0xef, 0x11, 0xdd, 0xd7, 0x46, 0xc4, 0xb5, 0xa8, 0x79, 0xfd, 0x2a, 0x2f, 0x85, 0x22, 0x5d, 0x2e, - 0xa1, 0xfe, 0x57, 0x02, 0x00, 0xeb, 0xfb, 0x41, 0x46, 0xf6, 0x7d, 0x58, 0xf6, 0x1c, 0x7d, 0xe4, - 0x1d, 0x50, 0x5f, 0xb3, 0x1c, 0x9f, 0xb8, 0x47, 0xba, 0x2d, 0xaf, 0x59, 0x94, 0x80, 0xd1, 0x92, - 0x74, 0xf4, 0x2e, 0xa0, 0x43, 0x42, 0x46, 0x1a, 0xb5, 0x4d, 0x2d, 0x60, 0x8a, 0x37, 0xcd, 0x34, - 0x56, 0x18, 0xa7, 0x63, 0x9b, 0xbd, 0x80, 0x8e, 0x6a, 0xb0, 0xc6, 0xa6, 0x4f, 0x1c, 0xdf, 0xb5, - 0x88, 0xa7, 0xed, 0x53, 0x57, 0xf3, 0x6c, 0x7a, 0xac, 0xed, 0x53, 0xdb, 0xa6, 0xc7, 0xc4, 0x0d, - 0x6e, 0xb0, 0x4a, 0x36, 0x1d, 0x34, 0x05, 0x68, 0x93, 0xba, 0x3d, 0x9b, 0x1e, 0x6f, 0x06, 0x08, - 0x96, 0xb6, 0x4d, 0xe7, 0xec, 0x5b, 0xc6, 0x61, 0x90, 0xb6, 0x85, 0xd4, 0xbe, 0x65, 0x1c, 0xa2, - 0xd7, 0x61, 0x81, 0xd8, 0x84, 0x5f, 0x64, 0x08, 0x54, 0x86, 0xa3, 0x8a, 0x01, 0x91, 0x81, 0xd4, - 0xcf, 0x41, 0x69, 0x3a, 0x86, 0x3b, 0x19, 0x45, 0xd6, 0xfc, 0x5d, 0x40, 0x2c, 0x48, 0x6a, 0x36, - 0x35, 0x0e, 0xb5, 0xa1, 0xee, 0xe8, 0x03, 0x36, 0x2e, 0xf1, 0xd4, 0xa4, 0x30, 0xce, 0x36, 0x35, - 0x0e, 0x77, 0x24, 0x5d, 0xfd, 0x08, 0xa0, 0x37, 0x72, 0x89, 0x6e, 0x76, 0x58, 0x36, 0xc1, 0x4c, - 0xc7, 0x5b, 0x9a, 0x29, 0x9f, 0xea, 0xa8, 0x2b, 0xb7, 0xba, 0x22, 0x18, 0x8d, 0x90, 0xae, 0xfe, - 0x02, 0xdc, 0xe8, 0xda, 0xba, 0xc1, 0x9f, 0xad, 0xbb, 0xe1, 0xdb, 0x09, 0x7a, 0x00, 0x59, 0x01, - 0x95, 0x2b, 0x19, 0xbb, 0xdd, 0xa6, 0x7d, 0x6e, 0xcd, 0x61, 0x89, 0xaf, 0x15, 0x01, 0xa6, 0x7a, - 0xd4, 0x3f, 0x4b, 0x40, 0x3e, 0xd4, 0x8f, 0xca, 0xc0, 0x4a, 0x79, 0xe6, 0xde, 0x96, 0x23, 0x6b, - 0xef, 0x3c, 0x8e, 0x92, 0x50, 0x0b, 0x0a, 0xa3, 0x50, 0xfa, 0xca, 0x7c, 0x2e, 0x66, 0xd4, 0x38, - 0x2a, 0x8b, 0x3e, 0x86, 0x7c, 0xf0, 0x36, 0x1a, 0x44, 0xd8, 0xab, 0x9f, 0x52, 0xa7, 0x70, 0xf5, - 0x53, 0x80, 0x1f, 0x52, 0xcb, 0xe9, 0xd3, 0x43, 0xe2, 0xf0, 0xb7, 0x3e, 0x56, 0x13, 0x92, 0xc0, - 0x8a, 0xb2, 0xc5, 0x0b, 0x72, 0xb1, 0x04, 0xe1, 0x93, 0x97, 0x68, 0xaa, 0x7f, 0x9d, 0x84, 0x2c, - 0xa6, 0xd4, 0xaf, 0x57, 0x51, 0x19, 0xb2, 0x32, 0x4e, 0xf0, 0xf3, 0xa7, 0x96, 0x3f, 0x3f, 0x5b, - 0xcf, 0x88, 0x00, 0x91, 0x31, 0x78, 0x64, 0x88, 0x44, 0xf0, 0xe4, 0x65, 0x11, 0x1c, 0xdd, 0x85, - 0xa2, 0x04, 0x69, 0x07, 0xba, 0x77, 0x20, 0x0a, 0xb4, 0xda, 0xe2, 0xf9, 0xd9, 0x3a, 0x08, 0xe4, - 0x96, 0xee, 0x1d, 0x60, 0x10, 0x68, 0xf6, 0x8d, 0x9a, 0x50, 0xf8, 0x92, 0x5a, 0x8e, 0xe6, 0xf3, - 0x49, 0xc8, 0x2b, 0xbf, 0xd8, 0x75, 0x9c, 0x4e, 0x55, 0x3e, 0x7c, 0xc3, 0x97, 0xd3, 0xc9, 0x37, - 0x61, 0xc1, 0xa5, 0xd4, 0x17, 0x61, 0xcb, 0xa2, 0x8e, 0xbc, 0x4d, 0x28, 0xc7, 0x5e, 0x32, 0x53, - 0xea, 0x63, 0x89, 0xc3, 0x45, 0x37, 0xd2, 0x42, 0x77, 0x61, 0xc5, 0xd6, 0x3d, 0x5f, 0xe3, 0xf1, - 0xce, 0x9c, 0x6a, 0xcb, 0xf2, 0xad, 0x86, 0x18, 0x6f, 0x93, 0xb3, 0x02, 0x09, 0xf5, 0x1f, 0x13, - 0x50, 0x60, 0x93, 0xb1, 0xf6, 0x2d, 0x83, 0x25, 0x79, 0xdf, 0x3e, 0xf7, 0xb8, 0x05, 0x29, 0xc3, - 0x73, 0xa5, 0x51, 0xf9, 0xe1, 0x5b, 0xef, 0x61, 0xcc, 0x68, 0xe8, 0x73, 0xc8, 0xca, 0x5b, 0x0d, - 0x91, 0x76, 0xa8, 0xd7, 0xa7, 0xa3, 0xd2, 0x36, 0x52, 0x8e, 0xfb, 0xf2, 0x74, 0x74, 0xe2, 0x10, - 0xc0, 0x51, 0x12, 0xba, 0x09, 0x49, 0x43, 0x98, 0x4b, 0xfe, 0xb2, 0xa2, 0xde, 0xc6, 0x49, 0xc3, - 0x51, 0xff, 0x2e, 0x01, 0x0b, 0xd3, 0x0d, 0xcf, 0x3c, 0xe0, 0x36, 0xe4, 0xbd, 0xf1, 0x9e, 0x37, - 0xf1, 0x7c, 0x32, 0x0c, 0xde, 0x31, 0x43, 0x02, 0x6a, 0x41, 0x5e, 0xb7, 0x07, 0xd4, 0xb5, 0xfc, - 0x83, 0xa1, 0xac, 0x44, 0xe3, 0x53, 0x85, 0xa8, 0xce, 0x4a, 0x35, 0x10, 0xc1, 0x53, 0xe9, 0xe0, - 0xdc, 0x17, 0x8f, 0xdd, 0xfc, 0xdc, 0x7f, 0x0d, 0x8a, 0xb6, 0x3e, 0xe4, 0xd7, 0x3c, 0xbe, 0x35, - 0x14, 0xf3, 0x48, 0xe3, 0x82, 0xa4, 0xf5, 0xad, 0x21, 0x51, 0x55, 0xc8, 0x87, 0xca, 0xd0, 0x12, - 0x14, 0xaa, 0xcd, 0x9e, 0x76, 0x6f, 0xe3, 0x81, 0xf6, 0xb0, 0xbe, 0xa3, 0xcc, 0xc9, 0xdc, 0xf4, - 0xcf, 0x13, 0xb0, 0x20, 0xc3, 0x91, 0xcc, 0xf7, 0x5f, 0x87, 0x79, 0x57, 0xdf, 0xf7, 0x83, 0x8a, - 0x24, 0x2d, 0xbc, 0x9a, 0x45, 0x78, 0x56, 0x91, 0x30, 0x56, 0x7c, 0x45, 0x12, 0x79, 0x59, 0x4f, - 0x5d, 0xf9, 0xb2, 0x9e, 0xfe, 0xb9, 0xbc, 0xac, 0xab, 0xbf, 0x06, 0xb0, 0x69, 0xd9, 0xa4, 0x2f, - 0xee, 0x9a, 0xe2, 0xea, 0x4b, 0x96, 0xc3, 0xc9, 0x1b, 0xc7, 0x20, 0x87, 0x6b, 0x35, 0x30, 0xa3, - 0x31, 0xd6, 0xc0, 0x32, 0xe5, 0x66, 0xe4, 0xac, 0x87, 0x8c, 0x35, 0xb0, 0xcc, 0xf0, 0x2d, 0x29, - 0x7d, 0xdd, 0x5b, 0xd2, 0x69, 0x02, 0x96, 0x64, 0xee, 0x1a, 0x86, 0xdf, 0xb7, 0x21, 0x2f, 0xd2, - 0xd8, 0x69, 0x41, 0xc7, 0x5f, 0x93, 0x05, 0xae, 0xd5, 0xc0, 0x39, 0xc1, 0x6e, 0x99, 0x68, 0x1d, - 0x0a, 0x12, 0x1a, 0xf9, 0x15, 0x0e, 0x08, 0x52, 0x9b, 0x0d, 0xff, 0x7d, 0x48, 0xef, 0x5b, 0x36, - 0x91, 0x8e, 0x1e, 0x1b, 0x00, 0xa6, 0x06, 0xd8, 0x9a, 0xc3, 0x1c, 0x5d, 0xcb, 0x05, 0x97, 0x71, - 0x7c, 0x7c, 0xb2, 0xec, 0x8c, 0x8e, 0x4f, 0x54, 0xa0, 0x17, 0xc6, 0x27, 0x70, 0x6c, 0x7c, 0x82, - 0x2d, 0xc6, 0x27, 0xa1, 0xd1, 0xf1, 0x09, 0xd2, 0xcf, 0x65, 0x7c, 0xdb, 0x70, 0xb3, 0x66, 0xeb, - 0xc6, 0xa1, 0x6d, 0x79, 0x3e, 0x31, 0xa3, 0x11, 0x63, 0x03, 0xb2, 0x33, 0x49, 0xe7, 0x55, 0x97, - 0xb3, 0x12, 0xa9, 0xfe, 0x5b, 0x02, 0x8a, 0x5b, 0x44, 0xb7, 0xfd, 0x83, 0xe9, 0xd5, 0x90, 0x4f, - 0x3c, 0x5f, 0x1e, 0x56, 0xfc, 0x1b, 0x7d, 0x00, 0xb9, 0x30, 0x27, 0xb9, 0xf6, 0x95, 0x2c, 0x84, - 0xa2, 0xfb, 0x30, 0xcf, 0xf6, 0x18, 0x1d, 0x07, 0xc5, 0xce, 0x55, 0x0f, 0x30, 0x12, 0xc9, 0x0e, - 0x19, 0x97, 0xf0, 0x24, 0x84, 0xbb, 0x52, 0x06, 0x07, 0x4d, 0xf4, 0xff, 0xa1, 0xc8, 0xdf, 0x0f, - 0x82, 0x9c, 0x2b, 0x73, 0x9d, 0xce, 0x82, 0x78, 0x02, 0x14, 0xf9, 0xd6, 0xff, 0x24, 0x60, 0x65, - 0x47, 0x9f, 0xec, 0x11, 0x19, 0x36, 0x88, 0x89, 0x89, 0x41, 0x5d, 0x13, 0x75, 0xa3, 0xe1, 0xe6, - 0x8a, 0x17, 0xc5, 0x38, 0xe1, 0xf8, 0xa8, 0x13, 0x14, 0x60, 0xc9, 0x48, 0x01, 0xb6, 0x02, 0x19, - 0x87, 0x3a, 0x06, 0x91, 0xb1, 0x48, 0x34, 0x54, 0x2b, 0x1a, 0x6a, 0x4a, 0xe1, 0x63, 0x1f, 0x7f, - 0xaa, 0x6b, 0x53, 0x3f, 0xec, 0x0d, 0x7d, 0x0e, 0xa5, 0x5e, 0xb3, 0x8e, 0x9b, 0xfd, 0x5a, 0xe7, - 0x47, 0x5a, 0xaf, 0xba, 0xdd, 0xab, 0x6e, 0xdc, 0xd5, 0xba, 0x9d, 0xed, 0x2f, 0xee, 0xdd, 0xbf, - 0xfb, 0x81, 0x92, 0x28, 0x95, 0x4f, 0x4e, 0xcb, 0xb7, 0xdb, 0xd5, 0xfa, 0xb6, 0xd8, 0x31, 0x7b, - 0xf4, 0x69, 0x4f, 0xb7, 0x3d, 0x7d, 0xe3, 0x6e, 0x97, 0xda, 0x13, 0x86, 0x61, 0x6e, 0x5d, 0x8c, - 0x9e, 0x57, 0xd1, 0x63, 0x38, 0x71, 0xe9, 0x31, 0x3c, 0x3d, 0xcd, 0x93, 0x97, 0x9c, 0xe6, 0x9b, - 0xb0, 0x62, 0xb8, 0xd4, 0xf3, 0x34, 0x96, 0xfd, 0x13, 0xf3, 0x42, 0x7d, 0xf1, 0xd2, 0xf9, 0xd9, - 0xfa, 0x72, 0x9d, 0xf1, 0x7b, 0x9c, 0x2d, 0xd5, 0x2f, 0x1b, 0x11, 0x12, 0xef, 0x49, 0xfd, 0xfd, - 0x14, 0x4b, 0xa4, 0xac, 0x23, 0xcb, 0x26, 0x03, 0xe2, 0xa1, 0xc7, 0xb0, 0x64, 0xb8, 0xc4, 0x64, - 0x69, 0xbd, 0x6e, 0x6b, 0xde, 0x88, 0x18, 0xd2, 0xa9, 0xff, 0x5f, 0x6c, 0x4e, 0x13, 0x0a, 0x56, - 0xea, 0xa1, 0x54, 0x6f, 0x44, 0x0c, 0xbc, 0x68, 0xcc, 0xb4, 0xd1, 0x97, 0xb0, 0xe4, 0x11, 0xdb, - 0x72, 0xc6, 0x4f, 0x35, 0x83, 0x3a, 0x3e, 0x79, 0x1a, 0xbc, 0x5b, 0x5d, 0xa7, 0xb7, 0xd7, 0xdc, - 0x66, 0x52, 0x75, 0x21, 0x54, 0x43, 0xe7, 0x67, 0xeb, 0x8b, 0xb3, 0x34, 0xbc, 0x28, 0x35, 0xcb, - 0x76, 0xa9, 0x0d, 0x8b, 0xb3, 0xa3, 0x41, 0x2b, 0x72, 0xef, 0xf3, 0x10, 0x12, 0xec, 0x6d, 0x74, - 0x1b, 0x72, 0x2e, 0x19, 0x58, 0x9e, 0xef, 0x0a, 0x33, 0x33, 0x4e, 0x48, 0x61, 0x3b, 0x5f, 0xfc, - 0x14, 0xa7, 0xf4, 0x2b, 0x70, 0xa1, 0x47, 0xb6, 0x59, 0x4c, 0xcb, 0xd3, 0xf7, 0xa4, 0xca, 0x1c, - 0x0e, 0x9a, 0xcc, 0x07, 0xc7, 0x5e, 0x98, 0xa8, 0xf1, 0x6f, 0x46, 0xe3, 0x19, 0x85, 0xfc, 0x61, - 0x12, 0xcf, 0x19, 0x82, 0x5f, 0x38, 0xa6, 0x23, 0xbf, 0x70, 0x5c, 0x81, 0x8c, 0x4d, 0x8e, 0x88, - 0x2d, 0xce, 0x72, 0x2c, 0x1a, 0xef, 0xfc, 0x2c, 0x05, 0xf9, 0xf0, 0x8d, 0x86, 0x9d, 0x04, 0xed, - 0xe6, 0x93, 0xc0, 0x57, 0x43, 0x7a, 0x9b, 0x1c, 0xa3, 0xd7, 0xa6, 0x77, 0x4a, 0x9f, 0x8b, 0x47, - 0xe9, 0x90, 0x1d, 0xdc, 0x27, 0xbd, 0x01, 0xb9, 0x6a, 0xaf, 0xd7, 0x7a, 0xd8, 0x6e, 0x36, 0x94, - 0xaf, 0x12, 0xa5, 0x97, 0x4e, 0x4e, 0xcb, 0xcb, 0x21, 0xa8, 0xea, 0x09, 0x57, 0xe2, 0xa8, 0x7a, - 0xbd, 0xd9, 0xed, 0x37, 0x1b, 0xca, 0xb3, 0xe4, 0x45, 0x14, 0xbf, 0x23, 0xe1, 0x3f, 0x2d, 0xc9, - 0x77, 0x71, 0xb3, 0x5b, 0xc5, 0xac, 0xc3, 0xaf, 0x92, 0xe2, 0xaa, 0x6b, 0xda, 0xa3, 0x4b, 0x46, - 0xba, 0xcb, 0xfa, 0x5c, 0x0b, 0x7e, 0x62, 0xf5, 0x2c, 0x25, 0x7e, 0x7e, 0x30, 0x7d, 0x70, 0x22, - 0xba, 0x39, 0x61, 0xbd, 0xf1, 0x97, 0x3e, 0xae, 0x26, 0x75, 0xa1, 0xb7, 0x1e, 0x8b, 0x24, 0x4c, - 0x8b, 0x0a, 0xf3, 0x78, 0xb7, 0xdd, 0x66, 0xa0, 0x67, 0xe9, 0x0b, 0xb3, 0xc3, 0x63, 0x87, 0xd5, - 0xbf, 0xe8, 0x0e, 0xe4, 0x82, 0x87, 0x40, 0xe5, 0xab, 0xf4, 0x85, 0x01, 0xd5, 0x83, 0x57, 0x4c, - 0xde, 0xe1, 0xd6, 0x6e, 0x9f, 0xff, 0x02, 0xec, 0x59, 0xe6, 0x62, 0x87, 0x07, 0x63, 0xdf, 0xa4, - 0xc7, 0x0e, 0xdb, 0x81, 0xf2, 0x56, 0xed, 0xab, 0x8c, 0xb8, 0x82, 0x08, 0x31, 0xf2, 0x4a, 0xed, - 0x0d, 0xc8, 0xe1, 0xe6, 0x0f, 0xc5, 0x8f, 0xc5, 0x9e, 0x65, 0x2f, 0xe8, 0xc1, 0xe4, 0x4b, 0x62, - 0xc8, 0xde, 0x3a, 0xb8, 0xbb, 0x55, 0xe5, 0x26, 0xbf, 0x88, 0xea, 0xb8, 0xa3, 0x03, 0xdd, 0x21, - 0xe6, 0xf4, 0x37, 0x18, 0x21, 0xeb, 0x9d, 0x5f, 0x84, 0x5c, 0x90, 0x67, 0xa2, 0x35, 0xc8, 0x3e, - 0xe9, 0xe0, 0x47, 0x4d, 0xac, 0xcc, 0x09, 0x1b, 0x06, 0x9c, 0x27, 0xa2, 0x42, 0x28, 0xc3, 0xfc, - 0x4e, 0xb5, 0x5d, 0x7d, 0xd8, 0xc4, 0xc1, 0x85, 0x77, 0x00, 0x90, 0xc9, 0x52, 0x49, 0x91, 0x1d, - 0x84, 0x3a, 0x6b, 0xab, 0x5f, 0x7f, 0xb3, 0x36, 0xf7, 0xd3, 0x6f, 0xd6, 0xe6, 0x9e, 0x9d, 0xaf, - 0x25, 0xbe, 0x3e, 0x5f, 0x4b, 0xfc, 0xe4, 0x7c, 0x2d, 0xf1, 0xaf, 0xe7, 0x6b, 0x89, 0xbd, 0x2c, - 0x0f, 0xe9, 0xf7, 0xff, 0x37, 0x00, 0x00, 0xff, 0xff, 0x62, 0x46, 0x73, 0x55, 0x80, 0x2e, 0x00, - 0x00, + // 4808 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x7a, 0x4d, 0x6c, 0x24, 0x49, + 0x56, 0xbf, 0xeb, 0xd3, 0x55, 0xaf, 0xca, 0x76, 0x76, 0xb4, 0xb7, 0xd7, 0x5d, 0xd3, 0x63, 0xd7, + 0xe4, 0x4c, 0xef, 0x7c, 0xec, 0xfc, 0x6b, 0xba, 0xdd, 0x33, 0xa3, 0xee, 0xe9, 0xff, 0x7c, 0xd4, + 0x97, 0xdb, 0xb5, 0x6d, 0x57, 0x95, 0xa2, 0xca, 0xdd, 0x3b, 0x07, 0x48, 0xa5, 0x33, 0xc3, 0xe5, + 0x1c, 0x67, 0x65, 0x14, 0x99, 0x59, 0x76, 0x17, 0x0b, 0xa2, 0xc5, 0x01, 0x90, 0x4f, 0x70, 0x62, + 0x25, 0x64, 0x2e, 0x70, 0x42, 0x48, 0x1c, 0x40, 0x42, 0x70, 0x61, 0x90, 0x38, 0xcc, 0x8d, 0x05, + 0x24, 0xb4, 0x02, 0xc9, 0x30, 0x3e, 0x70, 0x43, 0x70, 0x59, 0x71, 0x01, 0x09, 0xc5, 0x47, 0x66, + 0x65, 0xb9, 0xd3, 0x76, 0x0f, 0xb3, 0x17, 0x3b, 0xe3, 0xbd, 0xdf, 0x7b, 0xf1, 0xe2, 0x45, 0xc4, + 0x8b, 0xf7, 0x22, 0x0a, 0x0a, 0xfe, 0x64, 0x44, 0xbc, 0xca, 0xc8, 0xa5, 0x3e, 0x45, 0xc8, 0xa4, + 0xc6, 0x01, 0x71, 0x2b, 0xde, 0x91, 0xee, 0x0e, 0x0f, 0x2c, 0xbf, 0x72, 0x78, 0xb7, 0xb4, 0x36, + 0xa0, 0x74, 0x60, 0x93, 0xf7, 0x38, 0x62, 0x77, 0xbc, 0xf7, 0x9e, 0x6f, 0x0d, 0x89, 0xe7, 0xeb, + 0xc3, 0x91, 0x10, 0x2a, 0xad, 0x9e, 0x07, 0x98, 0x63, 0x57, 0xf7, 0x2d, 0xea, 0x48, 0xfe, 0xf2, + 0x80, 0x0e, 0x28, 0xff, 0x7c, 0x8f, 0x7d, 0x09, 0xaa, 0xba, 0x06, 0xf3, 0x4f, 0x88, 0xeb, 0x59, + 0xd4, 0x41, 0xcb, 0x90, 0xb1, 0x1c, 0x93, 0x3c, 0x5b, 0x49, 0x94, 0x13, 0x6f, 0xa5, 0xb1, 0x68, + 0xa8, 0x77, 0x00, 0x5a, 0xec, 0xa3, 0xe9, 0xf8, 0xee, 0x04, 0x29, 0x90, 0x3a, 0x20, 0x13, 0x8e, + 0xc8, 0x63, 0xf6, 0xc9, 0x28, 0x87, 0xba, 0xbd, 0x92, 0x14, 0x94, 0x43, 0xdd, 0x56, 0xbf, 0x4e, + 0x40, 0xa1, 0xea, 0x38, 0xd4, 0xe7, 0xbd, 0x7b, 0x08, 0x41, 0xda, 0xd1, 0x87, 0x44, 0x0a, 0xf1, + 0x6f, 0x54, 0x87, 0xac, 0xad, 0xef, 0x12, 0xdb, 0x5b, 0x49, 0x96, 0x53, 0x6f, 0x15, 0xd6, 0xbf, + 0x5f, 0x79, 0x71, 0xc8, 0x95, 0x88, 0x92, 0xca, 0x16, 0x47, 0x73, 0x23, 0xb0, 0x14, 0x45, 0x9f, + 0xc0, 0xbc, 0xe5, 0x98, 0x96, 0x41, 0xbc, 0x95, 0x34, 0xd7, 0xb2, 0x1a, 0xa7, 0x65, 0x6a, 0x7d, + 0x2d, 0xfd, 0xd5, 0xe9, 0xda, 0x1c, 0x0e, 0x84, 0x4a, 0x0f, 0xa0, 0x10, 0x51, 0x1b, 0x33, 0xb6, + 0x65, 0xc8, 0x1c, 0xea, 0xf6, 0x98, 0xc8, 0xd1, 0x89, 0xc6, 0x47, 0xc9, 0xfb, 0x09, 0xf5, 0x01, + 0x2c, 0x3c, 0x22, 0x0e, 0x71, 0x2d, 0xa3, 0xe7, 0xbb, 0x96, 0x33, 0x60, 0x83, 0x3c, 0xb0, 0x1c, + 0x33, 0x18, 0x24, 0xfb, 0x8e, 0x17, 0x57, 0x1f, 0xc2, 0x92, 0x14, 0x6d, 0x58, 0x9e, 0xe1, 0x12, + 0x9f, 0x5c, 0x2d, 0x9c, 0x0a, 0x84, 0x7f, 0x37, 0x11, 0x4a, 0x63, 0xe2, 0xd1, 0xb1, 0x6b, 0x10, + 0xf4, 0x01, 0xa4, 0x3c, 0xdf, 0xe5, 0xc2, 0x85, 0xf5, 0xd7, 0xe2, 0x5c, 0x30, 0x63, 0xea, 0xe6, + 0x1c, 0x66, 0x78, 0x54, 0x85, 0x9c, 0x29, 0x0d, 0xe0, 0x7d, 0x14, 0xd6, 0x5f, 0xbf, 0x44, 0x36, + 0xb0, 0x75, 0x73, 0x0e, 0x87, 0x62, 0x35, 0x80, 0x9c, 0x2b, 0xad, 0x50, 0x7f, 0x9c, 0x80, 0x7c, + 0x60, 0x92, 0x87, 0xde, 0x86, 0xbc, 0xa3, 0x3b, 0x54, 0x33, 0x46, 0x63, 0x8f, 0x5b, 0x96, 0xaa, + 0x15, 0xcf, 0x4e, 0xd7, 0x72, 0x6d, 0xdd, 0xa1, 0xf5, 0xee, 0x8e, 0x87, 0x73, 0x8c, 0x5d, 0x1f, + 0x8d, 0x3d, 0xf4, 0x1a, 0x14, 0x87, 0x64, 0x48, 0xdd, 0x89, 0xb6, 0x3b, 0xf1, 0x89, 0x27, 0xc7, + 0x5b, 0x10, 0xb4, 0x1a, 0x23, 0xa1, 0x8f, 0x61, 0x7e, 0x20, 0xcc, 0x58, 0x49, 0xf1, 0x89, 0xbe, + 0xcc, 0xd2, 0xc0, 0x08, 0x1c, 0xc8, 0xa8, 0xbf, 0x9d, 0x80, 0xe5, 0x90, 0x4a, 0x7e, 0x69, 0x6c, + 0xb9, 0x64, 0x48, 0x1c, 0xdf, 0x43, 0x1f, 0x40, 0xd6, 0xb6, 0x86, 0x96, 0xef, 0x49, 0xe7, 0xbd, + 0x1a, 0xa7, 0x36, 0x1c, 0x14, 0x96, 0x60, 0x54, 0x85, 0xa2, 0x4b, 0x3c, 0xe2, 0x1e, 0x8a, 0xb5, + 0x29, 0xbd, 0x77, 0x85, 0xf0, 0x8c, 0x88, 0xba, 0x01, 0xb9, 0xae, 0xad, 0xfb, 0x7b, 0xd4, 0x1d, + 0x22, 0x15, 0x8a, 0xba, 0x6b, 0xec, 0x5b, 0x3e, 0x31, 0xfc, 0xb1, 0x1b, 0xec, 0x93, 0x19, 0x1a, + 0xba, 0x01, 0x49, 0x2a, 0x3a, 0xca, 0xd7, 0xb2, 0x67, 0xa7, 0x6b, 0xc9, 0x4e, 0x0f, 0x27, 0xa9, + 0xa7, 0x3e, 0x84, 0x6b, 0x5d, 0x7b, 0x3c, 0xb0, 0x9c, 0x06, 0xf1, 0x0c, 0xd7, 0x1a, 0x31, 0xed, + 0x6c, 0x39, 0xb1, 0x68, 0x12, 0x2c, 0x27, 0xf6, 0x1d, 0x6e, 0xc2, 0xe4, 0x74, 0x13, 0xaa, 0xbf, + 0x99, 0x84, 0x6b, 0x4d, 0x67, 0x60, 0x39, 0x24, 0x2a, 0x7d, 0x1b, 0x16, 0x09, 0x27, 0x6a, 0x87, + 0x22, 0x30, 0x48, 0x3d, 0x0b, 0x82, 0x1a, 0x44, 0x8b, 0xd6, 0xb9, 0x1d, 0x7c, 0x37, 0x6e, 0xf8, + 0x2f, 0x68, 0x8f, 0xdd, 0xc7, 0x4d, 0x98, 0x1f, 0xf1, 0x41, 0x78, 0x72, 0x7a, 0x6f, 0xc7, 0xe9, + 0x7a, 0x61, 0x9c, 0xc1, 0x76, 0x96, 0xb2, 0xdf, 0x66, 0x3b, 0xff, 0x71, 0x12, 0x96, 0xda, 0xd4, + 0x9c, 0xf1, 0x43, 0x09, 0x72, 0xfb, 0xd4, 0xf3, 0x23, 0xa1, 0x2b, 0x6c, 0xa3, 0xfb, 0x90, 0x1b, + 0xc9, 0xe9, 0x93, 0xb3, 0x7f, 0x2b, 0xde, 0x64, 0x81, 0xc1, 0x21, 0x1a, 0x3d, 0x84, 0x7c, 0xb0, + 0x65, 0xd8, 0x68, 0x5f, 0x62, 0xe1, 0x4c, 0xf1, 0xe8, 0x63, 0xc8, 0x8a, 0x49, 0x58, 0x49, 0x73, + 0xc9, 0xdb, 0x2f, 0xe5, 0x73, 0x2c, 0x85, 0xd0, 0x23, 0xc8, 0xf9, 0xb6, 0xa7, 0x59, 0xce, 0x1e, + 0x5d, 0xc9, 0x70, 0x05, 0x6b, 0x71, 0x0a, 0x98, 0x23, 0xfa, 0x5b, 0xbd, 0x96, 0xb3, 0x47, 0x6b, + 0x85, 0xb3, 0xd3, 0xb5, 0x79, 0xd9, 0xc0, 0xf3, 0xbe, 0xed, 0xb1, 0x0f, 0xf5, 0x77, 0x12, 0x50, + 0x88, 0xa0, 0xd0, 0xab, 0x00, 0xbe, 0x3b, 0xf6, 0x7c, 0xcd, 0xa5, 0xd4, 0xe7, 0xce, 0x2a, 0xe2, + 0x3c, 0xa7, 0x60, 0x4a, 0x7d, 0x54, 0x81, 0xeb, 0x06, 0x71, 0x7d, 0xcd, 0xf2, 0xbc, 0x31, 0x71, + 0x35, 0x6f, 0xbc, 0xfb, 0x05, 0x31, 0x7c, 0xee, 0xb8, 0x22, 0xbe, 0xc6, 0x58, 0x2d, 0xce, 0xe9, + 0x09, 0x06, 0xba, 0x07, 0x37, 0xa2, 0xf8, 0xd1, 0x78, 0xd7, 0xb6, 0x0c, 0x8d, 0x4d, 0x66, 0x8a, + 0x8b, 0x5c, 0x9f, 0x8a, 0x74, 0x39, 0xef, 0x31, 0x99, 0xa8, 0x3f, 0x4d, 0x80, 0x82, 0xf5, 0x3d, + 0x7f, 0x9b, 0x0c, 0x77, 0x89, 0xdb, 0xf3, 0x75, 0x7f, 0xec, 0xa1, 0x1b, 0x90, 0xb5, 0x89, 0x6e, + 0x12, 0x11, 0x1d, 0x73, 0x58, 0xb6, 0xd0, 0x0e, 0xdb, 0xc1, 0xba, 0xb1, 0xaf, 0xef, 0x5a, 0xb6, + 0xe5, 0x4f, 0xb8, 0x29, 0x8b, 0xf1, 0x4b, 0xf8, 0xbc, 0xce, 0x0a, 0x8e, 0x08, 0xe2, 0x19, 0x35, + 0x68, 0x05, 0xe6, 0x87, 0xc4, 0xf3, 0xf4, 0x01, 0xe1, 0x96, 0xe6, 0x71, 0xd0, 0x54, 0x1f, 0x42, + 0x31, 0x2a, 0x87, 0x0a, 0x30, 0xbf, 0xd3, 0x7e, 0xdc, 0xee, 0x3c, 0x6d, 0x2b, 0x73, 0x68, 0x09, + 0x0a, 0x3b, 0x6d, 0xdc, 0xac, 0xd6, 0x37, 0xab, 0xb5, 0xad, 0xa6, 0x92, 0x40, 0x0b, 0x90, 0x9f, + 0x36, 0x93, 0xea, 0x9f, 0x26, 0x00, 0x98, 0xbb, 0xe5, 0xa0, 0x3e, 0x82, 0x8c, 0xe7, 0xeb, 0xbe, + 0x58, 0x95, 0x8b, 0xeb, 0x6f, 0x5c, 0x34, 0x87, 0xd2, 0x5e, 0xf6, 0x8f, 0x60, 0x21, 0x12, 0xb5, + 0x30, 0x39, 0x63, 0x21, 0x0b, 0x10, 0xba, 0x69, 0xba, 0xd2, 0x70, 0xfe, 0xad, 0x3e, 0x84, 0x0c, + 0x97, 0x9e, 0x35, 0x37, 0x07, 0xe9, 0x06, 0xfb, 0x4a, 0xa0, 0x3c, 0x64, 0x70, 0xb3, 0xda, 0xf8, + 0x5c, 0x49, 0x22, 0x05, 0x8a, 0x8d, 0x56, 0xaf, 0xde, 0x69, 0xb7, 0x9b, 0xf5, 0x7e, 0xb3, 0xa1, + 0xa4, 0xd4, 0xdb, 0x90, 0x69, 0x0d, 0x99, 0xe6, 0x5b, 0x6c, 0xc9, 0xef, 0x11, 0x97, 0x38, 0x46, + 0xb0, 0x93, 0xa6, 0x04, 0xf5, 0x27, 0x79, 0xc8, 0x6c, 0xd3, 0xb1, 0xe3, 0xa3, 0xf5, 0x48, 0xd8, + 0x5a, 0x8c, 0x3f, 0xcb, 0x39, 0xb0, 0xd2, 0x9f, 0x8c, 0x88, 0x0c, 0x6b, 0x37, 0x20, 0x2b, 0x36, + 0x87, 0x1c, 0x8e, 0x6c, 0x31, 0xba, 0xaf, 0xbb, 0x03, 0xe2, 0xcb, 0xf1, 0xc8, 0x16, 0x7a, 0x8b, + 0x9d, 0x58, 0xba, 0x49, 0x1d, 0x7b, 0xc2, 0xf7, 0x50, 0x4e, 0x1c, 0x4b, 0x98, 0xe8, 0x66, 0xc7, + 0xb1, 0x27, 0x38, 0xe4, 0xa2, 0x4d, 0x28, 0xee, 0x5a, 0x8e, 0xa9, 0xd1, 0x91, 0x08, 0xf2, 0x99, + 0x8b, 0x77, 0x9c, 0xb0, 0xaa, 0x66, 0x39, 0x66, 0x47, 0x80, 0x71, 0x61, 0x77, 0xda, 0x40, 0x6d, + 0x58, 0x3c, 0xa4, 0xf6, 0x78, 0x48, 0x42, 0x5d, 0x59, 0xae, 0xeb, 0xcd, 0x8b, 0x75, 0x3d, 0xe1, + 0xf8, 0x40, 0xdb, 0xc2, 0x61, 0xb4, 0x89, 0x1e, 0xc3, 0x82, 0x3f, 0x1c, 0xed, 0x79, 0xa1, 0xba, + 0x79, 0xae, 0xee, 0x7b, 0x97, 0x38, 0x8c, 0xc1, 0x03, 0x6d, 0x45, 0x3f, 0xd2, 0x2a, 0xfd, 0x7a, + 0x0a, 0x0a, 0x11, 0xcb, 0x51, 0x0f, 0x0a, 0x23, 0x97, 0x8e, 0xf4, 0x01, 0x3f, 0xa8, 0xe4, 0x5c, + 0xdc, 0x7d, 0xa9, 0x51, 0x57, 0xba, 0x53, 0x41, 0x1c, 0xd5, 0xa2, 0x9e, 0x24, 0xa1, 0x10, 0x61, + 0xa2, 0x77, 0x20, 0x87, 0xbb, 0xb8, 0xf5, 0xa4, 0xda, 0x6f, 0x2a, 0x73, 0xa5, 0x5b, 0xc7, 0x27, + 0xe5, 0x15, 0xae, 0x2d, 0xaa, 0xa0, 0xeb, 0x5a, 0x87, 0x6c, 0xe9, 0xbd, 0x05, 0xf3, 0x01, 0x34, + 0x51, 0x7a, 0xe5, 0xf8, 0xa4, 0xfc, 0xdd, 0xf3, 0xd0, 0x08, 0x12, 0xf7, 0x36, 0xab, 0xb8, 0xd9, + 0x50, 0x92, 0xf1, 0x48, 0xdc, 0xdb, 0xd7, 0x5d, 0x62, 0xa2, 0xef, 0x41, 0x56, 0x02, 0x53, 0xa5, + 0xd2, 0xf1, 0x49, 0xf9, 0xc6, 0x79, 0xe0, 0x14, 0x87, 0x7b, 0x5b, 0xd5, 0x27, 0x4d, 0x25, 0x1d, + 0x8f, 0xc3, 0x3d, 0x5b, 0x3f, 0x24, 0xe8, 0x0d, 0xc8, 0x08, 0x58, 0xa6, 0x74, 0xf3, 0xf8, 0xa4, + 0xfc, 0x9d, 0x17, 0xd4, 0x31, 0x54, 0x69, 0xe5, 0xb7, 0xfe, 0x60, 0x75, 0xee, 0x2f, 0xff, 0x70, + 0x55, 0x39, 0xcf, 0x2e, 0xfd, 0x77, 0x02, 0x16, 0x66, 0xa6, 0x1c, 0xa9, 0x90, 0x75, 0xa8, 0x41, + 0x47, 0xe2, 0xfc, 0xca, 0xd5, 0xe0, 0xec, 0x74, 0x2d, 0xdb, 0xa6, 0x75, 0x3a, 0x9a, 0x60, 0xc9, + 0x41, 0x8f, 0xcf, 0x9d, 0xc0, 0xf7, 0x5e, 0x72, 0x3d, 0xc5, 0x9e, 0xc1, 0x9f, 0xc2, 0x82, 0xe9, + 0x5a, 0x87, 0xc4, 0xd5, 0x0c, 0xea, 0xec, 0x59, 0x03, 0x79, 0x36, 0x95, 0xe2, 0x74, 0x36, 0x38, + 0x10, 0x17, 0x85, 0x40, 0x9d, 0xe3, 0xbf, 0xc5, 0xe9, 0x5b, 0x7a, 0x02, 0xc5, 0xe8, 0x0a, 0x65, + 0xc7, 0x89, 0x67, 0xfd, 0x32, 0x91, 0xf9, 0x20, 0xcf, 0x1e, 0x71, 0x9e, 0x51, 0x44, 0x36, 0xf8, + 0x26, 0xa4, 0x87, 0xd4, 0x14, 0x7a, 0x16, 0x6a, 0xd7, 0x59, 0x12, 0xf0, 0x4f, 0xa7, 0x6b, 0x05, + 0xea, 0x55, 0x36, 0x2c, 0x9b, 0x6c, 0x53, 0x93, 0x60, 0x0e, 0x50, 0x0f, 0x21, 0xcd, 0x42, 0x05, + 0x7a, 0x05, 0xd2, 0xb5, 0x56, 0xbb, 0xa1, 0xcc, 0x95, 0xae, 0x1d, 0x9f, 0x94, 0x17, 0xb8, 0x4b, + 0x18, 0x83, 0xad, 0x5d, 0xb4, 0x06, 0xd9, 0x27, 0x9d, 0xad, 0x9d, 0x6d, 0xb6, 0xbc, 0xae, 0x1f, + 0x9f, 0x94, 0x97, 0x42, 0xb6, 0x70, 0x1a, 0x7a, 0x15, 0x32, 0xfd, 0xed, 0xee, 0x46, 0x4f, 0x49, + 0x96, 0xd0, 0xf1, 0x49, 0x79, 0x31, 0xe4, 0x73, 0x9b, 0x4b, 0xd7, 0xe4, 0xac, 0xe6, 0x43, 0xba, + 0xfa, 0xb3, 0x24, 0x2c, 0x60, 0x56, 0x9b, 0xb9, 0x7e, 0x97, 0xda, 0x96, 0x31, 0x41, 0x5d, 0xc8, + 0x1b, 0xd4, 0x31, 0xad, 0xc8, 0x9e, 0x5a, 0xbf, 0xe0, 0xd4, 0x9f, 0x4a, 0x05, 0xad, 0x7a, 0x20, + 0x89, 0xa7, 0x4a, 0xd0, 0x7b, 0x90, 0x31, 0x89, 0xad, 0x4f, 0x64, 0xfa, 0x71, 0xb3, 0x22, 0xaa, + 0xbf, 0x4a, 0x50, 0xfd, 0x55, 0x1a, 0xb2, 0xfa, 0xc3, 0x02, 0xc7, 0xd3, 0x6c, 0xfd, 0x99, 0xa6, + 0xfb, 0x3e, 0x19, 0x8e, 0x7c, 0x91, 0x7b, 0xa4, 0x71, 0x61, 0xa8, 0x3f, 0xab, 0x4a, 0x12, 0xba, + 0x0b, 0xd9, 0x23, 0xcb, 0x31, 0xe9, 0x91, 0x4c, 0x2f, 0x2e, 0x51, 0x2a, 0x81, 0xea, 0x31, 0x3b, + 0x75, 0xcf, 0x99, 0xc9, 0xfc, 0xdd, 0xee, 0xb4, 0x9b, 0x81, 0xbf, 0x25, 0xbf, 0xe3, 0xb4, 0xa9, + 0xc3, 0xf6, 0x0a, 0x74, 0xda, 0xda, 0x46, 0xb5, 0xb5, 0xb5, 0x83, 0x99, 0xcf, 0x97, 0x8f, 0x4f, + 0xca, 0x4a, 0x08, 0xd9, 0xd0, 0x2d, 0x9b, 0xe5, 0xbb, 0x37, 0x21, 0x55, 0x6d, 0x7f, 0xae, 0x24, + 0x4b, 0xca, 0xf1, 0x49, 0xb9, 0x18, 0xb2, 0xab, 0xce, 0x64, 0xba, 0x8d, 0xce, 0xf7, 0xab, 0xfe, + 0x6d, 0x0a, 0x8a, 0x3b, 0x23, 0x53, 0xf7, 0x89, 0x58, 0x93, 0xa8, 0x0c, 0x85, 0x91, 0xee, 0xea, + 0xb6, 0x4d, 0x6c, 0xcb, 0x1b, 0xca, 0xba, 0x36, 0x4a, 0x42, 0x0f, 0x5e, 0xd6, 0x8d, 0xb5, 0x1c, + 0x5b, 0x67, 0x3f, 0xfe, 0x97, 0xb5, 0x44, 0xe0, 0xd0, 0x1d, 0x58, 0xdc, 0x13, 0xd6, 0x6a, 0xba, + 0xc1, 0x27, 0x36, 0xc5, 0x27, 0xb6, 0x12, 0x37, 0xb1, 0x51, 0xb3, 0x2a, 0x72, 0x90, 0x55, 0x2e, + 0x85, 0x17, 0xf6, 0xa2, 0x4d, 0x74, 0x0f, 0xe6, 0x87, 0xd4, 0xb1, 0x7c, 0xea, 0x5e, 0x3d, 0x0b, + 0x01, 0x12, 0xbd, 0x03, 0xd7, 0xd8, 0xe4, 0x06, 0xf6, 0x70, 0x36, 0x3f, 0xb1, 0x92, 0x78, 0x69, + 0xa8, 0x3f, 0x93, 0x1d, 0x62, 0x46, 0x46, 0x35, 0xc8, 0x50, 0x97, 0xa5, 0x44, 0x59, 0x6e, 0xee, + 0xbb, 0x57, 0x9a, 0x2b, 0x1a, 0x1d, 0x26, 0x83, 0x85, 0xa8, 0xfa, 0x21, 0x2c, 0xcc, 0x0c, 0x82, + 0x65, 0x02, 0xdd, 0xea, 0x4e, 0xaf, 0xa9, 0xcc, 0xa1, 0x22, 0xe4, 0xea, 0x9d, 0x76, 0xbf, 0xd5, + 0xde, 0x61, 0xa9, 0x4c, 0x11, 0x72, 0xb8, 0xb3, 0xb5, 0x55, 0xab, 0xd6, 0x1f, 0x2b, 0x49, 0xb5, + 0x02, 0x85, 0x88, 0x36, 0xb4, 0x08, 0xd0, 0xeb, 0x77, 0xba, 0xda, 0x46, 0x0b, 0xf7, 0xfa, 0x22, + 0x11, 0xea, 0xf5, 0xab, 0xb8, 0x2f, 0x09, 0x09, 0xf5, 0x3f, 0x92, 0xc1, 0x8c, 0xca, 0xdc, 0xa7, + 0x36, 0x9b, 0xfb, 0x5c, 0x62, 0xbc, 0xcc, 0x7e, 0xa6, 0x8d, 0x30, 0x07, 0x7a, 0x00, 0xc0, 0x17, + 0x0e, 0x31, 0x35, 0xdd, 0x97, 0x13, 0x5f, 0x7a, 0xc1, 0xc9, 0xfd, 0xe0, 0x7a, 0x05, 0xe7, 0x25, + 0xba, 0xea, 0xa3, 0x8f, 0xa1, 0x68, 0xd0, 0xe1, 0xc8, 0x26, 0x52, 0x38, 0x75, 0xa5, 0x70, 0x21, + 0xc4, 0x57, 0xfd, 0x68, 0xf6, 0x95, 0x9e, 0xcd, 0x0f, 0x7f, 0x23, 0x11, 0x78, 0x26, 0x26, 0xe1, + 0x2a, 0x42, 0x6e, 0xa7, 0xdb, 0xa8, 0xf6, 0x5b, 0xed, 0x47, 0x4a, 0x02, 0x01, 0x64, 0xb9, 0xab, + 0x1b, 0x4a, 0x92, 0x25, 0x8a, 0xf5, 0xce, 0x76, 0x77, 0xab, 0xc9, 0x53, 0x2e, 0xb4, 0x0c, 0x4a, + 0xe0, 0x6c, 0x8d, 0x3b, 0xb2, 0xd9, 0x50, 0xd2, 0xe8, 0x3a, 0x2c, 0x85, 0x54, 0x29, 0x99, 0x41, + 0x37, 0x00, 0x85, 0xc4, 0xa9, 0x8a, 0xac, 0xfa, 0xab, 0xb0, 0x54, 0xa7, 0x8e, 0xaf, 0x5b, 0x4e, + 0x98, 0x44, 0xaf, 0xb3, 0x41, 0x4b, 0x92, 0x66, 0xc9, 0x5b, 0x8a, 0xda, 0xd2, 0xd9, 0xe9, 0x5a, + 0x21, 0x84, 0xb6, 0x1a, 0x6c, 0xa4, 0x41, 0xc3, 0x64, 0xfb, 0x77, 0x64, 0x99, 0xdc, 0xb9, 0x99, + 0xda, 0xfc, 0xd9, 0xe9, 0x5a, 0xaa, 0xdb, 0x6a, 0x60, 0x46, 0x43, 0xaf, 0x40, 0x9e, 0x3c, 0xb3, + 0x7c, 0xcd, 0x60, 0x31, 0x9c, 0x39, 0x30, 0x83, 0x73, 0x8c, 0x50, 0x67, 0x21, 0xbb, 0x06, 0xd0, + 0xa5, 0xae, 0x2f, 0x7b, 0x7e, 0x1f, 0x32, 0x23, 0xea, 0xf2, 0xf2, 0xfc, 0xc2, 0xeb, 0x1d, 0x06, + 0x17, 0x0b, 0x15, 0x0b, 0xb0, 0xfa, 0x57, 0x49, 0x80, 0xbe, 0xee, 0x1d, 0x48, 0x25, 0xf7, 0x21, + 0x1f, 0x5e, 0x95, 0xc9, 0x3a, 0xff, 0xd2, 0xd9, 0x0e, 0xc1, 0xe8, 0x5e, 0xb0, 0xd8, 0x44, 0x79, + 0x10, 0x5b, 0xa7, 0x05, 0x1d, 0xc5, 0x65, 0xd8, 0xb3, 0x35, 0x00, 0x3b, 0x12, 0x89, 0xeb, 0xca, + 0x99, 0x67, 0x9f, 0xa8, 0xce, 0x8f, 0x05, 0xe1, 0x34, 0x99, 0x60, 0xc6, 0xde, 0x6c, 0x9c, 0x9b, + 0x91, 0xcd, 0x39, 0x3c, 0x95, 0x43, 0x9f, 0x42, 0x81, 0x8d, 0x5b, 0xf3, 0x38, 0x4f, 0xe6, 0x96, + 0x17, 0xba, 0x4a, 0x68, 0xc0, 0x30, 0x0a, 0xbf, 0x6b, 0x0a, 0x2c, 0xba, 0x63, 0x87, 0x0d, 0x5b, + 0xea, 0x50, 0xff, 0x24, 0x09, 0xdf, 0x6d, 0x13, 0xff, 0x88, 0xba, 0x07, 0x55, 0xdf, 0xd7, 0x8d, + 0xfd, 0x21, 0x71, 0xa4, 0x93, 0x23, 0x99, 0x75, 0x62, 0x26, 0xb3, 0x5e, 0x81, 0x79, 0xdd, 0xb6, + 0x74, 0x8f, 0x88, 0x74, 0x24, 0x8f, 0x83, 0x26, 0xcb, 0xff, 0x59, 0x35, 0x41, 0x3c, 0x8f, 0x88, + 0x02, 0x3f, 0x8f, 0xa7, 0x04, 0xf4, 0x23, 0xb8, 0x21, 0x13, 0x0f, 0x3d, 0xec, 0x8a, 0x65, 0xb6, + 0xc1, 0x9d, 0x5e, 0x33, 0xb6, 0xbc, 0x89, 0x37, 0x4e, 0x66, 0x26, 0x53, 0x72, 0x67, 0xe4, 0xcb, + 0x3c, 0x67, 0xd9, 0x8c, 0x61, 0x95, 0x1e, 0xc1, 0xcd, 0x0b, 0x45, 0xbe, 0xd1, 0x05, 0xc2, 0x3f, + 0x24, 0x01, 0x5a, 0xdd, 0xea, 0xb6, 0x74, 0x52, 0x03, 0xb2, 0x7b, 0xfa, 0xd0, 0xb2, 0x27, 0x97, + 0xc5, 0xa9, 0x29, 0xbe, 0x52, 0x15, 0xee, 0xd8, 0xe0, 0x32, 0x58, 0xca, 0xf2, 0xe2, 0x66, 0xbc, + 0xeb, 0x10, 0x3f, 0x2c, 0x6e, 0x78, 0x8b, 0x99, 0xe1, 0xea, 0x4e, 0xb8, 0xc0, 0x44, 0x83, 0x4d, + 0xc0, 0x40, 0xf7, 0xc9, 0x91, 0x3e, 0x09, 0x82, 0x8b, 0x6c, 0xa2, 0x4d, 0x7e, 0x4d, 0x47, 0xdc, + 0x43, 0x62, 0xae, 0x64, 0xb8, 0x53, 0xaf, 0xb2, 0x07, 0x4b, 0xb8, 0xf0, 0x5d, 0x28, 0x5d, 0x7a, + 0xc8, 0x13, 0x9b, 0x29, 0xeb, 0x1b, 0xf9, 0xe8, 0x0e, 0x2c, 0xcc, 0x8c, 0xf3, 0x85, 0xaa, 0xb2, + 0xd5, 0x7d, 0xf2, 0xbe, 0x92, 0x96, 0x5f, 0x1f, 0x2a, 0x59, 0xf5, 0x8f, 0x52, 0x22, 0x1c, 0x48, + 0xaf, 0xc6, 0x5f, 0x24, 0xe7, 0xf8, 0x26, 0x36, 0xa8, 0x2d, 0xb7, 0xe9, 0x9b, 0x97, 0x47, 0x09, + 0x56, 0xa5, 0x70, 0x38, 0x0e, 0x05, 0xd1, 0x1a, 0x14, 0xc4, 0x2a, 0xd6, 0xd8, 0xb6, 0xe0, 0x6e, + 0x5d, 0xc0, 0x20, 0x48, 0x4c, 0x12, 0xdd, 0x86, 0x45, 0x7e, 0x0b, 0xe1, 0xed, 0x13, 0x53, 0x60, + 0xd2, 0x1c, 0xb3, 0x10, 0x52, 0x39, 0x6c, 0x1b, 0x8a, 0x92, 0xa0, 0xf1, 0x0c, 0x35, 0xc3, 0x0d, + 0x7a, 0xe7, 0x2a, 0x83, 0x84, 0x08, 0x4f, 0x5c, 0x0b, 0xa3, 0x69, 0x43, 0x6d, 0x40, 0x2e, 0x30, + 0x16, 0xad, 0x40, 0xaa, 0x5f, 0xef, 0x2a, 0x73, 0xa5, 0xa5, 0xe3, 0x93, 0x72, 0x21, 0x20, 0xf7, + 0xeb, 0x5d, 0xc6, 0xd9, 0x69, 0x74, 0x95, 0xc4, 0x2c, 0x67, 0xa7, 0xd1, 0x2d, 0xa5, 0x59, 0xa6, + 0xa4, 0xee, 0x41, 0x21, 0xd2, 0x03, 0x7a, 0x1d, 0xe6, 0x5b, 0xed, 0x47, 0xb8, 0xd9, 0xeb, 0x29, + 0x73, 0xa5, 0x1b, 0xc7, 0x27, 0x65, 0x14, 0xe1, 0xb6, 0x9c, 0x01, 0x9b, 0x1f, 0xf4, 0x2a, 0xa4, + 0x37, 0x3b, 0xec, 0x04, 0x16, 0x29, 0x71, 0x04, 0xb1, 0x49, 0x3d, 0xbf, 0x74, 0x5d, 0xa6, 0x60, + 0x51, 0xc5, 0xea, 0xef, 0x25, 0x20, 0x2b, 0x36, 0x53, 0xec, 0x44, 0x55, 0x61, 0x3e, 0xa8, 0x57, + 0x45, 0xb9, 0xf2, 0xe6, 0xc5, 0xa5, 0x45, 0x45, 0x56, 0x02, 0x62, 0xf9, 0x05, 0x72, 0xa5, 0x8f, + 0xa0, 0x18, 0x65, 0x7c, 0xa3, 0xc5, 0xf7, 0x23, 0x28, 0xb0, 0xf5, 0x1d, 0x94, 0x18, 0xeb, 0x90, + 0x15, 0x01, 0x21, 0x3c, 0x11, 0x2e, 0xae, 0x73, 0x24, 0x12, 0xdd, 0x87, 0x79, 0x51, 0x1b, 0x05, + 0xd7, 0x94, 0xab, 0x97, 0xef, 0x22, 0x1c, 0xc0, 0xd5, 0x4f, 0x21, 0xdd, 0x25, 0xc4, 0x65, 0xbe, + 0x77, 0xa8, 0x49, 0xa6, 0x87, 0xa8, 0x2c, 0xeb, 0x4c, 0xd2, 0x6a, 0xb0, 0xb2, 0xce, 0x24, 0x2d, + 0x33, 0xbc, 0x88, 0x49, 0x46, 0x2e, 0x62, 0xfa, 0x50, 0x7c, 0x4a, 0xac, 0xc1, 0xbe, 0x4f, 0x4c, + 0xae, 0xe8, 0x5d, 0x48, 0x8f, 0x48, 0x68, 0xfc, 0x4a, 0xec, 0x02, 0x23, 0xc4, 0xc5, 0x1c, 0xc5, + 0xe2, 0xc8, 0x11, 0x97, 0x96, 0x77, 0xeb, 0xb2, 0xa5, 0xfe, 0x7d, 0x12, 0x16, 0x5b, 0x9e, 0x37, + 0xd6, 0x1d, 0x23, 0xc8, 0xaf, 0x3e, 0x99, 0xcd, 0xaf, 0xde, 0x8a, 0x1d, 0xe1, 0x8c, 0xc8, 0xec, + 0xfd, 0x92, 0x3c, 0xe3, 0x92, 0xe1, 0x19, 0xa7, 0xfe, 0x7b, 0x22, 0xb8, 0x44, 0xba, 0x1d, 0xd9, + 0xee, 0xa5, 0x95, 0xe3, 0x93, 0xf2, 0x72, 0x54, 0x13, 0xd9, 0x71, 0x0e, 0x1c, 0x7a, 0xe4, 0xa0, + 0xd7, 0x20, 0x83, 0x9b, 0xed, 0xe6, 0x53, 0x25, 0x21, 0x96, 0xe7, 0x0c, 0x08, 0x13, 0x87, 0x1c, + 0x31, 0x4d, 0xdd, 0x66, 0xbb, 0xc1, 0xf2, 0xa1, 0x64, 0x8c, 0xa6, 0x2e, 0x71, 0x4c, 0xcb, 0x19, + 0xa0, 0xd7, 0x21, 0xdb, 0xea, 0xf5, 0x76, 0x78, 0x99, 0xff, 0xdd, 0xe3, 0x93, 0xf2, 0xf5, 0x19, + 0x14, 0xbf, 0x40, 0x34, 0x19, 0x88, 0x15, 0x23, 0x2c, 0x53, 0x8a, 0x01, 0xb1, 0x2c, 0x57, 0x80, + 0x70, 0xa7, 0x5f, 0xed, 0xb3, 0x0a, 0xff, 0x45, 0x10, 0xa6, 0xec, 0xaf, 0xdc, 0x6e, 0xff, 0x9c, + 0x04, 0xa5, 0x6a, 0x18, 0x64, 0xe4, 0x33, 0xbe, 0xac, 0xff, 0xfa, 0x90, 0x1b, 0xb1, 0x2f, 0x8b, + 0x04, 0xb9, 0xcc, 0xfd, 0xd8, 0x07, 0xaf, 0x73, 0x72, 0x15, 0x4c, 0x6d, 0x52, 0x35, 0x87, 0x96, + 0xe7, 0x59, 0xd4, 0x11, 0x34, 0x1c, 0x6a, 0x2a, 0xfd, 0x67, 0x02, 0xae, 0xc7, 0x20, 0xd0, 0x1d, + 0x48, 0xbb, 0xd4, 0x0e, 0xe6, 0xf0, 0xd6, 0x45, 0xf7, 0x83, 0x4c, 0x14, 0x73, 0x24, 0x5a, 0x05, + 0xd0, 0xc7, 0x3e, 0xd5, 0x79, 0xff, 0x7c, 0xf6, 0x72, 0x38, 0x42, 0x41, 0x4f, 0x21, 0xeb, 0x11, + 0xc3, 0x25, 0x41, 0xc6, 0xfb, 0xe9, 0xff, 0xd5, 0xfa, 0x4a, 0x8f, 0xab, 0xc1, 0x52, 0x5d, 0xa9, + 0x02, 0x59, 0x41, 0x61, 0xcb, 0xde, 0xd4, 0x7d, 0x5d, 0xde, 0x1e, 0xf3, 0x6f, 0xb6, 0x9a, 0x74, + 0x7b, 0x10, 0xac, 0x26, 0xdd, 0x1e, 0xa8, 0x7f, 0x93, 0x04, 0x68, 0x3e, 0xf3, 0x89, 0xeb, 0xe8, + 0x76, 0xbd, 0x8a, 0x9a, 0x91, 0xe8, 0x2f, 0x46, 0xfb, 0x76, 0xec, 0x95, 0x78, 0x28, 0x51, 0xa9, + 0x57, 0x63, 0xe2, 0xff, 0x4d, 0x48, 0x8d, 0x5d, 0xf9, 0x86, 0x29, 0xb2, 0xd5, 0x1d, 0xbc, 0x85, + 0x19, 0x0d, 0x35, 0xa7, 0x61, 0x2b, 0x75, 0xf1, 0x4b, 0x65, 0xa4, 0x83, 0xd8, 0xd0, 0xc5, 0x76, + 0xbe, 0xa1, 0x6b, 0x06, 0x91, 0x27, 0x47, 0x51, 0xec, 0xfc, 0x7a, 0xb5, 0x4e, 0x5c, 0x1f, 0x67, + 0x0d, 0x9d, 0xfd, 0xff, 0x56, 0xf1, 0xed, 0x5d, 0x80, 0xe9, 0xd0, 0xd0, 0x2a, 0x64, 0xea, 0x1b, + 0xbd, 0xde, 0x96, 0x32, 0x27, 0x02, 0xf8, 0x94, 0xc5, 0xc9, 0xea, 0x5f, 0x24, 0x21, 0x57, 0xaf, + 0xca, 0x63, 0xb5, 0x0e, 0x0a, 0x8f, 0x4a, 0xfc, 0xce, 0x9d, 0x3c, 0x1b, 0x59, 0xee, 0x44, 0x06, + 0x96, 0x4b, 0x4a, 0xcf, 0x45, 0x26, 0xc2, 0xac, 0x6e, 0x72, 0x01, 0x84, 0xa1, 0x48, 0xa4, 0x13, + 0x34, 0x43, 0x0f, 0x62, 0xfc, 0xea, 0xe5, 0xce, 0x12, 0x45, 0xc4, 0xb4, 0xed, 0xe1, 0x42, 0xa0, + 0xa4, 0xae, 0x7b, 0xe8, 0x01, 0x2c, 0x79, 0xd6, 0xc0, 0xb1, 0x9c, 0x81, 0x16, 0x38, 0x8f, 0x3f, + 0x00, 0xd4, 0xae, 0x9d, 0x9d, 0xae, 0x2d, 0xf4, 0x04, 0x4b, 0xfa, 0x70, 0x41, 0x22, 0xeb, 0xdc, + 0x95, 0xe8, 0x43, 0x58, 0x8c, 0x88, 0x32, 0x2f, 0x0a, 0xb7, 0x2b, 0x67, 0xa7, 0x6b, 0xc5, 0x50, + 0xf2, 0x31, 0x99, 0xe0, 0x62, 0x28, 0xf8, 0x98, 0xf0, 0x5b, 0x92, 0x3d, 0xea, 0x1a, 0x44, 0x73, + 0xf9, 0x9e, 0xe6, 0x27, 0x78, 0x1a, 0x17, 0x38, 0x4d, 0x6c, 0x73, 0xf5, 0x09, 0x5c, 0xef, 0xb8, + 0xc6, 0x3e, 0xf1, 0x7c, 0xe1, 0x0a, 0xe9, 0xc5, 0x4f, 0xe1, 0x96, 0xaf, 0x7b, 0x07, 0xda, 0xbe, + 0xe5, 0xf9, 0xd4, 0x9d, 0x68, 0x2e, 0xf1, 0x89, 0xc3, 0xf8, 0x1a, 0x7f, 0x35, 0x94, 0xd7, 0x58, + 0x37, 0x19, 0x66, 0x53, 0x40, 0x70, 0x80, 0xd8, 0x62, 0x00, 0xb5, 0x05, 0x45, 0x56, 0x4c, 0x34, + 0xc8, 0x9e, 0x3e, 0xb6, 0x7d, 0x36, 0x7a, 0xb0, 0xe9, 0x40, 0x7b, 0xe9, 0x63, 0x2a, 0x6f, 0xd3, + 0x81, 0xf8, 0x54, 0x7f, 0x08, 0x4a, 0xc3, 0xf2, 0x46, 0xba, 0x6f, 0xec, 0x07, 0xf7, 0x73, 0xa8, + 0x01, 0xca, 0x3e, 0xd1, 0x5d, 0x7f, 0x97, 0xe8, 0xbe, 0x36, 0x22, 0xae, 0x45, 0xcd, 0xab, 0x67, + 0x79, 0x29, 0x14, 0xe9, 0x72, 0x09, 0xf5, 0xbf, 0x12, 0x00, 0x58, 0xdf, 0x0b, 0x32, 0xb2, 0xef, + 0xc3, 0x35, 0xcf, 0xd1, 0x47, 0xde, 0x3e, 0xf5, 0x35, 0xcb, 0xf1, 0x89, 0x7b, 0xa8, 0xdb, 0xf2, + 0x9a, 0x45, 0x09, 0x18, 0x2d, 0x49, 0x47, 0xef, 0x02, 0x3a, 0x20, 0x64, 0xa4, 0x51, 0xdb, 0xd4, + 0x02, 0xa6, 0x78, 0xd3, 0x4c, 0x63, 0x85, 0x71, 0x3a, 0xb6, 0xd9, 0x0b, 0xe8, 0xa8, 0x06, 0xab, + 0x6c, 0xf8, 0xc4, 0xf1, 0x5d, 0x8b, 0x78, 0xda, 0x1e, 0x75, 0x35, 0xcf, 0xa6, 0x47, 0xda, 0x1e, + 0xb5, 0x6d, 0x7a, 0x44, 0xdc, 0xe0, 0x06, 0xab, 0x64, 0xd3, 0x41, 0x53, 0x80, 0x36, 0xa8, 0xdb, + 0xb3, 0xe9, 0xd1, 0x46, 0x80, 0x60, 0x69, 0xdb, 0x74, 0xcc, 0xbe, 0x65, 0x1c, 0x04, 0x69, 0x5b, + 0x48, 0xed, 0x5b, 0xc6, 0x01, 0x7a, 0x1d, 0x16, 0x88, 0x4d, 0xf8, 0x45, 0x86, 0x40, 0x65, 0x38, + 0xaa, 0x18, 0x10, 0x19, 0x48, 0xfd, 0x0c, 0x94, 0xa6, 0x63, 0xb8, 0x93, 0x51, 0x64, 0xce, 0xdf, + 0x05, 0xc4, 0x82, 0xa4, 0x66, 0x53, 0xe3, 0x40, 0x1b, 0xea, 0x8e, 0x3e, 0x60, 0x76, 0x89, 0xa7, + 0x26, 0x85, 0x71, 0xb6, 0xa8, 0x71, 0xb0, 0x2d, 0xe9, 0xea, 0x03, 0x80, 0xde, 0xc8, 0x25, 0xba, + 0xd9, 0x61, 0xd9, 0x04, 0x73, 0x1d, 0x6f, 0x69, 0xa6, 0x7c, 0xaa, 0xa3, 0xae, 0xdc, 0xea, 0x8a, + 0x60, 0x34, 0x42, 0xba, 0xfa, 0x0b, 0x70, 0xbd, 0x6b, 0xeb, 0x06, 0x7f, 0xb6, 0xee, 0x86, 0x6f, + 0x27, 0xe8, 0x3e, 0x64, 0x05, 0x54, 0xce, 0x64, 0xec, 0x76, 0x9b, 0xf6, 0xb9, 0x39, 0x87, 0x25, + 0xbe, 0x56, 0x04, 0x98, 0xea, 0x51, 0xff, 0x2c, 0x01, 0xf9, 0x50, 0x3f, 0x2a, 0x03, 0x2b, 0xe5, + 0xd9, 0xf2, 0xb6, 0x1c, 0x59, 0x7b, 0xe7, 0x71, 0x94, 0x84, 0x5a, 0x50, 0x18, 0x85, 0xd2, 0x97, + 0xe6, 0x73, 0x31, 0x56, 0xe3, 0xa8, 0x2c, 0xfa, 0x08, 0xf2, 0xc1, 0xdb, 0x68, 0x10, 0x61, 0x2f, + 0x7f, 0x4a, 0x9d, 0xc2, 0xd5, 0x4f, 0x00, 0x7e, 0x40, 0x2d, 0xa7, 0x4f, 0x0f, 0x88, 0xc3, 0xdf, + 0xfa, 0x58, 0x4d, 0x48, 0x02, 0x2f, 0xca, 0x16, 0x2f, 0xc8, 0xc5, 0x14, 0x84, 0x4f, 0x5e, 0xa2, + 0xa9, 0xfe, 0x75, 0x12, 0xb2, 0x98, 0x52, 0xbf, 0x5e, 0x45, 0x65, 0xc8, 0xca, 0x38, 0xc1, 0xcf, + 0x9f, 0x5a, 0xfe, 0xec, 0x74, 0x2d, 0x23, 0x02, 0x44, 0xc6, 0xe0, 0x91, 0x21, 0x12, 0xc1, 0x93, + 0x17, 0x45, 0x70, 0x74, 0x07, 0x8a, 0x12, 0xa4, 0xed, 0xeb, 0xde, 0xbe, 0x28, 0xd0, 0x6a, 0x8b, + 0x67, 0xa7, 0x6b, 0x20, 0x90, 0x9b, 0xba, 0xb7, 0x8f, 0x41, 0xa0, 0xd9, 0x37, 0x6a, 0x42, 0xe1, + 0x0b, 0x6a, 0x39, 0x9a, 0xcf, 0x07, 0x21, 0xaf, 0xfc, 0x62, 0xe7, 0x71, 0x3a, 0x54, 0xf9, 0xf0, + 0x0d, 0x5f, 0x4c, 0x07, 0xdf, 0x84, 0x05, 0x97, 0x52, 0x5f, 0x84, 0x2d, 0x8b, 0x3a, 0xf2, 0x36, + 0xa1, 0x1c, 0x7b, 0xc9, 0x4c, 0xa9, 0x8f, 0x25, 0x0e, 0x17, 0xdd, 0x48, 0x0b, 0xdd, 0x81, 0x65, + 0x5b, 0xf7, 0x7c, 0x8d, 0xc7, 0x3b, 0x73, 0xaa, 0x2d, 0xcb, 0xb7, 0x1a, 0x62, 0xbc, 0x0d, 0xce, + 0x0a, 0x24, 0xd4, 0x7f, 0x4c, 0x40, 0x81, 0x0d, 0xc6, 0xda, 0xb3, 0x0c, 0x96, 0xe4, 0x7d, 0xf3, + 0xdc, 0xe3, 0x26, 0xa4, 0x0c, 0xcf, 0x95, 0x4e, 0xe5, 0x87, 0x6f, 0xbd, 0x87, 0x31, 0xa3, 0xa1, + 0xcf, 0x20, 0x2b, 0x6f, 0x35, 0x44, 0xda, 0xa1, 0x5e, 0x9d, 0x8e, 0x4a, 0xdf, 0x48, 0x39, 0xbe, + 0x96, 0xa7, 0xd6, 0x89, 0x43, 0x00, 0x47, 0x49, 0xe8, 0x06, 0x24, 0x0d, 0xe1, 0x2e, 0xf9, 0xcb, + 0x8a, 0x7a, 0x1b, 0x27, 0x0d, 0x47, 0xfd, 0xbb, 0x04, 0x2c, 0x4c, 0x37, 0x3c, 0x5b, 0x01, 0xb7, + 0x20, 0xef, 0x8d, 0x77, 0xbd, 0x89, 0xe7, 0x93, 0x61, 0xf0, 0x8e, 0x19, 0x12, 0x50, 0x0b, 0xf2, + 0xba, 0x3d, 0xa0, 0xae, 0xe5, 0xef, 0x0f, 0x65, 0x25, 0x1a, 0x9f, 0x2a, 0x44, 0x75, 0x56, 0xaa, + 0x81, 0x08, 0x9e, 0x4a, 0x07, 0xe7, 0xbe, 0x78, 0xec, 0xe6, 0xe7, 0xfe, 0x6b, 0x50, 0xb4, 0xf5, + 0x21, 0xbf, 0xe6, 0xf1, 0xad, 0xa1, 0x18, 0x47, 0x1a, 0x17, 0x24, 0xad, 0x6f, 0x0d, 0x89, 0xaa, + 0x42, 0x3e, 0x54, 0x86, 0x96, 0xa0, 0x50, 0x6d, 0xf6, 0xb4, 0xbb, 0xeb, 0xf7, 0xb5, 0x47, 0xf5, + 0x6d, 0x65, 0x4e, 0xe6, 0xa6, 0x7f, 0x9e, 0x80, 0x05, 0x19, 0x8e, 0x64, 0xbe, 0xff, 0x3a, 0xcc, + 0xbb, 0xfa, 0x9e, 0x1f, 0x54, 0x24, 0x69, 0xb1, 0xaa, 0x59, 0x84, 0x67, 0x15, 0x09, 0x63, 0xc5, + 0x57, 0x24, 0x91, 0x97, 0xf5, 0xd4, 0xa5, 0x2f, 0xeb, 0xe9, 0x9f, 0xcb, 0xcb, 0xba, 0xfa, 0x6b, + 0x00, 0x1b, 0x96, 0x4d, 0xfa, 0xe2, 0xae, 0x29, 0xae, 0xbe, 0x64, 0x39, 0x9c, 0xbc, 0x71, 0x0c, + 0x72, 0xb8, 0x56, 0x03, 0x33, 0x1a, 0x63, 0x0d, 0x2c, 0x53, 0x6e, 0x46, 0xce, 0x7a, 0xc4, 0x58, + 0x03, 0xcb, 0x0c, 0xdf, 0x92, 0xd2, 0x57, 0xbd, 0x25, 0x9d, 0x24, 0x60, 0x49, 0xe6, 0xae, 0x61, + 0xf8, 0x7d, 0x1b, 0xf2, 0x22, 0x8d, 0x9d, 0x16, 0x74, 0xfc, 0x35, 0x59, 0xe0, 0x5a, 0x0d, 0x9c, + 0x13, 0xec, 0x96, 0x89, 0xd6, 0xa0, 0x20, 0xa1, 0x91, 0x5f, 0xe1, 0x80, 0x20, 0xb5, 0x99, 0xf9, + 0xef, 0x43, 0x7a, 0xcf, 0xb2, 0x89, 0x5c, 0xe8, 0xb1, 0x01, 0x60, 0xea, 0x80, 0xcd, 0x39, 0xcc, + 0xd1, 0xb5, 0x5c, 0x70, 0x19, 0xc7, 0xed, 0x93, 0x65, 0x67, 0xd4, 0x3e, 0x51, 0x81, 0x9e, 0xb3, + 0x4f, 0xe0, 0x98, 0x7d, 0x82, 0x2d, 0xec, 0x93, 0xd0, 0xa8, 0x7d, 0x82, 0xf4, 0x73, 0xb1, 0x6f, + 0x0b, 0x6e, 0xd4, 0x6c, 0xdd, 0x38, 0xb0, 0x2d, 0xcf, 0x27, 0x66, 0x34, 0x62, 0xac, 0x43, 0x76, + 0x26, 0xe9, 0xbc, 0xec, 0x72, 0x56, 0x22, 0xd5, 0x7f, 0x4b, 0x40, 0x71, 0x93, 0xe8, 0xb6, 0xbf, + 0x3f, 0xbd, 0x1a, 0xf2, 0x89, 0xe7, 0xcb, 0xc3, 0x8a, 0x7f, 0xa3, 0x0f, 0x20, 0x17, 0xe6, 0x24, + 0x57, 0xbe, 0x92, 0x85, 0x50, 0x74, 0x0f, 0xe6, 0xd9, 0x1e, 0xa3, 0xe3, 0xa0, 0xd8, 0xb9, 0xec, + 0x01, 0x46, 0x22, 0xd9, 0x21, 0xe3, 0x12, 0x9e, 0x84, 0xf0, 0xa5, 0x94, 0xc1, 0x41, 0x13, 0xfd, + 0x7f, 0x28, 0xf2, 0xf7, 0x83, 0x20, 0xe7, 0xca, 0x5c, 0xa5, 0xb3, 0x20, 0x9e, 0x00, 0x45, 0xbe, + 0xf5, 0x3f, 0x09, 0x58, 0xde, 0xd6, 0x27, 0xbb, 0x44, 0x86, 0x0d, 0x62, 0x62, 0x62, 0x50, 0xd7, + 0x44, 0xdd, 0x68, 0xb8, 0xb9, 0xe4, 0x45, 0x31, 0x4e, 0x38, 0x3e, 0xea, 0x04, 0x05, 0x58, 0x32, + 0x52, 0x80, 0x2d, 0x43, 0xc6, 0xa1, 0x8e, 0x41, 0x64, 0x2c, 0x12, 0x0d, 0xd5, 0x8a, 0x86, 0x9a, + 0x52, 0xf8, 0xd8, 0xc7, 0x9f, 0xea, 0xda, 0xd4, 0x0f, 0x7b, 0x43, 0x9f, 0x41, 0xa9, 0xd7, 0xac, + 0xe3, 0x66, 0xbf, 0xd6, 0xf9, 0xa1, 0xd6, 0xab, 0x6e, 0xf5, 0xaa, 0xeb, 0x77, 0xb4, 0x6e, 0x67, + 0xeb, 0xf3, 0xbb, 0xf7, 0xee, 0x7c, 0xa0, 0x24, 0x4a, 0xe5, 0xe3, 0x93, 0xf2, 0xad, 0x76, 0xb5, + 0xbe, 0x25, 0x76, 0xcc, 0x2e, 0x7d, 0xd6, 0xd3, 0x6d, 0x4f, 0x5f, 0xbf, 0xd3, 0xa5, 0xf6, 0x84, + 0x61, 0xd8, 0xb2, 0x2e, 0x46, 0xcf, 0xab, 0xe8, 0x31, 0x9c, 0xb8, 0xf0, 0x18, 0x9e, 0x9e, 0xe6, + 0xc9, 0x0b, 0x4e, 0xf3, 0x0d, 0x58, 0x36, 0x5c, 0xea, 0x79, 0x1a, 0xcb, 0xfe, 0x89, 0x79, 0xae, + 0xbe, 0xf8, 0xce, 0xd9, 0xe9, 0xda, 0xb5, 0x3a, 0xe3, 0xf7, 0x38, 0x5b, 0xaa, 0xbf, 0x66, 0x44, + 0x48, 0xbc, 0x27, 0xf5, 0xf7, 0x53, 0x2c, 0x91, 0xb2, 0x0e, 0x2d, 0x9b, 0x0c, 0x88, 0x87, 0x9e, + 0xc0, 0x92, 0xe1, 0x12, 0x93, 0xa5, 0xf5, 0xba, 0xad, 0x79, 0x23, 0x62, 0xc8, 0x45, 0xfd, 0xff, + 0x62, 0x73, 0x9a, 0x50, 0xb0, 0x52, 0x0f, 0xa5, 0x7a, 0x23, 0x62, 0xe0, 0x45, 0x63, 0xa6, 0x8d, + 0xbe, 0x80, 0x25, 0x8f, 0xd8, 0x96, 0x33, 0x7e, 0xa6, 0x19, 0xd4, 0xf1, 0xc9, 0xb3, 0xe0, 0xdd, + 0xea, 0x2a, 0xbd, 0xbd, 0xe6, 0x16, 0x93, 0xaa, 0x0b, 0xa1, 0x1a, 0x3a, 0x3b, 0x5d, 0x5b, 0x9c, + 0xa5, 0xe1, 0x45, 0xa9, 0x59, 0xb6, 0x4b, 0x6d, 0x58, 0x9c, 0xb5, 0x06, 0x2d, 0xcb, 0xbd, 0xcf, + 0x43, 0x48, 0xb0, 0xb7, 0xd1, 0x2d, 0xc8, 0xb9, 0x64, 0x60, 0x79, 0xbe, 0x2b, 0xdc, 0xcc, 0x38, + 0x21, 0x85, 0xed, 0x7c, 0xf1, 0x53, 0x9c, 0xd2, 0xaf, 0xc0, 0xb9, 0x1e, 0xd9, 0x66, 0x31, 0x2d, + 0x4f, 0xdf, 0x95, 0x2a, 0x73, 0x38, 0x68, 0xb2, 0x35, 0x38, 0xf6, 0xc2, 0x44, 0x8d, 0x7f, 0x33, + 0x1a, 0xcf, 0x28, 0xe4, 0x0f, 0x93, 0x78, 0xce, 0x10, 0xfc, 0xc2, 0x31, 0x1d, 0xf9, 0x85, 0xe3, + 0x32, 0x64, 0x6c, 0x72, 0x48, 0x6c, 0x71, 0x96, 0x63, 0xd1, 0x78, 0xe7, 0x67, 0x29, 0xc8, 0x87, + 0x6f, 0x34, 0xec, 0x24, 0x68, 0x37, 0x9f, 0x06, 0x6b, 0x35, 0xa4, 0xb7, 0xc9, 0x11, 0x7a, 0x6d, + 0x7a, 0xa7, 0xf4, 0x99, 0x78, 0x94, 0x0e, 0xd9, 0xc1, 0x7d, 0xd2, 0x1b, 0x90, 0xab, 0xf6, 0x7a, + 0xad, 0x47, 0xed, 0x66, 0x43, 0xf9, 0x32, 0x51, 0xfa, 0xce, 0xf1, 0x49, 0xf9, 0x5a, 0x08, 0xaa, + 0x7a, 0x62, 0x29, 0x71, 0x54, 0xbd, 0xde, 0xec, 0xf6, 0x9b, 0x0d, 0xe5, 0x79, 0xf2, 0x3c, 0x8a, + 0xdf, 0x91, 0xf0, 0x9f, 0x96, 0xe4, 0xbb, 0xb8, 0xd9, 0xad, 0x62, 0xd6, 0xe1, 0x97, 0x49, 0x71, + 0xd5, 0x35, 0xed, 0xd1, 0x25, 0x23, 0x9d, 0xff, 0xae, 0x78, 0x35, 0xf8, 0x89, 0xd5, 0xf3, 0x94, + 0xf8, 0xf9, 0xc1, 0xf4, 0xc1, 0x89, 0xe8, 0xe6, 0x84, 0xf5, 0xc6, 0x5f, 0xfa, 0xb8, 0x9a, 0xd4, + 0xb9, 0xde, 0x7a, 0x2c, 0x92, 0x30, 0x2d, 0x2a, 0xcc, 0xe3, 0x9d, 0x76, 0x9b, 0x81, 0x9e, 0xa7, + 0xcf, 0x8d, 0x0e, 0x8f, 0x1d, 0x56, 0xff, 0xa2, 0xdb, 0x90, 0x0b, 0x1e, 0x02, 0x95, 0x2f, 0xd3, + 0xe7, 0x0c, 0xaa, 0x07, 0xaf, 0x98, 0xbc, 0xc3, 0xcd, 0x9d, 0x3e, 0xff, 0x05, 0xd8, 0xf3, 0xcc, + 0xf9, 0x0e, 0xf7, 0xc7, 0xbe, 0x49, 0x8f, 0x1c, 0xb6, 0x03, 0xe5, 0xad, 0xda, 0x97, 0x19, 0x71, + 0x05, 0x11, 0x62, 0xe4, 0x95, 0xda, 0x1b, 0x90, 0xc3, 0xcd, 0x1f, 0x88, 0x1f, 0x8b, 0x3d, 0xcf, + 0x9e, 0xd3, 0x83, 0xc9, 0x17, 0xc4, 0x90, 0xbd, 0x75, 0x70, 0x77, 0xb3, 0xca, 0x5d, 0x7e, 0x1e, + 0xd5, 0x71, 0x47, 0xfb, 0xba, 0x43, 0xcc, 0xe9, 0x6f, 0x30, 0x42, 0xd6, 0x3b, 0xbf, 0x08, 0xb9, + 0x20, 0xcf, 0x44, 0xab, 0x90, 0x7d, 0xda, 0xc1, 0x8f, 0x9b, 0x58, 0x99, 0x13, 0x3e, 0x0c, 0x38, + 0x4f, 0x45, 0x85, 0x50, 0x86, 0xf9, 0xed, 0x6a, 0xbb, 0xfa, 0xa8, 0x89, 0x83, 0x0b, 0xef, 0x00, + 0x20, 0x93, 0xa5, 0x92, 0x22, 0x3b, 0x08, 0x75, 0xd6, 0x56, 0xbe, 0xfa, 0x7a, 0x75, 0xee, 0xa7, + 0x5f, 0xaf, 0xce, 0x3d, 0x3f, 0x5b, 0x4d, 0x7c, 0x75, 0xb6, 0x9a, 0xf8, 0xc9, 0xd9, 0x6a, 0xe2, + 0x5f, 0xcf, 0x56, 0x13, 0xbb, 0x59, 0x1e, 0xd2, 0xef, 0xfd, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, + 0xdb, 0x9d, 0xe2, 0x3d, 0xd2, 0x2f, 0x00, 0x00, } diff --git a/vendor/github.com/docker/swarmkit/api/types.proto b/vendor/github.com/docker/swarmkit/api/types.proto index 719b88a9c627..201bc3587f1a 100644 --- a/vendor/github.com/docker/swarmkit/api/types.proto +++ b/vendor/github.com/docker/swarmkit/api/types.proto @@ -30,12 +30,32 @@ message Annotations { repeated IndexEntry indices = 4 [(gogoproto.nullable) = false]; } +message GenericString { + string kind = 1; + string value = 2; +} + +message GenericDiscrete { + string kind = 1; + int64 value = 2; +} + +message GenericResource { + oneof resource { + GenericString str = 1; + GenericDiscrete discrete = 2; + } +} + message Resources { // Amount of CPUs (e.g. 2000000000 = 2 CPU cores) int64 nano_cpus = 1 [(gogoproto.customname) = "NanoCPUs"]; // Amount of memory in bytes. int64 memory_bytes = 2; + + // User specified resource (e.g: bananas=2;apple={red,yellow,green}) + repeated GenericResource generic = 3; } message ResourceRequirements { diff --git a/vendor/github.com/docker/swarmkit/vendor.conf b/vendor/github.com/docker/swarmkit/vendor.conf index 52fa7aafe523..4f5d293b8b0b 100644 --- a/vendor/github.com/docker/swarmkit/vendor.conf +++ b/vendor/github.com/docker/swarmkit/vendor.conf @@ -1,8 +1,9 @@ # grpc and protobuf -google.golang.org/grpc v1.0.4 +google.golang.org/grpc v1.3.0 github.com/gogo/protobuf v0.4 -github.com/golang/protobuf 8ee79997227bf9b34611aee7946ae64735e6fd93 +github.com/golang/protobuf 7a211bcf3bce0e3f1d74f9894916e6f116ae83b4 github.com/matttproud/golang_protobuf_extensions v1.0.0 +google.golang.org/genproto d80a6e20e776b0b17a324d0ba1ab50a39c8e8944 # metrics github.com/grpc-ecosystem/go-grpc-prometheus 6b7015e65d366bf3f19b2b2a000a831940f0f7e0 @@ -18,15 +19,24 @@ github.com/prometheus/common ebdfc6da46522d58825777cf1f90490a5b1ef1d8 github.com/prometheus/procfs abf152e5f3e97f2fafac028d2cc06c1feb87ffa5 github.com/docker/distribution b38e5838b7b2f2ad48e06ec4b500011976080621 -github.com/docker/docker 9585d0ea19859c5f145bc763d474190447b91c7b +github.com/docker/docker 77c9728847358a3ed3581d828fb0753017e1afd3 github.com/docker/go-connections 34b5052da6b11e27f5f2e357b38b571ddddd3928 github.com/docker/go-events 37d35add5005832485c0225ec870121b78fcff1c github.com/docker/go-units 954fed01cc617c55d838fa2230073f2cb17386c8 github.com/docker/libkv 9fd56606e928ff1f309808f5d5a0b7a2ef73f9a8 github.com/docker/libnetwork 37e20af882e13dd01ade3658b7aabdae3412118b github.com/docker/libtrust 9cbd2a1374f46905c68a4eb3694a130610adc62a -github.com/opencontainers/runc 8e8d01d38d7b4fb0a35bf89b72bc3e18c98882d7 +github.com/opencontainers/runc b6b70e53451794e8333e9b602cc096b47a20bd0f github.com/opencontainers/go-digest a6d0ee40d4207ea02364bd3b9e8e77b9159ba1eb +github.com/opencontainers/image-spec f03dbe35d449c54915d235f1a3cf8f585a24babe + +# containerd executor +github.com/containerd/containerd 7fc91b05917e93d474fab9465547d44eacd10ce3 +github.com/containerd/continuity f4ad4294c92f596c9241947c416d1297f9faf3ea +github.com/containerd/fifo 69b99525e472735860a5269b75af1970142b3062 +github.com/opencontainers/runtime-spec v1.0.0-rc5 +github.com/nightlyone/lockfile 1d49c987357a327b5b03aa84cbddd582c328615d +golang.org/x/sync 450f422ab23cf9881c94e2db30cac0eb1b7cf80c github.com/davecgh/go-spew 5215b55f46b2b919f50a1df0eaa5886afe4e3b3d github.com/Microsoft/go-winio f778f05015353be65d242f3fedc18695756153bb @@ -49,7 +59,7 @@ github.com/spf13/cobra 8e91712f174ced10270cf66615e0a9127e7c4de5 github.com/spf13/pflag 7f60f83a2c81bc3c3c0d5297f61ddfa68da9d3b7 github.com/stretchr/testify v1.1.4 golang.org/x/crypto 3fbbcd23f1cb824e69491a5930cfeff09b12f4d2 -golang.org/x/net c427ad74c6d7a814201695e9ffde0c5d400a7674 +golang.org/x/net 7dcfb8076726a3fdd9353b6b8a1f1b6be6811bd6 golang.org/x/sys 5eaf0df67e70d6997a9fe0ed24383fa1b01638d3 golang.org/x/text f72d8390a633d5dfb0cc84043294db9f6c935756 golang.org/x/time a4bde12657593d5e90d0533a3e4fd95e635124cb diff --git a/vendor/github.com/golang/protobuf/README.md b/vendor/github.com/golang/protobuf/README.md index 037fc7c8e2d3..aa933d788402 100644 --- a/vendor/github.com/golang/protobuf/README.md +++ b/vendor/github.com/golang/protobuf/README.md @@ -22,7 +22,7 @@ To use this software, you must: for details or, if you are using gccgo, follow the instructions at https://golang.org/doc/install/gccgo - Grab the code from the repository and install the proto package. - The simplest way is to run `go get -u github.com/golang/protobuf/{proto,protoc-gen-go}`. + The simplest way is to run `go get -u github.com/golang/protobuf/protoc-gen-go`. The compiler plugin, protoc-gen-go, will be installed in $GOBIN, defaulting to $GOPATH/bin. It must be in your $PATH for the protocol compiler, protoc, to find it. diff --git a/vendor/github.com/golang/protobuf/ptypes/any/any.pb.go b/vendor/github.com/golang/protobuf/ptypes/any/any.pb.go new file mode 100644 index 000000000000..1fbaa44caa20 --- /dev/null +++ b/vendor/github.com/golang/protobuf/ptypes/any/any.pb.go @@ -0,0 +1,168 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: github.com/golang/protobuf/ptypes/any/any.proto + +/* +Package any is a generated protocol buffer package. + +It is generated from these files: + github.com/golang/protobuf/ptypes/any/any.proto + +It has these top-level messages: + Any +*/ +package any + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package + +// `Any` contains an arbitrary serialized protocol buffer message along with a +// URL that describes the type of the serialized message. +// +// Protobuf library provides support to pack/unpack Any values in the form +// of utility functions or additional generated methods of the Any type. +// +// Example 1: Pack and unpack a message in C++. +// +// Foo foo = ...; +// Any any; +// any.PackFrom(foo); +// ... +// if (any.UnpackTo(&foo)) { +// ... +// } +// +// Example 2: Pack and unpack a message in Java. +// +// Foo foo = ...; +// Any any = Any.pack(foo); +// ... +// if (any.is(Foo.class)) { +// foo = any.unpack(Foo.class); +// } +// +// Example 3: Pack and unpack a message in Python. +// +// foo = Foo(...) +// any = Any() +// any.Pack(foo) +// ... +// if any.Is(Foo.DESCRIPTOR): +// any.Unpack(foo) +// ... +// +// The pack methods provided by protobuf library will by default use +// 'type.googleapis.com/full.type.name' as the type URL and the unpack +// methods only use the fully qualified type name after the last '/' +// in the type URL, for example "foo.bar.com/x/y.z" will yield type +// name "y.z". +// +// +// JSON +// ==== +// The JSON representation of an `Any` value uses the regular +// representation of the deserialized, embedded message, with an +// additional field `@type` which contains the type URL. Example: +// +// package google.profile; +// message Person { +// string first_name = 1; +// string last_name = 2; +// } +// +// { +// "@type": "type.googleapis.com/google.profile.Person", +// "firstName": , +// "lastName": +// } +// +// If the embedded message type is well-known and has a custom JSON +// representation, that representation will be embedded adding a field +// `value` which holds the custom JSON in addition to the `@type` +// field. Example (for message [google.protobuf.Duration][]): +// +// { +// "@type": "type.googleapis.com/google.protobuf.Duration", +// "value": "1.212s" +// } +// +type Any struct { + // A URL/resource name whose content describes the type of the + // serialized protocol buffer message. + // + // For URLs which use the scheme `http`, `https`, or no scheme, the + // following restrictions and interpretations apply: + // + // * If no scheme is provided, `https` is assumed. + // * The last segment of the URL's path must represent the fully + // qualified name of the type (as in `path/google.protobuf.Duration`). + // The name should be in a canonical form (e.g., leading "." is + // not accepted). + // * An HTTP GET on the URL must yield a [google.protobuf.Type][] + // value in binary format, or produce an error. + // * Applications are allowed to cache lookup results based on the + // URL, or have them precompiled into a binary to avoid any + // lookup. Therefore, binary compatibility needs to be preserved + // on changes to types. (Use versioned type names to manage + // breaking changes.) + // + // Schemes other than `http`, `https` (or the empty scheme) might be + // used with implementation specific semantics. + // + TypeUrl string `protobuf:"bytes,1,opt,name=type_url,json=typeUrl" json:"type_url,omitempty"` + // Must be a valid serialized protocol buffer of the above specified type. + Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` +} + +func (m *Any) Reset() { *m = Any{} } +func (m *Any) String() string { return proto.CompactTextString(m) } +func (*Any) ProtoMessage() {} +func (*Any) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } +func (*Any) XXX_WellKnownType() string { return "Any" } + +func (m *Any) GetTypeUrl() string { + if m != nil { + return m.TypeUrl + } + return "" +} + +func (m *Any) GetValue() []byte { + if m != nil { + return m.Value + } + return nil +} + +func init() { + proto.RegisterType((*Any)(nil), "google.protobuf.Any") +} + +func init() { proto.RegisterFile("github.com/golang/protobuf/ptypes/any/any.proto", fileDescriptor0) } + +var fileDescriptor0 = []byte{ + // 184 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xd2, 0x4f, 0xcf, 0x2c, 0xc9, + 0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xcf, 0xcf, 0x49, 0xcc, 0x4b, 0xd7, 0x2f, 0x28, + 0xca, 0x2f, 0xc9, 0x4f, 0x2a, 0x4d, 0xd3, 0x2f, 0x28, 0xa9, 0x2c, 0x48, 0x2d, 0xd6, 0x4f, 0xcc, + 0xab, 0x04, 0x61, 0x3d, 0xb0, 0xb8, 0x10, 0x7f, 0x7a, 0x7e, 0x7e, 0x7a, 0x4e, 0xaa, 0x1e, 0x4c, + 0x95, 0x92, 0x19, 0x17, 0xb3, 0x63, 0x5e, 0xa5, 0x90, 0x24, 0x17, 0x07, 0x48, 0x79, 0x7c, 0x69, + 0x51, 0x8e, 0x04, 0xa3, 0x02, 0xa3, 0x06, 0x67, 0x10, 0x3b, 0x88, 0x1f, 0x5a, 0x94, 0x23, 0x24, + 0xc2, 0xc5, 0x5a, 0x96, 0x98, 0x53, 0x9a, 0x2a, 0xc1, 0xa4, 0xc0, 0xa8, 0xc1, 0x13, 0x04, 0xe1, + 0x38, 0xe5, 0x73, 0x09, 0x27, 0xe7, 0xe7, 0xea, 0xa1, 0x19, 0xe7, 0xc4, 0xe1, 0x98, 0x57, 0x19, + 0x00, 0xe2, 0x04, 0x30, 0x46, 0xa9, 0x12, 0xe5, 0xb8, 0x45, 0x4c, 0xcc, 0xee, 0x01, 0x4e, 0xab, + 0x98, 0xe4, 0xdc, 0x21, 0x46, 0x05, 0x40, 0x95, 0xe8, 0x85, 0xa7, 0xe6, 0xe4, 0x78, 0xe7, 0xe5, + 0x97, 0xe7, 0x85, 0x80, 0x94, 0x26, 0xb1, 0x81, 0xf5, 0x1a, 0x03, 0x02, 0x00, 0x00, 0xff, 0xff, + 0x45, 0x1f, 0x1a, 0xf2, 0xf3, 0x00, 0x00, 0x00, +} diff --git a/vendor/github.com/golang/protobuf/ptypes/any/any.proto b/vendor/github.com/golang/protobuf/ptypes/any/any.proto new file mode 100644 index 000000000000..9bd3f50a4537 --- /dev/null +++ b/vendor/github.com/golang/protobuf/ptypes/any/any.proto @@ -0,0 +1,139 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +package google.protobuf; + +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; +option go_package = "github.com/golang/protobuf/ptypes/any"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "AnyProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; + +// `Any` contains an arbitrary serialized protocol buffer message along with a +// URL that describes the type of the serialized message. +// +// Protobuf library provides support to pack/unpack Any values in the form +// of utility functions or additional generated methods of the Any type. +// +// Example 1: Pack and unpack a message in C++. +// +// Foo foo = ...; +// Any any; +// any.PackFrom(foo); +// ... +// if (any.UnpackTo(&foo)) { +// ... +// } +// +// Example 2: Pack and unpack a message in Java. +// +// Foo foo = ...; +// Any any = Any.pack(foo); +// ... +// if (any.is(Foo.class)) { +// foo = any.unpack(Foo.class); +// } +// +// Example 3: Pack and unpack a message in Python. +// +// foo = Foo(...) +// any = Any() +// any.Pack(foo) +// ... +// if any.Is(Foo.DESCRIPTOR): +// any.Unpack(foo) +// ... +// +// The pack methods provided by protobuf library will by default use +// 'type.googleapis.com/full.type.name' as the type URL and the unpack +// methods only use the fully qualified type name after the last '/' +// in the type URL, for example "foo.bar.com/x/y.z" will yield type +// name "y.z". +// +// +// JSON +// ==== +// The JSON representation of an `Any` value uses the regular +// representation of the deserialized, embedded message, with an +// additional field `@type` which contains the type URL. Example: +// +// package google.profile; +// message Person { +// string first_name = 1; +// string last_name = 2; +// } +// +// { +// "@type": "type.googleapis.com/google.profile.Person", +// "firstName": , +// "lastName": +// } +// +// If the embedded message type is well-known and has a custom JSON +// representation, that representation will be embedded adding a field +// `value` which holds the custom JSON in addition to the `@type` +// field. Example (for message [google.protobuf.Duration][]): +// +// { +// "@type": "type.googleapis.com/google.protobuf.Duration", +// "value": "1.212s" +// } +// +message Any { + // A URL/resource name whose content describes the type of the + // serialized protocol buffer message. + // + // For URLs which use the scheme `http`, `https`, or no scheme, the + // following restrictions and interpretations apply: + // + // * If no scheme is provided, `https` is assumed. + // * The last segment of the URL's path must represent the fully + // qualified name of the type (as in `path/google.protobuf.Duration`). + // The name should be in a canonical form (e.g., leading "." is + // not accepted). + // * An HTTP GET on the URL must yield a [google.protobuf.Type][] + // value in binary format, or produce an error. + // * Applications are allowed to cache lookup results based on the + // URL, or have them precompiled into a binary to avoid any + // lookup. Therefore, binary compatibility needs to be preserved + // on changes to types. (Use versioned type names to manage + // breaking changes.) + // + // Schemes other than `http`, `https` (or the empty scheme) might be + // used with implementation specific semantics. + // + string type_url = 1; + + // Must be a valid serialized protocol buffer of the above specified type. + bytes value = 2; +} diff --git a/vendor/golang.org/x/net/context/context.go b/vendor/golang.org/x/net/context/context.go index 134654cf7e2b..f143ed6a1eb0 100644 --- a/vendor/golang.org/x/net/context/context.go +++ b/vendor/golang.org/x/net/context/context.go @@ -7,7 +7,7 @@ // and between processes. // // Incoming requests to a server should create a Context, and outgoing calls to -// servers should accept a Context. The chain of function calls between must +// servers should accept a Context. The chain of function calls between must // propagate the Context, optionally replacing it with a modified copy created // using WithDeadline, WithTimeout, WithCancel, or WithValue. // @@ -16,14 +16,14 @@ // propagation: // // Do not store Contexts inside a struct type; instead, pass a Context -// explicitly to each function that needs it. The Context should be the first +// explicitly to each function that needs it. The Context should be the first // parameter, typically named ctx: // // func DoSomething(ctx context.Context, arg Arg) error { // // ... use ctx ... // } // -// Do not pass a nil Context, even if a function permits it. Pass context.TODO +// Do not pass a nil Context, even if a function permits it. Pass context.TODO // if you are unsure about which Context to use. // // Use context Values only for request-scoped data that transits processes and @@ -44,13 +44,13 @@ import "time" // Context's methods may be called by multiple goroutines simultaneously. type Context interface { // Deadline returns the time when work done on behalf of this context - // should be canceled. Deadline returns ok==false when no deadline is - // set. Successive calls to Deadline return the same results. + // should be canceled. Deadline returns ok==false when no deadline is + // set. Successive calls to Deadline return the same results. Deadline() (deadline time.Time, ok bool) // Done returns a channel that's closed when work done on behalf of this - // context should be canceled. Done may return nil if this context can - // never be canceled. Successive calls to Done return the same value. + // context should be canceled. Done may return nil if this context can + // never be canceled. Successive calls to Done return the same value. // // WithCancel arranges for Done to be closed when cancel is called; // WithDeadline arranges for Done to be closed when the deadline @@ -79,24 +79,24 @@ type Context interface { // a Done channel for cancelation. Done() <-chan struct{} - // Err returns a non-nil error value after Done is closed. Err returns + // Err returns a non-nil error value after Done is closed. Err returns // Canceled if the context was canceled or DeadlineExceeded if the - // context's deadline passed. No other values for Err are defined. + // context's deadline passed. No other values for Err are defined. // After Done is closed, successive calls to Err return the same value. Err() error // Value returns the value associated with this context for key, or nil - // if no value is associated with key. Successive calls to Value with + // if no value is associated with key. Successive calls to Value with // the same key returns the same result. // // Use context values only for request-scoped data that transits // processes and API boundaries, not for passing optional parameters to // functions. // - // A key identifies a specific value in a Context. Functions that wish + // A key identifies a specific value in a Context. Functions that wish // to store values in Context typically allocate a key in a global // variable then use that key as the argument to context.WithValue and - // Context.Value. A key can be any type that supports equality; + // Context.Value. A key can be any type that supports equality; // packages should define keys as an unexported type to avoid // collisions. // @@ -115,7 +115,7 @@ type Context interface { // // This prevents collisions with keys defined in other packages. // type key int // - // // userKey is the key for user.User values in Contexts. It is + // // userKey is the key for user.User values in Contexts. It is // // unexported; clients use user.NewContext and user.FromContext // // instead of using this key directly. // var userKey key = 0 @@ -134,14 +134,14 @@ type Context interface { } // Background returns a non-nil, empty Context. It is never canceled, has no -// values, and has no deadline. It is typically used by the main function, +// values, and has no deadline. It is typically used by the main function, // initialization, and tests, and as the top-level Context for incoming // requests. func Background() Context { return background } -// TODO returns a non-nil, empty Context. Code should use context.TODO when +// TODO returns a non-nil, empty Context. Code should use context.TODO when // it's unclear which Context to use or it is not yet available (because the // surrounding function has not yet been extended to accept a Context // parameter). TODO is recognized by static analysis tools that determine diff --git a/vendor/golang.org/x/net/context/go17.go b/vendor/golang.org/x/net/context/go17.go index f8cda19adaee..d20f52b7de93 100644 --- a/vendor/golang.org/x/net/context/go17.go +++ b/vendor/golang.org/x/net/context/go17.go @@ -35,8 +35,8 @@ func WithCancel(parent Context) (ctx Context, cancel CancelFunc) { } // WithDeadline returns a copy of the parent context with the deadline adjusted -// to be no later than d. If the parent's deadline is already earlier than d, -// WithDeadline(parent, d) is semantically equivalent to parent. The returned +// to be no later than d. If the parent's deadline is already earlier than d, +// WithDeadline(parent, d) is semantically equivalent to parent. The returned // context's Done channel is closed when the deadline expires, when the returned // cancel function is called, or when the parent context's Done channel is // closed, whichever happens first. diff --git a/vendor/golang.org/x/net/context/pre_go17.go b/vendor/golang.org/x/net/context/pre_go17.go index 5a30acabd03c..0f35592df518 100644 --- a/vendor/golang.org/x/net/context/pre_go17.go +++ b/vendor/golang.org/x/net/context/pre_go17.go @@ -13,7 +13,7 @@ import ( "time" ) -// An emptyCtx is never canceled, has no values, and has no deadline. It is not +// An emptyCtx is never canceled, has no values, and has no deadline. It is not // struct{}, since vars of this type must have distinct addresses. type emptyCtx int @@ -104,7 +104,7 @@ func propagateCancel(parent Context, child canceler) { } // parentCancelCtx follows a chain of parent references until it finds a -// *cancelCtx. This function understands how each of the concrete types in this +// *cancelCtx. This function understands how each of the concrete types in this // package represents its parent. func parentCancelCtx(parent Context) (*cancelCtx, bool) { for { @@ -134,14 +134,14 @@ func removeChild(parent Context, child canceler) { p.mu.Unlock() } -// A canceler is a context type that can be canceled directly. The +// A canceler is a context type that can be canceled directly. The // implementations are *cancelCtx and *timerCtx. type canceler interface { cancel(removeFromParent bool, err error) Done() <-chan struct{} } -// A cancelCtx can be canceled. When canceled, it also cancels any children +// A cancelCtx can be canceled. When canceled, it also cancels any children // that implement canceler. type cancelCtx struct { Context @@ -193,8 +193,8 @@ func (c *cancelCtx) cancel(removeFromParent bool, err error) { } // WithDeadline returns a copy of the parent context with the deadline adjusted -// to be no later than d. If the parent's deadline is already earlier than d, -// WithDeadline(parent, d) is semantically equivalent to parent. The returned +// to be no later than d. If the parent's deadline is already earlier than d, +// WithDeadline(parent, d) is semantically equivalent to parent. The returned // context's Done channel is closed when the deadline expires, when the returned // cancel function is called, or when the parent context's Done channel is // closed, whichever happens first. @@ -226,8 +226,8 @@ func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc) { return c, func() { c.cancel(true, Canceled) } } -// A timerCtx carries a timer and a deadline. It embeds a cancelCtx to -// implement Done and Err. It implements cancel by stopping its timer then +// A timerCtx carries a timer and a deadline. It embeds a cancelCtx to +// implement Done and Err. It implements cancel by stopping its timer then // delegating to cancelCtx.cancel. type timerCtx struct { *cancelCtx @@ -281,7 +281,7 @@ func WithValue(parent Context, key interface{}, val interface{}) Context { return &valueCtx{parent, key, val} } -// A valueCtx carries a key-value pair. It implements Value for that key and +// A valueCtx carries a key-value pair. It implements Value for that key and // delegates all other calls to the embedded Context. type valueCtx struct { Context diff --git a/vendor/golang.org/x/net/http2/ciphers.go b/vendor/golang.org/x/net/http2/ciphers.go new file mode 100644 index 000000000000..698860b77755 --- /dev/null +++ b/vendor/golang.org/x/net/http2/ciphers.go @@ -0,0 +1,641 @@ +// Copyright 2017 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 http2 + +// A list of the possible cipher suite ids. Taken from +// http://www.iana.org/assignments/tls-parameters/tls-parameters.txt + +const ( + cipher_TLS_NULL_WITH_NULL_NULL uint16 = 0x0000 + cipher_TLS_RSA_WITH_NULL_MD5 uint16 = 0x0001 + cipher_TLS_RSA_WITH_NULL_SHA uint16 = 0x0002 + cipher_TLS_RSA_EXPORT_WITH_RC4_40_MD5 uint16 = 0x0003 + cipher_TLS_RSA_WITH_RC4_128_MD5 uint16 = 0x0004 + cipher_TLS_RSA_WITH_RC4_128_SHA uint16 = 0x0005 + cipher_TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 uint16 = 0x0006 + cipher_TLS_RSA_WITH_IDEA_CBC_SHA uint16 = 0x0007 + cipher_TLS_RSA_EXPORT_WITH_DES40_CBC_SHA uint16 = 0x0008 + cipher_TLS_RSA_WITH_DES_CBC_SHA uint16 = 0x0009 + cipher_TLS_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0x000A + cipher_TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA uint16 = 0x000B + cipher_TLS_DH_DSS_WITH_DES_CBC_SHA uint16 = 0x000C + cipher_TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA uint16 = 0x000D + cipher_TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA uint16 = 0x000E + cipher_TLS_DH_RSA_WITH_DES_CBC_SHA uint16 = 0x000F + cipher_TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0x0010 + cipher_TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA uint16 = 0x0011 + cipher_TLS_DHE_DSS_WITH_DES_CBC_SHA uint16 = 0x0012 + cipher_TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA uint16 = 0x0013 + cipher_TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA uint16 = 0x0014 + cipher_TLS_DHE_RSA_WITH_DES_CBC_SHA uint16 = 0x0015 + cipher_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0x0016 + cipher_TLS_DH_anon_EXPORT_WITH_RC4_40_MD5 uint16 = 0x0017 + cipher_TLS_DH_anon_WITH_RC4_128_MD5 uint16 = 0x0018 + cipher_TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA uint16 = 0x0019 + cipher_TLS_DH_anon_WITH_DES_CBC_SHA uint16 = 0x001A + cipher_TLS_DH_anon_WITH_3DES_EDE_CBC_SHA uint16 = 0x001B + // Reserved uint16 = 0x001C-1D + cipher_TLS_KRB5_WITH_DES_CBC_SHA uint16 = 0x001E + cipher_TLS_KRB5_WITH_3DES_EDE_CBC_SHA uint16 = 0x001F + cipher_TLS_KRB5_WITH_RC4_128_SHA uint16 = 0x0020 + cipher_TLS_KRB5_WITH_IDEA_CBC_SHA uint16 = 0x0021 + cipher_TLS_KRB5_WITH_DES_CBC_MD5 uint16 = 0x0022 + cipher_TLS_KRB5_WITH_3DES_EDE_CBC_MD5 uint16 = 0x0023 + cipher_TLS_KRB5_WITH_RC4_128_MD5 uint16 = 0x0024 + cipher_TLS_KRB5_WITH_IDEA_CBC_MD5 uint16 = 0x0025 + cipher_TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA uint16 = 0x0026 + cipher_TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA uint16 = 0x0027 + cipher_TLS_KRB5_EXPORT_WITH_RC4_40_SHA uint16 = 0x0028 + cipher_TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5 uint16 = 0x0029 + cipher_TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5 uint16 = 0x002A + cipher_TLS_KRB5_EXPORT_WITH_RC4_40_MD5 uint16 = 0x002B + cipher_TLS_PSK_WITH_NULL_SHA uint16 = 0x002C + cipher_TLS_DHE_PSK_WITH_NULL_SHA uint16 = 0x002D + cipher_TLS_RSA_PSK_WITH_NULL_SHA uint16 = 0x002E + cipher_TLS_RSA_WITH_AES_128_CBC_SHA uint16 = 0x002F + cipher_TLS_DH_DSS_WITH_AES_128_CBC_SHA uint16 = 0x0030 + cipher_TLS_DH_RSA_WITH_AES_128_CBC_SHA uint16 = 0x0031 + cipher_TLS_DHE_DSS_WITH_AES_128_CBC_SHA uint16 = 0x0032 + cipher_TLS_DHE_RSA_WITH_AES_128_CBC_SHA uint16 = 0x0033 + cipher_TLS_DH_anon_WITH_AES_128_CBC_SHA uint16 = 0x0034 + cipher_TLS_RSA_WITH_AES_256_CBC_SHA uint16 = 0x0035 + cipher_TLS_DH_DSS_WITH_AES_256_CBC_SHA uint16 = 0x0036 + cipher_TLS_DH_RSA_WITH_AES_256_CBC_SHA uint16 = 0x0037 + cipher_TLS_DHE_DSS_WITH_AES_256_CBC_SHA uint16 = 0x0038 + cipher_TLS_DHE_RSA_WITH_AES_256_CBC_SHA uint16 = 0x0039 + cipher_TLS_DH_anon_WITH_AES_256_CBC_SHA uint16 = 0x003A + cipher_TLS_RSA_WITH_NULL_SHA256 uint16 = 0x003B + cipher_TLS_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0x003C + cipher_TLS_RSA_WITH_AES_256_CBC_SHA256 uint16 = 0x003D + cipher_TLS_DH_DSS_WITH_AES_128_CBC_SHA256 uint16 = 0x003E + cipher_TLS_DH_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0x003F + cipher_TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 uint16 = 0x0040 + cipher_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA uint16 = 0x0041 + cipher_TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA uint16 = 0x0042 + cipher_TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA uint16 = 0x0043 + cipher_TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA uint16 = 0x0044 + cipher_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA uint16 = 0x0045 + cipher_TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA uint16 = 0x0046 + // Reserved uint16 = 0x0047-4F + // Reserved uint16 = 0x0050-58 + // Reserved uint16 = 0x0059-5C + // Unassigned uint16 = 0x005D-5F + // Reserved uint16 = 0x0060-66 + cipher_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0x0067 + cipher_TLS_DH_DSS_WITH_AES_256_CBC_SHA256 uint16 = 0x0068 + cipher_TLS_DH_RSA_WITH_AES_256_CBC_SHA256 uint16 = 0x0069 + cipher_TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 uint16 = 0x006A + cipher_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 uint16 = 0x006B + cipher_TLS_DH_anon_WITH_AES_128_CBC_SHA256 uint16 = 0x006C + cipher_TLS_DH_anon_WITH_AES_256_CBC_SHA256 uint16 = 0x006D + // Unassigned uint16 = 0x006E-83 + cipher_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA uint16 = 0x0084 + cipher_TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA uint16 = 0x0085 + cipher_TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA uint16 = 0x0086 + cipher_TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA uint16 = 0x0087 + cipher_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA uint16 = 0x0088 + cipher_TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA uint16 = 0x0089 + cipher_TLS_PSK_WITH_RC4_128_SHA uint16 = 0x008A + cipher_TLS_PSK_WITH_3DES_EDE_CBC_SHA uint16 = 0x008B + cipher_TLS_PSK_WITH_AES_128_CBC_SHA uint16 = 0x008C + cipher_TLS_PSK_WITH_AES_256_CBC_SHA uint16 = 0x008D + cipher_TLS_DHE_PSK_WITH_RC4_128_SHA uint16 = 0x008E + cipher_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA uint16 = 0x008F + cipher_TLS_DHE_PSK_WITH_AES_128_CBC_SHA uint16 = 0x0090 + cipher_TLS_DHE_PSK_WITH_AES_256_CBC_SHA uint16 = 0x0091 + cipher_TLS_RSA_PSK_WITH_RC4_128_SHA uint16 = 0x0092 + cipher_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA uint16 = 0x0093 + cipher_TLS_RSA_PSK_WITH_AES_128_CBC_SHA uint16 = 0x0094 + cipher_TLS_RSA_PSK_WITH_AES_256_CBC_SHA uint16 = 0x0095 + cipher_TLS_RSA_WITH_SEED_CBC_SHA uint16 = 0x0096 + cipher_TLS_DH_DSS_WITH_SEED_CBC_SHA uint16 = 0x0097 + cipher_TLS_DH_RSA_WITH_SEED_CBC_SHA uint16 = 0x0098 + cipher_TLS_DHE_DSS_WITH_SEED_CBC_SHA uint16 = 0x0099 + cipher_TLS_DHE_RSA_WITH_SEED_CBC_SHA uint16 = 0x009A + cipher_TLS_DH_anon_WITH_SEED_CBC_SHA uint16 = 0x009B + cipher_TLS_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0x009C + cipher_TLS_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0x009D + cipher_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0x009E + cipher_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0x009F + cipher_TLS_DH_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0x00A0 + cipher_TLS_DH_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0x00A1 + cipher_TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 uint16 = 0x00A2 + cipher_TLS_DHE_DSS_WITH_AES_256_GCM_SHA384 uint16 = 0x00A3 + cipher_TLS_DH_DSS_WITH_AES_128_GCM_SHA256 uint16 = 0x00A4 + cipher_TLS_DH_DSS_WITH_AES_256_GCM_SHA384 uint16 = 0x00A5 + cipher_TLS_DH_anon_WITH_AES_128_GCM_SHA256 uint16 = 0x00A6 + cipher_TLS_DH_anon_WITH_AES_256_GCM_SHA384 uint16 = 0x00A7 + cipher_TLS_PSK_WITH_AES_128_GCM_SHA256 uint16 = 0x00A8 + cipher_TLS_PSK_WITH_AES_256_GCM_SHA384 uint16 = 0x00A9 + cipher_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 uint16 = 0x00AA + cipher_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 uint16 = 0x00AB + cipher_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 uint16 = 0x00AC + cipher_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 uint16 = 0x00AD + cipher_TLS_PSK_WITH_AES_128_CBC_SHA256 uint16 = 0x00AE + cipher_TLS_PSK_WITH_AES_256_CBC_SHA384 uint16 = 0x00AF + cipher_TLS_PSK_WITH_NULL_SHA256 uint16 = 0x00B0 + cipher_TLS_PSK_WITH_NULL_SHA384 uint16 = 0x00B1 + cipher_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 uint16 = 0x00B2 + cipher_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 uint16 = 0x00B3 + cipher_TLS_DHE_PSK_WITH_NULL_SHA256 uint16 = 0x00B4 + cipher_TLS_DHE_PSK_WITH_NULL_SHA384 uint16 = 0x00B5 + cipher_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 uint16 = 0x00B6 + cipher_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 uint16 = 0x00B7 + cipher_TLS_RSA_PSK_WITH_NULL_SHA256 uint16 = 0x00B8 + cipher_TLS_RSA_PSK_WITH_NULL_SHA384 uint16 = 0x00B9 + cipher_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0x00BA + cipher_TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0x00BB + cipher_TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0x00BC + cipher_TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0x00BD + cipher_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0x00BE + cipher_TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0x00BF + cipher_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 uint16 = 0x00C0 + cipher_TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256 uint16 = 0x00C1 + cipher_TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256 uint16 = 0x00C2 + cipher_TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256 uint16 = 0x00C3 + cipher_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 uint16 = 0x00C4 + cipher_TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256 uint16 = 0x00C5 + // Unassigned uint16 = 0x00C6-FE + cipher_TLS_EMPTY_RENEGOTIATION_INFO_SCSV uint16 = 0x00FF + // Unassigned uint16 = 0x01-55,* + cipher_TLS_FALLBACK_SCSV uint16 = 0x5600 + // Unassigned uint16 = 0x5601 - 0xC000 + cipher_TLS_ECDH_ECDSA_WITH_NULL_SHA uint16 = 0xC001 + cipher_TLS_ECDH_ECDSA_WITH_RC4_128_SHA uint16 = 0xC002 + cipher_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA uint16 = 0xC003 + cipher_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA uint16 = 0xC004 + cipher_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA uint16 = 0xC005 + cipher_TLS_ECDHE_ECDSA_WITH_NULL_SHA uint16 = 0xC006 + cipher_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA uint16 = 0xC007 + cipher_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA uint16 = 0xC008 + cipher_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA uint16 = 0xC009 + cipher_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA uint16 = 0xC00A + cipher_TLS_ECDH_RSA_WITH_NULL_SHA uint16 = 0xC00B + cipher_TLS_ECDH_RSA_WITH_RC4_128_SHA uint16 = 0xC00C + cipher_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0xC00D + cipher_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA uint16 = 0xC00E + cipher_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA uint16 = 0xC00F + cipher_TLS_ECDHE_RSA_WITH_NULL_SHA uint16 = 0xC010 + cipher_TLS_ECDHE_RSA_WITH_RC4_128_SHA uint16 = 0xC011 + cipher_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0xC012 + cipher_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA uint16 = 0xC013 + cipher_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA uint16 = 0xC014 + cipher_TLS_ECDH_anon_WITH_NULL_SHA uint16 = 0xC015 + cipher_TLS_ECDH_anon_WITH_RC4_128_SHA uint16 = 0xC016 + cipher_TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA uint16 = 0xC017 + cipher_TLS_ECDH_anon_WITH_AES_128_CBC_SHA uint16 = 0xC018 + cipher_TLS_ECDH_anon_WITH_AES_256_CBC_SHA uint16 = 0xC019 + cipher_TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA uint16 = 0xC01A + cipher_TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0xC01B + cipher_TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA uint16 = 0xC01C + cipher_TLS_SRP_SHA_WITH_AES_128_CBC_SHA uint16 = 0xC01D + cipher_TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA uint16 = 0xC01E + cipher_TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA uint16 = 0xC01F + cipher_TLS_SRP_SHA_WITH_AES_256_CBC_SHA uint16 = 0xC020 + cipher_TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA uint16 = 0xC021 + cipher_TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA uint16 = 0xC022 + cipher_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 uint16 = 0xC023 + cipher_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 uint16 = 0xC024 + cipher_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 uint16 = 0xC025 + cipher_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 uint16 = 0xC026 + cipher_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0xC027 + cipher_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 uint16 = 0xC028 + cipher_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0xC029 + cipher_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 uint16 = 0xC02A + cipher_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 uint16 = 0xC02B + cipher_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 uint16 = 0xC02C + cipher_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 uint16 = 0xC02D + cipher_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 uint16 = 0xC02E + cipher_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0xC02F + cipher_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0xC030 + cipher_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0xC031 + cipher_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0xC032 + cipher_TLS_ECDHE_PSK_WITH_RC4_128_SHA uint16 = 0xC033 + cipher_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA uint16 = 0xC034 + cipher_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA uint16 = 0xC035 + cipher_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA uint16 = 0xC036 + cipher_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 uint16 = 0xC037 + cipher_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 uint16 = 0xC038 + cipher_TLS_ECDHE_PSK_WITH_NULL_SHA uint16 = 0xC039 + cipher_TLS_ECDHE_PSK_WITH_NULL_SHA256 uint16 = 0xC03A + cipher_TLS_ECDHE_PSK_WITH_NULL_SHA384 uint16 = 0xC03B + cipher_TLS_RSA_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC03C + cipher_TLS_RSA_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC03D + cipher_TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC03E + cipher_TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC03F + cipher_TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC040 + cipher_TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC041 + cipher_TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC042 + cipher_TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC043 + cipher_TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC044 + cipher_TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC045 + cipher_TLS_DH_anon_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC046 + cipher_TLS_DH_anon_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC047 + cipher_TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC048 + cipher_TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC049 + cipher_TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC04A + cipher_TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC04B + cipher_TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC04C + cipher_TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC04D + cipher_TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC04E + cipher_TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC04F + cipher_TLS_RSA_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC050 + cipher_TLS_RSA_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC051 + cipher_TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC052 + cipher_TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC053 + cipher_TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC054 + cipher_TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC055 + cipher_TLS_DHE_DSS_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC056 + cipher_TLS_DHE_DSS_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC057 + cipher_TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC058 + cipher_TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC059 + cipher_TLS_DH_anon_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC05A + cipher_TLS_DH_anon_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC05B + cipher_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC05C + cipher_TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC05D + cipher_TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC05E + cipher_TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC05F + cipher_TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC060 + cipher_TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC061 + cipher_TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC062 + cipher_TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC063 + cipher_TLS_PSK_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC064 + cipher_TLS_PSK_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC065 + cipher_TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC066 + cipher_TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC067 + cipher_TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC068 + cipher_TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC069 + cipher_TLS_PSK_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC06A + cipher_TLS_PSK_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC06B + cipher_TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC06C + cipher_TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC06D + cipher_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC06E + cipher_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC06F + cipher_TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC070 + cipher_TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC071 + cipher_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0xC072 + cipher_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 uint16 = 0xC073 + cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0xC074 + cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 uint16 = 0xC075 + cipher_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0xC076 + cipher_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 uint16 = 0xC077 + cipher_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0xC078 + cipher_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 uint16 = 0xC079 + cipher_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC07A + cipher_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC07B + cipher_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC07C + cipher_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC07D + cipher_TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC07E + cipher_TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC07F + cipher_TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC080 + cipher_TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC081 + cipher_TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC082 + cipher_TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC083 + cipher_TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC084 + cipher_TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC085 + cipher_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC086 + cipher_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC087 + cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC088 + cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC089 + cipher_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC08A + cipher_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC08B + cipher_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC08C + cipher_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC08D + cipher_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC08E + cipher_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC08F + cipher_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC090 + cipher_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC091 + cipher_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC092 + cipher_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC093 + cipher_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0xC094 + cipher_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 uint16 = 0xC095 + cipher_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0xC096 + cipher_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 uint16 = 0xC097 + cipher_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0xC098 + cipher_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 uint16 = 0xC099 + cipher_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0xC09A + cipher_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 uint16 = 0xC09B + cipher_TLS_RSA_WITH_AES_128_CCM uint16 = 0xC09C + cipher_TLS_RSA_WITH_AES_256_CCM uint16 = 0xC09D + cipher_TLS_DHE_RSA_WITH_AES_128_CCM uint16 = 0xC09E + cipher_TLS_DHE_RSA_WITH_AES_256_CCM uint16 = 0xC09F + cipher_TLS_RSA_WITH_AES_128_CCM_8 uint16 = 0xC0A0 + cipher_TLS_RSA_WITH_AES_256_CCM_8 uint16 = 0xC0A1 + cipher_TLS_DHE_RSA_WITH_AES_128_CCM_8 uint16 = 0xC0A2 + cipher_TLS_DHE_RSA_WITH_AES_256_CCM_8 uint16 = 0xC0A3 + cipher_TLS_PSK_WITH_AES_128_CCM uint16 = 0xC0A4 + cipher_TLS_PSK_WITH_AES_256_CCM uint16 = 0xC0A5 + cipher_TLS_DHE_PSK_WITH_AES_128_CCM uint16 = 0xC0A6 + cipher_TLS_DHE_PSK_WITH_AES_256_CCM uint16 = 0xC0A7 + cipher_TLS_PSK_WITH_AES_128_CCM_8 uint16 = 0xC0A8 + cipher_TLS_PSK_WITH_AES_256_CCM_8 uint16 = 0xC0A9 + cipher_TLS_PSK_DHE_WITH_AES_128_CCM_8 uint16 = 0xC0AA + cipher_TLS_PSK_DHE_WITH_AES_256_CCM_8 uint16 = 0xC0AB + cipher_TLS_ECDHE_ECDSA_WITH_AES_128_CCM uint16 = 0xC0AC + cipher_TLS_ECDHE_ECDSA_WITH_AES_256_CCM uint16 = 0xC0AD + cipher_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 uint16 = 0xC0AE + cipher_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 uint16 = 0xC0AF + // Unassigned uint16 = 0xC0B0-FF + // Unassigned uint16 = 0xC1-CB,* + // Unassigned uint16 = 0xCC00-A7 + cipher_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xCCA8 + cipher_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xCCA9 + cipher_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xCCAA + cipher_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xCCAB + cipher_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xCCAC + cipher_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xCCAD + cipher_TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xCCAE +) + +// isBadCipher reports whether the cipher is blacklisted by the HTTP/2 spec. +// References: +// https://tools.ietf.org/html/rfc7540#appendix-A +// Reject cipher suites from Appendix A. +// "This list includes those cipher suites that do not +// offer an ephemeral key exchange and those that are +// based on the TLS null, stream or block cipher type" +func isBadCipher(cipher uint16) bool { + switch cipher { + case cipher_TLS_NULL_WITH_NULL_NULL, + cipher_TLS_RSA_WITH_NULL_MD5, + cipher_TLS_RSA_WITH_NULL_SHA, + cipher_TLS_RSA_EXPORT_WITH_RC4_40_MD5, + cipher_TLS_RSA_WITH_RC4_128_MD5, + cipher_TLS_RSA_WITH_RC4_128_SHA, + cipher_TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5, + cipher_TLS_RSA_WITH_IDEA_CBC_SHA, + cipher_TLS_RSA_EXPORT_WITH_DES40_CBC_SHA, + cipher_TLS_RSA_WITH_DES_CBC_SHA, + cipher_TLS_RSA_WITH_3DES_EDE_CBC_SHA, + cipher_TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA, + cipher_TLS_DH_DSS_WITH_DES_CBC_SHA, + cipher_TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA, + cipher_TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA, + cipher_TLS_DH_RSA_WITH_DES_CBC_SHA, + cipher_TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA, + cipher_TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, + cipher_TLS_DHE_DSS_WITH_DES_CBC_SHA, + cipher_TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA, + cipher_TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, + cipher_TLS_DHE_RSA_WITH_DES_CBC_SHA, + cipher_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, + cipher_TLS_DH_anon_EXPORT_WITH_RC4_40_MD5, + cipher_TLS_DH_anon_WITH_RC4_128_MD5, + cipher_TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA, + cipher_TLS_DH_anon_WITH_DES_CBC_SHA, + cipher_TLS_DH_anon_WITH_3DES_EDE_CBC_SHA, + cipher_TLS_KRB5_WITH_DES_CBC_SHA, + cipher_TLS_KRB5_WITH_3DES_EDE_CBC_SHA, + cipher_TLS_KRB5_WITH_RC4_128_SHA, + cipher_TLS_KRB5_WITH_IDEA_CBC_SHA, + cipher_TLS_KRB5_WITH_DES_CBC_MD5, + cipher_TLS_KRB5_WITH_3DES_EDE_CBC_MD5, + cipher_TLS_KRB5_WITH_RC4_128_MD5, + cipher_TLS_KRB5_WITH_IDEA_CBC_MD5, + cipher_TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA, + cipher_TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA, + cipher_TLS_KRB5_EXPORT_WITH_RC4_40_SHA, + cipher_TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5, + cipher_TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5, + cipher_TLS_KRB5_EXPORT_WITH_RC4_40_MD5, + cipher_TLS_PSK_WITH_NULL_SHA, + cipher_TLS_DHE_PSK_WITH_NULL_SHA, + cipher_TLS_RSA_PSK_WITH_NULL_SHA, + cipher_TLS_RSA_WITH_AES_128_CBC_SHA, + cipher_TLS_DH_DSS_WITH_AES_128_CBC_SHA, + cipher_TLS_DH_RSA_WITH_AES_128_CBC_SHA, + cipher_TLS_DHE_DSS_WITH_AES_128_CBC_SHA, + cipher_TLS_DHE_RSA_WITH_AES_128_CBC_SHA, + cipher_TLS_DH_anon_WITH_AES_128_CBC_SHA, + cipher_TLS_RSA_WITH_AES_256_CBC_SHA, + cipher_TLS_DH_DSS_WITH_AES_256_CBC_SHA, + cipher_TLS_DH_RSA_WITH_AES_256_CBC_SHA, + cipher_TLS_DHE_DSS_WITH_AES_256_CBC_SHA, + cipher_TLS_DHE_RSA_WITH_AES_256_CBC_SHA, + cipher_TLS_DH_anon_WITH_AES_256_CBC_SHA, + cipher_TLS_RSA_WITH_NULL_SHA256, + cipher_TLS_RSA_WITH_AES_128_CBC_SHA256, + cipher_TLS_RSA_WITH_AES_256_CBC_SHA256, + cipher_TLS_DH_DSS_WITH_AES_128_CBC_SHA256, + cipher_TLS_DH_RSA_WITH_AES_128_CBC_SHA256, + cipher_TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, + cipher_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA, + cipher_TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA, + cipher_TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA, + cipher_TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA, + cipher_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA, + cipher_TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA, + cipher_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, + cipher_TLS_DH_DSS_WITH_AES_256_CBC_SHA256, + cipher_TLS_DH_RSA_WITH_AES_256_CBC_SHA256, + cipher_TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, + cipher_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, + cipher_TLS_DH_anon_WITH_AES_128_CBC_SHA256, + cipher_TLS_DH_anon_WITH_AES_256_CBC_SHA256, + cipher_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA, + cipher_TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA, + cipher_TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA, + cipher_TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA, + cipher_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA, + cipher_TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA, + cipher_TLS_PSK_WITH_RC4_128_SHA, + cipher_TLS_PSK_WITH_3DES_EDE_CBC_SHA, + cipher_TLS_PSK_WITH_AES_128_CBC_SHA, + cipher_TLS_PSK_WITH_AES_256_CBC_SHA, + cipher_TLS_DHE_PSK_WITH_RC4_128_SHA, + cipher_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA, + cipher_TLS_DHE_PSK_WITH_AES_128_CBC_SHA, + cipher_TLS_DHE_PSK_WITH_AES_256_CBC_SHA, + cipher_TLS_RSA_PSK_WITH_RC4_128_SHA, + cipher_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA, + cipher_TLS_RSA_PSK_WITH_AES_128_CBC_SHA, + cipher_TLS_RSA_PSK_WITH_AES_256_CBC_SHA, + cipher_TLS_RSA_WITH_SEED_CBC_SHA, + cipher_TLS_DH_DSS_WITH_SEED_CBC_SHA, + cipher_TLS_DH_RSA_WITH_SEED_CBC_SHA, + cipher_TLS_DHE_DSS_WITH_SEED_CBC_SHA, + cipher_TLS_DHE_RSA_WITH_SEED_CBC_SHA, + cipher_TLS_DH_anon_WITH_SEED_CBC_SHA, + cipher_TLS_RSA_WITH_AES_128_GCM_SHA256, + cipher_TLS_RSA_WITH_AES_256_GCM_SHA384, + cipher_TLS_DH_RSA_WITH_AES_128_GCM_SHA256, + cipher_TLS_DH_RSA_WITH_AES_256_GCM_SHA384, + cipher_TLS_DH_DSS_WITH_AES_128_GCM_SHA256, + cipher_TLS_DH_DSS_WITH_AES_256_GCM_SHA384, + cipher_TLS_DH_anon_WITH_AES_128_GCM_SHA256, + cipher_TLS_DH_anon_WITH_AES_256_GCM_SHA384, + cipher_TLS_PSK_WITH_AES_128_GCM_SHA256, + cipher_TLS_PSK_WITH_AES_256_GCM_SHA384, + cipher_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256, + cipher_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384, + cipher_TLS_PSK_WITH_AES_128_CBC_SHA256, + cipher_TLS_PSK_WITH_AES_256_CBC_SHA384, + cipher_TLS_PSK_WITH_NULL_SHA256, + cipher_TLS_PSK_WITH_NULL_SHA384, + cipher_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256, + cipher_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384, + cipher_TLS_DHE_PSK_WITH_NULL_SHA256, + cipher_TLS_DHE_PSK_WITH_NULL_SHA384, + cipher_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256, + cipher_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384, + cipher_TLS_RSA_PSK_WITH_NULL_SHA256, + cipher_TLS_RSA_PSK_WITH_NULL_SHA384, + cipher_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256, + cipher_TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256, + cipher_TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256, + cipher_TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256, + cipher_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256, + cipher_TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256, + cipher_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256, + cipher_TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256, + cipher_TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256, + cipher_TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256, + cipher_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256, + cipher_TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256, + cipher_TLS_EMPTY_RENEGOTIATION_INFO_SCSV, + cipher_TLS_ECDH_ECDSA_WITH_NULL_SHA, + cipher_TLS_ECDH_ECDSA_WITH_RC4_128_SHA, + cipher_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, + cipher_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, + cipher_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, + cipher_TLS_ECDHE_ECDSA_WITH_NULL_SHA, + cipher_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, + cipher_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, + cipher_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, + cipher_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, + cipher_TLS_ECDH_RSA_WITH_NULL_SHA, + cipher_TLS_ECDH_RSA_WITH_RC4_128_SHA, + cipher_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, + cipher_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, + cipher_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, + cipher_TLS_ECDHE_RSA_WITH_NULL_SHA, + cipher_TLS_ECDHE_RSA_WITH_RC4_128_SHA, + cipher_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, + cipher_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, + cipher_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, + cipher_TLS_ECDH_anon_WITH_NULL_SHA, + cipher_TLS_ECDH_anon_WITH_RC4_128_SHA, + cipher_TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA, + cipher_TLS_ECDH_anon_WITH_AES_128_CBC_SHA, + cipher_TLS_ECDH_anon_WITH_AES_256_CBC_SHA, + cipher_TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA, + cipher_TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA, + cipher_TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA, + cipher_TLS_SRP_SHA_WITH_AES_128_CBC_SHA, + cipher_TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA, + cipher_TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA, + cipher_TLS_SRP_SHA_WITH_AES_256_CBC_SHA, + cipher_TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA, + cipher_TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA, + cipher_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, + cipher_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, + cipher_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, + cipher_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, + cipher_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, + cipher_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, + cipher_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, + cipher_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, + cipher_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, + cipher_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, + cipher_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, + cipher_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, + cipher_TLS_ECDHE_PSK_WITH_RC4_128_SHA, + cipher_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA, + cipher_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA, + cipher_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA, + cipher_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, + cipher_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384, + cipher_TLS_ECDHE_PSK_WITH_NULL_SHA, + cipher_TLS_ECDHE_PSK_WITH_NULL_SHA256, + cipher_TLS_ECDHE_PSK_WITH_NULL_SHA384, + cipher_TLS_RSA_WITH_ARIA_128_CBC_SHA256, + cipher_TLS_RSA_WITH_ARIA_256_CBC_SHA384, + cipher_TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256, + cipher_TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384, + cipher_TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256, + cipher_TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384, + cipher_TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256, + cipher_TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384, + cipher_TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256, + cipher_TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384, + cipher_TLS_DH_anon_WITH_ARIA_128_CBC_SHA256, + cipher_TLS_DH_anon_WITH_ARIA_256_CBC_SHA384, + cipher_TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256, + cipher_TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384, + cipher_TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256, + cipher_TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384, + cipher_TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256, + cipher_TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384, + cipher_TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256, + cipher_TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384, + cipher_TLS_RSA_WITH_ARIA_128_GCM_SHA256, + cipher_TLS_RSA_WITH_ARIA_256_GCM_SHA384, + cipher_TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256, + cipher_TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384, + cipher_TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256, + cipher_TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384, + cipher_TLS_DH_anon_WITH_ARIA_128_GCM_SHA256, + cipher_TLS_DH_anon_WITH_ARIA_256_GCM_SHA384, + cipher_TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256, + cipher_TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384, + cipher_TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256, + cipher_TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384, + cipher_TLS_PSK_WITH_ARIA_128_CBC_SHA256, + cipher_TLS_PSK_WITH_ARIA_256_CBC_SHA384, + cipher_TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256, + cipher_TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384, + cipher_TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256, + cipher_TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384, + cipher_TLS_PSK_WITH_ARIA_128_GCM_SHA256, + cipher_TLS_PSK_WITH_ARIA_256_GCM_SHA384, + cipher_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256, + cipher_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384, + cipher_TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256, + cipher_TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384, + cipher_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256, + cipher_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384, + cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256, + cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384, + cipher_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256, + cipher_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384, + cipher_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256, + cipher_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384, + cipher_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256, + cipher_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384, + cipher_TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256, + cipher_TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384, + cipher_TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256, + cipher_TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384, + cipher_TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256, + cipher_TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384, + cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256, + cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384, + cipher_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256, + cipher_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384, + cipher_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256, + cipher_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384, + cipher_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256, + cipher_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384, + cipher_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256, + cipher_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384, + cipher_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256, + cipher_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, + cipher_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256, + cipher_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384, + cipher_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256, + cipher_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, + cipher_TLS_RSA_WITH_AES_128_CCM, + cipher_TLS_RSA_WITH_AES_256_CCM, + cipher_TLS_RSA_WITH_AES_128_CCM_8, + cipher_TLS_RSA_WITH_AES_256_CCM_8, + cipher_TLS_PSK_WITH_AES_128_CCM, + cipher_TLS_PSK_WITH_AES_256_CCM, + cipher_TLS_PSK_WITH_AES_128_CCM_8, + cipher_TLS_PSK_WITH_AES_256_CCM_8: + return true + default: + return false + } +} diff --git a/vendor/golang.org/x/net/http2/client_conn_pool.go b/vendor/golang.org/x/net/http2/client_conn_pool.go index b13941258a35..bdf5652b01ce 100644 --- a/vendor/golang.org/x/net/http2/client_conn_pool.go +++ b/vendor/golang.org/x/net/http2/client_conn_pool.go @@ -247,7 +247,7 @@ func filterOutClientConn(in []*ClientConn, exclude *ClientConn) []*ClientConn { } // noDialClientConnPool is an implementation of http2.ClientConnPool -// which never dials. We let the HTTP/1.1 client dial and use its TLS +// which never dials. We let the HTTP/1.1 client dial and use its TLS // connection instead. type noDialClientConnPool struct{ *clientConnPool } diff --git a/vendor/golang.org/x/net/http2/databuffer.go b/vendor/golang.org/x/net/http2/databuffer.go new file mode 100644 index 000000000000..a3067f8de741 --- /dev/null +++ b/vendor/golang.org/x/net/http2/databuffer.go @@ -0,0 +1,146 @@ +// 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 http2 + +import ( + "errors" + "fmt" + "sync" +) + +// Buffer chunks are allocated from a pool to reduce pressure on GC. +// The maximum wasted space per dataBuffer is 2x the largest size class, +// which happens when the dataBuffer has multiple chunks and there is +// one unread byte in both the first and last chunks. We use a few size +// classes to minimize overheads for servers that typically receive very +// small request bodies. +// +// TODO: Benchmark to determine if the pools are necessary. The GC may have +// improved enough that we can instead allocate chunks like this: +// make([]byte, max(16<<10, expectedBytesRemaining)) +var ( + dataChunkSizeClasses = []int{ + 1 << 10, + 2 << 10, + 4 << 10, + 8 << 10, + 16 << 10, + } + dataChunkPools = [...]sync.Pool{ + {New: func() interface{} { return make([]byte, 1<<10) }}, + {New: func() interface{} { return make([]byte, 2<<10) }}, + {New: func() interface{} { return make([]byte, 4<<10) }}, + {New: func() interface{} { return make([]byte, 8<<10) }}, + {New: func() interface{} { return make([]byte, 16<<10) }}, + } +) + +func getDataBufferChunk(size int64) []byte { + i := 0 + for ; i < len(dataChunkSizeClasses)-1; i++ { + if size <= int64(dataChunkSizeClasses[i]) { + break + } + } + return dataChunkPools[i].Get().([]byte) +} + +func putDataBufferChunk(p []byte) { + for i, n := range dataChunkSizeClasses { + if len(p) == n { + dataChunkPools[i].Put(p) + return + } + } + panic(fmt.Sprintf("unexpected buffer len=%v", len(p))) +} + +// dataBuffer is an io.ReadWriter backed by a list of data chunks. +// Each dataBuffer is used to read DATA frames on a single stream. +// The buffer is divided into chunks so the server can limit the +// total memory used by a single connection without limiting the +// request body size on any single stream. +type dataBuffer struct { + chunks [][]byte + r int // next byte to read is chunks[0][r] + w int // next byte to write is chunks[len(chunks)-1][w] + size int // total buffered bytes + expected int64 // we expect at least this many bytes in future Write calls (ignored if <= 0) +} + +var errReadEmpty = errors.New("read from empty dataBuffer") + +// Read copies bytes from the buffer into p. +// It is an error to read when no data is available. +func (b *dataBuffer) Read(p []byte) (int, error) { + if b.size == 0 { + return 0, errReadEmpty + } + var ntotal int + for len(p) > 0 && b.size > 0 { + readFrom := b.bytesFromFirstChunk() + n := copy(p, readFrom) + p = p[n:] + ntotal += n + b.r += n + b.size -= n + // If the first chunk has been consumed, advance to the next chunk. + if b.r == len(b.chunks[0]) { + putDataBufferChunk(b.chunks[0]) + end := len(b.chunks) - 1 + copy(b.chunks[:end], b.chunks[1:]) + b.chunks[end] = nil + b.chunks = b.chunks[:end] + b.r = 0 + } + } + return ntotal, nil +} + +func (b *dataBuffer) bytesFromFirstChunk() []byte { + if len(b.chunks) == 1 { + return b.chunks[0][b.r:b.w] + } + return b.chunks[0][b.r:] +} + +// Len returns the number of bytes of the unread portion of the buffer. +func (b *dataBuffer) Len() int { + return b.size +} + +// Write appends p to the buffer. +func (b *dataBuffer) Write(p []byte) (int, error) { + ntotal := len(p) + for len(p) > 0 { + // If the last chunk is empty, allocate a new chunk. Try to allocate + // enough to fully copy p plus any additional bytes we expect to + // receive. However, this may allocate less than len(p). + want := int64(len(p)) + if b.expected > want { + want = b.expected + } + chunk := b.lastChunkOrAlloc(want) + n := copy(chunk[b.w:], p) + p = p[n:] + b.w += n + b.size += n + b.expected -= int64(n) + } + return ntotal, nil +} + +func (b *dataBuffer) lastChunkOrAlloc(want int64) []byte { + if len(b.chunks) != 0 { + last := b.chunks[len(b.chunks)-1] + if b.w < len(last) { + return last + } + } + chunk := getDataBufferChunk(want) + b.chunks = append(b.chunks, chunk) + b.w = 0 + return chunk +} diff --git a/vendor/golang.org/x/net/http2/fixed_buffer.go b/vendor/golang.org/x/net/http2/fixed_buffer.go deleted file mode 100644 index 47da0f0bf71f..000000000000 --- a/vendor/golang.org/x/net/http2/fixed_buffer.go +++ /dev/null @@ -1,60 +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 http2 - -import ( - "errors" -) - -// fixedBuffer is an io.ReadWriter backed by a fixed size buffer. -// It never allocates, but moves old data as new data is written. -type fixedBuffer struct { - buf []byte - r, w int -} - -var ( - errReadEmpty = errors.New("read from empty fixedBuffer") - errWriteFull = errors.New("write on full fixedBuffer") -) - -// Read copies bytes from the buffer into p. -// It is an error to read when no data is available. -func (b *fixedBuffer) Read(p []byte) (n int, err error) { - if b.r == b.w { - return 0, errReadEmpty - } - n = copy(p, b.buf[b.r:b.w]) - b.r += n - if b.r == b.w { - b.r = 0 - b.w = 0 - } - return n, nil -} - -// Len returns the number of bytes of the unread portion of the buffer. -func (b *fixedBuffer) Len() int { - return b.w - b.r -} - -// Write copies bytes from p into the buffer. -// It is an error to write more data than the buffer can hold. -func (b *fixedBuffer) Write(p []byte) (n int, err error) { - // Slide existing data to beginning. - if b.r > 0 && len(p) > len(b.buf)-b.w { - copy(b.buf, b.buf[b.r:b.w]) - b.w -= b.r - b.r = 0 - } - - // Write new data. - n = copy(b.buf[b.w:], p) - b.w += n - if n < len(p) { - err = errWriteFull - } - return n, err -} diff --git a/vendor/golang.org/x/net/http2/frame.go b/vendor/golang.org/x/net/http2/frame.go index 358833fedfe4..3b14890728f5 100644 --- a/vendor/golang.org/x/net/http2/frame.go +++ b/vendor/golang.org/x/net/http2/frame.go @@ -122,7 +122,7 @@ var flagName = map[FrameType]map[Flags]string{ // a frameParser parses a frame given its FrameHeader and payload // bytes. The length of payload will always equal fh.Length (which // might be 0). -type frameParser func(fh FrameHeader, payload []byte) (Frame, error) +type frameParser func(fc *frameCache, fh FrameHeader, payload []byte) (Frame, error) var frameParsers = map[FrameType]frameParser{ FrameData: parseDataFrame, @@ -312,7 +312,7 @@ type Framer struct { MaxHeaderListSize uint32 // TODO: track which type of frame & with which flags was sent - // last. Then return an error (unless AllowIllegalWrites) if + // last. Then return an error (unless AllowIllegalWrites) if // we're in the middle of a header block and a // non-Continuation or Continuation on a different stream is // attempted to be written. @@ -323,6 +323,8 @@ type Framer struct { debugFramerBuf *bytes.Buffer debugReadLoggerf func(string, ...interface{}) debugWriteLoggerf func(string, ...interface{}) + + frameCache *frameCache // nil if frames aren't reused (default) } func (fr *Framer) maxHeaderListSize() uint32 { @@ -398,6 +400,27 @@ const ( maxFrameSize = 1<<24 - 1 ) +// SetReuseFrames allows the Framer to reuse Frames. +// If called on a Framer, Frames returned by calls to ReadFrame are only +// valid until the next call to ReadFrame. +func (fr *Framer) SetReuseFrames() { + if fr.frameCache != nil { + return + } + fr.frameCache = &frameCache{} +} + +type frameCache struct { + dataFrame DataFrame +} + +func (fc *frameCache) getDataFrame() *DataFrame { + if fc == nil { + return &DataFrame{} + } + return &fc.dataFrame +} + // NewFramer returns a Framer that writes frames to w and reads them from r. func NewFramer(w io.Writer, r io.Reader) *Framer { fr := &Framer{ @@ -477,7 +500,7 @@ func (fr *Framer) ReadFrame() (Frame, error) { if _, err := io.ReadFull(fr.r, payload); err != nil { return nil, err } - f, err := typeFrameParser(fh.Type)(fh, payload) + f, err := typeFrameParser(fh.Type)(fr.frameCache, fh, payload) if err != nil { if ce, ok := err.(connError); ok { return nil, fr.connError(ce.Code, ce.Reason) @@ -565,7 +588,7 @@ func (f *DataFrame) Data() []byte { return f.data } -func parseDataFrame(fh FrameHeader, payload []byte) (Frame, error) { +func parseDataFrame(fc *frameCache, fh FrameHeader, payload []byte) (Frame, error) { if fh.StreamID == 0 { // DATA frames MUST be associated with a stream. If a // DATA frame is received whose stream identifier @@ -574,9 +597,9 @@ func parseDataFrame(fh FrameHeader, payload []byte) (Frame, error) { // PROTOCOL_ERROR. return nil, connError{ErrCodeProtocol, "DATA frame with stream ID 0"} } - f := &DataFrame{ - FrameHeader: fh, - } + f := fc.getDataFrame() + f.FrameHeader = fh + var padSize byte if fh.Flags.Has(FlagDataPadded) { var err error @@ -600,6 +623,7 @@ var ( errStreamID = errors.New("invalid stream ID") errDepStreamID = errors.New("invalid dependent stream ID") errPadLength = errors.New("pad length too large") + errPadBytes = errors.New("padding bytes must all be zeros unless AllowIllegalWrites is enabled") ) func validStreamIDOrZero(streamID uint32) bool { @@ -623,6 +647,7 @@ func (f *Framer) WriteData(streamID uint32, endStream bool, data []byte) error { // // If pad is nil, the padding bit is not sent. // The length of pad must not exceed 255 bytes. +// The bytes of pad must all be zero, unless f.AllowIllegalWrites is set. // // It will perform exactly one Write to the underlying Writer. // It is the caller's responsibility not to violate the maximum frame size @@ -631,8 +656,18 @@ func (f *Framer) WriteDataPadded(streamID uint32, endStream bool, data, pad []by if !validStreamID(streamID) && !f.AllowIllegalWrites { return errStreamID } - if len(pad) > 255 { - return errPadLength + if len(pad) > 0 { + if len(pad) > 255 { + return errPadLength + } + if !f.AllowIllegalWrites { + for _, b := range pad { + if b != 0 { + // "Padding octets MUST be set to zero when sending." + return errPadBytes + } + } + } } var flags Flags if endStream { @@ -660,10 +695,10 @@ type SettingsFrame struct { p []byte } -func parseSettingsFrame(fh FrameHeader, p []byte) (Frame, error) { +func parseSettingsFrame(_ *frameCache, fh FrameHeader, p []byte) (Frame, error) { if fh.Flags.Has(FlagSettingsAck) && fh.Length > 0 { // When this (ACK 0x1) bit is set, the payload of the - // SETTINGS frame MUST be empty. Receipt of a + // SETTINGS frame MUST be empty. Receipt of a // SETTINGS frame with the ACK flag set and a length // field value other than 0 MUST be treated as a // connection error (Section 5.4.1) of type @@ -672,7 +707,7 @@ func parseSettingsFrame(fh FrameHeader, p []byte) (Frame, error) { } if fh.StreamID != 0 { // SETTINGS frames always apply to a connection, - // never a single stream. The stream identifier for a + // never a single stream. The stream identifier for a // SETTINGS frame MUST be zero (0x0). If an endpoint // receives a SETTINGS frame whose stream identifier // field is anything other than 0x0, the endpoint MUST @@ -762,7 +797,7 @@ type PingFrame struct { func (f *PingFrame) IsAck() bool { return f.Flags.Has(FlagPingAck) } -func parsePingFrame(fh FrameHeader, payload []byte) (Frame, error) { +func parsePingFrame(_ *frameCache, fh FrameHeader, payload []byte) (Frame, error) { if len(payload) != 8 { return nil, ConnectionError(ErrCodeFrameSize) } @@ -802,7 +837,7 @@ func (f *GoAwayFrame) DebugData() []byte { return f.debugData } -func parseGoAwayFrame(fh FrameHeader, p []byte) (Frame, error) { +func parseGoAwayFrame(_ *frameCache, fh FrameHeader, p []byte) (Frame, error) { if fh.StreamID != 0 { return nil, ConnectionError(ErrCodeProtocol) } @@ -842,7 +877,7 @@ func (f *UnknownFrame) Payload() []byte { return f.p } -func parseUnknownFrame(fh FrameHeader, p []byte) (Frame, error) { +func parseUnknownFrame(_ *frameCache, fh FrameHeader, p []byte) (Frame, error) { return &UnknownFrame{fh, p}, nil } @@ -853,7 +888,7 @@ type WindowUpdateFrame struct { Increment uint32 // never read with high bit set } -func parseWindowUpdateFrame(fh FrameHeader, p []byte) (Frame, error) { +func parseWindowUpdateFrame(_ *frameCache, fh FrameHeader, p []byte) (Frame, error) { if len(p) != 4 { return nil, ConnectionError(ErrCodeFrameSize) } @@ -918,12 +953,12 @@ func (f *HeadersFrame) HasPriority() bool { return f.FrameHeader.Flags.Has(FlagHeadersPriority) } -func parseHeadersFrame(fh FrameHeader, p []byte) (_ Frame, err error) { +func parseHeadersFrame(_ *frameCache, fh FrameHeader, p []byte) (_ Frame, err error) { hf := &HeadersFrame{ FrameHeader: fh, } if fh.StreamID == 0 { - // HEADERS frames MUST be associated with a stream. If a HEADERS frame + // HEADERS frames MUST be associated with a stream. If a HEADERS frame // is received whose stream identifier field is 0x0, the recipient MUST // respond with a connection error (Section 5.4.1) of type // PROTOCOL_ERROR. @@ -1045,7 +1080,7 @@ type PriorityParam struct { Exclusive bool // Weight is the stream's zero-indexed weight. It should be - // set together with StreamDep, or neither should be set. Per + // set together with StreamDep, or neither should be set. Per // the spec, "Add one to the value to obtain a weight between // 1 and 256." Weight uint8 @@ -1055,7 +1090,7 @@ func (p PriorityParam) IsZero() bool { return p == PriorityParam{} } -func parsePriorityFrame(fh FrameHeader, payload []byte) (Frame, error) { +func parsePriorityFrame(_ *frameCache, fh FrameHeader, payload []byte) (Frame, error) { if fh.StreamID == 0 { return nil, connError{ErrCodeProtocol, "PRIORITY frame with stream ID 0"} } @@ -1102,7 +1137,7 @@ type RSTStreamFrame struct { ErrCode ErrCode } -func parseRSTStreamFrame(fh FrameHeader, p []byte) (Frame, error) { +func parseRSTStreamFrame(_ *frameCache, fh FrameHeader, p []byte) (Frame, error) { if len(p) != 4 { return nil, ConnectionError(ErrCodeFrameSize) } @@ -1132,7 +1167,7 @@ type ContinuationFrame struct { headerFragBuf []byte } -func parseContinuationFrame(fh FrameHeader, p []byte) (Frame, error) { +func parseContinuationFrame(_ *frameCache, fh FrameHeader, p []byte) (Frame, error) { if fh.StreamID == 0 { return nil, connError{ErrCodeProtocol, "CONTINUATION frame with stream ID 0"} } @@ -1182,7 +1217,7 @@ func (f *PushPromiseFrame) HeadersEnded() bool { return f.FrameHeader.Flags.Has(FlagPushPromiseEndHeaders) } -func parsePushPromise(fh FrameHeader, p []byte) (_ Frame, err error) { +func parsePushPromise(_ *frameCache, fh FrameHeader, p []byte) (_ Frame, err error) { pp := &PushPromiseFrame{ FrameHeader: fh, } diff --git a/vendor/golang.org/x/net/http2/go16.go b/vendor/golang.org/x/net/http2/go16.go index 2b72855f5521..00b2e9e3cf3a 100644 --- a/vendor/golang.org/x/net/http2/go16.go +++ b/vendor/golang.org/x/net/http2/go16.go @@ -7,7 +7,6 @@ package http2 import ( - "crypto/tls" "net/http" "time" ) @@ -15,29 +14,3 @@ import ( func transportExpectContinueTimeout(t1 *http.Transport) time.Duration { return t1.ExpectContinueTimeout } - -// isBadCipher reports whether the cipher is blacklisted by the HTTP/2 spec. -func isBadCipher(cipher uint16) bool { - switch cipher { - case tls.TLS_RSA_WITH_RC4_128_SHA, - tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA, - tls.TLS_RSA_WITH_AES_128_CBC_SHA, - tls.TLS_RSA_WITH_AES_256_CBC_SHA, - tls.TLS_RSA_WITH_AES_128_GCM_SHA256, - tls.TLS_RSA_WITH_AES_256_GCM_SHA384, - tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, - tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, - tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, - tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA, - tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, - tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, - tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: - // Reject cipher suites from Appendix A. - // "This list includes those cipher suites that do not - // offer an ephemeral key exchange and those that are - // based on the TLS null, stream or block cipher type" - return true - default: - return false - } -} diff --git a/vendor/golang.org/x/net/http2/go18.go b/vendor/golang.org/x/net/http2/go18.go index 633202c39fd1..73cc2381f32b 100644 --- a/vendor/golang.org/x/net/http2/go18.go +++ b/vendor/golang.org/x/net/http2/go18.go @@ -12,7 +12,11 @@ import ( "net/http" ) -func cloneTLSConfig(c *tls.Config) *tls.Config { return c.Clone() } +func cloneTLSConfig(c *tls.Config) *tls.Config { + c2 := c.Clone() + c2.GetClientCertificate = c.GetClientCertificate // golang.org/issue/19264 + return c2 +} var _ http.Pusher = (*responseWriter)(nil) diff --git a/vendor/golang.org/x/net/http2/go19.go b/vendor/golang.org/x/net/http2/go19.go new file mode 100644 index 000000000000..38124ba56e25 --- /dev/null +++ b/vendor/golang.org/x/net/http2/go19.go @@ -0,0 +1,16 @@ +// 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 go1.9 + +package http2 + +import ( + "net/http" +) + +func configureServer19(s *http.Server, conf *Server) error { + s.RegisterOnShutdown(conf.state.startGracefulShutdown) + return nil +} diff --git a/vendor/golang.org/x/net/http2/hpack/encode.go b/vendor/golang.org/x/net/http2/hpack/encode.go index f9bb03398483..54726c2a3c52 100644 --- a/vendor/golang.org/x/net/http2/hpack/encode.go +++ b/vendor/golang.org/x/net/http2/hpack/encode.go @@ -39,13 +39,14 @@ func NewEncoder(w io.Writer) *Encoder { tableSizeUpdate: false, w: w, } + e.dynTab.table.init() e.dynTab.setMaxSize(initialHeaderTableSize) return e } // WriteField encodes f into a single Write to e's underlying Writer. // This function may also produce bytes for "Header Table Size Update" -// if necessary. If produced, it is done before encoding f. +// if necessary. If produced, it is done before encoding f. func (e *Encoder) WriteField(f HeaderField) error { e.buf = e.buf[:0] @@ -88,29 +89,17 @@ func (e *Encoder) WriteField(f HeaderField) error { // only name matches, i points to that index and nameValueMatch // becomes false. func (e *Encoder) searchTable(f HeaderField) (i uint64, nameValueMatch bool) { - for idx, hf := range staticTable { - if !constantTimeStringCompare(hf.Name, f.Name) { - continue - } - if i == 0 { - i = uint64(idx + 1) - } - if f.Sensitive { - continue - } - if !constantTimeStringCompare(hf.Value, f.Value) { - continue - } - i = uint64(idx + 1) - nameValueMatch = true - return + i, nameValueMatch = staticTable.search(f) + if nameValueMatch { + return i, true } - j, nameValueMatch := e.dynTab.search(f) + j, nameValueMatch := e.dynTab.table.search(f) if nameValueMatch || (i == 0 && j != 0) { - i = j + uint64(len(staticTable)) + return j + uint64(staticTable.len()), nameValueMatch } - return + + return i, false } // SetMaxDynamicTableSize changes the dynamic header table size to v. diff --git a/vendor/golang.org/x/net/http2/hpack/hpack.go b/vendor/golang.org/x/net/http2/hpack/hpack.go index 135b9f62cd64..176644acdace 100644 --- a/vendor/golang.org/x/net/http2/hpack/hpack.go +++ b/vendor/golang.org/x/net/http2/hpack/hpack.go @@ -61,7 +61,7 @@ func (hf HeaderField) String() string { func (hf HeaderField) Size() uint32 { // http://http2.github.io/http2-spec/compression.html#rfc.section.4.1 // "The size of the dynamic table is the sum of the size of - // its entries. The size of an entry is the sum of its name's + // its entries. The size of an entry is the sum of its name's // length in octets (as defined in Section 5.2), its value's // length in octets (see Section 5.2), plus 32. The size of // an entry is calculated using the length of the name and @@ -102,6 +102,7 @@ func NewDecoder(maxDynamicTableSize uint32, emitFunc func(f HeaderField)) *Decod emit: emitFunc, emitEnabled: true, } + d.dynTab.table.init() d.dynTab.allowedMaxSize = maxDynamicTableSize d.dynTab.setMaxSize(maxDynamicTableSize) return d @@ -154,12 +155,9 @@ func (d *Decoder) SetAllowedMaxDynamicTableSize(v uint32) { } type dynamicTable struct { - // ents is the FIFO described at // http://http2.github.io/http2-spec/compression.html#rfc.section.2.3.2 - // The newest (low index) is append at the end, and items are - // evicted from the front. - ents []HeaderField - size uint32 + table headerFieldTable + size uint32 // in bytes maxSize uint32 // current maxSize allowedMaxSize uint32 // maxSize may go up to this, inclusive } @@ -169,95 +167,45 @@ func (dt *dynamicTable) setMaxSize(v uint32) { dt.evict() } -// TODO: change dynamicTable to be a struct with a slice and a size int field, -// per http://http2.github.io/http2-spec/compression.html#rfc.section.4.1: -// -// -// Then make add increment the size. maybe the max size should move from Decoder to -// dynamicTable and add should return an ok bool if there was enough space. -// -// Later we'll need a remove operation on dynamicTable. - func (dt *dynamicTable) add(f HeaderField) { - dt.ents = append(dt.ents, f) + dt.table.addEntry(f) dt.size += f.Size() dt.evict() } -// If we're too big, evict old stuff (front of the slice) +// If we're too big, evict old stuff. func (dt *dynamicTable) evict() { - base := dt.ents // keep base pointer of slice - for dt.size > dt.maxSize { - dt.size -= dt.ents[0].Size() - dt.ents = dt.ents[1:] - } - - // Shift slice contents down if we evicted things. - if len(dt.ents) != len(base) { - copy(base, dt.ents) - dt.ents = base[:len(dt.ents)] + var n int + for dt.size > dt.maxSize && n < dt.table.len() { + dt.size -= dt.table.ents[n].Size() + n++ } -} - -// constantTimeStringCompare compares string a and b in a constant -// time manner. -func constantTimeStringCompare(a, b string) bool { - if len(a) != len(b) { - return false - } - - c := byte(0) - - for i := 0; i < len(a); i++ { - c |= a[i] ^ b[i] - } - - return c == 0 -} - -// Search searches f in the table. The return value i is 0 if there is -// no name match. If there is name match or name/value match, i is the -// index of that entry (1-based). If both name and value match, -// nameValueMatch becomes true. -func (dt *dynamicTable) search(f HeaderField) (i uint64, nameValueMatch bool) { - l := len(dt.ents) - for j := l - 1; j >= 0; j-- { - ent := dt.ents[j] - if !constantTimeStringCompare(ent.Name, f.Name) { - continue - } - if i == 0 { - i = uint64(l - j) - } - if f.Sensitive { - continue - } - if !constantTimeStringCompare(ent.Value, f.Value) { - continue - } - i = uint64(l - j) - nameValueMatch = true - return - } - return + dt.table.evictOldest(n) } func (d *Decoder) maxTableIndex() int { - return len(d.dynTab.ents) + len(staticTable) + // This should never overflow. RFC 7540 Section 6.5.2 limits the size of + // the dynamic table to 2^32 bytes, where each entry will occupy more than + // one byte. Further, the staticTable has a fixed, small length. + return d.dynTab.table.len() + staticTable.len() } func (d *Decoder) at(i uint64) (hf HeaderField, ok bool) { - if i < 1 { + // See Section 2.3.3. + if i == 0 { return } + if i <= uint64(staticTable.len()) { + return staticTable.ents[i-1], true + } if i > uint64(d.maxTableIndex()) { return } - if i <= uint64(len(staticTable)) { - return staticTable[i-1], true - } - dents := d.dynTab.ents - return dents[len(dents)-(int(i)-len(staticTable))], true + // In the dynamic table, newer entries have lower indices. + // However, dt.ents[0] is the oldest entry. Hence, dt.ents is + // the reversed dynamic table. + dt := d.dynTab.table + return dt.ents[dt.len()-(int(i)-staticTable.len())], true } // Decode decodes an entire block. @@ -307,7 +255,7 @@ func (d *Decoder) Write(p []byte) (n int, err error) { err = d.parseHeaderFieldRepr() if err == errNeedMore { // Extra paranoia, making sure saveBuf won't - // get too large. All the varint and string + // get too large. All the varint and string // reading code earlier should already catch // overlong things and return ErrStringLength, // but keep this as a last resort. diff --git a/vendor/golang.org/x/net/http2/hpack/tables.go b/vendor/golang.org/x/net/http2/hpack/tables.go index b9283a023302..a66cfbea69d9 100644 --- a/vendor/golang.org/x/net/http2/hpack/tables.go +++ b/vendor/golang.org/x/net/http2/hpack/tables.go @@ -4,73 +4,200 @@ package hpack -func pair(name, value string) HeaderField { - return HeaderField{Name: name, Value: value} +import ( + "fmt" +) + +// headerFieldTable implements a list of HeaderFields. +// This is used to implement the static and dynamic tables. +type headerFieldTable struct { + // For static tables, entries are never evicted. + // + // For dynamic tables, entries are evicted from ents[0] and added to the end. + // Each entry has a unique id that starts at one and increments for each + // entry that is added. This unique id is stable across evictions, meaning + // it can be used as a pointer to a specific entry. As in hpack, unique ids + // are 1-based. The unique id for ents[k] is k + evictCount + 1. + // + // Zero is not a valid unique id. + // + // evictCount should not overflow in any remotely practical situation. In + // practice, we will have one dynamic table per HTTP/2 connection. If we + // assume a very powerful server that handles 1M QPS per connection and each + // request adds (then evicts) 100 entries from the table, it would still take + // 2M years for evictCount to overflow. + ents []HeaderField + evictCount uint64 + + // byName maps a HeaderField name to the unique id of the newest entry with + // the same name. See above for a definition of "unique id". + byName map[string]uint64 + + // byNameValue maps a HeaderField name/value pair to the unique id of the newest + // entry with the same name and value. See above for a definition of "unique id". + byNameValue map[pairNameValue]uint64 +} + +type pairNameValue struct { + name, value string +} + +func (t *headerFieldTable) init() { + t.byName = make(map[string]uint64) + t.byNameValue = make(map[pairNameValue]uint64) +} + +// len reports the number of entries in the table. +func (t *headerFieldTable) len() int { + return len(t.ents) +} + +// addEntry adds a new entry. +func (t *headerFieldTable) addEntry(f HeaderField) { + id := uint64(t.len()) + t.evictCount + 1 + t.byName[f.Name] = id + t.byNameValue[pairNameValue{f.Name, f.Value}] = id + t.ents = append(t.ents, f) +} + +// evictOldest evicts the n oldest entries in the table. +func (t *headerFieldTable) evictOldest(n int) { + if n > t.len() { + panic(fmt.Sprintf("evictOldest(%v) on table with %v entries", n, t.len())) + } + for k := 0; k < n; k++ { + f := t.ents[k] + id := t.evictCount + uint64(k) + 1 + if t.byName[f.Name] == id { + delete(t.byName, f.Name) + } + if p := (pairNameValue{f.Name, f.Value}); t.byNameValue[p] == id { + delete(t.byNameValue, p) + } + } + copy(t.ents, t.ents[n:]) + for k := t.len() - n; k < t.len(); k++ { + t.ents[k] = HeaderField{} // so strings can be garbage collected + } + t.ents = t.ents[:t.len()-n] + if t.evictCount+uint64(n) < t.evictCount { + panic("evictCount overflow") + } + t.evictCount += uint64(n) +} + +// search finds f in the table. If there is no match, i is 0. +// If both name and value match, i is the matched index and nameValueMatch +// becomes true. If only name matches, i points to that index and +// nameValueMatch becomes false. +// +// The returned index is a 1-based HPACK index. For dynamic tables, HPACK says +// that index 1 should be the newest entry, but t.ents[0] is the oldest entry, +// meaning t.ents is reversed for dynamic tables. Hence, when t is a dynamic +// table, the return value i actually refers to the entry t.ents[t.len()-i]. +// +// All tables are assumed to be a dynamic tables except for the global +// staticTable pointer. +// +// See Section 2.3.3. +func (t *headerFieldTable) search(f HeaderField) (i uint64, nameValueMatch bool) { + if !f.Sensitive { + if id := t.byNameValue[pairNameValue{f.Name, f.Value}]; id != 0 { + return t.idToIndex(id), true + } + } + if id := t.byName[f.Name]; id != 0 { + return t.idToIndex(id), false + } + return 0, false +} + +// idToIndex converts a unique id to an HPACK index. +// See Section 2.3.3. +func (t *headerFieldTable) idToIndex(id uint64) uint64 { + if id <= t.evictCount { + panic(fmt.Sprintf("id (%v) <= evictCount (%v)", id, t.evictCount)) + } + k := id - t.evictCount - 1 // convert id to an index t.ents[k] + if t != staticTable { + return uint64(t.len()) - k // dynamic table + } + return k + 1 } // http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-07#appendix-B -var staticTable = [...]HeaderField{ - pair(":authority", ""), // index 1 (1-based) - pair(":method", "GET"), - pair(":method", "POST"), - pair(":path", "/"), - pair(":path", "/index.html"), - pair(":scheme", "http"), - pair(":scheme", "https"), - pair(":status", "200"), - pair(":status", "204"), - pair(":status", "206"), - pair(":status", "304"), - pair(":status", "400"), - pair(":status", "404"), - pair(":status", "500"), - pair("accept-charset", ""), - pair("accept-encoding", "gzip, deflate"), - pair("accept-language", ""), - pair("accept-ranges", ""), - pair("accept", ""), - pair("access-control-allow-origin", ""), - pair("age", ""), - pair("allow", ""), - pair("authorization", ""), - pair("cache-control", ""), - pair("content-disposition", ""), - pair("content-encoding", ""), - pair("content-language", ""), - pair("content-length", ""), - pair("content-location", ""), - pair("content-range", ""), - pair("content-type", ""), - pair("cookie", ""), - pair("date", ""), - pair("etag", ""), - pair("expect", ""), - pair("expires", ""), - pair("from", ""), - pair("host", ""), - pair("if-match", ""), - pair("if-modified-since", ""), - pair("if-none-match", ""), - pair("if-range", ""), - pair("if-unmodified-since", ""), - pair("last-modified", ""), - pair("link", ""), - pair("location", ""), - pair("max-forwards", ""), - pair("proxy-authenticate", ""), - pair("proxy-authorization", ""), - pair("range", ""), - pair("referer", ""), - pair("refresh", ""), - pair("retry-after", ""), - pair("server", ""), - pair("set-cookie", ""), - pair("strict-transport-security", ""), - pair("transfer-encoding", ""), - pair("user-agent", ""), - pair("vary", ""), - pair("via", ""), - pair("www-authenticate", ""), +var staticTable = newStaticTable() +var staticTableEntries = [...]HeaderField{ + {Name: ":authority"}, + {Name: ":method", Value: "GET"}, + {Name: ":method", Value: "POST"}, + {Name: ":path", Value: "/"}, + {Name: ":path", Value: "/index.html"}, + {Name: ":scheme", Value: "http"}, + {Name: ":scheme", Value: "https"}, + {Name: ":status", Value: "200"}, + {Name: ":status", Value: "204"}, + {Name: ":status", Value: "206"}, + {Name: ":status", Value: "304"}, + {Name: ":status", Value: "400"}, + {Name: ":status", Value: "404"}, + {Name: ":status", Value: "500"}, + {Name: "accept-charset"}, + {Name: "accept-encoding", Value: "gzip, deflate"}, + {Name: "accept-language"}, + {Name: "accept-ranges"}, + {Name: "accept"}, + {Name: "access-control-allow-origin"}, + {Name: "age"}, + {Name: "allow"}, + {Name: "authorization"}, + {Name: "cache-control"}, + {Name: "content-disposition"}, + {Name: "content-encoding"}, + {Name: "content-language"}, + {Name: "content-length"}, + {Name: "content-location"}, + {Name: "content-range"}, + {Name: "content-type"}, + {Name: "cookie"}, + {Name: "date"}, + {Name: "etag"}, + {Name: "expect"}, + {Name: "expires"}, + {Name: "from"}, + {Name: "host"}, + {Name: "if-match"}, + {Name: "if-modified-since"}, + {Name: "if-none-match"}, + {Name: "if-range"}, + {Name: "if-unmodified-since"}, + {Name: "last-modified"}, + {Name: "link"}, + {Name: "location"}, + {Name: "max-forwards"}, + {Name: "proxy-authenticate"}, + {Name: "proxy-authorization"}, + {Name: "range"}, + {Name: "referer"}, + {Name: "refresh"}, + {Name: "retry-after"}, + {Name: "server"}, + {Name: "set-cookie"}, + {Name: "strict-transport-security"}, + {Name: "transfer-encoding"}, + {Name: "user-agent"}, + {Name: "vary"}, + {Name: "via"}, + {Name: "www-authenticate"}, +} + +func newStaticTable() *headerFieldTable { + t := &headerFieldTable{} + t.init() + for _, e := range staticTableEntries[:] { + t.addEntry(e) + } + return t } var huffmanCodes = [256]uint32{ diff --git a/vendor/golang.org/x/net/http2/not_go16.go b/vendor/golang.org/x/net/http2/not_go16.go index efd2e1282cf6..508cebcc4db2 100644 --- a/vendor/golang.org/x/net/http2/not_go16.go +++ b/vendor/golang.org/x/net/http2/not_go16.go @@ -7,7 +7,6 @@ package http2 import ( - "crypto/tls" "net/http" "time" ) @@ -20,27 +19,3 @@ func transportExpectContinueTimeout(t1 *http.Transport) time.Duration { return 0 } - -// isBadCipher reports whether the cipher is blacklisted by the HTTP/2 spec. -func isBadCipher(cipher uint16) bool { - switch cipher { - case tls.TLS_RSA_WITH_RC4_128_SHA, - tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA, - tls.TLS_RSA_WITH_AES_128_CBC_SHA, - tls.TLS_RSA_WITH_AES_256_CBC_SHA, - tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, - tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, - tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, - tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA, - tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, - tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, - tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: - // Reject cipher suites from Appendix A. - // "This list includes those cipher suites that do not - // offer an ephemeral key exchange and those that are - // based on the TLS null, stream or block cipher type" - return true - default: - return false - } -} diff --git a/vendor/golang.org/x/net/http2/not_go19.go b/vendor/golang.org/x/net/http2/not_go19.go new file mode 100644 index 000000000000..5ae07726b743 --- /dev/null +++ b/vendor/golang.org/x/net/http2/not_go19.go @@ -0,0 +1,16 @@ +// 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 !go1.9 + +package http2 + +import ( + "net/http" +) + +func configureServer19(s *http.Server, conf *Server) error { + // not supported prior to go1.9 + return nil +} diff --git a/vendor/golang.org/x/net/http2/pipe.go b/vendor/golang.org/x/net/http2/pipe.go index 53b7a1daf630..0b9848be8c3d 100644 --- a/vendor/golang.org/x/net/http2/pipe.go +++ b/vendor/golang.org/x/net/http2/pipe.go @@ -10,13 +10,13 @@ import ( "sync" ) -// pipe is a goroutine-safe io.Reader/io.Writer pair. It's like +// pipe is a goroutine-safe io.Reader/io.Writer pair. It's like // io.Pipe except there are no PipeReader/PipeWriter halves, and the // underlying buffer is an interface. (io.Pipe is always unbuffered) type pipe struct { mu sync.Mutex - c sync.Cond // c.L lazily initialized to &p.mu - b pipeBuffer + c sync.Cond // c.L lazily initialized to &p.mu + b pipeBuffer // nil when done reading err error // read error once empty. non-nil means closed. breakErr error // immediate read error (caller doesn't see rest of b) donec chan struct{} // closed on error @@ -32,6 +32,9 @@ type pipeBuffer interface { func (p *pipe) Len() int { p.mu.Lock() defer p.mu.Unlock() + if p.b == nil { + return 0 + } return p.b.Len() } @@ -55,6 +58,7 @@ func (p *pipe) Read(d []byte) (n int, err error) { p.readFn() // e.g. copy trailers p.readFn = nil // not sticky like p.err } + p.b = nil return 0, p.err } p.c.Wait() @@ -75,6 +79,9 @@ func (p *pipe) Write(d []byte) (n int, err error) { if p.err != nil { return 0, errClosedPipeWrite } + if p.breakErr != nil { + return len(d), nil // discard when there is no reader + } return p.b.Write(d) } @@ -109,6 +116,9 @@ func (p *pipe) closeWithError(dst *error, err error, fn func()) { return } p.readFn = fn + if dst == &p.breakErr { + p.b = nil + } *dst = err p.closeDoneLocked() } diff --git a/vendor/golang.org/x/net/http2/server.go b/vendor/golang.org/x/net/http2/server.go index 3c6b90ccd55f..7367b31c5760 100644 --- a/vendor/golang.org/x/net/http2/server.go +++ b/vendor/golang.org/x/net/http2/server.go @@ -110,9 +110,41 @@ type Server struct { // activity for the purposes of IdleTimeout. IdleTimeout time.Duration + // MaxUploadBufferPerConnection is the size of the initial flow + // control window for each connections. The HTTP/2 spec does not + // allow this to be smaller than 65535 or larger than 2^32-1. + // If the value is outside this range, a default value will be + // used instead. + MaxUploadBufferPerConnection int32 + + // MaxUploadBufferPerStream is the size of the initial flow control + // window for each stream. The HTTP/2 spec does not allow this to + // be larger than 2^32-1. If the value is zero or larger than the + // maximum, a default value will be used instead. + MaxUploadBufferPerStream int32 + // NewWriteScheduler constructs a write scheduler for a connection. // If nil, a default scheduler is chosen. NewWriteScheduler func() WriteScheduler + + // Internal state. This is a pointer (rather than embedded directly) + // so that we don't embed a Mutex in this struct, which will make the + // struct non-copyable, which might break some callers. + state *serverInternalState +} + +func (s *Server) initialConnRecvWindowSize() int32 { + if s.MaxUploadBufferPerConnection > initialWindowSize { + return s.MaxUploadBufferPerConnection + } + return 1 << 20 +} + +func (s *Server) initialStreamRecvWindowSize() int32 { + if s.MaxUploadBufferPerStream > 0 { + return s.MaxUploadBufferPerStream + } + return 1 << 20 } func (s *Server) maxReadFrameSize() uint32 { @@ -129,6 +161,40 @@ func (s *Server) maxConcurrentStreams() uint32 { return defaultMaxStreams } +type serverInternalState struct { + mu sync.Mutex + activeConns map[*serverConn]struct{} +} + +func (s *serverInternalState) registerConn(sc *serverConn) { + if s == nil { + return // if the Server was used without calling ConfigureServer + } + s.mu.Lock() + s.activeConns[sc] = struct{}{} + s.mu.Unlock() +} + +func (s *serverInternalState) unregisterConn(sc *serverConn) { + if s == nil { + return // if the Server was used without calling ConfigureServer + } + s.mu.Lock() + delete(s.activeConns, sc) + s.mu.Unlock() +} + +func (s *serverInternalState) startGracefulShutdown() { + if s == nil { + return // if the Server was used without calling ConfigureServer + } + s.mu.Lock() + for sc := range s.activeConns { + sc.startGracefulShutdown() + } + s.mu.Unlock() +} + // ConfigureServer adds HTTP/2 support to a net/http Server. // // The configuration conf may be nil. @@ -141,9 +207,13 @@ func ConfigureServer(s *http.Server, conf *Server) error { if conf == nil { conf = new(Server) } + conf.state = &serverInternalState{activeConns: make(map[*serverConn]struct{})} if err := configureServer18(s, conf); err != nil { return err } + if err := configureServer19(s, conf); err != nil { + return err + } if s.TLSConfig == nil { s.TLSConfig = new(tls.Config) @@ -255,35 +325,37 @@ func (s *Server) ServeConn(c net.Conn, opts *ServeConnOpts) { defer cancel() sc := &serverConn{ - srv: s, - hs: opts.baseConfig(), - conn: c, - baseCtx: baseCtx, - remoteAddrStr: c.RemoteAddr().String(), - bw: newBufferedWriter(c), - handler: opts.handler(), - streams: make(map[uint32]*stream), - readFrameCh: make(chan readFrameResult), - wantWriteFrameCh: make(chan FrameWriteRequest, 8), - wantStartPushCh: make(chan startPushRequest, 8), - wroteFrameCh: make(chan frameWriteResult, 1), // buffered; one send in writeFrameAsync - bodyReadCh: make(chan bodyReadMsg), // buffering doesn't matter either way - doneServing: make(chan struct{}), - clientMaxStreams: math.MaxUint32, // Section 6.5.2: "Initially, there is no limit to this value" - advMaxStreams: s.maxConcurrentStreams(), - initialWindowSize: initialWindowSize, - maxFrameSize: initialMaxFrameSize, - headerTableSize: initialHeaderTableSize, - serveG: newGoroutineLock(), - pushEnabled: true, - } + srv: s, + hs: opts.baseConfig(), + conn: c, + baseCtx: baseCtx, + remoteAddrStr: c.RemoteAddr().String(), + bw: newBufferedWriter(c), + handler: opts.handler(), + streams: make(map[uint32]*stream), + readFrameCh: make(chan readFrameResult), + wantWriteFrameCh: make(chan FrameWriteRequest, 8), + serveMsgCh: make(chan interface{}, 8), + wroteFrameCh: make(chan frameWriteResult, 1), // buffered; one send in writeFrameAsync + bodyReadCh: make(chan bodyReadMsg), // buffering doesn't matter either way + doneServing: make(chan struct{}), + clientMaxStreams: math.MaxUint32, // Section 6.5.2: "Initially, there is no limit to this value" + advMaxStreams: s.maxConcurrentStreams(), + initialStreamSendWindowSize: initialWindowSize, + maxFrameSize: initialMaxFrameSize, + headerTableSize: initialHeaderTableSize, + serveG: newGoroutineLock(), + pushEnabled: true, + } + + s.state.registerConn(sc) + defer s.state.unregisterConn(sc) // The net/http package sets the write deadline from the // http.Server.WriteTimeout during the TLS handshake, but then - // passes the connection off to us with the deadline already - // set. Disarm it here so that it is not applied to additional - // streams opened on this connection. - // TODO: implement WriteTimeout fully. See Issue 18437. + // passes the connection off to us with the deadline already set. + // Write deadlines are set per stream in serverConn.newStream. + // Disarm the net.Conn write deadline here. if sc.hs.WriteTimeout != 0 { sc.conn.SetWriteDeadline(time.Time{}) } @@ -294,6 +366,9 @@ func (s *Server) ServeConn(c net.Conn, opts *ServeConnOpts) { sc.writeSched = NewRandomWriteScheduler() } + // These start at the RFC-specified defaults. If there is a higher + // configured value for inflow, that will be updated when we send a + // WINDOW_UPDATE shortly after sending SETTINGS. sc.flow.add(initialWindowSize) sc.inflow.add(initialWindowSize) sc.hpackEncoder = hpack.NewEncoder(&sc.headerWriteBuf) @@ -376,10 +451,9 @@ type serverConn struct { doneServing chan struct{} // closed when serverConn.serve ends readFrameCh chan readFrameResult // written by serverConn.readFrames wantWriteFrameCh chan FrameWriteRequest // from handlers -> serve - wantStartPushCh chan startPushRequest // from handlers -> serve wroteFrameCh chan frameWriteResult // from writeFrameAsync -> serve, tickles more frame writes bodyReadCh chan bodyReadMsg // from handlers -> serve - testHookCh chan func(int) // code to run on the serve loop + serveMsgCh chan interface{} // misc messages & code to send to / run on the serve loop flow flow // conn-wide (not stream-specific) outbound flow control inflow flow // conn-wide inbound flow control tlsState *tls.ConnectionState // shared by all handlers, like net/http @@ -387,38 +461,39 @@ type serverConn struct { writeSched WriteScheduler // Everything following is owned by the serve loop; use serveG.check(): - serveG goroutineLock // used to verify funcs are on serve() - pushEnabled bool - sawFirstSettings bool // got the initial SETTINGS frame after the preface - needToSendSettingsAck bool - unackedSettings int // how many SETTINGS have we sent without ACKs? - clientMaxStreams uint32 // SETTINGS_MAX_CONCURRENT_STREAMS from client (our PUSH_PROMISE limit) - advMaxStreams uint32 // our SETTINGS_MAX_CONCURRENT_STREAMS advertised the client - curClientStreams uint32 // number of open streams initiated by the client - curPushedStreams uint32 // number of open streams initiated by server push - maxClientStreamID uint32 // max ever seen from client (odd), or 0 if there have been no client requests - maxPushPromiseID uint32 // ID of the last push promise (even), or 0 if there have been no pushes - streams map[uint32]*stream - initialWindowSize int32 - maxFrameSize int32 - headerTableSize uint32 - peerMaxHeaderListSize uint32 // zero means unknown (default) - canonHeader map[string]string // http2-lower-case -> Go-Canonical-Case - writingFrame bool // started writing a frame (on serve goroutine or separate) - writingFrameAsync bool // started a frame on its own goroutine but haven't heard back on wroteFrameCh - needsFrameFlush bool // last frame write wasn't a flush - inGoAway bool // we've started to or sent GOAWAY - inFrameScheduleLoop bool // whether we're in the scheduleFrameWrite loop - needToSendGoAway bool // we need to schedule a GOAWAY frame write - goAwayCode ErrCode - shutdownTimerCh <-chan time.Time // nil until used - shutdownTimer *time.Timer // nil until used - idleTimer *time.Timer // nil if unused - idleTimerCh <-chan time.Time // nil if unused + serveG goroutineLock // used to verify funcs are on serve() + pushEnabled bool + sawFirstSettings bool // got the initial SETTINGS frame after the preface + needToSendSettingsAck bool + unackedSettings int // how many SETTINGS have we sent without ACKs? + clientMaxStreams uint32 // SETTINGS_MAX_CONCURRENT_STREAMS from client (our PUSH_PROMISE limit) + advMaxStreams uint32 // our SETTINGS_MAX_CONCURRENT_STREAMS advertised the client + curClientStreams uint32 // number of open streams initiated by the client + curPushedStreams uint32 // number of open streams initiated by server push + maxClientStreamID uint32 // max ever seen from client (odd), or 0 if there have been no client requests + maxPushPromiseID uint32 // ID of the last push promise (even), or 0 if there have been no pushes + streams map[uint32]*stream + initialStreamSendWindowSize int32 + maxFrameSize int32 + headerTableSize uint32 + peerMaxHeaderListSize uint32 // zero means unknown (default) + canonHeader map[string]string // http2-lower-case -> Go-Canonical-Case + writingFrame bool // started writing a frame (on serve goroutine or separate) + writingFrameAsync bool // started a frame on its own goroutine but haven't heard back on wroteFrameCh + needsFrameFlush bool // last frame write wasn't a flush + inGoAway bool // we've started to or sent GOAWAY + inFrameScheduleLoop bool // whether we're in the scheduleFrameWrite loop + needToSendGoAway bool // we need to schedule a GOAWAY frame write + goAwayCode ErrCode + shutdownTimer *time.Timer // nil until used + idleTimer *time.Timer // nil if unused // Owned by the writeFrameAsync goroutine: headerWriteBuf bytes.Buffer hpackEncoder *hpack.Encoder + + // Used by startGracefulShutdown. + shutdownOnce sync.Once } func (sc *serverConn) maxHeaderListSize() uint32 { @@ -463,10 +538,10 @@ type stream struct { numTrailerValues int64 weight uint8 state streamState - resetQueued bool // RST_STREAM queued for write; set by sc.resetStream - gotTrailerHeader bool // HEADER frame for trailers was seen - wroteHeaders bool // whether we wrote headers (not status 100) - reqBuf []byte // if non-nil, body pipe buffer to return later at EOF + resetQueued bool // RST_STREAM queued for write; set by sc.resetStream + gotTrailerHeader bool // HEADER frame for trailers was seen + wroteHeaders bool // whether we wrote headers (not status 100) + writeDeadline *time.Timer // nil if unused trailer http.Header // accumulated trailers reqTrailer http.Header // handler's Request.Trailer @@ -696,48 +771,48 @@ func (sc *serverConn) serve() { {SettingMaxFrameSize, sc.srv.maxReadFrameSize()}, {SettingMaxConcurrentStreams, sc.advMaxStreams}, {SettingMaxHeaderListSize, sc.maxHeaderListSize()}, - - // TODO: more actual settings, notably - // SettingInitialWindowSize, but then we also - // want to bump up the conn window size the - // same amount here right after the settings + {SettingInitialWindowSize, uint32(sc.srv.initialStreamRecvWindowSize())}, }, }) sc.unackedSettings++ + // Each connection starts with intialWindowSize inflow tokens. + // If a higher value is configured, we add more tokens. + if diff := sc.srv.initialConnRecvWindowSize() - initialWindowSize; diff > 0 { + sc.sendWindowUpdate(nil, int(diff)) + } + if err := sc.readPreface(); err != nil { sc.condlogf(err, "http2: server: error reading preface from client %v: %v", sc.conn.RemoteAddr(), err) return } // Now that we've got the preface, get us out of the - // "StateNew" state. We can't go directly to idle, though. + // "StateNew" state. We can't go directly to idle, though. // Active means we read some data and anticipate a request. We'll // do another Active when we get a HEADERS frame. sc.setConnState(http.StateActive) sc.setConnState(http.StateIdle) if sc.srv.IdleTimeout != 0 { - sc.idleTimer = time.NewTimer(sc.srv.IdleTimeout) + sc.idleTimer = time.AfterFunc(sc.srv.IdleTimeout, sc.onIdleTimer) defer sc.idleTimer.Stop() - sc.idleTimerCh = sc.idleTimer.C - } - - var gracefulShutdownCh <-chan struct{} - if sc.hs != nil { - gracefulShutdownCh = h1ServerShutdownChan(sc.hs) } go sc.readFrames() // closed by defer sc.conn.Close above - settingsTimer := time.NewTimer(firstSettingsTimeout) + settingsTimer := time.AfterFunc(firstSettingsTimeout, sc.onSettingsTimer) + defer settingsTimer.Stop() + loopNum := 0 for { loopNum++ select { case wr := <-sc.wantWriteFrameCh: + if se, ok := wr.write.(StreamError); ok { + sc.resetStream(se) + break + } sc.writeFrame(wr) - case spr := <-sc.wantStartPushCh: - sc.startPush(spr) case res := <-sc.wroteFrameCh: sc.wroteFrame(res) case res := <-sc.readFrameCh: @@ -745,26 +820,37 @@ func (sc *serverConn) serve() { return } res.readMore() - if settingsTimer.C != nil { + if settingsTimer != nil { settingsTimer.Stop() - settingsTimer.C = nil + settingsTimer = nil } case m := <-sc.bodyReadCh: sc.noteBodyRead(m.st, m.n) - case <-settingsTimer.C: - sc.logf("timeout waiting for SETTINGS frames from %v", sc.conn.RemoteAddr()) - return - case <-gracefulShutdownCh: - gracefulShutdownCh = nil - sc.startGracefulShutdown() - case <-sc.shutdownTimerCh: - sc.vlogf("GOAWAY close timer fired; closing conn from %v", sc.conn.RemoteAddr()) - return - case <-sc.idleTimerCh: - sc.vlogf("connection is idle") - sc.goAway(ErrCodeNo) - case fn := <-sc.testHookCh: - fn(loopNum) + case msg := <-sc.serveMsgCh: + switch v := msg.(type) { + case func(int): + v(loopNum) // for testing + case *serverMessage: + switch v { + case settingsTimerMsg: + sc.logf("timeout waiting for SETTINGS frames from %v", sc.conn.RemoteAddr()) + return + case idleTimerMsg: + sc.vlogf("connection is idle") + sc.goAway(ErrCodeNo) + case shutdownTimerMsg: + sc.vlogf("GOAWAY close timer fired; closing conn from %v", sc.conn.RemoteAddr()) + return + case gracefulShutdownMsg: + sc.startGracefulShutdownInternal() + default: + panic("unknown timer") + } + case *startPushRequest: + sc.startPush(v) + default: + panic(fmt.Sprintf("unexpected type %T", v)) + } } if sc.inGoAway && sc.curOpenStreams() == 0 && !sc.needToSendGoAway && !sc.writingFrame { @@ -773,6 +859,36 @@ func (sc *serverConn) serve() { } } +func (sc *serverConn) awaitGracefulShutdown(sharedCh <-chan struct{}, privateCh chan struct{}) { + select { + case <-sc.doneServing: + case <-sharedCh: + close(privateCh) + } +} + +type serverMessage int + +// Message values sent to serveMsgCh. +var ( + settingsTimerMsg = new(serverMessage) + idleTimerMsg = new(serverMessage) + shutdownTimerMsg = new(serverMessage) + gracefulShutdownMsg = new(serverMessage) +) + +func (sc *serverConn) onSettingsTimer() { sc.sendServeMsg(settingsTimerMsg) } +func (sc *serverConn) onIdleTimer() { sc.sendServeMsg(idleTimerMsg) } +func (sc *serverConn) onShutdownTimer() { sc.sendServeMsg(shutdownTimerMsg) } + +func (sc *serverConn) sendServeMsg(msg interface{}) { + sc.serveG.checkNotOn() // NOT + select { + case sc.serveMsgCh <- msg: + case <-sc.doneServing: + } +} + // readPreface reads the ClientPreface greeting from the peer // or returns an error on timeout or an invalid greeting. func (sc *serverConn) readPreface() error { @@ -1014,7 +1130,11 @@ func (sc *serverConn) wroteFrame(res frameWriteResult) { // stateClosed after the RST_STREAM frame is // written. st.state = stateHalfClosedLocal - sc.resetStream(streamError(st.id, ErrCodeCancel)) + // Section 8.1: a server MAY request that the client abort + // transmission of a request without error by sending a + // RST_STREAM with an error code of NO_ERROR after sending + // a complete response. + sc.resetStream(streamError(st.id, ErrCodeNo)) case stateHalfClosedRemote: sc.closeStream(st, errHandlerComplete) } @@ -1086,10 +1206,19 @@ func (sc *serverConn) scheduleFrameWrite() { sc.inFrameScheduleLoop = false } -// startGracefulShutdown sends a GOAWAY with ErrCodeNo to tell the -// client we're gracefully shutting down. The connection isn't closed -// until all current streams are done. +// startGracefulShutdown gracefully shuts down a connection. This +// sends GOAWAY with ErrCodeNo to tell the client we're gracefully +// shutting down. The connection isn't closed until all current +// streams are done. +// +// startGracefulShutdown returns immediately; it does not wait until +// the connection has shut down. func (sc *serverConn) startGracefulShutdown() { + sc.serveG.checkNotOn() // NOT + sc.shutdownOnce.Do(func() { sc.sendServeMsg(gracefulShutdownMsg) }) +} + +func (sc *serverConn) startGracefulShutdownInternal() { sc.goAwayIn(ErrCodeNo, 0) } @@ -1121,8 +1250,7 @@ func (sc *serverConn) goAwayIn(code ErrCode, forceCloseIn time.Duration) { func (sc *serverConn) shutDownIn(d time.Duration) { sc.serveG.check() - sc.shutdownTimer = time.NewTimer(d) - sc.shutdownTimerCh = sc.shutdownTimer.C + sc.shutdownTimer = time.AfterFunc(d, sc.onShutdownTimer) } func (sc *serverConn) resetStream(se StreamError) { @@ -1305,6 +1433,9 @@ func (sc *serverConn) closeStream(st *stream, err error) { panic(fmt.Sprintf("invariant; can't close stream in state %v", st.state)) } st.state = stateClosed + if st.writeDeadline != nil { + st.writeDeadline.Stop() + } if st.isPushed() { sc.curPushedStreams-- } else { @@ -1317,7 +1448,7 @@ func (sc *serverConn) closeStream(st *stream, err error) { sc.idleTimer.Reset(sc.srv.IdleTimeout) } if h1ServerKeepAlivesDisabled(sc.hs) { - sc.startGracefulShutdown() + sc.startGracefulShutdownInternal() } } if p := st.body; p != nil { @@ -1395,9 +1526,9 @@ func (sc *serverConn) processSettingInitialWindowSize(val uint32) error { // adjust the size of all stream flow control windows that it // maintains by the difference between the new value and the // old value." - old := sc.initialWindowSize - sc.initialWindowSize = int32(val) - growth := sc.initialWindowSize - old // may be negative + old := sc.initialStreamSendWindowSize + sc.initialStreamSendWindowSize = int32(val) + growth := int32(val) - old // may be negative for _, st := range sc.streams { if !st.flow.add(growth) { // 6.9.2 Initial Flow Control Window Size @@ -1504,7 +1635,7 @@ func (sc *serverConn) processGoAway(f *GoAwayFrame) error { } else { sc.vlogf("http2: received GOAWAY %+v, starting graceful shutdown", f) } - sc.startGracefulShutdown() + sc.startGracefulShutdownInternal() // http://tools.ietf.org/html/rfc7540#section-6.8 // We should not create any new streams, which means we should disable push. sc.pushEnabled = false @@ -1543,6 +1674,12 @@ func (st *stream) copyTrailersToHandlerRequest() { } } +// onWriteTimeout is run on its own goroutine (from time.AfterFunc) +// when the stream's WriteTimeout has fired. +func (st *stream) onWriteTimeout() { + st.sc.writeFrameFromHandler(FrameWriteRequest{write: streamError(st.id, ErrCodeInternal)}) +} + func (sc *serverConn) processHeaders(f *MetaHeadersFrame) error { sc.serveG.check() id := f.StreamID @@ -1719,9 +1856,12 @@ func (sc *serverConn) newStream(id, pusherID uint32, state streamState) *stream } st.cw.Init() st.flow.conn = &sc.flow // link to conn-level counter - st.flow.add(sc.initialWindowSize) - st.inflow.conn = &sc.inflow // link to conn-level counter - st.inflow.add(initialWindowSize) // TODO: update this when we send a higher initial window size in the initial settings + st.flow.add(sc.initialStreamSendWindowSize) + st.inflow.conn = &sc.inflow // link to conn-level counter + st.inflow.add(sc.srv.initialStreamRecvWindowSize()) + if sc.hs.WriteTimeout != 0 { + st.writeDeadline = time.AfterFunc(sc.hs.WriteTimeout, st.onWriteTimeout) + } sc.streams[id] = st sc.writeSched.OpenStream(st.id, OpenStreamOptions{PusherID: pusherID}) @@ -1785,16 +1925,14 @@ func (sc *serverConn) newWriterAndRequest(st *stream, f *MetaHeadersFrame) (*res return nil, nil, err } if bodyOpen { - st.reqBuf = getRequestBodyBuf() - req.Body.(*requestBody).pipe = &pipe{ - b: &fixedBuffer{buf: st.reqBuf}, - } - if vv, ok := rp.header["Content-Length"]; ok { req.ContentLength, _ = strconv.ParseInt(vv[0], 10, 64) } else { req.ContentLength = -1 } + req.Body.(*requestBody).pipe = &pipe{ + b: &dataBuffer{expected: req.ContentLength}, + } } return rw, req, nil } @@ -1890,24 +2028,6 @@ func (sc *serverConn) newWriterAndRequestNoBody(st *stream, rp requestParam) (*r return rw, req, nil } -var reqBodyCache = make(chan []byte, 8) - -func getRequestBodyBuf() []byte { - select { - case b := <-reqBodyCache: - return b - default: - return make([]byte, initialWindowSize) - } -} - -func putRequestBodyBuf(b []byte) { - select { - case reqBodyCache <- b: - default: - } -} - // Run on its own goroutine. func (sc *serverConn) runHandler(rw *responseWriter, req *http.Request, handler func(http.ResponseWriter, *http.Request)) { didPanic := true @@ -2003,12 +2123,6 @@ func (sc *serverConn) noteBodyReadFromHandler(st *stream, n int, err error) { case <-sc.doneServing: } } - if err == io.EOF { - if buf := st.reqBuf; buf != nil { - st.reqBuf = nil // shouldn't matter; field unused by other - putRequestBodyBuf(buf) - } - } } func (sc *serverConn) noteBodyRead(st *stream, n int) { @@ -2103,8 +2217,8 @@ func (b *requestBody) Read(p []byte) (n int, err error) { return } -// responseWriter is the http.ResponseWriter implementation. It's -// intentionally small (1 pointer wide) to minimize garbage. The +// responseWriter is the http.ResponseWriter implementation. It's +// intentionally small (1 pointer wide) to minimize garbage. The // responseWriterState pointer inside is zeroed at the end of a // request (in handlerDone) and calls on the responseWriter thereafter // simply crash (caller's mistake), but the much larger responseWriterState @@ -2278,7 +2392,7 @@ const TrailerPrefix = "Trailer:" // says you SHOULD (but not must) predeclare any trailers in the // header, the official ResponseWriter rules said trailers in Go must // be predeclared, and then we reuse the same ResponseWriter.Header() -// map to mean both Headers and Trailers. When it's time to write the +// map to mean both Headers and Trailers. When it's time to write the // Trailers, we pick out the fields of Headers that were declared as // trailers. That worked for a while, until we found the first major // user of Trailers in the wild: gRPC (using them only over http2), @@ -2514,7 +2628,7 @@ func (w *responseWriter) push(target string, opts pushOptions) error { return fmt.Errorf("method %q must be GET or HEAD", opts.Method) } - msg := startPushRequest{ + msg := &startPushRequest{ parent: st, method: opts.Method, url: u, @@ -2527,7 +2641,7 @@ func (w *responseWriter) push(target string, opts pushOptions) error { return errClientDisconnected case <-st.cw: return errStreamClosed - case sc.wantStartPushCh <- msg: + case sc.serveMsgCh <- msg: } select { @@ -2549,7 +2663,7 @@ type startPushRequest struct { done chan error } -func (sc *serverConn) startPush(msg startPushRequest) { +func (sc *serverConn) startPush(msg *startPushRequest) { sc.serveG.check() // http://tools.ietf.org/html/rfc7540#section-6.6. @@ -2588,7 +2702,7 @@ func (sc *serverConn) startPush(msg startPushRequest) { // A server that is unable to establish a new stream identifier can send a GOAWAY // frame so that the client is forced to open a new connection for new streams. if sc.maxPushPromiseID+2 >= 1<<31 { - sc.startGracefulShutdown() + sc.startGracefulShutdownInternal() return 0, ErrPushLimitReached } sc.maxPushPromiseID += 2 @@ -2713,31 +2827,6 @@ var badTrailer = map[string]bool{ "Www-Authenticate": true, } -// h1ServerShutdownChan returns a channel that will be closed when the -// provided *http.Server wants to shut down. -// -// This is a somewhat hacky way to get at http1 innards. It works -// when the http2 code is bundled into the net/http package in the -// standard library. The alternatives ended up making the cmd/go tool -// depend on http Servers. This is the lightest option for now. -// This is tested via the TestServeShutdown* tests in net/http. -func h1ServerShutdownChan(hs *http.Server) <-chan struct{} { - if fn := testh1ServerShutdownChan; fn != nil { - return fn(hs) - } - var x interface{} = hs - type I interface { - getDoneChan() <-chan struct{} - } - if hs, ok := x.(I); ok { - return hs.getDoneChan() - } - return nil -} - -// optional test hook for h1ServerShutdownChan. -var testh1ServerShutdownChan func(hs *http.Server) <-chan struct{} - // h1ServerKeepAlivesDisabled reports whether hs has its keep-alives // disabled. See comments on h1ServerShutdownChan above for why // the code is written this way. diff --git a/vendor/golang.org/x/net/http2/transport.go b/vendor/golang.org/x/net/http2/transport.go index 0c7e859db1ed..3a85f25a2009 100644 --- a/vendor/golang.org/x/net/http2/transport.go +++ b/vendor/golang.org/x/net/http2/transport.go @@ -575,7 +575,7 @@ func (cc *ClientConn) canTakeNewRequestLocked() bool { cc.nextStreamID < math.MaxInt32 } -// onIdleTimeout is called from a time.AfterFunc goroutine. It will +// onIdleTimeout is called from a time.AfterFunc goroutine. It will // only be called when we're idle, but because we're coming from a new // goroutine, there could be a new request coming in at the same time, // so this simply calls the synchronized closeIfIdle to shut down this @@ -809,8 +809,8 @@ func (cc *ClientConn) RoundTrip(req *http.Request) (*http.Response, error) { // 2xx, however, then assume the server DOES potentially // want our body (e.g. full-duplex streaming: // golang.org/issue/13444). If it turns out the server - // doesn't, they'll RST_STREAM us soon enough. This is a - // heuristic to avoid adding knobs to Transport. Hopefully + // doesn't, they'll RST_STREAM us soon enough. This is a + // heuristic to avoid adding knobs to Transport. Hopefully // we can keep it. bodyWriter.cancel() cs.abortRequestBodyWrite(errStopReqBodyWrite) @@ -1528,8 +1528,7 @@ func (rl *clientConnReadLoop) handleResponse(cs *clientStream, f *MetaHeadersFra return res, nil } - buf := new(bytes.Buffer) // TODO(bradfitz): recycle this garbage - cs.bufPipe = pipe{b: buf} + cs.bufPipe = pipe{b: &dataBuffer{expected: res.ContentLength}} cs.bytesRemain = res.ContentLength res.Body = transportResponseBody{cs} go cs.awaitRequestCancel(cs.req) @@ -1656,6 +1655,7 @@ func (b transportResponseBody) Close() error { cc.wmu.Lock() if !serverSentStreamEnd { cc.fr.WriteRSTStream(cs.ID, ErrCodeCancel) + cs.didReset = true } // Return connection-level flow control. if unread > 0 { @@ -1703,12 +1703,6 @@ func (rl *clientConnReadLoop) processData(f *DataFrame) error { return nil } if f.Length > 0 { - if len(data) > 0 && cs.bufPipe.b == nil { - // Data frame after it's already closed? - cc.logf("http2: Transport received DATA frame for closed stream; closing connection") - return ConnectionError(ErrCodeProtocol) - } - // Check connection-level flow control. cc.mu.Lock() if cs.inflow.available() >= int32(f.Length) { diff --git a/vendor/golang.org/x/net/http2/writesched_priority.go b/vendor/golang.org/x/net/http2/writesched_priority.go index 01132721bddd..848fed6ec769 100644 --- a/vendor/golang.org/x/net/http2/writesched_priority.go +++ b/vendor/golang.org/x/net/http2/writesched_priority.go @@ -53,7 +53,7 @@ type PriorityWriteSchedulerConfig struct { } // NewPriorityWriteScheduler constructs a WriteScheduler that schedules -// frames by following HTTP/2 priorities as described in RFC 7340 Section 5.3. +// frames by following HTTP/2 priorities as described in RFC 7540 Section 5.3. // If cfg is nil, default options are used. func NewPriorityWriteScheduler(cfg *PriorityWriteSchedulerConfig) WriteScheduler { if cfg == nil { diff --git a/vendor/golang.org/x/net/idna/idna.go b/vendor/golang.org/x/net/idna/idna.go index 47466e947af9..ee2dbda6d0d4 100644 --- a/vendor/golang.org/x/net/idna/idna.go +++ b/vendor/golang.org/x/net/idna/idna.go @@ -1,4 +1,4 @@ -// Copied from the golang.org/x/text repo; DO NOT EDIT +// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. // Copyright 2016 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style @@ -39,27 +39,24 @@ import ( // error in the future. // I think Option 1 is best, but it is quite opinionated. -// ToASCII converts a domain or domain label to its ASCII form. For example, -// ToASCII("bücher.example.com") is "xn--bcher-kva.example.com", and -// ToASCII("golang") is "golang". If an error is encountered it will return -// an error and a (partially) processed result. +// ToASCII is a wrapper for Punycode.ToASCII. func ToASCII(s string) (string, error) { - return Resolve.process(s, true) + return Punycode.process(s, true) } -// ToUnicode converts a domain or domain label to its Unicode form. For example, -// ToUnicode("xn--bcher-kva.example.com") is "bücher.example.com", and -// ToUnicode("golang") is "golang". If an error is encountered it will return -// an error and a (partially) processed result. +// ToUnicode is a wrapper for Punycode.ToUnicode. func ToUnicode(s string) (string, error) { - return NonTransitional.process(s, false) + return Punycode.process(s, false) } // An Option configures a Profile at creation time. type Option func(*options) -// Transitional sets a Profile to use the Transitional mapping as defined -// in UTS #46. +// Transitional sets a Profile to use the Transitional mapping as defined in UTS +// #46. This will cause, for example, "ß" to be mapped to "ss". Using the +// transitional mapping provides a compromise between IDNA2003 and IDNA2008 +// compatibility. It is used by most browsers when resolving domain names. This +// option is only meaningful if combined with MapForLookup. func Transitional(transitional bool) Option { return func(o *options) { o.transitional = true } } @@ -70,19 +67,93 @@ func VerifyDNSLength(verify bool) Option { return func(o *options) { o.verifyDNSLength = verify } } -// IgnoreSTD3Rules sets whether ASCII characters outside the A-Z, a-z, 0-9 and -// the hyphen should be allowed. By default this is not allowed, but IDNA2003, -// and as a consequence UTS #46, allows this to be overridden to support -// browsers that allow characters outside this range, for example a '_' (U+005F -// LOW LINE). See http://www.rfc- editor.org/std/std3.txt for more details. -func IgnoreSTD3Rules(ignore bool) Option { - return func(o *options) { o.ignoreSTD3Rules = ignore } +// ValidateLabels sets whether to check the mandatory label validation criteria +// as defined in Section 5.4 of RFC 5891. This includes testing for correct use +// of hyphens ('-'), normalization, validity of runes, and the context rules. +func ValidateLabels(enable bool) Option { + return func(o *options) { + // Don't override existing mappings, but set one that at least checks + // normalization if it is not set. + if o.mapping == nil && enable { + o.mapping = normalize + } + o.trie = trie + o.validateLabels = enable + o.fromPuny = validateFromPunycode + } +} + +// StrictDomainName limits the set of permissable ASCII characters to those +// allowed in domain names as defined in RFC 1034 (A-Z, a-z, 0-9 and the +// hyphen). This is set by default for MapForLookup and ValidateForRegistration. +// +// This option is useful, for instance, for browsers that allow characters +// outside this range, for example a '_' (U+005F LOW LINE). See +// http://www.rfc-editor.org/std/std3.txt for more details This option +// corresponds to the UseSTD3ASCIIRules option in UTS #46. +func StrictDomainName(use bool) Option { + return func(o *options) { + o.trie = trie + o.useSTD3Rules = use + o.fromPuny = validateFromPunycode + } +} + +// NOTE: the following options pull in tables. The tables should not be linked +// in as long as the options are not used. + +// BidiRule enables the Bidi rule as defined in RFC 5893. Any application +// that relies on proper validation of labels should include this rule. +func BidiRule() Option { + return func(o *options) { o.bidirule = bidirule.ValidString } +} + +// ValidateForRegistration sets validation options to verify that a given IDN is +// properly formatted for registration as defined by Section 4 of RFC 5891. +func ValidateForRegistration() Option { + return func(o *options) { + o.mapping = validateRegistration + StrictDomainName(true)(o) + ValidateLabels(true)(o) + VerifyDNSLength(true)(o) + BidiRule()(o) + } +} + +// MapForLookup sets validation and mapping options such that a given IDN is +// transformed for domain name lookup according to the requirements set out in +// Section 5 of RFC 5891. The mappings follow the recommendations of RFC 5894, +// RFC 5895 and UTS 46. It does not add the Bidi Rule. Use the BidiRule option +// to add this check. +// +// The mappings include normalization and mapping case, width and other +// compatibility mappings. +func MapForLookup() Option { + return func(o *options) { + o.mapping = validateAndMap + StrictDomainName(true)(o) + ValidateLabels(true)(o) + } } type options struct { transitional bool - ignoreSTD3Rules bool + useSTD3Rules bool + validateLabels bool verifyDNSLength bool + + trie *idnaTrie + + // fromPuny calls validation rules when converting A-labels to U-labels. + fromPuny func(p *Profile, s string) error + + // mapping implements a validation and mapping step as defined in RFC 5895 + // or UTS 46, tailored to, for example, domain registration or lookup. + mapping func(p *Profile, s string) (string, error) + + // bidirule, if specified, checks whether s conforms to the Bidi Rule + // defined in RFC 5893. + bidirule func(s string) bool } // A Profile defines the configuration of a IDNA mapper. @@ -97,8 +168,13 @@ func apply(o *options, opts []Option) { } // New creates a new Profile. -// With no options, the returned profile is the non-transitional profile as -// defined in UTS #46. +// +// With no options, the returned Profile is the most permissive and equals the +// Punycode Profile. Options can be passed to further restrict the Profile. The +// MapForLookup and ValidateForRegistration options set a collection of options, +// for lookup and registration purposes respectively, which can be tailored by +// adding more fine-grained options, where later options override earlier +// options. func New(o ...Option) *Profile { p := &Profile{} apply(&p.options, o) @@ -132,33 +208,67 @@ func (p *Profile) String() string { } else { s = "NonTransitional" } - if p.ignoreSTD3Rules { - s += ":NoSTD3Rules" + if p.useSTD3Rules { + s += ":UseSTD3Rules" + } + if p.validateLabels { + s += ":ValidateLabels" + } + if p.verifyDNSLength { + s += ":VerifyDNSLength" } return s } var ( - // Resolve is the recommended profile for resolving domain names. - // The configuration of this profile may change over time. - Resolve = resolve + // Punycode is a Profile that does raw punycode processing with a minimum + // of validation. + Punycode *Profile = punycode + + // Lookup is the recommended profile for looking up domain names, according + // to Section 5 of RFC 5891. The exact configuration of this profile may + // change over time. + Lookup *Profile = lookup // Display is the recommended profile for displaying domain names. // The configuration of this profile may change over time. - Display = display - - // NonTransitional defines a profile that implements the Transitional - // mapping as defined in UTS #46 with no additional constraints. - NonTransitional = nonTransitional - - resolve = &Profile{options{transitional: true}} - display = &Profile{} - nonTransitional = &Profile{} + Display *Profile = display + + // Registration is the recommended profile for checking whether a given + // IDN is valid for registration, according to Section 4 of RFC 5891. + Registration *Profile = registration + + punycode = &Profile{} + lookup = &Profile{options{ + transitional: true, + useSTD3Rules: true, + validateLabels: true, + trie: trie, + fromPuny: validateFromPunycode, + mapping: validateAndMap, + bidirule: bidirule.ValidString, + }} + display = &Profile{options{ + useSTD3Rules: true, + validateLabels: true, + trie: trie, + fromPuny: validateFromPunycode, + mapping: validateAndMap, + bidirule: bidirule.ValidString, + }} + registration = &Profile{options{ + useSTD3Rules: true, + validateLabels: true, + verifyDNSLength: true, + trie: trie, + fromPuny: validateFromPunycode, + mapping: validateRegistration, + bidirule: bidirule.ValidString, + }} // TODO: profiles - // V2008: strict IDNA2008 - // Register: recommended for approving domain names: nontransitional, but - // bundle or block deviation characters. + // Register: recommended for approving domain names: don't do any mappings + // but rather reject on invalid input. Bundle or block deviation characters. ) type labelError struct{ label, code_ string } @@ -178,53 +288,17 @@ func (e runeError) Error() string { // process implements the algorithm described in section 4 of UTS #46, // see http://www.unicode.org/reports/tr46. func (p *Profile) process(s string, toASCII bool) (string, error) { - var ( - b []byte - err error - k, i int - ) - for i < len(s) { - v, sz := trie.lookupString(s[i:]) - start := i - i += sz - // Copy bytes not copied so far. - switch p.simplify(info(v).category()) { - case valid: - continue - case disallowed: - if err == nil { - r, _ := utf8.DecodeRuneInString(s[i:]) - err = runeError(r) - } - continue - case mapped, deviation: - b = append(b, s[k:start]...) - b = info(v).appendMapping(b, s[start:i]) - case ignored: - b = append(b, s[k:start]...) - // drop the rune - case unknown: - b = append(b, s[k:start]...) - b = append(b, "\ufffd"...) - } - k = i - } - if k == 0 { - // No changes so far. - s = norm.NFC.String(s) - } else { - b = append(b, s[k:]...) - if norm.NFC.QuickSpan(b) != len(b) { - b = norm.NFC.Bytes(b) - } - // TODO: the punycode converters require strings as input. - s = string(b) + var err error + if p.mapping != nil { + s, err = p.mapping(p, s) } - // Remove leading empty labels + // Remove leading empty labels. for ; len(s) > 0 && s[0] == '.'; s = s[1:] { } - if s == "" { - return "", &labelError{s, "A4"} + // It seems like we should only create this error on ToASCII, but the + // UTS 46 conformance tests suggests we should always check this. + if err == nil && p.verifyDNSLength && s == "" { + err = &labelError{s, "A4"} } labels := labelIter{orig: s} for ; !labels.done(); labels.next() { @@ -232,7 +306,7 @@ func (p *Profile) process(s string, toASCII bool) (string, error) { if label == "" { // Empty labels are not okay. The label iterator skips the last // label if it is empty. - if err == nil { + if err == nil && p.verifyDNSLength { err = &labelError{s, "A4"} } continue @@ -247,14 +321,17 @@ func (p *Profile) process(s string, toASCII bool) (string, error) { continue } labels.set(u) - if err == nil { - err = p.validateFromPunycode(u) + if err == nil && p.validateLabels { + err = p.fromPuny(p, u) } if err == nil { - err = NonTransitional.validate(u) + // This should be called on NonTransitional, according to the + // spec, but that currently does not have any effect. Use the + // original profile to preserve options. + err = p.validateLabel(u) } } else if err == nil { - err = p.validate(label) + err = p.validateLabel(label) } } if toASCII { @@ -288,6 +365,79 @@ func (p *Profile) process(s string, toASCII bool) (string, error) { return s, err } +func normalize(p *Profile, s string) (string, error) { + return norm.NFC.String(s), nil +} + +func validateRegistration(p *Profile, s string) (string, error) { + if !norm.NFC.IsNormalString(s) { + return s, &labelError{s, "V1"} + } + var err error + for i := 0; i < len(s); { + v, sz := trie.lookupString(s[i:]) + i += sz + // Copy bytes not copied so far. + switch p.simplify(info(v).category()) { + // TODO: handle the NV8 defined in the Unicode idna data set to allow + // for strict conformance to IDNA2008. + case valid, deviation: + case disallowed, mapped, unknown, ignored: + if err == nil { + r, _ := utf8.DecodeRuneInString(s[i:]) + err = runeError(r) + } + } + } + return s, err +} + +func validateAndMap(p *Profile, s string) (string, error) { + var ( + err error + b []byte + k int + ) + for i := 0; i < len(s); { + v, sz := trie.lookupString(s[i:]) + start := i + i += sz + // Copy bytes not copied so far. + switch p.simplify(info(v).category()) { + case valid: + continue + case disallowed: + if err == nil { + r, _ := utf8.DecodeRuneInString(s[i:]) + err = runeError(r) + } + continue + case mapped, deviation: + b = append(b, s[k:start]...) + b = info(v).appendMapping(b, s[start:i]) + case ignored: + b = append(b, s[k:start]...) + // drop the rune + case unknown: + b = append(b, s[k:start]...) + b = append(b, "\ufffd"...) + } + k = i + } + if k == 0 { + // No changes so far. + s = norm.NFC.String(s) + } else { + b = append(b, s[k:]...) + if norm.NFC.QuickSpan(b) != len(b) { + b = norm.NFC.Bytes(b) + } + // TODO: the punycode converters require strings as input. + s = string(b) + } + return s, err +} + // A labelIter allows iterating over domain name labels. type labelIter struct { orig string @@ -354,13 +504,13 @@ const acePrefix = "xn--" func (p *Profile) simplify(cat category) category { switch cat { case disallowedSTD3Mapped: - if !p.ignoreSTD3Rules { + if p.useSTD3Rules { cat = disallowed } else { cat = mapped } case disallowedSTD3Valid: - if !p.ignoreSTD3Rules { + if p.useSTD3Rules { cat = disallowed } else { cat = valid @@ -376,7 +526,7 @@ func (p *Profile) simplify(cat category) category { return cat } -func (p *Profile) validateFromPunycode(s string) error { +func validateFromPunycode(p *Profile, s string) error { if !norm.NFC.IsNormalString(s) { return &labelError{s, "V1"} } @@ -452,9 +602,22 @@ var joinStates = [][numJoinTypes]joinState{ }, } -// validate validates the criteria from Section 4.1. Item 1, 4, and 6 are +// validateLabel validates the criteria from Section 4.1. Item 1, 4, and 6 are // already implicitly satisfied by the overall implementation. -func (p *Profile) validate(s string) error { +func (p *Profile) validateLabel(s string) error { + if s == "" { + if p.verifyDNSLength { + return &labelError{s, "A4"} + } + return nil + } + if p.bidirule != nil && !p.bidirule(s) { + return &labelError{s, "B"} + } + if !p.validateLabels { + return nil + } + trie := p.trie // p.validateLabels is only set if trie is set. if len(s) > 4 && s[2] == '-' && s[3] == '-' { return &labelError{s, "V2"} } @@ -467,9 +630,6 @@ func (p *Profile) validate(s string) error { if x.isModifier() { return &labelError{s, "V5"} } - if !bidirule.ValidString(s) { - return &labelError{s, "B"} - } // Quickly return in the absence of zero-width (non) joiners. if strings.Index(s, zwj) == -1 && strings.Index(s, zwnj) == -1 { return nil diff --git a/vendor/golang.org/x/net/idna/punycode.go b/vendor/golang.org/x/net/idna/punycode.go index df3411a5bcc4..02c7d59af3b4 100644 --- a/vendor/golang.org/x/net/idna/punycode.go +++ b/vendor/golang.org/x/net/idna/punycode.go @@ -1,4 +1,4 @@ -// Copied from the golang.org/x/text repo; DO NOT EDIT +// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. // Copyright 2016 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style diff --git a/vendor/golang.org/x/net/idna/tables.go b/vendor/golang.org/x/net/idna/tables.go index 663d73c531e0..d2819345fcd8 100644 --- a/vendor/golang.org/x/net/idna/tables.go +++ b/vendor/golang.org/x/net/idna/tables.go @@ -1,6 +1,4 @@ -// Copied from the golang.org/x/text repo; DO NOT EDIT - -// This file was generated by go generate; DO NOT EDIT +// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. package idna diff --git a/vendor/golang.org/x/net/idna/trie.go b/vendor/golang.org/x/net/idna/trie.go index 6d37998f5da7..c4ef847e7a37 100644 --- a/vendor/golang.org/x/net/idna/trie.go +++ b/vendor/golang.org/x/net/idna/trie.go @@ -1,4 +1,4 @@ -// Copied from the golang.org/x/text repo; DO NOT EDIT +// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. // Copyright 2016 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style @@ -44,7 +44,8 @@ var idnaSparse = sparseBlocks{ offset: idnaSparseOffset[:], } -var trie = newIdnaTrie(0) +// Don't use newIdnaTrie to avoid unconditional linking in of the table. +var trie = &idnaTrie{} // lookup determines the type of block n and looks up the value for b. // For n < t.cutoff, the block is a simple lookup table. Otherwise, the block diff --git a/vendor/golang.org/x/net/idna/trieval.go b/vendor/golang.org/x/net/idna/trieval.go index d1b3256c8be9..63cb03b59b12 100644 --- a/vendor/golang.org/x/net/idna/trieval.go +++ b/vendor/golang.org/x/net/idna/trieval.go @@ -1,6 +1,4 @@ -// Copied from the golang.org/x/text repo; DO NOT EDIT - -// This file was generated by go generate; DO NOT EDIT +// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. package idna diff --git a/vendor/golang.org/x/net/internal/timeseries/timeseries.go b/vendor/golang.org/x/net/internal/timeseries/timeseries.go index 1119f3448228..685f0e7ea236 100644 --- a/vendor/golang.org/x/net/internal/timeseries/timeseries.go +++ b/vendor/golang.org/x/net/internal/timeseries/timeseries.go @@ -371,7 +371,7 @@ func (ts *timeSeries) ComputeRange(start, finish time.Time, num int) []Observabl } } - // Failed to find a level that covers the desired range. So just + // Failed to find a level that covers the desired range. So just // extract from the last level, even if it doesn't cover the entire // desired range. ts.extract(ts.levels[len(ts.levels)-1], start, finish, num, results) diff --git a/vendor/golang.org/x/net/proxy/socks5.go b/vendor/golang.org/x/net/proxy/socks5.go index 9b9628239a13..973f57f19703 100644 --- a/vendor/golang.org/x/net/proxy/socks5.go +++ b/vendor/golang.org/x/net/proxy/socks5.go @@ -72,24 +72,28 @@ func (s *socks5) Dial(network, addr string) (net.Conn, error) { if err != nil { return nil, err } - closeConn := &conn - defer func() { - if closeConn != nil { - (*closeConn).Close() - } - }() + if err := s.connect(conn, addr); err != nil { + conn.Close() + return nil, err + } + return conn, nil +} - host, portStr, err := net.SplitHostPort(addr) +// connect takes an existing connection to a socks5 proxy server, +// and commands the server to extend that connection to target, +// which must be a canonical address with a host and port. +func (s *socks5) connect(conn net.Conn, target string) error { + host, portStr, err := net.SplitHostPort(target) if err != nil { - return nil, err + return err } port, err := strconv.Atoi(portStr) if err != nil { - return nil, errors.New("proxy: failed to parse port number: " + portStr) + return errors.New("proxy: failed to parse port number: " + portStr) } if port < 1 || port > 0xffff { - return nil, errors.New("proxy: port number out of range: " + portStr) + return errors.New("proxy: port number out of range: " + portStr) } // the size here is just an estimate @@ -103,17 +107,17 @@ func (s *socks5) Dial(network, addr string) (net.Conn, error) { } if _, err := conn.Write(buf); err != nil { - return nil, errors.New("proxy: failed to write greeting to SOCKS5 proxy at " + s.addr + ": " + err.Error()) + return errors.New("proxy: failed to write greeting to SOCKS5 proxy at " + s.addr + ": " + err.Error()) } if _, err := io.ReadFull(conn, buf[:2]); err != nil { - return nil, errors.New("proxy: failed to read greeting from SOCKS5 proxy at " + s.addr + ": " + err.Error()) + return errors.New("proxy: failed to read greeting from SOCKS5 proxy at " + s.addr + ": " + err.Error()) } if buf[0] != 5 { - return nil, errors.New("proxy: SOCKS5 proxy at " + s.addr + " has unexpected version " + strconv.Itoa(int(buf[0]))) + return errors.New("proxy: SOCKS5 proxy at " + s.addr + " has unexpected version " + strconv.Itoa(int(buf[0]))) } if buf[1] == 0xff { - return nil, errors.New("proxy: SOCKS5 proxy at " + s.addr + " requires authentication") + return errors.New("proxy: SOCKS5 proxy at " + s.addr + " requires authentication") } if buf[1] == socks5AuthPassword { @@ -125,15 +129,15 @@ func (s *socks5) Dial(network, addr string) (net.Conn, error) { buf = append(buf, s.password...) if _, err := conn.Write(buf); err != nil { - return nil, errors.New("proxy: failed to write authentication request to SOCKS5 proxy at " + s.addr + ": " + err.Error()) + return errors.New("proxy: failed to write authentication request to SOCKS5 proxy at " + s.addr + ": " + err.Error()) } if _, err := io.ReadFull(conn, buf[:2]); err != nil { - return nil, errors.New("proxy: failed to read authentication reply from SOCKS5 proxy at " + s.addr + ": " + err.Error()) + return errors.New("proxy: failed to read authentication reply from SOCKS5 proxy at " + s.addr + ": " + err.Error()) } if buf[1] != 0 { - return nil, errors.New("proxy: SOCKS5 proxy at " + s.addr + " rejected username/password") + return errors.New("proxy: SOCKS5 proxy at " + s.addr + " rejected username/password") } } @@ -150,7 +154,7 @@ func (s *socks5) Dial(network, addr string) (net.Conn, error) { buf = append(buf, ip...) } else { if len(host) > 255 { - return nil, errors.New("proxy: destination hostname too long: " + host) + return errors.New("proxy: destination hostname too long: " + host) } buf = append(buf, socks5Domain) buf = append(buf, byte(len(host))) @@ -159,11 +163,11 @@ func (s *socks5) Dial(network, addr string) (net.Conn, error) { buf = append(buf, byte(port>>8), byte(port)) if _, err := conn.Write(buf); err != nil { - return nil, errors.New("proxy: failed to write connect request to SOCKS5 proxy at " + s.addr + ": " + err.Error()) + return errors.New("proxy: failed to write connect request to SOCKS5 proxy at " + s.addr + ": " + err.Error()) } if _, err := io.ReadFull(conn, buf[:4]); err != nil { - return nil, errors.New("proxy: failed to read connect reply from SOCKS5 proxy at " + s.addr + ": " + err.Error()) + return errors.New("proxy: failed to read connect reply from SOCKS5 proxy at " + s.addr + ": " + err.Error()) } failure := "unknown error" @@ -172,7 +176,7 @@ func (s *socks5) Dial(network, addr string) (net.Conn, error) { } if len(failure) > 0 { - return nil, errors.New("proxy: SOCKS5 proxy at " + s.addr + " failed to connect: " + failure) + return errors.New("proxy: SOCKS5 proxy at " + s.addr + " failed to connect: " + failure) } bytesToDiscard := 0 @@ -184,11 +188,11 @@ func (s *socks5) Dial(network, addr string) (net.Conn, error) { case socks5Domain: _, err := io.ReadFull(conn, buf[:1]) if err != nil { - return nil, errors.New("proxy: failed to read domain length from SOCKS5 proxy at " + s.addr + ": " + err.Error()) + return errors.New("proxy: failed to read domain length from SOCKS5 proxy at " + s.addr + ": " + err.Error()) } bytesToDiscard = int(buf[0]) default: - return nil, errors.New("proxy: got unknown address type " + strconv.Itoa(int(buf[3])) + " from SOCKS5 proxy at " + s.addr) + return errors.New("proxy: got unknown address type " + strconv.Itoa(int(buf[3])) + " from SOCKS5 proxy at " + s.addr) } if cap(buf) < bytesToDiscard { @@ -197,14 +201,13 @@ func (s *socks5) Dial(network, addr string) (net.Conn, error) { buf = buf[:bytesToDiscard] } if _, err := io.ReadFull(conn, buf); err != nil { - return nil, errors.New("proxy: failed to read address from SOCKS5 proxy at " + s.addr + ": " + err.Error()) + return errors.New("proxy: failed to read address from SOCKS5 proxy at " + s.addr + ": " + err.Error()) } // Also need to discard the port number if _, err := io.ReadFull(conn, buf[:2]); err != nil { - return nil, errors.New("proxy: failed to read port from SOCKS5 proxy at " + s.addr + ": " + err.Error()) + return errors.New("proxy: failed to read port from SOCKS5 proxy at " + s.addr + ": " + err.Error()) } - closeConn = nil - return conn, nil + return nil } diff --git a/vendor/golang.org/x/net/trace/trace.go b/vendor/golang.org/x/net/trace/trace.go index 64f56a373684..3d9b646111ff 100644 --- a/vendor/golang.org/x/net/trace/trace.go +++ b/vendor/golang.org/x/net/trace/trace.go @@ -77,7 +77,6 @@ import ( "sync/atomic" "time" - "golang.org/x/net/context" "golang.org/x/net/internal/timeseries" ) @@ -271,18 +270,6 @@ type contextKeyT string var contextKey = contextKeyT("golang.org/x/net/trace.Trace") -// NewContext returns a copy of the parent context -// and associates it with a Trace. -func NewContext(ctx context.Context, tr Trace) context.Context { - return context.WithValue(ctx, contextKey, tr) -} - -// FromContext returns the Trace bound to the context, if any. -func FromContext(ctx context.Context) (tr Trace, ok bool) { - tr, ok = ctx.Value(contextKey).(Trace) - return -} - // Trace represents an active request. type Trace interface { // LazyLog adds x to the event log. It will be evaluated each time the diff --git a/vendor/golang.org/x/net/trace/trace_go16.go b/vendor/golang.org/x/net/trace/trace_go16.go new file mode 100644 index 000000000000..d6081911853f --- /dev/null +++ b/vendor/golang.org/x/net/trace/trace_go16.go @@ -0,0 +1,21 @@ +// Copyright 2017 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 !go1.7 + +package trace + +import "golang.org/x/net/context" + +// NewContext returns a copy of the parent context +// and associates it with a Trace. +func NewContext(ctx context.Context, tr Trace) context.Context { + return context.WithValue(ctx, contextKey, tr) +} + +// FromContext returns the Trace bound to the context, if any. +func FromContext(ctx context.Context) (tr Trace, ok bool) { + tr, ok = ctx.Value(contextKey).(Trace) + return +} diff --git a/vendor/golang.org/x/net/trace/trace_go17.go b/vendor/golang.org/x/net/trace/trace_go17.go new file mode 100644 index 000000000000..df6e1fba7caf --- /dev/null +++ b/vendor/golang.org/x/net/trace/trace_go17.go @@ -0,0 +1,21 @@ +// Copyright 2017 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 go1.7 + +package trace + +import "context" + +// NewContext returns a copy of the parent context +// and associates it with a Trace. +func NewContext(ctx context.Context, tr Trace) context.Context { + return context.WithValue(ctx, contextKey, tr) +} + +// FromContext returns the Trace bound to the context, if any. +func FromContext(ctx context.Context) (tr Trace, ok bool) { + tr, ok = ctx.Value(contextKey).(Trace) + return +} diff --git a/vendor/golang.org/x/sys/unix/mkpost.go b/vendor/golang.org/x/sys/unix/mkpost.go deleted file mode 100644 index ed50d902af59..000000000000 --- a/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/vendor/golang.org/x/sys/unix/types_darwin.go b/vendor/golang.org/x/sys/unix/types_darwin.go deleted file mode 100644 index 1153261822b2..000000000000 --- a/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/vendor/golang.org/x/sys/unix/types_dragonfly.go b/vendor/golang.org/x/sys/unix/types_dragonfly.go deleted file mode 100644 index f3c971dffd49..000000000000 --- a/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/vendor/golang.org/x/sys/unix/types_freebsd.go b/vendor/golang.org/x/sys/unix/types_freebsd.go deleted file mode 100644 index ae24557ad155..000000000000 --- a/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/vendor/golang.org/x/sys/unix/types_linux.go b/vendor/golang.org/x/sys/unix/types_linux.go deleted file mode 100644 index 7dea79a8effa..000000000000 --- a/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/vendor/golang.org/x/sys/unix/types_netbsd.go b/vendor/golang.org/x/sys/unix/types_netbsd.go deleted file mode 100644 index d15f93d19251..000000000000 --- a/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/vendor/golang.org/x/sys/unix/types_openbsd.go b/vendor/golang.org/x/sys/unix/types_openbsd.go deleted file mode 100644 index b66fe25f73bd..000000000000 --- a/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/vendor/golang.org/x/sys/unix/types_solaris.go b/vendor/golang.org/x/sys/unix/types_solaris.go deleted file mode 100644 index c5d5c8f16a55..000000000000 --- a/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/vendor/golang.org/x/text/internal/gen/code.go b/vendor/golang.org/x/text/internal/gen/code.go deleted file mode 100644 index d7031b6945a2..000000000000 --- a/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/vendor/golang.org/x/text/internal/gen/gen.go b/vendor/golang.org/x/text/internal/gen/gen.go deleted file mode 100644 index 84c699faa96f..000000000000 --- a/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/vendor/golang.org/x/text/internal/triegen/compact.go b/vendor/golang.org/x/text/internal/triegen/compact.go deleted file mode 100644 index 397b975c1b71..000000000000 --- a/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/vendor/golang.org/x/text/internal/triegen/print.go b/vendor/golang.org/x/text/internal/triegen/print.go deleted file mode 100644 index 8d9f120bcdf0..000000000000 --- a/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/vendor/golang.org/x/text/internal/triegen/triegen.go b/vendor/golang.org/x/text/internal/triegen/triegen.go deleted file mode 100644 index adb01081247b..000000000000 --- a/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/vendor/golang.org/x/text/internal/ucd/ucd.go b/vendor/golang.org/x/text/internal/ucd/ucd.go deleted file mode 100644 index 309e8d8b16e6..000000000000 --- a/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/vendor/golang.org/x/text/unicode/bidi/gen.go b/vendor/golang.org/x/text/unicode/bidi/gen.go deleted file mode 100644 index 040f3013d585..000000000000 --- a/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/vendor/golang.org/x/text/unicode/bidi/gen_ranges.go b/vendor/golang.org/x/text/unicode/bidi/gen_ranges.go deleted file mode 100644 index 51bd68fa7f38..000000000000 --- a/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/vendor/golang.org/x/text/unicode/bidi/gen_trieval.go b/vendor/golang.org/x/text/unicode/bidi/gen_trieval.go deleted file mode 100644 index 9cb994289492..000000000000 --- a/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/vendor/golang.org/x/text/unicode/cldr/base.go b/vendor/golang.org/x/text/unicode/cldr/base.go deleted file mode 100644 index 2382f4d6da1a..000000000000 --- a/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/vendor/golang.org/x/text/unicode/cldr/cldr.go b/vendor/golang.org/x/text/unicode/cldr/cldr.go deleted file mode 100644 index 2197f8ac268e..000000000000 --- a/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/vendor/golang.org/x/text/unicode/cldr/collate.go b/vendor/golang.org/x/text/unicode/cldr/collate.go deleted file mode 100644 index 80ee28d795e3..000000000000 --- a/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 -// [