Implement container build support

This commit is contained in:
David Boreham 2023-11-14 20:41:11 -07:00
parent 918ef25f1a
commit daf099b5ea
3 changed files with 35 additions and 11 deletions

View File

@ -27,7 +27,7 @@ import subprocess
import click import click
import importlib.resources import importlib.resources
from pathlib import Path from pathlib import Path
from stack_orchestrator.util import include_exclude_check, get_parsed_stack_config from stack_orchestrator.util import include_exclude_check, get_parsed_stack_config, stack_is_external
from stack_orchestrator.base import get_npm_registry_url from stack_orchestrator.base import get_npm_registry_url
# TODO: find a place for this # TODO: find a place for this
@ -58,7 +58,8 @@ def make_container_build_env(dev_root_path: str,
return container_build_env return container_build_env
def process_container(container, def process_container(stack: str,
container,
container_build_dir: str, container_build_dir: str,
container_build_env: dict, container_build_env: dict,
dev_root_path: str, dev_root_path: str,
@ -69,12 +70,29 @@ def process_container(container,
): ):
if not quiet: if not quiet:
print(f"Building: {container}") print(f"Building: {container}")
build_dir = os.path.join(container_build_dir, container.replace("/", "-"))
build_script_filename = os.path.join(build_dir, "build.sh") default_container_tag = f"{container}:local"
container_build_env.update({"CERC_DEFAULT_CONTAINER_IMAGE_TAG": default_container_tag})
# Check if this is in an external stack
if stack_is_external(stack):
container_parent_dir = Path(stack).joinpath("container-build")
temp_build_dir = container_parent_dir.joinpath(container.replace("/", "-"))
temp_build_script_filename = temp_build_dir.joinpath("build.sh")
# Now check if the container exists in the external stack.
if not temp_build_script_filename.exists():
# If not, revert to building an internal container
container_parent_dir = container_build_dir
else:
container_parent_dir = container_build_dir
build_dir = container_parent_dir.joinpath(container.replace("/", "-"))
build_script_filename = build_dir.joinpath("build.sh")
if verbose: if verbose:
print(f"Build script filename: {build_script_filename}") print(f"Build script filename: {build_script_filename}")
if os.path.exists(build_script_filename): if os.path.exists(build_script_filename):
build_command = build_script_filename build_command = build_script_filename.as_posix()
else: else:
if verbose: if verbose:
print(f"No script file found: {build_script_filename}, using default build script") print(f"No script file found: {build_script_filename}, using default build script")
@ -84,7 +102,7 @@ def process_container(container,
repo_full_path = os.path.join(dev_root_path, repo_dir) repo_full_path = os.path.join(dev_root_path, repo_dir)
repo_dir_or_build_dir = repo_full_path if os.path.exists(repo_full_path) else build_dir repo_dir_or_build_dir = repo_full_path if os.path.exists(repo_full_path) else build_dir
build_command = os.path.join(container_build_dir, build_command = os.path.join(container_build_dir,
"default-build.sh") + f" {container}:local {repo_dir_or_build_dir}" "default-build.sh") + f" {default_container_tag} {repo_dir_or_build_dir}"
if not dry_run: if not dry_run:
if verbose: if verbose:
print(f"Executing: {build_command} with environment: {container_build_env}") print(f"Executing: {build_command} with environment: {container_build_env}")
@ -158,7 +176,7 @@ def command(ctx, include, exclude, force_rebuild, extra_build_args):
for container in containers_in_scope: for container in containers_in_scope:
if include_exclude_check(container, include, exclude): if include_exclude_check(container, include, exclude):
process_container(container, container_build_dir, container_build_env, process_container(stack, container, container_build_dir, container_build_env,
dev_root_path, quiet, verbose, dry_run, continue_on_error) dev_root_path, quiet, verbose, dry_run, continue_on_error)
else: else:
if verbose: if verbose:

View File

@ -26,7 +26,7 @@ import importlib.resources
from pathlib import Path from pathlib import Path
import yaml import yaml
from stack_orchestrator.constants import stack_file_name from stack_orchestrator.constants import stack_file_name
from stack_orchestrator.util import include_exclude_check, error_exit from stack_orchestrator.util import include_exclude_check, stack_is_external, error_exit
class GitProgress(git.RemoteProgress): class GitProgress(git.RemoteProgress):
@ -239,9 +239,9 @@ def command(ctx, include, exclude, git_ssh, check_only, pull, branches, branches
repos_in_scope = [] repos_in_scope = []
if stack: if stack:
# Check if the stack argument is a path or a plain string. if stack_is_external(stack):
stack_file_path = Path(stack).joinpath(stack_file_name) stack_file_path = Path(stack).joinpath(stack_file_name)
if not stack_file_path.exists(): else:
# In order to be compatible with Python 3.8 we need to use this hack to get the path: # In order to be compatible with Python 3.8 we need to use this hack to get the path:
# See: https://stackoverflow.com/questions/25389095/python-get-path-of-root-project-structure # See: https://stackoverflow.com/questions/25389095/python-get-path-of-root-project-structure
stack_file_path = Path(__file__).absolute().parent.parent.joinpath("data", "stacks", stack, stack_file_name) stack_file_path = Path(__file__).absolute().parent.parent.joinpath("data", "stacks", stack, stack_file_name)

View File

@ -150,6 +150,12 @@ def get_parsed_deployment_spec(spec_file):
sys.exit(1) sys.exit(1)
def stack_is_external(stack: str):
# Bit of a hack: if the supplied stack string represents
# a path that exists then we assume it must be external
return Path(stack).exists()
def get_yaml(): def get_yaml():
# See: https://stackoverflow.com/a/45701840/1701505 # See: https://stackoverflow.com/a/45701840/1701505
yaml = ruamel.yaml.YAML() yaml = ruamel.yaml.YAML()