import logging import os import time import requests from desktop_env.providers.base import Provider logger = logging.getLogger("desktopenv.providers.direct.DirectProvider") logger.setLevel(logging.INFO) RETRY_INTERVAL = 3 MAX_WAIT_READY = 60 class DirectProvider(Provider): """ Provider for directly connected machines (physical / bare-metal). No VM lifecycle management — the machine is assumed to be already running. The Flask server IP is read from the environment variable DIRECT_VM_IP. Usage: export DIRECT_VM_IP=192.168.1.11 python run.py --provider_name direct --path_to_vm ignored ... """ def __init__(self, region: str = None): super().__init__(region) self.vm_ip = os.environ.get("DIRECT_VM_IP", "192.168.1.11") def start_emulator(self, path_to_vm: str, headless: bool, os_type: str = "Windows"): """No-op: machine is already on. Just verify Flask server is reachable.""" logger.info(f"[direct] Using physical machine at {self.vm_ip}:5000 (no VM lifecycle)") self._wait_for_vm_ready(self.vm_ip) def _wait_for_vm_ready(self, ip: str, timeout: int = MAX_WAIT_READY) -> bool: url = f"http://{ip}:5000/screenshot" deadline = time.time() + timeout while time.time() < deadline: try: r = requests.get(url, timeout=5) if r.status_code == 200: logger.info(f"[direct] Flask server ready at {url}") return True except Exception: pass logger.info(f"[direct] Waiting for Flask server at {url}...") time.sleep(RETRY_INTERVAL) logger.warning(f"[direct] Flask server at {url} not ready within {timeout}s — continuing anyway") return False def get_ip_address(self, path_to_vm: str) -> str: return self.vm_ip def save_state(self, path_to_vm: str, snapshot_name: str): logger.info("[direct] save_state: no-op (physical machine)") def revert_to_snapshot(self, path_to_vm: str, snapshot_name: str) -> str: logger.info("[direct] revert_to_snapshot: no-op (physical machine)") return path_to_vm def stop_emulator(self, path_to_vm: str): logger.info("[direct] stop_emulator: no-op (physical machine)")