package org.openslx.dozmod.gui.wizard.page; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.io.Reader; import java.nio.file.Files; import javax.swing.JFileChooser; import javax.swing.JOptionPane; import org.apache.commons.io.FileUtils; import org.apache.commons.io.FilenameUtils; import org.apache.log4j.Logger; import org.openslx.dozmod.Config; import org.openslx.dozmod.gui.Gui; import org.openslx.dozmod.gui.helper.I18n; import org.openslx.dozmod.gui.helper.MessageType; import org.openslx.dozmod.gui.helper.QFileChooser; import org.openslx.dozmod.gui.wizard.Wizard; import org.openslx.dozmod.gui.wizard.layout.ImageOvfConversionPageLayout; import org.openslx.dozmod.state.UploadWizardState; import org.openslx.dozmod.util.ConversionTaskWorker; /** * Page for converting an ovf image into an vmx image. Creates a directory for * the new vmx image, starts the conversion SwingWorker and shows the progress. * Replaces the image description file in state after conversion. */ public class ImageOvfConversionPage extends ImageOvfConversionPageLayout { /** * Version for serialization. */ private static final long serialVersionUID = 464428060782110490L; private final static Logger LOGGER = Logger.getLogger(ImageOvfConversionPage.class); private UploadWizardState state; private ImageOvfConversionPage page; private File vmxFile; private ConversionTaskWorker worker; private String startConversionButtonString = I18n.PAGE .getString("ImageOvfConversion.StartConversionButton.text"); public boolean conversionStarted = false; public boolean conversionSuccessful = false; private String ovfToolPath = "ovftool"; public ImageOvfConversionPage(Wizard wizard, UploadWizardState uploadWizardState) { super(wizard); setPageComplete(false); this.canComeBack = false; this.state = uploadWizardState; page = this; String os = System.getProperty("os.name"); // Linux install should have put the ovftool into the path variable. // Try to set it for windows and macos. if (os.toLowerCase().contains("windows")) { ovfToolPath = System.getenv("ProgramFiles(X86)") + "\\VMware\\VMware Workstation\\OVFTool\\ovftool.exe"; if (!(new File(ovfToolPath).exists())) { ovfToolPath = System.getenv("ProgramFiles(X86)") + "\\VMware\\VMware Player\\OVFTool\\ovftool.exe"; } } else if (os.toLowerCase().contains("mac")) { ovfToolPath = "/Applications/VMware Fusion.app/Contents/Library/VMware OVF Tool"; } txtInfoText.setVisible(true); // Start the conversion btnStartConversion.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (worker == null) { try { updateConversionProgressbar(0); btnStartConversion.setText( I18n.PAGE.getString("ImageOvfConversion.AbortConversionButton.text")); convertOvfToVmx(state.descriptionFile); } catch (Exception error) { btnStartConversion.setEnabled(false); Gui.showMessageBox(page, I18n.PAGE.getString("ImageOvfConversion.ErrorMessage.ConversionFailed"), MessageType.ERROR, LOGGER, error); } } else { page.cancelConversionWorker(); } } }); // Browse for *.vmx btnBrowseForOvftool.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { browseForOvftoolPath(); } }); } // Check wether the file contains the keyword. Stops after the first few lines. private boolean fileContainsKeyword(File file, String keyword) { try (Reader reader = new FileReader(file); BufferedReader buffered = new BufferedReader(reader)) { String line; int lineCount = 0; while ((line = buffered.readLine()) != null && lineCount < 50) { if (line.toLowerCase().contains(keyword)) { LOGGER.debug("Detected OVF/OVA created with Virtual Box"); return true; } } } catch (IOException e) { e.printStackTrace(); } return false; } public void browseForOvftoolPath() { QFileChooser fc = new QFileChooser(Config.getUploadPath(), false); int action = fc.showOpenDialog(getDialog()); File file = fc.getSelectedFile(); if (action != JFileChooser.APPROVE_OPTION || file == null) { return; } page.ovfToolPath = file.getAbsolutePath(); btnStartConversion.setEnabled(true); ovfToolFile.setText(page.ovfToolPath); } public void cancelConversionWorker() { if (worker != null) { worker.cancel(true); btnStartConversion.setText(startConversionButtonString); worker = null; } } // Check if the directory we want to create for the converted virtual machine // exists and create it private void convertOvfToVmx(File file) throws IOException { File directoryFile = new File(file.getParent() + "/converted_vm"); LOGGER.debug("Directory for converted VM:" + directoryFile.getAbsolutePath()); // Cancel if user clicks cancel if (directoryFile.exists() && !askDeleteDirAndContinue(directoryFile)) { btnStartConversion.setText(startConversionButtonString); return; } conversionStarted = true; Files.createDirectories(directoryFile.toPath()); vmxFile = new File( directoryFile.getPath() + "/" + FilenameUtils.removeExtension((file.getName())) + ".vmx"); worker = new ConversionTaskWorker(file, vmxFile, page, ovfToolPath); worker.execute(); state.convertedDescriptionFile = vmxFile; } private boolean askDeleteDirAndContinue(File directoryFile) throws IOException { if (directoryFile.exists()) { int dialogButton = JOptionPane.YES_NO_OPTION; int dialogResult; if (!conversionStarted) { dialogResult = JOptionPane.showConfirmDialog(this, I18n.PAGE.getString("ImageOvfConversion.Dialog.DirectoryExists"), I18n.PAGE.getString("ImageOvfConversion.Dialog.DirectoryExists.title"), dialogButton); } else { dialogResult = JOptionPane.showConfirmDialog(this, I18n.PAGE.getString("ImageOvfConversion.Dialog.RemoveTmpDirectory"), I18n.PAGE.getString("ImageOvfConversion.Dialog.RemoveTmpDirectory.title"), dialogButton); } if (dialogResult == 0) { FileUtils.deleteDirectory(directoryFile); return true; } else { return false; } } // Nothing to delete. Should be OK to continue return true; } public void updateConversionProgressbar(int percent) { conversionProgressBar.setValue(percent); } public void updateConversionProgressbarText(String text) { conversionProgressBar.setString(text); } @Override protected boolean wantNextOrFinish() { return false; } @Override protected void onPageEnter() { if (!fileContainsKeyword(state.descriptionFile, "vmware")) { Gui.showMessageBox(this, I18n.PAGE.getString("ImageOvfConversion.MessageBox.notAVmwareOrVboxImage"), MessageType.WARNING, LOGGER, null); } else if (fileContainsKeyword(state.descriptionFile, "vbox")) { Gui.showMessageBox(this, I18n.PAGE.getString("ImageOvfConversion.MessageBox.VboxDetected"), MessageType.INFO, LOGGER, null); } updateConversionProgressbar(0); updateConversionProgressbarText(""); conversionStarted = false; conversionSuccessful = false; btnStartConversion.setText(startConversionButtonString); } @Override protected void onPageLeave() { // Make sure the worker is stopped when leaving the page. if (wizard.isCancelled() || (conversionStarted && !conversionSuccessful)) { page.cancelConversionWorker(); if (state.convertedDescriptionFile != null) { try { askDeleteDirAndContinue(state.convertedDescriptionFile.getParentFile()); } catch (IOException e) { LOGGER.debug(e); } } state.convertedDescriptionFile = null; conversionStarted = false; } super.onPageLeave(); } }