| + + | +名称 | +状态 | +CPU | +内存 | +操作 | +
|---|
diff --git a/Tools/qemu/OVMF_CODE.fd b/Tools/qemu/OVMF_CODE.fd new file mode 100644 index 0000000..ab81b1c Binary files /dev/null and b/Tools/qemu/OVMF_CODE.fd differ diff --git a/server/qemu/Package.py b/server/qemu/Package.py new file mode 100755 index 0000000..0bc3398 --- /dev/null +++ b/server/qemu/Package.py @@ -0,0 +1,153 @@ +# coding=utf-8 +#!/bin/python +#cding=utf-8 +# encoding=utf8 + +import os +import sys +import platform + +name = "qemu" +Version = "V0.1" + +rul = "https://jiang144.i234.me/data/jcm" + +def progress_bar( nb_traits,name,d,prin,new_client_socket): + prin(new_client_socket,('\r' + name + d + ' : Downloading [').encode("utf-8")) + for i in range(0, nb_traits): + if i == nb_traits - 1: + prin(new_client_socket,'>'.encode("utf-8")) + else: + prin(new_client_socket,'='.encode("utf-8")) + for i in range(0, 49 - nb_traits): + prin(new_client_socket,' '.encode("utf-8")) + prin(new_client_socket,']'.encode("utf-8")) + +def down(rul,dir,d,prin,new_client_socket): + import requests + prin(new_client_socket,(dir.split('/')[-1] + d + ' : Downloading...').encode("utf-8")) + + bresp = requests.get(rul, stream=True, verify=False) + if (bresp.status_code != 200): # When the layer is located at a custom URL + if(bresp.status_code == 404): + prin(new_client_socket,('\rERROR: Cannot download layer {} [HTTP {}]'.format(dir.split('/')[-1], bresp.status_code, "")).encode("utf-8")) + prin(new_client_socket,(str(bresp.content)).encode("utf-8")) + return + bresp = requests.get(layer['urls'][0], headers=auth_head, stream=True, verify=False) + if (bresp.status_code != 200): + prin(new_client_socket,('\rERROR: Cannot download layer {} [HTTP {}]'.format(dir.split('/')[-1], bresp.status_code, bresp.headers['Content-Length'])).encode("utf-8")) + prin(new_client_socket,(str(bresp.content)).encode("utf-8")) + return + #exit(1) + # Stream download and follow the progress + bresp.raise_for_status() + unit = int(bresp.headers['Content-Length']) / 50 + acc = 0 + nb_traits = 0 + progress_bar( nb_traits,dir.split('/')[-1],d,prin,new_client_socket) + with open(".out/" + name + "_" + Version + ".pkg/" + dir.split("/")[-1], "wb") as file: + for chunk in bresp.iter_content(chunk_size=8192): + if chunk: + file.write(chunk) + acc = acc + 8192 + if acc > unit: + nb_traits = nb_traits + 1 + progress_bar( nb_traits,dir.split('/')[-1],d,prin,new_client_socket) + acc = 0 + prin(new_client_socket,("\r{}".format(dir.split('/')[-1]) + d + " : Extracting...{}".format(" "*50)).encode("utf-8")) # Ugly but works everywhere + os.rename(".out/" + name + "_" + Version + ".pkg/" + dir.split("/")[-1],dir) + + prin(new_client_socket,("\r{}".format(dir.split('/')[-1]) + d + " : Pull complete [{}]".format(bresp.headers['Content-Length'])).encode("utf-8")) + +def install(new_client_socket,post,Versino,Headers,info,prin): + pkg="" + try: + fs = open("server/server.ini", "rb") + pkg = fs.read().decode("utf-8").split('\n') + except Exception as e: + prin(new_client_socket,(e.args).encode("utf-8")) + inpkg = "install" + for i in pkg: + if i.split('\r')[0] == name: + inpkg = "" + prin(new_client_socket,("install " + name + " " + Version + "\n\r").encode("utf-8")) + prin(new_client_socket,("系统类型 " + platform.system() + " \n\r").encode("utf-8")) + prin(new_client_socket,("系统架构 " + platform.machine() + " \n\r").encode("utf-8")) + gz = platform.machine() + os.system("cp -rf .out/" + name + "_" + Version + ".pkg/.out/* ./") + if platform.system() == "Windows": + pkg = '' + else: + if os.path.exists("/bin/apt"): + os.system("apt-get install -y qemu-kvm") + os.system("apt-get install -y virt-manager") + os.system("apt-get install -y libvirt-daemon-system") + os.system("apt-get install -y virtinst") + os.system("apt-get install -y libvirt-clients") + else: + prin(new_client_socket,("安装脚本不支持此架构 " + platform.machine() + " \n\r").encode("utf-8")) + return + + if inpkg == "install": + os.system("echo " + name + ">>server/server.ini") + #prin(new_client_socket,("END\n\r").encode("utf-8")) + os.system("rm -rf .out/" + name + "_" + Version + ".pkg") + +def remove(): + os.system("rm -rf server/" + name) + os.system("rm -rf web/" + name) +def out(): + os.system("cp -rf web/Ace_Admin/" + name + " .out/web/Ace_Admin/") + os.system("cp -rf server/" + name + " .out/server/") + + rm('.out/server/','__pycache__') + +# os.system("find .out/ -name __pycache__") +def rm(dir,name): + path = os.listdir(dir) + for p in path: + if os.path.isdir(dir + p): + if p == name: + os.system("rm -rf " + dir + name) + else: + rm(dir + p + '/',name) +def info(): + data = {} + #文件夹名称 + data["Package"] = name + #首选名称 + data["names"] = "QEMU" + #多国语言翻译 + data["namei"] = {} + data["namei"]["zh-CN"] = "QEMU".encode("utf-8") + #版本 + data["Version"] = Version + #依赖 + data["Depends"] = "main" + #License + data["License"] = "GPL-2.0" + #首选解释 + data["Description"] = "QEMU 虚拟机" + #多国语言翻译 + data["Descriptions"] = {} + data["Descriptions"]["zh-CN"] = "QEMU 虚拟机".encode("utf-8") + #库名称 + data["issued"] = "pkg" + + return data + +def pri(new_client_socket,p): + print(p.decode("utf-8"),end='') + +if __name__ == "__main__": + if len(sys.argv) == 1: + sys.argv = sys.argv[0],"install" + + if sys.argv[1] == "install": + install('','','','','',pri) + elif sys.argv[1] == "remove": + remove() + elif sys.argv[1] == "out": + out() + else: + info() \ No newline at end of file diff --git a/server/qemu/api/api.py b/server/qemu/api/api.py new file mode 100644 index 0000000..9e5794b --- /dev/null +++ b/server/qemu/api/api.py @@ -0,0 +1,336 @@ +# coding=utf-8 +#!/bin/python +import os +import sys +import imp +import time +import socket +import psutil +import threading +from configparser import ConfigParser + +def catinfo(conf,section,option): + if conf.has_section(section): + if conf.has_option(section, option): + return conf[section][option] + return '' + +def setinfo(conf,section,option,value): + if conf.has_section(section) == False: + conf.add_section(section) + conf.set(section, option, value) + +def catio(): + global qemu_jcm_io + io = os.popen("top -n 2 | grep 'wa,' | awk '{print $10}'").read() + qemu_jcm_io = io.split("\n") + +def main(data): + global qemu_jcm_io + new_client_socket = data["new_client_socket"] + RUL_CS = data["RUL_CS"] + post_data = data["post_data"] + Headers = data["Headers"] + info = data["info"] + user = data["user"] + + type = "" + res = "" + post = RUL_CS + for i in post: + tmp = i.split('=') + if tmp[0] == 'type': + type = tmp[1] + res = '{"data":"ERROR"}' + + if type == "run": + res = '{' + re = "" + p1 = threading.Thread(target=catio,args=()) + p1.start() + #io = os.popen("top -n 2 | grep 'wa,' | awk '{print $10}'").read() + fo = 0 + list = os.listdir(".config/qemu/config/") + for i in list: + fo = fo + 1 + conf = ConfigParser() + conf.read(".config/qemu/config/" + i + "") + dir = catinfo(conf,"qemu","qemu_dir") + name = dir.split("/")[-1] + if not os.path.exists(dir + "/qemu.ini"): + re += '{"name":"' + name + '","api":"0","cpu":"0","ram":"0","soket":"qemu_' + name + '"},' + else: + if not os.path.exists("/run/jcm/qemu/pid/" + name + ".pid"): + re += '{"name":"' + name + '","api":"1","cpu":"0","ram":"0","soket":"qemu_' + name + '"},' + else: + pid = open("/run/jcm/qemu/pid/" + name + ".pid","r").read() + p = psutil.Process(int(pid)) + cpu = p.cpu_percent() + time.sleep(0.1) + cpu = p.cpu_percent() + cpu = str(cpu)[:5] + ram = p.memory_info() + ram = ram.rss / 1024 / 1024 + rams = 0 + conf.read(dir + "/qemu.ini") + value = catinfo(conf,"qemu","qemu_ram") + if value[-1] == 'g' or value[-1] == 'G': + rams += int(value[:-1]) + elif value[-1] == 'm' or value[-1] == 'M': + rams += int(value[:-1]) + else: + rams += int(value) + #ram = str(ram)[:5] + ram = '{:.2%}'.format(ram/rams)[:-1] + re += '{"name":"' + name + '","api":"2","cpu":"' + cpu + '","ram":"' + ram + '","soket":"qemu_' + name + '"},' + res += '"fo":"' + str(fo) + '",' + res += '"data":[' + re[:-1] + '],' + #p1.join() + io = qemu_jcm_io + cpu = str(psutil.cpu_percent(None)) + ram = str(psutil.virtual_memory().percent) + if int(io[0].split(".")[0]) < int(io[1].split(".")[0]): + io[0] = io[1] + res += '"cpu":"' + str(cpu) + '",' + res += '"ram":"' + str(ram) + '",' + res += '"io":"' + str(io[0]) + '"' + #for i in io: + res += '}' + elif type == "stop": + name = "" + post = RUL_CS + for i in post: + tmp = i.split('=') + if tmp[0] == 'name': + name = tmp[1] + if os.path.exists("/run/jcm/qemu/qmp/" + name + ".qmp"): + qmp = socket.socket(family=socket.AF_UNIX,type=socket.SOCK_STREAM) + qmp.connect("/run/jcm/qemu/qmp/" + name + ".qmp") + time.sleep(0.5) + data = qmp.recv(102400) + qmp.send(b'{"execute":"qmp_capabilities"}') + time.sleep(0.5) + data = qmp.recv(102400) + qmp.send(b'{ "execute": "system_powerdown" }') + data = qmp.recv(102400) + qmp.close() + res = '{"data":"正在关机"}' + elif type == "kill": + name = "" + post = RUL_CS + for i in post: + tmp = i.split('=') + if tmp[0] == 'name': + name = tmp[1] + if os.path.exists("/run/jcm/qemu/pid/" + name + ".pid"): + pid = open("/run/jcm/qemu/pid/" + name + ".pid","r").read() + data = os.popen("kill " + pid).read() + if data == "": + data = "成功" + res = '{"data":"' + data + '"}' + elif type == "addpost": + data = {} + qemu_name = "" + qemu_smp = "" + qemu_ram = "" + qemu_disk = "" + try: + for i in post: + tmp = i.split('=') + data[tmp[0]] = tmp[1] + if tmp[0] == 'qemu_name': + qemu_name = tmp[1] + if tmp[0] == 'qemu_smp': + qemu_smp = tmp[1] + if tmp[0] == 'qemu_ram': + qemu_ram = tmp[1] + if tmp[0] == 'qemu_disk': + qemu_disk = tmp[1] + if os.path.exists(".config/qemu") == False: + os.mkdir(".config/qemu") + if os.path.exists(".config/qemu/config") == False: + os.mkdir(".config/qemu/config") + if os.path.exists(".config/qemu/config/" + qemu_name + ".ini"): + res = '{"data":"存在此名称的虚拟机"}' + else: + res = "" + try: + if qemu_ram[-1] == "m" or qemu_ram[-1] == "M" or qemu_ram[-1] == "G" or qemu_ram[-1] == "g": + ram = int(qemu_ram[:-1]) + else: + ram = int(qemu_ram) + except Exception as e: + res = '{"data":"' + "RAM is ERROR" + '"}' + try: + smp = int(qemu_smp) + except Exception as e: + res = '{"data":"' + "SMP is ERROR" + '"}' + + try: + if qemu_disk == "": + disk = 0 + elif qemu_disk[-1] == "m" or qemu_disk[-1] == "M" or qemu_disk[-1] == "G" or qemu_disk[-1] == "g": + disk = int(qemu_disk[:-1]) + else: + disk = int(qemu_disk) + except Exception as e: + res = '{"data":"' + "DISK is ERROR" + '"}' + + if res == "": + conf = ConfigParser() + conf.read(".config/qemu/config/" + qemu_name + ".ini") + setinfo(conf,"qemu","qemu_dir",data["qemu_dir"]) + dir = "" + for i in data["qemu_dir"].split("/")[1:]: + dir = dir + "/" + i + if not os.path.exists(dir): + os.mkdir(dir) + with open(".config/qemu/config/" + qemu_name + ".ini", 'w', encoding='utf-8') as file: + conf.write(file) # 值写入配置文件 + if not os.path.exists(dir + "/qemu.ini"): + conf = ConfigParser() + conf.read(dir + "/qemu.ini") + setinfo(conf,"qemu","qemu_name",data["qemu_name"]) + setinfo(conf,"qemu","qemu_dir",data["qemu_dir"]) + setinfo(conf,"qemu","qemu_smp",data["qemu_smp"]) + setinfo(conf,"qemu","qemu_ram",data["qemu_ram"]) + if disk != 0: + setinfo(conf,"qemu_sata_0","qemu_disk",data["qemu_disk"]) + setinfo(conf,"qemu_sata_0","qemu_boot","") + os.system("qemu-img create -fqcow2 " + data["qemu_dir"] + "/" + data["qemu_name"] + ".qcow2 " + data["qemu_disk"]) + with open(dir + "/qemu.ini", 'w', encoding='utf-8') as file: + conf.write(file) # 值写入配置文件 + + res = '{"data":"' + "成功" + '"}' + else: + res = '{"data":"' + "存在虚拟机,注册" + '"}' + + + except Exception as e: + res = '{"data":"' + e.args[0] + '"}' + elif type == "start": + dir = "" + name = "" + post = RUL_CS + for i in post: + tmp = i.split('=') + if tmp[0] == 'name': + name = tmp[1] + conf = ConfigParser() + conf.read(".config/qemu/config/" + name + ".ini") + dir = catinfo(conf,"qemu","qemu_dir") + if not os.path.exists(dir + "/qemu.ini"): + res = '{"data":"' + '没找到虚拟机文件' + '"}' + else: + if not os.path.exists("/run"): + os.mkdir("/run") + if not os.path.exists("/run/jcm"): + os.mkdir("/run/jcm") + if not os.path.exists("/run/jcm/qemu"): + os.mkdir("/run/jcm/qemu") + if not os.path.exists("/run/jcm/qemu/qmp"): + os.mkdir("/run/jcm/qemu/qmp") + if not os.path.exists("/run/jcm/qemu/vnc"): + os.mkdir("/run/jcm/qemu/vnc") + if not os.path.exists("/run/jcm/qemu/pid"): + os.mkdir("/run/jcm/qemu/pid") + conf.read(dir + "/qemu.ini") + value = "" + cmd = "qemu-system-x86_64 -enable-kvm -cpu host " + value = catinfo(conf,"qemu","qemu_name") + cmd += " -name " + value + value = catinfo(conf,"qemu","qemu_smp") + cmd += " -smp " + value + value = catinfo(conf,"qemu","qemu_ram") + if value[-1] == 'g' or value[-1] == 'G': + value = value + elif value[-1] == 'm' or value[-1] == 'M': + value = value + else: + value += 'M' + cmd += " -m " + value + + + cmd += "\ + -device pci-bridge,id=pci.1,chassis_nr=1,bus=pci.0,addr=0x1e \ + -device pci-bridge,id=pci.2,chassis_nr=2,bus=pci.0,addr=0x1f \ + -device pci-bridge,id=pci.3,chassis_nr=3,bus=pci.0,addr=0x5 " + + value = catinfo(conf,"qemu","qemu_uefi") + if value == 'True': + uefidir = info["dir"] + uefidir = uefidir + "/Tools/qemu/OVMF_CODE.fd" + cmd += " -boot order=dc,menu=on,strict=on,reboot-timeout=1000" + cmd += " -drive if=pflash,unit=0,format=raw,readonly=on,file=" + uefidir + value = catinfo(conf,"qemu","qemu_usb") + if value == '3.0': + cmd += " -device qemu-xhci,p2=15,p3=15,id=xhci,bus=pci.1,addr=0x1b" + + sata = "" + data = conf.sections() + for d in data: + if d != "qemu": + d = d.split('_') + if d[1] == "sata": + bootino = catinfo(conf,d[0] + "_" + d[1] + "_" + d[2],"qemu_boot") + if sata == "": + cmd += " -device ahci,id=ahci0,multifunction=on,bus=pci.0,addr=0x7" + sata = "0" + cmd += " -device ide-hd,bus=ahci0." + d[2] + ",drive=drive-sata" + d[2] + ",id=sata" + d[2] + "" + diskdir = catinfo(conf,d[0] + "_" + d[1] + "_" + d[2],"qemu_dir") + if diskdir == '': + diskdir = dir + '/' + name + '.qcow2' + disklist = "qcow2" + cmd += " -drive file=" + diskdir + ",if=none,format=" + disklist + ",id=drive-sata" + d[2] + "" + else: + diskdisk = catinfo(conf,d[0] + "_" + d[1] + "_" + d[2],"qemu_disk") + if diskdisk == "disk": + disklist = "raw" + cmd += " -drive file=" + diskdir + ",if=none,format=" + disklist + ",id=drive-sata" + d[2] + "" + else: + hz = diskdir.split(".")[-1] + if hz == "qcow2": + disklist = "qcow2" + if diskdir[0] != "/": + diskdir = dir + '/' + diskdir + cmd += " -drive file=" + diskdir + ",if=none,format=" + disklist + ",id=drive-sata" + d[2] + "" + elif hz == "img": + disklist = "raw" + if diskdir[0] != "/": + diskdir = dir + '/' + diskdir + cmd += " -drive file=" + diskdir + ",if=none,format=" + disklist + ",id=drive-sata" + d[2] + "" + else: + if diskdir[0] != "/": + diskdir = dir + '/' + diskdir + cmd += " -drive file=" + diskdir + ",if=none,id=drive-sata" + d[2] + "" + elif d[1] == "usb": + vid = catinfo(conf,d[0] + "_" + d[1] + "_" + d[2],"vid") + pid = catinfo(conf,d[0] + "_" + d[1] + "_" + d[2],"pid") + cmd += " -device usb-host,bus=xhci.0,port=1,vendorid=" + vid + ",productid=" + pid + ",id=usb0" + elif d[1] == "virtionet": + br = catinfo(conf,d[0] + "_" + d[1] + "_" + d[2],"br") + mac = catinfo(conf,d[0] + "_" + d[1] + "_" + d[2],"mac") + cmd += " -netdev bridge,br=" + br + ",id=br0" + cmd += " -device virtio-net-pci,mac=" + mac + ",netdev=br0,bus=pci.0,addr=0x12,id=net0,rx_queue_size=1024,tx_queue_size=256" + + cmd += " -chardev socket,id=qmp,path=/run/jcm/qemu/qmp/" + name + ".qmp,server=on,wait=off " + cmd += " -mon chardev=qmp,mode=control " + cmd += " -pidfile /run/jcm/qemu/pid/" + name + ".pid " + cmd += " -vnc unix:/run/jcm/qemu/vnc/" + name + ".vnc" + #cmd += " -device ide-cd,bus=ahci0.1,drive=drive-sata1,id=sata1" + #cmd += " -drive file=/home/jiang/edit/hassos/dsm/ubuntu-20.04.6-live-server-amd64.iso,if=none,id=drive-sata1,media=cdrom " + cmd += " -daemonize 2>&1" +#scp -r jiang/SynologyDrive jiang@n2840.lan:~/edit/jcm/04130822/ + sh = os.popen(cmd).read()[:-1] + + + if sh == "": + res = '{"data":"' + 'Start' + '","soket":"qemu_' + name + '"}' + else: + res = '{"data":"' + sh + '","soket":"qemu_' + name + '"}' + + httpserver = imp.load_source("server/main/httpserver.py","server/main/httpserver.py") + httpserver.httppostchar(new_client_socket,"200",res.encode("utf-8"),"application/json;charset=UTF-8",Headers,info) + + + \ No newline at end of file diff --git a/server/qemu/biao.json b/server/qemu/biao.json new file mode 100644 index 0000000..a5d7611 --- /dev/null +++ b/server/qemu/biao.json @@ -0,0 +1,5 @@ +{ + "name": "QEMU", + "link": "qemu?", + "fa": "fa-tachometer" +} \ No newline at end of file diff --git a/server/qemu/to be continued b/server/qemu/to be continued new file mode 100644 index 0000000..e69de29 diff --git a/server/server.ini b/server/server.ini index 9f11097..f6ce1d1 100755 --- a/server/server.ini +++ b/server/server.ini @@ -4,3 +4,4 @@ APP dom setup frpc +qemu diff --git a/web/Ace_Admin/qemu/index.php b/web/Ace_Admin/qemu/index.php new file mode 100755 index 0000000..e1ed664 --- /dev/null +++ b/web/Ace_Admin/qemu/index.php @@ -0,0 +1,964 @@ + + +
+ + +