From c46c0b4c47b669b1b8f48aa0bf7ece9b0719ef8c Mon Sep 17 00:00:00 2001 From: andreaturli Date: Fri, 23 Sep 2011 23:10:02 +0100 Subject: [PATCH] issue 384: VirtualBoxComputeServiceAdapter --- .../virtualbox/VirtualBoxContextBuilder.java | 16 +- .../VirtualBoxComputeServiceAdapter.java | 165 +++++++++++++----- ...VirtualBoxComputeServiceContextModule.java | 36 +++- .../functions/IMachineToNodeMetadata.java | 41 +++-- .../virtualbox/experiment/TestUtils.java | 45 ----- 5 files changed, 183 insertions(+), 120 deletions(-) diff --git a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/VirtualBoxContextBuilder.java b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/VirtualBoxContextBuilder.java index 21f4af813f..e11d4c4769 100644 --- a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/VirtualBoxContextBuilder.java +++ b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/VirtualBoxContextBuilder.java @@ -21,22 +21,24 @@ package org.jclouds.virtualbox; -import com.google.inject.Module; -import org.jclouds.compute.StandaloneComputeServiceContextBuilder; -import org.jclouds.virtualbox.config.VirtualBoxComputeServiceContextModule; - import java.util.List; import java.util.Properties; +import org.jclouds.compute.StandaloneComputeServiceContextBuilder; +import org.jclouds.virtualbox.config.VirtualBoxComputeServiceContextModule; +import org.virtualbox_4_1.VirtualBoxManager; + +import com.google.inject.Module; + /** * Creates compute service context for VirtualBox * - * @author Mattias Holmqvist + * @author Mattias Holmqvist, Andrea Turli */ -public class VirtualBoxContextBuilder extends StandaloneComputeServiceContextBuilder { +public class VirtualBoxContextBuilder extends StandaloneComputeServiceContextBuilder { public VirtualBoxContextBuilder(Properties properties) { - super(VirtualBox.class, properties); + super(VirtualBoxManager.class, properties); } @Override diff --git a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/compute/VirtualBoxComputeServiceAdapter.java b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/compute/VirtualBoxComputeServiceAdapter.java index 66290371ac..c329e63552 100644 --- a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/compute/VirtualBoxComputeServiceAdapter.java +++ b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/compute/VirtualBoxComputeServiceAdapter.java @@ -21,74 +21,147 @@ package org.jclouds.virtualbox.compute; -import com.google.inject.Singleton; -import org.jclouds.compute.ComputeServiceAdapter; -import org.jclouds.compute.domain.Template; -import org.jclouds.domain.Credentials; -import org.jclouds.virtualbox.domain.VMSpec; -import org.jclouds.virtualbox.domain.Host; -import org.jclouds.virtualbox.domain.Image; -import org.virtualbox_4_1.IMachine; +import static com.google.common.base.Preconditions.checkNotNull; import java.util.Collections; import java.util.Map; +import javax.inject.Inject; + +import org.jclouds.compute.ComputeServiceAdapter; +import org.jclouds.compute.domain.Template; +import org.jclouds.domain.Credentials; +import org.jclouds.virtualbox.domain.Host; +import org.jclouds.virtualbox.domain.Image; +import org.jclouds.virtualbox.domain.VMSpec; +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.SessionState; +import org.virtualbox_4_1.VirtualBoxManager; + +import com.google.common.base.Throwables; +import com.google.inject.Singleton; + /** - * Defines the connection between the {@link org.jclouds.virtualbox.VirtualBox} implementation and the jclouds + * Defines the connection between the {@link org.virtualbox_4_1.VirtualBoxManager} implementation and the jclouds * {@link org.jclouds.compute.ComputeService} * - * @author Mattias Holmqvist + * @author Mattias Holmqvist, Andrea Turli */ @Singleton public class VirtualBoxComputeServiceAdapter implements ComputeServiceAdapter { - @Override - public IMachine createNodeWithGroupEncodedIntoNameThenStoreCredentials(String tag, String name, Template template, Map credentialStore) { - return null; - } + private final VirtualBoxManager manager; - @Override - public Iterable listHardwareProfiles() { - return Collections.emptyList(); - } + @Inject + public VirtualBoxComputeServiceAdapter(VirtualBoxManager manager) { + this.manager = checkNotNull(manager, "manager"); + } - @Override - public Iterable listImages() { - return Collections.emptyList(); - } + @Override + public IMachine createNodeWithGroupEncodedIntoNameThenStoreCredentials(String tag, String name, Template template, Map credentialStore) { + return null; + } - @Override - public Iterable listLocations() { - return Collections.emptyList(); - } + @Override + public Iterable listNodes() { + return Collections.emptyList(); + } + + @Override + public Iterable listHardwareProfiles() { + return Collections.emptyList(); + } - @Override - public IMachine getNode(String id) { - return null; - } + @Override + public Iterable listImages() { + return Collections.emptyList(); + } - @Override - public void destroyNode(String id) { + @Override + public Iterable listLocations() { + return Collections.emptyList(); + } - } + @Override + public IMachine getNode(String vmName) { + return manager.getVBox().findMachine(vmName); + } - @Override - public void rebootNode(String id) { + @Override + public void destroyNode(String vmName) { + IMachine machine = manager.getVBox().findMachine(vmName); + powerDownMachine(machine); + machine.unregister(CleanupMode.Full); + } - } + @Override + public void rebootNode(String vmName) { + IMachine machine = manager.getVBox().findMachine(vmName); + powerDownMachine(machine); + launchVMProcess(machine, manager.getSessionObject()); + } - @Override - public void resumeNode(String id) { + @Override + public void resumeNode(String vmName) { + IMachine machine = manager.getVBox().findMachine(vmName); + ISession machineSession; + try { + machineSession = manager.openMachineSession(machine); + machineSession.getConsole().resume(); + machineSession.unlockMachine(); + } catch (Exception e) { + propogate(e); + } + } - } + @Override + public void suspendNode(String vmName) { + IMachine machine = manager.getVBox().findMachine(vmName); + ISession machineSession; + try { + machineSession = manager.openMachineSession(machine); + machineSession.getConsole().pause(); + machineSession.unlockMachine(); + } catch (Exception e) { + propogate(e); + } + } - @Override - public void suspendNode(String id) { + protected 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); + session.unlockMachine(); + } + + private void powerDownMachine(IMachine machine) { + try { + ISession machineSession = manager.openMachineSession(machine); + IProgress progress = machineSession.getConsole().powerDown(); + progress.waitForCompletion(-1); + machineSession.unlockMachine(); - } + while (!machine.getSessionState().equals(SessionState.Unlocked)) { + try { + System.out + .println("waiting for unlocking session - session state: " + + machine.getSessionState()); + Thread.sleep(1000); + } catch (InterruptedException e) { + } + } - @Override - public Iterable listNodes() { - return Collections.emptyList(); - } + } catch (Exception e) { + e.printStackTrace(); + e.printStackTrace(); + } + } } diff --git a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/config/VirtualBoxComputeServiceContextModule.java b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/config/VirtualBoxComputeServiceContextModule.java index a0f1f81329..0f239a20ab 100644 --- a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/config/VirtualBoxComputeServiceContextModule.java +++ b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/config/VirtualBoxComputeServiceContextModule.java @@ -21,35 +21,53 @@ package org.jclouds.virtualbox.config; -import com.google.common.base.Function; -import com.google.common.base.Supplier; -import com.google.inject.Injector; -import com.google.inject.TypeLiteral; +import java.net.URI; + +import javax.inject.Named; +import javax.inject.Singleton; + +import org.jclouds.Constants; import org.jclouds.compute.ComputeServiceAdapter; import org.jclouds.compute.config.ComputeServiceAdapterContextModule; import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.OsFamily; import org.jclouds.compute.domain.TemplateBuilder; import org.jclouds.domain.Location; +import org.jclouds.location.Provider; import org.jclouds.location.suppliers.OnlyLocationOrFirstZone; -import org.jclouds.virtualbox.VirtualBox; import org.jclouds.virtualbox.compute.VirtualBoxComputeServiceAdapter; -import org.jclouds.virtualbox.domain.VMSpec; import org.jclouds.virtualbox.domain.Host; import org.jclouds.virtualbox.domain.Image; +import org.jclouds.virtualbox.domain.VMSpec; import org.jclouds.virtualbox.functions.HostToLocation; import org.jclouds.virtualbox.functions.IMachineToNodeMetadata; import org.jclouds.virtualbox.functions.ImageToImage; import org.jclouds.virtualbox.functions.VMSpecToHardware; import org.virtualbox_4_1.IMachine; +import org.virtualbox_4_1.VirtualBoxManager; + +import com.google.common.base.Function; +import com.google.common.base.Supplier; +import com.google.inject.Injector; +import com.google.inject.Provides; +import com.google.inject.TypeLiteral; /** - * @author Mattias Holmqvist + * @author Mattias Holmqvist, Andrea Turli */ -public class VirtualBoxComputeServiceContextModule extends ComputeServiceAdapterContextModule { +public class VirtualBoxComputeServiceContextModule extends ComputeServiceAdapterContextModule { public VirtualBoxComputeServiceContextModule() { - super(VirtualBox.class, VirtualBox.class); + super(VirtualBoxManager.class, VirtualBoxManager.class); + } + + @Provides + @Singleton + protected VirtualBoxManager createInstance(@Provider URI endpoint, @Named(Constants.PROPERTY_IDENTITY) String identity, + @Named(Constants.PROPERTY_CREDENTIAL) String credential) { + VirtualBoxManager manager = VirtualBoxManager.createInstance(""); + manager.connect(endpoint.toASCIIString(), identity, credential); + return manager; } @Override diff --git a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/IMachineToNodeMetadata.java b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/IMachineToNodeMetadata.java index 6dda4c7e6e..d8eaddcf1d 100644 --- a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/IMachineToNodeMetadata.java +++ b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/IMachineToNodeMetadata.java @@ -19,23 +19,37 @@ package org.jclouds.virtualbox.functions; -import com.google.common.base.Function; -import org.jclouds.compute.domain.*; -import org.jclouds.compute.reference.ComputeServiceConstants; -import org.jclouds.domain.Credentials; -import org.jclouds.domain.LocationBuilder; -import org.jclouds.domain.LocationScope; -import org.jclouds.javax.annotation.Nullable; -import org.jclouds.logging.Logger; -import org.virtualbox_4_1.*; - -import javax.annotation.Resource; -import javax.inject.Named; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; +import javax.annotation.Resource; +import javax.inject.Named; + +import org.eclipse.jetty.server.Server; +import org.jclouds.collect.FindResourceInSet; +import org.jclouds.collect.Memoized; +import org.jclouds.compute.domain.HardwareBuilder; +import org.jclouds.compute.domain.NodeMetadata; +import org.jclouds.compute.domain.NodeMetadataBuilder; +import org.jclouds.compute.domain.NodeState; +import org.jclouds.compute.domain.Processor; +import org.jclouds.compute.reference.ComputeServiceConstants; +import org.jclouds.domain.Credentials; +import org.jclouds.domain.Location; +import org.jclouds.domain.LocationBuilder; +import org.jclouds.domain.LocationScope; +import org.jclouds.javax.annotation.Nullable; +import org.jclouds.logging.Logger; +import org.virtualbox_4_1.IMachine; +import org.virtualbox_4_1.MachineState; + +import com.google.common.base.Function; +import com.google.common.base.Supplier; +import com.google.inject.Inject; +import com.google.inject.Singleton; + public class IMachineToNodeMetadata implements Function { @Resource @@ -55,6 +69,7 @@ public class IMachineToNodeMetadata implements Function locationBuilder.id(""); locationBuilder.scope(LocationScope.HOST); nodeMetadataBuilder.location(locationBuilder.build()); + HardwareBuilder hardwareBuilder = new HardwareBuilder(); hardwareBuilder.ram(vm.getMemorySize().intValue()); @@ -119,6 +134,6 @@ public class IMachineToNodeMetadata implements Function nodeMetadataBuilder.credentials(new Credentials(identity, credential)); nodeMetadataBuilder.id(vm.getId()); return nodeMetadataBuilder.build(); - } + } diff --git a/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/experiment/TestUtils.java b/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/experiment/TestUtils.java index 3aed31e8cf..c5a352f41b 100644 --- a/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/experiment/TestUtils.java +++ b/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/experiment/TestUtils.java @@ -68,51 +68,6 @@ public class TestUtils { return new ComputeServiceContextFactory().createContext("byon", "foo", "bar", ImmutableSet.of( new SshjSshClientModule(), new SLF4JLoggingModule(), new BouncyCastleCryptoModule(), new CacheNodeStoreModule(nodeMap))); } - - public static ComputeServiceContext computeServiceForVBox() throws IOException { - - Node host = Node.builder().id("host") - .name("host installing virtualbox") - .hostname("localhost") - .osFamily(OsFamily.LINUX.toString()) - .osDescription(System.getProperty("os.name")) - .osVersion(System.getProperty("os.version")) - .group("ssh") - .username(System.getProperty("user.name")) - .credentialUrl(privateKeyFile()) - .build(); - Node guest = Node.builder().id("guest") - .name("new guest") - .hostname("localhost") - .loginPort(2222) - .osFamily(OsFamily.UBUNTU.toString()) - .osDescription("ubuntu/11.04") - .osVersion(System.getProperty("11.04")) - .group("guest") - .username("toor") - .sudoPassword("password") - .credential("password") - .build(); - - - final CacheLoader cacheLoader = new CacheLoader() { - /* - * (non-Javadoc) - * @see com.google.common.cache.CacheLoader#load(java.lang.Object) - * this will take the machine from vbox and convert to a node by id - * so you would use vbox/arp commands whatever and then return Node.builder()..... - * inside the load method - */ - @Override - public Node load(String instanceName) throws Exception { - // TODO Auto-generated method stub - return null; - } - }; - - return new ComputeServiceContextFactory().createContext("byon", "foo", "bar", ImmutableSet.of( - new SshjSshClientModule(), new SLF4JLoggingModule(), new BouncyCastleCryptoModule(), new CacheNodeStoreModule(cacheLoader))); - } private static URI privateKeyFile() { try {