From 75bed6f10b7b8719c58080e59a4ce25c7a29465b Mon Sep 17 00:00:00 2001 From: Roy Crihfield Date: Wed, 3 Jul 2024 15:12:27 +0800 Subject: [PATCH] fix external stack path resolution for deployments --- stack_orchestrator/deploy/deploy.py | 25 +++++++++++------- stack_orchestrator/deploy/deployment.py | 6 ++--- .../deploy/deployment_create.py | 6 ++--- stack_orchestrator/util.py | 26 +++++++++++-------- 4 files changed, 36 insertions(+), 27 deletions(-) diff --git a/stack_orchestrator/deploy/deploy.py b/stack_orchestrator/deploy/deploy.py index db1611f9..ddbec3d3 100644 --- a/stack_orchestrator/deploy/deploy.py +++ b/stack_orchestrator/deploy/deploy.py @@ -26,8 +26,15 @@ import click from pathlib import Path from stack_orchestrator import constants from stack_orchestrator.opts import opts -from stack_orchestrator.util import include_exclude_check, get_parsed_stack_config, global_options2, get_dev_root_path -from stack_orchestrator.util import resolve_compose_file +from stack_orchestrator.util import ( + get_stack_path, + include_exclude_check, + get_parsed_stack_config, + global_options2, + get_dev_root_path, + stack_is_in_deployment, + resolve_compose_file, +) from stack_orchestrator.deploy.deployer import Deployer, DeployerException from stack_orchestrator.deploy.deployer_factory import getDeployer from stack_orchestrator.deploy.deploy_types import ClusterContext, DeployCommandContext @@ -60,6 +67,7 @@ def command(ctx, include, exclude, env_file, cluster, deploy_to): if deploy_to is None: deploy_to = "compose" + stack = get_stack_path(stack) ctx.obj = create_deploy_context(global_options2(ctx), None, stack, include, exclude, cluster, env_file, deploy_to) # Subcommand is executed now, by the magic of click @@ -77,6 +85,7 @@ def create_deploy_context( if deployment_context and cluster is None: cluster = deployment_context.get_cluster_id() cluster_context = _make_cluster_context(global_context, stack, include, exclude, cluster, env_file) + # breakpoint() deployer = getDeployer(deploy_to, deployment_context, compose_files=cluster_context.compose_files, compose_project_name=cluster_context.cluster, compose_env_file=cluster_context.env_file) @@ -274,16 +283,12 @@ def _make_default_cluster_name(deployment, compose_dir, stack, include, exclude) # stack has to be either PathLike pointing to a stack yml file, or a string with the name of a known stack def _make_cluster_context(ctx, stack, include, exclude, cluster, env_file): - dev_root_path = get_dev_root_path(ctx) - # TODO: huge hack, fix this - # If the caller passed a path for the stack file, then we know that we can get the compose files - # from the same directory - deployment = False - if isinstance(stack, os.PathLike): - compose_dir = stack.parent.joinpath("compose") - deployment = True + # TODO: hack, this should be encapsulated by the deployment context. + deployment = stack_is_in_deployment(stack) + if deployment: + compose_dir = stack.joinpath("compose") else: # See: https://stackoverflow.com/questions/25389095/python-get-path-of-root-project-structure compose_dir = Path(__file__).absolute().parent.parent.joinpath("data", "compose") diff --git a/stack_orchestrator/deploy/deployment.py b/stack_orchestrator/deploy/deployment.py index db6ad6cc..a7fd8bb2 100644 --- a/stack_orchestrator/deploy/deployment.py +++ b/stack_orchestrator/deploy/deployment.py @@ -50,15 +50,15 @@ def command(ctx, dir): def make_deploy_context(ctx) -> DeployCommandContext: context: DeploymentContext = ctx.obj - stack_file_path = context.get_stack_file() env_file = context.get_env_file() cluster_name = context.get_cluster_id() if constants.deploy_to_key in context.spec.obj: deployment_type = context.spec.obj[constants.deploy_to_key] else: deployment_type = constants.compose_deploy_type - return create_deploy_context(ctx.parent.parent.obj, context, stack_file_path, None, None, cluster_name, env_file, - deployment_type) + stack = context.deployment_dir + return create_deploy_context(ctx.parent.parent.obj, context, stack, None, None, + cluster_name, env_file, deployment_type) @command.command() diff --git a/stack_orchestrator/deploy/deployment_create.py b/stack_orchestrator/deploy/deployment_create.py index ac40b768..5f565854 100644 --- a/stack_orchestrator/deploy/deployment_create.py +++ b/stack_orchestrator/deploy/deployment_create.py @@ -24,7 +24,7 @@ from secrets import token_hex import sys from stack_orchestrator import constants from stack_orchestrator.opts import opts -from stack_orchestrator.util import (get_internal_stack_file_path, get_parsed_deployment_spec, get_parsed_stack_config, +from stack_orchestrator.util import (get_stack_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, env_var_map_from_file, resolve_config_dir) @@ -459,7 +459,7 @@ def create_operation(deployment_command_context, spec_file, deployment_dir, netw _check_volume_definitions(parsed_spec) stack_name = parsed_spec["stack"] deployment_type = parsed_spec[constants.deploy_to_key] - stack_file = get_internal_stack_file_path(stack_name) + stack_file = get_stack_path(stack_name).joinpath(constants.stack_file_name) parsed_stack = get_parsed_stack_config(stack_name) if opts.o.debug: print(f"parsed spec: {parsed_spec}") @@ -472,7 +472,7 @@ def create_operation(deployment_command_context, spec_file, deployment_dir, netw os.mkdir(deployment_dir_path) # Copy spec file and the stack file into the deployment dir copyfile(spec_file, deployment_dir_path.joinpath(constants.spec_file_name)) - copyfile(stack_file, deployment_dir_path.joinpath(os.path.basename(stack_file))) + copyfile(stack_file, deployment_dir_path.joinpath(constants.stack_file_name)) _create_deployment_file(deployment_dir_path) # Copy any config varibles from the spec file into an env file suitable for compose _write_config_file(spec_file, deployment_dir_path.joinpath(constants.config_file_name)) diff --git a/stack_orchestrator/util.py b/stack_orchestrator/util.py index 3d4054ac..d2dd0425 100644 --- a/stack_orchestrator/util.py +++ b/stack_orchestrator/util.py @@ -20,7 +20,7 @@ import ruamel.yaml from pathlib import Path from dotenv import dotenv_values from typing import Mapping, Set, List -from stack_orchestrator.constants import stack_file_name +from stack_orchestrator.constants import stack_file_name, deployment_file_name def include_exclude_check(s, include, exclude): @@ -34,11 +34,14 @@ def include_exclude_check(s, include, exclude): return s not in exclude_list -def get_internal_stack_file_path(stack): - # 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 - stack_file_path = Path(__file__).absolute().parent.joinpath("data", "stacks", stack, stack_file_name) - return stack_file_path +def get_stack_path(stack): + if stack_is_external(stack): + stack_path = Path(stack) + else: + # 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 + stack_path = Path(__file__).absolute().parent.joinpath("data", "stacks", stack) + return stack_path def get_dev_root_path(ctx): @@ -53,10 +56,7 @@ def get_dev_root_path(ctx): # Caller can pass either the name of a stack, or a path to a stack file def get_parsed_stack_config(stack): - if stack_is_external(stack): - stack_file_path = Path(stack).joinpath(stack_file_name) - else: - stack_file_path = get_internal_stack_file_path(stack) + stack_file_path = get_stack_path(stack).joinpath(stack_file_name) if stack_file_path.exists(): return get_yaml().load(open(stack_file_path, "r")) # We try here to generate a useful diagnostic error @@ -84,7 +84,7 @@ def get_plugin_code_paths(stack) -> List[Path]: result: Set[Path] = set() for pod in pods: if type(pod) is str: - result.add(get_internal_stack_file_path(stack).parent) + result.add(get_stack_path(stack)) else: pod_root_dir = os.path.join(get_dev_root_path(None), pod["repository"].split("/")[-1], pod["path"]) result.add(Path(os.path.join(pod_root_dir, "stack"))) @@ -196,6 +196,10 @@ def stack_is_external(stack: str): return Path(stack).exists() if stack is not None else False +def stack_is_in_deployment(stack: Path): + return stack.joinpath(deployment_file_name).exists() + + def get_yaml(): # See: https://stackoverflow.com/a/45701840/1701505 yaml = ruamel.yaml.YAML()