diff --git a/app.py b/app.py index 6365409..3f25e35 100644 --- a/app.py +++ b/app.py @@ -190,8 +190,23 @@ def delvol(): @app.route('/network',methods=['GET']) @login_required def network(): - net_hard_int,net_tree,net_na = list_network_VM() - return render_template('network.html', net_hard_int =net_hard_int, net_tree=net_tree, net_na=net_na) + 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 @@ -293,6 +308,7 @@ def detachdisk(): flash('Error Detaching '+disk_name+' on '+vm_name+':'+str(e), category='danger') return redirect(url_for('state')) + ############################ ## VNC ## ############################ @@ -405,7 +421,6 @@ def editlxc(): 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))) -#TEST @app.route('/editressourceslxc',methods=['POST']) @login_required def editressourceslxc(): @@ -441,8 +456,6 @@ def editressourceslxc(): 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(): @@ -451,10 +464,20 @@ def edit(): try: screen_64=get_screenshot(vm_name).decode('ASCII') except: - #Green screen 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)) + 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 @@ -474,7 +497,6 @@ def editressources(): 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: set_autostart(vm_name) @@ -687,10 +709,8 @@ def create_VM(): 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:bridged --graphics vnc,listen=0.0.0.0 --noautoconsole --console pty,target_type=serial '+opt+' --cdrom '+str(iso)+' --force --debug ' 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:bridged --graphics vnc,listen=0.0.0.0 --noautoconsole --console pty,target_type=serial '+opt+' --cdrom '+str(iso)+' --force --debug ' 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+' ') diff --git a/functions/__pycache__/fbackup.cpython-311.pyc b/functions/__pycache__/fbackup.cpython-311.pyc deleted file mode 100644 index 42889b0..0000000 Binary files a/functions/__pycache__/fbackup.cpython-311.pyc and /dev/null differ diff --git a/functions/__pycache__/fdisks.cpython-311.pyc b/functions/__pycache__/fdisks.cpython-311.pyc deleted file mode 100644 index d418a19..0000000 Binary files a/functions/__pycache__/fdisks.cpython-311.pyc and /dev/null differ diff --git a/functions/__pycache__/fedit.cpython-311.pyc b/functions/__pycache__/fedit.cpython-311.pyc deleted file mode 100644 index ab64183..0000000 Binary files a/functions/__pycache__/fedit.cpython-311.pyc and /dev/null differ diff --git a/functions/__pycache__/fhost.cpython-311.pyc b/functions/__pycache__/fhost.cpython-311.pyc deleted file mode 100644 index 4267b91..0000000 Binary files a/functions/__pycache__/fhost.cpython-311.pyc and /dev/null differ diff --git a/functions/__pycache__/fiso.cpython-311.pyc b/functions/__pycache__/fiso.cpython-311.pyc deleted file mode 100644 index caaf660..0000000 Binary files a/functions/__pycache__/fiso.cpython-311.pyc and /dev/null differ diff --git a/functions/__pycache__/flxc.cpython-311.pyc b/functions/__pycache__/flxc.cpython-311.pyc deleted file mode 100644 index 95e5506..0000000 Binary files a/functions/__pycache__/flxc.cpython-311.pyc and /dev/null differ diff --git a/functions/__pycache__/fnet.cpython-311.pyc b/functions/__pycache__/fnet.cpython-311.pyc deleted file mode 100644 index 5193f19..0000000 Binary files a/functions/__pycache__/fnet.cpython-311.pyc and /dev/null differ diff --git a/functions/__pycache__/fpool.cpython-311.pyc b/functions/__pycache__/fpool.cpython-311.pyc deleted file mode 100644 index 7096c5e..0000000 Binary files a/functions/__pycache__/fpool.cpython-311.pyc and /dev/null differ diff --git a/functions/__pycache__/fscreen.cpython-311.pyc b/functions/__pycache__/fscreen.cpython-311.pyc deleted file mode 100644 index dda9a78..0000000 Binary files a/functions/__pycache__/fscreen.cpython-311.pyc and /dev/null differ diff --git a/functions/__pycache__/fvm.cpython-311.pyc b/functions/__pycache__/fvm.cpython-311.pyc deleted file mode 100644 index f9de3ba..0000000 Binary files a/functions/__pycache__/fvm.cpython-311.pyc and /dev/null differ diff --git a/functions/__pycache__/fvnc.cpython-311.pyc b/functions/__pycache__/fvnc.cpython-311.pyc deleted file mode 100644 index 3932b2c..0000000 Binary files a/functions/__pycache__/fvnc.cpython-311.pyc and /dev/null differ diff --git a/functions/fedit.py b/functions/fedit.py index cade4bb..c827e71 100644 --- a/functions/fedit.py +++ b/functions/fedit.py @@ -1,4 +1,5 @@ from config import * +from functions.fnet import * import base64 import time import lxc @@ -65,7 +66,18 @@ def get_info_vm(vm_name): state, maxmem, mem, cpus, cput = dom.info() return state, maxmem, mem, cpus, cput -#Screenshot +def attach_net(vm_name,net_name): + dom = conn.lookupByName(vm_name) + network_xml = f'' + dom.attachDeviceFlags(network_xml, libvirt.VIR_DOMAIN_AFFECT_CONFIG | libvirt.VIR_DOMAIN_AFFECT_LIVE) + +def detach_net(vm_name, net_name, net_mac,net_int): + dom = conn.lookupByName(vm_name) +# network_xml = f'' + network_xml = f'' + print(network_xml) + dom.detachDeviceFlags(network_xml, libvirt.VIR_DOMAIN_AFFECT_CONFIG | libvirt.VIR_DOMAIN_AFFECT_LIVE) + def get_screenshot(vm_name): dom = conn.lookupByName(vm_name) stream = conn.newStream() @@ -83,8 +95,6 @@ def get_screenshot(vm_name): os.remove(file) return data -#Autostart - def get_autostart(vm_name): dom = conn.lookupByName(vm_name) return dom.autostart() @@ -97,3 +107,12 @@ def unset_autostart(vm_name): dom = conn.lookupByName(vm_name) dom.setAutostart(0) +""" +def get_net_vm(vm_name): + netws, nu2 = get_virt_int() + vm_net_list=[] + for net in netws: + if vm_name in net[1][0]: + vm_net_list.append(net[0][0][0]) + return vm_net_list +""" diff --git a/functions/fedit.py.ori b/functions/fedit.py.ori deleted file mode 100644 index cade4bb..0000000 --- a/functions/fedit.py.ori +++ /dev/null @@ -1,99 +0,0 @@ -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 - - -def set_memory(vm_name,memory_new): - dom = conn.lookupByName(vm_name) - 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.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() - imageType = dom.screenshot(stream,0) - file = "tmp_screen_" + dom.name() - fileHandler = open(file, 'wb') - streamBytes = stream.recv(262120) - while streamBytes != b'': - fileHandler.write(streamBytes) - streamBytes = stream.recv(262120) - fileHandler.close() - stream.finish() - with open(file, "rb") as f: - 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/fnet.py b/functions/fnet.py index a5b5ed0..f6fec25 100644 --- a/functions/fnet.py +++ b/functions/fnet.py @@ -2,6 +2,35 @@ from app import * import ipaddress from xml.dom import minidom + +def ip_fom_mac(vm_name,net_mac): + dom=conn.lookupByName(vm_name) + mac_ip=[] + try: + ifaces = dom.interfaceAddresses(libvirt.VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_AGENT) + except: + ifaces = None + result="---.---.---.---" + + if ifaces is None: + result="---.---.---.---" + else: + for (name, val) in ifaces.items(): + if val['addrs']: + for addr in val['addrs']: + if addr['addr']: + mac_ip.append([val['hwaddr'],addr['addr']]) + break + else: + result = "---.---.---.---" + for int in mac_ip: + if int[0] == net_mac: + result=int[1] + else: + result = "---.---.---.---" + return result + + def diff_net(min_dhcp,max_dhcp): ip1 = ipaddress.IPv4Address(min_dhcp) ip2 = ipaddress.IPv4Address(max_dhcp) @@ -43,28 +72,44 @@ def create_network(net_name,net_int): net_use.create() net_use.setAutostart(True) -def list_network_VM(): - net_tree = [] - net_na = [] -#Host Interfaces - net_hard_int = conn.listInterfaces() -#Virtual Interfaces - net_list = conn.listAllNetworks() - for net_name in net_list: - if net_name.isActive(): - net_sub_tree=[] - net_sub_tree.append(net_name.name()) - net_use = conn.networkLookupByName(net_name.name()) - ports = net_use.listAllPorts() - net_ports = [] - for port in ports: - raw_xml = port.XMLDesc() - net_xml = minidom.parseString(raw_xml) - net_element = net_xml.documentElement - net_VM = net_element.getElementsByTagName("name")[0] - net_ports.append(net_VM.firstChild.data) - net_sub_tree.append(net_ports) - net_tree.append(net_sub_tree) - else: - net_na.append(net_name.name()) - return net_hard_int,net_tree,net_na +def get_mac_net(vm_name,net_name): + dom = conn.lookupByName(vm_name) + raw_xml = dom.XMLDesc() + net_xml = minidom.parseString(raw_xml) + VM_mac = [] + for device in net_xml.getElementsByTagName('devices'): + ifaces = device.getElementsByTagName('interface') + for iface in ifaces: + sources = iface.getElementsByTagName('source') + for source in sources: + if source.getAttribute('network') == net_name: + mac = iface.getElementsByTagName('mac') + target = iface.getElementsByTagName('target') + ip = ip_fom_mac(vm_name,str(mac[0].getAttribute('address'))) + VM_mac.append([target[0].getAttribute('dev'),mac[0].getAttribute('address'),ip]) + return VM_mac + +def get_virt_int(): + net_na = [] + out=[] + for network in conn.listAllNetworks(): + if network.isActive(): + int_name=[] + int_mac = conn.interfaceLookupByName(network.bridgeName()) + int_name.append([network.name(),network.bridgeName(),int_mac.MACString()]) + net_detail = conn.networkLookupByName(network.name()) + net_vms = net_detail.listAllPorts() + vm_name=[] + for vm in net_vms: + net_VM_info = [] + raw_xml = vm.XMLDesc() + net_xml = minidom.parseString(raw_xml) + net_element = net_xml.documentElement + net_VM = net_element.getElementsByTagName("name")[0] + net_VM_info = [net_VM.firstChild.data,get_mac_net(net_VM.firstChild.data,network.name())] + if net_VM_info not in vm_name: + vm_name.append(net_VM_info) + out.append([int_name,vm_name]) + else: + net_na.append(network.name()) + return out, net_na diff --git a/templates/edit.html b/templates/edit.html index e896f2b..b09fa99 100644 --- a/templates/edit.html +++ b/templates/edit.html @@ -109,6 +109,31 @@ +
+
+
+ Networking for {{ vm_name }} +
+
+ Attach new network
+
+
+
+ + +
+ +
+
+
+ +
+
+ {% endblock %} diff --git a/templates/network.html b/templates/network.html index f1de0d4..07fda18 100644 --- a/templates/network.html +++ b/templates/network.html @@ -29,15 +29,33 @@ Virtual Interfaces: {% endfor %} {% for item in net_tree %}
  • - {{ item[0] }} +
    + {{ item[0][0][0] }} - {{ item[0][0][1] }} - {{ item[0][0][2] }} +
    - - -

    + + + +
    diff --git a/templates/network.html.ori b/templates/network.html.ori deleted file mode 100644 index 4ba5f5c..0000000 --- a/templates/network.html.ori +++ /dev/null @@ -1,56 +0,0 @@ -{% extends 'layout.html' %} -{% block content %} -{% include 'menu.html' %} - -
    -
    -
    - {% for pint in net_hard_int %} - {{ pint }}
    - {% endfor %} -
    -
    -
    -
    -
    -graph TD -{% for item in net_tree %} -root[Root] --- {{ item[0] }}[{{ item[0] }}] -{% for sub_item in item[1] %} -{{ item[0] }}[{{ item[0] }}] --- {{ sub_item }}[{{ sub_item }}] -{% endfor %} -{% endfor %} -
    -
    -
    -
    - -{% endblock %}