Merge pull request #537 from dralves/vbox-linux

oneiric update and a few other goodies
This commit is contained in:
Adrian Cole 2012-04-02 07:28:28 -07:00
commit 8cf71adedf
22 changed files with 554 additions and 424 deletions

View File

@ -3,7 +3,7 @@
Have virtualbox 4.1.8 installed.
Make sure you change your VirtualBox preferences to not auto-capture keyboard, and also set host key to none. Otherwise you may accidentally screw-up automated installs.
Have an ssh daemon with passwordless login to localhost (i.e. "ssh [me]@localhost" must work without password).
That's it!

View File

@ -19,7 +19,9 @@
package org.jclouds.virtualbox.config;
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_PRECONFIGURATION_URL;
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_DEFAULT_IMAGE_ARCH;
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_DEFAULT_IMAGE_OS;
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_DEFAULT_IMAGE_VERSION;
import java.io.File;
import java.io.InputStream;
@ -29,7 +31,6 @@ import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import javax.inject.Named;
import javax.inject.Singleton;
import org.eclipse.jetty.server.Server;
@ -46,7 +47,6 @@ import org.jclouds.compute.domain.HardwareBuilder;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.NodeState;
import org.jclouds.compute.domain.OsFamily;
import org.jclouds.compute.domain.TemplateBuilder;
import org.jclouds.compute.reference.ComputeServiceConstants.Timeouts;
import org.jclouds.domain.Location;
@ -56,7 +56,6 @@ import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.ssh.SshClient;
import org.jclouds.sshj.config.SshjSshClientModule;
import org.jclouds.virtualbox.Host;
import org.jclouds.virtualbox.Preconfiguration;
import org.jclouds.virtualbox.compute.VirtualBoxComputeServiceAdapter;
import org.jclouds.virtualbox.domain.CloneSpec;
import org.jclouds.virtualbox.domain.ExecutionType;
@ -76,7 +75,7 @@ import org.jclouds.virtualbox.functions.NodeCreator;
import org.jclouds.virtualbox.functions.YamlImagesFromFileConfig;
import org.jclouds.virtualbox.functions.admin.FileDownloadFromURI;
import org.jclouds.virtualbox.functions.admin.ImagesToYamlImagesFromYamlDescriptor;
import org.jclouds.virtualbox.functions.admin.StartJettyIfNotAlreadyRunning;
import org.jclouds.virtualbox.functions.admin.PreseedCfgServer;
import org.jclouds.virtualbox.functions.admin.StartVBoxIfNotAlreadyRunning;
import org.jclouds.virtualbox.predicates.SshResponds;
import org.testng.internal.annotations.Sets;
@ -91,7 +90,6 @@ import com.google.common.base.Functions;
import com.google.common.base.Predicate;
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableMap;
@ -128,10 +126,10 @@ public class VirtualBoxComputeServiceContextModule extends
bind(new TypeLiteral<Function<IMachine, Image>>() {
}).to(IMachineToImage.class);
bind(new TypeLiteral<CacheLoader<IsoSpec, URI>>() {
}).to((Class) StartJettyIfNotAlreadyRunning.class);
}).to((Class) PreseedCfgServer.class);
bind(new TypeLiteral<Function<URI, File>>() {
}).to((Class) FileDownloadFromURI.class);
bind(new TypeLiteral<Supplier<VirtualBoxManager>>() {
}).to((Class) StartVBoxIfNotAlreadyRunning.class);
// the yaml config to image mapper
@ -139,9 +137,11 @@ public class VirtualBoxComputeServiceContextModule extends
}).to((Class) ImagesToYamlImagesFromYamlDescriptor.class);
// the yaml config provider
bind(YamlImagesFromFileConfig.class);
// the master machines cache
bind(new TypeLiteral<LoadingCache<Image, Master>>() {
}).to((Class) MastersLoadingCache.class);
}).to(MastersLoadingCache.class);
// the master creating function
bind(new TypeLiteral<Function<MasterSpec, IMachine>>() {
}).to((Class) CreateAndInstallVm.class);
@ -150,6 +150,9 @@ public class VirtualBoxComputeServiceContextModule extends
}).to((Class) NodeCreator.class);
bind(new TypeLiteral<Function<CloneSpec, IMachine>>() {
}).to((Class) CloneAndRegisterMachineFromIMachineIfNotAlreadyExists.class);
// the jetty server provider
bind(new TypeLiteral<Server>() {
}).to((Class) PreseedCfgServer.class).asEagerSingleton();
// for byon
bind(new TypeLiteral<Function<URI, InputStream>>() {
@ -162,13 +165,6 @@ public class VirtualBoxComputeServiceContextModule extends
bind(LockType.class).toInstance(LockType.Write);
}
@Provides
@Singleton
@Preconfiguration
protected LoadingCache<IsoSpec, URI> preconfiguration(CacheLoader<IsoSpec, URI> cacheLoader) {
return CacheBuilder.newBuilder().build(cacheLoader);
}
@Provides
@Host
@Singleton
@ -180,12 +176,6 @@ public class VirtualBoxComputeServiceContextModule extends
ImmutableSet.<Module> of(new SLF4JLoggingModule(), new SshjSshClientModule()));
}
@Provides
@Singleton
protected Server providesJettyServer(@Named(VIRTUALBOX_PRECONFIGURATION_URL) String preconfigurationUrl) {
return new Server(URI.create(preconfigurationUrl).getPort());
}
@Provides
@Singleton
protected Function<Supplier<NodeMetadata>, VirtualBoxManager> provideVBox() {
@ -230,7 +220,8 @@ public class VirtualBoxComputeServiceContextModule extends
@Override
protected TemplateBuilder provideTemplate(Injector injector, TemplateBuilder template) {
return template.osFamily(OsFamily.UBUNTU).osVersionMatches("11.04");
return template.osFamily(VIRTUALBOX_DEFAULT_IMAGE_OS).osVersionMatches(VIRTUALBOX_DEFAULT_IMAGE_VERSION)
.osArchMatches(VIRTUALBOX_DEFAULT_IMAGE_ARCH);
}
@Provides
@ -248,8 +239,7 @@ public class VirtualBoxComputeServiceContextModule extends
@VisibleForTesting
public static final Map<MachineState, NodeState> machineToNodeState = ImmutableMap
.<MachineState, NodeState> builder()
.put(MachineState.Running, NodeState.RUNNING)
.<MachineState, NodeState> builder().put(MachineState.Running, NodeState.RUNNING)
.put(MachineState.PoweredOff, NodeState.SUSPENDED)
.put(MachineState.DeletingSnapshot, NodeState.PENDING)
.put(MachineState.DeletingSnapshotOnline, NodeState.PENDING)
@ -261,15 +251,10 @@ public class VirtualBoxComputeServiceContextModule extends
.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, NodeState.UNRECOGNIZED).build();
.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, NodeState.UNRECOGNIZED).build();
}

View File

@ -21,6 +21,8 @@ package org.jclouds.virtualbox.config;
import java.io.File;
import org.jclouds.compute.domain.OsFamily;
/**
* Configuration properties used for interacting with VirtualBox instances.
*
@ -30,7 +32,7 @@ import java.io.File;
public interface VirtualBoxConstants {
public static final String VIRTUALBOX_NODE_NAME_SEPARATOR = "-0x0-";
public static final String VIRTUALBOX_IMAGE_PREFIX = "jclouds-image" + VIRTUALBOX_NODE_NAME_SEPARATOR;
public static final String VIRTUALBOX_NODE_PREFIX = "jclouds-node" + VIRTUALBOX_NODE_NAME_SEPARATOR;
@ -60,6 +62,12 @@ public interface VirtualBoxConstants {
public static final String VIRTUALBOX_DEFAULT_DIR = System.getProperty("user.home") + File.separator
+ ".jclouds-vbox";
public static final OsFamily VIRTUALBOX_DEFAULT_IMAGE_OS = OsFamily.UBUNTU;
public static final String VIRTUALBOX_DEFAULT_IMAGE_VERSION = "11.10";
public static final String VIRTUALBOX_DEFAULT_IMAGE_ARCH = "x86";
public static final String VIRTUALBOX_PROVIDER = "virtualbox";
}

View File

@ -139,7 +139,7 @@ public class YamlImage {
OsFamily family = parseOsFamilyOrUnrecognized(arg0.os_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).arch(arg0.os_arch).build();
return new ImageBuilder().id(arg0.id).name(arg0.name).description(arg0.description)
.operatingSystem(operatingSystem).build();
@ -149,4 +149,15 @@ public class YamlImage {
public Image toImage() {
return toImage.apply(this);
}
@Override
public String toString() {
return "YamlImage [id=" + id + ", name=" + name + ", description=" + description + ", hostname=" + hostname
+ ", location_id=" + location_id + ", os_arch=" + os_arch + ", os_family=" + os_family
+ ", os_description=" + os_description + ", os_version=" + os_version + ", iso=" + iso
+ ", keystroke_sequence=" + keystroke_sequence + ", preseed_cfg=" + preseed_cfg + ", login_port="
+ login_port + ", os_64bit=" + os_64bit + ", group=" + group + ", tags=" + tags + ", metadata="
+ metadata + ", username=" + username + ", credential=" + credential + ", credential_url="
+ credential_url + ", sudo_password=" + sudo_password + "]";
}
}

View File

@ -21,8 +21,8 @@ package org.jclouds.virtualbox.functions;
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.collect.Iterables.transform;
import static org.jclouds.scriptbuilder.domain.Statements.call;
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_PRECONFIGURATION_URL;
import java.net.URI;
import java.util.List;
import javax.annotation.Resource;
@ -36,7 +36,6 @@ import org.jclouds.compute.options.RunScriptOptions;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.logging.Logger;
import org.jclouds.ssh.SshClient;
import org.jclouds.virtualbox.Preconfiguration;
import org.jclouds.virtualbox.domain.IsoSpec;
import org.jclouds.virtualbox.domain.MasterSpec;
import org.jclouds.virtualbox.domain.VmSpec;
@ -49,7 +48,6 @@ import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.base.Splitter;
import com.google.common.base.Throwables;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.Iterables;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
@ -64,28 +62,28 @@ public class CreateAndInstallVm implements Function<MasterSpec, IMachine> {
private final CreateAndRegisterMachineFromIsoIfNotAlreadyExists createAndRegisterMachineFromIsoIfNotAlreadyExists;
private final Predicate<SshClient> sshResponds;
private LoadingCache<IsoSpec, URI> preConfiguration;
private final Function<IMachine, SshClient> sshClientForIMachine;
private final MachineUtils machineUtils;
private final IMachineToNodeMetadata imachineToNodeMetadata;
private final MachineController machineController;
private final String version;
private final String preconfigurationUrl;
@Inject
public CreateAndInstallVm(
CreateAndRegisterMachineFromIsoIfNotAlreadyExists CreateAndRegisterMachineFromIsoIfNotAlreadyExists,
IMachineToNodeMetadata imachineToNodeMetadata, Predicate<SshClient> sshResponds,
Function<IMachine, SshClient> sshClientForIMachine, MachineUtils machineUtils,
@Preconfiguration LoadingCache<IsoSpec, URI> preConfiguration, MachineController machineController,
@Named(Constants.PROPERTY_BUILD_VERSION) String version) {
MachineController machineController, @Named(Constants.PROPERTY_BUILD_VERSION) String version,
@Named(VIRTUALBOX_PRECONFIGURATION_URL) String preconfigurationUrl) {
this.createAndRegisterMachineFromIsoIfNotAlreadyExists = CreateAndRegisterMachineFromIsoIfNotAlreadyExists;
this.sshResponds = sshResponds;
this.sshClientForIMachine = sshClientForIMachine;
this.machineUtils = machineUtils;
this.preConfiguration = preConfiguration;
this.imachineToNodeMetadata = imachineToNodeMetadata;
this.machineController = machineController;
this.version = Iterables.get(Splitter.on('r').split(version), 0);
this.preconfigurationUrl = preconfigurationUrl;
}
@Override
@ -100,9 +98,8 @@ public class CreateAndInstallVm implements Function<MasterSpec, IMachine> {
// Launch machine and wait for it to come online
machineController.ensureMachineIsLaunched(vmName);
URI uri = preConfiguration.getUnchecked(isoSpec);
String installationKeySequence = isoSpec.getInstallationKeySequence().replace("PRECONFIGURATION_URL",
uri.toASCIIString());
preconfigurationUrl);
configureOsInstallationWithKeyboardSequence(vmName, installationKeySequence);
@ -112,7 +109,7 @@ public class CreateAndInstallVm implements Function<MasterSpec, IMachine> {
} catch (InterruptedException e) {
Throwables.propagate(e);
}
SshClient client = sshClientForIMachine.apply(vm);
logger.debug(">> awaiting installation to finish node(%s)", vmName);
@ -127,7 +124,6 @@ public class CreateAndInstallVm implements Function<MasterSpec, IMachine> {
ExecResponse cleanupResponse = Futures.getUnchecked(execCleanup);
checkState(cleanupResponse.getExitStatus() == 0);
logger.debug(">> awaiting installation of guest additions on vm: %s", vmName);
ListenableFuture<ExecResponse> execInstallGA = machineUtils.runScriptOnNode(nodeMetadata,
new InstallGuestAdditions(vmSpec, version), RunScriptOptions.NONE);

View File

@ -21,7 +21,7 @@ package org.jclouds.virtualbox.functions;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_DEFAULT_DIR;
import static org.jclouds.virtualbox.config.VirtualBoxConstants.*;
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_NODE_NAME_SEPARATOR;
@ -54,6 +54,7 @@ import org.jclouds.virtualbox.domain.NetworkSpec;
import org.jclouds.virtualbox.domain.StorageController;
import org.jclouds.virtualbox.domain.VmSpec;
import org.jclouds.virtualbox.domain.YamlImage;
import org.jclouds.virtualbox.functions.admin.PreseedCfgServer;
import org.virtualbox_4_1.CleanupMode;
import org.virtualbox_4_1.IMachine;
import org.virtualbox_4_1.NetworkAttachmentType;
@ -72,7 +73,8 @@ import com.google.common.collect.Maps;
/**
* A {@link LoadingCache} for masters. If the requested master has been previously created this
* returns it, if not it coordinates its creation including downloading isos and creating
* cache/config directories.
* cache/config directories. This also implements {@link Supplier} in order to provide jetty with
* the current image (only one master can be created at a time).
*
* @author dralves
*
@ -94,13 +96,15 @@ public class MastersLoadingCache extends AbstractLoadingCache<Image, Master> {
private final String workingDir;
private final String installationKeySequence;
private final String isosDir;
private Supplier<VirtualBoxManager> manager;
private Function<URI, File> isoDownloader;
private String version;
private final Supplier<VirtualBoxManager> manager;
private final Function<URI, File> isoDownloader;
private final String version;
private final String preconfigurationUrl;
@Inject
public MastersLoadingCache(@Named(Constants.PROPERTY_BUILD_VERSION) String version,
@Named(VIRTUALBOX_INSTALLATION_KEY_SEQUENCE) String installationKeySequence,
@Named(VIRTUALBOX_PRECONFIGURATION_URL) String preconfigurationUrl,
@Named(VIRTUALBOX_WORKINGDIR) String workingDir, Function<MasterSpec, IMachine> masterLoader,
Supplier<Map<Image, YamlImage>> yamlMapper, Supplier<VirtualBoxManager> manager,
Function<URI, File> isoDownloader) {
@ -118,6 +122,7 @@ public class MastersLoadingCache extends AbstractLoadingCache<Image, Master> {
}
this.version = Iterables.get(Splitter.on('r').split(version), 0);
this.isoDownloader = isoDownloader;
this.preconfigurationUrl = preconfigurationUrl;
}
@PostConstruct
@ -135,11 +140,11 @@ public class MastersLoadingCache extends AbstractLoadingCache<Image, Master> {
}
// the yaml image
YamlImage yamlImage = imageMapping.get(key.getId());
YamlImage currentImage = imageMapping.get(key.getId());
checkNotNull(yamlImage, "could not find yaml image for image: " + key);
checkNotNull(currentImage, "could not find yaml image for image: " + key);
checkState(!yamlImage.id.contains(VIRTUALBOX_NODE_NAME_SEPARATOR), "master image names cannot contain \""
checkState(!currentImage.id.contains(VIRTUALBOX_NODE_NAME_SEPARATOR), "master image names cannot contain \""
+ VIRTUALBOX_NODE_NAME_SEPARATOR + "\"");
String guestAdditionsFileName = String.format("VBoxGuestAdditions_%s.iso", version);
@ -151,9 +156,9 @@ public class MastersLoadingCache extends AbstractLoadingCache<Image, Master> {
checkState(new File(guestAdditionsIso).exists(), "guest additions iso does not exist at: " + guestAdditionsIso);
// check if the iso is here, download if not
String localIsoUrl = getFilePathOrDownload(yamlImage.iso);
String localIsoUrl = getFilePathOrDownload(currentImage.iso);
String vmName = VIRTUALBOX_IMAGE_PREFIX + yamlImage.id;
String vmName = VIRTUALBOX_IMAGE_PREFIX + currentImage.id;
String adminDisk = workingDir + File.separator + vmName + ".vdi";
@ -163,7 +168,7 @@ public class MastersLoadingCache extends AbstractLoadingCache<Image, Master> {
StorageController ideController = StorageController.builder().name("IDE Controller").bus(StorageBus.IDE)
.attachISO(0, 0, localIsoUrl).attachHardDisk(hardDisk).attachISO(1, 0, guestAdditionsIso).build();
VmSpec vmSpecification = VmSpec.builder().id(yamlImage.id).name(vmName).memoryMB(512).osTypeId("")
VmSpec vmSpecification = VmSpec.builder().id(currentImage.id).name(vmName).memoryMB(512).osTypeId("")
.controller(ideController).forceOverwrite(true).cleanUpMode(CleanupMode.Full).build();
NetworkAdapter networkAdapter = NetworkAdapter.builder().networkAttachmentType(NetworkAttachmentType.NAT)
@ -183,17 +188,24 @@ public class MastersLoadingCache extends AbstractLoadingCache<Image, Master> {
IMachine masterMachine;
// try and find a master machine in vbox
// ready the preseed file server
PreseedCfgServer server = new PreseedCfgServer();
try {
// try and find a master machine in vbox
masterMachine = manager.get().getVBox().findMachine(vmName);
} catch (VBoxException e) {
if (machineNotFoundException(e)) {
server.start(preconfigurationUrl,currentImage.preseed_cfg);
// create the master machine if it can't be found
masterMachine = masterCreatorAndInstaller.apply(masterSpec);
} else {
throw e;
}
} finally {
server.stop();
}
Master master = Master.builder().machine(masterMachine).spec(masterSpec).build();

View File

@ -48,7 +48,7 @@ public class ImagesToYamlImagesFromYamlDescriptor implements Supplier<Map<Image,
private String yamlDescriptor;
@Inject
public ImagesToYamlImagesFromYamlDescriptor(/*Supplier<String> yamlDescriptorSupplier*/YamlImagesFromFileConfig yamlDescriptorSupplier) {
public ImagesToYamlImagesFromYamlDescriptor(YamlImagesFromFileConfig yamlDescriptorSupplier) {
this.yamlDescriptor = yamlDescriptorSupplier.get();
checkNotNull(yamlDescriptor, "yaml descriptor");
checkState(!yamlDescriptor.equals(""), "yaml descriptor is empty");

View File

@ -0,0 +1,74 @@
/**
* 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 java.io.IOException;
import java.net.URI;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler;
import com.google.common.base.Throwables;
/**
* Sets up jetty so that it can serve the preseed.cfg file to automate master creation.
*
* @author Andrea Turli, David Alves
*/
public class PreseedCfgServer {
private Server jetty;
public void start(String preconfigurationUrl, final String preseedCfg) {
this.jetty = new Server(URI.create(preconfigurationUrl).getPort());
try {
// since we're only serving the preseed.cfg file respond to all requests with it
jetty.setHandler(new AbstractHandler() {
@Override
public void handle(String target, Request baseRequest, HttpServletRequest request,
HttpServletResponse response) throws IOException, ServletException {
response.setContentType("text/plain;charset=utf-8");
response.setStatus(HttpServletResponse.SC_OK);
baseRequest.setHandled(true);
response.getWriter().println(preseedCfg);
}
});
jetty.start();
} catch (Exception e) {
throw Throwables.propagate(e);
}
}
public void stop() {
try {
if (jetty != null) {
jetty.stop();
}
} catch (Exception e) {
throw Throwables.propagate(e);
}
}
}

View File

@ -1,127 +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.functions.admin;
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.base.Throwables.propagate;
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_PRECONFIGURATION_URL;
import java.io.IOException;
import java.net.URI;
import javax.annotation.PreDestroy;
import javax.inject.Inject;
import javax.inject.Named;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.IOUtils;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.util.resource.Resource;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.logging.Logger;
import org.jclouds.virtualbox.domain.IsoSpec;
import com.google.common.base.Throwables;
import com.google.common.cache.CacheLoader;
import com.google.inject.Singleton;
/**
* Sets up jetty so that it can serve the preseed.cfg file to automate master creation.
*
* TODO - Probably we can make this only start jetty. This has not been used to serve isos.
*
* @author Andrea Turli, David Alves
*/
@Singleton
public class StartJettyIfNotAlreadyRunning extends CacheLoader<IsoSpec, URI> {
@javax.annotation.Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL;
private Server jetty;
private final String preconfigurationUrl;
@Inject
public StartJettyIfNotAlreadyRunning(@Named(VIRTUALBOX_PRECONFIGURATION_URL) String preconfigurationUrl, Server jetty) {
this.preconfigurationUrl = preconfigurationUrl;
this.jetty = jetty;
}
@Override
public URI load(IsoSpec isoSpec) throws Exception {
try {
start();
} catch (Exception e) {
logger.error("Could not connect to host providing ISO " + isoSpec, e);
propagate(e);
}
return URI.create(preconfigurationUrl);
}
private void start() {
if (jetty.getState().equals(Server.STARTED)) {
logger.debug("not starting jetty, as existing host is serving %s", preconfigurationUrl);
} else {
try {
// find the the parent dir inside the jar to serve the file from
final String preseedFile = IOUtils
.toString(Resource.newSystemResource("preseed.cfg").getURL().openStream());
checkState(preseedFile != null);
// since we're only serving the preseed.cfg file respond to all requests with it
jetty.setHandler(new AbstractHandler() {
@Override
public void handle(String target, Request baseRequest, HttpServletRequest request,
HttpServletResponse response) throws IOException, ServletException {
response.setContentType("text/plain;charset=utf-8");
response.setStatus(HttpServletResponse.SC_OK);
baseRequest.setHandled(true);
response.getWriter().println(preseedFile);
}
});
jetty.start();
} catch (Exception e) {
logger.error(e, "Server jetty could not be started for %s", preconfigurationUrl);
throw Throwables.propagate(e);
}
}
}
@PreDestroy()
public void stop() {
try {
jetty.stop();
} catch (Exception e) {
logger.error("Could not stop jetty.", e);
}
}
}

View File

@ -59,8 +59,6 @@ public class StartVBoxIfNotAlreadyRunning implements Supplier<VirtualBoxManager>
private final RetryIfSocketNotYetOpen socketTester;
private final Supplier<NodeMetadata> host;
private final Supplier<URI> providerSupplier;
// private final String identity;
// private final String credential;
private final Function<Supplier<NodeMetadata>, VirtualBoxManager> managerForNode;
private transient VirtualBoxManager manager;
@ -75,8 +73,6 @@ public class StartVBoxIfNotAlreadyRunning implements Supplier<VirtualBoxManager>
this.socketTester.seconds(3L);
this.host = checkNotNull(host, "host");
this.providerSupplier = checkNotNull(providerSupplier, "endpoint to virtualbox websrvd is needed");
// this.identity = checkNotNull(identity, "identity");
// this.credential = checkNotNull(credential, "credential");
this.managerForNode = checkNotNull(managerForNode, "managerForNode");
}
@ -89,10 +85,6 @@ public class StartVBoxIfNotAlreadyRunning implements Supplier<VirtualBoxManager>
runAsRoot(false).wrapInInitScript(false)).init().call();
logger.debug(">> starting vboxwebsrv");
String vboxwebsrv = "vboxwebsrv -t 10000 -v -b";
if (host.get().getOperatingSystem() != null
&& host.get().getOperatingSystem().getDescription().equals("Mac OS X"))
vboxwebsrv = "cd /Applications/VirtualBox.app/Contents/MacOS/ && " + vboxwebsrv;
runScriptOnNodeFactory.create(host.get(), Statements.exec(vboxwebsrv),
runAsRoot(false).wrapInInitScript(false).blockOnComplete(false).nameTask("vboxwebsrv")).init().call();

View File

@ -0,0 +1,37 @@
/**
* 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.predicates;
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_DEFAULT_IMAGE_ARCH;
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_DEFAULT_IMAGE_OS;
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_DEFAULT_IMAGE_VERSION;
import org.jclouds.compute.domain.Image;
import com.google.common.base.Predicate;
public class DefaultImagePredicate implements Predicate<Image> {
@Override
public boolean apply(Image input) {
return input.getOperatingSystem().getFamily() == VIRTUALBOX_DEFAULT_IMAGE_OS
&& input.getOperatingSystem().getVersion().equals(VIRTUALBOX_DEFAULT_IMAGE_VERSION)
&& input.getOperatingSystem().getArch().equals(VIRTUALBOX_DEFAULT_IMAGE_ARCH);
}
}

View File

@ -1,5 +1,5 @@
images:
- id: default-ubuntu-11.04-i386
- id: ubuntu-11.04-i386
name: ubuntu-11.04-server-i386
description: ubuntu 11.04 server (i386)
os_arch: x86
@ -66,3 +66,70 @@ images:
# debconf-get-selections --install
#Use mirror
choose-mirror-bin mirror/http/proxy string
- id: ubuntu-11.10-i386
name: ubuntu-11.10-server-i386
description: ubuntu 11.10 server (i386)
os_arch: x86
os_family: ubuntu
os_description: ubuntu
os_version: 11.10
iso: http://releases.ubuntu.com/11.10/ubuntu-11.10-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

View File

@ -1,88 +0,0 @@
## 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 dummy
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 netcfg/no_default_route boolean
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
#d-i base-installer/kernel/override-image string linux-image-2.6.32-21-generic
# 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 regular
d-i partman-auto/method string lvm
#d-i partman-auto/purge_lvm_from_device boolean true
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
#http://ubuntu-virginia.ubuntuforums.org/showthread.php?p=9626883
#Message: "write the changes to disk and configure lvm preseed"
#http://serverfault.com/questions/189328/ubuntu-kickstart-installation-using-lvm-waits-for-input
#preseed partman-lvm/confirm_nooverwrite 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
## minimum is puppet and ssh and ntp
# Individual additional packages to install
d-i pkgsel/include string openssh-server ntp
# dkms build-essential module-assistant
# 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
#d-i apt-setup/use_mirror boolean true
#d-i mirror/country string manual
#choose-mirror-bin mirror/protocol string http
#choose-mirror-bin mirror/http/hostname string 192.168.4.150
#choose-mirror-bin mirror/http/directory string /ubuntu
#choose-mirror-bin mirror/suite select maverick
#d-i debian-installer/allow_unauthenticated string true
choose-mirror-bin mirror/http/proxy string

View File

@ -20,10 +20,11 @@
package org.jclouds.virtualbox;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_IMAGE_PREFIX;
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_INSTALLATION_KEY_SEQUENCE;
import java.io.File;
import java.net.URI;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ExecutorService;
@ -52,11 +53,16 @@ import org.jclouds.virtualbox.domain.NetworkInterfaceCard;
import org.jclouds.virtualbox.domain.NetworkSpec;
import org.jclouds.virtualbox.domain.StorageController;
import org.jclouds.virtualbox.domain.VmSpec;
import org.jclouds.virtualbox.domain.YamlImage;
import org.jclouds.virtualbox.functions.IMachineToVmSpec;
import org.jclouds.virtualbox.functions.YamlImagesFromFileConfig;
import org.jclouds.virtualbox.functions.admin.ImagesToYamlImagesFromYamlDescriptor;
import org.jclouds.virtualbox.functions.admin.UnregisterMachineIfExistsAndDeleteItsMedia;
import org.jclouds.virtualbox.predicates.DefaultImagePredicate;
import org.jclouds.virtualbox.util.MachineController;
import org.jclouds.virtualbox.util.MachineUtils;
import org.testng.annotations.AfterClass;
import org.testng.annotations.AfterSuite;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import org.virtualbox_4_1.CleanupMode;
@ -83,12 +89,15 @@ import com.google.inject.Module;
*/
@Test(groups = "live", singleThreaded = true, testName = "BaseVirtualBoxClientLiveTest")
public class BaseVirtualBoxClientLiveTest extends BaseVersionedServiceLiveTest {
public static final String DONT_DESTROY_MASTER = "jclouds.virtualbox.keep-test-master";
public BaseVirtualBoxClientLiveTest() {
provider = "virtualbox";
}
protected ComputeServiceContext context;
@Inject
protected MachineController machineController;
@ -104,11 +113,6 @@ public class BaseVirtualBoxClientLiveTest extends BaseVersionedServiceLiveTest {
@Inject
protected MachineUtils machineUtils;
// this will eagerly startup Jetty, note the impl will shut itself down
@Inject
@Preconfiguration
protected LoadingCache<IsoSpec, URI> preconfigurationUri;
protected String hostVersion;
protected String operatingSystemIso;
protected String guestAdditionsIso;
@ -122,8 +126,9 @@ public class BaseVirtualBoxClientLiveTest extends BaseVersionedServiceLiveTest {
protected PrioritizeCredentialsFromTemplate prioritizeCredentialsFromTemplate;
@Inject
protected LoadingCache<Image, Master> mastersCache;
private final ExecutorService singleThreadExec = MoreExecutors.sameThreadExecutor();
private final ExecutorService singleThreadExec = MoreExecutors.sameThreadExecutor();
private String masterVmName;
@Override
protected void setupCredentials() {
@ -147,16 +152,19 @@ public class BaseVirtualBoxClientLiveTest extends BaseVersionedServiceLiveTest {
context = new ComputeServiceContextFactory().createContext(provider, identity, credential, ImmutableSet
.<Module> of(new SLF4JLoggingModule(), new SshjSshClientModule(), new ExecutorServiceModule(
singleThreadExec, singleThreadExec)), overrides);
context.utils().injector().injectMembers(this);
imageId = "ubuntu-11.04-server-i386";
YamlImage image = getDefaultImage();
imageId = image.id;
masterVmName = VIRTUALBOX_IMAGE_PREFIX + image.id;
isosDir = workingDir + File.separator + "isos";
hostVersion = Iterables.get(Splitter.on('r').split(context.getProviderSpecificContext().getBuildVersion()), 0);
operatingSystemIso = String.format("%s/%s.iso", isosDir, imageId);
operatingSystemIso = String.format("%s/%s.iso", isosDir, image.name);
guestAdditionsIso = String.format("%s/VBoxGuestAdditions_%s.iso", isosDir, hostVersion);
// try and get a master from the cache, this will initialize the config/download isos and
// prepare everything IF a master is not available, subsequent calls should be pretty fast
Template template = context.getComputeService().templateBuilder().build();
@ -189,7 +197,8 @@ public class BaseVirtualBoxClientLiveTest extends BaseVersionedServiceLiveTest {
}
public MasterSpec getMasterSpecForTest() {
String masterName = "jclouds-image-0x0-default-ubuntu-11.04-i386";
String masterName = "jclouds-image-0x0-" + imageId;
StorageController ideController = StorageController
.builder()
.name("IDE Controller")
@ -199,37 +208,45 @@ public class BaseVirtualBoxClientLiveTest extends BaseVersionedServiceLiveTest {
HardDisk.builder().diskpath(adminDisk(masterName)).controllerPort(0).deviceSlot(1)
.autoDelete(true).build()).attachISO(1, 0, guestAdditionsIso).build();
VmSpec sourceVmSpec = VmSpec.builder().id(masterName).name(masterName)
.osTypeId("").memoryMB(512).cleanUpMode(CleanupMode.Full)
.controller(ideController).forceOverwrite(true).build();
VmSpec sourceVmSpec = VmSpec.builder().id(masterName).name(masterName).osTypeId("").memoryMB(512)
.cleanUpMode(CleanupMode.Full).controller(ideController).forceOverwrite(true).build();
Injector injector = context.utils().injector();
Function<String, String> configProperties = injector
.getInstance(ValueOfConfigurationKeyOrNull.class);
IsoSpec isoSpec = IsoSpec
.builder()
.sourcePath(operatingSystemIso)
.installationScript(
configProperties.apply(
VIRTUALBOX_INSTALLATION_KEY_SEQUENCE).replace(
"HOSTNAME", sourceVmSpec.getVmName())).build();
NetworkAdapter networkAdapter = NetworkAdapter.builder()
.networkAttachmentType(NetworkAttachmentType.NAT)
.tcpRedirectRule("127.0.0.1", 2222, "", 22).build();
NetworkInterfaceCard networkInterfaceCard = NetworkInterfaceCard
.builder().addNetworkAdapter(networkAdapter).build();
Injector injector = context.utils().injector();
Function<String, String> configProperties = injector.getInstance(ValueOfConfigurationKeyOrNull.class);
IsoSpec isoSpec = IsoSpec
.builder()
.sourcePath(operatingSystemIso)
.installationScript(
configProperties.apply(VIRTUALBOX_INSTALLATION_KEY_SEQUENCE).replace("HOSTNAME",
sourceVmSpec.getVmName())).build();
NetworkSpec networkSpec = NetworkSpec.builder()
.addNIC(networkInterfaceCard).build();
return MasterSpec.builder().iso(isoSpec).vm(sourceVmSpec)
.network(networkSpec).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(networkInterfaceCard).build();
return MasterSpec.builder().iso(isoSpec).vm(sourceVmSpec).network(networkSpec).build();
}
public static YamlImage getDefaultImage() {
Map<Image, YamlImage> images = new ImagesToYamlImagesFromYamlDescriptor(new YamlImagesFromFileConfig(
"/default-images.yaml")).get();
return images.get(Iterables.getOnlyElement(Iterables.filter(images.keySet(), new DefaultImagePredicate())));
}
@AfterClass(groups = "live")
protected void tearDown() throws Exception {
if (context != null)
context.close();
}
@AfterSuite
protected void destroyMaster() {
if (System.getProperty(DONT_DESTROY_MASTER) == null
|| !Boolean.parseBoolean(System.getProperty(DONT_DESTROY_MASTER))) {
undoVm(masterVmName);
}
}
}

View File

@ -25,20 +25,19 @@ import java.net.URL;
import java.util.Properties;
import org.apache.commons.io.IOUtils;
import org.eclipse.jetty.server.Server;
import org.jclouds.virtualbox.config.VirtualBoxConstants;
import org.jclouds.virtualbox.functions.admin.StartJettyIfNotAlreadyRunning;
import org.jclouds.virtualbox.functions.admin.PreseedCfgServer;
import org.testng.annotations.Test;
/**
* Tests that jetty is able to serve the preseed.cfg file. This test is here to have access to the
* defaultProperties() method in {@link VirtualBoxPropertiesBuilder}.
* Tests that jetty is able to serve the preseed.cfg from the provided yaml image. This test is here
* to have access to the defaultProperties() method in {@link VirtualBoxPropertiesBuilder}.
*
* @author dralves
*
*/
@Test(groups = "live", singleThreaded = true, testName = "StartJettyIfNotAlreadyRunningLiveTest")
public class StartJettyIfNotAlreadyRunningLiveTest {
public class PreseedCfgServerTest {
@Test
public void testJettyServerServesPreseedFile() throws Exception {
@ -48,15 +47,14 @@ public class StartJettyIfNotAlreadyRunningLiveTest {
int port = URI.create(preconfigurationUrl).getPort();
Server server = new Server(port);
PreseedCfgServer starter = new PreseedCfgServer();
StartJettyIfNotAlreadyRunning starter = new StartJettyIfNotAlreadyRunning(preconfigurationUrl, server);
starter.load(null);
starter.start(preconfigurationUrl, BaseVirtualBoxClientLiveTest.getDefaultImage().preseed_cfg);
String preseedFileFromJetty = IOUtils.toString(new URL("http://127.0.0.1:" + port + "/preseed.cfg").openStream());
String preseedFileFromFile = IOUtils
.toString(this.getClass().getClassLoader().getResourceAsStream("preseed.cfg")) + "\n";
String preseedFileFromFile = BaseVirtualBoxClientLiveTest.getDefaultImage().preseed_cfg + "\n";
assertEquals(preseedFileFromFile, preseedFileFromJetty);
starter.stop();
}
}

View File

@ -19,6 +19,7 @@
package org.jclouds.virtualbox.compute;
import static junit.framework.Assert.assertTrue;
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_NODE_PREFIX;
import static org.testng.Assert.assertEquals;
@ -42,7 +43,7 @@ import com.google.common.collect.Iterables;
public class VirtualBoxComputeServiceAdapterLiveTest extends BaseVirtualBoxClientLiveTest {
private NodeAndInitialCredentials<IMachine> machine;
@Inject
protected VirtualBoxComputeServiceAdapter adapter;
@ -50,14 +51,14 @@ public class VirtualBoxComputeServiceAdapterLiveTest extends BaseVirtualBoxClien
public void testCreatedNodeHasExpectedNameAndWeCanConnectViaSsh() {
String group = "foo";
String name = "foo-ef4";
String machineName = VIRTUALBOX_NODE_PREFIX + "default-ubuntu-11.04-i386-" + "0x0-" + group + "-0x0-" + name;
Template template = context.getComputeService().templateBuilder().build();
machine = adapter.createNodeWithGroupEncodedIntoName(group, name, template);
assertEquals(machine.getNode().getName(), machineName);
assertTrue(machine.getNode().getName().contains(group));
assertTrue(machine.getNode().getName().contains(name));
assertTrue(machine.getNode().getName().startsWith(VIRTUALBOX_NODE_PREFIX));
doConnectViaSsh(machine.getNode(), prioritizeCredentialsFromTemplate.apply(template, machine.getCredentials()));
}
protected void doConnectViaSsh(IMachine machine, LoginCredentials creds) {
SshClient ssh = context.utils().injector().getInstance(IMachineToSshClient.class).apply(machine);
try {
@ -76,15 +77,13 @@ public class VirtualBoxComputeServiceAdapterLiveTest extends BaseVirtualBoxClien
@Test
public void testListHardwareProfiles() {
Iterable<IMachine> profiles = adapter.listHardwareProfiles();
assertEquals(1, Iterables.size(profiles));
//TODO: check state;
assertTrue(!Iterables.isEmpty(profiles));
}
@Test
public void testListImages() {
Iterable<Image> iMageIterable = adapter.listImages();
assertEquals(1, Iterables.size(iMageIterable));
//TODO: check state;
assertTrue(!Iterables.isEmpty(iMageIterable));
}
@AfterClass

View File

@ -39,6 +39,7 @@ import org.jclouds.logging.slf4j.config.SLF4JLoggingModule;
import org.jclouds.scriptbuilder.statements.login.AdminAccess;
import org.jclouds.ssh.SshClient;
import org.jclouds.sshj.config.SshjSshClientModule;
import org.jclouds.virtualbox.BaseVirtualBoxClientLiveTest;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
@ -51,7 +52,7 @@ import com.google.inject.Module;
* @author Adrian Cole
*/
@Test(groups = "live", singleThreaded = true, testName = "VirtualBoxExperimentLiveTest")
public class VirtualBoxExperimentLiveTest {
public class VirtualBoxExperimentLiveTest extends BaseVirtualBoxClientLiveTest {
@Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
@ -69,7 +70,8 @@ public class VirtualBoxExperimentLiveTest {
public void testLaunchCluster() throws RunNodesException {
int numNodes = 2;
final String clusterName = "test-launch-cluster";
Set<? extends NodeMetadata> nodes = context.getComputeService().createNodesInGroup(clusterName, numNodes, TemplateOptions.Builder.runScript(AdminAccess.standard()));
Set<? extends NodeMetadata> nodes = context.getComputeService().createNodesInGroup(clusterName, numNodes,
TemplateOptions.Builder.runScript(AdminAccess.standard()));
assertEquals(numNodes, nodes.size(), "wrong number of nodes");
for (NodeMetadata node : nodes) {
assertTrue(node.getGroup().equals("test-launch-cluster"));

View File

@ -19,16 +19,19 @@
package org.jclouds.virtualbox.functions.admin;
import static junit.framework.Assert.assertTrue;
import static org.testng.Assert.assertEquals;
import java.io.InputStreamReader;
import java.util.Map;
import org.apache.commons.io.IOUtils;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.ImageBuilder;
import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.compute.domain.OsFamily;
import org.jclouds.virtualbox.domain.YamlImage;
import org.jclouds.virtualbox.functions.YamlImagesFromFileConfig;
import org.jclouds.virtualbox.predicates.DefaultImagePredicate;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import com.google.common.collect.Iterables;
@ -40,22 +43,31 @@ import com.google.common.collect.Iterables;
public class ImageFromYamlStringTest {
public static final Image TEST1 = new ImageBuilder()
.id("default-ubuntu-11.04-i386")
.id("ubuntu-11.04-i386")
.name("ubuntu-11.04-server-i386")
.description("ubuntu 11.04 server (i386)")
.operatingSystem(
OperatingSystem.builder().description("ubuntu").family(OsFamily.UBUNTU).version("11.04").build())
.build();
OperatingSystem.builder().description("ubuntu").family(OsFamily.UBUNTU).version("11.04")
.arch("x86").build()).build();
Map<Image, YamlImage> images;
@BeforeMethod
public void setUp() {
images = new ImagesToYamlImagesFromYamlDescriptor(new YamlImagesFromFileConfig("/default-images.yaml")).get();
}
@Test
public void testNodesParse() throws Exception {
public void testNodesParse() {
assertEquals(Iterables.getFirst(images.keySet(), null), TEST1);
}
final StringBuilder yamlFileLines = new StringBuilder();
for (Object line : IOUtils
.readLines(new InputStreamReader(getClass().getResourceAsStream("/default-images.yaml")))) {
yamlFileLines.append(line).append("\n");
}
ImagesToYamlImagesFromYamlDescriptor parser = new ImagesToYamlImagesFromYamlDescriptor(new YamlImagesFromFileConfig("/default-images.yaml"));
assertEquals(Iterables.getFirst(parser.get().keySet(), null), TEST1);
@Test
public void testDefaultImagePresent() {
Iterable<Image> defaultImage = Iterables.filter(images.keySet(), new DefaultImagePredicate());
assertTrue(!Iterables.isEmpty(defaultImage));
assertEquals(1, Iterables.size(defaultImage));
}
}

View File

@ -1,62 +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.functions.admin;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.verify;
import static org.testng.Assert.assertEquals;
import java.net.URI;
import org.eclipse.jetty.server.Server;
import org.jclouds.virtualbox.domain.IsoSpec;
import org.testng.annotations.Test;
/**
* @author Andrea Turli, Adrian Cole
*/
@Test(groups = "unit", singleThreaded = true, testName = "StartJettyIfNotAlreadyRunningTest")
public class StartJettyIfNotAlreadyRunningTest {
@Test
public void testLoadStartsJettyServer() throws Exception {
Server jetty = createMock(Server.class);
String preconfigurationUrl = "http://foo:8080";
expect(jetty.getState()).andReturn(Server.STARTED);
replay(jetty);
StartJettyIfNotAlreadyRunning starter = new StartJettyIfNotAlreadyRunning(preconfigurationUrl, jetty);
IsoSpec isoSpec = IsoSpec.builder()
.sourcePath("/tmp/myisos/ubuntu.iso")
.installationScript("install").build();
assertEquals(starter.load(isoSpec), URI.create(preconfigurationUrl));
verify(jetty);
}
@Test
public void testLaunchJettyServerWhenNotRunningStartsJettyOnCorrectHostPortAndBasedir() {
// TODO: all yours!
}
}

View File

@ -0,0 +1,64 @@
/**
* 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.predicates;
import static junit.framework.Assert.assertTrue;
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_DEFAULT_IMAGE_ARCH;
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_DEFAULT_IMAGE_OS;
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_DEFAULT_IMAGE_VERSION;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.ImageBuilder;
import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.compute.domain.OsFamily;
import org.testng.annotations.Test;
/**
* A simple test for {@link DefaultImagePredicate} that makes sure the predicate returns true when
* an image built with the defaults is passed and false when it's not.
*
* @author dralves
*
*/
public class DefaultImagePredicateTest {
@Test
public void testFindDefaultImage() {
Image image = new ImageBuilder()
.id("test-id")
.description("test-image")
.operatingSystem(
OperatingSystem.builder().arch(VIRTUALBOX_DEFAULT_IMAGE_ARCH)
.version(VIRTUALBOX_DEFAULT_IMAGE_VERSION).description("test-os")
.family(VIRTUALBOX_DEFAULT_IMAGE_OS).build()).build();
assertTrue(new DefaultImagePredicate().apply(image));
}
@Test
public void testNotFindDefaultImage() {
Image image = new ImageBuilder()
.id("test-id")
.description("test-image")
.operatingSystem(
OperatingSystem.builder().arch(VIRTUALBOX_DEFAULT_IMAGE_ARCH)
.version(VIRTUALBOX_DEFAULT_IMAGE_VERSION).description("test-os")
.family(OsFamily.UNRECOGNIZED).build()).build();
assertTrue(!new DefaultImagePredicate().apply(image));
}
}

View File

@ -25,7 +25,6 @@ import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_INSTA
import org.jclouds.config.ValueOfConfigurationKeyOrNull;
import org.jclouds.virtualbox.BaseVirtualBoxClientLiveTest;
import org.jclouds.virtualbox.domain.CloneSpec;
import org.jclouds.virtualbox.domain.ExecutionType;
import org.jclouds.virtualbox.domain.HardDisk;
import org.jclouds.virtualbox.domain.IsoSpec;
import org.jclouds.virtualbox.domain.MasterSpec;
@ -36,7 +35,6 @@ import org.jclouds.virtualbox.domain.StorageController;
import org.jclouds.virtualbox.domain.VmSpec;
import org.jclouds.virtualbox.functions.CloneAndRegisterMachineFromIMachineIfNotAlreadyExists;
import org.jclouds.virtualbox.functions.CreateAndInstallVm;
import org.jclouds.virtualbox.functions.LaunchMachineIfNotAlreadyRunning;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

View File

@ -0,0 +1,135 @@
images:
- id: ubuntu-11.04-i386
name: ubuntu-11.04-server-i386
description: ubuntu 11.04 server (i386)
os_arch: x86
os_family: ubuntu
os_description: ubuntu
os_version: 11.04
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
- id: test-ubuntu-11.10-i386
name: ubuntu-11.10-server-i386
description: ubuntu 11.10 server (i386)
os_arch: x86
os_family: ubuntu
os_description: ubuntu
os_version: 11.10
iso: http://releases.ubuntu.com/11.10/ubuntu-11.10-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