mirror of https://github.com/apache/jclouds.git
formatted most changed classes to comply with jclouds formatting guildelines
This commit is contained in:
parent
c08cbc89f4
commit
fa26fe34f9
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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";
|
||||||
|
|
||||||
|
|
|
@ -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 +
|
|
||||||
'}';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 +
|
|
||||||
'}';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 +
|
|
||||||
'}';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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, ""));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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")));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -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 {");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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")
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue