/******************************************************************************* * Copyright (c) 2015 Red Hat. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Red Hat - Initial Contribution *******************************************************************************/ package org.eclipse.linuxtools.internal.vagrant.ui.commands; import java.io.File; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.List; import java.util.Map; import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.linuxtools.internal.vagrant.core.Activator; import org.eclipse.linuxtools.internal.vagrant.core.EnvironmentsManager; import org.eclipse.linuxtools.internal.vagrant.core.VagrantConnection; import org.eclipse.linuxtools.internal.vagrant.ui.views.DVMessages; import org.eclipse.linuxtools.internal.vagrant.ui.wizards.CreateVMWizard; import org.eclipse.linuxtools.internal.vagrant.ui.wizards.WizardMessages; import org.eclipse.linuxtools.vagrant.core.IVagrantBox; import org.eclipse.linuxtools.vagrant.core.IVagrantConnection; import org.eclipse.linuxtools.vagrant.core.IVagrantVM; import org.eclipse.linuxtools.vagrant.core.VagrantException; import org.eclipse.linuxtools.vagrant.core.VagrantService; import org.eclipse.swt.widgets.Display; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.handlers.HandlerUtil; public class CreateVmCommandHandler extends AbstractHandler { private static final String CREATE_VM_MSG = "CreateVM.msg"; //$NON-NLS-1$ private static final String CRATE_VM_TITLE = "CreateVM.title"; //$NON-NLS-1$ @Override public Object execute(final ExecutionEvent event) { if (VagrantConnection.findVagrantPath() == null) { Display.getDefault() .syncExec(() -> MessageDialog.openError(Display.getCurrent() .getActiveShell(), WizardMessages.getString("VagrantCommandNotFound.title"), //$NON-NLS-1$ WizardMessages.getString("VagrantCommandNotFound.msg"))); //$NON-NLS-1$ } else { final IWorkbenchPart activePart = HandlerUtil.getActivePart(event); final List<IVagrantBox> selectedBoxes = CommandUtils .getSelectedImages(activePart); if (selectedBoxes.size() <= 1) { IVagrantBox selectedBox = selectedBoxes.isEmpty() ? null : selectedBoxes.get(0); final CreateVMWizard wizard = new CreateVMWizard(selectedBox); final boolean finished = CommandUtils.openWizard(wizard, HandlerUtil.getActiveShell(event)); if (finished) { performCreateVM(wizard.getVMName(), wizard.getBoxReference(), wizard.getVMFile(), wizard.getVMEnvironment()); } } } return null; } private void performCreateVM(String vmName, String boxRef, String vmFile, Map<String, String> environment) { final Job createVMJob = new Job(DVMessages.getFormattedString(CREATE_VM_MSG)) { @Override protected IStatus run(final IProgressMonitor monitor) { monitor.beginTask(DVMessages.getFormattedString(CRATE_VM_TITLE, vmName), IProgressMonitor.UNKNOWN); IVagrantConnection connection = VagrantService.getInstance(); if (findVM(connection, vmName) != null) { Display.getDefault() .syncExec(() -> MessageDialog.openError(Display.getCurrent() .getActiveShell(), WizardMessages.getString("CreateVmCommandHandler.VMExists.title"), //$NON-NLS-1$ WizardMessages.getString("CreateVmCommandHandler.VMExists.msg"))); //$NON-NLS-1$ return Status.CANCEL_STATUS; } IVagrantBox box = null; File vagrantDir; String boxName = boxRef; if (vmFile == null) { // The boxRef is a reference to an actual box file/url boolean isValidURL = true; try { new URL(boxRef); } catch (MalformedURLException e1) { isValidURL = false; } if (Paths.get(boxRef).toFile().canRead() || isValidURL) { try { String boxPath = boxRef; // Generate the box name from the file name (basename) boxName = boxRef.substring( boxRef.lastIndexOf(File.separator) + 1) .replace(".box", ""); //$NON-NLS-1$ //$NON-NLS-2$ connection.addBox(boxName, boxPath, isValidURL); } catch (VagrantException e) { } catch (InterruptedException e) { } } // Init a new vagrant folder inside plugin metadata vagrantDir = performInit(vmName, boxName, connection); // box download job might not be complete so we wait box = findBox(connection, boxName); while (box == null && isValidURL) { try { Thread.sleep(1000); } catch (InterruptedException e) { } connection.getVMs(true); box = findBox(connection, boxName); if (monitor.isCanceled()) { CommandUtils.delete(vagrantDir); return Status.CANCEL_STATUS; } } } else { vagrantDir = Paths.get(vmFile).getParent().toFile(); } EnvironmentsManager.getSingleton().setEnvironment(vagrantDir, environment); String provider = (box == null ? null : box.getProvider()); connection.up(vagrantDir, provider); connection.getVMs(true); return Status.OK_STATUS; } }; createVMJob.setUser(true); createVMJob.schedule(); } private IVagrantBox findBox(IVagrantConnection connection, String boxName) { IVagrantBox box = null; for (IVagrantBox b : connection.getBoxes()) { if (b.getName().equals(boxName)) { box = b; break; } } return box; } private IVagrantVM findVM(IVagrantConnection connection, String vmName) { IVagrantVM vm = null; for (IVagrantVM v : connection.getVMs()) { if (v.name().equals(vmName)) { vm = v; break; } } return vm; } /* * init the folder in this bundle's state location, and ensure the * Vagrantfile has the proper vm name and box name */ private File performInit(String vmName, String boxName, IVagrantConnection connection) { String stateLoc = Activator.getDefault().getStateLocation() .toOSString(); File vagrantDir = Paths.get(stateLoc, vmName).toFile(); // Project folder exists (but VM cannot exist here) // Safe to remove the stale Vagrant project entry if (!vagrantDir.mkdir()) { CommandUtils.delete(vagrantDir); vagrantDir.mkdir(); } connection.init(vagrantDir); Path vagrantFilePath = Paths.get(stateLoc, vmName, "Vagrantfile"); //$NON-NLS-1$ String defaultContent; StringBuffer bcontent = new StringBuffer(); try { defaultContent = new String(Files.readAllBytes(vagrantFilePath), StandardCharsets.UTF_8); for (String line : defaultContent.split("\n")) { //$NON-NLS-1$ if (line.contains("config.vm.box")) { //$NON-NLS-1$ String defLine = line.replaceAll("config.vm.box = \".*\"", //$NON-NLS-1$ "config.vm.define :\"" + vmName + "\""); //$NON-NLS-1$ //$NON-NLS-2$ String boxLine = line.replaceAll("config.vm.box = \".*\"", //$NON-NLS-1$ "config.vm.box = \"" + boxName + "\""); //$NON-NLS-1$ //$NON-NLS-2$ bcontent.append(defLine + '\n'); bcontent.append(boxLine + '\n'); } else { bcontent.append(line + '\n'); } } Files.write(vagrantFilePath, bcontent.toString().getBytes(StandardCharsets.UTF_8)); } catch (IOException e) { } return vagrantDir; } }