diff --git a/app.py b/app.py
index 3b8e999..fe4402b 100644
--- a/app.py
+++ b/app.py
@@ -17,6 +17,7 @@ from functions.fvnc import *
from functions.fbackup import *
from functions.fpool import *
from functions.fedit import *
+from functions.fdisks import *
app = Flask(__name__,static_url_path='',static_folder='static',template_folder='templates')
@@ -107,12 +108,13 @@ def logout():
@app.route('/',methods=['GET'])
@login_required
def get_home():
+ vlxc, vlibvirt, vhype = get_version()
lxc_up = len(get_lxc_activ())
lxc_down = len(get_lxc_inactiv())
vm_up = len(get_vm_activ())
vm_down = len(get_vm_inactiv())
full = get_host_full()
- return render_template('index.html', host=Host(), full = full, lxc_up=lxc_up, lxc_down=lxc_down, vm_up=vm_up, vm_down=vm_down)
+ return render_template('index.html', host=Host(), full = full, lxc_up=lxc_up, lxc_down=lxc_down, vm_up=vm_up, vm_down=vm_down,vlxc=vlxc, vlibvirt=vlibvirt, vhype=vhype)
def get_ressources():
while True:
@@ -181,6 +183,53 @@ def delvol():
flash('Error on deleting '+volume_name+':'+str(e), category='danger')
return redirect(url_for('get_pool'))
+############################
+## DISKS ##
+############################
+
+@app.route('/editdisks',methods=['POST'])
+@login_required
+def editdisks():
+ disk_id = request.form['disk_id']
+ disk_file = request.form['diskfile']
+ disk_name = os.path.basename(disk_file)
+ actual_size = request.form['actual_size']
+ new_size = request.form['new_size']
+ vm_name = request.form['vm_name']
+ try:
+ resize_disk(disk_file,actual_size,new_size,vm_name,disk_id)
+ flash(disk_name+' had been resized to '+str(new_size)+'G', category='success')
+ except Exception as e:
+ flash('Error resizing '+disk_name+':'+str(e), category='danger')
+ return redirect(url_for('state'))
+
+@app.route('/adddisk',methods=['POST'])
+@login_required
+def adddisk():
+ disk_name = request.form['disk_name']
+ vm_name = request.form['vm_name']
+ disk_size = request.form['disk_size']
+ disk_id = request.form['disk_id']
+ try:
+ create_attached_disk(vm_name,disk_name,disk_size,disk_id)
+ flash(disk_name+' had been created and attached', category='success')
+ except Exception as e:
+ flash('Error creating '+disk_name+':'+str(e), category='danger')
+ return redirect(url_for('state'))
+
+@app.route('/detachdisk',methods=['POST'])
+@login_required
+def detachdisk():
+ diskfile = request.form['diskfile']
+ disk_name = os.path.basename(diskfile)
+ vm_name = request.form['vm_name']
+ try:
+ detach_disk(vm_name,diskfile)
+ flash(disk_name+' had been dettached', category='success')
+ except Exception as e:
+ flash('Error Detaching '+disk_name+' on '+vm_name+':'+str(e), category='danger')
+ return redirect(url_for('state'))
+
############################
## VNC ##
############################
@@ -291,24 +340,27 @@ def edit():
vm_name = request.form['edit']
state, maxmem, mem, cpus, cput = get_info_vm(vm_name)
#Memory in MB
- return render_template('edit.html', vm_name=vm_name, max_Mermory=conn.getInfo()[1],max_vCPU= conn.getMaxVcpus(None),actual_vCPU=cpus, actual_ram=int(mem/1024),screen_64=get_screenshot(vm_name).decode('ASCII'),actual_autostart=get_autostart(vm_name))
+ return render_template('edit.html', vm_name=vm_name, max_Mermory=conn.getInfo()[1],max_vCPU= conn.getMaxVcpus(None),actual_vCPU=cpus, actual_ram=int(mem/1024),screen_64=get_screenshot(vm_name).decode('ASCII'),actual_autostart=get_autostart(vm_name),disks=get_disks_info(vm_name))
@app.route('/editressources',methods=['POST'])
@login_required
def editressources():
vm_name = request.form['vm_name']
+ state, maxmem, mem, cpus, cput = get_info_vm(vm_name)
new_ram = int(request.form['new_mem'])
- new_cpu = int(request.form['new_cpu'])
new_autostart = request.form.get('new_autostart')
- try:
- set_memory(vm_name,int(new_ram*1024))
- except Exception as e:
- flash('Error editing Memory for '+vm_name+': '+str(e), category='danger')
- try:
- set_vcpu(vm_name,new_cpu)
- except Exception as e:
- flash('Error editing CPU for '+vm_name+': '+str(e), category='danger')
+ new_cpu = int(request.form['new_cpu'])
+ if new_cpu != cpus:
+ try:
+ set_vcpu(vm_name,new_cpu)
+ except Exception as e:
+ flash('Error editing CPU for '+vm_name+': '+str(e), category='danger')
+ if new_ram != int(mem/1024):
+ try:
+ set_memory(vm_name,int(new_ram*1024))
+ except Exception as e:
+ flash('Error editing Memory for '+vm_name+': '+str(e), category='danger')
#Autostart
if request.form.get('new_autostart')=='auto_check':
try:
diff --git a/functions/__pycache__/fbackup.cpython-311.pyc b/functions/__pycache__/fbackup.cpython-311.pyc
index 5627093..42889b0 100644
Binary files a/functions/__pycache__/fbackup.cpython-311.pyc and b/functions/__pycache__/fbackup.cpython-311.pyc differ
diff --git a/functions/__pycache__/fdisks.cpython-311.pyc b/functions/__pycache__/fdisks.cpython-311.pyc
new file mode 100644
index 0000000..d6511f0
Binary files /dev/null and b/functions/__pycache__/fdisks.cpython-311.pyc differ
diff --git a/functions/__pycache__/fedit.cpython-311.pyc b/functions/__pycache__/fedit.cpython-311.pyc
index 80091c2..5067193 100644
Binary files a/functions/__pycache__/fedit.cpython-311.pyc and b/functions/__pycache__/fedit.cpython-311.pyc differ
diff --git a/functions/__pycache__/fhost.cpython-311.pyc b/functions/__pycache__/fhost.cpython-311.pyc
index 12b365d..4267b91 100644
Binary files a/functions/__pycache__/fhost.cpython-311.pyc and b/functions/__pycache__/fhost.cpython-311.pyc differ
diff --git a/functions/__pycache__/fiso.cpython-311.pyc b/functions/__pycache__/fiso.cpython-311.pyc
index 21de786..caaf660 100644
Binary files a/functions/__pycache__/fiso.cpython-311.pyc and b/functions/__pycache__/fiso.cpython-311.pyc differ
diff --git a/functions/__pycache__/flxc.cpython-311.pyc b/functions/__pycache__/flxc.cpython-311.pyc
index 7a48ce0..f4952af 100644
Binary files a/functions/__pycache__/flxc.cpython-311.pyc and b/functions/__pycache__/flxc.cpython-311.pyc differ
diff --git a/functions/__pycache__/fpool.cpython-311.pyc b/functions/__pycache__/fpool.cpython-311.pyc
index b806b4d..7096c5e 100644
Binary files a/functions/__pycache__/fpool.cpython-311.pyc and b/functions/__pycache__/fpool.cpython-311.pyc differ
diff --git a/functions/__pycache__/fscreen.cpython-311.pyc b/functions/__pycache__/fscreen.cpython-311.pyc
index 840f385..dda9a78 100644
Binary files a/functions/__pycache__/fscreen.cpython-311.pyc and b/functions/__pycache__/fscreen.cpython-311.pyc differ
diff --git a/functions/__pycache__/fvm.cpython-311.pyc b/functions/__pycache__/fvm.cpython-311.pyc
index a2f0063..961b471 100644
Binary files a/functions/__pycache__/fvm.cpython-311.pyc and b/functions/__pycache__/fvm.cpython-311.pyc differ
diff --git a/functions/__pycache__/fvnc.cpython-311.pyc b/functions/__pycache__/fvnc.cpython-311.pyc
index 0abe216..3932b2c 100644
Binary files a/functions/__pycache__/fvnc.cpython-311.pyc and b/functions/__pycache__/fvnc.cpython-311.pyc differ
diff --git a/functions/fbackup.py b/functions/fbackup.py
index efb1a0d..aa61441 100644
--- a/functions/fbackup.py
+++ b/functions/fbackup.py
@@ -55,3 +55,11 @@ def del_snap_vm(vm_name,item):
dom=conn.lookupByName(vm_name)
snap_del=dom.snapshotLookupByName(item)
snap_del.delete()
+
+def rest_snap_vm(vm_name,item):
+ dom=conn.lookupByName(vm_name)
+ snaps = dom.listAllSnapshots()
+ for snap in snaps:
+ if snap.getName() == item:
+ dom.revertToSnapshot(snap)
+
diff --git a/functions/fdisks.py b/functions/fdisks.py
new file mode 100644
index 0000000..0014525
--- /dev/null
+++ b/functions/fdisks.py
@@ -0,0 +1,81 @@
+import os
+from config import *
+from xml.dom import minidom
+import subprocess
+from functions.fpool import *
+
+
+def get_volume_disk(disk_path):
+ refresh_pool()
+ vol_disk = conn.storageVolLookupByPath(disk_path)
+ vol_size = vol_disk.info()[1]
+ vol_size_G = vol_size / (1024*1024*1024)
+ return vol_size_G
+
+def get_disks_info(vm_name):
+ disks = []
+ dom = conn.lookupByName(vm_name)
+ raw_xml = dom.XMLDesc(0)
+ xml = minidom.parseString(raw_xml)
+ diskTypes = xml.getElementsByTagName('disk')
+ for diskType in diskTypes:
+ if diskType.getAttribute('device') == 'disk':
+ disk_unit = []
+ disk_id = 'Unknown'
+ diskNodes = diskType.childNodes
+ for diskNode in diskNodes:
+ if diskNode.nodeName == 'target':
+ for attr in diskNode.attributes.keys():
+ if diskNode.attributes[attr].name == 'dev':
+ disk_id = diskNode.attributes[attr].value
+ if diskNode.nodeName == 'source':
+ for attr in diskNode.attributes.keys():
+ if diskNode.attributes[attr].name == 'file':
+ blkinf = dom.blockInfo(diskNode.attributes[attr].value)
+ vol_size = os.path.getsize(diskNode.attributes[attr].value)
+ diskname = os.path.basename(diskNode.attributes[attr].value)
+ volsize = get_volume_disk(diskNode.attributes[attr].value)
+ disksize = round(blkinf[0] / 1024**3)
+ diskused = round(blkinf[1] / 1024**3)
+ if disksize > 0:
+ diskpercent = (diskused*100 / disksize)
+ else:
+ diskpercent = 0
+ disk_unit = [diskNode.attributes[attr].value,disksize,diskused,diskpercent,diskname,int(volsize)]
+ if diskNode.nodeName == 'target':
+ for attr in diskNode.attributes.keys():
+ if diskNode.attributes[attr].name == 'dev':
+ disk_id = diskNode.attributes[attr].value
+ disk_unit.append(disk_id)
+ disks.append(disk_unit)
+ return disks
+
+def create_attached_disk(vm_name,disk_name,disk_size,disk_id):
+ cmd = "qemu-img create -f qcow2 "+str(disk_path)+str(disk_name)+".qcow2 "+str(disk_size)+"G"
+ subprocess.call(cmd, shell=True)
+ dom = conn.lookupByName(vm_name)
+ if not dom.isActive():
+ dom.create()
+ disk_full = disk_path+disk_name+".qcow2"
+ cmd = "virsh attach-disk --domain "+vm_name+" "+disk_full+" --target "+disk_id+" --persistent --config --live"
+ subprocess.call(cmd, shell=True)
+ refresh_pool()
+
+def resize_disk(disk_file,actual_size,new_size,vm_name,disk_id):
+ cmd = "virsh detach-disk '"+vm_name+"' "+disk_file+" --persistent --config --live"
+ subprocess.call(cmd, shell=True)
+ if int(actual_size) < int(new_size):
+ cmd = "qemu-img resize -f qcow2 "+str(disk_file)+" "+str(new_size)+"G"
+ subprocess.call(cmd, shell=True)
+ else:
+ cmd = "qemu-img resize -f qcow2 --shrink "+str(disk_file)+" "+str(new_size)+"G"
+ subprocess.call(cmd, shell=True)
+ cmd = "virsh attach-disk '"+str(vm_name)+"' "+str(disk_file)+" "+str(disk_id)+" --cache none --persistent --config --live"
+ subprocess.call(cmd, shell=True)
+ refresh_pool()
+
+def detach_disk(vm_name,diskfile):
+ cmd = "virsh detach-disk '"+str(vm_name)+"' "+str(diskfile)+" --persistent --config --live"
+ subprocess.call(cmd, shell=True)
+ refresh_pool()
+
diff --git a/functions/fedit.py b/functions/fedit.py
index fa16bf0..cade4bb 100644
--- a/functions/fedit.py
+++ b/functions/fedit.py
@@ -1,20 +1,71 @@
from config import *
import base64
+import time
+import lxc
+
+def get_version():
+ vlxc = lxc.version
+ vlibvirt = str(libvirt.getVersion()/1000000) #1000000 * major + 1000 * minor + release
+ vhype = hype_version
+ return vlxc, vlibvirt, vhype
+
-#memory = Memory in Mo
def set_memory(vm_name,memory_new):
dom = conn.lookupByName(vm_name)
- dom.setMemory(memory_new)
+ dom.shutdown()
+ time.sleep(3)
+ alive=0
+ while alive < 5:
+ if dom.isActive():
+ time.sleep(3)
+ alive+=1
+ else:
+ alive=6
+ if dom.isActive():
+ dom.destroy()
+ dom.setMaxMemory(memory_new)
+ dom.setMemoryFlags(memory_new)
+ dom.create()
+ time.sleep(3)
+ alive=0
+ while alive < 3:
+ if dom.isActive():
+ alive=4
+ else:
+ time.sleep(3)
+ alive+=1
def set_vcpu(vm_name,vcpu_new):
dom = conn.lookupByName(vm_name)
- dom.setVcpus(vcpu_new)
+ dom.shutdown()
+ time.sleep(3)
+ alive=0
+ while alive < 5:
+ if dom.isActive():
+ time.sleep(3)
+ alive+=1
+ else:
+ alive=6
+ if dom.isActive():
+ dom.destroy()
+ dom.setVcpusFlags(vcpu_new,libvirt.VIR_DOMAIN_AFFECT_CONFIG | libvirt.VIR_DOMAIN_VCPU_MAXIMUM)
+ dom.setVcpusFlags(vcpu_new,libvirt.VIR_DOMAIN_AFFECT_CONFIG | libvirt.VIR_DOMAIN_VCPU_CURRENT)
+ dom.create()
+ time.sleep(3)
+ alive=0
+ while alive < 3:
+ if dom.isActive():
+ alive=4
+ else:
+ time.sleep(3)
+ alive+=1
def get_info_vm(vm_name):
dom = conn.lookupByName(vm_name)
state, maxmem, mem, cpus, cput = dom.info()
return state, maxmem, mem, cpus, cput
+#Screenshot
def get_screenshot(vm_name):
dom = conn.lookupByName(vm_name)
stream = conn.newStream()
@@ -31,3 +82,18 @@ def get_screenshot(vm_name):
data = base64.b64encode(f.read())
os.remove(file)
return data
+
+#Autostart
+
+def get_autostart(vm_name):
+ dom = conn.lookupByName(vm_name)
+ return dom.autostart()
+
+def set_autostart(vm_name):
+ dom = conn.lookupByName(vm_name)
+ dom.setAutostart(1)
+
+def unset_autostart(vm_name):
+ dom = conn.lookupByName(vm_name)
+ dom.setAutostart(0)
+
diff --git a/functions/fpool.py b/functions/fpool.py
index c41b7e7..ab028a9 100644
--- a/functions/fpool.py
+++ b/functions/fpool.py
@@ -29,7 +29,6 @@ def get_pool_info(pool_name):
pool_info.append(pool.UUIDString())
pool_info.append(str(pool.isActive()))
pool_info.append(str(human_size(pool.info()[1])))
-
pool_info.append(str(human_size(pool.info()[2])))
pool_info.append(str(human_size(pool.info()[3])))
if pool.info()[1]==0:
diff --git a/templates/build.html b/templates/build.html
index 3733f04..49c906a 100644
--- a/templates/build.html
+++ b/templates/build.html
@@ -66,5 +66,10 @@
-
+
{% endblock %}
diff --git a/templates/edit.html b/templates/edit.html
index a9469b5..48e45fe 100644
--- a/templates/edit.html
+++ b/templates/edit.html
@@ -12,18 +12,98 @@
- Vcpu : {{ actual_vCPU }}
- Memory: {{ actual_ram }} MB
+ vCPU : {{ actual_vCPU }}
+ Memory: {{ actual_ram }} MB
+{% if actual_autostart == 1 %}
+ Autostart :
+{% else %}
+ Autostart :
+{% endif %}
+
-
+
+
+{% if actual_autostart == 1 %}
+ Autostart
+{% else %}
+ Autostart
+{% endif %}
+
+
Changing vCPU and/or Memory will restart {{ vm_name }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+{% for disk in disks %}
+
+
{{ disk[4] }} ({{ disk[5] }} G)
+
System disk:
name: {{ disk[6] }} - Size : {{ disk[1] }} G (Used : {{ disk[2] }} G)
+
+
+{% endfor %}
+
+
+
Shrinking a disk size, can corrupt or delete your data
+
+{% for disk in disks %}
+ {{ disk[4] }} |
+ | G |
+
+
+ |
+
+ |
+
+
|
|
|
+{% endfor%}
+
+
+
+
+ Add a disk
+
diff --git a/templates/index.html b/templates/index.html
index f82c4a8..e1b47a1 100644
--- a/templates/index.html
+++ b/templates/index.html
@@ -10,7 +10,8 @@
{{ host.hostname }}
- Last boot : {{ host.boot_time }}
+ Last boot : {{ host.boot_time }}
+ LXC: {{ vlxc }} - Libvirt: {{ vlibvirt }} - Hype: {{ vhype }}
diff --git a/templates/iso.html b/templates/iso.html
index c4be4e9..f109730 100644
--- a/templates/iso.html
+++ b/templates/iso.html
@@ -60,4 +60,12 @@
+
+
+
{% endblock %}
diff --git a/templates/layout.html b/templates/layout.html
index 9e3d2ec..99aaf94 100644
--- a/templates/layout.html
+++ b/templates/layout.html
@@ -16,7 +16,6 @@
-
@@ -73,8 +72,6 @@
{% block content %}{% endblock %}
-
-Version Beta 2.7
-
+