Issue 130: added rimu and vanilla vcloud, hardened state changes to delete with status checks, added example build.properties to ant samples

git-svn-id: http://jclouds.googlecode.com/svn/trunk@2727 3d8758e0-26b5-11de-8745-db77d3ebf521
This commit is contained in:
adrian.f.cole 2010-01-23 03:22:28 +00:00
parent c6de9196a1
commit 9d305c95a9
41 changed files with 616 additions and 140 deletions

View File

@ -81,18 +81,21 @@ public class EC2ComputeService implements ComputeService {
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<RunningInstance> instanceStateRunning; private final Predicate<RunningInstance> instanceStateRunning;
private final Predicate<RunningInstance> instanceStateTerminated;
private final RunningInstanceToNodeMetadata runningInstanceToNodeMetadata; private final RunningInstanceToNodeMetadata runningInstanceToNodeMetadata;
@Inject @Inject
public EC2ComputeService(EC2Client client, Provider<TemplateBuilder> templateBuilderProvider, public EC2ComputeService(EC2Client client, Provider<TemplateBuilder> templateBuilderProvider,
Provider<Set<? extends Image>> images, Provider<Set<? extends Size>> sizes, Provider<Set<? extends Image>> images, Provider<Set<? extends Size>> sizes,
Predicate<RunningInstance> instanceStateRunning, @Named("RUNNING") Predicate<RunningInstance> instanceStateRunning,
@Named("TERMINATED") Predicate<RunningInstance> instanceStateTerminated,
RunningInstanceToNodeMetadata runningInstanceToNodeMetadata) { RunningInstanceToNodeMetadata runningInstanceToNodeMetadata) {
this.ec2Client = client; this.ec2Client = client;
this.images = images; this.images = images;
this.sizes = sizes; this.sizes = sizes;
this.templateBuilderProvider = templateBuilderProvider; this.templateBuilderProvider = templateBuilderProvider;
this.instanceStateRunning = instanceStateRunning; this.instanceStateRunning = instanceStateRunning;
this.instanceStateTerminated = instanceStateTerminated;
this.runningInstanceToNodeMetadata = runningInstanceToNodeMetadata; this.runningInstanceToNodeMetadata = runningInstanceToNodeMetadata;
} }
@ -289,7 +292,8 @@ public class EC2ComputeService implements ComputeService {
String name = runningInstance.getKeyName(); String name = runningInstance.getKeyName();
logger.debug(">> terminating instance(%s)", node.getId()); logger.debug(">> terminating instance(%s)", node.getId());
ec2Client.getInstanceServices().terminateInstancesInRegion(region, node.getId()); ec2Client.getInstanceServices().terminateInstancesInRegion(region, node.getId());
logger.debug("<< terminated instance(%s)", node.getId()); boolean success = instanceStateTerminated.apply(runningInstance);
logger.debug("<< terminated instance(%s) success(%s)", node.getId(), success);
logger.debug(">> deleting keyPair(%s)", name); logger.debug(">> deleting keyPair(%s)", name);
ec2Client.getKeyPairServices().deleteKeyPairInRegion(region, name); ec2Client.getKeyPairServices().deleteKeyPairInRegion(region, name);
logger.debug("<< deleted keyPair(%s)", name); logger.debug("<< deleted keyPair(%s)", name);

View File

@ -109,14 +109,14 @@ public class EC2ComputeServiceContextModule extends EC2ContextModule {
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"))) {
OsFamily os = null; OsFamily os = null;
String osDescription = ""; String osDescription = from.getImageLocation();
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 = OsFamily.fromValue(matcher.group(1)); os = OsFamily.fromValue(matcher.group(1));
osDescription = matcher.group(2); matcher.group(2);//TODO no field for os version
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));

View File

@ -83,10 +83,19 @@ import com.google.inject.Provides;
public class EC2RestClientModule extends AbstractModule { public class EC2RestClientModule extends AbstractModule {
@Provides @Provides
@Singleton @Singleton
@Named("RUNNING")
protected Predicate<RunningInstance> instanceStateRunning(InstanceStateRunning stateRunning) { protected Predicate<RunningInstance> instanceStateRunning(InstanceStateRunning stateRunning) {
return new RetryablePredicate<RunningInstance>(stateRunning, 600, 3, TimeUnit.SECONDS); return new RetryablePredicate<RunningInstance>(stateRunning, 600, 3, TimeUnit.SECONDS);
} }
@Provides
@Singleton
@Named("TERMINATED")
protected Predicate<RunningInstance> instanceStateTerminated(InstanceStateRunning stateTerminated) {
return new RetryablePredicate<RunningInstance>(stateTerminated, 600, 50,
TimeUnit.MILLISECONDS);
}
@Override @Override
protected void configure() { protected void configure() {
bindErrorHandlers(); bindErrorHandlers();

View File

@ -18,6 +18,8 @@
*/ */
package org.jclouds.aws.ec2.predicates; package org.jclouds.aws.ec2.predicates;
import java.util.NoSuchElementException;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.inject.Singleton; import javax.inject.Singleton;
@ -51,8 +53,11 @@ public class InstanceStateTerminated implements Predicate<RunningInstance> {
public boolean apply(RunningInstance instance) { public boolean apply(RunningInstance instance) {
logger.trace("looking for state on instance %s", instance); logger.trace("looking for state on instance %s", instance);
try {
instance = refresh(instance); instance = refresh(instance);
} catch (NoSuchElementException e) {
return true;
}
logger.trace("%s: looking for instance state %s: currently: %s", instance.getId(), logger.trace("%s: looking for instance state %s: currently: %s", instance.getId(),
InstanceState.TERMINATED, instance.getInstanceState()); InstanceState.TERMINATED, instance.getInstanceState());
return instance.getInstanceState() == InstanceState.TERMINATED; return instance.getInstanceState() == InstanceState.TERMINATED;

View File

@ -36,7 +36,7 @@ public class ImageImpl implements Image {
private final String description; private final String description;
private final String version; private final String version;
private final OsFamily operatingSystem; private final OsFamily operatingSystem;
private final String operatingSystemVersion; private final String operatingSystemDescription;
private final String location; private final String location;
private final Architecture architecture; private final Architecture architecture;
@ -57,12 +57,12 @@ public class ImageImpl implements Image {
} }
public ImageImpl(String id, String description, String version, OsFamily operatingSystem, public ImageImpl(String id, String description, String version, OsFamily operatingSystem,
String operatingSystemVersion, String location, Architecture architecture) { String operatingSystemDescription, String location, Architecture architecture) {
this.id = id; this.id = id;
this.description = description; this.description = description;
this.version = version; this.version = version;
this.operatingSystem = operatingSystem; this.operatingSystem = operatingSystem;
this.operatingSystemVersion = operatingSystemVersion; this.operatingSystemDescription = operatingSystemDescription;
this.location = location; this.location = location;
this.architecture = architecture; this.architecture = architecture;
} }
@ -116,7 +116,7 @@ public class ImageImpl implements Image {
public String toString() { public String toString() {
return "[id=" + id + ", version=" + version + ", location=" + location + ", architecture=" return "[id=" + id + ", version=" + version + ", location=" + location + ", architecture="
+ architecture + ", operatingSystem=" + operatingSystem + architecture + ", operatingSystem=" + operatingSystem
+ ", operatingSystemVersion=" + operatingSystemVersion + ", description=" + ", operatingSystemVersion=" + operatingSystemDescription + ", description="
+ description + "]"; + description + "]";
} }
@ -173,7 +173,7 @@ public class ImageImpl implements Image {
*/ */
@Override @Override
public String getOsDescription() { public String getOsDescription() {
return operatingSystemVersion; return operatingSystemDescription;
} }
} }

View File

@ -22,6 +22,8 @@ terremark.contextbuilder=org.jclouds.vcloud.terremark.compute.TerremarkVCloudCom
terremark.propertiesbuilder=org.jclouds.vcloud.terremark.TerremarkVCloudPropertiesBuilder terremark.propertiesbuilder=org.jclouds.vcloud.terremark.TerremarkVCloudPropertiesBuilder
hostingdotcom.contextbuilder=org.jclouds.vcloud.hostingdotcom.compute.HostingDotComVCloudComputeServiceContextBuilder hostingdotcom.contextbuilder=org.jclouds.vcloud.hostingdotcom.compute.HostingDotComVCloudComputeServiceContextBuilder
hostingdotcom.propertiesbuilder=org.jclouds.vcloud.hostingdotcom.HostingDotComVCloudPropertiesBuilder hostingdotcom.propertiesbuilder=org.jclouds.vcloud.hostingdotcom.HostingDotComVCloudPropertiesBuilder
vcloud.contextbuilder=org.jclouds.vcloud.compute.VCloudComputeServiceContextBuilder
vcloud.propertiesbuilder=org.jclouds.vcloud.VCloudPropertiesBuilder
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.contextbuilder=org.jclouds.rackspace.cloudservers.compute.CloudServersComputeServiceContextBuilder

View File

@ -98,7 +98,7 @@ public abstract class BaseComputeServiceLiveTest {
client = context.getComputeService(); client = context.getComputeService();
} }
private boolean canRunScript(Template template) { protected boolean canRunScript(Template template) {
return template.getImage().getOsFamily() == OsFamily.UBUNTU return template.getImage().getOsFamily() == OsFamily.UBUNTU
|| template.getImage().getOsFamily() == OsFamily.JEOS; || template.getImage().getOsFamily() == OsFamily.JEOS;
} }
@ -137,10 +137,12 @@ public abstract class BaseComputeServiceLiveTest {
assertNotNull(node.getName()); assertNotNull(node.getName());
assertEquals(node.getPublicAddresses().size(), 1); assertEquals(node.getPublicAddresses().size(), 1);
assertNotNull(node.getCredentials()); assertNotNull(node.getCredentials());
if (node.getCredentials().account != null) {
assertNotNull(node.getCredentials().account); assertNotNull(node.getCredentials().account);
assertNotNull(node.getCredentials().key); assertNotNull(node.getCredentials().key);
sshPing(); sshPing();
} }
}
protected abstract Template buildTemplate(TemplateBuilder templateBuilder); protected abstract Template buildTemplate(TemplateBuilder templateBuilder);
@ -206,7 +208,7 @@ public abstract class BaseComputeServiceLiveTest {
} }
@AfterTest @AfterTest
void cleanup() throws InterruptedException, ExecutionException, TimeoutException { protected void cleanup() throws InterruptedException, ExecutionException, TimeoutException {
if (node != null) if (node != null)
client.destroyNode(node); client.destroyNode(node);
context.close(); context.close();

View File

@ -80,7 +80,7 @@ public abstract class RestContextFactory<T, B extends RestContextBuilder<?, ?>>
* @throws IOException * @throws IOException
* if {@code filename} cannot load. * if {@code filename} cannot load.
*/ */
static Properties getPropertiesFromResource(String filename) throws IOException { public static Properties getPropertiesFromResource(String filename) throws IOException {
Properties properties = new Properties(); Properties properties = new Properties();
properties.load(Resources.newInputStreamSupplier(Resources.getResource(filename)).getInput()); properties.load(Resources.newInputStreamSupplier(Resources.getResource(filename)).getInput());
properties.putAll(System.getProperties()); properties.putAll(System.getProperties());

View File

@ -77,12 +77,14 @@ public class CloudServersComputeService implements ComputeService {
private final ComputeUtils utils; private final ComputeUtils utils;
private final Predicate<Server> serverActive; private final Predicate<Server> serverActive;
private final ServerToNodeMetadata serverToNodeMetadata; private final ServerToNodeMetadata serverToNodeMetadata;
private final Predicate<Server> serverDeleted;
@Inject @Inject
public CloudServersComputeService(CloudServersClient client, public CloudServersComputeService(CloudServersClient client,
Provider<TemplateBuilder> templateBuilderProvider, @ResourceLocation String location, Provider<TemplateBuilder> templateBuilderProvider, @ResourceLocation String location,
Provider<Set<? extends Image>> images, Provider<Set<? extends Size>> sizes, Provider<Set<? extends Image>> images, Provider<Set<? extends Size>> sizes,
ComputeUtils utils, Predicate<Server> serverActive, ComputeUtils utils, @Named("ACTIVE") Predicate<Server> serverActive,
@Named("DELETED") Predicate<Server> serverDeleted,
ServerToNodeMetadata serverToNodeMetadata) { ServerToNodeMetadata serverToNodeMetadata) {
this.location = location; this.location = location;
this.client = client; this.client = client;
@ -91,10 +93,11 @@ public class CloudServersComputeService implements ComputeService {
this.utils = utils; this.utils = utils;
this.templateBuilderProvider = templateBuilderProvider; this.templateBuilderProvider = templateBuilderProvider;
this.serverActive = serverActive; this.serverActive = serverActive;
this.serverDeleted = serverDeleted;
this.serverToNodeMetadata = serverToNodeMetadata; this.serverToNodeMetadata = serverToNodeMetadata;
} }
private static Map<ServerStatus, NodeState> instanceToNodeState = ImmutableMap private static Map<ServerStatus, NodeState> serverToNodeState = ImmutableMap
.<ServerStatus, NodeState> builder().put(ServerStatus.ACTIVE, NodeState.RUNNING)// .<ServerStatus, NodeState> builder().put(ServerStatus.ACTIVE, NodeState.RUNNING)//
.put(ServerStatus.SUSPENDED, NodeState.SUSPENDED)// .put(ServerStatus.SUSPENDED, NodeState.SUSPENDED)//
.put(ServerStatus.DELETED, NodeState.TERMINATED)// .put(ServerStatus.DELETED, NodeState.TERMINATED)//
@ -135,7 +138,7 @@ public class CloudServersComputeService implements ComputeService {
+ template.getSize().getClass()); + template.getSize().getClass());
CloudServersSize cloudServersSize = CloudServersSize.class.cast(template.getSize()); CloudServersSize cloudServersSize = CloudServersSize.class.cast(template.getSize());
logger.debug(">> running instance location(%s) image(%s) flavor(%s)", location, logger.debug(">> running server location(%s) image(%s) flavor(%s)", location,
cloudServersImage.getId(), template.getSize().getId()); cloudServersImage.getId(), template.getSize().getId());
Server server = client.createServer(name, cloudServersImage.getImage().getId(), Server server = client.createServer(name, cloudServersImage.getImage().getId(),
@ -145,9 +148,9 @@ public class CloudServersComputeService implements ComputeService {
null, server.getMetadata(), NodeState.RUNNING, server.getAddresses() null, server.getMetadata(), NodeState.RUNNING, server.getAddresses()
.getPublicAddresses(), server.getAddresses().getPrivateAddresses(), .getPublicAddresses(), server.getAddresses().getPrivateAddresses(),
new Credentials("root", server.getAdminPass()), ImmutableMap.<String, String> of()); new Credentials("root", server.getAdminPass()), ImmutableMap.<String, String> of());
logger.debug("<< started instance(%s)", server.getId()); logger.debug("<< started server(%s)", server.getId());
serverActive.apply(server); serverActive.apply(server);
logger.debug("<< running instance(%s)", server.getId()); logger.debug("<< running server(%s)", server.getId());
if (options.getRunScript() != null) { if (options.getRunScript() != null) {
utils.runScriptOnNode(node, options.getRunScript()); utils.runScriptOnNode(node, options.getRunScript());
} }
@ -175,7 +178,7 @@ public class CloudServersComputeService implements ComputeService {
@Override @Override
public NodeMetadata apply(Server from) { public NodeMetadata apply(Server from) {
return new NodeMetadataImpl(from.getId() + "", from.getName(), location, null, from return new NodeMetadataImpl(from.getId() + "", from.getName(), location, null, from
.getMetadata(), instanceToNodeState.get(from.getStatus()), from.getAddresses() .getMetadata(), serverToNodeState.get(from.getStatus()), from.getAddresses()
.getPublicAddresses(), from.getAddresses().getPrivateAddresses(), ImmutableMap .getPublicAddresses(), from.getAddresses().getPrivateAddresses(), ImmutableMap
.<String, String> of()); .<String, String> of());
} }
@ -197,9 +200,11 @@ public class CloudServersComputeService implements ComputeService {
+ node.getType()); + node.getType());
checkNotNull(node.getId(), "node.id"); checkNotNull(node.getId(), "node.id");
logger.debug(">> terminating instance(%s)", node.getId()); logger.debug(">> deleting server(%s)", node.getId());
boolean success = client.deleteServer(Integer.parseInt(node.getId())); int serverId = Integer.parseInt(node.getId());
logger.debug("<< terminated instance(%s) success(%s)", node.getId(), success); client.deleteServer(serverId);
boolean successful = serverDeleted.apply(client.getServer(serverId));
logger.debug("<< deleted server(%s) success(%s)", node.getId(), successful);
} }
@Override @Override

View File

@ -34,6 +34,7 @@ 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.domain.Server;
import org.jclouds.rackspace.cloudservers.predicates.ServerActive; import org.jclouds.rackspace.cloudservers.predicates.ServerActive;
import org.jclouds.rackspace.cloudservers.predicates.ServerDeleted;
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;
@ -51,8 +52,16 @@ public class CloudServersContextModule extends AbstractModule {
@Provides @Provides
@Singleton @Singleton
protected Predicate<Server> instanceStateRunning(ServerActive stateRunning) { @Named("ACTIVE")
return new RetryablePredicate<Server>(stateRunning, 600, 2, TimeUnit.SECONDS); protected Predicate<Server> serverRunning(ServerActive stateRunning) {
return new RetryablePredicate<Server>(stateRunning, 600, 1, TimeUnit.SECONDS);
}
@Provides
@Singleton
@Named("DELETED")
protected Predicate<Server> serverDeleted(ServerDeleted stateDeleted) {
return new RetryablePredicate<Server>(stateDeleted, 600, 50, TimeUnit.MILLISECONDS);
} }
@Provides @Provides

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 ServerDeleted implements Predicate<Server> {
private final CloudServersClient client;
@Resource
protected Logger logger = Logger.NULL;
@Inject
public ServerDeleted(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.DELETED, server.getStatus());
return server.getStatus() == ServerStatus.DELETED;
} catch (ResourceNotFoundException e) {
return true;
}
}
private Server refresh(Server server) {
return client.getServer(server.getId());
}
}

View File

@ -23,13 +23,12 @@ import static com.google.common.base.Preconditions.checkNotNull;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.SortedSet;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Named; import javax.inject.Named;
import javax.inject.Provider;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.jclouds.compute.ComputeService; import org.jclouds.compute.ComputeService;
@ -39,15 +38,15 @@ import org.jclouds.compute.domain.CreateNodeResponse;
import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.Image;
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.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;
import org.jclouds.compute.domain.internal.ComputeMetadataImpl;
import org.jclouds.compute.domain.internal.CreateNodeResponseImpl; import org.jclouds.compute.domain.internal.CreateNodeResponseImpl;
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.domain.Credentials; import org.jclouds.domain.Credentials;
import org.jclouds.domain.ResourceLocation;
import org.jclouds.logging.Logger; import org.jclouds.logging.Logger;
import org.jclouds.rimuhosting.miro.RimuHostingClient; import org.jclouds.rimuhosting.miro.RimuHostingClient;
import org.jclouds.rimuhosting.miro.domain.NewServerResponse; import org.jclouds.rimuhosting.miro.domain.NewServerResponse;
@ -68,20 +67,23 @@ public class RimuHostingComputeService implements ComputeService {
@Resource @Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER) @Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL; protected Logger logger = Logger.NULL;
protected final RimuHostingClient client;
RimuHostingClient rhClient; protected final Provider<Set<? extends Image>> images;
protected final Provider<Set<? extends Size>> sizes;
protected final Provider<TemplateBuilder> templateBuilderProvider;
private final String location;
@Inject @Inject
public RimuHostingComputeService(RimuHostingClient rhClient) { public RimuHostingComputeService(RimuHostingClient client,
this.rhClient = rhClient; Provider<TemplateBuilder> templateBuilderProvider, @ResourceLocation String location,
Provider<Set<? extends Image>> images, Provider<Set<? extends Size>> sizes) {
this.client = client;
this.location = location;
this.images = images;
this.sizes = sizes;
this.templateBuilderProvider = templateBuilderProvider;
} }
private Map<OsFamily, String> imageNameMap = ImmutableMap.<OsFamily, String> builder().put(
OsFamily.CENTOS, "centos53").put(OsFamily.UBUNTU, "ubuntu904").build();
// private Map<Size, String> profileNameMap = ImmutableMap.<Profile, String> builder().put(
// Profile.SMALLEST, "MIRO1B").build();
@Override @Override
public CreateNodeResponse runNode(String name, Template template) { public CreateNodeResponse runNode(String name, Template template) {
return this.runNode(name, template, RunNodeOptions.NONE); return this.runNode(name, template, RunNodeOptions.NONE);
@ -89,22 +91,23 @@ 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 = client.createServer(name, checkNotNull(template.getImage()
.get(template.getImage().getOsFamily()), "os not supported: " .getId(), "imageId"), checkNotNull(template.getSize().getId(), "sizeId"));
+ template.getImage().getOsFamily()), "MIRO1B"); return new CreateNodeResponseImpl(null,// dunno why there is no information here....
return new CreateNodeResponseImpl(serverResponse.getServer().getId().toString(), name, location, null, ImmutableMap.<String, String> of(), NodeState.UNKNOWN,// TODO
serverResponse.getServer().getName(), "default", null, ImmutableMap // need a
.<String, String> of(), // real
NodeState.RUNNING,// TODO need a real state! // state!
getPublicAddresses(serverResponse.getServer()), ImmutableList.<InetAddress> of(), ImmutableList.<InetAddress> of(),// no real useful data here..
new Credentials("root", serverResponse.getNewInstanceRequest().getCreateOptions() ImmutableList.<InetAddress> of(), new Credentials("root", serverResponse
.getPassword()), ImmutableMap.<String, String> of()); .getNewInstanceRequest().getCreateOptions().getPassword()), ImmutableMap
.<String, String> of());
} }
@VisibleForTesting @VisibleForTesting
static Iterable<InetAddress> getPublicAddresses(Server rhServer) { static Iterable<InetAddress> getPublicAddresses(Server server) {
Iterable<String> addresses = Iterables.concat(ImmutableList.of(rhServer.getIpAddresses() Iterable<String> addresses = Iterables.concat(ImmutableList.of(server.getIpAddresses()
.getPrimaryIp()), rhServer.getIpAddresses().getSecondaryIps()); .getPrimaryIp()), server.getIpAddresses().getSecondaryIps());
return Iterables.transform(addresses, new Function<String, InetAddress>() { return Iterables.transform(addresses, new Function<String, InetAddress>() {
@Override @Override
@ -121,20 +124,26 @@ public class RimuHostingComputeService implements ComputeService {
public Set<ComputeMetadata> listNodes() { public Set<ComputeMetadata> listNodes() {
Set<ComputeMetadata> serverSet = Sets.newLinkedHashSet(); Set<ComputeMetadata> serverSet = Sets.newLinkedHashSet();
Set<Server> rhNodes = rhClient.getServerList(); Set<Server> servers = client.getServerList();
for (Server rhNode : rhNodes) { for (Server server : servers) {
serverSet.add(new ComputeMetadataImpl(ComputeType.NODE, rhNode.getId() + "", rhNode serverSet.add(toNode(server));
.getName(), null, null, ImmutableMap.<String, String> of()));
} }
return serverSet; return serverSet;
} }
private NodeMetadataImpl toNode(Server server) {
return new NodeMetadataImpl(server.getId() + "", server.getName(), location, null,
ImmutableMap.<String, String> of(), NodeState.UNKNOWN, getPublicAddresses(server),
ImmutableList.<InetAddress> of(), ImmutableMap.<String, String> of("state", server
.getState()));
}
@Override @Override
public NodeMetadata getNodeMetadata(ComputeMetadata node) { public NodeMetadata getNodeMetadata(ComputeMetadata node) {
checkArgument(node.getType() == ComputeType.NODE, "this is only valid for nodes, not " checkArgument(node.getType() == ComputeType.NODE, "this is only valid for nodes, not "
+ node.getType()); + node.getType());
checkNotNull(node.getId(), "node.id"); checkNotNull(node.getId(), "node.id");
throw new UnsupportedOperationException("not yet implemented"); return toNode(client.getServer(Long.parseLong(node.getId())));
} }
@Override @Override
@ -142,21 +151,21 @@ public class RimuHostingComputeService implements ComputeService {
checkArgument(node.getType() == ComputeType.NODE, "this is only valid for nodes, not " checkArgument(node.getType() == ComputeType.NODE, "this is only valid for nodes, not "
+ node.getType()); + node.getType());
checkNotNull(node.getId(), "node.id"); checkNotNull(node.getId(), "node.id");
rhClient.destroyServer(new Long(node.getId())); client.destroyServer(new Long(node.getId()));
} }
@Override @Override
public SortedSet<? extends Size> listSizes() { public Set<? extends Size> listSizes() {
return null; return sizes.get();
} }
@Override @Override
public Set<? extends Image> listImages() { public Set<? extends Image> listImages() {
return null; return images.get();
} }
@Override @Override
public TemplateBuilder templateBuilder() { public TemplateBuilder templateBuilder() {
return null; return this.templateBuilderProvider.get();
} }
} }

View File

@ -18,17 +18,38 @@
*/ */
package org.jclouds.rimuhosting.miro.compute.config; package org.jclouds.rimuhosting.miro.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 javax.inject.Singleton;
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.Architecture;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.OsFamily;
import org.jclouds.compute.domain.Size;
import org.jclouds.compute.domain.internal.ImageImpl;
import org.jclouds.compute.domain.internal.SizeImpl;
import org.jclouds.compute.internal.ComputeServiceContextImpl; import org.jclouds.compute.internal.ComputeServiceContextImpl;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.domain.ResourceLocation;
import org.jclouds.logging.Logger;
import org.jclouds.rest.RestContext; import org.jclouds.rest.RestContext;
import org.jclouds.rimuhosting.miro.RimuHostingAsyncClient; import org.jclouds.rimuhosting.miro.RimuHostingAsyncClient;
import org.jclouds.rimuhosting.miro.RimuHostingClient; import org.jclouds.rimuhosting.miro.RimuHostingClient;
import org.jclouds.rimuhosting.miro.compute.RimuHostingComputeService; import org.jclouds.rimuhosting.miro.compute.RimuHostingComputeService;
import org.jclouds.rimuhosting.miro.config.RimuHostingContextModule; import org.jclouds.rimuhosting.miro.config.RimuHostingContextModule;
import org.jclouds.rimuhosting.miro.domain.PricingPlan;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import com.google.inject.Provides; import com.google.inject.Provides;
/** /**
@ -52,4 +73,66 @@ public class RimuHostingComputeServiceContextModule extends RimuHostingContextMo
return new ComputeServiceContextImpl<RimuHostingAsyncClient, RimuHostingClient>( return new ComputeServiceContextImpl<RimuHostingAsyncClient, RimuHostingClient>(
computeService, context); computeService, context);
} }
@Provides
@Singleton
@ResourceLocation
String getRegion() {
return "default";
}
@Provides
@Singleton
protected Set<? extends Size> provideSizes(RimuHostingClient 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 PricingPlan from : sync.getPricingPlanList()) {
sizes.add(new SizeImpl(from.getId(), from.getDiskSize(), from.getRam(),
from.getDiskSize(), 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 RIMU_PATTERN = Pattern.compile("([^0-9]*)(.*)");
@Provides
@Singleton
protected Set<? extends Image> provideImages(final RimuHostingClient 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.rimuhosting.miro.domain.Image from : sync.getImageList()) {
OsFamily os = null;
Architecture arch = from.getId().indexOf("64") == -1 ? Architecture.X86_32
: Architecture.X86_64;
String osDescription = "";
String version = "";
osDescription = from.getId();
Matcher matcher = RIMU_PATTERN.matcher(from.getId());
if (matcher.find()) {
try {
os = OsFamily.fromValue(matcher.group(1).toLowerCase());
} catch (IllegalArgumentException e) {
holder.logger.debug("<< didn't match os(%s)", matcher.group(2));
}
}
images.add(new ImageImpl(from.getId(), from.getDescription(), version, os, osDescription,
location, arch));
}
holder.logger.debug("<< images(%d)", images.size());
return images;
}
} }

View File

@ -32,8 +32,8 @@ public class Server implements Comparable<Server> {
@SerializedName("allocated_ips") @SerializedName("allocated_ips")
private IpAddresses ipAddresses; private IpAddresses ipAddresses;
@SerializedName("billing_info") // @SerializedName("billing_info")
private BillingData billingData; // private BillingData billingData;
@SerializedName("billing_oid") @SerializedName("billing_oid")
private Long billingId; private Long billingId;
@SerializedName("data_transfer_allowance") @SerializedName("data_transfer_allowance")
@ -69,13 +69,13 @@ public class Server implements Comparable<Server> {
this.ipAddresses = ipAddresses; this.ipAddresses = ipAddresses;
} }
public BillingData getBillingData() { // public BillingData getBillingData() {
return billingData; // return billingData;
} // }
//
public void setBillingData(BillingData billingData) { // public void setBillingData(BillingData billingData) {
this.billingData = billingData; // this.billingData = billingData;
} // }
public Long getBillingId() { public Long getBillingId() {
return billingId; return billingId;

View File

@ -51,6 +51,8 @@ public class ParseRimuHostingException implements Function<Exception, Object> {
public Object apply(Exception e) { public Object apply(Exception e) {
if (e instanceof HttpResponseException) { if (e instanceof HttpResponseException) {
HttpResponseException responseException = (HttpResponseException) e; HttpResponseException responseException = (HttpResponseException) e;
if (responseException.getContent() != null) {
Type setType = new TypeToken<Map<String, RimuHostingResponse>>() { Type setType = new TypeToken<Map<String, RimuHostingResponse>>() {
}.getType(); }.getType();
@ -59,6 +61,7 @@ public class ParseRimuHostingException implements Function<Exception, Object> {
throw new RuntimeException(responseMap.values().iterator().next().getErrorInfo() throw new RuntimeException(responseMap.values().iterator().next().getErrorInfo()
.getErrorClass()); .getErrorClass());
} }
}
return propagateOrNull(e); return propagateOrNull(e);
} }
} }

View File

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

View File

@ -0,0 +1,5 @@
service=ec2
driver=aws
account=accesskeyid
key=secretaccesskey
nodename=we_create_and_delete_based_on_key_and_security_group_name_not_instance_id

View File

@ -1,5 +0,0 @@
host=localhost
username=${user.name}
keyfile=${user.home}/.ssh/id_dsa
account=email@registered.with.terremark.org
key=your_password

View File

@ -0,0 +1,5 @@
service=hostingdotcom
driver=hostingdotcom
account=user@youregistered.com
key=password
nodename=name_of_your_vapp

View File

@ -0,0 +1,5 @@
service=cloudservers
driver=rackspace
account=user
key=your_key
nodename=name_of_your_server

View File

@ -0,0 +1,5 @@
service=rimuhosting
driver=rimuhosting
account=apikey
key=apikey
nodename=name_of_your_server

View File

@ -0,0 +1,5 @@
service=terremark
driver=terremark
account=user@youregistered.com
key=password
nodename=name_of_your_vapp

View File

@ -0,0 +1,7 @@
service=vcloud
driver=vcloud
# note you need to change this to the correct endpoint
vcloud.endpoint=https://vcloud_host_you_want/api
account=user@youregistered.com
key=password
nodename=name_of_your_vapp

View File

@ -34,6 +34,18 @@
<get src="http://apache.imghat.com/maven/binaries/maven-ant-tasks-2.1.0.jar" dest="build/maven-ant-tasks-2.1.0.jar"/> <get src="http://apache.imghat.com/maven/binaries/maven-ant-tasks-2.1.0.jar" dest="build/maven-ant-tasks-2.1.0.jar"/>
<get src="http://web-actions.googlecode.com/files/samples-blazeds.war" dest="${warfile}"/> <get src="http://web-actions.googlecode.com/files/samples-blazeds.war" dest="${warfile}"/>
--> -->
<input
message="Which service would you like to use (ec2, cloudservers, vcloud, terremark, rimuhosting, hostingdotcom)?"
validargs="ec2,cloudservers,vcloud,terremark,rimuhosting,hostingdotcom"
addproperty="service"
/>
<input
message="Which driver does ${service} use?"
validargs="aws,rackspace,vcloud,terremark,rimuhosting,hostingdotcom"
addproperty="driver"
/>
<!-- initialize maven tasks --> <!-- initialize maven tasks -->
<path id="maven-ant-tasks.classpath" path="build/maven-ant-tasks-2.1.0.jar"/> <path id="maven-ant-tasks.classpath" path="build/maven-ant-tasks-2.1.0.jar"/>
<typedef resource="org/apache/maven/artifact/ant/antlib.xml" uri="urn:maven-artifact-ant" classpathref="maven-ant-tasks.classpath"/> <typedef resource="org/apache/maven/artifact/ant/antlib.xml" uri="urn:maven-artifact-ant" classpathref="maven-ant-tasks.classpath"/>
@ -46,7 +58,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="${driver}" version="1.0-SNAPSHOT"/> <dependency groupId="org.jclouds" artifactId="jclouds-${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,10 +69,9 @@
<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="${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"/> <input message="What is the nodename for the deployment?" addproperty="nodename"/>
<property name="url" value="compute://${account}:${key}@${service}"/> <property name="url" value="compute://${account}:${key}@${service}"/>
<target name="destroy" description="destroy the node ${nodename}"> <target name="destroy" description="destroy the node ${nodename}">

View File

@ -0,0 +1,5 @@
service=ec2
driver=aws
account=accesskeyid
key=secretaccesskey
nodename=we_create_and_delete_based_on_key_and_security_group_name_not_instance_id

View File

@ -0,0 +1,5 @@
service=hostingdotcom
driver=hostingdotcom
account=user@youregistered.com
key=password
nodename=name_of_your_vapp

View File

@ -0,0 +1,5 @@
service=cloudservers
driver=rackspace
account=user
key=your_key
nodename=name_of_your_server

View File

@ -0,0 +1,5 @@
service=rimuhosting
driver=rimuhosting
account=apikey
key=apikey
nodename=name_of_your_server

View File

@ -0,0 +1,5 @@
service=terremark
driver=terremark
account=user@youregistered.com
key=password
nodename=name_of_your_vapp

View File

@ -0,0 +1,7 @@
service=vcloud
driver=vcloud
# note you need to change this to the correct endpoint
vcloud.endpoint=https://vcloud_host_you_want/api
account=user@youregistered.com
key=password
nodename=name_of_your_vapp

View File

@ -19,11 +19,24 @@
--> -->
<project name="compute" default="list" basedir="." xmlns:artifact="urn:maven-artifact-ant"> <project name="compute" default="list" basedir="." xmlns:artifact="urn:maven-artifact-ant">
<property file="build.properties" />
<mkdir dir="build" /> <mkdir dir="build" />
<!-- <!--
<get src="http://apache.imghat.com/maven/binaries/maven-ant-tasks-2.1.0.jar" dest="build/maven-ant-tasks-2.1.0.jar"/> <get src="http://apache.imghat.com/maven/binaries/maven-ant-tasks-2.1.0.jar" dest="build/maven-ant-tasks-2.1.0.jar"/>
--> -->
<input
message="Which service would you like to use (ec2, cloudservers, vcloud, terremark, rimuhosting, hostingdotcom)?"
validargs="ec2,cloudservers,vcloud,terremark,rimuhosting,hostingdotcom"
addproperty="service"
/>
<input
message="Which driver does ${service} use?"
validargs="aws,rackspace,vcloud,terremark,rimuhosting,hostingdotcom"
addproperty="driver"
/>
<path id="maven-ant-tasks.classpath" path="build/maven-ant-tasks-2.1.0.jar" /> <path id="maven-ant-tasks.classpath" path="build/maven-ant-tasks-2.1.0.jar" />
<typedef resource="org/apache/maven/artifact/ant/antlib.xml" uri="urn:maven-artifact-ant" classpathref="maven-ant-tasks.classpath" /> <typedef resource="org/apache/maven/artifact/ant/antlib.xml" uri="urn:maven-artifact-ant" classpathref="maven-ant-tasks.classpath" />
@ -32,23 +45,13 @@
<artifact:dependencies pathId="jclouds.classpath"> <artifact:dependencies pathId="jclouds.classpath">
<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-${driver}" 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-terremark" version="1.0-SNAPSHOT" />
<localRepository refid="local.repository" /> <localRepository refid="local.repository" />
<remoteRepository refid="jclouds-snapshot.repository" /> <remoteRepository refid="jclouds-snapshot.repository" />
</artifact:dependencies> </artifact:dependencies>
<typedef name="compute" classname="org.jclouds.tools.ant.taskdefs.compute.ComputeTask" classpathref="jclouds.classpath" /> <typedef name="compute" classname="org.jclouds.tools.ant.taskdefs.compute.ComputeTask" classpathref="jclouds.classpath" />
<input
message="Which service would you like to use (ec2, terremark, rimuhosting, hostingdotcom)?"
validargs="ec2,terremark,rimuhosting,hostingdotcom"
addproperty="service"
/>
<input <input
message="What is your account on ${service}?" message="What is your account on ${service}?"
addproperty="account" addproperty="account"

View File

@ -23,6 +23,8 @@
*/ */
package org.jclouds.tools.ant.taskdefs.compute; package org.jclouds.tools.ant.taskdefs.compute;
import static org.jclouds.rest.RestContextFactory.getPropertiesFromResource;
import java.io.IOException; import java.io.IOException;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.URI; import java.net.URI;
@ -77,9 +79,10 @@ public class ComputeTaskUtils {
@Override @Override
public ComputeServiceContext apply(URI from) { public ComputeServiceContext apply(URI from) {
try { try {
Properties props = new Properties(); Properties props = getPropertiesFromResource("compute.properties");
props.putAll(projectProvider.get().getProperties()); props.putAll(projectProvider.get().getProperties());
return new ComputeServiceContextFactory().createContext(from, // adding the properties to the factory will allow us to pass alternate endpoints
return new ComputeServiceContextFactory(props).createContext(from,
ImmutableSet ImmutableSet
.of((Module) new AntLoggingModule(projectProvider.get(), .of((Module) new AntLoggingModule(projectProvider.get(),
ComputeServiceConstants.COMPUTE_LOGGER), ComputeServiceConstants.COMPUTE_LOGGER),

View File

@ -60,6 +60,7 @@ import org.jclouds.vcloud.options.InstantiateVAppTemplateOptions;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import com.google.inject.Inject; import com.google.inject.Inject;
@ -77,6 +78,7 @@ public class VCloudComputeService implements ComputeService, VCloudComputeClient
protected final Provider<TemplateBuilder> templateBuilderProvider; protected final Provider<TemplateBuilder> templateBuilderProvider;
protected final ComputeUtils utils; protected final ComputeUtils utils;
protected final Predicate<String> taskTester; protected final Predicate<String> taskTester;
protected final Predicate<VApp> notFoundTester;
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(
@ -88,13 +90,15 @@ 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,
ComputeUtils utils, Predicate<String> successTester) { ComputeUtils utils, Predicate<String> successTester,
@Named("NOT_FOUND") Predicate<VApp> notFoundTester) {
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.utils = utils; this.utils = utils;
this.notFoundTester = notFoundTester;
} }
@Override @Override
@ -191,14 +195,21 @@ public class VCloudComputeService implements ComputeService, VCloudComputeClient
logger.debug("<< instantiated VApp(%s)", vAppResponse.getId()); logger.debug("<< instantiated VApp(%s)", vAppResponse.getId());
logger.debug(">> deploying vApp(%s)", vAppResponse.getId()); logger.debug(">> deploying vApp(%s)", vAppResponse.getId());
VApp vApp = blockUntilVAppStatusOrThrowException(vAppResponse, client.deployVApp(vAppResponse
.getId()), "deploy", ImmutableSet.of(VAppStatus.OFF, VAppStatus.ON));
logger.debug("<< deployed vApp(%s)", vApp.getId());
logger.debug(">> powering vApp(%s)", vApp.getId()); Task task = client.deployVApp(vAppResponse.getId());
vApp = blockUntilVAppStatusOrThrowException(vApp, client.powerOnVApp(vApp.getId()), if (!taskTester.apply(task.getId())) {
"powerOn", ImmutableSet.of(VAppStatus.ON)); throw new TaskException("deploy", vAppResponse, task);
logger.debug("<< on vApp(%s)", vApp.getId()); }
logger.debug("<< deployed vApp(%s)", vAppResponse.getId());
logger.debug(">> powering vApp(%s)", vAppResponse.getId());
task = client.powerOnVApp(vAppResponse.getId());
if (!taskTester.apply(task.getId())) {
throw new TaskException("powerOn", vAppResponse, task);
}
logger.debug("<< on vApp(%s)", vAppResponse.getId());
Map<String, String> response = parseResponse(vAppResponse); Map<String, String> response = parseResponse(vAppResponse);
checkState(response.containsKey("id"), "bad configuration: [id] should be in response"); checkState(response.containsKey("id"), "bad configuration: [id] should be in response");
checkState(response.containsKey("username"), checkState(response.containsKey("username"),
@ -209,15 +220,20 @@ public class VCloudComputeService implements ComputeService, VCloudComputeClient
} }
protected Map<String, String> parseResponse(VApp vAppResponse) { protected Map<String, String> parseResponse(VApp vAppResponse) {
return ImmutableMap.<String, String> of("id", vAppResponse.getId(), "username", "", Map<String, String> config = Maps.newLinkedHashMap();// Allows nulls
"password", ""); config.put("id", vAppResponse.getId());
config.put("username", null);
config.put("password", null);
return config;
} }
public void reboot(String id) { public void reboot(String id) {
VApp vApp = client.getVApp(id); VApp vApp = client.getVApp(id);
logger.debug(">> rebooting vApp(%s)", vApp.getId()); logger.debug(">> resetting vApp(%s)", vApp.getId());
blockUntilVAppStatusOrThrowException(vApp, client.resetVApp(vApp.getId()), "reset", Task task = client.resetVApp(vApp.getId());
ImmutableSet.of(VAppStatus.ON)); if (!taskTester.apply(task.getId())) {
throw new TaskException("resetVApp", vApp, task);
}
logger.debug("<< on vApp(%s)", vApp.getId()); logger.debug("<< on vApp(%s)", vApp.getId());
} }
@ -226,27 +242,16 @@ public class VCloudComputeService implements ComputeService, VCloudComputeClient
if (vApp.getStatus() != VAppStatus.OFF) { if (vApp.getStatus() != VAppStatus.OFF) {
logger.debug(">> powering off vApp(%s), current status: %s", vApp.getId(), vApp logger.debug(">> powering off vApp(%s), current status: %s", vApp.getId(), vApp
.getStatus()); .getStatus());
blockUntilVAppStatusOrThrowException(vApp, client.powerOffVApp(vApp.getId()), "powerOff", Task task = client.powerOffVApp(vApp.getId());
ImmutableSet.of(VAppStatus.OFF)); if (!taskTester.apply(task.getId())) {
throw new TaskException("powerOff", vApp, task);
}
logger.debug("<< off vApp(%s)", vApp.getId()); logger.debug("<< off vApp(%s)", vApp.getId());
} }
logger.debug(">> deleting vApp(%s)", vApp.getId()); logger.debug(">> deleting vApp(%s)", vApp.getId());
client.deleteVApp(id); client.deleteVApp(id);
logger.debug("<< deleted vApp(%s)", vApp.getId()); boolean successful = notFoundTester.apply(vApp);
} logger.debug("<< deleted vApp(%s) completed(%s)", vApp.getId(), successful);
private VApp blockUntilVAppStatusOrThrowException(VApp vApp, Task deployTask, String taskType,
Set<VAppStatus> acceptableStatuses) {
if (!taskTester.apply(deployTask.getId())) {
throw new TaskException(taskType, vApp, deployTask);
}
vApp = client.getVApp(vApp.getId());
if (!acceptableStatuses.contains(vApp.getStatus())) {
throw new VAppException(String.format("vApp %s status %s should be %s after %s", vApp
.getId(), vApp.getStatus(), acceptableStatuses, taskType), vApp);
}
return vApp;
} }
public static class TaskException extends VAppException { public static class TaskException extends VAppException {

View File

@ -127,7 +127,7 @@ public class VCloudComputeServiceContextModule extends VCloudContextModule {
myOs = os; myOs = os;
} }
} }
Architecture arch = resource.getName().matches("64[- ]bit") ? Architecture.X86_32 Architecture arch = resource.getName().indexOf("64") == -1 ? Architecture.X86_32
: Architecture.X86_64; : Architecture.X86_64;
VAppTemplate template = client.getVAppTemplate(item.getEntity().getId()); VAppTemplate template = client.getVAppTemplate(item.getEntity().getId());
images.add(new ImageImpl(resource.getId(), template.getName(), "", myOs, images.add(new ImageImpl(resource.getId(), template.getName(), "", myOs,

View File

@ -52,6 +52,7 @@ import org.jclouds.vcloud.VCloudAsyncClient;
import org.jclouds.vcloud.VCloudClient; import org.jclouds.vcloud.VCloudClient;
import org.jclouds.vcloud.VCloudToken; import org.jclouds.vcloud.VCloudToken;
import org.jclouds.vcloud.domain.Organization; import org.jclouds.vcloud.domain.Organization;
import org.jclouds.vcloud.domain.VApp;
import org.jclouds.vcloud.endpoints.Catalog; import org.jclouds.vcloud.endpoints.Catalog;
import org.jclouds.vcloud.endpoints.Network; import org.jclouds.vcloud.endpoints.Network;
import org.jclouds.vcloud.endpoints.Org; import org.jclouds.vcloud.endpoints.Org;
@ -67,6 +68,7 @@ import org.jclouds.vcloud.internal.VCloudLoginAsyncClient;
import org.jclouds.vcloud.internal.VCloudVersionsAsyncClient; import org.jclouds.vcloud.internal.VCloudVersionsAsyncClient;
import org.jclouds.vcloud.internal.VCloudLoginAsyncClient.VCloudSession; import org.jclouds.vcloud.internal.VCloudLoginAsyncClient.VCloudSession;
import org.jclouds.vcloud.predicates.TaskSuccess; import org.jclouds.vcloud.predicates.TaskSuccess;
import org.jclouds.vcloud.predicates.VAppNotFound;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
import com.google.common.base.Supplier; import com.google.common.base.Supplier;
@ -104,6 +106,13 @@ public class VCloudRestClientModule extends AbstractModule {
return new RetryablePredicate<String>(success, 600, 10, TimeUnit.SECONDS); return new RetryablePredicate<String>(success, 600, 10, TimeUnit.SECONDS);
} }
@Provides
@Singleton
@Named("NOT_FOUND")
protected Predicate<VApp> successTester(VAppNotFound notFound) {
return new RetryablePredicate<VApp>(notFound, 5, 1, TimeUnit.SECONDS);
}
@Override @Override
protected void configure() { protected void configure() {
requestInjection(this); requestInjection(this);
@ -244,7 +253,10 @@ public class VCloudRestClientModule extends AbstractModule {
@Singleton @Singleton
protected URI provideDefaultNetwork(VCloudAsyncClient client) throws InterruptedException, protected URI provideDefaultNetwork(VCloudAsyncClient client) throws InterruptedException,
ExecutionException, TimeoutException { ExecutionException, TimeoutException {
return Iterables.get(client.getDefaultVDC().get(180, TimeUnit.SECONDS).getAvailableNetworks().values(), 0).getLocation(); return Iterables
.get(
client.getDefaultVDC().get(180, TimeUnit.SECONDS).getAvailableNetworks()
.values(), 0).getLocation();
} }
@Provides @Provides

View File

@ -0,0 +1,58 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.vcloud.predicates;
import javax.annotation.Resource;
import javax.inject.Singleton;
import org.jclouds.logging.Logger;
import org.jclouds.rest.ResourceNotFoundException;
import org.jclouds.vcloud.VCloudClient;
import org.jclouds.vcloud.domain.VApp;
import com.google.common.base.Predicate;
import com.google.inject.Inject;
/**
*
* Tests to see if a task succeeds.
*
* @author Adrian Cole
*/
@Singleton
public class VAppNotFound implements Predicate<VApp> {
private final VCloudClient client;
@Resource
protected Logger logger = Logger.NULL;
@Inject
public VAppNotFound(VCloudClient client) {
this.client = client;
}
public boolean apply(VApp vApp) {
try {
return client.getVApp(vApp.getId()) == null;
} catch (ResourceNotFoundException e) {
return true;
}
}
}

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.vcloud.compute;
import static org.testng.Assert.assertEquals;
import java.io.IOException;
import java.util.Properties;
import org.jclouds.vcloud.VCloudPropertiesBuilder;
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 test() {
assertEquals(properties.getProperty("vcloud.contextbuilder"),
VCloudComputeServiceContextBuilder.class.getName());
assertEquals(properties.getProperty("vcloud.propertiesbuilder"),
VCloudPropertiesBuilder.class.getName());
}
}

View File

@ -0,0 +1,59 @@
package org.jclouds.vcloud.compute;
import static com.google.common.base.Preconditions.checkNotNull;
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.rest.RestContext;
import org.jclouds.ssh.jsch.config.JschSshClientModule;
import org.jclouds.vcloud.VCloudAsyncClient;
import org.jclouds.vcloud.VCloudClient;
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 = "vcloud.VCloudComputeServiceLiveTest")
public class VCloudComputeServiceLiveTest extends BaseComputeServiceLiveTest {
@BeforeClass
@Override
public void setServiceDefaults() {
System.setProperty("vcloud.endpoint", checkNotNull(System
.getProperty("jclouds.test.endpoint"), "jclouds.test.endpoint"));
service = "vcloud";
}
@Override
protected boolean canRunScript(Template template) {
return false;
}
@Override
protected Template buildTemplate(TemplateBuilder templateBuilder) {
return templateBuilder.osFamily(UBUNTU).smallest().build();
}
@Override
protected JschSshClientModule getSshModule() {
return new JschSshClientModule();
}
public void testAssignability() throws Exception {
@SuppressWarnings("unused")
RestContext<VCloudAsyncClient, VCloudClient> tmContext = new ComputeServiceContextFactory()
.createContext(service, user, password).getProviderSpecificContext();
VCloudComputeService computeService = VCloudComputeService.class.cast(client);
@SuppressWarnings("unused")
VCloudComputeClient computeClient = VCloudComputeClient.class.cast(computeService);
}
}

View File

@ -67,6 +67,31 @@
</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" />
<!-- Rollover at midnight each day -->
<param name="DatePattern" value="'.'yyyy-MM-dd" />
<param name="Threshold" value="TRACE" />
<layout class="org.apache.log4j.PatternLayout">
<!-- The default pattern: Date Priority [Category] Message\n -->
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
<!--
The full pattern: Date MS Priority [Category] (Thread:NDC) Message\n
<param name="ConversionPattern" value="%d %-5r %-5p [%c] (%t:%x)
%m%n"/>
-->
</layout>
</appender>
<appender name="ASYNCCOMPUTE" class="org.apache.log4j.AsyncAppender">
<appender-ref ref="COMPUTEFILE" />
</appender>
<appender name="ASYNC" class="org.apache.log4j.AsyncAppender"> <appender name="ASYNC" class="org.apache.log4j.AsyncAppender">
<appender-ref ref="FILE" /> <appender-ref ref="FILE" />
</appender> </appender>
@ -93,6 +118,11 @@
<priority value="DEBUG" /> <priority value="DEBUG" />
<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 -->
<!-- ======================= --> <!-- ======================= -->

View File

@ -6,6 +6,7 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Provider; import javax.inject.Provider;
import javax.inject.Singleton; import javax.inject.Singleton;
@ -31,8 +32,9 @@ 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, ComputeUtils utils) { Predicate<String> successTester, ComputeUtils utils,
super(client, templateBuilderProvider, images, sizes, utils, successTester); @Named("NOT_FOUND") Predicate<VApp> notFoundTester) {
super(client, templateBuilderProvider, images, sizes, utils, successTester, notFoundTester);
} }
@Override @Override

View File

@ -66,8 +66,9 @@ 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, ComputeUtils utils) { ComputeUtils utils, Predicate<String> successTester,
super(client, templateBuilderProvider, images, sizes, utils, successTester); @Named("NOT_FOUND") Predicate<VApp> notFoundTester) {
super(client, templateBuilderProvider, images, sizes, utils, successTester, notFoundTester);
this.client = client; this.client = client;
} }