mirror of https://github.com/apache/jclouds.git
Issue 130: properly modeled node and templates
git-svn-id: http://jclouds.googlecode.com/svn/trunk@2702 3d8758e0-26b5-11de-8745-db77d3ebf521
This commit is contained in:
parent
2c373ed68e
commit
2e213ae223
|
@ -24,7 +24,6 @@ import static org.jclouds.aws.ec2.options.RunInstancesOptions.Builder.withKeyNam
|
|||
import static org.jclouds.scriptbuilder.domain.Statements.exec;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Set;
|
||||
|
@ -32,26 +31,26 @@ import java.util.Set;
|
|||
import javax.annotation.Resource;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Provider;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.aws.AWSResponseException;
|
||||
import org.jclouds.aws.domain.Region;
|
||||
import org.jclouds.aws.ec2.EC2Client;
|
||||
import org.jclouds.aws.ec2.domain.InstanceState;
|
||||
import org.jclouds.aws.ec2.domain.InstanceType;
|
||||
import org.jclouds.aws.ec2.domain.IpProtocol;
|
||||
import org.jclouds.aws.ec2.domain.KeyPair;
|
||||
import org.jclouds.aws.ec2.domain.RunningInstance;
|
||||
import org.jclouds.compute.ComputeService;
|
||||
import org.jclouds.compute.domain.Architecture;
|
||||
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.Profile;
|
||||
import org.jclouds.compute.domain.Size;
|
||||
import org.jclouds.compute.domain.OperatingSystem;
|
||||
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;
|
||||
|
@ -62,7 +61,6 @@ import org.jclouds.scriptbuilder.ScriptBuilder;
|
|||
import org.jclouds.scriptbuilder.domain.OsFamily;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
@ -78,67 +76,40 @@ 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 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 tmClient, Predicate<RunningInstance> instanceStateRunning,
|
||||
public EC2ComputeService(EC2Client client, Set<EC2Size> sizes,
|
||||
Provider<Set<EC2Template>> templates,
|
||||
Map<Architecture, Map<OperatingSystem, Map<Region, String>>> imageAmiIdMap,
|
||||
Predicate<RunningInstance> instanceStateRunning,
|
||||
RunningInstanceToNodeMetadata runningInstanceToNodeMetadata) {
|
||||
this.ec2Client = tmClient;
|
||||
this.ec2Client = client;
|
||||
this.sizes = sizes;
|
||||
this.templates = templates; // delayed intentionally, as generation is slow
|
||||
this.imageAmiIdMap = imageAmiIdMap;
|
||||
this.instanceStateRunning = instanceStateRunning;
|
||||
this.runningInstanceToNodeMetadata = runningInstanceToNodeMetadata;
|
||||
}
|
||||
|
||||
private Map<InstanceType, Map<Image, Map<Region, String>>> imageAmiIdMap = ImmutableMap
|
||||
.<InstanceType, Map<Image, Map<Region, String>>> of(InstanceType.M1_SMALL,//
|
||||
ImmutableMap.<Image, Map<Region, String>> builder().put(
|
||||
Image.UBUNTU_90,
|
||||
ImmutableMap.of(Region.DEFAULT, "ami-1515f67c", Region.US_EAST_1,
|
||||
"ami-1515f67c", Region.US_WEST_1, "ami-7d3c6d38",
|
||||
Region.EU_WEST_1, "ami-a62a01d2")).put(
|
||||
Image.RHEL_53,
|
||||
ImmutableMap.of(Region.DEFAULT, "ami-368b685f", Region.US_EAST_1,
|
||||
"ami-368b685f")).build(),//
|
||||
InstanceType.C1_MEDIUM,//
|
||||
ImmutableMap.<Image, Map<Region, String>> builder().put(
|
||||
Image.UBUNTU_90,
|
||||
ImmutableMap.of(Region.DEFAULT, "ami-1515f67c", Region.US_EAST_1,
|
||||
"ami-1515f67c", Region.US_WEST_1, "ami-7d3c6d38",
|
||||
Region.EU_WEST_1, "ami-a62a01d2")).put(
|
||||
Image.RHEL_53,
|
||||
ImmutableMap.of(Region.DEFAULT, "ami-368b685f", Region.US_EAST_1,
|
||||
"ami-368b685f")).build(), //
|
||||
InstanceType.C1_XLARGE,//
|
||||
ImmutableMap.<Image, Map<Region, String>> builder().put(
|
||||
Image.UBUNTU_90,
|
||||
ImmutableMap.of(Region.DEFAULT, "ami-ab15f6c2", Region.US_EAST_1,
|
||||
"ami-ab15f6c2", Region.US_WEST_1, "ami-7b3c6d3e",
|
||||
Region.EU_WEST_1, "ami-9a2a01ee")).build());// todo ami
|
||||
|
||||
private Map<Profile, InstanceType> profileInstanceTypeMap = ImmutableMap
|
||||
.<Profile, InstanceType> builder().put(Profile.SMALLEST, InstanceType.M1_SMALL).put(
|
||||
Profile.MEDIUM, InstanceType.C1_MEDIUM).put(Profile.FASTEST,
|
||||
InstanceType.C1_XLARGE).build();
|
||||
|
||||
private static Map<InstanceState, NodeState> instanceToNodeState = ImmutableMap
|
||||
.<InstanceState, NodeState> builder().put(InstanceState.PENDING, NodeState.PENDING)
|
||||
.put(InstanceState.RUNNING, NodeState.RUNNING).put(InstanceState.SHUTTING_DOWN,
|
||||
NodeState.PENDING).put(InstanceState.TERMINATED, NodeState.TERMINATED).build();
|
||||
|
||||
@Override
|
||||
public CreateNodeResponse startNodeInLocation(String location, String name, Profile profile,
|
||||
Image image) {
|
||||
Region region = Region.fromValue(location);
|
||||
public CreateNodeResponse runNode(String name, Template template) {
|
||||
checkArgument(template instanceof EC2Template,
|
||||
"unexpected template type. should be EC2Template, was: " + template.getClass());
|
||||
EC2Template ec2Template = (EC2Template) template;
|
||||
|
||||
InstanceType type = checkNotNull(profileInstanceTypeMap.get(profile),
|
||||
"profile not supported: " + profile);
|
||||
String ami = checkNotNull(checkNotNull(
|
||||
checkNotNull(imageAmiIdMap.get(type), "type not supported: " + type).get(image),
|
||||
"image not supported: " + image).get(region), "region not supported: " + region);
|
||||
|
||||
KeyPair keyPair = createKeyPairInRegion(region, name);
|
||||
KeyPair keyPair = createKeyPairInRegion(ec2Template.getRegion(), name);
|
||||
String securityGroupName = name;
|
||||
createSecurityGroupInRegion(region, securityGroupName, 22, 80, 8080, 443);
|
||||
createSecurityGroupInRegion(ec2Template.getRegion(), securityGroupName, 22, 80, 8080, 443);
|
||||
|
||||
String script = new ScriptBuilder() // update and install jdk
|
||||
.addStatement(exec("apt-get update"))//
|
||||
|
@ -149,35 +120,45 @@ public class EC2ComputeService implements ComputeService {
|
|||
.build(OsFamily.UNIX);
|
||||
|
||||
logger.debug(">> running instance region(%s) ami(%s) type(%s) keyPair(%s) securityGroup(%s)",
|
||||
region, ami, type, keyPair.getKeyName(), securityGroupName);
|
||||
ec2Template.getRegion(), ec2Template.getImage().getId(), ec2Template.getSize()
|
||||
.getInstanceType(), keyPair.getKeyName(), securityGroupName);
|
||||
|
||||
RunningInstance runningInstance = Iterables.getOnlyElement(ec2Client.getInstanceServices()
|
||||
.runInstancesInRegion(region, null, ami, 1, 1, withKeyName(keyPair.getKeyName())// key
|
||||
// I
|
||||
// created
|
||||
// above
|
||||
.asType(type)// instance size
|
||||
.withSecurityGroup(securityGroupName)// group I created above
|
||||
.withAdditionalInfo(name)// description
|
||||
.withUserData(script.getBytes()) // script to run as root
|
||||
.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
|
||||
));
|
||||
logger.debug("<< started instance(%s)", runningInstance.getId());
|
||||
instanceStateRunning.apply(runningInstance);
|
||||
logger.debug("<< running instance(%s)", runningInstance.getId());
|
||||
|
||||
// refresh to get IP address
|
||||
runningInstance = getOnlyRunningInstanceInRegion(region, runningInstance.getId());
|
||||
runningInstance = getOnlyRunningInstanceInRegion(ec2Template.getRegion(), runningInstance
|
||||
.getId());
|
||||
|
||||
Set<InetAddress> publicAddresses = runningInstance.getIpAddress() == null ? ImmutableSet
|
||||
.<InetAddress> of() : ImmutableSet.<InetAddress> of(runningInstance.getIpAddress());
|
||||
Set<InetAddress> privateAddresses = runningInstance.getPrivateIpAddress() == null ? ImmutableSet
|
||||
.<InetAddress> of()
|
||||
: ImmutableSet.<InetAddress> of(runningInstance.getPrivateIpAddress());
|
||||
return new CreateNodeResponseImpl(runningInstance.getId(), name, runningInstance.getRegion()
|
||||
.toString(), null, ImmutableMap.<String, String> of(), instanceToNodeState
|
||||
.get(runningInstance.getInstanceState()), publicAddresses, privateAddresses, 22,
|
||||
LoginType.SSH, new Credentials(image == Image.UBUNTU_90 ? "ubuntu" : "root", keyPair
|
||||
.getKeyMaterial()), ImmutableMap.<String, String> of());
|
||||
return new CreateNodeResponseImpl(
|
||||
runningInstance.getId(),
|
||||
name,
|
||||
runningInstance.getRegion().toString(),
|
||||
null,
|
||||
ImmutableMap.<String, String> of(),
|
||||
instanceToNodeState.get(runningInstance.getInstanceState()),
|
||||
publicAddresses,
|
||||
privateAddresses,
|
||||
22,
|
||||
LoginType.SSH,
|
||||
new Credentials(
|
||||
ec2Template.getImage().getOperatingSystem() == OperatingSystem.UBUNTU ? "ubuntu"
|
||||
: "root", keyPair.getKeyMaterial()), ImmutableMap
|
||||
.<String, String> of());
|
||||
}
|
||||
|
||||
private KeyPair createKeyPairInRegion(Region region, String name) {
|
||||
|
@ -205,13 +186,13 @@ public class EC2ComputeService implements ComputeService {
|
|||
try {
|
||||
ec2Client.getSecurityGroupServices().createSecurityGroupInRegion(region, name, name);
|
||||
logger.debug("<< created securityGroup(%s)", name);
|
||||
logger.debug(">> authorizing securityGroup region(%s) name(%s) ports(%s)", region, name,
|
||||
Joiner.on(',').join(Arrays.asList(ports)));
|
||||
for (int port : ports) {
|
||||
logger.debug(">> authorizing securityGroup region(%s) name(%s) port(%s)", region, name,
|
||||
port);
|
||||
ec2Client.getSecurityGroupServices().authorizeSecurityGroupIngressInRegion(region,
|
||||
name, IpProtocol.TCP, port, port, "0.0.0.0/0");
|
||||
logger.debug("<< authorized securityGroup(%s)", name);
|
||||
}
|
||||
logger.debug("<< authorized securityGroup(%s)", name);
|
||||
} catch (AWSResponseException e) {
|
||||
if (e.getError().getCode().equals("InvalidGroup.Duplicate")) {
|
||||
logger.debug("<< reused securityGroup(%s)", name);
|
||||
|
@ -335,7 +316,17 @@ public class EC2ComputeService implements ComputeService {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Size> getSizes() {
|
||||
throw new UnsupportedOperationException();
|
||||
public Set<EC2Size> listSizes() {
|
||||
return sizes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<EC2Template> listTemplates() {
|
||||
return templates.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Template createTemplateInLocation(String location) {
|
||||
return new EC2Template(ec2Client, imageAmiIdMap, location);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
/**
|
||||
*
|
||||
* 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.aws.ec2.compute;
|
||||
|
||||
import org.jclouds.aws.ec2.domain.InstanceType;
|
||||
import org.jclouds.compute.domain.Architecture;
|
||||
import org.jclouds.compute.domain.internal.SizeImpl;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class EC2Size extends SizeImpl {
|
||||
private final InstanceType instanceType;
|
||||
|
||||
EC2Size(InstanceType instanceType, Integer cores, Integer ram, Integer disk,
|
||||
Iterable<Architecture> supportedArchitectures) {
|
||||
super(cores, ram, disk, supportedArchitectures);
|
||||
this.instanceType = instanceType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the EC2 InstanceType associated with this size.
|
||||
*/
|
||||
public InstanceType getInstanceType() {
|
||||
return instanceType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see InstanceType#M1_SMALL
|
||||
*/
|
||||
public static final EC2Size M1_SMALL = new EC2Size(InstanceType.M1_SMALL, 1, 1740, 160,
|
||||
ImmutableSet.of(Architecture.X86_32));
|
||||
/**
|
||||
* @see InstanceType#M1_LARGE
|
||||
*/
|
||||
public static final EC2Size M1_LARGE = new EC2Size(InstanceType.M1_LARGE, 4, 7680, 850,
|
||||
ImmutableSet.of(Architecture.X86_64));
|
||||
/**
|
||||
* @see InstanceType#M1_XLARGE
|
||||
*/
|
||||
public static final EC2Size M1_XLARGE = new EC2Size(InstanceType.M1_XLARGE, 8, 15360, 1690,
|
||||
ImmutableSet.of(Architecture.X86_64));
|
||||
/**
|
||||
* @see InstanceType#M2_2XLARGE
|
||||
*/
|
||||
public static final EC2Size M2_2XLARGE = new EC2Size(InstanceType.M2_2XLARGE, 13, 35020, 850,
|
||||
ImmutableSet.of(Architecture.X86_64));
|
||||
/**
|
||||
* @see InstanceType#M2_4XLARGE
|
||||
*/
|
||||
public static final EC2Size M2_4XLARGE = new EC2Size(InstanceType.M2_4XLARGE, 26, 70041, 1690,
|
||||
ImmutableSet.of(Architecture.X86_64));
|
||||
/**
|
||||
* @see InstanceType#C1_MEDIUM
|
||||
*/
|
||||
public static final EC2Size C1_MEDIUM = new EC2Size(InstanceType.C1_MEDIUM, 5, 1740, 350,
|
||||
ImmutableSet.of(Architecture.X86_32));
|
||||
/**
|
||||
* @see InstanceType#C1_XLARGE
|
||||
*/
|
||||
public static final EC2Size C1_XLARGE = new EC2Size(InstanceType.C1_XLARGE, 20, 7168, 1690,
|
||||
ImmutableSet.of(Architecture.X86_64));
|
||||
|
||||
}
|
|
@ -0,0 +1,233 @@
|
|||
/**
|
||||
*
|
||||
* 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.aws.ec2.compute;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.jclouds.aws.domain.Region;
|
||||
import org.jclouds.aws.ec2.EC2Client;
|
||||
import org.jclouds.aws.ec2.util.EC2Utils;
|
||||
import org.jclouds.compute.domain.Architecture;
|
||||
import org.jclouds.compute.domain.Image;
|
||||
import org.jclouds.compute.domain.OperatingSystem;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class EC2Template implements Template {
|
||||
private final EC2Client client;
|
||||
private final Map<Architecture, Map<OperatingSystem, Map<Region, String>>> imageAmiIdMap;
|
||||
private EC2Size size;
|
||||
private OperatingSystem operatingSystem;
|
||||
private Region region;
|
||||
private transient Image image;
|
||||
|
||||
public EC2Template(EC2Client client,
|
||||
Map<Architecture, Map<OperatingSystem, Map<Region, String>>> imageAmiIdMap,
|
||||
EC2Size size, OperatingSystem operatingSystem, Region region, @Nullable Image image) {
|
||||
this.client = client;
|
||||
this.size = size;
|
||||
this.operatingSystem = operatingSystem;
|
||||
this.region = region;
|
||||
this.imageAmiIdMap = imageAmiIdMap;
|
||||
this.image = image != null ? image : resolveImage();
|
||||
}
|
||||
|
||||
EC2Template(EC2Client client,
|
||||
Map<Architecture, Map<OperatingSystem, Map<Region, String>>> imageAmiIdMap,
|
||||
String location) {
|
||||
this(client, imageAmiIdMap, EC2Size.M1_SMALL, OperatingSystem.UBUNTU, Region
|
||||
.fromValue(location), null);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public EC2Size getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Image getImage() {
|
||||
return image;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
Image resolveImage() {
|
||||
Architecture architecture = size.supportsArchitecture(Architecture.X86_64) ? Architecture.X86_64
|
||||
: Architecture.X86_32;
|
||||
String ami = checkNotNull(
|
||||
checkNotNull(
|
||||
checkNotNull(
|
||||
imageAmiIdMap.get(architecture),
|
||||
String.format(
|
||||
"architecture %s not supported. Valid choices %s: ",
|
||||
architecture, imageAmiIdMap.keySet())).get(
|
||||
operatingSystem),
|
||||
String
|
||||
.format(
|
||||
"operatingSystem %s not supported for architecture %s. Valid choices %s: ",
|
||||
operatingSystem, architecture, imageAmiIdMap.get(
|
||||
architecture).keySet())).get(region),
|
||||
String
|
||||
.format(
|
||||
"region %s not supported for operatingSystem %s, architecture %s. Valid choices %s: ",
|
||||
region, operatingSystem, architecture, imageAmiIdMap.get(
|
||||
architecture).get(operatingSystem).keySet()));
|
||||
return EC2Utils.newImage(client, region, operatingSystem, architecture, ami);
|
||||
}
|
||||
|
||||
public Template asSize(EC2Size size) {
|
||||
this.size = size;
|
||||
this.image = resolveImage();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Template smallest() {
|
||||
return asSize(EC2Size.M1_SMALL);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Template biggest() {
|
||||
return asSize(EC2Size.M2_4XLARGE);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Template fastest() {
|
||||
return asSize(EC2Size.C1_XLARGE);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Template inLocation(String location) {
|
||||
this.region = Region.fromValue(location);
|
||||
this.image = resolveImage();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Template os(OperatingSystem os) {
|
||||
this.operatingSystem = os;
|
||||
this.image = resolveImage();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@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 + ((region == null) ? 0 : region.hashCode());
|
||||
result = prime * result + ((size == null) ? 0 : size.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
EC2Template other = (EC2Template) 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 (region == null) {
|
||||
if (other.region != null)
|
||||
return false;
|
||||
} else if (!region.equals(other.region))
|
||||
return false;
|
||||
if (size == null) {
|
||||
if (other.size != null)
|
||||
return false;
|
||||
} else if (!size.equals(other.size))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return "EC2Template [image=" + image + ", operatingSystem=" + operatingSystem + ", region="
|
||||
+ region + ", size=" + size + "]";
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected Object clone() throws CloneNotSupportedException {
|
||||
return new EC2Template(client, imageAmiIdMap, size, operatingSystem, region, image);
|
||||
}
|
||||
|
||||
public Region getRegion() {
|
||||
return region;
|
||||
}
|
||||
|
||||
}
|
|
@ -18,17 +18,33 @@
|
|||
*/
|
||||
package org.jclouds.aws.ec2.compute.config;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.aws.domain.Region;
|
||||
import org.jclouds.aws.ec2.EC2AsyncClient;
|
||||
import org.jclouds.aws.ec2.EC2Client;
|
||||
import org.jclouds.aws.ec2.compute.EC2ComputeService;
|
||||
import org.jclouds.aws.ec2.compute.EC2Size;
|
||||
import org.jclouds.aws.ec2.compute.EC2Template;
|
||||
import org.jclouds.aws.ec2.config.EC2ContextModule;
|
||||
import org.jclouds.aws.ec2.util.EC2Utils;
|
||||
import org.jclouds.compute.ComputeService;
|
||||
import org.jclouds.compute.ComputeServiceContext;
|
||||
import org.jclouds.compute.domain.Architecture;
|
||||
import org.jclouds.compute.domain.OperatingSystem;
|
||||
import org.jclouds.compute.internal.ComputeServiceContextImpl;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
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.Sets;
|
||||
import com.google.inject.Provides;
|
||||
|
||||
/**
|
||||
|
@ -51,4 +67,63 @@ public class EC2ComputeServiceContextModule extends EC2ContextModule {
|
|||
return new ComputeServiceContextImpl<EC2AsyncClient, EC2Client>(computeService, context);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
Set<EC2Size> provideSizes() {
|
||||
return ImmutableSet.<EC2Size> of(EC2Size.C1_MEDIUM, EC2Size.C1_XLARGE, EC2Size.M1_LARGE,
|
||||
EC2Size.M1_SMALL, EC2Size.M1_XLARGE, EC2Size.M2_2XLARGE, EC2Size.M2_4XLARGE);
|
||||
}
|
||||
|
||||
private static class LogHolder {
|
||||
@Resource
|
||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||
protected Logger logger = Logger.NULL;
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
Set<EC2Template> provideTemplates(EC2Client client, Set<EC2Size> sizes,
|
||||
Map<Architecture, Map<OperatingSystem, Map<Region, String>>> imageAmiIdMap,
|
||||
LogHolder holder) {
|
||||
Set<EC2Template> templates = Sets.newHashSet();
|
||||
holder.logger.debug(">> generating templates");
|
||||
for (EC2Size size : sizes) {
|
||||
for (Architecture architecture : imageAmiIdMap.keySet()) {
|
||||
if (size.supportsArchitecture(architecture)) {
|
||||
for (OperatingSystem operatingSystem : imageAmiIdMap.get(architecture).keySet()) {
|
||||
for (Region region : imageAmiIdMap.get(architecture).get(operatingSystem)
|
||||
.keySet()) {
|
||||
String ami = imageAmiIdMap.get(architecture).get(operatingSystem).get(region);
|
||||
templates.add(new EC2Template(client, imageAmiIdMap, size, operatingSystem,
|
||||
region, EC2Utils.newImage(client, region, operatingSystem,
|
||||
architecture, ami)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
holder.logger.debug("<< templates(%d)", templates.size());
|
||||
return templates;
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
Map<Architecture, Map<OperatingSystem, Map<Region, String>>> provideimageAmiIdMap() {
|
||||
return ImmutableMap.<Architecture, Map<OperatingSystem, Map<Region, String>>> of(
|
||||
Architecture.X86_32,//
|
||||
ImmutableMap.<OperatingSystem, Map<Region, String>> builder().put(
|
||||
OperatingSystem.UBUNTU,
|
||||
ImmutableMap.of(Region.DEFAULT, "ami-1515f67c", Region.US_EAST_1,
|
||||
"ami-1515f67c", Region.US_WEST_1, "ami-7d3c6d38",
|
||||
Region.EU_WEST_1, "ami-a62a01d2")).put(
|
||||
OperatingSystem.RHEL,
|
||||
ImmutableMap.of(Region.DEFAULT, "ami-368b685f", Region.US_EAST_1,
|
||||
"ami-368b685f")).build(),//
|
||||
Architecture.X86_64,//
|
||||
ImmutableMap.<OperatingSystem, Map<Region, String>> builder().put(
|
||||
OperatingSystem.UBUNTU,
|
||||
ImmutableMap.of(Region.DEFAULT, "ami-ab15f6c2", Region.US_EAST_1,
|
||||
"ami-ab15f6c2", Region.US_WEST_1, "ami-7b3c6d3e",
|
||||
Region.EU_WEST_1, "ami-9a2a01ee")).build());// todo ami
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,16 +20,31 @@ package org.jclouds.aws.ec2.util;
|
|||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.jclouds.aws.ec2.options.DescribeImagesOptions.Builder.imageIds;
|
||||
|
||||
import org.jclouds.aws.domain.Region;
|
||||
import org.jclouds.aws.ec2.EC2Client;
|
||||
import org.jclouds.aws.ec2.domain.AvailabilityZone;
|
||||
import org.jclouds.compute.domain.Architecture;
|
||||
import org.jclouds.compute.domain.Image;
|
||||
import org.jclouds.compute.domain.OperatingSystem;
|
||||
import org.jclouds.compute.domain.internal.ImageImpl;
|
||||
import org.jclouds.rest.internal.GeneratedHttpRequest;
|
||||
|
||||
import com.google.inject.internal.Iterables;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class EC2Utils {
|
||||
public static Image newImage(EC2Client client, Region region, OperatingSystem os,
|
||||
Architecture architecture, String ami) {
|
||||
org.jclouds.aws.ec2.domain.Image image = Iterables.getOnlyElement(client.getAMIServices()
|
||||
.describeImagesInRegion(region, imageIds(ami)));
|
||||
return new ImageImpl(ami, image.getDescription(), os, null, region.toString(), architecture);
|
||||
}
|
||||
|
||||
public static void indexStringArrayToFormValuesWithPrefix(GeneratedHttpRequest<?> request,
|
||||
String prefix, Object input) {
|
||||
checkArgument(checkNotNull(input, "input") instanceof String[],
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
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;
|
||||
|
||||
|
@ -29,15 +30,16 @@ 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.Image;
|
||||
import org.jclouds.compute.domain.LoginType;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.Profile;
|
||||
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;
|
||||
|
@ -61,31 +63,34 @@ import com.google.inject.Injector;
|
|||
*/
|
||||
@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 nodePrefix = System.getProperty("user.name") + ".ec2serv";
|
||||
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("ec2", user, password,
|
||||
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 void testCreate() throws Exception {
|
||||
node = context.getComputeService().startNodeInLocation("default", nodePrefix,
|
||||
Profile.SMALLEST, Image.UBUNTU_90);
|
||||
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);
|
||||
|
@ -100,7 +105,7 @@ public class EC2ComputeServiceLiveTest {
|
|||
|
||||
@Test(dependsOnMethods = "testCreate")
|
||||
public void testGet() throws Exception {
|
||||
NodeMetadata metadata = context.getComputeService().getNodeMetadata(node);
|
||||
NodeMetadata metadata = client.getNodeMetadata(node);
|
||||
assertEquals(metadata.getId(), node.getId());
|
||||
assertEquals(metadata.getLoginPort(), node.getLoginPort());
|
||||
assertEquals(metadata.getLoginType(), node.getLoginType());
|
||||
|
@ -110,13 +115,27 @@ public class EC2ComputeServiceLiveTest {
|
|||
}
|
||||
|
||||
public void testList() throws Exception {
|
||||
for (ComputeMetadata node : context.getComputeService().listNodes()) {
|
||||
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();
|
||||
|
@ -150,7 +169,7 @@ public class EC2ComputeServiceLiveTest {
|
|||
@AfterTest
|
||||
void cleanup() throws InterruptedException, ExecutionException, TimeoutException {
|
||||
if (node != null)
|
||||
context.getComputeService().destroyNode(node);
|
||||
client.destroyNode(node);
|
||||
context.close();
|
||||
}
|
||||
|
||||
|
|
|
@ -46,6 +46,32 @@
|
|||
</layout>
|
||||
</appender>
|
||||
|
||||
<!-- A time/date based rolling appender -->
|
||||
<appender name="COMPUTEFILE" class="org.apache.log4j.DailyRollingFileAppender">
|
||||
<param name="File" value="target/test-data/jclouds-compute.log" />
|
||||
<param name="Append" value="true" />
|
||||
|
||||
<!-- Rollover at midnight each day -->
|
||||
<param name="DatePattern" value="'.'yyyy-MM-dd" />
|
||||
|
||||
<param name="Threshold" value="TRACE" />
|
||||
|
||||
<layout class="org.apache.log4j.PatternLayout">
|
||||
<!-- The default pattern: Date Priority [Category] Message\n -->
|
||||
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
|
||||
|
||||
<!--
|
||||
The full pattern: Date MS Priority [Category] (Thread:NDC) Message\n
|
||||
<param name="ConversionPattern" value="%d %-5r %-5p [%c] (%t:%x)
|
||||
%m%n"/>
|
||||
-->
|
||||
</layout>
|
||||
</appender>
|
||||
|
||||
<appender name="ASYNCCOMPUTE" class="org.apache.log4j.AsyncAppender">
|
||||
<appender-ref ref="COMPUTEFILE" />
|
||||
</appender>
|
||||
|
||||
<appender name="ASYNC" class="org.apache.log4j.AsyncAppender">
|
||||
<appender-ref ref="FILE" />
|
||||
</appender>
|
||||
|
@ -72,6 +98,12 @@
|
|||
<priority value="DEBUG" />
|
||||
<appender-ref ref="ASYNCWIRE" />
|
||||
</category>
|
||||
|
||||
<category name="jclouds.compute">
|
||||
<priority value="TRACE" />
|
||||
<appender-ref ref="ASYNCCOMPUTE" />
|
||||
</category>
|
||||
|
||||
<!--======================= -->
|
||||
<!-- Setup the Root category -->
|
||||
<!-- ======================= -->
|
||||
|
|
|
@ -18,15 +18,13 @@
|
|||
*/
|
||||
package org.jclouds.compute;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jclouds.compute.domain.ComputeMetadata;
|
||||
import org.jclouds.compute.domain.CreateNodeResponse;
|
||||
import org.jclouds.compute.domain.Image;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.Profile;
|
||||
import org.jclouds.compute.domain.Size;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
|
||||
/**
|
||||
* Provides portable access to launching compute instances.
|
||||
|
@ -35,23 +33,34 @@ import org.jclouds.compute.domain.Size;
|
|||
* @author Ivan Meredith
|
||||
*/
|
||||
public interface ComputeService {
|
||||
/**
|
||||
* Creates a new template in the specified location.
|
||||
*
|
||||
* @param location
|
||||
* where the template is valid for
|
||||
*/
|
||||
Template createTemplateInLocation(String location);
|
||||
|
||||
/**
|
||||
* List all sizes available to the current user
|
||||
*/
|
||||
Map<String, Size> getSizes();
|
||||
Set<? extends Size> listSizes();
|
||||
|
||||
/**
|
||||
* List all templates available to the current user
|
||||
*/
|
||||
Set<? extends Template> listTemplates();
|
||||
|
||||
/**
|
||||
* List all nodes available to the current user
|
||||
*/
|
||||
Set<ComputeMetadata> listNodes();
|
||||
|
||||
Set<? extends ComputeMetadata> listNodes();
|
||||
|
||||
/**
|
||||
* Create a new node given the name, size, and Image
|
||||
* Create a new node given the name, and template
|
||||
*
|
||||
*/
|
||||
CreateNodeResponse startNodeInLocation(String location, String name, Profile size, Image image);
|
||||
CreateNodeResponse runNode(String name, Template template);
|
||||
|
||||
/**
|
||||
* destroy the node.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
@ -23,29 +23,19 @@
|
|||
*/
|
||||
package org.jclouds.compute.domain;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Configured operating system used to start nodes.
|
||||
* Architecture of a node
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public interface Image {
|
||||
/**
|
||||
* Unique ID provided by the provider (ami-abcd1234, etc)
|
||||
*
|
||||
*/
|
||||
String getId();
|
||||
public enum Architecture {
|
||||
|
||||
/**
|
||||
* Name provided by the provider (Ubuntu 8.1)
|
||||
*
|
||||
* 32-bit platform
|
||||
*/
|
||||
String getName();
|
||||
|
||||
X86_32,
|
||||
/**
|
||||
* Other variables present that the provider supports
|
||||
* 64-bit platform
|
||||
*/
|
||||
Map<String, String> getExtra();
|
||||
|
||||
X86_64;
|
||||
}
|
|
@ -1,26 +1,63 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.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
|
||||
* 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
|
||||
* 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.
|
||||
* 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.domain;
|
||||
|
||||
/**
|
||||
* Running Operating system
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public enum Image {
|
||||
CENTOS_53, RHEL_53, UBUNTU_90, UBUNTU_JEOS_90, WEBAPPVM_93
|
||||
public interface Image {
|
||||
|
||||
/**
|
||||
* Unique ID provided by the provider (ami-abcd1234, etc)
|
||||
*
|
||||
*/
|
||||
String getId();
|
||||
|
||||
/**
|
||||
* Description of the image
|
||||
*/
|
||||
String getDescription();
|
||||
|
||||
/**
|
||||
* Operating System
|
||||
*/
|
||||
OperatingSystem getOperatingSystem();
|
||||
|
||||
/**
|
||||
* Version of the image
|
||||
*/
|
||||
String getVersion();
|
||||
|
||||
/**
|
||||
* Geographic location of the image.
|
||||
*/
|
||||
String getLocation();
|
||||
|
||||
/**
|
||||
* Operating System
|
||||
*/
|
||||
Architecture getArchitecture();
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
|
@ -24,10 +24,11 @@
|
|||
package org.jclouds.compute.domain;
|
||||
|
||||
/**
|
||||
* Running Operating system
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public interface Profile {
|
||||
Image getImage();
|
||||
public enum OperatingSystem {
|
||||
|
||||
Size getSize();
|
||||
CENTOS, RHEL, UBUNTU, WINDOWS, UNKNOWN;
|
||||
}
|
|
@ -1,40 +1,34 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.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
|
||||
* 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
|
||||
* 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.
|
||||
* 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.domain;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Configured operating system used to start nodes.
|
||||
* Size of a node.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public interface Size {
|
||||
/**
|
||||
* provider-specific identifier (m1.small, etc)
|
||||
*/
|
||||
String getId();
|
||||
|
||||
/**
|
||||
* Name provided by the provider (Small CPU, etc)
|
||||
*/
|
||||
String getName();
|
||||
public interface Size extends Comparable<Size> {
|
||||
|
||||
/**
|
||||
* Amount of virtual or physical cores provided
|
||||
|
@ -44,26 +38,15 @@ public interface Size {
|
|||
/**
|
||||
* Amount of RAM provided in MB (256M, 1740)
|
||||
*/
|
||||
Long getRam();
|
||||
Integer getRam();
|
||||
|
||||
/**
|
||||
* Amount of boot disk provided in GB (200)
|
||||
*/
|
||||
Long getDisk();
|
||||
Integer getDisk();
|
||||
|
||||
/**
|
||||
* Amount of total transfer bandwidth in GB
|
||||
* Determines platforms this can support
|
||||
*/
|
||||
Long getBandwidth();
|
||||
|
||||
/**
|
||||
* Hourly price of this server in USD, estimated if monthly.
|
||||
*/
|
||||
Float getPrice();
|
||||
|
||||
/**
|
||||
* Other variables present that the provider supports
|
||||
*/
|
||||
Map<String, String> getExtra();
|
||||
|
||||
boolean supportsArchitecture(Architecture architecture);
|
||||
}
|
|
@ -19,8 +19,46 @@
|
|||
package org.jclouds.compute.domain;
|
||||
|
||||
/**
|
||||
* Configured operating system used to start nodes.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public enum Profile {
|
||||
SMALLEST, MEDIUM, FASTEST
|
||||
public interface Template extends Cloneable {
|
||||
|
||||
/**
|
||||
* configure this template to the smallest size.
|
||||
*/
|
||||
Template smallest();
|
||||
|
||||
/**
|
||||
* configure this template to the fastest size.
|
||||
*/
|
||||
Template fastest();
|
||||
|
||||
/**
|
||||
* configure this template to the largest size.
|
||||
*/
|
||||
Template biggest();
|
||||
|
||||
/**
|
||||
* Configure this template to use a specific operating system image.
|
||||
*/
|
||||
Template os(OperatingSystem os);
|
||||
|
||||
/**
|
||||
* Configure this template to start in a specific location
|
||||
*/
|
||||
Template inLocation(String location);
|
||||
|
||||
/**
|
||||
* Image that suits the requirements.
|
||||
*
|
||||
*/
|
||||
Image getImage();
|
||||
|
||||
/**
|
||||
* Size that suits the requirements.
|
||||
*/
|
||||
Size getSize();
|
||||
|
||||
}
|
|
@ -0,0 +1,171 @@
|
|||
/**
|
||||
*
|
||||
* 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.compute.domain.internal;
|
||||
|
||||
import org.jclouds.compute.domain.Architecture;
|
||||
import org.jclouds.compute.domain.Image;
|
||||
import org.jclouds.compute.domain.OperatingSystem;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class ImageImpl implements Image {
|
||||
|
||||
private final String id;
|
||||
private final String description;
|
||||
private final OperatingSystem operatingSystem;
|
||||
private final String version;
|
||||
private final String location;
|
||||
private final Architecture architecture;
|
||||
|
||||
public ImageImpl(String id, String description, OperatingSystem operatingSystem, String version,
|
||||
String location, Architecture architecture) {
|
||||
this.id = id;
|
||||
this.description = description;
|
||||
this.operatingSystem = operatingSystem;
|
||||
this.version = version;
|
||||
this.location = location;
|
||||
this.architecture = architecture;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((architecture == null) ? 0 : architecture.hashCode());
|
||||
result = prime * result + ((description == null) ? 0 : description.hashCode());
|
||||
result = prime * result + ((id == null) ? 0 : id.hashCode());
|
||||
result = prime * result + ((location == null) ? 0 : location.hashCode());
|
||||
result = prime * result + ((operatingSystem == null) ? 0 : operatingSystem.hashCode());
|
||||
result = prime * result + ((version == null) ? 0 : version.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
ImageImpl other = (ImageImpl) obj;
|
||||
if (architecture == null) {
|
||||
if (other.architecture != null)
|
||||
return false;
|
||||
} else if (!architecture.equals(other.architecture))
|
||||
return false;
|
||||
if (description == null) {
|
||||
if (other.description != null)
|
||||
return false;
|
||||
} else if (!description.equals(other.description))
|
||||
return false;
|
||||
if (id == null) {
|
||||
if (other.id != null)
|
||||
return false;
|
||||
} else if (!id.equals(other.id))
|
||||
return false;
|
||||
if (location == null) {
|
||||
if (other.location != null)
|
||||
return false;
|
||||
} else if (!location.equals(other.location))
|
||||
return false;
|
||||
if (operatingSystem == null) {
|
||||
if (other.operatingSystem != null)
|
||||
return false;
|
||||
} else if (!operatingSystem.equals(other.operatingSystem))
|
||||
return false;
|
||||
if (version == null) {
|
||||
if (other.version != null)
|
||||
return false;
|
||||
} else if (!version.equals(other.version))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ImageImpl [architecture=" + architecture + ", description=" + description + ", id="
|
||||
+ id + ", location=" + location + ", operatingSystem=" + operatingSystem
|
||||
+ ", version=" + version + "]";
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public OperatingSystem getOperatingSystem() {
|
||||
return operatingSystem;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Architecture getArchitecture() {
|
||||
return architecture;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,138 @@
|
|||
/**
|
||||
*
|
||||
* 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.domain.internal;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.jclouds.compute.domain.Architecture;
|
||||
import org.jclouds.compute.domain.Size;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class SizeImpl implements Size {
|
||||
|
||||
private final Integer cores;
|
||||
private final Integer ram;
|
||||
private final Integer disk;
|
||||
private final Set<Architecture> supportedArchitectures = Sets.newHashSet();
|
||||
|
||||
public SizeImpl(Integer cores, Integer ram, Integer disk,
|
||||
Iterable<Architecture> supportedArchitectures) {
|
||||
this.cores = cores;
|
||||
this.ram = ram;
|
||||
this.disk = disk;
|
||||
Iterables.addAll(this.supportedArchitectures, supportedArchitectures);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Integer getCores() {
|
||||
return cores;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Integer getRam() {
|
||||
return ram;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Integer getDisk() {
|
||||
return disk;
|
||||
}
|
||||
|
||||
@Override
|
||||
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
|
||||
+ ((supportedArchitectures == null) ? 0 : supportedArchitectures.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;
|
||||
SizeImpl other = (SizeImpl) obj;
|
||||
if (cores == null) {
|
||||
if (other.cores != null)
|
||||
return false;
|
||||
} else if (!cores.equals(other.cores))
|
||||
return false;
|
||||
if (disk == null) {
|
||||
if (other.disk != null)
|
||||
return false;
|
||||
} else if (!disk.equals(other.disk))
|
||||
return false;
|
||||
if (ram == null) {
|
||||
if (other.ram != null)
|
||||
return false;
|
||||
} else if (!ram.equals(other.ram))
|
||||
return false;
|
||||
if (supportedArchitectures == null) {
|
||||
if (other.supportedArchitectures != null)
|
||||
return false;
|
||||
} else if (!supportedArchitectures.equals(other.supportedArchitectures))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SizeImpl [cores=" + cores + ", disk=" + disk + ", ram=" + ram + "]";
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public int compareTo(Size o) {
|
||||
return (this == o) ? 0 : getCores().compareTo(o.getCores());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean supportsArchitecture(Architecture architecture) {
|
||||
return supportedArchitectures.contains(architecture);
|
||||
}
|
||||
}
|
|
@ -28,7 +28,7 @@ import com.google.common.collect.Iterables;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
public class ComputeUtils {
|
||||
public static Iterable<ComputeMetadata> filterByName(Iterable<ComputeMetadata> nodes,
|
||||
public static Iterable<? extends ComputeMetadata> filterByName(Iterable<? extends ComputeMetadata> nodes,
|
||||
final String name) {
|
||||
return Iterables.filter(nodes, new Predicate<ComputeMetadata>() {
|
||||
@Override
|
||||
|
|
|
@ -35,12 +35,12 @@ 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.Profile;
|
||||
import org.jclouds.compute.domain.OperatingSystem;
|
||||
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.reference.ComputeServiceConstants;
|
||||
|
@ -73,17 +73,18 @@ public class RimuHostingComputeService implements ComputeService {
|
|||
this.rhClient = rhClient;
|
||||
}
|
||||
|
||||
private Map<Image, String> imageNameMap = ImmutableMap.<Image, String> builder().put(
|
||||
Image.CENTOS_53, "centos53").put(Image.UBUNTU_90, "ubuntu904").build();
|
||||
private Map<Profile, String> profileNameMap = ImmutableMap.<Profile, String> builder().put(
|
||||
Profile.SMALLEST, "MIRO1B").build();
|
||||
private Map<OperatingSystem, String> imageNameMap = ImmutableMap
|
||||
.<OperatingSystem, String> builder().put(OperatingSystem.CENTOS, "centos53").put(
|
||||
OperatingSystem.UBUNTU, "ubuntu904").build();
|
||||
|
||||
// private Map<Size, String> profileNameMap = ImmutableMap.<Profile, String> builder().put(
|
||||
// Profile.SMALLEST, "MIRO1B").build();
|
||||
|
||||
@Override
|
||||
public CreateNodeResponse startNodeInLocation(String location, String name, Profile profile,
|
||||
Image image) {
|
||||
public CreateNodeResponse runNode(String name, Template template) {
|
||||
NewServerResponse serverResponse = rhClient.createServer(name, checkNotNull(imageNameMap
|
||||
.get(image), "image not supported: " + image), checkNotNull(profileNameMap
|
||||
.get(profile), "profile not supported: " + profile));
|
||||
.get(template.getImage().getOperatingSystem()), "os not supported: "
|
||||
+ template.getImage().getOperatingSystem()), "MIRO1B");
|
||||
return new CreateNodeResponseImpl(serverResponse.getServer().getId().toString(),
|
||||
serverResponse.getServer().getName(), "default", null, ImmutableMap
|
||||
.<String, String> of(),
|
||||
|
@ -138,7 +139,17 @@ public class RimuHostingComputeService implements ComputeService {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Size> getSizes() {
|
||||
public Template createTemplateInLocation(String location) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<? extends Size> listSizes() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<? extends Template> listTemplates() {
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -19,37 +19,30 @@
|
|||
package org.jclouds.rimuhosting.miro.compute;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.easymock.EasyMock.expect;
|
||||
import static org.easymock.classextension.EasyMock.createMock;
|
||||
import static org.easymock.classextension.EasyMock.replay;
|
||||
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.net.UnknownHostException;
|
||||
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.Image;
|
||||
import org.jclouds.compute.domain.LoginType;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.Profile;
|
||||
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.rimuhosting.miro.data.CreateOptions;
|
||||
import org.jclouds.rimuhosting.miro.data.NewServerData;
|
||||
import org.jclouds.rimuhosting.miro.domain.IpAddresses;
|
||||
import org.jclouds.rimuhosting.miro.domain.NewServerResponse;
|
||||
import org.jclouds.rimuhosting.miro.domain.Server;
|
||||
import org.jclouds.ssh.ExecResponse;
|
||||
import org.jclouds.ssh.SshClient;
|
||||
import org.jclouds.ssh.SshException;
|
||||
|
@ -59,7 +52,6 @@ import org.testng.annotations.BeforeGroups;
|
|||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.ImmutableSortedSet;
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
|
||||
|
@ -68,29 +60,34 @@ import com.google.inject.Injector;
|
|||
*/
|
||||
@Test(groups = "live", sequential = true, testName = "rimuhosting.RimuHostingNodeServiceLiveTest")
|
||||
public class RimuHostingComputeServiceLiveTest {
|
||||
private static final String service = "rimuhosting";
|
||||
|
||||
protected SshClient.Factory sshFactory;
|
||||
private String nodePrefix = System.getProperty("user.name") + ".rimuhosting";
|
||||
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 IOException {
|
||||
String key = checkNotNull(System.getProperty("jclouds.test.key"), "jclouds.test.key");
|
||||
context = new ComputeServiceContextFactory().createContext("rimuhosting", key, key,
|
||||
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 void testCreate() throws Exception {
|
||||
node = context.getComputeService().startNodeInLocation("default", nodePrefix,
|
||||
Profile.SMALLEST, Image.CENTOS_53);
|
||||
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);
|
||||
|
@ -105,7 +102,7 @@ public class RimuHostingComputeServiceLiveTest {
|
|||
|
||||
@Test(dependsOnMethods = "testCreate")
|
||||
public void testGet() throws Exception {
|
||||
NodeMetadata metadata = context.getComputeService().getNodeMetadata(node);
|
||||
NodeMetadata metadata = client.getNodeMetadata(node);
|
||||
assertEquals(metadata.getId(), node.getId());
|
||||
assertEquals(metadata.getLoginPort(), node.getLoginPort());
|
||||
assertEquals(metadata.getLoginType(), node.getLoginType());
|
||||
|
@ -115,13 +112,27 @@ public class RimuHostingComputeServiceLiveTest {
|
|||
}
|
||||
|
||||
public void testList() throws Exception {
|
||||
for (ComputeMetadata node : context.getComputeService().listNodes()) {
|
||||
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();
|
||||
|
@ -155,65 +166,8 @@ public class RimuHostingComputeServiceLiveTest {
|
|||
@AfterTest
|
||||
void cleanup() throws InterruptedException, ExecutionException, TimeoutException {
|
||||
if (node != null)
|
||||
context.getComputeService().destroyNode(node);
|
||||
client.destroyNode(node);
|
||||
context.close();
|
||||
}
|
||||
|
||||
public void testParseInetAddress() throws UnknownHostException {
|
||||
|
||||
Server rhServer = createMock(Server.class);
|
||||
IpAddresses addresses = createMock(IpAddresses.class);
|
||||
expect(rhServer.getIpAddresses()).andReturn(addresses).atLeastOnce();
|
||||
expect(addresses.getPrimaryIp()).andReturn("127.0.0.1");
|
||||
expect(addresses.getSecondaryIps()).andReturn(ImmutableSortedSet.of("www.yahoo.com"));
|
||||
replay(rhServer);
|
||||
replay(addresses);
|
||||
|
||||
// assertEquals(Sets
|
||||
// .newLinkedHashSet(RimuHostingCreateNodeResponse.getPublicAddresses(rhServer)),
|
||||
// ImmutableSet.of(InetAddress.getByName("127.0.0.1"), InetAddress
|
||||
// .getByName("www.yahoo.com")));
|
||||
}
|
||||
|
||||
@Test(enabled = false)
|
||||
public void test() throws UnknownHostException {
|
||||
|
||||
NewServerResponse nsResponse = createMock(NewServerResponse.class);
|
||||
Server rhServer = createMock(Server.class);
|
||||
|
||||
expect(nsResponse.getServer()).andReturn(rhServer).atLeastOnce();
|
||||
|
||||
expect(rhServer.getId()).andReturn(new Long(1));
|
||||
expect(rhServer.getName()).andReturn("name");
|
||||
|
||||
IpAddresses addresses = createMock(IpAddresses.class);
|
||||
expect(rhServer.getIpAddresses()).andReturn(addresses).atLeastOnce();
|
||||
|
||||
expect(addresses.getPrimaryIp()).andReturn("127.0.0.1");
|
||||
expect(addresses.getSecondaryIps()).andReturn(ImmutableSortedSet.<String> of());
|
||||
|
||||
NewServerData data = createMock(NewServerData.class);
|
||||
|
||||
expect(nsResponse.getNewInstanceRequest()).andReturn(data).atLeastOnce();
|
||||
CreateOptions options = createMock(CreateOptions.class);
|
||||
expect(data.getCreateOptions()).andReturn(options);
|
||||
expect(options.getPassword()).andReturn("password");
|
||||
|
||||
replay(nsResponse);
|
||||
replay(rhServer);
|
||||
replay(addresses);
|
||||
replay(data);
|
||||
replay(options);
|
||||
|
||||
// RimuHostingCreateNodeResponse response = new RimuHostingCreateNodeResponse(nsResponse);
|
||||
// assertEquals(response.getId(), "1");
|
||||
// assertEquals(response.getName(), "name");
|
||||
// assertEquals(response.getPublicAddresses(), ImmutableSet.<InetAddress> of(InetAddress
|
||||
// .getByName("127.0.0.1")));
|
||||
// assertEquals(response.getPrivateAddresses(), ImmutableSet.<InetAddress> of());
|
||||
// assertEquals(response.getLoginPort(), 22);
|
||||
// assertEquals(response.getLoginType(), LoginType.SSH);
|
||||
// assertEquals(response.getCredentials(), new Credentials("root", "password"));
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -72,7 +72,7 @@
|
|||
|
||||
<target name="create" description="create the node ${jclouds.compute.nodename}" depends="destroy" >
|
||||
<compute action="create" provider="${jclouds.compute.url}">
|
||||
<node name="${jclouds.compute.nodename}" image="UBUNTU_JEOS_90" profile="SMALLEST"
|
||||
<node name="${jclouds.compute.nodename}" os="UBUNTU" size="SMALLEST"
|
||||
hostproperty="host" usernameproperty="username" passwordproperty="password" />
|
||||
</compute>
|
||||
|
||||
|
|
|
@ -94,7 +94,7 @@
|
|||
|
||||
<property name="location" value="default" />
|
||||
<target name="create" description="create the node ${nodename}">
|
||||
<property name="image" value="UBUNTU_90" />
|
||||
<property name="os" value="UBUNTU" />
|
||||
|
||||
<input
|
||||
message="What do you want to name your node?"
|
||||
|
@ -102,7 +102,7 @@
|
|||
/>
|
||||
|
||||
<compute action="create" provider="${jclouds.compute.url}">
|
||||
<node name="${nodename}" location="${location}" image="${image}" profile="SMALLEST" hostproperty="host" usernameproperty="username" passwordproperty="password" />
|
||||
<node name="${nodename}" location="${location}" os="${os}" size="SMALLEST" hostproperty="host" usernameproperty="username" passwordproperty="password" />
|
||||
</compute>
|
||||
</target>
|
||||
|
||||
|
|
|
@ -35,9 +35,9 @@ 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.Image;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.Profile;
|
||||
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.http.HttpUtils;
|
||||
|
@ -187,12 +187,21 @@ public class ComputeTask extends Task {
|
|||
}
|
||||
|
||||
private void create(ComputeService computeService) {
|
||||
log(String.format("create name: %s, profile: %s, image: %s", nodeElement.getName(),
|
||||
nodeElement.getProfile(), nodeElement.getImage()));
|
||||
CreateNodeResponse createdNode = computeService.startNodeInLocation(
|
||||
nodeElement.getLocation(), nodeElement.getName(), Profile.valueOf(nodeElement
|
||||
.getProfile().toUpperCase()), Image.valueOf(nodeElement.getImage()
|
||||
.toUpperCase()));
|
||||
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");
|
||||
}
|
||||
CreateNodeResponse createdNode = computeService.runNode(nodeElement.getName(), template);
|
||||
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
|
||||
|
@ -221,7 +230,7 @@ public class ComputeTask extends Task {
|
|||
|
||||
private void destroy(ComputeService computeService) {
|
||||
log(String.format("destroy name: %s", nodeElement.getName()));
|
||||
Iterable<ComputeMetadata> nodesThatMatch = ComputeUtils.filterByName(computeService
|
||||
Iterable<? extends ComputeMetadata> nodesThatMatch = ComputeUtils.filterByName(computeService
|
||||
.listNodes(), nodeElement.getName());
|
||||
for (ComputeMetadata node : nodesThatMatch) {
|
||||
log(String.format(" destroying id=%s, name=%s", node.getId(), node.getName()));
|
||||
|
@ -231,7 +240,7 @@ public class ComputeTask extends Task {
|
|||
|
||||
private void get(ComputeService computeService) {
|
||||
log(String.format("get name: %s", nodeElement.getName()));
|
||||
Iterable<ComputeMetadata> nodesThatMatch = ComputeUtils.filterByName(computeService
|
||||
Iterable<? extends ComputeMetadata> nodesThatMatch = ComputeUtils.filterByName(computeService
|
||||
.listNodes(), nodeElement.getName());
|
||||
for (ComputeMetadata node : nodesThatMatch) {
|
||||
logDetails(computeService, node);
|
||||
|
|
|
@ -24,8 +24,8 @@ package org.jclouds.tools.ant.taskdefs.compute;
|
|||
*/
|
||||
public class NodeElement {
|
||||
private String name;
|
||||
private String profile;
|
||||
private String image;
|
||||
private String size;
|
||||
private String os;
|
||||
private String passwordproperty;
|
||||
private String keyfi1le;
|
||||
private String hostproperty;
|
||||
|
@ -49,22 +49,6 @@ public class NodeElement {
|
|||
this.name = name;
|
||||
}
|
||||
|
||||
String getProfile() {
|
||||
return profile;
|
||||
}
|
||||
|
||||
public void setProfile(String profile) {
|
||||
this.profile = profile;
|
||||
}
|
||||
|
||||
String getImage() {
|
||||
return image;
|
||||
}
|
||||
|
||||
public void setImage(String image) {
|
||||
this.image = image;
|
||||
}
|
||||
|
||||
String getUsernameproperty() {
|
||||
return usernameproperty;
|
||||
}
|
||||
|
@ -124,4 +108,20 @@ public class NodeElement {
|
|||
return keyfi1le;
|
||||
}
|
||||
|
||||
public void setSize(String size) {
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
public String getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
public void setOs(String os) {
|
||||
this.os = os;
|
||||
}
|
||||
|
||||
public String getOs() {
|
||||
return os;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ import java.util.Map;
|
|||
import javax.annotation.Resource;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.jclouds.compute.domain.Image;
|
||||
import org.jclouds.compute.domain.OperatingSystem;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.vcloud.domain.Task;
|
||||
import org.jclouds.vcloud.domain.VApp;
|
||||
|
@ -49,17 +49,16 @@ public class VCloudComputeClient {
|
|||
private final VCloudClient tmClient;
|
||||
|
||||
@Inject
|
||||
public VCloudComputeClient(VCloudClient tmClient,
|
||||
Predicate<String> successTester) {
|
||||
public VCloudComputeClient(VCloudClient tmClient, Predicate<String> successTester) {
|
||||
this.tmClient = tmClient;
|
||||
this.taskTester = successTester;
|
||||
}
|
||||
|
||||
private Map<Image, String> imageCatalogIdMap = ImmutableMap.<Image, String> builder().put(
|
||||
Image.CENTOS_53, "1").put(Image.RHEL_53, "8").put(Image.UBUNTU_90, "10").put(
|
||||
Image.UBUNTU_JEOS_90, "11").build();
|
||||
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, Image image, int minCores, int minMegs,
|
||||
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);
|
||||
|
@ -68,9 +67,9 @@ public class VCloudComputeClient {
|
|||
.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));
|
||||
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());
|
||||
|
@ -85,7 +84,8 @@ public class VCloudComputeClient {
|
|||
// "powerOn", VAppStatus.ON);
|
||||
logger.debug("<< on vApp(%s)", vApp.getId());
|
||||
|
||||
return ImmutableMap.<String, String> of("id", vApp.getId(), "username", null, "password", null);
|
||||
return ImmutableMap.<String, String> of("id", vApp.getId(), "username", null, "password",
|
||||
null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -28,7 +28,7 @@ import java.util.Map;
|
|||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.jclouds.compute.domain.Image;
|
||||
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;
|
||||
|
@ -59,7 +59,8 @@ public class VCloudComputeClientLiveTest {
|
|||
private String id;
|
||||
private InetAddress privateAddress;
|
||||
|
||||
public static final String PREFIX = (System.getProperty("user.name") + "-vcloud").replaceAll("\\.","");
|
||||
public static final String PREFIX = (System.getProperty("user.name") + "-vcloud").replaceAll(
|
||||
"\\.", "");
|
||||
|
||||
private static class Expectation {
|
||||
final long hardDisk;
|
||||
|
@ -71,20 +72,20 @@ public class VCloudComputeClientLiveTest {
|
|||
}
|
||||
}
|
||||
|
||||
private Map<Image, Expectation> expectationMap = ImmutableMap.<Image, Expectation> builder()
|
||||
.put(Image.CENTOS_53,
|
||||
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(
|
||||
Image.RHEL_53,
|
||||
OperatingSystem.RHEL,
|
||||
new Expectation(4194304 / 2 * 10, "Red Hat Enterprise Linux 5 (64-bit)")).put(
|
||||
Image.UBUNTU_90, new Expectation(4194304, "Ubuntu Linux (64-bit)")).put(
|
||||
Image.UBUNTU_JEOS_90, new Expectation(4194304, "Ubuntu Linux (32-bit)")).build();
|
||||
OperatingSystem.UBUNTU, new Expectation(4194304, "Ubuntu Linux (32-bit)"))
|
||||
.build();
|
||||
|
||||
private Predicate<InetAddress> addressTester;
|
||||
|
||||
@Test
|
||||
public void testPowerOn() throws InterruptedException, ExecutionException, TimeoutException,
|
||||
IOException {
|
||||
Image toTest = Image.CENTOS_53;
|
||||
OperatingSystem toTest = OperatingSystem.CENTOS;
|
||||
|
||||
String serverName = getCompatibleServerName(toTest);
|
||||
int processorCount = 1;
|
||||
|
@ -101,10 +102,10 @@ public class VCloudComputeClientLiveTest {
|
|||
assertEquals(vApp.getStatus(), VAppStatus.ON);
|
||||
}
|
||||
|
||||
private String getCompatibleServerName(Image toTest) {
|
||||
String serverName = CaseFormat.UPPER_UNDERSCORE
|
||||
.to(CaseFormat.LOWER_CAMEL, toTest.toString()).substring(0,
|
||||
toTest.toString().length()-1 <= 15 ? toTest.toString().length()-1 : 14);
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -146,8 +147,8 @@ public class VCloudComputeClientLiveTest {
|
|||
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();
|
||||
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>>() {
|
||||
|
|
|
@ -18,15 +18,12 @@
|
|||
*/
|
||||
package org.jclouds.vcloud.hostingdotcom.compute;
|
||||
|
||||
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.Image;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.vcloud.domain.Task;
|
||||
import org.jclouds.vcloud.domain.VApp;
|
||||
|
@ -57,34 +54,15 @@ public class HostingDotComVCloudComputeClient {
|
|||
this.taskTester = successTester;
|
||||
}
|
||||
|
||||
private Map<Image, String> imageCatalogIdMap = ImmutableMap.<Image, String> builder().put(
|
||||
Image.CENTOS_53, "3").build();
|
||||
|
||||
// <ResourceEntity href="https://vcloud.safesecureweb.com/api/v0.8/vAppTemplate/1"
|
||||
// type="application/vnd.vmware.vcloud.vAppTemplate+xml"
|
||||
// name="Plesk (Linux) 64-bit Template" />
|
||||
// <ResourceEntity href="https://vcloud.safesecureweb.com/api/v0.8/vAppTemplate/2"
|
||||
// type="application/vnd.vmware.vcloud.vAppTemplate+xml"
|
||||
// name="Windows 2008 Datacenter 64 Bit Template" />
|
||||
// <ResourceEntity href="https://vcloud.safesecureweb.com/api/v0.8/vAppTemplate/3"
|
||||
// type="application/vnd.vmware.vcloud.vAppTemplate+xml"
|
||||
// name="Cent OS 64 Bit Template" />
|
||||
// <ResourceEntity href="https://vcloud.safesecureweb.com/api/v0.8/vAppTemplate/4"
|
||||
// type="application/vnd.vmware.vcloud.vAppTemplate+xml"
|
||||
// name="cPanel (Linux) 64 Bit Template" />
|
||||
|
||||
public Map<String, String> start(String name, Image 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();
|
||||
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));
|
||||
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());
|
||||
|
|
|
@ -28,6 +28,7 @@ import java.util.Set;
|
|||
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;
|
||||
|
@ -38,8 +39,8 @@ 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.Profile;
|
||||
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;
|
||||
|
@ -65,6 +66,9 @@ public class HostingDotComVCloudComputeService implements ComputeService {
|
|||
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(
|
||||
|
@ -74,25 +78,28 @@ public class HostingDotComVCloudComputeService implements ComputeService {
|
|||
|
||||
@Inject
|
||||
public HostingDotComVCloudComputeService(HostingDotComVCloudClient client,
|
||||
HostingDotComVCloudComputeClient computeClient) {
|
||||
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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CreateNodeResponse startNodeInLocation(String location, String name, Profile profile,
|
||||
Image image) {
|
||||
if (checkNotNull(location, "location").equalsIgnoreCase("default"))
|
||||
location = client.getDefaultVDC().getId();
|
||||
Map<String, String> metaMap = computeClient.start(name, image, 1, 512, (10l * 1025 * 1024),
|
||||
ImmutableMap.<String, String> of());
|
||||
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(), location, 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());
|
||||
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
|
||||
|
@ -105,10 +112,10 @@ public class HostingDotComVCloudComputeService implements ComputeService {
|
|||
|
||||
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());
|
||||
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
|
||||
|
@ -132,7 +139,17 @@ public class HostingDotComVCloudComputeService implements ComputeService {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Size> getSizes() {
|
||||
return null;// TODO
|
||||
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();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,180 @@
|
|||
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,16 +18,38 @@
|
|||
*/
|
||||
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.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;
|
||||
|
||||
/**
|
||||
|
@ -48,8 +70,70 @@ public class HostingDotComVCloudComputeServiceContextModule extends
|
|||
@Provides
|
||||
@Singleton
|
||||
ComputeServiceContext provideContext(ComputeService computeService,
|
||||
RestContext<HostingDotComVCloudAsyncClient, HostingDotComVCloudAsyncClient> context) {
|
||||
return new ComputeServiceContextImpl<HostingDotComVCloudAsyncClient, HostingDotComVCloudAsyncClient>(
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ import java.util.Map;
|
|||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.jclouds.compute.domain.Image;
|
||||
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;
|
||||
|
@ -73,13 +73,9 @@ public class HostingDotComVCloudComputeClientLiveTest {
|
|||
}
|
||||
}
|
||||
|
||||
private Map<Image, Expectation> expectationMap = ImmutableMap.<Image, Expectation> builder()
|
||||
.put(Image.CENTOS_53,
|
||||
new Expectation(4194304 / 2 * 10, "Red Hat Enterprise Linux 5 (64-bit)")).put(
|
||||
Image.RHEL_53,
|
||||
new Expectation(4194304 / 2 * 10, "Red Hat Enterprise Linux 5 (64-bit)")).put(
|
||||
Image.UBUNTU_90, new Expectation(4194304, "Ubuntu Linux (64-bit)")).put(
|
||||
Image.UBUNTU_JEOS_90, new Expectation(4194304, "Ubuntu Linux (32-bit)"))
|
||||
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;
|
||||
|
@ -87,7 +83,7 @@ public class HostingDotComVCloudComputeClientLiveTest {
|
|||
@Test(enabled = true)
|
||||
public void testPowerOn() throws InterruptedException, ExecutionException, TimeoutException,
|
||||
IOException {
|
||||
Image toTest = Image.CENTOS_53;
|
||||
OperatingSystem toTest = OperatingSystem.CENTOS;
|
||||
|
||||
String serverName = getCompatibleServerName(toTest);
|
||||
int processorCount = 1;
|
||||
|
@ -95,7 +91,8 @@ public class HostingDotComVCloudComputeClientLiveTest {
|
|||
long disk = 10 * 1025 * 1024;
|
||||
Map<String, String> properties = ImmutableMap.of("foo", "bar");
|
||||
|
||||
id = client.start(serverName, toTest, processorCount, memory, disk, properties).get("id");
|
||||
id = client.start(hostingClient.getDefaultVDC().getId(), serverName, "3", processorCount,
|
||||
memory, disk, properties).get("id");
|
||||
Expectation expectation = expectationMap.get(toTest);
|
||||
|
||||
VApp vApp = hostingClient.getVApp(id);
|
||||
|
@ -104,7 +101,7 @@ public class HostingDotComVCloudComputeClientLiveTest {
|
|||
assertEquals(vApp.getStatus(), VAppStatus.ON);
|
||||
}
|
||||
|
||||
private String getCompatibleServerName(Image toTest) {
|
||||
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);
|
||||
|
@ -148,8 +145,8 @@ public class HostingDotComVCloudComputeClientLiveTest {
|
|||
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(
|
||||
new HostingDotComVCloudPropertiesBuilder(account, key).build())
|
||||
.withModules(new Log4JLoggingModule(), new JschSshClientModule()).buildInjector();
|
||||
new HostingDotComVCloudPropertiesBuilder(account, key).build()).withModules(
|
||||
new Log4JLoggingModule(), new JschSshClientModule()).buildInjector();
|
||||
client = injector.getInstance(HostingDotComVCloudComputeClient.class);
|
||||
hostingClient = injector.getInstance(HostingDotComVCloudClient.class);
|
||||
addressTester = injector.getInstance(Key.get(new TypeLiteral<Predicate<InetAddress>>() {
|
||||
|
|
|
@ -20,23 +20,28 @@
|
|||
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.Image;
|
||||
import org.jclouds.compute.domain.LoginType;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.Profile;
|
||||
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;
|
||||
|
@ -48,6 +53,7 @@ import org.testng.annotations.AfterTest;
|
|||
import org.testng.annotations.BeforeGroups;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
|
||||
|
@ -59,30 +65,35 @@ import com.google.inject.Injector;
|
|||
*/
|
||||
@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 nodePrefix = System.getProperty("user.name");
|
||||
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 {
|
||||
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 = HostingDotComVCloudComputeServiceContextFactory.createContext(user, password,
|
||||
new Log4JLoggingModule());
|
||||
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 void testCreate() throws Exception {
|
||||
node = context.getComputeService().startNodeInLocation("default", nodePrefix,
|
||||
Profile.SMALLEST, Image.UBUNTU_90);
|
||||
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);
|
||||
|
@ -97,7 +108,7 @@ public class HostingDotComVCloudComputeServiceLiveTest {
|
|||
|
||||
@Test(dependsOnMethods = "testCreate")
|
||||
public void testGet() throws Exception {
|
||||
NodeMetadata metadata = context.getComputeService().getNodeMetadata(node);
|
||||
NodeMetadata metadata = client.getNodeMetadata(node);
|
||||
assertEquals(metadata.getId(), node.getId());
|
||||
assertEquals(metadata.getLoginPort(), node.getLoginPort());
|
||||
assertEquals(metadata.getLoginType(), node.getLoginType());
|
||||
|
@ -107,13 +118,27 @@ public class HostingDotComVCloudComputeServiceLiveTest {
|
|||
}
|
||||
|
||||
public void testList() throws Exception {
|
||||
for (ComputeMetadata node : context.getComputeService().listNodes()) {
|
||||
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();
|
||||
|
@ -147,7 +172,7 @@ public class HostingDotComVCloudComputeServiceLiveTest {
|
|||
@AfterTest
|
||||
void cleanup() throws InterruptedException, ExecutionException, TimeoutException {
|
||||
if (node != null)
|
||||
context.getComputeService().destroyNode(node);
|
||||
client.destroyNode(node);
|
||||
context.close();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,32 +1,31 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
<!--
|
||||
|
||||
|
||||
Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
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
|
||||
====================================================================
|
||||
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.
|
||||
====================================================================
|
||||
|
||||
-->
|
||||
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.
|
||||
====================================================================
|
||||
-->
|
||||
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
|
||||
|
||||
<!--
|
||||
For more configuration infromation and examples see the Apache Log4j
|
||||
website: http://logging.apache.org/log4j/
|
||||
-->
|
||||
<!--
|
||||
For more configuration infromation and examples see the Apache
|
||||
Log4j website: http://logging.apache.org/log4j/
|
||||
-->
|
||||
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"
|
||||
debug="false">
|
||||
debug="false">
|
||||
|
||||
<!-- A time/date based rolling appender -->
|
||||
<appender name="WIREFILE" class="org.apache.log4j.DailyRollingFileAppender">
|
||||
|
@ -43,36 +42,34 @@
|
|||
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
|
||||
|
||||
<!--
|
||||
The full pattern: Date MS Priority [Category] (Thread:NDC) Message\n
|
||||
<param name="ConversionPattern" value="%d %-5r %-5p [%c] (%t:%x)
|
||||
%m%n"/>
|
||||
The full pattern: Date MS Priority [Category]
|
||||
(Thread:NDC) Message\n <param name="ConversionPattern"
|
||||
value="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
|
||||
-->
|
||||
</layout>
|
||||
</appender>
|
||||
|
||||
<!-- A time/date based rolling appender -->
|
||||
<appender name="FILE" class="org.apache.log4j.DailyRollingFileAppender">
|
||||
<param name="File" value="target/test-data/jclouds.log" />
|
||||
<param name="Append" value="true" />
|
||||
<!-- A time/date based rolling appender -->
|
||||
<appender name="FILE" class="org.apache.log4j.DailyRollingFileAppender">
|
||||
<param name="File" value="target/test-data/jclouds.log" />
|
||||
<param name="Append" value="true" />
|
||||
|
||||
<!-- Rollover at midnight each day -->
|
||||
<param name="DatePattern" value="'.'yyyy-MM-dd" />
|
||||
<!-- Rollover at midnight each day -->
|
||||
<param name="DatePattern" value="'.'yyyy-MM-dd" />
|
||||
|
||||
<param name="Threshold" value="TRACE" />
|
||||
|
||||
<layout class="org.apache.log4j.PatternLayout">
|
||||
<!-- The default pattern: Date Priority [Category] Message\n -->
|
||||
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
|
||||
|
||||
<!--
|
||||
The full pattern: Date MS Priority [Category] (Thread:NDC) Message\n
|
||||
<param name="ConversionPattern" value="%d %-5r %-5p [%c] (%t:%x)
|
||||
%m%n"/>
|
||||
-->
|
||||
</layout>
|
||||
</appender>
|
||||
<param name="Threshold" value="TRACE" />
|
||||
|
||||
<layout class="org.apache.log4j.PatternLayout">
|
||||
<!-- The default pattern: Date Priority [Category] Message\n -->
|
||||
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
|
||||
|
||||
<!--
|
||||
The full pattern: Date MS Priority [Category]
|
||||
(Thread:NDC) Message\n <param name="ConversionPattern"
|
||||
value="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
|
||||
-->
|
||||
</layout>
|
||||
</appender>
|
||||
|
||||
<!-- A time/date based rolling appender -->
|
||||
<appender name="COMPUTEFILE" class="org.apache.log4j.DailyRollingFileAppender">
|
||||
|
@ -89,70 +86,60 @@
|
|||
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
|
||||
|
||||
<!--
|
||||
The full pattern: Date MS Priority [Category] (Thread:NDC) Message\n
|
||||
<param name="ConversionPattern" value="%d %-5r %-5p [%c] (%t:%x)
|
||||
%m%n"/>
|
||||
The full pattern: Date MS Priority [Category]
|
||||
(Thread:NDC) Message\n <param name="ConversionPattern"
|
||||
value="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
|
||||
-->
|
||||
</layout>
|
||||
</appender>
|
||||
|
||||
|
||||
<appender name="ASYNC" class="org.apache.log4j.AsyncAppender">
|
||||
<appender-ref ref="FILE" />
|
||||
</appender>
|
||||
|
||||
<appender name="ASYNCWIRE" class="org.apache.log4j.AsyncAppender">
|
||||
<appender-ref ref="WIREFILE" />
|
||||
</appender>
|
||||
|
||||
<appender name="ASYNCCOMPUTE" class="org.apache.log4j.AsyncAppender">
|
||||
<appender-ref ref="COMPUTEFILE" />
|
||||
</appender>
|
||||
|
||||
<!-- ================ -->
|
||||
<!-- Limit categories -->
|
||||
<!-- ================ -->
|
||||
<appender name="ASYNC" class="org.apache.log4j.AsyncAppender">
|
||||
<appender-ref ref="FILE" />
|
||||
</appender>
|
||||
|
||||
<category name="org.jclouds">
|
||||
<priority value="DEBUG" />
|
||||
<appender name="ASYNCWIRE" class="org.apache.log4j.AsyncAppender">
|
||||
<appender-ref ref="WIREFILE" />
|
||||
</appender>
|
||||
|
||||
<!-- ================ -->
|
||||
<!-- Limit categories -->
|
||||
<!-- ================ -->
|
||||
|
||||
<category name="org.jclouds">
|
||||
<priority value="DEBUG" />
|
||||
<appender-ref ref="ASYNC" />
|
||||
</category>
|
||||
</category>
|
||||
|
||||
<category name="jclouds.http.headers">
|
||||
<priority value="DEBUG" />
|
||||
<appender-ref ref="ASYNCWIRE" />
|
||||
</category>
|
||||
|
||||
|
||||
|
||||
<category name="org.jclouds.vcloud.hostingdotcom.compute.HostingDotComVCloudComputeClient">
|
||||
<priority value="TRACE" />
|
||||
<appender-ref ref="ASYNCCOMPUTE" />
|
||||
</category>
|
||||
|
||||
|
||||
<category name="org.jclouds.predicates.SocketOpen">
|
||||
<priority value="TRACE" />
|
||||
<appender-ref ref="ASYNCWIRE" />
|
||||
</category>
|
||||
|
||||
<category name="org.jclouds.vcloud.predicates.TaskSuccess">
|
||||
<category name="jclouds.compute">
|
||||
<priority value="TRACE" />
|
||||
<appender-ref ref="ASYNCWIRE" />
|
||||
<appender-ref ref="ASYNCCOMPUTE" />
|
||||
</category>
|
||||
|
||||
|
||||
<category name="jclouds.http.wire">
|
||||
<priority value="DEBUG" />
|
||||
<appender-ref ref="ASYNCWIRE" />
|
||||
</category>
|
||||
|
||||
<!-- ======================= -->
|
||||
<!-- Setup the Root category -->
|
||||
<!-- ======================= -->
|
||||
<!-- Setup the Root category -->
|
||||
<!-- ======================= -->
|
||||
|
||||
<root>
|
||||
<priority value="WARN" />
|
||||
</root>
|
||||
<root>
|
||||
<priority value="WARN" />
|
||||
</root>
|
||||
|
||||
</log4j:configuration>
|
|
@ -31,7 +31,7 @@ import javax.annotation.Resource;
|
|||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
|
||||
import org.jclouds.compute.domain.Image;
|
||||
import org.jclouds.compute.domain.OperatingSystem;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.vcloud.domain.Task;
|
||||
|
@ -68,11 +68,13 @@ public class TerremarkVCloudComputeClient {
|
|||
this.taskTester = successTester;
|
||||
}
|
||||
|
||||
private Map<Image, String> imageCatalogIdMap = ImmutableMap.<Image, String> builder().put(
|
||||
Image.CENTOS_53, "6").put(Image.RHEL_53, "8").put(Image.UBUNTU_90, "10").put(
|
||||
Image.UBUNTU_JEOS_90, "11").put(Image.WEBAPPVM_93, "29").build();
|
||||
private Map<OperatingSystem, String> imageCatalogIdMap = ImmutableMap
|
||||
.<OperatingSystem, String> builder().put(OperatingSystem.CENTOS, "6").put(
|
||||
OperatingSystem.RHEL, "8").put(OperatingSystem.UBUNTU, "10").build();
|
||||
|
||||
public String start(String name, Image image, int minCores, int minMegs,
|
||||
// .put( OperatingSystem.UBUNTU_JEOS_90, "11").put(OperatingSystem.WEBAPPVM_93, "29")
|
||||
|
||||
public String start(String name, OperatingSystem image, int minCores, int minMegs,
|
||||
Map<String, String> properties) {
|
||||
checkArgument(imageCatalogIdMap.containsKey(image), "image not configured: " + image);
|
||||
return start(name, imageCatalogIdMap.get(image), minCores, minMegs, properties);
|
||||
|
@ -80,6 +82,12 @@ public class TerremarkVCloudComputeClient {
|
|||
|
||||
public String start(String name, String templateId, int minCores, int minMegs,
|
||||
Map<String, String> properties) {
|
||||
return this.start(tmClient.getDefaultVDC().getId(), name, templateId, minCores, minMegs,
|
||||
properties);
|
||||
}
|
||||
|
||||
public String start(String vdc, String name, String templateId, int minCores, int minMegs,
|
||||
Map<String, String> properties) {
|
||||
String vDCId = tmClient.getDefaultVDC().getId();
|
||||
logger
|
||||
.debug(
|
||||
|
|
|
@ -28,6 +28,7 @@ import java.util.Set;
|
|||
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;
|
||||
|
@ -38,8 +39,8 @@ 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.Profile;
|
||||
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;
|
||||
|
@ -65,6 +66,9 @@ public class TerremarkVCloudComputeService implements ComputeService {
|
|||
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(
|
||||
|
@ -74,21 +78,25 @@ public class TerremarkVCloudComputeService implements ComputeService {
|
|||
|
||||
@Inject
|
||||
public TerremarkVCloudComputeService(TerremarkVCloudClient tmClient,
|
||||
TerremarkVCloudComputeClient computeClient) {
|
||||
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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CreateNodeResponse startNodeInLocation(String location, String name, Profile profile,
|
||||
Image image) {
|
||||
if (checkNotNull(location, "location").equalsIgnoreCase("default"))
|
||||
location = client.getDefaultVDC().getId();
|
||||
String id = computeClient.start(name, image, 1, 512, ImmutableMap.<String, String> of());
|
||||
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());
|
||||
VApp vApp = client.getVApp(id);
|
||||
InetAddress publicIp = computeClient
|
||||
.createPublicAddressMappedToPorts(vApp, 22, 80, 8080, 443);
|
||||
return new CreateNodeResponseImpl(vApp.getId(), vApp.getName(), location, vApp.getLocation(),
|
||||
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
|
||||
|
@ -99,8 +107,8 @@ public class TerremarkVCloudComputeService implements ComputeService {
|
|||
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"));
|
||||
return getNodeMetadataByIdInVDC(checkNotNull(node.getLocation(), "location"), checkNotNull(
|
||||
node.getId(), "node.id"));
|
||||
}
|
||||
|
||||
private NodeMetadata getNodeMetadataByIdInVDC(String vDCId, String id) {
|
||||
|
@ -133,7 +141,17 @@ public class TerremarkVCloudComputeService implements ComputeService {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Size> getSizes() {
|
||||
return null;// TODO
|
||||
public Template createTemplateInLocation(String location) {
|
||||
return new TerremarkVCloudTemplate(client, images, sizes, location);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<? extends Size> listSizes() {
|
||||
return sizes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<? extends Template> listTemplates() {
|
||||
return templates.get();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,178 @@
|
|||
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,17 +18,42 @@
|
|||
*/
|
||||
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 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.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;
|
||||
|
||||
/**
|
||||
|
@ -53,4 +78,82 @@ public class TerremarkVCloudComputeServiceContextModule extends TerremarkVCloudC
|
|||
computeService, context);
|
||||
}
|
||||
|
||||
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
|
||||
.<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) {
|
||||
Image anyImage = Iterables.get(images, 0);
|
||||
holder.logger.debug(">> providing sizes");
|
||||
LinkedHashSet<Size> sizes = Sets.newLinkedHashSet(Iterables.transform(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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ import java.util.Map;
|
|||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.jclouds.compute.domain.Image;
|
||||
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;
|
||||
|
@ -73,18 +73,20 @@ public class TerremarkVCloudComputeClientLiveTest {
|
|||
}
|
||||
}
|
||||
|
||||
private Map<Image, Expectation> expectationMap = ImmutableMap.<Image, Expectation> builder()
|
||||
.put(Image.CENTOS_53, new Expectation(10485760, "Red Hat Enterprise Linux 5 (64-bit)"))
|
||||
.put(Image.RHEL_53, new Expectation(10485760, "Red Hat Enterprise Linux 5 (64-bit)"))
|
||||
.put(Image.UBUNTU_90, new Expectation(4194304, "Ubuntu Linux (64-bit)")).put(
|
||||
Image.UBUNTU_JEOS_90, new Expectation(4194304, "Ubuntu Linux (32-bit)")).build();
|
||||
|
||||
private Map<OperatingSystem, Expectation> expectationMap = ImmutableMap
|
||||
.<OperatingSystem, Expectation> builder().put(OperatingSystem.CENTOS,
|
||||
new Expectation(10485760, "Red Hat Enterprise Linux 5 (64-bit)")).put(
|
||||
OperatingSystem.RHEL,
|
||||
new Expectation(10485760, "Red Hat Enterprise Linux 5 (64-bit)")).put(
|
||||
OperatingSystem.UBUNTU, new Expectation(4194304, "Ubuntu Linux (64-bit)"))
|
||||
.build();
|
||||
// .put(OperatingSystem.UBUNTU, new Expectation(4194304, "Ubuntu Linux (32-bit)"))
|
||||
private Predicate<InetAddress> addressTester;
|
||||
|
||||
@Test
|
||||
public void testPowerOn() throws InterruptedException, ExecutionException, TimeoutException,
|
||||
IOException {
|
||||
Image toTest = Image.CENTOS_53;
|
||||
OperatingSystem toTest = OperatingSystem.CENTOS;
|
||||
|
||||
String serverName = getCompatibleServerName(toTest);
|
||||
int processorCount = 1;
|
||||
|
@ -100,7 +102,7 @@ public class TerremarkVCloudComputeClientLiveTest {
|
|||
assertEquals(vApp.getStatus(), VAppStatus.ON);
|
||||
}
|
||||
|
||||
private String getCompatibleServerName(Image toTest) {
|
||||
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);
|
||||
|
@ -115,9 +117,8 @@ public class TerremarkVCloudComputeClientLiveTest {
|
|||
|
||||
@Test(dependsOnMethods = "testGetAnyPrivateAddress")
|
||||
public void testSshLoadBalanceIp() {
|
||||
InetAddress publicIp = client.createPublicAddressMappedToPorts(tmClient.getVApp(id), 22,
|
||||
80,
|
||||
443, 8080); /// error 500
|
||||
InetAddress publicIp = client.createPublicAddressMappedToPorts(tmClient.getVApp(id), 22, 80,
|
||||
443, 8080); // / error 500
|
||||
assert addressTester.apply(publicIp);
|
||||
// client.exec(publicIp, "uname -a");
|
||||
}
|
||||
|
|
|
@ -20,23 +20,29 @@
|
|||
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 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.Image;
|
||||
import org.jclouds.compute.domain.LoginType;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.Profile;
|
||||
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;
|
||||
|
@ -48,6 +54,7 @@ import org.testng.annotations.AfterTest;
|
|||
import org.testng.annotations.BeforeGroups;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
|
||||
|
@ -59,30 +66,35 @@ import com.google.inject.Injector;
|
|||
*/
|
||||
@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 nodePrefix = System.getProperty("user.name");
|
||||
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 {
|
||||
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 = TerremarkVCloudComputeServiceContextFactory.createContext(user, password,
|
||||
new Log4JLoggingModule());
|
||||
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 void testCreate() throws Exception {
|
||||
node = context.getComputeService().startNodeInLocation("default", nodePrefix,
|
||||
Profile.SMALLEST, Image.UBUNTU_90);
|
||||
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);
|
||||
|
@ -97,7 +109,7 @@ public class TerremarkVCloudComputeServiceLiveTest {
|
|||
|
||||
@Test(dependsOnMethods = "testCreate")
|
||||
public void testGet() throws Exception {
|
||||
NodeMetadata metadata = context.getComputeService().getNodeMetadata(node);
|
||||
NodeMetadata metadata = client.getNodeMetadata(node);
|
||||
assertEquals(metadata.getId(), node.getId());
|
||||
assertEquals(metadata.getLoginPort(), node.getLoginPort());
|
||||
assertEquals(metadata.getLoginType(), node.getLoginType());
|
||||
|
@ -107,13 +119,27 @@ public class TerremarkVCloudComputeServiceLiveTest {
|
|||
}
|
||||
|
||||
public void testList() throws Exception {
|
||||
for (ComputeMetadata node : context.getComputeService().listNodes()) {
|
||||
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();
|
||||
|
@ -147,7 +173,7 @@ public class TerremarkVCloudComputeServiceLiveTest {
|
|||
@AfterTest
|
||||
void cleanup() throws InterruptedException, ExecutionException, TimeoutException {
|
||||
if (node != null)
|
||||
context.getComputeService().destroyNode(node);
|
||||
client.destroyNode(node);
|
||||
context.close();
|
||||
}
|
||||
}
|
|
@ -67,6 +67,32 @@
|
|||
</layout>
|
||||
</appender>
|
||||
|
||||
<!-- A time/date based rolling appender -->
|
||||
<appender name="COMPUTEFILE" class="org.apache.log4j.DailyRollingFileAppender">
|
||||
<param name="File" value="target/test-data/jclouds-compute.log" />
|
||||
<param name="Append" value="true" />
|
||||
|
||||
<!-- Rollover at midnight each day -->
|
||||
<param name="DatePattern" value="'.'yyyy-MM-dd" />
|
||||
|
||||
<param name="Threshold" value="TRACE" />
|
||||
|
||||
<layout class="org.apache.log4j.PatternLayout">
|
||||
<!-- The default pattern: Date Priority [Category] Message\n -->
|
||||
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
|
||||
|
||||
<!--
|
||||
The full pattern: Date MS Priority [Category] (Thread:NDC) Message\n
|
||||
<param name="ConversionPattern" value="%d %-5r %-5p [%c] (%t:%x)
|
||||
%m%n"/>
|
||||
-->
|
||||
</layout>
|
||||
</appender>
|
||||
|
||||
<appender name="ASYNCCOMPUTE" class="org.apache.log4j.AsyncAppender">
|
||||
<appender-ref ref="COMPUTEFILE" />
|
||||
</appender>
|
||||
|
||||
<appender name="ASYNC" class="org.apache.log4j.AsyncAppender">
|
||||
<appender-ref ref="FILE" />
|
||||
</appender>
|
||||
|
@ -93,6 +119,11 @@
|
|||
<priority value="DEBUG" />
|
||||
<appender-ref ref="ASYNCWIRE" />
|
||||
</category>
|
||||
|
||||
<category name="jclouds.compute">
|
||||
<priority value="TRACE" />
|
||||
<appender-ref ref="ASYNCCOMPUTE" />
|
||||
</category>
|
||||
<!--======================= -->
|
||||
<!-- Setup the Root category -->
|
||||
<!-- ======================= -->
|
||||
|
|
Loading…
Reference in New Issue