update for new pool and node format

This commit is contained in:
Arthur Lu 2024-04-16 21:38:25 +00:00
parent a6a76930f9
commit 29c36cdbf5
4 changed files with 39 additions and 57 deletions

View File

@ -59,7 +59,7 @@
<div class="w3-card w3-padding"> <div class="w3-card w3-padding">
<h3>Account Details</h3> <h3>Account Details</h3>
<p id="username">Username:</p> <p id="username">Username:</p>
<p id="pool">Pool:</p> <p id="pool">Pools:</p>
<p id="vmid">VMID Range:</p> <p id="vmid">VMID Range:</p>
<p id="nodes">Nodes:</p> <p id="nodes">Nodes:</p>
</div> </div>

View File

@ -29,18 +29,16 @@ async function init () {
let resources = requestAPI("/user/dynamic/resources"); let resources = requestAPI("/user/dynamic/resources");
let meta = requestAPI("/global/config/resources"); let meta = requestAPI("/global/config/resources");
let instances = requestAPI("/user/config/cluster"); let userCluster = requestAPI("/user/config/cluster");
let nodes = requestAPI("/user/config/nodes");
resources = await resources; resources = await resources;
meta = await meta; meta = await meta;
instances = await instances; userCluster = await userCluster;
nodes = await nodes;
document.querySelector("#username").innerText = `Username: ${getCookie("username")}`; document.querySelector("#username").innerText = `Username: ${getCookie("username")}`;
document.querySelector("#pool").innerText = `Pool: ${instances.pool}`; document.querySelector("#pool").innerText = `Pools: ${Object.keys(userCluster.pools).toString()}`;
document.querySelector("#vmid").innerText = `VMID Range: ${instances.vmid.min} - ${instances.vmid.max}`; document.querySelector("#vmid").innerText = `VMID Range: ${userCluster.vmid.min} - ${userCluster.vmid.max}`;
document.querySelector("#nodes").innerText = `Nodes: ${nodes.toString()}`; document.querySelector("#nodes").innerText = `Nodes: ${Object.keys(userCluster.nodes).toString()}`;
populateResources("#resource-container", meta, resources); populateResources("#resource-container", meta, resources);

View File

@ -409,23 +409,13 @@ async function handleDiskAdd () {
} }
async function handleCDAdd () { async function handleCDAdd () {
const content = "iso"; const isos = await requestAPI("/user/vm-isos", "GET");
const storage = await requestPVE(`/nodes/${node}/storage`, "GET");
const header = "Add a CDROM"; const header = "Add a CDROM";
let storageOptions = "";
storage.data.forEach((element) => {
if (element.content.includes(content)) {
storageOptions += `<option value="${element.storage}">${element.storage}</option>"`;
}
});
const storageSelect = `<label for="storage-select">Storage</label><select class="w3-select w3-border" name="storage-select" id="storage-select" required><option hidden disabled selected value></option>${storageOptions}</select>`;
const body = ` const body = `
<form method="dialog" class="input-grid" style="grid-template-columns: auto 1fr;" id="form"> <form method="dialog" class="input-grid" style="grid-template-columns: auto 1fr;" id="form">
<label for="device">IDE</label><input class="w3-input w3-border" name="device" id="device" type="number" min="0" max="3" required></input> <label for="device">IDE</label><input class="w3-input w3-border" name="device" id="device" type="number" min="0" max="3" required></input>
${storageSelect}
<label for="iso-select">Image</label><select class="w3-select w3-border" name="iso-select" id="iso-select" required></select> <label for="iso-select">Image</label><select class="w3-select w3-border" name="iso-select" id="iso-select" required></select>
</form> </form>
`; `;
@ -446,17 +436,12 @@ async function handleCDAdd () {
} }
}); });
d.querySelector("#storage-select").addEventListener("change", async () => { const isoSelect = d.querySelector("#iso-select");
const storage = document.querySelector("#storage-select").value;
const ISOSelect = document.querySelector("#iso-select"); for (const iso of isos) {
ISOSelect.innerHTML = "<option hidden disabled selected value></option>"; isoSelect.append(new Option(iso.name, iso.volid))
const isos = await requestPVE(`/nodes/${node}/storage/${storage}/content`, "GET", { content }); }
isos.data.forEach((element) => { isoSelect.selectedIndex = -1;
if (element.content.includes(content)) {
ISOSelect.append(new Option(element.volid.replace(`${storage}:${content}/`, ""), element.volid));
}
});
});
} }
async function populateNetworks () { async function populateNetworks () {

View File

@ -90,6 +90,8 @@ async function handleInstanceAdd () {
<input class="w3-input w3-border" name="name" id="name" required></input> <input class="w3-input w3-border" name="name" id="name" required></input>
<label for="vmid">ID</label> <label for="vmid">ID</label>
<input class="w3-input w3-border" name="vmid" id="vmid" type="number" required></input> <input class="w3-input w3-border" name="vmid" id="vmid" type="number" required></input>
<label for="pool">Pool</label>
<select class="w3-select w3-border" name="pool" id="pool" required></select>
<label for="cores">Cores (Threads)</label> <label for="cores">Cores (Threads)</label>
<input class="w3-input w3-border" name="cores" id="cores" type="number" min="1" max="8192" required></input> <input class="w3-input w3-border" name="cores" id="cores" type="number" min="1" max="8192" required></input>
<label for="memory">Memory (MiB)</label> <label for="memory">Memory (MiB)</label>
@ -97,8 +99,6 @@ async function handleInstanceAdd () {
<p class="container-specific none" style="grid-column: 1 / span 2; text-align: center;">Container Options</p> <p class="container-specific none" style="grid-column: 1 / span 2; text-align: center;">Container Options</p>
<label class="container-specific none" for="swap">Swap (MiB)</label> <label class="container-specific none" for="swap">Swap (MiB)</label>
<input class="w3-input w3-border container-specific none" name="swap" id="swap" type="number" min="0" step="1" required disabled></input> <input class="w3-input w3-border container-specific none" name="swap" id="swap" type="number" min="0" step="1" required disabled></input>
<label class="container-specific none" for="template-storage">Template Storage</label>
<select class="w3-select w3-border container-specific none" name="template-storage" id="template-storage" required disabled></select>
<label class="container-specific none" for="template-image">Template Image</label> <label class="container-specific none" for="template-image">Template Image</label>
<select class="w3-select w3-border container-specific none" name="template-image" id="template-image" required disabled></select> <select class="w3-select w3-border container-specific none" name="template-image" id="template-image" required disabled></select>
<label class="container-specific none" for="rootfs-storage">ROOTFS Storage</label> <label class="container-specific none" for="rootfs-storage">ROOTFS Storage</label>
@ -110,12 +110,15 @@ async function handleInstanceAdd () {
</form> </form>
`; `;
const templates = await requestAPI("/user/ct-templates", "GET");
const d = dialog(header, body, async (result, form) => { const d = dialog(header, body, async (result, form) => {
if (result === "confirm") { if (result === "confirm") {
const body = { const body = {
name: form.get("name"), name: form.get("name"),
cores: form.get("cores"), cores: form.get("cores"),
memory: form.get("memory") memory: form.get("memory"),
pool: form.get("pool")
}; };
if (form.get("type") === "lxc") { if (form.get("type") === "lxc") {
body.swap = form.get("swap"); body.swap = form.get("swap");
@ -155,10 +158,6 @@ async function handleInstanceAdd () {
} }
}); });
const templateContent = "iso";
const templateStorage = d.querySelector("#template-storage");
templateStorage.selectedIndex = -1;
const rootfsContent = "rootdir"; const rootfsContent = "rootdir";
const rootfsStorage = d.querySelector("#rootfs-storage"); const rootfsStorage = d.querySelector("#rootfs-storage");
rootfsStorage.selectedIndex = -1; rootfsStorage.selectedIndex = -1;
@ -168,27 +167,24 @@ async function handleInstanceAdd () {
const nodeSelect = d.querySelector("#node"); const nodeSelect = d.querySelector("#node");
const clusterNodes = await requestPVE("/nodes", "GET"); const clusterNodes = await requestPVE("/nodes", "GET");
const allowedNodes = await requestAPI("/user/config/nodes", "GET"); const allowedNodes = Object.keys(userCluster.nodes)
clusterNodes.data.forEach((element) => { clusterNodes.data.forEach((element) => {
if (element.status === "online" && allowedNodes.includes(element.node)) { if (element.status === "online" && allowedNodes.includes(element.node)) {
nodeSelect.add(new Option(element.node)); nodeSelect.add(new Option(element.node));
} }
}); });
nodeSelect.selectedIndex = -1; nodeSelect.selectedIndex = -1;
nodeSelect.addEventListener("change", async () => { // change template and rootfs storage based on node nodeSelect.addEventListener("change", async () => { // change rootfs storage based on node
const node = nodeSelect.value; const node = nodeSelect.value;
const storage = await requestPVE(`/nodes/${node}/storage`, "GET"); const storage = await requestPVE(`/nodes/${node}/storage`, "GET");
storage.data.forEach((element) => { storage.data.forEach((element) => {
if (element.content.includes(templateContent)) {
templateStorage.add(new Option(element.storage));
}
if (element.content.includes(rootfsContent)) { if (element.content.includes(rootfsContent)) {
rootfsStorage.add(new Option(element.storage)); rootfsStorage.add(new Option(element.storage));
} }
}); });
templateStorage.selectedIndex = -1;
rootfsStorage.selectedIndex = -1; rootfsStorage.selectedIndex = -1;
// set core and memory min/max depending on node selected
if (node in userResources.cores.nodes) { if (node in userResources.cores.nodes) {
d.querySelector("#cores").max = userResources.cores.nodes[node].avail; d.querySelector("#cores").max = userResources.cores.nodes[node].avail;
} }
@ -202,21 +198,24 @@ async function handleInstanceAdd () {
else { else {
d.querySelector("#memory").max = userResources.memory.global.avail; d.querySelector("#memory").max = userResources.memory.global.avail;
} }
d.querySelector("#vmid").min = userCluster.vmid.min;
d.querySelector("#vmid").max = userCluster.vmid.max;
}); });
// set vmid min/max
d.querySelector("#vmid").min = userCluster.vmid.min;
d.querySelector("#vmid").max = userCluster.vmid.max;
// add user pools to selector
const poolSelect = d.querySelector("#pool");
const userPools = Object.keys(userCluster.pools);
userPools.forEach((element) => {
poolSelect.add(new Option(element));
});
poolSelect.selectedIndex = -1;
// add template images to selector
const templateImage = d.querySelector("#template-image"); // populate templateImage depending on selected image storage const templateImage = d.querySelector("#template-image"); // populate templateImage depending on selected image storage
templateStorage.addEventListener("change", async () => { for (const template of templates) {
templateImage.innerHTML = ""; templateImage.append(new Option(template.name, template.volid))
const content = "vztmpl"; }
const images = await requestPVE(`/nodes/${nodeSelect.value}/storage/${templateStorage.value}/content`, "GET"); templateImage.selectedIndex = -1;
images.data.forEach((element) => {
if (element.content.includes(content)) {
templateImage.append(new Option(element.volid.replace(`${templateStorage.value}:${content}/`, ""), element.volid));
}
});
templateImage.selectedIndex = -1;
});
} }