from __future__ import annotations import hashlib import json import math import multiprocessing as mp import os import platform import queue import threading import time import urllib.request from dataclasses import asdict, dataclass, field from datetime import datetime, timezone from pathlib import Path from typing import Any GB = 1024 ** 3 MB = 1024 ** 2 def _read_text(path: str) -> str | None: try: candidate = Path(path) if candidate.exists(): return candidate.read_text(encoding="utf-8", errors="replace").strip() except OSError: return None return None def _safe_float(value: Any, default: float = 0.0) -> float: try: return float(value) except (TypeError, ValueError): return default def _cpu_model_name() -> str: cpuinfo = _read_text("/proc/cpuinfo") or "" for line in cpuinfo.splitlines(): key, separator, value = line.partition(":") if separator and key.strip().lower() in {"model name", "hardware", "processor"}: clean = value.strip() if clean and not clean.isdigit(): return clean return platform.processor() or platform.machine() or "Unknown CPU" def _cgroup_cpu_quota() -> tuple[float | None, str, str]: cpu_max = _read_text("/sys/fs/cgroup/cpu.max") if cpu_max: parts = cpu_max.split() if len(parts) >= 2: raw = f"{parts[0]} {parts[1]}" if parts[0] == "max": return None, "cgroup_v2_cpu.max", raw try: quota = int(parts[0]) period = int(parts[1]) if quota > 0 and period > 0: return quota / period, "cgroup_v2_cpu.max", raw except (ValueError, ZeroDivisionError): pass quota_text = _read_text("/sys/fs/cgroup/cpu/cpu.cfs_quota_us") period_text = _read_text("/sys/fs/cgroup/cpu/cpu.cfs_period_us") if quota_text and period_text: raw = f"{quota_text} {period_text}" try: quota = int(quota_text) period = int(period_text) if quota < 0: return None, "cgroup_v1_cpu", raw if quota > 0 and period > 0: return quota / period, "cgroup_v1_cpu", raw except (ValueError, ZeroDivisionError): pass return None, "unavailable", "unavailable" def _cgroup_memory_limit() -> tuple[int | None, str, str]: for path, source in ( ("/sys/fs/cgroup/memory.max", "cgroup_v2_memory.max"), ("/sys/fs/cgroup/memory/memory.limit_in_bytes", "cgroup_v1_memory.limit"), ): text = _read_text(path) if not text: continue if text == "max": return None, source, text try: value = int(text) except ValueError: continue # Some cgroup-v1 hosts expose an enormous sentinel instead of "max". if value >= (1 << 60): return None, source, text if value > 0: return value, source, text return None, "unavailable", "unavailable" def _visible_total_ram() -> int: try: import psutil # type: ignore return int(psutil.virtual_memory().total) except Exception: meminfo = _read_text("/proc/meminfo") or "" for line in meminfo.splitlines(): if line.startswith("MemTotal:"): try: return int(line.split()[1]) * 1024 except (IndexError, ValueError): break return 0 def _memory_current() -> tuple[int, str]: for path, source in ( ("/sys/fs/cgroup/memory.current", "cgroup_v2_memory.current"), ("/sys/fs/cgroup/memory/memory.usage_in_bytes", "cgroup_v1_memory.usage_in_bytes"), ): text = _read_text(path) if text: try: return max(0, int(text)), source except ValueError: pass try: import psutil # type: ignore return int(psutil.Process(os.getpid()).memory_info().rss), "process_rss_fallback" except Exception: return 0, "unavailable" @dataclass(frozen=True) class HardwareSnapshot: cpu_model: str logical_cpu_visible: int affinity_cpu_count: int cpu_quota_vcpu: float | None effective_vcpu: float cpu_limit_source: str cpu_limit_raw: str visible_ram_bytes: int cgroup_ram_limit_bytes: int | None effective_ram_bytes: int ram_limit_source: str ram_limit_raw: str platform: str python_version: str @dataclass(frozen=True) class ResourceSnapshot: """Latest real CloudVaultHub container resource reading. cpu_used_vcpu is average CPU seconds divided by wall seconds. For example, 2.50 means that the container used the equivalent of 2.5 CPU cores during the sample. It is not a simulated percentage. """ cpu_used_vcpu: float ram_used_bytes: int ram_used_gb: float effective_vcpu: float logical_cpu_visible: int effective_ram_bytes: int effective_ram_gb: float sample_seconds: float updated_at_unix: float cpu_source: str ram_source: str class SystemResourceMonitor: def __init__(self, refresh_seconds: float = 60.0) -> None: self.refresh_seconds = max(5.0, float(refresh_seconds)) self._lock = threading.RLock() self._stop = threading.Event() self._hardware = self._detect_hardware() self._snapshot = ResourceSnapshot( cpu_used_vcpu=0.0, ram_used_bytes=0, ram_used_gb=0.0, effective_vcpu=self._hardware.effective_vcpu, logical_cpu_visible=self._hardware.logical_cpu_visible, effective_ram_bytes=self._hardware.effective_ram_bytes, effective_ram_gb=round(self._hardware.effective_ram_bytes / GB, 3), sample_seconds=0.0, updated_at_unix=time.time(), cpu_source="waiting_for_first_sample", ram_source="waiting_for_first_sample", ) self._print_startup_report() self._thread = threading.Thread( target=self._run, daemon=True, name="cloudvault-resource-monitor", ) self._thread.start() def _detect_hardware(self) -> HardwareSnapshot: visible = max(1, os.cpu_count() or 1) try: affinity = max(1, len(os.sched_getaffinity(0))) except (AttributeError, OSError): affinity = visible quota, cpu_source, cpu_raw = _cgroup_cpu_quota() candidates = [float(visible), float(affinity)] if quota is not None: candidates.append(float(quota)) effective_vcpu = max(0.01, min(candidates)) visible_ram = _visible_total_ram() ram_limit, ram_source, ram_raw = _cgroup_memory_limit() ram_candidates = [value for value in (visible_ram, ram_limit) if value and value > 0] effective_ram = min(ram_candidates) if ram_candidates else max(0, visible_ram) return HardwareSnapshot( cpu_model=_cpu_model_name(), logical_cpu_visible=visible, affinity_cpu_count=affinity, cpu_quota_vcpu=round(quota, 3) if quota is not None else None, effective_vcpu=round(effective_vcpu, 3), cpu_limit_source=cpu_source, cpu_limit_raw=cpu_raw, visible_ram_bytes=visible_ram, cgroup_ram_limit_bytes=ram_limit, effective_ram_bytes=effective_ram, ram_limit_source=ram_source, ram_limit_raw=ram_raw, platform=platform.platform(), python_version=platform.python_version(), ) def _print_startup_report(self) -> None: h = self._hardware cpu_quota = "unlimited/not exposed" if h.cpu_quota_vcpu is None else f"{h.cpu_quota_vcpu:.2f} vCPU" ram_limit = "unlimited/not exposed" if h.cgroup_ram_limit_bytes is None else f"{h.cgroup_ram_limit_bytes / GB:.2f} GB" print("\n========== CLOUDVAULTHUB v172 HARDWARE ==========") print(f"CPU model : {h.cpu_model}") print(f"Logical CPUs visible : {h.logical_cpu_visible}") print(f"CPU affinity count : {h.affinity_cpu_count}") print(f"cgroup CPU quota : {cpu_quota} ({h.cpu_limit_source}: {h.cpu_limit_raw})") print(f"Effective CPU capacity : {h.effective_vcpu:.2f} vCPU") print(f"Visible RAM : {h.visible_ram_bytes / GB:.2f} GB") print(f"cgroup RAM limit : {ram_limit} ({h.ram_limit_source}: {h.ram_limit_raw})") print(f"Effective RAM capacity : {h.effective_ram_bytes / GB:.2f} GB") print(f"Platform : {h.platform}") print(f"Python : {h.python_version}") print("=================================================\n", flush=True) def hardware(self) -> HardwareSnapshot: return self._hardware def _cpu_counter_seconds(self) -> tuple[float, str]: cpu_stat = _read_text("/sys/fs/cgroup/cpu.stat") if cpu_stat: for line in cpu_stat.splitlines(): key, _, value = line.partition(" ") if key == "usage_usec": try: return int(value.strip()) / 1_000_000.0, "cgroup_v2_cpu.stat" except ValueError: break cpuacct = _read_text("/sys/fs/cgroup/cpuacct/cpuacct.usage") if cpuacct: try: return int(cpuacct) / 1_000_000_000.0, "cgroup_v1_cpuacct" except ValueError: pass try: process_times = os.times() return float(process_times.user + process_times.system), "process_times_fallback" except (AttributeError, OSError): return 0.0, "unavailable" def _store_sample( self, previous_cpu: float, previous_wall: float, current_cpu: float, current_wall: float, cpu_source: str, ) -> None: elapsed = max(0.001, current_wall - previous_wall) cpu_delta = max(0.0, current_cpu - previous_cpu) used_vcpu = cpu_delta / elapsed used_vcpu = min(max(0.0, used_vcpu), max(self._hardware.effective_vcpu, 0.01)) ram_bytes, ram_source = _memory_current() snapshot = ResourceSnapshot( cpu_used_vcpu=round(used_vcpu, 3), ram_used_bytes=ram_bytes, ram_used_gb=round(ram_bytes / GB, 3), effective_vcpu=self._hardware.effective_vcpu, logical_cpu_visible=self._hardware.logical_cpu_visible, effective_ram_bytes=self._hardware.effective_ram_bytes, effective_ram_gb=round(self._hardware.effective_ram_bytes / GB, 3), sample_seconds=round(elapsed, 3), updated_at_unix=time.time(), cpu_source=cpu_source, ram_source=ram_source, ) with self._lock: self._snapshot = snapshot def _run(self) -> None: previous_cpu, source = self._cpu_counter_seconds() previous_wall = time.monotonic() if self._stop.wait(1.0): return current_cpu, source = self._cpu_counter_seconds() current_wall = time.monotonic() self._store_sample(previous_cpu, previous_wall, current_cpu, current_wall, source) previous_cpu, previous_wall = current_cpu, current_wall while not self._stop.wait(self.refresh_seconds): current_cpu, source = self._cpu_counter_seconds() current_wall = time.monotonic() self._store_sample(previous_cpu, previous_wall, current_cpu, current_wall, source) previous_cpu, previous_wall = current_cpu, current_wall def snapshot(self) -> ResourceSnapshot: with self._lock: return self._snapshot def as_dict(self) -> dict[str, Any]: return asdict(self.snapshot()) def stop(self) -> None: self._stop.set() def _cpu_benchmark_worker( duration_seconds: float, stop_event: Any, output_queue: Any, ) -> None: started_wall = time.perf_counter() started_cpu = time.process_time() deadline = started_wall + max(0.5, duration_seconds) payload = b"CloudVaultHub-v172-CPU-benchmark" iterations = 0 try: while time.perf_counter() < deadline and not stop_event.is_set(): # 128 hashes per cancellation check keeps the worker responsive. for _ in range(128): payload = hashlib.sha256(payload).digest() iterations += 128 output_queue.put( { "iterations": iterations, "cpu_seconds": max(0.0, time.process_time() - started_cpu), "wall_seconds": max(0.001, time.perf_counter() - started_wall), } ) except BaseException as exc: # child process must always report completion try: output_queue.put({"error": str(exc), "iterations": iterations}) except Exception: pass @dataclass class BenchmarkState: status: str = "idle" stage: str = "Ready" progress: int = 0 started_at: str | None = None finished_at: str | None = None cancelled: bool = False error: str = "" result: dict[str, Any] = field(default_factory=dict) class SystemBenchmarkManager: """One safe, cancellable Admin benchmark for CPU, RAM and HTTP latency.""" def __init__(self, monitor: SystemResourceMonitor) -> None: self.monitor = monitor self._lock = threading.RLock() self._stop = threading.Event() self._mp_stop: Any = None self._thread: threading.Thread | None = None self._children: list[Any] = [] self._state = BenchmarkState() def _set(self, **updates: Any) -> None: with self._lock: for key, value in updates.items(): setattr(self._state, key, value) def state(self) -> dict[str, Any]: with self._lock: payload = asdict(self._state) payload["hardware"] = asdict(self.monitor.hardware()) payload["live"] = asdict(self.monitor.snapshot()) return payload def start(self, ping_url: str) -> tuple[bool, str]: with self._lock: if self._thread and self._thread.is_alive(): return False, "A hardware measurement is already running." self._stop = threading.Event() self._mp_stop = None self._children = [] self._state = BenchmarkState( status="running", stage="Preparing real hardware measurement", progress=2, started_at=datetime.now(timezone.utc).isoformat(), ) self._thread = threading.Thread( target=self._run, args=(str(ping_url or "").strip(),), daemon=True, name="cloudvault-admin-hardware-benchmark", ) self._thread.start() return True, "Hardware measurement started." def stop(self) -> bool: with self._lock: running = bool(self._thread and self._thread.is_alive()) if not running: return False self._state.stage = "Stopping safely" self._state.cancelled = True self._stop.set() if self._mp_stop is not None: try: self._mp_stop.set() except Exception: pass children = list(self._children) for child in children: try: if child.is_alive(): child.join(timeout=0.25) if child.is_alive(): child.terminate() except Exception: pass return True def _measure_ping(self, url: str) -> dict[str, Any]: if not url: return {"available": False, "error": "PUBLIC_BASE_URL is empty."} samples: list[float] = [] errors: list[str] = [] for _ in range(3): if self._stop.is_set(): break started = time.perf_counter() try: request = urllib.request.Request( url, method="GET", headers={"User-Agent": "CloudVaultHub-v172-hardware-test"}, ) with urllib.request.urlopen(request, timeout=6) as response: response.read(64) samples.append((time.perf_counter() - started) * 1000.0) except Exception as exc: errors.append(str(exc)[:240]) if self._stop.wait(0.15): break if not samples: return {"available": False, "error": errors[-1] if errors else "Measurement stopped."} return { "available": True, "samples_ms": [round(value, 2) for value in samples], "average_ms": round(sum(samples) / len(samples), 2), "minimum_ms": round(min(samples), 2), "maximum_ms": round(max(samples), 2), "errors": errors, } def _measure_memory(self) -> dict[str, Any]: # 128 MiB keeps the test safe even on CPU Basic while still measuring # real copy bandwidth. It never tries to fill the advertised RAM. size = 128 * MB source = bytearray(os.urandom(1024)) * (size // 1024) target = bytearray(size) passes = 6 started = time.perf_counter() completed = 0 for _ in range(passes): if self._stop.is_set(): break target[:] = source completed += 1 elapsed = max(0.001, time.perf_counter() - started) bytes_copied = size * completed checksum = hashlib.sha256(target[:4096]).hexdigest()[:12] if completed else "" del source, target return { "buffer_mb": size / MB, "passes": completed, "elapsed_seconds": round(elapsed, 3), "copy_mbps": round((bytes_copied / MB) / elapsed, 2) if completed else 0.0, "checksum": checksum, } def _measure_cpu(self) -> dict[str, Any]: hardware = self.monitor.hardware() desired = max(1, min(16, hardware.logical_cpu_visible, int(math.ceil(hardware.effective_vcpu)))) duration = 5.0 try: context = mp.get_context("fork") except ValueError: context = mp.get_context() stop_event = context.Event() output_queue = context.Queue() with self._lock: self._mp_stop = stop_event processes = [ context.Process( target=_cpu_benchmark_worker, args=(duration, stop_event, output_queue), daemon=True, name=f"cvh-cpu-benchmark-{index + 1}", ) for index in range(desired) ] with self._lock: self._children = processes wall_started = time.perf_counter() for process in processes: process.start() while any(process.is_alive() for process in processes): if self._stop.wait(0.1): stop_event.set() break for process in processes: process.join(timeout=1.0) if process.is_alive(): process.terminate() process.join(timeout=0.5) wall_elapsed = max(0.001, time.perf_counter() - wall_started) reports: list[dict[str, Any]] = [] while True: try: reports.append(output_queue.get_nowait()) except queue.Empty: break except Exception: break total_iterations = sum(int(item.get("iterations", 0)) for item in reports) total_cpu_seconds = sum(_safe_float(item.get("cpu_seconds")) for item in reports) estimated_parallel = min( float(desired), max(0.0, total_cpu_seconds / wall_elapsed), ) return { "workers_requested": desired, "workers_reported": len(reports), "duration_seconds": round(wall_elapsed, 3), "hashes": total_iterations, "hashes_per_second": round(total_iterations / wall_elapsed, 2), "aggregate_cpu_seconds": round(total_cpu_seconds, 3), "mathematical_parallel_vcpu": round(estimated_parallel, 2), "effective_cgroup_vcpu": hardware.effective_vcpu, "cancelled": self._stop.is_set(), } def _run(self, ping_url: str) -> None: result: dict[str, Any] = {} try: self._set(stage="Measuring server ping", progress=10) result["ping"] = self._measure_ping(ping_url) if self._stop.is_set(): raise InterruptedError("Measurement stopped by the developer.") self._set(stage="Measuring RAM copy speed", progress=32) result["memory"] = self._measure_memory() if self._stop.is_set(): raise InterruptedError("Measurement stopped by the developer.") self._set(stage="Measuring parallel CPU capacity", progress=55) result["cpu"] = self._measure_cpu() if self._stop.is_set(): raise InterruptedError("Measurement stopped by the developer.") result["hardware"] = asdict(self.monitor.hardware()) result["live_after_test"] = asdict(self.monitor.snapshot()) self._set( status="complete", stage="Measurement completed", progress=100, finished_at=datetime.now(timezone.utc).isoformat(), result=result, ) print("[CloudVaultHub v172 benchmark] " + json.dumps(result, ensure_ascii=False), flush=True) except InterruptedError as exc: self._set( status="cancelled", stage=str(exc), progress=min(99, max(0, self._state.progress)), finished_at=datetime.now(timezone.utc).isoformat(), cancelled=True, result=result, ) except Exception as exc: self._set( status="error", stage="Measurement failed", finished_at=datetime.now(timezone.utc).isoformat(), error=str(exc), result=result, ) finally: with self._lock: self._children = [] self._mp_stop = None RESOURCE_MONITOR = SystemResourceMonitor(refresh_seconds=60.0) RESOURCE_BENCHMARK = SystemBenchmarkManager(RESOURCE_MONITOR)