diff --git a/sky/backends/cloud_vm_ray_backend.py b/sky/backends/cloud_vm_ray_backend.py index aceac8951b0..f0fb4d97ba1 100644 --- a/sky/backends/cloud_vm_ray_backend.py +++ b/sky/backends/cloud_vm_ray_backend.py @@ -2844,9 +2844,9 @@ def _provision( time.sleep(gap_seconds) continue logger.error( - f'{colorama.Fore.RED}⨯{colorama.Style.RESET_ALL} ' - 'Failed to provision resources. ' - f'{ux_utils.log_path_hint(log_path)}') + ux_utils.error_message( + 'Failed to provision resources. ' + f'{ux_utils.log_path_hint(log_path)}')) error_message += ( '\nTo keep retrying until the cluster is up, use ' 'the `--retry-until-up` flag.') diff --git a/sky/provision/provisioner.py b/sky/provision/provisioner.py index b2ac6d6660f..7706a3d489b 100644 --- a/sky/provision/provisioner.py +++ b/sky/provision/provisioner.py @@ -571,7 +571,10 @@ def post_provision_runtime_setup( provision_record=provision_record, custom_resource=custom_resource) except Exception: # pylint: disable=broad-except - logger.error('*** Failed setting up cluster. ***') + logger.error( + ux_utils.error_message( + 'Failed to set up SkyPilot runtime on cluster.', + provision_logging.config.log_path)) logger.debug(f'Stacktrace:\n{traceback.format_exc()}') with ux_utils.print_exception_no_traceback(): raise diff --git a/sky/utils/ux_utils.py b/sky/utils/ux_utils.py index f6699f355f8..2fffa8a9df9 100644 --- a/sky/utils/ux_utils.py +++ b/sky/utils/ux_utils.py @@ -121,11 +121,6 @@ def run(self, *args, **kwargs): raise -def starting_message(message: str) -> str: - """Gets the starting message for the given message.""" - return f'⚙︎ {message}' - - def log_path_hint(log_path: Union[str, 'pathlib.Path']) -> str: """Gets the log path hint for the given log path.""" log_path = str(log_path) @@ -135,21 +130,50 @@ def log_path_hint(log_path: Union[str, 'pathlib.Path']) -> str: return _LOG_PATH_HINT.format(log_path=log_path) +def starting_message(message: str) -> str: + """Gets the starting message for the given message.""" + # We have to reset the color before the message, because sometimes if a + # previous spinner with dimmed color overflows in a narrow terminal, the + # color might be messed up. + return f'{colorama.Style.RESET_ALL}⚙︎ {message}' + + def finishing_message( message: str, log_path: Optional[Union[str, 'pathlib.Path']] = None) -> str: """Gets the finishing message for the given message.""" - success_prefix = (f'{colorama.Fore.GREEN}✓ {message}' - f'{colorama.Style.RESET_ALL}') + # We have to reset the color before the message, because sometimes if a + # previous spinner with dimmed color overflows in a narrow terminal, the + # color might be messed up. + success_prefix = (f'{colorama.Style.RESET_ALL}{colorama.Fore.GREEN}✓ ' + f'{message}{colorama.Style.RESET_ALL}') if log_path is None: return success_prefix path_hint = log_path_hint(log_path) return f'{success_prefix} {path_hint}' +def error_message(message: str, + log_path: Optional[Union[str, 'pathlib.Path']] = None) -> str: + """Gets the error message for the given message.""" + # We have to reset the color before the message, because sometimes if a + # previous spinner with dimmed color overflows in a narrow terminal, the + # color might be messed up. + error_prefix = (f'{colorama.Style.RESET_ALL}{colorama.Fore.RED}⨯' + f'{colorama.Style.RESET_ALL} {message}') + if log_path is None: + return error_prefix + path_hint = log_path_hint(log_path) + return f'{error_prefix} {path_hint}' + + def retry_message(message: str) -> str: """Gets the retry message for the given message.""" - return f'{colorama.Fore.YELLOW}↺{colorama.Style.RESET_ALL} {message}' + # We have to reset the color before the message, because sometimes if a + # previous spinner with dimmed color overflows in a narrow terminal, the + # color might be messed up. + return (f'{colorama.Style.RESET_ALL}{colorama.Fore.YELLOW}↺' + f'{colorama.Style.RESET_ALL} {message}') def spinner_message(