mirror of https://github.com/apache/jclouds.git
Added LaunchMachineIfNotAlreadyRunning to IsoToIMachine.
This commit is contained in:
parent
c3eb23399b
commit
f4a53fa0da
|
@ -46,27 +46,27 @@ import java.util.Map;
|
|||
*/
|
||||
public enum ErrorCode {
|
||||
|
||||
E_OBJECT_NOT_FOUND(2159738881L),
|
||||
E_INVALID_VM_STATE(2159738882L),
|
||||
E_VM_ERROR(2159738883L),
|
||||
E_FILE_ERROR(2159738884L),
|
||||
E_IPRT_ERROR(2159738885L),
|
||||
E_PDM_ERROR(2159738886L),
|
||||
E_INVALID_OBJECT_STATE(2159738887L),
|
||||
E_HOST_ERROR(2159738888L),
|
||||
E_NOT_SUPPORTED(2159738889L),
|
||||
E_XML_ERROR(2159738890L),
|
||||
E_INVALID_SESSION_STATE(2159738891L),
|
||||
E_OBJECT_IN_USE(2159738892L),
|
||||
E_ACCESSDENIED(2147942405L),
|
||||
E_POINTER(2147500035L),
|
||||
E_FAIL(2147500037L),
|
||||
E_NOTIMPL(2147500033L),
|
||||
E_OUTOFMEMORY(2147942414L),
|
||||
E_INVALIDARG(2147942487L),
|
||||
E_UNEXPECTED(2147549183L),
|
||||
E_UNKNOWN_ERROR_CODE(-1L),
|
||||
E_ERROR_CODE_UNAVAILABLE(-2L);
|
||||
VBOX_E_OBJECT_NOT_FOUND(2159738881L),
|
||||
VBOX_E_INVALID_VM_STATE(2159738882L),
|
||||
VBOX_E_VM_ERROR(2159738883L),
|
||||
VBOX_E_FILE_ERROR(2159738884L),
|
||||
VBOX_E_IPRT_ERROR(2159738885L),
|
||||
VBOX_E_PDM_ERROR(2159738886L),
|
||||
VBOX_E_INVALID_OBJECT_STATE(2159738887L),
|
||||
VBOX_E_HOST_ERROR(2159738888L),
|
||||
VBOX_E_NOT_SUPPORTED(2159738889L),
|
||||
VBOX_E_XML_ERROR(2159738890L),
|
||||
VBOX_E_INVALID_SESSION_STATE(2159738891L),
|
||||
VBOX_E_OBJECT_IN_USE(2159738892L),
|
||||
VBOX_E_ACCESSDENIED(2147942405L),
|
||||
VBOX_E_POINTER(2147500035L),
|
||||
VBOX_E_FAIL(2147500037L),
|
||||
VBOX_E_NOTIMPL(2147500033L),
|
||||
VBOX_E_OUTOFMEMORY(2147942414L),
|
||||
VBOX_E_INVALIDARG(2147942487L),
|
||||
VBOX_E_UNEXPECTED(2147549183L),
|
||||
VBOX_E_UNKNOWN_ERROR_CODE(-1L),
|
||||
VBOX_E_ERROR_CODE_UNAVAILABLE(-2L);
|
||||
|
||||
private long code;
|
||||
|
||||
|
@ -97,9 +97,9 @@ public enum ErrorCode {
|
|||
if (errorCode != null) {
|
||||
return errorCode;
|
||||
}
|
||||
return E_UNKNOWN_ERROR_CODE;
|
||||
return VBOX_E_UNKNOWN_ERROR_CODE;
|
||||
}
|
||||
return E_ERROR_CODE_UNAVAILABLE;
|
||||
return VBOX_E_ERROR_CODE_UNAVAILABLE;
|
||||
}
|
||||
|
||||
private static long unsignedIntToLong(int faultCode) {
|
||||
|
|
|
@ -19,23 +19,8 @@
|
|||
|
||||
package org.jclouds.virtualbox.functions;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Throwables.propagate;
|
||||
import static org.jclouds.compute.options.RunScriptOptions.Builder.runAsRoot;
|
||||
import static org.jclouds.compute.options.RunScriptOptions.Builder.wrapInInitScript;
|
||||
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_INSTALLATION_KEY_SEQUENCE;
|
||||
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_WORKINGDIR;
|
||||
import static org.virtualbox_4_1.AccessMode.ReadOnly;
|
||||
import static org.virtualbox_4_1.DeviceType.DVD;
|
||||
import static org.virtualbox_4_1.DeviceType.HardDisk;
|
||||
import static org.virtualbox_4_1.LockType.Shared;
|
||||
import static org.virtualbox_4_1.LockType.Write;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Named;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.inject.Inject;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.jclouds.compute.ComputeServiceContext;
|
||||
import org.jclouds.compute.domain.ExecResponse;
|
||||
|
@ -46,12 +31,25 @@ import org.jclouds.javax.annotation.Nullable;
|
|||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.ssh.SshException;
|
||||
import org.jclouds.virtualbox.config.VirtualBoxConstants;
|
||||
import org.jclouds.virtualbox.domain.ExecutionType;
|
||||
import org.jclouds.virtualbox.functions.admin.StartJettyIfNotAlreadyRunning;
|
||||
import org.jclouds.virtualbox.settings.KeyboardScancodes;
|
||||
import org.virtualbox_4_1.*;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.inject.Inject;
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Named;
|
||||
import java.io.File;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.jclouds.compute.options.RunScriptOptions.Builder.runAsRoot;
|
||||
import static org.jclouds.compute.options.RunScriptOptions.Builder.wrapInInitScript;
|
||||
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_INSTALLATION_KEY_SEQUENCE;
|
||||
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_WORKINGDIR;
|
||||
import static org.virtualbox_4_1.AccessMode.ReadOnly;
|
||||
import static org.virtualbox_4_1.DeviceType.DVD;
|
||||
import static org.virtualbox_4_1.DeviceType.HardDisk;
|
||||
import static org.virtualbox_4_1.LockType.Shared;
|
||||
import static org.virtualbox_4_1.LockType.Write;
|
||||
|
||||
public class IsoToIMachine implements Function<String, IMachine> {
|
||||
|
||||
|
@ -136,13 +134,8 @@ public class IsoToIMachine implements Function<String, IMachine> {
|
|||
// Guest additions
|
||||
ensureGuestAdditionsMediumIsAttached(vmName, guestAdditionsDvdMedium);
|
||||
|
||||
IProgress prog = vm.launchVMProcess(manager.getSessionObject(), "gui", "");
|
||||
prog.waitForCompletion(-1);
|
||||
try {
|
||||
Thread.sleep(5000);
|
||||
} catch (InterruptedException e) {
|
||||
propagate(e);
|
||||
}
|
||||
// Launch machine and wait for it to come online
|
||||
ensureMachineIsLaunched(vmName);
|
||||
|
||||
String installKeySequence = System.getProperty(VIRTUALBOX_INSTALLATION_KEY_SEQUENCE, defaultInstallSequence());
|
||||
sendKeyboardSequence(installKeySequence);
|
||||
|
@ -180,6 +173,10 @@ public class IsoToIMachine implements Function<String, IMachine> {
|
|||
return vm;
|
||||
}
|
||||
|
||||
private void ensureMachineIsLaunched(String vmName) {
|
||||
applyForMachine(manager, vmName, new LaunchMachineIfNotAlreadyRunning(manager, ExecutionType.GUI, ""));
|
||||
}
|
||||
|
||||
private void ensureGuestAdditionsMediumIsAttached(String vmName, final IMedium guestAdditionsDvdMedium) {
|
||||
lockMachineAndApply(manager, Write, vmName,
|
||||
new AttachMediumToMachineIfNotAlreadyAttached(controllerIDE, guestAdditionsDvdMedium, 1, 1, DeviceType.DVD));
|
||||
|
@ -219,6 +216,21 @@ public class IsoToIMachine implements Function<String, IMachine> {
|
|||
new AddIDEControllerIfNotExists(checkNotNull(controllerIDE, "controllerIDE")));
|
||||
}
|
||||
|
||||
private <T> T applyForMachine(VirtualBoxManager manager, final String machineId, final Function<IMachine, T> function) {
|
||||
final IMachine immutableMachine = manager.getVBox().findMachine(machineId);
|
||||
return new Function<IMachine, T>() {
|
||||
@Override
|
||||
public T apply(IMachine machine) {
|
||||
return function.apply(machine);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return function.toString();
|
||||
}
|
||||
}.apply(immutableMachine);
|
||||
}
|
||||
|
||||
public static <T> T lockMachineAndApply(VirtualBoxManager manager, final LockType type, final String machineId,
|
||||
final Function<IMachine, T> function) {
|
||||
return lockSessionOnMachineAndApply(manager, type, machineId, new Function<ISession, T>() {
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.jclouds.virtualbox.functions;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.virtualbox.domain.ErrorCode;
|
||||
import org.jclouds.virtualbox.domain.ExecutionType;
|
||||
import org.virtualbox_4_1.*;
|
||||
import org.virtualbox_4_1.jaxws.RuntimeFaultMsg;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Named;
|
||||
import javax.lang.model.type.ExecutableType;
|
||||
|
||||
import static com.google.common.base.Throwables.propagate;
|
||||
import static javax.xml.bind.DatatypeConverter.parseUnsignedInt;
|
||||
|
||||
/**
|
||||
* Starts a machine using launchMachine() with the provided type and environment.
|
||||
* <p/>
|
||||
* Note that launchMachine() may throw VBoxException with the following error codes:
|
||||
* <p/>
|
||||
* VBOX_E_UNEXPECTED: Virtual machine not registered.
|
||||
* VBOX_E_INVALIDARG: Invalid session type type.
|
||||
* VBOX_E_OBJECT_NOT_FOUND: No machine matching machineId found.
|
||||
* VBOX_E_INVALID_OBJECT_STATE: Session already open or being opened.
|
||||
* VBOX_E_IPRT_ERROR: Launching process for machine failed.
|
||||
* VBOX_E_VM_ERROR: Failed to assign machine to session.
|
||||
*
|
||||
* @author Mattias Holmqvist
|
||||
*
|
||||
* @see ErrorCode
|
||||
*/
|
||||
public class LaunchMachineIfNotAlreadyRunning implements Function<IMachine, Void> {
|
||||
|
||||
@Resource
|
||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||
protected Logger logger = Logger.NULL;
|
||||
|
||||
private final VirtualBoxManager manager;
|
||||
private final ExecutionType type;
|
||||
private final String environment;
|
||||
|
||||
public LaunchMachineIfNotAlreadyRunning(VirtualBoxManager manager, ExecutionType type, String environment) {
|
||||
this.manager = manager;
|
||||
this.type = type;
|
||||
this.environment = environment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void apply(@Nullable IMachine machine) {
|
||||
try {
|
||||
final IProgress progress = machine.launchVMProcess(manager.getSessionObject(), type.stringValue(), environment);
|
||||
progress.waitForCompletion(-1);
|
||||
Thread.sleep(5000);
|
||||
} catch (InterruptedException e) {
|
||||
propagate(e);
|
||||
} catch (VBoxException e) {
|
||||
ErrorCode errorCode = ErrorCode.valueOf(e);
|
||||
switch (errorCode) {
|
||||
case VBOX_E_INVALID_OBJECT_STATE:
|
||||
logger.warn(e, "Could not start machine. Got error code %s from launchMachine(). " +
|
||||
"The machine might already be running.", errorCode);
|
||||
break;
|
||||
default:
|
||||
propagate(e);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.jclouds.virtualbox.functions;
|
||||
|
||||
import org.jclouds.virtualbox.domain.ExecutionType;
|
||||
import org.testng.annotations.Test;
|
||||
import org.virtualbox_4_1.IMachine;
|
||||
import org.virtualbox_4_1.IProgress;
|
||||
import org.virtualbox_4_1.ISession;
|
||||
import org.virtualbox_4_1.VirtualBoxManager;
|
||||
|
||||
import static org.easymock.classextension.EasyMock.verify;
|
||||
import static org.easymock.classextension.EasyMock.replay;
|
||||
import static org.easymock.classextension.EasyMock.createMock;
|
||||
import static org.easymock.classextension.EasyMock.expect;
|
||||
|
||||
@Test(groups = "unit", testName = "LaunchMachineIfNotAlreadyRunningTest")
|
||||
public class LaunchMachineIfNotAlreadyRunningTest {
|
||||
|
||||
@Test
|
||||
public void testDoNotLaunchIfAlreadyRunning() throws Exception {
|
||||
|
||||
}
|
||||
|
||||
// VirtualBox error: The given session is busy (0x80BB0007)
|
||||
// VirtualBox error: The machine 'jclouds-image-virtualbox-iso-to-machine-test' is not registered (0x8000FFFF)
|
||||
|
||||
|
||||
@Test
|
||||
public void testLaunchIfNotStarted() throws Exception {
|
||||
|
||||
final String type = "gui";
|
||||
final String environment = "";
|
||||
ISession session = createMock(ISession.class);
|
||||
VirtualBoxManager manager = createMock(VirtualBoxManager.class);
|
||||
IMachine machine = createMock(IMachine.class);
|
||||
IProgress progress = createMock(IProgress.class);
|
||||
|
||||
expect(manager.getSessionObject()).andReturn(session);
|
||||
expect(machine.launchVMProcess(session, type, environment)).andReturn(progress);
|
||||
progress.waitForCompletion(-1);
|
||||
|
||||
replay(manager, machine, session, progress);
|
||||
|
||||
new LaunchMachineIfNotAlreadyRunning(manager, ExecutionType.GUI, "").apply(machine);
|
||||
|
||||
verify(manager, machine, session, progress);
|
||||
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue