From 64b8d3983e49aebbf8fef131299838433b1c4efa Mon Sep 17 00:00:00 2001 From: Jordan Rodgers Date: Sun, 18 Mar 2018 22:18:20 -0400 Subject: [PATCH] add ability to change boot order, a lot more cleanup from conversion to classes --- proxstar/__init__.py | 46 +++++++++------- proxstar/static/js/script.js | 87 ++++++++++++++++++++++++++++++ proxstar/tasks.py | 12 ++--- proxstar/templates/create.html | 2 +- proxstar/templates/vm_details.html | 83 +++++++++++++++------------- proxstar/user.py | 2 +- proxstar/vm.py | 59 +++++++++++++++++--- 7 files changed, 217 insertions(+), 74 deletions(-) diff --git a/proxstar/__init__.py b/proxstar/__init__.py index da5925a..caa24c6 100644 --- a/proxstar/__init__.py +++ b/proxstar/__init__.py @@ -13,7 +13,6 @@ from sqlalchemy.orm import sessionmaker from flask_pyoidc.flask_pyoidc import OIDCAuthentication from flask import Flask, render_template, request, redirect, session, abort from proxstar.db import * -from proxstar.vm import VM from proxstar.vnc import * from proxstar.util import gen_password from proxstar.starrs import * @@ -64,6 +63,7 @@ starrs = psycopg2.connect( app.config['STARRS_DB_NAME'], app.config['STARRS_DB_USER'], app.config['STARRS_DB_HOST'], app.config['STARRS_DB_PASS'])) +from proxstar.vm import VM from proxstar.user import User from proxstar.tasks import generate_pool_cache_task, process_expiring_vms_task, cleanup_vnc_task, delete_vm_task, create_vm_task, setup_template_task @@ -179,25 +179,11 @@ def vm_details(vmid): proxmox = connect_proxmox() if user.rtp or int(vmid) in user.allowed_vms: vm = VM(vmid) - vm_dict = vm.info - vm_dict['vmid'] = vmid - vm_dict['config'] = vm.config - vm_dict['node'] = vm.node - vm_dict['disks'] = vm.get_disks() - vm_dict['iso'] = vm.get_iso() - vm_dict['interfaces'] = [] - for interface in vm.get_interfaces(): - vm_dict['interfaces'].append( - [interface[0], - get_ip_for_mac(starrs, interface[1])]) - vm_dict['expire'] = get_vm_expire( - db, vmid, app.config['VM_EXPIRE_MONTHS']).strftime('%m/%d/%Y') - usage_check = user.check_usage(vm_dict['config']['cores'], - vm_dict['config']['memory'], 0) + usage_check = user.check_usage(vm.cpu, vm.mem, 0) return render_template( 'vm_details.html', user=user, - vm=vm_dict, + vm=vm, usage=user.usage, limits=user.limits, usage_check=usage_check) @@ -338,8 +324,9 @@ def vm_renew(vmid): if user.rtp or int(vmid) in user.allowed_vms: vm = VM(vmid) renew_vm_expire(db, vmid, app.config['VM_EXPIRE_MONTHS']) - for interface in vm.get_interfaces(): - renew_ip(starrs, get_ip_for_mac(starrs, interface[1])) + for interface in vm.interfaces: + if interface[2] != 'No IP': + renew_ip(starrs, interface[2]) return '', 200 else: return '', 403 @@ -384,6 +371,22 @@ def delete(vmid): return '', 403 +@app.route("/vm//boot_order", methods=['POST']) +@auth.oidc_auth +def boot_order(vmid): + user = User(session['userinfo']['preferred_username']) + proxmox = connect_proxmox() + if user.rtp or int(vmid) in user.allowed_vms: + boot_order = [] + for key, value in request.form.items(): + boot_order.append(value) + vm = VM(vmid) + vm.set_boot_order(boot_order) + return '', 200 + else: + return '', 403 + + @app.route("/vm/create", methods=['GET', 'POST']) @auth.oidc_auth def create(): @@ -414,7 +417,10 @@ def create(): iso = "{}:iso/{}".format(app.config['PROXMOX_ISO_STORAGE'], iso) if not user.rtp: - usage_check = user.check_usage(0, 0, disk) + if template == 'none': + usage_check = user.check_usage(0, 0, disk) + else: + usage_check = user.check_usage(cores, memory, disk) username = user.name else: usage_check = None diff --git a/proxstar/static/js/script.js b/proxstar/static/js/script.js index 98a5af3..c92bcf9 100644 --- a/proxstar/static/js/script.js +++ b/proxstar/static/js/script.js @@ -392,6 +392,8 @@ $("#create-vm").click(function(){ const template = document.getElementById('template').value; const iso = document.getElementById('iso').value; const user = document.getElementById('user'); + const max_cpu = $(this).data('max_cpu'); + const max_mem = $(this).data('max_mem'); const max_disk = $(this).data('max_disk'); var disk = document.getElementById('disk').value; fetch(`/template/${template}/disk`, { @@ -407,6 +409,10 @@ $("#create-vm").click(function(){ if (name && disk) { if (disk > max_disk) { swal("Uh oh...", `You do not have enough disk resources available! Please lower the VM disk size to ${max_disk}GB or lower.`, "error"); + } else if (template != 'none' && cores > max_cpu) { + swal("Uh oh...", `You do not have enough CPU resources available! Please lower the VM cores to ${max_cpu} or lower.`, "error"); + } else if (template != 'none' && mem/1024 > max_mem) { + swal("Uh oh...", `You do not have enough memory resources available! Please lower the VM memory to ${max_mem}GB or lower.`, "error"); } else { fetch(`/hostname/${name}`, { credentials: 'same-origin', @@ -942,3 +948,84 @@ $(".edit-template").click(function(){ } }); }); + +$("#edit-boot-order").click(function(){ + const vmid = $(this).data('vmid'); + const vmname = $(this).data('vmname'); + const boot_order = $(this).data('boot_order'); + var options = document.createElement('div'); + for (i = 0; i < boot_order.length; i++) { + text = document.createElement('span'); + text.innerHTML = `${i + 1}. `; + options.append(text); + var entry = document.createElement('select'); + entry.setAttribute("id", `boot-order-${i + 1}`); + for (j = 0; j < boot_order.length; j++) { + entry.appendChild(new Option(boot_order[j], boot_order[j])); + } + entry.selectedIndex = i; + entry.setAttribute('style', 'width: 85px'); + options.append(entry); + options.append(document.createElement('br')); + } + swal({ + title: `Select the new boot order for ${vmname} (full shutdown required for settings to take effect):`, + content: options, + buttons: { + cancel: { + text: "Cancel", + visible: true, + closeModal: true, + }, + confirm: { + text: "Submit", + closeModal: false, + } + }, + }) + .then((willChange) => { + if (willChange) { + var data = new FormData(); + for (k = 0; k < boot_order.length; k++) { + e = document.getElementById(`boot-order-${k + 1}`); + data.append(`${k + 1}`, e.options[e.selectedIndex].value); + } + fetch(`/vm/${vmid}/boot_order`, { + credentials: 'same-origin', + method: 'post', + body: data + }).then((response) => { + return swal(`Now applying the new boot order to ${vmname}!`, { + icon: "success", + buttons: { + ok: { + text: "OK", + closeModal: true, + } + } + }); + }).then(() => { + window.location = `/vm/${vmid}`; + }); + } + }).catch(err => { + if (err) { + swal("Uh oh...", `Unable to change the boot order for ${vmname}. Please try again later.`, "error"); + } else { + swal.stopLoading(); + swal.close(); + } + }); +}); + +$(document).on('focus click', "[id^=boot-order-]", function() { + previous = $(this).val(); +}).on('change', "[id^=boot-order-]", function() { + current = $(this).val(); + id = $(this).attr("id"); + $("[id^=boot-order-]").each(function() { + if ($(this).attr("id") != id && $(this).val() == current) { + $(this).val(previous); + } + }); +}); diff --git a/proxstar/tasks.py b/proxstar/tasks.py index 938e742..c219425 100644 --- a/proxstar/tasks.py +++ b/proxstar/tasks.py @@ -98,15 +98,13 @@ def process_expiring_vms_task(): expiring_vms = [] vms = user.vms for vm in vms: - vmid = vm['vmid'] - expire = get_vm_expire(db, vmid, - app.config['VM_EXPIRE_MONTHS']) - days = (expire - datetime.date.today()).days + vm = VM(vm['vmid']) + days = (vm.expire - datetime.date.today()).days if days in [10, 7, 3, 1, 0]: - name = VM(vmid).config['name'] - expiring_vms.append([name, days]) + name = vm.name + expiring_vms.append([vm.name, days]) if days == 0: - VM(vmid).stop() + vm.stop() if expiring_vms: send_vm_expire_email('com6056', expiring_vms) diff --git a/proxstar/templates/create.html b/proxstar/templates/create.html index 92c6f19..32d0250 100644 --- a/proxstar/templates/create.html +++ b/proxstar/templates/create.html @@ -71,7 +71,7 @@ {% endif %} - + {% endif %} diff --git a/proxstar/templates/vm_details.html b/proxstar/templates/vm_details.html index 25477ed..166845c 100644 --- a/proxstar/templates/vm_details.html +++ b/proxstar/templates/vm_details.html @@ -9,27 +9,27 @@

Actions

- {% if vm['qmpstatus'] == 'stopped' %} + {% if vm.qmpstatus == 'stopped' %} {% if not usage_check %} - + {% else %} Insufficient resources to start VM. {% endif %} {% endif %} - {% if vm['qmpstatus'] == 'suspended' or vm['qmpstatus'] == 'paused' %} - + {% if vm.qmpstatus == 'suspended' or vm.qmpstatus == 'paused' %} + {% endif %} - {% if vm['qmpstatus'] == 'running' or vm['qmpstatus'] == 'suspended' or vm['qmpstatus'] == 'paused' %} - {% if vm['qmpstatus'] == 'running' %} - - + {% if vm.qmpstatus == 'running' or vm.qmpstatus == 'suspended' or vm.qmpstatus == 'paused' %} + {% if vm.qmpstatus == 'running' %} + + {% endif %} - - - + + + {% endif %} - {% if vm['qmpstatus'] == 'stopped' %} - + {% if vm.qmpstatus == 'stopped' %} + {% else %} To delete VM, power it off. {% endif %} @@ -43,28 +43,35 @@