Resolves: RHEL-180613 Resolves: RHEL-189524 Resolves: RHEL-170880 Resolves: RHEL-168794 Resolves: RHEL-155023 Resolves: RHEL-193538 Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
96 lines
4.6 KiB
Diff
96 lines
4.6 KiB
Diff
From 87d8867b1e668007592aefb53f6022a5df80554f Mon Sep 17 00:00:00 2001
|
|
From: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
|
|
Date: Thu, 9 Jul 2026 09:54:07 +0200
|
|
Subject: [PATCH] fix: handle invalid config values for typed server options
|
|
|
|
When a typed configuration option (int, float, bool) contains an empty
|
|
or invalid value, configparser raises ValueError instead of using the
|
|
fallback. This causes the verifier to crash on startup when e.g.
|
|
max_workers has an empty value after a config upgrade.
|
|
|
|
Catch ValueError in _set_option for typed config reads and fall back to
|
|
the caller-provided default with a warning. Also add a default fallback
|
|
of 0 for max_workers (meaning use all CPUs).
|
|
|
|
Fixes: keylime/keylime#1929
|
|
|
|
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
|
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
|
|
---
|
|
keylime/web/base/server.py | 42 +++++++++++++++++++++++++++++---------
|
|
1 file changed, 32 insertions(+), 10 deletions(-)
|
|
|
|
diff --git a/keylime/web/base/server.py b/keylime/web/base/server.py
|
|
index fe9ccbf6d..1bced714f 100644
|
|
--- a/keylime/web/base/server.py
|
|
+++ b/keylime/web/base/server.py
|
|
@@ -449,9 +449,34 @@ def _use_config(self, component: str) -> None:
|
|
"""Sets config component (i.e., namespace) used to locate config values when setting server options."""
|
|
self.__config_component = component
|
|
|
|
+ _TYPED_CONFIG_GETTERS: dict[type, Callable[..., Any]] = {
|
|
+ int: config.getint,
|
|
+ float: config.getfloat,
|
|
+ bool: config.getboolean,
|
|
+ }
|
|
+
|
|
+ def _get_typed_config_value(self, config_name: str, data_type: type, fallback: Any) -> Any:
|
|
+ """Read a typed config value, falling back gracefully on ValueError."""
|
|
+ getter = self._TYPED_CONFIG_GETTERS[data_type]
|
|
+ try:
|
|
+ return getter(self.config_component, config_name, fallback=fallback) # type: ignore
|
|
+ except ValueError:
|
|
+ if fallback is None:
|
|
+ raise
|
|
+ raw_value = config.get(self.config_component, config_name, fallback="<unknown>") # type: ignore[arg-type]
|
|
+ logger.warning(
|
|
+ "Cannot parse '%s' as %s for option '%s' (component: %s), using fallback: %s",
|
|
+ raw_value,
|
|
+ data_type.__name__,
|
|
+ config_name,
|
|
+ self.config_component,
|
|
+ fallback,
|
|
+ )
|
|
+ return fallback
|
|
+
|
|
def _set_option(self, name: str, **kwargs: Any) -> None:
|
|
"""Sets server option by name either from given value or by obtaining it from user config. If the value is
|
|
- falsy, uses the given fallback value instead or ``None`` if no fallback is provided. Examples::
|
|
+ ``None``, uses the given fallback value instead. Examples::
|
|
|
|
# Set option using provided value
|
|
self._set_option("bind_interface", value="0.0.0.0")
|
|
@@ -487,19 +512,13 @@ def _set_option(self, name: str, **kwargs: Any) -> None:
|
|
case {"from_config": (config_name, data_type)} if data_type is str:
|
|
value = config.get(self.config_component, config_name, fallback=fallback) # type: ignore
|
|
|
|
- case {"from_config": (config_name, data_type)} if data_type is int:
|
|
- value = config.getint(self.config_component, config_name, fallback=fallback) # type: ignore
|
|
-
|
|
- case {"from_config": (config_name, data_type)} if data_type is float:
|
|
- value = config.getfloat(self.config_component, config_name, fallback=fallback) # type: ignore
|
|
-
|
|
- case {"from_config": (config_name, data_type)} if data_type is bool:
|
|
- value = config.getboolean(self.config_component, config_name, fallback=fallback) # type: ignore
|
|
+ case {"from_config": (config_name, data_type)} if data_type in self._TYPED_CONFIG_GETTERS:
|
|
+ value = self._get_typed_config_value(config_name, data_type, fallback)
|
|
|
|
case _:
|
|
raise TypeError(f"invalid arguments given when setting option '{name}' for {self.__class__.__name__}")
|
|
|
|
- setattr(self, attr_name, value or fallback)
|
|
+ setattr(self, attr_name, value if value is not None else fallback)
|
|
|
|
def _set_operating_mode(self, **kwargs: Any) -> None:
|
|
"""Sets operating mode of the server (push or pull)."""
|
|
@@ -574,6 +593,9 @@ def _set_max_workers(self, **kwargs: Any) -> None:
|
|
if "from_config" in kwargs:
|
|
kwargs.update({"from_config": (kwargs["from_config"], int)})
|
|
|
|
+ if "fallback" not in kwargs:
|
|
+ kwargs.update({"fallback": 0})
|
|
+
|
|
self._set_option("max_workers", **kwargs)
|
|
|
|
def _set_ssl_ctx(self, **kwargs: Any) -> None:
|