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 %}
+
- (Max : {{ max_vCPU }})
- MB (Max : {{ max_Mermory }} MB)

- -
-
+
CPU : (Max : {{ max_vCPU }} )

+
Memory : MB (Max : {{ max_Mermory }} MB)

+{% if actual_autostart == 1 %} + Autostart +{% else %} + Autostart +{% endif %} +

+
Changing vCPU and/or Memory will restart {{ vm_name }} +

+ + + + + + +
+
+
+ Disk(s) of {{ vm_name }} +
+
+
+
+{% for disk in disks %} + + {{ disk[4] }} ({{ disk[5] }} G)
+ System disk:
name: {{ disk[6] }} - Size : {{ disk[1] }} G (Used : {{ disk[2] }} G)

+
+
{{ disk[3] }} %
+

+ +{% endfor %} +
+
+ Shrinking a disk size, can corrupt or delete your data

+ +{% for disk in disks %} + + + +{% endfor%} +
{{ disk[4] }} +
+ + + + + +
G + + + +
+ + + +
+
+
+
+
+ Add a disk
+
+
+
+ + Name


Size

Disk target
+
+
+
+ G
+
+
+
+
+ + +
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
- +