using QemuVmManager.Services; using QemuVmManager.Core; using QemuVmManager.Models; using System.Linq; namespace QemuVmManager.Console; class Program { static async Task Main(string[] args) { System.Console.WriteLine("=== QEMU VM Manager ==="); System.Console.WriteLine("Choose mode:"); System.Console.WriteLine("1. Single Node Mode (original)"); System.Console.WriteLine("2. P2P Distributed Mode (new)"); System.Console.Write("Enter choice (1 or 2): "); var choice = System.Console.ReadLine()?.Trim(); if (choice == "2") { await RunP2PModeAsync(args); } else { await RunSingleNodeModeAsync(); } } static async Task RunP2PModeAsync(string[] args) { System.Console.WriteLine(); System.Console.WriteLine("=== P2P Distributed Mode ==="); var nodeId = args.Length > 0 ? args[0] : Environment.MachineName; var port = args.Length > 1 && int.TryParse(args[1], out var p) ? p : 8080; System.Console.WriteLine($"Node ID: {nodeId}"); System.Console.WriteLine($"Port: {port}"); System.Console.WriteLine(); var p2pConsole = new P2PConsole(nodeId, port); try { await p2pConsole.StartAsync(); } catch (Exception ex) { System.Console.WriteLine($"Error starting P2P node: {ex.Message}"); } } static async Task RunSingleNodeModeAsync() { System.Console.WriteLine(); System.Console.WriteLine("=== Single Node Mode ==="); var vmService = new VmManagementService(); System.Console.WriteLine("QEMU VM Manager - Single Node Mode"); System.Console.WriteLine("Type 'help' for available commands"); System.Console.WriteLine(); while (true) { try { System.Console.Write("qemu-vm> "); var input = System.Console.ReadLine()?.Trim(); if (string.IsNullOrEmpty(input)) continue; var parts = input.Split(' ', StringSplitOptions.RemoveEmptyEntries); var command = parts[0].ToLower(); var arguments = parts.Skip(1).ToArray(); switch (command) { case "help": ShowHelp(); break; case "list": await ListVmsAsync(vmService); break; case "create": await CreateVmAsync(vmService, arguments); break; case "start": await StartVmAsync(vmService, arguments); break; case "stop": await StopVmAsync(vmService, arguments); break; case "pause": await PauseVmAsync(vmService, arguments); break; case "resume": await ResumeVmAsync(vmService, arguments); break; case "delete": await DeleteVmAsync(vmService, arguments); break; case "import": await ImportVmAsync(vmService, arguments); break; case "status": await ShowVmStatusAsync(vmService, arguments); break; case "disk": await HandleDiskCommandsAsync(vmService, arguments); break; case "validate": await ValidateVmAsync(vmService, arguments); break; case "diagnose": await DiagnoseSystem(); break; case "monitor": await MonitorPerformance(arguments); break; case "metrics": await ShowMetrics(arguments); break; case "network": await HandleNetworkCommandsAsync(arguments); break; case "port": await HandlePortCommandsAsync(arguments); break; case "config": await HandleConfigCommandsAsync(vmService, arguments); break; case "exit": case "quit": System.Console.WriteLine("Goodbye!"); return; default: System.Console.WriteLine($"Unknown command: {command}"); System.Console.WriteLine("Type 'help' for available commands"); break; } } catch (Exception ex) { System.Console.WriteLine($"Error: {ex.Message}"); } System.Console.WriteLine(); } } static void ShowHelp() { System.Console.WriteLine("Available commands:"); System.Console.WriteLine(" list - List all VMs"); System.Console.WriteLine(" create - Create a new VM (interactive)"); System.Console.WriteLine(" import [name] - Import VM from configuration file"); System.Console.WriteLine(" start - Start a VM"); System.Console.WriteLine(" stop [--force] - Stop a VM"); System.Console.WriteLine(" pause - Pause a VM"); System.Console.WriteLine(" resume - Resume a VM"); System.Console.WriteLine(" delete - Delete a VM"); System.Console.WriteLine(" status [name] - Show VM status"); System.Console.WriteLine(" disk [info|resize|convert] - Manage disk images"); System.Console.WriteLine(" validate - Validate VM disk images"); System.Console.WriteLine(" diagnose - Diagnose system and QEMU installation"); System.Console.WriteLine(" monitor [start|stop|status] - Performance monitoring"); System.Console.WriteLine(" metrics [current|history] - Show performance metrics"); System.Console.WriteLine(" network - Network management (bridge, interfaces)"); System.Console.WriteLine(" port - Port forwarding management"); System.Console.WriteLine(" help - Show this help"); System.Console.WriteLine(" exit/quit - Exit the application"); } static async Task ListVmsAsync(VmManagementService vmService) { var configs = vmService.GetAllVmConfigurations().ToList(); var statuses = vmService.GetAllVmStatuses().ToDictionary(s => s.Name); if (configs.Count == 0) { System.Console.WriteLine("No VMs configured."); return; } System.Console.WriteLine($"{"Name",-20} {"Status",-10} {"CPU",-8} {"Memory",-10} {"Description"}"); System.Console.WriteLine(new string('-', 80)); foreach (var config in configs) { var status = statuses.GetValueOrDefault(config.Name); var statusText = status?.State.ToString() ?? "Unknown"; var cpuText = $"{config.Cpu.Cores} cores"; var memoryText = $"{config.Memory.Size}{config.Memory.Unit}"; System.Console.WriteLine($"{config.Name,-20} {statusText,-10} {cpuText,-8} {memoryText,-10} {config.Description}"); } } static async Task CreateVmAsync(VmManagementService vmService, string[] arguments) { string vmName; if (arguments.Length > 0) { vmName = arguments[0]; } else { System.Console.Write("Enter VM name: "); vmName = System.Console.ReadLine()?.Trim() ?? ""; } if (string.IsNullOrEmpty(vmName)) { System.Console.WriteLine("VM name cannot be empty."); return; } var config = new VmConfiguration { Name = vmName, Description = GetUserInput("Description (optional): "), Cpu = new CpuConfiguration { Cores = int.Parse(GetUserInput("CPU cores (2): ", "2")), Model = GetUserInput("CPU model (qemu64): ", "qemu64") }, Memory = new MemoryConfiguration { Size = long.Parse(GetUserInput("Memory size in MB (2048): ", "2048")), Unit = "M" }, Storage = new StorageConfiguration { Disks = new List { new DiskConfiguration { Path = GetUserInput($"Disk path (vm-disks/{vmName}.qcow2): ", $"vm-disks/{vmName}.qcow2"), Size = long.Parse(GetUserInput("Disk size in GB (10): ", "10")), Format = GetUserInput("Disk format (qcow2): ", "qcow2"), Interface = GetUserInput("Disk interface (virtio): ", "virtio"), IsBoot = true } } }, Network = new NetworkConfiguration { Interfaces = new List { new NetworkInterfaceConfiguration { Type = "user", Model = "e1000" } } }, Display = new DisplayConfiguration { Type = GetUserInput("Display type (gtk): ", "gtk"), Vga = GetUserInput("VGA type (virtio): ", "virtio") } }; await vmService.CreateVmAsync(config); System.Console.WriteLine($"VM '{vmName}' created successfully."); } static async Task StartVmAsync(VmManagementService vmService, string[] arguments) { if (arguments.Length == 0) { System.Console.WriteLine("Usage: start "); return; } var vmName = arguments[0]; var success = await vmService.StartVmAsync(vmName); if (success) System.Console.WriteLine($"VM '{vmName}' started successfully."); else System.Console.WriteLine($"Failed to start VM '{vmName}'."); } static async Task StopVmAsync(VmManagementService vmService, string[] arguments) { if (arguments.Length == 0) { System.Console.WriteLine("Usage: stop [--force]"); return; } var vmName = arguments[0]; var force = arguments.Contains("--force"); var success = await vmService.StopVmAsync(vmName, force); if (success) System.Console.WriteLine($"VM '{vmName}' stopped successfully."); else System.Console.WriteLine($"Failed to stop VM '{vmName}'."); } static async Task PauseVmAsync(VmManagementService vmService, string[] arguments) { if (arguments.Length == 0) { System.Console.WriteLine("Usage: pause "); return; } var vmName = arguments[0]; var success = await vmService.PauseVmAsync(vmName); if (success) System.Console.WriteLine($"VM '{vmName}' paused successfully."); else System.Console.WriteLine($"Failed to pause VM '{vmName}'."); } static async Task ResumeVmAsync(VmManagementService vmService, string[] arguments) { if (arguments.Length == 0) { System.Console.WriteLine("Usage: resume "); return; } var vmName = arguments[0]; var success = await vmService.ResumeVmAsync(vmName); if (success) System.Console.WriteLine($"VM '{vmName}' resumed successfully."); else System.Console.WriteLine($"Failed to resume VM '{vmName}'."); } static async Task DeleteVmAsync(VmManagementService vmService, string[] arguments) { if (arguments.Length == 0) { System.Console.WriteLine("Usage: delete "); return; } var vmName = arguments[0]; await vmService.DeleteVmAsync(vmName); System.Console.WriteLine($"VM '{vmName}' deleted successfully."); } static async Task ShowVmStatusAsync(VmManagementService vmService, string[] arguments) { if (arguments.Length == 0) { // Show status of all VMs var statuses = vmService.GetAllVmStatuses(); if (!statuses.Any()) { System.Console.WriteLine("No VMs found."); return; } System.Console.WriteLine($"{"Name",-20} {"State",-10} {"PID",-8} {"CPU %",-8} {"Memory (MB)",-12}"); System.Console.WriteLine(new string('-', 70)); foreach (var status in statuses) { var cpuUsage = status.ResourceUsage?.CpuUsage.ToString("F1") ?? "N/A"; var memoryUsage = status.ResourceUsage?.MemoryUsage.ToString() ?? "N/A"; var pid = status.ProcessId > 0 ? status.ProcessId.ToString() : "N/A"; System.Console.WriteLine($"{status.Name,-20} {status.State,-10} {pid,-8} {cpuUsage,-8} {memoryUsage,-12}"); } } else { // Show status of specific VM var vmName = arguments[0]; var status = vmService.GetVmStatus(vmName); if (status == null) { System.Console.WriteLine($"VM '{vmName}' not found."); return; } System.Console.WriteLine($"=== VM Status: {vmName} ==="); System.Console.WriteLine($"State: {status.State}"); System.Console.WriteLine($"Process ID: {(status.ProcessId > 0 ? status.ProcessId.ToString() : "N/A")}"); System.Console.WriteLine($"Started: {status.StartedAt}"); if (status.ResourceUsage != null) { System.Console.WriteLine(); System.Console.WriteLine("=== Resource Usage ==="); System.Console.WriteLine($"CPU Usage: {status.ResourceUsage.CpuUsage:F1}%"); System.Console.WriteLine($"Memory Usage: {status.ResourceUsage.MemoryUsage} MB"); System.Console.WriteLine($"Disk Usage: {status.ResourceUsage.DiskUsage} MB"); System.Console.WriteLine($"Network RX: {status.ResourceUsage.NetworkRx} bytes"); System.Console.WriteLine($"Network TX: {status.ResourceUsage.NetworkTx} bytes"); } } } static async Task HandleDiskCommandsAsync(VmManagementService vmService, string[] arguments) { if (arguments.Length < 2) { System.Console.WriteLine("Usage: disk [options]"); System.Console.WriteLine("Commands: info, resize, convert"); return; } var vmName = arguments[0]; var command = arguments[1].ToLower(); var options = arguments.Skip(2).ToArray(); var config = vmService.GetVmConfiguration(vmName); if (config == null) { System.Console.WriteLine($"VM '{vmName}' not found."); return; } var diskManager = new DiskManager(); switch (command) { case "info": foreach (var disk in config.Storage.Disks) { var info = await diskManager.GetDiskInfoAsync(disk.Path, disk.Format); if (info != null) { System.Console.WriteLine($"=== Disk: {disk.Path} ==="); System.Console.WriteLine($"Format: {info.Format}"); System.Console.WriteLine($"Virtual Size: {info.VirtualSize}"); System.Console.WriteLine($"Disk Size: {info.DiskSize}"); } } break; case "resize": if (options.Length == 0) { System.Console.WriteLine("Usage: disk resize "); return; } var newSize = long.Parse(options[0]); foreach (var disk in config.Storage.Disks) { var success = await diskManager.ResizeDiskAsync(disk.Path, disk.Format, newSize); if (success) System.Console.WriteLine($"Resized disk {disk.Path} to {newSize} bytes"); else System.Console.WriteLine($"Failed to resize disk {disk.Path}"); } break; case "convert": if (options.Length == 0) { System.Console.WriteLine("Usage: disk convert [output-path]"); return; } var newFormat = options[0]; var outputPath = options.Length > 1 ? options[1] : null; foreach (var disk in config.Storage.Disks) { var targetPath = outputPath ?? disk.Path.Replace(Path.GetExtension(disk.Path), $".{newFormat}"); var success = await diskManager.ConvertDiskAsync(disk.Path, disk.Format, targetPath, newFormat); if (success) System.Console.WriteLine($"Converted disk {disk.Path} to {targetPath}"); else System.Console.WriteLine($"Failed to convert disk {disk.Path}"); } break; default: System.Console.WriteLine($"Unknown disk command: {command}"); break; } } static async Task ValidateVmAsync(VmManagementService vmService, string[] arguments) { if (arguments.Length == 0) { System.Console.WriteLine("Usage: validate "); return; } var vmName = arguments[0]; var config = vmService.GetVmConfiguration(vmName); if (config == null) { System.Console.WriteLine($"VM '{vmName}' not found."); return; } System.Console.WriteLine($"=== Validating VM: {vmName} ==="); var diskManager = new DiskManager(); var isValid = true; // Validate disks foreach (var disk in config.Storage.Disks) { System.Console.WriteLine($"Checking disk: {disk.Path}"); if (!File.Exists(disk.Path)) { System.Console.WriteLine($" ❌ Disk file not found: {disk.Path}"); isValid = false; continue; } try { var info = await diskManager.GetDiskInfoAsync(disk.Path, disk.Format); if (info != null) { System.Console.WriteLine($" ✅ Disk format: {info.Format}"); System.Console.WriteLine($" ✅ Virtual size: {info.VirtualSize:N0} bytes"); } else { System.Console.WriteLine($" ❌ Invalid disk format: {disk.Path}"); isValid = false; } } catch (Exception ex) { System.Console.WriteLine($" ❌ Error reading disk: {ex.Message}"); isValid = false; } } // Validate CD-ROM if specified if (!string.IsNullOrEmpty(config.Storage.Cdrom)) { System.Console.WriteLine($"Checking CD-ROM: {config.Storage.Cdrom}"); if (File.Exists(config.Storage.Cdrom)) { System.Console.WriteLine(" ✅ CD-ROM file found"); } else { System.Console.WriteLine(" ❌ CD-ROM file not found"); isValid = false; } } if (isValid) { System.Console.WriteLine($"✅ VM '{vmName}' validation passed"); } else { System.Console.WriteLine($"❌ VM '{vmName}' validation failed"); } } static async Task DiagnoseSystem() { System.Console.WriteLine("=== System Diagnosis ==="); System.Console.WriteLine(); // .NET Runtime System.Console.WriteLine("1. .NET Runtime:"); System.Console.WriteLine($" Version: {Environment.Version}"); System.Console.WriteLine($" OS: {Environment.OSVersion}"); System.Console.WriteLine($" Architecture: {Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE")}"); System.Console.WriteLine(); // QEMU Installation System.Console.WriteLine("2. QEMU Installation:"); var qemuManager = new QemuProcessManager(); var isInstalled = qemuManager.IsQemuInstalled(); var version = qemuManager.GetQemuVersion(); var virtualization = qemuManager.GetAvailableVirtualization(); var virtualizationEnabled = qemuManager.IsVirtualizationEnabled(); System.Console.WriteLine($" Installed: {(isInstalled ? "Yes" : "No")}"); if (isInstalled) { System.Console.WriteLine($" Version: {version}"); } System.Console.WriteLine($" Virtualization Enabled in BIOS: {(virtualizationEnabled ? "Yes" : "No")}"); System.Console.WriteLine($" Available Virtualization: {virtualization}"); if (!virtualizationEnabled) { System.Console.WriteLine(" ⚠️ Virtualization is not enabled in BIOS/UEFI"); System.Console.WriteLine(" Please enable VT-x (Intel) or AMD-V (AMD) in your BIOS settings"); System.Console.WriteLine(" This will significantly improve VM performance"); } System.Console.WriteLine(); // Disk Manager System.Console.WriteLine("3. Disk Manager:"); try { var diskManager = new DiskManager(); System.Console.WriteLine(" ✅ Disk manager initialized successfully"); } catch (Exception ex) { System.Console.WriteLine($" ❌ Disk manager initialization failed: {ex.Message}"); } System.Console.WriteLine(); // VM Configurations System.Console.WriteLine("4. VM Configurations:"); try { var vmService = new VmManagementService(); var configs = vmService.GetAllVmConfigurations().ToList(); System.Console.WriteLine($" Found {configs.Count} VM configuration(s)"); foreach (var config in configs) { System.Console.WriteLine($" - {config.Name}: {config.Description}"); foreach (var disk in config.Storage.Disks) { var exists = File.Exists(disk.Path); System.Console.WriteLine($" Disk: {disk.Path} - {(exists ? "✅ Exists" : "❌ Missing")}"); } } } catch (Exception ex) { System.Console.WriteLine($" ❌ Error reading VM configurations: {ex.Message}"); } System.Console.WriteLine(); // Running VMs System.Console.WriteLine("5. Running VMs:"); try { var vmService = new VmManagementService(); var statuses = vmService.GetAllVmStatuses().Where(s => s.State == VmState.Running).ToList(); System.Console.WriteLine($" Running: {statuses.Count}"); foreach (var status in statuses) { System.Console.WriteLine($" - {status.Name} (PID: {(status.ProcessId > 0 ? status.ProcessId.ToString() : "N/A")})"); } } catch (Exception ex) { System.Console.WriteLine($" ❌ Error checking running VMs: {ex.Message}"); } System.Console.WriteLine(); System.Console.WriteLine("=== Diagnosis Complete ==="); } static async Task MonitorPerformance(string[] arguments) { if (arguments.Length == 0) { System.Console.WriteLine("Usage: monitor [start|stop|status]"); return; } var vmName = arguments[0]; var action = arguments.Length > 1 ? arguments[1].ToLower() : "status"; try { var vmService = new VmManagementService(); switch (action) { case "start": await vmService.StartPerformanceMonitoringAsync(vmName); System.Console.WriteLine($"Started performance monitoring for VM '{vmName}'"); break; case "stop": await vmService.StopPerformanceMonitoringAsync(vmName); System.Console.WriteLine($"Stopped performance monitoring for VM '{vmName}'"); break; case "status": var isMonitoring = await vmService.IsPerformanceMonitoringActiveAsync(vmName); System.Console.WriteLine($"Performance monitoring for VM '{vmName}': {(isMonitoring ? "Active" : "Inactive")}"); break; default: System.Console.WriteLine($"Unknown action: {action}"); break; } } catch (Exception ex) { System.Console.WriteLine($"Error: {ex.Message}"); } } static async Task ShowMetrics(string[] arguments) { if (arguments.Length == 0) { System.Console.WriteLine("Usage: metrics [current|history]"); return; } var vmName = arguments[0]; var type = arguments.Length > 1 ? arguments[1].ToLower() : "current"; try { var vmService = new VmManagementService(); switch (type) { case "current": var currentMetrics = await vmService.GetCurrentPerformanceMetricsAsync(vmName); if (currentMetrics != null) { System.Console.WriteLine($"=== Current Metrics for VM '{vmName}' ==="); System.Console.WriteLine($"Timestamp: {currentMetrics.Timestamp:yyyy-MM-dd HH:mm:ss}"); System.Console.WriteLine($"Process ID: {currentMetrics.ProcessId}"); System.Console.WriteLine($"CPU Usage: {currentMetrics.CpuUsagePercent:F2}%"); System.Console.WriteLine($"System CPU: {currentMetrics.SystemCpuUsagePercent:F2}%"); System.Console.WriteLine($"Memory Usage: {currentMetrics.MemoryUsageMB:N0} MB"); System.Console.WriteLine($"Private Memory: {currentMetrics.PrivateMemoryMB:N0} MB"); System.Console.WriteLine($"Virtual Memory: {currentMetrics.VirtualMemoryMB:N0} MB"); System.Console.WriteLine($"Threads: {currentMetrics.ThreadCount}"); System.Console.WriteLine($"Handles: {currentMetrics.HandleCount}"); } else { System.Console.WriteLine($"No metrics available for VM '{vmName}'"); } break; case "history": var history = await vmService.GetPerformanceHistoryAsync(vmName); if (history.Any()) { System.Console.WriteLine($"=== Performance History for VM '{vmName}' ==="); System.Console.WriteLine($"{"Timestamp",-20} {"CPU %",-8} {"Memory MB",-12} {"Threads",-8}"); System.Console.WriteLine(new string('-', 50)); foreach (var metric in history.TakeLast(10)) { var timestamp = metric.Timestamp.ToString("HH:mm:ss"); System.Console.WriteLine($"{timestamp,-20} {metric.CpuUsagePercent,-8:F1} {metric.MemoryUsageMB,-12:N0} {metric.ThreadCount,-8}"); } } else { System.Console.WriteLine($"No history available for VM '{vmName}'"); } break; default: System.Console.WriteLine($"Unknown metrics type: {type}"); break; } } catch (Exception ex) { System.Console.WriteLine($"Error: {ex.Message}"); } } static async Task ImportVmAsync(VmManagementService vmService, string[] arguments) { if (arguments.Length == 0) { System.Console.WriteLine("Usage: import [new-vm-name]"); System.Console.WriteLine("Example: import examples/sample-vm-config.json my-imported-vm"); return; } var configPath = arguments[0]; var newName = arguments.Length > 1 ? arguments[1] : null; try { System.Console.WriteLine($"Importing VM configuration from: {configPath}"); var importedConfig = await vmService.ImportVmConfigurationAsync(configPath, newName); System.Console.WriteLine($"Successfully imported VM '{importedConfig.Name}'"); System.Console.WriteLine($"Description: {importedConfig.Description}"); System.Console.WriteLine($"CPU: {importedConfig.Cpu.Cores} cores"); System.Console.WriteLine($"Memory: {importedConfig.Memory.Size}{importedConfig.Memory.Unit}"); if (importedConfig.Storage.Disks.Any()) { System.Console.WriteLine("Disks:"); foreach (var disk in importedConfig.Storage.Disks) { System.Console.WriteLine($" - {disk.Path} ({disk.Size}GB, {disk.Format})"); } } } catch (FileNotFoundException) { System.Console.WriteLine($"Error: Configuration file '{configPath}' not found"); System.Console.WriteLine("Make sure the file path is correct and the file exists."); } catch (Exception ex) { System.Console.WriteLine($"Error importing VM: {ex.Message}"); } } static string GetUserInput(string prompt, string defaultValue = "") { System.Console.Write(prompt); var input = System.Console.ReadLine()?.Trim(); return string.IsNullOrEmpty(input) ? defaultValue : input; } static async Task HandleNetworkCommandsAsync(string[] arguments) { if (arguments.Length == 0) { System.Console.WriteLine("Network management commands:"); System.Console.WriteLine(" network bridges - List available bridges"); System.Console.WriteLine(" network interfaces - List network interfaces"); System.Console.WriteLine(" network create [interface] - Create a bridge"); System.Console.WriteLine(" network delete - Delete a bridge"); System.Console.WriteLine(" network config - Configure bridge IP"); System.Console.WriteLine(" network vm bridge - Configure VM for bridge networking"); System.Console.WriteLine(" network vm user - Configure VM for user networking"); return; } var networkManager = new NetworkManager(); var command = arguments[0].ToLower(); try { switch (command) { case "bridges": await ShowBridgesAsync(networkManager); break; case "interfaces": await ShowInterfacesAsync(networkManager); break; case "create": if (arguments.Length < 2) { System.Console.WriteLine("Usage: network create [interface-name]"); return; } await CreateBridgeAsync(networkManager, arguments[1], arguments.Length > 2 ? arguments[2] : null); break; case "delete": if (arguments.Length < 2) { System.Console.WriteLine("Usage: network delete "); return; } await DeleteBridgeAsync(networkManager, arguments[1]); break; case "config": if (arguments.Length < 4) { System.Console.WriteLine("Usage: network config "); System.Console.WriteLine("Example: network config virbr0 192.168.122.1 24"); return; } await ConfigureBridgeAsync(networkManager, arguments[1], arguments[2], arguments[3]); break; case "vm": if (arguments.Length < 3) { System.Console.WriteLine("Usage: network vm [bridge-name]"); return; } await ConfigureVmNetworkAsync(arguments[1], arguments[2], arguments.Length > 3 ? arguments[3] : null); break; default: System.Console.WriteLine($"Unknown network command: {command}"); System.Console.WriteLine("Type 'network' for available network commands"); break; } } catch (Exception ex) { System.Console.WriteLine($"Error: {ex.Message}"); } } static async Task ShowBridgesAsync(NetworkManager networkManager) { System.Console.WriteLine("=== Available Network Bridges ==="); var bridges = await networkManager.GetAvailableBridgesAsync(); if (bridges.Any()) { foreach (var bridge in bridges) { var ipAddress = await networkManager.GetBridgeIpAddressAsync(bridge); System.Console.WriteLine($" {bridge}: {ipAddress ?? "No IP configured"}"); } } else { System.Console.WriteLine("No bridges found"); System.Console.WriteLine("Use 'network create ' to create a bridge"); } } static async Task ShowInterfacesAsync(NetworkManager networkManager) { System.Console.WriteLine("=== Available Network Interfaces ==="); var interfaces = await networkManager.GetNetworkInterfacesAsync(); if (interfaces.Any()) { foreach (var iface in interfaces) { System.Console.WriteLine($" {iface}"); } } else { System.Console.WriteLine("No network interfaces found"); } } static async Task CreateBridgeAsync(NetworkManager networkManager, string bridgeName, string? interfaceName) { System.Console.WriteLine($"Creating bridge '{bridgeName}'..."); if (!string.IsNullOrEmpty(interfaceName)) { System.Console.WriteLine($"Adding interface '{interfaceName}' to bridge..."); } var success = await networkManager.CreateBridgeAsync(bridgeName, interfaceName); if (success) { System.Console.WriteLine($"✅ Bridge '{bridgeName}' created successfully"); if (!string.IsNullOrEmpty(interfaceName)) { System.Console.WriteLine($"✅ Interface '{interfaceName}' added to bridge"); } } else { System.Console.WriteLine($"❌ Failed to create bridge '{bridgeName}'"); System.Console.WriteLine("Note: Bridge creation may require root privileges"); } } static async Task DeleteBridgeAsync(NetworkManager networkManager, string bridgeName) { System.Console.WriteLine($"Deleting bridge '{bridgeName}'..."); var success = await networkManager.DeleteBridgeAsync(bridgeName); if (success) { System.Console.WriteLine($"✅ Bridge '{bridgeName}' deleted successfully"); } else { System.Console.WriteLine($"❌ Failed to delete bridge '{bridgeName}'"); System.Console.WriteLine("Note: Bridge deletion may require root privileges"); } } static async Task ConfigureBridgeAsync(NetworkManager networkManager, string bridgeName, string ipAddress, string netmask) { System.Console.WriteLine($"Configuring bridge '{bridgeName}' with IP {ipAddress}/{netmask}..."); var success = await networkManager.ConfigureBridgeAsync(bridgeName, ipAddress, netmask); if (success) { System.Console.WriteLine($"✅ Bridge '{bridgeName}' configured successfully"); } else { System.Console.WriteLine($"❌ Failed to configure bridge '{bridgeName}'"); System.Console.WriteLine("Note: Bridge configuration may require root privileges"); } } static async Task ConfigureVmNetworkAsync(string vmName, string networkType, string? bridgeName) { var vmService = new VmManagementService(); var config = vmService.GetVmConfiguration(vmName); if (config == null) { System.Console.WriteLine($"VM '{vmName}' not found"); return; } if (networkType == "bridge") { if (string.IsNullOrEmpty(bridgeName)) { System.Console.WriteLine("Bridge name required for bridge networking"); System.Console.WriteLine("Usage: network vm bridge "); return; } // Configure for bridge networking config.Network.Interfaces.Clear(); config.Network.Interfaces.Add(new NetworkInterfaceConfiguration { Type = "bridge", Model = "virtio-net-pci", Bridge = bridgeName }); System.Console.WriteLine($"✅ VM '{vmName}' configured for bridge networking on '{bridgeName}'"); } else if (networkType == "user") { // Configure for user networking (NAT) config.Network.Interfaces.Clear(); config.Network.Interfaces.Add(new NetworkInterfaceConfiguration { Type = "user", Model = "virtio-net-pci" }); System.Console.WriteLine($"✅ VM '{vmName}' configured for user networking (NAT)"); } else { System.Console.WriteLine($"Unknown network type: {networkType}"); System.Console.WriteLine("Supported types: bridge, user"); return; } // Save the updated configuration await vmService.UpdateVmConfigurationAsync(vmName, config); System.Console.WriteLine($"Configuration saved for VM '{vmName}'"); } static async Task HandlePortCommandsAsync(string[] arguments) { if (arguments.Length == 0) { System.Console.WriteLine("Port forwarding commands:"); System.Console.WriteLine(" port forward [protocol] - Forward host port to VM"); System.Console.WriteLine(" port list - List active port forwards"); System.Console.WriteLine(" port remove - Remove port forward"); System.Console.WriteLine(" port status - Show port forwarding status"); return; } var command = arguments[0].ToLower(); try { switch (command) { case "forward": if (arguments.Length < 4) { System.Console.WriteLine("Usage: port forward [protocol]"); System.Console.WriteLine("Example: port forward ubuntu-desktop 8080 80 tcp"); return; } await ForwardPortAsync(arguments[1], int.Parse(arguments[2]), int.Parse(arguments[3]), arguments.Length > 4 ? arguments[4] : "tcp"); break; case "list": if (arguments.Length < 2) { System.Console.WriteLine("Usage: port list "); return; } await ListPortForwardsAsync(arguments[1]); break; case "remove": if (arguments.Length < 3) { System.Console.WriteLine("Usage: port remove "); return; } await RemovePortForwardAsync(arguments[1], int.Parse(arguments[2])); break; case "status": if (arguments.Length < 2) { System.Console.WriteLine("Usage: port status "); return; } await ShowPortForwardStatusAsync(arguments[1]); break; default: System.Console.WriteLine($"Unknown port command: {command}"); System.Console.WriteLine("Type 'port' for available port commands"); break; } } catch (Exception ex) { System.Console.WriteLine($"Error: {ex.Message}"); } } static async Task ForwardPortAsync(string vmName, int hostPort, int vmPort, string protocol) { var vmService = new VmManagementService(); var config = vmService.GetVmConfiguration(vmName); if (config == null) { System.Console.WriteLine($"VM '{vmName}' not found"); return; } try { // Check if port is already in use if (IsPortInUse(hostPort)) { System.Console.WriteLine($"❌ Port {hostPort} is already in use on the host"); return; } // Create port forward entry var portForward = new QemuVmManager.Models.PortForward { VmName = vmName, HostPort = hostPort, VmPort = vmPort, Protocol = protocol.ToUpper(), Created = DateTime.UtcNow }; // Save port forward configuration await SavePortForwardAsync(portForward); System.Console.WriteLine($"✅ Port forward created: {hostPort}:{vmPort} ({protocol})"); System.Console.WriteLine($" Host: localhost:{hostPort} → VM: {vmName}:{vmPort}"); if (OperatingSystem.IsMacOS()) { System.Console.WriteLine($" Note: On macOS, VMs use socket networking on ports 10000+"); System.Console.WriteLine($" You may need to configure your application to listen on the socket port"); } } catch (Exception ex) { System.Console.WriteLine($"❌ Failed to create port forward: {ex.Message}"); } } static async Task ListPortForwardsAsync(string vmName) { var portForwards = await LoadPortForwardsAsync(); var vmForwards = portForwards.Where(pf => pf.VmName == vmName).ToList(); if (vmForwards.Any()) { System.Console.WriteLine($"=== Port Forwards for VM '{vmName}' ==="); System.Console.WriteLine($"{"Host Port",-12} {"VM Port",-8} {"Protocol",-8} {"Status",-10}"); System.Console.WriteLine(new string('-', 40)); foreach (var pf in vmForwards) { var status = IsPortInUse(pf.HostPort) ? "Active" : "Inactive"; System.Console.WriteLine($"{pf.HostPort,-12} {pf.VmPort,-8} {pf.Protocol,-8} {status,-10}"); } } else { System.Console.WriteLine($"No port forwards configured for VM '{vmName}'"); } } static async Task RemovePortForwardAsync(string vmName, int hostPort) { var portForwards = await LoadPortForwardsAsync(); var toRemove = portForwards.FirstOrDefault(pf => pf.VmName == vmName && pf.HostPort == hostPort); if (toRemove != null) { portForwards.Remove(toRemove); await SavePortForwardsAsync(portForwards); System.Console.WriteLine($"✅ Port forward {hostPort} removed for VM '{vmName}'"); } else { System.Console.WriteLine($"Port forward {hostPort} not found for VM '{vmName}'"); } } static async Task ShowPortForwardStatusAsync(string vmName) { var portForwards = await LoadPortForwardsAsync(); var vmForwards = portForwards.Where(pf => pf.VmName == vmName).ToList(); if (vmForwards.Any()) { System.Console.WriteLine($"=== Port Forward Status for VM '{vmName}' ==="); foreach (var pf in vmForwards) { var status = IsPortInUse(pf.HostPort) ? "✅ Active" : "❌ Inactive"; System.Console.WriteLine($"Port {pf.HostPort}:{pf.VmPort} ({pf.Protocol}) - {status}"); } } else { System.Console.WriteLine($"No port forwards configured for VM '{vmName}'"); } } static bool IsPortInUse(int port) { try { using var client = new System.Net.Sockets.TcpClient(); client.Connect("127.0.0.1", port); return true; } catch { return false; } } static async Task> LoadPortForwardsAsync() { var configFile = "port-forwards.json"; if (File.Exists(configFile)) { try { var json = await File.ReadAllTextAsync(configFile); return System.Text.Json.JsonSerializer.Deserialize>(json) ?? new List(); } catch { return new List(); } } return new List(); } static async Task SavePortForwardsAsync(List portForwards) { var configFile = "port-forwards.json"; var json = System.Text.Json.JsonSerializer.Serialize(portForwards, new System.Text.Json.JsonSerializerOptions { WriteIndented = true }); await File.WriteAllTextAsync(configFile, json); } static async Task SavePortForwardAsync(QemuVmManager.Models.PortForward portForward) { var portForwards = await LoadPortForwardsAsync(); portForwards.Add(portForward); await SavePortForwardsAsync(portForwards); } static async Task HandleConfigCommandsAsync(VmManagementService vmService, string[] arguments) { if (arguments.Length < 3) { System.Console.WriteLine("Usage: config "); System.Console.WriteLine("Settings:"); System.Console.WriteLine(" display [port] - Set display type (gtk, vnc, spice)"); System.Console.WriteLine(" vga - Set VGA type (std, virtio, qxl)"); System.Console.WriteLine(" memory - Set memory size in GB"); System.Console.WriteLine(" cpu - Set CPU cores"); System.Console.WriteLine("Examples:"); System.Console.WriteLine(" config ubuntu-desktop display vnc 5900"); System.Console.WriteLine(" config ubuntu-desktop display gtk"); System.Console.WriteLine(" config ubuntu-desktop vga std"); return; } var vmName = arguments[0]; var setting = arguments[1].ToLower(); var value = arguments[2]; var config = vmService.GetVmConfiguration(vmName); if (config == null) { System.Console.WriteLine($"VM '{vmName}' not found."); return; } try { switch (setting) { case "display": config.Display.Type = value; if (arguments.Length > 3 && value == "vnc") { config.Display.SpicePort = int.Parse(arguments[3]); } System.Console.WriteLine($"Display type set to '{value}' for VM '{vmName}'"); break; case "vga": config.Display.Vga = value; System.Console.WriteLine($"VGA type set to '{value}' for VM '{vmName}'"); break; case "memory": if (int.TryParse(value, out int memorySize)) { config.Memory.Size = memorySize; System.Console.WriteLine($"Memory set to {memorySize}GB for VM '{vmName}'"); } else { System.Console.WriteLine("Invalid memory size. Please specify a number."); } break; case "cpu": if (int.TryParse(value, out int cpuCores)) { config.Cpu.Cores = cpuCores; System.Console.WriteLine($"CPU cores set to {cpuCores} for VM '{vmName}'"); } else { System.Console.WriteLine("Invalid CPU cores. Please specify a number."); } break; default: System.Console.WriteLine($"Unknown setting '{setting}'"); break; } // Save the updated configuration await vmService.UpdateVmConfigurationAsync(vmName, config); System.Console.WriteLine($"Configuration updated successfully for VM '{vmName}'"); } catch (Exception ex) { System.Console.WriteLine($"Error updating configuration: {ex.Message}"); } } }