From 6f8b98894b2ea417de834af598ff566de16e7137 Mon Sep 17 00:00:00 2001 From: abmantis Date: Thu, 12 Jun 2025 20:18:43 +0100 Subject: [PATCH] Stop writing to config dir log file on supervised install --- homeassistant/bootstrap.py | 45 +++++++++++++++++++++----------------- tests/test_bootstrap.py | 41 +++++++++++++++++++++++++++------- 2 files changed, 58 insertions(+), 28 deletions(-) diff --git a/homeassistant/bootstrap.py b/homeassistant/bootstrap.py index 55aeaef2554..066c2bd16c5 100644 --- a/homeassistant/bootstrap.py +++ b/homeassistant/bootstrap.py @@ -613,34 +613,39 @@ async def async_enable_logging( ), ) + logger = logging.getLogger() + logger.setLevel(logging.INFO if verbose else logging.WARNING) + # Log errors to a file if we have write access to file or config dir if log_file is None: - err_log_path = hass.config.path(ERROR_LOG_FILENAME) + if "SUPERVISOR" in os.environ: + _LOGGER.info("Running in Supervisor, not logging to file") + err_log_path = None + else: + err_log_path = hass.config.path(ERROR_LOG_FILENAME) else: err_log_path = os.path.abspath(log_file) - err_path_exists = os.path.isfile(err_log_path) - err_dir = os.path.dirname(err_log_path) + if err_log_path: + err_path_exists = os.path.isfile(err_log_path) + err_dir = os.path.dirname(err_log_path) - # Check if we can write to the error log if it exists or that - # we can create files in the containing directory if not. - if (err_path_exists and os.access(err_log_path, os.W_OK)) or ( - not err_path_exists and os.access(err_dir, os.W_OK) - ): - err_handler = await hass.async_add_executor_job( - _create_log_file, err_log_path, log_rotate_days - ) + # Check if we can write to the error log if it exists or that + # we can create files in the containing directory if not. + if (err_path_exists and os.access(err_log_path, os.W_OK)) or ( + not err_path_exists and os.access(err_dir, os.W_OK) + ): + err_handler = await hass.async_add_executor_job( + _create_log_file, err_log_path, log_rotate_days + ) - err_handler.setFormatter(logging.Formatter(fmt, datefmt=FORMAT_DATETIME)) + err_handler.setFormatter(logging.Formatter(fmt, datefmt=FORMAT_DATETIME)) + logger.addHandler(err_handler) - logger = logging.getLogger() - logger.addHandler(err_handler) - logger.setLevel(logging.INFO if verbose else logging.WARNING) - - # Save the log file location for access by other components. - hass.data[DATA_LOGGING] = err_log_path - else: - _LOGGER.error("Unable to set up error log %s (access denied)", err_log_path) + # Save the log file location for access by other components. + hass.data[DATA_LOGGING] = err_log_path + else: + _LOGGER.error("Unable to set up error log %s (access denied)", err_log_path) async_activate_log_queue_handler(hass) diff --git a/tests/test_bootstrap.py b/tests/test_bootstrap.py index 9e1f246b551..4c22129b023 100644 --- a/tests/test_bootstrap.py +++ b/tests/test_bootstrap.py @@ -88,11 +88,15 @@ async def test_async_enable_logging( config_log_file_pattern = get_test_config_dir("home-assistant.log*") arg_log_file_pattern = "test.log*" + def cleanup_log_files() -> None: + """Remove all log files.""" + for f in glob.glob(config_log_file_pattern): + os.remove(f) + for f in glob.glob(arg_log_file_pattern): + os.remove(f) + # Ensure we start with a clean slate - for f in glob.glob(arg_log_file_pattern): - os.remove(f) - for f in glob.glob(config_log_file_pattern): - os.remove(f) + cleanup_log_files() assert len(glob.glob(config_log_file_pattern)) == 0 assert len(glob.glob(arg_log_file_pattern)) == 0 @@ -121,10 +125,31 @@ async def test_async_enable_logging( assert "Error rolling over log file" in caplog.text - for f in glob.glob(arg_log_file_pattern): - os.remove(f) - for f in glob.glob(config_log_file_pattern): - os.remove(f) + cleanup_log_files() + + with ( + patch.dict(os.environ, {"SUPERVISOR": "1"}), + patch("logging.getLogger"), + patch( + "homeassistant.bootstrap.async_activate_log_queue_handler" + ) as mock_async_activate_log_queue_handler, + ): + await bootstrap.async_enable_logging(hass) + mock_async_activate_log_queue_handler.assert_called_once() + # On Supervisor, the default log file should not be created + assert len(glob.glob(config_log_file_pattern)) == 0 + + mock_async_activate_log_queue_handler.reset_mock() + await bootstrap.async_enable_logging( + hass, + log_rotate_days=5, + log_file="test.log", + ) + mock_async_activate_log_queue_handler.assert_called_once() + # Even on Supervisor, the log file should be created if explicitly set + assert len(glob.glob(arg_log_file_pattern)) > 0 + + cleanup_log_files() async def test_load_hassio(hass: HomeAssistant) -> None: