Issue 130: added rackspace and cleaned up builder concepts

git-svn-id: http://jclouds.googlecode.com/svn/trunk@2721 3d8758e0-26b5-11de-8745-db77d3ebf521
This commit is contained in:
adrian.f.cole 2010-01-22 20:39:23 +00:00
parent 28aadccb49
commit aa41f4512b
55 changed files with 1308 additions and 355 deletions

View File

@ -36,6 +36,8 @@ import javax.inject.Singleton;
import org.jclouds.aws.AWSResponseException; import org.jclouds.aws.AWSResponseException;
import org.jclouds.aws.domain.Region; import org.jclouds.aws.domain.Region;
import org.jclouds.aws.ec2.EC2Client; import org.jclouds.aws.ec2.EC2Client;
import org.jclouds.aws.ec2.compute.domain.EC2Image;
import org.jclouds.aws.ec2.compute.domain.EC2Size;
import org.jclouds.aws.ec2.domain.InstanceState; import org.jclouds.aws.ec2.domain.InstanceState;
import org.jclouds.aws.ec2.domain.IpProtocol; import org.jclouds.aws.ec2.domain.IpProtocol;
import org.jclouds.aws.ec2.domain.KeyPair; import org.jclouds.aws.ec2.domain.KeyPair;
@ -46,7 +48,6 @@ import org.jclouds.compute.domain.ComputeMetadata;
import org.jclouds.compute.domain.ComputeType; import org.jclouds.compute.domain.ComputeType;
import org.jclouds.compute.domain.CreateNodeResponse; import org.jclouds.compute.domain.CreateNodeResponse;
import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.LoginType;
import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.NodeState; import org.jclouds.compute.domain.NodeState;
import org.jclouds.compute.domain.Size; import org.jclouds.compute.domain.Size;
@ -146,9 +147,9 @@ public class EC2ComputeService implements ComputeService {
: ImmutableSet.<InetAddress> of(runningInstance.getPrivateIpAddress()); : ImmutableSet.<InetAddress> of(runningInstance.getPrivateIpAddress());
return new CreateNodeResponseImpl(runningInstance.getId(), name, runningInstance.getRegion() return new CreateNodeResponseImpl(runningInstance.getId(), name, runningInstance.getRegion()
.toString(), null, ImmutableMap.<String, String> of(), instanceToNodeState .toString(), null, ImmutableMap.<String, String> of(), instanceToNodeState
.get(runningInstance.getInstanceState()), publicAddresses, privateAddresses, 22, .get(runningInstance.getInstanceState()), publicAddresses, privateAddresses,
LoginType.SSH, new Credentials("root", keyPair.getKeyMaterial()), ImmutableMap
new Credentials("root", keyPair.getKeyMaterial()), ImmutableMap.<String, String> of()); .<String, String> of());
} }
private KeyPair createKeyPairInRegion(Region region, String name) { private KeyPair createKeyPairInRegion(Region region, String name) {
@ -213,9 +214,8 @@ public class EC2ComputeService implements ComputeService {
return new NodeMetadataImpl(from.getId(), from.getKeyName(), from.getRegion().toString(), return new NodeMetadataImpl(from.getId(), from.getKeyName(), from.getRegion().toString(),
null, ImmutableMap.<String, String> of(), instanceToNodeState.get(from null, ImmutableMap.<String, String> of(), instanceToNodeState.get(from
.getInstanceState()), nullSafeSet(from.getIpAddress()), nullSafeSet(from .getInstanceState()), nullSafeSet(from.getIpAddress()), nullSafeSet(from
.getPrivateIpAddress()), 22, LoginType.SSH, ImmutableMap .getPrivateIpAddress()), ImmutableMap.<String, String> of(
.<String, String> of("availabilityZone", from.getAvailabilityZone() "availabilityZone", from.getAvailabilityZone().toString()));
.toString()));
} }
Set<InetAddress> nullSafeSet(InetAddress in) { Set<InetAddress> nullSafeSet(InetAddress in) {

View File

@ -37,13 +37,13 @@ import org.jclouds.aws.ec2.EC2;
import org.jclouds.aws.ec2.EC2AsyncClient; import org.jclouds.aws.ec2.EC2AsyncClient;
import org.jclouds.aws.ec2.EC2Client; import org.jclouds.aws.ec2.EC2Client;
import org.jclouds.aws.ec2.compute.EC2ComputeService; import org.jclouds.aws.ec2.compute.EC2ComputeService;
import org.jclouds.aws.ec2.compute.EC2Image; import org.jclouds.aws.ec2.compute.domain.EC2Image;
import org.jclouds.aws.ec2.compute.EC2Size; import org.jclouds.aws.ec2.compute.domain.EC2Size;
import org.jclouds.aws.ec2.config.EC2ContextModule; import org.jclouds.aws.ec2.config.EC2ContextModule;
import org.jclouds.compute.ComputeService; import org.jclouds.compute.ComputeService;
import org.jclouds.compute.ComputeServiceContext; import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.OperatingSystem; import org.jclouds.compute.domain.OsFamily;
import org.jclouds.compute.domain.Size; import org.jclouds.compute.domain.Size;
import org.jclouds.compute.internal.ComputeServiceContextImpl; import org.jclouds.compute.internal.ComputeServiceContextImpl;
import org.jclouds.compute.reference.ComputeServiceConstants; import org.jclouds.compute.reference.ComputeServiceConstants;
@ -108,21 +108,21 @@ public class EC2ComputeServiceContextModule extends EC2ContextModule {
for (final Region region : regionMap.keySet()) { for (final Region region : regionMap.keySet()) {
for (final org.jclouds.aws.ec2.domain.Image from : sync.getAMIServices() for (final org.jclouds.aws.ec2.domain.Image from : sync.getAMIServices()
.describeImagesInRegion(region, ownedBy("063491364108"))) { .describeImagesInRegion(region, ownedBy("063491364108"))) {
OperatingSystem os = null; OsFamily os = null;
String osVersion = ""; String osDescription = "";
String version = ""; String version = "";
Matcher matcher = ALESTIC_PATTERN.matcher(from.getImageLocation()); Matcher matcher = ALESTIC_PATTERN.matcher(from.getImageLocation());
if (matcher.find()) { if (matcher.find()) {
try { try {
os = OperatingSystem.fromValue(matcher.group(1)); os = OsFamily.fromValue(matcher.group(1));
osVersion = matcher.group(2); osDescription = matcher.group(2);
version = matcher.group(3); version = matcher.group(3);
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
holder.logger.debug("<< didn't match os(%s)", matcher.group(1)); holder.logger.debug("<< didn't match os(%s)", matcher.group(1));
} }
} }
images.add(new EC2Image(from, os, osVersion, version)); images.add(new EC2Image(from, os, osDescription, version));
} }
} }
holder.logger.debug("<< images(%d)", images.size()); holder.logger.debug("<< images(%d)", images.size());

View File

@ -21,11 +21,11 @@
* under the License. * under the License.
* ==================================================================== * ====================================================================
*/ */
package org.jclouds.aws.ec2.compute; package org.jclouds.aws.ec2.compute.domain;
import org.jclouds.compute.domain.Architecture; import org.jclouds.compute.domain.Architecture;
import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.OperatingSystem; import org.jclouds.compute.domain.OsFamily;
/** /**
* *
@ -33,15 +33,15 @@ import org.jclouds.compute.domain.OperatingSystem;
*/ */
public class EC2Image implements Image { public class EC2Image implements Image {
private final org.jclouds.aws.ec2.domain.Image image; private final org.jclouds.aws.ec2.domain.Image image;
private final OperatingSystem os; private final OsFamily os;
private final String osVersion; private final String osDescription;
private final String version; private final String version;
public EC2Image(org.jclouds.aws.ec2.domain.Image image, OperatingSystem os, String osVersion, public EC2Image(org.jclouds.aws.ec2.domain.Image image, OsFamily os, String osDescription,
String version) { String version) {
this.image = image; this.image = image;
this.os = os; this.os = os;
this.osVersion = osVersion; this.osDescription = osDescription;
this.version = version; this.version = version;
} }
@ -67,13 +67,13 @@ public class EC2Image implements Image {
} }
@Override @Override
public OperatingSystem getOperatingSystem() { public OsFamily getOsFamily() {
return os; return os;
} }
@Override @Override
public String getOperatingSystemVersion() { public String getOsDescription() {
return osVersion; return osDescription;
} }
@Override @Override
@ -91,7 +91,7 @@ public class EC2Image implements Image {
int result = 1; int result = 1;
result = prime * result + ((image == null) ? 0 : image.hashCode()); result = prime * result + ((image == null) ? 0 : image.hashCode());
result = prime * result + ((os == null) ? 0 : os.hashCode()); result = prime * result + ((os == null) ? 0 : os.hashCode());
result = prime * result + ((osVersion == null) ? 0 : osVersion.hashCode()); result = prime * result + ((osDescription == null) ? 0 : osDescription.hashCode());
result = prime * result + ((version == null) ? 0 : version.hashCode()); result = prime * result + ((version == null) ? 0 : version.hashCode());
return result; return result;
} }
@ -115,10 +115,10 @@ public class EC2Image implements Image {
return false; return false;
} else if (!os.equals(other.os)) } else if (!os.equals(other.os))
return false; return false;
if (osVersion == null) { if (osDescription == null) {
if (other.osVersion != null) if (other.osDescription != null)
return false; return false;
} else if (!osVersion.equals(other.osVersion)) } else if (!osDescription.equals(other.osDescription))
return false; return false;
if (version == null) { if (version == null) {
if (other.version != null) if (other.version != null)
@ -132,7 +132,7 @@ public class EC2Image implements Image {
public String toString() { public String toString() {
return "[id=" + getId() + ", version=" + version + ", location=" + getLocation() return "[id=" + getId() + ", version=" + version + ", location=" + getLocation()
+ ", architecture=" + getArchitecture() + ", operatingSystem=" + ", architecture=" + getArchitecture() + ", operatingSystem="
+ getOperatingSystem() + ", operatingSystemVersion=" + getOperatingSystemVersion() + getOsFamily() + ", operatingSystemVersion=" + getOsDescription()
+ ", description=" + getDescription() + "]"; + ", description=" + getDescription() + "]";
} }

View File

@ -21,7 +21,7 @@
* under the License. * under the License.
* ==================================================================== * ====================================================================
*/ */
package org.jclouds.aws.ec2.compute; package org.jclouds.aws.ec2.compute.domain;
import org.jclouds.aws.ec2.domain.InstanceType; import org.jclouds.aws.ec2.domain.InstanceType;
import org.jclouds.compute.domain.Architecture; import org.jclouds.compute.domain.Architecture;

View File

@ -18,7 +18,7 @@
*/ */
package org.jclouds.aws.ec2.compute; package org.jclouds.aws.ec2.compute;
import static org.jclouds.compute.domain.OperatingSystem.UBUNTU; import static org.jclouds.compute.domain.OsFamily.UBUNTU;
import org.jclouds.compute.BaseComputeServiceLiveTest; import org.jclouds.compute.BaseComputeServiceLiveTest;
import org.jclouds.compute.domain.Template; import org.jclouds.compute.domain.Template;
@ -42,7 +42,7 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest {
} }
protected Template buildTemplate(TemplateBuilder templateBuilder) { protected Template buildTemplate(TemplateBuilder templateBuilder) {
return templateBuilder.os(UBUNTU).smallest().build(); return templateBuilder.osFamily(UBUNTU).smallest().build();
} }
@Override @Override

View File

@ -35,6 +35,8 @@ import java.io.UnsupportedEncodingException;
import java.util.Date; import java.util.Date;
import java.util.SortedSet; import java.util.SortedSet;
import javax.ws.rs.core.MediaType;
import org.jclouds.blobstore.ContainerNotFoundException; import org.jclouds.blobstore.ContainerNotFoundException;
import org.jclouds.blobstore.domain.Blob; import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.domain.BlobMetadata; import org.jclouds.blobstore.domain.BlobMetadata;
@ -321,7 +323,7 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest {
Blob object = context.getBlobStore().newBlob(key); Blob object = context.getBlobStore().newBlob(key);
object.setPayload(TEST_STRING); object.setPayload(TEST_STRING);
object.getMetadata().setContentType("text/plain"); object.getMetadata().setContentType(MediaType.TEXT_PLAIN);
object.getMetadata().setSize(new Long(TEST_STRING.length())); object.getMetadata().setSize(new Long(TEST_STRING.length()));
// NOTE all metadata in jclouds comes out as lowercase, in an effort to normalize the // NOTE all metadata in jclouds comes out as lowercase, in an effort to normalize the
// providers. // providers.

View File

@ -44,12 +44,12 @@ public interface Image {
/** /**
* Operating System * Operating System
*/ */
OperatingSystem getOperatingSystem(); OsFamily getOsFamily();
/** /**
* Version of the operating system * Description of the operating system including the version.
*/ */
String getOperatingSystemVersion(); String getOsDescription();
/** /**
* Version of the image * Version of the image

View File

@ -33,10 +33,6 @@ public interface NodeMetadata extends ComputeMetadata {
SortedSet<InetAddress> getPrivateAddresses(); SortedSet<InetAddress> getPrivateAddresses();
int getLoginPort();
LoginType getLoginType();
/** /**
* Other variables present that the provider supports * Other variables present that the provider supports
*/ */

View File

@ -39,6 +39,14 @@ public enum NodeState {
/** /**
* The node is available for requests * The node is available for requests
*/ */
RUNNING; RUNNING,
/**
* There is an error on the node
*/
ERROR,
/**
* The state of the node is unknown.
*/
UNKNOWN;
} }

View File

@ -32,7 +32,7 @@ import com.google.common.base.CaseFormat;
* *
* @author Adrian Cole * @author Adrian Cole
*/ */
public enum OperatingSystem { public enum OsFamily {
CENTOS, RHEL, FEDORA, DEBIAN, UBUNTU, JEOS, WINDOWS; CENTOS, RHEL, FEDORA, DEBIAN, UBUNTU, JEOS, WINDOWS;
public String value() { public String value() {
return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_HYPHEN, name()); return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_HYPHEN, name());
@ -43,7 +43,7 @@ public enum OperatingSystem {
return value(); return value();
} }
public static OperatingSystem fromValue(String operatingSystem) { public static OsFamily fromValue(String operatingSystem) {
return valueOf(CaseFormat.LOWER_HYPHEN.to(CaseFormat.UPPER_UNDERSCORE, checkNotNull( return valueOf(CaseFormat.LOWER_HYPHEN.to(CaseFormat.UPPER_UNDERSCORE, checkNotNull(
operatingSystem, "region"))); operatingSystem, "region")));
} }

View File

@ -67,7 +67,7 @@ public interface TemplateBuilder {
/** /**
* Configure this template to use a specific operating system image. * Configure this template to use a specific operating system image.
*/ */
TemplateBuilder os(OperatingSystem os); TemplateBuilder osFamily(OsFamily os);
/** /**
* Configure this template to start in a specific location * Configure this template to start in a specific location
@ -92,10 +92,10 @@ public interface TemplateBuilder {
TemplateBuilder sizeId(String sizeId); TemplateBuilder sizeId(String sizeId);
/** /**
* Configure this template to have an operating system version that matches the regular * Configure this template to have an operating system description that matches the regular
* expression * expression
*/ */
TemplateBuilder osVersionMatches(String osVersionRegex); TemplateBuilder osDescriptionMatches(String osDescriptionRegex);
/** /**
* Configure this template to have an image version that matches the regular expression * Configure this template to have an image version that matches the regular expression

View File

@ -23,7 +23,6 @@ import java.net.URI;
import java.util.Map; import java.util.Map;
import org.jclouds.compute.domain.CreateNodeResponse; import org.jclouds.compute.domain.CreateNodeResponse;
import org.jclouds.compute.domain.LoginType;
import org.jclouds.compute.domain.NodeState; import org.jclouds.compute.domain.NodeState;
import org.jclouds.domain.Credentials; import org.jclouds.domain.Credentials;
@ -41,9 +40,8 @@ public class CreateNodeResponseImpl extends NodeMetadataImpl implements CreateNo
public CreateNodeResponseImpl(String id, String name, String location, URI uri, public CreateNodeResponseImpl(String id, String name, String location, URI uri,
Map<String, String> userMetadata, NodeState state, Map<String, String> userMetadata, NodeState state,
Iterable<InetAddress> publicAddresses, Iterable<InetAddress> privateAddresses, Iterable<InetAddress> publicAddresses, Iterable<InetAddress> privateAddresses,
int loginPort, LoginType loginType, Credentials credentials, Map<String, String> extra) { Credentials credentials, Map<String, String> extra) {
super(id, name, location, uri, userMetadata, state, publicAddresses, privateAddresses, super(id, name, location, uri, userMetadata, state, publicAddresses, privateAddresses, extra);
loginPort, loginType, extra);
this.credentials = credentials; this.credentials = credentials;
} }

View File

@ -25,7 +25,7 @@ package org.jclouds.compute.domain.internal;
import org.jclouds.compute.domain.Architecture; import org.jclouds.compute.domain.Architecture;
import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.OperatingSystem; import org.jclouds.compute.domain.OsFamily;
/** /**
* @author Adrian Cole * @author Adrian Cole
@ -35,7 +35,7 @@ public class ImageImpl implements Image {
private final String id; private final String id;
private final String description; private final String description;
private final String version; private final String version;
private final OperatingSystem operatingSystem; private final OsFamily operatingSystem;
private final String operatingSystemVersion; private final String operatingSystemVersion;
private final String location; private final String location;
private final Architecture architecture; private final Architecture architecture;
@ -56,7 +56,7 @@ public class ImageImpl implements Image {
return result; return result;
} }
public ImageImpl(String id, String description, String version, OperatingSystem operatingSystem, public ImageImpl(String id, String description, String version, OsFamily operatingSystem,
String operatingSystemVersion, String location, Architecture architecture) { String operatingSystemVersion, String location, Architecture architecture) {
this.id = id; this.id = id;
this.description = description; this.description = description;
@ -140,7 +140,7 @@ public class ImageImpl implements Image {
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override @Override
public OperatingSystem getOperatingSystem() { public OsFamily getOsFamily() {
return operatingSystem; return operatingSystem;
} }
@ -172,7 +172,7 @@ public class ImageImpl implements Image {
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override @Override
public String getOperatingSystemVersion() { public String getOsDescription() {
return operatingSystemVersion; return operatingSystemVersion;
} }

View File

@ -25,7 +25,6 @@ import java.util.Map;
import java.util.SortedSet; import java.util.SortedSet;
import org.jclouds.compute.domain.ComputeType; import org.jclouds.compute.domain.ComputeType;
import org.jclouds.compute.domain.LoginType;
import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.NodeState; import org.jclouds.compute.domain.NodeState;
@ -53,19 +52,15 @@ public class NodeMetadataImpl extends ComputeMetadataImpl implements NodeMetadat
private final SortedSet<InetAddress> publicAddresses = Sets.newTreeSet(ADDRESS_COMPARATOR); private final SortedSet<InetAddress> publicAddresses = Sets.newTreeSet(ADDRESS_COMPARATOR);
private final SortedSet<InetAddress> privateAddresses = Sets.newTreeSet(ADDRESS_COMPARATOR); private final SortedSet<InetAddress> privateAddresses = Sets.newTreeSet(ADDRESS_COMPARATOR);
private final Map<String, String> extra = Maps.newLinkedHashMap(); private final Map<String, String> extra = Maps.newLinkedHashMap();
private final int loginPort;
private final LoginType loginType;
public NodeMetadataImpl(String id, String name, String location, URI uri, public NodeMetadataImpl(String id, String name, String location, URI uri,
Map<String, String> userMetadata, NodeState state, Map<String, String> userMetadata, NodeState state,
Iterable<InetAddress> publicAddresses, Iterable<InetAddress> privateAddresses, Iterable<InetAddress> publicAddresses, Iterable<InetAddress> privateAddresses,
int loginPort, LoginType loginType, Map<String, String> extra) { Map<String, String> extra) {
super(ComputeType.NODE, id, name, location, uri, userMetadata); super(ComputeType.NODE, id, name, location, uri, userMetadata);
this.state = state; this.state = state;
Iterables.addAll(this.publicAddresses, publicAddresses); Iterables.addAll(this.publicAddresses, publicAddresses);
Iterables.addAll(this.privateAddresses, privateAddresses); Iterables.addAll(this.privateAddresses, privateAddresses);
this.loginPort = loginPort;
this.loginType = loginType;
this.extra.putAll(extra); this.extra.putAll(extra);
} }
@ -83,20 +78,6 @@ public class NodeMetadataImpl extends ComputeMetadataImpl implements NodeMetadat
return privateAddresses; return privateAddresses;
} }
/**
* {@inheritDoc}
*/
public int getLoginPort() {
return loginPort;
}
/**
* {@inheritDoc}
*/
public LoginType getLoginType() {
return loginType;
}
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@ -125,8 +106,6 @@ public class NodeMetadataImpl extends ComputeMetadataImpl implements NodeMetadat
final int prime = 31; final int prime = 31;
int result = super.hashCode(); int result = super.hashCode();
result = prime * result + ((extra == null) ? 0 : extra.hashCode()); result = prime * result + ((extra == null) ? 0 : extra.hashCode());
result = prime * result + loginPort;
result = prime * result + ((loginType == null) ? 0 : loginType.hashCode());
result = prime * result + ((privateAddresses == null) ? 0 : privateAddresses.hashCode()); result = prime * result + ((privateAddresses == null) ? 0 : privateAddresses.hashCode());
result = prime * result + ((publicAddresses == null) ? 0 : publicAddresses.hashCode()); result = prime * result + ((publicAddresses == null) ? 0 : publicAddresses.hashCode());
result = prime * result + ((state == null) ? 0 : state.hashCode()); result = prime * result + ((state == null) ? 0 : state.hashCode());
@ -147,13 +126,6 @@ public class NodeMetadataImpl extends ComputeMetadataImpl implements NodeMetadat
return false; return false;
} else if (!extra.equals(other.extra)) } else if (!extra.equals(other.extra))
return false; return false;
if (loginPort != other.loginPort)
return false;
if (loginType == null) {
if (other.loginType != null)
return false;
} else if (!loginType.equals(other.loginType))
return false;
if (privateAddresses == null) { if (privateAddresses == null) {
if (other.privateAddresses != null) if (other.privateAddresses != null)
return false; return false;

View File

@ -9,7 +9,7 @@ import javax.inject.Named;
import org.jclouds.compute.domain.Architecture; import org.jclouds.compute.domain.Architecture;
import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.OperatingSystem; import org.jclouds.compute.domain.OsFamily;
import org.jclouds.compute.domain.Size; import org.jclouds.compute.domain.Size;
import org.jclouds.compute.domain.Template; import org.jclouds.compute.domain.Template;
import org.jclouds.compute.domain.TemplateBuilder; import org.jclouds.compute.domain.TemplateBuilder;
@ -40,12 +40,12 @@ public class TemplateBuilderImpl implements TemplateBuilder {
private final Set<? extends Image> images; private final Set<? extends Image> images;
private final Set<? extends Size> sizes; private final Set<? extends Size> sizes;
private String location; private String location;
private OperatingSystem os; private OsFamily os;
private Architecture arch; private Architecture arch;
private String imageId; private String imageId;
private String sizeId; private String sizeId;
private String osVersion; private String osDescription;
private String imageVersion; private String imageVersion;
private String imageDescription; private String imageDescription;
@ -94,7 +94,7 @@ public class TemplateBuilderImpl implements TemplateBuilder {
public boolean apply(Image input) { public boolean apply(Image input) {
boolean returnVal = true; boolean returnVal = true;
if (os != null) if (os != null)
returnVal = os.equals(input.getOperatingSystem()); returnVal = os.equals(input.getOsFamily());
return returnVal; return returnVal;
} }
@ -110,15 +110,15 @@ public class TemplateBuilderImpl implements TemplateBuilder {
} }
}; };
private final Predicate<Image> osVersionPredicate = new Predicate<Image>() { private final Predicate<Image> osDescriptionPredicate = new Predicate<Image>() {
@Override @Override
public boolean apply(Image input) { public boolean apply(Image input) {
boolean returnVal = true; boolean returnVal = true;
if (osVersion != null) { if (osDescription != null) {
if (input.getOperatingSystemVersion() == null) if (input.getOsDescription() == null)
returnVal = false; returnVal = false;
else else
returnVal = input.getOperatingSystemVersion().matches(osVersion); returnVal = input.getOsDescription().matches(osDescription);
} }
return returnVal; return returnVal;
} }
@ -166,7 +166,7 @@ public class TemplateBuilderImpl implements TemplateBuilder {
}; };
private final Predicate<Image> imagePredicate = Predicates.and(imageIdPredicate, private final Predicate<Image> imagePredicate = Predicates.and(imageIdPredicate,
locationPredicate, osPredicate, imageArchPredicate, osVersionPredicate, locationPredicate, osPredicate, imageArchPredicate, osDescriptionPredicate,
imageVersionPredicate, imageDescriptionPredicate); imageVersionPredicate, imageDescriptionPredicate);
private final Predicate<Size> sizeArchPredicate = new Predicate<Size>() { private final Predicate<Size> sizeArchPredicate = new Predicate<Size>() {
@ -208,8 +208,8 @@ public class TemplateBuilderImpl implements TemplateBuilder {
}; };
static final Ordering<Image> DEFAULT_IMAGE_ORDERING = new Ordering<Image>() { static final Ordering<Image> DEFAULT_IMAGE_ORDERING = new Ordering<Image>() {
public int compare(Image left, Image right) { public int compare(Image left, Image right) {
return ComparisonChain.start().compare(left.getOperatingSystemVersion(), return ComparisonChain.start().compare(left.getOsDescription(),
right.getOperatingSystemVersion()).compare(left.getVersion(), right.getVersion()) right.getOsDescription()).compare(left.getVersion(), right.getVersion())
.result(); .result();
} }
}; };
@ -241,10 +241,10 @@ public class TemplateBuilderImpl implements TemplateBuilder {
public TemplateBuilder fromImage(Image image) { public TemplateBuilder fromImage(Image image) {
if (image.getLocation() != null) if (image.getLocation() != null)
this.location = image.getLocation(); this.location = image.getLocation();
if (image.getOperatingSystem() != null) if (image.getOsFamily() != null)
this.os = image.getOperatingSystem(); this.os = image.getOsFamily();
if (image.getOperatingSystemVersion() != null) if (image.getOsDescription() != null)
this.osVersion = image.getOperatingSystemVersion(); this.osDescription = image.getOsDescription();
if (image.getVersion() != null) if (image.getVersion() != null)
this.imageVersion = image.getVersion(); this.imageVersion = image.getVersion();
if (image.getArchitecture() != null) if (image.getArchitecture() != null)
@ -292,7 +292,7 @@ public class TemplateBuilderImpl implements TemplateBuilder {
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override @Override
public TemplateBuilder os(OperatingSystem os) { public TemplateBuilder osFamily(OsFamily os) {
this.os = os; this.os = os;
return this; return this;
} }
@ -387,8 +387,8 @@ public class TemplateBuilderImpl implements TemplateBuilder {
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override @Override
public TemplateBuilder osVersionMatches(String osVersionRegex) { public TemplateBuilder osDescriptionMatches(String osDescriptionRegex) {
this.osVersion = osVersionRegex; this.osDescription = osDescriptionRegex;
return this; return this;
} }
@ -406,7 +406,7 @@ public class TemplateBuilderImpl implements TemplateBuilder {
return "[arch=" + arch + ", biggest=" + biggest + ", fastest=" + fastest return "[arch=" + arch + ", biggest=" + biggest + ", fastest=" + fastest
+ ", imageDescription=" + imageDescription + ", imageId=" + imageId + ", imageDescription=" + imageDescription + ", imageId=" + imageId
+ ", imageVersion=" + imageVersion + ", location=" + location + ", minCores=" + ", imageVersion=" + imageVersion + ", location=" + location + ", minCores="
+ minCores + ", minRam=" + minRam + ", os=" + os + ", osVersion=" + osVersion + minCores + ", minRam=" + minRam + ", os=" + os + ", osDescription=" + osDescription
+ ", sizeId=" + sizeId + "]"; + ", sizeId=" + sizeId + "]";
} }

View File

@ -18,17 +18,41 @@
*/ */
package org.jclouds.compute.util; package org.jclouds.compute.util;
import static com.google.common.base.Preconditions.checkState;
import java.io.ByteArrayInputStream;
import java.net.InetSocketAddress;
import javax.annotation.Resource;
import javax.inject.Named;
import org.jclouds.compute.domain.ComputeMetadata; import org.jclouds.compute.domain.ComputeMetadata;
import org.jclouds.compute.domain.CreateNodeResponse; import org.jclouds.compute.domain.CreateNodeResponse;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.logging.Logger;
import org.jclouds.ssh.SshClient;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import com.google.inject.Inject;
/** /**
* *
* @author Adrian Cole * @author Adrian Cole
*/ */
public class ComputeUtils { public class ComputeUtils {
@Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL;
@Inject(optional = true)
private SshClient.Factory sshFactory;
private final Predicate<InetSocketAddress> socketTester;
@Inject
public ComputeUtils(Predicate<InetSocketAddress> socketTester) {
this.socketTester = socketTester;
}
public static Iterable<? extends ComputeMetadata> filterByName( public static Iterable<? extends ComputeMetadata> filterByName(
Iterable<? extends ComputeMetadata> nodes, final String name) { Iterable<? extends ComputeMetadata> nodes, final String name) {
return Iterables.filter(nodes, new Predicate<ComputeMetadata>() { return Iterables.filter(nodes, new Predicate<ComputeMetadata>() {
@ -39,6 +63,37 @@ public class ComputeUtils {
}); });
} }
public void runScriptOnNode(CreateNodeResponse node, byte[] script) {
checkState(this.sshFactory != null, "runScript requested, but no SshModule configured");
InetSocketAddress socket = new InetSocketAddress(node.getPublicAddresses().last(), 22);
socketTester.apply(socket);
SshClient ssh = isKeyAuth(node) ? sshFactory.create(socket, node.getCredentials().account,
node.getCredentials().key.getBytes()) : sshFactory.create(socket, node
.getCredentials().account, node.getCredentials().key);
try {
ssh.connect();
String scriptName = node.getId() + ".sh";
ssh.put(scriptName, new ByteArrayInputStream(script));
ssh.exec("chmod 755 " + scriptName);
if (node.getCredentials().account.equals("root")) {
logger.debug(">> running %s as %s", scriptName, node.getCredentials().account);
logger.debug("<< complete(%d)", ssh.exec("./" + scriptName).getExitCode());
} else if (isKeyAuth(node)) {
logger.debug(">> running sudo %s as %s", scriptName, node.getCredentials().account);
logger.debug("<< complete(%d)", ssh.exec("sudo ./" + scriptName).getExitCode());
} else {
logger.debug(">> running sudo -S %s as %s", scriptName, node.getCredentials().account);
logger.debug("<< complete(%d)", ssh.exec(
String.format("echo %s|sudo -S ./%s", node.getCredentials().key, scriptName))
.getExitCode());
}
} finally {
if (ssh != null)
ssh.disconnect();
}
}
public static boolean isKeyAuth(CreateNodeResponse createdNode) { public static boolean isKeyAuth(CreateNodeResponse createdNode) {
return createdNode.getCredentials().key.startsWith("-----BEGIN RSA PRIVATE KEY-----"); return createdNode.getCredentials().key.startsWith("-----BEGIN RSA PRIVATE KEY-----");
} }

View File

@ -24,5 +24,7 @@ hostingdotcom.contextbuilder=org.jclouds.vcloud.hostingdotcom.compute.HostingDot
hostingdotcom.propertiesbuilder=org.jclouds.vcloud.hostingdotcom.HostingDotComVCloudPropertiesBuilder hostingdotcom.propertiesbuilder=org.jclouds.vcloud.hostingdotcom.HostingDotComVCloudPropertiesBuilder
ec2.contextbuilder=org.jclouds.aws.ec2.compute.EC2ComputeServiceContextBuilder ec2.contextbuilder=org.jclouds.aws.ec2.compute.EC2ComputeServiceContextBuilder
ec2.propertiesbuilder=org.jclouds.aws.ec2.EC2PropertiesBuilder ec2.propertiesbuilder=org.jclouds.aws.ec2.EC2PropertiesBuilder
cloudservers.contextbuilder=org.jclouds.rackspace.cloudservers.compute.CloudServersComputeServiceContextBuilder
cloudservers.propertiesbuilder=org.jclouds.rackspace.RackspacePropertiesBuilder
# example of where to change your endpoint # example of where to change your endpoint
# ec2.endpoint=https://ec2.us-west-1.amazonaws.com # ec2.endpoint=https://ec2.us-west-1.amazonaws.com

View File

@ -33,9 +33,8 @@ import org.jclouds.compute.domain.ComputeMetadata;
import org.jclouds.compute.domain.ComputeType; import org.jclouds.compute.domain.ComputeType;
import org.jclouds.compute.domain.CreateNodeResponse; import org.jclouds.compute.domain.CreateNodeResponse;
import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.LoginType;
import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.OperatingSystem; import org.jclouds.compute.domain.OsFamily;
import org.jclouds.compute.domain.Size; import org.jclouds.compute.domain.Size;
import org.jclouds.compute.domain.Template; import org.jclouds.compute.domain.Template;
import org.jclouds.compute.domain.TemplateBuilder; import org.jclouds.compute.domain.TemplateBuilder;
@ -45,7 +44,6 @@ import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.predicates.RetryablePredicate; import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.predicates.SocketOpen; import org.jclouds.predicates.SocketOpen;
import org.jclouds.scriptbuilder.ScriptBuilder; import org.jclouds.scriptbuilder.ScriptBuilder;
import org.jclouds.scriptbuilder.domain.OsFamily;
import org.jclouds.scriptbuilder.domain.Statements; import org.jclouds.scriptbuilder.domain.Statements;
import org.jclouds.ssh.ExecResponse; import org.jclouds.ssh.ExecResponse;
import org.jclouds.ssh.SshClient; import org.jclouds.ssh.SshClient;
@ -101,13 +99,13 @@ public abstract class BaseComputeServiceLiveTest {
} }
private boolean canRunScript(Template template) { private boolean canRunScript(Template template) {
return template.getImage().getOperatingSystem() == OperatingSystem.UBUNTU return template.getImage().getOsFamily() == OsFamily.UBUNTU
|| template.getImage().getOperatingSystem() == OperatingSystem.JEOS; || template.getImage().getOsFamily() == OsFamily.JEOS;
} }
abstract protected Module getSshModule(); abstract protected Module getSshModule();
@Test(enabled = false) @Test(enabled = true)
public void testCreate() throws Exception { public void testCreate() throws Exception {
try { try {
client.destroyNode(Iterables.find(client.listNodes(), new Predicate<ComputeMetadata>() { client.destroyNode(Iterables.find(client.listNodes(), new Predicate<ComputeMetadata>() {
@ -133,11 +131,9 @@ public abstract class BaseComputeServiceLiveTest {
.addStatement(Statements.exec("apt-get install -y openjdk-6-jdk"))// .addStatement(Statements.exec("apt-get install -y openjdk-6-jdk"))//
.addStatement(Statements.exec("wget -qO/usr/bin/runurl run.alestic.com/runurl"))// .addStatement(Statements.exec("wget -qO/usr/bin/runurl run.alestic.com/runurl"))//
.addStatement(Statements.exec("chmod 755 /usr/bin/runurl"))// .addStatement(Statements.exec("chmod 755 /usr/bin/runurl"))//
.build(OsFamily.UNIX).getBytes()); .build(org.jclouds.scriptbuilder.domain.OsFamily.UNIX).getBytes());
node = client.runNode(nodeName, template, options); node = client.runNode(nodeName, template, options);
assertNotNull(node.getId()); assertNotNull(node.getId());
assertEquals(node.getLoginPort(), 22);
assertEquals(node.getLoginType(), LoginType.SSH);
assertNotNull(node.getName()); assertNotNull(node.getName());
assertEquals(node.getPublicAddresses().size(), 1); assertEquals(node.getPublicAddresses().size(), 1);
assertNotNull(node.getCredentials()); assertNotNull(node.getCredentials());
@ -148,12 +144,10 @@ public abstract class BaseComputeServiceLiveTest {
protected abstract Template buildTemplate(TemplateBuilder templateBuilder); protected abstract Template buildTemplate(TemplateBuilder templateBuilder);
@Test(enabled = false, dependsOnMethods = "testCreate") @Test(enabled = true, dependsOnMethods = "testCreate")
public void testGet() throws Exception { public void testGet() throws Exception {
NodeMetadata metadata = client.getNodeMetadata(node); NodeMetadata metadata = client.getNodeMetadata(node);
assertEquals(metadata.getId(), node.getId()); assertEquals(metadata.getId(), node.getId());
assertEquals(metadata.getLoginPort(), node.getLoginPort());
assertEquals(metadata.getLoginType(), node.getLoginType());
assertEquals(metadata.getName(), node.getName()); assertEquals(metadata.getName(), node.getName());
assertEquals(metadata.getPrivateAddresses(), node.getPrivateAddresses()); assertEquals(metadata.getPrivateAddresses(), node.getPrivateAddresses());
assertEquals(metadata.getPublicAddresses(), node.getPublicAddresses()); assertEquals(metadata.getPublicAddresses(), node.getPublicAddresses());
@ -176,7 +170,7 @@ public abstract class BaseComputeServiceLiveTest {
public void testListSizes() throws Exception { public void testListSizes() throws Exception {
for (Size size : client.listSizes()) { for (Size size : client.listSizes()) {
assert size.getCores() > 0; assert size.getCores() > 0 : size;
} }
} }
@ -193,8 +187,7 @@ public abstract class BaseComputeServiceLiveTest {
} }
private void doCheckKey() throws IOException { private void doCheckKey() throws IOException {
InetSocketAddress socket = new InetSocketAddress(node.getPublicAddresses().last(), node InetSocketAddress socket = new InetSocketAddress(node.getPublicAddresses().last(), 22);
.getLoginPort());
socketTester.apply(socket); socketTester.apply(socket);
SshClient ssh = node.getCredentials().key.startsWith("-----BEGIN RSA PRIVATE KEY-----") ? sshFactory SshClient ssh = node.getCredentials().key.startsWith("-----BEGIN RSA PRIVATE KEY-----") ? sshFactory
.create(socket, node.getCredentials().account, node.getCredentials().key.getBytes()) .create(socket, node.getCredentials().account, node.getCredentials().key.getBytes())

View File

@ -59,7 +59,7 @@ public interface CloudFilesClient {
* Determine the number of Containers within the account and the total bytes stored. Since the * Determine the number of Containers within the account and the total bytes stored. Since the
* storage system is designed to store large amounts of data, care should be taken when * storage system is designed to store large amounts of data, care should be taken when
* representing the total bytes response as an integer; when possible, convert it to a 64-bit * representing the total bytes response as an integer; when possible, convert it to a 64-bit
* unsigned integer if your platform supports that primitive type. * unsigned integer if your platform supports that primitive flavor.
*/ */
AccountMetadata getAccountStatistics(); AccountMetadata getAccountStatistics();

View File

@ -145,7 +145,7 @@ public class ParseObjectInfoListFromJsonResponse extends
@Override @Override
public String toString() { public String toString() {
return "ObjectInfoImpl [bytes=" + bytes + ", content_type=" + content_type + ", hash=" return "ObjectInfoImpl [bytes=" + bytes + ", content_flavor=" + content_type + ", hash="
+ hash + ", last_modified=" + last_modified.getTime() + ", name=" + name + "]"; + hash + ", last_modified=" + last_modified.getTime() + ", name=" + name + "]";
} }
} }

View File

@ -44,7 +44,7 @@ public class BindRebootTypeToJsonPayload extends BindToJsonPayload {
@Override @Override
public void bindToRequest(HttpRequest request, Object toBind) { public void bindToRequest(HttpRequest request, Object toBind) {
checkArgument(toBind instanceof RebootType, "this binder is only valid for RebootTypes!"); checkArgument(toBind instanceof RebootType, "this binder is only valid for RebootTypes!");
super.bindToRequest(request, ImmutableMap.of("reboot", ImmutableMap.of("type", super.bindToRequest(request, ImmutableMap.of("reboot", ImmutableMap.of("flavor",
checkNotNull(toBind, "type")))); checkNotNull(toBind, "flavor"))));
} }
} }

View File

@ -0,0 +1,220 @@
/**
*
* 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.rackspace.cloudservers.compute;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Map;
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;
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.NodeMetadata;
import org.jclouds.compute.domain.NodeState;
import org.jclouds.compute.domain.Size;
import org.jclouds.compute.domain.Template;
import org.jclouds.compute.domain.TemplateBuilder;
import org.jclouds.compute.domain.internal.CreateNodeResponseImpl;
import org.jclouds.compute.domain.internal.NodeMetadataImpl;
import org.jclouds.compute.options.RunNodeOptions;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.compute.util.ComputeUtils;
import org.jclouds.domain.Credentials;
import org.jclouds.domain.ResourceLocation;
import org.jclouds.logging.Logger;
import org.jclouds.rackspace.cloudservers.CloudServersClient;
import org.jclouds.rackspace.cloudservers.compute.domain.CloudServersImage;
import org.jclouds.rackspace.cloudservers.compute.domain.CloudServersSize;
import org.jclouds.rackspace.cloudservers.domain.Server;
import org.jclouds.rackspace.cloudservers.domain.ServerStatus;
import org.jclouds.rackspace.cloudservers.options.ListOptions;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
/**
* @author Adrian Cole
*/
@Singleton
public class CloudServersComputeService implements ComputeService {
@Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL;
private final org.jclouds.rackspace.cloudservers.CloudServersClient client;
protected final Provider<Set<? extends Image>> images;
protected final Provider<Set<? extends Size>> sizes;
protected final Provider<TemplateBuilder> templateBuilderProvider;
private final String location;
private final ComputeUtils utils;
private final Predicate<Server> serverActive;
private final ServerToNodeMetadata serverToNodeMetadata;
@Inject
public CloudServersComputeService(CloudServersClient client,
Provider<TemplateBuilder> templateBuilderProvider, @ResourceLocation String location,
Provider<Set<? extends Image>> images, Provider<Set<? extends Size>> sizes,
ComputeUtils utils, Predicate<Server> serverActive,
ServerToNodeMetadata serverToNodeMetadata) {
this.location = location;
this.client = client;
this.images = images;
this.sizes = sizes;
this.utils = utils;
this.templateBuilderProvider = templateBuilderProvider;
this.serverActive = serverActive;
this.serverToNodeMetadata = serverToNodeMetadata;
}
private static Map<ServerStatus, NodeState> instanceToNodeState = ImmutableMap
.<ServerStatus, NodeState> builder().put(ServerStatus.ACTIVE, NodeState.RUNNING)//
.put(ServerStatus.SUSPENDED, NodeState.SUSPENDED)//
.put(ServerStatus.DELETED, NodeState.TERMINATED)//
.put(ServerStatus.QUEUE_RESIZE, NodeState.PENDING)//
.put(ServerStatus.PREP_RESIZE, NodeState.PENDING)//
.put(ServerStatus.RESIZE, NodeState.PENDING)//
.put(ServerStatus.VERIFY_RESIZE, NodeState.PENDING)//
.put(ServerStatus.QUEUE_MOVE, NodeState.PENDING)//
.put(ServerStatus.PREP_MOVE, NodeState.PENDING)//
.put(ServerStatus.MOVE, NodeState.PENDING)//
.put(ServerStatus.VERIFY_MOVE, NodeState.PENDING)//
.put(ServerStatus.RESCUE, NodeState.PENDING)//
.put(ServerStatus.ERROR, NodeState.ERROR)//
.put(ServerStatus.BUILD, NodeState.PENDING)//
.put(ServerStatus.RESTORING, NodeState.PENDING)//
.put(ServerStatus.PASSWORD, NodeState.PENDING)//
.put(ServerStatus.REBUILD, NodeState.PENDING)//
.put(ServerStatus.DELETE_IP, NodeState.PENDING)//
.put(ServerStatus.SHARE_IP_NO_CONFIG, NodeState.PENDING)//
.put(ServerStatus.SHARE_IP, NodeState.PENDING)//
.put(ServerStatus.REBOOT, NodeState.PENDING)//
.put(ServerStatus.HARD_REBOOT, NodeState.PENDING)//
.put(ServerStatus.UNKNOWN, NodeState.UNKNOWN).build();
@Override
public CreateNodeResponse runNode(String name, Template template) {
return this.runNode(name, template, RunNodeOptions.NONE);
}
@Override
public CreateNodeResponse runNode(String name, Template template, RunNodeOptions options) {
checkArgument(template.getImage() instanceof CloudServersImage,
"unexpected image type. should be CloudServersImage, was: "
+ template.getImage().getClass());
CloudServersImage cloudServersImage = CloudServersImage.class.cast(template.getImage());
checkArgument(template.getSize() instanceof CloudServersSize,
"unexpected size type. should be CloudServersSize, was: "
+ template.getSize().getClass());
CloudServersSize cloudServersSize = CloudServersSize.class.cast(template.getSize());
logger.debug(">> running instance location(%s) image(%s) flavor(%s)", location,
cloudServersImage.getId(), template.getSize().getId());
Server server = client.createServer(name, cloudServersImage.getImage().getId(),
cloudServersSize.getFlavor().getId());
CreateNodeResponse node = new CreateNodeResponseImpl(server.getId() + "", name, location,
null, server.getMetadata(), NodeState.RUNNING, server.getAddresses()
.getPublicAddresses(), server.getAddresses().getPrivateAddresses(),
new Credentials("root", server.getAdminPass()), ImmutableMap.<String, String> of());
logger.debug("<< started instance(%s)", server.getId());
serverActive.apply(server);
logger.debug("<< running instance(%s)", server.getId());
if (options.getRunScript() != null) {
utils.runScriptOnNode(node, options.getRunScript());
}
return node;
}
@Override
public NodeMetadata getNodeMetadata(ComputeMetadata node) {
checkArgument(node.getType() == ComputeType.NODE, "this is only valid for nodes, not "
+ node.getType());
checkNotNull(node.getId(), "node.id");
return serverToNodeMetadata.apply(client.getServer(Integer.parseInt(node.getId())));
}
@Singleton
private static class ServerToNodeMetadata implements Function<Server, NodeMetadata> {
private final String location;
@SuppressWarnings("unused")
@Inject
ServerToNodeMetadata(@ResourceLocation String location) {
this.location = location;
}
@Override
public NodeMetadata apply(Server from) {
return new NodeMetadataImpl(from.getId() + "", from.getName(), location, null, from
.getMetadata(), instanceToNodeState.get(from.getStatus()), from.getAddresses()
.getPublicAddresses(), from.getAddresses().getPrivateAddresses(), ImmutableMap
.<String, String> of());
}
}
@Override
public Set<ComputeMetadata> listNodes() {
logger.debug(">> listing servers");
Set<ComputeMetadata> servers = Sets.newHashSet();
Iterables.addAll(servers, Iterables.transform(client.listServers(ListOptions.Builder
.withDetails()), serverToNodeMetadata));
logger.debug("<< list(%d)", servers.size());
return servers;
}
@Override
public void destroyNode(ComputeMetadata node) {
checkArgument(node.getType() == ComputeType.NODE, "this is only valid for nodes, not "
+ node.getType());
checkNotNull(node.getId(), "node.id");
logger.debug(">> terminating instance(%s)", node.getId());
boolean success = client.deleteServer(Integer.parseInt(node.getId()));
logger.debug("<< terminated instance(%s) success(%s)", node.getId(), success);
}
@Override
public Set<? extends Size> listSizes() {
return sizes.get();
}
@Override
public Set<? extends Image> listImages() {
return images.get();
}
@Override
public TemplateBuilder templateBuilder() {
return templateBuilderProvider.get();
}
}

View File

@ -0,0 +1,81 @@
/**
*
* 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.rackspace.cloudservers.compute;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.ExecutorService;
import org.jclouds.compute.ComputeServiceContextBuilder;
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
import org.jclouds.logging.jdk.config.JDKLoggingModule;
import org.jclouds.rackspace.cloudservers.CloudServersAsyncClient;
import org.jclouds.rackspace.cloudservers.CloudServersClient;
import org.jclouds.rackspace.cloudservers.compute.config.CloudServersComputeServiceContextModule;
import org.jclouds.rackspace.cloudservers.config.CloudServersRestClientModule;
import org.jclouds.rackspace.config.RackspaceAuthenticationRestModule;
import com.google.inject.Injector;
import com.google.inject.Module;
import com.google.inject.TypeLiteral;
/**
* Creates {@link CloudServersComputeServiceContext} or {@link Injector} instances based on the most commonly
* requested arguments.
* <p/>
* Note that Threadsafe objects will be bound as singletons to the Injector or Context provided.
* <p/>
* <p/>
* If no <code>Module</code>s are specified, the default {@link JDKLoggingModule logging} and
* {@link JavaUrlHttpCommandExecutorServiceModule http transports} will be installed.
*
* @author Adrian Cole
* @see CloudServersComputeServiceContext
*/
public class CloudServersComputeServiceContextBuilder extends
ComputeServiceContextBuilder<CloudServersAsyncClient, CloudServersClient> {
public CloudServersComputeServiceContextBuilder(Properties props) {
super(new TypeLiteral<CloudServersAsyncClient>() {
}, new TypeLiteral<CloudServersClient>() {
}, props);
}
@Override
public CloudServersComputeServiceContextBuilder withExecutorService(ExecutorService service) {
return (CloudServersComputeServiceContextBuilder) super.withExecutorService(service);
}
@Override
public CloudServersComputeServiceContextBuilder withModules(Module... modules) {
return (CloudServersComputeServiceContextBuilder) super.withModules(modules);
}
@Override
protected void addContextModule(List<Module> modules) {
modules.add(new RackspaceAuthenticationRestModule());
modules.add(new CloudServersComputeServiceContextModule());
}
@Override
protected void addClientModule(List<Module> modules) {
modules.add(new CloudServersRestClientModule());
}
}

View File

@ -0,0 +1,69 @@
/**
*
* 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.rackspace.cloudservers.compute;
import java.net.URI;
import java.util.Properties;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
import org.jclouds.logging.jdk.config.JDKLoggingModule;
import org.jclouds.rackspace.RackspacePropertiesBuilder;
import com.google.inject.Module;
/**
* Creates {@link CloudServersComputeServiceContext} instances based on the most commonly requested
* arguments.
* <p/>
* Note that Threadsafe objects will be bound as singletons to the Injector or Context provided.
* <p/>
* <p/>
* If no <code>Module</code>s are specified, the default {@link JDKLoggingModule logging} and
* {@link JavaUrlHttpCommandExecutorServiceModule http transports} will be installed.
*
* @author Adrian Cole
* @see CloudServersComputeServiceContext
*/
public class CloudServersComputeServiceContextFactory {
public static ComputeServiceContext createContext(Properties properties, Module... modules) {
return new CloudServersComputeServiceContextBuilder(new RackspacePropertiesBuilder(properties).build())
.withModules(modules).buildComputeServiceContext();
}
public static ComputeServiceContext createContext(String user,
String password, Module... modules) {
return new CloudServersComputeServiceContextBuilder(new RackspacePropertiesBuilder(user,
password).build()).withModules(modules).buildComputeServiceContext();
}
public static ComputeServiceContext createContext(Properties properties, String user,
String password, Module... modules) {
return new CloudServersComputeServiceContextBuilder(new RackspacePropertiesBuilder(properties)
.withCredentials(user, password).build()).withModules(modules)
.buildComputeServiceContext();
}
public static ComputeServiceContext createContext(URI endpoint, String user,
String password, Module... modules) {
return new CloudServersComputeServiceContextBuilder(new RackspacePropertiesBuilder(user,
password).withEndpoint(endpoint).build()).withModules(modules)
.buildComputeServiceContext();
}
}

View File

@ -0,0 +1,137 @@
/**
*
* 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.rackspace.cloudservers.compute.config;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeoutException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
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.OsFamily;
import org.jclouds.compute.domain.Size;
import org.jclouds.compute.internal.ComputeServiceContextImpl;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.domain.ResourceLocation;
import org.jclouds.logging.Logger;
import org.jclouds.rackspace.cloudservers.CloudServersAsyncClient;
import org.jclouds.rackspace.cloudservers.CloudServersClient;
import org.jclouds.rackspace.cloudservers.compute.CloudServersComputeService;
import org.jclouds.rackspace.cloudservers.compute.domain.CloudServersImage;
import org.jclouds.rackspace.cloudservers.compute.domain.CloudServersSize;
import org.jclouds.rackspace.cloudservers.config.CloudServersContextModule;
import org.jclouds.rackspace.cloudservers.domain.Flavor;
import org.jclouds.rackspace.cloudservers.options.ListOptions;
import org.jclouds.rest.RestContext;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import com.google.inject.Provides;
/**
* Configures the {@link CloudServersComputeServiceContext}; requires
* {@link CloudServersComputeService} bound.
*
* @author Adrian Cole
*/
public class CloudServersComputeServiceContextModule extends CloudServersContextModule {
@Override
protected void configure() {
super.configure();
bind(ComputeService.class).to(CloudServersComputeService.class).asEagerSingleton();
}
@Provides
@Singleton
ComputeServiceContext provideContext(ComputeService computeService,
RestContext<CloudServersAsyncClient, CloudServersClient> context) {
return new ComputeServiceContextImpl<CloudServersAsyncClient, CloudServersClient>(
computeService, context);
}
@Provides
@Singleton
@ResourceLocation
String getRegion() {
return "default";
}
@Provides
@Singleton
protected Set<? extends Size> provideSizes(CloudServersClient sync, Set<? extends Image> images,
LogHolder holder, ExecutorService executor) throws InterruptedException,
TimeoutException, ExecutionException {
final Set<Size> sizes = Sets.newHashSet();
holder.logger.debug(">> providing sizes");
for (final Flavor from : sync.listFlavors(ListOptions.Builder.withDetails())) {
sizes.add(new CloudServersSize(from, from.getId() + "", from.getDisk() / 10,
from .getRam(), from.getDisk(), ImmutableSet.<Architecture> of(Architecture.X86_32,
Architecture.X86_64)));
}
holder.logger.debug("<< sizes(%d)", sizes.size());
return sizes;
}
private static class LogHolder {
@Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL;
}
public static final Pattern RACKSPACE_PATTERN = Pattern.compile("(([^ ]*) .*)");
@Provides
@Singleton
protected Set<? extends Image> provideImages(final CloudServersClient sync,
@ResourceLocation String location, LogHolder holder) throws InterruptedException,
ExecutionException, TimeoutException {
final Set<Image> images = Sets.newHashSet();
holder.logger.debug(">> providing images");
for (final org.jclouds.rackspace.cloudservers.domain.Image from : sync
.listImages(ListOptions.Builder.withDetails())) {
OsFamily os = null;
Architecture arch = Architecture.X86_64;
String osDescription = "";
String version = "";
Matcher matcher = RACKSPACE_PATTERN.matcher(from.getName());
if (matcher.find()) {
try {
os = OsFamily.fromValue(matcher.group(2).toLowerCase());
osDescription = matcher.group(1);
} catch (IllegalArgumentException e) {
holder.logger.debug("<< didn't match os(%s)", matcher.group(2));
}
}
images.add(new CloudServersImage(from, location, arch, os, osDescription, version));
}
holder.logger.debug("<< images(%d)", images.size());
return images;
}
}

View File

@ -0,0 +1,154 @@
/**
*
* 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.rackspace.cloudservers.compute.domain;
import org.jclouds.compute.domain.Architecture;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.OsFamily;
/**
*
* @author Adrian Cole
*/
public class CloudServersImage implements Image {
private final org.jclouds.rackspace.cloudservers.domain.Image image;
private final String location;
private final Architecture architecture;
private final OsFamily os;
private final String osDescription;
private final String version;
public CloudServersImage(org.jclouds.rackspace.cloudservers.domain.Image image, String location,
Architecture architecture, OsFamily os, String osDescription, String version) {
this.location = location;
this.architecture = architecture;
this.image = image;
this.os = os;
this.osDescription = osDescription;
this.version = version;
}
@Override
public Architecture getArchitecture() {
return architecture;
}
@Override
public String getDescription() {
return getImage().getName();
}
@Override
public String getId() {
return getImage().getId()+"";
}
@Override
public String getLocation() {
return location;
}
@Override
public OsFamily getOsFamily() {
return os;
}
@Override
public String getOsDescription() {
return osDescription;
}
@Override
public String getVersion() {
return version;
}
public org.jclouds.rackspace.cloudservers.domain.Image getImage() {
return image;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((architecture == null) ? 0 : architecture.hashCode());
result = prime * result + ((image == null) ? 0 : image.hashCode());
result = prime * result + ((location == null) ? 0 : location.hashCode());
result = prime * result + ((os == null) ? 0 : os.hashCode());
result = prime * result + ((osDescription == null) ? 0 : osDescription.hashCode());
result = prime * result + ((version == null) ? 0 : version.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;
CloudServersImage other = (CloudServersImage) obj;
if (architecture == null) {
if (other.architecture != null)
return false;
} else if (!architecture.equals(other.architecture))
return false;
if (image == null) {
if (other.image != null)
return false;
} else if (!image.equals(other.image))
return false;
if (location == null) {
if (other.location != null)
return false;
} else if (!location.equals(other.location))
return false;
if (os == null) {
if (other.os != null)
return false;
} else if (!os.equals(other.os))
return false;
if (osDescription == null) {
if (other.osDescription != null)
return false;
} else if (!osDescription.equals(other.osDescription))
return false;
if (version == null) {
if (other.version != null)
return false;
} else if (!version.equals(other.version))
return false;
return true;
}
@Override
public String toString() {
return "[id=" + getId() + ", version=" + version + ", location=" + getLocation()
+ ", architecture=" + getArchitecture() + ", operatingSystem="
+ getOsFamily() + ", operatingSystemVersion=" + getOsDescription()
+ ", description=" + getDescription() + "]";
}
}

View File

@ -0,0 +1,72 @@
/**
*
* 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.rackspace.cloudservers.compute.domain;
import org.jclouds.compute.domain.Architecture;
import org.jclouds.compute.domain.internal.SizeImpl;
import org.jclouds.rackspace.cloudservers.domain.Flavor;
/**
*
* @author Adrian Cole
*/
public class CloudServersSize extends SizeImpl {
private final Flavor flavor;
public CloudServersSize(Flavor flavor, String id, int cores, int ram, int disk,
Iterable<Architecture> supportedArchitectures) {
super(id, cores, ram, disk, supportedArchitectures);
this.flavor = flavor;
}
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + ((flavor == null) ? 0 : flavor.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!super.equals(obj))
return false;
if (getClass() != obj.getClass())
return false;
CloudServersSize other = (CloudServersSize) obj;
if (flavor == null) {
if (other.flavor != null)
return false;
} else if (!flavor.equals(other.flavor))
return false;
return true;
}
public Flavor getFlavor() {
return flavor;
}
}

View File

@ -18,20 +18,27 @@
*/ */
package org.jclouds.rackspace.cloudservers.config; package org.jclouds.rackspace.cloudservers.config;
import java.net.InetSocketAddress;
import java.net.URI; import java.net.URI;
import java.util.concurrent.TimeUnit;
import javax.inject.Named; import javax.inject.Named;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.jclouds.http.RequiresHttp; import org.jclouds.http.RequiresHttp;
import org.jclouds.lifecycle.Closer; import org.jclouds.lifecycle.Closer;
import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.predicates.SocketOpen;
import org.jclouds.rackspace.CloudServers; import org.jclouds.rackspace.CloudServers;
import org.jclouds.rackspace.cloudservers.CloudServersAsyncClient; import org.jclouds.rackspace.cloudservers.CloudServersAsyncClient;
import org.jclouds.rackspace.cloudservers.CloudServersClient; import org.jclouds.rackspace.cloudservers.CloudServersClient;
import org.jclouds.rackspace.cloudservers.domain.Server;
import org.jclouds.rackspace.cloudservers.predicates.ServerActive;
import org.jclouds.rackspace.reference.RackspaceConstants; import org.jclouds.rackspace.reference.RackspaceConstants;
import org.jclouds.rest.RestContext; import org.jclouds.rest.RestContext;
import org.jclouds.rest.internal.RestContextImpl; import org.jclouds.rest.internal.RestContextImpl;
import com.google.common.base.Predicate;
import com.google.inject.AbstractModule; import com.google.inject.AbstractModule;
import com.google.inject.Provides; import com.google.inject.Provides;
@ -42,6 +49,18 @@ public class CloudServersContextModule extends AbstractModule {
protected void configure() { protected void configure() {
} }
@Provides
@Singleton
protected Predicate<Server> instanceStateRunning(ServerActive stateRunning) {
return new RetryablePredicate<Server>(stateRunning, 600, 2, TimeUnit.SECONDS);
}
@Provides
@Singleton
protected Predicate<InetSocketAddress> socketTester(SocketOpen open) {
return new RetryablePredicate<InetSocketAddress>(open, 130, 1, TimeUnit.SECONDS);
}
@Provides @Provides
@Singleton @Singleton
RestContext<CloudServersAsyncClient, CloudServersClient> provideContext(Closer closer, RestContext<CloudServersAsyncClient, CloudServersClient> provideContext(Closer closer,

View File

@ -49,11 +49,11 @@ public class ParseInetAddressListFromJsonResponse extends ParseJson<List<InetAdd
Map<String, List<InetAddress>> addressMap; Map<String, List<InetAddress>> addressMap;
public List<InetAddress> apply(InputStream stream) { public List<InetAddress> apply(InputStream stream) {
Type type = new TypeToken<Map<String, List<InetAddress>>>() { Type flavor = new TypeToken<Map<String, List<InetAddress>>>() {
}.getType(); }.getType();
try { try {
Map<String, List<InetAddress>> map = gson.fromJson(new InputStreamReader(stream, "UTF-8"), Map<String, List<InetAddress>> map = gson.fromJson(new InputStreamReader(stream, "UTF-8"),
type); flavor);
return map.values().iterator().next(); return map.values().iterator().next();
} catch (UnsupportedEncodingException e) { } catch (UnsupportedEncodingException e) {
throw new RuntimeException("jclouds requires UTF-8 encoding", e); throw new RuntimeException("jclouds requires UTF-8 encoding", e);

View File

@ -0,0 +1,49 @@
package org.jclouds.rackspace.cloudservers.predicates;
import javax.annotation.Resource;
import javax.inject.Singleton;
import org.jclouds.logging.Logger;
import org.jclouds.rackspace.cloudservers.CloudServersClient;
import org.jclouds.rackspace.cloudservers.domain.Server;
import org.jclouds.rackspace.cloudservers.domain.ServerStatus;
import org.jclouds.rest.ResourceNotFoundException;
import com.google.common.base.Predicate;
import com.google.inject.Inject;
/**
*
* Tests to see if a task succeeds.
*
* @author Adrian Cole
*/
@Singleton
public class ServerActive implements Predicate<Server> {
private final CloudServersClient client;
@Resource
protected Logger logger = Logger.NULL;
@Inject
public ServerActive(CloudServersClient client) {
this.client = client;
}
public boolean apply(Server server) {
logger.trace("looking for state on server %s", server);
try {
server = refresh(server);
logger.trace("%s: looking for server state %s: currently: %s", server.getId(),
ServerStatus.ACTIVE, server.getStatus());
return server.getStatus() == ServerStatus.ACTIVE;
} catch (ResourceNotFoundException e) {
return false;
}
}
private Server refresh(Server server) {
return client.getServer(server.getId());
}
}

View File

@ -23,6 +23,7 @@ import static org.jclouds.rackspace.reference.RackspaceConstants.PROPERTY_RACKSP
import static org.jclouds.rackspace.reference.RackspaceConstants.PROPERTY_RACKSPACE_USER; import static org.jclouds.rackspace.reference.RackspaceConstants.PROPERTY_RACKSPACE_USER;
import java.net.URI; import java.net.URI;
import java.util.Date;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
@ -30,6 +31,8 @@ import java.util.concurrent.TimeoutException;
import javax.inject.Named; import javax.inject.Named;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.jclouds.concurrent.ExpirableSupplier;
import org.jclouds.date.TimeStamp;
import org.jclouds.http.RequiresHttp; import org.jclouds.http.RequiresHttp;
import org.jclouds.rackspace.Authentication; import org.jclouds.rackspace.Authentication;
import org.jclouds.rackspace.CloudFiles; import org.jclouds.rackspace.CloudFiles;
@ -39,6 +42,8 @@ import org.jclouds.rackspace.RackspaceAuthentication;
import org.jclouds.rackspace.RackspaceAuthentication.AuthenticationResponse; import org.jclouds.rackspace.RackspaceAuthentication.AuthenticationResponse;
import org.jclouds.rest.RestClientFactory; import org.jclouds.rest.RestClientFactory;
import com.google.common.base.Supplier;
import com.google.common.base.Throwables;
import com.google.inject.AbstractModule; import com.google.inject.AbstractModule;
import com.google.inject.Provides; import com.google.inject.Provides;
@ -54,6 +59,39 @@ public class RackspaceAuthenticationRestModule extends AbstractModule {
protected void configure() { protected void configure() {
} }
/**
* borrowing concurrency code to ensure that caching takes place properly
*/
@Provides
@Singleton
@Authentication
Supplier<String> provideAuthenticationTokenCache(final RestClientFactory factory,
@Named(PROPERTY_RACKSPACE_USER) final String user,
@Named(PROPERTY_RACKSPACE_KEY) final String key) {
return new ExpirableSupplier<String>(new Supplier<String>() {
public String get() {
try {
return factory.create(RackspaceAuthentication.class).authenticate(user, key).get(30,
TimeUnit.SECONDS).getAuthToken();
} catch (Exception e) {
Throwables.propagateIfPossible(e);
throw new RuntimeException("Error logging in", e);
}
}
}, 23, TimeUnit.HOURS);
}
@Provides
@Singleton
@TimeStamp
Supplier<Date> provideCacheBusterDate() {
return new ExpirableSupplier<Date>(new Supplier<Date>() {
public Date get() {
return new Date();
}
}, 1, TimeUnit.SECONDS);
}
@Provides @Provides
@Singleton @Singleton
@Authentication @Authentication
@ -70,15 +108,6 @@ public class RackspaceAuthenticationRestModule extends AbstractModule {
TimeUnit.SECONDS); TimeUnit.SECONDS);
} }
@Provides
@Authentication
protected String provideAuthenticationToken(RestClientFactory factory,
@Named(PROPERTY_RACKSPACE_USER) String user, @Named(PROPERTY_RACKSPACE_KEY) String key)
throws InterruptedException, ExecutionException, TimeoutException {
return factory.create(RackspaceAuthentication.class).authenticate(user, key).get(30,
TimeUnit.SECONDS).getAuthToken();
}
@Provides @Provides
@Singleton @Singleton
@CloudFiles @CloudFiles

View File

@ -21,14 +21,16 @@ package org.jclouds.rackspace.filters;
import java.util.Date; import java.util.Date;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Provider;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.jclouds.date.TimeStamp;
import org.jclouds.http.HttpException; import org.jclouds.http.HttpException;
import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpRequestFilter; import org.jclouds.http.HttpRequestFilter;
import org.jclouds.rest.internal.GeneratedHttpRequest; import org.jclouds.rest.internal.GeneratedHttpRequest;
import com.google.common.base.Supplier;
/** /**
* Adds a timestamp to the query line so that cache is invalidated. * Adds a timestamp to the query line so that cache is invalidated.
* *
@ -37,10 +39,10 @@ import org.jclouds.rest.internal.GeneratedHttpRequest;
*/ */
@Singleton @Singleton
public class AddTimestampQuery implements HttpRequestFilter { public class AddTimestampQuery implements HttpRequestFilter {
private final Provider<Date> dateProvider; private final Supplier<Date> dateProvider;
@Inject @Inject
public AddTimestampQuery(Provider<Date> dateProvider) { public AddTimestampQuery(@TimeStamp Supplier<Date> dateProvider) {
this.dateProvider = dateProvider; this.dateProvider = dateProvider;
} }

View File

@ -19,11 +19,8 @@
package org.jclouds.rackspace.filters; package org.jclouds.rackspace.filters;
import java.util.Collections; import java.util.Collections;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Provider;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.jclouds.http.HttpException; import org.jclouds.http.HttpException;
@ -32,6 +29,8 @@ import org.jclouds.http.HttpRequestFilter;
import org.jclouds.rackspace.Authentication; import org.jclouds.rackspace.Authentication;
import org.jclouds.rackspace.reference.RackspaceHeaders; import org.jclouds.rackspace.reference.RackspaceHeaders;
import com.google.common.base.Supplier;
/** /**
* Signs the Rackspace request. This will update the Authentication Token before 24 hours is up. * Signs the Rackspace request. This will update the Authentication Token before 24 hours is up.
* *
@ -41,51 +40,16 @@ import org.jclouds.rackspace.reference.RackspaceHeaders;
@Singleton @Singleton
public class AuthenticateRequest implements HttpRequestFilter { public class AuthenticateRequest implements HttpRequestFilter {
private final Provider<String> authTokenProvider; private final Supplier<String> authTokenProvider;
public final long BILLION = 1000000000;
public final long MINUTES = 60 * BILLION;
public final long HOURS = 60 * MINUTES;
private final AtomicReference<String> authToken;
private final AtomicLong trigger = new AtomicLong(0);
/**
* Start the time update service. Rackspace clocks need to be 24 hours of the auth token. This is
* not performed per-request, as creation of the token is a slow, synchronized command.
*/
synchronized void updateIfTimeOut() {
if (trigger.get() - System.nanoTime() <= 0) {
createNewToken();
}
}
// this is a hotspot when submitted concurrently, so be lazy.
// rackspace is ok with up to 23:59 off their time, so let's
// be as lazy as possible.
public String createNewToken() {
authToken.set(authTokenProvider.get());
trigger.set(System.nanoTime() + System.nanoTime() + 23 * HOURS);
return authToken.get();
}
public String getAuthToken() {
updateIfTimeOut();
return authToken.get();
}
@Inject @Inject
public AuthenticateRequest(@Authentication Provider<String> authTokenProvider) { public AuthenticateRequest(@Authentication Supplier<String> authTokenProvider) {
this.authTokenProvider = authTokenProvider; this.authTokenProvider = authTokenProvider;
authToken = new AtomicReference<String>();
} }
public void filter(HttpRequest request) throws HttpException { public void filter(HttpRequest request) throws HttpException {
request.getHeaders().replaceValues(RackspaceHeaders.AUTH_TOKEN, request.getHeaders().replaceValues(RackspaceHeaders.AUTH_TOKEN,
Collections.singletonList(getAuthToken())); Collections.singletonList(authTokenProvider.get()));
} }
} }

View File

@ -18,7 +18,6 @@
*/ */
package org.jclouds.rackspace.cloudservers; package org.jclouds.rackspace.cloudservers;
import static com.google.common.util.concurrent.Executors.sameThreadExecutor;
import static org.jclouds.rackspace.cloudservers.options.CreateServerOptions.Builder.withFile; import static org.jclouds.rackspace.cloudservers.options.CreateServerOptions.Builder.withFile;
import static org.jclouds.rackspace.cloudservers.options.CreateServerOptions.Builder.withMetadata; import static org.jclouds.rackspace.cloudservers.options.CreateServerOptions.Builder.withMetadata;
import static org.jclouds.rackspace.cloudservers.options.CreateServerOptions.Builder.withSharedIpGroup; import static org.jclouds.rackspace.cloudservers.options.CreateServerOptions.Builder.withSharedIpGroup;
@ -41,6 +40,7 @@ import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import org.jclouds.concurrent.config.ExecutorServiceModule; import org.jclouds.concurrent.config.ExecutorServiceModule;
import org.jclouds.date.TimeStamp;
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule; import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
import org.jclouds.http.functions.ReturnFalseOn404; import org.jclouds.http.functions.ReturnFalseOn404;
import org.jclouds.http.functions.ReturnTrueIf2xx; import org.jclouds.http.functions.ReturnTrueIf2xx;
@ -74,7 +74,9 @@ import org.jclouds.rest.internal.RestAnnotationProcessor;
import org.testng.annotations.BeforeClass; import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.common.util.concurrent.Executors;
import com.google.inject.AbstractModule; import com.google.inject.AbstractModule;
import com.google.inject.Guice; import com.google.inject.Guice;
import com.google.inject.Injector; import com.google.inject.Injector;
@ -917,7 +919,7 @@ public class CloudServersClientTest {
+ "")); + ""));
assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_TYPE), Collections assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_TYPE), Collections
.singletonList(MediaType.APPLICATION_JSON)); .singletonList(MediaType.APPLICATION_JSON));
assertEquals("{\"reboot\":{\"type\":\"HARD\"}}", httpMethod.getPayload().getRawContent()); assertEquals("{\"reboot\":{\"flavor\":\"HARD\"}}", httpMethod.getPayload().getRawContent());
assertEquals(processor assertEquals(processor
.createExceptionParserOrThrowResourceNotFoundOn404IfNoAnnotation(method).getClass(), .createExceptionParserOrThrowResourceNotFoundOn404IfNoAnnotation(method).getClass(),
ReturnFalseOn404.class); ReturnFalseOn404.class);
@ -1007,10 +1009,25 @@ public class CloudServersClientTest {
@SuppressWarnings("unused") @SuppressWarnings("unused")
@Provides @Provides
@Authentication @Authentication
public String getAuthToken() { public Supplier<String> getAuthToken() {
return "testtoken"; return new Supplier<String>() {
public String get() {
return "testtoken";
}
};
} }
}, new RestModule(), new ExecutorServiceModule(sameThreadExecutor()),
@SuppressWarnings("unused")
@Provides
@TimeStamp
public Supplier<Date> getDate() {
return new Supplier<Date>() {
public Date get() {
return new Date();
}
};
}
}, new RestModule(), new ExecutorServiceModule(Executors.sameThreadExecutor()),
new JavaUrlHttpCommandExecutorServiceModule()); new JavaUrlHttpCommandExecutorServiceModule());
processor = injector.getInstance(Key processor = injector.getInstance(Key
.get(new TypeLiteral<RestAnnotationProcessor<CloudServersAsyncClient>>() { .get(new TypeLiteral<RestAnnotationProcessor<CloudServersAsyncClient>>() {

View File

@ -66,7 +66,7 @@ public class BindRebootTypeToJsonPayloadTest {
injector.injectMembers(binder); injector.injectMembers(binder);
HttpRequest request = new HttpRequest(HttpMethod.POST, URI.create("http://localhost")); HttpRequest request = new HttpRequest(HttpMethod.POST, URI.create("http://localhost"));
binder.bindToRequest(request, RebootType.HARD); binder.bindToRequest(request, RebootType.HARD);
assertEquals("{\"reboot\":{\"type\":\"HARD\"}}", request.getPayload().getRawContent()); assertEquals("{\"reboot\":{\"flavor\":\"HARD\"}}", request.getPayload().getRawContent());
} }
@Test @Test
@ -75,7 +75,7 @@ public class BindRebootTypeToJsonPayloadTest {
injector.injectMembers(binder); injector.injectMembers(binder);
HttpRequest request = new HttpRequest(HttpMethod.POST, URI.create("http://localhost")); HttpRequest request = new HttpRequest(HttpMethod.POST, URI.create("http://localhost"));
binder.bindToRequest(request, RebootType.SOFT); binder.bindToRequest(request, RebootType.SOFT);
assertEquals("{\"reboot\":{\"type\":\"SOFT\"}}", request.getPayload().getRawContent()); assertEquals("{\"reboot\":{\"flavor\":\"SOFT\"}}", request.getPayload().getRawContent());
} }
@Test(expectedExceptions = { NullPointerException.class, IllegalStateException.class }) @Test(expectedExceptions = { NullPointerException.class, IllegalStateException.class })

View File

@ -0,0 +1,66 @@
/**
*
* 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.rackspace.cloudservers.compute;
import static org.jclouds.compute.domain.OsFamily.UBUNTU;
import org.jclouds.compute.BaseComputeServiceLiveTest;
import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.compute.domain.Template;
import org.jclouds.compute.domain.TemplateBuilder;
import org.jclouds.rackspace.cloudservers.CloudServersAsyncClient;
import org.jclouds.rackspace.cloudservers.CloudServersClient;
import org.jclouds.rest.RestContext;
import org.jclouds.ssh.jsch.config.JschSshClientModule;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
/**
*
* Generally disabled, as it incurs higher fees.
*
* @author Adrian Cole
*/
@Test(groups = "live", enabled = true, sequential = true, testName = "cloudservers.CloudServersComputeServiceLiveTest")
public class CloudServersComputeServiceLiveTest extends BaseComputeServiceLiveTest {
@BeforeClass
@Override
public void setServiceDefaults() {
service = "cloudservers";
}
protected Template buildTemplate(TemplateBuilder templateBuilder) {
return templateBuilder.osFamily(UBUNTU).osDescriptionMatches(".*9.10.*").smallest().build();
}
@Override
protected JschSshClientModule getSshModule() {
return new JschSshClientModule();
}
public void testAssignability() throws Exception {
@SuppressWarnings("unused")
RestContext<CloudServersAsyncClient, CloudServersClient> tmContext = new ComputeServiceContextFactory()
.createContext(service, user, password).getProviderSpecificContext();
CloudServersComputeService.class.cast(client);
}
}

View File

@ -0,0 +1,53 @@
/**
*
* 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.rackspace.cloudservers.compute;
import static org.testng.Assert.assertEquals;
import java.io.IOException;
import java.util.Properties;
import org.jclouds.rackspace.RackspacePropertiesBuilder;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import com.google.common.io.Resources;
/**
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "compute.PropertiesTest")
public class PropertiesTest {
private Properties properties;
@BeforeTest
public void setUp() throws IOException {
properties = new Properties();
properties.load(Resources.newInputStreamSupplier(Resources.getResource("compute.properties"))
.getInput());
}
public void testRackspace() {
assertEquals(properties.getProperty("cloudservers.contextbuilder"),
CloudServersComputeServiceContextBuilder.class.getName());
assertEquals(properties.getProperty("cloudservers.propertiesbuilder"),
RackspacePropertiesBuilder.class.getName());
}
}

View File

@ -23,11 +23,11 @@ import static org.easymock.classextension.EasyMock.replay;
import java.util.Date; import java.util.Date;
import javax.inject.Provider;
import org.jclouds.rest.internal.GeneratedHttpRequest; import org.jclouds.rest.internal.GeneratedHttpRequest;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import com.google.common.base.Supplier;
/** /**
* *
* @author Adrian Cole * @author Adrian Cole
@ -39,7 +39,7 @@ public class AddTimestampQueryTest {
@Test @Test
public void testApplySetsKey() { public void testApplySetsKey() {
final Date date = new Date(); final Date date = new Date();
Provider<Date> dateProvider = new Provider<Date>() { Supplier<Date> dateSupplier = new Supplier<Date>() {
@Override @Override
public Date get() { public Date get() {
@ -51,7 +51,7 @@ public class AddTimestampQueryTest {
request.addQueryParam("now", date.getTime() + ""); request.addQueryParam("now", date.getTime() + "");
replay(request); replay(request);
AddTimestampQuery filter = new AddTimestampQuery(dateProvider); AddTimestampQuery filter = new AddTimestampQuery(dateSupplier);
filter.filter(request); filter.filter(request);
} }

View File

@ -1,32 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?> <?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"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at 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
Unless required by applicable law or agreed to in writing, software under the License is distributed on an "AS IS" BASIS, WITHOUT
distributed under the License is distributed on an "AS IS" BASIS, WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions
See the License for the specific language governing permissions and and limitations under the License.
limitations under the License. ====================================================================
==================================================================== -->
-->
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<!-- <!--
For more configuration infromation and examples see the Apache Log4j For more configuration infromation and examples see the Apache
website: http://logging.apache.org/log4j/ Log4j website: http://logging.apache.org/log4j/
--> -->
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"
debug="false"> debug="false">
<!-- A time/date based rolling appender --> <!-- A time/date based rolling appender -->
<appender name="WIREFILE" class="org.apache.log4j.DailyRollingFileAppender"> <appender name="WIREFILE" class="org.apache.log4j.DailyRollingFileAppender">
@ -43,51 +42,75 @@
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" /> <param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
<!-- <!--
The full pattern: Date MS Priority [Category] (Thread:NDC) Message\n The full pattern: Date MS Priority [Category]
<param name="ConversionPattern" value="%d %-5r %-5p [%c] (%t:%x) (Thread:NDC) Message\n <param name="ConversionPattern"
%m%n"/> value="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
--> -->
</layout> </layout>
</appender> </appender>
<!-- A time/date based rolling appender --> <!-- A time/date based rolling appender -->
<appender name="FILE" class="org.apache.log4j.DailyRollingFileAppender"> <appender name="FILE" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="target/test-data/jclouds.log" /> <param name="File" value="target/test-data/jclouds.log" />
<param name="Append" value="true" /> <param name="Append" value="true" />
<!-- Rollover at midnight each day --> <!-- Rollover at midnight each day -->
<param name="DatePattern" value="'.'yyyy-MM-dd" /> <param name="DatePattern" value="'.'yyyy-MM-dd" />
<param name="Threshold" value="TRACE" /> <param name="Threshold" value="TRACE" />
<layout class="org.apache.log4j.PatternLayout"> <layout class="org.apache.log4j.PatternLayout">
<!-- The default pattern: Date Priority [Category] Message\n --> <!-- The default pattern: Date Priority [Category] Message\n -->
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" /> <param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
<!-- <!--
The full pattern: Date MS Priority [Category] (Thread:NDC) Message\n The full pattern: Date MS Priority [Category]
<param name="ConversionPattern" value="%d %-5r %-5p [%c] (%t:%x) (Thread:NDC) Message\n <param name="ConversionPattern"
%m%n"/> value="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
--> -->
</layout> </layout>
</appender> </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" />
<appender name="ASYNC" class="org.apache.log4j.AsyncAppender"> <!-- Rollover at midnight each day -->
<appender-ref ref="FILE" /> <param name="DatePattern" value="'.'yyyy-MM-dd" />
</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>
<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>
<appender name="ASYNCWIRE" class="org.apache.log4j.AsyncAppender"> <appender name="ASYNCWIRE" class="org.apache.log4j.AsyncAppender">
<appender-ref ref="WIREFILE" /> <appender-ref ref="WIREFILE" />
</appender> </appender>
<!-- ================ --> <!-- ================ -->
<!-- Limit categories --> <!-- Limit categories -->
<!-- ================ --> <!-- ================ -->
<category name="org.jclouds"> <category name="org.jclouds">
<priority value="DEBUG" /> <priority value="DEBUG" />
<appender-ref ref="ASYNC" /> <appender-ref ref="ASYNC" />
</category> </category>
<category name="jclouds.http.headers"> <category name="jclouds.http.headers">
<priority value="DEBUG" /> <priority value="DEBUG" />
@ -98,12 +121,16 @@
<appender-ref ref="ASYNCWIRE" /> <appender-ref ref="ASYNCWIRE" />
</category> </category>
<category name="jclouds.compute">
<priority value="TRACE" />
<appender-ref ref="ASYNCCOMPUTE" />
</category>
<!-- ======================= -->
<!-- Setup the Root category -->
<!-- ======================= --> <!-- ======================= -->
<!-- Setup the Root category -->
<!-- ======================= -->
<root> <root>
<priority value="WARN" /> <priority value="WARN" />
</root> </root>
</log4j:configuration> </log4j:configuration>

View File

@ -37,10 +37,9 @@ import org.jclouds.compute.domain.ComputeMetadata;
import org.jclouds.compute.domain.ComputeType; import org.jclouds.compute.domain.ComputeType;
import org.jclouds.compute.domain.CreateNodeResponse; import org.jclouds.compute.domain.CreateNodeResponse;
import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.LoginType;
import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.NodeState; import org.jclouds.compute.domain.NodeState;
import org.jclouds.compute.domain.OperatingSystem; import org.jclouds.compute.domain.OsFamily;
import org.jclouds.compute.domain.Size; import org.jclouds.compute.domain.Size;
import org.jclouds.compute.domain.Template; import org.jclouds.compute.domain.Template;
import org.jclouds.compute.domain.TemplateBuilder; import org.jclouds.compute.domain.TemplateBuilder;
@ -77,9 +76,8 @@ public class RimuHostingComputeService implements ComputeService {
this.rhClient = rhClient; this.rhClient = rhClient;
} }
private Map<OperatingSystem, String> imageNameMap = ImmutableMap private Map<OsFamily, String> imageNameMap = ImmutableMap.<OsFamily, String> builder().put(
.<OperatingSystem, String> builder().put(OperatingSystem.CENTOS, "centos53").put( OsFamily.CENTOS, "centos53").put(OsFamily.UBUNTU, "ubuntu904").build();
OperatingSystem.UBUNTU, "ubuntu904").build();
// private Map<Size, String> profileNameMap = ImmutableMap.<Profile, String> builder().put( // private Map<Size, String> profileNameMap = ImmutableMap.<Profile, String> builder().put(
// Profile.SMALLEST, "MIRO1B").build(); // Profile.SMALLEST, "MIRO1B").build();
@ -92,15 +90,15 @@ public class RimuHostingComputeService implements ComputeService {
@Override @Override
public CreateNodeResponse runNode(String name, Template template, RunNodeOptions options) { public CreateNodeResponse runNode(String name, Template template, RunNodeOptions options) {
NewServerResponse serverResponse = rhClient.createServer(name, checkNotNull(imageNameMap NewServerResponse serverResponse = rhClient.createServer(name, checkNotNull(imageNameMap
.get(template.getImage().getOperatingSystem()), "os not supported: " .get(template.getImage().getOsFamily()), "os not supported: "
+ template.getImage().getOperatingSystem()), "MIRO1B"); + template.getImage().getOsFamily()), "MIRO1B");
return new CreateNodeResponseImpl(serverResponse.getServer().getId().toString(), return new CreateNodeResponseImpl(serverResponse.getServer().getId().toString(),
serverResponse.getServer().getName(), "default", null, ImmutableMap serverResponse.getServer().getName(), "default", null, ImmutableMap
.<String, String> of(), .<String, String> of(),
NodeState.RUNNING,// TODO need a real state! NodeState.RUNNING,// TODO need a real state!
getPublicAddresses(serverResponse.getServer()), ImmutableList.<InetAddress> of(), getPublicAddresses(serverResponse.getServer()), ImmutableList.<InetAddress> of(),
22, LoginType.SSH, new Credentials("root", serverResponse.getNewInstanceRequest() new Credentials("root", serverResponse.getNewInstanceRequest().getCreateOptions()
.getCreateOptions().getPassword()), ImmutableMap.<String, String> of()); .getPassword()), ImmutableMap.<String, String> of());
} }
@VisibleForTesting @VisibleForTesting

View File

@ -18,7 +18,7 @@
*/ */
package org.jclouds.rimuhosting.miro.compute; package org.jclouds.rimuhosting.miro.compute;
import static org.jclouds.compute.domain.OperatingSystem.JEOS; import static org.jclouds.compute.domain.OsFamily.JEOS;
import org.jclouds.compute.BaseComputeServiceLiveTest; import org.jclouds.compute.BaseComputeServiceLiveTest;
import org.jclouds.compute.domain.Template; import org.jclouds.compute.domain.Template;
@ -39,7 +39,7 @@ public class RimuHostingComputeServiceLiveTest extends BaseComputeServiceLiveTes
} }
protected Template buildTemplate(TemplateBuilder templateBuilder) { protected Template buildTemplate(TemplateBuilder templateBuilder) {
return templateBuilder.os(JEOS).osVersionMatches(".*9.04.*").smallest().build(); return templateBuilder.osFamily(JEOS).osDescriptionMatches(".*9.04.*").smallest().build();
} }
@Override @Override

View File

@ -46,7 +46,7 @@
<artifact:dependencies pathId="jclouds.classpath"> <artifact:dependencies pathId="jclouds.classpath">
<dependency groupid="org.codehaus.cargo" artifactId="cargo-ant" version="1.0.1-SNAPSHOT"/> <dependency groupid="org.codehaus.cargo" artifactId="cargo-ant" version="1.0.1-SNAPSHOT"/>
<dependency groupid="org.codehaus.cargo" artifactId="cargo-core-container-tomcat" version="1.0.1-SNAPSHOT"/> <dependency groupid="org.codehaus.cargo" artifactId="cargo-core-container-tomcat" version="1.0.1-SNAPSHOT"/>
<dependency groupId="org.jclouds" artifactId="jclouds-terremark" version="1.0-SNAPSHOT"/> <dependency groupId="org.jclouds" artifactId="${driver}" version="1.0-SNAPSHOT"/>
<dependency groupId="org.jclouds" artifactId="jclouds-antcontrib" version="1.0-SNAPSHOT"/> <dependency groupId="org.jclouds" artifactId="jclouds-antcontrib" version="1.0-SNAPSHOT"/>
<remoteRepository refid="jclouds-snapshot.repository"/> <remoteRepository refid="jclouds-snapshot.repository"/>
<remoteRepository refid="cargo-snapshot.repository"/> <remoteRepository refid="cargo-snapshot.repository"/>
@ -57,7 +57,7 @@
<taskdef name="sshexec" classname="org.apache.tools.ant.taskdefs.optional.ssh.SSHExec" classpathref="jclouds.classpath" /> <taskdef name="sshexec" classname="org.apache.tools.ant.taskdefs.optional.ssh.SSHExec" classpathref="jclouds.classpath" />
<taskdef resource="cargo.tasks" classpathref="jclouds.classpath"/> <taskdef resource="cargo.tasks" classpathref="jclouds.classpath"/>
<property name="service" value="terremark"/> <property name="service" value="${service}"/>
<input message="What is your account on ${service}?" addproperty="account"/> <input message="What is your account on ${service}?" addproperty="account"/>
<input message="What is the key for ${account}?" addproperty="key"/> <input message="What is the key for ${account}?" addproperty="key"/>
<property name="nodename" value="terremark-blaze"/> <property name="nodename" value="terremark-blaze"/>

View File

@ -34,6 +34,7 @@
<dependency groupId="org.jclouds" artifactId="jclouds-antcontrib" version="1.0-SNAPSHOT" /> <dependency groupId="org.jclouds" artifactId="jclouds-antcontrib" version="1.0-SNAPSHOT" />
<dependency groupId="org.jclouds" artifactId="jclouds-hostingdotcom" version="1.0-SNAPSHOT" /> <dependency groupId="org.jclouds" artifactId="jclouds-hostingdotcom" version="1.0-SNAPSHOT" />
<dependency groupId="org.jclouds" artifactId="jclouds-rimuhosting" version="1.0-SNAPSHOT" /> <dependency groupId="org.jclouds" artifactId="jclouds-rimuhosting" version="1.0-SNAPSHOT" />
<dependency groupId="org.jclouds" artifactId="jclouds-rackspace" version="1.0-SNAPSHOT" />
<dependency groupId="org.jclouds" artifactId="jclouds-aws" version="1.0-SNAPSHOT" /> <dependency groupId="org.jclouds" artifactId="jclouds-aws" version="1.0-SNAPSHOT" />
<dependency groupId="org.jclouds" artifactId="jclouds-terremark" version="1.0-SNAPSHOT" /> <dependency groupId="org.jclouds" artifactId="jclouds-terremark" version="1.0-SNAPSHOT" />
<localRepository refid="local.repository" /> <localRepository refid="local.repository" />

View File

@ -163,10 +163,9 @@ public class ComputeTask extends Task {
} }
private void logNodeDetails(CreateNodeResponse createdNode) { private void logNodeDetails(CreateNodeResponse createdNode) {
log(String.format(" id=%s, name=%s, connection=%s://%s:%s@%s:%d", createdNode.getId(), log(String.format(" id=%s, name=%s, connection=%s:%s@%s", createdNode.getId(), createdNode
createdNode.getName(), createdNode.getLoginType().toString().toLowerCase(), .getName(), createdNode.getCredentials().account, createdNode.getCredentials().key,
createdNode.getCredentials().account, createdNode.getCredentials().key, createdNode createdNode.getPublicAddresses().first().getHostAddress()));
.getPublicAddresses().first().getHostAddress(), createdNode.getLoginPort()));
} }
private void addNodeDetailsAsProjectProperties(CreateNodeResponse createdNode) { private void addNodeDetailsAsProjectProperties(CreateNodeResponse createdNode) {

View File

@ -35,7 +35,7 @@ import org.apache.tools.ant.Project;
import org.jclouds.compute.ComputeService; import org.jclouds.compute.ComputeService;
import org.jclouds.compute.ComputeServiceContext; import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.ComputeServiceContextFactory; import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.compute.domain.OperatingSystem; import org.jclouds.compute.domain.OsFamily;
import org.jclouds.compute.domain.Template; import org.jclouds.compute.domain.Template;
import org.jclouds.compute.domain.TemplateBuilder; import org.jclouds.compute.domain.TemplateBuilder;
import org.jclouds.compute.options.RunNodeOptions; import org.jclouds.compute.options.RunNodeOptions;
@ -94,7 +94,7 @@ public class ComputeTaskUtils {
TemplateBuilder templateBuilder = computeService.templateBuilder(); TemplateBuilder templateBuilder = computeService.templateBuilder();
if (nodeElement.getLocation() != null && !"".equals(nodeElement.getLocation())) if (nodeElement.getLocation() != null && !"".equals(nodeElement.getLocation()))
templateBuilder.location(nodeElement.getLocation()); templateBuilder.location(nodeElement.getLocation());
templateBuilder.os(OperatingSystem.valueOf(nodeElement.getOs())); templateBuilder.osFamily(OsFamily.valueOf(nodeElement.getOs()));
addSizeFromElementToTemplate(nodeElement, templateBuilder); addSizeFromElementToTemplate(nodeElement, templateBuilder);
return templateBuilder.build(); return templateBuilder.build();
} }

View File

@ -23,9 +23,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState; import static com.google.common.base.Preconditions.checkState;
import static org.jclouds.vcloud.options.InstantiateVAppTemplateOptions.Builder.processorCount; import static org.jclouds.vcloud.options.InstantiateVAppTemplateOptions.Builder.processorCount;
import java.io.ByteArrayInputStream;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@ -39,7 +37,6 @@ import org.jclouds.compute.domain.ComputeMetadata;
import org.jclouds.compute.domain.ComputeType; import org.jclouds.compute.domain.ComputeType;
import org.jclouds.compute.domain.CreateNodeResponse; import org.jclouds.compute.domain.CreateNodeResponse;
import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.LoginType;
import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.NodeState; import org.jclouds.compute.domain.NodeState;
import org.jclouds.compute.domain.Size; import org.jclouds.compute.domain.Size;
@ -49,9 +46,9 @@ import org.jclouds.compute.domain.internal.CreateNodeResponseImpl;
import org.jclouds.compute.domain.internal.NodeMetadataImpl; import org.jclouds.compute.domain.internal.NodeMetadataImpl;
import org.jclouds.compute.options.RunNodeOptions; import org.jclouds.compute.options.RunNodeOptions;
import org.jclouds.compute.reference.ComputeServiceConstants; import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.compute.util.ComputeUtils;
import org.jclouds.domain.Credentials; import org.jclouds.domain.Credentials;
import org.jclouds.logging.Logger; import org.jclouds.logging.Logger;
import org.jclouds.ssh.SshClient;
import org.jclouds.vcloud.VCloudClient; import org.jclouds.vcloud.VCloudClient;
import org.jclouds.vcloud.VCloudMediaType; import org.jclouds.vcloud.VCloudMediaType;
import org.jclouds.vcloud.domain.NamedResource; import org.jclouds.vcloud.domain.NamedResource;
@ -78,10 +75,8 @@ public class VCloudComputeService implements ComputeService, VCloudComputeClient
protected final Provider<Set<? extends Image>> images; protected final Provider<Set<? extends Image>> images;
protected final Provider<Set<? extends Size>> sizes; protected final Provider<Set<? extends Size>> sizes;
protected final Provider<TemplateBuilder> templateBuilderProvider; protected final Provider<TemplateBuilder> templateBuilderProvider;
private final Predicate<String> taskTester; protected final ComputeUtils utils;
@Inject(optional = true) protected final Predicate<String> taskTester;
private SshClient.Factory sshFactory;
private Predicate<InetSocketAddress> socketTester;
protected static final Map<VAppStatus, NodeState> vAppStatusToNodeState = ImmutableMap protected static final Map<VAppStatus, NodeState> vAppStatusToNodeState = ImmutableMap
.<VAppStatus, NodeState> builder().put(VAppStatus.OFF, NodeState.TERMINATED).put( .<VAppStatus, NodeState> builder().put(VAppStatus.OFF, NodeState.TERMINATED).put(
@ -93,13 +88,13 @@ public class VCloudComputeService implements ComputeService, VCloudComputeClient
public VCloudComputeService(VCloudClient client, public VCloudComputeService(VCloudClient client,
Provider<TemplateBuilder> templateBuilderProvider, Provider<TemplateBuilder> templateBuilderProvider,
Provider<Set<? extends Image>> images, Provider<Set<? extends Size>> sizes, Provider<Set<? extends Image>> images, Provider<Set<? extends Size>> sizes,
Predicate<String> successTester, Predicate<InetSocketAddress> socketTester) { ComputeUtils utils, Predicate<String> successTester) {
this.taskTester = successTester; this.taskTester = successTester;
this.client = client; this.client = client;
this.images = images; this.images = images;
this.sizes = sizes; this.sizes = sizes;
this.templateBuilderProvider = templateBuilderProvider; this.templateBuilderProvider = templateBuilderProvider;
this.socketTester = socketTester; this.utils = utils;
} }
@Override @Override
@ -117,54 +112,18 @@ public class VCloudComputeService implements ComputeService, VCloudComputeClient
VApp vApp = client.getVApp(metaMap.get("id")); VApp vApp = client.getVApp(metaMap.get("id"));
CreateNodeResponse node = newCreateNodeResponse(template, metaMap, vApp); CreateNodeResponse node = newCreateNodeResponse(template, metaMap, vApp);
if (options.getRunScript() != null) { if (options.getRunScript() != null) {
checkState(this.sshFactory != null, "runScript requested, but no SshModule configured"); utils.runScriptOnNode(node, options.getRunScript());
runScriptOnNode(node, options.getRunScript());
} }
return node; return node;
} }
private void runScriptOnNode(CreateNodeResponse node, byte[] script) {
InetSocketAddress socket = new InetSocketAddress(node.getPublicAddresses().last(), node
.getLoginPort());
socketTester.apply(socket);
SshClient ssh = isKeyBasedAuth(node) ? sshFactory.create(socket,
node.getCredentials().account, node.getCredentials().key.getBytes()) : sshFactory
.create(socket, node.getCredentials().account, node.getCredentials().key);
try {
ssh.connect();
String scriptName = node.getId() + ".sh";
ssh.put(scriptName, new ByteArrayInputStream(script));
ssh.exec("chmod 755 " + scriptName);
if (node.getCredentials().account.equals("root")) {
logger.debug(">> running %s as %s", scriptName, node.getCredentials().account);
logger.debug("<< complete(%d)", ssh.exec("./" + scriptName).getExitCode());
} else if (isKeyBasedAuth(node)) {
logger.debug(">> running sudo %s as %s", scriptName, node.getCredentials().account);
logger.debug("<< complete(%d)", ssh.exec("sudo ./" + scriptName).getExitCode());
} else {
logger.debug(">> running sudo -S %s as %s", scriptName, node.getCredentials().account);
logger.debug("<< complete(%d)", ssh.exec(
String.format("echo %s|sudo -S ./%s", node.getCredentials().key, scriptName))
.getExitCode());
}
} finally {
if (ssh != null)
ssh.disconnect();
}
}
private boolean isKeyBasedAuth(CreateNodeResponse node) {
return node.getCredentials().key.startsWith("-----BEGIN RSA PRIVATE KEY-----");
}
protected CreateNodeResponse newCreateNodeResponse(Template template, protected CreateNodeResponse newCreateNodeResponse(Template template,
Map<String, String> metaMap, VApp vApp) { Map<String, String> metaMap, VApp vApp) {
return new CreateNodeResponseImpl(vApp.getId(), vApp.getName(), template.getImage() return new CreateNodeResponseImpl(vApp.getId(), vApp.getName(), template.getImage()
.getLocation(), vApp.getLocation(), ImmutableMap.<String, String> of(), .getLocation(), vApp.getLocation(), ImmutableMap.<String, String> of(),
vAppStatusToNodeState.get(vApp.getStatus()), getPublicAddresses(vApp.getId()), vAppStatusToNodeState.get(vApp.getStatus()), getPublicAddresses(vApp.getId()),
getPrivateAddresses(vApp.getId()), 22, LoginType.SSH, new Credentials(metaMap getPrivateAddresses(vApp.getId()), new Credentials(metaMap.get("username"), metaMap
.get("username"), metaMap.get("password")), ImmutableMap .get("password")), ImmutableMap.<String, String> of());
.<String, String> of());
} }
@Override @Override
@ -175,12 +134,12 @@ public class VCloudComputeService implements ComputeService, VCloudComputeClient
node.getId(), "node.id")); node.getId(), "node.id"));
} }
private NodeMetadata getNodeMetadataByIdInVDC(String vDCId, String id) { protected NodeMetadata getNodeMetadataByIdInVDC(String vDCId, String id) {
VApp vApp = client.getVApp(id); VApp vApp = client.getVApp(id);
return new NodeMetadataImpl(vApp.getId(), vApp.getName(), vDCId, vApp.getLocation(), return new NodeMetadataImpl(vApp.getId(), vApp.getName(), vDCId, vApp.getLocation(),
ImmutableMap.<String, String> of(), vAppStatusToNodeState.get(vApp.getStatus()), ImmutableMap.<String, String> of(), vAppStatusToNodeState.get(vApp.getStatus()),
vApp.getNetworkToAddresses().values(), ImmutableSet.<InetAddress> of(), 22, vApp.getNetworkToAddresses().values(), ImmutableSet.<InetAddress> of(), ImmutableMap
LoginType.SSH, ImmutableMap.<String, String> of()); .<String, String> of());
} }
@Override @Override

View File

@ -33,7 +33,7 @@ import org.jclouds.compute.ComputeService;
import org.jclouds.compute.ComputeServiceContext; import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.domain.Architecture; import org.jclouds.compute.domain.Architecture;
import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.OperatingSystem; import org.jclouds.compute.domain.OsFamily;
import org.jclouds.compute.domain.Size; import org.jclouds.compute.domain.Size;
import org.jclouds.compute.domain.internal.ImageImpl; import org.jclouds.compute.domain.internal.ImageImpl;
import org.jclouds.compute.domain.internal.SizeImpl; import org.jclouds.compute.domain.internal.SizeImpl;
@ -120,8 +120,8 @@ public class VCloudComputeServiceContextModule extends VCloudContextModule {
responses.add(executor.submit(new Callable<Void>() { responses.add(executor.submit(new Callable<Void>() {
@Override @Override
public Void call() throws Exception { public Void call() throws Exception {
OperatingSystem myOs = null; OsFamily myOs = null;
for (OperatingSystem os : OperatingSystem.values()) { for (OsFamily os : OsFamily.values()) {
if (resource.getName().toLowerCase().replaceAll("\\s", "").indexOf( if (resource.getName().toLowerCase().replaceAll("\\s", "").indexOf(
os.toString()) != -1) { os.toString()) != -1) {
myOs = os; myOs = os;

View File

@ -28,7 +28,7 @@ import java.util.Map;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
import org.jclouds.compute.domain.OperatingSystem; import org.jclouds.compute.domain.OsFamily;
import org.jclouds.logging.log4j.config.Log4JLoggingModule; import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.ssh.jsch.config.JschSshClientModule; import org.jclouds.ssh.jsch.config.JschSshClientModule;
import org.jclouds.vcloud.VCloudClient; import org.jclouds.vcloud.VCloudClient;
@ -73,14 +73,14 @@ public class VCloudComputeClientLiveTest {
} }
} }
protected Map<OperatingSystem, Expectation> expectationMap; protected Map<OsFamily, Expectation> expectationMap;
protected Predicate<InetAddress> addressTester; protected Predicate<InetAddress> addressTester;
@Test(enabled = true) @Test(enabled = true)
public void testPowerOn() throws InterruptedException, ExecutionException, TimeoutException, public void testPowerOn() throws InterruptedException, ExecutionException, TimeoutException,
IOException { IOException {
OperatingSystem toTest = OperatingSystem.CENTOS; OsFamily toTest = OsFamily.CENTOS;
String serverName = getCompatibleServerName(toTest); String serverName = getCompatibleServerName(toTest);
int processorCount = 1; int processorCount = 1;
@ -98,7 +98,7 @@ public class VCloudComputeClientLiveTest {
assertEquals(vApp.getStatus(), VAppStatus.ON); assertEquals(vApp.getStatus(), VAppStatus.ON);
} }
private String getCompatibleServerName(OperatingSystem toTest) { private String getCompatibleServerName(OsFamily toTest) {
String serverName = CaseFormat.UPPER_UNDERSCORE String serverName = CaseFormat.UPPER_UNDERSCORE
.to(CaseFormat.LOWER_HYPHEN, toTest.toString()).substring(0, .to(CaseFormat.LOWER_HYPHEN, toTest.toString()).substring(0,
toTest.toString().length() <= 15 ? toTest.toString().length() : 14); toTest.toString().length() <= 15 ? toTest.toString().length() : 14);
@ -149,8 +149,8 @@ public class VCloudComputeClientLiveTest {
client = injector.getInstance(VCloudClient.class); client = injector.getInstance(VCloudClient.class);
addressTester = injector.getInstance(Key.get(new TypeLiteral<Predicate<InetAddress>>() { addressTester = injector.getInstance(Key.get(new TypeLiteral<Predicate<InetAddress>>() {
})); }));
expectationMap = ImmutableMap.<OperatingSystem, Expectation> builder().put( expectationMap = ImmutableMap.<OsFamily, Expectation> builder().put(
OperatingSystem.CENTOS, OsFamily.CENTOS,
new Expectation(4194304 / 2 * 10, "Red Hat Enterprise Linux 5 (64-bit)")).build(); new Expectation(4194304 / 2 * 10, "Red Hat Enterprise Linux 5 (64-bit)")).build();
service = "vcloudtest"; service = "vcloudtest";
templateId = "3"; templateId = "3";

View File

@ -2,7 +2,6 @@ package org.jclouds.vcloud.hostingdotcom.compute;
import static com.google.common.base.Preconditions.checkState; import static com.google.common.base.Preconditions.checkState;
import java.net.InetSocketAddress;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@ -13,6 +12,7 @@ import javax.inject.Singleton;
import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.Size; import org.jclouds.compute.domain.Size;
import org.jclouds.compute.domain.TemplateBuilder; import org.jclouds.compute.domain.TemplateBuilder;
import org.jclouds.compute.util.ComputeUtils;
import org.jclouds.vcloud.VCloudClient; import org.jclouds.vcloud.VCloudClient;
import org.jclouds.vcloud.compute.VCloudComputeService; import org.jclouds.vcloud.compute.VCloudComputeService;
import org.jclouds.vcloud.domain.VApp; import org.jclouds.vcloud.domain.VApp;
@ -31,8 +31,8 @@ public class HostingDotComVCloudComputeService extends VCloudComputeService {
HostingDotComVCloudComputeService(VCloudClient client, HostingDotComVCloudComputeService(VCloudClient client,
Provider<TemplateBuilder> templateBuilderProvider, Provider<TemplateBuilder> templateBuilderProvider,
Provider<Set<? extends Image>> images, Provider<Set<? extends Size>> sizes, Provider<Set<? extends Image>> images, Provider<Set<? extends Size>> sizes,
Predicate<String> successTester, Predicate<InetSocketAddress> socketTester) { Predicate<String> successTester, ComputeUtils utils) {
super(client, templateBuilderProvider, images, sizes, successTester, socketTester); super(client, templateBuilderProvider, images, sizes, utils, successTester);
} }
@Override @Override

View File

@ -22,7 +22,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
import java.net.InetAddress; import java.net.InetAddress;
import org.jclouds.compute.domain.OperatingSystem; import org.jclouds.compute.domain.OsFamily;
import org.jclouds.logging.log4j.config.Log4JLoggingModule; import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.ssh.jsch.config.JschSshClientModule; import org.jclouds.ssh.jsch.config.JschSshClientModule;
import org.jclouds.vcloud.compute.VCloudComputeClientLiveTest; import org.jclouds.vcloud.compute.VCloudComputeClientLiveTest;
@ -57,8 +57,8 @@ public class HostingDotComVCloudComputeClientLiveTest extends VCloudComputeClien
client = injector.getInstance(HostingDotComVCloudClient.class); client = injector.getInstance(HostingDotComVCloudClient.class);
addressTester = injector.getInstance(Key.get(new TypeLiteral<Predicate<InetAddress>>() { addressTester = injector.getInstance(Key.get(new TypeLiteral<Predicate<InetAddress>>() {
})); }));
expectationMap = ImmutableMap.<OperatingSystem, Expectation> builder().put( expectationMap = ImmutableMap.<OsFamily, Expectation> builder().put(
OperatingSystem.CENTOS, OsFamily.CENTOS,
new Expectation(4194304 / 2 * 10, "Red Hat Enterprise Linux 5 (64-bit)")).build(); new Expectation(4194304 / 2 * 10, "Red Hat Enterprise Linux 5 (64-bit)")).build();
service = "vcloudtest"; service = "vcloudtest";
templateId = "3"; templateId = "3";

View File

@ -19,7 +19,7 @@
package org.jclouds.vcloud.hostingdotcom.compute; package org.jclouds.vcloud.hostingdotcom.compute;
import static org.jclouds.compute.domain.OperatingSystem.CENTOS; import static org.jclouds.compute.domain.OsFamily.CENTOS;
import org.jclouds.compute.BaseComputeServiceLiveTest; import org.jclouds.compute.BaseComputeServiceLiveTest;
import org.jclouds.compute.domain.Template; import org.jclouds.compute.domain.Template;
@ -42,7 +42,7 @@ public class HostingDotComVCloudComputeServiceLiveTest extends BaseComputeServic
} }
protected Template buildTemplate(TemplateBuilder templateBuilder) { protected Template buildTemplate(TemplateBuilder templateBuilder) {
return templateBuilder.os(CENTOS).smallest().build(); return templateBuilder.osFamily(CENTOS).smallest().build();
} }
@Override @Override

View File

@ -31,7 +31,7 @@ import javax.annotation.Resource;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Named; import javax.inject.Named;
import org.jclouds.compute.domain.OperatingSystem; import org.jclouds.compute.domain.OsFamily;
import org.jclouds.compute.reference.ComputeServiceConstants; import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.logging.Logger; import org.jclouds.logging.Logger;
import org.jclouds.vcloud.domain.Task; import org.jclouds.vcloud.domain.Task;
@ -68,13 +68,13 @@ public class TerremarkVCloudComputeClient {
this.taskTester = successTester; this.taskTester = successTester;
} }
private Map<OperatingSystem, String> imageCatalogIdMap = ImmutableMap private Map<OsFamily, String> imageCatalogIdMap = ImmutableMap
.<OperatingSystem, String> builder().put(OperatingSystem.CENTOS, "6").put( .<OsFamily, String> builder().put(OsFamily.CENTOS, "6").put(
OperatingSystem.RHEL, "8").put(OperatingSystem.UBUNTU, "10").build(); OsFamily.RHEL, "8").put(OsFamily.UBUNTU, "10").build();
// .put( OperatingSystem.UBUNTU_JEOS_90, "11").put(OperatingSystem.WEBAPPVM_93, "29") // .put( OperatingSystem.UBUNTU_JEOS_90, "11").put(OperatingSystem.WEBAPPVM_93, "29")
public String start(String name, OperatingSystem image, int minCores, int minMegs, public String start(String name, OsFamily image, int minCores, int minMegs,
Map<String, String> properties) { Map<String, String> properties) {
checkArgument(imageCatalogIdMap.containsKey(image), "image not configured: " + image); checkArgument(imageCatalogIdMap.containsKey(image), "image not configured: " + image);
return start(name, imageCatalogIdMap.get(image), minCores, minMegs, properties); return start(name, imageCatalogIdMap.get(image), minCores, minMegs, properties);

View File

@ -21,7 +21,6 @@ package org.jclouds.vcloud.terremark.compute;
import static org.jclouds.vcloud.terremark.options.AddInternetServiceOptions.Builder.withDescription; import static org.jclouds.vcloud.terremark.options.AddInternetServiceOptions.Builder.withDescription;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.SortedSet; import java.util.SortedSet;
@ -33,9 +32,12 @@ import javax.inject.Provider;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.Size; import org.jclouds.compute.domain.Size;
import org.jclouds.compute.domain.TemplateBuilder; import org.jclouds.compute.domain.TemplateBuilder;
import org.jclouds.compute.domain.internal.NodeMetadataImpl;
import org.jclouds.compute.reference.ComputeServiceConstants; import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.compute.util.ComputeUtils;
import org.jclouds.logging.Logger; import org.jclouds.logging.Logger;
import org.jclouds.vcloud.compute.VCloudComputeService; import org.jclouds.vcloud.compute.VCloudComputeService;
import org.jclouds.vcloud.domain.VApp; import org.jclouds.vcloud.domain.VApp;
@ -64,8 +66,8 @@ public class TerremarkVCloudComputeService extends VCloudComputeService {
public TerremarkVCloudComputeService(TerremarkVCloudClient client, public TerremarkVCloudComputeService(TerremarkVCloudClient client,
Provider<TemplateBuilder> templateBuilderProvider, Provider<TemplateBuilder> templateBuilderProvider,
Provider<Set<? extends Image>> images, Provider<Set<? extends Size>> sizes, Provider<Set<? extends Image>> images, Provider<Set<? extends Size>> sizes,
Predicate<String> successTester, Predicate<InetSocketAddress> socketTester) { Predicate<String> successTester, ComputeUtils utils) {
super(client, templateBuilderProvider, images, sizes, successTester, socketTester); super(client, templateBuilderProvider, images, sizes, utils, successTester);
this.client = client; this.client = client;
} }
@ -85,6 +87,15 @@ public class TerremarkVCloudComputeService extends VCloudComputeService {
return response; return response;
} }
@Override
protected 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()),
getPublicAddresses(id), vApp.getNetworkToAddresses().values(), ImmutableMap
.<String, String> of());
}
public InetAddress createPublicAddressMappedToPorts(String vAppId, int... ports) { public InetAddress createPublicAddressMappedToPorts(String vAppId, int... ports) {
VApp vApp = client.getVApp(vAppId); VApp vApp = client.getVApp(vAppId);
PublicIpAddress ip = null; PublicIpAddress ip = null;

View File

@ -27,7 +27,7 @@ import java.util.Map;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
import org.jclouds.compute.domain.OperatingSystem; import org.jclouds.compute.domain.OsFamily;
import org.jclouds.logging.log4j.config.Log4JLoggingModule; import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.ssh.jsch.config.JschSshClientModule; import org.jclouds.ssh.jsch.config.JschSshClientModule;
import org.jclouds.vcloud.domain.ResourceType; import org.jclouds.vcloud.domain.ResourceType;
@ -73,12 +73,12 @@ public class TerremarkVCloudComputeClientLiveTest {
} }
} }
private Map<OperatingSystem, Expectation> expectationMap = ImmutableMap private Map<OsFamily, Expectation> expectationMap = ImmutableMap
.<OperatingSystem, Expectation> builder().put(OperatingSystem.CENTOS, .<OsFamily, Expectation> builder().put(OsFamily.CENTOS,
new Expectation(10485760, "Red Hat Enterprise Linux 5 (64-bit)")).put( new Expectation(10485760, "Red Hat Enterprise Linux 5 (64-bit)")).put(
OperatingSystem.RHEL, OsFamily.RHEL,
new Expectation(10485760, "Red Hat Enterprise Linux 5 (64-bit)")).put( new Expectation(10485760, "Red Hat Enterprise Linux 5 (64-bit)")).put(
OperatingSystem.UBUNTU, new Expectation(4194304, "Ubuntu Linux (64-bit)")) OsFamily.UBUNTU, new Expectation(4194304, "Ubuntu Linux (64-bit)"))
.build(); .build();
// .put(OperatingSystem.UBUNTU, new Expectation(4194304, "Ubuntu Linux (32-bit)")) // .put(OperatingSystem.UBUNTU, new Expectation(4194304, "Ubuntu Linux (32-bit)"))
private Predicate<InetAddress> addressTester; private Predicate<InetAddress> addressTester;
@ -86,7 +86,7 @@ public class TerremarkVCloudComputeClientLiveTest {
@Test @Test
public void testPowerOn() throws InterruptedException, ExecutionException, TimeoutException, public void testPowerOn() throws InterruptedException, ExecutionException, TimeoutException,
IOException { IOException {
OperatingSystem toTest = OperatingSystem.CENTOS; OsFamily toTest = OsFamily.CENTOS;
String serverName = getCompatibleServerName(toTest); String serverName = getCompatibleServerName(toTest);
int processorCount = 1; int processorCount = 1;
@ -102,7 +102,7 @@ public class TerremarkVCloudComputeClientLiveTest {
assertEquals(vApp.getStatus(), VAppStatus.ON); assertEquals(vApp.getStatus(), VAppStatus.ON);
} }
private String getCompatibleServerName(OperatingSystem toTest) { private String getCompatibleServerName(OsFamily toTest) {
String serverName = CaseFormat.UPPER_UNDERSCORE String serverName = CaseFormat.UPPER_UNDERSCORE
.to(CaseFormat.LOWER_HYPHEN, toTest.toString()).substring(0, .to(CaseFormat.LOWER_HYPHEN, toTest.toString()).substring(0,
toTest.toString().length() <= 15 ? toTest.toString().length() : 14); toTest.toString().length() <= 15 ? toTest.toString().length() : 14);

View File

@ -19,7 +19,7 @@
package org.jclouds.vcloud.terremark.compute; package org.jclouds.vcloud.terremark.compute;
import static org.jclouds.compute.domain.OperatingSystem.JEOS; import static org.jclouds.compute.domain.OsFamily.UBUNTU;
import org.jclouds.compute.BaseComputeServiceLiveTest; import org.jclouds.compute.BaseComputeServiceLiveTest;
import org.jclouds.compute.ComputeServiceContextFactory; import org.jclouds.compute.ComputeServiceContextFactory;
@ -49,7 +49,7 @@ public class TerremarkVCloudComputeServiceLiveTest extends BaseComputeServiceLiv
} }
protected Template buildTemplate(TemplateBuilder templateBuilder) { protected Template buildTemplate(TemplateBuilder templateBuilder) {
return templateBuilder.os(JEOS).osVersionMatches(".*9.04.*").smallest().build(); return templateBuilder.osFamily(UBUNTU).smallest().build();
} }
@Override @Override