From e9f38032688cc2463e9a0f27faa7ae08ef839914 Mon Sep 17 00:00:00 2001 From: William Chong Date: Sat, 12 Feb 2022 14:04:34 +0800 Subject: [PATCH 01/27] =?UTF-8?q?=F0=9F=94=A7=20Add=20cosmosvisor=20into?= =?UTF-8?q?=20dockerfile?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Dockerfile b/Dockerfile index b7ec78a2b8..68d4511a94 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,6 +3,10 @@ FROM likecoin/rbuilder:cf0d1a9f3731e30540bbfa36a36d13e4dcccf5eb as builder ARG LIKED_VERSION=unknown ARG LIKED_COMMIT=unknown +WORKDIR /cosmovisor +RUN wget https://github.com/cosmos/cosmos-sdk/releases/download/cosmovisor%2Fv1.1.0/cosmovisor-v1.1.0-linux-amd64.tar.gz +RUN tar -xzvf cosmovisor-v1.1.0-linux-amd64.tar.gz + COPY . /sources WORKDIR /sources @@ -17,5 +21,12 @@ RUN /bin/bash -c /sources/.build.sh FROM debian:buster WORKDIR /usr/bin +ENV DAEMON_NAME liked +ENV DAEMON_HOME /likechain/.liked +ENV DAEMON_ALLOW_DOWNLOAD_BINARIES true +ENV DAEMON_RESTART_AFTER_UPGRADE true +RUN mkdir -p /likechain/.liked/cosmovisor RUN apt-get update && apt-get install -y curl +COPY --from=builder /cosmovisor/cosmovisor /usr/bin/cosmovisor COPY --from=builder ./home/builder/artifacts/liked-*-linux-amd64 /usr/bin/liked +RUN cp /usr/bin/liked /likechain/.liked/genesis/bin/liked From cb0bf3a54807aadaa2009c2afe39c8c9b7f617f2 Mon Sep 17 00:00:00 2001 From: William Chong Date: Mon, 14 Feb 2022 17:49:12 +0800 Subject: [PATCH 02/27] =?UTF-8?q?=F0=9F=94=A8=20Add=20cosmosvisor=20script?= =?UTF-8?q?=20in=20compose=20and=20init?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 4 ++-- docker-compose.yml.template | 36 +++++++++++++++++++++++++++++++++--- init.sh | 3 +-- 3 files changed, 36 insertions(+), 7 deletions(-) diff --git a/Dockerfile b/Dockerfile index 68d4511a94..f92dbfb610 100644 --- a/Dockerfile +++ b/Dockerfile @@ -25,8 +25,8 @@ ENV DAEMON_NAME liked ENV DAEMON_HOME /likechain/.liked ENV DAEMON_ALLOW_DOWNLOAD_BINARIES true ENV DAEMON_RESTART_AFTER_UPGRADE true -RUN mkdir -p /likechain/.liked/cosmovisor +RUN mkdir -p /likechain/.liked/cosmovisor/genesis/bin /likechain/.liked/data /likechain/.liked/config RUN apt-get update && apt-get install -y curl COPY --from=builder /cosmovisor/cosmovisor /usr/bin/cosmovisor COPY --from=builder ./home/builder/artifacts/liked-*-linux-amd64 /usr/bin/liked -RUN cp /usr/bin/liked /likechain/.liked/genesis/bin/liked +RUN cp /usr/bin/liked /likechain/.liked/cosmovisor/genesis/bin/liked diff --git a/docker-compose.yml.template b/docker-compose.yml.template index 73e4913f1f..aaa9367458 100644 --- a/docker-compose.yml.template +++ b/docker-compose.yml.template @@ -10,12 +10,16 @@ x-script-base: &script-base source: ./ target: /host services: - liked-service: + liked-service-liked: <<: *base + profiles: ["raw"] volumes: - type: bind - source: ./.liked - target: /likechain/.liked + source: ./.liked/config + target: /likechain/.liked/config + - type: bind + source: ./.liked/data + target: /likechain/.liked/data ports: - 26656:26656 - 127.0.0.1:26657:26657 @@ -30,6 +34,30 @@ services: "--halt-time", "${LIKECOIN_HALT_TIME}", "--halt-height", "${LIKECOIN_HALT_HEIGHT}", ] + liked-service-cosmovisor: + <<: *base + volumes: + - type: bind + source: ./.liked/config + target: /likechain/.liked/config + - type: bind + source: ./.liked/data + target: /likechain/.liked/data + - upgrades-volume:/likechain/.liked/cosmovisor/upgrades + ports: + - 26656:26656 + - 127.0.0.1:26657:26657 + # - 1317:1317 # for RESTful API + # - 9090:9090 # for gRPC + restart: always + command: [ + "cosmovisor", "run", "--home", "/likechain/.liked", "start", + "--get-ip", + "--rpc.laddr", "tcp://0.0.0.0:26657", + "--p2p.seeds", "${LIKECOIN_SEED_NODES}", + "--halt-time", "${LIKECOIN_HALT_TIME}", + "--halt-height", "${LIKECOIN_HALT_HEIGHT}", + ] # Below are scripts for `docker-compose run` command, not auto-executing services liked-command: <<: *script-base @@ -72,6 +100,8 @@ services: # 1. proposal ID # 2. vote option ("yes" / "no" / "veto" / "abstain") ] +volumes: + upgrades-volume: networks: default: name: likecoin-chain diff --git a/init.sh b/init.sh index c21f304f23..c868279ab4 100755 --- a/init.sh +++ b/init.sh @@ -4,7 +4,6 @@ set -e LIKECOIN_ROOT="$(dirname "$0")" LIKECOIN_LIKED_HOME="$LIKECOIN_ROOT/.liked" -LIKECOIN_LIKECLI_HOME="$LIKECOIN_ROOT/.likecli" MONIKER="$1" GENESIS_PATH="$2" @@ -20,7 +19,7 @@ if [ -z $MONIKER ] || [ -z $GENESIS_PATH ]; then fi if [ ! -f "$LIKECOIN_LIKED_HOME/config/genesis.json" ]; then - mkdir -p "$LIKECOIN_LIKED_HOME" "$LIKECOIN_LIKECLI_HOME" + mkdir -p "$LIKECOIN_LIKED_HOME/config" "$LIKECOIN_LIKED_HOME/data" liked --home "$LIKECOIN_LIKED_HOME" init "$MONIKER" > /dev/null 2>&1 echo "Initialized ./.liked folder as node data folder." From 116b7a48758aa2927a99b1cd591e51f10e286c0a Mon Sep 17 00:00:00 2001 From: William Chong Date: Thu, 17 Feb 2022 03:03:46 +0800 Subject: [PATCH 03/27] =?UTF-8?q?=F0=9F=94=A7=20Fix=20chown=20issue=20by?= =?UTF-8?q?=20defaulting=20to=20gid=201000?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 11 +++++++++-- docker-compose.yml.template | 4 ++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index f92dbfb610..1750f17907 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,6 @@ FROM likecoin/rbuilder:cf0d1a9f3731e30540bbfa36a36d13e4dcccf5eb as builder +USER root ARG LIKED_VERSION=unknown ARG LIKED_COMMIT=unknown @@ -7,6 +8,7 @@ WORKDIR /cosmovisor RUN wget https://github.com/cosmos/cosmos-sdk/releases/download/cosmovisor%2Fv1.1.0/cosmovisor-v1.1.0-linux-amd64.tar.gz RUN tar -xzvf cosmovisor-v1.1.0-linux-amd64.tar.gz +USER builder COPY . /sources WORKDIR /sources @@ -20,13 +22,18 @@ RUN /bin/bash -c /sources/.build.sh FROM debian:buster -WORKDIR /usr/bin +RUN groupadd --gid 1000 likechain \ + && useradd --uid 1000 --gid likechain --shell /bin/bash likechain +WORKDIR /likechain +RUN mkdir -p /likechain/.liked/cosmovisor/genesis/bin +RUN chown -R likechain:likechain /likechain +RUN chmod -R g+w /likechain ENV DAEMON_NAME liked ENV DAEMON_HOME /likechain/.liked ENV DAEMON_ALLOW_DOWNLOAD_BINARIES true ENV DAEMON_RESTART_AFTER_UPGRADE true -RUN mkdir -p /likechain/.liked/cosmovisor/genesis/bin /likechain/.liked/data /likechain/.liked/config RUN apt-get update && apt-get install -y curl COPY --from=builder /cosmovisor/cosmovisor /usr/bin/cosmovisor COPY --from=builder ./home/builder/artifacts/liked-*-linux-amd64 /usr/bin/liked +USER likechain:likechain RUN cp /usr/bin/liked /likechain/.liked/cosmovisor/genesis/bin/liked diff --git a/docker-compose.yml.template b/docker-compose.yml.template index aaa9367458..5c255524f8 100644 --- a/docker-compose.yml.template +++ b/docker-compose.yml.template @@ -1,6 +1,6 @@ version: "3.6" x-base: &base - user: "${LIKECOIN_UID}" + user: "${LIKECOIN_UID}:1000" image: ${LIKECOIN_DOCKER_IMAGE} x-script-base: &script-base <<: *base @@ -81,7 +81,7 @@ services: "--commission-max-rate", "1.0", "--commission-max-change-rate", "1.0", "--min-self-delegation", "1", - # to fill in: + # to fill in: # --amount # --details # --commission-rate From cf6b9a48299e8b4bafdd9c27cc73f52d72f37158 Mon Sep 17 00:00:00 2001 From: William Chong Date: Fri, 18 Feb 2022 00:31:36 +0800 Subject: [PATCH 04/27] =?UTF-8?q?=F0=9F=94=A7=20Expose=20upgrades=20direct?= =?UTF-8?q?ory=20to=20host=20to=20allow=20mannual=20upgrade=20-=20Also=20m?= =?UTF-8?q?itigate=20some=20volume=20permission=20issue?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker-compose.yml.template | 4 +++- init.sh | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/docker-compose.yml.template b/docker-compose.yml.template index 5c255524f8..abe0482111 100644 --- a/docker-compose.yml.template +++ b/docker-compose.yml.template @@ -43,7 +43,9 @@ services: - type: bind source: ./.liked/data target: /likechain/.liked/data - - upgrades-volume:/likechain/.liked/cosmovisor/upgrades + - type: bind + source: ./.liked/cosmovisor/upgrades + target: /likechain/.liked/cosmovisor/upgrades ports: - 26656:26656 - 127.0.0.1:26657:26657 diff --git a/init.sh b/init.sh index c868279ab4..9467056cbc 100755 --- a/init.sh +++ b/init.sh @@ -55,6 +55,9 @@ else cp "$LIKECOIN_ROOT/$GENESIS_PATH" "$GENESIS_OUTPUT" fi +echo "Create cosmovisor directories" +mkdir "$LIKECOIN_LIKED_HOME/cosmovisor/upgrades" + echo "" echo "Genesis file installed into .liked/config folder." echo "Please verify with the SHA256 checksum:" From 3fff77a0784389ea929387dca8724e6f14b2ed78 Mon Sep 17 00:00:00 2001 From: Rick Mak Date: Mon, 21 Feb 2022 21:06:36 +0800 Subject: [PATCH 05/27] docs: Create documentation on node creation with cosmovisor refs oursky/likecoin-chain#26 --- .gitignore | 2 + deploy/Makefile | 25 +++++++++++ deploy/liked.service.template | 18 ++++++++ deploy/scripts/node-setup.sh | 82 +++++++++++++++++++++++++++++++++++ docs/node-setup.md | 71 ++++++++++++++++++++++++++++++ 5 files changed, 198 insertions(+) create mode 100644 deploy/Makefile create mode 100644 deploy/liked.service.template create mode 100755 deploy/scripts/node-setup.sh create mode 100644 docs/node-setup.md diff --git a/.gitignore b/.gitignore index d4ac999c6e..6470900412 100644 --- a/.gitignore +++ b/.gitignore @@ -9,5 +9,7 @@ docker-compose.yml artifacts build +dist release dist/ +deploy/liked.service diff --git a/deploy/Makefile b/deploy/Makefile new file mode 100644 index 0000000000..5c1e398e9b --- /dev/null +++ b/deploy/Makefile @@ -0,0 +1,25 @@ +LIKED_VERSION ?= $(shell git describe --tags --abbrev=0 | sed 's|v\(.*\)|\1|g') +COSMOVISOR_VERSION ?= "1.1.0" +MONIKER ?= "" + +LIKED_WORKDIR ?= $(HOME) +LIKED_HOME ?= "$(LIKED_WORKDIR)/.liked" +LIKED_USER ?= "$(USER)" + +.PHONY: setup-node +setup-node: +ifeq ($(MONIKER), "") + @echo "Missing MONIKER env" + @echo "Usage: MONIKER= make setup-node" +else + LIKED_VERSION=$(LIKED_VERSION) COSMOVISOR_VERSION=$(COSMOVISOR_VERSION) ./scripts/node-setup.sh $(MONIKER) $(GENESIS_URL) $(LIKED_WORKDIR) $(LIKED_HOME) $(LIKED_USER) +endif + +.PHONY: initialize-systemctl +initialize-systemctl: + sudo cp ./liked.service /etc/systemd/system/liked.service + sudo systemctl daemon-reload + +.PHONY: start-node +start-node: + sudo systemctl start liked diff --git a/deploy/liked.service.template b/deploy/liked.service.template new file mode 100644 index 0000000000..093c675f4a --- /dev/null +++ b/deploy/liked.service.template @@ -0,0 +1,18 @@ +[Unit] +Description=Likecoin node +After=network.target + +[Service] +User= +WorkingDirectory= +ExecStart=/cosmovisor run --home /.liked start --rpc.laddr tcp://0.0.0.0:26657 --halt-time 0 --halt-height 0 +Restart=always +RuntimeMaxSec=86400 +Environment="DAEMON_NAME=liked" +Environment="DAEMON_HOME=/.liked" +Environment="DAEMON_RESTART_AFTER_UPGRADE=true" +Environment="DAEMON_ALLOW_DOWNLOAD_BINARIES=true" +LimitNOFILE=4096 + +[Install] +WantedBy=multi-user.target \ No newline at end of file diff --git a/deploy/scripts/node-setup.sh b/deploy/scripts/node-setup.sh new file mode 100755 index 0000000000..71d5603ca6 --- /dev/null +++ b/deploy/scripts/node-setup.sh @@ -0,0 +1,82 @@ +#!/bin/bash + +set -e + +MONIKER="$1" +GENESIS_URL="$2" +LIKED_WORKDIR="$3" +LIKED_HOME="$4" +LIKED_USER="$5" + +if [ -z $MONIKER ]; then + echo "Usage: $0 NODE_NAME " + echo "Example: $0 likecoin-test" + echo "Example: $0 likecoin-test https://example.com/genesis.json" + exit 1 +fi + +if [ -z $LIKED_VERSION ]; then + LIKED_VERSION="2.0.0-alpha" +fi + +if [ -z $COSMOVISOR_VERSION ]; then + COSMOVISOR_VERSION="1.1.0" +fi + +if [ -z $LIKED_USER ]; then + LIKED_USER="${USER}" +fi + +if [ -z $LIKED_WORKDIR ]; then + LIKED_WORKDIR="$(HOME)" +fi + +if [ -z $LIKED_HOME ]; then + LIKED_HOME="${HOME}/.liked" +fi + +if [ ! -f "$LIKED_WORKDIR/cosmovisor" ]; then + echo "Downloading the latest cosmovisor binary..." + mkdir -p cosmovisor_temp + cd cosmovisor_temp + curl -sL "https://github.com/cosmos/cosmos-sdk/releases/download/cosmovisor%2Fv$COSMOVISOR_VERSION/cosmovisor-v$COSMOVISOR_VERSION-$(uname -s)-$(uname -m | sed "s|x86_64|amd64|").tar.gz" | tar zx + cp cosmovisor $LIKED_WORKDIR/cosmovisor + cd .. + rm -r cosmovisor_temp +fi + +if [ ! -f "$LIKED_WORKDIR/liked" ]; then + echo "Downloading the latest liked binary..." + mkdir -p liked_temp + cd liked_temp + curl -sL "https://github.com/likecoin/likecoin-chain/releases/download/v${LIKED_VERSION}/likecoin-chain_${LIKED_VERSION}_$(uname -s)_$(uname -m).tar.gz" | tar xz + cp bin/liked $LIKED_WORKDIR + cd .. + rm -r liked_temp +fi + +if [ ! -f "$LIKED_HOME/config/genesis.json" ]; then + $LIKED_WORKDIR/liked --home "$LIKED_HOME" init "$MONIKER" +else + echo "Like instance already initialized, skipping..." +fi + +if [ ! -z $GENESIS_URL ]; then + mkdir -p "$LIKED_HOME/config/" + curl -OL "$GENESIS_URL" + mv -f "genesis.json" "$LIKED_HOME/config/genesis.json" + CHAIN_ID=`grep chain_id "$LIKED_HOME/config/genesis.json" | sed 's/ *"chain_id": *"\(.*\)"/\1/g' | sed 's/,$//g'` +else + CHAIN_ID="likecoin-devnet-1" +fi + +if [ ! -f "$LIKED_HOME/cosmovisor/genesis/bin/liked" ]; then + echo "Copying binary to cosmovisor genesis" + mkdir -p "$LIKED_HOME/cosmovisor/genesis/bin" + cp "$LIKED_WORKDIR/liked" "$LIKED_HOME/cosmovisor/genesis/bin/liked" +fi + +chown -R $LIKED_USER $LIKED_HOME + +sed "s||$LIKED_USER|g; s||$LIKED_WORKDIR|g;" ./liked.service.template > ./liked.service +echo "Setup complete, Please setup DAEMON_NAME and DAEMON_HOME environment variable and run 'cosmovisor run start' to start a node locally." \ No newline at end of file diff --git a/docs/node-setup.md b/docs/node-setup.md new file mode 100644 index 0000000000..8696807497 --- /dev/null +++ b/docs/node-setup.md @@ -0,0 +1,71 @@ +# Node Setup + +## Quickstart (Recommended) + +To setup a node using our setup script, please run the following command in the project root folder + +``` +MONIKER= make -C deploy setup-node +``` + +After the initialization, you may run the following commands to start the node as a service. + +``` +make -C deploy initialize-systemctl + +make -C deploy start-node +``` + +**NOTE: If any existing liked instance is running, Please terminate them before starting a new node to prevent double signing** + +## Starting node locally (Not recommended) + +If you wish to start the node locally, run the following commands + +``` +MONIKER= make -C deploy setup-node + +export DAEMON_NAME=liked +export DAEMON_HOME="$HOME/.liked" + +$(LIKED_WORKDIR)/cosmovisor run start +``` + +**NOTE: This method does not restart the node automatically if the device is restarted under normal circumstances and is not recommended to be used as a validator node.** + +## Advanced Setup + +By default, the [node-setup.sh](../deploy/scripts/node-setup.sh) script would download the latest cosmovisor and like binary to the working folder to setup the node automatically. Please refer to the table below for environment variables you can override. + +| Env | Description | Default | +| ------------------ | ----------------------------------------------------------------------------------- | ------------------------------------ | +| MONIKER | Moniker identifier for the node, this is mandatory for the node setup | Empty | +| LIKED_VERSION | Release version of the latest like binary | Latest tag using git describe --tags | +| COSMOVISOR_VERSION | Release version of the latest cosmovisor binary | 1.1.0 | +| LIKED_WORKDIR | Working directory, binaries will be downloaded here | $HOME | +| LIKED_HOME | Home directory for the like node, chain data and configurations will be stored here | $HOME/.liked | +| LIKED_USER | User used for 'liked.service' to run on behalf of | $USER | + +# Upgrades + +As a process manager, Cosmovisor automatically download and upgrade binary as upgrade proposals are approved on chain. + +There are two methods to upgrading the chain version using cosmovisor. + +## Automatic Upgrade + +An automatic upgrade will be executed if an upgrade proposal is submitted and approved with the upgrade info attached. With this method, no extra action is required and cosmovisor will be able to download the suitable binary and replace the current executable in which the process will restart itself automatically when the upgrade block is reached. However, one should monitor the upgrade process to ensure the upgrade is executed successfully. + +## Manual Upgrade + +If a manual upgrade is expected, the new binary should be placed inside + +``` +$HOME/.liked/cosmovisor/upgrades//bin +``` + +Once the upgrade block is reached, cosmovisor should be able to link the `current` folder to the destinated upgrade folder and automatically restart itself to continue the block syncing process with the latest binary. An extra `upgrade-info.json` file will be generated to indicate the metadata for the upgrade. + +# Dependencies + +[Cosmovisor](https://docs.cosmos.network/master/run-node/cosmovisor.html) From 5c559ca37625b6495eedd1a83e92b6fc8d717dae Mon Sep 17 00:00:00 2001 From: Rico Date: Fri, 18 Feb 2022 21:19:48 +0800 Subject: [PATCH 06/27] Add missing p flag for mkdir in init script --- init.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/init.sh b/init.sh index 9467056cbc..bdd73ce29f 100755 --- a/init.sh +++ b/init.sh @@ -56,7 +56,7 @@ else fi echo "Create cosmovisor directories" -mkdir "$LIKECOIN_LIKED_HOME/cosmovisor/upgrades" +mkdir -p "$LIKECOIN_LIKED_HOME/cosmovisor/upgrades" echo "" echo "Genesis file installed into .liked/config folder." From 227f8446aaa03b9e9be21986b01cf523f19882f3 Mon Sep 17 00:00:00 2001 From: Rico Date: Fri, 18 Feb 2022 21:23:02 +0800 Subject: [PATCH 07/27] docs: Add docker node setup instruction to node setup docs --- docs/node-setup.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/docs/node-setup.md b/docs/node-setup.md index 8696807497..cd85eb8c20 100644 --- a/docs/node-setup.md +++ b/docs/node-setup.md @@ -18,6 +18,29 @@ make -C deploy start-node **NOTE: If any existing liked instance is running, Please terminate them before starting a new node to prevent double signing** +## Docker + +**NOTE: The docker image has updated to be integrated with cosmovisor and is currently unsupported for Apple M1 ARM Macs.** + +### Setting up a full node + +1. Get the URL of the genesis file and other parameters (e.g. seed node) of the network. +2. Copy `.env.template` to `.env`, and also `docker-compose.yml.template` to `docker-compose.yml`. +3. Edit `.env` for config on `LIKECOIN_CHAIN_ID`, `LIKECOIN_MONIKER`, `LIKECOIN_GENESIS_URL` and `LIKECOIN_SEED_NODES`. See comments in the file. +4. Run `docker-compose run --rm init` to setup node data in `.liked` folder. +5. Run `docker-compose up -d` to start up the node and wait for synchronization. +6. Then you may check the logs by `docker-compose logs --tail 1000 -f`. + +### Setting up a validator node + +1. Setup a full node by following the section above. +2. Make sure the node is synchronized, by checking `localhost:26657/status` and see if `result.sync_info.catching_up` is `false`. +3. Setup validator key by `docker-compose run --rm liked-command keys add validator` and follow the instructions. This will generate a key named `validator` in the keystore. +4. Get the address and mnemonic words from the output of the command above. Jot down the address (`cosmos1...`) and backup the mnemonic words. +5. Get some LIKE in the address above. The LIKE tokens are needed for creating validator. +6. Run `docker-compose run --rm create-validator --amount --details
--commission-rate ` to create and activate validator. `` is the amount for self-delegation (e.g. `100000000000nanolike` for 100 LIKE), `
` is the introduction of the validator, `` is the commission you receive from delegators (e.g. `0.1` for 10%). +7. After sending the create validator transaction, your node should become a validator. + ## Starting node locally (Not recommended) If you wish to start the node locally, run the following commands From a745bdc4629c042f69c01e21687016543fcde575 Mon Sep 17 00:00:00 2001 From: Rick Mak Date: Tue, 22 Feb 2022 06:42:42 +0000 Subject: [PATCH 08/27] Move the setup notes to root folder --- docs/node-setup.md => SETUP.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename docs/node-setup.md => SETUP.md (100%) diff --git a/docs/node-setup.md b/SETUP.md similarity index 100% rename from docs/node-setup.md rename to SETUP.md From 33f65c3c1bf924dece8c926f13dd9df522c4516d Mon Sep 17 00:00:00 2001 From: Rick Mak Date: Tue, 22 Feb 2022 06:43:27 +0000 Subject: [PATCH 09/27] Remove the unused volume at docker-compose --- docker-compose.yml.template | 2 -- 1 file changed, 2 deletions(-) diff --git a/docker-compose.yml.template b/docker-compose.yml.template index abe0482111..f706df36f7 100644 --- a/docker-compose.yml.template +++ b/docker-compose.yml.template @@ -102,8 +102,6 @@ services: # 1. proposal ID # 2. vote option ("yes" / "no" / "veto" / "abstain") ] -volumes: - upgrades-volume: networks: default: name: likecoin-chain From cdd003b0b975f082fccd89ed8d2e6685b271630b Mon Sep 17 00:00:00 2001 From: Rick Mak Date: Tue, 22 Feb 2022 07:29:43 +0000 Subject: [PATCH 10/27] Update the SETUP.md for clearly stating the 3 way and respective use case --- SETUP.md | 67 +++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 45 insertions(+), 22 deletions(-) diff --git a/SETUP.md b/SETUP.md index cd85eb8c20..c697acaa92 100644 --- a/SETUP.md +++ b/SETUP.md @@ -1,11 +1,25 @@ # Node Setup -## Quickstart (Recommended) +This document describe how to setup cosmovisor and respective likecoin node. The intended audience is developer would like to test out locally. For a more validator production setup document, one should found at https://docs.like.co + +The developer team maintains 3 way on running the node software, they are: + +1. `systemd` based. +2. `docker` and `docker-compose` based. +3. Run at shell. + +It depends on the situation which one is better. Since the development resource is limiting, we are planning to drop maintaining `docker-compose` way. So if you are new to the ecosystem, I recommend to check out the `systemd` way. + +## systemd based, recommended + +Following is assuming your OS is Linux based with systemd installed. + +Following command will download a pre-compiled binary from Github. For compiling locally, please checkout `RELEASE.md` for details. To setup a node using our setup script, please run the following command in the project root folder ``` -MONIKER= make -C deploy setup-node +make -C deploy setup-node MONIKER=$MONIKER ``` After the initialization, you may run the following commands to start the node as a service. @@ -16,11 +30,35 @@ make -C deploy initialize-systemctl make -C deploy start-node ``` +Above command is warp around `systemctl`. For checking logs, you can run + +``` +journalctl -u liked.service -f +``` + +For more advance usage, please checkout the doc of `systemctl` and `journalctl`. + **NOTE: If any existing liked instance is running, Please terminate them before starting a new node to prevent double signing** -## Docker +For converting the full node into validator, you should able to interact with `liked` directly. -**NOTE: The docker image has updated to be integrated with cosmovisor and is currently unsupported for Apple M1 ARM Macs.** +### Advanced Setup + +By default, the [node-setup.sh](../deploy/scripts/node-setup.sh) script would download the latest cosmovisor and like binary to the working folder to setup the node automatically. Please refer to the table below for environment variables you can override. + +| Env | Description | Default | +| ------------------ | ----------------------------------------------------------------------------------- | ------------------------------------ | +| MONIKER | Moniker identifier for the node, this is mandatory for the node setup | Empty | +| LIKED_VERSION | Release version of the latest like binary | Latest tag using git describe --tags | +| COSMOVISOR_VERSION | Release version of the latest cosmovisor binary | 1.1.0 | +| LIKED_WORKDIR | Working directory, binaries will be downloaded here | $HOME | +| LIKED_HOME | Home directory for the like node, chain data and configurations will be stored here | $HOME/.liked | +| LIKED_USER | User used for 'liked.service' to run on behalf of | $USER | + + +## Docker based + +**NOTE: The docker image is only for amd64, arm(i.e. Apple M1) is currently unsupported.** ### Setting up a full node @@ -31,17 +69,17 @@ make -C deploy start-node 5. Run `docker-compose up -d` to start up the node and wait for synchronization. 6. Then you may check the logs by `docker-compose logs --tail 1000 -f`. -### Setting up a validator node +### Converting a full not into validator node 1. Setup a full node by following the section above. 2. Make sure the node is synchronized, by checking `localhost:26657/status` and see if `result.sync_info.catching_up` is `false`. 3. Setup validator key by `docker-compose run --rm liked-command keys add validator` and follow the instructions. This will generate a key named `validator` in the keystore. 4. Get the address and mnemonic words from the output of the command above. Jot down the address (`cosmos1...`) and backup the mnemonic words. -5. Get some LIKE in the address above. The LIKE tokens are needed for creating validator. +5. Deposit some LIKE in the above address. LIKE tokens are needed for creating validator. 6. Run `docker-compose run --rm create-validator --amount --details
--commission-rate ` to create and activate validator. `` is the amount for self-delegation (e.g. `100000000000nanolike` for 100 LIKE), `
` is the introduction of the validator, `` is the commission you receive from delegators (e.g. `0.1` for 10%). 7. After sending the create validator transaction, your node should become a validator. -## Starting node locally (Not recommended) +## Run node at shell locally for development or testing If you wish to start the node locally, run the following commands @@ -54,21 +92,6 @@ export DAEMON_HOME="$HOME/.liked" $(LIKED_WORKDIR)/cosmovisor run start ``` -**NOTE: This method does not restart the node automatically if the device is restarted under normal circumstances and is not recommended to be used as a validator node.** - -## Advanced Setup - -By default, the [node-setup.sh](../deploy/scripts/node-setup.sh) script would download the latest cosmovisor and like binary to the working folder to setup the node automatically. Please refer to the table below for environment variables you can override. - -| Env | Description | Default | -| ------------------ | ----------------------------------------------------------------------------------- | ------------------------------------ | -| MONIKER | Moniker identifier for the node, this is mandatory for the node setup | Empty | -| LIKED_VERSION | Release version of the latest like binary | Latest tag using git describe --tags | -| COSMOVISOR_VERSION | Release version of the latest cosmovisor binary | 1.1.0 | -| LIKED_WORKDIR | Working directory, binaries will be downloaded here | $HOME | -| LIKED_HOME | Home directory for the like node, chain data and configurations will be stored here | $HOME/.liked | -| LIKED_USER | User used for 'liked.service' to run on behalf of | $USER | - # Upgrades As a process manager, Cosmovisor automatically download and upgrade binary as upgrade proposals are approved on chain. From 7541860c4b32909b02346d1a21794904aee7a25f Mon Sep 17 00:00:00 2001 From: Rico Date: Mon, 14 Feb 2022 18:36:03 +0800 Subject: [PATCH 11/27] Add seed node support to the deployment script refs oursky/likecoin-chain#26 --- .gitignore | 1 - deploy/Makefile | 3 ++- deploy/liked.service.template | 2 +- deploy/scripts/node-setup.sh | 11 ++++++++--- 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index 6470900412..67cb17c42b 100644 --- a/.gitignore +++ b/.gitignore @@ -11,5 +11,4 @@ artifacts build dist release -dist/ deploy/liked.service diff --git a/deploy/Makefile b/deploy/Makefile index 5c1e398e9b..9db22131e4 100644 --- a/deploy/Makefile +++ b/deploy/Makefile @@ -1,6 +1,7 @@ LIKED_VERSION ?= $(shell git describe --tags --abbrev=0 | sed 's|v\(.*\)|\1|g') COSMOVISOR_VERSION ?= "1.1.0" MONIKER ?= "" +GENESIS_URL ?= "" LIKED_WORKDIR ?= $(HOME) LIKED_HOME ?= "$(LIKED_WORKDIR)/.liked" @@ -12,7 +13,7 @@ ifeq ($(MONIKER), "") @echo "Missing MONIKER env" @echo "Usage: MONIKER= make setup-node" else - LIKED_VERSION=$(LIKED_VERSION) COSMOVISOR_VERSION=$(COSMOVISOR_VERSION) ./scripts/node-setup.sh $(MONIKER) $(GENESIS_URL) $(LIKED_WORKDIR) $(LIKED_HOME) $(LIKED_USER) + LIKED_VERSION=$(LIKED_VERSION) COSMOVISOR_VERSION=$(COSMOVISOR_VERSION) ./scripts/node-setup.sh $(MONIKER) $(GENESIS_URL) $(LIKED_WORKDIR) $(LIKED_HOME) $(LIKED_USER) $(LIKED_SEED_NODES) endif .PHONY: initialize-systemctl diff --git a/deploy/liked.service.template b/deploy/liked.service.template index 093c675f4a..05bcf3367b 100644 --- a/deploy/liked.service.template +++ b/deploy/liked.service.template @@ -5,7 +5,7 @@ After=network.target [Service] User= WorkingDirectory= -ExecStart=/cosmovisor run --home /.liked start --rpc.laddr tcp://0.0.0.0:26657 --halt-time 0 --halt-height 0 +ExecStart=/cosmovisor run --home /.liked start --rpc.laddr tcp://0.0.0.0:26657 --p2p.seeds "" --halt-time 0 --halt-height 0 Restart=always RuntimeMaxSec=86400 Environment="DAEMON_NAME=liked" diff --git a/deploy/scripts/node-setup.sh b/deploy/scripts/node-setup.sh index 71d5603ca6..ad8ef76811 100755 --- a/deploy/scripts/node-setup.sh +++ b/deploy/scripts/node-setup.sh @@ -7,6 +7,7 @@ GENESIS_URL="$2" LIKED_WORKDIR="$3" LIKED_HOME="$4" LIKED_USER="$5" +LIKED_SEED_NODES="$6" if [ -z $MONIKER ]; then echo "Usage: $0 NODE_NAME " @@ -35,6 +36,10 @@ if [ -z $LIKED_HOME ]; then LIKED_HOME="${HOME}/.liked" fi +if [ ! -f "$LIKED_WORKDIR" ]; then + mkdir -p "$LIKED_WORKDIR" +fi + if [ ! -f "$LIKED_WORKDIR/cosmovisor" ]; then echo "Downloading the latest cosmovisor binary..." mkdir -p cosmovisor_temp @@ -50,7 +55,7 @@ if [ ! -f "$LIKED_WORKDIR/liked" ]; then mkdir -p liked_temp cd liked_temp curl -sL "https://github.com/likecoin/likecoin-chain/releases/download/v${LIKED_VERSION}/likecoin-chain_${LIKED_VERSION}_$(uname -s)_$(uname -m).tar.gz" | tar xz - cp bin/liked $LIKED_WORKDIR + cp bin/liked $LIKED_WORKDIR/liked cd .. rm -r liked_temp fi @@ -63,7 +68,7 @@ fi if [ ! -z $GENESIS_URL ]; then mkdir -p "$LIKED_HOME/config/" - curl -OL "$GENESIS_URL" + curl -o genesis.json -OL "$GENESIS_URL" mv -f "genesis.json" "$LIKED_HOME/config/genesis.json" CHAIN_ID=`grep chain_id "$LIKED_HOME/config/genesis.json" | sed 's/ *"chain_id": *"\(.*\)"/\1/g' | sed 's/,$//g'` else @@ -78,5 +83,5 @@ fi chown -R $LIKED_USER $LIKED_HOME -sed "s||$LIKED_USER|g; s||$LIKED_WORKDIR|g;" ./liked.service.template > ./liked.service +sed "s||$LIKED_USER|g; s||$LIKED_WORKDIR|g; s||$LIKED_SEED_NODES|g;" ./liked.service.template > ./liked.service echo "Setup complete, Please setup DAEMON_NAME and DAEMON_HOME environment variable and run 'cosmovisor run start' to start a node locally." \ No newline at end of file From 63e993241d29f3987454c0a0e16cf47373d23dbc Mon Sep 17 00:00:00 2001 From: Rico Date: Fri, 18 Feb 2022 02:05:29 +0800 Subject: [PATCH 12/27] Setup pulumi for azure node deployment refs oursky/likecoin-chain#24 --- deploy/.gitignore | 2 + deploy/Pulumi.yaml | 4 + deploy/README.md | 11 + deploy/cmd/azure/main.go | 376 +++++++++++++++++++++++++++++ deploy/go.mod | 11 + deploy/go.sum | 373 ++++++++++++++++++++++++++++ deploy/{scripts => }/node-setup.sh | 0 deploy/pkg/utils/hash/hash.go | 25 ++ 8 files changed, 802 insertions(+) create mode 100644 deploy/.gitignore create mode 100644 deploy/Pulumi.yaml create mode 100644 deploy/README.md create mode 100644 deploy/cmd/azure/main.go create mode 100644 deploy/go.mod create mode 100644 deploy/go.sum rename deploy/{scripts => }/node-setup.sh (100%) create mode 100644 deploy/pkg/utils/hash/hash.go diff --git a/deploy/.gitignore b/deploy/.gitignore new file mode 100644 index 0000000000..1e2fc11099 --- /dev/null +++ b/deploy/.gitignore @@ -0,0 +1,2 @@ +.vscode +Pulumi.*.yaml \ No newline at end of file diff --git a/deploy/Pulumi.yaml b/deploy/Pulumi.yaml new file mode 100644 index 0000000000..db988cac91 --- /dev/null +++ b/deploy/Pulumi.yaml @@ -0,0 +1,4 @@ +name: node-deployment +runtime: go +main: cmd/azure # TODO: Add support aws and gcp deployment +description: azure-node-deployment diff --git a/deploy/README.md b/deploy/README.md new file mode 100644 index 0000000000..23f5c4f515 --- /dev/null +++ b/deploy/README.md @@ -0,0 +1,11 @@ +# Setting up likecoin node on cloud services using Pulumi + +## Prerequisites + +- (Pulumi)[https://www.pulumi.com/docs/get-started/install/] +- Go 1.17+ +- Azure CLI (for azure nodes) + +## Setup + +### Azure diff --git a/deploy/cmd/azure/main.go b/deploy/cmd/azure/main.go new file mode 100644 index 0000000000..2c900ae86b --- /dev/null +++ b/deploy/cmd/azure/main.go @@ -0,0 +1,376 @@ +package main + +import ( + hashUtils "deploy/pkg/utils/hash" + "strings" + + "github.com/pulumi/pulumi-azure-native/sdk/go/azure/compute" + "github.com/pulumi/pulumi-azure-native/sdk/go/azure/network" + "github.com/pulumi/pulumi-azure-native/sdk/go/azure/resources" + "github.com/pulumi/pulumi-command/sdk/go/command/remote" + "github.com/pulumi/pulumi/sdk/v3/go/pulumi" + "github.com/pulumi/pulumi/sdk/v3/go/pulumi/config" +) + +func main() { + pulumi.Run(func(ctx *pulumi.Context) error { + cfg := config.New(ctx, "") + resourceGroupName := cfg.Require("resource-group-name") + vmUsername := cfg.Require("vm-username") + vmPassword := cfg.RequireSecret("vm-password") + publicKey := cfg.Require("vm-public-key") + privateKey := cfg.RequireSecret("vm-private-key") + sshAllowList := cfg.Require("vm-ssh-allow-list") + + genesisUrl := cfg.Require("node-genesis") + seeds := cfg.Require("node-seeds") + moniker := cfg.Require("node-moniker") + + stackName := ctx.Stack() + + var sshAllowCIDRs pulumi.StringArray + for _, cidr := range strings.Split(sshAllowList, ",") { + _cidr := pulumi.String(strings.TrimSpace(cidr)) + if len(_cidr) > 0 { + sshAllowCIDRs = append(sshAllowCIDRs, _cidr) + } + } + + // Locate an Azure Resource Group + resourceGroup, err := resources.LookupResourceGroup(ctx, &resources.LookupResourceGroupArgs{ + ResourceGroupName: resourceGroupName, + }) + if err != nil { + return err + } + + // Create network for VMs + virtualNetwork, err := network.NewVirtualNetwork( + ctx, + "Create Node Network", + &network.VirtualNetworkArgs{ + VirtualNetworkName: pulumi.Sprintf("vn-%s", stackName), + ResourceGroupName: pulumi.String(resourceGroup.Name), + AddressSpace: &network.AddressSpaceArgs{ + AddressPrefixes: pulumi.StringArray{ + pulumi.String("10.0.0.0/16"), + }, + }, + Subnets: network.SubnetTypeArray{ + network.SubnetTypeArgs{ + Name: pulumi.String("default"), + AddressPrefix: pulumi.String("10.0.1.0/24"), + }, + }, + }, + ) + if err != nil { + return err + } + + // Create public ip address + pubIp, err := network.NewPublicIPAddress(ctx, "Create Public IP Address", &network.PublicIPAddressArgs{ + PublicIpAddressName: pulumi.Sprintf("node-ip-%s", stackName), + ResourceGroupName: pulumi.String(resourceGroup.Name), + PublicIPAllocationMethod: pulumi.String(network.IPAllocationMethodDynamic), + }) + if err != nil { + return err + } + + sshSecurityRule := network.SecurityRuleTypeArgs{ + Access: pulumi.String(network.AccessAllow), + Protocol: pulumi.String("*"), + SourcePortRange: pulumi.String("*"), + DestinationAddressPrefix: pulumi.String("*"), + DestinationPortRange: pulumi.String("22"), + Direction: pulumi.String(network.SecurityRuleDirectionInbound), + Name: pulumi.Sprintf("ssh-inbound-%s", stackName), + Priority: pulumi.Int(102), + } + + if len(sshAllowCIDRs) > 0 { + sshSecurityRule.SourceAddressPrefixes = sshAllowCIDRs + } else { + sshSecurityRule.SourceAddressPrefix = pulumi.String("*") + } + // Create network security group + networkSg, err := network.NewNetworkSecurityGroup(ctx, "Create Network Security Group", &network.NetworkSecurityGroupArgs{ + NetworkSecurityGroupName: pulumi.Sprintf("network-sg-%s", stackName), + ResourceGroupName: pulumi.String(resourceGroup.Name), + SecurityRules: network.SecurityRuleTypeArray{ + // Inbound rule for rpc and peer connections + network.SecurityRuleTypeArgs{ + Access: pulumi.String(network.AccessAllow), + Protocol: pulumi.String("*"), + SourceAddressPrefix: pulumi.String("*"), + SourcePortRange: pulumi.String("*"), + DestinationAddressPrefix: pulumi.String("*"), + DestinationPortRange: pulumi.String("26656-26657"), + Direction: pulumi.String(network.SecurityRuleDirectionInbound), + Name: pulumi.Sprintf("network-inbound-%s", stackName), + Priority: pulumi.Int(100), + }, + // Outbound rule without port limit + network.SecurityRuleTypeArgs{ + Access: pulumi.String(network.AccessAllow), + Protocol: pulumi.String("*"), + SourceAddressPrefix: pulumi.String("*"), + SourcePortRange: pulumi.String("*"), + DestinationAddressPrefix: pulumi.String("*"), + DestinationPortRange: pulumi.String("*"), + Direction: pulumi.String(network.SecurityRuleDirectionOutbound), + Name: pulumi.Sprintf("network-outbound-%s", stackName), + Priority: pulumi.Int(101), + }, + sshSecurityRule, + }, + }) + if err != nil { + return err + } + + // Create network interface with previously created ip address and security group + networkIf, err := network.NewNetworkInterface(ctx, "Create Network Interface", &network.NetworkInterfaceArgs{ + NetworkInterfaceName: pulumi.Sprintf("network-if-%s", stackName), + ResourceGroupName: pulumi.String(resourceGroup.Name), + IpConfigurations: network.NetworkInterfaceIPConfigurationArray{ + network.NetworkInterfaceIPConfigurationArgs{ + Name: pulumi.Sprintf("node-ipcfg-%s", stackName), + PrivateIPAllocationMethod: pulumi.String(network.IPAllocationMethodDynamic), + Subnet: network.SubnetTypeArgs{ + Id: virtualNetwork.Subnets.Index(pulumi.Int(0)).Id(), + }, + PublicIPAddress: network.PublicIPAddressTypeArgs{ + Id: pubIp.ID(), + }, + }, + }, + NetworkSecurityGroup: network.NetworkSecurityGroupTypeArgs{ + Id: networkSg.ID(), + }, + }, pulumi.DependsOn([]pulumi.Resource{ + networkSg, + })) + if err != nil { + return err + } + + // Create virtual machine for node to run on + vm, err := compute.NewVirtualMachine(ctx, "Create Virtual Machine", &compute.VirtualMachineArgs{ + VmName: pulumi.Sprintf("node-vm-%s", stackName), + ResourceGroupName: pulumi.String(resourceGroup.Name), + NetworkProfile: compute.NetworkProfileArgs{ + NetworkInterfaces: compute.NetworkInterfaceReferenceArray{ + compute.NetworkInterfaceReferenceArgs{ + Id: networkIf.ID(), + Primary: pulumi.Bool(true), + }, + }, + }, + HardwareProfile: &compute.HardwareProfileArgs{ + VmSize: pulumi.String("Standard_B2s"), + }, + Location: pulumi.String(resourceGroup.Location), + OsProfile: &compute.OSProfileArgs{ + AdminUsername: pulumi.String(vmUsername), + AdminPassword: vmPassword, + ComputerName: pulumi.String(vmUsername), + LinuxConfiguration: &compute.LinuxConfigurationArgs{ + DisablePasswordAuthentication: pulumi.Bool(true), + PatchSettings: &compute.LinuxPatchSettingsArgs{ + AssessmentMode: pulumi.String(compute.LinuxPatchAssessmentModeImageDefault), + }, + ProvisionVMAgent: pulumi.Bool(true), + Ssh: &compute.SshConfigurationArgs{ + PublicKeys: &compute.SshPublicKeyTypeArray{ + compute.SshPublicKeyTypeArgs{ + KeyData: pulumi.String(publicKey), + Path: pulumi.Sprintf("/home/%s/.ssh/authorized_keys", vmUsername), + }, + }, + }, + }, + }, + StorageProfile: &compute.StorageProfileArgs{ + ImageReference: &compute.ImageReferenceArgs{ + Offer: pulumi.String("0001-com-ubuntu-server-focal"), + Publisher: pulumi.String("Canonical"), + Sku: pulumi.String("20_04-lts-gen2"), + Version: pulumi.String("latest"), + }, + OsDisk: &compute.OSDiskArgs{ + Caching: compute.CachingTypesReadWrite, + CreateOption: pulumi.String(compute.DiskCreateOptionFromImage), + ManagedDisk: &compute.ManagedDiskParametersArgs{ + StorageAccountType: pulumi.String(compute.StorageAccountType_Premium_LRS), + }, + Name: pulumi.Sprintf("node-vm-os-disk-%s", stackName), + DeleteOption: pulumi.String(compute.DeleteOptionsDelete), + }, + }, + }, pulumi.DependsOn([]pulumi.Resource{ + networkIf, + }), + ) + if err != nil { + return err + } + + // Ensure the resources are created first + ready := pulumi.All(vm.ID(), pubIp.Name, pulumi.String(resourceGroup.Name)) + + ipAddress := ready.ApplyT(func(args []interface{}) (string, error) { + name := args[1].(string) + resourceGroupName := args[2].(string) + ip, err := network.LookupPublicIPAddress(ctx, &network.LookupPublicIPAddressArgs{ + ResourceGroupName: resourceGroupName, + PublicIpAddressName: name, + }) + if err != nil { + return "", err + } + return *ip.IpAddress, nil + }).(pulumi.StringOutput) + + // TODO: Extract this part as it is common on all cloud services + // Send files and run commands to setup node + connection := remote.ConnectionArgs{ + Host: ipAddress, + User: pulumi.String(vmUsername), + PrivateKey: privateKey, + } + + scriptChange, err := hashUtils.GetFileHash("../../node-setup.sh") + if err != nil { + return err + } + + cpScript, err := remote.NewCopyFile(ctx, "Copy deployment script to VM", &remote.CopyFileArgs{ + Connection: connection, + LocalPath: pulumi.String("../../node-setup.sh"), + RemotePath: pulumi.Sprintf("/home/%s/node-setup.sh", vmUsername), + Triggers: pulumi.Array{ + pulumi.String(scriptChange), + }, + }, pulumi.DependsOn([]pulumi.Resource{ + vm, + pubIp, + })) + if err != nil { + return err + } + + chmodScript, err := remote.NewCommand(ctx, "Set deployment script permission", &remote.CommandArgs{ + Connection: connection, + Create: pulumi.Sprintf("chmod u+x /home/%s/node-setup.sh", vmUsername), + Triggers: pulumi.Array{ + pulumi.String(scriptChange), + }, + }, pulumi.DependsOn([]pulumi.Resource{ + cpScript, + })) + if err != nil { + return err + } + + serviceTemplateChange, err := hashUtils.GetFileHash("../../liked.service.template") + if err != nil { + return err + } + + cpService, err := remote.NewCopyFile(ctx, "Copy node service template to VM", &remote.CopyFileArgs{ + Connection: connection, + LocalPath: pulumi.String("../../liked.service.template"), + RemotePath: pulumi.Sprintf("/home/%s/liked.service.template", vmUsername), + Triggers: pulumi.Array{ + pulumi.String(serviceTemplateChange), + }, + }, pulumi.DependsOn([]pulumi.Resource{ + vm, + pubIp, + })) + if err != nil { + return err + } + + makeFileChange, err := hashUtils.GetFileHash("../../Makefile") + if err != nil { + return err + } + + cpMakefile, err := remote.NewCopyFile(ctx, "Copy Makefile to VM", &remote.CopyFileArgs{ + Connection: connection, + LocalPath: pulumi.String("../../Makefile"), + RemotePath: pulumi.Sprintf("/home/%s/Makefile", vmUsername), + Triggers: pulumi.Array{ + pulumi.String(makeFileChange), + }, + }, pulumi.DependsOn([]pulumi.Resource{ + vm, + pubIp, + })) + if err != nil { + return err + } + + installBuildEssentialsCommand, err := remote.NewCommand(ctx, "Install make on VM", &remote.CommandArgs{ + Connection: connection, + Create: pulumi.String("sudo apt install -y make"), + }, pulumi.DependsOn([]pulumi.Resource{ + cpScript, + cpService, + chmodScript, + cpMakefile, + })) + if err != nil { + return err + } + + setupNodeCommand, err := remote.NewCommand(ctx, "Execute setup node command", &remote.CommandArgs{ + Connection: connection, + Create: pulumi.Sprintf("MONIKER=%s LIKED_USER=%s LIKED_WORKDIR=/home/%s GENESIS_URL=%s LIKED_SEED_NODES=%s make setup-node", moniker, vmUsername, vmUsername, genesisUrl, seeds), + Triggers: pulumi.Array{ + pulumi.String(scriptChange), + pulumi.String(serviceTemplateChange), + pulumi.String(makeFileChange), + }, + }, pulumi.DependsOn([]pulumi.Resource{ + installBuildEssentialsCommand, + cpScript, + cpService, + chmodScript, + cpMakefile, + })) + if err != nil { + return err + } + + _, err = remote.NewCommand(ctx, "Execute initialize node service command", &remote.CommandArgs{ + Connection: connection, + Create: pulumi.String("make initialize-systemctl"), + Triggers: pulumi.Array{ + pulumi.String(scriptChange), + pulumi.String(serviceTemplateChange), + pulumi.String(makeFileChange), + }, + }, pulumi.DependsOn([]pulumi.Resource{ + installBuildEssentialsCommand, + setupNodeCommand, + cpScript, + cpService, + chmodScript, + cpMakefile, + })) + if err != nil { + return err + } + + ctx.Export("Stack Name", pulumi.String(stackName)) + ctx.Export("Virtual Machine ID", vm.ID()) + ctx.Export("Virtual Machine IP", ipAddress) + ctx.Export("SSH Endpoint", pulumi.Sprintf("%s@%s", vmUsername, ipAddress)) + + return nil + }) +} diff --git a/deploy/go.mod b/deploy/go.mod new file mode 100644 index 0000000000..ca6bd80ce9 --- /dev/null +++ b/deploy/go.mod @@ -0,0 +1,11 @@ +module deploy + +go 1.14 + +require ( + github.com/pulumi/pulumi-azure-native/sdk v1.55.0 + github.com/pulumi/pulumi-azure/sdk/v4 v4.37.0 + github.com/pulumi/pulumi-command/sdk v0.0.3 + github.com/pulumi/pulumi-tls/sdk/v4 v4.1.0 // indirect + github.com/pulumi/pulumi/sdk/v3 v3.24.1 +) diff --git a/deploy/go.sum b/deploy/go.sum new file mode 100644 index 0000000000..76698f2a5d --- /dev/null +++ b/deploy/go.sum @@ -0,0 +1,373 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs= +github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA= +github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= +github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= +github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/cheggaaa/pb v1.0.18 h1:G/DgkKaBP0V5lnBg/vx61nVxxAU+VqU5yMzSc0f2PPE= +github.com/cheggaaa/pb v1.0.18/go.mod h1:pQciLPpbU0oxA0h+VJYYLxO+XeDQb5pZijXscXHm81s= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd h1:qMd81Ts1T2OTKmB4acZcyKaMtRnY5Y44NuXGX2GFJ1w= +github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= +github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= +github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/djherbis/times v1.2.0 h1:xANXjsC/iBqbO00vkWlYwPWgBgEVU6m6AFYg0Pic+Mc= +github.com/djherbis/times v1.2.0/go.mod h1:CGMZlo255K5r4Yw0b9RRfFQpM2y7uOmxg4jm9HsaVf8= +github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg= +github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= +github.com/fatih/color v1.10.0 h1:s36xzo75JdqLaaWoiEHk767eHiwo0598uUxyfiPkDsg= +github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= +github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ= +github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0= +github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gofrs/flock v0.7.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= +github.com/gofrs/uuid v3.3.0+incompatible h1:8K4tyRfvU1CYPgJsveYFQMhpFd/wXNM7iK6rR7UHz84= +github.com/gofrs/uuid v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls= +github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1 h1:/exdXoGamhu5ONeUJH0deniYLWYvQwW66yvlfiiKTu0= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= +github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645 h1:MJG/KsmcqMwFAkh8mTnAwhyKoB+sTAnY4CACC110tbU= +github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645/go.mod h1:6iZfnjpejD4L/4DwD7NryNaJyCQdzwWwH2MWhCA90Kw= +github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd h1:Coekwdh0v2wtGp9Gmz1Ze3eVRAWJMLokvN3QjdzCHLY= +github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8= +github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= +github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-runewidth v0.0.8 h1:3tS41NlGYSmhhe/8fhGRzc+z3AYCw1Fe1WAyLuujKs0= +github.com/mattn/go-runewidth v0.0.8/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-ps v1.0.0 h1:i6ampVEEF4wQFF+bkYfwYgY+F/uYJDktmvLPf7qIgjc= +github.com/mitchellh/go-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN3nvg8Pg= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +github.com/opentracing/basictracer-go v1.0.0 h1:YyUAhaEfjoWXclZVJ9sGoNct7j4TVk7lZWlQw5UXuoo= +github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= +github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/pelletier/go-buffruneio v0.2.0/go.mod h1:JkE26KsDizTr40EUHkXVtNPvgGtbSNq5BcowyYOWdKo= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/pulumi/pulumi-azure-native/sdk v1.55.0 h1:C4gqeLpAzCRCkhNrR8ofBUiQiFGVGDHkjZKvYvfFpBU= +github.com/pulumi/pulumi-azure-native/sdk v1.55.0/go.mod h1:5l+UEpggoWApYLSHJO2GlzMyhopoHgtuDOGPQQ0fFE4= +github.com/pulumi/pulumi-azure/sdk/v4 v4.37.0 h1:7y+9qF+8KcdZPIGKebWnVWklwhaAKnPHa5f57r8dQo8= +github.com/pulumi/pulumi-azure/sdk/v4 v4.37.0/go.mod h1:qgdnvXf4sIcYXMKDArIZpu4qCnphTCMxnP10fvrUnQw= +github.com/pulumi/pulumi-command/sdk v0.0.3 h1:APhWyBSjCp94b5VTVPz0GwwhP//HT22CD7cBQ0JhAic= +github.com/pulumi/pulumi-command/sdk v0.0.3/go.mod h1:WtWndGuQusF2p68t6xEa9yQy6ObMJugKigB2hN4dzts= +github.com/pulumi/pulumi-tls/sdk/v4 v4.1.0 h1:revpmx5G08vdbqbMLtOmPkp3c/nXGiia6Z2MWWafH30= +github.com/pulumi/pulumi-tls/sdk/v4 v4.1.0/go.mod h1:MiYAhU5/WMZtTGRzNIN46eYKux9o4DUF0vnFlkB8cf0= +github.com/pulumi/pulumi/sdk/v3 v3.7.0/go.mod h1:GBHyQ7awNQSRmiKp/p8kIKrGrMOZeA/k2czoM/GOqds= +github.com/pulumi/pulumi/sdk/v3 v3.14.0/go.mod h1:aT7YmFdR6/T7tp2tMIZ68WRD1Xyv5a6Y4BhsuaCNpW0= +github.com/pulumi/pulumi/sdk/v3 v3.23.2 h1:m/YfyUsoeRFyHXDm2HtJhK+tBV58nrdmWsAkNQimRU4= +github.com/pulumi/pulumi/sdk/v3 v3.23.2/go.mod h1:WHOQB00iuHZyXhwrymxpKXhpOahSguJIpRjVokmM11w= +github.com/pulumi/pulumi/sdk/v3 v3.24.1 h1:Ywaih9y/zBfS8s4w6BtcsBF/rHQpGbbZ82oXwEVUfVI= +github.com/pulumi/pulumi/sdk/v3 v3.24.1/go.mod h1:WHOQB00iuHZyXhwrymxpKXhpOahSguJIpRjVokmM11w= +github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/rogpeppe/go-internal v1.8.1 h1:geMPLpDpQOgVyCg5z5GoRwLHepNdb71NXb67XFkP+Eg= +github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/sabhiram/go-gitignore v0.0.0-20180611051255-d3107576ba94 h1:G04eS0JkAIVZfaJLjla9dNxkJCPiKIGZlw9AfOhzOD0= +github.com/sabhiram/go-gitignore v0.0.0-20180611051255-d3107576ba94/go.mod h1:b18R55ulyQ/h3RaWyloPyER7fWQVZvimKKhnI5OfrJQ= +github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= +github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= +github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= +github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng= +github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v1.0.0 h1:6m/oheQuQ13N9ks4hubMG6BnvwOeaJrqSPLahSnczz8= +github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= +github.com/src-d/gcfg v1.4.0 h1:xXbNR5AlLSA315x2UO+fTSSAXCDf+Ar38/6oyGbDKQ4= +github.com/src-d/gcfg v1.4.0/go.mod h1:p/UMsR43ujA89BJY9duynAwIpvqEujIH/jFlfL7jWoI= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/texttheater/golang-levenshtein v0.0.0-20191208221605-eb6844b05fc6 h1:9VTskZOIRf2vKF3UL8TuWElry5pgUpV1tFSe/e/0m/E= +github.com/texttheater/golang-levenshtein v0.0.0-20191208221605-eb6844b05fc6/go.mod h1:XDKHRm5ThF8YJjx001LtgelzsoaEcvnA7lVWz9EeX3g= +github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/tweekmonster/luser v0.0.0-20161003172636-3fa38070dbd7 h1:X9dsIWPuuEJlPX//UmRKophhOKCGXc46RVIGuttks68= +github.com/tweekmonster/luser v0.0.0-20161003172636-3fa38070dbd7/go.mod h1:UxoP3EypF8JfGEjAII8jx1q8rQyDnX8qdTCs/UQBVIE= +github.com/uber/jaeger-client-go v2.22.1+incompatible h1:NHcubEkVbahf9t3p75TOCR83gdUHXjRJvjoBh1yACsM= +github.com/uber/jaeger-client-go v2.22.1+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= +github.com/uber/jaeger-lib v2.2.0+incompatible h1:MxZXOiR2JuoANZ3J6DE/U0kSFv/eJ/GfSYVCjK7dyaw= +github.com/uber/jaeger-lib v2.2.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= +github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= +github.com/xanzy/ssh-agent v0.2.1 h1:TCbipTQL2JiiCprBWx9frJ2eJlCYT00NmctrHxVAr70= +github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk= +go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200317142112-1b76d66859c6/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200602114024-627f9648deb9 h1:pNX+40auqi2JqRfOP1akLGtYcn15TUbkhwuCO3foqqM= +golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210817190340-bfb29a6856f2 h1:c8PlLMqBbOHoqtjteWm5/kbe6rNY2pbRfbIMVnepueo= +golang.org/x/sys v0.0.0-20210817190340-bfb29a6856f2/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190729092621-ff9f1409240a/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI= +golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200608174601-1b747fd94509 h1:MI14dOfl3OG6Zd32w3ugsrvcUO810fDZdWakTq39dH4= +golang.org/x/tools v0.0.0-20200608174601-1b747fd94509/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200608115520-7c474a2e3482 h1:i+Aiej6cta/Frzp13/swvwz5O00kYcSe0A/C5Wd7zX8= +google.golang.org/genproto v0.0.0-20200608115520-7c474a2e3482/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.29.1 h1:EC2SB8S04d2r73uptxphDSUG+kTKVgjRPF+N3xpxRB4= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0 h1:UhZDfRO8JRQru4/+LlLE0BRKGF8L+PICnvYZmx/fEGA= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/cheggaaa/pb.v1 v1.0.28 h1:n1tBJnnK2r7g9OW2btFH91V92STTUevLXYFb8gy9EMk= +gopkg.in/cheggaaa/pb.v1 v1.0.28/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/src-d/go-billy.v4 v4.3.2 h1:0SQA1pRztfTFx2miS8sA97XvooFeNOmvUenF4o0EcVg= +gopkg.in/src-d/go-billy.v4 v4.3.2/go.mod h1:nDjArDMp+XMs1aFAESLRjfGSgfvoYN0hDfzEk0GjC98= +gopkg.in/src-d/go-git-fixtures.v3 v3.5.0 h1:ivZFOIltbce2Mo8IjzUHAFoq/IylO9WHhNOAJK+LsJg= +gopkg.in/src-d/go-git-fixtures.v3 v3.5.0/go.mod h1:dLBcvytrw/TYZsNTWCnkNF2DSIlzWYqTe3rJR56Ac7g= +gopkg.in/src-d/go-git.v4 v4.13.1 h1:SRtFyV8Kxc0UP7aCHcijOMQGPxHSmMOPrzulQWolkYE= +gopkg.in/src-d/go-git.v4 v4.13.1/go.mod h1:nx5NYcxdKxq5fpltdHnPa2Exj4Sx0EclMWZQbYDu2z8= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= +gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +pgregory.net/rapid v0.4.7 h1:MTNRktPuv5FNqOO151TM9mDTa+XHcX6ypYeISDVD14g= +pgregory.net/rapid v0.4.7/go.mod h1:UYpPVyjFHzYBGHIxLFoupi8vwk6rXNzRY9OMvVxFIOU= +sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0 h1:ucqkfpjg9WzSUubAO62csmucvxl4/JeW3F4I4909XkM= +sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= diff --git a/deploy/scripts/node-setup.sh b/deploy/node-setup.sh similarity index 100% rename from deploy/scripts/node-setup.sh rename to deploy/node-setup.sh diff --git a/deploy/pkg/utils/hash/hash.go b/deploy/pkg/utils/hash/hash.go new file mode 100644 index 0000000000..cf6bf181e6 --- /dev/null +++ b/deploy/pkg/utils/hash/hash.go @@ -0,0 +1,25 @@ +package utils + +import ( + "crypto/md5" + "encoding/hex" + "io" + "os" +) + +func GetFileHash(filePath string) (string, error) { + file, err := os.Open(filePath) + if err != nil { + return "", err + } + + defer file.Close() + + hash := md5.New() + _, err = io.Copy(hash, file) + if err != nil { + return "", err + } + + return hex.EncodeToString(hash.Sum(nil)), nil +} From e1e1581b95f43fd44750d168f1138ee967ea5da2 Mon Sep 17 00:00:00 2001 From: Rico Wong Date: Mon, 21 Feb 2022 23:54:08 +0800 Subject: [PATCH 13/27] Add pulumi config template and related commands to Makefile refs oursky/likecoin-chain#24 --- deploy/Makefile | 21 +++++++++++++++++++-- deploy/Pulumi.config.yaml.template | 10 ++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 deploy/Pulumi.config.yaml.template diff --git a/deploy/Makefile b/deploy/Makefile index 9db22131e4..ece57943dc 100644 --- a/deploy/Makefile +++ b/deploy/Makefile @@ -1,4 +1,4 @@ -LIKED_VERSION ?= $(shell git describe --tags --abbrev=0 | sed 's|v\(.*\)|\1|g') +LIKED_VERSION ?= "1.2.0-rc3" COSMOVISOR_VERSION ?= "1.1.0" MONIKER ?= "" GENESIS_URL ?= "" @@ -7,13 +7,26 @@ LIKED_WORKDIR ?= $(HOME) LIKED_HOME ?= "$(LIKED_WORKDIR)/.liked" LIKED_USER ?= "$(USER)" +.PHONY: setup-pulumi +setup-pulumi: + pulumi stack init $(PULUMI_STACK) + cp ./Pulumi.config.yaml.template "./Pulumi.$(PULUMI_STACK).yaml" + +.PHONY: deploy +deploy: + pulumi up + +.PHONY: destroy +destroy: + pulumi destroy + .PHONY: setup-node setup-node: ifeq ($(MONIKER), "") @echo "Missing MONIKER env" @echo "Usage: MONIKER= make setup-node" else - LIKED_VERSION=$(LIKED_VERSION) COSMOVISOR_VERSION=$(COSMOVISOR_VERSION) ./scripts/node-setup.sh $(MONIKER) $(GENESIS_URL) $(LIKED_WORKDIR) $(LIKED_HOME) $(LIKED_USER) $(LIKED_SEED_NODES) + LIKED_VERSION=$(LIKED_VERSION) COSMOVISOR_VERSION=$(COSMOVISOR_VERSION) ./node-setup.sh $(MONIKER) "$(GENESIS_URL)" $(LIKED_WORKDIR) $(LIKED_HOME) $(LIKED_USER) "$(LIKED_SEED_NODES)" endif .PHONY: initialize-systemctl @@ -24,3 +37,7 @@ initialize-systemctl: .PHONY: start-node start-node: sudo systemctl start liked + +.PHONY: stop-node +stop-node: + sudo systemctl stop liked diff --git a/deploy/Pulumi.config.yaml.template b/deploy/Pulumi.config.yaml.template new file mode 100644 index 0000000000..2d9d763dcb --- /dev/null +++ b/deploy/Pulumi.config.yaml.template @@ -0,0 +1,10 @@ +config: + node-deployment:node-genesis: + node-deployment:node-moniker: likecoin + node-deployment:node-seeds: + node-deployment:resource-group-name: likecoin + node-deployment:vm-password: + node-deployment:vm-private-key: + node-deployment:vm-public-key: + node-deployment:vm-ssh-allow-list: + node-deployment:vm-username: likecoin From 397f25f56210514a47cda3a17b64a030fdaff76a Mon Sep 17 00:00:00 2001 From: Rico Wong Date: Mon, 21 Feb 2022 23:54:33 +0800 Subject: [PATCH 14/27] Add README for deployment instructions refs oursky/likecoin-chain#24 --- deploy/README.md | 97 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 93 insertions(+), 4 deletions(-) diff --git a/deploy/README.md b/deploy/README.md index 23f5c4f515..6a0f13ac7f 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -1,11 +1,100 @@ # Setting up likecoin node on cloud services using Pulumi -## Prerequisites +# Prerequisites -- (Pulumi)[https://www.pulumi.com/docs/get-started/install/] +- [Pulumi](https://www.pulumi.com/docs/get-started/install/) - Go 1.17+ - Azure CLI (for azure nodes) -## Setup +# Setup -### Azure +## Azure + +Login to Azure CLI and Pulumi CLI with the following commands + +``` +az login + +pulumi login +``` + +or if you wish to use Pulumi without an account in which you will need to enter a passphrase for secret storing + +``` +az login + +pulumi login --local +export PULUMI_CONFIG_PASSPHRASE= +``` + +Create a resource group on Azure with the following command + +``` +az group create --location --resource-group +``` + +Pulumi should be able to capture your login session and perform deployments on your behalf. + +Run the following command to setup a pulumi stack. + +``` +PULUMI_STACK= make setup-pulumi +``` + +This creates a config file `Pulumi..yaml` for your stack in which you will have to modify for the deployment to work. + +First, you can create a SSH keypair with the following command, we will be using RSA as per instructions provided by [Azure](https://docs.microsoft.com/en-us/azure/virtual-machines/linux/ssh-from-windows#create-an-ssh-key-pair). + +**Note: Azure Pulumi does not seem to work with keys that has a passphrase due to the prompt being missed out during deployment hence we will be using one with empty passphrase.** + +``` +ssh-keygen -t rsa -f rsa -m PEM +``` + +Run the following commands to setup configurations for your stack + +``` +pulumi config set node-deployment:resource-group-name +pulumi config set node-deployment:vm-password --secret + +cat rsa.pub | pulumi config set node-deployment:vm-public-key -- +cat rsa | pulumi config set node-deployment:vm-private-key --secret -- +``` + +You should now see the values being assigned in `Pulumi..yaml` + +You may now run the following command to execute the deployment + +``` +make deploy +``` + +Pulumi will execute a dry-run deployment to validate the deployment script, You may select `Yes` to confirm the deployment. + +After a successful deployment, connect to the virtual machine via SSH to the IP address output displayed on screen + +``` +ssh -i rsa @ +``` + +Simply run the following command to start the service + +``` +make start-node +``` + +## Configurations + +Pulumi stack configurations that is used by the deployment script + +| Configuration | Description | Mandatory | +| ----------------------------------- | -------------------------------------------- | --------- | +| node-deployment:node-genesis | URL to the genesis.json file | ❌ | +| node-deployment:node-moniker | Moniker identifier of the node | ✅ | +| node-deployment:node-seeds | Comma separated P2P Seed nodes | ❌ | +| node-deployment:resource-group-name | Resource group name for Azure | ✅ | +| node-deployment:vm-username | Admin username to the Virtual Machine | ✅ | +| node-deployment:vm-password | Admin password to the Virtual Machine | ✅ | +| node-deployment:vm-private-key | SSH private key to the Virtual Machine | ✅ | +| node-deployment:vm-public-key | SSH public key to the Virtual Machine | ✅ | +| node-deployment:vm-ssh-allow-list | Comma separated CIDR list for SSH white list | ❌ | From 2d7d7182143fbfdbc332d74d60baa277a6d2a0b0 Mon Sep 17 00:00:00 2001 From: Rick Mak Date: Tue, 22 Feb 2022 12:54:42 +0800 Subject: [PATCH 15/27] Update the deployment README and change name to easier to understand --- deploy/.gitignore | 3 +- deploy/Makefile | 19 ++++++-- deploy/Pulumi.config.yaml.template | 18 +++---- deploy/Pulumi.yaml | 4 +- deploy/README.md | 76 +++++++++++++++--------------- 5 files changed, 67 insertions(+), 53 deletions(-) diff --git a/deploy/.gitignore b/deploy/.gitignore index 1e2fc11099..1d6f73855b 100644 --- a/deploy/.gitignore +++ b/deploy/.gitignore @@ -1,2 +1,3 @@ .vscode -Pulumi.*.yaml \ No newline at end of file +Pulumi.*.yaml +id_rsa* diff --git a/deploy/Makefile b/deploy/Makefile index ece57943dc..f1e594d52b 100644 --- a/deploy/Makefile +++ b/deploy/Makefile @@ -6,19 +6,30 @@ GENESIS_URL ?= "" LIKED_WORKDIR ?= $(HOME) LIKED_HOME ?= "$(LIKED_WORKDIR)/.liked" LIKED_USER ?= "$(USER)" +STACK ?= validator .PHONY: setup-pulumi setup-pulumi: - pulumi stack init $(PULUMI_STACK) - cp ./Pulumi.config.yaml.template "./Pulumi.$(PULUMI_STACK).yaml" + pulumi stack init $(STACK) + cp ./Pulumi.config.yaml.template "./Pulumi.$(STACK).yaml" + +.PHONY: ssh-key +ssh-key: + ssh-keygen -t rsa -f id_rsa -m PEM + pulumi config set -s $(STACK) \ + likecoin-skynet:resource-group-name $(RESOURCE_GROUP) + pulumi config set -s $(STACK) \ + like-skynet:vm-password --secret $(PASSWORD) + cat id_rsa.pub | pulumi config set likecoin-skynet:vm-public-key -- + cat id_rsa | pulumi config set likecoin-skynet:vm-private-key --secret -- .PHONY: deploy deploy: - pulumi up + pulumi up -s $(STACK) .PHONY: destroy destroy: - pulumi destroy + pulumi destroy -s $(STACK) .PHONY: setup-node setup-node: diff --git a/deploy/Pulumi.config.yaml.template b/deploy/Pulumi.config.yaml.template index 2d9d763dcb..f4b20738ac 100644 --- a/deploy/Pulumi.config.yaml.template +++ b/deploy/Pulumi.config.yaml.template @@ -1,10 +1,10 @@ config: - node-deployment:node-genesis: - node-deployment:node-moniker: likecoin - node-deployment:node-seeds: - node-deployment:resource-group-name: likecoin - node-deployment:vm-password: - node-deployment:vm-private-key: - node-deployment:vm-public-key: - node-deployment:vm-ssh-allow-list: - node-deployment:vm-username: likecoin + likecoin-skynet:node-genesis: + likecoin-skynet:node-moniker: likecoin + likecoin-skynet:node-seeds: + likecoin-skynet:resource-group-name: likecoin + likecoin-skynet:vm-password: + likecoin-skynet:vm-private-key: + likecoin-skynet:vm-public-key: + likecoin-skynet:vm-ssh-allow-list: + likecoin-skynet:vm-username: likecoin diff --git a/deploy/Pulumi.yaml b/deploy/Pulumi.yaml index db988cac91..951be78d3f 100644 --- a/deploy/Pulumi.yaml +++ b/deploy/Pulumi.yaml @@ -1,4 +1,4 @@ -name: node-deployment +name: likecoin-skynet runtime: go main: cmd/azure # TODO: Add support aws and gcp deployment -description: azure-node-deployment +description: likecoin-skynet-deployment diff --git a/deploy/README.md b/deploy/README.md index 6a0f13ac7f..d138453a15 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -1,5 +1,7 @@ # Setting up likecoin node on cloud services using Pulumi +This document describe how to use Pulumi to set up devnet that support development work. Although it may use at production environment, it is not recommended. + # Prerequisites - [Pulumi](https://www.pulumi.com/docs/get-started/install/) @@ -8,73 +10,73 @@ # Setup -## Azure +## Account setup Login to Azure CLI and Pulumi CLI with the following commands ``` az login - pulumi login ``` -or if you wish to use Pulumi without an account in which you will need to enter a passphrase for secret storing +Alternatively you can explore local setup via , `pulumi login --local`. However, we are not going to cover in this document. -``` -az login +Pulumi will use the currently logged in session of `az` command to perform following action. Please use `az account --set` to correctly set the default account. -pulumi login --local -export PULUMI_CONFIG_PASSPHRASE= +## Environment and secret preparation + +Prepare the variable for ease of setup, we may want to change according to the current cloud/testnet situation. + +``` +export RESOURCE_GROUP=likecoin-skynet +export REGION=southeastasia +export PASSWORD=$(openssl rand -hex 10) +export STACK=validator +echo $PASSWORD ``` Create a resource group on Azure with the following command ``` -az group create --location --resource-group +az group create --location $REGION --resource-group $RESOURCE_GROUP ``` -Pulumi should be able to capture your login session and perform deployments on your behalf. - Run the following command to setup a pulumi stack. ``` -PULUMI_STACK= make setup-pulumi +make setup-pulumi STACK=$STACK ``` -This creates a config file `Pulumi..yaml` for your stack in which you will have to modify for the deployment to work. +This creates a file `Pulumi.$STACK.yaml` for our stack in which we will modify for configuring the deployment to work. -First, you can create a SSH keypair with the following command, we will be using RSA as per instructions provided by [Azure](https://docs.microsoft.com/en-us/azure/virtual-machines/linux/ssh-from-windows#create-an-ssh-key-pair). +We will create a SSH keypair with the following command, we will be using RSA as per instructions provided by [Azure](https://docs.microsoft.com/en-us/azure/virtual-machines/linux/ssh-from-windows#create-an-ssh-key-pair). **Note: Azure Pulumi does not seem to work with keys that has a passphrase due to the prompt being missed out during deployment hence we will be using one with empty passphrase.** -``` -ssh-keygen -t rsa -f rsa -m PEM -``` - -Run the following commands to setup configurations for your stack +Create deployment SSH key and inflate the respective value in `Pulmi.$STACK.yaml` ``` -pulumi config set node-deployment:resource-group-name -pulumi config set node-deployment:vm-password --secret - -cat rsa.pub | pulumi config set node-deployment:vm-public-key -- -cat rsa | pulumi config set node-deployment:vm-private-key --secret -- +make ssh-key ``` -You should now see the values being assigned in `Pulumi..yaml` +We should now see the values being assigned in `Pulumi.$STACK.yaml` + +## Provision of resources -You may now run the following command to execute the deployment +After Run the following command to execute the deployment ``` make deploy ``` -Pulumi will execute a dry-run deployment to validate the deployment script, You may select `Yes` to confirm the deployment. +Pulumi will execute a dry-run deployment to validate the deployment script, review and confirm the deployment. + +After a successful deployment, the public ID of the deploy vm should be printed on console. -After a successful deployment, connect to the virtual machine via SSH to the IP address output displayed on screen +We can connect to the virtual machine via SSH as follow. ``` -ssh -i rsa @ +ssh -i id_rsa likecoin@ ``` Simply run the following command to start the service @@ -89,12 +91,12 @@ Pulumi stack configurations that is used by the deployment script | Configuration | Description | Mandatory | | ----------------------------------- | -------------------------------------------- | --------- | -| node-deployment:node-genesis | URL to the genesis.json file | ❌ | -| node-deployment:node-moniker | Moniker identifier of the node | ✅ | -| node-deployment:node-seeds | Comma separated P2P Seed nodes | ❌ | -| node-deployment:resource-group-name | Resource group name for Azure | ✅ | -| node-deployment:vm-username | Admin username to the Virtual Machine | ✅ | -| node-deployment:vm-password | Admin password to the Virtual Machine | ✅ | -| node-deployment:vm-private-key | SSH private key to the Virtual Machine | ✅ | -| node-deployment:vm-public-key | SSH public key to the Virtual Machine | ✅ | -| node-deployment:vm-ssh-allow-list | Comma separated CIDR list for SSH white list | ❌ | +| likecoin-skynet:node-genesis | URL to the genesis.json file | ❌ | +| likecoin-skynet:node-moniker | Moniker identifier of the node | ✅ | +| likecoin-skynet:node-seeds | Comma separated P2P Seed nodes | ❌ | +| likecoin-skynet:resource-group-name | Resource group name for Azure | ✅ | +| likecoin-skynet:vm-username | Admin username to the Virtual Machine | ✅ | +| likecoin-skynet:vm-password | Admin password to the Virtual Machine | ✅ | +| likecoin-skynet:vm-private-key | SSH private key to the Virtual Machine | ✅ | +| likecoin-skynet:vm-public-key | SSH public key to the Virtual Machine | ✅ | +| likecoin-skynet:vm-ssh-allow-list | Comma separated CIDR list for SSH white list | ❌ | From baec49dbaaac13491a61d711920d30ac628df557 Mon Sep 17 00:00:00 2001 From: Rico Wong Date: Tue, 22 Feb 2022 11:44:30 +0800 Subject: [PATCH 16/27] Make VM Hardware and DiskSize customizable refs oursky/likecoin-chain#24 --- deploy/Pulumi.config.yaml.template | 2 ++ deploy/README.md | 24 +++++++++++++----------- deploy/cmd/azure/main.go | 11 +++++++++-- 3 files changed, 24 insertions(+), 13 deletions(-) diff --git a/deploy/Pulumi.config.yaml.template b/deploy/Pulumi.config.yaml.template index f4b20738ac..aee005517f 100644 --- a/deploy/Pulumi.config.yaml.template +++ b/deploy/Pulumi.config.yaml.template @@ -8,3 +8,5 @@ config: likecoin-skynet:vm-public-key: likecoin-skynet:vm-ssh-allow-list: likecoin-skynet:vm-username: likecoin + likecoin-skynet:vm-hardware: Standard_B2s + likecoin-skynet:vm-disk-size: 50 diff --git a/deploy/README.md b/deploy/README.md index d138453a15..11fc83fbc5 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -89,14 +89,16 @@ make start-node Pulumi stack configurations that is used by the deployment script -| Configuration | Description | Mandatory | -| ----------------------------------- | -------------------------------------------- | --------- | -| likecoin-skynet:node-genesis | URL to the genesis.json file | ❌ | -| likecoin-skynet:node-moniker | Moniker identifier of the node | ✅ | -| likecoin-skynet:node-seeds | Comma separated P2P Seed nodes | ❌ | -| likecoin-skynet:resource-group-name | Resource group name for Azure | ✅ | -| likecoin-skynet:vm-username | Admin username to the Virtual Machine | ✅ | -| likecoin-skynet:vm-password | Admin password to the Virtual Machine | ✅ | -| likecoin-skynet:vm-private-key | SSH private key to the Virtual Machine | ✅ | -| likecoin-skynet:vm-public-key | SSH public key to the Virtual Machine | ✅ | -| likecoin-skynet:vm-ssh-allow-list | Comma separated CIDR list for SSH white list | ❌ | +| Configuration | Description | Default | Mandatory | +| ----------------------------------- | ------------------------------------------------- | ------------ | --------- | +| likecoin-skynet:node-genesis | URL to the genesis.json file | | ❌ | +| likecoin-skynet:node-moniker | Moniker identifier of the node | likecoin | ✅ | +| likecoin-skynet:node-seeds | Comma separated P2P Seed nodes | | ❌ | +| likecoin-skynet:resource-group-name | Resource group name for Azure | | ✅ | +| likecoin-skynet:vm-username | Admin username to the Virtual Machine | likecoin | ✅ | +| likecoin-skynet:vm-password | Admin password to the Virtual Machine | | ✅ | +| likecoin-skynet:vm-private-key | SSH private key to the Virtual Machine | | ✅ | +| likecoin-skynet:vm-public-key | SSH public key to the Virtual Machine | | ✅ | +| likecoin-skynet:vm-hardware | Hardware model identifier for the Virtual Machine | Standard_B2s | ✅ | +| likecoin-skynet:vm-disk-size | Disk Size for the Virtual Machine | 50 | ✅ | +| likecoin-skynet:vm-ssh-allow-list | Comma separated CIDR list for SSH white list | | ❌ | diff --git a/deploy/cmd/azure/main.go b/deploy/cmd/azure/main.go index 2c900ae86b..551a5ac89d 100644 --- a/deploy/cmd/azure/main.go +++ b/deploy/cmd/azure/main.go @@ -22,6 +22,12 @@ func main() { privateKey := cfg.RequireSecret("vm-private-key") sshAllowList := cfg.Require("vm-ssh-allow-list") + vmHardware := cfg.Require("vm-hardware") + vmDiskSize := cfg.GetInt("vm-disk-size") + if vmDiskSize == 0 { + vmDiskSize = int(50) + } + genesisUrl := cfg.Require("node-genesis") seeds := cfg.Require("node-seeds") moniker := cfg.Require("node-moniker") @@ -169,7 +175,7 @@ func main() { }, }, HardwareProfile: &compute.HardwareProfileArgs{ - VmSize: pulumi.String("Standard_B2s"), + VmSize: pulumi.String(vmHardware), }, Location: pulumi.String(resourceGroup.Location), OsProfile: &compute.OSProfileArgs{ @@ -203,8 +209,9 @@ func main() { Caching: compute.CachingTypesReadWrite, CreateOption: pulumi.String(compute.DiskCreateOptionFromImage), ManagedDisk: &compute.ManagedDiskParametersArgs{ - StorageAccountType: pulumi.String(compute.StorageAccountType_Premium_LRS), + StorageAccountType: pulumi.String(compute.StorageAccountTypes_StandardSSD_LRS), }, + DiskSizeGB: pulumi.Int(vmDiskSize), Name: pulumi.Sprintf("node-vm-os-disk-%s", stackName), DeleteOption: pulumi.String(compute.DeleteOptionsDelete), }, From 424e81e22fcd6bb732238dd4986086e0c2d0938a Mon Sep 17 00:00:00 2001 From: Rico Wong Date: Tue, 22 Feb 2022 12:56:23 +0800 Subject: [PATCH 17/27] Separate Makefile and group assets into subdirectory refs oursky/likecoin#24 --- deploy/Makefile | 23 -------------- deploy/cmd/azure/assets/Makefile | 31 +++++++++++++++++++ .../azure/assets}/liked.service.template | 0 deploy/{ => cmd/azure/assets}/node-setup.sh | 0 deploy/cmd/azure/main.go | 12 +++---- 5 files changed, 37 insertions(+), 29 deletions(-) create mode 100644 deploy/cmd/azure/assets/Makefile rename deploy/{ => cmd/azure/assets}/liked.service.template (100%) rename deploy/{ => cmd/azure/assets}/node-setup.sh (100%) diff --git a/deploy/Makefile b/deploy/Makefile index f1e594d52b..68e092b3bc 100644 --- a/deploy/Makefile +++ b/deploy/Makefile @@ -1,4 +1,3 @@ -LIKED_VERSION ?= "1.2.0-rc3" COSMOVISOR_VERSION ?= "1.1.0" MONIKER ?= "" GENESIS_URL ?= "" @@ -30,25 +29,3 @@ deploy: .PHONY: destroy destroy: pulumi destroy -s $(STACK) - -.PHONY: setup-node -setup-node: -ifeq ($(MONIKER), "") - @echo "Missing MONIKER env" - @echo "Usage: MONIKER= make setup-node" -else - LIKED_VERSION=$(LIKED_VERSION) COSMOVISOR_VERSION=$(COSMOVISOR_VERSION) ./node-setup.sh $(MONIKER) "$(GENESIS_URL)" $(LIKED_WORKDIR) $(LIKED_HOME) $(LIKED_USER) "$(LIKED_SEED_NODES)" -endif - -.PHONY: initialize-systemctl -initialize-systemctl: - sudo cp ./liked.service /etc/systemd/system/liked.service - sudo systemctl daemon-reload - -.PHONY: start-node -start-node: - sudo systemctl start liked - -.PHONY: stop-node -stop-node: - sudo systemctl stop liked diff --git a/deploy/cmd/azure/assets/Makefile b/deploy/cmd/azure/assets/Makefile new file mode 100644 index 0000000000..632d22d67a --- /dev/null +++ b/deploy/cmd/azure/assets/Makefile @@ -0,0 +1,31 @@ + +LIKED_VERSION ?= "1.2.0-rc3" +COSMOVISOR_VERSION ?= "1.1.0" +MONIKER ?= "" +GENESIS_URL ?= "" + +LIKED_WORKDIR ?= $(HOME) +LIKED_HOME ?= "$(LIKED_WORKDIR)/.liked" +LIKED_USER ?= "$(USER)" + +.PHONY: setup-node +setup-node: +ifeq ($(MONIKER), "") + @echo "Missing MONIKER env" + @echo "Usage: MONIKER= make setup-node" +else + LIKED_VERSION=$(LIKED_VERSION) COSMOVISOR_VERSION=$(COSMOVISOR_VERSION) ./node-setup.sh $(MONIKER) "$(GENESIS_URL)" $(LIKED_WORKDIR) $(LIKED_HOME) $(LIKED_USER) "$(LIKED_SEED_NODES)" +endif + +.PHONY: initialize-systemctl +initialize-systemctl: + sudo cp ./liked.service /etc/systemd/system/liked.service + sudo systemctl daemon-reload + +.PHONY: start-node +start-node: + sudo systemctl start liked + +.PHONY: stop-node +stop-node: + sudo systemctl stop liked \ No newline at end of file diff --git a/deploy/liked.service.template b/deploy/cmd/azure/assets/liked.service.template similarity index 100% rename from deploy/liked.service.template rename to deploy/cmd/azure/assets/liked.service.template diff --git a/deploy/node-setup.sh b/deploy/cmd/azure/assets/node-setup.sh similarity index 100% rename from deploy/node-setup.sh rename to deploy/cmd/azure/assets/node-setup.sh diff --git a/deploy/cmd/azure/main.go b/deploy/cmd/azure/main.go index 551a5ac89d..ace79c94ea 100644 --- a/deploy/cmd/azure/main.go +++ b/deploy/cmd/azure/main.go @@ -248,14 +248,14 @@ func main() { PrivateKey: privateKey, } - scriptChange, err := hashUtils.GetFileHash("../../node-setup.sh") + scriptChange, err := hashUtils.GetFileHash("./assets/node-setup.sh") if err != nil { return err } cpScript, err := remote.NewCopyFile(ctx, "Copy deployment script to VM", &remote.CopyFileArgs{ Connection: connection, - LocalPath: pulumi.String("../../node-setup.sh"), + LocalPath: pulumi.String("./assets/node-setup.sh"), RemotePath: pulumi.Sprintf("/home/%s/node-setup.sh", vmUsername), Triggers: pulumi.Array{ pulumi.String(scriptChange), @@ -281,14 +281,14 @@ func main() { return err } - serviceTemplateChange, err := hashUtils.GetFileHash("../../liked.service.template") + serviceTemplateChange, err := hashUtils.GetFileHash("./assets/liked.service.template") if err != nil { return err } cpService, err := remote.NewCopyFile(ctx, "Copy node service template to VM", &remote.CopyFileArgs{ Connection: connection, - LocalPath: pulumi.String("../../liked.service.template"), + LocalPath: pulumi.String("./assets/liked.service.template"), RemotePath: pulumi.Sprintf("/home/%s/liked.service.template", vmUsername), Triggers: pulumi.Array{ pulumi.String(serviceTemplateChange), @@ -301,14 +301,14 @@ func main() { return err } - makeFileChange, err := hashUtils.GetFileHash("../../Makefile") + makeFileChange, err := hashUtils.GetFileHash("./assets/Makefile") if err != nil { return err } cpMakefile, err := remote.NewCopyFile(ctx, "Copy Makefile to VM", &remote.CopyFileArgs{ Connection: connection, - LocalPath: pulumi.String("../../Makefile"), + LocalPath: pulumi.String("./assets/Makefile"), RemotePath: pulumi.Sprintf("/home/%s/Makefile", vmUsername), Triggers: pulumi.Array{ pulumi.String(makeFileChange), From 3d844c86fc14d1431702e88072dd75680e41fcb8 Mon Sep 17 00:00:00 2001 From: Rico Wong Date: Tue, 22 Feb 2022 15:06:16 +0800 Subject: [PATCH 18/27] Make likecoin repo source an environment variable for deployment script refs oursky/likecoin-chain#24 --- deploy/cmd/azure/assets/Makefile | 3 ++- deploy/cmd/azure/assets/node-setup.sh | 6 +++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/deploy/cmd/azure/assets/Makefile b/deploy/cmd/azure/assets/Makefile index 632d22d67a..367faf2149 100644 --- a/deploy/cmd/azure/assets/Makefile +++ b/deploy/cmd/azure/assets/Makefile @@ -7,6 +7,7 @@ GENESIS_URL ?= "" LIKED_WORKDIR ?= $(HOME) LIKED_HOME ?= "$(LIKED_WORKDIR)/.liked" LIKED_USER ?= "$(USER)" +LIKED_REPO_SOURCE ?= "likecoin" .PHONY: setup-node setup-node: @@ -14,7 +15,7 @@ ifeq ($(MONIKER), "") @echo "Missing MONIKER env" @echo "Usage: MONIKER= make setup-node" else - LIKED_VERSION=$(LIKED_VERSION) COSMOVISOR_VERSION=$(COSMOVISOR_VERSION) ./node-setup.sh $(MONIKER) "$(GENESIS_URL)" $(LIKED_WORKDIR) $(LIKED_HOME) $(LIKED_USER) "$(LIKED_SEED_NODES)" + LIKED_VERSION=$(LIKED_VERSION) COSMOVISOR_VERSION=$(COSMOVISOR_VERSION) LIKED_REPO_SOURCE=$(LIKED_REPO_SOURCE) ./node-setup.sh $(MONIKER) "$(GENESIS_URL)" $(LIKED_WORKDIR) $(LIKED_HOME) $(LIKED_USER) "$(LIKED_SEED_NODES)" endif .PHONY: initialize-systemctl diff --git a/deploy/cmd/azure/assets/node-setup.sh b/deploy/cmd/azure/assets/node-setup.sh index ad8ef76811..5eb5eae349 100755 --- a/deploy/cmd/azure/assets/node-setup.sh +++ b/deploy/cmd/azure/assets/node-setup.sh @@ -16,6 +16,10 @@ if [ -z $MONIKER ]; then exit 1 fi +if [ -z $LIKED_REPO_SOURCE ]; then + LIKED_REPO_SOURCE="likecoin" +fi + if [ -z $LIKED_VERSION ]; then LIKED_VERSION="2.0.0-alpha" fi @@ -54,7 +58,7 @@ if [ ! -f "$LIKED_WORKDIR/liked" ]; then echo "Downloading the latest liked binary..." mkdir -p liked_temp cd liked_temp - curl -sL "https://github.com/likecoin/likecoin-chain/releases/download/v${LIKED_VERSION}/likecoin-chain_${LIKED_VERSION}_$(uname -s)_$(uname -m).tar.gz" | tar xz + curl -sL "https://github.com/${LIKED_REPO_SOURCE}/likecoin-chain/releases/download/v${LIKED_VERSION}/likecoin-chain_${LIKED_VERSION}_$(uname -s)_$(uname -m).tar.gz" | tar xz cp bin/liked $LIKED_WORKDIR/liked cd .. rm -r liked_temp From 16c7b1fd7058f39774dc8034bbd14a0db657d614 Mon Sep 17 00:00:00 2001 From: Rico Wong Date: Tue, 22 Feb 2022 02:22:47 +0800 Subject: [PATCH 19/27] Extract Azure related function as a separated deployment module refs oursky/likecoin-chain#24 --- deploy/Makefile | 7 - deploy/Pulumi.yaml | 2 +- deploy/cmd/azure/main.go | 383 ------------------ deploy/cmd/{azure => deploy}/assets/Makefile | 0 .../assets/liked.service.template | 0 .../{azure => deploy}/assets/node-setup.sh | 0 deploy/cmd/deploy/main.go | 159 ++++++++ deploy/pkg/providers/azure/azure.go | 245 +++++++++++ deploy/pkg/providers/provider.go | 28 ++ 9 files changed, 433 insertions(+), 391 deletions(-) delete mode 100644 deploy/cmd/azure/main.go rename deploy/cmd/{azure => deploy}/assets/Makefile (100%) rename deploy/cmd/{azure => deploy}/assets/liked.service.template (100%) rename deploy/cmd/{azure => deploy}/assets/node-setup.sh (100%) create mode 100644 deploy/cmd/deploy/main.go create mode 100644 deploy/pkg/providers/azure/azure.go create mode 100644 deploy/pkg/providers/provider.go diff --git a/deploy/Makefile b/deploy/Makefile index 68e092b3bc..becd446624 100644 --- a/deploy/Makefile +++ b/deploy/Makefile @@ -1,10 +1,3 @@ -COSMOVISOR_VERSION ?= "1.1.0" -MONIKER ?= "" -GENESIS_URL ?= "" - -LIKED_WORKDIR ?= $(HOME) -LIKED_HOME ?= "$(LIKED_WORKDIR)/.liked" -LIKED_USER ?= "$(USER)" STACK ?= validator .PHONY: setup-pulumi diff --git a/deploy/Pulumi.yaml b/deploy/Pulumi.yaml index 951be78d3f..f13f4ff271 100644 --- a/deploy/Pulumi.yaml +++ b/deploy/Pulumi.yaml @@ -1,4 +1,4 @@ name: likecoin-skynet runtime: go -main: cmd/azure # TODO: Add support aws and gcp deployment +main: cmd/deploy # TODO: Add support aws and gcp deployment description: likecoin-skynet-deployment diff --git a/deploy/cmd/azure/main.go b/deploy/cmd/azure/main.go deleted file mode 100644 index ace79c94ea..0000000000 --- a/deploy/cmd/azure/main.go +++ /dev/null @@ -1,383 +0,0 @@ -package main - -import ( - hashUtils "deploy/pkg/utils/hash" - "strings" - - "github.com/pulumi/pulumi-azure-native/sdk/go/azure/compute" - "github.com/pulumi/pulumi-azure-native/sdk/go/azure/network" - "github.com/pulumi/pulumi-azure-native/sdk/go/azure/resources" - "github.com/pulumi/pulumi-command/sdk/go/command/remote" - "github.com/pulumi/pulumi/sdk/v3/go/pulumi" - "github.com/pulumi/pulumi/sdk/v3/go/pulumi/config" -) - -func main() { - pulumi.Run(func(ctx *pulumi.Context) error { - cfg := config.New(ctx, "") - resourceGroupName := cfg.Require("resource-group-name") - vmUsername := cfg.Require("vm-username") - vmPassword := cfg.RequireSecret("vm-password") - publicKey := cfg.Require("vm-public-key") - privateKey := cfg.RequireSecret("vm-private-key") - sshAllowList := cfg.Require("vm-ssh-allow-list") - - vmHardware := cfg.Require("vm-hardware") - vmDiskSize := cfg.GetInt("vm-disk-size") - if vmDiskSize == 0 { - vmDiskSize = int(50) - } - - genesisUrl := cfg.Require("node-genesis") - seeds := cfg.Require("node-seeds") - moniker := cfg.Require("node-moniker") - - stackName := ctx.Stack() - - var sshAllowCIDRs pulumi.StringArray - for _, cidr := range strings.Split(sshAllowList, ",") { - _cidr := pulumi.String(strings.TrimSpace(cidr)) - if len(_cidr) > 0 { - sshAllowCIDRs = append(sshAllowCIDRs, _cidr) - } - } - - // Locate an Azure Resource Group - resourceGroup, err := resources.LookupResourceGroup(ctx, &resources.LookupResourceGroupArgs{ - ResourceGroupName: resourceGroupName, - }) - if err != nil { - return err - } - - // Create network for VMs - virtualNetwork, err := network.NewVirtualNetwork( - ctx, - "Create Node Network", - &network.VirtualNetworkArgs{ - VirtualNetworkName: pulumi.Sprintf("vn-%s", stackName), - ResourceGroupName: pulumi.String(resourceGroup.Name), - AddressSpace: &network.AddressSpaceArgs{ - AddressPrefixes: pulumi.StringArray{ - pulumi.String("10.0.0.0/16"), - }, - }, - Subnets: network.SubnetTypeArray{ - network.SubnetTypeArgs{ - Name: pulumi.String("default"), - AddressPrefix: pulumi.String("10.0.1.0/24"), - }, - }, - }, - ) - if err != nil { - return err - } - - // Create public ip address - pubIp, err := network.NewPublicIPAddress(ctx, "Create Public IP Address", &network.PublicIPAddressArgs{ - PublicIpAddressName: pulumi.Sprintf("node-ip-%s", stackName), - ResourceGroupName: pulumi.String(resourceGroup.Name), - PublicIPAllocationMethod: pulumi.String(network.IPAllocationMethodDynamic), - }) - if err != nil { - return err - } - - sshSecurityRule := network.SecurityRuleTypeArgs{ - Access: pulumi.String(network.AccessAllow), - Protocol: pulumi.String("*"), - SourcePortRange: pulumi.String("*"), - DestinationAddressPrefix: pulumi.String("*"), - DestinationPortRange: pulumi.String("22"), - Direction: pulumi.String(network.SecurityRuleDirectionInbound), - Name: pulumi.Sprintf("ssh-inbound-%s", stackName), - Priority: pulumi.Int(102), - } - - if len(sshAllowCIDRs) > 0 { - sshSecurityRule.SourceAddressPrefixes = sshAllowCIDRs - } else { - sshSecurityRule.SourceAddressPrefix = pulumi.String("*") - } - // Create network security group - networkSg, err := network.NewNetworkSecurityGroup(ctx, "Create Network Security Group", &network.NetworkSecurityGroupArgs{ - NetworkSecurityGroupName: pulumi.Sprintf("network-sg-%s", stackName), - ResourceGroupName: pulumi.String(resourceGroup.Name), - SecurityRules: network.SecurityRuleTypeArray{ - // Inbound rule for rpc and peer connections - network.SecurityRuleTypeArgs{ - Access: pulumi.String(network.AccessAllow), - Protocol: pulumi.String("*"), - SourceAddressPrefix: pulumi.String("*"), - SourcePortRange: pulumi.String("*"), - DestinationAddressPrefix: pulumi.String("*"), - DestinationPortRange: pulumi.String("26656-26657"), - Direction: pulumi.String(network.SecurityRuleDirectionInbound), - Name: pulumi.Sprintf("network-inbound-%s", stackName), - Priority: pulumi.Int(100), - }, - // Outbound rule without port limit - network.SecurityRuleTypeArgs{ - Access: pulumi.String(network.AccessAllow), - Protocol: pulumi.String("*"), - SourceAddressPrefix: pulumi.String("*"), - SourcePortRange: pulumi.String("*"), - DestinationAddressPrefix: pulumi.String("*"), - DestinationPortRange: pulumi.String("*"), - Direction: pulumi.String(network.SecurityRuleDirectionOutbound), - Name: pulumi.Sprintf("network-outbound-%s", stackName), - Priority: pulumi.Int(101), - }, - sshSecurityRule, - }, - }) - if err != nil { - return err - } - - // Create network interface with previously created ip address and security group - networkIf, err := network.NewNetworkInterface(ctx, "Create Network Interface", &network.NetworkInterfaceArgs{ - NetworkInterfaceName: pulumi.Sprintf("network-if-%s", stackName), - ResourceGroupName: pulumi.String(resourceGroup.Name), - IpConfigurations: network.NetworkInterfaceIPConfigurationArray{ - network.NetworkInterfaceIPConfigurationArgs{ - Name: pulumi.Sprintf("node-ipcfg-%s", stackName), - PrivateIPAllocationMethod: pulumi.String(network.IPAllocationMethodDynamic), - Subnet: network.SubnetTypeArgs{ - Id: virtualNetwork.Subnets.Index(pulumi.Int(0)).Id(), - }, - PublicIPAddress: network.PublicIPAddressTypeArgs{ - Id: pubIp.ID(), - }, - }, - }, - NetworkSecurityGroup: network.NetworkSecurityGroupTypeArgs{ - Id: networkSg.ID(), - }, - }, pulumi.DependsOn([]pulumi.Resource{ - networkSg, - })) - if err != nil { - return err - } - - // Create virtual machine for node to run on - vm, err := compute.NewVirtualMachine(ctx, "Create Virtual Machine", &compute.VirtualMachineArgs{ - VmName: pulumi.Sprintf("node-vm-%s", stackName), - ResourceGroupName: pulumi.String(resourceGroup.Name), - NetworkProfile: compute.NetworkProfileArgs{ - NetworkInterfaces: compute.NetworkInterfaceReferenceArray{ - compute.NetworkInterfaceReferenceArgs{ - Id: networkIf.ID(), - Primary: pulumi.Bool(true), - }, - }, - }, - HardwareProfile: &compute.HardwareProfileArgs{ - VmSize: pulumi.String(vmHardware), - }, - Location: pulumi.String(resourceGroup.Location), - OsProfile: &compute.OSProfileArgs{ - AdminUsername: pulumi.String(vmUsername), - AdminPassword: vmPassword, - ComputerName: pulumi.String(vmUsername), - LinuxConfiguration: &compute.LinuxConfigurationArgs{ - DisablePasswordAuthentication: pulumi.Bool(true), - PatchSettings: &compute.LinuxPatchSettingsArgs{ - AssessmentMode: pulumi.String(compute.LinuxPatchAssessmentModeImageDefault), - }, - ProvisionVMAgent: pulumi.Bool(true), - Ssh: &compute.SshConfigurationArgs{ - PublicKeys: &compute.SshPublicKeyTypeArray{ - compute.SshPublicKeyTypeArgs{ - KeyData: pulumi.String(publicKey), - Path: pulumi.Sprintf("/home/%s/.ssh/authorized_keys", vmUsername), - }, - }, - }, - }, - }, - StorageProfile: &compute.StorageProfileArgs{ - ImageReference: &compute.ImageReferenceArgs{ - Offer: pulumi.String("0001-com-ubuntu-server-focal"), - Publisher: pulumi.String("Canonical"), - Sku: pulumi.String("20_04-lts-gen2"), - Version: pulumi.String("latest"), - }, - OsDisk: &compute.OSDiskArgs{ - Caching: compute.CachingTypesReadWrite, - CreateOption: pulumi.String(compute.DiskCreateOptionFromImage), - ManagedDisk: &compute.ManagedDiskParametersArgs{ - StorageAccountType: pulumi.String(compute.StorageAccountTypes_StandardSSD_LRS), - }, - DiskSizeGB: pulumi.Int(vmDiskSize), - Name: pulumi.Sprintf("node-vm-os-disk-%s", stackName), - DeleteOption: pulumi.String(compute.DeleteOptionsDelete), - }, - }, - }, pulumi.DependsOn([]pulumi.Resource{ - networkIf, - }), - ) - if err != nil { - return err - } - - // Ensure the resources are created first - ready := pulumi.All(vm.ID(), pubIp.Name, pulumi.String(resourceGroup.Name)) - - ipAddress := ready.ApplyT(func(args []interface{}) (string, error) { - name := args[1].(string) - resourceGroupName := args[2].(string) - ip, err := network.LookupPublicIPAddress(ctx, &network.LookupPublicIPAddressArgs{ - ResourceGroupName: resourceGroupName, - PublicIpAddressName: name, - }) - if err != nil { - return "", err - } - return *ip.IpAddress, nil - }).(pulumi.StringOutput) - - // TODO: Extract this part as it is common on all cloud services - // Send files and run commands to setup node - connection := remote.ConnectionArgs{ - Host: ipAddress, - User: pulumi.String(vmUsername), - PrivateKey: privateKey, - } - - scriptChange, err := hashUtils.GetFileHash("./assets/node-setup.sh") - if err != nil { - return err - } - - cpScript, err := remote.NewCopyFile(ctx, "Copy deployment script to VM", &remote.CopyFileArgs{ - Connection: connection, - LocalPath: pulumi.String("./assets/node-setup.sh"), - RemotePath: pulumi.Sprintf("/home/%s/node-setup.sh", vmUsername), - Triggers: pulumi.Array{ - pulumi.String(scriptChange), - }, - }, pulumi.DependsOn([]pulumi.Resource{ - vm, - pubIp, - })) - if err != nil { - return err - } - - chmodScript, err := remote.NewCommand(ctx, "Set deployment script permission", &remote.CommandArgs{ - Connection: connection, - Create: pulumi.Sprintf("chmod u+x /home/%s/node-setup.sh", vmUsername), - Triggers: pulumi.Array{ - pulumi.String(scriptChange), - }, - }, pulumi.DependsOn([]pulumi.Resource{ - cpScript, - })) - if err != nil { - return err - } - - serviceTemplateChange, err := hashUtils.GetFileHash("./assets/liked.service.template") - if err != nil { - return err - } - - cpService, err := remote.NewCopyFile(ctx, "Copy node service template to VM", &remote.CopyFileArgs{ - Connection: connection, - LocalPath: pulumi.String("./assets/liked.service.template"), - RemotePath: pulumi.Sprintf("/home/%s/liked.service.template", vmUsername), - Triggers: pulumi.Array{ - pulumi.String(serviceTemplateChange), - }, - }, pulumi.DependsOn([]pulumi.Resource{ - vm, - pubIp, - })) - if err != nil { - return err - } - - makeFileChange, err := hashUtils.GetFileHash("./assets/Makefile") - if err != nil { - return err - } - - cpMakefile, err := remote.NewCopyFile(ctx, "Copy Makefile to VM", &remote.CopyFileArgs{ - Connection: connection, - LocalPath: pulumi.String("./assets/Makefile"), - RemotePath: pulumi.Sprintf("/home/%s/Makefile", vmUsername), - Triggers: pulumi.Array{ - pulumi.String(makeFileChange), - }, - }, pulumi.DependsOn([]pulumi.Resource{ - vm, - pubIp, - })) - if err != nil { - return err - } - - installBuildEssentialsCommand, err := remote.NewCommand(ctx, "Install make on VM", &remote.CommandArgs{ - Connection: connection, - Create: pulumi.String("sudo apt install -y make"), - }, pulumi.DependsOn([]pulumi.Resource{ - cpScript, - cpService, - chmodScript, - cpMakefile, - })) - if err != nil { - return err - } - - setupNodeCommand, err := remote.NewCommand(ctx, "Execute setup node command", &remote.CommandArgs{ - Connection: connection, - Create: pulumi.Sprintf("MONIKER=%s LIKED_USER=%s LIKED_WORKDIR=/home/%s GENESIS_URL=%s LIKED_SEED_NODES=%s make setup-node", moniker, vmUsername, vmUsername, genesisUrl, seeds), - Triggers: pulumi.Array{ - pulumi.String(scriptChange), - pulumi.String(serviceTemplateChange), - pulumi.String(makeFileChange), - }, - }, pulumi.DependsOn([]pulumi.Resource{ - installBuildEssentialsCommand, - cpScript, - cpService, - chmodScript, - cpMakefile, - })) - if err != nil { - return err - } - - _, err = remote.NewCommand(ctx, "Execute initialize node service command", &remote.CommandArgs{ - Connection: connection, - Create: pulumi.String("make initialize-systemctl"), - Triggers: pulumi.Array{ - pulumi.String(scriptChange), - pulumi.String(serviceTemplateChange), - pulumi.String(makeFileChange), - }, - }, pulumi.DependsOn([]pulumi.Resource{ - installBuildEssentialsCommand, - setupNodeCommand, - cpScript, - cpService, - chmodScript, - cpMakefile, - })) - if err != nil { - return err - } - - ctx.Export("Stack Name", pulumi.String(stackName)) - ctx.Export("Virtual Machine ID", vm.ID()) - ctx.Export("Virtual Machine IP", ipAddress) - ctx.Export("SSH Endpoint", pulumi.Sprintf("%s@%s", vmUsername, ipAddress)) - - return nil - }) -} diff --git a/deploy/cmd/azure/assets/Makefile b/deploy/cmd/deploy/assets/Makefile similarity index 100% rename from deploy/cmd/azure/assets/Makefile rename to deploy/cmd/deploy/assets/Makefile diff --git a/deploy/cmd/azure/assets/liked.service.template b/deploy/cmd/deploy/assets/liked.service.template similarity index 100% rename from deploy/cmd/azure/assets/liked.service.template rename to deploy/cmd/deploy/assets/liked.service.template diff --git a/deploy/cmd/azure/assets/node-setup.sh b/deploy/cmd/deploy/assets/node-setup.sh similarity index 100% rename from deploy/cmd/azure/assets/node-setup.sh rename to deploy/cmd/deploy/assets/node-setup.sh diff --git a/deploy/cmd/deploy/main.go b/deploy/cmd/deploy/main.go new file mode 100644 index 0000000000..82938190e2 --- /dev/null +++ b/deploy/cmd/deploy/main.go @@ -0,0 +1,159 @@ +package main + +import ( + providers "deploy/pkg/providers" + hashUtils "deploy/pkg/utils/hash" + + "github.com/pulumi/pulumi-command/sdk/go/command/remote" + "github.com/pulumi/pulumi/sdk/v3/go/pulumi" + "github.com/pulumi/pulumi/sdk/v3/go/pulumi/config" +) + +func main() { + pulumi.Run(func(ctx *pulumi.Context) error { + cfg := config.New(ctx, "") + + cloudProviderName := cfg.Require("cloud-provider") + + vmUsername := cfg.Require("vm-username") + genesisUrl := cfg.Require("node-genesis") + seeds := cfg.Require("node-seeds") + moniker := cfg.Require("node-moniker") + + stackName := ctx.Stack() + + cloudProvider := providers.Provider{ + Name: cloudProviderName, + } + + CreateNodeVM, err := cloudProvider.GetVMBuilder() + if err != nil { + return err + } + + connectionArgs, dependencies, err := CreateNodeVM(stackName, ctx, cfg) + if err != nil { + return err + } + + scriptChange, err := hashUtils.GetFileHash("./assets/node-setup.sh") + if err != nil { + return err + } + + cpScript, err := remote.NewCopyFile(ctx, "Copy deployment script to VM", &remote.CopyFileArgs{ + Connection: connectionArgs, + LocalPath: pulumi.String("./assets/node-setup.sh"), + RemotePath: pulumi.Sprintf("/home/%s/node-setup.sh", vmUsername), + Triggers: pulumi.Array{ + pulumi.String(scriptChange), + }, + }, pulumi.DependsOn(dependencies)) + if err != nil { + return err + } + + chmodScript, err := remote.NewCommand(ctx, "Set deployment script permission", &remote.CommandArgs{ + Connection: connectionArgs, + Create: pulumi.Sprintf("chmod u+x /home/%s/node-setup.sh", vmUsername), + Triggers: pulumi.Array{ + pulumi.String(scriptChange), + }, + }, pulumi.DependsOn([]pulumi.Resource{ + cpScript, + })) + if err != nil { + return err + } + + serviceTemplateChange, err := hashUtils.GetFileHash("./assets/liked.service.template") + if err != nil { + return err + } + + cpService, err := remote.NewCopyFile(ctx, "Copy node service template to VM", &remote.CopyFileArgs{ + Connection: connectionArgs, + LocalPath: pulumi.String("./assets/liked.service.template"), + RemotePath: pulumi.Sprintf("/home/%s/liked.service.template", vmUsername), + Triggers: pulumi.Array{ + pulumi.String(serviceTemplateChange), + }, + }, pulumi.DependsOn(dependencies)) + if err != nil { + return err + } + + makeFileChange, err := hashUtils.GetFileHash("./assets/Makefile") + if err != nil { + return err + } + + cpMakefile, err := remote.NewCopyFile(ctx, "Copy Makefile to VM", &remote.CopyFileArgs{ + Connection: connectionArgs, + LocalPath: pulumi.String("./assets/Makefile"), + RemotePath: pulumi.Sprintf("/home/%s/Makefile", vmUsername), + Triggers: pulumi.Array{ + pulumi.String(makeFileChange), + }, + }, pulumi.DependsOn(dependencies)) + if err != nil { + return err + } + + installBuildEssentialsCommand, err := remote.NewCommand(ctx, "Install make on VM", &remote.CommandArgs{ + Connection: connectionArgs, + Create: pulumi.String("sudo apt install -y make"), + }, pulumi.DependsOn([]pulumi.Resource{ + cpScript, + cpService, + chmodScript, + cpMakefile, + })) + if err != nil { + return err + } + + setupNodeCommand, err := remote.NewCommand(ctx, "Execute setup node command", &remote.CommandArgs{ + Connection: connectionArgs, + Create: pulumi.Sprintf("MONIKER=%s LIKED_USER=%s LIKED_WORKDIR=/home/%s GENESIS_URL=%s LIKED_SEED_NODES=%s make setup-node", moniker, vmUsername, vmUsername, genesisUrl, seeds), + Triggers: pulumi.Array{ + pulumi.String(scriptChange), + pulumi.String(serviceTemplateChange), + pulumi.String(makeFileChange), + }, + }, pulumi.DependsOn([]pulumi.Resource{ + installBuildEssentialsCommand, + cpScript, + cpService, + chmodScript, + cpMakefile, + })) + if err != nil { + return err + } + + _, err = remote.NewCommand(ctx, "Execute initialize node service command", &remote.CommandArgs{ + Connection: connectionArgs, + Create: pulumi.String("make initialize-systemctl"), + Triggers: pulumi.Array{ + pulumi.String(scriptChange), + pulumi.String(serviceTemplateChange), + pulumi.String(makeFileChange), + }, + }, pulumi.DependsOn([]pulumi.Resource{ + installBuildEssentialsCommand, + setupNodeCommand, + cpScript, + cpService, + chmodScript, + cpMakefile, + })) + if err != nil { + return err + } + + ctx.Export("Stack Name", pulumi.String(stackName)) + + return nil + }) +} diff --git a/deploy/pkg/providers/azure/azure.go b/deploy/pkg/providers/azure/azure.go new file mode 100644 index 0000000000..769e8afecb --- /dev/null +++ b/deploy/pkg/providers/azure/azure.go @@ -0,0 +1,245 @@ +package providers + +import ( + "strings" + + "github.com/pulumi/pulumi-azure-native/sdk/go/azure/compute" + "github.com/pulumi/pulumi-azure-native/sdk/go/azure/network" + "github.com/pulumi/pulumi-azure-native/sdk/go/azure/resources" + "github.com/pulumi/pulumi-command/sdk/go/command/remote" + "github.com/pulumi/pulumi/sdk/v3/go/pulumi" + "github.com/pulumi/pulumi/sdk/v3/go/pulumi/config" +) + +func CreateNodeVM(deploymentId string, ctx *pulumi.Context, cfg *config.Config) (*remote.ConnectionArgs, []pulumi.Resource, error) { + resourceGroupName := cfg.Require("resource-group-name") + vmUsername := cfg.Require("vm-username") + vmPassword := cfg.RequireSecret("vm-password") + publicKey := cfg.Require("vm-public-key") + privateKey := cfg.RequireSecret("vm-private-key") + sshAllowList := cfg.Require("vm-ssh-allow-list") + vmHardware := cfg.Require("vm-hardware") + vmDiskSize := cfg.GetInt("vm-disk-size") + if vmDiskSize == 0 { + vmDiskSize = int(50) + } + + var sshAllowCIDRs pulumi.StringArray + for _, cidr := range strings.Split(sshAllowList, ",") { + _cidr := pulumi.String(strings.TrimSpace(cidr)) + if len(_cidr) > 0 { + sshAllowCIDRs = append(sshAllowCIDRs, _cidr) + } + } + + // Locate an Azure Resource Group + resourceGroup, err := resources.LookupResourceGroup(ctx, &resources.LookupResourceGroupArgs{ + ResourceGroupName: resourceGroupName, + }) + if err != nil { + return nil, []pulumi.Resource{}, err + } + + // Create network for VMs + virtualNetwork, err := network.NewVirtualNetwork( + ctx, + "Create Node Network", + &network.VirtualNetworkArgs{ + VirtualNetworkName: pulumi.Sprintf("vn-%s", deploymentId), + ResourceGroupName: pulumi.String(resourceGroup.Name), + AddressSpace: &network.AddressSpaceArgs{ + AddressPrefixes: pulumi.StringArray{ + pulumi.String("10.0.0.0/16"), + }, + }, + Subnets: network.SubnetTypeArray{ + network.SubnetTypeArgs{ + Name: pulumi.String("default"), + AddressPrefix: pulumi.String("10.0.1.0/24"), + }, + }, + }, + ) + if err != nil { + return nil, []pulumi.Resource{}, err + } + + // Create public ip address + pubIp, err := network.NewPublicIPAddress(ctx, "Create Public IP Address", &network.PublicIPAddressArgs{ + PublicIpAddressName: pulumi.Sprintf("node-ip-%s", deploymentId), + ResourceGroupName: pulumi.String(resourceGroup.Name), + PublicIPAllocationMethod: pulumi.String(network.IPAllocationMethodDynamic), + }) + if err != nil { + return nil, []pulumi.Resource{}, err + } + + sshSecurityRule := network.SecurityRuleTypeArgs{ + Access: pulumi.String(network.AccessAllow), + Protocol: pulumi.String("*"), + SourcePortRange: pulumi.String("*"), + DestinationAddressPrefix: pulumi.String("*"), + DestinationPortRange: pulumi.String("22"), + Direction: pulumi.String(network.SecurityRuleDirectionInbound), + Name: pulumi.Sprintf("ssh-inbound-%s", deploymentId), + Priority: pulumi.Int(102), + } + + if len(sshAllowCIDRs) > 0 { + sshSecurityRule.SourceAddressPrefixes = sshAllowCIDRs + } else { + sshSecurityRule.SourceAddressPrefix = pulumi.String("*") + } + // Create network security group + networkSg, err := network.NewNetworkSecurityGroup(ctx, "Create Network Security Group", &network.NetworkSecurityGroupArgs{ + NetworkSecurityGroupName: pulumi.Sprintf("network-sg-%s", deploymentId), + ResourceGroupName: pulumi.String(resourceGroup.Name), + SecurityRules: network.SecurityRuleTypeArray{ + // Inbound rule for rpc and peer connections + network.SecurityRuleTypeArgs{ + Access: pulumi.String(network.AccessAllow), + Protocol: pulumi.String("*"), + SourceAddressPrefix: pulumi.String("*"), + SourcePortRange: pulumi.String("*"), + DestinationAddressPrefix: pulumi.String("*"), + DestinationPortRange: pulumi.String("26656"), + Direction: pulumi.String(network.SecurityRuleDirectionInbound), + Name: pulumi.Sprintf("network-inbound-%s", deploymentId), + Priority: pulumi.Int(100), + }, + // Outbound rule without port limit + network.SecurityRuleTypeArgs{ + Access: pulumi.String(network.AccessAllow), + Protocol: pulumi.String("*"), + SourceAddressPrefix: pulumi.String("*"), + SourcePortRange: pulumi.String("*"), + DestinationAddressPrefix: pulumi.String("*"), + DestinationPortRange: pulumi.String("*"), + Direction: pulumi.String(network.SecurityRuleDirectionOutbound), + Name: pulumi.Sprintf("network-outbound-%s", deploymentId), + Priority: pulumi.Int(101), + }, + sshSecurityRule, + }, + }) + if err != nil { + return nil, []pulumi.Resource{}, err + } + + // Create network interface with previously created ip address and security group + networkIf, err := network.NewNetworkInterface(ctx, "Create Network Interface", &network.NetworkInterfaceArgs{ + NetworkInterfaceName: pulumi.Sprintf("network-if-%s", deploymentId), + ResourceGroupName: pulumi.String(resourceGroup.Name), + IpConfigurations: network.NetworkInterfaceIPConfigurationArray{ + network.NetworkInterfaceIPConfigurationArgs{ + Name: pulumi.Sprintf("node-ipcfg-%s", deploymentId), + PrivateIPAllocationMethod: pulumi.String(network.IPAllocationMethodDynamic), + Subnet: network.SubnetTypeArgs{ + Id: virtualNetwork.Subnets.Index(pulumi.Int(0)).Id(), + }, + PublicIPAddress: network.PublicIPAddressTypeArgs{ + Id: pubIp.ID(), + }, + }, + }, + NetworkSecurityGroup: network.NetworkSecurityGroupTypeArgs{ + Id: networkSg.ID(), + }, + }, pulumi.DependsOn([]pulumi.Resource{ + networkSg, + })) + if err != nil { + return nil, []pulumi.Resource{}, err + } + + // Create virtual machine for node to run on + vm, err := compute.NewVirtualMachine(ctx, "Create Virtual Machine", &compute.VirtualMachineArgs{ + VmName: pulumi.Sprintf("node-vm-%s", deploymentId), + ResourceGroupName: pulumi.String(resourceGroup.Name), + NetworkProfile: compute.NetworkProfileArgs{ + NetworkInterfaces: compute.NetworkInterfaceReferenceArray{ + compute.NetworkInterfaceReferenceArgs{ + Id: networkIf.ID(), + Primary: pulumi.Bool(true), + }, + }, + }, + HardwareProfile: &compute.HardwareProfileArgs{ + VmSize: pulumi.String(vmHardware), + }, + Location: pulumi.String(resourceGroup.Location), + OsProfile: &compute.OSProfileArgs{ + AdminUsername: pulumi.String(vmUsername), + AdminPassword: vmPassword, + ComputerName: pulumi.String(vmUsername), + LinuxConfiguration: &compute.LinuxConfigurationArgs{ + DisablePasswordAuthentication: pulumi.Bool(true), + PatchSettings: &compute.LinuxPatchSettingsArgs{ + AssessmentMode: pulumi.String(compute.LinuxPatchAssessmentModeImageDefault), + }, + ProvisionVMAgent: pulumi.Bool(true), + Ssh: &compute.SshConfigurationArgs{ + PublicKeys: &compute.SshPublicKeyTypeArray{ + compute.SshPublicKeyTypeArgs{ + KeyData: pulumi.String(publicKey), + Path: pulumi.Sprintf("/home/%s/.ssh/authorized_keys", vmUsername), + }, + }, + }, + }, + }, + StorageProfile: &compute.StorageProfileArgs{ + ImageReference: &compute.ImageReferenceArgs{ + Offer: pulumi.String("0001-com-ubuntu-server-focal"), + Publisher: pulumi.String("Canonical"), + Sku: pulumi.String("20_04-lts-gen2"), + Version: pulumi.String("latest"), + }, + OsDisk: &compute.OSDiskArgs{ + Caching: compute.CachingTypesReadWrite, + CreateOption: pulumi.String(compute.DiskCreateOptionFromImage), + ManagedDisk: &compute.ManagedDiskParametersArgs{ + StorageAccountType: pulumi.String(compute.StorageAccountType_Premium_LRS), + }, + DiskSizeGB: pulumi.Int(vmDiskSize), + Name: pulumi.Sprintf("node-vm-os-disk-%s", deploymentId), + DeleteOption: pulumi.String(compute.DeleteOptionsDelete), + }, + }, + }, pulumi.DependsOn([]pulumi.Resource{ + networkIf, + }), + ) + if err != nil { + return nil, []pulumi.Resource{}, err + } + + // Ensure the resources are created first + ready := pulumi.All(vm.ID(), pubIp.Name, pulumi.String(resourceGroup.Name)) + + ipAddress := ready.ApplyT(func(args []interface{}) (string, error) { + name := args[1].(string) + resourceGroupName := args[2].(string) + ip, err := network.LookupPublicIPAddress(ctx, &network.LookupPublicIPAddressArgs{ + ResourceGroupName: resourceGroupName, + PublicIpAddressName: name, + }) + if err != nil { + return "", err + } + return *ip.IpAddress, nil + }).(pulumi.StringOutput) + + // Send files and run commands to setup node + connection := remote.ConnectionArgs{ + Host: ipAddress, + User: pulumi.String(vmUsername), + PrivateKey: privateKey, + } + + ctx.Export("Virtual Machine ID", vm.ID()) + ctx.Export("Virtual Machine IP", ipAddress) + ctx.Export("SSH Endpoint", pulumi.Sprintf("%s@%s", vmUsername, ipAddress)) + + return &connection, []pulumi.Resource{vm, pubIp}, nil +} diff --git a/deploy/pkg/providers/provider.go b/deploy/pkg/providers/provider.go new file mode 100644 index 0000000000..66ec8c9c46 --- /dev/null +++ b/deploy/pkg/providers/provider.go @@ -0,0 +1,28 @@ +package providers + +import ( + AzureProvider "deploy/pkg/providers/azure" + "errors" + + "github.com/pulumi/pulumi-command/sdk/go/command/remote" + "github.com/pulumi/pulumi/sdk/v3/go/pulumi" + "github.com/pulumi/pulumi/sdk/v3/go/pulumi/config" +) + +const ( + GCP string = "gcp" + Azure string = "azure" +) + +type Provider struct { + Name string +} + +func (provider Provider) GetVMBuilder() (func(deploymentId string, ctx *pulumi.Context, cfg *config.Config) (*remote.ConnectionArgs, []pulumi.Resource, error), error) { + switch provider.Name { + case Azure: + return AzureProvider.CreateNodeVM, nil + } + + return nil, errors.New("unknown provider") +} From a8f3c83c3f7d13e5bd4063825eaf7f9d85bc8167 Mon Sep 17 00:00:00 2001 From: Rico Wong Date: Tue, 22 Feb 2022 16:59:19 +0800 Subject: [PATCH 20/27] Create pulumi deployment script for gcp refs oursky/likecoin-chain#24 --- deploy/Pulumi.yaml | 2 +- deploy/go.mod | 3 +- deploy/go.sum | 8 +- deploy/pkg/providers/gcp/gcp.go | 197 +++++++++++++++++++++++++++++++ deploy/pkg/providers/provider.go | 4 +- 5 files changed, 204 insertions(+), 10 deletions(-) create mode 100644 deploy/pkg/providers/gcp/gcp.go diff --git a/deploy/Pulumi.yaml b/deploy/Pulumi.yaml index f13f4ff271..f00607e6d2 100644 --- a/deploy/Pulumi.yaml +++ b/deploy/Pulumi.yaml @@ -1,4 +1,4 @@ name: likecoin-skynet runtime: go -main: cmd/deploy # TODO: Add support aws and gcp deployment +main: cmd/deploy description: likecoin-skynet-deployment diff --git a/deploy/go.mod b/deploy/go.mod index ca6bd80ce9..c10b215132 100644 --- a/deploy/go.mod +++ b/deploy/go.mod @@ -4,8 +4,7 @@ go 1.14 require ( github.com/pulumi/pulumi-azure-native/sdk v1.55.0 - github.com/pulumi/pulumi-azure/sdk/v4 v4.37.0 github.com/pulumi/pulumi-command/sdk v0.0.3 - github.com/pulumi/pulumi-tls/sdk/v4 v4.1.0 // indirect + github.com/pulumi/pulumi-gcp/sdk/v6 v6.12.0 github.com/pulumi/pulumi/sdk/v3 v3.24.1 ) diff --git a/deploy/go.sum b/deploy/go.sum index 76698f2a5d..8a81de354b 100644 --- a/deploy/go.sum +++ b/deploy/go.sum @@ -167,15 +167,11 @@ github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7z github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/pulumi/pulumi-azure-native/sdk v1.55.0 h1:C4gqeLpAzCRCkhNrR8ofBUiQiFGVGDHkjZKvYvfFpBU= github.com/pulumi/pulumi-azure-native/sdk v1.55.0/go.mod h1:5l+UEpggoWApYLSHJO2GlzMyhopoHgtuDOGPQQ0fFE4= -github.com/pulumi/pulumi-azure/sdk/v4 v4.37.0 h1:7y+9qF+8KcdZPIGKebWnVWklwhaAKnPHa5f57r8dQo8= -github.com/pulumi/pulumi-azure/sdk/v4 v4.37.0/go.mod h1:qgdnvXf4sIcYXMKDArIZpu4qCnphTCMxnP10fvrUnQw= github.com/pulumi/pulumi-command/sdk v0.0.3 h1:APhWyBSjCp94b5VTVPz0GwwhP//HT22CD7cBQ0JhAic= github.com/pulumi/pulumi-command/sdk v0.0.3/go.mod h1:WtWndGuQusF2p68t6xEa9yQy6ObMJugKigB2hN4dzts= -github.com/pulumi/pulumi-tls/sdk/v4 v4.1.0 h1:revpmx5G08vdbqbMLtOmPkp3c/nXGiia6Z2MWWafH30= -github.com/pulumi/pulumi-tls/sdk/v4 v4.1.0/go.mod h1:MiYAhU5/WMZtTGRzNIN46eYKux9o4DUF0vnFlkB8cf0= +github.com/pulumi/pulumi-gcp/sdk/v6 v6.12.0 h1:ou7NYqo+w4hPeUEssUbMFb2niKx0KxTHagfbq2Y8OJM= +github.com/pulumi/pulumi-gcp/sdk/v6 v6.12.0/go.mod h1:KTiOKAfnFOJF3wic/DhNs8izW7LF8WAkmGkQEPvh05g= github.com/pulumi/pulumi/sdk/v3 v3.7.0/go.mod h1:GBHyQ7awNQSRmiKp/p8kIKrGrMOZeA/k2czoM/GOqds= -github.com/pulumi/pulumi/sdk/v3 v3.14.0/go.mod h1:aT7YmFdR6/T7tp2tMIZ68WRD1Xyv5a6Y4BhsuaCNpW0= -github.com/pulumi/pulumi/sdk/v3 v3.23.2 h1:m/YfyUsoeRFyHXDm2HtJhK+tBV58nrdmWsAkNQimRU4= github.com/pulumi/pulumi/sdk/v3 v3.23.2/go.mod h1:WHOQB00iuHZyXhwrymxpKXhpOahSguJIpRjVokmM11w= github.com/pulumi/pulumi/sdk/v3 v3.24.1 h1:Ywaih9y/zBfS8s4w6BtcsBF/rHQpGbbZ82oXwEVUfVI= github.com/pulumi/pulumi/sdk/v3 v3.24.1/go.mod h1:WHOQB00iuHZyXhwrymxpKXhpOahSguJIpRjVokmM11w= diff --git a/deploy/pkg/providers/gcp/gcp.go b/deploy/pkg/providers/gcp/gcp.go new file mode 100644 index 0000000000..3d148b33ef --- /dev/null +++ b/deploy/pkg/providers/gcp/gcp.go @@ -0,0 +1,197 @@ +package providers + +import ( + "strings" + + "github.com/pulumi/pulumi-command/sdk/go/command/remote" + "github.com/pulumi/pulumi-gcp/sdk/v6/go/gcp/compute" + "github.com/pulumi/pulumi-gcp/sdk/v6/go/gcp/organizations" + serviceaccount "github.com/pulumi/pulumi-gcp/sdk/v6/go/gcp/serviceAccount" + "github.com/pulumi/pulumi/sdk/v3/go/pulumi" + "github.com/pulumi/pulumi/sdk/v3/go/pulumi/config" +) + +func CreateNodeVM(_deploymentId string, ctx *pulumi.Context, cfg *config.Config) (*remote.ConnectionArgs, []pulumi.Resource, error) { + projectId := cfg.Require("project-id") + vmUsername := cfg.Require("vm-username") + publicKey := cfg.Require("vm-public-key") + privateKey := cfg.RequireSecret("vm-private-key") + sshAllowList := cfg.Require("vm-ssh-allow-list") + + vmHardware := cfg.Require("vm-hardware") + vmDiskSize := cfg.GetInt("vm-disk-size") + networkRegion := cfg.Require("network-region") + vmZone := cfg.Require("vm-zone") + + deploymentId := strings.ReplaceAll(_deploymentId, "_", "-") // GCP naming convention + + var sshAllowCIDRs pulumi.StringArray + for _, cidr := range strings.Split(sshAllowList, ",") { + _cidr := pulumi.String(strings.TrimSpace(cidr)) + if len(_cidr) > 0 { + sshAllowCIDRs = append(sshAllowCIDRs, _cidr) + } + } + if len(sshAllowCIDRs) == 0 { + sshAllowCIDRs = pulumi.StringArray{ + pulumi.String("0.0.0.0/0"), + } + } + + // Locate a GCP project + project, err := organizations.LookupProject(ctx, &organizations.LookupProjectArgs{ + ProjectId: &projectId, + }) + if err != nil { + return nil, []pulumi.Resource{}, err + } + // Create service account + serviceAccount, err := serviceaccount.NewAccount(ctx, "Create Service Account", &serviceaccount.AccountArgs{ + AccountId: pulumi.Sprintf("account-%s", strings.ReplaceAll(deploymentId, "_", "-")), + Project: pulumi.String(*project.ProjectId), + }) + if err != nil { + return nil, []pulumi.Resource{}, err + } + + // Create network for VMs + network, err := compute.NewNetwork(ctx, "Create Network", &compute.NetworkArgs{ + Name: pulumi.Sprintf("network-%s", deploymentId), + Project: pulumi.String(*project.ProjectId), + AutoCreateSubnetworks: pulumi.Bool(false), + }) + if err != nil { + return nil, []pulumi.Resource{}, err + } + + subnetwork, err := compute.NewSubnetwork(ctx, "Create Subnetwork", &compute.SubnetworkArgs{ + Name: pulumi.Sprintf("subnetwork-%s", deploymentId), + Project: pulumi.String(*project.ProjectId), + IpCidrRange: pulumi.String("10.0.1.0/24"), + Region: pulumi.String(networkRegion), + Network: network.ID(), + }, pulumi.DependsOn( + []pulumi.Resource{ + network, + }, + )) + if err != nil { + return nil, []pulumi.Resource{}, err + } + + // Create firewall rules for ssh and compute + sshFirewall, err := compute.NewFirewall(ctx, "Create SSH Firewall", + &compute.FirewallArgs{ + Name: pulumi.Sprintf("network-ssh-firewall-%s", deploymentId), + Project: pulumi.String(*project.ProjectId), + Network: network.SelfLink, + SourceRanges: sshAllowCIDRs, + Direction: pulumi.String("INGRESS"), + Allows: &compute.FirewallAllowArray{ + &compute.FirewallAllowArgs{ + Protocol: pulumi.String("tcp"), + Ports: pulumi.StringArray{ + pulumi.String("22"), + }, + }, + }, + }, pulumi.DependsOn( + []pulumi.Resource{ + network, subnetwork, + }, + ), + ) + if err != nil { + return nil, []pulumi.Resource{}, err + } + + computeFirewall, err := compute.NewFirewall(ctx, "Create Compute Firewall", + &compute.FirewallArgs{ + Name: pulumi.Sprintf("network-firewall-%s", deploymentId), + Project: pulumi.String(*project.ProjectId), + Network: network.SelfLink, + SourceRanges: pulumi.StringArray{ + pulumi.String("0.0.0.0/0"), + }, + Direction: pulumi.String("INGRESS"), + Allows: &compute.FirewallAllowArray{ + &compute.FirewallAllowArgs{ + Protocol: pulumi.String("tcp"), + Ports: pulumi.StringArray{ + pulumi.String("26656"), + }, + }, + }, + }, pulumi.DependsOn( + []pulumi.Resource{ + network, subnetwork, + }, + ), + ) + if err != nil { + return nil, []pulumi.Resource{}, err + } + + // Create public ip address + pubIp, err := compute.NewAddress(ctx, "Create Public IP Address", &compute.AddressArgs{ + Name: pulumi.Sprintf("node-ip-%s", deploymentId), + Project: pulumi.String(*project.ProjectId), + Region: pulumi.String(networkRegion), + }) + if err != nil { + return nil, []pulumi.Resource{}, err + } + + vm, err := compute.NewInstance(ctx, "Create VM Instance", &compute.InstanceArgs{ + Name: pulumi.Sprintf("node-vm-%s", deploymentId), + Project: pulumi.String(*project.ProjectId), + MachineType: pulumi.String(vmHardware), + Zone: pulumi.String(vmZone), + BootDisk: &compute.InstanceBootDiskArgs{ + InitializeParams: &compute.InstanceBootDiskInitializeParamsArgs{ + Image: pulumi.String("ubuntu-2004-focal-v20220204"), + Size: pulumi.Int(vmDiskSize), + }, + }, + Metadata: pulumi.StringMap{ + "enable-oslogin": pulumi.String("false"), + "ssh-keys": pulumi.Sprintf("%s:%s", vmUsername, publicKey), + }, + NetworkInterfaces: compute.InstanceNetworkInterfaceArray{ + &compute.InstanceNetworkInterfaceArgs{ + Subnetwork: subnetwork.ID(), + AccessConfigs: &compute.InstanceNetworkInterfaceAccessConfigArray{ + &compute.InstanceNetworkInterfaceAccessConfigArgs{ + NatIp: pubIp.Address, + }, + }, + }, + }, + ServiceAccount: &compute.InstanceServiceAccountArgs{ + Email: serviceAccount.Email, + Scopes: pulumi.StringArray{ + pulumi.String("cloud-platform"), + }, + }, + }, pulumi.DependsOn( + []pulumi.Resource{ + sshFirewall, computeFirewall, + }, + )) + if err != nil { + return nil, []pulumi.Resource{}, err + } + + // Send files and run commands to setup node + connection := remote.ConnectionArgs{ + Host: pubIp.Address, + User: pulumi.String(vmUsername), + PrivateKey: privateKey, + } + + ctx.Export("Virtual Machine ID", vm.ID()) + ctx.Export("Virtual Machine IP", pubIp.Address) + ctx.Export("SSH Endpoint", pulumi.Sprintf("%s@%s", vmUsername, pubIp.Address)) + + return &connection, []pulumi.Resource{vm, pubIp}, nil +} diff --git a/deploy/pkg/providers/provider.go b/deploy/pkg/providers/provider.go index 66ec8c9c46..d487eddd00 100644 --- a/deploy/pkg/providers/provider.go +++ b/deploy/pkg/providers/provider.go @@ -2,6 +2,7 @@ package providers import ( AzureProvider "deploy/pkg/providers/azure" + GCPProvider "deploy/pkg/providers/gcp" "errors" "github.com/pulumi/pulumi-command/sdk/go/command/remote" @@ -22,7 +23,8 @@ func (provider Provider) GetVMBuilder() (func(deploymentId string, ctx *pulumi.C switch provider.Name { case Azure: return AzureProvider.CreateNodeVM, nil + case GCP: + return GCPProvider.CreateNodeVM, nil } - return nil, errors.New("unknown provider") } From 0d2d0ceee711d21f2882639ffc9c8ca8ff15271b Mon Sep 17 00:00:00 2001 From: Rico Wong Date: Tue, 22 Feb 2022 21:29:27 +0800 Subject: [PATCH 21/27] Add GCP related values to config template and README --- deploy/Pulumi.config.yaml.template | 12 ++++++--- deploy/README.md | 42 +++++++++++++++++++++--------- 2 files changed, 38 insertions(+), 16 deletions(-) diff --git a/deploy/Pulumi.config.yaml.template b/deploy/Pulumi.config.yaml.template index aee005517f..530aab766c 100644 --- a/deploy/Pulumi.config.yaml.template +++ b/deploy/Pulumi.config.yaml.template @@ -1,12 +1,18 @@ config: - likecoin-skynet:node-genesis: + likecoin-skynet:cloud-provider: azure + likecoin-skynet:network-region: asia-southeast1 + likecoin-skynet:node-genesis: likecoin-skynet:node-moniker: likecoin - likecoin-skynet:node-seeds: + likecoin-skynet:node-seeds: + likecoin-skynet:project-id: likecoin-devnet likecoin-skynet:resource-group-name: likecoin likecoin-skynet:vm-password: + likecoin-skynet:vm-disk-size: "50" + likecoin-skynet:vm-hardware: e2-medium likecoin-skynet:vm-private-key: likecoin-skynet:vm-public-key: - likecoin-skynet:vm-ssh-allow-list: + likecoin-skynet:vm-ssh-allow-list: "" likecoin-skynet:vm-username: likecoin likecoin-skynet:vm-hardware: Standard_B2s likecoin-skynet:vm-disk-size: 50 + likecoin-skynet:vm-zone: asia-southeast1-b diff --git a/deploy/README.md b/deploy/README.md index 11fc83fbc5..55864d341f 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -89,16 +89,32 @@ make start-node Pulumi stack configurations that is used by the deployment script -| Configuration | Description | Default | Mandatory | -| ----------------------------------- | ------------------------------------------------- | ------------ | --------- | -| likecoin-skynet:node-genesis | URL to the genesis.json file | | ❌ | -| likecoin-skynet:node-moniker | Moniker identifier of the node | likecoin | ✅ | -| likecoin-skynet:node-seeds | Comma separated P2P Seed nodes | | ❌ | -| likecoin-skynet:resource-group-name | Resource group name for Azure | | ✅ | -| likecoin-skynet:vm-username | Admin username to the Virtual Machine | likecoin | ✅ | -| likecoin-skynet:vm-password | Admin password to the Virtual Machine | | ✅ | -| likecoin-skynet:vm-private-key | SSH private key to the Virtual Machine | | ✅ | -| likecoin-skynet:vm-public-key | SSH public key to the Virtual Machine | | ✅ | -| likecoin-skynet:vm-hardware | Hardware model identifier for the Virtual Machine | Standard_B2s | ✅ | -| likecoin-skynet:vm-disk-size | Disk Size for the Virtual Machine | 50 | ✅ | -| likecoin-skynet:vm-ssh-allow-list | Comma separated CIDR list for SSH white list | | ❌ | +### Common + +| Configuration | Description | Mandatory | +| --------------------------------- | -------------------------------------------- | --------- | +| likecoin-skynet:cloud-provider | Cloud provider (azure, gcp) | ✅ | +| likecoin-skynet:node-genesis | URL to the genesis.json file | ❌ | +| likecoin-skynet:node-moniker | Moniker identifier of the node | ✅ | +| likecoin-skynet:node-seeds | Comma separated P2P Seed nodes | ❌ | +| likecoin-skynet:vm-username | Admin username to the Virtual Machine | ✅ | +| likecoin-skynet:vm-private-key | SSH private key to the Virtual Machine | ✅ | +| likecoin-skynet:vm-public-key | SSH public key to the Virtual Machine | ✅ | +| likecoin-skynet:vm-ssh-allow-list | Comma separated CIDR list for SSH white list | ❌ | +| likecoin-skynet:vm-disk-size | Disk size for the Virtual Machine | ✅ | +| likecoin-skynet:vm-hardware | Hardware type for the Virtual Machine | ✅ | + +### Azure Specific + +| Configuration | Description | Mandatory | +| ----------------------------------- | ------------------------------------- | --------- | +| likecoin-skynet:resource-group-name | Resource group name for Azure | ✅ | +| likecoin-skynet:vm-password | Admin password to the Virtual Machine | ✅ | + +### GCP Specific + +| Configuration | Description | Mandatory | +| ------------------------------ | ------------------------------------ | --------- | +| likecoin-skynet:project-id | Project ID for GCP | ✅ | +| likecoin-skynet:vm-zone | Zone for Virtual Machine | ✅ | +| likecoin-skynet:network-region | Region for Network related resources | ✅ | From 110d84ef4a32f7bcbcd771ef4437a0fb6500b67f Mon Sep 17 00:00:00 2001 From: Rico Date: Wed, 23 Feb 2022 15:30:22 +0800 Subject: [PATCH 22/27] Separate gcp and azure config templates --- deploy/Makefile | 3 ++- deploy/Pulumi.azure.yaml.template | 13 ++++++++++ ...yaml.template => Pulumi.gcp.yaml.template} | 14 ++++------ deploy/README.md | 26 ++++++++++++++----- 4 files changed, 40 insertions(+), 16 deletions(-) create mode 100644 deploy/Pulumi.azure.yaml.template rename deploy/{Pulumi.config.yaml.template => Pulumi.gcp.yaml.template} (58%) diff --git a/deploy/Makefile b/deploy/Makefile index becd446624..1930196ea3 100644 --- a/deploy/Makefile +++ b/deploy/Makefile @@ -1,9 +1,10 @@ STACK ?= validator +CLOUD ?= azure .PHONY: setup-pulumi setup-pulumi: pulumi stack init $(STACK) - cp ./Pulumi.config.yaml.template "./Pulumi.$(STACK).yaml" + cp ./Pulumi.$(CLOUD).yaml.template "./Pulumi.$(STACK).yaml" .PHONY: ssh-key ssh-key: diff --git a/deploy/Pulumi.azure.yaml.template b/deploy/Pulumi.azure.yaml.template new file mode 100644 index 0000000000..36f0d61698 --- /dev/null +++ b/deploy/Pulumi.azure.yaml.template @@ -0,0 +1,13 @@ +config: + likecoin-skynet:cloud-provider: azure + likecoin-skynet:node-genesis: https://raw.githubusercontent.com/oursky/likecoin-skynet/master/genesis.json + likecoin-skynet:node-moniker: likecoin + likecoin-skynet:node-seeds: 38d4770245a3f50da3d6e12ff25eaa7065cec431@52.148.89.139:26656,3ed370332975b6ddc1b842774f72bebee0e89d7f@34.126.191.131:26656 + likecoin-skynet:resource-group-name: likecoin + likecoin-skynet:vm-password: + likecoin-skynet:vm-private-key: + likecoin-skynet:vm-public-key: + likecoin-skynet:vm-ssh-allow-list: "" + likecoin-skynet:vm-username: likecoin + likecoin-skynet:vm-hardware: Standard_B2s + likecoin-skynet:vm-disk-size: 50 diff --git a/deploy/Pulumi.config.yaml.template b/deploy/Pulumi.gcp.yaml.template similarity index 58% rename from deploy/Pulumi.config.yaml.template rename to deploy/Pulumi.gcp.yaml.template index 530aab766c..baee9a2215 100644 --- a/deploy/Pulumi.config.yaml.template +++ b/deploy/Pulumi.gcp.yaml.template @@ -1,18 +1,14 @@ config: - likecoin-skynet:cloud-provider: azure + likecoin-skynet:cloud-provider: gcp likecoin-skynet:network-region: asia-southeast1 - likecoin-skynet:node-genesis: + likecoin-skynet:node-genesis: https://raw.githubusercontent.com/oursky/likecoin-skynet/master/genesis.json likecoin-skynet:node-moniker: likecoin - likecoin-skynet:node-seeds: + likecoin-skynet:node-seeds: 38d4770245a3f50da3d6e12ff25eaa7065cec431@52.148.89.139:26656,3ed370332975b6ddc1b842774f72bebee0e89d7f@34.126.191.131:26656 likecoin-skynet:project-id: likecoin-devnet - likecoin-skynet:resource-group-name: likecoin - likecoin-skynet:vm-password: - likecoin-skynet:vm-disk-size: "50" - likecoin-skynet:vm-hardware: e2-medium likecoin-skynet:vm-private-key: likecoin-skynet:vm-public-key: likecoin-skynet:vm-ssh-allow-list: "" + likecoin-skynet:vm-disk-size: "50" likecoin-skynet:vm-username: likecoin - likecoin-skynet:vm-hardware: Standard_B2s - likecoin-skynet:vm-disk-size: 50 + likecoin-skynet:vm-hardware: e2-medium likecoin-skynet:vm-zone: asia-southeast1-b diff --git a/deploy/README.md b/deploy/README.md index 55864d341f..71438956c2 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -6,16 +6,22 @@ This document describe how to use Pulumi to set up devnet that support developme - [Pulumi](https://www.pulumi.com/docs/get-started/install/) - Go 1.17+ -- Azure CLI (for azure nodes) +- [Azure CLI](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli-macos) (for azure nodes) +- [Gcloud CLI](https://cloud.google.com/sdk/docs/install-sdk) (for gcp nodes) # Setup ## Account setup -Login to Azure CLI and Pulumi CLI with the following commands +Login to Azure CLI/ GCloud CLI and Pulumi CLI with the following commands ``` +# For Azure az login +# For GCP +gcloud auth application-default login +gcloud config set project $GCP_PROJECT_ID + pulumi login ``` @@ -28,9 +34,16 @@ Pulumi will use the currently logged in session of `az` command to perform follo Prepare the variable for ease of setup, we may want to change according to the current cloud/testnet situation. ``` +# For Azure export RESOURCE_GROUP=likecoin-skynet export REGION=southeastasia -export PASSWORD=$(openssl rand -hex 10) +export CLOUD=azure + +# For GCP +export PROJECT_ID=likecoin-skynet +export CLOUD=gcp + +export PASSWORD=$(openssl rand -base64 48 | sed -e 's/[\/|=|+]//g') export STACK=validator echo $PASSWORD ``` @@ -38,13 +51,14 @@ echo $PASSWORD Create a resource group on Azure with the following command ``` +# For Azure az group create --location $REGION --resource-group $RESOURCE_GROUP ``` Run the following command to setup a pulumi stack. ``` -make setup-pulumi STACK=$STACK +make setup-pulumi STACK=$STACK CLOUD=$CLOUD ``` This creates a file `Pulumi.$STACK.yaml` for our stack in which we will modify for configuring the deployment to work. @@ -94,9 +108,9 @@ Pulumi stack configurations that is used by the deployment script | Configuration | Description | Mandatory | | --------------------------------- | -------------------------------------------- | --------- | | likecoin-skynet:cloud-provider | Cloud provider (azure, gcp) | ✅ | -| likecoin-skynet:node-genesis | URL to the genesis.json file | ❌ | +| likecoin-skynet:node-genesis | URL to the genesis.json file | ✅ | | likecoin-skynet:node-moniker | Moniker identifier of the node | ✅ | -| likecoin-skynet:node-seeds | Comma separated P2P Seed nodes | ❌ | +| likecoin-skynet:node-seeds | Comma separated P2P Seed nodes | ✅ | | likecoin-skynet:vm-username | Admin username to the Virtual Machine | ✅ | | likecoin-skynet:vm-private-key | SSH private key to the Virtual Machine | ✅ | | likecoin-skynet:vm-public-key | SSH public key to the Virtual Machine | ✅ | From 88cdbe8f360f593a022047b38e1a1335f069302d Mon Sep 17 00:00:00 2001 From: Rico Date: Wed, 23 Feb 2022 15:36:53 +0800 Subject: [PATCH 23/27] Make genesis url and seed nodes compulsory --- deploy/cmd/deploy/assets/Makefile | 2 +- deploy/cmd/deploy/assets/node-setup.sh | 25 ++++++++++--------------- 2 files changed, 11 insertions(+), 16 deletions(-) diff --git a/deploy/cmd/deploy/assets/Makefile b/deploy/cmd/deploy/assets/Makefile index 367faf2149..fa04f4ef34 100644 --- a/deploy/cmd/deploy/assets/Makefile +++ b/deploy/cmd/deploy/assets/Makefile @@ -15,7 +15,7 @@ ifeq ($(MONIKER), "") @echo "Missing MONIKER env" @echo "Usage: MONIKER= make setup-node" else - LIKED_VERSION=$(LIKED_VERSION) COSMOVISOR_VERSION=$(COSMOVISOR_VERSION) LIKED_REPO_SOURCE=$(LIKED_REPO_SOURCE) ./node-setup.sh $(MONIKER) "$(GENESIS_URL)" $(LIKED_WORKDIR) $(LIKED_HOME) $(LIKED_USER) "$(LIKED_SEED_NODES)" + LIKED_VERSION=$(LIKED_VERSION) COSMOVISOR_VERSION=$(COSMOVISOR_VERSION) LIKED_REPO_SOURCE=$(LIKED_REPO_SOURCE) ./node-setup.sh $(MONIKER) "$(GENESIS_URL)" "$(LIKED_SEED_NODES)" $(LIKED_WORKDIR) $(LIKED_HOME) $(LIKED_USER) endif .PHONY: initialize-systemctl diff --git a/deploy/cmd/deploy/assets/node-setup.sh b/deploy/cmd/deploy/assets/node-setup.sh index 5eb5eae349..4fcc2e1c4d 100755 --- a/deploy/cmd/deploy/assets/node-setup.sh +++ b/deploy/cmd/deploy/assets/node-setup.sh @@ -4,15 +4,14 @@ set -e MONIKER="$1" GENESIS_URL="$2" -LIKED_WORKDIR="$3" -LIKED_HOME="$4" -LIKED_USER="$5" -LIKED_SEED_NODES="$6" +LIKED_SEED_NODES="$3" +LIKED_WORKDIR="$4" +LIKED_HOME="$5" +LIKED_USER="$6" -if [ -z $MONIKER ]; then +if [ -z $MONIKER ] || [ -z $GENESIS_URL ] || [ -z $LIKED_SEED_NODES ]; then echo "Usage: $0 NODE_NAME " - echo "Example: $0 likecoin-test" - echo "Example: $0 likecoin-test https://example.com/genesis.json" + echo "Example: $0 likecoin-test https://example.com/genesis.json 38d4770245a3f50da3d6e12ff25eaa7065cec431@52.148.89.139:25565" exit 1 fi @@ -70,14 +69,10 @@ else echo "Like instance already initialized, skipping..." fi -if [ ! -z $GENESIS_URL ]; then - mkdir -p "$LIKED_HOME/config/" - curl -o genesis.json -OL "$GENESIS_URL" - mv -f "genesis.json" "$LIKED_HOME/config/genesis.json" - CHAIN_ID=`grep chain_id "$LIKED_HOME/config/genesis.json" | sed 's/ *"chain_id": *"\(.*\)"/\1/g' | sed 's/,$//g'` -else - CHAIN_ID="likecoin-devnet-1" -fi +mkdir -p "$LIKED_HOME/config/" +curl -o genesis.json -OL "$GENESIS_URL" +mv -f "genesis.json" "$LIKED_HOME/config/genesis.json" +CHAIN_ID=`grep chain_id "$LIKED_HOME/config/genesis.json" | sed 's/ *"chain_id": *"\(.*\)"/\1/g' | sed 's/,$//g'` if [ ! -f "$LIKED_HOME/cosmovisor/genesis/bin/liked" ]; then echo "Copying binary to cosmovisor genesis" From cf978592fb92450f831519b6a878b1d3324156af Mon Sep 17 00:00:00 2001 From: Rick Mak Date: Wed, 23 Feb 2022 17:25:02 +0800 Subject: [PATCH 24/27] Include the go Makefile content at deploy makefile So the SETUP.md still works, and people plan to clone the repo and run at their machine will works. --- deploy/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/deploy/Makefile b/deploy/Makefile index 1930196ea3..b9d34c37f0 100644 --- a/deploy/Makefile +++ b/deploy/Makefile @@ -1,6 +1,8 @@ STACK ?= validator CLOUD ?= azure +include ./cmd/deploy/assets/Makefile + .PHONY: setup-pulumi setup-pulumi: pulumi stack init $(STACK) From 9d9bc01188d56bccd4749622912c6852617a18cb Mon Sep 17 00:00:00 2001 From: Rico Date: Wed, 23 Feb 2022 19:08:57 +0800 Subject: [PATCH 25/27] Add instructions for binary version upgrade via cosmovisor to SETUP.md refs oursky/likecoin-chain#54 --- SETUP.md | 43 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/SETUP.md b/SETUP.md index c697acaa92..3b64de563a 100644 --- a/SETUP.md +++ b/SETUP.md @@ -6,7 +6,7 @@ The developer team maintains 3 way on running the node software, they are: 1. `systemd` based. 2. `docker` and `docker-compose` based. -3. Run at shell. +3. Run at shell. It depends on the situation which one is better. Since the development resource is limiting, we are planning to drop maintaining `docker-compose` way. So if you are new to the ecosystem, I recommend to check out the `systemd` way. @@ -30,7 +30,7 @@ make -C deploy initialize-systemctl make -C deploy start-node ``` -Above command is warp around `systemctl`. For checking logs, you can run +Above command is warp around `systemctl`. For checking logs, you can run ``` journalctl -u liked.service -f @@ -55,7 +55,6 @@ By default, the [node-setup.sh](../deploy/scripts/node-setup.sh) script would do | LIKED_HOME | Home directory for the like node, chain data and configurations will be stored here | $HOME/.liked | | LIKED_USER | User used for 'liked.service' to run on behalf of | $USER | - ## Docker based **NOTE: The docker image is only for amd64, arm(i.e. Apple M1) is currently unsupported.** @@ -112,6 +111,44 @@ $HOME/.liked/cosmovisor/upgrades//bin Once the upgrade block is reached, cosmovisor should be able to link the `current` folder to the destinated upgrade folder and automatically restart itself to continue the block syncing process with the latest binary. An extra `upgrade-info.json` file will be generated to indicate the metadata for the upgrade. +## Upgrade Proposal + +To submit an auto upgrade proposal, execute the following command + +``` +./liked tx gov submit-proposal software-upgrade $UPGRADED_VERSION \ + --title "$TITLE" \ + --description "$DESCRIPTION" \ + --from $ACCOUNT \ + --upgrade-height $UPGRADE_HEIGHT \ + --upgrade-info '{"binaries":{"linux/amd64":"$BINARY_URL","darwin/amd64":"$BINARY_URL"}}' \ + --deposit 10000000nanolike \ + --chain-id $CHAIN_ID \ + -y +``` + +Query the proposal to ensure its existance + +``` +./liked query gov proposal $PROPOSAL_ID +``` + +Deposite a certain amount of `LIKE` to the proposal + +``` +./liked tx gov deposit $PROPOSAL_ID 10000000nanolike --from $ACCOUNT --yes +``` + +Proceed to submit a `Yes` vote for the proposal + +``` +./liked tx gov vote $PROPOSAL_ID yes --from $ACCOUNT --chain-id $CHAIN_ID -y +``` + +To submit a manual uprade proposal, remove `--upgrade-info` from the proposal submission command above. +Note that this will require the new binary to be placed in `/.liked/cosmovisor/upgrades/$UPGRADED_VERSION/bin` for the +upgrade to be executed successfully. + # Dependencies [Cosmovisor](https://docs.cosmos.network/master/run-node/cosmovisor.html) From 7c0fef3156f0e65df6a5298231c48d4022920fd1 Mon Sep 17 00:00:00 2001 From: Rico Date: Mon, 28 Feb 2022 16:32:43 +0800 Subject: [PATCH 26/27] Fix ssh-key phony command typo in deployment makefile --- deploy/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/Makefile b/deploy/Makefile index b9d34c37f0..e78de879c9 100644 --- a/deploy/Makefile +++ b/deploy/Makefile @@ -14,7 +14,7 @@ ssh-key: pulumi config set -s $(STACK) \ likecoin-skynet:resource-group-name $(RESOURCE_GROUP) pulumi config set -s $(STACK) \ - like-skynet:vm-password --secret $(PASSWORD) + likecoin-skynet:vm-password --secret $(PASSWORD) cat id_rsa.pub | pulumi config set likecoin-skynet:vm-public-key -- cat id_rsa | pulumi config set likecoin-skynet:vm-private-key --secret -- From 28d376d08c37d65a4838f7f537fd016c95a4e7a4 Mon Sep 17 00:00:00 2001 From: Rico Date: Mon, 28 Feb 2022 16:39:36 +0800 Subject: [PATCH 27/27] Add ssh whitelist config to makefile --- deploy/Makefile | 2 ++ deploy/README.md | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/deploy/Makefile b/deploy/Makefile index e78de879c9..b13c4b5339 100644 --- a/deploy/Makefile +++ b/deploy/Makefile @@ -13,6 +13,8 @@ ssh-key: ssh-keygen -t rsa -f id_rsa -m PEM pulumi config set -s $(STACK) \ likecoin-skynet:resource-group-name $(RESOURCE_GROUP) + pulumi config set -s $(STACK) \ + likecoin-skynet:vm-ssh-allow-list $(SSH_WHITELIST) pulumi config set -s $(STACK) \ likecoin-skynet:vm-password --secret $(PASSWORD) cat id_rsa.pub | pulumi config set likecoin-skynet:vm-public-key -- diff --git a/deploy/README.md b/deploy/README.md index 71438956c2..33a51a5556 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -43,6 +43,9 @@ export CLOUD=azure export PROJECT_ID=likecoin-skynet export CLOUD=gcp +# source cidr/ip addresses for ssh access, comma separated, default current ip address +export SSH_WHITELIST=$(curl checkip.amazonaws.com) + export PASSWORD=$(openssl rand -base64 48 | sed -e 's/[\/|=|+]//g') export STACK=validator echo $PASSWORD @@ -75,6 +78,8 @@ make ssh-key We should now see the values being assigned in `Pulumi.$STACK.yaml` +**NOTE: It is highly recommended to set a value for the config `vm-ssh-allow-list` to prevent global ssh access to the virtual machine. If any assigned ip address is dynamically allocated by the ISP, newly rotated ip address shall be updated on Azure Portal/Google Cloud Platform to maintain said ssh access.** + ## Provision of resources After Run the following command to execute the deployment