diff --git a/.circleci/config.yml b/.circleci/config.yml index cccc97d262..6d70b3120e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -676,6 +676,140 @@ jobs: key: cache002-warm-go-build-vendor-cache_6876_{{checksum ".buildcache/cache-keys/warm-go-build-vendor-cache-6876aa566f90846d4627c4a1c86ca155ccde2f1c"}} paths: - .buildcache/archives/08-warm-go-build-vendor-cache-6876aa566f90846d4627c4a1c86ca155ccde2f1c.tar.gz + test-go-remote-docker: + docker: + - image: circleci/golang:1.14.7-stretch + resource_class: large + working_directory: /go/src/github.com/hashicorp/vault + parallelism: 8 + steps: + - run: + command: | + # If the branch being tested starts with ui/ or docs/ we want to exit the job without failing + [[ "$CIRCLE_BRANCH" = ui/* || "$CIRCLE_BRANCH" = docs/* ]] && { + # stop the job from this step + circleci-agent step halt + } + # exit with success either way + exit 0 + name: Check branch name + working_directory: ~/ + - checkout + - setup_remote_docker: + docker_layer_caching: true + version: 18.09.3 + - run: + command: | + TZ=GMT date '+%Y%m%d' > /tmp/go-cache-key + name: Compute test cache key + - restore_cache: + keys: + - go-test-cache-date-v1-{{ checksum "/tmp/go-cache-key" }} + - run: + command: | + set -x + + case "" in + *-race*) export VAULT_CI_GO_TEST_RACE=1;; + esac + + # Install CircleCI CLI + curl -sSL \ + "https://github.com/CircleCI-Public/circleci-cli/releases/download/v${CIRCLECI_CLI_VERSION}/circleci-cli_${CIRCLECI_CLI_VERSION}_linux_amd64.tar.gz" \ + | sudo tar --overwrite -xz \ + -C /usr/local/bin \ + "circleci-cli_${CIRCLECI_CLI_VERSION}_linux_amd64/circleci" + + USE_DOCKER=0 + USE_DOCKER=1 + + # Split Go tests by prior test times. If use_docker is true, only run + # tests that depend on docker, otherwise only those that don't. + if [ $USE_DOCKER == 1 ]; then + package_names=$(go list -test -json ./... | + jq -r 'select(.Deps != null) | + select(any(.Deps[] ; contains("github.com/hashicorp/vault/helper/testhelpers/docker"))) | + .ForTest | select(. != null)' | + sort -u | circleci tests split --split-by=timings --timings-type=classname) + else + package_names=$(go list -test -json ./... | + jq -r 'select(.Deps != null) | + select(all(.Deps[] ; contains("github.com/hashicorp/vault/helper/testhelpers/docker")|not)) | + .ForTest | select(. != null)' | + sort -u | circleci tests split --split-by=timings --timings-type=classname) + fi + + # After running tests split step, we are now running the following steps + # in multiple different containers, each getting a different subset of + # the test packages in their package_names variable. Each container + # has its own remote docker VM. + + make prep + mkdir -p test-results/go-test + + # Create a docker network for our testcontainer + if [ $USE_DOCKER == 1 ]; then + export TEST_DOCKER_NETWORK_ID=$(docker network list -q -f 'name=vaulttest') + if [ -z $TEST_DOCKER_NETWORK_ID ]; then + TEST_DOCKER_NETWORK_ID=$(docker network create vaulttest) + fi + + # Start a docker testcontainer to run the tests in + docker run -d -e TEST_DOCKER_NETWORK_ID \ + -e DOCKER_CERT_PATH -e DOCKER_HOST -e DOCKER_MACHINE_NAME -e DOCKER_TLS_VERIFY -e NO_PROXY \ + -e VAULT_TEST_LOG_DIR=/tmp/testlogs \ + --network vaulttest --name \ + testcontainer circleci/golang:1.14.7-stretch \ + tail -f /dev/null + + # Run tests + docker cp /tmp/go-cache testcontainer:/tmp/gocache + docker exec testcontainer sh -c 'mkdir -p /go/src/github.com/hashicorp/vault' + docker cp . testcontainer:/go/src/github.com/hashicorp/vault/ + docker cp $DOCKER_CERT_PATH/ testcontainer:$DOCKER_CERT_PATH + + docker exec -w /go/src/github.com/hashicorp/vault/ \ + -e GO111MODULE -e CIRCLECI -e GOCACHE=/tmp/gocache -e VAULT_CI_GO_TEST_RACE \ + testcontainer \ + gotestsum --format=short-verbose \ + --junitfile test-results/go-test/results.xml \ + --jsonfile test-results/go-test/results.json \ + -- \ + -tags "${GO_TAGS}" \ + -timeout=15m \ + -parallel=20 \ + \ + ${package_names} + else + GOCACHE=/tmp/go-cache \ + gotestsum --format=short-verbose \ + --junitfile test-results/go-test/results.xml \ + --jsonfile test-results/go-test/results.json \ + -- \ + -tags "${GO_TAGS}" \ + -timeout=60m \ + -parallel=20 \ + \ + ${package_names} + fi + name: Run Go tests + no_output_timeout: 60m + - run: + command: | + docker cp testcontainer:/go/src/github.com/hashicorp/vault/test-results . + docker cp testcontainer:/tmp/gocache /tmp/go-cache + name: Copy test results + when: always + - store_artifacts: + path: test-results + - store_test_results: + path: test-results + - store_artifacts: + path: /tmp/testlogs + environment: + - CIRCLECI_CLI_VERSION: 0.1.5546 + - GO_TAGS: '' + - GO111MODULE: 'off' freebsd_386_package: docker: - image: circleci/buildpack-deps @@ -740,26 +874,22 @@ jobs: paths: - .buildcache/archives/08-warm-go-build-vendor-cache-0245576886d78da53ffbd161a95bd0ca099e5fc1.tar.gz test-go-race: - machine: true - shell: /usr/bin/env bash -euo pipefail -c + docker: + - image: circleci/golang:1.14.7-stretch + resource_class: xlarge working_directory: /go/src/github.com/hashicorp/vault + parallelism: 8 steps: - run: command: | - [ -n "$GO_VERSION" ] || { echo "You must set GO_VERSION"; exit 1; } - # Install Go - curl -sSLO "https://dl.google.com/go/go${GO_VERSION}.linux-amd64.tar.gz" - sudo rm -rf /usr/local/go - sudo tar -C /usr/local -xzf "go${GO_VERSION}.linux-amd64.tar.gz" - rm -f "go${GO_VERSION}.linux-amd64.tar.gz" - GOPATH="/go" - mkdir $GOPATH 2>/dev/null || { sudo mkdir $GOPATH && sudo chmod 777 $GOPATH; } - echo "export GOPATH='$GOPATH'" >> "$BASH_ENV" - echo "export PATH='$PATH:$GOPATH/bin:/usr/local/go/bin'" >> "$BASH_ENV" - - echo "$ go version" - go version - name: Setup Go + # If the branch being tested starts with ui/ or docs/ we want to exit the job without failing + [[ "$CIRCLE_BRANCH" = ui/* || "$CIRCLE_BRANCH" = docs/* ]] && { + # stop the job from this step + circleci-agent step halt + } + # exit with success either way + exit 0 + name: Check branch name working_directory: ~/ - checkout - run: @@ -774,7 +904,7 @@ jobs: set -x case "-race" in - *-race*) VAULT_CI_GO_TEST_RACE=1;; + *-race*) export VAULT_CI_GO_TEST_RACE=1;; esac # Install CircleCI CLI @@ -784,38 +914,77 @@ jobs: -C /usr/local/bin \ "circleci-cli_${CIRCLECI_CLI_VERSION}_linux_amd64/circleci" - # Split Go tests by prior test times - package_names=$(go list \ - -tags "${GO_TAGS}" \ - ./... \ - | grep -v /integ \ - | grep -v /vendor/ \ - | sort \ - | circleci tests split --split-by=timings --timings-type=classname) + USE_DOCKER=0 - # Install gotestsum - curl -sSL "https://github.com/gotestyourself/gotestsum/releases/download/v${GOTESTSUM_VERSION}/gotestsum_${GOTESTSUM_VERSION}_linux_amd64.tar.gz" \ - | sudo tar --overwrite -xz -C /usr/local/bin gotestsum + # Split Go tests by prior test times. If use_docker is true, only run + # tests that depend on docker, otherwise only those that don't. + if [ $USE_DOCKER == 1 ]; then + package_names=$(go list -test -json ./... | + jq -r 'select(.Deps != null) | + select(any(.Deps[] ; contains("github.com/hashicorp/vault/helper/testhelpers/docker"))) | + .ForTest | select(. != null)' | + sort -u | circleci tests split --split-by=timings --timings-type=classname) + else + package_names=$(go list -test -json ./... | + jq -r 'select(.Deps != null) | + select(all(.Deps[] ; contains("github.com/hashicorp/vault/helper/testhelpers/docker")|not)) | + .ForTest | select(. != null)' | + sort -u | circleci tests split --split-by=timings --timings-type=classname) + fi + + # After running tests split step, we are now running the following steps + # in multiple different containers, each getting a different subset of + # the test packages in their package_names variable. Each container + # has its own remote docker VM. - # Run tests make prep mkdir -p test-results/go-test - CGO_ENABLED= \ - VAULT_ADDR= \ - VAULT_TOKEN= \ - VAULT_DEV_ROOT_TOKEN_ID= \ - VAULT_ACC= \ + + # Create a docker network for our testcontainer + if [ $USE_DOCKER == 1 ]; then + export TEST_DOCKER_NETWORK_ID=$(docker network list -q -f 'name=vaulttest') + if [ -z $TEST_DOCKER_NETWORK_ID ]; then + TEST_DOCKER_NETWORK_ID=$(docker network create vaulttest) + fi + + # Start a docker testcontainer to run the tests in + docker run -d -e TEST_DOCKER_NETWORK_ID \ + -e DOCKER_CERT_PATH -e DOCKER_HOST -e DOCKER_MACHINE_NAME -e DOCKER_TLS_VERIFY -e NO_PROXY \ + -e VAULT_TEST_LOG_DIR=/tmp/testlogs \ + --network vaulttest --name \ + testcontainer circleci/golang:1.14.7-stretch \ + tail -f /dev/null + + # Run tests + docker cp /tmp/go-cache testcontainer:/tmp/gocache + docker exec testcontainer sh -c 'mkdir -p /go/src/github.com/hashicorp/vault' + docker cp . testcontainer:/go/src/github.com/hashicorp/vault/ + docker cp $DOCKER_CERT_PATH/ testcontainer:$DOCKER_CERT_PATH + + docker exec -w /go/src/github.com/hashicorp/vault/ \ + -e GO111MODULE -e CIRCLECI -e GOCACHE=/tmp/gocache -e VAULT_CI_GO_TEST_RACE \ + testcontainer \ + gotestsum --format=short-verbose \ + --junitfile test-results/go-test/results.xml \ + --jsonfile test-results/go-test/results.json \ + -- \ + -tags "${GO_TAGS}" \ + -timeout=15m \ + -parallel=20 \ + -race \ + ${package_names} + else GOCACHE=/tmp/go-cache \ - VAULT_TEST_LOG_DIR=/tmp/testlogs \ - gotestsum --format=short-verbose \ - --junitfile test-results/go-test/results.xml \ - --jsonfile test-results/go-test/results.json \ - -- \ - -tags "${GO_TAGS}" \ - -timeout=60m \ - -parallel=20 \ - -race \ - ${package_names} + gotestsum --format=short-verbose \ + --junitfile test-results/go-test/results.xml \ + --jsonfile test-results/go-test/results.json \ + -- \ + -tags "${GO_TAGS}" \ + -timeout=60m \ + -parallel=20 \ + -race \ + ${package_names} + fi name: Run Go tests no_output_timeout: 60m - store_artifacts: @@ -827,9 +996,7 @@ jobs: environment: - CIRCLECI_CLI_VERSION: 0.1.5546 - GO_TAGS: '' - - GO_VERSION: 1.14.7 - GO111MODULE: 'off' - - GOTESTSUM_VERSION: 0.5.2 freebsd_amd64_package: docker: - image: circleci/buildpack-deps @@ -1106,10 +1273,11 @@ jobs: paths: - .buildcache/archives/08-warm-go-build-vendor-cache-a0884ebd3bcd667787991bce276f3a9be2061998.tar.gz test-go: - machine: true - shell: /usr/bin/env bash -euo pipefail -c + docker: + - image: circleci/golang:1.14.7-stretch + resource_class: large working_directory: /go/src/github.com/hashicorp/vault - parallelism: 2 + parallelism: 8 steps: - run: command: | @@ -1122,23 +1290,6 @@ jobs: exit 0 name: Check branch name working_directory: ~/ - - run: - command: | - [ -n "$GO_VERSION" ] || { echo "You must set GO_VERSION"; exit 1; } - # Install Go - curl -sSLO "https://dl.google.com/go/go${GO_VERSION}.linux-amd64.tar.gz" - sudo rm -rf /usr/local/go - sudo tar -C /usr/local -xzf "go${GO_VERSION}.linux-amd64.tar.gz" - rm -f "go${GO_VERSION}.linux-amd64.tar.gz" - GOPATH="/go" - mkdir $GOPATH 2>/dev/null || { sudo mkdir $GOPATH && sudo chmod 777 $GOPATH; } - echo "export GOPATH='$GOPATH'" >> "$BASH_ENV" - echo "export PATH='$PATH:$GOPATH/bin:/usr/local/go/bin'" >> "$BASH_ENV" - - echo "$ go version" - go version - name: Setup Go - working_directory: ~/ - checkout - run: command: | @@ -1152,7 +1303,7 @@ jobs: set -x case "" in - *-race*) VAULT_CI_GO_TEST_RACE=1;; + *-race*) export VAULT_CI_GO_TEST_RACE=1;; esac # Install CircleCI CLI @@ -1162,38 +1313,77 @@ jobs: -C /usr/local/bin \ "circleci-cli_${CIRCLECI_CLI_VERSION}_linux_amd64/circleci" - # Split Go tests by prior test times - package_names=$(go list \ - -tags "${GO_TAGS}" \ - ./... \ - | grep -v /integ \ - | grep -v /vendor/ \ - | sort \ - | circleci tests split --split-by=timings --timings-type=classname) + USE_DOCKER=0 - # Install gotestsum - curl -sSL "https://github.com/gotestyourself/gotestsum/releases/download/v${GOTESTSUM_VERSION}/gotestsum_${GOTESTSUM_VERSION}_linux_amd64.tar.gz" \ - | sudo tar --overwrite -xz -C /usr/local/bin gotestsum + # Split Go tests by prior test times. If use_docker is true, only run + # tests that depend on docker, otherwise only those that don't. + if [ $USE_DOCKER == 1 ]; then + package_names=$(go list -test -json ./... | + jq -r 'select(.Deps != null) | + select(any(.Deps[] ; contains("github.com/hashicorp/vault/helper/testhelpers/docker"))) | + .ForTest | select(. != null)' | + sort -u | circleci tests split --split-by=timings --timings-type=classname) + else + package_names=$(go list -test -json ./... | + jq -r 'select(.Deps != null) | + select(all(.Deps[] ; contains("github.com/hashicorp/vault/helper/testhelpers/docker")|not)) | + .ForTest | select(. != null)' | + sort -u | circleci tests split --split-by=timings --timings-type=classname) + fi + + # After running tests split step, we are now running the following steps + # in multiple different containers, each getting a different subset of + # the test packages in their package_names variable. Each container + # has its own remote docker VM. - # Run tests make prep mkdir -p test-results/go-test - CGO_ENABLED= \ - VAULT_ADDR= \ - VAULT_TOKEN= \ - VAULT_DEV_ROOT_TOKEN_ID= \ - VAULT_ACC= \ + + # Create a docker network for our testcontainer + if [ $USE_DOCKER == 1 ]; then + export TEST_DOCKER_NETWORK_ID=$(docker network list -q -f 'name=vaulttest') + if [ -z $TEST_DOCKER_NETWORK_ID ]; then + TEST_DOCKER_NETWORK_ID=$(docker network create vaulttest) + fi + + # Start a docker testcontainer to run the tests in + docker run -d -e TEST_DOCKER_NETWORK_ID \ + -e DOCKER_CERT_PATH -e DOCKER_HOST -e DOCKER_MACHINE_NAME -e DOCKER_TLS_VERIFY -e NO_PROXY \ + -e VAULT_TEST_LOG_DIR=/tmp/testlogs \ + --network vaulttest --name \ + testcontainer circleci/golang:1.14.7-stretch \ + tail -f /dev/null + + # Run tests + docker cp /tmp/go-cache testcontainer:/tmp/gocache + docker exec testcontainer sh -c 'mkdir -p /go/src/github.com/hashicorp/vault' + docker cp . testcontainer:/go/src/github.com/hashicorp/vault/ + docker cp $DOCKER_CERT_PATH/ testcontainer:$DOCKER_CERT_PATH + + docker exec -w /go/src/github.com/hashicorp/vault/ \ + -e GO111MODULE -e CIRCLECI -e GOCACHE=/tmp/gocache -e VAULT_CI_GO_TEST_RACE \ + testcontainer \ + gotestsum --format=short-verbose \ + --junitfile test-results/go-test/results.xml \ + --jsonfile test-results/go-test/results.json \ + -- \ + -tags "${GO_TAGS}" \ + -timeout=15m \ + -parallel=20 \ + \ + ${package_names} + else GOCACHE=/tmp/go-cache \ - VAULT_TEST_LOG_DIR=/tmp/testlogs \ - gotestsum --format=short-verbose \ - --junitfile test-results/go-test/results.xml \ - --jsonfile test-results/go-test/results.json \ - -- \ - -tags "${GO_TAGS}" \ - -timeout=60m \ - -parallel=20 \ - \ - ${package_names} + gotestsum --format=short-verbose \ + --junitfile test-results/go-test/results.xml \ + --jsonfile test-results/go-test/results.json \ + -- \ + -tags "${GO_TAGS}" \ + -timeout=60m \ + -parallel=20 \ + \ + ${package_names} + fi name: Run Go tests no_output_timeout: 60m - store_artifacts: @@ -1205,9 +1395,7 @@ jobs: environment: - CIRCLECI_CLI_VERSION: 0.1.5546 - GO_TAGS: '' - - GO_VERSION: 1.14.7 - GO111MODULE: 'off' - - GOTESTSUM_VERSION: 0.5.2 test-go-nightly: machine: true shell: /usr/bin/env bash -euo pipefail -c @@ -1254,7 +1442,7 @@ jobs: set -x case "" in - *-race*) VAULT_CI_GO_TEST_RACE=1;; + *-race*) export VAULT_CI_GO_TEST_RACE=1;; esac # Install CircleCI CLI @@ -1264,38 +1452,77 @@ jobs: -C /usr/local/bin \ "circleci-cli_${CIRCLECI_CLI_VERSION}_linux_amd64/circleci" - # Split Go tests by prior test times - package_names=$(go list \ - -tags "${GO_TAGS}" \ - ./... \ - | grep -v /integ \ - | grep -v /vendor/ \ - | sort \ - | circleci tests split --split-by=timings --timings-type=classname) + USE_DOCKER=0 - # Install gotestsum - curl -sSL "https://github.com/gotestyourself/gotestsum/releases/download/v${GOTESTSUM_VERSION}/gotestsum_${GOTESTSUM_VERSION}_linux_amd64.tar.gz" \ - | sudo tar --overwrite -xz -C /usr/local/bin gotestsum + # Split Go tests by prior test times. If use_docker is true, only run + # tests that depend on docker, otherwise only those that don't. + if [ $USE_DOCKER == 1 ]; then + package_names=$(go list -test -json ./... | + jq -r 'select(.Deps != null) | + select(any(.Deps[] ; contains("github.com/hashicorp/vault/helper/testhelpers/docker"))) | + .ForTest | select(. != null)' | + sort -u | circleci tests split --split-by=timings --timings-type=classname) + else + package_names=$(go list -test -json ./... | + jq -r 'select(.Deps != null) | + select(all(.Deps[] ; contains("github.com/hashicorp/vault/helper/testhelpers/docker")|not)) | + .ForTest | select(. != null)' | + sort -u | circleci tests split --split-by=timings --timings-type=classname) + fi + + # After running tests split step, we are now running the following steps + # in multiple different containers, each getting a different subset of + # the test packages in their package_names variable. Each container + # has its own remote docker VM. - # Run tests make prep mkdir -p test-results/go-test - CGO_ENABLED= \ - VAULT_ADDR= \ - VAULT_TOKEN= \ - VAULT_DEV_ROOT_TOKEN_ID= \ - VAULT_ACC= \ + + # Create a docker network for our testcontainer + if [ $USE_DOCKER == 1 ]; then + export TEST_DOCKER_NETWORK_ID=$(docker network list -q -f 'name=vaulttest') + if [ -z $TEST_DOCKER_NETWORK_ID ]; then + TEST_DOCKER_NETWORK_ID=$(docker network create vaulttest) + fi + + # Start a docker testcontainer to run the tests in + docker run -d -e TEST_DOCKER_NETWORK_ID \ + -e DOCKER_CERT_PATH -e DOCKER_HOST -e DOCKER_MACHINE_NAME -e DOCKER_TLS_VERIFY -e NO_PROXY \ + -e VAULT_TEST_LOG_DIR=/tmp/testlogs \ + --network vaulttest --name \ + testcontainer circleci/golang:1.14.7-stretch \ + tail -f /dev/null + + # Run tests + docker cp /tmp/go-cache testcontainer:/tmp/gocache + docker exec testcontainer sh -c 'mkdir -p /go/src/github.com/hashicorp/vault' + docker cp . testcontainer:/go/src/github.com/hashicorp/vault/ + docker cp $DOCKER_CERT_PATH/ testcontainer:$DOCKER_CERT_PATH + + docker exec -w /go/src/github.com/hashicorp/vault/ \ + -e GO111MODULE -e CIRCLECI -e GOCACHE=/tmp/gocache -e VAULT_CI_GO_TEST_RACE \ + testcontainer \ + gotestsum --format=short-verbose \ + --junitfile test-results/go-test/results.xml \ + --jsonfile test-results/go-test/results.json \ + -- \ + -tags "${GO_TAGS}" \ + -timeout=15m \ + -parallel=20 \ + \ + ${package_names} + else GOCACHE=/tmp/go-cache \ - VAULT_TEST_LOG_DIR=/tmp/testlogs \ - gotestsum --format=short-verbose \ - --junitfile test-results/go-test/results.xml \ - --jsonfile test-results/go-test/results.json \ - -- \ - -tags "${GO_TAGS}" \ - -timeout=60m \ - -parallel=20 \ - \ - ${package_names} + gotestsum --format=short-verbose \ + --junitfile test-results/go-test/results.xml \ + --jsonfile test-results/go-test/results.json \ + -- \ + -tags "${GO_TAGS}" \ + -timeout=60m \ + -parallel=20 \ + \ + ${package_names} + fi name: Run Go tests no_output_timeout: 60m - save_cache: @@ -1757,6 +1984,140 @@ jobs: environment: - AUTO_INSTALL_TOOLS: 'YES' - PRODUCT_REVISION: '' + test-go-race-remote-docker: + docker: + - image: circleci/golang:1.14.7-stretch + resource_class: xlarge + working_directory: /go/src/github.com/hashicorp/vault + parallelism: 8 + steps: + - run: + command: | + # If the branch being tested starts with ui/ or docs/ we want to exit the job without failing + [[ "$CIRCLE_BRANCH" = ui/* || "$CIRCLE_BRANCH" = docs/* ]] && { + # stop the job from this step + circleci-agent step halt + } + # exit with success either way + exit 0 + name: Check branch name + working_directory: ~/ + - checkout + - setup_remote_docker: + docker_layer_caching: true + version: 18.09.3 + - run: + command: | + TZ=GMT date '+%Y%m%d' > /tmp/go-cache-key + name: Compute test cache key + - restore_cache: + keys: + - go-test-cache-date-v1-{{ checksum "/tmp/go-cache-key" }} + - run: + command: | + set -x + + case "-race" in + *-race*) export VAULT_CI_GO_TEST_RACE=1;; + esac + + # Install CircleCI CLI + curl -sSL \ + "https://github.com/CircleCI-Public/circleci-cli/releases/download/v${CIRCLECI_CLI_VERSION}/circleci-cli_${CIRCLECI_CLI_VERSION}_linux_amd64.tar.gz" \ + | sudo tar --overwrite -xz \ + -C /usr/local/bin \ + "circleci-cli_${CIRCLECI_CLI_VERSION}_linux_amd64/circleci" + + USE_DOCKER=0 + USE_DOCKER=1 + + # Split Go tests by prior test times. If use_docker is true, only run + # tests that depend on docker, otherwise only those that don't. + if [ $USE_DOCKER == 1 ]; then + package_names=$(go list -test -json ./... | + jq -r 'select(.Deps != null) | + select(any(.Deps[] ; contains("github.com/hashicorp/vault/helper/testhelpers/docker"))) | + .ForTest | select(. != null)' | + sort -u | circleci tests split --split-by=timings --timings-type=classname) + else + package_names=$(go list -test -json ./... | + jq -r 'select(.Deps != null) | + select(all(.Deps[] ; contains("github.com/hashicorp/vault/helper/testhelpers/docker")|not)) | + .ForTest | select(. != null)' | + sort -u | circleci tests split --split-by=timings --timings-type=classname) + fi + + # After running tests split step, we are now running the following steps + # in multiple different containers, each getting a different subset of + # the test packages in their package_names variable. Each container + # has its own remote docker VM. + + make prep + mkdir -p test-results/go-test + + # Create a docker network for our testcontainer + if [ $USE_DOCKER == 1 ]; then + export TEST_DOCKER_NETWORK_ID=$(docker network list -q -f 'name=vaulttest') + if [ -z $TEST_DOCKER_NETWORK_ID ]; then + TEST_DOCKER_NETWORK_ID=$(docker network create vaulttest) + fi + + # Start a docker testcontainer to run the tests in + docker run -d -e TEST_DOCKER_NETWORK_ID \ + -e DOCKER_CERT_PATH -e DOCKER_HOST -e DOCKER_MACHINE_NAME -e DOCKER_TLS_VERIFY -e NO_PROXY \ + -e VAULT_TEST_LOG_DIR=/tmp/testlogs \ + --network vaulttest --name \ + testcontainer circleci/golang:1.14.7-stretch \ + tail -f /dev/null + + # Run tests + docker cp /tmp/go-cache testcontainer:/tmp/gocache + docker exec testcontainer sh -c 'mkdir -p /go/src/github.com/hashicorp/vault' + docker cp . testcontainer:/go/src/github.com/hashicorp/vault/ + docker cp $DOCKER_CERT_PATH/ testcontainer:$DOCKER_CERT_PATH + + docker exec -w /go/src/github.com/hashicorp/vault/ \ + -e GO111MODULE -e CIRCLECI -e GOCACHE=/tmp/gocache -e VAULT_CI_GO_TEST_RACE \ + testcontainer \ + gotestsum --format=short-verbose \ + --junitfile test-results/go-test/results.xml \ + --jsonfile test-results/go-test/results.json \ + -- \ + -tags "${GO_TAGS}" \ + -timeout=15m \ + -parallel=20 \ + -race \ + ${package_names} + else + GOCACHE=/tmp/go-cache \ + gotestsum --format=short-verbose \ + --junitfile test-results/go-test/results.xml \ + --jsonfile test-results/go-test/results.json \ + -- \ + -tags "${GO_TAGS}" \ + -timeout=60m \ + -parallel=20 \ + -race \ + ${package_names} + fi + name: Run Go tests + no_output_timeout: 60m + - run: + command: | + docker cp testcontainer:/go/src/github.com/hashicorp/vault/test-results . + docker cp testcontainer:/tmp/gocache /tmp/go-cache + name: Copy test results + when: always + - store_artifacts: + path: test-results + - store_test_results: + path: test-results + - store_artifacts: + path: /tmp/testlogs + environment: + - CIRCLECI_CLI_VERSION: 0.1.5546 + - GO_TAGS: '' + - GO111MODULE: 'off' workflows: build-standalone: jobs: @@ -1853,8 +2214,21 @@ workflows: - install-ui-dependencies - build-go-dev - test-go: + filters: + branches: + ignore: + - /^docs\/.*/ + - /^ui\/.*/ requires: - - build-go-dev + - pre-flight-checks + - test-go-remote-docker: + filters: + branches: + ignore: + - /^docs\/.*/ + - /^ui\/.*/ + requires: + - pre-flight-checks - test-go-race: filters: branches: @@ -1862,7 +2236,15 @@ workflows: - /^docs\/.*/ - /^ui\/.*/ requires: - - build-go-dev + - pre-flight-checks + - test-go-race-remote-docker: + filters: + branches: + ignore: + - /^docs\/.*/ + - /^ui\/.*/ + requires: + - pre-flight-checks - website-docker-image: filters: branches: diff --git a/.circleci/config/@config.yml b/.circleci/config/@config.yml index 1eb7a29618..38fbc68312 100644 --- a/.circleci/config/@config.yml +++ b/.circleci/config/@config.yml @@ -3,4 +3,3 @@ version: 2.1 orbs: slack: circleci/slack@3.2.0 - diff --git a/.circleci/config/commands/go_test.yml b/.circleci/config/commands/go_test.yml index 459195811f..5dff6448d8 100644 --- a/.circleci/config/commands/go_test.yml +++ b/.circleci/config/commands/go_test.yml @@ -12,6 +12,12 @@ parameters: save_cache: type: boolean default: false + go_image: + type: string + default: "circleci/golang:1.14.7-stretch" + use_docker: + type: boolean + default: false steps: - run: name: Compute test cache key @@ -27,7 +33,7 @@ steps: set -x case "<< parameters.extra_flags >>" in - *-race*) VAULT_CI_GO_TEST_RACE=1;; + *-race*) export VAULT_CI_GO_TEST_RACE=1;; esac # Install CircleCI CLI @@ -37,39 +43,90 @@ steps: -C /usr/local/bin \ "circleci-cli_${CIRCLECI_CLI_VERSION}_linux_amd64/circleci" - # Split Go tests by prior test times - package_names=$(go list \ - -tags "${GO_TAGS}" \ - ./... \ - | grep -v /integ \ - | grep -v /vendor/ \ - | sort \ - | circleci tests split --split-by=timings --timings-type=classname) + USE_DOCKER=0 + <<# parameters.use_docker >> + USE_DOCKER=1 + <> - # Install gotestsum - curl -sSL "https://github.com/gotestyourself/gotestsum/releases/download/v${GOTESTSUM_VERSION}/gotestsum_${GOTESTSUM_VERSION}_linux_amd64.tar.gz" \ - | sudo tar --overwrite -xz -C /usr/local/bin gotestsum + # Split Go tests by prior test times. If use_docker is true, only run + # tests that depend on docker, otherwise only those that don't. + if [ $USE_DOCKER == 1 ]; then + package_names=$(go list -test -json ./... | + jq -r 'select(.Deps != null) | + select(any(.Deps[] ; contains("github.com/hashicorp/vault/helper/testhelpers/docker"))) | + .ForTest | select(. != null)' | + sort -u | circleci tests split --split-by=timings --timings-type=classname) + else + package_names=$(go list -test -json ./... | + jq -r 'select(.Deps != null) | + select(all(.Deps[] ; contains("github.com/hashicorp/vault/helper/testhelpers/docker")|not)) | + .ForTest | select(. != null)' | + sort -u | circleci tests split --split-by=timings --timings-type=classname) + fi + + # After running tests split step, we are now running the following steps + # in multiple different containers, each getting a different subset of + # the test packages in their package_names variable. Each container + # has its own remote docker VM. - # Run tests make prep mkdir -p test-results/go-test - CGO_ENABLED= \ - VAULT_ADDR= \ - VAULT_TOKEN= \ - VAULT_DEV_ROOT_TOKEN_ID= \ - VAULT_ACC= \ - GOCACHE=<< parameters.cache_dir >> \ - VAULT_TEST_LOG_DIR=<< parameters.log_dir >> \ - gotestsum --format=short-verbose \ - --junitfile test-results/go-test/results.xml \ - --jsonfile test-results/go-test/results.json \ - -- \ - -tags "${GO_TAGS}" \ - -timeout=60m \ - -parallel=20 \ - << parameters.extra_flags >> \ - ${package_names} + # Create a docker network for our testcontainer + if [ $USE_DOCKER == 1 ]; then + export TEST_DOCKER_NETWORK_ID=$(docker network list -q -f 'name=vaulttest') + if [ -z $TEST_DOCKER_NETWORK_ID ]; then + TEST_DOCKER_NETWORK_ID=$(docker network create vaulttest) + fi + + # Start a docker testcontainer to run the tests in + docker run -d -e TEST_DOCKER_NETWORK_ID \ + -e DOCKER_CERT_PATH -e DOCKER_HOST -e DOCKER_MACHINE_NAME -e DOCKER_TLS_VERIFY -e NO_PROXY \ + -e VAULT_TEST_LOG_DIR=<< parameters.log_dir >> \ + --network vaulttest --name \ + testcontainer << parameters.go_image >> \ + tail -f /dev/null + + # Run tests + docker cp << parameters.cache_dir >> testcontainer:/tmp/gocache + docker exec testcontainer sh -c 'mkdir -p /go/src/github.com/hashicorp/vault' + docker cp . testcontainer:/go/src/github.com/hashicorp/vault/ + docker cp $DOCKER_CERT_PATH/ testcontainer:$DOCKER_CERT_PATH + + docker exec -w /go/src/github.com/hashicorp/vault/ \ + -e GO111MODULE -e CIRCLECI -e GOCACHE=/tmp/gocache -e VAULT_CI_GO_TEST_RACE \ + testcontainer \ + gotestsum --format=short-verbose \ + --junitfile test-results/go-test/results.xml \ + --jsonfile test-results/go-test/results.json \ + -- \ + -tags "${GO_TAGS}" \ + -timeout=15m \ + -parallel=20 \ + << parameters.extra_flags >> \ + ${package_names} + else + GOCACHE=<< parameters.cache_dir >> \ + gotestsum --format=short-verbose \ + --junitfile test-results/go-test/results.xml \ + --jsonfile test-results/go-test/results.json \ + -- \ + -tags "${GO_TAGS}" \ + -timeout=60m \ + -parallel=20 \ + << parameters.extra_flags >> \ + ${package_names} + fi + + - when: + condition: << parameters.use_docker >> + steps: + - run: + name: Copy test results + when: always + command: | + docker cp testcontainer:/go/src/github.com/hashicorp/vault/test-results . + docker cp testcontainer:/tmp/gocache << parameters.cache_dir >> - when: condition: << parameters.save_cache >> steps: diff --git a/.circleci/config/executors/@executors.yml b/.circleci/config/executors/@executors.yml index ddba26b92e..6de7b70956 100644 --- a/.circleci/config/executors/@executors.yml +++ b/.circleci/config/executors/@executors.yml @@ -23,3 +23,21 @@ alpine: - image: alpine:3.10.2 shell: /bin/sh working_directory: /go/src/github.com/hashicorp/vault +docker-env-large: + resource_class: large + docker: + - image: "circleci/golang:1.14.7-stretch" + environment: + GO111MODULE: "off" + CIRCLECI_CLI_VERSION: 0.1.5546 # Pin CircleCI CLI to patch version (ex: 1.2.3) + GO_TAGS: "" + working_directory: /go/src/github.com/hashicorp/vault +docker-env-xlarge: + resource_class: xlarge + docker: + - image: "circleci/golang:1.14.7-stretch" + environment: + GO111MODULE: "off" + CIRCLECI_CLI_VERSION: 0.1.5546 # Pin CircleCI CLI to patch version (ex: 1.2.3) + GO_TAGS: "" + working_directory: /go/src/github.com/hashicorp/vault diff --git a/.circleci/config/jobs/test-go-race-remote-docker.yml b/.circleci/config/jobs/test-go-race-remote-docker.yml new file mode 100644 index 0000000000..3139fc5ffb --- /dev/null +++ b/.circleci/config/jobs/test-go-race-remote-docker.yml @@ -0,0 +1,18 @@ +executor: docker-env-xlarge +parallelism: 8 +steps: + - check-branch-name + - checkout + - setup_remote_docker: + version: 18.09.3 + docker_layer_caching: true + - go_test: + extra_flags: "-race" + log_dir: "/tmp/testlogs" + use_docker: true + - store_artifacts: + path: test-results + - store_test_results: + path: test-results + - store_artifacts: + path: "/tmp/testlogs" diff --git a/.circleci/config/jobs/test-go-race.yml b/.circleci/config/jobs/test-go-race.yml index e20167420d..5cd3fa0328 100644 --- a/.circleci/config/jobs/test-go-race.yml +++ b/.circleci/config/jobs/test-go-race.yml @@ -1,6 +1,7 @@ -executor: go-machine +executor: docker-env-xlarge +parallelism: 8 steps: - - setup-go + - check-branch-name - checkout - go_test: extra_flags: "-race" diff --git a/.circleci/config/jobs/test-go-remote-docker.yml b/.circleci/config/jobs/test-go-remote-docker.yml new file mode 100644 index 0000000000..6542713d3b --- /dev/null +++ b/.circleci/config/jobs/test-go-remote-docker.yml @@ -0,0 +1,17 @@ +executor: docker-env-large +parallelism: 8 +steps: + - check-branch-name + - checkout + - setup_remote_docker: + version: 18.09.3 + docker_layer_caching: true + - go_test: + log_dir: "/tmp/testlogs" + use_docker: true + - store_artifacts: + path: test-results + - store_test_results: + path: test-results + - store_artifacts: + path: "/tmp/testlogs" diff --git a/.circleci/config/jobs/test-go.yml b/.circleci/config/jobs/test-go.yml index 78cc7d3ea7..8116234a20 100644 --- a/.circleci/config/jobs/test-go.yml +++ b/.circleci/config/jobs/test-go.yml @@ -1,8 +1,7 @@ -executor: go-machine -parallelism: 2 +executor: docker-env-large +parallelism: 8 steps: - check-branch-name - - setup-go - checkout - go_test: log_dir: "/tmp/testlogs" diff --git a/.circleci/config/workflows/ci.yml b/.circleci/config/workflows/ci.yml index 66a891df42..30c4231bc9 100644 --- a/.circleci/config/workflows/ci.yml +++ b/.circleci/config/workflows/ci.yml @@ -20,10 +20,34 @@ jobs: ignore: /pull\/[0-9]+/ - test-go: requires: - - build-go-dev + - pre-flight-checks + filters: + branches: + # UI and Docs-only branches should skip go tests + ignore: + - /^docs\/.*/ + - /^ui\/.*/ + - test-go-remote-docker: + requires: + - pre-flight-checks + filters: + branches: + # UI and Docs-only branches should skip go tests + ignore: + - /^docs\/.*/ + - /^ui\/.*/ - test-go-race: requires: - - build-go-dev + - pre-flight-checks + filters: + branches: + # UI and Docs-only branches should skip go tests + ignore: + - /^docs\/.*/ + - /^ui\/.*/ + - test-go-race-remote-docker: + requires: + - pre-flight-checks filters: branches: # UI and Docs-only branches should skip go tests diff --git a/builtin/credential/aws/backend.go b/builtin/credential/aws/backend.go index 127fd87641..d0fca69f85 100644 --- a/builtin/credential/aws/backend.go +++ b/builtin/credential/aws/backend.go @@ -18,6 +18,7 @@ import ( ) const amzHeaderPrefix = "X-Amz-" + var defaultAllowedSTSRequestHeaders = []string{ "X-Amz-Date", "X-Amz-Credential", diff --git a/builtin/credential/aws/path_config_client.go b/builtin/credential/aws/path_config_client.go index 16c368635f..4719f20055 100644 --- a/builtin/credential/aws/path_config_client.go +++ b/builtin/credential/aws/path_config_client.go @@ -336,7 +336,7 @@ type clientConfig struct { func (c *clientConfig) validateAllowedSTSHeaderValues(headers http.Header) error { for k := range headers { h := textproto.CanonicalMIMEHeaderKey(k) - if strings.HasPrefix(h, amzHeaderPrefix) && + if strings.HasPrefix(h, amzHeaderPrefix) && !strutil.StrListContains(defaultAllowedSTSRequestHeaders, h) && !strutil.StrListContains(c.AllowedSTSHeaderValues, h) { return errors.New("invalid request header: " + k) diff --git a/builtin/credential/radius/backend_test.go b/builtin/credential/radius/backend_test.go index c1c5291741..1ded629b6c 100644 --- a/builtin/credential/radius/backend_test.go +++ b/builtin/credential/radius/backend_test.go @@ -6,13 +6,13 @@ import ( "os" "reflect" "strconv" + "strings" "testing" "time" "github.com/hashicorp/vault/helper/testhelpers/docker" logicaltest "github.com/hashicorp/vault/helper/testhelpers/logical" "github.com/hashicorp/vault/sdk/logical" - "github.com/ory/dockertest" ) const ( @@ -32,40 +32,30 @@ func prepareRadiusTestContainer(t *testing.T) (func(), string, int) { return func() {}, os.Getenv(envRadiusRadiusHost), port } - pool, err := dockertest.NewPool("") + runner, err := docker.NewServiceRunner(docker.RunOptions{ + ImageRepo: "jumanjiman/radiusd", + ImageTag: "latest", + ContainerName: "radiusd", + Cmd: []string{"-f", "-l", "stdout"}, + Ports: []string{"1812/udp"}, + }) if err != nil { - t.Fatalf("Failed to connect to docker: %s", err) + t.Fatalf("Could not start docker radiusd: %s", err) } - runOpts := &dockertest.RunOptions{ - Repository: "jumanjiman/radiusd", - Cmd: []string{"-f", "-l", "stdout"}, - ExposedPorts: []string{"1812/udp"}, - Tag: "latest", - } - resource, err := pool.RunWithOptions(runOpts) - if err != nil { - t.Fatalf("Could not start local radius docker container: %s", err) - } - - cleanup := func() { - docker.CleanupResource(t, pool, resource) - } - - port, _ := strconv.Atoi(resource.GetPort("1812/udp")) - address := fmt.Sprintf("127.0.0.1") - - // exponential backoff-retry - if err = pool.Retry(func() error { + svc, err := runner.StartService(context.Background(), func(ctx context.Context, host string, port int) (docker.ServiceConfig, error) { // There's no straightfoward way to check the state, but the server starts // up quick so a 2 second sleep should be enough. time.Sleep(2 * time.Second) - return nil - }); err != nil { - cleanup() - t.Fatalf("Could not connect to radius docker container: %s", err) + return docker.NewServiceHostPort(host, port), nil + }) + if err != nil { + t.Fatalf("Could not start docker radiusd: %s", err) } - return cleanup, address, port + + pieces := strings.Split(svc.Config.Address(), ":") + port, _ := strconv.Atoi(pieces[1]) + return svc.Cleanup, pieces[0], port } func TestBackend_Config(t *testing.T) { diff --git a/builtin/logical/cassandra/backend_test.go b/builtin/logical/cassandra/backend_test.go index 56e89d9aad..fcf8e02b7d 100644 --- a/builtin/logical/cassandra/backend_test.go +++ b/builtin/logical/cassandra/backend_test.go @@ -4,81 +4,15 @@ import ( "context" "fmt" "log" - "os" - "strconv" - "sync" "testing" - "github.com/gocql/gocql" - "github.com/hashicorp/vault/helper/testhelpers/docker" + "github.com/hashicorp/vault/helper/testhelpers/cassandra" logicaltest "github.com/hashicorp/vault/helper/testhelpers/logical" "github.com/hashicorp/vault/sdk/logical" "github.com/mitchellh/mapstructure" - "github.com/ory/dockertest" ) -var ( - testImagePull sync.Once -) - -func prepareCassandraTestContainer(t *testing.T) (func(), string, int) { - if os.Getenv("CASSANDRA_HOST") != "" { - return func() {}, os.Getenv("CASSANDRA_HOST"), 0 - } - - pool, err := dockertest.NewPool("") - if err != nil { - t.Fatalf("Failed to connect to docker: %s", err) - } - - cwd, _ := os.Getwd() - cassandraMountPath := fmt.Sprintf("%s/test-fixtures/:/etc/cassandra/", cwd) - - ro := &dockertest.RunOptions{ - Repository: "cassandra", - Tag: "latest", - Env: []string{"CASSANDRA_BROADCAST_ADDRESS=127.0.0.1"}, - Mounts: []string{cassandraMountPath}, - } - resource, err := pool.RunWithOptions(ro) - if err != nil { - t.Fatalf("Could not start local cassandra docker container: %s", err) - } - - cleanup := func() { - docker.CleanupResource(t, pool, resource) - } - - port, _ := strconv.Atoi(resource.GetPort("9042/tcp")) - address := fmt.Sprintf("127.0.0.1:%d", port) - - // exponential backoff-retry - if err = pool.Retry(func() error { - clusterConfig := gocql.NewCluster(address) - clusterConfig.Authenticator = gocql.PasswordAuthenticator{ - Username: "cassandra", - Password: "cassandra", - } - clusterConfig.ProtoVersion = 4 - clusterConfig.Port = port - - session, err := clusterConfig.CreateSession() - if err != nil { - return fmt.Errorf("error creating session: %s", err) - } - defer session.Close() - return nil - }); err != nil { - cleanup() - t.Fatalf("Could not connect to cassandra docker container: %s", err) - } - return cleanup, address, port -} - func TestBackend_basic(t *testing.T) { - if os.Getenv("VAULT_ACC") == "" { - t.SkipNow() - } config := logical.TestBackendConfig() config.StorageView = &logical.InmemStorage{} b, err := Factory(context.Background(), config) @@ -86,7 +20,7 @@ func TestBackend_basic(t *testing.T) { t.Fatal(err) } - cleanup, hostname, _ := prepareCassandraTestContainer(t) + cleanup, hostname := cassandra.PrepareTestContainer(t, "latest") defer cleanup() logicaltest.Test(t, logicaltest.TestCase{ @@ -100,9 +34,6 @@ func TestBackend_basic(t *testing.T) { } func TestBackend_roleCrud(t *testing.T) { - if os.Getenv("VAULT_ACC") == "" { - t.SkipNow() - } config := logical.TestBackendConfig() config.StorageView = &logical.InmemStorage{} b, err := Factory(context.Background(), config) @@ -110,7 +41,7 @@ func TestBackend_roleCrud(t *testing.T) { t.Fatal(err) } - cleanup, hostname, _ := prepareCassandraTestContainer(t) + cleanup, hostname := cassandra.PrepareTestContainer(t, "latest") defer cleanup() logicaltest.Test(t, logicaltest.TestCase{ @@ -129,12 +60,6 @@ func TestBackend_roleCrud(t *testing.T) { }) } -func testAccPreCheck(t *testing.T) { - if v := os.Getenv("CASSANDRA_HOST"); v == "" { - t.Fatal("CASSANDRA_HOST must be set for acceptance tests") - } -} - func testAccStepConfig(t *testing.T, hostname string) logicaltest.TestStep { return logicaltest.TestStep{ Operation: logical.UpdateOperation, diff --git a/builtin/logical/consul/backend_test.go b/builtin/logical/consul/backend_test.go index 285f96e029..69dcee7ec9 100644 --- a/builtin/logical/consul/backend_test.go +++ b/builtin/logical/consul/backend_test.go @@ -38,12 +38,12 @@ func testBackendConfigAccess(t *testing.T, version string) { t.Fatal(err) } - cleanup, connURL, connToken := consul.PrepareTestContainer(t, version) + cleanup, consulConfig := consul.PrepareTestContainer(t, version) defer cleanup() connData := map[string]interface{}{ - "address": connURL, - "token": connToken, + "address": consulConfig.Address(), + "token": consulConfig.Token, } confReq := &logical.Request{ @@ -103,11 +103,12 @@ func testBackendRenewRevoke(t *testing.T, version string) { t.Fatal(err) } - cleanup, connURL, connToken := consul.PrepareTestContainer(t, version) + cleanup, consulConfig := consul.PrepareTestContainer(t, version) defer cleanup() + connData := map[string]interface{}{ - "address": connURL, - "token": connToken, + "address": consulConfig.Address(), + "token": consulConfig.Token, } req := &logical.Request{ @@ -208,11 +209,12 @@ func testBackendRenewRevoke14(t *testing.T, version string) { t.Fatal(err) } - cleanup, connURL, connToken := consul.PrepareTestContainer(t, version) + cleanup, consulConfig := consul.PrepareTestContainer(t, version) defer cleanup() + connData := map[string]interface{}{ - "address": connURL, - "token": connToken, + "address": consulConfig.Address(), + "token": consulConfig.Token, } req := &logical.Request{ @@ -317,11 +319,12 @@ func TestBackend_LocalToken(t *testing.T) { t.Fatal(err) } - cleanup, connURL, connToken := consul.PrepareTestContainer(t, "") + cleanup, consulConfig := consul.PrepareTestContainer(t, "") defer cleanup() + connData := map[string]interface{}{ - "address": connURL, - "token": connToken, + "address": consulConfig.Address(), + "token": consulConfig.Token, } req := &logical.Request{ @@ -459,11 +462,12 @@ func testBackendManagement(t *testing.T, version string) { t.Fatal(err) } - cleanup, connURL, connToken := consul.PrepareTestContainer(t, version) + cleanup, consulConfig := consul.PrepareTestContainer(t, version) defer cleanup() + connData := map[string]interface{}{ - "address": connURL, - "token": connToken, + "address": consulConfig.Address(), + "token": consulConfig.Token, } logicaltest.Test(t, logicaltest.TestCase{ @@ -503,11 +507,12 @@ func testBackendBasic(t *testing.T, version string) { t.Fatal(err) } - cleanup, connURL, connToken := consul.PrepareTestContainer(t, version) + cleanup, consulConfig := consul.PrepareTestContainer(t, version) defer cleanup() + connData := map[string]interface{}{ - "address": connURL, - "token": connToken, + "address": consulConfig.Address(), + "token": consulConfig.Token, } logicaltest.Test(t, logicaltest.TestCase{ diff --git a/builtin/logical/database/backend_test.go b/builtin/logical/database/backend_test.go index cf59f6d639..26eca31159 100644 --- a/builtin/logical/database/backend_test.go +++ b/builtin/logical/database/backend_test.go @@ -3,12 +3,10 @@ package database import ( "context" "database/sql" - "fmt" "log" "os" "reflect" "strings" - "sync" "testing" "time" @@ -16,7 +14,7 @@ import ( "github.com/hashicorp/vault-plugin-database-mongodbatlas" "github.com/hashicorp/vault/api" "github.com/hashicorp/vault/helper/namespace" - "github.com/hashicorp/vault/helper/testhelpers/docker" + postgreshelper "github.com/hashicorp/vault/helper/testhelpers/postgresql" vaulthttp "github.com/hashicorp/vault/http" "github.com/hashicorp/vault/plugins/database/mongodb" "github.com/hashicorp/vault/plugins/database/postgresql" @@ -29,64 +27,8 @@ import ( "github.com/hashicorp/vault/vault" "github.com/lib/pq" "github.com/mitchellh/mapstructure" - "github.com/ory/dockertest" ) -var ( - testImagePull sync.Once -) - -func preparePostgresTestContainer(t *testing.T, s logical.Storage, b logical.Backend) (cleanup func(), retURL string) { - t.Helper() - if os.Getenv("PG_URL") != "" { - return func() {}, os.Getenv("PG_URL") - } - - pool, err := dockertest.NewPool("") - if err != nil { - t.Fatalf("Failed to connect to docker: %s", err) - } - - resource, err := pool.Run("postgres", "latest", []string{"POSTGRES_PASSWORD=secret", "POSTGRES_DB=database"}) - if err != nil { - t.Fatalf("Could not start local PostgreSQL docker container: %s", err) - } - - cleanup = func() { - docker.CleanupResource(t, pool, resource) - } - - retURL = fmt.Sprintf("postgres://postgres:secret@localhost:%s/database?sslmode=disable", resource.GetPort("5432/tcp")) - - // Exponential backoff-retry - if err = pool.Retry(func() error { - // This will cause a validation to run - resp, err := b.HandleRequest(namespace.RootContext(nil), &logical.Request{ - Storage: s, - Operation: logical.UpdateOperation, - Path: "config/postgresql", - Data: map[string]interface{}{ - "plugin_name": "postgresql-database-plugin", - "connection_url": retURL, - }, - }) - if err != nil || (resp != nil && resp.IsError()) { - // It's likely not up and running yet, so return error and try again - return fmt.Errorf("err:%#v resp:%+v", err, resp) - } - if resp == nil { - t.Fatal("expected warning") - } - - return nil - }); err != nil { - cleanup() - t.Fatalf("Could not connect to PostgreSQL docker container: %s", err) - } - - return -} - func getCluster(t *testing.T) (*vault.TestCluster, logical.SystemView) { coreConfig := &vault.CoreConfig{ LogicalBackends: map[string]logical.Factory{ @@ -425,7 +367,7 @@ func TestBackend_BadConnectionString(t *testing.T) { } defer b.Cleanup(context.Background()) - cleanup, _ := preparePostgresTestContainer(t, config.StorageView, b) + cleanup, _ := postgreshelper.PrepareTestContainer(t, "latest") defer cleanup() respCheck := func(req *logical.Request) { @@ -474,7 +416,7 @@ func TestBackend_basic(t *testing.T) { } defer b.Cleanup(context.Background()) - cleanup, connURL := preparePostgresTestContainer(t, config.StorageView, b) + cleanup, connURL := postgreshelper.PrepareTestContainer(t, "latest") defer cleanup() // Configure a connection @@ -681,7 +623,7 @@ func TestBackend_connectionCrud(t *testing.T) { } defer b.Cleanup(context.Background()) - cleanup, connURL := preparePostgresTestContainer(t, config.StorageView, b) + cleanup, connURL := postgreshelper.PrepareTestContainer(t, "latest") defer cleanup() // Configure a connection @@ -859,7 +801,7 @@ func TestBackend_roleCrud(t *testing.T) { } defer b.Cleanup(context.Background()) - cleanup, connURL := preparePostgresTestContainer(t, config.StorageView, b) + cleanup, connURL := postgreshelper.PrepareTestContainer(t, "latest") defer cleanup() // Configure a connection @@ -1107,7 +1049,7 @@ func TestBackend_allowedRoles(t *testing.T) { } defer b.Cleanup(context.Background()) - cleanup, connURL := preparePostgresTestContainer(t, config.StorageView, b) + cleanup, connURL := postgreshelper.PrepareTestContainer(t, "latest") defer cleanup() // Configure a connection @@ -1304,7 +1246,7 @@ func TestBackend_RotateRootCredentials(t *testing.T) { } defer b.Cleanup(context.Background()) - cleanup, connURL := preparePostgresTestContainer(t, config.StorageView, b) + cleanup, connURL := postgreshelper.PrepareTestContainer(t, "latest") defer cleanup() connURL = strings.Replace(connURL, "postgres:secret", "{{username}}:{{password}}", -1) diff --git a/builtin/logical/database/path_roles_test.go b/builtin/logical/database/path_roles_test.go index 0e9bf4f003..f4b6d56b6b 100644 --- a/builtin/logical/database/path_roles_test.go +++ b/builtin/logical/database/path_roles_test.go @@ -8,6 +8,7 @@ import ( "github.com/go-test/deep" "github.com/hashicorp/vault/helper/namespace" + postgreshelper "github.com/hashicorp/vault/helper/testhelpers/postgresql" "github.com/hashicorp/vault/sdk/logical" ) @@ -31,7 +32,7 @@ func TestBackend_StaticRole_Config(t *testing.T) { } defer b.Cleanup(context.Background()) - cleanup, connURL := preparePostgresTestContainer(t, config.StorageView, b) + cleanup, connURL := postgreshelper.PrepareTestContainer(t, "") defer cleanup() // create the database user @@ -201,7 +202,7 @@ func TestBackend_StaticRole_Updates(t *testing.T) { } defer b.Cleanup(context.Background()) - cleanup, connURL := preparePostgresTestContainer(t, config.StorageView, b) + cleanup, connURL := postgreshelper.PrepareTestContainer(t, "") defer cleanup() // create the database user @@ -394,7 +395,7 @@ func TestBackend_StaticRole_Role_name_check(t *testing.T) { } defer b.Cleanup(context.Background()) - cleanup, connURL := preparePostgresTestContainer(t, config.StorageView, b) + cleanup, connURL := postgreshelper.PrepareTestContainer(t, "") defer cleanup() // create the database user diff --git a/builtin/logical/database/rollback_test.go b/builtin/logical/database/rollback_test.go index 36ce2ea596..ec2bbc82c8 100644 --- a/builtin/logical/database/rollback_test.go +++ b/builtin/logical/database/rollback_test.go @@ -6,6 +6,7 @@ import ( "testing" "github.com/hashicorp/vault/helper/namespace" + postgreshelper "github.com/hashicorp/vault/helper/testhelpers/postgresql" "github.com/hashicorp/vault/sdk/database/dbplugin" "github.com/hashicorp/vault/sdk/framework" "github.com/hashicorp/vault/sdk/logical" @@ -39,7 +40,7 @@ func TestBackend_RotateRootCredentials_WAL_rollback(t *testing.T) { } defer lb.Cleanup(context.Background()) - cleanup, connURL := preparePostgresTestContainer(t, config.StorageView, lb) + cleanup, connURL := postgreshelper.PrepareTestContainer(t, "") defer cleanup() connURL = strings.Replace(connURL, "postgres:secret", "{{username}}:{{password}}", -1) @@ -174,7 +175,7 @@ func TestBackend_RotateRootCredentials_WAL_no_rollback_1(t *testing.T) { } defer lb.Cleanup(context.Background()) - cleanup, connURL := preparePostgresTestContainer(t, config.StorageView, lb) + cleanup, connURL := postgreshelper.PrepareTestContainer(t, "") defer cleanup() connURL = strings.Replace(connURL, "postgres:secret", "{{username}}:{{password}}", -1) @@ -282,7 +283,7 @@ func TestBackend_RotateRootCredentials_WAL_no_rollback_2(t *testing.T) { } defer lb.Cleanup(context.Background()) - cleanup, connURL := preparePostgresTestContainer(t, config.StorageView, lb) + cleanup, connURL := postgreshelper.PrepareTestContainer(t, "") defer cleanup() connURL = strings.Replace(connURL, "postgres:secret", "{{username}}:{{password}}", -1) diff --git a/builtin/logical/mysql/backend_test.go b/builtin/logical/mysql/backend_test.go index b77c06b9ab..be99e73c7d 100644 --- a/builtin/logical/mysql/backend_test.go +++ b/builtin/logical/mysql/backend_test.go @@ -2,59 +2,17 @@ package mysql import ( "context" - "database/sql" "fmt" "log" - "os" "reflect" "testing" - "github.com/hashicorp/vault/helper/testhelpers/docker" logicaltest "github.com/hashicorp/vault/helper/testhelpers/logical" + mysqlhelper "github.com/hashicorp/vault/helper/testhelpers/mysql" "github.com/hashicorp/vault/sdk/logical" "github.com/mitchellh/mapstructure" - "github.com/ory/dockertest" ) -func prepareTestContainer(t *testing.T) (func(), string) { - if os.Getenv("MYSQL_URL") != "" { - return func() {}, os.Getenv("MYSQL_URL") - } - - pool, err := dockertest.NewPool("") - if err != nil { - t.Fatalf("Failed to connect to docker: %s", err) - } - - resource, err := pool.Run("mysql", "5.7", []string{"MYSQL_ROOT_PASSWORD=secret"}) - if err != nil { - t.Fatalf("Could not start local MySQL docker container: %s", err) - } - - cleanup := func() { - docker.CleanupResource(t, pool, resource) - } - - retURL := fmt.Sprintf("root:secret@(localhost:%s)/mysql?parseTime=true", resource.GetPort("3306/tcp")) - - // exponential backoff-retry - if err = pool.Retry(func() error { - var err error - var db *sql.DB - db, err = sql.Open("mysql", retURL) - if err != nil { - return err - } - defer db.Close() - return db.Ping() - }); err != nil { - cleanup() - t.Fatalf("Could not connect to MySQL docker container: %s", err) - } - - return cleanup, retURL -} - func TestBackend_config_connection(t *testing.T) { var resp *logical.Response var err error @@ -104,7 +62,7 @@ func TestBackend_basic(t *testing.T) { t.Fatal(err) } - cleanup, connURL := prepareTestContainer(t) + cleanup, connURL := mysqlhelper.PrepareTestContainer(t, false, "secret") defer cleanup() connData := map[string]interface{}{ @@ -130,7 +88,7 @@ func TestBackend_basicHostRevoke(t *testing.T) { t.Fatal(err) } - cleanup, connURL := prepareTestContainer(t) + cleanup, connURL := mysqlhelper.PrepareTestContainer(t, false, "secret") defer cleanup() connData := map[string]interface{}{ @@ -156,7 +114,7 @@ func TestBackend_roleCrud(t *testing.T) { t.Fatal(err) } - cleanup, connURL := prepareTestContainer(t) + cleanup, connURL := mysqlhelper.PrepareTestContainer(t, false, "secret") defer cleanup() connData := map[string]interface{}{ @@ -187,7 +145,7 @@ func TestBackend_leaseWriteRead(t *testing.T) { t.Fatal(err) } - cleanup, connURL := prepareTestContainer(t) + cleanup, connURL := mysqlhelper.PrepareTestContainer(t, false, "secret") defer cleanup() connData := map[string]interface{}{ diff --git a/builtin/logical/nomad/backend_test.go b/builtin/logical/nomad/backend_test.go index 8d0ecc91bc..170531518a 100644 --- a/builtin/logical/nomad/backend_test.go +++ b/builtin/logical/nomad/backend_test.go @@ -13,52 +13,53 @@ import ( "github.com/hashicorp/vault/helper/testhelpers/docker" "github.com/hashicorp/vault/sdk/logical" "github.com/mitchellh/mapstructure" - "github.com/ory/dockertest" ) -func prepareTestContainer(t *testing.T) (cleanup func(), retAddress string, nomadToken string) { - nomadToken = os.Getenv("NOMAD_TOKEN") +type Config struct { + docker.ServiceURL + Token string +} - retAddress = os.Getenv("NOMAD_ADDR") +func (c *Config) APIConfig() *nomadapi.Config { + apiConfig := nomadapi.DefaultConfig() + apiConfig.Address = c.URL().String() + apiConfig.SecretID = c.Token + return apiConfig +} - if retAddress != "" { - return func() {}, retAddress, nomadToken +func prepareTestContainer(t *testing.T) (func(), *Config) { + if retAddress := os.Getenv("NOMAD_ADDR"); retAddress != "" { + s, err := docker.NewServiceURLParse(retAddress) + if err != nil { + t.Fatal(err) + } + return func() {}, &Config{*s, os.Getenv("NOMAD_TOKEN")} } - pool, err := dockertest.NewPool("") + runner, err := docker.NewServiceRunner(docker.RunOptions{ + ImageRepo: "catsby/nomad", + ImageTag: "0.8.4", + ContainerName: "nomad", + Ports: []string{"4646/tcp"}, + Cmd: []string{"agent", "-dev"}, + Env: []string{`NOMAD_LOCAL_CONFIG=bind_addr = "0.0.0.0" acl { enabled = true }`}, + }) if err != nil { - t.Fatalf("Failed to connect to docker: %s", err) + t.Fatalf("Could not start docker Nomad: %s", err) } - dockerOptions := &dockertest.RunOptions{ - Repository: "catsby/nomad", - Tag: "0.8.4", - Cmd: []string{"agent", "-dev"}, - Env: []string{`NOMAD_LOCAL_CONFIG=bind_addr = "0.0.0.0" acl { enabled = true }`}, - } - resource, err := pool.RunWithOptions(dockerOptions) - if err != nil { - t.Fatalf("Could not start local Nomad docker container: %s", err) - } - - cleanup = func() { - docker.CleanupResource(t, pool, resource) - } - - retAddress = fmt.Sprintf("http://localhost:%s/", resource.GetPort("4646/tcp")) - - // exponential backoff-retry - if err = pool.Retry(func() error { + var nomadToken string + svc, err := runner.StartService(context.Background(), func(ctx context.Context, host string, port int) (docker.ServiceConfig, error) { var err error nomadapiConfig := nomadapi.DefaultConfig() - nomadapiConfig.Address = retAddress + nomadapiConfig.Address = fmt.Sprintf("http://%s:%d/", host, port) nomad, err := nomadapi.NewClient(nomadapiConfig) if err != nil { - return err + return nil, err } aclbootstrap, _, err := nomad.ACLTokens().Bootstrap(nil) if err != nil { - return err + return nil, err } nomadToken = aclbootstrap.SecretID t.Logf("[WARN] Generated Master token: %s", nomadToken) @@ -85,23 +86,29 @@ func prepareTestContainer(t *testing.T) (cleanup func(), retAddress string, noma `, } nomadAuthConfig := nomadapi.DefaultConfig() - nomadAuthConfig.Address = retAddress + nomadAuthConfig.Address = nomad.Address() nomadAuthConfig.SecretID = nomadToken nomadAuth, err := nomadapi.NewClient(nomadAuthConfig) _, err = nomadAuth.ACLPolicies().Upsert(policy, nil) if err != nil { - return err + return nil, err } _, err = nomadAuth.ACLPolicies().Upsert(anonPolicy, nil) if err != nil { - return err + return nil, err } - return nil - }); err != nil { - cleanup() - t.Fatalf("Could not connect to docker: %s", err) + u, _ := docker.NewServiceURLParse(nomadapiConfig.Address) + return &Config{ + ServiceURL: *u, + Token: nomadToken, + }, nil + }) + + if err != nil { + t.Fatalf("Could not start docker Nomad: %s", err) } - return cleanup, retAddress, nomadToken + + return svc.Cleanup, svc.Config.(*Config) } func TestBackend_config_access(t *testing.T) { @@ -112,12 +119,12 @@ func TestBackend_config_access(t *testing.T) { t.Fatal(err) } - cleanup, connURL, connToken := prepareTestContainer(t) + cleanup, svccfg := prepareTestContainer(t) defer cleanup() connData := map[string]interface{}{ - "address": connURL, - "token": connToken, + "address": svccfg.URL().String(), + "token": svccfg.Token, } confReq := &logical.Request{ @@ -158,11 +165,12 @@ func TestBackend_renew_revoke(t *testing.T) { t.Fatal(err) } - cleanup, connURL, connToken := prepareTestContainer(t) + cleanup, svccfg := prepareTestContainer(t) defer cleanup() + connData := map[string]interface{}{ - "address": connURL, - "token": connToken, + "address": svccfg.URL().String(), + "token": svccfg.Token, } req := &logical.Request{ @@ -267,7 +275,7 @@ func TestBackend_CredsCreateEnvVar(t *testing.T) { t.Fatal(err) } - cleanup, connURL, connToken := prepareTestContainer(t) + cleanup, svccfg := prepareTestContainer(t) defer cleanup() req := logical.TestRequest(t, logical.UpdateOperation, "role/test") @@ -280,9 +288,9 @@ func TestBackend_CredsCreateEnvVar(t *testing.T) { t.Fatal(err) } - os.Setenv("NOMAD_TOKEN", connToken) + os.Setenv("NOMAD_TOKEN", svccfg.Token) defer os.Unsetenv("NOMAD_TOKEN") - os.Setenv("NOMAD_ADDR", connURL) + os.Setenv("NOMAD_ADDR", svccfg.URL().String()) defer os.Unsetenv("NOMAD_ADDR") req.Operation = logical.ReadOperation @@ -307,7 +315,7 @@ func TestBackend_max_token_name_length(t *testing.T) { t.Fatal(err) } - cleanup, connURL, connToken := prepareTestContainer(t) + cleanup, svccfg := prepareTestContainer(t) defer cleanup() testCases := []struct { @@ -337,12 +345,12 @@ func TestBackend_max_token_name_length(t *testing.T) { t.Run(tc.title, func(t *testing.T) { // setup config/access connData := map[string]interface{}{ - "address": connURL, - "token": connToken, + "address": svccfg.URL().String(), + "token": svccfg.Token, "max_token_name_length": tc.tokenLength, } expected := map[string]interface{}{ - "address": connURL, + "address": svccfg.URL().String(), "max_token_name_length": tc.tokenLength, } diff --git a/builtin/logical/pki/backend_test.go b/builtin/logical/pki/backend_test.go index 0964290673..749a6850e2 100644 --- a/builtin/logical/pki/backend_test.go +++ b/builtin/logical/pki/backend_test.go @@ -2797,8 +2797,8 @@ func TestBackend_AllowedDomainsTemplate(t *testing.T) { // Write role PKI. _, err = client.Logical().Write("pki/roles/test", map[string]interface{}{ - "allowed_domains": []string{"foobar.com", "zipzap.com", "{{identity.entity.aliases." + userpassAccessor + ".name}}", - "foo.{{identity.entity.aliases." + userpassAccessor + ".name}}.example.com"}, + "allowed_domains": []string{"foobar.com", "zipzap.com", "{{identity.entity.aliases." + userpassAccessor + ".name}}", + "foo.{{identity.entity.aliases." + userpassAccessor + ".name}}.example.com"}, "allowed_domains_template": true, "allow_bare_domains": true, }) diff --git a/builtin/logical/rabbitmq/backend_test.go b/builtin/logical/rabbitmq/backend_test.go index d942c05b8f..35da7d7d59 100644 --- a/builtin/logical/rabbitmq/backend_test.go +++ b/builtin/logical/rabbitmq/backend_test.go @@ -5,17 +5,15 @@ import ( "fmt" "log" "os" - "strconv" "testing" "github.com/hashicorp/vault/helper/testhelpers/docker" + logicaltest "github.com/hashicorp/vault/helper/testhelpers/logical" "github.com/hashicorp/vault/sdk/helper/base62" "github.com/hashicorp/vault/sdk/helper/jsonutil" "github.com/hashicorp/vault/sdk/logical" - logicaltest "github.com/hashicorp/vault/helper/testhelpers/logical" rabbithole "github.com/michaelklishin/rabbit-hole" "github.com/mitchellh/mapstructure" - "github.com/ory/dockertest" ) const ( @@ -32,60 +30,45 @@ const ( roleName = "web" ) -func prepareRabbitMQTestContainer(t *testing.T) (func(), string, int) { +func prepareRabbitMQTestContainer(t *testing.T) (func(), string) { if os.Getenv(envRabbitMQConnectionURI) != "" { - return func() {}, os.Getenv(envRabbitMQConnectionURI), 0 + return func() {}, os.Getenv(envRabbitMQConnectionURI) } - pool, err := dockertest.NewPool("") + runner, err := docker.NewServiceRunner(docker.RunOptions{ + ImageRepo: "rabbitmq", + ImageTag: "3-management", + ContainerName: "rabbitmq", + Ports: []string{"15672/tcp"}, + }) if err != nil { - t.Fatalf("Failed to connect to docker: %s", err) + t.Fatalf("could not start docker rabbitmq: %s", err) } - runOpts := &dockertest.RunOptions{ - Repository: "rabbitmq", - Tag: "3-management", - } - resource, err := pool.RunWithOptions(runOpts) - if err != nil { - t.Fatalf("Could not start local rabbitmq docker container: %s", err) - } - - cleanup := func() { - docker.CleanupResource(t, pool, resource) - } - - port, _ := strconv.Atoi(resource.GetPort("15672/tcp")) - address := fmt.Sprintf("http://127.0.0.1:%d", port) - - // exponential backoff-retry - if err = pool.Retry(func() error { - rmqc, err := rabbithole.NewClient(address, "guest", "guest") + svc, err := runner.StartService(context.Background(), func(ctx context.Context, host string, port int) (docker.ServiceConfig, error) { + connURL := fmt.Sprintf("http://%s:%d", host, port) + rmqc, err := rabbithole.NewClient(connURL, "guest", "guest") if err != nil { - return err + return nil, err } _, err = rmqc.Overview() if err != nil { - return err + return nil, err } - return nil - }); err != nil { - cleanup() - t.Fatalf("Could not connect to rabbitmq docker container: %s", err) + return docker.NewServiceURLParse(connURL) + }) + if err != nil { + t.Fatalf("could not start docker rabbitmq: %s", err) } - return cleanup, address, port + return svc.Cleanup, svc.Config.URL().String() } func TestBackend_basic(t *testing.T) { - if os.Getenv(logicaltest.TestEnvVar) == "" { - t.Skip(fmt.Sprintf("Acceptance tests skipped unless env '%s' set", logicaltest.TestEnvVar)) - return - } b, _ := Factory(context.Background(), logical.TestBackendConfig()) - cleanup, uri, _ := prepareRabbitMQTestContainer(t) + cleanup, uri := prepareRabbitMQTestContainer(t) defer cleanup() logicaltest.Test(t, logicaltest.TestCase{ @@ -101,13 +84,9 @@ func TestBackend_basic(t *testing.T) { } func TestBackend_returnsErrs(t *testing.T) { - if os.Getenv(logicaltest.TestEnvVar) == "" { - t.Skip(fmt.Sprintf("Acceptance tests skipped unless env '%s' set", logicaltest.TestEnvVar)) - return - } b, _ := Factory(context.Background(), logical.TestBackendConfig()) - cleanup, uri, _ := prepareRabbitMQTestContainer(t) + cleanup, uri := prepareRabbitMQTestContainer(t) defer cleanup() logicaltest.Test(t, logicaltest.TestCase{ @@ -134,13 +113,9 @@ func TestBackend_returnsErrs(t *testing.T) { } func TestBackend_roleCrud(t *testing.T) { - if os.Getenv(logicaltest.TestEnvVar) == "" { - t.Skip(fmt.Sprintf("Acceptance tests skipped unless env '%s' set", logicaltest.TestEnvVar)) - return - } b, _ := Factory(context.Background(), logical.TestBackendConfig()) - cleanup, uri, _ := prepareRabbitMQTestContainer(t) + cleanup, uri := prepareRabbitMQTestContainer(t) defer cleanup() logicaltest.Test(t, logicaltest.TestCase{ @@ -169,7 +144,7 @@ func TestBackend_roleWithPasswordPolicy(t *testing.T) { backendConfig.System.(*logical.StaticSystemView).SetPasswordPolicy("testpolicy", passGen) b, _ := Factory(context.Background(), backendConfig) - cleanup, uri, _ := prepareRabbitMQTestContainer(t) + cleanup, uri := prepareRabbitMQTestContainer(t) defer cleanup() logicaltest.Test(t, logicaltest.TestCase{ diff --git a/builtin/logical/ssh/backend_test.go b/builtin/logical/ssh/backend_test.go index 430c0827e6..36b0123f3a 100644 --- a/builtin/logical/ssh/backend_test.go +++ b/builtin/logical/ssh/backend_test.go @@ -4,6 +4,8 @@ import ( "bytes" "context" "fmt" + "github.com/hashicorp/vault/api" + "github.com/hashicorp/vault/sdk/logical" "net" "reflect" "strconv" @@ -17,13 +19,10 @@ import ( "errors" "strings" - "github.com/hashicorp/vault/api" "github.com/hashicorp/vault/helper/testhelpers/docker" logicaltest "github.com/hashicorp/vault/helper/testhelpers/logical" - "github.com/hashicorp/vault/sdk/logical" "github.com/hashicorp/vault/vault" "github.com/mitchellh/mapstructure" - "github.com/ory/dockertest" ) const ( @@ -126,44 +125,39 @@ SjOQL/GkH1nkRcDS9++aAAAAAmNhAQID ) func prepareTestContainer(t *testing.T, tag, caPublicKeyPEM string) (func(), string) { - pool, err := dockertest.NewPool("") - if err != nil { - t.Fatalf("Failed to connect to docker: %s", err) - } - - signer, err := ssh.ParsePrivateKey([]byte(testSharedPrivateKey)) - if err != nil { - t.Fatal(err) - } - if tag == "" { tag = dockerImageTagSupportsNoRSA1 } - resource, err := pool.RunWithOptions(&dockertest.RunOptions{ - Repository: "linuxserver/openssh-server", - Tag: tag, + runner, err := docker.NewServiceRunner(docker.RunOptions{ + ContainerName: "openssh", + ImageRepo: "linuxserver/openssh-server", + ImageTag: tag, Env: []string{ "DOCKER_MODS=linuxserver/mods:openssh-server-openssh-client", "PUBLIC_KEY=" + testPublicKeyInstall, "SUDO_ACCESS=true", "USER_NAME=vaultssh", }, - ExposedPorts: []string{"2222/tcp"}, + Ports: []string{"2222/tcp"}, }) if err != nil { t.Fatalf("Could not start local ssh docker container: %s", err) } - cleanup := func() { - docker.CleanupResource(t, pool, resource) - } + svc, err := runner.StartService(context.Background(), func(ctx context.Context, host string, port int) (docker.ServiceConfig, error) { + ipaddr, err := net.ResolveIPAddr("ip", host) + if err != nil { + return nil, err + } + sshAddress := fmt.Sprintf("%s:%d", ipaddr.String(), port) - sshAddress := fmt.Sprintf("127.0.0.1:%s", resource.GetPort("2222/tcp")) + signer, err := ssh.ParsePrivateKey([]byte(testSharedPrivateKey)) + if err != nil { + return nil, err + } - // exponential backoff-retry - if err = pool.Retry(func() error { // Install util-linux for non-busybox flock that supports timeout option - return testSSH(t, "vaultssh", sshAddress, ssh.PublicKeys(signer), fmt.Sprintf(` + err = testSSH("vaultssh", sshAddress, ssh.PublicKeys(signer), fmt.Sprintf(` set -e; sudo ln -s /config /home/vaultssh sudo apk add util-linux; @@ -172,15 +166,19 @@ func prepareTestContainer(t *testing.T, tag, caPublicKeyPEM string) (func(), str kill -HUP $(cat /config/sshd.pid) echo "%s" | sudo tee /config/ssh_host_keys/trusted-user-ca-keys.pem `, caPublicKeyPEM)) - }); err != nil { - cleanup() - t.Fatalf("Could not connect to SSH docker container: %s", err) - } + if err != nil { + return nil, err + } - return cleanup, sshAddress + return docker.NewServiceHostPort(ipaddr.String(), port), nil + }) + if err != nil { + t.Fatalf("Could not start docker ssh server: %s", err) + } + return svc.Cleanup, svc.Config.Address() } -func testSSH(t *testing.T, user, host string, auth ssh.AuthMethod, command string) error { +func testSSH(user, host string, auth ssh.AuthMethod, command string) error { client, err := ssh.Dial("tcp", host, &ssh.ClientConfig{ User: user, Auth: []ssh.AuthMethod{auth}, @@ -199,7 +197,7 @@ func testSSH(t *testing.T, user, host string, auth ssh.AuthMethod, command strin defer session.Close() err = session.Run(command) if err != nil { - t.Logf("command %v failed, error: %v, stderr: %v", command, err, stderr.String()) + return fmt.Errorf("command %v failed, error: %v, stderr: %v", command, err, stderr.String()) } return err } @@ -431,7 +429,7 @@ func TestSSHBackend_DynamicKeyCreate(t *testing.T) { "key": testKeyName, "admin_user": testAdminUser, "default_user": testAdminUser, - "cidr_list": testCIDRList, + "cidr_list": host + "/32", "port": port, } data := map[string]interface{}{ @@ -537,7 +535,7 @@ func TestSSHBackend_OTPCreate(t *testing.T) { testOTPRoleData := map[string]interface{}{ "key_type": testOTPKeyType, "default_user": testUserName, - "cidr_list": testCIDRList, + "cidr_list": host + "/32", "port": port, } data := map[string]interface{}{ @@ -854,7 +852,7 @@ cKumubUxOfFdy1ZvAAAAEm5jY0BtYnAudWJudC5sb2NhbA== return err } - err = testSSH(t, testUserName, sshAddress, ssh.PublicKeys(certSigner), "date") + err = testSSH(testUserName, sshAddress, ssh.PublicKeys(certSigner), "date") if expectError && err == nil { return fmt.Errorf("expected error but got none") } @@ -978,7 +976,7 @@ cKumubUxOfFdy1ZvAAAAEm5jY0BtYnAudWJudC5sb2NhbA== return err } - err = testSSH(t, testUserName, sshAddress, ssh.PublicKeys(certSigner), "date") + err = testSSH(testUserName, sshAddress, ssh.PublicKeys(certSigner), "date") if err != nil { return err } @@ -1645,7 +1643,7 @@ func testCredsWrite(t *testing.T, roleName string, data map[string]interface{}, if err != nil { return fmt.Errorf("generated key is invalid") } - if err := testSSH(t, data["username"].(string), address, ssh.PublicKeys(privKey), "date"); err != nil { + if err := testSSH(data["username"].(string), address, ssh.PublicKeys(privKey), "date"); err != nil { return fmt.Errorf("unable to SSH with new key (%s): %w", d.Key, err) } } else { diff --git a/command/agent/approle_end_to_end_test.go b/command/agent/approle_end_to_end_test.go index 1cf8022923..2049c99c75 100644 --- a/command/agent/approle_end_to_end_test.go +++ b/command/agent/approle_end_to_end_test.go @@ -23,6 +23,7 @@ import ( ) func TestAppRoleEndToEnd(t *testing.T) { + t.Parallel() testCases := []struct { removeSecretIDFile bool @@ -54,6 +55,7 @@ func TestAppRoleEndToEnd(t *testing.T) { secretFileAction = "remove" } t.Run(fmt.Sprintf("%s_secret_id_file bindSecretID=%v secretIDLess=%v expectToken=%v", secretFileAction, tc.bindSecretID, tc.secretIDLess, tc.expectToken), func(t *testing.T) { + t.Parallel() testAppRoleEndToEnd(t, tc.removeSecretIDFile, tc.bindSecretID, tc.secretIDLess, tc.expectToken) }) } diff --git a/command/agent/config/config_test.go b/command/agent/config/config_test.go index a316a73eb9..dda9fc452e 100644 --- a/command/agent/config/config_test.go +++ b/command/agent/config/config_test.go @@ -138,11 +138,11 @@ func TestLoadConfigFile(t *testing.T) { }, }, { - Type: "file", - WrapTTL: 5 * time.Minute, - DHType: "curve25519", - DHPath: "/tmp/file-foo-dhpath2", - AAD: "aad", + Type: "file", + WrapTTL: 5 * time.Minute, + DHType: "curve25519", + DHPath: "/tmp/file-foo-dhpath2", + AAD: "aad", DeriveKey: true, Config: map[string]interface{}{ "path": "/tmp/file-bar", diff --git a/command/agent/jwt_end_to_end_test.go b/command/agent/jwt_end_to_end_test.go index 0cda243725..3b3d92f12e 100644 --- a/command/agent/jwt_end_to_end_test.go +++ b/command/agent/jwt_end_to_end_test.go @@ -154,10 +154,10 @@ func testJWTEndToEnd(t *testing.T, ahWrapping bool) { }() config := &sink.SinkConfig{ - Logger: logger.Named("sink.file"), - AAD: "foobar", - DHType: "curve25519", - DHPath: dhpath, + Logger: logger.Named("sink.file"), + AAD: "foobar", + DHType: "curve25519", + DHPath: dhpath, DeriveKey: true, Config: map[string]interface{}{ "path": out, diff --git a/command/audit_enable_test.go b/command/audit_enable_test.go index c43a812758..cef209f262 100644 --- a/command/audit_enable_test.go +++ b/command/audit_enable_test.go @@ -195,6 +195,11 @@ func TestAuditEnableCommand_Run(t *testing.T) { t.Log("skipping syslog test on WSL") continue } + if os.Getenv("CIRCLECI") == "true" { + // TODO install syslog in docker image we run our tests in + t.Log("skipping syslog test on CircleCI") + continue + } } code := cmd.Run(args) if exp := 0; code != exp { diff --git a/command/server/server_seal_transit_acc_test.go b/command/server/server_seal_transit_acc_test.go index b895edaf6d..e6c56c725a 100644 --- a/command/server/server_seal_transit_acc_test.go +++ b/command/server/server_seal_transit_acc_test.go @@ -3,27 +3,27 @@ package server import ( "context" "fmt" + "net/url" "path" "reflect" - "strings" "testing" "time" "github.com/hashicorp/go-uuid" "github.com/hashicorp/vault/api" + "github.com/hashicorp/vault/helper/testhelpers/docker" "github.com/hashicorp/vault/internalshared/configutil" - "github.com/ory/dockertest" ) func TestTransitWrapper_Lifecycle(t *testing.T) { - cleanup, retAddress, token, mountPath, keyName, _ := prepareTestContainer(t) + cleanup, config := prepareTestContainer(t) defer cleanup() wrapperConfig := map[string]string{ - "address": retAddress, - "token": token, - "mount_path": mountPath, - "key_name": keyName, + "address": config.URL().String(), + "token": config.token, + "mount_path": config.mountPath, + "key_name": config.keyName, } kms, _, err := configutil.GetTransitKMSFunc(nil, &configutil.KMS{Config: wrapperConfig}) @@ -49,21 +49,14 @@ func TestTransitWrapper_Lifecycle(t *testing.T) { } func TestTransitSeal_TokenRenewal(t *testing.T) { - cleanup, retAddress, token, mountPath, keyName, tlsConfig := prepareTestContainer(t) + cleanup, config := prepareTestContainer(t) defer cleanup() - clientConfig := &api.Config{ - Address: retAddress, - } - if err := clientConfig.ConfigureTLS(tlsConfig); err != nil { - t.Fatalf("err: %s", err) - } - - remoteClient, err := api.NewClient(clientConfig) + remoteClient, err := api.NewClient(config.apiConfig()) if err != nil { t.Fatalf("err: %s", err) } - remoteClient.SetToken(token) + remoteClient.SetToken(config.token) req := &api.TokenCreateRequest{ Period: "5s", @@ -74,10 +67,10 @@ func TestTransitSeal_TokenRenewal(t *testing.T) { } wrapperConfig := map[string]string{ - "address": retAddress, + "address": config.URL().String(), "token": rsp.Auth.ClientToken, - "mount_path": mountPath, - "key_name": keyName, + "mount_path": config.mountPath, + "key_name": config.keyName, } kms, _, err := configutil.GetTransitKMSFunc(nil, &configutil.KMS{Config: wrapperConfig}) if err != nil { @@ -103,8 +96,28 @@ func TestTransitSeal_TokenRenewal(t *testing.T) { } } -func prepareTestContainer(t *testing.T) (cleanup func(), retAddress, token, mountPath, keyName string, tlsConfig *api.TLSConfig) { - testToken, err := uuid.GenerateUUID() +type DockerVaultConfig struct { + docker.ServiceURL + token string + mountPath string + keyName string + tlsConfig *api.TLSConfig +} + +func (c *DockerVaultConfig) apiConfig() *api.Config { + vaultConfig := api.DefaultConfig() + vaultConfig.Address = c.URL().String() + if err := vaultConfig.ConfigureTLS(c.tlsConfig); err != nil { + panic("unable to configure TLS") + } + + return vaultConfig +} + +var _ docker.ServiceConfig = &DockerVaultConfig{} + +func prepareTestContainer(t *testing.T) (func(), *DockerVaultConfig) { + rootToken, err := uuid.GenerateUUID() if err != nil { t.Fatalf("err: %s", err) } @@ -117,72 +130,49 @@ func prepareTestContainer(t *testing.T) (cleanup func(), retAddress, token, moun t.Fatalf("err: %s", err) } - pool, err := dockertest.NewPool("") - if err != nil { - t.Fatalf("Failed to connect to docker: %s", err) - } - - dockerOptions := &dockertest.RunOptions{ - Repository: "vault", - Tag: "latest", - Cmd: []string{"server", "-log-level=trace", "-dev", fmt.Sprintf("-dev-root-token-id=%s", testToken), + runner, err := docker.NewServiceRunner(docker.RunOptions{ + ImageRepo: "vault", + ImageTag: "latest", + Cmd: []string{"server", "-log-level=trace", "-dev", fmt.Sprintf("-dev-root-token-id=%s", rootToken), "-dev-listen-address=0.0.0.0:8200"}, - } - resource, err := pool.RunWithOptions(dockerOptions) + Ports: []string{"8200/tcp"}, + }) if err != nil { - t.Fatalf("Could not start local Vault docker container: %s", err) + t.Fatalf("could not start docker vault: %s", err) } - cleanup = func() { - var err error - for i := 0; i < 10; i++ { - err = pool.Purge(resource) - if err == nil { - return - } - time.Sleep(1 * time.Second) + svc, err := runner.StartService(context.Background(), func(ctx context.Context, host string, port int) (docker.ServiceConfig, error) { + c := &DockerVaultConfig{ + ServiceURL: *docker.NewServiceURL(url.URL{Scheme: "http", Host: fmt.Sprintf("%s:%d", host, port)}), + tlsConfig: &api.TLSConfig{ + Insecure: true, + }, + token: rootToken, + mountPath: testMountPath, + keyName: testKeyName, } - - if strings.Contains(err.Error(), "No such container") { - return - } - t.Fatalf("Failed to cleanup local container: %s", err) - } - - retAddress = fmt.Sprintf("http://127.0.0.1:%s", resource.GetPort("8200/tcp")) - tlsConfig = &api.TLSConfig{ - Insecure: true, - } - - // exponential backoff-retry - if err = pool.Retry(func() error { - vaultConfig := api.DefaultConfig() - vaultConfig.Address = retAddress - if err := vaultConfig.ConfigureTLS(tlsConfig); err != nil { - return err - } - vault, err := api.NewClient(vaultConfig) + vault, err := api.NewClient(c.apiConfig()) if err != nil { - return err + return nil, err } - vault.SetToken(testToken) + vault.SetToken(rootToken) // Set up transit if err := vault.Sys().Mount(testMountPath, &api.MountInput{ Type: "transit", }); err != nil { - return err + return nil, err } // Create default aesgcm key if _, err := vault.Logical().Write(path.Join(testMountPath, "keys", testKeyName), map[string]interface{}{}); err != nil { - return err + return nil, err } - return nil - }); err != nil { - cleanup() - t.Fatalf("Could not connect to vault: %s", err) + return c, nil + }) + if err != nil { + t.Fatalf("could not start docker vault: %s", err) } - return cleanup, retAddress, testToken, testMountPath, testKeyName, tlsConfig + return svc.Cleanup, svc.Config.(*DockerVaultConfig) } diff --git a/go.mod b/go.mod index 2f9db84c9d..741443cd40 100644 --- a/go.mod +++ b/go.mod @@ -26,12 +26,17 @@ require ( github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf github.com/aws/aws-sdk-go v1.30.27 github.com/bitly/go-hostpool v0.1.0 // indirect + github.com/cenkalti/backoff/v3 v3.0.0 github.com/chrismalek/oktasdk-go v0.0.0-20181212195951-3430665dfaa0 github.com/client9/misspell v0.3.4 github.com/cockroachdb/cockroach-go v0.0.0-20181001143604-e0a95dfd547c + github.com/containerd/containerd v1.3.4 // indirect github.com/coreos/go-semver v0.2.0 github.com/denisenkom/go-mssqldb v0.0.0-20200428022330-06a60b6afbbc github.com/dnaeon/go-vcr v1.0.1 // indirect + github.com/docker/distribution v2.7.1+incompatible // indirect + github.com/docker/docker v17.12.0-ce-rc1.0.20200309214505-aa6a9891b09c+incompatible + github.com/docker/go-connections v0.4.0 github.com/dsnet/compress v0.0.1 // indirect github.com/duosecurity/duo_api_golang v0.0.0-20190308151101-6c680f768e74 github.com/elazarl/go-bindata-assetfs v1.0.1-0.20200509193318-234c15e7648f @@ -120,6 +125,7 @@ require ( github.com/okta/okta-sdk-golang/v2 v2.0.0 github.com/oracle/oci-go-sdk v12.5.0+incompatible github.com/ory/dockertest v3.3.5+incompatible + github.com/ory/dockertest/v3 v3.6.0 // indirect github.com/patrickmn/go-cache v2.1.0+incompatible github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 // indirect github.com/pkg/errors v0.9.1 diff --git a/go.sum b/go.sum index 1c5996d0cf..f2e25dee2c 100644 --- a/go.sum +++ b/go.sum @@ -17,15 +17,12 @@ cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbf cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= -cloud.google.com/go/bigquery v1.6.0 h1:ajp/DjpiCHO71SyIhwb83YsUGAyWuzVvMko+9xCsJLw= cloud.google.com/go/bigquery v1.6.0/go.mod h1:hyFDG0qSGdHNz8Q6nDN8rYIkld0q/+5uBZaelxiDLfE= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= -cloud.google.com/go/datastore v1.1.0 h1:/May9ojXjRkPBNVrq+oWLqmWCkr4OU5uRY29bu0mRyQ= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= -cloud.google.com/go/pubsub v1.3.1 h1:ukjixP1wl0LpnZ6LWtZJ0mX5tBmjp1f8Sqer8Z2OMUU= cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= cloud.google.com/go/spanner v1.5.1 h1:dWyj10TLlaxH2No6+tXsSCaq9oWgrRbXy1N3x/bhMGU= cloud.google.com/go/spanner v1.5.1/go.mod h1:e1+8M6PF3ntV9Xr57X2Gf+UhylXXYF6gI4WRZ1kfu2A= @@ -64,7 +61,6 @@ github.com/Azure/go-autorest/autorest/date v0.2.0 h1:yW+Zlqf26583pE43KhfnhFcdmSW github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g= github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= -github.com/Azure/go-autorest/autorest/mocks v0.3.0 h1:qJumjCaCudz+OcqE9/XtEPfvtOjOmKaui4EOpFI6zZc= github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM= github.com/Azure/go-autorest/autorest/to v0.3.0 h1:zebkZaadz7+wIQYgC7GXaz3Wb28yKYfVkkBKwc38VF8= github.com/Azure/go-autorest/autorest/to v0.3.0/go.mod h1:MgwOyqaIuKdG4TL/2ywSsIWKAfJfgHDo8ObuUk3t5sA= @@ -86,7 +82,6 @@ github.com/Jeffail/gabs v1.1.1 h1:V0uzR08Hj22EX8+8QMhyI9sX2hwRu+/RJhJUmnwda/E= github.com/Jeffail/gabs v1.1.1/go.mod h1:6xMvQMK4k33lb7GUUpaAPh6nKMmemQeg5d4gn7/bOXc= github.com/Masterminds/semver v1.4.2 h1:WBLTQ37jOCzSLtXNdoo8bNM8876KhNqOKvrlGITgsTc= github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= -github.com/Microsoft/go-winio v0.4.13 h1:Hmi80lzZuI/CaYmlJp/b+FjZdRZhKu9c2mDVqKlLWVs= github.com/Microsoft/go-winio v0.4.13/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5 h1:ygIc8M6trr62pF5DucadTWGdEB4mEyvzi0e2nbcmcyA= @@ -106,7 +101,6 @@ github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWX github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d h1:G0m3OIz70MZUWq3EgK3CesDbo8upS2Vm9/P3FtgI+Jk= github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= -github.com/abdullin/seq v0.0.0-20160510034733-d5467c17e7af h1:DBNMBMuMiWYu0b+8KMJuWmfCkcxl09JwdlqwDZZ6U14= github.com/abdullin/seq v0.0.0-20160510034733-d5467c17e7af/go.mod h1:5Jv4cbFiHJMsVxt52+i0Ha45fjshj6wxYr1r19tB9bw= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= @@ -138,7 +132,6 @@ github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf h1:eg0MeVzs github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/aws/aws-sdk-go v1.30.27 h1:9gPjZWVDSoQrBO2AvqrWObS6KAZByfEJxQoCYo4ZfK0= github.com/aws/aws-sdk-go v1.30.27/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= -github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f h1:ZNv7On9kyUzm7fvRZumSyy/IUiSC7AzL0I1jKKtwooA= github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f/go.mod h1:AuiFmCCPBSrqvVMvuqFuk0qogytodnVFVSN5CeJB8Gc= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= @@ -147,9 +140,7 @@ github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6r github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCSz6Q9T7+igc/hlvDOUdtWKryOrtFyIVABv/p7k= -github.com/bitly/go-hostpool v0.1.0 h1:XKmsF6k5el6xHG3WPJ8U0Ku/ye7njX7W81Ng7O2ioR0= github.com/bitly/go-hostpool v0.1.0/go.mod h1:4gOCgp6+NZnVqlKyZ/iBZFTAJKembaVENUpMkpg42fw= -github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc h1:biVzkmvwrH8WK8raXaxBx6fRVTlJILwEwQGL1I/ByEI= @@ -158,6 +149,8 @@ github.com/briankassouf/jose v0.9.2-0.20180619214549-d2569464773f h1:ZMEzE7R0WNq github.com/briankassouf/jose v0.9.2-0.20180619214549-d2569464773f/go.mod h1:HQhVmdUf7dBNwIIdBTivnCDxcf6IZY3/zrb+uKSJz6Y= github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= +github.com/cenkalti/backoff/v3 v3.0.0 h1:ske+9nBpD9qZsTBoF41nW5L+AIuFBKMeze18XQ3eG1c= +github.com/cenkalti/backoff/v3 v3.0.0/go.mod h1:cIeZDE3IrqwwJl6VUwCN6trj1oXrTS4rc0ij+ULvLYs= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/centrify/cloud-golang-sdk v0.0.0-20190214225812-119110094d0f h1:gJzxrodnNd/CtPXjO3WYiakyNzHg3rtAi7rO74ejHYU= github.com/centrify/cloud-golang-sdk v0.0.0-20190214225812-119110094d0f/go.mod h1:C0rtzmGXgN78pYR0tGJFhtHgkbAs0lIbHwkB81VxDQE= @@ -179,22 +172,18 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk github.com/cloudfoundry-community/go-cfclient v0.0.0-20190201205600-f136f9222381 h1:rdRS5BT13Iae9ssvcslol66gfOOXjaLYwqerEn/cl9s= github.com/cloudfoundry-community/go-cfclient v0.0.0-20190201205600-f136f9222381/go.mod h1:e5+USP2j8Le2M0Jo3qKPFnNhuo1wueU4nWHCXBOfQ14= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I= github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/cockroachdb/cockroach-go v0.0.0-20181001143604-e0a95dfd547c h1:2zRrJWIt/f9c9HhNHAgrRgq0San5gRRUJTBXLkchal0= github.com/cockroachdb/cockroach-go v0.0.0-20181001143604-e0a95dfd547c/go.mod h1:XGLbWH/ujMcbPbhZq52Nv6UrCghb1yGn//133kEsvDk= -github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa h1:OaNxuTZr7kxeODyLWsRMC+OD03aFUH+mW6r2d+MWa5Y= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= -github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 h1:sDMmm+q/3+BukdIpxwO365v/Rbspp2Nt5XntgQRXq8Q= github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f/go.mod h1:OApqhQ4XNSNC13gXIwDjhOQxjWa/NxkwZXJ1EvqT0ko= github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw= github.com/containerd/containerd v1.3.2/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= github.com/containerd/containerd v1.3.4 h1:3o0smo5SKY7H6AJCmJhsnCjR2/V2T8VmiHt7seN2/kI= github.com/containerd/containerd v1.3.4/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= -github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc h1:TP+534wVlf61smEIq1nwLLAjQVEK2EADoW3CX9AuT+8= github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= -github.com/containerd/continuity v0.0.0-20200709052629-daa8e1ccc0bc h1:lDK/G7OlwUnJW3O6nv/8M89bMupV6FuLK6FXmC3ueWc= +github.com/containerd/continuity v0.0.0-20190827140505-75bee3e2ccb6/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= github.com/containerd/continuity v0.0.0-20200709052629-daa8e1ccc0bc/go.mod h1:cECdGN1O8G9bgKTlLhuPJimka6Xb/Gg7vYzCTNVxhvo= github.com/containerd/continuity v0.0.0-20200710164510-efbc4488d8fe h1:PEmIrUvwG9Yyv+0WKZqjXfSFDeZjs/q15g0m08BYS9k= github.com/containerd/continuity v0.0.0-20200710164510-efbc4488d8fe/go.mod h1:cECdGN1O8G9bgKTlLhuPJimka6Xb/Gg7vYzCTNVxhvo= @@ -211,12 +200,9 @@ github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHo github.com/coreos/go-semver v0.2.0 h1:3Jm3tLmsgAYcjC+4Up7hJrFBPr+n7rAqYeSw/SZazuY= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e h1:Wf6HqHfScWJN9/ZjdUKyjop4mf3Qdd+1TvvltAvM3m8= -github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e h1:Wf6HqHfScWJN9/ZjdUKyjop4mf3Qdd+1TvvltAvM3m8= -github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd/v22 v22.0.0 h1:XJIw/+VlJ+87J+doOxznsAWIdmWuViOVhkQamW5YV28= github.com/coreos/go-systemd/v22 v22.0.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= -github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbpBpLoyyu8B6e44T7hJy6potg= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/couchbase/gocb/v2 v2.1.4 h1:HRuVhqZpVNIck3FwzTxWh5TnmGXeTmSfjhxkjeradLg= github.com/couchbase/gocb/v2 v2.1.4/go.mod h1:lESKM6wCEajrFVSZUewYuRzNtuNtnRey5wOfcZZsH90= @@ -235,12 +221,12 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/dimchansky/utfbom v1.1.0 h1:FcM3g+nofKgUteL8dm/UpdRXNC9KmADgTpLKsu0TRo4= github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8= -github.com/dnaeon/go-vcr v1.0.1 h1:r8L/HqC0Hje5AXMu1ooW8oyQyOFv4GxqpL0nRP7SLLY= github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug= github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v1.4.2-0.20200319182547-c7ad2b866182 h1:Caj/qGJ9KyulC1WSksyPgp7r8+DKgTGfU39lmb2C5MQ= github.com/docker/docker v1.4.2-0.20200319182547-c7ad2b866182/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v17.12.0-ce-rc1.0.20200309214505-aa6a9891b09c+incompatible h1:G2hY8RD7jB9QaSmcb8mYEIg8QbEvVAB7se8+lXHZHfg= +github.com/docker/docker v17.12.0-ce-rc1.0.20200309214505-aa6a9891b09c+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= @@ -253,7 +239,6 @@ github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdf github.com/duosecurity/duo_api_golang v0.0.0-20190308151101-6c680f768e74 h1:2MIhn2R6oXQbgW5yHfS+d6YqyMfXiu2L55rFZC4UD/M= github.com/duosecurity/duo_api_golang v0.0.0-20190308151101-6c680f768e74/go.mod h1:UqXY1lYT/ERa4OEAywUqdok1T4RCRdArkhic1Opuavo= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= @@ -272,11 +257,8 @@ github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/frankban/quicktest v1.4.0/go.mod h1:36zfPVQyHxymz4cH7wlDmVwDrJuljRB60qkgn7rorfQ= -github.com/frankban/quicktest v1.4.1 h1:Wv2VwvNn73pAdFIVUQRXYDFp31lXKbqblIXo/Q5GPSg= github.com/frankban/quicktest v1.4.1/go.mod h1:36zfPVQyHxymz4cH7wlDmVwDrJuljRB60qkgn7rorfQ= -github.com/frankban/quicktest v1.10.0 h1:Gfh+GAJZOAoKZsIZeZbdn2JF10kN1XHNvjsvQK8gVkE= github.com/frankban/quicktest v1.10.0/go.mod h1:ui7WezCLWMWxVWr1GETZY3smRy0G4KWq9vcPtJmFl7Y= -github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa h1:RDBNVkRviHZtvDvId8XSGPu3rmpmSe+wKRcEWNgsfWU= github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa/go.mod h1:KnogPXtdwXqoenmZCw6S+25EAm2MkxbG0deNDu4cbSA= @@ -301,7 +283,6 @@ github.com/go-ldap/ldap/v3 v3.1.10 h1:7WsKqasmPThNvdl0Q5GPpbTDD/ZD98CfuawrMIuh7q github.com/go-ldap/ldap/v3 v3.1.10/go.mod h1:5Zun81jBTabRaI8lzN7E1JjyEl1g6zI6u9pd8luAK4Q= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab h1:xveKWz2iaueeTaUgdetzel+U7exyigDYBryyVfV/rZk= github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= github.com/go-ole/go-ole v1.2.4 h1:nNBDSCOigTSiarFpYE9J/KtEA1IOW4CNeqT9TQDqCxI= github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM= @@ -311,7 +292,6 @@ github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-test/deep v1.0.1/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/go-test/deep v1.0.2-0.20181118220953-042da051cf31/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= -github.com/go-test/deep v1.0.2 h1:onZX1rnHT3Wv6cqNgYyFOOlgVKJrksuCMCRvJStbMYw= github.com/go-test/deep v1.0.2/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68= github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= @@ -323,7 +303,6 @@ github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6 github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= @@ -332,7 +311,6 @@ github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZ github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef h1:veQD95Isof8w9/WXiA+pa3tz3fJXkt5B7QaRBrM62gk= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -340,12 +318,10 @@ github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18h github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.2.0 h1:28o5sBqPkBsMGnC6b4MvE2TzSr5/AT4c/1fLqVGIwlk= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.3 h1:GV+pQPG/EUUbkh47niozDcADz6go/dUwhVzdUQHIVRw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -358,7 +334,6 @@ github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:x github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.1 h1:ZFgWrT+bLgsYPirOnRfKLYJLvssAegOj/hgyMFdJZe0= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= @@ -367,7 +342,6 @@ github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8l github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -385,7 +359,6 @@ github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= @@ -393,7 +366,6 @@ github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/uuid v1.0.0 h1:b4Gk+7WdP/d3HZH8EJsZpvV7EtDOgaZLtnaNGIu1adA= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -402,34 +374,24 @@ github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= github.com/gopherjs/gopherjs v0.0.0-20180628210949-0892b62f0d9f/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorhill/cronexpr v0.0.0-20180427100037-88b0669f7d75 h1:f0n1xnMSmBLzVfsMMvriDyA75NB/oBgILX2GcHXIQzY= github.com/gorhill/cronexpr v0.0.0-20180427100037-88b0669f7d75/go.mod h1:g2644b03hfBX9Ov0ZBDgXXens4rxSxmqFBbhvKv2yVA= -github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= -github.com/gorilla/mux v1.6.2 h1:Pgr17XVTNXAk3q/r4CpKzC5xBM/qW1uVLV+IhRZpIIk= github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/mux v1.7.4 h1:VuZ8uybHlWmqV03+zRzdwKL4tUnIp1MAQtp1mIFE1bc= github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= -github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ= github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= -github.com/gorilla/sessions v1.2.0 h1:S7P+1Hm5V/AT9cjEcUD5uDaQSX0OE577aCXgoaKpYbQ= github.com/gorilla/sessions v1.2.0/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gotestyourself/gotestyourself v2.2.0+incompatible h1:AQwinXlbQR2HvPjQZOmDhRqsv5mZf+Jb1RnSLxcqZcI= github.com/gotestyourself/gotestyourself v2.2.0+incompatible/go.mod h1:zZKM6oeNM8k+FRljX1mnzVYeS8wiGgQyvST1/GafPbY= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4 h1:z53tR0945TRRQO/fLEVPI6SMv7ZflF0TEaTAoU7tOzg= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.6.2/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/grpc-ecosystem/grpc-gateway v1.9.5 h1:UImYN5qQ8tuGpGE16ZmjvcTtTw24zw1QAp/SlnNrZhI= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc1Q53c0bnx2ufif5kANL7bfZWcc6VJWJd8= github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4= @@ -438,7 +400,6 @@ github.com/hashicorp/consul-template v0.25.1/go.mod h1:/vUsrJvDuuQHcxEw0zik+YXTS github.com/hashicorp/consul/api v1.4.0 h1:jfESivXnO5uLdH650JU/6AnjRoHrLhULq0FnC3Kp9EY= github.com/hashicorp/consul/api v1.4.0/go.mod h1:xc8u05kyMa3Wjr9eEAsIAo3dg8+LywT5E/Cl7cNS5nU= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= -github.com/hashicorp/consul/sdk v0.4.0 h1:zBtCfKJZcJDBvSCkQJch4ulp59m1rATFLKwNo/LYY30= github.com/hashicorp/consul/sdk v0.4.0/go.mod h1:fY08Y9z5SvJqevyZNy6WWPXiG3KwBPAvlcdx16zZ0fM= github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -447,7 +408,6 @@ github.com/hashicorp/go-bindata v3.0.8-0.20180209072458-bf7910af8997+incompatibl github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.1 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVoDkXMzJM= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-gatedio v0.5.0 h1:Jm1X5yP4yCqqWj5L1TgW7iZwCVPGtVc+mro5r/XX7Tg= github.com/hashicorp/go-gatedio v0.5.0/go.mod h1:Lr3t8L6IyxD3DAeaUxGcgl2JnRUpWMCsmBl4Omu/2t4= github.com/hashicorp/go-gcp-common v0.5.0/go.mod h1:IDGUI2N/OS3PiU4qZcXJeWKPI6O/9Y8hOrbSiMcqyYw= github.com/hashicorp/go-gcp-common v0.6.0 h1:m1X+DK003bj4WEjqOnv+Csepb3zpfN/bidboUeUSj68= @@ -457,8 +417,6 @@ github.com/hashicorp/go-hclog v0.8.0/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrj github.com/hashicorp/go-hclog v0.9.1/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= -github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= -github.com/hashicorp/go-hclog v0.13.0 h1:Do32YnDMnq7v7FU50AgH+1ExKCOkl9HBxvSI1JWr+rA= github.com/hashicorp/go-hclog v0.13.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-hclog v0.14.1 h1:nQcJDQwIAGnmoUWp8ubocEX40cCml/17YkF6csQLReU= github.com/hashicorp/go-hclog v0.14.1/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= @@ -474,7 +432,6 @@ github.com/hashicorp/go-memdb v1.0.2/go.mod h1:I6dKdmYhZqU0RJSheVEWgTNWdVQH5QvTg github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-msgpack v0.5.5 h1:i9R9JSrqIz0QVLz3sz+i3YJdT7TTSLcfLLzJi9aZTuI= github.com/hashicorp/go-msgpack v0.5.5/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= -github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.1.0 h1:B9UzwGQJehnUY1yNrnwREHc3fGbC2xefo8g4TbElacI= github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= @@ -483,7 +440,6 @@ github.com/hashicorp/go-plugin v1.0.1/go.mod h1:++UyYGoz3o5w9ZzAdZxtQKrWWP+iqPBn github.com/hashicorp/go-raftchunking v0.6.3-0.20191002164813-7e9e8525653a h1:FmnBDwGwlTgugDGbVxwV8UavqSMACbGrUpfc98yFLR4= github.com/hashicorp/go-raftchunking v0.6.3-0.20191002164813-7e9e8525653a/go.mod h1:xbXnmKqX9/+RhPkJ4zrEx4738HacP72aaUPlT2RZ4sU= github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= -github.com/hashicorp/go-retryablehttp v0.6.2 h1:bHM2aVXwBtBJWxHtkSrWuI4umABCUczs52eiUS9nSiw= github.com/hashicorp/go-retryablehttp v0.6.2/go.mod h1:gEx6HMUGxYYhJScX7W1Il64m6cc2C1mDaW3NQ9sY1FY= github.com/hashicorp/go-retryablehttp v0.6.6 h1:HJunrbHTDDbBb/ay4kxa1n+dLmttUlnP3V9oNE4hmsM= github.com/hashicorp/go-retryablehttp v0.6.6/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= @@ -502,7 +458,6 @@ github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/b github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE= github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.0.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/go-version v1.2.0 h1:3vNe/fWF5CBgRIguda1meWhsZHy3m8gCJ5wx+dIzX/E= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.2.1 h1:zEfKbn2+PDgroKdiOzqiE8rsmLqU2uwi5PB5pBJ3TkI= github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= @@ -517,12 +472,10 @@ github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= -github.com/hashicorp/memberlist v0.1.4 h1:gkyML/r71w3FL8gUi74Vk76avkj/9lYAY9lvg0OcoGs= github.com/hashicorp/memberlist v0.1.4/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= github.com/hashicorp/nomad/api v0.0.0-20191220223628-edc62acd919d h1:BXqsASWhyiAiEVm6FcltF0dg8XvoookQwmpHn8lstu8= github.com/hashicorp/nomad/api v0.0.0-20191220223628-edc62acd919d/go.mod h1:WKCL+tLVhN1D+APwH3JiTRZoxcdwRk86bWu1LVCUPaE= github.com/hashicorp/raft v1.0.1/go.mod h1:DVSAWItjLjTOkVbSpWQ0j0kUADIvDaCtBxIcbNAQLkI= -github.com/hashicorp/raft v1.1.2-0.20191002163536-9c6bd3e3eb17 h1:p+2EISNdFCnD9R+B4xCiqSn429MCFtvM41aHJDJ6qW4= github.com/hashicorp/raft v1.1.2-0.20191002163536-9c6bd3e3eb17/go.mod h1:vPAJM8Asw6u8LxC3eJCUZmRP/E4QmUGE1R7g7k8sG/8= github.com/hashicorp/raft v1.1.3-0.20200914140732-b7cd2b346b06 h1:faxx3CU4pvdKtCZXsP62A5X0iV37eqLHgFObVkOplHQ= github.com/hashicorp/raft v1.1.3-0.20200914140732-b7cd2b346b06/go.mod h1:vPAJM8Asw6u8LxC3eJCUZmRP/E4QmUGE1R7g7k8sG/8= @@ -578,7 +531,6 @@ github.com/hashicorp/vault-plugin-secrets-openldap v0.1.5/go.mod h1:NM+5N+URHHg8 github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d h1:kJCB4vdITiW1eC1vq2e6IsrXKrZit1bv/TDYFGMp4BQ= github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= -github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huaweicloud/golangsdk v0.0.0-20200304081349-45ec0797f2a4/go.mod h1:WQBcHRNX9shz3928lWEvstQJtAtYI7ks6XlgtRT9Tcw= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= @@ -586,7 +538,6 @@ github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJ github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/influxdata/influxdb v0.0.0-20190411212539-d24b7ba8c4c4 h1:3K3KcD4S6/Y2hevi70EzUTNKOS3cryQyhUnkjE6Tz0w= github.com/influxdata/influxdb v0.0.0-20190411212539-d24b7ba8c4c4/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY= -github.com/jackc/fake v0.0.0-20150926172116-812a484cc733 h1:vr3AYkKovP8uR8AvSGGUK1IDqRa5lAAvEkZG1LKaCRc= github.com/jackc/fake v0.0.0-20150926172116-812a484cc733/go.mod h1:WrMFNQdiFJ80sQsxDoMokWK1W5TQtxBFNpzWTD84ibQ= github.com/jackc/pgx v3.3.0+incompatible h1:Wa90/+qsITBAPkAZjiByeIGHFcj3Ztu+VzrrIpHjL90= github.com/jackc/pgx v3.3.0+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I= @@ -613,7 +564,6 @@ github.com/jefferai/jsonx v1.0.0/go.mod h1:OGmqmi2tTeI/PS+qQfBDToLHHJIy/RMp24fPo github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.3.0 h1:OS12ieG61fsCg5+qLJ+SsW9NicxNkg3b25OyT2yCeUc= github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik= -github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/joyent/triton-go v1.7.1-0.20200416154420-6801d15b779f h1:ENpDacvnr8faw5ugQmEF1QYk+f/Y9lXFvuYmRxykago= github.com/joyent/triton-go v1.7.1-0.20200416154420-6801d15b779f/go.mod h1:KDSfL7qe5ZfQqvlDMkVjCztbmcpp/c8M77vhQP8ZPvk= @@ -627,10 +577,8 @@ github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1 github.com/jstemmer/go-junit-report v0.9.1 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/kelseyhightower/envconfig v1.3.0 h1:IvRS4f2VcIQy6j4ORGIf9145T/AsUB+oY8LyvN8BXNM= github.com/kelseyhightower/envconfig v1.3.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8= github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= @@ -641,28 +589,25 @@ github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQL github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= -github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= -github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/lestrrat-go/jwx v0.9.0/go.mod h1:iEoxlYfZjvoGpuWwxUz+eR5e6KTJGsaRcy/YNA/UnBk= +github.com/lib/pq v0.0.0-20180327071824-d34b9ff171c2/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.8.0 h1:9xohqzkUwzR4Ga4ivdTcawVS89YSDVxXMa3xJX3cGzg= github.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/martini-contrib/render v0.0.0-20150707142108-ec18f8345a11 h1:YFh+sjyJTMQSYjKwM4dFKhJPJC/wfo98tPUc17HdoYw= github.com/martini-contrib/render v0.0.0-20150707142108-ec18f8345a11/go.mod h1:Ah2dBMoxZEqk118as2T4u4fjfXarE0pPnMJaArZQZsI= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= @@ -686,7 +631,6 @@ github.com/mholt/archiver v3.1.1+incompatible/go.mod h1:Dh2dOXnSdiLxRiPoVfIr/fI1 github.com/michaelklishin/rabbit-hole v0.0.0-20191008194146-93d9988f0cd5 h1:uA3b4GgZMZxAJsTkd+CVQ85b7KBlD7HLpd/FfTNlGN0= github.com/michaelklishin/rabbit-hole v0.0.0-20191008194146-93d9988f0cd5/go.mod h1:+pmbihVqjC3GPdfWv1V2TnRSuVvwrWLKfEP/MZVB/Wc= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/miekg/dns v1.1.15 h1:CSSIDtllwGLMoA6zjdKnaE6Tx6eVUxQ29LUgGetiDCI= github.com/miekg/dns v1.1.15/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/mitchellh/cli v1.0.0 h1:iGBIsUe3+HZ/AD/Vd7DErOt5sU9fa8Uj7A2s1aggv1Y= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= @@ -706,9 +650,7 @@ github.com/mitchellh/hashstructure v1.0.0/go.mod h1:QjSHrPWS+BGUVBYkbTZWEnOh3G1D github.com/mitchellh/iochan v1.0.0 h1:C+X3KsSTLFVBr/tK1eYN/vs4rJcvsiLU338UhYPJWeY= github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.3.2 h1:mRS76wmkOn3KkKAyXDu42V+6ebnXWIztFSYGN7GeoRg= github.com/mitchellh/mapstructure v1.3.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.3.3 h1:SzB1nHZ2Xi+17FP0zVQBHIZqvwRN9408fJO8h+eeNA8= github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= @@ -725,7 +667,6 @@ github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9 github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/mongodb/go-client-mongodb-atlas v0.1.2 h1:qmUme1TlQBPZupmXMnpD8DxnfGXLVGs3w+0Z17HBiSA= github.com/mongodb/go-client-mongodb-atlas v0.1.2/go.mod h1:LS8O0YLkA+sbtOb3fZLF10yY3tJM+1xATXMJ3oU35LU= -github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/mwielbut/pointy v1.1.0 h1:U5/YEfoIkaGCHv0St3CgjduqXID4FNRoyZgLM1kY9vg= github.com/mwielbut/pointy v1.1.0/go.mod h1:MvvO+uMFj9T5DMda33HlvogsFBX7pWWKAkFIn4teYwY= @@ -748,26 +689,22 @@ github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:v github.com/olekukonko/tablewriter v0.0.0-20180130162743-b8a9be070da4/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w= github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.10.1 h1:q/mM8GF/n0shIN8SaAZ0V+jnLPzen6WIVZdiwrRlMlo= github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/gomega v0.0.0-20190113212917-5533ce8a0da3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo= github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= -github.com/opencontainers/go-digest v1.0.0-rc1 h1:WzifXhOVOEOuFYOJAW6aQqW0TooG2iki3E3Ii+WN7gQ= github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.0.1 h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVojFA6h/TRcI= github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= -github.com/opencontainers/runc v0.1.1 h1:GlxAyO6x8rfZYN9Tt0Kti5a/cP41iuiO2yYT0IJGY8Y= github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= +github.com/opencontainers/runc v1.0.0-rc9 h1:/k06BMULKF5hidyoZymkoDCzdJzltZpz/UU4LguQVtc= +github.com/opencontainers/runc v1.0.0-rc9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/openzipkin/zipkin-go v0.1.3/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= @@ -777,10 +714,9 @@ github.com/oracle/oci-go-sdk v12.5.0+incompatible/go.mod h1:VQb79nF8Z2cwLkLS35uk github.com/ory/dockertest v3.3.4+incompatible/go.mod h1:1vX4m9wsvi00u5bseYwXaSnhNrne+V0E6LAcBILJdPs= github.com/ory/dockertest v3.3.5+incompatible h1:iLLK6SQwIhcbrG783Dghaaa3WPzGc+4Emza6EbVUUGA= github.com/ory/dockertest v3.3.5+incompatible/go.mod h1:1vX4m9wsvi00u5bseYwXaSnhNrne+V0E6LAcBILJdPs= -github.com/oxtoacart/bpool v0.0.0-20150712133111-4e1c5567d7c2 h1:CXwSGu/LYmbjEab5aMCs5usQRVBGThelUKBNnoSOuso= +github.com/ory/dockertest/v3 v3.6.0/go.mod h1:4ZOpj8qBUmh8fcBSVzkH2bws2s91JdGvHUqan4GHEuQ= github.com/oxtoacart/bpool v0.0.0-20150712133111-4e1c5567d7c2/go.mod h1:L3UMQOThbttwfYRNFOWLLVXMhk5Lkio4GGOtw5UrxS0= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/patrickmn/go-cache v0.0.0-20180815053127-5633e0862627/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= @@ -790,7 +726,6 @@ github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 h1:q2e307iGHPdTGp github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pierrec/lz4 v2.2.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= -github.com/pierrec/lz4 v2.2.6+incompatible h1:6aCX4/YZ9v8q69hTyiR7dNLnTA3fgtKHVVW5BCd5Znw= github.com/pierrec/lz4 v2.2.6+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pierrec/lz4 v2.5.2+incompatible h1:WCjObylUIOlKy/+7Abdn34TLIkXiA4UWUMhxq9m9ZXI= github.com/pierrec/lz4 v2.5.2+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= @@ -857,28 +792,22 @@ github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/sean-/conswriter v0.0.0-20180208195008-f5ae3917a627/go.mod h1:7zjs06qF79/FKAJpBvFx3P8Ww4UTIMAe+lpNXDHziac= github.com/sean-/pager v0.0.0-20180208200047-666be9bf53b5/go.mod h1:BeybITEsBEg6qbIiqJ6/Bqeq25bCLbL7YFmpaFfJDuM= -github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/sethvargo/go-limiter v0.3.0 h1:yRMc+Qs2yqw6YJp6UxrO2iUs6DOSq4zcnljbB7/rMns= github.com/sethvargo/go-limiter v0.3.0/go.mod h1:C0kbSFbiriE5k2FFOe18M1YZbAR2Fiwf72uGu0CXCcU= github.com/shirou/gopsutil v2.20.6-0.20200630091542-01afd763e6c0+incompatible h1:IYOqH6sML3rQGNVEQ5foLtpDt4TeW8PIUBuI9f8itkI= github.com/shirou/gopsutil v2.20.6-0.20200630091542-01afd763e6c0+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= -github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24 h1:pntxY8Ary0t43dCZ5dqY4YTJCObLY1kIXl0uzMv+7DE= github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= -github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/smartystreets/assertions v0.0.0-20180725160413-e900ae048470/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v0.0.0-20180222194500-ef6db91d284a/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s= -github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a h1:pa8hGb/2YqsZKovtsgrwcDH1RZhVbTKCjLp47XpqCDs= github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/soheilhy/cmux v0.1.4 h1:0HKaf1o97UwFjHH9o5XsHUOF+tqmdA7KEzXLpiyaw0E= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= @@ -890,18 +819,14 @@ github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tL github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= -github.com/square/go-jose v2.4.1+incompatible h1:KFYc54wTtgnd3x4B/Y7Zr1s/QaEx2BNzRsB3Hae5LHo= github.com/square/go-jose v2.4.1+incompatible/go.mod h1:7MxpAF/1WTVUu8Am+T5kNy+t0902CaLWM4Z745MkOa8= github.com/square/go-jose/v3 v3.0.0-20200225220504-708a9fe87ddc/go.mod h1:JbpHhNyeVc538vtj/ECJ3gPYm1VEitNjsLhm4eJQQbg= -github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94 h1:0ngsPmuP6XIjiFRNFYlvKwSr5zff2v+uPHaffZ6/M4k= github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= @@ -909,16 +834,13 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/tencentcloud/tencentcloud-sdk-go v3.0.171+incompatible/go.mod h1:0PfYow01SHPMhKY31xa+EFz2RStxIqj6JFAJS+IkCi4= -github.com/tidwall/pretty v1.0.1 h1:WE4RBSZ1x6McVVC8S/Md+Qse8YUv6HRObAx6ke00NY8= github.com/tidwall/pretty v1.0.1/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 h1:LnC5Kc/wtumK+WB441p7ynQJzVuNRJiqddSIE3IlSEQ= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926 h1:G3dpKMzFDjgEh2q1Z7zUUtKa8ViPtH+ocF0bE0g00O8= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -github.com/ulikunitz/xz v0.5.6 h1:jGHAfXawEGZQ3blwU5wnWKQJvAraT7Ftq9EXjnXYgt8= github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8= github.com/ulikunitz/xz v0.5.7 h1:YvTNdFzX6+W5m9msiYg/zpkSURPPtOlzbqYjrFn7Yt4= github.com/ulikunitz/xz v0.5.7/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= @@ -930,7 +852,6 @@ github.com/xdg/stringprep v1.0.0 h1:d9X0esnoa3dFsV0FG35rAT0RIhYFlPq7MiP+DW89La0= github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo= github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos= -github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -956,7 +877,6 @@ go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= -go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.14.1 h1:nYDKopTbvAPq/NrUVZwT15y2lpROBiLLyoRTbXOYWOo= @@ -978,7 +898,6 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200117160349-530e935923ad/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37 h1:cg5LA/zNPRzIXIWSCxQW10Rvpy94aQh3LT/ShoCpkHw= golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9 h1:vEg9joUBmeBcK9iSJftGNf3coIG4HqZElCPehJsfAYM= golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -1038,6 +957,7 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191003171128-d98b1b443823/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -1046,9 +966,7 @@ golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200513185701-a91f0712d120 h1:EZ3cVSzKOlJxAd8e8YAJ7no8nNypTxexh/YE/xW3ZEY= golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200519113804-d87ec0cfa476 h1:E7ct1C6/33eOdrGZKMoyntcEvs2dwZnDe30crG5vpYU= golang.org/x/net v0.0.0-20200519113804-d87ec0cfa476/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200602114024-627f9648deb9 h1:pNX+40auqi2JqRfOP1akLGtYcn15TUbkhwuCO3foqqM= golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= @@ -1099,30 +1017,23 @@ golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200121082415-34d275377bf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae h1:/WDfKMnPU+m5M4xB+6x4kaepxRw6jWvR5iDRdvjHgy8= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200409092240-59c9f1ba88fa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200413165638-669c56c373c4 h1:opSr2sbRXk5X5/givKrrKj9HXxFpW2sdCiP8MJSKLQY= golang.org/x/sys v0.0.0-20200413165638-669c56c373c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200519105757-fe76b779f299 h1:DYfZAGf2WMFjMxbgTjaC+2HC7NkNAQs+6Q8b9WEB/F4= golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980 h1:OjiUf46hAmXblsZdnoSXsEUSKU8r1UEzcL5RVZ4gO9Y= golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae h1:Ih9Yo4hSPImZOpfGuA4bR/ORKTAbhZo2AbWNRCnevdo= golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1135,7 +1046,6 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1 h1:NusfzzA6yGQ+ua51ck7E3omNUX/JuqbFSaRGqU8CcLI= golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1182,7 +1092,6 @@ golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjs golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= golang.org/x/tools v0.0.0-20200409170454-77362c5149f0/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200416214402-fc959738d646 h1:7CEkhBsBejkW845gR1AmglqMfc1yGzn42FBmtM4jxyM= golang.org/x/tools v0.0.0-20200416214402-fc959738d646/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200521155704-91d71f6c2f04 h1:LbW6ziLoA0vw8ZR4bmjKAzgEpunUBaEX1ia1Q1jEGC4= golang.org/x/tools v0.0.0-20200521155704-91d71f6c2f04/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= @@ -1208,7 +1117,6 @@ google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/ google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.21.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.24.0 h1:cG03eaksBzhfSIk7JRGctfp3lanklcOM/mTGvow7BbQ= google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.29.0 h1:BaiDisFir8O4IJxvAabCGGkQ6yCJegNQqSVoYUNAnbk= google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= @@ -1247,9 +1155,7 @@ google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfG google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200409111301-baae70f3302d/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200416231807-8751e049a2a0/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884 h1:fiNLklpBwWK1mth30Hlwk+fcdBmIALlgF5iy77O37Ig= google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200519141106-08726f379972 h1:6ydLqG65DIMNJf6p97WudGsmd1w3Ickm/LiZnBrREPI= google.golang.org/genproto v0.0.0-20200519141106-08726f379972/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= @@ -1268,7 +1174,6 @@ google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8 google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= -google.golang.org/grpc v1.28.1 h1:C1QC6KzgSiLyBabDi87BbjaGreoRgGUF5nOyvfrAZ1k= google.golang.org/grpc v1.28.1/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= google.golang.org/grpc v1.29.1 h1:EC2SB8S04d2r73uptxphDSUG+kTKVgjRPF+N3xpxRB4= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= @@ -1277,9 +1182,7 @@ google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.22.0 h1:cJv5/xdbk1NnMPR1VP9+HU6gupuG9MLBoH1r6RHZ2MY= google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.24.0 h1:UhZDfRO8JRQru4/+LlLE0BRKGF8L+PICnvYZmx/fEGA= @@ -1288,15 +1191,12 @@ google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4 google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= -gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d h1:TxyelI5cVkbREznMhfzycHdkp5cLA7DpE+GKjSslYhM= gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= gopkg.in/inf.v0 v0.9.0/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= @@ -1306,7 +1206,6 @@ gopkg.in/ini.v1 v1.42.0 h1:7N3gPTt50s8GuLortA00n8AqRTk75qOP98+mTPpgzRk= gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/jcmturner/goidentity.v3 v3.0.0 h1:1duIyWiTaYvVx3YX2CYtpJbUFd7/UuPYCfgXtQ3VTbI= gopkg.in/jcmturner/goidentity.v3 v3.0.0/go.mod h1:oG2kH0IvSYNIu80dVAyu/yoefjq1mNfM5bm88whjWx4= -gopkg.in/ldap.v3 v3.0.3 h1:YKRHW/2sIl05JsCtx/5ZuUueFuJyoj/6+DGXe3wp6ro= gopkg.in/ldap.v3 v3.0.3/go.mod h1:oxD7NyBuxchC+SgJDE1Q5Od05eGt29SDQVBmV+HYbzw= gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce h1:xcEWjVhvbDy+nHP67nPDDpbYrY+ILlfndk4bRioVHaU= gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= @@ -1315,23 +1214,19 @@ gopkg.in/ory-am/dockertest.v3 v3.3.4/go.mod h1:s9mmoLkaGeAh97qygnNj4xWkiN7e1SKek gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/square/go-jose.v2 v2.3.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= -gopkg.in/square/go-jose.v2 v2.4.1 h1:H0TmLt7/KmzlrDOpa1F+zr0Tk90PbJYBfsVUmRLrf9Y= gopkg.in/square/go-jose.v2 v2.4.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/square/go-jose.v2 v2.5.1 h1:7odma5RETjNHWJnR32wx8t+Io4djHE1PqxCFx3iiZ2w= gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.5 h1:ymVxjfMaHvXD8RqPRmzHHsB3VvucivSkIAvJFDI5O3c= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= -gotest.tools/v3 v3.0.2 h1:kG1BFyqVHuQoVQiR1bWGnfz/fmHvvuiSPIV7rvl360E= gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20180920025451-e3ad64cb4ed3/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -1354,5 +1249,4 @@ layeh.com/radius v0.0.0-20190322222518-890bc1058917/go.mod h1:fywZKyu//X7iRzaxLg rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= diff --git a/helper/dhutil/dhutil.go b/helper/dhutil/dhutil.go index 23257cf91b..848b7b85c8 100644 --- a/helper/dhutil/dhutil.go +++ b/helper/dhutil/dhutil.go @@ -55,15 +55,15 @@ func GenerateSharedSecret(ourPrivate, theirPublic []byte) ([]byte, error) { func DeriveSharedKey(secret, ourPublic, theirPublic []byte) ([]byte, error) { // Derive the final key from the HKDF of the secret and public keys. -/* - Internally, HKDF hashes the secret and two public keys. If Alice and Bob are doing DH key exchange, Alice calculates: + /* + Internally, HKDF hashes the secret and two public keys. If Alice and Bob are doing DH key exchange, Alice calculates: - HKDF(secret, A, B) since ourPublic is A. + HKDF(secret, A, B) since ourPublic is A. - Bob calculates HKDF(secret, B, A), since Bob's ours is B. That produces a different value. Now we only care - that both public keys participate in the derivation, so simply sorting them so they are in a consistent - numerical order (either one would do) arrives at an agreed value. -*/ + Bob calculates HKDF(secret, B, A), since Bob's ours is B. That produces a different value. Now we only care + that both public keys participate in the derivation, so simply sorting them so they are in a consistent + numerical order (either one would do) arrives at an agreed value. + */ var pub1 []byte var pub2 []byte diff --git a/helper/testhelpers/cassandra/cassandrahelper.go b/helper/testhelpers/cassandra/cassandrahelper.go new file mode 100644 index 0000000000..7b736069d5 --- /dev/null +++ b/helper/testhelpers/cassandra/cassandrahelper.go @@ -0,0 +1,88 @@ +package cassandra + +import ( + "context" + "errors" + "fmt" + "github.com/gocql/gocql" + "github.com/hashicorp/vault/helper/testhelpers/docker" + "os" + "testing" + "time" +) + +func PrepareTestContainer(t *testing.T, version string) (func(), string) { + t.Helper() + if os.Getenv("CASSANDRA_HOSTS") != "" { + return func() {}, os.Getenv("CASSANDRA_HOSTS") + } + + if version == "" { + version = "3.11" + } + + var copyFromTo map[string]string + cwd, _ := os.Getwd() + fixturePath := fmt.Sprintf("%s/test-fixtures/", cwd) + if _, err := os.Stat(fixturePath); err != nil { + if !errors.Is(err, os.ErrNotExist) { + // If it doesn't exist, no biggie + t.Fatal(err) + } + } else { + copyFromTo = map[string]string{ + fixturePath: "/etc/cassandra", + } + } + + runner, err := docker.NewServiceRunner(docker.RunOptions{ + ImageRepo: "cassandra", + ImageTag: version, + Ports: []string{"9042/tcp"}, + CopyFromTo: copyFromTo, + Env: []string{"CASSANDRA_BROADCAST_ADDRESS=127.0.0.1"}, + }) + if err != nil { + t.Fatalf("Could not start docker cassandra: %s", err) + } + + svc, err := runner.StartService(context.Background(), func(ctx context.Context, host string, port int) (docker.ServiceConfig, error) { + cfg := docker.NewServiceHostPort(host, port) + clusterConfig := gocql.NewCluster(cfg.Address()) + clusterConfig.Authenticator = gocql.PasswordAuthenticator{ + Username: "cassandra", + Password: "cassandra", + } + clusterConfig.Timeout = 30 * time.Second + clusterConfig.ProtoVersion = 4 + clusterConfig.Port = port + + session, err := clusterConfig.CreateSession() + if err != nil { + return nil, fmt.Errorf("error creating session: %s", err) + } + defer session.Close() + + // Create keyspace + q := session.Query(`CREATE KEYSPACE "vault" WITH REPLICATION = { 'class' : 'SimpleStrategy', 'replication_factor' : 1 };`) + if err := q.Exec(); err != nil { + t.Fatalf("could not create cassandra keyspace: %v", err) + } + + // Create table + q = session.Query(`CREATE TABLE "vault"."entries" ( + bucket text, + key text, + value blob, + PRIMARY KEY (bucket, key) + ) WITH CLUSTERING ORDER BY (key ASC);`) + if err := q.Exec(); err != nil { + t.Fatalf("could not create cassandra table: %v", err) + } + return cfg, nil + }) + if err != nil { + t.Fatalf("Could not start docker cassandra: %s", err) + } + return svc.Cleanup, svc.Config.Address() +} diff --git a/helper/testhelpers/consul/consulhelper.go b/helper/testhelpers/consul/consulhelper.go index 37638e3dc0..8e7ace19c5 100644 --- a/helper/testhelpers/consul/consulhelper.go +++ b/helper/testhelpers/consul/consulhelper.go @@ -1,32 +1,38 @@ package consul import ( - "fmt" + "context" "os" "strings" "testing" consulapi "github.com/hashicorp/consul/api" "github.com/hashicorp/vault/helper/testhelpers/docker" - "github.com/ory/dockertest" - dc "github.com/ory/dockertest/docker" ) +type Config struct { + docker.ServiceHostPort + Token string +} + +func (c *Config) APIConfig() *consulapi.Config { + apiConfig := consulapi.DefaultConfig() + apiConfig.Address = c.Address() + apiConfig.Token = c.Token + return apiConfig +} + // PrepareTestContainer creates a Consul docker container. If version is empty, // the Consul version used will be given by the environment variable // CONSUL_DOCKER_VERSION, or if that's empty, whatever we've hardcoded as the // the latest Consul version. -func PrepareTestContainer(t *testing.T, version string) (cleanup func(), retAddress string, consulToken string) { - t.Logf("preparing test container") - consulToken = os.Getenv("CONSUL_HTTP_TOKEN") - retAddress = os.Getenv("CONSUL_HTTP_ADDR") - if retAddress != "" { - return func() {}, retAddress, consulToken - } - - pool, err := dockertest.NewPool("") - if err != nil { - t.Fatalf("Failed to connect to docker: %s", err) +func PrepareTestContainer(t *testing.T, version string) (func(), *Config) { + if retAddress := os.Getenv("CONSUL_HTTP_ADDR"); retAddress != "" { + shp, err := docker.NewServiceHostPortParse(retAddress) + if err != nil { + t.Fatal(err) + } + return func() {}, &Config{ServiceHostPort: *shp, Token: os.Getenv("CONSUL_HTTP_TOKEN")} } config := `acl { enabled = true default_policy = "deny" }` @@ -42,43 +48,32 @@ func PrepareTestContainer(t *testing.T, version string) (cleanup func(), retAddr config = `datacenter = "test" acl_default_policy = "deny" acl_datacenter = "test" acl_master_token = "test"` } - dockerOptions := &dockertest.RunOptions{ - Repository: "consul", - Tag: version, - Cmd: []string{"agent", "-dev", "-client", "0.0.0.0", "-hcl", config}, - } - consulRepo := os.Getenv("CONSUL_DOCKER_REPO") - if consulRepo != "" { - dockerOptions.Repository = consulRepo - dockerOptions.Auth = dc.AuthConfiguration{ - Username: os.Getenv("CONSUL_DOCKER_USERNAME"), - Password: os.Getenv("CONSUL_DOCKER_PASSWORD"), - } - } - resource, err := pool.RunWithOptions(dockerOptions) + runner, err := docker.NewServiceRunner(docker.RunOptions{ + ImageRepo: "consul", + ImageTag: version, + Cmd: []string{"agent", "-dev", "-client", "0.0.0.0", "-hcl", config}, + Ports: []string{"8500/tcp"}, + // TODO auth untested on this branch + Repository: os.Getenv("CONSUL_DOCKER_REPO"), + AuthUsername: os.Getenv("CONSUL_DOCKER_USERNAME"), + AuthPassword: os.Getenv("CONSUL_DOCKER_PASSWORD"), + }) if err != nil { - t.Fatalf("Could not start local Consul %s docker container: %s", version, err) + t.Fatalf("Could not start docker Consul: %s", err) } - cleanup = func() { - docker.CleanupResource(t, pool, resource) - } - - retAddress = fmt.Sprintf("localhost:%s", resource.GetPort("8500/tcp")) - - // exponential backoff-retry - if err = pool.Retry(func() error { - var err error - consulConfig := consulapi.DefaultNonPooledConfig() - consulConfig.Address = retAddress - consul, err := consulapi.NewClient(consulConfig) + svc, err := runner.StartService(context.Background(), func(ctx context.Context, host string, port int) (docker.ServiceConfig, error) { + shp := docker.NewServiceHostPort(host, port) + apiConfig := consulapi.DefaultNonPooledConfig() + apiConfig.Address = shp.Address() + consul, err := consulapi.NewClient(apiConfig) if err != nil { - return err + return nil, err } // For version of Consul < 1.4 if strings.HasPrefix(version, "1.3") { - consulToken = "test" + consulToken := "test" _, err = consul.KV().Put(&consulapi.KVPair{ Key: "setuptest", Value: []byte("setuptest"), @@ -86,18 +81,20 @@ func PrepareTestContainer(t *testing.T, version string) (cleanup func(), retAddr Token: consulToken, }) if err != nil { - return err + return nil, err } - return nil + return &Config{ + ServiceHostPort: *shp, + Token: consulToken, + }, nil } // New default behavior aclbootstrap, _, err := consul.ACL().Bootstrap() if err != nil { - return err + return nil, err } - consulToken = aclbootstrap.SecretID - t.Logf("Generated Master token: %s", consulToken) + consulToken := aclbootstrap.SecretID policy := &consulapi.ACLPolicy{ Name: "test", Description: "test", @@ -115,12 +112,15 @@ func PrepareTestContainer(t *testing.T, version string) (cleanup func(), retAddr } _, _, err = consul.ACL().PolicyCreate(policy, q) if err != nil { - return err + return nil, err } - return nil - }); err != nil { - cleanup() - t.Fatalf("Could not connect to docker: %s", err) + return &Config{ + ServiceHostPort: *shp, + Token: consulToken, + }, nil + }) + if err != nil { + t.Fatalf("Could not start docker Consul: %s", err) } - return cleanup, retAddress, consulToken + return svc.Cleanup, svc.Config.(*Config) } diff --git a/helper/testhelpers/docker/testhelpers.go b/helper/testhelpers/docker/testhelpers.go index 8a48039342..b9677f6d77 100644 --- a/helper/testhelpers/docker/testhelpers.go +++ b/helper/testhelpers/docker/testhelpers.go @@ -1,25 +1,309 @@ package docker import ( + "bytes" + "context" + "encoding/base64" + "encoding/json" + "fmt" + "io/ioutil" + "net/url" + "os" + "strconv" "strings" "time" - "github.com/mitchellh/go-testing-interface" - "github.com/ory/dockertest" + "github.com/cenkalti/backoff/v3" + "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/container" + "github.com/docker/docker/api/types/network" + "github.com/docker/docker/client" + "github.com/docker/docker/pkg/archive" + "github.com/docker/go-connections/nat" + "github.com/hashicorp/go-uuid" ) -func CleanupResource(t testing.T, pool *dockertest.Pool, resource *dockertest.Resource) { - var err error - for i := 0; i < 10; i++ { - err = pool.Purge(resource) - if err == nil { - return - } - time.Sleep(1 * time.Second) +type Runner struct { + DockerAPI *client.Client + RunOptions RunOptions +} + +type RunOptions struct { + ImageRepo string + ImageTag string + ContainerName string + Cmd []string + Env []string + NetworkID string + CopyFromTo map[string]string + Ports []string + DoNotAutoRemove bool + Repository string + AuthUsername string + AuthPassword string +} + +func NewServiceRunner(opts RunOptions) (*Runner, error) { + dapi, err := client.NewClientWithOpts(client.FromEnv, client.WithVersion("1.39")) + if err != nil { + return nil, err } - if strings.Contains(err.Error(), "No such container") { - return + if opts.NetworkID == "" { + opts.NetworkID = os.Getenv("TEST_DOCKER_NETWORK_ID") } - t.Fatalf("Failed to cleanup local container: %s", err) + if opts.ContainerName == "" { + if strings.Contains(opts.ImageRepo, "/") { + return nil, fmt.Errorf("ContainerName is required for non-library images") + } + // If there's no slash in the repo it's almost certainly going to be + // a good container name. + opts.ContainerName = opts.ImageRepo + } + return &Runner{ + DockerAPI: dapi, + RunOptions: opts, + }, nil +} + +type ServiceConfig interface { + Address() string + URL() *url.URL +} + +func NewServiceHostPort(host string, port int) *ServiceHostPort { + return &ServiceHostPort{address: fmt.Sprintf("%s:%d", host, port)} +} + +func NewServiceHostPortParse(s string) (*ServiceHostPort, error) { + pieces := strings.Split(s, ":") + if len(pieces) != 2 { + return nil, fmt.Errorf("address must be of the form host:port, got: %v", s) + } + + port, err := strconv.Atoi(pieces[1]) + if err != nil || port < 1 { + return nil, fmt.Errorf("address must be of the form host:port, got: %v", s) + } + + return &ServiceHostPort{s}, nil +} + +type ServiceHostPort struct { + address string +} + +func (s ServiceHostPort) Address() string { + return s.address +} + +func (s ServiceHostPort) URL() *url.URL { + return &url.URL{Host: s.address} +} + +func NewServiceURLParse(s string) (*ServiceURL, error) { + u, err := url.Parse(s) + if err != nil { + return nil, err + } + return &ServiceURL{u: *u}, nil +} + +func NewServiceURL(u url.URL) *ServiceURL { + return &ServiceURL{u: u} +} + +type ServiceURL struct { + u url.URL +} + +func (s ServiceURL) Address() string { + return s.u.Host +} + +func (s ServiceURL) URL() *url.URL { + return &s.u +} + +// ServiceAdapter verifies connectivity to the service, then returns either the +// connection string (typically a URL) and nil, or empty string and an error. +type ServiceAdapter func(ctx context.Context, host string, port int) (ServiceConfig, error) + +func (d *Runner) StartService(ctx context.Context, connect ServiceAdapter) (*Service, error) { + container, hostIPs, err := d.Start(context.Background()) + if err != nil { + return nil, err + } + + cleanup := func() { + for i := 0; i < 10; i++ { + err := d.DockerAPI.ContainerRemove(ctx, container.ID, types.ContainerRemoveOptions{Force: true}) + if err == nil { + return + } + time.Sleep(1 * time.Second) + } + } + + bo := backoff.NewExponentialBackOff() + bo.MaxInterval = time.Second * 5 + bo.MaxElapsedTime = time.Minute + + pieces := strings.Split(hostIPs[0], ":") + portInt, err := strconv.Atoi(pieces[1]) + if err != nil { + return nil, err + } + + var config ServiceConfig + err = backoff.Retry(func() error { + c, err := connect(ctx, pieces[0], portInt) + if err != nil { + return err + } + if c == nil { + return fmt.Errorf("service adapter returned nil error and config") + } + config = c + return nil + }, bo) + + if err != nil { + if !d.RunOptions.DoNotAutoRemove { + cleanup() + } + return nil, err + } + + return &Service{ + Config: config, + Cleanup: cleanup, + }, nil +} + +type Service struct { + Config ServiceConfig + Cleanup func() +} + +func (d *Runner) Start(ctx context.Context) (*types.ContainerJSON, []string, error) { + suffix, err := uuid.GenerateUUID() + if err != nil { + return nil, nil, err + } + name := d.RunOptions.ContainerName + "-" + suffix + + cfg := &container.Config{ + Hostname: name, + Image: fmt.Sprintf("%s:%s", d.RunOptions.ImageRepo, d.RunOptions.ImageTag), + Env: d.RunOptions.Env, + Cmd: d.RunOptions.Cmd, + } + if len(d.RunOptions.Ports) > 0 { + cfg.ExposedPorts = make(map[nat.Port]struct{}) + for _, p := range d.RunOptions.Ports { + cfg.ExposedPorts[nat.Port(p)] = struct{}{} + } + } + + hostConfig := &container.HostConfig{ + AutoRemove: !d.RunOptions.DoNotAutoRemove, + PublishAllPorts: true, + } + + netConfig := &network.NetworkingConfig{} + if d.RunOptions.NetworkID != "" { + netConfig.EndpointsConfig = map[string]*network.EndpointSettings{ + d.RunOptions.NetworkID: &network.EndpointSettings{}, + } + } + + // best-effort pull + var opts types.ImageCreateOptions + if d.RunOptions.AuthUsername != "" && d.RunOptions.AuthPassword != "" { + var buf bytes.Buffer + auth := map[string]string{ + "username": d.RunOptions.AuthUsername, + "password": d.RunOptions.AuthPassword, + } + if err := json.NewEncoder(&buf).Encode(auth); err != nil { + return nil, nil, err + } + opts.RegistryAuth = base64.URLEncoding.EncodeToString(buf.Bytes()) + } + resp, _ := d.DockerAPI.ImageCreate(ctx, cfg.Image, opts) + if resp != nil { + _, _ = ioutil.ReadAll(resp) + } + + container, err := d.DockerAPI.ContainerCreate(ctx, cfg, hostConfig, netConfig, cfg.Hostname) + if err != nil { + return nil, nil, fmt.Errorf("container create failed: %v", err) + } + + for from, to := range d.RunOptions.CopyFromTo { + if err := copyToContainer(ctx, d.DockerAPI, container.ID, from, to); err != nil { + _ = d.DockerAPI.ContainerRemove(ctx, container.ID, types.ContainerRemoveOptions{}) + return nil, nil, err + } + } + + err = d.DockerAPI.ContainerStart(ctx, container.ID, types.ContainerStartOptions{}) + if err != nil { + _ = d.DockerAPI.ContainerRemove(ctx, container.ID, types.ContainerRemoveOptions{}) + return nil, nil, fmt.Errorf("container start failed: %v", err) + } + + inspect, err := d.DockerAPI.ContainerInspect(ctx, container.ID) + if err != nil { + _ = d.DockerAPI.ContainerRemove(ctx, container.ID, types.ContainerRemoveOptions{}) + return nil, nil, err + } + + var addrs []string + for _, port := range d.RunOptions.Ports { + pieces := strings.Split(port, "/") + if len(pieces) < 2 { + return nil, nil, fmt.Errorf("expected port of the form 1234/tcp, got: %s", port) + } + if d.RunOptions.NetworkID != "" { + addrs = append(addrs, fmt.Sprintf("%s:%s", cfg.Hostname, pieces[0])) + } else { + mapped, ok := inspect.NetworkSettings.Ports[nat.Port(port)] + if !ok || len(mapped) == 0 { + return nil, nil, fmt.Errorf("no port mapping found for %s", port) + } + + addrs = append(addrs, fmt.Sprintf("127.0.0.1:%s", mapped[0].HostPort)) + } + } + + return &inspect, addrs, nil +} + +func copyToContainer(ctx context.Context, dapi *client.Client, containerID, from, to string) error { + srcInfo, err := archive.CopyInfoSourcePath(from, false) + if err != nil { + return fmt.Errorf("error copying from source %q: %v", from, err) + } + + srcArchive, err := archive.TarResource(srcInfo) + if err != nil { + return fmt.Errorf("error creating tar from source %q: %v", from, err) + } + defer srcArchive.Close() + + dstInfo := archive.CopyInfo{Path: to} + + dstDir, content, err := archive.PrepareArchiveCopy(srcArchive, srcInfo, dstInfo) + if err != nil { + return fmt.Errorf("error preparing copy from %q -> %q: %v", from, to, err) + } + defer content.Close() + err = dapi.CopyToContainer(ctx, containerID, dstDir, content, types.CopyToContainerOptions{}) + if err != nil { + return fmt.Errorf("error copying from %q -> %q: %v", from, to, err) + } + + return nil } diff --git a/helper/testhelpers/ldap/ldaphelper.go b/helper/testhelpers/ldap/ldaphelper.go index 386606382e..f8b468c3e9 100644 --- a/helper/testhelpers/ldap/ldaphelper.go +++ b/helper/testhelpers/ldap/ldaphelper.go @@ -1,70 +1,63 @@ package ldap import ( + "context" "fmt" "testing" hclog "github.com/hashicorp/go-hclog" "github.com/hashicorp/vault/helper/testhelpers/docker" "github.com/hashicorp/vault/sdk/helper/ldaputil" - "github.com/ory/dockertest" ) func PrepareTestContainer(t *testing.T, version string) (cleanup func(), cfg *ldaputil.ConfigEntry) { - pool, err := dockertest.NewPool("") - if err != nil { - t.Fatalf("Failed to connect to docker: %s", err) - } - - dockerOptions := &dockertest.RunOptions{ + runner, err := docker.NewServiceRunner(docker.RunOptions{ // Currently set to "michelvocks" until https://github.com/rroemhild/docker-test-openldap/pull/14 // has been merged. - Repository: "michelvocks/docker-test-openldap", - Tag: version, - Privileged: true, + ImageRepo: "michelvocks/docker-test-openldap", + ImageTag: version, + ContainerName: "ldap", + Ports: []string{"389/tcp"}, //Env: []string{"LDAP_DEBUG_LEVEL=384"}, - } - resource, err := pool.RunWithOptions(dockerOptions) + }) if err != nil { - t.Fatalf("Could not start local LDAP %s docker container: %s", version, err) + t.Fatalf("could not start local LDAP docker container: %s", err) } - cleanup = func() { - docker.CleanupResource(t, pool, resource) - } + cfg = new(ldaputil.ConfigEntry) + cfg.UserDN = "ou=people,dc=planetexpress,dc=com" + cfg.UserAttr = "cn" + cfg.BindDN = "cn=admin,dc=planetexpress,dc=com" + cfg.BindPassword = "GoodNewsEveryone" + cfg.GroupDN = "ou=people,dc=planetexpress,dc=com" + cfg.GroupAttr = "cn" + cfg.RequestTimeout = 60 - //pool.MaxWait = time.Second - // exponential backoff-retry - if err = pool.Retry(func() error { + svc, err := runner.StartService(context.Background(), func(ctx context.Context, host string, port int) (docker.ServiceConfig, error) { + connURL := fmt.Sprintf("ldap://%s:%d", host, port) + cfg.Url = connURL logger := hclog.New(nil) client := ldaputil.Client{ LDAP: ldaputil.NewLDAP(), Logger: logger, } - cfg = new(ldaputil.ConfigEntry) - cfg.Url = fmt.Sprintf("ldap://localhost:%s", resource.GetPort("389/tcp")) - cfg.UserDN = "ou=people,dc=planetexpress,dc=com" - cfg.UserAttr = "cn" - cfg.BindDN = "cn=admin,dc=planetexpress,dc=com" - cfg.BindPassword = "GoodNewsEveryone" - cfg.GroupDN = "ou=people,dc=planetexpress,dc=com" - cfg.GroupAttr = "cn" - cfg.RequestTimeout = 60 conn, err := client.DialLDAP(cfg) if err != nil { - return err + return nil, err } defer conn.Close() if _, err := client.GetUserBindDN(cfg, conn, "Philip J. Fry"); err != nil { - return err + return nil, err } - return nil - }); err != nil { - cleanup() - t.Fatalf("Could not connect to docker: %s", err) + + return docker.NewServiceURLParse(connURL) + }) + + if err != nil { + t.Fatalf("could not start local LDAP docker container: %s", err) } - return cleanup, cfg + return svc.Cleanup, cfg } diff --git a/helper/testhelpers/mongodb/mongodbhelper.go b/helper/testhelpers/mongodb/mongodbhelper.go index 48ab47552c..f9b1657e71 100644 --- a/helper/testhelpers/mongodb/mongodbhelper.go +++ b/helper/testhelpers/mongodb/mongodbhelper.go @@ -1,6 +1,7 @@ package mongodb import ( + "context" "crypto/tls" "errors" "fmt" @@ -12,7 +13,7 @@ import ( "testing" "time" - "github.com/ory/dockertest" + "github.com/hashicorp/vault/helper/testhelpers/docker" "gopkg.in/mgo.v2" ) @@ -24,55 +25,51 @@ func PrepareTestContainer(t *testing.T, version string) (cleanup func(), retURL // PrepareTestContainerWithDatabase configures a test container with a given // database name, to test non-test/admin database configurations -func PrepareTestContainerWithDatabase(t *testing.T, version, dbName string) (cleanup func(), retURL string) { +func PrepareTestContainerWithDatabase(t *testing.T, version, dbName string) (func(), string) { if os.Getenv("MONGODB_URL") != "" { return func() {}, os.Getenv("MONGODB_URL") } - pool, err := dockertest.NewPool("") + runner, err := docker.NewServiceRunner(docker.RunOptions{ + ImageRepo: "mongo", + ImageTag: version, + Ports: []string{"27017/tcp"}, + }) if err != nil { - t.Fatalf("Failed to connect to docker: %s", err) + t.Fatalf("could not start docker mongo: %s", err) } - resource, err := pool.Run("mongo", version, []string{}) - if err != nil { - t.Fatalf("Could not start local mongo docker container: %s", err) - } - - cleanup = func() { - err := pool.Purge(resource) - if err != nil { - t.Fatalf("Failed to cleanup local container: %s", err) + svc, err := runner.StartService(context.Background(), func(ctx context.Context, host string, port int) (docker.ServiceConfig, error) { + connURL := fmt.Sprintf("mongodb://%s:%d", host, port) + if dbName != "" { + connURL = fmt.Sprintf("%s/%s", connURL, dbName) } - } - - retURL = fmt.Sprintf("mongodb://localhost:%s", resource.GetPort("27017/tcp")) - if dbName != "" { - retURL = fmt.Sprintf("%s/%s", retURL, dbName) - } - - // exponential backoff-retry - if err = pool.Retry(func() error { - var err error - dialInfo, err := ParseMongoURL(retURL) + dialInfo, err := ParseMongoURL(connURL) if err != nil { - return err + return nil, err } session, err := mgo.DialWithInfo(dialInfo) if err != nil { - return err + return nil, err } defer session.Close() + session.SetSyncTimeout(1 * time.Minute) session.SetSocketTimeout(1 * time.Minute) - return session.Ping() - }); err != nil { - cleanup() - t.Fatalf("Could not connect to mongo docker container: %s", err) + err = session.Ping() + if err != nil { + return nil, err + } + + return docker.NewServiceURLParse(connURL) + }) + + if err != nil { + t.Fatalf("could not start docker mongo: %s", err) } - return + return svc.Cleanup, svc.Config.URL().String() } // ParseMongoURL will parse a connection string and return a configured dialer diff --git a/helper/testhelpers/mssql/mssqlhelper.go b/helper/testhelpers/mssql/mssqlhelper.go index 65ff209f0a..018eeabbcc 100644 --- a/helper/testhelpers/mssql/mssqlhelper.go +++ b/helper/testhelpers/mssql/mssqlhelper.go @@ -1,50 +1,58 @@ package mssqlhelper import ( + "context" "database/sql" "fmt" + "net/url" "os" "testing" "github.com/hashicorp/vault/helper/testhelpers/docker" - "github.com/ory/dockertest" ) +const mssqlPassword = "yourStrong(!)Password" + func PrepareMSSQLTestContainer(t *testing.T) (cleanup func(), retURL string) { if os.Getenv("MSSQL_URL") != "" { return func() {}, os.Getenv("MSSQL_URL") } - pool, err := dockertest.NewPool("") + runner, err := docker.NewServiceRunner(docker.RunOptions{ + ContainerName: "sqlserver", + ImageRepo: "mcr.microsoft.com/mssql/server", + ImageTag: "2017-latest-ubuntu", + Env: []string{"ACCEPT_EULA=Y", "SA_PASSWORD=" + mssqlPassword}, + Ports: []string{"1433/tcp"}, + }) if err != nil { - t.Fatalf("Failed to connect to docker: %s", err) + t.Fatalf("Could not start docker MSSQL: %s", err) } - resource, err := pool.Run("mcr.microsoft.com/mssql/server", "2017-latest-ubuntu", []string{"ACCEPT_EULA=Y", "SA_PASSWORD=yourStrong(!)Password"}) + svc, err := runner.StartService(context.Background(), connectMSSQL) if err != nil { - t.Fatalf("Could not start local MSSQL docker container: %s", err) + t.Fatalf("Could not start docker MSSQL: %s", err) } - cleanup = func() { - docker.CleanupResource(t, pool, resource) - } - - retURL = fmt.Sprintf("sqlserver://sa:yourStrong(!)Password@127.0.0.1:%s", resource.GetPort("1433/tcp")) - - // exponential backoff-retry - if err = pool.Retry(func() error { - var err error - var db *sql.DB - db, err = sql.Open("mssql", retURL) - if err != nil { - return err - } - defer db.Close() - return db.Ping() - }); err != nil { - cleanup() - t.Fatalf("Could not connect to MSSQL docker container: %s", err) - } - - return + return svc.Cleanup, svc.Config.URL().String() +} + +func connectMSSQL(ctx context.Context, host string, port int) (docker.ServiceConfig, error) { + u := url.URL{ + Scheme: "sqlserver", + User: url.UserPassword("sa", mssqlPassword), + Host: fmt.Sprintf("%s:%d", host, port), + } + + db, err := sql.Open("mssql", u.String()) + if err != nil { + return nil, err + } + defer db.Close() + + err = db.Ping() + if err != nil { + return nil, err + } + return docker.NewServiceURL(u), nil } diff --git a/helper/testhelpers/mysql/mysqlhelper.go b/helper/testhelpers/mysql/mysqlhelper.go index d5a26ffbc9..db9684e0ec 100644 --- a/helper/testhelpers/mysql/mysqlhelper.go +++ b/helper/testhelpers/mysql/mysqlhelper.go @@ -1,6 +1,7 @@ package mysqlhelper import ( + "context" "database/sql" "fmt" "os" @@ -8,51 +9,54 @@ import ( "testing" "github.com/hashicorp/vault/helper/testhelpers/docker" - "github.com/ory/dockertest" ) -func PrepareMySQLTestContainer(t *testing.T, legacy bool, pw string) (cleanup func(), retURL string) { +type Config struct { + docker.ServiceHostPort + ConnString string +} + +var _ docker.ServiceConfig = &Config{} + +func PrepareTestContainer(t *testing.T, legacy bool, pw string) (func(), string) { if os.Getenv("MYSQL_URL") != "" { return func() {}, os.Getenv("MYSQL_URL") } - pool, err := dockertest.NewPool("") - if err != nil { - t.Fatalf("Failed to connect to docker: %s", err) - } - imageVersion := "5.7" if legacy { imageVersion = "5.6" } - resource, err := pool.Run("mysql", imageVersion, []string{"MYSQL_ROOT_PASSWORD=" + pw}) + runner, err := docker.NewServiceRunner(docker.RunOptions{ + ImageRepo: "mysql", + ImageTag: imageVersion, + Ports: []string{"3306/tcp"}, + Env: []string{"MYSQL_ROOT_PASSWORD=" + pw}, + }) if err != nil { - t.Fatalf("Could not start local MySQL docker container: %s", err) + t.Fatalf("could not start docker mysql: %s", err) } - cleanup = func() { - docker.CleanupResource(t, pool, resource) - } - - retURL = fmt.Sprintf("root:%s@(localhost:%s)/mysql?parseTime=true", pw, resource.GetPort("3306/tcp")) - - // exponential backoff-retry - if err = pool.Retry(func() error { - var err error - var db *sql.DB - db, err = sql.Open("mysql", retURL) + svc, err := runner.StartService(context.Background(), func(ctx context.Context, host string, port int) (docker.ServiceConfig, error) { + hostIP := docker.NewServiceHostPort(host, port) + connString := fmt.Sprintf("root:%s@(%s)/mysql?parseTime=true", pw, hostIP.Address()) + db, err := sql.Open("mysql", connString) if err != nil { - return err + return nil, err } defer db.Close() - return db.Ping() - }); err != nil { - cleanup() - t.Fatalf("Could not connect to MySQL docker container: %s", err) - } + err = db.Ping() + if err != nil { + return nil, err + } + return &Config{ServiceHostPort: *hostIP, ConnString: connString}, nil + }) - return + if err != nil { + t.Fatalf("could not start docker mysql: %s", err) + } + return svc.Cleanup, svc.Config.(*Config).ConnString } func TestCredsExist(t testing.TB, connURL, username, password string) error { diff --git a/helper/testhelpers/postgresql/postgreshelper.go b/helper/testhelpers/postgresql/postgreshelper.go deleted file mode 100644 index 581ab59600..0000000000 --- a/helper/testhelpers/postgresql/postgreshelper.go +++ /dev/null @@ -1,53 +0,0 @@ -package postgresql - -import ( - "database/sql" - "fmt" - "os" - "testing" - - "github.com/hashicorp/vault/helper/testhelpers/docker" - "github.com/ory/dockertest" -) - -func PrepareTestContainer(t *testing.T, version string) (cleanup func(), retURL string) { - if os.Getenv("PG_URL") != "" { - return func() {}, os.Getenv("PG_URL") - } - if version == "" { - version = "latest" - } - - pool, err := dockertest.NewPool("") - if err != nil { - t.Fatalf("Failed to connect to docker: %s", err) - } - - resource, err := pool.Run("postgres", "latest", []string{"POSTGRES_PASSWORD=secret", "POSTGRES_DB=database"}) - if err != nil { - t.Fatalf("Could not start local PostgreSQL docker container: %s", err) - } - - cleanup = func() { - docker.CleanupResource(t, pool, resource) - } - - retURL = fmt.Sprintf("postgres://postgres:secret@localhost:%s/database?sslmode=disable", resource.GetPort("5432/tcp")) - - // exponential backoff-retry - if err = pool.Retry(func() error { - var err error - var db *sql.DB - db, err = sql.Open("postgres", retURL) - if err != nil { - return err - } - defer db.Close() - return db.Ping() - }); err != nil { - cleanup() - t.Fatalf("Could not connect to PostgreSQL docker container: %s", err) - } - - return -} diff --git a/helper/testhelpers/postgresql/postgresqlhelper.go b/helper/testhelpers/postgresql/postgresqlhelper.go new file mode 100644 index 0000000000..0ee5b81412 --- /dev/null +++ b/helper/testhelpers/postgresql/postgresqlhelper.go @@ -0,0 +1,59 @@ +package postgresql + +import ( + "context" + "database/sql" + "fmt" + "github.com/hashicorp/vault/helper/testhelpers/docker" + "net/url" + "os" + "testing" +) + +func PrepareTestContainer(t *testing.T, version string) (func(), string) { + if os.Getenv("PG_URL") != "" { + return func() {}, os.Getenv("PG_URL") + } + + if version == "" { + version = "11" + } + runner, err := docker.NewServiceRunner(docker.RunOptions{ + ImageRepo: "postgres", + ImageTag: version, + Env: []string{"POSTGRES_PASSWORD=secret", "POSTGRES_DB=database"}, + Ports: []string{"5432/tcp"}, + }) + if err != nil { + t.Fatalf("Could not start docker Postgres: %s", err) + } + + svc, err := runner.StartService(context.Background(), connectPostgres) + if err != nil { + t.Fatalf("Could not start docker Postgres: %s", err) + } + + return svc.Cleanup, svc.Config.URL().String() +} + +func connectPostgres(ctx context.Context, host string, port int) (docker.ServiceConfig, error) { + u := url.URL{ + Scheme: "postgres", + User: url.UserPassword("postgres", "secret"), + Host: fmt.Sprintf("%s:%d", host, port), + Path: "postgres", + RawQuery: "sslmode=disable", + } + + db, err := sql.Open("postgres", u.String()) + if err != nil { + return nil, err + } + defer db.Close() + + err = db.Ping() + if err != nil { + return nil, err + } + return docker.NewServiceURL(u), nil +} diff --git a/helper/testhelpers/teststorage/teststorage.go b/helper/testhelpers/teststorage/teststorage.go index 100d350e2e..0684735dab 100644 --- a/helper/testhelpers/teststorage/teststorage.go +++ b/helper/testhelpers/teststorage/teststorage.go @@ -83,10 +83,11 @@ func MakeFileBackend(t testing.T, logger hclog.Logger) *vault.PhysicalBackendBun } func MakeConsulBackend(t testing.T, logger hclog.Logger) *vault.PhysicalBackendBundle { - cleanup, consulAddress, consulToken := consul.PrepareTestContainer(t.(*realtesting.T), "") + cleanup, config := consul.PrepareTestContainer(t.(*realtesting.T), "") + consulConf := map[string]string{ - "address": consulAddress, - "token": consulToken, + "address": config.Address(), + "token": config.Token, "max_parallel": "32", } consulBackend, err := physConsul.NewConsulBackend(consulConf, logger) @@ -105,7 +106,7 @@ func MakeRaftBackend(t testing.T, coreIdx int, logger hclog.Logger) *vault.Physi if err != nil { t.Fatal(err) } - t.Logf("raft dir: %s", raftDir) + //t.Logf("raft dir: %s", raftDir) cleanupFunc := func() { os.RemoveAll(raftDir) } diff --git a/helper/testhelpers/teststorage/teststorage_reusable.go b/helper/testhelpers/teststorage/teststorage_reusable.go index 6579a36afa..f158b67aef 100644 --- a/helper/testhelpers/teststorage/teststorage_reusable.go +++ b/helper/testhelpers/teststorage/teststorage_reusable.go @@ -164,7 +164,7 @@ func makeRaftDir(t testing.T) string { if err != nil { t.Fatal(err) } - t.Logf("raft dir: %s", raftDir) + //t.Logf("raft dir: %s", raftDir) return raftDir } diff --git a/physical/cassandra/cassandra_test.go b/physical/cassandra/cassandra_test.go index cd30248547..f5ba015915 100644 --- a/physical/cassandra/cassandra_test.go +++ b/physical/cassandra/cassandra_test.go @@ -1,27 +1,24 @@ package cassandra import ( - "fmt" - "os" - "reflect" - "strconv" - "testing" - "time" - - "github.com/gocql/gocql" log "github.com/hashicorp/go-hclog" - "github.com/hashicorp/vault/helper/testhelpers/docker" + "github.com/hashicorp/vault/helper/testhelpers/cassandra" "github.com/hashicorp/vault/sdk/helper/logging" "github.com/hashicorp/vault/sdk/physical" - "github.com/ory/dockertest" + "os" + "reflect" + "testing" ) func TestCassandraBackend(t *testing.T) { if testing.Short() { t.Skipf("skipping in short mode") } + if os.Getenv("VAULT_CI_GO_TEST_RACE") != "" { + t.Skip("skipping race test in CI pending https://github.com/gocql/gocql/pull/1474") + } - cleanup, hosts := prepareCassandraTestContainer(t) + cleanup, hosts := cassandra.PrepareTestContainer(t, "") defer cleanup() // Run vault tests @@ -54,60 +51,3 @@ func TestCassandraBackendBuckets(t *testing.T) { } } } - -func prepareCassandraTestContainer(t *testing.T) (func(), string) { - if os.Getenv("CASSANDRA_HOSTS") != "" { - return func() {}, os.Getenv("CASSANDRA_HOSTS") - } - - pool, err := dockertest.NewPool("") - if err != nil { - t.Fatalf("cassandra: failed to connect to docker: %s", err) - } - - resource, err := pool.Run("cassandra", "3.11", []string{"CASSANDRA_BROADCAST_ADDRESS=127.0.0.1"}) - if err != nil { - t.Fatalf("cassandra: could not start container: %s", err) - } - - cleanup := func() { - docker.CleanupResource(t, pool, resource) - } - - setup := func() error { - cluster := gocql.NewCluster("127.0.0.1") - p, _ := strconv.Atoi(resource.GetPort("9042/tcp")) - cluster.Port = p - cluster.Timeout = 15 * time.Second - sess, err := cluster.CreateSession() - if err != nil { - return err - } - defer sess.Close() - - // Create keyspace - q := sess.Query(`CREATE KEYSPACE "vault" WITH REPLICATION = { 'class' : 'SimpleStrategy', 'replication_factor' : 1 };`) - if err := q.Exec(); err != nil { - t.Fatalf("could not create cassandra keyspace: %v", err) - } - - // Create table - q = sess.Query(`CREATE TABLE "vault"."entries" ( - bucket text, - key text, - value blob, - PRIMARY KEY (bucket, key) - ) WITH CLUSTERING ORDER BY (key ASC);`) - if err := q.Exec(); err != nil { - t.Fatalf("could not create cassandra table: %v", err) - } - - return nil - } - if pool.Retry(setup); err != nil { - cleanup() - t.Fatalf("cassandra: could not setup container: %s", err) - } - - return cleanup, fmt.Sprintf("127.0.0.1:%s", resource.GetPort("9042/tcp")) -} diff --git a/physical/cockroachdb/cockroachdb_test.go b/physical/cockroachdb/cockroachdb_test.go index 43853d5607..c169869f5a 100644 --- a/physical/cockroachdb/cockroachdb_test.go +++ b/physical/cockroachdb/cockroachdb_test.go @@ -1,8 +1,10 @@ package cockroachdb import ( + "context" "database/sql" "fmt" + "net/url" "os" "testing" @@ -10,72 +12,89 @@ import ( "github.com/hashicorp/vault/helper/testhelpers/docker" "github.com/hashicorp/vault/sdk/helper/logging" "github.com/hashicorp/vault/sdk/physical" - "github.com/ory/dockertest" _ "github.com/lib/pq" ) -func prepareCockroachDBTestContainer(t *testing.T) (cleanup func(), retURL, tableName string) { - tableName = os.Getenv("CR_TABLE") +type Config struct { + docker.ServiceURL + TableName string +} + +var _ docker.ServiceConfig = &Config{} + +func prepareCockroachDBTestContainer(t *testing.T) (func(), *Config) { + if retURL := os.Getenv("CR_URL"); retURL != "" { + s, err := docker.NewServiceURLParse(retURL) + if err != nil { + t.Fatal(err) + } + tableName := os.Getenv("CR_TABLE") + if tableName == "" { + tableName = defaultTableName + } + return func() {}, &Config{*s, "vault." + tableName} + } + + runner, err := docker.NewServiceRunner(docker.RunOptions{ + ImageRepo: "cockroachdb/cockroach", + ImageTag: "release-1.0", + ContainerName: "cockroachdb", + Cmd: []string{"start", "--insecure"}, + Ports: []string{"26257/tcp"}, + }) + if err != nil { + t.Fatalf("Could not start docker CockroachDB: %s", err) + } + svc, err := runner.StartService(context.Background(), connectCockroachDB) + if err != nil { + t.Fatalf("Could not start docker CockroachDB: %s", err) + } + + return svc.Cleanup, svc.Config.(*Config) +} + +func connectCockroachDB(ctx context.Context, host string, port int) (docker.ServiceConfig, error) { + u := url.URL{ + Scheme: "postgresql", + User: url.UserPassword("root", ""), + Host: fmt.Sprintf("%s:%d", host, port), + RawQuery: "sslmode=disable", + } + + db, err := sql.Open("postgres", u.String()) + if err != nil { + return nil, err + } + defer db.Close() + + database := "vault" + _, err = db.Exec(fmt.Sprintf("CREATE DATABASE %s", database)) + if err != nil { + return nil, err + } + + tableName := os.Getenv("CR_TABLE") if tableName == "" { tableName = defaultTableName } - t.Logf("Table name: %s", tableName) - retURL = os.Getenv("CR_URL") - if retURL != "" { - return func() {}, retURL, tableName - } - pool, err := dockertest.NewPool("") - if err != nil { - t.Fatalf("Failed to connect to docker: %s", err) - } - - dockerOptions := &dockertest.RunOptions{ - Repository: "cockroachdb/cockroach", - Tag: "release-1.0", - Cmd: []string{"start", "--insecure"}, - } - resource, err := pool.RunWithOptions(dockerOptions) - if err != nil { - t.Fatalf("Could not start local CockroachDB docker container: %s", err) - } - - cleanup = func() { - docker.CleanupResource(t, pool, resource) - } - - retURL = fmt.Sprintf("postgresql://root@localhost:%s/?sslmode=disable", resource.GetPort("26257/tcp")) - database := "vault" - tableName = fmt.Sprintf("%s.%s", database, tableName) - - // exponential backoff-retry - if err = pool.Retry(func() error { - var err error - db, err := sql.Open("postgres", retURL) - if err != nil { - return err - } - defer db.Close() - _, err = db.Exec(fmt.Sprintf("CREATE DATABASE %s", database)) - return err - }); err != nil { - cleanup() - t.Fatalf("Could not connect to docker: %s", err) - } - return cleanup, retURL, tableName + return &Config{ + ServiceURL: *docker.NewServiceURL(u), + TableName: database + "." + tableName, + }, nil } func TestCockroachDBBackend(t *testing.T) { - cleanup, connURL, table := prepareCockroachDBTestContainer(t) + cleanup, config := prepareCockroachDBTestContainer(t) defer cleanup() // Run vault tests logger := logging.NewVaultLogger(log.Debug) b, err := NewCockroachDBBackend(map[string]string{ - "connection_url": connURL, - "table": table, + "connection_url": config.URL().String(), + "table": config.TableName, }, logger) if err != nil { diff --git a/physical/consul/consul_test.go b/physical/consul/consul_test.go index 9c42bbf73b..2f1e71ca2f 100644 --- a/physical/consul/consul_test.go +++ b/physical/consul/consul_test.go @@ -4,7 +4,6 @@ import ( "context" "fmt" "math/rand" - "os" "reflect" "strings" "testing" @@ -158,18 +157,10 @@ func TestConsul_newConsulBackend(t *testing.T) { } func TestConsulBackend(t *testing.T) { - consulToken := os.Getenv("CONSUL_HTTP_TOKEN") - addr := os.Getenv("CONSUL_HTTP_ADDR") - if addr == "" { - cleanup, connURL, token := consul.PrepareTestContainer(t, "1.4.4") - defer cleanup() - addr, consulToken = connURL, token - } + cleanup, config := consul.PrepareTestContainer(t, "1.4.4") + defer cleanup() - conf := api.DefaultConfig() - conf.Address = addr - conf.Token = consulToken - client, err := api.NewClient(conf) + client, err := api.NewClient(config.APIConfig()) if err != nil { t.Fatalf("err: %v", err) } @@ -182,10 +173,10 @@ func TestConsulBackend(t *testing.T) { logger := logging.NewVaultLogger(log.Debug) b, err := NewConsulBackend(map[string]string{ - "address": conf.Address, + "address": config.Address(), + "token": config.Token, "path": randPath, "max_parallel": "256", - "token": conf.Token, }, logger) if err != nil { t.Fatalf("err: %s", err) @@ -196,18 +187,10 @@ func TestConsulBackend(t *testing.T) { } func TestConsul_TooLarge(t *testing.T) { - consulToken := os.Getenv("CONSUL_HTTP_TOKEN") - addr := os.Getenv("CONSUL_HTTP_ADDR") - if addr == "" { - cleanup, connURL, token := consul.PrepareTestContainer(t, "1.4.4") - defer cleanup() - addr, consulToken = connURL, token - } + cleanup, config := consul.PrepareTestContainer(t, "1.4.4") + defer cleanup() - conf := api.DefaultConfig() - conf.Address = addr - conf.Token = consulToken - client, err := api.NewClient(conf) + client, err := api.NewClient(config.APIConfig()) if err != nil { t.Fatalf("err: %v", err) } @@ -220,10 +203,10 @@ func TestConsul_TooLarge(t *testing.T) { logger := logging.NewVaultLogger(log.Debug) b, err := NewConsulBackend(map[string]string{ - "address": conf.Address, + "address": config.Address(), + "token": config.Token, "path": randPath, "max_parallel": "256", - "token": conf.Token, }, logger) if err != nil { t.Fatalf("err: %s", err) @@ -267,18 +250,10 @@ func TestConsul_TooLarge(t *testing.T) { } func TestConsulHABackend(t *testing.T) { - consulToken := os.Getenv("CONSUL_HTTP_TOKEN") - addr := os.Getenv("CONSUL_HTTP_ADDR") - if addr == "" { - cleanup, connURL, token := consul.PrepareTestContainer(t, "1.4.4") - defer cleanup() - addr, consulToken = connURL, token - } + cleanup, config := consul.PrepareTestContainer(t, "1.4.4") + defer cleanup() - conf := api.DefaultConfig() - conf.Address = addr - conf.Token = consulToken - client, err := api.NewClient(conf) + client, err := api.NewClient(config.APIConfig()) if err != nil { t.Fatalf("err: %v", err) } @@ -289,19 +264,19 @@ func TestConsulHABackend(t *testing.T) { }() logger := logging.NewVaultLogger(log.Debug) - config := map[string]string{ - "address": conf.Address, + backendConfig := map[string]string{ + "address": config.Address(), + "token": config.Token, "path": randPath, "max_parallel": "-1", - "token": conf.Token, } - b, err := NewConsulBackend(config, logger) + b, err := NewConsulBackend(backendConfig, logger) if err != nil { t.Fatalf("err: %s", err) } - b2, err := NewConsulBackend(config, logger) + b2, err := NewConsulBackend(backendConfig, logger) if err != nil { t.Fatalf("err: %s", err) } diff --git a/physical/couchdb/couchdb_test.go b/physical/couchdb/couchdb_test.go index 395c29d8cc..4205f8e64b 100644 --- a/physical/couchdb/couchdb_test.go +++ b/physical/couchdb/couchdb_test.go @@ -1,9 +1,11 @@ package couchdb import ( + "context" "fmt" "io/ioutil" "net/http" + "net/url" "os" "strings" "testing" @@ -13,19 +15,18 @@ import ( "github.com/hashicorp/vault/helper/testhelpers/docker" "github.com/hashicorp/vault/sdk/helper/logging" "github.com/hashicorp/vault/sdk/physical" - "github.com/ory/dockertest" ) func TestCouchDBBackend(t *testing.T) { - cleanup, endpoint, username, password := prepareCouchdbDBTestContainer(t) + cleanup, config := prepareCouchdbDBTestContainer(t) defer cleanup() logger := logging.NewVaultLogger(log.Debug) b, err := NewCouchDBBackend(map[string]string{ - "endpoint": endpoint, - "username": username, - "password": password, + "endpoint": config.URL().String(), + "username": config.username, + "password": config.password, }, logger) if err != nil { t.Fatalf("err: %s", err) @@ -36,15 +37,15 @@ func TestCouchDBBackend(t *testing.T) { } func TestTransactionalCouchDBBackend(t *testing.T) { - cleanup, endpoint, username, password := prepareCouchdbDBTestContainer(t) + cleanup, config := prepareCouchdbDBTestContainer(t) defer cleanup() logger := logging.NewVaultLogger(log.Debug) b, err := NewTransactionalCouchDBBackend(map[string]string{ - "endpoint": endpoint, - "username": username, - "password": password, + "endpoint": config.URL().String(), + "username": config.username, + "password": config.password, }, logger) if err != nil { t.Fatalf("err: %s", err) @@ -54,77 +55,107 @@ func TestTransactionalCouchDBBackend(t *testing.T) { physical.ExerciseBackend_ListPrefix(t, b) } -func prepareCouchdbDBTestContainer(t *testing.T) (cleanup func(), retAddress, username, password string) { +type couchDB struct { + baseURL url.URL + dbname string + username string + password string +} + +func (c couchDB) Address() string { + return c.baseURL.Host +} + +func (c couchDB) URL() *url.URL { + u := c.baseURL + u.Path = c.dbname + return &u +} + +var _ docker.ServiceConfig = &couchDB{} + +func prepareCouchdbDBTestContainer(t *testing.T) (func(), *couchDB) { // If environment variable is set, assume caller wants to target a real // DynamoDB. if os.Getenv("COUCHDB_ENDPOINT") != "" { - return func() {}, os.Getenv("COUCHDB_ENDPOINT"), os.Getenv("COUCHDB_USERNAME"), os.Getenv("COUCHDB_PASSWORD") + return func() {}, &couchDB{ + baseURL: url.URL{Host: os.Getenv("COUCHDB_ENDPOINT")}, + username: os.Getenv("COUCHDB_USERNAME"), + password: os.Getenv("COUCHDB_PASSWORD"), + } } - pool, err := dockertest.NewPool("") + runner, err := docker.NewServiceRunner(docker.RunOptions{ + ImageRepo: "couchdb", + ImageTag: "1.6", + Ports: []string{"5984/tcp"}, + DoNotAutoRemove: true, + }) if err != nil { - t.Fatalf("Failed to connect to docker: %s", err) + t.Fatalf("Could not start local CouchDB: %s", err) } - resource, err := pool.Run("couchdb", "1.6", []string{}) + svc, err := runner.StartService(context.Background(), setupCouchDB) if err != nil { - t.Fatalf("Could not start local DynamoDB: %s", err) + t.Fatalf("Could not start local CouchDB: %s", err) } - retAddress = "http://localhost:" + resource.GetPort("5984/tcp") - cleanup = func() { - docker.CleanupResource(t, pool, resource) + return svc.Cleanup, svc.Config.(*couchDB) +} + +func setupCouchDB(ctx context.Context, host string, port int) (docker.ServiceConfig, error) { + c := &couchDB{ + baseURL: url.URL{Scheme: "http", Host: fmt.Sprintf("%s:%d", host, port)}, + dbname: fmt.Sprintf("vault-test-%d", time.Now().Unix()), + username: "admin", + password: "admin", } - // exponential backoff-retry, because the couchDB may not be able to accept - // connections yet - if err := pool.Retry(func() error { - var err error - resp, err := http.Get(retAddress) + { + resp, err := http.Get(c.baseURL.String()) if err != nil { - return err + return nil, err } if resp.StatusCode != http.StatusOK { - return fmt.Errorf("expected couchdb to return status code 200, got (%s) instead.", resp.Status) + return nil, fmt.Errorf("expected couchdb to return status code 200, got (%s) instead", resp.Status) } - return nil - }); err != nil { - t.Fatalf("Could not connect to docker: %s", err) } - dbName := fmt.Sprintf("vault-test-%d", time.Now().Unix()) { - req, err := http.NewRequest("PUT", fmt.Sprintf("%s/%s", retAddress, dbName), nil) + req, err := http.NewRequest("PUT", c.URL().String(), nil) if err != nil { - t.Fatalf("Could not create create database request: %q", err) + return nil, fmt.Errorf("could not create create database request: %q", err) } resp, err := http.DefaultClient.Do(req) if err != nil { - t.Fatalf("Could not create database: %q", err) + return nil, fmt.Errorf("could not create database: %q", err) } defer resp.Body.Close() if resp.StatusCode != http.StatusCreated { bs, _ := ioutil.ReadAll(resp.Body) - t.Fatalf("Failed to create database: %s %s\n", resp.Status, string(bs)) + return nil, fmt.Errorf("failed to create database: %s %s\n", resp.Status, string(bs)) } } + { - req, err := http.NewRequest("PUT", fmt.Sprintf("%s/_config/admins/admin", retAddress), strings.NewReader(`"admin"`)) + u := c.baseURL + u.Path = fmt.Sprintf("_config/admins/%s", c.username) + req, err := http.NewRequest("PUT", u.String(), strings.NewReader(fmt.Sprintf(`"%s"`, c.password))) if err != nil { - t.Fatalf("Could not create admin user request: %q", err) + return nil, fmt.Errorf("Could not create admin user request: %q", err) } resp, err := http.DefaultClient.Do(req) if err != nil { - t.Fatalf("Could not create admin user: %q", err) + return nil, fmt.Errorf("Could not create admin user: %q", err) } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { bs, _ := ioutil.ReadAll(resp.Body) - t.Fatalf("Failed to create admin user: %s %s\n", resp.Status, string(bs)) + return nil, fmt.Errorf("Failed to create admin user: %s %s\n", resp.Status, string(bs)) } } - return cleanup, retAddress + "/" + dbName, "admin", "admin" + return c, nil } diff --git a/physical/dynamodb/dynamodb_test.go b/physical/dynamodb/dynamodb_test.go index daae71c74c..5236ce6ed0 100644 --- a/physical/dynamodb/dynamodb_test.go +++ b/physical/dynamodb/dynamodb_test.go @@ -5,6 +5,7 @@ import ( "fmt" "math/rand" "net/http" + "net/url" "os" "testing" "time" @@ -14,7 +15,6 @@ import ( "github.com/hashicorp/vault/helper/testhelpers/docker" "github.com/hashicorp/vault/sdk/helper/logging" "github.com/hashicorp/vault/sdk/physical" - "github.com/ory/dockertest" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/credentials" @@ -24,10 +24,10 @@ import ( ) func TestDynamoDBBackend(t *testing.T) { - cleanup, endpoint, credsProvider := prepareDynamoDBTestContainer(t) + cleanup, svccfg := prepareDynamoDBTestContainer(t) defer cleanup() - creds, err := credsProvider.Get() + creds, err := svccfg.Credentials.Get() if err != nil { t.Fatalf("err: %v", err) } @@ -38,8 +38,8 @@ func TestDynamoDBBackend(t *testing.T) { } awsSession, err := session.NewSession(&aws.Config{ - Credentials: credsProvider, - Endpoint: aws.String(endpoint), + Credentials: svccfg.Credentials, + Endpoint: aws.String(svccfg.URL().String()), Region: aws.String(region), }) if err != nil { @@ -65,7 +65,7 @@ func TestDynamoDBBackend(t *testing.T) { "session_token": creds.SessionToken, "table": table, "region": region, - "endpoint": endpoint, + "endpoint": svccfg.URL().String(), }, logger) if err != nil { t.Fatalf("err: %s", err) @@ -114,10 +114,10 @@ func TestDynamoDBBackend(t *testing.T) { } func TestDynamoDBHABackend(t *testing.T) { - cleanup, endpoint, credsProvider := prepareDynamoDBTestContainer(t) + cleanup, svccfg := prepareDynamoDBTestContainer(t) defer cleanup() - creds, err := credsProvider.Get() + creds, err := svccfg.Credentials.Get() if err != nil { t.Fatalf("err: %v", err) } @@ -128,8 +128,8 @@ func TestDynamoDBHABackend(t *testing.T) { } awsSession, err := session.NewSession(&aws.Config{ - Credentials: credsProvider, - Endpoint: aws.String(endpoint), + Credentials: svccfg.Credentials, + Endpoint: aws.String(svccfg.URL().String()), Region: aws.String(region), }) if err != nil { @@ -154,7 +154,7 @@ func TestDynamoDBHABackend(t *testing.T) { "session_token": creds.SessionToken, "table": table, "region": region, - "endpoint": endpoint, + "endpoint": svccfg.URL().String(), } b, err := NewDynamoDBBackend(config, logger) @@ -362,43 +362,57 @@ func testDynamoDBLockRenewal(t *testing.T, ha physical.HABackend) { newLock.Unlock() } -func prepareDynamoDBTestContainer(t *testing.T) (cleanup func(), retAddress string, creds *credentials.Credentials) { +type Config struct { + docker.ServiceURL + Credentials *credentials.Credentials +} + +var _ docker.ServiceConfig = &Config{} + +func prepareDynamoDBTestContainer(t *testing.T) (func(), *Config) { // If environment variable is set, assume caller wants to target a real // DynamoDB. - if os.Getenv("AWS_DYNAMODB_ENDPOINT") != "" { - return func() {}, os.Getenv("AWS_DYNAMODB_ENDPOINT"), credentials.NewEnvCredentials() + if endpoint := os.Getenv("AWS_DYNAMODB_ENDPOINT"); endpoint != "" { + s, err := docker.NewServiceURLParse(endpoint) + if err != nil { + t.Fatal(err) + } + return func() {}, &Config{*s, credentials.NewEnvCredentials()} } - pool, err := dockertest.NewPool("") - if err != nil { - t.Fatalf("Failed to connect to docker: %s", err) - } - - resource, err := pool.Run("cnadiminti/dynamodb-local", "latest", []string{}) + runner, err := docker.NewServiceRunner(docker.RunOptions{ + ImageRepo: "cnadiminti/dynamodb-local", + ImageTag: "latest", + ContainerName: "dynamodb", + Ports: []string{"8000/tcp"}, + }) if err != nil { t.Fatalf("Could not start local DynamoDB: %s", err) } - retAddress = "http://localhost:" + resource.GetPort("8000/tcp") - cleanup = func() { - docker.CleanupResource(t, pool, resource) + svc, err := runner.StartService(context.Background(), connectDynamoDB) + if err != nil { + t.Fatalf("Could not start local DynamoDB: %s", err) } - // exponential backoff-retry, because the DynamoDB may not be able to accept - // connections yet - if err := pool.Retry(func() error { - var err error - resp, err := http.Get(retAddress) - if err != nil { - return err - } - if resp.StatusCode != 400 { - return fmt.Errorf("expected DynamoDB to return status code 400, got (%s) instead", resp.Status) - } - return nil - }); err != nil { - cleanup() - t.Fatalf("Could not connect to docker: %s", err) - } - return cleanup, retAddress, credentials.NewStaticCredentials("fake", "fake", "") + return svc.Cleanup, svc.Config.(*Config) +} + +func connectDynamoDB(ctx context.Context, host string, port int) (docker.ServiceConfig, error) { + u := url.URL{ + Scheme: "http", + Host: fmt.Sprintf("%s:%d", host, port), + } + resp, err := http.Get(u.String()) + if err != nil { + return nil, err + } + if resp.StatusCode != 400 { + return nil, err + } + + return &Config{ + ServiceURL: *docker.NewServiceURL(u), + Credentials: credentials.NewStaticCredentials("fake", "fake", ""), + }, nil } diff --git a/physical/mysql/mysql_test.go b/physical/mysql/mysql_test.go index 75d220b9ae..940b1af2d9 100644 --- a/physical/mysql/mysql_test.go +++ b/physical/mysql/mysql_test.go @@ -162,7 +162,7 @@ func TestMySQLHABackend(t *testing.T) { // https://github.com/hashicorp/vault/issues/8203 and patched in // https://github.com/hashicorp/vault/pull/8229 func TestMySQLHABackend_LockFailPanic(t *testing.T) { - cleanup, connURL := mysqlhelper.PrepareMySQLTestContainer(t, false, "secret") + cleanup, connURL := mysqlhelper.PrepareTestContainer(t, false, "secret") cfg, err := mysql.ParseDSN(connURL) if err != nil { diff --git a/plugins/database/cassandra/cassandra_test.go b/plugins/database/cassandra/cassandra_test.go index c5f916010f..ecde690654 100644 --- a/plugins/database/cassandra/cassandra_test.go +++ b/plugins/database/cassandra/cassandra_test.go @@ -2,86 +2,27 @@ package cassandra import ( "context" - "fmt" - "os" - "strconv" + "strings" "testing" "time" "github.com/gocql/gocql" "github.com/hashicorp/errwrap" - "github.com/hashicorp/vault/helper/testhelpers/docker" + "github.com/hashicorp/vault/helper/testhelpers/cassandra" "github.com/hashicorp/vault/sdk/database/dbplugin" - "github.com/ory/dockertest" ) -func prepareCassandraTestContainer(t *testing.T) (func(), string, int) { - if os.Getenv("CASSANDRA_HOST") != "" { - return func() {}, os.Getenv("CASSANDRA_HOST"), 0 - } - - pool, err := dockertest.NewPool("") - if err != nil { - t.Fatalf("Failed to connect to docker: %s", err) - } - - cwd, _ := os.Getwd() - cassandraMountPath := fmt.Sprintf("%s/test-fixtures/:/etc/cassandra/", cwd) - - ro := &dockertest.RunOptions{ - Repository: "cassandra", - Tag: "latest", - Env: []string{"CASSANDRA_BROADCAST_ADDRESS=127.0.0.1"}, - Mounts: []string{cassandraMountPath}, - } - resource, err := pool.RunWithOptions(ro) - if err != nil { - t.Fatalf("Could not start local cassandra docker container: %s", err) - } - - cleanup := func() { - docker.CleanupResource(t, pool, resource) - } - - port, _ := strconv.Atoi(resource.GetPort("9042/tcp")) - address := fmt.Sprintf("127.0.0.1:%d", port) - - // exponential backoff-retry - if err = pool.Retry(func() error { - clusterConfig := gocql.NewCluster(address) - clusterConfig.Authenticator = gocql.PasswordAuthenticator{ - Username: "cassandra", - Password: "cassandra", - } - clusterConfig.ProtoVersion = 4 - clusterConfig.Port = port - - session, err := clusterConfig.CreateSession() - if err != nil { - return errwrap.Wrapf("error creating session: {{err}}", err) - } - defer session.Close() - return nil - }); err != nil { - cleanup() - t.Fatalf("Could not connect to cassandra docker container: %s", err) - } - return cleanup, address, port -} - -func TestCassandra_Initialize(t *testing.T) { - if os.Getenv("VAULT_ACC") == "" { - t.SkipNow() - } - cleanup, address, port := prepareCassandraTestContainer(t) - defer cleanup() +func getCassandra(t *testing.T, protocolVersion interface{}) (*Cassandra, func()) { + cleanup, connURL := cassandra.PrepareTestContainer(t, "latest") + pieces := strings.Split(connURL, ":") connectionDetails := map[string]interface{}{ - "hosts": address, - "port": port, + "hosts": connURL, + "port": pieces[1], "username": "cassandra", "password": "cassandra", - "protocol_version": 4, + "protocol_version": protocolVersion, + "connect_timeout": "20s", } db := new() @@ -93,48 +34,26 @@ func TestCassandra_Initialize(t *testing.T) { if !db.Initialized { t.Fatal("Database should be initialized") } + return db, cleanup +} - err = db.Close() +func TestCassandra_Initialize(t *testing.T) { + db, cleanup := getCassandra(t, 4) + defer cleanup() + + err := db.Close() if err != nil { t.Fatalf("err: %s", err) } - // test a string protocol - connectionDetails = map[string]interface{}{ - "hosts": address, - "port": strconv.Itoa(port), - "username": "cassandra", - "password": "cassandra", - "protocol_version": "4", - } - - _, err = db.Init(context.Background(), connectionDetails, true) - if err != nil { - t.Fatalf("err: %s", err) - } + db, cleanup = getCassandra(t, "4") + defer cleanup() } func TestCassandra_CreateUser(t *testing.T) { - if os.Getenv("VAULT_ACC") == "" { - t.SkipNow() - } - cleanup, address, port := prepareCassandraTestContainer(t) + db, cleanup := getCassandra(t, 4) defer cleanup() - connectionDetails := map[string]interface{}{ - "hosts": address, - "port": port, - "username": "cassandra", - "password": "cassandra", - "protocol_version": 4, - } - - db := new() - _, err := db.Init(context.Background(), connectionDetails, true) - if err != nil { - t.Fatalf("err: %s", err) - } - statements := dbplugin.Statements{ Creation: []string{testCassandraRole}, } @@ -149,32 +68,15 @@ func TestCassandra_CreateUser(t *testing.T) { t.Fatalf("err: %s", err) } - if err := testCredsExist(t, address, port, username, password); err != nil { + if err := testCredsExist(db.Hosts, db.Port, username, password); err != nil { t.Fatalf("Could not connect with new credentials: %s", err) } } func TestMyCassandra_RenewUser(t *testing.T) { - if os.Getenv("VAULT_ACC") == "" { - t.SkipNow() - } - cleanup, address, port := prepareCassandraTestContainer(t) + db, cleanup := getCassandra(t, 4) defer cleanup() - connectionDetails := map[string]interface{}{ - "hosts": address, - "port": port, - "username": "cassandra", - "password": "cassandra", - "protocol_version": 4, - } - - db := new() - _, err := db.Init(context.Background(), connectionDetails, true) - if err != nil { - t.Fatalf("err: %s", err) - } - statements := dbplugin.Statements{ Creation: []string{testCassandraRole}, } @@ -189,7 +91,7 @@ func TestMyCassandra_RenewUser(t *testing.T) { t.Fatalf("err: %s", err) } - if err := testCredsExist(t, address, port, username, password); err != nil { + if err := testCredsExist(db.Hosts, db.Port, username, password); err != nil { t.Fatalf("Could not connect with new credentials: %s", err) } @@ -200,26 +102,9 @@ func TestMyCassandra_RenewUser(t *testing.T) { } func TestCassandra_RevokeUser(t *testing.T) { - if os.Getenv("VAULT_ACC") == "" { - t.SkipNow() - } - cleanup, address, port := prepareCassandraTestContainer(t) + db, cleanup := getCassandra(t, 4) defer cleanup() - connectionDetails := map[string]interface{}{ - "hosts": address, - "port": port, - "username": "cassandra", - "password": "cassandra", - "protocol_version": 4, - } - - db := new() - _, err := db.Init(context.Background(), connectionDetails, true) - if err != nil { - t.Fatalf("err: %s", err) - } - statements := dbplugin.Statements{ Creation: []string{testCassandraRole}, } @@ -234,7 +119,7 @@ func TestCassandra_RevokeUser(t *testing.T) { t.Fatalf("err: %s", err) } - if err = testCredsExist(t, address, port, username, password); err != nil { + if err = testCredsExist(db.Hosts, db.Port, username, password); err != nil { t.Fatalf("Could not connect with new credentials: %s", err) } @@ -244,36 +129,16 @@ func TestCassandra_RevokeUser(t *testing.T) { t.Fatalf("err: %s", err) } - if err = testCredsExist(t, address, port, username, password); err == nil { + if err = testCredsExist(db.Hosts, db.Port, username, password); err == nil { t.Fatal("Credentials were not revoked") } } func TestCassandra_RotateRootCredentials(t *testing.T) { - if os.Getenv("VAULT_ACC") == "" { - t.SkipNow() - } - cleanup, address, port := prepareCassandraTestContainer(t) + db, cleanup := getCassandra(t, 4) defer cleanup() - connectionDetails := map[string]interface{}{ - "hosts": address, - "port": port, - "username": "cassandra", - "password": "cassandra", - "protocol_version": 4, - } - - db := new() - - connProducer := db.cassandraConnectionProducer - - _, err := db.Init(context.Background(), connectionDetails, true) - if err != nil { - t.Fatalf("err: %s", err) - } - - if !connProducer.Initialized { + if !db.cassandraConnectionProducer.Initialized { t.Fatal("Database should be initialized") } @@ -291,7 +156,7 @@ func TestCassandra_RotateRootCredentials(t *testing.T) { } } -func testCredsExist(t testing.TB, address string, port int, username, password string) error { +func testCredsExist(address string, port int, username, password string) error { clusterConfig := gocql.NewCluster(address) clusterConfig.Authenticator = gocql.PasswordAuthenticator{ Username: username, diff --git a/plugins/database/influxdb/influxdb_test.go b/plugins/database/influxdb/influxdb_test.go index 8a552d66b6..013cfa8182 100644 --- a/plugins/database/influxdb/influxdb_test.go +++ b/plugins/database/influxdb/influxdb_test.go @@ -3,8 +3,10 @@ package influxdb import ( "context" "fmt" + "net/url" "os" "strconv" + "strings" "testing" "time" @@ -12,77 +14,90 @@ import ( "github.com/hashicorp/vault/helper/testhelpers/docker" "github.com/hashicorp/vault/sdk/database/dbplugin" influx "github.com/influxdata/influxdb/client/v2" - "github.com/ory/dockertest" ) const testInfluxRole = `CREATE USER "{{username}}" WITH PASSWORD '{{password}}';GRANT ALL ON "vault" TO "{{username}}";` -func prepareInfluxdbTestContainer(t *testing.T) (func(), string, int) { - if os.Getenv("INFLUXDB_HOST") != "" { - return func() {}, os.Getenv("INFLUXDB_HOST"), 0 +type Config struct { + docker.ServiceURL + Username string + Password string +} + +var _ docker.ServiceConfig = &Config{} + +func (c *Config) apiConfig() influx.HTTPConfig { + return influx.HTTPConfig{ + Addr: c.URL().String(), + Username: c.Username, + Password: c.Password, + } +} + +func (c *Config) connectionParams() map[string]interface{} { + pieces := strings.Split(c.Address(), ":") + port, _ := strconv.Atoi(pieces[1]) + return map[string]interface{}{ + "host": pieces[0], + "port": port, + "username": c.Username, + "password": c.Password, + } +} + +func prepareInfluxdbTestContainer(t *testing.T) (func(), *Config) { + c := &Config{ + Username: "influx-root", + Password: "influx-root", + } + if host := os.Getenv("INFLUXDB_HOST"); host != "" { + c.ServiceURL = *docker.NewServiceURL(url.URL{Scheme: "http", Host: host}) + return func() {}, c } - pool, err := dockertest.NewPool("") + runner, err := docker.NewServiceRunner(docker.RunOptions{ + ImageRepo: "influxdb", + ImageTag: "alpine", + Env: []string{ + "INFLUXDB_DB=vault", + "INFLUXDB_ADMIN_USER=" + c.Username, + "INFLUXDB_ADMIN_PASSWORD=" + c.Password, + "INFLUXDB_HTTP_AUTH_ENABLED=true"}, + Ports: []string{"8086/tcp"}, + }) if err != nil { - t.Fatalf("Failed to connect to docker: %s", err) + t.Fatalf("Could not start docker InfluxDB: %s", err) } - - ro := &dockertest.RunOptions{ - Repository: "influxdb", - Tag: "alpine", - Env: []string{"INFLUXDB_DB=vault", "INFLUXDB_ADMIN_USER=influx-root", "INFLUXDB_ADMIN_PASSWORD=influx-root", "INFLUXDB_HTTP_AUTH_ENABLED=true"}, - } - resource, err := pool.RunWithOptions(ro) - if err != nil { - t.Fatalf("Could not start local influxdb docker container: %s", err) - } - - cleanup := func() { - docker.CleanupResource(t, pool, resource) - } - - port, _ := strconv.Atoi(resource.GetPort("8086/tcp")) - address := "127.0.0.1" - - // exponential backoff-retry - if err = pool.Retry(func() error { - cli, err := influx.NewHTTPClient(influx.HTTPConfig{ - Addr: fmt.Sprintf("http://%s:%d", address, port), - Username: "influx-root", - Password: "influx-root", + svc, err := runner.StartService(context.Background(), func(ctx context.Context, host string, port int) (docker.ServiceConfig, error) { + c.ServiceURL = *docker.NewServiceURL(url.URL{ + Scheme: "http", + Host: fmt.Sprintf("%s:%d", host, port), }) + cli, err := influx.NewHTTPClient(c.apiConfig()) if err != nil { - return errwrap.Wrapf("Error creating InfluxDB Client: ", err) + return nil, errwrap.Wrapf("error creating InfluxDB client: {{err}}", err) } defer cli.Close() _, _, err = cli.Ping(1) if err != nil { - return errwrap.Wrapf("error checking cluster status: {{err}}", err) + return nil, errwrap.Wrapf("error checking cluster status: {{err}}", err) } - return nil - }); err != nil { - cleanup() - t.Fatalf("Could not connect to influxdb docker container: %s", err) + + return c, nil + }) + if err != nil { + t.Fatalf("Could not start docker InfluxDB: %s", err) } - return cleanup, address, port + + return svc.Cleanup, svc.Config.(*Config) } func TestInfluxdb_Initialize(t *testing.T) { - if os.Getenv("VAULT_ACC") == "" { - t.SkipNow() - } - cleanup, address, port := prepareInfluxdbTestContainer(t) + cleanup, config := prepareInfluxdbTestContainer(t) defer cleanup() - connectionDetails := map[string]interface{}{ - "host": address, - "port": port, - "username": "influx-root", - "password": "influx-root", - } - db := new() - _, err := db.Init(context.Background(), connectionDetails, true) + _, err := db.Init(context.Background(), config.connectionParams(), true) if err != nil { t.Fatalf("err: %s", err) } @@ -96,36 +111,20 @@ func TestInfluxdb_Initialize(t *testing.T) { t.Fatalf("err: %s", err) } - // test a string protocol - connectionDetails = map[string]interface{}{ - "host": address, - "port": strconv.Itoa(port), - "username": "influx-root", - "password": "influx-root", - } - - _, err = db.Init(context.Background(), connectionDetails, true) + connectionParams := config.connectionParams() + connectionParams["port"] = strconv.Itoa(connectionParams["port"].(int)) + _, err = db.Init(context.Background(), connectionParams, true) if err != nil { t.Fatalf("err: %s", err) } } func TestInfluxdb_CreateUser(t *testing.T) { - if os.Getenv("VAULT_ACC") == "" { - t.SkipNow() - } - cleanup, address, port := prepareInfluxdbTestContainer(t) + cleanup, config := prepareInfluxdbTestContainer(t) defer cleanup() - connectionDetails := map[string]interface{}{ - "host": address, - "port": port, - "username": "influx-root", - "password": "influx-root", - } - db := new() - _, err := db.Init(context.Background(), connectionDetails, true) + _, err := db.Init(context.Background(), config.connectionParams(), true) if err != nil { t.Fatalf("err: %s", err) } @@ -144,27 +143,18 @@ func TestInfluxdb_CreateUser(t *testing.T) { t.Fatalf("err: %s", err) } - if err := testCredsExist(t, address, port, username, password); err != nil { + config.Username, config.Password = username, password + if err := testCredsExist(t, config); err != nil { t.Fatalf("Could not connect with new credentials: %s", err) } } func TestMyInfluxdb_RenewUser(t *testing.T) { - if os.Getenv("VAULT_ACC") == "" { - t.SkipNow() - } - cleanup, address, port := prepareInfluxdbTestContainer(t) + cleanup, config := prepareInfluxdbTestContainer(t) defer cleanup() - connectionDetails := map[string]interface{}{ - "host": address, - "port": port, - "username": "influx-root", - "password": "influx-root", - } - db := new() - _, err := db.Init(context.Background(), connectionDetails, true) + _, err := db.Init(context.Background(), config.connectionParams(), true) if err != nil { t.Fatalf("err: %s", err) } @@ -183,7 +173,8 @@ func TestMyInfluxdb_RenewUser(t *testing.T) { t.Fatalf("err: %s", err) } - if err := testCredsExist(t, address, port, username, password); err != nil { + config.Username, config.Password = username, password + if err = testCredsExist(t, config); err != nil { t.Fatalf("Could not connect with new credentials: %s", err) } @@ -197,20 +188,11 @@ func TestMyInfluxdb_RenewUser(t *testing.T) { // deleted externally. Guards against a panic, see // https://github.com/hashicorp/vault/issues/6734 func TestInfluxdb_RevokeDeletedUser(t *testing.T) { - if os.Getenv("VAULT_ACC") == "" { - t.SkipNow() - } - cleanup, address, port := prepareInfluxdbTestContainer(t) - - connectionDetails := map[string]interface{}{ - "host": address, - "port": port, - "username": "influx-root", - "password": "influx-root", - } + cleanup, config := prepareInfluxdbTestContainer(t) + defer cleanup() db := new() - _, err := db.Init(context.Background(), connectionDetails, true) + _, err := db.Init(context.Background(), config.connectionParams(), true) if err != nil { t.Fatalf("err: %s", err) } @@ -229,7 +211,8 @@ func TestInfluxdb_RevokeDeletedUser(t *testing.T) { t.Fatalf("err: %s", err) } - if err = testCredsExist(t, address, port, username, password); err != nil { + config.Username, config.Password = username, password + if err = testCredsExist(t, config); err != nil { t.Fatalf("Could not connect with new credentials: %s", err) } @@ -244,21 +227,11 @@ func TestInfluxdb_RevokeDeletedUser(t *testing.T) { } func TestInfluxdb_RevokeUser(t *testing.T) { - if os.Getenv("VAULT_ACC") == "" { - t.SkipNow() - } - cleanup, address, port := prepareInfluxdbTestContainer(t) + cleanup, config := prepareInfluxdbTestContainer(t) defer cleanup() - connectionDetails := map[string]interface{}{ - "host": address, - "port": port, - "username": "influx-root", - "password": "influx-root", - } - db := new() - _, err := db.Init(context.Background(), connectionDetails, true) + _, err := db.Init(context.Background(), config.connectionParams(), true) if err != nil { t.Fatalf("err: %s", err) } @@ -277,39 +250,30 @@ func TestInfluxdb_RevokeUser(t *testing.T) { t.Fatalf("err: %s", err) } - if err = testCredsExist(t, address, port, username, password); err != nil { + config.Username, config.Password = username, password + if err = testCredsExist(t, config); err != nil { t.Fatalf("Could not connect with new credentials: %s", err) } // Test default revoke statements - err = db.RevokeUser(context.Background(), statements, username) + err = db.RevokeUser(context.Background(), dbplugin.Statements{}, username) if err != nil { t.Fatalf("err: %s", err) } - if err = testCredsExist(t, address, port, username, password); err == nil { + if err = testCredsExist(t, config); err == nil { t.Fatal("Credentials were not revoked") } } func TestInfluxdb_RotateRootCredentials(t *testing.T) { - if os.Getenv("VAULT_ACC") == "" { - t.SkipNow() - } - cleanup, address, port := prepareInfluxdbTestContainer(t) + cleanup, config := prepareInfluxdbTestContainer(t) defer cleanup() - connectionDetails := map[string]interface{}{ - "host": address, - "port": port, - "username": "influx-root", - "password": "influx-root", - } - db := new() connProducer := db.influxdbConnectionProducer - _, err := db.Init(context.Background(), connectionDetails, true) + _, err := db.Init(context.Background(), config.connectionParams(), true) if err != nil { t.Fatalf("err: %s", err) } @@ -332,12 +296,8 @@ func TestInfluxdb_RotateRootCredentials(t *testing.T) { } } -func testCredsExist(t testing.TB, address string, port int, username, password string) error { - cli, err := influx.NewHTTPClient(influx.HTTPConfig{ - Addr: fmt.Sprintf("http://%s:%d", address, port), - Username: username, - Password: password, - }) +func testCredsExist(t testing.TB, c *Config) error { + cli, err := influx.NewHTTPClient(c.apiConfig()) if err != nil { return errwrap.Wrapf("Error creating InfluxDB Client: ", err) } diff --git a/plugins/database/mysql/mysql_test.go b/plugins/database/mysql/mysql_test.go index e73545ffb7..5ebac37f23 100644 --- a/plugins/database/mysql/mysql_test.go +++ b/plugins/database/mysql/mysql_test.go @@ -18,7 +18,7 @@ import ( var _ dbplugin.Database = (*MySQL)(nil) func TestMySQL_Initialize(t *testing.T) { - cleanup, connURL := mysqlhelper.PrepareMySQLTestContainer(t, false, "secret") + cleanup, connURL := mysqlhelper.PrepareTestContainer(t, false, "secret") defer cleanup() connectionDetails := map[string]interface{}{ @@ -75,7 +75,7 @@ func TestMySQL_CreateUser(t *testing.T) { t.Run("non-legacy", func(t *testing.T) { // Shared test container for speed - there should not be any overlap between the tests - cleanup, connURL := mysqlhelper.PrepareMySQLTestContainer(t, false, "secret") + cleanup, connURL := mysqlhelper.PrepareTestContainer(t, false, "secret") defer cleanup() connectionDetails := map[string]interface{}{ @@ -93,7 +93,7 @@ func TestMySQL_CreateUser(t *testing.T) { t.Run("legacy", func(t *testing.T) { // Shared test container for speed - there should not be any overlap between the tests - cleanup, connURL := mysqlhelper.PrepareMySQLTestContainer(t, true, "secret") + cleanup, connURL := mysqlhelper.PrepareTestContainer(t, true, "secret") defer cleanup() connectionDetails := map[string]interface{}{ @@ -204,7 +204,7 @@ func TestMySQL_RotateRootCredentials(t *testing.T) { for name, test := range tests { t.Run(name, func(t *testing.T) { - cleanup, connURL := mysqlhelper.PrepareMySQLTestContainer(t, false, "secret") + cleanup, connURL := mysqlhelper.PrepareTestContainer(t, false, "secret") defer cleanup() connURL = strings.Replace(connURL, "root:secret", `{{username}}:{{password}}`, -1) @@ -266,7 +266,7 @@ func TestMySQL_RevokeUser(t *testing.T) { } // Shared test container for speed - there should not be any overlap between the tests - cleanup, connURL := mysqlhelper.PrepareMySQLTestContainer(t, false, "secret") + cleanup, connURL := mysqlhelper.PrepareTestContainer(t, false, "secret") defer cleanup() connectionDetails := map[string]interface{}{ @@ -344,7 +344,7 @@ func TestMySQL_SetCredentials(t *testing.T) { for name, test := range tests { t.Run(name, func(t *testing.T) { - cleanup, connURL := mysqlhelper.PrepareMySQLTestContainer(t, false, "secret") + cleanup, connURL := mysqlhelper.PrepareTestContainer(t, false, "secret") defer cleanup() // create the database user and verify we can access @@ -414,7 +414,7 @@ func TestMySQL_SetCredentials(t *testing.T) { func TestMySQL_Initialize_ReservedChars(t *testing.T) { pw := "#secret!%25#{@}" - cleanup, connURL := mysqlhelper.PrepareMySQLTestContainer(t, false, pw) + cleanup, connURL := mysqlhelper.PrepareTestContainer(t, false, pw) defer cleanup() // Revert password set to test replacement by db.Init diff --git a/sdk/go.sum b/sdk/go.sum index 3c7169eb7e..6acd468237 100644 --- a/sdk/go.sum +++ b/sdk/go.sum @@ -122,6 +122,7 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= diff --git a/serviceregistration/consul/consul_service_registration_test.go b/serviceregistration/consul/consul_service_registration_test.go index fae75329bb..cc31810385 100644 --- a/serviceregistration/consul/consul_service_registration_test.go +++ b/serviceregistration/consul/consul_service_registration_test.go @@ -49,16 +49,12 @@ func testConsulServiceRegistrationConfig(t *testing.T, conf *consulConf) *servic // TestConsul_ServiceRegistration tests whether consul ServiceRegistration works func TestConsul_ServiceRegistration(t *testing.T) { - // Prepare a docker-based consul instance - cleanup, addr, token := consul.PrepareTestContainer(t, "") + cleanup, config := consul.PrepareTestContainer(t, "") defer cleanup() // Create a consul client - cfg := api.DefaultConfig() - cfg.Address = addr - cfg.Token = token - client, err := api.NewClient(cfg) + client, err := api.NewClient(config.APIConfig()) if err != nil { t.Fatal(err) } @@ -93,8 +89,8 @@ func TestConsul_ServiceRegistration(t *testing.T) { // Create a ServiceRegistration that points to our consul instance logger := logging.NewVaultLogger(log.Trace) sd, err := NewServiceRegistration(map[string]string{ - "address": addr, - "token": token, + "address": config.Address(), + "token": config.Token, }, logger, sr.State{}) if err != nil { t.Fatal(err) diff --git a/vault/external_tests/raft/raft_ha_test.go b/vault/external_tests/raft/raft_ha_test.go index d8a0ea5f4f..3d8f97d812 100644 --- a/vault/external_tests/raft/raft_ha_test.go +++ b/vault/external_tests/raft/raft_ha_test.go @@ -127,6 +127,7 @@ func testRaftHANewCluster(t *testing.T, bundler teststorage.PhysicalBackendBundl } func TestRaft_HA_ExistingCluster(t *testing.T) { + t.Parallel() conf := vault.CoreConfig{ DisablePerformanceStandby: true, } diff --git a/vault/external_tests/raft/raft_test.go b/vault/external_tests/raft/raft_test.go index d3f46f7a0b..e050ed3227 100644 --- a/vault/external_tests/raft/raft_test.go +++ b/vault/external_tests/raft/raft_test.go @@ -35,6 +35,7 @@ func raftCluster(t testing.TB) *vault.TestCluster { } func TestRaft_Retry_Join(t *testing.T) { + t.Parallel() var conf vault.CoreConfig var opts = vault.TestClusterOptions{HandlerFunc: vaulthttp.Handler} teststorage.RaftBackendSetup(&conf, &opts) @@ -98,6 +99,7 @@ func TestRaft_Retry_Join(t *testing.T) { } func TestRaft_Join(t *testing.T) { + t.Parallel() var conf vault.CoreConfig var opts = vault.TestClusterOptions{HandlerFunc: vaulthttp.Handler} teststorage.RaftBackendSetup(&conf, &opts) @@ -160,6 +162,7 @@ func TestRaft_Join(t *testing.T) { } func TestRaft_RemovePeer(t *testing.T) { + t.Parallel() cluster := raftCluster(t) defer cluster.Cleanup() @@ -202,6 +205,7 @@ func TestRaft_RemovePeer(t *testing.T) { } func TestRaft_Configuration(t *testing.T) { + t.Parallel() cluster := raftCluster(t) defer cluster.Cleanup() @@ -248,6 +252,7 @@ func TestRaft_Configuration(t *testing.T) { } func TestRaft_ShamirUnseal(t *testing.T) { + t.Parallel() cluster := raftCluster(t) defer cluster.Cleanup() @@ -259,6 +264,7 @@ func TestRaft_ShamirUnseal(t *testing.T) { } func TestRaft_SnapshotAPI(t *testing.T) { + t.Parallel() cluster := raftCluster(t) defer cluster.Cleanup() @@ -691,6 +697,7 @@ func TestRaft_SnapshotAPI_RekeyRotate_Forward(t *testing.T) { } func TestRaft_SnapshotAPI_DifferentCluster(t *testing.T) { + t.Parallel() cluster := raftCluster(t) defer cluster.Cleanup() diff --git a/vault/external_tests/sealmigration/seal_migration_pre14_test.go b/vault/external_tests/sealmigration/seal_migration_pre14_test.go index 43ab77a7d7..0b446326f5 100644 --- a/vault/external_tests/sealmigration/seal_migration_pre14_test.go +++ b/vault/external_tests/sealmigration/seal_migration_pre14_test.go @@ -23,6 +23,7 @@ import ( // migration, using the pre-1.4 method of bring down the whole cluster to do // the migration. func TestSealMigration_TransitToShamir_Pre14(t *testing.T) { + t.Parallel() // Note that we do not test integrated raft storage since this is // a pre-1.4 test. testVariousBackends(t, testSealMigrationTransitToShamir_Pre14, basePort_TransitToShamir_Pre14, false) diff --git a/vault/external_tests/sealmigration/seal_migration_test.go b/vault/external_tests/sealmigration/seal_migration_test.go index 483abf6e2f..9cc86e6dbf 100644 --- a/vault/external_tests/sealmigration/seal_migration_test.go +++ b/vault/external_tests/sealmigration/seal_migration_test.go @@ -92,6 +92,7 @@ func testVariousBackends(t *testing.T, tf testFunc, basePort int, includeRaft bo // migration, using the pre-1.4 method of bring down the whole cluster to do // the migration. func TestSealMigration_ShamirToTransit_Pre14(t *testing.T) { + t.Parallel() // Note that we do not test integrated raft storage since this is // a pre-1.4 test. testVariousBackends(t, testSealMigrationShamirToTransit_Pre14, basePort_ShamirToTransit_Pre14, false) @@ -192,6 +193,7 @@ func migrateFromShamirToTransit_Pre14(t *testing.T, logger hclog.Logger, storage // migration, using the post-1.4 method of bring individual nodes in the cluster // to do the migration. func TestSealMigration_ShamirToTransit_Post14(t *testing.T) { + t.Parallel() testVariousBackends(t, testSealMigrationShamirToTransit_Post14, basePort_ShamirToTransit_Post14, true) } @@ -259,6 +261,7 @@ func migrateFromShamirToTransit_Post14(t *testing.T, logger hclog.Logger, storag // migration, using the post-1.4 method of bring individual nodes in the // cluster to do the migration. func TestSealMigration_TransitToShamir_Post14(t *testing.T) { + t.Parallel() testVariousBackends(t, testSealMigrationTransitToShamir_Post14, basePort_TransitToShamir_Post14, true) } diff --git a/vault/identity_store_oidc_test.go b/vault/identity_store_oidc_test.go index d8c8cbff2f..5fc5ba0ff0 100644 --- a/vault/identity_store_oidc_test.go +++ b/vault/identity_store_oidc_test.go @@ -4,7 +4,6 @@ import ( "crypto/rand" "crypto/rsa" "encoding/json" - "fmt" "testing" "time" @@ -254,7 +253,7 @@ func TestOIDC_Path_OIDCKeyKey(t *testing.T) { Storage: storage, }) expectSuccess(t, resp, err) - fmt.Printf("resp is:\n%#v", resp) + //fmt.Printf("resp is:\n%#v", resp) // Delete test-key -- should fail because test-role depends on test-key resp, err = c.identityStore.HandleRequest(ctx, &logical.Request{ diff --git a/vendor/github.com/cenkalti/backoff/v3/.gitignore b/vendor/github.com/cenkalti/backoff/v3/.gitignore new file mode 100644 index 0000000000..00268614f0 --- /dev/null +++ b/vendor/github.com/cenkalti/backoff/v3/.gitignore @@ -0,0 +1,22 @@ +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Folders +_obj +_test + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.exe diff --git a/vendor/github.com/cenkalti/backoff/v3/.travis.yml b/vendor/github.com/cenkalti/backoff/v3/.travis.yml new file mode 100644 index 0000000000..47a6a46ec2 --- /dev/null +++ b/vendor/github.com/cenkalti/backoff/v3/.travis.yml @@ -0,0 +1,10 @@ +language: go +go: + - 1.7 + - 1.x + - tip +before_install: + - go get github.com/mattn/goveralls + - go get golang.org/x/tools/cmd/cover +script: + - $HOME/gopath/bin/goveralls -service=travis-ci diff --git a/vendor/github.com/cenkalti/backoff/v3/LICENSE b/vendor/github.com/cenkalti/backoff/v3/LICENSE new file mode 100644 index 0000000000..89b8179965 --- /dev/null +++ b/vendor/github.com/cenkalti/backoff/v3/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2014 Cenk Altı + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/cenkalti/backoff/v3/README.md b/vendor/github.com/cenkalti/backoff/v3/README.md new file mode 100644 index 0000000000..55ebc98fc2 --- /dev/null +++ b/vendor/github.com/cenkalti/backoff/v3/README.md @@ -0,0 +1,30 @@ +# Exponential Backoff [![GoDoc][godoc image]][godoc] [![Build Status][travis image]][travis] [![Coverage Status][coveralls image]][coveralls] + +This is a Go port of the exponential backoff algorithm from [Google's HTTP Client Library for Java][google-http-java-client]. + +[Exponential backoff][exponential backoff wiki] +is an algorithm that uses feedback to multiplicatively decrease the rate of some process, +in order to gradually find an acceptable rate. +The retries exponentially increase and stop increasing when a certain threshold is met. + +## Usage + +See https://godoc.org/github.com/cenkalti/backoff#pkg-examples + +## Contributing + +* I would like to keep this library as small as possible. +* Please don't send a PR without opening an issue and discussing it first. +* If proposed change is not a common use case, I will probably not accept it. + +[godoc]: https://godoc.org/github.com/cenkalti/backoff +[godoc image]: https://godoc.org/github.com/cenkalti/backoff?status.png +[travis]: https://travis-ci.org/cenkalti/backoff +[travis image]: https://travis-ci.org/cenkalti/backoff.png?branch=master +[coveralls]: https://coveralls.io/github/cenkalti/backoff?branch=master +[coveralls image]: https://coveralls.io/repos/github/cenkalti/backoff/badge.svg?branch=master + +[google-http-java-client]: https://github.com/google/google-http-java-client/blob/da1aa993e90285ec18579f1553339b00e19b3ab5/google-http-client/src/main/java/com/google/api/client/util/ExponentialBackOff.java +[exponential backoff wiki]: http://en.wikipedia.org/wiki/Exponential_backoff + +[advanced example]: https://godoc.org/github.com/cenkalti/backoff#example_ diff --git a/vendor/github.com/cenkalti/backoff/v3/backoff.go b/vendor/github.com/cenkalti/backoff/v3/backoff.go new file mode 100644 index 0000000000..3676ee405d --- /dev/null +++ b/vendor/github.com/cenkalti/backoff/v3/backoff.go @@ -0,0 +1,66 @@ +// Package backoff implements backoff algorithms for retrying operations. +// +// Use Retry function for retrying operations that may fail. +// If Retry does not meet your needs, +// copy/paste the function into your project and modify as you wish. +// +// There is also Ticker type similar to time.Ticker. +// You can use it if you need to work with channels. +// +// See Examples section below for usage examples. +package backoff + +import "time" + +// BackOff is a backoff policy for retrying an operation. +type BackOff interface { + // NextBackOff returns the duration to wait before retrying the operation, + // or backoff. Stop to indicate that no more retries should be made. + // + // Example usage: + // + // duration := backoff.NextBackOff(); + // if (duration == backoff.Stop) { + // // Do not retry operation. + // } else { + // // Sleep for duration and retry operation. + // } + // + NextBackOff() time.Duration + + // Reset to initial state. + Reset() +} + +// Stop indicates that no more retries should be made for use in NextBackOff(). +const Stop time.Duration = -1 + +// ZeroBackOff is a fixed backoff policy whose backoff time is always zero, +// meaning that the operation is retried immediately without waiting, indefinitely. +type ZeroBackOff struct{} + +func (b *ZeroBackOff) Reset() {} + +func (b *ZeroBackOff) NextBackOff() time.Duration { return 0 } + +// StopBackOff is a fixed backoff policy that always returns backoff.Stop for +// NextBackOff(), meaning that the operation should never be retried. +type StopBackOff struct{} + +func (b *StopBackOff) Reset() {} + +func (b *StopBackOff) NextBackOff() time.Duration { return Stop } + +// ConstantBackOff is a backoff policy that always returns the same backoff delay. +// This is in contrast to an exponential backoff policy, +// which returns a delay that grows longer as you call NextBackOff() over and over again. +type ConstantBackOff struct { + Interval time.Duration +} + +func (b *ConstantBackOff) Reset() {} +func (b *ConstantBackOff) NextBackOff() time.Duration { return b.Interval } + +func NewConstantBackOff(d time.Duration) *ConstantBackOff { + return &ConstantBackOff{Interval: d} +} diff --git a/vendor/github.com/cenkalti/backoff/v3/context.go b/vendor/github.com/cenkalti/backoff/v3/context.go new file mode 100644 index 0000000000..7706faa2b6 --- /dev/null +++ b/vendor/github.com/cenkalti/backoff/v3/context.go @@ -0,0 +1,63 @@ +package backoff + +import ( + "context" + "time" +) + +// BackOffContext is a backoff policy that stops retrying after the context +// is canceled. +type BackOffContext interface { + BackOff + Context() context.Context +} + +type backOffContext struct { + BackOff + ctx context.Context +} + +// WithContext returns a BackOffContext with context ctx +// +// ctx must not be nil +func WithContext(b BackOff, ctx context.Context) BackOffContext { + if ctx == nil { + panic("nil context") + } + + if b, ok := b.(*backOffContext); ok { + return &backOffContext{ + BackOff: b.BackOff, + ctx: ctx, + } + } + + return &backOffContext{ + BackOff: b, + ctx: ctx, + } +} + +func ensureContext(b BackOff) BackOffContext { + if cb, ok := b.(BackOffContext); ok { + return cb + } + return WithContext(b, context.Background()) +} + +func (b *backOffContext) Context() context.Context { + return b.ctx +} + +func (b *backOffContext) NextBackOff() time.Duration { + select { + case <-b.ctx.Done(): + return Stop + default: + } + next := b.BackOff.NextBackOff() + if deadline, ok := b.ctx.Deadline(); ok && deadline.Sub(time.Now()) < next { + return Stop + } + return next +} diff --git a/vendor/github.com/cenkalti/backoff/v3/exponential.go b/vendor/github.com/cenkalti/backoff/v3/exponential.go new file mode 100644 index 0000000000..a031a65979 --- /dev/null +++ b/vendor/github.com/cenkalti/backoff/v3/exponential.go @@ -0,0 +1,153 @@ +package backoff + +import ( + "math/rand" + "time" +) + +/* +ExponentialBackOff is a backoff implementation that increases the backoff +period for each retry attempt using a randomization function that grows exponentially. + +NextBackOff() is calculated using the following formula: + + randomized interval = + RetryInterval * (random value in range [1 - RandomizationFactor, 1 + RandomizationFactor]) + +In other words NextBackOff() will range between the randomization factor +percentage below and above the retry interval. + +For example, given the following parameters: + + RetryInterval = 2 + RandomizationFactor = 0.5 + Multiplier = 2 + +the actual backoff period used in the next retry attempt will range between 1 and 3 seconds, +multiplied by the exponential, that is, between 2 and 6 seconds. + +Note: MaxInterval caps the RetryInterval and not the randomized interval. + +If the time elapsed since an ExponentialBackOff instance is created goes past the +MaxElapsedTime, then the method NextBackOff() starts returning backoff.Stop. + +The elapsed time can be reset by calling Reset(). + +Example: Given the following default arguments, for 10 tries the sequence will be, +and assuming we go over the MaxElapsedTime on the 10th try: + + Request # RetryInterval (seconds) Randomized Interval (seconds) + + 1 0.5 [0.25, 0.75] + 2 0.75 [0.375, 1.125] + 3 1.125 [0.562, 1.687] + 4 1.687 [0.8435, 2.53] + 5 2.53 [1.265, 3.795] + 6 3.795 [1.897, 5.692] + 7 5.692 [2.846, 8.538] + 8 8.538 [4.269, 12.807] + 9 12.807 [6.403, 19.210] + 10 19.210 backoff.Stop + +Note: Implementation is not thread-safe. +*/ +type ExponentialBackOff struct { + InitialInterval time.Duration + RandomizationFactor float64 + Multiplier float64 + MaxInterval time.Duration + // After MaxElapsedTime the ExponentialBackOff stops. + // It never stops if MaxElapsedTime == 0. + MaxElapsedTime time.Duration + Clock Clock + + currentInterval time.Duration + startTime time.Time +} + +// Clock is an interface that returns current time for BackOff. +type Clock interface { + Now() time.Time +} + +// Default values for ExponentialBackOff. +const ( + DefaultInitialInterval = 500 * time.Millisecond + DefaultRandomizationFactor = 0.5 + DefaultMultiplier = 1.5 + DefaultMaxInterval = 60 * time.Second + DefaultMaxElapsedTime = 15 * time.Minute +) + +// NewExponentialBackOff creates an instance of ExponentialBackOff using default values. +func NewExponentialBackOff() *ExponentialBackOff { + b := &ExponentialBackOff{ + InitialInterval: DefaultInitialInterval, + RandomizationFactor: DefaultRandomizationFactor, + Multiplier: DefaultMultiplier, + MaxInterval: DefaultMaxInterval, + MaxElapsedTime: DefaultMaxElapsedTime, + Clock: SystemClock, + } + b.Reset() + return b +} + +type systemClock struct{} + +func (t systemClock) Now() time.Time { + return time.Now() +} + +// SystemClock implements Clock interface that uses time.Now(). +var SystemClock = systemClock{} + +// Reset the interval back to the initial retry interval and restarts the timer. +func (b *ExponentialBackOff) Reset() { + b.currentInterval = b.InitialInterval + b.startTime = b.Clock.Now() +} + +// NextBackOff calculates the next backoff interval using the formula: +// Randomized interval = RetryInterval +/- (RandomizationFactor * RetryInterval) +func (b *ExponentialBackOff) NextBackOff() time.Duration { + // Make sure we have not gone over the maximum elapsed time. + if b.MaxElapsedTime != 0 && b.GetElapsedTime() > b.MaxElapsedTime { + return Stop + } + defer b.incrementCurrentInterval() + return getRandomValueFromInterval(b.RandomizationFactor, rand.Float64(), b.currentInterval) +} + +// GetElapsedTime returns the elapsed time since an ExponentialBackOff instance +// is created and is reset when Reset() is called. +// +// The elapsed time is computed using time.Now().UnixNano(). It is +// safe to call even while the backoff policy is used by a running +// ticker. +func (b *ExponentialBackOff) GetElapsedTime() time.Duration { + return b.Clock.Now().Sub(b.startTime) +} + +// Increments the current interval by multiplying it with the multiplier. +func (b *ExponentialBackOff) incrementCurrentInterval() { + // Check for overflow, if overflow is detected set the current interval to the max interval. + if float64(b.currentInterval) >= float64(b.MaxInterval)/b.Multiplier { + b.currentInterval = b.MaxInterval + } else { + b.currentInterval = time.Duration(float64(b.currentInterval) * b.Multiplier) + } +} + +// Returns a random value from the following interval: +// [randomizationFactor * currentInterval, randomizationFactor * currentInterval]. +func getRandomValueFromInterval(randomizationFactor, random float64, currentInterval time.Duration) time.Duration { + var delta = randomizationFactor * float64(currentInterval) + var minInterval = float64(currentInterval) - delta + var maxInterval = float64(currentInterval) + delta + + // Get a random value from the range [minInterval, maxInterval]. + // The formula used below has a +1 because if the minInterval is 1 and the maxInterval is 3 then + // we want a 33% chance for selecting either 1, 2 or 3. + return time.Duration(minInterval + (random * (maxInterval - minInterval + 1))) +} diff --git a/vendor/github.com/cenkalti/backoff/v3/go.mod b/vendor/github.com/cenkalti/backoff/v3/go.mod new file mode 100644 index 0000000000..479e62adaf --- /dev/null +++ b/vendor/github.com/cenkalti/backoff/v3/go.mod @@ -0,0 +1,3 @@ +module github.com/cenkalti/backoff/v3 + +go 1.12 diff --git a/vendor/github.com/cenkalti/backoff/v3/retry.go b/vendor/github.com/cenkalti/backoff/v3/retry.go new file mode 100644 index 0000000000..e936a506f8 --- /dev/null +++ b/vendor/github.com/cenkalti/backoff/v3/retry.go @@ -0,0 +1,82 @@ +package backoff + +import "time" + +// An Operation is executing by Retry() or RetryNotify(). +// The operation will be retried using a backoff policy if it returns an error. +type Operation func() error + +// Notify is a notify-on-error function. It receives an operation error and +// backoff delay if the operation failed (with an error). +// +// NOTE that if the backoff policy stated to stop retrying, +// the notify function isn't called. +type Notify func(error, time.Duration) + +// Retry the operation o until it does not return error or BackOff stops. +// o is guaranteed to be run at least once. +// +// If o returns a *PermanentError, the operation is not retried, and the +// wrapped error is returned. +// +// Retry sleeps the goroutine for the duration returned by BackOff after a +// failed operation returns. +func Retry(o Operation, b BackOff) error { return RetryNotify(o, b, nil) } + +// RetryNotify calls notify function with the error and wait duration +// for each failed attempt before sleep. +func RetryNotify(operation Operation, b BackOff, notify Notify) error { + var err error + var next time.Duration + var t *time.Timer + + cb := ensureContext(b) + + b.Reset() + for { + if err = operation(); err == nil { + return nil + } + + if permanent, ok := err.(*PermanentError); ok { + return permanent.Err + } + + if next = cb.NextBackOff(); next == Stop { + return err + } + + if notify != nil { + notify(err, next) + } + + if t == nil { + t = time.NewTimer(next) + defer t.Stop() + } else { + t.Reset(next) + } + + select { + case <-cb.Context().Done(): + return err + case <-t.C: + } + } +} + +// PermanentError signals that the operation should not be retried. +type PermanentError struct { + Err error +} + +func (e *PermanentError) Error() string { + return e.Err.Error() +} + +// Permanent wraps the given err in a *PermanentError. +func Permanent(err error) *PermanentError { + return &PermanentError{ + Err: err, + } +} diff --git a/vendor/github.com/cenkalti/backoff/v3/ticker.go b/vendor/github.com/cenkalti/backoff/v3/ticker.go new file mode 100644 index 0000000000..e41084b0ef --- /dev/null +++ b/vendor/github.com/cenkalti/backoff/v3/ticker.go @@ -0,0 +1,82 @@ +package backoff + +import ( + "sync" + "time" +) + +// Ticker holds a channel that delivers `ticks' of a clock at times reported by a BackOff. +// +// Ticks will continue to arrive when the previous operation is still running, +// so operations that take a while to fail could run in quick succession. +type Ticker struct { + C <-chan time.Time + c chan time.Time + b BackOffContext + stop chan struct{} + stopOnce sync.Once +} + +// NewTicker returns a new Ticker containing a channel that will send +// the time at times specified by the BackOff argument. Ticker is +// guaranteed to tick at least once. The channel is closed when Stop +// method is called or BackOff stops. It is not safe to manipulate the +// provided backoff policy (notably calling NextBackOff or Reset) +// while the ticker is running. +func NewTicker(b BackOff) *Ticker { + c := make(chan time.Time) + t := &Ticker{ + C: c, + c: c, + b: ensureContext(b), + stop: make(chan struct{}), + } + t.b.Reset() + go t.run() + return t +} + +// Stop turns off a ticker. After Stop, no more ticks will be sent. +func (t *Ticker) Stop() { + t.stopOnce.Do(func() { close(t.stop) }) +} + +func (t *Ticker) run() { + c := t.c + defer close(c) + + // Ticker is guaranteed to tick at least once. + afterC := t.send(time.Now()) + + for { + if afterC == nil { + return + } + + select { + case tick := <-afterC: + afterC = t.send(tick) + case <-t.stop: + t.c = nil // Prevent future ticks from being sent to the channel. + return + case <-t.b.Context().Done(): + return + } + } +} + +func (t *Ticker) send(tick time.Time) <-chan time.Time { + select { + case t.c <- tick: + case <-t.stop: + return nil + } + + next := t.b.NextBackOff() + if next == Stop { + t.Stop() + return nil + } + + return time.After(next) +} diff --git a/vendor/github.com/cenkalti/backoff/v3/tries.go b/vendor/github.com/cenkalti/backoff/v3/tries.go new file mode 100644 index 0000000000..cfeefd9b76 --- /dev/null +++ b/vendor/github.com/cenkalti/backoff/v3/tries.go @@ -0,0 +1,35 @@ +package backoff + +import "time" + +/* +WithMaxRetries creates a wrapper around another BackOff, which will +return Stop if NextBackOff() has been called too many times since +the last time Reset() was called + +Note: Implementation is not thread-safe. +*/ +func WithMaxRetries(b BackOff, max uint64) BackOff { + return &backOffTries{delegate: b, maxTries: max} +} + +type backOffTries struct { + delegate BackOff + maxTries uint64 + numTries uint64 +} + +func (b *backOffTries) NextBackOff() time.Duration { + if b.maxTries > 0 { + if b.maxTries <= b.numTries { + return Stop + } + b.numTries++ + } + return b.delegate.NextBackOff() +} + +func (b *backOffTries) Reset() { + b.numTries = 0 + b.delegate.Reset() +} diff --git a/vendor/github.com/docker/docker/AUTHORS b/vendor/github.com/docker/docker/AUTHORS index ad166ba8df..c5f725bc19 100644 --- a/vendor/github.com/docker/docker/AUTHORS +++ b/vendor/github.com/docker/docker/AUTHORS @@ -4,7 +4,6 @@ Aanand Prasad Aaron Davidson Aaron Feng -Aaron Hnatiw Aaron Huslage Aaron L. Xu Aaron Lehmann @@ -18,7 +17,6 @@ Abhishek Chanda Abhishek Sharma Abin Shahab Adam Avilla -Adam Dobrawy Adam Eijdenberg Adam Kunk Adam Miller @@ -114,7 +112,6 @@ Anda Xu Anders Janmyr Andre Dublin <81dublin@gmail.com> Andre Granovsky -Andrea Denisse Gómez Andrea Luzzardi Andrea Turli Andreas Elvers @@ -179,10 +176,8 @@ Anusha Ragunathan apocas Arash Deshmeh ArikaChen -Arko Dasgupta Arnaud Lefebvre Arnaud Porterie -Arnaud Rebillout Arthur Barr Arthur Gautier Artur Meyster @@ -284,7 +279,6 @@ Carl Loa Odin Carl X. Su Carlo Mion Carlos Alexandro Becker -Carlos de Paula Carlos Sanchez Carol Fager-Higgins Cary @@ -334,7 +328,6 @@ Chris Gibson Chris Khoo Chris McKinnel Chris McKinnel -Chris Price Chris Seto Chris Snow Chris St. Pierre @@ -424,14 +417,12 @@ Daniel Norberg Daniel Nordberg Daniel Robinson Daniel S -Daniel Sweet Daniel Von Fange Daniel Watkins Daniel X Moore Daniel YC Lin Daniel Zhang Danny Berger -Danny Milosavljevic Danny Yates Danyal Khaliq Darren Coxall @@ -525,8 +516,6 @@ Dmitry Smirnov Dmitry V. Krivenok Dmitry Vorobev Dolph Mathews -Dominic Tubach -Dominic Yin Dominik Dingel Dominik Finkbeiner Dominik Honnef @@ -595,7 +584,6 @@ Erik Weathers Erno Hopearuoho Erwin van der Koogh Ethan Bell -Ethan Mosbaugh Euan Kemp Eugen Krizo Eugene Yakubovich @@ -632,7 +620,6 @@ Fareed Dudhia Fathi Boudra Federico Gimenez Felipe Oliveira -Felipe Ruhland Felix Abecassis Felix Geisendörfer Felix Hupfeld @@ -667,7 +654,6 @@ Frank Groeneveld Frank Herrmann Frank Macreery Frank Rosquin -frankyang Fred Lifton Frederick F. Kautz IV Frederik Loeffert @@ -715,7 +701,6 @@ Gleb M Borisov Glyn Normington GoBella Goffert van Gool -Goldwyn Rodrigues Gopikannan Venugopalsamy Gosuke Miyashita Gou Rao @@ -739,7 +724,6 @@ Guruprasad Gustav Sinder gwx296173 Günter Zöchbauer -Haichao Yang haikuoliu Hakan Özler Hamish Hutchings @@ -748,7 +732,6 @@ Hans Rødtang Hao Shu Wei Hao Zhang <21521210@zju.edu.cn> Harald Albers -Harald Niesche Harley Laue Harold Cooper Harrison Turton @@ -768,11 +751,9 @@ Hobofan Hollie Teal Hong Xu Hongbin Lu -Hongxu Jia hsinko <21551195@zju.edu.cn> Hu Keping Hu Tao -HuanHuan Ye Huanzhong Zhang Huayi Zhang Hugo Duncan @@ -916,7 +897,6 @@ Jie Luo Jihyun Hwang Jilles Oldenbeuving Jim Alateras -Jim Ehrismann Jim Galasyn Jim Minter Jim Perrin @@ -954,7 +934,7 @@ John Feminella John Gardiner Myers John Gossman John Harris -John Howard +John Howard (VM) John Laswell John Maguire John Mulhausen @@ -968,7 +948,6 @@ John Willis Jon Johnson Jon Surrell Jon Wedaman -Jonas Dohse Jonas Pfenniger Jonathan A. Schweder Jonathan A. Sternberg @@ -1022,7 +1001,6 @@ Julio Montes Jun-Ru Chang Jussi Nummelin Justas Brazauskas -Justen Martin Justin Cormack Justin Force Justin Menga @@ -1031,7 +1009,6 @@ Justin Simonelis Justin Terry Justyn Temme Jyrki Puttonen -Jérémy Leherpeur Jérôme Petazzoni Jörg Thalheim K. Heller @@ -1069,7 +1046,6 @@ Ken Reese Kenfe-Mickaël Laventure Kenjiro Nakayama Kent Johnson -Kenta Tada Kevin "qwazerty" Houdebert Kevin Burke Kevin Clark @@ -1080,7 +1056,6 @@ Kevin Kern Kevin Menard Kevin Meredith Kevin P. Kucharczyk -Kevin Parsons Kevin Richardson Kevin Shi Kevin Wallace @@ -1171,7 +1146,6 @@ longliqiang88 <394564827@qq.com> Lorenz Leutgeb Lorenzo Fontana Lotus Fenn -Louis Delossantos Louis Opter Luca Favatella Luca Marturana @@ -1180,18 +1154,15 @@ Luca-Bogdan Grigorescu Lucas Chan Lucas Chi Lucas Molas -Lucas Silvestre Luciano Mores Luis Martínez de Bartolomé Izquierdo Luiz Svoboda -Lukas Heeren Lukas Waslowski lukaspustina Lukasz Zajaczkowski Luke Marsden Lyn Lynda O'Leary -lzhfromutsc Lénaïc Huard Ma Müller Ma Shimiao @@ -1325,7 +1296,6 @@ Michael Stapelberg Michael Steinert Michael Thies Michael West -Michael Zhao Michal Fojtik Michal Gebauer Michal Jemala @@ -1410,7 +1380,6 @@ Neyazul Haque Nghia Tran Niall O'Higgins Nicholas E. Rabenau -Nick Adcock Nick DeCoursin Nick Irvine Nick Neisen @@ -1449,7 +1418,6 @@ Nuutti Kotivuori nzwsch O.S. Tezer objectified -Odin Ugedal Oguz Bilgic Oh Jinkyun Ohad Schneider @@ -1460,7 +1428,6 @@ Oliver Reason Olivier Gambier Olle Jonsson Olli Janatuinen -Olly Pomeroy Omri Shiv Oriol Francès Oskar Niburski @@ -1470,7 +1437,6 @@ Ovidio Mallo Panagiotis Moustafellos Paolo G. Giarrusso Pascal -Pascal Bach Pascal Borreli Pascal Hartig Patrick Böänziger @@ -1495,7 +1461,6 @@ Paul Nasrat Paul Weaver Paulo Ribeiro Pavel Lobashov -Pavel Matěja Pavel Pletenev Pavel Pospisil Pavel Sutyrin @@ -1607,7 +1572,6 @@ Riku Voipio Riley Guerin Ritesh H Shukla Riyaz Faizullabhoy -Rob Gulewich Rob Vesse Robert Bachmann Robert Bittle @@ -1616,13 +1580,11 @@ Robert Schneider Robert Stern Robert Terhaar Robert Wallis -Robert Wang Roberto G. Hashioka Roberto Muñoz Fernández Robin Naundorf Robin Schneider Robin Speekenbrink -Robin Thoni robpc Rodolfo Carvalho Rodrigo Vaz @@ -1656,7 +1618,6 @@ Rozhnov Alexandr Rudolph Gottesheim Rui Cao Rui Lopes -Ruilin Li Runshen Zhu Russ Magee Ryan Abrams @@ -1695,7 +1656,6 @@ Sam J Sharpe Sam Neirinck Sam Reis Sam Rijs -Sam Whited Sambuddha Basu Sami Wagiaalla Samuel Andaya @@ -1710,7 +1670,6 @@ sapphiredev Sargun Dhillon Sascha Andres Sascha Grunert -SataQiu Satnam Singh Satoshi Amemiya Satoshi Tagomori @@ -1759,7 +1718,6 @@ Shijun Qin Shishir Mahajan Shoubhik Bose Shourya Sarcar -Shu-Wai Chow shuai-z Shukui Yang Shuwei Hao @@ -1770,7 +1728,6 @@ Silas Sewell Silvan Jegen Simão Reis Simei He -Simon Barendse Simon Eskildsen Simon Ferquel Simon Leinen @@ -1779,7 +1736,6 @@ Simon Taranto Simon Vikstrom Sindhu S Sjoerd Langkemper -skanehira Solganik Alexander Solomon Hykes Song Gao @@ -1791,18 +1747,16 @@ Sridatta Thatipamala Sridhar Ratnakumar Srini Brahmaroutu Srinivasan Srivatsan -Staf Wagemakers Stanislav Bondarenko Steeve Morin Stefan Berger Stefan J. Wernli Stefan Praszalowicz Stefan S. -Stefan Scherer +Stefan Scherer Stefan Staudenmeyer Stefan Weil Stephan Spindler -Stephen Benjamin Stephen Crosby Stephen Day Stephen Drake @@ -1819,12 +1773,10 @@ Steven Iveson Steven Merrill Steven Richards Steven Taylor -Stig Larsson Subhajit Ghosh Sujith Haridasan Sun Gengze <690388648@qq.com> Sun Jianbo -Sune Keller Sunny Gogoi Suryakumar Sudar Sven Dowideit @@ -1875,7 +1827,6 @@ Tianyi Wang Tibor Vass Tiffany Jernigan Tiffany Low -Tim Tim Bart Tim Bosse Tim Dettrick @@ -1961,7 +1912,6 @@ Victor Palma Victor Vieux Victoria Bialas Vijaya Kumar K -Vikram bir Singh Viktor Stanchev Viktor Vojnovski VinayRaghavanKS @@ -2019,7 +1969,6 @@ Wenyu You <21551128@zju.edu.cn> Wenzhi Liang Wes Morgan Wewang Xiaorenfine -Wiktor Kwapisiewicz Will Dietz Will Rouesnel Will Weaver @@ -2047,7 +1996,6 @@ xichengliudui <1693291525@qq.com> xiekeyang Ximo Guanter Gonzálbez Xinbo Weng -Xinfeng Liu Xinzi Zhou Xiuming Chen Xuecong Liao @@ -2062,7 +2010,6 @@ Yang Pengfei yangchenliang Yanqiang Miao Yao Zaiyong -Yash Murty Yassine Tijani Yasunori Mahata Yazhong Liu @@ -2077,7 +2024,6 @@ Yongxin Li Yongzhi Pan Yosef Fertel You-Sheng Yang (楊有勝) -youcai Youcef YEKHLEF Yu Changchun Yu Chengxia @@ -2114,7 +2060,6 @@ Zhoulin Xie Zhu Guihua Zhu Kunjia Zhuoyun Wei -Ziheng Liu Zilin Du zimbatm Ziming Dong @@ -2123,7 +2068,7 @@ zmarouf Zoltan Tombol Zou Yu zqh -Zuhayr Elahi +Zuhayr Elahi Zunayed Ali Álex González Álvaro Lázaro diff --git a/vendor/github.com/docker/docker/api/common.go b/vendor/github.com/docker/docker/api/common.go index 1565e2af64..aa146cdaeb 100644 --- a/vendor/github.com/docker/docker/api/common.go +++ b/vendor/github.com/docker/docker/api/common.go @@ -3,7 +3,7 @@ package api // import "github.com/docker/docker/api" // Common constants for daemon and client. const ( // DefaultVersion of Current REST API - DefaultVersion = "1.41" + DefaultVersion = "1.40" // NoBaseImageSpecifier is the symbol used by the FROM // command to specify that no base image is to be used. diff --git a/vendor/github.com/docker/docker/api/swagger.yaml b/vendor/github.com/docker/docker/api/swagger.yaml index fde6015334..ce4b80ac5e 100644 --- a/vendor/github.com/docker/docker/api/swagger.yaml +++ b/vendor/github.com/docker/docker/api/swagger.yaml @@ -19,10 +19,10 @@ produces: consumes: - "application/json" - "text/plain" -basePath: "/v1.41" +basePath: "/v1.40" info: title: "Docker Engine API" - version: "1.41" + version: "1.40" x-logo: url: "https://docs.docker.com/images/logo-docker-main.png" description: | @@ -49,8 +49,8 @@ info: the URL is not supported by the daemon, a HTTP `400 Bad Request` error message is returned. - If you omit the version-prefix, the current version of the API (v1.41) is used. - For example, calling `/info` is the same as calling `/v1.41/info`. Using the + If you omit the version-prefix, the current version of the API (v1.40) is used. + For example, calling `/info` is the same as calling `/v1.40/info`. Using the API without a version-prefix is deprecated and will be removed in a future release. Engine releases in the near future should support this version of the API, @@ -800,19 +800,6 @@ definitions: description: "A list of kernel capabilities to drop from the container. Conflicts with option 'Capabilities'" items: type: "string" - CgroupnsMode: - type: "string" - enum: - - "private" - - "host" - description: | - cgroup namespace mode for the container. Possible values are: - - - `"private"`: the container runs in its own private cgroup namespace - - `"host"`: use the host system's cgroup namespace - - If not specified, the daemon default is used, which can either be `"private"` - or `"host"`, depending on daemon version, kernel support and configuration. Dns: type: "array" description: "A list of DNS servers for the container to use." @@ -2979,18 +2966,6 @@ definitions: type: "object" additionalProperties: type: "string" - # This option is not used by Windows containers - Capabilities: - type: "array" - description: | - A list of kernel capabilities to be available for container (this overrides the default set). - items: - type: "string" - example: - - "CAP_NET_RAW" - - "CAP_SYS_ADMIN" - - "CAP_SYS_CHROOT" - - "CAP_SYSLOG" NetworkAttachmentSpec: description: | Read-only spec type for non-swarm containers attached to swarm overlay @@ -3205,12 +3180,6 @@ definitions: type: "integer" DesiredState: $ref: "#/definitions/TaskState" - JobIteration: - description: | - If the Service this Task belongs to is a job-mode service, contains - the JobIteration of the Service this Task was created for. Absent if - the Task was created for a Replicated or Global Service. - $ref: "#/definitions/ObjectVersion" example: ID: "0kzzo1i0y4jz6027t0k7aezc7" Version: @@ -3303,22 +3272,6 @@ definitions: format: "int64" Global: type: "object" - ReplicatedJob: - description: "The mode used for services with a finite number of tasks that run to a completed state." - type: "object" - properties: - MaxConcurrent: - description: "The maximum number of replicas to run simultaneously." - type: "integer" - format: "int64" - default: 1 - TotalCompletions: - description: "The total number of replicas desired to reach the Completed state. If unset, will default to the value of MaxConcurrent" - type: "integer" - format: "int64" - GlobalJob: - description: "The mode used for services which run a task to the completed state on each valid node." - type: "object" UpdateConfig: description: "Specification for the update strategy of the service." type: "object" @@ -3498,58 +3451,6 @@ definitions: format: "dateTime" Message: type: "string" - ServiceStatus: - description: | - The status of the service's tasks. Provided only when requested as - part of a ServiceList operation. - type: "object" - properties: - RunningTasks: - description: "The number of tasks for the service currently in the Running state" - type: "integer" - format: "uint64" - example: 7 - DesiredTasks: - description: | - The number of tasks for the service desired to be running. - For replicated services, this is the replica count from the - service spec. For global services, this is computed by taking - count of all tasks for the service with a Desired State other - than Shutdown. - type: "integer" - format: "uint64" - example: 10 - CompletedTasks: - description: | - The number of tasks for a job that are in the Completed state. - This field must be cross-referenced with the service type, as the - value of 0 may mean the service is not in a job mode, or it may - mean the job-mode service has no tasks yet Completed. - type: "integer" - format: "uint64" - JobStatus: - description: | - The status of the service when it is in one of ReplicatedJob or - GlobalJob modes. Absent on Replicated and Global mode services. The - JobIteration is an ObjectVersion, but unlike the Service's version, - does not need to be sent with an update request. - type: "object" - properties: - JobIteration: - description: | - JobIteration is a value increased each time a Job is executed, - successfully or otherwise. "Executed", in this case, means the - job as a whole has been started, not that an individual Task has - been launched. A job is "Executed" when its ServiceSpec is - updated. JobIteration can be used to disambiguate Tasks belonging - to different executions of a job. Though JobIteration will - increase with each subsequent execution, it may not necessarily - increase by 1, and so JobIteration should not be used to - $ref: "#/definitions/ObjectVersion" - LastExecution: - description: "The last time, as observed by the server, that this job was started" - type: "string" - format: "dateTime" example: ID: "9mnpnzenvg8p8tdbtq4wvbkcz" Version: @@ -3953,6 +3854,44 @@ definitions: on Windows. type: "string" example: "/var/lib/docker" + SystemStatus: + description: | + Status information about this node (standalone Swarm API). + +


+ + > **Note**: The information returned in this field is only propagated + > by the Swarm standalone API, and is empty (`null`) when using + > built-in swarm mode. + type: "array" + items: + type: "array" + items: + type: "string" + example: + - ["Role", "primary"] + - ["State", "Healthy"] + - ["Strategy", "spread"] + - ["Filters", "health, port, containerslots, dependency, affinity, constraint, whitelist"] + - ["Nodes", "2"] + - [" swarm-agent-00", "192.168.99.102:2376"] + - [" └ ID", "5CT6:FBGO:RVGO:CZL4:PB2K:WCYN:2JSV:KSHH:GGFW:QOPG:6J5Q:IOZ2|192.168.99.102:2376"] + - [" └ Status", "Healthy"] + - [" └ Containers", "1 (1 Running, 0 Paused, 0 Stopped)"] + - [" └ Reserved CPUs", "0 / 1"] + - [" └ Reserved Memory", "0 B / 1.021 GiB"] + - [" └ Labels", "kernelversion=4.4.74-boot2docker, operatingsystem=Boot2Docker 17.06.0-ce (TCL 7.2); HEAD : 0672754 - Thu Jun 29 00:06:31 UTC 2017, ostype=linux, provider=virtualbox, storagedriver=aufs"] + - [" └ UpdatedAt", "2017-08-09T10:03:46Z"] + - [" └ ServerVersion", "17.06.0-ce"] + - [" swarm-manager", "192.168.99.101:2376"] + - [" └ ID", "TAMD:7LL3:SEF7:LW2W:4Q2X:WVFH:RTXX:JSYS:XY2P:JEHL:ZMJK:JGIW|192.168.99.101:2376"] + - [" └ Status", "Healthy"] + - [" └ Containers", "2 (2 Running, 0 Paused, 0 Stopped)"] + - [" └ Reserved CPUs", "0 / 1"] + - [" └ Reserved Memory", "0 B / 1.021 GiB"] + - [" └ Labels", "kernelversion=4.4.74-boot2docker, operatingsystem=Boot2Docker 17.06.0-ce (TCL 7.2); HEAD : 0672754 - Thu Jun 29 00:06:31 UTC 2017, ostype=linux, provider=virtualbox, storagedriver=aufs"] + - [" └ UpdatedAt", "2017-08-09T10:04:11Z"] + - [" └ ServerVersion", "17.06.0-ce"] Plugins: $ref: "#/definitions/PluginsInfo" MemoryLimit: @@ -4059,17 +3998,6 @@ definitions: or "Windows Server 2016 Datacenter" type: "string" example: "Alpine Linux v3.5" - OSVersion: - description: | - Version of the host's operating system - -


- - > **Note**: The information returned in this field, including its - > very existence, and the formatting of values, should not be considered - > stable, and may change without notice. - type: "string" - example: "16.04" OSType: description: | Generic type of the operating system of the host, as returned by the @@ -4186,7 +4114,7 @@ definitions:


- > **Deprecated**: This field is only propagated when using standalone Swarm + > **Note**: This field is only propagated when using standalone Swarm > mode, and overlay networking using an external k/v store. Overlay > networks with Swarm mode enabled use the built-in raft store, and > this field will be empty. @@ -4200,7 +4128,7 @@ definitions:


- > **Deprecated**: This field is only propagated when using standalone Swarm + > **Note**: This field is only propagated when using standalone Swarm > mode, and overlay networking using an external k/v store. Overlay > networks with Swarm mode enabled use the built-in raft store, and > this field will be empty. @@ -5096,6 +5024,9 @@ paths: type: "string" LogPath: type: "string" + Node: + description: "TODO" + type: "object" Name: type: "string" RestartCount: @@ -9510,10 +9441,6 @@ paths: - `label=` - `mode=["replicated"|"global"]` - `name=` - - name: "status" - in: "query" - type: "boolean" - description: "Include service status, with count of running and desired tasks" tags: ["Service"] /services/create: post: diff --git a/vendor/github.com/docker/docker/api/types/client.go b/vendor/github.com/docker/docker/api/types/client.go index 9c464b73e2..fe90617eec 100644 --- a/vendor/github.com/docker/docker/api/types/client.go +++ b/vendor/github.com/docker/docker/api/types/client.go @@ -205,7 +205,7 @@ const ( // BuilderV1 is the first generation builder in docker daemon BuilderV1 BuilderVersion = "1" // BuilderBuildKit is builder based on moby/buildkit project - BuilderBuildKit BuilderVersion = "2" + BuilderBuildKit = "2" ) // ImageBuildResponse holds information @@ -265,7 +265,7 @@ type ImagePullOptions struct { // if the privilege request fails. type RequestPrivilegeFunc func() (string, error) -// ImagePushOptions holds information to push images. +//ImagePushOptions holds information to push images. type ImagePushOptions ImagePullOptions // ImageRemoveOptions holds parameters to remove images. @@ -363,10 +363,6 @@ type ServiceUpdateOptions struct { // ServiceListOptions holds parameters to list services with. type ServiceListOptions struct { Filters filters.Args - - // Status indicates whether the server should include the service task - // count of running and desired tasks. - Status bool } // ServiceInspectOptions holds parameters related to the "service inspect" diff --git a/vendor/github.com/docker/docker/api/types/container/container_changes.go b/vendor/github.com/docker/docker/api/types/container/container_changes.go index 16dd5019ee..222d141007 100644 --- a/vendor/github.com/docker/docker/api/types/container/container_changes.go +++ b/vendor/github.com/docker/docker/api/types/container/container_changes.go @@ -1,7 +1,8 @@ package container // import "github.com/docker/docker/api/types/container" // ---------------------------------------------------------------------------- -// Code generated by `swagger generate operation`. DO NOT EDIT. +// DO NOT EDIT THIS FILE +// This file was generated by `swagger generate operation` // // See hack/generate-swagger-api.sh // ---------------------------------------------------------------------------- diff --git a/vendor/github.com/docker/docker/api/types/container/container_create.go b/vendor/github.com/docker/docker/api/types/container/container_create.go index d0c852f84d..1ec9c3728b 100644 --- a/vendor/github.com/docker/docker/api/types/container/container_create.go +++ b/vendor/github.com/docker/docker/api/types/container/container_create.go @@ -1,7 +1,8 @@ package container // import "github.com/docker/docker/api/types/container" // ---------------------------------------------------------------------------- -// Code generated by `swagger generate operation`. DO NOT EDIT. +// DO NOT EDIT THIS FILE +// This file was generated by `swagger generate operation` // // See hack/generate-swagger-api.sh // ---------------------------------------------------------------------------- diff --git a/vendor/github.com/docker/docker/api/types/container/container_top.go b/vendor/github.com/docker/docker/api/types/container/container_top.go index f0ee9dde70..f8a606687c 100644 --- a/vendor/github.com/docker/docker/api/types/container/container_top.go +++ b/vendor/github.com/docker/docker/api/types/container/container_top.go @@ -1,7 +1,8 @@ package container // import "github.com/docker/docker/api/types/container" // ---------------------------------------------------------------------------- -// Code generated by `swagger generate operation`. DO NOT EDIT. +// DO NOT EDIT THIS FILE +// This file was generated by `swagger generate operation` // // See hack/generate-swagger-api.sh // ---------------------------------------------------------------------------- diff --git a/vendor/github.com/docker/docker/api/types/container/container_update.go b/vendor/github.com/docker/docker/api/types/container/container_update.go index c10f175ea8..33addedf77 100644 --- a/vendor/github.com/docker/docker/api/types/container/container_update.go +++ b/vendor/github.com/docker/docker/api/types/container/container_update.go @@ -1,7 +1,8 @@ package container // import "github.com/docker/docker/api/types/container" // ---------------------------------------------------------------------------- -// Code generated by `swagger generate operation`. DO NOT EDIT. +// DO NOT EDIT THIS FILE +// This file was generated by `swagger generate operation` // // See hack/generate-swagger-api.sh // ---------------------------------------------------------------------------- diff --git a/vendor/github.com/docker/docker/api/types/container/container_wait.go b/vendor/github.com/docker/docker/api/types/container/container_wait.go index 49e05ae669..94b6a20e15 100644 --- a/vendor/github.com/docker/docker/api/types/container/container_wait.go +++ b/vendor/github.com/docker/docker/api/types/container/container_wait.go @@ -1,7 +1,8 @@ package container // import "github.com/docker/docker/api/types/container" // ---------------------------------------------------------------------------- -// Code generated by `swagger generate operation`. DO NOT EDIT. +// DO NOT EDIT THIS FILE +// This file was generated by `swagger generate operation` // // See hack/generate-swagger-api.sh // ---------------------------------------------------------------------------- diff --git a/vendor/github.com/docker/docker/api/types/container/host_config.go b/vendor/github.com/docker/docker/api/types/container/host_config.go index b8a4b3aa62..c3de3d976a 100644 --- a/vendor/github.com/docker/docker/api/types/container/host_config.go +++ b/vendor/github.com/docker/docker/api/types/container/host_config.go @@ -7,32 +7,9 @@ import ( "github.com/docker/docker/api/types/mount" "github.com/docker/docker/api/types/strslice" "github.com/docker/go-connections/nat" - units "github.com/docker/go-units" + "github.com/docker/go-units" ) -// CgroupnsMode represents the cgroup namespace mode of the container -type CgroupnsMode string - -// IsPrivate indicates whether the container uses its own private cgroup namespace -func (c CgroupnsMode) IsPrivate() bool { - return c == "private" -} - -// IsHost indicates whether the container shares the host's cgroup namespace -func (c CgroupnsMode) IsHost() bool { - return c == "host" -} - -// IsEmpty indicates whether the container cgroup namespace mode is unset -func (c CgroupnsMode) IsEmpty() bool { - return c == "" -} - -// Valid indicates whether the cgroup namespace mode is valid -func (c CgroupnsMode) Valid() bool { - return c.IsEmpty() || c.IsPrivate() || c.IsHost() -} - // Isolation represents the isolation technology of a container. The supported // values are platform specific type Isolation string @@ -145,7 +122,7 @@ func (n NetworkMode) ConnectedContainer() string { return "" } -// UserDefined indicates user-created network +//UserDefined indicates user-created network func (n NetworkMode) UserDefined() string { if n.IsUserDefined() { return string(n) @@ -404,10 +381,9 @@ type HostConfig struct { CapAdd strslice.StrSlice // List of kernel capabilities to add to the container CapDrop strslice.StrSlice // List of kernel capabilities to remove from the container Capabilities []string `json:"Capabilities"` // List of kernel capabilities to be available for container (this overrides the default set) - CgroupnsMode CgroupnsMode // Cgroup namespace mode to use for the container - DNS []string `json:"Dns"` // List of DNS server to lookup - DNSOptions []string `json:"DnsOptions"` // List of DNSOption to look for - DNSSearch []string `json:"DnsSearch"` // List of DNSSearch to look for + DNS []string `json:"Dns"` // List of DNS server to lookup + DNSOptions []string `json:"DnsOptions"` // List of DNSOption to look for + DNSSearch []string `json:"DnsSearch"` // List of DNSSearch to look for ExtraHosts []string // List of extra hosts GroupAdd []string // List of additional groups that the container process will run as IpcMode IpcMode // IPC namespace to use for the container diff --git a/vendor/github.com/docker/docker/api/types/error_response_ext.go b/vendor/github.com/docker/docker/api/types/error_response_ext.go deleted file mode 100644 index f84f034cd5..0000000000 --- a/vendor/github.com/docker/docker/api/types/error_response_ext.go +++ /dev/null @@ -1,6 +0,0 @@ -package types - -// Error returns the error message -func (e ErrorResponse) Error() string { - return e.Message -} diff --git a/vendor/github.com/docker/docker/api/types/filters/parse.go b/vendor/github.com/docker/docker/api/types/filters/parse.go index 4bc91cffd6..0bd2e1e185 100644 --- a/vendor/github.com/docker/docker/api/types/filters/parse.go +++ b/vendor/github.com/docker/docker/api/types/filters/parse.go @@ -66,7 +66,7 @@ func ToJSON(a Args) (string, error) { // then the encoded format will use an older legacy format where the values are a // list of strings, instead of a set. // -// Deprecated: do not use in any new code; use ToJSON instead +// Deprecated: Use ToJSON func ToParamWithVersion(version string, a Args) (string, error) { if a.Len() == 0 { return "", nil @@ -154,7 +154,7 @@ func (args Args) Len() int { func (args Args) MatchKVList(key string, sources map[string]string) bool { fieldValues := args.fields[key] - // do not filter if there is no filter set or cannot determine filter + //do not filter if there is no filter set or cannot determine filter if len(fieldValues) == 0 { return true } @@ -200,7 +200,7 @@ func (args Args) Match(field, source string) bool { // ExactMatch returns true if the source matches exactly one of the values. func (args Args) ExactMatch(key, source string) bool { fieldValues, ok := args.fields[key] - // do not filter if there is no filter set or cannot determine filter + //do not filter if there is no filter set or cannot determine filter if !ok || len(fieldValues) == 0 { return true } @@ -213,7 +213,7 @@ func (args Args) ExactMatch(key, source string) bool { // matches exactly the value. func (args Args) UniqueExactMatch(key, source string) bool { fieldValues := args.fields[key] - // do not filter if there is no filter set or cannot determine filter + //do not filter if there is no filter set or cannot determine filter if len(fieldValues) == 0 { return true } diff --git a/vendor/github.com/docker/docker/api/types/image/image_history.go b/vendor/github.com/docker/docker/api/types/image/image_history.go index e302bb0aeb..b5a7a0c490 100644 --- a/vendor/github.com/docker/docker/api/types/image/image_history.go +++ b/vendor/github.com/docker/docker/api/types/image/image_history.go @@ -1,7 +1,8 @@ package image // import "github.com/docker/docker/api/types/image" // ---------------------------------------------------------------------------- -// Code generated by `swagger generate operation`. DO NOT EDIT. +// DO NOT EDIT THIS FILE +// This file was generated by `swagger generate operation` // // See hack/generate-swagger-api.sh // ---------------------------------------------------------------------------- diff --git a/vendor/github.com/docker/docker/api/types/network/network.go b/vendor/github.com/docker/docker/api/types/network/network.go index 7927dbfffb..71e97338fd 100644 --- a/vendor/github.com/docker/docker/api/types/network/network.go +++ b/vendor/github.com/docker/docker/api/types/network/network.go @@ -13,7 +13,7 @@ type Address struct { // IPAM represents IP Address Management type IPAM struct { Driver string - Options map[string]string // Per network IPAM driver options + Options map[string]string //Per network IPAM driver options Config []IPAMConfig } diff --git a/vendor/github.com/docker/docker/api/types/registry/registry.go b/vendor/github.com/docker/docker/api/types/registry/registry.go index 53e47084c8..8789ad3b32 100644 --- a/vendor/github.com/docker/docker/api/types/registry/registry.go +++ b/vendor/github.com/docker/docker/api/types/registry/registry.go @@ -4,7 +4,7 @@ import ( "encoding/json" "net" - v1 "github.com/opencontainers/image-spec/specs-go/v1" + "github.com/opencontainers/image-spec/specs-go/v1" ) // ServiceConfig stores daemon registry services configuration. diff --git a/vendor/github.com/docker/docker/api/types/swarm/container.go b/vendor/github.com/docker/docker/api/types/swarm/container.go index 5bbedfcf68..48190c1762 100644 --- a/vendor/github.com/docker/docker/api/types/swarm/container.go +++ b/vendor/github.com/docker/docker/api/types/swarm/container.go @@ -67,11 +67,10 @@ type ContainerSpec struct { // The format of extra hosts on swarmkit is specified in: // http://man7.org/linux/man-pages/man5/hosts.5.html // IP_address canonical_hostname [aliases...] - Hosts []string `json:",omitempty"` - DNSConfig *DNSConfig `json:",omitempty"` - Secrets []*SecretReference `json:",omitempty"` - Configs []*ConfigReference `json:",omitempty"` - Isolation container.Isolation `json:",omitempty"` - Sysctls map[string]string `json:",omitempty"` - Capabilities []string `json:",omitempty"` + Hosts []string `json:",omitempty"` + DNSConfig *DNSConfig `json:",omitempty"` + Secrets []*SecretReference `json:",omitempty"` + Configs []*ConfigReference `json:",omitempty"` + Isolation container.Isolation `json:",omitempty"` + Sysctls map[string]string `json:",omitempty"` } diff --git a/vendor/github.com/docker/docker/api/types/swarm/runtime/plugin.pb.go b/vendor/github.com/docker/docker/api/types/swarm/runtime/plugin.pb.go index e45045866a..1fdc9b0436 100644 --- a/vendor/github.com/docker/docker/api/types/swarm/runtime/plugin.pb.go +++ b/vendor/github.com/docker/docker/api/types/swarm/runtime/plugin.pb.go @@ -1,5 +1,6 @@ -// Code generated by protoc-gen-gogo. DO NOT EDIT. +// Code generated by protoc-gen-gogo. // source: plugin.proto +// DO NOT EDIT! /* Package runtime is a generated protocol buffer package. @@ -37,7 +38,6 @@ type PluginSpec struct { Remote string `protobuf:"bytes,2,opt,name=remote,proto3" json:"remote,omitempty"` Privileges []*PluginPrivilege `protobuf:"bytes,3,rep,name=privileges" json:"privileges,omitempty"` Disabled bool `protobuf:"varint,4,opt,name=disabled,proto3" json:"disabled,omitempty"` - Env []string `protobuf:"bytes,5,rep,name=env" json:"env,omitempty"` } func (m *PluginSpec) Reset() { *m = PluginSpec{} } @@ -73,13 +73,6 @@ func (m *PluginSpec) GetDisabled() bool { return false } -func (m *PluginSpec) GetEnv() []string { - if m != nil { - return m.Env - } - return nil -} - // PluginPrivilege describes a permission the user has to accept // upon installing a plugin. type PluginPrivilege struct { @@ -167,21 +160,6 @@ func (m *PluginSpec) MarshalTo(dAtA []byte) (int, error) { } i++ } - if len(m.Env) > 0 { - for _, s := range m.Env { - dAtA[i] = 0x2a - i++ - l = len(s) - for l >= 1<<7 { - dAtA[i] = uint8(uint64(l)&0x7f | 0x80) - l >>= 7 - i++ - } - dAtA[i] = uint8(l) - i++ - i += copy(dAtA[i:], s) - } - } return i, nil } @@ -230,6 +208,24 @@ func (m *PluginPrivilege) MarshalTo(dAtA []byte) (int, error) { return i, nil } +func encodeFixed64Plugin(dAtA []byte, offset int, v uint64) int { + dAtA[offset] = uint8(v) + dAtA[offset+1] = uint8(v >> 8) + dAtA[offset+2] = uint8(v >> 16) + dAtA[offset+3] = uint8(v >> 24) + dAtA[offset+4] = uint8(v >> 32) + dAtA[offset+5] = uint8(v >> 40) + dAtA[offset+6] = uint8(v >> 48) + dAtA[offset+7] = uint8(v >> 56) + return offset + 8 +} +func encodeFixed32Plugin(dAtA []byte, offset int, v uint32) int { + dAtA[offset] = uint8(v) + dAtA[offset+1] = uint8(v >> 8) + dAtA[offset+2] = uint8(v >> 16) + dAtA[offset+3] = uint8(v >> 24) + return offset + 4 +} func encodeVarintPlugin(dAtA []byte, offset int, v uint64) int { for v >= 1<<7 { dAtA[offset] = uint8(v&0x7f | 0x80) @@ -259,12 +255,6 @@ func (m *PluginSpec) Size() (n int) { if m.Disabled { n += 2 } - if len(m.Env) > 0 { - for _, s := range m.Env { - l = len(s) - n += 1 + l + sovPlugin(uint64(l)) - } - } return n } @@ -439,35 +429,6 @@ func (m *PluginSpec) Unmarshal(dAtA []byte) error { } } m.Disabled = bool(v != 0) - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Env", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowPlugin - } - 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 ErrInvalidLengthPlugin - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Env = append(m.Env, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipPlugin(dAtA[iNdEx:]) @@ -734,21 +695,18 @@ var ( func init() { proto.RegisterFile("plugin.proto", fileDescriptorPlugin) } var fileDescriptorPlugin = []byte{ - // 256 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x90, 0x4d, 0x4b, 0xc3, 0x30, - 0x18, 0xc7, 0x89, 0xdd, 0xc6, 0xfa, 0x4c, 0x70, 0x04, 0x91, 0xe2, 0xa1, 0x94, 0x9d, 0x7a, 0x6a, - 0x45, 0x2f, 0x82, 0x37, 0x0f, 0x9e, 0x47, 0xbc, 0x09, 0x1e, 0xd2, 0xf6, 0xa1, 0x06, 0x9b, 0x17, - 0x92, 0xb4, 0xe2, 0x37, 0xf1, 0x23, 0x79, 0xf4, 0x23, 0x48, 0x3f, 0x89, 0x98, 0x75, 0x32, 0x64, - 0xa7, 0xff, 0x4b, 0xc2, 0x9f, 0x1f, 0x0f, 0x9c, 0x9a, 0xae, 0x6f, 0x85, 0x2a, 0x8c, 0xd5, 0x5e, - 0x6f, 0x3e, 0x08, 0xc0, 0x36, 0x14, 0x8f, 0x06, 0x6b, 0x4a, 0x61, 0xa6, 0xb8, 0xc4, 0x84, 0x64, - 0x24, 0x8f, 0x59, 0xf0, 0xf4, 0x02, 0x16, 0x16, 0xa5, 0xf6, 0x98, 0x9c, 0x84, 0x76, 0x4a, 0xf4, - 0x0a, 0xc0, 0x58, 0x31, 0x88, 0x0e, 0x5b, 0x74, 0x49, 0x94, 0x45, 0xf9, 0xea, 0x7a, 0x5d, 0xec, - 0xc6, 0xb6, 0xfb, 0x07, 0x76, 0xf0, 0x87, 0x5e, 0xc2, 0xb2, 0x11, 0x8e, 0x57, 0x1d, 0x36, 0xc9, - 0x2c, 0x23, 0xf9, 0x92, 0xfd, 0x65, 0xba, 0x86, 0x08, 0xd5, 0x90, 0xcc, 0xb3, 0x28, 0x8f, 0xd9, - 0xaf, 0xdd, 0x3c, 0xc3, 0xd9, 0xbf, 0xb1, 0xa3, 0x78, 0x19, 0xac, 0x1a, 0x74, 0xb5, 0x15, 0xc6, - 0x0b, 0xad, 0x26, 0xc6, 0xc3, 0x8a, 0x9e, 0xc3, 0x7c, 0xe0, 0x5d, 0x8f, 0x81, 0x31, 0x66, 0xbb, - 0x70, 0xff, 0xf0, 0x39, 0xa6, 0xe4, 0x6b, 0x4c, 0xc9, 0xf7, 0x98, 0x92, 0xa7, 0xdb, 0x56, 0xf8, - 0x97, 0xbe, 0x2a, 0x6a, 0x2d, 0xcb, 0x46, 0xd7, 0xaf, 0x68, 0xf7, 0xc2, 0x8d, 0x28, 0xfd, 0xbb, - 0x41, 0x57, 0xba, 0x37, 0x6e, 0x65, 0x69, 0x7b, 0xe5, 0x85, 0xc4, 0xbb, 0x49, 0xab, 0x45, 0x38, - 0xe4, 0xcd, 0x4f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x99, 0xa8, 0xd9, 0x9b, 0x58, 0x01, 0x00, 0x00, + // 196 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xe2, 0x29, 0xc8, 0x29, 0x4d, + 0xcf, 0xcc, 0xd3, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x57, 0x6a, 0x63, 0xe4, 0xe2, 0x0a, 0x00, 0x0b, + 0x04, 0x17, 0xa4, 0x26, 0x0b, 0x09, 0x71, 0xb1, 0xe4, 0x25, 0xe6, 0xa6, 0x4a, 0x30, 0x2a, 0x30, + 0x6a, 0x70, 0x06, 0x81, 0xd9, 0x42, 0x62, 0x5c, 0x6c, 0x45, 0xa9, 0xb9, 0xf9, 0x25, 0xa9, 0x12, + 0x4c, 0x60, 0x51, 0x28, 0x4f, 0xc8, 0x80, 0x8b, 0xab, 0xa0, 0x28, 0xb3, 0x2c, 0x33, 0x27, 0x35, + 0x3d, 0xb5, 0x58, 0x82, 0x59, 0x81, 0x59, 0x83, 0xdb, 0x48, 0x40, 0x0f, 0x62, 0x58, 0x00, 0x4c, + 0x22, 0x08, 0x49, 0x8d, 0x90, 0x14, 0x17, 0x47, 0x4a, 0x66, 0x71, 0x62, 0x52, 0x4e, 0x6a, 0x8a, + 0x04, 0x8b, 0x02, 0xa3, 0x06, 0x47, 0x10, 0x9c, 0xaf, 0x14, 0xcb, 0xc5, 0x8f, 0xa6, 0x15, 0xab, + 0x63, 0x14, 0xb8, 0xb8, 0x53, 0x52, 0x8b, 0x93, 0x8b, 0x32, 0x0b, 0x4a, 0x32, 0xf3, 0xf3, 0xa0, + 0x2e, 0x42, 0x16, 0x12, 0x12, 0xe1, 0x62, 0x2d, 0x4b, 0xcc, 0x29, 0x4d, 0x05, 0xbb, 0x88, 0x33, + 0x08, 0xc2, 0x71, 0xe2, 0x39, 0xf1, 0x48, 0x8e, 0xf1, 0xc2, 0x23, 0x39, 0xc6, 0x07, 0x8f, 0xe4, + 0x18, 0x93, 0xd8, 0xc0, 0x9e, 0x37, 0x06, 0x04, 0x00, 0x00, 0xff, 0xff, 0xb8, 0x84, 0xad, 0x79, + 0x0c, 0x01, 0x00, 0x00, } diff --git a/vendor/github.com/docker/docker/api/types/swarm/runtime/plugin.proto b/vendor/github.com/docker/docker/api/types/swarm/runtime/plugin.proto index 9ef169046b..6d63b7783f 100644 --- a/vendor/github.com/docker/docker/api/types/swarm/runtime/plugin.proto +++ b/vendor/github.com/docker/docker/api/types/swarm/runtime/plugin.proto @@ -9,7 +9,6 @@ message PluginSpec { string remote = 2; repeated PluginPrivilege privileges = 3; bool disabled = 4; - repeated string env = 5; } // PluginPrivilege describes a permission the user has to accept diff --git a/vendor/github.com/docker/docker/api/types/swarm/service.go b/vendor/github.com/docker/docker/api/types/swarm/service.go index 6eb452d24d..abf192e759 100644 --- a/vendor/github.com/docker/docker/api/types/swarm/service.go +++ b/vendor/github.com/docker/docker/api/types/swarm/service.go @@ -10,17 +10,6 @@ type Service struct { PreviousSpec *ServiceSpec `json:",omitempty"` Endpoint Endpoint `json:",omitempty"` UpdateStatus *UpdateStatus `json:",omitempty"` - - // ServiceStatus is an optional, extra field indicating the number of - // desired and running tasks. It is provided primarily as a shortcut to - // calculating these values client-side, which otherwise would require - // listing all tasks for a service, an operation that could be - // computation and network expensive. - ServiceStatus *ServiceStatus `json:",omitempty"` - - // JobStatus is the status of a Service which is in one of ReplicatedJob or - // GlobalJob modes. It is absent on Replicated and Global services. - JobStatus *JobStatus `json:",omitempty"` } // ServiceSpec represents the spec of a service. @@ -43,10 +32,8 @@ type ServiceSpec struct { // ServiceMode represents the mode of a service. type ServiceMode struct { - Replicated *ReplicatedService `json:",omitempty"` - Global *GlobalService `json:",omitempty"` - ReplicatedJob *ReplicatedJob `json:",omitempty"` - GlobalJob *GlobalJob `json:",omitempty"` + Replicated *ReplicatedService `json:",omitempty"` + Global *GlobalService `json:",omitempty"` } // UpdateState is the state of a service update. @@ -83,32 +70,6 @@ type ReplicatedService struct { // GlobalService is a kind of ServiceMode. type GlobalService struct{} -// ReplicatedJob is the a type of Service which executes a defined Tasks -// in parallel until the specified number of Tasks have succeeded. -type ReplicatedJob struct { - // MaxConcurrent indicates the maximum number of Tasks that should be - // executing simultaneously for this job at any given time. There may be - // fewer Tasks that MaxConcurrent executing simultaneously; for example, if - // there are fewer than MaxConcurrent tasks needed to reach - // TotalCompletions. - // - // If this field is empty, it will default to a max concurrency of 1. - MaxConcurrent *uint64 `json:",omitempty"` - - // TotalCompletions is the total number of Tasks desired to run to - // completion. - // - // If this field is empty, the value of MaxConcurrent will be used. - TotalCompletions *uint64 `json:",omitempty"` -} - -// GlobalJob is the type of a Service which executes a Task on every Node -// matching the Service's placement constraints. These tasks run to completion -// and then exit. -// -// This type is deliberately empty. -type GlobalJob struct{} - const ( // UpdateFailureActionPause PAUSE UpdateFailureActionPause = "pause" @@ -161,42 +122,3 @@ type UpdateConfig struct { // started, or the new task is started before the old task is shut down. Order string } - -// ServiceStatus represents the number of running tasks in a service and the -// number of tasks desired to be running. -type ServiceStatus struct { - // RunningTasks is the number of tasks for the service actually in the - // Running state - RunningTasks uint64 - - // DesiredTasks is the number of tasks desired to be running by the - // service. For replicated services, this is the replica count. For global - // services, this is computed by taking the number of tasks with desired - // state of not-Shutdown. - DesiredTasks uint64 - - // CompletedTasks is the number of tasks in the state Completed, if this - // service is in ReplicatedJob or GlobalJob mode. This field must be - // cross-referenced with the service type, because the default value of 0 - // may mean that a service is not in a job mode, or it may mean that the - // job has yet to complete any tasks. - CompletedTasks uint64 -} - -// JobStatus is the status of a job-type service. -type JobStatus struct { - // JobIteration is a value increased each time a Job is executed, - // successfully or otherwise. "Executed", in this case, means the job as a - // whole has been started, not that an individual Task has been launched. A - // job is "Executed" when its ServiceSpec is updated. JobIteration can be - // used to disambiguate Tasks belonging to different executions of a job. - // - // Though JobIteration will increase with each subsequent execution, it may - // not necessarily increase by 1, and so JobIteration should not be used to - // keep track of the number of times a job has been executed. - JobIteration Version - - // LastExecution is the time that the job was last executed, as observed by - // Swarm manager. - LastExecution time.Time `json:",omitempty"` -} diff --git a/vendor/github.com/docker/docker/api/types/swarm/task.go b/vendor/github.com/docker/docker/api/types/swarm/task.go index 9f193df37c..d5a57df5db 100644 --- a/vendor/github.com/docker/docker/api/types/swarm/task.go +++ b/vendor/github.com/docker/docker/api/types/swarm/task.go @@ -56,12 +56,6 @@ type Task struct { DesiredState TaskState `json:",omitempty"` NetworksAttachments []NetworkAttachment `json:",omitempty"` GenericResources []GenericResource `json:",omitempty"` - - // JobIteration is the JobIteration of the Service that this Task was - // spawned from, if the Service is a ReplicatedJob or GlobalJob. This is - // used to determine which Tasks belong to which run of the job. This field - // is absent if the Service mode is Replicated or Global. - JobIteration *Version `json:",omitempty"` } // TaskSpec represents the spec of a task. diff --git a/vendor/github.com/docker/docker/api/types/types.go b/vendor/github.com/docker/docker/api/types/types.go index 79e6dd8436..a39ffcb7be 100644 --- a/vendor/github.com/docker/docker/api/types/types.go +++ b/vendor/github.com/docker/docker/api/types/types.go @@ -39,7 +39,6 @@ type ImageInspect struct { Author string Config *container.Config Architecture string - Variant string `json:",omitempty"` Os string OsVersion string `json:",omitempty"` Size int64 @@ -154,7 +153,7 @@ type Info struct { Images int Driver string DriverStatus [][2]string - SystemStatus [][2]string `json:",omitempty"` // SystemStatus is only propagated by the Swarm standalone API + SystemStatus [][2]string Plugins PluginsInfo MemoryLimit bool SwapLimit bool @@ -178,7 +177,6 @@ type Info struct { NEventsListener int KernelVersion string OperatingSystem string - OSVersion string OSType string Architecture string IndexServerAddress string @@ -194,8 +192,8 @@ type Info struct { Labels []string ExperimentalBuild bool ServerVersion string - ClusterStore string `json:",omitempty"` // Deprecated: host-discovery and overlay networks with external k/v stores are deprecated - ClusterAdvertise string `json:",omitempty"` // Deprecated: host-discovery and overlay networks with external k/v stores are deprecated + ClusterStore string + ClusterAdvertise string Runtimes map[string]Runtime DefaultRuntime string Swarm swarm.Info @@ -318,7 +316,7 @@ type ContainerState struct { } // ContainerNode stores information about the node that a container -// is running on. It's only used by the Docker Swarm standalone API +// is running on. It's only available in Docker Swarm type ContainerNode struct { ID string IPAddress string `json:"IP"` @@ -342,7 +340,7 @@ type ContainerJSONBase struct { HostnamePath string HostsPath string LogPath string - Node *ContainerNode `json:",omitempty"` // Node is only propagated by Docker Swarm standalone API + Node *ContainerNode `json:",omitempty"` Name string RestartCount int Driver string diff --git a/vendor/github.com/docker/docker/api/types/volume/volume_create.go b/vendor/github.com/docker/docker/api/types/volume/volume_create.go index 0d4f46a846..0c3772d3ad 100644 --- a/vendor/github.com/docker/docker/api/types/volume/volume_create.go +++ b/vendor/github.com/docker/docker/api/types/volume/volume_create.go @@ -1,7 +1,8 @@ package volume // import "github.com/docker/docker/api/types/volume" // ---------------------------------------------------------------------------- -// Code generated by `swagger generate operation`. DO NOT EDIT. +// DO NOT EDIT THIS FILE +// This file was generated by `swagger generate operation` // // See hack/generate-swagger-api.sh // ---------------------------------------------------------------------------- diff --git a/vendor/github.com/docker/docker/api/types/volume/volume_list.go b/vendor/github.com/docker/docker/api/types/volume/volume_list.go index 8e685d51c9..45c3c1c9ae 100644 --- a/vendor/github.com/docker/docker/api/types/volume/volume_list.go +++ b/vendor/github.com/docker/docker/api/types/volume/volume_list.go @@ -1,7 +1,8 @@ package volume // import "github.com/docker/docker/api/types/volume" // ---------------------------------------------------------------------------- -// Code generated by `swagger generate operation`. DO NOT EDIT. +// DO NOT EDIT THIS FILE +// This file was generated by `swagger generate operation` // // See hack/generate-swagger-api.sh // ---------------------------------------------------------------------------- diff --git a/vendor/github.com/docker/docker/client/client.go b/vendor/github.com/docker/docker/client/client.go index 0649a69cc7..b63d4d6d49 100644 --- a/vendor/github.com/docker/docker/client/client.go +++ b/vendor/github.com/docker/docker/client/client.go @@ -252,8 +252,7 @@ func (cli *Client) DaemonHost() string { // HTTPClient returns a copy of the HTTP client bound to the server func (cli *Client) HTTPClient() *http.Client { - c := *cli.client - return &c + return &*cli.client } // ParseHostURL parses a url string, validates the string is a host url, and diff --git a/vendor/github.com/docker/docker/client/client_unix.go b/vendor/github.com/docker/docker/client/client_unix.go index 23c2e1e344..3d24470ba3 100644 --- a/vendor/github.com/docker/docker/client/client_unix.go +++ b/vendor/github.com/docker/docker/client/client_unix.go @@ -1,4 +1,4 @@ -// +build linux freebsd openbsd darwin solaris illumos +// +build linux freebsd openbsd darwin package client // import "github.com/docker/docker/client" diff --git a/vendor/github.com/docker/docker/client/container_list.go b/vendor/github.com/docker/docker/client/container_list.go index a973de597f..1e7a63a9c0 100644 --- a/vendor/github.com/docker/docker/client/container_list.go +++ b/vendor/github.com/docker/docker/client/container_list.go @@ -35,7 +35,6 @@ func (cli *Client) ContainerList(ctx context.Context, options types.ContainerLis } if options.Filters.Len() > 0 { - //nolint:staticcheck // ignore SA1019 for old code filterJSON, err := filters.ToParamWithVersion(cli.version, options.Filters) if err != nil { diff --git a/vendor/github.com/docker/docker/client/events.go b/vendor/github.com/docker/docker/client/events.go index f0dc9d9e12..6e56538955 100644 --- a/vendor/github.com/docker/docker/client/events.go +++ b/vendor/github.com/docker/docker/client/events.go @@ -90,7 +90,6 @@ func buildEventsQueryParams(cliVersion string, options types.EventsOptions) (url } if options.Filters.Len() > 0 { - //nolint:staticcheck // ignore SA1019 for old code filterJSON, err := filters.ToParamWithVersion(cliVersion, options.Filters) if err != nil { return nil, err diff --git a/vendor/github.com/docker/docker/client/hijack.go b/vendor/github.com/docker/docker/client/hijack.go index e1dc49ef0f..e9c9a752f8 100644 --- a/vendor/github.com/docker/docker/client/hijack.go +++ b/vendor/github.com/docker/docker/client/hijack.go @@ -24,7 +24,7 @@ func (cli *Client) postHijacked(ctx context.Context, path string, query url.Valu } apiPath := cli.getAPIPath(ctx, path, query) - req, err := http.NewRequest(http.MethodPost, apiPath, bodyEncoded) + req, err := http.NewRequest("POST", apiPath, bodyEncoded) if err != nil { return types.HijackedResponse{}, err } @@ -40,7 +40,7 @@ func (cli *Client) postHijacked(ctx context.Context, path string, query url.Valu // DialHijack returns a hijacked connection with negotiated protocol proto. func (cli *Client) DialHijack(ctx context.Context, url, proto string, meta map[string][]string) (net.Conn, error) { - req, err := http.NewRequest(http.MethodPost, url, nil) + req, err := http.NewRequest("POST", url, nil) if err != nil { return nil, err } @@ -87,8 +87,6 @@ func (cli *Client) setupHijackConn(ctx context.Context, req *http.Request, proto // Server hijacks the connection, error 'connection closed' expected resp, err := clientconn.Do(req) - - //nolint:staticcheck // ignore SA1019 for connecting to old (pre go1.8) daemons if err != httputil.ErrPersistEOF { if err != nil { return nil, err diff --git a/vendor/github.com/docker/docker/client/image_import.go b/vendor/github.com/docker/docker/client/image_import.go index d3336d4106..c2972ea950 100644 --- a/vendor/github.com/docker/docker/client/image_import.go +++ b/vendor/github.com/docker/docker/client/image_import.go @@ -14,7 +14,7 @@ import ( // It returns the JSON content in the response body. func (cli *Client) ImageImport(ctx context.Context, source types.ImageImportSource, ref string, options types.ImageImportOptions) (io.ReadCloser, error) { if ref != "" { - // Check if the given image name can be resolved + //Check if the given image name can be resolved if _, err := reference.ParseNormalizedNamed(ref); err != nil { return nil, err } diff --git a/vendor/github.com/docker/docker/client/image_list.go b/vendor/github.com/docker/docker/client/image_list.go index a4d7505094..4fa8c006b2 100644 --- a/vendor/github.com/docker/docker/client/image_list.go +++ b/vendor/github.com/docker/docker/client/image_list.go @@ -24,7 +24,6 @@ func (cli *Client) ImageList(ctx context.Context, options types.ImageListOptions } } if optionFilters.Len() > 0 { - //nolint:staticcheck // ignore SA1019 for old code filterJSON, err := filters.ToParamWithVersion(cli.version, optionFilters) if err != nil { return images, err diff --git a/vendor/github.com/docker/docker/client/image_push.go b/vendor/github.com/docker/docker/client/image_push.go index 845580d4a4..49d412ee37 100644 --- a/vendor/github.com/docker/docker/client/image_push.go +++ b/vendor/github.com/docker/docker/client/image_push.go @@ -25,15 +25,16 @@ func (cli *Client) ImagePush(ctx context.Context, image string, options types.Im return nil, errors.New("cannot push a digest reference") } + tag := "" name := reference.FamiliarName(ref) - query := url.Values{} - if !options.All { - ref = reference.TagNameOnly(ref) - if tagged, ok := ref.(reference.Tagged); ok { - query.Set("tag", tagged.Tag()) - } + + if nameTaggedRef, isNamedTagged := ref.(reference.NamedTagged); isNamedTagged { + tag = nameTaggedRef.Tag() } + query := url.Values{} + query.Set("tag", tag) + resp, err := cli.tryImagePush(ctx, name, query, options.RegistryAuth) if errdefs.IsUnauthorized(err) && options.PrivilegeFunc != nil { newAuthHeader, privilegeErr := options.PrivilegeFunc() diff --git a/vendor/github.com/docker/docker/client/network_list.go b/vendor/github.com/docker/docker/client/network_list.go index ed2acb5571..7130c1364e 100644 --- a/vendor/github.com/docker/docker/client/network_list.go +++ b/vendor/github.com/docker/docker/client/network_list.go @@ -13,7 +13,6 @@ import ( func (cli *Client) NetworkList(ctx context.Context, options types.NetworkListOptions) ([]types.NetworkResource, error) { query := url.Values{} if options.Filters.Len() > 0 { - //nolint:staticcheck // ignore SA1019 for old code filterJSON, err := filters.ToParamWithVersion(cli.version, options.Filters) if err != nil { return nil, err diff --git a/vendor/github.com/docker/docker/client/ping.go b/vendor/github.com/docker/docker/client/ping.go index a9af001ef4..90f39ec14f 100644 --- a/vendor/github.com/docker/docker/client/ping.go +++ b/vendor/github.com/docker/docker/client/ping.go @@ -17,9 +17,9 @@ func (cli *Client) Ping(ctx context.Context) (types.Ping, error) { var ping types.Ping // Using cli.buildRequest() + cli.doRequest() instead of cli.sendRequest() - // because ping requests are used during API version negotiation, so we want + // because ping requests are used during API version negotiation, so we want // to hit the non-versioned /_ping endpoint, not /v1.xx/_ping - req, err := cli.buildRequest(http.MethodHead, path.Join(cli.basePath, "/_ping"), nil, nil) + req, err := cli.buildRequest("HEAD", path.Join(cli.basePath, "/_ping"), nil, nil) if err != nil { return ping, err } @@ -35,7 +35,7 @@ func (cli *Client) Ping(ctx context.Context) (types.Ping, error) { return ping, err } - req, err = cli.buildRequest(http.MethodGet, path.Join(cli.basePath, "/_ping"), nil, nil) + req, err = cli.buildRequest("GET", path.Join(cli.basePath, "/_ping"), nil, nil) if err != nil { return ping, err } diff --git a/vendor/github.com/docker/docker/client/plugin_list.go b/vendor/github.com/docker/docker/client/plugin_list.go index cf1935e2f5..8285cecd6e 100644 --- a/vendor/github.com/docker/docker/client/plugin_list.go +++ b/vendor/github.com/docker/docker/client/plugin_list.go @@ -15,7 +15,6 @@ func (cli *Client) PluginList(ctx context.Context, filter filters.Args) (types.P query := url.Values{} if filter.Len() > 0 { - //nolint:staticcheck // ignore SA1019 for old code filterJSON, err := filters.ToParamWithVersion(cli.version, filter) if err != nil { return plugins, err diff --git a/vendor/github.com/docker/docker/client/request.go b/vendor/github.com/docker/docker/client/request.go index ee15a46ed0..2610338da6 100644 --- a/vendor/github.com/docker/docker/client/request.go +++ b/vendor/github.com/docker/docker/client/request.go @@ -29,12 +29,12 @@ type serverResponse struct { // head sends an http request to the docker API using the method HEAD. func (cli *Client) head(ctx context.Context, path string, query url.Values, headers map[string][]string) (serverResponse, error) { - return cli.sendRequest(ctx, http.MethodHead, path, query, nil, headers) + return cli.sendRequest(ctx, "HEAD", path, query, nil, headers) } // get sends an http request to the docker API using the method GET with a specific Go context. func (cli *Client) get(ctx context.Context, path string, query url.Values, headers map[string][]string) (serverResponse, error) { - return cli.sendRequest(ctx, http.MethodGet, path, query, nil, headers) + return cli.sendRequest(ctx, "GET", path, query, nil, headers) } // post sends an http request to the docker API using the method POST with a specific Go context. @@ -43,21 +43,30 @@ func (cli *Client) post(ctx context.Context, path string, query url.Values, obj if err != nil { return serverResponse{}, err } - return cli.sendRequest(ctx, http.MethodPost, path, query, body, headers) + return cli.sendRequest(ctx, "POST", path, query, body, headers) } func (cli *Client) postRaw(ctx context.Context, path string, query url.Values, body io.Reader, headers map[string][]string) (serverResponse, error) { - return cli.sendRequest(ctx, http.MethodPost, path, query, body, headers) + return cli.sendRequest(ctx, "POST", path, query, body, headers) +} + +// put sends an http request to the docker API using the method PUT. +func (cli *Client) put(ctx context.Context, path string, query url.Values, obj interface{}, headers map[string][]string) (serverResponse, error) { + body, headers, err := encodeBody(obj, headers) + if err != nil { + return serverResponse{}, err + } + return cli.sendRequest(ctx, "PUT", path, query, body, headers) } // putRaw sends an http request to the docker API using the method PUT. func (cli *Client) putRaw(ctx context.Context, path string, query url.Values, body io.Reader, headers map[string][]string) (serverResponse, error) { - return cli.sendRequest(ctx, http.MethodPut, path, query, body, headers) + return cli.sendRequest(ctx, "PUT", path, query, body, headers) } // delete sends an http request to the docker API using the method DELETE. func (cli *Client) delete(ctx context.Context, path string, query url.Values, headers map[string][]string) (serverResponse, error) { - return cli.sendRequest(ctx, http.MethodDelete, path, query, nil, headers) + return cli.sendRequest(ctx, "DELETE", path, query, nil, headers) } type headers map[string][]string @@ -79,7 +88,7 @@ func encodeBody(obj interface{}, headers headers) (io.Reader, headers, error) { } func (cli *Client) buildRequest(method, path string, body io.Reader, headers headers) (*http.Request, error) { - expectedPayload := (method == http.MethodPost || method == http.MethodPut) + expectedPayload := (method == "POST" || method == "PUT") if expectedPayload && body == nil { body = bytes.NewReader([]byte{}) } diff --git a/vendor/github.com/docker/docker/client/service_create.go b/vendor/github.com/docker/docker/client/service_create.go index 56bfe55b71..620fc6cff7 100644 --- a/vendor/github.com/docker/docker/client/service_create.go +++ b/vendor/github.com/docker/docker/client/service_create.go @@ -9,7 +9,7 @@ import ( "github.com/docker/distribution/reference" "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/swarm" - digest "github.com/opencontainers/go-digest" + "github.com/opencontainers/go-digest" "github.com/pkg/errors" ) diff --git a/vendor/github.com/docker/docker/client/service_list.go b/vendor/github.com/docker/docker/client/service_list.go index f97ec75a5c..64d35e7159 100644 --- a/vendor/github.com/docker/docker/client/service_list.go +++ b/vendor/github.com/docker/docker/client/service_list.go @@ -23,10 +23,6 @@ func (cli *Client) ServiceList(ctx context.Context, options types.ServiceListOpt query.Set("filters", filterJSON) } - if options.Status { - query.Set("status", "true") - } - resp, err := cli.get(ctx, "/services", query, nil) defer ensureReaderClosed(resp) if err != nil { diff --git a/vendor/github.com/docker/docker/client/volume_list.go b/vendor/github.com/docker/docker/client/volume_list.go index 942498dde2..2380d56382 100644 --- a/vendor/github.com/docker/docker/client/volume_list.go +++ b/vendor/github.com/docker/docker/client/volume_list.go @@ -15,7 +15,6 @@ func (cli *Client) VolumeList(ctx context.Context, filter filters.Args) (volumet query := url.Values{} if filter.Len() > 0 { - //nolint:staticcheck // ignore SA1019 for old code filterJSON, err := filters.ToParamWithVersion(cli.version, filter) if err != nil { return volumes, err diff --git a/vendor/github.com/docker/docker/pkg/archive/archive.go b/vendor/github.com/docker/docker/pkg/archive/archive.go index 86f5c02b7a..bb623fa856 100644 --- a/vendor/github.com/docker/docker/pkg/archive/archive.go +++ b/vendor/github.com/docker/docker/pkg/archive/archive.go @@ -442,7 +442,7 @@ func newTarAppender(idMapping *idtools.IdentityMapping, writer io.Writer, chownO } // canonicalTarName provides a platform-independent and consistent posix-style -// path for files and directories to be archived regardless of the platform. +//path for files and directories to be archived regardless of the platform. func canonicalTarName(name string, isDir bool) string { name = CanonicalTarNameForPath(name) @@ -495,13 +495,13 @@ func (ta *tarAppender) addTarFile(path, name string) error { } } - // check whether the file is overlayfs whiteout - // if yes, skip re-mapping container ID mappings. + //check whether the file is overlayfs whiteout + //if yes, skip re-mapping container ID mappings. isOverlayWhiteout := fi.Mode()&os.ModeCharDevice != 0 && hdr.Devmajor == 0 && hdr.Devminor == 0 - // handle re-mapping container ID mappings back to host ID mappings before - // writing tar headers/files. We skip whiteout files because they were written - // by the kernel and already have proper ownership relative to the host + //handle re-mapping container ID mappings back to host ID mappings before + //writing tar headers/files. We skip whiteout files because they were written + //by the kernel and already have proper ownership relative to the host if !isOverlayWhiteout && !strings.HasPrefix(filepath.Base(hdr.Name), WhiteoutPrefix) && !ta.IdentityMapping.Empty() { fileIDPair, err := getFileUIDGID(fi.Sys()) if err != nil { @@ -1134,7 +1134,7 @@ func (archiver *Archiver) CopyFileWithTar(src, dst string) (err error) { dst = filepath.Join(dst, filepath.Base(src)) } // Create the holding directory if necessary - if err := system.MkdirAll(filepath.Dir(dst), 0700); err != nil { + if err := system.MkdirAll(filepath.Dir(dst), 0700, ""); err != nil { return err } @@ -1218,9 +1218,6 @@ func cmdStream(cmd *exec.Cmd, input io.Reader) (io.ReadCloser, error) { return nil, err } - // Ensure the command has exited before we clean anything up - done := make(chan struct{}) - // Copy stdout to the returned pipe go func() { if err := cmd.Wait(); err != nil { @@ -1228,16 +1225,9 @@ func cmdStream(cmd *exec.Cmd, input io.Reader) (io.ReadCloser, error) { } else { pipeW.Close() } - close(done) }() - return ioutils.NewReadCloserWrapper(pipeR, func() error { - // Close pipeR, and then wait for the command to complete before returning. We have to close pipeR first, as - // cmd.Wait waits for any non-file stdout/stderr/stdin to close. - err := pipeR.Close() - <-done - return err - }), nil + return pipeR, nil } // NewTempArchive reads the content of src into a temporary file, and returns the contents diff --git a/vendor/github.com/docker/docker/pkg/archive/archive_linux.go b/vendor/github.com/docker/docker/pkg/archive/archive_linux.go index fae42c00e6..0601f7b0d1 100644 --- a/vendor/github.com/docker/docker/pkg/archive/archive_linux.go +++ b/vendor/github.com/docker/docker/pkg/archive/archive_linux.go @@ -10,7 +10,6 @@ import ( "syscall" "github.com/containerd/continuity/fs" - "github.com/docker/docker/pkg/mount" "github.com/docker/docker/pkg/system" "github.com/pkg/errors" "golang.org/x/sys/unix" @@ -153,8 +152,9 @@ func mknodChar0Overlay(cleansedOriginalPath string) error { return errors.Wrapf(err, "failed to create a dummy lower file %s", lowerDummy) } mOpts := fmt.Sprintf("lowerdir=%s,upperdir=%s,workdir=%s", lower, upper, work) - if err := mount.Mount("overlay", merged, "overlay", mOpts); err != nil { - return err + // docker/pkg/mount.Mount() requires procfs to be mounted. So we use syscall.Mount() directly instead. + if err := syscall.Mount("overlay", merged, "overlay", uintptr(0), mOpts); err != nil { + return errors.Wrapf(err, "failed to mount overlay (%s) on %s", mOpts, merged) } mergedDummy := filepath.Join(merged, dummyBase) if err := os.Remove(mergedDummy); err != nil { @@ -237,8 +237,9 @@ func createDirWithOverlayOpaque(tmp string) (string, error) { return "", errors.Wrapf(err, "failed to create a dummy lower directory %s", lowerDummy) } mOpts := fmt.Sprintf("lowerdir=%s,upperdir=%s,workdir=%s", lower, upper, work) - if err := mount.Mount("overlay", merged, "overlay", mOpts); err != nil { - return "", err + // docker/pkg/mount.Mount() requires procfs to be mounted. So we use syscall.Mount() directly instead. + if err := syscall.Mount("overlay", merged, "overlay", uintptr(0), mOpts); err != nil { + return "", errors.Wrapf(err, "failed to mount overlay (%s) on %s", mOpts, merged) } mergedDummy := filepath.Join(merged, dummyBase) if err := os.Remove(mergedDummy); err != nil { diff --git a/vendor/github.com/docker/docker/pkg/archive/archive_windows.go b/vendor/github.com/docker/docker/pkg/archive/archive_windows.go index 7260174bfb..ae6b89fd71 100644 --- a/vendor/github.com/docker/docker/pkg/archive/archive_windows.go +++ b/vendor/github.com/docker/docker/pkg/archive/archive_windows.go @@ -31,7 +31,7 @@ func CanonicalTarNameForPath(p string) string { // chmodTarEntry is used to adjust the file permissions used in tar header based // on the platform the archival is done. func chmodTarEntry(perm os.FileMode) os.FileMode { - // perm &= 0755 // this 0-ed out tar flags (like link, regular file, directory marker etc.) + //perm &= 0755 // this 0-ed out tar flags (like link, regular file, directory marker etc.) permPart := perm & os.ModePerm noPermPart := perm &^ os.ModePerm // Add the x bit: make everything +x from windows diff --git a/vendor/github.com/docker/docker/pkg/archive/diff.go b/vendor/github.com/docker/docker/pkg/archive/diff.go index 27897e6ab7..146e21fe18 100644 --- a/vendor/github.com/docker/docker/pkg/archive/diff.go +++ b/vendor/github.com/docker/docker/pkg/archive/diff.go @@ -84,7 +84,7 @@ func UnpackLayer(dest string, layer io.Reader, options *TarOptions) (size int64, parentPath := filepath.Join(dest, parent) if _, err := os.Lstat(parentPath); err != nil && os.IsNotExist(err) { - err = system.MkdirAll(parentPath, 0600) + err = system.MkdirAll(parentPath, 0600, "") if err != nil { return 0, err } @@ -196,7 +196,7 @@ func UnpackLayer(dest string, layer io.Reader, options *TarOptions) (size int64, return 0, err } - if err := createTarFile(path, dest, srcHdr, srcData, !options.NoLchown, nil, options.InUserNS); err != nil { + if err := createTarFile(path, dest, srcHdr, srcData, true, nil, options.InUserNS); err != nil { return 0, err } diff --git a/vendor/github.com/docker/docker/pkg/idtools/idtools_unix.go b/vendor/github.com/docker/docker/pkg/idtools/idtools_unix.go index 3981ff64d3..fb239743a0 100644 --- a/vendor/github.com/docker/docker/pkg/idtools/idtools_unix.go +++ b/vendor/github.com/docker/docker/pkg/idtools/idtools_unix.go @@ -59,7 +59,7 @@ func mkdirAs(path string, mode os.FileMode, owner Identity, mkAll, chownExisting paths = append(paths, dirPath) } } - if err := system.MkdirAll(path, mode); err != nil { + if err := system.MkdirAll(path, mode, ""); err != nil { return err } } else { diff --git a/vendor/github.com/docker/docker/pkg/idtools/idtools_windows.go b/vendor/github.com/docker/docker/pkg/idtools/idtools_windows.go index 35ede0fffa..4ae38a1b17 100644 --- a/vendor/github.com/docker/docker/pkg/idtools/idtools_windows.go +++ b/vendor/github.com/docker/docker/pkg/idtools/idtools_windows.go @@ -11,7 +11,7 @@ import ( // Ownership is handled elsewhere, but in the future could be support here // too. func mkdirAs(path string, mode os.FileMode, owner Identity, mkAll, chownExisting bool) error { - if err := system.MkdirAll(path, mode); err != nil { + if err := system.MkdirAll(path, mode, ""); err != nil { return err } return nil diff --git a/vendor/github.com/docker/docker/pkg/idtools/utils_unix.go b/vendor/github.com/docker/docker/pkg/idtools/utils_unix.go index bcf6a4ffbc..903ac4501b 100644 --- a/vendor/github.com/docker/docker/pkg/idtools/utils_unix.go +++ b/vendor/github.com/docker/docker/pkg/idtools/utils_unix.go @@ -18,8 +18,8 @@ func resolveBinary(binname string) (string, error) { if err != nil { return "", err } - // only return no error if the final resolved binary basename - // matches what was searched for + //only return no error if the final resolved binary basename + //matches what was searched for if filepath.Base(resolvedPath) == binname { return resolvedPath, nil } diff --git a/vendor/github.com/docker/docker/pkg/ioutils/bytespipe.go b/vendor/github.com/docker/docker/pkg/ioutils/bytespipe.go index 87514b643d..d4bbf3c9dc 100644 --- a/vendor/github.com/docker/docker/pkg/ioutils/bytespipe.go +++ b/vendor/github.com/docker/docker/pkg/ioutils/bytespipe.go @@ -128,9 +128,8 @@ func (bp *BytesPipe) Read(p []byte) (n int, err error) { bp.mu.Lock() if bp.bufLen == 0 { if bp.closeErr != nil { - err := bp.closeErr bp.mu.Unlock() - return 0, err + return 0, bp.closeErr } bp.wait.Wait() if bp.bufLen == 0 && bp.closeErr != nil { diff --git a/vendor/github.com/docker/docker/pkg/mount/mount.go b/vendor/github.com/docker/docker/pkg/mount/mount.go index e07cd431bc..be0631c630 100644 --- a/vendor/github.com/docker/docker/pkg/mount/mount.go +++ b/vendor/github.com/docker/docker/pkg/mount/mount.go @@ -97,19 +97,24 @@ func Mounted(mountpoint string) (bool, error) { return len(entries) > 0, nil } -// Mount will mount filesystem according to the specified configuration. -// Options must be specified like the mount or fstab unix commands: -// "opt1=val1,opt2=val2". See flags.go for supported option flags. +// Mount will mount filesystem according to the specified configuration, on the +// condition that the target path is *not* already mounted. Options must be +// specified like the mount or fstab unix commands: "opt1=val1,opt2=val2". See +// flags.go for supported option flags. func Mount(device, target, mType, options string) error { flag, data := parseOptions(options) + if flag&REMOUNT != REMOUNT { + if mounted, err := Mounted(target); err != nil || mounted { + return err + } + } return mount(device, target, mType, uintptr(flag), data) } -// ForceMount will mount filesystem according to the specified configuration. -// Options must be specified like the mount or fstab unix commands: -// "opt1=val1,opt2=val2". See flags.go for supported option flags. -// -// Deprecated: use Mount instead. +// ForceMount will mount a filesystem according to the specified configuration, +// *regardless* if the target path is not already mounted. Options must be +// specified like the mount or fstab unix commands: "opt1=val1,opt2=val2". See +// flags.go for supported option flags. func ForceMount(device, target, mType, options string) error { flag, data := parseOptions(options) return mount(device, target, mType, uintptr(flag), data) @@ -139,10 +144,13 @@ func RecursiveUnmount(target string) error { err = unmount(m.Mountpoint, mntDetach) if err != nil { if i == len(mounts)-1 { // last mount - return err + if mounted, e := Mounted(m.Mountpoint); e != nil || mounted { + return err + } + } else { + // This is some submount, we can ignore this error for now, the final unmount will fail if this is a real problem + logrus.WithError(err).Warnf("Failed to unmount submount %s", m.Mountpoint) } - // This is some submount, we can ignore this error for now, the final unmount will fail if this is a real problem - logrus.WithError(err).Warnf("Failed to unmount submount %s", m.Mountpoint) } logrus.Debugf("Unmounted %s", m.Mountpoint) diff --git a/vendor/github.com/docker/docker/pkg/mount/mountinfo_freebsd.go b/vendor/github.com/docker/docker/pkg/mount/mountinfo_freebsd.go index 0af3959dcf..36c89dc1a2 100644 --- a/vendor/github.com/docker/docker/pkg/mount/mountinfo_freebsd.go +++ b/vendor/github.com/docker/docker/pkg/mount/mountinfo_freebsd.go @@ -13,7 +13,8 @@ import ( "unsafe" ) -// parseMountTable returns information about mounted filesystems +// Parse /proc/self/mountinfo because comparing Dev and ino does not work from +// bind mounts. func parseMountTable(filter FilterFunc) ([]*Info, error) { var rawEntries *C.struct_statfs @@ -36,7 +37,7 @@ func parseMountTable(filter FilterFunc) ([]*Info, error) { if filter != nil { // filter out entries we're not interested in - skip, stop = filter(&mountinfo) + skip, stop = filter(p) if skip { continue } diff --git a/vendor/github.com/docker/docker/pkg/mount/mountinfo_linux.go b/vendor/github.com/docker/docker/pkg/mount/mountinfo_linux.go index 58ca61f3f7..fe6e3ddba1 100644 --- a/vendor/github.com/docker/docker/pkg/mount/mountinfo_linux.go +++ b/vendor/github.com/docker/docker/pkg/mount/mountinfo_linux.go @@ -90,6 +90,7 @@ func parseInfoFile(r io.Reader, filter FilterFunc) ([]*Info, error) { mount propagation flags in fields[6]. The correct behavior is to ignore any unknown optional fields. */ + break } } if i == numFields { diff --git a/vendor/github.com/docker/docker/pkg/pools/pools.go b/vendor/github.com/docker/docker/pkg/pools/pools.go index 3792c67a9e..46339c282f 100644 --- a/vendor/github.com/docker/docker/pkg/pools/pools.go +++ b/vendor/github.com/docker/docker/pkg/pools/pools.go @@ -62,23 +62,23 @@ type bufferPool struct { func newBufferPoolWithSize(size int) *bufferPool { return &bufferPool{ pool: sync.Pool{ - New: func() interface{} { s := make([]byte, size); return &s }, + New: func() interface{} { return make([]byte, size) }, }, } } -func (bp *bufferPool) Get() *[]byte { - return bp.pool.Get().(*[]byte) +func (bp *bufferPool) Get() []byte { + return bp.pool.Get().([]byte) } -func (bp *bufferPool) Put(b *[]byte) { +func (bp *bufferPool) Put(b []byte) { bp.pool.Put(b) } // Copy is a convenience wrapper which uses a buffer to avoid allocation in io.Copy. func Copy(dst io.Writer, src io.Reader) (written int64, err error) { buf := buffer32KPool.Get() - written, err = io.CopyBuffer(dst, src, *buf) + written, err = io.CopyBuffer(dst, src, buf) buffer32KPool.Put(buf) return } diff --git a/vendor/github.com/docker/docker/pkg/system/chtimes_unix.go b/vendor/github.com/docker/docker/pkg/system/chtimes_unix.go index d5fab96f9d..259138a45b 100644 --- a/vendor/github.com/docker/docker/pkg/system/chtimes_unix.go +++ b/vendor/github.com/docker/docker/pkg/system/chtimes_unix.go @@ -6,9 +6,9 @@ import ( "time" ) -// setCTime will set the create time on a file. On Unix, the create -// time is updated as a side effect of setting the modified time, so -// no action is required. +//setCTime will set the create time on a file. On Unix, the create +//time is updated as a side effect of setting the modified time, so +//no action is required. func setCTime(path string, ctime time.Time) error { return nil } diff --git a/vendor/github.com/docker/docker/pkg/system/chtimes_windows.go b/vendor/github.com/docker/docker/pkg/system/chtimes_windows.go index 6664b8bcad..d3a115ff42 100644 --- a/vendor/github.com/docker/docker/pkg/system/chtimes_windows.go +++ b/vendor/github.com/docker/docker/pkg/system/chtimes_windows.go @@ -6,8 +6,8 @@ import ( "golang.org/x/sys/windows" ) -// setCTime will set the create time on a file. On Windows, this requires -// calling SetFileTime and explicitly including the create time. +//setCTime will set the create time on a file. On Windows, this requires +//calling SetFileTime and explicitly including the create time. func setCTime(path string, ctime time.Time) error { ctimespec := windows.NsecToTimespec(ctime.UnixNano()) pathp, e := windows.UTF16PtrFromString(path) diff --git a/vendor/github.com/docker/docker/pkg/system/filesys_unix.go b/vendor/github.com/docker/docker/pkg/system/filesys.go similarity index 93% rename from vendor/github.com/docker/docker/pkg/system/filesys_unix.go rename to vendor/github.com/docker/docker/pkg/system/filesys.go index dcee3e9f98..adeb163052 100644 --- a/vendor/github.com/docker/docker/pkg/system/filesys_unix.go +++ b/vendor/github.com/docker/docker/pkg/system/filesys.go @@ -8,14 +8,14 @@ import ( "path/filepath" ) -// MkdirAllWithACL is a wrapper for os.MkdirAll on unix systems. +// MkdirAllWithACL is a wrapper for MkdirAll on unix systems. func MkdirAllWithACL(path string, perm os.FileMode, sddl string) error { - return os.MkdirAll(path, perm) + return MkdirAll(path, perm, sddl) } // MkdirAll creates a directory named path along with any necessary parents, // with permission specified by attribute perm for all dir created. -func MkdirAll(path string, perm os.FileMode) error { +func MkdirAll(path string, perm os.FileMode, sddl string) error { return os.MkdirAll(path, perm) } diff --git a/vendor/github.com/docker/docker/pkg/system/filesys_windows.go b/vendor/github.com/docker/docker/pkg/system/filesys_windows.go index b4646277ab..3049ff38a4 100644 --- a/vendor/github.com/docker/docker/pkg/system/filesys_windows.go +++ b/vendor/github.com/docker/docker/pkg/system/filesys_windows.go @@ -11,6 +11,7 @@ import ( "time" "unsafe" + winio "github.com/Microsoft/go-winio" "golang.org/x/sys/windows" ) @@ -25,10 +26,9 @@ func MkdirAllWithACL(path string, perm os.FileMode, sddl string) error { return mkdirall(path, true, sddl) } -// MkdirAll implementation that is volume path aware for Windows. It can be used -// as a drop-in replacement for os.MkdirAll() -func MkdirAll(path string, _ os.FileMode) error { - return mkdirall(path, false, "") +// MkdirAll implementation that is volume path aware for Windows. +func MkdirAll(path string, _ os.FileMode, sddl string) error { + return mkdirall(path, false, sddl) } // mkdirall is a custom version of os.MkdirAll modified for use on Windows @@ -102,13 +102,13 @@ func mkdirall(path string, applyACL bool, sddl string) error { // and Local System. func mkdirWithACL(name string, sddl string) error { sa := windows.SecurityAttributes{Length: 0} - sd, err := windows.SecurityDescriptorFromString(sddl) + sd, err := winio.SddlToSecurityDescriptor(sddl) if err != nil { return &os.PathError{Op: "mkdir", Path: name, Err: err} } sa.Length = uint32(unsafe.Sizeof(sa)) sa.InheritHandle = 1 - sa.SecurityDescriptor = sd + sa.SecurityDescriptor = uintptr(unsafe.Pointer(&sd[0])) namep, err := windows.UTF16PtrFromString(name) if err != nil { @@ -130,10 +130,12 @@ func mkdirWithACL(name string, sddl string) error { // by the daemon. This SHOULD be treated as absolute from a docker processing // perspective. func IsAbs(path string) bool { - if filepath.IsAbs(path) || strings.HasPrefix(path, string(os.PathSeparator)) { - return true + if !filepath.IsAbs(path) { + if !strings.HasPrefix(path, string(os.PathSeparator)) { + return false + } } - return false + return true } // The origin of the functions below here are the golang OS and windows packages, @@ -233,7 +235,7 @@ func windowsOpenSequential(path string, mode int, _ uint32) (fd windows.Handle, createmode = windows.OPEN_EXISTING } // Use FILE_FLAG_SEQUENTIAL_SCAN rather than FILE_ATTRIBUTE_NORMAL as implemented in golang. - // https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858(v=vs.85).aspx + //https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858(v=vs.85).aspx const fileFlagSequentialScan = 0x08000000 // FILE_FLAG_SEQUENTIAL_SCAN h, e := windows.CreateFile(pathp, access, sharemode, sa, createmode, fileFlagSequentialScan, 0) return h, e diff --git a/vendor/github.com/docker/docker/pkg/system/init_windows.go b/vendor/github.com/docker/docker/pkg/system/init_windows.go index 7e4ac55d76..f303aa9063 100644 --- a/vendor/github.com/docker/docker/pkg/system/init_windows.go +++ b/vendor/github.com/docker/docker/pkg/system/init_windows.go @@ -18,7 +18,8 @@ var ( // InitLCOW sets whether LCOW is supported or not. Requires RS5+ func InitLCOW(experimental bool) { - if experimental && osversion.Build() >= osversion.RS5 { + v := GetOSVersion() + if experimental && v.Build >= osversion.RS5 { lcowSupported = true } } diff --git a/vendor/github.com/docker/docker/pkg/system/meminfo_linux.go b/vendor/github.com/docker/docker/pkg/system/meminfo_linux.go index cd060eff24..d79e8b0765 100644 --- a/vendor/github.com/docker/docker/pkg/system/meminfo_linux.go +++ b/vendor/github.com/docker/docker/pkg/system/meminfo_linux.go @@ -7,7 +7,7 @@ import ( "strconv" "strings" - units "github.com/docker/go-units" + "github.com/docker/go-units" ) // ReadMemInfo retrieves memory statistics of the host system and returns a @@ -27,7 +27,6 @@ func ReadMemInfo() (*MemInfo, error) { func parseMemInfo(reader io.Reader) (*MemInfo, error) { meminfo := &MemInfo{} scanner := bufio.NewScanner(reader) - memAvailable := int64(-1) for scanner.Scan() { // Expected format: ["MemTotal:", "1234", "kB"] parts := strings.Fields(scanner.Text()) @@ -49,8 +48,6 @@ func parseMemInfo(reader io.Reader) (*MemInfo, error) { meminfo.MemTotal = bytes case "MemFree:": meminfo.MemFree = bytes - case "MemAvailable:": - memAvailable = bytes case "SwapTotal:": meminfo.SwapTotal = bytes case "SwapFree:": @@ -58,9 +55,6 @@ func parseMemInfo(reader io.Reader) (*MemInfo, error) { } } - if memAvailable != -1 { - meminfo.MemFree = memAvailable - } // Handle errors that may have occurred during the reading of the file. if err := scanner.Err(); err != nil { diff --git a/vendor/github.com/docker/docker/pkg/system/path.go b/vendor/github.com/docker/docker/pkg/system/path.go index 64e892289a..a3d957afab 100644 --- a/vendor/github.com/docker/docker/pkg/system/path.go +++ b/vendor/github.com/docker/docker/pkg/system/path.go @@ -5,6 +5,8 @@ import ( "path/filepath" "runtime" "strings" + + "github.com/containerd/continuity/pathdriver" ) const defaultUnixPathEnv = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" @@ -25,12 +27,6 @@ func DefaultPathEnv(os string) string { } -// PathVerifier defines the subset of a PathDriver that CheckSystemDriveAndRemoveDriveLetter -// actually uses in order to avoid system depending on containerd/continuity. -type PathVerifier interface { - IsAbs(string) bool -} - // CheckSystemDriveAndRemoveDriveLetter verifies that a path, if it includes a drive letter, // is the system drive. // On Linux: this is a no-op. @@ -46,7 +42,7 @@ type PathVerifier interface { // a --> a // /a --> \a // d:\ --> Fail -func CheckSystemDriveAndRemoveDriveLetter(path string, driver PathVerifier) (string, error) { +func CheckSystemDriveAndRemoveDriveLetter(path string, driver pathdriver.PathDriver) (string, error) { if runtime.GOOS != "windows" || LCOWSupported() { return path, nil } diff --git a/vendor/github.com/docker/docker/pkg/system/path_windows.go b/vendor/github.com/docker/docker/pkg/system/path_windows.go index 22a56136c8..188f2c2957 100644 --- a/vendor/github.com/docker/docker/pkg/system/path_windows.go +++ b/vendor/github.com/docker/docker/pkg/system/path_windows.go @@ -1,27 +1,24 @@ package system // import "github.com/docker/docker/pkg/system" -import "golang.org/x/sys/windows" +import "syscall" // GetLongPathName converts Windows short pathnames to full pathnames. // For example C:\Users\ADMIN~1 --> C:\Users\Administrator. // It is a no-op on non-Windows platforms func GetLongPathName(path string) (string, error) { // See https://groups.google.com/forum/#!topic/golang-dev/1tufzkruoTg - p, err := windows.UTF16FromString(path) - if err != nil { - return "", err - } + p := syscall.StringToUTF16(path) b := p // GetLongPathName says we can reuse buffer - n, err := windows.GetLongPathName(&p[0], &b[0], uint32(len(b))) + n, err := syscall.GetLongPathName(&p[0], &b[0], uint32(len(b))) if err != nil { return "", err } if n > uint32(len(b)) { b = make([]uint16, n) - _, err = windows.GetLongPathName(&p[0], &b[0], uint32(len(b))) + _, err = syscall.GetLongPathName(&p[0], &b[0], uint32(len(b))) if err != nil { return "", err } } - return windows.UTF16ToString(b), nil + return syscall.UTF16ToString(b), nil } diff --git a/vendor/github.com/docker/docker/pkg/system/process_windows.go b/vendor/github.com/docker/docker/pkg/system/process_windows.go index 09bdfa0ca0..4e70c97b18 100644 --- a/vendor/github.com/docker/docker/pkg/system/process_windows.go +++ b/vendor/github.com/docker/docker/pkg/system/process_windows.go @@ -13,6 +13,6 @@ func IsProcessAlive(pid int) bool { func KillProcess(pid int) { p, err := os.FindProcess(pid) if err == nil { - _ = p.Kill() + p.Kill() } } diff --git a/vendor/github.com/docker/docker/pkg/system/rm.go b/vendor/github.com/docker/docker/pkg/system/rm.go index ef7f505fdf..b310991800 100644 --- a/vendor/github.com/docker/docker/pkg/system/rm.go +++ b/vendor/github.com/docker/docker/pkg/system/rm.go @@ -63,8 +63,12 @@ func EnsureRemoveAll(dir string) error { return err } - if e := mount.Unmount(pe.Path); e != nil { - return errors.Wrapf(e, "error while removing %s", dir) + if mounted, _ := mount.Mounted(pe.Path); mounted { + if e := mount.Unmount(pe.Path); e != nil { + if mounted, _ := mount.Mounted(pe.Path); mounted { + return errors.Wrapf(e, "error while removing %s", dir) + } + } } if exitOnErr[pe.Path] == maxRetry { diff --git a/vendor/github.com/docker/docker/pkg/system/stat_solaris.go b/vendor/github.com/docker/docker/pkg/system/stat_solaris.go new file mode 100644 index 0000000000..756b92d1e6 --- /dev/null +++ b/vendor/github.com/docker/docker/pkg/system/stat_solaris.go @@ -0,0 +1,13 @@ +package system // import "github.com/docker/docker/pkg/system" + +import "syscall" + +// fromStatT converts a syscall.Stat_t type to a system.Stat_t type +func fromStatT(s *syscall.Stat_t) (*StatT, error) { + return &StatT{size: s.Size, + mode: uint32(s.Mode), + uid: s.Uid, + gid: s.Gid, + rdev: uint64(s.Rdev), + mtim: s.Mtim}, nil +} diff --git a/vendor/github.com/docker/docker/pkg/system/syscall_unix.go b/vendor/github.com/docker/docker/pkg/system/syscall_unix.go index 905d10f153..919a412a7b 100644 --- a/vendor/github.com/docker/docker/pkg/system/syscall_unix.go +++ b/vendor/github.com/docker/docker/pkg/system/syscall_unix.go @@ -9,3 +9,9 @@ import "golang.org/x/sys/unix" func Unmount(dest string) error { return unix.Unmount(dest, 0) } + +// CommandLineToArgv should not be used on Unix. +// It simply returns commandLine in the only element in the returned array. +func CommandLineToArgv(commandLine string) ([]string, error) { + return []string{commandLine}, nil +} diff --git a/vendor/github.com/docker/docker/pkg/system/syscall_windows.go b/vendor/github.com/docker/docker/pkg/system/syscall_windows.go index b668342492..4ae92fa6c7 100644 --- a/vendor/github.com/docker/docker/pkg/system/syscall_windows.go +++ b/vendor/github.com/docker/docker/pkg/system/syscall_windows.go @@ -1,45 +1,45 @@ package system // import "github.com/docker/docker/pkg/system" import ( + "fmt" "syscall" "unsafe" - "github.com/Microsoft/hcsshim/osversion" "github.com/sirupsen/logrus" "golang.org/x/sys/windows" ) const ( - OWNER_SECURITY_INFORMATION = windows.OWNER_SECURITY_INFORMATION // Deprecated: use golang.org/x/sys/windows.OWNER_SECURITY_INFORMATION - GROUP_SECURITY_INFORMATION = windows.GROUP_SECURITY_INFORMATION // Deprecated: use golang.org/x/sys/windows.GROUP_SECURITY_INFORMATION - DACL_SECURITY_INFORMATION = windows.DACL_SECURITY_INFORMATION // Deprecated: use golang.org/x/sys/windows.DACL_SECURITY_INFORMATION - SACL_SECURITY_INFORMATION = windows.SACL_SECURITY_INFORMATION // Deprecated: use golang.org/x/sys/windows.SACL_SECURITY_INFORMATION - LABEL_SECURITY_INFORMATION = windows.LABEL_SECURITY_INFORMATION // Deprecated: use golang.org/x/sys/windows.LABEL_SECURITY_INFORMATION - ATTRIBUTE_SECURITY_INFORMATION = windows.ATTRIBUTE_SECURITY_INFORMATION // Deprecated: use golang.org/x/sys/windows.ATTRIBUTE_SECURITY_INFORMATION - SCOPE_SECURITY_INFORMATION = windows.SCOPE_SECURITY_INFORMATION // Deprecated: use golang.org/x/sys/windows.SCOPE_SECURITY_INFORMATION + OWNER_SECURITY_INFORMATION = 0x00000001 + GROUP_SECURITY_INFORMATION = 0x00000002 + DACL_SECURITY_INFORMATION = 0x00000004 + SACL_SECURITY_INFORMATION = 0x00000008 + LABEL_SECURITY_INFORMATION = 0x00000010 + ATTRIBUTE_SECURITY_INFORMATION = 0x00000020 + SCOPE_SECURITY_INFORMATION = 0x00000040 PROCESS_TRUST_LABEL_SECURITY_INFORMATION = 0x00000080 ACCESS_FILTER_SECURITY_INFORMATION = 0x00000100 - BACKUP_SECURITY_INFORMATION = windows.BACKUP_SECURITY_INFORMATION // Deprecated: use golang.org/x/sys/windows.BACKUP_SECURITY_INFORMATION - PROTECTED_DACL_SECURITY_INFORMATION = windows.PROTECTED_DACL_SECURITY_INFORMATION // Deprecated: use golang.org/x/sys/windows.PROTECTED_DACL_SECURITY_INFORMATION - PROTECTED_SACL_SECURITY_INFORMATION = windows.PROTECTED_SACL_SECURITY_INFORMATION // Deprecated: use golang.org/x/sys/windows.PROTECTED_SACL_SECURITY_INFORMATION - UNPROTECTED_DACL_SECURITY_INFORMATION = windows.UNPROTECTED_DACL_SECURITY_INFORMATION // Deprecated: use golang.org/x/sys/windows.UNPROTECTED_DACL_SECURITY_INFORMATION - UNPROTECTED_SACL_SECURITY_INFORMATION = windows.UNPROTECTED_SACL_SECURITY_INFORMATION // Deprecated: use golang.org/x/sys/windows.UNPROTECTED_SACL_SECURITY_INFORMATION + BACKUP_SECURITY_INFORMATION = 0x00010000 + PROTECTED_DACL_SECURITY_INFORMATION = 0x80000000 + PROTECTED_SACL_SECURITY_INFORMATION = 0x40000000 + UNPROTECTED_DACL_SECURITY_INFORMATION = 0x20000000 + UNPROTECTED_SACL_SECURITY_INFORMATION = 0x10000000 ) const ( - SE_UNKNOWN_OBJECT_TYPE = windows.SE_UNKNOWN_OBJECT_TYPE // Deprecated: use golang.org/x/sys/windows.SE_UNKNOWN_OBJECT_TYPE - SE_FILE_OBJECT = windows.SE_FILE_OBJECT // Deprecated: use golang.org/x/sys/windows.SE_FILE_OBJECT - SE_SERVICE = windows.SE_SERVICE // Deprecated: use golang.org/x/sys/windows.SE_SERVICE - SE_PRINTER = windows.SE_PRINTER // Deprecated: use golang.org/x/sys/windows.SE_PRINTER - SE_REGISTRY_KEY = windows.SE_REGISTRY_KEY // Deprecated: use golang.org/x/sys/windows.SE_REGISTRY_KEY - SE_LMSHARE = windows.SE_LMSHARE // Deprecated: use golang.org/x/sys/windows.SE_LMSHARE - SE_KERNEL_OBJECT = windows.SE_KERNEL_OBJECT // Deprecated: use golang.org/x/sys/windows.SE_KERNEL_OBJECT - SE_WINDOW_OBJECT = windows.SE_WINDOW_OBJECT // Deprecated: use golang.org/x/sys/windows.SE_WINDOW_OBJECT - SE_DS_OBJECT = windows.SE_DS_OBJECT // Deprecated: use golang.org/x/sys/windows.SE_DS_OBJECT - SE_DS_OBJECT_ALL = windows.SE_DS_OBJECT_ALL // Deprecated: use golang.org/x/sys/windows.SE_DS_OBJECT_ALL - SE_PROVIDER_DEFINED_OBJECT = windows.SE_PROVIDER_DEFINED_OBJECT // Deprecated: use golang.org/x/sys/windows.SE_PROVIDER_DEFINED_OBJECT - SE_WMIGUID_OBJECT = windows.SE_WMIGUID_OBJECT // Deprecated: use golang.org/x/sys/windows.SE_WMIGUID_OBJECT - SE_REGISTRY_WOW64_32KEY = windows.SE_REGISTRY_WOW64_32KEY // Deprecated: use golang.org/x/sys/windows.SE_REGISTRY_WOW64_32KEY + SE_UNKNOWN_OBJECT_TYPE = iota + SE_FILE_OBJECT + SE_SERVICE + SE_PRINTER + SE_REGISTRY_KEY + SE_LMSHARE + SE_KERNEL_OBJECT + SE_WINDOW_OBJECT + SE_DS_OBJECT + SE_DS_OBJECT_ALL + SE_PROVIDER_DEFINED_OBJECT + SE_WMIGUID_OBJECT + SE_REGISTRY_WOW64_32KEY ) const ( @@ -55,16 +55,21 @@ var ( ntuserApiset = windows.NewLazyDLL("ext-ms-win-ntuser-window-l1-1-0") modadvapi32 = windows.NewLazySystemDLL("advapi32.dll") procGetVersionExW = modkernel32.NewProc("GetVersionExW") + procGetProductInfo = modkernel32.NewProc("GetProductInfo") procSetNamedSecurityInfo = modadvapi32.NewProc("SetNamedSecurityInfoW") procGetSecurityDescriptorDacl = modadvapi32.NewProc("GetSecurityDescriptorDacl") ) // OSVersion is a wrapper for Windows version information // https://msdn.microsoft.com/en-us/library/windows/desktop/ms724439(v=vs.85).aspx -type OSVersion = osversion.OSVersion +type OSVersion struct { + Version uint32 + MajorVersion uint8 + MinorVersion uint8 + Build uint16 +} // https://msdn.microsoft.com/en-us/library/windows/desktop/ms724833(v=vs.85).aspx -// TODO: use golang.org/x/sys/windows.OsVersionInfoEx (needs OSVersionInfoSize to be exported) type osVersionInfoEx struct { OSVersionInfoSize uint32 MajorVersion uint32 @@ -80,13 +85,28 @@ type osVersionInfoEx struct { } // GetOSVersion gets the operating system version on Windows. Note that -// dockerd.exe must be manifested to get the correct version information. -// Deprecated: use github.com/Microsoft/hcsshim/osversion.Get() instead +// docker.exe must be manifested to get the correct version information. func GetOSVersion() OSVersion { - return osversion.Get() + var err error + osv := OSVersion{} + osv.Version, err = windows.GetVersion() + if err != nil { + // GetVersion never fails. + panic(err) + } + osv.MajorVersion = uint8(osv.Version & 0xFF) + osv.MinorVersion = uint8(osv.Version >> 8 & 0xFF) + osv.Build = uint16(osv.Version >> 16) + return osv +} + +func (osv OSVersion) ToString() string { + return fmt.Sprintf("%d.%d.%d", osv.MajorVersion, osv.MinorVersion, osv.Build) } // IsWindowsClient returns true if the SKU is client +// @engine maintainers - this function should not be removed or modified as it +// is used to enforce licensing restrictions on Windows. func IsWindowsClient() bool { osviex := &osVersionInfoEx{OSVersionInfoSize: 284} r1, _, err := procGetVersionExW.Call(uintptr(unsafe.Pointer(osviex))) @@ -98,12 +118,51 @@ func IsWindowsClient() bool { return osviex.ProductType == verNTWorkstation } +// IsIoTCore returns true if the currently running image is based off of +// Windows 10 IoT Core. +// @engine maintainers - this function should not be removed or modified as it +// is used to enforce licensing restrictions on Windows. +func IsIoTCore() bool { + var returnedProductType uint32 + r1, _, err := procGetProductInfo.Call(6, 1, 0, 0, uintptr(unsafe.Pointer(&returnedProductType))) + if r1 == 0 { + logrus.Warnf("GetProductInfo failed - assuming this is not IoT: %v", err) + return false + } + const productIoTUAP = 0x0000007B + const productIoTUAPCommercial = 0x00000083 + return returnedProductType == productIoTUAP || returnedProductType == productIoTUAPCommercial +} + // Unmount is a platform-specific helper function to call // the unmount syscall. Not supported on Windows -func Unmount(_ string) error { +func Unmount(dest string) error { return nil } +// CommandLineToArgv wraps the Windows syscall to turn a commandline into an argument array. +func CommandLineToArgv(commandLine string) ([]string, error) { + var argc int32 + + argsPtr, err := windows.UTF16PtrFromString(commandLine) + if err != nil { + return nil, err + } + + argv, err := windows.CommandLineToArgv(argsPtr, &argc) + if err != nil { + return nil, err + } + defer windows.LocalFree(windows.Handle(uintptr(unsafe.Pointer(argv)))) + + newArgs := make([]string, argc) + for i, v := range (*argv)[:argc] { + newArgs[i] = string(windows.UTF16ToString((*v)[:])) + } + + return newArgs, nil +} + // HasWin32KSupport determines whether containers that depend on win32k can // run on this machine. Win32k is the driver used to implement windowing. func HasWin32KSupport() bool { @@ -125,7 +184,7 @@ func GetSecurityDescriptorDacl(securityDescriptor *byte, daclPresent *uint32, da r1, _, e1 := syscall.Syscall6(procGetSecurityDescriptorDacl.Addr(), 4, uintptr(unsafe.Pointer(securityDescriptor)), uintptr(unsafe.Pointer(daclPresent)), uintptr(unsafe.Pointer(dacl)), uintptr(unsafe.Pointer(daclDefaulted)), 0, 0) if r1 == 0 { if e1 != 0 { - result = e1 + result = syscall.Errno(e1) } else { result = syscall.EINVAL } diff --git a/vendor/github.com/docker/docker/pkg/system/utimes_unix.go b/vendor/github.com/docker/docker/pkg/system/utimes_freebsd.go similarity index 58% rename from vendor/github.com/docker/docker/pkg/system/utimes_unix.go rename to vendor/github.com/docker/docker/pkg/system/utimes_freebsd.go index 61ba8c474c..ed1b9fad59 100644 --- a/vendor/github.com/docker/docker/pkg/system/utimes_unix.go +++ b/vendor/github.com/docker/docker/pkg/system/utimes_freebsd.go @@ -1,9 +1,8 @@ -// +build linux freebsd - package system // import "github.com/docker/docker/pkg/system" import ( "syscall" + "unsafe" "golang.org/x/sys/unix" ) @@ -11,12 +10,13 @@ import ( // LUtimesNano is used to change access and modification time of the specified path. // It's used for symbol link file because unix.UtimesNano doesn't support a NOFOLLOW flag atm. func LUtimesNano(path string, ts []syscall.Timespec) error { - uts := []unix.Timespec{ - unix.NsecToTimespec(syscall.TimespecToNsec(ts[0])), - unix.NsecToTimespec(syscall.TimespecToNsec(ts[1])), + var _path *byte + _path, err := unix.BytePtrFromString(path) + if err != nil { + return err } - err := unix.UtimesNanoAt(unix.AT_FDCWD, path, uts, unix.AT_SYMLINK_NOFOLLOW) - if err != nil && err != unix.ENOSYS { + + if _, _, err := unix.Syscall(unix.SYS_LUTIMES, uintptr(unsafe.Pointer(_path)), uintptr(unsafe.Pointer(&ts[0])), 0); err != 0 && err != unix.ENOSYS { return err } diff --git a/vendor/github.com/docker/docker/pkg/system/utimes_linux.go b/vendor/github.com/docker/docker/pkg/system/utimes_linux.go new file mode 100644 index 0000000000..0afe854589 --- /dev/null +++ b/vendor/github.com/docker/docker/pkg/system/utimes_linux.go @@ -0,0 +1,25 @@ +package system // import "github.com/docker/docker/pkg/system" + +import ( + "syscall" + "unsafe" + + "golang.org/x/sys/unix" +) + +// LUtimesNano is used to change access and modification time of the specified path. +// It's used for symbol link file because unix.UtimesNano doesn't support a NOFOLLOW flag atm. +func LUtimesNano(path string, ts []syscall.Timespec) error { + atFdCwd := unix.AT_FDCWD + + var _path *byte + _path, err := unix.BytePtrFromString(path) + if err != nil { + return err + } + if _, _, err := unix.Syscall6(unix.SYS_UTIMENSAT, uintptr(atFdCwd), uintptr(unsafe.Pointer(_path)), uintptr(unsafe.Pointer(&ts[0])), unix.AT_SYMLINK_NOFOLLOW, 0, 0); err != 0 && err != unix.ENOSYS { + return err + } + + return nil +} diff --git a/vendor/github.com/docker/docker/pkg/system/xattrs_linux.go b/vendor/github.com/docker/docker/pkg/system/xattrs_linux.go index 95b609fe7a..d4f1a57fb0 100644 --- a/vendor/github.com/docker/docker/pkg/system/xattrs_linux.go +++ b/vendor/github.com/docker/docker/pkg/system/xattrs_linux.go @@ -10,23 +10,24 @@ func Lgetxattr(path string, attr string) ([]byte, error) { dest := make([]byte, 128) sz, errno := unix.Lgetxattr(path, attr, dest) - for errno == unix.ERANGE { - // Buffer too small, use zero-sized buffer to get the actual size + switch { + case errno == unix.ENODATA: + return nil, nil + case errno == unix.ERANGE: + // 128 byte array might just not be good enough. A dummy buffer is used + // to get the real size of the xattrs on disk sz, errno = unix.Lgetxattr(path, attr, []byte{}) if errno != nil { return nil, errno } dest = make([]byte, sz) sz, errno = unix.Lgetxattr(path, attr, dest) - } - - switch { - case errno == unix.ENODATA: - return nil, nil + if errno != nil { + return nil, errno + } case errno != nil: return nil, errno } - return dest[:sz], nil } diff --git a/vendor/github.com/opencontainers/runc/libcontainer/system/linux.go b/vendor/github.com/opencontainers/runc/libcontainer/system/linux.go index 8b199d92ed..a4ae8901ac 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/system/linux.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/system/linux.go @@ -3,12 +3,13 @@ package system import ( - "bufio" - "fmt" "os" "os/exec" - "syscall" + "syscall" // only for exec "unsafe" + + "github.com/opencontainers/runc/libcontainer/user" + "golang.org/x/sys/unix" ) // If arg2 is nonzero, set the "child subreaper" attribute of the @@ -53,8 +54,8 @@ func Execv(cmd string, args []string, env []string) error { return syscall.Exec(name, args, env) } -func Prlimit(pid, resource int, limit syscall.Rlimit) error { - _, _, err := syscall.RawSyscall6(syscall.SYS_PRLIMIT64, uintptr(pid), uintptr(resource), uintptr(unsafe.Pointer(&limit)), uintptr(unsafe.Pointer(&limit)), 0, 0) +func Prlimit(pid, resource int, limit unix.Rlimit) error { + _, _, err := unix.RawSyscall6(unix.SYS_PRLIMIT64, uintptr(pid), uintptr(resource), uintptr(unsafe.Pointer(&limit)), uintptr(unsafe.Pointer(&limit)), 0, 0) if err != 0 { return err } @@ -62,7 +63,7 @@ func Prlimit(pid, resource int, limit syscall.Rlimit) error { } func SetParentDeathSignal(sig uintptr) error { - if _, _, err := syscall.RawSyscall(syscall.SYS_PRCTL, syscall.PR_SET_PDEATHSIG, sig, 0); err != 0 { + if err := unix.Prctl(unix.PR_SET_PDEATHSIG, sig, 0, 0, 0); err != nil { return err } return nil @@ -70,15 +71,14 @@ func SetParentDeathSignal(sig uintptr) error { func GetParentDeathSignal() (ParentDeathSignal, error) { var sig int - _, _, err := syscall.RawSyscall(syscall.SYS_PRCTL, syscall.PR_GET_PDEATHSIG, uintptr(unsafe.Pointer(&sig)), 0) - if err != 0 { + if err := unix.Prctl(unix.PR_GET_PDEATHSIG, uintptr(unsafe.Pointer(&sig)), 0, 0, 0); err != nil { return -1, err } return ParentDeathSignal(sig), nil } func SetKeepCaps() error { - if _, _, err := syscall.RawSyscall(syscall.SYS_PRCTL, syscall.PR_SET_KEEPCAPS, 1, 0); err != 0 { + if err := unix.Prctl(unix.PR_SET_KEEPCAPS, 1, 0, 0, 0); err != nil { return err } @@ -86,7 +86,7 @@ func SetKeepCaps() error { } func ClearKeepCaps() error { - if _, _, err := syscall.RawSyscall(syscall.SYS_PRCTL, syscall.PR_SET_KEEPCAPS, 0, 0); err != 0 { + if err := unix.Prctl(unix.PR_SET_KEEPCAPS, 0, 0, 0, 0); err != nil { return err } @@ -94,55 +94,62 @@ func ClearKeepCaps() error { } func Setctty() error { - if _, _, err := syscall.RawSyscall(syscall.SYS_IOCTL, 0, uintptr(syscall.TIOCSCTTY), 0); err != 0 { + if err := unix.IoctlSetInt(0, unix.TIOCSCTTY, 0); err != nil { return err } return nil } -/* - * Detect whether we are currently running in a user namespace. - * Copied from github.com/lxc/lxd/shared/util.go - */ +// RunningInUserNS detects whether we are currently running in a user namespace. +// Originally copied from github.com/lxc/lxd/shared/util.go func RunningInUserNS() bool { - file, err := os.Open("/proc/self/uid_map") + uidmap, err := user.CurrentProcessUIDMap() if err != nil { - /* - * This kernel-provided file only exists if user namespaces are - * supported - */ + // This kernel-provided file only exists if user namespaces are supported return false } - defer file.Close() + return UIDMapInUserNS(uidmap) +} - buf := bufio.NewReader(file) - l, _, err := buf.ReadLine() - if err != nil { - return false - } - - line := string(l) - var a, b, c int64 - fmt.Sscanf(line, "%d %d %d", &a, &b, &c) +func UIDMapInUserNS(uidmap []user.IDMap) bool { /* * We assume we are in the initial user namespace if we have a full * range - 4294967295 uids starting at uid 0. */ - if a == 0 && b == 0 && c == 4294967295 { + if len(uidmap) == 1 && uidmap[0].ID == 0 && uidmap[0].ParentID == 0 && uidmap[0].Count == 4294967295 { return false } return true } -// SetSubreaper sets the value i as the subreaper setting for the calling process -func SetSubreaper(i int) error { - return Prctl(PR_SET_CHILD_SUBREAPER, uintptr(i), 0, 0, 0) +// GetParentNSeuid returns the euid within the parent user namespace +func GetParentNSeuid() int64 { + euid := int64(os.Geteuid()) + uidmap, err := user.CurrentProcessUIDMap() + if err != nil { + // This kernel-provided file only exists if user namespaces are supported + return euid + } + for _, um := range uidmap { + if um.ID <= euid && euid <= um.ID+um.Count-1 { + return um.ParentID + euid - um.ID + } + } + return euid } -func Prctl(option int, arg2, arg3, arg4, arg5 uintptr) (err error) { - _, _, e1 := syscall.Syscall6(syscall.SYS_PRCTL, uintptr(option), arg2, arg3, arg4, arg5, 0) - if e1 != 0 { - err = e1 - } - return +// SetSubreaper sets the value i as the subreaper setting for the calling process +func SetSubreaper(i int) error { + return unix.Prctl(PR_SET_CHILD_SUBREAPER, uintptr(i), 0, 0, 0) +} + +// GetSubreaper returns the subreaper setting for the calling process +func GetSubreaper() (int, error) { + var i uintptr + + if err := unix.Prctl(unix.PR_GET_CHILD_SUBREAPER, uintptr(unsafe.Pointer(&i)), 0, 0, 0); err != nil { + return -1, err + } + + return int(i), nil } diff --git a/vendor/github.com/opencontainers/runc/libcontainer/system/proc.go b/vendor/github.com/opencontainers/runc/libcontainer/system/proc.go index 37808a29f6..79232a4371 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/system/proc.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/system/proc.go @@ -1,27 +1,113 @@ package system import ( + "fmt" "io/ioutil" "path/filepath" "strconv" "strings" ) -// look in /proc to find the process start time so that we can verify -// that this pid has started after ourself +// State is the status of a process. +type State rune + +const ( // Only values for Linux 3.14 and later are listed here + Dead State = 'X' + DiskSleep State = 'D' + Running State = 'R' + Sleeping State = 'S' + Stopped State = 'T' + TracingStop State = 't' + Zombie State = 'Z' +) + +// String forms of the state from proc(5)'s documentation for +// /proc/[pid]/status' "State" field. +func (s State) String() string { + switch s { + case Dead: + return "dead" + case DiskSleep: + return "disk sleep" + case Running: + return "running" + case Sleeping: + return "sleeping" + case Stopped: + return "stopped" + case TracingStop: + return "tracing stop" + case Zombie: + return "zombie" + default: + return fmt.Sprintf("unknown (%c)", s) + } +} + +// Stat_t represents the information from /proc/[pid]/stat, as +// described in proc(5) with names based on the /proc/[pid]/status +// fields. +type Stat_t struct { + // PID is the process ID. + PID uint + + // Name is the command run by the process. + Name string + + // State is the state of the process. + State State + + // StartTime is the number of clock ticks after system boot (since + // Linux 2.6). + StartTime uint64 +} + +// Stat returns a Stat_t instance for the specified process. +func Stat(pid int) (stat Stat_t, err error) { + bytes, err := ioutil.ReadFile(filepath.Join("/proc", strconv.Itoa(pid), "stat")) + if err != nil { + return stat, err + } + return parseStat(string(bytes)) +} + +// GetProcessStartTime is deprecated. Use Stat(pid) and +// Stat_t.StartTime instead. func GetProcessStartTime(pid int) (string, error) { - data, err := ioutil.ReadFile(filepath.Join("/proc", strconv.Itoa(pid), "stat")) + stat, err := Stat(pid) if err != nil { return "", err } - - parts := strings.Split(string(data), " ") - // the starttime is located at pos 22 - // from the man page - // - // starttime %llu (was %lu before Linux 2.6) - // (22) The time the process started after system boot. In kernels before Linux 2.6, this - // value was expressed in jiffies. Since Linux 2.6, the value is expressed in clock ticks - // (divide by sysconf(_SC_CLK_TCK)). - return parts[22-1], nil // starts at 1 + return fmt.Sprintf("%d", stat.StartTime), nil +} + +func parseStat(data string) (stat Stat_t, err error) { + // From proc(5), field 2 could contain space and is inside `(` and `)`. + // The following is an example: + // 89653 (gunicorn: maste) S 89630 89653 89653 0 -1 4194560 29689 28896 0 3 146 32 76 19 20 0 1 0 2971844 52965376 3920 18446744073709551615 1 1 0 0 0 0 0 16781312 137447943 0 0 0 17 1 0 0 0 0 0 0 0 0 0 0 0 0 0 + i := strings.LastIndex(data, ")") + if i <= 2 || i >= len(data)-1 { + return stat, fmt.Errorf("invalid stat data: %q", data) + } + + parts := strings.SplitN(data[:i], "(", 2) + if len(parts) != 2 { + return stat, fmt.Errorf("invalid stat data: %q", data) + } + + stat.Name = parts[1] + _, err = fmt.Sscanf(parts[0], "%d", &stat.PID) + if err != nil { + return stat, err + } + + // parts indexes should be offset by 3 from the field number given + // proc(5), because parts is zero-indexed and we've removed fields + // one (PID) and two (Name) in the paren-split. + parts = strings.Split(data[i+2:], " ") + var state int + fmt.Sscanf(parts[3-3], "%c", &state) + stat.State = State(state) + fmt.Sscanf(parts[22-3], "%d", &stat.StartTime) + return stat, nil } diff --git a/vendor/github.com/opencontainers/runc/libcontainer/system/setns_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/system/setns_linux.go deleted file mode 100644 index 615ff4c827..0000000000 --- a/vendor/github.com/opencontainers/runc/libcontainer/system/setns_linux.go +++ /dev/null @@ -1,40 +0,0 @@ -package system - -import ( - "fmt" - "runtime" - "syscall" -) - -// Via http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=7b21fddd087678a70ad64afc0f632e0f1071b092 -// -// We need different setns values for the different platforms and arch -// We are declaring the macro here because the SETNS syscall does not exist in th stdlib -var setNsMap = map[string]uintptr{ - "linux/386": 346, - "linux/arm64": 268, - "linux/amd64": 308, - "linux/arm": 375, - "linux/ppc": 350, - "linux/ppc64": 350, - "linux/ppc64le": 350, - "linux/s390x": 339, -} - -var sysSetns = setNsMap[fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH)] - -func SysSetns() uint32 { - return uint32(sysSetns) -} - -func Setns(fd uintptr, flags uintptr) error { - ns, exists := setNsMap[fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH)] - if !exists { - return fmt.Errorf("unsupported platform %s/%s", runtime.GOOS, runtime.GOARCH) - } - _, _, err := syscall.RawSyscall(ns, fd, flags, 0) - if err != 0 { - return err - } - return nil -} diff --git a/vendor/github.com/opencontainers/runc/libcontainer/system/syscall_linux_386.go b/vendor/github.com/opencontainers/runc/libcontainer/system/syscall_linux_32.go similarity index 61% rename from vendor/github.com/opencontainers/runc/libcontainer/system/syscall_linux_386.go rename to vendor/github.com/opencontainers/runc/libcontainer/system/syscall_linux_32.go index c990065189..c5ca5d8623 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/system/syscall_linux_386.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/system/syscall_linux_32.go @@ -1,14 +1,15 @@ -// +build linux,386 +// +build linux +// +build 386 arm package system import ( - "syscall" + "golang.org/x/sys/unix" ) // Setuid sets the uid of the calling thread to the specified uid. func Setuid(uid int) (err error) { - _, _, e1 := syscall.RawSyscall(syscall.SYS_SETUID, uintptr(uid), 0, 0) + _, _, e1 := unix.RawSyscall(unix.SYS_SETUID32, uintptr(uid), 0, 0) if e1 != 0 { err = e1 } @@ -17,7 +18,7 @@ func Setuid(uid int) (err error) { // Setgid sets the gid of the calling thread to the specified gid. func Setgid(gid int) (err error) { - _, _, e1 := syscall.RawSyscall(syscall.SYS_SETGID32, uintptr(gid), 0, 0) + _, _, e1 := unix.RawSyscall(unix.SYS_SETGID32, uintptr(gid), 0, 0) if e1 != 0 { err = e1 } diff --git a/vendor/github.com/opencontainers/runc/libcontainer/system/syscall_linux_64.go b/vendor/github.com/opencontainers/runc/libcontainer/system/syscall_linux_64.go index 0816bf8281..e05e30adc3 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/system/syscall_linux_64.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/system/syscall_linux_64.go @@ -1,14 +1,15 @@ -// +build linux,arm64 linux,amd64 linux,ppc linux,ppc64 linux,ppc64le linux,s390x +// +build linux +// +build arm64 amd64 mips mipsle mips64 mips64le ppc ppc64 ppc64le riscv64 s390x package system import ( - "syscall" + "golang.org/x/sys/unix" ) // Setuid sets the uid of the calling thread to the specified uid. func Setuid(uid int) (err error) { - _, _, e1 := syscall.RawSyscall(syscall.SYS_SETUID, uintptr(uid), 0, 0) + _, _, e1 := unix.RawSyscall(unix.SYS_SETUID, uintptr(uid), 0, 0) if e1 != 0 { err = e1 } @@ -17,7 +18,7 @@ func Setuid(uid int) (err error) { // Setgid sets the gid of the calling thread to the specified gid. func Setgid(gid int) (err error) { - _, _, e1 := syscall.RawSyscall(syscall.SYS_SETGID, uintptr(gid), 0, 0) + _, _, e1 := unix.RawSyscall(unix.SYS_SETGID, uintptr(gid), 0, 0) if e1 != 0 { err = e1 } diff --git a/vendor/github.com/opencontainers/runc/libcontainer/system/syscall_linux_arm.go b/vendor/github.com/opencontainers/runc/libcontainer/system/syscall_linux_arm.go deleted file mode 100644 index 3f780f312b..0000000000 --- a/vendor/github.com/opencontainers/runc/libcontainer/system/syscall_linux_arm.go +++ /dev/null @@ -1,25 +0,0 @@ -// +build linux,arm - -package system - -import ( - "syscall" -) - -// Setuid sets the uid of the calling thread to the specified uid. -func Setuid(uid int) (err error) { - _, _, e1 := syscall.RawSyscall(syscall.SYS_SETUID32, uintptr(uid), 0, 0) - if e1 != 0 { - err = e1 - } - return -} - -// Setgid sets the gid of the calling thread to the specified gid. -func Setgid(gid int) (err error) { - _, _, e1 := syscall.RawSyscall(syscall.SYS_SETGID32, uintptr(gid), 0, 0) - if e1 != 0 { - err = e1 - } - return -} diff --git a/vendor/github.com/opencontainers/runc/libcontainer/system/sysconfig.go b/vendor/github.com/opencontainers/runc/libcontainer/system/sysconfig.go index b3a07cba3e..b8434f1050 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/system/sysconfig.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/system/sysconfig.go @@ -1,4 +1,4 @@ -// +build cgo,linux cgo,freebsd +// +build cgo,linux package system diff --git a/vendor/github.com/opencontainers/runc/libcontainer/system/unsupported.go b/vendor/github.com/opencontainers/runc/libcontainer/system/unsupported.go index e7cfd62b29..b94be74a66 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/system/unsupported.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/system/unsupported.go @@ -2,8 +2,26 @@ package system +import ( + "os" + + "github.com/opencontainers/runc/libcontainer/user" +) + // RunningInUserNS is a stub for non-Linux systems // Always returns false func RunningInUserNS() bool { return false } + +// UIDMapInUserNS is a stub for non-Linux systems +// Always returns false +func UIDMapInUserNS(uidmap []user.IDMap) bool { + return false +} + +// GetParentNSeuid returns the euid within the parent user namespace +// Always returns os.Geteuid on non-linux +func GetParentNSeuid() int { + return os.Geteuid() +} diff --git a/vendor/github.com/opencontainers/runc/libcontainer/system/xattrs_linux.go b/vendor/github.com/opencontainers/runc/libcontainer/system/xattrs_linux.go index 30f74dfb1b..a6823fc99b 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/system/xattrs_linux.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/system/xattrs_linux.go @@ -1,99 +1,35 @@ package system -import ( - "syscall" - "unsafe" -) - -var _zero uintptr - -// Returns the size of xattrs and nil error -// Requires path, takes allocated []byte or nil as last argument -func Llistxattr(path string, dest []byte) (size int, err error) { - pathBytes, err := syscall.BytePtrFromString(path) - if err != nil { - return -1, err - } - var newpathBytes unsafe.Pointer - if len(dest) > 0 { - newpathBytes = unsafe.Pointer(&dest[0]) - } else { - newpathBytes = unsafe.Pointer(&_zero) - } - - _size, _, errno := syscall.Syscall6(syscall.SYS_LLISTXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(newpathBytes), uintptr(len(dest)), 0, 0, 0) - size = int(_size) - if errno != 0 { - return -1, errno - } - - return size, nil -} +import "golang.org/x/sys/unix" // Returns a []byte slice if the xattr is set and nil otherwise // Requires path and its attribute as arguments func Lgetxattr(path string, attr string) ([]byte, error) { var sz int - pathBytes, err := syscall.BytePtrFromString(path) - if err != nil { - return nil, err - } - attrBytes, err := syscall.BytePtrFromString(attr) - if err != nil { - return nil, err - } - // Start with a 128 length byte array - sz = 128 - dest := make([]byte, sz) - destBytes := unsafe.Pointer(&dest[0]) - _sz, _, errno := syscall.Syscall6(syscall.SYS_LGETXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(unsafe.Pointer(attrBytes)), uintptr(destBytes), uintptr(len(dest)), 0, 0) + dest := make([]byte, 128) + sz, errno := unix.Lgetxattr(path, attr, dest) switch { - case errno == syscall.ENODATA: + case errno == unix.ENODATA: return nil, errno - case errno == syscall.ENOTSUP: + case errno == unix.ENOTSUP: return nil, errno - case errno == syscall.ERANGE: + case errno == unix.ERANGE: // 128 byte array might just not be good enough, - // A dummy buffer is used ``uintptr(0)`` to get real size + // A dummy buffer is used to get the real size // of the xattrs on disk - _sz, _, errno = syscall.Syscall6(syscall.SYS_LGETXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(unsafe.Pointer(attrBytes)), uintptr(unsafe.Pointer(nil)), uintptr(0), 0, 0) - sz = int(_sz) - if sz < 0 { + sz, errno = unix.Lgetxattr(path, attr, []byte{}) + if errno != nil { return nil, errno } dest = make([]byte, sz) - destBytes := unsafe.Pointer(&dest[0]) - _sz, _, errno = syscall.Syscall6(syscall.SYS_LGETXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(unsafe.Pointer(attrBytes)), uintptr(destBytes), uintptr(len(dest)), 0, 0) - if errno != 0 { + sz, errno = unix.Lgetxattr(path, attr, dest) + if errno != nil { return nil, errno } - case errno != 0: + case errno != nil: return nil, errno } - sz = int(_sz) return dest[:sz], nil } - -func Lsetxattr(path string, attr string, data []byte, flags int) error { - pathBytes, err := syscall.BytePtrFromString(path) - if err != nil { - return err - } - attrBytes, err := syscall.BytePtrFromString(attr) - if err != nil { - return err - } - var dataBytes unsafe.Pointer - if len(data) > 0 { - dataBytes = unsafe.Pointer(&data[0]) - } else { - dataBytes = unsafe.Pointer(&_zero) - } - _, _, errno := syscall.Syscall6(syscall.SYS_LSETXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(unsafe.Pointer(attrBytes)), uintptr(dataBytes), uintptr(len(data)), uintptr(flags), 0) - if errno != 0 { - return errno - } - return nil -} diff --git a/vendor/github.com/opencontainers/runc/libcontainer/user/lookup.go b/vendor/github.com/opencontainers/runc/libcontainer/user/lookup.go index ab1439f361..6fd8dd0d44 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/user/lookup.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/user/lookup.go @@ -2,7 +2,6 @@ package user import ( "errors" - "syscall" ) var ( @@ -13,98 +12,30 @@ var ( ErrNoGroupEntries = errors.New("no matching entries in group file") ) -func lookupUser(filter func(u User) bool) (User, error) { - // Get operating system-specific passwd reader-closer. - passwd, err := GetPasswd() - if err != nil { - return User{}, err - } - defer passwd.Close() - - // Get the users. - users, err := ParsePasswdFilter(passwd, filter) - if err != nil { - return User{}, err - } - - // No user entries found. - if len(users) == 0 { - return User{}, ErrNoPasswdEntries - } - - // Assume the first entry is the "correct" one. - return users[0], nil -} - -// CurrentUser looks up the current user by their user id in /etc/passwd. If the -// user cannot be found (or there is no /etc/passwd file on the filesystem), -// then CurrentUser returns an error. -func CurrentUser() (User, error) { - return LookupUid(syscall.Getuid()) -} - // LookupUser looks up a user by their username in /etc/passwd. If the user // cannot be found (or there is no /etc/passwd file on the filesystem), then // LookupUser returns an error. func LookupUser(username string) (User, error) { - return lookupUser(func(u User) bool { - return u.Name == username - }) + return lookupUser(username) } // LookupUid looks up a user by their user id in /etc/passwd. If the user cannot // be found (or there is no /etc/passwd file on the filesystem), then LookupId // returns an error. func LookupUid(uid int) (User, error) { - return lookupUser(func(u User) bool { - return u.Uid == uid - }) -} - -func lookupGroup(filter func(g Group) bool) (Group, error) { - // Get operating system-specific group reader-closer. - group, err := GetGroup() - if err != nil { - return Group{}, err - } - defer group.Close() - - // Get the users. - groups, err := ParseGroupFilter(group, filter) - if err != nil { - return Group{}, err - } - - // No user entries found. - if len(groups) == 0 { - return Group{}, ErrNoGroupEntries - } - - // Assume the first entry is the "correct" one. - return groups[0], nil -} - -// CurrentGroup looks up the current user's group by their primary group id's -// entry in /etc/passwd. If the group cannot be found (or there is no -// /etc/group file on the filesystem), then CurrentGroup returns an error. -func CurrentGroup() (Group, error) { - return LookupGid(syscall.Getgid()) + return lookupUid(uid) } // LookupGroup looks up a group by its name in /etc/group. If the group cannot // be found (or there is no /etc/group file on the filesystem), then LookupGroup // returns an error. func LookupGroup(groupname string) (Group, error) { - return lookupGroup(func(g Group) bool { - return g.Name == groupname - }) + return lookupGroup(groupname) } // LookupGid looks up a group by its group id in /etc/group. If the group cannot // be found (or there is no /etc/group file on the filesystem), then LookupGid // returns an error. func LookupGid(gid int) (Group, error) { - return lookupGroup(func(g Group) bool { - return g.Gid == gid - }) + return lookupGid(gid) } diff --git a/vendor/github.com/opencontainers/runc/libcontainer/user/lookup_unix.go b/vendor/github.com/opencontainers/runc/libcontainer/user/lookup_unix.go index 758b734c22..92b5ae8de0 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/user/lookup_unix.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/user/lookup_unix.go @@ -5,6 +5,9 @@ package user import ( "io" "os" + "strconv" + + "golang.org/x/sys/unix" ) // Unix-specific path to the passwd and group formatted files. @@ -13,6 +16,76 @@ const ( unixGroupPath = "/etc/group" ) +func lookupUser(username string) (User, error) { + return lookupUserFunc(func(u User) bool { + return u.Name == username + }) +} + +func lookupUid(uid int) (User, error) { + return lookupUserFunc(func(u User) bool { + return u.Uid == uid + }) +} + +func lookupUserFunc(filter func(u User) bool) (User, error) { + // Get operating system-specific passwd reader-closer. + passwd, err := GetPasswd() + if err != nil { + return User{}, err + } + defer passwd.Close() + + // Get the users. + users, err := ParsePasswdFilter(passwd, filter) + if err != nil { + return User{}, err + } + + // No user entries found. + if len(users) == 0 { + return User{}, ErrNoPasswdEntries + } + + // Assume the first entry is the "correct" one. + return users[0], nil +} + +func lookupGroup(groupname string) (Group, error) { + return lookupGroupFunc(func(g Group) bool { + return g.Name == groupname + }) +} + +func lookupGid(gid int) (Group, error) { + return lookupGroupFunc(func(g Group) bool { + return g.Gid == gid + }) +} + +func lookupGroupFunc(filter func(g Group) bool) (Group, error) { + // Get operating system-specific group reader-closer. + group, err := GetGroup() + if err != nil { + return Group{}, err + } + defer group.Close() + + // Get the users. + groups, err := ParseGroupFilter(group, filter) + if err != nil { + return Group{}, err + } + + // No user entries found. + if len(groups) == 0 { + return Group{}, ErrNoGroupEntries + } + + // Assume the first entry is the "correct" one. + return groups[0], nil +} + func GetPasswdPath() (string, error) { return unixPasswdPath, nil } @@ -28,3 +101,44 @@ func GetGroupPath() (string, error) { func GetGroup() (io.ReadCloser, error) { return os.Open(unixGroupPath) } + +// CurrentUser looks up the current user by their user id in /etc/passwd. If the +// user cannot be found (or there is no /etc/passwd file on the filesystem), +// then CurrentUser returns an error. +func CurrentUser() (User, error) { + return LookupUid(unix.Getuid()) +} + +// CurrentGroup looks up the current user's group by their primary group id's +// entry in /etc/passwd. If the group cannot be found (or there is no +// /etc/group file on the filesystem), then CurrentGroup returns an error. +func CurrentGroup() (Group, error) { + return LookupGid(unix.Getgid()) +} + +func currentUserSubIDs(fileName string) ([]SubID, error) { + u, err := CurrentUser() + if err != nil { + return nil, err + } + filter := func(entry SubID) bool { + return entry.Name == u.Name || entry.Name == strconv.Itoa(u.Uid) + } + return ParseSubIDFileFilter(fileName, filter) +} + +func CurrentUserSubUIDs() ([]SubID, error) { + return currentUserSubIDs("/etc/subuid") +} + +func CurrentUserSubGIDs() ([]SubID, error) { + return currentUserSubIDs("/etc/subgid") +} + +func CurrentProcessUIDMap() ([]IDMap, error) { + return ParseIDMapFile("/proc/self/uid_map") +} + +func CurrentProcessGIDMap() ([]IDMap, error) { + return ParseIDMapFile("/proc/self/gid_map") +} diff --git a/vendor/github.com/opencontainers/runc/libcontainer/user/lookup_unsupported.go b/vendor/github.com/opencontainers/runc/libcontainer/user/lookup_unsupported.go deleted file mode 100644 index 7217948870..0000000000 --- a/vendor/github.com/opencontainers/runc/libcontainer/user/lookup_unsupported.go +++ /dev/null @@ -1,21 +0,0 @@ -// +build !darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris - -package user - -import "io" - -func GetPasswdPath() (string, error) { - return "", ErrUnsupported -} - -func GetPasswd() (io.ReadCloser, error) { - return nil, ErrUnsupported -} - -func GetGroupPath() (string, error) { - return "", ErrUnsupported -} - -func GetGroup() (io.ReadCloser, error) { - return nil, ErrUnsupported -} diff --git a/vendor/github.com/opencontainers/runc/libcontainer/user/lookup_windows.go b/vendor/github.com/opencontainers/runc/libcontainer/user/lookup_windows.go new file mode 100644 index 0000000000..65cd40e928 --- /dev/null +++ b/vendor/github.com/opencontainers/runc/libcontainer/user/lookup_windows.go @@ -0,0 +1,40 @@ +// +build windows + +package user + +import ( + "fmt" + "os/user" +) + +func lookupUser(username string) (User, error) { + u, err := user.Lookup(username) + if err != nil { + return User{}, err + } + return userFromOS(u) +} + +func lookupUid(uid int) (User, error) { + u, err := user.LookupId(fmt.Sprintf("%d", uid)) + if err != nil { + return User{}, err + } + return userFromOS(u) +} + +func lookupGroup(groupname string) (Group, error) { + g, err := user.LookupGroup(groupname) + if err != nil { + return Group{}, err + } + return groupFromOS(g) +} + +func lookupGid(gid int) (Group, error) { + g, err := user.LookupGroupId(fmt.Sprintf("%d", gid)) + if err != nil { + return Group{}, err + } + return groupFromOS(g) +} diff --git a/vendor/github.com/opencontainers/runc/libcontainer/user/user.go b/vendor/github.com/opencontainers/runc/libcontainer/user/user.go index 43fd39ef54..7b912bbf8b 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/user/user.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/user/user.go @@ -5,6 +5,7 @@ import ( "fmt" "io" "os" + "os/user" "strconv" "strings" ) @@ -28,6 +29,28 @@ type User struct { Shell string } +// userFromOS converts an os/user.(*User) to local User +// +// (This does not include Pass, Shell or Gecos) +func userFromOS(u *user.User) (User, error) { + newUser := User{ + Name: u.Username, + Home: u.HomeDir, + } + id, err := strconv.Atoi(u.Uid) + if err != nil { + return newUser, err + } + newUser.Uid = id + + id, err = strconv.Atoi(u.Gid) + if err != nil { + return newUser, err + } + newUser.Gid = id + return newUser, nil +} + type Group struct { Name string Pass string @@ -35,12 +58,46 @@ type Group struct { List []string } +// groupFromOS converts an os/user.(*Group) to local Group +// +// (This does not include Pass, Shell or Gecos) +func groupFromOS(g *user.Group) (Group, error) { + newGroup := Group{ + Name: g.Name, + } + + id, err := strconv.Atoi(g.Gid) + if err != nil { + return newGroup, err + } + newGroup.Gid = id + + return newGroup, nil +} + +// SubID represents an entry in /etc/sub{u,g}id +type SubID struct { + Name string + SubID int64 + Count int64 +} + +// IDMap represents an entry in /proc/PID/{u,g}id_map +type IDMap struct { + ID int64 + ParentID int64 + Count int64 +} + func parseLine(line string, v ...interface{}) { - if line == "" { + parseParts(strings.Split(line, ":"), v...) +} + +func parseParts(parts []string, v ...interface{}) { + if len(parts) == 0 { return } - parts := strings.Split(line, ":") for i, p := range parts { // Ignore cases where we don't have enough fields to populate the arguments. // Some configuration files like to misbehave. @@ -56,6 +113,8 @@ func parseLine(line string, v ...interface{}) { case *int: // "numbers", with conversion errors ignored because of some misbehaving configuration files. *e, _ = strconv.Atoi(p) + case *int64: + *e, _ = strconv.ParseInt(p, 10, 64) case *[]string: // Comma-separated lists. if p != "" { @@ -65,7 +124,7 @@ func parseLine(line string, v ...interface{}) { } default: // Someone goof'd when writing code using this function. Scream so they can hear us. - panic(fmt.Sprintf("parseLine only accepts {*string, *int, *[]string} as arguments! %#v is not a pointer!", e)) + panic(fmt.Sprintf("parseLine only accepts {*string, *int, *int64, *[]string} as arguments! %#v is not a pointer!", e)) } } } @@ -199,18 +258,16 @@ type ExecUser struct { // files cannot be opened for any reason, the error is ignored and a nil // io.Reader is passed instead. func GetExecUserPath(userSpec string, defaults *ExecUser, passwdPath, groupPath string) (*ExecUser, error) { - passwd, err := os.Open(passwdPath) - if err != nil { - passwd = nil - } else { - defer passwd.Close() + var passwd, group io.Reader + + if passwdFile, err := os.Open(passwdPath); err == nil { + passwd = passwdFile + defer passwdFile.Close() } - group, err := os.Open(groupPath) - if err != nil { - group = nil - } else { - defer group.Close() + if groupFile, err := os.Open(groupPath); err == nil { + group = groupFile + defer groupFile.Close() } return GetExecUser(userSpec, defaults, passwd, group) @@ -343,7 +400,7 @@ func GetExecUser(userSpec string, defaults *ExecUser, passwd, group io.Reader) ( if len(groups) > 0 { // First match wins, even if there's more than one matching entry. user.Gid = groups[0].Gid - } else if groupArg != "" { + } else { // If we can't find a group with the given name, the only other valid // option is if it's a numeric group name with no associated entry in group. @@ -433,9 +490,119 @@ func GetAdditionalGroups(additionalGroups []string, group io.Reader) ([]int, err // that opens the groupPath given and gives it as an argument to // GetAdditionalGroups. func GetAdditionalGroupsPath(additionalGroups []string, groupPath string) ([]int, error) { - group, err := os.Open(groupPath) - if err == nil { - defer group.Close() + var group io.Reader + + if groupFile, err := os.Open(groupPath); err == nil { + group = groupFile + defer groupFile.Close() } return GetAdditionalGroups(additionalGroups, group) } + +func ParseSubIDFile(path string) ([]SubID, error) { + subid, err := os.Open(path) + if err != nil { + return nil, err + } + defer subid.Close() + return ParseSubID(subid) +} + +func ParseSubID(subid io.Reader) ([]SubID, error) { + return ParseSubIDFilter(subid, nil) +} + +func ParseSubIDFileFilter(path string, filter func(SubID) bool) ([]SubID, error) { + subid, err := os.Open(path) + if err != nil { + return nil, err + } + defer subid.Close() + return ParseSubIDFilter(subid, filter) +} + +func ParseSubIDFilter(r io.Reader, filter func(SubID) bool) ([]SubID, error) { + if r == nil { + return nil, fmt.Errorf("nil source for subid-formatted data") + } + + var ( + s = bufio.NewScanner(r) + out = []SubID{} + ) + + for s.Scan() { + if err := s.Err(); err != nil { + return nil, err + } + + line := strings.TrimSpace(s.Text()) + if line == "" { + continue + } + + // see: man 5 subuid + p := SubID{} + parseLine(line, &p.Name, &p.SubID, &p.Count) + + if filter == nil || filter(p) { + out = append(out, p) + } + } + + return out, nil +} + +func ParseIDMapFile(path string) ([]IDMap, error) { + r, err := os.Open(path) + if err != nil { + return nil, err + } + defer r.Close() + return ParseIDMap(r) +} + +func ParseIDMap(r io.Reader) ([]IDMap, error) { + return ParseIDMapFilter(r, nil) +} + +func ParseIDMapFileFilter(path string, filter func(IDMap) bool) ([]IDMap, error) { + r, err := os.Open(path) + if err != nil { + return nil, err + } + defer r.Close() + return ParseIDMapFilter(r, filter) +} + +func ParseIDMapFilter(r io.Reader, filter func(IDMap) bool) ([]IDMap, error) { + if r == nil { + return nil, fmt.Errorf("nil source for idmap-formatted data") + } + + var ( + s = bufio.NewScanner(r) + out = []IDMap{} + ) + + for s.Scan() { + if err := s.Err(); err != nil { + return nil, err + } + + line := strings.TrimSpace(s.Text()) + if line == "" { + continue + } + + // see: man 7 user_namespaces + p := IDMap{} + parseParts(strings.Fields(line), &p.ID, &p.ParentID, &p.Count) + + if filter == nil || filter(p) { + out = append(out, p) + } + } + + return out, nil +} diff --git a/vendor/modules.txt b/vendor/modules.txt index c6957f568d..23e5dbde8d 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -181,6 +181,8 @@ github.com/briankassouf/jose/jws github.com/briankassouf/jose/jwt # github.com/cenkalti/backoff v2.2.1+incompatible github.com/cenkalti/backoff +# github.com/cenkalti/backoff/v3 v3.0.0 +github.com/cenkalti/backoff/v3 # github.com/centrify/cloud-golang-sdk v0.0.0-20190214225812-119110094d0f github.com/centrify/cloud-golang-sdk/oauth github.com/centrify/cloud-golang-sdk/restapi @@ -237,7 +239,7 @@ github.com/dimchansky/utfbom github.com/docker/distribution/digestset github.com/docker/distribution/reference github.com/docker/distribution/registry/api/errcode -# github.com/docker/docker v1.4.2-0.20200319182547-c7ad2b866182 +# github.com/docker/docker v17.12.0-ce-rc1.0.20200309214505-aa6a9891b09c+incompatible github.com/docker/docker/api github.com/docker/docker/api/types github.com/docker/docker/api/types/blkiodev @@ -720,7 +722,7 @@ github.com/opencontainers/go-digest # github.com/opencontainers/image-spec v1.0.1 github.com/opencontainers/image-spec/specs-go github.com/opencontainers/image-spec/specs-go/v1 -# github.com/opencontainers/runc v0.1.1 +# github.com/opencontainers/runc v1.0.0-rc9 github.com/opencontainers/runc/libcontainer/system github.com/opencontainers/runc/libcontainer/user # github.com/oracle/oci-go-sdk v12.5.0+incompatible