formatted most changed classes to comply with jclouds formatting guildelines

This commit is contained in:
David Ribeiro Alves 2012-03-05 17:03:15 +00:00
parent c08cbc89f4
commit fa26fe34f9
24 changed files with 1190 additions and 1281 deletions

View File

@ -44,49 +44,50 @@ import org.jclouds.PropertiesBuilder;
*/ */
public class VirtualBoxPropertiesBuilder extends PropertiesBuilder { public class VirtualBoxPropertiesBuilder extends PropertiesBuilder {
public VirtualBoxPropertiesBuilder() { public VirtualBoxPropertiesBuilder() {
super(); super();
} }
public VirtualBoxPropertiesBuilder(Properties properties) { public VirtualBoxPropertiesBuilder(Properties properties) {
super(properties); super(properties);
} }
@Override @Override
protected Properties defaultProperties() { protected Properties defaultProperties() {
Properties properties = super.defaultProperties(); Properties properties = super.defaultProperties();
properties.put(PROPERTY_ENDPOINT, "http://localhost:18083/"); properties.put(PROPERTY_ENDPOINT, "http://localhost:18083/");
// later version not in maven, yet // later version not in maven, yet
properties.put(PROPERTY_API_VERSION, "4.1.4"); properties.put(PROPERTY_API_VERSION, "4.1.4");
properties.put(PROPERTY_BUILD_VERSION, "4.1.8r75467"); properties.put(PROPERTY_BUILD_VERSION, "4.1.8r75467");
properties.put(PROPERTY_IDENTITY, "administrator"); properties.put(PROPERTY_IDENTITY, "administrator");
properties.put(PROPERTY_CREDENTIAL, "12345"); properties.put(PROPERTY_CREDENTIAL, "12345");
properties.put(PROPERTY_IMAGE_LOGIN_USER, "toor:password"); properties.put(PROPERTY_IMAGE_LOGIN_USER, "toor:password");
properties.put(PROPERTY_IMAGE_AUTHENTICATE_SUDO, "true"); properties.put(PROPERTY_IMAGE_AUTHENTICATE_SUDO, "true");
properties.put(VIRTUALBOX_INSTALLATION_KEY_SEQUENCE, "<Esc><Esc><Enter> " properties.put(VIRTUALBOX_INSTALLATION_KEY_SEQUENCE, "<Esc><Esc><Enter> "
+ "/install/vmlinuz noapic preseed/url=PRECONFIGURATION_URL " + "/install/vmlinuz noapic preseed/url=PRECONFIGURATION_URL "
+ "debian-installer=en_US auto locale=en_US kbd-chooser/method=us " + "hostname=" + "HOSTNAME " + "debian-installer=en_US auto locale=en_US kbd-chooser/method=us " + "hostname=" + "HOSTNAME "
+ "fb=false debconf/frontend=noninteractive " + "fb=false debconf/frontend=noninteractive "
+ "keyboard-configuration/layout=USA keyboard-configuration/variant=USA console-setup/ask_detect=false " + "keyboard-configuration/layout=USA keyboard-configuration/variant=USA console-setup/ask_detect=false "
+ "initrd=/install/initrd.gz -- <Enter>"); + "initrd=/install/initrd.gz -- <Enter>");
properties.put( properties.put(
VIRTUALBOX_WORKINGDIR, VIRTUALBOX_WORKINGDIR,
System.getProperty("user.home") + File.separator System.getProperty("user.home") + File.separator
+ System.getProperty("test.virtualbox.workingDir", ".jclouds-vbox")); + System.getProperty("test.virtualbox.workingDir", ".jclouds-vbox"));
// allow to set the descriptor as a sysprop but default to just setting a default file path. The configured supplier // allow to set the descriptor as a sysprop but default to just setting a default file path.
// must be able to handle the chosen option. // The configured supplier
properties.put( // must be able to handle the chosen option.
VIRTUALBOX_IMAGES_DESCRIPTOR, properties.put(
System.getProperty("test.virtualbox.image.descriptor.yaml", VIRTUALBOX_DEFAULT_DIR + File.separator VIRTUALBOX_IMAGES_DESCRIPTOR,
+ "images.yaml")); System.getProperty("test.virtualbox.image.descriptor.yaml", VIRTUALBOX_DEFAULT_DIR + File.separator
+ "images.yaml"));
properties.put(VIRTUALBOX_PRECONFIGURATION_URL, "http://10.0.2.2:8080/src/test/resources/preseed.cfg"); properties.put(VIRTUALBOX_PRECONFIGURATION_URL, "http://10.0.2.2:8080/src/test/resources/preseed.cfg");
return properties; return properties;
} }
} }

View File

@ -53,147 +53,147 @@ import com.google.common.collect.Iterables;
import com.google.inject.Singleton; import com.google.inject.Singleton;
/** /**
* Defines the connection between the {@link org.virtualbox_4_1.VirtualBoxManager} implementation and the jclouds * Defines the connection between the {@link org.virtualbox_4_1.VirtualBoxManager} implementation
* {@link org.jclouds.compute.ComputeService} * and the jclouds {@link org.jclouds.compute.ComputeService}
* *
* @author Mattias Holmqvist, Andrea Turli * @author Mattias Holmqvist, Andrea Turli
*/ */
@Singleton @Singleton
public class VirtualBoxComputeServiceAdapter implements ComputeServiceAdapter<IMachine, IMachine, Image, Location> { public class VirtualBoxComputeServiceAdapter implements ComputeServiceAdapter<IMachine, IMachine, Image, Location> {
private final Supplier<VirtualBoxManager> manager; private final Supplier<VirtualBoxManager> manager;
private final Map<Image, YamlImage> images; private final Map<Image, YamlImage> images;
private final LoadingCache<Image, Master> mastersLoader; private final LoadingCache<Image, Master> mastersLoader;
private final Function<NodeSpec, NodeAndInitialCredentials<IMachine>> cloneCreator; private final Function<NodeSpec, NodeAndInitialCredentials<IMachine>> cloneCreator;
@Inject @Inject
public VirtualBoxComputeServiceAdapter(Supplier<VirtualBoxManager> manager, public VirtualBoxComputeServiceAdapter(Supplier<VirtualBoxManager> manager,
Supplier<Map<Image, YamlImage>> imagesMapper, LoadingCache<Image, Master> mastersLoader, Supplier<Map<Image, YamlImage>> imagesMapper, LoadingCache<Image, Master> mastersLoader,
Function<NodeSpec, NodeAndInitialCredentials<IMachine>> cloneCreator) { Function<NodeSpec, NodeAndInitialCredentials<IMachine>> cloneCreator) {
this.manager = checkNotNull(manager, "manager"); this.manager = checkNotNull(manager, "manager");
this.images = imagesMapper.get(); this.images = imagesMapper.get();
this.mastersLoader = mastersLoader; this.mastersLoader = mastersLoader;
this.cloneCreator = cloneCreator; this.cloneCreator = cloneCreator;
} }
@Override @Override
public NodeAndInitialCredentials<IMachine> createNodeWithGroupEncodedIntoName(String tag, String name, public NodeAndInitialCredentials<IMachine> createNodeWithGroupEncodedIntoName(String tag, String name,
Template template) { Template template) {
try { try {
Master master = mastersLoader.get(template.getImage()); Master master = mastersLoader.get(template.getImage());
NodeSpec nodeSpec = NodeSpec.builder().master(master).name(name).tag(tag).template(template).build(); NodeSpec nodeSpec = NodeSpec.builder().master(master).name(name).tag(tag).template(template).build();
return cloneCreator.apply(nodeSpec); return cloneCreator.apply(nodeSpec);
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException(e); throw new RuntimeException(e);
}
}
@Override
public Iterable<IMachine> listNodes() {
return Iterables.filter(manager.get().getVBox().getMachines(), new Predicate<IMachine>() {
@Override
public boolean apply(IMachine arg0) {
return !arg0.getName().startsWith(VIRTUALBOX_NODE_PREFIX);
} }
}); }
}
@Override @Override
public Iterable<IMachine> listHardwareProfiles() { public Iterable<IMachine> listNodes() {
return imageMachines(); return Iterables.filter(manager.get().getVBox().getMachines(), new Predicate<IMachine>() {
} @Override
public boolean apply(IMachine arg0) {
return !arg0.getName().startsWith(VIRTUALBOX_NODE_PREFIX);
}
});
}
@Override @Override
public Iterable<Image> listImages() { public Iterable<IMachine> listHardwareProfiles() {
return images.keySet(); return imageMachines();
} }
private Iterable<IMachine> imageMachines() { @Override
final Predicate<? super IMachine> imagePredicate = new Predicate<IMachine>() { public Iterable<Image> listImages() {
@Override return images.keySet();
public boolean apply(@Nullable IMachine iMachine) { }
return iMachine.getName().startsWith(VIRTUALBOX_IMAGE_PREFIX);
private Iterable<IMachine> imageMachines() {
final Predicate<? super IMachine> imagePredicate = new Predicate<IMachine>() {
@Override
public boolean apply(@Nullable IMachine iMachine) {
return iMachine.getName().startsWith(VIRTUALBOX_IMAGE_PREFIX);
}
};
final Iterable<IMachine> imageMachines = filter(manager.get().getVBox().getMachines(), imagePredicate);
return imageMachines;
}
@Override
public Iterable<Location> listLocations() {
// Not using the adapter to determine locations
return ImmutableSet.<Location> of();
}
@Override
public IMachine getNode(String vmName) {
return manager.get().getVBox().findMachine(vmName);
}
@Override
public void destroyNode(String vmName) {
IMachine machine = manager.get().getVBox().findMachine(vmName);
powerDownMachine(machine);
machine.unregister(CleanupMode.Full);
}
@Override
public void rebootNode(String vmName) {
IMachine machine = manager.get().getVBox().findMachine(vmName);
powerDownMachine(machine);
launchVMProcess(machine, manager.get().getSessionObject());
}
@Override
public void resumeNode(String vmName) {
IMachine machine = manager.get().getVBox().findMachine(vmName);
ISession machineSession;
try {
machineSession = manager.get().openMachineSession(machine);
machineSession.getConsole().resume();
machineSession.unlockMachine();
} catch (Exception e) {
throw Throwables.propagate(e);
} }
}; }
final Iterable<IMachine> imageMachines = filter(manager.get().getVBox().getMachines(), imagePredicate);
return imageMachines;
}
@Override @Override
public Iterable<Location> listLocations() { public void suspendNode(String vmName) {
// Not using the adapter to determine locations IMachine machine = manager.get().getVBox().findMachine(vmName);
return ImmutableSet.<Location> of(); ISession machineSession;
} try {
machineSession = manager.get().openMachineSession(machine);
@Override machineSession.getConsole().pause();
public IMachine getNode(String vmName) { machineSession.unlockMachine();
return manager.get().getVBox().findMachine(vmName); } catch (Exception e) {
} throw Throwables.propagate(e);
@Override
public void destroyNode(String vmName) {
IMachine machine = manager.get().getVBox().findMachine(vmName);
powerDownMachine(machine);
machine.unregister(CleanupMode.Full);
}
@Override
public void rebootNode(String vmName) {
IMachine machine = manager.get().getVBox().findMachine(vmName);
powerDownMachine(machine);
launchVMProcess(machine, manager.get().getSessionObject());
}
@Override
public void resumeNode(String vmName) {
IMachine machine = manager.get().getVBox().findMachine(vmName);
ISession machineSession;
try {
machineSession = manager.get().openMachineSession(machine);
machineSession.getConsole().resume();
machineSession.unlockMachine();
} catch (Exception e) {
throw Throwables.propagate(e);
}
}
@Override
public void suspendNode(String vmName) {
IMachine machine = manager.get().getVBox().findMachine(vmName);
ISession machineSession;
try {
machineSession = manager.get().openMachineSession(machine);
machineSession.getConsole().pause();
machineSession.unlockMachine();
} catch (Exception e) {
throw Throwables.propagate(e);
}
}
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.get().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) {
}
} }
}
} catch (Exception e) { private void launchVMProcess(IMachine machine, ISession session) {
throw Throwables.propagate(e); IProgress prog = machine.launchVMProcess(session, "gui", "");
} prog.waitForCompletion(-1);
} session.unlockMachine();
}
private void powerDownMachine(IMachine machine) {
try {
ISession machineSession = manager.get().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) {
}
}
} catch (Exception e) {
throw Throwables.propagate(e);
}
}
} }

View File

@ -103,185 +103,166 @@ import com.google.inject.TypeLiteral;
*/ */
@SuppressWarnings({ "unchecked", "rawtypes" }) @SuppressWarnings({ "unchecked", "rawtypes" })
public class VirtualBoxComputeServiceContextModule extends public class VirtualBoxComputeServiceContextModule extends
ComputeServiceAdapterContextModule<Supplier, Supplier, IMachine, IMachine, Image, Location> { ComputeServiceAdapterContextModule<Supplier, Supplier, IMachine, IMachine, Image, Location> {
public VirtualBoxComputeServiceContextModule() { public VirtualBoxComputeServiceContextModule() {
super(Supplier.class, Supplier.class); super(Supplier.class, Supplier.class);
} }
@Override @Override
protected void configure() { protected void configure() {
super.configure(); super.configure();
bind(new TypeLiteral<ComputeServiceAdapter<IMachine, IMachine, Image, Location>>() { bind(new TypeLiteral<ComputeServiceAdapter<IMachine, IMachine, Image, Location>>() {
}).to(VirtualBoxComputeServiceAdapter.class); }).to(VirtualBoxComputeServiceAdapter.class);
bind(new TypeLiteral<Function<IMachine, NodeMetadata>>() { bind(new TypeLiteral<Function<IMachine, NodeMetadata>>() {
}).to(IMachineToNodeMetadata.class); }).to(IMachineToNodeMetadata.class);
bind(new TypeLiteral<Function<Location, Location>>() { bind(new TypeLiteral<Function<Location, Location>>() {
}).to((Class) IdentityFunction.class); }).to((Class) IdentityFunction.class);
bind(new TypeLiteral<Function<Image, Image>>() { bind(new TypeLiteral<Function<Image, Image>>() {
}).to((Class) IdentityFunction.class); }).to((Class) IdentityFunction.class);
bind(new TypeLiteral<Function<IMachine, Hardware>>() { bind(new TypeLiteral<Function<IMachine, Hardware>>() {
}).to(IMachineToHardware.class); }).to(IMachineToHardware.class);
bind(new TypeLiteral<Function<IMachine, Image>>() { bind(new TypeLiteral<Function<IMachine, Image>>() {
}).to(IMachineToImage.class); }).to(IMachineToImage.class);
bind(new TypeLiteral<CacheLoader<IsoSpec, URI>>() { bind(new TypeLiteral<CacheLoader<IsoSpec, URI>>() {
}).to((Class) StartJettyIfNotAlreadyRunning.class); }).to((Class) StartJettyIfNotAlreadyRunning.class);
bind(new TypeLiteral<Supplier<VirtualBoxManager>>() { bind(new TypeLiteral<Supplier<VirtualBoxManager>>() {
}).to((Class) StartVBoxIfNotAlreadyRunning.class); }).to((Class) StartVBoxIfNotAlreadyRunning.class);
// the yaml config to image mapper // the yaml config to image mapper
bind(new TypeLiteral<Supplier<Map<Image, YamlImage>>>() { bind(new TypeLiteral<Supplier<Map<Image, YamlImage>>>() {
}).to((Class) ImagesToYamlImagesFromYamlDescriptor.class); }).to((Class) ImagesToYamlImagesFromYamlDescriptor.class);
// the yaml config provider // the yaml config provider
bind(new TypeLiteral<Supplier<String>>() { bind(new TypeLiteral<Supplier<String>>() {
}).to((Class) YamlImagesFromFileConfig.class); }).to((Class) YamlImagesFromFileConfig.class);
// the master machines cache // the master machines cache
bind(new TypeLiteral<LoadingCache<Image, Master>>() { bind(new TypeLiteral<LoadingCache<Image, Master>>() {
}).to((Class) MastersCache.class); }).to((Class) MastersCache.class);
// the master creating function // the master creating function
bind(new TypeLiteral<Function<MasterSpec, IMachine>>() { bind(new TypeLiteral<Function<MasterSpec, IMachine>>() {
}).to((Class) CreateAndInstallVm.class); }).to((Class) CreateAndInstallVm.class);
// the machine cloning function // the machine cloning function
bind(new TypeLiteral<Function<NodeSpec, NodeAndInitialCredentials<IMachine>>>() { bind(new TypeLiteral<Function<NodeSpec, NodeAndInitialCredentials<IMachine>>>() {
}).to((Class) NodeCreator.class); }).to((Class) NodeCreator.class);
bind(new TypeLiteral<Function<CloneSpec, IMachine>>() { bind(new TypeLiteral<Function<CloneSpec, IMachine>>() {
}).to((Class) CloneAndRegisterMachineFromIMachineIfNotAlreadyExists.class); }).to((Class) CloneAndRegisterMachineFromIMachineIfNotAlreadyExists.class);
// for byon // for byon
bind(new TypeLiteral<Function<URI, InputStream>>() { bind(new TypeLiteral<Function<URI, InputStream>>() {
}).to(SupplyFromProviderURIOrNodesProperty.class); }).to(SupplyFromProviderURIOrNodesProperty.class);
bind(new TypeLiteral<Function<IMachine, SshClient>>() { bind(new TypeLiteral<Function<IMachine, SshClient>>() {
}).to(IMachineToSshClient.class); }).to(IMachineToSshClient.class);
bind(ExecutionType.class).toInstance(ExecutionType.GUI); bind(ExecutionType.class).toInstance(ExecutionType.GUI);
bind(LockType.class).toInstance(LockType.Write); bind(LockType.class).toInstance(LockType.Write);
} }
@Provides @Provides
@Singleton @Singleton
@Preconfiguration @Preconfiguration
protected LoadingCache<IsoSpec, URI> preconfiguration(CacheLoader<IsoSpec, URI> cacheLoader) { protected LoadingCache<IsoSpec, URI> preconfiguration(CacheLoader<IsoSpec, URI> cacheLoader) {
return CacheBuilder.newBuilder().build(cacheLoader); return CacheBuilder.newBuilder().build(cacheLoader);
} }
@Provides @Provides
@Host @Host
@Singleton @Singleton
protected ComputeServiceContext provideHostController() { protected ComputeServiceContext provideHostController() {
String provider = "byon"; String provider = "byon";
String identity = ""; String identity = "";
String credential = ""; String credential = "";
CacheNodeStoreModule hostModule = new CacheNodeStoreModule(ImmutableMap.of( CacheNodeStoreModule hostModule = new CacheNodeStoreModule(ImmutableMap.of(
"host", "host",
Node.builder().id("host").name("host installing virtualbox").hostname("localhost") Node.builder().id("host").name("host installing virtualbox").hostname("localhost")
.osFamily(OsFamily.LINUX.toString()).osDescription(System.getProperty("os.name")) .osFamily(OsFamily.LINUX.toString()).osDescription(System.getProperty("os.name"))
.osVersion(System.getProperty("os.version")).group("ssh").username(System.getProperty("user.name")) .osVersion(System.getProperty("os.version")).group("ssh")
.credentialUrl(URI.create("file://" + System.getProperty("user.home") + "/.ssh/id_rsa")).build())); .username(System.getProperty("user.name"))
return new ComputeServiceContextFactory().createContext(provider, identity, credential, .credentialUrl(URI.create("file://" + System.getProperty("user.home") + "/.ssh/id_rsa"))
ImmutableSet.<Module> of(new SLF4JLoggingModule(), new SshjSshClientModule(), hostModule)); .build()));
} return new ComputeServiceContextFactory().createContext(provider, identity, credential,
ImmutableSet.<Module> of(new SLF4JLoggingModule(), new SshjSshClientModule(), hostModule));
}
@Provides @Provides
@Singleton @Singleton
protected Server providesJettyServer(@Named(VIRTUALBOX_PRECONFIGURATION_URL) String preconfigurationUrl) { protected Server providesJettyServer(@Named(VIRTUALBOX_PRECONFIGURATION_URL) String preconfigurationUrl) {
return new Server(URI.create(preconfigurationUrl).getPort()); return new Server(URI.create(preconfigurationUrl).getPort());
} }
@Provides @Provides
@Singleton @Singleton
protected Function<Supplier<NodeMetadata>, VirtualBoxManager> provideVBox() { protected Function<Supplier<NodeMetadata>, VirtualBoxManager> provideVBox() {
return new Function<Supplier<NodeMetadata>, VirtualBoxManager>() { return new Function<Supplier<NodeMetadata>, VirtualBoxManager>() {
@Override @Override
public VirtualBoxManager apply(Supplier<NodeMetadata> nodeSupplier) { public VirtualBoxManager apply(Supplier<NodeMetadata> nodeSupplier) {
return VirtualBoxManager.createInstance(nodeSupplier.get().getId()); return VirtualBoxManager.createInstance(nodeSupplier.get().getId());
} }
@Override @Override
public String toString() { public String toString() {
return "createInstanceByNodeId()"; return "createInstanceByNodeId()";
} }
}; };
} }
@Provides @Provides
@Singleton @Singleton
protected Supplier defaultClient(Supplier<VirtualBoxManager> in) { protected Supplier defaultClient(Supplier<VirtualBoxManager> in) {
return in; return in;
} }
@Provides @Provides
@Singleton @Singleton
protected Predicate<SshClient> sshResponds(SshResponds sshResponds, Timeouts timeouts) { protected Predicate<SshClient> sshResponds(SshResponds sshResponds, Timeouts timeouts) {
return new RetryablePredicate<SshClient>(sshResponds, timeouts.nodeRunning); return new RetryablePredicate<SshClient>(sshResponds, timeouts.nodeRunning);
} }
@Override @Override
protected Supplier provideHardware(ComputeServiceAdapter<IMachine, IMachine, Image, Location> adapter, protected Supplier provideHardware(ComputeServiceAdapter<IMachine, IMachine, Image, Location> adapter,
Function<IMachine, Hardware> transformer) { Function<IMachine, Hardware> transformer) {
return Suppliers.ofInstance(Collections.singleton(new HardwareBuilder().id("").build())); return Suppliers.ofInstance(Collections.singleton(new HardwareBuilder().id("").build()));
} }
@Override @Override
protected TemplateBuilder provideTemplate(Injector injector, TemplateBuilder template) { protected TemplateBuilder provideTemplate(Injector injector, TemplateBuilder template) {
return template.osFamily(OsFamily.UBUNTU).osVersionMatches("11.04"); return template.osFamily(OsFamily.UBUNTU).osVersionMatches("11.04");
} }
@Provides @Provides
@Singleton @Singleton
protected Supplier<NodeMetadata> host(Supplier<LoadingCache<String, Node>> nodes, NodeToNodeMetadata converter) protected Supplier<NodeMetadata> host(Supplier<LoadingCache<String, Node>> nodes, NodeToNodeMetadata converter)
throws ExecutionException { throws ExecutionException {
return Suppliers.compose(Functions.compose(converter, new Function<LoadingCache<String, Node>, Node>() { return Suppliers.compose(Functions.compose(converter, new Function<LoadingCache<String, Node>, Node>() {
@Override @Override
public Node apply(LoadingCache<String, Node> arg0) { public Node apply(LoadingCache<String, Node> arg0) {
return arg0.apply("host"); return arg0.apply("host");
} }
}), nodes); }), nodes);
} }
@VisibleForTesting @VisibleForTesting
public static final Map<MachineState, NodeState> machineToNodeState = ImmutableMap public static final Map<MachineState, NodeState> machineToNodeState = ImmutableMap
.<MachineState, NodeState> builder() .<MachineState, NodeState> builder().put(MachineState.Running, NodeState.RUNNING)
.put(MachineState.Running, NodeState.RUNNING) .put(MachineState.PoweredOff, NodeState.SUSPENDED)
.put(MachineState.PoweredOff, .put(MachineState.DeletingSnapshot, NodeState.PENDING)
NodeState.SUSPENDED) .put(MachineState.DeletingSnapshotOnline, NodeState.PENDING)
.put(MachineState.DeletingSnapshot, .put(MachineState.DeletingSnapshotPaused, NodeState.PENDING)
NodeState.PENDING) .put(MachineState.FaultTolerantSyncing, NodeState.PENDING)
.put(MachineState.DeletingSnapshotOnline, .put(MachineState.LiveSnapshotting, NodeState.PENDING)
NodeState.PENDING) .put(MachineState.SettingUp, NodeState.PENDING)
.put(MachineState.DeletingSnapshotPaused, .put(MachineState.Starting, NodeState.PENDING)
NodeState.PENDING) .put(MachineState.Stopping, NodeState.PENDING)
.put(MachineState.FaultTolerantSyncing, .put(MachineState.Restoring, NodeState.PENDING)
NodeState.PENDING) // TODO What to map these states to?
.put(MachineState.LiveSnapshotting, .put(MachineState.FirstOnline, NodeState.PENDING).put(MachineState.FirstTransient, NodeState.PENDING)
NodeState.PENDING) .put(MachineState.LastOnline, NodeState.PENDING).put(MachineState.LastTransient, NodeState.PENDING)
.put(MachineState.SettingUp, .put(MachineState.Teleported, NodeState.PENDING).put(MachineState.TeleportingIn, NodeState.PENDING)
NodeState.PENDING) .put(MachineState.TeleportingPausedVM, NodeState.PENDING).put(MachineState.Aborted, NodeState.ERROR)
.put(MachineState.Starting, NodeState.PENDING) .put(MachineState.Stuck, NodeState.ERROR)
.put(MachineState.Stopping, NodeState.PENDING)
.put(MachineState.Restoring,
NodeState.PENDING)
// TODO What to map these states to?
.put(MachineState.FirstOnline,
NodeState.PENDING)
.put(MachineState.FirstTransient,
NodeState.PENDING)
.put(MachineState.LastOnline,
NodeState.PENDING)
.put(MachineState.LastTransient,
NodeState.PENDING)
.put(MachineState.Teleported,
NodeState.PENDING)
.put(MachineState.TeleportingIn,
NodeState.PENDING)
.put(MachineState.TeleportingPausedVM,
NodeState.PENDING)
.put(MachineState.Aborted, NodeState.ERROR)
.put(MachineState.Stuck, NodeState.ERROR)
.put(MachineState.Null, .put(MachineState.Null, NodeState.UNRECOGNIZED).build();
NodeState.UNRECOGNIZED).build();
} }

View File

@ -55,8 +55,8 @@ public interface VirtualBoxConstants {
public static final String VIRTUALBOX_WEBSERVER_CREDENTIAL = "jclouds.virtualbox.webserver.credential"; public static final String VIRTUALBOX_WEBSERVER_CREDENTIAL = "jclouds.virtualbox.webserver.credential";
public static final String VIRTUALBOX_DEFAULT_DIR = System.getProperty("user.home") public static final String VIRTUALBOX_DEFAULT_DIR = System.getProperty("user.home") + File.separator
+ File.separator +".jclouds-vbox"; + ".jclouds-vbox";
public static final String VIRTUALBOX_PROVIDER = "virtualbox"; public static final String VIRTUALBOX_PROVIDER = "virtualbox";

View File

@ -26,8 +26,8 @@ import org.virtualbox_4_1.IMachine;
import com.google.common.base.Objects; import com.google.common.base.Objects;
/** /**
* A complete specification of a "clone" node with networking setup * A complete specification of a "clone" node with networking setup and the physical machine
* and the physical machine specification. * specification.
*/ */
public class CloneSpec { public class CloneSpec {
@ -57,18 +57,18 @@ public class CloneSpec {
return this; return this;
} }
public Builder master(IMachine master){ public Builder master(IMachine master) {
this.master = master; this.master = master;
return this; return this;
} }
public Builder linked(boolean isLinked){ public Builder linked(boolean isLinked) {
this.isLinked = isLinked; this.isLinked = isLinked;
return this; return this;
} }
public CloneSpec build() { public CloneSpec build() {
return new CloneSpec(vmSpec, networkSpec, master ,isLinked); return new CloneSpec(vmSpec, networkSpec, master, isLinked);
} }
} }
@ -92,34 +92,31 @@ public class CloneSpec {
} }
public IMachine getMaster() { public IMachine getMaster() {
return master; return master;
} }
public boolean isLinked() { public boolean isLinked() {
return isLinked; return isLinked;
} }
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (this == o) return true; if (this == o)
return true;
if (o instanceof VmSpec) { if (o instanceof VmSpec) {
CloneSpec other = (CloneSpec) o; CloneSpec other = (CloneSpec) o;
return Objects.equal(vmSpec, other.vmSpec) && return Objects.equal(vmSpec, other.vmSpec) && Objects.equal(networkSpec, other.networkSpec);
Objects.equal(networkSpec, other.networkSpec);
} }
return false; return false;
} }
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hashCode(vmSpec,networkSpec); return Objects.hashCode(vmSpec, networkSpec);
} }
@Override @Override
public String toString() { public String toString() {
return "IMachineSpec{" + return "IMachineSpec{" + "vmSpec= " + vmSpec + ", networkSpec= " + networkSpec + '}';
"vmSpec= " + vmSpec +
", networkSpec= " + networkSpec +
'}';
} }
} }

View File

@ -23,45 +23,45 @@ import org.virtualbox_4_1.IMachine;
public class Master { public class Master {
private final IMachine machine; private final IMachine machine;
private final MasterSpec spec; private final MasterSpec spec;
public static Builder builder() { public static Builder builder() {
return new Builder(); return new Builder();
} }
public static class Builder { public static class Builder {
private IMachine machine; private IMachine machine;
private MasterSpec spec; private MasterSpec spec;
public Builder machine(IMachine machine){ public Builder machine(IMachine machine) {
this.machine = machine;
return this;
}
public Builder spec(MasterSpec spec) {
this.spec = spec;
return this;
}
public Master build() {
return new Master(machine, spec);
}
}
private Master(IMachine machine, MasterSpec spec) {
super();
this.machine = machine; this.machine = machine;
return this;
}
public Builder spec(MasterSpec spec){
this.spec = spec; this.spec = spec;
return this; }
}
public Master build(){ public IMachine getMachine() {
return new Master(machine,spec); return machine;
} }
} public MasterSpec getSpec() {
return spec;
private Master(IMachine machine, MasterSpec spec) { }
super();
this.machine = machine;
this.spec = spec;
}
public IMachine getMachine() {
return machine;
}
public MasterSpec getSpec() {
return spec;
}
} }

View File

@ -24,8 +24,8 @@ import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.base.Objects; import com.google.common.base.Objects;
/** /**
* A complete specification of a "master" node, including the ISO, networking setup * A complete specification of a "master" node, including the ISO, networking setup and the physical
* and the physical machine specification. * machine specification.
*/ */
public class MasterSpec { public class MasterSpec {
@ -87,27 +87,23 @@ public class MasterSpec {
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (this == o) return true; if (this == o)
return true;
if (o instanceof VmSpec) { if (o instanceof VmSpec) {
MasterSpec other = (MasterSpec) o; MasterSpec other = (MasterSpec) o;
return Objects.equal(vmSpec, other.vmSpec) && return Objects.equal(vmSpec, other.vmSpec) && Objects.equal(isoSpec, other.isoSpec)
Objects.equal(isoSpec, other.isoSpec) && && Objects.equal(networkSpec, other.networkSpec);
Objects.equal(networkSpec, other.networkSpec);
} }
return false; return false;
} }
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hashCode(vmSpec,isoSpec,networkSpec); return Objects.hashCode(vmSpec, isoSpec, networkSpec);
} }
@Override @Override
public String toString() { public String toString() {
return "IMachineSpec{" + return "IMachineSpec{" + "vmSpec=" + vmSpec + ", isoSpec=" + isoSpec + ", networkSpec=" + networkSpec + '}';
"vmSpec=" + vmSpec +
", isoSpec=" + isoSpec +
", networkSpec=" + networkSpec +
'}';
} }
} }

View File

@ -23,70 +23,70 @@ import org.jclouds.compute.domain.Template;
public class NodeSpec { public class NodeSpec {
private final Master master; private final Master master;
private final String name; private final String name;
private final String tag; private final String tag;
private final Template template; private final Template template;
public static Builder builder() { public static Builder builder() {
return new Builder(); return new Builder();
} }
public static class Builder { public static class Builder {
private Master master; private Master master;
private String name; private String name;
private String tag; private String tag;
private Template template; private Template template;
public Builder master(Master master) { public Builder master(Master master) {
this.master = master;
return this;
}
public Builder name(String name) {
this.name = name;
return this;
}
public Builder tag(String tag) {
this.tag = tag;
return this;
}
public Builder template(Template template) {
this.template = template;
return this;
}
public NodeSpec build() {
return new NodeSpec(master, name, tag, template);
}
}
private NodeSpec(Master master, String name, String tag, Template template) {
super();
this.master = master; this.master = master;
return this;
}
public Builder name(String name) {
this.name = name; this.name = name;
return this;
}
public Builder tag(String tag) {
this.tag = tag; this.tag = tag;
return this;
}
public Builder template(Template template) {
this.template = template; this.template = template;
return this; }
}
public NodeSpec build() { public Master getMaster() {
return new NodeSpec(master, name, tag, template); return master;
} }
} public String getName() {
return name;
}
private NodeSpec(Master master, String name, String tag, Template template) { public String getTag() {
super(); return tag;
this.master = master; }
this.name = name;
this.tag = tag;
this.template = template;
}
public Master getMaster() { public Template getTemplate() {
return master; return template;
} }
public String getName() {
return name;
}
public String getTag() {
return tag;
}
public Template getTemplate() {
return template;
}
} }

View File

@ -42,7 +42,8 @@ public class VmSpec {
private final Set<StorageController> controllers; private final Set<StorageController> controllers;
private final CleanupMode cleanupMode; private final CleanupMode cleanupMode;
public VmSpec(String vmId, String vmName, String osTypeId, long memory, boolean forceOverwrite, Set<StorageController> controllers, CleanupMode cleanupMode) { public VmSpec(String vmId, String vmName, String osTypeId, long memory, boolean forceOverwrite,
Set<StorageController> controllers, CleanupMode cleanupMode) {
this.vmId = checkNotNull(vmId, "vmId"); this.vmId = checkNotNull(vmId, "vmId");
this.vmName = checkNotNull(vmName, "vmName"); this.vmName = checkNotNull(vmName, "vmName");
this.osTypeId = checkNotNull(osTypeId, "osTypeId"); this.osTypeId = checkNotNull(osTypeId, "osTypeId");
@ -141,16 +142,14 @@ public class VmSpec {
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (this == o) return true; if (this == o)
return true;
if (o instanceof VmSpec) { if (o instanceof VmSpec) {
VmSpec other = (VmSpec) o; VmSpec other = (VmSpec) o;
return Objects.equal(vmId, other.vmId) && return Objects.equal(vmId, other.vmId) && Objects.equal(vmName, other.vmName)
Objects.equal(vmName, other.vmName) && && Objects.equal(osTypeId, other.osTypeId) && Objects.equal(memory, other.memory)
Objects.equal(osTypeId, other.osTypeId) && && Objects.equal(forceOverwrite, other.forceOverwrite)
Objects.equal(memory, other.memory) && && Objects.equal(controllers, other.controllers) && Objects.equal(cleanupMode, other.cleanupMode);
Objects.equal(forceOverwrite, other.forceOverwrite) &&
Objects.equal(controllers, other.controllers) &&
Objects.equal(cleanupMode, other.cleanupMode);
} }
return false; return false;
} }
@ -162,14 +161,8 @@ public class VmSpec {
@Override @Override
public String toString() { public String toString() {
return "VmSpecification{" + return "VmSpecification{" + "vmName='" + vmName + '\'' + ", osTypeId='" + osTypeId + '\'' + ", memory='" + memory
"vmName='" + vmName + '\'' + + '\'' + ", vmId='" + vmId + '\'' + ", forceOverwrite=" + forceOverwrite + ", controllers="
", osTypeId='" + osTypeId + '\'' + + controllers + ", cleanupMode=" + cleanupMode + '}';
", memory='" + memory + '\'' +
", vmId='" + vmId + '\'' +
", forceOverwrite=" + forceOverwrite +
", controllers=" + controllers +
", cleanupMode=" + cleanupMode +
'}';
} }
} }

View File

@ -139,10 +139,10 @@ public class YamlImage {
OsFamily family = parseOsFamilyOrUnrecognized(arg0.os_family); OsFamily family = parseOsFamilyOrUnrecognized(arg0.os_family);
OperatingSystem operatingSystem = OperatingSystem.builder().description(arg0.os_description).family(family) OperatingSystem operatingSystem = OperatingSystem.builder().description(arg0.os_description).family(family)
.version(arg0.os_version).is64Bit(arg0.os_64bit).build(); .version(arg0.os_version).is64Bit(arg0.os_64bit).build();
return new ImageBuilder().id(arg0.id).name(arg0.name).description(arg0.description) return new ImageBuilder().id(arg0.id).name(arg0.name).description(arg0.description)
.operatingSystem(operatingSystem).build(); .operatingSystem(operatingSystem).build();
} }
}; };

View File

@ -46,90 +46,81 @@ import com.google.common.base.Supplier;
import com.google.inject.Inject; import com.google.inject.Inject;
/** /**
* CloneAndRegisterMachineFromIMachineIfNotAlreadyExists will take care of the * CloneAndRegisterMachineFromIMachineIfNotAlreadyExists will take care of the followings: - cloning
* followings: - cloning the master - register the clone machine - * the master - register the clone machine -
* *
* @author Andrea Turli * @author Andrea Turli
*/ */
public class CloneAndRegisterMachineFromIMachineIfNotAlreadyExists implements public class CloneAndRegisterMachineFromIMachineIfNotAlreadyExists implements Function<CloneSpec, IMachine> {
Function<CloneSpec, IMachine> {
@Resource @Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER) @Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL; protected Logger logger = Logger.NULL;
private final Supplier<VirtualBoxManager> manager; private final Supplier<VirtualBoxManager> manager;
private final String workingDir; private final String workingDir;
private final MachineUtils machineUtils; private final MachineUtils machineUtils;
@Inject @Inject
public CloneAndRegisterMachineFromIMachineIfNotAlreadyExists( public CloneAndRegisterMachineFromIMachineIfNotAlreadyExists(Supplier<VirtualBoxManager> manager,
Supplier<VirtualBoxManager> manager, @Named(VirtualBoxConstants.VIRTUALBOX_WORKINGDIR) String workingDir, MachineUtils machineUtils) {
@Named(VirtualBoxConstants.VIRTUALBOX_WORKINGDIR) String workingDir, this.manager = manager;
MachineUtils machineUtils) { this.workingDir = workingDir;
this.manager = manager; this.machineUtils = machineUtils;
this.workingDir = workingDir; }
this.machineUtils = machineUtils;
}
@Override @Override
public IMachine apply(CloneSpec cloneSpec) { public IMachine apply(CloneSpec cloneSpec) {
VmSpec vmSpec = cloneSpec.getVmSpec(); VmSpec vmSpec = cloneSpec.getVmSpec();
try { try {
manager.get().getVBox().findMachine(vmSpec.getVmName()); manager.get().getVBox().findMachine(vmSpec.getVmName());
throw new IllegalStateException("Machine " + vmSpec.getVmName() throw new IllegalStateException("Machine " + vmSpec.getVmName() + " is already registered.");
+ " is already registered."); } catch (VBoxException e) {
} catch (VBoxException e) { if (machineNotFoundException(e))
if (machineNotFoundException(e)) return cloneMachine(cloneSpec);
return cloneMachine(cloneSpec); else
else throw e;
throw e; }
} }
}
private boolean machineNotFoundException(VBoxException e) { private boolean machineNotFoundException(VBoxException e) {
return e.getMessage().contains( return e.getMessage().contains("VirtualBox error: Could not find a registered machine named ")
"VirtualBox error: Could not find a registered machine named ") || e.getMessage().contains("Could not find a registered machine with UUID {");
|| e.getMessage().contains( }
"Could not find a registered machine with UUID {");
}
private IMachine cloneMachine(CloneSpec cloneSpec) { private IMachine cloneMachine(CloneSpec cloneSpec) {
VmSpec vmSpec = cloneSpec.getVmSpec(); VmSpec vmSpec = cloneSpec.getVmSpec();
NetworkSpec networkSpec = cloneSpec.getNetworkSpec(); NetworkSpec networkSpec = cloneSpec.getNetworkSpec();
boolean isLinkedClone = cloneSpec.isLinked(); boolean isLinkedClone = cloneSpec.isLinked();
IMachine master = cloneSpec.getMaster(); IMachine master = cloneSpec.getMaster();
String settingsFile = manager.get().getVBox() String settingsFile = manager.get().getVBox().composeMachineFilename(vmSpec.getVmName(), workingDir);
.composeMachineFilename(vmSpec.getVmName(), workingDir); IMachine clonedMachine = manager
IMachine clonedMachine = manager .get()
.get() .getVBox()
.getVBox() .createMachine(settingsFile, vmSpec.getVmName(), vmSpec.getOsTypeId(), vmSpec.getVmId(),
.createMachine(settingsFile, vmSpec.getVmName(), vmSpec.isForceOverwrite());
vmSpec.getOsTypeId(), vmSpec.getVmId(), List<CloneOptions> options = new ArrayList<CloneOptions>();
vmSpec.isForceOverwrite()); if (isLinkedClone)
List<CloneOptions> options = new ArrayList<CloneOptions>(); options.add(CloneOptions.Link);
if (isLinkedClone)
options.add(CloneOptions.Link);
// TODO snapshot name // TODO snapshot name
ISnapshot currentSnapshot = new TakeSnapshotIfNotAlreadyAttached( ISnapshot currentSnapshot = new TakeSnapshotIfNotAlreadyAttached(manager, "snapshotName", "snapshotDesc")
manager, "snapshotName", "snapshotDesc").apply(master); .apply(master);
// clone // clone
IProgress progress = currentSnapshot.getMachine().cloneTo( IProgress progress = currentSnapshot.getMachine().cloneTo(clonedMachine, CloneMode.MachineState, options);
clonedMachine, CloneMode.MachineState, options);
progress.waitForCompletion(-1); progress.waitForCompletion(-1);
logger.debug("clone done"); logger.debug("clone done");
// registering // registering
manager.get().getVBox().registerMachine(clonedMachine); manager.get().getVBox().registerMachine(clonedMachine);
// Networking // Networking
for (NetworkInterfaceCard networkInterfaceCard : networkSpec.getNetworkInterfaceCards()) { for (NetworkInterfaceCard networkInterfaceCard : networkSpec.getNetworkInterfaceCards()) {
new AttachNicToMachine(vmSpec.getVmName(), machineUtils).apply(networkInterfaceCard); new AttachNicToMachine(vmSpec.getVmName(), machineUtils).apply(networkInterfaceCard);
} }
return clonedMachine; return clonedMachine;
} }
} }

View File

@ -61,118 +61,120 @@ import com.google.inject.Inject;
@Singleton @Singleton
public class CreateAndInstallVm implements Function<MasterSpec, IMachine> { public class CreateAndInstallVm implements Function<MasterSpec, IMachine> {
@Resource @Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER) @Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL; protected Logger logger = Logger.NULL;
private final Supplier<VirtualBoxManager> manager; private final Supplier<VirtualBoxManager> manager;
private final CreateAndRegisterMachineFromIsoIfNotAlreadyExists createAndRegisterMachineFromIsoIfNotAlreadyExists; private final CreateAndRegisterMachineFromIsoIfNotAlreadyExists createAndRegisterMachineFromIsoIfNotAlreadyExists;
private final GuestAdditionsInstaller guestAdditionsInstaller; private final GuestAdditionsInstaller guestAdditionsInstaller;
private final Predicate<SshClient> sshResponds; private final Predicate<SshClient> sshResponds;
private final ExecutionType executionType; private final ExecutionType executionType;
private LoadingCache<IsoSpec, URI> preConfiguration; private LoadingCache<IsoSpec, URI> preConfiguration;
private final Function<IMachine, SshClient> sshClientForIMachine; private final Function<IMachine, SshClient> sshClientForIMachine;
private final MachineUtils machineUtils; private final MachineUtils machineUtils;
private final IMachineToNodeMetadata imachineToNodeMetadata; private final IMachineToNodeMetadata imachineToNodeMetadata;
@Inject @Inject
public CreateAndInstallVm(Supplier<VirtualBoxManager> manager, public CreateAndInstallVm(Supplier<VirtualBoxManager> manager,
CreateAndRegisterMachineFromIsoIfNotAlreadyExists CreateAndRegisterMachineFromIsoIfNotAlreadyExists, CreateAndRegisterMachineFromIsoIfNotAlreadyExists CreateAndRegisterMachineFromIsoIfNotAlreadyExists,
GuestAdditionsInstaller guestAdditionsInstaller, IMachineToNodeMetadata imachineToNodeMetadata, GuestAdditionsInstaller guestAdditionsInstaller, IMachineToNodeMetadata imachineToNodeMetadata,
Predicate<SshClient> sshResponds, Function<IMachine, SshClient> sshClientForIMachine, Predicate<SshClient> sshResponds, Function<IMachine, SshClient> sshClientForIMachine,
ExecutionType executionType, MachineUtils machineUtils, ExecutionType executionType, MachineUtils machineUtils,
@Preconfiguration LoadingCache<IsoSpec, URI> preConfiguration) { @Preconfiguration LoadingCache<IsoSpec, URI> preConfiguration) {
this.manager = manager; this.manager = manager;
this.createAndRegisterMachineFromIsoIfNotAlreadyExists = CreateAndRegisterMachineFromIsoIfNotAlreadyExists; this.createAndRegisterMachineFromIsoIfNotAlreadyExists = CreateAndRegisterMachineFromIsoIfNotAlreadyExists;
this.sshResponds = sshResponds; this.sshResponds = sshResponds;
this.sshClientForIMachine = sshClientForIMachine; this.sshClientForIMachine = sshClientForIMachine;
this.executionType = executionType; this.executionType = executionType;
this.machineUtils = machineUtils; this.machineUtils = machineUtils;
this.preConfiguration = preConfiguration; this.preConfiguration = preConfiguration;
this.guestAdditionsInstaller = guestAdditionsInstaller; this.guestAdditionsInstaller = guestAdditionsInstaller;
this.imachineToNodeMetadata = imachineToNodeMetadata; this.imachineToNodeMetadata = imachineToNodeMetadata;
} }
@Override @Override
public IMachine apply(MasterSpec masterSpec) { public IMachine apply(MasterSpec masterSpec) {
VmSpec vmSpec = masterSpec.getVmSpec(); VmSpec vmSpec = masterSpec.getVmSpec();
IsoSpec isoSpec = masterSpec.getIsoSpec(); IsoSpec isoSpec = masterSpec.getIsoSpec();
String vmName = vmSpec.getVmName(); String vmName = vmSpec.getVmName();
IMachine vm = createAndRegisterMachineFromIsoIfNotAlreadyExists.apply(masterSpec); IMachine vm = createAndRegisterMachineFromIsoIfNotAlreadyExists.apply(masterSpec);
// Launch machine and wait for it to come online // Launch machine and wait for it to come online
ensureMachineIsLaunched(vmName); ensureMachineIsLaunched(vmName);
URI uri = preConfiguration.getUnchecked(isoSpec); URI uri = preConfiguration.getUnchecked(isoSpec);
String installationKeySequence = isoSpec.getInstallationKeySequence().replace("PRECONFIGURATION_URL", String installationKeySequence = isoSpec.getInstallationKeySequence().replace("PRECONFIGURATION_URL",
uri.toASCIIString()); uri.toASCIIString());
configureOsInstallationWithKeyboardSequence(vmName, installationKeySequence); configureOsInstallationWithKeyboardSequence(vmName, installationKeySequence);
SshClient client = sshClientForIMachine.apply(vm); SshClient client = sshClientForIMachine.apply(vm);
logger.debug(">> awaiting installation to finish node(%s)", vmName); logger.debug(">> awaiting installation to finish node(%s)", vmName);
checkState(sshResponds.apply(client), "timed out waiting for guest %s to be accessible via ssh", vmName); checkState(sshResponds.apply(client), "timed out waiting for guest %s to be accessible via ssh", vmName);
logger.debug(">> awaiting installation of guest additions on vm: %s", vmName); logger.debug(">> awaiting installation of guest additions on vm: %s", vmName);
checkState(guestAdditionsInstaller.apply(vm)); checkState(guestAdditionsInstaller.apply(vm));
logger.debug(">> awaiting post-installation actions on vm: %s", vmName); logger.debug(">> awaiting post-installation actions on vm: %s", vmName);
NodeMetadata vmMetadata = imachineToNodeMetadata.apply(vm); NodeMetadata vmMetadata = imachineToNodeMetadata.apply(vm);
ListenableFuture<ExecResponse> execFuture = machineUtils.runScriptOnNode(vmMetadata, call("cleanupUdevIfNeeded"), ListenableFuture<ExecResponse> execFuture = machineUtils.runScriptOnNode(vmMetadata, call("cleanupUdevIfNeeded"),
RunScriptOptions.NONE); RunScriptOptions.NONE);
ExecResponse execResponse = Futures.getUnchecked(execFuture); ExecResponse execResponse = Futures.getUnchecked(execFuture);
checkState(execResponse.getExitCode() == 0); checkState(execResponse.getExitCode() == 0);
logger.debug("<< installation of image complete. Powering down node(%s)", vmName); logger.debug("<< installation of image complete. Powering down node(%s)", vmName);
ensureMachineHasPowerDown(vmName); ensureMachineHasPowerDown(vmName);
return vm; return vm;
} }
private void configureOsInstallationWithKeyboardSequence(String vmName, String installationKeySequence) { private void configureOsInstallationWithKeyboardSequence(String vmName, String installationKeySequence) {
Iterable<List<Integer>> scancodelist = transform(Splitter.on(" ").split(installationKeySequence), Iterable<List<Integer>> scancodelist = transform(Splitter.on(" ").split(installationKeySequence),
new StringToKeyCode()); new StringToKeyCode());
for (List<Integer> scancodes : scancodelist) { for (List<Integer> scancodes : scancodelist) {
machineUtils.lockSessionOnMachineAndApply(vmName, LockType.Shared, new SendScancodes(scancodes)); machineUtils.lockSessionOnMachineAndApply(vmName, LockType.Shared, new SendScancodes(scancodes));
}
}
/**
* ensureMachineHasPowerDown needs to have this delay just to ensure that the machine is completely powered off
*
* @param vmName
*/
private void ensureMachineHasPowerDown(String vmName) {
while (!manager.get().getVBox().findMachine(vmName).getState().equals(MachineState.POWERED_OFF)) {
try {
machineUtils.lockSessionOnMachineAndApply(vmName, LockType.Shared, new Function<ISession, Void>() {
@Override
public Void apply(ISession session) {
IProgress powerDownProgress = session.getConsole().powerDown();
powerDownProgress.waitForCompletion(-1);
return null;
}
});
} catch (RuntimeException e) {
// sometimes the machine might be powered of between the while test and the call to lockSessionOnMachineAndApply
if (e.getMessage().contains("Invalid machine state: PoweredOff")){
return;
} else if(e.getMessage().contains("VirtualBox error: The object is not ready")){
continue;
} else {
throw e;
}
} }
} }
}
private void ensureMachineIsLaunched(String vmName) { /**
machineUtils.applyForMachine(vmName, new LaunchMachineIfNotAlreadyRunning(manager.get(), executionType, "")); * ensureMachineHasPowerDown needs to have this delay just to ensure that the machine is
} * completely powered off
*
* @param vmName
*/
private void ensureMachineHasPowerDown(String vmName) {
while (!manager.get().getVBox().findMachine(vmName).getState().equals(MachineState.POWERED_OFF)) {
try {
machineUtils.lockSessionOnMachineAndApply(vmName, LockType.Shared, new Function<ISession, Void>() {
@Override
public Void apply(ISession session) {
IProgress powerDownProgress = session.getConsole().powerDown();
powerDownProgress.waitForCompletion(-1);
return null;
}
});
} catch (RuntimeException e) {
// sometimes the machine might be powered of between the while test and the call to
// lockSessionOnMachineAndApply
if (e.getMessage().contains("Invalid machine state: PoweredOff")) {
return;
} else if (e.getMessage().contains("VirtualBox error: The object is not ready")) {
continue;
} else {
throw e;
}
}
}
}
private void ensureMachineIsLaunched(String vmName) {
machineUtils.applyForMachine(vmName, new LaunchMachineIfNotAlreadyRunning(manager.get(), executionType, ""));
}
} }

View File

@ -70,8 +70,8 @@ public class CreateAndRegisterMachineFromIsoIfNotAlreadyExists implements Functi
private final String workingDir; private final String workingDir;
@Inject @Inject
public CreateAndRegisterMachineFromIsoIfNotAlreadyExists(Supplier<VirtualBoxManager> manager, MachineUtils machineUtils, public CreateAndRegisterMachineFromIsoIfNotAlreadyExists(Supplier<VirtualBoxManager> manager,
@Named(VirtualBoxConstants.VIRTUALBOX_WORKINGDIR) String workingDir) { MachineUtils machineUtils, @Named(VirtualBoxConstants.VIRTUALBOX_WORKINGDIR) String workingDir) {
this.manager = manager; this.manager = manager;
this.machineUtils = machineUtils; this.machineUtils = machineUtils;
this.workingDir = workingDir; this.workingDir = workingDir;
@ -124,7 +124,7 @@ public class CreateAndRegisterMachineFromIsoIfNotAlreadyExists implements Functi
// Networking // Networking
for (NetworkInterfaceCard networkInterfaceCard : networkSpec.getNetworkInterfaceCards()) { for (NetworkInterfaceCard networkInterfaceCard : networkSpec.getNetworkInterfaceCards()) {
new AttachNicToMachine(vmName, machineUtils).apply(networkInterfaceCard); new AttachNicToMachine(vmName, machineUtils).apply(networkInterfaceCard);
} }
} }
@ -132,22 +132,21 @@ public class CreateAndRegisterMachineFromIsoIfNotAlreadyExists implements Functi
Set<IsoImage> dvds = controller.getIsoImages(); Set<IsoImage> dvds = controller.getIsoImages();
for (IsoImage dvd : dvds) { for (IsoImage dvd : dvds) {
String dvdSource = dvd.getSourcePath(); String dvdSource = dvd.getSourcePath();
final IMedium dvdMedium = manager.get().getVBox().openMedium(dvdSource, DeviceType.DVD, AccessMode.ReadOnly, final IMedium dvdMedium = manager.get().getVBox()
vmSpecification.isForceOverwrite()); .openMedium(dvdSource, DeviceType.DVD, AccessMode.ReadOnly, vmSpecification.isForceOverwrite());
ensureMachineDevicesAttached(vmName, dvdMedium, dvd.getDeviceDetails(), controller.getName()); ensureMachineDevicesAttached(vmName, dvdMedium, dvd.getDeviceDetails(), controller.getName());
} }
} }
private void ensureMachineDevicesAttached(String vmName, IMedium medium, DeviceDetails deviceDetails, private void ensureMachineDevicesAttached(String vmName, IMedium medium, DeviceDetails deviceDetails,
String controllerName) { String controllerName) {
machineUtils.writeLockMachineAndApply(vmName, new AttachMediumToMachineIfNotAlreadyAttached(deviceDetails, medium, machineUtils.writeLockMachineAndApply(vmName, new AttachMediumToMachineIfNotAlreadyAttached(deviceDetails,
controllerName)); medium, controllerName));
} }
private String missingIDEControllersMessage(VmSpec vmSpecification) { private String missingIDEControllersMessage(VmSpec vmSpecification) {
return String return String
.format( .format("First controller is not an IDE controller. Please verify that the VM spec is a correct master node: %s",
"First controller is not an IDE controller. Please verify that the VM spec is a correct master node: %s",
vmSpecification); vmSpecification);
} }
@ -171,7 +170,7 @@ public class CreateAndRegisterMachineFromIsoIfNotAlreadyExists implements Functi
} }
public void ensureMachineHasStorageControllerNamed(String vmName, StorageController storageController) { public void ensureMachineHasStorageControllerNamed(String vmName, StorageController storageController) {
machineUtils.writeLockMachineAndApply(vmName, new AddIDEControllerIfNotExists(checkNotNull( machineUtils.writeLockMachineAndApply(vmName,
storageController, "storageController"))); new AddIDEControllerIfNotExists(checkNotNull(storageController, "storageController")));
} }
} }

View File

@ -61,10 +61,10 @@ public class IMachineToImage implements Function<IMachine, Image> {
OsFamily family = parseOsFamilyOrUnrecognized(guestOSType.getDescription()); OsFamily family = parseOsFamilyOrUnrecognized(guestOSType.getDescription());
String version = parseVersionOrReturnEmptyString(family, guestOSType.getDescription(), osVersionMap); String version = parseVersionOrReturnEmptyString(family, guestOSType.getDescription(), osVersionMap);
OperatingSystem os = OperatingSystem.builder().description(guestOSType.getDescription()).family(family) OperatingSystem os = OperatingSystem.builder().description(guestOSType.getDescription()).family(family)
.version(version).is64Bit(guestOSType.getIs64Bit()).build(); .version(version).is64Bit(guestOSType.getIs64Bit()).build();
return new ImageBuilder().id("" + from.getId()).name(from.getName()).description(from.getDescription()) return new ImageBuilder().id("" + from.getId()).name(from.getName()).description(from.getDescription())
.operatingSystem(os).build(); .operatingSystem(os).build();
} }
} }

View File

@ -40,9 +40,9 @@ import com.google.inject.Inject;
@Singleton @Singleton
public class IMachineToSshClient implements Function<IMachine, SshClient> { public class IMachineToSshClient implements Function<IMachine, SshClient> {
@Resource @Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER) @Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL; protected Logger logger = Logger.NULL;
private final SshClient.Factory sshClientFactory; private final SshClient.Factory sshClientFactory;
@ -53,7 +53,7 @@ public class IMachineToSshClient implements Function<IMachine, SshClient> {
@Override @Override
public SshClient apply(final IMachine vm) { public SshClient apply(final IMachine vm) {
INetworkAdapter networkAdapter = vm.getNetworkAdapter(0L); INetworkAdapter networkAdapter = vm.getNetworkAdapter(0L);
SshClient client = null; SshClient client = null;
checkNotNull(networkAdapter); checkNotNull(networkAdapter);
@ -66,8 +66,8 @@ public class IMachineToSshClient implements Function<IMachine, SshClient> {
// TODO: we need a way to align the default login credentials from the iso with the // TODO: we need a way to align the default login credentials from the iso with the
// vmspec // vmspec
if ("1".equals(protocolNumber) && "22".equals(targetPort)) { if ("1".equals(protocolNumber) && "22".equals(targetPort)) {
client = sshClientFactory.create(new IPSocket(hostAddress, Integer.parseInt(inboundPort)), client = sshClientFactory.create(new IPSocket(hostAddress, Integer.parseInt(inboundPort)), LoginCredentials
LoginCredentials.builder().user("toor").password("password").authenticateSudo(true).build()); .builder().user("toor").password("password").authenticateSudo(true).build());
} }
} }
checkNotNull(client); checkNotNull(client);

View File

@ -58,13 +58,10 @@ public class IMachineToVmSpec implements Function<IMachine, VmSpec> {
// TODO some parameters are predefined cause the IMachine doesn't have the // TODO some parameters are predefined cause the IMachine doesn't have the
// concept i.e.: cleanUpMode // concept i.e.: cleanUpMode
org.jclouds.virtualbox.domain.VmSpec.Builder vmSpecBuilder = VmSpec org.jclouds.virtualbox.domain.VmSpec.Builder vmSpecBuilder = VmSpec.builder();
.builder();
vmSpecBuilder.id(machine.getId()).name(machine.getName()) vmSpecBuilder.id(machine.getId()).name(machine.getName()).memoryMB(machine.getMemorySize().intValue())
.memoryMB(machine.getMemorySize().intValue()) .osTypeId(machine.getOSTypeId()).forceOverwrite(true).cleanUpMode(CleanupMode.Full);
.osTypeId(machine.getOSTypeId()).forceOverwrite(true)
.cleanUpMode(CleanupMode.Full);
for (StorageController storageController : controllers) { for (StorageController storageController : controllers) {
vmSpecBuilder.controller(storageController); vmSpecBuilder.controller(storageController);
@ -76,28 +73,23 @@ public class IMachineToVmSpec implements Function<IMachine, VmSpec> {
private List<StorageController> buildControllers(IMachine machine) { private List<StorageController> buildControllers(IMachine machine) {
List<StorageController> controllers = Lists.newArrayList(); List<StorageController> controllers = Lists.newArrayList();
for (IStorageController iStorageController : machine for (IStorageController iStorageController : machine.getStorageControllers()) {
.getStorageControllers()) {
Builder storageControlleBuiler = StorageController.builder(); Builder storageControlleBuiler = StorageController.builder();
for (IMediumAttachment iMediumAttachment : machine for (IMediumAttachment iMediumAttachment : machine.getMediumAttachmentsOfController(iStorageController
.getMediumAttachmentsOfController(iStorageController.getName())) { .getName())) {
IMedium iMedium = iMediumAttachment.getMedium(); IMedium iMedium = iMediumAttachment.getMedium();
if (iMedium.getDeviceType().equals(DeviceType.HardDisk)) { if (iMedium.getDeviceType().equals(DeviceType.HardDisk)) {
storageControlleBuiler.attachHardDisk(HardDisk.builder() storageControlleBuiler.attachHardDisk(HardDisk.builder().diskpath(iMedium.getLocation())
.diskpath(iMedium.getLocation()).autoDelete(true) .autoDelete(true).controllerPort(iMediumAttachment.getPort())
.controllerPort(iMediumAttachment.getPort()) .deviceSlot(iMediumAttachment.getDevice().intValue()).build());
.deviceSlot(iMediumAttachment.getDevice().intValue())
.build());
} else if (iMedium.getDeviceType().equals(DeviceType.DVD)) { } else if (iMedium.getDeviceType().equals(DeviceType.DVD)) {
storageControlleBuiler.attachISO(iMediumAttachment.getPort(), storageControlleBuiler.attachISO(iMediumAttachment.getPort(), iMediumAttachment.getDevice().intValue(),
iMediumAttachment.getDevice().intValue(), iMedium.getLocation());
iMedium.getLocation());
} }
} }
controllers.add(storageControlleBuiler controllers.add(storageControlleBuiler.name(iStorageController.getName()).bus(iStorageController.getBus())
.name(iStorageController.getName()) .build());
.bus(iStorageController.getBus()).build());
} }
return controllers; return controllers;
} }

View File

@ -69,121 +69,120 @@ import com.google.common.collect.Maps;
*/ */
public class MastersCache extends AbstractLoadingCache<Image, Master> { public class MastersCache extends AbstractLoadingCache<Image, Master> {
private final Map<String, Master> masters = Maps.newHashMap(); private final Map<String, Master> masters = Maps.newHashMap();
private final Function<MasterSpec, IMachine> masterCreatorAndInstaller; private final Function<MasterSpec, IMachine> masterCreatorAndInstaller;
private final Map<String, YamlImage> imageMapping; private final Map<String, YamlImage> imageMapping;
private final String workingDir; private final String workingDir;
private final String adminDisk; private final String adminDisk;
private final String guestAdditionsIso; private final String guestAdditionsIso;
private final String installationKeySequence; private final String installationKeySequence;
private final String isosDir; private final String isosDir;
private Supplier<VirtualBoxManager> manager; private Supplier<VirtualBoxManager> manager;
@Inject @Inject
public MastersCache(@Named(Constants.PROPERTY_BUILD_VERSION) String version, public MastersCache(@Named(Constants.PROPERTY_BUILD_VERSION) String version,
@Named(VIRTUALBOX_INSTALLATION_KEY_SEQUENCE) String installationKeySequence, @Named(VIRTUALBOX_INSTALLATION_KEY_SEQUENCE) String installationKeySequence,
@Named(VIRTUALBOX_WORKINGDIR) String workingDir, Function<MasterSpec, IMachine> masterLoader, @Named(VIRTUALBOX_WORKINGDIR) String workingDir, Function<MasterSpec, IMachine> masterLoader,
Supplier<Map<Image, YamlImage>> yamlMapper, Supplier<VirtualBoxManager> manager) { Supplier<Map<Image, YamlImage>> yamlMapper, Supplier<VirtualBoxManager> manager) {
checkNotNull(version, "version"); checkNotNull(version, "version");
checkNotNull(installationKeySequence, "installationKeySequence"); checkNotNull(installationKeySequence, "installationKeySequence");
checkNotNull(manager, "vboxmanager"); checkNotNull(manager, "vboxmanager");
this.manager = manager; this.manager = manager;
this.masterCreatorAndInstaller = masterLoader; this.masterCreatorAndInstaller = masterLoader;
this.installationKeySequence = installationKeySequence; this.installationKeySequence = installationKeySequence;
this.workingDir = workingDir == null ? VIRTUALBOX_DEFAULT_DIR : workingDir; this.workingDir = workingDir == null ? VIRTUALBOX_DEFAULT_DIR : workingDir;
File wdFile = new File(this.workingDir); File wdFile = new File(this.workingDir);
if (!wdFile.exists()) { if (!wdFile.exists()) {
wdFile.mkdirs(); wdFile.mkdirs();
}
this.isosDir = wdFile.getAbsolutePath() + File.separator + "isos";
this.adminDisk = workingDir + "/testadmin.vdi";
this.imageMapping = Maps.newLinkedHashMap();
for (Entry<Image, YamlImage> entry : yamlMapper.get().entrySet()) {
this.imageMapping.put(entry.getKey().getId(), entry.getValue());
}
this.guestAdditionsIso = String.format("%s/VBoxGuestAdditions_%s.iso", isosDir,
Iterables.get(Splitter.on('r').split(version), 0));
checkState(new File(guestAdditionsIso).exists(), "guest additions iso does not exist at: " + guestAdditionsIso);
}
@Override
public Master get(Image key) throws ExecutionException {
// check if we have loaded this machine before
if (masters.containsKey(key.getId())) {
return masters.get(key);
}
// the yaml image
YamlImage yamlImage = imageMapping.get(key.getId());
checkNotNull(yamlImage, "could not find yaml image for image: " + key);
// check if the iso is here, download if not
String localIsoUrl = getFilePathOrDownload(yamlImage.iso);
String vmName = VIRTUALBOX_IMAGE_PREFIX + yamlImage.id;
HardDisk hardDisk = HardDisk.builder().diskpath(adminDisk).autoDelete(true).controllerPort(0).deviceSlot(1).build();
StorageController ideController = StorageController.builder().name("IDE Controller").bus(StorageBus.IDE)
.attachISO(0, 0, localIsoUrl).attachHardDisk(hardDisk).attachISO(1, 1, guestAdditionsIso).build();
VmSpec vmSpecification = VmSpec.builder().id(yamlImage.id).name(vmName).memoryMB(512).osTypeId("")
.controller(ideController).forceOverwrite(true).cleanUpMode(CleanupMode.Full).build();
NetworkAdapter networkAdapter = NetworkAdapter.builder().networkAttachmentType(NetworkAttachmentType.NAT)
.tcpRedirectRule("127.0.0.1", 2222, "", 22).build();
NetworkInterfaceCard networkInterfaceCard = NetworkInterfaceCard.builder().addNetworkAdapter(networkAdapter)
.build();
NetworkSpec networkSpec = NetworkSpec.builder().addNIC(0L, networkInterfaceCard).build();
MasterSpec masterSpec = MasterSpec
.builder()
.vm(vmSpecification)
.iso(
IsoSpec.builder().sourcePath(localIsoUrl)
.installationScript(installationKeySequence.replace("HOSTNAME", vmSpecification.getVmName())).build())
.network(networkSpec).build();
IMachine masterMachine;
// try and find a master machine in vbox
try {
masterMachine = manager.get().getVBox().findMachine(vmName);
} catch (VBoxException e) {
if (machineNotFoundException(e)) {
// create the master machine if it can't be found
masterMachine = masterCreatorAndInstaller.apply(masterSpec);
} }
else { this.isosDir = wdFile.getAbsolutePath() + File.separator + "isos";
throw e; this.adminDisk = workingDir + "/testadmin.vdi";
this.imageMapping = Maps.newLinkedHashMap();
for (Entry<Image, YamlImage> entry : yamlMapper.get().entrySet()) {
this.imageMapping.put(entry.getKey().getId(), entry.getValue());
} }
this.guestAdditionsIso = String.format("%s/VBoxGuestAdditions_%s.iso", isosDir,
Iterables.get(Splitter.on('r').split(version), 0));
checkState(new File(guestAdditionsIso).exists(), "guest additions iso does not exist at: " + guestAdditionsIso);
} }
Master master = Master.builder().machine(masterMachine).spec(masterSpec).build(); @Override
public Master get(Image key) throws ExecutionException {
// check if we have loaded this machine before
if (masters.containsKey(key.getId())) {
return masters.get(key);
}
masters.put(key.getId(), master); // the yaml image
YamlImage yamlImage = imageMapping.get(key.getId());
return master; checkNotNull(yamlImage, "could not find yaml image for image: " + key);
}
private String getFilePathOrDownload(String httpUrl) throws ExecutionException { // check if the iso is here, download if not
// TODO validation String localIsoUrl = getFilePathOrDownload(yamlImage.iso);
String fileName = httpUrl.substring(httpUrl.lastIndexOf('/') + 1, httpUrl.length());
File localFile = new File(isosDir, fileName);
// TODO download. for now just expect the file to be there
checkState(localFile.exists(), "iso file has not been downloaded: " + fileName);
return localFile.getAbsolutePath();
}
@Override String vmName = VIRTUALBOX_IMAGE_PREFIX + yamlImage.id;
public Master getIfPresent(Image key) {
if (masters.containsKey(key.getId())) { HardDisk hardDisk = HardDisk.builder().diskpath(adminDisk).autoDelete(true).controllerPort(0).deviceSlot(1)
return masters.get(key.getId()); .build();
}
return null; StorageController ideController = StorageController.builder().name("IDE Controller").bus(StorageBus.IDE)
} .attachISO(0, 0, localIsoUrl).attachHardDisk(hardDisk).attachISO(1, 1, guestAdditionsIso).build();
VmSpec vmSpecification = VmSpec.builder().id(yamlImage.id).name(vmName).memoryMB(512).osTypeId("")
.controller(ideController).forceOverwrite(true).cleanUpMode(CleanupMode.Full).build();
NetworkAdapter networkAdapter = NetworkAdapter.builder().networkAttachmentType(NetworkAttachmentType.NAT)
.tcpRedirectRule("127.0.0.1", 2222, "", 22).build();
NetworkInterfaceCard networkInterfaceCard = NetworkInterfaceCard.builder().addNetworkAdapter(networkAdapter)
.build();
NetworkSpec networkSpec = NetworkSpec.builder().addNIC(0L, networkInterfaceCard).build();
MasterSpec masterSpec = MasterSpec
.builder()
.vm(vmSpecification)
.iso(IsoSpec.builder().sourcePath(localIsoUrl)
.installationScript(installationKeySequence.replace("HOSTNAME", vmSpecification.getVmName()))
.build()).network(networkSpec).build();
IMachine masterMachine;
// try and find a master machine in vbox
try {
masterMachine = manager.get().getVBox().findMachine(vmName);
} catch (VBoxException e) {
if (machineNotFoundException(e)) {
// create the master machine if it can't be found
masterMachine = masterCreatorAndInstaller.apply(masterSpec);
} else {
throw e;
}
}
Master master = Master.builder().machine(masterMachine).spec(masterSpec).build();
masters.put(key.getId(), master);
return master;
}
private String getFilePathOrDownload(String httpUrl) throws ExecutionException {
// TODO validation
String fileName = httpUrl.substring(httpUrl.lastIndexOf('/') + 1, httpUrl.length());
File localFile = new File(isosDir, fileName);
// TODO download. for now just expect the file to be there
checkState(localFile.exists(), "iso file has not been downloaded: " + fileName);
return localFile.getAbsolutePath();
}
@Override
public Master getIfPresent(Image key) {
if (masters.containsKey(key.getId())) {
return masters.get(key.getId());
}
return null;
}
} }

View File

@ -48,57 +48,58 @@ import com.google.common.base.Supplier;
@Singleton @Singleton
public class NodeCreator implements Function<NodeSpec, NodeAndInitialCredentials<IMachine>> { public class NodeCreator implements Function<NodeSpec, NodeAndInitialCredentials<IMachine>> {
private final Supplier<VirtualBoxManager> manager; private final Supplier<VirtualBoxManager> manager;
private final Function<CloneSpec, IMachine> cloner; private final Function<CloneSpec, IMachine> cloner;
@Inject @Inject
public NodeCreator(Supplier<VirtualBoxManager> manager, Function<CloneSpec, IMachine> cloner, MachineUtils machineUtils) { public NodeCreator(Supplier<VirtualBoxManager> manager, Function<CloneSpec, IMachine> cloner,
this.manager = manager; MachineUtils machineUtils) {
this.cloner = cloner; this.manager = manager;
} this.cloner = cloner;
}
@Override @Override
public NodeAndInitialCredentials<IMachine> apply(NodeSpec nodeSpec) { public NodeAndInitialCredentials<IMachine> apply(NodeSpec nodeSpec) {
Master master = nodeSpec.getMaster(); Master master = nodeSpec.getMaster();
if (master.getMachine().getCurrentSnapshot() != null) { if (master.getMachine().getCurrentSnapshot() != null) {
ISession session; ISession session;
try { try {
session = manager.get().openMachineSession(master.getMachine()); session = manager.get().openMachineSession(master.getMachine());
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException("error opening vbox machine session: " + e.getMessage(), e); throw new RuntimeException("error opening vbox machine session: " + e.getMessage(), e);
}
session.getConsole().deleteSnapshot(master.getMachine().getCurrentSnapshot().getId());
session.unlockMachine();
} }
session.getConsole().deleteSnapshot(master.getMachine().getCurrentSnapshot().getId()); String masterNameWithoutPrefix = master.getSpec().getVmSpec().getVmName().replace(VIRTUALBOX_IMAGE_PREFIX, "");
session.unlockMachine();
}
String masterNameWithoutPrefix = master.getSpec().getVmSpec().getVmName().replace(VIRTUALBOX_IMAGE_PREFIX, "");
String cloneName = VIRTUALBOX_NODE_PREFIX + masterNameWithoutPrefix + "-" + nodeSpec.getTag() + "-" String cloneName = VIRTUALBOX_NODE_PREFIX + masterNameWithoutPrefix + "-" + nodeSpec.getTag() + "-"
+ nodeSpec.getName(); + nodeSpec.getName();
VmSpec cloneVmSpec = VmSpec.builder().id(cloneName).name(cloneName).memoryMB(512).cleanUpMode(CleanupMode.Full) VmSpec cloneVmSpec = VmSpec.builder().id(cloneName).name(cloneName).memoryMB(512).cleanUpMode(CleanupMode.Full)
.forceOverwrite(true).build(); .forceOverwrite(true).build();
NetworkAdapter networkAdapter = NetworkAdapter.builder().networkAttachmentType(NetworkAttachmentType.NAT) NetworkAdapter networkAdapter = NetworkAdapter.builder().networkAttachmentType(NetworkAttachmentType.NAT)
.tcpRedirectRule("127.0.0.1", 2222, "", 22).build(); .tcpRedirectRule("127.0.0.1", 2222, "", 22).build();
NetworkInterfaceCard networkInterfaceCard = NetworkInterfaceCard.builder().addNetworkAdapter(networkAdapter) NetworkInterfaceCard networkInterfaceCard = NetworkInterfaceCard.builder().addNetworkAdapter(networkAdapter)
.build(); .build();
NetworkSpec networkSpec = NetworkSpec.builder().addNIC(0L, networkInterfaceCard).build(); NetworkSpec networkSpec = NetworkSpec.builder().addNIC(0L, networkInterfaceCard).build();
CloneSpec cloneSpec = CloneSpec.builder().linked(true).master(master.getMachine()).network(networkSpec) CloneSpec cloneSpec = CloneSpec.builder().linked(true).master(master.getMachine()).network(networkSpec)
.vm(cloneVmSpec).build(); .vm(cloneVmSpec).build();
IMachine cloned = cloner.apply(cloneSpec); IMachine cloned = cloner.apply(cloneSpec);
new LaunchMachineIfNotAlreadyRunning(manager.get(), ExecutionType.GUI, "").apply(cloned); new LaunchMachineIfNotAlreadyRunning(manager.get(), ExecutionType.GUI, "").apply(cloned);
// TODO get credentials from somewhere else (they are also HC in IMachineToSshClient) // TODO get credentials from somewhere else (they are also HC in IMachineToSshClient)
NodeAndInitialCredentials<IMachine> nodeAndInitialCredentials = new NodeAndInitialCredentials<IMachine>(cloned, NodeAndInitialCredentials<IMachine> nodeAndInitialCredentials = new NodeAndInitialCredentials<IMachine>(cloned,
cloneName, LoginCredentials.builder().user("toor").password("password").authenticateSudo(true).build()); cloneName, LoginCredentials.builder().user("toor").password("password").authenticateSudo(true).build());
return nodeAndInitialCredentials; return nodeAndInitialCredentials;
} }
} }

View File

@ -43,22 +43,22 @@ import com.google.common.base.Supplier;
*/ */
public class YamlImagesFromFileConfig implements Supplier<String> { public class YamlImagesFromFileConfig implements Supplier<String> {
private String yamlFilePath; private String yamlFilePath;
@Inject @Inject
public YamlImagesFromFileConfig(@Named(VirtualBoxConstants.VIRTUALBOX_IMAGES_DESCRIPTOR) String yamlFilePath) { public YamlImagesFromFileConfig(@Named(VirtualBoxConstants.VIRTUALBOX_IMAGES_DESCRIPTOR) String yamlFilePath) {
this.yamlFilePath = yamlFilePath; this.yamlFilePath = yamlFilePath;
} }
@Override @Override
public String get() { public String get() {
checkNotNull(yamlFilePath, "yaml file path"); checkNotNull(yamlFilePath, "yaml file path");
File yamlFile = new File(yamlFilePath); File yamlFile = new File(yamlFilePath);
checkState(yamlFile.exists(), "yaml file does not exist at: " + yamlFilePath); checkState(yamlFile.exists(), "yaml file does not exist at: " + yamlFilePath);
try { try {
return IOUtils.toString(new FileInputStream(yamlFile)); return IOUtils.toString(new FileInputStream(yamlFile));
} catch (IOException e) { } catch (IOException e) {
throw new RuntimeException("error reading yaml file"); throw new RuntimeException("error reading yaml file");
} }
} }
} }

View File

@ -43,42 +43,42 @@ import com.google.common.collect.Maps;
@Singleton @Singleton
public class ImagesToYamlImagesFromYamlDescriptor implements Supplier<Map<Image, YamlImage>> { public class ImagesToYamlImagesFromYamlDescriptor implements Supplier<Map<Image, YamlImage>> {
private String yamlDescriptor; private String yamlDescriptor;
@Inject @Inject
public ImagesToYamlImagesFromYamlDescriptor(Supplier<String> yamlDescriptorSupplier) { public ImagesToYamlImagesFromYamlDescriptor(Supplier<String> yamlDescriptorSupplier) {
this.yamlDescriptor = yamlDescriptorSupplier.get(); this.yamlDescriptor = yamlDescriptorSupplier.get();
checkNotNull(yamlDescriptor, "yaml descriptor"); checkNotNull(yamlDescriptor, "yaml descriptor");
checkState(!yamlDescriptor.equals(""), "yaml descriptor is empty"); checkState(!yamlDescriptor.equals(""), "yaml descriptor is empty");
} }
/** /**
* Type-safe config class for YAML * Type-safe config class for YAML
* *
*/ */
public static class Config { public static class Config {
public List<YamlImage> images; public List<YamlImage> images;
} }
@Override @Override
public Map<Image, YamlImage> get() { public Map<Image, YamlImage> get() {
Constructor constructor = new Constructor(Config.class); Constructor constructor = new Constructor(Config.class);
TypeDescription imageDesc = new TypeDescription(YamlImage.class); TypeDescription imageDesc = new TypeDescription(YamlImage.class);
imageDesc.putListPropertyType("images", String.class); imageDesc.putListPropertyType("images", String.class);
constructor.addTypeDescription(imageDesc); constructor.addTypeDescription(imageDesc);
Yaml yaml = new Yaml(constructor); Yaml yaml = new Yaml(constructor);
Config config = (Config) yaml.load(yamlDescriptor); Config config = (Config) yaml.load(yamlDescriptor);
checkState(config != null, "missing config: class"); checkState(config != null, "missing config: class");
checkState(config.images != null, "missing images: collection"); checkState(config.images != null, "missing images: collection");
Map<Image, YamlImage> backingMap = Maps.newLinkedHashMap(); Map<Image, YamlImage> backingMap = Maps.newLinkedHashMap();
for (YamlImage yamlImage : config.images) { for (YamlImage yamlImage : config.images) {
backingMap.put(YamlImage.toImage.apply(yamlImage), yamlImage); backingMap.put(YamlImage.toImage.apply(yamlImage), yamlImage);
} }
return backingMap; return backingMap;
} }
} }

View File

@ -59,165 +59,168 @@ import com.google.inject.Inject;
@Singleton @Singleton
public class MachineUtils { public class MachineUtils {
@Resource @Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER) @Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL; protected Logger logger = Logger.NULL;
private final Supplier<VirtualBoxManager> manager; private final Supplier<VirtualBoxManager> manager;
private final Factory scriptRunner; private final Factory scriptRunner;
private final Supplier<NodeMetadata> host; private final Supplier<NodeMetadata> host;
@Inject @Inject
public MachineUtils(Supplier<VirtualBoxManager> manager, RunScriptOnNode.Factory scriptRunner, public MachineUtils(Supplier<VirtualBoxManager> manager, RunScriptOnNode.Factory scriptRunner,
Supplier<NodeMetadata> host) { Supplier<NodeMetadata> host) {
super(); super();
this.manager = manager; this.manager = manager;
this.scriptRunner = scriptRunner; this.scriptRunner = scriptRunner;
this.host = host; this.host = host;
} }
public ListenableFuture<ExecResponse> runScriptOnNode(NodeMetadata metadata, Statement statement, public ListenableFuture<ExecResponse> runScriptOnNode(NodeMetadata metadata, Statement statement,
RunScriptOptions options) { RunScriptOptions options) {
return scriptRunner.submit(metadata, statement, options); return scriptRunner.submit(metadata, statement, options);
} }
/** /**
* Locks the machine and executes the given function using the machine matching the given id. Since the machine is * Locks the machine and executes the given function using the machine matching the given id.
* locked it is possible to perform some modifications to the IMachine. * Since the machine is locked it is possible to perform some modifications to the IMachine.
* <p/> * <p/>
* Unlocks the machine before returning. * Unlocks the machine before returning.
* *
* @param machineId * @param machineId
* the id of the machine * the id of the machine
* @param function * @param function
* the function to execute * the function to execute
* @return the result from applying the function to the machine. * @return the result from applying the function to the machine.
*/ */
public <T> T writeLockMachineAndApply(final String machineId, final Function<IMachine, T> function) { public <T> T writeLockMachineAndApply(final String machineId, final Function<IMachine, T> function) {
return lockSessionOnMachineAndApply(machineId, LockType.Write, new Function<ISession, T>() { return lockSessionOnMachineAndApply(machineId, LockType.Write, new Function<ISession, T>() {
@Override @Override
public T apply(ISession session) { public T apply(ISession session) {
return function.apply(session.getMachine()); return function.apply(session.getMachine());
} }
@Override @Override
public String toString() { public String toString() {
return function.toString(); return function.toString();
} }
}); });
} }
/** /**
* Locks the machine and executes the given function using the current session. Since the machine is locked it is * Locks the machine and executes the given function using the current session. Since the machine
* possible to perform some modifications to the IMachine. * is locked it is possible to perform some modifications to the IMachine.
* <p/> * <p/>
* Unlocks the machine before returning. * Unlocks the machine before returning.
* *
* @param type * @param type
* the kind of lock to use when initially locking the machine. * the kind of lock to use when initially locking the machine.
* @param machineId * @param machineId
* the id of the machine * the id of the machine
* @param function * @param function
* the function to execute * the function to execute
* @return the result from applying the function to the session. * @return the result from applying the function to the session.
*/ */
public <T> T lockSessionOnMachineAndApply(String machineId, LockType type, Function<ISession, T> function) { public <T> T lockSessionOnMachineAndApply(String machineId, LockType type, Function<ISession, T> function) {
try {
ISession session = lockSessionOnMachine(type, machineId);
try { try {
return function.apply(session); ISession session = lockSessionOnMachine(type, machineId);
} finally { try {
session.unlockMachine(); return function.apply(session);
} finally {
session.unlockMachine();
}
} catch (VBoxException e) {
throw new RuntimeException(String.format("error applying %s to %s with %s lock: %s", function, machineId,
type, e.getMessage()), e);
} }
} catch (VBoxException e) { }
throw new RuntimeException(String.format("error applying %s to %s with %s lock: %s", function, machineId, type,
e.getMessage()), e);
}
}
private ISession lockSessionOnMachine(LockType type, String machineId) { private ISession lockSessionOnMachine(LockType type, String machineId) {
return new MutableMachine(manager, type).apply(machineId); return new MutableMachine(manager, type).apply(machineId);
} }
private void unlockMachine(final String machineId) { private void unlockMachine(final String machineId) {
IMachine immutableMachine = manager.get().getVBox().findMachine(machineId);
if (immutableMachine.getSessionState().equals(SessionState.Locked)) {
Statement kill = newStatementList(call("default"), findPid(immutableMachine.getSessionPid().toString()), kill());
scriptRunner.create(host.get(), kill, runAsRoot(false).wrapInInitScript(false)).init().call();
}
}
/**
* Unlocks the machine and executes the given function using the machine matching the given id. Since the machine is
* unlocked it is possible to delete the IMachine.
* <p/>
* <p/>
* <h3>Note!</h3> Currently, this can only unlock the machine, if the lock was created in the current session.
*
* @param machineId
* the id of the machine
* @param function
* the function to execute
* @return the result from applying the function to the machine.
*/
public <T> T unlockMachineAndApply(final String machineId, final Function<IMachine, T> function) {
try {
unlockMachine(machineId);
IMachine immutableMachine = manager.get().getVBox().findMachine(machineId); IMachine immutableMachine = manager.get().getVBox().findMachine(machineId);
return function.apply(immutableMachine); if (immutableMachine.getSessionState().equals(SessionState.Locked)) {
Statement kill = newStatementList(call("default"), findPid(immutableMachine.getSessionPid().toString()),
} catch (VBoxException e) { kill());
throw new RuntimeException(String.format("error applying %s to %s: %s", function, machineId, e.getMessage()), e); scriptRunner.create(host.get(), kill, runAsRoot(false).wrapInInitScript(false)).init().call();
}
}
/**
* Unlocks the machine and executes the given function, if the machine is registered. Since the machine is unlocked it
* is possible to delete the machine.
* <p/>
*
* @param machineId
* the id of the machine
* @param function
* the function to execute
* @return the result from applying the function to the session.
*/
public <T> T unlockMachineAndApplyOrReturnNullIfNotRegistered(String machineId, Function<IMachine, T> function) {
try {
return unlockMachineAndApply(machineId, function);
} catch (RuntimeException e) {
VBoxException vbex = Throwables2.getFirstThrowableOfType(e, VBoxException.class);
if (vbex != null && vbex.getMessage().indexOf("not find a registered") == -1)
throw e;
return null;
}
}
/**
* @param machineId
* @param function
* @return
*/
public <T> T applyForMachine(final String machineId, final Function<IMachine, T> function) {
final IMachine immutableMachine = manager.get().getVBox().findMachine(machineId);
return new Function<IMachine, T>() {
@Override
public T apply(IMachine machine) {
return function.apply(machine);
} }
}
@Override /**
public String toString() { * Unlocks the machine and executes the given function using the machine matching the given id.
return function.toString(); * Since the machine is unlocked it is possible to delete the IMachine.
* <p/>
* <p/>
* <h3>Note!</h3> Currently, this can only unlock the machine, if the lock was created in the
* current session.
*
* @param machineId
* the id of the machine
* @param function
* the function to execute
* @return the result from applying the function to the machine.
*/
public <T> T unlockMachineAndApply(final String machineId, final Function<IMachine, T> function) {
try {
unlockMachine(machineId);
IMachine immutableMachine = manager.get().getVBox().findMachine(machineId);
return function.apply(immutableMachine);
} catch (VBoxException e) {
throw new RuntimeException(String.format("error applying %s to %s: %s", function, machineId, e.getMessage()),
e);
} }
}.apply(immutableMachine); }
}
public static boolean machineNotFoundException(VBoxException e) { /**
return e.getMessage().contains("VirtualBox error: Could not find a registered machine named ") * Unlocks the machine and executes the given function, if the machine is registered. Since the
|| e.getMessage().contains("Could not find a registered machine with UUID {"); * machine is unlocked it is possible to delete the machine.
} * <p/>
*
* @param machineId
* the id of the machine
* @param function
* the function to execute
* @return the result from applying the function to the session.
*/
public <T> T unlockMachineAndApplyOrReturnNullIfNotRegistered(String machineId, Function<IMachine, T> function) {
try {
return unlockMachineAndApply(machineId, function);
} catch (RuntimeException e) {
VBoxException vbex = Throwables2.getFirstThrowableOfType(e, VBoxException.class);
if (vbex != null && vbex.getMessage().indexOf("not find a registered") == -1)
throw e;
return null;
}
}
/**
* @param machineId
* @param function
* @return
*/
public <T> T applyForMachine(final String machineId, final Function<IMachine, T> function) {
final IMachine immutableMachine = manager.get().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 boolean machineNotFoundException(VBoxException e) {
return e.getMessage().contains("VirtualBox error: Could not find a registered machine named ")
|| e.getMessage().contains("Could not find a registered machine with UUID {");
}
} }

View File

@ -32,7 +32,6 @@ import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.OsFamily; import org.jclouds.compute.domain.OsFamily;
import org.jclouds.compute.functions.DefaultCredentialsFromImageOrOverridingCredentials; import org.jclouds.compute.functions.DefaultCredentialsFromImageOrOverridingCredentials;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.compute.strategy.PrioritizeCredentialsFromTemplate; import org.jclouds.compute.strategy.PrioritizeCredentialsFromTemplate;
import org.jclouds.config.ValueOfConfigurationKeyOrNull; import org.jclouds.config.ValueOfConfigurationKeyOrNull;
import org.jclouds.logging.slf4j.config.SLF4JLoggingModule; import org.jclouds.logging.slf4j.config.SLF4JLoggingModule;
@ -85,7 +84,7 @@ public class BaseVirtualBoxClientLiveTest extends BaseVersionedServiceLiveTest {
protected String isosDir; protected String isosDir;
protected Supplier<NodeMetadata> host; protected Supplier<NodeMetadata> host;
protected static final PrioritizeCredentialsFromTemplate prioritizeCredentialsFromTemplate = new PrioritizeCredentialsFromTemplate( protected static final PrioritizeCredentialsFromTemplate prioritizeCredentialsFromTemplate = new PrioritizeCredentialsFromTemplate(
new DefaultCredentialsFromImageOrOverridingCredentials()); new DefaultCredentialsFromImageOrOverridingCredentials());
@Override @Override
protected void setupCredentials() { protected void setupCredentials() {
@ -97,11 +96,10 @@ public class BaseVirtualBoxClientLiveTest extends BaseVersionedServiceLiveTest {
} }
protected void ensureIdentityPropertyIsSpecifiedOrTakeFromDefaults() { protected void ensureIdentityPropertyIsSpecifiedOrTakeFromDefaults() {
Properties defaultVBoxProperties = new VirtualBoxPropertiesBuilder() Properties defaultVBoxProperties = new VirtualBoxPropertiesBuilder().build();
.build();
if (!System.getProperties().containsKey("test." + provider + ".identity")) if (!System.getProperties().containsKey("test." + provider + ".identity"))
System.setProperty("test." + provider + ".identity", System.setProperty("test." + provider + ".identity",
defaultVBoxProperties.getProperty(Constants.PROPERTY_IDENTITY)); defaultVBoxProperties.getProperty(Constants.PROPERTY_IDENTITY));
} }
@BeforeClass(groups = "live") @BeforeClass(groups = "live")
@ -109,44 +107,33 @@ public class BaseVirtualBoxClientLiveTest extends BaseVersionedServiceLiveTest {
setupCredentials(); setupCredentials();
Properties overrides = new VirtualBoxPropertiesBuilder(setupProperties()).build(); Properties overrides = new VirtualBoxPropertiesBuilder(setupProperties()).build();
CacheNodeStoreModule hostModule = new CacheNodeStoreModule( CacheNodeStoreModule hostModule = new CacheNodeStoreModule(ImmutableMap.of(
ImmutableMap.of( "host",
"host", Node.builder().id("host").name("host installing virtualbox").hostname("localhost")
Node.builder() .osFamily(OsFamily.LINUX.toString()).osDescription(System.getProperty("os.name"))
.id("host") .osVersion(System.getProperty("os.version")).group("ssh")
.name("host installing virtualbox") .username(System.getProperty("user.name"))
.hostname("localhost") .credentialUrl(URI.create("file://" + System.getProperty("user.home") + "/.ssh/id_rsa"))
.osFamily(OsFamily.LINUX.toString()) .build()));
.osDescription(System.getProperty("os.name"))
.osVersion(System.getProperty("os.version"))
.group("ssh")
.username(System.getProperty("user.name"))
.credentialUrl(
URI.create("file://"
+ System.getProperty("user.home")
+ "/.ssh/id_rsa")).build()));
context = new ComputeServiceContextFactory().createContext(provider, context = new ComputeServiceContextFactory().createContext(provider, identity, credential,
identity, credential, ImmutableSet.<Module>of( ImmutableSet.<Module> of(new SLF4JLoggingModule(), new SshjSshClientModule(), hostModule), overrides);
new SLF4JLoggingModule(), new SshjSshClientModule(),
hostModule), overrides);
Function<String, String> configProperties = context.utils().injector() Function<String, String> configProperties = context.utils().injector()
.getInstance(ValueOfConfigurationKeyOrNull.class); .getInstance(ValueOfConfigurationKeyOrNull.class);
imageId = "ubuntu-11.04-server-i386"; imageId = "ubuntu-11.04-server-i386";
workingDir = configProperties workingDir = configProperties.apply(VirtualBoxConstants.VIRTUALBOX_WORKINGDIR);
.apply(VirtualBoxConstants.VIRTUALBOX_WORKINGDIR); isosDir = workingDir + File.separator + "isos";
isosDir = workingDir+File.separator+"isos";
File isosDirFile = new File(isosDir); File isosDirFile = new File(isosDir);
if(!isosDirFile.exists()){ if (!isosDirFile.exists()) {
isosDirFile.mkdirs(); isosDirFile.mkdirs();
} }
host = context.utils().injector() host = context.utils().injector().getInstance(Key.get(new TypeLiteral<Supplier<NodeMetadata>>() {
.getInstance(Key.get(new TypeLiteral<Supplier<NodeMetadata>>() { }));
}));
// this will eagerly startup Jetty, note the impl will shut itself down // this will eagerly startup Jetty, note the impl will shut itself down
preconfigurationUri = context.utils().injector().getInstance(Key.get(new TypeLiteral<LoadingCache<IsoSpec, URI>>() { preconfigurationUri = context.utils().injector()
}, Preconfiguration.class)); .getInstance(Key.get(new TypeLiteral<LoadingCache<IsoSpec, URI>>() {
}, Preconfiguration.class));
// this will eagerly startup Jetty, note the impl will shut itself down // this will eagerly startup Jetty, note the impl will shut itself down
manager = context.utils().injector().getInstance(Key.get(new TypeLiteral<Supplier<VirtualBoxManager>>() { manager = context.utils().injector().getInstance(Key.get(new TypeLiteral<Supplier<VirtualBoxManager>>() {
@ -156,43 +143,40 @@ public class BaseVirtualBoxClientLiveTest extends BaseVersionedServiceLiveTest {
machineUtils = context.utils().injector().getInstance(MachineUtils.class); machineUtils = context.utils().injector().getInstance(MachineUtils.class);
hostVersion = Iterables.get( hostVersion = Iterables.get(Splitter.on('r').split(context.getProviderSpecificContext().getBuildVersion()), 0);
Splitter.on('r').split(
context.getProviderSpecificContext().getBuildVersion()), 0);
adminDisk = workingDir + "/testadmin.vdi"; adminDisk = workingDir + "/testadmin.vdi";
operatingSystemIso = String.format("%s/%s.iso", isosDir, imageId); operatingSystemIso = String.format("%s/%s.iso", isosDir, imageId);
guestAdditionsIso = String.format("%s/VBoxGuestAdditions_%s.iso", guestAdditionsIso = String.format("%s/VBoxGuestAdditions_%s.iso", isosDir, hostVersion);
isosDir, hostVersion);
} }
protected void undoVm(VmSpec vmSpecification) { protected void undoVm(VmSpec vmSpecification) {
machineUtils.unlockMachineAndApplyOrReturnNullIfNotRegistered( machineUtils.unlockMachineAndApplyOrReturnNullIfNotRegistered(vmSpecification.getVmId(),
vmSpecification.getVmId(), new UnregisterMachineIfExistsAndDeleteItsMedia(vmSpecification));
new UnregisterMachineIfExistsAndDeleteItsMedia(vmSpecification));
} }
protected void ensureMachineHasPowerDown(String vmName) { protected void ensureMachineHasPowerDown(String vmName) {
while (!manager.get().getVBox().findMachine(vmName).getState().equals(MachineState.POWERED_OFF)) { while (!manager.get().getVBox().findMachine(vmName).getState().equals(MachineState.POWERED_OFF)) {
try { try {
machineUtils.lockSessionOnMachineAndApply(vmName, LockType.Shared, new Function<ISession, Void>() { machineUtils.lockSessionOnMachineAndApply(vmName, LockType.Shared, new Function<ISession, Void>() {
@Override @Override
public Void apply(ISession session) { public Void apply(ISession session) {
IProgress powerDownProgress = session.getConsole().powerDown(); IProgress powerDownProgress = session.getConsole().powerDown();
powerDownProgress.waitForCompletion(-1); powerDownProgress.waitForCompletion(-1);
return null; return null;
} }
}); });
} catch (RuntimeException e) { } catch (RuntimeException e) {
// sometimes the machine might be powered of between the while test and the call to lockSessionOnMachineAndApply // sometimes the machine might be powered of between the while test and the call to
if (e.getMessage().contains("Invalid machine state: PoweredOff")){ // lockSessionOnMachineAndApply
return; if (e.getMessage().contains("Invalid machine state: PoweredOff")) {
} else if(e.getMessage().contains("VirtualBox error: The object is not ready")){ return;
continue; } else if (e.getMessage().contains("VirtualBox error: The object is not ready")) {
} else { continue;
throw e; } else {
throw e;
}
} }
} }
}
} }
@AfterClass(groups = "live") @AfterClass(groups = "live")

View File

@ -38,70 +38,70 @@ import com.google.common.collect.Iterables;
@Test(groups = "live", singleThreaded = true, testName = "VirtualBoxComputeServiceAdapterLiveTest") @Test(groups = "live", singleThreaded = true, testName = "VirtualBoxComputeServiceAdapterLiveTest")
public class VirtualBoxComputeServiceAdapterLiveTest extends BaseVirtualBoxClientLiveTest { public class VirtualBoxComputeServiceAdapterLiveTest extends BaseVirtualBoxClientLiveTest {
private VirtualBoxComputeServiceAdapter adapter; private VirtualBoxComputeServiceAdapter adapter;
private NodeAndInitialCredentials<IMachine> machine; private NodeAndInitialCredentials<IMachine> machine;
@Override @Override
public void setupClient() { public void setupClient() {
super.setupClient(); super.setupClient();
adapter = context.utils().injector().getInstance(VirtualBoxComputeServiceAdapter.class); adapter = context.utils().injector().getInstance(VirtualBoxComputeServiceAdapter.class);
} }
@Test @Test
public void testCreateNodeWithGroupEncodedIntoNameThenStoreCredentials() { public void testCreateNodeWithGroupEncodedIntoNameThenStoreCredentials() {
String group = "foo"; String group = "foo";
String name = "foo-ef4"; String name = "foo-ef4";
String machineName = VIRTUALBOX_NODE_PREFIX + "myTestId-" + group + "-" + name; String machineName = VIRTUALBOX_NODE_PREFIX + "myTestId-" + group + "-" + name;
// get the image from // get the image from
Image image = Iterables.get(adapter.listImages(), 0); Image image = Iterables.get(adapter.listImages(), 0);
System.out.println(context.getComputeService().templateBuilder()); System.out.println(context.getComputeService().templateBuilder());
Template template = context.getComputeService().templateBuilder().fromImage(image).build(); Template template = context.getComputeService().templateBuilder().fromImage(image).build();
machine = adapter.createNodeWithGroupEncodedIntoName(group, name, template); machine = adapter.createNodeWithGroupEncodedIntoName(group, name, template);
assertEquals(machine.getNode().getName(), machineName); assertEquals(machine.getNode().getName(), machineName);
// is there a place for group? // is there a place for group?
// check other things, like cpu correct, mem correct, image/os is correct // check other things, like cpu correct, mem correct, image/os is correct
// (as possible) // (as possible)
// TODO: what's the IP address? // TODO: what's the IP address?
// assert // assert
// InetAddresses.isInetAddress(machine.getPrimaryBackendIpAddress()) : // InetAddresses.isInetAddress(machine.getPrimaryBackendIpAddress()) :
// machine; // machine;
doConnectViaSsh(machine.getNode(), prioritizeCredentialsFromTemplate.apply(template, machine.getCredentials())); doConnectViaSsh(machine.getNode(), prioritizeCredentialsFromTemplate.apply(template, machine.getCredentials()));
} }
protected void doConnectViaSsh(IMachine machine, LoginCredentials creds) { protected void doConnectViaSsh(IMachine machine, LoginCredentials creds) {
SshClient ssh = context.utils().injector().getInstance(IMachineToSshClient.class).apply(machine); SshClient ssh = context.utils().injector().getInstance(IMachineToSshClient.class).apply(machine);
try { try {
ssh.connect(); ssh.connect();
ExecResponse hello = ssh.exec("echo hello"); ExecResponse hello = ssh.exec("echo hello");
assertEquals(hello.getOutput().trim(), "hello"); assertEquals(hello.getOutput().trim(), "hello");
System.err.println(ssh.exec("df -k").getOutput()); System.err.println(ssh.exec("df -k").getOutput());
System.err.println(ssh.exec("mount").getOutput()); System.err.println(ssh.exec("mount").getOutput());
System.err.println(ssh.exec("uname -a").getOutput()); System.err.println(ssh.exec("uname -a").getOutput());
} finally { } finally {
if (ssh != null) if (ssh != null)
ssh.disconnect(); ssh.disconnect();
} }
} }
@Test @Test
public void testListHardwareProfiles() { public void testListHardwareProfiles() {
Iterable<IMachine> profiles = adapter.listHardwareProfiles(); Iterable<IMachine> profiles = adapter.listHardwareProfiles();
assertEquals(1, Iterables.size(profiles)); assertEquals(1, Iterables.size(profiles));
} }
@Test @Test
public void testListImages() { public void testListImages() {
Iterable<Image> iMageIterable = adapter.listImages(); Iterable<Image> iMageIterable = adapter.listImages();
for (Image image : iMageIterable) { for (Image image : iMageIterable) {
System.out.println(image); System.out.println(image);
} }
// check state; // check state;
} }
@Override @Override
protected void tearDown() throws Exception { protected void tearDown() throws Exception {
if (machine != null) if (machine != null)
// adapter.destroyNode(machine.getNodeId() + ""); // adapter.destroyNode(machine.getNodeId() + "");
super.tearDown(); super.tearDown();
} }
} }

View File

@ -20,16 +20,12 @@
package org.jclouds.virtualbox.functions; package org.jclouds.virtualbox.functions;
import static com.google.common.base.Preconditions.checkState; 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 junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertEquals;
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_IMAGE_PREFIX; import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_IMAGE_PREFIX;
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_INSTALLATION_KEY_SEQUENCE; import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_INSTALLATION_KEY_SEQUENCE;
import static org.testng.Assert.assertTrue; import static org.testng.Assert.assertTrue;
import java.util.Map; import java.util.Map;
import java.util.Set;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -57,18 +53,15 @@ import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import org.virtualbox_4_1.CleanupMode; import org.virtualbox_4_1.CleanupMode;
import org.virtualbox_4_1.IMachine; import org.virtualbox_4_1.IMachine;
import org.virtualbox_4_1.IProgress;
import org.virtualbox_4_1.ISession; import org.virtualbox_4_1.ISession;
import org.virtualbox_4_1.LockType; import org.virtualbox_4_1.LockType;
import org.virtualbox_4_1.NetworkAttachmentType; import org.virtualbox_4_1.NetworkAttachmentType;
import org.virtualbox_4_1.StorageBus; import org.virtualbox_4_1.StorageBus;
import org.virtualbox_4_1.jaxws.MachineState;
import com.google.common.base.CaseFormat; import com.google.common.base.CaseFormat;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
import com.google.common.base.Splitter; import com.google.common.base.Splitter;
import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import com.google.inject.Guice; import com.google.inject.Guice;
@ -80,142 +73,119 @@ import com.google.inject.Injector;
@Test(groups = "live", singleThreaded = true, testName = "CreateAndInstallVmLiveTest") @Test(groups = "live", singleThreaded = true, testName = "CreateAndInstallVmLiveTest")
public class CreateAndInstallVmLiveTest extends BaseVirtualBoxClientLiveTest { public class CreateAndInstallVmLiveTest extends BaseVirtualBoxClientLiveTest {
Map<OsFamily, Map<String, String>> map = new BaseComputeServiceContextModule() { Map<OsFamily, Map<String, String>> map = new BaseComputeServiceContextModule() {
}.provideOsVersionMap(new ComputeServiceConstants.ReferenceData(), Guice }.provideOsVersionMap(new ComputeServiceConstants.ReferenceData(), Guice.createInjector(new GsonModule())
.createInjector(new GsonModule()).getInstance(Json.class)); .getInstance(Json.class));
private VmSpec vmSpecification; private VmSpec vmSpecification;
private MasterSpec masterSpec; private MasterSpec masterSpec;
private Injector injector; private Injector injector;
private Function<IMachine, SshClient> sshClientForIMachine; private Function<IMachine, SshClient> sshClientForIMachine;
private Predicate<SshClient> sshResponds; private Predicate<SshClient> sshResponds;
private String vmName; private String vmName;
@Override @Override
@BeforeClass(groups = "live") @BeforeClass(groups = "live")
public void setupClient() { public void setupClient() {
super.setupClient(); super.setupClient();
this.vmName = VIRTUALBOX_IMAGE_PREFIX this.vmName = VIRTUALBOX_IMAGE_PREFIX
+ CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_HYPHEN, getClass() + CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_HYPHEN, getClass().getSimpleName());
.getSimpleName());
HardDisk hardDisk = HardDisk.builder().diskpath(adminDisk) HardDisk hardDisk = HardDisk.builder().diskpath(adminDisk).autoDelete(true).controllerPort(0).deviceSlot(1)
.autoDelete(true).controllerPort(0).deviceSlot(1).build(); .build();
StorageController ideController = StorageController.builder() StorageController ideController = StorageController.builder().name("IDE Controller").bus(StorageBus.IDE)
.name("IDE Controller").bus(StorageBus.IDE) .attachISO(0, 0, operatingSystemIso).attachHardDisk(hardDisk).attachISO(1, 1, guestAdditionsIso).build();
.attachISO(0, 0, operatingSystemIso).attachHardDisk(hardDisk) vmSpecification = VmSpec.builder().id(vmName).name(vmName).memoryMB(512).osTypeId("").controller(ideController)
.attachISO(1, 1, guestAdditionsIso).build(); .forceOverwrite(true).cleanUpMode(CleanupMode.Full).build();
vmSpecification = VmSpec.builder().id(vmName).name(vmName)
.memoryMB(512).osTypeId("").controller(ideController)
.forceOverwrite(true).cleanUpMode(CleanupMode.Full).build();
injector = context.utils().injector(); injector = context.utils().injector();
Function<String, String> configProperties = injector Function<String, String> configProperties = injector.getInstance(ValueOfConfigurationKeyOrNull.class);
.getInstance(ValueOfConfigurationKeyOrNull.class);
NetworkAdapter networkAdapter = NetworkAdapter.builder() NetworkAdapter networkAdapter = NetworkAdapter.builder().networkAttachmentType(NetworkAttachmentType.NAT)
.networkAttachmentType(NetworkAttachmentType.NAT) .tcpRedirectRule("127.0.0.1", 2222, "", 22).build();
.tcpRedirectRule("127.0.0.1", 2222, "", 22).build(); NetworkInterfaceCard networkInterfaceCard = NetworkInterfaceCard.builder().addNetworkAdapter(networkAdapter)
NetworkInterfaceCard networkInterfaceCard = NetworkInterfaceCard .build();
.builder().addNetworkAdapter(networkAdapter).build();
NetworkSpec networkSpec = NetworkSpec.builder() NetworkSpec networkSpec = NetworkSpec.builder().addNIC(0L, networkInterfaceCard).build();
.addNIC(0L, networkInterfaceCard).build();
masterSpec = MasterSpec masterSpec = MasterSpec
.builder() .builder()
.vm(vmSpecification) .vm(vmSpecification)
.iso(IsoSpec .iso(IsoSpec
.builder() .builder()
.sourcePath(operatingSystemIso) .sourcePath(operatingSystemIso)
.installationScript( .installationScript(
configProperties.apply( configProperties.apply(VIRTUALBOX_INSTALLATION_KEY_SEQUENCE).replace("HOSTNAME",
VIRTUALBOX_INSTALLATION_KEY_SEQUENCE) vmSpecification.getVmName())).build()).network(networkSpec).build();
.replace("HOSTNAME",
vmSpecification.getVmName()))
.build()).network(networkSpec).build();
undoVm(vmSpecification); undoVm(vmSpecification);
} }
@Test @Test
public void testCreateImageMachineFromIso() throws Exception { public void testCreateImageMachineFromIso() throws Exception {
IMachine imageMachine = getVmWithGuestAdditionsInstalled(); IMachine imageMachine = getVmWithGuestAdditionsInstalled();
IMachineToImage iMachineToImage = new IMachineToImage(manager, map); IMachineToImage iMachineToImage = new IMachineToImage(manager, map);
Image newImage = iMachineToImage.apply(imageMachine); Image newImage = iMachineToImage.apply(imageMachine);
assertEquals(vmName,newImage.getName()); assertEquals(vmName, newImage.getName());
} }
@Test @Test
public void testGuestAdditionsAreInstalled() throws Exception { public void testGuestAdditionsAreInstalled() throws Exception {
try { try {
IMachine machine = getVmWithGuestAdditionsInstalled(); IMachine machine = getVmWithGuestAdditionsInstalled();
machineUtils.applyForMachine(machine.getName(), machineUtils.applyForMachine(machine.getName(), new LaunchMachineIfNotAlreadyRunning(manager.get(),
new LaunchMachineIfNotAlreadyRunning(manager.get(), ExecutionType.GUI, ""));
ExecutionType.GUI, "")); sshClientForIMachine = injector.getInstance(IMachineToSshClient.class);
sshClientForIMachine = injector SshClient client = sshClientForIMachine.apply(machine);
.getInstance(IMachineToSshClient.class);
SshClient client = sshClientForIMachine.apply(machine);
sshResponds = injector.getInstance(SshResponds.class); sshResponds = injector.getInstance(SshResponds.class);
checkState(sshResponds.apply(client), checkState(sshResponds.apply(client), "timed out waiting for guest %s to be accessible via ssh",
"timed out waiting for guest %s to be accessible via ssh", machine.getName());
machine.getName());
assertTrue(machineUtils.lockSessionOnMachineAndApply( assertTrue(machineUtils.lockSessionOnMachineAndApply(machine.getName(), LockType.Shared,
machine.getName(), LockType.Shared, new Function<ISession, Boolean>() {
new Function<ISession, Boolean>() { @Override
@Override public Boolean apply(ISession session) {
public Boolean apply(ISession session) { String vboxVersion = Iterables.get(
String vboxVersion = Iterables Splitter.on('r').split(context.getProviderSpecificContext().getBuildVersion()), 0);
.get(Splitter return session.getMachine().getGuestPropertyValue("/VirtualBox/GuestAdd/Version")
.on('r') .equals(vboxVersion);
.split(context }
.getProviderSpecificContext() }));
.getBuildVersion()), 0); } finally {
return session for (VmSpec spec : ImmutableSet.of(vmSpecification)) {
.getMachine() ensureMachineHasPowerDown(spec.getVmName());
.getGuestPropertyValue( }
"/VirtualBox/GuestAdd/Version") }
.equals(vboxVersion); }
}
}));
} finally {
for (VmSpec spec : ImmutableSet.of(vmSpecification)) {
ensureMachineHasPowerDown(spec.getVmName());
}
}
}
private Function<Image, String> extractId() { private Function<Image, String> extractId() {
return new Function<Image, String>() { return new Function<Image, String>() {
@Override @Override
public String apply(@Nullable Image input) { public String apply(@Nullable Image input) {
return input.getId(); return input.getId();
} }
}; };
} }
private IMachine getVmWithGuestAdditionsInstalled() { private IMachine getVmWithGuestAdditionsInstalled() {
try { try {
Injector injector = context.utils().injector(); Injector injector = context.utils().injector();
return injector.getInstance(CreateAndInstallVm.class).apply( return injector.getInstance(CreateAndInstallVm.class).apply(masterSpec);
masterSpec); } catch (IllegalStateException e) {
} catch (IllegalStateException e) { // already created
// already created return manager.get().getVBox().findMachine(masterSpec.getVmSpec().getVmId());
return manager.get().getVBox() }
.findMachine(masterSpec.getVmSpec().getVmId()); }
}
}
@Override @Override
@AfterClass(groups = "live") @AfterClass(groups = "live")
protected void tearDown() throws Exception { protected void tearDown() throws Exception {
for (VmSpec spec : ImmutableSet.of(vmSpecification)) { for (VmSpec spec : ImmutableSet.of(vmSpecification)) {
undoVm(spec); undoVm(spec);
} }
super.tearDown(); super.tearDown();
} }
} }