From 290c5d5f476f2f6375fdef7a6177fca1f2753dbe Mon Sep 17 00:00:00 2001 From: andreaturli Date: Sat, 18 Feb 2012 12:44:44 +0000 Subject: [PATCH 1/2] issue 384: fixed GuestAdditions LiveTest --- .../VirtualBoxComputeServiceAdapter.java | 1 - .../functions/CreateAndInstallVm.java | 52 ++++--- .../functions/cleanupUdevIfNeeded.sh | 12 ++ ...rtualBoxComputeServiceAdapterLiveTest.java | 5 - ...hineFromIsoIfNotAlreadyExistsLiveTest.java | 2 + .../functions/CreateAndInstallVmLiveTest.java | 145 ++++++++++++++---- .../IMachinePredicatesLiveTest.java | 11 -- 7 files changed, 161 insertions(+), 67 deletions(-) create mode 100644 labs/virtualbox/src/main/resources/functions/cleanupUdevIfNeeded.sh diff --git a/labs/virtualbox/src/main/java/org/jclouds/virtualbox/compute/VirtualBoxComputeServiceAdapter.java b/labs/virtualbox/src/main/java/org/jclouds/virtualbox/compute/VirtualBoxComputeServiceAdapter.java index 4c0a4e46c6..4081ec1854 100644 --- a/labs/virtualbox/src/main/java/org/jclouds/virtualbox/compute/VirtualBoxComputeServiceAdapter.java +++ b/labs/virtualbox/src/main/java/org/jclouds/virtualbox/compute/VirtualBoxComputeServiceAdapter.java @@ -185,7 +185,6 @@ public class VirtualBoxComputeServiceAdapter implements ComputeServiceAdapter { @@ -88,12 +98,12 @@ public class CreateAndInstallVm implements Function { VmSpec vmSpec = masterSpec.getVmSpec(); IsoSpec isoSpec = masterSpec.getIsoSpec(); String vmName = vmSpec.getVmName(); - + final IMachine vm = createAndRegisterMachineFromIsoIfNotAlreadyExists.apply(masterSpec); // Launch machine and wait for it to come online ensureMachineIsLaunched(vmName); - + URI uri = preConfiguration.getUnchecked(isoSpec); String installationKeySequence = isoSpec.getInstallationKeySequence().replace("PRECONFIGURATION_URL", uri.toASCIIString()); @@ -106,7 +116,13 @@ public class CreateAndInstallVm implements Function { logger.debug(">> awaiting installation of guest additions on vm: %s", vmName); checkState(new GuestAdditionsInstaller(context).apply(vmName)); - + + logger.debug(">> awaiting post-installation actions on vm: %s", vmName); + ListenableFuture execFuture = context.getComputeService().submitScriptOnNode(vmName, + call("cleanupUdevIfNeeded"), RunScriptOptions.NONE); + ExecResponse execResponse = Futures.getUnchecked(execFuture); + checkState(execResponse.getExitCode() == 0); + logger.debug("<< installation of image complete. Powering down node(%s)", vmName); ensureMachineHasPowerDown(vmName); return vm; diff --git a/labs/virtualbox/src/main/resources/functions/cleanupUdevIfNeeded.sh b/labs/virtualbox/src/main/resources/functions/cleanupUdevIfNeeded.sh new file mode 100644 index 0000000000..59f3d0b2ab --- /dev/null +++ b/labs/virtualbox/src/main/resources/functions/cleanupUdevIfNeeded.sh @@ -0,0 +1,12 @@ +function cleanupUdevIfNeeded { + unset OSNAME; + local OSNAME=`lsb_release -d -s | cut -d ' ' -f 1`; shift + if [ $OSNAME = 'Ubuntu' ] + then + echo "OS is Ubuntu" + rm /etc/udev/rules.d/70-persistent-net.rules; + mkdir /etc/udev/rules.d/70-persistent-net.rules; + rm -rf /dev/.udev/; + rm /lib/udev/rules.d/75-persistent-net-generator.rules + fi +} \ No newline at end of file diff --git a/labs/virtualbox/src/test/java/org/jclouds/virtualbox/compute/VirtualBoxComputeServiceAdapterLiveTest.java b/labs/virtualbox/src/test/java/org/jclouds/virtualbox/compute/VirtualBoxComputeServiceAdapterLiveTest.java index df24afd931..f8bb78a589 100644 --- a/labs/virtualbox/src/test/java/org/jclouds/virtualbox/compute/VirtualBoxComputeServiceAdapterLiveTest.java +++ b/labs/virtualbox/src/test/java/org/jclouds/virtualbox/compute/VirtualBoxComputeServiceAdapterLiveTest.java @@ -50,11 +50,6 @@ public class VirtualBoxComputeServiceAdapterLiveTest extends BaseVirtualBoxClien adapter = context.utils().injector().getInstance(VirtualBoxComputeServiceAdapter.class); } - @Test - public void testListLocations() { - assertFalse(Iterables.isEmpty(adapter.listLocations())); - } - private static final PrioritizeCredentialsFromTemplate prioritizeCredentialsFromTemplate = new PrioritizeCredentialsFromTemplate( new DefaultCredentialsFromImageOrOverridingCredentials()); diff --git a/labs/virtualbox/src/test/java/org/jclouds/virtualbox/functions/CloneAndRegisterMachineFromIsoIfNotAlreadyExistsLiveTest.java b/labs/virtualbox/src/test/java/org/jclouds/virtualbox/functions/CloneAndRegisterMachineFromIsoIfNotAlreadyExistsLiveTest.java index c67956d000..182a5da936 100644 --- a/labs/virtualbox/src/test/java/org/jclouds/virtualbox/functions/CloneAndRegisterMachineFromIsoIfNotAlreadyExistsLiveTest.java +++ b/labs/virtualbox/src/test/java/org/jclouds/virtualbox/functions/CloneAndRegisterMachineFromIsoIfNotAlreadyExistsLiveTest.java @@ -33,6 +33,7 @@ import org.jclouds.virtualbox.domain.StorageController; import org.jclouds.virtualbox.domain.VmSpec; import org.jclouds.virtualbox.functions.CloneAndRegisterMachineFromIMachineIfNotAlreadyExists; import org.jclouds.virtualbox.functions.CreateAndRegisterMachineFromIsoIfNotAlreadyExists; +import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; import org.virtualbox_4_1.CleanupMode; @@ -138,4 +139,5 @@ public class CloneAndRegisterMachineFromIsoIfNotAlreadyExistsLiveTest extends .findMachine(sourceMachineSpec.getVmSpec().getVmId()); } } + } \ No newline at end of file diff --git a/labs/virtualbox/src/test/java/org/jclouds/virtualbox/functions/CreateAndInstallVmLiveTest.java b/labs/virtualbox/src/test/java/org/jclouds/virtualbox/functions/CreateAndInstallVmLiveTest.java index 362868c1a9..a52b0ab05d 100644 --- a/labs/virtualbox/src/test/java/org/jclouds/virtualbox/functions/CreateAndInstallVmLiveTest.java +++ b/labs/virtualbox/src/test/java/org/jclouds/virtualbox/functions/CreateAndInstallVmLiveTest.java @@ -19,10 +19,19 @@ package org.jclouds.virtualbox.functions; -import com.google.common.base.CaseFormat; -import com.google.common.base.Function; -import com.google.inject.Guice; -import com.google.inject.Injector; +import static com.google.common.base.Preconditions.checkState; +import static com.google.common.base.Predicates.equalTo; +import static com.google.common.collect.Iterables.any; +import static com.google.common.collect.Iterables.transform; +import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_IMAGE_PREFIX; +import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_INSTALLATION_KEY_SEQUENCE; +import static org.testng.Assert.assertTrue; + +import java.util.Map; +import java.util.Set; + +import javax.annotation.Nullable; + import org.jclouds.compute.config.BaseComputeServiceContextModule; import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.OsFamily; @@ -30,25 +39,35 @@ import org.jclouds.compute.reference.ComputeServiceConstants; import org.jclouds.config.ValueOfConfigurationKeyOrNull; import org.jclouds.json.Json; import org.jclouds.json.config.GsonModule; +import org.jclouds.ssh.SshClient; import org.jclouds.virtualbox.BaseVirtualBoxClientLiveTest; -import org.jclouds.virtualbox.domain.*; +import org.jclouds.virtualbox.domain.ExecutionType; +import org.jclouds.virtualbox.domain.HardDisk; +import org.jclouds.virtualbox.domain.IsoSpec; +import org.jclouds.virtualbox.domain.MasterSpec; +import org.jclouds.virtualbox.domain.NatAdapter; +import org.jclouds.virtualbox.domain.NetworkSpec; +import org.jclouds.virtualbox.domain.StorageController; +import org.jclouds.virtualbox.domain.VmSpec; +import org.jclouds.virtualbox.predicates.SshResponds; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; import org.virtualbox_4_1.CleanupMode; import org.virtualbox_4_1.IMachine; +import org.virtualbox_4_1.IProgress; +import org.virtualbox_4_1.ISession; +import org.virtualbox_4_1.LockType; import org.virtualbox_4_1.StorageBus; -import javax.annotation.Nullable; -import java.util.Map; -import java.util.Set; - -import static com.google.common.base.Predicates.equalTo; -import static com.google.common.collect.Iterables.any; -import static com.google.common.collect.Iterables.transform; -import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_IMAGE_PREFIX; -import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_INSTALLATION_KEY_SEQUENCE; -import static org.testng.Assert.assertTrue; +import com.google.common.base.CaseFormat; +import com.google.common.base.Function; +import com.google.common.base.Predicate; +import com.google.common.base.Splitter; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Iterables; +import com.google.inject.Guice; +import com.google.inject.Injector; /** * @author Andrea Turli, Mattias Holmqvist @@ -61,7 +80,12 @@ public class CreateAndInstallVmLiveTest extends BaseVirtualBoxClientLiveTest { .createInjector(new GsonModule()).getInstance(Json.class)); private VmSpec vmSpecification; + private MasterSpec masterSpec; + private Injector injector; + private Function sshClientForIMachine; + private Predicate sshResponds; + @Override @BeforeClass(groups = "live") public void setupClient() { @@ -76,28 +100,31 @@ public class CreateAndInstallVmLiveTest extends BaseVirtualBoxClientLiveTest { .attachISO(0, 0, operatingSystemIso) .attachHardDisk(hardDisk) .attachISO(1, 1, guestAdditionsIso).build(); - vmSpecification = VmSpec.builder().id("jclouds-image-create-and-install-vm-test").name(vmName).memoryMB(512).osTypeId("") + vmSpecification = VmSpec.builder().id(vmName).name(vmName).memoryMB(512).osTypeId("") .controller(ideController) .forceOverwrite(true) .cleanUpMode(CleanupMode.Full).build(); - } - - public void testCreateImageMachineFromIso() throws Exception { - Injector injector = context.utils().injector(); + + injector = context.utils().injector(); Function configProperties = injector .getInstance(ValueOfConfigurationKeyOrNull.class); - MasterSpec masterSpec = MasterSpec.builder().vm(vmSpecification) - .iso(IsoSpec.builder() - .sourcePath(operatingSystemIso) - .installationScript(configProperties - .apply(VIRTUALBOX_INSTALLATION_KEY_SEQUENCE) - .replace("HOSTNAME", vmSpecification.getVmName())) - .build()) - .network(NetworkSpec.builder() - .natNetworkAdapter(0, NatAdapter.builder().tcpRedirectRule("127.0.0.1", 2222, "", 22).build()) - .build()).build(); - IMachine imageMachine = injector.getInstance(CreateAndInstallVm.class).apply(masterSpec); + masterSpec = MasterSpec.builder().vm(vmSpecification) + .iso(IsoSpec.builder() + .sourcePath(operatingSystemIso) + .installationScript(configProperties + .apply(VIRTUALBOX_INSTALLATION_KEY_SEQUENCE) + .replace("HOSTNAME", vmSpecification.getVmName())) + .build()) + .network(NetworkSpec.builder() + .natNetworkAdapter(0, NatAdapter.builder().tcpRedirectRule("127.0.0.1", 2222, "", 22).build()) + .build()).build(); + + undoVm(vmSpecification); + } + + public void testCreateImageMachineFromIso() throws Exception { + IMachine imageMachine = getVmWithGuestAdditionsInstalled(); IMachineToImage iMachineToImage = new IMachineToImage(manager, map); Image newImage = iMachineToImage.apply(imageMachine); @@ -107,6 +134,33 @@ public class CreateAndInstallVmLiveTest extends BaseVirtualBoxClientLiveTest { Iterable imageIds = transform(images, extractId()); assertTrue(any(imageIds, equalTo(newImage.getId()))); } + + @Test + public void testGuestAdditionsAreInstalled() throws Exception { + try { + IMachine machine = getVmWithGuestAdditionsInstalled(); + + machineUtils.applyForMachine(machine.getName(), new LaunchMachineIfNotAlreadyRunning(manager.get(), ExecutionType.GUI, "")); + sshClientForIMachine = injector.getInstance(IMachineToSshClient.class); + SshClient client = sshClientForIMachine.apply(machine); + + sshResponds = injector.getInstance(SshResponds.class); + checkState(sshResponds.apply(client), "timed out waiting for guest %s to be accessible via ssh", machine.getName()); + + assertTrue(machineUtils.lockSessionOnMachineAndApply(machine.getName(), LockType.Shared, new Function() { + @Override + public Boolean apply(ISession session) { + String vboxVersion = Iterables.get(Splitter.on('r').split(context.getProviderSpecificContext().getBuildVersion()), 0); + return session.getMachine().getGuestPropertyValue("/VirtualBox/GuestAdd/Version").equals(vboxVersion); + } + })); + } finally { + for (VmSpec spec : ImmutableSet.of( + vmSpecification)) { + ensureMachineHasPowerDown(spec.getVmName()); + } + } + } private Function extractId() { return new Function() { @@ -118,10 +172,37 @@ public class CreateAndInstallVmLiveTest extends BaseVirtualBoxClientLiveTest { }; } + private IMachine getVmWithGuestAdditionsInstalled() { + try { + Injector injector = context.utils().injector(); + return injector.getInstance( + CreateAndInstallVm.class).apply( + masterSpec); + } catch (IllegalStateException e) { + // already created + return manager.get().getVBox() + .findMachine(masterSpec.getVmSpec().getVmId()); + } + } + + private void ensureMachineHasPowerDown(String vmName) { + machineUtils.lockSessionOnMachineAndApply(vmName, LockType.Shared, new Function() { + @Override + public Void apply(ISession session) { + IProgress powerDownProgress = session.getConsole().powerDown(); + powerDownProgress.waitForCompletion(-1); + return null; + } + }); + } + @Override @AfterClass(groups = "live") protected void tearDown() throws Exception { - undoVm(vmSpecification); + for (VmSpec spec : ImmutableSet.of( + vmSpecification)) { + undoVm(spec); + } super.tearDown(); } } diff --git a/labs/virtualbox/src/test/java/org/jclouds/virtualbox/predicates/IMachinePredicatesLiveTest.java b/labs/virtualbox/src/test/java/org/jclouds/virtualbox/predicates/IMachinePredicatesLiveTest.java index 085f225a9d..00d2196579 100644 --- a/labs/virtualbox/src/test/java/org/jclouds/virtualbox/predicates/IMachinePredicatesLiveTest.java +++ b/labs/virtualbox/src/test/java/org/jclouds/virtualbox/predicates/IMachinePredicatesLiveTest.java @@ -96,17 +96,6 @@ public class IMachinePredicatesLiveTest extends BaseVirtualBoxClientLiveTest { assertTrue(isLinkedClone().apply(clone)); } - /* - * public void testFullClone() { IMachine master = - * context.utils().injector(). - * getInstance(CreateAndRegisterMachineFromIsoIfNotAlreadyExists.class) - * .apply(masterSpec); IMachine clone = new - * CloneAndRegisterMachineFromIMachineIfNotAlreadyExists(manager, workingDir, - * cloneSpec, !IS_LINKED_CLONE).apply(master); - * - * assertFalse(new IsLinkedClone(manager).apply(clone)); } - */ - @BeforeMethod @AfterMethod void cleanUpVms() { From 328621e961625c7a091e9221ada474f5835489c7 Mon Sep 17 00:00:00 2001 From: andreaturli Date: Sun, 19 Feb 2012 10:59:45 +0000 Subject: [PATCH 2/2] issue 384: fixed GuestAdditions LiveTest - Adrian comments addressed --- .../compute/VirtualBoxComputeServiceAdapter.java | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/labs/virtualbox/src/main/java/org/jclouds/virtualbox/compute/VirtualBoxComputeServiceAdapter.java b/labs/virtualbox/src/main/java/org/jclouds/virtualbox/compute/VirtualBoxComputeServiceAdapter.java index 4081ec1854..1b031d1370 100644 --- a/labs/virtualbox/src/main/java/org/jclouds/virtualbox/compute/VirtualBoxComputeServiceAdapter.java +++ b/labs/virtualbox/src/main/java/org/jclouds/virtualbox/compute/VirtualBoxComputeServiceAdapter.java @@ -139,7 +139,7 @@ public class VirtualBoxComputeServiceAdapter implements ComputeServiceAdapter T propogate(Exception e) { - Throwables.propagate(e); - assert false; - return null; - } - private void launchVMProcess(IMachine machine, ISession session) { IProgress prog = machine.launchVMProcess(session, "gui", ""); prog.waitForCompletion(-1); @@ -184,7 +178,7 @@ public class VirtualBoxComputeServiceAdapter implements ComputeServiceAdapter