From e8aaa6d416c4afcb65161018e375133ae0cb8b12 Mon Sep 17 00:00:00 2001 From: "L. Bradley LaBoon" Date: Wed, 22 Jan 2020 21:01:47 -0500 Subject: [PATCH] Implemented plan upgrades --- img/lv-upgrade.png | Bin 0 -> 4010 bytes linodes/dashboard/dashboard.css | 12 ++ linodes/dashboard/dashboard.js | 18 +++ linodes/dashboard/index.shtml | 5 + linodes/mutate/index.shtml | 76 +++++++++ linodes/mutate/mutate.css | 78 +++++++++ linodes/mutate/mutate.js | 269 ++++++++++++++++++++++++++++++++ 7 files changed, 458 insertions(+) create mode 100644 img/lv-upgrade.png create mode 100644 linodes/mutate/index.shtml create mode 100644 linodes/mutate/mutate.css create mode 100644 linodes/mutate/mutate.js diff --git a/img/lv-upgrade.png b/img/lv-upgrade.png new file mode 100644 index 0000000000000000000000000000000000000000..60dc317a91eefc6da8271df3658c97e8ee17c06b GIT binary patch literal 4010 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.
+
+ upgrade +

A free upgrade is available for this Linode!

+

Click here for more information!

+
diff --git a/linodes/mutate/index.shtml b/linodes/mutate/index.shtml new file mode 100644 index 0000000..0e1627e --- /dev/null +++ b/linodes/mutate/index.shtml @@ -0,0 +1,76 @@ + + + + + + LMC - Pending Upgrades! + + + + + + + +
+ +
+
+ + + + + + + + + + + +
Pending upgrades!
+

This Linode has pending upgrades:

+ Resources affected: +
    +
  • RAM goes from GB → GB
  • +
  • Storage goes from GB → GB
  • +
  • vCPUs go from vCPUs → vCPUs
  • +
  • GPUs go from GPUs → GPUs
  • +
  • Outbound Mbits goes from Mbits → Mbits
  • +
  • Outbound transfer goes from MB → MB
  • +
+
+ +
+

How it works

+
    +
  1. Click button
  2. +
  3. Wait turn in upgrade queue
  4. +
  5. + Linode is shut down and its disk images are migrated
    + You will experience downtime while your Linode is migrated. It will take around to migrate your Linode, but that may vary based on host and network load. +
  6. +
  7. Linode upgraded and booted (if it was running)
  8. +
  9. + Enjoyment
    + After the migration completes, you can take advantage of the new resources by resizing your disk images. +
  10. +
+
+
+
+ + diff --git a/linodes/mutate/mutate.css b/linodes/mutate/mutate.css new file mode 100644 index 0000000..324aa99 --- /dev/null +++ b/linodes/mutate/mutate.css @@ -0,0 +1,78 @@ +/* + * This file is part of Linode Manager Classic. + * + * Linode Manager Classic is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Linode Manager Classic is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Linode Manager Classic. If not, see . + */ + +@import url('/global.css'); + +button { + margin-top: 10px; +} + +#eta { + color: #333; + font-weight: bold; +} + +h2 { + margin-top: 0; +} + +.lmc-tr3 { + border-bottom: none; +} + +#mutate { + padding: 0px 15px 15px; +} + +ol { + font-weight: bold; +} + +ol li { + font-weight: normal; + margin-bottom: 10px; +} + +#resize { + display: none; +} + +tbody td { + color: #666; + font-size: 14px; + vertical-align: top; +} + +tbody td:last-child { + width: 50%; +} + +tbody td h2 { + color: #333; +} + +tbody td strong { + color: #333; +} + +#tiny { + font-size: 12px; +} + +ul li { + display: none; +} diff --git a/linodes/mutate/mutate.js b/linodes/mutate/mutate.js new file mode 100644 index 0000000..1023fd3 --- /dev/null +++ b/linodes/mutate/mutate.js @@ -0,0 +1,269 @@ +/* + * This file is part of Linode Manager Classic. + * + * Linode Manager Classic is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Linode Manager Classic is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Linode Manager Classic. If not, see . + */ + +import { settings, elements, apiGet, migrateETA, parseParams, setupHeader } from "/global.js"; + +(function() +{ + // Element names specific to this page + elements.cpu = "cpu"; + elements.cpuCurrent = "cpu-current"; + elements.cpuNew = "cpu-new"; + elements.diskName = "disk-name"; + elements.eta = "eta"; + elements.gpu = "gpu"; + elements.gpuCurrent = "gpu-current"; + elements.gpuNew = "gpu-new"; + elements.linodeLabel = "linode-label"; + elements.linodeTag = "linode-tag"; + elements.linodeTagLink = "linode-tag-link"; + elements.mbit = "mbit"; + elements.mbitCurrent = "mbit-current"; + elements.mbitNew = "mbit-new"; + elements.ram = "ram"; + elements.ramCurrent = "ram-current"; + elements.ramNew = "ram-new"; + elements.resize = "resize"; + elements.resizeBox = "resize-box"; + elements.storage = "storage"; + elements.storageCurrent = "storage-current"; + elements.storageNew = "storage-new"; + elements.upgradeButton = "upgrade-button"; + elements.xfer = "xfer"; + elements.xferCurrent = "xfer-current"; + elements.xferNew = "xfer-new"; + + // Data recieved from API calls + var data = {}; + data.disks = []; + data.linode = {}; + data.plan = {}; + data.successor = {}; + + // Static references to UI elements + var ui = {}; + ui.cpu = {}; + ui.cpuCurrent = {}; + ui.cpuNew = {}; + ui.diskName = {}; + ui.eta = {}; + ui.gpu = {}; + ui.gpuCurrent = {}; + ui.gpuNew = {}; + ui.linodeLabel = {}; + ui.linodeTag = {}; + ui.linodeTagLink = {}; + ui.mbit = {}; + ui.mbitCurrent = {}; + ui.mbitNew = {}; + ui.ram = {}; + ui.ramCurrent = {}; + ui.ramNew = {}; + ui.resize = {}; + ui.resizeBox = {}; + ui.storage = {}; + ui.storageCurrent = {}; + ui.storageNew = {}; + ui.upgradeButton = {}; + ui.xfer = {}; + ui.xferCurrent = {}; + ui.xferNew = {}; + + // Callback for linode details API call + var displayDetails = function(response) + { + data.linode = response; + + // Set page title and header stuff + document.title += " // " + data.linode.label; + ui.linodeLabel.innerHTML = data.linode.label; + if (data.linode.tags.length == 1) { + ui.linodeTagLink.href = "/linodes?tag=" + data.linode.tags[0]; + ui.linodeTagLink.innerHTML = "(" + data.linode.tags[0] + ")"; + ui.linodeTag.style.display = "inline"; + } + + // Get plan info + apiGet("/linode/types/" + data.linode.type, displayPlan, null); + }; + + // Callback for linode disks API call + var displayDisks = function(response) + { + // Add disks to array + data.disks = data.disks.concat(response.data); + + // Request the next page if there are more pages + if (response.page != response.pages) { + apiGet("/linode/instances/" + data.params.lid + "/disks?page=" + (response.page + 1), displayDisks, null); + return; + } + + // Compute total size and types of disks + var size = 0; + var numExt = 0; + var numSwap = 0; + for (var i = 0; i < data.disks.length; i++) { + size += data.disks[i].size; + if (data.disks[i].filesystem.match(/ext3|ext4/)) { + numExt++; + ui.diskName.innerHTML = data.disks[i].label; + } + else if (data.disks[i].filesystem == "swap") + numSwap++; + } + + // Compute estimated resize time + ui.eta.innerHTML = migrateETA(size, true); + + // Show auto-resize option if there is only a single ext disk + if ((data.disks.length == 1 && numExt == 1) || (data.disks.length == 2 && numExt == 1 && numSwap == 1)) { + ui.resizeBox.disabled = false; + ui.resizeBox.checked = true; + ui.resize.style.display = "initial"; + } + }; + + // Callback for plan details API call + var displayPlan = function(response) + { + data.plan = response; + + // Redirect to dashboard if there is no upgrade + if (!data.plan.successor) { + location.href = "/linodes/dashboard?lid=" + data.params.lid; + return; + } + + // Get successor + apiGet("/linode/types/" + data.plan.successor, displaySuccessor, null); + }; + + // Callback for successor details API call + var displaySuccessor = function(response) + { + data.successor = response; + + // Set UI stuff + if (data.plan.memory != data.successor.memory) { + ui.ramCurrent.innerHTML = data.plan.memory / 1024; + ui.ramNew.innerHTML = data.successor.memory / 1024; + ui.ram.style.display = "list-item"; + } + if (data.plan.disk != data.successor.disk) { + ui.storageCurrent.innerHTML = data.plan.disk / 1024; + ui.storageNew.innerHTML = data.successor.disk / 1024; + ui.storage.style.display = "list-item"; + } + if (data.plan.vcpus != data.successor.vcpus) { + ui.cpuCurrent.innerHTML = data.plan.vcpus; + ui.cpuNew.innerHTML = data.successor.vcpus; + ui.cpu.style.display = "list-item"; + } + if (data.plan.gpus != data.successor.gpus) { + ui.gpuCurrent.innerHTML = data.plan.gpus; + ui.gpuNew.innerHTML = data.successor.gpus; + ui.gpu.style.display = "list-item"; + } + if (data.plan.network_out != data.successor.network_out) { + ui.mbitCurrent.innerHTML = data.plan.network_out; + ui.mbitNew.innerHTML = data.successor.network_out; + ui.mbit.style.display = "list-item"; + } + if (data.plan.transfer != data.successor.transfer) { + ui.xferCurrent.innerHTML = data.plan.transfer; + ui.xferNew.innerHTML = data.successor.transfer; + ui.xfer.style.display = "list-item"; + } + + ui.upgradeButton.disabled = false; + }; + + // Click handler for upgrade button + var handleUpgrade = function(event) + { + if (event.currentTarget.disabled) + return; + + var req = { + "allow_auto_disk_resize": (!ui.resizeBox.disabled && ui.resizeBox.checked) + }; + + apiPost("/linode/instances/" + data.params.lid + "/mutate", req, function(response) + { + location.href = "/linodes/dashboard?lid=" + data.params.lid; + }); + }; + + // Initial setup + var setup = function() + { + // Parse URL parameters + data.params = parseParams(); + + // We need a Linode ID, so die if we don't have it + if (!data.params.lid) { + alert("No Linode ID supplied!"); + return; + } + + setupHeader(); + + // Update links on page to include proper Linode ID + var anchors = document.getElementsByTagName("a"); + for (var i = 0; i < anchors.length; i++) + anchors[i].href = anchors[i].href.replace("lid=0", "lid=" + data.params.lid); + + // Get element references + ui.cpu = document.getElementById(elements.cpu); + ui.cpuCurrent = document.getElementById(elements.cpuCurrent); + ui.cpuNew = document.getElementById(elements.cpuNew); + ui.diskName = document.getElementById(elements.diskName); + ui.eta = document.getElementById(elements.eta); + ui.gpu = document.getElementById(elements.gpu); + ui.gpuCurrent = document.getElementById(elements.gpuCurrent); + ui.gpuNew = document.getElementById(elements.gpuNew); + ui.linodeLabel = document.getElementById(elements.linodeLabel); + ui.linodeTag = document.getElementById(elements.linodeTag); + ui.linodeTagLink = document.getElementById(elements.linodeTagLink); + ui.mbit = document.getElementById(elements.mbit); + ui.mbitCurrent = document.getElementById(elements.mbitCurrent); + ui.mbitNew = document.getElementById(elements.mbitNew); + ui.ram = document.getElementById(elements.ram); + ui.ramCurrent = document.getElementById(elements.ramCurrent); + ui.ramNew = document.getElementById(elements.ramNew); + ui.resize = document.getElementById(elements.resize); + ui.resizeBox = document.getElementById(elements.resizeBox); + ui.storage = document.getElementById(elements.storage); + ui.storageCurrent = document.getElementById(elements.storageCurrent); + ui.storageNew = document.getElementById(elements.storageNew); + ui.upgradeButton = document.getElementById(elements.upgradeButton); + ui.xfer = document.getElementById(elements.xfer); + ui.xferCurrent = document.getElementById(elements.xferCurrent); + ui.xferNew = document.getElementById(elements.xferNew); + + // Attach event handlers + ui.upgradeButton.addEventListener("click", handleUpgrade); + + // Get data from API + apiGet("/linode/instances/" + data.params.lid, displayDetails, null); + apiGet("/linode/instances/" + data.params.lid + "/disks", displayDisks, null); + }; + + // Attach onload handler + window.addEventListener("load", setup); +})();