mirror of https://github.com/apache/jclouds.git
Merge branch 'master' of git://github.com/jclouds/jclouds
This commit is contained in:
commit
9afa28bab1
|
@ -16,7 +16,7 @@ check out our examples site! https://github.com/jclouds/jclouds-examples
|
|||
our compute api supports: aws-ec2, gogrid, cloudservers-us, stub (in-memory), deltacloud,
|
||||
cloudservers-uk, vcloud (generic), ec2 (generic), byon, nova,
|
||||
trmk-ecloud, trmk-vcloudexpress, eucalyptus (generic),
|
||||
cloudsigma-zrh, elasticstack(generic),
|
||||
cloudsigma-zrh, elasticstack(generic), go2cloud-jhb1,
|
||||
bluelock-vcloud-zone01, stratogen-vcloud-mycloud, rimuhosting,
|
||||
slicehost, eucalyptus-partnercloud-ec2, elastichosts-lon-p (Peer 1),
|
||||
elastichosts-sat-p (Peer 1), elastichosts-lon-b (BlueSquare),
|
||||
|
|
|
@ -165,5 +165,10 @@
|
|||
<artifactId>cloudsigma-zrh</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jclouds.provider</groupId>
|
||||
<artifactId>go2cloud-jhb1</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
|
@ -23,23 +23,27 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.elasticstack.domain.Device;
|
||||
import org.jclouds.elasticstack.domain.NIC;
|
||||
import org.jclouds.elasticstack.domain.Server;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.rest.annotations.ApiVersion;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import org.jclouds.rest.annotations.ApiVersion;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class ServerToMap implements Function<Server, Map<String, String>> {
|
||||
@Resource
|
||||
protected Logger logger = Logger.NULL;
|
||||
|
||||
@ApiVersion
|
||||
private final String apiVersion;
|
||||
|
@ -75,7 +79,7 @@ public class ServerToMap implements Function<Server, Map<String, String>> {
|
|||
if (nic.getVlan() != null)
|
||||
builder.put("nic:" + nicId + ":vlan", nic.getVlan());
|
||||
if (nic.getMac() != null)
|
||||
builder.put("nic:" + nicId + ":mac", nic.getMac());
|
||||
logger.trace("setting mac on network interfaces not supported: %s", nic);
|
||||
nicId++;
|
||||
}
|
||||
|
||||
|
|
|
@ -63,6 +63,30 @@ public class ServerToMapTest {
|
|||
"vnc:password", "XXXXXXXX")).build());
|
||||
}
|
||||
|
||||
public void testWeDontSetMac() {
|
||||
assertEquals(
|
||||
SERVER_TO_MAP.apply(new Server.Builder()
|
||||
.name("TestServer")
|
||||
.cpu(2000)
|
||||
.mem(1024)
|
||||
.devices(
|
||||
ImmutableMap.of("ide:0:0",
|
||||
new IDEDevice.Builder(0, 0).uuid("08c92dd5-70a0-4f51-83d2-835919d254df").build()))
|
||||
.bootDeviceIds(ImmutableSet.of("ide:0:0"))
|
||||
.nics(ImmutableSet.of(new NIC.Builder().mac("foo").model(Model.E1000).
|
||||
|
||||
build())).vnc(new VNC(null, "XXXXXXXX", false)).build()),
|
||||
ImmutableMap
|
||||
.builder()
|
||||
.putAll(ImmutableMap.of("name", "TestServer", "cpu", "2000", "smp", "auto", "mem", "1024"))
|
||||
.putAll(
|
||||
ImmutableMap.of("persistent", "false", "boot", "ide:0:0", "ide:0:0",
|
||||
"08c92dd5-70a0-4f51-83d2-835919d254df"))
|
||||
.putAll(
|
||||
ImmutableMap.of("ide:0:0:media", "disk", "nic:0:model", "e1000", "vnc:ip", "auto",
|
||||
"vnc:password", "XXXXXXXX")).build());
|
||||
}
|
||||
|
||||
public void testBasicsV2() {
|
||||
assertEquals(
|
||||
SERVER_TO_MAP_V2.apply(new Server.Builder()
|
||||
|
|
|
@ -26,7 +26,7 @@ import org.testng.annotations.Test;
|
|||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "live", sequential = true, testName = "EucalyptusComputeServiceLiveTest")
|
||||
@Test(groups = "live", singleThreaded = true, testName = "EucalyptusComputeServiceLiveTest")
|
||||
public class EucalyptusComputeServiceLiveTest extends EC2ComputeServiceLiveTest {
|
||||
|
||||
public EucalyptusComputeServiceLiveTest() {
|
||||
|
@ -46,6 +46,12 @@ public class EucalyptusComputeServiceLiveTest extends EC2ComputeServiceLiveTest
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Test(enabled = true)
|
||||
public void testMapEBS() throws Exception {
|
||||
// ebs backed not yet available
|
||||
}
|
||||
|
||||
@Override
|
||||
@Test(enabled = true, dependsOnMethods = "testSuspendResume")
|
||||
public void testListNodes() throws Exception {
|
||||
|
|
|
@ -109,7 +109,7 @@
|
|||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>10.0-rc3</version>
|
||||
<version>10.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
|
|
@ -52,7 +52,12 @@ import com.google.inject.Provides;
|
|||
/**
|
||||
* Configures {@link ExecutorService}.
|
||||
*
|
||||
* Note that this uses threads
|
||||
* Note that this uses threads.
|
||||
*
|
||||
* <p>
|
||||
* This extends the underlying Future to expose a description (the task's toString) and the submission context (stack trace).
|
||||
* The submission stack trace is appended to relevant stack traces on exceptions that are returned,
|
||||
* so the user can see the logical chain of execution (in the executor, and where it was passed to the executor).
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
|
@ -92,7 +97,7 @@ public class ExecutorServiceModule extends AbstractModule {
|
|||
|
||||
static ExecutorService addToStringOnSubmit(ExecutorService executor) {
|
||||
if (executor != null) {
|
||||
return new AddToStringOnSubmitExecutorService(executor);
|
||||
return new DescribingExecutorService(executor);
|
||||
}
|
||||
return executor;
|
||||
}
|
||||
|
@ -117,11 +122,11 @@ public class ExecutorServiceModule extends AbstractModule {
|
|||
protected void configure() {
|
||||
}
|
||||
|
||||
static class AddToStringOnSubmitExecutorService implements ExecutorService {
|
||||
static class DescribingExecutorService implements ExecutorService {
|
||||
|
||||
private final ExecutorService delegate;
|
||||
|
||||
public AddToStringOnSubmitExecutorService(ExecutorService delegate) {
|
||||
public DescribingExecutorService(ExecutorService delegate) {
|
||||
this.delegate = checkNotNull(delegate, "delegate");
|
||||
}
|
||||
|
||||
|
@ -174,18 +179,18 @@ public class ExecutorServiceModule extends AbstractModule {
|
|||
|
||||
@Override
|
||||
public <T> Future<T> submit(Callable<T> task) {
|
||||
return new AddToStringFuture<T>(delegate.submit(task), task.toString());
|
||||
return new DescribedFuture<T>(delegate.submit(task), task.toString(), getStackTraceHere());
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
@Override
|
||||
public Future<?> submit(Runnable task) {
|
||||
return new AddToStringFuture(delegate.submit(task), task.toString());
|
||||
return new DescribedFuture(delegate.submit(task), task.toString(), getStackTraceHere());
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Future<T> submit(Runnable task, T result) {
|
||||
return new AddToStringFuture<T>(delegate.submit(task, result), task.toString());
|
||||
return new DescribedFuture<T>(delegate.submit(task, result), task.toString(), getStackTraceHere());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -210,13 +215,15 @@ public class ExecutorServiceModule extends AbstractModule {
|
|||
|
||||
}
|
||||
|
||||
static class AddToStringFuture<T> implements Future<T> {
|
||||
static class DescribedFuture<T> implements Future<T> {
|
||||
private final Future<T> delegate;
|
||||
private final String toString;
|
||||
private final String description;
|
||||
private StackTraceElement[] submissionTrace;
|
||||
|
||||
public AddToStringFuture(Future<T> delegate, String toString) {
|
||||
public DescribedFuture(Future<T> delegate, String description, StackTraceElement[] submissionTrace) {
|
||||
this.delegate = delegate;
|
||||
this.toString = toString;
|
||||
this.description = description;
|
||||
this.submissionTrace = submissionTrace;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -226,12 +233,65 @@ public class ExecutorServiceModule extends AbstractModule {
|
|||
|
||||
@Override
|
||||
public T get() throws InterruptedException, ExecutionException {
|
||||
try {
|
||||
return delegate.get();
|
||||
} catch (ExecutionException e) {
|
||||
throw ensureCauseHasSubmissionTrace(e);
|
||||
} catch (InterruptedException e) {
|
||||
throw ensureCauseHasSubmissionTrace(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public T get(long arg0, TimeUnit arg1) throws InterruptedException, ExecutionException, TimeoutException {
|
||||
try {
|
||||
return delegate.get(arg0, arg1);
|
||||
} catch (ExecutionException e) {
|
||||
throw ensureCauseHasSubmissionTrace(e);
|
||||
} catch (InterruptedException e) {
|
||||
throw ensureCauseHasSubmissionTrace(e);
|
||||
} catch (TimeoutException e) {
|
||||
throw ensureCauseHasSubmissionTrace(e);
|
||||
}
|
||||
}
|
||||
|
||||
/** This method does the work to ensure _if_ a submission stack trace was provided,
|
||||
* it is included in the exception. most errors are thrown from the frame of the
|
||||
* Future.get call, with a cause that took place in the executor's thread.
|
||||
* We extend the stack trace of that cause with the submission stack trace.
|
||||
* (An alternative would be to put the stack trace as a root cause,
|
||||
* at the bottom of the stack, or appended to all traces, or inserted
|
||||
* after the second cause, etc ... but since we can't change the "Caused by:"
|
||||
* method in Throwable the compromise made here seems best.)
|
||||
*/
|
||||
private <ET extends Exception> ET ensureCauseHasSubmissionTrace(ET e) {
|
||||
if (submissionTrace==null) return e;
|
||||
if (e.getCause()==null) {
|
||||
ExecutionException ee = new ExecutionException("task submitted from the following trace", null);
|
||||
e.initCause(ee);
|
||||
return e;
|
||||
}
|
||||
Throwable cause = e.getCause();
|
||||
StackTraceElement[] causeTrace = cause.getStackTrace();
|
||||
boolean causeIncludesSubmissionTrace = submissionTrace.length >= causeTrace.length;
|
||||
for (int i=0; causeIncludesSubmissionTrace && i<submissionTrace.length; i++) {
|
||||
if (!causeTrace[causeTrace.length-1-i].equals(submissionTrace[submissionTrace.length-1-i])) {
|
||||
causeIncludesSubmissionTrace = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!causeIncludesSubmissionTrace) {
|
||||
cause.setStackTrace(merge(causeTrace, submissionTrace));
|
||||
}
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
private StackTraceElement[] merge(StackTraceElement[] t1, StackTraceElement[] t2) {
|
||||
StackTraceElement[] t12 = new StackTraceElement[t1.length + t2.length];
|
||||
System.arraycopy(t1, 0, t12, 0, t1.length);
|
||||
System.arraycopy(t2, 0, t12, t1.length, t2.length);
|
||||
return t12;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -256,7 +316,7 @@ public class ExecutorServiceModule extends AbstractModule {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return toString;
|
||||
return description;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -302,4 +362,14 @@ public class ExecutorServiceModule extends AbstractModule {
|
|||
.setThreadFactory(Executors.defaultThreadFactory()).build());
|
||||
}
|
||||
|
||||
/** returns the stack trace at the caller */
|
||||
static StackTraceElement[] getStackTraceHere() {
|
||||
// remove the first two items in the stack trace (because the first one refers to the call to
|
||||
// Thread.getStackTrace, and the second one is us)
|
||||
StackTraceElement[] fullSubmissionTrace = Thread.currentThread().getStackTrace();
|
||||
StackTraceElement[] cleanedSubmissionTrace = new StackTraceElement[fullSubmissionTrace.length-2];
|
||||
System.arraycopy(fullSubmissionTrace, 2, cleanedSubmissionTrace, 0, cleanedSubmissionTrace.length);
|
||||
return cleanedSubmissionTrace;
|
||||
}
|
||||
|
||||
}
|
|
@ -25,12 +25,16 @@ import static org.easymock.classextension.EasyMock.verify;
|
|||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import org.jclouds.Constants;
|
||||
import org.jclouds.lifecycle.Closer;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
|
@ -64,15 +68,14 @@ public class ExecutorServiceModuleTest {
|
|||
public void testShutdownOnCloseThroughModule() throws IOException {
|
||||
|
||||
ExecutorServiceModule module = new ExecutorServiceModule() {
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
bindConstant().annotatedWith(Names.named(Constants.PROPERTY_IO_WORKER_THREADS)).to(1);
|
||||
bindConstant().annotatedWith(Names.named(Constants.PROPERTY_USER_THREADS)).to(1);
|
||||
super.configure();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
Injector i = Guice.createInjector(module);
|
||||
assertEquals(module.userExecutorFromConstructor, null);
|
||||
assertEquals(module.ioExecutorFromConstructor, null);
|
||||
|
@ -93,4 +96,163 @@ public class ExecutorServiceModuleTest {
|
|||
assert io.isShutdown();
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDescribedFutureToString() throws Exception {
|
||||
|
||||
ExecutorServiceModule module = new ExecutorServiceModule() {
|
||||
@Override
|
||||
protected void configure() {
|
||||
bindConstant().annotatedWith(Names.named(Constants.PROPERTY_IO_WORKER_THREADS)).to(1);
|
||||
bindConstant().annotatedWith(Names.named(Constants.PROPERTY_USER_THREADS)).to(1);
|
||||
super.configure();
|
||||
}
|
||||
};
|
||||
|
||||
Injector i = Guice.createInjector(module);
|
||||
Closer closer = i.getInstance(Closer.class);
|
||||
|
||||
ExecutorService user = i
|
||||
.getInstance(Key.get(ExecutorService.class, Names.named(Constants.PROPERTY_USER_THREADS)));
|
||||
ExecutorService io = i.getInstance(Key.get(ExecutorService.class, Names
|
||||
.named(Constants.PROPERTY_IO_WORKER_THREADS)));
|
||||
|
||||
ConfigurableRunner t1 = new ConfigurableRunner();
|
||||
t1.result = "okay";
|
||||
|
||||
Future<Object> euc = performSubmissionInSeparateMethod1(user, t1);
|
||||
assert euc.toString().indexOf("ConfigurableRunner") >= 0;
|
||||
assert euc.get().equals("okay");
|
||||
|
||||
Future<Object> eic = performSubmissionInSeparateMethod1(io, t1);
|
||||
assert eic.toString().indexOf("ConfigurableRunner") >= 0;
|
||||
assert eic.get().equals("okay");
|
||||
|
||||
|
||||
closer.close();
|
||||
}
|
||||
|
||||
/*
|
||||
* The decoration makes sure that the stack trace looks like the following.
|
||||
* Note the last three included trace elements: this details where the task was submitted _from_
|
||||
* (technically it is a different stack frame, since it is across threads; but logically it is the same)
|
||||
*
|
||||
java.util.concurrent.ExecutionException: java.lang.IllegalStateException: foo
|
||||
at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:222)
|
||||
at java.util.concurrent.FutureTask.get(FutureTask.java:83)
|
||||
at org.jclouds.concurrent.config.ExecutorServiceModule$DescribedFuture.get(ExecutorServiceModule.java:232)
|
||||
at org.jclouds.concurrent.config.ExecutorServiceModuleTest.checkFutureGetFailsWith(ExecutorServiceModuleTest.java:186)
|
||||
at org.jclouds.concurrent.config.ExecutorServiceModuleTest.testDescribedFutureExceptionIncludesSubmissionTrace(ExecutorServiceModuleTest.java:171)
|
||||
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
|
||||
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
|
||||
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
|
||||
at java.lang.reflect.Method.invoke(Method.java:597)
|
||||
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:80)
|
||||
at org.testng.internal.Invoker.invokeMethod(Invoker.java:691)
|
||||
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:883)
|
||||
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1208)
|
||||
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:127)
|
||||
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:111)
|
||||
at org.testng.TestRunner.privateRun(TestRunner.java:753)
|
||||
at org.testng.TestRunner.run(TestRunner.java:613)
|
||||
at org.testng.SuiteRunner.runTest(SuiteRunner.java:335)
|
||||
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:330)
|
||||
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:292)
|
||||
at org.testng.SuiteRunner.run(SuiteRunner.java:241)
|
||||
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
|
||||
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
|
||||
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1169)
|
||||
at org.testng.TestNG.runSuitesLocally(TestNG.java:1094)
|
||||
at org.testng.TestNG.run(TestNG.java:1006)
|
||||
at org.testng.remote.RemoteTestNG.run(RemoteTestNG.java:107)
|
||||
at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:199)
|
||||
at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:170)
|
||||
Caused by: java.lang.IllegalStateException: foo
|
||||
at org.jclouds.concurrent.config.ExecutorServiceModuleTest$ConfigurableRunner.call(ExecutorServiceModuleTest.java:206)
|
||||
at org.jclouds.concurrent.config.ExecutorServiceModuleTest$ConfigurableRunner.run(ExecutorServiceModuleTest.java:203)
|
||||
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
|
||||
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
|
||||
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
|
||||
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
|
||||
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
|
||||
at java.lang.Thread.run(Thread.java:637)
|
||||
at org.jclouds.concurrent.config.ExecutorServiceModule$DescribingExecutorService.submit(ExecutorServiceModule.java:188)
|
||||
at org.jclouds.concurrent.config.ExecutorServiceModuleTest.performSubmissionInSeparateMethod2(ExecutorServiceModuleTest.java:181)
|
||||
at org.jclouds.concurrent.config.ExecutorServiceModuleTest.testDescribedFutureExceptionIncludesSubmissionTrace(ExecutorServiceModuleTest.java:170)
|
||||
... 24 more
|
||||
|
||||
*
|
||||
*/
|
||||
@Test
|
||||
public void testDescribedFutureExceptionIncludesSubmissionTrace() throws Exception {
|
||||
|
||||
ExecutorServiceModule module = new ExecutorServiceModule() {
|
||||
@Override
|
||||
protected void configure() {
|
||||
bindConstant().annotatedWith(Names.named(Constants.PROPERTY_IO_WORKER_THREADS)).to(1);
|
||||
bindConstant().annotatedWith(Names.named(Constants.PROPERTY_USER_THREADS)).to(1);
|
||||
super.configure();
|
||||
}
|
||||
};
|
||||
|
||||
Injector i = Guice.createInjector(module);
|
||||
Closer closer = i.getInstance(Closer.class);
|
||||
|
||||
ExecutorService user = i
|
||||
.getInstance(Key.get(ExecutorService.class, Names.named(Constants.PROPERTY_USER_THREADS)));
|
||||
ExecutorService io = i.getInstance(Key.get(ExecutorService.class, Names
|
||||
.named(Constants.PROPERTY_IO_WORKER_THREADS)));
|
||||
|
||||
ConfigurableRunner t1 = new ConfigurableRunner();
|
||||
t1.failMessage = "foo";
|
||||
t1.result = "shouldn't happen";
|
||||
|
||||
Future<Object> euc = performSubmissionInSeparateMethod1(user, t1);
|
||||
checkFutureGetFailsWith(euc, "foo", "testDescribedFutureExceptionIncludesSubmissionTrace", "performSubmissionInSeparateMethod1");
|
||||
|
||||
Future<Object> eur = performSubmissionInSeparateMethod2(user, t1);
|
||||
checkFutureGetFailsWith(eur, "foo", "testDescribedFutureExceptionIncludesSubmissionTrace", "performSubmissionInSeparateMethod2");
|
||||
|
||||
Future<Object> eic = performSubmissionInSeparateMethod1(io, t1);
|
||||
checkFutureGetFailsWith(eic, "foo", "testDescribedFutureExceptionIncludesSubmissionTrace", "performSubmissionInSeparateMethod1");
|
||||
|
||||
Future<Object> eir = performSubmissionInSeparateMethod2(io, t1);
|
||||
checkFutureGetFailsWith(eir, "foo", "testDescribedFutureExceptionIncludesSubmissionTrace", "performSubmissionInSeparateMethod2");
|
||||
|
||||
closer.close();
|
||||
}
|
||||
|
||||
static Future<Object> performSubmissionInSeparateMethod1(ExecutorService user, ConfigurableRunner t1) {
|
||||
return user.submit((Callable<Object>)t1);
|
||||
}
|
||||
|
||||
static Future<Object> performSubmissionInSeparateMethod2(ExecutorService io, ConfigurableRunner t1) {
|
||||
return io.submit((Runnable)t1, (Object)"shouldn't happen");
|
||||
}
|
||||
|
||||
static void checkFutureGetFailsWith(Future<Object> task, String ...requiredPhrases) throws Exception {
|
||||
try {
|
||||
task.get();
|
||||
assert false : "task should have failed";
|
||||
} catch (ExecutionException e) {
|
||||
String trace = Throwables.getStackTraceAsString(e);
|
||||
for (String requiredPhrase : requiredPhrases) {
|
||||
assert trace.indexOf(requiredPhrase) >= 0 : "stack trace should have contained '"+requiredPhrase+"'";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class ConfigurableRunner implements Runnable, Callable<Object> {
|
||||
private Object result;
|
||||
private String failMessage;
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
call();
|
||||
}
|
||||
public Object call() {
|
||||
if (failMessage!=null) throw new IllegalStateException(failMessage);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
package org.jclouds.go2cloud.config;
|
||||
|
||||
import static org.jclouds.compute.domain.OsFamily.DEBIAN;
|
||||
import static org.jclouds.compute.domain.OsFamily.UBUNTU;
|
||||
|
||||
import org.jclouds.compute.domain.TemplateBuilder;
|
||||
import org.jclouds.elasticstack.compute.config.ElasticStackComputeServiceContextModule;
|
||||
|
@ -33,6 +33,6 @@ public class Go2CloudJohannesburg1ComputeServiceContextModule extends ElasticSta
|
|||
|
||||
@Override
|
||||
protected TemplateBuilder provideTemplate(Injector injector, TemplateBuilder template) {
|
||||
return template.osFamily(DEBIAN).osVersionMatches("6.0").os64Bit(true);
|
||||
return template.osFamily(UBUNTU).osVersionMatches("10.10").os64Bit(true);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
[
|
||||
{
|
||||
"uuid": "14c88d27-1f5e-4ad5-9f3a-28e5d2282f61",
|
||||
"description": "Ubuntu 10.10",
|
||||
"osFamily": "UBUNTU",
|
||||
"osVersion": "10.10",
|
||||
"size": "1"
|
||||
},
|
||||
{
|
||||
"uuid": "cc54132d-4912-4106-a91a-7a27e6866c8b",
|
||||
"description": "Debian 6.0.2.1",
|
||||
"osFamily": "DEBIAN",
|
||||
"osVersion": "6.0",
|
||||
"size": "1"
|
||||
},
|
||||
{
|
||||
"uuid": "77ad0ffe-9537-4c64-a8e3-10db185261c0",
|
||||
"description": "Windows 2008 R2 (x64) with SP1",
|
||||
"osFamily": "WINDOWS",
|
||||
"osVersion": "2008 R2",
|
||||
"size": "13"
|
||||
},
|
||||
{
|
||||
"uuid": "d971ddfb-7a69-48f7-8d14-a76ef61b01d8",
|
||||
"description": "Windows 8 Developer Preview (x64)",
|
||||
"osFamily": "WINDOWS",
|
||||
"osVersion": "8",
|
||||
"size": "13"
|
||||
}
|
||||
]
|
|
@ -25,10 +25,10 @@ import org.testng.annotations.Test;
|
|||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "live", sequential = true)
|
||||
@Test(groups = "live", singleThreaded = true)
|
||||
public class Go2CloudJohannesburg1ClientLiveTest extends ElasticStackClientLiveTest {
|
||||
public Go2CloudJohannesburg1ClientLiveTest() {
|
||||
provider = "go2cloud-jhb1";
|
||||
bootDrive = "5192adbd-046f-4a48-90f9-3db390b1efab";
|
||||
bootDrive = "14c88d27-1f5e-4ad5-9f3a-28e5d2282f61";
|
||||
}
|
||||
}
|
|
@ -52,6 +52,8 @@ public class Go2CloudJohannesburg1TemplateBuilderLiveTest extends BaseTemplateBu
|
|||
@Override
|
||||
public boolean apply(OsFamilyVersion64Bit input) {
|
||||
switch (input.family) {
|
||||
case UBUNTU:
|
||||
return (input.version.equals("") || input.version.equals("10.10")) && input.is64Bit;
|
||||
case DEBIAN:
|
||||
return (input.version.equals("") || input.version.equals("6.0")) && input.is64Bit;
|
||||
case WINDOWS:
|
||||
|
@ -68,8 +70,8 @@ public class Go2CloudJohannesburg1TemplateBuilderLiveTest extends BaseTemplateBu
|
|||
public void testDefaultTemplateBuilder() throws IOException {
|
||||
Template defaultTemplate = this.context.getComputeService().templateBuilder().build();
|
||||
assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true);
|
||||
assertEquals(defaultTemplate.getImage().getOperatingSystem().getVersion(), "6.0");
|
||||
assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.DEBIAN);
|
||||
assertEquals(defaultTemplate.getImage().getOperatingSystem().getVersion(), "10.10");
|
||||
assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.UBUNTU);
|
||||
assertEquals(defaultTemplate.getLocation().getId(), "go2cloud-jhb1");
|
||||
assertEquals(getCores(defaultTemplate.getHardware()), 1.0d);
|
||||
}
|
|
@ -35,7 +35,7 @@
|
|||
|
||||
<properties>
|
||||
<test.openhosting-east1.endpoint>https://api.east1.openhosting.com</test.openhosting-east1.endpoint>
|
||||
<test.openhosting-east1.apiversion>1.0</test.openhosting-east1.apiversion>
|
||||
<test.openhosting-east1.apiversion>2.0</test.openhosting-east1.apiversion>
|
||||
<test.openhosting-east1.identity>FIXME_IDENTITY</test.openhosting-east1.identity>
|
||||
<test.openhosting-east1.credential>FIXME_CREDENTIAL</test.openhosting-east1.credential>
|
||||
</properties>
|
||||
|
|
|
@ -35,9 +35,9 @@ public class OpenHostingEast1PropertiesBuilder extends ElasticStackPropertiesBui
|
|||
@Override
|
||||
protected Properties defaultProperties() {
|
||||
Properties properties = super.defaultProperties();
|
||||
properties.setProperty(PROPERTY_ISO3166_CODES, "US-VA");
|
||||
properties.setProperty(PROPERTY_ISO3166_CODES, "US-FL");
|
||||
properties.setProperty(PROPERTY_ENDPOINT, "https://api.east1.openhosting.com");
|
||||
properties.setProperty(PROPERTY_API_VERSION, "1.0");
|
||||
properties.setProperty(PROPERTY_API_VERSION, "2.0");
|
||||
return properties;
|
||||
}
|
||||
|
||||
|
|
|
@ -102,7 +102,7 @@ public class OpenHostingEast1ProviderMetadata extends BaseProviderMetadata {
|
|||
*/
|
||||
@Override
|
||||
public Set<String> getIso3166Codes() {
|
||||
return ImmutableSet.of("US-VA");
|
||||
return ImmutableSet.of("US-FL");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -78,6 +78,6 @@ public class OpenHostingEast1TemplateBuilderLiveTest extends BaseTemplateBuilder
|
|||
|
||||
@Override
|
||||
protected Set<String> getIso3166Codes() {
|
||||
return ImmutableSet.<String> of("US-VA");
|
||||
return ImmutableSet.<String> of("US-FL");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,5 +62,6 @@
|
|||
<module>savvis-symphonyvpdc</module>
|
||||
<module>greenhousedata-element-vcloud</module>
|
||||
<module>aws-cloudwatch</module>
|
||||
<module>go2cloud-jhb1</module>
|
||||
</modules>
|
||||
</project>
|
||||
|
|
|
@ -69,6 +69,7 @@ public class VirtualBoxPropertiesBuilder extends PropertiesBuilder {
|
|||
"jclouds-virtualbox-test"));
|
||||
|
||||
// TODO: Add more properties and use the wired properties from test code.
|
||||
properties.put(VirtualBoxConstants.VIRTUALBOX_DISTRO_ISO_NAME, "ubuntu-11.04-server-i386.iso");
|
||||
return properties;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,19 +21,27 @@
|
|||
|
||||
package org.jclouds.virtualbox.compute;
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.inject.Singleton;
|
||||
import org.jclouds.compute.ComputeServiceAdapter;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.virtualbox.domain.Host;
|
||||
import org.virtualbox_4_1.*;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.jclouds.compute.ComputeServiceAdapter;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.location.suppliers.JustProvider;
|
||||
import org.virtualbox_4_1.CleanupMode;
|
||||
import org.virtualbox_4_1.IMachine;
|
||||
import org.virtualbox_4_1.IProgress;
|
||||
import org.virtualbox_4_1.ISession;
|
||||
import org.virtualbox_4_1.SessionState;
|
||||
import org.virtualbox_4_1.VirtualBoxManager;
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.inject.Singleton;
|
||||
|
||||
/**
|
||||
* Defines the connection between the {@link org.virtualbox_4_1.VirtualBoxManager} implementation and the jclouds
|
||||
|
@ -42,13 +50,15 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||
* @author Mattias Holmqvist, Andrea Turli
|
||||
*/
|
||||
@Singleton
|
||||
public class VirtualBoxComputeServiceAdapter implements ComputeServiceAdapter<IMachine, IMachine, IMachine, Host> {
|
||||
public class VirtualBoxComputeServiceAdapter implements ComputeServiceAdapter<IMachine, IMachine, IMachine, Location> {
|
||||
|
||||
private final VirtualBoxManager manager;
|
||||
private final JustProvider justProvider;
|
||||
|
||||
@Inject
|
||||
public VirtualBoxComputeServiceAdapter(VirtualBoxManager manager) {
|
||||
public VirtualBoxComputeServiceAdapter(VirtualBoxManager manager, JustProvider justProvider) {
|
||||
this.manager = checkNotNull(manager, "manager");
|
||||
this.justProvider = checkNotNull(justProvider, "justProvider");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -63,17 +73,18 @@ public class VirtualBoxComputeServiceAdapter implements ComputeServiceAdapter<IM
|
|||
|
||||
@Override
|
||||
public Iterable<IMachine> listHardwareProfiles() {
|
||||
return Collections.emptyList();
|
||||
return manager.getVBox().getMachines();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<IMachine> listImages() {
|
||||
return Collections.emptyList();
|
||||
return manager.getVBox().getMachines();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public Iterable<Host> listLocations() {
|
||||
return Collections.emptyList();
|
||||
public Iterable<Location> listLocations() {
|
||||
return (Iterable<Location>) justProvider.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -21,23 +21,26 @@
|
|||
|
||||
package org.jclouds.virtualbox.config;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Provides;
|
||||
import com.google.inject.TypeLiteral;
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.Constants;
|
||||
import org.jclouds.compute.ComputeServiceAdapter;
|
||||
import org.jclouds.compute.config.ComputeServiceAdapterContextModule;
|
||||
import org.jclouds.compute.domain.*;
|
||||
import org.jclouds.compute.domain.Hardware;
|
||||
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.domain.Location;
|
||||
import org.jclouds.functions.IdentityFunction;
|
||||
import org.jclouds.location.Provider;
|
||||
import org.jclouds.location.suppliers.OnlyLocationOrFirstZone;
|
||||
import org.jclouds.virtualbox.compute.VirtualBoxComputeServiceAdapter;
|
||||
import org.jclouds.virtualbox.domain.Host;
|
||||
import org.jclouds.virtualbox.functions.HostToLocation;
|
||||
import org.jclouds.virtualbox.functions.IMachineToHardware;
|
||||
import org.jclouds.virtualbox.functions.IMachineToImage;
|
||||
import org.jclouds.virtualbox.functions.IMachineToNodeMetadata;
|
||||
|
@ -45,15 +48,18 @@ import org.virtualbox_4_1.IMachine;
|
|||
import org.virtualbox_4_1.MachineState;
|
||||
import org.virtualbox_4_1.VirtualBoxManager;
|
||||
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Provides;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
||||
/**
|
||||
* @author Mattias Holmqvist, Andrea Turli
|
||||
*/
|
||||
public class VirtualBoxComputeServiceContextModule extends ComputeServiceAdapterContextModule<VirtualBoxManager, VirtualBoxManager, IMachine, IMachine, IMachine, Host> {
|
||||
public class VirtualBoxComputeServiceContextModule extends ComputeServiceAdapterContextModule<VirtualBoxManager, VirtualBoxManager, IMachine, IMachine, IMachine, Location> {
|
||||
|
||||
public VirtualBoxComputeServiceContextModule() {
|
||||
super(VirtualBoxManager.class, VirtualBoxManager.class);
|
||||
|
@ -68,15 +74,16 @@ public class VirtualBoxComputeServiceContextModule extends ComputeServiceAdapter
|
|||
return manager;
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
@Override
|
||||
protected void configure() {
|
||||
super.configure();
|
||||
bind(new TypeLiteral<ComputeServiceAdapter<IMachine, IMachine, IMachine, Host>>() {
|
||||
bind(new TypeLiteral<ComputeServiceAdapter<IMachine, IMachine, IMachine, Location>>() {
|
||||
}).to(VirtualBoxComputeServiceAdapter.class);
|
||||
bind(new TypeLiteral<Function<IMachine, NodeMetadata>>() {
|
||||
}).to(IMachineToNodeMetadata.class);
|
||||
bind(new TypeLiteral<Function<Host, Location>>() {
|
||||
}).to(HostToLocation.class);
|
||||
bind(new TypeLiteral<Function<Location, Location>>() {
|
||||
}).to((Class) IdentityFunction.class);
|
||||
bind(new TypeLiteral<Function<IMachine, Hardware>>() {
|
||||
}).to(IMachineToHardware.class);
|
||||
bind(new TypeLiteral<Function<IMachine, Image>>() {
|
||||
|
|
|
@ -50,4 +50,6 @@ public interface VirtualBoxConstants {
|
|||
public static final String VIRTUALBOX_MACHINE_LOCATION = "jclouds.virtualbox.location";
|
||||
|
||||
public static final String VIRTUALBOX_HOST_ID = "jclouds.virtualbox.hostid";
|
||||
|
||||
public static final String VIRTUALBOX_DISTRO_ISO_NAME = "jclouds.virtualbox.distroIsoName";
|
||||
}
|
||||
|
|
|
@ -1,25 +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.domain;
|
||||
|
||||
public class Host {
|
||||
}
|
|
@ -1,36 +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;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.domain.LocationBuilder;
|
||||
import org.jclouds.javax.annotation.Nullable;
|
||||
import org.jclouds.virtualbox.domain.Host;
|
||||
|
||||
public class HostToLocation implements Function<Host, Location> {
|
||||
@Override
|
||||
public Location apply(@Nullable Host input) {
|
||||
LocationBuilder locationBuilder = new LocationBuilder();
|
||||
return locationBuilder.build();
|
||||
}
|
||||
}
|
|
@ -21,36 +21,39 @@
|
|||
|
||||
package org.jclouds.virtualbox.functions;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.jclouds.compute.domain.Hardware;
|
||||
import org.jclouds.compute.domain.HardwareBuilder;
|
||||
import org.jclouds.compute.predicates.ImagePredicates;
|
||||
import org.jclouds.javax.annotation.Nullable;
|
||||
import org.jclouds.virtualbox.VirtualBox;
|
||||
import org.virtualbox_4_1.IGuestOSType;
|
||||
import org.virtualbox_4_1.IMachine;
|
||||
import org.virtualbox_4_1.VirtualBoxManager;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import com.google.common.base.Function;
|
||||
|
||||
public class IMachineToHardware implements Function<IMachine, Hardware> {
|
||||
|
||||
private VirtualBox vbox;
|
||||
private VirtualBoxManager virtualBoxManager;
|
||||
|
||||
@Inject
|
||||
public IMachineToHardware(VirtualBox vbox) {
|
||||
this.vbox = vbox;
|
||||
public IMachineToHardware(VirtualBoxManager virtualBoxManager) {
|
||||
this.virtualBoxManager = virtualBoxManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Hardware apply(@Nullable IMachine vm) {
|
||||
String osTypeId = vm.getOSTypeId();
|
||||
|
||||
IGuestOSType guestOSType = vbox.manager().getVBox().getGuestOSType(osTypeId);
|
||||
|
||||
IGuestOSType guestOSType = virtualBoxManager.getVBox().getGuestOSType(osTypeId);
|
||||
Boolean is64Bit = guestOSType.getIs64Bit();
|
||||
HardwareBuilder hardwareBuilder = new HardwareBuilder();
|
||||
hardwareBuilder.ids(vm.getId());
|
||||
vm.getSessionPid();
|
||||
hardwareBuilder.supportsImage(ImagePredicates.idEquals(vm.getId()));
|
||||
hardwareBuilder.is64Bit(is64Bit);
|
||||
hardwareBuilder.supportsImage(ImagePredicates.idEquals(vm.getId()));
|
||||
return hardwareBuilder.build();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,26 +21,22 @@
|
|||
|
||||
package org.jclouds.virtualbox.functions;
|
||||
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
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.javax.annotation.Nullable;
|
||||
import org.jclouds.virtualbox.VirtualBox;
|
||||
import org.virtualbox_4_1.IGuestOSType;
|
||||
import org.virtualbox_4_1.IMachine;
|
||||
import org.virtualbox_4_1.VirtualBoxManager;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import javax.inject.Inject;
|
||||
|
||||
|
||||
public class IMachineToImage implements Function<IMachine, Image> {
|
||||
|
||||
private static final String UBUNTU = "Ubuntu Linux";
|
||||
private static final String UBUNTU = "Ubuntu";
|
||||
|
||||
private VirtualBoxManager virtualboxManager;
|
||||
|
||||
|
@ -52,15 +48,14 @@ public class IMachineToImage implements Function<IMachine, Image> {
|
|||
@Override
|
||||
public Image apply(@Nullable IMachine from) {
|
||||
|
||||
Boolean is64Bit = virtualboxManager.getVBox().getGuestOSType(from.getOSTypeId()).getIs64Bit();
|
||||
IGuestOSType guestOSType = virtualboxManager.getVBox().getGuestOSType(from.getOSTypeId());
|
||||
|
||||
//Somehow this method gets called with the correct product item.
|
||||
OsFamily family = osFamily().apply(from);
|
||||
OsFamily family = osFamily().apply(guestOSType.getDescription());
|
||||
OperatingSystem os = OperatingSystem.builder()
|
||||
.description(from.getDescription())
|
||||
.description(guestOSType.getDescription())
|
||||
.family(family)
|
||||
.version(osVersion().apply(from))
|
||||
.is64Bit(is64Bit)
|
||||
.version(osVersion().apply(guestOSType.getDescription()))
|
||||
.is64Bit(guestOSType.getIs64Bit())
|
||||
.build();
|
||||
|
||||
return new ImageBuilder()
|
||||
|
@ -72,14 +67,15 @@ public class IMachineToImage implements Function<IMachine, Image> {
|
|||
|
||||
/**
|
||||
* Parses the item description to determine the OSFamily
|
||||
*
|
||||
* @return the @see OsFamily or OsFamily.UNRECOGNIZED
|
||||
*/
|
||||
public static Function<IMachine, OsFamily> osFamily() {
|
||||
return new Function<IMachine,OsFamily>() {
|
||||
public static Function<String, OsFamily> osFamily() {
|
||||
|
||||
return new Function<String, OsFamily>() {
|
||||
@Override
|
||||
public OsFamily apply(IMachine iMachine) {
|
||||
final String description = iMachine.getDescription();
|
||||
if ( description.startsWith(UBUNTU) ) return OsFamily.UBUNTU;
|
||||
public OsFamily apply(String osDescription) {
|
||||
if (osDescription.startsWith(UBUNTU)) return OsFamily.UBUNTU;
|
||||
return OsFamily.UNRECOGNIZED;
|
||||
}
|
||||
};
|
||||
|
@ -87,17 +83,18 @@ public class IMachineToImage implements Function<IMachine, Image> {
|
|||
|
||||
/**
|
||||
* Parses the item description to determine the os version
|
||||
* @return the version
|
||||
* @throws java.util.NoSuchElementException if the version cannot be determined
|
||||
*
|
||||
* @return the version, empty if not found
|
||||
*/
|
||||
public static Function<IMachine, String> osVersion() {
|
||||
return new Function<IMachine, String>() {
|
||||
public static Function<String, String> osVersion() {
|
||||
return new Function<String, String>() {
|
||||
@Override
|
||||
public String apply(IMachine iMachine) {
|
||||
final String description = iMachine.getDescription();
|
||||
OsFamily family = osFamily().apply(iMachine);
|
||||
if(family.equals(OsFamily.UBUNTU)) return parseVersion(description, UBUNTU);
|
||||
else throw new NoSuchElementException("No os parseVersion for item:" + iMachine);
|
||||
public String apply(String osDescription) {
|
||||
OsFamily family = osFamily().apply(osDescription);
|
||||
if (family.equals(OsFamily.UBUNTU))
|
||||
return parseVersion(osDescription, UBUNTU);
|
||||
else
|
||||
return "";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -34,6 +34,11 @@ import javax.annotation.Nullable;
|
|||
|
||||
import static org.jclouds.compute.options.RunScriptOptions.Builder.runAsRoot;
|
||||
|
||||
/**
|
||||
* Get an IP address from an IMachine using arp of the host machine.
|
||||
*
|
||||
* @author Mattias Holmqvist, Andrea Turli
|
||||
*/
|
||||
public class IMachineToIpAddress implements Function<IMachine, String> {
|
||||
|
||||
private VirtualBoxManager manager;
|
||||
|
@ -67,13 +72,13 @@ public class IMachineToIpAddress implements Function<IMachine, String> {
|
|||
simplifiedMacAddressOfClonedVM = new StringBuffer(simplifiedMacAddressOfClonedVM).delete(simplifiedMacAddressOfClonedVM.indexOf("0"), simplifiedMacAddressOfClonedVM.indexOf("0") + 1).toString();
|
||||
}
|
||||
|
||||
// TODO: This is both shell-dependent and hard-coded. Needs to be fixed.
|
||||
ExecResponse execResponse = runScriptOnNode(hostId, "for i in {1..254} ; do ping -c 1 -t 1 192.168.2.$i & done", runAsRoot(false).wrapInInitScript(false));
|
||||
System.out.println(execResponse);
|
||||
|
||||
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);
|
||||
|
||||
return ipAddress;
|
||||
}
|
||||
|
||||
|
@ -84,8 +89,7 @@ public class IMachineToIpAddress implements Function<IMachine, String> {
|
|||
protected boolean isOSX(IMachine machine) {
|
||||
String osTypeId = machine.getOSTypeId();
|
||||
IGuestOSType guestOSType = manager.getVBox().getGuestOSType(osTypeId);
|
||||
String familyDescription = guestOSType.getFamilyDescription();
|
||||
return true;
|
||||
return guestOSType.getFamilyDescription().equals("Other");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,229 @@
|
|||
/*
|
||||
* *
|
||||
* * 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;
|
||||
|
||||
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.File;
|
||||
|
||||
import org.jclouds.compute.ComputeServiceContext;
|
||||
import org.jclouds.compute.domain.ExecResponse;
|
||||
import org.jclouds.compute.options.RunScriptOptions;
|
||||
import org.jclouds.javax.annotation.Nullable;
|
||||
import org.jclouds.virtualbox.config.VirtualBoxConstants;
|
||||
import org.jclouds.virtualbox.experiment.settings.KeyboardScancodes;
|
||||
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.NetworkAttachmentType;
|
||||
import org.virtualbox_4_1.StorageBus;
|
||||
import org.virtualbox_4_1.VirtualBoxManager;
|
||||
import org.virtualbox_4_1.jaxws.MediumVariant;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.inject.Inject;
|
||||
|
||||
public class IsoToIMachine implements Function<String, IMachine> {
|
||||
|
||||
private VirtualBoxManager manager;
|
||||
private String adminDisk;
|
||||
private String diskFormat;
|
||||
private String settingsFile;
|
||||
private String vmName;
|
||||
private String osTypeId;
|
||||
private String vmId;
|
||||
private String controllerIDE;
|
||||
private boolean forceOverwrite;
|
||||
private ComputeServiceContext context;
|
||||
private String hostId;
|
||||
private String guestId;
|
||||
|
||||
@Inject
|
||||
public IsoToIMachine(VirtualBoxManager manager, String adminDisk,
|
||||
String diskFormat, String settingsFile, String vmName,
|
||||
String osTypeId, String vmId, boolean forceOverwrite,
|
||||
String controllerIDE, ComputeServiceContext context, String hostId,
|
||||
String guestId) {
|
||||
super();
|
||||
this.manager = manager;
|
||||
this.adminDisk = adminDisk;
|
||||
this.diskFormat = diskFormat;
|
||||
this.settingsFile = settingsFile;
|
||||
this.vmName = vmName;
|
||||
this.osTypeId = osTypeId;
|
||||
this.vmId = vmId;
|
||||
this.controllerIDE = controllerIDE;
|
||||
this.forceOverwrite = forceOverwrite;
|
||||
this.context = context;
|
||||
this.hostId = hostId;
|
||||
this.guestId = guestId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IMachine apply(@Nullable String isoName) {
|
||||
IMachine vm = manager.getVBox().createMachine(settingsFile, vmName,
|
||||
osTypeId, vmId, forceOverwrite);
|
||||
assertNotNull(vm.getName());
|
||||
|
||||
IMedium distroMedium = manager.getVBox().openMedium(
|
||||
VirtualBoxConstants.VIRTUALBOX_WORKINGDIR + "/" + isoName,
|
||||
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.addStorageController(controllerIDE, StorageBus.IDE);
|
||||
// assertEquals(manager.getVBox().findMachine(vmName).getStorageControllers().size(),
|
||||
// 1);
|
||||
|
||||
mutable.saveSettings();
|
||||
|
||||
// CONTROLLER
|
||||
mutable.attachDevice(controllerIDE, 0, 0, DeviceType.DVD, distroMedium);
|
||||
mutable.saveSettings();
|
||||
|
||||
// DISK
|
||||
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;
|
||||
hd.createBaseStorage(new Long(size),
|
||||
new Long(MediumVariant.STANDARD.ordinal()));
|
||||
mutable.attachDevice(controllerIDE, 0, 1, DeviceType.HardDisk, hd);
|
||||
mutable.saveSettings();
|
||||
assertEquals(hd.getId().equals(""), false);
|
||||
|
||||
// NIC
|
||||
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();
|
||||
|
||||
launchVMProcess(machine, session);
|
||||
assertEquals(machine.getState(), MachineState.Running);
|
||||
try {
|
||||
Thread.sleep(5000);
|
||||
} catch (InterruptedException e) {
|
||||
propagate(e);
|
||||
}
|
||||
|
||||
try {
|
||||
sendKeyboardSequence(VirtualBoxConstants.VIRTUALBOX_INSTALLATION_KEY_SEQUENCE);
|
||||
} catch (InterruptedException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
session.unlockMachine();
|
||||
|
||||
return vm;
|
||||
}
|
||||
|
||||
private void launchVMProcess(IMachine machine, ISession session) {
|
||||
IProgress prog = machine.launchVMProcess(session, "gui", "");
|
||||
prog.waitForCompletion(-1);
|
||||
session.unlockMachine();
|
||||
}
|
||||
|
||||
private 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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
ExecResponse toReturn = context.getComputeService().runScriptOnNode(
|
||||
nodeId, command, options);
|
||||
assert toReturn.getExitCode() == 0 : toReturn;
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
protected ExecResponse runScriptOnNode(String nodeId, String command) {
|
||||
return runScriptOnNode(nodeId, command, wrapInInitScript(false));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
/**
|
||||
* 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;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import org.jclouds.compute.ComputeServiceContext;
|
||||
import org.jclouds.compute.ComputeServiceContextFactory;
|
||||
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
|
||||
import org.jclouds.sshj.config.SshjSshClientModule;
|
||||
import org.testng.annotations.AfterGroups;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.BeforeGroups;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.inject.Module;
|
||||
|
||||
/**
|
||||
* Tests behavior of {@code VirtualBoxClient}
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "live")
|
||||
public class BaseVirtualBoxClientLiveTest {
|
||||
|
||||
protected String provider = "virtualbox";
|
||||
protected String identity;
|
||||
protected String credential;
|
||||
protected String endpoint;
|
||||
protected String apiversion;
|
||||
|
||||
@BeforeClass
|
||||
protected void setupCredentials() {
|
||||
identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
|
||||
credential = System.getProperty("test." + provider + ".credential");
|
||||
endpoint = System.getProperty("test." + provider + ".endpoint", "http://localhost:18083/");
|
||||
apiversion = System.getProperty("test." + provider + ".apiversion", "4.1.2r73507");
|
||||
}
|
||||
|
||||
protected ComputeServiceContext context;
|
||||
|
||||
@BeforeGroups(groups = { "live" })
|
||||
public void setupClient() {
|
||||
Properties properties = new Properties();
|
||||
properties.setProperty(provider + ".endpoint", endpoint);
|
||||
properties.setProperty(provider + ".apiversion", apiversion);
|
||||
context = new ComputeServiceContextFactory().createContext(provider, identity, credential,
|
||||
ImmutableSet.<Module> of(new Log4JLoggingModule(), new SshjSshClientModule()));
|
||||
}
|
||||
|
||||
@AfterGroups(groups = "live")
|
||||
protected void tearDown() {
|
||||
if (context != null)
|
||||
context.close();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,127 @@
|
|||
/**
|
||||
* 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.compute;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertFalse;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jclouds.compute.domain.ExecResponse;
|
||||
import org.jclouds.compute.domain.Image;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.location.suppliers.JustProvider;
|
||||
import org.jclouds.net.IPSocket;
|
||||
import org.jclouds.ssh.SshClient;
|
||||
import org.jclouds.virtualbox.BaseVirtualBoxClientLiveTest;
|
||||
import org.jclouds.virtualbox.functions.IMachineToImage;
|
||||
import org.testng.annotations.AfterGroups;
|
||||
import org.testng.annotations.BeforeGroups;
|
||||
import org.testng.annotations.Test;
|
||||
import org.virtualbox_4_1.IMachine;
|
||||
import org.virtualbox_4_1.VirtualBoxManager;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
@Test(groups = "live", singleThreaded = true, testName = "VirtualBoxComputeServiceAdapterLiveTest")
|
||||
public class VirtualBoxComputeServiceAdapterLiveTest extends BaseVirtualBoxClientLiveTest {
|
||||
|
||||
private VirtualBoxComputeServiceAdapter adapter;
|
||||
private IMachine machine;
|
||||
|
||||
@BeforeGroups(groups = { "live" })
|
||||
public void setupClient() {
|
||||
super.setupClient();
|
||||
adapter = new VirtualBoxComputeServiceAdapter(getManager(),
|
||||
new JustProvider(ImmutableSet.<String> of(), provider, URI.create(endpoint)));
|
||||
}
|
||||
|
||||
protected VirtualBoxManager getManager() {
|
||||
return (VirtualBoxManager) context.getProviderSpecificContext().getApi();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testListLocations() {
|
||||
assertFalse(Iterables.isEmpty(adapter.listLocations()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateNodeWithGroupEncodedIntoNameThenStoreCredentials() {
|
||||
String group = "foo";
|
||||
String name = "foo-ef4";
|
||||
Template template = context.getComputeService().templateBuilder().build();
|
||||
Map<String, Credentials> credentialStore = Maps.newLinkedHashMap();
|
||||
machine = adapter.createNodeWithGroupEncodedIntoNameThenStoreCredentials(group, name, template, credentialStore);
|
||||
assertEquals(machine.getName(), name);
|
||||
// is there a place for group?
|
||||
// check other things, like cpu correct, mem correct, image/os is correct
|
||||
// (as possible)
|
||||
assert credentialStore.containsKey("node#" + machine.getId()) : "credentials to log into machine not found "
|
||||
+ machine;
|
||||
// TODO: what's the IP address?
|
||||
// assert InetAddresses.isInetAddress(machine.getPrimaryBackendIpAddress()) : machine;
|
||||
doConnectViaSsh(machine, credentialStore.get("node#" + machine.getId()));
|
||||
}
|
||||
|
||||
protected void doConnectViaSsh(IMachine machine, Credentials creds) {
|
||||
SshClient ssh = context.utils().sshFactory()
|
||||
.create(new IPSocket("//TODO", 22), creds);
|
||||
try {
|
||||
ssh.connect();
|
||||
ExecResponse hello = ssh.exec("echo hello");
|
||||
assertEquals(hello.getOutput().trim(), "hello");
|
||||
System.err.println(ssh.exec("df -k").getOutput());
|
||||
System.err.println(ssh.exec("mount").getOutput());
|
||||
System.err.println(ssh.exec("uname -a").getOutput());
|
||||
} finally {
|
||||
if (ssh != null)
|
||||
ssh.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testListHardwareProfiles() {
|
||||
Iterable<IMachine> profiles = adapter.listHardwareProfiles();
|
||||
assertFalse(Iterables.isEmpty(profiles));
|
||||
// check state;
|
||||
}
|
||||
@Test
|
||||
public void testListImages() {
|
||||
IMachineToImage iMachineToImage = new IMachineToImage(getManager());
|
||||
|
||||
Iterable<IMachine> iMachineIterable = adapter.listImages();
|
||||
for (IMachine iMachine : iMachineIterable) {
|
||||
Image image = iMachineToImage.apply(iMachine);
|
||||
System.out.println(image);
|
||||
}
|
||||
// check state;
|
||||
}
|
||||
|
||||
@AfterGroups(groups = "live")
|
||||
protected void tearDown() {
|
||||
if (machine != null)
|
||||
adapter.destroyNode(machine.getId() + "");
|
||||
super.tearDown();
|
||||
}
|
||||
}
|
|
@ -1,88 +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.compute;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.inject.Module;
|
||||
import org.jclouds.compute.BaseComputeServiceLiveTest;
|
||||
import org.jclouds.compute.ComputeServiceContext;
|
||||
import org.jclouds.compute.ComputeServiceContextFactory;
|
||||
import org.jclouds.compute.StandaloneComputeServiceContextSpec;
|
||||
import org.jclouds.sshj.config.SshjSshClientModule;
|
||||
import org.jclouds.virtualbox.VirtualBox;
|
||||
import org.jclouds.virtualbox.VirtualBoxContextBuilder;
|
||||
import org.jclouds.virtualbox.domain.Host;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.Test;
|
||||
import org.virtualbox_4_1.IMachine;
|
||||
import org.virtualbox_4_1.VirtualBoxManager;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
@Test(groups = "live")
|
||||
public class VirtualBoxComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
||||
|
||||
public VirtualBoxComputeServiceLiveTest() {
|
||||
provider = "virtualbox";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Module getSshModule() {
|
||||
return new SshjSshClientModule();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Properties setupRestProperties() {
|
||||
Properties restProperties = new Properties();
|
||||
restProperties.setProperty("virtualbox.contextbuilder", VirtualBoxContextBuilder.class.getName());
|
||||
restProperties.setProperty("virtualbox.endpoint", "http://localhost:18083/");
|
||||
restProperties.setProperty("virtualbox.apiversion", "4.1.2r73507");
|
||||
return restProperties;
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
protected void setupCredentials() {
|
||||
identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
|
||||
credential = System.getProperty("test." + provider + ".credential");
|
||||
endpoint = System.getProperty("test." + provider + ".endpoint");
|
||||
apiversion = System.getProperty("test." + provider + ".apiversion");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAndExperiment() {
|
||||
ComputeServiceContext context = null;
|
||||
try {
|
||||
context = new ComputeServiceContextFactory()
|
||||
.createContext(new StandaloneComputeServiceContextSpec<VirtualBoxManager, IMachine, IMachine, IMachine, Host>(
|
||||
"virtualbox", endpoint, apiversion, "", identity, credential, VirtualBoxManager.class,
|
||||
VirtualBoxContextBuilder.class, ImmutableSet.<Module>of()));
|
||||
|
||||
context.getComputeService().listNodes();
|
||||
|
||||
} finally {
|
||||
if (context != null)
|
||||
context.close();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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.compute;
|
||||
|
||||
import org.jclouds.virtualbox.BaseVirtualBoxClientLiveTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "live", testName = "VirtualBoxExperimentLiveTest")
|
||||
public class VirtualBoxExperimentLiveTest extends BaseVirtualBoxClientLiveTest{
|
||||
|
||||
@Test
|
||||
public void testAndExperiment() {
|
||||
context.getComputeService().listNodes();
|
||||
}
|
||||
|
||||
}
|
|
@ -174,7 +174,7 @@ public class KickstartTest2 {
|
|||
}
|
||||
|
||||
private void runAll() throws Exception {
|
||||
context = TestUtils.computeServiceForLocalhost();
|
||||
context = TestUtils.computeServiceForLocalhostAndGuest();
|
||||
socketTester = new RetryablePredicate<IPSocket>(
|
||||
new InetSocketAddressConnect(), 130, 10, TimeUnit.SECONDS);
|
||||
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* *
|
||||
* * 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;
|
||||
|
||||
import static org.easymock.EasyMock.eq;
|
||||
import static org.easymock.EasyMock.expect;
|
||||
import static org.easymock.classextension.EasyMock.createNiceMock;
|
||||
import static org.easymock.classextension.EasyMock.replay;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import org.jclouds.compute.domain.Hardware;
|
||||
import org.jclouds.compute.predicates.ImagePredicates;
|
||||
import org.testng.annotations.Test;
|
||||
import org.virtualbox_4_1.IGuestOSType;
|
||||
import org.virtualbox_4_1.IMachine;
|
||||
import org.virtualbox_4_1.IVirtualBox;
|
||||
import org.virtualbox_4_1.VirtualBoxManager;
|
||||
|
||||
@Test(groups = "unit")
|
||||
public class IMachineToHardwareTest {
|
||||
|
||||
@Test
|
||||
public void testConvert() throws Exception {
|
||||
VirtualBoxManager vbm = createNiceMock(VirtualBoxManager.class);
|
||||
IVirtualBox vBox = createNiceMock(IVirtualBox.class);
|
||||
IMachine vm = createNiceMock(IMachine.class);
|
||||
IGuestOSType guestOsType = createNiceMock(IGuestOSType.class);
|
||||
|
||||
String linuxDescription = "Ubuntu Linux 10.04";
|
||||
String machineId = "hw-machineId";
|
||||
|
||||
expect(vm.getOSTypeId()).andReturn("os-type").anyTimes();
|
||||
expect(vm.getId()).andReturn(machineId).anyTimes();
|
||||
|
||||
expect(vm.getDescription()).andReturn(linuxDescription).anyTimes();
|
||||
|
||||
expect(vBox.getGuestOSType(eq("os-type"))).andReturn(guestOsType);
|
||||
expect(vbm.getVBox()).andReturn(vBox);
|
||||
expect(guestOsType.getIs64Bit()).andReturn(true);
|
||||
|
||||
replay(vbm, vBox, vm, guestOsType);
|
||||
|
||||
Hardware hardware = new IMachineToHardware(vbm).apply(vm);
|
||||
|
||||
assertEquals(hardware.getId(), machineId);
|
||||
assertEquals(hardware.getProviderId(), machineId);
|
||||
// for starters assume 1-to-1 relationship hardware to image (which
|
||||
// correlate to a single source IMachine)
|
||||
assertEquals(hardware.supportsImage().toString(), ImagePredicates.idEquals(machineId).toString());
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* *
|
||||
* * 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;
|
||||
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import org.jclouds.compute.domain.Image;
|
||||
import org.jclouds.compute.domain.OsFamily;
|
||||
import org.testng.annotations.Test;
|
||||
import org.virtualbox_4_1.IGuestOSType;
|
||||
import org.virtualbox_4_1.IMachine;
|
||||
import org.virtualbox_4_1.IVirtualBox;
|
||||
import org.virtualbox_4_1.VirtualBoxManager;
|
||||
|
||||
import static org.easymock.EasyMock.eq;
|
||||
import static org.easymock.EasyMock.expect;
|
||||
import static org.easymock.classextension.EasyMock.createNiceMock;
|
||||
import static org.easymock.classextension.EasyMock.replay;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.AssertJUnit.assertTrue;
|
||||
|
||||
@Test(groups = "unit")
|
||||
public class IMachineToImageTest {
|
||||
|
||||
@Test
|
||||
public void testConvert() throws Exception {
|
||||
|
||||
VirtualBoxManager vbm = createNiceMock(VirtualBoxManager.class);
|
||||
IVirtualBox vBox= createNiceMock(IVirtualBox.class);
|
||||
IMachine vm = createNiceMock(IMachine.class);
|
||||
IGuestOSType guestOsType = createNiceMock(IGuestOSType.class);
|
||||
String linuxDescription = "Ubuntu 10.04";
|
||||
expect(vbm.getVBox()).andReturn(vBox).anyTimes();
|
||||
|
||||
expect(vm.getOSTypeId()).andReturn("os-type").anyTimes();
|
||||
expect(vBox.getGuestOSType(eq("os-type"))).andReturn(guestOsType);
|
||||
expect(vm.getDescription()).andReturn("my-ubuntu-machine").anyTimes();
|
||||
expect(guestOsType.getDescription()).andReturn(linuxDescription).anyTimes();
|
||||
expect(guestOsType.getIs64Bit()).andReturn(true);
|
||||
|
||||
replay(vbm, vBox, vm, guestOsType);
|
||||
|
||||
IMachineToImage fn = new IMachineToImage(vbm);
|
||||
|
||||
Image image = fn.apply(vm);
|
||||
|
||||
assertEquals(image.getDescription(), "my-ubuntu-machine");
|
||||
assertEquals(image.getOperatingSystem().getDescription(), linuxDescription);
|
||||
assertTrue(image.getOperatingSystem().is64Bit());
|
||||
assertEquals(image.getOperatingSystem().getFamily(), OsFamily.UBUNTU);
|
||||
assertEquals(image.getOperatingSystem().getVersion(), "10.04");
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOsVersion() throws Exception {
|
||||
|
||||
String osDescription = "Ubuntu 10.04";
|
||||
|
||||
Function<String, String> iMachineStringFunction = IMachineToImage.osVersion();
|
||||
assertEquals("10.04", iMachineStringFunction.apply(osDescription));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnparseableOsString() throws Exception {
|
||||
|
||||
VirtualBoxManager vbm = createNiceMock(VirtualBoxManager.class);
|
||||
IVirtualBox vBox= createNiceMock(IVirtualBox.class);
|
||||
IMachine vm = createNiceMock(IMachine.class);
|
||||
IGuestOSType guestOsType = createNiceMock(IGuestOSType.class);
|
||||
|
||||
expect(vbm.getVBox()).andReturn(vBox).anyTimes();
|
||||
|
||||
String unknownOsDescription = "SomeOtherOs 2.04";
|
||||
expect(vm.getOSTypeId()).andReturn("os-type").anyTimes();
|
||||
expect(vm.getDescription()).andReturn("my-unknown-machine").anyTimes();
|
||||
expect(guestOsType.getDescription()).andReturn(unknownOsDescription).anyTimes();
|
||||
expect(guestOsType.getIs64Bit()).andReturn(true);
|
||||
expect(vBox.getGuestOSType(eq("os-type"))).andReturn(guestOsType);
|
||||
|
||||
replay(vbm, vBox, vm, guestOsType);
|
||||
|
||||
Image image = new IMachineToImage(vbm).apply(vm);
|
||||
|
||||
assertEquals(image.getOperatingSystem().getDescription(), "SomeOtherOs 2.04");
|
||||
assertEquals(image.getOperatingSystem().getVersion(), "");
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -47,7 +47,7 @@ public class IMachineToNodeMetadataTest {
|
|||
|
||||
VirtualBox virtualBox = new VirtualBox();
|
||||
IMachineToNodeMetadata parser = new IMachineToNodeMetadata();
|
||||
IMachineToHardware hwParser = new IMachineToHardware(virtualBox);
|
||||
IMachineToHardware hwParser = new IMachineToHardware(manager);
|
||||
|
||||
// hwParser.apply()
|
||||
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* *
|
||||
* * 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;
|
||||
|
||||
/**
|
||||
* @author Andrea Turli
|
||||
*/
|
||||
|
||||
import static org.easymock.EasyMock.expect;
|
||||
import static org.easymock.classextension.EasyMock.createNiceMock;
|
||||
import static org.easymock.classextension.EasyMock.replay;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import org.jclouds.compute.ComputeServiceContext;
|
||||
import org.jclouds.virtualbox.config.VirtualBoxConstants;
|
||||
import org.jclouds.virtualbox.experiment.TestUtils;
|
||||
import org.testng.annotations.Test;
|
||||
import org.virtualbox_4_1.IMachine;
|
||||
import org.virtualbox_4_1.ISession;
|
||||
import org.virtualbox_4_1.IVirtualBox;
|
||||
import org.virtualbox_4_1.VirtualBoxManager;
|
||||
|
||||
//TODO should it be a live test?
|
||||
@Test(groups = "unit")
|
||||
public class IsoToIMachineTest {
|
||||
|
||||
private String settingsFile = "";
|
||||
private boolean forceOverwrite = true;
|
||||
private String vmId = null;
|
||||
private String osTypeId = null;
|
||||
private String controllerIDE = "test-IDE";
|
||||
private String diskFormat = "";
|
||||
private String adminDisk = "testAdmin.vdi";
|
||||
private String guestId = "guestId";
|
||||
private String hostId = "hostId";
|
||||
|
||||
@Test
|
||||
public void testConvert() throws Exception {
|
||||
String vmName = "virtualbox-iso-to-machine-test";
|
||||
VirtualBoxManager vbm = createNiceMock(VirtualBoxManager.class);
|
||||
IVirtualBox vBox = createNiceMock(IVirtualBox.class);
|
||||
IMachine vm = createNiceMock(IMachine.class);
|
||||
ISession session = createNiceMock(ISession.class);
|
||||
expect(vbm.getVBox()).andReturn(vBox).anyTimes();
|
||||
expect(vbm.getSessionObject()).andReturn(session).anyTimes();
|
||||
expect(vBox.findMachine(vmName)).andReturn(vm).anyTimes();
|
||||
expect(
|
||||
vBox.createMachine(settingsFile, vmName, osTypeId, vmId,
|
||||
forceOverwrite)).andReturn(vm).anyTimes();
|
||||
expect(vm.getName()).andReturn(vmName).anyTimes();
|
||||
// expect(vm.lockMachine(session, LockType.Write)).and
|
||||
expect(session.getMachine()).andReturn(vm).anyTimes();
|
||||
replay(vbm, vBox, vm, session);
|
||||
|
||||
ComputeServiceContext context = TestUtils
|
||||
.computeServiceForLocalhostAndGuest();
|
||||
IMachine iMachine = new IsoToIMachine(vbm, adminDisk, diskFormat,
|
||||
settingsFile, vmName, osTypeId, vmId, forceOverwrite,
|
||||
controllerIDE, context, hostId, guestId)
|
||||
.apply(VirtualBoxConstants.VIRTUALBOX_DISTRO_ISO_NAME);
|
||||
|
||||
assertEquals(iMachine.getName(), vmName);
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
[
|
||||
{
|
||||
"uuid": "cc54132d-4912-4106-a91a-7a27e6866c8b",
|
||||
"description": "Debian 6.0.2.1",
|
||||
"osFamily": "DEBIAN",
|
||||
"osVersion": "6.0",
|
||||
"size": "1"
|
||||
},
|
||||
{
|
||||
"uuid": "46e305b6-6a49-409c-bd12-eb966cdb3664",
|
||||
"description": "Windows 2008 R2 with SP1 (x64)",
|
||||
"osFamily": "WINDOWS",
|
||||
"osVersion": "2008 R2",
|
||||
"size": "13"
|
||||
}
|
||||
]
|
|
@ -54,7 +54,7 @@ public class SoftLayerProviderMetadata extends BaseProviderMetadata {
|
|||
*/
|
||||
@Override
|
||||
public String getName() {
|
||||
return "//TODO SoftLayer";
|
||||
return "SoftLayer";
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -62,7 +62,7 @@ public class SoftLayerProviderMetadata extends BaseProviderMetadata {
|
|||
*/
|
||||
@Override
|
||||
public String getIdentityName() {
|
||||
return "//TODO";
|
||||
return "API Username";
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -70,7 +70,7 @@ public class SoftLayerProviderMetadata extends BaseProviderMetadata {
|
|||
*/
|
||||
@Override
|
||||
public String getCredentialName() {
|
||||
return "//TODO";
|
||||
return "API Key";
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -78,7 +78,7 @@ public class SoftLayerProviderMetadata extends BaseProviderMetadata {
|
|||
*/
|
||||
@Override
|
||||
public URI getHomepage() {
|
||||
return URI.create("//TODO");
|
||||
return URI.create("http://www.softlayer.com");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -86,7 +86,7 @@ public class SoftLayerProviderMetadata extends BaseProviderMetadata {
|
|||
*/
|
||||
@Override
|
||||
public URI getConsole() {
|
||||
return URI.create("//TODO");
|
||||
return URI.create("https://manage.softlayer.com");
|
||||
}
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
|
|
|
@ -18,15 +18,14 @@
|
|||
*/
|
||||
package org.jclouds.softlayer.compute.config;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.TypeLiteral;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jclouds.compute.ComputeServiceAdapter;
|
||||
import org.jclouds.compute.config.ComputeServiceAdapterContextModule;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.OsFamily;
|
||||
import org.jclouds.compute.domain.TemplateBuilder;
|
||||
import org.jclouds.compute.options.TemplateOptions;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.location.suppliers.OnlyLocationOrFirstZone;
|
||||
import org.jclouds.softlayer.SoftLayerAsyncClient;
|
||||
|
@ -35,12 +34,16 @@ import org.jclouds.softlayer.compute.functions.DatacenterToLocation;
|
|||
import org.jclouds.softlayer.compute.functions.ProductItemToImage;
|
||||
import org.jclouds.softlayer.compute.functions.ProductItemsToHardware;
|
||||
import org.jclouds.softlayer.compute.functions.VirtualGuestToNodeMetadata;
|
||||
import org.jclouds.softlayer.compute.options.SoftLayerTemplateOptions;
|
||||
import org.jclouds.softlayer.compute.strategy.SoftLayerComputeServiceAdapter;
|
||||
import org.jclouds.softlayer.domain.Datacenter;
|
||||
import org.jclouds.softlayer.domain.ProductItem;
|
||||
import org.jclouds.softlayer.domain.VirtualGuest;
|
||||
|
||||
import java.util.Set;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -68,6 +71,7 @@ public class SoftLayerComputeServiceContextModule extends
|
|||
.to(DatacenterToLocation.class);
|
||||
bind(new TypeLiteral<Supplier<Location>>() {})
|
||||
.to(OnlyLocationOrFirstZone.class);
|
||||
bind(TemplateOptions.class).to(SoftLayerTemplateOptions.class);
|
||||
}
|
||||
|
||||
protected TemplateBuilder provideTemplate(Injector injector, TemplateBuilder template) {
|
||||
|
|
|
@ -0,0 +1,231 @@
|
|||
/**
|
||||
* 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.softlayer.compute.options;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import org.jclouds.compute.ComputeService;
|
||||
import org.jclouds.compute.options.TemplateOptions;
|
||||
import org.jclouds.io.Payload;
|
||||
import org.jclouds.softlayer.features.VirtualGuestClient;
|
||||
|
||||
import com.google.common.net.InternetDomainName;
|
||||
|
||||
/**
|
||||
* Contains options supported by the
|
||||
* {@link ComputeService#createNodesInGroup(String, int, TemplateOptions)} and
|
||||
* {@link ComputeService#runNodesWithTag(String, int, TemplateOptions)} operations on the
|
||||
* <em>gogrid</em> provider.
|
||||
*
|
||||
* <h2>Usage</h2> The recommended way to instantiate a {@link SoftLayerTemplateOptions} object is to
|
||||
* statically import {@code SoftLayerTemplateOptions.*} and invoke a static creation method followed
|
||||
* by an instance mutator (if needed):
|
||||
* <p>
|
||||
*
|
||||
* <pre>
|
||||
* import static org.jclouds.compute.options.SoftLayerTemplateOptions.Builder.*;
|
||||
* ComputeService client = // get connection
|
||||
* templateBuilder.options(inboundPorts(22, 80, 8080, 443));
|
||||
* Set<? extends NodeMetadata> set = client.runNodesWithTag(tag, 2, templateBuilder.build());
|
||||
* </pre>
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class SoftLayerTemplateOptions extends TemplateOptions implements Cloneable {
|
||||
|
||||
protected String domainName = "jclouds.org";
|
||||
|
||||
@Override
|
||||
public SoftLayerTemplateOptions clone() {
|
||||
SoftLayerTemplateOptions options = new SoftLayerTemplateOptions();
|
||||
copyTo(options);
|
||||
return options;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void copyTo(TemplateOptions to) {
|
||||
super.copyTo(to);
|
||||
if (to instanceof SoftLayerTemplateOptions) {
|
||||
SoftLayerTemplateOptions eTo = SoftLayerTemplateOptions.class.cast(to);
|
||||
eTo.domainName(domainName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* will replace the default domain used when ordering virtual guests. Note this needs to contain
|
||||
* a public suffix!
|
||||
*
|
||||
* @see VirtualGuestClient#orderVirtualGuest
|
||||
* @see InternetDomainName#hasPublicSuffix
|
||||
*/
|
||||
public TemplateOptions domainName(String domainName) {
|
||||
checkNotNull(domainName, "domainName was null");
|
||||
checkArgument(InternetDomainName.from(domainName).hasPublicSuffix(), "domainName %s has no public suffix",
|
||||
domainName);
|
||||
this.domainName = domainName;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getDomainName() {
|
||||
return domainName;
|
||||
}
|
||||
|
||||
public static final SoftLayerTemplateOptions NONE = new SoftLayerTemplateOptions();
|
||||
|
||||
public static class Builder {
|
||||
|
||||
/**
|
||||
* @see #domainName
|
||||
*/
|
||||
public static SoftLayerTemplateOptions domainName(String domainName) {
|
||||
SoftLayerTemplateOptions options = new SoftLayerTemplateOptions();
|
||||
return SoftLayerTemplateOptions.class.cast(options.domainName(domainName));
|
||||
}
|
||||
|
||||
// methods that only facilitate returning the correct object type
|
||||
|
||||
/**
|
||||
* @see TemplateOptions#inboundPorts(int...)
|
||||
*/
|
||||
public static SoftLayerTemplateOptions inboundPorts(int... ports) {
|
||||
SoftLayerTemplateOptions options = new SoftLayerTemplateOptions();
|
||||
return SoftLayerTemplateOptions.class.cast(options.inboundPorts(ports));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see TemplateOptions#blockOnPort(int, int)
|
||||
*/
|
||||
public static SoftLayerTemplateOptions blockOnPort(int port, int seconds) {
|
||||
SoftLayerTemplateOptions options = new SoftLayerTemplateOptions();
|
||||
return SoftLayerTemplateOptions.class.cast(options.blockOnPort(port, seconds));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see TemplateOptions#runScript(Payload)
|
||||
*/
|
||||
public static SoftLayerTemplateOptions runScript(Payload script) {
|
||||
SoftLayerTemplateOptions options = new SoftLayerTemplateOptions();
|
||||
return SoftLayerTemplateOptions.class.cast(options.runScript(script));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see TemplateOptions#installPrivateKey(Payload)
|
||||
*/
|
||||
@Deprecated
|
||||
public static SoftLayerTemplateOptions installPrivateKey(Payload rsaKey) {
|
||||
SoftLayerTemplateOptions options = new SoftLayerTemplateOptions();
|
||||
return SoftLayerTemplateOptions.class.cast(options.installPrivateKey(rsaKey));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see TemplateOptions#authorizePublicKey(Payload)
|
||||
*/
|
||||
@Deprecated
|
||||
public static SoftLayerTemplateOptions authorizePublicKey(Payload rsaKey) {
|
||||
SoftLayerTemplateOptions options = new SoftLayerTemplateOptions();
|
||||
return SoftLayerTemplateOptions.class.cast(options.authorizePublicKey(rsaKey));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see TemplateOptions#withMetadata()
|
||||
*/
|
||||
public static SoftLayerTemplateOptions withMetadata() {
|
||||
SoftLayerTemplateOptions options = new SoftLayerTemplateOptions();
|
||||
return SoftLayerTemplateOptions.class.cast(options.withMetadata());
|
||||
}
|
||||
}
|
||||
|
||||
// methods that only facilitate returning the correct object type
|
||||
|
||||
/**
|
||||
* @see TemplateOptions#blockOnPort(int, int)
|
||||
*/
|
||||
@Override
|
||||
public SoftLayerTemplateOptions blockOnPort(int port, int seconds) {
|
||||
return SoftLayerTemplateOptions.class.cast(super.blockOnPort(port, seconds));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see TemplateOptions#inboundPorts(int...)
|
||||
*/
|
||||
@Override
|
||||
public SoftLayerTemplateOptions inboundPorts(int... ports) {
|
||||
return SoftLayerTemplateOptions.class.cast(super.inboundPorts(ports));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see TemplateOptions#authorizePublicKey(String)
|
||||
*/
|
||||
@Override
|
||||
public SoftLayerTemplateOptions authorizePublicKey(String publicKey) {
|
||||
return SoftLayerTemplateOptions.class.cast(super.authorizePublicKey(publicKey));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see TemplateOptions#authorizePublicKey(Payload)
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
public SoftLayerTemplateOptions authorizePublicKey(Payload publicKey) {
|
||||
return SoftLayerTemplateOptions.class.cast(super.authorizePublicKey(publicKey));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see TemplateOptions#installPrivateKey(String)
|
||||
*/
|
||||
@Override
|
||||
public SoftLayerTemplateOptions installPrivateKey(String privateKey) {
|
||||
return SoftLayerTemplateOptions.class.cast(super.installPrivateKey(privateKey));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see TemplateOptions#installPrivateKey(Payload)
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
public SoftLayerTemplateOptions installPrivateKey(Payload privateKey) {
|
||||
return SoftLayerTemplateOptions.class.cast(super.installPrivateKey(privateKey));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see TemplateOptions#runScript(Payload)
|
||||
*/
|
||||
@Override
|
||||
public SoftLayerTemplateOptions runScript(Payload script) {
|
||||
return SoftLayerTemplateOptions.class.cast(super.runScript(script));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see TemplateOptions#runScript(byte[])
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
public SoftLayerTemplateOptions runScript(byte[] script) {
|
||||
return SoftLayerTemplateOptions.class.cast(super.runScript(script));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see TemplateOptions#withMetadata()
|
||||
*/
|
||||
@Override
|
||||
public SoftLayerTemplateOptions withMetadata() {
|
||||
return SoftLayerTemplateOptions.class.cast(super.withMetadata());
|
||||
}
|
||||
}
|
|
@ -18,31 +18,46 @@
|
|||
*/
|
||||
package org.jclouds.softlayer.compute.strategy;
|
||||
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.jclouds.softlayer.predicates.ProductItemPredicates.categoryCode;
|
||||
import static org.jclouds.softlayer.predicates.ProductItemPredicates.matches;
|
||||
import static org.jclouds.softlayer.predicates.ProductItemPredicates.units;
|
||||
import static org.jclouds.softlayer.predicates.ProductPackagePredicates.named;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.compute.ComputeService;
|
||||
import org.jclouds.compute.ComputeServiceAdapter;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.softlayer.SoftLayerClient;
|
||||
import org.jclouds.softlayer.compute.functions.ProductItems;
|
||||
import org.jclouds.softlayer.domain.*;
|
||||
import org.jclouds.softlayer.compute.options.SoftLayerTemplateOptions;
|
||||
import org.jclouds.softlayer.domain.BillingItemVirtualGuest;
|
||||
import org.jclouds.softlayer.domain.Datacenter;
|
||||
import org.jclouds.softlayer.domain.OperatingSystem;
|
||||
import org.jclouds.softlayer.domain.Password;
|
||||
import org.jclouds.softlayer.domain.ProductItem;
|
||||
import org.jclouds.softlayer.domain.ProductItemPrice;
|
||||
import org.jclouds.softlayer.domain.ProductOrder;
|
||||
import org.jclouds.softlayer.domain.ProductPackage;
|
||||
import org.jclouds.softlayer.domain.VirtualGuest;
|
||||
import org.jclouds.softlayer.features.AccountClient;
|
||||
import org.jclouds.softlayer.features.ProductPackageClient;
|
||||
import org.jclouds.softlayer.reference.SoftLayerConstants;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.jclouds.softlayer.predicates.ProductItemPredicates.*;
|
||||
import static org.jclouds.softlayer.predicates.ProductPackagePredicates.named;
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
/**
|
||||
* defines the connection between the {@link SoftLayerClient} implementation and the jclouds
|
||||
|
@ -54,7 +69,6 @@ public class SoftLayerComputeServiceAdapter implements
|
|||
ComputeServiceAdapter<VirtualGuest, Set<ProductItem>, ProductItem, Datacenter> {
|
||||
|
||||
public static final String SAN_DESCRIPTION_REGEX=".*GB \\(SAN\\).*";
|
||||
//TODO: Better to pass this in as a property like virtualGuestPackageName?
|
||||
private static final Float BOOT_VOLUME_CAPACITY = 100F;
|
||||
|
||||
private final SoftLayerClient client;
|
||||
|
@ -68,20 +82,87 @@ public class SoftLayerComputeServiceAdapter implements
|
|||
}
|
||||
|
||||
@Override
|
||||
public VirtualGuest createNodeWithGroupEncodedIntoNameThenStoreCredentials(String tag, String name,
|
||||
public VirtualGuest createNodeWithGroupEncodedIntoNameThenStoreCredentials(String group, String name,
|
||||
Template template, Map<String, Credentials> credentialStore) {
|
||||
VirtualGuest from = null; // TODO create the backend object using parameters from the
|
||||
// template. ex.
|
||||
// VirtualGuest from =
|
||||
// client.getVirtualGuestClient().createServerInDC(template.getLocation().getId(), name,
|
||||
// Long.parseLong(template.getImage().getProviderId()),
|
||||
// Long.parseLong(template.getHardware().getProviderId()));
|
||||
// store the credentials so that later functions can use them
|
||||
// credentialStore.put("node#"+ from.getId() + "", new Credentials(from.loginUser,
|
||||
// from.password));
|
||||
return from;
|
||||
checkNotNull(template, "template was null");
|
||||
checkNotNull(template.getOptions(), "template options was null");
|
||||
checkArgument(template.getOptions().getClass().isAssignableFrom(SoftLayerTemplateOptions.class),
|
||||
"options class %s should have been assignable from SoftLayerTemplateOptions", template.getOptions()
|
||||
.getClass());
|
||||
|
||||
Iterable<VirtualGuest> existing = findVirtualGuests(name,group);
|
||||
if(!Iterables.isEmpty(existing)) {
|
||||
throw new IllegalStateException(
|
||||
"VirtualGuest(s) already exist with hostname:"+name+", group:"+group+". Existing:"+existing);
|
||||
}
|
||||
|
||||
VirtualGuest newGuest = VirtualGuest.builder()
|
||||
.domain(template.getOptions().as(SoftLayerTemplateOptions.class).getDomainName())
|
||||
.hostname(name)
|
||||
.build();
|
||||
|
||||
ProductOrder order = ProductOrder.builder()
|
||||
.packageId(getProductPackage().getId())
|
||||
.location(template.getLocation().getId())
|
||||
.quantity(1)
|
||||
.useHourlyPricing(true)
|
||||
.prices(getPrices(template))
|
||||
.virtualGuest(newGuest)
|
||||
.build();
|
||||
|
||||
client.getVirtualGuestClient().orderVirtualGuest(order);
|
||||
|
||||
|
||||
VirtualGuest result = Iterables.getOnlyElement(findVirtualGuests(name, group));
|
||||
Credentials credentials = new Credentials(null,null);
|
||||
|
||||
// This information is not always available.
|
||||
OperatingSystem os = result.getOperatingSystem();
|
||||
if(os!=null) {
|
||||
Set<Password> passwords = os.getPasswords();
|
||||
if(passwords.size()>0) {
|
||||
Password pw = Iterables.get(passwords,0);
|
||||
credentials = new Credentials(pw.getUsername(),pw.getPassword());
|
||||
}
|
||||
}
|
||||
credentialStore.put("node#"+result.getId(),credentials);
|
||||
return result;
|
||||
}
|
||||
|
||||
private Iterable<VirtualGuest> findVirtualGuests(String hostname,String domain) {
|
||||
checkNotNull(hostname,"hostname");
|
||||
checkNotNull(domain,"domain");
|
||||
|
||||
Set<VirtualGuest> result = Sets.newLinkedHashSet();
|
||||
|
||||
for( VirtualGuest guest : client.getVirtualGuestClient().listVirtualGuests()) {
|
||||
if ( guest.getHostname().equals(hostname) && guest.getDomain().equals(domain)) {
|
||||
result.add(guest);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private Iterable<ProductItemPrice> getPrices(Template template) {
|
||||
Set<ProductItemPrice> result = Sets.newLinkedHashSet();
|
||||
|
||||
int imageId = Integer.parseInt(template.getImage().getId());
|
||||
result.add(ProductItemPrice.builder().id(imageId).build());
|
||||
|
||||
Iterable<String> hardwareIds = Splitter.on(",").split(template.getHardware().getId());
|
||||
for(String hardwareId: hardwareIds) {
|
||||
int id = Integer.parseInt(hardwareId);
|
||||
result.add(ProductItemPrice.builder().id(id).build());
|
||||
}
|
||||
|
||||
result.addAll(SoftLayerConstants.DEFAULT_VIRTUAL_GUEST_PRICES);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public Iterable<Set<ProductItem>> listHardwareProfiles() {
|
||||
ProductPackage productPackage = getProductPackage();
|
||||
|
|
|
@ -0,0 +1,137 @@
|
|||
/**
|
||||
* 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.softlayer.domain;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* Extends the SoftLayer_Software_Component data type to include operating system specific properties.
|
||||
*
|
||||
* @author Jason King
|
||||
* @see <a href=
|
||||
* "http://sldn.softlayer.com/reference/datatypes/SoftLayer_Software_Component_OperatingSystem"
|
||||
* />
|
||||
*/
|
||||
public class OperatingSystem implements Comparable<OperatingSystem> {
|
||||
|
||||
// There are other properties
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private int id = -1;
|
||||
private Set<Password> passwords = Sets.newLinkedHashSet();
|
||||
|
||||
public Builder id(int id) {
|
||||
this.id = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder password(Password password) {
|
||||
this.passwords.add(checkNotNull(password, "password"));
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder passwords(Iterable<Password> passwords) {
|
||||
this.passwords = ImmutableSet.<Password> copyOf(checkNotNull(passwords, "passwords"));
|
||||
return this;
|
||||
}
|
||||
|
||||
public OperatingSystem build() {
|
||||
return new OperatingSystem(id, passwords);
|
||||
}
|
||||
|
||||
public static Builder fromOperatingSystem(OperatingSystem in) {
|
||||
return OperatingSystem.builder()
|
||||
.id(in.getId())
|
||||
.passwords(in.getPasswords());
|
||||
}
|
||||
}
|
||||
|
||||
private int id = -1;
|
||||
private Set<Password> passwords = Sets.newLinkedHashSet();
|
||||
|
||||
// for deserializer
|
||||
OperatingSystem() {
|
||||
|
||||
}
|
||||
|
||||
public OperatingSystem(int id,Iterable<Password> passwords) {
|
||||
this.id = id;
|
||||
this.passwords = ImmutableSet.<Password> copyOf(checkNotNull(passwords, "passwords"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(OperatingSystem arg0) {
|
||||
return new Integer(id).compareTo(arg0.getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return An ID number identifying this Software Component (Software Installation)
|
||||
*/
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return Username/Password pairs used for access to this Software Installation.
|
||||
*/
|
||||
public Set<Password> getPasswords() {
|
||||
return passwords;
|
||||
}
|
||||
|
||||
public Builder toBuilder() {
|
||||
return Builder.fromOperatingSystem(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + (id ^ (id >>> 32));
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
OperatingSystem other = (OperatingSystem) obj;
|
||||
if (id != other.id)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "OperatingSystem [id=" + id + ", passwords=" + passwords + "]";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,141 @@
|
|||
/**
|
||||
* 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.softlayer.domain;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Strings.emptyToNull;
|
||||
|
||||
/**
|
||||
*
|
||||
* Contains a password for a specific software component instance
|
||||
*
|
||||
* @author Jason King
|
||||
* @see <a href= "http://sldn.softlayer.com/reference/datatypes/SoftLayer_Software_Component_Password"
|
||||
* />
|
||||
*/
|
||||
public class Password implements Comparable<Password> {
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private int id = -1;
|
||||
private String username;
|
||||
private String password;
|
||||
|
||||
public Builder id(int id) {
|
||||
this.id = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder username(String username) {
|
||||
this.username = username;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder password(String password) {
|
||||
this.password = password;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Password build() {
|
||||
return new Password(id, username, password);
|
||||
}
|
||||
|
||||
public static Builder fromPassword(Password in) {
|
||||
return Password.builder().id(in.getId())
|
||||
.username(in.getUsername())
|
||||
.password(in.getPassword());
|
||||
}
|
||||
}
|
||||
|
||||
private int id = -1;
|
||||
private String username;
|
||||
private String password;
|
||||
|
||||
// for deserializer
|
||||
Password() {
|
||||
|
||||
}
|
||||
|
||||
public Password(int id, String username, String password) {
|
||||
this.id = id;
|
||||
this.username = checkNotNull(emptyToNull(username),"username cannot be null or empty:"+username);
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(Password arg0) {
|
||||
return new Integer(id).compareTo(arg0.getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return An id number for this specific username/password pair.
|
||||
*/
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The username part of the username/password pair.
|
||||
*/
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The password part of the username/password pair.
|
||||
*/
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public Builder toBuilder() {
|
||||
return Builder.fromPassword(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + (id ^ (id >>> 32));
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
Password other = (Password) obj;
|
||||
if (id != other.id)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Password [id=" + id + ", username=" + username + ", password=**********]";
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -32,6 +32,17 @@ import com.google.gson.annotations.SerializedName;
|
|||
* A guest, also known as a virtual server or CloudLayer Computing Instance, represents an
|
||||
* allocation of resources on a virtual host.
|
||||
*
|
||||
* The hostname and domain must be alphanumeric strings that may be separated by periods '.'.
|
||||
* The only other allowable special character is the dash '-'.
|
||||
* However the special characters '.' and '-' may not be consecutive.
|
||||
* Each alphanumeric string separated by a period is considered a label.
|
||||
* Labels must begin and end with an alphanumeric character.
|
||||
* Each label cannot be soley comprised of digits and must be between 1-63 characters in length.
|
||||
* The last label, the TLD (top level domain) must be between 2-6 alphabetic characters.
|
||||
* The domain portion must consist of least one label followed by a period '.' then ending with the TLD label.
|
||||
* Combining the hostname, followed by a period '.', followed by the domain gives the FQDN (fully qualified domain name),
|
||||
* which may not exceed 253 characters in total length.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
* @see <a href=
|
||||
* "http://sldn.softlayer.com/reference/datatypes/SoftLayer_Virtual_Guest"
|
||||
|
@ -64,6 +75,7 @@ public class VirtualGuest implements Comparable<VirtualGuest> {
|
|||
private String primaryBackendIpAddress;
|
||||
private String primaryIpAddress;
|
||||
private BillingItemVirtualGuest billingItem;
|
||||
private OperatingSystem operatingSystem;
|
||||
|
||||
public Builder id(int id) {
|
||||
this.id = id;
|
||||
|
@ -170,12 +182,17 @@ public class VirtualGuest implements Comparable<VirtualGuest> {
|
|||
return this;
|
||||
}
|
||||
|
||||
public Builder operatingSystem(OperatingSystem operatingSystem) {
|
||||
this.operatingSystem = operatingSystem;
|
||||
return this;
|
||||
}
|
||||
|
||||
public VirtualGuest build() {
|
||||
return new VirtualGuest(accountId, createDate, dedicatedAccountHostOnly, domain,
|
||||
fullyQualifiedDomainName, hostname, id, lastVerifiedDate, maxCpu,
|
||||
maxCpuUnits, maxMemory, metricPollDate, modifyDate, notes,
|
||||
privateNetworkOnly, startCpus, statusId, uuid, primaryBackendIpAddress,
|
||||
primaryIpAddress,billingItem);
|
||||
primaryIpAddress,billingItem,operatingSystem);
|
||||
}
|
||||
|
||||
public static Builder fromVirtualGuest(VirtualGuest in) {
|
||||
|
@ -200,7 +217,9 @@ public class VirtualGuest implements Comparable<VirtualGuest> {
|
|||
.uuid(in.getUuid())
|
||||
.primaryBackendIpAddress(in.getPrimaryBackendIpAddress())
|
||||
.primaryIpAddress(in.getPrimaryIpAddress())
|
||||
.billingItem(in.getBillingItem());
|
||||
.billingItem(in.getBillingItem())
|
||||
.operatingSystem(in.getOperatingSystem());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -252,6 +271,7 @@ public class VirtualGuest implements Comparable<VirtualGuest> {
|
|||
private String primaryIpAddress;
|
||||
|
||||
private BillingItemVirtualGuest billingItem;
|
||||
private OperatingSystem operatingSystem;
|
||||
|
||||
// for deserializer
|
||||
VirtualGuest() {
|
||||
|
@ -262,7 +282,7 @@ public class VirtualGuest implements Comparable<VirtualGuest> {
|
|||
String fullyQualifiedDomainName, String hostname, int id, Date lastVerifiedDate, int maxCpu,
|
||||
String maxCpuUnits, int maxMemory, Date metricPollDate, Date modifyDate, String notes,
|
||||
boolean privateNetworkOnly, int startCpus, int statusId, String uuid, String primaryBackendIpAddress,
|
||||
String primaryIpAddress,BillingItemVirtualGuest billingItem) {
|
||||
String primaryIpAddress,BillingItemVirtualGuest billingItem, OperatingSystem operatingSystem) {
|
||||
this.accountId = accountId;
|
||||
this.createDate = createDate;
|
||||
this.dedicatedAccountHostOnly = dedicatedAccountHostOnly;
|
||||
|
@ -284,6 +304,7 @@ public class VirtualGuest implements Comparable<VirtualGuest> {
|
|||
this.primaryBackendIpAddress = primaryBackendIpAddress;
|
||||
this.primaryIpAddress = primaryIpAddress;
|
||||
this.billingItem = billingItem;
|
||||
this.operatingSystem = operatingSystem;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -441,6 +462,13 @@ public class VirtualGuest implements Comparable<VirtualGuest> {
|
|||
return billingItem;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return A guest's operating system.
|
||||
*/
|
||||
public OperatingSystem getOperatingSystem() {
|
||||
return operatingSystem;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
|
@ -466,6 +494,7 @@ public class VirtualGuest implements Comparable<VirtualGuest> {
|
|||
result = prime * result + statusId;
|
||||
result = prime * result + ((uuid == null) ? 0 : uuid.hashCode());
|
||||
result = prime * result + ((billingItem == null) ? 0 : billingItem.hashCode());
|
||||
result = prime * result + ((operatingSystem == null) ? 0 : operatingSystem.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -559,6 +588,11 @@ public class VirtualGuest implements Comparable<VirtualGuest> {
|
|||
return false;
|
||||
} else if (!billingItem.equals(other.billingItem))
|
||||
return false;
|
||||
if (operatingSystem == null) {
|
||||
if (other.operatingSystem != null)
|
||||
return false;
|
||||
} else if (!operatingSystem.equals(other.operatingSystem))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -571,7 +605,7 @@ public class VirtualGuest implements Comparable<VirtualGuest> {
|
|||
+ ", metricPollDate=" + metricPollDate + ", modifyDate=" + modifyDate + ", notes=" + notes
|
||||
+ ", primaryBackendIpAddress=" + primaryBackendIpAddress + ", primaryIpAddress=" + primaryIpAddress
|
||||
+ ", privateNetworkOnly=" + privateNetworkOnly + ", startCpus=" + startCpus + ", statusId=" + statusId
|
||||
+ ", uuid=" + uuid + ", billingItem="+billingItem+"]";
|
||||
+ ", uuid=" + uuid + ", billingItem="+billingItem+", operatingSystem="+operatingSystem+"]";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -47,6 +47,7 @@ import java.util.Set;
|
|||
@RequestFilters(BasicAuthentication.class)
|
||||
@Path("/v{jclouds.api-version}")
|
||||
public interface VirtualGuestAsyncClient {
|
||||
public static String LIST_GUEST_MASK = "virtualGuests.powerState;virtualGuests.networkVlans;virtualGuests.operatingSystem.passwords;virtualGuests.datacenter;virtualGuests.billingItem";
|
||||
public static String GUEST_MASK = "powerState;networkVlans;operatingSystem.passwords;datacenter;virtualGuests.billingItem";
|
||||
|
||||
/**
|
||||
|
@ -54,7 +55,7 @@ public interface VirtualGuestAsyncClient {
|
|||
*/
|
||||
@GET
|
||||
@Path("/SoftLayer_Account/VirtualGuests.json")
|
||||
@QueryParams(keys = "objectMask", values = GUEST_MASK)
|
||||
@QueryParams(keys = "objectMask", values = LIST_GUEST_MASK)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
|
||||
ListenableFuture<Set<VirtualGuest>> listVirtualGuests();
|
||||
|
|
|
@ -20,30 +20,42 @@ package org.jclouds.softlayer.compute;
|
|||
|
||||
import static org.jclouds.softlayer.predicates.ProductItemPredicates.categoryCode;
|
||||
import static org.jclouds.softlayer.predicates.ProductItemPredicates.units;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertFalse;
|
||||
import static org.testng.AssertJUnit.assertEquals;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jclouds.compute.domain.ExecResponse;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.net.IPSocket;
|
||||
import org.jclouds.softlayer.compute.options.SoftLayerTemplateOptions;
|
||||
import org.jclouds.softlayer.compute.strategy.SoftLayerComputeServiceAdapter;
|
||||
import org.jclouds.softlayer.domain.ProductItem;
|
||||
import org.jclouds.softlayer.domain.VirtualGuest;
|
||||
import org.jclouds.softlayer.features.BaseSoftLayerClientLiveTest;
|
||||
import org.jclouds.softlayer.features.ProductPackageClientLiveTest;
|
||||
import org.testng.Assert;
|
||||
import org.jclouds.ssh.SshClient;
|
||||
import org.testng.annotations.AfterGroups;
|
||||
import org.testng.annotations.BeforeGroups;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.net.InetAddresses;
|
||||
|
||||
@Test(groups = "live", testName = "SoftLayerComputeServiceAdapterLiveTest")
|
||||
@Test(groups = "live", singleThreaded = true, testName = "SoftLayerComputeServiceAdapterLiveTest")
|
||||
public class SoftLayerComputeServiceAdapterLiveTest extends BaseSoftLayerClientLiveTest {
|
||||
|
||||
private SoftLayerComputeServiceAdapter adapter;
|
||||
private VirtualGuest guest;
|
||||
|
||||
@BeforeGroups(groups = { "live" })
|
||||
public void setupClient() {
|
||||
super.setupClient();
|
||||
adapter = new SoftLayerComputeServiceAdapter(context.getApi(), ProductPackageClientLiveTest.CLOUD_SERVER_PACKAGE_NAME);
|
||||
adapter = new SoftLayerComputeServiceAdapter(context.getApi(),
|
||||
ProductPackageClientLiveTest.CLOUD_SERVER_PACKAGE_NAME);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -51,6 +63,44 @@ public class SoftLayerComputeServiceAdapterLiveTest extends BaseSoftLayerClientL
|
|||
assertFalse(Iterables.isEmpty(adapter.listLocations()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateNodeWithGroupEncodedIntoNameThenStoreCredentials() {
|
||||
String group = "foo";
|
||||
String name = "foo-ef4";
|
||||
Template template = computeContext.getComputeService().templateBuilder()
|
||||
.locationId("3") // the default (singapore) doesn't work.
|
||||
.build();
|
||||
|
||||
// test passing custom options
|
||||
template.getOptions().as(SoftLayerTemplateOptions.class).domainName("me.org");
|
||||
|
||||
Map<String, Credentials> credentialStore = Maps.newLinkedHashMap();
|
||||
guest = adapter.createNodeWithGroupEncodedIntoNameThenStoreCredentials(group, name, template, credentialStore);
|
||||
assertEquals(guest.getHostname(), name);
|
||||
assertEquals(guest.getDomain(), template.getOptions().as(SoftLayerTemplateOptions.class).getDomainName());
|
||||
// check other things, like cpu correct, mem correct, image/os is correct
|
||||
// (as possible)
|
||||
assert credentialStore.containsKey("node#" + guest.getId()) : "credentials to log into guest not found " + guest;
|
||||
assert InetAddresses.isInetAddress(guest.getPrimaryBackendIpAddress()) : guest;
|
||||
doConnectViaSsh(guest, credentialStore.get("node#" + guest.getId()));
|
||||
}
|
||||
|
||||
protected void doConnectViaSsh(VirtualGuest guest, Credentials creds) {
|
||||
SshClient ssh = computeContext.utils().sshFactory()
|
||||
.create(new IPSocket(guest.getPrimaryBackendIpAddress(), 22), creds);
|
||||
try {
|
||||
ssh.connect();
|
||||
ExecResponse hello = ssh.exec("echo hello");
|
||||
assertEquals(hello.getOutput().trim(), "hello");
|
||||
System.err.println(ssh.exec("df -k").getOutput());
|
||||
System.err.println(ssh.exec("mount").getOutput());
|
||||
System.err.println(ssh.exec("uname -a").getOutput());
|
||||
} finally {
|
||||
if (ssh != null)
|
||||
ssh.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testListHardwareProfiles() {
|
||||
Iterable<Set<ProductItem>> profiles = adapter.listHardwareProfiles();
|
||||
|
@ -61,8 +111,14 @@ public class SoftLayerComputeServiceAdapterLiveTest extends BaseSoftLayerClientL
|
|||
assertEquals(profile.size(), 3);
|
||||
ProductItem cpuItem = Iterables.getOnlyElement(Iterables.filter(profile, units("PRIVATE_CORE")));
|
||||
ProductItem ramItem = Iterables.getOnlyElement(Iterables.filter(profile, categoryCode("ram")));
|
||||
Assert.assertEquals(cpuItem.getCapacity(),ramItem.getCapacity());
|
||||
assertEquals(cpuItem.getCapacity(), ramItem.getCapacity());
|
||||
}
|
||||
}
|
||||
|
||||
@AfterGroups(groups = "live")
|
||||
protected void tearDown() {
|
||||
if (guest != null)
|
||||
adapter.destroyNode(guest.getId() + "");
|
||||
super.tearDown();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,20 +18,22 @@
|
|||
*/
|
||||
package org.jclouds.softlayer.compute;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import org.jclouds.compute.BaseTemplateBuilderLiveTest;
|
||||
import org.jclouds.compute.domain.OsFamily;
|
||||
import org.jclouds.compute.domain.OsFamilyVersion64Bit;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
import org.testng.annotations.Test;
|
||||
import static org.jclouds.compute.util.ComputeServiceUtils.getCores;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.jclouds.compute.util.ComputeServiceUtils.getCores;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import org.jclouds.compute.BaseTemplateBuilderLiveTest;
|
||||
import org.jclouds.compute.domain.OsFamily;
|
||||
import org.jclouds.compute.domain.OsFamilyVersion64Bit;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.softlayer.compute.options.SoftLayerTemplateOptions;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -80,6 +82,8 @@ public class SoftLayerTemplateBuilderLiveTest extends BaseTemplateBuilderLiveTes
|
|||
assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true);
|
||||
assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.UBUNTU);
|
||||
assertEquals(getCores(defaultTemplate.getHardware()), 2.0d);
|
||||
// test that we bound the correct templateoptions in guice
|
||||
assertEquals(defaultTemplate.getOptions().getClass(), SoftLayerTemplateOptions.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -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.softlayer.compute.options;
|
||||
|
||||
import static org.jclouds.softlayer.compute.options.SoftLayerTemplateOptions.Builder.domainName;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import org.jclouds.compute.options.TemplateOptions;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* Tests possible uses of {@code SoftLayerTemplateOptions} and {@code
|
||||
* SoftLayerTemplateOptions.Builder.*}.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
// NOTE:without testName, this will not call @Before* and fail w/NPE during surefire
|
||||
@Test(groups = "unit", testName = "SoftLayerTemplateOptionsTest")
|
||||
public class SoftLayerTemplateOptionsTest {
|
||||
@Test
|
||||
public void testAs() {
|
||||
TemplateOptions options = new SoftLayerTemplateOptions();
|
||||
assertEquals(options.as(SoftLayerTemplateOptions.class), options);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDefaultDomainName() {
|
||||
TemplateOptions options = new SoftLayerTemplateOptions();
|
||||
assertEquals(options.as(SoftLayerTemplateOptions.class).getDomainName(), "jclouds.org");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDomainName() {
|
||||
TemplateOptions options = new SoftLayerTemplateOptions().domainName("me.com");
|
||||
assertEquals(options.as(SoftLayerTemplateOptions.class).getDomainName(), "me.com");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDomainNameStatic() {
|
||||
TemplateOptions options = domainName("me.com");
|
||||
assertEquals(options.as(SoftLayerTemplateOptions.class).getDomainName(), "me.com");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDomainNameNullHasDecentMessage() {
|
||||
try {
|
||||
new SoftLayerTemplateOptions().domainName(null);
|
||||
assert false : "should NPE";
|
||||
} catch (NullPointerException e) {
|
||||
assertEquals(e.getMessage(), "domainName was null");
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||
public void testDomainNameIsInvalidThrowsIllegalArgument() {
|
||||
new SoftLayerTemplateOptions().domainName("foo");
|
||||
}
|
||||
}
|
|
@ -20,11 +20,13 @@ package org.jclouds.softlayer.features;
|
|||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import org.jclouds.compute.ComputeServiceContext;
|
||||
import org.jclouds.compute.ComputeServiceContextFactory;
|
||||
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
|
||||
import org.jclouds.rest.RestContext;
|
||||
import org.jclouds.softlayer.SoftLayerAsyncClient;
|
||||
import org.jclouds.softlayer.SoftLayerClient;
|
||||
import org.jclouds.sshj.config.SshjSshClientModule;
|
||||
import org.testng.annotations.AfterGroups;
|
||||
import org.testng.annotations.BeforeGroups;
|
||||
import org.testng.annotations.Test;
|
||||
|
@ -41,15 +43,16 @@ import com.google.inject.Module;
|
|||
public class BaseSoftLayerClientLiveTest {
|
||||
|
||||
protected RestContext<SoftLayerClient, SoftLayerAsyncClient> context;
|
||||
protected ComputeServiceContext computeContext;
|
||||
|
||||
@BeforeGroups(groups = { "live" })
|
||||
public void setupClient() {
|
||||
String identity = checkNotNull(System.getProperty("test.softlayer.identity"), "test.softlayer.identity");
|
||||
String credential = checkNotNull(System.getProperty("test.softlayer.credential"), "test.softlayer.credential");
|
||||
|
||||
|
||||
context = new ComputeServiceContextFactory().createContext("softlayer", identity, credential,
|
||||
ImmutableSet.<Module> of(new Log4JLoggingModule())).getProviderSpecificContext();
|
||||
computeContext = new ComputeServiceContextFactory().createContext("softlayer", identity, credential,
|
||||
ImmutableSet.<Module> of(new Log4JLoggingModule(), new SshjSshClientModule()));
|
||||
context = computeContext.getProviderSpecificContext();
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ public class VirtualGuestAsyncClientTest extends BaseSoftLayerAsyncClientTest<Vi
|
|||
|
||||
assertRequestLineEquals(
|
||||
httpRequest,
|
||||
"GET https://api.softlayer.com/rest/v3/SoftLayer_Account/VirtualGuests.json?objectMask=powerState%3BnetworkVlans%3BoperatingSystem.passwords%3Bdatacenter%3BvirtualGuests.billingItem HTTP/1.1");
|
||||
"GET https://api.softlayer.com/rest/v3/SoftLayer_Account/VirtualGuests.json?objectMask=virtualGuests.powerState%3BvirtualGuests.networkVlans%3BvirtualGuests.operatingSystem.passwords%3BvirtualGuests.datacenter%3BvirtualGuests.billingItem HTTP/1.1");
|
||||
assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n");
|
||||
assertPayloadEquals(httpRequest, null, null, false);
|
||||
|
||||
|
@ -57,7 +57,7 @@ public class VirtualGuestAsyncClientTest extends BaseSoftLayerAsyncClientTest<Vi
|
|||
|
||||
assertRequestLineEquals(
|
||||
httpRequest,
|
||||
"GET https://api.softlayer.com/rest/v3/SoftLayer_Account/VirtualGuests.json?objectMask=powerState%3BnetworkVlans%3BoperatingSystem.passwords%3Bdatacenter%3BvirtualGuests.billingItem HTTP/1.1");
|
||||
"GET https://api.softlayer.com/rest/v3/SoftLayer_Account/VirtualGuests.json?objectMask=virtualGuests.powerState%3BvirtualGuests.networkVlans%3BvirtualGuests.operatingSystem.passwords%3BvirtualGuests.datacenter%3BvirtualGuests.billingItem HTTP/1.1");
|
||||
// for example, using basic authentication, we should get "only one"
|
||||
// header
|
||||
assertNonPayloadHeadersEqual(httpRequest,
|
||||
|
|
|
@ -62,7 +62,9 @@ public class Utils {
|
|||
}
|
||||
}
|
||||
|
||||
private static final Pattern pattern = Pattern.compile("\\{(.+?)\\}");
|
||||
/** matches any expression inside curly braces (where the expression does not including an open curly brace) */
|
||||
private static final Pattern pattern = Pattern.compile("\\{([^\\{]+?)\\}");
|
||||
|
||||
|
||||
/**
|
||||
* replaces tokens that are expressed as <code>{token}</code>
|
||||
|
|
|
@ -23,6 +23,7 @@ import static org.testng.Assert.assertEquals;
|
|||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
import org.jclouds.scriptbuilder.domain.OsFamily;
|
||||
import org.jclouds.scriptbuilder.domain.ShellToken;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
@ -80,4 +81,9 @@ public class UtilsTest {
|
|||
"set HOST=\r\nset PORT=\r\n");
|
||||
}
|
||||
|
||||
public void testSingleCurlyBraceDoesntBreakLfTokenReplacement() {
|
||||
assertEquals(Utils.replaceTokens("{{lf}", ShellToken.tokenValueMap(OsFamily.UNIX)),
|
||||
"{\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue