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 "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(" 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; } }