forked from cerc-io/stack-orchestrator
Compare commits
11
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1d8f252a51 | ||
|
|
161665ef72 | ||
|
|
9c5f6469ff | ||
|
|
85225c72d7 | ||
|
|
223d1171e8 | ||
|
|
1e38e16550 | ||
|
|
dddae8cc7a | ||
|
|
aa702737ef | ||
|
|
c9155eafd2 | ||
|
|
1ffc6b1687 | ||
|
|
87c25dfb5e |
@@ -0,0 +1,39 @@
|
||||
name: Deploy Test
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: '*'
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- ci-test
|
||||
|
||||
# Needed until we can incorporate docker startup into the executor container
|
||||
env:
|
||||
DOCKER_HOST: unix:///var/run/dind.sock
|
||||
|
||||
jobs:
|
||||
test:
|
||||
name: "Run deploy test suite"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: "Clone project repository"
|
||||
uses: actions/checkout@v3
|
||||
- name: "Install Python"
|
||||
uses: cerc-io/setup-python@v4
|
||||
with:
|
||||
python-version: '3.8'
|
||||
- name: "Print Python version"
|
||||
run: python3 --version
|
||||
- name: "Install shiv"
|
||||
run: pip install shiv
|
||||
- name: "Generate build version file"
|
||||
run: ./scripts/create_build_tag_file.sh
|
||||
- name: "Build local shiv package"
|
||||
run: ./scripts/build_shiv_package.sh
|
||||
- name: Start dockerd # Also needed until we can incorporate into the executor
|
||||
run: |
|
||||
dockerd -H $DOCKER_HOST --userland-proxy=false &
|
||||
sleep 5
|
||||
- name: "Run deploy tests"
|
||||
run: ./tests/deploy/run-deploy-test.sh
|
||||
@@ -1,4 +1,4 @@
|
||||
name: Integration Test
|
||||
name: Smoke Test
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
name: Deploy Test
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: '*'
|
||||
push:
|
||||
branches: '*'
|
||||
|
||||
jobs:
|
||||
test:
|
||||
name: "Run deploy test suite"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: "Clone project repository"
|
||||
uses: actions/checkout@v3
|
||||
- name: "Install Python"
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.8'
|
||||
- name: "Print Python version"
|
||||
run: python3 --version
|
||||
- name: "Install shiv"
|
||||
run: pip install shiv
|
||||
- name: "Generate build version file"
|
||||
run: ./scripts/create_build_tag_file.sh
|
||||
- name: "Build local shiv package"
|
||||
run: ./scripts/build_shiv_package.sh
|
||||
- name: "Run deploy tests"
|
||||
run: ./tests/deploy/run-deploy-test.sh
|
||||
@@ -1,4 +1,4 @@
|
||||
name: Test
|
||||
name: Smoke Test
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
|
||||
@@ -90,7 +90,7 @@ def command(ctx, include, exclude, force_rebuild, extra_build_args):
|
||||
"CERC_CONTAINER_BASE_DIR": container_build_dir,
|
||||
"CERC_HOST_UID": f"{os.getuid()}",
|
||||
"CERC_HOST_GID": f"{os.getgid()}",
|
||||
"DOCKER_BUILDKIT": "0"
|
||||
"DOCKER_BUILDKIT": config("DOCKER_BUILDKIT", default="0")
|
||||
}
|
||||
container_build_env.update({"CERC_SCRIPT_DEBUG": "true"} if debug else {})
|
||||
container_build_env.update({"CERC_FORCE_REBUILD": "true"} if force_rebuild else {})
|
||||
|
||||
@@ -2,6 +2,7 @@ version: '3.7'
|
||||
|
||||
services:
|
||||
fixturenet-eth-bootnode-geth:
|
||||
restart: always
|
||||
hostname: fixturenet-eth-bootnode-geth
|
||||
env_file:
|
||||
- ../config/fixturenet-eth/fixturenet-eth.env
|
||||
@@ -15,6 +16,7 @@ services:
|
||||
- "30303"
|
||||
|
||||
fixturenet-eth-geth-1:
|
||||
restart: always
|
||||
hostname: fixturenet-eth-geth-1
|
||||
cap_add:
|
||||
- SYS_PTRACE
|
||||
@@ -42,6 +44,7 @@ services:
|
||||
- "6060"
|
||||
|
||||
fixturenet-eth-geth-2:
|
||||
restart: always
|
||||
hostname: fixturenet-eth-geth-2
|
||||
healthcheck:
|
||||
test: ["CMD", "nc", "-v", "localhost", "8545"]
|
||||
@@ -60,12 +63,14 @@ services:
|
||||
- fixturenet_eth_geth_2_data:/root/ethdata
|
||||
|
||||
fixturenet-eth-bootnode-lighthouse:
|
||||
restart: always
|
||||
hostname: fixturenet-eth-bootnode-lighthouse
|
||||
environment:
|
||||
RUN_BOOTNODE: "true"
|
||||
image: cerc/fixturenet-eth-lighthouse:local
|
||||
|
||||
fixturenet-eth-lighthouse-1:
|
||||
restart: always
|
||||
hostname: fixturenet-eth-lighthouse-1
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "--tries=1", "--connect-timeout=1", "--quiet", "-O", "-", "http://localhost:8001/eth/v2/beacon/blocks/head"]
|
||||
@@ -91,6 +96,7 @@ services:
|
||||
- "8001"
|
||||
|
||||
fixturenet-eth-lighthouse-2:
|
||||
restart: always
|
||||
hostname: fixturenet-eth-lighthouse-2
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "--tries=1", "--connect-timeout=1", "--quiet", "-O", "-", "http://localhost:8001/eth/v2/beacon/blocks/head"]
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
version: "3.2"
|
||||
services:
|
||||
laconicd:
|
||||
restart: unless-stopped
|
||||
image: cerc/laconicd:local
|
||||
command: ["sh", "/docker-entrypoint-scripts.d/create-fixturenet.sh"]
|
||||
volumes:
|
||||
# The cosmos-sdk node's database directory:
|
||||
- laconicd-data:/root/.laconicd/data
|
||||
# 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
|
||||
|
||||
@@ -5,6 +5,7 @@ services:
|
||||
# Creates / updates the configuration for L1 contracts deployment
|
||||
# Deploys the L1 smart contracts (outputs to volume l1_deployment)
|
||||
fixturenet-optimism-contracts:
|
||||
restart: on-failure
|
||||
hostname: fixturenet-optimism-contracts
|
||||
image: cerc/optimism-contracts:local
|
||||
env_file:
|
||||
@@ -35,6 +36,7 @@ services:
|
||||
|
||||
# Generates the config files required for L2 (outputs to volume l2_config)
|
||||
op-node-l2-config-gen:
|
||||
restart: on-failure
|
||||
image: cerc/optimism-op-node:local
|
||||
depends_on:
|
||||
fixturenet-optimism-contracts:
|
||||
@@ -54,6 +56,7 @@ services:
|
||||
|
||||
# Initializes and runs the L2 execution client (outputs to volume l2_geth_data)
|
||||
op-geth:
|
||||
restart: always
|
||||
image: cerc/optimism-l2geth:local
|
||||
depends_on:
|
||||
op-node-l2-config-gen:
|
||||
@@ -76,6 +79,7 @@ services:
|
||||
|
||||
# Runs the L2 consensus client (Sequencer node)
|
||||
op-node:
|
||||
restart: always
|
||||
image: cerc/optimism-op-node:local
|
||||
depends_on:
|
||||
op-geth:
|
||||
@@ -103,6 +107,7 @@ services:
|
||||
|
||||
# Runs the batcher (takes transactions from the Sequencer and publishes them to L1)
|
||||
op-batcher:
|
||||
restart: always
|
||||
image: cerc/optimism-op-batcher:local
|
||||
depends_on:
|
||||
op-node:
|
||||
@@ -129,6 +134,7 @@ services:
|
||||
|
||||
# Runs the proposer (periodically submits new state roots to L1)
|
||||
op-proposer:
|
||||
restart: always
|
||||
image: cerc/optimism-op-proposer:local
|
||||
depends_on:
|
||||
op-node:
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# Add-on pod to include foundry tooling within a fixturenet
|
||||
services:
|
||||
foundry:
|
||||
restart: always
|
||||
image: cerc/foundry:local
|
||||
command: ["while :; do sleep 600; done"]
|
||||
volumes:
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
version: "3.2"
|
||||
services:
|
||||
test:
|
||||
image: cerc/test-container:local
|
||||
restart: always
|
||||
environment:
|
||||
CERC_SCRIPT_DEBUG: ${CERC_SCRIPT_DEBUG}
|
||||
volumes:
|
||||
- test-data:/var
|
||||
ports:
|
||||
- "80"
|
||||
|
||||
volumes:
|
||||
test-data:
|
||||
|
||||
@@ -27,8 +27,8 @@ yarn_info_output=$(yarn info --json $versioned_target_package 2>/dev/null)
|
||||
# If it doesn't exist there will be no .data.dist.tarball element,
|
||||
# and jq will output the string "null"
|
||||
package_tarball=$(echo $yarn_info_output | jq -r .data.dist.tarball)
|
||||
if [[ $package_tarball == "null" ]]; then
|
||||
echo "FATAL: Target package version ($versioned_target_package) not found" >&2
|
||||
if [[ "$yarn_info_output" == "" || $package_tarball == "null" ]]; then
|
||||
echo "FATAL: Target package version ($versioned_target_package) not found (or bad npm auth token)" >&2
|
||||
exit 1
|
||||
fi
|
||||
# Code below parses out the values we need
|
||||
|
||||
@@ -6,7 +6,7 @@ RUN go install github.com/go-delve/delve/cmd/dlv@latest
|
||||
|
||||
FROM cerc/go-ethereum:local as geth
|
||||
|
||||
FROM alpine:latest
|
||||
FROM alpine:3.17
|
||||
RUN apk add --no-cache python3 python3-dev py3-pip curl wget jq build-base gettext libintl openssl bash bind-tools postgresql-client
|
||||
|
||||
COPY --from=delve /go/bin/dlv /usr/local/bin/
|
||||
|
||||
@@ -13,22 +13,26 @@ DEBUG_LEVEL=${1:-info}
|
||||
|
||||
echo "Starting bootnode"
|
||||
|
||||
if [ ! -f "$DATADIR/bootnode/enr.dat" ]; then
|
||||
echo "Generating bootnode enr"
|
||||
lcli \
|
||||
generate-bootnode-enr \
|
||||
--ip $ENR_IP \
|
||||
--udp-port $BOOTNODE_PORT \
|
||||
--tcp-port $BOOTNODE_PORT \
|
||||
--genesis-fork-version $GENESIS_FORK_VERSION \
|
||||
--output-dir $DATADIR/bootnode
|
||||
|
||||
bootnode_enr=`cat $DATADIR/bootnode/enr.dat`
|
||||
echo "- $bootnode_enr" > $TESTNET_DIR/boot_enr.yaml
|
||||
|
||||
echo "Generated bootnode enr and written to $TESTNET_DIR/boot_enr.yaml"
|
||||
# Clean up existing ENR dir to avoid node connectivity issues on a restart
|
||||
if [ -d "$DATADIR/bootnode" ]; then
|
||||
echo "Removing existing bootnode enr directory"
|
||||
rm -r "$DATADIR/bootnode"
|
||||
fi
|
||||
|
||||
echo "Generating bootnode enr"
|
||||
lcli \
|
||||
generate-bootnode-enr \
|
||||
--ip $ENR_IP \
|
||||
--udp-port $BOOTNODE_PORT \
|
||||
--tcp-port $BOOTNODE_PORT \
|
||||
--genesis-fork-version $GENESIS_FORK_VERSION \
|
||||
--output-dir $DATADIR/bootnode
|
||||
|
||||
bootnode_enr=`cat $DATADIR/bootnode/enr.dat`
|
||||
echo "- $bootnode_enr" > $TESTNET_DIR/boot_enr.yaml
|
||||
|
||||
echo "Generated bootnode enr and written to $TESTNET_DIR/boot_enr.yaml"
|
||||
|
||||
exec lighthouse boot_node \
|
||||
--testnet-dir $TESTNET_DIR \
|
||||
--port $BOOTNODE_PORT \
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
#!/bin/sh
|
||||
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
if [ -n "$CERC_SCRIPT_DEBUG" ]; then
|
||||
set -x
|
||||
fi
|
||||
# Test if the container's filesystem is old (run previously) or new
|
||||
EXISTSFILENAME=/var/exists
|
||||
echo "Test container starting"
|
||||
if [[ -f "$EXISTSFILENAME" ]];
|
||||
then
|
||||
TIMESTAMP = `cat $EXISTSFILENAME`
|
||||
TIMESTAMP=`cat $EXISTSFILENAME`
|
||||
echo "Filesystem is old, created: $TIMESTAMP"
|
||||
else
|
||||
echo "Filesystem is fresh"
|
||||
|
||||
+128
-89
@@ -28,108 +28,146 @@ import importlib.resources
|
||||
from pathlib import Path
|
||||
from .util import include_exclude_check, get_parsed_stack_config
|
||||
|
||||
class DeployCommandContext(object):
|
||||
def __init__(self, cluster_context, docker):
|
||||
self.cluster_context = cluster_context
|
||||
self.docker = docker
|
||||
|
||||
@click.command()
|
||||
|
||||
@click.group()
|
||||
@click.option("--include", help="only start these components")
|
||||
@click.option("--exclude", help="don\'t start these components")
|
||||
@click.option("--env-file", help="env file to be used")
|
||||
@click.option("--cluster", help="specify a non-default cluster name")
|
||||
@click.argument('command', required=True) # help: command: up|down|ps
|
||||
@click.argument('extra_args', nargs=-1) # help: command: up|down|ps <service1> <service2>
|
||||
@click.pass_context
|
||||
def command(ctx, include, exclude, env_file, cluster, command, extra_args):
|
||||
def command(ctx, include, exclude, env_file, cluster):
|
||||
'''deploy a stack'''
|
||||
|
||||
# TODO: implement option exclusion and command value constraint lost with the move from argparse to click
|
||||
|
||||
debug = ctx.obj.debug
|
||||
quiet = ctx.obj.quiet
|
||||
verbose = ctx.obj.verbose
|
||||
local_stack = ctx.obj.local_stack
|
||||
dry_run = ctx.obj.dry_run
|
||||
stack = ctx.obj.stack
|
||||
|
||||
cluster_context = _make_cluster_context(ctx.obj, include, exclude, cluster)
|
||||
cluster_context = _make_cluster_context(ctx.obj, include, exclude, cluster, env_file)
|
||||
|
||||
# See: https://gabrieldemarmiesse.github.io/python-on-whales/sub-commands/compose/
|
||||
docker = DockerClient(compose_files=cluster_context.compose_files, compose_project_name=cluster_context.cluster, compose_env_file=env_file)
|
||||
docker = DockerClient(compose_files=cluster_context.compose_files, compose_project_name=cluster_context.cluster,
|
||||
compose_env_file=cluster_context.env_file)
|
||||
|
||||
ctx.obj = DeployCommandContext(cluster_context, docker)
|
||||
# Subcommand is executed now, by the magic of click
|
||||
|
||||
|
||||
@command.command()
|
||||
@click.argument('extra_args', nargs=-1) # help: command: up <service1> <service2>
|
||||
@click.pass_context
|
||||
def up(ctx, extra_args):
|
||||
global_context = ctx.parent.parent.obj
|
||||
extra_args_list = list(extra_args) or None
|
||||
if not global_context.dry_run:
|
||||
cluster_context = ctx.obj.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: {extra_args_list}")
|
||||
for pre_start_command in cluster_context.pre_start_commands:
|
||||
_run_command(global_context, cluster_context.cluster, pre_start_command)
|
||||
ctx.obj.docker.compose.up(detach=True, services=extra_args_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, ctx.obj.docker, container_exec_env)
|
||||
|
||||
if not dry_run:
|
||||
if command == "up":
|
||||
container_exec_env = _make_runtime_env(ctx.obj)
|
||||
for attr, value in container_exec_env.items():
|
||||
os.environ[attr] = value
|
||||
if verbose:
|
||||
print(f"Running compose up with container_exec_env: {container_exec_env}, extra_args: {extra_args_list}")
|
||||
for pre_start_command in cluster_context.pre_start_commands:
|
||||
_run_command(ctx.obj, cluster_context.cluster, pre_start_command)
|
||||
docker.compose.up(detach=True, services=extra_args_list)
|
||||
for post_start_command in cluster_context.post_start_commands:
|
||||
_run_command(ctx.obj, cluster_context.cluster, post_start_command)
|
||||
|
||||
_orchestrate_cluster_config(ctx.obj, cluster_context.config, docker, container_exec_env)
|
||||
@command.command()
|
||||
@click.option("--delete-volumes/--preserve-volumes", default=False, help="delete data volumes")
|
||||
@click.argument('extra_args', nargs=-1) # help: command: down<service1> <service2>
|
||||
@click.pass_context
|
||||
def down(ctx, delete_volumes, extra_args):
|
||||
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 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.docker.compose.down(timeout=timeout_arg, volumes=delete_volumes)
|
||||
|
||||
elif command == "down":
|
||||
if verbose:
|
||||
print("Running compose down")
|
||||
|
||||
timeout_arg = None
|
||||
if extra_args_list:
|
||||
timeout_arg=extra_args_list[0]
|
||||
@command.command()
|
||||
@click.pass_context
|
||||
def ps(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.docker.compose.ps()
|
||||
if len(container_list) > 0:
|
||||
print("Running containers:")
|
||||
for container in container_list:
|
||||
print(f"id: {container.id}, name: {container.name}, ports: ", end="")
|
||||
ports = container.network_settings.ports
|
||||
comma = ""
|
||||
for port_mapping in ports.keys():
|
||||
mapping = ports[port_mapping]
|
||||
print(comma, end="")
|
||||
if mapping is None:
|
||||
print(f"{port_mapping}", end="")
|
||||
else:
|
||||
print(f"{mapping[0]['HostIp']}:{mapping[0]['HostPort']}->{port_mapping}", end="")
|
||||
comma = ", "
|
||||
print()
|
||||
else:
|
||||
print("No containers running")
|
||||
|
||||
# Specify shutdown timeout (default 10s) to give services enough time to shutdown gracefully
|
||||
docker.compose.down(timeout=timeout_arg)
|
||||
elif command == "exec":
|
||||
if extra_args_list is None or len(extra_args_list) < 2:
|
||||
print("Usage: exec <service> <cmd>")
|
||||
sys.exit(1)
|
||||
service_name = extra_args_list[0]
|
||||
command_to_exec = ["sh", "-c"] + extra_args_list[1:]
|
||||
container_exec_env = _make_runtime_env(ctx.obj)
|
||||
if verbose:
|
||||
print(f"Running compose exec {service_name} {command_to_exec}")
|
||||
try:
|
||||
docker.compose.execute(service_name, command_to_exec, envs=container_exec_env)
|
||||
except DockerException as error:
|
||||
print(f"container command returned error exit status")
|
||||
elif command == "port":
|
||||
if extra_args_list is None or len(extra_args_list) < 2:
|
||||
print("Usage: port <service> <exposed-port>")
|
||||
sys.exit(1)
|
||||
service_name = extra_args_list[0]
|
||||
exposed_port = extra_args_list[1]
|
||||
if verbose:
|
||||
print(f"Running compose port {service_name} {exposed_port}")
|
||||
mapped_port_data = docker.compose.port(service_name, exposed_port)
|
||||
print(f"{mapped_port_data[0]}:{mapped_port_data[1]}")
|
||||
elif command == "ps":
|
||||
if verbose:
|
||||
print("Running compose ps")
|
||||
container_list = docker.compose.ps()
|
||||
if len(container_list) > 0:
|
||||
print("Running containers:")
|
||||
for container in container_list:
|
||||
print(f"id: {container.id}, name: {container.name}, ports: ", end="")
|
||||
ports = container.network_settings.ports
|
||||
comma = ""
|
||||
for port_mapping in ports.keys():
|
||||
mapping = ports[port_mapping]
|
||||
print(comma, end="")
|
||||
if mapping is None:
|
||||
print(f"{port_mapping}", end="")
|
||||
else:
|
||||
print(f"{mapping[0]['HostIp']}:{mapping[0]['HostPort']}->{port_mapping}", end="")
|
||||
comma = ", "
|
||||
print()
|
||||
else:
|
||||
print("No containers running")
|
||||
elif command == "logs":
|
||||
if verbose:
|
||||
print("Running compose logs")
|
||||
logs_output = docker.compose.logs(services=extra_args_list if extra_args_list is not None else [])
|
||||
print(logs_output)
|
||||
|
||||
@command.command()
|
||||
@click.argument('extra_args', nargs=-1) # help: command: port <service1> <service2>
|
||||
@click.pass_context
|
||||
def port(ctx, extra_args):
|
||||
global_context = ctx.parent.parent.obj
|
||||
extra_args_list = list(extra_args) or None
|
||||
if not global_context.dry_run:
|
||||
if extra_args_list is None or len(extra_args_list) < 2:
|
||||
print("Usage: port <service> <exposed-port>")
|
||||
sys.exit(1)
|
||||
service_name = extra_args_list[0]
|
||||
exposed_port = extra_args_list[1]
|
||||
if global_context.verbose:
|
||||
print(f"Running compose port {service_name} {exposed_port}")
|
||||
mapped_port_data = ctx.obj.docker.compose.port(service_name, exposed_port)
|
||||
print(f"{mapped_port_data[0]}:{mapped_port_data[1]}")
|
||||
|
||||
|
||||
@command.command()
|
||||
@click.argument('extra_args', nargs=-1) # help: command: exec <service> <command>
|
||||
@click.pass_context
|
||||
def exec(ctx, extra_args):
|
||||
global_context = ctx.parent.parent.obj
|
||||
extra_args_list = list(extra_args) or None
|
||||
if not global_context.dry_run:
|
||||
if extra_args_list is None or len(extra_args_list) < 2:
|
||||
print("Usage: exec <service> <cmd>")
|
||||
sys.exit(1)
|
||||
service_name = extra_args_list[0]
|
||||
command_to_exec = ["sh", "-c"] + extra_args_list[1:]
|
||||
container_exec_env = _make_runtime_env(global_context)
|
||||
if global_context.verbose:
|
||||
print(f"Running compose exec {service_name} {command_to_exec}")
|
||||
try:
|
||||
ctx.obj.docker.compose.execute(service_name, command_to_exec, envs=container_exec_env)
|
||||
except DockerException as error:
|
||||
print(f"container command returned error exit status")
|
||||
|
||||
|
||||
@command.command()
|
||||
@click.argument('extra_args', nargs=-1) # help: command: logs <service1> <service2>
|
||||
@click.pass_context
|
||||
def logs(ctx, extra_args):
|
||||
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")
|
||||
logs_output = ctx.obj.docker.compose.logs(services=extra_args_list if extra_args_list is not None else [])
|
||||
print(logs_output)
|
||||
|
||||
|
||||
def get_stack_status(ctx, stack):
|
||||
@@ -137,7 +175,7 @@ def get_stack_status(ctx, stack):
|
||||
ctx_copy = copy.copy(ctx)
|
||||
ctx_copy.stack = stack
|
||||
|
||||
cluster_context = _make_cluster_context(ctx_copy, None, None, None)
|
||||
cluster_context = _make_cluster_context(ctx_copy, None, None, None, None)
|
||||
docker = DockerClient(compose_files=cluster_context.compose_files, compose_project_name=cluster_context.cluster)
|
||||
# TODO: refactor to avoid duplicating this code above
|
||||
if ctx.verbose:
|
||||
@@ -162,7 +200,7 @@ def _make_runtime_env(ctx):
|
||||
return container_exec_env
|
||||
|
||||
|
||||
def _make_cluster_context(ctx, include, exclude, cluster):
|
||||
def _make_cluster_context(ctx, include, exclude, cluster, env_file):
|
||||
|
||||
if ctx.local_stack:
|
||||
dev_root_path = os.getcwd()[0:os.getcwd().rindex("stack-orchestrator")]
|
||||
@@ -235,16 +273,17 @@ def _make_cluster_context(ctx, include, exclude, cluster):
|
||||
if ctx.verbose:
|
||||
print(f"files: {compose_files}")
|
||||
|
||||
return cluster_context(cluster, compose_files, pre_start_commands, post_start_commands, cluster_config)
|
||||
return cluster_context(cluster, compose_files, pre_start_commands, post_start_commands, cluster_config, env_file)
|
||||
|
||||
|
||||
class cluster_context:
|
||||
def __init__(self, cluster, compose_files, pre_start_commands, post_start_commands, config) -> None:
|
||||
def __init__(self, cluster, compose_files, pre_start_commands, post_start_commands, config, env_file) -> None:
|
||||
self.cluster = cluster
|
||||
self.compose_files = compose_files
|
||||
self.pre_start_commands = pre_start_commands
|
||||
self.post_start_commands = post_start_commands
|
||||
self.config = config
|
||||
self.env_file = env_file
|
||||
|
||||
|
||||
def _convert_to_new_format(old_pod_array):
|
||||
|
||||
Executable
+56
@@ -0,0 +1,56 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
if [ -n "$CERC_SCRIPT_DEBUG" ]; then
|
||||
set -x
|
||||
fi
|
||||
# Dump environment variables for debugging
|
||||
echo "Environment variables:"
|
||||
env
|
||||
# Test basic stack-orchestrator deploy
|
||||
echo "Running stack-orchestrator deploy test"
|
||||
# Bit of a hack, test the most recent package
|
||||
TEST_TARGET_SO=$( ls -t1 ./package/laconic-so* | head -1 )
|
||||
# Set a non-default repo dir
|
||||
export CERC_REPO_BASE_DIR=~/stack-orchestrator-test/repo-base-dir
|
||||
echo "Testing this package: $TEST_TARGET_SO"
|
||||
echo "Test version command"
|
||||
reported_version_string=$( $TEST_TARGET_SO version )
|
||||
echo "Version reported is: ${reported_version_string}"
|
||||
echo "Cloning repositories into: $CERC_REPO_BASE_DIR"
|
||||
rm -rf $CERC_REPO_BASE_DIR
|
||||
mkdir -p $CERC_REPO_BASE_DIR
|
||||
# Test bringing the test container up and down
|
||||
# with and without volume removal
|
||||
$TEST_TARGET_SO --stack test setup-repositories
|
||||
$TEST_TARGET_SO --stack test build-containers
|
||||
$TEST_TARGET_SO --stack test deploy up
|
||||
# Test deploy port command
|
||||
deploy_port_output=$( $TEST_TARGET_SO --stack test deploy port test 80 )
|
||||
if [[ "$deploy_port_output" =~ ^0.0.0.0:[1-9][0-9]* ]]; then
|
||||
echo "Deploy port test: passed"
|
||||
else
|
||||
echo "Deploy port test: FAILED"
|
||||
exit 1
|
||||
fi
|
||||
$TEST_TARGET_SO --stack test deploy down
|
||||
# The next time we bring the container up the volume will be old (from the previous run above)
|
||||
$TEST_TARGET_SO --stack test deploy up
|
||||
log_output_1=$( $TEST_TARGET_SO --stack test deploy logs )
|
||||
if [[ "$log_output_1" == *"Filesystem is old"* ]]; then
|
||||
echo "Retain volumes test: passed"
|
||||
else
|
||||
echo "Retain volumes test: FAILED"
|
||||
exit 1
|
||||
fi
|
||||
$TEST_TARGET_SO --stack test deploy down --delete-volumes
|
||||
# Now when we bring the container up the volume will be new again
|
||||
$TEST_TARGET_SO --stack test deploy up
|
||||
log_output_2=$( $TEST_TARGET_SO --stack test deploy logs )
|
||||
if [[ "$log_output_2" == *"Filesystem is fresh"* ]]; then
|
||||
echo "Delete volumes test: passed"
|
||||
else
|
||||
echo "Delete volumes test: FAILED"
|
||||
exit 1
|
||||
fi
|
||||
$TEST_TARGET_SO --stack test deploy down --delete-volumes
|
||||
echo "Test passed"
|
||||
Reference in New Issue
Block a user