app.js 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. const API_BASE = window.location.origin;
  2. function getStateClass(state) {
  3. switch (state) {
  4. case 'running': return 'bg-success';
  5. case 'shut off': return 'bg-secondary';
  6. case 'paused': return 'bg-warning text-dark';
  7. case 'crashed': return 'bg-danger';
  8. default: return 'bg-light text-dark';
  9. }
  10. }
  11. async function loadIsos() {
  12. try {
  13. const response = await fetch(`${API_BASE}/isos`);
  14. const data = await response.json();
  15. const select = document.getElementById('iso');
  16. select.innerHTML = '<option value="">Select ISO</option>';
  17. data.isos.forEach(iso => {
  18. select.innerHTML += `<option value="${iso.path}">${iso.name}</option>`;
  19. });
  20. } catch (error) {
  21. console.error('Error loading ISOs:', error);
  22. }
  23. }
  24. async function loadVMs() {
  25. try {
  26. const response = await fetch(`${API_BASE}/vms`);
  27. const data = await response.json();
  28. const tbody = document.getElementById('vmTableBody');
  29. tbody.innerHTML = '';
  30. const select = document.getElementById('bootVM');
  31. select.innerHTML = '<option value="">Select VM</option>';
  32. data.vms.forEach(vm => {
  33. const row = document.createElement('tr');
  34. row.innerHTML = `
  35. <td>${vm.id}</td>
  36. <td>${vm.name}</td>
  37. <td><span class="badge ${getStateClass(vm.state)}">${vm.state}</span></td>
  38. <td>
  39. <button class="btn btn-sm btn-success" onclick="startVM('${vm.name}')">Lanzar</button>
  40. <button class="btn btn-sm btn-warning" onclick="stopVM('${vm.name}')">Stop</button>
  41. <button class="btn btn-sm btn-danger" onclick="deleteVM('${vm.name}')">Delete</button>
  42. ${vm.vnc_port ? `<button class="btn btn-sm btn-info" onclick="openVNC('${vm.name}')">Console</button>` : ''}
  43. </td>
  44. `;
  45. tbody.appendChild(row);
  46. select.innerHTML += `<option value="${vm.name}">${vm.name}</option>`;
  47. });
  48. loadIsos(); // Load ISOs after loading VMs
  49. } catch (error) {
  50. console.error('Error loading VMs:', error);
  51. alert('Error loading VMs');
  52. }
  53. }
  54. async function startVM(name) {
  55. try {
  56. await fetch(`${API_BASE}/vms/${name}/start`);
  57. loadVMs();
  58. } catch (error) {
  59. console.error('Error starting VM:', error);
  60. alert('Error starting VM');
  61. }
  62. }
  63. async function stopVM(name) {
  64. try {
  65. await fetch(`${API_BASE}/vms/${name}/stop`);
  66. loadVMs();
  67. } catch (error) {
  68. console.error('Error stopping VM:', error);
  69. alert('Error stopping VM');
  70. }
  71. }
  72. async function deleteVM(name) {
  73. if (confirm(`Delete VM ${name}?`)) {
  74. try {
  75. await fetch(`${API_BASE}/vms/${name}`, { method: 'DELETE' });
  76. loadVMs();
  77. } catch (error) {
  78. console.error('Error deleting VM:', error);
  79. alert('Error deleting VM');
  80. }
  81. }
  82. }
  83. function openVNC(vm_name) {
  84. fetch(`${API_BASE}/console/${vm_name}`)
  85. .then(response => response.json())
  86. .then(data => {
  87. if (data.url) {
  88. window.open(data.url);
  89. } else {
  90. alert(data.error || 'Error opening console');
  91. }
  92. })
  93. .catch(error => {
  94. console.error('Error:', error);
  95. alert('Error opening console');
  96. });
  97. }
  98. document.getElementById('createVMForm').addEventListener('submit', async (e) => {
  99. e.preventDefault();
  100. const name = document.getElementById('name').value;
  101. const memory = document.getElementById('memory').value;
  102. const disk_size = document.getElementById('disk_size').value;
  103. const iso = document.getElementById('iso').value;
  104. try {
  105. const response = await fetch(`${API_BASE}/vms?name=${name}&memory=${memory}&disk_size=${disk_size}&iso=${iso}`, {
  106. method: 'POST'
  107. });
  108. let result;
  109. try {
  110. result = await response.json();
  111. } catch {
  112. result = { error: 'Unknown error' };
  113. }
  114. if (response.ok) {
  115. alert(result.message);
  116. loadVMs();
  117. document.getElementById('createVMForm').reset();
  118. } else {
  119. alert(result.error || 'Error creating VM');
  120. }
  121. } catch (error) {
  122. console.error('Error creating VM:', error);
  123. alert('Error creating VM');
  124. }
  125. });
  126. document.getElementById('setBootOrderForm').addEventListener('submit', async (e) => {
  127. e.preventDefault();
  128. const vm_name = document.getElementById('bootVM').value;
  129. const boot_order_str = document.getElementById('bootOrder').value;
  130. const order = boot_order_str.split(',').map(s => s.trim());
  131. try {
  132. const response = await fetch(`${API_BASE}/vms/${vm_name}/boot-order`, {
  133. method: 'PUT',
  134. headers: {
  135. 'Content-Type': 'application/json'
  136. },
  137. body: JSON.stringify({ order: order })
  138. });
  139. const result = await response.json();
  140. if (response.ok) {
  141. alert(result.message);
  142. loadVMs();
  143. document.getElementById('setBootOrderForm').reset();
  144. } else {
  145. alert(result.error);
  146. }
  147. } catch (error) {
  148. console.error('Error setting boot order:', error);
  149. alert('Error setting boot order');
  150. }
  151. });
  152. document.getElementById('uploadIsoForm').addEventListener('submit', async (e) => {
  153. e.preventDefault();
  154. const fileInput = document.getElementById('isoFile');
  155. const file = fileInput.files[0];
  156. if (!file) {
  157. alert('Please select a file');
  158. return;
  159. }
  160. const formData = new FormData();
  161. formData.append('file', file);
  162. try {
  163. const response = await fetch(`${API_BASE}/upload-iso`, {
  164. method: 'POST',
  165. body: formData
  166. });
  167. const result = await response.json();
  168. if (response.ok) {
  169. alert(result.message);
  170. loadIsos(); // Refresh ISO list
  171. document.getElementById('uploadIsoForm').reset();
  172. } else {
  173. alert(result.error || 'Error uploading ISO');
  174. }
  175. } catch (error) {
  176. console.error('Error uploading ISO:', error);
  177. alert('Error uploading ISO');
  178. }
  179. });
  180. // Load VMs on page load
  181. loadVMs();