diff --git a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/CheckSshDaemonIsRunning.java b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/CheckSshDaemonIsRunning.java new file mode 100644 index 0000000000..aad61a9177 --- /dev/null +++ b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/CheckSshDaemonIsRunning.java @@ -0,0 +1,87 @@ +/* + * 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 static com.google.common.base.Throwables.propagate; +import static org.jclouds.compute.options.RunScriptOptions.Builder.wrapInInitScript; + +import javax.annotation.Nullable; +import javax.annotation.Resource; +import javax.inject.Named; + +import org.jclouds.compute.ComputeServiceContext; +import org.jclouds.compute.reference.ComputeServiceConstants; +import org.jclouds.logging.Logger; +import org.jclouds.ssh.SshException; +import org.jclouds.virtualbox.domain.ErrorCode; +import org.virtualbox_4_1.IMachine; + +import com.google.common.base.Predicate; + +/** + * Starts a machine using launchMachine() with the provided type and + * environment. + *

+ * Note that launchMachine() may throw VBoxException with the following error + * codes: + *

+ * 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 Andrea Turli + * @see ErrorCode + */ +public class CheckSshDaemonIsRunning implements Predicate { + + @Resource + @Named(ComputeServiceConstants.COMPUTE_LOGGER) + protected Logger logger = Logger.NULL; + + private final ComputeServiceContext context; + private final String nodeId; + + public CheckSshDaemonIsRunning(ComputeServiceContext context, String nodeId) { + this.context = context; + this.nodeId = nodeId; + } + + @Override + public boolean apply(@Nullable IMachine machine) { + boolean sshDeamonIsRunning = false; + while (!sshDeamonIsRunning) { + try { + if (context.getComputeService() + .runScriptOnNode(nodeId, "id", wrapInInitScript(false)) + .getExitCode() == 0) { + logger.debug("Got response from ssh daemon."); + sshDeamonIsRunning = true; + } + } catch (SshException e) { + logger.debug("No response from ssh daemon..."); + propagate(e); + } + } + return sshDeamonIsRunning; + } + +} diff --git a/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/CheckSshDaemonIsRunningLiveTest.java b/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/CheckSshDaemonIsRunningLiveTest.java new file mode 100644 index 0000000000..b521508ee6 --- /dev/null +++ b/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/CheckSshDaemonIsRunningLiveTest.java @@ -0,0 +1,64 @@ +package org.jclouds.virtualbox.functions; + +import static org.jclouds.virtualbox.experiment.TestUtils.computeServiceForLocalhostAndGuest; +import static org.jclouds.virtualbox.util.MachineUtils.applyForMachine; + +import java.util.concurrent.TimeUnit; + +import org.jclouds.compute.ComputeServiceContext; +import org.jclouds.domain.Credentials; +import org.jclouds.net.IPSocket; +import org.jclouds.predicates.InetSocketAddressConnect; +import org.jclouds.predicates.RetryablePredicate; +import org.jclouds.virtualbox.BaseVirtualBoxClientLiveTest; +import org.jclouds.virtualbox.domain.ExecutionType; +import org.testng.annotations.Test; +import org.virtualbox_4_1.IMachine; +import org.virtualbox_4_1.VirtualBoxManager; + +import com.google.common.base.Predicate; + +@Test(groups = "live", singleThreaded = true, testName = "IsoToIMachineLiveTest") +public class CheckSshDaemonIsRunningLiveTest extends BaseVirtualBoxClientLiveTest { + + private boolean forceOverwrite = true; + private String vmId = "jclouds-image-iso-1"; + private String osTypeId = ""; + private String controllerIDE = "IDE Controller"; + private String diskFormat = ""; + private String adminDisk = "testadmin.vdi"; + private String guestId = "guest"; + private String hostId = "host"; + + private String vmName = "jclouds-image-virtualbox-iso-to-machine-test"; + private String isoName = "ubuntu-11.04-server-i386.iso"; + + @Test + public void testCheckSshDaemonIsRunning() { + VirtualBoxManager manager = (VirtualBoxManager) context.getProviderSpecificContext().getApi(); + ComputeServiceContext localHostContext = + computeServiceForLocalhostAndGuest(hostId, "localhost", guestId, "localhost", new Credentials("toor", "password")); + + IMachine nodeWithSshDaemonRunning = getNodeWithSshDaemonRunning(manager, localHostContext); + ensureMachineIsLaunched(vmName); + new CheckSshDaemonIsRunning(localHostContext, guestId).apply(nodeWithSshDaemonRunning); + } + + private IMachine getNodeWithSshDaemonRunning(VirtualBoxManager manager, ComputeServiceContext localHostContext) { + try { + Predicate socketTester = new RetryablePredicate(new InetSocketAddressConnect(), 10, 1, TimeUnit.SECONDS); + return new IsoToIMachine(manager, adminDisk, diskFormat, + vmName, osTypeId, vmId, forceOverwrite, + controllerIDE, localHostContext, hostId, guestId, socketTester, + "127.0.0.1", 8080).apply(isoName); + } catch (IllegalStateException e) { + // already created + return manager.getVBox().findMachine(vmName); + } + } + + private void ensureMachineIsLaunched(String vmName) { + applyForMachine(manager, vmName, new LaunchMachineIfNotAlreadyRunning(manager, ExecutionType.GUI, "")); + } + +} \ No newline at end of file