From 32d0b8063a9dfd8e66a81e402943b138ec50a674 Mon Sep 17 00:00:00 2001 From: David Boreham Date: Tue, 21 Nov 2023 21:52:04 -0700 Subject: [PATCH 01/14] Add deployment name --- stack_orchestrator/deploy/deploy.py | 2 +- stack_orchestrator/deploy/k8s/cluster_info.py | 5 +++-- stack_orchestrator/deploy/k8s/deploy_k8s.py | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/stack_orchestrator/deploy/deploy.py b/stack_orchestrator/deploy/deploy.py index 32c13a61..df231e74 100644 --- a/stack_orchestrator/deploy/deploy.py +++ b/stack_orchestrator/deploy/deploy.py @@ -276,7 +276,7 @@ def _make_cluster_context(ctx, stack, include, exclude, cluster, env_file): unique_cluster_descriptor = f"{path},{stack},{include},{exclude}" if ctx.debug: print(f"pre-hash descriptor: {unique_cluster_descriptor}") - hash = hashlib.md5(unique_cluster_descriptor.encode()).hexdigest() + hash = hashlib.md5(unique_cluster_descriptor.encode()).hexdigest()[:16] cluster = f"laconic-{hash}" if ctx.verbose: print(f"Using cluster name: {cluster}") diff --git a/stack_orchestrator/deploy/k8s/cluster_info.py b/stack_orchestrator/deploy/k8s/cluster_info.py index a7426804..0f4c8231 100644 --- a/stack_orchestrator/deploy/k8s/cluster_info.py +++ b/stack_orchestrator/deploy/k8s/cluster_info.py @@ -29,18 +29,19 @@ from stack_orchestrator.deploy.images import remote_tag_for_image class ClusterInfo: parsed_pod_yaml_map: Any image_set: Set[str] = set() - app_name: str = "test-app" + app_name: str environment_variables: DeployEnvVars spec: Spec def __init__(self) -> None: pass - def int(self, pod_files: List[str], compose_env_file, spec: Spec): + def int(self, pod_files: List[str], compose_env_file, deployment_name, spec: Spec): self.parsed_pod_yaml_map = parsed_pod_files_map_from_file_names(pod_files) # Find the set of images in the pods self.image_set = images_for_deployment(pod_files) self.environment_variables = DeployEnvVars(env_var_map_from_file(compose_env_file)) + self.app_name = deployment_name self.spec = spec if (opts.o.debug): print(f"Env vars: {self.environment_variables.map}") diff --git a/stack_orchestrator/deploy/k8s/deploy_k8s.py b/stack_orchestrator/deploy/k8s/deploy_k8s.py index 8e790d10..01c1b264 100644 --- a/stack_orchestrator/deploy/k8s/deploy_k8s.py +++ b/stack_orchestrator/deploy/k8s/deploy_k8s.py @@ -55,7 +55,7 @@ class K8sDeployer(Deployer): self.deployment_context = deployment_context self.kind_cluster_name = compose_project_name self.cluster_info = ClusterInfo() - self.cluster_info.int(compose_files, compose_env_file, deployment_context.spec) + self.cluster_info.int(compose_files, compose_env_file, compose_project_name, deployment_context.spec) if (opts.o.debug): print(f"Deployment dir: {deployment_context.deployment_dir}") print(f"Compose files: {compose_files}") -- 2.45.2 From 854c197e359387af3065e975b43972af41f82d3b Mon Sep 17 00:00:00 2001 From: David Boreham Date: Tue, 21 Nov 2023 21:58:49 -0700 Subject: [PATCH 02/14] Move run-webapp command --- stack_orchestrator/deploy/{ => webapp}/run_webapp.py | 0 stack_orchestrator/main.py | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename stack_orchestrator/deploy/{ => webapp}/run_webapp.py (100%) diff --git a/stack_orchestrator/deploy/run_webapp.py b/stack_orchestrator/deploy/webapp/run_webapp.py similarity index 100% rename from stack_orchestrator/deploy/run_webapp.py rename to stack_orchestrator/deploy/webapp/run_webapp.py diff --git a/stack_orchestrator/main.py b/stack_orchestrator/main.py index 8ee8ae61..fdcad96f 100644 --- a/stack_orchestrator/main.py +++ b/stack_orchestrator/main.py @@ -20,7 +20,7 @@ from stack_orchestrator.repos import setup_repositories from stack_orchestrator.build import build_containers from stack_orchestrator.build import build_npms from stack_orchestrator.build import build_webapp -from stack_orchestrator.deploy import run_webapp +from stack_orchestrator.deploy.webapp import run_webapp from stack_orchestrator.deploy import deploy from stack_orchestrator import version from stack_orchestrator.deploy import deployment -- 2.45.2 From 5bf36c2bf88dffa6a82ade0d9975b4b69ec9f173 Mon Sep 17 00:00:00 2001 From: David Boreham Date: Tue, 21 Nov 2023 22:04:05 -0700 Subject: [PATCH 03/14] Force docker --- stack_orchestrator/deploy/webapp/run_webapp.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/stack_orchestrator/deploy/webapp/run_webapp.py b/stack_orchestrator/deploy/webapp/run_webapp.py index aa22acdf..e4e01171 100644 --- a/stack_orchestrator/deploy/webapp/run_webapp.py +++ b/stack_orchestrator/deploy/webapp/run_webapp.py @@ -22,17 +22,17 @@ import hashlib import click - from dotenv import dotenv_values + +from stack_orchestrator import constants from stack_orchestrator.deploy.deployer_factory import getDeployer @click.command() @click.option("--image", help="image to deploy", required=True) -@click.option("--deploy-to", default="compose", help="deployment type ([Docker] 'compose' or 'k8s')") @click.option("--env-file", help="environment file for webapp") @click.pass_context -def command(ctx, image, deploy_to, env_file): +def command(ctx, image, env_file): '''build the specified webapp container''' env = {} @@ -43,7 +43,7 @@ def command(ctx, image, deploy_to, env_file): hash = hashlib.md5(unique_cluster_descriptor.encode()).hexdigest() cluster = f"laconic-webapp-{hash}" - deployer = getDeployer(deploy_to, + deployer = getDeployer(type=constants.compose_deploy_type, deployment_context=None, compose_files=None, compose_project_name=cluster, -- 2.45.2 From c67612e0487797f7094f5d56486e58d707c141dd Mon Sep 17 00:00:00 2001 From: David Boreham Date: Tue, 21 Nov 2023 22:26:13 -0700 Subject: [PATCH 04/14] First cut at webapp deploy create --- .../docker-compose-webapp-template.yml | 8 ++++ .../data/stacks/webapp-template/README.md | 1 + .../data/stacks/webapp-template/stack.yml | 7 ++++ .../deploy/webapp/deploy_webapp.py | 40 +++++++++++++++++++ stack_orchestrator/main.py | 3 +- 5 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 stack_orchestrator/data/compose/docker-compose-webapp-template.yml create mode 100644 stack_orchestrator/data/stacks/webapp-template/README.md create mode 100644 stack_orchestrator/data/stacks/webapp-template/stack.yml create mode 100644 stack_orchestrator/deploy/webapp/deploy_webapp.py diff --git a/stack_orchestrator/data/compose/docker-compose-webapp-template.yml b/stack_orchestrator/data/compose/docker-compose-webapp-template.yml new file mode 100644 index 00000000..b8697afa --- /dev/null +++ b/stack_orchestrator/data/compose/docker-compose-webapp-template.yml @@ -0,0 +1,8 @@ +services: + webapp: + image: cerc/webapp-container:local + restart: always + environment: + CERC_SCRIPT_DEBUG: ${CERC_SCRIPT_DEBUG} + ports: + - "3000" diff --git a/stack_orchestrator/data/stacks/webapp-template/README.md b/stack_orchestrator/data/stacks/webapp-template/README.md new file mode 100644 index 00000000..4441e475 --- /dev/null +++ b/stack_orchestrator/data/stacks/webapp-template/README.md @@ -0,0 +1 @@ +# Template stack for webapp deployments diff --git a/stack_orchestrator/data/stacks/webapp-template/stack.yml b/stack_orchestrator/data/stacks/webapp-template/stack.yml new file mode 100644 index 00000000..d574e764 --- /dev/null +++ b/stack_orchestrator/data/stacks/webapp-template/stack.yml @@ -0,0 +1,7 @@ +version: "1.0" +name: test +description: "Webapp deployment stack" +containers: + - cerc/webapp-template-container +pods: + - webapp-template diff --git a/stack_orchestrator/deploy/webapp/deploy_webapp.py b/stack_orchestrator/deploy/webapp/deploy_webapp.py new file mode 100644 index 00000000..aa530f60 --- /dev/null +++ b/stack_orchestrator/deploy/webapp/deploy_webapp.py @@ -0,0 +1,40 @@ +# Copyright ©2023 Vulcanize + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. + +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +import click + +from stack_orchestrator.util import error_exit + + +@click.group() +@click.pass_context +def command(ctx): + '''manage a webapp deployment''' + + # Check that --stack wasn't supplied + if ctx.parent.obj.stack: + error_exit("--stack can't be supplied with the deploy-webapp command") + + +@command.command() +@click.option("--kube-config", help="Provide a config file for a k8s deployment") +@click.option("--image-registry", help="Provide a container image registry url for this k8s cluster") +@click.option("--deployment-dir", help="Create deployment files in this directory") +@click.option("--image", help="image to deploy", required=True) +@click.option("--env-file", help="environment file for webapp") +@click.pass_context +def create(ctx, image, deploy_to, env_file): + '''create a deployment for the specified webapp container''' + pass diff --git a/stack_orchestrator/main.py b/stack_orchestrator/main.py index fdcad96f..26a011b0 100644 --- a/stack_orchestrator/main.py +++ b/stack_orchestrator/main.py @@ -20,7 +20,7 @@ from stack_orchestrator.repos import setup_repositories from stack_orchestrator.build import build_containers from stack_orchestrator.build import build_npms from stack_orchestrator.build import build_webapp -from stack_orchestrator.deploy.webapp import run_webapp +from stack_orchestrator.deploy.webapp import run_webapp, deploy_webapp from stack_orchestrator.deploy import deploy from stack_orchestrator import version from stack_orchestrator.deploy import deployment @@ -52,6 +52,7 @@ cli.add_command(build_containers.command, "build-containers") cli.add_command(build_npms.command, "build-npms") cli.add_command(build_webapp.command, "build-webapp") cli.add_command(run_webapp.command, "run-webapp") +cli.add_command(deploy_webapp.command, "deploy-webapp") cli.add_command(deploy.command, "deploy") # deploy is an alias for deploy-system cli.add_command(deploy.command, "deploy-system") cli.add_command(deployment.command, "deployment") -- 2.45.2 From 3f6a85e09083b803b3aceeb75739fd047d807225 Mon Sep 17 00:00:00 2001 From: David Boreham Date: Wed, 22 Nov 2023 07:22:30 -0700 Subject: [PATCH 05/14] Add arguments --- stack_orchestrator/deploy/webapp/deploy_webapp.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stack_orchestrator/deploy/webapp/deploy_webapp.py b/stack_orchestrator/deploy/webapp/deploy_webapp.py index aa530f60..75aa863c 100644 --- a/stack_orchestrator/deploy/webapp/deploy_webapp.py +++ b/stack_orchestrator/deploy/webapp/deploy_webapp.py @@ -31,10 +31,10 @@ def command(ctx): @command.command() @click.option("--kube-config", help="Provide a config file for a k8s deployment") @click.option("--image-registry", help="Provide a container image registry url for this k8s cluster") -@click.option("--deployment-dir", help="Create deployment files in this directory") +@click.option("--deployment-dir", help="Create deployment files in this directory", required=True) @click.option("--image", help="image to deploy", required=True) @click.option("--env-file", help="environment file for webapp") @click.pass_context -def create(ctx, image, deploy_to, env_file): +def create(ctx, deployment_dir, image, kube_config, image_registry, env_file): '''create a deployment for the specified webapp container''' pass -- 2.45.2 From 1a37255c187040672c83b7f145d21b7517d2706c Mon Sep 17 00:00:00 2001 From: Thomas E Lackey Date: Wed, 22 Nov 2023 11:31:30 -0600 Subject: [PATCH 06/14] Tweak laconicd config to allow setting endpoint port and to make the fixturenet restartable. (#660) * Endpoint includes port * Make it restartable * Don't try to remove the mounted directory * Make copy of init.sh --- ...ker-compose-fixturenet-laconic-console.yml | 2 +- .../docker-compose-fixturenet-laconicd.yml | 2 +- .../fixturenet-laconicd/create-fixturenet.sh | 187 +++++++++--------- .../cerc-laconic-console-host/config.yml | 4 +- 4 files changed, 101 insertions(+), 94 deletions(-) diff --git a/stack_orchestrator/data/compose/docker-compose-fixturenet-laconic-console.yml b/stack_orchestrator/data/compose/docker-compose-fixturenet-laconic-console.yml index da2fd95f..a186e761 100644 --- a/stack_orchestrator/data/compose/docker-compose-fixturenet-laconic-console.yml +++ b/stack_orchestrator/data/compose/docker-compose-fixturenet-laconic-console.yml @@ -4,6 +4,6 @@ services: image: cerc/laconic-console-host:local environment: - CERC_WEBAPP_FILES_DIR=${CERC_WEBAPP_FILES_DIR:-/usr/local/share/.config/yarn/global/node_modules/@cerc-io/console-app/dist/production} - - LACONIC_HOSTED_ENDPOINT=${LACONIC_HOSTED_ENDPOINT:-http://localhost} + - LACONIC_HOSTED_ENDPOINT=${LACONIC_HOSTED_ENDPOINT:-http://localhost:9473} ports: - "80" diff --git a/stack_orchestrator/data/compose/docker-compose-fixturenet-laconicd.yml b/stack_orchestrator/data/compose/docker-compose-fixturenet-laconicd.yml index 641229d4..7b48f60d 100644 --- a/stack_orchestrator/data/compose/docker-compose-fixturenet-laconicd.yml +++ b/stack_orchestrator/data/compose/docker-compose-fixturenet-laconicd.yml @@ -5,7 +5,7 @@ services: command: ["sh", "/docker-entrypoint-scripts.d/create-fixturenet.sh"] volumes: # The cosmos-sdk node's database directory: - - laconicd-data:/root/.laconicd/data + - laconicd-data:/root/.laconicd # TODO: look at folding these scripts into the container - ../config/fixturenet-laconicd/create-fixturenet.sh:/docker-entrypoint-scripts.d/create-fixturenet.sh - ../config/fixturenet-laconicd/export-mykey.sh:/docker-entrypoint-scripts.d/export-mykey.sh diff --git a/stack_orchestrator/data/config/fixturenet-laconicd/create-fixturenet.sh b/stack_orchestrator/data/config/fixturenet-laconicd/create-fixturenet.sh index 9c30bff8..d444fcad 100644 --- a/stack_orchestrator/data/config/fixturenet-laconicd/create-fixturenet.sh +++ b/stack_orchestrator/data/config/fixturenet-laconicd/create-fixturenet.sh @@ -14,104 +14,111 @@ LOGLEVEL="info" TRACE="--trace" # TRACE="" -# validate dependencies are installed -command -v jq > /dev/null 2>&1 || { echo >&2 "jq not installed. More info: https://stedolan.github.io/jq/download/"; exit 1; } +if [ "$1" == "clean" ] || [ ! -d "$HOME/.laconicd/data/blockstore.db" ]; then + # validate dependencies are installed + command -v jq > /dev/null 2>&1 || { echo >&2 "jq not installed. More info: https://stedolan.github.io/jq/download/"; exit 1; } -# remove existing daemon and client -rm -rf ~/.laconic* + # remove existing daemon and client + rm -rf $HOME/.laconicd/* + rm -rf $HOME/.laconic/* -make install - -laconicd config keyring-backend $KEYRING -laconicd config chain-id $CHAINID - -# if $KEY exists it should be deleted -laconicd keys add $KEY --keyring-backend $KEYRING --algo $KEYALGO - -# Set moniker and chain-id for Ethermint (Moniker can be anything, chain-id must be an integer) -laconicd init $MONIKER --chain-id $CHAINID - -# Change parameter token denominations to aphoton -cat $HOME/.laconicd/config/genesis.json | jq '.app_state["staking"]["params"]["bond_denom"]="aphoton"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json -cat $HOME/.laconicd/config/genesis.json | jq '.app_state["crisis"]["constant_fee"]["denom"]="aphoton"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json -cat $HOME/.laconicd/config/genesis.json | jq '.app_state["gov"]["deposit_params"]["min_deposit"][0]["denom"]="aphoton"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json -cat $HOME/.laconicd/config/genesis.json | jq '.app_state["mint"]["params"]["mint_denom"]="aphoton"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json -# Custom modules -cat $HOME/.laconicd/config/genesis.json | jq '.app_state["registry"]["params"]["record_rent"]["denom"]="aphoton"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json -cat $HOME/.laconicd/config/genesis.json | jq '.app_state["registry"]["params"]["authority_rent"]["denom"]="aphoton"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json -cat $HOME/.laconicd/config/genesis.json | jq '.app_state["registry"]["params"]["authority_auction_commit_fee"]["denom"]="aphoton"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json -cat $HOME/.laconicd/config/genesis.json | jq '.app_state["registry"]["params"]["authority_auction_reveal_fee"]["denom"]="aphoton"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json -cat $HOME/.laconicd/config/genesis.json | jq '.app_state["registry"]["params"]["authority_auction_minimum_bid"]["denom"]="aphoton"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json - -if [[ "$TEST_REGISTRY_EXPIRY" == "true" ]]; then - echo "Setting timers for expiry tests." - - cat $HOME/.laconicd/config/genesis.json | jq '.app_state["registry"]["params"]["record_rent_duration"]="60s"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json - cat $HOME/.laconicd/config/genesis.json | jq '.app_state["registry"]["params"]["authority_grace_period"]="60s"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json - cat $HOME/.laconicd/config/genesis.json | jq '.app_state["registry"]["params"]["authority_rent_duration"]="60s"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json -fi - -if [[ "$TEST_AUCTION_ENABLED" == "true" ]]; then - echo "Enabling auction and setting timers." - - cat $HOME/.laconicd/config/genesis.json | jq '.app_state["registry"]["params"]["authority_auction_enabled"]=true' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json - cat $HOME/.laconicd/config/genesis.json | jq '.app_state["registry"]["params"]["authority_rent_duration"]="60s"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json - cat $HOME/.laconicd/config/genesis.json | jq '.app_state["registry"]["params"]["authority_grace_period"]="300s"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json - cat $HOME/.laconicd/config/genesis.json | jq '.app_state["registry"]["params"]["authority_auction_commits_duration"]="60s"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json - cat $HOME/.laconicd/config/genesis.json | jq '.app_state["registry"]["params"]["authority_auction_reveals_duration"]="60s"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json -fi - -# increase block time (?) -cat $HOME/.laconicd/config/genesis.json | jq '.consensus_params["block"]["time_iota_ms"]="1000"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json - -# Set gas limit in genesis -cat $HOME/.laconicd/config/genesis.json | jq '.consensus_params["block"]["max_gas"]="10000000"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json - -# disable produce empty block -if [[ "$OSTYPE" == "darwin"* ]]; then - sed -i '' 's/create_empty_blocks = true/create_empty_blocks = false/g' $HOME/.laconicd/config/config.toml - else - sed -i 's/create_empty_blocks = true/create_empty_blocks = false/g' $HOME/.laconicd/config/config.toml -fi - -if [[ $1 == "pending" ]]; then - if [[ "$OSTYPE" == "darwin"* ]]; then - sed -i '' 's/create_empty_blocks_interval = "0s"/create_empty_blocks_interval = "30s"/g' $HOME/.laconicd/config/config.toml - sed -i '' 's/timeout_propose = "3s"/timeout_propose = "30s"/g' $HOME/.laconicd/config/config.toml - sed -i '' 's/timeout_propose_delta = "500ms"/timeout_propose_delta = "5s"/g' $HOME/.laconicd/config/config.toml - sed -i '' 's/timeout_prevote = "1s"/timeout_prevote = "10s"/g' $HOME/.laconicd/config/config.toml - sed -i '' 's/timeout_prevote_delta = "500ms"/timeout_prevote_delta = "5s"/g' $HOME/.laconicd/config/config.toml - sed -i '' 's/timeout_precommit = "1s"/timeout_precommit = "10s"/g' $HOME/.laconicd/config/config.toml - sed -i '' 's/timeout_precommit_delta = "500ms"/timeout_precommit_delta = "5s"/g' $HOME/.laconicd/config/config.toml - sed -i '' 's/timeout_commit = "5s"/timeout_commit = "150s"/g' $HOME/.laconicd/config/config.toml - sed -i '' 's/timeout_broadcast_tx_commit = "10s"/timeout_broadcast_tx_commit = "150s"/g' $HOME/.laconicd/config/config.toml - else - sed -i 's/create_empty_blocks_interval = "0s"/create_empty_blocks_interval = "30s"/g' $HOME/.laconicd/config/config.toml - sed -i 's/timeout_propose = "3s"/timeout_propose = "30s"/g' $HOME/.laconicd/config/config.toml - sed -i 's/timeout_propose_delta = "500ms"/timeout_propose_delta = "5s"/g' $HOME/.laconicd/config/config.toml - sed -i 's/timeout_prevote = "1s"/timeout_prevote = "10s"/g' $HOME/.laconicd/config/config.toml - sed -i 's/timeout_prevote_delta = "500ms"/timeout_prevote_delta = "5s"/g' $HOME/.laconicd/config/config.toml - sed -i 's/timeout_precommit = "1s"/timeout_precommit = "10s"/g' $HOME/.laconicd/config/config.toml - sed -i 's/timeout_precommit_delta = "500ms"/timeout_precommit_delta = "5s"/g' $HOME/.laconicd/config/config.toml - sed -i 's/timeout_commit = "5s"/timeout_commit = "150s"/g' $HOME/.laconicd/config/config.toml - sed -i 's/timeout_broadcast_tx_commit = "10s"/timeout_broadcast_tx_commit = "150s"/g' $HOME/.laconicd/config/config.toml + if [ -n "`which make`" ]; then + make install fi -fi -# Allocate genesis accounts (cosmos formatted addresses) -laconicd add-genesis-account $KEY 100000000000000000000000000aphoton --keyring-backend $KEYRING + laconicd config keyring-backend $KEYRING + laconicd config chain-id $CHAINID -# Sign genesis transaction -laconicd gentx $KEY 1000000000000000000000aphoton --keyring-backend $KEYRING --chain-id $CHAINID + # if $KEY exists it should be deleted + laconicd keys add $KEY --keyring-backend $KEYRING --algo $KEYALGO -# Collect genesis tx -laconicd collect-gentxs + # Set moniker and chain-id for Ethermint (Moniker can be anything, chain-id must be an integer) + laconicd init $MONIKER --chain-id $CHAINID -# Run this to ensure everything worked and that the genesis file is setup correctly -laconicd validate-genesis + # Change parameter token denominations to aphoton + cat $HOME/.laconicd/config/genesis.json | jq '.app_state["staking"]["params"]["bond_denom"]="aphoton"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json + cat $HOME/.laconicd/config/genesis.json | jq '.app_state["crisis"]["constant_fee"]["denom"]="aphoton"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json + cat $HOME/.laconicd/config/genesis.json | jq '.app_state["gov"]["deposit_params"]["min_deposit"][0]["denom"]="aphoton"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json + cat $HOME/.laconicd/config/genesis.json | jq '.app_state["mint"]["params"]["mint_denom"]="aphoton"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json + # Custom modules + cat $HOME/.laconicd/config/genesis.json | jq '.app_state["registry"]["params"]["record_rent"]["denom"]="aphoton"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json + cat $HOME/.laconicd/config/genesis.json | jq '.app_state["registry"]["params"]["authority_rent"]["denom"]="aphoton"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json + cat $HOME/.laconicd/config/genesis.json | jq '.app_state["registry"]["params"]["authority_auction_commit_fee"]["denom"]="aphoton"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json + cat $HOME/.laconicd/config/genesis.json | jq '.app_state["registry"]["params"]["authority_auction_reveal_fee"]["denom"]="aphoton"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json + cat $HOME/.laconicd/config/genesis.json | jq '.app_state["registry"]["params"]["authority_auction_minimum_bid"]["denom"]="aphoton"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json -if [[ $1 == "pending" ]]; then - echo "pending mode is on, please wait for the first block committed." + if [[ "$TEST_REGISTRY_EXPIRY" == "true" ]]; then + echo "Setting timers for expiry tests." + + cat $HOME/.laconicd/config/genesis.json | jq '.app_state["registry"]["params"]["record_rent_duration"]="60s"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json + cat $HOME/.laconicd/config/genesis.json | jq '.app_state["registry"]["params"]["authority_grace_period"]="60s"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json + cat $HOME/.laconicd/config/genesis.json | jq '.app_state["registry"]["params"]["authority_rent_duration"]="60s"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json + fi + + if [[ "$TEST_AUCTION_ENABLED" == "true" ]]; then + echo "Enabling auction and setting timers." + + cat $HOME/.laconicd/config/genesis.json | jq '.app_state["registry"]["params"]["authority_auction_enabled"]=true' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json + cat $HOME/.laconicd/config/genesis.json | jq '.app_state["registry"]["params"]["authority_rent_duration"]="60s"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json + cat $HOME/.laconicd/config/genesis.json | jq '.app_state["registry"]["params"]["authority_grace_period"]="300s"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json + cat $HOME/.laconicd/config/genesis.json | jq '.app_state["registry"]["params"]["authority_auction_commits_duration"]="60s"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json + cat $HOME/.laconicd/config/genesis.json | jq '.app_state["registry"]["params"]["authority_auction_reveals_duration"]="60s"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json + fi + + # increase block time (?) + cat $HOME/.laconicd/config/genesis.json | jq '.consensus_params["block"]["time_iota_ms"]="1000"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json + + # Set gas limit in genesis + cat $HOME/.laconicd/config/genesis.json | jq '.consensus_params["block"]["max_gas"]="10000000"' > $HOME/.laconicd/config/tmp_genesis.json && mv $HOME/.laconicd/config/tmp_genesis.json $HOME/.laconicd/config/genesis.json + + # disable produce empty block + if [[ "$OSTYPE" == "darwin"* ]]; then + sed -i '' 's/create_empty_blocks = true/create_empty_blocks = false/g' $HOME/.laconicd/config/config.toml + else + sed -i 's/create_empty_blocks = true/create_empty_blocks = false/g' $HOME/.laconicd/config/config.toml + fi + + if [[ $1 == "pending" ]]; then + if [[ "$OSTYPE" == "darwin"* ]]; then + sed -i '' 's/create_empty_blocks_interval = "0s"/create_empty_blocks_interval = "30s"/g' $HOME/.laconicd/config/config.toml + sed -i '' 's/timeout_propose = "3s"/timeout_propose = "30s"/g' $HOME/.laconicd/config/config.toml + sed -i '' 's/timeout_propose_delta = "500ms"/timeout_propose_delta = "5s"/g' $HOME/.laconicd/config/config.toml + sed -i '' 's/timeout_prevote = "1s"/timeout_prevote = "10s"/g' $HOME/.laconicd/config/config.toml + sed -i '' 's/timeout_prevote_delta = "500ms"/timeout_prevote_delta = "5s"/g' $HOME/.laconicd/config/config.toml + sed -i '' 's/timeout_precommit = "1s"/timeout_precommit = "10s"/g' $HOME/.laconicd/config/config.toml + sed -i '' 's/timeout_precommit_delta = "500ms"/timeout_precommit_delta = "5s"/g' $HOME/.laconicd/config/config.toml + sed -i '' 's/timeout_commit = "5s"/timeout_commit = "150s"/g' $HOME/.laconicd/config/config.toml + sed -i '' 's/timeout_broadcast_tx_commit = "10s"/timeout_broadcast_tx_commit = "150s"/g' $HOME/.laconicd/config/config.toml + else + sed -i 's/create_empty_blocks_interval = "0s"/create_empty_blocks_interval = "30s"/g' $HOME/.laconicd/config/config.toml + sed -i 's/timeout_propose = "3s"/timeout_propose = "30s"/g' $HOME/.laconicd/config/config.toml + sed -i 's/timeout_propose_delta = "500ms"/timeout_propose_delta = "5s"/g' $HOME/.laconicd/config/config.toml + sed -i 's/timeout_prevote = "1s"/timeout_prevote = "10s"/g' $HOME/.laconicd/config/config.toml + sed -i 's/timeout_prevote_delta = "500ms"/timeout_prevote_delta = "5s"/g' $HOME/.laconicd/config/config.toml + sed -i 's/timeout_precommit = "1s"/timeout_precommit = "10s"/g' $HOME/.laconicd/config/config.toml + sed -i 's/timeout_precommit_delta = "500ms"/timeout_precommit_delta = "5s"/g' $HOME/.laconicd/config/config.toml + sed -i 's/timeout_commit = "5s"/timeout_commit = "150s"/g' $HOME/.laconicd/config/config.toml + sed -i 's/timeout_broadcast_tx_commit = "10s"/timeout_broadcast_tx_commit = "150s"/g' $HOME/.laconicd/config/config.toml + fi + fi + + # Allocate genesis accounts (cosmos formatted addresses) + laconicd add-genesis-account $KEY 100000000000000000000000000aphoton --keyring-backend $KEYRING + + # Sign genesis transaction + laconicd gentx $KEY 1000000000000000000000aphoton --keyring-backend $KEYRING --chain-id $CHAINID + + # Collect genesis tx + laconicd collect-gentxs + + # Run this to ensure everything worked and that the genesis file is setup correctly + laconicd validate-genesis + + if [[ $1 == "pending" ]]; then + echo "pending mode is on, please wait for the first block committed." + fi +else + echo "Using existing database at $HOME/.laconicd. To replace, run '`basename $0` clean'" fi # Start the node (remove the --pruning=nothing flag if historical queries are not needed) diff --git a/stack_orchestrator/data/container-build/cerc-laconic-console-host/config.yml b/stack_orchestrator/data/container-build/cerc-laconic-console-host/config.yml index d557ace5..6c310842 100644 --- a/stack_orchestrator/data/container-build/cerc-laconic-console-host/config.yml +++ b/stack_orchestrator/data/container-build/cerc-laconic-console-host/config.yml @@ -2,5 +2,5 @@ services: wns: - server: 'LACONIC_HOSTED_ENDPOINT:9473/api' - webui: 'LACONIC_HOSTED_ENDPOINT:9473/console' + server: 'LACONIC_HOSTED_ENDPOINT/api' + webui: 'LACONIC_HOSTED_ENDPOINT/console' -- 2.45.2 From 5fea0d7ada5344c158490e9f4f405f9d64b95efa Mon Sep 17 00:00:00 2001 From: David Boreham Date: Wed, 22 Nov 2023 12:00:43 -0700 Subject: [PATCH 07/14] Refactor to call deploy init programatically --- .../deploy/deployment_create.py | 25 ++++++++++++++++--- .../deploy/webapp/deploy_webapp.py | 7 +++++- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/stack_orchestrator/deploy/deployment_create.py b/stack_orchestrator/deploy/deployment_create.py index 64647ab2..f0901835 100644 --- a/stack_orchestrator/deploy/deployment_create.py +++ b/stack_orchestrator/deploy/deployment_create.py @@ -22,6 +22,7 @@ import random from shutil import copy, copyfile, copytree import sys from stack_orchestrator import constants +from stack_orchestrator import opts from stack_orchestrator.util import (get_stack_file_path, get_parsed_deployment_spec, get_parsed_stack_config, global_options, get_yaml, get_pod_list, get_pod_file_path, pod_has_scripts, get_pod_script_paths, get_plugin_code_paths, error_exit) @@ -257,13 +258,29 @@ def _parse_config_variables(variable_values: str): "localhost-same, any-same, localhost-fixed-random, any-fixed-random") @click.pass_context def init(ctx, config, kube_config, image_registry, output, map_ports_to_host): - yaml = get_yaml() stack = global_options(ctx).stack - debug = global_options(ctx).debug deployer_type = ctx.obj.deployer.type - default_spec_file_content = call_stack_deploy_init(ctx.obj) + deploy_command_context = ctx.obj + return init_operation( + deploy_command_context, + stack, deployer_type, + config, kube_config, + image_registry, + output, + map_ports_to_host) + + +# The init command's implementation is in a separate function so that we can +# call it from other commands, bypassing the click decoration stuff +def init_operation(deploy_command_context, stack, deployer_type, config, kube_config, image_registry, output, map_ports_to_host): + yaml = get_yaml() + default_spec_file_content = call_stack_deploy_init(deploy_command_context) spec_file_content = {"stack": stack, constants.deploy_to_key: deployer_type} if deployer_type == "k8s": + if kube_config is None: + error_exit("--kube-config must be supplied with --deploy-to k8s") + if image_registry is None: + error_exit("--image-registry must be supplied with --deploy-to k8s") spec_file_content.update({constants.kube_config_key: kube_config}) spec_file_content.update({constants.image_resigtry_key: image_registry}) else: @@ -281,7 +298,7 @@ def init(ctx, config, kube_config, image_registry, output, map_ports_to_host): new_config = config_variables["config"] merged_config = {**new_config, **orig_config} spec_file_content.update({"config": merged_config}) - if debug: + if opts.o.debug: print(f"Creating spec file for stack: {stack} with content: {spec_file_content}") ports = _get_mapped_ports(stack, map_ports_to_host) diff --git a/stack_orchestrator/deploy/webapp/deploy_webapp.py b/stack_orchestrator/deploy/webapp/deploy_webapp.py index 75aa863c..99fc8c86 100644 --- a/stack_orchestrator/deploy/webapp/deploy_webapp.py +++ b/stack_orchestrator/deploy/webapp/deploy_webapp.py @@ -37,4 +37,9 @@ def command(ctx): @click.pass_context def create(ctx, deployment_dir, image, kube_config, image_registry, env_file): '''create a deployment for the specified webapp container''' - pass + # Do the equivalent of: + # 1. laconic-so --stack webapp-template deploy --deploy-to k8s init --output webapp-spec.yml + # --config (eqivalent of the contents of my-config.env) + # 2. laconic-so --stack webapp-template deploy --deploy-to k8s create --deployment-dir test-deployment + # --spec-file webapp-spec.yml + # 3. Replace the container image tag with the specified image -- 2.45.2 From 52d8615406eaff94618b1207155623d062bd54f7 Mon Sep 17 00:00:00 2001 From: David Boreham Date: Wed, 22 Nov 2023 12:44:43 -0700 Subject: [PATCH 08/14] Refactor deploy create command --- stack_orchestrator/deploy/deployment_create.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/stack_orchestrator/deploy/deployment_create.py b/stack_orchestrator/deploy/deployment_create.py index f0901835..41a0f043 100644 --- a/stack_orchestrator/deploy/deployment_create.py +++ b/stack_orchestrator/deploy/deployment_create.py @@ -346,12 +346,19 @@ def _copy_files_to_directory(file_paths: List[Path], directory: Path): @click.option("--initial-peers", help="Initial set of persistent peers") @click.pass_context def create(ctx, spec_file, deployment_dir, network_dir, initial_peers): + deployment_command_context = ctx.obj + return create_operation(deployment_command_context, spec_file, deployment_dir, network_dir, initial_peers) + + +# The init command's implementation is in a separate function so that we can +# call it from other commands, bypassing the click decoration stuff +def create_operation(deployment_command_context, spec_file, deployment_dir, network_dir, initial_peers): parsed_spec = get_parsed_deployment_spec(spec_file) stack_name = parsed_spec["stack"] deployment_type = parsed_spec[constants.deploy_to_key] stack_file = get_stack_file_path(stack_name) parsed_stack = get_parsed_stack_config(stack_name) - if global_options(ctx).debug: + if opts.o.debug: print(f"parsed spec: {parsed_spec}") if deployment_dir is None: deployment_dir_path = _make_default_deployment_dir() @@ -383,7 +390,7 @@ def create(ctx, spec_file, deployment_dir, network_dir, initial_peers): extra_config_dirs = _find_extra_config_dirs(parsed_pod_file, pod) destination_pod_dir = destination_pods_dir.joinpath(pod) os.mkdir(destination_pod_dir) - if global_options(ctx).debug: + if opts.o.debug: print(f"extra config dirs: {extra_config_dirs}") _fixup_pod_file(parsed_pod_file, parsed_spec, destination_compose_dir) with open(destination_compose_dir.joinpath("docker-compose-%s.yml" % pod), "w") as output_file: @@ -407,7 +414,6 @@ def create(ctx, spec_file, deployment_dir, network_dir, initial_peers): # Delegate to the stack's Python code # The deploy create command doesn't require a --stack argument so we need to insert the # stack member here. - deployment_command_context = ctx.obj deployment_command_context.stack = stack_name deployment_context = DeploymentContext() deployment_context.init(deployment_dir_path) -- 2.45.2 From 40e2f09e39b2187bdb1366495bb303b1a1adab1b Mon Sep 17 00:00:00 2001 From: David Boreham Date: Wed, 22 Nov 2023 20:17:25 -0700 Subject: [PATCH 09/14] Fix deploy create --- stack_orchestrator/deploy/deployment_create.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stack_orchestrator/deploy/deployment_create.py b/stack_orchestrator/deploy/deployment_create.py index 41a0f043..fd52dba8 100644 --- a/stack_orchestrator/deploy/deployment_create.py +++ b/stack_orchestrator/deploy/deployment_create.py @@ -22,7 +22,7 @@ import random from shutil import copy, copyfile, copytree import sys from stack_orchestrator import constants -from stack_orchestrator import opts +from stack_orchestrator.opts import opts from stack_orchestrator.util import (get_stack_file_path, get_parsed_deployment_spec, get_parsed_stack_config, global_options, get_yaml, get_pod_list, get_pod_file_path, pod_has_scripts, get_pod_script_paths, get_plugin_code_paths, error_exit) -- 2.45.2 From 5b5559d4a45c180c5f276356c0cfab7ec6fbf020 Mon Sep 17 00:00:00 2001 From: David Boreham Date: Wed, 22 Nov 2023 20:27:49 -0700 Subject: [PATCH 10/14] Add the magic file --- stack_orchestrator/deploy/webapp/__init__.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 stack_orchestrator/deploy/webapp/__init__.py diff --git a/stack_orchestrator/deploy/webapp/__init__.py b/stack_orchestrator/deploy/webapp/__init__.py new file mode 100644 index 00000000..e69de29b -- 2.45.2 From 0c52a0f85b8ebf010291ece7e047c0774581f72e Mon Sep 17 00:00:00 2001 From: David Boreham Date: Sun, 26 Nov 2023 22:46:21 -0700 Subject: [PATCH 11/14] Implement create-webapp --- .../deploy/webapp/deploy_webapp.py | 48 ++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/stack_orchestrator/deploy/webapp/deploy_webapp.py b/stack_orchestrator/deploy/webapp/deploy_webapp.py index 99fc8c86..b090b9b5 100644 --- a/stack_orchestrator/deploy/webapp/deploy_webapp.py +++ b/stack_orchestrator/deploy/webapp/deploy_webapp.py @@ -14,8 +14,23 @@ # along with this program. If not, see . import click +from pathlib import Path -from stack_orchestrator.util import error_exit +from stack_orchestrator.util import error_exit, global_options2 +from stack_orchestrator.deploy.deployment_create import init_operation, create_operation +from stack_orchestrator.deploy.deploy import create_deploy_context +from stack_orchestrator.deploy.deploy_types import DeployCommandContext + + +def _fixup_container_tag(deployment_dir: str, image: str): + deployment_dir_path = Path(deployment_dir) + compose_file = deployment_dir_path.joinpath("compose", "docker-compose-webapp-template.yml") + # replace "cerc/webapp-container:local" in the file with our image tag + with open(compose_file) as rfile: + contents = rfile.read() + contents = contents.replace("cerc/webapp-container:local", image) + with open(compose_file, "w") as wfile: + wfile.write(contents) @click.group() @@ -43,3 +58,34 @@ def create(ctx, deployment_dir, image, kube_config, image_registry, env_file): # 2. laconic-so --stack webapp-template deploy --deploy-to k8s create --deployment-dir test-deployment # --spec-file webapp-spec.yml # 3. Replace the container image tag with the specified image + deployment_dir_path = Path(deployment_dir) + # Check the deployment dir does not exist + if deployment_dir_path.exists(): + error_exit(f"Deployment dir {deployment_dir} already exists") + # Generate a temporary file name for the spec file + spec_file_name = "webapp-spec.yml" + # Specify the webapp template stack + stack = "webapp-template" + # TODO: support env file + deploy_command_context: DeployCommandContext = create_deploy_context( + global_options2(ctx), None, stack, None, None, None, env_file, "k8s" + ) + init_operation( + deploy_command_context, + stack, + "k8s", + None, + kube_config, + image_registry, + spec_file_name, + None + ) + create_operation( + deploy_command_context, + spec_file_name, + deployment_dir, + None, + None + ) + # Fix up the container tag inside the deployment compose file + _fixup_container_tag(deployment_dir, image) -- 2.45.2 From f438448b76334ed3a031a78db2fd792c16b3a995 Mon Sep 17 00:00:00 2001 From: David Boreham Date: Sun, 26 Nov 2023 23:22:07 -0700 Subject: [PATCH 12/14] Add TLS config --- stack_orchestrator/deploy/k8s/deploy_k8s.py | 2 ++ .../deploy/webapp/deploy_webapp.py | 21 ++++++++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/stack_orchestrator/deploy/k8s/deploy_k8s.py b/stack_orchestrator/deploy/k8s/deploy_k8s.py index 01c1b264..5d41ae23 100644 --- a/stack_orchestrator/deploy/k8s/deploy_k8s.py +++ b/stack_orchestrator/deploy/k8s/deploy_k8s.py @@ -126,6 +126,8 @@ class K8sDeployer(Deployer): # TODO: disable ingress for kind ingress: client.V1Ingress = self.cluster_info.get_ingress() + if opts.o.debug: + print(f"Sending this ingress: {ingress}") ingress_resp = self.networking_api.create_namespaced_ingress( namespace=self.k8s_namespace, body=ingress diff --git a/stack_orchestrator/deploy/webapp/deploy_webapp.py b/stack_orchestrator/deploy/webapp/deploy_webapp.py index b090b9b5..a0ff9f08 100644 --- a/stack_orchestrator/deploy/webapp/deploy_webapp.py +++ b/stack_orchestrator/deploy/webapp/deploy_webapp.py @@ -33,6 +33,22 @@ def _fixup_container_tag(deployment_dir: str, image: str): wfile.write(contents) +def _fixup_url_spec(spec_file_name: str): + http_proxy_spec = ''' + http-proxy: + - host-name: test-app.laconic.servesthe.world + routes: + - path: '/' + proxy-to: webapp:3000 + ''' + spec_file_path = Path(spec_file_name) + with open(spec_file_path) as rfile: + contents = rfile.read() + contents = contents + http_proxy_spec + with open(spec_file_path, "w") as wfile: + wfile.write(contents) + + @click.group() @click.pass_context def command(ctx): @@ -48,9 +64,10 @@ def command(ctx): @click.option("--image-registry", help="Provide a container image registry url for this k8s cluster") @click.option("--deployment-dir", help="Create deployment files in this directory", required=True) @click.option("--image", help="image to deploy", required=True) +@click.option("--url", help="url to serve", required=True) @click.option("--env-file", help="environment file for webapp") @click.pass_context -def create(ctx, deployment_dir, image, kube_config, image_registry, env_file): +def create(ctx, deployment_dir, image, url, kube_config, image_registry, env_file): '''create a deployment for the specified webapp container''' # Do the equivalent of: # 1. laconic-so --stack webapp-template deploy --deploy-to k8s init --output webapp-spec.yml @@ -80,6 +97,8 @@ def create(ctx, deployment_dir, image, kube_config, image_registry, env_file): spec_file_name, None ) + # Add the TLS and DNS spec + _fixup_url_spec(spec_file_name) create_operation( deploy_command_context, spec_file_name, -- 2.45.2 From 4e94b360a6e8b32a31db584d43a22844e4af74d4 Mon Sep 17 00:00:00 2001 From: David Boreham Date: Mon, 27 Nov 2023 21:42:16 -0700 Subject: [PATCH 13/14] Support arbitrary port numbers --- stack_orchestrator/deploy/k8s/cluster_info.py | 23 +++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/stack_orchestrator/deploy/k8s/cluster_info.py b/stack_orchestrator/deploy/k8s/cluster_info.py index 0f4c8231..6c19b20a 100644 --- a/stack_orchestrator/deploy/k8s/cluster_info.py +++ b/stack_orchestrator/deploy/k8s/cluster_info.py @@ -68,6 +68,8 @@ class ClusterInfo: proxy_to = route["proxy-to"] if opts.o.debug: print(f"proxy config: {path} -> {proxy_to}") + # proxy_to has the form : + proxy_to_port = int(proxy_to.split(":")[1]) paths.append(client.V1HTTPIngressPath( path_type="Prefix", path=path, @@ -76,7 +78,7 @@ class ClusterInfo: # TODO: this looks wrong name=f"{self.app_name}-service", # TODO: pull port number from the service - port=client.V1ServiceBackendPort(number=80) + port=client.V1ServiceBackendPort(number=proxy_to_port) ) ) )) @@ -102,14 +104,23 @@ class ClusterInfo: ) return ingress + # TODO: suppoprt multiple services def get_service(self): + for pod_name in self.parsed_pod_yaml_map: + pod = self.parsed_pod_yaml_map[pod_name] + services = pod["services"] + for service_name in services: + service_info = services[service_name] + port = int(service_info["ports"][0]) + if opts.o.debug: + print(f"service port: {port}") service = client.V1Service( metadata=client.V1ObjectMeta(name=f"{self.app_name}-service"), spec=client.V1ServiceSpec( type="ClusterIP", ports=[client.V1ServicePort( - port=80, - target_port=80 + port=port, + target_port=port )], selector={"app": self.app_name} ) @@ -166,6 +177,10 @@ class ClusterInfo: container_name = service_name service_info = services[service_name] image = service_info["image"] + port = int(service_info["ports"][0]) + if opts.o.debug: + print(f"image: {image}") + print(f"service port: {port}") # Re-write the image tag for remote deployment image_to_use = remote_tag_for_image( image, self.spec.get_image_registry()) if self.spec.get_image_registry() is not None else image @@ -174,7 +189,7 @@ class ClusterInfo: name=container_name, image=image_to_use, env=envs_from_environment_variables_map(self.environment_variables.map), - ports=[client.V1ContainerPort(container_port=80)], + ports=[client.V1ContainerPort(container_port=port)], volume_mounts=volume_mounts, resources=client.V1ResourceRequirements( requests={"cpu": "100m", "memory": "200Mi"}, -- 2.45.2 From 2fa1785ce84fc5e390f58cf821e1bc22b96b9713 Mon Sep 17 00:00:00 2001 From: David Boreham Date: Mon, 27 Nov 2023 21:59:38 -0700 Subject: [PATCH 14/14] Parse url parameter --- stack_orchestrator/deploy/webapp/deploy_webapp.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/stack_orchestrator/deploy/webapp/deploy_webapp.py b/stack_orchestrator/deploy/webapp/deploy_webapp.py index a0ff9f08..a1e573fb 100644 --- a/stack_orchestrator/deploy/webapp/deploy_webapp.py +++ b/stack_orchestrator/deploy/webapp/deploy_webapp.py @@ -15,6 +15,7 @@ import click from pathlib import Path +from urllib.parse import urlparse from stack_orchestrator.util import error_exit, global_options2 from stack_orchestrator.deploy.deployment_create import init_operation, create_operation @@ -33,12 +34,14 @@ def _fixup_container_tag(deployment_dir: str, image: str): wfile.write(contents) -def _fixup_url_spec(spec_file_name: str): - http_proxy_spec = ''' +def _fixup_url_spec(spec_file_name: str, url: str): + # url is like: https://example.com/path + parsed_url = urlparse(url) + http_proxy_spec = f''' http-proxy: - - host-name: test-app.laconic.servesthe.world + - host-name: {parsed_url.hostname} routes: - - path: '/' + - path: '{parsed_url.path if parsed_url.path else "/"}' proxy-to: webapp:3000 ''' spec_file_path = Path(spec_file_name) @@ -98,7 +101,7 @@ def create(ctx, deployment_dir, image, url, kube_config, image_registry, env_fil None ) # Add the TLS and DNS spec - _fixup_url_spec(spec_file_name) + _fixup_url_spec(spec_file_name, url) create_operation( deploy_command_context, spec_file_name, -- 2.45.2