diff --git a/packages/orchestration/tools/starship/Makefile b/packages/orchestration/tools/starship/Makefile new file mode 100644 index 000000000000..9430b88924e8 --- /dev/null +++ b/packages/orchestration/tools/starship/Makefile @@ -0,0 +1,83 @@ +NAME = starship-getting-started +FILE = config.yaml + +HELM_REPO = starship +HELM_CHART = devnet +HELM_VERSION = v0.2.2 + +############################################################################### +### All commands ### +############################################################################### + +.PHONY: setup +setup: setup-deps setup-kind + +.PHONY: stop +stop: stop-forward delete + +.PHONY: clean +clean: stop clean-kind + +############################################################################### +### Dependency check ### +############################################################################### + +.PHONY: check +setup-deps: + bash $(CURDIR)/scripts/dev-setup.sh + +############################################################################### +### Helm Charts ### +############################################################################### + +install: + bash $(CURDIR)/scripts/install.sh --config $(FILE) --name $(NAME) --version $(HELM_VERSION) + +delete: + -helm delete $(NAME) + +############################################################################### +### Port forward ### +############################################################################### + +.PHONY: port-forward +port-forward: + bash $(CURDIR)/scripts/port-forward.sh --config=$(FILE) + +.PHONY: stop-forward +stop-forward: + -pkill -f "port-forward" + +############################################################################### +### Local Kind Setup ### +############################################################################### +KIND_CLUSTER=starship + +.PHONY: setup-kind +setup-kind: + kind create cluster --name $(KIND_CLUSTER) + +.PHONY: clean-kind +clean-kind: + kind delete cluster --name $(KIND_CLUSTER) + +############################################################################### +### Agoric Setup ### +############################################################################### +PROVISION_POOL_ADDR=agoric1megzytg65cyrgzs6fvzxgrcqvwwl7ugpt62346 + +fund-provision-pool: + kubectl exec -it agoriclocal-genesis-0 -c validator -- agd tx bank send faucet $(PROVISION_POOL_ADDR) 1000000000uist -y -b block + +ADDR=agoric1ldmtatp24qlllgxmrsjzcpe20fvlkp448zcuce +COIN=1000000000uist + +fund-wallet: + kubectl exec -it agoriclocal-genesis-0 -c validator -- agd tx bank send faucet $(ADDR) $(COIN) -y -b block + +provision-smart-wallet: + kubectl exec -it agoriclocal-genesis-0 -c validator -- agd tx swingset provision-one wallet $(ADDR) SMART_WALLET --from faucet -y -b block + +# view agoric swingset logs from slog file, until we can set `DEBUG=SwingSet:vat,SwingSet:ls` +tail-slog: + kubectl exec -it agoriclocal-genesis-0 -c validator -- tail -f slog.slog diff --git a/packages/orchestration/tools/starship/README.md b/packages/orchestration/tools/starship/README.md new file mode 100644 index 000000000000..7f9f0cd208f1 --- /dev/null +++ b/packages/orchestration/tools/starship/README.md @@ -0,0 +1,55 @@ +# Starship + +End-to-end testing environment for fully simulated chains, powered by [Starship](https://docs.cosmology.zone/starship). + + +## Initial Setup + +Ensure you have `docker`, `kubectl`, `kind`, and `helm` installed on your machine For convenience, the following command will install dependencies: + +```sh +make setup-deps +``` + +You will need a `kind` cluster: + +```sh +make setup-kind +``` + +## Getting Started + +```sh +# install helm chart and start starship service +make install + +# expose ports on your local machine. useful for testing dapps +make port-forward + +# stop the containers and port-forwarding +make stop +``` + +To setup finish setting up Agoric, also run: + +```bash +make fund-provision-poool +``` + +You can use these commands to fund an account and make a smart wallet: +```bash +ADDR=agoric123 COIN=100000ubld make fund-wallet +ADDR=agoric123 make provision-smart-wallet +``` + +## Logs + +You can use the following commmands to view logs: + +```sh +# agoric slogfile +make tail-slog + +# agoric validator logs +kubkubectl logs agoriclocal-genesis-0 --container=validator --follow +``` diff --git a/packages/orchestration/tools/starship/config.yaml b/packages/orchestration/tools/starship/config.yaml new file mode 100644 index 000000000000..25cf104c1edd --- /dev/null +++ b/packages/orchestration/tools/starship/config.yaml @@ -0,0 +1,103 @@ +chains: + - id: agoriclocal + name: agoric + # also have the option to build from a git tag or branch: https://docs.cosmology.zone/starship/config/chains#build-optional + image: ghcr.io/agoric/agoric-sdk:dev + numValidators: 1 + env: + - name: DEBUG + value: SwingSet:vat,SwingSet:ls + genesis: + app_state: + staking: + params: + unbonding_time: "48h" + swingset: + params: + bootstrap_vat_config: "@agoric/vm-config/decentral-devnet-config.json" + faucet: + enabled: false + ports: + rest: 1317 + rpc: 26657 + exposer: 38087 + grpc: 9090 + resources: + cpu: 1 + memory: 4Gi + - id: osmosislocal + name: osmosis + numValidators: 1 + genesis: + app_state: + staking: + params: + unbonding_time: "48h" + interchain_accounts: + host_genesis_state: + params: + host_enabled: true + allow_messages: ["*"] + interchainquery: + host_port: "icqhost" + params: + host_enabled: true + allow_queries: ["*"] + faucet: + enabled: true + type: starship + ports: + rest: 1315 + rpc: 26655 + grpc: 9093 + faucet: 8084 + - id: gaialocal + name: cosmoshub + numValidators: 1 + genesis: + app_state: + staking: + params: + unbonding_time: "48h" + interchain_accounts: + host_genesis_state: + params: + host_enabled: true + allow_messages: ["*"] + faucet: + enabled: true + ports: + rest: 1314 + rpc: 26654 + grpc: 9092 + faucet: 8083 + +relayers: + - name: osmosis-gaia + type: hermes + replicas: 1 + chains: + - osmosislocal + - gaialocal + - name: agoric-osmosis + type: hermes + replicas: 1 + chains: + - agoriclocal + - osmosislocal + - name: agoric-gaia + type: hermes + replicas: 1 + chains: + - agoriclocal + - gaialocal + +explorer: + enabled: true + ports: + rest: 8080 + +registry: + enabled: true + ports: + rest: 8081 diff --git a/packages/orchestration/tools/starship/scripts/dev-setup.sh b/packages/orchestration/tools/starship/scripts/dev-setup.sh new file mode 100644 index 000000000000..b438895f03ce --- /dev/null +++ b/packages/orchestration/tools/starship/scripts/dev-setup.sh @@ -0,0 +1,69 @@ +#!/bin/bash + +set -euo pipefail + +function color() { + local color=$1 + shift + local black=30 red=31 green=32 yellow=33 blue=34 magenta=35 cyan=36 white=37 + local color_code=${!color:-$green} + printf "\033[%sm%s\033[0m\n" "$color_code" "$*" +} + +# Define a function to install a binary on macOS +install_macos() { + case $1 in + docker) color red "Please install docker. Follow: https://docs.docker.com/desktop/install/mac-install/" ;; + kubectl) brew install kubectl ;; + helm) brew install helm ;; + yq) brew install yq ;; + kind) brew install kind ;; + esac +} + +# Define a function to install a binary on Linux +install_linux() { + color green "Installing $1 at ~/.local/bin, please add it to PATH" + mkdir -p ~/.local/bin + case $1 in + docker) color red "Please install docker. Follow: https://docs.docker.com/engine/install/ubuntu/" ;; + kubectl) curl -Lks "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" > ~/.local/bin/kubectl && chmod +x ~/.local/bin/kubectl ;; + helm) curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash ;; + yq) curl -Lks "https://github.com/mikefarah/yq/releases/download/v4.33.3/yq_linux_amd64" > ~/.local/bin/yq && chmod +x ~/.local/bin/yq ;; + kind) curl -Lks https://kind.sigs.k8s.io/dl/v0.18.1/kind-linux-amd64 > ~/.local/bin/kind && chmod +x ~/.local/bin/kind ;; + esac +} + +# Define a function to install a binary +install_binary() { + if [[ $(uname -s) == "Darwin" ]]; then + install_macos $1 + else + install_linux $1 + fi +} + +# Define a function to check for the presence of a binary +check_binary() { + if ! command -v $1 &> /dev/null + then + echo "$1 is not installed" + install_binary $1 + if ! command -v $1 &> /dev/null + then + color red "Installation of $1 failed, exiting..." + color red "Please install $1 manually, then run me again to verify the installation" + exit 1 + fi + fi +} + +# Check the binaries +check_binary kubectl +check_binary helm +check_binary yq +check_binary kind +check_binary docker + +color green "All binaries are installed" + diff --git a/packages/orchestration/tools/starship/scripts/install.sh b/packages/orchestration/tools/starship/scripts/install.sh new file mode 100644 index 000000000000..5b2b2514e538 --- /dev/null +++ b/packages/orchestration/tools/starship/scripts/install.sh @@ -0,0 +1,125 @@ +#!/bin/bash + +## Script used to install the helm chart for the devnet from a config file +## Usage: +## ./scripts/install.sh --coinfig +## Options: +## -c|--config: config file to use (default: config.yaml) +## -v|--version: helm chart version (default: 0.1.43) + +set -euo pipefail + +# read config file from args into variable +CONFIGFILE="config.yaml" + +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) +echo "Script dir: ${SCRIPT_DIR}" + +# default values +DRY_RUN="" +TIMEOUT="" +NAMESPACE="" +HELM_REPO="starship" +HELM_CHART="starship/devnet" +HELM_REPO_URL="https://cosmology-tech.github.io/starship/" +HELM_CHART_VERSION="0.2.2" +HELM_NAME="starship-getting-started" + +# check_helm function verifies the helm binary is installed +function check_helm() { + if ! command -v helm &> /dev/null + then + echo "helm could not be found; please install it first!!!" + exit + fi +} + +# setup_helm function adds the helm repo and updates it +function setup_helm() { + if [ -d "$HELM_CHART" ]; then + echo "using local helm chart" + return + fi + helm repo add ${HELM_REPO} ${HELM_REPO_URL} + helm repo update + helm search repo ${HELM_CHART} --version ${HELM_CHART_VERSION} +} + +function set_helm_args() { + if [[ $TIMEOUT ]]; then + args="$args --timeout $TIMEOUT --wait --debug" + fi + if [[ $NAMESPACE ]]; then + args="$args --namespace $NAMESPACE --create-namespace" + fi + if [[ $DRY_RUN ]]; then + args="$args --dry-run --debug" + fi + num_chains=$(yq -r ".chains | length - 1" ${CONFIGFILE}) + if [[ $num_chains -lt 0 ]]; then + echo "No chains to parse: num: $num_chains" + return 0 + fi + for i in $(seq 0 $num_chains); do + chain=$(yq -r ".chains[$i].name" ${CONFIGFILE}) + scripts=$(yq -r ".chains[$i].scripts" ${CONFIGFILE}) + if [[ "$scripts" == "null" ]]; then + return 0 + fi + datadir="$(cd "$(dirname -- "${CONFIGFILE}")" >/dev/null; pwd -P)" + for script in $(yq -r ".chains[$i].scripts | keys | .[]" ${CONFIGFILE}); do + args="$args --set-file chains[$i].scripts.$script.data=$datadir/$(yq -r ".chains[$i].scripts.$script.file" ${CONFIGFILE})" + done + done +} + +function install_chart() { + args="" + set_helm_args + echo "name: ${HELM_NAME}, args: $args, chart: ${HELM_CHART}, version: ${HELM_CHART_VERSION}" + helm install ${HELM_NAME} ${HELM_CHART} --version ${HELM_CHART_VERSION} -f ${CONFIGFILE} $args +} + +while [ $# -gt 0 ]; do + case "$1" in + -c|--config) + CONFIGFILE="$2" + shift 2 # past argument=value + ;; + -v|--version) + HELM_CHART_VERSION="$2" + shift 2 # past argument + ;; + -t|--timeout) + TIMEOUT="$2" + shift 2 # past argument + ;; + -n|--name) + HELM_NAME="$2" + shift 2 # past argument + ;; + --namespace) + NAMESPACE="$2" + shift 2 # past argument + ;; + --chart) + HELM_CHART="$2" + shift 2 # past argument + ;; + --dry-run) + DRY_RUN=1 + shift # past argument + ;; + -*|--*) + echo "Unknown option $1" + exit 1 + ;; + *) + ;; + esac +done + +check_helm +setup_helm +install_chart + diff --git a/packages/orchestration/tools/starship/scripts/port-forward.sh b/packages/orchestration/tools/starship/scripts/port-forward.sh new file mode 100644 index 000000000000..96db67a1a48f --- /dev/null +++ b/packages/orchestration/tools/starship/scripts/port-forward.sh @@ -0,0 +1,132 @@ +#!/bin/bash + +set -euo pipefail + +function color() { + local color=$1 + shift + local black=30 red=31 green=32 yellow=33 blue=34 magenta=35 cyan=36 white=37 + local color_code=${!color:-$green} + printf "\033[%sm%s\033[0m\n" "$color_code" "$*" +} + +function stop_port_forward() { + color green "Trying to stop all port-forward, if any...." + PIDS=$(ps -ef | grep -i -e 'kubectl port-forward' | grep -v 'grep' | cat | awk '{print $2}') || true + for p in $PIDS; do + kill -15 $p + done + sleep 2 +} + +# Default values +CHAIN_RPC_PORT=26657 +CHAIN_COMETMOCK_PORT=22331 +CHAIN_GRPC_PORT=9090 +CHAIN_LCD_PORT=1317 +CHAIN_EXPOSER_PORT=8081 +CHAIN_FAUCET_PORT=8000 +RELAYER_REST_PORT=3000 +RELAYER_EXPOSER_PORT=8081 +EXPLORER_LCD_PORT=8080 +REGISTRY_LCD_PORT=8080 +REGISTRY_GRPC_PORT=9090 +MONITORING_PROMETHEUS_PORT=8080 +MONITORING_GRAFANA_PORT=8080 + +for i in "$@"; do + case $i in + -c=*|--config=*) + CONFIGFILE="${i#*=}" + shift # past argument=value + ;; + -*|--*) + echo "Unknown option $i" + exit 1 + ;; + *) + ;; + esac +done + +stop_port_forward + +echo "Port forwarding for config ${CONFIGFILE}" +echo "Port forwarding all chains" +num_chains=$(yq -r ".chains | length - 1" ${CONFIGFILE}) +if [[ $num_chains -gt -1 ]]; then + for i in $(seq 0 $num_chains); do + # derive chain pod name from chain id + # https://github.com/cosmology-tech/starship/blob/main/charts/devnet/templates/_helpers.tpl#L56 + chain=$(yq -r ".chains[$i].name" ${CONFIGFILE} ) + chain=${chain/_/"-"} + localrpc=$(yq -r ".chains[$i].ports.rpc" ${CONFIGFILE} ) + localgrpc=$(yq -r ".chains[$i].ports.grpc" ${CONFIGFILE} ) + locallcd=$(yq -r ".chains[$i].ports.rest" ${CONFIGFILE} ) + localexp=$(yq -r ".chains[$i].ports.exposer" ${CONFIGFILE}) + localfaucet=$(yq -r ".chains[$i].ports.faucet" ${CONFIGFILE}) + color yellow "chains: forwarded $chain" + if [[ $(yq -r ".chains[$i].cometmock.enabled" $CONFIGFILE) == "true" ]]; + then + [[ "$localrpc" != "null" ]] && color yellow " cometmock rpc to http://localhost:$localrpc" && kubectl port-forward pods/$chain-cometmock-0 $localrpc:$CHAIN_COMETMOCK_PORT > /dev/null 2>&1 & + else + [[ "$localrpc" != "null" ]] && color yellow " rpc to http://localhost:$localrpc" && kubectl port-forward pods/$chain-genesis-0 $localrpc:$CHAIN_RPC_PORT > /dev/null 2>&1 & + fi + [[ "$localgrpc" != "null" ]] && color yellow " grpc to http://localhost:$localgrpc" && kubectl port-forward pods/$chain-genesis-0 $localgrpc:$CHAIN_GRPC_PORT > /dev/null 2>&1 & + [[ "$locallcd" != "null" ]] && color yellow " lcd to http://localhost:$locallcd" && kubectl port-forward pods/$chain-genesis-0 $locallcd:$CHAIN_LCD_PORT > /dev/null 2>&1 & + [[ "$localexp" != "null" ]] && color yellow " exposer to http://localhost:$localexp" && kubectl port-forward pods/$chain-genesis-0 $localexp:$CHAIN_EXPOSER_PORT > /dev/null 2>&1 & + [[ "$localfaucet" != "null" ]] && color yellow " faucet to http://localhost:$localfaucet" && kubectl port-forward pods/$chain-genesis-0 $localfaucet:$CHAIN_FAUCET_PORT > /dev/null 2>&1 & + sleep 1 + done +else + echo "No chains to port-forward: num: $num_chains" +fi + + +echo "Port forward relayers" +num_relayers=$(yq -r ".relayers | length - 1" ${CONFIGFILE}) +if [[ $num_relayers -gt -1 ]]; then + for i in $(seq 0 $num_relayers); do + # derive chain pod name from chain id + # https://github.com/cosmology-tech/starship/blob/main/charts/devnet/templates/_helpers.tpl#L56 + relayer=$(yq -r ".relayers[$i].name" ${CONFIGFILE} ) + relayer=$(yq -r ".relayers[$i].type" ${CONFIGFILE} )-${relayer/_/"-"} + localrest=$(yq -r ".relayers[$i].ports.rest" ${CONFIGFILE} ) + localexposer=$(yq -r ".relayers[$i].ports.exposer" ${CONFIGFILE} ) + color yellow "relayers: forwarded $relayer" + [[ "$localrest" != "null" ]] && color yellow " rpc to http://localhost:$localrest" && kubectl port-forward pods/$relayer-0 $localrest:$RELAYER_REST_PORT > /dev/null 2>&1 & + [[ "$localexposer" != "null" ]] && color yellow " rpc to http://localhost:$localexposer" && kubectl port-forward pods/$relayer-0 $localexposer:$RELAYER_EXPOSER_PORT > /dev/null 2>&1 & + sleep 1 + done +else + echo "No relayer to port-forward: num: $num_relayers" +fi + + +echo "Port forward services" + +if [[ $(yq -r ".registry.enabled" $CONFIGFILE) == "true" ]]; +then + kubectl port-forward service/registry 8081:$REGISTRY_LCD_PORT > /dev/null 2>&1 & + kubectl port-forward service/registry 9091:$REGISTRY_GRPC_PORT > /dev/null 2>&1 & + sleep 1 + color yellow "registry: forwarded registry lcd to grpc http://localhost:8081, to http://localhost:9091" +fi + +if [[ $(yq -r ".explorer.enabled" $CONFIGFILE) == "true" ]]; +then + kubectl port-forward service/explorer 8080:$EXPLORER_LCD_PORT > /dev/null 2>&1 & + sleep 1 + color green "Open the explorer to get started.... http://localhost:8080" +fi + +if [[ $(yq -r ".monitoring.enabled" $CONFIGFILE) == "true" ]]; +then + color yellow "monitoring port forward:" + localgrafana=$(yq -r ".monitoring.ports.grafana" ${CONFIGFILE}) + localprometheus=$(yq -r ".monitoring.ports.prometheus" ${CONFIGFILE}) + [[ "$localgrafana" != "null" ]] && color yellow " grafana to http://localhost:$localgrafana" && kubectl port-forward service/grafana $localgrafana:$MONITORING_GRAFANA_PORT > /dev/null 2>&1 & + [[ "$localprometheus" != "null" ]] && color yellow " prometheus to http://localhost:$localprometheus" && kubectl port-forward service/prometheus-service $localprometheus:$MONITORING_PROMETHEUS_PORT > /dev/null 2>&1 & + sleep 1 +fi +