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();