diff --git a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/predicates/SshAvailable.java b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/predicates/SshAvailable.java new file mode 100644 index 0000000000..4be1bf7b74 --- /dev/null +++ b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/predicates/SshAvailable.java @@ -0,0 +1,73 @@ +/* + * 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.predicates; + +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 com.google.common.base.Predicate; + +/** + * + * @author Andrea Turli + */ +public class SshAvailable implements Predicate { + + @Resource + @Named(ComputeServiceConstants.COMPUTE_LOGGER) + protected Logger logger = Logger.NULL; + + private final ComputeServiceContext context; + + public SshAvailable(ComputeServiceContext context) { + this.context = context; + } + + @Override + public boolean apply(@Nullable String nodeId) { + boolean sshDaemonIsRunning = false; + try { + if (context.getComputeService() + .runScriptOnNode(nodeId, "id", wrapInInitScript(false).runAsRoot(false)) + .getExitCode() == 0) { + logger.debug("Got response from ssh daemon running on %s", nodeId); + sshDaemonIsRunning = true; + } + } catch (SshException e) { + logger.debug("No response from ssh daemon running on %s", nodeId); + return sshDaemonIsRunning; + } + return sshDaemonIsRunning; + } + + @Override + public String toString() { + return "sshAvailable()"; + } + +} diff --git a/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/predicates/SshAvailableLiveTest.java b/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/predicates/SshAvailableLiveTest.java new file mode 100644 index 0000000000..123f9c01e0 --- /dev/null +++ b/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/predicates/SshAvailableLiveTest.java @@ -0,0 +1,90 @@ +package org.jclouds.virtualbox.predicates; + +import static org.jclouds.virtualbox.experiment.TestUtils.computeServiceForLocalhostAndGuest; +import static org.jclouds.virtualbox.util.MachineUtils.applyForMachine; +import static org.jclouds.virtualbox.util.MachineUtils.lockSessionOnMachineAndApply; +import static org.virtualbox_4_1.LockType.Shared; +import static org.testng.Assert.assertTrue; + +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.jclouds.virtualbox.functions.IsoToIMachine; +import org.jclouds.virtualbox.functions.LaunchMachineIfNotAlreadyRunning; +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 com.google.common.base.Function; +import com.google.common.base.Predicate; + +@Test(groups = "live", singleThreaded = true, testName = "IsoToIMachineLiveTest") +public class SshAvailableLiveTest 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 testSshDaemonIsRunning() { + VirtualBoxManager manager = (VirtualBoxManager) context + .getProviderSpecificContext().getApi(); + ComputeServiceContext localHostContext = computeServiceForLocalhostAndGuest( + hostId, "localhost", guestId, "localhost", new Credentials("toor", + "password")); + + getNodeWithSshDaemonRunning(manager, localHostContext); + ensureMachineIsLaunched(vmName); + RetryablePredicate predicate = new RetryablePredicate( + new SshAvailable(localHostContext), 5, 1, + TimeUnit.SECONDS); + assertTrue(predicate.apply(guestId)); + + lockSessionOnMachineAndApply(manager, Shared, vmName, new Function() { + + @Override + public Void apply(ISession session) { + IProgress powerDownProgress = session.getConsole().powerDown(); + powerDownProgress.waitForCompletion(-1); + return null; + } + + }); + } + + 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