| 
									
										
										
										
											2018-11-11 08:19:04 -08:00
										 |  |  | #!/usr/bin/env bash
 | 
					
						
							|  |  |  | set -e | 
					
						
							| 
									
										
										
										
											2018-08-28 10:19:33 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | here=$(dirname "$0") | 
					
						
							|  |  |  | SOLANA_ROOT="$(cd "$here"/..; pwd)" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # shellcheck source=net/common.sh | 
					
						
							|  |  |  | source "$here"/common.sh | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | usage() { | 
					
						
							|  |  |  |   exitcode=0 | 
					
						
							|  |  |  |   if [[ -n "$1" ]]; then | 
					
						
							|  |  |  |     exitcode=1 | 
					
						
							|  |  |  |     echo "Error: $*" | 
					
						
							|  |  |  |   fi | 
					
						
							| 
									
										
										
										
											2020-03-06 15:32:27 -08:00
										 |  |  |   CLIENT_OPTIONS=$(cat << EOM | 
					
						
							|  |  |  | -c clientType=numClients=extraArgs - Number of clientTypes to start.  This options can be specified | 
					
						
							|  |  |  |                                      more than once.  Defaults to bench-tps for all clients if not | 
					
						
							|  |  |  |                                      specified. | 
					
						
							|  |  |  |                                      Valid client types are: | 
					
						
							|  |  |  |                                          idle | 
					
						
							|  |  |  |                                          bench-tps | 
					
						
							|  |  |  |                                          bench-exchange | 
					
						
							|  |  |  |                                      User can optionally provide extraArgs that are transparently | 
					
						
							|  |  |  |                                      supplied to the client program as command line parameters. | 
					
						
							|  |  |  |                                      For example, | 
					
						
							|  |  |  |                                          -c bench-tps=2="--tx_count 25000" | 
					
						
							|  |  |  |                                      This will start 2 bench-tps clients, and supply "--tx_count 25000" | 
					
						
							|  |  |  |                                      to the bench-tps client. | 
					
						
							|  |  |  | EOM | 
					
						
							|  |  |  | ) | 
					
						
							| 
									
										
										
										
											2018-08-28 10:19:33 -07:00
										 |  |  |   cat <<EOF | 
					
						
							| 
									
										
										
										
											2018-09-04 15:16:25 -07:00
										 |  |  | usage: $0 [start|stop|restart|sanity] [command-specific options] | 
					
						
							| 
									
										
										
										
											2018-08-28 10:19:33 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-03 18:15:55 -10:00
										 |  |  | Operate a configured testnet | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-06 15:32:27 -08:00
										 |  |  |  start        - Start the network | 
					
						
							|  |  |  |  sanity       - Sanity check the network | 
					
						
							|  |  |  |  stop         - Stop the network | 
					
						
							|  |  |  |  restart      - Shortcut for stop then start | 
					
						
							|  |  |  |  logs         - Fetch remote logs from each network node | 
					
						
							|  |  |  |  startnode    - Start an individual node (previously stopped with stopNode) | 
					
						
							|  |  |  |  stopnode     - Stop an individual node | 
					
						
							|  |  |  |  startclients - Start client nodes only | 
					
						
							|  |  |  |  update       - Deploy a new software update to the cluster | 
					
						
							| 
									
										
										
										
											2020-06-01 14:00:35 -06:00
										 |  |  |  upgrade      - Upgrade software on bootstrap validator. (Restart bootstrap validator manually to run it) | 
					
						
							| 
									
										
										
										
											2018-09-03 18:15:55 -10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-19 08:31:22 -07:00
										 |  |  |  start-specific options: | 
					
						
							| 
									
										
										
										
											2019-04-24 11:11:30 -07:00
										 |  |  |    -T [tarFilename]                   - Deploy the specified release tarball | 
					
						
							|  |  |  |    -t edge|beta|stable|vX.Y.Z         - Deploy the latest tarball release for the | 
					
						
							|  |  |  |                                         specified release channel (edge|beta|stable) or release tag | 
					
						
							|  |  |  |                                         (vX.Y.Z) | 
					
						
							| 
									
										
										
										
											2019-09-19 08:31:22 -07:00
										 |  |  |    -r / --skip-setup                  - Reuse existing node/ledger configuration from a | 
					
						
							| 
									
										
										
										
											2019-04-24 11:11:30 -07:00
										 |  |  |                                         previous |start| (ie, don't run ./multinode-demo/setup.sh). | 
					
						
							| 
									
										
										
										
											2019-08-23 19:31:18 -06:00
										 |  |  |    -d / --debug                       - Build/deploy the testnet with debug binaries | 
					
						
							| 
									
										
										
										
											2020-03-06 15:32:27 -08:00
										 |  |  |    $CLIENT_OPTIONS | 
					
						
							| 
									
										
										
										
											2019-12-05 21:03:26 -05:00
										 |  |  |    --client-delay-start | 
					
						
							|  |  |  |                                       - Number of seconds to wait after validators have finished starting before starting client programs | 
					
						
							|  |  |  |                                         (default: $clientDelayStart) | 
					
						
							| 
									
										
										
										
											2019-10-21 21:21:21 -06:00
										 |  |  |    -n NUM_VALIDATORS                  - Number of validators to apply command to. | 
					
						
							| 
									
										
										
										
											2019-10-14 10:33:32 -06:00
										 |  |  |    --gpu-mode GPU_MODE                - Specify GPU mode to launch validators with (default: $gpuMode). | 
					
						
							|  |  |  |                                         MODE must be one of | 
					
						
							|  |  |  |                                           on - GPU *required*, any vendor * | 
					
						
							|  |  |  |                                           off - No GPU, CPU-only | 
					
						
							|  |  |  |                                           auto - Use GPU if available, any vendor * | 
					
						
							|  |  |  |                                           cuda - GPU *required*, Nvidia CUDA only | 
					
						
							|  |  |  |                                           *  Currently, Nvidia CUDA is the only supported GPU vendor | 
					
						
							| 
									
										
										
										
											2019-05-18 14:01:36 -07:00
										 |  |  |    --hashes-per-tick NUM_HASHES|sleep|auto | 
					
						
							|  |  |  |                                       - Override the default --hashes-per-tick for the cluster | 
					
						
							| 
									
										
										
										
											2019-07-19 12:51:38 -06:00
										 |  |  |    --no-airdrop | 
					
						
							| 
									
										
										
										
											2020-05-19 20:07:30 -07:00
										 |  |  |                                       - If set, disables the faucet keypair.  Nodes must be funded in genesis config | 
					
						
							| 
									
										
										
										
											2019-11-19 10:22:30 -05:00
										 |  |  |    --faucet-lamports NUM_LAMPORTS_TO_MINT | 
					
						
							| 
									
										
										
										
											2019-10-29 20:03:48 -06:00
										 |  |  |                                       - Override the default 500000000000000000 lamports minted in genesis | 
					
						
							| 
									
										
										
										
											2019-07-19 12:51:38 -06:00
										 |  |  |    --internal-nodes-stake-lamports NUM_LAMPORTS_PER_NODE | 
					
						
							|  |  |  |                                       - Amount to stake internal nodes. | 
					
						
							|  |  |  |    --internal-nodes-lamports NUM_LAMPORTS_PER_NODE | 
					
						
							| 
									
										
										
										
											2019-11-08 23:56:57 -05:00
										 |  |  |                                       - Amount to fund internal nodes in genesis config. | 
					
						
							| 
									
										
										
										
											2019-07-09 14:39:55 -06:00
										 |  |  |    --external-accounts-file FILE_PATH | 
					
						
							| 
									
										
										
										
											2019-09-19 08:31:22 -07:00
										 |  |  |                                       - A YML file with a list of account pubkeys and corresponding lamport balances | 
					
						
							| 
									
										
										
										
											2019-11-08 23:56:57 -05:00
										 |  |  |                                         in genesis config for external nodes | 
					
						
							| 
									
										
										
										
											2019-08-14 19:25:22 -07:00
										 |  |  |    --no-snapshot-fetch | 
					
						
							| 
									
										
										
										
											2019-07-14 13:17:30 -06:00
										 |  |  |                                       - If set, disables booting validators from a snapshot | 
					
						
							| 
									
										
										
										
											2019-11-04 22:14:55 -07:00
										 |  |  |    --skip-poh-verify | 
					
						
							| 
									
										
										
										
											2019-07-17 19:26:23 -07:00
										 |  |  |                                       - If set, validators will skip verifying | 
					
						
							|  |  |  |                                         the ledger they already have saved to disk at | 
					
						
							|  |  |  |                                         boot (results in a much faster boot) | 
					
						
							| 
									
										
										
										
											2019-07-22 21:38:26 -07:00
										 |  |  |    --no-deploy | 
					
						
							|  |  |  |                                       - Don't deploy new software, use the | 
					
						
							|  |  |  |                                         existing deployment | 
					
						
							| 
									
										
										
										
											2019-09-09 16:40:12 -06:00
										 |  |  |    --no-build | 
					
						
							|  |  |  |                                       - Don't build new software, deploy the | 
					
						
							|  |  |  |                                         existing binaries | 
					
						
							| 
									
										
										
										
											2019-07-22 21:38:26 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-19 12:03:47 -07:00
										 |  |  |    --deploy-if-newer                  - Only deploy if newer software is | 
					
						
							|  |  |  |                                         available (requires -t or -T) | 
					
						
							| 
									
										
										
										
											2019-07-22 21:38:26 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-01 07:53:30 -07:00
										 |  |  |    --use-move                         - Build the move-loader-program and add it to the cluster | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-19 10:22:30 -05:00
										 |  |  |    --operating-mode development|softlaunch | 
					
						
							|  |  |  |                                       - Specify whether or not to launch the cluster in "development" mode with all features enabled at epoch 0, | 
					
						
							|  |  |  |                                         or "softlaunch" mode with some features disabled at epoch 0 (default: development) | 
					
						
							| 
									
										
										
										
											2019-09-19 08:31:22 -07:00
										 |  |  |  sanity/start-specific options: | 
					
						
							| 
									
										
										
										
											2019-04-29 21:38:03 -07:00
										 |  |  |    -F                   - Discard validator nodes that didn't bootup successfully | 
					
						
							| 
									
										
										
										
											2019-06-05 15:31:29 -07:00
										 |  |  |    -o noInstallCheck    - Skip solana-install sanity | 
					
						
							| 
									
										
										
										
											2018-09-11 20:00:49 -07:00
										 |  |  |    -o rejectExtraNodes  - Require the exact number of nodes | 
					
						
							| 
									
										
										
										
											2018-09-03 19:33:40 -10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-03 18:15:55 -10:00
										 |  |  |  stop-specific options: | 
					
						
							|  |  |  |    none | 
					
						
							| 
									
										
										
										
											2018-08-28 10:19:33 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-23 08:54:24 -08:00
										 |  |  |  logs-specific options: | 
					
						
							|  |  |  |    none | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-07 11:14:33 -08:00
										 |  |  |  netem-specific options: | 
					
						
							|  |  |  |    --config            - Netem configuration (as a double quoted string) | 
					
						
							|  |  |  |    --parition          - Percentage of network that should be configured with netem | 
					
						
							| 
									
										
										
										
											2019-11-15 12:10:48 -08:00
										 |  |  |    --config-file       - Configuration file for partition and netem configuration | 
					
						
							|  |  |  |    --netem-cmd         - Optional command argument to netem. Default is "add". Use "cleanup" to remove rules. | 
					
						
							| 
									
										
										
										
											2019-11-07 11:14:33 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-19 12:03:47 -07:00
										 |  |  |  update-specific options: | 
					
						
							|  |  |  |    --platform linux|osx|windows       - Deploy the tarball using 'solana-install deploy ...' for the | 
					
						
							|  |  |  |                                         given platform (multiple platforms may be specified) | 
					
						
							|  |  |  |                                         (-t option must be supplied as well) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-17 19:26:23 -07:00
										 |  |  |  startnode/stopnode-specific options: | 
					
						
							|  |  |  |    -i [ip address]                    - IP Address of the node to start or stop | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-06 15:32:27 -08:00
										 |  |  |  startclients-specific options: | 
					
						
							|  |  |  |    $CLIENT_OPTIONS | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-09 12:57:00 -07:00
										 |  |  | Note: if RUST_LOG is set in the environment it will be propogated into the | 
					
						
							|  |  |  |       network nodes. | 
					
						
							| 
									
										
										
										
											2018-08-28 10:19:33 -07:00
										 |  |  | EOF | 
					
						
							|  |  |  |   exit $exitcode | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-08 21:46:03 -07:00
										 |  |  | initLogDir() { # Initializes the netLogDir global variable.  Idempotent | 
					
						
							|  |  |  |   [[ -z $netLogDir ]] || return 0 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   netLogDir="$netDir"/log | 
					
						
							|  |  |  |   declare netLogDateDir | 
					
						
							|  |  |  |   netLogDateDir="$netDir"/log-$(date +"%Y-%m-%d_%H_%M_%S") | 
					
						
							|  |  |  |   if [[ -d $netLogDir && ! -L $netLogDir ]]; then | 
					
						
							|  |  |  |     echo "Warning: moving $netLogDir to make way for symlink." | 
					
						
							|  |  |  |     mv "$netLogDir" "$netDir"/log.old | 
					
						
							|  |  |  |   elif [[ -L $netLogDir ]]; then | 
					
						
							|  |  |  |     rm "$netLogDir" | 
					
						
							|  |  |  |   fi | 
					
						
							|  |  |  |   mkdir -p "$netConfigDir" "$netLogDateDir" | 
					
						
							|  |  |  |   ln -sf "$netLogDateDir" "$netLogDir" | 
					
						
							|  |  |  |   echo "Log directory: $netLogDateDir" | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-24 08:09:37 -07:00
										 |  |  | annotate() { | 
					
						
							| 
									
										
										
										
											2019-04-27 20:37:36 -07:00
										 |  |  |   [[ -z $BUILDKITE ]] || { | 
					
						
							| 
									
										
										
										
											2019-04-24 08:09:37 -07:00
										 |  |  |     buildkite-agent annotate "$@" | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | annotateBlockexplorerUrl() { | 
					
						
							|  |  |  |   declare blockstreamer=${blockstreamerIpList[0]} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if [[ -n $blockstreamer ]]; then | 
					
						
							|  |  |  |     annotate --style info --context blockexplorer-url "Block explorer: http://$blockstreamer/" | 
					
						
							|  |  |  |   fi | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-28 10:19:33 -07:00
										 |  |  | build() { | 
					
						
							| 
									
										
										
										
											2019-04-22 18:22:43 -07:00
										 |  |  |   supported=("18.04") | 
					
						
							| 
									
										
										
										
											2018-08-28 20:55:13 -07:00
										 |  |  |   declare MAYBE_DOCKER= | 
					
						
							| 
									
										
										
										
											2019-04-22 18:22:43 -07:00
										 |  |  |   if [[ $(uname) != Linux || ! " ${supported[*]} " =~ $(lsb_release -sr) ]]; then | 
					
						
							| 
									
										
										
										
											2019-04-19 09:56:01 -07:00
										 |  |  |     # shellcheck source=ci/rust-version.sh | 
					
						
							|  |  |  |     source "$SOLANA_ROOT"/ci/rust-version.sh | 
					
						
							| 
									
										
										
										
											2019-04-15 20:27:52 -07:00
										 |  |  |     MAYBE_DOCKER="ci/docker-run.sh $rust_stable_docker_image" | 
					
						
							| 
									
										
										
										
											2018-08-28 10:19:33 -07:00
										 |  |  |   fi | 
					
						
							|  |  |  |   SECONDS=0 | 
					
						
							|  |  |  |   ( | 
					
						
							|  |  |  |     cd "$SOLANA_ROOT" | 
					
						
							| 
									
										
										
										
											2018-09-04 09:21:03 -07:00
										 |  |  |     echo "--- Build started at $(date)" | 
					
						
							| 
									
										
										
										
											2018-08-28 10:19:33 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-28 20:55:13 -07:00
										 |  |  |     set -x | 
					
						
							|  |  |  |     rm -rf farf | 
					
						
							| 
									
										
										
										
											2018-11-14 19:19:27 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-13 23:46:21 -07:00
										 |  |  |     buildVariant= | 
					
						
							|  |  |  |     if $debugBuild; then | 
					
						
							|  |  |  |       buildVariant=debug | 
					
						
							|  |  |  |     fi | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-16 08:04:46 -08:00
										 |  |  |     $MAYBE_DOCKER bash -c "
 | 
					
						
							|  |  |  |       set -ex | 
					
						
							| 
									
										
										
										
											2019-11-01 07:53:30 -07:00
										 |  |  |       scripts/cargo-install-all.sh farf \"$buildVariant\" \"$maybeUseMove\" | 
					
						
							| 
									
										
										
										
											2018-11-16 08:04:46 -08:00
										 |  |  |     "
 | 
					
						
							| 
									
										
										
										
											2018-08-28 10:19:33 -07:00
										 |  |  |   ) | 
					
						
							|  |  |  |   echo "Build took $SECONDS seconds" | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-07 08:49:22 -07:00
										 |  |  | startCommon() { | 
					
						
							| 
									
										
										
										
											2018-08-28 10:19:33 -07:00
										 |  |  |   declare ipAddress=$1 | 
					
						
							| 
									
										
										
										
											2018-09-04 15:16:25 -07:00
										 |  |  |   test -d "$SOLANA_ROOT" | 
					
						
							| 
									
										
										
										
											2019-01-08 23:11:31 -07:00
										 |  |  |   if $skipSetup; then | 
					
						
							|  |  |  |     ssh "${sshOptions[@]}" "$ipAddress" "
 | 
					
						
							|  |  |  |       set -x; | 
					
						
							| 
									
										
										
										
											2019-09-19 08:31:22 -07:00
										 |  |  |       mkdir -p ~/solana/config; | 
					
						
							|  |  |  |       rm -rf ~/config; | 
					
						
							|  |  |  |       mv ~/solana/config ~; | 
					
						
							| 
									
										
										
										
											2019-01-08 23:11:31 -07:00
										 |  |  |       rm -rf ~/solana; | 
					
						
							|  |  |  |       mkdir -p ~/solana ~/.cargo/bin; | 
					
						
							| 
									
										
										
										
											2019-09-19 08:31:22 -07:00
										 |  |  |       mv ~/config ~/solana/ | 
					
						
							| 
									
										
										
										
											2019-01-08 23:11:31 -07:00
										 |  |  |     "
 | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     ssh "${sshOptions[@]}" "$ipAddress" "
 | 
					
						
							|  |  |  |       set -x; | 
					
						
							|  |  |  |       rm -rf ~/solana; | 
					
						
							|  |  |  |       mkdir -p ~/.cargo/bin | 
					
						
							|  |  |  |     "
 | 
					
						
							|  |  |  |   fi | 
					
						
							| 
									
										
										
										
											2019-04-02 20:48:14 +00:00
										 |  |  |   [[ -z "$externalNodeSshKey" ]] || ssh-copy-id -f -i "$externalNodeSshKey" "${sshOptions[@]}" "solana@$ipAddress" | 
					
						
							| 
									
										
										
										
											2019-12-23 14:31:57 -08:00
										 |  |  |   syncScripts "$ipAddress" | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | syncScripts() { | 
					
						
							|  |  |  |   echo "rsyncing scripts... to $ipAddress" | 
					
						
							|  |  |  |   declare ipAddress=$1 | 
					
						
							| 
									
										
										
										
											2018-09-04 15:16:25 -07:00
										 |  |  |   rsync -vPrc -e "ssh ${sshOptions[*]}" \
 | 
					
						
							| 
									
										
										
										
											2019-11-09 13:38:17 -08:00
										 |  |  |     --exclude 'net/log*' \
 | 
					
						
							| 
									
										
										
										
											2018-09-04 15:16:25 -07:00
										 |  |  |     "$SOLANA_ROOT"/{fetch-perf-libs.sh,scripts,net,multinode-demo} \
 | 
					
						
							| 
									
										
										
										
											2019-12-23 14:31:57 -08:00
										 |  |  |     "$ipAddress":~/solana/ > /dev/null | 
					
						
							| 
									
										
										
										
											2018-08-28 10:19:33 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-01 13:56:20 -06:00
										 |  |  | # Deploy local binaries to bootstrap validator.  Other validators and clients later fetch the | 
					
						
							|  |  |  | # binaries from it | 
					
						
							|  |  |  | deployBootstrapValidator() { | 
					
						
							|  |  |  |   declare ipAddress=$1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   echo "Deploying software to bootstrap validator ($ipAddress)" | 
					
						
							|  |  |  |   case $deployMethod in | 
					
						
							|  |  |  |   tar) | 
					
						
							|  |  |  |     rsync -vPrc -e "ssh ${sshOptions[*]}" "$SOLANA_ROOT"/solana-release/bin/* "$ipAddress:~/.cargo/bin/" | 
					
						
							|  |  |  |     rsync -vPrc -e "ssh ${sshOptions[*]}" "$SOLANA_ROOT"/solana-release/version.yml "$ipAddress:~/" | 
					
						
							|  |  |  |     ;; | 
					
						
							|  |  |  |   local) | 
					
						
							|  |  |  |     rsync -vPrc -e "ssh ${sshOptions[*]}" "$SOLANA_ROOT"/farf/bin/* "$ipAddress:~/.cargo/bin/" | 
					
						
							|  |  |  |     ssh "${sshOptions[@]}" -n "$ipAddress" "rm -f ~/version.yml; touch ~/version.yml" | 
					
						
							|  |  |  |     ;; | 
					
						
							|  |  |  |   skip) | 
					
						
							|  |  |  |     ;; | 
					
						
							|  |  |  |   *) | 
					
						
							|  |  |  |     usage "Internal error: invalid deployMethod: $deployMethod" | 
					
						
							|  |  |  |     ;; | 
					
						
							|  |  |  |   esac | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-09 09:42:09 -08:00
										 |  |  | startBootstrapLeader() { | 
					
						
							| 
									
										
										
										
											2018-08-28 10:19:33 -07:00
										 |  |  |   declare ipAddress=$1 | 
					
						
							| 
									
										
										
										
											2019-07-17 19:26:23 -07:00
										 |  |  |   declare nodeIndex="$2" | 
					
						
							|  |  |  |   declare logFile="$3" | 
					
						
							| 
									
										
										
										
											2020-01-22 09:22:09 -07:00
										 |  |  |   echo "--- Starting bootstrap validator: $ipAddress" | 
					
						
							| 
									
										
										
										
											2018-09-08 13:48:17 -07:00
										 |  |  |   echo "start log: $logFile" | 
					
						
							| 
									
										
										
										
											2018-08-28 10:19:33 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   ( | 
					
						
							|  |  |  |     set -x | 
					
						
							| 
									
										
										
										
											2018-09-07 08:49:22 -07:00
										 |  |  |     startCommon "$ipAddress" || exit 1 | 
					
						
							| 
									
										
										
										
											2019-06-10 19:42:49 -07:00
										 |  |  |     [[ -z "$externalPrimordialAccountsFile" ]] || rsync -vPrc -e "ssh ${sshOptions[*]}" "$externalPrimordialAccountsFile" \
 | 
					
						
							| 
									
										
										
										
											2019-07-09 14:39:55 -06:00
										 |  |  |       "$ipAddress:$remoteExternalPrimordialAccountsFile" | 
					
						
							| 
									
										
										
										
											2020-06-01 13:56:20 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |     deployBootstrapValidator "$ipAddress" | 
					
						
							| 
									
										
										
										
											2018-09-03 18:15:55 -10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-04 09:21:03 -07:00
										 |  |  |     ssh "${sshOptions[@]}" -n "$ipAddress" \
 | 
					
						
							| 
									
										
										
										
											2018-12-09 09:42:09 -08:00
										 |  |  |       "./solana/net/remote/remote-node.sh \
 | 
					
						
							|  |  |  |          $deployMethod \
 | 
					
						
							| 
									
										
										
										
											2020-01-22 09:22:09 -07:00
										 |  |  |          bootstrap-validator \
 | 
					
						
							| 
									
										
										
										
											2018-12-09 09:42:09 -08:00
										 |  |  |          $entrypointIp \
 | 
					
						
							| 
									
										
										
										
											2020-05-14 18:22:47 -07:00
										 |  |  |          $((${#validatorIpList[@]} + ${#blockstreamerIpList[@]})) \
 | 
					
						
							| 
									
										
										
										
											2018-12-09 09:42:09 -08:00
										 |  |  |          \"$RUST_LOG\" \
 | 
					
						
							| 
									
										
										
										
											2018-12-09 17:28:18 -08:00
										 |  |  |          $skipSetup \
 | 
					
						
							| 
									
										
										
										
											2019-04-29 21:38:03 -07:00
										 |  |  |          $failOnValidatorBootupFailure \
 | 
					
						
							| 
									
										
										
										
											2019-07-09 14:39:55 -06:00
										 |  |  |          \"$remoteExternalPrimordialAccountsFile\" \
 | 
					
						
							| 
									
										
										
										
											2019-07-19 12:51:38 -06:00
										 |  |  |          \"$maybeDisableAirdrops\" \
 | 
					
						
							|  |  |  |          \"$internalNodesStakeLamports\" \
 | 
					
						
							|  |  |  |          \"$internalNodesLamports\" \
 | 
					
						
							| 
									
										
										
										
											2019-06-10 19:42:49 -07:00
										 |  |  |          $nodeIndex \
 | 
					
						
							| 
									
										
										
										
											2020-03-06 15:32:27 -08:00
										 |  |  |          ${#clientIpList[@]} \"$benchTpsExtraArgs\" \
 | 
					
						
							|  |  |  |          ${#clientIpList[@]} \"$benchExchangeExtraArgs\" \
 | 
					
						
							| 
									
										
										
										
											2019-05-18 14:01:36 -07:00
										 |  |  |          \"$genesisOptions\" \
 | 
					
						
							| 
									
										
										
										
											2019-09-17 10:05:41 -07:00
										 |  |  |          \"$maybeNoSnapshot $maybeSkipLedgerVerify $maybeLimitLedgerSize\" \
 | 
					
						
							| 
									
										
										
										
											2019-10-14 10:33:32 -06:00
										 |  |  |          \"$gpuMode\" \
 | 
					
						
							| 
									
										
										
										
											2019-10-23 09:53:06 -07:00
										 |  |  |          \"$GEOLOCATION_API_KEY\" \
 | 
					
						
							| 
									
										
										
										
											2018-12-09 09:42:09 -08:00
										 |  |  |       "
 | 
					
						
							| 
									
										
										
										
											2019-10-23 09:53:06 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-04 15:16:25 -07:00
										 |  |  |   ) >> "$logFile" 2>&1 || { | 
					
						
							|  |  |  |     cat "$logFile" | 
					
						
							|  |  |  |     echo "^^^ +++" | 
					
						
							|  |  |  |     exit 1 | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-08-28 10:19:33 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-05 16:40:08 -08:00
										 |  |  | startNode() { | 
					
						
							| 
									
										
										
										
											2018-08-28 10:19:33 -07:00
										 |  |  |   declare ipAddress=$1 | 
					
						
							| 
									
										
										
										
											2019-02-17 09:48:27 -08:00
										 |  |  |   declare nodeType=$2 | 
					
						
							| 
									
										
										
										
											2019-06-10 19:42:49 -07:00
										 |  |  |   declare nodeIndex="$3" | 
					
						
							| 
									
										
										
										
											2019-11-08 21:46:03 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   initLogDir | 
					
						
							| 
									
										
										
										
											2019-10-21 21:21:21 -06:00
										 |  |  |   declare logFile="$netLogDir/validator-$ipAddress.log" | 
					
						
							| 
									
										
										
										
											2018-08-28 10:19:33 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-17 19:26:23 -07:00
										 |  |  |   if [[ -z $nodeType ]]; then | 
					
						
							|  |  |  |     echo nodeType not specified | 
					
						
							|  |  |  |     exit 1 | 
					
						
							|  |  |  |   fi | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if [[ -z $nodeIndex ]]; then | 
					
						
							|  |  |  |     echo nodeIndex not specified | 
					
						
							|  |  |  |     exit 1 | 
					
						
							|  |  |  |   fi | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-17 09:48:27 -08:00
										 |  |  |   echo "--- Starting $nodeType: $ipAddress" | 
					
						
							| 
									
										
										
										
											2018-09-08 13:48:17 -07:00
										 |  |  |   echo "start log: $logFile" | 
					
						
							| 
									
										
										
										
											2018-08-28 10:19:33 -07:00
										 |  |  |   ( | 
					
						
							|  |  |  |     set -x | 
					
						
							| 
									
										
										
										
											2018-09-07 08:49:22 -07:00
										 |  |  |     startCommon "$ipAddress" | 
					
						
							| 
									
										
										
										
											2019-07-09 15:45:46 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if [[ $nodeType = blockstreamer ]] && [[ -n $letsEncryptDomainName ]]; then | 
					
						
							|  |  |  |       # | 
					
						
							|  |  |  |       # Create/renew TLS certificate | 
					
						
							|  |  |  |       # | 
					
						
							|  |  |  |       declare localArchive=~/letsencrypt-"$letsEncryptDomainName".tgz | 
					
						
							|  |  |  |       if [[ -r "$localArchive" ]]; then | 
					
						
							|  |  |  |         timeout 30s scp "${sshOptions[@]}" "$localArchive" "$ipAddress:letsencrypt.tgz" | 
					
						
							|  |  |  |       fi | 
					
						
							|  |  |  |       ssh "${sshOptions[@]}" -n "$ipAddress" \
 | 
					
						
							| 
									
										
										
										
											2020-06-13 15:41:05 -06:00
										 |  |  |         "sudo -H /certbot-restore.sh $letsEncryptDomainName maintainers@solana.foundation" | 
					
						
							| 
									
										
										
										
											2019-07-09 15:45:46 -07:00
										 |  |  |       rm -f letsencrypt.tgz | 
					
						
							|  |  |  |       timeout 30s scp "${sshOptions[@]}" "$ipAddress:/letsencrypt.tgz" letsencrypt.tgz | 
					
						
							|  |  |  |       test -s letsencrypt.tgz # Ensure non-empty before overwriting $localArchive | 
					
						
							|  |  |  |       cp letsencrypt.tgz "$localArchive" | 
					
						
							|  |  |  |     fi | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-04 09:21:03 -07:00
										 |  |  |     ssh "${sshOptions[@]}" -n "$ipAddress" \
 | 
					
						
							| 
									
										
										
										
											2018-12-09 09:42:09 -08:00
										 |  |  |       "./solana/net/remote/remote-node.sh \
 | 
					
						
							|  |  |  |          $deployMethod \
 | 
					
						
							| 
									
										
										
										
											2019-02-17 09:48:27 -08:00
										 |  |  |          $nodeType \
 | 
					
						
							| 
									
										
										
										
											2018-12-09 09:42:09 -08:00
										 |  |  |          $entrypointIp \
 | 
					
						
							| 
									
										
										
										
											2020-05-14 18:22:47 -07:00
										 |  |  |          $((${#validatorIpList[@]} + ${#blockstreamerIpList[@]})) \
 | 
					
						
							| 
									
										
										
										
											2018-12-09 09:42:09 -08:00
										 |  |  |          \"$RUST_LOG\" \
 | 
					
						
							| 
									
										
										
										
											2018-12-09 17:28:18 -08:00
										 |  |  |          $skipSetup \
 | 
					
						
							| 
									
										
										
										
											2019-04-29 21:38:03 -07:00
										 |  |  |          $failOnValidatorBootupFailure \
 | 
					
						
							| 
									
										
										
										
											2019-07-09 14:39:55 -06:00
										 |  |  |          \"$remoteExternalPrimordialAccountsFile\" \
 | 
					
						
							| 
									
										
										
										
											2019-07-19 12:51:38 -06:00
										 |  |  |          \"$maybeDisableAirdrops\" \
 | 
					
						
							|  |  |  |          \"$internalNodesStakeLamports\" \
 | 
					
						
							|  |  |  |          \"$internalNodesLamports\" \
 | 
					
						
							| 
									
										
										
										
											2019-06-10 19:42:49 -07:00
										 |  |  |          $nodeIndex \
 | 
					
						
							| 
									
										
										
										
											2020-03-06 15:32:27 -08:00
										 |  |  |          ${#clientIpList[@]} \"$benchTpsExtraArgs\" \
 | 
					
						
							|  |  |  |          ${#clientIpList[@]} \"$benchExchangeExtraArgs\" \
 | 
					
						
							| 
									
										
										
										
											2019-05-18 14:01:36 -07:00
										 |  |  |          \"$genesisOptions\" \
 | 
					
						
							| 
									
										
										
										
											2019-09-17 10:05:41 -07:00
										 |  |  |          \"$maybeNoSnapshot $maybeSkipLedgerVerify $maybeLimitLedgerSize\" \
 | 
					
						
							| 
									
										
										
										
											2019-10-14 10:33:32 -06:00
										 |  |  |          \"$gpuMode\" \
 | 
					
						
							| 
									
										
										
										
											2019-10-23 09:53:06 -07:00
										 |  |  |          \"$GEOLOCATION_API_KEY\" \
 | 
					
						
							| 
									
										
										
										
											2018-12-09 09:42:09 -08:00
										 |  |  |       "
 | 
					
						
							| 
									
										
										
										
											2018-09-08 13:48:17 -07:00
										 |  |  |   ) >> "$logFile" 2>&1 & | 
					
						
							| 
									
										
										
										
											2018-09-04 09:21:03 -07:00
										 |  |  |   declare pid=$! | 
					
						
							| 
									
										
										
										
											2019-10-21 21:21:21 -06:00
										 |  |  |   ln -sf "validator-$ipAddress.log" "$netLogDir/validator-$pid.log" | 
					
						
							| 
									
										
										
										
											2018-09-04 09:21:03 -07:00
										 |  |  |   pids+=("$pid") | 
					
						
							| 
									
										
										
										
											2018-08-28 10:19:33 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | startClient() { | 
					
						
							|  |  |  |   declare ipAddress=$1 | 
					
						
							| 
									
										
										
										
											2019-04-19 09:56:01 -07:00
										 |  |  |   declare clientToRun="$2" | 
					
						
							| 
									
										
										
										
											2019-06-11 18:47:35 -07:00
										 |  |  |   declare clientIndex="$3" | 
					
						
							| 
									
										
										
										
											2019-11-08 21:46:03 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   initLogDir | 
					
						
							| 
									
										
										
										
											2019-04-19 09:56:01 -07:00
										 |  |  |   declare logFile="$netLogDir/client-$clientToRun-$ipAddress.log" | 
					
						
							| 
									
										
										
										
											2019-11-08 21:46:03 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-19 09:56:01 -07:00
										 |  |  |   echo "--- Starting client: $ipAddress - $clientToRun" | 
					
						
							| 
									
										
										
										
											2018-09-08 13:48:17 -07:00
										 |  |  |   echo "start log: $logFile" | 
					
						
							| 
									
										
										
										
											2018-09-03 19:33:40 -10:00
										 |  |  |   ( | 
					
						
							|  |  |  |     set -x | 
					
						
							| 
									
										
										
										
											2018-09-07 08:49:22 -07:00
										 |  |  |     startCommon "$ipAddress" | 
					
						
							| 
									
										
										
										
											2018-09-03 19:33:40 -10:00
										 |  |  |     ssh "${sshOptions[@]}" -f "$ipAddress" \
 | 
					
						
							| 
									
										
										
										
											2019-04-23 15:13:29 -07:00
										 |  |  |       "./solana/net/remote/remote-client.sh $deployMethod $entrypointIp \
 | 
					
						
							| 
									
										
										
										
											2019-06-11 18:47:35 -07:00
										 |  |  |       $clientToRun \"$RUST_LOG\" \"$benchTpsExtraArgs\" \"$benchExchangeExtraArgs\" $clientIndex"
 | 
					
						
							| 
									
										
										
										
											2018-09-04 15:16:25 -07:00
										 |  |  |   ) >> "$logFile" 2>&1 || { | 
					
						
							|  |  |  |     cat "$logFile" | 
					
						
							|  |  |  |     echo "^^^ +++" | 
					
						
							|  |  |  |     exit 1 | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-08-28 10:19:33 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-06 15:32:27 -08:00
										 |  |  | startClients() { | 
					
						
							|  |  |  |   for ((i=0; i < "$numClients" && i < "$numClientsRequested"; i++)) do | 
					
						
							|  |  |  |     if [[ $i -lt "$numBenchTpsClients" ]]; then | 
					
						
							|  |  |  |       startClient "${clientIpList[$i]}" "solana-bench-tps" "$i" | 
					
						
							|  |  |  |     elif [[ $i -lt $((numBenchTpsClients + numBenchExchangeClients)) ]]; then | 
					
						
							|  |  |  |       startClient "${clientIpList[$i]}" "solana-bench-exchange" $((i-numBenchTpsClients)) | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       startClient "${clientIpList[$i]}" "idle" | 
					
						
							|  |  |  |     fi | 
					
						
							|  |  |  |   done | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | sanity() { | 
					
						
							|  |  |  |   declare skipBlockstreamerSanity=$1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   $metricsWriteDatapoint "testnet-deploy net-sanity-begin=1" | 
					
						
							| 
									
										
										
										
											2018-09-06 13:00:01 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-09 17:16:10 -07:00
										 |  |  |   declare ok=true | 
					
						
							| 
									
										
										
										
											2019-10-21 21:21:21 -06:00
										 |  |  |   declare bootstrapLeader=${validatorIpList[0]} | 
					
						
							| 
									
										
										
										
											2019-04-09 16:20:44 -07:00
										 |  |  |   declare blockstreamer=${blockstreamerIpList[0]} | 
					
						
							| 
									
										
										
										
											2019-04-09 17:16:10 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-24 08:09:37 -07:00
										 |  |  |   annotateBlockexplorerUrl | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-09 17:16:10 -07:00
										 |  |  |   echo "--- Sanity: $bootstrapLeader" | 
					
						
							| 
									
										
										
										
											2018-09-03 19:33:40 -10:00
										 |  |  |   ( | 
					
						
							|  |  |  |     set -x | 
					
						
							| 
									
										
										
										
											2018-09-04 14:36:35 -07:00
										 |  |  |     # shellcheck disable=SC2029 # remote-client.sh args are expanded on client side intentionally | 
					
						
							| 
									
										
										
										
											2019-04-09 16:20:44 -07:00
										 |  |  |     ssh "${sshOptions[@]}" "$bootstrapLeader" \
 | 
					
						
							| 
									
										
										
										
											2019-06-04 22:46:48 -07:00
										 |  |  |       "./solana/net/remote/remote-sanity.sh $bootstrapLeader $sanityExtraArgs \"$RUST_LOG\"" | 
					
						
							| 
									
										
										
										
											2019-04-09 17:16:10 -07:00
										 |  |  |   ) || ok=false | 
					
						
							|  |  |  |   $ok || exit 1 | 
					
						
							| 
									
										
										
										
											2019-04-09 16:20:44 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-05 17:10:36 -07:00
										 |  |  |   if [[ -z $skipBlockstreamerSanity && -n $blockstreamer ]]; then | 
					
						
							| 
									
										
										
										
											2019-04-09 16:20:44 -07:00
										 |  |  |     # If there's a blockstreamer node run a reduced sanity check on it as well | 
					
						
							| 
									
										
										
										
											2019-04-09 17:16:10 -07:00
										 |  |  |     echo "--- Sanity: $blockstreamer" | 
					
						
							|  |  |  |     ( | 
					
						
							|  |  |  |       set -x | 
					
						
							| 
									
										
										
										
											2019-04-09 16:20:44 -07:00
										 |  |  |       # shellcheck disable=SC2029 # remote-client.sh args are expanded on client side intentionally | 
					
						
							|  |  |  |       ssh "${sshOptions[@]}" "$blockstreamer" \
 | 
					
						
							| 
									
										
										
										
											2019-10-18 08:26:08 -07:00
										 |  |  |         "./solana/net/remote/remote-sanity.sh $blockstreamer $sanityExtraArgs \"$RUST_LOG\"" | 
					
						
							| 
									
										
										
										
											2019-04-09 17:16:10 -07:00
										 |  |  |     ) || ok=false | 
					
						
							|  |  |  |     $ok || exit 1 | 
					
						
							|  |  |  |   fi | 
					
						
							| 
									
										
										
										
											2018-09-06 13:00:01 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   $metricsWriteDatapoint "testnet-deploy net-sanity-complete=1" | 
					
						
							| 
									
										
										
										
											2018-09-03 19:33:40 -10:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2018-09-03 18:15:55 -10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-10 16:46:30 -07:00
										 |  |  | deployUpdate() { | 
					
						
							| 
									
										
										
										
											2019-06-07 12:59:58 -07:00
										 |  |  |   if [[ -z $updatePlatforms ]]; then | 
					
						
							| 
									
										
										
										
											2019-09-19 12:03:47 -07:00
										 |  |  |     echo "No update platforms" | 
					
						
							| 
									
										
										
										
											2019-04-10 16:46:30 -07:00
										 |  |  |     return | 
					
						
							|  |  |  |   fi | 
					
						
							| 
									
										
										
										
											2019-09-19 12:03:47 -07:00
										 |  |  |   if [[ -z $releaseChannel ]]; then | 
					
						
							|  |  |  |     echo "Release channel not specified (use -t option)" | 
					
						
							|  |  |  |     exit 1 | 
					
						
							|  |  |  |   fi | 
					
						
							| 
									
										
										
										
											2019-04-10 16:46:30 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   declare ok=true | 
					
						
							| 
									
										
										
										
											2019-10-21 21:21:21 -06:00
										 |  |  |   declare bootstrapLeader=${validatorIpList[0]} | 
					
						
							| 
									
										
										
										
											2019-04-10 16:46:30 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-07 12:59:58 -07:00
										 |  |  |   for updatePlatform in $updatePlatforms; do | 
					
						
							|  |  |  |     echo "--- Deploying solana-install update: $updatePlatform" | 
					
						
							|  |  |  |     ( | 
					
						
							|  |  |  |       set -x | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       scripts/solana-install-update-manifest-keypair.sh "$updatePlatform" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       timeout 30s scp "${sshOptions[@]}" \
 | 
					
						
							|  |  |  |         update_manifest_keypair.json "$bootstrapLeader:solana/update_manifest_keypair.json" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       # shellcheck disable=SC2029 # remote-deploy-update.sh args are expanded on client side intentionally | 
					
						
							|  |  |  |       ssh "${sshOptions[@]}" "$bootstrapLeader" \
 | 
					
						
							|  |  |  |         "./solana/net/remote/remote-deploy-update.sh $releaseChannel $updatePlatform" | 
					
						
							|  |  |  |     ) || ok=false | 
					
						
							|  |  |  |     $ok || exit 1 | 
					
						
							|  |  |  |   done | 
					
						
							| 
									
										
										
										
											2019-07-17 19:26:23 -07:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2019-04-10 16:46:30 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-17 19:26:23 -07:00
										 |  |  | getNodeType() { | 
					
						
							|  |  |  |   echo "getNodeType: $nodeAddress" | 
					
						
							|  |  |  |   [[ -n $nodeAddress ]] || { | 
					
						
							|  |  |  |     echo "Error: nodeAddress not set" | 
					
						
							|  |  |  |     exit 1 | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   nodeIndex=0 # <-- global | 
					
						
							|  |  |  |   nodeType=validator # <-- global | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-14 18:22:47 -07:00
										 |  |  |   for ipAddress in "${validatorIpList[@]}" b "${blockstreamerIpList[@]}"; do | 
					
						
							| 
									
										
										
										
											2019-07-17 19:26:23 -07:00
										 |  |  |     if [[ $ipAddress = b ]]; then | 
					
						
							|  |  |  |       nodeType=blockstreamer | 
					
						
							|  |  |  |       continue | 
					
						
							|  |  |  |     fi | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if [[ $ipAddress = "$nodeAddress" ]]; then | 
					
						
							|  |  |  |       echo "getNodeType: $nodeType ($nodeIndex)" | 
					
						
							|  |  |  |       return | 
					
						
							|  |  |  |     fi | 
					
						
							|  |  |  |     ((nodeIndex = nodeIndex + 1)) | 
					
						
							|  |  |  |   done | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   echo "Error: Unknown node: $nodeAddress" | 
					
						
							|  |  |  |   exit 1 | 
					
						
							| 
									
										
										
										
											2019-04-10 16:46:30 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-06 15:32:27 -08:00
										 |  |  | prepareDeploy() { | 
					
						
							| 
									
										
										
										
											2018-09-03 18:15:55 -10:00
										 |  |  |   case $deployMethod in | 
					
						
							| 
									
										
										
										
											2018-10-30 18:05:38 -07:00
										 |  |  |   tar) | 
					
						
							|  |  |  |     if [[ -n $releaseChannel ]]; then | 
					
						
							|  |  |  |       rm -f "$SOLANA_ROOT"/solana-release.tar.bz2 | 
					
						
							| 
									
										
										
										
											2019-06-07 12:59:58 -07:00
										 |  |  |       declare updateDownloadUrl=http://release.solana.com/"$releaseChannel"/solana-release-x86_64-unknown-linux-gnu.tar.bz2 | 
					
						
							| 
									
										
										
										
											2018-12-05 16:40:08 -08:00
										 |  |  |       ( | 
					
						
							|  |  |  |         set -x | 
					
						
							| 
									
										
										
										
											2019-07-02 08:37:10 -07:00
										 |  |  |         curl --retry 5 --retry-delay 2 --retry-connrefused \
 | 
					
						
							|  |  |  |           -o "$SOLANA_ROOT"/solana-release.tar.bz2 "$updateDownloadUrl" | 
					
						
							| 
									
										
										
										
											2018-12-05 16:40:08 -08:00
										 |  |  |       ) | 
					
						
							|  |  |  |       tarballFilename="$SOLANA_ROOT"/solana-release.tar.bz2 | 
					
						
							| 
									
										
										
										
											2018-10-30 18:05:38 -07:00
										 |  |  |     fi | 
					
						
							| 
									
										
										
										
											2018-12-05 16:40:08 -08:00
										 |  |  |     ( | 
					
						
							|  |  |  |       set -x | 
					
						
							|  |  |  |       rm -rf "$SOLANA_ROOT"/solana-release | 
					
						
							|  |  |  |       (cd "$SOLANA_ROOT"; tar jxv) < "$tarballFilename" | 
					
						
							| 
									
										
										
										
											2019-03-13 16:11:50 -07:00
										 |  |  |       cat "$SOLANA_ROOT"/solana-release/version.yml | 
					
						
							| 
									
										
										
										
											2018-12-05 16:40:08 -08:00
										 |  |  |     ) | 
					
						
							| 
									
										
										
										
											2018-10-30 18:05:38 -07:00
										 |  |  |     ;; | 
					
						
							| 
									
										
										
										
											2018-09-03 18:15:55 -10:00
										 |  |  |   local) | 
					
						
							| 
									
										
										
										
											2019-09-09 16:40:12 -06:00
										 |  |  |     if $doBuild; then | 
					
						
							|  |  |  |       build | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       echo "Build skipped due to --no-build" | 
					
						
							|  |  |  |     fi | 
					
						
							| 
									
										
										
										
											2018-09-03 18:15:55 -10:00
										 |  |  |     ;; | 
					
						
							| 
									
										
										
										
											2019-07-22 21:38:26 -07:00
										 |  |  |   skip) | 
					
						
							|  |  |  |     ;; | 
					
						
							| 
									
										
										
										
											2018-09-03 18:15:55 -10:00
										 |  |  |   *) | 
					
						
							|  |  |  |     usage "Internal error: invalid deployMethod: $deployMethod" | 
					
						
							|  |  |  |     ;; | 
					
						
							|  |  |  |   esac | 
					
						
							| 
									
										
										
										
											2019-09-19 12:03:47 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if [[ -n $deployIfNewer ]]; then | 
					
						
							|  |  |  |     if [[ $deployMethod != tar ]]; then | 
					
						
							|  |  |  |       echo "Error: --deploy-if-newer only supported for tar deployments" | 
					
						
							|  |  |  |       exit 1 | 
					
						
							|  |  |  |     fi | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     echo "Fetching current software version" | 
					
						
							|  |  |  |     ( | 
					
						
							|  |  |  |       set -x | 
					
						
							| 
									
										
										
										
											2019-10-21 21:21:21 -06:00
										 |  |  |       rsync -vPrc -e "ssh ${sshOptions[*]}" "${validatorIpList[0]}":~/version.yml current-version.yml | 
					
						
							| 
									
										
										
										
											2019-09-19 12:03:47 -07:00
										 |  |  |     ) | 
					
						
							|  |  |  |     cat current-version.yml | 
					
						
							|  |  |  |     if ! diff -q current-version.yml "$SOLANA_ROOT"/solana-release/version.yml; then | 
					
						
							|  |  |  |       echo "Cluster software version is old.  Update required" | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       echo "Cluster software version is current.  No update required" | 
					
						
							|  |  |  |       exit 0 | 
					
						
							|  |  |  |     fi | 
					
						
							|  |  |  |   fi | 
					
						
							| 
									
										
										
										
											2019-07-18 18:59:47 -07:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2018-09-03 18:15:55 -10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-18 18:59:47 -07:00
										 |  |  | deploy() { | 
					
						
							| 
									
										
										
										
											2019-11-08 21:46:03 -07:00
										 |  |  |   initLogDir | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-28 10:19:33 -07:00
										 |  |  |   echo "Deployment started at $(date)" | 
					
						
							| 
									
										
										
										
											2019-09-19 08:31:22 -07:00
										 |  |  |   $metricsWriteDatapoint "testnet-deploy net-start-begin=1" | 
					
						
							| 
									
										
										
										
											2018-08-28 10:19:33 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-17 09:48:27 -08:00
										 |  |  |   declare bootstrapLeader=true | 
					
						
							| 
									
										
										
										
											2020-05-14 18:22:47 -07:00
										 |  |  |   for nodeAddress in "${validatorIpList[@]}" "${blockstreamerIpList[@]}"; do | 
					
						
							| 
									
										
										
										
											2019-07-17 19:26:23 -07:00
										 |  |  |     nodeType= | 
					
						
							|  |  |  |     nodeIndex= | 
					
						
							|  |  |  |     getNodeType | 
					
						
							| 
									
										
										
										
											2018-12-09 09:42:09 -08:00
										 |  |  |     if $bootstrapLeader; then | 
					
						
							|  |  |  |       SECONDS=0 | 
					
						
							|  |  |  |       declare bootstrapNodeDeployTime= | 
					
						
							| 
									
										
										
										
											2020-01-22 09:22:09 -07:00
										 |  |  |       startBootstrapLeader "$nodeAddress" $nodeIndex "$netLogDir/bootstrap-validator-$ipAddress.log" | 
					
						
							| 
									
										
										
										
											2018-12-09 09:42:09 -08:00
										 |  |  |       bootstrapNodeDeployTime=$SECONDS | 
					
						
							|  |  |  |       $metricsWriteDatapoint "testnet-deploy net-bootnode-leader-started=1" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       bootstrapLeader=false | 
					
						
							|  |  |  |       SECONDS=0 | 
					
						
							|  |  |  |       pids=() | 
					
						
							|  |  |  |     else | 
					
						
							| 
									
										
										
										
											2019-07-17 19:26:23 -07:00
										 |  |  |       startNode "$ipAddress" $nodeType $nodeIndex | 
					
						
							| 
									
										
										
										
											2018-12-09 09:42:09 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |       # Stagger additional node start time. If too many nodes start simultaneously | 
					
						
							|  |  |  |       # the bootstrap node gets more rsync requests from the additional nodes than | 
					
						
							|  |  |  |       # it can handle. | 
					
						
							| 
									
										
										
										
											2019-10-28 16:43:40 -06:00
										 |  |  |       sleep 2 | 
					
						
							| 
									
										
										
										
											2018-12-09 09:42:09 -08:00
										 |  |  |     fi | 
					
						
							| 
									
										
										
										
											2018-09-04 09:21:03 -07:00
										 |  |  |   done | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-17 19:26:23 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-04 09:21:03 -07:00
										 |  |  |   for pid in "${pids[@]}"; do | 
					
						
							|  |  |  |     declare ok=true | 
					
						
							|  |  |  |     wait "$pid" || ok=false | 
					
						
							|  |  |  |     if ! $ok; then | 
					
						
							| 
									
										
										
										
											2019-10-21 21:21:21 -06:00
										 |  |  |       echo "+++ validator failed to start" | 
					
						
							|  |  |  |       cat "$netLogDir/validator-$pid.log" | 
					
						
							| 
									
										
										
										
											2019-04-29 21:38:03 -07:00
										 |  |  |       if $failOnValidatorBootupFailure; then | 
					
						
							|  |  |  |         exit 1 | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         echo "Failure is non-fatal" | 
					
						
							|  |  |  |       fi | 
					
						
							| 
									
										
										
										
											2018-09-04 09:21:03 -07:00
										 |  |  |     fi | 
					
						
							| 
									
										
										
										
											2018-08-28 10:19:33 -07:00
										 |  |  |   done | 
					
						
							| 
									
										
										
										
											2018-09-04 09:21:03 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-21 21:21:21 -06:00
										 |  |  |   $metricsWriteDatapoint "testnet-deploy net-validators-started=1" | 
					
						
							| 
									
										
										
										
											2018-12-05 16:40:08 -08:00
										 |  |  |   additionalNodeDeployTime=$SECONDS | 
					
						
							| 
									
										
										
										
											2018-08-28 10:19:33 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-24 08:09:37 -07:00
										 |  |  |   annotateBlockexplorerUrl | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-05 17:10:36 -07:00
										 |  |  |   sanity skipBlockstreamerSanity # skip sanity on blockstreamer node, it may not | 
					
						
							| 
									
										
										
										
											2020-01-22 09:22:09 -07:00
										 |  |  |                                  # have caught up to the bootstrap validator yet | 
					
						
							| 
									
										
										
										
											2018-09-03 19:33:40 -10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-05 21:03:26 -05:00
										 |  |  |   echo "--- Sleeping $clientDelayStart seconds after validators are started before starting clients" | 
					
						
							|  |  |  |   sleep "$clientDelayStart" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-03 18:15:55 -10:00
										 |  |  |   SECONDS=0 | 
					
						
							| 
									
										
										
										
											2020-03-06 15:32:27 -08:00
										 |  |  |   startClients | 
					
						
							| 
									
										
										
										
											2018-08-28 10:19:33 -07:00
										 |  |  |   clientDeployTime=$SECONDS | 
					
						
							| 
									
										
										
										
											2018-12-10 21:05:39 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-19 08:31:22 -07:00
										 |  |  |   $metricsWriteDatapoint "testnet-deploy net-start-complete=1" | 
					
						
							| 
									
										
										
										
											2018-08-28 10:19:33 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-08 22:01:45 -08:00
										 |  |  |   declare networkVersion=unknown | 
					
						
							|  |  |  |   case $deployMethod in | 
					
						
							|  |  |  |   tar) | 
					
						
							|  |  |  |     networkVersion="$( | 
					
						
							| 
									
										
										
										
											2019-03-13 16:11:50 -07:00
										 |  |  |       ( | 
					
						
							|  |  |  |         set -o pipefail | 
					
						
							| 
									
										
										
										
											2019-04-25 11:13:45 -07:00
										 |  |  |         grep "^commit: " "$SOLANA_ROOT"/solana-release/version.yml | head -n1 | cut -d\  -f2 | 
					
						
							| 
									
										
										
										
											2019-03-13 16:11:50 -07:00
										 |  |  |       ) || echo "tar-unknown" | 
					
						
							| 
									
										
										
										
											2018-11-08 22:01:45 -08:00
										 |  |  |     )"
 | 
					
						
							|  |  |  |     ;; | 
					
						
							|  |  |  |   local) | 
					
						
							|  |  |  |     networkVersion="$(git rev-parse HEAD || echo local-unknown)" | 
					
						
							|  |  |  |     ;; | 
					
						
							| 
									
										
										
										
											2019-07-22 21:38:26 -07:00
										 |  |  |   skip) | 
					
						
							|  |  |  |     ;; | 
					
						
							| 
									
										
										
										
											2018-11-08 22:01:45 -08:00
										 |  |  |   *) | 
					
						
							|  |  |  |     usage "Internal error: invalid deployMethod: $deployMethod" | 
					
						
							|  |  |  |     ;; | 
					
						
							|  |  |  |   esac | 
					
						
							|  |  |  |   $metricsWriteDatapoint "testnet-deploy version=\"${networkVersion:0:9}\"" | 
					
						
							| 
									
										
										
										
											2018-09-03 18:15:55 -10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-28 10:19:33 -07:00
										 |  |  |   echo | 
					
						
							| 
									
										
										
										
											2020-03-11 11:54:49 -07:00
										 |  |  |   echo "--- Deployment Successful" | 
					
						
							| 
									
										
										
										
											2020-01-22 09:22:09 -07:00
										 |  |  |   echo "Bootstrap validator deployment took $bootstrapNodeDeployTime seconds" | 
					
						
							| 
									
										
										
										
											2020-05-14 18:22:47 -07:00
										 |  |  |   echo "Additional validator deployment (${#validatorIpList[@]} validators, ${#blockstreamerIpList[@]} blockstreamer nodes) took $additionalNodeDeployTime seconds" | 
					
						
							| 
									
										
										
										
											2018-08-28 10:19:33 -07:00
										 |  |  |   echo "Client deployment (${#clientIpList[@]} instances) took $clientDeployTime seconds" | 
					
						
							| 
									
										
										
										
											2019-05-22 13:11:20 -07:00
										 |  |  |   echo "Network start logs in $netLogDir" | 
					
						
							| 
									
										
										
										
											2018-08-28 10:19:33 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-07 08:49:22 -07:00
										 |  |  | stopNode() { | 
					
						
							| 
									
										
										
										
											2018-08-28 10:19:33 -07:00
										 |  |  |   local ipAddress=$1 | 
					
						
							| 
									
										
										
										
											2019-04-30 10:39:52 -07:00
										 |  |  |   local block=$2 | 
					
						
							| 
									
										
										
										
											2019-11-08 21:46:03 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   initLogDir | 
					
						
							| 
									
										
										
										
											2019-10-21 21:21:21 -06:00
										 |  |  |   declare logFile="$netLogDir/stop-validator-$ipAddress.log" | 
					
						
							| 
									
										
										
										
											2019-11-08 21:46:03 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-04 09:21:03 -07:00
										 |  |  |   echo "--- Stopping node: $ipAddress" | 
					
						
							| 
									
										
										
										
											2019-04-30 10:39:52 -07:00
										 |  |  |   echo "stop log: $logFile" | 
					
						
							| 
									
										
										
										
											2019-12-23 14:31:57 -08:00
										 |  |  |   syncScripts "$ipAddress" | 
					
						
							| 
									
										
										
										
											2018-08-28 10:19:33 -07:00
										 |  |  |   ( | 
					
						
							| 
									
										
										
										
											2019-12-23 14:31:57 -08:00
										 |  |  |     # Since cleanup.sh does a pkill, we cannot pass the command directly, | 
					
						
							|  |  |  |     # otherwise the process which is doing the killing will be killed because | 
					
						
							|  |  |  |     # the script itself will match the pkill pattern | 
					
						
							| 
									
										
										
										
											2018-08-28 10:19:33 -07:00
										 |  |  |     set -x | 
					
						
							| 
									
										
										
										
											2019-01-09 22:06:58 -07:00
										 |  |  |     # shellcheck disable=SC2029 # It's desired that PS4 be expanded on the client side | 
					
						
							| 
									
										
										
										
											2019-12-23 14:31:57 -08:00
										 |  |  |     ssh "${sshOptions[@]}" "$ipAddress" "PS4=\"$PS4\" ./solana/net/remote/cleanup.sh" | 
					
						
							| 
									
										
										
										
											2019-04-30 10:39:52 -07:00
										 |  |  |   ) >> "$logFile" 2>&1 & | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   declare pid=$! | 
					
						
							| 
									
										
										
										
											2019-10-21 21:21:21 -06:00
										 |  |  |   ln -sf "stop-validator-$ipAddress.log" "$netLogDir/stop-validator-$pid.log" | 
					
						
							| 
									
										
										
										
											2019-04-30 10:39:52 -07:00
										 |  |  |   if $block; then | 
					
						
							|  |  |  |     wait $pid | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     pids+=("$pid") | 
					
						
							|  |  |  |   fi | 
					
						
							| 
									
										
										
										
											2018-08-28 10:19:33 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | stop() { | 
					
						
							|  |  |  |   SECONDS=0 | 
					
						
							| 
									
										
										
										
											2018-09-06 13:00:01 -07:00
										 |  |  |   $metricsWriteDatapoint "testnet-deploy net-stop-begin=1" | 
					
						
							| 
									
										
										
										
											2018-09-03 18:15:55 -10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-30 10:39:52 -07:00
										 |  |  |   declare loopCount=0 | 
					
						
							|  |  |  |   pids=() | 
					
						
							| 
									
										
										
										
											2020-05-14 18:22:47 -07:00
										 |  |  |   for ipAddress in "${validatorIpList[@]}" "${blockstreamerIpList[@]}" "${clientIpList[@]}"; do | 
					
						
							| 
									
										
										
										
											2019-04-30 10:39:52 -07:00
										 |  |  |     stopNode "$ipAddress" false | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Stagger additional node stop time to avoid too many concurrent ssh | 
					
						
							|  |  |  |     # sessions | 
					
						
							|  |  |  |     ((loopCount++ % 4 == 0)) && sleep 2 | 
					
						
							| 
									
										
										
										
											2018-08-28 10:19:33 -07:00
										 |  |  |   done | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-30 10:39:52 -07:00
										 |  |  |   echo --- Waiting for nodes to finish stopping | 
					
						
							|  |  |  |   for pid in "${pids[@]}"; do | 
					
						
							|  |  |  |     echo -n "$pid " | 
					
						
							|  |  |  |     wait "$pid" || true | 
					
						
							|  |  |  |   done | 
					
						
							|  |  |  |   echo | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-06 13:00:01 -07:00
										 |  |  |   $metricsWriteDatapoint "testnet-deploy net-stop-complete=1" | 
					
						
							| 
									
										
										
										
											2018-08-28 10:19:33 -07:00
										 |  |  |   echo "Stopping nodes took $SECONDS seconds" | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-14 23:11:29 -07:00
										 |  |  | checkPremptibleInstances() { | 
					
						
							| 
									
										
										
										
											2019-10-21 21:21:21 -06:00
										 |  |  |   # The validatorIpList nodes may be preemptible instances that can disappear at | 
					
						
							|  |  |  |   # any time.  Try to detect when a validator has been preempted to help the user | 
					
						
							| 
									
										
										
										
											2019-10-14 23:11:29 -07:00
										 |  |  |   # out. | 
					
						
							|  |  |  |   # | 
					
						
							|  |  |  |   # Of course this isn't airtight as an instance could always disappear | 
					
						
							|  |  |  |   # immediately after its successfully pinged. | 
					
						
							| 
									
										
										
										
											2019-10-21 21:21:21 -06:00
										 |  |  |   for ipAddress in "${validatorIpList[@]}"; do | 
					
						
							| 
									
										
										
										
											2019-10-14 23:11:29 -07:00
										 |  |  |     ( | 
					
						
							|  |  |  |       set -x | 
					
						
							| 
									
										
										
										
											2019-10-16 13:31:58 -07:00
										 |  |  |       timeout 5s ping -c 1 "$ipAddress" | tr - _ | 
					
						
							| 
									
										
										
										
											2019-10-14 23:11:29 -07:00
										 |  |  |     ) || { | 
					
						
							|  |  |  |       cat <<EOF | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Warning: $ipAddress may have been preempted. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Run |./gce.sh config| to restart it | 
					
						
							|  |  |  | EOF | 
					
						
							|  |  |  |       exit 1 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   done | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-06 15:32:27 -08:00
										 |  |  | releaseChannel= | 
					
						
							|  |  |  | deployMethod=local | 
					
						
							|  |  |  | deployIfNewer= | 
					
						
							|  |  |  | sanityExtraArgs= | 
					
						
							|  |  |  | skipSetup=false | 
					
						
							|  |  |  | updatePlatforms= | 
					
						
							|  |  |  | nodeAddress= | 
					
						
							|  |  |  | numIdleClients=0 | 
					
						
							|  |  |  | numBenchTpsClients=0 | 
					
						
							|  |  |  | numBenchExchangeClients=0 | 
					
						
							|  |  |  | benchTpsExtraArgs= | 
					
						
							|  |  |  | benchExchangeExtraArgs= | 
					
						
							|  |  |  | failOnValidatorBootupFailure=true | 
					
						
							|  |  |  | genesisOptions= | 
					
						
							|  |  |  | numValidatorsRequested= | 
					
						
							|  |  |  | externalPrimordialAccountsFile= | 
					
						
							|  |  |  | remoteExternalPrimordialAccountsFile= | 
					
						
							|  |  |  | internalNodesStakeLamports= | 
					
						
							|  |  |  | internalNodesLamports= | 
					
						
							|  |  |  | maybeNoSnapshot="" | 
					
						
							|  |  |  | maybeLimitLedgerSize="" | 
					
						
							|  |  |  | maybeSkipLedgerVerify="" | 
					
						
							|  |  |  | maybeDisableAirdrops="" | 
					
						
							|  |  |  | debugBuild=false | 
					
						
							|  |  |  | doBuild=true | 
					
						
							|  |  |  | gpuMode=auto | 
					
						
							|  |  |  | maybeUseMove="" | 
					
						
							|  |  |  | netemPartition="" | 
					
						
							|  |  |  | netemConfig="" | 
					
						
							|  |  |  | netemConfigFile="" | 
					
						
							|  |  |  | netemCommand="add" | 
					
						
							|  |  |  | clientDelayStart=0 | 
					
						
							|  |  |  | netLogDir= | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | command=$1 | 
					
						
							|  |  |  | [[ -n $command ]] || usage | 
					
						
							|  |  |  | shift | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | shortArgs=() | 
					
						
							|  |  |  | while [[ -n $1 ]]; do | 
					
						
							|  |  |  |   if [[ ${1:0:2} = -- ]]; then | 
					
						
							|  |  |  |     if [[ $1 = --hashes-per-tick ]]; then | 
					
						
							|  |  |  |       genesisOptions="$genesisOptions $1 $2" | 
					
						
							|  |  |  |       shift 2 | 
					
						
							|  |  |  |     elif [[ $1 = --slots-per-epoch ]]; then | 
					
						
							|  |  |  |       genesisOptions="$genesisOptions $1 $2" | 
					
						
							|  |  |  |       shift 2 | 
					
						
							|  |  |  |     elif [[ $1 = --target-lamports-per-signature ]]; then | 
					
						
							|  |  |  |       genesisOptions="$genesisOptions $1 $2" | 
					
						
							|  |  |  |       shift 2 | 
					
						
							|  |  |  |     elif [[ $1 = --faucet-lamports ]]; then | 
					
						
							|  |  |  |       genesisOptions="$genesisOptions $1 $2" | 
					
						
							|  |  |  |       shift 2 | 
					
						
							|  |  |  |     elif [[ $1 = --operating-mode ]]; then | 
					
						
							|  |  |  |       case "$2" in | 
					
						
							|  |  |  |         development|softlaunch) | 
					
						
							|  |  |  |           ;; | 
					
						
							|  |  |  |         *) | 
					
						
							|  |  |  |           echo "Unexpected operating mode: \"$2\"" | 
					
						
							|  |  |  |           exit 1 | 
					
						
							|  |  |  |           ;; | 
					
						
							|  |  |  |       esac | 
					
						
							|  |  |  |       genesisOptions="$genesisOptions $1 $2" | 
					
						
							|  |  |  |       shift 2 | 
					
						
							|  |  |  |     elif [[ $1 = --no-snapshot-fetch ]]; then | 
					
						
							|  |  |  |       maybeNoSnapshot="$1" | 
					
						
							|  |  |  |       shift 1 | 
					
						
							|  |  |  |     elif [[ $1 = --deploy-if-newer ]]; then | 
					
						
							|  |  |  |       deployIfNewer=1 | 
					
						
							|  |  |  |       shift 1 | 
					
						
							|  |  |  |     elif [[ $1 = --no-deploy ]]; then | 
					
						
							|  |  |  |       deployMethod=skip | 
					
						
							|  |  |  |       shift 1 | 
					
						
							|  |  |  |     elif [[ $1 = --no-build ]]; then | 
					
						
							|  |  |  |       doBuild=false | 
					
						
							|  |  |  |       shift 1 | 
					
						
							|  |  |  |     elif [[ $1 = --limit-ledger-size ]]; then | 
					
						
							|  |  |  |       maybeLimitLedgerSize="$1" | 
					
						
							|  |  |  |       shift 1 | 
					
						
							|  |  |  |     elif [[ $1 = --skip-poh-verify ]]; then | 
					
						
							|  |  |  |       maybeSkipLedgerVerify="$1" | 
					
						
							|  |  |  |       shift 1 | 
					
						
							|  |  |  |     elif [[ $1 = --skip-setup ]]; then | 
					
						
							|  |  |  |       skipSetup=true | 
					
						
							|  |  |  |       shift 1 | 
					
						
							|  |  |  |     elif [[ $1 = --platform ]]; then | 
					
						
							|  |  |  |       updatePlatforms="$updatePlatforms $2" | 
					
						
							|  |  |  |       shift 2 | 
					
						
							|  |  |  |     elif [[ $1 = --internal-nodes-stake-lamports ]]; then | 
					
						
							|  |  |  |       internalNodesStakeLamports="$2" | 
					
						
							|  |  |  |       shift 2 | 
					
						
							|  |  |  |     elif [[ $1 = --internal-nodes-lamports ]]; then | 
					
						
							|  |  |  |       internalNodesLamports="$2" | 
					
						
							|  |  |  |       shift 2 | 
					
						
							|  |  |  |     elif [[ $1 = --external-accounts-file ]]; then | 
					
						
							|  |  |  |       externalPrimordialAccountsFile="$2" | 
					
						
							|  |  |  |       remoteExternalPrimordialAccountsFile=/tmp/external-primordial-accounts.yml | 
					
						
							|  |  |  |       shift 2 | 
					
						
							|  |  |  |     elif [[ $1 = --no-airdrop ]]; then | 
					
						
							|  |  |  |       maybeDisableAirdrops="$1" | 
					
						
							|  |  |  |       shift 1 | 
					
						
							|  |  |  |     elif [[ $1 = --debug ]]; then | 
					
						
							|  |  |  |       debugBuild=true | 
					
						
							|  |  |  |       shift 1 | 
					
						
							|  |  |  |     elif [[ $1 = --use-move ]]; then | 
					
						
							|  |  |  |       maybeUseMove=$1 | 
					
						
							|  |  |  |       shift 1 | 
					
						
							|  |  |  |     elif [[ $1 = --partition ]]; then | 
					
						
							|  |  |  |       netemPartition=$2 | 
					
						
							|  |  |  |       shift 2 | 
					
						
							|  |  |  |     elif [[ $1 = --config ]]; then | 
					
						
							|  |  |  |       netemConfig=$2 | 
					
						
							|  |  |  |       shift 2 | 
					
						
							|  |  |  |     elif [[ $1 == --config-file ]]; then | 
					
						
							|  |  |  |       netemConfigFile=$2 | 
					
						
							|  |  |  |       shift 2 | 
					
						
							|  |  |  |     elif [[ $1 == --netem-cmd ]]; then | 
					
						
							|  |  |  |       netemCommand=$2 | 
					
						
							|  |  |  |       shift 2 | 
					
						
							|  |  |  |     elif [[ $1 = --gpu-mode ]]; then | 
					
						
							|  |  |  |       gpuMode=$2 | 
					
						
							|  |  |  |       case "$gpuMode" in | 
					
						
							|  |  |  |         on|off|auto|cuda) | 
					
						
							|  |  |  |           ;; | 
					
						
							|  |  |  |         *) | 
					
						
							|  |  |  |           echo "Unexpected GPU mode: \"$gpuMode\"" | 
					
						
							|  |  |  |           exit 1 | 
					
						
							|  |  |  |           ;; | 
					
						
							|  |  |  |       esac | 
					
						
							|  |  |  |       shift 2 | 
					
						
							|  |  |  |     elif [[ $1 == --client-delay-start ]]; then | 
					
						
							|  |  |  |       clientDelayStart=$2 | 
					
						
							|  |  |  |       shift 2 | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       usage "Unknown long option: $1" | 
					
						
							|  |  |  |     fi | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     shortArgs+=("$1") | 
					
						
							|  |  |  |     shift | 
					
						
							|  |  |  |   fi | 
					
						
							|  |  |  | done | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | while getopts "h?T:t:o:f:rc:Fn:i:d" opt "${shortArgs[@]}"; do | 
					
						
							|  |  |  |   case $opt in | 
					
						
							|  |  |  |   h | \?) | 
					
						
							|  |  |  |     usage | 
					
						
							|  |  |  |     ;; | 
					
						
							|  |  |  |   T) | 
					
						
							|  |  |  |     tarballFilename=$OPTARG | 
					
						
							|  |  |  |     [[ -r $tarballFilename ]] || usage "File not readable: $tarballFilename" | 
					
						
							|  |  |  |     deployMethod=tar | 
					
						
							|  |  |  |     ;; | 
					
						
							|  |  |  |   t) | 
					
						
							|  |  |  |     case $OPTARG in | 
					
						
							|  |  |  |     edge|beta|stable|v*) | 
					
						
							|  |  |  |       releaseChannel=$OPTARG | 
					
						
							|  |  |  |       deployMethod=tar | 
					
						
							|  |  |  |       ;; | 
					
						
							|  |  |  |     *) | 
					
						
							|  |  |  |       usage "Invalid release channel: $OPTARG" | 
					
						
							|  |  |  |       ;; | 
					
						
							|  |  |  |     esac | 
					
						
							|  |  |  |     ;; | 
					
						
							|  |  |  |   n) | 
					
						
							|  |  |  |     numValidatorsRequested=$OPTARG | 
					
						
							|  |  |  |     ;; | 
					
						
							|  |  |  |   r) | 
					
						
							|  |  |  |     skipSetup=true | 
					
						
							|  |  |  |     ;; | 
					
						
							|  |  |  |   o) | 
					
						
							|  |  |  |     case $OPTARG in | 
					
						
							|  |  |  |     rejectExtraNodes|noInstallCheck) | 
					
						
							|  |  |  |       sanityExtraArgs="$sanityExtraArgs -o $OPTARG" | 
					
						
							|  |  |  |       ;; | 
					
						
							|  |  |  |     *) | 
					
						
							|  |  |  |       usage "Unknown option: $OPTARG" | 
					
						
							|  |  |  |       ;; | 
					
						
							|  |  |  |     esac | 
					
						
							|  |  |  |     ;; | 
					
						
							|  |  |  |   c) | 
					
						
							|  |  |  |     getClientTypeAndNum() { | 
					
						
							|  |  |  |       if ! [[ $OPTARG == *'='* ]]; then | 
					
						
							|  |  |  |         echo "Error: Expecting tuple \"clientType=numClientType=extraArgs\" but got \"$OPTARG\"" | 
					
						
							|  |  |  |         exit 1 | 
					
						
							|  |  |  |       fi | 
					
						
							|  |  |  |       local keyValue | 
					
						
							|  |  |  |       IFS='=' read -ra keyValue <<< "$OPTARG" | 
					
						
							|  |  |  |       local clientType=${keyValue[0]} | 
					
						
							|  |  |  |       local numClients=${keyValue[1]} | 
					
						
							|  |  |  |       local extraArgs=${keyValue[2]} | 
					
						
							|  |  |  |       re='^[0-9]+$' | 
					
						
							|  |  |  |       if ! [[ $numClients =~ $re ]] ; then | 
					
						
							|  |  |  |         echo "error: numClientType must be a number but got \"$numClients\"" | 
					
						
							|  |  |  |         exit 1 | 
					
						
							|  |  |  |       fi | 
					
						
							|  |  |  |       case $clientType in | 
					
						
							|  |  |  |         idle) | 
					
						
							|  |  |  |           numIdleClients=$numClients | 
					
						
							|  |  |  |           # $extraArgs ignored for 'idle' | 
					
						
							|  |  |  |         ;; | 
					
						
							|  |  |  |         bench-tps) | 
					
						
							|  |  |  |           numBenchTpsClients=$numClients | 
					
						
							|  |  |  |           benchTpsExtraArgs=$extraArgs | 
					
						
							|  |  |  |         ;; | 
					
						
							|  |  |  |         bench-exchange) | 
					
						
							|  |  |  |           numBenchExchangeClients=$numClients | 
					
						
							|  |  |  |           benchExchangeExtraArgs=$extraArgs | 
					
						
							|  |  |  |         ;; | 
					
						
							|  |  |  |         *) | 
					
						
							|  |  |  |           echo "Unknown client type: $clientType" | 
					
						
							|  |  |  |           exit 1 | 
					
						
							|  |  |  |           ;; | 
					
						
							|  |  |  |       esac | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     getClientTypeAndNum | 
					
						
							|  |  |  |     ;; | 
					
						
							|  |  |  |   F) | 
					
						
							|  |  |  |     failOnValidatorBootupFailure=false | 
					
						
							|  |  |  |     ;; | 
					
						
							|  |  |  |   i) | 
					
						
							|  |  |  |     nodeAddress=$OPTARG | 
					
						
							|  |  |  |     ;; | 
					
						
							|  |  |  |   d) | 
					
						
							|  |  |  |     debugBuild=true | 
					
						
							|  |  |  |     ;; | 
					
						
							|  |  |  |   *) | 
					
						
							|  |  |  |     usage "Error: unhandled option: $opt" | 
					
						
							|  |  |  |     ;; | 
					
						
							|  |  |  |   esac | 
					
						
							|  |  |  | done | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | loadConfigFile | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | if [[ -n $numValidatorsRequested ]]; then | 
					
						
							|  |  |  |   truncatedNodeList=( "${validatorIpList[@]:0:$numValidatorsRequested}" ) | 
					
						
							|  |  |  |   unset validatorIpList | 
					
						
							|  |  |  |   validatorIpList=( "${truncatedNodeList[@]}" ) | 
					
						
							|  |  |  | fi | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | numClients=${#clientIpList[@]} | 
					
						
							|  |  |  | numClientsRequested=$((numBenchTpsClients + numBenchExchangeClients + numIdleClients)) | 
					
						
							|  |  |  | if [[ "$numClientsRequested" -eq 0 ]]; then | 
					
						
							|  |  |  |   numBenchTpsClients=$numClients | 
					
						
							|  |  |  |   numClientsRequested=$numClients | 
					
						
							|  |  |  | else | 
					
						
							|  |  |  |   if [[ "$numClientsRequested" -gt "$numClients" ]]; then | 
					
						
							|  |  |  |     echo "Error: More clients requested ($numClientsRequested) then available ($numClients)" | 
					
						
							|  |  |  |     exit 1 | 
					
						
							|  |  |  |   fi | 
					
						
							|  |  |  | fi | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-14 23:11:29 -07:00
										 |  |  | checkPremptibleInstances | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-03 19:33:40 -10:00
										 |  |  | case $command in | 
					
						
							| 
									
										
										
										
											2018-09-04 09:21:03 -07:00
										 |  |  | restart) | 
					
						
							| 
									
										
										
										
											2020-03-06 15:32:27 -08:00
										 |  |  |   prepareDeploy | 
					
						
							| 
									
										
										
										
											2018-09-03 19:33:40 -10:00
										 |  |  |   stop | 
					
						
							| 
									
										
										
										
											2019-07-18 18:59:47 -07:00
										 |  |  |   deploy | 
					
						
							| 
									
										
										
										
											2018-09-03 19:33:40 -10:00
										 |  |  |   ;; | 
					
						
							| 
									
										
										
										
											2018-09-04 09:21:03 -07:00
										 |  |  | start) | 
					
						
							| 
									
										
										
										
											2020-03-06 15:32:27 -08:00
										 |  |  |   prepareDeploy | 
					
						
							| 
									
										
										
										
											2019-07-18 18:59:47 -07:00
										 |  |  |   deploy | 
					
						
							| 
									
										
										
										
											2018-09-04 09:21:03 -07:00
										 |  |  |   ;; | 
					
						
							| 
									
										
										
										
											2018-09-03 19:33:40 -10:00
										 |  |  | sanity) | 
					
						
							|  |  |  |   sanity | 
					
						
							|  |  |  |   ;; | 
					
						
							|  |  |  | stop) | 
					
						
							|  |  |  |   stop | 
					
						
							|  |  |  |   ;; | 
					
						
							| 
									
										
										
										
											2019-09-19 12:03:47 -07:00
										 |  |  | update) | 
					
						
							|  |  |  |   deployUpdate | 
					
						
							|  |  |  |   ;; | 
					
						
							| 
									
										
										
										
											2020-06-01 14:00:35 -06:00
										 |  |  | upgrade) | 
					
						
							|  |  |  |   bootstrapValidatorIp="${validatorIpList[0]}" | 
					
						
							|  |  |  |   prepareDeploy | 
					
						
							|  |  |  |   deployBootstrapValidator "$bootstrapValidatorIp" | 
					
						
							|  |  |  |   # (start|stop)Node need refactored to support restarting the bootstrap validator | 
					
						
							|  |  |  |   ;; | 
					
						
							| 
									
										
										
										
											2019-06-16 23:30:11 -07:00
										 |  |  | stopnode) | 
					
						
							| 
									
										
										
										
											2019-07-17 19:26:23 -07:00
										 |  |  |   if [[ -z $nodeAddress ]]; then | 
					
						
							|  |  |  |     usage "node address (-i) not specified" | 
					
						
							|  |  |  |     exit 1 | 
					
						
							|  |  |  |   fi | 
					
						
							| 
									
										
										
										
											2019-06-16 23:30:11 -07:00
										 |  |  |   stopNode "$nodeAddress" true | 
					
						
							|  |  |  |   ;; | 
					
						
							|  |  |  | startnode) | 
					
						
							| 
									
										
										
										
											2019-07-17 19:26:23 -07:00
										 |  |  |   if [[ -z $nodeAddress ]]; then | 
					
						
							|  |  |  |     usage "node address (-i) not specified" | 
					
						
							|  |  |  |     exit 1 | 
					
						
							|  |  |  |   fi | 
					
						
							|  |  |  |   nodeType= | 
					
						
							|  |  |  |   nodeIndex= | 
					
						
							|  |  |  |   getNodeType | 
					
						
							|  |  |  |   startNode "$nodeAddress" $nodeType $nodeIndex | 
					
						
							| 
									
										
										
										
											2019-06-16 23:30:11 -07:00
										 |  |  |   ;; | 
					
						
							| 
									
										
										
										
											2020-03-06 15:32:27 -08:00
										 |  |  | startclients) | 
					
						
							|  |  |  |   startClients | 
					
						
							|  |  |  |   ;; | 
					
						
							| 
									
										
										
										
											2018-12-23 08:54:24 -08:00
										 |  |  | logs) | 
					
						
							| 
									
										
										
										
											2019-11-08 21:46:03 -07:00
										 |  |  |   initLogDir | 
					
						
							| 
									
										
										
										
											2018-12-23 08:54:24 -08:00
										 |  |  |   fetchRemoteLog() { | 
					
						
							|  |  |  |     declare ipAddress=$1 | 
					
						
							|  |  |  |     declare log=$2 | 
					
						
							|  |  |  |     echo "--- fetching $log from $ipAddress" | 
					
						
							|  |  |  |     ( | 
					
						
							|  |  |  |       set -x | 
					
						
							|  |  |  |       timeout 30s scp "${sshOptions[@]}" \
 | 
					
						
							| 
									
										
										
										
											2018-12-23 10:33:40 -08:00
										 |  |  |         "$ipAddress":solana/"$log".log "$netLogDir"/remote-"$log"-"$ipAddress".log | 
					
						
							| 
									
										
										
										
											2018-12-23 08:54:24 -08:00
										 |  |  |     ) || echo "failed to fetch log" | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-12-16 14:05:17 -07:00
										 |  |  |   fetchRemoteLog "${validatorIpList[0]}" faucet | 
					
						
							| 
									
										
										
										
											2019-10-21 21:21:21 -06:00
										 |  |  |   for ipAddress in "${validatorIpList[@]}"; do | 
					
						
							|  |  |  |     fetchRemoteLog "$ipAddress" validator | 
					
						
							| 
									
										
										
										
											2018-12-23 08:54:24 -08:00
										 |  |  |   done | 
					
						
							|  |  |  |   for ipAddress in "${clientIpList[@]}"; do | 
					
						
							|  |  |  |     fetchRemoteLog "$ipAddress" client | 
					
						
							|  |  |  |   done | 
					
						
							| 
									
										
										
										
											2019-02-21 16:35:26 -07:00
										 |  |  |   for ipAddress in "${blockstreamerIpList[@]}"; do | 
					
						
							| 
									
										
										
										
											2019-10-21 21:21:21 -06:00
										 |  |  |     fetchRemoteLog "$ipAddress" validator | 
					
						
							| 
									
										
										
										
											2019-02-17 09:48:27 -08:00
										 |  |  |   done | 
					
						
							| 
									
										
										
										
											2018-12-23 08:54:24 -08:00
										 |  |  |   ;; | 
					
						
							| 
									
										
										
										
											2019-11-07 11:14:33 -08:00
										 |  |  | netem) | 
					
						
							| 
									
										
										
										
											2019-11-15 12:10:48 -08:00
										 |  |  |   if [[ -n $netemConfigFile ]]; then | 
					
						
							| 
									
										
										
										
											2020-01-22 13:46:50 -05:00
										 |  |  |     remoteNetemConfigFile="$(basename "$netemConfigFile")" | 
					
						
							| 
									
										
										
										
											2019-11-18 11:33:33 -08:00
										 |  |  |     if [[ $netemCommand = "add" ]]; then | 
					
						
							|  |  |  |       for ipAddress in "${validatorIpList[@]}"; do | 
					
						
							|  |  |  |         "$here"/scp.sh "$netemConfigFile" solana@"$ipAddress":~/solana | 
					
						
							|  |  |  |       done | 
					
						
							|  |  |  |     fi | 
					
						
							| 
									
										
										
										
											2019-11-15 12:10:48 -08:00
										 |  |  |     for i in "${!validatorIpList[@]}"; do | 
					
						
							|  |  |  |       "$here"/ssh.sh solana@"${validatorIpList[$i]}" 'solana/scripts/net-shaper.sh' \
 | 
					
						
							| 
									
										
										
										
											2020-01-22 13:46:50 -05:00
										 |  |  |       "$netemCommand" ~solana/solana/"$remoteNetemConfigFile" "${#validatorIpList[@]}" "$i" | 
					
						
							| 
									
										
										
										
											2019-11-15 12:10:48 -08:00
										 |  |  |     done | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     num_nodes=$((${#validatorIpList[@]}*netemPartition/100)) | 
					
						
							|  |  |  |     if [[ $((${#validatorIpList[@]}*netemPartition%100)) -gt 0 ]]; then | 
					
						
							|  |  |  |       num_nodes=$((num_nodes+1)) | 
					
						
							|  |  |  |     fi | 
					
						
							|  |  |  |     if [[ "$num_nodes" -gt "${#validatorIpList[@]}" ]]; then | 
					
						
							|  |  |  |       num_nodes=${#validatorIpList[@]} | 
					
						
							|  |  |  |     fi | 
					
						
							| 
									
										
										
										
											2018-12-23 08:54:24 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-15 12:10:48 -08:00
										 |  |  |     # Stop netem on all nodes | 
					
						
							|  |  |  |     for ipAddress in "${validatorIpList[@]}"; do | 
					
						
							|  |  |  |       "$here"/ssh.sh solana@"$ipAddress" 'solana/scripts/netem.sh delete < solana/netem.cfg || true' | 
					
						
							|  |  |  |     done | 
					
						
							| 
									
										
										
										
											2019-11-07 11:14:33 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-15 12:10:48 -08:00
										 |  |  |     # Start netem on required nodes | 
					
						
							|  |  |  |     for ((i=0; i<num_nodes; i++ )); do : | 
					
						
							|  |  |  |       "$here"/ssh.sh solana@"${validatorIpList[$i]}" "echo $netemConfig > solana/netem.cfg; solana/scripts/netem.sh add \"$netemConfig\"" | 
					
						
							|  |  |  |     done | 
					
						
							|  |  |  |   fi | 
					
						
							| 
									
										
										
										
											2019-11-07 11:14:33 -08:00
										 |  |  |   ;; | 
					
						
							| 
									
										
										
										
											2018-09-03 19:33:40 -10:00
										 |  |  | *) | 
					
						
							|  |  |  |   echo "Internal error: Unknown command: $command" | 
					
						
							| 
									
										
										
										
											2019-04-27 16:12:13 -07:00
										 |  |  |   usage | 
					
						
							| 
									
										
										
										
											2018-09-03 19:33:40 -10:00
										 |  |  |   exit 1 | 
					
						
							|  |  |  | esac |