#! /bin/sh set -e print_help() { cat <<-END Usage: $0 [subcommand] [option(s)] Commands: build Build the project help Show this help screen and exit install Perform installation steps process-blocks Process blocks run-tests Runs tests serve Start server install-app Installs Balance Tracker in HAF Install subcommands: jmeter Installs Apache Jmeter postgrest Installs PostgREST backend-runtime-dependencies Installs backend runtime dependencies frontend-runtime-dependencies Installs frontend runtime dependencies test-dependencies Installs test dependencies Serve subcommands: frontend Start frontend server postgrest-backend Start PostgREST backend server test-results Serve test results generated by run-tests command Balance Tracker installation (install-app) options: --postgres-host=HOSTNAME PostgreSQL hostname (default: localhost) --postgres-port=PORT PostgreSQL port (default: 5432) --postgres-user=USERNAME PostgreSQL user name (default: haf_admin) --postgres-url=URL PostgreSQL URL (if set, overrides three previous options, empty by default) --no-context=true|false When set to true, do not create context (default: false) --no-context The same as '--no-context=true' Block processing (process-blocks) options: --number-of-blocks=INTEGER Number of blocks to process (default: 10^9), if set to value greater than number of blocks in the database (or 0), indexer will wait for new blocks --postgres-host=HOSTNAME PostgreSQL hostname (default: localhost) --postgres-port=PORT PostgreSQL port (default: 5432) --postgres-user=USERNAME PostgreSQL user name (default: btracker_owner) --postgres-url=URL PostgreSQL URL (if set, overrides three previous options, empty by default) --log-dir=DIR-PATH Directory for block procesing logs (default: unset), setting this parameter will cause the block processing to run in the background, logs will be rotated once they reach 5M size Test running options: --test-report-dir=PATH Directory where HTML test report will be generated --test-result-path=PATH File where JTL test result will be generated --test-thread-count=NUMBER Number of threads to be used to run tests (default: 8) --test-loop-count=NUMBER Number of loops to be run during tests (default: 60) --backend-port=PORT Port used by the backend (default: 3000) --backend-host=HOSTNAME Hostname of backend's host (default: localhost) Serving options: --frontend-port=PORT Frontend port (default: 4000) --log-dir=PATH Log directory for frontend and/or backend logs --postgres-host=HOSTNAME PostgreSQL hostname (default: localhost) --postgres-port=PORT PostgreSQL port (default: 5432) --postgres-user=USERNAME PostgreSQL user name (default: btracker_user) --postgres-url=URL PostgreSQL URL (if set, overrides three previous options, empty by default) --postgrest-host=HOST PostgREST bind address (default: !4) See https://postgrest.org/en/stable/references/configuration.html#server-host for possible values --postgrest-port=PORT PostgREST bind port (default: 3000) --postgrest-admin-server-port=PORT PostgREST admin port (default: unset, health checks not available) See https://postgrest.org/en/stable/references/admin.html#health-check for details --test-server-port=PORT Port on which the test report is served --test-report-dir=PATH Directory where HTML test report is located END } build() { subcommand=$1 shift case "$subcommand" in frontend) echo "Building frontend" cd gui export NODE_ENV=production npm install npm run build npx react-inject-env set cd .. echo "Finished building frontend" ;; *) echo "Unknown subcommand: $subcommand" print_help exit 1 esac } install_jmeter() { version="5.6.2" bin_path="/usr/local/bin/jmeter" src_path="/usr/local/src/jmeter-$version" echo "Installing Jmeter $version to $bin_path..." wget "https://downloads.apache.org/jmeter/binaries/apache-jmeter-${version}.zip" -O jmeter.zip unzip "jmeter.zip" rm "jmeter.zip" sudo mv "apache-jmeter-${version}" "$src_path" jmeter="$bin_path-$version" cat <<-_jmeter | sudo tee "$jmeter" #!/usr/bin/env bash cd "$src_path/bin" ./jmeter.sh "\$@" _jmeter sudo chmod +x "$jmeter" sudo ln -sf "$jmeter" "$bin_path" echo "Finished installing Jmeter" } install_postgrest() { version="v11.1.0" path="/usr/local/bin/postgrest" echo "Installing PostgREST $version to $path..." wget https://github.com/PostgREST/postgrest/releases/download/$version/postgrest-$version-linux-static-x64.tar.xz -O postgrest.tar.xz tar -xJf postgrest.tar.xz sudo mv postgrest "$path" rm postgrest.tar.xz echo "Finished installing PostgrREST" } install_backend_runtime_dependencies() { echo "Installing backend runtime dependencies..." sudo apt-get update sudo apt-get -y install \ apache2-utils \ curl \ postgresql-client \ wget \ xz-utils echo "Finished installing backend runtime dependencies" } install_frontend_runtime_dependencies() { echo "Installing frontend runtime dependencies..." sudo apt-get update sudo apt-get -y install curl curl https://get.volta.sh | bash export VOLTA_HOME="$HOME/.volta" export PATH="$VOLTA_HOME/bin:$PATH" cd gui npm install cd .. echo "Finished installing frontend runtime dependencies" } install_test_dependencies() { echo "Installing test dependencies..." sudo apt-get update sudo apt-get -y install \ openjdk-8-jdk-headless \ python3 \ unzip echo "Finished installing test dependencies" } install() { subcommand=$1 shift case "$subcommand" in jmeter) install_jmeter ;; postgrest) install_postgrest ;; backend-runtime-dependencies) install_backend_runtime_dependencies ;; frontend-runtime-dependencies) install_frontend_runtime_dependencies ;; test-dependencies) install_test_dependencies ;; *) echo "Unknown subcommand: $subcommand" print_help exit 1 esac } process_blocks() { echo "Running indexer..." echo "Arguments: $*" block_number=${BLOCK_NUMBER:-null} postgres_user=${POSTGRES_USER:-"btracker_owner"} postgres_host=${POSTGRES_HOST:-"localhost"} postgres_port=${POSTGRES_PORT:-5432} postgres_url=${POSTGRES_URL:-""} btracker_schema=${BTRACKER_SCHEMA:-"btracker_app"} log_dir=${LOG_DIR:-} while [ $# -gt 0 ]; do case "$1" in --number-of-blocks=*) block_number="${1#*=}" ;; --postgres-host=*) postgres_host="${1#*=}" ;; --postgres-port=*) postgres_port="${1#*=}" ;; --postgres-user=*) postgres_user="${1#*=}" ;; --postgres-url=*) postgres_url="${1#*=}" ;; --schema=*) btracker_schema="${1#*=}" ;; --log-dir=*) log_dir="${1#*=}" ;; -*) echo "Unknown option: $1" print_help exit 1 ;; *) echo "Unknown argument: $1" print_help exit 2 ;; esac shift done if [ -z "$block_number" ]; then block_number=1000000000 echo 'Running indexer for existing blocks and expecting new blocks...' fi postgres_access=${postgres_url:-"postgresql://$postgres_user@$postgres_host:$postgres_port/haf_block_log?application_name=btracker_block_processing"} if [ -z "$log_dir" ]; then echo "Running indexer in the foreground" psql -a -v "ON_ERROR_STOP=1" "$postgres_access" -c "SET SEARCH_PATH TO ${btracker_schema};" -c "call ${btracker_schema}.main('${btracker_schema}', $block_number);" echo "Finished running indexer" else echo "Running indexer in the background" mkdir -p "$log_dir" psql -a -v "ON_ERROR_STOP=1" "$postgres_access" -c "SET SEARCH_PATH TO ${btracker_schema};" -c "call ${btracker_schema}.main('${btracker_schema}', $block_number);" 2>&1 | /usr/bin/rotatelogs "$log_dir/process-blocks.%Y-%m-%d-%H_%M_%S.log" 5M & fi } run_tests() { test_scenario_path="$(pwd)/tests/performance/test_scenarios.jmx" test_result_path=${TEST_RESULT_PATH:-"$(pwd)/tests/performance/result.jtl"} test_report_dir=${TEST_REPORT_DIR:-"$(pwd)/tests/performance/result_report"} test_thread_count=${TEST_THREAD_COUNT:-8} test_loop_count=${TEST_LOOP_COUNT:-60} backend_port=${BACKEND_PORT:-3000} backend_host=${BACKEND_HOST:-localhost} postgres_user=${POSTGRES_USER:-"btracker_owner"} postgres_host=${POSTGRES_HOST:-"localhost"} postgres_port=${POSTGRES_PORT:-5432} postgres_url=${POSTGRES_URL:-""} btracker_schema=${BTRACKER_SCHEMA:-"btracker_app"} while [ $# -gt 0 ]; do case "$1" in --test-report-dir=*) test_report_dir="${1#*=}" ;; --test-result-path=*) test_result_path="${1#*=}" ;; --test-thread-count=*) test_thread_count="${1#*=}" ;; --test-loop-count=*) test_loop_count="${1#*=}" ;; --postgres-host=*) postgres_host="${1#*=}" ;; --postgres-port=*) postgres_port="${1#*=}" ;; --postgres-user=*) postgres_user="${1#*=}" ;; --postgres-url=*) postgres_url="${1#*=}" ;; --schema=*) btracker_schema="${1#*=}" ;; --backend-port=*) backend_port="${1#*=}" ;; --backend-host=*) backend_host="${1#*=}" ;; -*) echo "Unknown option: $1" print_help exit 1 ;; *) echo "Unknown argument: $1" print_help exit 2 ;; esac shift done postgres_access=${postgres_url:-"postgresql://$postgres_user@$postgres_host:$postgres_port/haf_block_log"} psql -a -v "ON_ERROR_STOP=1" "$postgres_access" -c "SET SEARCH_PATH TO ${btracker_schema};" -c "SELECT ${btracker_schema}.create_btracker_indexes();" test_summary_report_path="${test_result_path%jtl}xml" rm -f "$test_result_path" mkdir -p "${test_result_path%/*}" rm -rf "$test_report_dir" mkdir -p "$test_report_dir" jmeter --nongui --testfile "$test_scenario_path" --logfile "$test_result_path" \ --reportatendofloadtests --reportoutputfolder "$test_report_dir" \ --jmeterproperty backend.port="$backend_port" --jmeterproperty backend.host="$backend_host" \ --jmeterproperty thread.count="$test_thread_count" --jmeterproperty loop.count="$test_loop_count" \ --jmeterproperty summary.report.path="$test_summary_report_path" } start_frontend() { echo "Starting frontend..." echo "Arguments: $*" frontend_port=${FRONTEND_PORT:-} log_dir=${LOG_DIR:-} while [ $# -gt 0 ]; do case "$1" in --frontend-port=*) frontend_port="${1#*=}" ;; --log-dir=*) log_dir="${1#*=}" ;; -*) echo "Unknown option: $1" print_help exit 1 ;; *) echo "Unknown argument: $1" print_help exit 2 ;; esac shift done [ -n "$frontend_port" ] && export PORT="$frontend_port" if [ -z "$log_dir" ]; then echo "Running frontend in the foreground" cd gui npm run start cd .. echo "Finished running frontend" else echo "Running frontend in the background" mkdir -p "$log_dir" cd gui npm run start 2>&1 | /usr/bin/rotatelogs "$log_dir/frontend.%Y-%m-%d-%H_%M_%S.log" 5M & cd .. fi } start_postgrest() { echo "Starting PostgREST..." echo "Arguments: $*" postgres_user=${POSTGRES_USER:-"btracker_user"} postgres_host=${POSTGRES_HOST:-"localhost"} postgres_port=${POSTGRES_PORT:-5432} postgres_url=${POSTGRES_URL:-""} PGRST_SERVER_HOST=${PGRST_SERVER_HOST:-"!4"} PGRST_SERVER_PORT=${PGRST_SERVER_PORT:-3000} PGRST_ADMIN_SERVER_PORT=${PGRST_ADMIN_SERVER_PORT:-} log_dir=${LOG_DIR:-} while [ $# -gt 0 ]; do case "$1" in --postgres-host=*) postgres_host="${1#*=}" ;; --postgres-port=*) postgres_port="${1#*=}" ;; --postgres-user=*) postgres_user="${1#*=}" ;; --postgres-url=*) postgres_url="${1#*=}" ;; --postgrest-host=*) PGRST_SERVER_HOST="${1#*=}" ;; --postgrest-port=*) PGRST_SERVER_PORT="${1#*=}" ;; --postgrest-admin-server-port=*) PGRST_ADMIN_SERVER_PORT="${1#*=}" ;; --log-dir=*) log_dir="${1#*=}" ;; -*) echo "Unknown option: $1" print_help exit 1 ;; *) echo "Unknown argument: $1" print_help exit 2 ;; esac shift done export PGRST_DB_URI="${postgres_url:-postgresql://$postgres_user@$postgres_host:$postgres_port/haf_block_log}" export PGRST_SERVER_HOST export PGRST_SERVER_PORT export PGRST_ADMIN_SERVER_PORT if [ -z "$log_dir" ]; then echo "Running PostgREST in the foreground" postgrest postgrest.conf echo "Finished running PostgREST" else echo "Running PostgREST in the background" mkdir -p "$log_dir" postgrest postgrest.conf 2>&1 | /usr/bin/rotatelogs "$log_dir/balance-tracker.%Y-%m-%d-%H_%M_%S.log" 5M & fi } serve_test_results() { echo "Starting test result server..." echo "Arguments: $*" port=${TEST_SERVER_PORT:-8000} test_report_dir=${TEST_REPORT_DIR:-"$(pwd)/tests/performance/result_report"} while [ $# -gt 0 ]; do case "$1" in --test-report-dir=*) test_report_dir="${1#*=}" ;; --test-server-port=*) port="${1#*=}" ;; -*) echo "Unknown option: $1" print_help exit 1 ;; *) echo "Unknown argument: $1" print_help exit 2 ;; esac shift done python3 -m http.server --directory "$test_report_dir" "$port" } serve() { echo "Starting server..." echo "Arguments: $*" subcommand=$1 shift case "$subcommand" in frontend) start_frontend "$@" ;; postgrest-backend) start_postgrest "$@" ;; test-results) serve_test_results "$@" ;; *) echo "Unknown subcommand: $subcommand" print_help exit 1 esac echo "Done" } install_app() { echo "Installing Balance Tracker in HAF..." echo "Arguments: $*" ./scripts/install_app.sh "$@" echo "Finished installing Balance Tracker in HAF" } command=$1 shift case "$command" in build) build "$@" ;; install) install "$@" ;; process-blocks) process_blocks "$@" ;; run-tests) run_tests "$@" ;; serve) serve "$@" ;; install-app) install_app "$@" ;; help | --help | -?) print_help exit 0 ;; *) echo "Unknown command: $command" print_help exit 1 ;; esac