#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ 自动检测VM的IP地址 使用vmrun getGuestIPAddress命令获取VM的当前IP """ import subprocess import sys import json import os from pathlib import Path try: import requests except ImportError: requests = None # 添加项目根目录到路径 project_root = Path(__file__).parent.parent.parent sys.path.insert(0, str(project_root)) from scripts.utils.config_loader import load_config def get_vm_ip(vmx_path, vm_password=None): """ 使用vmrun获取VM的IP地址 Args: vmx_path: 虚拟机.vmx文件路径 vm_password: 虚拟机文件加密密码(可选) Returns: str: VM的IP地址,如果失败返回None """ vmrun = "/Applications/VMware Fusion.app/Contents/Library/vmrun" # 构建命令 cmd = [vmrun, "-T", "fusion"] if vm_password: cmd.extend(["-vp", vm_password]) cmd.extend(["getGuestIPAddress", vmx_path]) try: result = subprocess.run( cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, timeout=10 ) if result.returncode == 0: ip = result.stdout.strip() if ip and ip != "": return ip else: print(f"⚠️ vmrun返回空IP地址") return None else: error_msg = result.stderr or result.stdout print(f"❌ 获取IP失败: {error_msg}") return None except subprocess.TimeoutExpired: print(f"❌ 获取IP超时") return None except Exception as e: print(f"❌ 获取IP异常: {e}") return None def update_config_ip(new_ip, config_path="config.json"): """ 更新config.json中的IP地址 Args: new_ip: 新的IP地址 config_path: 配置文件路径 """ config_path = os.path.join(project_root, config_path) if not os.path.exists(config_path): print(f"❌ 配置文件不存在: {config_path}") return False try: with open(config_path, 'r', encoding='utf-8') as f: config = json.load(f) old_ip = config.get("network", {}).get("vm_ip", "未知") if old_ip == new_ip: print(f"✅ IP地址未变化: {new_ip}") return True config["network"]["vm_ip"] = new_ip with open(config_path, 'w', encoding='utf-8') as f: json.dump(config, f, indent=2, ensure_ascii=False) print(f"✅ 已更新IP地址: {old_ip} → {new_ip}") return True except Exception as e: print(f"❌ 更新配置文件失败: {e}") return False def test_http_connection(ip, port=5000, timeout=5): """ 测试HTTP连接是否可用 Args: ip: VM的IP地址 port: 端口号 timeout: 超时时间(秒) Returns: bool: 连接是否成功 """ try: import requests except ImportError: print(f"⚠️ requests模块未安装,跳过HTTP连接测试") return False url = f"http://{ip}:{port}/screen_info" proxies = {'http': None, 'https': None} # 绕过代理 try: response = requests.get(url, timeout=timeout, proxies=proxies) if response.status_code == 200: print(f"✅ HTTP服务连接成功: {url}") return True else: print(f"⚠️ HTTP服务响应异常: 状态码 {response.status_code}") return False except requests.exceptions.Timeout: print(f"⚠️ HTTP服务连接超时: {url}") return False except requests.exceptions.ConnectionError as e: print(f"⚠️ HTTP服务连接失败: {url}") print(f" 错误: {str(e)[:100]}") return False except Exception as e: print(f"⚠️ HTTP连接异常: {e}") return False def main(): """主函数""" print("=" * 60) print("🔍 检测VM IP地址") print("=" * 60) # 加载配置 try: config = load_config() vmx_path = config["vmware"]["vmx_path"] vm_password = config["vmware"].get("vm_password") current_ip = config["network"].get("vm_ip", "未知") except Exception as e: print(f"❌ 加载配置失败: {e}") sys.exit(1) print(f"\n📋 当前配置:") print(f" VM路径: {os.path.basename(vmx_path)}") print(f" 当前IP: {current_ip}") print(f" 端口: {config['network'].get('agent_server_port', 5000)}") # 获取VM IP print(f"\n🔍 正在获取VM IP地址...") vm_ip = get_vm_ip(vmx_path, vm_password) if not vm_ip: print("\n❌ 无法获取VM IP地址") print(" 可能原因:") print(" 1. VM未运行") print(" 2. VM网络未配置") print(" 3. vmrun命令执行失败") sys.exit(1) print(f"✅ 检测到VM IP: {vm_ip}") # 测试HTTP连接 port = config["network"].get("agent_server_port", 5000) print(f"\n🔗 测试HTTP连接 (端口 {port})...") http_ok = test_http_connection(vm_ip, port) # 询问是否更新配置 if vm_ip != current_ip: print(f"\n⚠️ IP地址已变化: {current_ip} → {vm_ip}") if http_ok: print(f"\n❓ 是否更新配置文件? (y/n): ", end="") try: choice = input().strip().lower() if choice == 'y': if update_config_ip(vm_ip): print(f"\n✅ 配置已更新!") else: print(f"\n❌ 配置更新失败") else: print(f"\n⏭️ 跳过更新") except KeyboardInterrupt: print(f"\n\n⚠️ 用户取消") else: print(f"\n⚠️ HTTP服务不可用,请检查:") print(f" 1. VM中是否运行了 agent_server.py?") print(f" 2. 端口 {port} 是否被占用?") print(f" 3. 防火墙是否阻止了连接?") else: print(f"\n✅ IP地址未变化") if not http_ok: print(f"\n⚠️ 但HTTP服务不可用,请检查VM中的agent_server.py") print("=" * 60) if __name__ == "__main__": main()