Hype-2/app.py

824 lines
46 KiB
Python

import os
import json
import requests
import subprocess
from flask import Flask , redirect , render_template, request, Response, stream_with_context, url_for, make_response, flash
from werkzeug.utils import secure_filename
from flask_sqlalchemy import SQLAlchemy
from flask_login import LoginManager , UserMixin , login_required ,login_user, logout_user,current_user
from werkzeug.security import generate_password_hash, check_password_hash
from config import *
from functions.fhost import *
from functions.flxc import *
from functions.fiso import *
from functions.fvm import *
from functions.fvnc import *
from functions.fbackup import *
from functions.fpool import *
from functions.fedit import *
from functions.fdisks import *
from functions.fnet import *
app = Flask(__name__,static_url_path='',static_folder='static',template_folder='templates')
###########################
## DROPZONE ##
###########################
app.config['MAX_CONTENT_LENGTH'] = 10 * 1024 * 1024 * 1024
app.config['UPLOAD_EXTENSIONS'] = ['.iso']
app.config['UPLOAD_PATH'] = iso_path
############################
## LOGIN ##
############################
#Database (see base.sql for creation user table)
app.config['SQLALCHEMY_DATABASE_URI']='sqlite:///'+os.path.join(path,'db.db')
app.config['SECRET_KEY']='619619'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS']=True
db = SQLAlchemy(app)
#Login init (login_view => default login page)
login_manager = LoginManager()
login_manager.login_view = "/login"
login_manager.init_app(app)
#Database search
class User(UserMixin,db.Model):
id = db.Column(db.Integer,primary_key=True,autoincrement=True)
username = db.Column(db.String(200))
email = db.Column(db.String(200))
password = db.Column(db.String(200))
@login_manager.user_loader
def get(id):
return User.query.get(id)
#Pass encrypt
def encrypt(password):
hashed_pass=generate_password_hash(password)
return hashed_pass
#Page for login
@app.route('/login',methods=['GET'])
def get_login():
return render_template('login.html')
#Page for user creation (secured)
@app.route('/signup',methods=['GET'])
@login_required
def get_signup():
return render_template('signup.html')
#Page for login, adding user and logout
@app.route('/login',methods=['POST'])
def login_post():
email = request.form['email']
password = request.form['password']
user = User.query.filter_by(email=email).first()
if user and check_password_hash(user.password, password):
login_user(user)
return redirect('/')
return redirect('/')
@app.route('/signup',methods=['POST'])
@login_required
def signup_post():
username = request.form['username']
email = request.form['email']
password = encrypt(request.form['password'])
user = User(username=username,email=email,password=password)
try:
db.session.add(user)
db.session.commit()
flash(user+' added', category='success')
except Exception as e:
flash('Error on adding user :'+str(e), category='danger')
return redirect('param')
@app.route('/logout',methods=['GET'])
def logout():
logout_user()
return redirect('/login')
############################
## INDEX ##
############################
@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,vlxc=vlxc, vlibvirt=vlibvirt, vhype=vhype)
def get_ressources():
while True:
full = get_host_full()
json_data = json.dumps(
{
"time": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
"cpu_percent": full['cpu']['percent'],
"mem_percent": full['mem']['percent'],
"swap_percent": full['swap']['percent'],
"cpu_time_user": full['cpu']['time_user'],
"cpu_time_nice": full['cpu']['time_nice'],
"cpu_time_system": full['cpu']['time_system'],
"cpu_time_idle": full['cpu']['time_idle'],
"cpu_time_iowait": full['cpu']['time_iowait'],
"cpu_time_irq": full['cpu']['time_irq'],
"cpu_time_softirq": full['cpu']['time_softirq'],
"cpu_time_steal": full['cpu']['time_steal'],
"cpu_time_guest": full['cpu']['time_guest'],
"cpu_time_guest_nice": full['cpu']['time_nice'],
"mem_total": full['mem']['total'],
"mem_available": full['mem']['available'],
"mem_used": full['mem']['used'],
"mem_free": full['mem']['free'],
"mem_active": full['mem']['active'],
"mem_inactive": full['mem']['inactive'],
"mem_buffers": full['mem']['buffers'],
"mem_cached": full['mem']['cached'],
"mem_shared": full['mem']['shared'],
"mem_slab": full['mem']['slab'],
"swap_total": full['swap']['total'],
"swap_used": full['swap']['used'],
"swap_free": full['swap']['free'],
"swap_sin": full['swap']['sin'],
"swap_sout": full['swap']['sout'],
}
)
yield f"data:{json_data}\n\n"
time.sleep(1)
@app.route('/chart-ressources/')
def chart_data() -> Response:
response = Response(stream_with_context(get_ressources()), mimetype="text/event-stream")
response.headers["Cache-Control"] = "no-cache"
response.headers["X-Accel-Buffering"] = "no"
return response
############################
## POOL ##
############################
@app.route('/pool',methods=['GET'])
@login_required
def get_pool():
return render_template('pool.html',list_pool_full = get_full_pool())
@app.route('/del_volume',methods=['POST'])
@login_required
def delvol():
pool_name = request.form['pool_name']
volume_name = request.form['volume_name']
try:
del_pool_vol(pool_name,volume_name)
flash(volume_name+' deleted', category='success')
except Exception as e:
flash('Error on deleting '+volume_name+':'+str(e), category='danger')
return redirect(url_for('get_pool'))
############################
## NETWORK ##
############################
@app.route('/network',methods=['GET'])
@login_required
def network():
net_tree,net_na = get_virt_int()
return render_template('network.html', net_hard_int = conn.listInterfaces(), net_tree=net_tree, net_na=net_na)
@app.route('/delnetvm',methods=['POST'])
@login_required
def delnetvm():
vm_name = request.form['vm_name']
net_name = request.form['del_net_vm']
net_mac = request.form['del_mac_vm']
net_int = request.form['del_net_int']
try:
detach_net(vm_name, net_name, net_mac, net_int)
flash(net_name+' detached from '+vm_name, category='success')
except Exception as e:
flash('Error deleting '+net_name+' from '+vm_name+': '+str(e), category='danger')
return redirect(url_for('network'))
@app.route('/createnet',methods=['GET'])
@login_required
def createnet():
return render_template('createnet.html')
@app.route('/delnet',methods=['POST'])
@login_required
def delnet():
net_name = request.form['net_del']
net_int = get_int(net_name)
try:
delete_network(net_name,net_int)
flash(net_name+' deleted', category='success')
except Exception as e:
flash('Error on deleting '+net_name+':'+str(e), category='danger')
return redirect(url_for('network'))
@app.route('/createint',methods=['POST'])
@login_required
def createint():
net_name = request.form['net_name']
net_int = request.form['net_int']
ip_int = request.form['ip_int']
mask_int = request.form['mask_int']
min_dhcp = request.form['min_dhcp']
max_dhcp = request.form['max_dhcp']
nb_ip = diff_net(min_dhcp,max_dhcp)
try:
create_network(net_name,net_int)
except Exception as e:
flash('Error creating '+net_name+':'+str(e), category='danger')
delete_network(net_name,net_int)
return redirect(url_for('network'))
try:
cmd="ifconfig "+str(net_int)+" "+str(ip_int)+" netmask "+str(mask_int)+" up"
subprocess.call(cmd, shell=True)
except Exception as e:
flash('Error starting '+net_name+':'+str(e), category='danger')
delete_network(net_name,net_int)
return redirect(url_for('network'))
try:
cmd2="dnsmasq --interface="+str(net_int)+" --bind-interfaces --dhcp-range "+str(min_dhcp)+","+str(max_dhcp)+" --dhcp-lease-max="+str(nb_ip)+" --dhcp-authoritative --pid-file=/run/dhypecp_"+net_int+".pid"
subprocess.call(cmd2, shell=True)
except Exception as e:
flash("Error on DHCP for "+net_name,category='danger')
delete_network(net_name,net_int)
return redirect(url_for('network'))
flash(net_name+' had been created', category='success')
return redirect(url_for('network'))
############################
## 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']
is_active(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']
is_active(vm_name)
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']
is_active(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 ##
############################
@app.route('/vnc',methods=['GET','POST',"DELETE"])
@login_required
def vnc_connect():
if request.method=='GET':
resp = requests.get('http://localhost:6080/vnc.html')
excluded_headers = ['content-encoding', 'content-length', 'transfer-encoding', 'connection']
headers = [(name, value) for (name, value) in resp.raw.headers.items() if name.lower() not in excluded_headers]
response = Response(resp.content, resp.status_code, headers)
return response
elif request.method=='POST':
resp = requests.post('http://localhost:6080/vnc.html',json=request.get_json())
excluded_headers = ['content-encoding', 'content-length', 'transfer-encoding', 'connection']
headers = [(name, value) for (name, value) in resp.raw.headers.items() if name.lower() not in excluded_headers]
response = Response(resp.content, resp.status_code, headers)
return response
elif request.method=='DELETE':
resp = requests.delete('http://localhost:6080/vnc.html').content
response = Response(resp.content, resp.status_code, headers)
return response
@app.route('/console_lxc',methods=['GET','POST','DELETE'])
@login_required
def consolelxc():
lxc_name = request.form['lxc_name']
try:
pyxterm_connect(path,lxc_name)
time.sleep(2)
return render_template('terminal.html')
except Exception as e:
flash('Error starting Terminal :'+str(e), category='danger')
return redirect(url_for('state'))
@app.route('/ter',methods=['GET','POST',"DELETE"])
@login_required
def ter_connect():
if request.method=='GET':
resp = requests.get('http://localhost:5008/')
excluded_headers = ['content-encoding', 'content-length', 'transfer-encoding', 'connection']
headers = [(name, value) for (name, value) in resp.raw.headers.items() if name.lower() not in excluded_headers]
response = Response(resp.content, resp.status_code, headers)
return response
elif request.method=='POST':
resp = requests.post('http://localhost:5008/',json=request.get_json())
excluded_headers = ['content-encoding', 'content-length', 'transfer-encoding', 'connection']
headers = [(name, value) for (name, value) in resp.raw.headers.items() if name.lower() not in excluded_headers]
response = Response(resp.content, resp.status_code, headers)
return response
elif request.method=='DELETE':
resp = requests.delete('http://localhost:5008/').content
response = Response(resp.content, resp.status_code, headers)
return response
@app.route('/console_vm',methods=['POST'])
@login_required
def consolevm():
vm_name = request.form['vm_name']
is_active(vm_name)
try:
socket_connect(vm_name)
return render_template('vnc.html')
except Exception as e:
flash('Error starting VNC :'+str(e), category='danger')
return redirect(url_for('state'))
############################
## PARAMETERS ##
############################
def get_users():
users = User.query.all()
list_users=[]
for uni in users:
single=[]
single.append(uni.username)
single.append(uni.email)
list_users.append(single)
return list_users
@app.route('/param',methods=['GET'])
@login_required
def param():
return render_template('param.html',users_list = get_users())
@app.route('/deluser',methods=['POST'])
@login_required
def deluser():
username = request.form['username']
email = request.form['email']
try:
User.query.filter_by(username=username,email=email).delete()
db.session.commit()
flash(username+' deleted', category='success')
except Exception as e:
flash('Error on deleting '+username+':'+str(e), category='danger')
return redirect('param')
############################
## EDIT ##
############################
@app.route('/editlxc',methods=['POST'])
@login_required
def editlxc():
lxc_name = request.form['edit']
vcpu, mem, mem_max, swap_max = get_lxc_ressources(lxc_name)
return render_template('edit_lxc.html', lxc_name=str(lxc_name), max_Mermory=str(' '.join(mem_max)),max_vCPU=str(' '.join(vcpu)), max_swap=str(' '.join(swap_max)), actual_ram=str(' '.join(mem)))
@app.route('/editressourceslxc',methods=['POST'])
@login_required
def editressourceslxc():
lxc_name = str(request.form['lxc_name'])
vcpu, mem, mem_max, swap_max = get_lxc_ressources(lxc_name)
new_max_swap = request.form['new_max_swap']
new_max_mem = request.form['new_max_mem']
new_mem = request.form['new_mem']
new_cpu = request.form['new_cpu']
if new_max_swap != ' '.join(swap_max):
try:
lxc_item = 'lxc.cgroup2.memory.swap.max'
set_lxc_ressources(lxc_name,lxc_item,new_max_swap)
except Exception as e:
flash('Error editing Swap for '+lxc_name+': '+str(e), category='danger')
if new_max_mem != ' '.join(mem_max):
try:
lxc_item = 'lxc.cgroup2.memory.max'
set_lxc_ressources(lxc_name,lxc_item,new_max_mem)
except Exception as e:
flash('Error editing Max Memory for '+lxc_name+': '+str(e), category='danger')
if new_mem != ' '.join(mem):
try:
lxc_item = 'lxc.cgroup2.memory.high'
set_lxc_ressources(lxc_name,lxc_item,new_mem)
except Exception as e:
flash('Error editing Memory for '+lxc_name+': '+str(e), category='danger')
if new_cpu != ' '.join(vcpu):
try:
lxc_item = 'lxc.cgroup2.cpuset.cpus'
set_lxc_ressources(lxc_name,lxc_item,new_cpu)
except Exception as e:
flash('Error editing CPU for '+lxc_name+': '+str(e), category='danger')
return redirect(url_for('state'))
@app.route('/editvm',methods=['POST'])
@login_required
def edit():
vm_name = request.form['edit']
state, maxmem, mem, cpus, cput = get_info_vm(vm_name)
try:
screen_64=get_screenshot(vm_name).decode('ASCII')
except:
screen_64="/9j/4AAQSkZJRgABAQEAeAB4AAD/2wBDAAIBAQIBAQICAgICAgICAwUDAwMDAwYEBAMFBwYHBwcGBwcICQsJCAgKCAcHCg0KCgsMDAwMBwkODw0MDgsMDAz/2wBDAQICAgMDAwYDAwYMCAcIDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAz/wAARCAMABAADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwDLooor8XP4DCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA/9k="
# 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=screen_64,actual_autostart=get_autostart(vm_name),disks=get_disks_info(vm_name),list_net=conn.listNetworks(),vm_info=get_vm_infos(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=screen_64,actual_autostart=get_autostart(vm_name),disks=get_disks_info(vm_name),list_net=conn.listNetworks())
@app.route('/addnetvm',methods=['POST'])
@login_required
def addnetvm():
vm_name = request.form['vm_name']
new_net_vm = request.form['new_net_vm']
try:
attach_net(vm_name,new_net_vm)
flash(new_net_vm+' attached to '+vm_name, category='success')
except Exception as e:
flash('Error adding '+new_net_vm+' to '+vm_name+': '+str(e), category='danger')
return redirect(url_for('state'))
@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_autostart = request.form.get('new_autostart')
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')
if request.form.get('new_autostart')=='auto_check':
try:
set_autostart(vm_name)
except Exception as e:
flash('Error editing Autostart for '+vm_name+': '+str(e), category='danger')
else:
try:
unset_autostart(vm_name)
except Exception as e:
flash('Error editing Autostart for '+vm_name+': '+str(e), category='danger')
return redirect(url_for('state'))
############################
## ISO ##
############################
@app.route('/iso',methods=['GET'])
@login_required
def iso():
return render_template('iso.html', list_iso = get_iso_list(), list_vm = get_vm_list(), list_iso_mount = get_iso_list())
@app.route('/deliso',methods=['POST'])
@login_required
def delete_iso():
file=request.form['fichier']
path=os.path.join(iso_path, file)
try:
os.remove(path)
flash(file+' deleted', category='success')
except Exception as e:
flash('Error on deleting '+file+':'+str(e), category='danger')
return render_template('iso.html', list_iso = get_iso_list(), list_vm = get_vm_list(), list_iso_mount = get_iso_list())
@app.route('/mountiso', methods=['POST'])
@login_required
def mountiso():
vm_name=request.form['vm']
if request.form['iso'] == '':
iso_name = ''
else:
iso_name=iso_path+request.form['iso']
try:
mount_iso(vm_name,iso_name)
flash(iso_name+' mounted', category='success')
except Exception as e:
flash('Error on mounting '+iso_name+':'+str(e), category='danger')
return redirect(url_for('state'))
@app.route('/ejectiso', methods = ['POST'])
@login_required
def eject_iso():
vm_name=request.form['ejectisovm']
state = check_iso_is_mounted(vm_name)
while state != 0:
iso_file='';
mount_iso(vm_name,iso_name)
state = check_iso_is_mounted(vm_name)
@app.route('/iso', methods=['POST'])
@login_required
def upload_files():
uploaded_file = request.files['file']
filename = secure_filename(uploaded_file.filename)
if filename != '':
file_ext = os.path.splitext(filename)[1]
if file_ext not in app.config['UPLOAD_EXTENSIONS']:
return "Invalid image", 400
uploaded_file.save(os.path.join(app.config['UPLOAD_PATH'], filename))
return '', 204
############################
## BACKUP ##
############################
@app.route('/backup')
@login_required
def backup():
full_snap_lxc=[]
full_snap_vm=[]
for lxc_name in get_lxc_list():
if get_snap_list_lxc(lxc_name):
full_snap_lxc.append(get_snap_list_lxc(lxc_name))
else:
full_snap_lxc.append('')
for vm_name in get_vm_list():
if get_snap_list_vm(vm_name):
full_snap_vm.append(get_snap_list_vm(vm_name))
else:
full_snap_vm.append('')
list_snap_lxc = zip(get_lxc_list(), full_snap_lxc)
list_snap_vm = zip(get_vm_list(), full_snap_vm)
return render_template('backup.html',list_snap_lxc=list_snap_lxc,list_snap_vm=list_snap_vm)
@app.route('/snaplxc', methods = ['POST'])
@login_required
def snaplxc():
lxc_name=request.form['snap']
try:
create_snap_lxc(lxc_name)
flash('Snapshot '+lxc_name+' done', category='success')
except Exception as e:
flash('Error on snapshoting '+lxc_name+':'+str(e), category='danger')
return redirect(url_for('backup'))
@app.route('/del_snap_lxc', methods = ['POST'])
@login_required
def delsnaplxc():
lxc_name=request.form['lxc_name']
item=request.form['item']
try:
del_snap_lxc(lxc_name,item)
flash(item+' deleted', category='success')
except Exception as e:
flash('Error on deleting '+item+':'+str(e), category='danger')
return redirect(url_for('backup'))
@app.route('/rest_snap_lxc', methods = ['POST'])
@login_required
def restsnap_lxc():
lxc_name=request.form['lxc_name']
item=request.form['item']
try:
rest_snap_lxc(lxc_name,item)
flash('Restore '+item+' done', category='success')
except Exception as e:
flash('Error restoring '+item+':'+str(e), category='danger')
return redirect(url_for('backup'))
@app.route('/snapvm', methods = ['POST'])
@login_required
def snapvm():
vm_name=request.form['snap']
try:
create_snap_vm(vm_name)
flash('Snapshot '+vm_name+' done', category='success')
except Exception as e:
flash('Error on snapshoting '+vm_name+':'+str(e), category='danger')
return redirect(url_for('backup'))
@app.route('/del_snap_vm', methods = ['POST'])
@login_required
def delsnapvm():
vm_name=request.form['vm_name']
item=request.form['item']
try:
del_snap_vm(vm_name,item)
flash(item+' deleted', category='success')
except Exception as e:
flash('Error on deleting '+item+':'+str(e), category='danger')
return redirect(url_for('backup'))
@app.route('/rest_snap_vm', methods = ['POST'])
@login_required
def restsnap_vm():
vm_name=request.form['lxc_name']
item=request.form['item']
try:
rest_snap_vm(vm_name,item)
flash('Restore '+item+' done', category='success')
except Exception as e:
flash('Error restoring '+item+':'+str(e), category='danger')
return redirect(url_for('backup'))
############################
## BUILD ##
############################
@app.route('/build',methods=['GET'])
@login_required
def build_lxc():
return render_template('build.html', list_lxc_os=list_distrib(), list_profiles=get_os_profile_list(), list_net=conn.listNetworks(),list_iso = get_iso_list())
@app.route("/creation", methods=['POST'])
@login_required
def create_ct():
lxc_ip = request.form['ip']
try:
create_lxc(request.form['nom'],request.form['os'])
flash(request.form['nom']+' created', category='success')
except Exception as e:
flash('Error on creating '+request.form['nom']+':'+str(e), category='danger')
if lxc_ip:
set_lxc_ip(lxc_ip)
return redirect(url_for('state'))
@app.route('/creationvm', methods=['POST'])
@login_required
def create_VM():
#VNC Version
nom = request.form['vm_name']
ram = request.form['ram']
cpu = request.form['cpu']
ose = request.form['os']
iso = request.form['iso']
iso = iso_path+iso
net = request.form['net']
disk = request.form['disk']
opt = ''
ostype = 'linux'
####################################
## WINDOWS ##
####################################
if ose.startswith('win'):
try:
cmd = "qemu-img create -f qcow2 "+str(disk_path)+str(nom)+".qcow2 "+str(disk)+"G"
subprocess.call(cmd, shell=True)
except Exception as e:
flash('Error on creating '+str(nom)+':'+str(e),category='danger')
return redirect(url_for('state'))
opt = " --disk path="+virtuo_path+virtuo_file+",device=cdrom"
ostype = 'windows'
creationcmd='--name '+str(nom)+' --ram '+str(ram)+' --disk path='+str(disk_path)+str(nom)+'.qcow2,bus=virtio,format=qcow2 --vcpus '+str(cpu)+' --os-type '+str(ostype)+' --os-variant '+str(ose)+' --network network:'+str(net)+' --graphics vnc,listen=0.0.0.0 --noautoconsole --console pty,target_type=serial '+opt+' --cdrom '+str(iso)+' --force --debug '
else:
creationcmd='--name '+str(nom)+' --ram '+str(ram)+' --disk path='+str(disk_path)+str(nom)+'.qcow2,size='+str(disk)+',bus=virtio --vcpus '+str(cpu)+' --os-type '+str(ostype)+' --os-variant '+str(ose)+' --network network:'+str(net)+' --graphics vnc,listen=0.0.0.0 --noautoconsole --console pty,target_type=serial '+opt+' --cdrom '+str(iso)+' --force --debug '
try:
os.system('virt-install '+creationcmd+' ')
flash(str(nom)+' created', category='success')
except Exception as e:
flash('Error on creating '+str(nom)+':'+str(e),category='danger')
return redirect(url_for('state'))
############################
## STATE ##
############################
@app.route('/state',methods=['GET'])
@login_required
def state():
ips_lxc=[]
for lxc_name in get_lxc_activ():
ips_lxc.append(get_lxc_ip(lxc_name))
activ_lxc=zip(get_lxc_activ(),ips_lxc)
state_act_vm = []
ips_vm = []
for vm_name in get_vm_activ():
state_act_vm.append(check_iso_is_mounted(vm_name))
ips_vm.append(get_vm_ips(vm_name))
activ_vm=zip(get_vm_activ(),state_act_vm,ips_vm)
state_inact_vm = []
for vm_name in get_vm_inactiv():
state_inact_vm.append(check_iso_is_mounted(vm_name))
inactiv_vm=zip(get_vm_inactiv(),state_inact_vm)
return render_template('state.html', activ_vm=activ_vm, inactiv_vm=inactiv_vm,activ_lxc=activ_lxc,inactiv_lxc=get_lxc_inactiv())
############################
## LXC ##
############################
@app.route('/start_lxc',methods=['POST'])
@login_required
def startct():
lxc_name = request.form['start']
try:
start_lxc(lxc_name)
flash(lxc_name+' started', category='success')
except Exception as e:
flash('Error starting '+lxc_name+':'+str(e), category='danger')
return redirect(url_for('state'))
@app.route('/stop_lxc',methods=['POST'])
@login_required
def stopct():
lxc_name = request.form['stop']
try:
stop_lxc(lxc_name)
flash(lxc_name+' stoped', category='success')
except Exception as e:
flash('Error stoping '+lxc_name+':'+str(e), category='danger')
return redirect(url_for('state'))
@app.route('/destroy_lxc',methods=['POST'])
@login_required
def destroyct():
lxc_name = request.form['destroy']
try:
destroy_lxc(lxc_name)
flash(lxc_name+' destroyed', category='success')
except Exception as e:
flash('Error destroying '+lxc_name+':'+str(e), category='danger')
return redirect(url_for('state'))
############################
## VM ##
############################
@app.route('/start_vm',methods=['POST'])
@login_required
def startvm():
vm_name = request.form['start']
try:
start_vm(vm_name)
flash(vm_name+' started', category='success')
except Exception as e:
flash('Error starting '+vm_name+':'+str(e), category='danger')
return redirect(url_for('state'))
@app.route('/stop_vm',methods=['POST'])
@login_required
def stopvm():
vm_name = request.form['stop']
try:
stop_vm(vm_name)
flash(vm_name+' stoped', category='success')
except Exception as e:
flash('Error stoping '+vm_name+':'+str(e), category='danger')
return redirect(url_for('state'))
@app.route('/destroy_vm',methods=['POST'])
@login_required
def destroyvm():
vm_name = request.form['destroy']
try:
destroy_vm(vm_name)
flash(vm_name+' destroyed', category='success')
except Exception as e:
flash('Error destroying '+vm_name+':'+str(e), category='danger')
return redirect(url_for('state'))
############################
## LOGIN ##
############################
#Self certificate page
if __name__=='__main__':
# atexit.register(cleanup)
app.run(host=flask_config.host, port=flask_config.port, threaded=flask_config.thread, debug=flask_config.debug, ssl_context='adhoc')