update for new pool and node format
This commit is contained in:
parent
a6a76930f9
commit
29c36cdbf5
@ -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>
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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) => {
|
|
||||||
if (element.content.includes(content)) {
|
|
||||||
ISOSelect.append(new Option(element.volid.replace(`${storage}:${content}/`, ""), element.volid));
|
|
||||||
}
|
}
|
||||||
});
|
isoSelect.selectedIndex = -1;
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function populateNetworks () {
|
async function populateNetworks () {
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// set vmid min/max
|
||||||
d.querySelector("#vmid").min = userCluster.vmid.min;
|
d.querySelector("#vmid").min = userCluster.vmid.min;
|
||||||
d.querySelector("#vmid").max = userCluster.vmid.max;
|
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");
|
|
||||||
images.data.forEach((element) => {
|
|
||||||
if (element.content.includes(content)) {
|
|
||||||
templateImage.append(new Option(element.volid.replace(`${templateStorage.value}:${content}/`, ""), element.volid));
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
templateImage.selectedIndex = -1;
|
templateImage.selectedIndex = -1;
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user