diff --git a/.dockerignore b/.dockerignore index 58354ff4211..98cca97e5d5 100644 --- a/.dockerignore +++ b/.dockerignore @@ -6,7 +6,6 @@ java/*/bin php/vendor releases /dist/ -/py-vtdb/ /vthook/ /bin/ /vtdataroot/ diff --git a/.github/workflows/check_formatting.yml b/.github/workflows/check_formatting.yml new file mode 100644 index 00000000000..7233082da38 --- /dev/null +++ b/.github/workflows/check_formatting.yml @@ -0,0 +1,21 @@ +name: check_formatting +on: [pull_request] +jobs: + + build: + name: Check Formatting + runs-on: ubuntu-latest + steps: + + - name: Set up Go + uses: actions/setup-go@v1 + with: + go-version: 1.13 + + - name: Check out code + uses: actions/checkout@v2 + + - name: Run go fmt + run: | + gofmt -l . | grep -vF vendor/ && exit 1 || echo "All files formatted correctly" + diff --git a/.github/workflows/check_make_visitor.yml b/.github/workflows/check_make_visitor.yml new file mode 100644 index 00000000000..68d8660ba84 --- /dev/null +++ b/.github/workflows/check_make_visitor.yml @@ -0,0 +1,35 @@ +name: check_make_visitor +on: [push, pull_request] +jobs: + + build: + name: Check Make Visitor + runs-on: ubuntu-latest + steps: + + - name: Set up Go + uses: actions/setup-go@v1 + with: + go-version: 1.13 + + - name: Check out code + uses: actions/checkout@v2 + + - name: Get dependencies + run: | + sudo apt-get update + sudo apt-get install -y mysql-server mysql-client make unzip g++ etcd curl git wget + sudo service mysql stop + sudo service etcd stop + sudo ln -s /etc/apparmor.d/usr.sbin.mysqld /etc/apparmor.d/disable/ + sudo apparmor_parser -R /etc/apparmor.d/usr.sbin.mysqld + go mod download + + - name: Run make minimaltools + run: | + make minimaltools + + - name: check_make_visitor + run: | + misc/git/hooks/visitorgen + diff --git a/.github/workflows/cluster_endtoend.yml b/.github/workflows/cluster_endtoend.yml index fad6e302642..401a147edb1 100644 --- a/.github/workflows/cluster_endtoend.yml +++ b/.github/workflows/cluster_endtoend.yml @@ -6,7 +6,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - name: [11, 12, 13, 14, 15, 16, 17, 18, 19, 20] + name: [11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24] steps: - name: Set up Go @@ -32,7 +32,16 @@ jobs: sudo apt-get update sudo apt-get install percona-xtrabackup-24 + - name: Installing zookeeper and consul + run: | + # Only running for shard 18 and 24 where we need to install consul and zookeeper + if [[ ${{matrix.name}} == 18 || ${{matrix.name}} == 24 ]]; then + make tools + fi + - name: sharded cluster_endtoend + timeout-minutes: 30 run: | source build.env - eatmydata -- go run test.go -docker=false -print-log -shard ${{matrix.name}} + eatmydata -- go run test.go -docker=false -print-log -follow -shard ${{matrix.name}} + diff --git a/.github/workflows/cluster_initial_sharding_multi.yml b/.github/workflows/cluster_initial_sharding_multi.yml new file mode 100644 index 00000000000..e2f5cf03bf5 --- /dev/null +++ b/.github/workflows/cluster_initial_sharding_multi.yml @@ -0,0 +1,20 @@ +name: cluster_initial_sharding_multi +on: [push, pull_request] +jobs: + + build: + name: cluster initial sharding multi + runs-on: ubuntu-latest + steps: + + - name: Set up Go + uses: actions/setup-go@v1 + with: + go-version: 1.13 + + - name: Check out code + uses: actions/checkout@v2 + + - name: Run initial sharding multi + run: | + go run test.go -print-log initial_sharding_multi \ No newline at end of file diff --git a/.github/workflows/cluster_vtctl_web.yml b/.github/workflows/cluster_vtctl_web.yml new file mode 100644 index 00000000000..82597559b0e --- /dev/null +++ b/.github/workflows/cluster_vtctl_web.yml @@ -0,0 +1,22 @@ +name: cluster_vtctl_web +on: [push, pull_request] +jobs: + + build: + name: cluster vtctl web + runs-on: ubuntu-latest + steps: + + - name: Set up Go + uses: actions/setup-go@v1 + with: + go-version: 1.13 + + - name: Check out code + uses: actions/checkout@v2 + + - name: Run vtctl web + run: | + # Running web test inside docker + go run test.go -docker=true -print-log -shard 10 + diff --git a/.github/workflows/create_release.yml b/.github/workflows/create_release.yml index 4759963a66c..1f8bb410199 100644 --- a/.github/workflows/create_release.yml +++ b/.github/workflows/create_release.yml @@ -16,7 +16,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v1 with: - go-version: 1.12 + go-version: 1.13 - name: Check out code uses: actions/checkout@v2 @@ -26,7 +26,7 @@ jobs: sudo apt-get update sudo apt-get install -y make ruby ruby-dev go mod download - sudo gem install --no-ri --no-rdoc fpm + sudo gem install fpm - name: Make Packages run: | diff --git a/.github/workflows/e2e_race.yml b/.github/workflows/e2e_race.yml index 3909974b1ce..5484bf81372 100644 --- a/.github/workflows/e2e_race.yml +++ b/.github/workflows/e2e_race.yml @@ -30,5 +30,6 @@ jobs: make minimaltools - name: e2e_race + timeout-minutes: 30 run: | make e2e_test_race diff --git a/.github/workflows/endtoend.yml b/.github/workflows/endtoend.yml index 37f2c866343..5e039acfda2 100644 --- a/.github/workflows/endtoend.yml +++ b/.github/workflows/endtoend.yml @@ -34,5 +34,6 @@ jobs: make build - name: endtoend + timeout-minutes: 30 run: | tools/e2e_test_runner.sh diff --git a/.github/workflows/legacy_local_example.yml b/.github/workflows/legacy_local_example.yml new file mode 100644 index 00000000000..5780f90ce52 --- /dev/null +++ b/.github/workflows/legacy_local_example.yml @@ -0,0 +1,54 @@ +name: local_example +on: [push, pull_request] +jobs: + + build: + name: Legacy local example using ${{ matrix.topo }} on ${{ matrix.os }} + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest] + topo: [etcd,k8s] + + steps: + + - name: Set up Go + uses: actions/setup-go@v1 + with: + go-version: 1.13 + + - name: Check out code + uses: actions/checkout@v2 + + - name: Get dependencies + run: | + if [ ${{matrix.os}} = "ubuntu-latest" ]; then + sudo apt-get update + sudo apt-get install -y mysql-server mysql-client make unzip g++ etcd curl git wget eatmydata + sudo service mysql stop + sudo service etcd stop + sudo ln -s /etc/apparmor.d/usr.sbin.mysqld /etc/apparmor.d/disable/ + sudo apparmor_parser -R /etc/apparmor.d/usr.sbin.mysqld + elif [ ${{matrix.os}} = "macos-latest" ]; then + brew install mysql@5.7 make unzip etcd curl git wget + fi + go mod download + + - name: Run make minimaltools + run: | + make minimaltools + + - name: Build + run: | + make build + + - name: local_example + timeout-minutes: 30 + run: | + export TOPO=${{matrix.topo}} + if [ ${{matrix.os}} = "macos-latest" ]; then + export PATH="/usr/local/opt/mysql@5.7/bin:$PATH" + fi + # Make sure that testing is entirely non-reliant on config + mv config config-moved + eatmydata -- test/legacy_local_example.sh diff --git a/.github/workflows/local_example.yml b/.github/workflows/local_example.yml index c702a9684aa..45869342ac6 100644 --- a/.github/workflows/local_example.yml +++ b/.github/workflows/local_example.yml @@ -42,6 +42,7 @@ jobs: make build - name: local_example + timeout-minutes: 30 run: | if [ ${{matrix.os}} = "macos-latest" ]; then export PATH="/usr/local/opt/mysql@5.7/bin:$PATH" diff --git a/.github/workflows/misc_test_docker.yml b/.github/workflows/misc_test_docker.yml new file mode 100644 index 00000000000..fd617e46b34 --- /dev/null +++ b/.github/workflows/misc_test_docker.yml @@ -0,0 +1,20 @@ +name: misc test +on: [push, pull_request] +jobs: + + build: + name: Misc Test + runs-on: ubuntu-latest + steps: + + - name: Set up Go + uses: actions/setup-go@v1 + with: + go-version: 1.13 + + - name: Check out code + uses: actions/checkout@v2 + + - name: Run Misc test which requires docker + run: | + go run test.go -docker=true -shard 25 \ No newline at end of file diff --git a/.github/workflows/sonar_analysis.yml b/.github/workflows/sonar_analysis.yml new file mode 100644 index 00000000000..3381d93b223 --- /dev/null +++ b/.github/workflows/sonar_analysis.yml @@ -0,0 +1,53 @@ +name: sonar_analysis +on: + push: + branches: + - 'sonartest' +jobs: + + build: + runs-on: ubuntu-latest + + steps: + - name: Set up Go + uses: actions/setup-go@v1 + with: + go-version: 1.13 + + - name: Check out code + uses: actions/checkout@v2 + + - name: Get dependencies + run: | + sudo apt-get update + sudo apt-get install -y mysql-server mysql-client make unzip g++ etcd curl git wget eatmydata + sudo service mysql stop + sudo service etcd stop + sudo ln -s /etc/apparmor.d/usr.sbin.mysqld /etc/apparmor.d/disable/ + sudo apparmor_parser -R /etc/apparmor.d/usr.sbin.mysqld + go mod download + + - name: Execute unit test and cluster endtoend test + run: | + eatmydata -- ./tools/all_test_for_coverage.sh + mkdir report + cp /tmp/*.out ./report/. + + - name: Analyse sonar + run: | + export SONAR_SCANNER_VERSION=4.2.0.1873 + export SONAR_SCANNER_HOME=$HOME/.sonar/sonar-scanner-$SONAR_SCANNER_VERSION-linux + curl --create-dirs -sSLo $HOME/.sonar/sonar-scanner.zip https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-$SONAR_SCANNER_VERSION-linux.zip + unzip -o $HOME/.sonar/sonar-scanner.zip -d $HOME/.sonar/ + export PATH=$SONAR_SCANNER_HOME/bin:$PATH + export SONAR_SCANNER_OPTS="-server" + + sonar-scanner \ + -Dsonar.projectKey=vitessio \ + -Dsonar.organization=vitess \ + -Dsonar.host.url=https://sonarcloud.io \ + -Dsonar.login=${SONAR_TOKEN} \ + -Dsonar.go.coverage.reportPaths=report/*.out + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} diff --git a/.github/workflows/unit.yml b/.github/workflows/unit.yml index af1ac347a4a..5929e7f3366 100644 --- a/.github/workflows/unit.yml +++ b/.github/workflows/unit.yml @@ -6,7 +6,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - name: [percona56, mysql57, mariadb101, mariadb102, mariadb103] + name: [percona56, mysql57, mysql80, mariadb101, mariadb102, mariadb103] steps: - name: Set up Go @@ -19,14 +19,21 @@ jobs: - name: Get dependencies run: | + export DEBIAN_FRONTEND="noninteractive" sudo apt-get update if [ ${{matrix.name}} = "mysql57" ]; then sudo apt-get install -y mysql-server mysql-client else # Uninstall likely installed MySQL first - sudo apt-get remove -y mysql-server mysql-client - + sudo systemctl stop apparmor + sudo DEBIAN_FRONTEND="noninteractive" apt-get remove -y --purge mysql-server mysql-client mysql-common + sudo apt-get -y autoremove + sudo apt-get -y autoclean + sudo deluser mysql + sudo rm -rf /var/lib/mysql + sudo rm -rf /etc/mysql + if [ ${{matrix.name}} = "percona56" ]; then sudo rm -rf /var/lib/mysql sudo apt install -y gnupg2 @@ -41,7 +48,11 @@ jobs: sudo apt-get update sudo DEBIAN_FRONTEND="noninteractive" apt-get install -y mysql-server mysql-client elif [ ${{matrix.name}} = "mariadb101" ]; then - sudo apt install -y mariadb-server mariadb-client + sudo apt-get install -y software-properties-common + sudo apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0xF1656F24C74CD1D8 + sudo add-apt-repository 'deb [arch=amd64,arm64,ppc64el] http://nyc2.mirrors.digitalocean.com/mariadb/repo/10.1/ubuntu bionic main' + sudo apt update + sudo DEBIAN_FRONTEND="noninteractive" apt install -y mariadb-server elif [ ${{matrix.name}} = "mariadb102" ]; then sudo apt-get install -y software-properties-common sudo apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0xF1656F24C74CD1D8 @@ -74,5 +85,6 @@ jobs: make tools - name: unit + timeout-minutes: 30 run: | - eatmydata -- make test + eatmydata -- make unit_test diff --git a/.github/workflows/unit_race.yml b/.github/workflows/unit_race.yml index 96219e5991c..09f1d996f5d 100644 --- a/.github/workflows/unit_race.yml +++ b/.github/workflows/unit_race.yml @@ -34,5 +34,6 @@ jobs: make tools - name: unit_race + timeout-minutes: 30 run: | eatmydata -- make unit_test_race diff --git a/.gitignore b/.gitignore index be8fe727562..041443eeedd 100644 --- a/.gitignore +++ b/.gitignore @@ -30,9 +30,6 @@ tags # C build dirs **/build -# site-local example files -/examples/kubernetes/config.sh - # generated protobuf files /go/vt/.proto.tmp @@ -81,7 +78,10 @@ releases .vagrant /dist/ -/py-vtdb /vthook/ /bin/ /vtdataroot/ +venv + +.scannerwork +report \ No newline at end of file diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 733f8213a21..00000000000 --- a/.travis.yml +++ /dev/null @@ -1,61 +0,0 @@ -# Travis CI configuration for Vitess. -# -# Note that we have our own test runner written in Go (test.go) which downloads -# our bootstrap Docker image and runs all tests within Docker. -# This solution is slower than running the tests natively, but has the -# advantage that we do not have to install (and cache) any dependencies within -# Travis itself. -# -# For the record, we expect the following overhead per Travis build: -# - 20 seconds Travis starting up the VM. -# - Up to 2 minutes to pull the Docker image. -# - More than a minute to run "make build" and cache the result as temporary -# Docker image. -# -# In total, it will always take up to 4 minutes until the environment is -# bootstrapped and the first test can be run. -# -# Open TODOs: -# - Re-add travis/check_make_proto.sh, ideally as part of test/config.json. -# - Add a presubmit which checks that if bootstrap has changed, and docker image is out of date. - -# sudo is required because we run Docker in our builds. -# See: https://docs.travis-ci.com/user/docker/ -sudo: required - -services: - - docker - -language: go -go: - - 1.12.x -go_import_path: vitess.io/vitess -env: - global: - # Run go build and test with -p 4 (i.e. up to 4 packages are compiled/tested in parallel). - # As of 07/2015 this value works best in a Travis CI container. - # TODO(mberlin): This will probably not be passed through to Docker. Verify and fix this. - - VT_GO_PARALLEL_VALUE=4 - # Note: The per test timeout must always be < 10 minutes because test.go - # does not produce any log output while running and Travis kills a - # build after 10 minutes without log output. - # See: https://docs.travis-ci.com/user/customizing-the-build#Build-Timeouts - # To diagnose stuck tests, add "-follow" to TEST_FLAGS below. Then test.go - # will print the test's output. - - TEST_FLAGS="-docker -use_docker_cache -timeout=8m -print-log" - matrix: - # NOTE: Travis CI schedules up to 5 tests simultaneously. - # All our tests should be spread out as evenly as possible across these 5 slots. - # We should always utilize all 5 slots because the cost of the setup is high (up to four minutes). - - TEST_MATRIX="-shard 0" - - TEST_MATRIX="-shard 1" - - TEST_MATRIX="-shard 2" - - TEST_MATRIX="-shard 3" - - TEST_MATRIX="-shard 4" -script: - - go run test.go $TEST_FLAGS $TEST_MATRIX - # Uncomment the next line to verify the GOMAXPROCS value (should be 2 as of 09/2017). - # - ./docker/test/run.sh mysql57 'go run travis/log_gomaxprocs.go' -notifications: - slack: - secure: S9n4rVWuEvSaF9RZUIx3Nkc2ycpM254zmalyMMbT5EmV1Xz6Zww2FL39RR5d57zsZ2M8GVW5n9uB8Bx57mr+L/wClEltzknYr7MA2/yYNMo5iK83tdQtNNw5U+dZG9/Plhlm4n883lcw9aZOyotNcLg2zBsd48Y74olk4NdmSfo= diff --git a/MAINTAINERS.md b/MAINTAINERS.md index 6eb672ab6a2..4ac0a3104f5 100644 --- a/MAINTAINERS.md +++ b/MAINTAINERS.md @@ -2,7 +2,7 @@ This page lists all active maintainers and their areas of expertise. This can be The following is the full list, alphabetically ordered. -* Andres Taylor ([systay](https://github.com/systay)) antaylor@squareup.com +* Andres Taylor ([systay](https://github.com/systay)) andres@planetscale.com * Anthony Yeh ([enisoc](https://github.com/enisoc)) enisoc@planetscale.com * Dan Kozlowski ([dkhenry](https://github.com/dkhenry)) koz@planetscale.com * David Weitzman ([dweitzman](https://github.com/dweitzman)) dweitzman@pinterest.com diff --git a/Makefile b/Makefile index 829db1f86fe..2c977f2fe9c 100644 --- a/Makefile +++ b/Makefile @@ -74,29 +74,18 @@ install: build # binaries mkdir -p "$${PREFIX}/bin" cp "$${VTROOT}/bin/"{mysqlctld,vtctld,vtctlclient,vtgate,vttablet,vtworker,vtbackup} "$${PREFIX}/bin/" - # config files - mkdir -p "$${PREFIX}/src/vitess.io/vitess" - cp -R config "$${PREFIX}/src/vitess.io/vitess/" - # also symlink config files in the old location - ln -sf src/vitess.io/vitess/config "$${PREFIX}/config" - # vtctld web UI files - mkdir -p "$${PREFIX}/src/vitess.io/vitess/web/vtctld2" - cp -R web/vtctld2/app "$${PREFIX}/src/vitess.io/vitess/web/vtctld2/" parser: make -C go/vt/sqlparser visitor: - go build -o visitorgen go/visitorgen/main/main.go - ./visitorgen -input=go/vt/sqlparser/ast.go -output=$(REWRITER) - rm ./visitorgen + go generate go/vt/sqlparser/rewriter.go # To pass extra flags, run test.go manually. # For example: go run test.go -docker=false -- --extra-flag # For more info see: go run test.go -help -test: build dependency_check - echo $$(date): Running unit tests - tools/unit_test_runner.sh +test: + go run test.go -docker=false site_test: unit_test site_integration_test @@ -114,6 +103,10 @@ cleanall: clean # Remind people to run bootstrap.sh again echo "Please run 'make tools' again to setup your environment" +unit_test: build dependency_check + echo $$(date): Running unit tests + tools/unit_test_runner.sh + e2e_test: build echo $$(date): Running endtoend tests go test $(VT_GO_PARALLEL) ./go/.../endtoend/... @@ -151,37 +144,17 @@ java_test: install_protoc-gen-go: go install github.com/golang/protobuf/protoc-gen-go -# Find protoc compiler. -# NOTE: We are *not* using the "protoc" binary (as suggested by the grpc Go -# quickstart for example). Instead, we run "protoc" via the Python -# wrapper script which is provided by the "grpcio-tools" PyPi package. -# (The package includes the compiler as library, but not as binary. -# Therefore, we have to use the wrapper script they provide.) -ifneq ($(wildcard $(VTROOT)/dist/grpc/usr/local/lib/python2.7/site-packages/grpc_tools/protoc.py),) -# IMPORTANT: The next line must not be indented. -PROTOC_COMMAND := python -m grpc_tools.protoc -endif - PROTO_SRCS = $(wildcard proto/*.proto) PROTO_SRC_NAMES = $(basename $(notdir $(PROTO_SRCS))) -PROTO_PY_OUTS = $(foreach name, $(PROTO_SRC_NAMES), py/vtproto/$(name)_pb2.py) PROTO_GO_OUTS = $(foreach name, $(PROTO_SRC_NAMES), go/vt/proto/$(name)/$(name).pb.go) -# This rule rebuilds all the go and python files from the proto definitions for gRPC. -proto: proto_banner $(PROTO_GO_OUTS) $(PROTO_PY_OUTS) - -proto_banner: -ifeq (,$(PROTOC_COMMAND)) - $(error "Cannot find protoc compiler. Did bootstrap.sh succeed, and did you execute 'source dev.env'?") -endif +# This rule rebuilds all the go files from the proto definitions for gRPC. +proto: $(PROTO_GO_OUTS) ifndef NOBANNER echo $$(date): Compiling proto definitions endif -$(PROTO_PY_OUTS): py/vtproto/%_pb2.py: proto/%.proto - $(PROTOC_COMMAND) -Iproto $< --python_out=py/vtproto --grpc_python_out=py/vtproto - # TODO(sougou): find a better way around this temp hack. VTTOP=$(VTROOT)/../../.. $(PROTO_GO_OUTS): install_protoc-gen-go proto/*.proto @@ -255,10 +228,18 @@ docker_lite_mysql57: chmod -R o=g * docker build -f docker/lite/Dockerfile.mysql57 -t vitess/lite:mysql57 . +docker_lite_ubi7.mysql57: + chmod -R o=g * + docker build -f docker/lite/Dockerfile.ubi7.mysql57 -t vitess/lite:ubi7.mysql57 . + docker_lite_mysql80: chmod -R o=g * docker build -f docker/lite/Dockerfile.mysql80 -t vitess/lite:mysql80 . +docker_lite_ubi7.mysql80: + chmod -R o=g * + docker build -f docker/lite/Dockerfile.ubi7.mysql80 -t vitess/lite:ubi7.mysql80 . + docker_lite_mariadb: chmod -R o=g * docker build -f docker/lite/Dockerfile.mariadb -t vitess/lite:mariadb . @@ -275,17 +256,22 @@ docker_lite_percona57: chmod -R o=g * docker build -f docker/lite/Dockerfile.percona57 -t vitess/lite:percona57 . +docker_lite_ubi7.percona57: + chmod -R o=g * + docker build -f docker/lite/Dockerfile.ubi7.percona57 -t vitess/lite:ubi7.percona57 . + docker_lite_percona80: chmod -R o=g * docker build -f docker/lite/Dockerfile.percona80 -t vitess/lite:percona80 . +docker_lite_ubi7.percona80: + chmod -R o=g * + docker build -f docker/lite/Dockerfile.ubi7.percona80 -t vitess/lite:ubi7.percona80 . + docker_lite_alpine: chmod -R o=g * docker build -f docker/lite/Dockerfile.alpine -t vitess/lite:alpine . -docker_guestbook: - cd examples/kubernetes/guestbook && ./build.sh - # This rule loads the working copy of the code into a bootstrap image, # and then runs the tests inside Docker. # Example: $ make docker_test flavor=mariadb @@ -295,12 +281,6 @@ docker_test: docker_unit_test: go run test.go -flavor $(flavor) unit -# This can be used to rebalance the total average runtime of each group of -# tests in Travis. The results are saved in test/config.json, which you can -# then commit and push. -rebalance_tests: - go run test.go -rebalance 5 - # Release a version. # This will generate a tar.gz file into the releases folder with the current source release: docker_base @@ -326,11 +306,11 @@ packages: docker_base tools: echo $$(date): Installing dependencies - BUILD_PYTHON=0 ./bootstrap.sh + ./bootstrap.sh minimaltools: echo $$(date): Installing minimal dependencies - BUILD_PYTHON=0 BUILD_JAVA=0 BUILD_CONSUL=0 ./bootstrap.sh + BUILD_CHROME=0 BUILD_JAVA=0 BUILD_CONSUL=0 ./bootstrap.sh dependency_check: ./tools/dependency_check.sh diff --git a/README.md b/README.md index bbe10c4c8c7..af1c4b89a1a 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,7 @@ [![Go Report Card](https://goreportcard.com/badge/vitess.io/vitess)](https://goreportcard.com/report/vitess.io/vitess) [![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fvitessio%2Fvitess.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2Fvitessio%2Fvitess?ref=badge_shield) [![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/1724/badge)](https://bestpractices.coreinfrastructure.org/projects/1724) +[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=vitessio&metric=coverage)](https://sonarcloud.io/dashboard?id=vitessio) # Vitess @@ -39,6 +40,12 @@ for low-frequency updates like new features and releases. ## Security +### Reporting Security Vulnerabilities + +To report a security vulnerability, please email [vitess-maintainers](mailto:cncf-vitess-maintainers@lists.cncf.io). + +See [Security](SECURITY.md) for a full outline of the security process. + ### Security Audit A third party security audit was performed by Cure53. You can see the full report [here](doc/VIT-01-report.pdf). diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 00000000000..c524bdc11de --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,93 @@ +# Security Release Process + +Vitess is a large growing community of volunteers, users, and vendors. The Vitess community has +adopted this security disclosure and response policy to ensure we responsibly handle critical +issues. + +## Maintainers Team + +Security vulnerabilities should be handled quickly and sometimes privately. The primary goal of this +process is to reduce the total time users are vulnerable to publicly known exploits. + +The Vitess [maintainers](MAINTAINERS.md) team is responsible for the entire response including internal communication and external disclosure. In the future, we may delegate responsibility to a sub-team as other projects have elected to do so. + +## Disclosures + +### Private Disclosure Processes + +The Vitess community asks that all suspected vulnerabilities be privately and responsibly disclosed via the [reporting policy](README.md#reporting-security-vulnerabilities). + +### Public Disclosure Processes + +If you know of a publicly disclosed security vulnerability please IMMEDIATELY email +[vitess-maintainers](mailto:cncf-vitess-maintainers@lists.cncf.io) so that we may start the patch, release, and communication process. + +## Patch, Release, and Public Communication + +For each reported vulnerability, a member of the maintainers team will volunteer to lead coordination of the fix (Fix Lead), and ensure that it is backported to each supported branch. They will then coordinate with the remainder of the maintainers team to coordinate new releases and ensure a communication plan is in place for vulnerability disclosure. + +All of the timelines below are suggestions and assume a private disclosure. The Fix Lead drives the +schedule using their best judgment based on severity and development time. If the Fix Lead is +dealing with a public disclosure all timelines become ASAP (assuming the vulnerability has a CVSS +score >= 4; see below). If the fix relies on another upstream project's disclosure timeline, that +will adjust the process as well. We will work with the upstream project to fit their timeline and +best protect our users. + +#### Policy for master-only vulnerabilities + +If a security vulnerability affects master, but not a currently supported branch, then the following process will apply: + +* The fix will land in master. +* A courtesy email will be sent to [vitess@googlegroups.com](https://groups.google.com/forum/#!forum/vitess) along with a posted notice in #developers on Slack. + +#### Policy for unsupported releases + +If a security vulnerability affects only a stable release which is no longer under active support, then the following process will apply: + +* A fix **will not** be issued (exceptions may be made for extreme circumstances) +* An email will be sent to [vitess-announce@googlegroups.com](https://groups.google.com/forum/#!forum/vitess-announce) identifying the threat, and encouraging users to upgrade. + +#### Policy for supported releases + +If a security vulnerability affects supported branches, then a Fix Lead will be appointed and the full security process as defined below will apply. + +### Fix Development Process + +These steps should be completed within the 1-7 days of Disclosure. + +- The Fix Lead will create a + [CVSS](https://www.first.org/cvss/specification-document) using the [CVSS + Calculator](https://www.first.org/cvss/calculator/3.0). The Fix Lead makes the final call on the + calculated CVSS; it is better to move quickly than making the CVSS perfect. +- The Fix Lead will notify the maintainers that work on the fix branch is complete. Maintainers will review the fix branch in a private repo and provide require LGTMs. + +If the CVSS score is under 4.0 ([a low severity +score](https://www.first.org/cvss/specification-document#i5)) the maintainers can decide to slow the +release process down in the face of holidays, developer bandwidth and other related circumstances. + +### Fix Disclosure Process + +With the fix development underway, the Fix Lead needs to come up with an overall communication plan +for the wider community. This Disclosure process should begin after the Fix Lead has developed a Fix +or mitigation so that a realistic timeline can be communicated to users. + +**Disclosure of Forthcoming Fix to Users** (Completed within 1-7 days of Disclosure) + +- The Fix Lead will email [vitess-announce@googlegroups.com](https://groups.google.com/forum/#!forum/vitess-announce) + informing users that a security vulnerability has been disclosed and that a fix will be made + available at YYYY-MM-DD HH:MM UTC in the future via this list. This time is the Release Date. +- The Fix Lead will include any mitigating steps users can take until a fix is available. + +The communication to users should be actionable. They should know when to block time to apply +patches, understand exact mitigation steps, etc. + +**Disclosure of Fixed Vulnerability** + +- The Fix Lead will email [vitess-announce@googlegroups.com](https://groups.google.com/forum/#!forum/vitess-announce) + informing users that there are new releases available to address an identified vulnerability. +- As much as possible this email should be actionable and include links to CVEs, and how to apply + the fix to user's environments; this can include links to external distributor documentation. + +### Embargo Policy + +The Vitess team currently does not provide advance notice of undisclosed vulnerabilities to any third parties. We are open to feedback on what such a policy can or should look like. For the interim, the best way to receive advanced notice of undisclosed vulnerabilities is to apply to join the maintainers team. diff --git a/bootstrap.sh b/bootstrap.sh index 1252e3717b0..642e262608f 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -23,9 +23,9 @@ source ./dev.env # 0. Initialization and helper methods. # 1. Installation of dependencies. -BUILD_PYTHON=${BUILD_PYTHON:-1} BUILD_JAVA=${BUILD_JAVA:-1} BUILD_CONSUL=${BUILD_CONSUL:-1} +BUILD_CHROME=${BUILD_CHROME:-1} # # 0. Initialization and helper methods. @@ -89,34 +89,6 @@ function get_arch() { uname -m } - -# Install the gRPC Python library (grpcio) and the protobuf gRPC Python plugin (grpcio-tools) from PyPI. -# Dependencies like the Python protobuf package will be installed automatically. -function install_grpc() { - local version="$1" - local dist="$2" - - # Python requires a very recent version of virtualenv. - # We also require a recent version of pip, as we use it to - # upgrade the other tools. - # For instance, setuptools doesn't work with pip 6.0: - # https://github.com/pypa/setuptools/issues/945 - # (and setuptools is used by grpc install). - grpc_virtualenv="$dist/usr/local" - $VIRTUALENV -v "$grpc_virtualenv" - PIP=$grpc_virtualenv/bin/pip - $PIP install --upgrade pip - $PIP install --upgrade --ignore-installed virtualenv - $PIP install mysql-connector-python - - grpcio_ver=$version - $PIP install --upgrade grpcio=="$grpcio_ver" grpcio-tools=="$grpcio_ver" -} - -if [ "$BUILD_PYTHON" == 1 ] ; then - install_dep "gRPC" "1.16.0" "$VTROOT/dist/grpc" install_grpc -fi - # Install protoc. function install_protoc() { local version="$1" @@ -220,49 +192,16 @@ if [ "$BUILD_CONSUL" == 1 ] ; then install_dep "Consul" "1.4.0" "$VTROOT/dist/consul" install_consul fi -# Install py-mock. -function install_pymock() { - local version="$1" - local dist="$2" - - # For some reason, it seems like setuptools won't create directories even with the --prefix argument - mkdir -p lib/python2.7/site-packages - PYTHONPATH=$(prepend_path "$PYTHONPATH" "$dist/lib/python2.7/site-packages") - export PYTHONPATH - - pushd "$VTROOT/third_party/py" >/dev/null - tar -xzf "mock-$version.tar.gz" - cd "mock-$version" - $PYTHON ./setup.py install --prefix="$dist" - cd .. - rm -r "mock-$version" - popd >/dev/null -} -pymock_version=1.0.1 -if [ "$BUILD_PYTHON" == 1 ] ; then - install_dep "py-mock" "$pymock_version" "$VTROOT/dist/py-mock-$pymock_version" install_pymock -fi - -# Download Selenium (necessary to run test/vtctld_web_test.py). -function install_selenium() { - local version="$1" - local dist="$2" - - PYTHONPATH='' $VIRTUALENV "$dist" - PIP="$dist/bin/pip" - # PYTHONPATH is removed for `pip install` because otherwise it can pick up go/dist/grpc/usr/local/lib/python2.7/site-packages - # instead of go/dist/selenium/lib/python3.5/site-packages and then can't find module 'pip._vendor.requests' - PYTHONPATH='' $PIP install selenium -} -if [ "$BUILD_PYTHON" == 1 ] ; then - install_dep "Selenium" "latest" "$VTROOT/dist/selenium" install_selenium -fi - -# Download chromedriver (necessary to run test/vtctld_web_test.py). +# Download chromedriver function install_chromedriver() { local version="$1" local dist="$2" + case $(uname) in + Linux) local platform=linux;; + *) echo "Platform not supported for vtctl-web tests. Skipping chromedriver install."; return;; + esac + if [ "$(arch)" == "aarch64" ] ; then os=$(cat /etc/*release | grep "^ID=" | cut -d '=' -f 2) case $os in @@ -283,12 +222,9 @@ function install_chromedriver() { rm chromedriver_linux64.zip fi } -if [ "$BUILD_PYTHON" == 1 ] ; then - install_dep "chromedriver" "73.0.3683.20" "$VTROOT/dist/chromedriver" install_chromedriver -fi -if [ "$BUILD_PYTHON" == 1 ] ; then - PYTHONPATH='' $PIP install mysql-connector-python +if [ "$BUILD_CHROME" == 1 ] ; then + install_dep "chromedriver" "73.0.3683.20" "$VTROOT/dist/chromedriver" install_chromedriver fi echo diff --git a/build.env b/build.env index 467749a10f1..a09807bdf5a 100755 --- a/build.env +++ b/build.env @@ -17,7 +17,7 @@ source ./tools/shell_functions.inc go version >/dev/null 2>&1 || fail "Go is not installed or is not in \$PATH. See https://vitess.io/contributing/build-from-source for install instructions." -goversion_min 1.12 || fail "Go is not version 1.12+. See https://vitess.io/contributing/build-from-source for install instructions." +goversion_min 1.13 || fail "Go version reported: `go version`. Version 1.13+ required. See https://vitess.io/contributing/build-from-source for install instructions." mkdir -p dist mkdir -p bin @@ -32,7 +32,6 @@ mkdir -p "$VTDATAROOT" # Set up required soft links. # TODO(mberlin): Which of these can be deleted? -ln -snf "$PWD/py" py-vtdb ln -snf "$PWD/go/vt/zkctl/zksrv.sh" bin/zksrv.sh ln -snf "$PWD/test/vthook-test.sh" vthook/test.sh ln -snf "$PWD/test/vthook-test_backup_error" vthook/test_backup_error diff --git a/config/tablet/default.yaml b/config/tablet/default.yaml new file mode 100644 index 00000000000..68de610693e --- /dev/null +++ b/config/tablet/default.yaml @@ -0,0 +1,115 @@ +tabletID: zone-1234 + +init: + dbName: # init_db_name_override + keyspace: # init_keyspace + shard: # init_shard + tabletType: # init_tablet_type + timeoutSeconds: 60 # init_timeout + +db: + socket: # db_socket + host: # db_host + port: 0 # db_port + charSet: # db_charset + flags: 0 # db_flags + flavor: # db_flavor + sslCa: # db_ssl_ca + sslCaPath: # db_ssl_ca_path + sslCert: # db_ssl_cert + sslKey: # db_ssl_key + serverName: # db_server_name + connectTimeoutMilliseconds: 0 # db_connect_timeout_ms + app: + user: vt_app # db_app_user + password: # db_app_password + useSsl: true # db_app_use_ssl + preferTcp: false + dba: + user: vt_dba # db_dba_user + password: # db_dba_password + useSsl: true # db_dba_use_ssl + preferTcp: false + filtered: + user: vt_filtered # db_filtered_user + password: # db_filtered_password + useSsl: true # db_filtered_use_ssl + preferTcp: false + repl: + user: vt_repl # db_repl_user + password: # db_repl_password + useSsl: true # db_repl_use_ssl + preferTcp: false + appdebug: + user: vt_appdebug # db_appdebug_user + password: # db_appdebug_password + useSsl: true # db_appdebug_use_ssl + preferTcp: false + allprivs: + user: vt_allprivs # db_allprivs_user + password: # db_allprivs_password + useSsl: true # db_allprivs_use_ssl + preferTcp: false + +oltpReadPool: + size: 16 # queryserver-config-pool-size + timeoutSeconds: 0 # queryserver-config-query-pool-timeout + idleTimeoutSeconds: 1800 # queryserver-config-idle-timeout + prefillParallelism: 0 # queryserver-config-pool-prefill-parallelism + maxWaiters: 50000 # queryserver-config-query-pool-waiter-cap + +olapReadPool: + size: 200 # queryserver-config-stream-pool-size + timeoutSeconds: 0 # queryserver-config-query-pool-timeout + idleTimeoutSeconds: 1800 # queryserver-config-idle-timeout + prefillParallelism: 0 # queryserver-config-stream-pool-prefill-parallelism + maxWaiters: 0 + +txPool: + size: 20 # queryserver-config-transaction-cap + timeoutSeconds: 1 # queryserver-config-txpool-timeout + idleTimeoutSeconds: 1800 # queryserver-config-idle-timeout + prefillParallelism: 0 # queryserver-config-transaction-prefill-parallelism + maxWaiters: 50000 # queryserver-config-txpool-waiter-cap + +oltp: + queryTimeoutSeconds: 30 # queryserver-config-query-timeout + txTimeoutSeconds: 30 # queryserver-config-transaction-timeout + maxRows: 10000 # queryserver-config-max-result-size + warnRows: 0 # queryserver-config-warn-result-size + +hotRowProtection: + mode: disable|dryRun|enable # enable_hot_row_protection, enable_hot_row_protection_dry_run + # Default value is same as txPool.size. + maxQueueSize: 20 # hot_row_protection_max_queue_size + maxGlobalQueueSize: 1000 # hot_row_protection_max_global_queue_size + maxConcurrency: 5 # hot_row_protection_concurrent_transactions + +consolidator: enable|disable|notOnMaster # enable-consolidator, enable-consolidator-replicas +heartbeatIntervalMilliseconds: 0 # heartbeat_enable, heartbeat_interval +shutdownGracePeriodSeconds: 0 # transaction_shutdown_grace_period +passthroughDML: false # queryserver-config-passthrough-dmls +streamBufferSize: 32768 # queryserver-config-stream-buffer-size +queryCacheSize: 5000 # queryserver-config-query-cache-size +schemaReloadIntervalSeconds: 1800 # queryserver-config-schema-reload-time +watchReplication: false # watch_replication_stream +terseErrors: false # queryserver-config-terse-errors +messagePostponeParallelism: 4 # queryserver-config-message-postpone-cap +cacheResultFields: true # enable-query-plan-field-caching + + +# The following flags are currently not supported. +# enforce_strict_trans_tables +# queryserver-config-strict-table-acl +# queryserver-config-enable-table-acl-dry-run +# queryserver-config-acl-exempt-acl +# enable-tx-throttler +# tx-throttler-config +# tx-throttler-healthcheck-cells +# enable_transaction_limit +# enable_transaction_limit_dry_run +# transaction_limit_per_user +# transaction_limit_by_username +# transaction_limit_by_principal +# transaction_limit_by_component +# transaction_limit_by_subcomponent diff --git a/dev.env b/dev.env index f256abbd93a..f1e6e71b896 100644 --- a/dev.env +++ b/dev.env @@ -24,30 +24,6 @@ source ./build.env export VTPORTSTART=15000 -# Add all site-packages or dist-packages directories below $VTROOT/dist to $PYTHONPATH. -BACKUP_IFS="$IFS" -IFS=" -" -# Note that the escaped ( ) around the -or expression are important. -# Otherwise, the -print would match *all* files. -for pypath in $(find "$VTROOT/dist" \( -name site-packages -or -name dist-packages \) -print); do - PYTHONPATH=$(prepend_path "$PYTHONPATH" "$pypath") -done -IFS="$BACKUP_IFS" - -PYTHONPATH=$(prepend_path "$PYTHONPATH" "$VTROOT/py-vtdb") -PYTHONPATH=$(prepend_path "$PYTHONPATH" "$VTROOT/dist/selenium") -PYTHONPATH=$(prepend_path "$PYTHONPATH" "$VTROOT/test") -PYTHONPATH=$(prepend_path "$PYTHONPATH" "$VTROOT/test/cluster/sandbox") -export PYTHONPATH - -# Ensure bootstrap.sh uses python2 on systems which default to python3. -command -v python2 >/dev/null && PYTHON=python2 || PYTHON=python -export PYTHON -command -v pip2 >/dev/null && PIP=pip2 || PIP=pip -export PIP -command -v virtualenv2 >/dev/null && VIRTUALENV=virtualenv2 || VIRTUALENV=virtualenv -export VIRTUALENV # Add chromedriver to path for Selenium tests. PATH=$(prepend_path "$PATH" "$VTROOT/dist/chromedriver") diff --git a/doc/DockerBuild.md b/doc/DockerBuild.md index 986b8e672c6..afb96430655 100644 --- a/doc/DockerBuild.md +++ b/doc/DockerBuild.md @@ -1,4 +1,4 @@ -By default, the [Kubernetes configs](https://github.com/vitessio/vitess/tree/master/examples/kubernetes) +By default, the [Helm Charts](https://github.com/vitessio/vitess/tree/master/helm) point to the `vitess/lite` image on [Docker Hub](https://hub.docker.com/u/vitess/). We created the `lite` image as a stripped down version of our main image `base` such that Kubernetes pods can start faster. @@ -81,19 +81,5 @@ Then you can run our build script for the `lite` image which extracts the Vitess **Note:** If you chose a non-default flavor above, then change `vitess/lite` in the above command to `vitess/lite:`. -1. Change the Kubernetes configs to point to your personal repository: - ```sh - vitess/examples/kubernetes$ sed -i -e 's,image: vitess/lite,image: yourname/vitess:latest,' *.yaml - ``` - - Adding the `:latest` label at the end of the image name tells Kubernetes - to check for a newer image every time a pod is launched. - When you push a new version of your image, any new pods will use it - automatically without you having to clear the Kubernetes image cache. - - Once you've stabilized your image, you'll probably want to replace `:latest` - with a specific label that you change each time you make a new build, - so you can control when pods update. - -1. Launch [Vitess on Kubernetes]({% link getting-started/index.md %}) as usual. +1. Launch [Vitess on Kubernetes](https://vitess.io/docs/get-started/index.html) as usual. diff --git a/doc/V3HighLevelDesign.md b/doc/V3HighLevelDesign.md index 5becdb0d46b..72fc15d43c4 100644 --- a/doc/V3HighLevelDesign.md +++ b/doc/V3HighLevelDesign.md @@ -641,7 +641,7 @@ All other operations are considered ‘cheap’ because they can be applied as t ## Preserving the original representation -In the case of VTGate, the ‘Route’ operation is capable of performing all 9 functions, as long as all the rows needed to fulfil the query reside in a single database. However, those functions have to be expressed as an SQL query. Most often, the original query could just be passed-through to a single shard. So, the one important question is: If we converted a query to its relational representation, can we then convert it back to the original query? The answer is no, or at least not trivially; The relational operators don’t always map one-to-one with the constructs of an SQL statement. Here’s a specific example: +In the case of VTGate, the ‘Route’ operation is capable of performing all 9 functions, as long as all the rows needed to fulfill the query reside in a single database. However, those functions have to be expressed as an SQL query. Most often, the original query could just be passed-through to a single shard. So, the one important question is: If we converted a query to its relational representation, can we then convert it back to the original query? The answer is no, or at least not trivially; The relational operators don’t always map one-to-one with the constructs of an SQL statement. Here’s a specific example: `select count(*), a+1, b from t group by a+1, b` diff --git a/docker/README.md b/docker/README.md index 8627204bf49..0741e7a2f1a 100644 --- a/docker/README.md +++ b/docker/README.md @@ -40,11 +40,3 @@ All these Vitess images include a specific MySQL/MariaDB version ("flavor"). * On Docker Hub we publish only images with MySQL 5.7 to minimize maintenance overhead and avoid confusion. If you are looking for a stable version of Vitess, use the **lite** image with a fixed version. If you are looking for the latest Vitess code in binary form, use the "latest" tag of the **base** image. - -### Kubernetes Tutorial Dependencies - -| Image | How (When) Updated | Description | -| --- | --- | --- | -| **guestbook** | manual (updated with every Vitess release) | Vitess adaption of the Kubernetes guestbook example. Used to showcase sharding in Vitess. Dockerfile is located in [`examples/kubernetes/guestbook/`](https://github.com/vitessio/vitess/tree/master/examples/kubernetes/guestbook). | -| **orchestrator** | manual | Binaries for [Orchestrator](https://github.com/github/orchestrator). It can be used with Vitess for automatic failovers. Currently not part of the Kubernetes Tutorial and only used in tests. | - diff --git a/docker/bootstrap/Dockerfile.common b/docker/bootstrap/Dockerfile.common index 6a9255b38e7..4ee1e190b96 100644 --- a/docker/bootstrap/Dockerfile.common +++ b/docker/bootstrap/Dockerfile.common @@ -1,4 +1,4 @@ -FROM golang:1.12-stretch +FROM golang:1.13-stretch # Install Vitess build dependencies RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ @@ -14,12 +14,6 @@ RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-ins libtool \ make \ openjdk-8-jdk \ - python-crypto \ - python-dev \ - python-mysqldb \ - python-pip \ - ruby \ - ruby-dev \ software-properties-common \ virtualenv \ unzip \ @@ -40,16 +34,13 @@ RUN mkdir -p /vt/src/vitess.io/vitess/dist && \ ENV VTROOT /vt/src/vitess.io/vitess ENV VTDATAROOT /vt/vtdataroot ENV VTPORTSTART 15000 -ENV PYTHONPATH $VTROOT/dist/grpc/usr/local/lib/python2.7/site-packages:$VTROOT/dist/py-mock-1.0.1/lib/python2.7/site-packages:$VTROOT/py-vtdb:$VTROOT/dist/selenium/lib/python2.7/site-packages ENV PATH $VTROOT/bin:$VTROOT/dist/maven/bin:$VTROOT/dist/chromedriver:$PATH ENV USER vitess # Copy files needed for bootstrap COPY bootstrap.sh dev.env build.env go.mod go.sum /vt/src/vitess.io/vitess/ COPY config /vt/src/vitess.io/vitess/config -COPY third_party /vt/src/vitess.io/vitess/third_party COPY tools /vt/src/vitess.io/vitess/tools -COPY travis /vt/src/vitess.io/vitess/travis # Create vitess user RUN groupadd -r vitess && useradd -r -g vitess vitess && \ diff --git a/docker/lite/Dockerfile.ubi7.mysql57 b/docker/lite/Dockerfile.ubi7.mysql57 new file mode 100644 index 00000000000..d4dbe1df4f1 --- /dev/null +++ b/docker/lite/Dockerfile.ubi7.mysql57 @@ -0,0 +1,102 @@ +# Copyright 2019 The Vitess Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# NOTE: We have to build the Vitess binaries from scratch instead of sharing +# a base image because Docker Hub dropped the feature we relied upon to +# ensure images contain the right binaries. + +# Use a temporary layer for the build stage. +FROM vitess/bootstrap:mysql57 AS builder + +# Allows some docker builds to disable CGO +ARG CGO_ENABLED=0 + +# Re-copy sources from working tree. +COPY --chown=vitess:vitess . /vt/src/vitess.io/vitess + +# Build and install Vitess in a temporary output directory. +USER vitess +RUN make install PREFIX=/vt/install + +# Start over and build the final image. +FROM registry.access.redhat.com/ubi7/ubi:latest + +# Install keys and dependencies +RUN mkdir /tmp/gpg && chmod 700 /tmp/gpg && export GNUPGHOME=/tmp/gpg \ + && yum install --setopt=alwaysprompt=no gnupg \ + && ( gpg --keyserver keyserver.ubuntu.com --recv-keys 430BDF5C56E7C94E848EE60C1C4CBDCDCD2EFD2A 4D1BB29D63D98E422B2113B19334A25F8507EFA5 6341AB2753D78A78A7C27BB124C6A8A7F4A80EB5 A4A9406876FCBD3C456770C88C718D3B5072E1F5 \ + || gpg --keyserver ha.pool.sks-keyservers.net --recv-keys 430BDF5C56E7C94E848EE60C1C4CBDCDCD2EFD2A 4D1BB29D63D98E422B2113B19334A25F8507EFA5 6341AB2753D78A78A7C27BB124C6A8A7F4A80EB5 A4A9406876FCBD3C456770C88C718D3B5072E1F5 ) \ + && gpg --export --armor 430BDF5C56E7C94E848EE60C1C4CBDCDCD2EFD2A > ${GNUPGHOME}/RPM-GPG-KEY-Percona.1 \ + && gpg --export --armor 4D1BB29D63D98E422B2113B19334A25F8507EFA5 > ${GNUPGHOME}/RPM-GPG-KEY-Percona.2 \ + && gpg --export --armor 6341AB2753D78A78A7C27BB124C6A8A7F4A80EB5 > ${GNUPGHOME}/RPM-GPG-KEY-CentOS-7 \ + && gpg --export --armor A4A9406876FCBD3C456770C88C718D3B5072E1F5 > ${GNUPGHOME}/RPM-GPG-KEY-MySQL \ + && rpmkeys --import ${GNUPGHOME}/RPM-GPG-KEY-Percona.1 ${GNUPGHOME}/RPM-GPG-KEY-Percona.2 ${GNUPGHOME}/RPM-GPG-KEY-CentOS-7 ${GNUPGHOME}/RPM-GPG-KEY-MySQL /etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release \ + && curl -L --retry-delay 10 --retry 3 -o /tmp/mysqlrepo.rpm https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm \ + && curl -L --retry-delay 10 --retry 3 -o /tmp/perconarepo.rpm https://repo.percona.com/yum/percona-release-latest.noarch.rpm \ + && rpmkeys --checksig /tmp/mysqlrepo.rpm /tmp/perconarepo.rpm \ + && rpm -Uvh /tmp/mysqlrepo.rpm /tmp/perconarepo.rpm \ + && rm -f /tmp/mysqlrepo.rpm /tmp/perconarepo.rpm +RUN curl -L --retry-delay 10 --retry 3 -o /tmp/libev.rpm http://mirror.centos.org/centos/7/extras/x86_64/Packages/libev-4.15-7.el7.x86_64.rpm \ + && curl -L --retry-delay 10 --retry 3 -o /tmp/gperf.rpm http://mirror.centos.org/centos/7/os/x86_64/Packages/gperftools-libs-2.6.1-1.el7.x86_64.rpm \ + && curl -L --retry-delay 10 --retry 3 -o /tmp/numactl.rpm http://mirror.centos.org/centos/7/updates/x86_64/Packages/numactl-libs-2.0.12-3.el7_7.1.x86_64.rpm \ + && curl -L --retry-delay 10 --retry 3 -o /tmp/sysstat.rpm http://mirror.centos.org/centos/7/updates/x86_64/Packages/sysstat-10.1.5-18.el7_7.1.x86_64.rpm \ + && curl -L --retry-delay 10 --retry 3 -o /tmp/strace.rpm http://mirror.centos.org/centos/7/os/x86_64/Packages/strace-4.12-9.el7.x86_64.rpm \ + && rpm -i --nodeps /tmp/libev.rpm /tmp/gperf.rpm /tmp/numactl.rpm /tmp/sysstat.rpm /tmp/strace.rpm \ + && rm -f /tmp/libev.rpm /tmp/gperf.rpm /tmp/numactl.rpm /tmp/sysstat.rpm /tmp/strace.rpm +RUN yum update \ + && yum install --setopt=alwaysprompt=no --setopt=tsflags=nodocs bzip2 ca-certificates gnupg libaio libcurl \ + jemalloc gperftools-libs procps-ng rsync wget openssl hostname curl tzdata make \ +# Can't use alwaysprompt=no here, since we need to pick up deps +# No way to separate key imports and accept deps separately in yum/dnf + && yum install -y --setopt=tsflags=nodocs --enablerepo mysql57-community --disablerepo mysql80-community \ + mysql-community-client mysql-community-server \ +# Have to use hacks to ignore conflicts on /etc/my.cnf install + && mkdir -p /tmp/1 \ + && yum install --setopt=alwaysprompt=no --downloadonly --downloaddir=/tmp/1 --enablerepo mysql57-community --disablerepo mysql80-community percona-xtrabackup-24 \ + && rpm -Uvh --replacefiles /tmp/1/*rpm \ + && rm -rf /tmp/1 \ + && yum clean all \ + && yum clean all --enablerepo mysql57-community --disablerepo mysql80-community \ + && rm -rf /etc/my.cnf /var/lib/mysql /tmp/gpg /sbin/mysqld-debug + +# Set up Vitess user and directory tree. +RUN groupadd -g 1001 -r vitess && useradd -r -u 1001 -g vitess vitess +RUN mkdir -p /vt/vtdataroot && chown -R vitess:vitess /vt + +# Set up Vitess environment (just enough to run pre-built Go binaries) +ENV VTROOT /vt/src/vitess.io/vitess +ENV VTDATAROOT /vt/vtdataroot +ENV PATH $VTROOT/bin:$PATH + +# Copy artifacts from builder layer. +COPY --from=builder --chown=vitess:vitess /vt/install /vt + +RUN mkdir -p /licenses +COPY LICENSE /licenses + +# Create mount point for actual data (e.g. MySQL data dir) +VOLUME /vt/vtdataroot +USER vitess + +LABEL name="Vitess Lite image - MySQL Community Server 5.7" \ + io.k8s.display-name="Vitess Lite image - MySQL Community Server 5.7" \ + maintainer="cncf-vitess-maintainers@lists.cncf.io" \ + vendor="CNCF" \ + version="6.0.0" \ + release="1" \ + summary="Vitess base container image, containing Vitess components along with MySQL Community Server 5.7" \ + description="Vitess base container image, containing Vitess components along with MySQL Community Server 5.7" \ + io.k8s.description="Vitess base container image, containing Vitess components along with MySQL Community Server 5.7" \ + distribution-scope="public" \ + url="https://vitess.io" diff --git a/docker/lite/Dockerfile.ubi7.mysql80 b/docker/lite/Dockerfile.ubi7.mysql80 new file mode 100644 index 00000000000..9da03ca65a6 --- /dev/null +++ b/docker/lite/Dockerfile.ubi7.mysql80 @@ -0,0 +1,103 @@ +# Copyright 2019 The Vitess Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# NOTE: We have to build the Vitess binaries from scratch instead of sharing +# a base image because Docker Hub dropped the feature we relied upon to +# ensure images contain the right binaries. + +# Use a temporary layer for the build stage. +FROM vitess/bootstrap:mysql80 AS builder + +# Allows some docker builds to disable CGO +ARG CGO_ENABLED=0 + +# Re-copy sources from working tree. +COPY --chown=vitess:vitess . /vt/src/vitess.io/vitess + +# Build and install Vitess in a temporary output directory. +USER vitess +RUN make install PREFIX=/vt/install + +# Start over and build the final image. +FROM registry.access.redhat.com/ubi7/ubi:latest + +# Install keys and dependencies +RUN mkdir /tmp/gpg && chmod 700 /tmp/gpg && export GNUPGHOME=/tmp/gpg \ + && yum install --setopt=alwaysprompt=no gnupg \ + && ( gpg --keyserver keyserver.ubuntu.com --recv-keys 430BDF5C56E7C94E848EE60C1C4CBDCDCD2EFD2A 4D1BB29D63D98E422B2113B19334A25F8507EFA5 6341AB2753D78A78A7C27BB124C6A8A7F4A80EB5 A4A9406876FCBD3C456770C88C718D3B5072E1F5 \ + || gpg --keyserver ha.pool.sks-keyservers.net --recv-keys 430BDF5C56E7C94E848EE60C1C4CBDCDCD2EFD2A 4D1BB29D63D98E422B2113B19334A25F8507EFA5 6341AB2753D78A78A7C27BB124C6A8A7F4A80EB5 A4A9406876FCBD3C456770C88C718D3B5072E1F5 ) \ + && gpg --export --armor 430BDF5C56E7C94E848EE60C1C4CBDCDCD2EFD2A > ${GNUPGHOME}/RPM-GPG-KEY-Percona.1 \ + && gpg --export --armor 4D1BB29D63D98E422B2113B19334A25F8507EFA5 > ${GNUPGHOME}/RPM-GPG-KEY-Percona.2 \ + && gpg --export --armor 6341AB2753D78A78A7C27BB124C6A8A7F4A80EB5 > ${GNUPGHOME}/RPM-GPG-KEY-CentOS-7 \ + && gpg --export --armor A4A9406876FCBD3C456770C88C718D3B5072E1F5 > ${GNUPGHOME}/RPM-GPG-KEY-MySQL \ + && rpmkeys --import ${GNUPGHOME}/RPM-GPG-KEY-Percona.1 ${GNUPGHOME}/RPM-GPG-KEY-Percona.2 ${GNUPGHOME}/RPM-GPG-KEY-CentOS-7 ${GNUPGHOME}/RPM-GPG-KEY-MySQL /etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release \ + && curl -L --retry-delay 10 --retry 3 -o /tmp/mysqlrepo.rpm https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm \ + && curl -L --retry-delay 10 --retry 3 -o /tmp/perconarepo.rpm https://repo.percona.com/yum/percona-release-latest.noarch.rpm \ + && rpmkeys --checksig /tmp/mysqlrepo.rpm /tmp/perconarepo.rpm \ + && rpm -Uvh /tmp/mysqlrepo.rpm /tmp/perconarepo.rpm \ + && rm -f /tmp/mysqlrepo.rpm /tmp/perconarepo.rpm +RUN curl -L --retry-delay 10 --retry 3 -o /tmp/libev.rpm http://mirror.centos.org/centos/7/extras/x86_64/Packages/libev-4.15-7.el7.x86_64.rpm \ + && curl -L --retry-delay 10 --retry 3 -o /tmp/gperf.rpm http://mirror.centos.org/centos/7/os/x86_64/Packages/gperftools-libs-2.6.1-1.el7.x86_64.rpm \ + && curl -L --retry-delay 10 --retry 3 -o /tmp/numactl.rpm http://mirror.centos.org/centos/7/updates/x86_64/Packages/numactl-libs-2.0.12-3.el7_7.1.x86_64.rpm \ + && curl -L --retry-delay 10 --retry 3 -o /tmp/sysstat.rpm http://mirror.centos.org/centos/7/updates/x86_64/Packages/sysstat-10.1.5-18.el7_7.1.x86_64.rpm \ + && curl -L --retry-delay 10 --retry 3 -o /tmp/strace.rpm http://mirror.centos.org/centos/7/os/x86_64/Packages/strace-4.12-9.el7.x86_64.rpm \ + && rpm -i --nodeps /tmp/libev.rpm /tmp/gperf.rpm /tmp/numactl.rpm /tmp/sysstat.rpm /tmp/strace.rpm \ + && rm -f /tmp/libev.rpm /tmp/gperf.rpm /tmp/numactl.rpm /tmp/sysstat.rpm /tmp/strace.rpm +RUN yum update \ + && yum install --setopt=alwaysprompt=no --setopt=tsflags=nodocs bzip2 ca-certificates gnupg libaio libcurl \ + jemalloc gperftools-libs procps-ng rsync wget openssl hostname curl tzdata make \ +# Can't use alwaysprompt=no here, since we need to pick up deps +# No way to separate key imports and accept deps separately in yum/dnf + && yum install -y --setopt=tsflags=nodocs --enablerepo mysql80-community --disablerepo mysql57-community \ + mysql-community-client mysql-community-server \ +# Have to use hacks to ignore conflicts on /etc/my.cnf install + && mkdir -p /tmp/1 \ + && yum install --setopt=alwaysprompt=no --downloadonly --downloaddir=/tmp/1 --enablerepo mysql80-community --disablerepo mysql57-community percona-xtrabackup-80 \ + && rpm -Uvh --replacefiles /tmp/1/*rpm \ + && rm -rf /tmp/1 \ + && yum clean all \ + && yum clean all --enablerepo mysql80-community --disablerepo mysql57-community \ + && rm -rf /etc/my.cnf /var/lib/mysql /tmp/gpg /sbin/mysqld-debug + +# Set up Vitess user and directory tree. +RUN groupadd -g 1001 -r vitess && useradd -r -u 1001 -g vitess vitess +RUN mkdir -p /vt/vtdataroot && chown -R vitess:vitess /vt + +# Set up Vitess environment (just enough to run pre-built Go binaries) +ENV VTROOT /vt/src/vitess.io/vitess +ENV VTDATAROOT /vt/vtdataroot +ENV PATH $VTROOT/bin:$PATH +ENV MYSQL_FLAVOR MySQL80 + +# Copy artifacts from builder layer. +COPY --from=builder --chown=vitess:vitess /vt/install /vt + +RUN mkdir -p /licenses +COPY LICENSE /licenses + +# Create mount point for actual data (e.g. MySQL data dir) +VOLUME /vt/vtdataroot +USER vitess + +LABEL name="Vitess Lite image - MySQL Community Server 8.0" \ + io.k8s.display-name="Vitess Lite image - MySQL Community Server 8.0" \ + maintainer="cncf-vitess-maintainers@lists.cncf.io" \ + vendor="CNCF" \ + version="6.0.0" \ + release="1" \ + summary="Vitess base container image, containing Vitess components along with MySQL Community Server 8.0" \ + description="Vitess base container image, containing Vitess components along with MySQL Community Server 8.0" \ + io.k8s.description="Vitess base container image, containing Vitess components along with MySQL Community Server 8.0" \ + distribution-scope="public" \ + url="https://vitess.io" diff --git a/docker/lite/Dockerfile.ubi7.percona57 b/docker/lite/Dockerfile.ubi7.percona57 new file mode 100644 index 00000000000..c05e8150cfc --- /dev/null +++ b/docker/lite/Dockerfile.ubi7.percona57 @@ -0,0 +1,93 @@ +# Copyright 2019 The Vitess Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# NOTE: We have to build the Vitess binaries from scratch instead of sharing +# a base image because Docker Hub dropped the feature we relied upon to +# ensure images contain the right binaries. + +# Use a temporary layer for the build stage. +FROM vitess/bootstrap:percona57 AS builder + +# Allows some docker builds to disable CGO +ARG CGO_ENABLED=0 + +# Re-copy sources from working tree. +COPY --chown=vitess:vitess . /vt/src/vitess.io/vitess + +# Build and install Vitess in a temporary output directory. +USER vitess +RUN make install PREFIX=/vt/install + +# Start over and build the final image. +FROM registry.access.redhat.com/ubi7/ubi:latest + +# Install keys and dependencies +RUN mkdir /tmp/gpg && chmod 700 /tmp/gpg && export GNUPGHOME=/tmp/gpg \ + && yum install --setopt=alwaysprompt=no gnupg \ + && ( gpg --keyserver keyserver.ubuntu.com --recv-keys 430BDF5C56E7C94E848EE60C1C4CBDCDCD2EFD2A 4D1BB29D63D98E422B2113B19334A25F8507EFA5 6341AB2753D78A78A7C27BB124C6A8A7F4A80EB5 \ + || gpg --keyserver ha.pool.sks-keyservers.net --recv-keys 430BDF5C56E7C94E848EE60C1C4CBDCDCD2EFD2A 4D1BB29D63D98E422B2113B19334A25F8507EFA5 6341AB2753D78A78A7C27BB124C6A8A7F4A80EB5 ) \ + && gpg --export --armor 430BDF5C56E7C94E848EE60C1C4CBDCDCD2EFD2A > ${GNUPGHOME}/RPM-GPG-KEY-Percona.1 \ + && gpg --export --armor 4D1BB29D63D98E422B2113B19334A25F8507EFA5 > ${GNUPGHOME}/RPM-GPG-KEY-Percona.2 \ + && gpg --export --armor 6341AB2753D78A78A7C27BB124C6A8A7F4A80EB5 > ${GNUPGHOME}/RPM-GPG-KEY-CentOS-7 \ + && rpmkeys --import ${GNUPGHOME}/RPM-GPG-KEY-Percona.1 ${GNUPGHOME}/RPM-GPG-KEY-Percona.2 ${GNUPGHOME}/RPM-GPG-KEY-CentOS-7 /etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release \ + && curl -L --retry-delay 10 --retry 3 -o /tmp/perconarepo.rpm https://repo.percona.com/yum/percona-release-latest.noarch.rpm \ + && rpmkeys --checksig /tmp/perconarepo.rpm \ + && rpm -Uvh /tmp/perconarepo.rpm \ + && rm -f /tmp/perconarepo.rpm +RUN curl -L --retry-delay 10 --retry 3 -o /tmp/libev.rpm http://mirror.centos.org/centos/7/extras/x86_64/Packages/libev-4.15-7.el7.x86_64.rpm \ + && curl -L --retry-delay 10 --retry 3 -o /tmp/gperf.rpm http://mirror.centos.org/centos/7/os/x86_64/Packages/gperftools-libs-2.6.1-1.el7.x86_64.rpm \ + && curl -L --retry-delay 10 --retry 3 -o /tmp/numactl.rpm http://mirror.centos.org/centos/7/updates/x86_64/Packages/numactl-libs-2.0.12-3.el7_7.1.x86_64.rpm \ + && curl -L --retry-delay 10 --retry 3 -o /tmp/sysstat.rpm http://mirror.centos.org/centos/7/updates/x86_64/Packages/sysstat-10.1.5-18.el7_7.1.x86_64.rpm \ + && curl -L --retry-delay 10 --retry 3 -o /tmp/strace.rpm http://mirror.centos.org/centos/7/os/x86_64/Packages/strace-4.12-9.el7.x86_64.rpm \ + && rpm -i --nodeps /tmp/libev.rpm /tmp/gperf.rpm /tmp/numactl.rpm /tmp/sysstat.rpm /tmp/strace.rpm \ + && rm -f /tmp/libev.rpm /tmp/gperf.rpm /tmp/numactl.rpm /tmp/sysstat.rpm /tmp/strace.rpm +RUN yum update \ + && yum install --setopt=alwaysprompt=no --setopt=tsflags=nodocs bzip2 ca-certificates gnupg libaio libcurl \ + jemalloc gperftools-libs procps-ng rsync wget openssl hostname curl tzdata make \ +# Can't use alwaysprompt=no here, since we need to pick up deps +# No way to separate key imports and accept deps separately in yum/dnf + && yum install -y --setopt=tsflags=nodocs Percona-Server-server-57 percona-xtrabackup-24 \ + && yum clean all \ + && rm -rf /etc/my.cnf /var/lib/mysql /tmp/gpg /sbin/mysqld-debug + +# Set up Vitess user and directory tree. +RUN groupadd -g 1001 -r vitess && useradd -r -u 1001 -g vitess vitess +RUN mkdir -p /vt/vtdataroot && chown -R vitess:vitess /vt + +# Set up Vitess environment (just enough to run pre-built Go binaries) +ENV VTROOT /vt/src/vitess.io/vitess +ENV VTDATAROOT /vt/vtdataroot +ENV PATH $VTROOT/bin:$PATH + +# Copy artifacts from builder layer. +COPY --from=builder --chown=vitess:vitess /vt/install /vt + +RUN mkdir -p /licenses +COPY LICENSE /licenses + +# Create mount point for actual data (e.g. MySQL data dir) +VOLUME /vt/vtdataroot +USER vitess + +LABEL name="Vitess Lite image - Percona Server 5.7" \ + io.k8s.display-name="Vitess Lite image - Percona Server 5.7" \ + maintainer="cncf-vitess-maintainers@lists.cncf.io" \ + vendor="CNCF" \ + version="6.0.0" \ + release="1" \ + summary="Vitess base container image, containing Vitess components along with Percona Server 5.7" \ + description="Vitess base container image, containing Vitess components along with Percona Server 5.7" \ + io.k8s.description="Vitess base container image, containing Vitess components along with Percona Server 5.7" \ + distribution-scope="public" \ + url="https://vitess.io" diff --git a/docker/lite/Dockerfile.ubi7.percona80 b/docker/lite/Dockerfile.ubi7.percona80 new file mode 100644 index 00000000000..828b0a79db6 --- /dev/null +++ b/docker/lite/Dockerfile.ubi7.percona80 @@ -0,0 +1,98 @@ +# Copyright 2019 The Vitess Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# NOTE: We have to build the Vitess binaries from scratch instead of sharing +# a base image because Docker Hub dropped the feature we relied upon to +# ensure images contain the right binaries. + +# Use a temporary layer for the build stage. +FROM vitess/bootstrap:percona80 AS builder + +# Allows some docker builds to disable CGO +ARG CGO_ENABLED=0 + +# Re-copy sources from working tree. +COPY --chown=vitess:vitess . /vt/src/vitess.io/vitess + +# Build and install Vitess in a temporary output directory. +USER vitess +RUN make install PREFIX=/vt/install + +# Start over and build the final image. +FROM registry.access.redhat.com/ubi7/ubi:latest + +# Install keys and dependencies +RUN mkdir /tmp/gpg && chmod 700 /tmp/gpg && export GNUPGHOME=/tmp/gpg \ + && yum install --setopt=alwaysprompt=no gnupg \ + && ( gpg --keyserver keyserver.ubuntu.com --recv-keys 430BDF5C56E7C94E848EE60C1C4CBDCDCD2EFD2A 4D1BB29D63D98E422B2113B19334A25F8507EFA5 6341AB2753D78A78A7C27BB124C6A8A7F4A80EB5 \ + || gpg --keyserver ha.pool.sks-keyservers.net --recv-keys 430BDF5C56E7C94E848EE60C1C4CBDCDCD2EFD2A 4D1BB29D63D98E422B2113B19334A25F8507EFA5 6341AB2753D78A78A7C27BB124C6A8A7F4A80EB5 ) \ + && gpg --export --armor 430BDF5C56E7C94E848EE60C1C4CBDCDCD2EFD2A > ${GNUPGHOME}/RPM-GPG-KEY-Percona.1 \ + && gpg --export --armor 4D1BB29D63D98E422B2113B19334A25F8507EFA5 > ${GNUPGHOME}/RPM-GPG-KEY-Percona.2 \ + && gpg --export --armor 6341AB2753D78A78A7C27BB124C6A8A7F4A80EB5 > ${GNUPGHOME}/RPM-GPG-KEY-CentOS-7 \ + && rpmkeys --import ${GNUPGHOME}/RPM-GPG-KEY-Percona.1 ${GNUPGHOME}/RPM-GPG-KEY-Percona.2 ${GNUPGHOME}/RPM-GPG-KEY-CentOS-7 /etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release \ + && curl -L --retry-delay 10 --retry 3 -o /tmp/perconarepo.rpm https://repo.percona.com/yum/percona-release-latest.noarch.rpm \ + && rpmkeys --checksig /tmp/perconarepo.rpm \ + && rpm -Uvh /tmp/perconarepo.rpm \ + && rm -f /tmp/perconarepo.rpm +RUN curl -L --retry-delay 10 --retry 3 -o /tmp/libev.rpm http://mirror.centos.org/centos/7/extras/x86_64/Packages/libev-4.15-7.el7.x86_64.rpm \ + && curl -L --retry-delay 10 --retry 3 -o /tmp/gperf.rpm http://mirror.centos.org/centos/7/os/x86_64/Packages/gperftools-libs-2.6.1-1.el7.x86_64.rpm \ + && curl -L --retry-delay 10 --retry 3 -o /tmp/numactl.rpm http://mirror.centos.org/centos/7/updates/x86_64/Packages/numactl-libs-2.0.12-3.el7_7.1.x86_64.rpm \ + && curl -L --retry-delay 10 --retry 3 -o /tmp/sysstat.rpm http://mirror.centos.org/centos/7/updates/x86_64/Packages/sysstat-10.1.5-18.el7_7.1.x86_64.rpm \ + && curl -L --retry-delay 10 --retry 3 -o /tmp/strace.rpm http://mirror.centos.org/centos/7/os/x86_64/Packages/strace-4.12-9.el7.x86_64.rpm \ + && rpm -i --nodeps /tmp/libev.rpm /tmp/gperf.rpm /tmp/numactl.rpm /tmp/sysstat.rpm /tmp/strace.rpm \ + && rm -f /tmp/libev.rpm /tmp/gperf.rpm /tmp/numactl.rpm /tmp/sysstat.rpm /tmp/strace.rpm +RUN yum update \ + && yum install --setopt=alwaysprompt=no --setopt=tsflags=nodocs bzip2 ca-certificates gnupg libaio libcurl \ + jemalloc gperftools-libs procps-ng rsync wget openssl hostname curl tzdata make \ + && percona-release setup ps80 \ +# Without this pause, the subsequent yum install fails downloads +# regularly + && sleep 5 \ +# Can't use alwaysprompt=no here, since we need to pick up deps +# No way to separate key imports and accept deps separately in yum/dnf + && yum install -y --setopt=tsflags=nodocs percona-server-server percona-xtrabackup-80 \ + && yum clean all \ + && rm -rf /etc/my.cnf /var/lib/mysql /tmp/gpg /sbin/mysqld-debug + +# Set up Vitess user and directory tree. +RUN groupadd -g 1001 -r vitess && useradd -r -u 1001 -g vitess vitess +RUN mkdir -p /vt/vtdataroot && chown -R vitess:vitess /vt + +# Set up Vitess environment (just enough to run pre-built Go binaries) +ENV VTROOT /vt/src/vitess.io/vitess +ENV VTDATAROOT /vt/vtdataroot +ENV PATH $VTROOT/bin:$PATH +ENV MYSQL_FLAVOR MySQL80 + +# Copy artifacts from builder layer. +COPY --from=builder --chown=vitess:vitess /vt/install /vt + +RUN mkdir -p /licenses +COPY LICENSE /licenses + +# Create mount point for actual data (e.g. MySQL data dir) +VOLUME /vt/vtdataroot +USER vitess + +LABEL name="Vitess Lite image - Percona Server 8.0" \ + io.k8s.display-name="Vitess Lite image - Percona Server 8.0" \ + maintainer="cncf-vitess-maintainers@lists.cncf.io" \ + vendor="CNCF" \ + version="6.0.0" \ + release="1" \ + summary="Vitess base container image, containing Vitess components along with Percona Server 8.0" \ + description="Vitess base container image, containing Vitess components along with Percona Server 8.0" \ + io.k8s.description="Vitess base container image, containing Vitess components along with Percona Server 8.0" \ + distribution-scope="public" \ + url="https://vitess.io" diff --git a/docker/lite/install_dependencies.sh b/docker/lite/install_dependencies.sh index 60c66642bdd..986d80df05d 100755 --- a/docker/lite/install_dependencies.sh +++ b/docker/lite/install_dependencies.sh @@ -31,6 +31,8 @@ BASE_PACKAGES=( libtcmalloc-minimal4 procps rsync + strace + sysstat wget ) @@ -172,4 +174,4 @@ apt-get install -y --no-install-recommends "${PACKAGES[@]}" # Clean up files we won't need in the final image. rm -rf /var/lib/apt/lists/* - rm -rf /var/lib/mysql/ \ No newline at end of file + rm -rf /var/lib/mysql/ diff --git a/docker/test/run.sh b/docker/test/run.sh index df0c6a20f82..539a7fa57e0 100755 --- a/docker/test/run.sh +++ b/docker/test/run.sh @@ -165,14 +165,13 @@ bashcmd="" if [[ -z "$existing_cache_image" ]]; then # Construct "cp" command to copy the source code. - bashcmd=$(append_cmd "$bashcmd" "cp -R /tmp/src/!(vtdataroot|dist|bin|lib|vthook|py-vtdb) . && cp -R /tmp/src/.git .") + bashcmd=$(append_cmd "$bashcmd" "cp -R /tmp/src/!(vtdataroot|dist|bin|lib|vthook) . && cp -R /tmp/src/.git .") fi # Reset the environment if this was an old bootstrap. We can detect this from VTTOP presence. bashcmd=$(append_cmd "$bashcmd" "export VTROOT=/vt/src/vitess.io/vitess") bashcmd=$(append_cmd "$bashcmd" "export VTDATAROOT=/vt/vtdataroot") -bashcmd=$(append_cmd "$bashcmd" "export PYTHONPATH=/vt/src/vitess.io/vitess/dist/grpc/usr/local/lib/python2.7/site-packages:/vt/src/vitess.io/vitess/dist/py-mock-1.0.1/lib/python2.7/site-packages:/vt/src/vitess.io/vitess/py-vtdb:/vt/src/vitess.io/vitess/dist/selenium/lib/python2.7/site-packages") bashcmd=$(append_cmd "$bashcmd" "mkdir -p dist; mkdir -p bin; mkdir -p lib; mkdir -p vthook") bashcmd=$(append_cmd "$bashcmd" "rm -rf /vt/dist; ln -s /vt/src/vitess.io/vitess/dist /vt/dist") diff --git a/examples/are-you-alive/.gitignore b/examples/are-you-alive/.gitignore new file mode 100644 index 00000000000..a0ba6e25a73 --- /dev/null +++ b/examples/are-you-alive/.gitignore @@ -0,0 +1,2 @@ +vendor +are-you-alive diff --git a/examples/are-you-alive/Makefile b/examples/are-you-alive/Makefile new file mode 100644 index 00000000000..d6cc94e5f39 --- /dev/null +++ b/examples/are-you-alive/Makefile @@ -0,0 +1,15 @@ +# We are using the public "planetscale-vitess" registry for this +NAME := "us.gcr.io/planetscale-vitess/are-you-alive" +TAG := $$(git log -1 --pretty=%H) +IMG := ${NAME}:${TAG} +LATEST := ${NAME}:latest + +.PHONY: build push + +build: + @docker build -f build/release/Dockerfile -t ${IMG} . + @docker tag ${IMG} ${LATEST} + +push: + @docker push ${IMG} + @docker push ${LATEST} diff --git a/examples/are-you-alive/README.md b/examples/are-you-alive/README.md new file mode 100644 index 00000000000..65bff90cad6 --- /dev/null +++ b/examples/are-you-alive/README.md @@ -0,0 +1,85 @@ +# Are You Alive? + +What does it mean to be alive? + +Well we don't know what it means for you, but we know what it means for a Vitess +Cluster! + +This project contains a simulated client application that can be used to measure +the health of a Vitess cluster over time. + +## Design + +For now, there is a specific database schema and vschema that you must apply to +the database that you are using for this test. + +This client application: + +1. Hammers the database with random data (not a load test though). +1. Measures all the important things: + - Client connection errors + - Write latency + - Read latency from masters + - Read latency from replicas + - Write errors + - Read errors on masters + - Write errors on replicas + - Errors in other operations on masters and replicas (e.g. COUNT) + - Latency on other operations on masters and replicas (e.g. COUNT) + - Data loss (by writing predictable data and testing for that) +1. Reports all these metrics to Prometheus. + +That's it! + +## Usage + +First, [initialize your database with the correct schemas](schemas/README.md). + +Run `are-you-alive --help` for usage. You can us the command line flags to +control the dataset size, whether to target reads at masters and replicas, your +mysql connection string, and the rate at which to send requests. + +Example: + +``` +./are-you-alive --mysql_connection_string +``` + +Where `` points to the database you are trying to test, +and everything else will be set to defaults. + +## Building + +``` +go build vitess.io/vitess/examples/are-you-alive/cmd/are-you-alive +``` + +## Testing + +First, [install docker compose](https://docs.docker.com/compose/install/) and +make sure it's working. Then run: + +``` +docker-compose build +docker-compose up +``` + +This will create a local mysqld and a local prometheus to scrape the app. It +will also start the app with the `--initialize` flag which tells it to +automatically create the test database. You might have to run this twice to +give mysql a chance to do its first initialization. + +After you run docker compose, navigate to `http://localhost:9090` to see +Prometheus and `http://localhost:8080/metrics` to see the raw metrics being +exported. + +## Push to Registry + +If you have push access to the [planetscale public +registry](https://us.gcr.io/planetscale-vitess), you can use the following +commands to build and push the image: + +``` +make build +make push +``` diff --git a/examples/are-you-alive/build/dev/Dockerfile b/examples/are-you-alive/build/dev/Dockerfile new file mode 100644 index 00000000000..3b079cfcf8a --- /dev/null +++ b/examples/are-you-alive/build/dev/Dockerfile @@ -0,0 +1,13 @@ +# Use a [multi stage +# build](https://docs.docker.com/develop/develop-images/multistage-build/) to +# build [reflex](https://github.com/cespare/reflex), a tool that will allow us +# to automatically rerun the project when any files change. +FROM golang:1.12.5 AS build +# Build reflex as a static binary (CGO_ENABLED=0) so we can run it in our final +# container. +RUN CGO_ENABLED=0 go get -v github.com/cespare/reflex + +FROM golang:1.12.5-alpine AS runtime +COPY --from=build /go/bin/reflex /go/bin/reflex +COPY reflex.conf / +ENTRYPOINT ["/go/bin/reflex", "-c", "/reflex.conf"] diff --git a/examples/are-you-alive/build/dev/reflex.conf b/examples/are-you-alive/build/dev/reflex.conf new file mode 100644 index 00000000000..9e92ab1a7ca --- /dev/null +++ b/examples/are-you-alive/build/dev/reflex.conf @@ -0,0 +1,2 @@ +# Rerun "go run" every time a ".go" file changes. +-r '(\.go$)' -s -- go run vitess.io/vitess/examples/are-you-alive/cmd/are-you-alive --initialize diff --git a/examples/are-you-alive/build/release/Dockerfile b/examples/are-you-alive/build/release/Dockerfile new file mode 100644 index 00000000000..67310da895a --- /dev/null +++ b/examples/are-you-alive/build/release/Dockerfile @@ -0,0 +1,7 @@ +FROM golang:1.12.5 AS build +COPY . /go/src/vitess.io/vitess/examples/are-you-alive +RUN CGO_ENABLED=0 go install vitess.io/vitess/examples/are-you-alive/cmd/are-you-alive + +FROM debian:stretch-slim AS runtime +COPY --from=build /go/bin/are-you-alive /go/bin/are-you-alive +ENTRYPOINT ["/go/bin/are-you-alive"] diff --git a/examples/are-you-alive/cmd/are-you-alive/main.go b/examples/are-you-alive/cmd/are-you-alive/main.go new file mode 100644 index 00000000000..fd747468558 --- /dev/null +++ b/examples/are-you-alive/cmd/are-you-alive/main.go @@ -0,0 +1,352 @@ +package main + +import ( + "database/sql" + "flag" + "fmt" + "github.com/go-sql-driver/mysql" + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" + "github.com/prometheus/client_golang/prometheus/promhttp" + "github.com/sirupsen/logrus" + "math/rand" + "net/http" + "os" + "os/signal" + "sync" + "time" + "vitess.io/vitess/examples/are-you-alive/pkg/client" +) + +/* +* To measure data loss, we need predictable writes. We do this with "minPage" +* and "maxPage". Once the difference between them is our desired dataset size, +* we can start deleting old records, but we expect to find one record for every +* "page" number between "minPage" and "maxPage". +* +* We don't measure "update loss" with this client right now. + */ + +var ( + maxPage = 0 + minPage = 0 + dataLossEvents = promauto.NewCounterVec(prometheus.CounterOpts{ + Name: "are_you_alive_data_loss_events", + Help: "Data loss events", + }, + []string{"database_name"}, + ) +) + +func writeNextRecord(environmentName string, connectionString string) error { + + // 1. Call monitored client + err := client.Write(environmentName, connectionString, maxPage) + if err != nil { + // Check to see if this is a duplicate key error. We've seen this + // sometimes happen, and when it does this client app gets stuck in an + // infinite loop of failure to write a duplicate key. It's possible + // that happens because a write is succesful but something goes wrong + // before the client recieves a response, so the client thinks the write + // failed and does not increment the count. + // + // So when we specifically see a duplicate key error, assume that's what + // happened, bump the count, and move on. + // + // See https://github.com/planetscale/planetscale-operator/issues/1776 + if me, ok := err.(*mysql.MySQLError); ok && me.Number == 1062 { + logrus.WithError(err).Warnf( + "Key '%d' already found, incrementing count", maxPage) + maxPage = maxPage + 1 + return nil + } + + logrus.WithError(err).Error("Error writing record") + return err + } + + // 2. Increment "maxPage" + maxPage = maxPage + 1 + return nil +} + +func readRandomRecord(environmentName string, connectionString string) error { + + // 1. Pick Random Number Between "minPage" and "maxPage" + if minPage == maxPage { + logrus.Warn("Nothing has been inserted yet!") + return nil + } + page := (rand.Int() % (maxPage - minPage)) + minPage + + // 2. Read Record + readID, readMsg, err := client.Read(environmentName, connectionString, page) + if err != nil { + if err == sql.ErrNoRows { + // This races with deletion, but if our page is greater than minPage + // we know that it should be in there. If it's less than minPage + // assume we are just racing the deletion goroutine and ignore the + // error. + if page <= minPage { + return nil + } + // For replicas, there is a chance we are suffering from replication + // lag, so ignore the missing row if we are a replica. + // TODO: Should we attempt to roughly figure out replication lag in + // this client, at least to catch major failures? We could probably + // multiply delay by the difference betwen maxCount and the page we + // are trying to read to figure out how long ago the row we were + // trying to write was written. + if client.ParseTabletType(connectionString) == "replica" || + client.ParseTabletType(connectionString) == "rdonly" { + return nil + } + logrus.WithError(err).WithFields(logrus.Fields{ + "page": page, + "minPage": minPage, + "maxPage": maxPage, + }).Error("Query succeeded but record not found, may mean data loss") + dataLossEvents.With( + prometheus.Labels{"database_name": client.ParseDBName(connectionString)}).Inc() + return err + } + logrus.WithError(err).Error("Error reading record") + return err + } + // Add zero here just so the metric exists for this database, even if it's + // zero. + dataLossEvents.With( + prometheus.Labels{"database_name": client.ParseDBName(connectionString)}).Add(0) + logrus.WithFields(logrus.Fields{ + "readID": readID, + "readMsg": readMsg, + }).Debug("Read row!") + + return nil +} + +func runCount(environmentName string, connectionString string) error { + + // 1. Run Count + count, err := client.Count(environmentName, connectionString) + if err != nil { + logrus.WithError(err).Error("Error counting records") + return err + } + logrus.WithFields(logrus.Fields{ + "count": count, + }).Debug("Counted rows!") + + // 2. Log if COUNT != "minPage" - "maxPage" + return nil +} + +func deleteLastRecordIfNecessary(environmentName string, connectionString string) error { + + // 1. Compare "maxPage" - "minPage" to Desired Dataset Size + if (maxPage - minPage) < *datasetSize { + return nil + } + logrus.WithFields(logrus.Fields{ + "current": maxPage - minPage, + "desired": *datasetSize, + }).Debug("Deleting last record") + + // 2. Delete Record If We Are Above Desired Size + err := client.Delete(environmentName, connectionString, minPage) + if err != nil { + logrus.WithError(err).Error("Error deleting record") + return err + } + + // 3. Increment "minPage" + minPage = minPage + 1 + return nil +} + +var ( + mysqlConnectionString = flag.String( + "mysql_connection_string", "", "Connection string for db to test") + prometheusMetricsAddress = flag.String( + "prometheus_metrics_address", ":8080", "Address on which to serve prometheus metrics") + debug = flag.Bool("debug", false, "Enable debug logging") + useVtgate = flag.Bool("vtgate", false, "Using vtgate (for @master and @replica)") + readFromReplica = flag.Bool("replica", false, "Read from replica") + readFromReadOnly = flag.Bool("rdonly", false, "Read from rdonly") + initialize = flag.Bool("initialize", false, "Initialize database (for testing)") + sleepTime = flag.Int("delay", 1*1000*1000*1000, "Delay in nanoseconds between ops") + datasetSize = flag.Int("dataset_size", 10, "Number of total records in database") + environmentName = flag.String("environment_name", "prod", + "Environment the database is deployed in that this client is pointing at") +) + +type runner struct { + connString string + envName string + fn func(string, string) error + errMessage string + sleepTime time.Duration +} + +func (r *runner) run() { + for { + time.Sleep(r.sleepTime) + err := r.fn(r.envName, r.connString) + if err != nil { + logrus.WithError(err).Error(r.errMessage) + } + } +} + +func waitForCtrlC() { + var endWaiter sync.WaitGroup + endWaiter.Add(1) + var signalChannel chan os.Signal + signalChannel = make(chan os.Signal, 1) + signal.Notify(signalChannel, os.Interrupt) + go func() { + <-signalChannel + endWaiter.Done() + }() + endWaiter.Wait() +} + +func runPrometheus() { + http.Handle("/metrics", promhttp.Handler()) + logrus.Fatal(http.ListenAndServe(*prometheusMetricsAddress, nil)) +} + +func main() { + + // 0. Handle Arguments + flag.Parse() + if *debug { + logrus.SetLevel(logrus.DebugLevel) + } + logrus.WithFields(logrus.Fields{ + "mysqlConnectionString": *mysqlConnectionString, + "prometheusMetricsAddress": *prometheusMetricsAddress, + "debug": *debug, + }).Debug("Command line arguments") + + connectionString := "" + if *mysqlConnectionString != "" { + connectionString = *mysqlConnectionString + } else if os.Getenv("MYSQL_CONN_STRING") != "" { + connectionString = os.Getenv("MYSQL_CONN_STRING") + } + masterConnectionString := connectionString + replicaConnectionString := connectionString + rdonlyConnectionString := connectionString + // When using vtgate, we want to append @master and @replica to the DSN, but + // this will fail against normal mysql which we're using for testing. See: + // https://vitess.io/docs/user-guides/faq/#how-do-i-choose-between-master-vs-replica-for-queries + if *useVtgate { + // We need to pass interpolateParams when using a vtgate because + // prepare is not supported. + // + // See: + // - https://github.com/go-sql-driver/mysql/blob/master/README.md#interpolateparams + // - https://github.com/src-d/go-mysql-server/issues/428 + // - https://github.com/vitessio/vitess/pull/3862 + masterConnectionString = fmt.Sprintf("%s@master?interpolateParams=true", connectionString) + replicaConnectionString = fmt.Sprintf("%s@replica?interpolateParams=true", connectionString) + rdonlyConnectionString = fmt.Sprintf("%s@rdonly?interpolateParams=true", connectionString) + } + fmt.Println("masterConnectionString:", masterConnectionString) + fmt.Println("replicaConnectionString:", replicaConnectionString) + fmt.Println("rdonlyConnectionString:", rdonlyConnectionString) + + // 1. Set Up Prometheus Metrics + logrus.Info("Prometheus Go") + go runPrometheus() + + // 2. Initialize Database + logrus.Info("Initializing database") + // For local testing, does not initialize vschema + if *initialize { + client.InitializeDatabase(*environmentName, masterConnectionString, "are_you_alive_messages") + } + client.WipeTestTable(*environmentName, masterConnectionString, "are_you_alive_messages") + + // 3. Start goroutines to do various things + logrus.Info("Starting client goroutines") + deleter := runner{ + connString: masterConnectionString, + envName: *environmentName, + fn: deleteLastRecordIfNecessary, + errMessage: "Recieved error deleting last record", + sleepTime: time.Duration(*sleepTime), + } + go deleter.run() + writer := runner{ + connString: masterConnectionString, + envName: *environmentName, + fn: writeNextRecord, + errMessage: "Recieved error writing next record", + sleepTime: time.Duration(*sleepTime), + } + go writer.run() + reader := runner{ + connString: masterConnectionString, + envName: *environmentName, + fn: readRandomRecord, + errMessage: "Recieved error reading record", + sleepTime: time.Duration(*sleepTime), + } + go reader.run() + counter := runner{ + connString: masterConnectionString, + envName: *environmentName, + fn: runCount, + errMessage: "Recieved error running count", + sleepTime: time.Duration(*sleepTime), + } + go counter.run() + + // Only bother starting a replica reader/counter if we are using a vtgate + // and actually are asking to do replica reads + if *useVtgate && *readFromReplica { + replicaReader := runner{ + connString: replicaConnectionString, + envName: *environmentName, + fn: readRandomRecord, + errMessage: "Recieved error reading record from replica", + sleepTime: time.Duration(*sleepTime), + } + go replicaReader.run() + replicaRowCounter := runner{ + connString: replicaConnectionString, + envName: *environmentName, + fn: runCount, + errMessage: "Recieved error running count on replica", + sleepTime: time.Duration(*sleepTime), + } + go replicaRowCounter.run() + } + + // Only bother starting a rdonly reader/counter if we are using a vtgate and + // actually are asking to do rdonly reads + if *useVtgate && *readFromReadOnly { + replicaReader := runner{ + connString: rdonlyConnectionString, + envName: *environmentName, + fn: readRandomRecord, + errMessage: "Recieved error reading record from rdonly", + sleepTime: time.Duration(*sleepTime), + } + go replicaReader.run() + replicaRowCounter := runner{ + connString: rdonlyConnectionString, + envName: *environmentName, + fn: runCount, + errMessage: "Recieved error running count on rdonly", + sleepTime: time.Duration(*sleepTime), + } + go replicaRowCounter.run() + } + + logrus.Info("Press Ctrl+C to end\n") + waitForCtrlC() + logrus.Info("\n") +} diff --git a/examples/are-you-alive/docker-compose.yml b/examples/are-you-alive/docker-compose.yml new file mode 100644 index 00000000000..603353dcb89 --- /dev/null +++ b/examples/are-you-alive/docker-compose.yml @@ -0,0 +1,29 @@ +# https://www.firehydrant.io/blog/developer-a-go-app-with-docker-compose/ +version: '3' +services: + app: + build: build/dev + image: are-you-alive-dev + volumes: + - .:/go/src/vitess.io/vitess/examples/are-you-alive + working_dir: /go/src/vitess.io/vitess/examples/are-you-alive + environment: + MYSQL_CONN_STRING: root:mysql@tcp(mysql)/testfixture + depends_on: + - mysql + ports: + - 8080:8080 + prom: + image: quay.io/prometheus/prometheus:v2.0.0 + volumes: + - ./prometheus.yml:/etc/prometheus/prometheus.yml + command: "--config.file=/etc/prometheus/prometheus.yml --storage.tsdb.path=/prometheus" + ports: + - 9090:9090 + depends_on: + - app + mysql: + image: mysql:5.7 + environment: + MYSQL_DATABASE: testfixture + MYSQL_ROOT_PASSWORD: mysql diff --git a/examples/are-you-alive/go.mod b/examples/are-you-alive/go.mod new file mode 100644 index 00000000000..9bb69e1307b --- /dev/null +++ b/examples/are-you-alive/go.mod @@ -0,0 +1,9 @@ +module vitess.io/vitess/examples/are-you-alive + +go 1.12 + +require ( + github.com/go-sql-driver/mysql v1.5.0 + github.com/prometheus/client_golang v1.4.1 + github.com/sirupsen/logrus v1.4.2 +) diff --git a/examples/are-you-alive/go.sum b/examples/are-you-alive/go.sum new file mode 100644 index 00000000000..7c05c83b99b --- /dev/null +++ b/examples/are-you-alive/go.sum @@ -0,0 +1,92 @@ +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= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +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= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +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-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs= +github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +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= +github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +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/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.4.1 h1:FFSuS004yOQEtDdTq+TAOLP5xUq63KqAFYyOi8zA+Y8= +github.com/prometheus/client_golang v1.4.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= +github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.9.1 h1:KOMtN28tlbam3/7ZKEYKHhKoJZYYj3gMH4uc62x7X7U= +github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.8 h1:+fpWZdT24pJBiqJdAwYBjPSk+5YmQzYNPYzQsdzLkt8= +github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +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/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82 h1:ywK/j/KkyTHcdyYSZNXGjMwgmDSfjglYZ3vStQ/gSCU= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +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/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +vitess.io/vitess v2.1.1+incompatible h1:nuuGHiWYWpudD3gOCLeGzol2EJ25e/u5Wer2wV1O130= diff --git a/examples/are-you-alive/pkg/client/client.go b/examples/are-you-alive/pkg/client/client.go new file mode 100644 index 00000000000..e4f35d3e882 --- /dev/null +++ b/examples/are-you-alive/pkg/client/client.go @@ -0,0 +1,347 @@ +package client + +import ( + "database/sql" + "fmt" + mysql "github.com/go-sql-driver/mysql" + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" + "github.com/sirupsen/logrus" + "strings" +) + +/* + * This package is meant to provide a client that includes prometheus metrics + * for common database issues. + */ + +var ( + defaultBuckets = []float64{.005, .01, .025, .05, .1, .25, .5, 1, 2.5, 5, 10} + countErrorLatency = promauto.NewHistogramVec(prometheus.HistogramOpts{ + Name: "are_you_alive_count_error_latency_seconds", + Help: "Latency to recieve a count error", + Buckets: defaultBuckets, + }, + []string{"environment_name", "database_name", "tablet_type"}, + ) + readErrorLatency = promauto.NewHistogramVec(prometheus.HistogramOpts{ + Name: "are_you_alive_read_error_latency_seconds", + Help: "Latency to recieve a read error", + Buckets: defaultBuckets, + }, + []string{"environment_name", "database_name", "tablet_type"}, + ) + deleteErrorLatency = promauto.NewHistogramVec(prometheus.HistogramOpts{ + Name: "are_you_alive_delete_error_latency_seconds", + Help: "Latency to recieve a delete error", + Buckets: defaultBuckets, + }, + []string{"environment_name", "database_name"}, + ) + writeErrorLatency = promauto.NewHistogramVec(prometheus.HistogramOpts{ + Name: "are_you_alive_write_error_latency_seconds", + Help: "Latency to recieve a write error", + Buckets: defaultBuckets, + }, + []string{"environment_name", "database_name"}, + ) + connectErrorLatency = promauto.NewHistogramVec(prometheus.HistogramOpts{ + Name: "are_you_alive_connect_error_latency_seconds", + Help: "Latency to recieve a connect error", + Buckets: defaultBuckets, + }, + []string{"environment_name", "database_name", "tablet_type"}, + ) + countLatency = promauto.NewHistogramVec(prometheus.HistogramOpts{ + Name: "are_you_alive_count_latency_seconds", + Help: "Time it takes to count to the database", + Buckets: defaultBuckets, + }, + []string{"environment_name", "database_name", "tablet_type"}, + ) + readLatency = promauto.NewHistogramVec(prometheus.HistogramOpts{ + Name: "are_you_alive_read_latency_seconds", + Help: "Time it takes to read to the database", + Buckets: defaultBuckets, + }, + []string{"environment_name", "database_name", "tablet_type"}, + ) + deleteLatency = promauto.NewHistogramVec(prometheus.HistogramOpts{ + Name: "are_you_alive_delete_latency_seconds", + Help: "Time it takes to delete to the database", + Buckets: defaultBuckets, + }, + []string{"environment_name", "database_name"}, + ) + writeLatency = promauto.NewHistogramVec(prometheus.HistogramOpts{ + Name: "are_you_alive_write_latency_seconds", + Help: "Time it takes to write to the database", + Buckets: defaultBuckets, + }, + []string{"environment_name", "database_name"}, + ) + connectLatency = promauto.NewHistogramVec(prometheus.HistogramOpts{ + Name: "are_you_alive_connect_latency_seconds", + Help: "Time it takes to connect to the database", + Buckets: defaultBuckets, + }, + []string{"environment_name", "database_name", "tablet_type"}, + ) +) + +// ParseDBName extracts the database name from a mysql connection string. +func ParseDBName(connectionString string) string { + mysqlConfig, err := mysql.ParseDSN(connectionString) + if err != nil { + logrus.WithError(err).Fatal("Error parsing DSN!") + } + return mysqlConfig.DBName +} + +// ParseTabletType extracts the tablet type from a vitess specific mysql +// connection string. +// +// See https://vitess.io/docs/faq/queries/ for where these come from. +func ParseTabletType(connectionString string) string { + databaseName := ParseDBName(connectionString) + if strings.HasSuffix(databaseName, "@master") { + return "master" + } else if strings.HasSuffix(databaseName, "@replica") { + return "replica" + } else if strings.HasSuffix(databaseName, "@rdonly") { + return "rdonly" + } else { + return "default" + } +} + +func openDatabase(environmentName string, connectionString string) (*sql.DB, error) { + databaseName := ParseDBName(connectionString) + tabletType := ParseTabletType(connectionString) + // NOTE: This is probably not measuring open connections. I think they + // connections are created/fetched from the pool when an operation is + // actually performed. We could force this with a ping probably, but for + // now this is here just as a sanity check that this is actually all + // happening locally. We should just see everything complete within + // milliseconds. + labels := prometheus.Labels{ + "environment_name": environmentName, + "database_name": databaseName, + "tablet_type": tabletType} + connectTimer := prometheus.NewTimer(connectLatency.With(labels)) + connectErrorTimer := prometheus.NewTimer(connectErrorLatency.With(labels)) + db, err := sql.Open("mysql", connectionString) + if err != nil { + logrus.WithError(err).Error("Error connecting to database") + connectErrorTimer.ObserveDuration() + return nil, err + } + connectTimer.ObserveDuration() + return db, nil +} + +// InitializeDatabase will connect to the given connectionString, drop the +// given tableName, and recreate it with the schema that the rest of the client +// expects. This is not something any normal client would do but is convenient +// here because we are just using this client for monitoring. +func InitializeDatabase(environmentName string, connectionString string, tableName string) error { + + // 0. Create logger + log := logrus.WithField("connection_string", connectionString) + + // 1. Open client to database + db, err := openDatabase(environmentName, connectionString) + if err != nil { + log.WithError(err).Error("Error opening database") + return err + } + defer db.Close() + + // 2. Delete test table, but continue if it's not there + if _, err := db.Exec(fmt.Sprintf("DROP TABLE %s", tableName)); err != nil { + log.WithError(err).Warn("Error deleting database") + } + + // 3. Create table + createSQL := fmt.Sprintf( + "CREATE TABLE IF NOT EXISTS %s(page INT, message VARCHAR(255) NOT NULL, PRIMARY KEY (page))", tableName) + if _, err := db.Exec(createSQL); err != nil { + log.WithError(err).Error("Error creating database") + return err + } + return nil +} + +// WipeTestTable connects to the database given by connectionString and deletes +// everything in the table given by tableName because this client expects the +// table to be empty. No client would normally do this, but it's convenient for +// testing. +func WipeTestTable(environmentName string, connectionString string, tableName string) error { + + // 0. Create logger + log := logrus.WithField("connection_string", connectionString) + + // 1. Open client to database + db, err := openDatabase(environmentName, connectionString) + if err != nil { + log.WithError(err).Error("Error opening database") + return err + } + defer db.Close() + + // 2. Clear database + if _, err := db.Exec(fmt.Sprintf("DELETE FROM %s", tableName)); err != nil { + log.WithError(err).Warn("Error clearing table") + } + return nil +} + +// Write will write the record given by page to the test table in the database +// referenced by connectionString. +func Write(environmentName string, connectionString string, page int) error { + + // 0. Create logger + log := logrus.WithField("connection_string", connectionString) + + // 1. Open client to database + databaseName := ParseDBName(connectionString) + db, err := openDatabase(environmentName, connectionString) + if err != nil { + log.WithError(err).Error("Error opening database") + return err + } + defer db.Close() + + // 2. Write record + labels := prometheus.Labels{ + "environment_name": environmentName, + "database_name": databaseName} + writeTimer := prometheus.NewTimer(writeLatency.With(labels)) + writeErrorTimer := prometheus.NewTimer(writeErrorLatency.With(labels)) + if _, err := db.Exec("INSERT INTO are_you_alive_messages (page, message) VALUES (?, ?)", page, "foo"); err != nil { + log.WithError(err).Error("Error inserting into database") + writeErrorTimer.ObserveDuration() + return err + } + writeTimer.ObserveDuration() + return nil +} + +// Read will read the record given by page from the test table in the database +// referenced by connectionString. +func Read(environmentName string, connectionString string, page int) (int, string, error) { + + // 0. Create logger + log := logrus.WithField("connection_string", connectionString) + + // 1. Open client to database + databaseName := ParseDBName(connectionString) + db, err := openDatabase(environmentName, connectionString) + if err != nil { + log.WithError(err).Error("Error opening database") + return 0, "", err + } + defer db.Close() + + // 2. Read record + tabletType := ParseTabletType(connectionString) + labels := prometheus.Labels{ + "environment_name": environmentName, + "database_name": databaseName, + "tablet_type": tabletType} + readTimer := prometheus.NewTimer(readLatency.With(labels)) + readErrorTimer := prometheus.NewTimer(readErrorLatency.With(labels)) + row := db.QueryRow("SELECT * FROM are_you_alive_messages WHERE page=?", page) + var readID int + var readMsg string + if err := row.Scan(&readID, &readMsg); err != nil { + if err == sql.ErrNoRows { + // If our error is just that we didn't find anything, don't treat + // this as an error or a success. Just return and let the caller + // deal with it so we don't mess up our metrics. + return 0, "", err + } + log.WithError(err).Error("Error connecting to database") + readErrorTimer.ObserveDuration() + return 0, "", err + } + logrus.WithFields(logrus.Fields{ + "readId": readID, + "readMsg": readMsg, + }).Debug("Successfully read row") + readTimer.ObserveDuration() + return readID, readMsg, nil +} + +// Count will count all the documents in the test table in the database +// referenced by connectionString. +func Count(environmentName string, connectionString string) (int, error) { + + // 0. Create logger + log := logrus.WithField("connection_string", connectionString) + + // 1. Open client to database + databaseName := ParseDBName(connectionString) + db, err := openDatabase(environmentName, connectionString) + if err != nil { + log.WithError(err).Error("Error opening database") + return 0, err + } + defer db.Close() + + // 2. Run Count + tabletType := ParseTabletType(connectionString) + labels := prometheus.Labels{ + "environment_name": environmentName, + "database_name": databaseName, + "tablet_type": tabletType} + countTimer := prometheus.NewTimer(countLatency.With(labels)) + countErrorTimer := prometheus.NewTimer(countErrorLatency.With(labels)) + row := db.QueryRow("SELECT COUNT(*) FROM are_you_alive_messages") + var count int + if err := row.Scan(&count); err != nil { + log.WithError(err).Error("Error running count") + countErrorTimer.ObserveDuration() + return 0, err + } + logrus.WithFields(logrus.Fields{ + "count": count, + }).Debug("Successfully ran count") + countTimer.ObserveDuration() + return count, nil +} + +// Delete will delete the record given by page from the test table in the +// database referenced by connectionString. +func Delete(environmentName string, connectionString string, page int) error { + + // 0. Create logger + log := logrus.WithFields(logrus.Fields{ + "connection_string": connectionString, + "page": page, + }) + + // 1. Open client to database + databaseName := ParseDBName(connectionString) + labels := prometheus.Labels{ + "environment_name": environmentName, + "database_name": databaseName} + deleteTimer := prometheus.NewTimer(deleteLatency.With(labels)) + deleteErrorTimer := prometheus.NewTimer(deleteErrorLatency.With(labels)) + db, err := openDatabase(environmentName, connectionString) + if err != nil { + log.WithError(err).Error("Error opening database") + deleteErrorTimer.ObserveDuration() + return err + } + defer db.Close() + + // 2. Delete record + if _, err := db.Exec("DELETE FROM are_you_alive_messages WHERE page=?", page); err != nil { + log.WithError(err).Error("Error deleting record") + deleteErrorTimer.ObserveDuration() + return err + } + deleteTimer.ObserveDuration() + return nil +} diff --git a/examples/are-you-alive/prometheus.yml b/examples/are-you-alive/prometheus.yml new file mode 100644 index 00000000000..d968a28136d --- /dev/null +++ b/examples/are-you-alive/prometheus.yml @@ -0,0 +1,34 @@ +# my global config +global: + scrape_interval: 5s # By default, scrape targets every 5 seconds. + evaluation_interval: 5s # By default, scrape targets every 5 seconds. + # scrape_timeout is set to the global default (10s). + + # Attach these labels to any time series or alerts when communicating with + # external systems (federation, remote storage, Alertmanager). + external_labels: + monitor: 'local-integration-test' + +# Load rules once and periodically evaluate them according to the global 'evaluation_interval'. +rule_files: + # - "first.rules" + # - "second.rules" + +# A scrape configuration containing exactly one endpoint to scrape: +# Here it's Prometheus itself. +scrape_configs: + # The job name is added as a label `job=` to any timeseries scraped from this config. + - job_name: 'prometheus' + + # Override the global default and scrape targets from this job every 5 seconds. + scrape_interval: 5s + + # metrics_path defaults to '/metrics' + # scheme defaults to 'http'. + + static_configs: + - targets: ['localhost:9090'] + - job_name: "app" + scrape_interval: "5s" + static_configs: + - targets: ['app:8080'] diff --git a/examples/are-you-alive/schemas/README.md b/examples/are-you-alive/schemas/README.md new file mode 100644 index 00000000000..e119ab33506 --- /dev/null +++ b/examples/are-you-alive/schemas/README.md @@ -0,0 +1,9 @@ +# Test Schemas + +MySQL schemas and Vitess schemas that must be applied to your cluster to use +this test helper. They should be applied using `vtctlclient` like this: + +``` +vtctlclient -server "" ApplySchema -sql "$(cat create_test_table.sql)" +vtctlclient -server "" ApplyVSchema -vschema "$(cat vschema.json)" +``` diff --git a/examples/are-you-alive/schemas/create_test_table.sql b/examples/are-you-alive/schemas/create_test_table.sql new file mode 100644 index 00000000000..c382d343529 --- /dev/null +++ b/examples/are-you-alive/schemas/create_test_table.sql @@ -0,0 +1,6 @@ +CREATE TABLE IF NOT EXISTS are_you_alive_messages ( + page INT, + message VARCHAR(255) NOT NULL, + PRIMARY KEY (page) +) + diff --git a/examples/are-you-alive/schemas/vschema.json b/examples/are-you-alive/schemas/vschema.json new file mode 100644 index 00000000000..bf8df1b6e64 --- /dev/null +++ b/examples/are-you-alive/schemas/vschema.json @@ -0,0 +1,18 @@ +{ + "sharded": true, + "vindexes": { + "hash": { + "type": "hash" + } + }, + "tables": { + "are_you_alive_messages": { + "column_vindexes": [ + { + "column": "page", + "name": "hash" + } + ] + } + } +} diff --git a/examples/compose/vtcompose/docker-compose.test.yml b/examples/compose/vtcompose/docker-compose.test.yml new file mode 100644 index 00000000000..1e55db8e9fd --- /dev/null +++ b/examples/compose/vtcompose/docker-compose.test.yml @@ -0,0 +1,318 @@ +# This file was generated by running `go run vtcompose/vtcompose.go` with no arguments. + +services: + consul1: + command: agent -server -bootstrap-expect 3 -ui -disable-host-node-id -client 0.0.0.0 + hostname: consul1 + image: consul:latest + ports: + - 8400:8400 + - 8500:8500 + - 8600:8600 + consul2: + command: agent -server -retry-join consul1 -disable-host-node-id + depends_on: + - consul1 + expose: + - "8400" + - "8500" + - "8600" + hostname: consul2 + image: consul:latest + consul3: + command: agent -server -retry-join consul1 -disable-host-node-id + depends_on: + - consul1 + expose: + - "8400" + - "8500" + - "8600" + hostname: consul3 + image: consul:latest + schemaload_test_keyspace: + command: + - sh + - -c + - /script/schemaload.sh + depends_on: + vttablet101: + condition: service_healthy + vttablet201: + condition: service_healthy + environment: + - TOPOLOGY_FLAGS=-topo_implementation consul -topo_global_server_address consul1:8500 + -topo_global_root vitess/global + - WEB_PORT=8080 + - GRPC_PORT=15999 + - CELL=test + - KEYSPACE=test_keyspace + - TARGETTAB=test-0000000101 + - SLEEPTIME=15 + - VSCHEMA_FILE=test_keyspace_vschema.json + - SCHEMA_FILES=test_keyspace_schema_file.sql + - POST_LOAD_FILE= + - EXTERNAL_DB=0 + image: vitess/base + volumes: + - .:/script + schemaload_unsharded_keyspace: + command: + - sh + - -c + - /script/schemaload.sh + depends_on: + vttablet301: + condition: service_healthy + environment: + - TOPOLOGY_FLAGS=-topo_implementation consul -topo_global_server_address consul1:8500 + -topo_global_root vitess/global + - WEB_PORT=8080 + - GRPC_PORT=15999 + - CELL=test + - KEYSPACE=unsharded_keyspace + - TARGETTAB=test-0000000301 + - SLEEPTIME=15 + - VSCHEMA_FILE=unsharded_keyspace_vschema.json + - SCHEMA_FILES=unsharded_keyspace_schema_file.sql + - POST_LOAD_FILE= + - EXTERNAL_DB=0 + image: vitess/base + volumes: + - .:/script + vtctld: + command: + - sh + - -c + - ' $$VTROOT/bin/vtctld -topo_implementation consul -topo_global_server_address + consul1:8500 -topo_global_root vitess/global -cell test -workflow_manager_init + -workflow_manager_use_election -service_map ''grpc-vtctl'' -backup_storage_implementation + file -file_backup_storage_root $$VTDATAROOT/backups -logtostderr=true -port + 8080 -grpc_port 15999 -pid_file $$VTDATAROOT/tmp/vtctld.pid ' + depends_on: + - consul1 + - consul2 + - consul3 + image: vitess/base + ports: + - 15000:8080 + - "15999" + volumes: + - .:/script + vtgate: + command: + - sh + - -c + - '/script/run-forever.sh $$VTROOT/bin/vtgate -topo_implementation consul -topo_global_server_address + consul1:8500 -topo_global_root vitess/global -logtostderr=true -port 8080 -grpc_port + 15999 -mysql_server_port 15306 -mysql_auth_server_impl none -cell test -cells_to_watch + test -tablet_types_to_wait MASTER,REPLICA,RDONLY -gateway_implementation discoverygateway + -service_map ''grpc-vtgateservice'' -pid_file $$VTDATAROOT/tmp/vtgate.pid -normalize_queries=true ' + depends_on: + - vtctld + image: vitess/base + ports: + - 15099:8080 + - "15999" + - 15306:15306 + volumes: + - .:/script + vttablet101: + command: + - sh + - -c + - /script/vttablet-up.sh 101 + depends_on: + - vtctld + environment: + - TOPOLOGY_FLAGS=-topo_implementation consul -topo_global_server_address consul1:8500 + -topo_global_root vitess/global + - WEB_PORT=8080 + - GRPC_PORT=15999 + - CELL=test + - KEYSPACE=test_keyspace + - SHARD=-80 + - ROLE=master + - VTHOST=vttablet101 + - EXTERNAL_DB=0 + - DB_PORT= + - DB_HOST= + - DB_USER= + - DB_PASS= + - DB_CHARSET= + healthcheck: + interval: 30s + retries: 15 + test: + - CMD-SHELL + - curl localhost:8080/debug/health + timeout: 10s + image: vitess/base + ports: + - 15101:8080 + - "15999" + - "3306" + volumes: + - .:/script + vttablet102: + command: + - sh + - -c + - /script/vttablet-up.sh 102 + depends_on: + - vtctld + environment: + - TOPOLOGY_FLAGS=-topo_implementation consul -topo_global_server_address consul1:8500 + -topo_global_root vitess/global + - WEB_PORT=8080 + - GRPC_PORT=15999 + - CELL=test + - KEYSPACE=test_keyspace + - SHARD=-80 + - ROLE=replica + - VTHOST=vttablet102 + - EXTERNAL_DB=0 + - DB_PORT= + - DB_HOST= + - DB_USER= + - DB_PASS= + - DB_CHARSET= + healthcheck: + interval: 30s + retries: 15 + test: + - CMD-SHELL + - curl localhost:8080/debug/health + timeout: 10s + image: vitess/base + ports: + - 15102:8080 + - "15999" + - "3306" + volumes: + - .:/script + vttablet201: + command: + - sh + - -c + - /script/vttablet-up.sh 201 + depends_on: + - vtctld + environment: + - TOPOLOGY_FLAGS=-topo_implementation consul -topo_global_server_address consul1:8500 + -topo_global_root vitess/global + - WEB_PORT=8080 + - GRPC_PORT=15999 + - CELL=test + - KEYSPACE=test_keyspace + - SHARD=80- + - ROLE=master + - VTHOST=vttablet201 + - EXTERNAL_DB=0 + - DB_PORT= + - DB_HOST= + - DB_USER= + - DB_PASS= + - DB_CHARSET= + healthcheck: + interval: 30s + retries: 15 + test: + - CMD-SHELL + - curl localhost:8080/debug/health + timeout: 10s + image: vitess/base + ports: + - 15201:8080 + - "15999" + - "3306" + volumes: + - .:/script + vttablet202: + command: + - sh + - -c + - /script/vttablet-up.sh 202 + depends_on: + - vtctld + environment: + - TOPOLOGY_FLAGS=-topo_implementation consul -topo_global_server_address consul1:8500 + -topo_global_root vitess/global + - WEB_PORT=8080 + - GRPC_PORT=15999 + - CELL=test + - KEYSPACE=test_keyspace + - SHARD=80- + - ROLE=replica + - VTHOST=vttablet202 + - EXTERNAL_DB=0 + - DB_PORT= + - DB_HOST= + - DB_USER= + - DB_PASS= + - DB_CHARSET= + healthcheck: + interval: 30s + retries: 15 + test: + - CMD-SHELL + - curl localhost:8080/debug/health + timeout: 10s + image: vitess/base + ports: + - 15202:8080 + - "15999" + - "3306" + volumes: + - .:/script + vttablet301: + command: + - sh + - -c + - /script/vttablet-up.sh 301 + depends_on: + - vtctld + environment: + - TOPOLOGY_FLAGS=-topo_implementation consul -topo_global_server_address consul1:8500 + -topo_global_root vitess/global + - WEB_PORT=8080 + - GRPC_PORT=15999 + - CELL=test + - KEYSPACE=unsharded_keyspace + - SHARD=- + - ROLE=master + - VTHOST=vttablet301 + - EXTERNAL_DB=0 + - DB_PORT= + - DB_HOST= + - DB_USER= + - DB_PASS= + - DB_CHARSET= + healthcheck: + interval: 30s + retries: 15 + test: + - CMD-SHELL + - curl localhost:8080/debug/health + timeout: 10s + image: vitess/base + ports: + - 15301:8080 + - "15999" + - "3306" + volumes: + - .:/script + vtwork: + command: + - sh + - -c + - '$$VTROOT/bin/vtworker -topo_implementation consul -topo_global_server_address + consul1:8500 -topo_global_root vitess/global -cell test -logtostderr=true -service_map + ''grpc-vtworker'' -port 8080 -grpc_port 15999 -use_v3_resharding_mode=true -pid_file + $$VTDATAROOT/tmp/vtwork.pid ' + depends_on: + - vtctld + image: vitess/base + ports: + - 15100:8080 + - "15999" +version: "2.1" \ No newline at end of file diff --git a/examples/compose/vtcompose/vtcompose.go b/examples/compose/vtcompose/vtcompose.go index 912081b66e6..412542d8cef 100644 --- a/examples/compose/vtcompose/vtcompose.go +++ b/examples/compose/vtcompose/vtcompose.go @@ -34,23 +34,46 @@ import ( "vitess.io/vitess/go/vt/log" ) +const ( + DefaultWebPort = 8080 + webPortUsage = "Web port to be used" + DefaultGrpcPort = 15999 + gRpcPortUsage = "gRPC port to be used" + DefaultMysqlPort = 15306 + mySqlPortUsage = "mySql port to be used" + DefaultKeyspaceData = "test_keyspace:2:1:create_messages.sql,create_tokens.sql;unsharded_keyspace:0:0:create_dinosaurs.sql,create_eggs.sql" + keyspaceDataUsage = "List of keyspace_name/external_db_name:num_of_shards:num_of_replica_tablets:schema_files:lookup_keyspace_name separated by ';'" + DefaultCell = "test" + cellUsage = "Vitess Cell name" + DefaultExternalDbData = "" + externalDbDataUsage = "List of Data corresponding to external DBs. List of ,,,,, separated by ';'" + DefaultTopologyFlags = "-topo_implementation consul -topo_global_server_address consul1:8500 -topo_global_root vitess/global" + topologyFlagsUsage = "Vitess Topology Flags config" +) + var ( tabletsUsed = 0 tablesPath = "tables/" baseDockerComposeFile = flag.String("base_yaml", "vtcompose/docker-compose.base.yml", "Starting docker-compose yaml") baseVschemaFile = flag.String("base_vschema", "vtcompose/base_vschema.json", "Starting vschema json") - topologyFlags = flag.String("topologyFlags", - "-topo_implementation consul -topo_global_server_address consul1:8500 -topo_global_root vitess/global", - "Vitess Topology Flags config") - webPort = flag.String("webPort", "8080", "Web port to be used") - gRpcPort = flag.String("gRpcPort", "15999", "gRPC port to be used") - mySqlPort = flag.String("mySqlPort", "15306", "mySql port to be used") - cell = flag.String("cell", "test", "Vitess Cell name") - keyspaceData = flag.String("keyspaceData", "test_keyspace:2:1:create_messages.sql,create_tokens.sql;unsharded_keyspace:0:0:create_dinosaurs.sql,create_eggs.sql", "List of keyspace_name/external_db_name:num_of_shards:num_of_replica_tablets:schema_files:lookup_keyspace_name separated by ';'") - externalDbData = flag.String("externalDbData", "", "List of Data corresponding to external DBs. List of ,,,,, separated by ';'") + topologyFlags = flag.String("topologyFlags", DefaultTopologyFlags, topologyFlagsUsage) + webPort = flag.Int("webPort", DefaultWebPort, webPortUsage) + gRpcPort = flag.Int("gRpcPort", DefaultGrpcPort, gRpcPortUsage) + mySqlPort = flag.Int("mySqlPort", DefaultMysqlPort, mySqlPortUsage) + cell = flag.String("cell", DefaultCell, cellUsage) + keyspaceData = flag.String("keyspaceData", DefaultKeyspaceData, keyspaceDataUsage) + externalDbData = flag.String("externalDbData", DefaultExternalDbData, externalDbDataUsage) ) +type vtOptions struct { + webPort int + gRpcPort int + mySqlPort int + topologyFlags string + cell string +} + type keyspaceInfo struct { keyspace string shards int @@ -70,8 +93,20 @@ type externalDbInfo struct { dbCharset string } -func newKeyspaceInfo(keyspace string, shards int, replicaTablets int, schemaFiles []string, lookupKeyspace string) keyspaceInfo { - k := keyspaceInfo{keyspace: keyspace, shards: shards, replicaTablets: replicaTablets, schemaFileNames: schemaFiles, lookupKeyspace: lookupKeyspace} +func newKeyspaceInfo( + keyspace string, + shards int, + replicaTablets int, + schemaFiles []string, + lookupKeyspace string, +) keyspaceInfo { + k := keyspaceInfo{ + keyspace: keyspace, + shards: shards, + replicaTablets: replicaTablets, + schemaFileNames: schemaFiles, + lookupKeyspace: lookupKeyspace, + } if len(strings.TrimSpace(lookupKeyspace)) == 0 { k.useLookups = false } else { @@ -83,21 +118,24 @@ func newKeyspaceInfo(keyspace string, shards int, replicaTablets int, schemaFile } func newExternalDbInfo(dbName, dbHost, dbPort, dbUser, dbPass, dbCharset string) externalDbInfo { - d := externalDbInfo{dbName: dbName, dbHost: dbHost, dbPort: dbPort, dbUser: dbUser, dbPass: dbPass, dbCharset: dbCharset} - return d + return externalDbInfo{ + dbName: dbName, + dbHost: dbHost, + dbPort: dbPort, + dbUser: dbUser, + dbPass: dbPass, + dbCharset: dbCharset, + } } -func main() { - flag.Parse() +func parseKeyspaceInfo(keyspaceData string) map[string]keyspaceInfo { keyspaceInfoMap := make(map[string]keyspaceInfo) - externalDbInfoMap := make(map[string]externalDbInfo) - for _, v := range strings.Split(*keyspaceData, ";") { + for _, v := range strings.Split(keyspaceData, ";") { tokens := strings.Split(v, ":") shards, _ := strconv.Atoi(tokens[1]) replicaTablets, _ := strconv.Atoi(tokens[2]) schemaFileNames := strings.Split(tokens[3], ",") - print(shards) if len(tokens) > 4 { keyspaceInfoMap[tokens[0]] = newKeyspaceInfo(tokens[0], shards, replicaTablets, schemaFileNames, tokens[4]) @@ -106,17 +144,39 @@ func main() { } } - for _, v := range strings.Split(*externalDbData, ";") { + return keyspaceInfoMap +} + +func parseExternalDbData(externalDbData string) map[string]externalDbInfo { + externalDbInfoMap := make(map[string]externalDbInfo) + for _, v := range strings.Split(externalDbData, ";") { tokens := strings.Split(v, ":") if len(tokens) > 1 { - externalDbInfoMap[tokens[0]] = newExternalDbInfo(tokens[0], tokens[1], tokens[2], tokens[3], tokens[4], tokens[5]) + externalDbInfoMap[tokens[0]] = + newExternalDbInfo(tokens[0], tokens[1], tokens[2], tokens[3], tokens[4], tokens[5]) } } + return externalDbInfoMap +} + +func main() { + flag.Parse() + keyspaceInfoMap := parseKeyspaceInfo(*keyspaceData) + externalDbInfoMap := parseExternalDbData(*externalDbData) + vtOpts := vtOptions{ + webPort: *webPort, + gRpcPort: *gRpcPort, + mySqlPort: *mySqlPort, + topologyFlags: *topologyFlags, + cell: *cell, + } + + // Write schemaFile. for k, v := range keyspaceInfoMap { if _, ok := externalDbInfoMap[k]; !ok { v.schemaFile = createFile(fmt.Sprintf("%s%s_schema_file.sql", tablesPath, v.keyspace)) - appendtoSqlFile(v.schemaFileNames, v.schemaFile) + appendToSqlFile(v.schemaFileNames, v.schemaFile) closeFile(v.schemaFile) } } @@ -138,8 +198,8 @@ func main() { vSchemaFile, primaryTableColumns = addTablesVschemaPatch(vSchemaFile, keyspaceData.schemaFileNames) if keyspaceData.useLookups { - lookupKeyspace := keyspaceInfoMap[keyspaceData.lookupKeyspace] - vSchemaFile = addLookupDataToVschema(vSchemaFile, lookupKeyspace.schemaFileNames, primaryTableColumns, lookupKeyspace.keyspace) + lookup := keyspaceInfoMap[keyspaceData.lookupKeyspace] + vSchemaFile = addLookupDataToVschema(vSchemaFile, lookup.schemaFileNames, primaryTableColumns, lookup.keyspace) } } @@ -148,7 +208,7 @@ func main() { // Docker Compose File Patches dockerComposeFile := readFile(*baseDockerComposeFile) - dockerComposeFile = applyDockerComposePatches(dockerComposeFile, keyspaceInfoMap, externalDbInfoMap) + dockerComposeFile = applyDockerComposePatches(dockerComposeFile, keyspaceInfoMap, externalDbInfoMap, vtOpts) writeFile(dockerComposeFile, "docker-compose.yml") } @@ -227,9 +287,13 @@ func handleError(err error) { } } -func appendtoSqlFile(schemaFileNames []string, f *os.File) { +func appendToSqlFile(schemaFileNames []string, f *os.File) { for _, file := range schemaFileNames { data, err := ioutil.ReadFile(tablesPath + file) + if err != nil { + log.Fatalf("reading %s: %s", tablesPath+file, err) + } + _, err = f.Write(data) handleError(err) @@ -273,7 +337,6 @@ func getKeyColumns(sqlFile string) string { r, _ := regexp.Compile("[^PRIMARY] (KEY|UNIQUE KEY) .*\\((.*)\\).*") rs := r.FindStringSubmatch(string(sqlFileData)) - print(rs[2]) // replace all ` from column names if exists return strings.ReplaceAll(rs[2], "`", "") } @@ -292,7 +355,12 @@ func addTablesVschemaPatch(vSchemaFile []byte, schemaFileNames []string) ([]byte return vSchemaFile, primaryTableColumns } -func addLookupDataToVschema(vSchemaFile []byte, schemaFileNames []string, primaryTableColumns map[string]string, keyspace string) []byte { +func addLookupDataToVschema( + vSchemaFile []byte, + schemaFileNames []string, + primaryTableColumns map[string]string, + keyspace string, +) []byte { for _, fileName := range schemaFileNames { tableName := fileName[7 : len(fileName)-4] lookupTableOwner := "" @@ -311,8 +379,8 @@ func addLookupDataToVschema(vSchemaFile []byte, schemaFileNames []string, primar vSchemaFile = applyJsonInMemoryPatch(vSchemaFile, addToColumnVIndexes(lookupTableOwner, firstColumnName, tableName)) // Generate Vschema lookup hash types - vSchemaFile = applyJsonInMemoryPatch(vSchemaFile, - generateVschemaLookupHash(tableName, keyspace, firstColumnName, primaryTableColumns[lookupTableOwner], lookupTableOwner)) + lookupHash := generateVschemaLookupHash(tableName, keyspace, firstColumnName, primaryTableColumns[lookupTableOwner], lookupTableOwner) + vSchemaFile = applyJsonInMemoryPatch(vSchemaFile, lookupHash) } return vSchemaFile @@ -335,7 +403,12 @@ func writeFile(file []byte, fileName string) { } } -func applyKeyspaceDependentPatches(dockerComposeFile []byte, keyspaceData keyspaceInfo, externalDbInfoMap map[string]externalDbInfo) []byte { +func applyKeyspaceDependentPatches( + dockerComposeFile []byte, + keyspaceData keyspaceInfo, + externalDbInfoMap map[string]externalDbInfo, + opts vtOptions, +) []byte { var externalDbInfo externalDbInfo if val, ok := externalDbInfoMap[keyspaceData.keyspace]; ok { externalDbInfo = val @@ -354,12 +427,13 @@ func applyKeyspaceDependentPatches(dockerComposeFile []byte, keyspaceData keyspa masterTablets = append(masterTablets, strconv.Itoa((i+1)*100+1)) } - dockerComposeFile = applyInMemoryPatch(dockerComposeFile, generateSchemaload(masterTablets, "", keyspaceData.keyspace, externalDbInfo)) + schemaLoad := generateSchemaload(masterTablets, "", keyspaceData.keyspace, externalDbInfo, opts) + dockerComposeFile = applyInMemoryPatch(dockerComposeFile, schemaLoad) // Append Master and Replica Tablets if keyspaceData.shards < 2 { tabAlias = tabAlias + 100 - dockerComposeFile = applyTabletPatches(dockerComposeFile, tabAlias, shard, keyspaceData, externalDbInfoMap) + dockerComposeFile = applyTabletPatches(dockerComposeFile, tabAlias, shard, keyspaceData, externalDbInfoMap, opts) } else { // Determine shard range for i := 0; i < keyspaceData.shards; i++ { @@ -371,7 +445,7 @@ func applyKeyspaceDependentPatches(dockerComposeFile []byte, keyspaceData keyspa shard = fmt.Sprintf("%x-%x", interval*(i), interval*(i+1)) } tabAlias = tabAlias + 100 - dockerComposeFile = applyTabletPatches(dockerComposeFile, tabAlias, shard, keyspaceData, externalDbInfoMap) + dockerComposeFile = applyTabletPatches(dockerComposeFile, tabAlias, shard, keyspaceData, externalDbInfoMap, opts) } } @@ -379,90 +453,99 @@ func applyKeyspaceDependentPatches(dockerComposeFile []byte, keyspaceData keyspa return dockerComposeFile } -func applyDefaultDockerPatches(dockerComposeFile []byte) []byte { - dockerComposeFile = applyInMemoryPatch(dockerComposeFile, generateVtctld()) - dockerComposeFile = applyInMemoryPatch(dockerComposeFile, generateVtgate()) - dockerComposeFile = applyInMemoryPatch(dockerComposeFile, generateVtwork()) +func applyDefaultDockerPatches(dockerComposeFile []byte, opts vtOptions) []byte { + dockerComposeFile = applyInMemoryPatch(dockerComposeFile, generateVtctld(opts)) + dockerComposeFile = applyInMemoryPatch(dockerComposeFile, generateVtgate(opts)) + dockerComposeFile = applyInMemoryPatch(dockerComposeFile, generateVtwork(opts)) return dockerComposeFile } -func applyDockerComposePatches(dockerComposeFile []byte, keyspaceInfoMap map[string]keyspaceInfo, externalDbInfoMap map[string]externalDbInfo) []byte { - //Vtctld, vtgate, vtwork patches - dockerComposeFile = applyDefaultDockerPatches(dockerComposeFile) +func applyDockerComposePatches( + dockerComposeFile []byte, + keyspaceInfoMap map[string]keyspaceInfo, + externalDbInfoMap map[string]externalDbInfo, + vtOpts vtOptions, +) []byte { + // Vtctld, vtgate, vtwork patches. + dockerComposeFile = applyDefaultDockerPatches(dockerComposeFile, vtOpts) for _, keyspaceData := range keyspaceInfoMap { - dockerComposeFile = applyKeyspaceDependentPatches(dockerComposeFile, keyspaceData, externalDbInfoMap) + dockerComposeFile = applyKeyspaceDependentPatches(dockerComposeFile, keyspaceData, externalDbInfoMap, vtOpts) } return dockerComposeFile } -func applyTabletPatches(dockerComposeFile []byte, tabAlias int, shard string, keyspaceData keyspaceInfo, externalDbInfoMap map[string]externalDbInfo) []byte { +func applyTabletPatches( + dockerComposeFile []byte, + tabAlias int, + shard string, + keyspaceData keyspaceInfo, + externalDbInfoMap map[string]externalDbInfo, + opts vtOptions, +) []byte { var dbInfo externalDbInfo if val, ok := externalDbInfoMap[keyspaceData.keyspace]; ok { dbInfo = val } - dockerComposeFile = applyInMemoryPatch(dockerComposeFile, generateDefaultTablet(strconv.Itoa(tabAlias+1), shard, "master", keyspaceData.keyspace, dbInfo)) + dockerComposeFile = applyInMemoryPatch(dockerComposeFile, generateDefaultTablet(tabAlias+1, shard, "master", keyspaceData.keyspace, dbInfo, opts)) for i := 0; i < keyspaceData.replicaTablets; i++ { - dockerComposeFile = applyInMemoryPatch(dockerComposeFile, generateDefaultTablet(strconv.Itoa(tabAlias+2+i), shard, "replica", keyspaceData.keyspace, dbInfo)) + dockerComposeFile = applyInMemoryPatch(dockerComposeFile, generateDefaultTablet(tabAlias+2+i, shard, "replica", keyspaceData.keyspace, dbInfo, opts)) } return dockerComposeFile } -// Default Tablet -func generateDefaultTablet(tabAlias, shard, role, keyspace string, dbInfo externalDbInfo) string { +func generateDefaultTablet(tabAlias int, shard, role, keyspace string, dbInfo externalDbInfo, opts vtOptions) string { externalDb := "0" if dbInfo.dbName != "" { externalDb = "1" } - data := fmt.Sprintf(` + + return fmt.Sprintf(` - op: add - path: /services/vttablet%[1]s + path: /services/vttablet%[1]d value: image: vitess/base ports: - - "15%[1]s:%[4]s" - - "%[5]s" + - "15%[1]d:%[4]d" + - "%[5]d" - "3306" volumes: - ".:/script" environment: - TOPOLOGY_FLAGS=%[7]s - - WEB_PORT=%[4]s - - GRPC_PORT=%[5]s + - WEB_PORT=%[4]d + - GRPC_PORT=%[5]d - CELL=%[8]s - KEYSPACE=%[6]s - SHARD=%[2]s - ROLE=%[3]s - - VTHOST=vttablet%[1]s + - VTHOST=vttablet%[1]d - EXTERNAL_DB=%[9]s - DB_PORT=%[10]s - DB_HOST=%[11]s - DB_USER=%[12]s - DB_PASS=%[13]s - DB_CHARSET=%[14]s - command: ["sh", "-c", "/script/vttablet-up.sh %[1]s"] + command: ["sh", "-c", "/script/vttablet-up.sh %[1]d"] depends_on: - vtctld healthcheck: - test: ["CMD-SHELL","curl localhost:%[4]s/debug/health"] + test: ["CMD-SHELL","curl localhost:%[4]d/debug/health"] interval: 30s timeout: 10s retries: 15 -`, tabAlias, shard, role, *webPort, *gRpcPort, keyspace, *topologyFlags, *cell, externalDb, dbInfo.dbPort, dbInfo.dbHost, dbInfo.dbUser, dbInfo.dbPass, dbInfo.dbCharset) - - return data +`, tabAlias, shard, role, opts.webPort, opts.gRpcPort, keyspace, opts.topologyFlags, opts.cell, externalDb, dbInfo.dbPort, dbInfo.dbHost, dbInfo.dbUser, dbInfo.dbPass, dbInfo.dbCharset) } -// Generate Vtctld -func generateVtctld() string { - data := fmt.Sprintf(` +func generateVtctld(opts vtOptions) string { + return fmt.Sprintf(` - op: add path: /services/vtctld value: image: vitess/base ports: - - "15000:%[1]s" - - "%[2]s" + - "15000:%[1]d" + - "%[2]d" command: ["sh", "-c", " $$VTROOT/bin/vtctld \ %[3]s \ -cell %[4]s \ @@ -472,8 +555,8 @@ func generateVtctld() string { -backup_storage_implementation file \ -file_backup_storage_root $$VTDATAROOT/backups \ -logtostderr=true \ - -port %[1]s \ - -grpc_port %[2]s \ + -port %[1]d \ + -grpc_port %[2]d \ -pid_file $$VTDATAROOT/tmp/vtctld.pid "] volumes: @@ -482,28 +565,25 @@ func generateVtctld() string { - consul1 - consul2 - consul3 -`, *webPort, *gRpcPort, *topologyFlags, *cell) - - return data +`, opts.webPort, opts.gRpcPort, opts.topologyFlags, opts.cell) } -// Generate Vtgate -func generateVtgate() string { - data := fmt.Sprintf(` +func generateVtgate(opts vtOptions) string { + return fmt.Sprintf(` - op: add path: /services/vtgate value: image: vitess/base ports: - - "15099:%[1]s" - - "%[2]s" - - "15306:%[3]s" + - "15099:%[1]d" + - "%[2]d" + - "15306:%[3]d" command: ["sh", "-c", "/script/run-forever.sh $$VTROOT/bin/vtgate \ %[4]s \ -logtostderr=true \ - -port %[1]s \ - -grpc_port %[2]s \ - -mysql_server_port %[3]s \ + -port %[1]d \ + -grpc_port %[2]d \ + -mysql_server_port %[3]d \ -mysql_auth_server_impl none \ -cell %[5]s \ -cells_to_watch %[5]s \ @@ -517,38 +597,40 @@ func generateVtgate() string { - .:/script depends_on: - vtctld -`, *webPort, *gRpcPort, *mySqlPort, *topologyFlags, *cell) - - return data +`, opts.webPort, opts.gRpcPort, opts.mySqlPort, opts.topologyFlags, opts.cell) } -func generateVtwork() string { - data := fmt.Sprintf(` +func generateVtwork(opts vtOptions) string { + return fmt.Sprintf(` - op: add path: /services/vtwork value: image: vitess/base ports: - - "15100:%[1]s" - - "%[2]s" + - "15100:%[1]d" + - "%[2]d" command: ["sh", "-c", "$$VTROOT/bin/vtworker \ %[3]s \ -cell %[4]s \ -logtostderr=true \ -service_map 'grpc-vtworker' \ - -port %[1]s \ - -grpc_port %[2]s \ + -port %[1]d \ + -grpc_port %[2]d \ -use_v3_resharding_mode=true \ -pid_file $$VTDATAROOT/tmp/vtwork.pid \ "] depends_on: - vtctld -`, *webPort, *gRpcPort, *topologyFlags, *cell) - - return data +`, opts.webPort, opts.gRpcPort, opts.topologyFlags, opts.cell) } -func generateSchemaload(tabletAliases []string, postLoadFile string, keyspace string, dbInfo externalDbInfo) string { +func generateSchemaload( + tabletAliases []string, + postLoadFile string, + keyspace string, + dbInfo externalDbInfo, + opts vtOptions, +) string { targetTab := tabletAliases[0] schemaFileName := fmt.Sprintf("%s_schema_file.sql", keyspace) externalDb := "0" @@ -560,13 +642,11 @@ func generateSchemaload(tabletAliases []string, postLoadFile string, keyspace st // Formatting for list in yaml for i, tabletId := range tabletAliases { - //tabletAliases[i] = "\"vttablet" + tabletId + "\"" tabletAliases[i] = "vttablet" + tabletId + ": " + "{condition : service_healthy}" } - //dependsOn := "[" + strings.Join(tabletAliases, ", ") + "]" dependsOn := "depends_on: {" + strings.Join(tabletAliases, ", ") + "}" - data := fmt.Sprintf(` + return fmt.Sprintf(` - op: add path: /services/schemaload_%[7]s value: @@ -575,8 +655,8 @@ func generateSchemaload(tabletAliases []string, postLoadFile string, keyspace st - ".:/script" environment: - TOPOLOGY_FLAGS=%[3]s - - WEB_PORT=%[4]s - - GRPC_PORT=%[5]s + - WEB_PORT=%[4]d + - GRPC_PORT=%[5]d - CELL=%[6]s - KEYSPACE=%[7]s - TARGETTAB=%[6]s-0000000%[2]s @@ -587,13 +667,11 @@ func generateSchemaload(tabletAliases []string, postLoadFile string, keyspace st - EXTERNAL_DB=%[10]s command: ["sh", "-c", "/script/schemaload.sh"] %[1]s -`, dependsOn, targetTab, *topologyFlags, *webPort, *gRpcPort, *cell, keyspace, postLoadFile, schemaFileName, externalDb) - - return data +`, dependsOn, targetTab, opts.topologyFlags, opts.webPort, opts.gRpcPort, opts.cell, keyspace, postLoadFile, schemaFileName, externalDb) } -func generatePrimaryVIndex(tableName, column string, name string) string { - data := fmt.Sprintf(` +func generatePrimaryVIndex(tableName, column, name string) string { + return fmt.Sprintf(` [{"op": "add", "path": "/tables/%[1]s", "value": @@ -605,12 +683,10 @@ func generatePrimaryVIndex(tableName, column string, name string) string { ]} }] `, tableName, column, name) - - return data } func generateVschemaLookupHash(tableName, tableKeyspace, from, to, owner string) string { - data := fmt.Sprintf(` + return fmt.Sprintf(` [{"op": "add", "path": "/vindexes/%[1]s", "value": @@ -625,12 +701,10 @@ func generateVschemaLookupHash(tableName, tableKeyspace, from, to, owner string) } }] `, tableName, tableKeyspace, from, to, owner) - - return data } func addToColumnVIndexes(tableName, column, referenceName string) string { - data := fmt.Sprintf(` + return fmt.Sprintf(` [{"op": "add", "path": "/tables/%[1]s/column_vindexes/-", "value": @@ -640,6 +714,4 @@ func addToColumnVIndexes(tableName, column, referenceName string) string { } }] `, tableName, column, referenceName) - - return data } diff --git a/examples/compose/vtcompose/vtcompose_test.go b/examples/compose/vtcompose/vtcompose_test.go new file mode 100644 index 00000000000..fefd595bcc5 --- /dev/null +++ b/examples/compose/vtcompose/vtcompose_test.go @@ -0,0 +1,76 @@ +/* + * Copyright 2019 The Vitess Authors. + + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + + * http://www.apache.org/licenses/LICENSE-2.0 + + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package main + +import ( + "fmt" + "github.com/stretchr/testify/assert" + "strconv" + "testing" +) + +var ( + referenceYaml = string(readFile("./docker-compose.test.yml")) + testComposeFile = readFile("./docker-compose.base.yml") + testKeyspaceInfoMap = parseKeyspaceInfo(DefaultKeyspaceData) + testExternalDbInfoMap = parseExternalDbData(DefaultExternalDbData) + + testVtOpts = vtOptions{ + webPort: DefaultWebPort, + gRpcPort: DefaultGrpcPort, + mySqlPort: DefaultMysqlPort, + topologyFlags: DefaultTopologyFlags, + cell: DefaultCell, + } +) + +func TestGenerateCorrectFileWithDefaultOpts(t *testing.T) { + baseFile := testComposeFile + finalFile := applyDockerComposePatches(baseFile, testKeyspaceInfoMap, testExternalDbInfoMap, testVtOpts) + + yamlString := string(finalFile) + assert.YAMLEq(t, referenceYaml, yamlString) +} + +func TestOptsAppliedThroughoutGeneratedFile(t *testing.T) { + baseFile := testComposeFile + options := vtOptions{ + webPort: 55_555, + gRpcPort: 66_666, + mySqlPort: 77_777, + topologyFlags: "-custom -flags", + cell: "custom cell", + } + finalFile := applyDockerComposePatches(baseFile, testKeyspaceInfoMap, testExternalDbInfoMap, options) + yamlString := string(finalFile) + + // These asserts are not exhaustive, but should cover most cases. + assert.NotContains(t, yamlString, strconv.Itoa(DefaultWebPort)) + assert.Contains(t, yamlString, strconv.Itoa(options.webPort)) + + assert.NotContains(t, yamlString, strconv.Itoa(DefaultGrpcPort)) + assert.Contains(t, yamlString, strconv.Itoa(options.gRpcPort)) + + assert.NotContains(t, yamlString, ":"+strconv.Itoa(DefaultMysqlPort)) + assert.Contains(t, yamlString, ":"+strconv.Itoa(options.webPort)) + + assert.NotContains(t, yamlString, fmt.Sprintf("-cell %s", DefaultCell)) + assert.Contains(t, yamlString, fmt.Sprintf("-cell %s", options.cell)) + + assert.Contains(t, yamlString, fmt.Sprintf("- TOPOLOGY_FLAGS=%s", options.topologyFlags)) + assert.NotContains(t, yamlString, DefaultTopologyFlags) +} diff --git a/examples/demo/cgi-bin/data.py b/examples/demo/cgi-bin/data.py deleted file mode 100755 index 39058bc5e76..00000000000 --- a/examples/demo/cgi-bin/data.py +++ /dev/null @@ -1,183 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# -# Copyright 2019 The Vitess Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -"""This module allows you to bring up and tear down keyspaces.""" - -import cgi -import decimal -import json -import subprocess -import threading -import time - -from vtdb import keyrange -from vtdb import vtgate_client - -# TODO(sougou): remove this import once the deps are fixed -import google.protobuf -from vtdb import grpc_vtgate_client # pylint: disable=unused-import - - -def exec_query(conn, title, query, response, keyspace=None, kr=None): # pylint: disable=missing-docstring - if kr: - # v2 cursor to address individual shards directly, for debug display - cursor = conn.cursor( - tablet_type="master", keyspace=keyspace, - keyranges=[keyrange.KeyRange(kr)]) - else: - # v3 cursor is automated - cursor = conn.cursor( - tablet_type="master", keyspace=keyspace, writable=True) - - try: - if not query or query == "undefined": - return - if query.startswith("select"): - cursor.execute(query, {}) - else: - cursor.begin() - cursor.execute(query, {}) - cursor.commit() - response[title] = { - "title": title, - "description": cursor.description, - "rowcount": cursor.rowcount, - "lastrowid": cursor.lastrowid, - "results": cursor.results, - } - cursor.close() - except Exception as e: # pylint: disable=broad-except - response[title] = { - "title": title, - "error": str(e), - } - cursor.rollback() - cursor.close() - - -def capture_log(port, queries): # pylint: disable=missing-docstring - p = subprocess.Popen( - ["curl", "-s", "-N", "http://localhost:%d/debug/querylog" % port], - stdout=subprocess.PIPE) - def collect(): - for line in iter(p.stdout.readline, ""): - query = line.split("\t")[12].strip('"') - if not query: - continue - queries.append(query) - t = threading.Thread(target=collect) - t.daemon = True - t.start() - return p - - -def main(): - print "Content-Type: application/json\n" - try: - conn = vtgate_client.connect("grpc", "localhost:12346", 10.0) - - args = cgi.FieldStorage() - query = args.getvalue("query") - response = {} - - try: - queries = [] - stats = capture_log(12345, queries) - time.sleep(0.25) - exec_query(conn, "result", query, response) - finally: - stats.terminate() - time.sleep(0.25) - response["queries"] = queries - - # user table - exec_query( - conn, "user0", - "select * from user", response, keyspace="user", kr="-80") - exec_query( - conn, "user1", - "select * from user", response, keyspace="user", kr="80-") - - # user_extra table - exec_query( - conn, "user_extra0", - "select * from user_extra", response, keyspace="user", kr="-80") - exec_query( - conn, "user_extra1", - "select * from user_extra", response, keyspace="user", kr="80-") - - # music table - exec_query( - conn, "music0", - "select * from music", response, keyspace="user", kr="-80") - exec_query( - conn, "music1", - "select * from music", response, keyspace="user", kr="80-") - - # music_extra table - exec_query( - conn, "music_extra0", - "select * from music_extra", response, keyspace="user", kr="-80") - exec_query( - conn, "music_extra1", - "select * from music_extra", response, keyspace="user", kr="80-") - - # name_info table - exec_query( - conn, "name_info0", - "select * from name_info", response, keyspace="user", kr="-80") - exec_query( - conn, "name_info1", - "select * from name_info", response, keyspace="user", kr="80-") - - # music_keyspace_idx table - exec_query( - conn, "music_keyspace_idx0", - "select music_id, hex(keyspace_id) from music_keyspace_idx", response, keyspace="user", kr="-80") - exec_query( - conn, "music_keyspace_idx1", - "select music_id, hex(keyspace_id) from music_keyspace_idx", response, keyspace="user", kr="80-") - - # lookup tables - exec_query( - conn, "user_seq", "select * from user_seq", response, - keyspace="lookup", kr="-") - exec_query( - conn, "music_seq", "select * from music_seq", response, - keyspace="lookup", kr="-") - exec_query( - conn, "name_keyspace_idx", "select name, hex(keyspace_id) from name_keyspace_idx", response, - keyspace="lookup", kr="-") - - print json.dumps(response, default=decimal_default) - except Exception as e: # pylint: disable=broad-except - print json.dumps({"error": str(e)}) - - -def decimal_default(obj): - """Provide json-encodable conversion for decimal.Decimal type. - - json encoding fails on decimal.Decimal. This - function converts the decimal into a float object - which json knows how to encode. - """ - if isinstance(obj, decimal.Decimal): - return float(obj) - raise TypeError - - -if __name__ == "__main__": - main() diff --git a/examples/demo/demo.go b/examples/demo/demo.go new file mode 100644 index 00000000000..101d49d430e --- /dev/null +++ b/examples/demo/demo.go @@ -0,0 +1,257 @@ +/* +Copyright 2020 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +import ( + "bufio" + "context" + "encoding/json" + "flag" + "fmt" + "net/http" + "os" + "os/signal" + "path" + "strings" + "syscall" + "time" + + "vitess.io/vitess/go/mysql" + "vitess.io/vitess/go/sqltypes" + "vitess.io/vitess/go/vt/log" + vttestpb "vitess.io/vitess/go/vt/proto/vttest" + "vitess.io/vitess/go/vt/vttest" +) + +var cluster *vttest.LocalCluster +var querylog <-chan string + +func main() { + flag.Parse() + + runCluster() + querylog, _ = streamQuerylog(cluster.Env.PortForProtocol("vtcombo", "")) + + mux := http.NewServeMux() + mux.Handle("/", http.FileServer(http.Dir("./"))) + mux.HandleFunc("/exec", exec) + go http.ListenAndServe(":8000", mux) + + wait() + cluster.TearDown() +} + +func runCluster() { + cluster = &vttest.LocalCluster{ + Config: vttest.Config{ + Topology: &vttestpb.VTTestTopology{ + Keyspaces: []*vttestpb.Keyspace{{ + Name: "user", + Shards: []*vttestpb.Shard{{ + Name: "-80", + }, { + Name: "80-", + }}, + }, { + Name: "lookup", + Shards: []*vttestpb.Shard{{ + Name: "0", + }}, + }}, + }, + SchemaDir: path.Join(os.Getenv("VTROOT"), "examples/demo/schema"), + MySQLBindHost: "0.0.0.0", + }, + } + env, err := vttest.NewLocalTestEnv("", 12345) + if err != nil { + log.Exitf("Error: %v", err) + } + cluster.Env = env + err = cluster.Setup() + if err != nil { + cluster.TearDown() + log.Exitf("Error: %v", err) + } +} + +func wait() { + c := make(chan os.Signal, 2) + signal.Notify(c, os.Interrupt, syscall.SIGTERM) + <-c +} + +func exec(w http.ResponseWriter, req *http.Request) { + w.Header().Set("Content-Type", "application/json; charset=utf-8") + enc := json.NewEncoder(w) + enc.SetEscapeHTML(true) + + cp := &mysql.ConnParams{ + Host: "127.0.0.1", + Port: cluster.Env.PortForProtocol("vtcombo_mysql_port", ""), + } + conn, err := mysql.Connect(context.Background(), cp) + if err != nil { + response := map[string]string{ + "error": err.Error(), + } + enc.Encode(response) + return + } + defer conn.Close() + query := req.FormValue("query") + response := make(map[string]interface{}) + + var queries []string + // Clear existing log. + for { + select { + case <-querylog: + continue + default: + } + break + } + execQuery(conn, "result", query, "", "", response) + // Collect + time.Sleep(250 * time.Millisecond) + for { + select { + case val := <-querylog: + queries = append(queries, val) + continue + default: + } + break + } + response["queries"] = queries + + execQuery(conn, "user0", "select * from user", "user", "-80", response) + execQuery(conn, "user1", "select * from user", "user", "80-", response) + execQuery(conn, "user_extra0", "select * from user_extra", "user", "-80", response) + execQuery(conn, "user_extra1", "select * from user_extra", "user", "80-", response) + execQuery(conn, "music0", "select * from music", "user", "-80", response) + execQuery(conn, "music1", "select * from music", "user", "80-", response) + execQuery(conn, "music_extra0", "select * from music_extra", "user", "-80", response) + execQuery(conn, "music_extra1", "select * from music_extra", "user", "80-", response) + execQuery(conn, "name_info0", "select * from name_info", "user", "-80", response) + execQuery(conn, "name_info1", "select * from name_info", "user", "80-", response) + execQuery(conn, "music_keyspace_idx0", "select music_id, hex(keyspace_id) from music_keyspace_idx", "user", "-80", response) + execQuery(conn, "music_keyspace_idx1", "select music_id, hex(keyspace_id) from music_keyspace_idx", "user", "80-", response) + execQuery(conn, "user_seq", "select * from user_seq", "lookup", "0", response) + execQuery(conn, "music_seq", "select * from music_seq", "lookup", "0", response) + execQuery(conn, "name_keyspace_idx", "select name, hex(keyspace_id) from name_keyspace_idx", "lookup", "0", response) + enc.Encode(response) +} + +func execQuery(conn *mysql.Conn, key, query, keyspace, shard string, response map[string]interface{}) { + if query == "" || query == "undefined" { + return + } + if keyspace != "" { + _, err := conn.ExecuteFetch(fmt.Sprintf("use `%v:%v`", keyspace, shard), 10000, true) + if err != nil { + response[key] = map[string]interface{}{ + "title": key, + "error": err.Error(), + } + return + } + } + title := key + switch { + case strings.HasSuffix(key, "0"): + title = key[:len(key)-1] + ":-80" + case strings.HasSuffix(key, "1"): + title = key[:len(key)-1] + ":80-" + } + qr, err := conn.ExecuteFetch(query, 10000, true) + if err != nil { + response[key] = map[string]interface{}{ + "title": title, + "error": err.Error(), + } + log.Errorf("error: %v", err) + return + } + response[key] = resultToMap(title, qr) +} + +func resultToMap(title string, qr *sqltypes.Result) map[string]interface{} { + fields := make([]string, 0, len(qr.Fields)) + for _, field := range qr.Fields { + fields = append(fields, field.Name) + } + rows := make([][]string, 0, len(qr.Rows)) + for _, row := range qr.Rows { + srow := make([]string, 0, len(row)) + for _, value := range row { + srow = append(srow, value.ToString()) + } + rows = append(rows, srow) + } + return map[string]interface{}{ + "title": title, + "fields": fields, + "rows": rows, + "rowsaffected": int64(qr.RowsAffected), + "insertid": int64(qr.InsertID), + } +} + +func streamQuerylog(port int) (<-chan string, error) { + request := fmt.Sprintf("http://localhost:%d/debug/querylog", port) + resp, err := http.Get(request) + if err != nil { + log.Errorf("Error reading stream: %v: %v", request, err) + return nil, err + } + ch := make(chan string, 100) + go func() { + buffered := bufio.NewReader(resp.Body) + for { + str, err := buffered.ReadString('\n') + if err != nil { + log.Errorf("Error reading stream: %v: %v", request, err) + close(ch) + resp.Body.Close() + return + } + splits := strings.Split(str, "\t") + if len(splits) < 13 { + continue + } + trimmed := strings.Trim(splits[12], `"`) + if trimmed == "" { + continue + } + splitQueries := strings.Split(trimmed, ";") + var final []string + for _, query := range splitQueries { + if strings.Contains(query, "1 != 1") { + continue + } + final = append(final, query) + } + select { + case ch <- strings.Join(final, "; "): + default: + } + } + }() + return ch, nil +} diff --git a/examples/demo/index.html b/examples/demo/index.html index 8b282d4a444..7f86833da99 100644 --- a/examples/demo/index.html +++ b/examples/demo/index.html @@ -2,20 +2,82 @@ + href="https://stackpath.bootstrapcdn.com/bootswatch/4.3.1/minty/bootstrap.min.css"> Vitess V3 demo -
+

Vitess V3 demo

+
+
+
+
+
+

customer

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

lookup

+
+
+
+
+
+
+
+
+
+
+
+
-
+
- @@ -30,75 +92,29 @@

Vitess V3 demo

data-ng-model="query" id="query_input">
- - - - -
{{queryInfo}}
-
- {{result.error}}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
Executed Queries +
+
+ {{queryInfo}}
+
+
-
- - - - + + + + + diff --git a/examples/demo/demo.js b/examples/demo/index.js similarity index 99% rename from examples/demo/demo.js rename to examples/demo/index.js index 6803edb68dc..846d02a67ec 100644 --- a/examples/demo/demo.js +++ b/examples/demo/index.js @@ -70,7 +70,7 @@ function DemoController($scope, $http) { try { $http({ method: 'POST', - url: '/cgi-bin/data.py', + url: '/exec', data: "query=" + $scope.query, headers: { 'Content-Type': 'application/x-www-form-urlencoded' diff --git a/examples/demo/result.html b/examples/demo/result.html index a9d2471a132..538d777e736 100644 --- a/examples/demo/result.html +++ b/examples/demo/result.html @@ -1,22 +1,16 @@ -
-
-
{{curResult.title}}
- last_id: {{res.lastrowid}} -
-
- - - - - - - -
{{field[0]}}
{{cell}}
-
+
+
{{curResult.title}}
+ + + + + + + +
{{field}}
{{cell}}
- rows_affected: {{curResult.rowcount}} last_id: {{curResult.lastrowid}}
+ data-ng-show="(!curResult.error) && curResult.fields.length == 0"> + rows_affected: {{curResult.rowsaffected}} last_id: {{curResult.insertid}}
- {{curResult.title}}: {{curResult.error}}
\ No newline at end of file + {{curResult.title}}: {{curResult.error}}
diff --git a/examples/demo/run.py b/examples/demo/run.py deleted file mode 100755 index a5dae3a4e26..00000000000 --- a/examples/demo/run.py +++ /dev/null @@ -1,90 +0,0 @@ -#!/usr/bin/env python - -# Copyright 2019 The Vitess Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""This is a demo for V3 features. - -The script will launch all the processes necessary to bring up -the demo. It will bring up an HTTP server on port 8000 by default, -which you can override. Once done, hitting will terminate -all processes. Vitess will always be started on port 12345. -""" - -import json -import optparse -import os -import subprocess -import thread - -from CGIHTTPServer import CGIHTTPRequestHandler -from BaseHTTPServer import HTTPServer - -from google.protobuf import text_format - -from vtproto import vttest_pb2 - - -def start_http_server(port): - httpd = HTTPServer(('', port), CGIHTTPRequestHandler) - thread.start_new_thread(httpd.serve_forever, ()) - - -def start_vitess(): - """This is the main start function.""" - - topology = vttest_pb2.VTTestTopology() - keyspace = topology.keyspaces.add(name='user') - keyspace.shards.add(name='-80') - keyspace.shards.add(name='80-') - keyspace = topology.keyspaces.add(name='lookup') - keyspace.shards.add(name='0') - - vtroot = os.environ['VTROOT'] - args = [os.path.join(vtroot, 'py/vttest/run_local_database.py'), - '--port', '12345', - '--proto_topo', text_format.MessageToString(topology, - as_one_line=True), - '--schema_dir', os.path.join(vttop, 'examples/demo/schema'), - '--mysql_server_bind_address', '0.0.0.0'] - sp = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE) - - # This load will make us wait for vitess to come up. - print json.loads(sp.stdout.readline()) - return sp - - -def stop_vitess(sp): - sp.stdin.write('\n') - sp.wait() - - -def main(): - parser = optparse.OptionParser() - parser.add_option('-p', '--port', default=8000, help='http server port') - (options, unused_args) = parser.parse_args() - - sp = start_vitess() - try: - start_http_server(options.port) - raw_input('\n' - 'Demo is running at: http://localhost:%d/\n' - '\n' - 'Press enter to exit.\n' % options.port) - finally: - stop_vitess(sp) - - -if __name__ == '__main__': - main() diff --git a/examples/helm/101_initial_cluster.yaml b/examples/helm/101_initial_cluster.yaml index aab85cee688..2992f2c83ae 100644 --- a/examples/helm/101_initial_cluster.yaml +++ b/examples/helm/101_initial_cluster.yaml @@ -1,8 +1,6 @@ topology: cells: - name: "zone1" - etcd: - replicas: 1 vtctld: replicas: 1 vtgate: @@ -17,10 +15,7 @@ topology: tablets: - type: "replica" vttablet: - replicas: 2 - - type: "rdonly" - vttablet: - replicas: 1 + replicas: 3 schema: initial: |- create table product( @@ -51,10 +46,6 @@ topology: } } -etcd: - replicas: 1 - resources: - vtctld: serviceType: "NodePort" resources: @@ -67,6 +58,8 @@ vttablet: mysqlSize: "prod" resources: mysqlResources: + # It's generally not recommended to override this value for production usage. + terminationGracePeriodSeconds: 1 vtworker: resources: diff --git a/examples/helm/201_customer_tablets.yaml b/examples/helm/201_customer_tablets.yaml new file mode 100644 index 00000000000..fba4940100b --- /dev/null +++ b/examples/helm/201_customer_tablets.yaml @@ -0,0 +1,49 @@ +topology: + cells: + - name: "zone1" + vtctld: + replicas: 1 + vtgate: + replicas: 1 + mysqlProtocol: + enabled: true + authType: "none" + keyspaces: + - name: "commerce" + shards: + - name: "0" + tablets: + - type: "replica" + vttablet: + replicas: 3 + - name: "customer" + shards: + - name: "0" + tablets: + - type: "replica" + vttablet: + replicas: 3 + +vtctld: + serviceType: "NodePort" + resources: + +vtgate: + serviceType: "NodePort" + resources: + +vttablet: + mysqlSize: "prod" + resources: + mysqlResources: + # It's generally not recommended to override this value for production usage. + terminationGracePeriodSeconds: 1 + +vtworker: + resources: + +pmm: + enabled: false + +orchestrator: + enabled: false diff --git a/examples/helm/202_move_tables.yaml b/examples/helm/202_move_tables.yaml new file mode 100644 index 00000000000..a08f9311545 --- /dev/null +++ b/examples/helm/202_move_tables.yaml @@ -0,0 +1,54 @@ +topology: + cells: + - name: "zone1" + vtctld: + replicas: 1 + vtgate: + replicas: 1 + mysqlProtocol: + enabled: true + authType: "none" + keyspaces: + - name: "commerce" + shards: + - name: "0" + tablets: + - type: "replica" + vttablet: + replicas: 3 + - name: "customer" + shards: + - name: "0" + tablets: + - type: "replica" + vttablet: + replicas: 3 + +jobs: + - name: "move-tables" + kind: "vtctlclient" + command: "MoveTables -workflow=commerce2customer commerce customer \'{\"customer\":{}, \"corder\":{}}\'" + +vtctld: + serviceType: "NodePort" + resources: + +vtgate: + serviceType: "NodePort" + resources: + +vttablet: + mysqlSize: "prod" + resources: + mysqlResources: + # It's generally not recommended to override this value for production usage. + terminationGracePeriodSeconds: 1 + +vtworker: + resources: + +pmm: + enabled: false + +orchestrator: + enabled: false diff --git a/examples/helm/203_switch_reads.yaml b/examples/helm/203_switch_reads.yaml new file mode 100644 index 00000000000..940b1fb04dc --- /dev/null +++ b/examples/helm/203_switch_reads.yaml @@ -0,0 +1,57 @@ +topology: + cells: + - name: "zone1" + vtctld: + replicas: 1 + vtgate: + replicas: 1 + mysqlProtocol: + enabled: true + authType: "none" + keyspaces: + - name: "commerce" + shards: + - name: "0" + tablets: + - type: "replica" + vttablet: + replicas: 3 + - name: "customer" + shards: + - name: "0" + tablets: + - type: "replica" + vttablet: + replicas: 3 + +jobs: + - name: "mswitch1" + kind: "vtctlclient" + command: "SwitchReads -tablet_type=rdonly customer.commerce2customer" + - name: "mswitch2" + kind: "vtctlclient" + command: "SwitchReads -tablet_type=replica customer.commerce2customer" + +vtctld: + serviceType: "NodePort" + resources: + +vtgate: + serviceType: "NodePort" + resources: + +vttablet: + mysqlSize: "prod" + resources: + mysqlResources: + # It's generally not recommended to override this value for production usage. + terminationGracePeriodSeconds: 1 + +vtworker: + resources: + +pmm: + enabled: false + +orchestrator: + enabled: false diff --git a/examples/helm/204_switch_writes.yaml b/examples/helm/204_switch_writes.yaml new file mode 100644 index 00000000000..fb38ad6d344 --- /dev/null +++ b/examples/helm/204_switch_writes.yaml @@ -0,0 +1,54 @@ +topology: + cells: + - name: "zone1" + vtctld: + replicas: 1 + vtgate: + replicas: 1 + mysqlProtocol: + enabled: true + authType: "none" + keyspaces: + - name: "commerce" + shards: + - name: "0" + tablets: + - type: "replica" + vttablet: + replicas: 3 + - name: "customer" + shards: + - name: "0" + tablets: + - type: "replica" + vttablet: + replicas: 3 + +jobs: + - name: "mswitch3" + kind: "vtctlclient" + command: "SwitchWrites customer.commerce2customer" + +vtctld: + serviceType: "NodePort" + resources: + +vtgate: + serviceType: "NodePort" + resources: + +vttablet: + mysqlSize: "prod" + resources: + mysqlResources: + # It's generally not recommended to override this value for production usage. + terminationGracePeriodSeconds: 1 + +vtworker: + resources: + +pmm: + enabled: false + +orchestrator: + enabled: false diff --git a/examples/helm/205_clean_commerce.yaml b/examples/helm/205_clean_commerce.yaml new file mode 100644 index 00000000000..ce4437dc9c8 --- /dev/null +++ b/examples/helm/205_clean_commerce.yaml @@ -0,0 +1,74 @@ +topology: + cells: + - name: "zone1" + vtctld: + replicas: 1 + vtgate: + replicas: 1 + mysqlProtocol: + enabled: true + authType: "none" + keyspaces: + - name: "commerce" + shards: + - name: "0" + tablets: + - type: "replica" + vttablet: + replicas: 3 + schema: + postsplit: |- + drop table customer; + drop table corder; + vschema: + postsplit: |- + { + "tables": { + "product": {} + } + } + - name: "customer" + shards: + - name: "0" + tablets: + - type: "replica" + vttablet: + replicas: 3 + +jobs: + - name: "vclean1" + kind: "vtctlclient" + command: "SetShardTabletControl -blacklisted_tables=customer,corder -remove commerce/0 rdonly" + - name: "vclean2" + kind: "vtctlclient" + command: "SetShardTabletControl -blacklisted_tables=customer,corder -remove commerce/0 replica" + - name: "vclean3" + kind: "vtctlclient" + command: "SetShardTabletControl -blacklisted_tables=customer,corder -remove commerce/0 master" + - name: "vclean4" + kind: "vtctlclient" + command: "ApplyRoutingRules -rules=\'{}\'" + +vtctld: + serviceType: "NodePort" + resources: + +vtgate: + serviceType: "NodePort" + resources: + +vttablet: + mysqlSize: "prod" + resources: + mysqlResources: + # It's generally not recommended to override this value for production usage. + terminationGracePeriodSeconds: 1 + +vtworker: + resources: + +pmm: + enabled: false + +orchestrator: + enabled: false diff --git a/examples/helm/301_customer_sharded.yaml b/examples/helm/301_customer_sharded.yaml index d20497d6b93..306b1ff18de 100644 --- a/examples/helm/301_customer_sharded.yaml +++ b/examples/helm/301_customer_sharded.yaml @@ -1,8 +1,6 @@ topology: cells: - name: "zone1" - etcd: - replicas: 1 vtctld: replicas: 1 vtgate: @@ -17,10 +15,7 @@ topology: tablets: - type: "replica" vttablet: - replicas: 2 - - type: "rdonly" - vttablet: - replicas: 1 + replicas: 3 schema: seq: |- create table customer_seq(id int, next_id bigint, cache bigint, primary key(id)) comment 'vitess_sequence'; @@ -46,10 +41,7 @@ topology: tablets: - type: "replica" vttablet: - replicas: 2 - - type: "rdonly" - vttablet: - replicas: 1 + replicas: 3 schema: sharded: |- alter table customer change customer_id customer_id bigint not null; @@ -91,10 +83,6 @@ topology: } } -etcd: - replicas: 1 - resources: - vtctld: serviceType: "NodePort" resources: @@ -107,6 +95,8 @@ vttablet: mysqlSize: "prod" resources: mysqlResources: + # It's generally not recommended to override this value for production usage. + terminationGracePeriodSeconds: 1 vtworker: resources: diff --git a/examples/helm/302_new_shards.yaml b/examples/helm/302_new_shards.yaml index 658281899ad..85eff65b450 100644 --- a/examples/helm/302_new_shards.yaml +++ b/examples/helm/302_new_shards.yaml @@ -1,8 +1,6 @@ topology: cells: - name: "zone1" - etcd: - replicas: 1 vtctld: replicas: 1 vtgate: @@ -17,45 +15,29 @@ topology: tablets: - type: "replica" vttablet: - replicas: 2 - - type: "rdonly" - vttablet: - replicas: 1 + replicas: 3 - name: "customer" shards: - name: "0" tablets: - type: "replica" vttablet: - replicas: 2 - - type: "rdonly" - vttablet: - replicas: 1 + replicas: 3 - name: "-80" tablets: - type: "replica" vttablet: - replicas: 2 - - type: "rdonly" - vttablet: - replicas: 1 + replicas: 3 copySchema: source: "customer/0" - name: "80-" tablets: - type: "replica" vttablet: - replicas: 2 - - type: "rdonly" - vttablet: - replicas: 1 + replicas: 3 copySchema: source: "customer/0" -etcd: - replicas: 1 - resources: - vtctld: serviceType: "NodePort" resources: @@ -68,6 +50,8 @@ vttablet: mysqlSize: "prod" resources: mysqlResources: + # It's generally not recommended to override this value for production usage. + terminationGracePeriodSeconds: 1 vtworker: resources: diff --git a/examples/helm/303_reshard.yaml b/examples/helm/303_reshard.yaml new file mode 100644 index 00000000000..cd7a0237d1b --- /dev/null +++ b/examples/helm/303_reshard.yaml @@ -0,0 +1,64 @@ +topology: + cells: + - name: "zone1" + vtctld: + replicas: 1 + vtgate: + replicas: 1 + mysqlProtocol: + enabled: true + authType: "none" + keyspaces: + - name: "commerce" + shards: + - name: "0" + tablets: + - type: "replica" + vttablet: + replicas: 3 + - name: "customer" + shards: + - name: "0" + tablets: + - type: "replica" + vttablet: + replicas: 3 + - name: "-80" + tablets: + - type: "replica" + vttablet: + replicas: 3 + - name: "80-" + tablets: + - type: "replica" + vttablet: + replicas: 3 + +jobs: + - name: "reshard" + kind: "vtctlclient" + command: "Reshard customer.cust2cust \'0\' \'-80,80-\'" + +vtctld: + serviceType: "NodePort" + resources: + +vtgate: + serviceType: "NodePort" + resources: + +vttablet: + mysqlSize: "prod" + resources: + mysqlResources: + # It's generally not recommended to override this value for production usage. + terminationGracePeriodSeconds: 1 + +vtworker: + resources: + +pmm: + enabled: false + +orchestrator: + enabled: false diff --git a/examples/helm/304_switch_reads.yaml b/examples/helm/304_switch_reads.yaml new file mode 100644 index 00000000000..fbdf578fa2e --- /dev/null +++ b/examples/helm/304_switch_reads.yaml @@ -0,0 +1,67 @@ +topology: + cells: + - name: "zone1" + vtctld: + replicas: 1 + vtgate: + replicas: 1 + mysqlProtocol: + enabled: true + authType: "none" + keyspaces: + - name: "commerce" + shards: + - name: "0" + tablets: + - type: "replica" + vttablet: + replicas: 3 + - name: "customer" + shards: + - name: "0" + tablets: + - type: "replica" + vttablet: + replicas: 3 + - name: "-80" + tablets: + - type: "replica" + vttablet: + replicas: 3 + - name: "80-" + tablets: + - type: "replica" + vttablet: + replicas: 3 + +jobs: + - name: "rswitch1" + kind: "vtctlclient" + command: "SwitchReads -tablet_type=rdonly customer.cust2cust" + - name: "rswitch2" + kind: "vtctlclient" + command: "SwitchReads -tablet_type=replica customer.cust2cust" + +vtctld: + serviceType: "NodePort" + resources: + +vtgate: + serviceType: "NodePort" + resources: + +vttablet: + mysqlSize: "prod" + resources: + mysqlResources: + # It's generally not recommended to override this value for production usage. + terminationGracePeriodSeconds: 1 + +vtworker: + resources: + +pmm: + enabled: false + +orchestrator: + enabled: false diff --git a/examples/helm/305_switch_writes.yaml b/examples/helm/305_switch_writes.yaml new file mode 100644 index 00000000000..6316f45c2eb --- /dev/null +++ b/examples/helm/305_switch_writes.yaml @@ -0,0 +1,64 @@ +topology: + cells: + - name: "zone1" + vtctld: + replicas: 1 + vtgate: + replicas: 1 + mysqlProtocol: + enabled: true + authType: "none" + keyspaces: + - name: "commerce" + shards: + - name: "0" + tablets: + - type: "replica" + vttablet: + replicas: 3 + - name: "customer" + shards: + - name: "0" + tablets: + - type: "replica" + vttablet: + replicas: 3 + - name: "-80" + tablets: + - type: "replica" + vttablet: + replicas: 3 + - name: "80-" + tablets: + - type: "replica" + vttablet: + replicas: 3 + +jobs: + - name: "rswitch3" + kind: "vtctlclient" + command: "SwitchWrites customer.cust2cust" + +vtctld: + serviceType: "NodePort" + resources: + +vtgate: + serviceType: "NodePort" + resources: + +vttablet: + mysqlSize: "prod" + resources: + mysqlResources: + # It's generally not recommended to override this value for production usage. + terminationGracePeriodSeconds: 1 + +vtworker: + resources: + +pmm: + enabled: false + +orchestrator: + enabled: false diff --git a/examples/helm/306_down_shard_0.yaml b/examples/helm/306_down_shard_0.yaml index d34ac318f65..7bbc7ef62ed 100644 --- a/examples/helm/306_down_shard_0.yaml +++ b/examples/helm/306_down_shard_0.yaml @@ -1,8 +1,6 @@ topology: cells: - name: "zone1" - etcd: - replicas: 1 vtctld: replicas: 1 vtgate: @@ -17,32 +15,19 @@ topology: tablets: - type: "replica" vttablet: - replicas: 2 - - type: "rdonly" - vttablet: - replicas: 1 + replicas: 3 - name: "customer" shards: - name: "-80" tablets: - type: "replica" vttablet: - replicas: 2 - - type: "rdonly" - vttablet: - replicas: 1 + replicas: 3 - name: "80-" tablets: - type: "replica" vttablet: - replicas: 2 - - type: "rdonly" - vttablet: - replicas: 1 - -etcd: - replicas: 1 - resources: + replicas: 3 vtctld: serviceType: "NodePort" @@ -56,6 +41,8 @@ vttablet: mysqlSize: "prod" resources: mysqlResources: + # It's generally not recommended to override this value for production usage. + terminationGracePeriodSeconds: 1 vtworker: resources: diff --git a/examples/helm/307_delete_shard_0.yaml b/examples/helm/307_delete_shard_0.yaml index ccfad668d30..59de5b2f369 100644 --- a/examples/helm/307_delete_shard_0.yaml +++ b/examples/helm/307_delete_shard_0.yaml @@ -1,8 +1,6 @@ topology: cells: - name: "zone1" - etcd: - replicas: 1 vtctld: replicas: 1 vtgate: @@ -17,38 +15,25 @@ topology: tablets: - type: "replica" vttablet: - replicas: 2 - - type: "rdonly" - vttablet: - replicas: 1 + replicas: 3 - name: "customer" shards: - name: "-80" tablets: - type: "replica" vttablet: - replicas: 2 - - type: "rdonly" - vttablet: - replicas: 1 + replicas: 3 - name: "80-" tablets: - type: "replica" vttablet: - replicas: 2 - - type: "rdonly" - vttablet: - replicas: 1 + replicas: 3 jobs: - name: "delete-shard0" kind: "vtctlclient" command: "DeleteShard -recursive customer/0" -etcd: - replicas: 1 - resources: - vtctld: serviceType: "NodePort" resources: @@ -61,6 +46,8 @@ vttablet: mysqlSize: "prod" resources: mysqlResources: + # It's generally not recommended to override this value for production usage. + terminationGracePeriodSeconds: 1 vtworker: resources: diff --git a/examples/helm/308_final.yaml b/examples/helm/308_final.yaml index ccfad668d30..7bbc7ef62ed 100644 --- a/examples/helm/308_final.yaml +++ b/examples/helm/308_final.yaml @@ -1,8 +1,6 @@ topology: cells: - name: "zone1" - etcd: - replicas: 1 vtctld: replicas: 1 vtgate: @@ -17,37 +15,19 @@ topology: tablets: - type: "replica" vttablet: - replicas: 2 - - type: "rdonly" - vttablet: - replicas: 1 + replicas: 3 - name: "customer" shards: - name: "-80" tablets: - type: "replica" vttablet: - replicas: 2 - - type: "rdonly" - vttablet: - replicas: 1 + replicas: 3 - name: "80-" tablets: - type: "replica" vttablet: - replicas: 2 - - type: "rdonly" - vttablet: - replicas: 1 - -jobs: - - name: "delete-shard0" - kind: "vtctlclient" - command: "DeleteShard -recursive customer/0" - -etcd: - replicas: 1 - resources: + replicas: 3 vtctld: serviceType: "NodePort" @@ -61,6 +41,8 @@ vttablet: mysqlSize: "prod" resources: mysqlResources: + # It's generally not recommended to override this value for production usage. + terminationGracePeriodSeconds: 1 vtworker: resources: diff --git a/examples/helm/README.md b/examples/helm/README.md new file mode 100644 index 00000000000..11af8cc427c --- /dev/null +++ b/examples/helm/README.md @@ -0,0 +1,51 @@ +# Instructions + +Detailed instructions for running this example can be found at https://vitess.io. +This document contains the summary of the commands to be run. + + +``` +# Start minikube +minikube start --cpus=4 --memory=8000 + +# Bring up initial cluster and commerce keyspace +helm install vitess ../../helm/vitess -f 101_initial_cluster.yaml + +# Setup aliases +source alias.source + +# Insert and verify data +mysql < ../common/insert_commerce_data.sql +mysql --table < ../common/select_commerce_data.sql + +# Bring up customer keyspace +helm upgrade vitess ../../helm/vitess/ -f 201_customer_tablets.yaml + +# Initiate move tables +vtctlclient MoveTables -workflow=commerce2customer commerce customer '{"customer":{}, "corder":{}}' + +# Cut-over +vtctlclient SwitchReads -tablet_type=rdonly customer.commerce2customer +vtctlclient SwitchReads -tablet_type=replica customer.commerce2customer +vtctlclient SwitchWrites customer.commerce2customer + +# Clean-up +vtctlclient SetShardTabletControl -blacklisted_tables=customer,corder -remove commerce/0 rdonly +vtctlclient SetShardTabletControl -blacklisted_tables=customer,corder -remove commerce/0 replica +vtctlclient SetShardTabletControl -blacklisted_tables=customer,corder -remove commerce/0 master +vtctlclient ApplyRoutingRules -rules='{}' + +# Prepare for resharding +helm upgrade vitess ../../helm/vitess/ -f 301_customer_sharded.yaml +helm upgrade vitess ../../helm/vitess/ -f 302_new_shards.yaml + +# Reshard +vtctlclient Reshard customer.cust2cust '0' '-80,80-' +vtctlclient SwitchReads -tablet_type=rdonly customer.cust2cust +vtctlclient SwitchReads -tablet_type=replica customer.cust2cust +vtctlclient SwitchWrites customer.cust2cust + +# Down shard 0 +helm upgrade vitess ../../helm/vitess/ -f 306_down_shard_0.yaml +vtctlclient DeleteShard -recursive customer/0 +``` diff --git a/examples/helm/alias.source b/examples/helm/alias.source new file mode 100644 index 00000000000..f10a5d6a47d --- /dev/null +++ b/examples/helm/alias.source @@ -0,0 +1,35 @@ +function vhostport() { + vhost=$(minikube service $1 --url=true --format="{{.IP}}" | tail -n 1) + vport=$(minikube service $1 --url=true --format="{{.Port}}" | tail -n 1) + + if [ -z $vport ]; then + # This checks K8s running on an single node by kubeadm + if [ $(kubectl get nodes | grep -v NAM | wc -l) -eq 1 -o $(kubectl get nodes | grep -v NAM | grep master | wc -l ) -eq 1 ]; then + vhost="127.0.0.1" + vport=`kubectl describe service vtgate-zone1 | grep NodePort | grep mysql | awk '{print $3}' | awk -F'/' '{print $1}'` + fi + fi +} + +function vsetmysql() { + vhostport vtgate-zone1 + if [ -z $vport ]; then + echo "Error: failed to obtain [host:port] minikube or kubectl." + return 1 + fi + echo "Setting alias mysql to: mysql -h $vhost -P $vport" + alias mysql="mysql -h $vhost -P $vport" +} + +function vsetvtctlclient() { + vhostport vtctld + if [ -z $vport ]; then + echo "Error: failed to: obtain [host:port] minikube or kubectl." + return 1 + fi + echo "Setting alias vtctlclient to vtctlclient -server=$vhost:$vport" + alias vtctlclient="vtctlclient -server=$vhost:$vport" +} + +vsetmysql +vsetvtctlclient diff --git a/examples/helm/legacy/101_initial_cluster.yaml b/examples/helm/legacy/101_initial_cluster.yaml new file mode 100644 index 00000000000..2db8b28fe71 --- /dev/null +++ b/examples/helm/legacy/101_initial_cluster.yaml @@ -0,0 +1,74 @@ +topology: + cells: + - name: "zone1" + vtctld: + replicas: 1 + vtgate: + replicas: 1 + mysqlProtocol: + enabled: true + authType: "none" + keyspaces: + - name: "commerce" + shards: + - name: "0" + tablets: + - type: "replica" + vttablet: + replicas: 2 + - type: "rdonly" + vttablet: + replicas: 1 + schema: + initial: |- + create table product( + sku varbinary(128), + description varbinary(128), + price bigint, + primary key(sku) + ); + create table customer( + customer_id bigint not null auto_increment, + email varbinary(128), + primary key(customer_id) + ); + create table corder( + order_id bigint not null auto_increment, + customer_id bigint, + sku varbinary(128), + price bigint, + primary key(order_id) + ); + vschema: + initial: |- + { + "tables": { + "product": {}, + "customer": {}, + "corder": {} + } + } + +vtctld: + serviceType: "NodePort" + resources: + +vtgate: + serviceType: "NodePort" + resources: + +vttablet: + mysqlSize: "prod" + resources: + mysqlResources: + # It's generally not recommended to override this value for production usage. + terminationGracePeriodSeconds: 1 + +vtworker: + resources: + +pmm: + enabled: false + +orchestrator: + enabled: false diff --git a/examples/helm/201_customer_keyspace.yaml b/examples/helm/legacy/201_customer_keyspace.yaml similarity index 88% rename from examples/helm/201_customer_keyspace.yaml rename to examples/helm/legacy/201_customer_keyspace.yaml index c343abb8d97..48e527d3908 100644 --- a/examples/helm/201_customer_keyspace.yaml +++ b/examples/helm/legacy/201_customer_keyspace.yaml @@ -1,8 +1,6 @@ topology: cells: - name: "zone1" - etcd: - replicas: 1 vtctld: replicas: 1 vtgate: @@ -27,10 +25,6 @@ jobs: kind: "vtctlclient" command: "CreateKeyspace -served_from='master:commerce,replica:commerce,rdonly:commerce' customer" -etcd: - replicas: 1 - resources: - vtctld: serviceType: "NodePort" resources: @@ -43,6 +37,8 @@ vttablet: mysqlSize: "prod" resources: mysqlResources: + # It's generally not recommended to override this value for production usage. + terminationGracePeriodSeconds: 1 vtworker: resources: diff --git a/examples/helm/202_customer_tablets.yaml b/examples/helm/legacy/202_customer_tablets.yaml similarity index 92% rename from examples/helm/202_customer_tablets.yaml rename to examples/helm/legacy/202_customer_tablets.yaml index 2a13c3940f2..a3aa566e468 100644 --- a/examples/helm/202_customer_tablets.yaml +++ b/examples/helm/legacy/202_customer_tablets.yaml @@ -1,8 +1,6 @@ topology: cells: - name: "zone1" - etcd: - replicas: 1 vtctld: replicas: 1 vtgate: @@ -52,10 +50,6 @@ topology: } } -etcd: - replicas: 1 - resources: - vtctld: serviceType: "NodePort" resources: @@ -68,6 +62,8 @@ vttablet: mysqlSize: "prod" resources: mysqlResources: + # It's generally not recommended to override this value for production usage. + terminationGracePeriodSeconds: 1 vtworker: resources: diff --git a/examples/helm/203_vertical_split.yaml b/examples/helm/legacy/203_vertical_split.yaml similarity index 90% rename from examples/helm/203_vertical_split.yaml rename to examples/helm/legacy/203_vertical_split.yaml index 2480f39a2d2..fbaf96f3dfb 100644 --- a/examples/helm/203_vertical_split.yaml +++ b/examples/helm/legacy/203_vertical_split.yaml @@ -1,8 +1,6 @@ topology: cells: - name: "zone1" - etcd: - replicas: 1 vtctld: replicas: 1 vtgate: @@ -38,10 +36,6 @@ jobs: cell: "zone1" command: "VerticalSplitClone -min_healthy_tablets=1 -tables=customer,corder customer/0" -etcd: - replicas: 1 - resources: - vtctld: serviceType: "NodePort" resources: @@ -54,6 +48,8 @@ vttablet: mysqlSize: "prod" resources: mysqlResources: + # It's generally not recommended to override this value for production usage. + terminationGracePeriodSeconds: 1 vtworker: resources: diff --git a/examples/helm/204_vertical_migrate_replicas.yaml b/examples/helm/legacy/204_vertical_migrate_replicas.yaml similarity index 91% rename from examples/helm/204_vertical_migrate_replicas.yaml rename to examples/helm/legacy/204_vertical_migrate_replicas.yaml index aad9a9b155c..c46219a982e 100644 --- a/examples/helm/204_vertical_migrate_replicas.yaml +++ b/examples/helm/legacy/204_vertical_migrate_replicas.yaml @@ -1,8 +1,6 @@ topology: cells: - name: "zone1" - etcd: - replicas: 1 vtctld: replicas: 1 vtgate: @@ -40,10 +38,6 @@ jobs: kind: "vtctlclient" command: "MigrateServedFrom customer/0 replica" -etcd: - replicas: 1 - resources: - vtctld: serviceType: "NodePort" resources: @@ -56,6 +50,8 @@ vttablet: mysqlSize: "prod" resources: mysqlResources: + # It's generally not recommended to override this value for production usage. + terminationGracePeriodSeconds: 1 vtworker: resources: diff --git a/examples/helm/205_vertical_migrate_master.yaml b/examples/helm/legacy/205_vertical_migrate_master.yaml similarity index 90% rename from examples/helm/205_vertical_migrate_master.yaml rename to examples/helm/legacy/205_vertical_migrate_master.yaml index 21ecc757762..abbcb47aacb 100644 --- a/examples/helm/205_vertical_migrate_master.yaml +++ b/examples/helm/legacy/205_vertical_migrate_master.yaml @@ -1,8 +1,6 @@ topology: cells: - name: "zone1" - etcd: - replicas: 1 vtctld: replicas: 1 vtgate: @@ -37,10 +35,6 @@ jobs: kind: "vtctlclient" command: "MigrateServedFrom customer/0 master" -etcd: - replicas: 1 - resources: - vtctld: serviceType: "NodePort" resources: @@ -53,6 +47,8 @@ vttablet: mysqlSize: "prod" resources: mysqlResources: + # It's generally not recommended to override this value for production usage. + terminationGracePeriodSeconds: 1 vtworker: resources: diff --git a/examples/helm/206_clean_commerce.yaml b/examples/helm/legacy/206_clean_commerce.yaml similarity index 93% rename from examples/helm/206_clean_commerce.yaml rename to examples/helm/legacy/206_clean_commerce.yaml index 11883808f52..4089a2863b2 100644 --- a/examples/helm/206_clean_commerce.yaml +++ b/examples/helm/legacy/206_clean_commerce.yaml @@ -1,8 +1,6 @@ topology: cells: - name: "zone1" - etcd: - replicas: 1 vtctld: replicas: 1 vtgate: @@ -47,10 +45,6 @@ jobs: kind: "vtctlclient" command: "SetShardTabletControl -blacklisted_tables=customer,corder -remove commerce/0 master" -etcd: - replicas: 1 - resources: - vtctld: serviceType: "NodePort" resources: @@ -63,6 +57,8 @@ vttablet: mysqlSize: "prod" resources: mysqlResources: + # It's generally not recommended to override this value for production usage. + terminationGracePeriodSeconds: 1 vtworker: resources: diff --git a/examples/helm/legacy/301_customer_sharded.yaml b/examples/helm/legacy/301_customer_sharded.yaml new file mode 100644 index 00000000000..6d906afcc69 --- /dev/null +++ b/examples/helm/legacy/301_customer_sharded.yaml @@ -0,0 +1,114 @@ +topology: + cells: + - name: "zone1" + vtctld: + replicas: 1 + vtgate: + replicas: 1 + mysqlProtocol: + enabled: true + authType: "none" + keyspaces: + - name: "commerce" + shards: + - name: "0" + tablets: + - type: "replica" + vttablet: + replicas: 2 + - type: "rdonly" + vttablet: + replicas: 1 + schema: + seq: |- + create table customer_seq(id int, next_id bigint, cache bigint, primary key(id)) comment 'vitess_sequence'; + insert into customer_seq(id, next_id, cache) values(0, 1000, 100); + create table order_seq(id int, next_id bigint, cache bigint, primary key(id)) comment 'vitess_sequence'; + insert into order_seq(id, next_id, cache) values(0, 1000, 100); + vschema: + seq: |- + { + "tables": { + "customer_seq": { + "type": "sequence" + }, + "order_seq": { + "type": "sequence" + }, + "product": {} + } + } + - name: "customer" + shards: + - name: "0" + tablets: + - type: "replica" + vttablet: + replicas: 2 + - type: "rdonly" + vttablet: + replicas: 1 + schema: + sharded: |- + alter table customer change customer_id customer_id bigint not null; + alter table corder change order_id order_id bigint not null; + vschema: + sharded: |- + { + "sharded": true, + "vindexes": { + "hash": { + "type": "hash" + } + }, + "tables": { + "customer": { + "column_vindexes": [ + { + "column": "customer_id", + "name": "hash" + } + ], + "auto_increment": { + "column": "customer_id", + "sequence": "customer_seq" + } + }, + "corder": { + "column_vindexes": [ + { + "column": "customer_id", + "name": "hash" + } + ], + "auto_increment": { + "column": "order_id", + "sequence": "order_seq" + } + } + } + } + +vtctld: + serviceType: "NodePort" + resources: + +vtgate: + serviceType: "NodePort" + resources: + +vttablet: + mysqlSize: "prod" + resources: + mysqlResources: + # It's generally not recommended to override this value for production usage. + terminationGracePeriodSeconds: 1 + +vtworker: + resources: + +pmm: + enabled: false + +orchestrator: + enabled: false diff --git a/examples/helm/legacy/302_new_shards.yaml b/examples/helm/legacy/302_new_shards.yaml new file mode 100644 index 00000000000..1598dcd4c17 --- /dev/null +++ b/examples/helm/legacy/302_new_shards.yaml @@ -0,0 +1,75 @@ +topology: + cells: + - name: "zone1" + vtctld: + replicas: 1 + vtgate: + replicas: 1 + mysqlProtocol: + enabled: true + authType: "none" + keyspaces: + - name: "commerce" + shards: + - name: "0" + tablets: + - type: "replica" + vttablet: + replicas: 2 + - type: "rdonly" + vttablet: + replicas: 1 + - name: "customer" + shards: + - name: "0" + tablets: + - type: "replica" + vttablet: + replicas: 2 + - type: "rdonly" + vttablet: + replicas: 1 + - name: "-80" + tablets: + - type: "replica" + vttablet: + replicas: 2 + - type: "rdonly" + vttablet: + replicas: 1 + copySchema: + source: "customer/0" + - name: "80-" + tablets: + - type: "replica" + vttablet: + replicas: 2 + - type: "rdonly" + vttablet: + replicas: 1 + copySchema: + source: "customer/0" + +vtctld: + serviceType: "NodePort" + resources: + +vtgate: + serviceType: "NodePort" + resources: + +vttablet: + mysqlSize: "prod" + resources: + mysqlResources: + # It's generally not recommended to override this value for production usage. + terminationGracePeriodSeconds: 1 + +vtworker: + resources: + +pmm: + enabled: false + +orchestrator: + enabled: false diff --git a/examples/helm/303_horizontal_split.yaml b/examples/helm/legacy/303_horizontal_split.yaml similarity index 93% rename from examples/helm/303_horizontal_split.yaml rename to examples/helm/legacy/303_horizontal_split.yaml index 7415384db45..1e9119c6540 100644 --- a/examples/helm/303_horizontal_split.yaml +++ b/examples/helm/legacy/303_horizontal_split.yaml @@ -1,8 +1,6 @@ topology: cells: - name: "zone1" - etcd: - replicas: 1 vtctld: replicas: 1 vtgate: @@ -54,10 +52,6 @@ jobs: cell: "zone1" command: "SplitClone -min_healthy_rdonly_tablets=1 customer/0" -etcd: - replicas: 1 - resources: - vtctld: serviceType: "NodePort" resources: @@ -70,6 +64,8 @@ vttablet: mysqlSize: "prod" resources: mysqlResources: + # It's generally not recommended to override this value for production usage. + terminationGracePeriodSeconds: 1 vtworker: resources: diff --git a/examples/helm/304_migrate_replicas.yaml b/examples/helm/legacy/304_migrate_replicas.yaml similarity index 93% rename from examples/helm/304_migrate_replicas.yaml rename to examples/helm/legacy/304_migrate_replicas.yaml index 950b1e8ce38..de2716f9710 100644 --- a/examples/helm/304_migrate_replicas.yaml +++ b/examples/helm/legacy/304_migrate_replicas.yaml @@ -1,8 +1,6 @@ topology: cells: - name: "zone1" - etcd: - replicas: 1 vtctld: replicas: 1 vtgate: @@ -56,10 +54,6 @@ jobs: kind: "vtctlclient" command: "MigrateServedTypes customer/0 replica" -etcd: - replicas: 1 - resources: - vtctld: serviceType: "NodePort" resources: @@ -72,6 +66,8 @@ vttablet: mysqlSize: "prod" resources: mysqlResources: + # It's generally not recommended to override this value for production usage. + terminationGracePeriodSeconds: 1 vtworker: resources: diff --git a/examples/helm/305_migrate_master.yaml b/examples/helm/legacy/305_migrate_master.yaml similarity index 93% rename from examples/helm/305_migrate_master.yaml rename to examples/helm/legacy/305_migrate_master.yaml index ae3dd170105..b85357bdaf8 100644 --- a/examples/helm/305_migrate_master.yaml +++ b/examples/helm/legacy/305_migrate_master.yaml @@ -1,8 +1,6 @@ topology: cells: - name: "zone1" - etcd: - replicas: 1 vtctld: replicas: 1 vtgate: @@ -53,10 +51,6 @@ jobs: kind: "vtctlclient" command: "MigrateServedTypes customer/0 master" -etcd: - replicas: 1 - resources: - vtctld: serviceType: "NodePort" resources: @@ -69,6 +63,8 @@ vttablet: mysqlSize: "prod" resources: mysqlResources: + # It's generally not recommended to override this value for production usage. + terminationGracePeriodSeconds: 1 vtworker: resources: diff --git a/examples/helm/legacy/306_down_shard_0.yaml b/examples/helm/legacy/306_down_shard_0.yaml new file mode 100644 index 00000000000..a540e81ba19 --- /dev/null +++ b/examples/helm/legacy/306_down_shard_0.yaml @@ -0,0 +1,63 @@ +topology: + cells: + - name: "zone1" + vtctld: + replicas: 1 + vtgate: + replicas: 1 + mysqlProtocol: + enabled: true + authType: "none" + keyspaces: + - name: "commerce" + shards: + - name: "0" + tablets: + - type: "replica" + vttablet: + replicas: 2 + - type: "rdonly" + vttablet: + replicas: 1 + - name: "customer" + shards: + - name: "-80" + tablets: + - type: "replica" + vttablet: + replicas: 2 + - type: "rdonly" + vttablet: + replicas: 1 + - name: "80-" + tablets: + - type: "replica" + vttablet: + replicas: 2 + - type: "rdonly" + vttablet: + replicas: 1 + +vtctld: + serviceType: "NodePort" + resources: + +vtgate: + serviceType: "NodePort" + resources: + +vttablet: + mysqlSize: "prod" + resources: + mysqlResources: + # It's generally not recommended to override this value for production usage. + terminationGracePeriodSeconds: 1 + +vtworker: + resources: + +pmm: + enabled: false + +orchestrator: + enabled: false diff --git a/examples/helm/legacy/307_delete_shard_0.yaml b/examples/helm/legacy/307_delete_shard_0.yaml new file mode 100644 index 00000000000..20527187cc8 --- /dev/null +++ b/examples/helm/legacy/307_delete_shard_0.yaml @@ -0,0 +1,68 @@ +topology: + cells: + - name: "zone1" + vtctld: + replicas: 1 + vtgate: + replicas: 1 + mysqlProtocol: + enabled: true + authType: "none" + keyspaces: + - name: "commerce" + shards: + - name: "0" + tablets: + - type: "replica" + vttablet: + replicas: 2 + - type: "rdonly" + vttablet: + replicas: 1 + - name: "customer" + shards: + - name: "-80" + tablets: + - type: "replica" + vttablet: + replicas: 2 + - type: "rdonly" + vttablet: + replicas: 1 + - name: "80-" + tablets: + - type: "replica" + vttablet: + replicas: 2 + - type: "rdonly" + vttablet: + replicas: 1 + +jobs: + - name: "delete-shard0" + kind: "vtctlclient" + command: "DeleteShard -recursive customer/0" + +vtctld: + serviceType: "NodePort" + resources: + +vtgate: + serviceType: "NodePort" + resources: + +vttablet: + mysqlSize: "prod" + resources: + mysqlResources: + # It's generally not recommended to override this value for production usage. + terminationGracePeriodSeconds: 1 + +vtworker: + resources: + +pmm: + enabled: false + +orchestrator: + enabled: false diff --git a/examples/helm/legacy/308_final.yaml b/examples/helm/legacy/308_final.yaml new file mode 100644 index 00000000000..a540e81ba19 --- /dev/null +++ b/examples/helm/legacy/308_final.yaml @@ -0,0 +1,63 @@ +topology: + cells: + - name: "zone1" + vtctld: + replicas: 1 + vtgate: + replicas: 1 + mysqlProtocol: + enabled: true + authType: "none" + keyspaces: + - name: "commerce" + shards: + - name: "0" + tablets: + - type: "replica" + vttablet: + replicas: 2 + - type: "rdonly" + vttablet: + replicas: 1 + - name: "customer" + shards: + - name: "-80" + tablets: + - type: "replica" + vttablet: + replicas: 2 + - type: "rdonly" + vttablet: + replicas: 1 + - name: "80-" + tablets: + - type: "replica" + vttablet: + replicas: 2 + - type: "rdonly" + vttablet: + replicas: 1 + +vtctld: + serviceType: "NodePort" + resources: + +vtgate: + serviceType: "NodePort" + resources: + +vttablet: + mysqlSize: "prod" + resources: + mysqlResources: + # It's generally not recommended to override this value for production usage. + terminationGracePeriodSeconds: 1 + +vtworker: + resources: + +pmm: + enabled: false + +orchestrator: + enabled: false diff --git a/examples/helm/kmysql.sh b/examples/helm/legacy/kmysql.sh similarity index 87% rename from examples/helm/kmysql.sh rename to examples/helm/legacy/kmysql.sh index 29ddb2c054f..f9cfaaf80a4 100755 --- a/examples/helm/kmysql.sh +++ b/examples/helm/legacy/kmysql.sh @@ -16,8 +16,8 @@ # This is a convenience script to run the mysql client against the local example. -host=$(minikube service vtgate-zone1 --format "{{.IP}}" | tail -n 1) -port=$(minikube service vtgate-zone1 --format "{{.Port}}" | tail -n 1) +host=$(minikube service vtgate-zone1 --url=true --format="{{.IP}}" | tail -n 1) +port=$(minikube service vtgate-zone1 --url=true --format="{{.Port}}" | tail -n 1) if [ -z $port ]; then #This checks K8s running on an single node by kubeadm diff --git a/examples/local/lvtctl.sh b/examples/helm/legacy/kvtctld.sh similarity index 91% rename from examples/local/lvtctl.sh rename to examples/helm/legacy/kvtctld.sh index 0197fb79b33..2499e706301 100755 --- a/examples/local/lvtctl.sh +++ b/examples/helm/legacy/kvtctld.sh @@ -1,13 +1,13 @@ #!/bin/bash # Copyright 2019 The Vitess Authors. -# +# # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -16,4 +16,4 @@ # This is a convenience script to run vtctlclient against the local example. -exec vtctlclient -server localhost:15999 "$@" +xdg-open "$(minikube service vtctld --url|head -n 1)" diff --git a/examples/kubernetes/README.md b/examples/kubernetes/README.md deleted file mode 100644 index a4ea12366cd..00000000000 --- a/examples/kubernetes/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# Vitess on Kubernetes - -This directory contains an example configuration for running Vitess on -[Kubernetes](https://kubernetes.io/). - -See the [Vitess on Kubernetes](https://vitess.io/docs/tutorials/kubernetes/) \ No newline at end of file diff --git a/examples/kubernetes/advanced.md b/examples/kubernetes/advanced.md deleted file mode 100644 index 1b4e4f260f3..00000000000 --- a/examples/kubernetes/advanced.md +++ /dev/null @@ -1,61 +0,0 @@ -# Advanced Vitess on Kubernetes - -## Automatically run Vitess on Container Engine - -The following commands will create a Google Container Engine cluster and bring -up Vitess with two shards and three tablets per shard: (Note that it does not -bring up the Guestbook example) - -``` - -vitess/examples/kubernetes$ export SHARDS=-80,80- -vitess/examples/kubernetes$ export GKE_ZONE=us-central1-b -vitess/examples/kubernetes$ export GKE_NUM_NODES=10 -vitess/examples/kubernetes$ export GKE_MACHINE_TYPE=n1-standard-8 -vitess/examples/kubernetes$ ./cluster-up.sh -vitess/examples/kubernetes$ ./vitess-up.sh -``` - -Run the following to tear down the entire Vitess + container engine cluster: - -``` -vitess/examples/kubernetes$ ./vitess-down.sh -vitess/examples/kubernetes$ ./cluster-down.sh -``` - -## Parameterizing configs - -The vitess and cluster scripts both support parameterization via exporting -environment variables. - -### Parameterizing cluster scripts - -Common environment variables: - -* GKE_ZONE - Zone to use for Container Engine (default us-central1-b) -* GKE_CLUSTER_NAME - Name to use when creating a cluster (default example). -* SHARDS - Comma delimited keyranges for shards (default -80,80- for 2 shards). -Use 0 for an unsharded keyspace. - -The cluster-up.sh script supports the following environment variables: - -* GKE_MACHINE_TYPE - Container Engine machine type (default n1-standard-1) -* GKE_NUM_NODES - Number of nodes to use for the cluster (required). -* GKE_SSD_SIZE_GB - SSD size (in GB) to use (default 0 for no SSD). - -The vitess-up.sh script supports the following environment variables: - -* TABLETS_PER_SHARD - Number of tablets per shard (default 3). -* RDONLY_COUNT - Number of tablets per shard that are rdonly (default 0). -* VTGATE_COUNT - Number of vtgates (default 25% of total vttablet count, -with a minimum of 3). - -For example, to create an unsharded keyspace with 5 tablets, use the following: - -``` -export SHARDS=0 -export TABLETS_PER_SHARD=5 -vitess/examples/kubernetes$ ./cluster-up.sh -vitess/examples/kubernetes$ ./vitess-up.sh -``` - diff --git a/examples/kubernetes/cluster-up.sh b/examples/kubernetes/cluster-up.sh deleted file mode 100755 index 7e4da58946c..00000000000 --- a/examples/kubernetes/cluster-up.sh +++ /dev/null @@ -1,83 +0,0 @@ -#!/bin/bash - -# Copyright 2019 The Vitess Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# This is an example script that creates a fully functional vitess cluster. -# It performs the following steps: -# 1. Create a container engine cluster -# 2. Create etcd clusters -# 3. Create vtctld clusters -# 4. Forward vtctld port -# 5. Create vttablet clusters -# 6. Perform vtctl initialization: -# SetKeyspaceShardingInfo, Rebuild Keyspace, Reparent Shard, Apply Schema -# 7. Create vtgate clusters -# 8. Forward vtgate port - -# Customizable parameters -GKE_ZONE=${GKE_ZONE:-'us-central1-b'} -GKE_MACHINE_TYPE=${GKE_MACHINE_TYPE:-'n1-standard-4'} -GKE_CLUSTER_NAME=${GKE_CLUSTER_NAME:-'example'} -GKE_SSD_SIZE_GB=${GKE_SSD_SIZE_GB:-0} -GKE_NUM_NODES=${GKE_NUM_NODES:-0} -VTDATAROOT_VOLUME=${VTDATAROOT_VOLUME:-'/ssd'} - -# Get region from zone (everything to last dash) -gke_region=`echo $GKE_ZONE | sed "s/-[^-]*$//"` - -export KUBECTL='kubectl' -gcloud config set compute/zone $GKE_ZONE -project_id=`gcloud config list project | sed -n 2p | cut -d " " -f 3` - -echo "****************************" -echo "*Creating cluster:" -echo "* Zone: $GKE_ZONE" -echo "* Machine type: $GKE_MACHINE_TYPE" -echo "* Num nodes: $GKE_NUM_NODES" -echo "* SSD Size: $GKE_SSD_SIZE_GB" -echo "* Cluster name: $GKE_CLUSTER_NAME" -echo "* Project ID: $project_id" -echo "****************************" -gcloud container clusters create $GKE_CLUSTER_NAME --machine-type $GKE_MACHINE_TYPE --num-nodes $GKE_NUM_NODES --scopes storage-rw -gcloud config set container/cluster $GKE_CLUSTER_NAME - -if [ $GKE_SSD_SIZE_GB -gt 0 ] -then - echo Creating SSDs and attaching to container engine nodes - i=1 - for nodename in `$KUBECTL get nodes --no-headers | awk '{print $1}'`; do - diskname=$GKE_CLUSTER_NAME-vt-ssd-$i - gcloud compute disks create $diskname --type=pd-ssd --size=${GKE_SSD_SIZE_GB}GB - gcloud compute instances attach-disk $nodename --disk $diskname - gcloud compute ssh $nodename --zone=$GKE_ZONE --command "sudo mkdir ${VTDATAROOT_VOLUME}; sudo /usr/share/google/safe_format_and_mount -m \"mkfs.ext4 -o noatime -F\" /dev/disk/by-id/google-persistent-disk-1 ${VTDATAROOT_VOLUME} &" - gcloud compute ssh $nodename --zone=$GKE_ZONE --command "echo '/dev/disk/by-id/google-persistent-disk-1 /ssd ext4 defaults,noatime 0 0' | sudo tee --append /etc/fstab > /dev/null" - let i=i+1 - done -fi - -if [ -n "$NEWRELIC_LICENSE_KEY" -a $GKE_SSD_SIZE_GB -gt 0 ]; then - i=1 - for nodename in `$KUBECTL get nodes --no-header | awk '{print $1}'`; do - gcloud compute copy-files newrelic.sh $nodename:~/ - gcloud compute copy-files newrelic_start_agent.sh $nodename:~/ - gcloud compute copy-files newrelic_start_mysql_plugin.sh $nodename:~/ - gcloud compute ssh $nodename --command "bash -c '~/newrelic.sh ${NEWRELIC_LICENSE_KEY}'" - let i=i+1 - done -fi - -echo "****************************" -echo "* Complete!" -echo "****************************" diff --git a/examples/kubernetes/configure.sh b/examples/kubernetes/configure.sh deleted file mode 100755 index 8ed12fd9587..00000000000 --- a/examples/kubernetes/configure.sh +++ /dev/null @@ -1,69 +0,0 @@ -#!/bin/bash - -# Copyright 2019 The Vitess Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# This script generates config.sh, which is a site-local config file that is not -# checked into source control. - -# Erase any existing file since we append from here on. -> config.sh - -# Custom Docker image. -read -p "Vitess Docker image (leave empty for default) []: " -echo "vitess_image=\"$REPLY\"" >> config.sh - -# Select and configure Backup Storage Implementation. -storage=gcs -read -p "Backup Storage (file, gcs) [gcs]: " -if [ -n "$REPLY" ]; then storage="$REPLY"; fi - -case "$storage" in -gcs) - # Google Cloud Storage - read -p "Google Cloud Storage bucket for Vitess backups: " bucket - if [ -z "$bucket" ]; then - echo "ERROR: Bucket name must not be empty." - exit 1 - fi - echo - echo "NOTE: If you haven't already created this bucket, you can do so by running:" - echo " gsutil mb gs://$bucket" - echo - - backup_flags=$(echo -backup_storage_implementation gcs \ - -gcs_backup_storage_bucket "'$bucket'") - ;; -file) - # Mounted volume (e.g. NFS) - read -p "Root directory for backups (usually an NFS mount): " file_root - if [ -z "$file_root" ]; then - echo "ERROR: Root directory must not be empty." - exit 1 - fi - echo - echo "NOTE: You must add your NFS mount to the vtctld-controller-template" - echo " and vttablet-pod-template as described in the Kubernetes docs:" - echo " https://kubernetes.io/docs/concepts/storage/volumes#nfs" - echo - - backup_flags=$(echo -backup_storage_implementation file \ - -file_backup_storage_root "'$file_root'") - ;; -*) - echo "ERROR: Unsupported backup storage implementation: $storage" - exit 1 -esac -echo "backup_flags=\"$backup_flags\"" >> config.sh - diff --git a/examples/kubernetes/env.sh b/examples/kubernetes/env.sh deleted file mode 100644 index c644b4de8be..00000000000 --- a/examples/kubernetes/env.sh +++ /dev/null @@ -1,94 +0,0 @@ -#!/bin/bash -# Copyright 2019 The Vitess Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# This is an include file used by the other scripts in this directory. - -# Most clusters will just be accessed with 'kubectl' on $PATH. -# However, some might require a different command. For example, GKE required -# KUBECTL='gcloud container kubectl' for a while. Now that most of our -# use cases just need KUBECTL=kubectl, we'll make that the default. -KUBECTL=${KUBECTL:-kubectl} - -# Kubernetes API address for $KUBECTL. When the Kubernetes API server is not -# local, We can easily access the API by editing KUBERNETES_API_SERVER's value -KUBERNETES_API_SERVER=${KUBERNETES_API_SERVER:-""} - -# Kubernetes namespace for Vitess and components. -VITESS_NAME=${VITESS_NAME:-'default'} - -# Kubernetes options config -KUBECTL_OPTIONS="--namespace=$VITESS_NAME" -if [[ -n "$KUBERNETES_API_SERVER" ]]; then - KUBECTL_OPTIONS+=" --server=$KUBERNETES_API_SERVER" -fi - -# CELLS should be a comma separated list of cells -# the first cell listed will become local to vtctld. -CELLS=${CELLS:-'test'} - -# This should match the nodePort in vtctld-service.yaml -VTCTLD_PORT=${VTCTLD_PORT:-30001} - -# Get the ExternalIP of any node. -get_node_ip() { - $KUBECTL $KUBECTL_OPTIONS get -o template --template '{{range (index .items 0).status.addresses}}{{if eq .type "ExternalIP" "LegacyHostIP"}}{{.address}}{{end}}{{end}}' nodes -} - -# Try to find vtctld address if not provided. -get_vtctld_addr() { - if [ -z "$VTCTLD_ADDR" ]; then - VTCTLD_HOST=$(get_node_ip) - if [ -n "$VTCTLD_HOST" ]; then - VTCTLD_ADDR="$VTCTLD_HOST:$VTCTLD_PORT" - fi - fi -} - -# Find the name of a vtctld pod. -get_vtctld_pod() { - $KUBECTL $KUBECTL_OPTIONS get -o template --template "{{if ge (len .items) 1 }}{{(index .items 0).metadata.name}}{{end}}" -l 'app=vitess,component=vtctld' pods -} - -start_vtctld_forward() { - pod=`get_vtctld_pod` - if [ -z "$pod" ]; then - >&2 echo "ERROR: Can't get vtctld pod name. Is vtctld running?" - return 1 - fi - - tmpfile=`mktemp` - $KUBECTL $KUBECTL_OPTIONS port-forward $pod 0:15999 &> $tmpfile & - vtctld_forward_pid=$! - - until [[ `cat $tmpfile` =~ :([0-9]+)\ -\> ]]; do :; done - vtctld_forward_port=${BASH_REMATCH[1]} - rm $tmpfile -} - -stop_vtctld_forward() { - kill $vtctld_forward_pid -} - -config_file=`dirname "${BASH_SOURCE}"`/config.sh -if [ ! -f $config_file ]; then - echo "Please run ./configure.sh first to generate config.sh file." - exit 1 -fi - -source $config_file - -# Fill in defaults for new variables, so old config.sh files still work. -vitess_image=${vitess_image:-vitess/lite} - diff --git a/examples/kubernetes/etcd-down.sh b/examples/kubernetes/etcd-down.sh deleted file mode 100644 index 3aef6636bd7..00000000000 --- a/examples/kubernetes/etcd-down.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/bin/bash - -# Copyright 2019 The Vitess Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# This is an example script that tears down the etcd servers started by -# etcd-up.sh. - -set -e - -script_root=`dirname "${BASH_SOURCE}"` -source $script_root/env.sh - -replicas=${ETCD_REPLICAS:-3} -cells=`echo $CELLS | tr ',' ' '` - -# Delete etcd clusters -for cell in 'global' $cells; do - echo "Stopping etcd cluster for $cell cell..." - sed -e "s/{{cell}}/$cell/g" -e "s/{{replicas}}/$replicas/g" \ - etcd-service-template.yaml | \ - $KUBECTL $KUBECTL_OPTIONS delete -f - -done diff --git a/examples/kubernetes/etcd-service-template.yaml b/examples/kubernetes/etcd-service-template.yaml deleted file mode 100644 index 9aceaec4b33..00000000000 --- a/examples/kubernetes/etcd-service-template.yaml +++ /dev/null @@ -1,14 +0,0 @@ -apiVersion: "etcd.database.coreos.com/v1beta2" -kind: "EtcdCluster" -metadata: - name: "etcd-{{cell}}" -spec: - size: {{replicas}} - version: "3.1.8" - repository: "quay.io/coreos/etcd" - pod: - labels: - component: etcd - cell: {{cell}} - application: vitess - busyboxImage: "busybox:1.28.0-glibc" diff --git a/examples/kubernetes/etcd-up.sh b/examples/kubernetes/etcd-up.sh deleted file mode 100755 index f4d4d6118bc..00000000000 --- a/examples/kubernetes/etcd-up.sh +++ /dev/null @@ -1,61 +0,0 @@ -#!/bin/bash - -# Copyright 2019 The Vitess Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# This is an example script that creates etcd clusters. -# Vitess requires a global cluster, as well as one for each cell. -# -# For automatic discovery, an etcd cluster can be bootstrapped from an -# existing cluster. In this example, we use an externally-run discovery -# service, but you can use your own. See the etcd docs for more: -# https://github.com/coreos/etcd/blob/v2.0.13/Documentation/clustering.md - -set -e - -script_root=`dirname "${BASH_SOURCE}"` -source $script_root/env.sh - -replicas=${ETCD_REPLICAS:-3} -cells=`echo $CELLS | tr ',' ' '` - -# Check the installation for etcd-operator has been done. -# To make sure the EtcdClusters CRD not only exists but is ready to serve, -# we try to list EtcdClusters. This will succeed even if the list is empty. -if ! kubectl get etcdclusters.etcd.database.coreos.com &> /dev/null ; then - # etcd-operator is a shared resource, and installing it on a secure - # cluster requires granting RBAC permissions. - # We therefore require the user to do this before running Vitess. - echo - echo "Please install etcd-operator in the same namespace as Vitess" - echo "before running etcd-up.sh. See the instructions here:" - echo - echo " https://github.com/coreos/etcd-operator/blob/master/doc/user/install_guide.md" - echo - echo "If you already installed etcd-operator and still get this prompt," - echo "check for any errors in etcd-operator logs:" - echo - echo " kubectl logs -l name=etcd-operator" - echo - exit 1 -fi - -for cell in 'global' $cells; do - # Create the etcd cluster using etcd-operator - echo "Creating etcd service for '$cell' cell..." - sed -e "s/{{cell}}/$cell/g" -e "s/{{replicas}}/$replicas/g" \ - etcd-service-template.yaml | \ - $KUBECTL $KUBECTL_OPTIONS create -f - -done - diff --git a/examples/kubernetes/guestbook-controller-template.yaml b/examples/kubernetes/guestbook-controller-template.yaml deleted file mode 100644 index 2897b3f5929..00000000000 --- a/examples/kubernetes/guestbook-controller-template.yaml +++ /dev/null @@ -1,29 +0,0 @@ -kind: ReplicationController -apiVersion: v1 -metadata: - name: guestbook -spec: - replicas: 3 - template: - metadata: - labels: - component: frontend - app: guestbook - spec: - containers: - - name: guestbook - image: vitess/guestbook - livenessProbe: - httpGet: - path: /env - port: 8080 - initialDelaySeconds: 30 - timeoutSeconds: 5 - ports: - - name: http-server - containerPort: 8080 - resources: - limits: - memory: "128Mi" - cpu: "100m" - args: ["--port", "{{port}}", "--cell", "{{cell}}", "--keyspace", "{{keyspace}}", "--vtgate_port", "{{vtgate_port}}"] diff --git a/examples/kubernetes/guestbook-down.sh b/examples/kubernetes/guestbook-down.sh deleted file mode 100755 index 35186041553..00000000000 --- a/examples/kubernetes/guestbook-down.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/bash - -# Copyright 2019 The Vitess Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# This is an example script that stops guestbook. - -script_root=`dirname "${BASH_SOURCE}"` -source $script_root/env.sh - -echo "Stopping guestbook replicationcontroller..." -$KUBECTL $KUBECTL_OPTIONS delete replicationcontroller guestbook - -echo "Deleting guestbook service..." -$KUBECTL $KUBECTL_OPTIONS delete service guestbook diff --git a/examples/kubernetes/guestbook-service.yaml b/examples/kubernetes/guestbook-service.yaml deleted file mode 100644 index 341c3ee0314..00000000000 --- a/examples/kubernetes/guestbook-service.yaml +++ /dev/null @@ -1,16 +0,0 @@ -kind: Service -apiVersion: v1 -metadata: - name: guestbook - labels: - component: frontend - app: guestbook -spec: - ports: - - port: 80 - targetPort: http-server - selector: - component: frontend - app: guestbook - type: LoadBalancer - diff --git a/examples/kubernetes/guestbook-up.sh b/examples/kubernetes/guestbook-up.sh deleted file mode 100755 index f246a72e2ec..00000000000 --- a/examples/kubernetes/guestbook-up.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/bash - -# Copyright 2019 The Vitess Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# This is an example script that starts a guestbook replicationcontroller. - -set -e - -port=${GUESTBOOK_PORT:-8080} -cell=${GUESTBOOK_CELL:-"test"} -keyspace=${GUESTBOOK_KEYSPACE:-"test_keyspace"} -vtgate_port=${VTGATE_PORT:-15991} - -script_root=`dirname "${BASH_SOURCE}"` -source $script_root/env.sh - -echo "Creating guestbook service..." -$KUBECTL $KUBECTL_OPTIONS create -f guestbook-service.yaml - -sed_script="" -for var in port cell keyspace vtgate_port; do - sed_script+="s,{{$var}},${!var},g;" -done - -echo "Creating guestbook replicationcontroller..." -sed -e "$sed_script" guestbook-controller-template.yaml | $KUBECTL $KUBECTL_OPTIONS create -f - diff --git a/examples/kubernetes/guestbook/Dockerfile b/examples/kubernetes/guestbook/Dockerfile deleted file mode 100644 index afdd85b4f2e..00000000000 --- a/examples/kubernetes/guestbook/Dockerfile +++ /dev/null @@ -1,43 +0,0 @@ -# Copyright 2019 The Vitess Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# This Dockerfile should be built from within the accompanying build.sh script. -FROM debian:jessie - -RUN apt-get update -y \ - && apt-get install --no-install-recommends -y -q \ - build-essential \ - python2.7 \ - python2.7-dev \ - python-pip \ - git \ - && pip install -U pip \ - && pip install virtualenv - -WORKDIR /app -RUN virtualenv /env -ADD requirements.txt /app/requirements.txt -RUN /env/bin/pip install -r /app/requirements.txt -ADD main.py requirements.txt /app/ -ADD static /app/static - -EXPOSE 8080 -CMD [] -ENTRYPOINT ["/env/bin/python", "main.py"] - -ADD tmp/pkg /app/pkg -ADD tmp/lib /app/lib -ENV LD_LIBRARY_PATH /app/lib -ENV PYTHONPATH /app/pkg/py-vtdb:/app/pkg/py-mock-1.0.1/lib/python2.7/site-packages:/app/pkg/dist-packages - diff --git a/examples/kubernetes/guestbook/README.md b/examples/kubernetes/guestbook/README.md deleted file mode 100644 index 2ff41a9217c..00000000000 --- a/examples/kubernetes/guestbook/README.md +++ /dev/null @@ -1,14 +0,0 @@ -# vitess/guestbook - -This is a Docker image for a sample guestbook app that uses Vitess. - -It is essentially a port of the -[kubernetes/guestbook-go](https://github.com/kubernetes/examples/tree/master/guestbook-go) -example, but using Python instead of Go for the app server, -and Vitess instead of Redis for the storage engine. - -It has also been modified to support multiple Guestbook pages, -to better demonstrate sharding support in Vitess. - -Note that the Dockerfile should be built with the accompanying build.sh script. -See the comments in the script for more information. diff --git a/examples/kubernetes/guestbook/build.sh b/examples/kubernetes/guestbook/build.sh deleted file mode 100755 index 712bc8bf123..00000000000 --- a/examples/kubernetes/guestbook/build.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/bin/bash - -# Copyright 2019 The Vitess Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# This is a script to build the vitess/guestbook Docker image. -# It must be run from within a bootstrapped vitess tree, after dev.env. - -set -e - -mkdir tmp tmp/pkg tmp/lib -cp extract.sh tmp/ -chmod -R 777 tmp - -# We also need the grpc library. -docker run --rm -v $PWD/tmp:/out vitess/base bash /out/extract.sh - -# Build the Docker image. -docker build -t vitess/guestbook . - -# Clean up. -docker run --rm -v $PWD/tmp:/out vitess/base bash -c 'rm -rf /out/pkg/* /out/lib/*' -rm -rf tmp diff --git a/examples/kubernetes/guestbook/extract.sh b/examples/kubernetes/guestbook/extract.sh deleted file mode 100644 index 04499c87397..00000000000 --- a/examples/kubernetes/guestbook/extract.sh +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright 2019 The Vitess Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# Don't run this. It is only used as part of build.sh. - -set -e - -# Collect all the local Python libs we need. -mkdir -p /out/pkg/py-vtdb -cp -R $VTROOT/py/* /out/pkg/py-vtdb/ -cp -R /usr/local/lib/python2.7/dist-packages /out/pkg/ -cp -R /vt/dist/py-* /out/pkg/ - diff --git a/examples/kubernetes/guestbook/main.py b/examples/kubernetes/guestbook/main.py deleted file mode 100644 index 9814990b915..00000000000 --- a/examples/kubernetes/guestbook/main.py +++ /dev/null @@ -1,115 +0,0 @@ -# Copyright 2019 The Vitess Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Main python file.""" - -import argparse -import json -import os -import time - -from flask import Flask - -from vtdb import vtgate_client - -# Register gRPC protocol. -from vtdb import grpc_vtgate_client # pylint: disable=unused-import - -app = Flask(__name__) - -# conn is the connection to vtgate. -conn = None -keyspace = None - - -@app.route('/') -def index(): - return app.send_static_file('index.html') - - -@app.route('/page/') -def view(page): - _ = page - return app.send_static_file('index.html') - - -@app.route('/lrange/guestbook/') -def list_guestbook(page): - """Read the list from a replica.""" - cursor = conn.cursor(tablet_type='replica', keyspace=keyspace) - - cursor.execute( - 'SELECT message, time_created_ns FROM messages WHERE page=:page' - ' ORDER BY time_created_ns', - {'page': page}) - entries = [row[0] for row in cursor.fetchall()] - cursor.close() - - return json.dumps(entries) - - -@app.route('/rpush/guestbook//') -def add_entry(page, value): - """Insert a row on the master.""" - cursor = conn.cursor(tablet_type='master', keyspace=keyspace, writable=True) - - cursor.begin() - cursor.execute( - 'INSERT INTO messages (page, time_created_ns, message)' - ' VALUES (:page, :time_created_ns, :message)', - { - 'page': page, - 'time_created_ns': int(time.time() * 1e9), - 'message': value, - }) - cursor.commit() - - # Read the list back from master (critical read) because it's - # important that the user sees their own addition immediately. - cursor.execute( - 'SELECT message, time_created_ns FROM messages WHERE page=:page' - ' ORDER BY time_created_ns', - {'page': page}) - entries = [row[0] for row in cursor.fetchall()] - cursor.close() - - return json.dumps(entries) - - -@app.route('/env') -def env(): - return json.dumps(dict(os.environ)) - - -if __name__ == '__main__': - parser = argparse.ArgumentParser(description='Run guestbook app') - parser.add_argument('--port', help='Port', default=8080, type=int) - parser.add_argument('--cell', help='Cell', default='test', type=str) - parser.add_argument( - '--keyspace', help='Keyspace', default='test_keyspace', type=str) - parser.add_argument( - '--timeout', help='Connect timeout (s)', default=10, type=int) - parser.add_argument( - '--vtgate_port', help='Vtgate Port', default=15991, type=int) - guestbook_args = parser.parse_args() - - # Get vtgate service address from Kubernetes DNS. - addr = 'vtgate-%s:%d' % (guestbook_args.cell, guestbook_args.vtgate_port) - - # Connect to vtgate. - conn = vtgate_client.connect('grpc', addr, guestbook_args.timeout) - - keyspace = guestbook_args.keyspace - - app.run(host='0.0.0.0', port=guestbook_args.port, debug=True) diff --git a/examples/kubernetes/guestbook/requirements.txt b/examples/kubernetes/guestbook/requirements.txt deleted file mode 100644 index eb913c5c387..00000000000 --- a/examples/kubernetes/guestbook/requirements.txt +++ /dev/null @@ -1,3 +0,0 @@ -Flask==1.0 -grpcio==1.12.0 -grpcio-tools==1.12.0 diff --git a/examples/kubernetes/guestbook/static/index.html b/examples/kubernetes/guestbook/static/index.html deleted file mode 100644 index 946a2b3d986..00000000000 --- a/examples/kubernetes/guestbook/static/index.html +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - Guestbook - - - - -
-

Waiting for database connection...

-
- -
-
- - Submit -
-
- -
-

-

/env -

- - - - diff --git a/examples/kubernetes/guestbook/static/script.js b/examples/kubernetes/guestbook/static/script.js deleted file mode 100644 index 0240307fcd9..00000000000 --- a/examples/kubernetes/guestbook/static/script.js +++ /dev/null @@ -1,60 +0,0 @@ -$(document).ready(function() { - var headerTitleElement = $("#header h1"); - var entriesElement = $("#guestbook-entries"); - var formElement = $("#guestbook-form"); - var submitElement = $("#guestbook-submit"); - var entryContentElement = $("#guestbook-entry-content"); - var hostAddressElement = $("#guestbook-host-address"); - - // Look for page number in the URL, if any. - var pageNum = -1; - var match = window.location.href.match(/\/page\/(\d+)$/); - if (match) { - pageNum = parseInt(match[1]); - headerTitleElement.text('Guestbook Page ' + pageNum); - } else { - // No page number provided. Link to a random one. - pageNum = Math.floor(Math.random() * 100); - entriesElement.html('

Pick a page to view by navigating to /page/### or go to a random page.

'); - formElement.remove(); - return; - } - - var appendGuestbookEntries = function(data) { - entriesElement.empty(); - $.each(data, function(key, val) { - entriesElement.append("

" + val + "

"); - }); - } - - var handleSubmission = function(e) { - e.preventDefault(); - var entryValue = entryContentElement.val() - if (entryValue.length > 0) { - entriesElement.append("

...

"); - $.getJSON("/rpush/guestbook/" + pageNum + "/" + entryValue, appendGuestbookEntries); - } - return false; - } - - // colors = purple, blue, red, green, yellow - var colors = ["#549", "#18d", "#d31", "#2a4", "#db1"]; - var randomColor = colors[Math.floor(5 * Math.random())]; - (function setElementsColor(color) { - headerTitleElement.css("color", color); - entryContentElement.css("box-shadow", "inset 0 0 0 2px " + color); - submitElement.css("background-color", color); - })(randomColor); - - submitElement.click(handleSubmission); - formElement.submit(handleSubmission); - hostAddressElement.append(document.URL); - - // Poll every second. - (function fetchGuestbook() { - $.getJSON("/lrange/guestbook/" + pageNum).done(appendGuestbookEntries).always( - function() { - setTimeout(fetchGuestbook, 1000); - }); - })(); -}); diff --git a/examples/kubernetes/guestbook/static/style.css b/examples/kubernetes/guestbook/static/style.css deleted file mode 100644 index fd1c393fb08..00000000000 --- a/examples/kubernetes/guestbook/static/style.css +++ /dev/null @@ -1,61 +0,0 @@ -body, input { - color: #123; - font-family: "Gill Sans", sans-serif; -} - -div { - overflow: hidden; - padding: 1em 0; - position: relative; - text-align: center; -} - -h1, h2, p, input, a { - font-weight: 300; - margin: 0; -} - -h1 { - color: #BDB76B; - font-size: 3.5em; -} - -h2 { - color: #999; -} - -form { - margin: 0 auto; - max-width: 50em; - text-align: center; -} - -input { - border: 0; - border-radius: 1000px; - box-shadow: inset 0 0 0 2px #BDB76B; - display: inline; - font-size: 1.5em; - margin-bottom: 1em; - outline: none; - padding: .5em 5%; - width: 55%; -} - -form a { - background: #BDB76B; - border: 0; - border-radius: 1000px; - color: #FFF; - font-size: 1.25em; - font-weight: 400; - padding: .75em 2em; - text-decoration: none; - text-transform: uppercase; - white-space: normal; -} - -p { - font-size: 1.5em; - line-height: 1.5; -} diff --git a/examples/kubernetes/namespace-template.yaml b/examples/kubernetes/namespace-template.yaml deleted file mode 100644 index f0030d5d254..00000000000 --- a/examples/kubernetes/namespace-template.yaml +++ /dev/null @@ -1,4 +0,0 @@ -kind: Namespace -apiVersion: v1 -metadata: - name: {{namespace}} diff --git a/examples/kubernetes/namespace-up.sh b/examples/kubernetes/namespace-up.sh deleted file mode 100755 index d5c6e53f030..00000000000 --- a/examples/kubernetes/namespace-up.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/bash - -# Copyright 2019 The Vitess Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# This is an example script that creates a namespace. - -set -e - -script_root=`dirname "${BASH_SOURCE}"` -source $script_root/env.sh - -namespace=${VITESS_NAME:-'vitess'} - -echo "Creating namespace $namespace..." -sed_script="" -for var in namespace; do - sed_script+="s,{{$var}},${!var},g;" -done -cat namespace-template.yaml | sed -e "$sed_script" | $KUBECTL $KUBECTL_OPTIONS create -f - - diff --git a/examples/kubernetes/newrelic.sh b/examples/kubernetes/newrelic.sh deleted file mode 100755 index 9cc2a2d0b96..00000000000 --- a/examples/kubernetes/newrelic.sh +++ /dev/null @@ -1,37 +0,0 @@ -#!/bin/bash - -# Copyright 2019 The Vitess Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -NEWRELIC_LICENSE_KEY=$1 -VTDATAROOT=$2 - -./newrelic_start_agent.sh $NEWRELIC_LICENSE_KEY -if [ -n "$VTDATAROOT" ]; then - sudo cp newrelic_start*.sh $VTDATAROOT -fi - -mysql_docker_image=`sudo docker ps | awk '$NF~/^k8s_mysql/ {print $1}'` -vttablet_docker_image=`sudo docker ps | awk '$NF~/^k8s_vttablet/ {print $1}'` -vtgate_docker_image=`sudo docker ps | awk '$NF~/^k8s_vtgate/ {print $1}'` -for image in `echo -e "$mysql_docker_image\n$vttablet_docker_image\n$vtgate_docker_image"`; do - if [ -z "$VTDATAROOT" ]; then - vtdataroot=`sudo docker inspect -f '{{index .Volumes "/vt/vtdataroot"}}' $image` - sudo cp newrelic_start*.sh $vtdataroot - fi - sudo docker exec $image apt-get update - sudo docker exec $image apt-get install sudo -y - sudo docker exec $image apt-get install procps -y - sudo docker exec $image bash /vt/vtdataroot/newrelic_start_agent.sh $NEWRELIC_LICENSE_KEY -done diff --git a/examples/kubernetes/newrelic_start_agent.sh b/examples/kubernetes/newrelic_start_agent.sh deleted file mode 100755 index 99b28d1f77f..00000000000 --- a/examples/kubernetes/newrelic_start_agent.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/bash - -# Copyright 2019 The Vitess Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -NEWRELIC_LICENSE_KEY=$1 - -sudo sh -c 'echo deb http://apt.newrelic.com/debian/ newrelic non-free >> /etc/apt/sources.list.d/newrelic.list' -wget -O- https://download.newrelic.com/548C16BF.gpg | sudo apt-key add - -sudo apt-get update -sudo apt-get install newrelic-sysmond -sudo nrsysmond-config --set license_key=$NEWRELIC_LICENSE_KEY -sudo /etc/init.d/newrelic-sysmond start diff --git a/examples/kubernetes/newrelic_start_mysql_plugin.sh b/examples/kubernetes/newrelic_start_mysql_plugin.sh deleted file mode 100755 index 30ab0337401..00000000000 --- a/examples/kubernetes/newrelic_start_mysql_plugin.sh +++ /dev/null @@ -1,58 +0,0 @@ -#!/bin/bash - -# Copyright 2019 The Vitess Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -NEWRELIC_LICENSE_KEY=$1 -AGENT_NAME=$2 - -export TERM=screen - -apt-get install openjdk-7-jdk -y - -yes | LICENSE_KEY=$NEWRELIC_LICENSE_KEY bash -c "$(curl -sSL https://download.newrelic.com/npi/release/install-npi-linux-debian-x64.sh)" - -vttablet_dir=`ls /vt/vtdataroot | grep -o vt_.* | tr '\r' ' ' | xargs` -mysql_sock=/vt/vtdataroot/${vttablet_dir}/mysql.sock -mysql -S $mysql_sock -u vt_dba -e "UPDATE mysql.user SET Password=PASSWORD('password') WHERE User='root'; FLUSH PRIVILEGES;" -mysql -S $mysql_sock -u vt_dba -e "create user newrelic@localhost identified by 'password'" -mysql -S $mysql_sock -u vt_dba -e "create user newrelic@127.0.0.1 identified by 'password'" -mysql -S $mysql_sock -u root --password=password -e "grant all on vt_test_keyspace.* to newrelic@localhost" -mysql -S $mysql_sock -u root --password=password -e "grant all on vt_test_keyspace.* to newrelic@127.0.0.1" -mysql -S $mysql_sock -u vt_dba -e "flush privileges;" - - -cd ~/newrelic-npi -./npi set user root -./npi config set license_key=$NEWRELIC_LICENSE_KEY -./npi fetch com.newrelic.plugins.mysql.instance -y -./npi prepare com.newrelic.plugins.mysql.instance -n - -echo "{ - \"agents\": [ - { - \"name\" : \"$AGENT_NAME\", - \"host\" : \"localhost\", - \"metrics\" : \"status,newrelic\", - \"user\" : \"root\", - \"passwd\" : \"password\", - \"properties\": \"mysql?socket=$mysql_sock\" - } - ] -}" > ~/newrelic-npi/plugins/com.newrelic.plugins.mysql.instance/newrelic_mysql_plugin-2.0.0/config/plugin.json - -sleep 10 -./npi add-service com.newrelic.plugins.mysql.instance --start -sleep 10 -./npi start com.newrelic.plugins.mysql.instance diff --git a/examples/kubernetes/orchestrator-down.sh b/examples/kubernetes/orchestrator-down.sh deleted file mode 100755 index 7648583d646..00000000000 --- a/examples/kubernetes/orchestrator-down.sh +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/bash - -# Copyright 2019 The Vitess Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# This is an example script that stops orchestrator. - -set -e - -script_root=`dirname "${BASH_SOURCE}"` -source $script_root/env.sh - -echo "Stopping orchestrator replicationcontroller..." -$KUBECTL $KUBECTL_OPTIONS delete replicationcontroller orchestrator - -echo "Deleting orchestrator service..." -$KUBECTL $KUBECTL_OPTIONS delete service orchestrator - -echo "Deleting orchestrator configmap..." -$KUBECTL $KUBECTL_OPTIONS delete configmap orchestrator-conf diff --git a/examples/kubernetes/orchestrator-template.yaml b/examples/kubernetes/orchestrator-template.yaml deleted file mode 100644 index 918aaaafffe..00000000000 --- a/examples/kubernetes/orchestrator-template.yaml +++ /dev/null @@ -1,56 +0,0 @@ -# Orchestrator service -apiVersion: v1 -kind: Service -metadata: - name: orchestrator - labels: - component: orchestrator - app: vitess -spec: - ports: - - port: 80 - targetPort: 3000 - selector: - component: orchestrator - app: vitess ---- -# Orchestrator replication controller -apiVersion: v1 -kind: ReplicationController -metadata: - name: orchestrator -spec: - replicas: 1 - template: - metadata: - labels: - component: orchestrator - app: vitess - spec: - containers: - - name: orchestrator - image: vitess/orchestrator - livenessProbe: - httpGet: - path: / - port: 3000 - initialDelaySeconds: 300 - timeoutSeconds: 30 - resources: - limits: - memory: "512Mi" - cpu: "100m" - volumeMounts: - - mountPath: /orc/conf - name: config - - name: mysql - image: vitess/orchestrator - resources: - limits: - memory: "512Mi" - cpu: "100m" - command: ["mysqld"] - volumes: - - name: config - configMap: - name: orchestrator-conf diff --git a/examples/kubernetes/orchestrator-up.sh b/examples/kubernetes/orchestrator-up.sh deleted file mode 100755 index af9544bc12c..00000000000 --- a/examples/kubernetes/orchestrator-up.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/bash - -# Copyright 2019 The Vitess Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# This is an example script that starts orchestrator. - -set -e - -script_root=`dirname "${BASH_SOURCE}"` -source $script_root/env.sh - -echo "Creating orchestrator service, configmap, and replicationcontroller..." -sed_script="" -for var in service_type; do - sed_script+="s,{{$var}},${!var},g;" -done - -# Create configmap from orchestrator docker config file -$KUBECTL $KUBECTL_OPTIONS create configmap orchestrator-conf --from-file="${script_root}/../../docker/orchestrator/orchestrator.conf.json" - -cat orchestrator-template.yaml | sed -e "$sed_script" | $KUBECTL $KUBECTL_OPTIONS create -f - - -echo -echo "To access orchestrator web UI, start kubectl proxy in another terminal:" -echo " kubectl proxy --port=8001" -echo "Then visit http://localhost:8001/api/v1/proxy/namespaces/$VITESS_NAME/services/orchestrator/" diff --git a/examples/kubernetes/sharded-vtworker.sh b/examples/kubernetes/sharded-vtworker.sh deleted file mode 100755 index 782c8e1c0cb..00000000000 --- a/examples/kubernetes/sharded-vtworker.sh +++ /dev/null @@ -1,64 +0,0 @@ -#!/bin/bash - -# Copyright 2019 The Vitess Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# This is an example script that runs vtworker. - -set -e - -script_root=`dirname "${BASH_SOURCE}"` -source $script_root/env.sh - -cell=test -port=15003 -vtworker_command="$*" - -# Expand template variables -sed_script="" -for var in vitess_image cell port vtworker_command; do - sed_script+="s,{{$var}},${!var},g;" -done - -# Instantiate template and send to kubectl. -echo "Creating vtworker pod in cell $cell..." -cat vtworker-pod-template.yaml | sed -e "$sed_script" | $KUBECTL $KUBECTL_OPTIONS create -f - - -set +e - -# Wait for vtworker pod to show up. -until [ $($KUBECTL $KUBECTL_OPTIONS get pod -o template --template '{{.status.phase}}' vtworker 2> /dev/null) = "Running" ]; do - echo "Waiting for vtworker pod to be created..." - sleep 1 -done - -echo "Following vtworker logs until termination..." -$KUBECTL $KUBECTL_OPTIONS logs -f vtworker - -# Get vtworker exit code. Wait for complete shutdown. -# (Although logs -f exited, the pod isn't fully shutdown yet and the exit code is not available yet.) -until [ $($KUBECTL $KUBECTL_OPTIONS get pod -o template --template '{{.status.phase}}' vtworker 2> /dev/null) != "Running" ]; do - echo "Waiting for vtworker pod to shutdown completely..." - sleep 1 -done -exit_code=$($KUBECTL $KUBECTL_OPTIONS get -o template --template '{{(index .status.containerStatuses 0).state.terminated.exitCode}}' pods vtworker) - -echo "Deleting vtworker pod..." -$KUBECTL $KUBECTL_OPTIONS delete pod vtworker - -if [ "$exit_code" != "0" ]; then - echo - echo "ERROR: vtworker did not run successfully (return value: $exit_code). Please check the error log above and try to run it again." - exit 1 -fi diff --git a/examples/kubernetes/vitess-down.sh b/examples/kubernetes/vitess-down.sh deleted file mode 100755 index 5e26c931234..00000000000 --- a/examples/kubernetes/vitess-down.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/bash - -# Copyright 2019 The Vitess Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -SHARDS=${SHARDS:-'-80,80-'} -TABLETS_PER_SHARD=${TABLETS_PER_SHARD:-3} -CELLS=${CELLS:-'test'} -TEST_MODE=${TEST_MODE:-'0'} -VITESS_NAME=${VITESS_NAME:-'vitess'} - -export VITESS_NAME=$VITESS_NAME - -./vtgate-down.sh -SHARDS=$SHARDS CELLS=$CELLS TABLETS_PER_SHARD=$TABLETS_PER_SHARD ./vttablet-down.sh -./vtctld-down.sh -./etcd-down.sh - -if [ $TEST_MODE -gt 0 ]; then - gcloud compute firewall-rules delete ${VITESS_NAME}-vtctld -q -fi - -for cell in `echo $CELLS | tr ',' ' '`; do - gcloud compute firewall-rules delete ${VITESS_NAME}-vtgate-$cell -q -done - -./namespace-down.sh diff --git a/examples/kubernetes/vitess-up.sh b/examples/kubernetes/vitess-up.sh deleted file mode 100755 index 58db653fc8b..00000000000 --- a/examples/kubernetes/vitess-up.sh +++ /dev/null @@ -1,236 +0,0 @@ -#!/bin/bash - -# Copyright 2019 The Vitess Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# This is an example script that creates a fully functional vitess cluster. -# It performs the following steps: -# 1. Create etcd clusters -# 2. Create vtctld clusters -# 3. Forward vtctld port -# 4. Create vttablet clusters -# 5. Perform vtctl initialization: -# SetKeyspaceShardingInfo, Rebuild Keyspace, Reparent Shard, Apply Schema -# 6. Create vtgate clusters -# 7. Forward vtgate port - -# Customizable parameters -VITESS_NAME=${VITESS_NAME:-'vitess'} -SHARDS=${SHARDS:-'-80,80-'} -TABLETS_PER_SHARD=${TABLETS_PER_SHARD:-3} -RDONLY_COUNT=${RDONLY_COUNT:-0} -MAX_TASK_WAIT_RETRIES=${MAX_TASK_WAIT_RETRIES:-300} -MAX_VTTABLET_TOPO_WAIT_RETRIES=${MAX_VTTABLET_TOPO_WAIT_RETRIES:-180} -VTTABLET_TEMPLATE=${VTTABLET_TEMPLATE:-'vttablet-pod-benchmarking-template.yaml'} -VTGATE_TEMPLATE=${VTGATE_TEMPLATE:-'vtgate-controller-benchmarking-template.yaml'} -VTGATE_COUNT=${VTGATE_COUNT:-0} -VTDATAROOT_VOLUME=${VTDATAROOT_VOLUME:-''} -CELLS=${CELLS:-'test'} -KEYSPACE=${KEYSPACE:-'test_keyspace'} -TEST_MODE=${TEST_MODE:-'0'} - -cells=`echo $CELLS | tr ',' ' '` -num_cells=`echo $cells | wc -w` - -num_shards=`echo $SHARDS | tr "," " " | wc -w` -total_tablet_count=$(($num_shards*$TABLETS_PER_SHARD*$num_cells)) -vtgate_count=$VTGATE_COUNT -if [ $vtgate_count -eq 0 ]; then - vtgate_count=$(($total_tablet_count/$num_cells/4>3?$total_tablet_count/$num_cells/4:3)) -fi - -VTCTLD_SERVICE_TYPE=`[[ $TEST_MODE -gt 0 ]] && echo 'LoadBalancer' || echo 'ClusterIP'` - -# export for other scripts -export SHARDS=$SHARDS -export TABLETS_PER_SHARD=$TABLETS_PER_SHARD -export RDONLY_COUNT=$RDONLY_COUNT -export VTDATAROOT_VOLUME=$VTDATAROOT_VOLUME -export VTGATE_TEMPLATE=$VTGATE_TEMPLATE -export VTTABLET_TEMPLATE=$VTTABLET_TEMPLATE -export VTGATE_REPLICAS=$vtgate_count -export VTCTLD_SERVICE_TYPE=$VTCTLD_SERVICE_TYPE -export VITESS_NAME=$VITESS_NAME - -function update_spinner_value () { - spinner='-\|/' - cur_spinner=${spinner:$(($1%${#spinner})):1} -} - -function wait_for_running_tasks () { - # This function waits for pods to be in the "Running" state - # 1. task_name: Name that the desired task begins with - # 2. num_tasks: Number of tasks to wait for - # Returns: - # 0 if successful, -1 if timed out - task_name=$1 - num_tasks=$2 - counter=0 - - echo "Waiting for ${num_tasks}x $task_name to enter state Running" - - while [ $counter -lt $MAX_TASK_WAIT_RETRIES ]; do - # Get status column of pods with name starting with $task_name, - # count how many are in state Running - num_running=`$KUBECTL get pods --namespace=$VITESS_NAME | grep ^$task_name | grep Running | wc -l` - - echo -en "\r$task_name: $num_running out of $num_tasks in state Running..." - if [ $num_running -eq $num_tasks ] - then - echo Complete - return 0 - fi - update_spinner_value $counter - echo -n $cur_spinner - let counter=counter+1 - sleep 1 - done - echo Timed out - return -1 -} - -if [ -z "$GOPATH" ]; then - echo "ERROR: GOPATH undefined, can't obtain vtctlclient" - exit -1 -fi - -export KUBECTL='kubectl' -go get vitess.io/vitess/go/cmd/vtctlclient - -echo "****************************" -echo "*Creating vitess cluster: $VITESS_NAME" -echo "* Shards: $SHARDS" -echo "* Tablets per shard: $TABLETS_PER_SHARD" -echo "* Rdonly per shard: $RDONLY_COUNT" -echo "* VTGate count: $vtgate_count" -echo "* Cells: $cells" -echo "****************************" - -echo 'Running namespace-up.sh' && ./namespace-up.sh - -echo 'Running etcd-up.sh' && CELLS=$CELLS ./etcd-up.sh -wait_for_running_tasks etcd-global 3 -for cell in $cells; do - wait_for_running_tasks etcd-$cell 3 -done - -echo 'Running vtctld-up.sh' && TEST_MODE=$TEST_MODE ./vtctld-up.sh - -wait_for_running_tasks vtctld 1 -kvtctl="./kvtctl.sh" - -if [ $num_shards -gt 0 ] -then - echo Calling CreateKeyspace and SetKeyspaceShardingInfo - $kvtctl CreateKeyspace -force $KEYSPACE - $kvtctl SetKeyspaceShardingInfo -force $KEYSPACE keyspace_id uint64 -fi - -echo 'Running vttablet-up.sh' && CELLS=$CELLS ./vttablet-up.sh -echo 'Running vtgate-up.sh' && ./vtgate-up.sh -wait_for_running_tasks vttablet $total_tablet_count -wait_for_running_tasks vtgate $(($vtgate_count*$num_cells)) - - -echo Waiting for tablets to be visible in the topology -counter=0 -while [ $counter -lt $MAX_VTTABLET_TOPO_WAIT_RETRIES ]; do - num_tablets=0 - for cell in $cells; do - num_tablets=$(($num_tablets+`$kvtctl ListAllTablets $cell | grep $KEYSPACE | wc -l`)) - done - echo -en "\r$num_tablets out of $total_tablet_count in topology..." - if [ $num_tablets -eq $total_tablet_count ] - then - echo Complete - break - fi - update_spinner_value $counter - echo -n $cur_spinner - let counter=counter+1 - sleep 1 - if [ $counter -eq $MAX_VTTABLET_TOPO_WAIT_RETRIES ] - then - echo Timed out - fi -done - -echo -n Setting Keyspace Sharding Info... -$kvtctl SetKeyspaceShardingInfo -force $KEYSPACE keyspace_id uint64 -echo Done -echo -n Rebuilding Keyspace Graph... -$kvtctl RebuildKeyspaceGraph $KEYSPACE -echo Done -echo -n Reparenting... -shard_num=1 -master_cell=`echo $cells | awk '{print $1}'` -for shard in $(echo $SHARDS | tr "," " "); do - [[ $num_cells -gt 1 ]] && cell_id=01 || cell_id=00 - printf -v master_tablet_id '%s-%02d0000%02d00' $master_cell $cell_id $shard_num - $kvtctl InitShardMaster -force $KEYSPACE/$shard $master_tablet_id - let shard_num=shard_num+1 -done -echo Done -echo -n Applying Schema... -$kvtctl ApplySchema -sql "$(cat create_test_table.sql)" $KEYSPACE -echo Done - -if [ $TEST_MODE -gt 0 ]; then - echo Creating firewall rule for vtctld - vtctld_port=15000 - gcloud compute firewall-rules create ${VITESS_NAME}-vtctld --allow tcp:$vtctld_port - vtctld_ip='' - until [ $vtctld_ip ]; do - vtctld_ip=`$KUBECTL get -o template --template '{{if ge (len .status.loadBalancer) 1}}{{index (index .status.loadBalancer.ingress 0) "ip"}}{{end}}' service vtctld --namespace=$VITESS_NAME` - sleep 1 - done - vtctld_server="$vtctld_ip:$vtctld_port" -fi - -vtgate_servers='' -for cell in $cells; do - echo Creating firewall rule for vtgate in cell $cell - vtgate_port=15001 - gcloud compute firewall-rules create ${VITESS_NAME}-vtgate-$cell --allow tcp:$vtgate_port - vtgate_ip='' - until [ $vtgate_ip ]; do - vtgate_ip=`$KUBECTL get -o template --template '{{if ge (len .status.loadBalancer) 1}}{{index (index .status.loadBalancer.ingress 0) "ip"}}{{end}}' service vtgate-$cell --namespace=$VITESS_NAME` - sleep 1 - done - vtgate_servers+="vtgate-$cell: $vtgate_ip:$vtgate_port," -done - -if [ -n "$NEWRELIC_LICENSE_KEY" ]; then - echo Setting up Newrelic monitoring - i=1 - for nodename in `$KUBECTL get nodes --no-headers --namespace=$VITESS_NAME | awk '{print $1}'`; do - gcloud compute copy-files newrelic.sh $nodename:~/ - gcloud compute copy-files newrelic_start_agent.sh $nodename:~/ - gcloud compute copy-files newrelic_start_mysql_plugin.sh $nodename:~/ - gcloud compute ssh $nodename --command "bash -c '~/newrelic.sh ${NEWRELIC_LICENSE_KEY} ${VTDATAROOT}'" - let i=i+1 - done -fi - -echo "****************************" -echo "* Complete!" -if [ $TEST_MODE -gt 0 ]; then - echo "* vtctld: $vtctld_server" -else - echo "* Access the vtctld web UI by performing the following steps:" - echo "* $ kubectl proxy --port=8001" - echo "* Visit http://localhost:8001/api/v1/proxy/namespaces/default/services/vtctld:web/" -fi -echo $vtgate_servers | awk -F',' '{for(i=1;i- - mkdir -p $VTDATAROOT/tmp && - chown -R vitess /vt && - su -p -c "/vt/bin/vtctld - -cell {{cell}} - -workflow_manager_init - -workflow_manager_use_election - -log_dir $VTDATAROOT/tmp - -alsologtostderr - -port 15000 - -grpc_port 15999 - -service_map 'grpc-vtctl' - -topo_implementation etcd2 - -topo_global_server_address http://etcd-global-client:2379 - -topo_global_root /global - {{backup_flags}} {{test_flags}}" vitess - volumes: - - name: syslog - hostPath: {path: /dev/log} - - name: vtdataroot - emptyDir: {} - - name: certs - # Uncomment one of the following lines to configure the location - # of the root certificates file on your host OS. We need this so - # we can import it into the container OS. - # If your host OS is Fedora/RHEL: - #hostPath: {path: /etc/pki/tls/certs/ca-bundle.crt} - # If your host OS is Debian/Ubuntu/Gentoo: - hostPath: {path: /etc/ssl/certs/ca-certificates.crt} diff --git a/examples/kubernetes/vtctld-down.sh b/examples/kubernetes/vtctld-down.sh deleted file mode 100755 index a48e803aaf2..00000000000 --- a/examples/kubernetes/vtctld-down.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/bash - -# Copyright 2019 The Vitess Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# This is an example script that stops vtctld. - -set -e - -script_root=`dirname "${BASH_SOURCE}"` -source $script_root/env.sh - -echo "Stopping vtctld replicationcontroller..." -$KUBECTL $KUBECTL_OPTIONS delete replicationcontroller vtctld - -echo "Deleting vtctld service..." -$KUBECTL $KUBECTL_OPTIONS delete service vtctld diff --git a/examples/kubernetes/vtctld-service-template.yaml b/examples/kubernetes/vtctld-service-template.yaml deleted file mode 100644 index 59327cb7d1a..00000000000 --- a/examples/kubernetes/vtctld-service-template.yaml +++ /dev/null @@ -1,17 +0,0 @@ -kind: Service -apiVersion: v1 -metadata: - name: vtctld - labels: - component: vtctld - app: vitess -spec: - ports: - - name: web - port: 15000 - - name: grpc - port: 15999 - selector: - component: vtctld - app: vitess - type: {{service_type}} diff --git a/examples/kubernetes/vtctld-up.sh b/examples/kubernetes/vtctld-up.sh deleted file mode 100755 index 1e65c6f587d..00000000000 --- a/examples/kubernetes/vtctld-up.sh +++ /dev/null @@ -1,50 +0,0 @@ -#!/bin/bash - -# Copyright 2019 The Vitess Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# This is an example script that starts vtctld. - -set -e - -script_root=`dirname "${BASH_SOURCE}"` -source $script_root/env.sh - -service_type=${VTCTLD_SERVICE_TYPE:-'ClusterIP'} -cell=(`echo $CELLS | tr ',' ' '`) # ref to cell will get first element -TEST_MODE=${TEST_MODE:-'0'} - -test_flags=`[[ $TEST_MODE -gt 0 ]] && echo '-enable_queries' || echo ''` - -echo "Creating vtctld $service_type service..." -sed_script="" -for var in service_type; do - sed_script+="s,{{$var}},${!var},g;" -done -cat vtctld-service-template.yaml | sed -e "$sed_script" | $KUBECTL $KUBECTL_OPTIONS create -f - - -echo "Creating vtctld replicationcontroller..." -# Expand template variables -sed_script="" -for var in vitess_image backup_flags test_flags cell; do - sed_script+="s,{{$var}},${!var},g;" -done - -# Instantiate template and send to kubectl. -cat vtctld-controller-template.yaml | sed -e "$sed_script" | $KUBECTL $KUBECTL_OPTIONS create -f - - -echo -echo "To access vtctld web UI, start kubectl proxy in another terminal:" -echo " kubectl proxy --port=8001" -echo "Then visit http://localhost:8001/api/v1/namespaces/$VITESS_NAME/services/vtctld:web/proxy" \ No newline at end of file diff --git a/examples/kubernetes/vtgate-controller-benchmarking-template.yaml b/examples/kubernetes/vtgate-controller-benchmarking-template.yaml deleted file mode 100644 index a5db7c585e8..00000000000 --- a/examples/kubernetes/vtgate-controller-benchmarking-template.yaml +++ /dev/null @@ -1,58 +0,0 @@ -kind: ReplicationController -apiVersion: v1 -metadata: - name: vtgate-{{cell}} -spec: - replicas: {{replicas}} - template: - metadata: - labels: - component: vtgate - cell: {{cell}} - app: vitess - spec: - containers: - - name: vtgate - image: vitess/root - livenessProbe: - httpGet: - path: /debug/vars - port: 15001 - initialDelaySeconds: 30 - timeoutSeconds: 5 - volumeMounts: - - name: syslog - mountPath: /dev/log - - name: vtdataroot - mountPath: /vt/vtdataroot - resources: - limits: - memory: "4Gi" - cpu: "6" - command: - - sh - - "-c" - - >- - mkdir -p $VTDATAROOT/tmp && - chown -R vitess /vt && - su -p -c "/vt/bin/vtgate - -topo_implementation etcd2 - -topo_global_server_address http://etcd-global-client:2379 - -topo_global_root /global - -log_dir $VTDATAROOT/tmp - -alsologtostderr - -port 15001 - -grpc_port 15991 - -service_map 'grpc-vtgateservice' - -cells_to_watch {{cell}} - -tablet_types_to_wait MASTER,REPLICA - -gateway_implementation discoverygateway - -cell {{cell}}" vitess - env: - - name: GOMAXPROCS - value: "16" - volumes: - - name: syslog - hostPath: {path: /dev/log} - - name: vtdataroot - {{vtdataroot_volume}} diff --git a/examples/kubernetes/vtgate-controller-template.yaml b/examples/kubernetes/vtgate-controller-template.yaml deleted file mode 100644 index bbaac915b98..00000000000 --- a/examples/kubernetes/vtgate-controller-template.yaml +++ /dev/null @@ -1,58 +0,0 @@ -kind: ReplicationController -apiVersion: v1 -metadata: - name: vtgate-{{cell}} -spec: - replicas: {{replicas}} - template: - metadata: - labels: - component: vtgate - cell: {{cell}} - app: vitess - spec: - containers: - - name: vtgate - image: {{vitess_image}} - livenessProbe: - httpGet: - path: /debug/vars - port: 15001 - initialDelaySeconds: 30 - timeoutSeconds: 5 - volumeMounts: - - name: syslog - mountPath: /dev/log - - name: vtdataroot - mountPath: /vt/vtdataroot - resources: - limits: - memory: "512Mi" - cpu: "500m" - command: - - sh - - "-c" - - >- - mkdir -p $VTDATAROOT/tmp && - chown -R vitess /vt && - su -p -c "/vt/bin/vtgate - -topo_implementation etcd2 - -topo_global_server_address http://etcd-global-client:2379 - -topo_global_root /global - -log_dir $VTDATAROOT/tmp - -alsologtostderr - -port 15001 - -grpc_port 15991 - -mysql_server_port {{mysql_server_port}} - -mysql_auth_server_static_string '{\"mysql_user\":{\"Password\":\"mysql_password\"}}' - -service_map 'grpc-vtgateservice' - -cells_to_watch {{cell}} - -tablet_types_to_wait MASTER,REPLICA - -gateway_implementation discoverygateway - -cell {{cell}}" vitess - volumes: - - name: syslog - hostPath: {path: /dev/log} - - name: vtdataroot - emptyDir: {} - diff --git a/examples/kubernetes/vtgate-service-template.yaml b/examples/kubernetes/vtgate-service-template.yaml deleted file mode 100644 index 8a9f7450c99..00000000000 --- a/examples/kubernetes/vtgate-service-template.yaml +++ /dev/null @@ -1,21 +0,0 @@ -kind: Service -apiVersion: v1 -metadata: - name: vtgate-{{cell}} - labels: - component: vtgate - cell: {{cell}} - app: vitess -spec: - ports: - - name: web - port: 15001 - - name: grpc - port: 15991 - - name: mysql - port: {{mysql_server_port}} - selector: - component: vtgate - cell: {{cell}} - app: vitess - type: LoadBalancer diff --git a/examples/kubernetes/vtgate-up.sh b/examples/kubernetes/vtgate-up.sh deleted file mode 100755 index 66ef0667024..00000000000 --- a/examples/kubernetes/vtgate-up.sh +++ /dev/null @@ -1,57 +0,0 @@ -#!/bin/bash - -# Copyright 2019 The Vitess Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# This is an example script that starts a vtgate replicationcontroller. - -set -e - -script_root=`dirname "${BASH_SOURCE}"` -source $script_root/env.sh - -# NOTE: mysql server support is currently in beta -mysql_server_port=${MYSQL_SERVER_PORT:-3306} - -VTGATE_REPLICAS=${VTGATE_REPLICAS:-3} -VTDATAROOT_VOLUME=${VTDATAROOT_VOLUME:-''} -VTGATE_TEMPLATE=${VTGATE_TEMPLATE:-'vtgate-controller-template.yaml'} - -vtdataroot_volume='emptyDir: {}' -if [ -n "$VTDATAROOT_VOLUME" ]; then - vtdataroot_volume="hostPath: {path: ${VTDATAROOT_VOLUME}}" -fi - -replicas=$VTGATE_REPLICAS - -cells=`echo $CELLS | tr ',' ' '` -for cell in $cells; do - sed_script="" - for var in cell; do - sed_script+="s,{{$var}},${!var},g;" - done - - sed_script+="s,{{mysql_server_port}},$mysql_server_port,g;" - - echo "Creating vtgate service in cell $cell..." - cat vtgate-service-template.yaml | sed -e "$sed_script" | $KUBECTL $KUBECTL_OPTIONS create -f - - - sed_script="" - for var in vitess_image replicas vtdataroot_volume cell mysql_server_port; do - sed_script+="s,{{$var}},${!var},g;" - done - - echo "Creating vtgate replicationcontroller in cell $cell..." - cat $VTGATE_TEMPLATE | sed -e "$sed_script" | $KUBECTL $KUBECTL_OPTIONS create -f - -done diff --git a/examples/kubernetes/vttablet-down.sh b/examples/kubernetes/vttablet-down.sh deleted file mode 100755 index e3fe9a67b03..00000000000 --- a/examples/kubernetes/vttablet-down.sh +++ /dev/null @@ -1,54 +0,0 @@ -#!/bin/bash - -# Copyright 2019 The Vitess Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# This is an example script that tears down the vttablet pods started by -# vttablet-up.sh. - -set -e - -script_root=`dirname "${BASH_SOURCE}"` -source $script_root/env.sh - -echo "Starting port forwarding to vtctld..." -start_vtctld_forward -trap stop_vtctld_forward EXIT -VTCTLD_ADDR="localhost:$vtctld_forward_port" - -# Delete the pods for all shards -keyspace='test_keyspace' -SHARDS=${SHARDS:-'0'} -TABLETS_PER_SHARD=${TABLETS_PER_SHARD:-5} -UID_BASE=${UID_BASE:-100} - -num_shards=`echo $SHARDS | tr "," " " | wc -w` -uid_base=$UID_BASE -cells=`echo $CELLS | tr ',' ' '` -num_cells=`echo $cells | wc -w` - -for shard in `seq 1 $num_shards`; do - [[ $num_cells -gt 1 ]] && cell_index=100000000 || cell_index=0 - for cell in $cells; do - for uid_index in `seq 0 $(($TABLETS_PER_SHARD-1))`; do - uid=$[$uid_base + $uid_index + $cell_index] - printf -v alias '%s-%010d' $cell $uid - - echo "Deleting pod for tablet $alias..." - $KUBECTL $KUBECTL_OPTIONS delete pod vttablet-$uid - done - let cell_index=cell_index+100000000 - done - let uid_base=uid_base+100 -done diff --git a/examples/kubernetes/vttablet-pod-benchmarking-template.yaml b/examples/kubernetes/vttablet-pod-benchmarking-template.yaml deleted file mode 100644 index f1cc59e7101..00000000000 --- a/examples/kubernetes/vttablet-pod-benchmarking-template.yaml +++ /dev/null @@ -1,95 +0,0 @@ -kind: Pod -apiVersion: v1 -metadata: - name: vttablet-{{uid}} - labels: - component: vttablet - keyspace: "{{keyspace}}" - shard: "{{shard_label}}" - tablet: "{{alias}}" - app: vitess -spec: - containers: - - name: vttablet - image: vitess/root - resources: - limits: - memory: "4Gi" - cpu: "2" - volumeMounts: - - name: syslog - mountPath: /dev/log - - name: vtdataroot - mountPath: /vt/vtdataroot - command: - - bash - - "-c" - - >- - set -e - - mysql_socket="$VTDATAROOT/{{tablet_subdir}}/mysql.sock" - - mkdir -p $VTDATAROOT/tmp - - chown -R vitess /vt - - while [ ! -e $mysql_socket ]; do - echo "[$(date)] waiting for $mysql_socket" ; - sleep 1 ; - done - - su -p -s /bin/bash -c "mysql -u vt_dba -S $mysql_socket - -e 'CREATE DATABASE IF NOT EXISTS vt_{{keyspace}}'" vitess - - su -p -s /bin/bash -c "/vt/bin/vttablet - -topo_implementation etcd2 - -topo_global_server_address http://etcd-global-client:2379 - -topo_global_root /global - -log_dir $VTDATAROOT/tmp - -alsologtostderr - -port {{port}} - -grpc_port {{grpc_port}} - -service_map 'grpc-queryservice,grpc-tabletmanager,grpc-updatestream' - -tablet-path {{alias}} - -tablet_hostname $(hostname -i) - -init_keyspace {{keyspace}} - -init_shard {{shard}} - -init_tablet_type {{tablet_type}} - -mysqlctl_socket $VTDATAROOT/mysqlctl.sock - -queryserver-config-transaction-cap 300 - -queryserver-config-schema-reload-time 1 - -queryserver-config-pool-size 100 - -enable_replication_reporter" vitess - env: - - name: GOMAXPROCS - value: "16" - - name: mysql - image: vitess/root - resources: - limits: - memory: "4Gi" - cpu: "2" - volumeMounts: - - name: syslog - mountPath: /dev/log - - name: vtdataroot - mountPath: /vt/vtdataroot - command: - - sh - - "-c" - - >- - mkdir -p $VTDATAROOT/tmp && - chown -R vitess /vt - - su -p -c "/vt/bin/mysqlctld - -log_dir $VTDATAROOT/tmp - -alsologtostderr - -tablet_uid {{uid}} - -socket_file $VTDATAROOT/mysqlctl.sock - -init_db_sql_file $VTROOT/config/init_db.sql" vitess - volumes: - - name: syslog - hostPath: {path: /dev/log} - - name: vtdataroot - {{vtdataroot_volume}} - diff --git a/examples/kubernetes/vttablet-pod-template.yaml b/examples/kubernetes/vttablet-pod-template.yaml deleted file mode 100644 index 6be80409cae..00000000000 --- a/examples/kubernetes/vttablet-pod-template.yaml +++ /dev/null @@ -1,109 +0,0 @@ -kind: Pod -apiVersion: v1 -metadata: - name: vttablet-{{uid}} - labels: - component: vttablet - keyspace: "{{keyspace}}" - shard: "{{shard_label}}" - tablet: "{{alias}}" - app: vitess -spec: - containers: - - name: vttablet - image: {{vitess_image}} - livenessProbe: - httpGet: - path: /debug/vars - port: {{port}} - initialDelaySeconds: 60 - timeoutSeconds: 10 - volumeMounts: - - name: syslog - mountPath: /dev/log - - name: vtdataroot - mountPath: /vt/vtdataroot - - name: certs - readOnly: true - # Mount root certs from the host OS into the location - # expected for our container OS (Debian): - mountPath: /etc/ssl/certs/ca-certificates.crt - resources: - limits: - memory: "1Gi" - cpu: "500m" - ports: - - name: web - containerPort: {{port}} - - name: grpc - containerPort: {{grpc_port}} - command: - - bash - - "-c" - - >- - set -e - - mkdir -p $VTDATAROOT/tmp - - chown -R vitess /vt - - su -p -s /bin/bash -c "/vt/bin/vttablet - -binlog_use_v3_resharding_mode - -topo_implementation etcd2 - -topo_global_server_address http://etcd-global-client:2379 - -topo_global_root /global - -log_dir $VTDATAROOT/tmp - -alsologtostderr - -port {{port}} - -grpc_port {{grpc_port}} - -service_map 'grpc-queryservice,grpc-tabletmanager,grpc-updatestream' - -tablet-path {{alias}} - -tablet_hostname $(hostname -i) - -init_keyspace {{keyspace}} - -init_shard {{shard}} - -init_tablet_type {{tablet_type}} - -health_check_interval 5s - -mysqlctl_socket $VTDATAROOT/mysqlctl.sock - -enable_semi_sync - -enable_replication_reporter - -orc_api_url http://orchestrator/api - -orc_discover_interval 5m - -restore_from_backup {{backup_flags}}" vitess - - name: mysql - image: {{vitess_image}} - volumeMounts: - - name: syslog - mountPath: /dev/log - - name: vtdataroot - mountPath: /vt/vtdataroot - resources: - limits: - memory: "1Gi" - cpu: "500m" - command: - - sh - - "-c" - - >- - mkdir -p $VTDATAROOT/tmp && - chown -R vitess /vt - - su -p -c "/vt/bin/mysqlctld - -log_dir $VTDATAROOT/tmp - -alsologtostderr - -tablet_uid {{uid}} - -socket_file $VTDATAROOT/mysqlctl.sock - -init_db_sql_file $VTROOT/config/init_db.sql" vitess - volumes: - - name: syslog - hostPath: {path: /dev/log} - - name: vtdataroot - {{vtdataroot_volume}} - - name: certs - # Uncomment one of the following lines to configure the location - # of the root certificates file on your host OS. We need this so - # we can import it into the container OS. - # If your host OS is Fedora/RHEL: - #hostPath: {path: /etc/pki/tls/certs/ca-bundle.crt} - # If your host OS is Debian/Ubuntu/Gentoo: - hostPath: {path: /etc/ssl/certs/ca-certificates.crt} - diff --git a/examples/kubernetes/vttablet-up.sh b/examples/kubernetes/vttablet-up.sh deleted file mode 100755 index 8fbdcfc5ff3..00000000000 --- a/examples/kubernetes/vttablet-up.sh +++ /dev/null @@ -1,77 +0,0 @@ -#!/bin/bash - -# Copyright 2019 The Vitess Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# This is an example script that creates a vttablet deployment. - -set -e - -script_root=`dirname "${BASH_SOURCE}"` -source $script_root/env.sh - -# Create the pods for shard-0 -keyspace=${KEYSPACE:-'test_keyspace'} -SHARDS=${SHARDS:-'0'} -TABLETS_PER_SHARD=${TABLETS_PER_SHARD:-5} -port=15002 -grpc_port=16002 -UID_BASE=${UID_BASE:-100} -VTTABLET_TEMPLATE=${VTTABLET_TEMPLATE:-'vttablet-pod-template.yaml'} -VTDATAROOT_VOLUME=${VTDATAROOT_VOLUME:-''} -RDONLY_COUNT=${RDONLY_COUNT:-2} - -vtdataroot_volume='emptyDir: {}' -if [ -n "$VTDATAROOT_VOLUME" ]; then - vtdataroot_volume="hostPath: {path: ${VTDATAROOT_VOLUME}}" -fi - -uid_base=$UID_BASE -indices=${TASKS:-`seq 0 $(($TABLETS_PER_SHARD-1))`} -cells=`echo $CELLS | tr ',' ' '` -num_cells=`echo $cells | wc -w` - -for shard in $(echo $SHARDS | tr "," " "); do - [[ $num_cells -gt 1 ]] && cell_index=100000000 || cell_index=0 - for cell in $cells; do - echo "Creating $keyspace.shard-$shard pods in cell $cell..." - for uid_index in $indices; do - uid=$[$uid_base + $uid_index + $cell_index] - printf -v alias '%s-%010d' $cell $uid - printf -v tablet_subdir 'vt_%010d' $uid - - echo "Creating pod for tablet $alias..." - - # Add xx to beginning or end if there is a dash. K8s does not allow for - # leading or trailing dashes for labels - shard_label=`echo $shard | sed s'/[-]$/-xx/' | sed s'/^-/xx-/'` - - tablet_type=replica - if [ $uid_index -gt $(($TABLETS_PER_SHARD-$RDONLY_COUNT-1)) ]; then - tablet_type=rdonly - fi - - # Expand template variables - sed_script="" - for var in vitess_image alias cell uid keyspace shard shard_label port grpc_port tablet_subdir vtdataroot_volume tablet_type backup_flags; do - sed_script+="s,{{$var}},${!var},g;" - done - - # Instantiate template and send to kubectl. - cat $VTTABLET_TEMPLATE | sed -e "$sed_script" | $KUBECTL $KUBECTL_OPTIONS create -f - - done - let cell_index=cell_index+100000000 - done - let uid_base=uid_base+100 -done diff --git a/examples/kubernetes/vtworker-controller-interactive-template.yaml b/examples/kubernetes/vtworker-controller-interactive-template.yaml deleted file mode 100644 index b3f86ae191e..00000000000 --- a/examples/kubernetes/vtworker-controller-interactive-template.yaml +++ /dev/null @@ -1,42 +0,0 @@ -kind: ReplicationController -apiVersion: v1 -metadata: - name: vtworker -spec: - replicas: 1 - template: - metadata: - labels: - component: vtworker - app: vitess - spec: - containers: - - name: vtworker - image: {{vitess_image}} - volumeMounts: - - name: syslog - mountPath: /dev/log - - name: vtdataroot - mountPath: /vt/vtdataroot - command: - - sh - - "-c" - - >- - mkdir -p $VTDATAROOT/tmp && - chown -R vitess /vt && - su -p -c "/vt/bin/vtworker - -log_dir $VTDATAROOT/tmp - -alsologtostderr - -port {{port}} - -grpc_port {{grpc_port}} - -service_map \"grpc-vtworker\" - -topo_implementation etcd2 - -topo_global_server_address http://etcd-global-client:2379 - -topo_global_root /global - -cell {{cell}} - -use_v3_resharding_mode" vitess - volumes: - - name: syslog - hostPath: {path: /dev/log} - - name: vtdataroot - emptyDir: {} diff --git a/examples/kubernetes/vtworker-down.sh b/examples/kubernetes/vtworker-down.sh deleted file mode 100755 index d1ab7330b49..00000000000 --- a/examples/kubernetes/vtworker-down.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/bash - -# Copyright 2019 The Vitess Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# This is an example script that stops vtworker. - -script_root=`dirname "${BASH_SOURCE}"` -source $script_root/env.sh - -echo "Stopping vtworker replicationcontroller..." -$KUBECTL $KUBECTL_OPTIONS delete replicationcontroller vtworker - -echo "Deleting vtworker service..." -$KUBECTL $KUBECTL_OPTIONS delete service vtworker diff --git a/examples/kubernetes/vtworker-pod-template.yaml b/examples/kubernetes/vtworker-pod-template.yaml deleted file mode 100644 index 08ab4d68d36..00000000000 --- a/examples/kubernetes/vtworker-pod-template.yaml +++ /dev/null @@ -1,39 +0,0 @@ -kind: Pod -apiVersion: v1 -metadata: - name: vtworker - labels: - component: vtworker - app: vitess -spec: - containers: - - name: vtworker - image: {{vitess_image}} - volumeMounts: - - name: syslog - mountPath: /dev/log - - name: vtdataroot - mountPath: /vt/vtdataroot - command: - - sh - - "-c" - - >- - mkdir -p $VTDATAROOT/tmp && - chown -R vitess /vt && - su -p -c "/vt/bin/vtworker - -log_dir $VTDATAROOT/tmp - -alsologtostderr - -port {{port}} - -topo_implementation etcd2 - -topo_global_server_address http://etcd-global-client:2379 - -topo_global_root /global - -cell {{cell}} - -use_v3_resharding_mode - {{vtworker_command}}" vitess - restartPolicy: Never - volumes: - - name: syslog - hostPath: {path: /dev/log} - - name: vtdataroot - emptyDir: {} - diff --git a/examples/kubernetes/vtworker-service-template.yaml b/examples/kubernetes/vtworker-service-template.yaml deleted file mode 100644 index 1fbb7403c44..00000000000 --- a/examples/kubernetes/vtworker-service-template.yaml +++ /dev/null @@ -1,17 +0,0 @@ -kind: Service -apiVersion: v1 -metadata: - name: vtworker - labels: - component: vtworker - app: vitess -spec: - ports: - - name: web - port: {{port}} - - name: grpc - port: {{grpc_port}} - selector: - component: vtworker - app: vitess - type: {{service_type}} diff --git a/examples/kubernetes/vtworker-up.sh b/examples/kubernetes/vtworker-up.sh deleted file mode 100755 index d5cc3e32ccb..00000000000 --- a/examples/kubernetes/vtworker-up.sh +++ /dev/null @@ -1,42 +0,0 @@ -#!/bin/bash - -# Copyright 2019 The Vitess Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -set -e - -script_root=`dirname "${BASH_SOURCE}"` -source $script_root/env.sh - -cell=(`echo $CELLS | tr ',' ' '`) # ref to cell will get first element -port=15032 -grpc_port=15033 - -sed_script="" -for var in vitess_image cell port grpc_port; do - sed_script+="s,{{$var}},${!var},g;" -done - -echo "Creating vtworker pod in cell $cell..." -cat vtworker-controller-interactive-template.yaml | sed -e "$sed_script" | $KUBECTL $KUBECTL_OPTIONS create -f - - -set +e - -service_type='LoadBalancer' -echo "Creating vtworker $service_type service..." -sed_script="" -for var in service_type port grpc_port; do - sed_script+="s,{{$var}},${!var},g;" -done -cat vtworker-service-template.yaml | sed -e "$sed_script" | $KUBECTL $KUBECTL_OPTIONS create -f - diff --git a/examples/legacy_local/101_initial_cluster.sh b/examples/legacy_local/101_initial_cluster.sh new file mode 100755 index 00000000000..4472412e944 --- /dev/null +++ b/examples/legacy_local/101_initial_cluster.sh @@ -0,0 +1,50 @@ +#!/bin/bash + +# Copyright 2019 The Vitess Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# this script brings up zookeeper and all the vitess components +# required for a single shard deployment. + +source ./env.sh + +# start topo server +if [ "${TOPO}" = "zk2" ]; then + CELL=zone1 ./scripts/zk-up.sh +elif [ "${TOPO}" = "k8s" ]; then + CELL=zone1 ./scripts/k3s-up.sh +else + CELL=zone1 ./scripts/etcd-up.sh +fi + +# start vtctld +CELL=zone1 ./scripts/vtctld-up.sh + +# start vttablets for keyspace commerce +for i in 100 101 102; do + CELL=zone1 TABLET_UID=$i ./scripts/mysqlctl-up.sh + CELL=zone1 KEYSPACE=commerce TABLET_UID=$i ./scripts/vttablet-up.sh +done + +# set one of the replicas to master +vtctlclient -server localhost:15999 InitShardMaster -force commerce/0 zone1-100 + +# create the schema +vtctlclient -server localhost:15999 ApplySchema -sql-file create_commerce_schema.sql commerce + +# create the vschema +vtctlclient -server localhost:15999 ApplyVSchema -vschema_file vschema_commerce_initial.json commerce + +# start vtgate +CELL=zone1 ./scripts/vtgate-up.sh diff --git a/examples/local/201_customer_keyspace.sh b/examples/legacy_local/201_customer_keyspace.sh similarity index 84% rename from examples/local/201_customer_keyspace.sh rename to examples/legacy_local/201_customer_keyspace.sh index 72c415e6527..f948175195c 100755 --- a/examples/local/201_customer_keyspace.sh +++ b/examples/legacy_local/201_customer_keyspace.sh @@ -16,8 +16,5 @@ # this script creates a new keyspace in preparation for vertical resharding -set -e +vtctlclient -server localhost:15999 CreateKeyspace -served_from='master:commerce,replica:commerce,rdonly:commerce' customer -./lvtctl.sh CreateKeyspace -served_from='master:commerce,replica:commerce,rdonly:commerce' customer - -disown -a diff --git a/examples/legacy_local/202_customer_tablets.sh b/examples/legacy_local/202_customer_tablets.sh new file mode 100755 index 00000000000..ec77226342f --- /dev/null +++ b/examples/legacy_local/202_customer_tablets.sh @@ -0,0 +1,32 @@ +#!/bin/bash + +# Copyright 2019 The Vitess Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# this script creates the tablets and initializes them for vertical +# resharding it also splits the vschema between the two keyspaces +# old (commerce) and new (customer) + +source ./env.sh + +for i in 200 201 202; do + CELL=zone1 TABLET_UID=$i ./scripts/mysqlctl-up.sh + CELL=zone1 KEYSPACE=customer TABLET_UID=$i ./scripts/vttablet-up.sh +done + +vtctlclient -server localhost:15999 InitShardMaster -force customer/0 zone1-200 +vtctlclient -server localhost:15999 CopySchemaShard -tables customer,corder commerce/0 customer/0 +vtctlclient -server localhost:15999 ApplyVSchema -vschema_file vschema_commerce_vsplit.json commerce +vtctlclient -server localhost:15999 ApplyVSchema -vschema_file vschema_customer_vsplit.json customer + diff --git a/examples/local/203_vertical_split.sh b/examples/legacy_local/203_vertical_split.sh similarity index 82% rename from examples/local/203_vertical_split.sh rename to examples/legacy_local/203_vertical_split.sh index 5429430f052..372c4817a90 100755 --- a/examples/local/203_vertical_split.sh +++ b/examples/legacy_local/203_vertical_split.sh @@ -17,16 +17,8 @@ # this script copies over all the data from commerce keyspace to # customer keyspace for the customer and corder tables -set -e +source ./env.sh -# shellcheck disable=SC2128 -script_root=$(dirname "${BASH_SOURCE}") - -# shellcheck source=./env.sh -# shellcheck disable=SC1091 -source "$script_root/env.sh" - -# shellcheck disable=SC2086 vtworker \ $TOPOLOGY_FLAGS \ -cell zone1 \ @@ -35,4 +27,3 @@ vtworker \ -use_v3_resharding_mode \ VerticalSplitClone -min_healthy_tablets=1 -tables=customer,corder customer/0 -disown -a diff --git a/examples/local/204_vertical_migrate_replicas.sh b/examples/legacy_local/204_vertical_migrate_replicas.sh similarity index 83% rename from examples/local/204_vertical_migrate_replicas.sh rename to examples/legacy_local/204_vertical_migrate_replicas.sh index 1e13f62a4b3..45ada0aaf63 100755 --- a/examples/local/204_vertical_migrate_replicas.sh +++ b/examples/legacy_local/204_vertical_migrate_replicas.sh @@ -17,9 +17,6 @@ # this script migrates traffic for the new customer keyspace to the new # tablets of types rdonly and replica -set -e +vtctlclient -server localhost:15999 MigrateServedFrom customer/0 rdonly +vtctlclient -server localhost:15999 MigrateServedFrom customer/0 replica -./lvtctl.sh MigrateServedFrom customer/0 rdonly -./lvtctl.sh MigrateServedFrom customer/0 replica - -disown -a diff --git a/examples/local/205_vertical_migrate_master.sh b/examples/legacy_local/205_vertical_migrate_master.sh similarity index 90% rename from examples/local/205_vertical_migrate_master.sh rename to examples/legacy_local/205_vertical_migrate_master.sh index 3aebc52a05c..211d27eb6a7 100755 --- a/examples/local/205_vertical_migrate_master.sh +++ b/examples/legacy_local/205_vertical_migrate_master.sh @@ -17,8 +17,4 @@ # this script migrates master traffic for the customer keyspace to the # new master tablet -set -e - -./lvtctl.sh MigrateServedFrom customer/0 master - -disown -a +vtctlclient -server localhost:15999 MigrateServedFrom customer/0 master diff --git a/examples/kubernetes/cluster-down.sh b/examples/legacy_local/206_clean_commerce.sh similarity index 52% rename from examples/kubernetes/cluster-down.sh rename to examples/legacy_local/206_clean_commerce.sh index 33ea5891ae5..7111a4a91fc 100755 --- a/examples/kubernetes/cluster-down.sh +++ b/examples/legacy_local/206_clean_commerce.sh @@ -14,17 +14,10 @@ # See the License for the specific language governing permissions and # limitations under the License. -# Tears down the container engine cluster, removes rules/pools - -GKE_ZONE=${GKE_ZONE:-'us-central1-b'} -GKE_CLUSTER_NAME=${GKE_CLUSTER_NAME:-'example'} - -base_ssd_name="$GKE_CLUSTER_NAME-vt-ssd-" - -gcloud container clusters delete $GKE_CLUSTER_NAME -z $GKE_ZONE -q - -num_ssds=`gcloud compute disks list | awk -v name="$base_ssd_name" -v zone=$GKE_ZONE '$1~name && $2==zone' | wc -l` -for i in `seq 1 $num_ssds`; do - gcloud compute disks delete $base_ssd_name$i --zone $GKE_ZONE -q -done +# this script removes the customer and corder tables from the commerce +# keyspace +vtctlclient -server localhost:15999 ApplySchema -sql-file drop_commerce_tables.sql commerce +vtctlclient -server localhost:15999 SetShardTabletControl -blacklisted_tables=customer,corder -remove commerce/0 rdonly +vtctlclient -server localhost:15999 SetShardTabletControl -blacklisted_tables=customer,corder -remove commerce/0 replica +vtctlclient -server localhost:15999 SetShardTabletControl -blacklisted_tables=customer,corder -remove commerce/0 master diff --git a/examples/legacy_local/301_customer_sharded.sh b/examples/legacy_local/301_customer_sharded.sh new file mode 100755 index 00000000000..5335a0e7392 --- /dev/null +++ b/examples/legacy_local/301_customer_sharded.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +# Copyright 2019 The Vitess Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# this script creates vitess sequences for the auto_increment fields +# and alters the fields to no longer be auto_increment in preparation +# for horizontal sharding +# it also changes the customer vschema from unsharded to sharded and +# sets up the necessary vindexes + +vtctlclient -server localhost:15999 ApplySchema -sql-file create_commerce_seq.sql commerce +vtctlclient -server localhost:15999 ApplyVSchema -vschema_file vschema_commerce_seq.json commerce +vtctlclient -server localhost:15999 ApplySchema -sql-file create_customer_sharded.sql customer +vtctlclient -server localhost:15999 ApplyVSchema -vschema_file vschema_customer_sharded.json customer diff --git a/examples/legacy_local/302_new_shards.sh b/examples/legacy_local/302_new_shards.sh new file mode 100755 index 00000000000..c8830f97d0e --- /dev/null +++ b/examples/legacy_local/302_new_shards.sh @@ -0,0 +1,35 @@ +#!/bin/bash + +# Copyright 2019 The Vitess Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# this script brings up new tablets for the two new shards that we will +# be creating in the customer keyspace and copies the schema + +source ./env.sh + +for i in 300 301 302; do + CELL=zone1 TABLET_UID=$i ./scripts/mysqlctl-up.sh + SHARD=-80 CELL=zone1 KEYSPACE=customer TABLET_UID=$i ./scripts/vttablet-up.sh +done + +for i in 400 401 402; do + CELL=zone1 TABLET_UID=$i ./scripts/mysqlctl-up.sh + SHARD=80- CELL=zone1 KEYSPACE=customer TABLET_UID=$i ./scripts/vttablet-up.sh +done + +vtctlclient -server localhost:15999 InitShardMaster -force customer/-80 zone1-300 +vtctlclient -server localhost:15999 InitShardMaster -force customer/80- zone1-400 +vtctlclient -server localhost:15999 CopySchemaShard customer/0 customer/-80 +vtctlclient -server localhost:15999 CopySchemaShard customer/0 customer/80- diff --git a/examples/local/303_horizontal_split.sh b/examples/legacy_local/303_horizontal_split.sh similarity index 66% rename from examples/local/303_horizontal_split.sh rename to examples/legacy_local/303_horizontal_split.sh index ea1d9285fc4..aaa019559d4 100755 --- a/examples/local/303_horizontal_split.sh +++ b/examples/legacy_local/303_horizontal_split.sh @@ -17,22 +17,12 @@ # this script copies the data from customer/0 to customer/-80 and customer/80- # each row will be copied to exactly one shard based on the vindex value -set -e +source ./env.sh -# shellcheck disable=SC2128 -script_root=$(dirname "${BASH_SOURCE}") - -# shellcheck source=./env.sh -# shellcheck disable=SC1091 -source "${script_root}/env.sh" - -# shellcheck disable=SC2086 vtworker \ - $TOPOLOGY_FLAGS \ - -cell zone1 \ - -log_dir "$VTDATAROOT"/tmp \ - -alsologtostderr \ - -use_v3_resharding_mode \ - SplitClone -min_healthy_rdonly_tablets=1 customer/0 - -disown -a + $TOPOLOGY_FLAGS \ + -cell zone1 \ + -log_dir "$VTDATAROOT"/tmp \ + -alsologtostderr \ + -use_v3_resharding_mode \ + SplitClone -min_healthy_rdonly_tablets=1 customer/0 diff --git a/examples/local/304_migrate_replicas.sh b/examples/legacy_local/304_migrate_replicas.sh similarity index 81% rename from examples/local/304_migrate_replicas.sh rename to examples/legacy_local/304_migrate_replicas.sh index 917d650fdb4..3aed031ebab 100755 --- a/examples/local/304_migrate_replicas.sh +++ b/examples/legacy_local/304_migrate_replicas.sh @@ -16,9 +16,5 @@ # this script migrates traffic for the rdonly and replica tablets -set -e - -./lvtctl.sh MigrateServedTypes customer/0 rdonly -./lvtctl.sh MigrateServedTypes customer/0 replica - -disown -a +vtctlclient -server localhost:15999 MigrateServedTypes customer/0 rdonly +vtctlclient -server localhost:15999 MigrateServedTypes customer/0 replica diff --git a/examples/local/305_migrate_master.sh b/examples/legacy_local/305_migrate_master.sh similarity index 91% rename from examples/local/305_migrate_master.sh rename to examples/legacy_local/305_migrate_master.sh index e5ebed81e77..a9da079ea7c 100755 --- a/examples/local/305_migrate_master.sh +++ b/examples/legacy_local/305_migrate_master.sh @@ -16,9 +16,6 @@ # this script migrates traffic for the master tablet -set -e - -./lvtctl.sh MigrateServedTypes customer/0 master +vtctlclient -server localhost:15999 MigrateServedTypes customer/0 master # data has been copied over to shards, and databases for the new shards are now available -disown -a diff --git a/examples/kubernetes/sharded-vttablet-up.sh b/examples/legacy_local/306_down_shard_0.sh similarity index 75% rename from examples/kubernetes/sharded-vttablet-up.sh rename to examples/legacy_local/306_down_shard_0.sh index 507abfd37bb..25c23ab2111 100755 --- a/examples/kubernetes/sharded-vttablet-up.sh +++ b/examples/legacy_local/306_down_shard_0.sh @@ -13,11 +13,10 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +# this script brings down the tablets for customer/0 keyspace -# This is an example script that uses vttablet-up.sh with extra params -# to create a vttablet deployment with 2 shards. +for i in 200 201 202; do + CELL=zone1 TABLET_UID=$i ./scripts/vttablet-down.sh + CELL=zone1 TABLET_UID=$i ./scripts/mysqlctl-down.sh +done -SHARDS='-80,80-' -UID_BASE=200 - -source ./vttablet-up.sh diff --git a/examples/local/vtworker-down.sh b/examples/legacy_local/307_delete_shard_0.sh similarity index 79% rename from examples/local/vtworker-down.sh rename to examples/legacy_local/307_delete_shard_0.sh index 0ec047a5638..662bb7cdfe9 100755 --- a/examples/local/vtworker-down.sh +++ b/examples/legacy_local/307_delete_shard_0.sh @@ -14,12 +14,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -set -e - -script_root=`dirname "${BASH_SOURCE}"` -source $script_root/env.sh - -pid=`cat $VTDATAROOT/tmp/vtworker.pid` -echo "Stopping vtworker..." -kill $pid +# this script deletes the old shard 0 which has been replaced by 2 shards +vtctlclient -server localhost:15999 DeleteShard -recursive customer/0 diff --git a/examples/legacy_local/401_teardown.sh b/examples/legacy_local/401_teardown.sh new file mode 100755 index 00000000000..0193f04ff9e --- /dev/null +++ b/examples/legacy_local/401_teardown.sh @@ -0,0 +1,61 @@ +#!/bin/bash + +# Copyright 2019 The Vitess Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# We should not assume that any of the steps have been executed. +# This makes it possible for a user to cleanup at any point. + +source ./env.sh + +./scripts/vtgate-down.sh + +for tablet in 100 200 300 400; do + if vtctlclient -server localhost:15999 GetTablet zone1-$tablet >/dev/null 2>&1 ; then + # The zero tablet is up. Try to shutdown 0-2 tablet + mysqlctl + for i in 0 1 2; do + uid=$[$tablet + $i] + CELL=zone1 TABLET_UID=$uid ./scripts/vttablet-down.sh + CELL=zone1 TABLET_UID=$uid ./scripts/mysqlctl-down.sh + done + fi +done + +./scripts/vtctld-down.sh + +if [ "${TOPO}" = "zk2" ]; then + CELL=zone1 ./scripts/zk-down.sh +elif [ "${TOPO}" = "k8s" ]; then + CELL=zone1 ./scripts/k3s-down.sh +else + CELL=zone1 ./scripts/etcd-down.sh +fi + +# pedantic check: grep for any remaining processes + +if [ ! -z "$VTDATAROOT" ]; then + + if pgrep -f -l "$VTDATAROOT" > /dev/null; then + echo "ERROR: Stale processes detected! It is recommended to manuallly kill them:" + pgrep -f -l "$VTDATAROOT" + else + echo "All good! It looks like every process has shut down" + fi + + # shellcheck disable=SC2086 + rm -r ${VTDATAROOT:?}/* + +fi + +disown -a diff --git a/examples/legacy_local/README.md b/examples/legacy_local/README.md new file mode 100644 index 00000000000..245dbd4bb9e --- /dev/null +++ b/examples/legacy_local/README.md @@ -0,0 +1,10 @@ +# Local Vitess Cluster + +This directory contains example scripts to bring up a Vitess cluster on your +local machine, which may be useful for experimentation. These scripts can +also serve as a starting point for configuring Vitess into your preferred +deployment strategy or toolset. + +See the [Run Vitess Locally](https://vitess.io/docs/tutorials/local/) +tutorial ("Start a Vitess cluster" section) for instructions on using these scripts. + diff --git a/examples/legacy_local/ceph_backup_config.json b/examples/legacy_local/ceph_backup_config.json new file mode 100644 index 00000000000..d71c6170699 --- /dev/null +++ b/examples/legacy_local/ceph_backup_config.json @@ -0,0 +1,6 @@ +{ + "accessKey" : "AccessKey", + "secretKey" : "SecretKey", + "endPoint" : "URL", + "useSSL" : true +} diff --git a/examples/legacy_local/create_commerce_schema.sql b/examples/legacy_local/create_commerce_schema.sql new file mode 100644 index 00000000000..e62e7d2e8bf --- /dev/null +++ b/examples/legacy_local/create_commerce_schema.sql @@ -0,0 +1,18 @@ +create table product( + sku varbinary(128), + description varbinary(128), + price bigint, + primary key(sku) +) ENGINE=InnoDB; +create table customer( + customer_id bigint not null auto_increment, + email varbinary(128), + primary key(customer_id) +) ENGINE=InnoDB; +create table corder( + order_id bigint not null auto_increment, + customer_id bigint, + sku varbinary(128), + price bigint, + primary key(order_id) +) ENGINE=InnoDB; diff --git a/examples/legacy_local/create_commerce_seq.sql b/examples/legacy_local/create_commerce_seq.sql new file mode 100644 index 00000000000..b4e66c771b6 --- /dev/null +++ b/examples/legacy_local/create_commerce_seq.sql @@ -0,0 +1,4 @@ +create table customer_seq(id int, next_id bigint, cache bigint, primary key(id)) comment 'vitess_sequence'; +insert into customer_seq(id, next_id, cache) values(0, 1000, 100); +create table order_seq(id int, next_id bigint, cache bigint, primary key(id)) comment 'vitess_sequence'; +insert into order_seq(id, next_id, cache) values(0, 1000, 100); diff --git a/examples/legacy_local/create_customer_sharded.sql b/examples/legacy_local/create_customer_sharded.sql new file mode 100644 index 00000000000..9d3931c7c94 --- /dev/null +++ b/examples/legacy_local/create_customer_sharded.sql @@ -0,0 +1,2 @@ +alter table customer change customer_id customer_id bigint not null; +alter table corder change order_id order_id bigint not null; diff --git a/examples/kubernetes/create_test_table.sql b/examples/legacy_local/create_test_table.sql similarity index 100% rename from examples/kubernetes/create_test_table.sql rename to examples/legacy_local/create_test_table.sql diff --git a/examples/legacy_local/drop_commerce_tables.sql b/examples/legacy_local/drop_commerce_tables.sql new file mode 100644 index 00000000000..3393ac8141a --- /dev/null +++ b/examples/legacy_local/drop_commerce_tables.sql @@ -0,0 +1,2 @@ +drop table customer; +drop table corder; diff --git a/examples/legacy_local/env.sh b/examples/legacy_local/env.sh new file mode 100644 index 00000000000..1d21fafc98f --- /dev/null +++ b/examples/legacy_local/env.sh @@ -0,0 +1,72 @@ +#!/bin/bash + +# Copyright 2019 The Vitess Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -e + +hostname=`hostname -f` +vtctld_web_port=15000 +export VTDATAROOT="${VTDATAROOT:-${PWD}/vtdataroot}" + +function fail() { + echo "ERROR: $1" + exit 1 +} + +if [[ $EUID -eq 0 ]]; then + fail "This script refuses to be run as root. Please switch to a regular user." +fi + +# mysqld might be in /usr/sbin which will not be in the default PATH +PATH="/usr/sbin:$PATH" +for binary in mysqld etcd etcdctl curl vtctlclient vttablet vtgate vtctld vtctl mysqlctl; do + command -v "$binary" > /dev/null || fail "${binary} is not installed in PATH. See https://vitess.io/docs/get-started/local/ for install instructions." +done; + +if [ "${TOPO}" = "zk2" ]; then + # Each ZooKeeper server needs a list of all servers in the quorum. + # Since we're running them all locally, we need to give them unique ports. + # In a real deployment, these should be on different machines, and their + # respective hostnames should be given. + zkcfg=(\ + "1@$hostname:28881:38881:21811" \ + "2@$hostname:28882:38882:21812" \ + "3@$hostname:28883:38883:21813" \ + ) + printf -v zkcfg ",%s" "${zkcfg[@]}" + zkcfg=${zkcfg:1} + + zkids='1 2 3' + + # Set topology environment parameters. + ZK_SERVER="localhost:21811,localhost:21812,localhost:21813" + # shellcheck disable=SC2034 + TOPOLOGY_FLAGS="-topo_implementation zk2 -topo_global_server_address ${ZK_SERVER} -topo_global_root /vitess/global" +elif [ "${TOPO}" = "k8s" ]; then + # Set topology environment parameters. + K8S_ADDR="localhost" + K8S_PORT="8443" + K8S_KUBECONFIG=$VTDATAROOT/tmp/k8s.kubeconfig + # shellcheck disable=SC2034 + TOPOLOGY_FLAGS="-topo_implementation k8s -topo_k8s_kubeconfig ${K8S_KUBECONFIG} -topo_global_server_address ${K8S_ADDR}:${K8S_PORT} -topo_global_root /vitess/global" +else + ETCD_SERVER="localhost:2379" + TOPOLOGY_FLAGS="-topo_implementation etcd2 -topo_global_server_address $ETCD_SERVER -topo_global_root /vitess/global" + + mkdir -p "${VTDATAROOT}/etcd" +fi + +# Create a tmp dir +mkdir -p "${VTDATAROOT}/tmp" diff --git a/examples/legacy_local/grpc_static_auth.json b/examples/legacy_local/grpc_static_auth.json new file mode 100644 index 00000000000..e6586acfb83 --- /dev/null +++ b/examples/legacy_local/grpc_static_auth.json @@ -0,0 +1,6 @@ +[ + { + "Username": "vitess", + "Password": "vitess_password" + } +] diff --git a/examples/legacy_local/grpc_static_client_auth.json b/examples/legacy_local/grpc_static_client_auth.json new file mode 100644 index 00000000000..b808a87607f --- /dev/null +++ b/examples/legacy_local/grpc_static_client_auth.json @@ -0,0 +1,4 @@ +{ + "Username": "vitess", + "Password": "vitess_password" +} diff --git a/examples/legacy_local/mysql_auth_server_static_creds.json b/examples/legacy_local/mysql_auth_server_static_creds.json new file mode 100644 index 00000000000..cded6bc22c5 --- /dev/null +++ b/examples/legacy_local/mysql_auth_server_static_creds.json @@ -0,0 +1,33 @@ +{ + "mysql_user": [ + { + "MysqlNativePassword": "*9E128DA0C64A6FCCCDCFBDD0FC0A2C967C6DB36F", + "Password": "mysql_password", + "UserData": "mysql_user" + } + ], + "mysql_user2": [ + { + "Password": "mysql_password", + "UserData": "mysql_user" + } + ], + "mysql_user3": [ + { + "MysqlNativePassword": "*9E128DA0C64A6FCCCDCFBDD0FC0A2C967C6DB36F", + "UserData": "mysql_user" + } + ], + + "vt_appdebug": [ + { + "Password": "vtappdebug_password", + "UserData": "vt_appdebug" + }, + { + "SourceHost": "localhost", + "Password": "", + "UserData": "vt_appdebug" + } + ] +} diff --git a/examples/local/etcd-down.sh b/examples/legacy_local/scripts/etcd-down.sh similarity index 78% rename from examples/local/etcd-down.sh rename to examples/legacy_local/scripts/etcd-down.sh index cb2d5b1023f..018af7432a3 100755 --- a/examples/local/etcd-down.sh +++ b/examples/legacy_local/scripts/etcd-down.sh @@ -16,14 +16,7 @@ # This is an example script that stops the etcd servers started by etcd-up.sh. -set -e +source ./env.sh -script_root=$(dirname "${BASH_SOURCE[0]}") - -# shellcheck source=./env.sh -# shellcheck disable=SC1091 -source "${script_root}/env.sh" - -pid=`cat $VTDATAROOT/tmp/etcd.pid` echo "Stopping etcd..." -kill -9 $pid +kill -9 `cat $VTDATAROOT/tmp/etcd.pid` diff --git a/examples/local/etcd-up.sh b/examples/legacy_local/scripts/etcd-up.sh similarity index 91% rename from examples/local/etcd-up.sh rename to examples/legacy_local/scripts/etcd-up.sh index 0e87537f0b0..d8c0a869a7e 100755 --- a/examples/local/etcd-up.sh +++ b/examples/legacy_local/scripts/etcd-up.sh @@ -16,16 +16,11 @@ # This is an example script that creates a quorum of ZooKeeper servers. -set -e -cell=${CELL:-'test'} +source ./env.sh -script_root=$(dirname "${BASH_SOURCE[0]}") +cell=${CELL:-'test'} export ETCDCTL_API=2 -# shellcheck source=./env.sh -# shellcheck disable=SC1091 -source "${script_root}/env.sh" - # Check that etcd is not already running curl "http://${ETCD_SERVER}" > /dev/null 2>&1 && fail "etcd is already running. Exiting." @@ -37,7 +32,6 @@ sleep 5 echo "add /vitess/global" etcdctl --endpoints "http://${ETCD_SERVER}" mkdir /vitess/global & - echo "add /vitess/$cell" etcdctl --endpoints "http://${ETCD_SERVER}" mkdir /vitess/$cell & @@ -55,4 +49,3 @@ set -e echo "etcd start done..." - diff --git a/examples/local/vtctld-down.sh b/examples/legacy_local/scripts/k3s-down.sh similarity index 70% rename from examples/local/vtctld-down.sh rename to examples/legacy_local/scripts/k3s-down.sh index 398311ca043..590dc604e3e 100755 --- a/examples/local/vtctld-down.sh +++ b/examples/legacy_local/scripts/k3s-down.sh @@ -14,13 +14,17 @@ # See the License for the specific language governing permissions and # limitations under the License. -# This is an example script that starts vtctld. +# This is an example script that stops the k3s server started by k3s-up.sh. set -e -script_root=`dirname "${BASH_SOURCE}"` -source $script_root/env.sh +# shellcheck source=./env.sh +# shellcheck disable=SC1091 +source ./env.sh -pid=`cat $VTDATAROOT/tmp/vtctld.pid` -echo "Stopping vtctld..." +# Stop K3s server. +echo "Stopping k3s server..." + +pid=`cat $VTDATAROOT/tmp/k3s.pid` +echo "Stopping k3s..." kill -9 $pid diff --git a/examples/legacy_local/scripts/k3s-up.sh b/examples/legacy_local/scripts/k3s-up.sh new file mode 100755 index 00000000000..3b77600018e --- /dev/null +++ b/examples/legacy_local/scripts/k3s-up.sh @@ -0,0 +1,49 @@ +#!/bin/bash + +# Copyright 2019 The Vitess Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# This is an example script that creates a Kubernetes api for topo use by running k3s + +set -e +cell=${CELL:-'test'} + +script_root=$(dirname "${BASH_SOURCE[0]}") + +# shellcheck source=./env.sh +# shellcheck disable=SC1091 +source ./env.sh + +k3s server --disable-agent --data-dir "${VTDATAROOT}/k3s/" --https-listen-port "${K8S_PORT}" --write-kubeconfig "${K8S_KUBECONFIG}" > "${VTDATAROOT}"/tmp/k3s.out 2>&1 & +PID=$! +echo $PID > "${VTDATAROOT}/tmp/k3s.pid" +disown -a +echo "Waiting for k3s server to start" +sleep 15 + +# Use k3s built-in kubectl with custom config +KUBECTL="k3s kubectl --kubeconfig=${K8S_KUBECONFIG}" + +# Create the CRD for vitesstopologynodes +$KUBECTL create -f ../../go/vt/topo/k8stopo/VitessTopoNodes-crd.yaml + +# Add the CellInfo description for the cell +set +e +echo "add $cell CellInfo" +vtctl $TOPOLOGY_FLAGS AddCellInfo \ + -root /vitess/$cell \ + $cell +set -e + +echo "k3s start done..." diff --git a/examples/kubernetes/sharded-vttablet-down.sh b/examples/legacy_local/scripts/mysqlctl-down.sh similarity index 78% rename from examples/kubernetes/sharded-vttablet-down.sh rename to examples/legacy_local/scripts/mysqlctl-down.sh index 9c921dfcb85..9e5491d1d4c 100755 --- a/examples/kubernetes/sharded-vttablet-down.sh +++ b/examples/legacy_local/scripts/mysqlctl-down.sh @@ -14,10 +14,10 @@ # See the License for the specific language governing permissions and # limitations under the License. -# This is an example script that tears down the vttablet deployment -# created by sharded-vttablet-up.sh. +# This is an example script that stops the mysqld and vttablet instances +# created by vttablet-up.sh -SHARDS='-80,80-' -UID_BASE=200 +source ./env.sh + +mysqlctl -tablet_uid $TABLET_UID shutdown -source ./vttablet-down.sh diff --git a/examples/kubernetes/vtgate-down.sh b/examples/legacy_local/scripts/mysqlctl-up.sh similarity index 52% rename from examples/kubernetes/vtgate-down.sh rename to examples/legacy_local/scripts/mysqlctl-up.sh index 96c29c9c33b..e4c9f58f819 100755 --- a/examples/kubernetes/vtgate-down.sh +++ b/examples/legacy_local/scripts/mysqlctl-up.sh @@ -14,20 +14,29 @@ # See the License for the specific language governing permissions and # limitations under the License. -# This is an example script that stops vtgate. +# This is an example script that creates a single shard vttablet deployment. -set -e +source ./env.sh -script_root=`dirname "${BASH_SOURCE}"` -source $script_root/env.sh +cell=${CELL:-'test'} +uid=$TABLET_UID +mysql_port=$[17000 + $uid] +printf -v alias '%s-%010d' $cell $uid +printf -v tablet_dir 'vt_%010d' $uid -cells=`echo $CELLS | tr ',' ' '` +mkdir -p $VTDATAROOT/backups -for cell in $cells; do - echo "Stopping vtgate replicationcontroller in cell $cell..." - $KUBECTL $KUBECTL_OPTIONS delete replicationcontroller vtgate-$cell +echo "Starting MySQL for tablet $alias..." +action="init" - echo "Deleting vtgate service in cell $cell..." - $KUBECTL $KUBECTL_OPTIONS delete service vtgate-$cell -done +if [ -d $VTDATAROOT/$tablet_dir ]; then + echo "Resuming from existing vttablet dir:" + echo " $VTDATAROOT/$tablet_dir" + action='start' +fi +mysqlctl \ + -log_dir $VTDATAROOT/tmp \ + -tablet_uid $uid \ + -mysql_port $mysql_port \ + $action diff --git a/py/vttest/__init__.py b/examples/legacy_local/scripts/vtctld-down.sh old mode 100644 new mode 100755 similarity index 80% rename from py/vttest/__init__.py rename to examples/legacy_local/scripts/vtctld-down.sh index 4d32e37cccb..d96fa3b927f --- a/py/vttest/__init__.py +++ b/examples/legacy_local/scripts/vtctld-down.sh @@ -1,3 +1,5 @@ +#!/bin/bash + # Copyright 2019 The Vitess Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -12,7 +14,9 @@ # See the License for the specific language governing permissions and # limitations under the License. -from vttest import environment -from vttest import mysql_db_mysqlctl +# This is an example script that stops vtctld. + +source ./env.sh -environment.mysql_db_class = mysql_db_mysqlctl.MySqlDBMysqlctl +echo "Stopping vtctld..." +kill -9 `cat $VTDATAROOT/tmp/vtctld.pid` diff --git a/examples/local/vtworker-up.sh b/examples/legacy_local/scripts/vtctld-up.sh similarity index 54% rename from examples/local/vtworker-up.sh rename to examples/legacy_local/scripts/vtctld-up.sh index ec1a4e5ec41..662a234ae48 100755 --- a/examples/local/vtworker-up.sh +++ b/examples/legacy_local/scripts/vtctld-up.sh @@ -14,22 +14,25 @@ # See the License for the specific language governing permissions and # limitations under the License. -# This is an example script that runs vtworker. +# This is an example script that starts vtctld. -set -e +source ./env.sh cell=${CELL:-'test'} -script_root=`dirname "${BASH_SOURCE}"` -source $script_root/env.sh +grpc_port=15999 -echo "Starting vtworker..." -vtworker \ - $TOPOLOGY_FLAGS \ - -cell $cell \ - -log_dir $VTDATAROOT/tmp \ - -alsologtostderr \ - -service_map=grpc-vtworker \ - -grpc_port 15033 \ - -port 15032 \ - -pid_file $VTDATAROOT/tmp/vtworker.pid \ - -use_v3_resharding_mode & +echo "Starting vtctld..." +# shellcheck disable=SC2086 +vtctld \ + $TOPOLOGY_FLAGS \ + -cell $cell \ + -workflow_manager_init \ + -workflow_manager_use_election \ + -service_map 'grpc-vtctl' \ + -backup_storage_implementation file \ + -file_backup_storage_root $VTDATAROOT/backups \ + -log_dir $VTDATAROOT/tmp \ + -port $vtctld_web_port \ + -grpc_port $grpc_port \ + -pid_file $VTDATAROOT/tmp/vtctld.pid \ + > $VTDATAROOT/tmp/vtctld.out 2>&1 & diff --git a/examples/local/vtgate-down.sh b/examples/legacy_local/scripts/vtgate-down.sh similarity index 85% rename from examples/local/vtgate-down.sh rename to examples/legacy_local/scripts/vtgate-down.sh index d396cceab51..9da0a7179df 100755 --- a/examples/local/vtgate-down.sh +++ b/examples/legacy_local/scripts/vtgate-down.sh @@ -16,13 +16,8 @@ # This is an example script that stops the instance started by vtgate-up.sh. -set -e - -script_root=`dirname "${BASH_SOURCE}"` -source $script_root/env.sh +source ./env.sh # Stop vtgate. -pid=`cat $VTDATAROOT/tmp/vtgate.pid` echo "Stopping vtgate..." -kill $pid - +kill `cat $VTDATAROOT/tmp/vtgate.pid` diff --git a/examples/legacy_local/scripts/vtgate-up.sh b/examples/legacy_local/scripts/vtgate-up.sh new file mode 100755 index 00000000000..e3fe2d17f82 --- /dev/null +++ b/examples/legacy_local/scripts/vtgate-up.sh @@ -0,0 +1,58 @@ +#!/bin/bash + +# Copyright 2019 The Vitess Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# This is an example script that starts a single vtgate. + +source ./env.sh + +cell=${CELL:-'test'} +web_port=15001 +grpc_port=15991 +mysql_server_port=15306 +mysql_server_socket_path="/tmp/mysql.sock" + +# Start vtgate. +# shellcheck disable=SC2086 +vtgate \ + $TOPOLOGY_FLAGS \ + -log_dir $VTDATAROOT/tmp \ + -log_queries_to_file $VTDATAROOT/tmp/vtgate_querylog.txt \ + -port $web_port \ + -grpc_port $grpc_port \ + -mysql_server_port $mysql_server_port \ + -mysql_server_socket_path $mysql_server_socket_path \ + -cell $cell \ + -cells_to_watch $cell \ + -tablet_types_to_wait MASTER,REPLICA \ + -gateway_implementation discoverygateway \ + -service_map 'grpc-vtgateservice' \ + -pid_file $VTDATAROOT/tmp/vtgate.pid \ + -mysql_auth_server_impl none \ + > $VTDATAROOT/tmp/vtgate.out 2>&1 & + +# Block waiting for vtgate to be listening +# Not the same as healthy + +echo "Waiting for vtgate to be up..." +while true; do + curl -I "http://$hostname:$web_port/debug/status" >/dev/null 2>&1 && break + sleep 0.1 +done; +echo "vtgate is up!" + +echo "Access vtgate at http://$hostname:$web_port/debug/status" + +disown -a diff --git a/examples/kubernetes/namespace-down.sh b/examples/legacy_local/scripts/vttablet-down.sh similarity index 67% rename from examples/kubernetes/namespace-down.sh rename to examples/legacy_local/scripts/vttablet-down.sh index e5345f412e6..47b881b9793 100755 --- a/examples/kubernetes/namespace-down.sh +++ b/examples/legacy_local/scripts/vttablet-down.sh @@ -14,14 +14,17 @@ # See the License for the specific language governing permissions and # limitations under the License. -# This is an example script that deletes a namespace. +# This is an example script that stops the mysqld and vttablet instances +# created by vttablet-up.sh -set -e +source ./env.sh -script_root=`dirname "${BASH_SOURCE}"` -source $script_root/env.sh +printf -v tablet_dir 'vt_%010d' $TABLET_UID +pid=`cat $VTDATAROOT/$tablet_dir/vttablet.pid` + +kill $pid + +# Wait for vttablet to die. +while ps -p $pid > /dev/null; do sleep 1; done -namespace=${VITESS_NAME:-'vitess'} -echo "Deleting namespace $namespace..." -$KUBECTL $KUBECTL_OPTIONS delete namespace $namespace diff --git a/examples/legacy_local/scripts/vttablet-up.sh b/examples/legacy_local/scripts/vttablet-up.sh new file mode 100755 index 00000000000..c3f66fa806d --- /dev/null +++ b/examples/legacy_local/scripts/vttablet-up.sh @@ -0,0 +1,69 @@ +#!/bin/bash + +# Copyright 2019 The Vitess Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +source ./env.sh + +cell=${CELL:-'test'} +keyspace=${KEYSPACE:-'test_keyspace'} +shard=${SHARD:-'0'} +uid=$TABLET_UID +mysql_port=$[17000 + $uid] +port=$[15000 + $uid] +grpc_port=$[16000 + $uid] +printf -v alias '%s-%010d' $cell $uid +printf -v tablet_dir 'vt_%010d' $uid +tablet_hostname='' +printf -v tablet_logfile 'vttablet_%010d_querylog.txt' $uid + +tablet_type=replica +if [[ "${uid: -1}" -gt 1 ]]; then + tablet_type=rdonly +fi + +echo "Starting vttablet for $alias..." +# shellcheck disable=SC2086 +vttablet \ + $TOPOLOGY_FLAGS \ + -log_dir $VTDATAROOT/tmp \ + -log_queries_to_file $VTDATAROOT/tmp/$tablet_logfile \ + -tablet-path $alias \ + -tablet_hostname "$tablet_hostname" \ + -init_keyspace $keyspace \ + -init_shard $shard \ + -init_tablet_type $tablet_type \ + -health_check_interval 5s \ + -enable_semi_sync \ + -enable_replication_reporter \ + -backup_storage_implementation file \ + -file_backup_storage_root $VTDATAROOT/backups \ + -restore_from_backup \ + -port $port \ + -grpc_port $grpc_port \ + -service_map 'grpc-queryservice,grpc-tabletmanager,grpc-updatestream' \ + -pid_file $VTDATAROOT/$tablet_dir/vttablet.pid \ + -vtctld_addr http://$hostname:$vtctld_web_port/ \ + > $VTDATAROOT/$tablet_dir/vttablet.out 2>&1 & + +# Block waiting for the tablet to be listening +# Not the same as healthy + +for i in $(seq 0 300); do + curl -I "http://$hostname:$port/debug/status" >/dev/null 2>&1 && break + sleep 0.1 +done + +# check one last time +curl -I "http://$hostname:$port/debug/status" || fail "tablet could not be started!" diff --git a/examples/local/zk-down.sh b/examples/legacy_local/scripts/zk-down.sh similarity index 91% rename from examples/local/zk-down.sh rename to examples/legacy_local/scripts/zk-down.sh index bd6cffd0f7b..18dd7933bc9 100755 --- a/examples/local/zk-down.sh +++ b/examples/legacy_local/scripts/zk-down.sh @@ -16,10 +16,7 @@ # This is an example script that stops the ZooKeeper servers started by zk-up.sh. -set -e - -script_root=`dirname "${BASH_SOURCE}"` -source $script_root/env.sh +source ./env.sh # Stop ZooKeeper servers. echo "Stopping zk servers..." diff --git a/examples/local/zk-up.sh b/examples/legacy_local/scripts/zk-up.sh similarity index 96% rename from examples/local/zk-up.sh rename to examples/legacy_local/scripts/zk-up.sh index 39585320f5b..6671d1063a6 100755 --- a/examples/local/zk-up.sh +++ b/examples/legacy_local/scripts/zk-up.sh @@ -16,13 +16,10 @@ # This is an example script that creates a quorum of ZooKeeper servers. -set -e +source ./env.sh cell=${CELL:-'test'} -script_root=`dirname "${BASH_SOURCE}"` -source $script_root/env.sh - # Start ZooKeeper servers. # The "zkctl init" command won't return until the server is able to contact its # peers, so we need to start them all in the background and then wait for them. diff --git a/examples/local/lmysql.sh b/examples/legacy_local/topo-etcd2.sh old mode 100755 new mode 100644 similarity index 83% rename from examples/local/lmysql.sh rename to examples/legacy_local/topo-etcd2.sh index b043ed69b15..c61543a806c --- a/examples/local/lmysql.sh +++ b/examples/legacy_local/topo-etcd2.sh @@ -14,6 +14,8 @@ # See the License for the specific language governing permissions and # limitations under the License. -# This is a convenience script to run mysql client against the local vtgate. +# This is an example script that creates a single shard vttablet deployment. + +export TOPO='etcd2' + -mysql -h 127.0.0.1 -P 15306 -u mysql_user diff --git a/test/vtgate_gateway_flavor/__init__.py b/examples/legacy_local/topo-k8s.sh similarity index 84% rename from test/vtgate_gateway_flavor/__init__.py rename to examples/legacy_local/topo-k8s.sh index 35bf136ccc5..92e14ba4d69 100644 --- a/test/vtgate_gateway_flavor/__init__.py +++ b/examples/legacy_local/topo-k8s.sh @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/bin/bash # Copyright 2019 The Vitess Authors. # @@ -13,3 +13,9 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. + +# This is an example script that creates a single shard vttablet deployment. + +export TOPO='k8s' + + diff --git a/test/topo_flavor/__init__.py b/examples/legacy_local/topo-zk2.sh similarity index 84% rename from test/topo_flavor/__init__.py rename to examples/legacy_local/topo-zk2.sh index 35bf136ccc5..29380949d8f 100644 --- a/test/topo_flavor/__init__.py +++ b/examples/legacy_local/topo-zk2.sh @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/bin/bash # Copyright 2019 The Vitess Authors. # @@ -13,3 +13,9 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. + +# This is an example script that creates a single shard vttablet deployment. + +export TOPO='zk2' + + diff --git a/examples/kubernetes/vschema.json b/examples/legacy_local/vschema.json similarity index 100% rename from examples/kubernetes/vschema.json rename to examples/legacy_local/vschema.json diff --git a/examples/legacy_local/vschema_commerce_initial.json b/examples/legacy_local/vschema_commerce_initial.json new file mode 100644 index 00000000000..0d1bae44428 --- /dev/null +++ b/examples/legacy_local/vschema_commerce_initial.json @@ -0,0 +1,7 @@ +{ + "tables": { + "product": {}, + "customer": {}, + "corder": {} + } +} diff --git a/examples/legacy_local/vschema_commerce_seq.json b/examples/legacy_local/vschema_commerce_seq.json new file mode 100644 index 00000000000..2e564fa6c96 --- /dev/null +++ b/examples/legacy_local/vschema_commerce_seq.json @@ -0,0 +1,11 @@ +{ + "tables": { + "customer_seq": { + "type": "sequence" + }, + "order_seq": { + "type": "sequence" + }, + "product": {} + } +} diff --git a/examples/local/vschema_commerce_vsplit.json b/examples/legacy_local/vschema_commerce_vsplit.json similarity index 100% rename from examples/local/vschema_commerce_vsplit.json rename to examples/legacy_local/vschema_commerce_vsplit.json diff --git a/examples/legacy_local/vschema_customer_sharded.json b/examples/legacy_local/vschema_customer_sharded.json new file mode 100644 index 00000000000..3109e2a2f3c --- /dev/null +++ b/examples/legacy_local/vschema_customer_sharded.json @@ -0,0 +1,34 @@ +{ + "sharded": true, + "vindexes": { + "hash": { + "type": "hash" + } + }, + "tables": { + "customer": { + "column_vindexes": [ + { + "column": "customer_id", + "name": "hash" + } + ], + "auto_increment": { + "column": "customer_id", + "sequence": "customer_seq" + } + }, + "corder": { + "column_vindexes": [ + { + "column": "customer_id", + "name": "hash" + } + ], + "auto_increment": { + "column": "order_id", + "sequence": "order_seq" + } + } + } +} diff --git a/examples/local/vschema_customer_vsplit.json b/examples/legacy_local/vschema_customer_vsplit.json similarity index 100% rename from examples/local/vschema_customer_vsplit.json rename to examples/legacy_local/vschema_customer_vsplit.json diff --git a/examples/local/101_initial_cluster.sh b/examples/local/101_initial_cluster.sh index 1a484d98d5d..f426de8296d 100755 --- a/examples/local/101_initial_cluster.sh +++ b/examples/local/101_initial_cluster.sh @@ -1,13 +1,13 @@ #!/bin/bash # Copyright 2019 The Vitess Authors. -# +# # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -17,35 +17,32 @@ # this script brings up zookeeper and all the vitess components # required for a single shard deployment. -set -e - -# shellcheck disable=SC2128 -script_root=$(dirname "${BASH_SOURCE}") -source "${script_root}/env.sh" +source ./env.sh # start topo server if [ "${TOPO}" = "zk2" ]; then - CELL=zone1 "$script_root/zk-up.sh" + CELL=zone1 ./scripts/zk-up.sh else - CELL=zone1 "$script_root/etcd-up.sh" + CELL=zone1 ./scripts/etcd-up.sh fi # start vtctld -CELL=zone1 "$script_root/vtctld-up.sh" +CELL=zone1 ./scripts/vtctld-up.sh # start vttablets for keyspace commerce -CELL=zone1 KEYSPACE=commerce UID_BASE=100 "$script_root/vttablet-up.sh" +for i in 100 101 102; do + CELL=zone1 TABLET_UID=$i ./scripts/mysqlctl-up.sh + CELL=zone1 KEYSPACE=commerce TABLET_UID=$i ./scripts/vttablet-up.sh +done # set one of the replicas to master -./lvtctl.sh InitShardMaster -force commerce/0 zone1-100 +vtctlclient InitShardMaster -force commerce/0 zone1-100 # create the schema -./lvtctl.sh ApplySchema -sql-file create_commerce_schema.sql commerce +vtctlclient ApplySchema -sql-file create_commerce_schema.sql commerce # create the vschema -./lvtctl.sh ApplyVSchema -vschema_file vschema_commerce_initial.json commerce +vtctlclient ApplyVSchema -vschema_file vschema_commerce_initial.json commerce # start vtgate -CELL=zone1 "$script_root/vtgate-up.sh" - -disown -a +CELL=zone1 ./scripts/vtgate-up.sh diff --git a/examples/local/202_customer_tablets.sh b/examples/local/201_customer_tablets.sh similarity index 59% rename from examples/local/202_customer_tablets.sh rename to examples/local/201_customer_tablets.sh index 9420ba19713..b53ffb6cd16 100755 --- a/examples/local/202_customer_tablets.sh +++ b/examples/local/201_customer_tablets.sh @@ -1,13 +1,13 @@ #!/bin/bash -# Copyright 2019 The Vitess Authors. -# +# Copyright 2020 The Vitess Authors. +# # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -18,16 +18,11 @@ # resharding it also splits the vschema between the two keyspaces # old (commerce) and new (customer) -set -e +source ./env.sh -# shellcheck disable=SC2128 -script_root=$(dirname "${BASH_SOURCE}") +for i in 200 201 202; do + CELL=zone1 TABLET_UID=$i ./scripts/mysqlctl-up.sh + CELL=zone1 KEYSPACE=customer TABLET_UID=$i ./scripts/vttablet-up.sh +done -CELL=zone1 KEYSPACE=customer UID_BASE=200 "$script_root/vttablet-up.sh" - -./lvtctl.sh InitShardMaster -force customer/0 zone1-200 -./lvtctl.sh CopySchemaShard -tables customer,corder commerce/0 customer/0 -./lvtctl.sh ApplyVSchema -vschema_file vschema_commerce_vsplit.json commerce -./lvtctl.sh ApplyVSchema -vschema_file vschema_customer_vsplit.json customer - -disown -a +vtctlclient InitShardMaster -force customer/0 zone1-200 diff --git a/examples/local/202_move_tables.sh b/examples/local/202_move_tables.sh new file mode 100755 index 00000000000..8bf69cf95dd --- /dev/null +++ b/examples/local/202_move_tables.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +# Copyright 2020 The Vitess Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# this script copies over all the data from commerce keyspace to +# customer keyspace for the customer and corder tables + +source ./env.sh + +vtctlclient MoveTables -workflow=commerce2customer commerce customer '{"customer":{}, "corder":{}}' diff --git a/examples/local/203_switch_reads.sh b/examples/local/203_switch_reads.sh new file mode 100755 index 00000000000..93b4a31b76c --- /dev/null +++ b/examples/local/203_switch_reads.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +# Copyright 2020 The Vitess Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# this script migrates traffic for the new customer keyspace to the new +# tablets of types rdonly and replica + +source ./env.sh + +vtctlclient SwitchReads -tablet_type=rdonly customer.commerce2customer +vtctlclient SwitchReads -tablet_type=replica customer.commerce2customer diff --git a/examples/local/204_switch_writes.sh b/examples/local/204_switch_writes.sh new file mode 100755 index 00000000000..b2a6434ad17 --- /dev/null +++ b/examples/local/204_switch_writes.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +# Copyright 2020 The Vitess Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# this script migrates master traffic for the customer keyspace to the +# new master tablet + +source ./env.sh + +vtctlclient SwitchWrites customer.commerce2customer diff --git a/examples/local/206_clean_commerce.sh b/examples/local/205_clean_commerce.sh similarity index 67% rename from examples/local/206_clean_commerce.sh rename to examples/local/205_clean_commerce.sh index 6139558c385..6fe9350e8ae 100755 --- a/examples/local/206_clean_commerce.sh +++ b/examples/local/205_clean_commerce.sh @@ -1,13 +1,13 @@ #!/bin/bash -# Copyright 2019 The Vitess Authors. -# +# Copyright 2020 The Vitess Authors. +# # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -17,11 +17,10 @@ # this script removes the customer and corder tables from the commerce # keyspace -set -e +source ./env.sh -./lvtctl.sh ApplySchema -sql-file drop_commerce_tables.sql commerce -./lvtctl.sh SetShardTabletControl -blacklisted_tables=customer,corder -remove commerce/0 rdonly -./lvtctl.sh SetShardTabletControl -blacklisted_tables=customer,corder -remove commerce/0 replica -./lvtctl.sh SetShardTabletControl -blacklisted_tables=customer,corder -remove commerce/0 master - -disown -a +vtctlclient SetShardTabletControl -blacklisted_tables=customer,corder -remove commerce/0 rdonly +vtctlclient SetShardTabletControl -blacklisted_tables=customer,corder -remove commerce/0 replica +vtctlclient SetShardTabletControl -blacklisted_tables=customer,corder -remove commerce/0 master +vtctlclient ApplySchema -sql-file drop_commerce_tables.sql commerce +vtctlclient ApplyRoutingRules -rules='{}' diff --git a/examples/local/301_customer_sharded.sh b/examples/local/301_customer_sharded.sh index 4d7bacf01d4..033b219ed0b 100755 --- a/examples/local/301_customer_sharded.sh +++ b/examples/local/301_customer_sharded.sh @@ -1,13 +1,13 @@ #!/bin/bash # Copyright 2019 The Vitess Authors. -# +# # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -20,11 +20,9 @@ # it also changes the customer vschema from unsharded to sharded and # sets up the necessary vindexes -set -e +source ./env.sh -./lvtctl.sh ApplySchema -sql-file create_commerce_seq.sql commerce -./lvtctl.sh ApplyVSchema -vschema_file vschema_commerce_seq.json commerce -./lvtctl.sh ApplySchema -sql-file create_customer_sharded.sql customer -./lvtctl.sh ApplyVSchema -vschema_file vschema_customer_sharded.json customer - -disown -a +vtctlclient ApplySchema -sql-file create_commerce_seq.sql commerce +vtctlclient ApplyVSchema -vschema_file vschema_commerce_seq.json commerce +vtctlclient ApplySchema -sql-file create_customer_sharded.sql customer +vtctlclient ApplyVSchema -vschema_file vschema_customer_sharded.json customer diff --git a/examples/local/302_new_shards.sh b/examples/local/302_new_shards.sh index 8475a83f1b2..33f2ec294e1 100755 --- a/examples/local/302_new_shards.sh +++ b/examples/local/302_new_shards.sh @@ -1,13 +1,13 @@ #!/bin/bash # Copyright 2019 The Vitess Authors. -# +# # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -15,19 +15,19 @@ # limitations under the License. # this script brings up new tablets for the two new shards that we will -# be creating in the customer keyspace and copies the schema +# be creating in the customer keyspace and copies the schema -set -e +source ./env.sh -# shellcheck disable=SC2128 -script_root=$(dirname "${BASH_SOURCE}") +for i in 300 301 302; do + CELL=zone1 TABLET_UID=$i ./scripts/mysqlctl-up.sh + SHARD=-80 CELL=zone1 KEYSPACE=customer TABLET_UID=$i ./scripts/vttablet-up.sh +done -SHARD=-80 CELL=zone1 KEYSPACE=customer UID_BASE=300 "$script_root/vttablet-up.sh" -SHARD=80- CELL=zone1 KEYSPACE=customer UID_BASE=400 "$script_root/vttablet-up.sh" +for i in 400 401 402; do + CELL=zone1 TABLET_UID=$i ./scripts/mysqlctl-up.sh + SHARD=80- CELL=zone1 KEYSPACE=customer TABLET_UID=$i ./scripts/vttablet-up.sh +done -./lvtctl.sh InitShardMaster -force customer/-80 zone1-300 -./lvtctl.sh InitShardMaster -force customer/80- zone1-400 -./lvtctl.sh CopySchemaShard customer/0 customer/-80 -./lvtctl.sh CopySchemaShard customer/0 customer/80- - -disown -a +vtctlclient InitShardMaster -force customer/-80 zone1-300 +vtctlclient InitShardMaster -force customer/80- zone1-400 diff --git a/examples/local/303_reshard.sh b/examples/local/303_reshard.sh new file mode 100755 index 00000000000..2e980a8fee7 --- /dev/null +++ b/examples/local/303_reshard.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +# Copyright 2020 The Vitess Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# this script copies the data from customer/0 to customer/-80 and customer/80- +# each row will be copied to exactly one shard based on the vindex value + +source ./env.sh + +vtctlclient Reshard customer.cust2cust '0' '-80,80-' diff --git a/examples/local/304_switch_reads.sh b/examples/local/304_switch_reads.sh new file mode 100755 index 00000000000..041d4206048 --- /dev/null +++ b/examples/local/304_switch_reads.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +# Copyright 2020 The Vitess Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# this script migrates traffic for the rdonly and replica tablets + +source ./env.sh + +vtctlclient SwitchReads -tablet_type=rdonly customer.cust2cust +vtctlclient SwitchReads -tablet_type=replica customer.cust2cust diff --git a/py/vtctl/__init__.py b/examples/local/305_switch_writes.sh old mode 100644 new mode 100755 similarity index 76% rename from py/vtctl/__init__.py rename to examples/local/305_switch_writes.sh index fbc9e3ecdd1..94a276e3867 --- a/py/vtctl/__init__.py +++ b/examples/local/305_switch_writes.sh @@ -1,5 +1,7 @@ -# Copyright 2019 The Vitess Authors. -# +#!/bin/bash + +# Copyright 2020 The Vitess Authors. +# # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -11,3 +13,9 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. + +# this script migrates traffic for the master tablet + +source ./env.sh + +vtctlclient SwitchWrites customer.cust2cust diff --git a/examples/local/306_down_shard_0.sh b/examples/local/306_down_shard_0.sh index 79bdd6f3318..9b6a0ed8180 100755 --- a/examples/local/306_down_shard_0.sh +++ b/examples/local/306_down_shard_0.sh @@ -1,13 +1,13 @@ #!/bin/bash # Copyright 2019 The Vitess Authors. -# +# # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -15,11 +15,9 @@ # limitations under the License. # this script brings down the tablets for customer/0 keyspace -set -e +source ./env.sh -# shellcheck disable=SC2128 -script_root=$(dirname "${BASH_SOURCE}") - -CELL=zone1 UID_BASE=200 "$script_root/vttablet-down.sh" - -disown -a +for i in 200 201 202; do + CELL=zone1 TABLET_UID=$i ./scripts/vttablet-down.sh + CELL=zone1 TABLET_UID=$i ./scripts/mysqlctl-down.sh +done diff --git a/examples/local/307_delete_shard_0.sh b/examples/local/307_delete_shard_0.sh index 6076b0fabbe..12fdba72c8a 100755 --- a/examples/local/307_delete_shard_0.sh +++ b/examples/local/307_delete_shard_0.sh @@ -1,13 +1,13 @@ #!/bin/bash # Copyright 2019 The Vitess Authors. -# +# # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -16,8 +16,6 @@ # this script deletes the old shard 0 which has been replaced by 2 shards -set -e +source ./env.sh -./lvtctl.sh DeleteShard -recursive customer/0 - -disown -a +vtctlclient DeleteShard -recursive customer/0 diff --git a/examples/local/401_teardown.sh b/examples/local/401_teardown.sh index b0168ae133d..c0c3c614941 100755 --- a/examples/local/401_teardown.sh +++ b/examples/local/401_teardown.sh @@ -1,13 +1,13 @@ #!/bin/bash # Copyright 2019 The Vitess Authors. -# +# # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -17,38 +17,44 @@ # We should not assume that any of the steps have been executed. # This makes it possible for a user to cleanup at any point. -set -e +source ./env.sh -# shellcheck disable=SC2128 -script_root=$(dirname "${BASH_SOURCE}") +./scripts/vtgate-down.sh -./vtgate-down.sh +for tablet in 100 200 300 400; do + if vtctlclient -server localhost:15999 GetTablet zone1-$tablet >/dev/null 2>&1; then + # The zero tablet is up. Try to shutdown 0-2 tablet + mysqlctl + for i in 0 1 2; do + uid=$(($tablet + $i)) + echo "Shutting down tablet zone1-$uid" + CELL=zone1 TABLET_UID=$uid ./scripts/vttablet-down.sh + echo "Shutting down mysql zone1-$uid" + CELL=zone1 TABLET_UID=$uid ./scripts/mysqlctl-down.sh + done + fi +done -for TABLET in 100 200 300 400; do - ./lvtctl.sh GetTablet zone1-$TABLET >/dev/null 2>&1 && CELL=zone1 UID_BASE=$TABLET "$script_root/vttablet-down.sh" -done; - -./vtctld-down.sh +./scripts/vtctld-down.sh if [ "${TOPO}" = "zk2" ]; then - CELL=zone1 "$script_root/zk-down.sh" + CELL=zone1 ./scripts/zk-down.sh else - CELL=zone1 "$script_root/etcd-down.sh" + CELL=zone1 ./scripts/etcd-down.sh fi # pedantic check: grep for any remaining processes if [ ! -z "$VTDATAROOT" ]; then - if pgrep -f -l "$VTDATAROOT" > /dev/null; then - echo "ERROR: Stale processes detected! It is recommended to manuallly kill them:" - pgrep -f -l "$VTDATAROOT" - else - echo "All good! It looks like every process has shut down" - fi + if pgrep -f -l "$VTDATAROOT" >/dev/null; then + echo "ERROR: Stale processes detected! It is recommended to manuallly kill them:" + pgrep -f -l "$VTDATAROOT" + else + echo "All good! It looks like every process has shut down" + fi - # shellcheck disable=SC2086 - rm -r ${VTDATAROOT:?}/* + # shellcheck disable=SC2086 + rm -r ${VTDATAROOT:?}/* fi diff --git a/examples/local/README.md b/examples/local/README.md index 245dbd4bb9e..46f647e7aff 100644 --- a/examples/local/README.md +++ b/examples/local/README.md @@ -1,10 +1,51 @@ -# Local Vitess Cluster +# Instructions -This directory contains example scripts to bring up a Vitess cluster on your -local machine, which may be useful for experimentation. These scripts can -also serve as a starting point for configuring Vitess into your preferred -deployment strategy or toolset. +Detailed instructions for running this example can be found at https://vitess.io. +This document contains the summary of the commands to be run. -See the [Run Vitess Locally](https://vitess.io/docs/tutorials/local/) -tutorial ("Start a Vitess cluster" section) for instructions on using these scripts. +``` +# Bring up initial cluster and commerce keyspace +./101_initial_cluster.sh + +# Setup aliases +source alias.source + +# Insert and verify data +mysql < ../common/insert_commerce_data.sql +mysql --table < ../common/select_commerce_data.sql + +# Bring up customer keyspace +./201_customer_tablets.sh + +# Initiate move tables +vtctlclient MoveTables -workflow=commerce2customer commerce customer '{"customer":{}, "corder":{}}' + +# Cut-over +vtctlclient SwitchReads -tablet_type=rdonly customer.commerce2customer +vtctlclient SwitchReads -tablet_type=replica customer.commerce2customer +vtctlclient SwitchWrites customer.commerce2customer + +# Clean-up +vtctlclient SetShardTabletControl -blacklisted_tables=customer,corder -remove commerce/0 rdonly +vtctlclient SetShardTabletControl -blacklisted_tables=customer,corder -remove commerce/0 replica +vtctlclient SetShardTabletControl -blacklisted_tables=customer,corder -remove commerce/0 master +vtctlclient ApplyRoutingRules -rules='{}' + +# Prepare for resharding +./301_customer_sharded.sh +./302_new_shards.sh + +# Reshard +vtctlclient Reshard customer.cust2cust '0' '-80,80-' +vtctlclient SwitchReads -tablet_type=rdonly customer.cust2cust +vtctlclient SwitchReads -tablet_type=replica customer.cust2cust +vtctlclient SwitchWrites customer.cust2cust + +# Down shard 0 +./306_down_shard_0.sh +vtctlclient DeleteShard -recursive customer/0 + +# Down cluster +./401_teardown.sh +``` diff --git a/examples/local/client.py b/examples/local/client.py deleted file mode 100644 index 1204ce309de..00000000000 --- a/examples/local/client.py +++ /dev/null @@ -1,85 +0,0 @@ -#!/usr/bin/env python - -# Copyright 2019 The Vitess Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - - -"""Sample Vitess client in Python. - -This is a sample for using the Python Vitess client. -It's a script that inserts some random messages on random pages of the -guestbook sample app. - -Before running this, start up a local example cluster. - -Then run client.sh, which sets up PYTHONPATH before running client.py: -vitess/examples/local$ ./client.sh -""" - -import argparse -import random -import time - -from vtdb import vtgate_client - -# register the python gRPC client upon import -from vtdb import grpc_vtgate_client # pylint: disable=unused-import - -# Parse args -parser = argparse.ArgumentParser() -parser.add_argument('--server', dest='server', default='localhost:15991') -parser.add_argument('--timeout', dest='timeout', type=float, default='10.0') -args = parser.parse_args() - -# Connect -conn = vtgate_client.connect('grpc', args.server, args.timeout) - -try: - # Insert some messages on random pages. - print 'Inserting into master...' - cursor = conn.cursor(tablet_type='master', writable=True) - for i in range(3): - page = random.randint(1, 100) - - cursor.begin() - cursor.execute( - 'INSERT INTO messages (page, time_created_ns, message)' - ' VALUES (:page, :time_created_ns, :message)', - { - 'page': page, - 'time_created_ns': int(time.time() * 1e9), - 'message': 'V is for speed', - }) - cursor.commit() - - # Read it back from the master. - print 'Reading from master...' - cursor.execute('SELECT page, time_created_ns, message FROM messages', {}) - for row in cursor.fetchall(): - print row - - cursor.close() - - # Read from a replica. - # Note that this may be behind master due to replication lag. - print 'Reading from replica...' - cursor = conn.cursor(tablet_type='replica') - cursor.execute('SELECT page, time_created_ns, message FROM messages', {}) - for row in cursor.fetchall(): - print row - cursor.close() - -finally: - # Clean up - conn.close() diff --git a/examples/local/env.sh b/examples/local/env.sh index 0211bcbbc71..09421d33ce1 100644 --- a/examples/local/env.sh +++ b/examples/local/env.sh @@ -14,7 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -hostname=`hostname -f` +hostname=$(hostname -f) vtctld_web_port=15000 export VTDATAROOT="${VTDATAROOT:-${PWD}/vtdataroot}" @@ -61,3 +61,16 @@ else mkdir -p "${VTDATAROOT}/tmp" mkdir -p "${VTDATAROOT}/etcd" fi + +mkdir -p "${VTDATAROOT}/tmp" + +# Set aliases to simplify instructions. +# In your own environment you may prefer to use config files, +# such as ~/.my.cnf + +alias mysql="command mysql -h 127.0.0.1 -P 15306" +alias vtctlclient="command vtctlclient -server localhost:15999 -log_dir ${VTDATAROOT}/tmp -alsologtostderr" + +# Make sure aliases are expanded in non-interactive shell +shopt -s expand_aliases + diff --git a/examples/local/scripts/etcd-down.sh b/examples/local/scripts/etcd-down.sh new file mode 100755 index 00000000000..018af7432a3 --- /dev/null +++ b/examples/local/scripts/etcd-down.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +# Copyright 2019 The Vitess Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# This is an example script that stops the etcd servers started by etcd-up.sh. + +source ./env.sh + +echo "Stopping etcd..." +kill -9 `cat $VTDATAROOT/tmp/etcd.pid` diff --git a/examples/local/scripts/etcd-up.sh b/examples/local/scripts/etcd-up.sh new file mode 100755 index 00000000000..d8c0a869a7e --- /dev/null +++ b/examples/local/scripts/etcd-up.sh @@ -0,0 +1,51 @@ +#!/bin/bash + +# Copyright 2019 The Vitess Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# This is an example script that creates a quorum of ZooKeeper servers. + +source ./env.sh + +cell=${CELL:-'test'} +export ETCDCTL_API=2 + +# Check that etcd is not already running +curl "http://${ETCD_SERVER}" > /dev/null 2>&1 && fail "etcd is already running. Exiting." + +etcd --enable-v2=true --data-dir "${VTDATAROOT}/etcd/" --listen-client-urls "http://${ETCD_SERVER}" --advertise-client-urls "http://${ETCD_SERVER}" > "${VTDATAROOT}"/tmp/etcd.out 2>&1 & +PID=$! +echo $PID > "${VTDATAROOT}/tmp/etcd.pid" +sleep 5 + +echo "add /vitess/global" +etcdctl --endpoints "http://${ETCD_SERVER}" mkdir /vitess/global & + +echo "add /vitess/$cell" +etcdctl --endpoints "http://${ETCD_SERVER}" mkdir /vitess/$cell & + +# And also add the CellInfo description for the cell. +# If the node already exists, it's fine, means we used existing data. +echo "add $cell CellInfo" +set +e +# shellcheck disable=SC2086 +vtctl $TOPOLOGY_FLAGS AddCellInfo \ + -root /vitess/$cell \ + -server_address "${ETCD_SERVER}" \ + $cell +set -e + +echo "etcd start done..." + + diff --git a/examples/local/scripts/mysqlctl-down.sh b/examples/local/scripts/mysqlctl-down.sh new file mode 100755 index 00000000000..9e5491d1d4c --- /dev/null +++ b/examples/local/scripts/mysqlctl-down.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +# Copyright 2019 The Vitess Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# This is an example script that stops the mysqld and vttablet instances +# created by vttablet-up.sh + +source ./env.sh + +mysqlctl -tablet_uid $TABLET_UID shutdown + diff --git a/examples/local/client.sh b/examples/local/scripts/mysqlctl-up.sh similarity index 52% rename from examples/local/client.sh rename to examples/local/scripts/mysqlctl-up.sh index 8e1064bb770..e4c9f58f819 100755 --- a/examples/local/client.sh +++ b/examples/local/scripts/mysqlctl-up.sh @@ -14,20 +14,29 @@ # See the License for the specific language governing permissions and # limitations under the License. -# This is a wrapper script that sets up the environment for client.py. +# This is an example script that creates a single shard vttablet deployment. -set -e +source ./env.sh -hostname=`hostname -f` +cell=${CELL:-'test'} +uid=$TABLET_UID +mysql_port=$[17000 + $uid] +printf -v alias '%s-%010d' $cell $uid +printf -v tablet_dir 'vt_%010d' $uid -# We expect to find zk-client-conf.json in the same folder as this script. -script_root=`dirname "${BASH_SOURCE}"` +mkdir -p $VTDATAROOT/backups -# Set up environment. -for pkg in `find $VTROOT/dist -name site-packages`; do - export PYTHONPATH=$pkg:$PYTHONPATH -done +echo "Starting MySQL for tablet $alias..." +action="init" -export PYTHONPATH=$VTROOT/py-vtdb:$PYTHONPATH +if [ -d $VTDATAROOT/$tablet_dir ]; then + echo "Resuming from existing vttablet dir:" + echo " $VTDATAROOT/$tablet_dir" + action='start' +fi -exec env python $script_root/client.py $* +mysqlctl \ + -log_dir $VTDATAROOT/tmp \ + -tablet_uid $uid \ + -mysql_port $mysql_port \ + $action diff --git a/examples/local/scripts/vtctld-down.sh b/examples/local/scripts/vtctld-down.sh new file mode 100755 index 00000000000..d96fa3b927f --- /dev/null +++ b/examples/local/scripts/vtctld-down.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +# Copyright 2019 The Vitess Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# This is an example script that stops vtctld. + +source ./env.sh + +echo "Stopping vtctld..." +kill -9 `cat $VTDATAROOT/tmp/vtctld.pid` diff --git a/examples/kubernetes/kvtctl.sh b/examples/local/scripts/vtctld-up.sh similarity index 53% rename from examples/kubernetes/kvtctl.sh rename to examples/local/scripts/vtctld-up.sh index 5dcb6dc3730..662a234ae48 100755 --- a/examples/kubernetes/kvtctl.sh +++ b/examples/local/scripts/vtctld-up.sh @@ -14,17 +14,25 @@ # See the License for the specific language governing permissions and # limitations under the License. -# This is a script that uses kubectl to figure out the address for vtctld, -# and then runs vtctlclient with that address. +# This is an example script that starts vtctld. -set -e +source ./env.sh -script_root=`dirname "${BASH_SOURCE}"` -source $script_root/env.sh - -echo "Starting port forwarding to vtctld..." -start_vtctld_forward -trap stop_vtctld_forward EXIT - -vtctlclient -server 127.0.0.1:$vtctld_forward_port "$@" +cell=${CELL:-'test'} +grpc_port=15999 +echo "Starting vtctld..." +# shellcheck disable=SC2086 +vtctld \ + $TOPOLOGY_FLAGS \ + -cell $cell \ + -workflow_manager_init \ + -workflow_manager_use_election \ + -service_map 'grpc-vtctl' \ + -backup_storage_implementation file \ + -file_backup_storage_root $VTDATAROOT/backups \ + -log_dir $VTDATAROOT/tmp \ + -port $vtctld_web_port \ + -grpc_port $grpc_port \ + -pid_file $VTDATAROOT/tmp/vtctld.pid \ + > $VTDATAROOT/tmp/vtctld.out 2>&1 & diff --git a/examples/local/scripts/vtgate-down.sh b/examples/local/scripts/vtgate-down.sh new file mode 100755 index 00000000000..9da0a7179df --- /dev/null +++ b/examples/local/scripts/vtgate-down.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +# Copyright 2019 The Vitess Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# This is an example script that stops the instance started by vtgate-up.sh. + +source ./env.sh + +# Stop vtgate. +echo "Stopping vtgate..." +kill `cat $VTDATAROOT/tmp/vtgate.pid` diff --git a/examples/local/scripts/vtgate-up.sh b/examples/local/scripts/vtgate-up.sh new file mode 100755 index 00000000000..e3fe2d17f82 --- /dev/null +++ b/examples/local/scripts/vtgate-up.sh @@ -0,0 +1,58 @@ +#!/bin/bash + +# Copyright 2019 The Vitess Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# This is an example script that starts a single vtgate. + +source ./env.sh + +cell=${CELL:-'test'} +web_port=15001 +grpc_port=15991 +mysql_server_port=15306 +mysql_server_socket_path="/tmp/mysql.sock" + +# Start vtgate. +# shellcheck disable=SC2086 +vtgate \ + $TOPOLOGY_FLAGS \ + -log_dir $VTDATAROOT/tmp \ + -log_queries_to_file $VTDATAROOT/tmp/vtgate_querylog.txt \ + -port $web_port \ + -grpc_port $grpc_port \ + -mysql_server_port $mysql_server_port \ + -mysql_server_socket_path $mysql_server_socket_path \ + -cell $cell \ + -cells_to_watch $cell \ + -tablet_types_to_wait MASTER,REPLICA \ + -gateway_implementation discoverygateway \ + -service_map 'grpc-vtgateservice' \ + -pid_file $VTDATAROOT/tmp/vtgate.pid \ + -mysql_auth_server_impl none \ + > $VTDATAROOT/tmp/vtgate.out 2>&1 & + +# Block waiting for vtgate to be listening +# Not the same as healthy + +echo "Waiting for vtgate to be up..." +while true; do + curl -I "http://$hostname:$web_port/debug/status" >/dev/null 2>&1 && break + sleep 0.1 +done; +echo "vtgate is up!" + +echo "Access vtgate at http://$hostname:$web_port/debug/status" + +disown -a diff --git a/examples/local/scripts/vttablet-down.sh b/examples/local/scripts/vttablet-down.sh new file mode 100755 index 00000000000..47b881b9793 --- /dev/null +++ b/examples/local/scripts/vttablet-down.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +# Copyright 2019 The Vitess Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# This is an example script that stops the mysqld and vttablet instances +# created by vttablet-up.sh + +source ./env.sh + +printf -v tablet_dir 'vt_%010d' $TABLET_UID +pid=`cat $VTDATAROOT/$tablet_dir/vttablet.pid` + +kill $pid + +# Wait for vttablet to die. +while ps -p $pid > /dev/null; do sleep 1; done + + diff --git a/examples/local/scripts/vttablet-up.sh b/examples/local/scripts/vttablet-up.sh new file mode 100755 index 00000000000..c3f66fa806d --- /dev/null +++ b/examples/local/scripts/vttablet-up.sh @@ -0,0 +1,69 @@ +#!/bin/bash + +# Copyright 2019 The Vitess Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +source ./env.sh + +cell=${CELL:-'test'} +keyspace=${KEYSPACE:-'test_keyspace'} +shard=${SHARD:-'0'} +uid=$TABLET_UID +mysql_port=$[17000 + $uid] +port=$[15000 + $uid] +grpc_port=$[16000 + $uid] +printf -v alias '%s-%010d' $cell $uid +printf -v tablet_dir 'vt_%010d' $uid +tablet_hostname='' +printf -v tablet_logfile 'vttablet_%010d_querylog.txt' $uid + +tablet_type=replica +if [[ "${uid: -1}" -gt 1 ]]; then + tablet_type=rdonly +fi + +echo "Starting vttablet for $alias..." +# shellcheck disable=SC2086 +vttablet \ + $TOPOLOGY_FLAGS \ + -log_dir $VTDATAROOT/tmp \ + -log_queries_to_file $VTDATAROOT/tmp/$tablet_logfile \ + -tablet-path $alias \ + -tablet_hostname "$tablet_hostname" \ + -init_keyspace $keyspace \ + -init_shard $shard \ + -init_tablet_type $tablet_type \ + -health_check_interval 5s \ + -enable_semi_sync \ + -enable_replication_reporter \ + -backup_storage_implementation file \ + -file_backup_storage_root $VTDATAROOT/backups \ + -restore_from_backup \ + -port $port \ + -grpc_port $grpc_port \ + -service_map 'grpc-queryservice,grpc-tabletmanager,grpc-updatestream' \ + -pid_file $VTDATAROOT/$tablet_dir/vttablet.pid \ + -vtctld_addr http://$hostname:$vtctld_web_port/ \ + > $VTDATAROOT/$tablet_dir/vttablet.out 2>&1 & + +# Block waiting for the tablet to be listening +# Not the same as healthy + +for i in $(seq 0 300); do + curl -I "http://$hostname:$port/debug/status" >/dev/null 2>&1 && break + sleep 0.1 +done + +# check one last time +curl -I "http://$hostname:$port/debug/status" || fail "tablet could not be started!" diff --git a/examples/local/scripts/zk-down.sh b/examples/local/scripts/zk-down.sh new file mode 100755 index 00000000000..18dd7933bc9 --- /dev/null +++ b/examples/local/scripts/zk-down.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +# Copyright 2019 The Vitess Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# This is an example script that stops the ZooKeeper servers started by zk-up.sh. + +source ./env.sh + +# Stop ZooKeeper servers. +echo "Stopping zk servers..." +for zkid in $zkids; do + zkctl -zk.myid $zkid -zk.cfg $zkcfg -log_dir $VTDATAROOT/tmp shutdown +done + diff --git a/examples/local/scripts/zk-up.sh b/examples/local/scripts/zk-up.sh new file mode 100755 index 00000000000..6671d1063a6 --- /dev/null +++ b/examples/local/scripts/zk-up.sh @@ -0,0 +1,62 @@ +#!/bin/bash + +# Copyright 2019 The Vitess Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# This is an example script that creates a quorum of ZooKeeper servers. + +source ./env.sh + +cell=${CELL:-'test'} + +# Start ZooKeeper servers. +# The "zkctl init" command won't return until the server is able to contact its +# peers, so we need to start them all in the background and then wait for them. +echo "Starting zk servers..." +for zkid in $zkids; do + action='init' + printf -v zkdir 'zk_%03d' $zkid + if [ -f $VTDATAROOT/$zkdir/myid ]; then + echo "Resuming from existing ZK data dir:" + echo " $VTDATAROOT/$zkdir" + action='start' + fi + zkctl -zk.myid $zkid -zk.cfg $zkcfg -log_dir $VTDATAROOT/tmp $action \ + > $VTDATAROOT/tmp/zkctl_$zkid.out 2>&1 & + pids[$zkid]=$! +done + +# Wait for all the zkctl commands to return. +echo "Waiting for zk servers to be ready..." + +for zkid in $zkids; do + if ! wait ${pids[$zkid]}; then + echo "ZK server number $zkid failed to start. See log:" + echo " $VTDATAROOT/tmp/zkctl_$zkid.out" + fi +done + +echo "Started zk servers." + +# Add the CellInfo description for the $CELL cell. +# If the node already exists, it's fine, means we used existing data. +set +e +# shellcheck disable=SC2086 +vtctl $TOPOLOGY_FLAGS AddCellInfo \ + -root /vitess/$cell \ + -server_address $ZK_SERVER \ + $cell +set -e + +echo "Configured zk servers." diff --git a/examples/local/vtctld-up.sh b/examples/local/vtctld-up.sh deleted file mode 100755 index b1965e06baf..00000000000 --- a/examples/local/vtctld-up.sh +++ /dev/null @@ -1,53 +0,0 @@ -#!/bin/bash - -# Copyright 2019 The Vitess Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# This is an example script that starts vtctld. - -set -e - -cell=${CELL:-'test'} -grpc_port=15999 - -script_root=`dirname "${BASH_SOURCE}"` -source $script_root/env.sh - -optional_auth_args='' -if [ "$1" = "--enable-grpc-static-auth" ]; -then - echo "Enabling Auth with static authentication in grpc" - optional_auth_args='-grpc_auth_static_client_creds ./grpc_static_client_auth.json ' -fi - -echo "Starting vtctld..." -# shellcheck disable=SC2086 -vtctld \ - $TOPOLOGY_FLAGS \ - -cell $cell \ - -workflow_manager_init \ - -workflow_manager_use_election \ - -service_map 'grpc-vtctl' \ - -backup_storage_implementation file \ - -file_backup_storage_root $VTDATAROOT/backups \ - -log_dir $VTDATAROOT/tmp \ - -port $vtctld_web_port \ - -grpc_port $grpc_port \ - -pid_file $VTDATAROOT/tmp/vtctld.pid \ - $optional_auth_args \ - > $VTDATAROOT/tmp/vtctld.out 2>&1 & -disown -a - -echo "Access vtctld web UI at http://$hostname:$vtctld_web_port" -echo "Send commands with: vtctlclient -server $hostname:$grpc_port ..." diff --git a/examples/local/vtgate-up.sh b/examples/local/vtgate-up.sh deleted file mode 100755 index e4fb1dd5c10..00000000000 --- a/examples/local/vtgate-up.sh +++ /dev/null @@ -1,105 +0,0 @@ -#!/bin/bash - -# Copyright 2019 The Vitess Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# This is an example script that starts a single vtgate. - -set -e - -cell=${CELL:-'test'} -web_port=15001 -grpc_port=15991 -mysql_server_port=15306 -mysql_server_socket_path="/tmp/mysql.sock" - -script_root=`dirname "${BASH_SOURCE}"` -source $script_root/env.sh - -# When this script is run with the argument "--enable-tls", then it will generate signed certs and -# configure VTGate to accept only TLS connections with client authentication. This allows for end-to-end -# SSL testing (see also the "client_jdbc.sh" script). -optional_tls_args='' -if [ "$1" = "--enable-tls" ]; -then - echo "Enabling TLS with client authentication" - config_dir=../../java/grpc-client/src/test/resources - cert_dir=$VTDATAROOT/tls - rm -Rf $cert_dir - mkdir -p $cert_dir - - # Create CA - openssl genrsa -out $cert_dir/ca-key.pem - openssl req -new -x509 -nodes -days 3600 -batch -config $config_dir/ca.config -key $cert_dir/ca-key.pem -out $cert_dir/ca-cert.pem - - # Create server-side signed cert - openssl req -newkey rsa:2048 -days 3600 -nodes -batch -config $config_dir/cert.config -keyout $cert_dir/server-key.pem -out $cert_dir/server-req.pem - openssl x509 -req -in $cert_dir/server-req.pem -days 3600 -CA $cert_dir/ca-cert.pem -CAkey $cert_dir/ca-key.pem -set_serial 01 -out $cert_dir/server-cert.pem - - # Create client-side signed cert - openssl req -newkey rsa:2048 -days 3600 -nodes -batch -config $config_dir/cert.config -keyout $cert_dir/client-key.pem -out $cert_dir/client-req.pem - openssl x509 -req -in $cert_dir/client-req.pem -days 3600 -CA $cert_dir/ca-cert.pem -CAkey $cert_dir/ca-key.pem -set_serial 02 -out $cert_dir/client-cert.pem - - optional_tls_args="-grpc_cert $cert_dir/server-cert.pem -grpc_key $cert_dir/server-key.pem -grpc_ca $cert_dir/ca-cert.pem" -fi - -optional_auth_args='-mysql_auth_server_impl none' -optional_grpc_auth_args='' -if [ "$1" = "--enable-grpc-static-auth" ]; -then - echo "Enabling Auth with static authentication in grpc" - optional_grpc_auth_args='-grpc_auth_static_client_creds ./grpc_static_client_auth.json' -fi - -if [ "$1" = "--enable-mysql-static-auth" ]; -then - echo "Enabling Auth with mysql static authentication" - optional_auth_args='-mysql_auth_server_static_file ./mysql_auth_server_static_creds.json' -fi - -# Start vtgate. -# shellcheck disable=SC2086 -vtgate \ - $TOPOLOGY_FLAGS \ - -log_dir $VTDATAROOT/tmp \ - -log_queries_to_file $VTDATAROOT/tmp/vtgate_querylog.txt \ - -port $web_port \ - -grpc_port $grpc_port \ - -mysql_server_port $mysql_server_port \ - -mysql_server_socket_path $mysql_server_socket_path \ - -cell $cell \ - -cells_to_watch $cell \ - -tablet_types_to_wait MASTER,REPLICA \ - -gateway_implementation discoverygateway \ - -service_map 'grpc-vtgateservice' \ - -pid_file $VTDATAROOT/tmp/vtgate.pid \ - $optional_auth_args \ - $optional_grpc_auth_args \ - $optional_tls_args \ - > $VTDATAROOT/tmp/vtgate.out 2>&1 & - -# Block waiting for vtgate to be listening -# Not the same as healthy - -echo "Waiting for vtgate to be up..." -while true; do - curl -I "http://$hostname:$web_port/debug/status" >/dev/null 2>&1 && break - sleep 0.1 -done; -echo "vtgate is up!" - -echo "Access vtgate at http://$hostname:$web_port/debug/status" - -disown -a - diff --git a/examples/local/vttablet-down.sh b/examples/local/vttablet-down.sh deleted file mode 100755 index 44aae662bd0..00000000000 --- a/examples/local/vttablet-down.sh +++ /dev/null @@ -1,53 +0,0 @@ -#!/bin/bash - -# Copyright 2019 The Vitess Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# This is an example script that stops the mysqld and vttablet instances -# created by vttablet-up.sh - -cell=${CELL:-'test'} -uid_base=${UID_BASE:-'100'} - -script_root=`dirname "${BASH_SOURCE}"` -source $script_root/env.sh - -# Stop 3 vttablets by default. -# Pass a list of UID indices on the command line to override. -uids=${@:-'0 1 2'} - -wait_pids='' - -for uid_index in $uids; do - uid=$[$uid_base + $uid_index] - printf -v alias '%s-%010d' $cell $uid - printf -v tablet_dir 'vt_%010d' $uid - - echo "Stopping vttablet for $alias..." - pid=`cat $VTDATAROOT/$tablet_dir/vttablet.pid` - kill $pid - wait_pids="$wait_pids $pid" - - echo "Stopping MySQL for tablet $alias..." - mysqlctl \ - -tablet_uid $uid \ - shutdown & -done - -# Wait for vttablets to die. -while ps -p $wait_pids > /dev/null; do sleep 1; done - -# Wait for 'mysqlctl shutdown' commands to finish. -wait - diff --git a/examples/local/vttablet-up.sh b/examples/local/vttablet-up.sh deleted file mode 100755 index 4914a65493b..00000000000 --- a/examples/local/vttablet-up.sh +++ /dev/null @@ -1,161 +0,0 @@ -#!/bin/bash - -# Copyright 2019 The Vitess Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# This is an example script that creates a single shard vttablet deployment. - -set -e - -cell=${CELL:-'test'} -keyspace=${KEYSPACE:-'test_keyspace'} -shard=${SHARD:-'0'} -uid_base=${UID_BASE:-'100'} -port_base=$[15000 + $uid_base] -grpc_port_base=$[16000 + $uid_base] -mysql_port_base=$[17000 + $uid_base] -tablet_hostname='' - -# Travis hostnames are too long for MySQL, so we use IP. -# Otherwise, blank hostname means the tablet auto-detects FQDN. -if [ "$TRAVIS" == true ]; then - tablet_hostname=`hostname -i` -fi - -script_root=`dirname "${BASH_SOURCE}"` -source $script_root/env.sh - -mkdir -p $VTDATAROOT/backups - -# Start 3 vttablets by default. -# Pass TABLETS_UIDS indices as env variable to change -uids=${TABLETS_UIDS:-'0 1 2'} - -# Start all mysqlds in background. -for uid_index in $uids; do - uid=$[$uid_base + $uid_index] - mysql_port=$[$mysql_port_base + $uid_index] - printf -v alias '%s-%010d' $cell $uid - printf -v tablet_dir 'vt_%010d' $uid - - export KEYSPACE=$keyspace - export SHARD=$shard - export TABLET_ID=$alias - export TABLET_DIR=$tablet_dir - export MYSQL_PORT=$mysql_port - - tablet_type=replica - if [[ $uid_index -gt 1 ]]; then - tablet_type=rdonly - fi - - export TABLET_TYPE=$tablet_type - - echo "Starting MySQL for tablet $alias..." - action="init" - if [ -d $VTDATAROOT/$tablet_dir ]; then - echo "Resuming from existing vttablet dir:" - echo " $VTDATAROOT/$tablet_dir" - action='start' - fi - - set +e - - mysqlctl \ - -log_dir $VTDATAROOT/tmp \ - -tablet_uid $uid \ - -mysql_port $mysql_port \ - $action - - err=$? - if [[ $err -ne 0 ]]; then - fail "This script fails to start mysqld, possibly due to apparmor or selinux protection. - Utilities to help investigate: - apparmor: \"sudo aa-status\" - selinux: \"sudo sestatus\" - Please disable if so indicated. - You may also need to empty your \$VTDATAROOT to start clean." - fi - - set -e - -done - -# Wait for all mysqld to start up. -wait - -optional_auth_args='' -if [ "$1" = "--enable-grpc-static-auth" ]; -then - echo "Enabling Auth with static authentication in grpc" - optional_auth_args='-grpc_auth_mode static -grpc_auth_static_password_file ./grpc_static_auth.json -grpc_auth_static_client_creds ./grpc_static_client_auth.json' -fi - -# Start all vttablets in background. -for uid_index in $uids; do - uid=$[$uid_base + $uid_index] - port=$[$port_base + $uid_index] - grpc_port=$[$grpc_port_base + $uid_index] - printf -v alias '%s-%010d' $cell $uid - printf -v tablet_dir 'vt_%010d' $uid - printf -v tablet_logfile 'vttablet_%010d_querylog.txt' $uid - tablet_type=replica - if [[ $uid_index -gt 1 ]]; then - tablet_type=rdonly - fi - - echo "Starting vttablet for $alias..." - # shellcheck disable=SC2086 - vttablet \ - $TOPOLOGY_FLAGS \ - -log_dir $VTDATAROOT/tmp \ - -log_queries_to_file $VTDATAROOT/tmp/$tablet_logfile \ - -tablet-path $alias \ - -tablet_hostname "$tablet_hostname" \ - -init_keyspace $keyspace \ - -init_shard $shard \ - -init_tablet_type $tablet_type \ - -health_check_interval 5s \ - -enable_semi_sync \ - -enable_replication_reporter \ - -backup_storage_implementation file \ - -file_backup_storage_root $VTDATAROOT/backups \ - -restore_from_backup \ - -port $port \ - -grpc_port $grpc_port \ - -service_map 'grpc-queryservice,grpc-tabletmanager,grpc-updatestream' \ - -pid_file $VTDATAROOT/$tablet_dir/vttablet.pid \ - -vtctld_addr http://$hostname:$vtctld_web_port/ \ - $optional_auth_args \ - > $VTDATAROOT/$tablet_dir/vttablet.out 2>&1 & - - echo "Access tablet $alias at http://$hostname:$port/debug/status" -done - -# Block waiting for all tablets to be listening -# Not the same as healthy - -echo "Waiting for tablets to be listening..." -for uid_index in $uids; do - port=$[$port_base + $uid_index] - for i in $(seq 0 300); do - curl -I "http://$hostname:$port/debug/status" >/dev/null 2>&1 && break - sleep 0.1 - done; - # check one last time - curl -I "http://$hostname:$port/debug/status" || fail "tablets could not be started!" -done; -echo "Tablets up!" - -disown -a diff --git a/go.mod b/go.mod index e3d537a1fbe..2d2724445b2 100644 --- a/go.mod +++ b/go.mod @@ -1,69 +1,62 @@ module vitess.io/vitess -go 1.12 +go 1.13 require ( cloud.google.com/go v0.45.1 - github.com/Bowery/prompt v0.0.0-20190419144237-972d0ceb96f5 // indirect + github.com/Azure/azure-storage-blob-go v0.8.0 + github.com/Azure/go-autorest/autorest/adal v0.8.1 // indirect github.com/GeertJohan/go.rice v1.0.0 + github.com/PuerkitoBio/goquery v1.5.1 github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878 // indirect github.com/aws/aws-sdk-go v1.28.8 - github.com/boltdb/bolt v1.3.1 // indirect github.com/bombsimon/wsl v1.2.8 // indirect + github.com/buger/jsonparser v1.0.0 github.com/cespare/xxhash/v2 v2.1.1 - github.com/cockroachdb/cmux v0.0.0-20170110192607-30d10be49292 // indirect github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd // indirect github.com/coreos/etcd v3.3.10+incompatible github.com/coreos/go-semver v0.3.0 // indirect github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f // indirect + github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f // indirect github.com/corpix/uarand v0.1.1 // indirect github.com/dchest/safefile v0.0.0-20151022103144-855e8d98f185 // indirect github.com/evanphx/json-patch v4.5.0+incompatible github.com/go-critic/go-critic v0.4.0 // indirect - github.com/go-ini/ini v1.12.0 // indirect github.com/go-sql-driver/mysql v1.5.0 github.com/gogo/protobuf v1.3.1 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 // indirect github.com/golang/mock v1.3.1 github.com/golang/protobuf v1.3.2 - github.com/golang/snappy v0.0.0-20170215233205-553a64147049 - github.com/golangci/gocyclo v0.0.0-20180528144436-0a533e8fa43d // indirect - github.com/golangci/golangci-lint v1.21.0 // indirect - github.com/golangci/revgrep v0.0.0-20180812185044-276a5c0a1039 // indirect + github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db + github.com/google/go-cmp v0.4.0 github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf // indirect github.com/gorilla/websocket v1.4.0 github.com/gostaticanalysis/analysisutil v0.0.3 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.1.0 github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 github.com/hashicorp/consul v1.5.1 + github.com/hashicorp/consul/api v1.1.0 github.com/hashicorp/go-msgpack v0.5.5 // indirect - github.com/hashicorp/go-rootcerts v0.0.0-20160503143440-6bb64b370b90 // indirect - github.com/hashicorp/go-uuid v1.0.1 // indirect github.com/hashicorp/golang-lru v0.5.3 // indirect - github.com/hashicorp/memberlist v0.1.4 // indirect - github.com/hashicorp/serf v0.0.0-20161207011743-d3a67ab21bc8 // indirect github.com/icrowley/fake v0.0.0-20180203215853-4178557ae428 + github.com/klauspost/compress v1.10.9 // indirect github.com/klauspost/crc32 v1.2.0 // indirect - github.com/klauspost/pgzip v1.2.0 + github.com/klauspost/pgzip v1.2.4 github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect github.com/krishicks/yaml-patch v0.0.10 github.com/mattn/go-isatty v0.0.11 // indirect github.com/mattn/go-runewidth v0.0.1 // indirect github.com/minio/minio-go v0.0.0-20190131015406-c8a261de75c1 - github.com/mitchellh/go-testing-interface v1.0.0 // indirect github.com/olekukonko/tablewriter v0.0.0-20160115111002-cca8bbc07984 github.com/opentracing-contrib/go-grpc v0.0.0-20180928155321-4b5a12d3ff02 github.com/opentracing/opentracing-go v1.1.0 github.com/pborman/uuid v1.2.0 - github.com/pelletier/go-toml v1.6.0 // indirect github.com/philhofer/fwd v1.0.0 // indirect github.com/pires/go-proxyproto v0.0.0-20191211124218-517ecdf5bb2b github.com/pkg/errors v0.8.1 - github.com/prometheus/client_golang v1.1.0 - github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 // indirect - github.com/prometheus/common v0.7.0 - github.com/prometheus/procfs v0.0.5 // indirect + github.com/prometheus/client_golang v1.4.1 + github.com/prometheus/common v0.9.1 github.com/satori/go.uuid v0.0.0-20160713180306-0aa62d5ddceb // indirect github.com/securego/gosec v0.0.0-20191217083152-cb4f343eaff1 // indirect github.com/spf13/afero v1.2.2 // indirect @@ -72,18 +65,19 @@ require ( github.com/spf13/viper v1.6.1 // indirect github.com/stretchr/testify v1.4.0 github.com/tchap/go-patricia v0.0.0-20160729071656-dd168db6051b + github.com/tebeka/selenium v0.9.9 github.com/tinylib/msgp v1.1.1 // indirect + github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 // indirect github.com/uber-go/atomic v1.4.0 // indirect github.com/uber/jaeger-client-go v2.16.0+incompatible github.com/uber/jaeger-lib v2.0.0+incompatible // indirect github.com/ugorji/go v1.1.7 // indirect github.com/uudashr/gocognit v1.0.1 // indirect github.com/z-division/go-zookeeper v0.0.0-20190128072838-6d7457066b9b - golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd + golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413 golang.org/x/lint v0.0.0-20190409202823-959b441ac422 - golang.org/x/net v0.0.0-20190926025831-c00fd9afed17 + golang.org/x/net v0.0.0-20200202094626-16171245cfb2 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 - golang.org/x/sys v0.0.0-20191218084908-4a24b4065292 // indirect golang.org/x/text v0.3.2 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 golang.org/x/tools v0.0.0-20191219041853-979b82bfef62 @@ -91,9 +85,10 @@ require ( google.golang.org/genproto v0.0.0-20190926190326-7ee9db18f195 // indirect google.golang.org/grpc v1.24.0 gopkg.in/DataDog/dd-trace-go.v1 v1.17.0 - gopkg.in/asn1-ber.v1 v1.0.0-20150924051756-4e86f4367175 // indirect gopkg.in/ldap.v2 v2.5.0 honnef.co/go/tools v0.0.1-2019.2.3 mvdan.cc/unparam v0.0.0-20191111180625-960b1ec0f2c2 // indirect + sigs.k8s.io/yaml v1.2.0 sourcegraph.com/sqs/pbtypes v1.0.0 // indirect + vitess.io/vitess/examples/are-you-alive v0.0.0-20200302220708-6b7695375ce9 // indirect ) diff --git a/go.sum b/go.sum index 12ffff34b90..3dca61ecf6f 100644 --- a/go.sum +++ b/go.sum @@ -1,29 +1,65 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.41.0/go.mod h1:OauMR7DV8fzvZIl2qg6rkaIhD/vmgk4iwEw/h6ercmg= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1 h1:lRi0CHyU+ytlvylOlFKKq0af6JncuyoRh1J+QJBqQx0= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= -github.com/Bowery/prompt v0.0.0-20190419144237-972d0ceb96f5 h1:7tNlRGC3pUEPKS3DwgX5L0s+cBloaq/JBoi9ceN1MCM= -github.com/Bowery/prompt v0.0.0-20190419144237-972d0ceb96f5/go.mod h1:4/6eNcqZ09BZ9wLK3tZOjBA1nDj+B0728nlX5YRlSmQ= +github.com/Azure/azure-pipeline-go v0.2.1 h1:OLBdZJ3yvOn2MezlWvbrBMTEUQC72zAftRZOMdj5HYo= +github.com/Azure/azure-pipeline-go v0.2.1/go.mod h1:UGSo8XybXnIGZ3epmeBw7Jdz+HiUVpqIlpz/HKHylF4= +github.com/Azure/azure-sdk-for-go v16.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= +github.com/Azure/azure-storage-blob-go v0.8.0 h1:53qhf0Oxa0nOjgbDeeYPUeyiNmafAFEY95rZLK0Tj6o= +github.com/Azure/azure-storage-blob-go v0.8.0/go.mod h1:lPI3aLPpuLTeUwh1sViKXFxwl2B6teiRqI0deQUvsw0= +github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= +github.com/Azure/go-autorest v10.7.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= +github.com/Azure/go-autorest v10.15.3+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= +github.com/Azure/go-autorest/autorest v0.9.0 h1:MRvx8gncNaXJqOoLmhNjUAKh33JJF8LyxPhomEtOsjs= +github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= +github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0= +github.com/Azure/go-autorest/autorest/adal v0.8.1 h1:pZdL8o72rK+avFWl+p9nE8RWi1JInZrWJYlnpfXJwHk= +github.com/Azure/go-autorest/autorest/adal v0.8.1/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q= +github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA= +github.com/Azure/go-autorest/autorest/date v0.2.0 h1:yW+Zlqf26583pE43KhfnhFcdmSWlm5Ew6bxipnr/tbM= +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/logger v0.1.0 h1:ruG4BSDXONFRrZZJ2GUXDiUyVpayPmb1GnWeHDdaNKY= +github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= +github.com/Azure/go-autorest/tracing v0.5.0 h1:TRn4WjSnkcSy5AEG3pnbtFSwNtwzjr4VYyQflFE619k= +github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802 h1:1BDTz0u9nC3//pOCMdNH+CiXJVYJh5UQNCOBG7jbELc= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/BurntSushi/xgbutil v0.0.0-20160919175755-f7c97cef3b4e h1:4ZrkT/RzpnROylmoQL57iVUL57wGKTR5O6KpVnbm2tA= +github.com/BurntSushi/xgbutil v0.0.0-20160919175755-f7c97cef3b4e/go.mod h1:uw9h2sd4WWHOPdJ13MQpwK5qYWKYDumDqxWWIknEQ+k= +github.com/DataDog/datadog-go v0.0.0-20160329135253-cc2f4770f4d6/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/DataDog/datadog-go v2.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/GeertJohan/go.incremental v1.0.0 h1:7AH+pY1XUgQE4Y1HcXYaMqAI0m9yrFqo/jt0CW30vsg= github.com/GeertJohan/go.incremental v1.0.0/go.mod h1:6fAjUhbVuX1KcMD3c8TEgVUqmo4seqhv0i0kdATSkM0= github.com/GeertJohan/go.rice v1.0.0 h1:KkI6O9uMaQU3VEKaj01ulavtF7o1fWT7+pk/4voiMLQ= github.com/GeertJohan/go.rice v1.0.0/go.mod h1:eH6gbSOAUv07dQuZVnBmoDP8mgsM1rtixis4Tib9if0= +github.com/Jeffail/gabs v1.1.0/go.mod h1:6xMvQMK4k33lb7GUUpaAPh6nKMmemQeg5d4gn7/bOXc= github.com/Masterminds/glide v0.13.2/go.mod h1:STyF5vcenH/rUqTEv+/hBXlSTo7KYwg2oc2f4tzPWic= github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= github.com/Masterminds/vcs v1.13.0/go.mod h1:N09YCmOQr6RLxC6UNHzuVwAdodYbbnycGHSmwVJjcKA= +github.com/Microsoft/go-winio v0.4.3/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= +github.com/NYTimes/gziphandler v1.0.1/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= +github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OpenPeeDeeP/depguard v1.0.1 h1:VlW4R6jmBIv3/u1JNlawEvJMM4J+dPORPaZasQee8Us= github.com/OpenPeeDeeP/depguard v1.0.1/go.mod h1:xsIw86fROiiwelg+jB2uM9PiKihMMmUx/1V+TNhjQvM= +github.com/PuerkitoBio/goquery v1.5.1 h1:PSPBGne8NIUWw+/7vFBV+kG2J/5MOjbzc7154OaKCSE= +github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc= +github.com/SAP/go-hdb v0.12.0/go.mod h1:etBT+FAi1t5k3K3tf5vQTnosgYmhDkRi8jEnQqCnxF0= +github.com/SermoDigital/jose v0.0.0-20180104203859-803625baeddc/go.mod h1:ARgCUhI1MHQH+ONky/PAtmVHQrP5JlGY0F3poXOp/fA= github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= +github.com/abdullin/seq v0.0.0-20160510034733-d5467c17e7af/go.mod h1:5Jv4cbFiHJMsVxt52+i0Ha45fjshj6wxYr1r19tB9bw= github.com/akavel/rsrc v0.8.0 h1:zjWn7ukO9Kc5Q62DOJCcxGpXC18RawVtYAGdz2aLlfw= github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= @@ -32,12 +68,20 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4 h1:Hs82Z41s6SdL1CELW+XaDYmOH4hkBN4/N9og/AsOv7E= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/andybalholm/cascadia v1.1.0 h1:BuuO6sSfQNFRu1LppgbD25Hr2vLYW25JvxHs5zzsLTo= +github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878 h1:EFSB7Zo9Eg91v7MJPVsifUysc/wPdN+NOnVe6bWbdBM= github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878/go.mod h1:3AMJUQhVx52RsWOnlkpikZr01T/yAVN2gn0861vByNg= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= +github.com/asaskevich/govalidator v0.0.0-20180319081651-7d2e70ef918f/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/aws/aws-sdk-go v0.0.0-20180223184012-ebef4262e06a h1:Ed33uJE74ksDaYfdY72gK7Cg//o2FgsqlqUfBW079T8= github.com/aws/aws-sdk-go v0.0.0-20180223184012-ebef4262e06a/go.mod h1:ZRmQr0FajVIyZ4ZzBYKG5P3ZqPz9IHG41ZoMu1ADI3k= +github.com/aws/aws-sdk-go v1.15.24/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= github.com/aws/aws-sdk-go v1.28.8 h1:kPGnElMdW0GDc54Giy1lcE/3gAr2Gzl6cMjYKoBNFhw= github.com/aws/aws-sdk-go v1.28.8/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0= @@ -45,17 +89,25 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24 github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/boltdb/bolt v1.3.1 h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4= +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/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= +github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= +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/bombsimon/wsl v1.2.5 h1:9gTOkIwVtoDZywvX802SDHokeX4kW1cKnV8ZTVAPkRs= -github.com/bombsimon/wsl v1.2.5/go.mod h1:43lEF/i0kpXbLCeDXL9LMT8c92HyBywXb0AsgMHYngM= -github.com/bombsimon/wsl v1.2.8 h1:b+E/W7koicKBZDU+vEsw/hnQTN8026Gv1eMZDLUU/Wc= github.com/bombsimon/wsl v1.2.8/go.mod h1:43lEF/i0kpXbLCeDXL9LMT8c92HyBywXb0AsgMHYngM= +github.com/buger/jsonparser v0.0.0-20200322175846-f7e751efca13 h1:+qUNY4VRkEH46bLUwxCyUU+iOGJMQBVibAaYzWiwWcg= +github.com/buger/jsonparser v0.0.0-20200322175846-f7e751efca13/go.mod h1:tgcrVJ81GPSF0mz+0nu1Xaz0fazGPrmmJfJtxjbHhUQ= +github.com/buger/jsonparser v1.0.0 h1:etJTGF5ESxjI0Ic2UaLQs2LQQpa8G9ykQScukbh4L8A= +github.com/buger/jsonparser v1.0.0/go.mod h1:tgcrVJ81GPSF0mz+0nu1Xaz0fazGPrmmJfJtxjbHhUQ= +github.com/cenkalti/backoff v2.1.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/circonus-labs/circonus-gometrics v0.0.0-20161109192337-d17a8420c36e/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= +github.com/circonus-labs/circonusllhist v0.0.0-20161110002650-365d370cc145/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cockroachdb/cmux v0.0.0-20170110192607-30d10be49292 h1:dzj1/xcivGjNPwwifh/dWTczkwcuqsXXFHY1X/TZMtw= @@ -63,9 +115,10 @@ github.com/cockroachdb/cmux v0.0.0-20170110192607-30d10be49292/go.mod h1:qRiX68m github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd h1:qMd81Ts1T2OTKmB4acZcyKaMtRnY5Y44NuXGX2GFJ1w= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= github.com/codegangsta/cli v1.20.0/go.mod h1:/qJNoX69yVSKu5o4jLyXAENLRyk1uhi7zkbQ3slBdOA= +github.com/containerd/continuity v0.0.0-20181203112020-004b46473808/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= +github.com/coredns/coredns v1.1.2/go.mod h1:zASH/MVDgR6XZTbxvOnsZfffS+31vg6Ackf/wo1+AM0= +github.com/coreos/bbolt v1.3.2 h1:wZwiHHUieZCquLkDL0B8UhzreNWsPHooDAG3q34zk0s= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= -github.com/coreos/etcd v0.0.0-20170626015032-703663d1f6ed h1:uycR38QXnpc8YtCCTsNnQfeq6nPQ55F4ld6/WtGAIlM= -github.com/coreos/etcd v0.0.0-20170626015032-703663d1f6ed/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/etcd v3.3.10+incompatible h1:jFneRYjIvLMLhDLCzuTuU4rSJUjRplcJQ7pD7MnhC04= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= @@ -86,17 +139,25 @@ github.com/daaku/go.zipexe v1.0.0/go.mod h1:z8IiR6TsVLEYKwXAoE/I+8ys/sDkgTzSL0CL github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dchest/safefile v0.0.0-20151022103144-855e8d98f185 h1:3T8ZyTDp5QxTx3NU48JVb2u+75xc040fofcBaN+6jPA= github.com/dchest/safefile v0.0.0-20151022103144-855e8d98f185/go.mod h1:cFRxtTwTOJkz2x3rQUNCYKWC93yP1VKjR8NUhqFxZNU= -github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= +github.com/denisenkom/go-mssqldb v0.0.0-20180620032804-94c9c97e8c9f/go.mod h1:xN/JuLBIz4bjkxNmByTiV1IbhfnYb6oo99phBn4Eqhc= +github.com/denverdino/aliyungo v0.0.0-20170926055100-d3308649c661/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0= github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/digitalocean/godo v1.1.1/go.mod h1:h6faOIcZ8lWIwNQ+DN7b3CgX4Kwby5T+nbpNqkUIozU= +github.com/digitalocean/godo v1.10.0/go.mod h1:h6faOIcZ8lWIwNQ+DN7b3CgX4Kwby5T+nbpNqkUIozU= +github.com/docker/go-connections v0.3.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= +github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/duosecurity/duo_api_golang v0.0.0-20190308151101-6c680f768e74/go.mod h1:UqXY1lYT/ERa4OEAywUqdok1T4RCRdArkhic1Opuavo= +github.com/elazarl/go-bindata-assetfs v0.0.0-20160803192304-e1a2a7ec64b0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4= +github.com/envoyproxy/go-control-plane v0.0.0-20180919002855-2137d9196328/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0= github.com/evanphx/json-patch v4.5.0+incompatible h1:ouOWdg56aJriqS0huScTkVXPC5IcNrDCXZ6OoTAWu7M= github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/structs v0.0.0-20180123065059-ebf56d35bba7/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= 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/ghodss/yaml v0.0.0-20161207003320-04f313413ffd h1:U3yHrYB7NWH2o3UFzJ1J+TknZqM9QQtF8KVIE6Qzrfs= @@ -108,51 +169,45 @@ github.com/go-critic/go-critic v0.4.0 h1:sXD3pix0wDemuPuSlrXpJNNYXlUiKiysLrtPVQm github.com/go-critic/go-critic v0.4.0/go.mod h1:7/14rZGnZbY6E38VEGk2kVhoq6itzc1E68facVDK23g= github.com/go-ini/ini v1.12.0 h1:K324HQuOp7fYRWIW84d39Y7MqlH/0JU9fImSXUJ2TWk= github.com/go-ini/ini v1.12.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= +github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-lintpack/lintpack v0.5.2 h1:DI5mA3+eKdWeJ40nU4d6Wc26qmdG8RCi/btYq0TuRN0= +github.com/go-ldap/ldap v3.0.2+incompatible/go.mod h1:qfd9rJvER9Q0/D/Sqn1DfHRoBp40uXYvFoEVrNEPqRc= github.com/go-lintpack/lintpack v0.5.2/go.mod h1:NwZuYi2nUHho8XEIZ6SIxihrnPoqBTDqfpXvXAN0sXM= 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-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= +github.com/go-sql-driver/mysql v0.0.0-20180618115901-749ddf1598b4/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-toolsmith/astcast v1.0.0 h1:JojxlmI6STnFVG9yOImLeGREv8W2ocNUM+iOhR6jE7g= +github.com/go-test/deep v1.0.1/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/go-toolsmith/astcast v1.0.0/go.mod h1:mt2OdQTeAQcY4DQgPSArJjHCcOwlX+Wl/kwN+LbLGQ4= -github.com/go-toolsmith/astcopy v1.0.0 h1:OMgl1b1MEpjFQ1m5ztEO06rz5CUd3oBv9RF7+DyvdG8= github.com/go-toolsmith/astcopy v1.0.0/go.mod h1:vrgyG+5Bxrnz4MZWPF+pI4R8h3qKRjjyvV/DSez4WVQ= github.com/go-toolsmith/astequal v0.0.0-20180903214952-dcb477bfacd6/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CYFJ99GVbS5lDKY= -github.com/go-toolsmith/astequal v1.0.0 h1:4zxD8j3JRFNyLN46lodQuqz3xdKSrur7U/sr0SDS/gQ= github.com/go-toolsmith/astequal v1.0.0/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CYFJ99GVbS5lDKY= github.com/go-toolsmith/astfmt v0.0.0-20180903215011-8f8ee99c3086/go.mod h1:mP93XdblcopXwlyN4X4uodxXQhldPGZbcEJIimQHrkg= -github.com/go-toolsmith/astfmt v1.0.0 h1:A0vDDXt+vsvLEdbMFJAUBI/uTbRw1ffOPnxsILnFL6k= github.com/go-toolsmith/astfmt v1.0.0/go.mod h1:cnWmsOAuq4jJY6Ct5YWlVLmcmLMn1JUPuQIHCY7CJDw= github.com/go-toolsmith/astinfo v0.0.0-20180906194353-9809ff7efb21/go.mod h1:dDStQCHtmZpYOmjRP/8gHHnCCch3Zz3oEgCdZVdtweU= github.com/go-toolsmith/astp v0.0.0-20180903215135-0af7e3c24f30/go.mod h1:SV2ur98SGypH1UjcPpCatrV5hPazG6+IfNHbkDXBRrk= -github.com/go-toolsmith/astp v1.0.0 h1:alXE75TXgcmupDsMK1fRAy0YUzLzqPVvBKoyWV+KPXg= github.com/go-toolsmith/astp v1.0.0/go.mod h1:RSyrtpVlfTFGDYRbrjyWP1pYu//tSFcvdYrA8meBmLI= github.com/go-toolsmith/pkgload v0.0.0-20181119091011-e9e65178eee8/go.mod h1:WoMrjiy4zvdS+Bg6z9jZH82QXwkcgCBX6nOfnmdaHks= github.com/go-toolsmith/pkgload v1.0.0/go.mod h1:5eFArkbO80v7Z0kdngIxsRXRMTaX4Ilcwuh3clNrQJc= -github.com/go-toolsmith/strparse v1.0.0 h1:Vcw78DnpCAKlM20kSbAyO4mPfJn/lyYA4BJUDxe2Jb4= github.com/go-toolsmith/strparse v1.0.0/go.mod h1:YI2nUKP9YGZnL/L1/DLFBfixrcjslWct4wyljWhSRy8= -github.com/go-toolsmith/typep v1.0.0 h1:zKymWyA1TRYvqYrYDrfEMZULyrhcnGY3x7LDKU2XQaA= github.com/go-toolsmith/typep v1.0.0/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2Ns5AIQkATU= -github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= -github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= -github.com/gofrs/flock v0.0.0-20190320160742-5135e617513b h1:ekuhfTjngPhisSjOJ0QWKpPQE8/rbknHaes6WVJj5Hw= -github.com/gofrs/flock v0.0.0-20190320160742-5135e617513b/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= +github.com/gocql/gocql v0.0.0-20180617115710-e06f8c1bcd78/go.mod h1:4Fw1eo5iaEhDUs8XyuhSVCVy52Jq3L+/3GJgYkwc+/0= +github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/protobuf v1.1.1/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= -github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 h1:ZgQEtGgCBiWRM39fZuwSd1LwSqqSW0hOdXCYYDX0R3I= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/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/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1 h1:qGJ6qTW+x6xX/my+8YUVl4WNpX9B7+/l2tRsHGZ7f2s= @@ -161,61 +216,38 @@ github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/snappy v0.0.0-20170215233205-553a64147049 h1:K9KHZbXKpGydfDN0aZrsoHpLJlZsBrGMFWbgLDGnPZk= github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2 h1:23T5iq8rbUYlhpt5DB4XJkc6BU31uODLD1o1gKvZmD0= -github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2/go.mod h1:k9Qvh+8juN+UKMCS/3jFtGICgW8O96FVaZsaxdzDkR4= -github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a h1:w8hkcTqaFpzKqonE9uMCefW1WDie15eSP/4MssdenaM= -github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a/go.mod h1:ryS0uhF+x9jgbj/N71xsEqODy9BN81/GonCZiOzirOk= -github.com/golangci/errcheck v0.0.0-20181223084120-ef45e06d44b6 h1:YYWNAGTKWhKpcLLt7aSj/odlKrSrelQwlovBpDuf19w= -github.com/golangci/errcheck v0.0.0-20181223084120-ef45e06d44b6/go.mod h1:DbHgvLiFKX1Sh2T1w8Q/h4NAI8MHIpzCdnBUDTXU3I0= -github.com/golangci/go-misc v0.0.0-20180628070357-927a3d87b613 h1:9kfjN3AdxcbsZBf8NjltjWihK2QfBBBZuv91cMFfDHw= -github.com/golangci/go-misc v0.0.0-20180628070357-927a3d87b613/go.mod h1:SyvUF2NxV+sN8upjjeVYr5W7tyxaT1JVtvhKhOn2ii8= -github.com/golangci/goconst v0.0.0-20180610141641-041c5f2b40f3 h1:pe9JHs3cHHDQgOFXJJdYkK6fLz2PWyYtP4hthoCMvs8= -github.com/golangci/goconst v0.0.0-20180610141641-041c5f2b40f3/go.mod h1:JXrF4TWy4tXYn62/9x8Wm/K/dm06p8tCKwFRDPZG/1o= -github.com/golangci/gocyclo v0.0.0-20180528134321-2becd97e67ee h1:J2XAy40+7yz70uaOiMbNnluTg7gyQhtGqLQncQh+4J8= -github.com/golangci/gocyclo v0.0.0-20180528134321-2becd97e67ee/go.mod h1:ozx7R9SIwqmqf5pRP90DhR2Oay2UIjGuKheCBCNwAYU= -github.com/golangci/gocyclo v0.0.0-20180528144436-0a533e8fa43d h1:pXTK/gkVNs7Zyy7WKgLXmpQ5bHTrq5GDsp8R9Qs67g0= -github.com/golangci/gocyclo v0.0.0-20180528144436-0a533e8fa43d/go.mod h1:ozx7R9SIwqmqf5pRP90DhR2Oay2UIjGuKheCBCNwAYU= -github.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a h1:iR3fYXUjHCR97qWS8ch1y9zPNsgXThGwjKPrYfqMPks= -github.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a/go.mod h1:9qCChq59u/eW8im404Q2WWTrnBUQKjpNYKMbU4M7EFU= -github.com/golangci/golangci-lint v1.21.0 h1:HxAxpR8Z0M8omihvQdsD3PF0qPjlqYqp2vMJzstoKeI= -github.com/golangci/golangci-lint v1.21.0/go.mod h1:phxpHK52q7SE+5KpPnti4oZTdFCEsn/tKN+nFvCKXfk= -github.com/golangci/ineffassign v0.0.0-20190609212857-42439a7714cc h1:gLLhTLMk2/SutryVJ6D4VZCU3CUqr8YloG7FPIBWFpI= -github.com/golangci/ineffassign v0.0.0-20190609212857-42439a7714cc/go.mod h1:e5tpTHCfVze+7EpLEozzMB3eafxo2KT5veNg1k6byQU= -github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0 h1:MfyDlzVjl1hoaPzPD4Gpb/QgoRfSBR0jdhwGyAWwMSA= -github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0/go.mod h1:66R6K6P6VWk9I95jvqGxkqJxVWGFy9XlDwLwVz1RCFg= -github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca h1:kNY3/svz5T29MYHubXix4aDDuE3RWHkPvopM/EDv/MA= -github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca/go.mod h1:tvlJhZqDe4LMs4ZHD0oMUlt9G2LWuDGoisJTBzLMV9o= -github.com/golangci/misspell v0.0.0-20180809174111-950f5d19e770 h1:EL/O5HGrF7Jaq0yNhBLucz9hTuRzj2LdwGBOaENgxIk= -github.com/golangci/misspell v0.0.0-20180809174111-950f5d19e770/go.mod h1:dEbvlSfYbMQDtrpRMQU675gSDLDNa8sCPPChZ7PhiVA= -github.com/golangci/prealloc v0.0.0-20180630174525-215b22d4de21 h1:leSNB7iYzLYSSx3J/s5sVf4Drkc68W2wm4Ixh/mr0us= -github.com/golangci/prealloc v0.0.0-20180630174525-215b22d4de21/go.mod h1:tf5+bzsHdTM0bsB7+8mt0GUMvjCgwLpTapNZHU8AajI= -github.com/golangci/revgrep v0.0.0-20180526074752-d9c87f5ffaf0 h1:HVfrLniijszjS1aiNg8JbBMO2+E1WIQ+j/gL4SQqGPg= -github.com/golangci/revgrep v0.0.0-20180526074752-d9c87f5ffaf0/go.mod h1:qOQCunEYvmd/TLamH+7LlVccLvUH5kZNhbCgTHoBbp4= -github.com/golangci/revgrep v0.0.0-20180812185044-276a5c0a1039 h1:XQKc8IYQOeRwVs36tDrEmTgDgP88d5iEURwpmtiAlOM= -github.com/golangci/revgrep v0.0.0-20180812185044-276a5c0a1039/go.mod h1:qOQCunEYvmd/TLamH+7LlVccLvUH5kZNhbCgTHoBbp4= -github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 h1:zwtduBRr5SSWhqsYNgcuWO2kFlpdOZbP0+yRjmvPGys= -github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4/go.mod h1:Izgrg8RkN3rCIMLGE9CyYmU9pY2Jer6DgANEnZ/L/cQ= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pOkfl+p/TAqKOfFu+7KPlMVpok/w= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/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 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +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-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= +github.com/google/go-github/v27 v27.0.4/go.mod h1:/0Gr8pJ55COkmv+S/yPKCczSkUPIM/LnFyubufRNIS0= +github.com/google/go-querystring v0.0.0-20170111101155-53e6ce116135/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= 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= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf h1:7+FW5aGwISbqUtkfmIpZJGRgNFg2ioYPvFaUxdqpDsg= github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf/go.mod h1:RpwtwJQFrIEPstU94h88MWPXP2ektJZ8cZ0YntAmXiE= 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/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/googleapis/gnostic v0.2.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/gophercloud/gophercloud v0.0.0-20180828235145-f29afc2cceca/go.mod h1:3WdhXV3rUYy9p6AUW8d94kr+HS62Y4VL9mBnFxsD8q4= +github.com/gopherjs/gopherjs v0.0.0-20180825215210-0210a2f0f73c/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e h1:JKmoR8x90Iww1ks85zJ1lfDGgIiMDuIptTOhJq+zKyg= github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= @@ -223,10 +255,9 @@ github.com/gorilla/websocket v0.0.0-20160912153041-2d1e4548da23 h1:NqeYYy/q+eU5b github.com/gorilla/websocket v0.0.0-20160912153041-2d1e4548da23/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3 h1:JVnpOZS+qxli+rgVl98ILOXVNbW+kb5wcxeGx8ShUIw= -github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE= -github.com/gostaticanalysis/analysisutil v0.0.3 h1:iwp+5/UAyzQSFgQ4uR2sni99sJ8Eo9DEacKWM5pekIg= github.com/gostaticanalysis/analysisutil v0.0.3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE= +github.com/gotestyourself/gotestyourself v2.2.0+incompatible/go.mod h1:zZKM6oeNM8k+FRljX1mnzVYeS8wiGgQyvST1/GafPbY= +github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.1.0 h1:THDBEeQ9xZ8JEaCLyLQqXMMdRqNr0QAUJTIkQAUtFjg= github.com/grpc-ecosystem/go-grpc-middleware v1.1.0/go.mod h1:f5nM7jw/oeRSadq3xCzHAvxcr8HZnzsqU6ILg/0NiiE= @@ -235,77 +266,116 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgf github.com/grpc-ecosystem/grpc-gateway v0.0.0-20161128002007-199c40a060d1 h1:HpW72214zD3cWQsV9DW4Sd9piuuw8rPmE4/TAjTgYIE= github.com/grpc-ecosystem/grpc-gateway v0.0.0-20161128002007-199c40a060d1/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4= github.com/hashicorp/consul v1.4.0 h1:PQTW4xCuAExEiSbhrsFsikzbW5gVBoi74BjUvYFyKHw= github.com/hashicorp/consul v1.4.0/go.mod h1:mFrjN1mfidgJfYP1xrJCF+AfRhr6Eaqhb2+sfyn/OOI= +github.com/hashicorp/consul v1.5.1 h1:p7tRmQ4m3ZMYkGQkuyjLXKbdU1weeumgZFqZOvw7o4c= +github.com/hashicorp/consul v1.5.1/go.mod h1:QsmgXh2YA9Njv6y3/FHXqHYhsMye++3oBoAZ6SR8R8I= +github.com/hashicorp/consul/api v1.1.0 h1:BNQPM9ytxj6jbjjdRPioQ94T6YXriSopn0i8COv6SRA= +github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= +github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= 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= +github.com/hashicorp/go-bexpr v0.1.0/go.mod h1:ANbpTX1oAql27TZkKVeW8p1w8NTdnyzPe/0qqPCKohU= +github.com/hashicorp/go-checkpoint v0.0.0-20171009173528-1545e56e46de/go.mod h1:xIwEieBHERyEvaeKF/TcHh1Hu+lxPM+n2vT1+g9I4m4= github.com/hashicorp/go-cleanhttp v0.5.0 h1:wvCrVc9TjDls6+YGAF2hAifE1E5U1+b4tH6KdvN3Gig= 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-discover v0.0.0-20190403160810-22221edb15cd/go.mod h1:ueUgD9BeIocT7QNuvxSyJyPAM9dfifBcaWmeybb67OY= +github.com/hashicorp/go-hclog v0.0.0-20180402200405-69ff559dc25f/go.mod h1:9bjs9uLqI8l75knNv3lV1kA55veR+WUPSiKIWcQHudI= github.com/hashicorp/go-immutable-radix v1.0.0 h1:AKDB1HM5PWEA7i4nhcpwOrO2byshxBjXVn/J/3+z5/0= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-memdb v0.0.0-20180223233045-1289e7fffe71/go.mod h1:kbfItVoBJwCfKXDXN4YoAXjxcFVZ7MRrJzyTX6H4giE= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-msgpack v0.5.4/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-plugin v0.0.0-20180331002553-e8d22c780116/go.mod h1:JSqWYsict+jzcj0+xElxyrBQRPNoiWQuddnxArJ7XHQ= +github.com/hashicorp/go-retryablehttp v0.0.0-20180531211321-3b087ef2d313/go.mod h1:fXcdFsQoipQa7mwORhKad5jmDCeSy/RCGzWA08PO0lM= github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= github.com/hashicorp/go-rootcerts v0.0.0-20160503143440-6bb64b370b90 h1:VBj0QYQ0u2MCJzBfeYXGexnAl17GsH1yidnoxCqqD9E= github.com/hashicorp/go-rootcerts v0.0.0-20160503143440-6bb64b370b90/go.mod h1:o4zcYY1e0GEZI6eSEr+43QDYmuGglw1qSO6qdHUHCgg= +github.com/hashicorp/go-rootcerts v1.0.0 h1:Rqb66Oo1X/eSV1x66xbDccZjhJigjg0+e82kpwzSwCI= +github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= github.com/hashicorp/go-sockaddr v1.0.0 h1:GeH6tui99pF4NJgfnhp+L6+FfobzVW3Ah46sLo0ICXs= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1 h1:fv1ep09latC32wFoVwnqcnKJGnMSdBanPczbHAYm1BE= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v0.0.0-20170202080759-03c5bf6be031/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.3 h1:YPkqC67at8FYaadspW/6uE0COsBxS2656RLEr8Bppgk= github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/hcl v0.0.0-20180906183839-65a6292f0157/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/hil v0.0.0-20160711231837-1e86c6b523c5/go.mod h1:KHvg/R2/dPtaePb16oW4qIyzkMxXOL38xjRN64adsts= +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/mdns v1.0.1/go.mod h1:4gW7WsVCke5TE7EPeYliwHlRUyBtfCwuFwuMg2DmyNY= +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/net-rpc-msgpackrpc v0.0.0-20151116020338-a14192a58a69/go.mod h1:/z+jUGRBlwVpUZfjute9jWaF6/HuhjuFQuL1YXzVD1Q= +github.com/hashicorp/raft v1.0.1-0.20190409200437-d9fe23f7d472/go.mod h1:DVSAWItjLjTOkVbSpWQ0j0kUADIvDaCtBxIcbNAQLkI= +github.com/hashicorp/raft-boltdb v0.0.0-20150201200839-d1e82c1ec3f1/go.mod h1:pNv7Wc3ycL6F5oOWn+tPGo2gWD4a5X+yp/ntwdKLjRk= github.com/hashicorp/serf v0.0.0-20161207011743-d3a67ab21bc8 h1:Vd9tjFEMH3X1AMV1BzVAZRwnjy9MoxOsOl+1pqpCVQs= github.com/hashicorp/serf v0.0.0-20161207011743-d3a67ab21bc8/go.mod h1:h/Ru6tmZazX7WO/GDmwdpS975F019L4t5ng5IgwbNrE= +github.com/hashicorp/serf v0.8.2 h1:YZ7UKsJv+hKjqGVUUbtE3HNj79Eln2oQ75tniF6iPt0= +github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= +github.com/hashicorp/vault v0.10.3/go.mod h1:KfSyffbKxoVyspOdlaGVjIuwLobi07qD1bAbosPMpP0= +github.com/hashicorp/vault-plugin-secrets-kv v0.0.0-20190318174639-195e0e9d07f1/go.mod h1:VJHHT2SC1tAPrfENQeBhLlb5FbZoKZM+oC/ROmEftz0= +github.com/hashicorp/vic v1.5.1-0.20190403131502-bbfe86ec9443/go.mod h1:bEpDU35nTu0ey1EXjwNwPjI9xErAsoOCmcMb9GKvyxo= +github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/icrowley/fake v0.0.0-20180203215853-4178557ae428 h1:Mo9W14pwbO9VfRe+ygqZ8dFbPpoIK1HFrG/zjTuQ+nc= github.com/icrowley/fake v0.0.0-20180203215853-4178557ae428/go.mod h1:uhpZMVGznybq1itEKXj6RYw9I71qK4kH+OGMjRC4KEo= +github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/jarcoal/httpmock v0.0.0-20180424175123-9c70cfe4a1da/go.mod h1:ks+b9deReOc7jgqp+e7LuFiCBH6Rm5hL32cLcEAArb4= +github.com/jefferai/jsonx v0.0.0-20160721235117-9cc31c3135ee/go.mod h1:N0t2vlmpe8nyZB5ouIbJQPDSR+mH6oe7xHB9VZHSUzM= github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jinzhu/gorm v1.9.12 h1:Drgk1clyWT9t9ERbzHza6Mj/8FY/CqMyVzOiHviMo6Q= -github.com/jinzhu/gorm v1.9.12/go.mod h1:vhTjlKSJUTWNtcbQtrMBFCxy7eXTzeCAzfL5fBZT/Qs= -github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= -github.com/jinzhu/now v1.0.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= -github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8 h1:12VvqtR6Aowv3l/EQUlocDHW2Cp4G9WJVH7uyH8QFJE= github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= 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 v0.0.0-20180628001255-830d2b111e62/go.mod h1:U+RSyWxWd04xTqnuOQxnai7XGS2PrPY2cfGoDKtMHjA= +github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jtolds/gls v4.2.1+incompatible h1:fSuqC+Gmlu6l/ZYAoZzx2pyucC8Xza35fpRVWLVmUEE= 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/keybase/go-crypto v0.0.0-20180614160407-5114a9a81e1b/go.mod h1:ghbZscTyKdM07+Fw3KSi0hcJm+AlEUWj8QLlPtijN/M= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v0.0.0-20180801095237-b50017755d44 h1:uDhun+KVSncSm1UeN8A4llsQ6E+xAIBmhh816Q2zeOk= -github.com/klauspost/compress v0.0.0-20180801095237-b50017755d44/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.4.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.4.1 h1:8VMb5+0wMgdBykOV96DwNwKFQ+WTI4pzYURP99CcB9E= github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/cpuid v0.0.0-20180405133222-e7e905edc00e/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= +github.com/klauspost/compress v1.10.9 h1:pPRt1Z78crspaHISkpSSHjDlx+Tt9suHe519dsI0vF4= +github.com/klauspost/compress v1.10.9/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/cpuid v1.2.0 h1:NMpwD2G9JSFOE1/TJjGSo5zG7Yb2bTe7eq1jH+irmeE= github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/crc32 v1.2.0 h1:0VuyqOCruD33/lJ/ojXNvzVyl8Zr5zdTmj9l9qLZ86I= github.com/klauspost/crc32 v1.2.0/go.mod h1:+ZoRqAPRLkC4NPOvfYeR5KNOrY6TD+/sAC3HXPZgDYg= github.com/klauspost/pgzip v1.2.0 h1:SPtjjC68wy5g65KwQS4TcYtm6x/O8H4jSxtKZfhN4s0= github.com/klauspost/pgzip v1.2.0/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= +github.com/klauspost/pgzip v1.2.4 h1:TQ7CNpYKovDOmqzRHKxJh0BeaBI7UdQZYc6p7pMQh1A= +github.com/klauspost/pgzip v1.2.4/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= 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 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s= @@ -319,17 +389,22 @@ 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/krishicks/yaml-patch v0.0.10 h1:H4FcHpnNwVmw8u0MjPRjWyIXtco6zM2F78t+57oNM3E= github.com/krishicks/yaml-patch v0.0.10/go.mod h1:Sm5TchwZS6sm7RJoyg87tzxm2ZcKzdRE4Q7TjNhPrME= -github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v0.0.0-20180523175426-90697d60dd84/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= +github.com/lyft/protoc-gen-validate v0.0.0-20180911180927-64fcb82c878e/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/matoous/godox v0.0.0-20190911065817-5d6d842e92eb h1:RHba4YImhrUVQDHUCe2BNSOz4tVy2yGyXhvYDvxGgeE= github.com/matoous/godox v0.0.0-20190911065817-5d6d842e92eb/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149 h1:HfxbT6/JcvIljmERptWhwa8XzP7H3T+Z2N26gTsaDaA= +github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.11 h1:FxPOTFNqGkuDUGi3H/qkUbQO4ZiBa2brKq5r0l8TGeM= @@ -344,13 +419,23 @@ github.com/miekg/dns v1.0.14 h1:9jZdLNd/P4+SfEJ0TNyxYpsK8N4GtfylBLqtbYN1sbA= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/minio/minio-go v0.0.0-20190131015406-c8a261de75c1 h1:jw16EimP5oAEM/2wt+SiEUov/YDyTCTDuPtIKgQIvk0= github.com/minio/minio-go v0.0.0-20190131015406-c8a261de75c1/go.mod h1:vuvdOZLJuf5HmJAJrKV64MmozrSsk+or0PB5dzdfspg= +github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/copystructure v0.0.0-20160804032330-cdac8253d00f/go.mod h1:eOsF2yLPlBBJPvD+nhl5QMTBSOBbOph6N7j/IDUw7PY= +github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-ps v0.0.0-20190716172923-621e5597135b/go.mod h1:r1VsdOzOPt1ZSrGZWFoNhsAedKnEd6r9Np1+5blZCWk= -github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdIPrefOvVG1VZ96U0= +github.com/mitchellh/go-ps v1.0.0 h1:i6ampVEEF4wQFF+bkYfwYgY+F/uYJDktmvLPf7qIgjc= +github.com/mitchellh/go-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN3nvg8Pg= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/go-testing-interface v1.14.0 h1:/x0XQ6h+3U3nAyk1yx+bHPURrKa9sVVvYbuqZ7pIAtI= +github.com/mitchellh/go-testing-interface v1.14.0/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= +github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= +github.com/mitchellh/hashstructure v0.0.0-20170609045927-2bca23e0e452/go.mod h1:QjSHrPWS+BGUVBYkbTZWEnOh3G1DutKwClXU/ABz6AQ= +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/reflectwalk v1.0.1/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= @@ -360,31 +445,40 @@ github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRW github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d h1:AREM5mwr4u1ORQBMvzfzBgpsctsbQikCVpvC+tX285E= github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU= github.com/ngdinhtoan/glide-cleanup v0.2.0/go.mod h1:UQzsmiDOb8YV3nOsCxK/c9zPpCZVNoHScRE3EO9pVMM= +github.com/nicolai86/scaleway-sdk v1.10.2-0.20180628010248-798f60e20bb2/go.mod h1:TLb2Sg7HQcgGdloNxkrmtgDNR9uVYF3lfdFIN4Ro6Sk= github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229 h1:E2B8qYyeSgv5MXpmzZXRNp8IAQ4vjxIjhpAf5hv/tAg= github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229/go.mod h1:0aYXnNPJ8l7uZxf45rWW1a/uME32OF0rhiYGNQ2oF2E= +github.com/oklog/run v0.0.0-20180308005104-6934b124db28/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/olekukonko/tablewriter v0.0.0-20160115111002-cca8bbc07984 h1:c9gVtoY8wPlhJIN2V2I1V+Fn9UcXM8mDG8IHv/1c3r8= github.com/olekukonko/tablewriter v0.0.0-20160115111002-cca8bbc07984/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.10.3 h1:OoxbjfXVZyod1fmWYhI7SEyaD8B00ynP3T+D5GiyHOY= github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +github.com/onsi/gomega v1.4.2/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.7.1 h1:K0jcRCwNQM3vFGh1ppMtDh/+7ApJrjldlX8fA0jDTLQ= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= +github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= +github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= github.com/opentracing-contrib/go-grpc v0.0.0-20180928155321-4b5a12d3ff02 h1:0R5mDLI66Qw13qN80TRz85zthQ2nf2+uDyiV23w6c3Q= github.com/opentracing-contrib/go-grpc v0.0.0-20180928155321-4b5a12d3ff02/go.mod h1:JNdpVEzCpXBgIiv4ds+TzhN1hrtxq6ClLrTlT9OQRSc= github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/ory/dockertest v3.3.4+incompatible/go.mod h1:1vX4m9wsvi00u5bseYwXaSnhNrne+V0E6LAcBILJdPs= +github.com/packethost/packngo v0.1.1-0.20180711074735-b9cb5096f54c/go.mod h1:otzZQXgoO96RTzDB/Hycg0qZcXZsWJGJRSXbmEIJ+4M= 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/pborman/uuid v0.0.0-20160824210600-b984ec7fa9ff h1:pTiDfW+iOjIxjZeCm88gKn/AmR09UGZYZdqif2yPRrM= -github.com/pborman/uuid v0.0.0-20160824210600-b984ec7fa9ff/go.mod h1:VyrYX9gd7irzKovcSS6BIIEwPRkP2Wm2m9ufcdFSJ34= +github.com/patrickmn/go-cache v0.0.0-20180527043350-9f6ff22cfff8/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pelletier/go-toml v1.6.0 h1:aetoXYr0Tv7xRU/V4B4IZJ2QcbtMUFoNb3ORp7TzIK4= -github.com/pelletier/go-toml v1.6.0/go.mod h1:5N711Q9dKgbdkxHL+MEfF31hpT7l0S0s/t2kKREewys= +github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/philhofer/fwd v1.0.0 h1:UbZqGr5Y38ApvM/V/jEljVxwocdweyH+vmYvRPBnbqQ= github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= github.com/pires/go-proxyproto v0.0.0-20191211124218-517ecdf5bb2b h1:JPLdtNmpXbWytipbGwYz7zXZzlQNASEiFw5aGAM75us= @@ -394,40 +488,46 @@ github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/prometheus/client_golang v0.0.0-20180328130430-f504d69affe1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.2 h1:awm861/B8OKDd2I/6o1dy3ra4BamzKhYOiGItCeZ740= github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM= github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.1.0 h1:BQ53HtBmfOitExawJ6LokA4x8ov/z0SYYb0+HxJfRI8= -github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= +github.com/prometheus/client_golang v1.4.1 h1:FFSuS004yOQEtDdTq+TAOLP5xUq63KqAFYyOi8zA+Y8= +github.com/prometheus/client_golang v1.4.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= +github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910 h1:idejC8f05m9MGOsuEi1ATq9shN03HrxNkD/luQvxCv8= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 h1:gQz4mCbXsO+nc9n1hCxHcGA3Zx3Eo+UHZoInFGUIXNM= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= +github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.0.0-20180326160409-38c53a9f4bfc/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.0.0-20181126121408-4724e9255275 h1:PnBWHBf+6L0jOqq0gIVUe6Yk0/QMZ640k6NvkxcBf+8= github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= -github.com/prometheus/common v0.7.0 h1:L+1lyG48J1zAQXA3RBX/nG/B3gjlHq0zTt2tlbJLyCY= -github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= +github.com/prometheus/common v0.9.1 h1:KOMtN28tlbam3/7ZKEYKHhKoJZYYj3gMH4uc62x7X7U= +github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= +github.com/prometheus/procfs v0.0.0-20180408092902-8b1c2da0d56d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a h1:9a8MnZMP0X2nLJdBg+pBmGgkJlSaKC2KaQmTCk1XDtE= github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= -github.com/prometheus/procfs v0.0.5 h1:3+auTFlqw+ZaQYJARz6ArODtkaIwtvBTx3N2NehQlL8= -github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= +github.com/prometheus/procfs v0.0.8 h1:+fpWZdT24pJBiqJdAwYBjPSk+5YmQzYNPYzQsdzLkt8= +github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c/go.mod h1:5STLWrekHfjyYwxBRVRXNOSewLJ3PWfDJd1VyTS21fI= +github.com/renier/xmlrpc v0.0.0-20170708154548-ce4a1a486c03/go.mod h1:gRAiPF5C5Nd0eyyRdqIu9qTiFSoZzpTq727b5B8fkkU= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/ryanuber/go-glob v0.0.0-20170128012129-256dc444b735/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= github.com/satori/go.uuid v0.0.0-20160713180306-0aa62d5ddceb h1:1r/p6yT1FfHR1+qBm7UYBPgfqCmzz/8mpNvfc+iKlfU= github.com/satori/go.uuid v0.0.0-20160713180306-0aa62d5ddceb/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= @@ -436,22 +536,27 @@ github.com/securego/gosec v0.0.0-20191002120514-e680875ea14d h1:BzRvVq1EHuIjxpij github.com/securego/gosec v0.0.0-20191002120514-e680875ea14d/go.mod h1:w5+eXa0mYznDkHaMCXA4XYffjlH+cy1oyKbfzJXa2Do= github.com/securego/gosec v0.0.0-20191217083152-cb4f343eaff1 h1:p7IOnYri8VyitvXJfgXw7yt2G/teasqQHQ6f/u1RQvc= github.com/securego/gosec v0.0.0-20191217083152-cb4f343eaff1/go.mod h1:sM2KJ/O9PKom+0jAmXpblJ8PWrLbGAk6F2Lzwj4H6wg= +github.com/shirou/gopsutil v0.0.0-20181107111621-48177ef5f880/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/shirou/gopsutil v0.0.0-20190901111213-e4ec7b275ada/go.mod h1:WWnYX4lzhCH5h/3YBfyVA3VbLYjlMZZAQcW9ojMexNc= github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc= github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= +github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/smartystreets/assertions v0.0.0-20180820201707-7c9eb446e3cf/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304 h1:Jpy1PXuP99tXNrhbq2BaPz9B+jNAvH1JPQQpG/9GCXY= github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v0.0.0-20180222194500-ef6db91d284a/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s= github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c h1:Ho+uVpkel/udgjbwB5Lktg9BtvJSh2DT0Hi6LPSyI2w= github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s= +github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/softlayer/softlayer-go v0.0.0-20180806151055-260589d94c7d/go.mod h1:Cw4GTlQccdRGSEf6KiMju767x0NEHE0YIVPJSaXjlsw= +github.com/soheilhy/cmux v0.1.4 h1:0HKaf1o97UwFjHH9o5XsHUOF+tqmdA7KEzXLpiyaw0E= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= -github.com/sourcegraph/go-diff v0.5.1 h1:gO6i5zugwzo1RVTvgvfwCOSVegNuvnNi6bAD1QCmkHs= -github.com/sourcegraph/go-diff v0.5.1/go.mod h1:j2dHj3m8aZgQO8lMTcTnBcXkRRRqi34cd2MNlA9u1mE= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= @@ -467,13 +572,11 @@ github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9 github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= +github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= -github.com/spf13/viper v1.4.0 h1:yXHLWeravcrgGyFSyCgdYpXQ9dR9c/WED3pg1RhxqEU= -github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= -github.com/spf13/viper v1.6.1 h1:VPZzIkznI1YhVMRi6vNFLHSwhnhReBfgTxIPccpfdZk= github.com/spf13/viper v1.6.1/go.mod h1:t3iDnF5Jlj76alVNuyFBk5oUMCvsrkbvZK0WQdfDi5k= github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -484,10 +587,12 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/tchap/go-patricia v0.0.0-20160729071656-dd168db6051b h1:i3lm+BZX5fAaH95wJavMgsSYU95LhSxdNCMa8nLv2gk= github.com/tchap/go-patricia v0.0.0-20160729071656-dd168db6051b/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I= +github.com/tebeka/selenium v0.9.9 h1:cNziB+etNgyH/7KlNI7RMC1ua5aH1+5wUlFQyzeMh+w= +github.com/tebeka/selenium v0.9.9/go.mod h1:5Fr8+pUvU6B1OiPfkdCKdXZyr5znvVkxuPd0NOdZCQc= +github.com/tent/http-link-go v0.0.0-20130702225549-ac974c61c2f9/go.mod h1:RHkNRtSLfOK7qBTHaeSX1D6BNpI3qw7NTxsmNr4RvN8= github.com/timakin/bodyclose v0.0.0-20190930140734-f7f2e9bca95e h1:RumXZ56IrCj4CL+g1b9OL/oH0QnsF976bC8xQFYUD5Q= github.com/timakin/bodyclose v0.0.0-20190930140734-f7f2e9bca95e/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk= github.com/tinylib/msgp v1.1.1 h1:TnCZ3FIuKeaIy+F45+Cnp+caqdXGy4z74HvwXN+570Y= @@ -516,11 +621,11 @@ github.com/uudashr/gocognit v1.0.1 h1:MoG2fZ0b/Eo7NXoIwCVFLG5JED3qgQz5/NEE+rOsjP github.com/uudashr/gocognit v1.0.1/go.mod h1:j44Ayx2KW4+oB6SWMv8KsmHzZrOInQav7D3cQMJ5JUM= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasthttp v1.2.0/go.mod h1:4vX61m6KN+xDduDNwXrhIAVZaZaZiQ1luJk8LWSxF3s= github.com/valyala/fasttemplate v1.0.1 h1:tY9CJiPnMXf1ERmG2EyK7gNUd+c6RKGD0IfU8WdUSz8= github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= github.com/valyala/quicktemplate v1.2.0/go.mod h1:EH+4AkTd43SvgIbQHYu59/cJyxDoOVRUAfrukLPuGJ4= github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= +github.com/vmware/govmomi v0.18.0/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59bHWk6aFU= 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= @@ -532,7 +637,9 @@ go.opencensus.io v0.22.0 h1:C9hSCOW830chIVkdja34wa6Ky+IzWllkUinR+BtRZd4= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -547,11 +654,12 @@ golang.org/x/crypto v0.0.0-20190829043050-9756ffdc2472/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd h1:GGJVjV8waZKRHrgwvtH66z9ZGVurTD1MT0n1Bb+q4aM= -golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413 h1:ULYEB3JvPRE/IfO+9uO7vKV/xzVTO7XPAwm8xbf4w2g= +golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -561,6 +669,7 @@ golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -573,6 +682,7 @@ golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190403144856-b630fd6fe46b/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -583,6 +693,9 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190926025831-c00fd9afed17 h1:qPnAdmjNA41t3QBTx2mFGf/SD1IoslhYu7AmdsVzCcs= golang.org/x/net v0.0.0-20190926025831-c00fd9afed17/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2 h1:CCH4IOTTfewWjGOlSp+zGcjutRKlBEZQ6wTn8ozI/nI= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/oauth2 v0.0.0-20170807180024-9a379c6b3e95/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0= @@ -593,6 +706,9 @@ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -602,8 +718,8 @@ golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190124100055-b90733256f2e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -617,15 +733,18 @@ golang.org/x/sys v0.0.0-20190926180325-855e68c8590b/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191218084908-4a24b4065292 h1:Y8q0zsdcgAd+JU8VUA8p8Qv2YhuY9zevDG2ORt5qBUI= golang.org/x/sys v0.0.0-20191218084908-4a24b4065292/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82 h1:ywK/j/KkyTHcdyYSZNXGjMwgmDSfjglYZ3vStQ/gSCU= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= 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 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181117154741-2ddaf7f79a09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -636,7 +755,6 @@ golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3 golang.org/x/tools v0.0.0-20190311215038-5c2858a9cfe5/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190322203728-c1a832b0ad89/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= @@ -644,6 +762,7 @@ golang.org/x/tools v0.0.0-20190521203540-521d6ed310dd/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190624190245-7f2218787638/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190719005602-e377ae9d6386/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI= golang.org/x/tools v0.0.0-20190830154057-c17b040389b9 h1:5/jaG/gKlo3xxvUn85ReNyTlN7BvlPPsxC6sHZKjGEE= @@ -661,6 +780,9 @@ golang.org/x/tools v0.0.0-20191219041853-979b82bfef62/go.mod h1:TB2adYChydJhpapK golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898 h1:/atklqdjdhuosWIl6AIbOeHJjicWYPqR9bpxqxYG2pA= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.0.0-20180829000535-087779f1d2c9/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0 h1:9sdfJOzWlkqPltHAuzT2Cp+yrBeY1KRVYgms8soxMwM= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= @@ -677,12 +799,14 @@ google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRn google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190626174449-989357319d63/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64 h1:iKtrH9Y8mcbADOP0YFaEMth7OfuHY9xHOwNj4znpM1A= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55 h1:gSJIx1SDwno+2ElGhA4+qG2zF97qiUzTM+rQ0klBOcE= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190926190326-7ee9db18f195 h1:dWzgMaXfaHsnkRKZ1l3iJLDmTEB40JMl/dqRbJX4D/o= google.golang.org/genproto v0.0.0-20190926190326-7ee9db18f195/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/grpc v0.0.0-20180920234847-8997b5fa0873/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -692,23 +816,30 @@ google.golang.org/grpc v1.24.0 h1:vb/1TCsVn3DcJlQ0Gs1yB1pKI6Do2/QNwxdKqmc/b0s= google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA= gopkg.in/DataDog/dd-trace-go.v1 v1.17.0 h1:j9vAp9Re9bbtA/QFehkJpNba/6W2IbJtNuXZophCa54= gopkg.in/DataDog/dd-trace-go.v1 v1.17.0/go.mod h1:DVp8HmDh8PuTu2Z0fVVlBsyWaC++fzwVCaGWylTe3tg= +gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= -gopkg.in/asn1-ber.v1 v1.0.0-20150924051756-4e86f4367175 h1:nn6Zav2sOQHCFJHEspya8KqxhFwKci30UxHy3HXPTyQ= -gopkg.in/asn1-ber.v1 v1.0.0-20150924051756-4e86f4367175/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw= +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/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.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.41.0 h1:Ka3ViY6gNYSKiVy71zXBEqKplnV35ImDLVG+8uoIklE= gopkg.in/ini.v1 v1.41.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ldap.v2 v2.5.0 h1:1rO3ojzsHUk+gq4ZYhC4Pg+EzWaaKIV8+DJwExS5/QQ= gopkg.in/ldap.v2 v2.5.0/go.mod h1:oI0cpe/D7HRtBQl8aTg+ZmzFUAvu4lsv3eLXMLGFxWk= +gopkg.in/mgo.v2 v2.0.0-20160818020120-3f83fa500528/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= +gopkg.in/ory-am/dockertest.v3 v3.3.4/go.mod h1:s9mmoLkaGeAh97qygnNj4xWkiN7e1SKekYC6CovU+ek= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= 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= @@ -716,8 +847,13 @@ gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.7 h1:VUgggvou5XRW9mHwD/yXxIYSMtY0zoKQf/v226p2nyo= 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/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= +honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a h1:LJwr7TCTghdatWv40WobzlKXc9c4s8oGa7QKJUtHhWA= @@ -726,6 +862,11 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc h1:/hemPrYIhOhy8zYrNj+069z honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +k8s.io/api v0.0.0-20180806132203-61b11ee65332/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA= +k8s.io/api v0.0.0-20190325185214-7544f9db76f6/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA= +k8s.io/apimachinery v0.0.0-20180821005732-488889b0007f/go.mod h1:ccL7Eh7zubPUSh9A3USN90/OzHNSVN6zxzde07TDCL0= +k8s.io/apimachinery v0.0.0-20190223001710-c182ff3b9841/go.mod h1:ccL7Eh7zubPUSh9A3USN90/OzHNSVN6zxzde07TDCL0= +k8s.io/client-go v8.0.0+incompatible/go.mod h1:7vJpHMYJwNQCWgzmNV+VYUl1zCObLyodBc8nIyt8L5s= mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed h1:WX1yoOaKQfddO/mLzdV4wptyWgoH/6hwLs7QHTixo0I= mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc= mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b h1:DxJ5nJdkhDlLok9K6qO+5290kphDJbHOQO1DFFFTeBo= @@ -735,7 +876,11 @@ mvdan.cc/unparam v0.0.0-20190720180237-d51796306d8f/go.mod h1:4G1h5nDURzA3bwVMZI mvdan.cc/unparam v0.0.0-20191111180625-960b1ec0f2c2 h1:K7wru2CfJGumS5hkiguQ0Rb9ebKM2Jo8s5d4Jm9lFaM= mvdan.cc/unparam v0.0.0-20191111180625-960b1ec0f2c2/go.mod h1:rCqoQrfAmpTX/h2APczwM7UymU/uvaOluiVPIYCSY/k= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q= +sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4 h1:JPJh2pk3+X4lXAkZIk2RuE/7/FoK9maXw+TNPJhVS/c= sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0= sourcegraph.com/sqs/pbtypes v1.0.0 h1:f7lAwqviDEGvON4kRv0o5V7FT/IQK+tbkF664XMbP3o= sourcegraph.com/sqs/pbtypes v1.0.0/go.mod h1:3AciMUv4qUuRHRHhOG4TZOB+72GdPVz5k+c648qsFS4= +vitess.io/vitess/examples/are-you-alive v0.0.0-20200302220708-6b7695375ce9 h1:tB4oHYzfEkqCFNUO7yUFWg9xcYw9ULT5U9/tBVbjaD0= +vitess.io/vitess/examples/are-you-alive v0.0.0-20200302220708-6b7695375ce9/go.mod h1:3Lnc7tMP/PtC7X4Yxu2tcqYbXAX4aGLDKEDsaQwPDp4= diff --git a/go/cmd/vtbackup/plugin_azblobbackupstorage.go b/go/cmd/vtbackup/plugin_azblobbackupstorage.go new file mode 100644 index 00000000000..a4ca64096a9 --- /dev/null +++ b/go/cmd/vtbackup/plugin_azblobbackupstorage.go @@ -0,0 +1,21 @@ +/* +Copyright 2020 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +import ( + _ "vitess.io/vitess/go/vt/mysqlctl/azblobbackupstorage" +) diff --git a/go/cmd/vtcombo/main.go b/go/cmd/vtcombo/main.go index 117a6893f09..232865bf7bf 100644 --- a/go/cmd/vtcombo/main.go +++ b/go/cmd/vtcombo/main.go @@ -53,7 +53,9 @@ var ( schemaDir = flag.String("schema_dir", "", "Schema base directory. Should contain one directory per keyspace, with a vschema.json file if necessary.") - ts *topo.Server + ts *topo.Server + resilientServer *srvtopo.ResilientServer + healthCheck discovery.HealthCheck ) func init() { @@ -95,10 +97,7 @@ func main() { servenv.Init() tabletenv.Init() - dbcfgs, err := dbconfigs.Init("") - if err != nil { - log.Warning(err) - } + dbcfgs := dbconfigs.GlobalDBConfigs.Init("") mysqld := mysqlctl.NewMysqld(dbcfgs) servenv.OnClose(mysqld.Close) @@ -118,8 +117,8 @@ func main() { } // vtgate configuration and init - resilientServer := srvtopo.NewResilientServer(ts, "ResilientSrvTopoServer") - healthCheck := discovery.NewHealthCheck(1*time.Millisecond /*retryDelay*/, 1*time.Hour /*healthCheckTimeout*/) + resilientServer = srvtopo.NewResilientServer(ts, "ResilientSrvTopoServer") + healthCheck = discovery.NewHealthCheck(1*time.Millisecond /*retryDelay*/, 1*time.Hour /*healthCheckTimeout*/) tabletTypesToWait := []topodatapb.TabletType{ topodatapb.TabletType_MASTER, topodatapb.TabletType_REPLICA, @@ -129,11 +128,15 @@ func main() { vtgate.QueryLogHandler = "/debug/vtgate/querylog" vtgate.QueryLogzHandler = "/debug/vtgate/querylogz" vtgate.QueryzHandler = "/debug/vtgate/queryz" - vtgate.Init(context.Background(), healthCheck, resilientServer, tpb.Cells[0], 2 /*retryCount*/, tabletTypesToWait) + vtg := vtgate.Init(context.Background(), healthCheck, resilientServer, tpb.Cells[0], 2 /*retryCount*/, tabletTypesToWait) // vtctld configuration and init vtctld.InitVtctld(ts) + servenv.OnRun(func() { + addStatusParts(vtg) + }) + servenv.OnTerm(func() { // FIXME(alainjobart): stop vtgate }) diff --git a/go/cmd/vtcombo/status.go b/go/cmd/vtcombo/status.go new file mode 100644 index 00000000000..4d9b3079a94 --- /dev/null +++ b/go/cmd/vtcombo/status.go @@ -0,0 +1,49 @@ +/* +Copyright 2020 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +import ( + "vitess.io/vitess/go/vt/discovery" + "vitess.io/vitess/go/vt/servenv" + "vitess.io/vitess/go/vt/srvtopo" + "vitess.io/vitess/go/vt/vtgate" + + _ "vitess.io/vitess/go/vt/status" +) + +func addStatusParts(vtg *vtgate.VTGate) { + // Override and reparse the template string so we can point tablet server urls to a local path. + *discovery.TabletURLTemplateString = "{{.NamedStatusURL}}" + discovery.ParseTabletURLTemplateFromFlag() + + servenv.AddStatusPart("Executor", vtgate.ExecutorTemplate, func() interface{} { + return nil + }) + servenv.AddStatusPart("VSchema", vtgate.VSchemaTemplate, func() interface{} { + return vtg.VSchemaStats() + }) + servenv.AddStatusFuncs(srvtopo.StatusFuncs) + servenv.AddStatusPart("Topology Cache", srvtopo.TopoTemplate, func() interface{} { + return resilientServer.CacheStatus() + }) + servenv.AddStatusPart("Gateway Status", vtgate.StatusTemplate, func() interface{} { + return vtg.GetGatewayCacheStatus() + }) + servenv.AddStatusPart("Health Check Cache", discovery.HealthCheckTemplate, func() interface{} { + return healthCheck.CacheStatus() + }) +} diff --git a/go/cmd/vtctl/plugin_azblobbackupstorage.go b/go/cmd/vtctl/plugin_azblobbackupstorage.go new file mode 100644 index 00000000000..a4ca64096a9 --- /dev/null +++ b/go/cmd/vtctl/plugin_azblobbackupstorage.go @@ -0,0 +1,21 @@ +/* +Copyright 2020 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +import ( + _ "vitess.io/vitess/go/vt/mysqlctl/azblobbackupstorage" +) diff --git a/go/cmd/vtctld/plugin_azblobbackupstorage.go b/go/cmd/vtctld/plugin_azblobbackupstorage.go new file mode 100644 index 00000000000..a4ca64096a9 --- /dev/null +++ b/go/cmd/vtctld/plugin_azblobbackupstorage.go @@ -0,0 +1,21 @@ +/* +Copyright 2020 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +import ( + _ "vitess.io/vitess/go/vt/mysqlctl/azblobbackupstorage" +) diff --git a/go/cmd/vtgate/status.go b/go/cmd/vtgate/status.go index 0aa168e06d3..f8315945bf8 100644 --- a/go/cmd/vtgate/status.go +++ b/go/cmd/vtgate/status.go @@ -22,12 +22,8 @@ import ( "vitess.io/vitess/go/vt/srvtopo" _ "vitess.io/vitess/go/vt/status" "vitess.io/vitess/go/vt/vtgate" - "vitess.io/vitess/go/vt/vtgate/gateway" ) -// For use by plugins which wish to avoid racing when registering status page parts. -var onStatusRegistered func() - func addStatusParts(vtg *vtgate.VTGate) { servenv.AddStatusPart("Executor", vtgate.ExecutorTemplate, func() interface{} { return nil @@ -39,13 +35,10 @@ func addStatusParts(vtg *vtgate.VTGate) { servenv.AddStatusPart("Topology Cache", srvtopo.TopoTemplate, func() interface{} { return resilientServer.CacheStatus() }) - servenv.AddStatusPart("Gateway Status", gateway.StatusTemplate, func() interface{} { + servenv.AddStatusPart("Gateway Status", vtgate.StatusTemplate, func() interface{} { return vtg.GetGatewayCacheStatus() }) servenv.AddStatusPart("Health Check Cache", discovery.HealthCheckTemplate, func() interface{} { return healthCheck.CacheStatus() }) - if onStatusRegistered != nil { - onStatusRegistered() - } } diff --git a/go/cmd/vtgate/vtgate.go b/go/cmd/vtgate/vtgate.go index ad8148fe429..55779162e35 100644 --- a/go/cmd/vtgate/vtgate.go +++ b/go/cmd/vtgate/vtgate.go @@ -47,8 +47,6 @@ var ( var resilientServer *srvtopo.ResilientServer var healthCheck discovery.HealthCheck -var initFakeZK func() - func init() { rand.Seed(time.Now().UnixNano()) servenv.RegisterDefaultFlags() @@ -60,9 +58,6 @@ func main() { servenv.ParseFlags("vtgate") servenv.Init() - if initFakeZK != nil { - initFakeZK() - } ts := topo.Open() defer ts.Close() diff --git a/go/cmd/vtgateclienttest/goclienttest/callerid.go b/go/cmd/vtgateclienttest/goclienttest/callerid.go deleted file mode 100644 index e46ec5e5a92..00000000000 --- a/go/cmd/vtgateclienttest/goclienttest/callerid.go +++ /dev/null @@ -1,109 +0,0 @@ -/* -Copyright 2019 The Vitess Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package goclienttest - -import ( - "encoding/json" - "strings" - "testing" - - "golang.org/x/net/context" - "vitess.io/vitess/go/cmd/vtgateclienttest/services" - "vitess.io/vitess/go/vt/callerid" - "vitess.io/vitess/go/vt/vtgate/vtgateconn" - - querypb "vitess.io/vitess/go/vt/proto/query" - topodatapb "vitess.io/vitess/go/vt/proto/topodata" - vtgatepb "vitess.io/vitess/go/vt/proto/vtgate" -) - -// testCallerID adds a caller ID to a context, and makes sure the server -// gets it. -func testCallerID(t *testing.T, conn *vtgateconn.VTGateConn, session *vtgateconn.VTGateSession) { - ctx := context.Background() - callerID := callerid.NewEffectiveCallerID("test_principal", "test_component", "test_subcomponent") - ctx = callerid.NewContext(ctx, callerID, nil) - - data, err := json.Marshal(callerID) - if err != nil { - t.Errorf("failed to marshal callerid: %v", err) - return - } - query := services.CallerIDPrefix + string(data) - - // test Execute calls forward the callerID - _, err = session.Execute(ctx, query, nil) - checkCallerIDError(t, "Execute", err) - - _, err = conn.ExecuteShards(ctx, query, "", nil, nil, topodatapb.TabletType_MASTER, nil) - checkCallerIDError(t, "ExecuteShards", err) - - _, err = conn.ExecuteKeyspaceIds(ctx, query, "", nil, nil, topodatapb.TabletType_MASTER, nil) - checkCallerIDError(t, "ExecuteKeyspaceIds", err) - - _, err = conn.ExecuteKeyRanges(ctx, query, "", nil, nil, topodatapb.TabletType_MASTER, nil) - checkCallerIDError(t, "ExecuteKeyRanges", err) - - _, err = conn.ExecuteEntityIds(ctx, query, "", "", nil, nil, topodatapb.TabletType_MASTER, nil) - checkCallerIDError(t, "ExecuteEntityIds", err) - - // test ExecuteBatch calls forward the callerID - _, err = conn.ExecuteBatchShards(ctx, []*vtgatepb.BoundShardQuery{ - { - Query: &querypb.BoundQuery{ - Sql: query, - }, - }, - }, topodatapb.TabletType_MASTER, false, nil) - checkCallerIDError(t, "ExecuteBatchShards", err) - - _, err = conn.ExecuteBatchKeyspaceIds(ctx, []*vtgatepb.BoundKeyspaceIdQuery{ - { - Query: &querypb.BoundQuery{ - Sql: query, - }, - }, - }, topodatapb.TabletType_MASTER, false, nil) - checkCallerIDError(t, "ExecuteBatchKeyspaceIds", err) - - // test StreamExecute calls forward the callerID - err = getStreamError(session.StreamExecute(ctx, query, nil)) - checkCallerIDError(t, "StreamExecute", err) - - err = getStreamError(conn.StreamExecuteShards(ctx, query, "", nil, nil, topodatapb.TabletType_MASTER, nil)) - checkCallerIDError(t, "StreamExecuteShards", err) - - err = getStreamError(conn.StreamExecuteKeyspaceIds(ctx, query, "", nil, nil, topodatapb.TabletType_MASTER, nil)) - checkCallerIDError(t, "StreamExecuteKeyspaceIds", err) - - err = getStreamError(conn.StreamExecuteKeyRanges(ctx, query, "", nil, nil, topodatapb.TabletType_MASTER, nil)) - checkCallerIDError(t, "StreamExecuteKeyRanges", err) - - // test UpdateStream forwards the callerID - err = getUpdateStreamError(conn.UpdateStream(ctx, "", query, nil, topodatapb.TabletType_MASTER, 0, nil)) - checkCallerIDError(t, "UpdateStream", err) -} - -func checkCallerIDError(t *testing.T, name string, err error) { - if err == nil { - t.Errorf("callerid: got no error for %v", name) - return - } - if !strings.Contains(err.Error(), "SUCCESS: ") { - t.Errorf("failed to pass callerid for %v: %v", name, err) - } -} diff --git a/go/cmd/vtgateclienttest/goclienttest/echo.go b/go/cmd/vtgateclienttest/goclienttest/echo.go deleted file mode 100644 index ba1faef39f6..00000000000 --- a/go/cmd/vtgateclienttest/goclienttest/echo.go +++ /dev/null @@ -1,483 +0,0 @@ -/* -Copyright 2019 The Vitess Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package goclienttest - -import ( - "testing" - - "golang.org/x/net/context" - - "vitess.io/vitess/go/sqltypes" - "vitess.io/vitess/go/vt/callerid" - "vitess.io/vitess/go/vt/vtgate/vtgateconn" - - querypb "vitess.io/vitess/go/vt/proto/query" - topodatapb "vitess.io/vitess/go/vt/proto/topodata" - vtgatepb "vitess.io/vitess/go/vt/proto/vtgate" -) - -var ( - echoPrefix = "echo://" - - query = "test query with unicode: \u6211\u80fd\u541e\u4e0b\u73bb\u7483\u800c\u4e0d\u50b7\u8eab\u9ad4" - keyspace = "test_keyspace" - - shards = []string{"-80", "80-"} - shardsEcho = "[-80 80-]" - - keyspaceIDs = [][]byte{ - {1, 2, 3, 4}, - {5, 6, 7, 8}, - } - keyspaceIDsEcho = "[[1 2 3 4] [5 6 7 8]]" - - keyRanges = []*topodatapb.KeyRange{ - {Start: []byte{1, 2, 3, 4}, End: []byte{5, 6, 7, 8}}, - } - keyRangeZeroEcho = "start:\"\\001\\002\\003\\004\" end:\"\\005\\006\\007\\010\" " - keyRangesEcho = "[" + keyRangeZeroEcho + "]" - - entityKeyspaceIDs = []*vtgatepb.ExecuteEntityIdsRequest_EntityId{ - { - KeyspaceId: []byte{1, 2, 3}, - Type: sqltypes.Int64, - Value: []byte("123"), - }, - { - KeyspaceId: []byte{4, 5, 6}, - Type: sqltypes.Float64, - Value: []byte("2"), - }, - { - KeyspaceId: []byte{7, 8, 9}, - Type: sqltypes.VarBinary, - Value: []byte{1, 2, 3}, - }, - } - entityKeyspaceIDsEcho = "[type:INT64 value:\"123\" keyspace_id:\"\\001\\002\\003\" type:FLOAT64 value:\"2\" keyspace_id:\"\\004\\005\\006\" type:VARBINARY value:\"\\001\\002\\003\" keyspace_id:\"\\007\\010\\t\" ]" - - tabletType = topodatapb.TabletType_REPLICA - tabletTypeEcho = topodatapb.TabletType_name[int32(tabletType)] - - bindVars = map[string]*querypb.BindVariable{ - "int": sqltypes.Int64BindVariable(123), - "float": sqltypes.Float64BindVariable(2.1), - "bytes": sqltypes.BytesBindVariable([]byte{1, 2, 3}), - } - bindVarsEcho = "map[bytes:type:VARBINARY value:\"\\001\\002\\003\" float:type:FLOAT64 value:\"2.1\" int:type:INT64 value:\"123\" ]" - - sessionEcho = "in_transaction:true " - - callerID = callerid.NewEffectiveCallerID("test_principal", "test_component", "test_subcomponent") - callerIDEcho = "principal:\"test_principal\" component:\"test_component\" subcomponent:\"test_subcomponent\" " - - eventToken = &querypb.EventToken{ - Timestamp: 876543, - Shard: shards[0], - Position: "test_position", - } - eventTokenEcho = "timestamp:876543 shard:\"-80\" position:\"test_position\" " - - options = &querypb.ExecuteOptions{ - IncludedFields: querypb.ExecuteOptions_TYPE_ONLY, - IncludeEventToken: true, - CompareEventToken: eventToken, - } - optionsEcho = "include_event_token:true compare_event_token:<" + eventTokenEcho + "> included_fields:TYPE_ONLY " - extrasEcho = "event_token:<" + eventTokenEcho + "> fresher:true " - - updateStreamEcho = "map[callerId:" + callerIDEcho + " event:" + eventTokenEcho + " keyRange:" + keyRangeZeroEcho + " keyspace:conn_ks shard:echo://" + query + " tabletType:REPLICA timestamp:0]" -) - -// testEcho exercises the test cases provided by the "echo" service. -func testEcho(t *testing.T, conn *vtgateconn.VTGateConn, session *vtgateconn.VTGateSession) { - testEchoExecute(t, conn, session) - testEchoStreamExecute(t, conn, session) - testEchoTransactionExecute(t, conn) - testEchoSplitQuery(t, conn) - testEchoUpdateStream(t, conn) -} - -func testEchoExecute(t *testing.T, conn *vtgateconn.VTGateConn, session *vtgateconn.VTGateSession) { - var qr *sqltypes.Result - var err error - - ctx := callerid.NewContext(context.Background(), callerID, nil) - - qr, err = session.Execute(ctx, echoPrefix+query, bindVars) - checkEcho(t, "Execute", qr, err, map[string]string{ - "callerId": callerIDEcho, - "query": echoPrefix + query, - "bindVars": bindVarsEcho, - }) - - qr, err = conn.ExecuteShards(ctx, echoPrefix+query, keyspace, shards, bindVars, tabletType, options) - checkEcho(t, "ExecuteShards", qr, err, map[string]string{ - "callerId": callerIDEcho, - "query": echoPrefix + query, - "keyspace": keyspace, - "shards": shardsEcho, - "bindVars": bindVarsEcho, - "tabletType": tabletTypeEcho, - "options": optionsEcho, - "extras": extrasEcho, - }) - - qr, err = conn.ExecuteKeyspaceIds(ctx, echoPrefix+query, keyspace, keyspaceIDs, bindVars, tabletType, options) - checkEcho(t, "ExecuteKeyspaceIds", qr, err, map[string]string{ - "callerId": callerIDEcho, - "query": echoPrefix + query, - "keyspace": keyspace, - "keyspaceIds": keyspaceIDsEcho, - "bindVars": bindVarsEcho, - "tabletType": tabletTypeEcho, - "options": optionsEcho, - "extras": extrasEcho, - }) - - qr, err = conn.ExecuteKeyRanges(ctx, echoPrefix+query, keyspace, keyRanges, bindVars, tabletType, options) - checkEcho(t, "ExecuteKeyRanges", qr, err, map[string]string{ - "callerId": callerIDEcho, - "query": echoPrefix + query, - "keyspace": keyspace, - "keyRanges": keyRangesEcho, - "bindVars": bindVarsEcho, - "tabletType": tabletTypeEcho, - "options": optionsEcho, - "extras": extrasEcho, - }) - - qr, err = conn.ExecuteEntityIds(ctx, echoPrefix+query, keyspace, "column1", entityKeyspaceIDs, bindVars, tabletType, options) - checkEcho(t, "ExecuteEntityIds", qr, err, map[string]string{ - "callerId": callerIDEcho, - "query": echoPrefix + query, - "keyspace": keyspace, - "entityColumnName": "column1", - "entityIds": entityKeyspaceIDsEcho, - "bindVars": bindVarsEcho, - "tabletType": tabletTypeEcho, - "options": optionsEcho, - "extras": extrasEcho, - }) - - var qrs []sqltypes.Result - - qrs, err = conn.ExecuteBatchShards(ctx, []*vtgatepb.BoundShardQuery{ - { - Query: &querypb.BoundQuery{ - Sql: echoPrefix + query, - BindVariables: bindVars, - }, - Keyspace: keyspace, - Shards: shards, - }, - }, tabletType, true, options) - checkEcho(t, "ExecuteBatchShards", &qrs[0], err, map[string]string{ - "callerId": callerIDEcho, - "query": echoPrefix + query, - "keyspace": keyspace, - "shards": shardsEcho, - "bindVars": bindVarsEcho, - "tabletType": tabletTypeEcho, - "asTransaction": "true", - "options": optionsEcho, - }) - - qrs, err = conn.ExecuteBatchKeyspaceIds(ctx, []*vtgatepb.BoundKeyspaceIdQuery{ - { - Query: &querypb.BoundQuery{ - Sql: echoPrefix + query, - BindVariables: bindVars, - }, - Keyspace: keyspace, - KeyspaceIds: keyspaceIDs, - }, - }, tabletType, true, options) - checkEcho(t, "ExecuteBatchKeyspaceIds", &qrs[0], err, map[string]string{ - "callerId": callerIDEcho, - "query": echoPrefix + query, - "keyspace": keyspace, - "keyspaceIds": keyspaceIDsEcho, - "bindVars": bindVarsEcho, - "tabletType": tabletTypeEcho, - "asTransaction": "true", - "options": optionsEcho, - }) -} - -func testEchoStreamExecute(t *testing.T, conn *vtgateconn.VTGateConn, session *vtgateconn.VTGateSession) { - var stream sqltypes.ResultStream - var err error - var qr *sqltypes.Result - - ctx := callerid.NewContext(context.Background(), callerID, nil) - - stream, err = session.StreamExecute(ctx, echoPrefix+query, bindVars) - if err != nil { - t.Fatal(err) - } - qr, err = stream.Recv() - checkEcho(t, "StreamExecute", qr, err, map[string]string{ - "callerId": callerIDEcho, - "query": echoPrefix + query, - "bindVars": bindVarsEcho, - }) - - stream, err = conn.StreamExecuteShards(ctx, echoPrefix+query, keyspace, shards, bindVars, tabletType, options) - if err != nil { - t.Fatal(err) - } - qr, err = stream.Recv() - checkEcho(t, "StreamExecuteShards", qr, err, map[string]string{ - "callerId": callerIDEcho, - "query": echoPrefix + query, - "keyspace": keyspace, - "shards": shardsEcho, - "bindVars": bindVarsEcho, - "tabletType": tabletTypeEcho, - "options": optionsEcho, - }) - - stream, err = conn.StreamExecuteKeyspaceIds(ctx, echoPrefix+query, keyspace, keyspaceIDs, bindVars, tabletType, options) - if err != nil { - t.Fatal(err) - } - qr, err = stream.Recv() - checkEcho(t, "StreamExecuteKeyspaceIds", qr, err, map[string]string{ - "callerId": callerIDEcho, - "query": echoPrefix + query, - "keyspace": keyspace, - "keyspaceIds": keyspaceIDsEcho, - "bindVars": bindVarsEcho, - "tabletType": tabletTypeEcho, - "options": optionsEcho, - }) - - stream, err = conn.StreamExecuteKeyRanges(ctx, echoPrefix+query, keyspace, keyRanges, bindVars, tabletType, options) - if err != nil { - t.Fatal(err) - } - qr, err = stream.Recv() - checkEcho(t, "StreamExecuteKeyRanges", qr, err, map[string]string{ - "callerId": callerIDEcho, - "query": echoPrefix + query, - "keyspace": keyspace, - "keyRanges": keyRangesEcho, - "bindVars": bindVarsEcho, - "tabletType": tabletTypeEcho, - "options": optionsEcho, - }) -} - -func testEchoTransactionExecute(t *testing.T, conn *vtgateconn.VTGateConn) { - var qr *sqltypes.Result - var err error - - ctx := callerid.NewContext(context.Background(), callerID, nil) - - tx, err := conn.Begin(ctx) - if err != nil { - t.Fatalf("Begin error: %v", err) - } - - qr, err = tx.ExecuteShards(ctx, echoPrefix+query, keyspace, shards, bindVars, tabletType, options) - checkEcho(t, "ExecuteShards", qr, err, map[string]string{ - "callerId": callerIDEcho, - "query": echoPrefix + query, - "keyspace": keyspace, - "shards": shardsEcho, - "bindVars": bindVarsEcho, - "tabletType": tabletTypeEcho, - "session": sessionEcho, - "notInTransaction": "false", - "options": optionsEcho, - }) - - qr, err = tx.ExecuteKeyspaceIds(ctx, echoPrefix+query, keyspace, keyspaceIDs, bindVars, tabletType, options) - checkEcho(t, "ExecuteKeyspaceIds", qr, err, map[string]string{ - "callerId": callerIDEcho, - "query": echoPrefix + query, - "keyspace": keyspace, - "keyspaceIds": keyspaceIDsEcho, - "bindVars": bindVarsEcho, - "tabletType": tabletTypeEcho, - "session": sessionEcho, - "notInTransaction": "false", - "options": optionsEcho, - }) - - qr, err = tx.ExecuteKeyRanges(ctx, echoPrefix+query, keyspace, keyRanges, bindVars, tabletType, options) - checkEcho(t, "ExecuteKeyRanges", qr, err, map[string]string{ - "callerId": callerIDEcho, - "query": echoPrefix + query, - "keyspace": keyspace, - "keyRanges": keyRangesEcho, - "bindVars": bindVarsEcho, - "tabletType": tabletTypeEcho, - "session": sessionEcho, - "notInTransaction": "false", - "options": optionsEcho, - }) - - qr, err = tx.ExecuteEntityIds(ctx, echoPrefix+query, keyspace, "column1", entityKeyspaceIDs, bindVars, tabletType, options) - checkEcho(t, "ExecuteEntityIds", qr, err, map[string]string{ - "callerId": callerIDEcho, - "query": echoPrefix + query, - "keyspace": keyspace, - "entityColumnName": "column1", - "entityIds": entityKeyspaceIDsEcho, - "bindVars": bindVarsEcho, - "tabletType": tabletTypeEcho, - "session": sessionEcho, - "notInTransaction": "false", - "options": optionsEcho, - }) - - if err := tx.Rollback(ctx); err != nil { - t.Fatalf("Rollback error: %v", err) - } - tx, err = conn.Begin(ctx) - if err != nil { - t.Fatalf("Begin (again) error: %v", err) - } - - var qrs []sqltypes.Result - - qrs, err = tx.ExecuteBatchShards(ctx, []*vtgatepb.BoundShardQuery{ - { - Query: &querypb.BoundQuery{ - Sql: echoPrefix + query, - BindVariables: bindVars, - }, - Keyspace: keyspace, - Shards: shards, - }, - }, tabletType, options) - checkEcho(t, "ExecuteBatchShards", &qrs[0], err, map[string]string{ - "callerId": callerIDEcho, - "query": echoPrefix + query, - "keyspace": keyspace, - "shards": shardsEcho, - "bindVars": bindVarsEcho, - "tabletType": tabletTypeEcho, - "session": sessionEcho, - "asTransaction": "false", - "options": optionsEcho, - }) - - qrs, err = tx.ExecuteBatchKeyspaceIds(ctx, []*vtgatepb.BoundKeyspaceIdQuery{ - { - Query: &querypb.BoundQuery{ - Sql: echoPrefix + query, - BindVariables: bindVars, - }, - Keyspace: keyspace, - KeyspaceIds: keyspaceIDs, - }, - }, tabletType, options) - checkEcho(t, "ExecuteBatchKeyspaceIds", &qrs[0], err, map[string]string{ - "callerId": callerIDEcho, - "query": echoPrefix + query, - "keyspace": keyspace, - "keyspaceIds": keyspaceIDsEcho, - "bindVars": bindVarsEcho, - "tabletType": tabletTypeEcho, - "session": sessionEcho, - "asTransaction": "false", - "options": optionsEcho, - }) -} - -func testEchoSplitQuery(t *testing.T, conn *vtgateconn.VTGateConn) { - want := &vtgatepb.SplitQueryResponse_Part{ - Query: &querypb.BoundQuery{ - Sql: echoPrefix + query + ":[split_column1,split_column2]:123:1000:FULL_SCAN", - BindVariables: bindVars, - }, - KeyRangePart: &vtgatepb.SplitQueryResponse_KeyRangePart{Keyspace: keyspace}, - } - got, err := conn.SplitQuery(context.Background(), keyspace, echoPrefix+query, bindVars, []string{"split_column1,split_column2"}, 123, 1000, querypb.SplitQueryRequest_FULL_SCAN) - if err != nil { - t.Fatalf("SplitQuery error: %v", err) - } - // For some reason, proto.Equal() is calling them unequal even though no diffs - // are found. - gotstr, wantstr := got[0].String(), want.String() - if gotstr != wantstr { - t.Errorf("SplitQuery() = %v, want %v", gotstr, wantstr) - } -} - -func testEchoUpdateStream(t *testing.T, conn *vtgateconn.VTGateConn) { - var stream vtgateconn.UpdateStreamReader - var err error - - ctx := callerid.NewContext(context.Background(), callerID, nil) - - stream, err = conn.UpdateStream(ctx, "conn_ks", echoPrefix+query, keyRanges[0], tabletType, 0, eventToken) - if err != nil { - t.Fatal(err) - } - se, _, err := stream.Recv() - if err != nil { - t.Fatal(err) - } - if se.EventToken.Position != updateStreamEcho { - t.Errorf("UpdateStream(0) =\n%v, want\n%v", se.EventToken.Position, updateStreamEcho) - } -} - -// getEcho extracts the echoed field values from a query result. -func getEcho(qr *sqltypes.Result) map[string]sqltypes.Value { - values := map[string]sqltypes.Value{} - if qr == nil { - return values - } - for i, field := range qr.Fields { - values[field.Name] = qr.Rows[0][i] - } - return values -} - -// checkEcho verifies that the values present in 'want' are equal to those in -// 'got'. Note that extra values in 'got' are fine. -func checkEcho(t *testing.T, name string, qr *sqltypes.Result, err error, want map[string]string) { - if err != nil { - t.Fatalf("%v error: %v", name, err) - } - got := getEcho(qr) - for k, v := range want { - if k == "extras" { - gotExtras := qr.Extras.String() - if gotExtras != v { - t.Errorf("%v: extras = \n%q, want \n%q", name, gotExtras, v) - } - continue - } - if got[k].ToString() != v { - t.Errorf("%v: %v = \n%q, want \n%q", name, k, got[k], v) - } - } - - // Check NULL and empty string. - if !got["null"].IsNull() { - t.Errorf("MySQL NULL value wasn't preserved") - } - if !got["emptyString"].IsQuoted() || got["emptyString"].ToString() != "" { - t.Errorf("Empty string value wasn't preserved: %#v", got) - } -} diff --git a/go/cmd/vtgateclienttest/goclienttest/errors.go b/go/cmd/vtgateclienttest/goclienttest/errors.go deleted file mode 100644 index ec989698eb4..00000000000 --- a/go/cmd/vtgateclienttest/goclienttest/errors.go +++ /dev/null @@ -1,277 +0,0 @@ -/* -Copyright 2019 The Vitess Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package goclienttest - -import ( - "io" - "testing" - - "golang.org/x/net/context" - - "vitess.io/vitess/go/sqltypes" - - "vitess.io/vitess/go/vt/vterrors" - "vitess.io/vitess/go/vt/vtgate/vtgateconn" - - querypb "vitess.io/vitess/go/vt/proto/query" - vtgatepb "vitess.io/vitess/go/vt/proto/vtgate" - vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" -) - -var ( - errorPrefix = "error://" - partialErrorPrefix = "partialerror://" - - executeErrors = map[string]vtrpcpb.Code{ - "bad input": vtrpcpb.Code_INVALID_ARGUMENT, - "deadline exceeded": vtrpcpb.Code_DEADLINE_EXCEEDED, - "integrity error": vtrpcpb.Code_ALREADY_EXISTS, - "transient error": vtrpcpb.Code_UNAVAILABLE, - "unauthenticated": vtrpcpb.Code_UNAUTHENTICATED, - "aborted": vtrpcpb.Code_ABORTED, - "unknown error": vtrpcpb.Code_UNKNOWN, - } -) - -// testErrors exercises the test cases provided by the "errors" service. -func testErrors(t *testing.T, conn *vtgateconn.VTGateConn, session *vtgateconn.VTGateSession) { - testExecuteErrors(t, conn, session) - testStreamExecuteErrors(t, conn, session) - testTransactionExecuteErrors(t, conn) - testUpdateStreamErrors(t, conn) -} - -func testExecuteErrors(t *testing.T, conn *vtgateconn.VTGateConn, session *vtgateconn.VTGateSession) { - ctx := context.Background() - - checkExecuteErrors(t, func(query string) error { - _, err := session.Execute(ctx, query, bindVars) - return err - }) - checkExecuteErrors(t, func(query string) error { - _, err := conn.ExecuteShards(ctx, query, keyspace, shards, bindVars, tabletType, nil) - return err - }) - checkExecuteErrors(t, func(query string) error { - _, err := conn.ExecuteKeyspaceIds(ctx, query, keyspace, keyspaceIDs, bindVars, tabletType, nil) - return err - }) - checkExecuteErrors(t, func(query string) error { - _, err := conn.ExecuteKeyRanges(ctx, query, keyspace, keyRanges, bindVars, tabletType, nil) - return err - }) - checkExecuteErrors(t, func(query string) error { - _, err := conn.ExecuteEntityIds(ctx, query, keyspace, "column1", entityKeyspaceIDs, bindVars, tabletType, nil) - return err - }) - checkExecuteErrors(t, func(query string) error { - _, err := conn.ExecuteBatchShards(ctx, []*vtgatepb.BoundShardQuery{ - { - Query: &querypb.BoundQuery{ - Sql: query, - BindVariables: bindVars, - }, - Keyspace: keyspace, - Shards: shards, - }, - }, tabletType, true, nil) - return err - }) - checkExecuteErrors(t, func(query string) error { - _, err := conn.ExecuteBatchKeyspaceIds(ctx, []*vtgatepb.BoundKeyspaceIdQuery{ - { - Query: &querypb.BoundQuery{ - Sql: query, - BindVariables: bindVars, - }, - Keyspace: keyspace, - KeyspaceIds: keyspaceIDs, - }, - }, tabletType, true, nil) - return err - }) -} - -func testStreamExecuteErrors(t *testing.T, conn *vtgateconn.VTGateConn, session *vtgateconn.VTGateSession) { - ctx := context.Background() - - checkStreamExecuteErrors(t, func(query string) error { - return getStreamError(session.StreamExecute(ctx, query, bindVars)) - }) - checkStreamExecuteErrors(t, func(query string) error { - return getStreamError(conn.StreamExecuteShards(ctx, query, keyspace, shards, bindVars, tabletType, nil)) - }) - checkStreamExecuteErrors(t, func(query string) error { - return getStreamError(conn.StreamExecuteKeyspaceIds(ctx, query, keyspace, keyspaceIDs, bindVars, tabletType, nil)) - }) - checkStreamExecuteErrors(t, func(query string) error { - return getStreamError(conn.StreamExecuteKeyRanges(ctx, query, keyspace, keyRanges, bindVars, tabletType, nil)) - }) -} - -func testUpdateStreamErrors(t *testing.T, conn *vtgateconn.VTGateConn) { - ctx := context.Background() - - checkStreamExecuteErrors(t, func(query string) error { - return getUpdateStreamError(conn.UpdateStream(ctx, "", query, nil, tabletType, 0, nil)) - }) -} - -func testTransactionExecuteErrors(t *testing.T, conn *vtgateconn.VTGateConn) { - ctx := context.Background() - - checkTransactionExecuteErrors(t, conn, func(tx *vtgateconn.VTGateTx, query string) error { - _, err := tx.ExecuteShards(ctx, query, keyspace, shards, bindVars, tabletType, nil) - return err - }) - checkTransactionExecuteErrors(t, conn, func(tx *vtgateconn.VTGateTx, query string) error { - _, err := tx.ExecuteKeyspaceIds(ctx, query, keyspace, keyspaceIDs, bindVars, tabletType, nil) - return err - }) - checkTransactionExecuteErrors(t, conn, func(tx *vtgateconn.VTGateTx, query string) error { - _, err := tx.ExecuteKeyRanges(ctx, query, keyspace, keyRanges, bindVars, tabletType, nil) - return err - }) - checkTransactionExecuteErrors(t, conn, func(tx *vtgateconn.VTGateTx, query string) error { - _, err := tx.ExecuteEntityIds(ctx, query, keyspace, "column1", entityKeyspaceIDs, bindVars, tabletType, nil) - return err - }) - checkTransactionExecuteErrors(t, conn, func(tx *vtgateconn.VTGateTx, query string) error { - _, err := tx.ExecuteBatchShards(ctx, []*vtgatepb.BoundShardQuery{ - { - Query: &querypb.BoundQuery{ - Sql: query, - BindVariables: bindVars, - }, - Keyspace: keyspace, - Shards: shards, - }, - }, tabletType, nil) - return err - }) - checkTransactionExecuteErrors(t, conn, func(tx *vtgateconn.VTGateTx, query string) error { - _, err := tx.ExecuteBatchKeyspaceIds(ctx, []*vtgatepb.BoundKeyspaceIdQuery{ - { - Query: &querypb.BoundQuery{ - Sql: query, - BindVariables: bindVars, - }, - Keyspace: keyspace, - KeyspaceIds: keyspaceIDs, - }, - }, tabletType, nil) - return err - }) -} - -func getStreamError(stream sqltypes.ResultStream, err error) error { - if err != nil { - return err - } - for { - _, err := stream.Recv() - switch err { - case nil: - // keep going - case io.EOF: - return nil - default: - return err - } - } -} - -func getUpdateStreamError(stream vtgateconn.UpdateStreamReader, err error) error { - if err != nil { - return err - } - for { - _, _, err := stream.Recv() - switch err { - case nil: - // keep going - case io.EOF: - return nil - default: - return err - } - } -} - -func checkExecuteErrors(t *testing.T, execute func(string) error) { - for errStr, errCode := range executeErrors { - query := errorPrefix + errStr - checkError(t, execute(query), query, errStr, errCode) - - query = partialErrorPrefix + errStr - checkError(t, execute(query), query, errStr, errCode) - } -} - -func checkStreamExecuteErrors(t *testing.T, execute func(string) error) { - for errStr, errCode := range executeErrors { - query := errorPrefix + errStr - checkError(t, execute(query), query, errStr, errCode) - } -} - -func checkTransactionExecuteErrors(t *testing.T, conn *vtgateconn.VTGateConn, execute func(tx *vtgateconn.VTGateTx, query string) error) { - ctx := context.Background() - - for errStr, errCode := range executeErrors { - query := errorPrefix + errStr - tx, err := conn.Begin(ctx) - if err != nil { - t.Errorf("[%v] Begin error: %v", query, err) - } - checkError(t, execute(tx, query), query, errStr, errCode) - - // Partial error where server doesn't close the session. - query = partialErrorPrefix + errStr - tx, err = conn.Begin(ctx) - if err != nil { - t.Errorf("[%v] Begin error: %v", query, err) - } - checkError(t, execute(tx, query), query, errStr, errCode) - // The transaction should still be usable now. - if err := tx.Rollback(ctx); err != nil { - t.Errorf("[%v] Rollback error: %v", query, err) - } - - // Partial error where server closes the session. - tx, err = conn.Begin(ctx) - if err != nil { - t.Errorf("[%v] Begin error: %v", query, err) - } - query = partialErrorPrefix + errStr + "/close transaction" - checkError(t, execute(tx, query), query, errStr, errCode) - // The transaction should be unusable now. - if tx.Rollback(ctx) == nil { - t.Errorf("[%v] expected Rollback error, got nil", query) - } - } -} - -func checkError(t *testing.T, err error, query, errStr string, errCode vtrpcpb.Code) { - if err == nil { - t.Errorf("[%v] expected error, got nil", query) - return - } - if got, want := vterrors.Code(err), errCode; got != want { - t.Errorf("[%v] error code = %v, want %v", query, got, want) - } -} diff --git a/go/cmd/vtgateclienttest/goclienttest/main.go b/go/cmd/vtgateclienttest/goclienttest/main.go deleted file mode 100644 index ab33a400164..00000000000 --- a/go/cmd/vtgateclienttest/goclienttest/main.go +++ /dev/null @@ -1,53 +0,0 @@ -/* -Copyright 2019 The Vitess Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package goclienttest - -import ( - "testing" - - "golang.org/x/net/context" - "vitess.io/vitess/go/vt/vtgate/vtgateconn" -) - -const connectionKeyspace = "conn_ks" - -// This file contains the reference test for clients. It tests -// all the corner cases of the API, and makes sure the go client -// is full featured. -// -// It can be used as a template by other languages for their test suites. -// -// TODO(team) add more unit test cases. - -// TestGoClient runs the test suite for the provided client -func TestGoClient(t *testing.T, protocol, addr string) { - // Create a client connecting to the server - ctx := context.Background() - conn, err := vtgateconn.DialProtocol(ctx, protocol, addr) - session := conn.Session(connectionKeyspace, nil) - if err != nil { - t.Fatalf("dial failed: %v", err) - } - - testCallerID(t, conn, session) - testEcho(t, conn, session) - testErrors(t, conn, session) - testSuccess(t, conn) - - // and clean up - conn.Close() -} diff --git a/go/cmd/vtgateclienttest/goclienttest/success.go b/go/cmd/vtgateclienttest/goclienttest/success.go deleted file mode 100644 index 5bbe7439aa6..00000000000 --- a/go/cmd/vtgateclienttest/goclienttest/success.go +++ /dev/null @@ -1,67 +0,0 @@ -/* -Copyright 2019 The Vitess Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package goclienttest - -import ( - "testing" - - "golang.org/x/net/context" - - "github.com/golang/protobuf/proto" - "vitess.io/vitess/go/vt/vtgate/vtgateconn" - - topodatapb "vitess.io/vitess/go/vt/proto/topodata" -) - -// testSuccess exercises the test cases provided by the "success" service. -func testSuccess(t *testing.T, conn *vtgateconn.VTGateConn) { - testGetSrvKeyspace(t, conn) -} - -func testGetSrvKeyspace(t *testing.T, conn *vtgateconn.VTGateConn) { - want := &topodatapb.SrvKeyspace{ - Partitions: []*topodatapb.SrvKeyspace_KeyspacePartition{ - { - ServedType: topodatapb.TabletType_REPLICA, - ShardReferences: []*topodatapb.ShardReference{ - { - Name: "shard0", - KeyRange: &topodatapb.KeyRange{ - Start: []byte{0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - End: []byte{0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - }, - }, - }, - }, - }, - ShardingColumnName: "sharding_column_name", - ShardingColumnType: topodatapb.KeyspaceIdType_UINT64, - ServedFrom: []*topodatapb.SrvKeyspace_ServedFrom{ - { - TabletType: topodatapb.TabletType_MASTER, - Keyspace: "other_keyspace", - }, - }, - } - got, err := conn.GetSrvKeyspace(context.Background(), "big") - if err != nil { - t.Fatalf("GetSrvKeyspace error: %v", err) - } - if !proto.Equal(got, want) { - t.Errorf("GetSrvKeyspace() = %v, want %v", proto.MarshalTextString(got), proto.MarshalTextString(want)) - } -} diff --git a/go/cmd/vtgateclienttest/grpcclienttest/grpc_goclient_test.go b/go/cmd/vtgateclienttest/grpcclienttest/grpc_goclient_test.go deleted file mode 100644 index f9ef8110ec9..00000000000 --- a/go/cmd/vtgateclienttest/grpcclienttest/grpc_goclient_test.go +++ /dev/null @@ -1,48 +0,0 @@ -/* -Copyright 2019 The Vitess Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package grpcclienttest - -import ( - "net" - "testing" - - "google.golang.org/grpc" - - "vitess.io/vitess/go/cmd/vtgateclienttest/goclienttest" - "vitess.io/vitess/go/cmd/vtgateclienttest/services" - "vitess.io/vitess/go/vt/vtgate/grpcvtgateservice" -) - -// TestGRPCGoClient tests the go client using gRPC -func TestGRPCGoClient(t *testing.T) { - service := services.CreateServices() - - // listen on a random port - listener, err := net.Listen("tcp", ":0") - if err != nil { - t.Fatalf("Cannot listen: %v", err) - } - defer listener.Close() - - // Create a gRPC server and listen on the port - server := grpc.NewServer() - grpcvtgateservice.RegisterForTest(server, service) - go server.Serve(listener) - - // and run the test suite - goclienttest.TestGoClient(t, "grpc", listener.Addr().String()) -} diff --git a/go/cmd/vtgateclienttest/services/callerid.go b/go/cmd/vtgateclienttest/services/callerid.go index 746c6c697b3..99d68781b46 100644 --- a/go/cmd/vtgateclienttest/services/callerid.go +++ b/go/cmd/vtgateclienttest/services/callerid.go @@ -29,7 +29,6 @@ import ( "vitess.io/vitess/go/vt/vtgate/vtgateservice" querypb "vitess.io/vitess/go/vt/proto/query" - topodatapb "vitess.io/vitess/go/vt/proto/topodata" vtgatepb "vitess.io/vitess/go/vt/proto/vtgate" vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" ) @@ -99,114 +98,3 @@ func (c *callerIDClient) StreamExecute(ctx context.Context, session *vtgatepb.Se } return c.fallbackClient.StreamExecute(ctx, session, sql, bindVariables, callback) } - -func (c *callerIDClient) ExecuteShards(ctx context.Context, sql string, bindVariables map[string]*querypb.BindVariable, keyspace string, shards []string, tabletType topodatapb.TabletType, session *vtgatepb.Session, notInTransaction bool, options *querypb.ExecuteOptions) (*sqltypes.Result, error) { - if ok, err := c.checkCallerID(ctx, sql); ok { - return nil, err - } - return c.fallbackClient.ExecuteShards(ctx, sql, bindVariables, keyspace, shards, tabletType, session, notInTransaction, options) -} - -func (c *callerIDClient) ExecuteKeyspaceIds(ctx context.Context, sql string, bindVariables map[string]*querypb.BindVariable, keyspace string, keyspaceIds [][]byte, tabletType topodatapb.TabletType, session *vtgatepb.Session, notInTransaction bool, options *querypb.ExecuteOptions) (*sqltypes.Result, error) { - if ok, err := c.checkCallerID(ctx, sql); ok { - return nil, err - } - return c.fallbackClient.ExecuteKeyspaceIds(ctx, sql, bindVariables, keyspace, keyspaceIds, tabletType, session, notInTransaction, options) -} - -func (c *callerIDClient) ExecuteKeyRanges(ctx context.Context, sql string, bindVariables map[string]*querypb.BindVariable, keyspace string, keyRanges []*topodatapb.KeyRange, tabletType topodatapb.TabletType, session *vtgatepb.Session, notInTransaction bool, options *querypb.ExecuteOptions) (*sqltypes.Result, error) { - if ok, err := c.checkCallerID(ctx, sql); ok { - return nil, err - } - return c.fallbackClient.ExecuteKeyRanges(ctx, sql, bindVariables, keyspace, keyRanges, tabletType, session, notInTransaction, options) -} - -func (c *callerIDClient) ExecuteEntityIds(ctx context.Context, sql string, bindVariables map[string]*querypb.BindVariable, keyspace string, entityColumnName string, entityKeyspaceIDs []*vtgatepb.ExecuteEntityIdsRequest_EntityId, tabletType topodatapb.TabletType, session *vtgatepb.Session, notInTransaction bool, options *querypb.ExecuteOptions) (*sqltypes.Result, error) { - if ok, err := c.checkCallerID(ctx, sql); ok { - return nil, err - } - return c.fallbackClient.ExecuteEntityIds(ctx, sql, bindVariables, keyspace, entityColumnName, entityKeyspaceIDs, tabletType, session, notInTransaction, options) -} - -func (c *callerIDClient) ExecuteBatchShards(ctx context.Context, queries []*vtgatepb.BoundShardQuery, tabletType topodatapb.TabletType, asTransaction bool, session *vtgatepb.Session, options *querypb.ExecuteOptions) ([]sqltypes.Result, error) { - if len(queries) == 1 { - if ok, err := c.checkCallerID(ctx, queries[0].Query.Sql); ok { - return nil, err - } - } - return c.fallbackClient.ExecuteBatchShards(ctx, queries, tabletType, asTransaction, session, options) -} - -func (c *callerIDClient) ExecuteBatchKeyspaceIds(ctx context.Context, queries []*vtgatepb.BoundKeyspaceIdQuery, tabletType topodatapb.TabletType, asTransaction bool, session *vtgatepb.Session, options *querypb.ExecuteOptions) ([]sqltypes.Result, error) { - if len(queries) == 1 { - if ok, err := c.checkCallerID(ctx, queries[0].Query.Sql); ok { - return nil, err - } - } - return c.fallbackClient.ExecuteBatchKeyspaceIds(ctx, queries, tabletType, asTransaction, session, options) -} - -func (c *callerIDClient) StreamExecuteShards(ctx context.Context, sql string, bindVariables map[string]*querypb.BindVariable, keyspace string, shards []string, tabletType topodatapb.TabletType, options *querypb.ExecuteOptions, callback func(*sqltypes.Result) error) error { - if ok, err := c.checkCallerID(ctx, sql); ok { - return err - } - return c.fallbackClient.StreamExecuteShards(ctx, sql, bindVariables, keyspace, shards, tabletType, options, callback) -} - -func (c *callerIDClient) StreamExecuteKeyspaceIds(ctx context.Context, sql string, bindVariables map[string]*querypb.BindVariable, keyspace string, keyspaceIds [][]byte, tabletType topodatapb.TabletType, options *querypb.ExecuteOptions, callback func(*sqltypes.Result) error) error { - if ok, err := c.checkCallerID(ctx, sql); ok { - return err - } - return c.fallbackClient.StreamExecuteKeyspaceIds(ctx, sql, bindVariables, keyspace, keyspaceIds, tabletType, options, callback) -} - -func (c *callerIDClient) StreamExecuteKeyRanges(ctx context.Context, sql string, bindVariables map[string]*querypb.BindVariable, keyspace string, keyRanges []*topodatapb.KeyRange, tabletType topodatapb.TabletType, options *querypb.ExecuteOptions, callback func(*sqltypes.Result) error) error { - if ok, err := c.checkCallerID(ctx, sql); ok { - return err - } - return c.fallbackClient.StreamExecuteKeyRanges(ctx, sql, bindVariables, keyspace, keyRanges, tabletType, options, callback) -} - -func (c *callerIDClient) MessageStream(ctx context.Context, keyspace string, shard string, keyRange *topodatapb.KeyRange, name string, callback func(*sqltypes.Result) error) error { - if ok, err := c.checkCallerID(ctx, name); ok { - return err - } - return c.fallback.MessageStream(ctx, keyspace, shard, keyRange, name, callback) -} - -func (c *callerIDClient) MessageAck(ctx context.Context, keyspace string, name string, ids []*querypb.Value) (int64, error) { - if ok, err := c.checkCallerID(ctx, name); ok { - return 0, err - } - return c.fallback.MessageAck(ctx, keyspace, name, ids) -} - -func (c *callerIDClient) SplitQuery( - ctx context.Context, - keyspace string, - sql string, - bindVariables map[string]*querypb.BindVariable, - splitColumns []string, - splitCount int64, - numRowsPerQueryPart int64, - algorithm querypb.SplitQueryRequest_Algorithm) ([]*vtgatepb.SplitQueryResponse_Part, error) { - if ok, err := c.checkCallerID(ctx, sql); ok { - return nil, err - } - return c.fallbackClient.SplitQuery( - ctx, - sql, - keyspace, - bindVariables, - splitColumns, - splitCount, - numRowsPerQueryPart, - algorithm) -} - -func (c *callerIDClient) UpdateStream(ctx context.Context, keyspace string, shard string, keyRange *topodatapb.KeyRange, tabletType topodatapb.TabletType, timestamp int64, event *querypb.EventToken, callback func(*querypb.StreamEvent, int64) error) error { - if ok, err := c.checkCallerID(ctx, shard); ok { - return err - } - return c.fallbackClient.UpdateStream(ctx, keyspace, shard, keyRange, tabletType, timestamp, event, callback) -} diff --git a/go/cmd/vtgateclienttest/services/echo.go b/go/cmd/vtgateclienttest/services/echo.go index f0b175d3d7e..4323defe961 100644 --- a/go/cmd/vtgateclienttest/services/echo.go +++ b/go/cmd/vtgateclienttest/services/echo.go @@ -95,16 +95,6 @@ func echoQueryResult(vals map[string]interface{}) *sqltypes.Result { } qr.Rows = [][]sqltypes.Value{row} - if options, ok := vals["options"]; ok { - o := options.(*querypb.ExecuteOptions) - if o != nil && o.CompareEventToken != nil { - qr.Extras = &querypb.ResultExtras{ - Fresher: true, - EventToken: o.CompareEventToken, - } - } - } - return qr } @@ -120,6 +110,19 @@ func (c *echoClient) Execute(ctx context.Context, session *vtgatepb.Session, sql return c.fallbackClient.Execute(ctx, session, sql, bindVariables) } +func (c *echoClient) StreamExecute(ctx context.Context, session *vtgatepb.Session, sql string, bindVariables map[string]*querypb.BindVariable, callback func(*sqltypes.Result) error) error { + if strings.HasPrefix(sql, EchoPrefix) { + callback(echoQueryResult(map[string]interface{}{ + "callerId": callerid.EffectiveCallerIDFromContext(ctx), + "query": sql, + "bindVars": bindVariables, + "session": session, + })) + return nil + } + return c.fallbackClient.StreamExecute(ctx, session, sql, bindVariables, callback) +} + func (c *echoClient) ExecuteBatch(ctx context.Context, session *vtgatepb.Session, sqlList []string, bindVariablesList []map[string]*querypb.BindVariable) (*vtgatepb.Session, []sqltypes.QueryResponse, error) { if len(sqlList) > 0 && strings.HasPrefix(sqlList[0], EchoPrefix) { var queryResponse []sqltypes.QueryResponse @@ -140,263 +143,6 @@ func (c *echoClient) ExecuteBatch(ctx context.Context, session *vtgatepb.Session return c.fallbackClient.ExecuteBatch(ctx, session, sqlList, bindVariablesList) } -func (c *echoClient) StreamExecute(ctx context.Context, session *vtgatepb.Session, sql string, bindVariables map[string]*querypb.BindVariable, callback func(*sqltypes.Result) error) error { - if strings.HasPrefix(sql, EchoPrefix) { - callback(echoQueryResult(map[string]interface{}{ - "callerId": callerid.EffectiveCallerIDFromContext(ctx), - "query": sql, - "bindVars": bindVariables, - "session": session, - })) - return nil - } - return c.fallbackClient.StreamExecute(ctx, session, sql, bindVariables, callback) -} - -func (c *echoClient) ExecuteShards(ctx context.Context, sql string, bindVariables map[string]*querypb.BindVariable, keyspace string, shards []string, tabletType topodatapb.TabletType, session *vtgatepb.Session, notInTransaction bool, options *querypb.ExecuteOptions) (*sqltypes.Result, error) { - if strings.HasPrefix(sql, EchoPrefix) { - return echoQueryResult(map[string]interface{}{ - "callerId": callerid.EffectiveCallerIDFromContext(ctx), - "query": sql, - "bindVars": bindVariables, - "keyspace": keyspace, - "shards": shards, - "tabletType": tabletType, - "session": session, - "notInTransaction": notInTransaction, - "options": options, - }), nil - } - return c.fallbackClient.ExecuteShards(ctx, sql, bindVariables, keyspace, shards, tabletType, session, notInTransaction, options) -} - -func (c *echoClient) ExecuteKeyspaceIds(ctx context.Context, sql string, bindVariables map[string]*querypb.BindVariable, keyspace string, keyspaceIds [][]byte, tabletType topodatapb.TabletType, session *vtgatepb.Session, notInTransaction bool, options *querypb.ExecuteOptions) (*sqltypes.Result, error) { - if strings.HasPrefix(sql, EchoPrefix) { - return echoQueryResult(map[string]interface{}{ - "callerId": callerid.EffectiveCallerIDFromContext(ctx), - "query": sql, - "bindVars": bindVariables, - "keyspace": keyspace, - "keyspaceIds": keyspaceIds, - "tabletType": tabletType, - "session": session, - "notInTransaction": notInTransaction, - "options": options, - }), nil - } - return c.fallbackClient.ExecuteKeyspaceIds(ctx, sql, bindVariables, keyspace, keyspaceIds, tabletType, session, notInTransaction, options) -} - -func (c *echoClient) ExecuteKeyRanges(ctx context.Context, sql string, bindVariables map[string]*querypb.BindVariable, keyspace string, keyRanges []*topodatapb.KeyRange, tabletType topodatapb.TabletType, session *vtgatepb.Session, notInTransaction bool, options *querypb.ExecuteOptions) (*sqltypes.Result, error) { - if strings.HasPrefix(sql, EchoPrefix) { - return echoQueryResult(map[string]interface{}{ - "callerId": callerid.EffectiveCallerIDFromContext(ctx), - "query": sql, - "bindVars": bindVariables, - "keyspace": keyspace, - "keyRanges": keyRanges, - "tabletType": tabletType, - "session": session, - "notInTransaction": notInTransaction, - "options": options, - }), nil - } - return c.fallbackClient.ExecuteKeyRanges(ctx, sql, bindVariables, keyspace, keyRanges, tabletType, session, notInTransaction, options) -} - -func (c *echoClient) ExecuteEntityIds(ctx context.Context, sql string, bindVariables map[string]*querypb.BindVariable, keyspace string, entityColumnName string, entityKeyspaceIDs []*vtgatepb.ExecuteEntityIdsRequest_EntityId, tabletType topodatapb.TabletType, session *vtgatepb.Session, notInTransaction bool, options *querypb.ExecuteOptions) (*sqltypes.Result, error) { - if strings.HasPrefix(sql, EchoPrefix) { - return echoQueryResult(map[string]interface{}{ - "callerId": callerid.EffectiveCallerIDFromContext(ctx), - "query": sql, - "bindVars": bindVariables, - "keyspace": keyspace, - "entityColumnName": entityColumnName, - "entityIds": entityKeyspaceIDs, - "tabletType": tabletType, - "session": session, - "notInTransaction": notInTransaction, - "options": options, - }), nil - } - return c.fallbackClient.ExecuteEntityIds(ctx, sql, bindVariables, keyspace, entityColumnName, entityKeyspaceIDs, tabletType, session, notInTransaction, options) -} - -func (c *echoClient) ExecuteBatchShards(ctx context.Context, queries []*vtgatepb.BoundShardQuery, tabletType topodatapb.TabletType, asTransaction bool, session *vtgatepb.Session, options *querypb.ExecuteOptions) ([]sqltypes.Result, error) { - if len(queries) > 0 && strings.HasPrefix(queries[0].Query.Sql, EchoPrefix) { - var result []sqltypes.Result - for _, query := range queries { - result = append(result, *echoQueryResult(map[string]interface{}{ - "callerId": callerid.EffectiveCallerIDFromContext(ctx), - "query": query.Query.Sql, - "bindVars": query.Query.BindVariables, - "keyspace": query.Keyspace, - "shards": query.Shards, - "tabletType": tabletType, - "session": session, - "asTransaction": asTransaction, - "options": options, - })) - } - return result, nil - } - return c.fallbackClient.ExecuteBatchShards(ctx, queries, tabletType, asTransaction, session, options) -} - -func (c *echoClient) ExecuteBatchKeyspaceIds(ctx context.Context, queries []*vtgatepb.BoundKeyspaceIdQuery, tabletType topodatapb.TabletType, asTransaction bool, session *vtgatepb.Session, options *querypb.ExecuteOptions) ([]sqltypes.Result, error) { - if len(queries) > 0 && strings.HasPrefix(queries[0].Query.Sql, EchoPrefix) { - var result []sqltypes.Result - for _, query := range queries { - result = append(result, *echoQueryResult(map[string]interface{}{ - "callerId": callerid.EffectiveCallerIDFromContext(ctx), - "query": query.Query.Sql, - "bindVars": query.Query.BindVariables, - "keyspace": query.Keyspace, - "keyspaceIds": query.KeyspaceIds, - "tabletType": tabletType, - "session": session, - "asTransaction": asTransaction, - "options": options, - })) - } - return result, nil - } - return c.fallbackClient.ExecuteBatchKeyspaceIds(ctx, queries, tabletType, asTransaction, session, options) -} - -func (c *echoClient) StreamExecuteShards(ctx context.Context, sql string, bindVariables map[string]*querypb.BindVariable, keyspace string, shards []string, tabletType topodatapb.TabletType, options *querypb.ExecuteOptions, callback func(*sqltypes.Result) error) error { - if strings.HasPrefix(sql, EchoPrefix) { - callback(echoQueryResult(map[string]interface{}{ - "callerId": callerid.EffectiveCallerIDFromContext(ctx), - "query": sql, - "bindVars": bindVariables, - "keyspace": keyspace, - "shards": shards, - "tabletType": tabletType, - "options": options, - })) - return nil - } - return c.fallbackClient.StreamExecuteShards(ctx, sql, bindVariables, keyspace, shards, tabletType, options, callback) -} - -func (c *echoClient) StreamExecuteKeyspaceIds(ctx context.Context, sql string, bindVariables map[string]*querypb.BindVariable, keyspace string, keyspaceIds [][]byte, tabletType topodatapb.TabletType, options *querypb.ExecuteOptions, callback func(*sqltypes.Result) error) error { - if strings.HasPrefix(sql, EchoPrefix) { - callback(echoQueryResult(map[string]interface{}{ - "callerId": callerid.EffectiveCallerIDFromContext(ctx), - "query": sql, - "bindVars": bindVariables, - "keyspace": keyspace, - "keyspaceIds": keyspaceIds, - "tabletType": tabletType, - "options": options, - })) - return nil - } - return c.fallbackClient.StreamExecuteKeyspaceIds(ctx, sql, bindVariables, keyspace, keyspaceIds, tabletType, options, callback) -} - -func (c *echoClient) StreamExecuteKeyRanges(ctx context.Context, sql string, bindVariables map[string]*querypb.BindVariable, keyspace string, keyRanges []*topodatapb.KeyRange, tabletType topodatapb.TabletType, options *querypb.ExecuteOptions, callback func(*sqltypes.Result) error) error { - if strings.HasPrefix(sql, EchoPrefix) { - callback(echoQueryResult(map[string]interface{}{ - "callerId": callerid.EffectiveCallerIDFromContext(ctx), - "query": sql, - "bindVars": bindVariables, - "keyspace": keyspace, - "keyRanges": keyRanges, - "tabletType": tabletType, - "options": options, - })) - return nil - } - return c.fallbackClient.StreamExecuteKeyRanges(ctx, sql, bindVariables, keyspace, keyRanges, tabletType, options, callback) -} - -func (c *echoClient) MessageStream(ctx context.Context, keyspace string, shard string, keyRange *topodatapb.KeyRange, name string, callback func(*sqltypes.Result) error) error { - if strings.HasPrefix(name, EchoPrefix) { - callback(echoQueryResult(map[string]interface{}{ - "callerId": callerid.EffectiveCallerIDFromContext(ctx), - "keyspace": keyspace, - "shard": shard, - "keyRange": keyRange, - "name": name, - })) - return nil - } - return c.fallbackClient.MessageStream(ctx, keyspace, shard, keyRange, name, callback) -} - -func (c *echoClient) MessageAck(ctx context.Context, keyspace string, name string, ids []*querypb.Value) (int64, error) { - if strings.HasPrefix(name, EchoPrefix) { - return int64(len(ids)), nil - } - return c.fallback.MessageAck(ctx, keyspace, name, ids) -} - -func (c *echoClient) MessageAckKeyspaceIds(ctx context.Context, keyspace string, name string, idKeyspaceIDs []*vtgatepb.IdKeyspaceId) (int64, error) { - if strings.HasPrefix(name, EchoPrefix) { - return int64(len(idKeyspaceIDs)), nil - } - return c.fallback.MessageAckKeyspaceIds(ctx, keyspace, name, idKeyspaceIDs) -} - -func (c *echoClient) SplitQuery( - ctx context.Context, - keyspace string, - sql string, - bindVariables map[string]*querypb.BindVariable, - splitColumns []string, - splitCount int64, - numRowsPerQueryPart int64, - algorithm querypb.SplitQueryRequest_Algorithm) ([]*vtgatepb.SplitQueryResponse_Part, error) { - - if strings.HasPrefix(sql, EchoPrefix) { - return []*vtgatepb.SplitQueryResponse_Part{ - { - Query: &querypb.BoundQuery{ - Sql: fmt.Sprintf("%v:%v:%v:%v:%v", - sql, splitColumns, splitCount, numRowsPerQueryPart, algorithm), - BindVariables: bindVariables, - }, - KeyRangePart: &vtgatepb.SplitQueryResponse_KeyRangePart{ - Keyspace: keyspace, - }, - }, - }, nil - } - return c.fallback.SplitQuery( - ctx, - sql, - keyspace, - bindVariables, - splitColumns, - splitCount, - numRowsPerQueryPart, - algorithm) -} - -func (c *echoClient) UpdateStream(ctx context.Context, keyspace string, shard string, keyRange *topodatapb.KeyRange, tabletType topodatapb.TabletType, timestamp int64, event *querypb.EventToken, callback func(*querypb.StreamEvent, int64) error) error { - if strings.HasPrefix(shard, EchoPrefix) { - m := map[string]interface{}{ - "callerId": callerid.EffectiveCallerIDFromContext(ctx), - "keyspace": keyspace, - "shard": shard, - "keyRange": keyRange, - "timestamp": timestamp, - "tabletType": tabletType, - "event": event, - } - bytes := printSortedMap(reflect.ValueOf(m)) - callback(&querypb.StreamEvent{ - EventToken: &querypb.EventToken{ - Position: string(bytes), - }, - }, 0) - return nil - } - return c.fallbackClient.UpdateStream(ctx, keyspace, shard, keyRange, tabletType, timestamp, event, callback) -} - func (c *echoClient) VStream(ctx context.Context, tabletType topodatapb.TabletType, vgtid *binlogdatapb.VGtid, filter *binlogdatapb.Filter, callback func([]*binlogdatapb.VEvent) error) error { if strings.HasPrefix(vgtid.ShardGtids[0].Shard, EchoPrefix) { _ = callback([]*binlogdatapb.VEvent{ diff --git a/go/cmd/vtgateclienttest/services/errors.go b/go/cmd/vtgateclienttest/services/errors.go index 4d82fbc83b7..ad2203b7509 100644 --- a/go/cmd/vtgateclienttest/services/errors.go +++ b/go/cmd/vtgateclienttest/services/errors.go @@ -22,12 +22,10 @@ import ( "golang.org/x/net/context" "vitess.io/vitess/go/sqltypes" - "vitess.io/vitess/go/vt/callerid" "vitess.io/vitess/go/vt/vterrors" "vitess.io/vitess/go/vt/vtgate/vtgateservice" querypb "vitess.io/vitess/go/vt/proto/query" - topodatapb "vitess.io/vitess/go/vt/proto/topodata" vtgatepb "vitess.io/vitess/go/vt/proto/vtgate" vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" ) @@ -141,189 +139,3 @@ func (c *errorClient) StreamExecute(ctx context.Context, session *vtgatepb.Sessi } return c.fallbackClient.StreamExecute(ctx, session, sql, bindVariables, callback) } - -func (c *errorClient) ExecuteShards(ctx context.Context, sql string, bindVariables map[string]*querypb.BindVariable, keyspace string, shards []string, tabletType topodatapb.TabletType, session *vtgatepb.Session, notInTransaction bool, options *querypb.ExecuteOptions) (*sqltypes.Result, error) { - if err := requestToPartialError(sql, session); err != nil { - return nil, err - } - if err := requestToError(sql); err != nil { - return nil, err - } - return c.fallbackClient.ExecuteShards(ctx, sql, bindVariables, keyspace, shards, tabletType, session, notInTransaction, options) -} - -func (c *errorClient) ExecuteKeyspaceIds(ctx context.Context, sql string, bindVariables map[string]*querypb.BindVariable, keyspace string, keyspaceIds [][]byte, tabletType topodatapb.TabletType, session *vtgatepb.Session, notInTransaction bool, options *querypb.ExecuteOptions) (*sqltypes.Result, error) { - if err := requestToPartialError(sql, session); err != nil { - return nil, err - } - if err := requestToError(sql); err != nil { - return nil, err - } - return c.fallbackClient.ExecuteKeyspaceIds(ctx, sql, bindVariables, keyspace, keyspaceIds, tabletType, session, notInTransaction, options) -} - -func (c *errorClient) ExecuteKeyRanges(ctx context.Context, sql string, bindVariables map[string]*querypb.BindVariable, keyspace string, keyRanges []*topodatapb.KeyRange, tabletType topodatapb.TabletType, session *vtgatepb.Session, notInTransaction bool, options *querypb.ExecuteOptions) (*sqltypes.Result, error) { - if err := requestToPartialError(sql, session); err != nil { - return nil, err - } - if err := requestToError(sql); err != nil { - return nil, err - } - return c.fallbackClient.ExecuteKeyRanges(ctx, sql, bindVariables, keyspace, keyRanges, tabletType, session, notInTransaction, options) -} - -func (c *errorClient) ExecuteEntityIds(ctx context.Context, sql string, bindVariables map[string]*querypb.BindVariable, keyspace string, entityColumnName string, entityKeyspaceIDs []*vtgatepb.ExecuteEntityIdsRequest_EntityId, tabletType topodatapb.TabletType, session *vtgatepb.Session, notInTransaction bool, options *querypb.ExecuteOptions) (*sqltypes.Result, error) { - if err := requestToPartialError(sql, session); err != nil { - return nil, err - } - if err := requestToError(sql); err != nil { - return nil, err - } - return c.fallbackClient.ExecuteEntityIds(ctx, sql, bindVariables, keyspace, entityColumnName, entityKeyspaceIDs, tabletType, session, notInTransaction, options) -} - -func (c *errorClient) ExecuteBatchShards(ctx context.Context, queries []*vtgatepb.BoundShardQuery, tabletType topodatapb.TabletType, asTransaction bool, session *vtgatepb.Session, options *querypb.ExecuteOptions) ([]sqltypes.Result, error) { - if len(queries) == 1 { - if err := requestToPartialError(queries[0].Query.Sql, session); err != nil { - return nil, err - } - if err := requestToError(queries[0].Query.Sql); err != nil { - return nil, err - } - } - return c.fallbackClient.ExecuteBatchShards(ctx, queries, tabletType, asTransaction, session, options) -} - -func (c *errorClient) ExecuteBatchKeyspaceIds(ctx context.Context, queries []*vtgatepb.BoundKeyspaceIdQuery, tabletType topodatapb.TabletType, asTransaction bool, session *vtgatepb.Session, options *querypb.ExecuteOptions) ([]sqltypes.Result, error) { - if len(queries) == 1 { - if err := requestToPartialError(queries[0].Query.Sql, session); err != nil { - return nil, err - } - if err := requestToError(queries[0].Query.Sql); err != nil { - return nil, err - } - } - return c.fallbackClient.ExecuteBatchKeyspaceIds(ctx, queries, tabletType, asTransaction, session, options) -} - -func (c *errorClient) StreamExecuteShards(ctx context.Context, sql string, bindVariables map[string]*querypb.BindVariable, keyspace string, shards []string, tabletType topodatapb.TabletType, options *querypb.ExecuteOptions, callback func(*sqltypes.Result) error) error { - if err := requestToError(sql); err != nil { - return err - } - return c.fallbackClient.StreamExecuteShards(ctx, sql, bindVariables, keyspace, shards, tabletType, options, callback) -} - -func (c *errorClient) StreamExecuteKeyspaceIds(ctx context.Context, sql string, bindVariables map[string]*querypb.BindVariable, keyspace string, keyspaceIds [][]byte, tabletType topodatapb.TabletType, options *querypb.ExecuteOptions, callback func(*sqltypes.Result) error) error { - if err := requestToError(sql); err != nil { - return err - } - return c.fallbackClient.StreamExecuteKeyspaceIds(ctx, sql, bindVariables, keyspace, keyspaceIds, tabletType, options, callback) -} - -func (c *errorClient) StreamExecuteKeyRanges(ctx context.Context, sql string, bindVariables map[string]*querypb.BindVariable, keyspace string, keyRanges []*topodatapb.KeyRange, tabletType topodatapb.TabletType, options *querypb.ExecuteOptions, callback func(*sqltypes.Result) error) error { - if err := requestToError(sql); err != nil { - return err - } - return c.fallbackClient.StreamExecuteKeyRanges(ctx, sql, bindVariables, keyspace, keyRanges, tabletType, options, callback) -} - -func (c *errorClient) Begin(ctx context.Context, singledb bool) (*vtgatepb.Session, error) { - // The client sends the error request through the callerid, as there are no other parameters - cid := callerid.EffectiveCallerIDFromContext(ctx) - request := callerid.GetPrincipal(cid) - if err := requestToError(request); err != nil { - return nil, err - } - return c.fallbackClient.Begin(ctx, singledb) -} - -func (c *errorClient) Commit(ctx context.Context, twopc bool, session *vtgatepb.Session) error { - // The client sends the error request through the callerid, as there are no other parameters - cid := callerid.EffectiveCallerIDFromContext(ctx) - request := callerid.GetPrincipal(cid) - if err := requestToError(request); err != nil { - return err - } - return c.fallbackClient.Commit(ctx, twopc, session) -} - -func (c *errorClient) Rollback(ctx context.Context, session *vtgatepb.Session) error { - // The client sends the error request through the callerid, as there are no other parameters - cid := callerid.EffectiveCallerIDFromContext(ctx) - request := callerid.GetPrincipal(cid) - if err := requestToError(request); err != nil { - return err - } - return c.fallbackClient.Rollback(ctx, session) -} - -func (c *errorClient) MessageStream(ctx context.Context, keyspace string, shard string, keyRange *topodatapb.KeyRange, name string, callback func(*sqltypes.Result) error) error { - cid := callerid.EffectiveCallerIDFromContext(ctx) - request := callerid.GetPrincipal(cid) - if err := requestToError(request); err != nil { - return err - } - if err := requestToError(name); err != nil { - return err - } - return c.fallback.MessageStream(ctx, keyspace, shard, keyRange, name, callback) -} - -func (c *errorClient) MessageAck(ctx context.Context, keyspace string, name string, ids []*querypb.Value) (int64, error) { - cid := callerid.EffectiveCallerIDFromContext(ctx) - request := callerid.GetPrincipal(cid) - if err := requestToError(request); err != nil { - return 0, err - } - if err := requestToError(name); err != nil { - return 0, err - } - return c.fallback.MessageAck(ctx, keyspace, name, ids) -} - -func (c *errorClient) MessageAckKeyspaceIds(ctx context.Context, keyspace string, name string, idKeyspaceIDs []*vtgatepb.IdKeyspaceId) (int64, error) { - cid := callerid.EffectiveCallerIDFromContext(ctx) - request := callerid.GetPrincipal(cid) - if err := requestToError(request); err != nil { - return 0, err - } - return c.fallback.MessageAckKeyspaceIds(ctx, keyspace, name, idKeyspaceIDs) -} - -func (c *errorClient) SplitQuery( - ctx context.Context, - keyspace string, - sql string, - bindVariables map[string]*querypb.BindVariable, - splitColumns []string, - splitCount int64, - numRowsPerQueryPart int64, - algorithm querypb.SplitQueryRequest_Algorithm) ([]*vtgatepb.SplitQueryResponse_Part, error) { - - if err := requestToError(sql); err != nil { - return nil, err - } - return c.fallbackClient.SplitQuery( - ctx, - sql, - keyspace, - bindVariables, - splitColumns, - splitCount, - numRowsPerQueryPart, - algorithm) -} - -func (c *errorClient) GetSrvKeyspace(ctx context.Context, keyspace string) (*topodatapb.SrvKeyspace, error) { - if err := requestToError(keyspace); err != nil { - return nil, err - } - return c.fallbackClient.GetSrvKeyspace(ctx, keyspace) -} - -func (c *errorClient) UpdateStream(ctx context.Context, keyspace string, shard string, keyRange *topodatapb.KeyRange, tabletType topodatapb.TabletType, timestamp int64, event *querypb.EventToken, callback func(*querypb.StreamEvent, int64) error) error { - if err := requestToError(shard); err != nil { - return err - } - return c.fallbackClient.UpdateStream(ctx, keyspace, shard, keyRange, tabletType, timestamp, event, callback) -} diff --git a/go/cmd/vtgateclienttest/services/fallback.go b/go/cmd/vtgateclienttest/services/fallback.go index ca895a0942f..1f8b8032afb 100644 --- a/go/cmd/vtgateclienttest/services/fallback.go +++ b/go/cmd/vtgateclienttest/services/fallback.go @@ -52,96 +52,14 @@ func (c fallbackClient) StreamExecute(ctx context.Context, session *vtgatepb.Ses return c.fallback.StreamExecute(ctx, session, sql, bindVariables, callback) } -func (c fallbackClient) ExecuteShards(ctx context.Context, sql string, bindVariables map[string]*querypb.BindVariable, keyspace string, shards []string, tabletType topodatapb.TabletType, session *vtgatepb.Session, notInTransaction bool, options *querypb.ExecuteOptions) (*sqltypes.Result, error) { - return c.fallback.ExecuteShards(ctx, sql, bindVariables, keyspace, shards, tabletType, session, notInTransaction, options) -} - -func (c fallbackClient) ExecuteKeyspaceIds(ctx context.Context, sql string, bindVariables map[string]*querypb.BindVariable, keyspace string, keyspaceIds [][]byte, tabletType topodatapb.TabletType, session *vtgatepb.Session, notInTransaction bool, options *querypb.ExecuteOptions) (*sqltypes.Result, error) { - return c.fallback.ExecuteKeyspaceIds(ctx, sql, bindVariables, keyspace, keyspaceIds, tabletType, session, notInTransaction, options) -} - -func (c fallbackClient) ExecuteKeyRanges(ctx context.Context, sql string, bindVariables map[string]*querypb.BindVariable, keyspace string, keyRanges []*topodatapb.KeyRange, tabletType topodatapb.TabletType, session *vtgatepb.Session, notInTransaction bool, options *querypb.ExecuteOptions) (*sqltypes.Result, error) { - return c.fallback.ExecuteKeyRanges(ctx, sql, bindVariables, keyspace, keyRanges, tabletType, session, notInTransaction, options) -} - -func (c fallbackClient) ExecuteEntityIds(ctx context.Context, sql string, bindVariables map[string]*querypb.BindVariable, keyspace string, entityColumnName string, entityKeyspaceIDs []*vtgatepb.ExecuteEntityIdsRequest_EntityId, tabletType topodatapb.TabletType, session *vtgatepb.Session, notInTransaction bool, options *querypb.ExecuteOptions) (*sqltypes.Result, error) { - return c.fallback.ExecuteEntityIds(ctx, sql, bindVariables, keyspace, entityColumnName, entityKeyspaceIDs, tabletType, session, notInTransaction, options) -} - -func (c fallbackClient) ExecuteBatchShards(ctx context.Context, queries []*vtgatepb.BoundShardQuery, tabletType topodatapb.TabletType, asTransaction bool, session *vtgatepb.Session, options *querypb.ExecuteOptions) ([]sqltypes.Result, error) { - return c.fallback.ExecuteBatchShards(ctx, queries, tabletType, asTransaction, session, options) -} - -func (c fallbackClient) ExecuteBatchKeyspaceIds(ctx context.Context, queries []*vtgatepb.BoundKeyspaceIdQuery, tabletType topodatapb.TabletType, asTransaction bool, session *vtgatepb.Session, options *querypb.ExecuteOptions) ([]sqltypes.Result, error) { - return c.fallback.ExecuteBatchKeyspaceIds(ctx, queries, tabletType, asTransaction, session, options) -} - -func (c fallbackClient) StreamExecuteShards(ctx context.Context, sql string, bindVariables map[string]*querypb.BindVariable, keyspace string, shards []string, tabletType topodatapb.TabletType, options *querypb.ExecuteOptions, callback func(*sqltypes.Result) error) error { - return c.fallback.StreamExecuteShards(ctx, sql, bindVariables, keyspace, shards, tabletType, options, callback) -} - -func (c fallbackClient) StreamExecuteKeyspaceIds(ctx context.Context, sql string, bindVariables map[string]*querypb.BindVariable, keyspace string, keyspaceIds [][]byte, tabletType topodatapb.TabletType, options *querypb.ExecuteOptions, callback func(*sqltypes.Result) error) error { - return c.fallback.StreamExecuteKeyspaceIds(ctx, sql, bindVariables, keyspace, keyspaceIds, tabletType, options, callback) -} - -func (c fallbackClient) StreamExecuteKeyRanges(ctx context.Context, sql string, bindVariables map[string]*querypb.BindVariable, keyspace string, keyRanges []*topodatapb.KeyRange, tabletType topodatapb.TabletType, options *querypb.ExecuteOptions, callback func(*sqltypes.Result) error) error { - return c.fallback.StreamExecuteKeyRanges(ctx, sql, bindVariables, keyspace, keyRanges, tabletType, options, callback) -} - -func (c fallbackClient) Begin(ctx context.Context, singledb bool) (*vtgatepb.Session, error) { - return c.fallback.Begin(ctx, singledb) -} - -func (c fallbackClient) Commit(ctx context.Context, twopc bool, session *vtgatepb.Session) error { - return c.fallback.Commit(ctx, twopc, session) -} - -func (c fallbackClient) Rollback(ctx context.Context, session *vtgatepb.Session) error { - return c.fallback.Rollback(ctx, session) -} - func (c fallbackClient) ResolveTransaction(ctx context.Context, dtid string) error { return c.fallback.ResolveTransaction(ctx, dtid) } -func (c fallbackClient) MessageStream(ctx context.Context, keyspace string, shard string, keyRange *topodatapb.KeyRange, name string, callback func(*sqltypes.Result) error) error { - return c.fallback.MessageStream(ctx, keyspace, shard, keyRange, name, callback) -} - -func (c fallbackClient) MessageAck(ctx context.Context, keyspace string, name string, ids []*querypb.Value) (int64, error) { - return c.fallback.MessageAck(ctx, keyspace, name, ids) -} - -func (c fallbackClient) MessageAckKeyspaceIds(ctx context.Context, keyspace string, name string, idKeyspaceIDs []*vtgatepb.IdKeyspaceId) (int64, error) { - return c.fallback.MessageAckKeyspaceIds(ctx, keyspace, name, idKeyspaceIDs) -} - -func (c fallbackClient) SplitQuery( - ctx context.Context, - keyspace string, - sql string, - bindVariables map[string]*querypb.BindVariable, - splitColumns []string, - splitCount int64, - numRowsPerQueryPart int64, - algorithm querypb.SplitQueryRequest_Algorithm, -) ([]*vtgatepb.SplitQueryResponse_Part, error) { - return c.fallback.SplitQuery( - ctx, sql, keyspace, bindVariables, splitColumns, splitCount, numRowsPerQueryPart, algorithm) -} - -func (c fallbackClient) GetSrvKeyspace(ctx context.Context, keyspace string) (*topodatapb.SrvKeyspace, error) { - return c.fallback.GetSrvKeyspace(ctx, keyspace) -} - func (c fallbackClient) VStream(ctx context.Context, tabletType topodatapb.TabletType, vgtid *binlogdatapb.VGtid, filter *binlogdatapb.Filter, send func([]*binlogdatapb.VEvent) error) error { return c.fallback.VStream(ctx, tabletType, vgtid, filter, send) } -func (c fallbackClient) UpdateStream(ctx context.Context, keyspace string, shard string, keyRange *topodatapb.KeyRange, tabletType topodatapb.TabletType, timestamp int64, event *querypb.EventToken, callback func(*querypb.StreamEvent, int64) error) error { - return c.fallback.UpdateStream(ctx, keyspace, shard, keyRange, tabletType, timestamp, event, callback) -} - func (c fallbackClient) HandlePanic(err *error) { c.fallback.HandlePanic(err) } diff --git a/go/cmd/vtgateclienttest/services/services.go b/go/cmd/vtgateclienttest/services/services.go index f43c1456741..999c000e736 100644 --- a/go/cmd/vtgateclienttest/services/services.go +++ b/go/cmd/vtgateclienttest/services/services.go @@ -25,7 +25,6 @@ import ( func CreateServices() vtgateservice.VTGateService { var s vtgateservice.VTGateService s = newTerminalClient() - s = newSuccessClient(s) s = newErrorClient(s) s = newCallerIDClient(s) s = newEchoClient(s) diff --git a/go/cmd/vtgateclienttest/services/success.go b/go/cmd/vtgateclienttest/services/success.go deleted file mode 100644 index 0a78cbdde5d..00000000000 --- a/go/cmd/vtgateclienttest/services/success.go +++ /dev/null @@ -1,92 +0,0 @@ -/* -Copyright 2019 The Vitess Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package services - -import ( - "golang.org/x/net/context" - - "vitess.io/vitess/go/vt/vtgate/vtgateservice" - - topodatapb "vitess.io/vitess/go/vt/proto/topodata" - vtgatepb "vitess.io/vitess/go/vt/proto/vtgate" -) - -// successClient implements vtgateservice.VTGateService -// and returns specific values. It is meant to test all possible success cases, -// and make sure all clients handle any corner case correctly. -type successClient struct { - fallbackClient -} - -func newSuccessClient(fallback vtgateservice.VTGateService) *successClient { - return &successClient{ - fallbackClient: newFallbackClient(fallback), - } -} - -func (c *successClient) Begin(ctx context.Context, singledb bool) (*vtgatepb.Session, error) { - return &vtgatepb.Session{ - InTransaction: true, - }, nil -} - -func (c *successClient) Commit(ctx context.Context, twopc bool, session *vtgatepb.Session) error { - if session != nil && session.InTransaction { - return nil - } - return c.fallback.Commit(ctx, twopc, session) -} - -func (c *successClient) Rollback(ctx context.Context, session *vtgatepb.Session) error { - if session != nil && session.InTransaction { - return nil - } - return c.fallback.Rollback(ctx, session) -} - -func (c *successClient) GetSrvKeyspace(ctx context.Context, keyspace string) (*topodatapb.SrvKeyspace, error) { - if keyspace == "big" { - return &topodatapb.SrvKeyspace{ - Partitions: []*topodatapb.SrvKeyspace_KeyspacePartition{ - { - ServedType: topodatapb.TabletType_REPLICA, - ShardReferences: []*topodatapb.ShardReference{ - { - Name: "shard0", - KeyRange: &topodatapb.KeyRange{ - Start: []byte{0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - End: []byte{0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - }, - }, - }, - }, - }, - ShardingColumnName: "sharding_column_name", - ShardingColumnType: topodatapb.KeyspaceIdType_UINT64, - ServedFrom: []*topodatapb.SrvKeyspace_ServedFrom{ - { - TabletType: topodatapb.TabletType_MASTER, - Keyspace: "other_keyspace", - }, - }, - }, nil - } - if keyspace == "small" { - return &topodatapb.SrvKeyspace{}, nil - } - return c.fallback.GetSrvKeyspace(ctx, keyspace) -} diff --git a/go/cmd/vtgateclienttest/services/terminal.go b/go/cmd/vtgateclienttest/services/terminal.go index 7d828c79a38..43a104b7a71 100644 --- a/go/cmd/vtgateclienttest/services/terminal.go +++ b/go/cmd/vtgateclienttest/services/terminal.go @@ -61,95 +61,14 @@ func (c *terminalClient) StreamExecute(ctx context.Context, session *vtgatepb.Se return errTerminal } -func (c *terminalClient) ExecuteShards(ctx context.Context, sql string, bindVariables map[string]*querypb.BindVariable, keyspace string, shards []string, tabletType topodatapb.TabletType, session *vtgatepb.Session, notInTransaction bool, options *querypb.ExecuteOptions) (*sqltypes.Result, error) { - return nil, errTerminal -} - -func (c *terminalClient) ExecuteKeyspaceIds(ctx context.Context, sql string, bindVariables map[string]*querypb.BindVariable, keyspace string, keyspaceIds [][]byte, tabletType topodatapb.TabletType, session *vtgatepb.Session, notInTransaction bool, options *querypb.ExecuteOptions) (*sqltypes.Result, error) { - return nil, errTerminal -} - -func (c *terminalClient) ExecuteKeyRanges(ctx context.Context, sql string, bindVariables map[string]*querypb.BindVariable, keyspace string, keyRanges []*topodatapb.KeyRange, tabletType topodatapb.TabletType, session *vtgatepb.Session, notInTransaction bool, options *querypb.ExecuteOptions) (*sqltypes.Result, error) { - return nil, errTerminal -} - -func (c *terminalClient) ExecuteEntityIds(ctx context.Context, sql string, bindVariables map[string]*querypb.BindVariable, keyspace string, entityColumnName string, entityKeyspaceIDs []*vtgatepb.ExecuteEntityIdsRequest_EntityId, tabletType topodatapb.TabletType, session *vtgatepb.Session, notInTransaction bool, options *querypb.ExecuteOptions) (*sqltypes.Result, error) { - return nil, errTerminal -} - -func (c *terminalClient) ExecuteBatchShards(ctx context.Context, queries []*vtgatepb.BoundShardQuery, tabletType topodatapb.TabletType, asTransaction bool, session *vtgatepb.Session, options *querypb.ExecuteOptions) ([]sqltypes.Result, error) { - return nil, errTerminal -} - -func (c *terminalClient) ExecuteBatchKeyspaceIds(ctx context.Context, queries []*vtgatepb.BoundKeyspaceIdQuery, tabletType topodatapb.TabletType, asTransaction bool, session *vtgatepb.Session, options *querypb.ExecuteOptions) ([]sqltypes.Result, error) { - return nil, errTerminal -} - -func (c *terminalClient) StreamExecuteShards(ctx context.Context, sql string, bindVariables map[string]*querypb.BindVariable, keyspace string, shards []string, tabletType topodatapb.TabletType, options *querypb.ExecuteOptions, callback func(*sqltypes.Result) error) error { - return errTerminal -} - -func (c *terminalClient) StreamExecuteKeyspaceIds(ctx context.Context, sql string, bindVariables map[string]*querypb.BindVariable, keyspace string, keyspaceIds [][]byte, tabletType topodatapb.TabletType, options *querypb.ExecuteOptions, callback func(*sqltypes.Result) error) error { - return errTerminal -} - -func (c *terminalClient) StreamExecuteKeyRanges(ctx context.Context, sql string, bindVariables map[string]*querypb.BindVariable, keyspace string, keyRanges []*topodatapb.KeyRange, tabletType topodatapb.TabletType, options *querypb.ExecuteOptions, callback func(*sqltypes.Result) error) error { - return errTerminal -} - -func (c *terminalClient) Begin(ctx context.Context, singledb bool) (*vtgatepb.Session, error) { - return nil, errTerminal -} - -func (c *terminalClient) Commit(ctx context.Context, twopc bool, session *vtgatepb.Session) error { - return errTerminal -} - -func (c *terminalClient) Rollback(ctx context.Context, session *vtgatepb.Session) error { - return errTerminal -} - func (c *terminalClient) ResolveTransaction(ctx context.Context, dtid string) error { return errTerminal } -func (c *terminalClient) MessageStream(ctx context.Context, keyspace string, shard string, keyRange *topodatapb.KeyRange, name string, callback func(*sqltypes.Result) error) error { - return errTerminal -} - -func (c *terminalClient) MessageAck(ctx context.Context, keyspace string, name string, ids []*querypb.Value) (int64, error) { - return 0, errTerminal -} - -func (c *terminalClient) MessageAckKeyspaceIds(ctx context.Context, keyspace string, name string, idKeyspaceIDs []*vtgatepb.IdKeyspaceId) (int64, error) { - return 0, errTerminal -} - -func (c *terminalClient) SplitQuery( - ctx context.Context, - keyspace string, - sql string, - bindVariables map[string]*querypb.BindVariable, - splitColumns []string, - splitCount int64, - numRowsPerQueryPart int64, - algorithm querypb.SplitQueryRequest_Algorithm, -) ([]*vtgatepb.SplitQueryResponse_Part, error) { - return nil, errTerminal -} - -func (c *terminalClient) GetSrvKeyspace(ctx context.Context, keyspace string) (*topodatapb.SrvKeyspace, error) { - return nil, errTerminal -} - func (c *terminalClient) VStream(ctx context.Context, tabletType topodatapb.TabletType, vgtid *binlogdatapb.VGtid, filter *binlogdatapb.Filter, send func([]*binlogdatapb.VEvent) error) error { return errTerminal } -func (c *terminalClient) UpdateStream(ctx context.Context, keyspace string, shard string, keyRange *topodatapb.KeyRange, tabletType topodatapb.TabletType, timestamp int64, event *querypb.EventToken, callback func(*querypb.StreamEvent, int64) error) error { - return errTerminal -} - func (c *terminalClient) HandlePanic(err *error) { if x := recover(); x != nil { log.Errorf("Uncaught panic:\n%v\n%s", x, tb.Stack(4)) diff --git a/go/cmd/vttablet/plugin_azblobbackupstorage.go b/go/cmd/vttablet/plugin_azblobbackupstorage.go new file mode 100644 index 00000000000..a4ca64096a9 --- /dev/null +++ b/go/cmd/vttablet/plugin_azblobbackupstorage.go @@ -0,0 +1,21 @@ +/* +Copyright 2020 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +import ( + _ "vitess.io/vitess/go/vt/mysqlctl/azblobbackupstorage" +) diff --git a/go/cmd/vttablet/status.go b/go/cmd/vttablet/status.go index fa183bad5ed..920e5f70445 100644 --- a/go/cmd/vttablet/status.go +++ b/go/cmd/vttablet/status.go @@ -30,6 +30,7 @@ import ( var ( // tabletTemplate contains the style sheet and the tablet itself. + // This template is a slight duplicate of the one in go/vt/vttablet/tabletserver/status.go. tabletTemplate = ` \n\n \n \n\n \n\n\n Loading...\n\n\n"), } fileh := &embedded.EmbeddedFile{ Filename: "inline.js", - FileModTime: time.Unix(1576651902, 0), + FileModTime: time.Unix(1585527421, 0), Content: string("!function(e){function __webpack_require__(r){if(t[r])return t[r].exports;var n=t[r]={i:r,l:!1,exports:{}};return e[r].call(n.exports,n,n.exports,__webpack_require__),n.l=!0,n.exports}var r=window.webpackJsonp;window.webpackJsonp=function(t,o,c){for(var _,a,i,u=0,p=[];u1;){var o=r.shift();i=i.hasOwnProperty(o)&&isPresent(i[o])?i[o]:i[o]={}}void 0!==i&&null!==i||(i={}),i[r.shift()]=n}function getSymbolIterator(){if(isBlank(h))if(isPresent(n.Symbol)&&isPresent(Symbol.iterator))h=Symbol.iterator;else for(var e=Object.getOwnPropertyNames(Map.prototype),t=0;t=0&&e[r]==t;r--)n--;e=e.substring(0,n)}return e},StringWrapper.replace=function(e,t,n){return e.replace(t,n)},StringWrapper.replaceAll=function(e,t,n){return e.replace(t,n)},StringWrapper.slice=function(e,t,n){return void 0===t&&(t=0),void 0===n&&(n=null),e.slice(t,null===n?void 0:n)},StringWrapper.replaceAllMapped=function(e,t,n){return e.replace(t,function(){for(var e=[],t=0;tt?1:0},StringWrapper}();t.StringWrapper=s;var a=function(){function StringJoiner(e){void 0===e&&(e=[]),this.parts=e}return StringJoiner.prototype.add=function(e){this.parts.push(e)},StringJoiner.prototype.toString=function(){return this.parts.join(\"\")},StringJoiner}();t.StringJoiner=a;var l=function(e){function NumberParseError(t){e.call(this),this.message=t}return r(NumberParseError,e),NumberParseError.prototype.toString=function(){return this.message},NumberParseError}(Error);t.NumberParseError=l;var c=function(){function NumberWrapper(){}return NumberWrapper.toFixed=function(e,t){return e.toFixed(t)},NumberWrapper.equal=function(e,t){return e===t},NumberWrapper.parseIntAutoRadix=function(e){var t=parseInt(e);if(isNaN(t))throw new l(\"Invalid integer literal when parsing \"+e);return t},NumberWrapper.parseInt=function(e,t){if(10==t){if(/^(\\-|\\+)?[0-9]+$/.test(e))return parseInt(e,t)}else if(16==t){if(/^(\\-|\\+)?[0-9ABCDEFabcdef]+$/.test(e))return parseInt(e,t)}else{var n=parseInt(e,t);if(!isNaN(n))return n}throw new l(\"Invalid integer literal when parsing \"+e+\" in base \"+t)},NumberWrapper.parseFloat=function(e){return parseFloat(e)},Object.defineProperty(NumberWrapper,\"NaN\",{get:function(){return NaN},enumerable:!0,configurable:!0}),NumberWrapper.isNumeric=function(e){return!isNaN(e-parseFloat(e))},NumberWrapper.isNaN=function(e){return isNaN(e)},NumberWrapper.isInteger=function(e){return Number.isInteger(e)},NumberWrapper}();t.NumberWrapper=c,t.RegExp=i.RegExp;var u=function(){function FunctionWrapper(){}return FunctionWrapper.apply=function(e,t){return e.apply(null,t)},FunctionWrapper.bind=function(e,t){return e.bind(t)},FunctionWrapper}();t.FunctionWrapper=u,t.looseIdentical=looseIdentical,t.getMapKey=getMapKey,t.normalizeBlank=normalizeBlank,t.normalizeBool=normalizeBool,t.isJsObject=isJsObject,t.print=print,t.warn=warn;var p=function(){function Json(){}return Json.parse=function(e){return i.JSON.parse(e)},Json.stringify=function(e){return i.JSON.stringify(e,null,2)},Json}();t.Json=p;var d=function(){function DateWrapper(){}return DateWrapper.create=function(e,n,r,i,o,s,a){return void 0===n&&(n=1),void 0===r&&(r=1),void 0===i&&(i=0),void 0===o&&(o=0),void 0===s&&(s=0),void 0===a&&(a=0),new t.Date(e,n-1,r,i,o,s,a)},DateWrapper.fromISOString=function(e){return new t.Date(e)},DateWrapper.fromMillis=function(e){return new t.Date(e)},DateWrapper.toMillis=function(e){return e.getTime()},DateWrapper.now=function(){return new t.Date},DateWrapper.toJson=function(e){return e.toJSON()},DateWrapper}();t.DateWrapper=d,t.setValueOnPath=setValueOnPath;var h=null;t.getSymbolIterator=getSymbolIterator,t.evalExpression=evalExpression,t.isPrimitive=isPrimitive,t.hasConstructor=hasConstructor,t.escape=escape,t.escapeRegExp=escapeRegExp}).call(t,n(82))},4,function(e,t,n){\"use strict\";var r=this&&this.__extends||function(e,t){function __(){this.constructor=e}for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);e.prototype=null===t?Object.create(t):(__.prototype=t.prototype,new __)},i=n(217),o=n(41),s=n(215),a=n(897),l=function(e){function Subscriber(t,n,r){switch(e.call(this),this.syncErrorValue=null,this.syncErrorThrown=!1,this.syncErrorThrowable=!1,this.isStopped=!1,arguments.length){case 0:this.destination=a.empty;break;case 1:if(!t){this.destination=a.empty;break}if(\"object\"==typeof t){t instanceof Subscriber?(this.destination=t,this.destination.add(this)):(this.syncErrorThrowable=!0,this.destination=new c(this,t));break}default:this.syncErrorThrowable=!0,this.destination=new c(this,t,n,r)}}return r(Subscriber,e),Subscriber.create=function(e,t,n){var r=new Subscriber(e,t,n);return r.syncErrorThrowable=!1,r},Subscriber.prototype.next=function(e){this.isStopped||this._next(e)},Subscriber.prototype.error=function(e){this.isStopped||(this.isStopped=!0,this._error(e))},Subscriber.prototype.complete=function(){this.isStopped||(this.isStopped=!0,this._complete())},Subscriber.prototype.unsubscribe=function(){this.isUnsubscribed||(this.isStopped=!0,e.prototype.unsubscribe.call(this))},Subscriber.prototype._next=function(e){this.destination.next(e)},Subscriber.prototype._error=function(e){this.destination.error(e),this.unsubscribe()},Subscriber.prototype._complete=function(){this.destination.complete(),this.unsubscribe()},Subscriber.prototype[s.$$rxSubscriber]=function(){return this},Subscriber}(o.Subscription);t.Subscriber=l;var c=function(e){function SafeSubscriber(t,n,r,o){e.call(this),this._parent=t;var s,a=this;i.isFunction(n)?s=n:n&&(a=n,s=n.next,r=n.error,o=n.complete,i.isFunction(a.unsubscribe)&&this.add(a.unsubscribe.bind(a)),a.unsubscribe=this.unsubscribe.bind(this)),this._context=a,this._next=s,this._error=r,this._complete=o}return r(SafeSubscriber,e),SafeSubscriber.prototype.next=function(e){if(!this.isStopped&&this._next){var t=this._parent;t.syncErrorThrowable?this.__tryOrSetError(t,this._next,e)&&this.unsubscribe():this.__tryOrUnsub(this._next,e)}},SafeSubscriber.prototype.error=function(e){if(!this.isStopped){var t=this._parent;if(this._error)t.syncErrorThrowable?(this.__tryOrSetError(t,this._error,e),this.unsubscribe()):(this.__tryOrUnsub(this._error,e),this.unsubscribe());else{if(!t.syncErrorThrowable)throw this.unsubscribe(),e;t.syncErrorValue=e,t.syncErrorThrown=!0,this.unsubscribe()}}},SafeSubscriber.prototype.complete=function(){if(!this.isStopped){var e=this._parent;this._complete?e.syncErrorThrowable?(this.__tryOrSetError(e,this._complete),this.unsubscribe()):(this.__tryOrUnsub(this._complete),this.unsubscribe()):this.unsubscribe()}},SafeSubscriber.prototype.__tryOrUnsub=function(e,t){try{e.call(this._context,t)}catch(n){throw this.unsubscribe(),n}},SafeSubscriber.prototype.__tryOrSetError=function(e,t,n){try{t.call(this._context,n)}catch(r){return e.syncErrorValue=r,e.syncErrorThrown=!0,!0}return!1},SafeSubscriber.prototype._unsubscribe=function(){var e=this._parent;this._context=null,this._parent=null,e.unsubscribe()},SafeSubscriber}(l)},4,function(e,t,n){var r=n(15);e.exports=function(e){if(!r(e))throw TypeError(e+\" is not an object!\");return e}},function(e,t,n){\"use strict\";var r=this&&this.__decorate||function(e,t,n,r){var i,o=arguments.length,s=o<3?t:null===r?r=Object.getOwnPropertyDescriptor(t,n):r;if(\"object\"==typeof Reflect&&\"function\"==typeof Reflect.decorate)s=Reflect.decorate(e,t,n,r);else for(var a=e.length-1;a>=0;a--)(i=e[a])&&(s=(o<3?i(s):o>3?i(t,n,s):i(t,n))||s);return o>3&&s&&Object.defineProperty(t,n,s),s},i=this&&this.__metadata||function(e,t){if(\"object\"==typeof Reflect&&\"function\"==typeof Reflect.metadata)return Reflect.metadata(e,t)},o=n(0),s=function(){function DomHandler(){}return DomHandler.prototype.addClass=function(e,t){e.classList?e.classList.add(t):e.className+=\" \"+t},DomHandler.prototype.addMultipleClasses=function(e,t){if(e.classList)for(var n=t.split(\" \"),r=0;rwindow.innerHeight?-1*i.height:o,r=a.left+i.width>window.innerWidth?s-i.width:0,e.style.top=n+\"px\",e.style.left=r+\"px\"},DomHandler.prototype.absolutePosition=function(e,t){var n,r,i=e.offsetParent?{width:e.offsetWidth,height:e.offsetHeight}:this.getHiddenElementDimensions(e),o=i.height,s=i.width,a=t.offsetHeight,l=t.offsetWidth,c=t.getBoundingClientRect(),u=this.getWindowScrollTop(),p=this.getWindowScrollLeft();n=c.top+a+o>window.innerHeight?c.top+u-o:a+c.top+u,r=c.left+l+s>window.innerWidth?c.left+p+l-s:c.left+p,e.style.top=n+\"px\",e.style.left=r+\"px\"},DomHandler.prototype.getHiddenElementOuterHeight=function(e){e.style.visibility=\"hidden\",e.style.display=\"block\";var t=e.offsetHeight;return e.style.display=\"none\",e.style.visibility=\"visible\",t},DomHandler.prototype.getHiddenElementOuterWidth=function(e){e.style.visibility=\"hidden\",e.style.display=\"block\";var t=e.offsetWidth;return e.style.display=\"none\",e.style.visibility=\"visible\",t},DomHandler.prototype.getHiddenElementDimensions=function(e){var t={};return e.style.visibility=\"hidden\",e.style.display=\"block\",t.width=e.offsetWidth,t.height=e.offsetHeight,e.style.display=\"none\",e.style.visibility=\"visible\",t},DomHandler.prototype.scrollInView=function(e,t){var n=getComputedStyle(e).getPropertyValue(\"borderTopWidth\"),r=n?parseFloat(n):0,i=getComputedStyle(e).getPropertyValue(\"paddingTop\"),o=i?parseFloat(i):0,s=e.getBoundingClientRect(),a=t.getBoundingClientRect(),l=a.top+document.body.scrollTop-(s.top+document.body.scrollTop)-r-o,c=e.scrollTop,u=e.clientHeight,p=this.getOuterHeight(t);l<0?e.scrollTop=c+l:l+p>u&&(e.scrollTop=c+l-u+p)},DomHandler.prototype.fadeIn=function(e,t){e.style.opacity=0;var n=+new Date,r=function(){e.style.opacity=+e.style.opacity+((new Date).getTime()-n)/t,n=+new Date,+e.style.opacity<1&&(window.requestAnimationFrame&&requestAnimationFrame(r)||setTimeout(r,16))};r()},DomHandler.prototype.fadeOut=function(e,t){var n=1,r=50,i=t,o=r/i,s=setInterval(function(){n-=o,e.style.opacity=n,n<=0&&clearInterval(s)},r)},DomHandler.prototype.getWindowScrollTop=function(){var e=document.documentElement;return(window.pageYOffset||e.scrollTop)-(e.clientTop||0)},DomHandler.prototype.getWindowScrollLeft=function(){var e=document.documentElement;return(window.pageXOffset||e.scrollLeft)-(e.clientLeft||0)},DomHandler.prototype.matches=function(e,t){var n=Element.prototype,r=n.matches||n.webkitMatchesSelector||n.mozMatchesSelector||n.msMatchesSelector||function(e){return[].indexOf.call(document.querySelectorAll(e),this)!==-1};return r.call(e,t)},DomHandler.prototype.getOuterWidth=function(e,t){var n=e.offsetWidth;if(t){var r=getComputedStyle(e);n+=parseInt(r.paddingLeft)+parseInt(r.paddingRight)}return n},DomHandler.prototype.getHorizontalMargin=function(e){var t=getComputedStyle(e);return parseInt(t.marginLeft)+parseInt(t.marginRight)},DomHandler.prototype.innerWidth=function(e){var t=e.offsetWidth,n=getComputedStyle(e);return t+=parseInt(n.paddingLeft)+parseInt(n.paddingRight)},DomHandler.prototype.width=function(e){var t=e.offsetWidth,n=getComputedStyle(e);return t-=parseInt(n.paddingLeft)+parseInt(n.paddingRight)},DomHandler.prototype.getOuterHeight=function(e,t){var n=e.offsetHeight;if(t){var r=getComputedStyle(e);n+=parseInt(r.marginTop)+parseInt(r.marginBottom)}return n},DomHandler.prototype.getHeight=function(e){var t=e.offsetHeight,n=getComputedStyle(e);return t-=parseInt(n.paddingTop)+parseInt(n.paddingBottom)+parseInt(n.borderTopWidth)+parseInt(n.borderBottomWidth)},DomHandler.prototype.getViewport=function(){var e=window,t=document,n=t.documentElement,r=t.getElementsByTagName(\"body\")[0],i=e.innerWidth||n.clientWidth||r.clientWidth,o=e.innerHeight||n.clientHeight||r.clientHeight;return{width:i,height:o}},DomHandler.prototype.equals=function(e,t){if(null==e||null==t)return!1;if(e==t)return!0;if(\"object\"==typeof e&&\"object\"==typeof t){for(var n in e){if(e.hasOwnProperty(n)!==t.hasOwnProperty(n))return!1;switch(typeof e[n]){case\"object\":if(!this.equals(e[n],t[n]))return!1;break;case\"function\":if(\"undefined\"==typeof t[n]||\"compare\"!=n&&e[n].toString()!=t[n].toString())return!1;break;default:if(e[n]!=t[n])return!1}}for(var n in t)if(\"undefined\"==typeof e[n])return!1;return!0}return!1},DomHandler.zindex=1e3,DomHandler=r([o.Injectable(),i(\"design:paramtypes\",[])],DomHandler)}();t.DomHandler=s},[1104,5],function(e,t,n){\"use strict\";var r=this&&this.__extends||function(e,t){function __(){this.constructor=e}for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);e.prototype=null===t?Object.create(t):(__.prototype=t.prototype,new __)},i=n(6),o=function(e){function OuterSubscriber(){e.apply(this,arguments)}return r(OuterSubscriber,e),OuterSubscriber.prototype.notifyNext=function(e,t,n,r,i){this.destination.next(t)},OuterSubscriber.prototype.notifyError=function(e,t){this.destination.error(e)},OuterSubscriber.prototype.notifyComplete=function(e){this.destination.complete()},OuterSubscriber}(i.Subscriber);t.OuterSubscriber=o},function(e,t,n){\"use strict\";function subscribeToResult(e,t,n,u){var p=new c.InnerSubscriber(e,n,u);if(!p.isUnsubscribed){if(t instanceof s.Observable)return t._isScalar?(p.next(t.value),void p.complete()):t.subscribe(p);if(i.isArray(t)){for(var d=0,h=t.length;d=0;a--)(i=e[a])&&(s=(o<3?i(s):o>3?i(t,n,s):i(t,n))||s);return o>3&&s&&Object.defineProperty(t,n,s),s},i=this&&this.__metadata||function(e,t){if(\"object\"==typeof Reflect&&\"function\"==typeof Reflect.metadata)return Reflect.metadata(e,t)},o=n(0),s=n(3),a=n(0),l=function(){function Header(){}return Header=r([a.Component({selector:\"header\",template:\"\"}),i(\"design:paramtypes\",[])],Header)}();t.Header=l;var c=function(){function Footer(){}return Footer=r([a.Component({selector:\"footer\",template:\"\"}),i(\"design:paramtypes\",[])],Footer)}();t.Footer=c;var u=function(){function TemplateWrapper(e){this.viewContainer=e}return TemplateWrapper.prototype.ngOnInit=function(){this.viewContainer.createEmbeddedView(this.templateRef,{$implicit:this.item})},r([o.Input(),i(\"design:type\",Object)],TemplateWrapper.prototype,\"item\",void 0),r([o.Input(\"pTemplateWrapper\"),i(\"design:type\",o.TemplateRef)],TemplateWrapper.prototype,\"templateRef\",void 0),TemplateWrapper=r([o.Directive({selector:\"[pTemplateWrapper]\"}),i(\"design:paramtypes\",[o.ViewContainerRef])],TemplateWrapper)}();t.TemplateWrapper=u;var p=function(){function Column(){this.sortFunction=new o.EventEmitter}return r([o.Input(),i(\"design:type\",String)],Column.prototype,\"field\",void 0),r([o.Input(),i(\"design:type\",String)],Column.prototype,\"header\",void 0),r([o.Input(),i(\"design:type\",String)],Column.prototype,\"footer\",void 0),r([o.Input(),i(\"design:type\",Object)],Column.prototype,\"sortable\",void 0),r([o.Input(),i(\"design:type\",Boolean)],Column.prototype,\"editable\",void 0),r([o.Input(),i(\"design:type\",Boolean)],Column.prototype,\"filter\",void 0),r([o.Input(),i(\"design:type\",String)],Column.prototype,\"filterMatchMode\",void 0),r([o.Input(),i(\"design:type\",Number)],Column.prototype,\"rowspan\",void 0),r([o.Input(),i(\"design:type\",Number)],Column.prototype,\"colspan\",void 0),r([o.Input(),i(\"design:type\",Object)],Column.prototype,\"style\",void 0),r([o.Input(),i(\"design:type\",String)],Column.prototype,\"styleClass\",void 0),r([o.Input(),i(\"design:type\",Boolean)],Column.prototype,\"hidden\",void 0),r([o.Input(),i(\"design:type\",Boolean)],Column.prototype,\"expander\",void 0),r([o.Input(),i(\"design:type\",String)],Column.prototype,\"selectionMode\",void 0),r([o.Output(),i(\"design:type\",o.EventEmitter)],Column.prototype,\"sortFunction\",void 0),r([o.ContentChild(o.TemplateRef),i(\"design:type\",o.TemplateRef)],Column.prototype,\"template\",void 0),Column=r([a.Component({selector:\"p-column\",template:\"\"}),i(\"design:paramtypes\",[])],Column)}();t.Column=p;var d=function(){function ColumnTemplateLoader(e){this.viewContainer=e}return ColumnTemplateLoader.prototype.ngOnInit=function(){this.viewContainer.createEmbeddedView(this.column.template,{$implicit:this.column,rowData:this.rowData,rowIndex:this.rowIndex})},r([o.Input(),i(\"design:type\",Object)],ColumnTemplateLoader.prototype,\"column\",void 0),r([o.Input(),i(\"design:type\",Object)],ColumnTemplateLoader.prototype,\"rowData\",void 0),r([o.Input(),i(\"design:type\",Number)],ColumnTemplateLoader.prototype,\"rowIndex\",void 0),ColumnTemplateLoader=r([a.Component({selector:\"p-columnTemplateLoader\",template:\"\"}),i(\"design:paramtypes\",[o.ViewContainerRef])],ColumnTemplateLoader)}();t.ColumnTemplateLoader=d;var h=function(){function SharedModule(){}return SharedModule=r([o.NgModule({imports:[s.CommonModule],exports:[l,c,p,u,d],declarations:[l,c,p,u,d]}),i(\"design:paramtypes\",[])],SharedModule)}();t.SharedModule=h},function(e,t,n){\"use strict\";var r=this&&this.__extends||function(e,t){function __(){this.constructor=e}for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);e.prototype=null===t?Object.create(t):(__.prototype=t.prototype,new __)},i=n(1),o=n(6),s=n(41),a=n(899),l=n(215),c=n(517),u=n(317),p=function(e){function Subject(t,n){e.call(this),this.destination=t,this.source=n,this.observers=[],this.isUnsubscribed=!1,this.isStopped=!1,this.hasErrored=!1,this.dispatching=!1,this.hasCompleted=!1,this.source=n}return r(Subject,e),Subject.prototype.lift=function(e){var t=new Subject(this.destination||this,this);return t.operator=e,t},Subject.prototype.add=function(e){return s.Subscription.prototype.add.call(this,e)},Subject.prototype.remove=function(e){s.Subscription.prototype.remove.call(this,e)},Subject.prototype.unsubscribe=function(){s.Subscription.prototype.unsubscribe.call(this)},Subject.prototype._subscribe=function(e){if(this.source)return this.source.subscribe(e);if(!e.isUnsubscribed){if(this.hasErrored)return e.error(this.errorValue);if(this.hasCompleted)return e.complete();this.throwIfUnsubscribed();var t=new a.SubjectSubscription(this,e);return this.observers.push(e),t}},Subject.prototype._unsubscribe=function(){this.source=null,this.isStopped=!0,this.observers=null,this.destination=null},Subject.prototype.next=function(e){this.throwIfUnsubscribed(),this.isStopped||(this.dispatching=!0,this._next(e),this.dispatching=!1,this.hasErrored?this._error(this.errorValue):this.hasCompleted&&this._complete())},Subject.prototype.error=function(e){this.throwIfUnsubscribed(),this.isStopped||(this.isStopped=!0,this.hasErrored=!0,this.errorValue=e,this.dispatching||this._error(e))},Subject.prototype.complete=function(){this.throwIfUnsubscribed(),this.isStopped||(this.isStopped=!0,this.hasCompleted=!0,this.dispatching||this._complete())},Subject.prototype.asObservable=function(){var e=new d(this);return e},Subject.prototype._next=function(e){this.destination?this.destination.next(e):this._finalNext(e)},Subject.prototype._finalNext=function(e){for(var t=-1,n=this.observers.slice(0),r=n.length;++t\"+i+\"\"};e.exports=function(e,t){var n={};n[e]=t(a),r(r.P+r.F*i(function(){var t=\"\"[e]('\"');return t!==t.toLowerCase()||t.split('\"').length>3}),\"String\",n)}},function(e,t,n){\"use strict\";var r=n(81),i=n(514),o=n(217),s=n(42),a=n(38),l=n(513),c=function(){function Subscription(e){this.isUnsubscribed=!1,e&&(this._unsubscribe=e)}return Subscription.prototype.unsubscribe=function(){var e,t=!1;if(!this.isUnsubscribed){this.isUnsubscribed=!0;var n=this,c=n._unsubscribe,u=n._subscriptions;if(this._subscriptions=null,o.isFunction(c)){var p=s.tryCatch(c).call(this);p===a.errorObject&&(t=!0,(e=e||[]).push(a.errorObject.e))}if(r.isArray(u))for(var d=-1,h=u.length;++d0?i(r(e),9007199254740991):0}},function(e,t,n){\"use strict\";var r=n(1082);t.async=new r.AsyncScheduler},function(e,t,n){\"use strict\";function __export(e){for(var n in e)t.hasOwnProperty(n)||(t[n]=e[n])}var r=n(86);t.HostMetadata=r.HostMetadata,t.InjectMetadata=r.InjectMetadata,t.InjectableMetadata=r.InjectableMetadata,t.OptionalMetadata=r.OptionalMetadata,t.SelfMetadata=r.SelfMetadata,t.SkipSelfMetadata=r.SkipSelfMetadata,__export(n(115));var i=n(162);t.forwardRef=i.forwardRef,t.resolveForwardRef=i.resolveForwardRef;var o=n(163);t.Injector=o.Injector;var s=n(571);t.ReflectiveInjector=s.ReflectiveInjector;var a=n(250);t.Binding=a.Binding,t.ProviderBuilder=a.ProviderBuilder,t.bind=a.bind,t.Provider=a.Provider,t.provide=a.provide;var l=n(253);t.ResolvedReflectiveFactory=l.ResolvedReflectiveFactory;var c=n(252);t.ReflectiveKey=c.ReflectiveKey;var u=n(251);t.NoProviderError=u.NoProviderError,t.AbstractProviderError=u.AbstractProviderError,t.CyclicDependencyError=u.CyclicDependencyError,t.InstantiationError=u.InstantiationError,t.InvalidProviderError=u.InvalidProviderError,t.NoAnnotationError=u.NoAnnotationError,t.OutOfBoundsError=u.OutOfBoundsError;var p=n(374);t.OpaqueToken=p.OpaqueToken},[1104,32],function(e,t){var n={}.hasOwnProperty;e.exports=function(e,t){return n.call(e,t)}},function(e,t,n){\"use strict\";var r=n(13);e.exports=function(e,t){return!!e&&r(function(){t?e.call(null,function(){},1):e.call(null)})}},function(e,t,n){var r=n(75);e.exports=function(e){return Object(r(e))}},function(e,t,n){\"use strict\";(function(e,n){var r={\"boolean\":!1,\"function\":!0,object:!0,number:!1,string:!1,undefined:!1};t.root=r[typeof self]&&self||r[typeof window]&&window;var i=(r[typeof t]&&t&&!t.nodeType&&t,r[typeof e]&&e&&!e.nodeType&&e,r[typeof n]&&n);!i||i.global!==i&&i.window!==i||(t.root=i)}).call(t,n(1100)(e),n(82))},function(e,t,n){\"use strict\";var r=n(0);t.NG_VALUE_ACCESSOR=new r.OpaqueToken(\"NgValueAccessor\")},52,function(e,t,n){\"use strict\";function _convertToPromise(e){return s.isPromise(e)?e:i.toPromise.call(e)}function _executeValidators(e,t){return t.map(function(t){return t(e)})}function _executeAsyncValidators(e,t){return t.map(function(t){return t(e)})}function _mergeErrors(e){var t=e.reduce(function(e,t){return s.isPresent(t)?o.StringMapWrapper.merge(e,t):e},{});return o.StringMapWrapper.isEmpty(t)?null:t}var r=n(0),i=n(313),o=n(47),s=n(32);t.NG_VALIDATORS=new r.OpaqueToken(\"NgValidators\"),t.NG_ASYNC_VALIDATORS=new r.OpaqueToken(\"NgAsyncValidators\");var a=function(){function Validators(){}return Validators.required=function(e){return s.isBlank(e.value)||s.isString(e.value)&&\"\"==e.value?{required:!0}:null},Validators.minLength=function(e){return function(t){if(s.isPresent(Validators.required(t)))return null;var n=t.value;return n.lengthe?{maxlength:{requiredLength:e,actualLength:n.length}}:null}},Validators.pattern=function(e){return function(t){if(s.isPresent(Validators.required(t)))return null;var n=new RegExp(\"^\"+e+\"$\"),r=t.value;return n.test(r)?null:{pattern:{requiredPattern:\"^\"+e+\"$\",actualValue:r}}}},Validators.nullValidator=function(e){return null},Validators.compose=function(e){if(s.isBlank(e))return null;var t=e.filter(s.isPresent);return 0==t.length?null:function(e){return _mergeErrors(_executeValidators(e,t))}},Validators.composeAsync=function(e){if(s.isBlank(e))return null;var t=e.filter(s.isPresent);return 0==t.length?null:function(e){var n=_executeAsyncValidators(e,t).map(_convertToPromise);return Promise.all(n).then(_mergeErrors)}},Validators}();t.Validators=a},function(e,t,n){\"use strict\";var r=n(0),i=n(123),o=n(72),s=n(16),a=n(126),l=n(278);t.PRIMITIVE=String;var c=function(){function Serializer(e){this._renderStore=e}return Serializer.prototype.serialize=function(e,n){var i=this;if(!s.isPresent(e))return null;if(s.isArray(e))return e.map(function(e){return i.serialize(e,n)});if(n==t.PRIMITIVE)return e;if(n==u)return this._renderStore.serialize(e);if(n===r.RenderComponentType)return this._serializeRenderComponentType(e);if(n===r.ViewEncapsulation)return s.serializeEnum(e);if(n===l.LocationType)return this._serializeLocation(e);throw new o.BaseException(\"No serializer for \"+n.toString())},Serializer.prototype.deserialize=function(e,n,a){var c=this;if(!s.isPresent(e))return null;if(s.isArray(e)){var p=[];return e.forEach(function(e){return p.push(c.deserialize(e,n,a))}),p}if(n==t.PRIMITIVE)return e;if(n==u)return this._renderStore.deserialize(e);if(n===r.RenderComponentType)return this._deserializeRenderComponentType(e);if(n===r.ViewEncapsulation)return i.VIEW_ENCAPSULATION_VALUES[e];if(n===l.LocationType)return this._deserializeLocation(e);throw new o.BaseException(\"No deserializer for \"+n.toString())},Serializer.prototype._serializeLocation=function(e){return{href:e.href,protocol:e.protocol,host:e.host,hostname:e.hostname,port:e.port,pathname:e.pathname,search:e.search,hash:e.hash,origin:e.origin}},Serializer.prototype._deserializeLocation=function(e){return new l.LocationType(e.href,e.protocol,e.host,e.hostname,e.port,e.pathname,e.search,e.hash,e.origin)},Serializer.prototype._serializeRenderComponentType=function(e){return{id:e.id,templateUrl:e.templateUrl,slotCount:e.slotCount,encapsulation:this.serialize(e.encapsulation,r.ViewEncapsulation),styles:this.serialize(e.styles,t.PRIMITIVE)}},Serializer.prototype._deserializeRenderComponentType=function(e){return new r.RenderComponentType(e.id,e.templateUrl,e.slotCount,this.deserialize(e.encapsulation,r.ViewEncapsulation),this.deserialize(e.styles,t.PRIMITIVE),{})},Serializer.decorators=[{type:r.Injectable}],Serializer.ctorParameters=[{type:a.RenderStore}],Serializer}();t.Serializer=c;var u=function(){function RenderStoreObject(){}return RenderStoreObject}();t.RenderStoreObject=u},function(e,t,n){var r=n(2),i=n(24),o=n(13);e.exports=function(e,t){var n=(i.Object||{})[e]||Object[e],s={};s[e]=t(n),r(r.S+r.F*o(function(){n(1)}),\"Object\",s)}},function(e,t,n){var r=n(133),i=n(75);e.exports=function(e){return r(i(e))}},function(e,t,n){\"use strict\";function _convertToPromise(e){return s.isPromise(e)?e:i.toPromise.call(e)}function _executeValidators(e,t){return t.map(function(t){return t(e)})}function _executeAsyncValidators(e,t){return t.map(function(t){return t(e)})}function _mergeErrors(e){var t=e.reduce(function(e,t){return s.isPresent(t)?o.StringMapWrapper.merge(e,t):e},{});return o.StringMapWrapper.isEmpty(t)?null:t}var r=n(0),i=n(313),o=n(34),s=n(7);t.NG_VALIDATORS=new r.OpaqueToken(\"NgValidators\"),t.NG_ASYNC_VALIDATORS=new r.OpaqueToken(\"NgAsyncValidators\");var a=function(){function Validators(){}return Validators.required=function(e){return s.isBlank(e.value)||s.isString(e.value)&&\"\"==e.value?{required:!0}:null},Validators.minLength=function(e){return function(t){if(s.isPresent(Validators.required(t)))return null;var n=t.value;return n.lengthe?{maxlength:{requiredLength:e,actualLength:n.length}}:null}},Validators.pattern=function(e){return function(t){if(s.isPresent(Validators.required(t)))return null;var n=new RegExp(\"^\"+e+\"$\"),r=t.value;return n.test(r)?null:{pattern:{requiredPattern:\"^\"+e+\"$\",actualValue:r}}}},Validators.nullValidator=function(e){return null},Validators.compose=function(e){if(s.isBlank(e))return null;var t=e.filter(s.isPresent);return 0==t.length?null:function(e){return _mergeErrors(_executeValidators(e,t))}},Validators.composeAsync=function(e){if(s.isBlank(e))return null;var t=e.filter(s.isPresent);return 0==t.length?null:function(e){var n=_executeAsyncValidators(e,t).map(_convertToPromise);return Promise.all(n).then(_mergeErrors)}},Validators}();t.Validators=a},function(e,t,n){\"use strict\";var r=this&&this.__extends||function(e,t){function __(){this.constructor=e}for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);e.prototype=null===t?Object.create(t):(__.prototype=t.prototype,new __)},i=n(83),o=n(7),s=function(e){function InvalidPipeArgumentException(t,n){e.call(this,\"Invalid argument '\"+n+\"' for pipe '\"+o.stringify(t)+\"'\")}return r(InvalidPipeArgumentException,e),InvalidPipeArgumentException}(i.BaseException);t.InvalidPipeArgumentException=s},function(e,t,n){\"use strict\";/**\n * @license\n * Copyright Google Inc. All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\nvar r=n(5),i=function(){function ParseLocation(e,t,n,r){this.file=e,this.offset=t,this.line=n,this.col=r}return ParseLocation.prototype.toString=function(){return r.isPresent(this.offset)?this.file.url+\"@\"+this.line+\":\"+this.col:this.file.url},ParseLocation}();t.ParseLocation=i;var o=function(){function ParseSourceFile(e,t){this.content=e,this.url=t}return ParseSourceFile}();t.ParseSourceFile=o;var s=function(){function ParseSourceSpan(e,t,n){void 0===n&&(n=null),this.start=e,this.end=t,this.details=n}return ParseSourceSpan.prototype.toString=function(){return this.start.file.content.substring(this.start.offset,this.end.offset)},ParseSourceSpan}();t.ParseSourceSpan=s,function(e){e[e.WARNING=0]=\"WARNING\",e[e.FATAL=1]=\"FATAL\"}(t.ParseErrorLevel||(t.ParseErrorLevel={}));var a=t.ParseErrorLevel,l=function(){function ParseError(e,t,n){void 0===n&&(n=a.FATAL),this.span=e,this.msg=t,this.level=n}return ParseError.prototype.toString=function(){var e=this.span.start.file.content,t=this.span.start.offset,n=\"\",i=\"\";if(r.isPresent(t)){t>e.length-1&&(t=e.length-1);for(var o=t,s=0,a=0;s<100&&t>0&&(t--,s++,\"\\n\"!=e[t]||3!=++a););for(s=0,a=0;s<100&&o]\"+e.substring(this.span.start.offset,o+1);n=' (\"'+l+'\")'}return this.span.details&&(i=\", \"+this.span.details),\"\"+this.msg+n+\": \"+this.span.start+i},ParseError}();t.ParseError=l},function(e,t,n){\"use strict\";function templateVisitAll(e,t,n){void 0===n&&(n=null);var i=[];return t.forEach(function(t){var o=t.visit(e,n);r.isPresent(o)&&i.push(o)}),i}var r=n(5),i=function(){function TextAst(e,t,n){this.value=e,this.ngContentIndex=t,this.sourceSpan=n}return TextAst.prototype.visit=function(e,t){return e.visitText(this,t)},TextAst}();t.TextAst=i;var o=function(){function BoundTextAst(e,t,n){this.value=e,this.ngContentIndex=t,this.sourceSpan=n}return BoundTextAst.prototype.visit=function(e,t){return e.visitBoundText(this,t)},BoundTextAst}();t.BoundTextAst=o;var s=function(){function AttrAst(e,t,n){this.name=e,this.value=t,this.sourceSpan=n}return AttrAst.prototype.visit=function(e,t){return e.visitAttr(this,t)},AttrAst}();t.AttrAst=s;var a=function(){function BoundElementPropertyAst(e,t,n,r,i,o){this.name=e,this.type=t,this.securityContext=n,this.value=r,this.unit=i,this.sourceSpan=o}return BoundElementPropertyAst.prototype.visit=function(e,t){return e.visitElementProperty(this,t)},BoundElementPropertyAst}();t.BoundElementPropertyAst=a;var l=function(){function BoundEventAst(e,t,n,r){this.name=e,this.target=t,this.handler=n,this.sourceSpan=r}return BoundEventAst.prototype.visit=function(e,t){return e.visitEvent(this,t)},Object.defineProperty(BoundEventAst.prototype,\"fullName\",{get:function(){return r.isPresent(this.target)?this.target+\":\"+this.name:this.name},enumerable:!0,configurable:!0}),BoundEventAst}();t.BoundEventAst=l;var c=function(){function ReferenceAst(e,t,n){this.name=e,this.value=t,this.sourceSpan=n}return ReferenceAst.prototype.visit=function(e,t){return e.visitReference(this,t)},ReferenceAst}();t.ReferenceAst=c;var u=function(){function VariableAst(e,t,n){this.name=e,this.value=t,this.sourceSpan=n}return VariableAst.prototype.visit=function(e,t){return e.visitVariable(this,t)},VariableAst}();t.VariableAst=u;var p=function(){function ElementAst(e,t,n,r,i,o,s,a,l,c,u){this.name=e,this.attrs=t,this.inputs=n,this.outputs=r,this.references=i,this.directives=o,this.providers=s,this.hasViewContainer=a,this.children=l,this.ngContentIndex=c,this.sourceSpan=u}return ElementAst.prototype.visit=function(e,t){return e.visitElement(this,t)},ElementAst}();t.ElementAst=p;var d=function(){function EmbeddedTemplateAst(e,t,n,r,i,o,s,a,l,c){this.attrs=e,this.outputs=t,this.references=n,this.variables=r,this.directives=i,this.providers=o,this.hasViewContainer=s,this.children=a,this.ngContentIndex=l,this.sourceSpan=c}return EmbeddedTemplateAst.prototype.visit=function(e,t){return e.visitEmbeddedTemplate(this,t)},EmbeddedTemplateAst}();t.EmbeddedTemplateAst=d;var h=function(){function BoundDirectivePropertyAst(e,t,n,r){this.directiveName=e,this.templateName=t,this.value=n,this.sourceSpan=r}return BoundDirectivePropertyAst.prototype.visit=function(e,t){return e.visitDirectiveProperty(this,t)},BoundDirectivePropertyAst}();t.BoundDirectivePropertyAst=h;var f=function(){function DirectiveAst(e,t,n,r,i){this.directive=e,this.inputs=t,this.hostProperties=n,this.hostEvents=r,this.sourceSpan=i}return DirectiveAst.prototype.visit=function(e,t){return e.visitDirective(this,t)},DirectiveAst}();t.DirectiveAst=f;var m=function(){function ProviderAst(e,t,n,r,i,o,s){this.token=e,this.multiProvider=t,this.eager=n,this.providers=r,this.providerType=i,this.lifecycleHooks=o,this.sourceSpan=s}return ProviderAst.prototype.visit=function(e,t){return null},ProviderAst}();t.ProviderAst=m,function(e){e[e.PublicService=0]=\"PublicService\",e[e.PrivateService=1]=\"PrivateService\",e[e.Component=2]=\"Component\",e[e.Directive=3]=\"Directive\",e[e.Builtin=4]=\"Builtin\"}(t.ProviderAstType||(t.ProviderAstType={}));var g=(t.ProviderAstType,function(){function NgContentAst(e,t,n){this.index=e,this.ngContentIndex=t,this.sourceSpan=n}return NgContentAst.prototype.visit=function(e,t){return e.visitNgContent(this,t)},NgContentAst}());t.NgContentAst=g,function(e){e[e.Property=0]=\"Property\",e[e.Attribute=1]=\"Attribute\",e[e.Class=2]=\"Class\",e[e.Style=3]=\"Style\",e[e.Animation=4]=\"Animation\"}(t.PropertyBindingType||(t.PropertyBindingType={}));t.PropertyBindingType;t.templateVisitAll=templateVisitAll},function(e,t){\"use strict\";var n=function(){function MessageBus(){}return MessageBus}();t.MessageBus=n},function(e,t){\"use strict\";t.PRIMARY_OUTLET=\"primary\"},function(e,t,n){var r=n(106),i=n(133),o=n(50),s=n(44),a=n(676);e.exports=function(e,t){var n=1==e,l=2==e,c=3==e,u=4==e,p=6==e,d=5==e||p,h=t||a;return function(t,a,f){for(var m,g,y=o(t),v=i(y),b=r(a,f,3),_=s(v.length),w=0,S=n?h(t,_):l?h(t,0):void 0;_>w;w++)if((d||w in v)&&(m=v[w],g=b(m,w,y),e))if(n)S[w]=g;else if(g)switch(e){case 3:return!0;case 5:return m;case 6:return w;case 2:S.push(m)}else if(u)return!1;return p?-1:c||u?u:S}}},function(e,t,n){var r=n(30),i=n(109);e.exports=n(35)?function(e,t,n){return r.f(e,t,i(1,n))}:function(e,t,n){return e[t]=n,e}},function(e,t,n){var r=n(472),i=n(2),o=n(199)(\"metadata\"),s=o.store||(o.store=new(n(798))),a=function(e,t,n){var i=s.get(e);if(!i){if(!n)return;s.set(e,i=new r)}var o=i.get(t);if(!o){if(!n)return;i.set(t,o=new r)}return o},l=function(e,t,n){var r=a(t,n,!1);return void 0!==r&&r.has(e)},c=function(e,t,n){var r=a(t,n,!1);return void 0===r?void 0:r.get(e)},u=function(e,t,n,r){a(n,r,!0).set(e,t)},p=function(e,t){var n=a(e,t,!1),r=[];return n&&n.forEach(function(e,t){r.push(t)}),r},d=function(e){return void 0===e||\"symbol\"==typeof e?e:String(e)},h=function(e){i(i.S,\"Reflect\",e)};e.exports={store:s,map:a,has:l,get:c,set:u,keys:p,key:d,exp:h}},function(e,t,n){var r=n(48),i=n(50),o=n(300)(\"IE_PROTO\"),s=Object.prototype;e.exports=Object.getPrototypeOf||function(e){return e=i(e),r(e,o)?e[o]:\"function\"==typeof e.constructor&&e instanceof e.constructor?e.constructor.prototype:e instanceof Object?s:null}},function(e,t,n){\"use strict\";var r=n(347),i=function(){function InterpolationConfig(e,t){this.start=e,this.end=t}return InterpolationConfig.fromArray=function(e){return e?(r.assertInterpolationSymbols(\"interpolation\",e),new InterpolationConfig(e[0],e[1])):t.DEFAULT_INTERPOLATION_CONFIG},InterpolationConfig}();t.InterpolationConfig=i,t.DEFAULT_INTERPOLATION_CONFIG=new i(\"{{\",\"}}\")},[1107,263],function(e,t,n){\"use strict\";function controlPath(e,t){var n=r.ListWrapper.clone(t.path);return n.push(e),n}function setUpControl(e,t){o.isBlank(e)&&_throwError(t,\"Cannot find control with\"),o.isBlank(t.valueAccessor)&&_throwError(t,\"No value accessor for form control with\"),e.validator=s.Validators.compose([e.validator,t.validator]),e.asyncValidator=s.Validators.composeAsync([e.asyncValidator,t.asyncValidator]),t.valueAccessor.writeValue(e.value),t.valueAccessor.registerOnChange(function(n){t.viewToModelUpdate(n),e.markAsDirty(),e.setValue(n,{emitModelToViewChange:!1})}),e.registerOnChange(function(e,n){t.valueAccessor.writeValue(e),n&&t.viewToModelUpdate(e)}),t.valueAccessor.registerOnTouched(function(){return e.markAsTouched()})}function setUpFormContainer(e,t){o.isBlank(e)&&_throwError(t,\"Cannot find control with\"),e.validator=s.Validators.compose([e.validator,t.validator]),e.asyncValidator=s.Validators.composeAsync([e.asyncValidator,t.asyncValidator])}function _throwError(e,t){var n;throw n=e.path.length>1?\"path: '\"+e.path.join(\" -> \")+\"'\":e.path[0]?\"name: '\"+e.path+\"'\":\"unspecified name attribute\",new i.BaseException(t+\" \"+n)}function composeValidators(e){return o.isPresent(e)?s.Validators.compose(e.map(c.normalizeValidator)):null}function composeAsyncValidators(e){return o.isPresent(e)?s.Validators.composeAsync(e.map(c.normalizeAsyncValidator)):null}function isPropertyUpdated(e,t){if(!r.StringMapWrapper.contains(e,\"model\"))return!1;var n=e.model;return!!n.isFirstChange()||!o.looseIdentical(t,n.currentValue)}function selectValueAccessor(e,t){if(o.isBlank(t))return null;var n,r,i;return t.forEach(function(t){o.hasConstructor(t,l.DefaultValueAccessor)?n=t:o.hasConstructor(t,a.CheckboxControlValueAccessor)||o.hasConstructor(t,u.NumberValueAccessor)||o.hasConstructor(t,d.SelectControlValueAccessor)||o.hasConstructor(t,h.SelectMultipleControlValueAccessor)||o.hasConstructor(t,p.RadioControlValueAccessor)?(o.isPresent(r)&&_throwError(e,\"More than one built-in value accessor matches form control with\"),r=t):(o.isPresent(i)&&_throwError(e,\"More than one custom value accessor matches form control with\"),i=t)}),o.isPresent(i)?i:o.isPresent(r)?r:o.isPresent(n)?n:(_throwError(e,\"No valid value accessor for form control with\"),null)}var r=n(47),i=n(88),o=n(32),s=n(54),a=n(169),l=n(170),c=n(587),u=n(266),p=n(172),d=n(173),h=n(174);t.controlPath=controlPath,t.setUpControl=setUpControl,t.setUpFormContainer=setUpFormContainer,t.composeValidators=composeValidators,t.composeAsyncValidators=composeAsyncValidators,t.isPropertyUpdated=isPropertyUpdated,t.selectValueAccessor=selectValueAccessor},function(e,t){\"use strict\";!function(e){e[e.Get=0]=\"Get\",e[e.Post=1]=\"Post\",e[e.Put=2]=\"Put\",e[e.Delete=3]=\"Delete\",e[e.Options=4]=\"Options\",e[e.Head=5]=\"Head\",e[e.Patch=6]=\"Patch\"}(t.RequestMethod||(t.RequestMethod={}));t.RequestMethod;!function(e){e[e.Unsent=0]=\"Unsent\",e[e.Open=1]=\"Open\",e[e.HeadersReceived=2]=\"HeadersReceived\",e[e.Loading=3]=\"Loading\",e[e.Done=4]=\"Done\",e[e.Cancelled=5]=\"Cancelled\"}(t.ReadyState||(t.ReadyState={}));t.ReadyState;!function(e){e[e.Basic=0]=\"Basic\",e[e.Cors=1]=\"Cors\",e[e.Default=2]=\"Default\",e[e.Error=3]=\"Error\",e[e.Opaque=4]=\"Opaque\"}(t.ResponseType||(t.ResponseType={}));t.ResponseType;!function(e){e[e.NONE=0]=\"NONE\",e[e.JSON=1]=\"JSON\",e[e.FORM=2]=\"FORM\",e[e.FORM_DATA=3]=\"FORM_DATA\",e[e.TEXT=4]=\"TEXT\",e[e.BLOB=5]=\"BLOB\",e[e.ARRAY_BUFFER=6]=\"ARRAY_BUFFER\"}(t.ContentType||(t.ContentType={}));t.ContentType;!function(e){e[e.Text=0]=\"Text\",e[e.Json=1]=\"Json\",e[e.ArrayBuffer=2]=\"ArrayBuffer\",e[e.Blob=3]=\"Blob\"}(t.ResponseContentType||(t.ResponseContentType={}));t.ResponseContentType},[1106,418,419,419],function(e,t,n){\"use strict\";function createEmptyUrlTree(){return new o(new s([],{}),{},null)}function containsTree(e,t,n){return n?equalSegmentGroups(e.root,t.root):containsSegmentGroup(e.root,t.root)}function equalSegmentGroups(e,t){if(!equalPath(e.segments,t.segments))return!1;if(e.numberOfChildren!==t.numberOfChildren)return!1;for(var n in t.children){if(!e.children[n])return!1;if(!equalSegmentGroups(e.children[n],t.children[n]))return!1}return!0}function containsSegmentGroup(e,t){return containsSegmentGroupHelper(e,t,t.segments)}function containsSegmentGroupHelper(e,t,n){if(e.segments.length>n.length){var i=e.segments.slice(0,n.length);return!!equalPath(i,n)&&!t.hasChildren()}if(e.segments.length===n.length){if(!equalPath(e.segments,n))return!1;for(var o in t.children){if(!e.children[o])return!1;if(!containsSegmentGroup(e.children[o],t.children[o]))return!1}return!0}var i=n.slice(0,e.segments.length),s=n.slice(e.segments.length);return!!equalPath(e.segments,i)&&(!!e.children[r.PRIMARY_OUTLET]&&containsSegmentGroupHelper(e.children[r.PRIMARY_OUTLET],t,s))}function equalSegments(e,t){if(e.length!==t.length)return!1;for(var n=0;n0?n+\"(\"+o.join(\"//\")+\")\":\"\"+n}if(e.hasChildren()&&!t){var s=mapChildrenIntoArray(e,function(t,n){return n===r.PRIMARY_OUTLET?[serializeSegment(e.children[r.PRIMARY_OUTLET],!1)]:[n+\":\"+serializeSegment(t,!1)]});return serializePaths(e)+\"/(\"+s.join(\"//\")+\")\"}return serializePaths(e)}function encode(e){return encodeURIComponent(e)}function decode(e){return decodeURIComponent(e)}function serializePath(e){return\"\"+encode(e.path)+serializeParams(e.parameters)}function serializeParams(e){return pairs(e).map(function(e){return\";\"+encode(e.first)+\"=\"+encode(e.second)}).join(\"\")}function serializeQueryParams(e){var t=pairs(e).map(function(e){return encode(e.first)+\"=\"+encode(e.second)});return t.length>0?\"?\"+t.join(\"&\"):\"\"}function pairs(e){var t=[];for(var n in e)e.hasOwnProperty(n)&&t.push(new u(n,e[n]));return t}function matchSegments(e){p.lastIndex=0;var t=e.match(p);return t?t[0]:\"\"}function matchQueryParams(e){d.lastIndex=0;var t=e.match(p);return t?t[0]:\"\"}function matchUrlQueryParamValue(e){h.lastIndex=0;var t=e.match(h);return t?t[0]:\"\"}var r=n(63),i=n(74);t.createEmptyUrlTree=createEmptyUrlTree,t.containsTree=containsTree;var o=function(){function UrlTree(e,t,n){this.root=e,this.queryParams=t,this.fragment=n}return UrlTree.prototype.toString=function(){return(new c).serialize(this)},UrlTree}();t.UrlTree=o;var s=function(){function UrlSegmentGroup(e,t){var n=this;this.segments=e,this.children=t,this.parent=null,i.forEach(t,function(e,t){return e.parent=n})}return UrlSegmentGroup.prototype.hasChildren=function(){return this.numberOfChildren>0},Object.defineProperty(UrlSegmentGroup.prototype,\"numberOfChildren\",{get:function(){return Object.keys(this.children).length},enumerable:!0,configurable:!0}),UrlSegmentGroup.prototype.toString=function(){return serializePaths(this)},UrlSegmentGroup}();t.UrlSegmentGroup=s;var a=function(){function UrlSegment(e,t){this.path=e,this.parameters=t}return UrlSegment.prototype.toString=function(){return serializePath(this)},UrlSegment}();t.UrlSegment=a,t.equalSegments=equalSegments,t.equalPath=equalPath,t.mapChildrenIntoArray=mapChildrenIntoArray;var l=function(){function UrlSerializer(){}return UrlSerializer}();t.UrlSerializer=l;var c=function(){function DefaultUrlSerializer(){}return DefaultUrlSerializer.prototype.parse=function(e){var t=new f(e);return new o(t.parseRootSegment(),t.parseQueryParams(),t.parseFragment())},DefaultUrlSerializer.prototype.serialize=function(e){var t=\"/\"+serializeSegment(e.root,!0),n=serializeQueryParams(e.queryParams),r=null!==e.fragment&&void 0!==e.fragment?\"#\"+encodeURIComponent(e.fragment):\"\";return\"\"+t+n+r},DefaultUrlSerializer}();t.DefaultUrlSerializer=c,t.serializePaths=serializePaths,t.encode=encode,t.decode=decode,t.serializePath=serializePath;var u=function(){function Pair(e,t){this.first=e,this.second=t}return Pair}(),p=/^[^\\/\\(\\)\\?;=&#]+/,d=/^[^=\\?&#]+/,h=/^[^\\?&#]+/,f=function(){function UrlParser(e){this.url=e,this.remaining=e}return UrlParser.prototype.peekStartsWith=function(e){return this.remaining.startsWith(e)},UrlParser.prototype.capture=function(e){if(!this.remaining.startsWith(e))throw new Error('Expected \"'+e+'\".');this.remaining=this.remaining.substring(e.length)},UrlParser.prototype.parseRootSegment=function(){return this.remaining.startsWith(\"/\")&&this.capture(\"/\"),\"\"===this.remaining||this.remaining.startsWith(\"?\")||this.remaining.startsWith(\"#\")?new s([],{}):new s([],this.parseChildren())},UrlParser.prototype.parseChildren=function(){if(0==this.remaining.length)return{};this.peekStartsWith(\"/\")&&this.capture(\"/\");var e=[];for(this.peekStartsWith(\"(\")||e.push(this.parseSegments());this.peekStartsWith(\"/\")&&!this.peekStartsWith(\"//\")&&!this.peekStartsWith(\"/(\");)this.capture(\"/\"),e.push(this.parseSegments());var t={};this.peekStartsWith(\"/(\")&&(this.capture(\"/\"),t=this.parseParens(!0));var n={};return this.peekStartsWith(\"(\")&&(n=this.parseParens(!1)),(e.length>0||Object.keys(t).length>0)&&(n[r.PRIMARY_OUTLET]=new s(e,t)),n},UrlParser.prototype.parseSegments=function(){var e=matchSegments(this.remaining);if(\"\"===e&&this.peekStartsWith(\";\"))throw new Error(\"Empty path url segment cannot have parameters: '\"+this.remaining+\"'.\");this.capture(e);var t={};return this.peekStartsWith(\";\")&&(t=this.parseMatrixParams()),new a(decode(e),t)},UrlParser.prototype.parseQueryParams=function(){var e={};if(this.peekStartsWith(\"?\"))for(this.capture(\"?\"),this.parseQueryParam(e);this.remaining.length>0&&this.peekStartsWith(\"&\");)this.capture(\"&\"),this.parseQueryParam(e);return e},UrlParser.prototype.parseFragment=function(){return this.peekStartsWith(\"#\")?decode(this.remaining.substring(1)):null},UrlParser.prototype.parseMatrixParams=function(){for(var e={};this.remaining.length>0&&this.peekStartsWith(\";\");)this.capture(\";\"),this.parseParam(e);return e},UrlParser.prototype.parseParam=function(e){var t=matchSegments(this.remaining);if(t){this.capture(t);var n=\"true\";if(this.peekStartsWith(\"=\")){this.capture(\"=\");var r=matchSegments(this.remaining);r&&(n=r,this.capture(n))}e[decode(t)]=decode(n)}},UrlParser.prototype.parseQueryParam=function(e){var t=matchQueryParams(this.remaining);if(t){this.capture(t);var n=\"\";if(this.peekStartsWith(\"=\")){this.capture(\"=\");var r=matchUrlQueryParamValue(this.remaining);r&&(n=r,this.capture(n))}e[decode(t)]=decode(n)}},UrlParser.prototype.parseParens=function(e){var t={};for(this.capture(\"(\");!this.peekStartsWith(\")\")&&this.remaining.length>0;){var n=matchSegments(this.remaining),i=this.remaining[n.length];if(\"/\"!==i&&\")\"!==i&&\";\"!==i)throw new Error(\"Cannot parse url '\"+this.url+\"'\");var o=void 0;n.indexOf(\":\")>-1?(o=n.substr(0,n.indexOf(\":\")),this.capture(o),this.capture(\":\")):e&&(o=r.PRIMARY_OUTLET);var a=this.parseChildren();t[o]=1===Object.keys(a).length?a[r.PRIMARY_OUTLET]:new s([],a),this.peekStartsWith(\"//\")&&this.capture(\"//\")}return this.capture(\")\"),t},UrlParser}()},function(e,t,n){\"use strict\";function shallowEqualArrays(e,t){if(e.length!==t.length)return!1;for(var n=0;n0?e[0]:null}function last(e){return e.length>0?e[e.length-1]:null}function and(e){return e.reduce(function(e,t){return e&&t},!0)}function merge(e,t){var n={};for(var r in e)e.hasOwnProperty(r)&&(n[r]=e[r]);for(var r in t)t.hasOwnProperty(r)&&(n[r]=t[r]);return n}function forEach(e,t){for(var n in e)e.hasOwnProperty(n)&&t(e[n],n)}function waitForMap(e,t){var n=[],r={};return forEach(e,function(e,i){i===s.PRIMARY_OUTLET&&n.push(t(i,e).map(function(e){return r[i]=e,e}))}),forEach(e,function(e,i){i!==s.PRIMARY_OUTLET&&n.push(t(i,e).map(function(e){return r[i]=e,e}))}),n.length>0?o.of.apply(void 0,n).concatAll().last().map(function(e){return r}):o.of(r)}function andObservables(e){return e.mergeAll().every(function(e){return e===!0})}function wrapIntoObservable(e){return e instanceof r.Observable?e:e instanceof Promise?i.fromPromise(e):o.of(e)}n(304),n(497);var r=n(1),i=n(211),o=n(141),s=n(63);t.shallowEqualArrays=shallowEqualArrays,t.shallowEqual=shallowEqual,t.flatten=flatten,t.first=first,t.last=last,t.and=and,t.merge=merge,t.forEach=forEach,t.waitForMap=waitForMap,t.andObservables=andObservables,t.wrapIntoObservable=wrapIntoObservable},function(e,t){e.exports=function(e){if(void 0==e)throw TypeError(\"Can't call method on \"+e);return e}},function(e,t,n){var r=n(137)(\"meta\"),i=n(15),o=n(48),s=n(30).f,a=0,l=Object.isExtensible||function(){return!0},c=!n(13)(function(){return l(Object.preventExtensions({}))}),u=function(e){s(e,r,{value:{i:\"O\"+ ++a,w:{}}})},p=function(e,t){if(!i(e))return\"symbol\"==typeof e?e:(\"string\"==typeof e?\"S\":\"P\")+e;if(!o(e,r)){if(!l(e))return\"F\";if(!t)return\"E\";u(e)}return e[r].i},d=function(e,t){if(!o(e,r)){if(!l(e))return!0;if(!t)return!1;u(e)}return e[r].w},h=function(e){return c&&f.NEED&&l(e)&&!o(e,r)&&u(e),e},f=e.exports={KEY:r,NEED:!1,fastKey:p,getWeak:d,onFreeze:h}},function(e,t,n){var r=n(197),i=n(109),o=n(57),s=n(97),a=n(48),l=n(453),c=Object.getOwnPropertyDescriptor;t.f=n(35)?c:function(e,t){if(e=o(e),t=s(t,!0),l)try{return c(e,t)}catch(n){}if(a(e,t))return i(!r.f.call(e,t),e[t])}},function(e,t){e.exports=\".vt-row {\\n display: flex;\\n flex-wrap: wrap;\\n height: 100%;\\n width: 100%;\\n}\\n\\n.vt-card {\\n display: inline-table;\\n margin-left: 25px;\\n margin-bottom: 10px;\\n margin-top: 10px;\\n}\\n\\n.stats-container {\\n width: 100%;\\n}\\n\\n.vt-padding{\\n padding-left: 25px;\\n padding-right: 25px;\\n}\\n\\n>>> p-dialog .ui-dialog{\\n position: fixed !important;\\n top: 50% !important;\\n left: 50% !important;\\n transform: translate(-50%, -50%);\\n margin: 0;\\n width: auto !important;\\n}\\n\\n.vt-popUpContainer{\\n position: fixed;\\n padding: 0;\\n margin: 0;\\n z-index: 0;\\n bottom: 0;\\n right: 0;\\n top: 0;\\n left: 0;\\n min-height: 1000vh;\\n min-width: 1000vw;\\n height: 100%;\\n width: 100%;\\n background: rgba(0,0,0,0.6);\\n}\\n\\n.vt-dark-link:link {\\n text-decoration: none;\\n color: black;\\n}\\n\\n.vt-dark-link:visited {\\n text-decoration: none;\\n color: black;\\n}\\n\\n.vt-dark-link:hover {\\n text-decoration: none;\\n color: black;\\n}\\n\\n.vt-dark-link:active {\\n text-decoration: none;\\n color: black;\\n}\\n\\n/* Toolbar */\\n.vt-toolbar {\\n width: 100%;\\n text-align: center;\\n}\\n\\n>>> p-accordiontab a {\\n padding-left: 25px! important;\\n}\\n\\n>>> .ui-accordion-content button {\\n margin-top: 2px;\\n}\\n\\n>>> p-menu .ui-menu {\\n margin-top: 19px;\\n display: inline-block;\\n top: auto !important;\\n left: auto !important;\\n float: right;\\n \\n}\\n\\np-menu {\\n display: inline-block;\\n float: left;\\n}\\n\\n.vt-toolbar .vt-menu {\\n padding-top: 19px;\\n float: left;\\n}\\n\\n.vt-toolbar .vt-right-menu {\\n padding-top: 19px;\\n position: fixed;\\n right: 25px;\\n top: 19px;\\n}\\n\\n.vt-card-toolbar {\\n display: inline-block;\\n width: 100%;\\n}\\n\\n.vt-card-toolbar .vt-menu {\\n float: left;\\n}\\n.vt-card-toolbar .vt-title {\\n float: right;\\n margin: 0;\\n padding-left: 25px;\\n}\\n\\nmd-list:hover {\\n background: #E8E8E8\\n}\\n\"},function(e,t,n){\"use strict\";var r=this&&this.__extends||function(e,t){function __(){this.constructor=e}for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);e.prototype=null===t?Object.create(t):(__.prototype=t.prototype,new __)},i=n(1),o=n(308),s=n(80),a=n(98),l=function(e){function ArrayObservable(t,n){e.call(this),this.array=t,this.scheduler=n,n||1!==t.length||(this._isScalar=!0,this.value=t[0])}return r(ArrayObservable,e),ArrayObservable.create=function(e,t){return new ArrayObservable(e,t)},ArrayObservable.of=function(){for(var e=[],t=0;t1?new ArrayObservable(e,n):1===r?new o.ScalarObservable(e[0],n):new s.EmptyObservable(n)},ArrayObservable.dispatch=function(e){var t=e.array,n=e.index,r=e.count,i=e.subscriber;return n>=r?void i.complete():(i.next(t[n]),void(i.isUnsubscribed||(e.index=n+1,this.schedule(e))))},ArrayObservable.prototype._subscribe=function(e){var t=0,n=this.array,r=n.length,i=this.scheduler;if(i)return i.schedule(ArrayObservable.dispatch,0,{array:n,index:t,count:r,subscriber:e});for(var o=0;o0?\" { \"+e.children.map(serializeNode).join(\", \")+\" } \":\"\";return\"\"+e.value+t}function advanceActivatedRoute(e){e.snapshot?(a.shallowEqual(e.snapshot.queryParams,e._futureSnapshot.queryParams)||e.queryParams.next(e._futureSnapshot.queryParams),e.snapshot.fragment!==e._futureSnapshot.fragment&&e.fragment.next(e._futureSnapshot.fragment),a.shallowEqual(e.snapshot.params,e._futureSnapshot.params)||(e.params.next(e._futureSnapshot.params),e.data.next(e._futureSnapshot.data)),a.shallowEqualArrays(e.snapshot.url,e._futureSnapshot.url)||e.url.next(e._futureSnapshot.url),e.snapshot=e._futureSnapshot):(e.snapshot=e._futureSnapshot,e.data.next(e._futureSnapshot.data))}var r=this&&this.__extends||function(e,t){function __(){this.constructor=e}for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);e.prototype=null===t?Object.create(t):(__.prototype=t.prototype,new __)},i=n(207),o=n(63),s=n(73),a=n(74),l=n(281),c=function(e){function RouterState(t,n){e.call(this,t),this.snapshot=n,setRouterStateSnapshot(this,t)}return r(RouterState,e),Object.defineProperty(RouterState.prototype,\"queryParams\",{get:function(){return this.root.queryParams},enumerable:!0,configurable:!0}),Object.defineProperty(RouterState.prototype,\"fragment\",{get:function(){return this.root.fragment},enumerable:!0,configurable:!0}),RouterState.prototype.toString=function(){return this.snapshot.toString()},RouterState}(l.Tree);t.RouterState=c,t.createEmptyState=createEmptyState;var u=function(){function ActivatedRoute(e,t,n,r,i,o,s,a){this.url=e,this.params=t,this.queryParams=n,this.fragment=r,this.data=i,this.outlet=o,this.component=s,this._futureSnapshot=a}return Object.defineProperty(ActivatedRoute.prototype,\"routeConfig\",{get:function(){return this._futureSnapshot.routeConfig},enumerable:!0,configurable:!0}),Object.defineProperty(ActivatedRoute.prototype,\"root\",{get:function(){return this._routerState.root},enumerable:!0,configurable:!0}),Object.defineProperty(ActivatedRoute.prototype,\"parent\",{get:function(){return this._routerState.parent(this)},enumerable:!0,configurable:!0}),Object.defineProperty(ActivatedRoute.prototype,\"firstChild\",{get:function(){return this._routerState.firstChild(this)},enumerable:!0,configurable:!0}),Object.defineProperty(ActivatedRoute.prototype,\"children\",{get:function(){return this._routerState.children(this)},enumerable:!0,configurable:!0}),Object.defineProperty(ActivatedRoute.prototype,\"pathFromRoot\",{get:function(){return this._routerState.pathFromRoot(this)},enumerable:!0,configurable:!0}),ActivatedRoute.prototype.toString=function(){return this.snapshot?this.snapshot.toString():\"Future(\"+this._futureSnapshot+\")\"},ActivatedRoute}();t.ActivatedRoute=u;var p=function(){function InheritedResolve(e,t){this.parent=e,this.current=t,this.resolvedData={}}return Object.defineProperty(InheritedResolve.prototype,\"flattenedResolvedData\",{get:function(){return this.parent?a.merge(this.parent.flattenedResolvedData,this.resolvedData):this.resolvedData},enumerable:!0,configurable:!0}),Object.defineProperty(InheritedResolve,\"empty\",{get:function(){return new InheritedResolve(null,{})},enumerable:!0,configurable:!0}),InheritedResolve}();t.InheritedResolve=p;var d=function(){function ActivatedRouteSnapshot(e,t,n,r,i,o,s,a,l,c,u){this.url=e,this.params=t,this.queryParams=n,this.fragment=r,this.data=i,this.outlet=o,this.component=s,this._routeConfig=a,this._urlSegment=l,this._lastPathIndex=c,this._resolve=u}return Object.defineProperty(ActivatedRouteSnapshot.prototype,\"routeConfig\",{get:function(){return this._routeConfig},enumerable:!0,configurable:!0}),Object.defineProperty(ActivatedRouteSnapshot.prototype,\"root\",{get:function(){return this._routerState.root},enumerable:!0,configurable:!0}),Object.defineProperty(ActivatedRouteSnapshot.prototype,\"parent\",{get:function(){return this._routerState.parent(this)},enumerable:!0,configurable:!0}),Object.defineProperty(ActivatedRouteSnapshot.prototype,\"firstChild\",{get:function(){return this._routerState.firstChild(this)},enumerable:!0,configurable:!0}),Object.defineProperty(ActivatedRouteSnapshot.prototype,\"children\",{get:function(){return this._routerState.children(this)},enumerable:!0,configurable:!0}),Object.defineProperty(ActivatedRouteSnapshot.prototype,\"pathFromRoot\",{get:function(){return this._routerState.pathFromRoot(this)},enumerable:!0,configurable:!0}),ActivatedRouteSnapshot.prototype.toString=function(){var e=this.url.map(function(e){return e.toString()}).join(\"/\"),t=this._routeConfig?this._routeConfig.path:\"\";return\"Route(url:'\"+e+\"', path:'\"+t+\"')\"},ActivatedRouteSnapshot}();t.ActivatedRouteSnapshot=d;var h=function(e){function RouterStateSnapshot(t,n){e.call(this,n),this.url=t,setRouterStateSnapshot(this,n)}return r(RouterStateSnapshot,e),Object.defineProperty(RouterStateSnapshot.prototype,\"queryParams\",{get:function(){return this.root.queryParams},enumerable:!0,configurable:!0}),Object.defineProperty(RouterStateSnapshot.prototype,\"fragment\",{get:function(){return this.root.fragment},enumerable:!0,configurable:!0}),RouterStateSnapshot.prototype.toString=function(){return serializeNode(this._root)},RouterStateSnapshot}(l.Tree);t.RouterStateSnapshot=h,t.advanceActivatedRoute=advanceActivatedRoute},function(e,t,n){\"use strict\";var r=n(43),i=(n.n(r),n(0));n.n(i);n.d(t,\"a\",function(){return a});var o=this&&this.__decorate||function(e,t,n,r){var i,o=arguments.length,s=o<3?t:null===r?r=Object.getOwnPropertyDescriptor(t,n):r;if(\"object\"==typeof Reflect&&\"function\"==typeof Reflect.decorate)s=Reflect.decorate(e,t,n,r);else for(var a=e.length-1;a>=0;a--)(i=e[a])&&(s=(o<3?i(s):o>3?i(t,n,s):i(t,n))||s);return o>3&&s&&Object.defineProperty(t,n,s),s},s=this&&this.__metadata||function(e,t){if(\"object\"==typeof Reflect&&\"function\"==typeof Reflect.metadata)return Reflect.metadata(e,t)},a=function(){function VtctlService(e){this.http=e,this.vtctlUrl=\"../api/vtctl/\"}return VtctlService.prototype.sendPostRequest=function(e,t){var n=new r.Headers({\"Content-Type\":\"application/json\"}),i=new r.RequestOptions({headers:n});return this.http.post(e,JSON.stringify(t),i).map(function(e){return e.json()})},VtctlService.prototype.runCommand=function(e){return this.sendPostRequest(this.vtctlUrl,e)},VtctlService=o([n.i(i.Injectable)(),s(\"design:paramtypes\",[\"function\"==typeof(e=\"undefined\"!=typeof r.Http&&r.Http)&&e||Object])],VtctlService);var e}()},function(e,t,n){\"use strict\";var r=n(192);n.d(t,\"a\",function(){return i});var i=function(){function DialogContent(e,t,n,r,i){void 0===e&&(e=\"\"),void 0===t&&(t={}),void 0===n&&(n={}),void 0===r&&(r=void 0),void 0===i&&(i=\"\"),this.nameId=e,this.flags=t,this.requiredFlags=n,this.prepareFunction=r,this.action=i}return DialogContent.prototype.getName=function(){return this.flags[this.nameId]?this.flags[this.nameId].getStrValue():\"\"},DialogContent.prototype.setName=function(e){this.flags[this.nameId]&&this.flags[this.nameId].setValue(e)},DialogContent.prototype.getPostBody=function(e){void 0===e&&(e=void 0),e||(e=this.getFlags());var t=[],n=[];t.push(this.action);for(var r=0,i=e;r1?\"path: '\"+e.path.join(\" -> \")+\"'\":e.path[0]?\"name: '\"+e.path+\"'\":\"unspecified name\",new i.BaseException(t+\" \"+n)}function composeValidators(e){return o.isPresent(e)?s.Validators.compose(e.map(c.normalizeValidator)):null}function composeAsyncValidators(e){return o.isPresent(e)?s.Validators.composeAsync(e.map(c.normalizeAsyncValidator)):null}function isPropertyUpdated(e,t){if(!r.StringMapWrapper.contains(e,\"model\"))return!1;var n=e.model;return!!n.isFirstChange()||!o.looseIdentical(t,n.currentValue)}function selectValueAccessor(e,t){if(o.isBlank(t))return null;var n,r,i;return t.forEach(function(t){o.hasConstructor(t,l.DefaultValueAccessor)?n=t:o.hasConstructor(t,a.CheckboxControlValueAccessor)||o.hasConstructor(t,u.NumberValueAccessor)||o.hasConstructor(t,d.SelectControlValueAccessor)||o.hasConstructor(t,h.SelectMultipleControlValueAccessor)||o.hasConstructor(t,p.RadioControlValueAccessor)?(o.isPresent(r)&&_throwError(e,\"More than one built-in value accessor matches form control with\"),r=t):(o.isPresent(i)&&_throwError(e,\"More than one custom value accessor matches form control with\"),i=t)}),o.isPresent(i)?i:o.isPresent(r)?r:o.isPresent(n)?n:(_throwError(e,\"No valid value accessor for form control with\"),null)}var r=n(34),i=n(83),o=n(7),s=n(58),a=n(144),l=n(145),c=n(526),u=n(227),p=n(146),d=n(147),h=n(228);t.controlPath=controlPath,t.setUpControl=setUpControl,t.setUpControlGroup=setUpControlGroup,t.composeValidators=composeValidators,t.composeAsyncValidators=composeAsyncValidators,t.isPropertyUpdated=isPropertyUpdated,t.selectValueAccessor=selectValueAccessor},function(e,t,n){\"use strict\";var r=n(0),i=n(18),o=n(28),s=function(){function CompilerConfig(e){var t=void 0===e?{}:e,n=t.renderTypes,i=void 0===n?new l:n,o=t.defaultEncapsulation,s=void 0===o?r.ViewEncapsulation.Emulated:o,a=t.genDebugInfo,c=t.logBindingUpdate,u=t.useJit,p=void 0===u||u,d=t.deprecatedPlatformDirectives,h=void 0===d?[]:d,f=t.deprecatedPlatformPipes,m=void 0===f?[]:f;this.renderTypes=i,this.defaultEncapsulation=s,this._genDebugInfo=a,this._logBindingUpdate=c,this.useJit=p,this.platformDirectives=h,this.platformPipes=m}return Object.defineProperty(CompilerConfig.prototype,\"genDebugInfo\",{get:function(){return void 0===this._genDebugInfo?r.isDevMode():this._genDebugInfo},enumerable:!0,configurable:!0}),Object.defineProperty(CompilerConfig.prototype,\"logBindingUpdate\",{get:function(){return void 0===this._logBindingUpdate?r.isDevMode():this._logBindingUpdate},enumerable:!0,configurable:!0}),CompilerConfig}();t.CompilerConfig=s;var a=function(){function RenderTypes(){}return Object.defineProperty(RenderTypes.prototype,\"renderer\",{get:function(){return i.unimplemented()},enumerable:!0,configurable:!0}),Object.defineProperty(RenderTypes.prototype,\"renderText\",{get:function(){return i.unimplemented()},enumerable:!0,configurable:!0}),Object.defineProperty(RenderTypes.prototype,\"renderElement\",{get:function(){return i.unimplemented()},enumerable:!0,configurable:!0}),Object.defineProperty(RenderTypes.prototype,\"renderComment\",{get:function(){return i.unimplemented()},enumerable:!0,configurable:!0}),Object.defineProperty(RenderTypes.prototype,\"renderNode\",{get:function(){return i.unimplemented()},enumerable:!0,configurable:!0}),Object.defineProperty(RenderTypes.prototype,\"renderEvent\",{get:function(){return i.unimplemented()},enumerable:!0,configurable:!0}),RenderTypes}();t.RenderTypes=a;var l=function(){function DefaultRenderTypes(){this.renderer=o.Identifiers.Renderer,this.renderText=null,this.renderElement=null,this.renderComment=null,this.renderNode=null,this.renderEvent=null}return DefaultRenderTypes}();t.DefaultRenderTypes=l},function(e,t){\"use strict\";function splitNsName(e){if(\":\"!=e[0])return[null,e];var t=e.indexOf(\":\",1);if(t==-1)throw new Error('Unsupported format \"'+e+'\" expecting \":namespace:name\"');return[e.slice(1,t),e.slice(t+1)]}function getNsPrefix(e){return null===e?null:splitNsName(e)[0]}function mergeNsAndName(e,t){return e?\":\"+e+\":\"+t:t}!function(e){e[e.RAW_TEXT=0]=\"RAW_TEXT\",e[e.ESCAPABLE_RAW_TEXT=1]=\"ESCAPABLE_RAW_TEXT\",e[e.PARSABLE_DATA=2]=\"PARSABLE_DATA\"}(t.TagContentType||(t.TagContentType={}));t.TagContentType;t.splitNsName=splitNsName,t.getNsPrefix=getNsPrefix,t.mergeNsAndName=mergeNsAndName,t.NAMED_ENTITIES={Aacute:\"Á\",aacute:\"á\",Acirc:\"Â\",acirc:\"â\",acute:\"´\",AElig:\"Æ\",aelig:\"æ\",Agrave:\"À\",agrave:\"à\",alefsym:\"ℵ\",Alpha:\"Α\",alpha:\"α\",amp:\"&\",and:\"∧\",ang:\"∠\",apos:\"'\",Aring:\"Å\",aring:\"å\",asymp:\"≈\",Atilde:\"Ã\",atilde:\"ã\",Auml:\"Ä\",auml:\"ä\",bdquo:\"„\",Beta:\"Β\",beta:\"β\",brvbar:\"¦\",bull:\"•\",cap:\"∩\",Ccedil:\"Ç\",ccedil:\"ç\",cedil:\"¸\",cent:\"¢\",Chi:\"Χ\",chi:\"χ\",circ:\"ˆ\",clubs:\"♣\",cong:\"≅\",copy:\"©\",crarr:\"↵\",cup:\"∪\",curren:\"¤\",dagger:\"†\",Dagger:\"‡\",darr:\"↓\",dArr:\"⇓\",deg:\"°\",Delta:\"Δ\",delta:\"δ\",diams:\"♦\",divide:\"÷\",Eacute:\"É\",eacute:\"é\",Ecirc:\"Ê\",ecirc:\"ê\",Egrave:\"È\",egrave:\"è\",empty:\"∅\",emsp:\"\u2003\",ensp:\"\u2002\",Epsilon:\"Ε\",epsilon:\"ε\",equiv:\"≡\",Eta:\"Η\",eta:\"η\",ETH:\"Ð\",eth:\"ð\",Euml:\"Ë\",euml:\"ë\",euro:\"€\",exist:\"∃\",fnof:\"ƒ\",forall:\"∀\",frac12:\"½\",frac14:\"¼\",frac34:\"¾\",frasl:\"⁄\",Gamma:\"Γ\",gamma:\"γ\",ge:\"≥\",gt:\">\",harr:\"↔\",hArr:\"⇔\",hearts:\"♥\",hellip:\"…\",Iacute:\"Í\",iacute:\"í\",Icirc:\"Î\",icirc:\"î\",iexcl:\"¡\",Igrave:\"Ì\",igrave:\"ì\",image:\"ℑ\",infin:\"∞\",\"int\":\"∫\",Iota:\"Ι\",iota:\"ι\",iquest:\"¿\",isin:\"∈\",Iuml:\"Ï\",iuml:\"ï\",Kappa:\"Κ\",kappa:\"κ\",Lambda:\"Λ\",lambda:\"λ\",lang:\"⟨\",laquo:\"«\",larr:\"←\",lArr:\"⇐\",lceil:\"⌈\",ldquo:\"“\",le:\"≤\",lfloor:\"⌊\",lowast:\"∗\",loz:\"◊\",lrm:\"\u200e\",lsaquo:\"‹\",lsquo:\"‘\",lt:\"<\",macr:\"¯\",mdash:\"—\",micro:\"µ\",middot:\"·\",minus:\"−\",Mu:\"Μ\",mu:\"μ\",nabla:\"∇\",nbsp:\"\u00a0\",ndash:\"–\",ne:\"≠\",ni:\"∋\",not:\"¬\",notin:\"∉\",nsub:\"⊄\",Ntilde:\"Ñ\",ntilde:\"ñ\",Nu:\"Ν\",nu:\"ν\",Oacute:\"Ó\",oacute:\"ó\",Ocirc:\"Ô\",ocirc:\"ô\",OElig:\"Œ\",oelig:\"œ\",Ograve:\"Ò\",ograve:\"ò\",oline:\"‾\",Omega:\"Ω\",omega:\"ω\",Omicron:\"Ο\",omicron:\"ο\",oplus:\"⊕\",or:\"∨\",ordf:\"ª\",ordm:\"º\",Oslash:\"Ø\",oslash:\"ø\",Otilde:\"Õ\",otilde:\"õ\",otimes:\"⊗\",Ouml:\"Ö\",ouml:\"ö\",para:\"¶\",permil:\"‰\",perp:\"⊥\",Phi:\"Φ\",phi:\"φ\",Pi:\"Π\",pi:\"π\",piv:\"ϖ\",plusmn:\"±\",pound:\"£\",prime:\"′\",Prime:\"″\",prod:\"∏\",prop:\"∝\",Psi:\"Ψ\",psi:\"ψ\",quot:'\"',radic:\"√\",rang:\"⟩\",raquo:\"»\",rarr:\"→\",rArr:\"⇒\",rceil:\"⌉\",rdquo:\"”\",real:\"ℜ\",reg:\"®\",rfloor:\"⌋\",Rho:\"Ρ\",rho:\"ρ\",rlm:\"\u200f\",rsaquo:\"›\",rsquo:\"’\",sbquo:\"‚\",Scaron:\"Š\",scaron:\"š\",sdot:\"⋅\",sect:\"§\",shy:\"\u00ad\",Sigma:\"Σ\",sigma:\"σ\",sigmaf:\"ς\",sim:\"∼\",spades:\"♠\",sub:\"⊂\",sube:\"⊆\",sum:\"∑\",sup:\"⊃\",sup1:\"¹\",sup2:\"²\",sup3:\"³\",supe:\"⊇\",szlig:\"ß\",Tau:\"Τ\",tau:\"τ\",there4:\"∴\",Theta:\"Θ\",theta:\"θ\",thetasym:\"ϑ\",thinsp:\"\u2009\",THORN:\"Þ\",thorn:\"þ\",tilde:\"˜\",times:\"×\",trade:\"™\",Uacute:\"Ú\",uacute:\"ú\",uarr:\"↑\",uArr:\"⇑\",Ucirc:\"Û\",ucirc:\"û\",Ugrave:\"Ù\",ugrave:\"ù\",uml:\"¨\",upsih:\"ϒ\",Upsilon:\"Υ\",upsilon:\"υ\",Uuml:\"Ü\",uuml:\"ü\",weierp:\"℘\",Xi:\"Ξ\",xi:\"ξ\",Yacute:\"Ý\",yacute:\"ý\",yen:\"¥\",yuml:\"ÿ\",Yuml:\"Ÿ\",Zeta:\"Ζ\",zeta:\"ζ\",zwj:\"\u200d\",zwnj:\"\u200c\"}},function(e,t,n){\"use strict\";function createUrlResolverWithoutPackagePrefix(){return new s}function createOfflineCompileUrlResolver(){return new s(o)}function getUrlScheme(e){var t=_split(e);return t&&t[a.Scheme]||\"\"}function _buildFromEncodedParts(e,t,n,r,o,s,a){var l=[];return i.isPresent(e)&&l.push(e+\":\"),i.isPresent(n)&&(l.push(\"//\"),i.isPresent(t)&&l.push(t+\"@\"),l.push(n),i.isPresent(r)&&l.push(\":\"+r)),i.isPresent(o)&&l.push(o),i.isPresent(s)&&l.push(\"?\"+s),i.isPresent(a)&&l.push(\"#\"+a),l.join(\"\")}function _split(e){return e.match(l)}function _removeDotSegments(e){if(\"/\"==e)return\"/\";for(var t=\"/\"==e[0]?\"/\":\"\",n=\"/\"===e[e.length-1]?\"/\":\"\",r=e.split(\"/\"),i=[],o=0,s=0;s0?i.pop():o++;break;default:i.push(a)}}if(\"\"==t){for(;o-- >0;)i.unshift(\"..\");0===i.length&&i.push(\".\")}return t+i.join(\"/\")+n}function _joinAndCanonicalizePath(e){var t=e[a.Path];return t=i.isBlank(t)?\"\":_removeDotSegments(t),e[a.Path]=t,_buildFromEncodedParts(e[a.Scheme],e[a.UserInfo],e[a.Domain],e[a.Port],t,e[a.QueryData],e[a.Fragment])}function _resolveUrl(e,t){var n=_split(encodeURI(t)),r=_split(e);if(i.isPresent(n[a.Scheme]))return _joinAndCanonicalizePath(n);n[a.Scheme]=r[a.Scheme];for(var o=a.Scheme;o<=a.Port;o++)i.isBlank(n[o])&&(n[o]=r[o]);if(\"/\"==n[a.Path][0])return _joinAndCanonicalizePath(n);var s=r[a.Path];i.isBlank(s)&&(s=\"/\");var l=s.lastIndexOf(\"/\");return s=s.substring(0,l+1)+n[a.Path],n[a.Path]=s,_joinAndCanonicalizePath(n)}var r=n(0),i=n(5),o=\"asset:\";t.createUrlResolverWithoutPackagePrefix=createUrlResolverWithoutPackagePrefix,t.createOfflineCompileUrlResolver=createOfflineCompileUrlResolver,t.DEFAULT_PACKAGE_URL_PROVIDER={provide:r.PACKAGE_ROOT_URL,useValue:\"/\"};var s=function(){function UrlResolver(e){void 0===e&&(e=null),this._packagePrefix=e}return UrlResolver.prototype.resolve=function(e,t){var n=t;i.isPresent(e)&&e.length>0&&(n=_resolveUrl(e,n));var r=_split(n),s=this._packagePrefix;if(i.isPresent(s)&&i.isPresent(r)&&\"package\"==r[a.Scheme]){var l=r[a.Path];if(this._packagePrefix!==o)return s=i.StringWrapper.stripRight(s,\"/\"),l=i.StringWrapper.stripLeft(l,\"/\"),s+\"/\"+l;var c=l.split(/\\//);n=\"asset:\"+c[0]+\"/lib/\"+c.slice(1).join(\"/\")}return n},UrlResolver.decorators=[{type:r.Injectable}],UrlResolver.ctorParameters=[{type:void 0,decorators:[{type:r.Inject,args:[r.PACKAGE_ROOT_URL]}]}],UrlResolver}();t.UrlResolver=s,t.getUrlScheme=getUrlScheme;var a,l=new RegExp(\"^(?:([^:/?#.]+):)?(?://(?:([^/?#]*)@)?([\\\\w\\\\d\\\\-\\\\u0100-\\\\uffff.%]*)(?::([0-9]+))?)?([^?#]+)?(?:\\\\?([^#]*))?(?:#(.*))?$\");!function(e){e[e.Scheme=1]=\"Scheme\",e[e.UserInfo=2]=\"UserInfo\",e[e.Domain=3]=\"Domain\",e[e.Port=4]=\"Port\",e[e.Path=5]=\"Path\",e[e.QueryData=6]=\"QueryData\",e[e.Fragment=7]=\"Fragment\"}(a||(a={}))},function(e,t,n){\"use strict\";function _enumExpression(e,t){if(s.isBlank(t))return l.NULL_EXPR;var n=s.resolveEnumToken(e.runtime,t);return l.importExpr(new o.CompileIdentifierMetadata({name:e.name+\".\"+n,moduleUrl:e.moduleUrl,runtime:t}))}var r=n(0),i=n(27),o=n(31),s=n(5),a=n(28),l=n(17),c=function(){function ViewTypeEnum(){}return ViewTypeEnum.fromValue=function(e){return _enumExpression(a.Identifiers.ViewType,e)},ViewTypeEnum.HOST=ViewTypeEnum.fromValue(i.ViewType.HOST),ViewTypeEnum.COMPONENT=ViewTypeEnum.fromValue(i.ViewType.COMPONENT),ViewTypeEnum.EMBEDDED=ViewTypeEnum.fromValue(i.ViewType.EMBEDDED),ViewTypeEnum}();t.ViewTypeEnum=c;var u=function(){function ViewEncapsulationEnum(){}return ViewEncapsulationEnum.fromValue=function(e){return _enumExpression(a.Identifiers.ViewEncapsulation,e)},ViewEncapsulationEnum.Emulated=ViewEncapsulationEnum.fromValue(r.ViewEncapsulation.Emulated),ViewEncapsulationEnum.Native=ViewEncapsulationEnum.fromValue(r.ViewEncapsulation.Native),ViewEncapsulationEnum.None=ViewEncapsulationEnum.fromValue(r.ViewEncapsulation.None),ViewEncapsulationEnum}();t.ViewEncapsulationEnum=u;var p=function(){function ChangeDetectionStrategyEnum(){}return ChangeDetectionStrategyEnum.fromValue=function(e){return _enumExpression(a.Identifiers.ChangeDetectionStrategy,e)},ChangeDetectionStrategyEnum.OnPush=ChangeDetectionStrategyEnum.fromValue(r.ChangeDetectionStrategy.OnPush),ChangeDetectionStrategyEnum.Default=ChangeDetectionStrategyEnum.fromValue(r.ChangeDetectionStrategy.Default),ChangeDetectionStrategyEnum}();t.ChangeDetectionStrategyEnum=p;var d=function(){function ChangeDetectorStatusEnum(){}return ChangeDetectorStatusEnum.fromValue=function(e){return _enumExpression(a.Identifiers.ChangeDetectorStatus,e)},ChangeDetectorStatusEnum.CheckOnce=ChangeDetectorStatusEnum.fromValue(i.ChangeDetectorStatus.CheckOnce),ChangeDetectorStatusEnum.Checked=ChangeDetectorStatusEnum.fromValue(i.ChangeDetectorStatus.Checked),ChangeDetectorStatusEnum.CheckAlways=ChangeDetectorStatusEnum.fromValue(i.ChangeDetectorStatus.CheckAlways),ChangeDetectorStatusEnum.Detached=ChangeDetectorStatusEnum.fromValue(i.ChangeDetectorStatus.Detached),ChangeDetectorStatusEnum.Errored=ChangeDetectorStatusEnum.fromValue(i.ChangeDetectorStatus.Errored),ChangeDetectorStatusEnum.Destroyed=ChangeDetectorStatusEnum.fromValue(i.ChangeDetectorStatus.Destroyed),ChangeDetectorStatusEnum}();t.ChangeDetectorStatusEnum=d;var h=function(){function ViewConstructorVars(){}return ViewConstructorVars.viewUtils=l.variable(\"viewUtils\"),ViewConstructorVars.parentInjector=l.variable(\"parentInjector\"),ViewConstructorVars.declarationEl=l.variable(\"declarationEl\"),ViewConstructorVars}();t.ViewConstructorVars=h;var f=function(){function ViewProperties(){}return ViewProperties.renderer=l.THIS_EXPR.prop(\"renderer\"),ViewProperties.projectableNodes=l.THIS_EXPR.prop(\"projectableNodes\"),ViewProperties.viewUtils=l.THIS_EXPR.prop(\"viewUtils\"),ViewProperties}();t.ViewProperties=f;var m=function(){function EventHandlerVars(){}return EventHandlerVars.event=l.variable(\"$event\"),EventHandlerVars}();t.EventHandlerVars=m;var g=function(){function InjectMethodVars(){}return InjectMethodVars.token=l.variable(\"token\"),InjectMethodVars.requestNodeIndex=l.variable(\"requestNodeIndex\"),InjectMethodVars.notFoundResult=l.variable(\"notFoundResult\"),InjectMethodVars}();t.InjectMethodVars=g;var y=function(){function DetectChangesVars(){}return DetectChangesVars.throwOnChange=l.variable(\"throwOnChange\"),DetectChangesVars.changes=l.variable(\"changes\"),DetectChangesVars.changed=l.variable(\"changed\"),DetectChangesVars.valUnwrapper=l.variable(\"valUnwrapper\"),DetectChangesVars}();t.DetectChangesVars=y},99,function(e,t,n){var r=n(95);e.exports=function(e,t,n){if(r(e),void 0===t)return e;switch(n){case 1:return function(n){return e.call(t,n)};case 2:return function(n,r){return e.call(t,n,r)};case 3:return function(n,r,i){return e.call(t,n,r,i)}}return function(){return e.apply(t,arguments)}}},function(e,t,n){var r=n(8),i=n(462),o=n(288),s=n(300)(\"IE_PROTO\"),a=function(){},l=\"prototype\",c=function(){var e,t=n(451)(\"iframe\"),r=o.length,i=\"<\",s=\">\";for(t.style.display=\"none\",n(452).appendChild(t),t.src=\"javascript:\",e=t.contentWindow.document,e.open(),e.write(i+\"script\"+s+\"document.F=Object\"+i+\"/script\"+s),e.close(),c=e.F;r--;)delete c[l][o[r]];return c()};e.exports=Object.create||function(e,t){var n;return null!==e?(a[l]=r(e),n=new a,a[l]=null,n[s]=e):n=c(),void 0===t?n:i(n,t)}},function(e,t,n){var r=n(464),i=n(288);e.exports=Object.keys||function(e){return r(e,i)}},function(e,t){e.exports=function(e,t){return{enumerable:!(1&e),configurable:!(2&e),writable:!(4&e),value:t}}},function(e,t){var n=Math.ceil,r=Math.floor;e.exports=function(e){return isNaN(e=+e)?0:(e>0?r:n)(e)}},function(e,t,n){\"use strict\";function multicast(e){var t;return t=\"function\"==typeof e?e:function(){return e},new r.ConnectableObservable(this,t)}var r=n(502);t.multicast=multicast},[1107,219],function(e,t){\"use strict\";var n=function(){function ElementSchemaRegistry(){}return ElementSchemaRegistry}();t.ElementSchemaRegistry=n},function(e,t,n){\"use strict\";function getPropertyInView(e,t,n){if(t===n)return e;for(var o=s.THIS_EXPR,a=t;a!==n&&i.isPresent(a.declarationElement.view);)a=a.declarationElement.view,o=o.prop(\"parent\");if(a!==n)throw new r.BaseException(\"Internal error: Could not calculate a property in a parent view: \"+e);if(e instanceof s.ReadPropExpr){var l=e;(n.fields.some(function(e){return e.name==l.name})||n.getters.some(function(e){return e.name==l.name}))&&(o=o.cast(n.classType))}return s.replaceVarInExpression(s.THIS_EXPR.name,o,e)}function injectFromViewParentInjector(e,t){var n=[a.createDiTokenExpression(e)];return t&&n.push(s.NULL_EXPR),s.THIS_EXPR.prop(\"parentInjector\").callMethod(\"get\",n)}function getViewFactoryName(e,t){return\"viewFactory_\"+e.type.name+t}function createFlatArray(e){for(var t=[],n=s.literalArr([]),r=0;r0&&(n=n.callMethod(s.BuiltinMethod.ConcatArray,[s.literalArr(t)]),t=[]),n=n.callMethod(s.BuiltinMethod.ConcatArray,[i])):t.push(i)}return t.length>0&&(n=n.callMethod(s.BuiltinMethod.ConcatArray,[s.literalArr(t)])),n}function createPureProxy(e,t,n,a){a.fields.push(new s.ClassField(n.name,null));var l=t0){var r=e.substring(0,n),i=e.substring(n+1).trim();t.set(r,i)}}),t},Headers.prototype.append=function(e,t){e=normalize(e);var n=this._headersMap.get(e),i=r.isListLikeIterable(n)?n:[];i.push(t),this._headersMap.set(e,i)},Headers.prototype.delete=function(e){this._headersMap.delete(normalize(e))},Headers.prototype.forEach=function(e){this._headersMap.forEach(e)},Headers.prototype.get=function(e){return r.ListWrapper.first(this._headersMap.get(normalize(e)))},Headers.prototype.has=function(e){return this._headersMap.has(normalize(e))},Headers.prototype.keys=function(){return r.MapWrapper.keys(this._headersMap)},Headers.prototype.set=function(e,t){var n=[];if(r.isListLikeIterable(t)){var i=t.join(\",\");n.push(i)}else n.push(t);this._headersMap.set(normalize(e),n)},Headers.prototype.values=function(){return r.MapWrapper.values(this._headersMap)},Headers.prototype.toJSON=function(){var e={};return this._headersMap.forEach(function(t,n){var i=[];r.iterateListLike(t,function(e){return i=r.ListWrapper.concat(i,e.split(\",\"))}),e[normalize(n)]=i}),e},Headers.prototype.getAll=function(e){var t=this._headersMap.get(normalize(e));return r.isListLikeIterable(t)?t:[]},Headers.prototype.entries=function(){throw new i.BaseException('\"entries\" method is not implemented on Headers class')},Headers}();t.Headers=s},function(e,t){\"use strict\";var n=function(){function ConnectionBackend(){}return ConnectionBackend}();t.ConnectionBackend=n;var r=function(){function Connection(){}return Connection}();t.Connection=r;var i=function(){function XSRFStrategy(){}return XSRFStrategy}();t.XSRFStrategy=i},function(e,t,n){\"use strict\";var r=n(0);t.RenderDebugInfo=r.__core_private__.RenderDebugInfo,t.wtfInit=r.__core_private__.wtfInit,t.ReflectionCapabilities=r.__core_private__.ReflectionCapabilities,t.VIEW_ENCAPSULATION_VALUES=r.__core_private__.VIEW_ENCAPSULATION_VALUES,t.DebugDomRootRenderer=r.__core_private__.DebugDomRootRenderer,t.reflector=r.__core_private__.reflector,t.NoOpAnimationPlayer=r.__core_private__.NoOpAnimationPlayer,t.AnimationPlayer=r.__core_private__.AnimationPlayer,t.AnimationSequencePlayer=r.__core_private__.AnimationSequencePlayer,t.AnimationGroupPlayer=r.__core_private__.AnimationGroupPlayer,t.AnimationKeyframe=r.__core_private__.AnimationKeyframe,t.AnimationStyles=r.__core_private__.AnimationStyles,t.prepareFinalAnimationStyles=r.__core_private__.prepareFinalAnimationStyles,t.balanceAnimationKeyframes=r.__core_private__.balanceAnimationKeyframes,t.flattenStyles=r.__core_private__.flattenStyles,t.clearStyles=r.__core_private__.clearStyles,t.collectAndResolveStyles=r.__core_private__.collectAndResolveStyles},function(e,t,n){\"use strict\";var r=n(0);t.DOCUMENT=new r.OpaqueToken(\"DocumentToken\")},function(e,t,n){\"use strict\";var r=this&&this.__extends||function(e,t){function __(){this.constructor=e}for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);e.prototype=null===t?Object.create(t):(__.prototype=t.prototype,new __)},i=n(0),o=n(33),s=n(16),a=n(62),l=n(55),c=function(){function ClientMessageBrokerFactory(){}return ClientMessageBrokerFactory}();t.ClientMessageBrokerFactory=c;var u=function(e){function ClientMessageBrokerFactory_(t,n){e.call(this),this._messageBus=t,this._serializer=n}return r(ClientMessageBrokerFactory_,e),ClientMessageBrokerFactory_.prototype.createMessageBroker=function(e,t){return void 0===t&&(t=!0),this._messageBus.initChannel(e,t),new d(this._messageBus,this._serializer,e)},ClientMessageBrokerFactory_.decorators=[{type:i.Injectable}],ClientMessageBrokerFactory_.ctorParameters=[{type:a.MessageBus},{type:l.Serializer}],ClientMessageBrokerFactory_}(c);t.ClientMessageBrokerFactory_=u;var p=function(){function ClientMessageBroker(){}return ClientMessageBroker}();t.ClientMessageBroker=p;var d=function(e){function ClientMessageBroker_(t,n,r){var i=this;e.call(this),this.channel=r,this._pending=new Map,this._sink=t.to(r),this._serializer=n;var o=t.from(r);o.subscribe({next:function(e){return i._handleMessage(e)}})}return r(ClientMessageBroker_,e),ClientMessageBroker_.prototype._generateMessageId=function(e){for(var t=s.stringify(s.DateWrapper.toMillis(s.DateWrapper.now())),n=0,r=e+t+s.stringify(n);s.isPresent(this._pending[r]);)r=\"\"+e+t+n,n++;return r},ClientMessageBroker_.prototype.runOnService=function(e,t){var n=this,r=[];s.isPresent(e.args)&&e.args.forEach(function(e){null!=e.type?r.push(n._serializer.serialize(e.value,e.type)):r.push(e.value)});var i,o=null;if(null!=t){var a;i=new Promise(function(e,t){a={resolve:e,reject:t}}),o=this._generateMessageId(e.method),this._pending.set(o,a),i.catch(function(e){s.print(e),a.reject(e)}),i=i.then(function(e){return null==n._serializer?e:n._serializer.deserialize(e,t)})}else i=null;var l={method:e.method,args:r};return null!=o&&(l.id=o),this._sink.emit(l),i},ClientMessageBroker_.prototype._handleMessage=function(e){var t=new h(e);if(s.StringWrapper.equals(t.type,\"result\")||s.StringWrapper.equals(t.type,\"error\")){var n=t.id;this._pending.has(n)&&(s.StringWrapper.equals(t.type,\"result\")?this._pending.get(n).resolve(t.value):this._pending.get(n).reject(t.value),this._pending.delete(n))}},ClientMessageBroker_}(p);t.ClientMessageBroker_=d;var h=function(){function MessageData(e){this.type=o.StringMapWrapper.get(e,\"type\"),this.id=this._getValueIfPresent(e,\"id\"),this.value=this._getValueIfPresent(e,\"value\")}return MessageData.prototype._getValueIfPresent=function(e,t){return o.StringMapWrapper.contains(e,t)?o.StringMapWrapper.get(e,t):null},MessageData}(),f=function(){function FnArg(e,t){this.value=e,this.type=t}return FnArg}();t.FnArg=f;var m=function(){function UiArguments(e,t){this.method=e,this.args=t}return UiArguments}();t.UiArguments=m},function(e,t,n){\"use strict\";var r=n(0),i=function(){function RenderStore(){this._nextIndex=0,this._lookupById=new Map,this._lookupByObject=new Map}return RenderStore.prototype.allocateId=function(){return this._nextIndex++},RenderStore.prototype.store=function(e,t){this._lookupById.set(t,e),this._lookupByObject.set(e,t)},RenderStore.prototype.remove=function(e){var t=this._lookupByObject.get(e);this._lookupByObject.delete(e),this._lookupById.delete(t)},RenderStore.prototype.deserialize=function(e){return null==e?null:this._lookupById.has(e)?this._lookupById.get(e):null},RenderStore.prototype.serialize=function(e){return null==e?null:this._lookupByObject.get(e)},RenderStore.decorators=[{type:r.Injectable}],RenderStore.ctorParameters=[],RenderStore}();t.RenderStore=i},function(e,t,n){\"use strict\";var r=this&&this.__extends||function(e,t){function __(){this.constructor=e}for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);e.prototype=null===t?Object.create(t):(__.prototype=t.prototype,new __)},i=n(0),o=n(33),s=n(16),a=n(62),l=n(55),c=function(){function ServiceMessageBrokerFactory(){}return ServiceMessageBrokerFactory}();t.ServiceMessageBrokerFactory=c;var u=function(e){function ServiceMessageBrokerFactory_(t,n){e.call(this),this._messageBus=t,this._serializer=n}return r(ServiceMessageBrokerFactory_,e),ServiceMessageBrokerFactory_.prototype.createMessageBroker=function(e,t){return void 0===t&&(t=!0),this._messageBus.initChannel(e,t),new d(this._messageBus,this._serializer,e)},ServiceMessageBrokerFactory_.decorators=[{type:i.Injectable}],ServiceMessageBrokerFactory_.ctorParameters=[{type:a.MessageBus},{type:l.Serializer}],ServiceMessageBrokerFactory_}(c);t.ServiceMessageBrokerFactory_=u;var p=function(){function ServiceMessageBroker(){}return ServiceMessageBroker}();t.ServiceMessageBroker=p;var d=function(e){function ServiceMessageBroker_(t,n,r){var i=this;e.call(this),this._serializer=n,this.channel=r,this._methods=new o.Map,this._sink=t.to(r);var s=t.from(r);s.subscribe({next:function(e){return i._handleMessage(e)}})}return r(ServiceMessageBroker_,e),ServiceMessageBroker_.prototype.registerMethod=function(e,t,n,r){var i=this;this._methods.set(e,function(e){for(var a=e.args,l=null===t?0:t.length,c=o.ListWrapper.createFixedSize(l),u=0;u0?n[n.length-1]._routeConfig._loadedConfig:null}function nodeChildrenAsMap(e){return e?e.children.reduce(function(e,t){return e[t.value.outlet]=t,e},{}):{}}function getOutlet(e,t){var n=e._outlets[t.outlet];if(!n){var r=t.component.name;throw t.outlet===g.PRIMARY_OUTLET?new Error(\"Cannot find primary outlet to load '\"+r+\"'\"):new Error(\"Cannot find the outlet \"+t.outlet+\" to load '\"+r+\"'\")}return n}n(140),n(499),n(305),n(500),n(493);var r=n(0),i=n(20),o=n(309),s=n(141),a=n(623),l=n(624),c=n(625),u=n(626),p=n(627),d=n(628),h=n(187),f=n(129),m=n(91),g=n(63),y=n(73),v=n(74),b=function(){function NavigationStart(e,t){this.id=e,this.url=t}return NavigationStart.prototype.toString=function(){return\"NavigationStart(id: \"+this.id+\", url: '\"+this.url+\"')\"},NavigationStart}();t.NavigationStart=b;var _=function(){function NavigationEnd(e,t,n){this.id=e,this.url=t,this.urlAfterRedirects=n}return NavigationEnd.prototype.toString=function(){return\"NavigationEnd(id: \"+this.id+\", url: '\"+this.url+\"', urlAfterRedirects: '\"+this.urlAfterRedirects+\"')\"},NavigationEnd}();t.NavigationEnd=_;var w=function(){function NavigationCancel(e,t){this.id=e,this.url=t}return NavigationCancel.prototype.toString=function(){return\"NavigationCancel(id: \"+this.id+\", url: '\"+this.url+\"')\"},NavigationCancel}();t.NavigationCancel=w;var S=function(){function NavigationError(e,t,n){this.id=e,this.url=t,this.error=n}return NavigationError.prototype.toString=function(){return\"NavigationError(id: \"+this.id+\", url: '\"+this.url+\"', error: \"+this.error+\")\"},NavigationError}();t.NavigationError=S;var C=function(){function RoutesRecognized(e,t,n,r){this.id=e,this.url=t,this.urlAfterRedirects=n,this.state=r}return RoutesRecognized.prototype.toString=function(){return\"RoutesRecognized(id: \"+this.id+\", url: '\"+this.url+\"', urlAfterRedirects: '\"+this.urlAfterRedirects+\"', state: \"+this.state+\")\"},RoutesRecognized}();t.RoutesRecognized=C;var E=function(){function Router(e,t,n,r,o,s,a,l){this.rootComponentType=e,this.resolver=t,this.urlSerializer=n,this.outletMap=r,this.location=o,this.injector=s,this.navigationId=0,this.navigated=!1,this.resetConfig(l),this.routerEvents=new i.Subject,this.currentUrlTree=y.createEmptyUrlTree(),this.configLoader=new h.RouterConfigLoader(a),this.currentRouterState=m.createEmptyState(this.currentUrlTree,this.rootComponentType)}return Router.prototype.initialNavigation=function(){this.setUpLocationChangeListener(),this.navigateByUrl(this.location.path(!0))},Object.defineProperty(Router.prototype,\"routerState\",{get:function(){return this.currentRouterState},enumerable:!0,configurable:!0}),Object.defineProperty(Router.prototype,\"url\",{get:function(){return this.serializeUrl(this.currentUrlTree)},enumerable:!0,configurable:!0}),Object.defineProperty(Router.prototype,\"events\",{get:function(){return this.routerEvents},enumerable:!0,configurable:!0}),Router.prototype.resetConfig=function(e){l.validateConfig(e),this.config=e},Router.prototype.ngOnDestroy=function(){this.dispose()},Router.prototype.dispose=function(){this.locationSubscription.unsubscribe()},Router.prototype.createUrlTree=function(e,t){var n=void 0===t?{}:t,r=n.relativeTo,i=n.queryParams,o=n.fragment,s=n.preserveQueryParams,a=n.preserveFragment,l=r?r:this.routerState.root,c=s?this.currentUrlTree.queryParams:i,p=a?this.currentUrlTree.fragment:o;return u.createUrlTree(l,this.currentUrlTree,e,c,p)},Router.prototype.navigateByUrl=function(e,t){if(void 0===t&&(t={skipLocationChange:!1}),e instanceof y.UrlTree)return this.scheduleNavigation(e,t);var n=this.urlSerializer.parse(e);return this.scheduleNavigation(n,t)},Router.prototype.navigate=function(e,t){return void 0===t&&(t={skipLocationChange:!1}),this.scheduleNavigation(this.createUrlTree(e,t),t)},Router.prototype.serializeUrl=function(e){return this.urlSerializer.serialize(e)},Router.prototype.parseUrl=function(e){return this.urlSerializer.parse(e)},Router.prototype.isActive=function(e,t){if(e instanceof y.UrlTree)return y.containsTree(this.currentUrlTree,e,t);var n=this.urlSerializer.parse(e);return y.containsTree(this.currentUrlTree,n,t)},Router.prototype.scheduleNavigation=function(e,t){var n=this,r=++this.navigationId;return this.routerEvents.next(new b(r,this.serializeUrl(e))),Promise.resolve().then(function(i){return n.runNavigate(e,t.skipLocationChange,r)})},Router.prototype.setUpLocationChangeListener=function(){var e=this;this.locationSubscription=this.location.subscribe(Zone.current.wrap(function(t){var n=e.urlSerializer.parse(t.url);return e.currentUrlTree.toString()!==n.toString()?e.scheduleNavigation(n,t.pop):null}))},Router.prototype.runNavigate=function(e,t,n){var r=this;return n!==this.navigationId?(this.location.go(this.urlSerializer.serialize(this.currentUrlTree)),this.routerEvents.next(new w(n,this.serializeUrl(e))),Promise.resolve(!1)):new Promise(function(i,o){var l,u,h,f,m=r.currentRouterState,g=r.currentUrlTree;a.applyRedirects(r.injector,r.configLoader,e,r.config).mergeMap(function(e){return f=e,p.recognize(r.rootComponentType,r.config,f,r.serializeUrl(f))}).mergeMap(function(t){return r.routerEvents.next(new C(n,r.serializeUrl(e),r.serializeUrl(f),t)),d.resolve(r.resolver,t)}).map(function(e){return c.createRouterState(e,r.currentRouterState)}).map(function(e){l=e,h=new P(l.snapshot,r.currentRouterState.snapshot,r.injector),h.traverse(r.outletMap)}).mergeMap(function(e){return h.checkGuards()}).mergeMap(function(e){return e?h.resolveData().map(function(){return e}):s.of(e)}).forEach(function(i){if(!i||n!==r.navigationId)return r.routerEvents.next(new w(n,r.serializeUrl(e))),void(u=!1);if(r.currentUrlTree=f,r.currentRouterState=l,new x(l,m).activate(r.outletMap),!t){var o=r.urlSerializer.serialize(f);r.location.isCurrentPathEqualTo(o)?r.location.replaceState(o):r.location.go(o)}u=!0}).then(function(){r.navigated=!0,r.routerEvents.next(new _(n,r.serializeUrl(e),r.serializeUrl(f))),i(u)},function(t){r.currentRouterState=m,r.currentUrlTree=g,r.routerEvents.next(new S(n,r.serializeUrl(e),t)),o(t)})})},Router}();t.Router=E;var R=function(){function CanActivate(e){this.path=e}return Object.defineProperty(CanActivate.prototype,\"route\",{get:function(){return this.path[this.path.length-1]},enumerable:!0,configurable:!0}),CanActivate}(),T=function(){function CanDeactivate(e,t){this.component=e,this.route=t}return CanDeactivate}(),P=function(){function PreActivation(e,t,n){this.future=e,this.curr=t,this.injector=n,this.checks=[]}return PreActivation.prototype.traverse=function(e){var t=this.future._root,n=this.curr?this.curr._root:null;this.traverseChildRoutes(t,n,e,[t.value])},PreActivation.prototype.checkGuards=function(){var e=this;return 0===this.checks.length?s.of(!0):o.from(this.checks).map(function(t){if(t instanceof R)return v.andObservables(o.from([e.runCanActivate(t.route),e.runCanActivateChild(t.path)]));if(t instanceof T){var n=t;return e.runCanDeactivate(n.component,n.route)}throw new Error(\"Cannot be reached\")}).mergeAll().every(function(e){return e===!0})},PreActivation.prototype.resolveData=function(){var e=this;return 0===this.checks.length?s.of(null):o.from(this.checks).mergeMap(function(t){return t instanceof R?e.runResolve(t.route):s.of(null)}).reduce(function(e,t){return e})},PreActivation.prototype.traverseChildRoutes=function(e,t,n,r){var i=this,o=nodeChildrenAsMap(t);e.children.forEach(function(e){i.traverseRoutes(e,o[e.value.outlet],n,r.concat([e.value])),delete o[e.value.outlet]}),v.forEach(o,function(e,t){return i.deactivateOutletAndItChildren(e,n._outlets[t])})},PreActivation.prototype.traverseRoutes=function(e,t,n,r){var i=e.value,o=t?t.value:null,s=n?n._outlets[e.value.outlet]:null;o&&i._routeConfig===o._routeConfig?(v.shallowEqual(i.params,o.params)||this.checks.push(new T(s.component,o),new R(r)),i.component?this.traverseChildRoutes(e,t,s?s.outletMap:null,r):this.traverseChildRoutes(e,t,n,r)):(o&&(o.component?this.deactivateOutletAndItChildren(o,s):this.deactivateOutletMap(n)),this.checks.push(new R(r)),i.component?this.traverseChildRoutes(e,null,s?s.outletMap:null,r):this.traverseChildRoutes(e,null,n,r))},PreActivation.prototype.deactivateOutletAndItChildren=function(e,t){t&&t.isActivated&&(this.deactivateOutletMap(t.outletMap),this.checks.push(new T(t.component,e)))},PreActivation.prototype.deactivateOutletMap=function(e){var t=this;v.forEach(e._outlets,function(e){e.isActivated&&t.deactivateOutletAndItChildren(e.activatedRoute.snapshot,e)})},PreActivation.prototype.runCanActivate=function(e){var t=this,n=e._routeConfig?e._routeConfig.canActivate:null;if(!n||0===n.length)return s.of(!0);var r=o.from(n).map(function(n){var r=t.getToken(n,e,t.future);return r.canActivate?v.wrapIntoObservable(r.canActivate(e,t.future)):v.wrapIntoObservable(r(e,t.future))});return v.andObservables(r)},PreActivation.prototype.runCanActivateChild=function(e){var t=this,n=e[e.length-1],r=e.slice(0,e.length-1).reverse().map(function(e){return t.extractCanActivateChild(e)}).filter(function(e){return null!==e});return v.andObservables(o.from(r).map(function(e){var r=o.from(e.guards).map(function(e){var r=t.getToken(e,e.node,t.future);return r.canActivateChild?v.wrapIntoObservable(r.canActivateChild(n,t.future)):v.wrapIntoObservable(r(n,t.future))});return v.andObservables(r)}))},PreActivation.prototype.extractCanActivateChild=function(e){var t=e._routeConfig?e._routeConfig.canActivateChild:null;return t&&0!==t.length?{node:e,guards:t}:null},PreActivation.prototype.runCanDeactivate=function(e,t){var n=this,r=t&&t._routeConfig?t._routeConfig.canDeactivate:null;return r&&0!==r.length?o.from(r).map(function(r){var i=n.getToken(r,t,n.curr);return i.canDeactivate?v.wrapIntoObservable(i.canDeactivate(e,t,n.curr)):v.wrapIntoObservable(i(e,t,n.curr))}).mergeAll().every(function(e){return e===!0}):s.of(!0)},PreActivation.prototype.runResolve=function(e){var t=e._resolve;return this.resolveNode(t.current,e).map(function(n){return t.resolvedData=n,e.data=v.merge(e.data,t.flattenedResolvedData),null})},PreActivation.prototype.resolveNode=function(e,t){var n=this;return v.waitForMap(e,function(e,r){var i=n.getToken(r,t,n.future);return i.resolve?v.wrapIntoObservable(i.resolve(t,n.future)):v.wrapIntoObservable(i(t,n.future))})},PreActivation.prototype.getToken=function(e,t,n){var r=closestLoadedConfig(n,t),i=r?r.injector:this.injector;return i.get(e)},PreActivation}(),x=function(){function ActivateRoutes(e,t){this.futureState=e,this.currState=t}return ActivateRoutes.prototype.activate=function(e){var t=this.futureState._root,n=this.currState?this.currState._root:null;m.advanceActivatedRoute(this.futureState.root),this.activateChildRoutes(t,n,e)},ActivateRoutes.prototype.activateChildRoutes=function(e,t,n){var r=this,i=nodeChildrenAsMap(t);e.children.forEach(function(e){r.activateRoutes(e,i[e.value.outlet],n),delete i[e.value.outlet]}),v.forEach(i,function(e,t){return r.deactivateOutletAndItChildren(n._outlets[t])})},ActivateRoutes.prototype.activateRoutes=function(e,t,n){\nvar r=e.value,i=t?t.value:null;if(r===i)if(m.advanceActivatedRoute(r),r.component){var o=getOutlet(n,e.value);this.activateChildRoutes(e,t,o.outletMap)}else this.activateChildRoutes(e,t,n);else{if(i)if(i.component){var o=getOutlet(n,e.value);this.deactivateOutletAndItChildren(o)}else this.deactivateOutletMap(n);if(r.component){m.advanceActivatedRoute(r);var o=getOutlet(n,e.value),s=new f.RouterOutletMap;this.placeComponentIntoOutlet(s,r,o),this.activateChildRoutes(e,null,s)}else m.advanceActivatedRoute(r),this.activateChildRoutes(e,null,n)}},ActivateRoutes.prototype.placeComponentIntoOutlet=function(e,t,n){var i=[{provide:m.ActivatedRoute,useValue:t},{provide:f.RouterOutletMap,useValue:e}],o=closestLoadedConfig(this.futureState.snapshot,t.snapshot),s=null,a=null;o&&(s=o.factoryResolver,a=o.injector,i.push({provide:r.ComponentFactoryResolver,useValue:s})),n.activate(t,s,a,r.ReflectiveInjector.resolve(i),e)},ActivateRoutes.prototype.deactivateOutletAndItChildren=function(e){e&&e.isActivated&&(this.deactivateOutletMap(e.outletMap),e.deactivate())},ActivateRoutes.prototype.deactivateOutletMap=function(e){var t=this;v.forEach(e._outlets,function(e){return t.deactivateOutletAndItChildren(e)})},ActivateRoutes}()},function(e,t){\"use strict\";var n=function(){function RouterOutletMap(){this._outlets={}}return RouterOutletMap.prototype.registerOutlet=function(e,t){this._outlets[e]=t},RouterOutletMap.prototype.removeOutlet=function(e){this._outlets[e]=void 0},RouterOutletMap}();t.RouterOutletMap=n},function(e,t,n){\"use strict\";var r=n(43),i=(n.n(r),n(0));n.n(i);n.d(t,\"a\",function(){return a});var o=this&&this.__decorate||function(e,t,n,r){var i,o=arguments.length,s=o<3?t:null===r?r=Object.getOwnPropertyDescriptor(t,n):r;if(\"object\"==typeof Reflect&&\"function\"==typeof Reflect.decorate)s=Reflect.decorate(e,t,n,r);else for(var a=e.length-1;a>=0;a--)(i=e[a])&&(s=(o<3?i(s):o>3?i(t,n,s):i(t,n))||s);return o>3&&s&&Object.defineProperty(t,n,s),s},s=this&&this.__metadata||function(e,t){if(\"object\"==typeof Reflect&&\"function\"==typeof Reflect.metadata)return Reflect.metadata(e,t)},a=function(){function FeaturesService(e){var t=this;this.http=e,this.activeReparents=!1,this.showStatus=!1,this.showTopologyCRUD=!1,this.showWorkflows=!1,this.workflows=[],this.featuresUrl=\"../api/features\",this.getFeatures().subscribe(function(e){t.activeReparents=e.activeReparents,t.showStatus=e.showStatus,t.showTopologyCRUD=e.showTopologyCRUD,t.showWorkflows=e.showWorkflows,t.workflows=e.workflows})}return FeaturesService.prototype.getFeatures=function(){return this.http.get(this.featuresUrl).map(function(e){return e.json()})},FeaturesService=o([n.i(i.Injectable)(),s(\"design:paramtypes\",[\"function\"==typeof(e=\"undefined\"!=typeof r.Http&&r.Http)&&e||Object])],FeaturesService);var e}()},function(e,t,n){\"use strict\";var r=n(43),i=(n.n(r),n(0)),o=(n.n(i),n(484)),s=(n.n(o),n(283)),a=n(644),l=n(284);n.d(t,\"a\",function(){return p});var c=this&&this.__decorate||function(e,t,n,r){var i,o=arguments.length,s=o<3?t:null===r?r=Object.getOwnPropertyDescriptor(t,n):r;if(\"object\"==typeof Reflect&&\"function\"==typeof Reflect.decorate)s=Reflect.decorate(e,t,n,r);else for(var a=e.length-1;a>=0;a--)(i=e[a])&&(s=(o<3?i(s):o>3?i(t,n,s):i(t,n))||s);return o>3&&s&&Object.defineProperty(t,n,s),s},u=this&&this.__metadata||function(e,t){if(\"object\"==typeof Reflect&&\"function\"==typeof Reflect.metadata)return Reflect.metadata(e,t)},p=function(){function KeyspaceService(e,t){this.http=e,this.shardService=t,this.keyspacesUrl=\"../api/keyspaces/\",this.srvKeyspaceUrl=\"../api/srv_keyspace/local/\"}return KeyspaceService.prototype.getShards=function(e){return this.shardService.getShards(e)},KeyspaceService.prototype.getKeyspaceNames=function(){return this.http.get(this.keyspacesUrl).map(function(e){return e.json()})},KeyspaceService.prototype.getSrvKeyspaces=function(){return this.http.get(this.srvKeyspaceUrl).map(function(e){return e.json()})},KeyspaceService.prototype.SrvKeyspaceAndNamesObservable=function(){var e=this.getKeyspaceNames(),t=this.getSrvKeyspaces();return e.combineLatest(t)},KeyspaceService.prototype.getKeyspaceShardingData=function(e){return this.http.get(this.keyspacesUrl+e).map(function(e){return e.json()})},KeyspaceService.prototype.getShardsAndShardingData=function(e){var t=this.getShards(e),n=this.getKeyspaceShardingData(e);return t.combineLatest(n)},KeyspaceService.prototype.buildKeyspace=function(e,t){return this.getShardsAndShardingData(e).map(function(n){var r=n[0],i=n[1],o=new a.a(e);return t.forEach(function(e){return o.addServingShard(e)}),r.forEach(function(e){o.contains(e)||o.addNonservingShard(e)}),o.shardingColumnName=i.sharding_column_name||\"\",o.shardingColumnType=i.sharding_column_type||\"\",o})},KeyspaceService.prototype.getServingShards=function(e,t){if(t&&t[e]){var n=t[e].partitions;if(void 0===n)return[];for(var r=0;r=0;a--)(i=e[a])&&(s=(o<3?i(s):o>3?i(t,n,s):i(t,n))||s);return o>3&&s&&Object.defineProperty(t,n,s),s},i=this&&this.__metadata||function(e,t){if(\"object\"==typeof Reflect&&\"function\"==typeof Reflect.metadata)return Reflect.metadata(e,t)},o=n(0),s=n(9),a=n(3),l=function(){function Button(e,t){this.el=e,this.domHandler=t,this.iconPos=\"left\"}return Button.prototype.ngAfterViewInit=function(){if(this.domHandler.addMultipleClasses(this.el.nativeElement,this.getStyleClass()),this.icon){var e=document.createElement(\"span\"),t=\"right\"==this.iconPos?\"ui-button-icon-right\":\"ui-button-icon-left\";e.className=t+\" ui-c fa fa-fw \"+this.icon,this.el.nativeElement.appendChild(e)}var n=document.createElement(\"span\");n.className=\"ui-button-text ui-c\",n.appendChild(document.createTextNode(this.label||\"ui-button\")),this.el.nativeElement.appendChild(n),this.initialized=!0},Button.prototype.onMouseenter=function(e){this.hover=!0},Button.prototype.onMouseleave=function(e){this.hover=!1,this.active=!1},Button.prototype.onMouseDown=function(e){this.active=!0},Button.prototype.onMouseUp=function(e){this.active=!1},Button.prototype.onFocus=function(e){this.focus=!0},Button.prototype.onBlur=function(e){this.focus=!1},Button.prototype.isDisabled=function(){return this.el.nativeElement.disabled},Button.prototype.getStyleClass=function(){var e=\"ui-button ui-widget ui-state-default ui-corner-all\";return e+=this.icon?null!=this.label&&void 0!=this.label?\"left\"==this.iconPos?\" ui-button-text-icon-left\":\" ui-button-text-icon-right\":\" ui-button-icon-only\":\" ui-button-text-only\"},Object.defineProperty(Button.prototype,\"label\",{get:function(){return this._label},set:function(e){this._label=e,this.initialized&&(this.domHandler.findSingle(this.el.nativeElement,\".ui-button-text\").textContent=this._label)},enumerable:!0,configurable:!0}),Button.prototype.ngOnDestroy=function(){for(;this.el.nativeElement.hasChildNodes();)this.el.nativeElement.removeChild(this.el.nativeElement.lastChild);this.initialized=!1},r([o.Input(),i(\"design:type\",String)],Button.prototype,\"icon\",void 0),r([o.Input(),i(\"design:type\",String)],Button.prototype,\"iconPos\",void 0),r([o.HostListener(\"mouseenter\",[\"$event\"]),i(\"design:type\",Function),i(\"design:paramtypes\",[Object]),i(\"design:returntype\",void 0)],Button.prototype,\"onMouseenter\",null),r([o.HostListener(\"mouseleave\",[\"$event\"]),i(\"design:type\",Function),i(\"design:paramtypes\",[Object]),i(\"design:returntype\",void 0)],Button.prototype,\"onMouseleave\",null),r([o.HostListener(\"mousedown\",[\"$event\"]),i(\"design:type\",Function),i(\"design:paramtypes\",[Object]),i(\"design:returntype\",void 0)],Button.prototype,\"onMouseDown\",null),r([o.HostListener(\"mouseup\",[\"$event\"]),i(\"design:type\",Function),i(\"design:paramtypes\",[Object]),i(\"design:returntype\",void 0)],Button.prototype,\"onMouseUp\",null),r([o.HostListener(\"focus\",[\"$event\"]),i(\"design:type\",Function),i(\"design:paramtypes\",[Object]),i(\"design:returntype\",void 0)],Button.prototype,\"onFocus\",null),r([o.HostListener(\"blur\",[\"$event\"]),i(\"design:type\",Function),i(\"design:paramtypes\",[Object]),i(\"design:returntype\",void 0)],Button.prototype,\"onBlur\",null),r([o.Input(),i(\"design:type\",String)],Button.prototype,\"label\",null),Button=r([o.Directive({selector:\"[pButton]\",host:{\"[class.ui-state-hover]\":\"hover&&!isDisabled()\",\"[class.ui-state-focus]\":\"focus\",\"[class.ui-state-active]\":\"active\",\"[class.ui-state-disabled]\":\"isDisabled()\"},providers:[s.DomHandler]}),i(\"design:paramtypes\",[o.ElementRef,s.DomHandler])],Button)}();t.Button=l;var c=function(){function ButtonModule(){}return ButtonModule=r([o.NgModule({imports:[a.CommonModule],exports:[l],declarations:[l]}),i(\"design:paramtypes\",[])],ButtonModule)}();t.ButtonModule=c},function(e,t,n){\"use strict\";var r=n(1),i=n(505);r.Observable.prototype.map=i.map},function(e,t,n){\"use strict\";var r=n(79);t.of=r.ArrayObservable.of},function(e,t,n){\"use strict\";var r=n(51),i=r.root.Symbol;if(\"function\"==typeof i)i.iterator?t.$$iterator=i.iterator:\"function\"==typeof i.for&&(t.$$iterator=i.for(\"iterator\"));else if(r.root.Set&&\"function\"==typeof(new r.root.Set)[\"@@iterator\"])t.$$iterator=\"@@iterator\";else if(r.root.Map)for(var o=Object.getOwnPropertyNames(r.root.Map.prototype),s=0;s=this.length?i.$EOF:o.StringWrapper.charCodeAt(this.input,this.index)},_Scanner.prototype.scanToken=function(){for(var e=this.input,t=this.length,n=this.peek,r=this.index;n<=i.$SPACE;){if(++r>=t){n=i.$EOF;break}n=o.StringWrapper.charCodeAt(e,r)}if(this.peek=n,this.index=r,r>=t)return null;if(isIdentifierStart(n))return this.scanIdentifier();if(i.isDigit(n))return this.scanNumber(r);var s=r;switch(n){case i.$PERIOD:return this.advance(),i.isDigit(this.peek)?this.scanNumber(s):newCharacterToken(s,i.$PERIOD);case i.$LPAREN:case i.$RPAREN:case i.$LBRACE:case i.$RBRACE:case i.$LBRACKET:case i.$RBRACKET:case i.$COMMA:case i.$COLON:case i.$SEMICOLON:return this.scanCharacter(s,n);case i.$SQ:case i.$DQ:return this.scanString();case i.$HASH:case i.$PLUS:case i.$MINUS:case i.$STAR:case i.$SLASH:case i.$PERCENT:case i.$CARET:return this.scanOperator(s,o.StringWrapper.fromCharCode(n));case i.$QUESTION:return this.scanComplexOperator(s,\"?\",i.$PERIOD,\".\");case i.$LT:case i.$GT:return this.scanComplexOperator(s,o.StringWrapper.fromCharCode(n),i.$EQ,\"=\");case i.$BANG:case i.$EQ:return this.scanComplexOperator(s,o.StringWrapper.fromCharCode(n),i.$EQ,\"=\",i.$EQ,\"=\");case i.$AMPERSAND:return this.scanComplexOperator(s,\"&\",i.$AMPERSAND,\"&\");case i.$BAR:return this.scanComplexOperator(s,\"|\",i.$BAR,\"|\");case i.$NBSP:for(;i.isWhitespace(this.peek);)this.advance();return this.scanToken()}return this.advance(),this.error(\"Unexpected character [\"+o.StringWrapper.fromCharCode(n)+\"]\",0)},_Scanner.prototype.scanCharacter=function(e,t){return this.advance(),newCharacterToken(e,t)},_Scanner.prototype.scanOperator=function(e,t){return this.advance(),newOperatorToken(e,t)},_Scanner.prototype.scanComplexOperator=function(e,t,n,r,i,s){this.advance();var a=t;return this.peek==n&&(this.advance(),a+=r),o.isPresent(i)&&this.peek==i&&(this.advance(),a+=s),newOperatorToken(e,a)},_Scanner.prototype.scanIdentifier=function(){var e=this.index;for(this.advance();isIdentifierPart(this.peek);)this.advance();var t=this.input.substring(e,this.index);return a.indexOf(t)>-1?newKeywordToken(e,t):newIdentifierToken(e,t)},_Scanner.prototype.scanNumber=function(e){var t=this.index===e;for(this.advance();;){if(i.isDigit(this.peek));else if(this.peek==i.$PERIOD)t=!1;else{if(!isExponentStart(this.peek))break;if(this.advance(),isExponentSign(this.peek)&&this.advance(),!i.isDigit(this.peek))return this.error(\"Invalid exponent\",-1);t=!1}this.advance()}var n=this.input.substring(e,this.index),r=t?o.NumberWrapper.parseIntAutoRadix(n):o.NumberWrapper.parseFloat(n);return newNumberToken(e,r)},_Scanner.prototype.scanString=function(){var e=this.index,t=this.peek;this.advance();for(var n,r=this.index,s=this.input;this.peek!=t;)if(this.peek==i.$BACKSLASH){null==n&&(n=new o.StringJoiner),n.add(s.substring(r,this.index)),this.advance();var a;if(this.peek==i.$u){var l=s.substring(this.index+1,this.index+5);try{a=o.NumberWrapper.parseInt(l,16)}catch(c){return this.error(\"Invalid unicode escape [\\\\u\"+l+\"]\",0)}for(var u=0;u<5;u++)this.advance()}else a=unescape(this.peek),this.advance();n.add(o.StringWrapper.fromCharCode(a)),r=this.index}else{if(this.peek==i.$EOF)return this.error(\"Unterminated quote\",0);this.advance()}var p=s.substring(r,this.index);this.advance();var d=p;return null!=n&&(n.add(p),d=n.toString()),newStringToken(e,d)},_Scanner.prototype.error=function(e,t){var n=this.index+t;return newErrorToken(n,\"Lexer Error: \"+e+\" at column \"+n+\" in expression [\"+this.input+\"]\")},_Scanner}();t.isIdentifier=isIdentifier,t.isQuote=isQuote},function(e,t,n){\"use strict\";function _createInterpolateRegExp(e){var t=o.escapeRegExp(e.start)+\"([\\\\s\\\\S]*?)\"+o.escapeRegExp(e.end);return new RegExp(t,\"g\")}var r=n(0),i=n(233),o=n(5),s=n(68),a=n(236),l=n(151),c=function(){function SplitInterpolation(e,t){this.strings=e,this.expressions=t}return SplitInterpolation}();t.SplitInterpolation=c;var u=function(){function TemplateBindingParseResult(e,t,n){this.templateBindings=e,this.warnings=t,this.errors=n}return TemplateBindingParseResult}();t.TemplateBindingParseResult=u;var p=function(){function Parser(e){this._lexer=e,this.errors=[]}return Parser.prototype.parseAction=function(e,t,n){void 0===n&&(n=s.DEFAULT_INTERPOLATION_CONFIG),this._checkNoInterpolation(e,t,n);var r=this._lexer.tokenize(this._stripComments(e)),i=new d(e,t,r,(!0),this.errors).parseChain();return new a.ASTWithSource(i,e,t,this.errors)},Parser.prototype.parseBinding=function(e,t,n){void 0===n&&(n=s.DEFAULT_INTERPOLATION_CONFIG);var r=this._parseBindingAst(e,t,n);return new a.ASTWithSource(r,e,t,this.errors)},Parser.prototype.parseSimpleBinding=function(e,t,n){void 0===n&&(n=s.DEFAULT_INTERPOLATION_CONFIG);var r=this._parseBindingAst(e,t,n);return h.check(r)||this._reportError(\"Host binding expression can only contain field access and constants\",e,t),new a.ASTWithSource(r,e,t,this.errors)},Parser.prototype._reportError=function(e,t,n,r){this.errors.push(new a.ParserError(e,t,n,r))},Parser.prototype._parseBindingAst=function(e,t,n){var r=this._parseQuote(e,t);if(o.isPresent(r))return r;this._checkNoInterpolation(e,t,n);var i=this._lexer.tokenize(this._stripComments(e));return new d(e,t,i,(!1),this.errors).parseChain()},Parser.prototype._parseQuote=function(e,t){if(o.isBlank(e))return null;var n=e.indexOf(\":\");if(n==-1)return null;var r=e.substring(0,n).trim();if(!l.isIdentifier(r))return null;var i=e.substring(n+1);return new a.Quote(new a.ParseSpan(0,e.length),r,i,t)},Parser.prototype.parseTemplateBindings=function(e,t){var n=this._lexer.tokenize(e);return new d(e,t,n,(!1),this.errors).parseTemplateBindings()},Parser.prototype.parseInterpolation=function(e,t,n){void 0===n&&(n=s.DEFAULT_INTERPOLATION_CONFIG);var r=this.splitInterpolation(e,t,n);if(null==r)return null;for(var i=[],l=0;l0?l.push(p):this._reportError(\"Blank expressions are not allowed in interpolated strings\",e,\"at column \"+this._findInterpolationErrorColumn(i,u,n)+\" in\",t)}return new c(a,l)},Parser.prototype.wrapLiteralPrimitive=function(e,t){return new a.ASTWithSource(new a.LiteralPrimitive(new a.ParseSpan(0,o.isBlank(e)?0:e.length),e),e,t,this.errors)},Parser.prototype._stripComments=function(e){var t=this._commentStart(e);return o.isPresent(t)?e.substring(0,t).trim():e},Parser.prototype._commentStart=function(e){for(var t=null,n=0;n1&&this._reportError(\"Got interpolation (\"+n.start+n.end+\") where expression was expected\",e,\"at column \"+this._findInterpolationErrorColumn(i,1,n)+\" in\",t)},Parser.prototype._findInterpolationErrorColumn=function(e,t,n){for(var r=\"\",i=0;i\":case\"<=\":case\">=\":this.advance();var n=this.parseAdditive();e=new a.Binary(this.span(e.span.start),t,e,n);continue}break}return e},_ParseAST.prototype.parseAdditive=function(){for(var e=this.parseMultiplicative();this.next.type==l.TokenType.Operator;){var t=this.next.strValue;switch(t){case\"+\":case\"-\":this.advance();var n=this.parseMultiplicative();e=new a.Binary(this.span(e.span.start),t,e,n);continue}break}return e},_ParseAST.prototype.parseMultiplicative=function(){for(var e=this.parsePrefix();this.next.type==l.TokenType.Operator;){var t=this.next.strValue;switch(t){case\"*\":case\"%\":case\"/\":this.advance();var n=this.parsePrefix();e=new a.Binary(this.span(e.span.start),t,e,n);continue}break}return e},_ParseAST.prototype.parsePrefix=function(){if(this.next.type==l.TokenType.Operator){var e=this.inputIndex,t=this.next.strValue,n=void 0;switch(t){case\"+\":return this.advance(),this.parsePrefix();case\"-\":return this.advance(),n=this.parsePrefix(),new a.Binary(this.span(e),t,new a.LiteralPrimitive(new a.ParseSpan(e,e),0),n);case\"!\":return this.advance(),n=this.parsePrefix(),new a.PrefixNot(this.span(e),n)}}return this.parseCallChain()},_ParseAST.prototype.parseCallChain=function(){for(var e=this.parsePrimary();;)if(this.optionalCharacter(i.$PERIOD))e=this.parseAccessMemberOrMethodCall(e,!1);else if(this.optionalOperator(\"?.\"))e=this.parseAccessMemberOrMethodCall(e,!0);else if(this.optionalCharacter(i.$LBRACKET)){this.rbracketsExpected++;var t=this.parsePipe();if(this.rbracketsExpected--,this.expectCharacter(i.$RBRACKET),this.optionalOperator(\"=\")){var n=this.parseConditional();e=new a.KeyedWrite(this.span(e.span.start),e,t,n)}else e=new a.KeyedRead(this.span(e.span.start),e,t)}else{if(!this.optionalCharacter(i.$LPAREN))return e;this.rparensExpected++;var r=this.parseCallArguments();this.rparensExpected--,this.expectCharacter(i.$RPAREN),e=new a.FunctionCall(this.span(e.span.start),e,r)}},_ParseAST.prototype.parsePrimary=function(){var e=this.inputIndex;if(this.optionalCharacter(i.$LPAREN)){this.rparensExpected++;var t=this.parsePipe();return this.rparensExpected--,this.expectCharacter(i.$RPAREN),t}if(this.next.isKeywordNull())return this.advance(),new a.LiteralPrimitive(this.span(e),null);if(this.next.isKeywordUndefined())return this.advance(),new a.LiteralPrimitive(this.span(e),(void 0));if(this.next.isKeywordTrue())return this.advance(),new a.LiteralPrimitive(this.span(e),(!0));if(this.next.isKeywordFalse())return this.advance(),new a.LiteralPrimitive(this.span(e),(!1));if(this.next.isKeywordThis())return this.advance(),new a.ImplicitReceiver(this.span(e));if(this.optionalCharacter(i.$LBRACKET)){this.rbracketsExpected++;var n=this.parseExpressionList(i.$RBRACKET);return this.rbracketsExpected--,this.expectCharacter(i.$RBRACKET),new a.LiteralArray(this.span(e),n)}if(this.next.isCharacter(i.$LBRACE))return this.parseLiteralMap();if(this.next.isIdentifier())return this.parseAccessMemberOrMethodCall(new a.ImplicitReceiver(this.span(e)),!1);if(this.next.isNumber()){var r=this.next.toNumber();return this.advance(),new a.LiteralPrimitive(this.span(e),r)}if(this.next.isString()){var o=this.next.toString();return this.advance(),new a.LiteralPrimitive(this.span(e),o)}return this.index>=this.tokens.length?(this.error(\"Unexpected end of expression: \"+this.input),new a.EmptyExpr(this.span(e))):(this.error(\"Unexpected token \"+this.next),new a.EmptyExpr(this.span(e)))},_ParseAST.prototype.parseExpressionList=function(e){var t=[];if(!this.next.isCharacter(e))do t.push(this.parsePipe());while(this.optionalCharacter(i.$COMMA));return t},_ParseAST.prototype.parseLiteralMap=function(){var e=[],t=[],n=this.inputIndex;if(this.expectCharacter(i.$LBRACE),!this.optionalCharacter(i.$RBRACE)){this.rbracesExpected++;do{var r=this.expectIdentifierOrKeywordOrString();e.push(r),this.expectCharacter(i.$COLON),t.push(this.parsePipe())}while(this.optionalCharacter(i.$COMMA));this.rbracesExpected--,this.expectCharacter(i.$RBRACE)}return new a.LiteralMap(this.span(n),e,t)},_ParseAST.prototype.parseAccessMemberOrMethodCall=function(e,t){void 0===t&&(t=!1);var n=e.span.start,r=this.expectIdentifierOrKeyword();if(this.optionalCharacter(i.$LPAREN)){this.rparensExpected++;var o=this.parseCallArguments();this.expectCharacter(i.$RPAREN),this.rparensExpected--;var s=this.span(n);return t?new a.SafeMethodCall(s,e,r,o):new a.MethodCall(s,e,r,o)}if(t)return this.optionalOperator(\"=\")?(this.error(\"The '?.' operator cannot be used in the assignment\"),new a.EmptyExpr(this.span(n))):new a.SafePropertyRead(this.span(n),e,r);if(this.optionalOperator(\"=\")){if(!this.parseAction)return this.error(\"Bindings cannot contain assignments\"),new a.EmptyExpr(this.span(n));var l=this.parseConditional();return new a.PropertyWrite(this.span(n),e,r,l)}return new a.PropertyRead(this.span(n),e,r)},_ParseAST.prototype.parseCallArguments=function(){if(this.next.isCharacter(i.$RPAREN))return[];var e=[];do e.push(this.parsePipe());while(this.optionalCharacter(i.$COMMA));return e},_ParseAST.prototype.expectTemplateBindingKey=function(){var e=\"\",t=!1;do e+=this.expectIdentifierOrKeywordOrString(),t=this.optionalOperator(\"-\"),t&&(e+=\"-\");while(t);return e.toString()},_ParseAST.prototype.parseTemplateBindings=function(){for(var e=[],t=null,n=[];this.index0&&e[e.length-1]===t}var r=this&&this.__extends||function(e,t){function __(){this.constructor=e}for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);e.prototype=null===t?Object.create(t):(__.prototype=t.prototype,new __)},i=n(10),o=n(5),s=n(60),a=n(85),l=n(68),c=n(546),u=n(102),p=function(e){function TreeError(t,n,r){e.call(this,n,r),this.elementName=t}return r(TreeError,e),TreeError.create=function(e,t,n){return new TreeError(e,t,n)},TreeError}(s.ParseError);t.TreeError=p;var d=function(){function ParseTreeResult(e,t){this.rootNodes=e,this.errors=t}return ParseTreeResult}();t.ParseTreeResult=d;var h=function(){function Parser(e){this._getTagDefinition=e}return Parser.prototype.parse=function(e,t,n,r){void 0===n&&(n=!1),void 0===r&&(r=l.DEFAULT_INTERPOLATION_CONFIG);var i=c.tokenize(e,t,this._getTagDefinition,n,r),o=new f(i.tokens,this._getTagDefinition).build();return new d(o.rootNodes,i.errors.concat(o.errors))},Parser}();t.Parser=h;var f=function(){function _TreeBuilder(e,t){this.tokens=e,this.getTagDefinition=t,this._index=-1,this._rootNodes=[],this._errors=[],this._elementStack=[],this._advance()}return _TreeBuilder.prototype.build=function(){for(;this._peek.type!==c.TokenType.EOF;)this._peek.type===c.TokenType.TAG_OPEN_START?this._consumeStartTag(this._advance()):this._peek.type===c.TokenType.TAG_CLOSE?this._consumeEndTag(this._advance()):this._peek.type===c.TokenType.CDATA_START?(this._closeVoidElement(),this._consumeCdata(this._advance())):this._peek.type===c.TokenType.COMMENT_START?(this._closeVoidElement(),this._consumeComment(this._advance())):this._peek.type===c.TokenType.TEXT||this._peek.type===c.TokenType.RAW_TEXT||this._peek.type===c.TokenType.ESCAPABLE_RAW_TEXT?(this._closeVoidElement(),this._consumeText(this._advance())):this._peek.type===c.TokenType.EXPANSION_FORM_START?this._consumeExpansion(this._advance()):this._advance();return new d(this._rootNodes,this._errors)},_TreeBuilder.prototype._advance=function(){var e=this._peek;return this._index0)return this._errors=this._errors.concat(i.errors),null;var l=new s.ParseSourceSpan(e.sourceSpan.start,r.sourceSpan.end),u=new s.ParseSourceSpan(t.sourceSpan.start,r.sourceSpan.end);return new a.ExpansionCase(e.parts[0],i.rootNodes,l,e.sourceSpan,u)},_TreeBuilder.prototype._collectExpansionExpTokens=function(e){for(var t=[],n=[c.TokenType.EXPANSION_CASE_EXP_START];;){if(this._peek.type!==c.TokenType.EXPANSION_FORM_START&&this._peek.type!==c.TokenType.EXPANSION_CASE_EXP_START||n.push(this._peek.type),this._peek.type===c.TokenType.EXPANSION_CASE_EXP_END){if(!lastOnStack(n,c.TokenType.EXPANSION_CASE_EXP_START))return this._errors.push(p.create(null,e.sourceSpan,\"Invalid ICU message. Missing '}'.\")),null;if(n.pop(),0==n.length)return t}if(this._peek.type===c.TokenType.EXPANSION_FORM_END){if(!lastOnStack(n,c.TokenType.EXPANSION_FORM_START))return this._errors.push(p.create(null,e.sourceSpan,\"Invalid ICU message. Missing '}'.\")),null;n.pop()}if(this._peek.type===c.TokenType.EOF)return this._errors.push(p.create(null,e.sourceSpan,\"Invalid ICU message. Missing '}'.\")),null;t.push(this._advance())}},_TreeBuilder.prototype._consumeText=function(e){var t=e.parts[0];if(t.length>0&&\"\\n\"==t[0]){var n=this._getParentElement();o.isPresent(n)&&0==n.children.length&&this.getTagDefinition(n.name).ignoreFirstLf&&(t=t.substring(1))}t.length>0&&this._addToParent(new a.Text(t,e.sourceSpan))},_TreeBuilder.prototype._closeVoidElement=function(){if(this._elementStack.length>0){var e=i.ListWrapper.last(this._elementStack);this.getTagDefinition(e.name).isVoid&&this._elementStack.pop()}},_TreeBuilder.prototype._consumeStartTag=function(e){for(var t=e.parts[0],n=e.parts[1],r=[];this._peek.type===c.TokenType.ATTR_NAME;)r.push(this._consumeAttr(this._advance()));var i=this._getElementFullName(t,n,this._getParentElement()),o=!1;if(this._peek.type===c.TokenType.TAG_OPEN_END_VOID){this._advance(),o=!0;var l=this.getTagDefinition(i);l.canSelfClose||null!==u.getNsPrefix(i)||l.isVoid||this._errors.push(p.create(i,e.sourceSpan,'Only void and foreign elements can be self closed \"'+e.parts[1]+'\"'))}else this._peek.type===c.TokenType.TAG_OPEN_END&&(this._advance(),o=!1);var d=this._peek.sourceSpan.start,h=new s.ParseSourceSpan(e.sourceSpan.start,d),f=new a.Element(i,r,[],h,h,null);this._pushElement(f),o&&(this._popElement(i),f.endSourceSpan=h)},_TreeBuilder.prototype._pushElement=function(e){if(this._elementStack.length>0){var t=i.ListWrapper.last(this._elementStack);this.getTagDefinition(t.name).isClosedByChild(e.name)&&this._elementStack.pop()}var n=this.getTagDefinition(e.name),r=this._getParentElementSkippingContainers(),s=r.parent,l=r.container;if(o.isPresent(s)&&n.requireExtraParent(s.name)){var c=new a.Element(n.parentToAdd,[],[],e.sourceSpan,e.startSourceSpan,e.endSourceSpan);this._insertBeforeContainer(s,l,c)}this._addToParent(e),this._elementStack.push(e)},_TreeBuilder.prototype._consumeEndTag=function(e){var t=this._getElementFullName(e.parts[0],e.parts[1],this._getParentElement());this._getParentElement()&&(this._getParentElement().endSourceSpan=e.sourceSpan),this.getTagDefinition(t).isVoid?this._errors.push(p.create(t,e.sourceSpan,'Void elements do not have end tags \"'+e.parts[1]+'\"')):this._popElement(t)||this._errors.push(p.create(t,e.sourceSpan,'Unexpected closing tag \"'+e.parts[1]+'\"'))},_TreeBuilder.prototype._popElement=function(e){for(var t=this._elementStack.length-1;t>=0;t--){var n=this._elementStack[t];if(n.name==e)return i.ListWrapper.splice(this._elementStack,t,this._elementStack.length-t),!0;if(!this.getTagDefinition(n.name).closedByParent)return!1}return!1},_TreeBuilder.prototype._consumeAttr=function(e){var t=u.mergeNsAndName(e.parts[0],e.parts[1]),n=e.sourceSpan.end,r=\"\";if(this._peek.type===c.TokenType.ATTR_VALUE){var i=this._advance();r=i.parts[0],n=i.sourceSpan.end}return new a.Attribute(t,r,new s.ParseSourceSpan(e.sourceSpan.start,n))},_TreeBuilder.prototype._getParentElement=function(){return this._elementStack.length>0?i.ListWrapper.last(this._elementStack):null},_TreeBuilder.prototype._getParentElementSkippingContainers=function(){for(var e=null,t=this._elementStack.length-1;t>=0;t--){if(\"ng-container\"!==this._elementStack[t].name)return{parent:this._elementStack[t],container:e};e=this._elementStack[t]}return{parent:i.ListWrapper.last(this._elementStack),container:e}},_TreeBuilder.prototype._addToParent=function(e){var t=this._getParentElement();o.isPresent(t)?t.children.push(e):this._rootNodes.push(e)},_TreeBuilder.prototype._insertBeforeContainer=function(e,t,n){if(t){if(e){var r=e.children.indexOf(t);e.children[r]=n}else this._rootNodes.push(n);n.children.push(t),this._elementStack.splice(this._elementStack.indexOf(t),0,n)}else this._addToParent(n),this._elementStack.push(n)},_TreeBuilder.prototype._getElementFullName=function(e,t,n){return o.isBlank(e)&&(e=this.getTagDefinition(t).implicitNamespacePrefix,o.isBlank(e)&&o.isPresent(n)&&(e=u.getNsPrefix(n.name))),u.mergeNsAndName(e,t)},_TreeBuilder}()},function(e,t,n){\"use strict\";function splitClasses(e){return e.trim().split(/\\s+/g)}function createElementCssSelector(e,t){var n=new w.CssSelector,r=y.splitNsName(e)[1];n.setElement(r);for(var i=0;i0&&this._console.warn(\"Template parse warnings:\\n\"+a.join(\"\\n\")),l.length>0){var c=l.join(\"\\n\");throw new u.BaseException(\"Template parse errors:\\n\"+c)}return s.templateAst},TemplateParser.prototype.tryParse=function(e,t,n,r,i,o){var a;e.template&&(a=g.InterpolationConfig.fromArray(e.template.interpolation));var l,c=this._htmlParser.parse(t,o,!0,a),u=c.errors;if(0==u.length){var d=m.expandNodes(c.rootNodes);u.push.apply(u,d.errors),c=new f.ParseTreeResult(d.nodes,u)}if(c.rootNodes.length>0){var y=s.removeIdentifierDuplicates(n),v=s.removeIdentifierDuplicates(r),_=new b.ProviderViewContext(e,c.rootNodes[0].sourceSpan),w=new j(_,y,v,i,this._exprParser,this._schemaRegistry);l=h.visitAll(w,c.rootNodes,z),u.push.apply(u,w.errors.concat(_.errors))}else l=[];return this._assertNoReferenceDuplicationOnTemplate(l,u),u.length>0?new L(l,u):(p.isPresent(this.transforms)&&this.transforms.forEach(function(e){l=E.templateVisitAll(e,l)}),new L(l,u))},TemplateParser.prototype._assertNoReferenceDuplicationOnTemplate=function(e,t){var n=[];e.filter(function(e){return!!e.references}).forEach(function(e){return e.references.forEach(function(e){var r=e.name;if(n.indexOf(r)<0)n.push(r);else{var i=new V('Reference \"#'+r+'\" is defined several times',e.sourceSpan,v.ParseErrorLevel.FATAL);t.push(i)}})})},TemplateParser.decorators=[{type:i.Injectable}],TemplateParser.ctorParameters=[{type:l.Parser},{type:_.ElementSchemaRegistry},{type:f.HtmlParser},{type:o.Console},{type:Array,decorators:[{type:i.Optional},{type:i.Inject,args:[t.TEMPLATE_TRANSFORMS]}]}],TemplateParser}();t.TemplateParser=F;var j=function(){function TemplateParseVisitor(e,t,n,r,i,o){var s=this;this.providerViewContext=e,this._schemas=r,this._exprParser=i,this._schemaRegistry=o,this.errors=[],this.directivesIndex=new Map,this.ngContentCount=0,this.selectorMatcher=new w.SelectorMatcher;var a=e.component.template;p.isPresent(a)&&p.isPresent(a.interpolation)&&(this._interpolationConfig={start:a.interpolation[0],end:a.interpolation[1]}),c.ListWrapper.forEachWithIndex(t,function(e,t){var n=w.CssSelector.parse(e.selector);s.selectorMatcher.addSelectables(n,e),s.directivesIndex.set(e,t)}),this.pipesByName=new Map,n.forEach(function(e){return s.pipesByName.set(e.name,e)})}return TemplateParseVisitor.prototype._reportError=function(e,t,n){void 0===n&&(n=v.ParseErrorLevel.FATAL),this.errors.push(new V(e,t,n))},TemplateParseVisitor.prototype._reportParserErors=function(e,t){for(var n=0,r=e;no.MAX_INTERPOLATION_VALUES)throw new u.BaseException(\"Only support at most \"+o.MAX_INTERPOLATION_VALUES+\" interpolation values!\");return r}catch(i){return this._reportError(\"\"+i,t),this._exprParser.wrapLiteralPrimitive(\"ERROR\",n)}},TemplateParseVisitor.prototype._parseAction=function(e,t){var n=t.start.toString();try{var r=this._exprParser.parseAction(e,n,this._interpolationConfig);return r&&this._reportParserErors(r.errors,t),!r||r.ast instanceof a.EmptyExpr?(this._reportError(\"Empty expressions are not allowed\",t),this._exprParser.wrapLiteralPrimitive(\"ERROR\",n)):(this._checkPipes(r,t),r)}catch(i){return this._reportError(\"\"+i,t),this._exprParser.wrapLiteralPrimitive(\"ERROR\",n)}},TemplateParseVisitor.prototype._parseBinding=function(e,t){var n=t.start.toString();try{var r=this._exprParser.parseBinding(e,n,this._interpolationConfig);return r&&this._reportParserErors(r.errors,t),this._checkPipes(r,t),r}catch(i){return this._reportError(\"\"+i,t),this._exprParser.wrapLiteralPrimitive(\"ERROR\",n)}},TemplateParseVisitor.prototype._parseTemplateBindings=function(e,t){var n=this,r=t.start.toString();try{var i=this._exprParser.parseTemplateBindings(e,r);return this._reportParserErors(i.errors,t),i.templateBindings.forEach(function(e){p.isPresent(e.expression)&&n._checkPipes(e.expression,t)}),i.warnings.forEach(function(e){n._reportError(e,t,v.ParseErrorLevel.WARNING)}),i.templateBindings}catch(o){return this._reportError(\"\"+o,t),[]}},TemplateParseVisitor.prototype._checkPipes=function(e,t){var n=this;if(p.isPresent(e)){var r=new q;e.visit(r),r.pipes.forEach(function(e){n.pipesByName.has(e)||n._reportError(\"The pipe '\"+e+\"' could not be found\",t)})}},TemplateParseVisitor.prototype.visitExpansion=function(e,t){return null},TemplateParseVisitor.prototype.visitExpansionCase=function(e,t){return null},TemplateParseVisitor.prototype.visitText=function(e,t){var n=t.findNgContentIndex(N),r=this._parseInterpolation(e.value,e.sourceSpan);return p.isPresent(r)?new E.BoundTextAst(r,n,e.sourceSpan):new E.TextAst(e.value,n,e.sourceSpan)},TemplateParseVisitor.prototype.visitAttribute=function(e,t){return new E.AttrAst(e.name,e.value,e.sourceSpan)},TemplateParseVisitor.prototype.visitComment=function(e,t){return null},TemplateParseVisitor.prototype.visitElement=function(e,t){var n=this,r=e.name,i=R.preparseElement(e);if(i.type===R.PreparsedElementType.SCRIPT||i.type===R.PreparsedElementType.STYLE)return null;if(i.type===R.PreparsedElementType.STYLESHEET&&S.isStyleUrlResolvable(i.hrefAttr))return null;var o=[],s=[],a=[],l=[],c=[],u=[],d=[],f=[],m=[],g=!1,v=[],_=y.splitNsName(r.toLowerCase())[1],C=_==P;e.attrs.forEach(function(e){var t=n._parseAttr(C,e,o,s,c,u,a,l),r=n._parseInlineTemplateBinding(e,f,d,m);r&&g&&n._reportError(\"Can't have multiple template bindings on one element. Use only one attribute named 'template' or prefixed with *\",e.sourceSpan),t||r||(v.push(n.visitAttribute(e,null)),o.push([e.name,e.value])),r&&(g=!0)});var T=createElementCssSelector(r,o),x=this._parseDirectives(this.selectorMatcher,T),M=[],k=this._createDirectiveAsts(C,e.name,x,s,a,e.sourceSpan,M),I=this._createElementPropertyAsts(e.name,s,k).concat(c),A=t.isTemplateElement||g,O=new b.ProviderElementContext(this.providerViewContext,t.providerContext,A,k,v,M,e.sourceSpan),D=h.visitAll(i.nonBindable?G:this,e.children,U.create(C,k,C?t.providerContext:O));O.afterElement();var N,V=p.isPresent(i.projectAs)?w.CssSelector.parse(i.projectAs)[0]:T,L=t.findNgContentIndex(V);if(i.type===R.PreparsedElementType.NG_CONTENT)p.isPresent(e.children)&&e.children.length>0&&this._reportError(\" element cannot have content. must be immediately followed by \",e.sourceSpan),N=new E.NgContentAst((this.ngContentCount++),g?null:L,e.sourceSpan);else if(C)this._assertAllEventsPublishedByDirectives(k,u),this._assertNoComponentsNorElementBindingsOnTemplate(k,I,e.sourceSpan),N=new E.EmbeddedTemplateAst(v,u,M,l,O.transformedDirectiveAsts,O.transformProviders,O.transformedHasViewContainer,D,g?null:L,e.sourceSpan);else{this._assertOnlyOneComponent(k,e.sourceSpan);var F=g?null:t.findNgContentIndex(V);N=new E.ElementAst(r,v,I,u,M,O.transformedDirectiveAsts,O.transformProviders,O.transformedHasViewContainer,D,g?null:F,e.sourceSpan)}if(g){var j=createElementCssSelector(P,f),B=this._parseDirectives(this.selectorMatcher,j),W=this._createDirectiveAsts(!0,e.name,B,d,[],e.sourceSpan,[]),H=this._createElementPropertyAsts(e.name,d,W);this._assertNoComponentsNorElementBindingsOnTemplate(W,H,e.sourceSpan);var z=new b.ProviderElementContext(this.providerViewContext,t.providerContext,t.isTemplateElement,W,[],[],e.sourceSpan);z.afterElement(),N=new E.EmbeddedTemplateAst([],[],[],m,z.transformedDirectiveAsts,z.transformProviders,z.transformedHasViewContainer,[N],L,e.sourceSpan)}return N},TemplateParseVisitor.prototype._parseInlineTemplateBinding=function(e,t,n,r){var i=null;if(this._normalizeAttributeName(e.name)==x)i=e.value;else if(e.name.startsWith(M)){var o=e.name.substring(M.length);i=0==e.value.length?o:o+\" \"+e.value}if(p.isPresent(i)){for(var s=this._parseTemplateBindings(i,e.sourceSpan),a=0;a elements is deprecated. Use \"let-\" instead!',t.sourceSpan,v.ParseErrorLevel.WARNING),this._parseVariable(h,c,t.sourceSpan,a)):(this._reportError('\"var-\" on non