mirror of https://github.com/apache/jclouds.git
Issue 130: added options to runNode like openPorts and runScript; added ability to specify alternate endpoint in *ContextBuilderFactory; updated ant tasks to use new node features; Issue 112: normalized vcloud clients
git-svn-id: http://jclouds.googlecode.com/svn/trunk@2712 3d8758e0-26b5-11de-8745-db77d3ebf521
This commit is contained in:
parent
1d2b1495a2
commit
cb906ded3c
|
@ -21,12 +21,12 @@ package org.jclouds.aws.ec2.compute;
|
|||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.jclouds.aws.ec2.options.RunInstancesOptions.Builder.withKeyName;
|
||||
import static org.jclouds.scriptbuilder.domain.Statements.exec;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Set;
|
||||
import java.util.SortedSet;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Inject;
|
||||
|
@ -41,6 +41,7 @@ import org.jclouds.aws.ec2.domain.InstanceState;
|
|||
import org.jclouds.aws.ec2.domain.IpProtocol;
|
||||
import org.jclouds.aws.ec2.domain.KeyPair;
|
||||
import org.jclouds.aws.ec2.domain.RunningInstance;
|
||||
import org.jclouds.aws.ec2.options.RunInstancesOptions;
|
||||
import org.jclouds.compute.ComputeService;
|
||||
import org.jclouds.compute.domain.Architecture;
|
||||
import org.jclouds.compute.domain.ComputeMetadata;
|
||||
|
@ -54,11 +55,10 @@ import org.jclouds.compute.domain.Template;
|
|||
import org.jclouds.compute.domain.internal.ComputeMetadataImpl;
|
||||
import org.jclouds.compute.domain.internal.CreateNodeResponseImpl;
|
||||
import org.jclouds.compute.domain.internal.NodeMetadataImpl;
|
||||
import org.jclouds.compute.options.RunNodeOptions;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.scriptbuilder.ScriptBuilder;
|
||||
import org.jclouds.scriptbuilder.domain.OsFamily;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicate;
|
||||
|
@ -76,14 +76,14 @@ public class EC2ComputeService implements ComputeService {
|
|||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||
protected Logger logger = Logger.NULL;
|
||||
private final EC2Client ec2Client;
|
||||
private final Set<EC2Size> sizes;
|
||||
private final SortedSet<EC2Size> sizes;
|
||||
private final Provider<Set<EC2Template>> templates;
|
||||
private final Predicate<RunningInstance> instanceStateRunning;
|
||||
private final RunningInstanceToNodeMetadata runningInstanceToNodeMetadata;
|
||||
private final Map<Architecture, Map<OperatingSystem, Map<Region, String>>> imageAmiIdMap;
|
||||
|
||||
@Inject
|
||||
public EC2ComputeService(EC2Client client, Set<EC2Size> sizes,
|
||||
public EC2ComputeService(EC2Client client, SortedSet<EC2Size> sizes,
|
||||
Provider<Set<EC2Template>> templates,
|
||||
Map<Architecture, Map<OperatingSystem, Map<Region, String>>> imageAmiIdMap,
|
||||
Predicate<RunningInstance> instanceStateRunning,
|
||||
|
@ -103,34 +103,34 @@ public class EC2ComputeService implements ComputeService {
|
|||
|
||||
@Override
|
||||
public CreateNodeResponse runNode(String name, Template template) {
|
||||
return this.runNode(name, template, RunNodeOptions.NONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CreateNodeResponse runNode(String name, Template template, RunNodeOptions options) {
|
||||
checkArgument(template instanceof EC2Template,
|
||||
"unexpected template type. should be EC2Template, was: " + template.getClass());
|
||||
EC2Template ec2Template = (EC2Template) template;
|
||||
|
||||
KeyPair keyPair = createKeyPairInRegion(ec2Template.getRegion(), name);
|
||||
String securityGroupName = name;
|
||||
createSecurityGroupInRegion(ec2Template.getRegion(), securityGroupName, 22, 80, 8080, 443);
|
||||
|
||||
String script = new ScriptBuilder() // update and install jdk
|
||||
.addStatement(exec("apt-get update"))//
|
||||
.addStatement(exec("apt-get upgrade -y"))//
|
||||
.addStatement(exec("apt-get install -y openjdk-6-jdk"))//
|
||||
.addStatement(exec("wget -qO/usr/bin/runurl run.alestic.com/runurl"))//
|
||||
.addStatement(exec("chmod 755 /usr/bin/runurl"))//
|
||||
.build(OsFamily.UNIX);
|
||||
createSecurityGroupInRegion(ec2Template.getRegion(), securityGroupName, options
|
||||
.getOpenPorts());
|
||||
|
||||
logger.debug(">> running instance region(%s) ami(%s) type(%s) keyPair(%s) securityGroup(%s)",
|
||||
ec2Template.getRegion(), ec2Template.getImage().getId(), ec2Template.getSize()
|
||||
.getInstanceType(), keyPair.getKeyName(), securityGroupName);
|
||||
RunInstancesOptions instanceOptions = withKeyName(keyPair.getKeyName())// key
|
||||
.asType(ec2Template.getSize().getInstanceType())// instance size
|
||||
.withSecurityGroup(securityGroupName)// group I created above
|
||||
.withAdditionalInfo(name);
|
||||
|
||||
if (options.getRunScript() != null)
|
||||
instanceOptions.withUserData(options.getRunScript());
|
||||
|
||||
RunningInstance runningInstance = Iterables.getOnlyElement(ec2Client.getInstanceServices()
|
||||
.runInstancesInRegion(ec2Template.getRegion(), null, ec2Template.getImage().getId(),
|
||||
1, 1, withKeyName(keyPair.getKeyName())// key
|
||||
.asType(ec2Template.getSize().getInstanceType())// instance size
|
||||
.withSecurityGroup(securityGroupName)// group I created above
|
||||
.withAdditionalInfo(name)// description
|
||||
.withUserData(script.getBytes()) // script to run as root
|
||||
));
|
||||
1, 1, instanceOptions));
|
||||
logger.debug("<< started instance(%s)", runningInstance.getId());
|
||||
instanceStateRunning.apply(runningInstance);
|
||||
logger.debug("<< running instance(%s)", runningInstance.getId());
|
||||
|
@ -316,7 +316,7 @@ public class EC2ComputeService implements ComputeService {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Set<EC2Size> listSizes() {
|
||||
public SortedSet<EC2Size> listSizes() {
|
||||
return sizes;
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ package org.jclouds.aws.ec2.compute.config;
|
|||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.SortedSet;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Named;
|
||||
|
@ -43,7 +44,7 @@ import org.jclouds.logging.Logger;
|
|||
import org.jclouds.rest.RestContext;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.ImmutableSortedSet;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.inject.Provides;
|
||||
|
||||
|
@ -69,8 +70,8 @@ public class EC2ComputeServiceContextModule extends EC2ContextModule {
|
|||
|
||||
@Provides
|
||||
@Singleton
|
||||
Set<EC2Size> provideSizes() {
|
||||
return ImmutableSet.<EC2Size> of(EC2Size.C1_MEDIUM, EC2Size.C1_XLARGE, EC2Size.M1_LARGE,
|
||||
SortedSet<EC2Size> provideSizes() {
|
||||
return ImmutableSortedSet.of(EC2Size.C1_MEDIUM, EC2Size.C1_XLARGE, EC2Size.M1_LARGE,
|
||||
EC2Size.M1_SMALL, EC2Size.M1_XLARGE, EC2Size.M2_2XLARGE, EC2Size.M2_4XLARGE);
|
||||
}
|
||||
|
||||
|
@ -82,7 +83,7 @@ public class EC2ComputeServiceContextModule extends EC2ContextModule {
|
|||
|
||||
@Provides
|
||||
@Singleton
|
||||
Set<EC2Template> provideTemplates(EC2Client client, Set<EC2Size> sizes,
|
||||
Set<EC2Template> provideTemplates(EC2Client client, SortedSet<EC2Size> sizes,
|
||||
Map<Architecture, Map<OperatingSystem, Map<Region, String>>> imageAmiIdMap,
|
||||
LogHolder holder) {
|
||||
Set<EC2Template> templates = Sets.newHashSet();
|
||||
|
|
|
@ -18,43 +18,13 @@
|
|||
*/
|
||||
package org.jclouds.aws.ec2.compute;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.jclouds.compute.domain.OperatingSystem.UBUNTU;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.jclouds.compute.ComputeService;
|
||||
import org.jclouds.compute.ComputeServiceContext;
|
||||
import org.jclouds.compute.ComputeServiceContextFactory;
|
||||
import org.jclouds.compute.domain.ComputeMetadata;
|
||||
import org.jclouds.compute.domain.ComputeType;
|
||||
import org.jclouds.compute.domain.CreateNodeResponse;
|
||||
import org.jclouds.compute.domain.LoginType;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.Size;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
|
||||
import org.jclouds.predicates.RetryablePredicate;
|
||||
import org.jclouds.predicates.SocketOpen;
|
||||
import org.jclouds.ssh.ExecResponse;
|
||||
import org.jclouds.ssh.SshClient;
|
||||
import org.jclouds.ssh.SshException;
|
||||
import org.jclouds.compute.BaseComputeServiceLiveTest;
|
||||
import org.jclouds.ssh.jsch.config.JschSshClientModule;
|
||||
import org.testng.annotations.AfterTest;
|
||||
import org.testng.annotations.BeforeGroups;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
|
||||
/**
|
||||
*
|
||||
* Generally disabled, as it incurs higher fees.
|
||||
|
@ -62,115 +32,17 @@ import com.google.inject.Injector;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "live", enabled = true, sequential = true, testName = "ec2.EC2ComputeServiceLiveTest")
|
||||
public class EC2ComputeServiceLiveTest {
|
||||
private static final String service = "ec2";
|
||||
|
||||
protected SshClient.Factory sshFactory;
|
||||
private String nodeName = System.getProperty("user.name") + service;
|
||||
|
||||
private RetryablePredicate<InetSocketAddress> socketTester;
|
||||
private CreateNodeResponse node;
|
||||
private ComputeServiceContext context;
|
||||
private ComputeService client;
|
||||
|
||||
@BeforeGroups(groups = { "live" })
|
||||
public void setupClient() throws InterruptedException, ExecutionException, TimeoutException,
|
||||
IOException {
|
||||
String user = checkNotNull(System.getProperty("jclouds.test.user"), "jclouds.test.user");
|
||||
String password = checkNotNull(System.getProperty("jclouds.test.key"), "jclouds.test.key");
|
||||
context = new ComputeServiceContextFactory().createContext(service, user, password,
|
||||
ImmutableSet.of(new Log4JLoggingModule()), new Properties());
|
||||
Injector injector = Guice.createInjector(new JschSshClientModule());
|
||||
sshFactory = injector.getInstance(SshClient.Factory.class);
|
||||
SocketOpen socketOpen = injector.getInstance(SocketOpen.class);
|
||||
socketTester = new RetryablePredicate<InetSocketAddress>(socketOpen, 60, 1, TimeUnit.SECONDS);
|
||||
injector.injectMembers(socketOpen); // add logger
|
||||
client = context.getComputeService();
|
||||
public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
||||
@BeforeClass
|
||||
@Override
|
||||
public void setServiceDefaults() {
|
||||
service = "ec2";
|
||||
testOS = UBUNTU;
|
||||
}
|
||||
|
||||
public void testCreate() throws Exception {
|
||||
Template template = client.createTemplateInLocation("default").os(UBUNTU).smallest();
|
||||
node = client.runNode(nodeName, template);
|
||||
assertNotNull(node.getId());
|
||||
assertEquals(node.getLoginPort(), 22);
|
||||
assertEquals(node.getLoginType(), LoginType.SSH);
|
||||
assertNotNull(node.getName());
|
||||
assertEquals(node.getPrivateAddresses().size(), 1);
|
||||
assertEquals(node.getPublicAddresses().size(), 1);
|
||||
assertNotNull(node.getCredentials());
|
||||
assertNotNull(node.getCredentials().account);
|
||||
assertNotNull(node.getCredentials().key);
|
||||
sshPing();
|
||||
}
|
||||
|
||||
@Test(dependsOnMethods = "testCreate")
|
||||
public void testGet() throws Exception {
|
||||
NodeMetadata metadata = client.getNodeMetadata(node);
|
||||
assertEquals(metadata.getId(), node.getId());
|
||||
assertEquals(metadata.getLoginPort(), node.getLoginPort());
|
||||
assertEquals(metadata.getLoginType(), node.getLoginType());
|
||||
assertEquals(metadata.getName(), node.getName());
|
||||
assertEquals(metadata.getPrivateAddresses(), node.getPrivateAddresses());
|
||||
assertEquals(metadata.getPublicAddresses(), node.getPublicAddresses());
|
||||
}
|
||||
|
||||
public void testList() throws Exception {
|
||||
for (ComputeMetadata node : client.listNodes()) {
|
||||
assert node.getId() != null;
|
||||
assert node.getLocation() != null;
|
||||
assertEquals(node.getType(), ComputeType.NODE);
|
||||
}
|
||||
}
|
||||
|
||||
public void testListTemplates() throws Exception {
|
||||
for (Template template : client.listTemplates()) {
|
||||
assert template.getImage() != null;
|
||||
System.out.println(template);
|
||||
}
|
||||
}
|
||||
|
||||
public void testListSizes() throws Exception {
|
||||
for (Size size : client.listSizes()) {
|
||||
assert size.getCores() != null;
|
||||
System.out.println(size);
|
||||
}
|
||||
}
|
||||
|
||||
private void sshPing() throws IOException {
|
||||
try {
|
||||
doCheckKey();
|
||||
} catch (SshException e) {// try twice in case there is a network timeout
|
||||
try {
|
||||
Thread.sleep(10 * 1000);
|
||||
} catch (InterruptedException e1) {
|
||||
}
|
||||
doCheckKey();
|
||||
}
|
||||
}
|
||||
|
||||
private void doCheckKey() throws IOException {
|
||||
InetSocketAddress socket = new InetSocketAddress(node.getPublicAddresses().last(), node
|
||||
.getLoginPort());
|
||||
socketTester.apply(socket);
|
||||
SshClient ssh = node.getCredentials().key.startsWith("-----BEGIN RSA PRIVATE KEY-----") ? sshFactory
|
||||
.create(socket, node.getCredentials().account, node.getCredentials().key.getBytes())
|
||||
: sshFactory
|
||||
.create(socket, node.getCredentials().account, node.getCredentials().key);
|
||||
try {
|
||||
ssh.connect();
|
||||
ExecResponse hello = ssh.exec("echo hello");
|
||||
assertEquals(hello.getOutput().trim(), "hello");
|
||||
} finally {
|
||||
if (ssh != null)
|
||||
ssh.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
@AfterTest
|
||||
void cleanup() throws InterruptedException, ExecutionException, TimeoutException {
|
||||
if (node != null)
|
||||
client.destroyNode(node);
|
||||
context.close();
|
||||
@Override
|
||||
protected JschSshClientModule getSshModule() {
|
||||
return new JschSshClientModule();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,50 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed 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.blobstore;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import org.jclouds.blobstore.reference.BlobStoreConstants;
|
||||
import org.jclouds.http.HttpPropertiesBuilder;
|
||||
|
||||
/**
|
||||
* Builds properties used in Blob Stores
|
||||
*
|
||||
* @author Adrian Cole, Andrew Newdigate
|
||||
*/
|
||||
public class BlobStorePropertiesBuilder extends HttpPropertiesBuilder {
|
||||
|
||||
protected BlobStorePropertiesBuilder() {
|
||||
super();
|
||||
}
|
||||
|
||||
protected BlobStorePropertiesBuilder(Properties properties) {
|
||||
super(properties);
|
||||
}
|
||||
|
||||
/**
|
||||
* longest time a single synchronous operation can take before throwing an exception.
|
||||
*/
|
||||
public BlobStorePropertiesBuilder withRequestTimeout(long milliseconds) {
|
||||
properties.setProperty(BlobStoreConstants.PROPERTY_BLOBSTORE_TIMEOUT, Long
|
||||
.toString(milliseconds));
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
|
@ -18,6 +18,7 @@
|
|||
*/
|
||||
package org.jclouds.blobstore.integration;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.jclouds.http.HttpPropertiesBuilder;
|
||||
|
@ -37,4 +38,14 @@ public class StubPropertiesBuilder extends HttpPropertiesBuilder {
|
|||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpPropertiesBuilder withCredentials(String account, String key) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpPropertiesBuilder withEndpoint(URI endpoint) {
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -40,6 +40,11 @@
|
|||
</scm>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>jclouds-scriptbuilder</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>jclouds-core</artifactId>
|
||||
|
@ -52,5 +57,17 @@
|
|||
<type>test-jar</type>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>jclouds-log4j</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
<version>1.2.14</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
|
@ -19,12 +19,14 @@
|
|||
package org.jclouds.compute;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.SortedSet;
|
||||
|
||||
import org.jclouds.compute.domain.ComputeMetadata;
|
||||
import org.jclouds.compute.domain.CreateNodeResponse;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.Size;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.compute.options.RunNodeOptions;
|
||||
|
||||
/**
|
||||
* Provides portable access to launching compute instances.
|
||||
|
@ -44,7 +46,12 @@ public interface ComputeService {
|
|||
/**
|
||||
* List all sizes available to the current user
|
||||
*/
|
||||
Set<? extends Size> listSizes();
|
||||
SortedSet<? extends Size> listSizes();
|
||||
|
||||
/**
|
||||
* List all images available to the current user
|
||||
*/
|
||||
// Set<? extends Image> listImages();
|
||||
|
||||
/**
|
||||
* List all templates available to the current user
|
||||
|
@ -61,6 +68,7 @@ public interface ComputeService {
|
|||
*
|
||||
*/
|
||||
CreateNodeResponse runNode(String name, Template template);
|
||||
CreateNodeResponse runNode(String name, Template template, RunNodeOptions options);
|
||||
|
||||
/**
|
||||
* destroy the node.
|
||||
|
|
|
@ -29,6 +29,5 @@ package org.jclouds.compute.domain;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
public enum OperatingSystem {
|
||||
|
||||
CENTOS, RHEL, UBUNTU, WINDOWS, UNKNOWN;
|
||||
CENTOS, RHEL, UBUNTU, JEOS, WINDOWS, UNKNOWN;
|
||||
}
|
|
@ -33,17 +33,17 @@ public interface Size extends Comparable<Size> {
|
|||
/**
|
||||
* Amount of virtual or physical cores provided
|
||||
*/
|
||||
Integer getCores();
|
||||
int getCores();
|
||||
|
||||
/**
|
||||
* Amount of RAM provided in MB (256M, 1740)
|
||||
*/
|
||||
Integer getRam();
|
||||
int getRam();
|
||||
|
||||
/**
|
||||
* Amount of boot disk provided in GB (200)
|
||||
*/
|
||||
Integer getDisk();
|
||||
int getDisk();
|
||||
|
||||
/**
|
||||
* Determines platforms this can support
|
||||
|
|
|
@ -23,6 +23,7 @@ import java.util.Set;
|
|||
import org.jclouds.compute.domain.Architecture;
|
||||
import org.jclouds.compute.domain.Size;
|
||||
|
||||
import com.google.common.collect.ComparisonChain;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
|
@ -31,13 +32,12 @@ import com.google.common.collect.Sets;
|
|||
*/
|
||||
public class SizeImpl implements Size {
|
||||
|
||||
private final Integer cores;
|
||||
private final Integer ram;
|
||||
private final Integer disk;
|
||||
private final int cores;
|
||||
private final int ram;
|
||||
private final int disk;
|
||||
private final Set<Architecture> supportedArchitectures = Sets.newHashSet();
|
||||
|
||||
public SizeImpl(Integer cores, Integer ram, Integer disk,
|
||||
Iterable<Architecture> supportedArchitectures) {
|
||||
public SizeImpl(int cores, int ram, int disk, Iterable<Architecture> supportedArchitectures) {
|
||||
this.cores = cores;
|
||||
this.ram = ram;
|
||||
this.disk = disk;
|
||||
|
@ -48,7 +48,7 @@ public class SizeImpl implements Size {
|
|||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Integer getCores() {
|
||||
public int getCores() {
|
||||
return cores;
|
||||
}
|
||||
|
||||
|
@ -56,7 +56,7 @@ public class SizeImpl implements Size {
|
|||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Integer getRam() {
|
||||
public int getRam() {
|
||||
return ram;
|
||||
}
|
||||
|
||||
|
@ -64,7 +64,7 @@ public class SizeImpl implements Size {
|
|||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Integer getDisk() {
|
||||
public int getDisk() {
|
||||
return disk;
|
||||
}
|
||||
|
||||
|
@ -72,9 +72,9 @@ public class SizeImpl implements Size {
|
|||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((cores == null) ? 0 : cores.hashCode());
|
||||
result = prime * result + ((disk == null) ? 0 : disk.hashCode());
|
||||
result = prime * result + ((ram == null) ? 0 : ram.hashCode());
|
||||
result = prime * result + cores;
|
||||
result = prime * result + disk;
|
||||
result = prime * result + ram;
|
||||
result = prime * result
|
||||
+ ((supportedArchitectures == null) ? 0 : supportedArchitectures.hashCode());
|
||||
return result;
|
||||
|
@ -89,20 +89,11 @@ public class SizeImpl implements Size {
|
|||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
SizeImpl other = (SizeImpl) obj;
|
||||
if (cores == null) {
|
||||
if (other.cores != null)
|
||||
return false;
|
||||
} else if (!cores.equals(other.cores))
|
||||
if (cores != other.cores)
|
||||
return false;
|
||||
if (disk == null) {
|
||||
if (other.disk != null)
|
||||
return false;
|
||||
} else if (!disk.equals(other.disk))
|
||||
if (disk != other.disk)
|
||||
return false;
|
||||
if (ram == null) {
|
||||
if (other.ram != null)
|
||||
return false;
|
||||
} else if (!ram.equals(other.ram))
|
||||
if (ram != other.ram)
|
||||
return false;
|
||||
if (supportedArchitectures == null) {
|
||||
if (other.supportedArchitectures != null)
|
||||
|
@ -112,20 +103,17 @@ public class SizeImpl implements Size {
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SizeImpl [cores=" + cores + ", disk=" + disk + ", ram=" + ram + "]";
|
||||
public int compareTo(Size that) {
|
||||
return ComparisonChain.start().compare(this.getCores(), that.getCores()).compare(
|
||||
this.getRam(), that.getRam()).compare(this.getDisk(), that.getDisk()).result();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public int compareTo(Size o) {
|
||||
return (this == o) ? 0 : getCores().compareTo(o.getCores());
|
||||
public String toString() {
|
||||
return "Size [cores=" + cores + ", disk=" + disk + ", ram=" + ram + "]";
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
package org.jclouds.compute.options;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* Contains options supported in the {@code ComputeService#runNode} operation. <h2>
|
||||
* Usage</h2> The recommended way to instantiate a RunOptions object is to statically import
|
||||
* RunOptions.* and invoke a static creation method followed by an instance mutator (if needed):
|
||||
* <p/>
|
||||
* <code>
|
||||
* import static org.jclouds.compute.options.RunOptions.Builder.*
|
||||
* <p/>
|
||||
* ComputeService client = // get connection
|
||||
* CreateNodeResponse client.runNode(name, template, openPorts(22, 80, 8080, 443));
|
||||
* <code>
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class RunNodeOptions {
|
||||
|
||||
public static final RunNodeOptions NONE = new RunNodeOptions();
|
||||
|
||||
private int[] openPorts = new int[0];
|
||||
|
||||
private byte[] script;
|
||||
|
||||
public int[] getOpenPorts() {
|
||||
return openPorts;
|
||||
}
|
||||
|
||||
public byte[] getRunScript() {
|
||||
return script;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This script will be executed as the root user upon system startup.
|
||||
*/
|
||||
public RunNodeOptions runScript(byte[] script) {
|
||||
checkArgument(checkNotNull(script, "script").length <= 16 * 1024,
|
||||
"script cannot be larger than 16kb");
|
||||
this.script = script;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the set of ports to public access.
|
||||
*/
|
||||
public RunNodeOptions openPorts(int... ports) {
|
||||
this.openPorts = ports;
|
||||
return this;
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
|
||||
/**
|
||||
* @see RunNodeOptions#openPorts
|
||||
*/
|
||||
public static RunNodeOptions openPorts(int... ports) {
|
||||
RunNodeOptions options = new RunNodeOptions();
|
||||
return options.openPorts(ports);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see RunNodeOptions#runScript
|
||||
*/
|
||||
public static RunNodeOptions runScript(byte[] script) {
|
||||
RunNodeOptions options = new RunNodeOptions();
|
||||
return options.runScript(script);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -19,6 +19,7 @@
|
|||
package org.jclouds.compute.util;
|
||||
|
||||
import org.jclouds.compute.domain.ComputeMetadata;
|
||||
import org.jclouds.compute.domain.CreateNodeResponse;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
@ -28,8 +29,8 @@ import com.google.common.collect.Iterables;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
public class ComputeUtils {
|
||||
public static Iterable<? extends ComputeMetadata> filterByName(Iterable<? extends ComputeMetadata> nodes,
|
||||
final String name) {
|
||||
public static Iterable<? extends ComputeMetadata> filterByName(
|
||||
Iterable<? extends ComputeMetadata> nodes, final String name) {
|
||||
return Iterables.filter(nodes, new Predicate<ComputeMetadata>() {
|
||||
@Override
|
||||
public boolean apply(ComputeMetadata input) {
|
||||
|
@ -38,4 +39,7 @@ public class ComputeUtils {
|
|||
});
|
||||
}
|
||||
|
||||
public static boolean isKeyAuth(CreateNodeResponse createdNode) {
|
||||
return createdNode.getCredentials().key.startsWith("-----BEGIN RSA PRIVATE KEY-----");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,216 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed 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.compute;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.jclouds.compute.domain.ComputeMetadata;
|
||||
import org.jclouds.compute.domain.ComputeType;
|
||||
import org.jclouds.compute.domain.CreateNodeResponse;
|
||||
import org.jclouds.compute.domain.LoginType;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.OperatingSystem;
|
||||
import org.jclouds.compute.domain.Size;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.compute.options.RunNodeOptions;
|
||||
import org.jclouds.http.HttpResponseException;
|
||||
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
|
||||
import org.jclouds.predicates.RetryablePredicate;
|
||||
import org.jclouds.predicates.SocketOpen;
|
||||
import org.jclouds.scriptbuilder.ScriptBuilder;
|
||||
import org.jclouds.scriptbuilder.domain.OsFamily;
|
||||
import org.jclouds.scriptbuilder.domain.Statements;
|
||||
import org.jclouds.ssh.ExecResponse;
|
||||
import org.jclouds.ssh.SshClient;
|
||||
import org.jclouds.ssh.SshException;
|
||||
import org.testng.annotations.AfterTest;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.BeforeGroups;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Module;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "live", enabled = true, sequential = true, testName = "compute.ComputeServiceLiveTest")
|
||||
public abstract class BaseComputeServiceLiveTest {
|
||||
@BeforeClass
|
||||
abstract public void setServiceDefaults();
|
||||
|
||||
protected String service;
|
||||
protected OperatingSystem testOS;
|
||||
protected SshClient.Factory sshFactory;
|
||||
protected RunNodeOptions options = RunNodeOptions.Builder.openPorts(22);
|
||||
private String nodeName;
|
||||
|
||||
private RetryablePredicate<InetSocketAddress> socketTester;
|
||||
private CreateNodeResponse node;
|
||||
protected ComputeServiceContext context;
|
||||
protected ComputeService client;
|
||||
protected String user;
|
||||
protected String password;
|
||||
|
||||
@BeforeGroups(groups = { "live" })
|
||||
public void setupClient() throws InterruptedException, ExecutionException, TimeoutException,
|
||||
IOException {
|
||||
checkNotNull(testOS, "testOS");
|
||||
nodeName = checkNotNull(service, "service");
|
||||
if (canRunScript())
|
||||
options.runScript(new ScriptBuilder()
|
||||
// update add dns and install jdk
|
||||
.addStatement(
|
||||
Statements.exec("echo nameserver 208.67.222.222 >> /etc/resolv.conf"))
|
||||
.addStatement(Statements.exec("apt-get update"))//
|
||||
.addStatement(Statements.exec("apt-get upgrade -y"))//
|
||||
.addStatement(Statements.exec("apt-get install -y openjdk-6-jdk"))//
|
||||
.addStatement(Statements.exec("wget -qO/usr/bin/runurl run.alestic.com/runurl"))//
|
||||
.addStatement(Statements.exec("chmod 755 /usr/bin/runurl"))//
|
||||
.build(OsFamily.UNIX).getBytes());
|
||||
user = checkNotNull(System.getProperty("jclouds.test.user"), "jclouds.test.user");
|
||||
password = checkNotNull(System.getProperty("jclouds.test.key"), "jclouds.test.key");
|
||||
context = new ComputeServiceContextFactory().createContext(service, user, password,
|
||||
ImmutableSet.of(new Log4JLoggingModule(), getSshModule()), new Properties());
|
||||
Injector injector = Guice.createInjector(getSshModule());
|
||||
sshFactory = injector.getInstance(SshClient.Factory.class);
|
||||
SocketOpen socketOpen = injector.getInstance(SocketOpen.class);
|
||||
socketTester = new RetryablePredicate<InetSocketAddress>(socketOpen, 60, 1, TimeUnit.SECONDS);
|
||||
injector.injectMembers(socketOpen); // add logger
|
||||
client = context.getComputeService();
|
||||
}
|
||||
|
||||
private boolean canRunScript() {
|
||||
return testOS == OperatingSystem.UBUNTU || testOS == OperatingSystem.JEOS;
|
||||
}
|
||||
|
||||
abstract protected Module getSshModule();
|
||||
|
||||
public void testCreate() throws Exception {
|
||||
try {
|
||||
client.destroyNode(Iterables.find(client.listNodes(), new Predicate<ComputeMetadata>() {
|
||||
@Override
|
||||
public boolean apply(ComputeMetadata input) {
|
||||
return input.getName().equals(nodeName);
|
||||
}
|
||||
}));
|
||||
} catch (HttpResponseException e) {
|
||||
// TODO hosting.com throws 400 when we try to delete a vApp
|
||||
} catch (NoSuchElementException e) {
|
||||
|
||||
}
|
||||
Template template = client.createTemplateInLocation("default").os(testOS).smallest();
|
||||
node = client.runNode(nodeName, template, options);
|
||||
assertNotNull(node.getId());
|
||||
assertEquals(node.getLoginPort(), 22);
|
||||
assertEquals(node.getLoginType(), LoginType.SSH);
|
||||
assertNotNull(node.getName());
|
||||
assertEquals(node.getPublicAddresses().size(), 1);
|
||||
assertNotNull(node.getCredentials());
|
||||
assertNotNull(node.getCredentials().account);
|
||||
assertNotNull(node.getCredentials().key);
|
||||
sshPing();
|
||||
}
|
||||
|
||||
@Test(dependsOnMethods = "testCreate")
|
||||
public void testGet() throws Exception {
|
||||
NodeMetadata metadata = client.getNodeMetadata(node);
|
||||
assertEquals(metadata.getId(), node.getId());
|
||||
assertEquals(metadata.getLoginPort(), node.getLoginPort());
|
||||
assertEquals(metadata.getLoginType(), node.getLoginType());
|
||||
assertEquals(metadata.getName(), node.getName());
|
||||
assertEquals(metadata.getPrivateAddresses(), node.getPrivateAddresses());
|
||||
assertEquals(metadata.getPublicAddresses(), node.getPublicAddresses());
|
||||
}
|
||||
|
||||
public void testList() throws Exception {
|
||||
for (ComputeMetadata node : client.listNodes()) {
|
||||
assert node.getId() != null;
|
||||
assert node.getLocation() != null;
|
||||
assertEquals(node.getType(), ComputeType.NODE);
|
||||
}
|
||||
}
|
||||
|
||||
public void testListTemplates() throws Exception {
|
||||
for (Template template : client.listTemplates()) {
|
||||
assert template.getImage() != null;
|
||||
}
|
||||
}
|
||||
|
||||
public void testListSizes() throws Exception {
|
||||
for (Size size : client.listSizes()) {
|
||||
assert size.getCores() > 0;
|
||||
}
|
||||
}
|
||||
|
||||
private void sshPing() throws IOException {
|
||||
try {
|
||||
doCheckKey();
|
||||
} catch (SshException e) {// try twice in case there is a network timeout
|
||||
try {
|
||||
Thread.sleep(10 * 1000);
|
||||
} catch (InterruptedException e1) {
|
||||
}
|
||||
doCheckKey();
|
||||
}
|
||||
}
|
||||
|
||||
private void doCheckKey() throws IOException {
|
||||
InetSocketAddress socket = new InetSocketAddress(node.getPublicAddresses().last(), node
|
||||
.getLoginPort());
|
||||
socketTester.apply(socket);
|
||||
SshClient ssh = node.getCredentials().key.startsWith("-----BEGIN RSA PRIVATE KEY-----") ? sshFactory
|
||||
.create(socket, node.getCredentials().account, node.getCredentials().key.getBytes())
|
||||
: sshFactory
|
||||
.create(socket, node.getCredentials().account, node.getCredentials().key);
|
||||
try {
|
||||
ssh.connect();
|
||||
ExecResponse hello = ssh.exec("echo hello");
|
||||
assertEquals(hello.getOutput().trim(), "hello");
|
||||
if (canRunScript())
|
||||
System.out.println(ssh.exec("java -version"));
|
||||
} finally {
|
||||
if (ssh != null)
|
||||
ssh.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
@AfterTest
|
||||
void cleanup() throws InterruptedException, ExecutionException, TimeoutException {
|
||||
if (node != null)
|
||||
client.destroyNode(node);
|
||||
context.close();
|
||||
}
|
||||
|
||||
}
|
|
@ -27,6 +27,7 @@ import static org.jclouds.http.pool.PoolConstants.PROPERTY_POOL_MAX_CONNECTIONS;
|
|||
import static org.jclouds.http.pool.PoolConstants.PROPERTY_POOL_MAX_CONNECTION_REUSE;
|
||||
import static org.jclouds.http.pool.PoolConstants.PROPERTY_POOL_MAX_SESSION_FAILURES;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Properties;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
|
@ -36,7 +37,7 @@ import com.google.common.annotations.VisibleForTesting;
|
|||
*
|
||||
* @author Adrian Cole, Andrew Newdigate
|
||||
*/
|
||||
public class HttpPropertiesBuilder {
|
||||
public abstract class HttpPropertiesBuilder {
|
||||
|
||||
/**
|
||||
* @see org.jclouds.http.HttpConstants.PROPERTY_HTTP_RELAX_HOSTNAME
|
||||
|
@ -122,9 +123,8 @@ public class HttpPropertiesBuilder {
|
|||
this.properties.putAll(properties);
|
||||
}
|
||||
|
||||
public HttpPropertiesBuilder withCredentials(String account, String key) {
|
||||
return this;
|
||||
}
|
||||
public abstract HttpPropertiesBuilder withEndpoint(URI endpoint);
|
||||
public abstract HttpPropertiesBuilder withCredentials(String account, String key);
|
||||
|
||||
@VisibleForTesting
|
||||
public Properties build() {
|
||||
|
|
|
@ -110,30 +110,18 @@ public class HttpRequest extends HttpMessage {
|
|||
setLength();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void setPayload(InputStream data) {
|
||||
setPayload(Payloads.newPayload(checkNotNull(data, "data")));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void setPayload(byte[] data) {
|
||||
setPayload(Payloads.newPayload(checkNotNull(data, "data")));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void setPayload(String data) {
|
||||
setPayload(Payloads.newPayload(checkNotNull(data, "data")));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void setPayload(File data) {
|
||||
setPayload(Payloads.newPayload(checkNotNull(data, "data")));
|
||||
}
|
||||
|
|
|
@ -48,10 +48,10 @@ public abstract class RestContextFactory<T, B extends RestContextBuilder<?, ?>>
|
|||
* Initializes with the default properties built-in to jclouds. This is typically stored in the
|
||||
* classpath resource {@code filename}
|
||||
*
|
||||
* @parma filename name of the properties file to initialize from
|
||||
* @param filename name of the properties file to initialize from
|
||||
* @throws IOException
|
||||
* if the default properties file cannot be loaded
|
||||
* @see #init
|
||||
* @see #getPropertiesFromResource
|
||||
*/
|
||||
public RestContextFactory(String filename) throws IOException {
|
||||
this(getPropertiesFromResource(filename));
|
||||
|
@ -82,6 +82,7 @@ public abstract class RestContextFactory<T, B extends RestContextBuilder<?, ?>>
|
|||
static Properties getPropertiesFromResource(String filename) throws IOException {
|
||||
Properties properties = new Properties();
|
||||
properties.load(Resources.newInputStreamSupplier(Resources.getResource(filename)).getInput());
|
||||
properties.putAll(System.getProperties());
|
||||
return properties;
|
||||
}
|
||||
|
||||
|
@ -125,8 +126,7 @@ public abstract class RestContextFactory<T, B extends RestContextBuilder<?, ?>>
|
|||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* FIXME Comment this // ImmutableSet.<Module>of(new ExecutorServiceModule(myexecutor))
|
||||
* Creates a new remote context.
|
||||
*
|
||||
* @param hint
|
||||
* @param account
|
||||
|
@ -134,8 +134,11 @@ public abstract class RestContextFactory<T, B extends RestContextBuilder<?, ?>>
|
|||
* @param key
|
||||
* nullable, if credentials are present in the overrides
|
||||
* @param modules
|
||||
* Configuration you'd like to pass to the context. Ex. ImmutableSet.<Module>of(new
|
||||
* ExecutorServiceModule(myexecutor))
|
||||
* @param overrides
|
||||
* @return
|
||||
* properties to override defaults with.
|
||||
* @return initialized context ready for use
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public T createContext(String hint, @Nullable String account, @Nullable String key,
|
||||
|
@ -151,6 +154,8 @@ public abstract class RestContextFactory<T, B extends RestContextBuilder<?, ?>>
|
|||
String contextBuilderClassName = checkNotNull(properties.getProperty(contextBuilderKey),
|
||||
contextBuilderKey);
|
||||
|
||||
String endpointKey = String.format("%s.endpoint", hint);
|
||||
String endpoint = properties.getProperty(endpointKey);
|
||||
try {
|
||||
Class<HttpPropertiesBuilder> propertiesBuilderClass = (Class<HttpPropertiesBuilder>) Class
|
||||
.forName(propertiesBuilderClassName);
|
||||
|
@ -159,7 +164,8 @@ public abstract class RestContextFactory<T, B extends RestContextBuilder<?, ?>>
|
|||
.newInstance(overrides);
|
||||
if (key != null)
|
||||
builder.withCredentials(account, key);
|
||||
|
||||
if (endpoint != null)
|
||||
builder.withEndpoint(URI.create(endpoint));
|
||||
B contextBuilder = (B) contextBuilderClass.getConstructor(Properties.class).newInstance(
|
||||
builder.build()).withModules(Iterables.toArray(modules, Module.class));
|
||||
return build(contextBuilder);
|
||||
|
|
|
@ -41,12 +41,6 @@ public class InputStreamChain extends InputStream {
|
|||
*/
|
||||
private InputStream current;
|
||||
|
||||
/**
|
||||
* Constructor with an initial stream
|
||||
*
|
||||
* @param first
|
||||
* Initial InputStream
|
||||
*/
|
||||
public InputStreamChain(InputStream... inputStreams) {
|
||||
for (InputStream stream : inputStreams) {
|
||||
addInputStream(stream);
|
||||
|
|
|
@ -32,6 +32,7 @@ import com.google.common.collect.MapMaker;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
public class Patterns {
|
||||
public static final Pattern TOKEN_PATTERN = Pattern.compile("\\{(.+?)\\}");
|
||||
public static final Pattern TWO_SPACE_PATTERN = Pattern.compile(" ");
|
||||
public static final Pattern URL_ENCODED_PATTERN = Pattern.compile(".*%[a-fA-F0-9][a-fA-F0-9].*");
|
||||
public static final Pattern URI_PATTERN = Pattern.compile("([a-z0-9]+)://([^:]*):(.*)@(.*)");
|
||||
|
|
|
@ -43,7 +43,7 @@ import com.google.common.io.Closeables;
|
|||
import com.google.common.io.OutputSupplier;
|
||||
|
||||
/**
|
||||
* // TODO: Adrian: Document this!
|
||||
* General utilities used in jclouds code.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
|
@ -137,14 +137,16 @@ public class Utils {
|
|||
* @see {@link String#getBytes()} - used as fall-back.
|
||||
*
|
||||
* @param str
|
||||
* @param encoding
|
||||
* @return
|
||||
* what to encode
|
||||
* @param charsetName
|
||||
* the name of a supported {@link java.nio.charset.Charset </code>charset<code>}
|
||||
* @return properly encoded String.
|
||||
*/
|
||||
public static byte[] encodeString(String str, String encoding) {
|
||||
public static byte[] encodeString(String str, String charsetName) {
|
||||
try {
|
||||
return str.getBytes(encoding);
|
||||
return str.getBytes(charsetName);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
logger.warn(e, "Failed to encode string to bytes with encoding " + encoding
|
||||
logger.warn(e, "Failed to encode string to bytes with encoding " + charsetName
|
||||
+ ". Falling back to system's default encoding");
|
||||
return str.getBytes();
|
||||
}
|
||||
|
@ -156,45 +158,13 @@ public class Utils {
|
|||
* the system's default encoding.
|
||||
*
|
||||
* @param str
|
||||
* @return
|
||||
* what to encode
|
||||
* @return properly encoded String.
|
||||
*/
|
||||
public static byte[] encodeString(String str) {
|
||||
return encodeString(str, UTF8_ENCODING);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode the given string with the given encoding, if possible. If the decoding fails with
|
||||
* {@link UnsupportedEncodingException}, log a warning and fall back to the system's default
|
||||
* encoding.
|
||||
*
|
||||
* @param bytes
|
||||
* @param encoding
|
||||
* @return
|
||||
*/
|
||||
public static String decodeString(byte[] bytes, String encoding) {
|
||||
try {
|
||||
return new String(bytes, encoding);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
logger.warn(e, "Failed to decode bytes to string with encoding " + encoding
|
||||
+ ". Falling back to system's default encoding");
|
||||
return new String(bytes);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode the given string with the UTF-8 encoding, the sane default. In the very unlikely event
|
||||
* the encoding fails with {@link UnsupportedEncodingException}, log a warning and fall back to
|
||||
* the system's default encoding.
|
||||
*
|
||||
* @param str
|
||||
* @return
|
||||
*/
|
||||
public static String decodeString(byte[] bytes) {
|
||||
return decodeString(bytes, UTF8_ENCODING);
|
||||
}
|
||||
|
||||
public static final Pattern pattern = Pattern.compile("\\{(.+?)\\}");
|
||||
|
||||
/**
|
||||
* replaces tokens that are expressed as <code>{token}</code>
|
||||
*
|
||||
|
@ -209,7 +179,7 @@ public class Utils {
|
|||
* token/value pairs
|
||||
*/
|
||||
public static String replaceTokens(String input, Map<String, String> replacements) {
|
||||
Matcher matcher = pattern.matcher(input);
|
||||
Matcher matcher = Patterns.TOKEN_PATTERN.matcher(input);
|
||||
StringBuilder builder = new StringBuilder();
|
||||
int i = 0;
|
||||
while (matcher.find()) {
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
*/
|
||||
package org.jclouds.http;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.testng.annotations.Test;
|
||||
|
@ -37,7 +38,18 @@ public class HttpPropertiesBuilderTest {
|
|||
int poolMaxClients = 3382;
|
||||
int poolMaxSessionFailures = 857;
|
||||
|
||||
HttpPropertiesBuilder builder = new HttpPropertiesBuilder(new Properties());
|
||||
HttpPropertiesBuilder builder = new HttpPropertiesBuilder(new Properties()) {
|
||||
|
||||
@Override
|
||||
public HttpPropertiesBuilder withCredentials(String account, String key) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpPropertiesBuilder withEndpoint(URI endpoint) {
|
||||
return this;
|
||||
}
|
||||
};
|
||||
builder.withHttpMaxRetries(httpMaxRetries);
|
||||
|
||||
builder.withPoolIoWorkerThreads(poolIoWorkerThreads);
|
||||
|
|
|
@ -21,11 +21,15 @@ package org.jclouds.nirvanix.sdn;
|
|||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.jclouds.http.HttpPropertiesBuilder;
|
||||
import org.jclouds.nirvanix.sdn.reference.SDNConstants;
|
||||
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
/**
|
||||
* Builds properties used in SDN Clients
|
||||
*
|
||||
|
@ -65,4 +69,13 @@ public class SDNPropertiesBuilder extends HttpPropertiesBuilder {
|
|||
.toString());
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SDNPropertiesBuilder withCredentials(String account, String key) {
|
||||
List<String> parts = Lists.newArrayList(Splitter.on('/').split(account));
|
||||
if (parts.size() != 3) {
|
||||
throw new IllegalArgumentException("account syntax is appkey/appname/username");
|
||||
}
|
||||
return withCredentials(parts.get(0), parts.get(1), parts.get(2), key);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,15 +19,17 @@
|
|||
package org.jclouds.rimuhosting.miro;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import org.jclouds.http.HttpPropertiesBuilder;
|
||||
import static org.jclouds.rimuhosting.miro.reference.RimuHostingConstants.*;
|
||||
import static org.jclouds.rimuhosting.miro.reference.RimuHostingConstants.PROPERTY_RIMUHOSTING_APIKEY;
|
||||
import static org.jclouds.rimuhosting.miro.reference.RimuHostingConstants.PROPERTY_RIMUHOSTING_ENDPOINT;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.jclouds.http.HttpPropertiesBuilder;
|
||||
|
||||
/**
|
||||
* Builds properties used in RimuHosting Clients
|
||||
*
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class RimuHostingPropertiesBuilder extends HttpPropertiesBuilder {
|
||||
|
@ -52,9 +54,15 @@ public class RimuHostingPropertiesBuilder extends HttpPropertiesBuilder {
|
|||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RimuHostingPropertiesBuilder withEndpoint(URI endpoint) {
|
||||
properties.setProperty(PROPERTY_RIMUHOSTING_ENDPOINT, checkNotNull(endpoint, "endpoint")
|
||||
.toString());
|
||||
.toString());
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpPropertiesBuilder withCredentials(String account, String key) {
|
||||
return withCredentials(account != null ? account : key);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ import java.net.InetAddress;
|
|||
import java.net.UnknownHostException;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.SortedSet;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Inject;
|
||||
|
@ -43,6 +44,7 @@ import org.jclouds.compute.domain.Size;
|
|||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.compute.domain.internal.ComputeMetadataImpl;
|
||||
import org.jclouds.compute.domain.internal.CreateNodeResponseImpl;
|
||||
import org.jclouds.compute.options.RunNodeOptions;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.logging.Logger;
|
||||
|
@ -82,6 +84,11 @@ public class RimuHostingComputeService implements ComputeService {
|
|||
|
||||
@Override
|
||||
public CreateNodeResponse runNode(String name, Template template) {
|
||||
return this.runNode(name, template, RunNodeOptions.NONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CreateNodeResponse runNode(String name, Template template, RunNodeOptions options) {
|
||||
NewServerResponse serverResponse = rhClient.createServer(name, checkNotNull(imageNameMap
|
||||
.get(template.getImage().getOperatingSystem()), "os not supported: "
|
||||
+ template.getImage().getOperatingSystem()), "MIRO1B");
|
||||
|
@ -144,7 +151,7 @@ public class RimuHostingComputeService implements ComputeService {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Set<? extends Size> listSizes() {
|
||||
public SortedSet<? extends Size> listSizes() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,156 +18,28 @@
|
|||
*/
|
||||
package org.jclouds.rimuhosting.miro.compute;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.jclouds.compute.domain.OperatingSystem.UBUNTU;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.jclouds.compute.ComputeService;
|
||||
import org.jclouds.compute.ComputeServiceContext;
|
||||
import org.jclouds.compute.ComputeServiceContextFactory;
|
||||
import org.jclouds.compute.domain.ComputeMetadata;
|
||||
import org.jclouds.compute.domain.ComputeType;
|
||||
import org.jclouds.compute.domain.CreateNodeResponse;
|
||||
import org.jclouds.compute.domain.LoginType;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.Size;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
|
||||
import org.jclouds.predicates.RetryablePredicate;
|
||||
import org.jclouds.predicates.SocketOpen;
|
||||
import org.jclouds.ssh.ExecResponse;
|
||||
import org.jclouds.ssh.SshClient;
|
||||
import org.jclouds.ssh.SshException;
|
||||
import org.jclouds.compute.BaseComputeServiceLiveTest;
|
||||
import org.jclouds.ssh.jsch.config.JschSshClientModule;
|
||||
import org.testng.annotations.AfterTest;
|
||||
import org.testng.annotations.BeforeGroups;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
|
||||
/**
|
||||
* @author Ivan Meredith
|
||||
*/
|
||||
@Test(groups = "live", sequential = true, testName = "rimuhosting.RimuHostingNodeServiceLiveTest")
|
||||
public class RimuHostingComputeServiceLiveTest {
|
||||
private static final String service = "rimuhosting";
|
||||
|
||||
protected SshClient.Factory sshFactory;
|
||||
private String nodeName = System.getProperty("user.name") + service;
|
||||
|
||||
private RetryablePredicate<InetSocketAddress> socketTester;
|
||||
private CreateNodeResponse node;
|
||||
private ComputeServiceContext context;
|
||||
private ComputeService client;
|
||||
|
||||
@BeforeGroups(groups = { "live" })
|
||||
public void setupClient() throws InterruptedException, ExecutionException, TimeoutException,
|
||||
IOException {
|
||||
String user = checkNotNull(System.getProperty("jclouds.test.user"), "jclouds.test.user");
|
||||
String password = checkNotNull(System.getProperty("jclouds.test.key"), "jclouds.test.key");
|
||||
context = new ComputeServiceContextFactory().createContext(service, user, password,
|
||||
ImmutableSet.of(new Log4JLoggingModule()), new Properties());
|
||||
Injector injector = Guice.createInjector(new JschSshClientModule());
|
||||
sshFactory = injector.getInstance(SshClient.Factory.class);
|
||||
SocketOpen socketOpen = injector.getInstance(SocketOpen.class);
|
||||
socketTester = new RetryablePredicate<InetSocketAddress>(socketOpen, 60, 1, TimeUnit.SECONDS);
|
||||
injector.injectMembers(socketOpen); // add logger
|
||||
client = context.getComputeService();
|
||||
public class RimuHostingComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
||||
@BeforeClass
|
||||
@Override
|
||||
public void setServiceDefaults() {
|
||||
service = "rimuhosting";
|
||||
testOS = UBUNTU;
|
||||
}
|
||||
|
||||
public void testCreate() throws Exception {
|
||||
Template template = client.createTemplateInLocation("default").os(UBUNTU).smallest();
|
||||
node = client.runNode(nodeName, template);
|
||||
assertNotNull(node.getId());
|
||||
assertEquals(node.getLoginPort(), 22);
|
||||
assertEquals(node.getLoginType(), LoginType.SSH);
|
||||
assertNotNull(node.getName());
|
||||
assertEquals(node.getPrivateAddresses().size(), 1);
|
||||
assertEquals(node.getPublicAddresses().size(), 1);
|
||||
assertNotNull(node.getCredentials());
|
||||
assertNotNull(node.getCredentials().account);
|
||||
assertNotNull(node.getCredentials().key);
|
||||
sshPing();
|
||||
@Override
|
||||
protected JschSshClientModule getSshModule() {
|
||||
return new JschSshClientModule();
|
||||
}
|
||||
|
||||
@Test(dependsOnMethods = "testCreate")
|
||||
public void testGet() throws Exception {
|
||||
NodeMetadata metadata = client.getNodeMetadata(node);
|
||||
assertEquals(metadata.getId(), node.getId());
|
||||
assertEquals(metadata.getLoginPort(), node.getLoginPort());
|
||||
assertEquals(metadata.getLoginType(), node.getLoginType());
|
||||
assertEquals(metadata.getName(), node.getName());
|
||||
assertEquals(metadata.getPrivateAddresses(), node.getPrivateAddresses());
|
||||
assertEquals(metadata.getPublicAddresses(), node.getPublicAddresses());
|
||||
}
|
||||
|
||||
public void testList() throws Exception {
|
||||
for (ComputeMetadata node : client.listNodes()) {
|
||||
assert node.getId() != null;
|
||||
assert node.getLocation() != null;
|
||||
assertEquals(node.getType(), ComputeType.NODE);
|
||||
}
|
||||
}
|
||||
|
||||
public void testListTemplates() throws Exception {
|
||||
for (Template template : client.listTemplates()) {
|
||||
assert template.getImage() != null;
|
||||
System.out.println(template);
|
||||
}
|
||||
}
|
||||
|
||||
public void testListSizes() throws Exception {
|
||||
for (Size size : client.listSizes()) {
|
||||
assert size.getCores() != null;
|
||||
System.out.println(size);
|
||||
}
|
||||
}
|
||||
|
||||
private void sshPing() throws IOException {
|
||||
try {
|
||||
doCheckKey();
|
||||
} catch (SshException e) {// try twice in case there is a network timeout
|
||||
try {
|
||||
Thread.sleep(10 * 1000);
|
||||
} catch (InterruptedException e1) {
|
||||
}
|
||||
doCheckKey();
|
||||
}
|
||||
}
|
||||
|
||||
private void doCheckKey() throws IOException {
|
||||
InetSocketAddress socket = new InetSocketAddress(node.getPublicAddresses().last(), node
|
||||
.getLoginPort());
|
||||
socketTester.apply(socket);
|
||||
SshClient ssh = node.getCredentials().key.startsWith("-----BEGIN RSA PRIVATE KEY-----") ? sshFactory
|
||||
.create(socket, node.getCredentials().account, node.getCredentials().key.getBytes())
|
||||
: sshFactory
|
||||
.create(socket, node.getCredentials().account, node.getCredentials().key);
|
||||
try {
|
||||
ssh.connect();
|
||||
ExecResponse hello = ssh.exec("echo hello");
|
||||
assertEquals(hello.getOutput().trim(), "hello");
|
||||
} finally {
|
||||
if (ssh != null)
|
||||
ssh.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
@AfterTest
|
||||
void cleanup() throws InterruptedException, ExecutionException, TimeoutException {
|
||||
if (node != null)
|
||||
client.destroyNode(node);
|
||||
context.close();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
|
||||
Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
|
||||
====================================================================
|
||||
|
@ -23,6 +22,7 @@
|
|||
<property file="build.properties" />
|
||||
<property name="password" value="" />
|
||||
<property name="keyfile" value="" />
|
||||
<property name="listenport" value="8080" />
|
||||
<property name="container.zip" value="http://www.ibiblio.org/pub/mirrors/apache/tomcat/tomcat-6/v6.0.20/bin/apache-tomcat-6.0.20.zip" />
|
||||
<property name="warfile" value="build/samples-blazeds.war" />
|
||||
|
||||
|
@ -60,55 +60,32 @@
|
|||
<property name="service" value="terremark"/>
|
||||
<input message="What is your account on ${service}?" addproperty="account"/>
|
||||
<input message="What is the key for ${account}?" addproperty="key"/>
|
||||
<property name="jclouds.compute.nodename" value="terremark-blaze"/>
|
||||
<property name="jclouds.compute.url" value="compute://${account}:${key}@${service}"/>
|
||||
<property name="nodename" value="terremark-blaze"/>
|
||||
<property name="url" value="compute://${account}:${key}@${service}"/>
|
||||
|
||||
<target name="destroy" description="destroy the node ${jclouds.compute.nodename}">
|
||||
<compute action="destroy" provider="${jclouds.compute.url}">
|
||||
<node name="${jclouds.compute.nodename}" />
|
||||
<target name="destroy" description="destroy the node ${nodename}">
|
||||
<compute action="destroy" provider="${url}">
|
||||
<node name="${nodename}" />
|
||||
</compute>
|
||||
<sleep seconds="2" />
|
||||
</target>
|
||||
|
||||
<target name="create" description="create the node ${jclouds.compute.nodename}" depends="destroy" >
|
||||
<compute action="create" provider="${jclouds.compute.url}">
|
||||
<node name="${jclouds.compute.nodename}" os="UBUNTU" size="SMALLEST"
|
||||
hostproperty="host" usernameproperty="username" passwordproperty="password" />
|
||||
<target name="create" description="create the node ${nodename}" depends="destroy" >
|
||||
<compute action="create" provider="${url}">
|
||||
<node name="${nodename}" os="JEOS" size="SMALLEST"
|
||||
runscript="runscript.sh" openports="22,${listenport}"
|
||||
hostproperty="host" usernameproperty="username" passwordproperty="password" />
|
||||
</compute>
|
||||
|
||||
<echo message="provisioning java on: ${jclouds.compute.nodename}" />
|
||||
<property name="sudo" value="echo ${password}|sudo -S" />
|
||||
<!-- funny game to get around sudo problems with >>. first sudo is only to prime the password -->
|
||||
<sshexec host="${host}" username="${username}" password="${password}" trust="true"
|
||||
command="${sudo} echo hello;echo nameserver 208.67.222.222 |sudo tee -a /etc/resolv.conf" />
|
||||
<sshexec host="${host}" username="${username}" password="${password}" trust="true"
|
||||
command="${sudo} apt-get update -qq" />
|
||||
<sshexec host="${host}" username="${username}" password="${password}" trust="true"
|
||||
command="${sudo} apt-get upgrade -y -qq" />
|
||||
<sshexec host="${host}" username="${username}" password="${password}" trust="true"
|
||||
command="${sudo} apt-get install -y -qq wget" />
|
||||
<sshexec host="${host}" username="${username}" password="${password}" trust="true"
|
||||
command="${sudo} apt-get install -y -qq openjdk-6-jdk" />
|
||||
<sshexec host="${host}" username="${username}" password="${password}" trust="true"
|
||||
command="wget -q http://www.alliedquotes.com/mirrors/apache/tomcat/tomcat-6/v6.0.20/bin/apache-tomcat-6.0.20.tar.gz" />
|
||||
<sshexec host="${host}" username="${username}" password="${password}" trust="true"
|
||||
command="tar xzf apache-tomcat-6.0.20.tar.gz" />
|
||||
<sshexec host="${host}" username="${username}" password="${password}" trust="true"
|
||||
command="${sudo} mkdir -p /tmp/cargo/containers/" />
|
||||
<sshexec host="${host}" username="${username}" password="${password}" trust="true"
|
||||
command="${sudo} chmod 1777 /tmp/cargo" />
|
||||
<sshexec host="${host}" username="${username}" password="${password}" trust="true"
|
||||
command="${sudo} mv apache-tomcat-6.0.20 /tmp/cargo/containers/tomcat6x" />
|
||||
</target>
|
||||
|
||||
<target name="cargooverssh" depends="create" description="run cargo on remote node" >
|
||||
<echo message="deploying tomcat and blaze to: ${jclouds.compute.nodename}" />
|
||||
<echo message="deploying tomcat and blaze to: ${nodename}" />
|
||||
<cargo containerId="tomcat6x" output="build/output.log" log="build/cargo.log" action="start" timeout="600000">
|
||||
<zipurlinstaller installurl="${container.zip}" />
|
||||
<configuration home="build/cargo" type="standalone">
|
||||
<property name="cargo.java.home" value="/usr/lib/jvm/java-6-openjdk"/>
|
||||
<property name="cargo.hostname" value="${host}"/>
|
||||
<property name="cargo.servlet.port" value="8080"/>
|
||||
<property name="cargo.servlet.port" value="${listenport}"/>
|
||||
<property name="cargo.ssh.host" value="${host}"/>
|
||||
<property name="cargo.ssh.username" value="${username}"/>
|
||||
<property name="cargo.ssh.password" value="${password}"/>
|
||||
|
@ -125,7 +102,7 @@
|
|||
<cargo containerId="tomcat6x" output="build/output.log" log="build/cargo.log" action="start" timeout="600000">
|
||||
<zipurlinstaller installurl="${container.zip}" />
|
||||
<configuration home="build/cargo" type="standalone">
|
||||
<property name="cargo.servlet.port" value="8080"/>
|
||||
<property name="cargo.servlet.port" value="${listenport}"/>
|
||||
<property name="cargo.logging" value="high"/>
|
||||
<deployable type="war" file="${warfile}"/>
|
||||
</configuration>
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
echo nameserver 208.67.222.222 >> /etc/resolv.conf
|
||||
apt-get update -qq
|
||||
apt-get upgrade -y -qq
|
||||
apt-get install -y -qq wget
|
||||
apt-get install -y -qq openjdk-6-jdk
|
||||
wget -q http://www.alliedquotes.com/mirrors/apache/tomcat/tomcat-6/v6.0.20/bin/apache-tomcat-6.0.20.tar.gz
|
||||
tar xzf apache-tomcat-6.0.20.tar.gz
|
||||
mkdir -p /tmp/cargo/containers
|
||||
chmod 1777 /tmp/cargo
|
||||
mv apache-tomcat-6.0.20 /tmp/cargo/containers/tomcat6x
|
|
@ -18,37 +18,35 @@
|
|||
*/
|
||||
package org.jclouds.tools.ant.taskdefs.compute;
|
||||
|
||||
import static org.jclouds.compute.util.ComputeUtils.filterByName;
|
||||
import static org.jclouds.compute.util.ComputeUtils.isKeyAuth;
|
||||
import static org.jclouds.tools.ant.taskdefs.compute.ComputeTaskUtils.buildComputeMap;
|
||||
import static org.jclouds.tools.ant.taskdefs.compute.ComputeTaskUtils.createTemplateFromElement;
|
||||
import static org.jclouds.tools.ant.taskdefs.compute.ComputeTaskUtils.getNodeOptionsFromElement;
|
||||
import static org.jclouds.tools.ant.taskdefs.compute.ComputeTaskUtils.ipOrEmptyString;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.URI;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.SortedSet;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.apache.tools.ant.BuildException;
|
||||
import org.apache.tools.ant.Project;
|
||||
import org.apache.tools.ant.Task;
|
||||
import org.jclouds.compute.ComputeService;
|
||||
import org.jclouds.compute.ComputeServiceContext;
|
||||
import org.jclouds.compute.ComputeServiceContextFactory;
|
||||
import org.jclouds.compute.domain.ComputeMetadata;
|
||||
import org.jclouds.compute.domain.CreateNodeResponse;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.OperatingSystem;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.compute.util.ComputeUtils;
|
||||
import org.jclouds.compute.options.RunNodeOptions;
|
||||
import org.jclouds.http.HttpUtils;
|
||||
import org.jclouds.tools.ant.logging.config.AntLoggingModule;
|
||||
|
||||
import com.google.common.base.CaseFormat;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.MapMaker;
|
||||
import com.google.common.io.Files;
|
||||
import com.google.inject.Module;
|
||||
import com.google.inject.Provider;
|
||||
|
||||
/**
|
||||
|
@ -58,169 +56,133 @@ import com.google.inject.Provider;
|
|||
public class ComputeTask extends Task {
|
||||
|
||||
private final Map<URI, ComputeServiceContext> computeMap;
|
||||
private static Project project;
|
||||
/**
|
||||
* we don't have a reference to the project during the constructor, so we need to defer expansion
|
||||
* with a Provider.
|
||||
*/
|
||||
private static Provider<Iterable<? extends Module>> defaultModulesProvider = new Provider<Iterable<? extends Module>>() {
|
||||
|
||||
@Override
|
||||
public Iterable<Module> get() {
|
||||
return ImmutableSet.of((Module) new AntLoggingModule(project,
|
||||
ComputeServiceConstants.COMPUTE_LOGGER));
|
||||
}
|
||||
|
||||
};
|
||||
private String provider;
|
||||
private String action;
|
||||
private NodeElement nodeElement;
|
||||
|
||||
/**
|
||||
* we don't have a reference to the project during the constructor, so we need to defer expansion
|
||||
* with a Provider.
|
||||
*/
|
||||
private static Provider<Properties> defaultPropertiesProvider = new Provider<Properties>() {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private final Provider<Project> projectProvider = new Provider<Project>() {
|
||||
@Override
|
||||
public Properties get() {
|
||||
Properties props = new Properties();
|
||||
props.putAll(project.getProperties());
|
||||
return props;
|
||||
public Project get() {
|
||||
return getProject();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
public ComputeTask(Map<URI, ComputeServiceContext> computeMap) {
|
||||
this.computeMap = computeMap;
|
||||
public ComputeTask(@Nullable Map<URI, ComputeServiceContext> computeMap) {
|
||||
this.computeMap = computeMap != null ? computeMap : buildComputeMap(projectProvider);
|
||||
}
|
||||
|
||||
public ComputeTask() throws IOException {
|
||||
this(buildComputeMap());
|
||||
}
|
||||
|
||||
static Map<URI, ComputeServiceContext> buildComputeMap() {
|
||||
return new MapMaker().makeComputingMap(new Function<URI, ComputeServiceContext>() {
|
||||
|
||||
@Override
|
||||
public ComputeServiceContext apply(URI from) {
|
||||
try {
|
||||
return new ComputeServiceContextFactory().createContext(from, defaultModulesProvider
|
||||
.get(), defaultPropertiesProvider.get());
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
this(null);
|
||||
}
|
||||
|
||||
public static enum Action {
|
||||
CREATE, GET, LIST, LIST_DETAILS, DESTROY
|
||||
}
|
||||
|
||||
private String provider;
|
||||
private String action;
|
||||
private NodeElement nodeElement;
|
||||
|
||||
/**
|
||||
* @return the configured {@link NodeElement} element
|
||||
* makes a connection to the compute service and invokes
|
||||
*/
|
||||
public final NodeElement createNode() {
|
||||
if (getNode() == null) {
|
||||
this.nodeElement = new NodeElement();
|
||||
}
|
||||
|
||||
return this.nodeElement;
|
||||
}
|
||||
|
||||
public NodeElement getNode() {
|
||||
return this.nodeElement;
|
||||
}
|
||||
|
||||
public void execute() throws BuildException {
|
||||
ComputeTask.project = getProject();
|
||||
ComputeServiceContext context = computeMap.get(HttpUtils.createUri(provider));
|
||||
Action action = Action.valueOf(CaseFormat.LOWER_HYPHEN.to(CaseFormat.UPPER_UNDERSCORE,
|
||||
this.action));
|
||||
ComputeServiceContext context = computeMap.get(HttpUtils.createUri(provider));
|
||||
try {
|
||||
ComputeService computeService = context.getComputeService();
|
||||
switch (action) {
|
||||
case CREATE:
|
||||
case GET:
|
||||
case DESTROY:
|
||||
if (nodeElement != null) {
|
||||
switch (action) {
|
||||
case CREATE:
|
||||
create(computeService);
|
||||
break;
|
||||
case GET:
|
||||
get(computeService);
|
||||
break;
|
||||
case DESTROY:
|
||||
destroy(computeService);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
this.log("missing node element for action: " + action, Project.MSG_ERR);
|
||||
}
|
||||
break;
|
||||
case LIST:
|
||||
log("list");
|
||||
for (ComputeMetadata node : computeService.listNodes()) {
|
||||
log(String.format(" location=%s, id=%s, name=%s", node.getLocation(), node
|
||||
.getId(), node.getName()));
|
||||
}
|
||||
break;
|
||||
case LIST_DETAILS:
|
||||
log("list details");
|
||||
for (ComputeMetadata node : computeService.listNodes()) {// TODO
|
||||
// parallel
|
||||
logDetails(computeService, node);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
this.log("bad action: " + action, Project.MSG_ERR);
|
||||
}
|
||||
invokeActionOnService(action, context.getComputeService());
|
||||
} finally {
|
||||
context.close();
|
||||
}
|
||||
}
|
||||
|
||||
private void create(ComputeService computeService) {
|
||||
log(String.format("create name: %s, size: %s, os: %s", nodeElement.getName(), nodeElement
|
||||
.getSize(), nodeElement.getOs()));
|
||||
Template template = computeService.createTemplateInLocation(nodeElement.getLocation());
|
||||
template.os(OperatingSystem.valueOf(nodeElement.getOs()));
|
||||
if (nodeElement.getSize().equalsIgnoreCase("smallest")) {
|
||||
template.smallest();
|
||||
} else if (nodeElement.getSize().equalsIgnoreCase("fastest")) {
|
||||
template.fastest();
|
||||
} else if (nodeElement.getSize().equalsIgnoreCase("biggest")) {
|
||||
template.biggest();
|
||||
} else {
|
||||
throw new BuildException("size: " + nodeElement.getSize()
|
||||
+ " not supported. valid sizes are smallest, fastest, biggest");
|
||||
private void invokeActionOnService(Action action, ComputeService computeService) {
|
||||
switch (action) {
|
||||
case CREATE:
|
||||
case GET:
|
||||
case DESTROY:
|
||||
if (nodeElement != null) {
|
||||
switch (action) {
|
||||
case CREATE:
|
||||
create(computeService);
|
||||
break;
|
||||
case GET:
|
||||
get(computeService);
|
||||
break;
|
||||
case DESTROY:
|
||||
destroy(computeService);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
this.log("missing node element for action: " + action, Project.MSG_ERR);
|
||||
}
|
||||
break;
|
||||
case LIST:
|
||||
list(computeService);
|
||||
break;
|
||||
case LIST_DETAILS:
|
||||
listDetails(computeService);
|
||||
break;
|
||||
default:
|
||||
this.log("bad action: " + action, Project.MSG_ERR);
|
||||
}
|
||||
CreateNodeResponse createdNode = computeService.runNode(nodeElement.getName(), template);
|
||||
}
|
||||
|
||||
private void listDetails(ComputeService computeService) {
|
||||
log("list details");
|
||||
for (ComputeMetadata node : computeService.listNodes()) {// TODO
|
||||
// parallel
|
||||
logDetails(computeService, node);
|
||||
}
|
||||
}
|
||||
|
||||
private void list(ComputeService computeService) {
|
||||
log("list");
|
||||
for (ComputeMetadata node : computeService.listNodes()) {
|
||||
log(String.format(" location=%s, id=%s, name=%s", node.getLocation(), node.getId(), node
|
||||
.getName()));
|
||||
}
|
||||
}
|
||||
|
||||
private void create(ComputeService computeService) {
|
||||
String name = nodeElement.getName();
|
||||
|
||||
log(String.format("create name: %s, size: %s, os: %s", name, nodeElement.getSize(),
|
||||
nodeElement.getOs()));
|
||||
|
||||
Template template = createTemplateFromElement(nodeElement, computeService);
|
||||
|
||||
RunNodeOptions options = getNodeOptionsFromElement(nodeElement);
|
||||
|
||||
CreateNodeResponse createdNode = computeService.runNode(name, template, options);
|
||||
|
||||
logNodeDetails(createdNode);
|
||||
|
||||
addNodeDetailsAsProjectProperties(createdNode);
|
||||
}
|
||||
|
||||
private void logNodeDetails(CreateNodeResponse createdNode) {
|
||||
log(String.format(" id=%s, name=%s, connection=%s://%s:%s@%s:%d", createdNode.getId(),
|
||||
createdNode.getName(), createdNode.getLoginType().toString().toLowerCase(),
|
||||
createdNode.getCredentials().account, createdNode.getCredentials().key, createdNode
|
||||
.getPublicAddresses().first().getHostAddress(), createdNode.getLoginPort()));
|
||||
}
|
||||
|
||||
private void addNodeDetailsAsProjectProperties(CreateNodeResponse createdNode) {
|
||||
if (nodeElement.getIdproperty() != null)
|
||||
getProject().setProperty(nodeElement.getIdproperty(), createdNode.getId());
|
||||
if (nodeElement.getHostproperty() != null)
|
||||
getProject().setProperty(nodeElement.getHostproperty(),
|
||||
createdNode.getPublicAddresses().first().getHostAddress());
|
||||
if (nodeElement.getKeyfile() != null
|
||||
&& createdNode.getCredentials().key.startsWith("-----BEGIN RSA PRIVATE KEY-----"))
|
||||
if (nodeElement.getKeyfile() != null && isKeyAuth(createdNode))
|
||||
try {
|
||||
Files.write(createdNode.getCredentials().key, new File(nodeElement.getKeyfile()),
|
||||
Charset.defaultCharset());
|
||||
} catch (IOException e) {
|
||||
throw new BuildException(e);
|
||||
}
|
||||
if (nodeElement.getPasswordproperty() != null
|
||||
&& !createdNode.getCredentials().key.startsWith("-----BEGIN RSA PRIVATE KEY-----"))
|
||||
if (nodeElement.getPasswordproperty() != null && !isKeyAuth(createdNode))
|
||||
getProject().setProperty(nodeElement.getPasswordproperty(),
|
||||
createdNode.getCredentials().key);
|
||||
if (nodeElement.getUsernameproperty() != null)
|
||||
|
@ -230,8 +192,8 @@ public class ComputeTask extends Task {
|
|||
|
||||
private void destroy(ComputeService computeService) {
|
||||
log(String.format("destroy name: %s", nodeElement.getName()));
|
||||
Iterable<? extends ComputeMetadata> nodesThatMatch = ComputeUtils.filterByName(computeService
|
||||
.listNodes(), nodeElement.getName());
|
||||
Iterable<? extends ComputeMetadata> nodesThatMatch = filterByName(computeService.listNodes(),
|
||||
nodeElement.getName());
|
||||
for (ComputeMetadata node : nodesThatMatch) {
|
||||
log(String.format(" destroying id=%s, name=%s", node.getId(), node.getName()));
|
||||
computeService.destroyNode(node);
|
||||
|
@ -240,8 +202,8 @@ public class ComputeTask extends Task {
|
|||
|
||||
private void get(ComputeService computeService) {
|
||||
log(String.format("get name: %s", nodeElement.getName()));
|
||||
Iterable<? extends ComputeMetadata> nodesThatMatch = ComputeUtils.filterByName(computeService
|
||||
.listNodes(), nodeElement.getName());
|
||||
Iterable<? extends ComputeMetadata> nodesThatMatch = filterByName(computeService.listNodes(),
|
||||
nodeElement.getName());
|
||||
for (ComputeMetadata node : nodesThatMatch) {
|
||||
logDetails(computeService, node);
|
||||
}
|
||||
|
@ -257,12 +219,18 @@ public class ComputeTask extends Task {
|
|||
.getPrivateAddresses()), metadata.getExtra()));
|
||||
}
|
||||
|
||||
public static String ipOrEmptyString(SortedSet<InetAddress> set) {
|
||||
if (set.size() > 0) {
|
||||
return set.last().getHostAddress();
|
||||
} else {
|
||||
return "";
|
||||
/**
|
||||
* @return the configured {@link NodeElement} element
|
||||
*/
|
||||
public final NodeElement createNode() {
|
||||
if (getNode() == null) {
|
||||
this.nodeElement = new NodeElement();
|
||||
}
|
||||
return this.nodeElement;
|
||||
}
|
||||
|
||||
public NodeElement getNode() {
|
||||
return this.nodeElement;
|
||||
}
|
||||
|
||||
public String getAction() {
|
||||
|
|
|
@ -0,0 +1,143 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF 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.tools.ant.taskdefs.compute;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.SortedSet;
|
||||
|
||||
import org.apache.tools.ant.BuildException;
|
||||
import org.apache.tools.ant.Project;
|
||||
import org.jclouds.compute.ComputeService;
|
||||
import org.jclouds.compute.ComputeServiceContext;
|
||||
import org.jclouds.compute.ComputeServiceContextFactory;
|
||||
import org.jclouds.compute.domain.OperatingSystem;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.compute.options.RunNodeOptions;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.tools.ant.logging.config.AntLoggingModule;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.MapMaker;
|
||||
import com.google.common.io.Files;
|
||||
import com.google.inject.Module;
|
||||
import com.google.inject.Provider;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class ComputeTaskUtils {
|
||||
|
||||
/**
|
||||
*
|
||||
* Creates a Map that associates a uri with a live connection to the compute provider. This is
|
||||
* done on-demand.
|
||||
*
|
||||
* @param projectProvider
|
||||
* allows access to the ant project to retrieve default properties needed for compute
|
||||
* providers.
|
||||
*/
|
||||
static Map<URI, ComputeServiceContext> buildComputeMap(final Provider<Project> projectProvider) {
|
||||
return new MapMaker().makeComputingMap(new Function<URI, ComputeServiceContext>() {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public ComputeServiceContext apply(URI from) {
|
||||
try {
|
||||
Properties props = new Properties();
|
||||
props.putAll(projectProvider.get().getProperties());
|
||||
return new ComputeServiceContextFactory().createContext(from, ImmutableSet
|
||||
.of((Module) new AntLoggingModule(projectProvider.get(),
|
||||
ComputeServiceConstants.COMPUTE_LOGGER)), props);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
static Template createTemplateFromElement(NodeElement nodeElement, ComputeService computeService) {
|
||||
Template template = computeService.createTemplateInLocation(nodeElement.getLocation());
|
||||
template.os(OperatingSystem.valueOf(nodeElement.getOs()));
|
||||
addSizeFromElementToTemplate(nodeElement, template);
|
||||
return template;
|
||||
}
|
||||
|
||||
static void addSizeFromElementToTemplate(NodeElement nodeElement, Template template) {
|
||||
if (nodeElement.getSize().equalsIgnoreCase("smallest")) {
|
||||
template.smallest();
|
||||
} else if (nodeElement.getSize().equalsIgnoreCase("fastest")) {
|
||||
template.fastest();
|
||||
} else if (nodeElement.getSize().equalsIgnoreCase("biggest")) {
|
||||
template.biggest();
|
||||
} else {
|
||||
throw new BuildException("size: " + nodeElement.getSize()
|
||||
+ " not supported. valid sizes are smallest, fastest, biggest");
|
||||
}
|
||||
}
|
||||
|
||||
static RunNodeOptions getNodeOptionsFromElement(NodeElement nodeElement) {
|
||||
RunNodeOptions options = new RunNodeOptions()
|
||||
.openPorts(getPortsToOpenFromElement(nodeElement));
|
||||
addRunScriptToOptionsIfPresentInNodeElement(nodeElement, options);
|
||||
return options;
|
||||
}
|
||||
|
||||
static void addRunScriptToOptionsIfPresentInNodeElement(NodeElement nodeElement,
|
||||
RunNodeOptions options) {
|
||||
if (nodeElement.getRunscript() != null)
|
||||
try {
|
||||
options.runScript(Files.toByteArray(nodeElement.getRunscript()));
|
||||
} catch (IOException e) {
|
||||
throw new BuildException(e);
|
||||
}
|
||||
}
|
||||
|
||||
static String ipOrEmptyString(SortedSet<InetAddress> set) {
|
||||
if (set.size() > 0) {
|
||||
return set.last().getHostAddress();
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
static int[] getPortsToOpenFromElement(NodeElement nodeElement) {
|
||||
Iterable<String> portStrings = Splitter.on(',').split(nodeElement.getOpenports());
|
||||
int[] ports = new int[Iterables.size(portStrings)];
|
||||
int i = 0;
|
||||
for (String port : portStrings) {
|
||||
ports[i++] = Integer.parseInt(port);
|
||||
}
|
||||
return ports;
|
||||
}
|
||||
}
|
|
@ -18,6 +18,8 @@
|
|||
*/
|
||||
package org.jclouds.tools.ant.taskdefs.compute;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
* @author Ivan Meredith
|
||||
|
@ -26,12 +28,14 @@ public class NodeElement {
|
|||
private String name;
|
||||
private String size;
|
||||
private String os;
|
||||
private String openports = "22";
|
||||
private String passwordproperty;
|
||||
private String keyfi1le;
|
||||
private String keyfile;
|
||||
private String hostproperty;
|
||||
private String idproperty;
|
||||
private String usernameproperty;
|
||||
private String location = "default";
|
||||
private File runscript;
|
||||
|
||||
public String getLocation() {
|
||||
return location;
|
||||
|
@ -40,7 +44,7 @@ public class NodeElement {
|
|||
public void setLocation(String location) {
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
|
||||
String getName() {
|
||||
return name;
|
||||
}
|
||||
|
@ -101,11 +105,11 @@ public class NodeElement {
|
|||
* The name of a file under which to store the DSA key of the user (if supported)
|
||||
*/
|
||||
public void setKeyfile(String keyfile) {
|
||||
this.keyfi1le = keyfile;
|
||||
this.keyfile = keyfile;
|
||||
}
|
||||
|
||||
String getKeyfile() {
|
||||
return keyfi1le;
|
||||
return keyfile;
|
||||
}
|
||||
|
||||
public void setSize(String size) {
|
||||
|
@ -124,4 +128,20 @@ public class NodeElement {
|
|||
return os;
|
||||
}
|
||||
|
||||
public void setRunscript(File runscript) {
|
||||
this.runscript = runscript;
|
||||
}
|
||||
|
||||
public File getRunscript() {
|
||||
return runscript;
|
||||
}
|
||||
|
||||
public void setOpenports(String openports) {
|
||||
this.openports = openports;
|
||||
}
|
||||
|
||||
public String getOpenports() {
|
||||
return openports;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,171 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed 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.vcloud;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.jclouds.compute.domain.OperatingSystem;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.vcloud.domain.Task;
|
||||
import org.jclouds.vcloud.domain.VApp;
|
||||
import org.jclouds.vcloud.domain.VAppStatus;
|
||||
import org.jclouds.vcloud.options.InstantiateVAppTemplateOptions;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class VCloudComputeClient {
|
||||
@Resource
|
||||
protected Logger logger = Logger.NULL;
|
||||
|
||||
private final Predicate<String> taskTester;
|
||||
private final VCloudClient tmClient;
|
||||
|
||||
@Inject
|
||||
public VCloudComputeClient(VCloudClient tmClient, Predicate<String> successTester) {
|
||||
this.tmClient = tmClient;
|
||||
this.taskTester = successTester;
|
||||
}
|
||||
|
||||
private Map<OperatingSystem, String> imageCatalogIdMap = ImmutableMap
|
||||
.<OperatingSystem, String> builder().put(OperatingSystem.CENTOS, "1").put(
|
||||
OperatingSystem.RHEL, "8").put(OperatingSystem.UBUNTU, "11").build();
|
||||
|
||||
public Map<String, String> start(String name, OperatingSystem image, int minCores, int minMegs,
|
||||
long diskSize, Map<String, String> properties) {
|
||||
checkArgument(imageCatalogIdMap.containsKey(image), "image not configured: " + image);
|
||||
String templateId = imageCatalogIdMap.get(image);
|
||||
String vDCId = tmClient.getDefaultVDC().getId();
|
||||
logger
|
||||
.debug(
|
||||
">> instantiating vApp vDC(%s) name(%s) template(%s) minCores(%d) minMegs(%d) diskSize(%d) properties(%s) ",
|
||||
vDCId, name, templateId, minCores, minMegs, diskSize, properties);
|
||||
VApp vAppResponse = tmClient.instantiateVAppTemplateInVDC(vDCId, name, templateId,
|
||||
InstantiateVAppTemplateOptions.Builder.processorCount(minCores).memory(minMegs)
|
||||
.disk(diskSize).productProperties(properties));
|
||||
logger.debug("<< instantiated VApp(%s)", vAppResponse.getId());
|
||||
|
||||
logger.debug(">> deploying vApp(%s)", vAppResponse.getId());
|
||||
VApp vApp = blockUntilVAppStatusOrThrowException(vAppResponse, tmClient
|
||||
.deployVApp(vAppResponse.getId()), "deploy", VAppStatus.ON);// TODO, I'm not sure
|
||||
// this should be on
|
||||
// already
|
||||
// logger.debug("<< deployed vApp(%s)", vApp.getId());
|
||||
//
|
||||
// logger.debug(">> powering vApp(%s)", vApp.getId());
|
||||
// vApp = blockUntilVAppStatusOrThrowException(vApp, tmClient.powerOnVApp(vApp.getId()),
|
||||
// "powerOn", VAppStatus.ON);
|
||||
logger.debug("<< on vApp(%s)", vApp.getId());
|
||||
|
||||
return ImmutableMap.<String, String> of("id", vApp.getId(), "username", null, "password",
|
||||
null);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @throws ElementNotFoundException
|
||||
* if no address is configured
|
||||
*/
|
||||
public InetAddress getAnyPrivateAddress(String id) {
|
||||
VApp vApp = tmClient.getVApp(id);
|
||||
return Iterables.getLast(vApp.getNetworkToAddresses().values());
|
||||
}
|
||||
|
||||
public void reboot(String id) {
|
||||
VApp vApp = tmClient.getVApp(id);
|
||||
logger.debug(">> rebooting vApp(%s)", vApp.getId());
|
||||
blockUntilVAppStatusOrThrowException(vApp, tmClient.resetVApp(vApp.getId()), "reset",
|
||||
VAppStatus.ON);
|
||||
logger.debug("<< on vApp(%s)", vApp.getId());
|
||||
}
|
||||
|
||||
public void stop(String id) {
|
||||
VApp vApp = tmClient.getVApp(id);
|
||||
if (vApp.getStatus() != VAppStatus.OFF) {
|
||||
logger.debug(">> powering off vApp(%s), current status: %s", vApp.getId(), vApp
|
||||
.getStatus());
|
||||
blockUntilVAppStatusOrThrowException(vApp, tmClient.powerOffVApp(vApp.getId()),
|
||||
"powerOff", VAppStatus.OFF);
|
||||
logger.debug("<< off vApp(%s)", vApp.getId());
|
||||
}
|
||||
logger.debug(">> deleting vApp(%s)", vApp.getId());
|
||||
tmClient.deleteVApp(id);
|
||||
logger.debug("<< deleted vApp(%s)", vApp.getId());
|
||||
}
|
||||
|
||||
private VApp blockUntilVAppStatusOrThrowException(VApp vApp, Task deployTask, String taskType,
|
||||
VAppStatus expectedStatus) {
|
||||
if (!taskTester.apply(deployTask.getId())) {
|
||||
throw new TaskException(taskType, vApp, deployTask);
|
||||
}
|
||||
|
||||
vApp = tmClient.getVApp(vApp.getId());
|
||||
if (vApp.getStatus() != expectedStatus) {
|
||||
throw new VAppException(String.format("vApp %s status %s should be %s after %s", vApp
|
||||
.getId(), vApp.getStatus(), expectedStatus, taskType), vApp);
|
||||
}
|
||||
return vApp;
|
||||
}
|
||||
|
||||
public static class TaskException extends VAppException {
|
||||
|
||||
private final Task task;
|
||||
/** The serialVersionUID */
|
||||
private static final long serialVersionUID = 251801929573211256L;
|
||||
|
||||
public TaskException(String type, VApp vApp, Task task) {
|
||||
super(String.format("failed to %s vApp %s status %s;task %s status %s", type,
|
||||
vApp.getId(), vApp.getStatus(), task.getLocation(), task.getStatus()), vApp);
|
||||
this.task = task;
|
||||
}
|
||||
|
||||
public Task getTask() {
|
||||
return task;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class VAppException extends RuntimeException {
|
||||
|
||||
private final VApp vApp;
|
||||
/** The serialVersionUID */
|
||||
private static final long serialVersionUID = 251801929573211256L;
|
||||
|
||||
public VAppException(String message, VApp vApp) {
|
||||
super(message);
|
||||
this.vApp = vApp;
|
||||
}
|
||||
|
||||
public VApp getvApp() {
|
||||
return vApp;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,158 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed 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.vcloud;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.jclouds.compute.domain.OperatingSystem;
|
||||
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
|
||||
import org.jclouds.ssh.jsch.config.JschSshClientModule;
|
||||
import org.jclouds.vcloud.domain.ResourceType;
|
||||
import org.jclouds.vcloud.domain.VApp;
|
||||
import org.jclouds.vcloud.domain.VAppStatus;
|
||||
import org.testng.annotations.AfterTest;
|
||||
import org.testng.annotations.BeforeGroups;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.base.CaseFormat;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Key;
|
||||
import com.google.inject.TypeLiteral;
|
||||
import com.google.inject.internal.ImmutableMap;
|
||||
|
||||
/**
|
||||
* Tests behavior of {@code VCloudComputeClientLiveTest}
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "live", sequential = true, testName = "vcloud.VCloudClientLiveTest")
|
||||
public class VCloudComputeClientLiveTest {
|
||||
VCloudComputeClient client;
|
||||
VCloudClient tmClient;
|
||||
|
||||
private String id;
|
||||
private InetAddress privateAddress;
|
||||
|
||||
public static final String PREFIX = (System.getProperty("user.name") + "-vcloud").replaceAll(
|
||||
"\\.", "");
|
||||
|
||||
private static class Expectation {
|
||||
final long hardDisk;
|
||||
final String os;
|
||||
|
||||
public Expectation(long hardDisk, String os) {
|
||||
this.hardDisk = hardDisk;
|
||||
this.os = os;
|
||||
}
|
||||
}
|
||||
|
||||
private Map<OperatingSystem, Expectation> expectationMap = ImmutableMap
|
||||
.<OperatingSystem, Expectation> builder().put(OperatingSystem.CENTOS,
|
||||
new Expectation(4194304 / 2 * 10, "Red Hat Enterprise Linux 5 (64-bit)")).put(
|
||||
OperatingSystem.RHEL,
|
||||
new Expectation(4194304 / 2 * 10, "Red Hat Enterprise Linux 5 (64-bit)")).put(
|
||||
OperatingSystem.UBUNTU, new Expectation(4194304, "Ubuntu Linux (32-bit)"))
|
||||
.build();
|
||||
|
||||
private Predicate<InetAddress> addressTester;
|
||||
|
||||
@Test
|
||||
public void testPowerOn() throws InterruptedException, ExecutionException, TimeoutException,
|
||||
IOException {
|
||||
OperatingSystem toTest = OperatingSystem.CENTOS;
|
||||
|
||||
String serverName = getCompatibleServerName(toTest);
|
||||
int processorCount = 1;
|
||||
int memory = 512;
|
||||
long disk = 10 * 1025 * 1024;
|
||||
Map<String, String> properties = ImmutableMap.of("foo", "bar");
|
||||
|
||||
id = client.start(serverName, toTest, processorCount, memory, disk, properties).get("id");
|
||||
Expectation expectation = expectationMap.get(toTest);
|
||||
|
||||
VApp vApp = tmClient.getVApp(id);
|
||||
verifyConfigurationOfVApp(vApp, serverName, expectation.os, processorCount, memory,
|
||||
expectation.hardDisk);
|
||||
assertEquals(vApp.getStatus(), VAppStatus.ON);
|
||||
}
|
||||
|
||||
private String getCompatibleServerName(OperatingSystem toTest) {
|
||||
String serverName = CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, toTest.toString())
|
||||
.substring(0,
|
||||
toTest.toString().length() - 1 <= 15 ? toTest.toString().length() - 1 : 14);
|
||||
return serverName;
|
||||
}
|
||||
|
||||
@Test(dependsOnMethods = "testPowerOn")
|
||||
public void testGetAnyPrivateAddress() {
|
||||
privateAddress = client.getAnyPrivateAddress(id);
|
||||
assert !addressTester.apply(privateAddress);
|
||||
}
|
||||
|
||||
private void verifyConfigurationOfVApp(VApp vApp, String serverName, String expectedOs,
|
||||
int processorCount, int memory, long hardDisk) {
|
||||
// assertEquals(vApp.getName(), serverName);
|
||||
// assertEquals(vApp.getOperatingSystemDescription(), expectedOs);
|
||||
assertEquals(
|
||||
Iterables.getOnlyElement(
|
||||
vApp.getResourceAllocationByType().get(ResourceType.PROCESSOR))
|
||||
.getVirtualQuantity(), processorCount);
|
||||
assertEquals(Iterables.getOnlyElement(
|
||||
vApp.getResourceAllocationByType().get(ResourceType.SCSI_CONTROLLER))
|
||||
.getVirtualQuantity(), 1);
|
||||
assertEquals(Iterables.getOnlyElement(
|
||||
vApp.getResourceAllocationByType().get(ResourceType.MEMORY)).getVirtualQuantity(),
|
||||
memory);
|
||||
assertEquals(Iterables.getOnlyElement(
|
||||
vApp.getResourceAllocationByType().get(ResourceType.DISK_DRIVE))
|
||||
.getVirtualQuantity(), hardDisk);
|
||||
}
|
||||
|
||||
@AfterTest
|
||||
void cleanup() throws InterruptedException, ExecutionException, TimeoutException {
|
||||
if (id != null)
|
||||
client.stop(id);
|
||||
}
|
||||
|
||||
@BeforeGroups(groups = { "live" })
|
||||
public void setupClient() {
|
||||
String endpoint = checkNotNull(System.getProperty("jclouds.test.endpoint"),
|
||||
"jclouds.test.endpoint");
|
||||
String account = checkNotNull(System.getProperty("jclouds.test.user"), "jclouds.test.user");
|
||||
String key = checkNotNull(System.getProperty("jclouds.test.key"), "jclouds.test.key");
|
||||
Injector injector = new VCloudContextBuilder(new VCloudPropertiesBuilder(
|
||||
URI.create(endpoint), account, key).build()).withModules(new Log4JLoggingModule(),
|
||||
new JschSshClientModule()).buildInjector();
|
||||
client = injector.getInstance(VCloudComputeClient.class);
|
||||
tmClient = injector.getInstance(VCloudClient.class);
|
||||
addressTester = injector.getInstance(Key.get(new TypeLiteral<Predicate<InetAddress>>() {
|
||||
}));
|
||||
}
|
||||
|
||||
}
|
|
@ -1,164 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed 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.vcloud.hostingdotcom.compute;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.vcloud.domain.Task;
|
||||
import org.jclouds.vcloud.domain.VApp;
|
||||
import org.jclouds.vcloud.domain.VAppStatus;
|
||||
import org.jclouds.vcloud.hostingdotcom.HostingDotComVCloudClient;
|
||||
import org.jclouds.vcloud.hostingdotcom.domain.HostingDotComVApp;
|
||||
import org.jclouds.vcloud.options.InstantiateVAppTemplateOptions;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class HostingDotComVCloudComputeClient {
|
||||
@Resource
|
||||
protected Logger logger = Logger.NULL;
|
||||
|
||||
private final Predicate<String> taskTester;
|
||||
private final HostingDotComVCloudClient tmClient;
|
||||
|
||||
@Inject
|
||||
public HostingDotComVCloudComputeClient(HostingDotComVCloudClient tmClient,
|
||||
Predicate<String> successTester) {
|
||||
this.tmClient = tmClient;
|
||||
this.taskTester = successTester;
|
||||
}
|
||||
|
||||
public Map<String, String> start(String vDCId, String name, String templateId, int minCores,
|
||||
int minMegs, long diskSize, Map<String, String> properties) {
|
||||
logger
|
||||
.debug(
|
||||
">> instantiating vApp vDC(%s) name(%s) template(%s) minCores(%d) minMegs(%d) diskSize(%d) properties(%s) ",
|
||||
vDCId, name, templateId, minCores, minMegs, diskSize, properties);
|
||||
HostingDotComVApp vAppResponse = tmClient.instantiateVAppTemplateInVDC(vDCId, name,
|
||||
templateId, InstantiateVAppTemplateOptions.Builder.processorCount(minCores).memory(
|
||||
minMegs).disk(diskSize).productProperties(properties));
|
||||
logger.debug("<< instantiated VApp(%s)", vAppResponse.getId());
|
||||
|
||||
logger.debug(">> deploying vApp(%s)", vAppResponse.getId());
|
||||
VApp vApp = blockUntilVAppStatusOrThrowException(vAppResponse, tmClient
|
||||
.deployVApp(vAppResponse.getId()), "deploy", VAppStatus.ON);// TODO, I'm not sure
|
||||
// this should be on
|
||||
// already
|
||||
// logger.debug("<< deployed vApp(%s)", vApp.getId());
|
||||
//
|
||||
// logger.debug(">> powering vApp(%s)", vApp.getId());
|
||||
// vApp = blockUntilVAppStatusOrThrowException(vApp, tmClient.powerOnVApp(vApp.getId()),
|
||||
// "powerOn", VAppStatus.ON);
|
||||
logger.debug("<< on vApp(%s)", vApp.getId());
|
||||
|
||||
return ImmutableMap.<String, String> of("id", vApp.getId(), "username", vAppResponse
|
||||
.getUsername(), "password", vAppResponse.getPassword());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @throws ElementNotFoundException
|
||||
* if no address is configured
|
||||
*/
|
||||
public InetAddress getAnyPrivateAddress(String id) {
|
||||
VApp vApp = tmClient.getVApp(id);
|
||||
return Iterables.getLast(vApp.getNetworkToAddresses().values());
|
||||
}
|
||||
|
||||
public void reboot(String id) {
|
||||
VApp vApp = tmClient.getVApp(id);
|
||||
logger.debug(">> rebooting vApp(%s)", vApp.getId());
|
||||
blockUntilVAppStatusOrThrowException(vApp, tmClient.resetVApp(vApp.getId()), "reset",
|
||||
VAppStatus.ON);
|
||||
logger.debug("<< on vApp(%s)", vApp.getId());
|
||||
}
|
||||
|
||||
public void stop(String id) {
|
||||
VApp vApp = tmClient.getVApp(id);
|
||||
if (vApp.getStatus() != VAppStatus.OFF) {
|
||||
logger.debug(">> powering off vApp(%s), current status: %s", vApp.getId(), vApp
|
||||
.getStatus());
|
||||
blockUntilVAppStatusOrThrowException(vApp, tmClient.powerOffVApp(vApp.getId()),
|
||||
"powerOff", VAppStatus.OFF);
|
||||
logger.debug("<< off vApp(%s)", vApp.getId());
|
||||
}
|
||||
logger.debug(">> deleting vApp(%s)", vApp.getId());
|
||||
tmClient.deleteVApp(id);
|
||||
logger.debug("<< deleted vApp(%s)", vApp.getId());
|
||||
}
|
||||
|
||||
private VApp blockUntilVAppStatusOrThrowException(VApp vApp, Task deployTask, String taskType,
|
||||
VAppStatus expectedStatus) {
|
||||
if (!taskTester.apply(deployTask.getId())) {
|
||||
throw new TaskException(taskType, vApp, deployTask);
|
||||
}
|
||||
|
||||
vApp = tmClient.getVApp(vApp.getId());
|
||||
if (vApp.getStatus() != expectedStatus) {
|
||||
throw new VAppException(String.format("vApp %s status %s should be %s after %s", vApp
|
||||
.getId(), vApp.getStatus(), expectedStatus, taskType), vApp);
|
||||
}
|
||||
return vApp;
|
||||
}
|
||||
|
||||
public static class TaskException extends VAppException {
|
||||
|
||||
private final Task task;
|
||||
/** The serialVersionUID */
|
||||
private static final long serialVersionUID = 251801929573211256L;
|
||||
|
||||
public TaskException(String type, VApp vApp, Task task) {
|
||||
super(String.format("failed to %s vApp %s status %s;task %s status %s", type,
|
||||
vApp.getId(), vApp.getStatus(), task.getLocation(), task.getStatus()), vApp);
|
||||
this.task = task;
|
||||
}
|
||||
|
||||
public Task getTask() {
|
||||
return task;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class VAppException extends RuntimeException {
|
||||
|
||||
private final VApp vApp;
|
||||
/** The serialVersionUID */
|
||||
private static final long serialVersionUID = 251801929573211256L;
|
||||
|
||||
public VAppException(String message, VApp vApp) {
|
||||
super(message);
|
||||
this.vApp = vApp;
|
||||
}
|
||||
|
||||
public VApp getvApp() {
|
||||
return vApp;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,155 +1,48 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed 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.vcloud.hostingdotcom.compute;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.SortedSet;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Provider;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.compute.ComputeService;
|
||||
import org.jclouds.compute.domain.ComputeMetadata;
|
||||
import org.jclouds.compute.domain.ComputeType;
|
||||
import org.jclouds.compute.domain.CreateNodeResponse;
|
||||
import org.jclouds.compute.domain.Image;
|
||||
import org.jclouds.compute.domain.LoginType;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.NodeState;
|
||||
import org.jclouds.compute.domain.Size;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.compute.domain.internal.CreateNodeResponseImpl;
|
||||
import org.jclouds.compute.domain.internal.NodeMetadataImpl;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.vcloud.VCloudMediaType;
|
||||
import org.jclouds.vcloud.domain.NamedResource;
|
||||
import org.jclouds.vcloud.VCloudClient;
|
||||
import org.jclouds.vcloud.compute.VCloudComputeService;
|
||||
import org.jclouds.vcloud.compute.VCloudTemplate;
|
||||
import org.jclouds.vcloud.domain.VApp;
|
||||
import org.jclouds.vcloud.domain.VAppStatus;
|
||||
import org.jclouds.vcloud.hostingdotcom.HostingDotComVCloudClient;
|
||||
import org.jclouds.vcloud.hostingdotcom.domain.HostingDotComVApp;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.inject.internal.ImmutableSet;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class HostingDotComVCloudComputeService implements ComputeService {
|
||||
@Resource
|
||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||
protected Logger logger = Logger.NULL;
|
||||
private final HostingDotComVCloudComputeClient computeClient;
|
||||
private final HostingDotComVCloudClient client;
|
||||
private final Set<? extends Image> images;
|
||||
private final Set<? extends Size> sizes;
|
||||
private final Provider<Set<HostingDotComVCloudTemplate>> templates;
|
||||
|
||||
private static final Map<VAppStatus, NodeState> vAppStatusToNodeState = ImmutableMap
|
||||
.<VAppStatus, NodeState> builder().put(VAppStatus.OFF, NodeState.TERMINATED).put(
|
||||
VAppStatus.ON, NodeState.RUNNING).put(VAppStatus.RESOLVED, NodeState.PENDING)
|
||||
.put(VAppStatus.SUSPENDED, NodeState.SUSPENDED).put(VAppStatus.UNRESOLVED,
|
||||
NodeState.PENDING).build();
|
||||
public class HostingDotComVCloudComputeService extends VCloudComputeService {
|
||||
|
||||
@Inject
|
||||
public HostingDotComVCloudComputeService(HostingDotComVCloudClient client,
|
||||
HostingDotComVCloudComputeClient computeClient, Set<? extends Image> images,
|
||||
Set<? extends Size> sizes, Provider<Set<HostingDotComVCloudTemplate>> templates) {
|
||||
this.client = client;
|
||||
this.computeClient = computeClient;
|
||||
this.images = images;
|
||||
this.sizes = sizes;
|
||||
this.templates = templates;
|
||||
public HostingDotComVCloudComputeService(VCloudClient client,
|
||||
Provider<Set<? extends Image>> images, Provider<SortedSet<? extends Size>> sizes,
|
||||
Provider<Set<? extends VCloudTemplate>> templates, Predicate<String> successTester,
|
||||
Predicate<InetSocketAddress> socketTester) {
|
||||
super(client, images, sizes, templates, successTester, socketTester);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CreateNodeResponse runNode(String name, Template template) {
|
||||
checkNotNull(template.getImage().getLocation(), "location");
|
||||
Map<String, String> metaMap = computeClient.start(template.getImage().getLocation(), name,
|
||||
template.getImage().getId(), template.getSize().getCores(), template.getSize()
|
||||
.getRam(), template.getSize().getDisk(), ImmutableMap.<String, String> of());
|
||||
VApp vApp = client.getVApp(metaMap.get("id"));
|
||||
return new CreateNodeResponseImpl(vApp.getId(), vApp.getName(), template.getImage()
|
||||
.getLocation(), vApp.getLocation(), ImmutableMap.<String, String> of(),
|
||||
vAppStatusToNodeState.get(vApp.getStatus()), vApp.getNetworkToAddresses().values(),
|
||||
ImmutableSet.<InetAddress> of(), 22, LoginType.SSH, new Credentials(metaMap
|
||||
.get("username"), metaMap.get("password")), ImmutableMap
|
||||
.<String, String> of());
|
||||
}
|
||||
|
||||
@Override
|
||||
public NodeMetadata getNodeMetadata(ComputeMetadata node) {
|
||||
checkArgument(node.getType() == ComputeType.NODE, "this is only valid for nodes, not "
|
||||
+ node.getType());
|
||||
return getNodeMetadataByIdInVDC(checkNotNull(node.getLocation(), "location"), checkNotNull(
|
||||
node.getId(), "node.id"));
|
||||
}
|
||||
|
||||
private NodeMetadata getNodeMetadataByIdInVDC(String vDCId, String id) {
|
||||
VApp vApp = client.getVApp(id);
|
||||
return new NodeMetadataImpl(vApp.getId(), vApp.getName(), vDCId, vApp.getLocation(),
|
||||
ImmutableMap.<String, String> of(), vAppStatusToNodeState.get(vApp.getStatus()),
|
||||
vApp.getNetworkToAddresses().values(), ImmutableSet.<InetAddress> of(), 22,
|
||||
LoginType.SSH, ImmutableMap.<String, String> of());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<ComputeMetadata> listNodes() {
|
||||
Set<ComputeMetadata> nodes = Sets.newHashSet();
|
||||
for (NamedResource vdc : client.getDefaultOrganization().getVDCs().values()) {
|
||||
for (NamedResource resource : client.getVDC(vdc.getId()).getResourceEntities().values()) {
|
||||
if (resource.getType().equals(VCloudMediaType.VAPP_XML)) {
|
||||
nodes.add(getNodeMetadataByIdInVDC(vdc.getId(), resource.getId()));
|
||||
}
|
||||
}
|
||||
}
|
||||
return nodes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroyNode(ComputeMetadata node) {
|
||||
checkArgument(node.getType() == ComputeType.NODE, "this is only valid for nodes, not "
|
||||
+ node.getType());
|
||||
computeClient.stop(checkNotNull(node.getId(), "node.id"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Template createTemplateInLocation(String location) {
|
||||
return new HostingDotComVCloudTemplate(client, images, sizes, location);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<? extends Size> listSizes() {
|
||||
return sizes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<? extends Template> listTemplates() {
|
||||
return templates.get();
|
||||
protected Map<String, String> parseResponse(VApp vAppResponse) {
|
||||
checkState(vAppResponse instanceof HostingDotComVApp,
|
||||
"bad configuration, vApp should be an instance of "
|
||||
+ HostingDotComVApp.class.getName());
|
||||
HostingDotComVApp hVApp = HostingDotComVApp.class.cast(vAppResponse);
|
||||
return ImmutableMap.<String, String> of("id", vAppResponse.getId(), "username", hVApp
|
||||
.getUsername(), "password", hVApp.getPassword());
|
||||
}
|
||||
}
|
|
@ -20,22 +20,15 @@ package org.jclouds.vcloud.hostingdotcom.compute;
|
|||
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
import org.jclouds.compute.ComputeServiceContext;
|
||||
import org.jclouds.compute.ComputeServiceContextBuilder;
|
||||
import org.jclouds.compute.internal.ComputeServiceContextImpl;
|
||||
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
|
||||
import org.jclouds.logging.jdk.config.JDKLoggingModule;
|
||||
import org.jclouds.vcloud.hostingdotcom.HostingDotComVCloudAsyncClient;
|
||||
import org.jclouds.vcloud.hostingdotcom.HostingDotComVCloudClient;
|
||||
import org.jclouds.vcloud.compute.VCloudComputeServiceContextBuilder;
|
||||
import org.jclouds.vcloud.hostingdotcom.compute.config.HostingDotComVCloudComputeServiceContextModule;
|
||||
import org.jclouds.vcloud.hostingdotcom.config.HostingDotComVCloudRestClientModule;
|
||||
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Key;
|
||||
import com.google.inject.Module;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
||||
/**
|
||||
* Creates {@link HostingDotComVCloudComputeServiceContext} or {@link Injector} instances based on
|
||||
|
@ -51,23 +44,10 @@ import com.google.inject.TypeLiteral;
|
|||
* @see HostingDotComVCloudComputeServiceContext
|
||||
*/
|
||||
public class HostingDotComVCloudComputeServiceContextBuilder extends
|
||||
ComputeServiceContextBuilder<HostingDotComVCloudAsyncClient, HostingDotComVCloudClient> {
|
||||
VCloudComputeServiceContextBuilder {
|
||||
|
||||
public HostingDotComVCloudComputeServiceContextBuilder(Properties props) {
|
||||
super(new TypeLiteral<HostingDotComVCloudAsyncClient>() {
|
||||
}, new TypeLiteral<HostingDotComVCloudClient>() {
|
||||
}, props);
|
||||
}
|
||||
|
||||
@Override
|
||||
public HostingDotComVCloudComputeServiceContextBuilder withExecutorService(
|
||||
ExecutorService service) {
|
||||
return (HostingDotComVCloudComputeServiceContextBuilder) super.withExecutorService(service);
|
||||
}
|
||||
|
||||
@Override
|
||||
public HostingDotComVCloudComputeServiceContextBuilder withModules(Module... modules) {
|
||||
return (HostingDotComVCloudComputeServiceContextBuilder) super.withModules(modules);
|
||||
super(props);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -80,14 +60,4 @@ public class HostingDotComVCloudComputeServiceContextBuilder extends
|
|||
modules.add(new HostingDotComVCloudRestClientModule());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ComputeServiceContext buildComputeServiceContext() {
|
||||
// need the generic type information
|
||||
return (ComputeServiceContext) this
|
||||
.buildInjector()
|
||||
.getInstance(
|
||||
Key
|
||||
.get(new TypeLiteral<ComputeServiceContextImpl<HostingDotComVCloudAsyncClient, HostingDotComVCloudClient>>() {
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,180 +0,0 @@
|
|||
package org.jclouds.vcloud.hostingdotcom.compute;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.jclouds.compute.domain.Image;
|
||||
import org.jclouds.compute.domain.OperatingSystem;
|
||||
import org.jclouds.compute.domain.Size;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.vcloud.hostingdotcom.HostingDotComVCloudClient;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class HostingDotComVCloudTemplate implements Template {
|
||||
private final HostingDotComVCloudClient client;
|
||||
private final Set<? extends Image> images;
|
||||
private final Set<? extends Size> sizes;
|
||||
private Size size;
|
||||
private String vDC;
|
||||
private OperatingSystem operatingSystem;
|
||||
private transient Image image;
|
||||
|
||||
public HostingDotComVCloudTemplate(HostingDotComVCloudClient client,
|
||||
Set<? extends Image> images, Set<? extends Size> sizes, String location,
|
||||
@Nullable Size size, OperatingSystem operatingSystem, @Nullable Image image) {
|
||||
this.client = client;
|
||||
this.images = images;
|
||||
this.sizes = sizes;
|
||||
this.vDC = location;
|
||||
this.image = image != null ? image : resolveTemplate(images, operatingSystem);
|
||||
this.size = size != null ? size : Iterables.get(sizes, 0);
|
||||
this.operatingSystem = operatingSystem;
|
||||
}
|
||||
|
||||
private Image resolveTemplate(Set<? extends Image> images, OperatingSystem operatingSystem) {
|
||||
for (Image image : images) {
|
||||
if (image.getOperatingSystem() == operatingSystem)
|
||||
return image;
|
||||
}
|
||||
throw new RuntimeException("no configured image matches os: " + operatingSystem);
|
||||
}
|
||||
|
||||
HostingDotComVCloudTemplate(HostingDotComVCloudClient client, Set<? extends Image> images,
|
||||
Set<? extends Size> sizes, String location) {
|
||||
this(client, images, sizes, location, null, OperatingSystem.CENTOS, null);// note the default
|
||||
// os
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Size getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Image getImage() {
|
||||
return image;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Template smallest() {
|
||||
this.size = Iterables.get(sizes, 0);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Template biggest() {
|
||||
this.size = Iterables.getLast(sizes);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Template fastest() {
|
||||
this.size = Iterables.getLast(sizes);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Template inLocation(String location) {
|
||||
if (location.equalsIgnoreCase("default"))
|
||||
location = client.getDefaultVDC().getId();
|
||||
this.vDC = location;// TODO match vdc on template as well arch
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Template os(OperatingSystem os) {
|
||||
this.operatingSystem = os;
|
||||
this.image = resolveTemplate(images, operatingSystem);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected Object clone() throws CloneNotSupportedException {
|
||||
return new HostingDotComVCloudTemplate(client, images, sizes, vDC, size, operatingSystem,
|
||||
image);
|
||||
}
|
||||
|
||||
public String getvDC() {
|
||||
return vDC;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((image == null) ? 0 : image.hashCode());
|
||||
result = prime * result + ((operatingSystem == null) ? 0 : operatingSystem.hashCode());
|
||||
result = prime * result + ((size == null) ? 0 : size.hashCode());
|
||||
result = prime * result + ((vDC == null) ? 0 : vDC.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
HostingDotComVCloudTemplate other = (HostingDotComVCloudTemplate) obj;
|
||||
if (image == null) {
|
||||
if (other.image != null)
|
||||
return false;
|
||||
} else if (!image.equals(other.image))
|
||||
return false;
|
||||
if (operatingSystem == null) {
|
||||
if (other.operatingSystem != null)
|
||||
return false;
|
||||
} else if (!operatingSystem.equals(other.operatingSystem))
|
||||
return false;
|
||||
if (size == null) {
|
||||
if (other.size != null)
|
||||
return false;
|
||||
} else if (!size.equals(other.size))
|
||||
return false;
|
||||
if (vDC == null) {
|
||||
if (other.vDC != null)
|
||||
return false;
|
||||
} else if (!vDC.equals(other.vDC))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "HostingDotComVCloudTemplate [image=" + image + ", operatingSystem=" + operatingSystem
|
||||
+ ", size=" + size + ", vDC=" + vDC + "]";
|
||||
}
|
||||
|
||||
}
|
|
@ -18,39 +18,11 @@
|
|||
*/
|
||||
package org.jclouds.vcloud.hostingdotcom.compute.config;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.compute.ComputeService;
|
||||
import org.jclouds.compute.ComputeServiceContext;
|
||||
import org.jclouds.compute.domain.Architecture;
|
||||
import org.jclouds.compute.domain.Image;
|
||||
import org.jclouds.compute.domain.OperatingSystem;
|
||||
import org.jclouds.compute.domain.Size;
|
||||
import org.jclouds.compute.domain.internal.ImageImpl;
|
||||
import org.jclouds.compute.domain.internal.SizeImpl;
|
||||
import org.jclouds.compute.internal.ComputeServiceContextImpl;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.rest.RestContext;
|
||||
import org.jclouds.vcloud.VCloudClient;
|
||||
import org.jclouds.vcloud.VCloudMediaType;
|
||||
import org.jclouds.vcloud.domain.Catalog;
|
||||
import org.jclouds.vcloud.domain.CatalogItem;
|
||||
import org.jclouds.vcloud.domain.NamedResource;
|
||||
import org.jclouds.vcloud.domain.VAppTemplate;
|
||||
import org.jclouds.vcloud.hostingdotcom.HostingDotComVCloudAsyncClient;
|
||||
import org.jclouds.vcloud.hostingdotcom.HostingDotComVCloudClient;
|
||||
import org.jclouds.vcloud.compute.config.VCloudComputeServiceContextModule;
|
||||
import org.jclouds.vcloud.hostingdotcom.compute.HostingDotComVCloudComputeService;
|
||||
import org.jclouds.vcloud.hostingdotcom.compute.HostingDotComVCloudTemplate;
|
||||
import org.jclouds.vcloud.hostingdotcom.config.HostingDotComVCloudContextModule;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.inject.Provides;
|
||||
import com.google.inject.Injector;
|
||||
|
||||
/**
|
||||
* Configures the {@link HostingDotComVCloudComputeServiceContext}; requires
|
||||
|
@ -59,81 +31,16 @@ import com.google.inject.Provides;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
public class HostingDotComVCloudComputeServiceContextModule extends
|
||||
HostingDotComVCloudContextModule {
|
||||
VCloudComputeServiceContextModule {
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
super.configure();
|
||||
bind(ComputeService.class).to(HostingDotComVCloudComputeService.class).asEagerSingleton();
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
ComputeServiceContext provideContext(ComputeService computeService,
|
||||
RestContext<HostingDotComVCloudAsyncClient, HostingDotComVCloudClient> context) {
|
||||
return new ComputeServiceContextImpl<HostingDotComVCloudAsyncClient, HostingDotComVCloudClient>(
|
||||
computeService, context);
|
||||
}
|
||||
|
||||
private static class LogHolder {
|
||||
@Resource
|
||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||
protected Logger logger = Logger.NULL;
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
Set<? extends Image> provideImages(VCloudClient client, LogHolder holder) {
|
||||
Set<Image> images = Sets.newLinkedHashSet();
|
||||
holder.logger.debug(">> providing images");
|
||||
Catalog response = client.getDefaultCatalog();
|
||||
String vDC = client.getDefaultVDC().getId();
|
||||
for (NamedResource resource : response.values()) {
|
||||
if (resource.getType().equals(VCloudMediaType.CATALOGITEM_XML)) {
|
||||
|
||||
CatalogItem item = client.getCatalogItem(resource.getId());
|
||||
OperatingSystem myOs = OperatingSystem.UNKNOWN;
|
||||
for (OperatingSystem os : OperatingSystem.values()) {
|
||||
if (resource.getName().toUpperCase().replaceAll("\\s", "").indexOf(os.toString()) != -1) {
|
||||
myOs = os;
|
||||
}
|
||||
}
|
||||
Architecture arch = resource.getName().matches("64[- ]bit") ? Architecture.X86_32
|
||||
: Architecture.X86_64;
|
||||
if (item.getEntity().getType().equals(VCloudMediaType.VAPPTEMPLATE_XML)) {
|
||||
VAppTemplate template = client.getVAppTemplate(item.getEntity().getId());
|
||||
images.add(new ImageImpl(resource.getId(), template.getDescription(), myOs, null,
|
||||
vDC, arch));
|
||||
}
|
||||
}
|
||||
}
|
||||
holder.logger.debug("<< images(%d)", images.size());
|
||||
return images;
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
Set<? extends Size> provideSizes(HostingDotComVCloudClient client, Set<? extends Image> images,
|
||||
LogHolder holder) {
|
||||
return ImmutableSet.<Size> of(new SizeImpl(1, 512, (int) (10l * 1025 * 1024), ImmutableSet
|
||||
.<Architecture> of(Architecture.X86_32, Architecture.X86_64)));
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
Set<HostingDotComVCloudTemplate> provideTemplates(HostingDotComVCloudClient client,
|
||||
Set<? extends Image> images, Set<? extends Size> sizes, LogHolder holder) {
|
||||
Set<HostingDotComVCloudTemplate> templates = Sets.newHashSet();
|
||||
holder.logger.debug(">> generating templates");
|
||||
String vDC = client.getDefaultVDC().getId();
|
||||
for (Size size : sizes) {
|
||||
for (Image image : images) {
|
||||
templates.add(new HostingDotComVCloudTemplate(client, images, sizes, vDC, size, image
|
||||
.getOperatingSystem(), image));
|
||||
}
|
||||
}
|
||||
holder.logger.debug("<< templates(%d)", templates.size());
|
||||
return templates;
|
||||
@Override
|
||||
protected ComputeService provideComputeService(Injector injector) {
|
||||
return injector.getInstance(HostingDotComVCloudComputeService.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -19,138 +19,49 @@
|
|||
package org.jclouds.vcloud.hostingdotcom.compute;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.jclouds.compute.domain.OperatingSystem;
|
||||
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
|
||||
import org.jclouds.ssh.jsch.config.JschSshClientModule;
|
||||
import org.jclouds.vcloud.domain.ResourceType;
|
||||
import org.jclouds.vcloud.domain.VApp;
|
||||
import org.jclouds.vcloud.domain.VAppStatus;
|
||||
import org.jclouds.vcloud.compute.VCloudComputeClientLiveTest;
|
||||
import org.jclouds.vcloud.hostingdotcom.HostingDotComVCloudClient;
|
||||
import org.jclouds.vcloud.hostingdotcom.HostingDotComVCloudContextBuilder;
|
||||
import org.jclouds.vcloud.hostingdotcom.HostingDotComVCloudPropertiesBuilder;
|
||||
import org.testng.annotations.AfterTest;
|
||||
import org.testng.annotations.BeforeGroups;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.base.CaseFormat;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Key;
|
||||
import com.google.inject.TypeLiteral;
|
||||
import com.google.inject.internal.ImmutableMap;
|
||||
|
||||
/**
|
||||
* Tests behavior of {@code HostingDotComVCloudClient}
|
||||
* Tests behavior of {@code HostingDotComVCloudComputeClient}
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "live", enabled = true, sequential = true, testName = "vcloud.HostingDotComVCloudClientLiveTest")
|
||||
public class HostingDotComVCloudComputeClientLiveTest {
|
||||
HostingDotComVCloudComputeClient client;
|
||||
HostingDotComVCloudClient hostingClient;
|
||||
|
||||
private String id;
|
||||
private InetAddress privateAddress;
|
||||
|
||||
public static final String PREFIX = System.getProperty("user.name") + "-terremark";
|
||||
|
||||
private static class Expectation {
|
||||
final long hardDisk;
|
||||
final String os;
|
||||
|
||||
public Expectation(long hardDisk, String os) {
|
||||
this.hardDisk = hardDisk;
|
||||
this.os = os;
|
||||
}
|
||||
}
|
||||
|
||||
private Map<OperatingSystem, Expectation> expectationMap = ImmutableMap
|
||||
.<OperatingSystem, Expectation> builder().put(OperatingSystem.CENTOS,
|
||||
new Expectation(4194304 / 2 * 10, "Red Hat Enterprise Linux 5 (64-bit)"))
|
||||
.build();
|
||||
|
||||
private Predicate<InetAddress> addressTester;
|
||||
|
||||
@Test(enabled = true)
|
||||
public void testPowerOn() throws InterruptedException, ExecutionException, TimeoutException,
|
||||
IOException {
|
||||
OperatingSystem toTest = OperatingSystem.CENTOS;
|
||||
|
||||
String serverName = getCompatibleServerName(toTest);
|
||||
int processorCount = 1;
|
||||
int memory = 512;
|
||||
long disk = 10 * 1025 * 1024;
|
||||
Map<String, String> properties = ImmutableMap.of("foo", "bar");
|
||||
|
||||
id = client.start(hostingClient.getDefaultVDC().getId(), serverName, "3", processorCount,
|
||||
memory, disk, properties).get("id");
|
||||
Expectation expectation = expectationMap.get(toTest);
|
||||
|
||||
VApp vApp = hostingClient.getVApp(id);
|
||||
verifyConfigurationOfVApp(vApp, serverName, expectation.os, processorCount, memory,
|
||||
expectation.hardDisk);
|
||||
assertEquals(vApp.getStatus(), VAppStatus.ON);
|
||||
}
|
||||
|
||||
private String getCompatibleServerName(OperatingSystem toTest) {
|
||||
String serverName = CaseFormat.UPPER_UNDERSCORE
|
||||
.to(CaseFormat.LOWER_HYPHEN, toTest.toString()).substring(0,
|
||||
toTest.toString().length() <= 15 ? toTest.toString().length() : 14);
|
||||
return serverName;
|
||||
}
|
||||
|
||||
@Test(dependsOnMethods = "testPowerOn", enabled = true)
|
||||
public void testGetAnyPrivateAddress() {
|
||||
privateAddress = client.getAnyPrivateAddress(id);
|
||||
assert !addressTester.apply(privateAddress);
|
||||
}
|
||||
|
||||
private void verifyConfigurationOfVApp(VApp vApp, String serverName, String expectedOs,
|
||||
int processorCount, int memory, long hardDisk) {
|
||||
// assertEquals(vApp.getName(), serverName);
|
||||
// assertEquals(vApp.getOperatingSystemDescription(), expectedOs);
|
||||
assertEquals(
|
||||
Iterables.getOnlyElement(
|
||||
vApp.getResourceAllocationByType().get(ResourceType.PROCESSOR))
|
||||
.getVirtualQuantity(), processorCount);
|
||||
assertEquals(Iterables.getOnlyElement(
|
||||
vApp.getResourceAllocationByType().get(ResourceType.SCSI_CONTROLLER))
|
||||
.getVirtualQuantity(), 1);
|
||||
assertEquals(Iterables.getOnlyElement(
|
||||
vApp.getResourceAllocationByType().get(ResourceType.MEMORY)).getVirtualQuantity(),
|
||||
memory);
|
||||
assertEquals(Iterables.getOnlyElement(
|
||||
vApp.getResourceAllocationByType().get(ResourceType.DISK_DRIVE))
|
||||
.getVirtualQuantity(), hardDisk);
|
||||
}
|
||||
|
||||
@AfterTest
|
||||
void cleanup() throws InterruptedException, ExecutionException, TimeoutException {
|
||||
if (id != null)
|
||||
client.stop(id);
|
||||
}
|
||||
@Test(groups = "live", enabled = true, sequential = true, testName = "vcloud.HostingDotComVCloudComputeClientLiveTest")
|
||||
public class HostingDotComVCloudComputeClientLiveTest extends VCloudComputeClientLiveTest {
|
||||
|
||||
@BeforeGroups(groups = { "live" })
|
||||
@Override
|
||||
public void setupClient() {
|
||||
|
||||
String account = checkNotNull(System.getProperty("jclouds.test.user"), "jclouds.test.user");
|
||||
String key = checkNotNull(System.getProperty("jclouds.test.key"), "jclouds.test.key");
|
||||
Injector injector = new HostingDotComVCloudContextBuilder(
|
||||
Injector injector = new HostingDotComVCloudComputeServiceContextBuilder(
|
||||
new HostingDotComVCloudPropertiesBuilder(account, key).build()).withModules(
|
||||
new Log4JLoggingModule(), new JschSshClientModule()).buildInjector();
|
||||
client = injector.getInstance(HostingDotComVCloudComputeClient.class);
|
||||
hostingClient = injector.getInstance(HostingDotComVCloudClient.class);
|
||||
computeClient = injector.getInstance(HostingDotComVCloudComputeService.class);
|
||||
client = injector.getInstance(HostingDotComVCloudClient.class);
|
||||
addressTester = injector.getInstance(Key.get(new TypeLiteral<Predicate<InetAddress>>() {
|
||||
}));
|
||||
expectationMap = ImmutableMap.<OperatingSystem, Expectation> builder().put(
|
||||
OperatingSystem.CENTOS,
|
||||
new Expectation(4194304 / 2 * 10, "Red Hat Enterprise Linux 5 (64-bit)")).build();
|
||||
service = "vcloudtest";
|
||||
templateId = "3";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -19,160 +19,30 @@
|
|||
|
||||
package org.jclouds.vcloud.hostingdotcom.compute;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.jclouds.compute.domain.OperatingSystem.CENTOS;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.jclouds.compute.ComputeService;
|
||||
import org.jclouds.compute.ComputeServiceContext;
|
||||
import org.jclouds.compute.ComputeServiceContextFactory;
|
||||
import org.jclouds.compute.domain.ComputeMetadata;
|
||||
import org.jclouds.compute.domain.ComputeType;
|
||||
import org.jclouds.compute.domain.CreateNodeResponse;
|
||||
import org.jclouds.compute.domain.LoginType;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.OperatingSystem;
|
||||
import org.jclouds.compute.domain.Size;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
|
||||
import org.jclouds.predicates.RetryablePredicate;
|
||||
import org.jclouds.predicates.SocketOpen;
|
||||
import org.jclouds.ssh.ExecResponse;
|
||||
import org.jclouds.ssh.SshClient;
|
||||
import org.jclouds.ssh.SshException;
|
||||
import org.jclouds.compute.BaseComputeServiceLiveTest;
|
||||
import org.jclouds.ssh.jsch.config.JschSshClientModule;
|
||||
import org.testng.annotations.AfterTest;
|
||||
import org.testng.annotations.BeforeGroups;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
|
||||
/**
|
||||
*
|
||||
* Generally disabled, as it incurs higher fees.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "live", enabled = true, sequential = true, testName = "compute.HostingDotComVCloudComputeServiceLiveTest")
|
||||
public class HostingDotComVCloudComputeServiceLiveTest {
|
||||
private static final String service = "hostingdotcom";
|
||||
private static final OperatingSystem testOS = CENTOS;
|
||||
|
||||
protected SshClient.Factory sshFactory;
|
||||
private String nodeName = service;
|
||||
|
||||
private RetryablePredicate<InetSocketAddress> socketTester;
|
||||
private CreateNodeResponse node;
|
||||
private ComputeServiceContext context;
|
||||
private ComputeService client;
|
||||
|
||||
@BeforeGroups(groups = { "live" })
|
||||
public void setupClient() throws InterruptedException, ExecutionException, TimeoutException,
|
||||
IOException {
|
||||
String user = checkNotNull(System.getProperty("jclouds.test.user"), "jclouds.test.user");
|
||||
String password = checkNotNull(System.getProperty("jclouds.test.key"), "jclouds.test.key");
|
||||
context = new ComputeServiceContextFactory().createContext(service, user, password,
|
||||
ImmutableSet.of(new Log4JLoggingModule()), new Properties());
|
||||
Injector injector = Guice.createInjector(new JschSshClientModule());
|
||||
sshFactory = injector.getInstance(SshClient.Factory.class);
|
||||
SocketOpen socketOpen = injector.getInstance(SocketOpen.class);
|
||||
socketTester = new RetryablePredicate<InetSocketAddress>(socketOpen, 60, 1, TimeUnit.SECONDS);
|
||||
injector.injectMembers(socketOpen); // add logger
|
||||
client = context.getComputeService();
|
||||
public class HostingDotComVCloudComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
||||
@BeforeClass
|
||||
@Override
|
||||
public void setServiceDefaults() {
|
||||
service = "hostingdotcom";
|
||||
testOS = CENTOS;
|
||||
}
|
||||
|
||||
public void testCreate() throws Exception {
|
||||
Template template = client.createTemplateInLocation("default").os(testOS).smallest();
|
||||
node = client.runNode(nodeName, template);
|
||||
assertNotNull(node.getId());
|
||||
assertEquals(node.getLoginPort(), 22);
|
||||
assertEquals(node.getLoginType(), LoginType.SSH);
|
||||
assertNotNull(node.getName());
|
||||
assertEquals(node.getPrivateAddresses().size(), 1);
|
||||
assertEquals(node.getPublicAddresses().size(), 1);
|
||||
assertNotNull(node.getCredentials());
|
||||
assertNotNull(node.getCredentials().account);
|
||||
assertNotNull(node.getCredentials().key);
|
||||
sshPing();
|
||||
@Override
|
||||
protected JschSshClientModule getSshModule() {
|
||||
return new JschSshClientModule();
|
||||
}
|
||||
|
||||
@Test(dependsOnMethods = "testCreate")
|
||||
public void testGet() throws Exception {
|
||||
NodeMetadata metadata = client.getNodeMetadata(node);
|
||||
assertEquals(metadata.getId(), node.getId());
|
||||
assertEquals(metadata.getLoginPort(), node.getLoginPort());
|
||||
assertEquals(metadata.getLoginType(), node.getLoginType());
|
||||
assertEquals(metadata.getName(), node.getName());
|
||||
assertEquals(metadata.getPrivateAddresses(), node.getPrivateAddresses());
|
||||
assertEquals(metadata.getPublicAddresses(), node.getPublicAddresses());
|
||||
}
|
||||
|
||||
public void testList() throws Exception {
|
||||
for (ComputeMetadata node : client.listNodes()) {
|
||||
assert node.getId() != null;
|
||||
assert node.getLocation() != null;
|
||||
assertEquals(node.getType(), ComputeType.NODE);
|
||||
}
|
||||
}
|
||||
|
||||
public void testListTemplates() throws Exception {
|
||||
for (Template template : client.listTemplates()) {
|
||||
assert template.getImage() != null;
|
||||
System.out.println(template);
|
||||
}
|
||||
}
|
||||
|
||||
public void testListSizes() throws Exception {
|
||||
for (Size size : client.listSizes()) {
|
||||
assert size.getCores() != null;
|
||||
System.out.println(size);
|
||||
}
|
||||
}
|
||||
|
||||
private void sshPing() throws IOException {
|
||||
try {
|
||||
doCheckKey();
|
||||
} catch (SshException e) {// try twice in case there is a network timeout
|
||||
try {
|
||||
Thread.sleep(10 * 1000);
|
||||
} catch (InterruptedException e1) {
|
||||
}
|
||||
doCheckKey();
|
||||
}
|
||||
}
|
||||
|
||||
private void doCheckKey() throws IOException {
|
||||
InetSocketAddress socket = new InetSocketAddress(node.getPublicAddresses().last(), node
|
||||
.getLoginPort());
|
||||
socketTester.apply(socket);
|
||||
SshClient ssh = node.getCredentials().key.startsWith("-----BEGIN RSA PRIVATE KEY-----") ? sshFactory
|
||||
.create(socket, node.getCredentials().account, node.getCredentials().key.getBytes())
|
||||
: sshFactory
|
||||
.create(socket, node.getCredentials().account, node.getCredentials().key);
|
||||
try {
|
||||
ssh.connect();
|
||||
ExecResponse hello = ssh.exec("echo hello");
|
||||
assertEquals(hello.getOutput().trim(), "hello");
|
||||
} finally {
|
||||
if (ssh != null)
|
||||
ssh.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
@AfterTest
|
||||
void cleanup() throws InterruptedException, ExecutionException, TimeoutException {
|
||||
if (node != null)
|
||||
client.destroyNode(node);
|
||||
context.close();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -86,9 +86,8 @@ public class TerremarkVCloudComputeClient {
|
|||
properties);
|
||||
}
|
||||
|
||||
public String start(String vdc, String name, String templateId, int minCores, int minMegs,
|
||||
public String start(String vDCId, String name, String templateId, int minCores, int minMegs,
|
||||
Map<String, String> properties) {
|
||||
String vDCId = tmClient.getDefaultVDC().getId();
|
||||
logger
|
||||
.debug(
|
||||
">> instantiating vApp vDC(%s) template(%s) name(%s) minCores(%d) minMegs(%d) properties(%s)",
|
||||
|
|
|
@ -18,12 +18,13 @@
|
|||
*/
|
||||
package org.jclouds.vcloud.terremark.compute;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.jclouds.vcloud.terremark.options.AddInternetServiceOptions.Builder.withDescription;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.SortedSet;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Inject;
|
||||
|
@ -31,127 +32,176 @@ import javax.inject.Named;
|
|||
import javax.inject.Provider;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.compute.ComputeService;
|
||||
import org.jclouds.compute.domain.ComputeMetadata;
|
||||
import org.jclouds.compute.domain.ComputeType;
|
||||
import org.jclouds.compute.domain.CreateNodeResponse;
|
||||
import org.jclouds.compute.domain.Image;
|
||||
import org.jclouds.compute.domain.LoginType;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.NodeState;
|
||||
import org.jclouds.compute.domain.Size;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.compute.domain.internal.CreateNodeResponseImpl;
|
||||
import org.jclouds.compute.domain.internal.NodeMetadataImpl;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.vcloud.VCloudMediaType;
|
||||
import org.jclouds.vcloud.domain.NamedResource;
|
||||
import org.jclouds.vcloud.compute.VCloudComputeService;
|
||||
import org.jclouds.vcloud.compute.VCloudTemplate;
|
||||
import org.jclouds.vcloud.domain.VApp;
|
||||
import org.jclouds.vcloud.domain.VAppStatus;
|
||||
import org.jclouds.vcloud.terremark.TerremarkVCloudClient;
|
||||
import org.jclouds.vcloud.terremark.domain.InternetService;
|
||||
import org.jclouds.vcloud.terremark.domain.Node;
|
||||
import org.jclouds.vcloud.terremark.domain.Protocol;
|
||||
import org.jclouds.vcloud.terremark.domain.PublicIpAddress;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.inject.internal.ImmutableSet;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class TerremarkVCloudComputeService implements ComputeService {
|
||||
public class TerremarkVCloudComputeService extends VCloudComputeService {
|
||||
@Resource
|
||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||
protected Logger logger = Logger.NULL;
|
||||
private final TerremarkVCloudComputeClient computeClient;
|
||||
private final TerremarkVCloudClient client;
|
||||
private Set<? extends Image> images;
|
||||
private Set<? extends Size> sizes;
|
||||
private Provider<Set<TerremarkVCloudTemplate>> templates;
|
||||
|
||||
private static final Map<VAppStatus, NodeState> vAppStatusToNodeState = ImmutableMap
|
||||
.<VAppStatus, NodeState> builder().put(VAppStatus.OFF, NodeState.TERMINATED).put(
|
||||
VAppStatus.ON, NodeState.RUNNING).put(VAppStatus.RESOLVED, NodeState.PENDING)
|
||||
.put(VAppStatus.SUSPENDED, NodeState.SUSPENDED).put(VAppStatus.UNRESOLVED,
|
||||
NodeState.PENDING).build();
|
||||
|
||||
@Inject
|
||||
public TerremarkVCloudComputeService(TerremarkVCloudClient tmClient,
|
||||
TerremarkVCloudComputeClient computeClient, Set<? extends Image> images,
|
||||
Set<? extends Size> sizes, Provider<Set<TerremarkVCloudTemplate>> templates) {
|
||||
this.client = tmClient;
|
||||
this.computeClient = computeClient;
|
||||
this.images = images;
|
||||
this.sizes = sizes;
|
||||
this.templates = templates;
|
||||
public TerremarkVCloudComputeService(TerremarkVCloudClient client,
|
||||
Provider<Set<? extends Image>> images, Provider<SortedSet<? extends Size>> sizes,
|
||||
Provider<Set<? extends VCloudTemplate>> templates, Predicate<String> successTester,
|
||||
Predicate<InetSocketAddress> socketTester) {
|
||||
super(client, images, sizes, templates, successTester, socketTester);
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CreateNodeResponse runNode(String name, Template template) {
|
||||
checkNotNull(template.getImage().getLocation(), "location");
|
||||
String id = computeClient.start(template.getImage().getLocation(), name, template.getImage()
|
||||
.getId(), (int) template.getSize().getCores(), (int) template.getSize().getRam(),
|
||||
ImmutableMap.<String, String> of());
|
||||
protected Map<String, String> parseResponse(VApp vAppResponse) {
|
||||
return ImmutableMap.<String, String> of("id", vAppResponse.getId(), "username", "vcloud",
|
||||
"password", "p4ssw0rd");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> start(String vDCId, String name, String templateId, int minCores,
|
||||
int minMegs, Long diskSize, Map<String, String> properties, int... portsToOpen) {
|
||||
Map<String, String> response = super.start(vDCId, name, templateId, minCores, minMegs, null,
|
||||
properties, portsToOpen);// trmk does not support resizing the primary disk
|
||||
if (portsToOpen.length > 0)
|
||||
createPublicAddressMappedToPorts(response.get("id"), portsToOpen);
|
||||
return response;
|
||||
}
|
||||
|
||||
public InetAddress createPublicAddressMappedToPorts(String vAppId, int... ports) {
|
||||
VApp vApp = client.getVApp(vAppId);
|
||||
PublicIpAddress ip = null;
|
||||
InetAddress privateAddress = Iterables.getLast(vApp.getNetworkToAddresses().values());
|
||||
for (int port : ports) {
|
||||
InternetService is = null;
|
||||
Protocol protocol;
|
||||
switch (port) {
|
||||
case 22:
|
||||
protocol = Protocol.TCP;
|
||||
break;
|
||||
case 80:
|
||||
case 8080:
|
||||
protocol = Protocol.HTTP;
|
||||
break;
|
||||
case 443:
|
||||
protocol = Protocol.HTTPS;
|
||||
break;
|
||||
default:
|
||||
protocol = Protocol.HTTP;
|
||||
break;
|
||||
}
|
||||
if (ip == null) {
|
||||
logger.debug(">> creating InternetService in vDC %s:%s:%d", vApp.getVDC().getId(),
|
||||
protocol, port);
|
||||
is = client.addInternetServiceToVDC(vApp.getVDC().getId(), vApp.getName() + "-" + port,
|
||||
protocol, port, withDescription(String.format(
|
||||
"port %d access to serverId: %s name: %s", port, vApp.getId(), vApp
|
||||
.getName())));
|
||||
ip = is.getPublicIpAddress();
|
||||
} else {
|
||||
logger.debug(">> adding InternetService %s:%s:%d", ip.getAddress().getHostAddress(),
|
||||
protocol, port);
|
||||
is = client.addInternetServiceToExistingIp(ip.getId(), vApp.getName() + "-" + port,
|
||||
protocol, port, withDescription(String.format(
|
||||
"port %d access to serverId: %s name: %s", port, vApp.getId(), vApp
|
||||
.getName())));
|
||||
}
|
||||
logger.debug("<< created InternetService(%s) %s:%s:%d", is.getId(), is
|
||||
.getPublicIpAddress().getAddress().getHostAddress(), is.getProtocol(), is
|
||||
.getPort());
|
||||
logger.debug(">> adding Node %s:%d -> %s:%d", is.getPublicIpAddress().getAddress()
|
||||
.getHostAddress(), is.getPort(), privateAddress.getHostAddress(), port);
|
||||
Node node = client.addNode(is.getId(), privateAddress, vApp.getName() + "-" + port, port);
|
||||
logger.debug("<< added Node(%s)", node.getId());
|
||||
}
|
||||
return ip != null ? ip.getAddress() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop(String id) {
|
||||
VApp vApp = client.getVApp(id);
|
||||
InetAddress publicIp = computeClient
|
||||
.createPublicAddressMappedToPorts(vApp, 22, 80, 8080, 443);
|
||||
return new CreateNodeResponseImpl(vApp.getId(), vApp.getName(), template.getImage().getLocation(), vApp.getLocation(),
|
||||
ImmutableMap.<String, String> of(), vAppStatusToNodeState.get(vApp.getStatus()),
|
||||
ImmutableSet.<InetAddress> of(publicIp), vApp.getNetworkToAddresses().values(), 22,
|
||||
LoginType.SSH, new Credentials("vcloud", "p4ssw0rd"), ImmutableMap
|
||||
.<String, String> of());
|
||||
Set<PublicIpAddress> ipAddresses = deleteInternetServicesAndNodesAssociatedWithVApp(vApp);
|
||||
deletePublicIpAddressesWithNoServicesAttached(ipAddresses);
|
||||
super.stop(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NodeMetadata getNodeMetadata(ComputeMetadata node) {
|
||||
checkArgument(node.getType() == ComputeType.NODE, "this is only valid for nodes, not "
|
||||
+ node.getType());
|
||||
return getNodeMetadataByIdInVDC(checkNotNull(node.getLocation(), "location"), checkNotNull(
|
||||
node.getId(), "node.id"));
|
||||
}
|
||||
|
||||
private NodeMetadata getNodeMetadataByIdInVDC(String vDCId, String id) {
|
||||
VApp vApp = client.getVApp(id);
|
||||
Set<InetAddress> publicAddresses = computeClient.getPublicAddresses(vApp.getId());
|
||||
return new NodeMetadataImpl(vApp.getId(), vApp.getName(), vDCId, vApp.getLocation(),
|
||||
ImmutableMap.<String, String> of(), vAppStatusToNodeState.get(vApp.getStatus()),
|
||||
publicAddresses, vApp.getNetworkToAddresses().values(), 22, LoginType.SSH,
|
||||
ImmutableMap.<String, String> of());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<ComputeMetadata> listNodes() {
|
||||
Set<ComputeMetadata> nodes = Sets.newHashSet();
|
||||
for (NamedResource vdc : client.getDefaultOrganization().getVDCs().values()) {
|
||||
for (NamedResource resource : client.getVDC(vdc.getId()).getResourceEntities().values()) {
|
||||
if (resource.getType().equals(VCloudMediaType.VAPP_XML)) {
|
||||
nodes.add(getNodeMetadataByIdInVDC(vdc.getId(), resource.getId()));
|
||||
private Set<PublicIpAddress> deleteInternetServicesAndNodesAssociatedWithVApp(VApp vApp) {
|
||||
Set<PublicIpAddress> ipAddresses = Sets.newHashSet();
|
||||
SERVICE: for (InternetService service : client.getAllInternetServicesInVDC(vApp.getVDC()
|
||||
.getId())) {
|
||||
for (Node node : client.getNodes(service.getId())) {
|
||||
if (vApp.getNetworkToAddresses().containsValue(node.getIpAddress())) {
|
||||
ipAddresses.add(service.getPublicIpAddress());
|
||||
logger.debug(">> deleting Node(%s) %s:%d -> %s:%d", node.getId(), service
|
||||
.getPublicIpAddress().getAddress().getHostAddress(), service.getPort(),
|
||||
node.getIpAddress().getHostAddress(), node.getPort());
|
||||
client.deleteNode(node.getId());
|
||||
logger.debug("<< deleted Node(%s)", node.getId());
|
||||
SortedSet<Node> nodes = client.getNodes(service.getId());
|
||||
if (nodes.size() == 0) {
|
||||
logger.debug(">> deleting InternetService(%s) %s:%d", service.getId(), service
|
||||
.getPublicIpAddress().getAddress().getHostAddress(), service.getPort());
|
||||
client.deleteInternetService(service.getId());
|
||||
logger.debug("<< deleted InternetService(%s)", service.getId());
|
||||
continue SERVICE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nodes;
|
||||
return ipAddresses;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroyNode(ComputeMetadata node) {
|
||||
checkArgument(node.getType() == ComputeType.NODE, "this is only valid for nodes, not "
|
||||
+ node.getType());
|
||||
computeClient.stop(checkNotNull(node.getId(), "node.id"));
|
||||
private void deletePublicIpAddressesWithNoServicesAttached(Set<PublicIpAddress> ipAddresses) {
|
||||
IPADDRESS: for (PublicIpAddress address : ipAddresses) {
|
||||
SortedSet<InternetService> services = client
|
||||
.getInternetServicesOnPublicIp(address.getId());
|
||||
if (services.size() == 0) {
|
||||
logger.debug(">> deleting PublicIpAddress(%s) %s", address.getId(), address
|
||||
.getAddress().getHostAddress());
|
||||
client.deletePublicIp(address.getId());
|
||||
logger.debug("<< deleted PublicIpAddress(%s)", address.getId());
|
||||
continue IPADDRESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Template createTemplateInLocation(String location) {
|
||||
return new TerremarkVCloudTemplate(client, images, sizes, location);
|
||||
/**
|
||||
*
|
||||
* @throws ElementNotFoundException
|
||||
* if no address is configured
|
||||
*/
|
||||
public InetAddress getAnyPrivateAddress(String id) {
|
||||
VApp vApp = client.getVApp(id);
|
||||
return Iterables.getLast(vApp.getNetworkToAddresses().values());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<? extends Size> listSizes() {
|
||||
return sizes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<? extends Template> listTemplates() {
|
||||
return templates.get();
|
||||
public Set<InetAddress> getPublicAddresses(String id) {
|
||||
VApp vApp = client.getVApp(id);
|
||||
Set<InetAddress> ipAddresses = Sets.newHashSet();
|
||||
for (InternetService service : client.getAllInternetServicesInVDC(vApp.getVDC().getId())) {
|
||||
for (Node node : client.getNodes(service.getId())) {
|
||||
if (vApp.getNetworkToAddresses().containsValue(node.getIpAddress())) {
|
||||
ipAddresses.add(service.getPublicIpAddress().getAddress());
|
||||
}
|
||||
}
|
||||
}
|
||||
return ipAddresses;
|
||||
}
|
||||
}
|
|
@ -20,22 +20,15 @@ package org.jclouds.vcloud.terremark.compute;
|
|||
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
import org.jclouds.compute.ComputeServiceContext;
|
||||
import org.jclouds.compute.ComputeServiceContextBuilder;
|
||||
import org.jclouds.compute.internal.ComputeServiceContextImpl;
|
||||
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
|
||||
import org.jclouds.logging.jdk.config.JDKLoggingModule;
|
||||
import org.jclouds.vcloud.terremark.TerremarkVCloudAsyncClient;
|
||||
import org.jclouds.vcloud.terremark.TerremarkVCloudClient;
|
||||
import org.jclouds.vcloud.compute.VCloudComputeServiceContextBuilder;
|
||||
import org.jclouds.vcloud.terremark.compute.config.TerremarkVCloudComputeServiceContextModule;
|
||||
import org.jclouds.vcloud.terremark.config.TerremarkVCloudRestClientModule;
|
||||
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Key;
|
||||
import com.google.inject.Module;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
||||
/**
|
||||
* Creates {@link TerremarkVCloudComputeServiceContext} or {@link Injector} instances based on the
|
||||
|
@ -50,23 +43,10 @@ import com.google.inject.TypeLiteral;
|
|||
* @author Adrian Cole
|
||||
* @see TerremarkVCloudComputeServiceContext
|
||||
*/
|
||||
public class TerremarkVCloudComputeServiceContextBuilder extends
|
||||
ComputeServiceContextBuilder<TerremarkVCloudAsyncClient, TerremarkVCloudClient> {
|
||||
public class TerremarkVCloudComputeServiceContextBuilder extends VCloudComputeServiceContextBuilder {
|
||||
|
||||
public TerremarkVCloudComputeServiceContextBuilder(Properties props) {
|
||||
super(new TypeLiteral<TerremarkVCloudAsyncClient>() {
|
||||
}, new TypeLiteral<TerremarkVCloudClient>() {
|
||||
}, props);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TerremarkVCloudComputeServiceContextBuilder withExecutorService(ExecutorService service) {
|
||||
return (TerremarkVCloudComputeServiceContextBuilder) super.withExecutorService(service);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TerremarkVCloudComputeServiceContextBuilder withModules(Module... modules) {
|
||||
return (TerremarkVCloudComputeServiceContextBuilder) super.withModules(modules);
|
||||
super(props);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -79,14 +59,4 @@ public class TerremarkVCloudComputeServiceContextBuilder extends
|
|||
modules.add(new TerremarkVCloudRestClientModule());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ComputeServiceContext buildComputeServiceContext() {
|
||||
// need the generic type information
|
||||
return (ComputeServiceContext) this
|
||||
.buildInjector()
|
||||
.getInstance(
|
||||
Key
|
||||
.get(new TypeLiteral<ComputeServiceContextImpl<TerremarkVCloudAsyncClient, TerremarkVCloudClient>>() {
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,178 +0,0 @@
|
|||
package org.jclouds.vcloud.terremark.compute;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.jclouds.compute.domain.Image;
|
||||
import org.jclouds.compute.domain.OperatingSystem;
|
||||
import org.jclouds.compute.domain.Size;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.vcloud.terremark.TerremarkVCloudClient;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class TerremarkVCloudTemplate implements Template {
|
||||
private final TerremarkVCloudClient client;
|
||||
private final Set<? extends Image> images;
|
||||
private final Set<? extends Size> sizes;
|
||||
private Size size;
|
||||
private String vDC;
|
||||
private OperatingSystem operatingSystem;
|
||||
private transient Image image;
|
||||
|
||||
public TerremarkVCloudTemplate(TerremarkVCloudClient client, Set<? extends Image> images,
|
||||
Set<? extends Size> sizes, String location, @Nullable Size size,
|
||||
OperatingSystem operatingSystem, @Nullable Image image) {
|
||||
this.client = client;
|
||||
this.images = images;
|
||||
this.sizes = sizes;
|
||||
this.vDC = location;
|
||||
this.image = image != null ? image : resolveTemplate(images, operatingSystem);
|
||||
this.size = size != null ? size : Iterables.get(sizes, 0);
|
||||
this.operatingSystem = operatingSystem;
|
||||
}
|
||||
|
||||
private Image resolveTemplate(Set<? extends Image> images, OperatingSystem operatingSystem) {
|
||||
for (Image image : images) {
|
||||
if (image.getOperatingSystem() == operatingSystem)
|
||||
return image;
|
||||
}
|
||||
throw new RuntimeException("no configured image matches os: " + operatingSystem);
|
||||
}
|
||||
|
||||
TerremarkVCloudTemplate(TerremarkVCloudClient client, Set<? extends Image> images,
|
||||
Set<? extends Size> sizes, String location) {
|
||||
this(client, images, sizes, location, null, OperatingSystem.UBUNTU, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Size getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Image getImage() {
|
||||
return image;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Template smallest() {
|
||||
this.size = Iterables.get(sizes, 0);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Template biggest() {
|
||||
this.size = Iterables.getLast(sizes);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Template fastest() {
|
||||
this.size = Iterables.getLast(sizes);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Template inLocation(String location) {
|
||||
if (location.equalsIgnoreCase("default"))
|
||||
location = client.getDefaultVDC().getId();
|
||||
this.vDC = location;// TODO match vdc on template as well arch
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Template os(OperatingSystem os) {
|
||||
this.operatingSystem = os;
|
||||
this.image = resolveTemplate(images, operatingSystem);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected Object clone() throws CloneNotSupportedException {
|
||||
return new TerremarkVCloudTemplate(client, images, sizes, vDC, size, operatingSystem, image);
|
||||
}
|
||||
|
||||
public String getvDC() {
|
||||
return vDC;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((image == null) ? 0 : image.hashCode());
|
||||
result = prime * result + ((operatingSystem == null) ? 0 : operatingSystem.hashCode());
|
||||
result = prime * result + ((size == null) ? 0 : size.hashCode());
|
||||
result = prime * result + ((vDC == null) ? 0 : vDC.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
TerremarkVCloudTemplate other = (TerremarkVCloudTemplate) obj;
|
||||
if (image == null) {
|
||||
if (other.image != null)
|
||||
return false;
|
||||
} else if (!image.equals(other.image))
|
||||
return false;
|
||||
if (operatingSystem == null) {
|
||||
if (other.operatingSystem != null)
|
||||
return false;
|
||||
} else if (!operatingSystem.equals(other.operatingSystem))
|
||||
return false;
|
||||
if (size == null) {
|
||||
if (other.size != null)
|
||||
return false;
|
||||
} else if (!size.equals(other.size))
|
||||
return false;
|
||||
if (vDC == null) {
|
||||
if (other.vDC != null)
|
||||
return false;
|
||||
} else if (!vDC.equals(other.vDC))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TerremarkVCloudTemplate [image=" + image + ", operatingSystem=" + operatingSystem
|
||||
+ ", size=" + size + ", vDC=" + vDC + "]";
|
||||
}
|
||||
|
||||
}
|
|
@ -18,43 +18,26 @@
|
|||
*/
|
||||
package org.jclouds.vcloud.terremark.compute.config;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
import java.util.SortedSet;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
import org.jclouds.compute.ComputeService;
|
||||
import org.jclouds.compute.ComputeServiceContext;
|
||||
import org.jclouds.compute.domain.Architecture;
|
||||
import org.jclouds.compute.domain.Image;
|
||||
import org.jclouds.compute.domain.OperatingSystem;
|
||||
import org.jclouds.compute.domain.Size;
|
||||
import org.jclouds.compute.domain.internal.ImageImpl;
|
||||
import org.jclouds.compute.domain.internal.SizeImpl;
|
||||
import org.jclouds.compute.internal.ComputeServiceContextImpl;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.rest.RestContext;
|
||||
import org.jclouds.vcloud.VCloudClient;
|
||||
import org.jclouds.vcloud.VCloudMediaType;
|
||||
import org.jclouds.vcloud.domain.Catalog;
|
||||
import org.jclouds.vcloud.domain.CatalogItem;
|
||||
import org.jclouds.vcloud.domain.NamedResource;
|
||||
import org.jclouds.vcloud.domain.VAppTemplate;
|
||||
import org.jclouds.vcloud.terremark.TerremarkVCloudAsyncClient;
|
||||
import org.jclouds.vcloud.compute.config.VCloudComputeServiceContextModule;
|
||||
import org.jclouds.vcloud.terremark.TerremarkVCloudClient;
|
||||
import org.jclouds.vcloud.terremark.compute.TerremarkVCloudComputeService;
|
||||
import org.jclouds.vcloud.terremark.compute.TerremarkVCloudTemplate;
|
||||
import org.jclouds.vcloud.terremark.config.TerremarkVCloudContextModule;
|
||||
import org.jclouds.vcloud.terremark.domain.ComputeOptions;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.inject.Provides;
|
||||
import com.google.inject.Injector;
|
||||
|
||||
/**
|
||||
* Configures the {@link TerremarkVCloudComputeServiceContext}; requires
|
||||
|
@ -62,98 +45,37 @@ import com.google.inject.Provides;
|
|||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class TerremarkVCloudComputeServiceContextModule extends TerremarkVCloudContextModule {
|
||||
public class TerremarkVCloudComputeServiceContextModule extends VCloudComputeServiceContextModule {
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
super.configure();
|
||||
bind(ComputeService.class).to(TerremarkVCloudComputeService.class).asEagerSingleton();
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
ComputeServiceContext provideContext(ComputeService computeService,
|
||||
RestContext<TerremarkVCloudAsyncClient, TerremarkVCloudClient> context) {
|
||||
return new ComputeServiceContextImpl<TerremarkVCloudAsyncClient, TerremarkVCloudClient>(
|
||||
computeService, context);
|
||||
@Override
|
||||
protected ComputeService provideComputeService(Injector injector) {
|
||||
return injector.getInstance(TerremarkVCloudComputeService.class);
|
||||
}
|
||||
|
||||
private static final ComputeOptionsToSize sizeConverter = new ComputeOptionsToSize();
|
||||
|
||||
private static class ComputeOptionsToSize implements Function<ComputeOptions, Size> {
|
||||
|
||||
@Override
|
||||
public Size apply(ComputeOptions from) {
|
||||
return new SizeImpl(from.getProcessorCount(), (int) from.getMemory(), null, ImmutableSet
|
||||
return new SizeImpl(from.getProcessorCount(), from.getMemory(), 10, ImmutableSet
|
||||
.<Architecture> of(Architecture.X86_32, Architecture.X86_64));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class LogHolder {
|
||||
@Resource
|
||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||
protected Logger logger = Logger.NULL;
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
Set<? extends Image> provideImages(VCloudClient client, LogHolder holder) {
|
||||
Set<Image> images = Sets.newLinkedHashSet();
|
||||
holder.logger.debug(">> providing images");
|
||||
Catalog response = client.getDefaultCatalog();
|
||||
String vDC = client.getDefaultVDC().getId();
|
||||
for (NamedResource resource : response.values()) {
|
||||
if (resource.getType().equals(VCloudMediaType.CATALOGITEM_XML)) {
|
||||
|
||||
CatalogItem item = client.getCatalogItem(resource.getId());
|
||||
OperatingSystem myOs = OperatingSystem.UNKNOWN;
|
||||
for (OperatingSystem os : OperatingSystem.values()) {
|
||||
if (resource.getName().toUpperCase().replaceAll("\\s", "").indexOf(os.toString()) != -1) {
|
||||
myOs = os;
|
||||
}
|
||||
}
|
||||
Architecture arch = resource.getName().matches("64[- ]bit") ? Architecture.X86_32
|
||||
: Architecture.X86_64;
|
||||
if (item.getEntity().getType().equals(VCloudMediaType.VAPPTEMPLATE_XML)) {
|
||||
VAppTemplate template = client.getVAppTemplate(item.getEntity().getId());
|
||||
images.add(new ImageImpl(resource.getId(), template.getDescription(), myOs, null,
|
||||
vDC, arch));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
holder.logger.debug("<< images(%d)", images.size());
|
||||
return images;
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
Set<? extends Size> provideSizes(TerremarkVCloudClient client, Set<? extends Image> images,
|
||||
LogHolder holder) {
|
||||
@Override
|
||||
protected SortedSet<? extends Size> provideSizes(VCloudClient client,
|
||||
Set<? extends Image> images, LogHolder holder, ExecutorService executor) {
|
||||
Image anyImage = Iterables.get(images, 0);
|
||||
holder.logger.debug(">> providing sizes");
|
||||
LinkedHashSet<Size> sizes = Sets.newLinkedHashSet(Iterables.transform(client
|
||||
.getComputeOptionsOfCatalogItem(anyImage.getId()), sizeConverter));
|
||||
SortedSet<Size> sizes = Sets.newTreeSet(Iterables.transform(TerremarkVCloudClient.class.cast(
|
||||
client).getComputeOptionsOfCatalogItem(anyImage.getId()), sizeConverter));
|
||||
holder.logger.debug("<< sizes(%d)", sizes.size());
|
||||
return sizes;
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
Set<TerremarkVCloudTemplate> provideTemplates(TerremarkVCloudClient client,
|
||||
Set<? extends Image> images, Set<? extends Size> sizes, LogHolder holder) {
|
||||
Set<TerremarkVCloudTemplate> templates = Sets.newHashSet();
|
||||
holder.logger.debug(">> generating templates");
|
||||
String vDC = client.getDefaultVDC().getId();
|
||||
for (Size size : sizes) {
|
||||
for (Image image : images) {
|
||||
templates.add(new TerremarkVCloudTemplate(client, images, sizes, vDC, size, image
|
||||
.getOperatingSystem(), image));
|
||||
}
|
||||
}
|
||||
holder.logger.debug("<< templates(%d)", templates.size());
|
||||
return templates;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -29,10 +29,10 @@ package org.jclouds.vcloud.terremark.domain;
|
|||
*/
|
||||
public class ComputeOptions implements Comparable<ComputeOptions> {
|
||||
private final int processorCount;
|
||||
private final long memory;
|
||||
private final int memory;
|
||||
private final float costPerHour;
|
||||
|
||||
public ComputeOptions(int processorCount, long memory, float costPerHour) {
|
||||
public ComputeOptions(int processorCount, int memory, float costPerHour) {
|
||||
this.processorCount = processorCount;
|
||||
this.memory = memory;
|
||||
this.costPerHour = costPerHour;
|
||||
|
@ -42,7 +42,7 @@ public class ComputeOptions implements Comparable<ComputeOptions> {
|
|||
return processorCount;
|
||||
}
|
||||
|
||||
public long getMemory() {
|
||||
public int getMemory() {
|
||||
return memory;
|
||||
}
|
||||
|
||||
|
|
|
@ -19,45 +19,18 @@
|
|||
|
||||
package org.jclouds.vcloud.terremark.compute;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.jclouds.compute.domain.OperatingSystem.CENTOS;
|
||||
import static org.jclouds.compute.domain.OperatingSystem.UBUNTU;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
import static org.jclouds.compute.domain.OperatingSystem.JEOS;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.jclouds.compute.ComputeService;
|
||||
import org.jclouds.compute.ComputeServiceContext;
|
||||
import org.jclouds.compute.BaseComputeServiceLiveTest;
|
||||
import org.jclouds.compute.ComputeServiceContextFactory;
|
||||
import org.jclouds.compute.domain.ComputeMetadata;
|
||||
import org.jclouds.compute.domain.ComputeType;
|
||||
import org.jclouds.compute.domain.CreateNodeResponse;
|
||||
import org.jclouds.compute.domain.LoginType;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.OperatingSystem;
|
||||
import org.jclouds.compute.domain.Size;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
|
||||
import org.jclouds.predicates.RetryablePredicate;
|
||||
import org.jclouds.predicates.SocketOpen;
|
||||
import org.jclouds.ssh.ExecResponse;
|
||||
import org.jclouds.ssh.SshClient;
|
||||
import org.jclouds.ssh.SshException;
|
||||
import org.jclouds.rest.RestContext;
|
||||
import org.jclouds.ssh.jsch.config.JschSshClientModule;
|
||||
import org.testng.annotations.AfterTest;
|
||||
import org.testng.annotations.BeforeGroups;
|
||||
import org.jclouds.vcloud.compute.VCloudComputeClient;
|
||||
import org.jclouds.vcloud.terremark.TerremarkVCloudAsyncClient;
|
||||
import org.jclouds.vcloud.terremark.TerremarkVCloudClient;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
|
||||
/**
|
||||
*
|
||||
* Generally disabled, as it incurs higher fees.
|
||||
|
@ -65,115 +38,28 @@ import com.google.inject.Injector;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "live", enabled = true, sequential = true, testName = "terremark.TerremarkVCloudComputeServiceLiveTest")
|
||||
public class TerremarkVCloudComputeServiceLiveTest {
|
||||
private static final String service = "terremark";
|
||||
private static final OperatingSystem testOS = UBUNTU;
|
||||
|
||||
protected SshClient.Factory sshFactory;
|
||||
private String nodeName = service;
|
||||
|
||||
private RetryablePredicate<InetSocketAddress> socketTester;
|
||||
private CreateNodeResponse node;
|
||||
private ComputeServiceContext context;
|
||||
private ComputeService client;
|
||||
|
||||
@BeforeGroups(groups = { "live" })
|
||||
public void setupClient() throws InterruptedException, ExecutionException, TimeoutException,
|
||||
IOException {
|
||||
String user = checkNotNull(System.getProperty("jclouds.test.user"), "jclouds.test.user");
|
||||
String password = checkNotNull(System.getProperty("jclouds.test.key"), "jclouds.test.key");
|
||||
context = new ComputeServiceContextFactory().createContext(service, user, password,
|
||||
ImmutableSet.of(new Log4JLoggingModule()), new Properties());
|
||||
Injector injector = Guice.createInjector(new JschSshClientModule());
|
||||
sshFactory = injector.getInstance(SshClient.Factory.class);
|
||||
SocketOpen socketOpen = injector.getInstance(SocketOpen.class);
|
||||
socketTester = new RetryablePredicate<InetSocketAddress>(socketOpen, 60, 1, TimeUnit.SECONDS);
|
||||
injector.injectMembers(socketOpen); // add logger
|
||||
client = context.getComputeService();
|
||||
public class TerremarkVCloudComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
||||
@BeforeClass
|
||||
@Override
|
||||
public void setServiceDefaults() {
|
||||
service = "terremark";
|
||||
testOS = JEOS;
|
||||
}
|
||||
|
||||
public void testCreate() throws Exception {
|
||||
Template template = client.createTemplateInLocation("default").os(testOS).smallest();
|
||||
node = client.runNode(nodeName, template);
|
||||
assertNotNull(node.getId());
|
||||
assertEquals(node.getLoginPort(), 22);
|
||||
assertEquals(node.getLoginType(), LoginType.SSH);
|
||||
assertNotNull(node.getName());
|
||||
assertEquals(node.getPrivateAddresses().size(), 1);
|
||||
assertEquals(node.getPublicAddresses().size(), 1);
|
||||
assertNotNull(node.getCredentials());
|
||||
assertNotNull(node.getCredentials().account);
|
||||
assertNotNull(node.getCredentials().key);
|
||||
sshPing();
|
||||
@Override
|
||||
protected JschSshClientModule getSshModule() {
|
||||
return new JschSshClientModule();
|
||||
}
|
||||
|
||||
@Test(dependsOnMethods = "testCreate")
|
||||
public void testGet() throws Exception {
|
||||
NodeMetadata metadata = client.getNodeMetadata(node);
|
||||
assertEquals(metadata.getId(), node.getId());
|
||||
assertEquals(metadata.getLoginPort(), node.getLoginPort());
|
||||
assertEquals(metadata.getLoginType(), node.getLoginType());
|
||||
assertEquals(metadata.getName(), node.getName());
|
||||
assertEquals(metadata.getPrivateAddresses(), node.getPrivateAddresses());
|
||||
assertEquals(metadata.getPublicAddresses(), node.getPublicAddresses());
|
||||
}
|
||||
|
||||
public void testList() throws Exception {
|
||||
for (ComputeMetadata node : client.listNodes()) {
|
||||
assert node.getId() != null;
|
||||
assert node.getLocation() != null;
|
||||
assertEquals(node.getType(), ComputeType.NODE);
|
||||
}
|
||||
}
|
||||
|
||||
public void testListTemplates() throws Exception {
|
||||
for (Template template : client.listTemplates()) {
|
||||
assert template.getImage() != null;
|
||||
System.out.println(template);
|
||||
}
|
||||
}
|
||||
|
||||
public void testListSizes() throws Exception {
|
||||
for (Size size : client.listSizes()) {
|
||||
assert size.getCores() != null;
|
||||
System.out.println(size);
|
||||
}
|
||||
}
|
||||
|
||||
private void sshPing() throws IOException {
|
||||
try {
|
||||
doCheckKey();
|
||||
} catch (SshException e) {// try twice in case there is a network timeout
|
||||
try {
|
||||
Thread.sleep(10 * 1000);
|
||||
} catch (InterruptedException e1) {
|
||||
}
|
||||
doCheckKey();
|
||||
}
|
||||
}
|
||||
|
||||
private void doCheckKey() throws IOException {
|
||||
InetSocketAddress socket = new InetSocketAddress(node.getPublicAddresses().last(), node
|
||||
.getLoginPort());
|
||||
socketTester.apply(socket);
|
||||
SshClient ssh = node.getCredentials().key.startsWith("-----BEGIN RSA PRIVATE KEY-----") ? sshFactory
|
||||
.create(socket, node.getCredentials().account, node.getCredentials().key.getBytes())
|
||||
: sshFactory
|
||||
.create(socket, node.getCredentials().account, node.getCredentials().key);
|
||||
try {
|
||||
ssh.connect();
|
||||
ExecResponse hello = ssh.exec("echo hello");
|
||||
assertEquals(hello.getOutput().trim(), "hello");
|
||||
} finally {
|
||||
if (ssh != null)
|
||||
ssh.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
@AfterTest
|
||||
void cleanup() throws InterruptedException, ExecutionException, TimeoutException {
|
||||
if (node != null)
|
||||
client.destroyNode(node);
|
||||
context.close();
|
||||
public void testAssignability() throws Exception {
|
||||
@SuppressWarnings("unused")
|
||||
RestContext<TerremarkVCloudAsyncClient, TerremarkVCloudClient> tmContext = new ComputeServiceContextFactory()
|
||||
.createContext(service, user, password).getProviderSpecificContext();
|
||||
|
||||
TerremarkVCloudComputeService computeService = TerremarkVCloudComputeService.class
|
||||
.cast(client);
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
VCloudComputeClient computeClient = VCloudComputeClient.class.cast(computeService);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue