Skip to content

Commit 32f466b

Browse files
committed
[PATCH-ENCE] -Added Send&Receive method and patch for peflight check
Signed-off-by: Iván Rodriguez <ivanrwcm25@gmail.com>
1 parent bb9d87e commit 32f466b

2 files changed

Lines changed: 107 additions & 23 deletions

File tree

ShpCore.Kernel/RemoteLinuxConnection/Remote_Linux_Connection.cs

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@ public class RemoteLinuxBridgeConnection : IBridgeConnection
1414
private readonly HttpClient _client = new HttpClient();
1515
private readonly string _serviceUrl;
1616

17-
public RemoteLinuxBridgeConnection(string url) => _serviceUrl = url ?? throw new ArgumentException("URL no puede ser nula");
18-
17+
public RemoteLinuxBridgeConnection(string url) => _serviceUrl = url;
18+
1919
public void Start() => KernelLog.Info($"[RemoteBridge] Conectado a {_serviceUrl}");
20-
20+
2121
public void Send(string command)
2222
{
2323
try
@@ -50,11 +50,39 @@ public void Send(string command)
5050
}
5151
}
5252

53+
public string SendAndReceive(string command)
54+
{
55+
try
56+
{
57+
var body = new { cmd = command };
58+
var json = JsonSerializer.Serialize(body);
59+
var content = new StringContent(json, Encoding.UTF8, "application/json");
60+
61+
var response = _client.PostAsync(_serviceUrl, content).GetAwaiter().GetResult();
62+
63+
if (!response.IsSuccessStatusCode)
64+
{
65+
var errorText = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
66+
KernelLog.Panic($"[RemoteBridge] Error remoto: {response.StatusCode} - {errorText}");
67+
return string.Empty;
68+
}
69+
70+
var result = response.Content.ReadFromJsonAsync<RemoteLinuxResult>().GetAwaiter().GetResult();
71+
return result?.Stdout?.Trim() ?? string.Empty;
72+
}
73+
catch (Exception ex)
74+
{
75+
KernelLog.Panic($"[RemoteBridge] Excepción ejecutando comando: {ex.Message}");
76+
return string.Empty;
77+
}
78+
}
79+
80+
5381
public async Task SendAsync(string command)
5482
{
5583
try
5684
{
57-
var content = new StringContent(command ,Encoding.UTF8, "application/json");
85+
var content = new StringContent(command, Encoding.UTF8, "application/json");
5886

5987
var response = await _client.PostAsync(_serviceUrl, content);
6088

ShpCore.Kernel/VM_subsystem/QemuConnection.cs

Lines changed: 75 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using ShpCore.Logging;
55
using System.Net.Sockets;
66
using System.Net;
7+
using System.Runtime.InteropServices;
78

89

910
namespace ShpCore.Kernel.VirtualMachineSubsystem;
@@ -35,7 +36,7 @@ public Task SendAsync(string path) // No lo voy a usar por ahora.
3536
);
3637
}
3738

38-
private void PreflightCheck() // Realiza chequeos previos antes de iniciar la VM
39+
private void PreflightCheck()
3940
{
4041
KernelLog.Warn("[Preflight] Iniciando healthcheck previos para QEMU");
4142

@@ -45,59 +46,89 @@ private void PreflightCheck() // Realiza chequeos previos antes de iniciar la VM
4546
throw new ArgumentNullException(nameof(_options));
4647
}
4748

48-
// 1. Validación de imagen
49-
if (!File.Exists(_options.ImagePath) || _options.ImagePath.Length == 0)
49+
// 1. Validar imagen
50+
if (string.IsNullOrWhiteSpace(_options.ImagePath) || !File.Exists(_options.ImagePath))
5051
{
5152
KernelLog.Panic($"[Preflight] Imagen no encontrada: {_options.ImagePath}");
5253
throw new FileNotFoundException("La imagen de disco no existe.", _options.ImagePath);
5354
}
5455

55-
// 2. Validación y creación del folder compartido
56-
if (!string.IsNullOrEmpty(_options.SharedFolder))
56+
// 2. Validar SharedFolder o asignar por defecto según OS
57+
if (string.IsNullOrWhiteSpace(_options.SharedFolder))
5758
{
58-
if (!Directory.Exists(_options.SharedFolder))
59+
var userDir = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
60+
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
5961
{
60-
Directory.CreateDirectory(_options.SharedFolder);
61-
KernelLog.Info($"[Preflight] Carpeta compartida creada: {_options.SharedFolder}");
62+
_options.SharedFolder = Path.Combine(userDir, "SharpCoreShare");
63+
}
64+
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
65+
{
66+
_options.SharedFolder = Path.Combine(userDir, "sharpcore-share-mac");
67+
}
68+
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
69+
{
70+
_options.SharedFolder = Path.Combine(userDir, "sharpcore-share");
6271
}
72+
73+
KernelLog.Warn($"[Preflight] Carpeta compartida no definida. Usando fallback: {_options.SharedFolder}");
6374
}
6475

76+
// 3. Sanitizar path para Windows
6577
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
6678
{
67-
opts.SharedFolder = "C:\\Users\\Public\\SharpCoreShare";
79+
_options.SharedFolder = _options.SharedFolder.Replace("\\", "/");
6880
}
69-
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
81+
82+
// 4. Crear carpeta si no existe
83+
try
7084
{
71-
opts.SharedFolder = "/home/tuusuario/sharpcore-share";
85+
if (!Directory.Exists(_options.SharedFolder))
86+
{
87+
Directory.CreateDirectory(_options.SharedFolder);
88+
KernelLog.Info($"[Preflight] Carpeta compartida creada: {_options.SharedFolder}");
89+
}
7290
}
73-
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
91+
catch (Exception ex)
7492
{
75-
opts.SharedFolder = "/Users/tuusuario/sharpcore-share";
93+
KernelLog.Panic($"[Preflight] Error al crear carpeta compartida: {ex.Message}");
94+
throw;
7695
}
7796

97+
// (sigue con validación de puerto, procesos zombie, etc.)
7898

79-
// 3. Validación de puerto libre
99+
100+
101+
// Asignación dinámica de puerto si es necesario
80102
if (_options.Port == 0)
81103
{
82104
_options.Port = FindFreePort();
83105
KernelLog.Info($"[Preflight] Puerto libre asignado dinámicamente: {_options.Port}");
84106
}
107+
else
108+
{
109+
KernelLog.Info($"[Preflight] Usando puerto especificado: {_options.Port}");
110+
}
85111

86-
// 4. Limpieza de procesos zombie de QEMU
112+
// Limpieza de QEMU si está usando la imagen específica
87113
var qemuProcs = Process.GetProcessesByName("qemu-system-x86_64");
88114
foreach (var proc in qemuProcs)
89115
{
90116
try
91117
{
92-
proc.Kill(true);
93-
proc.WaitForExit(1500); // Espera hasta 1.5 segundos para que el proceso termine
94-
KernelLog.Info($"[Preflight] Proceso QEMU colgado eliminado: PID {proc.Id}");
118+
if (proc.StartInfo.Arguments.Contains(_options.ImagePath))
119+
{
120+
proc.Kill(true);
121+
proc.WaitForExit(1500);
122+
KernelLog.Info($"[Preflight] Proceso QEMU colgado eliminado: PID {proc.Id}");
123+
}
95124
}
96125
catch
97126
{
98-
KernelLog.Info($"[Preflight] No hay procesos QEMU en paralelo, Preflight OK.");
127+
KernelLog.Warn($"[Preflight] No se pudo eliminar el proceso QEMU con PID {proc.Id}. Puede que ya haya finalizado.");
99128
}
100129
}
130+
131+
KernelLog.Info("[Preflight] Todos los chequeos pasaron correctamente. Ready to boot");
101132
}
102133

103134

@@ -232,6 +263,29 @@ private int FindFreePort(int startPort = 5000) // Busca un puerto libre a partir
232263
KernelLog.Panic("[QEMU] No se pudo encontrar un puerto libre para la VM");
233264
return -1;
234265
}
266+
267+
public bool IsHostshareMounted()
268+
{
269+
if (_options == null)
270+
{
271+
KernelLog.Panic("[MountCheck] Opciones de QEMU no definidas.");
272+
throw new ArgumentNullException(nameof(_options));
273+
}
274+
275+
var remote = new RemoteLinuxBridgeConnection($"http://127.0.0.1:{_options.Port}/exec");
276+
var result = remote.SendAndReceive("mount | grep /mnt/hostshare");
277+
278+
if (!string.IsNullOrWhiteSpace(result) && result.Contains("9p"))
279+
{
280+
KernelLog.Info("[MountCheck] Montaje de carpeta hostshare OK.");
281+
return true;
282+
}
283+
else
284+
{
285+
KernelLog.Warn("[MountCheck] Montaje no detectado en /mnt/hostshare.");
286+
return false;
287+
}
288+
}
235289
}
236290

237291

@@ -246,3 +300,5 @@ public class QemuOptions
246300
public int StartPort { get; set; } = 5000;
247301
public string SharedFolder { get; set; } = "/path/to/share"; // ¡Personalizable!
248302
}
303+
304+

0 commit comments

Comments
 (0)