diff --git a/app/deploy.py b/app/deploy.py index 59fbf41c..b8173d2a 100644 --- a/app/deploy.py +++ b/app/deploy.py @@ -56,10 +56,10 @@ def command(ctx, include, exclude, env_file, cluster, deploy_to): # Subcommand is executed now, by the magic of click -def create_deploy_context(global_context, stack, include, exclude, cluster, env_file, deploy_to): +def create_deploy_context(global_context, stack, include, exclude, cluster, env_file, deployer): cluster_context = _make_cluster_context(global_context, stack, include, exclude, cluster, env_file) # See: https://gabrieldemarmiesse.github.io/python-on-whales/sub-commands/compose/ - deployer = getDeployer(deploy_to, compose_files=cluster_context.compose_files, compose_project_name=cluster_context.cluster, + deployer = getDeployer(deployer, compose_files=cluster_context.compose_files, compose_project_name=cluster_context.cluster, compose_env_file=cluster_context.env_file) return DeployCommandContext(stack, cluster_context, deployer) diff --git a/app/deployment.py b/app/deployment.py index c9c2bb98..3de8ac7a 100644 --- a/app/deployment.py +++ b/app/deployment.py @@ -14,20 +14,25 @@ # along with this program. If not, see . import click -from dataclasses import dataclass from pathlib import Path import sys from app.deploy import up_operation, down_operation, ps_operation, port_operation from app.deploy import exec_operation, logs_operation, create_deploy_context +from app.stack import Stack +from app.spec import Spec -@dataclass class DeploymentContext: dir: Path + spec: Spec + stack: Stack def get_stack_file(self): return self.dir.joinpath("stack.yml") + def get_spec_file(self): + return self.dir.joinpath("spec.yml") + def get_env_file(self): return self.dir.joinpath("config.env") @@ -35,12 +40,19 @@ class DeploymentContext: def get_cluster_name(self): return None + def init(self, dir): + self.dir = dir + self.stack = Stack() + self.stack.init_from_file(self.get_stack_file()) + self.spec = Spec() + self.spec.init_from_file(self.get_spec_file()) + @click.group() @click.option("--dir", required=True, help="path to deployment directory") @click.pass_context def command(ctx, dir): - '''create a deployment''' + '''manage a deployment''' # Check that --stack wasn't supplied if ctx.parent.obj.stack: @@ -55,14 +67,19 @@ def command(ctx, dir): print(f"Error: supplied deployment directory path {dir} exists but is a file not a directory") sys.exit(1) # Store the deployment context for subcommands - ctx.obj = DeploymentContext(dir_path) + deployment_context = DeploymentContext() + deployment_context.init(dir_path) + print(f"DEBUG dc: {deployment_context.spec.obj}") + ctx.obj = deployment_context def make_deploy_context(ctx): - stack_file_path = ctx.obj.get_stack_file() - env_file = ctx.obj.get_env_file() - cluster_name = ctx.obj.get_cluster_name() - return create_deploy_context(ctx.parent.parent.obj, stack_file_path, None, None, cluster_name, env_file, deploy_to) + context: DeploymentContext = ctx.obj + stack_file_path = context.get_stack_file() + env_file = context.get_env_file() + cluster_name = context.get_cluster_name() + return create_deploy_context(ctx.parent.parent.obj, stack_file_path, None, None, cluster_name, env_file, + context.spec.obj["deploy-to"]) @command.command() diff --git a/app/deployment_create.py b/app/deployment_create.py index 7f416300..85835343 100644 --- a/app/deployment_create.py +++ b/app/deployment_create.py @@ -249,7 +249,7 @@ def init(ctx, config, output, map_ports_to_host): stack = global_options(ctx).stack debug = global_options(ctx).debug default_spec_file_content = call_stack_deploy_init(ctx.obj) - spec_file_content = {"stack": stack} + spec_file_content = {"stack": stack, "deploy-to": "compose"} if default_spec_file_content: spec_file_content.update(default_spec_file_content) config_variables = _parse_config_variables(config) @@ -315,7 +315,7 @@ def create(ctx, spec_file, deployment_dir, network_dir, initial_peers): sys.exit(1) os.mkdir(deployment_dir) # Copy spec file and the stack file into the deployment dir - copyfile(spec_file, os.path.join(deployment_dir, os.path.basename(spec_file))) + copyfile(spec_file, os.path.join(deployment_dir, "spec.yml")) copyfile(stack_file, os.path.join(deployment_dir, os.path.basename(stack_file))) # Copy any config varibles from the spec file into an env file suitable for compose _write_config_file(spec_file, os.path.join(deployment_dir, "config.env")) diff --git a/app/spec.py b/app/spec.py new file mode 100644 index 00000000..a23bc167 --- /dev/null +++ b/app/spec.py @@ -0,0 +1,30 @@ +# Copyright © 2022, 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 . + +from pathlib import Path +import typing +from app.util import get_yaml + + +class Spec: + + obj: typing.Any + + def __init__(self) -> None: + pass + + def init_from_file(self, file_path: Path): + with file_path: + self.obj = get_yaml().load(open(file_path, "r")) diff --git a/app/stack.py b/app/stack.py new file mode 100644 index 00000000..1f94acdf --- /dev/null +++ b/app/stack.py @@ -0,0 +1,30 @@ +# 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 . + +from pathlib import Path +import typing +from app.util import get_yaml + + +class Stack: + + obj: typing.Any + + def __init__(self) -> None: + pass + + def init_from_file(self, file_path: Path): + with file_path: + self.obj = get_yaml().load(open(file_path, "r"))