diff --git a/bentoctl/cli/__init__.py b/bentoctl/cli/__init__.py index badc9ca..d32bb88 100644 --- a/bentoctl/cli/__init__.py +++ b/bentoctl/cli/__init__.py @@ -7,7 +7,7 @@ from bentoctl import __version__ from bentoctl.cli.interactive import deployment_config_builder from bentoctl.cli.operator_management import get_operator_management_subcommands -from bentoctl.cli.utils import BentoctlCommandGroup +from bentoctl.cli.utils import BentoctlCommandGroup, handle_bentoctl_exceptions from bentoctl.console import print_generated_files_list, prompt_user_for_filename from bentoctl.deployment_config import DeploymentConfig from bentoctl.docker_utils import build_docker_image, push_docker_image_to_repository @@ -46,37 +46,34 @@ def bentoctl(): type=click.Path(exists=True, file_okay=False), default=os.curdir, ) +@handle_bentoctl_exceptions def init(save_path, generate): """ Start the interactive deployment config builder file. Initialize a deployment configuration file using interactive mode. """ - try: - deployment_config = deployment_config_builder() - deployment_config_filname = prompt_user_for_filename() - - config_path = os.path.join(save_path, deployment_config_filname) - if os.path.exists(config_path): - if click.confirm( - "deployment config file exists! Should I override?", default=True - ): - os.remove(config_path) - else: - return - - deployment_config.save(save_path=save_path, filename=deployment_config_filname) - console.print( - "[green]deployment config generated to: " - f"{os.path.relpath(config_path, save_path)}[/]" - ) + deployment_config = deployment_config_builder() + deployment_config_filname = prompt_user_for_filename() + + config_path = os.path.join(save_path, deployment_config_filname) + if os.path.exists(config_path): + if click.confirm( + "deployment config file exists! Should I override?", default=True + ): + os.remove(config_path) + else: + return + + deployment_config.save(save_path=save_path, filename=deployment_config_filname) + console.print( + "[green]deployment config generated to: " + f"{os.path.relpath(config_path, save_path)}[/]" + ) - if generate: - generated_files = DeploymentConfig(deployment_config).generate() - print_generated_files_list(generated_files) - except BentoctlException as e: - console.print(f"[red]{e}[/]") - sys.exit(1) + if generate: + generated_files = deployment_config.generate() + print_generated_files_list(generated_files) @bentoctl.command() @@ -98,6 +95,7 @@ def init(save_path, generate): help="create/update the values file only.", default=False, ) +@handle_bentoctl_exceptions def generate(deployment_config_file, values_only, save_path): """ Generate template files for deployment. @@ -121,6 +119,7 @@ def generate(deployment_config_file, values_only, save_path): required=True, ) @click.option("--push/--no-push", default=False) +@handle_bentoctl_exceptions def build( bento_tag, operator, @@ -163,7 +162,9 @@ def build( if push: push_docker_image_to_repository( - repository=image_tag, username=registry_username, password=registry_password + repository=image_tag, + username=registry_username, + password=registry_password, ) generated_files = deployment_config.generate(values_only=True) print_generated_files_list(generated_files) diff --git a/bentoctl/cli/utils.py b/bentoctl/cli/utils.py index 70bc968..99e2d55 100644 --- a/bentoctl/cli/utils.py +++ b/bentoctl/cli/utils.py @@ -1,12 +1,27 @@ import functools import logging import os +import sys import click +from bentoctl.exceptions import BentoctlException + DEBUG_ENV_VAR = "BENTOCTL_DEBUG" +def handle_bentoctl_exceptions(func): + @functools.wraps(func) + def wrapper(*args, **kwargs): + try: + return func(*args, **kwargs) + except BentoctlException as error: + error.show() + sys.exit(0) + + return wrapper + + def set_debug_mode(is_enabled: bool): if is_enabled or os.environ.get(DEBUG_ENV_VAR): os.environ[DEBUG_ENV_VAR] = str(True) diff --git a/bentoctl/deployment_config.py b/bentoctl/deployment_config.py index 7d10e62..70d9671 100644 --- a/bentoctl/deployment_config.py +++ b/bentoctl/deployment_config.py @@ -12,6 +12,7 @@ from bentoml.bentos import Bento from bentoctl.exceptions import ( + BentoNotFound, DeploymentConfigNotFound, InvalidDeploymentConfig, OperatorNotFound, @@ -171,9 +172,7 @@ def set_bento(self, bento_tag: str): try: self.bento = bentoml.get(bento_tag) except bentoml.exceptions.NotFound: - print("bento not found") - except bentoml.exceptions.BentoMLException: - print("an exception in bentoml") + raise BentoNotFound(bento_tag) def generate(self, destination_dir=os.curdir, values_only=False): """ diff --git a/bentoctl/exceptions.py b/bentoctl/exceptions.py index a196bfe..0f05dd3 100644 --- a/bentoctl/exceptions.py +++ b/bentoctl/exceptions.py @@ -121,6 +121,10 @@ class BentoNotFound(BentoctlException): Raised when bento is not found. """ + def __init__(self, bento_tag: str): + self.msg = f"Bento with tag <{bento_tag}> not found in Bento Store." + super(BentoNotFound, self).__init__(self.msg) + class BentoctlBuildException(BentoctlException): """ @@ -132,3 +136,26 @@ class BentoctlPushException(BentoctlException): """ Raised when docker push failed """ + + +class TemplateExists(BentoctlException): + """ + Raised when a Template file exists. + """ + + def __init__(self, template_file_path): + self.msg = f"Generating Template files failed since <{template_file_path}> already exists. Please call with --values-only to create only the values file or remove the main template file in order to create a new one." + super(TemplateExists, self).__init__(self.msg) + + +class TemplateTypeNotDefined(BentoctlException): + """ + When the Template type provied in the deployment config is not supported by the + operator. + """ + + def __init__(self, template_type: str): + self.msg = ( + f"Template type <{template_type} not supported by the operator provided." + ) + super(TemplateTypeNotDefined, self).__init__(self.msg)