From 6ca3cea6178f8c12b02d711d9a51dcf5e2d93cb9 Mon Sep 17 00:00:00 2001 From: gfdgd_xi <3025613752@qq.com> Date: Wed, 31 Jul 2024 08:28:52 +0800 Subject: [PATCH] =?UTF-8?q?=E8=99=9A=E6=8B=9F=E5=B7=A5=E5=85=B7=E5=9F=BA?= =?UTF-8?q?=E7=A1=80=E6=A8=A1=E5=9D=97=E7=9A=84=E9=87=8D=E5=86=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- VM/buildvbox.py | 1 + VM/qemu.py | 248 ++++++++++++++++++++++++++++++++++++++++++++++++ VM/vbox.py | 107 +++++++++++++++++++++ 3 files changed, 356 insertions(+) create mode 100644 VM/buildvbox.py create mode 100644 VM/qemu.py create mode 100644 VM/vbox.py diff --git a/VM/buildvbox.py b/VM/buildvbox.py new file mode 100644 index 0000000..5f7ce86 --- /dev/null +++ b/VM/buildvbox.py @@ -0,0 +1 @@ +#!/usr/bin/env python3 \ No newline at end of file diff --git a/VM/qemu.py b/VM/qemu.py new file mode 100644 index 0000000..f799cba --- /dev/null +++ b/VM/qemu.py @@ -0,0 +1,248 @@ +import os +import shutil +import subprocess + +class qemu: + name = "" + managerPath = "" + vboxVersion = "" + commandOption = "" + isUEFI = False + + def applicationDirPath(self): + return os.path.split(os.path.realpath(__file__))[0] # 返回 string + + def homePath(self): + return os.getenv("HOME") + + def __init__(self, name: str, managerPath: str) -> None: + if (not os.path.exists(name)): + self.name = self.homePath() + "/Qemu/" + name + else: + self.name = name + self.managerPath = managerPath + self.qemuPath = "qemu-system-i386" + if (os.path.exists("/opt/apps/deepin-wine-runner-qemu-system-extra/files/run.sh")): + # 如果存在拓展 Qemu,则调用此 + qemuPath = "/opt/apps/deepin-wine-runner-qemu-system-extra/files/run.sh qemu-system-i386" + self.vboxVersion = subprocess.getoutput(qemuPath + " --version") + + def Create(self, type: str): + if(not os.path.exists(self.name)): + os.makedirs(self.name) + return 0 + + def CreateDisk(self, path: str, size: int): + if(os.path.exists(path)): + return 0 + return os.system(("qemu-img create -f qcow2 '" + self.path + "' " + str(size) + "M")) + + def CreateDiskControl(self, controlName: str): + return 0 + + def MountDisk(self, diskPath: str, controlName: str, port: int, device: int): + self.commandOption += "-drive 'file=" + diskPath + ",if=ide,index=" + str(device) + "' " + return 0 + + def MountISO(self, isoPath, controlName: str, port: int, device: int): + self.commandOption += "-drive 'media=cdrom,file=" + isoPath + ",if=ide,index=" + str(device) + "' " + return 0 + + def BootFirst(self, bootDrive: str): + self.commandOption += "-boot '" + bootDrive + "' " + return 0 + + def SetNetBridge(self, netDriver: str): + return 0 + + def SetCPU(self, number: int, cpuNum: int, coreNum: int): + # self.commandOption += "-smp " + str(number) + " " + # 调整调用方法 + #qDebug() << number << " " << cpuNum << " " << coreNum + print("Socket: ", cpuNum) + print("Core: ", coreNum) + print("Threads: ", number) + self.commandOption += "-smp " + str(number) + ",sockets=" + str(cpuNum) + ",cores=" + str(coreNum / cpuNum) + ",threads=" + str(number / cpuNum / coreNum) + " " + return 0 + + def SetMemory(self, memory: str): + self.commandOption += "-m " + str(memory) + "M " + return 0 + + def SetRemote(self, setting: bool): + return 0 + + def SetRemoteConnectSetting(self, port: int): + return 0 + + def MountMainDisk(self, diskPath: str): + self.commandOption += " --hda '" + diskPath + "' " + return 0 + + def StartArmhf(self): + print(self.commandOption) + qemuPath = "qemu-system-arm" + if(os.path.exists("/opt/apps/deepin-wine-runner-qemu-system-extra/files/run.sh")): + # 如果存在拓展 Qemu,则调用此 + qemuPath = "/opt/apps/deepin-wine-runner-qemu-system-extra/files/run.sh qemu-system-arm" + if(subprocess.getoutput("arch").replace("\n", "").replace(" ", "") == "aarch64" and not os.system((self.applicationDirPath() + "/kvm-ok").toUtf8())): + return os.system((qemuPath + " --boot 'splash=" + self.GetBootLogoPath() + ",order=d,menu=on,splash-time=2000' -display vnc=:5 -display gtk --enable-kvm -cpu host -M virt " + self.commandOption + " -device virtio-gpu-pci -device nec-usb-xhci,id=xhci,addr=0x1b -device usb-tablet,id=tablet,bus=xhci.0,port=1 -device usb-kbd,id=keyboard,bus=xhci.0,port=2 > /tmp/windows-virtual-machine-installer-for-wine-runner-install.log 2>&1 &")) + + return os.system((qemuPath + " --boot 'splash=" + self.GetBootLogoPath() + ",order=d,menu=on,splash-time=2000' -display vnc=:5 -display gtk -cpu max -M virt " + self.commandOption + " -device virtio-gpu-pci -device nec-usb-xhci,id=xhci,addr=0x1b -device usb-tablet,id=tablet,bus=xhci.0,port=1 -device usb-kbd,id=keyboard,bus=xhci.0,port=2 > /tmp/windows-virtual-machine-installer-for-wine-runner-install.log 2>&1 &")) + + def StartAarch64(self): + bootScreenLogo = "" + qemuPath = "qemu-system-aarch64" + # 判断 boot 文件是否存在 + if (os.path.exists(self.applicationDirPath() + "/boot.jpg")): + bootScreenLogo = self.applicationDirPath() + "/boot.jpg" + else: + # 写入 logo + shutil.copy(":/boot.jpg", "/tmp/deep-wine-runner-boot.jpg") + bootScreenLogo = "/tmp/deep-wine-runner-boot.jpg" + + if(os.path.exists("/opt/apps/deepin-wine-runner-qemu-system-extra/files/run.sh")): + # 如果存在拓展 Qemu,则调用此 + qemuPath = "/opt/apps/deepin-wine-runner-qemu-system-extra/files/run.sh qemu-system-aarch64" + + print(self.commandOption) + if(subprocess.getoutput("arch").replace("\n", "").replace(" ", "") == "aarch64" and not os.system((self.applicationDirPath() + "/kvm-ok").toUtf8())): + return os.system((qemuPath + " --boot 'splash=" + self.GetBootLogoPath() + ",order=d,menu=on,splash-time=2000' -display vnc=:5 -display gtk --enable-kvm -cpu host -M virt " + self.commandOption + " -device virtio-gpu-pci -device nec-usb-xhci,id=xhci,addr=0x1b -device usb-tablet,id=tablet,bus=xhci.0,port=1 -device usb-kbd,id=keyboard,bus=xhci.0,port=2 > /tmp/windows-virtual-machine-installer-for-wine-runner-install.log 2>&1 &")) + + return os.system((qemuPath + " --boot 'splash=" + self.GetBootLogoPath() + ",order=d,menu=on,splash-time=2000' -display vnc=:5 -display gtk -cpu max -M virt " + self.commandOption + " -device virtio-gpu-pci -device nec-usb-xhci,id=xhci,addr=0x1b -device usb-tablet,id=tablet,bus=xhci.0,port=1 -device usb-kbd,id=keyboard,bus=xhci.0,port=2 > /tmp/windows-virtual-machine-installer-for-wine-runner-install.log 2>&1 &")) + + def StartLoong64(self): + return 1 + + def Start(self, unShown: bool): + newCommandOption = self.commandOption + qemuPath = "qemu-system-x86_64" + print(self.GetBootLogoPath()) + if (self.isUEFI): + newcommandOption += " -vga none -device virtio-gpu-pci -device nec-usb-xhci,id=xhci,addr=0x1b -device usb-tablet,id=tablet,bus=xhci.0,port=1 -device usb-kbd,id=keyboard,bus=xhci.0,port=2 " + else: + newcommandOption += " -vga virtio -device nec-usb-xhci,id=xhci,addr=0x1b -device usb-tablet,id=tablet,bus=xhci.0,port=1 " + # UOS 3a4000 使用程序自带的 qemu + info = self.SystemInfo().lower() + if("uos" in info or "unio" in info): + # 判断架构 + arch = self.GetArch() + if(arch == "mips64" or arch == "mipsel64"): + qemuPath = "bwrap --dev-bind / / --bind '" + self.applicationDirPath() + "/MipsQemu/usr/lib/mips64el-linux-gnuabi64/qemu/ui-gtk.so' /usr/lib/mips64el-linux-gnuabi64/qemu/ui-gtk.so '" + self.applicationDirPath() + "/MipsQemu/usr/bin/qemu-system-x86_64' " + if(os.path.exists("/opt/apps/deepin-wine-runner-qemu-system-extra/files/run.sh")): + # 如果存在拓展 Qemu,则调用此 + qemuPath = "/opt/apps/deepin-wine-runner-qemu-system-extra/files/run.sh qemu-system-x86_64" + print(self.commandOption) + if(subprocess.getoutput("arch").replace("\n", "").replace(" ", "") == "x86_64" and not os.system((self.applicationDirPath() + "/kvm-ok").toUtf8())): + return os.system((qemuPath + " --boot 'splash=" + self.GetBootLogoPath() + ",order=d,menu=on,splash-time=2000' -display vnc=:5 -display gtk --enable-kvm -cpu host " + newCommandOption + " > /tmp/windows-virtual-machine-installer-for-wine-runner-install.log 2>&1 &")) + return os.system((qemuPath + " --boot 'splash=" + self.GetBootLogoPath() + ",order=d,menu=on,splash-time=2000' -display vnc=:5 -display gtk -nic model=rtl8139 " + newCommandOption + " > /tmp/windows-virtual-machine-installer-for-wine-runner-install.log 2>&1 &")) + + def Stop(self): + os.system("killall qemu-system-x86_64 -9") + os.system("killall qemu-system-aarch64 -9") + os.system("killall qemu-system-arm -9") + os.system("killall kvm -9") + return 0 + + def Delete(self): + return os.system(("rm -rfv '" + self.name + "'")) + + def SetDisplayMemory(self, memory: int): + return 0 + + def InstallGuessAdditions(self, controlName: str, port: int, device: int): + return 0 + + def EnabledAudio(self): + self.commandOption += "-device AC97 -device ES1370 -device intel-hda -device hda-duplex " + return 0 + + def EnabledClipboardMode(self): + return 0 + + def EnabledDraganddrop(self): + return 0 + + def ShareFile(self, name: str, path: str): + return 0 + + def SetVBoxSVGA(self): + return 0 + + def SetMousePS2(self): + return 0 + + def SetKeyboardPS2(self): + return 0 + + def OpenUSB(self): + return 0 + + def UseAarch64EFI(self): + if(os.path.exists("/usr/share/qemu-efi-aarch64/QEMU_EFI.fd")): + self.commandOption += "--bios /usr/share/qemu-efi-aarch64/QEMU_EFI.fd " + return 0 + if(os.path.exists(self.applicationDirPath() + "/QEMU_AARCH64_EFI.fd")): + self.commandOption += "--bios '" + self.applicationDirPath() + "/QEMU_AARCH64_EFI.fd' " + return 0 + return 1 + + def UseArmhfEFI(self): + if(os.path.exists("/usr/share/AAVMF/AAVMF32_CODE.fd")): + self.commandOption += "--bios /usr/share/AAVMF/AAVMF32_CODE.fd " + return 0 + if(os.path.exists(self.applicationDirPath() + "/AAVMF32_CODE.fd")): + self.commandOption += "--bios '" + self.applicationDirPath() + "/AAVMF32_CODE.fd' " + return 0 + return 1 + + def UseLoongarch64EFI(self): + return 0 + + def UseOtherEFI(self, fdFilePath: str): + return 0 + + def EnabledUEFI(self, status: str): + isUEFI = status + if(not status): + return 0 + if(os.path.exists("/usr/share/qemu/OVMF.fd")): + self.commandOption += "--bios /usr/share/qemu/OVMF.fd " + return 0 + if(os.path.exists(self.applicationDirPath() + "/OVMF.fd")): + self.commandOption += "--bios '" + self.applicationDirPath() + "/OVMF.fd' " + return 0 + return 1 + + def MountMainISO(self, isoPath: str): + self.commandOption += "--cdrom '" + isoPath + "' " + return 0 + + def AutoInstall(self, iso: str): + return 0 + + def AddDiskSpace(self, path, data: float): + return os.system(("qemu-img resize '" + self.path + "' +" + str(data) + "G").toUtf8()) + + def GetBootLogoPath(self) -> str: + bootScreenLogo = "" + # 判断 boot 文件是否存在 + if(os.path.exists(self.applicationDirPath() + "/boot.jpg")): + bootScreenLogo = self.applicationDirPath() + "/boot.jpg" + else: + # 写入 logo + if(os.path.exists("/tmp/deep-wine-runner-boot.jpg")): + os.remove("/tmp/deep-wine-runner-boot.jpg") + shutil.copy(":/boot.jpg", "/tmp/deep-wine-runner-boot.jpg") + bootScreenLogo = "/tmp/deep-wine-runner-boot.jpg" + return bootScreenLogo + + + def SystemInfo(self) -> str: + with open("/etc/os-version", "r") as file: + data = file.read() + return data + + def GetArch(self) -> str: + return subprocess.getoutput("uname -m").replace("\n", "").replace(" ", "") + \ No newline at end of file diff --git a/VM/vbox.py b/VM/vbox.py new file mode 100644 index 0000000..f6c3a4c --- /dev/null +++ b/VM/vbox.py @@ -0,0 +1,107 @@ +import os +import subprocess + +class vbox: + name = "" + managerPath = "" + vboxVersion = "" + + def __init__(self, name: str, managerPath: str) -> None: + self.name = name + self.managerPath = managerPath + self.vboxVersion = subprocess.getoutput("'" + managerPath + "' -v") + + def Create(self, type: str): + os.system(("\"" + self.managerPath + "\" createvm --name \"" + + self.name + "\" --ostype \"" + type + + "\" --register")) + return os.system(("\"" + self.managerPath + "\" modifyvm \"" + + self.name + "\" --ostype \"" + type + + "\" ")) + # vboxmanage modifyvm testvm --ostype + + def CreateDisk(self, path: str, size: int): + return os.system(("\"" + self.managerPath + "\" createvdi --filename \"" + path + "\" --size \"" + str(size) + "\"")) + + def CreateDiskControl(self, controlName: str): + return os.system(("\"" + self.managerPath + "\" storagectl \"" + self.name + "\" --name \"" + controlName + "\" --add ide")) + + def MountDisk(self, diskPath: str, controlName: str, port: int, device: int): + return os.system(("\"" + self.managerPath + "\" storageattach \"" + self.name + + "\" --storagectl \"" + controlName + "\" --type hdd --port " + + str(port) + " --device " + str(device) + " --medium \"" + diskPath + "\"")) + + def MountISO(self, isoPath: str, controlName: str, port: int, device: int): + return os.system(("\"" + self.managerPath + "\" storageattach \"" + self.name + "\" --storagectl \"" + + controlName + "\" --type dvddrive --port " + str(port) + " --device " + str(device) + + " --medium \"" + isoPath + "\"")) + + def BootFirst(self, bootDrive: str): + return os.system(("\"" + self.managerPath + "\" modifyvm \"" + self.name + "\" --boot1 " + bootDrive)) + + def SetNetBridge(self, netDriver: str): + return os.system(("\"" + self.managerPath + "\" modifyvm \"" + self.name + + "\" --nic1 bridged --cableconnected1 on --nictype1 82540EM --bridgeadapter1 \"" + netDriver + "\" --intnet1 brigh1 --macaddress1 auto")) + + def SetCPU(self, number: int, cpuNum: int, coreNum: int): + return os.system(("\"" + self.managerPath + "\" modifyvm \"" + self.name + "\" --cpus " + str(number))) + + def SetMemory(self, memory: int): + return os.system(("\"" + self.managerPath + "\" modifyvm \"" + self.name + "\" --memory " + str(memory))) + + def SetRemote(self, setting: bool): + if (setting): + return os.system(("\"" + self.managerPath + "\" modifyvm \"" + self.name + "\" --vrde on")) + return os.system(("\"" + self.managerPath + "\" modifyvm \"" + self.name + "\" --vrde off")) + + def SetRemoteConnectSetting(self, port: int): + return os.system(("\"" + self.managerPath + "\" modifyvm \"" + self.name + "\" --vrdeport " + str(port) + " --vrdeaddress """)) + + def Start(self, unShown: bool): + if (unShown): + return os.system(("\"" + self.managerPath + "\" > /tmp/windows-virtual-machine-installer-for-wine-runner-install.log 2>&1")) + return os.system(("\"" + self.managerPath + "\" startvm \"" + self.name + "\" > /tmp/windows-virtual-machine-installer-for-wine-runner-install.log 2>&1")) + + def Stop(self): + return os.system(("\"" + self.managerPath + "\" controlvm \"" + self.name + "\" poweroff")) + + def Delete(self): + return os.system(("\"" + self.managerPath + "\" unregistervm --delete \"" + self.name + "\"")) + + def SetDisplayMemory(self, memory: int): + return os.system(("\"" + self.managerPath + "\" modifyvm \"" + self.name + "\" --vram " + str(memory))) + + def InstallGuessAdditions(self, controlName: str, port: int, device: int): + return self.MountISO("/usr/share/virtualbox/VBoxGuestAdditions.iso", controlName, port, device); + + def EnabledAudio(self): + return os.system(("\"" + self.managerPath + "\" modifyvm \"" + self.name + "\" --audio-driver pulse --audiocontroller hda --audioin on --audioout on")) + + def EnabledClipboardMode(self): + return os.system(("\"" + self.managerPath + "\" modifyvm \"" + self.name + "\" --clipboard-mode bidirectional")) + + def EnabledDraganddrop(self): + return os.system(("\"" + self.managerPath + "\" modifyvm \"" + self.name + "\" --draganddrop bidirectional")) + + def ShareFile(self, name: str, path: str): + return os.system(("\"" + self.managerPath + "\" sharedfolder add \"" + this->name + "\" -name \"" + self.name + "\" -hostpath \"" + path + "\"")) + + def SetVBoxSVGA(self): + return os.system(("\"" + self.managerPath + "\" modifyvm \"" + self.name + "\" --graphicscontroller vboxsvga")) + + def SetMousePS2(self): + return os.system(("\"" + self.managerPath + "\" modifyvm \"" + self.name + "\" --mouse usb")) + + def SetKeyboardPS2(self): + return os.system(("\"" + self.managerPath + "\" modifyvm \"" + self.name + "\" --keyboard usb")) + + def OpenUSB(self): + return os.system(("\"" + self.managerPath + "\" modifyvm \"" + self.name + "\" --usbohci on")) + + def EnabledUEFI(self, status: bool): + if (status): + return os.system(("\"" + self.managerPath + "\" modifyvm \"" + self.name + "\" --firmware=efi")) + return os.system(("\"" + self.managerPath + "\" modifyvm \"" + self.name + "\" --firmware=bios")) + + def AutoInstall(self, iso: str): + return os.system(("vboxmanage unattended install '" + self.name + "' '--iso=" + iso + "'"))