fix formatting
This commit is contained in:
parent
6a00a22dc2
commit
5bbf928b2b
@ -1,5 +1,5 @@
|
|||||||
import {requestPVE, requestAPI, goToPage, getURIData, resources_config, setTitleAndHeader} from "./utils.js";
|
import { requestPVE, requestAPI, goToPage, getURIData, resources_config, setTitleAndHeader } from "./utils.js";
|
||||||
import {alert, dialog} from "./dialog.js";
|
import { alert, dialog } from "./dialog.js";
|
||||||
|
|
||||||
window.addEventListener("DOMContentLoaded", init); // do the dumb thing where the disk config refreshes every second
|
window.addEventListener("DOMContentLoaded", init); // do the dumb thing where the disk config refreshes every second
|
||||||
|
|
||||||
@ -11,13 +11,13 @@ let type;
|
|||||||
let vmid;
|
let vmid;
|
||||||
let config;
|
let config;
|
||||||
|
|
||||||
async function init () {
|
async function init() {
|
||||||
setTitleAndHeader();
|
setTitleAndHeader();
|
||||||
let cookie = document.cookie;
|
let cookie = document.cookie;
|
||||||
if (cookie === "") {
|
if (cookie === "") {
|
||||||
goToPage("login.html");
|
goToPage("login.html");
|
||||||
}
|
}
|
||||||
|
|
||||||
let uriData = getURIData();
|
let uriData = getURIData();
|
||||||
node = uriData.node;
|
node = uriData.node;
|
||||||
type = uriData.type;
|
type = uriData.type;
|
||||||
@ -32,27 +32,27 @@ async function init () {
|
|||||||
document.querySelector("#exit").addEventListener("click", handleFormExit);
|
document.querySelector("#exit").addEventListener("click", handleFormExit);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getOrdered(keys){
|
function getOrdered(keys) {
|
||||||
let ordered_keys = Object.keys(keys).sort((a,b) => {parseInt(a) - parseInt(b)}); // ordered integer list
|
let ordered_keys = Object.keys(keys).sort((a, b) => { parseInt(a) - parseInt(b) }); // ordered integer list
|
||||||
return ordered_keys;
|
return ordered_keys;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getConfig () {
|
async function getConfig() {
|
||||||
config = await requestPVE(`/nodes/${node}/${type}/${vmid}/config`, "GET");
|
config = await requestPVE(`/nodes/${node}/${type}/${vmid}/config`, "GET");
|
||||||
}
|
}
|
||||||
|
|
||||||
function populateResources () {
|
function populateResources() {
|
||||||
let name = type === "qemu" ? "name" : "hostname";
|
let name = type === "qemu" ? "name" : "hostname";
|
||||||
document.querySelector("#name").innerHTML = document.querySelector("#name").innerHTML.replace("%{vmname}", config.data[name]);
|
document.querySelector("#name").innerHTML = document.querySelector("#name").innerHTML.replace("%{vmname}", config.data[name]);
|
||||||
addResourceLine("resources", "images/resources/cpu.svg", "Cores", {type: "number", value: config.data.cores, min: 1, max: 8192}, "Threads");
|
addResourceLine("resources", "images/resources/cpu.svg", "Cores", { type: "number", value: config.data.cores, min: 1, max: 8192 }, "Threads");
|
||||||
addResourceLine("resources", "images/resources/ram.svg", "Memory", {type: "number", value: config.data.memory, min: 16, step: 1}, "MiB");
|
addResourceLine("resources", "images/resources/ram.svg", "Memory", { type: "number", value: config.data.memory, min: 16, step: 1 }, "MiB");
|
||||||
|
|
||||||
if (type === "lxc") {
|
if (type === "lxc") {
|
||||||
addResourceLine("resources", "images/resources/swap.svg", "Swap", {type: "number", value: config.data.swap, min: 0, step: 1}, "MiB");
|
addResourceLine("resources", "images/resources/swap.svg", "Swap", { type: "number", value: config.data.swap, min: 0, step: 1 }, "MiB");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function addResourceLine (fieldset, iconHref, labelText, inputAttr, unitText=null) {
|
function addResourceLine(fieldset, iconHref, labelText, inputAttr, unitText = null) {
|
||||||
let field = document.querySelector(`#${fieldset}`);
|
let field = document.querySelector(`#${fieldset}`);
|
||||||
|
|
||||||
let icon = document.createElement("img");
|
let icon = document.createElement("img");
|
||||||
@ -83,9 +83,9 @@ function addResourceLine (fieldset, iconHref, labelText, inputAttr, unitText=nul
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function populateDisk () {
|
function populateDisk() {
|
||||||
document.querySelector("#disks").innerHTML = "";
|
document.querySelector("#disks").innerHTML = "";
|
||||||
for(let i = 0; i < diskMetaData[type].prefixOrder.length; i++){
|
for (let i = 0; i < diskMetaData[type].prefixOrder.length; i++) {
|
||||||
let prefix = diskMetaData[type].prefixOrder[i];
|
let prefix = diskMetaData[type].prefixOrder[i];
|
||||||
let busName = diskMetaData[type][prefix].name;
|
let busName = diskMetaData[type][prefix].name;
|
||||||
let disks = {};
|
let disks = {};
|
||||||
@ -108,12 +108,12 @@ function populateDisk () {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function addDiskLine (fieldset, busPrefix, busName, device, diskDetails) {
|
function addDiskLine(fieldset, busPrefix, busName, device, diskDetails) {
|
||||||
let field = document.querySelector(`#${fieldset}`);
|
let field = document.querySelector(`#${fieldset}`);
|
||||||
|
|
||||||
let diskName = `${busName} ${device}`;
|
let diskName = `${busName} ${device}`;
|
||||||
let diskID = `${busPrefix}${device}`;
|
let diskID = `${busPrefix}${device}`;
|
||||||
|
|
||||||
// Set the disk icon, either drive.svg or disk.svg
|
// Set the disk icon, either drive.svg or disk.svg
|
||||||
let icon = document.createElement("img");
|
let icon = document.createElement("img");
|
||||||
icon.src = diskMetaData[type][busPrefix].icon;
|
icon.src = diskMetaData[type][busPrefix].icon;
|
||||||
@ -138,12 +138,12 @@ function addDiskLine (fieldset, busPrefix, busName, device, diskDetails) {
|
|||||||
diskMetaData.actionBarOrder.forEach((element) => {
|
diskMetaData.actionBarOrder.forEach((element) => {
|
||||||
let action = document.createElement("img");
|
let action = document.createElement("img");
|
||||||
action.classList.add("clickable");
|
action.classList.add("clickable");
|
||||||
if (element === "detach_attach" && diskMetaData[type][busPrefix].actions.includes("attach")){ // attach
|
if (element === "detach_attach" && diskMetaData[type][busPrefix].actions.includes("attach")) { // attach
|
||||||
action.src = "images/actions/disk/attach.svg";
|
action.src = "images/actions/disk/attach.svg";
|
||||||
action.title = "Attach Disk";
|
action.title = "Attach Disk";
|
||||||
action.addEventListener("click", handleDiskAttach);
|
action.addEventListener("click", handleDiskAttach);
|
||||||
}
|
}
|
||||||
else if (element === "detach_attach" && diskMetaData[type][busPrefix].actions.includes("detach")){ // detach
|
else if (element === "detach_attach" && diskMetaData[type][busPrefix].actions.includes("detach")) { // detach
|
||||||
action.src = "images/actions/disk/detach.svg";
|
action.src = "images/actions/disk/detach.svg";
|
||||||
action.title = "Detach Disk";
|
action.title = "Detach Disk";
|
||||||
action.addEventListener("click", handleDiskDetach);
|
action.addEventListener("click", handleDiskDetach);
|
||||||
@ -154,7 +154,7 @@ function addDiskLine (fieldset, busPrefix, busName, device, diskDetails) {
|
|||||||
action.title = "Delete Disk";
|
action.title = "Delete Disk";
|
||||||
if (active === "active") {
|
if (active === "active") {
|
||||||
action.addEventListener("click", handleDiskDelete);
|
action.addEventListener("click", handleDiskDelete);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
let active = diskMetaData[type][busPrefix].actions.includes(element) ? "active" : "inactive"; // resize
|
let active = diskMetaData[type][busPrefix].actions.includes(element) ? "active" : "inactive"; // resize
|
||||||
@ -176,7 +176,7 @@ function addDiskLine (fieldset, busPrefix, busName, device, diskDetails) {
|
|||||||
field.append(actionDiv);
|
field.append(actionDiv);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleDiskDetach () {
|
async function handleDiskDetach() {
|
||||||
let header = `Detach ${this.dataset.disk}`;
|
let header = `Detach ${this.dataset.disk}`;
|
||||||
let body = `<p>Are you sure you want to detach disk</p><p>${this.dataset.disk}</p>`;
|
let body = `<p>Are you sure you want to detach disk</p><p>${this.dataset.disk}</p>`;
|
||||||
dialog(header, body, async (result, form) => {
|
dialog(header, body, async (result, form) => {
|
||||||
@ -202,7 +202,7 @@ async function handleDiskDetach () {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleDiskAttach () {
|
async function handleDiskAttach() {
|
||||||
let diskImage = config.data[this.dataset.disk];
|
let diskImage = config.data[this.dataset.disk];
|
||||||
|
|
||||||
let header = `Attach ${diskImage}`;
|
let header = `Attach ${diskImage}`;
|
||||||
@ -211,7 +211,7 @@ async function handleDiskAttach () {
|
|||||||
dialog(header, body, async (result, form) => {
|
dialog(header, body, async (result, form) => {
|
||||||
if (result === "confirm") {
|
if (result === "confirm") {
|
||||||
let device = form.get("device");
|
let device = form.get("device");
|
||||||
document.querySelector(`img[data-disk="${this.dataset.disk}"]`).src = "images/status/loading.svg";
|
document.querySelector(`img[data-disk="${this.dataset.disk}"]`).src = "images/status/loading.svg";
|
||||||
let body = {
|
let body = {
|
||||||
node: node,
|
node: node,
|
||||||
type: type,
|
type: type,
|
||||||
@ -233,8 +233,8 @@ async function handleDiskAttach () {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleDiskResize () {
|
async function handleDiskResize() {
|
||||||
let header = `Resize ${this.dataset.disk}`;
|
let header = `Resize ${this.dataset.disk}`;
|
||||||
let body = `<label for="size-increment">Size Increment (GiB)</label><input class="w3-input w3-border" name="size-increment" id="size-increment" type="number" min="0" max="131072"></input>`;
|
let body = `<label for="size-increment">Size Increment (GiB)</label><input class="w3-input w3-border" name="size-increment" id="size-increment" type="number" min="0" max="131072"></input>`;
|
||||||
|
|
||||||
dialog(header, body, async (result, form) => {
|
dialog(header, body, async (result, form) => {
|
||||||
@ -252,7 +252,7 @@ async function handleDiskResize () {
|
|||||||
await getConfig();
|
await getConfig();
|
||||||
populateDisk();
|
populateDisk();
|
||||||
}
|
}
|
||||||
else{
|
else {
|
||||||
alert(result.error);
|
alert(result.error);
|
||||||
await getConfig();
|
await getConfig();
|
||||||
populateDisk();
|
populateDisk();
|
||||||
@ -261,7 +261,7 @@ async function handleDiskResize () {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleDiskMove () {
|
async function handleDiskMove() {
|
||||||
let content = type === "qemu" ? "images" : "rootdir";
|
let content = type === "qemu" ? "images" : "rootdir";
|
||||||
let storage = await requestPVE(`/nodes/${node}/storage`, "GET");
|
let storage = await requestPVE(`/nodes/${node}/storage`, "GET");
|
||||||
|
|
||||||
@ -269,7 +269,7 @@ async function handleDiskMove () {
|
|||||||
|
|
||||||
let options = "";
|
let options = "";
|
||||||
storage.data.forEach((element) => {
|
storage.data.forEach((element) => {
|
||||||
if (element.content.includes(content)){
|
if (element.content.includes(content)) {
|
||||||
options += `<option value="${element.storage}">${element.storage}</option>"`;
|
options += `<option value="${element.storage}">${element.storage}</option>"`;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -289,7 +289,7 @@ async function handleDiskMove () {
|
|||||||
vmid: vmid,
|
vmid: vmid,
|
||||||
disk: this.dataset.disk,
|
disk: this.dataset.disk,
|
||||||
storage: form.get("storage-select"),
|
storage: form.get("storage-select"),
|
||||||
delete: form.get("delete-check") === "on" ? "1": "0"
|
delete: form.get("delete-check") === "on" ? "1" : "0"
|
||||||
}
|
}
|
||||||
let result = await requestAPI("/instance/disk/move", "POST", body);
|
let result = await requestAPI("/instance/disk/move", "POST", body);
|
||||||
if (result.status === 200) {
|
if (result.status === 200) {
|
||||||
@ -305,7 +305,7 @@ async function handleDiskMove () {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleDiskDelete () {
|
async function handleDiskDelete() {
|
||||||
let header = `Delete ${this.dataset.disk}`;
|
let header = `Delete ${this.dataset.disk}`;
|
||||||
let body = `<p>Are you sure you want to <strong>delete</strong> disk</p><p>${this.dataset.disk}</p>`;
|
let body = `<p>Are you sure you want to <strong>delete</strong> disk</p><p>${this.dataset.disk}</p>`;
|
||||||
|
|
||||||
@ -332,15 +332,15 @@ async function handleDiskDelete () {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleDiskAdd () {
|
async function handleDiskAdd() {
|
||||||
let content = type === "qemu" ? "images" : "rootdir";
|
let content = type === "qemu" ? "images" : "rootdir";
|
||||||
let storage = await requestPVE(`/nodes/${node}/storage`, "GET");
|
let storage = await requestPVE(`/nodes/${node}/storage`, "GET");
|
||||||
|
|
||||||
let header = "Create New Disk";
|
let header = "Create New Disk";
|
||||||
|
|
||||||
let options = "";
|
let options = "";
|
||||||
storage.data.forEach((element) => {
|
storage.data.forEach((element) => {
|
||||||
if (element.content.includes(content)){
|
if (element.content.includes(content)) {
|
||||||
options += `<option value="${element.storage}">${element.storage}</option>"`;
|
options += `<option value="${element.storage}">${element.storage}</option>"`;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -376,15 +376,15 @@ async function handleDiskAdd () {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleCDAdd () {
|
async function handleCDAdd() {
|
||||||
let content = "iso";
|
let content = "iso";
|
||||||
let storage = await requestPVE(`/nodes/${node}/storage`, "GET");
|
let storage = await requestPVE(`/nodes/${node}/storage`, "GET");
|
||||||
|
|
||||||
let header = `Add a CDROM`;
|
let header = `Add a CDROM`;
|
||||||
|
|
||||||
let storageOptions = "";
|
let storageOptions = "";
|
||||||
storage.data.forEach((element) => {
|
storage.data.forEach((element) => {
|
||||||
if (element.content.includes(content)){
|
if (element.content.includes(content)) {
|
||||||
storageOptions += `<option value="${element.storage}">${element.storage}</option>"`;
|
storageOptions += `<option value="${element.storage}">${element.storage}</option>"`;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -422,7 +422,7 @@ async function handleCDAdd () {
|
|||||||
let storage = document.querySelector("#storage-select").value;
|
let storage = document.querySelector("#storage-select").value;
|
||||||
let ISOSelect = document.querySelector("#iso-select");
|
let ISOSelect = document.querySelector("#iso-select");
|
||||||
ISOSelect.innerHTML = `<option hidden disabled selected value></option>`;
|
ISOSelect.innerHTML = `<option hidden disabled selected value></option>`;
|
||||||
let isos = await requestPVE(`/nodes/${node}/storage/${storage}/content`, "GET", {content: content});
|
let isos = await requestPVE(`/nodes/${node}/storage/${storage}/content`, "GET", { content: content });
|
||||||
isos.data.forEach((element) => {
|
isos.data.forEach((element) => {
|
||||||
if (element.content.includes(content)) {
|
if (element.content.includes(content)) {
|
||||||
ISOSelect.append(new Option(element.volid.replace(`${storage}:${content}/`, ""), element.volid));
|
ISOSelect.append(new Option(element.volid.replace(`${storage}:${content}/`, ""), element.volid));
|
||||||
@ -431,7 +431,7 @@ async function handleCDAdd () {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function populateNetworks () {
|
function populateNetworks() {
|
||||||
document.querySelector("#networks").innerHTML = "";
|
document.querySelector("#networks").innerHTML = "";
|
||||||
let networks = {};
|
let networks = {};
|
||||||
let prefix = networkMetaData.prefix;
|
let prefix = networkMetaData.prefix;
|
||||||
@ -446,7 +446,7 @@ function populateNetworks () {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function addNetworkLine (fieldset, prefix, netID, netDetails) {
|
function addNetworkLine(fieldset, prefix, netID, netDetails) {
|
||||||
let field = document.querySelector(`#${fieldset}`);
|
let field = document.querySelector(`#${fieldset}`);
|
||||||
|
|
||||||
let icon = document.createElement("img");
|
let icon = document.createElement("img");
|
||||||
@ -481,12 +481,12 @@ function addNetworkLine (fieldset, prefix, netID, netDetails) {
|
|||||||
field.append(actionDiv);
|
field.append(actionDiv);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleNetworkConfig () {
|
async function handleNetworkConfig() {
|
||||||
let netID = this.dataset.network;
|
let netID = this.dataset.network;
|
||||||
let netDetails = this.dataset.netvals;
|
let netDetails = this.dataset.netvals;
|
||||||
let header = `Edit ${netID}`;
|
let header = `Edit ${netID}`;
|
||||||
let body = `<label for="rate">Rate Limit (MB/s)</label><input type="number" id="rate" name="rate" class="w3-input w3-border">`;
|
let body = `<label for="rate">Rate Limit (MB/s)</label><input type="number" id="rate" name="rate" class="w3-input w3-border">`;
|
||||||
|
|
||||||
let d = dialog(header, body, async (result, form) => {
|
let d = dialog(header, body, async (result, form) => {
|
||||||
if (result === "confirm") {
|
if (result === "confirm") {
|
||||||
document.querySelector(`img[data-network="${netID}"]`).src = "images/status/loading.svg";
|
document.querySelector(`img[data-network="${netID}"]`).src = "images/status/loading.svg";
|
||||||
@ -502,7 +502,7 @@ async function handleNetworkConfig () {
|
|||||||
await getConfig();
|
await getConfig();
|
||||||
populateNetworks();
|
populateNetworks();
|
||||||
}
|
}
|
||||||
else{
|
else {
|
||||||
alert(result.error);
|
alert(result.error);
|
||||||
await getConfig();
|
await getConfig();
|
||||||
populateNetworks();
|
populateNetworks();
|
||||||
@ -513,7 +513,7 @@ async function handleNetworkConfig () {
|
|||||||
d.querySelector("#rate").value = netDetails.split("rate=")[1].split(",")[0];
|
d.querySelector("#rate").value = netDetails.split("rate=")[1].split(",")[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleFormExit () {
|
async function handleFormExit() {
|
||||||
let body = {
|
let body = {
|
||||||
node: node,
|
node: node,
|
||||||
type: type,
|
type: type,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
export function dialog (header, body, callback = async (result, form) => {}) {
|
export function dialog(header, body, callback = async (result, form) => { }) {
|
||||||
let dialog = document.createElement("dialog");
|
let dialog = document.createElement("dialog");
|
||||||
dialog.innerHTML = `
|
dialog.innerHTML = `
|
||||||
<p class="w3-large" id="prompt" style="text-align: center;"></p>
|
<p class="w3-large" id="prompt" style="text-align: center;"></p>
|
||||||
@ -23,7 +23,7 @@ export function dialog (header, body, callback = async (result, form) => {}) {
|
|||||||
return dialog;
|
return dialog;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function alert (message) {
|
export function alert(message) {
|
||||||
let dialog = document.createElement("dialog");
|
let dialog = document.createElement("dialog");
|
||||||
dialog.innerHTML = `
|
dialog.innerHTML = `
|
||||||
<form method="dialog">
|
<form method="dialog">
|
||||||
|
@ -1,23 +1,23 @@
|
|||||||
import {requestPVE, requestAPI, goToPage, goToURL, instances_config, nodes_config, setTitleAndHeader} from "./utils.js";
|
import { requestPVE, requestAPI, goToPage, goToURL, instances_config, nodes_config, setTitleAndHeader } from "./utils.js";
|
||||||
import {alert, dialog} from "./dialog.js";
|
import { alert, dialog } from "./dialog.js";
|
||||||
import {PVE} from "../vars.js"
|
import { PVE } from "../vars.js"
|
||||||
|
|
||||||
window.addEventListener("DOMContentLoaded", init);
|
window.addEventListener("DOMContentLoaded", init);
|
||||||
|
|
||||||
async function init () {
|
async function init() {
|
||||||
setTitleAndHeader();
|
setTitleAndHeader();
|
||||||
let cookie = document.cookie;
|
let cookie = document.cookie;
|
||||||
if (cookie === "") {
|
if (cookie === "") {
|
||||||
goToPage("login.html");
|
goToPage("login.html");
|
||||||
}
|
}
|
||||||
|
|
||||||
await populateInstances();
|
await populateInstances();
|
||||||
|
|
||||||
let addInstanceBtn = document.querySelector("#instance-add");
|
let addInstanceBtn = document.querySelector("#instance-add");
|
||||||
addInstanceBtn.addEventListener("click", handleInstanceAdd);
|
addInstanceBtn.addEventListener("click", handleInstanceAdd);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function populateInstances () {
|
async function populateInstances() {
|
||||||
let resources = await requestPVE("/cluster/resources", "GET");
|
let resources = await requestPVE("/cluster/resources", "GET");
|
||||||
let instanceContainer = document.getElementById("instance-container");
|
let instanceContainer = document.getElementById("instance-container");
|
||||||
let instances = [];
|
let instances = [];
|
||||||
@ -26,7 +26,7 @@ async function populateInstances () {
|
|||||||
if (element.type === "lxc" || element.type === "qemu") {
|
if (element.type === "lxc" || element.type === "qemu") {
|
||||||
let nodeName = element.node;
|
let nodeName = element.node;
|
||||||
let nodeStatus = resources.data.find(item => item.node === nodeName && item.type === "node").status;
|
let nodeStatus = resources.data.find(item => item.node === nodeName && item.type === "node").status;
|
||||||
element.node = {name: nodeName, status: nodeStatus};
|
element.node = { name: nodeName, status: nodeStatus };
|
||||||
instances.push(element);
|
instances.push(element);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -58,14 +58,14 @@ async function populateInstances () {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
for(let i = 0; i < instances.length; i++) {
|
for (let i = 0; i < instances.length; i++) {
|
||||||
let newInstance = new Instance();
|
let newInstance = new Instance();
|
||||||
newInstance.data = instances[i];
|
newInstance.data = instances[i];
|
||||||
instanceContainer.append(newInstance.shadowElement);
|
instanceContainer.append(newInstance.shadowElement);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleInstanceAdd () {
|
async function handleInstanceAdd() {
|
||||||
let header = "Create New Instance";
|
let header = "Create New Instance";
|
||||||
|
|
||||||
let body = `
|
let body = `
|
||||||
@ -130,7 +130,7 @@ async function handleInstanceAdd () {
|
|||||||
let typeSelect = d.querySelector("#type");
|
let typeSelect = d.querySelector("#type");
|
||||||
typeSelect.selectedIndex = -1;
|
typeSelect.selectedIndex = -1;
|
||||||
typeSelect.addEventListener("change", () => {
|
typeSelect.addEventListener("change", () => {
|
||||||
if(typeSelect.value === "qemu") {
|
if (typeSelect.value === "qemu") {
|
||||||
d.querySelectorAll(".container-specific").forEach((element) => {
|
d.querySelectorAll(".container-specific").forEach((element) => {
|
||||||
element.classList.add("none");
|
element.classList.add("none");
|
||||||
element.disabled = true;
|
element.disabled = true;
|
||||||
@ -198,7 +198,7 @@ async function handleInstanceAdd () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class Instance {
|
export class Instance {
|
||||||
constructor () {
|
constructor() {
|
||||||
let shadowRoot = document.createElement("div");
|
let shadowRoot = document.createElement("div");
|
||||||
shadowRoot.classList.add("w3-row");
|
shadowRoot.classList.add("w3-row");
|
||||||
|
|
||||||
@ -235,7 +235,7 @@ export class Instance {
|
|||||||
this.actionLock = false;
|
this.actionLock = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
set data (data) {
|
set data(data) {
|
||||||
if (data.status === "unknown") {
|
if (data.status === "unknown") {
|
||||||
data.status = "stopped";
|
data.status = "stopped";
|
||||||
}
|
}
|
||||||
@ -247,7 +247,7 @@ export class Instance {
|
|||||||
this.update();
|
this.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
update () {
|
update() {
|
||||||
let vmidParagraph = this.shadowElement.querySelector("#instance-id");
|
let vmidParagraph = this.shadowElement.querySelector("#instance-id");
|
||||||
vmidParagraph.innerText = this.vmid;
|
vmidParagraph.innerText = this.vmid;
|
||||||
|
|
||||||
@ -306,9 +306,9 @@ export class Instance {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async handlePowerButton () {
|
async handlePowerButton() {
|
||||||
|
|
||||||
if(!this.actionLock) {
|
if (!this.actionLock) {
|
||||||
let header = `${this.status === "running" ? "Stop" : "Start"} VM ${this.vmid}`;
|
let header = `${this.status === "running" ? "Stop" : "Start"} VM ${this.vmid}`;
|
||||||
let body = `<p>Are you sure you want to ${this.status === "running" ? "stop" : "start"} VM</p><p>${this.vmid}</p>`
|
let body = `<p>Are you sure you want to ${this.status === "running" ? "stop" : "start"} VM</p><p>${this.vmid}</p>`
|
||||||
|
|
||||||
@ -322,13 +322,13 @@ export class Instance {
|
|||||||
|
|
||||||
this.update();
|
this.update();
|
||||||
|
|
||||||
let result = await requestPVE(`/nodes/${this.node.name}/${this.type}/${this.vmid}/status/${targetAction}`, "POST", {node: this.node.name, vmid: this.vmid});
|
let result = await requestPVE(`/nodes/${this.node.name}/${this.type}/${this.vmid}/status/${targetAction}`, "POST", { node: this.node.name, vmid: this.vmid });
|
||||||
|
|
||||||
const waitFor = delay => new Promise(resolve => setTimeout(resolve, delay));
|
const waitFor = delay => new Promise(resolve => setTimeout(resolve, delay));
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
let taskStatus = await requestPVE(`/nodes/${this.node.name}/tasks/${result.data}/status`, "GET");
|
let taskStatus = await requestPVE(`/nodes/${this.node.name}/tasks/${result.data}/status`, "GET");
|
||||||
if(taskStatus.data.status === "stopped" && taskStatus.data.exitstatus === "OK") { // task stopped and was successful
|
if (taskStatus.data.status === "stopped" && taskStatus.data.exitstatus === "OK") { // task stopped and was successful
|
||||||
this.status = targetStatus;
|
this.status = targetStatus;
|
||||||
this.update();
|
this.update();
|
||||||
this.actionLock = false;
|
this.actionLock = false;
|
||||||
@ -341,7 +341,7 @@ export class Instance {
|
|||||||
this.actionLock = false;
|
this.actionLock = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else{ // task has not stopped
|
else { // task has not stopped
|
||||||
await waitFor(1000);
|
await waitFor(1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -350,21 +350,21 @@ export class Instance {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handleConfigButton () {
|
handleConfigButton() {
|
||||||
if (!this.actionLock && this.status === "stopped") { // if the action lock is false, and the node is stopped, then navigate to the conig page with the node infor in the search query
|
if (!this.actionLock && this.status === "stopped") { // if the action lock is false, and the node is stopped, then navigate to the conig page with the node infor in the search query
|
||||||
goToPage("config.html", {node: this.node.name, type: this.type, vmid: this.vmid});
|
goToPage("config.html", { node: this.node.name, type: this.type, vmid: this.vmid });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handleConsoleButton () {
|
handleConsoleButton() {
|
||||||
if (!this.actionLock && this.status === "running") {
|
if (!this.actionLock && this.status === "running") {
|
||||||
let data = {console: `${this.type === "qemu" ? "kvm" : "lxc"}`, vmid: this.vmid, vmname: this.name, node: this.node.name, resize: "off", cmd: ""};
|
let data = { console: `${this.type === "qemu" ? "kvm" : "lxc"}`, vmid: this.vmid, vmname: this.name, node: this.node.name, resize: "off", cmd: "" };
|
||||||
data[`${this.type === "qemu" ? "novnc" : "xtermjs"}`] = 1;
|
data[`${this.type === "qemu" ? "novnc" : "xtermjs"}`] = 1;
|
||||||
goToURL(PVE, data, true);
|
goToURL(PVE, data, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handleDeleteButton () {
|
handleDeleteButton() {
|
||||||
if (!this.actionLock && this.status === "stopped") {
|
if (!this.actionLock && this.status === "stopped") {
|
||||||
|
|
||||||
let header = `Delete VM ${this.vmid}`;
|
let header = `Delete VM ${this.vmid}`;
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import {requestTicket, goToPage, deleteAllCookies, requestPVE, setTitleAndHeader} from "./utils.js";
|
import { requestTicket, goToPage, deleteAllCookies, requestPVE, setTitleAndHeader } from "./utils.js";
|
||||||
import {alert} from "./dialog.js";
|
import { alert } from "./dialog.js";
|
||||||
|
|
||||||
window.addEventListener("DOMContentLoaded", init);
|
window.addEventListener("DOMContentLoaded", init);
|
||||||
|
|
||||||
async function init (){
|
async function init() {
|
||||||
setTitleAndHeader();
|
setTitleAndHeader();
|
||||||
await deleteAllCookies();
|
await deleteAllCookies();
|
||||||
let formSubmitButton = document.querySelector("#submit");
|
let formSubmitButton = document.querySelector("#submit");
|
||||||
@ -11,7 +11,7 @@ async function init (){
|
|||||||
let realmSelect = document.querySelector("#realm");
|
let realmSelect = document.querySelector("#realm");
|
||||||
realms.data.forEach((element) => {
|
realms.data.forEach((element) => {
|
||||||
realmSelect.add(new Option(element.comment, element.realm));
|
realmSelect.add(new Option(element.comment, element.realm));
|
||||||
if("default" in element && element.default === 1){
|
if ("default" in element && element.default === 1) {
|
||||||
realmSelect.value = element.realm;
|
realmSelect.value = element.realm;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -23,7 +23,7 @@ async function init (){
|
|||||||
formSubmitButton.innerText = "Authenticating...";
|
formSubmitButton.innerText = "Authenticating...";
|
||||||
let ticket = await requestTicket(formData.get("username"), formData.get("password"), formData.get("realm"));
|
let ticket = await requestTicket(formData.get("username"), formData.get("password"), formData.get("realm"));
|
||||||
if (ticket.status === 200) {
|
if (ticket.status === 200) {
|
||||||
formSubmitButton.innerText = "LOGIN";
|
formSubmitButton.innerText = "LOGIN";
|
||||||
goToPage("index.html");
|
goToPage("index.html");
|
||||||
}
|
}
|
||||||
else if (ticket.status === 401) {
|
else if (ticket.status === 401) {
|
||||||
|
@ -1,19 +1,19 @@
|
|||||||
import {API, organization} from "/vars.js";
|
import { API, organization } from "/vars.js";
|
||||||
|
|
||||||
export const resources_config = {
|
export const resources_config = {
|
||||||
disk: {
|
disk: {
|
||||||
actionBarOrder: ["move", "resize", "detach_attach", "delete"],
|
actionBarOrder: ["move", "resize", "detach_attach", "delete"],
|
||||||
lxc: {
|
lxc: {
|
||||||
prefixOrder: ["rootfs", "mp", "unused"],
|
prefixOrder: ["rootfs", "mp", "unused"],
|
||||||
rootfs: {name: "ROOTFS", icon: "images/resources/drive.svg", actions: ["move", "resize"]},
|
rootfs: { name: "ROOTFS", icon: "images/resources/drive.svg", actions: ["move", "resize"] },
|
||||||
mp: {name: "MP", icon: "images/resources/drive.svg", actions: ["detach", "move", "reassign", "resize"]},
|
mp: { name: "MP", icon: "images/resources/drive.svg", actions: ["detach", "move", "reassign", "resize"] },
|
||||||
unused: {name: "UNUSED", icon: "images/resources/drive.svg", actions: ["attach", "delete", "reassign"]}
|
unused: { name: "UNUSED", icon: "images/resources/drive.svg", actions: ["attach", "delete", "reassign"] }
|
||||||
},
|
},
|
||||||
qemu: {
|
qemu: {
|
||||||
prefixOrder: ["ide", "sata", "unused"],
|
prefixOrder: ["ide", "sata", "unused"],
|
||||||
ide: {name: "IDE", icon: "images/resources/disk.svg", actions: ["delete"]},
|
ide: { name: "IDE", icon: "images/resources/disk.svg", actions: ["delete"] },
|
||||||
sata: {name: "SATA", icon: "images/resources/drive.svg", actions: ["detach", "move", "reassign", "resize"]},
|
sata: { name: "SATA", icon: "images/resources/drive.svg", actions: ["detach", "move", "reassign", "resize"] },
|
||||||
unused: {name: "UNUSED", icon: "images/resources/drive.svg", actions: ["attach", "delete", "reassign"]}
|
unused: { name: "UNUSED", icon: "images/resources/drive.svg", actions: ["attach", "delete", "reassign"] }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
network: {
|
network: {
|
||||||
@ -79,7 +79,7 @@ export function getCookie(cname) {
|
|||||||
let name = cname + "=";
|
let name = cname + "=";
|
||||||
let decodedCookie = decodeURIComponent(document.cookie);
|
let decodedCookie = decodeURIComponent(document.cookie);
|
||||||
let ca = decodedCookie.split(";");
|
let ca = decodedCookie.split(";");
|
||||||
for(let i = 0; i < ca.length; i++) {
|
for (let i = 0; i < ca.length; i++) {
|
||||||
let c = ca[i];
|
let c = ca[i];
|
||||||
while (c.charAt(0) === " ") {
|
while (c.charAt(0) === " ") {
|
||||||
c = c.substring(1);
|
c = c.substring(1);
|
||||||
@ -91,12 +91,12 @@ export function getCookie(cname) {
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function requestTicket (username, password, realm) {
|
export async function requestTicket(username, password, realm) {
|
||||||
let response = await requestAPI("/ticket", "POST", {username: `${username}@${realm}`, password: password}, false);
|
let response = await requestAPI("/ticket", "POST", { username: `${username}@${realm}`, password: password }, false);
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function requestPVE (path, method, body = null) {
|
export async function requestPVE(path, method, body = null) {
|
||||||
let prms = new URLSearchParams(body);
|
let prms = new URLSearchParams(body);
|
||||||
let content = {
|
let content = {
|
||||||
method: method,
|
method: method,
|
||||||
@ -106,7 +106,7 @@ export async function requestPVE (path, method, body = null) {
|
|||||||
"Content-Type": "application/x-www-form-urlencoded"
|
"Content-Type": "application/x-www-form-urlencoded"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(method === "POST") {
|
if (method === "POST") {
|
||||||
content.body = prms.toString();
|
content.body = prms.toString();
|
||||||
content.headers.CSRFPreventionToken = getCookie("CSRFPreventionToken");
|
content.headers.CSRFPreventionToken = getCookie("CSRFPreventionToken");
|
||||||
}
|
}
|
||||||
@ -115,7 +115,7 @@ export async function requestPVE (path, method, body = null) {
|
|||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function requestAPI (path, method, body = null) {
|
export async function requestAPI(path, method, body = null) {
|
||||||
let prms = new URLSearchParams(body);
|
let prms = new URLSearchParams(body);
|
||||||
let content = {
|
let content = {
|
||||||
method: method,
|
method: method,
|
||||||
@ -136,7 +136,7 @@ export async function requestAPI (path, method, body = null) {
|
|||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function request (url, content) {
|
async function request(url, content) {
|
||||||
|
|
||||||
let response = await fetch(url, content);
|
let response = await fetch(url, content);
|
||||||
let data = null;
|
let data = null;
|
||||||
@ -148,8 +148,8 @@ async function request (url, content) {
|
|||||||
data = null;
|
data = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!response.ok){
|
if (!response.ok) {
|
||||||
return {status: response.status, error: data ? data.error : response.status};
|
return { status: response.status, error: data ? data.error : response.status };
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
data.status = response.status;
|
data.status = response.status;
|
||||||
@ -157,9 +157,9 @@ async function request (url, content) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function goToPage (page, data={}, newwindow = false) {
|
export function goToPage(page, data = {}, newwindow = false) {
|
||||||
let url = new URL(`https://${window.location.host}/${page}`);
|
let url = new URL(`https://${window.location.host}/${page}`);
|
||||||
for(let k in data) {
|
for (let k in data) {
|
||||||
url.searchParams.append(k, data[k]);
|
url.searchParams.append(k, data[k]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,9 +171,9 @@ export function goToPage (page, data={}, newwindow = false) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function goToURL (href, data={}, newwindow = false) {
|
export function goToURL(href, data = {}, newwindow = false) {
|
||||||
let url = new URL(href);
|
let url = new URL(href);
|
||||||
for(let k in data) {
|
for (let k in data) {
|
||||||
url.searchParams.append(k, data[k]);
|
url.searchParams.append(k, data[k]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -185,16 +185,16 @@ export function goToURL (href, data={}, newwindow = false) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getURIData () {
|
export function getURIData() {
|
||||||
let url = new URL(window.location.href);
|
let url = new URL(window.location.href);
|
||||||
return Object.fromEntries(url.searchParams);
|
return Object.fromEntries(url.searchParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function deleteAllCookies () {
|
export async function deleteAllCookies() {
|
||||||
await requestAPI("/ticket", "DELETE");
|
await requestAPI("/ticket", "DELETE");
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setTitleAndHeader () {
|
export function setTitleAndHeader() {
|
||||||
document.title = `${organization} - client`;
|
document.title = `${organization} - client`;
|
||||||
document.querySelector("h1").innerText = organization;
|
document.querySelector("h1").innerText = organization;
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user