const API_BASE = window.location.origin; function getStateClass(state) { switch (state) { case 'running': return 'bg-success'; case 'shut off': return 'bg-secondary'; case 'paused': return 'bg-warning text-dark'; case 'crashed': return 'bg-danger'; default: return 'bg-light text-dark'; } } async function loadISOs() { try { const response = await fetch(`${API_BASE}/isos`); const data = await response.json(); const tbody = document.getElementById('isoTableBody'); tbody.innerHTML = ''; data.isos.forEach(iso => { const row = document.createElement('tr'); row.innerHTML = ` ${iso.name} `; tbody.appendChild(row); }); } catch (error) { console.error('Error loading ISOs:', error); alert('Error loading ISOs'); } } async function deleteISO(name) { if (confirm(`Delete ISO ${name}?`)) { try { const response = await fetch(`${API_BASE}/isos/${name}`, { method: 'DELETE' }); const result = await response.json(); if (response.ok) { alert(result.message); loadISOs(); loadISOsForSelect(); // Refresh the select } else { alert(result.error); } } catch (error) { console.error('Error deleting ISO:', error); alert('Error deleting ISO'); } } } async function loadISOsForSelect() { try { const response = await fetch(`${API_BASE}/isos`); const data = await response.json(); const select = document.getElementById('iso'); select.innerHTML = ''; data.isos.forEach(iso => { select.innerHTML += ``; }); } catch (error) { console.error('Error loading ISOs:', error); } } /* Load VMs and populate the table */ async function loadVMs() { try { const response = await fetch(`${API_BASE}/vms`); const data = await response.json(); const tbody = document.getElementById('vmTableBody'); tbody.innerHTML = ''; const select = document.getElementById('bootVM'); select.innerHTML = ''; data.vms.forEach(vm => { const row = document.createElement('tr'); row.innerHTML = ` ${vm.id} ${vm.name} ${vm.state} ${vm.vnc_port ? `` : ''} `; tbody.appendChild(row); select.innerHTML += ``; }); loadISOsForSelect(); // Load ISOs after loading VMs } catch (error) { console.error('Error loading VMs:', error); alert('Error loading VMs'); } } async function startVM(name) { try { await fetch(`${API_BASE}/vms/${name}/start`); loadVMs(); } catch (error) { console.error('Error starting VM:', error); alert('Error starting VM'); } } async function stopVM(name) { try { await fetch(`${API_BASE}/vms/${name}/stop`); loadVMs(); } catch (error) { console.error('Error stopping VM:', error); alert('Error stopping VM'); } } async function deleteVM(name) { if (confirm(`Delete VM ${name}?`)) { try { await fetch(`${API_BASE}/vms/${name}`, { method: 'DELETE' }); loadVMs(); } catch (error) { console.error('Error deleting VM:', error); alert('Error deleting VM'); } } } function openVNC(vm_name) { fetch(`${API_BASE}/console/${vm_name}`) .then(response => response.json()) .then(data => { if (data.url) { window.open(data.url); } else { alert(data.error || 'Error opening console'); } }) .catch(error => { console.error('Error:', error); alert('Error opening console'); }); } document.getElementById('createVMForm').addEventListener('submit', async (e) => { e.preventDefault(); const name = document.getElementById('name').value; const memory = document.getElementById('memory').value; const disk_size = document.getElementById('disk_size').value; const cpus = document.getElementById('cpus').value; const iso = document.getElementById('iso').value; try { const response = await fetch(`${API_BASE}/vms?name=${name}&memory=${memory}&disk_size=${disk_size}&cpus=${cpus}&iso=${iso}`, { method: 'POST' }); let result; try { result = await response.json(); } catch { result = { error: 'Unknown error' }; } if (response.ok) { alert(result.message); loadVMs(); document.getElementById('createVMForm').reset(); } else { alert(result.error || 'Error creating VM'); } } catch (error) { console.error('Error creating VM:', error); alert('Error creating VM'); } }); document.getElementById('setBootOrderForm').addEventListener('submit', async (e) => { e.preventDefault(); const vm_name = document.getElementById('bootVM').value; const boot_order_str = document.getElementById('bootOrder').value; const order = boot_order_str.split(',').map(s => s.trim()); try { const response = await fetch(`${API_BASE}/vms/${vm_name}/boot-order`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ order: order }) }); const result = await response.json(); if (response.ok) { alert(result.message); loadVMs(); document.getElementById('setBootOrderForm').reset(); } else { alert(result.error); } } catch (error) { console.error('Error setting boot order:', error); alert('Error setting boot order'); } }); document.getElementById('uploadIsoForm').addEventListener('submit', (e) => { e.preventDefault(); const fileInput = document.getElementById('isoFile'); const file = fileInput.files[0]; if (!file) { alert('Please select a file'); return; } const formData = new FormData(); formData.append('file', file); const progressContainer = document.getElementById('progressContainer'); const progressBar = document.getElementById('uploadProgress'); const uploadBtn = document.getElementById('uploadBtn'); // Show progress bar progressContainer.style.display = 'block'; uploadBtn.disabled = true; progressBar.style.width = '0%'; progressBar.textContent = '0%'; const xhr = new XMLHttpRequest(); xhr.upload.addEventListener('progress', (e) => { if (e.lengthComputable) { const percentComplete = Math.round((e.loaded / e.total) * 100); progressBar.style.width = percentComplete + '%'; progressBar.textContent = percentComplete + '%'; } }); xhr.addEventListener('load', () => { if (xhr.status === 200) { const result = JSON.parse(xhr.responseText); alert(result.message); loadISOsForSelect(); document.getElementById('uploadIsoForm').reset(); progressContainer.style.display = 'none'; uploadBtn.disabled = false; } else { try { const result = JSON.parse(xhr.responseText); alert(result.error || 'Error uploading ISO'); } catch { alert('Error uploading ISO'); } progressContainer.style.display = 'none'; uploadBtn.disabled = false; } }); xhr.addEventListener('error', () => { alert('Error uploading ISO'); progressContainer.style.display = 'none'; uploadBtn.disabled = false; }); xhr.open('POST', `${API_BASE}/upload-iso`); xhr.send(formData); }); // Load VMs on page load loadVMs(); loadISOs();