mirror of
https://github.com/ComputerScienceHouse/proxstar.git
synced 2025-03-09 15:40:09 +00:00
add ability to change boot order, a lot more cleanup from conversion to classes
This commit is contained in:
parent
cefe605bb9
commit
64b8d3983e
7 changed files with 217 additions and 74 deletions
|
@ -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/<string:vmid>/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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -71,7 +71,7 @@
|
|||
</select>
|
||||
</div>
|
||||
{% endif %}
|
||||
<button class="btn btn-success" id="create-vm" name="create" data-max_disk="{{ limits['disk'] - usage['disk'] }}">CREATE</button>
|
||||
<button class="btn btn-success" id="create-vm" name="create" data-max_cpu="{{ limits['cpu'] - usage['cpu'] }}" data-max_mem="{{ limits['mem'] - usage['mem'] }}" data-max_disk="{{ limits['disk'] - usage['disk'] }}">CREATE</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -9,27 +9,27 @@
|
|||
<h3 class="panel-title">Actions</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
{% if vm['qmpstatus'] == 'stopped' %}
|
||||
{% if vm.qmpstatus == 'stopped' %}
|
||||
{% if not usage_check %}
|
||||
<button class="btn btn-success proxstar-actionbtn" id="start-vm" name="start" data-vmid="{{ vm['vmid'] }}" data-vmname="{{ vm['name'] }}">START</button>
|
||||
<button class="btn btn-success proxstar-actionbtn" id="start-vm" name="start" data-vmid="{{ vm.id }}" data-vmname="{{ vm.name }}">START</button>
|
||||
{% else %}
|
||||
Insufficient resources to start VM.
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if vm['qmpstatus'] == 'suspended' or vm['qmpstatus'] == 'paused' %}
|
||||
<button class="btn btn-success proxstar-actionbtn" id="resume-vm" name="resume" data-vmid="{{ vm['vmid'] }}" data-vmname="{{ vm['name'] }}">RESUME</button>
|
||||
{% if vm.qmpstatus == 'suspended' or vm.qmpstatus == 'paused' %}
|
||||
<button class="btn btn-success proxstar-actionbtn" id="resume-vm" name="resume" data-vmid="{{ vm.id }}" data-vmname="{{ vm.name }}">RESUME</button>
|
||||
{% endif %}
|
||||
{% if vm['qmpstatus'] == 'running' or vm['qmpstatus'] == 'suspended' or vm['qmpstatus'] == 'paused' %}
|
||||
{% if vm['qmpstatus'] == 'running' %}
|
||||
<button class="btn btn-success proxstar-actionbtn" id="console-vm" name="console" data-vmid="{{ vm['vmid'] }}" data-vmname="{{ vm['name'] }}">CONSOLE</button>
|
||||
<button class="btn btn-info proxstar-actionbtn" id="suspend-vm" name="suspend" data-vmid="{{ vm['vmid'] }}" data-vmname="{{ vm['name'] }}">SUSPEND</button>
|
||||
{% if vm.qmpstatus == 'running' or vm.qmpstatus == 'suspended' or vm.qmpstatus == 'paused' %}
|
||||
{% if vm.qmpstatus == 'running' %}
|
||||
<button class="btn btn-success proxstar-actionbtn" id="console-vm" name="console" data-vmid="{{ vm.id }}" data-vmname="{{ vm.name }}">CONSOLE</button>
|
||||
<button class="btn btn-info proxstar-actionbtn" id="suspend-vm" name="suspend" data-vmid="{{ vm.id }}" data-vmname="{{ vm.name }}">SUSPEND</button>
|
||||
{% endif %}
|
||||
<button class="btn btn-info proxstar-actionbtn" id="shutdown-vm" name="shutdown" data-vmid="{{ vm['vmid'] }}" data-vmname="{{ vm['name'] }}">SHUTDOWN</button>
|
||||
<button class="btn btn-warning proxstar-actionbtn" id="stop-vm" name="stop" data-vmid="{{ vm['vmid'] }}" data-vmname="{{ vm['name'] }}">STOP</button>
|
||||
<button class="btn btn-warning proxstar-actionbtn" id="reset-vm" name="reset" data-vmid="{{ vm['vmid'] }}" data-vmname="{{ vm['name'] }}">RESET</button>
|
||||
<button class="btn btn-info proxstar-actionbtn" id="shutdown-vm" name="shutdown" data-vmid="{{ vm.id }}" data-vmname="{{ vm.name }}">SHUTDOWN</button>
|
||||
<button class="btn btn-warning proxstar-actionbtn" id="stop-vm" name="stop" data-vmid="{{ vm.id }}" data-vmname="{{ vm.name }}">STOP</button>
|
||||
<button class="btn btn-warning proxstar-actionbtn" id="reset-vm" name="reset" data-vmid="{{ vm.id }}" data-vmname="{{ vm.name }}">RESET</button>
|
||||
{% endif %}
|
||||
{% if vm['qmpstatus'] == 'stopped' %}
|
||||
<button class="btn btn-danger proxstar-actionbtn" id="delete-vm" name="delete" data-vmid="{{ vm['vmid'] }}" data-vmname="{{ vm['name'] }}">DELETE</button>
|
||||
{% if vm.qmpstatus == 'stopped' %}
|
||||
<button class="btn btn-danger proxstar-actionbtn" id="delete-vm" name="delete" data-vmid="{{ vm.id }}" data-vmname="{{ vm.name }}">DELETE</button>
|
||||
{% else %}
|
||||
To delete VM, power it off.
|
||||
{% endif %}
|
||||
|
@ -43,28 +43,35 @@
|
|||
</div>
|
||||
<div class="panel-body">
|
||||
<ul class="nav nav-list">
|
||||
<li class="nav-header">Boot Order</li>
|
||||
<li>
|
||||
{{ vm.boot_order|join(', ') }}
|
||||
<button class="btn btn-default proxstar-changebtn" id="edit-boot-order" data-vmid="{{ vm.id }}" data-vmname="{{ vm.name }}" data-boot_order="{{ vm.boot_order_json }}">
|
||||
<span class="glyphicon glyphicon-cog"></span>
|
||||
</button>
|
||||
</li>
|
||||
<li class="nav-header">Interfaces</li>
|
||||
{% for interface in vm['interfaces'] %}
|
||||
<li>{{ interface[0] }}: {{ interface[1] }}</li>
|
||||
{% for interface in vm.interfaces %}
|
||||
<li>{{ interface[0] }}: {{ interface[2] }}</li>
|
||||
{% endfor %}
|
||||
<li class="nav-header">Disks</li>
|
||||
{% for disk in vm['disks'] %}
|
||||
{% for disk in vm.disks %}
|
||||
<li>
|
||||
{{ disk[0] }}: {{ disk[1] }}GB
|
||||
<button class="btn btn-default proxstar-changebtn resize-disk" id="resize-disk" name="resize" data-vmid="{{ vm['vmid'] }}" data-disk="{{ disk[0] }}" data-usage="{{ usage['disk'] }}" data-limit="{{ limits['disk'] }}">
|
||||
<button class="btn btn-default proxstar-changebtn resize-disk" id="resize-disk" name="resize" data-vmid="{{ vm.id }}" data-disk="{{ disk[0] }}" data-usage="{{ usage['disk'] }}" data-limit="{{ limits['disk'] }}">
|
||||
<span class="glyphicon glyphicon-cog"></span>
|
||||
</button>
|
||||
</li>
|
||||
{% endfor %}
|
||||
<li class="nav-header">ISO</li>
|
||||
<li>
|
||||
{{ vm['iso'] }}
|
||||
{% if vm['iso'] != 'None' %}
|
||||
<button class="btn btn-danger proxstar-ejectbtn" id="eject-iso" name="eject" data-vmid="{{ vm['vmid'] }}" data-iso="{{ vm['iso'] }}">
|
||||
{{ vm.iso }}
|
||||
{% if vm.iso != 'None' %}
|
||||
<button class="btn btn-danger proxstar-ejectbtn" id="eject-iso" name="eject" data-vmid="{{ vm.id }}" data-iso="{{ vm.iso }}">
|
||||
<span class="glyphicon glyphicon-eject"></span>
|
||||
</button>
|
||||
{% endif %}
|
||||
<button class="btn btn-default proxstar-changebtn" id="change-iso" name="change" data-vmid="{{ vm['vmid'] }}" data-iso="{{ vm['iso'] }}">
|
||||
<button class="btn btn-default proxstar-changebtn" id="change-iso" name="change" data-vmid="{{ vm.id }}" data-iso="{{ vm.iso }}">
|
||||
<span class="glyphicon glyphicon-cog"></span>
|
||||
</button>
|
||||
</li>
|
||||
|
@ -80,49 +87,49 @@
|
|||
<div class="panel-body">
|
||||
<dl class="dl-horizontal">
|
||||
<dt>Name</dt>
|
||||
<dd>{{ vm['name'] }}</dd>
|
||||
<dd>{{ vm.name }}</dd>
|
||||
<dt>DNS Name</dt>
|
||||
<dd>{{ vm['name'] }}.csh.rit.edu</dd>
|
||||
<dd>{{ vm.name }}.csh.rit.edu</dd>
|
||||
<dt>ID</dt>
|
||||
<dd>{{ vm['vmid'] }}</dd>
|
||||
<dd>{{ vm.id }}</dd>
|
||||
<dt>Status</dt>
|
||||
<dd>{{ vm['qmpstatus'] }}</dd>
|
||||
<dd>{{ vm.qmpstatus }}</dd>
|
||||
<dt>Node</dt>
|
||||
<dd>{{ vm['node'] }}</dd>
|
||||
<dd>{{ vm.node }}</dd>
|
||||
<dt>Cores</dt>
|
||||
<dd>
|
||||
{{ vm['config']['cores'] * vm['config'].get('sockets', 1) }}
|
||||
{% if vm['qmpstatus'] == 'running' or vm['qmpstatus'] == 'suspended' or vm['qmpstatus'] == 'paused' %}
|
||||
<button class="btn btn-default proxstar-changebtn" id="change-cores" data-vmid="{{ vm['vmid'] }}" data-usage="{{ usage['cpu'] - (vm['config']['cores'] * vm['config'].get('sockets', 1)) }}" data-limit="{{ limits['cpu'] }}">
|
||||
{{ vm.cpu }}
|
||||
{% if vm.qmpstatus == 'running' or vm.qmpstatus == 'suspended' or vm.qmpstatus == 'paused' %}
|
||||
<button class="btn btn-default proxstar-changebtn" id="change-cores" data-vmid="{{ vm.id }}" data-usage="{{ usage['cpu'] - vm.cpu }}" data-limit="{{ limits['cpu'] }}">
|
||||
<span class="glyphicon glyphicon-cog"></span>
|
||||
</button>
|
||||
{% else %}
|
||||
<button class="btn btn-default proxstar-changebtn" id="change-cores" data-vmid="{{ vm['vmid'] }}" data-usage=0 data-limit="{{ limits['cpu'] }}">
|
||||
<button class="btn btn-default proxstar-changebtn" id="change-cores" data-vmid="{{ vm.id }}" data-usage=0 data-limit="{{ limits['cpu'] }}">
|
||||
<span class="glyphicon glyphicon-cog"></span>
|
||||
</button>
|
||||
{% endif %}
|
||||
</dd>
|
||||
<dt>Memory</dt>
|
||||
<dd>
|
||||
{% if vm['config']['memory'] < 1024 %}
|
||||
{{ vm['config']['memory'] }}MB
|
||||
{% if vm.mem < 1024 %}
|
||||
{{ vm.mem }}MB
|
||||
{% else %}
|
||||
{{ vm['config']['memory'] // 1024 }}GB
|
||||
{{ vm.mem // 1024 }}GB
|
||||
{% endif %}
|
||||
{% if vm['qmpstatus'] == 'running' or vm['qmpstatus'] == 'suspended' or vm['qmpstatus'] == 'paused' %}
|
||||
<button class="btn btn-default proxstar-changebtn" id="change-mem" data-vmid="{{ vm['vmid'] }}" data-usage="{{ usage['mem'] - vm['config']['memory'] // 1024 }}" data-limit="{{ limits['mem'] }}">
|
||||
{% if vm.qmpstatus == 'running' or vm.qmpstatus == 'suspended' or vm.qmpstatus == 'paused' %}
|
||||
<button class="btn btn-default proxstar-changebtn" id="change-mem" data-vmid="{{ vm.id }}" data-usage="{{ usage['mem'] - vm.config['memory'] // 1024 }}" data-limit="{{ limits['mem'] }}">
|
||||
<span class="glyphicon glyphicon-cog"></span>
|
||||
</button>
|
||||
{% else %}
|
||||
<button class="btn btn-default proxstar-changebtn" id="change-mem" data-vmid="{{ vm['vmid'] }}" data-usage=0 data-limit="{{ limits['mem'] }}">
|
||||
<button class="btn btn-default proxstar-changebtn" id="change-mem" data-vmid="{{ vm.id }}" data-usage=0 data-limit="{{ limits['mem'] }}">
|
||||
<span class="glyphicon glyphicon-cog"></span>
|
||||
</button>
|
||||
{% endif %}
|
||||
</dd>
|
||||
<dt>Expiration</dt>
|
||||
<dd>
|
||||
{{ vm['expire'] }}
|
||||
<button class="btn btn-success proxstar-renewbtn" id="renew-vm" name="renew" data-vmid="{{ vm['vmid'] }}" data-vmname="{{ vm['name'] }}">
|
||||
{{ vm.expire.strftime('%m/%d/%Y') }}
|
||||
<button class="btn btn-success proxstar-renewbtn" id="renew-vm" name="renew" data-vmid="{{ vm.id }}" data-vmname="{{ vm.name }}">
|
||||
<span class="glyphicon glyphicon-plus"></span>
|
||||
</button>
|
||||
</dd>
|
||||
|
|
|
@ -76,7 +76,7 @@ class User(object):
|
|||
if vm.status == 'running' or vm.status == 'paused':
|
||||
usage['cpu'] += int(vm.cpu * vm.config.get('sockets', 1))
|
||||
usage['mem'] += (int(vm.mem) / 1024)
|
||||
for disk in vm.get_disks():
|
||||
for disk in vm.disks:
|
||||
usage['disk'] += int(disk[1])
|
||||
return usage
|
||||
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
import time
|
||||
from proxstar.util import *
|
||||
import json
|
||||
from proxstar import db, starrs
|
||||
from proxstar.db import get_vm_expire
|
||||
from proxstar.util import lazy_property
|
||||
from proxstar.starrs import get_ip_for_mac
|
||||
from proxstar.proxmox import connect_proxmox, get_node_least_mem, get_free_vmid, get_vm_node
|
||||
from flask import current_app as app
|
||||
|
||||
|
||||
class VM(object):
|
||||
|
@ -13,7 +18,7 @@ class VM(object):
|
|||
|
||||
@lazy_property
|
||||
def cpu(self):
|
||||
return self.config['cores']
|
||||
return self.config['cores'] * self.config.get('sockets', 1)
|
||||
|
||||
@lazy_property
|
||||
def mem(self):
|
||||
|
@ -40,7 +45,8 @@ class VM(object):
|
|||
|
||||
def set_cpu(self, cores):
|
||||
proxmox = connect_proxmox()
|
||||
proxmox.nodes(self.node).qemu(self.id).config.put(cores=cores)
|
||||
proxmox.nodes(self.node).qemu(self.id).config.put(
|
||||
cores=cores, sockets=1)
|
||||
|
||||
def set_mem(self, mem):
|
||||
proxmox = connect_proxmox()
|
||||
|
@ -80,7 +86,39 @@ class VM(object):
|
|||
proxmox = connect_proxmox()
|
||||
return proxmox.nodes(self.node).qemu(self.id).config.get()
|
||||
|
||||
def get_interfaces(self):
|
||||
@lazy_property
|
||||
def boot_order(self):
|
||||
boot_order_lookup = {
|
||||
'a': 'Floppy',
|
||||
'c': 'Hard Disk',
|
||||
'd': 'CD-ROM',
|
||||
'n': 'Network'
|
||||
}
|
||||
raw_boot_order = self.config.get('boot', 'cdn')
|
||||
boot_order = []
|
||||
for i in range(0, len(raw_boot_order)):
|
||||
boot_order.append(boot_order_lookup[raw_boot_order[i]])
|
||||
return boot_order
|
||||
|
||||
@lazy_property
|
||||
def boot_order_json(self):
|
||||
return json.dumps(self.boot_order)
|
||||
|
||||
def set_boot_order(self, boot_order):
|
||||
proxmox = connect_proxmox()
|
||||
boot_order_lookup = {
|
||||
'Floppy': 'a',
|
||||
'Hard Disk': 'c',
|
||||
'CD-ROM': 'd',
|
||||
'Network': 'n'
|
||||
}
|
||||
raw_boot_order = ''
|
||||
for i in range(0, len(boot_order)):
|
||||
raw_boot_order += boot_order_lookup[boot_order[i]]
|
||||
proxmox.nodes(self.node).qemu(self.id).config.put(boot=raw_boot_order)
|
||||
|
||||
@lazy_property
|
||||
def interfaces(self):
|
||||
interfaces = []
|
||||
for key, val in self.config.items():
|
||||
if 'net' in key:
|
||||
|
@ -90,7 +128,8 @@ class VM(object):
|
|||
mac = mac[0].split('=')[1]
|
||||
else:
|
||||
mac = mac[1].split('=')[1]
|
||||
interfaces.append([key, mac])
|
||||
ip = get_ip_for_mac(starrs, mac)
|
||||
interfaces.append([key, mac, ip])
|
||||
interfaces = sorted(interfaces, key=lambda x: x[0])
|
||||
return interfaces
|
||||
|
||||
|
@ -109,7 +148,8 @@ class VM(object):
|
|||
disk_size = split.split('=')[1].rstrip('G')
|
||||
return disk_size
|
||||
|
||||
def get_disks(self):
|
||||
@lazy_property
|
||||
def disks(self):
|
||||
disks = []
|
||||
for key, val in self.config.items():
|
||||
valid_disk_types = ['virtio', 'ide', 'sata', 'scsi']
|
||||
|
@ -123,7 +163,8 @@ class VM(object):
|
|||
disks = sorted(disks, key=lambda x: x[0])
|
||||
return disks
|
||||
|
||||
def get_iso(self):
|
||||
@lazy_property
|
||||
def iso(self):
|
||||
if self.config.get('ide2'):
|
||||
if self.config['ide2'].split(',')[0] == 'none':
|
||||
iso = 'None'
|
||||
|
@ -154,6 +195,10 @@ class VM(object):
|
|||
proxmox.nodes(self.node).qemu(self.id).resize.put(
|
||||
disk=disk, size="+{}G".format(size))
|
||||
|
||||
@lazy_property
|
||||
def expire(self):
|
||||
return get_vm_expire(db, self.id, app.config['VM_EXPIRE_MONTHS'])
|
||||
|
||||
|
||||
def create_vm(proxmox, user, name, cores, memory, disk, iso):
|
||||
node = proxmox.nodes(get_node_least_mem(proxmox))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue