diff --git a/Docs/Tasks.md b/Docs/Tasks.md index e5a21cd..aec4361 100644 --- a/Docs/Tasks.md +++ b/Docs/Tasks.md @@ -37,6 +37,8 @@ If the runtime DB creation fails (e.g., path does not exist, permission denied) ### Task 2 — Fix log_service.preview_log: stale run_blocking call site +**Status:** Completed + **Severity:** Bug **Where:** diff --git a/backend/app/services/action_config_service.py b/backend/app/services/action_config_service.py index f9c9bb0..ef9b9c4 100644 --- a/backend/app/services/action_config_service.py +++ b/backend/app/services/action_config_service.py @@ -981,9 +981,7 @@ async def assign_action_to_jail( else: action_entry = req.action_name - await run_blocking( - None, - _append_jail_action_sync, + await run_blocking(_append_jail_action_sync, Path(config_dir), jail_name, action_entry, @@ -1043,9 +1041,7 @@ async def remove_action_from_jail( if jail_name not in all_jails: raise JailNotFoundInConfigError(jail_name) - await run_blocking( - None, - _remove_jail_action_sync, + await run_blocking(_remove_jail_action_sync, Path(config_dir), jail_name, action_name, diff --git a/backend/app/services/config_file_service.py b/backend/app/services/config_file_service.py index 3e42e2b..eacf4a2 100644 --- a/backend/app/services/config_file_service.py +++ b/backend/app/services/config_file_service.py @@ -1099,8 +1099,7 @@ async def list_inactive_jails( inactive jails. """ loop = asyncio.get_event_loop() - parsed_result: tuple[dict[str, dict[str, str]], dict[str, str]] = await run_blocking( - None, _parse_jails_sync, Path(config_dir) + parsed_result: tuple[dict[str, dict[str, str]], dict[str, str]] = await run_blocking(_parse_jails_sync, Path(config_dir) ) all_jails, source_files = parsed_result active_names: set[str] = await _get_active_jail_names(socket_path) @@ -1169,8 +1168,7 @@ async def activate_jail( # ---------------------------------------------------------------------- # # Pre-activation validation — collect warnings but do not block # # ---------------------------------------------------------------------- # - validation_result: JailValidationResult = await run_blocking( - None, _validate_jail_config_sync, Path(config_dir), name + validation_result: JailValidationResult = await run_blocking(_validate_jail_config_sync, Path(config_dir), name ) warnings: list[str] = [f"{i.field}: {i.message}" for i in validation_result.issues] if warnings: @@ -1209,14 +1207,10 @@ async def activate_jail( # we can restore it if activation fails. # # ---------------------------------------------------------------------- # local_path = Path(config_dir) / "jail.d" / f"{name}.local" - original_content: bytes | None = await run_blocking( - None, - lambda: local_path.read_bytes() if local_path.exists() else None, + original_content: bytes | None = await run_blocking(lambda: local_path.read_bytes() if local_path.exists() else None, ) - await run_blocking( - None, - _write_local_override_sync, + await run_blocking(_write_local_override_sync, Path(config_dir), name, True, @@ -1427,9 +1421,7 @@ async def deactivate_jail( if name not in active_names: raise JailAlreadyInactiveError(name) - await run_blocking( - None, - _write_local_override_sync, + await run_blocking(_write_local_override_sync, Path(config_dir), name, False, @@ -1516,9 +1508,7 @@ async def validate_jail_config( """ _safe_jail_name(name) loop = asyncio.get_event_loop() - return await run_blocking( - None, - _validate_jail_config_sync, + return await run_blocking(_validate_jail_config_sync, Path(config_dir), name, ) @@ -1555,9 +1545,7 @@ async def rollback_jail( loop = asyncio.get_event_loop() # Write enabled=false — this must succeed even when fail2ban is down. - await run_blocking( - None, - _write_local_override_sync, + await run_blocking(_write_local_override_sync, Path(config_dir), name, False, @@ -2184,9 +2172,7 @@ async def assign_filter_to_jail( await run_blocking( _check_filter) - await run_blocking( - None, - _set_jail_local_key_sync, + await run_blocking(_set_jail_local_key_sync, Path(config_dir), jail_name, "filter", @@ -3037,9 +3023,7 @@ async def assign_action_to_jail( else: action_entry = req.action_name - await run_blocking( - None, - _append_jail_action_sync, + await run_blocking(_append_jail_action_sync, Path(config_dir), jail_name, action_entry, @@ -3099,9 +3083,7 @@ async def remove_action_from_jail( if jail_name not in all_jails: raise JailNotFoundInConfigError(jail_name) - await run_blocking( - None, - _remove_jail_action_sync, + await run_blocking(_remove_jail_action_sync, Path(config_dir), jail_name, action_name, diff --git a/backend/app/services/filter_config_service.py b/backend/app/services/filter_config_service.py index 7bd9f2f..d20c6a4 100644 --- a/backend/app/services/filter_config_service.py +++ b/backend/app/services/filter_config_service.py @@ -899,9 +899,7 @@ async def assign_filter_to_jail( await run_blocking( _check_filter) - await run_blocking( - None, - _set_jail_local_key_sync, + await run_blocking(_set_jail_local_key_sync, Path(config_dir), jail_name, "filter", diff --git a/backend/app/services/jail_config_service.py b/backend/app/services/jail_config_service.py index b6daef4..3380b43 100644 --- a/backend/app/services/jail_config_service.py +++ b/backend/app/services/jail_config_service.py @@ -503,8 +503,7 @@ async def list_inactive_jails( inactive jails. """ loop = asyncio.get_event_loop() - parsed_result: tuple[dict[str, dict[str, str]], dict[str, str]] = await run_blocking( - None, _parse_jails_sync, Path(config_dir) + parsed_result: tuple[dict[str, dict[str, str]], dict[str, str]] = await run_blocking(_parse_jails_sync, Path(config_dir) ) all_jails, source_files = parsed_result active_names: set[str] = await _get_active_jail_names(socket_path) @@ -601,8 +600,7 @@ async def _activate_jail( # ---------------------------------------------------------------------- # # Pre-activation validation — collect warnings but do not block # # ---------------------------------------------------------------------- # - validation_result: JailValidationResult = await run_blocking( - None, _validate_jail_config_sync, Path(config_dir), name + validation_result: JailValidationResult = await run_blocking(_validate_jail_config_sync, Path(config_dir), name ) warnings: list[str] = [f"{i.field}: {i.message}" for i in validation_result.issues] if warnings: @@ -641,14 +639,10 @@ async def _activate_jail( # we can restore it if activation fails. # # ---------------------------------------------------------------------- # local_path = Path(config_dir) / "jail.d" / f"{name}.local" - original_content: bytes | None = await run_blocking( - None, - lambda: local_path.read_bytes() if local_path.exists() else None, + original_content: bytes | None = await run_blocking(lambda: local_path.read_bytes() if local_path.exists() else None, ) - await run_blocking( - None, - _write_local_override_sync, + await run_blocking(_write_local_override_sync, Path(config_dir), name, True, @@ -876,9 +870,7 @@ async def _deactivate_jail( if name not in active_names: raise JailAlreadyInactiveError(name) - await run_blocking( - None, - _write_local_override_sync, + await run_blocking(_write_local_override_sync, Path(config_dir), name, False, @@ -965,9 +957,7 @@ async def validate_jail_config( """ _safe_jail_name(name) loop = asyncio.get_event_loop() - return await run_blocking( - None, - _validate_jail_config_sync, + return await run_blocking(_validate_jail_config_sync, Path(config_dir), name, ) @@ -1021,9 +1011,7 @@ async def _rollback_jail( loop = asyncio.get_event_loop() # Write enabled=false — this must succeed even when fail2ban is down. - await run_blocking( - None, - _write_local_override_sync, + await run_blocking(_write_local_override_sync, Path(config_dir), name, False, diff --git a/backend/app/services/log_service.py b/backend/app/services/log_service.py index 2829b6e..74a7720 100644 --- a/backend/app/services/log_service.py +++ b/backend/app/services/log_service.py @@ -72,7 +72,6 @@ async def preview_log(req: LogPreviewRequest) -> LogPreviewResponse: try: raw_lines = await run_blocking( - None, _read_tail_lines, str(path), req.num_lines,