fix watcher for smb

This commit is contained in:
2026-07-14 11:43:59 -04:00
parent 834ab81a94
commit b68b8f54bd
7 changed files with 190 additions and 133 deletions
+38 -15
View File
@@ -3,6 +3,7 @@ import re
import threading
import tempfile
import smbclient
from pathlib import Path
from db_py import (
mark_tests_completed,
@@ -25,6 +26,8 @@ from parser import (
_SMB_SESSIONS = set()
_SCAN_STATE_LOCK = threading.Lock()
_ACTIVE_SCAN_COUNT = 0
_LAST_SCAN_ERRORS = []
_SCAN_ERRORS_LOCK = threading.Lock()
_ELAPSED_TIME_LINE_RE = re.compile(r"Elapsed\s+time\s*:\s*(\d+):(\d{1,2}):(\d{1,2}(?:\.\d+)?)", re.IGNORECASE)
@@ -158,6 +161,23 @@ def is_scan_in_progress():
return _ACTIVE_SCAN_COUNT > 0
def _clear_scan_errors():
global _LAST_SCAN_ERRORS
with _SCAN_ERRORS_LOCK:
_LAST_SCAN_ERRORS = []
def _record_scan_error(msg):
with _SCAN_ERRORS_LOCK:
if msg not in _LAST_SCAN_ERRORS:
_LAST_SCAN_ERRORS.append(msg)
def get_scan_errors():
with _SCAN_ERRORS_LOCK:
return list(_LAST_SCAN_ERRORS)
def resolve_runtime_path(path_value):
if not path_value:
return path_value
@@ -166,12 +186,15 @@ def resolve_runtime_path(path_value):
if not raw_path:
return raw_path
# If the path is already valid in the current runtime, keep it.
if os.path.exists(raw_path):
# UNC/network paths are handled separately via smbclient — check before
# any local filesystem call because backslashes are regular characters on
# Linux, so Path(unc).exists() treats the whole string as one path
# component and raises ENAMETOOLONG for paths > 255 chars.
if raw_path.startswith("\\\\") or raw_path.startswith("//"):
return raw_path
# UNC/network paths are handled separately via smbclient.
if raw_path.startswith("\\\\") or raw_path.startswith("//"):
# If the path is already valid in the current runtime, keep it.
if Path(raw_path).exists():
return raw_path
# Map host paths (Windows or Linux) to the container mount point when running in a container.
@@ -185,7 +208,7 @@ def resolve_runtime_path(path_value):
if raw_norm.lower() == host_norm.lower() or raw_norm.lower().startswith(host_norm.lower() + "/"):
relative = raw_norm[len(host_norm):].lstrip("/")
if relative:
return os.path.join(mount_root, *relative.split("/"))
return str(Path(mount_root).joinpath(*relative.split("/")))
return mount_root
return raw_path
@@ -248,14 +271,14 @@ def _iter_dir_entries(path):
if _is_unc_path(path):
_register_smb_session_if_needed(path)
return list(smbclient.scandir(path))
return list(os.scandir(path))
return list(Path(path).iterdir())
def _join_path(path, name):
if _is_unc_path(path):
base = path.rstrip("\\")
return f"{base}\\{name}"
return os.path.join(path, name)
return str(Path(path) / name)
def _read_text_lines(path):
@@ -371,6 +394,7 @@ def full_scan(target_dir, results_dir, results_dir_ref):
results_dir = _normalize_input_path(results_dir)
results_dir_ref = _normalize_input_path(results_dir_ref)
_clear_scan_errors()
_scan_started()
try:
clear_tests()
@@ -378,7 +402,7 @@ def full_scan(target_dir, results_dir, results_dir_ref):
return
print(f"[scanner] target dir : {target_dir}")
print(f"[scanner] results dir : {results_dir}")
print(f"[scanner] results dir dut : {results_dir}")
print(f"[scanner] results dir ref : {results_dir_ref}")
if not scan_targets(target_dir):
@@ -406,8 +430,9 @@ def scan_targets(target_dir):
for entry in _iter_dir_entries(target_dir)
if entry.is_dir()
]
except OSError as exc:
except (OSError, ValueError) as exc:
print(f"[scanner] Cannot read target dir: {exc}")
_record_scan_error(f"Cannot read target directory: {exc}")
return False
print(f"[scanner] subdirectories found: {len(parent_entries)}")
@@ -422,7 +447,7 @@ def scan_targets(target_dir):
and not entry.name.startswith("GLOBAL")
and entry.name.endswith(".ini")
]
except OSError as exc:
except (OSError, ValueError) as exc:
print(f"[scanner] Cannot read parent dir {parent_name}: {exc}")
continue
@@ -476,8 +501,9 @@ def scan_results(results_dir):
for entry in _iter_dir_entries(results_dir)
if entry.is_dir()
]
except OSError as exc:
except (OSError, ValueError) as exc:
print(f"[scanner] Cannot read results dir: {exc}")
_record_scan_error(f"Cannot read results directory: {exc}")
return
print(f"[scanner] results: {len(entries)} result dir(s) found")
@@ -557,9 +583,6 @@ def extract_measurement_data(db_file_path):
print(f"[scanner] Cannot read measurement db {db_file_path}: {exc}")
finally:
if local_db_path:
try:
os.remove(local_db_path)
except OSError:
pass
Path(local_db_path).unlink(missing_ok=True)
return result