forked from cerc-io/stack-orchestrator
Compare commits
13
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
faa48e8ca8 | ||
|
|
bfbcfb7904 | ||
|
|
037ffe9a47 | ||
|
|
3d5ececba5 | ||
|
|
01ab438c7e | ||
|
|
6848fc33cf | ||
|
|
36bb068983 | ||
|
|
c85f31760d | ||
|
|
25a2b70f2c | ||
|
|
f67668c1be | ||
|
|
2c17b901a8 | ||
|
|
886f1f322c | ||
|
|
d279aedf84 |
@@ -1 +1,2 @@
|
||||
Change this file to trigger running the test-k8s-deploy CI job
|
||||
Trigger test on PR branch
|
||||
|
||||
@@ -7,9 +7,7 @@ services:
|
||||
# The cosmos-sdk node's database directory:
|
||||
- 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
|
||||
- ../config/fixturenet-laconicd/export-myaddress.sh:/docker-entrypoint-scripts.d/export-myaddress.sh
|
||||
- laconicd-scripts:/docker-entrypoint-scripts.d:ro
|
||||
# TODO: determine which of the ports below is really needed
|
||||
ports:
|
||||
- "6060"
|
||||
@@ -24,7 +22,9 @@ services:
|
||||
cli:
|
||||
image: cerc/laconic-registry-cli:local
|
||||
volumes:
|
||||
- ../config/fixturenet-laconicd/registry-cli-config-template.yml:/registry-cli-config-template.yml
|
||||
- cli-config:/registry-cli-config
|
||||
|
||||
volumes:
|
||||
laconicd-data:
|
||||
laconicd-scripts:
|
||||
cli-config:
|
||||
|
||||
@@ -9,9 +9,7 @@ services:
|
||||
- laconicd-config:/root/.laconicd/config
|
||||
- laconicd-keyring:/root/.laconicd/keyring-test
|
||||
# TODO: look at folding these scripts into the container
|
||||
- ../config/mainnet-laconicd/scripts/run-laconicd.sh:/opt/run-laconicd.sh
|
||||
- ../config/mainnet-laconicd/scripts/export-mykey.sh:/docker-entrypoint-scripts.d/export-mykey.sh
|
||||
- ../config/mainnet-laconicd/scripts/export-myaddress.sh:/docker-entrypoint-scripts.d/export-myaddress.sh
|
||||
- laconicd-scripts:/docker-entrypoint-scripts.d:ro
|
||||
# TODO: determine which of the ports below is really needed
|
||||
ports:
|
||||
- "6060"
|
||||
@@ -26,9 +24,11 @@ services:
|
||||
cli:
|
||||
image: cerc/laconic-registry-cli:local
|
||||
volumes:
|
||||
- ../config/mainnet-laconicd/registry-cli-config-template.yml:/registry-cli-config-template.yml
|
||||
- cli-config:/registry-cli-config
|
||||
|
||||
volumes:
|
||||
laconicd-data:
|
||||
laconicd-config:
|
||||
laconicd-scripts:
|
||||
laconicd-keyring:
|
||||
cli-config:
|
||||
|
||||
@@ -7,8 +7,10 @@ services:
|
||||
CERC_TEST_PARAM_1: ${CERC_TEST_PARAM_1:-FAILED}
|
||||
volumes:
|
||||
- test-data:/data
|
||||
- test-config:/config:ro
|
||||
ports:
|
||||
- "80"
|
||||
|
||||
volumes:
|
||||
test-data:
|
||||
test-config:
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
#!/bin/bash
|
||||
|
||||
# TODO: this file is now an unmodified copy of cerc-io/laconicd/init.sh
|
||||
# so we should have a mechanism to bundle it inside the container rather than link from here
|
||||
# at deploy time.
|
||||
|
||||
KEY="mykey"
|
||||
CHAINID="laconic_9000-1"
|
||||
MONIKER="localtestnet"
|
||||
KEYRING="test"
|
||||
KEYALGO="eth_secp256k1"
|
||||
LOGLEVEL="info"
|
||||
# trace evm
|
||||
TRACE="--trace"
|
||||
# TRACE=""
|
||||
|
||||
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 $HOME/.laconicd/*
|
||||
rm -rf $HOME/.laconic/*
|
||||
|
||||
if [ -n "`which make`" ]; then
|
||||
make install
|
||||
fi
|
||||
|
||||
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
|
||||
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)
|
||||
laconicd start --pruning=nothing --evm.tracer=json $TRACE --log_level $LOGLEVEL --minimum-gas-prices=0.0001aphoton --json-rpc.api eth,txpool,personal,net,debug,web3,miner --api.enable --gql-server --gql-playground
|
||||
@@ -0,0 +1,2 @@
|
||||
#!/bin/sh
|
||||
laconicd keys show mykey | grep address | cut -d ' ' -f 3
|
||||
@@ -0,0 +1,2 @@
|
||||
#!/bin/sh
|
||||
echo y | laconicd keys export mykey --unarmored-hex --unsafe
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
services:
|
||||
cns:
|
||||
restEndpoint: 'http://laconicd:1317'
|
||||
gqlEndpoint: 'http://laconicd:9473/api'
|
||||
userKey: REPLACE_WITH_MYKEY
|
||||
bondId:
|
||||
chainId: laconic_9000-1
|
||||
gas: 350000
|
||||
fees: 200000aphoton
|
||||
@@ -1,2 +1,2 @@
|
||||
#!/bin/sh
|
||||
sed 's/REPLACE_WITH_MYKEY/'${1}'/' registry-cli-config-template.yml > config.yml
|
||||
sed 's/REPLACE_WITH_MYKEY/'${1}'/' /registry-cli-config/registry-cli-config-template.yml > config.yml
|
||||
|
||||
@@ -17,5 +17,20 @@ fi
|
||||
if [ -n "$CERC_TEST_PARAM_1" ]; then
|
||||
echo "Test-param-1: ${CERC_TEST_PARAM_1}"
|
||||
fi
|
||||
|
||||
if [ -d "/config" ]; then
|
||||
echo "/config: EXISTS"
|
||||
for f in /config/*; do
|
||||
if [[ -f "$f" ]] || [[ -L "$f" ]]; then
|
||||
echo "$f:"
|
||||
cat "$f"
|
||||
echo ""
|
||||
echo ""
|
||||
fi
|
||||
done
|
||||
else
|
||||
echo "/config: does NOT EXIST"
|
||||
fi
|
||||
|
||||
# Run nginx which will block here forever
|
||||
/usr/sbin/nginx -g "daemon off;"
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
# Copyright © 2022-2024 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 <http:#www.gnu.org/licenses/>.
|
||||
|
||||
from stack_orchestrator.util import get_yaml, get_config_file_dir
|
||||
from stack_orchestrator.deploy.deploy_types import DeployCommandContext
|
||||
from stack_orchestrator.deploy.deployment_context import DeploymentContext
|
||||
from pathlib import Path
|
||||
from shutil import copy
|
||||
|
||||
default_spec_file_content = ""
|
||||
|
||||
|
||||
def _stack_config_dir(context: DeploymentContext) -> Path:
|
||||
return get_config_file_dir().joinpath(context.stack.name)
|
||||
|
||||
|
||||
def _deployment_volume_dir(context: DeploymentContext, volume_name: str) -> Path:
|
||||
return context.deployment_dir.joinpath("data", volume_name)
|
||||
|
||||
|
||||
def _copy_laconicd_scripts(context: DeploymentContext):
|
||||
scripts = [
|
||||
"create-fixturenet.sh",
|
||||
"export-mykey.sh",
|
||||
"export-myaddress.sh"
|
||||
]
|
||||
destination_dir = _deployment_volume_dir(context, "laconicd-scripts")
|
||||
for script in scripts:
|
||||
# ../config/fixturenet-laconicd/
|
||||
source_file = _stack_config_dir(context).joinpath(script)
|
||||
copy(source_file, destination_dir)
|
||||
|
||||
|
||||
def _copy_cli_template(context: DeploymentContext):
|
||||
destination_dir = _deployment_volume_dir(context, "cli-config")
|
||||
# ../config/fixturenet-laconicd/
|
||||
source_file = _stack_config_dir(context).joinpath("registry-cli-config-template.yml")
|
||||
copy(source_file, destination_dir)
|
||||
|
||||
|
||||
def setup(command_context: DeployCommandContext, parameters, extra_args):
|
||||
pass
|
||||
|
||||
|
||||
def init(command_context: DeployCommandContext):
|
||||
yaml = get_yaml()
|
||||
return yaml.load(default_spec_file_content)
|
||||
|
||||
|
||||
def create(context: DeploymentContext, extra_args):
|
||||
_copy_laconicd_scripts(context)
|
||||
_copy_cli_template(context)
|
||||
|
||||
|
||||
def get_state(command_context: DeployCommandContext):
|
||||
pass
|
||||
|
||||
|
||||
def change_state(command_context: DeployCommandContext):
|
||||
pass
|
||||
@@ -18,7 +18,7 @@ $ laconic-so --stack mainnet-eth build-containers
|
||||
|
||||
```
|
||||
$ laconic-so --stack mainnet-eth deploy init --map-ports-to-host any-same --output mainnet-eth-spec.yml
|
||||
$ laconic-so deploy create --spec-file mainnet-eth-spec.yml --deployment-dir mainnet-eth-deployment
|
||||
$ laconic-so deploy --stack mainnet-eth create --spec-file mainnet-eth-spec.yml --deployment-dir mainnet-eth-deployment
|
||||
```
|
||||
## Start the stack
|
||||
```
|
||||
|
||||
@@ -17,6 +17,7 @@ from pathlib import Path
|
||||
from python_on_whales import DockerClient, DockerException
|
||||
from stack_orchestrator.deploy.deployer import Deployer, DeployerException, DeployerConfigGenerator
|
||||
from stack_orchestrator.deploy.deployment_context import DeploymentContext
|
||||
from stack_orchestrator.opts import opts
|
||||
|
||||
|
||||
class DockerDeployer(Deployer):
|
||||
@@ -29,60 +30,69 @@ class DockerDeployer(Deployer):
|
||||
self.type = type
|
||||
|
||||
def up(self, detach, services):
|
||||
try:
|
||||
return self.docker.compose.up(detach=detach, services=services)
|
||||
except DockerException as e:
|
||||
raise DeployerException(e)
|
||||
if not opts.o.dry_run:
|
||||
try:
|
||||
return self.docker.compose.up(detach=detach, services=services)
|
||||
except DockerException as e:
|
||||
raise DeployerException(e)
|
||||
|
||||
def down(self, timeout, volumes):
|
||||
try:
|
||||
return self.docker.compose.down(timeout=timeout, volumes=volumes)
|
||||
except DockerException as e:
|
||||
raise DeployerException(e)
|
||||
if not opts.o.dry_run:
|
||||
try:
|
||||
return self.docker.compose.down(timeout=timeout, volumes=volumes)
|
||||
except DockerException as e:
|
||||
raise DeployerException(e)
|
||||
|
||||
def update(self):
|
||||
try:
|
||||
return self.docker.compose.restart()
|
||||
except DockerException as e:
|
||||
raise DeployerException(e)
|
||||
if not opts.o.dry_run:
|
||||
try:
|
||||
return self.docker.compose.restart()
|
||||
except DockerException as e:
|
||||
raise DeployerException(e)
|
||||
|
||||
def status(self):
|
||||
try:
|
||||
for p in self.docker.compose.ps():
|
||||
print(f"{p.name}\t{p.state.status}")
|
||||
except DockerException as e:
|
||||
raise DeployerException(e)
|
||||
if not opts.o.dry_run:
|
||||
try:
|
||||
for p in self.docker.compose.ps():
|
||||
print(f"{p.name}\t{p.state.status}")
|
||||
except DockerException as e:
|
||||
raise DeployerException(e)
|
||||
|
||||
def ps(self):
|
||||
try:
|
||||
return self.docker.compose.ps()
|
||||
except DockerException as e:
|
||||
raise DeployerException(e)
|
||||
if not opts.o.dry_run:
|
||||
try:
|
||||
return self.docker.compose.ps()
|
||||
except DockerException as e:
|
||||
raise DeployerException(e)
|
||||
|
||||
def port(self, service, private_port):
|
||||
try:
|
||||
return self.docker.compose.port(service=service, private_port=private_port)
|
||||
except DockerException as e:
|
||||
raise DeployerException(e)
|
||||
if not opts.o.dry_run:
|
||||
try:
|
||||
return self.docker.compose.port(service=service, private_port=private_port)
|
||||
except DockerException as e:
|
||||
raise DeployerException(e)
|
||||
|
||||
def execute(self, service, command, tty, envs):
|
||||
try:
|
||||
return self.docker.compose.execute(service=service, command=command, tty=tty, envs=envs)
|
||||
except DockerException as e:
|
||||
raise DeployerException(e)
|
||||
if not opts.o.dry_run:
|
||||
try:
|
||||
return self.docker.compose.execute(service=service, command=command, tty=tty, envs=envs)
|
||||
except DockerException as e:
|
||||
raise DeployerException(e)
|
||||
|
||||
def logs(self, services, tail, follow, stream):
|
||||
try:
|
||||
return self.docker.compose.logs(services=services, tail=tail, follow=follow, stream=stream)
|
||||
except DockerException as e:
|
||||
raise DeployerException(e)
|
||||
if not opts.o.dry_run:
|
||||
try:
|
||||
return self.docker.compose.logs(services=services, tail=tail, follow=follow, stream=stream)
|
||||
except DockerException as e:
|
||||
raise DeployerException(e)
|
||||
|
||||
def run(self, image: str, command=None, user=None, volumes=None, entrypoint=None, env={}, ports=[], detach=False):
|
||||
try:
|
||||
return self.docker.run(image=image, command=command, user=user, volumes=volumes,
|
||||
entrypoint=entrypoint, envs=env, detach=detach, publish=ports, publish_all=len(ports) == 0)
|
||||
except DockerException as e:
|
||||
raise DeployerException(e)
|
||||
if not opts.o.dry_run:
|
||||
try:
|
||||
return self.docker.run(image=image, command=command, user=user, volumes=volumes,
|
||||
entrypoint=entrypoint, envs=env, detach=detach, publish=ports, publish_all=len(ports) == 0)
|
||||
except DockerException as e:
|
||||
raise DeployerException(e)
|
||||
|
||||
|
||||
class DockerDeployerConfigGenerator(DeployerConfigGenerator):
|
||||
|
||||
@@ -85,54 +85,39 @@ def create_deploy_context(
|
||||
def up_operation(ctx, services_list, stay_attached=False):
|
||||
global_context = ctx.parent.parent.obj
|
||||
deploy_context = ctx.obj
|
||||
if not global_context.dry_run:
|
||||
cluster_context = deploy_context.cluster_context
|
||||
container_exec_env = _make_runtime_env(global_context)
|
||||
for attr, value in container_exec_env.items():
|
||||
os.environ[attr] = value
|
||||
if global_context.verbose:
|
||||
print(f"Running compose up with container_exec_env: {container_exec_env}, extra_args: {services_list}")
|
||||
for pre_start_command in cluster_context.pre_start_commands:
|
||||
_run_command(global_context, cluster_context.cluster, pre_start_command)
|
||||
deploy_context.deployer.up(detach=not stay_attached, services=services_list)
|
||||
for post_start_command in cluster_context.post_start_commands:
|
||||
_run_command(global_context, cluster_context.cluster, post_start_command)
|
||||
_orchestrate_cluster_config(global_context, cluster_context.config, deploy_context.deployer, container_exec_env)
|
||||
cluster_context = deploy_context.cluster_context
|
||||
container_exec_env = _make_runtime_env(global_context)
|
||||
for attr, value in container_exec_env.items():
|
||||
os.environ[attr] = value
|
||||
if global_context.verbose:
|
||||
print(f"Running compose up with container_exec_env: {container_exec_env}, extra_args: {services_list}")
|
||||
for pre_start_command in cluster_context.pre_start_commands:
|
||||
_run_command(global_context, cluster_context.cluster, pre_start_command)
|
||||
deploy_context.deployer.up(detach=not stay_attached, services=services_list)
|
||||
for post_start_command in cluster_context.post_start_commands:
|
||||
_run_command(global_context, cluster_context.cluster, post_start_command)
|
||||
_orchestrate_cluster_config(global_context, cluster_context.config, deploy_context.deployer, container_exec_env)
|
||||
|
||||
|
||||
def down_operation(ctx, delete_volumes, extra_args_list):
|
||||
global_context = ctx.parent.parent.obj
|
||||
if not global_context.dry_run:
|
||||
if global_context.verbose:
|
||||
print("Running compose down")
|
||||
timeout_arg = None
|
||||
if extra_args_list:
|
||||
timeout_arg = extra_args_list[0]
|
||||
# Specify shutdown timeout (default 10s) to give services enough time to shutdown gracefully
|
||||
ctx.obj.deployer.down(timeout=timeout_arg, volumes=delete_volumes)
|
||||
timeout_arg = None
|
||||
if extra_args_list:
|
||||
timeout_arg = extra_args_list[0]
|
||||
# Specify shutdown timeout (default 10s) to give services enough time to shutdown gracefully
|
||||
ctx.obj.deployer.down(timeout=timeout_arg, volumes=delete_volumes)
|
||||
|
||||
|
||||
def status_operation(ctx):
|
||||
global_context = ctx.parent.parent.obj
|
||||
if not global_context.dry_run:
|
||||
if global_context.verbose:
|
||||
print("Running compose status")
|
||||
ctx.obj.deployer.status()
|
||||
ctx.obj.deployer.status()
|
||||
|
||||
|
||||
def update_operation(ctx):
|
||||
global_context = ctx.parent.parent.obj
|
||||
if not global_context.dry_run:
|
||||
if global_context.verbose:
|
||||
print("Running compose update")
|
||||
ctx.obj.deployer.update()
|
||||
ctx.obj.deployer.update()
|
||||
|
||||
|
||||
def ps_operation(ctx):
|
||||
global_context = ctx.parent.parent.obj
|
||||
if not global_context.dry_run:
|
||||
if global_context.verbose:
|
||||
print("Running compose ps")
|
||||
container_list = ctx.obj.deployer.ps()
|
||||
if len(container_list) > 0:
|
||||
print("Running containers:")
|
||||
@@ -187,15 +172,11 @@ def exec_operation(ctx, extra_args):
|
||||
|
||||
|
||||
def logs_operation(ctx, tail: int, follow: bool, extra_args: str):
|
||||
global_context = ctx.parent.parent.obj
|
||||
extra_args_list = list(extra_args) or None
|
||||
if not global_context.dry_run:
|
||||
if global_context.verbose:
|
||||
print("Running compose logs")
|
||||
services_list = extra_args_list if extra_args_list is not None else []
|
||||
logs_stream = ctx.obj.deployer.logs(services=services_list, tail=tail, follow=follow, stream=True)
|
||||
for stream_type, stream_content in logs_stream:
|
||||
print(stream_content.decode("utf-8"), end="")
|
||||
services_list = extra_args_list if extra_args_list is not None else []
|
||||
logs_stream = ctx.obj.deployer.logs(services=services_list, tail=tail, follow=follow, stream=True)
|
||||
for stream_type, stream_content in logs_stream:
|
||||
print(stream_content.decode("utf-8"), end="")
|
||||
|
||||
|
||||
@command.command()
|
||||
@@ -463,7 +444,7 @@ def _orchestrate_cluster_config(ctx, cluster_config, deployer, container_exec_en
|
||||
tty=False,
|
||||
envs=container_exec_env)
|
||||
waiting_for_data = False
|
||||
if ctx.debug:
|
||||
if ctx.debug and not waiting_for_data:
|
||||
print(f"destination output: {destination_output}")
|
||||
|
||||
|
||||
|
||||
@@ -18,11 +18,11 @@ from stack_orchestrator.deploy.k8s.deploy_k8s import K8sDeployer, K8sDeployerCon
|
||||
from stack_orchestrator.deploy.compose.deploy_docker import DockerDeployer, DockerDeployerConfigGenerator
|
||||
|
||||
|
||||
def getDeployerConfigGenerator(type: str):
|
||||
def getDeployerConfigGenerator(type: str, deployment_context):
|
||||
if type == "compose" or type is None:
|
||||
return DockerDeployerConfigGenerator(type)
|
||||
elif type == constants.k8s_deploy_type or type == constants.k8s_kind_deploy_type:
|
||||
return K8sDeployerConfigGenerator(type)
|
||||
return K8sDeployerConfigGenerator(type, deployment_context)
|
||||
else:
|
||||
print(f"ERROR: deploy-to {type} is not valid")
|
||||
|
||||
|
||||
@@ -487,7 +487,7 @@ def create_operation(deployment_command_context, spec_file, deployment_dir, netw
|
||||
deployment_context = DeploymentContext()
|
||||
deployment_context.init(deployment_dir_path)
|
||||
# Call the deployer to generate any deployer-specific files (e.g. for kind)
|
||||
deployer_config_generator = getDeployerConfigGenerator(deployment_type)
|
||||
deployer_config_generator = getDeployerConfigGenerator(deployment_type, deployment_context)
|
||||
# TODO: make deployment_dir_path a Path above
|
||||
deployer_config_generator.generate(deployment_dir_path)
|
||||
call_stack_deploy_create(deployment_context, [network_dir, initial_peers, deployment_command_context])
|
||||
|
||||
@@ -81,69 +81,84 @@ class K8sDeployer(Deployer):
|
||||
self.apps_api = client.AppsV1Api()
|
||||
self.custom_obj_api = client.CustomObjectsApi()
|
||||
|
||||
def up(self, detach, services):
|
||||
|
||||
if self.is_kind():
|
||||
# Create the kind cluster
|
||||
create_cluster(self.kind_cluster_name, self.deployment_dir.joinpath(constants.kind_config_filename))
|
||||
# Ensure the referenced containers are copied into kind
|
||||
load_images_into_kind(self.kind_cluster_name, self.cluster_info.image_set)
|
||||
self.connect_api()
|
||||
|
||||
def _create_volume_data(self):
|
||||
# Create the host-path-mounted PVs for this deployment
|
||||
pvs = self.cluster_info.get_pvs()
|
||||
for pv in pvs:
|
||||
if opts.o.debug:
|
||||
print(f"Sending this pv: {pv}")
|
||||
pv_resp = self.core_api.create_persistent_volume(body=pv)
|
||||
if opts.o.debug:
|
||||
print("PVs created:")
|
||||
print(f"{pv_resp}")
|
||||
if not opts.o.dry_run:
|
||||
pv_resp = self.core_api.create_persistent_volume(body=pv)
|
||||
if opts.o.debug:
|
||||
print("PVs created:")
|
||||
print(f"{pv_resp}")
|
||||
|
||||
# Figure out the PVCs for this deployment
|
||||
pvcs = self.cluster_info.get_pvcs()
|
||||
for pvc in pvcs:
|
||||
if opts.o.debug:
|
||||
print(f"Sending this pvc: {pvc}")
|
||||
pvc_resp = self.core_api.create_namespaced_persistent_volume_claim(body=pvc, namespace=self.k8s_namespace)
|
||||
if opts.o.debug:
|
||||
print("PVCs created:")
|
||||
print(f"{pvc_resp}")
|
||||
|
||||
if not opts.o.dry_run:
|
||||
pvc_resp = self.core_api.create_namespaced_persistent_volume_claim(body=pvc, namespace=self.k8s_namespace)
|
||||
if opts.o.debug:
|
||||
print("PVCs created:")
|
||||
print(f"{pvc_resp}")
|
||||
|
||||
# Figure out the ConfigMaps for this deployment
|
||||
config_maps = self.cluster_info.get_configmaps()
|
||||
for cfg_map in config_maps:
|
||||
if opts.o.debug:
|
||||
print(f"Sending this ConfigMap: {cfg_map}")
|
||||
cfg_rsp = self.core_api.create_namespaced_config_map(
|
||||
body=cfg_map,
|
||||
namespace=self.k8s_namespace
|
||||
)
|
||||
if opts.o.debug:
|
||||
print("ConfigMap created:")
|
||||
print(f"{cfg_rsp}")
|
||||
if not opts.o.dry_run:
|
||||
cfg_rsp = self.core_api.create_namespaced_config_map(
|
||||
body=cfg_map,
|
||||
namespace=self.k8s_namespace
|
||||
)
|
||||
if opts.o.debug:
|
||||
print("ConfigMap created:")
|
||||
print(f"{cfg_rsp}")
|
||||
|
||||
def _create_deployment(self):
|
||||
# Process compose files into a Deployment
|
||||
deployment = self.cluster_info.get_deployment(image_pull_policy=None if self.is_kind() else "Always")
|
||||
# Create the k8s objects
|
||||
if opts.o.debug:
|
||||
print(f"Sending this deployment: {deployment}")
|
||||
deployment_resp = self.apps_api.create_namespaced_deployment(
|
||||
body=deployment, namespace=self.k8s_namespace
|
||||
)
|
||||
if opts.o.debug:
|
||||
print("Deployment created:")
|
||||
print(f"{deployment_resp.metadata.namespace} {deployment_resp.metadata.name} \
|
||||
{deployment_resp.metadata.generation} {deployment_resp.spec.template.spec.containers[0].image}")
|
||||
if not opts.o.dry_run:
|
||||
deployment_resp = self.apps_api.create_namespaced_deployment(
|
||||
body=deployment, namespace=self.k8s_namespace
|
||||
)
|
||||
if opts.o.debug:
|
||||
print("Deployment created:")
|
||||
print(f"{deployment_resp.metadata.namespace} {deployment_resp.metadata.name} \
|
||||
{deployment_resp.metadata.generation} {deployment_resp.spec.template.spec.containers[0].image}")
|
||||
|
||||
service: client.V1Service = self.cluster_info.get_service()
|
||||
service_resp = self.core_api.create_namespaced_service(
|
||||
namespace=self.k8s_namespace,
|
||||
body=service
|
||||
)
|
||||
if opts.o.debug:
|
||||
print("Service created:")
|
||||
print(f"{service_resp}")
|
||||
print(f"Sending this service: {service}")
|
||||
if not opts.o.dry_run:
|
||||
service_resp = self.core_api.create_namespaced_service(
|
||||
namespace=self.k8s_namespace,
|
||||
body=service
|
||||
)
|
||||
if opts.o.debug:
|
||||
print("Service created:")
|
||||
print(f"{service_resp}")
|
||||
|
||||
def up(self, detach, services):
|
||||
if not opts.o.dry_run:
|
||||
if self.is_kind():
|
||||
# Create the kind cluster
|
||||
create_cluster(self.kind_cluster_name, self.deployment_dir.joinpath(constants.kind_config_filename))
|
||||
# Ensure the referenced containers are copied into kind
|
||||
load_images_into_kind(self.kind_cluster_name, self.cluster_info.image_set)
|
||||
self.connect_api()
|
||||
else:
|
||||
print("Dry run mode enabled, skipping k8s API connect")
|
||||
|
||||
self._create_volume_data()
|
||||
self._create_deployment()
|
||||
|
||||
if not self.is_kind():
|
||||
ingress: client.V1Ingress = self.cluster_info.get_ingress()
|
||||
@@ -151,13 +166,14 @@ class K8sDeployer(Deployer):
|
||||
if 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
|
||||
)
|
||||
if opts.o.debug:
|
||||
print("Ingress created:")
|
||||
print(f"{ingress_resp}")
|
||||
if not opts.o.dry_run:
|
||||
ingress_resp = self.networking_api.create_namespaced_ingress(
|
||||
namespace=self.k8s_namespace,
|
||||
body=ingress
|
||||
)
|
||||
if opts.o.debug:
|
||||
print("Ingress created:")
|
||||
print(f"{ingress_resp}")
|
||||
else:
|
||||
if opts.o.debug:
|
||||
print("No ingress configured")
|
||||
@@ -390,8 +406,9 @@ class K8sDeployer(Deployer):
|
||||
class K8sDeployerConfigGenerator(DeployerConfigGenerator):
|
||||
type: str
|
||||
|
||||
def __init__(self, type: str) -> None:
|
||||
def __init__(self, type: str, deployment_context) -> None:
|
||||
self.type = type
|
||||
self.deployment_context = deployment_context
|
||||
super().__init__()
|
||||
|
||||
def generate(self, deployment_dir: Path):
|
||||
@@ -399,7 +416,7 @@ class K8sDeployerConfigGenerator(DeployerConfigGenerator):
|
||||
if self.type == "k8s-kind":
|
||||
# Check the file isn't already there
|
||||
# Get the config file contents
|
||||
content = generate_kind_config(deployment_dir)
|
||||
content = generate_kind_config(deployment_dir, self.deployment_context)
|
||||
if opts.o.debug:
|
||||
print(f"kind config is: {content}")
|
||||
config_file = deployment_dir.joinpath(constants.kind_config_filename)
|
||||
|
||||
@@ -97,11 +97,17 @@ def volume_mounts_for_service(parsed_pod_files, service):
|
||||
if "volumes" in service_obj:
|
||||
volumes = service_obj["volumes"]
|
||||
for mount_string in volumes:
|
||||
# Looks like: test-data:/data
|
||||
parts = mount_string.split(":")
|
||||
volume_name = parts[0]
|
||||
mount_path = parts[1]
|
||||
mount_options = parts[2] if len(parts) == 3 else None
|
||||
# Looks like: test-data:/data or test-data:/data:ro or test-data:/data:rw
|
||||
if opts.o.debug:
|
||||
print(f"mount_string: {mount_string}")
|
||||
mount_split = mount_string.split(":")
|
||||
volume_name = mount_split[0]
|
||||
mount_path = mount_split[1]
|
||||
mount_options = mount_split[2] if len(mount_split) == 3 else None
|
||||
if opts.o.debug:
|
||||
print(f"volumne_name: {volume_name}")
|
||||
print(f"mount path: {mount_path}")
|
||||
print(f"mount options: {mount_options}")
|
||||
volume_device = client.V1VolumeMount(
|
||||
mount_path=mount_path, name=volume_name, read_only="ro" == mount_options)
|
||||
result.append(volume_device)
|
||||
@@ -134,8 +140,9 @@ def _get_host_paths_for_volumes(parsed_pod_files):
|
||||
volumes = parsed_pod_file["volumes"]
|
||||
for volume_name in volumes.keys():
|
||||
volume_definition = volumes[volume_name]
|
||||
host_path = volume_definition["driver_opts"]["device"]
|
||||
result[volume_name] = host_path
|
||||
if volume_definition and "driver_opts" in volume_definition:
|
||||
host_path = volume_definition["driver_opts"]["device"]
|
||||
result[volume_name] = host_path
|
||||
return result
|
||||
|
||||
|
||||
@@ -147,7 +154,7 @@ def _make_absolute_host_path(data_mount_path: Path, deployment_dir: Path) -> Pat
|
||||
return Path.cwd().joinpath(deployment_dir.joinpath("compose").joinpath(data_mount_path)).resolve()
|
||||
|
||||
|
||||
def _generate_kind_mounts(parsed_pod_files, deployment_dir):
|
||||
def _generate_kind_mounts(parsed_pod_files, deployment_dir, deployment_context):
|
||||
volume_definitions = []
|
||||
volume_host_path_map = _get_host_paths_for_volumes(parsed_pod_files)
|
||||
# Note these paths are relative to the location of the pod files (at present)
|
||||
@@ -162,12 +169,21 @@ def _generate_kind_mounts(parsed_pod_files, deployment_dir):
|
||||
if "volumes" in service_obj:
|
||||
volumes = service_obj["volumes"]
|
||||
for mount_string in volumes:
|
||||
# Looks like: test-data:/data
|
||||
(volume_name, mount_path) = mount_string.split(":")
|
||||
volume_definitions.append(
|
||||
f" - hostPath: {_make_absolute_host_path(volume_host_path_map[volume_name], deployment_dir)}\n"
|
||||
f" containerPath: {get_node_pv_mount_path(volume_name)}"
|
||||
)
|
||||
# Looks like: test-data:/data or test-data:/data:ro or test-data:/data:rw
|
||||
if opts.o.debug:
|
||||
print(f"mount_string: {mount_string}")
|
||||
mount_split = mount_string.split(":")
|
||||
volume_name = mount_split[0]
|
||||
mount_path = mount_split[1]
|
||||
if opts.o.debug:
|
||||
print(f"volumne_name: {volume_name}")
|
||||
print(f"map: {volume_host_path_map}")
|
||||
print(f"mount path: {mount_path}")
|
||||
if volume_name not in deployment_context.spec.get_configmaps():
|
||||
volume_definitions.append(
|
||||
f" - hostPath: {_make_absolute_host_path(volume_host_path_map[volume_name], deployment_dir)}\n"
|
||||
f" containerPath: {get_node_pv_mount_path(volume_name)}\n"
|
||||
)
|
||||
return (
|
||||
"" if len(volume_definitions) == 0 else (
|
||||
" extraMounts:\n"
|
||||
@@ -189,7 +205,7 @@ def _generate_kind_port_mappings(parsed_pod_files):
|
||||
for port_string in ports:
|
||||
# TODO handle the complex cases
|
||||
# Looks like: 80 or something more complicated
|
||||
port_definitions.append(f" - containerPort: {port_string}\n hostPort: {port_string}")
|
||||
port_definitions.append(f" - containerPort: {port_string}\n hostPort: {port_string}\n")
|
||||
return (
|
||||
"" if len(port_definitions) == 0 else (
|
||||
" extraPortMappings:\n"
|
||||
@@ -223,13 +239,13 @@ def envs_from_environment_variables_map(map: Mapping[str, str]) -> List[client.V
|
||||
# extraMounts:
|
||||
# - hostPath: /path/to/my/files
|
||||
# containerPath: /files
|
||||
def generate_kind_config(deployment_dir: Path):
|
||||
def generate_kind_config(deployment_dir: Path, deployment_context):
|
||||
compose_file_dir = deployment_dir.joinpath("compose")
|
||||
# TODO: this should come from the stack file, not this way
|
||||
pod_files = [p for p in compose_file_dir.iterdir() if p.is_file()]
|
||||
parsed_pod_files_map = parsed_pod_files_map_from_file_names(pod_files)
|
||||
port_mappings_yml = _generate_kind_port_mappings(parsed_pod_files_map)
|
||||
mounts_yml = _generate_kind_mounts(parsed_pod_files_map, deployment_dir)
|
||||
mounts_yml = _generate_kind_mounts(parsed_pod_files_map, deployment_dir, deployment_context)
|
||||
return (
|
||||
"kind: Cluster\n"
|
||||
"apiVersion: kind.x-k8s.io/v1alpha4\n"
|
||||
|
||||
@@ -19,7 +19,7 @@ import sys
|
||||
import ruamel.yaml
|
||||
from pathlib import Path
|
||||
from dotenv import dotenv_values
|
||||
from typing import Mapping
|
||||
from typing import Mapping, Set, List
|
||||
|
||||
|
||||
def include_exclude_check(s, include, exclude):
|
||||
@@ -81,17 +81,17 @@ def get_pod_list(parsed_stack):
|
||||
return result
|
||||
|
||||
|
||||
def get_plugin_code_paths(stack):
|
||||
def get_plugin_code_paths(stack) -> List[Path]:
|
||||
parsed_stack = get_parsed_stack_config(stack)
|
||||
pods = parsed_stack["pods"]
|
||||
result = []
|
||||
result: Set[Path] = set()
|
||||
for pod in pods:
|
||||
if type(pod) is str:
|
||||
result.append(get_stack_file_path(stack).parent)
|
||||
result.add(get_stack_file_path(stack).parent)
|
||||
else:
|
||||
pod_root_dir = os.path.join(get_dev_root_path(None), pod["repository"].split("/")[-1], pod["path"])
|
||||
result.append(Path(os.path.join(pod_root_dir, "stack")))
|
||||
return result
|
||||
result.add(Path(os.path.join(pod_root_dir, "stack")))
|
||||
return list(result)
|
||||
|
||||
|
||||
def get_pod_file_path(parsed_stack, pod_name: str):
|
||||
@@ -139,6 +139,13 @@ def get_compose_file_dir():
|
||||
return source_compose_dir
|
||||
|
||||
|
||||
def get_config_file_dir():
|
||||
# TODO: refactor to use common code with deploy command
|
||||
data_dir = Path(__file__).absolute().parent.joinpath("data")
|
||||
source_config_dir = data_dir.joinpath("config")
|
||||
return source_config_dir
|
||||
|
||||
|
||||
def get_parsed_deployment_spec(spec_file):
|
||||
spec_file_path = Path(spec_file)
|
||||
try:
|
||||
|
||||
@@ -97,6 +97,10 @@ if [ ! "$create_file_content" == "create-command-output-data" ]; then
|
||||
echo "deploy create test: FAILED"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Add a config file to be picked up by the ConfigMap before starting.
|
||||
echo "dbfc7a4d-44a7-416d-b5f3-29842cc47650" > $test_deployment_dir/data/test-config/test_config
|
||||
|
||||
echo "deploy create output file test: passed"
|
||||
# Try to start the deployment
|
||||
$TEST_TARGET_SO deployment --dir $test_deployment_dir start
|
||||
@@ -117,6 +121,16 @@ else
|
||||
echo "deployment config test: FAILED"
|
||||
delete_cluster_exit
|
||||
fi
|
||||
|
||||
# Check that the ConfigMap is mounted and contains the expected content.
|
||||
log_output_4=$( $TEST_TARGET_SO deployment --dir $test_deployment_dir logs )
|
||||
if [[ "$log_output_4" == *"/config/test_config:"* ]] && [[ "$log_output_4" == *"dbfc7a4d-44a7-416d-b5f3-29842cc47650"* ]]; then
|
||||
echo "deployment ConfigMap test: passed"
|
||||
else
|
||||
echo "deployment ConfigMap test: FAILED"
|
||||
delete_cluster_exit
|
||||
fi
|
||||
|
||||
# Stop then start again and check the volume was preserved
|
||||
$TEST_TARGET_SO deployment --dir $test_deployment_dir stop
|
||||
# Sleep a bit just in case
|
||||
@@ -125,8 +139,8 @@ sleep 20
|
||||
$TEST_TARGET_SO deployment --dir $test_deployment_dir start
|
||||
wait_for_pods_started
|
||||
wait_for_log_output
|
||||
log_output_4=$( $TEST_TARGET_SO deployment --dir $test_deployment_dir logs )
|
||||
if [[ "$log_output_4" == *"Filesystem is old"* ]]; then
|
||||
log_output_5=$( $TEST_TARGET_SO deployment --dir $test_deployment_dir logs )
|
||||
if [[ "$log_output_5" == *"Filesystem is old"* ]]; then
|
||||
echo "Retain volumes test: passed"
|
||||
else
|
||||
echo "Retain volumes test: FAILED"
|
||||
|
||||
Reference in New Issue
Block a user