issue 384: removed KickstartAdmin, VirtualboxLiveTest. Refactoring of listImages to support yaml idea

This commit is contained in:
andreaturli 2011-10-18 00:15:46 +01:00
parent 552242e863
commit a3505f80d1
9 changed files with 435 additions and 1007 deletions

View File

@ -69,9 +69,10 @@ public class VirtualBoxComputeServiceContextModule extends ComputeServiceAdapter
@Singleton @Singleton
protected VirtualBoxManager createInstance(@Provider URI endpoint, @Named(Constants.PROPERTY_IDENTITY) String identity, protected VirtualBoxManager createInstance(@Provider URI endpoint, @Named(Constants.PROPERTY_IDENTITY) String identity,
@Named(Constants.PROPERTY_CREDENTIAL) String credential) { @Named(Constants.PROPERTY_CREDENTIAL) String credential) {
VirtualBoxManager manager = VirtualBoxManager.createInstance(""); VirtualBoxManager manager = VirtualBoxManager.createInstance("");
manager.connect(endpoint.toASCIIString(), identity, credential); manager.connect(endpoint.toASCIIString(), identity, credential);
return manager; return manager;
} }
@SuppressWarnings({ "unchecked", "rawtypes" }) @SuppressWarnings({ "unchecked", "rawtypes" })

View File

@ -56,4 +56,11 @@ public interface VirtualBoxConstants {
public static final String VIRTUALBOX_DISTRO_ISO_NAME = "jclouds.virtualbox.distroisoname"; public static final String VIRTUALBOX_DISTRO_ISO_NAME = "jclouds.virtualbox.distroisoname";
public static final String VIRTUALBOX_JETTY_PORT = "jclouds.virtualbox.jetty.port"; public static final String VIRTUALBOX_JETTY_PORT = "jclouds.virtualbox.jetty.port";
public static final String VIRTUALBOX_JETTY_BASE_RESOURCE = "jclouds.virtualbox.jetty.baseresource";
public static final String VIRTUALBOX_WEBSERVER_IDENTITY = "jclouds.virtualbox.webserver.identity";
public static final String VIRTUALBOX_WEBSERVER_CREDENTIAL = "jclouds.virtualbox.webserver.credential";
} }

View File

@ -21,8 +21,22 @@
package org.jclouds.virtualbox.functions; package org.jclouds.virtualbox.functions;
import com.google.common.base.Function; import static com.google.common.base.Throwables.propagate;
import com.google.inject.Inject; import static org.jclouds.compute.options.RunScriptOptions.Builder.runAsRoot;
import static org.jclouds.compute.options.RunScriptOptions.Builder.wrapInInitScript;
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_INSTALLATION_KEY_SEQUENCE;
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_WORKINGDIR;
import static org.virtualbox_4_1.AccessMode.ReadOnly;
import static org.virtualbox_4_1.DeviceType.DVD;
import static org.virtualbox_4_1.LockType.Write;
import static org.virtualbox_4_1.NATProtocol.TCP;
import static org.virtualbox_4_1.NetworkAttachmentType.NAT;
import java.io.File;
import javax.annotation.Resource;
import javax.inject.Named;
import org.eclipse.jetty.server.Handler; import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.DefaultHandler; import org.eclipse.jetty.server.handler.DefaultHandler;
@ -36,275 +50,252 @@ import org.jclouds.domain.Credentials;
import org.jclouds.javax.annotation.Nullable; import org.jclouds.javax.annotation.Nullable;
import org.jclouds.logging.Logger; import org.jclouds.logging.Logger;
import org.jclouds.ssh.SshException; import org.jclouds.ssh.SshException;
import org.jclouds.virtualbox.config.VirtualBoxConstants;
import org.jclouds.virtualbox.functions.admin.StartJettyIfNotAlreadyRunning;
import org.jclouds.virtualbox.settings.KeyboardScancodes; import org.jclouds.virtualbox.settings.KeyboardScancodes;
import org.virtualbox_4_1.*; import org.virtualbox_4_1.AccessMode;
import org.virtualbox_4_1.DeviceType;
import org.virtualbox_4_1.IMachine;
import org.virtualbox_4_1.IMedium;
import org.virtualbox_4_1.IProgress;
import org.virtualbox_4_1.ISession;
import org.virtualbox_4_1.LockType;
import org.virtualbox_4_1.StorageBus;
import org.virtualbox_4_1.VirtualBoxManager;
import org.virtualbox_4_1.jaxws.MediumVariant; import org.virtualbox_4_1.jaxws.MediumVariant;
import javax.annotation.Resource; import com.google.common.base.Function;
import javax.inject.Named; import com.google.inject.Inject;
import java.io.File;
import static com.google.common.base.Throwables.propagate;
import static org.jclouds.compute.options.RunScriptOptions.Builder.runAsRoot;
import static org.jclouds.compute.options.RunScriptOptions.Builder.wrapInInitScript;
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_INSTALLATION_KEY_SEQUENCE;
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_WORKINGDIR;
import static org.virtualbox_4_1.AccessMode.ReadOnly;
import static org.virtualbox_4_1.DeviceType.DVD;
import static org.virtualbox_4_1.LockType.Write;
import static org.virtualbox_4_1.NATProtocol.TCP;
import static org.virtualbox_4_1.NetworkAttachmentType.NAT;
public class IsoToIMachine implements Function<String, IMachine> { public class IsoToIMachine implements Function<String, IMachine> {
@Resource @Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER) @Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL; protected Logger logger = Logger.NULL;
private VirtualBoxManager manager; private VirtualBoxManager manager;
private String adminDisk; private String adminDisk;
private String diskFormat; private String diskFormat;
private String settingsFile; private String settingsFile;
private String vmName; private String vmName;
private String osTypeId; private String osTypeId;
private String vmId; private String vmId;
private String controllerIDE; private String controllerIDE;
private boolean forceOverwrite; private boolean forceOverwrite;
private ComputeServiceContext context; private ComputeServiceContext context;
private String hostId; private String hostId;
private String guestId; private String guestId;
private Credentials credentials; private Credentials credentials;
@Inject @Inject
public IsoToIMachine(VirtualBoxManager manager, public IsoToIMachine(VirtualBoxManager manager,
String adminDisk, String adminDisk,
String diskFormat, String diskFormat,
String settingsFile, String settingsFile,
String vmName, String vmName,
String osTypeId, String osTypeId,
String vmId, String vmId,
boolean forceOverwrite, boolean forceOverwrite,
String controllerIDE, String controllerIDE,
ComputeServiceContext context, ComputeServiceContext context,
String hostId, String hostId,
String guestId, String guestId,
Credentials credentials) { Credentials credentials) {
super(); super();
this.manager = manager; this.manager = manager;
this.adminDisk = adminDisk; this.adminDisk = adminDisk;
this.diskFormat = diskFormat; this.diskFormat = diskFormat;
this.settingsFile = settingsFile; this.settingsFile = settingsFile;
this.vmName = vmName; this.vmName = vmName;
this.osTypeId = osTypeId; this.osTypeId = osTypeId;
this.vmId = vmId; this.vmId = vmId;
this.controllerIDE = controllerIDE; this.controllerIDE = controllerIDE;
this.forceOverwrite = forceOverwrite; this.forceOverwrite = forceOverwrite;
this.context = context; this.context = context;
this.hostId = hostId; this.hostId = hostId;
this.guestId = guestId; this.guestId = guestId;
this.credentials = credentials; this.credentials = credentials;
} }
@Override @Override
public IMachine apply(@Nullable String isoName) { public IMachine apply(@Nullable String isoName) {
Server server = configureJettyServer(); String port = System.getProperty(VirtualBoxConstants.VIRTUALBOX_JETTY_PORT, "8080");
try { String basebaseResource = ".";
logger.debug("Starting Jetty server for serving of preseed.cfg..."); Server server = new StartJettyIfNotAlreadyRunning(port).apply(basebaseResource);
server.start();
logger.debug("Jetty server started."); IMachine vm = manager.getVBox().createMachine(settingsFile, vmName, osTypeId, vmId, forceOverwrite);
} catch (Exception e) { manager.getVBox().registerMachine(vm);
logger.error(e, "Could not start Jetty server");
throw new IllegalStateException(e);
}
IMachine vm = manager.getVBox().createMachine(settingsFile, vmName, osTypeId, vmId, forceOverwrite); String defaultWorkingDir = System.getProperty("user.home") + "/jclouds-virtualbox-test";
manager.getVBox().registerMachine(vm); String workingDir = System.getProperty(VIRTUALBOX_WORKINGDIR, defaultWorkingDir);
IMedium distroMedium = manager.getVBox().openMedium(workingDir + "/" + isoName, DVD, ReadOnly, forceOverwrite);
String defaultWorkingDir = System.getProperty("user.home") + "/jclouds-virtualbox-test"; // Change RAM
String workingDir = System.getProperty(VIRTUALBOX_WORKINGDIR, defaultWorkingDir); Long memorySize = new Long(1024);
IMedium distroMedium = manager.getVBox().openMedium(workingDir + "/" + isoName, DVD, ReadOnly, forceOverwrite); ISession session = manager.getSessionObject();
IMachine machine = manager.getVBox().findMachine(vmName);
machine.lockMachine(session, Write);
IMachine mutable = session.getMachine();
mutable.setMemorySize(memorySize);
mutable.saveSettings();
session.unlockMachine();
// Change RAM // IDE Controller
Long memorySize = new Long(1024); machine.lockMachine(session, Write);
ISession session = manager.getSessionObject(); mutable = session.getMachine();
IMachine machine = manager.getVBox().findMachine(vmName); mutable.addStorageController(controllerIDE, StorageBus.IDE);
machine.lockMachine(session, Write); mutable.saveSettings();
IMachine mutable = session.getMachine(); session.unlockMachine();
mutable.setMemorySize(memorySize);
mutable.saveSettings();
session.unlockMachine();
// IDE Controller // DISK
machine.lockMachine(session, Write); String adminDiskPath = workingDir + "/" + adminDisk;
mutable = session.getMachine(); if (new File(adminDiskPath).exists()) {
mutable.addStorageController(controllerIDE, StorageBus.IDE); new File(adminDiskPath).delete();
mutable.saveSettings(); }
session.unlockMachine(); IMedium hd = manager.getVBox().createHardDisk(diskFormat, adminDiskPath);
long size = 4L * 1024L * 1024L * 1024L - 4L;
IProgress storageCreation = hd.createBaseStorage(size, (long) MediumVariant.STANDARD.ordinal());
storageCreation.waitForCompletion(-1);
// DISK machine.lockMachine(session, Write);
String adminDiskPath = workingDir + "/" + adminDisk; mutable = session.getMachine();
if (new File(adminDiskPath).exists()) { mutable.attachDevice(controllerIDE, 0, 0, DeviceType.DVD, distroMedium);
new File(adminDiskPath).delete(); mutable.saveSettings();
} session.unlockMachine();
IMedium hd = manager.getVBox().createHardDisk(diskFormat, adminDiskPath);
long size = 4L * 1024L * 1024L * 1024L - 4L;
IProgress storageCreation = hd.createBaseStorage(size, (long) MediumVariant.STANDARD.ordinal());
storageCreation.waitForCompletion(-1);
machine.lockMachine(session, Write); // Create and attach hard disk
mutable = session.getMachine(); machine.lockMachine(session, Write);
mutable.attachDevice(controllerIDE, 0, 0, DeviceType.DVD, distroMedium); mutable = session.getMachine();
mutable.saveSettings(); mutable.attachDevice(controllerIDE, 0, 1, DeviceType.HardDisk, hd);
session.unlockMachine(); mutable.saveSettings();
session.unlockMachine();
// Create and attach hard disk // NIC
machine.lockMachine(session, Write); machine.lockMachine(session, Write);
mutable = session.getMachine(); mutable = session.getMachine();
mutable.attachDevice(controllerIDE, 0, 1, DeviceType.HardDisk, hd);
mutable.saveSettings();
session.unlockMachine();
// NIC // NAT
machine.lockMachine(session, Write); mutable.getNetworkAdapter(0l).setAttachmentType(NAT);
mutable = session.getMachine(); machine.getNetworkAdapter(0l)
.getNatDriver()
.addRedirect("guestssh", TCP, "127.0.0.1", 2222, "", 22);
mutable.getNetworkAdapter(0l).setEnabled(true);
mutable.saveSettings();
session.unlockMachine();
// NAT String guestAdditionsDvd = workingDir + "/VBoxGuestAdditions_4.1.2.iso";
mutable.getNetworkAdapter(0l).setAttachmentType(NAT); IMedium guestAdditionsDvdMedium = manager.getVBox().openMedium(guestAdditionsDvd, DeviceType.DVD, AccessMode.ReadOnly, forceOverwrite);
machine.getNetworkAdapter(0l) machine.lockMachine(session, Write);
.getNatDriver() mutable = session.getMachine();
.addRedirect("guestssh", TCP, "127.0.0.1", 2222, "", 22); mutable.attachDevice(controllerIDE, 1, 1, DeviceType.DVD, guestAdditionsDvdMedium);
mutable.getNetworkAdapter(0l).setEnabled(true); mutable.saveSettings();
mutable.saveSettings(); session.unlockMachine();
session.unlockMachine();
String guestAdditionsDvd = workingDir + "/VBoxGuestAdditions_4.1.2.iso"; IProgress prog = machine.launchVMProcess(session, "gui", "");
IMedium guestAdditionsDvdMedium = manager.getVBox().openMedium(guestAdditionsDvd, DeviceType.DVD, AccessMode.ReadOnly, forceOverwrite); prog.waitForCompletion(-1);
machine.lockMachine(session, Write); try {
mutable = session.getMachine(); Thread.sleep(5000);
mutable.attachDevice(controllerIDE, 1, 1, DeviceType.DVD, guestAdditionsDvdMedium); } catch (InterruptedException e) {
mutable.saveSettings(); propagate(e);
session.unlockMachine(); }
IProgress prog = machine.launchVMProcess(session, "gui", ""); String installKeySequence = System.getProperty(VIRTUALBOX_INSTALLATION_KEY_SEQUENCE, defaultInstallSequence());
prog.waitForCompletion(-1); sendKeyboardSequence(installKeySequence);
try { session.unlockMachine();
Thread.sleep(5000);
} catch (InterruptedException e) {
propagate(e);
}
String installKeySequence = System.getProperty(VIRTUALBOX_INSTALLATION_KEY_SEQUENCE, defaultInstallSequence()); boolean sshDeamonIsRunning = false;
sendKeyboardSequence(installKeySequence); while (!sshDeamonIsRunning) {
session.unlockMachine(); try {
if (runScriptOnNode(guestId, "id", wrapInInitScript(false)).getExitCode() == 0) {
logger.debug("Got response from ssh daemon.");
sshDeamonIsRunning = true;
}
} catch (SshException e) {
logger.debug("No response from ssh daemon...");
}
}
boolean sshDeamonIsRunning = false; logger.debug("Installation of image complete. Powering down...");
while (!sshDeamonIsRunning) {
try {
if (runScriptOnNode(guestId, "id", wrapInInitScript(false)).getExitCode() == 0) {
logger.debug("Got response from ssh daemon.");
sshDeamonIsRunning = true;
}
} catch (SshException e) {
logger.debug("No response from ssh daemon...");
}
}
logger.debug("Installation of image complete. Powering down..."); machine.lockMachine(session, LockType.Shared);
IProgress powerDownProgress = session.getConsole().powerDown();
powerDownProgress.waitForCompletion(-1);
session.unlockMachine();
machine.lockMachine(session, LockType.Shared); try {
IProgress powerDownProgress = session.getConsole().powerDown(); logger.debug("Stopping Jetty server...");
powerDownProgress.waitForCompletion(-1); server.stop();
session.unlockMachine(); logger.debug("Jetty server stopped.");
} catch (Exception e) {
logger.error(e, "Could not stop Jetty server.");
}
return vm;
}
try { private String defaultInstallSequence() {
logger.debug("Stopping Jetty server..."); return "<Esc><Esc><Enter> "
server.stop(); + "/install/vmlinuz noapic preseed/url=http://10.0.2.2:8080/src/test/resources/preseed.cfg "
logger.debug("Jetty server stopped."); + "debian-installer=en_US auto locale=en_US kbd-chooser/method=us "
} catch (Exception e) { + "hostname="
logger.error(e, "Could not stop Jetty server."); + vmName
} + " "
return vm; + "fb=false debconf/frontend=noninteractive "
} + "keyboard-configuration/layout=USA keyboard-configuration/variant=USA console-setup/ask_detect=false "
+ "initrd=/install/initrd.gz -- <Enter>";
}
private Server configureJettyServer() { private void sendKeyboardSequence(String keyboardSequence) {
Server server = new Server(8080); String[] sequenceSplited = keyboardSequence.split(" ");
StringBuilder sb = new StringBuilder();
for (String line : sequenceSplited) {
String converted = stringToKeycode(line);
for (String word : converted.split(" ")) {
sb.append("vboxmanage controlvm " + vmName
+ " keyboardputscancode " + word + "; ");
if (word.endsWith(KeyboardScancodes.SPECIAL_KEYBOARD_BUTTON_MAP.get("<Enter>"))) {
runScriptOnNode(hostId, sb.toString(), runAsRoot(false).wrapInInitScript(false));
sb.delete(0, sb.length() - 1);
}
if (word.endsWith(KeyboardScancodes.SPECIAL_KEYBOARD_BUTTON_MAP.get("<Return>"))) {
runScriptOnNode(hostId, sb.toString(), runAsRoot(false).wrapInInitScript(false));
sb.delete(0, sb.length() - 1);
}
ResourceHandler resource_handler = new ResourceHandler(); }
resource_handler.setDirectoriesListed(true); }
resource_handler.setWelcomeFiles(new String[]{"index.html"}); }
resource_handler.setResourceBase("."); private String stringToKeycode(String s) {
logger.info("serving " + resource_handler.getBaseResource()); StringBuilder keycodes = new StringBuilder();
if (s.startsWith("<")) {
String[] specials = s.split("<");
for (int i = 1; i < specials.length; i++) {
keycodes.append(KeyboardScancodes.SPECIAL_KEYBOARD_BUTTON_MAP
.get("<" + specials[i]) + " ");
}
return keycodes.toString();
}
HandlerList handlers = new HandlerList(); int i = 0;
handlers.setHandlers(new Handler[]{resource_handler, new DefaultHandler()}); while (i < s.length()) {
server.setHandler(handlers); String digit = s.substring(i, i + 1);
return server; String hex = KeyboardScancodes.NORMAL_KEYBOARD_BUTTON_MAP
} .get(digit);
keycodes.append(hex + " ");
if (i != 0 && i % 14 == 0)
keycodes.append(" ");
i++;
}
keycodes.append(KeyboardScancodes.SPECIAL_KEYBOARD_BUTTON_MAP
.get("<Spacebar>") + " ");
private String defaultInstallSequence() { return keycodes.toString();
return "<Esc><Esc><Enter> " }
+ "/install/vmlinuz noapic preseed/url=http://10.0.2.2:8080/src/test/resources/preseed.cfg "
+ "debian-installer=en_US auto locale=en_US kbd-chooser/method=us "
+ "hostname="
+ vmName
+ " "
+ "fb=false debconf/frontend=noninteractive "
+ "keyboard-configuration/layout=USA keyboard-configuration/variant=USA console-setup/ask_detect=false "
+ "initrd=/install/initrd.gz -- <Enter>";
}
private void sendKeyboardSequence(String keyboardSequence) { protected ExecResponse runScriptOnNode(String nodeId, String command, RunScriptOptions options) {
String[] sequenceSplited = keyboardSequence.split(" "); return context.getComputeService().runScriptOnNode(nodeId, command, options);
StringBuilder sb = new StringBuilder(); }
for (String line : sequenceSplited) {
String converted = stringToKeycode(line);
for (String word : converted.split(" ")) {
sb.append("vboxmanage controlvm " + vmName
+ " keyboardputscancode " + word + "; ");
if (word.endsWith(KeyboardScancodes.SPECIAL_KEYBOARD_BUTTON_MAP.get("<Enter>"))) {
runScriptOnNode(hostId, sb.toString(), runAsRoot(false).wrapInInitScript(false));
sb.delete(0, sb.length() - 1);
}
if (word.endsWith(KeyboardScancodes.SPECIAL_KEYBOARD_BUTTON_MAP.get("<Return>"))) {
runScriptOnNode(hostId, sb.toString(), runAsRoot(false).wrapInInitScript(false));
sb.delete(0, sb.length() - 1);
}
}
}
}
private String stringToKeycode(String s) {
StringBuilder keycodes = new StringBuilder();
if (s.startsWith("<")) {
String[] specials = s.split("<");
for (int i = 1; i < specials.length; i++) {
keycodes.append(KeyboardScancodes.SPECIAL_KEYBOARD_BUTTON_MAP
.get("<" + specials[i]) + " ");
}
return keycodes.toString();
}
int i = 0;
while (i < s.length()) {
String digit = s.substring(i, i + 1);
String hex = KeyboardScancodes.NORMAL_KEYBOARD_BUTTON_MAP
.get(digit);
keycodes.append(hex + " ");
if (i != 0 && i % 14 == 0)
keycodes.append(" ");
i++;
}
keycodes.append(KeyboardScancodes.SPECIAL_KEYBOARD_BUTTON_MAP
.get("<Spacebar>") + " ");
return keycodes.toString();
}
protected ExecResponse runScriptOnNode(String nodeId, String command, RunScriptOptions options) {
return context.getComputeService().runScriptOnNode(nodeId, command, options);
}
} }

View File

@ -0,0 +1,109 @@
/*
* *
* * Licensed to jclouds, Inc. (jclouds) under one or more
* * contributor license agreements. See the NOTICE file
* * distributed with this work for additional information
* * regarding copyright ownership. jclouds licenses this file
* * to you under the Apache License, Version 2.0 (the
* * "License"); you may not use this file except in compliance
* * with the License. You may obtain a copy of the License at
* *
* * http://www.apache.org/licenses/LICENSE-2.0
* *
* * Unless required by applicable law or agreed to in writing,
* * software distributed under the License is distributed on an
* * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* * KIND, either express or implied. See the License for the
* * specific language governing permissions and limitations
* * under the License.
*
*/
package org.jclouds.virtualbox.functions.admin;
import javax.annotation.Resource;
import javax.inject.Inject;
import javax.inject.Named;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.DefaultHandler;
import org.eclipse.jetty.server.handler.HandlerList;
import org.eclipse.jetty.server.handler.ResourceHandler;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.logging.Logger;
import org.jclouds.net.IPSocket;
import org.jclouds.predicates.InetSocketAddressConnect;
import org.jclouds.virtualbox.config.VirtualBoxConstants;
import com.google.common.base.Function;
import com.google.inject.Singleton;
/**
* @author Andrea Turli
*/
public class StartJettyIfNotAlreadyRunning implements Function<String, Server> {
@Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL;
private final int port;
@Inject
public StartJettyIfNotAlreadyRunning(
@Named(VirtualBoxConstants.VIRTUALBOX_JETTY_PORT) final String port) {
this.port = Integer.parseInt(port);
}
@Override
public Server apply(@Nullable String baseResource) {
final Server server = ServerJetty.getInstance().getServer();
if (!server.getState().equals(Server.STARTED) && !new InetSocketAddressConnect().apply(new IPSocket("localhost", port))) {
ResourceHandler resource_handler = new ResourceHandler();
resource_handler.setDirectoriesListed(true);
resource_handler.setWelcomeFiles(new String[] { "index.html" });
resource_handler.setResourceBase(baseResource);
logger.info("serving " + resource_handler.getBaseResource());
HandlerList handlers = new HandlerList();
handlers.setHandlers(new Handler[] { resource_handler, new DefaultHandler() });
server.setHandler(handlers);
try {
server.start();
} catch (Exception e) {
logger.error(e, "Server jetty could not be started at this %s", baseResource);
}
return server;
} else {
logger.debug("Server jetty serving %s already running. Skipping start", baseResource);
return server;
}
}
@Singleton
private static class ServerJetty {
private static ServerJetty instance;
private Server server;
private String port = System.getProperty(VirtualBoxConstants.VIRTUALBOX_JETTY_PORT, "8080");
private ServerJetty() {
this.server = new Server(Integer.parseInt(port));
}
public static ServerJetty getInstance() {
if (instance == null)
instance = new ServerJetty();
return instance;
}
public Server getServer() {
return server;
}
}
}

View File

@ -42,12 +42,16 @@ import org.eclipse.jetty.server.handler.ResourceHandler;
import org.jclouds.compute.ComputeServiceContext; import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.domain.ExecResponse; import org.jclouds.compute.domain.ExecResponse;
import org.jclouds.compute.options.RunScriptOptions; import org.jclouds.compute.options.RunScriptOptions;
import org.jclouds.domain.Credentials;
import org.jclouds.logging.Logger; import org.jclouds.logging.Logger;
import org.jclouds.net.IPSocket; import org.jclouds.net.IPSocket;
import org.jclouds.predicates.InetSocketAddressConnect; import org.jclouds.predicates.InetSocketAddressConnect;
import org.jclouds.virtualbox.config.VirtualBoxConstants;
import org.jclouds.virtualbox.functions.StartVBoxIfNotAlreadyRunning;
import org.jclouds.virtualbox.functions.admin.StartJettyIfNotAlreadyRunning;
import org.testng.annotations.AfterSuite; import org.testng.annotations.AfterSuite;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.BeforeSuite; import org.testng.annotations.BeforeSuite;
import org.testng.annotations.Test;
import com.google.common.base.Splitter; import com.google.common.base.Splitter;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
@ -74,6 +78,11 @@ public class SetupVirtualBoxForLiveTest {
private String majorVersion; private String majorVersion;
private URI vboxDmg; private URI vboxDmg;
private String vboxVersionName; private String vboxVersionName;
private String basebaseResource;
private String port;
private String vboxWebServerCredential;
private String vboxWebServerIdentity;
public void setupCredentials() { public void setupCredentials() {
endpoint = URI.create(System.getProperty("test." + provider + ".endpoint", "http://localhost:18083/")); endpoint = URI.create(System.getProperty("test." + provider + ".endpoint", "http://localhost:18083/"));
@ -100,28 +109,14 @@ public class SetupVirtualBoxForLiveTest {
vboxDmg = URI.create(System.getProperty("test." + provider + ".vboxDmg", vboxDmg = URI.create(System.getProperty("test." + provider + ".vboxDmg",
"http://download.virtualbox.org/virtualbox/4.1.2/VirtualBox-4.1.2-73507-OSX.dmg")); "http://download.virtualbox.org/virtualbox/4.1.2/VirtualBox-4.1.2-73507-OSX.dmg"));
vboxVersionName = System.getProperty("test" + provider + ".vboxVersionName", "VirtualBox-4.1.2-73507-OSX.dmg"); vboxVersionName = System.getProperty("test" + provider + ".vboxVersionName", "VirtualBox-4.1.2-73507-OSX.dmg");
} basebaseResource = System.getProperty(VirtualBoxConstants.VIRTUALBOX_JETTY_BASE_RESOURCE, ".");
port = System.getProperty(VirtualBoxConstants.VIRTUALBOX_JETTY_PORT, "8080");
public void configureJettyServer() throws Exception { vboxWebServerIdentity = System.getProperty(VirtualBoxConstants.VIRTUALBOX_WEBSERVER_IDENTITY, "toor");
Server server = new Server(8080); vboxWebServerCredential = System.getProperty(VirtualBoxConstants.VIRTUALBOX_WEBSERVER_CREDENTIAL, "12345");
ResourceHandler resource_handler = new ResourceHandler();
resource_handler.setDirectoriesListed(true);
resource_handler.setWelcomeFiles(new String[] { "index.html" });
resource_handler.setResourceBase(".");
logger().info("serving " + resource_handler.getBaseResource());
HandlerList handlers = new HandlerList();
handlers.setHandlers(new Handler[] { resource_handler, new DefaultHandler() });
server.setHandler(handlers);
server.start();
} }
@BeforeSuite @BeforeSuite
public void setupClient() throws Exception { public void setupClient() throws Exception {
logger().info("\n\n\n\nSetting up Virtualbox environment");
context = TestUtils.computeServiceForLocalhostAndGuest(); context = TestUtils.computeServiceForLocalhostAndGuest();
setupCredentials(); setupCredentials();
setupConfigurationProperties(); setupConfigurationProperties();
@ -130,9 +125,13 @@ public class SetupVirtualBoxForLiveTest {
installVbox(); installVbox();
checkVboxVersionExpected(); checkVboxVersionExpected();
if (!new InetSocketAddressConnect().apply(new IPSocket(endpoint.getHost(), endpoint.getPort()))) new StartVBoxIfNotAlreadyRunning(context, hostId, new Credentials(vboxWebServerIdentity, vboxWebServerCredential));
startupVboxWebServer(); new StartJettyIfNotAlreadyRunning(port).apply(basebaseResource);
configureJettyServer(); }
@AfterSuite
public void stopVboxWebServer() throws IOException {
runScriptOnNode(hostId, "pidof vboxwebsrv | xargs kill");
} }
public void installVbox() throws Exception { public void installVbox() throws Exception {
@ -159,25 +158,6 @@ public class SetupVirtualBoxForLiveTest {
assertEquals(runScriptOnNode(hostId, "VBoxManage -version").getOutput().trim(), apiVersion); assertEquals(runScriptOnNode(hostId, "VBoxManage -version").getOutput().trim(), apiVersion);
} }
/**
*
* @param command
* absolute path to command. For ubuntu 10.04: /usr/bin/vboxwebsrv
* @throws IOException
* @throws InterruptedException
*/
public void startupVboxWebServer() {
logger().debug("disabling password access");
runScriptOnNode(hostId, "VBoxManage setproperty websrvauthlibrary null", runAsRoot(false).wrapInInitScript(false));
logger().debug("starting vboxwebsrv");
String vboxwebsrv = "vboxwebsrv -t 10000 -v -b";
if (isOSX(hostId))
vboxwebsrv = "cd /Applications/VirtualBox.app/Contents/MacOS/ && " + vboxwebsrv;
runScriptOnNode(hostId, vboxwebsrv, runAsRoot(false).wrapInInitScript(false).blockOnPort(endpoint.getPort(), 10)
.blockOnComplete(false).nameTask("vboxwebsrv"));
}
public boolean isOSX(String id) { public boolean isOSX(String id) {
return context.getComputeService().getNodeMetadata(hostId).getOperatingSystem().getDescription().equals( return context.getComputeService().getNodeMetadata(hostId).getOperatingSystem().getDescription().equals(
"Mac OS X"); "Mac OS X");
@ -199,11 +179,6 @@ public class SetupVirtualBoxForLiveTest {
return iso; return iso;
} }
@AfterSuite
public void stopVboxWebServer() throws IOException {
runScriptOnNode(guestId, "pidof vboxwebsrv | xargs kill");
}
public ExecResponse runScriptOnNode(String nodeId, String command, RunScriptOptions options) { public ExecResponse runScriptOnNode(String nodeId, String command, RunScriptOptions options) {
ExecResponse toReturn = context.getComputeService().runScriptOnNode(nodeId, command, options); ExecResponse toReturn = context.getComputeService().runScriptOnNode(nodeId, command, options);
assert toReturn.getExitCode() == 0 : toReturn; assert toReturn.getExitCode() == 0 : toReturn;

View File

@ -1,432 +0,0 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.virtualbox.experiment;
import static com.google.common.base.Throwables.propagate;
import static org.jclouds.compute.options.RunScriptOptions.Builder.runAsRoot;
import static org.jclouds.compute.options.RunScriptOptions.Builder.wrapInInitScript;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.rmi.RemoteException;
import org.jclouds.compute.domain.ExecResponse;
import org.jclouds.compute.options.RunScriptOptions;
import org.jclouds.scriptbuilder.domain.OsFamily;
import org.jclouds.scriptbuilder.statements.login.AdminAccess;
import org.jclouds.scriptbuilder.statements.login.DefaultConfiguration;
import org.jclouds.ssh.SshException;
import org.jclouds.virtualbox.BaseVirtualBoxClientLiveTest;
import org.jclouds.virtualbox.settings.KeyboardScancodes;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import org.virtualbox_4_1.AccessMode;
import org.virtualbox_4_1.DeviceType;
import org.virtualbox_4_1.IMachine;
import org.virtualbox_4_1.IMedium;
import org.virtualbox_4_1.IProgress;
import org.virtualbox_4_1.ISession;
import org.virtualbox_4_1.LockType;
import org.virtualbox_4_1.MachineState;
import org.virtualbox_4_1.NATProtocol;
import org.virtualbox_4_1.NetworkAdapterType;
import org.virtualbox_4_1.NetworkAttachmentType;
import org.virtualbox_4_1.SessionState;
import org.virtualbox_4_1.StorageBus;
import org.virtualbox_4_1.VirtualBoxManager;
import org.virtualbox_4_1.jaxws.MediumVariant;
import com.google.common.base.Splitter;
import com.google.common.collect.Iterables;
@Test(groups = "live", testName = "virtualbox.VirtualboxAdministrationKickstartTest")
public class VirtualboxAdministrationKickstartLiveTest extends BaseVirtualBoxClientLiveTest {
private String hostId = "host"; // TODO: shared between classes; move to iTestContext
private String guestId = "guest"; // TODO: ^^
private String distroIsoName; // TODO: ^^
private String workingDir;// TODO: ^^
private String settingsFile; // Fully qualified path where the settings
private String keyboardSequence;
private String vmId; // Machine UUID
private String vmName;
private String controllerIDE;
private String osTypeId; // Guest OS Type ID.
private boolean forceOverwrite;
private String diskFormat;
private String adminDisk;
private String guestAdditionsDvd;
private String snapshotDescription;
private VirtualBoxManager manager = VirtualBoxManager.createInstance("");
protected boolean isUbuntu(String id) {
return context.getComputeService().getNodeMetadata(id).getOperatingSystem().getDescription().contains("ubuntu");
}
@BeforeMethod
protected void setupManager() {
manager.connect(endpoint, identity, credential);
}
@BeforeClass
void setupConfigurationProperties() {
controllerIDE = System.getProperty("test." + provider + ".controllerIde", "IDE Controller");
diskFormat = System.getProperty("test." + provider + ".diskformat", "");
// VBOX
settingsFile = null;
osTypeId = System.getProperty("test." + provider + ".osTypeId", "");
vmId = System.getProperty("test." + provider + ".vmId", null);
forceOverwrite = true;
vmName = System.getProperty("test." + provider + ".vmname", "jclouds-virtualbox-kickstart-admin");
workingDir = System.getProperty("user.home") + File.separator
+ System.getProperty("test." + provider + ".workingDir", "jclouds-virtualbox-test");
if (new File(workingDir).mkdir())
;
distroIsoName = System.getProperty("test." + provider + ".distroIsoName", "ubuntu-11.04-server-i386.iso");
adminDisk = workingDir + File.separator + System.getProperty("test." + provider + ".adminDisk", "admin.vdi");
String majorVersion = Iterables.get(Splitter.on('r').split(apiversion), 0);
guestAdditionsDvd = workingDir
+ File.separator
+ System.getProperty("test." + provider + ".guestAdditionsDvd", "VBoxGuestAdditions_" + majorVersion
+ ".iso");
snapshotDescription = System
.getProperty("test." + provider + "snapshotdescription", "jclouds-virtualbox-snaphot");
keyboardSequence = System.getProperty("test." + provider + ".keyboardSequence", "<Esc><Esc><Enter> "
+ "/install/vmlinuz noapic preseed/url=http://10.0.2.2:8080/src/test/resources/preseed.cfg "
+ "debian-installer=en_US auto locale=en_US kbd-chooser/method=us " + "hostname=" + vmName + " "
+ "fb=false debconf/frontend=noninteractive "
+ "keyboard-configuration/layout=USA keyboard-configuration/variant=USA console-setup/ask_detect=false "
+ "initrd=/install/initrd.gz -- <Enter>");
}
public void sendKeyboardSequence(String keyboardSequence) throws InterruptedException {
String[] sequenceSplited = keyboardSequence.split(" ");
StringBuilder sb = new StringBuilder();
for (String line : sequenceSplited) {
String converted = stringToKeycode(line);
for (String word : converted.split(" ")) {
sb.append("vboxmanage controlvm " + vmName + " keyboardputscancode " + word + "; ");
if (word.endsWith(KeyboardScancodes.SPECIAL_KEYBOARD_BUTTON_MAP.get("<Enter>"))) {
runScriptOnNode(hostId, sb.toString(), runAsRoot(false).wrapInInitScript(false));
sb.delete(0, sb.length() - 1);
}
if (word.endsWith(KeyboardScancodes.SPECIAL_KEYBOARD_BUTTON_MAP.get("<Return>"))) {
runScriptOnNode(hostId, sb.toString(), runAsRoot(false).wrapInInitScript(false));
sb.delete(0, sb.length() - 1);
}
}
}
}
public ExecResponse runScriptOnNode(String nodeId, String command, RunScriptOptions options) {
ExecResponse toReturn = context.getComputeService().runScriptOnNode(nodeId, command, options);
assert toReturn.getExitCode() == 0 : toReturn;
return toReturn;
}
public ExecResponse runScriptOnNode(String nodeId, String command) {
return runScriptOnNode(nodeId, command, wrapInInitScript(false));
}
public String stringToKeycode(String s) {
StringBuilder keycodes = new StringBuilder();
if (s.startsWith("<")) {
String[] specials = s.split("<");
for (int i = 1; i < specials.length; i++) {
keycodes.append(KeyboardScancodes.SPECIAL_KEYBOARD_BUTTON_MAP.get("<" + specials[i]) + " ");
}
return keycodes.toString();
}
int i = 0;
while (i < s.length()) {
String digit = s.substring(i, i + 1);
String hex = KeyboardScancodes.NORMAL_KEYBOARD_BUTTON_MAP.get(digit);
keycodes.append(hex + " ");
if (i != 0 && i % 14 == 0)
keycodes.append(" ");
i++;
}
keycodes.append(KeyboardScancodes.SPECIAL_KEYBOARD_BUTTON_MAP.get("<Spacebar>") + " ");
return keycodes.toString();
}
@AfterMethod
protected void disconnectAndClenaupManager() throws RemoteException, MalformedURLException {
manager.disconnect();
manager.cleanup();
}
@Test
public void testCreateVirtualMachine() {
IMachine newVM = manager.getVBox().createMachine(settingsFile, vmName, osTypeId, vmId, forceOverwrite);
manager.getVBox().registerMachine(newVM);
assertNotNull(newVM.getName());
}
@Test(dependsOnMethods = "testCreateVirtualMachine")
public void testChangeRAM() {
Long memorySize = new Long(1024);
ISession session = manager.getSessionObject();
IMachine machine = manager.getVBox().findMachine(vmName);
machine.lockMachine(session, LockType.Write);
IMachine mutable = session.getMachine();
mutable.setMemorySize(memorySize);
mutable.saveSettings();
session.unlockMachine();
assertEquals(manager.getVBox().findMachine(vmName).getMemorySize(), memorySize);
}
@Test(dependsOnMethods = "testChangeRAM")
public void testCreateIdeController() {
ISession session = manager.getSessionObject();
IMachine machine = manager.getVBox().findMachine(vmName);
machine.lockMachine(session, LockType.Write);
IMachine mutable = session.getMachine();
mutable.addStorageController(controllerIDE, StorageBus.IDE);
mutable.saveSettings();
session.unlockMachine();
assertEquals(manager.getVBox().findMachine(vmName).getStorageControllers().size(), 1);
}
@Test(dependsOnMethods = "testCreateIdeController")
public void testAttachIsoDvd() {
IMedium distroMedium = manager.getVBox().openMedium(workingDir + "/" + distroIsoName, DeviceType.DVD,
AccessMode.ReadOnly, forceOverwrite);
ISession session = manager.getSessionObject();
IMachine machine = manager.getVBox().findMachine(vmName);
machine.lockMachine(session, LockType.Write);
IMachine mutable = session.getMachine();
mutable.attachDevice(controllerIDE, 0, 0, DeviceType.DVD, distroMedium);
mutable.saveSettings();
session.unlockMachine();
assertEquals(distroMedium.getId().equals(""), false);
}
@Test(dependsOnMethods = "testAttachIsoDvd")
public void testCreateAndAttachHardDisk() throws InterruptedException {
IMedium hd = null;
if (new File(adminDisk).exists()) {
new File(adminDisk).delete();
}
hd = manager.getVBox().createHardDisk(diskFormat, adminDisk);
long size = 4L * 1024L * 1024L * 1024L - 4L;
IProgress progress = hd.createBaseStorage(new Long(size), new Long(MediumVariant.STANDARD.ordinal()));
// TODO: poll?
ISession session = manager.getSessionObject();
IMachine machine = manager.getVBox().findMachine(vmName);
machine.lockMachine(session, LockType.Write);
IMachine mutable = session.getMachine();
mutable.attachDevice(controllerIDE, 0, 1, DeviceType.HardDisk, hd);
mutable.saveSettings();
session.unlockMachine();
assertEquals(hd.getId().equals(""), false);
}
@Test(dependsOnMethods = "testCreateAndAttachHardDisk")
public void testConfigureNIC() {
ISession session = manager.getSessionObject();
IMachine machine = manager.getVBox().findMachine(vmName);
machine.lockMachine(session, LockType.Write);
IMachine mutable = session.getMachine();
// NAT
mutable.getNetworkAdapter(new Long(0)).setAttachmentType(NetworkAttachmentType.NAT);
machine.getNetworkAdapter(new Long(0)).getNatDriver().addRedirect("guestssh", NATProtocol.TCP, "127.0.0.1", 2222,
"", 22);
mutable.getNetworkAdapter(new Long(0)).setEnabled(true);
mutable.saveSettings();
session.unlockMachine();
}
@Test(dependsOnMethods = "testConfigureNIC")
public void testAttachGuestAdditions() {
ISession session = manager.getSessionObject();
IMachine machine = manager.getVBox().findMachine(vmName);
IMedium distroMedium = manager.getVBox().openMedium(guestAdditionsDvd, DeviceType.DVD, AccessMode.ReadOnly,
forceOverwrite);
machine.lockMachine(session, LockType.Write);
IMachine mutable = session.getMachine();
mutable.attachDevice(controllerIDE, 1, 1, DeviceType.DVD, distroMedium);
mutable.saveSettings(); // write settings to xml
session.unlockMachine();
assertEquals(distroMedium.getId().equals(""), false);
}
@Test(dependsOnMethods = "testAttachGuestAdditions")
public void testStartVirtualMachine() throws InterruptedException {
IMachine machine = manager.getVBox().findMachine(vmName);
ISession session = manager.getSessionObject();
launchVMProcess(machine, session);
assertEquals(machine.getState(), MachineState.Running);
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
propagate(e);
}
sendKeyboardSequence(keyboardSequence);
// test if the sshd on the guest is ready and meanwhile apply AdminAccess
boolean sshDeamonIsRunning = false;
while (!sshDeamonIsRunning) {
try {
AdminAccess.standard().init(new DefaultConfiguration()).render(OsFamily.UNIX);
if (runScriptOnNode(guestId, "id").getExitCode() == 0)
sshDeamonIsRunning = true;
} catch (SshException e) {
System.err.println("connection reset");
}
}
}
@Test(dependsOnMethods = "testStartVirtualMachine")
public void testConfigureGuestAdditions() {
// TODO generalize
if (isUbuntu(guestId)) {
/*
* runScriptOnNode(guestId, "m-a prepare -i"); runScriptOnNode(guestId,
* "mount -o loop /dev/dvd /media/cdrom"); runScriptOnNode(guestId,
* "sh /media/cdrom/VBoxLinuxAdditions.run");
*
* runScriptOnNode(guestId, "/etc/init.d/vboxadd setup");
*/
runScriptOnNode(guestId, "rm /etc/udev/rules.d/70-persistent-net.rules");
runScriptOnNode(guestId, "mkdir /etc/udev/rules.d/70-persistent-net.rules");
runScriptOnNode(guestId, "rm -rf /dev/.udev/");
runScriptOnNode(guestId, "rm /lib/udev/rules.d/75-persistent-net-generator.rules");
}
}
@Test(dependsOnMethods = "testConfigureGuestAdditions")
public void testStopVirtualMachine() {
IMachine machine = manager.getVBox().findMachine(vmName);
powerDownMachine(machine);
assertEquals(machine.getState(), MachineState.PoweredOff);
}
@Test(dependsOnMethods = "testStopVirtualMachine")
public void testChangeNICtoBridged() {
ISession session = manager.getSessionObject();
IMachine adminNode = manager.getVBox().findMachine(vmName);
adminNode.lockMachine(session, LockType.Write);
IMachine mutable = session.getMachine();
// network
String hostInterface = null;
String command = "vboxmanage list bridgedifs";
try {
Process child = Runtime.getRuntime().exec(command);
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(child.getInputStream()));
String line = "";
boolean found = false;
while ((line = bufferedReader.readLine()) != null && !found) {
if (line.split(":")[0].contains("Name")) {
hostInterface = line.split(":")[1];
}
if (line.split(":")[0].contains("Status") && line.split(":")[1].contains("Up")) {
System.out.println("bridge: " + hostInterface.trim());
found = true;
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mutable.getNetworkAdapter(new Long(0)).setAttachmentType(NetworkAttachmentType.Bridged);
mutable.getNetworkAdapter(new Long(0)).setAdapterType(NetworkAdapterType.Am79C973);
mutable.getNetworkAdapter(new Long(0)).setMACAddress(manager.getVBox().getHost().generateMACAddress());
mutable.getNetworkAdapter(new Long(0)).setBridgedInterface(hostInterface.trim());
mutable.getNetworkAdapter(new Long(0)).setEnabled(true);
mutable.saveSettings();
session.unlockMachine();
}
@Test(dependsOnMethods = "testChangeNICtoBridged")
public void testTakeAdminNodeSnapshot() {
ISession session = manager.getSessionObject();
IMachine adminNode = manager.getVBox().findMachine(vmName);
adminNode.lockMachine(session, LockType.Write);
if (adminNode.getCurrentSnapshot() == null
|| !adminNode.getCurrentSnapshot().getDescription().equals(snapshotDescription)) {
manager.getSessionObject().getConsole().takeSnapshot(adminNode.getId(), snapshotDescription);
}
session.unlockMachine();
}
/**
*
* @param machine
* @param session
*/
public void launchVMProcess(IMachine machine, ISession session) {
IProgress prog = machine.launchVMProcess(session, "gui", "");
prog.waitForCompletion(-1);
session.unlockMachine();
}
/**
* @param machine
*/
public void powerDownMachine(IMachine machine) {
try {
ISession machineSession = manager.openMachineSession(machine);
IProgress progress = machineSession.getConsole().powerDown();
progress.waitForCompletion(-1);
machineSession.unlockMachine();
while (!machine.getSessionState().equals(SessionState.Unlocked)) {
try {
System.out.println("waiting for unlocking session - session state: " + machine.getSessionState());
Thread.sleep(1000);
} catch (InterruptedException e) {
}
}
} catch (Exception e) {
e.printStackTrace();
e.printStackTrace();
}
}
}

View File

@ -1,288 +0,0 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.virtualbox.experiment;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.compute.options.RunScriptOptions.Builder.runAsRoot;
import static org.testng.Assert.assertEquals;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URI;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.List;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.domain.ExecResponse;
import org.jclouds.compute.options.RunScriptOptions;
import org.jclouds.logging.Logger;
import org.jclouds.net.IPSocket;
import org.jclouds.predicates.InetSocketAddressConnect;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import org.virtualbox_4_1.CloneMode;
import org.virtualbox_4_1.CloneOptions;
import org.virtualbox_4_1.IMachine;
import org.virtualbox_4_1.IProgress;
import org.virtualbox_4_1.ISession;
import org.virtualbox_4_1.LockType;
import org.virtualbox_4_1.MachineState;
import org.virtualbox_4_1.NetworkAttachmentType;
import org.virtualbox_4_1.SessionState;
import org.virtualbox_4_1.VirtualBoxManager;
@Test(groups = "live", testName = "virtualbox.VirtualboxLiveTest")
public class VirtualboxLiveTest {
private String provider = "virtualbox";
private String identity;
private String credential;
private URI endpoint;
private String vmName;
private VirtualBoxManager manager = VirtualBoxManager.createInstance("");
private String settingsFile;
private String osTypeId;
private String vmId;
private boolean forceOverwrite;
private int numberOfVirtualMachine;
private ComputeServiceContext context;
private String hostId = "host";
private String adminNodeName;
private Logger logger() {
return context.utils().loggerFactory().getLogger("jclouds.compute");
}
private void setupCredentials() {
identity = System.getProperty("test." + provider + ".identity", "administrator");
credential = System.getProperty("test." + provider + ".credential", "12345");
endpoint = URI.create(System.getProperty("test." + provider + ".endpoint", "http://localhost:18083/"));
}
private void setupConfigurationProperties() {
// VBOX
settingsFile = null;
osTypeId = System.getProperty("test." + provider + ".osTypeId", "");
vmId = System.getProperty("test." + provider + ".vmId", null);
forceOverwrite = true;
// OS specific information
adminNodeName = System.getProperty("test." + provider + ".adminnodename", "jclouds-virtualbox-kickstart-admin");
vmName = checkNotNull(System.getProperty("test." + provider + ".vmname", "jclouds-virtualbox-node"));
numberOfVirtualMachine = Integer.parseInt(checkNotNull(System.getProperty("test." + provider
+ ".numberOfVirtualMachine", "1")));
}
@BeforeGroups(groups = "live")
public void setupClient() throws Exception {
context = TestUtils.computeServiceForLocalhostAndGuest();
setupCredentials();
setupConfigurationProperties();
if (!new InetSocketAddressConnect().apply(new IPSocket(endpoint.getHost(), endpoint.getPort())))
startupVboxWebServer();
}
@BeforeMethod
public void setupManager() throws RemoteException, MalformedURLException {
manager.connect(endpoint.toASCIIString(), identity, credential);
}
@AfterMethod
public void disconnectAndClenaupManager() throws RemoteException, MalformedURLException {
manager.disconnect();
manager.cleanup();
}
@Test
public void testStartAndValidateVirtualMachines() throws InterruptedException {
for (int i = 1; i < numberOfVirtualMachine + 1; i++) {
createVirtualMachine(i);
}
}
private void createVirtualMachine(int i) throws InterruptedException {
String instanceName = vmName + "_" + i;
IMachine adminNode = manager.getVBox().findMachine(adminNodeName);
IMachine clonedVM = manager.getVBox().createMachine(settingsFile, instanceName, osTypeId, vmId, forceOverwrite);
List<CloneOptions> options = new ArrayList<CloneOptions>();
options.add(CloneOptions.Link);
IProgress progress = adminNode.getCurrentSnapshot().getMachine().cloneTo(clonedVM, CloneMode.MachineState,
options);
if (progress.getCompleted())
logger().debug("clone done");
manager.getVBox().registerMachine(clonedVM);
ISession session = manager.getSessionObject();
clonedVM.lockMachine(session, LockType.Write);
IMachine mutable = session.getMachine();
mutable.getNetworkAdapter(new Long(0)).setAttachmentType(NetworkAttachmentType.Bridged);
String mac_address = manager.getVBox().getHost().generateMACAddress();
System.out.println("mac_address " + mac_address);
mutable.getNetworkAdapter(new Long(0)).setMACAddress(mac_address);
if (isOSX(hostId)) {
mutable.getNetworkAdapter(new Long(0)).setBridgedInterface(findBridgeInUse());
} else {
mutable.getNetworkAdapter(new Long(0)).setBridgedInterface("virbr0");
}
mutable.getNetworkAdapter(new Long(0)).setEnabled(true);
mutable.saveSettings();
session.unlockMachine();
System.out.println("\nLaunching VM named " + clonedVM.getName() + " ...");
launchVMProcess(clonedVM, manager.getSessionObject());
clonedVM = manager.getVBox().findMachine(instanceName);
String macAddressOfClonedVM = clonedVM.getNetworkAdapter(new Long(0)).getMACAddress();
int offset = 0, step = 2;
for (int j = 1; j <= 5; j++) {
macAddressOfClonedVM = new StringBuffer(macAddressOfClonedVM).insert(j * step + offset, ":").toString()
.toLowerCase();
offset++;
}
String simplifiedMacAddressOfClonedVM = macAddressOfClonedVM;
if (isOSX(hostId)) {
if (simplifiedMacAddressOfClonedVM.contains("00"))
simplifiedMacAddressOfClonedVM = new StringBuffer(simplifiedMacAddressOfClonedVM).delete(
simplifiedMacAddressOfClonedVM.indexOf("00"), simplifiedMacAddressOfClonedVM.indexOf("00") + 1)
.toString();
if (simplifiedMacAddressOfClonedVM.contains("0"))
if (simplifiedMacAddressOfClonedVM.indexOf("0") + 1 != ':'
&& simplifiedMacAddressOfClonedVM.indexOf("0") - 1 != ':')
simplifiedMacAddressOfClonedVM = new StringBuffer(simplifiedMacAddressOfClonedVM).delete(
simplifiedMacAddressOfClonedVM.indexOf("0"), simplifiedMacAddressOfClonedVM.indexOf("0") + 1)
.toString();
}
// TODO as we don't know the hostname (nor the IP address) of the cloned machine we can't use
// "ssh check" to check that the machine is up and running
// we need to find another way to check the machine is up: only at that stage a new IP would
// be used by the machine and arp will answer correctly
Thread.sleep(35000); // TODO to be removed asap
runScriptOnNode(hostId, "for i in $(seq 1 254) ; do ping -c 1 -t 1 192.168.122.$i & done", runAsRoot(false)
.wrapInInitScript(false));
String arpLine = runScriptOnNode(hostId, "arp -an | grep " + simplifiedMacAddressOfClonedVM,
runAsRoot(false).wrapInInitScript(false)).getOutput();
String ipAddress = arpLine.substring(arpLine.indexOf("(") + 1, arpLine.indexOf(")"));
System.out.println("IP address " + ipAddress);
// TODO we need to redifine guest node at runtinme: in particular hostnmane and ssh port
// runScriptOnNode(guestId, "echo ciao");
}
/**
*
*/
private String findBridgeInUse() {
// network
String hostInterface = null;
String command = "vboxmanage list bridgedifs";
try {
Process child = Runtime.getRuntime().exec(command);
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(child.getInputStream()));
String line = "";
boolean found = false;
while ((line = bufferedReader.readLine()) != null && !found) {
System.out.println("- " + line);
if (line.split(":")[0].contains("Name")) {
hostInterface = line.substring(line.indexOf(":") + 1);
}
if (line.split(":")[0].contains("Status") && line.split(":")[1].contains("Up")) {
found = true;
}
}
} catch (IOException e) {
e.printStackTrace();
}
return hostInterface.trim();
}
private void launchVMProcess(IMachine machine, ISession session) {
IProgress prog = machine.launchVMProcess(session, "gui", "");
prog.waitForCompletion(-1);
session.unlockMachine();
}
@Test(dependsOnMethods = "testStartAndValidateVirtualMachines")
public void testStopVirtualMachines() {
for (int i = 1; i < numberOfVirtualMachine + 1; i++) {
String instanceName = vmName + "_" + i;
IMachine machine = manager.getVBox().findMachine(instanceName);
try {
ISession machineSession = manager.openMachineSession(machine);
IProgress progress = machineSession.getConsole().powerDown();
progress.waitForCompletion(-1);
machineSession.unlockMachine();
while (!machine.getSessionState().equals(SessionState.Unlocked)) {
try {
System.out.println("waiting for unlocking session - session state: " + machine.getSessionState());
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
assertEquals(machine.getState(), MachineState.PoweredOff);
} catch (Exception e) {
e.printStackTrace();
}
}
}
private ExecResponse runScriptOnNode(String nodeId, String command, RunScriptOptions options) {
ExecResponse toReturn = context.getComputeService().runScriptOnNode(nodeId, command, options);
assert toReturn.getExitCode() == 0 : toReturn;
return toReturn;
}
private boolean isOSX(String id) {
return context.getComputeService().getNodeMetadata(hostId).getOperatingSystem().getDescription().equals(
"Mac OS X");
}
private void startupVboxWebServer() {
logger().debug("disabling password access");
runScriptOnNode(hostId, "VBoxManage setproperty websrvauthlibrary null", runAsRoot(false).wrapInInitScript(false));
logger().debug("starting vboxwebsrv");
String vboxwebsrv = "vboxwebsrv -t 10000 -v -b";
if (isOSX(hostId))
vboxwebsrv = "cd /Applications/VirtualBox.app/Contents/MacOS/ && " + vboxwebsrv;
runScriptOnNode(hostId, vboxwebsrv, runAsRoot(false).wrapInInitScript(false).blockOnPort(endpoint.getPort(), 10)
.blockOnComplete(false).nameTask("vboxwebsrv"));
}
}

View File

@ -30,6 +30,8 @@ import static com.google.common.collect.Iterables.any;
import static org.jclouds.virtualbox.experiment.TestUtils.computeServiceForLocalhostAndGuest; import static org.jclouds.virtualbox.experiment.TestUtils.computeServiceForLocalhostAndGuest;
import static org.testng.Assert.assertTrue; import static org.testng.Assert.assertTrue;
import java.io.IOException;
import java.net.URI;
import java.util.Set; import java.util.Set;
import org.jclouds.compute.ComputeServiceContext; import org.jclouds.compute.ComputeServiceContext;
@ -66,7 +68,7 @@ public class IsoToIMachineLiveTest extends BaseVirtualBoxClientLiveTest {
public void testCreateImageMachineFromIso() throws Exception { public void testCreateImageMachineFromIso() throws Exception {
VirtualBoxManager manager = (VirtualBoxManager) context.getProviderSpecificContext().getApi(); VirtualBoxManager manager = (VirtualBoxManager) context.getProviderSpecificContext().getApi();
ComputeServiceContext localHostContext = computeServiceForLocalhostAndGuest(hostId, "localhost", guestId, "localhost", new Credentials("toor", "password")); ComputeServiceContext localHostContext = computeServiceForLocalhostAndGuest(hostId, "localhost", guestId, "localhost", new Credentials("toor", "password"));
IMachine imageMachine = new IsoToIMachine(manager, IMachine imageMachine = new IsoToIMachine(manager,
adminDisk, adminDisk,
diskFormat, diskFormat,

View File

@ -0,0 +1,63 @@
images:
- name: ubuntu-11.04-server-i386
description: ubuntu 11.04 server (i386)
iso: http://releases.ubuntu.com/11.04/ubuntu-11.04-server-i386.iso
keystroke_sequence: |
<Esc><Esc><Enter>
/install/vmlinuz noapic preseed/url=http://10.0.2.2:8080/src/test/resources/preseed.cfg
debian-installer=en_US auto locale=en_US kbd-chooser/method=us
hostname=vmName
fb=false debconf/frontend=noninteractive
keyboard-configuration/layout=USA keyboard-configuration/variant=USA console-setup/ask_detect=false
initrd=/install/initrd.gz -- <Enter>
preseed_cfg: |
## Options to set on the command line
d-i debian-installer/locale string en_US.utf8
d-i console-setup/ask_detect boolean false
d-i console-setup/layout string USA
d-i netcfg/get_hostname string unassigned-hostname
d-i netcfg/get_domain string unassigned-domain
# Continue without a default route
# Not working , specify a dummy in the DHCP
d-i time/zone string UTC
d-i clock-setup/utc-auto boolean true
d-i clock-setup/utc boolean true
d-i kbd-chooser/method select American English
d-i netcfg/wireless_wep string
d-i base-installer/kernel/override-image string linux-server
# Choices: Dialog, Readline, Gnome, Kde, Editor, Noninteractive
d-i debconf debconf/frontend select Noninteractive
d-i pkgsel/install-language-support boolean false
tasksel tasksel/first multiselect standard, ubuntu-server
d-i partman-auto/method string lvm
d-i partman-lvm/confirm boolean true
d-i partman-lvm/device_remove_lvm boolean true
d-i partman-auto/choose_recipe select atomic
d-i partman/confirm_write_new_label boolean true
d-i partman/confirm_nooverwrite boolean true
d-i partman/choose_partition select finish
d-i partman/confirm boolean true
# Write the changes to disks and configure LVM?
d-i partman-lvm/confirm boolean true
d-i partman-lvm/confirm_nooverwrite boolean true
d-i partman-auto-lvm/guided_size string max
## Default user, we can get away with a recipe to change this
d-i passwd/user-fullname string toor
d-i passwd/username string toor
d-i passwd/user-password password password
d-i passwd/user-password-again password password
d-i user-setup/encrypt-home boolean false
d-i user-setup/allow-password-weak boolean true
# Individual additional packages to install
d-i pkgsel/include string openssh-server ntp
# Whether to upgrade packages after debootstrap.
# Allowed values: none, safe-upgrade, full-upgrade
d-i pkgsel/upgrade select full-upgrade
d-i grub-installer/only_debian boolean true
d-i grub-installer/with_other_os boolean true
d-i finish-install/reboot_in_progress note
#For the update
d-i pkgsel/update-policy select none
# debconf-get-selections --install
#Use mirror
choose-mirror-bin mirror/http/proxy string