|
|
@@ -83,10 +83,11 @@ async function loadVMs() {
|
|
|
<td>${vm.name}</td>
|
|
|
<td><span class="badge ${getStateClass(vm.state)}">${vm.state}</span></td>
|
|
|
<td>
|
|
|
+ <button class="btn btn-sm btn-info" onclick="showVMInfo('${vm.name}')">Info</button>
|
|
|
<button class="btn btn-sm btn-success" onclick="startVM('${vm.name}')">Lanzar</button>
|
|
|
<button class="btn btn-sm btn-warning" onclick="stopVM('${vm.name}')">Stop</button>
|
|
|
<button class="btn btn-sm btn-danger" onclick="deleteVM('${vm.name}')">Delete</button>
|
|
|
- ${vm.vnc_port ? `<button class="btn btn-sm btn-info" onclick="openVNC('${vm.name}')">Console</button>` : ''}
|
|
|
+ ${vm.vnc_port ? `<button class="btn btn-sm btn-primary" onclick="openVNC('${vm.name}')">Console</button>` : ''}
|
|
|
</td>
|
|
|
`;
|
|
|
tbody.appendChild(row);
|
|
|
@@ -101,6 +102,100 @@ async function loadVMs() {
|
|
|
|
|
|
|
|
|
|
|
|
+async function showVMInfo(name) {
|
|
|
+ try {
|
|
|
+ const response = await fetch(`${API_BASE}/vms/${name}/info`);
|
|
|
+ const data = await response.json();
|
|
|
+
|
|
|
+ if (!response.ok) {
|
|
|
+ alert(data.error || 'Error loading VM information');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ const modalBody = document.getElementById('infoModalBody');
|
|
|
+ modalBody.innerHTML = `
|
|
|
+ <div class="row mb-3">
|
|
|
+ <div class="col-md-6">
|
|
|
+ <h6><strong>Nombre:</strong></h6>
|
|
|
+ <p>${data.name}</p>
|
|
|
+ </div>
|
|
|
+ <div class="col-md-6">
|
|
|
+ <h6><strong>ID:</strong></h6>
|
|
|
+ <p>${data.id}</p>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="row mb-3">
|
|
|
+ <div class="col-md-6">
|
|
|
+ <h6><strong>Estado:</strong></h6>
|
|
|
+ <p><span class="badge ${getStateClass(data.state)}">${data.state}</span></p>
|
|
|
+ </div>
|
|
|
+ <div class="col-md-6">
|
|
|
+ <h6><strong>Memoria:</strong></h6>
|
|
|
+ <p>${data.memory} MiB</p>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="row mb-3">
|
|
|
+ <div class="col-md-6">
|
|
|
+ <h6><strong>CPUs:</strong></h6>
|
|
|
+ <p>${data.cpus}</p>
|
|
|
+ </div>
|
|
|
+ <div class="col-md-6">
|
|
|
+ <h6><strong>Puerto VNC:</strong></h6>
|
|
|
+ <p>${data.vnc_port || 'No asignado'}</p>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="mb-3">
|
|
|
+ <h6><strong>Discos:</strong></h6>
|
|
|
+ <table class="table table-sm">
|
|
|
+ <thead>
|
|
|
+ <tr>
|
|
|
+ <th>Dispositivo</th>
|
|
|
+ <th>Tipo</th>
|
|
|
+ <th>Ruta</th>
|
|
|
+ </tr>
|
|
|
+ </thead>
|
|
|
+ <tbody>
|
|
|
+ ${data.disks.map(disk => `
|
|
|
+ <tr>
|
|
|
+ <td>${disk.target}</td>
|
|
|
+ <td>${disk.type}</td>
|
|
|
+ <td>${disk.source}</td>
|
|
|
+ </tr>
|
|
|
+ `).join('')}
|
|
|
+ </tbody>
|
|
|
+ </table>
|
|
|
+ </div>
|
|
|
+ <div class="mb-3">
|
|
|
+ <h6><strong>Interfaces de Red:</strong></h6>
|
|
|
+ <table class="table table-sm">
|
|
|
+ <thead>
|
|
|
+ <tr>
|
|
|
+ <th>MAC</th>
|
|
|
+ <th>Red</th>
|
|
|
+ <th>Modelo</th>
|
|
|
+ </tr>
|
|
|
+ </thead>
|
|
|
+ <tbody>
|
|
|
+ ${data.interfaces.map(iface => `
|
|
|
+ <tr>
|
|
|
+ <td>${iface.mac}</td>
|
|
|
+ <td>${iface.network}</td>
|
|
|
+ <td>${iface.model}</td>
|
|
|
+ </tr>
|
|
|
+ `).join('')}
|
|
|
+ </tbody>
|
|
|
+ </table>
|
|
|
+ </div>
|
|
|
+ `;
|
|
|
+
|
|
|
+ const modal = new bootstrap.Modal(document.getElementById('infoModal'));
|
|
|
+ modal.show();
|
|
|
+ } catch (error) {
|
|
|
+ console.error('Error loading VM information:', error);
|
|
|
+ alert('Error loading VM information');
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
async function startVM(name) {
|
|
|
try {
|
|
|
await fetch(`${API_BASE}/vms/${name}/start`);
|