def cloneWorkshopActionEvent(self, menuItem): logging.debug("cloneWorkshopActionEvent() initiated: " + str(menuItem)) if self.session.currentWorkshop is None: WarningDialog( Gtk.Window(), "You must select a workshop before you can run the workshop.") return elif getStatus( self.session.currentWorkshop.filename) != "Clones Not Created": WarningDialog(Gtk.Window(), "Clones are already created for this workshop.") return workshopName = self.session.currentWorkshop.filename command = "python -u \"" + WORKSHOP_CREATOR_FILE_PATH + "\" \"" + os.path.join( WORKSHOP_CONFIG_DIRECTORY, workshopName + ".xml\"") logging.debug( "cloneWorkshopActionEvent(): instantiating ProcessDialog with command: " + command) pd = ProcessDialog(command) logging.debug("cloneWorkshopActionEvent(): running ProcessDialog") pd.run() pd.destroy() logging.debug( "cloneWorkshopActionEvent(): returned from ProcessDialog") self.session.overwriteAllToSaveDirectory() self.refreshActionEvent(self.session.workshopList)
def scriptWorker(self, filePath, script): logging.debug("scriptWorker() initiated " + str(filePath) + " " + script) pd = ProcessDialog("python -u \"" + script + "\" \"" + filePath + "\"", granularity="char") pd.set_title("Processing... please wait") pd.run()
def deleteClonesActionEvent(self, menuItem): logging.debug("deleteClonesActionEvent() initiated: " + str(menuItem)) if self.session.currentWorkshop is None: WarningDialog( self.window, "You must select a workshop before you can delete clones.") return elif getStatus( self.session.currentWorkshop.filename) == "Clones Not Created": WarningDialog(Gtk.Window(), "Clones are not yet created for this workshop.") return elif getStatus(self.session.currentWorkshop.filename) == "Running": WarningDialog( self.window, "Workshop is currently running. Cannot delete running clones.") elif getStatus(self.session.currentWorkshop.filename) == "Ready": workshopName = self.session.currentWorkshop.filename clones = getCloneNames(workshopName) for clone in clones: logging.debug( "deleteClonesActionEvent(): instantiating ProcessDialog") pd = ProcessDialog(VBOXMANAGE_DIRECTORY + " unregistervm " + clone.replace(" ", "\\ ") + " --delete") logging.debug( "deleteClonesActionEvent(): running ProcessDialog") pd.run() pd.destroy() logging.debug( "deleteClonesActionEvent(): returned from ProcessDialog") self.refreshActionEvent(self.session.workshopList)
def startVMsActionEvent(self, menuItem): logging.debug("startVMsActionEventActionEvent() initiated: " + str(menuItem)) if self.session.currentWorkshop is None: WarningDialog( Gtk.Window(), "You must select a workshop before you can run the workshop.") return elif getStatus( self.session.currentWorkshop.filename) == "Clones Not Created": WarningDialog(Gtk.Window(), "Clones are not yet created.") return elif getStatus(self.session.currentWorkshop.filename) == "Running": WarningDialog(Gtk.Window(), "Workshop is already running.") return workshopName = self.session.currentWorkshop.filename command = "python -u \"" + VM_STARTER_FILE_PATH + "\" \"" + os.path.join( WORKSHOP_CONFIG_DIRECTORY, workshopName + ".xml\"") logging.debug("startVMsActionEvent(): instantiating ProcessDialog") pd = ProcessDialog(command) logging.debug("startVMsActionEvent(): running ProcessDialog") pd.run() pd.destroy() logging.debug("startVMsActionEvent(): returned from ProcessDialog") self.refreshActionEvent(self.session.workshopList)
def poweroffVMsActionEvent(self, menuItem): logging.debug("poweroffVMsActionEvent() initiated: " + str(menuItem)) if self.session.currentWorkshop is None: WarningDialog(self.window, "You must select a workshop before you can run the workshop.") return workshopName = self.session.currentWorkshop.filename command = "python -u \"" + VM_POWEROFF_FILE_PATH + "\" \"" + os.path.join(WORKSHOP_CONFIG_DIRECTORY, workshopName + ".xml\"") logging.debug("poweroffVMsActionEvent(): instantiating ProcessDialog") pd = ProcessDialog(command) logging.debug("poweroffVMsActionEvent(): running ProcessDialog") pd.run() pd.destroy() logging.debug("poweroffVMsActionEvent(): returned from ProcessDialog")
def poweroffVMsActionEvent(self, menuItem): logging.debug("poweroffVMsActionEvent() initiated: " + str(menuItem)) if self.session.currentWorkshop is None: WarningDialog( self.window, "You must select a workshop before you can run the workshop.") return #TODO: will uncomment when we code a way to see if VM running in windows #elif getStatus(self.session.currentWorkshop.filename) != "Running": # WarningDialog(Gtk.Window(), "Workshop is not running") # return workshopName = self.session.currentWorkshop.filename command = "python -u \"" + VM_POWEROFF_FILE_PATH + "\" \"" + os.path.join( WORKSHOP_CONFIG_DIRECTORY, workshopName + ".xml\"") logging.debug("poweroffVMsActionEvent(): instantiating ProcessDialog") pd = ProcessDialog(command) logging.debug("poweroffVMsActionEvent(): running ProcessDialog") pd.run() pd.destroy() logging.debug("poweroffVMsActionEvent(): returned from ProcessDialog") self.refreshActionEvent(self.session.workshopList)
def exportWorkshop(self, folderPath, spinnerDialog): logging.debug("exportWorkshop() initiated " + str(folderPath)) # TODO: need to show a dialog warning users; but need to workout the spinnerDialog race condition first (hide before run) # Remove the folder if it exists if os.path.exists(folderPath): shutil.rmtree(folderPath) os.makedirs(folderPath) materialsPath = os.path.join(folderPath, "Materials") if os.path.exists(materialsPath): logging.error("Folder " + folderPath + " already exists. Cancelling export.") return os.makedirs(materialsPath) for material in self.currentWorkshop.materialList: shutil.copy2( os.path.join(WORKSHOP_MATERIAL_DIRECTORY, self.currentWorkshop.baseGroupName, material.name), materialsPath) rdpPath = os.path.join(folderPath, "RDP") if os.path.exists(rdpPath): logging.error("Folder " + folderPath + " already exists. Cancelling export.") return os.makedirs(rdpPath) rdpFiles = os.path.join(WORKSHOP_RDP_DIRECTORY, self.currentWorkshop.baseGroupName) if os.path.exists(rdpFiles): for rdpfile in os.listdir(rdpFiles): shutil.copy2(os.path.join(rdpFiles, rdpfile), rdpPath) else: logging.debug("No RDP file found in path during export: " + str(rdpFiles)) vmsToExport = self.currentWorkshop.vmList currVMNum = 0 numVMs = len(vmsToExport) for vm in vmsToExport: # subprocess.call([VBOXMANAGE_DIRECTORY, 'export', vm.name, '-o', os.path.join(folderPath,vm.name+'.ova')]) logging.debug("exportWorkshop(): Exporting VMS loop") logging.debug("Current VM NAME: " + vm.name) outputOva = os.path.join(folderPath, vm.name + '.ova') logging.debug( "exportWorkshop(): adjusting dialog progress value to " + str(currVMNum / (numVMs * 1.))) GLib.idle_add(spinnerDialog.setProgressVal, currVMNum / (numVMs * 1.)) GLib.idle_add( spinnerDialog.setLabelVal, "Exporting VM " + str(currVMNum + 1) + "/" + str(numVMs) + ": " + str(vm.name)) currVMNum = currVMNum + 1 logging.debug("Checking if " + folderPath + " exists: ") if os.path.exists(folderPath): pd = ProcessDialog(VBOXMANAGE_DIRECTORY + " export \"" + vm.name + "\" -o \"" + outputOva + "\" --iso", granularity="char", capture="stderr") pd.run() #pd.destroy() else: logging.error("folderPath" + folderPath + " was not created!") logging.debug("Done executing process. \r\nCreating zip") self.exportZipFiles(folderPath, spinnerDialog)
def importActionEvent(self, menuItem): logging.debug("importVMActionEvent() initiated") dialog = Gtk.FileChooserDialog( "Please select a EBX archive to import.", self, Gtk.FileChooserAction.OPEN, (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.OK)) response = dialog.run() if response == Gtk.ResponseType.OK: zipPath = dialog.get_filename() # get path for temporary directory to hold uncompressed files tempPath = os.path.join( os.path.dirname(zipPath), "creatorImportTemp", os.path.splitext(os.path.basename(zipPath))[0]) baseTempPath = os.path.join(os.path.dirname(zipPath), "creatorImportTemp") dialog.destroy() # First we need to unzip the import file to a temp folder # Following this protocol: any functions to which this spinner dialog can call run, but must call hide (not destroy!) # when finished. These will likely be functions that start threads. # TODO: need to make the spinnerDialog take a thread and start it after the dialog is shown, otherwise, this could lead to an undestroyable dialog spinnerDialog = SpinnerDialog( self, "Preparing to decompress EBX archive") self.session.importUnzip(zipPath, spinnerDialog) spinnerDialog.show() ovaList = [] xmlList = [] materialList = [] rdpList = [] # Get all files that end with .ova if os.path.exists(tempPath): baseFiles = os.listdir(tempPath) for filename in baseFiles: if filename.endswith(".ova"): ovaList.append(filename) elif filename.endswith(".xml"): xmlList.append(filename) materialsPath = os.path.join(tempPath, "Materials") logging.debug("importActionEvent(): Materials folder to search: " + str(materialsPath)) if os.path.exists(materialsPath): materialsFiles = os.listdir(materialsPath) logging.debug("importActionEvent(): Materials to import: " + str(materialsFiles)) for filename in materialsFiles: logging.debug( "importActionEvent(): Adding material to workshop: " + str(filename)) materialList.append(filename) rdpPath = os.path.join(tempPath, "RDP") if os.path.exists(rdpPath): rdpFiles = os.listdir(rdpPath) for filename in rdpFiles: rdpList.append(filename) vmNum = 1 for ova in ovaList: prog = float(float(vmNum) / len(ovaList)) logging.debug("importActionEvent(): Importing " + str(ova) + " into VirtualBox...") GLib.idle_add(spinnerDialog.setTitleVal, "Importing VMs") GLib.idle_add( spinnerDialog.setLabelVal, "Importing VM " + str(vmNum) + " of " + str(len(ovaList))) GLib.idle_add(spinnerDialog.setProgressVal, prog) #HERE is where pd = ProcessDialog(VBOXMANAGE_DIRECTORY + " import " + os.path.join(tempPath, ova) + " --options keepallmacs", granularity="char", capture="stderr") pd.run() vmNum = vmNum + 1 spinnerDialog.destroy() for xml in xmlList: # here we need to parse the file in order to obtain the groupBaseName logging.debug("importActionEvent(): Found XML file: " + xml) shutil.copy2(os.path.join(tempPath, xml), WORKSHOP_CONFIG_DIRECTORY) self.filename = os.path.join(tempPath, xmlList[0]) logging.debug( "importActionEvent(): Loading config file XML data: " + self.filename) tree = ET.parse(self.filename) root = tree.getroot() vmset = root.find('testbed-setup').find('vm-set') currXMLWorkshopGroupName = vmset.find('base-groupname').text logging.debug( "importActionEvent(): using workshop group name for directory creation: " + currXMLWorkshopGroupName) holdMatPath = os.path.join(WORKSHOP_MATERIAL_DIRECTORY, currXMLWorkshopGroupName) if not os.path.exists(holdMatPath): os.makedirs(holdMatPath) for material in materialList: logging.debug("importActionEvent(): Processing file " + str(material)) logging.debug("importActionEvent(): Checking for " + os.path.join(holdMatPath, material)) if not os.path.exists(os.path.join(holdMatPath, material)): logging.debug( "importActionEvent(): copying file " + str(os.path.join(tempPath, "Materials", material)) + " to " + str(material)) shutil.copy2(os.path.join(tempPath, "Materials", material), holdMatPath) holdRDPPath = os.path.join(WORKSHOP_RDP_DIRECTORY, currXMLWorkshopGroupName) if not os.path.exists(holdRDPPath): os.makedirs(holdRDPPath) for rdp in rdpList: if not os.path.exists(holdRDPPath + rdp): shutil.copy2(os.path.join(tempPath, "RDP", rdp), holdRDPPath) dialog = Gtk.MessageDialog(self, 0, Gtk.MessageType.INFO, Gtk.ButtonsType.OK, "Workshop import complete.") dialog.run() dialog.destroy() # reload all xml files and create a new display self.workshopTree.clearTreeStore() self.session.loadXMLFiles(WORKSHOP_CONFIG_DIRECTORY) self.workshopTree.populateTreeStore(self.session.workshopList) shutil.rmtree(baseTempPath, ignore_errors=True) self.superMenu.refreshActionEvent(self.session.workshopList) elif response == Gtk.ResponseType.CANCEL: dialog.destroy()