diff --git a/app/deploy/compose/deploy_docker.py b/app/deploy/compose/deploy_docker.py index 6a70f318..e8ee4b9f 100644 --- a/app/deploy/compose/deploy_docker.py +++ b/app/deploy/compose/deploy_docker.py @@ -13,8 +13,9 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . +from pathlib import Path from python_on_whales import DockerClient, DockerException -from app.deploy.deployer import Deployer, DeployerException +from app.deploy.deployer import Deployer, DeployerException, DeployerConfigGenerator class DockerDeployer(Deployer): @@ -65,3 +66,14 @@ class DockerDeployer(Deployer): return self.docker.run(image=image, command=command, user=user, volumes=volumes, entrypoint=entrypoint) except DockerException as e: raise DeployerException(e) + + +class DockerDeployerConfigGenerator(DeployerConfigGenerator): + config_file_name: str = "kind-config.yml" + + def __init__(self) -> None: + super().__init__() + + # Nothing needed at present for the docker deployer + def generate(self, deployment_dir: Path): + pass diff --git a/app/deploy/deployer.py b/app/deploy/deployer.py index 51b6010d..68b0088a 100644 --- a/app/deploy/deployer.py +++ b/app/deploy/deployer.py @@ -14,6 +14,7 @@ # along with this program. If not, see . from abc import ABC, abstractmethod +from pathlib import Path class Deployer(ABC): @@ -50,3 +51,10 @@ class Deployer(ABC): class DeployerException(Exception): def __init__(self, *args: object) -> None: super().__init__(*args) + + +class DeployerConfigGenerator(ABC): + + @abstractmethod + def generate(self, deployment_dir: Path): + pass diff --git a/app/deploy/deployer_factory.py b/app/deploy/deployer_factory.py index de89b72c..0c0ef69d 100644 --- a/app/deploy/deployer_factory.py +++ b/app/deploy/deployer_factory.py @@ -13,11 +13,20 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -from app.deploy.k8s.deploy_k8s import K8sDeployer -from app.deploy.compose.deploy_docker import DockerDeployer +from app.deploy.k8s.deploy_k8s import K8sDeployer, K8sDeployerConfigGenerator +from app.deploy.compose.deploy_docker import DockerDeployer, DockerDeployerConfigGenerator -def getDeployer(type, compose_files, compose_project_name, compose_env_file): +def getDeployerConfigGenerator(type: str): + if type == "compose" or type is None: + return DockerDeployerConfigGenerator() + elif type == "k8s": + return K8sDeployerConfigGenerator() + else: + print(f"ERROR: deploy-to {type} is not valid") + + +def getDeployer(type: str, compose_files, compose_project_name, compose_env_file): if type == "compose" or type is None: return DockerDeployer(compose_files, compose_project_name, compose_env_file) elif type == "k8s": diff --git a/app/deploy/deployment_create.py b/app/deploy/deployment_create.py index 04fdde4a..67893890 100644 --- a/app/deploy/deployment_create.py +++ b/app/deploy/deployment_create.py @@ -24,6 +24,7 @@ import sys from app.util import (get_stack_file_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) from app.deploy.deploy_types import DeploymentContext, DeployCommandContext, LaconicStackSetupCommand +from app.deploy.deployer_factory import getDeployerConfigGenerator def _make_default_deployment_dir(): @@ -366,6 +367,9 @@ def create(ctx, spec_file, deployment_dir, network_dir, initial_peers): deployment_command_context = ctx.obj deployment_command_context.stack = stack_name deployment_context = DeploymentContext(Path(deployment_dir), deployment_command_context) + # Call the deployer to generate any deployer-specific files (e.g. for kind) + deployer_config_generator = getDeployerConfigGenerator(parsed_spec["deploy-to"]) + deployer_config_generator.generate(deployment_dir) call_stack_deploy_create(deployment_context, [network_dir, initial_peers]) diff --git a/app/deploy/k8s/deploy_k8s.py b/app/deploy/k8s/deploy_k8s.py index 25e0f485..06f893df 100644 --- a/app/deploy/k8s/deploy_k8s.py +++ b/app/deploy/k8s/deploy_k8s.py @@ -13,11 +13,12 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . +from pathlib import Path from kubernetes import client, config -from app.deploy.deployer import Deployer +from app.deploy.deployer import Deployer, DeployerConfigGenerator from app.deploy.k8s.helpers import create_cluster, destroy_cluster, load_images_into_kind -from app.deploy.k8s.helpers import pods_in_deployment, log_stream_from_string +from app.deploy.k8s.helpers import pods_in_deployment, log_stream_from_string, generate_kind_config from app.deploy.k8s.cluster_info import ClusterInfo from app.opts import opts @@ -108,3 +109,18 @@ class K8sDeployer(Deployer): def run(self, image, command, user, volumes, entrypoint=None): # We need to figure out how to do this -- check why we're being called first pass + + +class K8sDeployerConfigGenerator(DeployerConfigGenerator): + config_file_name: str = "kind-config.yml" + + def __init__(self) -> None: + super().__init__() + + def generate(self, deployment_dir: Path): + # Check the file isn't already there + # Get the config file contents + content = generate_kind_config() + # Write the file + with open(deployment_dir, "w") as output_file: + output_file.write(content) diff --git a/app/deploy/k8s/helpers.py b/app/deploy/k8s/helpers.py index 3ff5e2b7..d6bca156 100644 --- a/app/deploy/k8s/helpers.py +++ b/app/deploy/k8s/helpers.py @@ -102,3 +102,13 @@ def volumes_for_pod_files(parsed_pod_files): volume = client.V1Volume(name=volume_name, persistent_volume_claim=claim) result.append(volume) return result + + +def generate_kind_config(): + return ( + '''kind: Cluster +apiVersion: kind.x-k8s.io/v1alpha4 +nodes: +- role: control-plane +''' + )