mirror of https://github.com/apache/jclouds.git
Issue 283 added
client.templateOptions().blockUntilRunning(false) and Issue 284: consolidated timeout properties into ComputeServiceConstants
This commit is contained in:
parent
ffaea53022
commit
aabaae2a51
|
@ -34,6 +34,7 @@ import ${package}.config.${providerName}ContextModule;
|
||||||
|
|
||||||
import org.jclouds.compute.ComputeServiceContext;
|
import org.jclouds.compute.ComputeServiceContext;
|
||||||
import org.jclouds.compute.LoadBalancerService;
|
import org.jclouds.compute.LoadBalancerService;
|
||||||
|
import org.jclouds.compute.config.ComputeServiceTimeoutsModule;
|
||||||
import org.jclouds.compute.domain.ComputeMetadata;
|
import org.jclouds.compute.domain.ComputeMetadata;
|
||||||
import org.jclouds.compute.domain.Image;
|
import org.jclouds.compute.domain.Image;
|
||||||
import org.jclouds.compute.domain.NodeMetadata;
|
import org.jclouds.compute.domain.NodeMetadata;
|
||||||
|
@ -80,6 +81,7 @@ public class ${providerName}ComputeServiceContextModule extends ${providerName}C
|
||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
super.configure();
|
super.configure();
|
||||||
|
install(new ComputeServiceTimeoutsModule());
|
||||||
bind(new TypeLiteral<ComputeServiceContext>() {
|
bind(new TypeLiteral<ComputeServiceContext>() {
|
||||||
})
|
})
|
||||||
.to(
|
.to(
|
||||||
|
@ -93,12 +95,6 @@ public class ${providerName}ComputeServiceContextModule extends ${providerName}C
|
||||||
bind(LoadBalancerService.class).toProvider(Providers.<LoadBalancerService> of(null));
|
bind(LoadBalancerService.class).toProvider(Providers.<LoadBalancerService> of(null));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
protected Predicate<IPSocket> socketTester(SocketOpen open) {
|
|
||||||
return new RetryablePredicate<IPSocket>(open, 130, 1, TimeUnit.SECONDS);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* tested known configuration
|
* tested known configuration
|
||||||
*/
|
*/
|
||||||
|
@ -205,14 +201,6 @@ public class ${providerName}ComputeServiceContextModule extends ${providerName}C
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
@Named("NOT_RUNNING")
|
|
||||||
protected Predicate<CommandUsingClient> runScriptRunning(ScriptStatusReturnsZero stateRunning) {
|
|
||||||
return new RetryablePredicate<CommandUsingClient>(Predicates.not(stateRunning), 600, 3,
|
|
||||||
TimeUnit.SECONDS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
Location getDefaultLocation(Set<? extends Location> locations) {
|
Location getDefaultLocation(Set<? extends Location> locations) {
|
||||||
|
|
|
@ -66,18 +66,27 @@ public class EC2ComputeService extends BaseComputeService {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
protected EC2ComputeService(ComputeServiceContext context,
|
protected EC2ComputeService(ComputeServiceContext context,
|
||||||
Provider<Set<? extends Image>> images, Provider<Set<? extends Size>> sizes,
|
Provider<Set<? extends Image>> images,
|
||||||
Provider<Set<? extends Location>> locations, ListNodesStrategy listNodesStrategy,
|
Provider<Set<? extends Size>> sizes,
|
||||||
|
Provider<Set<? extends Location>> locations,
|
||||||
|
ListNodesStrategy listNodesStrategy,
|
||||||
GetNodeMetadataStrategy getNodeMetadataStrategy,
|
GetNodeMetadataStrategy getNodeMetadataStrategy,
|
||||||
RunNodesAndAddToSetStrategy runNodesAndAddToSetStrategy,
|
RunNodesAndAddToSetStrategy runNodesAndAddToSetStrategy,
|
||||||
RebootNodeStrategy rebootNodeStrategy, DestroyNodeStrategy destroyNodeStrategy,
|
RebootNodeStrategy rebootNodeStrategy,
|
||||||
|
DestroyNodeStrategy destroyNodeStrategy,
|
||||||
Provider<TemplateBuilder> templateBuilderProvider,
|
Provider<TemplateBuilder> templateBuilderProvider,
|
||||||
Provider<TemplateOptions> templateOptionsProvider, ComputeUtils utils,
|
Provider<TemplateOptions> templateOptionsProvider,
|
||||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor, EC2Client ec2Client,
|
@Named("NODE_RUNNING") Predicate<NodeMetadata> nodeRunning,
|
||||||
Map<RegionAndName, KeyPair> credentialsMap, Map<RegionAndName, String> securityGroupMap) {
|
@Named("NODE_TERMINATED") Predicate<NodeMetadata> nodeTerminated,
|
||||||
super(context, images, sizes, locations, listNodesStrategy, getNodeMetadataStrategy,
|
ComputeUtils utils,
|
||||||
runNodesAndAddToSetStrategy, rebootNodeStrategy, destroyNodeStrategy,
|
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor,
|
||||||
templateBuilderProvider, templateOptionsProvider, utils, executor);
|
EC2Client ec2Client, Map<RegionAndName, KeyPair> credentialsMap,
|
||||||
|
Map<RegionAndName, String> securityGroupMap) {
|
||||||
|
super(context, images, sizes, locations, listNodesStrategy,
|
||||||
|
getNodeMetadataStrategy, runNodesAndAddToSetStrategy,
|
||||||
|
rebootNodeStrategy, destroyNodeStrategy, templateBuilderProvider,
|
||||||
|
templateOptionsProvider, nodeRunning, nodeTerminated, utils,
|
||||||
|
executor);
|
||||||
this.ec2Client = ec2Client;
|
this.ec2Client = ec2Client;
|
||||||
this.credentialsMap = credentialsMap;
|
this.credentialsMap = credentialsMap;
|
||||||
this.securityGroupMap = securityGroupMap;
|
this.securityGroupMap = securityGroupMap;
|
||||||
|
@ -86,38 +95,46 @@ public class EC2ComputeService extends BaseComputeService {
|
||||||
private void deleteSecurityGroup(String region, String tag) {
|
private void deleteSecurityGroup(String region, String tag) {
|
||||||
checkNotEmpty(tag, "tag");
|
checkNotEmpty(tag, "tag");
|
||||||
String group = "jclouds#" + tag;
|
String group = "jclouds#" + tag;
|
||||||
if (ec2Client.getSecurityGroupServices().describeSecurityGroupsInRegion(region, group).size() > 0) {
|
if (ec2Client.getSecurityGroupServices().describeSecurityGroupsInRegion(
|
||||||
|
region, group).size() > 0) {
|
||||||
logger.debug(">> deleting securityGroup(%s)", group);
|
logger.debug(">> deleting securityGroup(%s)", group);
|
||||||
ec2Client.getSecurityGroupServices().deleteSecurityGroupInRegion(region, group);
|
ec2Client.getSecurityGroupServices().deleteSecurityGroupInRegion(
|
||||||
|
region, group);
|
||||||
// TODO: test this clear happens
|
// TODO: test this clear happens
|
||||||
securityGroupMap.remove(new RegionNameAndIngressRules(region, tag, null, false));
|
securityGroupMap.remove(new RegionNameAndIngressRules(region, tag,
|
||||||
|
null, false));
|
||||||
logger.debug("<< deleted securityGroup(%s)", group);
|
logger.debug("<< deleted securityGroup(%s)", group);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void deleteKeyPair(String region, String tag) {
|
private void deleteKeyPair(String region, String tag) {
|
||||||
for (KeyPair keyPair : ec2Client.getKeyPairServices().describeKeyPairsInRegion(region)) {
|
for (KeyPair keyPair : ec2Client.getKeyPairServices()
|
||||||
|
.describeKeyPairsInRegion(region)) {
|
||||||
if (keyPair.getKeyName().matches("jclouds#" + tag + "-[0-9]+")) {
|
if (keyPair.getKeyName().matches("jclouds#" + tag + "-[0-9]+")) {
|
||||||
logger.debug(">> deleting keyPair(%s)", keyPair.getKeyName());
|
logger.debug(">> deleting keyPair(%s)", keyPair.getKeyName());
|
||||||
ec2Client.getKeyPairServices().deleteKeyPairInRegion(region, keyPair.getKeyName());
|
ec2Client.getKeyPairServices().deleteKeyPairInRegion(region,
|
||||||
|
keyPair.getKeyName());
|
||||||
// TODO: test this clear happens
|
// TODO: test this clear happens
|
||||||
credentialsMap.remove(new RegionAndName(region, keyPair.getKeyName()));
|
credentialsMap.remove(new RegionAndName(region, keyPair
|
||||||
|
.getKeyName()));
|
||||||
logger.debug("<< deleted keyPair(%s)", keyPair.getKeyName());
|
logger.debug("<< deleted keyPair(%s)", keyPair.getKeyName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* like {@link BaseComputeService#destroyNodesMatching} except that this will clean implicit
|
* like {@link BaseComputeService#destroyNodesMatching} except that this will
|
||||||
* keypairs and security groups.
|
* clean implicit keypairs and security groups.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Set<? extends NodeMetadata> destroyNodesMatching(Predicate<NodeMetadata> filter) {
|
public Set<? extends NodeMetadata> destroyNodesMatching(
|
||||||
|
Predicate<NodeMetadata> filter) {
|
||||||
Set<? extends NodeMetadata> deadOnes = super.destroyNodesMatching(filter);
|
Set<? extends NodeMetadata> deadOnes = super.destroyNodesMatching(filter);
|
||||||
Map<String, String> regionTags = Maps.newHashMap();
|
Map<String, String> regionTags = Maps.newHashMap();
|
||||||
for (NodeMetadata nodeMetadata : deadOnes) {
|
for (NodeMetadata nodeMetadata : deadOnes) {
|
||||||
if (nodeMetadata.getTag() != null)
|
if (nodeMetadata.getTag() != null)
|
||||||
regionTags.put(parseHandle(nodeMetadata.getId())[0], nodeMetadata.getTag());
|
regionTags.put(parseHandle(nodeMetadata.getId())[0], nodeMetadata
|
||||||
|
.getTag());
|
||||||
}
|
}
|
||||||
for (Entry<String, String> regionTag : regionTags.entrySet()) {
|
for (Entry<String, String> regionTag : regionTags.entrySet()) {
|
||||||
deleteKeyPair(regionTag.getKey(), regionTag.getValue());
|
deleteKeyPair(regionTag.getKey(), regionTag.getValue());
|
||||||
|
|
|
@ -64,9 +64,11 @@ import org.jclouds.aws.ec2.domain.KeyPair;
|
||||||
import org.jclouds.aws.ec2.domain.RunningInstance;
|
import org.jclouds.aws.ec2.domain.RunningInstance;
|
||||||
import org.jclouds.aws.ec2.domain.Image.ImageType;
|
import org.jclouds.aws.ec2.domain.Image.ImageType;
|
||||||
import org.jclouds.aws.ec2.functions.RunningInstanceToStorageMappingUnix;
|
import org.jclouds.aws.ec2.functions.RunningInstanceToStorageMappingUnix;
|
||||||
|
import org.jclouds.aws.ec2.predicates.InstancePresent;
|
||||||
import org.jclouds.aws.ec2.services.InstanceClient;
|
import org.jclouds.aws.ec2.services.InstanceClient;
|
||||||
import org.jclouds.compute.ComputeService;
|
import org.jclouds.compute.ComputeService;
|
||||||
import org.jclouds.compute.ComputeServiceContext;
|
import org.jclouds.compute.ComputeServiceContext;
|
||||||
|
import org.jclouds.compute.config.ComputeServiceTimeoutsModule;
|
||||||
import org.jclouds.compute.domain.Architecture;
|
import org.jclouds.compute.domain.Architecture;
|
||||||
import org.jclouds.compute.domain.ComputeMetadata;
|
import org.jclouds.compute.domain.ComputeMetadata;
|
||||||
import org.jclouds.compute.domain.Image;
|
import org.jclouds.compute.domain.Image;
|
||||||
|
@ -76,8 +78,6 @@ import org.jclouds.compute.domain.TemplateBuilder;
|
||||||
import org.jclouds.compute.internal.ComputeServiceContextImpl;
|
import org.jclouds.compute.internal.ComputeServiceContextImpl;
|
||||||
import org.jclouds.compute.options.TemplateOptions;
|
import org.jclouds.compute.options.TemplateOptions;
|
||||||
import org.jclouds.compute.predicates.NodePredicates;
|
import org.jclouds.compute.predicates.NodePredicates;
|
||||||
import org.jclouds.compute.predicates.ScriptStatusReturnsZero;
|
|
||||||
import org.jclouds.compute.predicates.ScriptStatusReturnsZero.CommandUsingClient;
|
|
||||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||||
import org.jclouds.compute.strategy.DestroyLoadBalancerStrategy;
|
import org.jclouds.compute.strategy.DestroyLoadBalancerStrategy;
|
||||||
import org.jclouds.compute.strategy.DestroyNodeStrategy;
|
import org.jclouds.compute.strategy.DestroyNodeStrategy;
|
||||||
|
@ -92,11 +92,9 @@ import org.jclouds.domain.LocationScope;
|
||||||
import org.jclouds.domain.internal.LocationImpl;
|
import org.jclouds.domain.internal.LocationImpl;
|
||||||
import org.jclouds.logging.Logger;
|
import org.jclouds.logging.Logger;
|
||||||
import org.jclouds.predicates.RetryablePredicate;
|
import org.jclouds.predicates.RetryablePredicate;
|
||||||
import com.google.inject.name.Names;
|
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
import com.google.common.base.Predicates;
|
|
||||||
import com.google.common.base.Splitter;
|
import com.google.common.base.Splitter;
|
||||||
import com.google.common.base.Supplier;
|
import com.google.common.base.Supplier;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
@ -108,9 +106,11 @@ import com.google.common.util.concurrent.ListenableFuture;
|
||||||
import com.google.inject.Provides;
|
import com.google.inject.Provides;
|
||||||
import com.google.inject.Scopes;
|
import com.google.inject.Scopes;
|
||||||
import com.google.inject.TypeLiteral;
|
import com.google.inject.TypeLiteral;
|
||||||
|
import com.google.inject.name.Names;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configures the {@link ComputeServiceContext}; requires {@link EC2ComputeService} bound.
|
* Configures the {@link ComputeServiceContext}; requires
|
||||||
|
* {@link EC2ComputeService} bound.
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
|
@ -122,25 +122,40 @@ public class EC2ComputeServiceContextModule extends EC2ContextModule {
|
||||||
this.providerName = providerName;
|
this.providerName = providerName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
@Named("PRESENT")
|
||||||
|
protected Predicate<RunningInstance> instancePresent(InstancePresent present) {
|
||||||
|
return new RetryablePredicate<RunningInstance>(present, 3000, 200,
|
||||||
|
TimeUnit.MILLISECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
super.configure();
|
super.configure();
|
||||||
|
install(new ComputeServiceTimeoutsModule());
|
||||||
bind(TemplateBuilder.class).to(EC2TemplateBuilderImpl.class);
|
bind(TemplateBuilder.class).to(EC2TemplateBuilderImpl.class);
|
||||||
bind(TemplateOptions.class).to(EC2TemplateOptions.class);
|
bind(TemplateOptions.class).to(EC2TemplateOptions.class);
|
||||||
bind(ComputeService.class).to(EC2ComputeService.class);
|
bind(ComputeService.class).to(EC2ComputeService.class);
|
||||||
bind(new TypeLiteral<ComputeServiceContext>() {
|
bind(new TypeLiteral<ComputeServiceContext>() {
|
||||||
}).to(new TypeLiteral<ComputeServiceContextImpl<EC2Client, EC2AsyncClient>>() {
|
})
|
||||||
|
.to(
|
||||||
|
new TypeLiteral<ComputeServiceContextImpl<EC2Client, EC2AsyncClient>>() {
|
||||||
}).in(Scopes.SINGLETON);
|
}).in(Scopes.SINGLETON);
|
||||||
bind(LoadBalanceNodesStrategy.class).to(EC2LoadBalanceNodesStrategy.class);
|
bind(LoadBalanceNodesStrategy.class)
|
||||||
bind(DestroyLoadBalancerStrategy.class).to(EC2DestroyLoadBalancerStrategy.class);
|
.to(EC2LoadBalanceNodesStrategy.class);
|
||||||
bind(RunNodesAndAddToSetStrategy.class).to(EC2RunNodesAndAddToSetStrategy.class);
|
bind(DestroyLoadBalancerStrategy.class).to(
|
||||||
|
EC2DestroyLoadBalancerStrategy.class);
|
||||||
|
bind(RunNodesAndAddToSetStrategy.class).to(
|
||||||
|
EC2RunNodesAndAddToSetStrategy.class);
|
||||||
bind(ListNodesStrategy.class).to(EC2ListNodesStrategy.class);
|
bind(ListNodesStrategy.class).to(EC2ListNodesStrategy.class);
|
||||||
bind(GetNodeMetadataStrategy.class).to(EC2GetNodeMetadataStrategy.class);
|
bind(GetNodeMetadataStrategy.class).to(EC2GetNodeMetadataStrategy.class);
|
||||||
bind(RebootNodeStrategy.class).to(EC2RebootNodeStrategy.class);
|
bind(RebootNodeStrategy.class).to(EC2RebootNodeStrategy.class);
|
||||||
bind(DestroyNodeStrategy.class).to(EC2DestroyNodeStrategy.class);
|
bind(DestroyNodeStrategy.class).to(EC2DestroyNodeStrategy.class);
|
||||||
bind(new TypeLiteral<Function<RunningInstance, Map<String, String>>>() {
|
bind(new TypeLiteral<Function<RunningInstance, Map<String, String>>>() {
|
||||||
}).annotatedWith(Names.named("volumeMapping")).to(RunningInstanceToStorageMappingUnix.class)
|
}).annotatedWith(Names.named("volumeMapping")).to(
|
||||||
.in(Scopes.SINGLETON);
|
RunningInstanceToStorageMappingUnix.class).in(Scopes.SINGLETON);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
|
@ -160,11 +175,12 @@ public class EC2ComputeServiceContextModule extends EC2ContextModule {
|
||||||
@Provides
|
@Provides
|
||||||
@Named("DEFAULT")
|
@Named("DEFAULT")
|
||||||
protected TemplateBuilder provideTemplate(TemplateBuilder template) {
|
protected TemplateBuilder provideTemplate(TemplateBuilder template) {
|
||||||
return template.architecture(Architecture.X86_32).osFamily(UBUNTU).imageNameMatches(
|
return template.architecture(Architecture.X86_32).osFamily(UBUNTU)
|
||||||
".*10\\.?04.*");
|
.imageNameMatches(".*10\\.?04.*").osDescriptionMatches("^ubuntu-images.*");
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO make this more efficient for listNodes(); currently RunningInstanceToNodeMetadata is slow
|
// TODO make this more efficient for listNodes(); currently
|
||||||
|
// RunningInstanceToNodeMetadata is slow
|
||||||
// due to image parsing; consider using MapMaker. computing map
|
// due to image parsing; consider using MapMaker. computing map
|
||||||
@Singleton
|
@Singleton
|
||||||
public static class EC2ListNodesStrategy implements ListNodesStrategy {
|
public static class EC2ListNodesStrategy implements ListNodesStrategy {
|
||||||
|
@ -178,7 +194,8 @@ public class EC2ComputeServiceContextModule extends EC2ContextModule {
|
||||||
private final ExecutorService executor;
|
private final ExecutorService executor;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
protected EC2ListNodesStrategy(EC2Client client, @EC2 Map<String, URI> regionMap,
|
protected EC2ListNodesStrategy(EC2Client client,
|
||||||
|
@EC2 Map<String, URI> regionMap,
|
||||||
RunningInstanceToNodeMetadata runningInstanceToNodeMetadata,
|
RunningInstanceToNodeMetadata runningInstanceToNodeMetadata,
|
||||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) {
|
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) {
|
||||||
this.client = client;
|
this.client = client;
|
||||||
|
@ -200,29 +217,31 @@ public class EC2ComputeServiceContextModule extends EC2ContextModule {
|
||||||
Map<String, ListenableFuture<?>> parallelResponses = Maps.newHashMap();
|
Map<String, ListenableFuture<?>> parallelResponses = Maps.newHashMap();
|
||||||
|
|
||||||
for (final String region : regionMap.keySet()) {
|
for (final String region : regionMap.keySet()) {
|
||||||
parallelResponses.put(region, ConcurrentUtils.makeListenable(executor
|
parallelResponses.put(region, ConcurrentUtils.makeListenable(
|
||||||
.submit(new Callable<Void>() {
|
executor.submit(new Callable<Void>() {
|
||||||
@Override
|
@Override
|
||||||
public Void call() throws Exception {
|
public Void call() throws Exception {
|
||||||
Iterables.addAll(nodes, Iterables.transform(Iterables.concat(client
|
Iterables.addAll(nodes, Iterables.transform(Iterables
|
||||||
.getInstanceServices().describeInstancesInRegion(region)),
|
.concat(client.getInstanceServices()
|
||||||
|
.describeInstancesInRegion(region)),
|
||||||
runningInstanceToNodeMetadata));
|
runningInstanceToNodeMetadata));
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}), executor));
|
}), executor));
|
||||||
}
|
}
|
||||||
Map<String, Exception> exceptions = awaitCompletion(parallelResponses, executor, null,
|
Map<String, Exception> exceptions = awaitCompletion(parallelResponses,
|
||||||
logger, "nodes");
|
executor, null, logger, "nodes");
|
||||||
|
|
||||||
if (exceptions.size() > 0)
|
if (exceptions.size() > 0)
|
||||||
throw new RuntimeException(String.format("error parsing nodes in regions: %s",
|
throw new RuntimeException(String.format(
|
||||||
exceptions));
|
"error parsing nodes in regions: %s", exceptions));
|
||||||
return Iterables.filter(nodes, filter);
|
return Iterables.filter(nodes, filter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public static class EC2GetNodeMetadataStrategy implements GetNodeMetadataStrategy {
|
public static class EC2GetNodeMetadataStrategy implements
|
||||||
|
GetNodeMetadataStrategy {
|
||||||
|
|
||||||
private final EC2Client client;
|
private final EC2Client client;
|
||||||
private final RunningInstanceToNodeMetadata runningInstanceToNodeMetadata;
|
private final RunningInstanceToNodeMetadata runningInstanceToNodeMetadata;
|
||||||
|
@ -239,8 +258,9 @@ public class EC2ComputeServiceContextModule extends EC2ContextModule {
|
||||||
String[] parts = parseHandle(id);
|
String[] parts = parseHandle(id);
|
||||||
String region = parts[0];
|
String region = parts[0];
|
||||||
String instanceId = parts[1];
|
String instanceId = parts[1];
|
||||||
RunningInstance runningInstance = Iterables.getOnlyElement(getAllRunningInstancesInRegion(
|
RunningInstance runningInstance = Iterables
|
||||||
client.getInstanceServices(), region, instanceId));
|
.getOnlyElement(getAllRunningInstancesInRegion(client
|
||||||
|
.getInstanceServices(), region, instanceId));
|
||||||
return runningInstanceToNodeMetadata.apply(runningInstance);
|
return runningInstanceToNodeMetadata.apply(runningInstance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -249,34 +269,30 @@ public class EC2ComputeServiceContextModule extends EC2ContextModule {
|
||||||
@Singleton
|
@Singleton
|
||||||
public static class EC2RebootNodeStrategy implements RebootNodeStrategy {
|
public static class EC2RebootNodeStrategy implements RebootNodeStrategy {
|
||||||
private final InstanceClient client;
|
private final InstanceClient client;
|
||||||
|
private final GetNodeMetadataStrategy getNode;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
protected EC2RebootNodeStrategy(EC2Client client) {
|
protected EC2RebootNodeStrategy(EC2Client client,
|
||||||
|
GetNodeMetadataStrategy getNode) {
|
||||||
this.client = client.getInstanceServices();
|
this.client = client.getInstanceServices();
|
||||||
|
this.getNode = getNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean execute(String id) {
|
public NodeMetadata execute(String id) {
|
||||||
String[] parts = parseHandle(id);
|
String[] parts = parseHandle(id);
|
||||||
String region = parts[0];
|
String region = parts[0];
|
||||||
String instanceId = parts[1];
|
String instanceId = parts[1];
|
||||||
client.rebootInstancesInRegion(region, instanceId);
|
client.rebootInstancesInRegion(region, instanceId);
|
||||||
return true;
|
return getNode.execute(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
@Named("NOT_RUNNING")
|
protected final Map<RegionAndName, KeyPair> credentialsMap(
|
||||||
protected Predicate<CommandUsingClient> runScriptRunning(ScriptStatusReturnsZero stateRunning) {
|
CreateUniqueKeyPair in) {
|
||||||
return new RetryablePredicate<CommandUsingClient>(Predicates.not(stateRunning), 600, 3,
|
|
||||||
TimeUnit.SECONDS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
protected final Map<RegionAndName, KeyPair> credentialsMap(CreateUniqueKeyPair in) {
|
|
||||||
// doesn't seem to clear when someone issues remove(key)
|
// doesn't seem to clear when someone issues remove(key)
|
||||||
// return new MapMaker().makeComputingMap(in);
|
// return new MapMaker().makeComputingMap(in);
|
||||||
return Maps.newLinkedHashMap();
|
return Maps.newLinkedHashMap();
|
||||||
|
@ -284,7 +300,8 @@ public class EC2ComputeServiceContextModule extends EC2ContextModule {
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
protected final Map<RegionAndName, String> securityGroupMap(CreateSecurityGroupIfNeeded in) {
|
protected final Map<RegionAndName, String> securityGroupMap(
|
||||||
|
CreateSecurityGroupIfNeeded in) {
|
||||||
// doesn't seem to clear when someone issues remove(key)
|
// doesn't seem to clear when someone issues remove(key)
|
||||||
// return new MapMaker().makeComputingMap(in);
|
// return new MapMaker().makeComputingMap(in);
|
||||||
return Maps.newLinkedHashMap();
|
return Maps.newLinkedHashMap();
|
||||||
|
@ -304,28 +321,33 @@ public class EC2ComputeServiceContextModule extends EC2ContextModule {
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
Set<? extends Size> provideSizes() {
|
Set<? extends Size> provideSizes() {
|
||||||
return ImmutableSet.of(EC2Size.C1_MEDIUM, EC2Size.C1_XLARGE, EC2Size.M1_LARGE,
|
return ImmutableSet.of(EC2Size.C1_MEDIUM, EC2Size.C1_XLARGE,
|
||||||
EC2Size.M1_SMALL, EC2Size.M1_XLARGE, EC2Size.M2_XLARGE, EC2Size.M2_2XLARGE,
|
EC2Size.M1_LARGE, EC2Size.M1_SMALL, EC2Size.M1_XLARGE,
|
||||||
EC2Size.M2_4XLARGE);
|
EC2Size.M2_XLARGE, EC2Size.M2_2XLARGE, EC2Size.M2_4XLARGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
Set<? extends Location> provideLocations(Map<String, String> availabilityZoneToRegionMap) {
|
Set<? extends Location> provideLocations(
|
||||||
Location ec2 = new LocationImpl(LocationScope.PROVIDER, providerName, providerName, null);
|
Map<String, String> availabilityZoneToRegionMap) {
|
||||||
|
Location ec2 = new LocationImpl(LocationScope.PROVIDER, providerName,
|
||||||
|
providerName, null);
|
||||||
Set<Location> locations = Sets.newLinkedHashSet();
|
Set<Location> locations = Sets.newLinkedHashSet();
|
||||||
for (String zone : availabilityZoneToRegionMap.keySet()) {
|
for (String zone : availabilityZoneToRegionMap.keySet()) {
|
||||||
Location region = new LocationImpl(LocationScope.REGION, availabilityZoneToRegionMap
|
Location region = new LocationImpl(LocationScope.REGION,
|
||||||
.get(zone), availabilityZoneToRegionMap.get(zone), ec2);
|
availabilityZoneToRegionMap.get(zone),
|
||||||
|
availabilityZoneToRegionMap.get(zone), ec2);
|
||||||
locations.add(region);
|
locations.add(region);
|
||||||
locations.add(new LocationImpl(LocationScope.ZONE, zone, zone, region));
|
locations
|
||||||
|
.add(new LocationImpl(LocationScope.ZONE, zone, zone, region));
|
||||||
}
|
}
|
||||||
return locations;
|
return locations;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
Location getDefaultLocation(@EC2 final String region, Set<? extends Location> set) {
|
Location getDefaultLocation(@EC2 final String region,
|
||||||
|
Set<? extends Location> set) {
|
||||||
return Iterables.find(set, new Predicate<Location>() {
|
return Iterables.find(set, new Predicate<Location>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -352,7 +374,8 @@ public class EC2ComputeServiceContextModule extends EC2ContextModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
protected Set<? extends Image> provideImages(Map<RegionAndName, ? extends Image> map) {
|
protected Set<? extends Image> provideImages(
|
||||||
|
Map<RegionAndName, ? extends Image> map) {
|
||||||
return ImmutableSet.copyOf(map.values());
|
return ImmutableSet.copyOf(map.values());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -365,10 +388,11 @@ public class EC2ComputeServiceContextModule extends EC2ContextModule {
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
protected Map<RegionAndName, ? extends Image> provideImages(final EC2Client sync,
|
protected Map<RegionAndName, ? extends Image> provideImages(
|
||||||
@EC2 Map<String, URI> regionMap, final LogHolder holder,
|
final EC2Client sync, @EC2 Map<String, URI> regionMap,
|
||||||
Function<ComputeMetadata, String> indexer,
|
final LogHolder holder, Function<ComputeMetadata, String> indexer,
|
||||||
@Named(PROPERTY_EC2_AMI_OWNERS) final String[] amiOwners, final ImageParser parser,
|
@Named(PROPERTY_EC2_AMI_OWNERS) final String[] amiOwners,
|
||||||
|
final ImageParser parser,
|
||||||
final ConcurrentMap<RegionAndName, Image> images,
|
final ConcurrentMap<RegionAndName, Image> images,
|
||||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor)
|
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor)
|
||||||
throws InterruptedException, ExecutionException, TimeoutException {
|
throws InterruptedException, ExecutionException, TimeoutException {
|
||||||
|
@ -380,30 +404,31 @@ public class EC2ComputeServiceContextModule extends EC2ContextModule {
|
||||||
Map<String, ListenableFuture<?>> parallelResponses = Maps.newHashMap();
|
Map<String, ListenableFuture<?>> parallelResponses = Maps.newHashMap();
|
||||||
|
|
||||||
for (final String region : regionMap.keySet()) {
|
for (final String region : regionMap.keySet()) {
|
||||||
parallelResponses.put(region, ConcurrentUtils.makeListenable(executor
|
parallelResponses.put(region, ConcurrentUtils.makeListenable(
|
||||||
.submit(new Callable<Void>() {
|
executor.submit(new Callable<Void>() {
|
||||||
@Override
|
@Override
|
||||||
public Void call() throws Exception {
|
public Void call() throws Exception {
|
||||||
for (final org.jclouds.aws.ec2.domain.Image from : sync.getAMIServices()
|
for (final org.jclouds.aws.ec2.domain.Image from : sync
|
||||||
.describeImagesInRegion(region, ownedBy(amiOwners))) {
|
.getAMIServices().describeImagesInRegion(region,
|
||||||
|
ownedBy(amiOwners))) {
|
||||||
Image image = parser.apply(from);
|
Image image = parser.apply(from);
|
||||||
if (image != null)
|
if (image != null)
|
||||||
images
|
images.put(new RegionAndName(region, image
|
||||||
.put(new RegionAndName(region, image.getProviderId()),
|
.getProviderId()), image);
|
||||||
image);
|
|
||||||
else if (from.getImageType() == ImageType.MACHINE)
|
else if (from.getImageType() == ImageType.MACHINE)
|
||||||
holder.logger.trace("<< image(%s) didn't parse", from.getId());
|
holder.logger.trace("<< image(%s) didn't parse",
|
||||||
|
from.getId());
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}), executor));
|
}), executor));
|
||||||
}
|
}
|
||||||
Map<String, Exception> exceptions = awaitCompletion(parallelResponses, executor, null,
|
Map<String, Exception> exceptions = awaitCompletion(parallelResponses,
|
||||||
holder.logger, "images");
|
executor, null, holder.logger, "images");
|
||||||
|
|
||||||
if (exceptions.size() > 0)
|
if (exceptions.size() > 0)
|
||||||
throw new RuntimeException(String.format("error parsing images in regions: %s",
|
throw new RuntimeException(String.format(
|
||||||
exceptions));
|
"error parsing images in regions: %s", exceptions));
|
||||||
|
|
||||||
holder.logger.debug("<< images(%d)", images.size());
|
holder.logger.debug("<< images(%d)", images.size());
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,15 +27,12 @@ import javax.inject.Named;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import org.jclouds.aws.ec2.EC2Client;
|
import org.jclouds.aws.ec2.EC2Client;
|
||||||
import org.jclouds.aws.ec2.domain.RunningInstance;
|
import org.jclouds.compute.domain.NodeMetadata;
|
||||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||||
import org.jclouds.compute.strategy.DestroyNodeStrategy;
|
import org.jclouds.compute.strategy.DestroyNodeStrategy;
|
||||||
import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
|
import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
|
||||||
import org.jclouds.logging.Logger;
|
import org.jclouds.logging.Logger;
|
||||||
|
|
||||||
import com.google.common.base.Predicate;
|
|
||||||
import com.google.common.collect.Iterables;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
|
@ -46,25 +43,22 @@ public class EC2DestroyNodeStrategy implements DestroyNodeStrategy {
|
||||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||||
protected Logger logger = Logger.NULL;
|
protected Logger logger = Logger.NULL;
|
||||||
protected final EC2Client ec2Client;
|
protected final EC2Client ec2Client;
|
||||||
protected final Predicate<RunningInstance> instanceStateTerminated;
|
protected final GetNodeMetadataStrategy getNode;
|
||||||
protected final GetNodeMetadataStrategy getNodeMetadataStrategy;
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
protected EC2DestroyNodeStrategy(EC2Client ec2Client,
|
protected EC2DestroyNodeStrategy(EC2Client ec2Client,
|
||||||
@Named("TERMINATED") Predicate<RunningInstance> instanceStateTerminated,
|
|
||||||
GetNodeMetadataStrategy getNodeMetadataStrategy) {
|
GetNodeMetadataStrategy getNodeMetadataStrategy) {
|
||||||
this.ec2Client = ec2Client;
|
this.ec2Client = ec2Client;
|
||||||
this.instanceStateTerminated = instanceStateTerminated;
|
this.getNode = getNodeMetadataStrategy;
|
||||||
this.getNodeMetadataStrategy = getNodeMetadataStrategy;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean execute(String id) {
|
public NodeMetadata execute(String id) {
|
||||||
String[] parts = parseHandle(id);
|
String[] parts = parseHandle(id);
|
||||||
String region = parts[0];
|
String region = parts[0];
|
||||||
String instanceId = parts[1];
|
String instanceId = parts[1];
|
||||||
ec2Client.getInstanceServices().terminateInstancesInRegion(region, instanceId);
|
ec2Client.getInstanceServices().terminateInstancesInRegion(region,
|
||||||
return instanceStateTerminated.apply(Iterables.getOnlyElement(Iterables.concat(ec2Client
|
instanceId);
|
||||||
.getInstanceServices().describeInstancesInRegion(region, instanceId))));
|
return getNode.execute(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -20,8 +20,6 @@
|
||||||
package org.jclouds.aws.ec2.compute.strategy;
|
package org.jclouds.aws.ec2.compute.strategy;
|
||||||
|
|
||||||
import static com.google.common.collect.Iterables.all;
|
import static com.google.common.collect.Iterables.all;
|
||||||
import static com.google.common.collect.Iterables.concat;
|
|
||||||
import static com.google.common.collect.Iterables.toArray;
|
|
||||||
import static com.google.common.collect.Iterables.transform;
|
import static com.google.common.collect.Iterables.transform;
|
||||||
import static org.jclouds.aws.ec2.compute.util.EC2ComputeUtils.getRegionFromLocationOrNull;
|
import static org.jclouds.aws.ec2.compute.util.EC2ComputeUtils.getRegionFromLocationOrNull;
|
||||||
import static org.jclouds.aws.ec2.compute.util.EC2ComputeUtils.getZoneFromLocationOrNull;
|
import static org.jclouds.aws.ec2.compute.util.EC2ComputeUtils.getZoneFromLocationOrNull;
|
||||||
|
@ -58,7 +56,8 @@ import com.google.common.util.concurrent.ListenableFuture;
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@Singleton
|
@Singleton
|
||||||
public class EC2RunNodesAndAddToSetStrategy implements RunNodesAndAddToSetStrategy {
|
public class EC2RunNodesAndAddToSetStrategy implements
|
||||||
|
RunNodesAndAddToSetStrategy {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||||
|
@ -69,58 +68,50 @@ public class EC2RunNodesAndAddToSetStrategy implements RunNodesAndAddToSetStrate
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
final CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions createKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions;
|
final CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions createKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions;
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
final Predicate<RunningInstance> instanceStateRunning;
|
|
||||||
@VisibleForTesting
|
|
||||||
final RunningInstanceToNodeMetadata runningInstanceToNodeMetadata;
|
final RunningInstanceToNodeMetadata runningInstanceToNodeMetadata;
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
final ComputeUtils utils;
|
final ComputeUtils utils;
|
||||||
|
|
||||||
|
final Predicate<RunningInstance> instancePresent;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
EC2RunNodesAndAddToSetStrategy(
|
EC2RunNodesAndAddToSetStrategy(
|
||||||
EC2Client client,
|
EC2Client client,
|
||||||
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions createKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions,
|
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions createKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions,
|
||||||
@Named("RUNNING") Predicate<RunningInstance> instanceStateRunning,
|
@Named("PRESENT") Predicate<RunningInstance> instancePresent,
|
||||||
RunningInstanceToNodeMetadata runningInstanceToNodeMetadata, ComputeUtils utils) {
|
RunningInstanceToNodeMetadata runningInstanceToNodeMetadata,
|
||||||
|
ComputeUtils utils) {
|
||||||
this.client = client;
|
this.client = client;
|
||||||
|
this.instancePresent = instancePresent;
|
||||||
this.createKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions = createKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions;
|
this.createKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions = createKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions;
|
||||||
this.instanceStateRunning = instanceStateRunning;
|
|
||||||
this.runningInstanceToNodeMetadata = runningInstanceToNodeMetadata;
|
this.runningInstanceToNodeMetadata = runningInstanceToNodeMetadata;
|
||||||
this.utils = utils;
|
this.utils = utils;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<?, ListenableFuture<Void>> execute(String tag, int count, Template template,
|
public Map<?, ListenableFuture<Void>> execute(String tag, int count,
|
||||||
Set<NodeMetadata> goodNodes, Map<NodeMetadata, Exception> badNodes) {
|
Template template, Set<NodeMetadata> goodNodes,
|
||||||
|
Map<NodeMetadata, Exception> badNodes) {
|
||||||
|
|
||||||
Reservation reservation = createKeyPairAndSecurityGroupsAsNeededThenRunInstances(tag, count,
|
Reservation reservation = createKeyPairAndSecurityGroupsAsNeededThenRunInstances(
|
||||||
template);
|
tag, count, template);
|
||||||
|
|
||||||
Iterable<NodeMetadata> runningNodes = blockUntilInstancesAreRunningAndConvertToNodes(reservation);
|
|
||||||
|
|
||||||
return utils.runOptionsOnNodesAndAddToGoodSetOrPutExceptionIntoBadMap(template.getOptions(),
|
|
||||||
runningNodes, goodNodes, badNodes);
|
|
||||||
}
|
|
||||||
|
|
||||||
@VisibleForTesting
|
|
||||||
Iterable<NodeMetadata> blockUntilInstancesAreRunningAndConvertToNodes(Reservation reservation) {
|
|
||||||
return transform(blockUntilInstancesAreRunning(reservation), runningInstanceToNodeMetadata);
|
|
||||||
}
|
|
||||||
|
|
||||||
@VisibleForTesting
|
|
||||||
Iterable<RunningInstance> blockUntilInstancesAreRunning(Reservation reservation) {
|
|
||||||
Iterable<String> ids = transform(reservation, instanceToId);
|
Iterable<String> ids = transform(reservation, instanceToId);
|
||||||
|
|
||||||
String idsString = Joiner.on(',').join(ids);
|
String idsString = Joiner.on(',').join(ids);
|
||||||
logger.debug("<< started instances(%s)", idsString);
|
|
||||||
all(reservation, instanceStateRunning);
|
|
||||||
logger.debug("<< running instances(%s)", idsString);
|
|
||||||
|
|
||||||
return getInstances(reservation.getRegion(), ids);
|
logger.debug("<< started instances(%s)", idsString);
|
||||||
|
all(reservation, instancePresent);
|
||||||
|
logger.debug("<< present instances(%s)", idsString);
|
||||||
|
|
||||||
|
return utils.runOptionsOnNodesAndAddToGoodSetOrPutExceptionIntoBadMap(
|
||||||
|
template.getOptions(), transform(reservation,
|
||||||
|
runningInstanceToNodeMetadata), goodNodes, badNodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
Reservation createKeyPairAndSecurityGroupsAsNeededThenRunInstances(String tag, int count,
|
Reservation createKeyPairAndSecurityGroupsAsNeededThenRunInstances(
|
||||||
Template template) {
|
String tag, int count, Template template) {
|
||||||
String region = getRegionFromLocationOrNull(template.getLocation());
|
String region = getRegionFromLocationOrNull(template.getLocation());
|
||||||
String zone = getZoneFromLocationOrNull(template.getLocation());
|
String zone = getZoneFromLocationOrNull(template.getLocation());
|
||||||
|
|
||||||
|
@ -128,17 +119,13 @@ public class EC2RunNodesAndAddToSetStrategy implements RunNodesAndAddToSetStrate
|
||||||
.execute(region, tag, template);
|
.execute(region, tag, template);
|
||||||
|
|
||||||
if (logger.isDebugEnabled())
|
if (logger.isDebugEnabled())
|
||||||
logger.debug(">> running %d instance region(%s) zone(%s) ami(%s) params(%s)", count,
|
logger.debug(
|
||||||
region, zone, template.getImage().getProviderId(), instanceOptions
|
">> running %d instance region(%s) zone(%s) ami(%s) params(%s)",
|
||||||
.buildFormParameters());
|
count, region, zone, template.getImage().getProviderId(),
|
||||||
|
instanceOptions.buildFormParameters());
|
||||||
|
|
||||||
return client.getInstanceServices().runInstancesInRegion(region, zone,
|
return client.getInstanceServices().runInstancesInRegion(region, zone,
|
||||||
template.getImage().getProviderId(), 1, count, instanceOptions);
|
template.getImage().getProviderId(), 1, count, instanceOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Iterable<RunningInstance> getInstances(String region, Iterable<String> ids) {
|
|
||||||
return concat(client.getInstanceServices().describeInstancesInRegion(region,
|
|
||||||
toArray(ids, String.class)));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -49,11 +49,11 @@ public class EC2ContextModule extends AbstractModule {
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
RestContext<EC2Client, EC2AsyncClient> provideContext(Closer closer, EC2AsyncClient defaultApi,
|
RestContext<EC2Client, EC2AsyncClient> provideContext(Closer closer,
|
||||||
EC2Client synchApi, @EC2 URI endPoint,
|
EC2AsyncClient defaultApi, EC2Client synchApi, @EC2 URI endPoint,
|
||||||
@Named(AWSConstants.PROPERTY_AWS_ACCESSKEYID) String account) {
|
@Named(AWSConstants.PROPERTY_AWS_ACCESSKEYID) String account) {
|
||||||
return new RestContextImpl<EC2Client, EC2AsyncClient>(closer, defaultApi, synchApi, endPoint,
|
return new RestContextImpl<EC2Client, EC2AsyncClient>(closer, defaultApi,
|
||||||
account);
|
synchApi, endPoint, account);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -21,7 +21,6 @@ package org.jclouds.aws.ec2.config;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
@ -32,9 +31,6 @@ import org.jclouds.aws.ec2.EC2AsyncClient;
|
||||||
import org.jclouds.aws.ec2.EC2Client;
|
import org.jclouds.aws.ec2.EC2Client;
|
||||||
import org.jclouds.aws.ec2.ELB;
|
import org.jclouds.aws.ec2.ELB;
|
||||||
import org.jclouds.aws.ec2.domain.AvailabilityZoneInfo;
|
import org.jclouds.aws.ec2.domain.AvailabilityZoneInfo;
|
||||||
import org.jclouds.aws.ec2.domain.RunningInstance;
|
|
||||||
import org.jclouds.aws.ec2.predicates.InstanceStateRunning;
|
|
||||||
import org.jclouds.aws.ec2.predicates.InstanceStateTerminated;
|
|
||||||
import org.jclouds.aws.ec2.reference.EC2Constants;
|
import org.jclouds.aws.ec2.reference.EC2Constants;
|
||||||
import org.jclouds.aws.ec2.services.AMIAsyncClient;
|
import org.jclouds.aws.ec2.services.AMIAsyncClient;
|
||||||
import org.jclouds.aws.ec2.services.AMIClient;
|
import org.jclouds.aws.ec2.services.AMIClient;
|
||||||
|
@ -66,14 +62,10 @@ import org.jclouds.http.RequiresHttp;
|
||||||
import org.jclouds.http.annotation.ClientError;
|
import org.jclouds.http.annotation.ClientError;
|
||||||
import org.jclouds.http.annotation.Redirection;
|
import org.jclouds.http.annotation.Redirection;
|
||||||
import org.jclouds.http.annotation.ServerError;
|
import org.jclouds.http.annotation.ServerError;
|
||||||
import org.jclouds.net.IPSocket;
|
|
||||||
import org.jclouds.predicates.RetryablePredicate;
|
|
||||||
import org.jclouds.predicates.SocketOpen;
|
|
||||||
import org.jclouds.rest.ConfiguresRestClient;
|
import org.jclouds.rest.ConfiguresRestClient;
|
||||||
import org.jclouds.rest.RequestSigner;
|
import org.jclouds.rest.RequestSigner;
|
||||||
import org.jclouds.rest.config.RestClientModule;
|
import org.jclouds.rest.config.RestClientModule;
|
||||||
|
|
||||||
import com.google.common.base.Predicate;
|
|
||||||
import com.google.common.collect.ImmutableBiMap;
|
import com.google.common.collect.ImmutableBiMap;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
|
@ -86,7 +78,8 @@ import com.google.inject.Provides;
|
||||||
*/
|
*/
|
||||||
@RequiresHttp
|
@RequiresHttp
|
||||||
@ConfiguresRestClient
|
@ConfiguresRestClient
|
||||||
public class EC2RestClientModule extends RestClientModule<EC2Client, EC2AsyncClient> {
|
public class EC2RestClientModule extends
|
||||||
|
RestClientModule<EC2Client, EC2AsyncClient> {
|
||||||
public static final Map<Class<?>, Class<?>> DELEGATE_MAP = ImmutableMap
|
public static final Map<Class<?>, Class<?>> DELEGATE_MAP = ImmutableMap
|
||||||
.<Class<?>, Class<?>> builder()//
|
.<Class<?>, Class<?>> builder()//
|
||||||
.put(AMIClient.class, AMIAsyncClient.class)//
|
.put(AMIClient.class, AMIAsyncClient.class)//
|
||||||
|
@ -95,41 +88,22 @@ public class EC2RestClientModule extends RestClientModule<EC2Client, EC2AsyncCli
|
||||||
.put(KeyPairClient.class, KeyPairAsyncClient.class)//
|
.put(KeyPairClient.class, KeyPairAsyncClient.class)//
|
||||||
.put(SecurityGroupClient.class, SecurityGroupAsyncClient.class)//
|
.put(SecurityGroupClient.class, SecurityGroupAsyncClient.class)//
|
||||||
.put(MonitoringClient.class, MonitoringAsyncClient.class)//
|
.put(MonitoringClient.class, MonitoringAsyncClient.class)//
|
||||||
.put(AvailabilityZoneAndRegionClient.class, AvailabilityZoneAndRegionAsyncClient.class)//
|
.put(AvailabilityZoneAndRegionClient.class,
|
||||||
|
AvailabilityZoneAndRegionAsyncClient.class)//
|
||||||
.put(ElasticBlockStoreClient.class, ElasticBlockStoreAsyncClient.class)//
|
.put(ElasticBlockStoreClient.class, ElasticBlockStoreAsyncClient.class)//
|
||||||
.put(ElasticLoadBalancerClient.class, ElasticLoadBalancerAsyncClient.class)//
|
.put(ElasticLoadBalancerClient.class,
|
||||||
|
ElasticLoadBalancerAsyncClient.class)//
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
public EC2RestClientModule() {
|
public EC2RestClientModule() {
|
||||||
super(EC2Client.class, EC2AsyncClient.class, DELEGATE_MAP);
|
super(EC2Client.class, EC2AsyncClient.class, DELEGATE_MAP);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
@Named("RUNNING")
|
|
||||||
protected Predicate<RunningInstance> instanceStateRunning(InstanceStateRunning stateRunning) {
|
|
||||||
return new RetryablePredicate<RunningInstance>(stateRunning, 600, 3, TimeUnit.SECONDS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
@Named("TERMINATED")
|
|
||||||
protected Predicate<RunningInstance> instanceStateTerminated(
|
|
||||||
InstanceStateTerminated stateTerminated) {
|
|
||||||
return new RetryablePredicate<RunningInstance>(stateTerminated, 20000, 500,
|
|
||||||
TimeUnit.MILLISECONDS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
protected Predicate<IPSocket> socketTester(SocketOpen open) {
|
|
||||||
return new RetryablePredicate<IPSocket>(open, 130, 1, TimeUnit.SECONDS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
@ELB
|
@ELB
|
||||||
protected URI provideELBURI(@Named(EC2Constants.PROPERTY_ELB_ENDPOINT) String endpoint) {
|
protected URI provideELBURI(
|
||||||
|
@Named(EC2Constants.PROPERTY_ELB_ENDPOINT) String endpoint) {
|
||||||
return URI.create(endpoint);
|
return URI.create(endpoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,21 +111,29 @@ public class EC2RestClientModule extends RestClientModule<EC2Client, EC2AsyncCli
|
||||||
@Singleton
|
@Singleton
|
||||||
@ELB
|
@ELB
|
||||||
Map<String, URI> provideELBRegions() {
|
Map<String, URI> provideELBRegions() {
|
||||||
return ImmutableMap.<String, URI> of(Region.US_EAST_1, URI
|
return ImmutableMap
|
||||||
.create("https://elasticloadbalancing.us-east-1.amazonaws.com"), Region.US_WEST_1,
|
.<String, URI> of(
|
||||||
URI.create("https://elasticloadbalancing.us-west-1.amazonaws.com"),
|
Region.US_EAST_1,
|
||||||
|
URI
|
||||||
|
.create("https://elasticloadbalancing.us-east-1.amazonaws.com"),
|
||||||
|
Region.US_WEST_1,
|
||||||
|
URI
|
||||||
|
.create("https://elasticloadbalancing.us-west-1.amazonaws.com"),
|
||||||
Region.EU_WEST_1,
|
Region.EU_WEST_1,
|
||||||
URI.create("https://elasticloadbalancing.eu-west-1.amazonaws.com"),
|
URI
|
||||||
Region.AP_SOUTHEAST_1, URI
|
.create("https://elasticloadbalancing.eu-west-1.amazonaws.com"),
|
||||||
|
Region.AP_SOUTHEAST_1,
|
||||||
|
URI
|
||||||
.create("https://elasticloadbalancing.ap-southeast-1.amazonaws.com"));
|
.create("https://elasticloadbalancing.ap-southeast-1.amazonaws.com"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
@EC2
|
@EC2
|
||||||
String provideCurrentRegion(@EC2 Map<String, URI> regionMap, @EC2 URI currentUri) {
|
String provideCurrentRegion(@EC2 Map<String, URI> regionMap,
|
||||||
ImmutableBiMap<URI, String> map = ImmutableBiMap.<String, URI> builder().putAll(regionMap)
|
@EC2 URI currentUri) {
|
||||||
.build().inverse();
|
ImmutableBiMap<URI, String> map = ImmutableBiMap.<String, URI> builder()
|
||||||
|
.putAll(regionMap).build().inverse();
|
||||||
String region = map.get(currentUri);
|
String region = map.get(currentUri);
|
||||||
assert region != null : currentUri + " not in " + map;
|
assert region != null : currentUri + " not in " + map;
|
||||||
return region;
|
return region;
|
||||||
|
@ -184,7 +166,8 @@ public class EC2RestClientModule extends RestClientModule<EC2Client, EC2AsyncCli
|
||||||
@EC2 Map<String, URI> regions) {
|
@EC2 Map<String, URI> regions) {
|
||||||
Map<String, String> map = Maps.newHashMap();
|
Map<String, String> map = Maps.newHashMap();
|
||||||
for (String region : regions.keySet()) {
|
for (String region : regions.keySet()) {
|
||||||
for (AvailabilityZoneInfo zoneInfo : client.getAvailabilityZoneAndRegionServices()
|
for (AvailabilityZoneInfo zoneInfo : client
|
||||||
|
.getAvailabilityZoneAndRegionServices()
|
||||||
.describeAvailabilityZonesInRegion(region)) {
|
.describeAvailabilityZonesInRegion(region)) {
|
||||||
map.put(zoneInfo.getZone(), region);
|
map.put(zoneInfo.getZone(), region);
|
||||||
}
|
}
|
||||||
|
@ -209,7 +192,8 @@ public class EC2RestClientModule extends RestClientModule<EC2Client, EC2AsyncCli
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
@EC2
|
@EC2
|
||||||
protected URI provideURI(@Named(EC2Constants.PROPERTY_EC2_ENDPOINT) String endpoint) {
|
protected URI provideURI(
|
||||||
|
@Named(EC2Constants.PROPERTY_EC2_ENDPOINT) String endpoint) {
|
||||||
return URI.create(endpoint);
|
return URI.create(endpoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 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.aws.ec2.predicates;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import org.jclouds.aws.ec2.EC2Client;
|
||||||
|
import org.jclouds.aws.ec2.domain.RunningInstance;
|
||||||
|
import org.jclouds.logging.Logger;
|
||||||
|
import org.jclouds.rest.ResourceNotFoundException;
|
||||||
|
|
||||||
|
import com.google.common.base.Predicate;
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Tests to see if a task succeeds.
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Singleton
|
||||||
|
public class InstancePresent implements Predicate<RunningInstance> {
|
||||||
|
|
||||||
|
private final EC2Client client;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
protected Logger logger = Logger.NULL;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public InstancePresent(EC2Client client) {
|
||||||
|
this.client = client;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean apply(RunningInstance instance) {
|
||||||
|
logger.trace("looking for instance %s", instance);
|
||||||
|
try {
|
||||||
|
instance = refresh(instance);
|
||||||
|
return true;
|
||||||
|
} catch (ResourceNotFoundException e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private RunningInstance refresh(RunningInstance instance) {
|
||||||
|
return Iterables.getOnlyElement(Iterables.getOnlyElement(client
|
||||||
|
.getInstanceServices().describeInstancesInRegion(
|
||||||
|
instance.getRegion(), instance.getId())));
|
||||||
|
}
|
||||||
|
}
|
|
@ -21,11 +21,11 @@ package org.jclouds.aws.ec2.predicates;
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import org.jclouds.aws.AWSResponseException;
|
|
||||||
import org.jclouds.aws.ec2.EC2Client;
|
import org.jclouds.aws.ec2.EC2Client;
|
||||||
import org.jclouds.aws.ec2.domain.InstanceState;
|
import org.jclouds.aws.ec2.domain.InstanceState;
|
||||||
import org.jclouds.aws.ec2.domain.RunningInstance;
|
import org.jclouds.aws.ec2.domain.RunningInstance;
|
||||||
import org.jclouds.logging.Logger;
|
import org.jclouds.logging.Logger;
|
||||||
|
import org.jclouds.rest.ResourceNotFoundException;
|
||||||
|
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
|
@ -54,18 +54,18 @@ public class InstanceStateRunning implements Predicate<RunningInstance> {
|
||||||
logger.trace("looking for state on instance %s", instance);
|
logger.trace("looking for state on instance %s", instance);
|
||||||
try {
|
try {
|
||||||
instance = refresh(instance);
|
instance = refresh(instance);
|
||||||
logger.trace("%s: looking for instance state %s: currently: %s", instance.getId(),
|
logger.trace("%s: looking for instance state %s: currently: %s",
|
||||||
InstanceState.RUNNING, instance.getInstanceState());
|
instance.getId(), InstanceState.RUNNING, instance
|
||||||
|
.getInstanceState());
|
||||||
return instance.getInstanceState() == InstanceState.RUNNING;
|
return instance.getInstanceState() == InstanceState.RUNNING;
|
||||||
} catch (AWSResponseException e) {
|
} catch (ResourceNotFoundException e) {
|
||||||
if (e.getError().getCode().equals("InvalidInstanceID.NotFound"))
|
|
||||||
return false;
|
return false;
|
||||||
throw e;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private RunningInstance refresh(RunningInstance instance) {
|
private RunningInstance refresh(RunningInstance instance) {
|
||||||
return Iterables.getOnlyElement(Iterables.getOnlyElement(client.getInstanceServices()
|
return Iterables.getOnlyElement(Iterables.getOnlyElement(client
|
||||||
.describeInstancesInRegion(instance.getRegion(), instance.getId())));
|
.getInstanceServices().describeInstancesInRegion(
|
||||||
|
instance.getRegion(), instance.getId())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,21 +63,23 @@ public class ParseAWSErrorFromXmlContent implements HttpErrorHandler {
|
||||||
Exception exception = new HttpResponseException(command, response);
|
Exception exception = new HttpResponseException(command, response);
|
||||||
try {
|
try {
|
||||||
AWSError error = parseErrorFromContentOrNull(command, response);
|
AWSError error = parseErrorFromContentOrNull(command, response);
|
||||||
exception = error != null ? new AWSResponseException(command, response, error) : exception;
|
exception = error != null ? new AWSResponseException(command,
|
||||||
|
response, error) : exception;
|
||||||
switch (response.getStatusCode()) {
|
switch (response.getStatusCode()) {
|
||||||
case 400:
|
case 400:
|
||||||
if (error.getCode().equals("InvalidAMIID.NotFound")
|
if (error.getCode().endsWith(".NotFound"))
|
||||||
|| error.getCode().equals("InvalidAMIID.Malformed"))
|
exception = new ResourceNotFoundException(error.getMessage(),
|
||||||
exception = new ResourceNotFoundException(error.getMessage(), exception);
|
exception);
|
||||||
break;
|
break;
|
||||||
case 401:
|
case 401:
|
||||||
exception = new AuthorizationException(command.getRequest(), error != null ? error
|
exception = new AuthorizationException(command.getRequest(),
|
||||||
.getMessage() : response.getStatusLine());
|
error != null ? error.getMessage() : response.getStatusLine());
|
||||||
break;
|
break;
|
||||||
case 404:
|
case 404:
|
||||||
if (!command.getRequest().getMethod().equals("DELETE")) {
|
if (!command.getRequest().getMethod().equals("DELETE")) {
|
||||||
String message = error != null ? error.getMessage() : String.format("%s -> %s",
|
String message = error != null ? error.getMessage() : String
|
||||||
command.getRequest().getRequestLine(), response.getStatusLine());
|
.format("%s -> %s", command.getRequest().getRequestLine(),
|
||||||
|
response.getStatusLine());
|
||||||
String container = command.getRequest().getEndpoint().getHost();
|
String container = command.getRequest().getEndpoint().getHost();
|
||||||
String key = command.getRequest().getEndpoint().getPath();
|
String key = command.getRequest().getEndpoint().getPath();
|
||||||
if (key == null || key.equals("/"))
|
if (key == null || key.equals("/"))
|
||||||
|
@ -93,12 +95,14 @@ public class ParseAWSErrorFromXmlContent implements HttpErrorHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AWSError parseErrorFromContentOrNull(HttpCommand command, HttpResponse response) {
|
AWSError parseErrorFromContentOrNull(HttpCommand command,
|
||||||
|
HttpResponse response) {
|
||||||
if (response.getContent() != null) {
|
if (response.getContent() != null) {
|
||||||
try {
|
try {
|
||||||
String content = Utils.toStringAndClose(response.getContent());
|
String content = Utils.toStringAndClose(response.getContent());
|
||||||
if (content != null && content.indexOf('<') >= 0)
|
if (content != null && content.indexOf('<') >= 0)
|
||||||
return utils.parseAWSErrorFromContent(command, response, content);
|
return utils
|
||||||
|
.parseAWSErrorFromContent(command, response, content);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
logger.warn(e, "exception reading error from response", response);
|
logger.warn(e, "exception reading error from response", response);
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,7 +67,8 @@ import com.google.inject.Injector;
|
||||||
/**
|
/**
|
||||||
* Follows the book Cloud Application Architectures ISBN: 978-0-596-15636-7
|
* Follows the book Cloud Application Architectures ISBN: 978-0-596-15636-7
|
||||||
* <p/>
|
* <p/>
|
||||||
* adds in functionality to boot a lamp instance: http://alestic.com/2009/06/ec2-user-data-scripts
|
* adds in functionality to boot a lamp instance:
|
||||||
|
* http://alestic.com/2009/06/ec2-user-data-scripts
|
||||||
* <p/>
|
* <p/>
|
||||||
* Generally disabled, as it incurs higher fees.
|
* Generally disabled, as it incurs higher fees.
|
||||||
*
|
*
|
||||||
|
@ -89,41 +90,50 @@ public class CloudApplicationArchitecturesEC2ClientLiveTest {
|
||||||
private RetryablePredicate<RunningInstance> runningTester;
|
private RetryablePredicate<RunningInstance> runningTester;
|
||||||
|
|
||||||
@BeforeGroups(groups = { "live" })
|
@BeforeGroups(groups = { "live" })
|
||||||
public void setupClient() throws InterruptedException, ExecutionException, TimeoutException {
|
public void setupClient() throws InterruptedException, ExecutionException,
|
||||||
String user = checkNotNull(System.getProperty("jclouds.test.user"), "jclouds.test.user");
|
TimeoutException {
|
||||||
String password = checkNotNull(System.getProperty("jclouds.test.key"), "jclouds.test.key");
|
String user = checkNotNull(System.getProperty("jclouds.test.user"),
|
||||||
Injector injector = new EC2ContextBuilder("ec2", new EC2PropertiesBuilder(user, password)
|
"jclouds.test.user");
|
||||||
.build()).withModules(new Log4JLoggingModule(), new JschSshClientModule())
|
String password = checkNotNull(System.getProperty("jclouds.test.key"),
|
||||||
|
"jclouds.test.key");
|
||||||
|
Injector injector = new EC2ContextBuilder("ec2",
|
||||||
|
new EC2PropertiesBuilder(user, password).build()).withModules(
|
||||||
|
new Log4JLoggingModule(), new JschSshClientModule())
|
||||||
.buildInjector();
|
.buildInjector();
|
||||||
client = injector.getInstance(EC2Client.class);
|
client = injector.getInstance(EC2Client.class);
|
||||||
sshFactory = injector.getInstance(SshClient.Factory.class);
|
sshFactory = injector.getInstance(SshClient.Factory.class);
|
||||||
runningTester = new RetryablePredicate<RunningInstance>(new InstanceStateRunning(client),
|
runningTester = new RetryablePredicate<RunningInstance>(
|
||||||
180, 5, TimeUnit.SECONDS);
|
new InstanceStateRunning(client), 180, 5, TimeUnit.SECONDS);
|
||||||
hasIpTester = new RetryablePredicate<RunningInstance>(new InstanceHasIpAddress(client), 180, 5, TimeUnit.SECONDS);
|
hasIpTester = new RetryablePredicate<RunningInstance>(
|
||||||
|
new InstanceHasIpAddress(client), 180, 5, TimeUnit.SECONDS);
|
||||||
SocketOpen socketOpen = injector.getInstance(SocketOpen.class);
|
SocketOpen socketOpen = injector.getInstance(SocketOpen.class);
|
||||||
socketTester = new RetryablePredicate<IPSocket>(socketOpen, 180, 1, TimeUnit.SECONDS);
|
socketTester = new RetryablePredicate<IPSocket>(socketOpen, 180, 1,
|
||||||
|
TimeUnit.SECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(enabled = false)
|
@Test(enabled = false)
|
||||||
void testCreateSecurityGroupIngressCidr() throws InterruptedException, ExecutionException,
|
void testCreateSecurityGroupIngressCidr() throws InterruptedException,
|
||||||
TimeoutException {
|
ExecutionException, TimeoutException {
|
||||||
securityGroupName = instancePrefix + "ingress";
|
securityGroupName = instancePrefix + "ingress";
|
||||||
|
|
||||||
try {
|
try {
|
||||||
client.getSecurityGroupServices().deleteSecurityGroupInRegion(null, securityGroupName);
|
client.getSecurityGroupServices().deleteSecurityGroupInRegion(null,
|
||||||
|
securityGroupName);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
client.getSecurityGroupServices().createSecurityGroupInRegion(null, securityGroupName,
|
client.getSecurityGroupServices().createSecurityGroupInRegion(null,
|
||||||
securityGroupName);
|
securityGroupName, securityGroupName);
|
||||||
for (int port : new int[] { 80, 443, 22 }) {
|
for (int port : new int[] { 80, 443, 22 }) {
|
||||||
client.getSecurityGroupServices().authorizeSecurityGroupIngressInRegion(null,
|
client.getSecurityGroupServices()
|
||||||
securityGroupName, IpProtocol.TCP, port, port, "0.0.0.0/0");
|
.authorizeSecurityGroupIngressInRegion(null, securityGroupName,
|
||||||
|
IpProtocol.TCP, port, port, "0.0.0.0/0");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(enabled = false)
|
@Test(enabled = false)
|
||||||
void testCreateKeyPair() throws InterruptedException, ExecutionException, TimeoutException {
|
void testCreateKeyPair() throws InterruptedException, ExecutionException,
|
||||||
|
TimeoutException {
|
||||||
String keyName = instancePrefix + "1";
|
String keyName = instancePrefix + "1";
|
||||||
try {
|
try {
|
||||||
client.getKeyPairServices().deleteKeyPairInRegion(null, keyName);
|
client.getKeyPairServices().deleteKeyPairInRegion(null, keyName);
|
||||||
|
@ -132,7 +142,8 @@ public class CloudApplicationArchitecturesEC2ClientLiveTest {
|
||||||
}
|
}
|
||||||
client.getKeyPairServices().deleteKeyPairInRegion(null, keyName);
|
client.getKeyPairServices().deleteKeyPairInRegion(null, keyName);
|
||||||
|
|
||||||
keyPair = client.getKeyPairServices().createKeyPairInRegion(null, keyName);
|
keyPair = client.getKeyPairServices()
|
||||||
|
.createKeyPairInRegion(null, keyName);
|
||||||
assertNotNull(keyPair);
|
assertNotNull(keyPair);
|
||||||
assertNotNull(keyPair.getKeyMaterial());
|
assertNotNull(keyPair.getKeyMaterial());
|
||||||
assertNotNull(keyPair.getKeyFingerprint());
|
assertNotNull(keyPair.getKeyFingerprint());
|
||||||
|
@ -151,21 +162,29 @@ public class CloudApplicationArchitecturesEC2ClientLiveTest {
|
||||||
while (instance == null) {
|
while (instance == null) {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
System.out.printf("%d: running instance%n", System.currentTimeMillis());
|
System.out.printf("%d: running instance%n", System
|
||||||
Reservation reservation = client.getInstanceServices().runInstancesInRegion(null, null, // allow
|
.currentTimeMillis());
|
||||||
|
Reservation reservation = client.getInstanceServices()
|
||||||
|
.runInstancesInRegion(null, null, // allow
|
||||||
// ec2
|
// ec2
|
||||||
// to
|
// to
|
||||||
// chose
|
// chose
|
||||||
// an
|
// an
|
||||||
// availability
|
// availability
|
||||||
// zone
|
// zone
|
||||||
"ami-ccf615a5", // alestic ami allows auto-invoke of user data scripts
|
"ami-ccf615a5", // alestic ami allows auto-invoke of
|
||||||
|
// user data scripts
|
||||||
1, // minimum instances
|
1, // minimum instances
|
||||||
1, // maximum instances
|
1, // maximum instances
|
||||||
asType(InstanceType.M1_SMALL) // smallest instance size
|
asType(InstanceType.M1_SMALL) // smallest instance size
|
||||||
.withKeyName(keyPair.getKeyName()) // key I created above
|
.withKeyName(keyPair.getKeyName()) // key I
|
||||||
.withSecurityGroup(securityGroupName) // group I created above
|
// created
|
||||||
.withUserData(script.getBytes())); // script to run as root
|
// above
|
||||||
|
.withSecurityGroup(securityGroupName) // group I
|
||||||
|
// created
|
||||||
|
// above
|
||||||
|
.withUserData(script.getBytes())); // script to
|
||||||
|
// run as root
|
||||||
|
|
||||||
instance = Iterables.getOnlyElement(reservation);
|
instance = Iterables.getOnlyElement(reservation);
|
||||||
|
|
||||||
|
@ -183,45 +202,51 @@ public class CloudApplicationArchitecturesEC2ClientLiveTest {
|
||||||
verifyInstanceProperties(script);
|
verifyInstanceProperties(script);
|
||||||
tryToChangeStuff();
|
tryToChangeStuff();
|
||||||
sshPing(instance);
|
sshPing(instance);
|
||||||
System.out.printf("%d: %s ssh connection made%n", System.currentTimeMillis(), instanceId);
|
System.out.printf("%d: %s ssh connection made%n", System
|
||||||
|
.currentTimeMillis(), instanceId);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void verifyInstanceProperties(String script) {
|
private void verifyInstanceProperties(String script) {
|
||||||
assertEquals(script, client.getInstanceServices().getUserDataForInstanceInRegion(null,
|
assertEquals(script, client.getInstanceServices()
|
||||||
instanceId));
|
.getUserDataForInstanceInRegion(null, instanceId));
|
||||||
|
|
||||||
assertEquals(null, client.getInstanceServices().getRootDeviceNameForInstanceInRegion(null,
|
assertEquals(null, client.getInstanceServices()
|
||||||
instanceId));
|
.getRootDeviceNameForInstanceInRegion(null, instanceId));
|
||||||
|
|
||||||
assert client.getInstanceServices().getRamdiskForInstanceInRegion(null, instanceId)
|
assert client.getInstanceServices().getRamdiskForInstanceInRegion(null,
|
||||||
.startsWith("ari-");
|
instanceId).startsWith("ari-");
|
||||||
|
|
||||||
assertEquals(false, client.getInstanceServices().isApiTerminationDisabledForInstanceInRegion(
|
assertEquals(false, client.getInstanceServices()
|
||||||
null, instanceId));
|
.isApiTerminationDisabledForInstanceInRegion(null, instanceId));
|
||||||
|
|
||||||
assert client.getInstanceServices().getKernelForInstanceInRegion(null, instanceId)
|
assert client.getInstanceServices().getKernelForInstanceInRegion(null,
|
||||||
.startsWith("aki-");
|
instanceId).startsWith("aki-");
|
||||||
|
|
||||||
assertEquals(InstanceType.M1_SMALL, client.getInstanceServices()
|
assertEquals(InstanceType.M1_SMALL, client.getInstanceServices()
|
||||||
.getInstanceTypeForInstanceInRegion(null, instanceId));
|
.getInstanceTypeForInstanceInRegion(null, instanceId));
|
||||||
|
|
||||||
assertEquals(InstanceInitiatedShutdownBehavior.TERMINATE, client.getInstanceServices()
|
assertEquals(InstanceInitiatedShutdownBehavior.TERMINATE, client
|
||||||
.getInstanceInitiatedShutdownBehaviorForInstanceInRegion(null, instanceId));
|
.getInstanceServices()
|
||||||
|
.getInstanceInitiatedShutdownBehaviorForInstanceInRegion(null,
|
||||||
|
instanceId));
|
||||||
|
|
||||||
assertEquals(ImmutableMap.<String, EbsBlockDevice> of(), client.getInstanceServices()
|
assertEquals(ImmutableMap.<String, EbsBlockDevice> of(), client
|
||||||
.getBlockDeviceMappingForInstanceInRegion(null, instanceId));
|
.getInstanceServices().getBlockDeviceMappingForInstanceInRegion(
|
||||||
|
null, instanceId));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setApiTerminationDisabledForInstanceInRegion() {
|
private void setApiTerminationDisabledForInstanceInRegion() {
|
||||||
client.getInstanceServices().setApiTerminationDisabledForInstanceInRegion(null, instanceId,
|
client.getInstanceServices()
|
||||||
|
.setApiTerminationDisabledForInstanceInRegion(null, instanceId,
|
||||||
true);
|
true);
|
||||||
assertEquals(true, client.getInstanceServices().isApiTerminationDisabledForInstanceInRegion(
|
assertEquals(true, client.getInstanceServices()
|
||||||
null, instanceId));
|
.isApiTerminationDisabledForInstanceInRegion(null, instanceId));
|
||||||
client.getInstanceServices().setApiTerminationDisabledForInstanceInRegion(null, instanceId,
|
client.getInstanceServices()
|
||||||
|
.setApiTerminationDisabledForInstanceInRegion(null, instanceId,
|
||||||
false);
|
false);
|
||||||
assertEquals(false, client.getInstanceServices().isApiTerminationDisabledForInstanceInRegion(
|
assertEquals(false, client.getInstanceServices()
|
||||||
null, instanceId));
|
.isApiTerminationDisabledForInstanceInRegion(null, instanceId));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void tryToChangeStuff() {
|
private void tryToChangeStuff() {
|
||||||
|
@ -236,8 +261,8 @@ public class CloudApplicationArchitecturesEC2ClientLiveTest {
|
||||||
|
|
||||||
private void setUserDataForInstanceInRegion() {
|
private void setUserDataForInstanceInRegion() {
|
||||||
try {
|
try {
|
||||||
client.getInstanceServices().setUserDataForInstanceInRegion(null, instanceId,
|
client.getInstanceServices().setUserDataForInstanceInRegion(null,
|
||||||
"test".getBytes());
|
instanceId, "test".getBytes());
|
||||||
assert false : "shouldn't be allowed, as instance needs to be stopped";
|
assert false : "shouldn't be allowed, as instance needs to be stopped";
|
||||||
} catch (AWSResponseException e) {
|
} catch (AWSResponseException e) {
|
||||||
assertEquals("IncorrectInstanceState", e.getError().getCode());
|
assertEquals("IncorrectInstanceState", e.getError().getCode());
|
||||||
|
@ -246,9 +271,10 @@ public class CloudApplicationArchitecturesEC2ClientLiveTest {
|
||||||
|
|
||||||
private void setRamdiskForInstanceInRegion() {
|
private void setRamdiskForInstanceInRegion() {
|
||||||
try {
|
try {
|
||||||
String ramdisk = client.getInstanceServices().getRamdiskForInstanceInRegion(null,
|
String ramdisk = client.getInstanceServices()
|
||||||
instanceId);
|
.getRamdiskForInstanceInRegion(null, instanceId);
|
||||||
client.getInstanceServices().setRamdiskForInstanceInRegion(null, instanceId, ramdisk);
|
client.getInstanceServices().setRamdiskForInstanceInRegion(null,
|
||||||
|
instanceId, ramdisk);
|
||||||
assert false : "shouldn't be allowed, as instance needs to be stopped";
|
assert false : "shouldn't be allowed, as instance needs to be stopped";
|
||||||
} catch (AWSResponseException e) {
|
} catch (AWSResponseException e) {
|
||||||
assertEquals("IncorrectInstanceState", e.getError().getCode());
|
assertEquals("IncorrectInstanceState", e.getError().getCode());
|
||||||
|
@ -257,9 +283,10 @@ public class CloudApplicationArchitecturesEC2ClientLiveTest {
|
||||||
|
|
||||||
private void setKernelForInstanceInRegion() {
|
private void setKernelForInstanceInRegion() {
|
||||||
try {
|
try {
|
||||||
String oldKernel = client.getInstanceServices().getKernelForInstanceInRegion(null,
|
String oldKernel = client.getInstanceServices()
|
||||||
instanceId);
|
.getKernelForInstanceInRegion(null, instanceId);
|
||||||
client.getInstanceServices().setKernelForInstanceInRegion(null, instanceId, oldKernel);
|
client.getInstanceServices().setKernelForInstanceInRegion(null,
|
||||||
|
instanceId, oldKernel);
|
||||||
assert false : "shouldn't be allowed, as instance needs to be stopped";
|
assert false : "shouldn't be allowed, as instance needs to be stopped";
|
||||||
} catch (AWSResponseException e) {
|
} catch (AWSResponseException e) {
|
||||||
assertEquals("IncorrectInstanceState", e.getError().getCode());
|
assertEquals("IncorrectInstanceState", e.getError().getCode());
|
||||||
|
@ -268,8 +295,8 @@ public class CloudApplicationArchitecturesEC2ClientLiveTest {
|
||||||
|
|
||||||
private void setInstanceTypeForInstanceInRegion() {
|
private void setInstanceTypeForInstanceInRegion() {
|
||||||
try {
|
try {
|
||||||
client.getInstanceServices().setInstanceTypeForInstanceInRegion(null, instanceId,
|
client.getInstanceServices().setInstanceTypeForInstanceInRegion(null,
|
||||||
InstanceType.C1_MEDIUM);
|
instanceId, InstanceType.C1_MEDIUM);
|
||||||
assert false : "shouldn't be allowed, as instance needs to be stopped";
|
assert false : "shouldn't be allowed, as instance needs to be stopped";
|
||||||
} catch (AWSResponseException e) {
|
} catch (AWSResponseException e) {
|
||||||
assertEquals("IncorrectInstanceState", e.getError().getCode());
|
assertEquals("IncorrectInstanceState", e.getError().getCode());
|
||||||
|
@ -279,8 +306,8 @@ public class CloudApplicationArchitecturesEC2ClientLiveTest {
|
||||||
private void setBlockDeviceMappingForInstanceInRegion() {
|
private void setBlockDeviceMappingForInstanceInRegion() {
|
||||||
BlockDeviceMapping blockDeviceMapping = new BlockDeviceMapping();
|
BlockDeviceMapping blockDeviceMapping = new BlockDeviceMapping();
|
||||||
try {
|
try {
|
||||||
client.getInstanceServices().setBlockDeviceMappingForInstanceInRegion(null, instanceId,
|
client.getInstanceServices().setBlockDeviceMappingForInstanceInRegion(
|
||||||
blockDeviceMapping);
|
null, instanceId, blockDeviceMapping);
|
||||||
assert false : "shouldn't be allowed, as instance needs to be ebs based-ami";
|
assert false : "shouldn't be allowed, as instance needs to be ebs based-ami";
|
||||||
} catch (AWSResponseException e) {
|
} catch (AWSResponseException e) {
|
||||||
assertEquals("InvalidParameterCombination", e.getError().getCode());
|
assertEquals("InvalidParameterCombination", e.getError().getCode());
|
||||||
|
@ -289,7 +316,8 @@ public class CloudApplicationArchitecturesEC2ClientLiveTest {
|
||||||
|
|
||||||
private void setInstanceInitiatedShutdownBehaviorForInstanceInRegion() {
|
private void setInstanceInitiatedShutdownBehaviorForInstanceInRegion() {
|
||||||
try {
|
try {
|
||||||
client.getInstanceServices().setInstanceInitiatedShutdownBehaviorForInstanceInRegion(null,
|
client.getInstanceServices()
|
||||||
|
.setInstanceInitiatedShutdownBehaviorForInstanceInRegion(null,
|
||||||
instanceId, InstanceInitiatedShutdownBehavior.STOP);
|
instanceId, InstanceInitiatedShutdownBehavior.STOP);
|
||||||
assert false : "shouldn't be allowed, as instance needs to be ebs based-ami";
|
assert false : "shouldn't be allowed, as instance needs to be ebs based-ami";
|
||||||
} catch (AWSResponseException e) {
|
} catch (AWSResponseException e) {
|
||||||
|
@ -298,19 +326,22 @@ public class CloudApplicationArchitecturesEC2ClientLiveTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(enabled = false, dependsOnMethods = "testCreateRunningInstance")
|
@Test(enabled = false, dependsOnMethods = "testCreateRunningInstance")
|
||||||
void testReboot() throws InterruptedException, ExecutionException, TimeoutException, IOException {
|
void testReboot() throws InterruptedException, ExecutionException,
|
||||||
|
TimeoutException, IOException {
|
||||||
RunningInstance instance = getInstance(instanceId);
|
RunningInstance instance = getInstance(instanceId);
|
||||||
System.out.printf("%d: %s rebooting instance %n", System.currentTimeMillis(), instanceId);
|
System.out.printf("%d: %s rebooting instance %n", System
|
||||||
|
.currentTimeMillis(), instanceId);
|
||||||
client.getInstanceServices().rebootInstancesInRegion(null, instanceId);
|
client.getInstanceServices().rebootInstancesInRegion(null, instanceId);
|
||||||
Thread.sleep(1000);
|
Thread.sleep(1000);
|
||||||
instance = getInstance(instanceId);
|
instance = getInstance(instanceId);
|
||||||
blockUntilWeCanSshIntoInstance(instance);
|
blockUntilWeCanSshIntoInstance(instance);
|
||||||
SshClient ssh = sshFactory.create(new IPSocket(instance.getIpAddress(), 22), "root", keyPair
|
SshClient ssh = sshFactory.create(new IPSocket(instance.getIpAddress(),
|
||||||
.getKeyMaterial().getBytes());
|
22), "root", keyPair.getKeyMaterial().getBytes());
|
||||||
try {
|
try {
|
||||||
ssh.connect();
|
ssh.connect();
|
||||||
ExecResponse uptime = ssh.exec("uptime");
|
ExecResponse uptime = ssh.exec("uptime");
|
||||||
assert uptime.getOutput().indexOf("0 min") != -1 : "reboot didn't work: " + uptime;
|
assert uptime.getOutput().indexOf("0 min") != -1 : "reboot didn't work: "
|
||||||
|
+ uptime;
|
||||||
} finally {
|
} finally {
|
||||||
if (ssh != null)
|
if (ssh != null)
|
||||||
ssh.disconnect();
|
ssh.disconnect();
|
||||||
|
@ -318,86 +349,95 @@ public class CloudApplicationArchitecturesEC2ClientLiveTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(enabled = false, dependsOnMethods = "testReboot")
|
@Test(enabled = false, dependsOnMethods = "testReboot")
|
||||||
void testElasticIpAddress() throws InterruptedException, ExecutionException, TimeoutException,
|
void testElasticIpAddress() throws InterruptedException, ExecutionException,
|
||||||
IOException {
|
TimeoutException, IOException {
|
||||||
address = client.getElasticIPAddressServices().allocateAddressInRegion(null);
|
address = client.getElasticIPAddressServices().allocateAddressInRegion(
|
||||||
|
null);
|
||||||
assertNotNull(address);
|
assertNotNull(address);
|
||||||
|
|
||||||
PublicIpInstanceIdPair compare = Iterables.getLast(client.getElasticIPAddressServices()
|
PublicIpInstanceIdPair compare = Iterables.getLast(client
|
||||||
.describeAddressesInRegion(null, address));
|
.getElasticIPAddressServices().describeAddressesInRegion(null,
|
||||||
|
address));
|
||||||
|
|
||||||
assertEquals(compare.getPublicIp(), address);
|
assertEquals(compare.getPublicIp(), address);
|
||||||
assert compare.getInstanceId() == null;
|
assert compare.getInstanceId() == null;
|
||||||
|
|
||||||
client.getElasticIPAddressServices().associateAddressInRegion(null, address, instanceId);
|
client.getElasticIPAddressServices().associateAddressInRegion(null,
|
||||||
|
address, instanceId);
|
||||||
|
|
||||||
compare = Iterables.getLast(client.getElasticIPAddressServices().describeAddressesInRegion(
|
compare = Iterables.getLast(client.getElasticIPAddressServices()
|
||||||
null, address));
|
.describeAddressesInRegion(null, address));
|
||||||
|
|
||||||
assertEquals(compare.getPublicIp(), address);
|
assertEquals(compare.getPublicIp(), address);
|
||||||
assertEquals(compare.getInstanceId(), instanceId);
|
assertEquals(compare.getInstanceId(), instanceId);
|
||||||
|
|
||||||
Reservation reservation = Iterables.getOnlyElement(client.getInstanceServices()
|
Reservation reservation = Iterables.getOnlyElement(client
|
||||||
.describeInstancesInRegion(null, instanceId));
|
.getInstanceServices().describeInstancesInRegion(null, instanceId));
|
||||||
|
|
||||||
assertNotNull(Iterables.getOnlyElement(reservation).getIpAddress());
|
assertNotNull(Iterables.getOnlyElement(reservation).getIpAddress());
|
||||||
assertFalse(Iterables.getOnlyElement(reservation).getIpAddress().equals(address));
|
assertFalse(Iterables.getOnlyElement(reservation).getIpAddress().equals(
|
||||||
|
address));
|
||||||
|
|
||||||
doCheckKey(address);
|
doCheckKey(address);
|
||||||
|
|
||||||
client.getElasticIPAddressServices().disassociateAddressInRegion(null, address);
|
client.getElasticIPAddressServices().disassociateAddressInRegion(null,
|
||||||
|
address);
|
||||||
|
|
||||||
compare = Iterables.getLast(client.getElasticIPAddressServices().describeAddressesInRegion(
|
compare = Iterables.getLast(client.getElasticIPAddressServices()
|
||||||
null, address));
|
.describeAddressesInRegion(null, address));
|
||||||
|
|
||||||
assertEquals(compare.getPublicIp(), address);
|
assertEquals(compare.getPublicIp(), address);
|
||||||
assert compare.getInstanceId() == null;
|
assert compare.getInstanceId() == null;
|
||||||
|
|
||||||
reservation = Iterables.getOnlyElement(client.getInstanceServices()
|
reservation = Iterables.getOnlyElement(client.getInstanceServices()
|
||||||
.describeInstancesInRegion(null, instanceId));
|
.describeInstancesInRegion(null, instanceId));
|
||||||
// assert reservation.getRunningInstances().last().getIpAddress() == null; TODO
|
// assert reservation.getRunningInstances().last().getIpAddress() == null;
|
||||||
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
private RunningInstance blockUntilWeCanSshIntoInstance(RunningInstance instance)
|
private RunningInstance blockUntilWeCanSshIntoInstance(
|
||||||
throws UnknownHostException {
|
RunningInstance instance) throws UnknownHostException {
|
||||||
System.out.printf("%d: %s awaiting instance to run %n", System.currentTimeMillis(), instance
|
System.out.printf("%d: %s awaiting instance to run %n", System
|
||||||
.getId());
|
.currentTimeMillis(), instance.getId());
|
||||||
assert runningTester.apply(instance);
|
assert runningTester.apply(instance);
|
||||||
|
|
||||||
instance = getInstance(instance.getId());
|
instance = getInstance(instance.getId());
|
||||||
|
|
||||||
System.out.printf("%d: %s awaiting instance to have ip assigned %n", System
|
System.out.printf("%d: %s awaiting instance to have ip assigned %n",
|
||||||
.currentTimeMillis(), instance.getId());
|
System.currentTimeMillis(), instance.getId());
|
||||||
assert hasIpTester.apply(instance);
|
assert hasIpTester.apply(instance);
|
||||||
|
|
||||||
System.out.printf("%d: %s awaiting ssh service to start%n", System.currentTimeMillis(),
|
System.out.printf("%d: %s awaiting ssh service to start%n", System
|
||||||
instance.getIpAddress());
|
.currentTimeMillis(), instance.getIpAddress());
|
||||||
assert socketTester.apply(new IPSocket(instance.getIpAddress(), 22));
|
assert socketTester.apply(new IPSocket(instance.getIpAddress(), 22));
|
||||||
|
|
||||||
System.out.printf("%d: %s ssh service started%n", System.currentTimeMillis(), instance
|
System.out.printf("%d: %s ssh service started%n", System
|
||||||
.getDnsName());
|
.currentTimeMillis(), instance.getDnsName());
|
||||||
sshPing(instance);
|
sshPing(instance);
|
||||||
System.out.printf("%d: %s ssh connection made%n", System.currentTimeMillis(), instance
|
System.out.printf("%d: %s ssh connection made%n", System
|
||||||
.getId());
|
.currentTimeMillis(), instance.getId());
|
||||||
|
|
||||||
System.out.printf("%d: %s awaiting http service to start%n", System.currentTimeMillis(),
|
System.out.printf("%d: %s awaiting http service to start%n", System
|
||||||
instance.getIpAddress());
|
.currentTimeMillis(), instance.getIpAddress());
|
||||||
assert socketTester.apply(new IPSocket(instance.getIpAddress(), 80));
|
assert socketTester.apply(new IPSocket(instance.getIpAddress(), 80));
|
||||||
System.out.printf("%d: %s http service started%n", System.currentTimeMillis(), instance
|
System.out.printf("%d: %s http service started%n", System
|
||||||
.getDnsName());
|
.currentTimeMillis(), instance.getDnsName());
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
private RunningInstance getInstance(String instanceId) {
|
private RunningInstance getInstance(String instanceId) {
|
||||||
// search my account for the instance I just created
|
// search my account for the instance I just created
|
||||||
Set<Reservation> reservations = client.getInstanceServices().describeInstancesInRegion(null,
|
Set<Reservation> reservations = client.getInstanceServices()
|
||||||
instanceId); // last parameter (ids) narrows the search
|
.describeInstancesInRegion(null, instanceId); // last parameter
|
||||||
|
// (ids) narrows the
|
||||||
|
// search
|
||||||
|
|
||||||
return Iterables.getOnlyElement(Iterables.getOnlyElement(reservations));
|
return Iterables.getOnlyElement(Iterables.getOnlyElement(reservations));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* this tests "personality" as the file looked up was sent during instance creation
|
* this tests "personality" as the file looked up was sent during instance
|
||||||
|
* creation
|
||||||
*
|
*
|
||||||
* @throws UnknownHostException
|
* @throws UnknownHostException
|
||||||
*/
|
*/
|
||||||
|
@ -413,13 +453,14 @@ public class CloudApplicationArchitecturesEC2ClientLiveTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void doCheckKey(RunningInstance newDetails) throws UnknownHostException {
|
private void doCheckKey(RunningInstance newDetails)
|
||||||
|
throws UnknownHostException {
|
||||||
doCheckKey(newDetails.getIpAddress());
|
doCheckKey(newDetails.getIpAddress());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void doCheckKey(String address) {
|
private void doCheckKey(String address) {
|
||||||
SshClient ssh = sshFactory.create(new IPSocket(address, 22), "root", keyPair.getKeyMaterial()
|
SshClient ssh = sshFactory.create(new IPSocket(address, 22), "root",
|
||||||
.getBytes());
|
keyPair.getKeyMaterial().getBytes());
|
||||||
try {
|
try {
|
||||||
ssh.connect();
|
ssh.connect();
|
||||||
ExecResponse hello = ssh.exec("echo hello");
|
ExecResponse hello = ssh.exec("echo hello");
|
||||||
|
@ -431,15 +472,20 @@ public class CloudApplicationArchitecturesEC2ClientLiveTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterTest
|
@AfterTest
|
||||||
void cleanup() throws InterruptedException, ExecutionException, TimeoutException {
|
void cleanup() throws InterruptedException, ExecutionException,
|
||||||
|
TimeoutException {
|
||||||
if (address != null)
|
if (address != null)
|
||||||
client.getElasticIPAddressServices().releaseAddressInRegion(null, address);
|
client.getElasticIPAddressServices().releaseAddressInRegion(null,
|
||||||
|
address);
|
||||||
if (instanceId != null)
|
if (instanceId != null)
|
||||||
client.getInstanceServices().terminateInstancesInRegion(null, instanceId);
|
client.getInstanceServices().terminateInstancesInRegion(null,
|
||||||
|
instanceId);
|
||||||
if (keyPair != null)
|
if (keyPair != null)
|
||||||
client.getKeyPairServices().deleteKeyPairInRegion(null, keyPair.getKeyName());
|
client.getKeyPairServices().deleteKeyPairInRegion(null,
|
||||||
|
keyPair.getKeyName());
|
||||||
if (securityGroupName != null)
|
if (securityGroupName != null)
|
||||||
client.getSecurityGroupServices().deleteSecurityGroupInRegion(null, securityGroupName);
|
client.getSecurityGroupServices().deleteSecurityGroupInRegion(null,
|
||||||
|
securityGroupName);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,8 +78,8 @@ import com.google.inject.Injector;
|
||||||
import com.google.inject.internal.ImmutableMap;
|
import com.google.inject.internal.ImmutableMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adapted from the following sources: {@link http://gist.github.com/249915}, {@link http
|
* Adapted from the following sources: {@link http://gist.github.com/249915},
|
||||||
* ://www.capsunlock.net/2009/12/create-ebs-boot-ami.html}
|
* {@link http ://www.capsunlock.net/2009/12/create-ebs-boot-ami.html}
|
||||||
* <p/>
|
* <p/>
|
||||||
*
|
*
|
||||||
* Generally disabled, as it incurs higher fees.
|
* Generally disabled, as it incurs higher fees.
|
||||||
|
@ -91,7 +91,9 @@ public class EBSBootEC2ClientLiveTest {
|
||||||
// don't need a lot of space. 2GB should be more than enough for testing
|
// don't need a lot of space. 2GB should be more than enough for testing
|
||||||
private static final int VOLUME_SIZE = 2;
|
private static final int VOLUME_SIZE = 2;
|
||||||
private static final String SCRIPT_END = "----COMPLETE----";
|
private static final String SCRIPT_END = "----COMPLETE----";
|
||||||
private static final String INSTANCE_PREFIX = System.getProperty("user.name") + ".ec2ebs";
|
private static final String INSTANCE_PREFIX = System
|
||||||
|
.getProperty("user.name")
|
||||||
|
+ ".ec2ebs";
|
||||||
private static final String IMAGE_ID = "ami-7e28ca17";
|
private static final String IMAGE_ID = "ami-7e28ca17";
|
||||||
|
|
||||||
private EC2Client client;
|
private EC2Client client;
|
||||||
|
@ -117,58 +119,70 @@ public class EBSBootEC2ClientLiveTest {
|
||||||
|
|
||||||
@BeforeGroups(groups = { "live" })
|
@BeforeGroups(groups = { "live" })
|
||||||
public void setupClient() {
|
public void setupClient() {
|
||||||
String user = checkNotNull(System.getProperty("jclouds.test.user"), "jclouds.test.user");
|
String user = checkNotNull(System.getProperty("jclouds.test.user"),
|
||||||
String password = checkNotNull(System.getProperty("jclouds.test.key"), "jclouds.test.key");
|
"jclouds.test.user");
|
||||||
Injector injector = new EC2ContextBuilder("ec2", new EC2PropertiesBuilder(user, password)
|
String password = checkNotNull(System.getProperty("jclouds.test.key"),
|
||||||
.build()).withModules(new Log4JLoggingModule(), new JschSshClientModule())
|
"jclouds.test.key");
|
||||||
|
Injector injector = new EC2ContextBuilder("ec2",
|
||||||
|
new EC2PropertiesBuilder(user, password).build()).withModules(
|
||||||
|
new Log4JLoggingModule(), new JschSshClientModule())
|
||||||
.buildInjector();
|
.buildInjector();
|
||||||
client = injector.getInstance(EC2Client.class);
|
client = injector.getInstance(EC2Client.class);
|
||||||
sshFactory = injector.getInstance(SshClient.Factory.class);
|
sshFactory = injector.getInstance(SshClient.Factory.class);
|
||||||
SocketOpen socketOpen = injector.getInstance(SocketOpen.class);
|
SocketOpen socketOpen = injector.getInstance(SocketOpen.class);
|
||||||
socketTester = new RetryablePredicate<IPSocket>(socketOpen, 120, 1, TimeUnit.SECONDS);
|
socketTester = new RetryablePredicate<IPSocket>(socketOpen, 120, 1,
|
||||||
|
|
||||||
VolumeAvailable volumeAvailable = injector.getInstance(VolumeAvailable.class);
|
|
||||||
volumeTester = new RetryablePredicate<Volume>(volumeAvailable, 60, 1, TimeUnit.SECONDS);
|
|
||||||
|
|
||||||
SnapshotCompleted snapshotCompleted = injector.getInstance(SnapshotCompleted.class);
|
|
||||||
snapshotTester = new RetryablePredicate<Snapshot>(snapshotCompleted, 120, 3, TimeUnit.SECONDS);
|
|
||||||
|
|
||||||
VolumeAttached volumeAttached = injector.getInstance(VolumeAttached.class);
|
|
||||||
attachTester = new RetryablePredicate<Attachment>(volumeAttached, 60, 1, TimeUnit.SECONDS);
|
|
||||||
|
|
||||||
runningTester = new RetryablePredicate<RunningInstance>(new InstanceStateRunning(client),
|
|
||||||
180, 5, TimeUnit.SECONDS);
|
|
||||||
|
|
||||||
InstanceStateStopped instanceStateStopped = injector.getInstance(InstanceStateStopped.class);
|
|
||||||
stoppedTester = new RetryablePredicate<RunningInstance>(instanceStateStopped, 60, 1,
|
|
||||||
TimeUnit.SECONDS);
|
TimeUnit.SECONDS);
|
||||||
|
|
||||||
|
VolumeAvailable volumeAvailable = injector
|
||||||
|
.getInstance(VolumeAvailable.class);
|
||||||
|
volumeTester = new RetryablePredicate<Volume>(volumeAvailable, 60, 1,
|
||||||
|
TimeUnit.SECONDS);
|
||||||
|
|
||||||
|
SnapshotCompleted snapshotCompleted = injector
|
||||||
|
.getInstance(SnapshotCompleted.class);
|
||||||
|
snapshotTester = new RetryablePredicate<Snapshot>(snapshotCompleted, 120,
|
||||||
|
3, TimeUnit.SECONDS);
|
||||||
|
|
||||||
|
VolumeAttached volumeAttached = injector
|
||||||
|
.getInstance(VolumeAttached.class);
|
||||||
|
attachTester = new RetryablePredicate<Attachment>(volumeAttached, 60, 1,
|
||||||
|
TimeUnit.SECONDS);
|
||||||
|
|
||||||
|
runningTester = new RetryablePredicate<RunningInstance>(
|
||||||
|
new InstanceStateRunning(client), 180, 5, TimeUnit.SECONDS);
|
||||||
|
|
||||||
|
InstanceStateStopped instanceStateStopped = injector
|
||||||
|
.getInstance(InstanceStateStopped.class);
|
||||||
|
stoppedTester = new RetryablePredicate<RunningInstance>(
|
||||||
|
instanceStateStopped, 60, 1, TimeUnit.SECONDS);
|
||||||
|
|
||||||
InstanceStateTerminated instanceStateTerminated = injector
|
InstanceStateTerminated instanceStateTerminated = injector
|
||||||
.getInstance(InstanceStateTerminated.class);
|
.getInstance(InstanceStateTerminated.class);
|
||||||
terminatedTester = new RetryablePredicate<RunningInstance>(instanceStateTerminated, 60, 1,
|
terminatedTester = new RetryablePredicate<RunningInstance>(
|
||||||
TimeUnit.SECONDS);
|
instanceStateTerminated, 60, 1, TimeUnit.SECONDS);
|
||||||
|
|
||||||
injector.injectMembers(socketOpen); // add logger
|
injector.injectMembers(socketOpen); // add logger
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(enabled = false)
|
@Test(enabled = false)
|
||||||
void testCreateSecurityGroupIngressCidr() throws InterruptedException, ExecutionException,
|
void testCreateSecurityGroupIngressCidr() throws InterruptedException,
|
||||||
TimeoutException {
|
ExecutionException, TimeoutException {
|
||||||
securityGroupName = INSTANCE_PREFIX + "ingress";
|
securityGroupName = INSTANCE_PREFIX + "ingress";
|
||||||
|
|
||||||
try {
|
try {
|
||||||
client.getSecurityGroupServices().deleteSecurityGroupInRegion(null, securityGroupName);
|
client.getSecurityGroupServices().deleteSecurityGroupInRegion(null,
|
||||||
|
securityGroupName);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
client.getSecurityGroupServices().createSecurityGroupInRegion(null, securityGroupName,
|
client.getSecurityGroupServices().createSecurityGroupInRegion(null,
|
||||||
securityGroupName);
|
securityGroupName, securityGroupName);
|
||||||
client.getSecurityGroupServices().authorizeSecurityGroupIngressInRegion(null,
|
client.getSecurityGroupServices().authorizeSecurityGroupIngressInRegion(
|
||||||
securityGroupName, IpProtocol.TCP, 80, 80, "0.0.0.0/0");
|
null, securityGroupName, IpProtocol.TCP, 80, 80, "0.0.0.0/0");
|
||||||
client.getSecurityGroupServices().authorizeSecurityGroupIngressInRegion(null,
|
client.getSecurityGroupServices().authorizeSecurityGroupIngressInRegion(
|
||||||
securityGroupName, IpProtocol.TCP, 443, 443, "0.0.0.0/0");
|
null, securityGroupName, IpProtocol.TCP, 443, 443, "0.0.0.0/0");
|
||||||
client.getSecurityGroupServices().authorizeSecurityGroupIngressInRegion(null,
|
client.getSecurityGroupServices().authorizeSecurityGroupIngressInRegion(
|
||||||
securityGroupName, IpProtocol.TCP, 22, 22, "0.0.0.0/0");
|
null, securityGroupName, IpProtocol.TCP, 22, 22, "0.0.0.0/0");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(enabled = false)
|
@Test(enabled = false)
|
||||||
|
@ -180,7 +194,8 @@ public class EBSBootEC2ClientLiveTest {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
keyPair = client.getKeyPairServices().createKeyPairInRegion(null, keyName);
|
keyPair = client.getKeyPairServices()
|
||||||
|
.createKeyPairInRegion(null, keyName);
|
||||||
assertNotNull(keyPair);
|
assertNotNull(keyPair);
|
||||||
assertNotNull(keyPair.getKeyMaterial());
|
assertNotNull(keyPair.getKeyMaterial());
|
||||||
assertNotNull(keyPair.getKeyFingerprint());
|
assertNotNull(keyPair.getKeyFingerprint());
|
||||||
|
@ -193,12 +208,15 @@ public class EBSBootEC2ClientLiveTest {
|
||||||
instance = createInstance(IMAGE_ID);
|
instance = createInstance(IMAGE_ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
private RunningInstance createInstance(String imageId) throws UnknownHostException {
|
private RunningInstance createInstance(String imageId)
|
||||||
|
throws UnknownHostException {
|
||||||
RunningInstance instance = null;
|
RunningInstance instance = null;
|
||||||
while (instance == null) {
|
while (instance == null) {
|
||||||
try {
|
try {
|
||||||
System.out.printf("%d: running instance%n", System.currentTimeMillis());
|
System.out.printf("%d: running instance%n", System
|
||||||
Reservation reservation = client.getInstanceServices().runInstancesInRegion(null, null, // allow
|
.currentTimeMillis());
|
||||||
|
Reservation reservation = client.getInstanceServices()
|
||||||
|
.runInstancesInRegion(null, null, // allow
|
||||||
// ec2
|
// ec2
|
||||||
// to
|
// to
|
||||||
// chose
|
// chose
|
||||||
|
@ -208,8 +226,11 @@ public class EBSBootEC2ClientLiveTest {
|
||||||
imageId, 1, // minimum instances
|
imageId, 1, // minimum instances
|
||||||
1, // maximum instances
|
1, // maximum instances
|
||||||
withKeyName(keyPair.getKeyName())// key I created above
|
withKeyName(keyPair.getKeyName())// key I created above
|
||||||
.asType(InstanceType.M1_SMALL)// smallest instance size
|
.asType(InstanceType.M1_SMALL)// smallest instance
|
||||||
.withSecurityGroup(securityGroupName));// group I created above
|
// size
|
||||||
|
.withSecurityGroup(securityGroupName));// group I
|
||||||
|
// created
|
||||||
|
// above
|
||||||
instance = Iterables.getOnlyElement(reservation);
|
instance = Iterables.getOnlyElement(reservation);
|
||||||
} catch (HttpResponseException htpe) {
|
} catch (HttpResponseException htpe) {
|
||||||
if (htpe.getResponse().getStatusCode() == 400)
|
if (htpe.getResponse().getStatusCode() == 400)
|
||||||
|
@ -225,25 +246,28 @@ public class EBSBootEC2ClientLiveTest {
|
||||||
|
|
||||||
@Test(enabled = false, dependsOnMethods = "testCreateRunningInstance")
|
@Test(enabled = false, dependsOnMethods = "testCreateRunningInstance")
|
||||||
void testCreateAndAttachVolume() {
|
void testCreateAndAttachVolume() {
|
||||||
volume = client.getElasticBlockStoreServices().createVolumeInAvailabilityZone(
|
volume = client.getElasticBlockStoreServices()
|
||||||
instance.getAvailabilityZone(), VOLUME_SIZE);
|
.createVolumeInAvailabilityZone(instance.getAvailabilityZone(),
|
||||||
System.out.printf("%d: %s awaiting volume to become available%n", System.currentTimeMillis(),
|
VOLUME_SIZE);
|
||||||
volume.getId());
|
System.out.printf("%d: %s awaiting volume to become available%n", System
|
||||||
|
.currentTimeMillis(), volume.getId());
|
||||||
|
|
||||||
assert volumeTester.apply(volume);
|
assert volumeTester.apply(volume);
|
||||||
|
|
||||||
Attachment attachment = client.getElasticBlockStoreServices().attachVolumeInRegion(
|
Attachment attachment = client.getElasticBlockStoreServices()
|
||||||
instance.getRegion(), volume.getId(), instance.getId(), "/dev/sdh");
|
.attachVolumeInRegion(instance.getRegion(), volume.getId(),
|
||||||
|
instance.getId(), "/dev/sdh");
|
||||||
|
|
||||||
System.out.printf("%d: %s awaiting attachment to complete%n", System.currentTimeMillis(),
|
System.out.printf("%d: %s awaiting attachment to complete%n", System
|
||||||
attachment.getId());
|
.currentTimeMillis(), attachment.getId());
|
||||||
|
|
||||||
assert attachTester.apply(attachment);
|
assert attachTester.apply(attachment);
|
||||||
System.out.printf("%d: %s attachment complete%n", System.currentTimeMillis(), attachment
|
System.out.printf("%d: %s attachment complete%n", System
|
||||||
.getId());
|
.currentTimeMillis(), attachment.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO use userData to do this, and make initbuilder an example for something else.
|
// TODO use userData to do this, and make initbuilder an example for
|
||||||
|
// something else.
|
||||||
@BeforeTest
|
@BeforeTest
|
||||||
void makeScript() {
|
void makeScript() {
|
||||||
|
|
||||||
|
@ -251,9 +275,11 @@ public class EBSBootEC2ClientLiveTest {
|
||||||
"mkebsboot",// name of the script
|
"mkebsboot",// name of the script
|
||||||
"/tmp",// working directory
|
"/tmp",// working directory
|
||||||
"/tmp/logs",// location of stdout.log and stderr.log
|
"/tmp/logs",// location of stdout.log and stderr.log
|
||||||
ImmutableMap.of("imageDir", "/mnt/tmp", "ebsDevice", "/dev/sdh", "ebsMountPoint",
|
ImmutableMap.of("imageDir", "/mnt/tmp", "ebsDevice", "/dev/sdh",
|
||||||
"/mnt/ebs"),// variables used inside of the script
|
"ebsMountPoint", "/mnt/ebs"),// variables used inside of the
|
||||||
"echo creating a filesystem and mounting the ebs volume",// what to execute
|
// script
|
||||||
|
"echo creating a filesystem and mounting the ebs volume",// what to
|
||||||
|
// execute
|
||||||
"{md} {varl}IMAGE_DIR{varr} {varl}EBS_MOUNT_POINT{varr}",
|
"{md} {varl}IMAGE_DIR{varr} {varl}EBS_MOUNT_POINT{varr}",
|
||||||
"rm -rf {varl}IMAGE_DIR{varr}/*",
|
"rm -rf {varl}IMAGE_DIR{varr}/*",
|
||||||
"yes| mkfs -t ext3 {varl}EBS_DEVICE{varr} 2>&-",
|
"yes| mkfs -t ext3 {varl}EBS_DEVICE{varr} 2>&-",
|
||||||
|
@ -264,16 +290,18 @@ public class EBSBootEC2ClientLiveTest {
|
||||||
"touch {varl}IMAGE_DIR{varr}/etc/init.d/ec2-init-user-data",
|
"touch {varl}IMAGE_DIR{varr}/etc/init.d/ec2-init-user-data",
|
||||||
"echo copying the local working copy to the ebs mount",
|
"echo copying the local working copy to the ebs mount",
|
||||||
"{cd} {varl}IMAGE_DIR{varr}",
|
"{cd} {varl}IMAGE_DIR{varr}",
|
||||||
"tar -cSf - * | tar xf - -C {varl}EBS_MOUNT_POINT{varr}", "echo size of ebs",
|
"tar -cSf - * | tar xf - -C {varl}EBS_MOUNT_POINT{varr}",
|
||||||
"du -sk {varl}EBS_MOUNT_POINT{varr}", "echo size of source",
|
"echo size of ebs", "du -sk {varl}EBS_MOUNT_POINT{varr}",
|
||||||
"du -sk {varl}IMAGE_DIR{varr}", "rm -rf {varl}IMAGE_DIR{varr}/*",
|
"echo size of source", "du -sk {varl}IMAGE_DIR{varr}",
|
||||||
"umount {varl}EBS_MOUNT_POINT{varr}", "echo " + SCRIPT_END).build(OsFamily.UNIX);
|
"rm -rf {varl}IMAGE_DIR{varr}/*",
|
||||||
|
"umount {varl}EBS_MOUNT_POINT{varr}", "echo " + SCRIPT_END)
|
||||||
|
.build(OsFamily.UNIX);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(enabled = false, dependsOnMethods = "testCreateAndAttachVolume")
|
@Test(enabled = false, dependsOnMethods = "testCreateAndAttachVolume")
|
||||||
void testBundleInstance() {
|
void testBundleInstance() {
|
||||||
SshClient ssh = sshFactory.create(new IPSocket(instance.getIpAddress(), 22), "ubuntu",
|
SshClient ssh = sshFactory.create(new IPSocket(instance.getIpAddress(),
|
||||||
keyPair.getKeyMaterial().getBytes());
|
22), "ubuntu", keyPair.getKeyMaterial().getBytes());
|
||||||
try {
|
try {
|
||||||
ssh.connect();
|
ssh.connect();
|
||||||
} catch (SshException e) {// try twice in case there is a network timeout
|
} catch (SshException e) {// try twice in case there is a network timeout
|
||||||
|
@ -284,13 +312,13 @@ public class EBSBootEC2ClientLiveTest {
|
||||||
ssh.connect();
|
ssh.connect();
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
System.out.printf("%d: %s writing ebs script%n", System.currentTimeMillis(), instance
|
System.out.printf("%d: %s writing ebs script%n", System
|
||||||
.getId());
|
.currentTimeMillis(), instance.getId());
|
||||||
String script = "/tmp/mkebsboot-init.sh";
|
String script = "/tmp/mkebsboot-init.sh";
|
||||||
ssh.put(script, new ByteArrayInputStream(mkEbsBoot.getBytes()));
|
ssh.put(script, new ByteArrayInputStream(mkEbsBoot.getBytes()));
|
||||||
|
|
||||||
System.out.printf("%d: %s launching ebs script%n", System.currentTimeMillis(), instance
|
System.out.printf("%d: %s launching ebs script%n", System
|
||||||
.getId());
|
.currentTimeMillis(), instance.getId());
|
||||||
ssh.exec("chmod 755 " + script);
|
ssh.exec("chmod 755 " + script);
|
||||||
ssh.exec(script + " init");
|
ssh.exec(script + " init");
|
||||||
ExecResponse output = ssh.exec("sudo " + script + " start");
|
ExecResponse output = ssh.exec("sudo " + script + " start");
|
||||||
|
@ -299,8 +327,8 @@ public class EBSBootEC2ClientLiveTest {
|
||||||
|
|
||||||
assert !output.getOutput().trim().equals("") : output;
|
assert !output.getOutput().trim().equals("") : output;
|
||||||
|
|
||||||
RetryablePredicate<String> scriptTester = new RetryablePredicate<String>(new ScriptTester(
|
RetryablePredicate<String> scriptTester = new RetryablePredicate<String>(
|
||||||
ssh, SCRIPT_END), 600, 10, TimeUnit.SECONDS);
|
new ScriptTester(ssh, SCRIPT_END), 600, 10, TimeUnit.SECONDS);
|
||||||
scriptTester.apply(script);
|
scriptTester.apply(script);
|
||||||
} finally {
|
} finally {
|
||||||
if (ssh != null)
|
if (ssh != null)
|
||||||
|
@ -319,7 +347,8 @@ public class EBSBootEC2ClientLiveTest {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(String script) {
|
public boolean apply(String script) {
|
||||||
System.out.printf("%d: %s testing status%n", System.currentTimeMillis(), script);
|
System.out.printf("%d: %s testing status%n", System
|
||||||
|
.currentTimeMillis(), script);
|
||||||
ExecResponse output = ssh.exec(script + " status");
|
ExecResponse output = ssh.exec(script + " status");
|
||||||
if (output.getOutput().trim().equals("")) {
|
if (output.getOutput().trim().equals("")) {
|
||||||
output = ssh.exec(script + " tail");
|
output = ssh.exec(script + " tail");
|
||||||
|
@ -329,7 +358,9 @@ public class EBSBootEC2ClientLiveTest {
|
||||||
} else {
|
} else {
|
||||||
output = ssh.exec(script + " tailerr");
|
output = ssh.exec(script + " tailerr");
|
||||||
String stderr = output.getOutput().trim();
|
String stderr = output.getOutput().trim();
|
||||||
throw new RuntimeException(String.format(
|
throw new RuntimeException(
|
||||||
|
String
|
||||||
|
.format(
|
||||||
"script %s ended without token: stdout.log: [%s]; stderr.log: [%s]; ",
|
"script %s ended without token: stdout.log: [%s]; stderr.log: [%s]; ",
|
||||||
script, stdout, stderr));
|
script, stdout, stderr));
|
||||||
}
|
}
|
||||||
|
@ -345,42 +376,49 @@ public class EBSBootEC2ClientLiveTest {
|
||||||
.describeVolumesInRegion(volume.getRegion(), volume.getId()));
|
.describeVolumesInRegion(volume.getRegion(), volume.getId()));
|
||||||
if (volume.getAttachments().size() > 0) {
|
if (volume.getAttachments().size() > 0) {
|
||||||
// should be cleanly unmounted, so force is not necessary.
|
// should be cleanly unmounted, so force is not necessary.
|
||||||
client.getElasticBlockStoreServices().detachVolumeInRegion(instance.getRegion(),
|
client.getElasticBlockStoreServices().detachVolumeInRegion(
|
||||||
volume.getId(), false);
|
instance.getRegion(), volume.getId(), false);
|
||||||
System.out.printf("%d: %s awaiting detachment to complete%n", System.currentTimeMillis(),
|
System.out.printf("%d: %s awaiting detachment to complete%n", System
|
||||||
volume.getId());
|
.currentTimeMillis(), volume.getId());
|
||||||
assert volumeTester.apply(volume);
|
assert volumeTester.apply(volume);
|
||||||
} else {
|
} else {
|
||||||
attachment = null; // protect test closer so that it doesn't try to detach
|
attachment = null; // protect test closer so that it doesn't try to
|
||||||
|
// detach
|
||||||
}
|
}
|
||||||
snapshot = client.getElasticBlockStoreServices().createSnapshotInRegion(volume.getRegion(),
|
snapshot = client.getElasticBlockStoreServices().createSnapshotInRegion(
|
||||||
volume.getId(), withDescription("EBS Ubuntu Hardy"));
|
volume.getRegion(), volume.getId(),
|
||||||
|
withDescription("EBS Ubuntu Hardy"));
|
||||||
|
|
||||||
System.out.printf("%d: %s awaiting snapshot to complete%n", System.currentTimeMillis(),
|
System.out.printf("%d: %s awaiting snapshot to complete%n", System
|
||||||
snapshot.getId());
|
.currentTimeMillis(), snapshot.getId());
|
||||||
|
|
||||||
assert snapshotTester.apply(snapshot);
|
assert snapshotTester.apply(snapshot);
|
||||||
Image image = Iterables.getOnlyElement(client.getAMIServices().describeImagesInRegion(
|
Image image = Iterables.getOnlyElement(client.getAMIServices()
|
||||||
snapshot.getRegion(), imageIds(IMAGE_ID)));
|
.describeImagesInRegion(snapshot.getRegion(), imageIds(IMAGE_ID)));
|
||||||
String description = image.getDescription() == null ? "jclouds" : image.getDescription();
|
String description = image.getDescription() == null ? "jclouds" : image
|
||||||
|
.getDescription();
|
||||||
|
|
||||||
System.out.printf("%d: %s creating ami from snapshot%n", System.currentTimeMillis(), snapshot
|
System.out.printf("%d: %s creating ami from snapshot%n", System
|
||||||
.getId());
|
.currentTimeMillis(), snapshot.getId());
|
||||||
|
|
||||||
String amiId = client.getAMIServices().registerUnixImageBackedByEbsInRegion(
|
String amiId = client.getAMIServices()
|
||||||
|
.registerUnixImageBackedByEbsInRegion(
|
||||||
snapshot.getRegion(),
|
snapshot.getRegion(),
|
||||||
"ebsboot-" + image.getId(),
|
"ebsboot-" + image.getId(),
|
||||||
snapshot.getId(),
|
snapshot.getId(),
|
||||||
withKernelId(image.getKernelId()).withRamdisk(image.getRamdiskId()).withDescription(
|
withKernelId(image.getKernelId()).withRamdisk(
|
||||||
description).asArchitecture(Architecture.I386));
|
image.getRamdiskId()).withDescription(description)
|
||||||
|
.asArchitecture(Architecture.I386));
|
||||||
try {
|
try {
|
||||||
ebsImage = Iterables.getOnlyElement(client.getAMIServices().describeImagesInRegion(
|
ebsImage = Iterables.getOnlyElement(client.getAMIServices()
|
||||||
snapshot.getRegion(), imageIds(amiId)));
|
.describeImagesInRegion(snapshot.getRegion(), imageIds(amiId)));
|
||||||
} catch (AWSResponseException e) {
|
} catch (AWSResponseException e) {
|
||||||
// TODO add a retry handler for this HTTP code 400 and the below error
|
// TODO add a retry handler for this HTTP code 400 and the below error
|
||||||
if (e.getError().getClass().equals("InvalidAMIID.NotFound"))
|
if (e.getError().getClass().equals("InvalidAMIID.NotFound"))
|
||||||
ebsImage = Iterables.getOnlyElement(client.getAMIServices().describeImagesInRegion(
|
ebsImage = Iterables
|
||||||
snapshot.getRegion(), imageIds(amiId)));
|
.getOnlyElement(client.getAMIServices()
|
||||||
|
.describeImagesInRegion(snapshot.getRegion(),
|
||||||
|
imageIds(amiId)));
|
||||||
else
|
else
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
@ -389,22 +427,22 @@ public class EBSBootEC2ClientLiveTest {
|
||||||
|
|
||||||
@Test(enabled = false, dependsOnMethods = { "testAMIFromBundle" })
|
@Test(enabled = false, dependsOnMethods = { "testAMIFromBundle" })
|
||||||
public void testInstanceFromEBS() throws Exception {
|
public void testInstanceFromEBS() throws Exception {
|
||||||
System.out.printf("%d: %s creating instance from ebs-backed ami%n", System
|
System.out.printf("%d: %s creating instance from ebs-backed ami%n",
|
||||||
.currentTimeMillis(), ebsImage.getId());
|
System.currentTimeMillis(), ebsImage.getId());
|
||||||
|
|
||||||
ebsInstance = createInstance(ebsImage.getId());
|
ebsInstance = createInstance(ebsImage.getId());
|
||||||
|
|
||||||
client.getInstanceServices().stopInstancesInRegion(ebsInstance.getRegion(), true,
|
client.getInstanceServices().stopInstancesInRegion(
|
||||||
ebsInstance.getId());
|
ebsInstance.getRegion(), true, ebsInstance.getId());
|
||||||
|
|
||||||
System.out.printf("%d: %s awaiting instance to stop %n", System.currentTimeMillis(),
|
System.out.printf("%d: %s awaiting instance to stop %n", System
|
||||||
ebsInstance.getId());
|
.currentTimeMillis(), ebsInstance.getId());
|
||||||
stoppedTester.apply(ebsInstance);
|
stoppedTester.apply(ebsInstance);
|
||||||
tryToChangeStuff();
|
tryToChangeStuff();
|
||||||
System.out.printf("%d: %s awaiting instance to start %n", System.currentTimeMillis(),
|
System.out.printf("%d: %s awaiting instance to start %n", System
|
||||||
ebsInstance.getId());
|
.currentTimeMillis(), ebsInstance.getId());
|
||||||
client.getInstanceServices().startInstancesInRegion(ebsInstance.getRegion(),
|
client.getInstanceServices().startInstancesInRegion(
|
||||||
ebsInstance.getId());
|
ebsInstance.getRegion(), ebsInstance.getId());
|
||||||
ebsInstance = blockUntilWeCanSshIntoInstance(ebsInstance);
|
ebsInstance = blockUntilWeCanSshIntoInstance(ebsInstance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -412,8 +450,10 @@ public class EBSBootEC2ClientLiveTest {
|
||||||
assertEquals(ebsImage.getImageType(), ImageType.MACHINE);
|
assertEquals(ebsImage.getImageType(), ImageType.MACHINE);
|
||||||
assertEquals(ebsImage.getRootDeviceType(), RootDeviceType.EBS);
|
assertEquals(ebsImage.getRootDeviceType(), RootDeviceType.EBS);
|
||||||
assertEquals(ebsImage.getRootDeviceName(), "/dev/sda1");
|
assertEquals(ebsImage.getRootDeviceName(), "/dev/sda1");
|
||||||
assertEquals(ebsImage.getEbsBlockDevices().entrySet(), ImmutableMap.of("/dev/sda1",
|
assertEquals(ebsImage.getEbsBlockDevices().entrySet(), ImmutableMap.of(
|
||||||
new Image.EbsBlockDevice(snapshot.getId(), VOLUME_SIZE, true)).entrySet());
|
"/dev/sda1",
|
||||||
|
new Image.EbsBlockDevice(snapshot.getId(), VOLUME_SIZE, true))
|
||||||
|
.entrySet());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void tryToChangeStuff() {
|
private void tryToChangeStuff() {
|
||||||
|
@ -426,56 +466,59 @@ public class EBSBootEC2ClientLiveTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setUserDataForInstanceInRegion() {
|
private void setUserDataForInstanceInRegion() {
|
||||||
client.getInstanceServices().setUserDataForInstanceInRegion(null, ebsInstance.getId(),
|
client.getInstanceServices().setUserDataForInstanceInRegion(null,
|
||||||
"test".getBytes());
|
ebsInstance.getId(), "test".getBytes());
|
||||||
assertEquals("test", client.getInstanceServices().getUserDataForInstanceInRegion(null,
|
assertEquals("test", client.getInstanceServices()
|
||||||
ebsInstance.getId()));
|
.getUserDataForInstanceInRegion(null, ebsInstance.getId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setRamdiskForInstanceInRegion() {
|
private void setRamdiskForInstanceInRegion() {
|
||||||
String ramdisk = client.getInstanceServices().getRamdiskForInstanceInRegion(null,
|
String ramdisk = client.getInstanceServices()
|
||||||
ebsInstance.getId());
|
.getRamdiskForInstanceInRegion(null, ebsInstance.getId());
|
||||||
client.getInstanceServices()
|
client.getInstanceServices().setRamdiskForInstanceInRegion(null,
|
||||||
.setRamdiskForInstanceInRegion(null, ebsInstance.getId(), ramdisk);
|
ebsInstance.getId(), ramdisk);
|
||||||
assertEquals(ramdisk, client.getInstanceServices().getRamdiskForInstanceInRegion(null,
|
assertEquals(ramdisk, client.getInstanceServices()
|
||||||
ebsInstance.getId()));
|
.getRamdiskForInstanceInRegion(null, ebsInstance.getId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setKernelForInstanceInRegion() {
|
private void setKernelForInstanceInRegion() {
|
||||||
String oldKernel = client.getInstanceServices().getKernelForInstanceInRegion(null,
|
String oldKernel = client.getInstanceServices()
|
||||||
ebsInstance.getId());
|
.getKernelForInstanceInRegion(null, ebsInstance.getId());
|
||||||
client.getInstanceServices().setKernelForInstanceInRegion(null, ebsInstance.getId(),
|
client.getInstanceServices().setKernelForInstanceInRegion(null,
|
||||||
oldKernel);
|
ebsInstance.getId(), oldKernel);
|
||||||
assertEquals(oldKernel, client.getInstanceServices().getKernelForInstanceInRegion(null,
|
assertEquals(oldKernel, client.getInstanceServices()
|
||||||
ebsInstance.getId()));
|
.getKernelForInstanceInRegion(null, ebsInstance.getId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setInstanceTypeForInstanceInRegion() {
|
private void setInstanceTypeForInstanceInRegion() {
|
||||||
client.getInstanceServices().setInstanceTypeForInstanceInRegion(null, ebsInstance.getId(),
|
client.getInstanceServices().setInstanceTypeForInstanceInRegion(null,
|
||||||
InstanceType.C1_MEDIUM);
|
ebsInstance.getId(), InstanceType.C1_MEDIUM);
|
||||||
assertEquals(InstanceType.C1_MEDIUM, client.getInstanceServices()
|
assertEquals(InstanceType.C1_MEDIUM, client.getInstanceServices()
|
||||||
.getInstanceTypeForInstanceInRegion(null, ebsInstance.getId()));
|
.getInstanceTypeForInstanceInRegion(null, ebsInstance.getId()));
|
||||||
client.getInstanceServices().setInstanceTypeForInstanceInRegion(null, ebsInstance.getId(),
|
client.getInstanceServices().setInstanceTypeForInstanceInRegion(null,
|
||||||
InstanceType.M1_SMALL);
|
ebsInstance.getId(), InstanceType.M1_SMALL);
|
||||||
assertEquals(InstanceType.M1_SMALL, client.getInstanceServices()
|
assertEquals(InstanceType.M1_SMALL, client.getInstanceServices()
|
||||||
.getInstanceTypeForInstanceInRegion(null, ebsInstance.getId()));
|
.getInstanceTypeForInstanceInRegion(null, ebsInstance.getId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setBlockDeviceMappingForInstanceInRegion() {
|
private void setBlockDeviceMappingForInstanceInRegion() {
|
||||||
String volumeId = ebsInstance.getEbsBlockDevices().get("/dev/sda1").getVolumeId();
|
String volumeId = ebsInstance.getEbsBlockDevices().get("/dev/sda1")
|
||||||
|
.getVolumeId();
|
||||||
|
|
||||||
BlockDeviceMapping blockDeviceMapping = new BlockDeviceMapping();
|
BlockDeviceMapping blockDeviceMapping = new BlockDeviceMapping();
|
||||||
blockDeviceMapping.addEbsBlockDevice("/dev/sda1", new RunningInstance.EbsBlockDevice(
|
blockDeviceMapping.addEbsBlockDevice("/dev/sda1",
|
||||||
volumeId, false));
|
new RunningInstance.EbsBlockDevice(volumeId, false));
|
||||||
try {
|
try {
|
||||||
client.getInstanceServices().setBlockDeviceMappingForInstanceInRegion(null,
|
client.getInstanceServices().setBlockDeviceMappingForInstanceInRegion(
|
||||||
ebsInstance.getId(), blockDeviceMapping);
|
null, ebsInstance.getId(), blockDeviceMapping);
|
||||||
|
|
||||||
Map<String, RunningInstance.EbsBlockDevice> devices = client.getInstanceServices()
|
Map<String, RunningInstance.EbsBlockDevice> devices = client
|
||||||
.getBlockDeviceMappingForInstanceInRegion(null, ebsInstance.getId());
|
.getInstanceServices().getBlockDeviceMappingForInstanceInRegion(
|
||||||
|
null, ebsInstance.getId());
|
||||||
assertEquals(devices.size(), 1);
|
assertEquals(devices.size(), 1);
|
||||||
String deviceName = Iterables.getOnlyElement(devices.keySet());
|
String deviceName = Iterables.getOnlyElement(devices.keySet());
|
||||||
RunningInstance.EbsBlockDevice device = Iterables.getOnlyElement(devices.values());
|
RunningInstance.EbsBlockDevice device = Iterables
|
||||||
|
.getOnlyElement(devices.values());
|
||||||
|
|
||||||
assertEquals(device.getVolumeId(), volumeId);
|
assertEquals(device.getVolumeId(), volumeId);
|
||||||
assertEquals(deviceName, "/dev/sda1");
|
assertEquals(deviceName, "/dev/sda1");
|
||||||
|
@ -492,27 +535,36 @@ public class EBSBootEC2ClientLiveTest {
|
||||||
private void setInstanceInitiatedShutdownBehaviorForInstanceInRegion() {
|
private void setInstanceInitiatedShutdownBehaviorForInstanceInRegion() {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
client.getInstanceServices().setInstanceInitiatedShutdownBehaviorForInstanceInRegion(null,
|
client.getInstanceServices()
|
||||||
ebsInstance.getId(), InstanceInitiatedShutdownBehavior.STOP);
|
.setInstanceInitiatedShutdownBehaviorForInstanceInRegion(null,
|
||||||
|
ebsInstance.getId(),
|
||||||
|
InstanceInitiatedShutdownBehavior.STOP);
|
||||||
|
|
||||||
assertEquals(InstanceInitiatedShutdownBehavior.STOP, client.getInstanceServices()
|
assertEquals(InstanceInitiatedShutdownBehavior.STOP, client
|
||||||
|
.getInstanceServices()
|
||||||
.getInstanceInitiatedShutdownBehaviorForInstanceInRegion(null,
|
.getInstanceInitiatedShutdownBehaviorForInstanceInRegion(null,
|
||||||
ebsInstance.getId()));
|
ebsInstance.getId()));
|
||||||
client.getInstanceServices().setInstanceInitiatedShutdownBehaviorForInstanceInRegion(null,
|
client.getInstanceServices()
|
||||||
ebsInstance.getId(), InstanceInitiatedShutdownBehavior.TERMINATE);
|
.setInstanceInitiatedShutdownBehaviorForInstanceInRegion(null,
|
||||||
|
ebsInstance.getId(),
|
||||||
|
InstanceInitiatedShutdownBehavior.TERMINATE);
|
||||||
|
|
||||||
assertEquals(InstanceInitiatedShutdownBehavior.TERMINATE, client.getInstanceServices()
|
assertEquals(InstanceInitiatedShutdownBehavior.TERMINATE, client
|
||||||
|
.getInstanceServices()
|
||||||
.getInstanceInitiatedShutdownBehaviorForInstanceInRegion(null,
|
.getInstanceInitiatedShutdownBehaviorForInstanceInRegion(null,
|
||||||
ebsInstance.getId()));
|
ebsInstance.getId()));
|
||||||
System.out.println("OK: setInstanceInitiatedShutdownBehaviorForInstanceInRegion");
|
System.out
|
||||||
|
.println("OK: setInstanceInitiatedShutdownBehaviorForInstanceInRegion");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
System.err.println("setInstanceInitiatedShutdownBehaviorForInstanceInRegion");
|
System.err
|
||||||
|
.println("setInstanceInitiatedShutdownBehaviorForInstanceInRegion");
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* this tests "personality" as the file looked up was sent during instance creation
|
* this tests "personality" as the file looked up was sent during instance
|
||||||
|
* creation
|
||||||
*
|
*
|
||||||
* @throws UnknownHostException
|
* @throws UnknownHostException
|
||||||
*/
|
*/
|
||||||
|
@ -528,13 +580,14 @@ public class EBSBootEC2ClientLiveTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void doCheckKey(RunningInstance newDetails) throws UnknownHostException {
|
private void doCheckKey(RunningInstance newDetails)
|
||||||
|
throws UnknownHostException {
|
||||||
doCheckKey(newDetails.getIpAddress());
|
doCheckKey(newDetails.getIpAddress());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void doCheckKey(String address) {
|
private void doCheckKey(String address) {
|
||||||
SshClient ssh = sshFactory.create(new IPSocket(address, 22), "ubuntu", keyPair
|
SshClient ssh = sshFactory.create(new IPSocket(address, 22), "ubuntu",
|
||||||
.getKeyMaterial().getBytes());
|
keyPair.getKeyMaterial().getBytes());
|
||||||
try {
|
try {
|
||||||
ssh.connect();
|
ssh.connect();
|
||||||
ExecResponse hello = ssh.exec("echo hello");
|
ExecResponse hello = ssh.exec("echo hello");
|
||||||
|
@ -545,26 +598,32 @@ public class EBSBootEC2ClientLiveTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private RunningInstance blockUntilWeCanSshIntoInstance(RunningInstance instance)
|
private RunningInstance blockUntilWeCanSshIntoInstance(
|
||||||
throws UnknownHostException {
|
RunningInstance instance) throws UnknownHostException {
|
||||||
System.out.printf("%d: %s awaiting instance to run %n", System.currentTimeMillis(), instance
|
System.out.printf("%d: %s awaiting instance to run %n", System
|
||||||
.getId());
|
.currentTimeMillis(), instance.getId());
|
||||||
assert runningTester.apply(instance);
|
assert runningTester.apply(instance);
|
||||||
|
|
||||||
// search my account for the instance I just created
|
// search my account for the instance I just created
|
||||||
Set<Reservation> reservations = client.getInstanceServices().describeInstancesInRegion(
|
Set<Reservation> reservations = client.getInstanceServices()
|
||||||
instance.getRegion(), instance.getId()); // last parameter (ids) narrows the search
|
.describeInstancesInRegion(instance.getRegion(), instance.getId()); // last
|
||||||
|
// parameter
|
||||||
|
// (ids)
|
||||||
|
// narrows
|
||||||
|
// the
|
||||||
|
// search
|
||||||
|
|
||||||
instance = Iterables.getOnlyElement(Iterables.getOnlyElement(reservations));
|
instance = Iterables.getOnlyElement(Iterables
|
||||||
|
.getOnlyElement(reservations));
|
||||||
|
|
||||||
System.out.printf("%d: %s awaiting ssh service to start%n", System.currentTimeMillis(),
|
System.out.printf("%d: %s awaiting ssh service to start%n", System
|
||||||
instance.getIpAddress());
|
.currentTimeMillis(), instance.getIpAddress());
|
||||||
assert socketTester.apply(new IPSocket(instance.getIpAddress(), 22));
|
assert socketTester.apply(new IPSocket(instance.getIpAddress(), 22));
|
||||||
System.out.printf("%d: %s ssh service started%n", System.currentTimeMillis(), instance
|
System.out.printf("%d: %s ssh service started%n", System
|
||||||
.getDnsName());
|
.currentTimeMillis(), instance.getDnsName());
|
||||||
sshPing(instance);
|
sshPing(instance);
|
||||||
System.out.printf("%d: %s ssh connection made%n", System.currentTimeMillis(), instance
|
System.out.printf("%d: %s ssh connection made%n", System
|
||||||
.getId());
|
.currentTimeMillis(), instance.getId());
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -572,8 +631,8 @@ public class EBSBootEC2ClientLiveTest {
|
||||||
void cleanup() {
|
void cleanup() {
|
||||||
if (ebsInstance != null) {
|
if (ebsInstance != null) {
|
||||||
try {
|
try {
|
||||||
client.getInstanceServices().terminateInstancesInRegion(ebsInstance.getRegion(),
|
client.getInstanceServices().terminateInstancesInRegion(
|
||||||
ebsInstance.getId());
|
ebsInstance.getRegion(), ebsInstance.getId());
|
||||||
terminatedTester.apply(ebsInstance);
|
terminatedTester.apply(ebsInstance);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
@ -581,7 +640,8 @@ public class EBSBootEC2ClientLiveTest {
|
||||||
}
|
}
|
||||||
if (ebsImage != null) {
|
if (ebsImage != null) {
|
||||||
try {
|
try {
|
||||||
client.getAMIServices().deregisterImageInRegion(ebsImage.getRegion(), ebsImage.getId());
|
client.getAMIServices().deregisterImageInRegion(
|
||||||
|
ebsImage.getRegion(), ebsImage.getId());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
@ -589,16 +649,16 @@ public class EBSBootEC2ClientLiveTest {
|
||||||
|
|
||||||
if (snapshot != null) {
|
if (snapshot != null) {
|
||||||
try {
|
try {
|
||||||
client.getElasticBlockStoreServices().deleteSnapshotInRegion(snapshot.getRegion(),
|
client.getElasticBlockStoreServices().deleteSnapshotInRegion(
|
||||||
snapshot.getId());
|
snapshot.getRegion(), snapshot.getId());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (attachment != null) {
|
if (attachment != null) {
|
||||||
try {
|
try {
|
||||||
client.getElasticBlockStoreServices().detachVolumeInRegion(volume.getRegion(),
|
client.getElasticBlockStoreServices().detachVolumeInRegion(
|
||||||
volume.getId(), true);
|
volume.getRegion(), volume.getId(), true);
|
||||||
assert volumeTester.apply(volume);
|
assert volumeTester.apply(volume);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
@ -606,8 +666,8 @@ public class EBSBootEC2ClientLiveTest {
|
||||||
}
|
}
|
||||||
if (instance != null) {
|
if (instance != null) {
|
||||||
try {
|
try {
|
||||||
client.getInstanceServices().terminateInstancesInRegion(instance.getRegion(),
|
client.getInstanceServices().terminateInstancesInRegion(
|
||||||
instance.getId());
|
instance.getRegion(), instance.getId());
|
||||||
terminatedTester.apply(instance);
|
terminatedTester.apply(instance);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
@ -615,23 +675,24 @@ public class EBSBootEC2ClientLiveTest {
|
||||||
}
|
}
|
||||||
if (volume != null) {
|
if (volume != null) {
|
||||||
try {
|
try {
|
||||||
client.getElasticBlockStoreServices().deleteVolumeInRegion(volume.getRegion(),
|
client.getElasticBlockStoreServices().deleteVolumeInRegion(
|
||||||
volume.getId());
|
volume.getRegion(), volume.getId());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (keyPair != null) {
|
if (keyPair != null) {
|
||||||
try {
|
try {
|
||||||
client.getKeyPairServices().deleteKeyPairInRegion(keyPair.getRegion(),
|
client.getKeyPairServices().deleteKeyPairInRegion(
|
||||||
keyPair.getKeyName());
|
keyPair.getRegion(), keyPair.getKeyName());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (securityGroupName != null) {
|
if (securityGroupName != null) {
|
||||||
try {
|
try {
|
||||||
client.getSecurityGroupServices().deleteSecurityGroupInRegion(null, securityGroupName);
|
client.getSecurityGroupServices().deleteSecurityGroupInRegion(null,
|
||||||
|
securityGroupName);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,13 +63,15 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
||||||
@Test(enabled = true, dependsOnMethods = "testCorrectAuthException")
|
@Test(enabled = true, dependsOnMethods = "testCorrectAuthException")
|
||||||
public void testExtendedOptionsAndLogin() throws Exception {
|
public void testExtendedOptionsAndLogin() throws Exception {
|
||||||
SecurityGroupClient securityGroupClient = EC2Client.class.cast(
|
SecurityGroupClient securityGroupClient = EC2Client.class.cast(
|
||||||
context.getProviderSpecificContext().getApi()).getSecurityGroupServices();
|
context.getProviderSpecificContext().getApi())
|
||||||
|
.getSecurityGroupServices();
|
||||||
|
|
||||||
KeyPairClient keyPairClient = EC2Client.class.cast(
|
KeyPairClient keyPairClient = EC2Client.class.cast(
|
||||||
context.getProviderSpecificContext().getApi()).getKeyPairServices();
|
context.getProviderSpecificContext().getApi()).getKeyPairServices();
|
||||||
|
|
||||||
InstanceClient instanceClient = EC2Client.class.cast(
|
InstanceClient instanceClient = EC2Client.class.cast(
|
||||||
context.getProviderSpecificContext().getApi()).getInstanceServices();
|
context.getProviderSpecificContext().getApi())
|
||||||
|
.getInstanceServices();
|
||||||
|
|
||||||
String tag = this.tag + "optionsandlogin";
|
String tag = this.tag + "optionsandlogin";
|
||||||
|
|
||||||
|
@ -82,15 +84,17 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
||||||
try {
|
try {
|
||||||
cleanupExtendedStuff(securityGroupClient, keyPairClient, tag);
|
cleanupExtendedStuff(securityGroupClient, keyPairClient, tag);
|
||||||
|
|
||||||
// create a security group that allows ssh in so that our scripts later will work
|
// create a security group that allows ssh in so that our scripts later
|
||||||
|
// will work
|
||||||
securityGroupClient.createSecurityGroupInRegion(null, tag, tag);
|
securityGroupClient.createSecurityGroupInRegion(null, tag, tag);
|
||||||
securityGroupClient.authorizeSecurityGroupIngressInRegion(null, tag, IpProtocol.TCP, 22,
|
securityGroupClient.authorizeSecurityGroupIngressInRegion(null, tag,
|
||||||
22, "0.0.0.0/0");
|
IpProtocol.TCP, 22, 22, "0.0.0.0/0");
|
||||||
|
|
||||||
// create a keypair to pass in as well
|
// create a keypair to pass in as well
|
||||||
KeyPair result = keyPairClient.createKeyPairInRegion(null, tag);
|
KeyPair result = keyPairClient.createKeyPairInRegion(null, tag);
|
||||||
|
|
||||||
Set<? extends NodeMetadata> nodes = client.runNodesWithTag(tag, 1, options);
|
Set<? extends NodeMetadata> nodes = client.runNodesWithTag(tag, 1,
|
||||||
|
options);
|
||||||
NodeMetadata first = Iterables.get(nodes, 0);
|
NodeMetadata first = Iterables.get(nodes, 0);
|
||||||
assert first.getCredentials() != null : first;
|
assert first.getCredentials() != null : first;
|
||||||
assert first.getCredentials().account != null : first;
|
assert first.getCredentials().account != null : first;
|
||||||
|
@ -102,7 +106,8 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
||||||
assertEquals(instance.getKeyName(), tag);
|
assertEquals(instance.getKeyName(), tag);
|
||||||
|
|
||||||
// make sure we made our dummy group and also let in the user's group
|
// make sure we made our dummy group and also let in the user's group
|
||||||
assertEquals(instance.getGroupIds(), ImmutableSet.<String> of(tag, "jclouds#" + tag));
|
assertEquals(instance.getGroupIds(), ImmutableSet.<String> of(tag,
|
||||||
|
"jclouds#" + tag));
|
||||||
|
|
||||||
// make sure our dummy group has no rules
|
// make sure our dummy group has no rules
|
||||||
SecurityGroup group = Iterables.getOnlyElement(securityGroupClient
|
SecurityGroup group = Iterables.getOnlyElement(securityGroupClient
|
||||||
|
@ -110,15 +115,18 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
||||||
assert group.getIpPermissions().size() == 0 : group;
|
assert group.getIpPermissions().size() == 0 : group;
|
||||||
|
|
||||||
// try to run a script with the original keyPair
|
// try to run a script with the original keyPair
|
||||||
runScriptWithCreds(tag, first.getImage().getOsFamily(), new Credentials(first
|
runScriptWithCreds(tag, first.getImage().getOsFamily(),
|
||||||
.getCredentials().account, result.getKeyMaterial()));
|
new Credentials(first.getCredentials().account, result
|
||||||
|
.getKeyMaterial()));
|
||||||
|
|
||||||
} finally {
|
} finally {
|
||||||
client.destroyNodesMatching(NodePredicates.withTag(tag));
|
client.destroyNodesMatching(NodePredicates.withTag(tag));
|
||||||
if (startedId != null) {
|
if (startedId != null) {
|
||||||
// ensure we didn't delete these resources!
|
// ensure we didn't delete these resources!
|
||||||
assertEquals(keyPairClient.describeKeyPairsInRegion(null, tag).size(), 1);
|
assertEquals(keyPairClient.describeKeyPairsInRegion(null, tag)
|
||||||
assertEquals(securityGroupClient.describeSecurityGroupsInRegion(null, tag).size(), 1);
|
.size(), 1);
|
||||||
|
assertEquals(securityGroupClient.describeSecurityGroupsInRegion(
|
||||||
|
null, tag).size(), 1);
|
||||||
}
|
}
|
||||||
cleanupExtendedStuff(securityGroupClient, keyPairClient, tag);
|
cleanupExtendedStuff(securityGroupClient, keyPairClient, tag);
|
||||||
}
|
}
|
||||||
|
@ -127,13 +135,15 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
||||||
@Test(enabled = true, dependsOnMethods = "testCorrectAuthException")
|
@Test(enabled = true, dependsOnMethods = "testCorrectAuthException")
|
||||||
public void testExtendedOptionsNoKeyPair() throws Exception {
|
public void testExtendedOptionsNoKeyPair() throws Exception {
|
||||||
SecurityGroupClient securityGroupClient = EC2Client.class.cast(
|
SecurityGroupClient securityGroupClient = EC2Client.class.cast(
|
||||||
context.getProviderSpecificContext().getApi()).getSecurityGroupServices();
|
context.getProviderSpecificContext().getApi())
|
||||||
|
.getSecurityGroupServices();
|
||||||
|
|
||||||
KeyPairClient keyPairClient = EC2Client.class.cast(
|
KeyPairClient keyPairClient = EC2Client.class.cast(
|
||||||
context.getProviderSpecificContext().getApi()).getKeyPairServices();
|
context.getProviderSpecificContext().getApi()).getKeyPairServices();
|
||||||
|
|
||||||
InstanceClient instanceClient = EC2Client.class.cast(
|
InstanceClient instanceClient = EC2Client.class.cast(
|
||||||
context.getProviderSpecificContext().getApi()).getInstanceServices();
|
context.getProviderSpecificContext().getApi())
|
||||||
|
.getInstanceServices();
|
||||||
|
|
||||||
String tag = this.tag + "optionsnokey";
|
String tag = this.tag + "optionsnokey";
|
||||||
|
|
||||||
|
@ -149,7 +159,8 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
||||||
// create the security group
|
// create the security group
|
||||||
securityGroupClient.createSecurityGroupInRegion(null, tag, tag);
|
securityGroupClient.createSecurityGroupInRegion(null, tag, tag);
|
||||||
|
|
||||||
Set<? extends NodeMetadata> nodes = client.runNodesWithTag(tag, 1, options);
|
Set<? extends NodeMetadata> nodes = client.runNodesWithTag(tag, 1,
|
||||||
|
options);
|
||||||
Credentials creds = nodes.iterator().next().getCredentials();
|
Credentials creds = nodes.iterator().next().getCredentials();
|
||||||
assert creds == null;
|
assert creds == null;
|
||||||
|
|
||||||
|
@ -160,7 +171,8 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
||||||
assertEquals(instance.getKeyName(), null);
|
assertEquals(instance.getKeyName(), null);
|
||||||
|
|
||||||
// make sure we made our dummy group and also let in the user's group
|
// make sure we made our dummy group and also let in the user's group
|
||||||
assertEquals(instance.getGroupIds(), ImmutableSet.<String> of(tag, "jclouds#" + tag));
|
assertEquals(instance.getGroupIds(), ImmutableSet.<String> of(tag,
|
||||||
|
"jclouds#" + tag));
|
||||||
|
|
||||||
// make sure our dummy group has no rules
|
// make sure our dummy group has no rules
|
||||||
SecurityGroup group = Iterables.getOnlyElement(securityGroupClient
|
SecurityGroup group = Iterables.getOnlyElement(securityGroupClient
|
||||||
|
@ -171,14 +183,16 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
||||||
client.destroyNodesMatching(NodePredicates.withTag(tag));
|
client.destroyNodesMatching(NodePredicates.withTag(tag));
|
||||||
if (startedId != null) {
|
if (startedId != null) {
|
||||||
// ensure we didn't delete these resources!
|
// ensure we didn't delete these resources!
|
||||||
assertEquals(securityGroupClient.describeSecurityGroupsInRegion(null, tag).size(), 1);
|
assertEquals(securityGroupClient.describeSecurityGroupsInRegion(
|
||||||
|
null, tag).size(), 1);
|
||||||
}
|
}
|
||||||
cleanupExtendedStuff(securityGroupClient, keyPairClient, tag);
|
cleanupExtendedStuff(securityGroupClient, keyPairClient, tag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private RunningInstance getInstance(InstanceClient instanceClient, String id) {
|
private RunningInstance getInstance(InstanceClient instanceClient, String id) {
|
||||||
RunningInstance instance = Iterables.getOnlyElement(Iterables.getOnlyElement(instanceClient
|
RunningInstance instance = Iterables
|
||||||
|
.getOnlyElement(Iterables.getOnlyElement(instanceClient
|
||||||
.describeInstancesInRegion(null, id)));
|
.describeInstancesInRegion(null, id)));
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,7 @@ public class ImageParserTest extends BaseEC2HandlerTest {
|
||||||
InputStream is = getClass().getResourceAsStream("/ec2/alestic_canonical.xml");
|
InputStream is = getClass().getResourceAsStream("/ec2/alestic_canonical.xml");
|
||||||
|
|
||||||
Set<Image> result = parseImages(is);
|
Set<Image> result = parseImages(is);
|
||||||
assertEquals(result.size(), 6);
|
assertEquals(result.size(), 7);
|
||||||
|
|
||||||
ImageParser parser = new ImageParser(
|
ImageParser parser = new ImageParser(
|
||||||
new EC2PopulateDefaultLoginCredentialsForImageStrategy(), ImmutableSet
|
new EC2PopulateDefaultLoginCredentialsForImageStrategy(), ImmutableSet
|
||||||
|
@ -87,6 +87,9 @@ public class ImageParserTest extends BaseEC2HandlerTest {
|
||||||
"063491364108"));
|
"063491364108"));
|
||||||
assertEquals(alesticKarmic.getVersion(), "20090623");
|
assertEquals(alesticKarmic.getVersion(), "20090623");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
org.jclouds.compute.domain.Image ubuntuKarmic = parser.apply(Iterables.get(result, 2));
|
org.jclouds.compute.domain.Image ubuntuKarmic = parser.apply(Iterables.get(result, 2));
|
||||||
|
|
||||||
assertEquals(ubuntuKarmic.getArchitecture(), org.jclouds.compute.domain.Architecture.X86_32);
|
assertEquals(ubuntuKarmic.getArchitecture(), org.jclouds.compute.domain.Architecture.X86_32);
|
||||||
|
@ -120,8 +123,24 @@ public class ImageParserTest extends BaseEC2HandlerTest {
|
||||||
"063491364108"));
|
"063491364108"));
|
||||||
assertEquals(alesticHardy.getVersion(), "20080905");
|
assertEquals(alesticHardy.getVersion(), "20080905");
|
||||||
|
|
||||||
|
org.jclouds.compute.domain.Image ubuntuLucid = parser.apply(Iterables.get(result, 5));
|
||||||
|
|
||||||
|
assertEquals(ubuntuLucid.getArchitecture(), org.jclouds.compute.domain.Architecture.X86_32);
|
||||||
|
assertEquals(ubuntuLucid.getDescription(),
|
||||||
|
"ubuntu-images-us-west-1/ubuntu-lucid-10.04-i386-server-20100427.1.manifest.xml");
|
||||||
|
assertEquals(ubuntuLucid.getProviderId(), "ami-c597c680");
|
||||||
|
assertEquals(ubuntuLucid.getLocation(), defaultLocation);
|
||||||
|
assertEquals(ubuntuLucid.getName(), "10.04");
|
||||||
|
assertEquals(ubuntuLucid.getOsDescription(),
|
||||||
|
"ubuntu-images-us-west-1/ubuntu-lucid-10.04-i386-server-20100427.1.manifest.xml");
|
||||||
|
assertEquals(ubuntuLucid.getOsFamily(), OsFamily.UBUNTU);
|
||||||
|
assertEquals(ubuntuLucid.getUserMetadata(), ImmutableMap.<String, String> of("owner",
|
||||||
|
"099720109477"));
|
||||||
|
assertEquals(ubuntuLucid.getVersion(), "20100427.1");
|
||||||
|
|
||||||
|
|
||||||
// should skip kernel
|
// should skip kernel
|
||||||
assert parser.apply(Iterables.get(result, 5)) == null;
|
assert parser.apply(Iterables.get(result, 6)) == null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Location defaultLocation = new LocationImpl(LocationScope.REGION, "us-east-1",
|
private Location defaultLocation = new LocationImpl(LocationScope.REGION, "us-east-1",
|
||||||
|
|
|
@ -60,18 +60,20 @@ public class EC2RunNodesAndAddToSetStrategyTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testZoneAsALocation() {
|
public void testZoneAsALocation() {
|
||||||
assertRegionAndZoneForLocation(ZONE_AP_SOUTHEAST_1A, Region.AP_SOUTHEAST_1,
|
assertRegionAndZoneForLocation(ZONE_AP_SOUTHEAST_1A,
|
||||||
AvailabilityZone.AP_SOUTHEAST_1A);
|
Region.AP_SOUTHEAST_1, AvailabilityZone.AP_SOUTHEAST_1A);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRegionAsALocation() {
|
public void testRegionAsALocation() {
|
||||||
assertRegionAndZoneForLocation(REGION_AP_SOUTHEAST_1, Region.AP_SOUTHEAST_1, null);
|
assertRegionAndZoneForLocation(REGION_AP_SOUTHEAST_1,
|
||||||
|
Region.AP_SOUTHEAST_1, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
// // fixtures
|
// // fixtures
|
||||||
|
|
||||||
public static Iterable<NodeMetadata> containsNodeMetadata(final NodeMetadata in) {
|
public static Iterable<NodeMetadata> containsNodeMetadata(
|
||||||
|
final NodeMetadata in) {
|
||||||
reportMatcher(new IArgumentMatcher() {
|
reportMatcher(new IArgumentMatcher() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -90,7 +92,8 @@ public class EC2RunNodesAndAddToSetStrategyTest {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertRegionAndZoneForLocation(Location location, String region, String zone) {
|
private void assertRegionAndZoneForLocation(Location location,
|
||||||
|
String region, String zone) {
|
||||||
String imageId = "ami1";
|
String imageId = "ami1";
|
||||||
String instanceCreatedId = "instance1";
|
String instanceCreatedId = "instance1";
|
||||||
// setup mocks
|
// setup mocks
|
||||||
|
@ -99,31 +102,37 @@ public class EC2RunNodesAndAddToSetStrategyTest {
|
||||||
InstanceClient instanceClient = createMock(InstanceClient.class);
|
InstanceClient instanceClient = createMock(InstanceClient.class);
|
||||||
RunInstancesOptions ec2Options = createMock(RunInstancesOptions.class);
|
RunInstancesOptions ec2Options = createMock(RunInstancesOptions.class);
|
||||||
RunningInstance instance = createMock(RunningInstance.class);
|
RunningInstance instance = createMock(RunningInstance.class);
|
||||||
Reservation reservation = new Reservation(region, ImmutableSet.<String> of(), ImmutableSet
|
Reservation reservation = new Reservation(region, ImmutableSet
|
||||||
.<RunningInstance> of(instance), "ownerId", "requesterId", "reservationId");
|
.<String> of(), ImmutableSet.<RunningInstance> of(instance),
|
||||||
|
"ownerId", "requesterId", "reservationId");
|
||||||
NodeMetadata nodeMetadata = createMock(NodeMetadata.class);
|
NodeMetadata nodeMetadata = createMock(NodeMetadata.class);
|
||||||
|
|
||||||
// setup expectations
|
// setup expectations
|
||||||
expect(strategy.client.getInstanceServices()).andReturn(instanceClient).atLeastOnce();
|
expect(strategy.client.getInstanceServices()).andReturn(instanceClient)
|
||||||
|
.atLeastOnce();
|
||||||
expect(
|
expect(
|
||||||
strategy.createKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.execute(region,
|
strategy.createKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions
|
||||||
input.tag, input.template)).andReturn(ec2Options);
|
.execute(region, input.tag, input.template)).andReturn(
|
||||||
expect(input.template.getLocation()).andReturn(input.location).atLeastOnce();
|
ec2Options);
|
||||||
|
expect(input.template.getLocation()).andReturn(input.location)
|
||||||
|
.atLeastOnce();
|
||||||
expect(input.template.getImage()).andReturn(input.image).atLeastOnce();
|
expect(input.template.getImage()).andReturn(input.image).atLeastOnce();
|
||||||
expect(input.image.getProviderId()).andReturn(imageId).atLeastOnce();
|
expect(input.image.getProviderId()).andReturn(imageId).atLeastOnce();
|
||||||
expect(instanceClient.runInstancesInRegion(region, zone, imageId, 1, input.count, ec2Options))
|
|
||||||
.andReturn(reservation);
|
|
||||||
expect(instance.getId()).andReturn(instanceCreatedId).atLeastOnce();
|
|
||||||
expect(strategy.instanceStateRunning.apply(instance)).andReturn(true);
|
|
||||||
expect(instanceClient.describeInstancesInRegion(region, instanceCreatedId)).andReturn(
|
|
||||||
ImmutableSet.of(reservation));
|
|
||||||
expect(input.template.getOptions()).andReturn(input.options).atLeastOnce();
|
|
||||||
|
|
||||||
expect(strategy.runningInstanceToNodeMetadata.apply(instance)).andReturn(nodeMetadata);
|
|
||||||
expect(
|
expect(
|
||||||
strategy.utils.runOptionsOnNodesAndAddToGoodSetOrPutExceptionIntoBadMap(
|
instanceClient.runInstancesInRegion(region, zone, imageId, 1,
|
||||||
eq(input.options), containsNodeMetadata(nodeMetadata), eq(input.nodes),
|
input.count, ec2Options)).andReturn(reservation);
|
||||||
eq(input.badNodes))).andReturn(null);
|
expect(instance.getId()).andReturn(instanceCreatedId).atLeastOnce();
|
||||||
|
expect(strategy.instancePresent.apply(instance)).andReturn(true);
|
||||||
|
expect(input.template.getOptions()).andReturn(input.options)
|
||||||
|
.atLeastOnce();
|
||||||
|
|
||||||
|
expect(strategy.runningInstanceToNodeMetadata.apply(instance)).andReturn(
|
||||||
|
nodeMetadata);
|
||||||
|
expect(
|
||||||
|
strategy.utils
|
||||||
|
.runOptionsOnNodesAndAddToGoodSetOrPutExceptionIntoBadMap(
|
||||||
|
eq(input.options), containsNodeMetadata(nodeMetadata),
|
||||||
|
eq(input.nodes), eq(input.badNodes))).andReturn(null);
|
||||||
|
|
||||||
// replay mocks
|
// replay mocks
|
||||||
replay(instanceClient);
|
replay(instanceClient);
|
||||||
|
@ -134,7 +143,8 @@ public class EC2RunNodesAndAddToSetStrategyTest {
|
||||||
replayStrategy(strategy);
|
replayStrategy(strategy);
|
||||||
|
|
||||||
// run
|
// run
|
||||||
strategy.execute(input.tag, input.count, input.template, input.nodes, input.badNodes);
|
strategy.execute(input.tag, input.count, input.template, input.nodes,
|
||||||
|
input.badNodes);
|
||||||
|
|
||||||
// verify mocks
|
// verify mocks
|
||||||
verify(instanceClient);
|
verify(instanceClient);
|
||||||
|
@ -145,12 +155,12 @@ public class EC2RunNodesAndAddToSetStrategyTest {
|
||||||
verifyStrategy(strategy);
|
verifyStrategy(strategy);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final Location REGION_AP_SOUTHEAST_1 = new LocationImpl(LocationScope.REGION,
|
private static final Location REGION_AP_SOUTHEAST_1 = new LocationImpl(
|
||||||
Region.AP_SOUTHEAST_1, Region.AP_SOUTHEAST_1, new LocationImpl(LocationScope.PROVIDER,
|
LocationScope.REGION, Region.AP_SOUTHEAST_1, Region.AP_SOUTHEAST_1,
|
||||||
"ec2", "ec2", null));
|
new LocationImpl(LocationScope.PROVIDER, "ec2", "ec2", null));
|
||||||
private static final Location ZONE_AP_SOUTHEAST_1A = new LocationImpl(LocationScope.ZONE,
|
private static final Location ZONE_AP_SOUTHEAST_1A = new LocationImpl(
|
||||||
AvailabilityZone.AP_SOUTHEAST_1A, AvailabilityZone.AP_SOUTHEAST_1A,
|
LocationScope.ZONE, AvailabilityZone.AP_SOUTHEAST_1A,
|
||||||
REGION_AP_SOUTHEAST_1);
|
AvailabilityZone.AP_SOUTHEAST_1A, REGION_AP_SOUTHEAST_1);
|
||||||
|
|
||||||
// /////////////////////////////////////////////////////////////////////
|
// /////////////////////////////////////////////////////////////////////
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
|
@ -191,7 +201,7 @@ public class EC2RunNodesAndAddToSetStrategyTest {
|
||||||
private void verifyStrategy(EC2RunNodesAndAddToSetStrategy strategy) {
|
private void verifyStrategy(EC2RunNodesAndAddToSetStrategy strategy) {
|
||||||
verify(strategy.createKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions);
|
verify(strategy.createKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions);
|
||||||
verify(strategy.client);
|
verify(strategy.client);
|
||||||
verify(strategy.instanceStateRunning);
|
verify(strategy.instancePresent);
|
||||||
verify(strategy.runningInstanceToNodeMetadata);
|
verify(strategy.runningInstanceToNodeMetadata);
|
||||||
verify(strategy.utils);
|
verify(strategy.utils);
|
||||||
}
|
}
|
||||||
|
@ -204,14 +214,14 @@ public class EC2RunNodesAndAddToSetStrategyTest {
|
||||||
RunningInstanceToNodeMetadata runningInstanceToNodeMetadata = createMock(RunningInstanceToNodeMetadata.class);
|
RunningInstanceToNodeMetadata runningInstanceToNodeMetadata = createMock(RunningInstanceToNodeMetadata.class);
|
||||||
ComputeUtils utils = createMock(ComputeUtils.class);
|
ComputeUtils utils = createMock(ComputeUtils.class);
|
||||||
return new EC2RunNodesAndAddToSetStrategy(client,
|
return new EC2RunNodesAndAddToSetStrategy(client,
|
||||||
createKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions, instanceStateRunning,
|
createKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions,
|
||||||
runningInstanceToNodeMetadata, utils);
|
instanceStateRunning, runningInstanceToNodeMetadata, utils);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void replayStrategy(EC2RunNodesAndAddToSetStrategy strategy) {
|
private void replayStrategy(EC2RunNodesAndAddToSetStrategy strategy) {
|
||||||
replay(strategy.createKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions);
|
replay(strategy.createKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions);
|
||||||
replay(strategy.client);
|
replay(strategy.client);
|
||||||
replay(strategy.instanceStateRunning);
|
replay(strategy.instancePresent);
|
||||||
replay(strategy.runningInstanceToNodeMetadata);
|
replay(strategy.runningInstanceToNodeMetadata);
|
||||||
replay(strategy.utils);
|
replay(strategy.utils);
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,6 +67,19 @@
|
||||||
<rootDeviceType>instance-store</rootDeviceType>
|
<rootDeviceType>instance-store</rootDeviceType>
|
||||||
<blockDeviceMapping />
|
<blockDeviceMapping />
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<imageId>ami-c597c680</imageId>
|
||||||
|
<imageLocation>ubuntu-images-us-west-1/ubuntu-lucid-10.04-i386-server-20100427.1.manifest.xml</imageLocation>
|
||||||
|
<imageState>available</imageState>
|
||||||
|
<imageOwnerId>099720109477</imageOwnerId>
|
||||||
|
<isPublic>true</isPublic>
|
||||||
|
<architecture>i386</architecture>
|
||||||
|
<imageType>machine</imageType>
|
||||||
|
<kernelId>aki-3197c674</kernelId>
|
||||||
|
<name>ubuntu-images/ubuntu-lucid-10.04-i386-server-20100427.1</name>
|
||||||
|
<rootDeviceType>instance-store</rootDeviceType>
|
||||||
|
<blockDeviceMapping/>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<imageId>aki-fd15f694</imageId>
|
<imageId>aki-fd15f694</imageId>
|
||||||
<imageLocation>ubuntu-kernels-us/ubuntu-karmic-amd64-linux-image-2.6.31-302-ec2-v-2.6.31-302.7-kernel.img.manifest.xml</imageLocation>
|
<imageLocation>ubuntu-kernels-us/ubuntu-karmic-amd64-linux-image-2.6.31-302-ec2-v-2.6.31-302.7-kernel.img.manifest.xml</imageLocation>
|
||||||
|
|
|
@ -0,0 +1,88 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||||
|
*
|
||||||
|
* ====================================================================
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
* ====================================================================
|
||||||
|
*/
|
||||||
|
package org.jclouds.compute.config;
|
||||||
|
|
||||||
|
import static com.google.common.base.Predicates.not;
|
||||||
|
|
||||||
|
import javax.inject.Named;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import org.jclouds.compute.domain.NodeMetadata;
|
||||||
|
import org.jclouds.compute.predicates.NodeRunning;
|
||||||
|
import org.jclouds.compute.predicates.NodeTerminated;
|
||||||
|
import org.jclouds.compute.predicates.ScriptStatusReturnsZero;
|
||||||
|
import org.jclouds.compute.predicates.ScriptStatusReturnsZero.CommandUsingClient;
|
||||||
|
import org.jclouds.compute.reference.ComputeServiceConstants.Timeouts;
|
||||||
|
import org.jclouds.net.IPSocket;
|
||||||
|
import org.jclouds.predicates.RetryablePredicate;
|
||||||
|
import org.jclouds.predicates.SocketOpen;
|
||||||
|
|
||||||
|
import com.google.common.base.Predicate;
|
||||||
|
import com.google.inject.AbstractModule;
|
||||||
|
import com.google.inject.Provides;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ComputeServiceTimeoutsModule extends AbstractModule {
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
@Named("NODE_RUNNING")
|
||||||
|
protected Predicate<NodeMetadata> nodeRunning(NodeRunning stateRunning,
|
||||||
|
Timeouts timeouts) {
|
||||||
|
return timeouts.nodeRunning == 0 ? stateRunning
|
||||||
|
: new RetryablePredicate<NodeMetadata>(stateRunning,
|
||||||
|
timeouts.nodeRunning);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
@Named("NODE_TERMINATED")
|
||||||
|
protected Predicate<NodeMetadata> serverTerminated(
|
||||||
|
NodeTerminated stateTerminated, Timeouts timeouts) {
|
||||||
|
return timeouts.nodeTerminated == 0 ? stateTerminated
|
||||||
|
: new RetryablePredicate<NodeMetadata>(stateTerminated,
|
||||||
|
timeouts.nodeTerminated);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
@Named("SCRIPT_COMPLETE")
|
||||||
|
protected Predicate<CommandUsingClient> runScriptRunning(
|
||||||
|
ScriptStatusReturnsZero stateRunning, Timeouts timeouts) {
|
||||||
|
return timeouts.scriptComplete == 0 ? not(stateRunning)
|
||||||
|
: new RetryablePredicate<CommandUsingClient>(not(stateRunning),
|
||||||
|
timeouts.scriptComplete);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
protected Predicate<IPSocket> socketTester(SocketOpen open, Timeouts timeouts) {
|
||||||
|
return timeouts.portOpen == 0 ? open : new RetryablePredicate<IPSocket>(
|
||||||
|
open, timeouts.portOpen);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configure() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -32,8 +32,8 @@ import org.jclouds.domain.Credentials;
|
||||||
public interface NodeMetadata extends ComputeMetadata {
|
public interface NodeMetadata extends ComputeMetadata {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tag used for all resources that belong to the same logical group. run, destroy commands are
|
* Tag used for all resources that belong to the same logical group. run,
|
||||||
* scoped to tag.
|
* destroy commands are scoped to tag.
|
||||||
*
|
*
|
||||||
* @return tag for this node, or null, if not a part of a group
|
* @return tag for this node, or null, if not a part of a group
|
||||||
*
|
*
|
||||||
|
@ -62,8 +62,8 @@ public interface NodeMetadata extends ComputeMetadata {
|
||||||
Set<String> getPrivateAddresses();
|
Set<String> getPrivateAddresses();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If possible, these are returned upon all detail requests. However, it is often the case that
|
* If possible, these are returned upon all detail requests. However, it is
|
||||||
* credentials are only available at "run" time.
|
* often the case that credentials are only available at "run" time.
|
||||||
*/
|
*/
|
||||||
Credentials getCredentials();
|
Credentials getCredentials();
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,8 @@ import com.google.common.collect.Sets;
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
* @author Ivan Meredith
|
* @author Ivan Meredith
|
||||||
*/
|
*/
|
||||||
public class NodeMetadataImpl extends ComputeMetadataImpl implements NodeMetadata {
|
public class NodeMetadataImpl extends ComputeMetadataImpl implements
|
||||||
|
NodeMetadata {
|
||||||
/** The serialVersionUID */
|
/** The serialVersionUID */
|
||||||
private static final long serialVersionUID = 7924307572338157887L;
|
private static final long serialVersionUID = 7924307572338157887L;
|
||||||
|
|
||||||
|
@ -53,17 +54,19 @@ public class NodeMetadataImpl extends ComputeMetadataImpl implements NodeMetadat
|
||||||
private final String tag;
|
private final String tag;
|
||||||
private final Image image;
|
private final Image image;
|
||||||
|
|
||||||
public NodeMetadataImpl(String providerId, String name, String id, Location location, URI uri,
|
public NodeMetadataImpl(String providerId, String name, String id,
|
||||||
Map<String, String> userMetadata, @Nullable String tag, @Nullable Image image,
|
Location location, URI uri, Map<String, String> userMetadata,
|
||||||
NodeState state, Iterable<String> publicAddresses,
|
@Nullable String tag, @Nullable Image image, NodeState state,
|
||||||
Iterable<String> privateAddresses, Map<String, String> extra,
|
Iterable<String> publicAddresses, Iterable<String> privateAddresses,
|
||||||
@Nullable Credentials credentials) {
|
Map<String, String> extra, @Nullable Credentials credentials) {
|
||||||
super(ComputeType.NODE, providerId, name, id, location, uri, userMetadata);
|
super(ComputeType.NODE, providerId, name, id, location, uri, userMetadata);
|
||||||
this.tag = tag;
|
this.tag = tag;
|
||||||
this.image = image;
|
this.image = image;
|
||||||
this.state = checkNotNull(state, "state");
|
this.state = checkNotNull(state, "state");
|
||||||
Iterables.addAll(this.publicAddresses, checkNotNull(publicAddresses, "publicAddresses"));
|
Iterables.addAll(this.publicAddresses, checkNotNull(publicAddresses,
|
||||||
Iterables.addAll(this.privateAddresses, checkNotNull(privateAddresses, "privateAddresses"));
|
"publicAddresses"));
|
||||||
|
Iterables.addAll(this.privateAddresses, checkNotNull(privateAddresses,
|
||||||
|
"privateAddresses"));
|
||||||
this.extra.putAll(checkNotNull(extra, "extra"));
|
this.extra.putAll(checkNotNull(extra, "extra"));
|
||||||
this.credentials = credentials;
|
this.credentials = credentials;
|
||||||
}
|
}
|
||||||
|
@ -127,19 +130,22 @@ public class NodeMetadataImpl extends ComputeMetadataImpl implements NodeMetadat
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "[id=" + getId() + ", providerId=" + getProviderId() + ", tag=" + getTag() + ", name="
|
return "[id=" + getId() + ", providerId=" + getProviderId() + ", tag="
|
||||||
+ getName() + ", location=" + getLocation() + ", uri=" + getUri() + ", image="
|
+ getTag() + ", name=" + getName() + ", location=" + getLocation()
|
||||||
+ getImage() + ", userMetadata=" + getUserMetadata() + ", state=" + getState()
|
+ ", uri=" + getUri() + ", image=" + getImage() + ", userMetadata="
|
||||||
+ ", privateAddresses=" + privateAddresses + ", publicAddresses=" + publicAddresses
|
+ getUserMetadata() + ", state=" + getState()
|
||||||
+ ", extra=" + getExtra() + "]";
|
+ ", privateAddresses=" + privateAddresses + ", publicAddresses="
|
||||||
|
+ publicAddresses + ", extra=" + getExtra() + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
final int prime = 31;
|
final int prime = 31;
|
||||||
int result = super.hashCode();
|
int result = super.hashCode();
|
||||||
result = prime * result + ((privateAddresses == null) ? 0 : privateAddresses.hashCode());
|
result = prime * result
|
||||||
result = prime * result + ((publicAddresses == null) ? 0 : publicAddresses.hashCode());
|
+ ((privateAddresses == null) ? 0 : privateAddresses.hashCode());
|
||||||
|
result = prime * result
|
||||||
|
+ ((publicAddresses == null) ? 0 : publicAddresses.hashCode());
|
||||||
result = prime * result + ((tag == null) ? 0 : tag.hashCode());
|
result = prime * result + ((tag == null) ? 0 : tag.hashCode());
|
||||||
result = prime * result + ((image == null) ? 0 : image.hashCode());
|
result = prime * result + ((image == null) ? 0 : image.hashCode());
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -97,34 +97,47 @@ public class BaseComputeService implements ComputeService {
|
||||||
protected final DestroyNodeStrategy destroyNodeStrategy;
|
protected final DestroyNodeStrategy destroyNodeStrategy;
|
||||||
protected final Provider<TemplateBuilder> templateBuilderProvider;
|
protected final Provider<TemplateBuilder> templateBuilderProvider;
|
||||||
protected final Provider<TemplateOptions> templateOptionsProvider;
|
protected final Provider<TemplateOptions> templateOptionsProvider;
|
||||||
|
protected final Predicate<NodeMetadata> nodeRunning;
|
||||||
|
protected final Predicate<NodeMetadata> nodeTerminated;
|
||||||
protected final ComputeUtils utils;
|
protected final ComputeUtils utils;
|
||||||
protected final ExecutorService executor;
|
protected final ExecutorService executor;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
protected BaseComputeService(ComputeServiceContext context,
|
protected BaseComputeService(ComputeServiceContext context,
|
||||||
Provider<Set<? extends Image>> images, Provider<Set<? extends Size>> sizes,
|
Provider<Set<? extends Image>> images,
|
||||||
Provider<Set<? extends Location>> locations, ListNodesStrategy listNodesStrategy,
|
Provider<Set<? extends Size>> sizes,
|
||||||
|
Provider<Set<? extends Location>> locations,
|
||||||
|
ListNodesStrategy listNodesStrategy,
|
||||||
GetNodeMetadataStrategy getNodeMetadataStrategy,
|
GetNodeMetadataStrategy getNodeMetadataStrategy,
|
||||||
RunNodesAndAddToSetStrategy runNodesAndAddToSetStrategy,
|
RunNodesAndAddToSetStrategy runNodesAndAddToSetStrategy,
|
||||||
RebootNodeStrategy rebootNodeStrategy, DestroyNodeStrategy destroyNodeStrategy,
|
RebootNodeStrategy rebootNodeStrategy,
|
||||||
|
DestroyNodeStrategy destroyNodeStrategy,
|
||||||
Provider<TemplateBuilder> templateBuilderProvider,
|
Provider<TemplateBuilder> templateBuilderProvider,
|
||||||
Provider<TemplateOptions> templateOptionsProvider, ComputeUtils utils,
|
Provider<TemplateOptions> templateOptionsProvider,
|
||||||
|
@Named("NODE_RUNNING") Predicate<NodeMetadata> nodeRunning,
|
||||||
|
@Named("NODE_TERMINATED") Predicate<NodeMetadata> nodeTerminated,
|
||||||
|
ComputeUtils utils,
|
||||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) {
|
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) {
|
||||||
this.context = checkNotNull(context, "context");
|
this.context = checkNotNull(context, "context");
|
||||||
this.images = checkNotNull(images, "images");
|
this.images = checkNotNull(images, "images");
|
||||||
this.sizes = checkNotNull(sizes, "sizes");
|
this.sizes = checkNotNull(sizes, "sizes");
|
||||||
this.locations = checkNotNull(locations, "locations");
|
this.locations = checkNotNull(locations, "locations");
|
||||||
this.listNodesStrategy = checkNotNull(listNodesStrategy, "listNodesStrategy");
|
this.listNodesStrategy = checkNotNull(listNodesStrategy,
|
||||||
|
"listNodesStrategy");
|
||||||
this.getNodeMetadataStrategy = checkNotNull(getNodeMetadataStrategy,
|
this.getNodeMetadataStrategy = checkNotNull(getNodeMetadataStrategy,
|
||||||
"getNodeMetadataStrategy");
|
"getNodeMetadataStrategy");
|
||||||
this.runNodesAndAddToSetStrategy = checkNotNull(runNodesAndAddToSetStrategy,
|
this.runNodesAndAddToSetStrategy = checkNotNull(
|
||||||
"runNodesAndAddToSetStrategy");
|
runNodesAndAddToSetStrategy, "runNodesAndAddToSetStrategy");
|
||||||
this.rebootNodeStrategy = checkNotNull(rebootNodeStrategy, "rebootNodeStrategy");
|
this.rebootNodeStrategy = checkNotNull(rebootNodeStrategy,
|
||||||
this.destroyNodeStrategy = checkNotNull(destroyNodeStrategy, "destroyNodeStrategy");
|
"rebootNodeStrategy");
|
||||||
|
this.destroyNodeStrategy = checkNotNull(destroyNodeStrategy,
|
||||||
|
"destroyNodeStrategy");
|
||||||
this.templateBuilderProvider = checkNotNull(templateBuilderProvider,
|
this.templateBuilderProvider = checkNotNull(templateBuilderProvider,
|
||||||
"templateBuilderProvider");
|
"templateBuilderProvider");
|
||||||
this.templateOptionsProvider = checkNotNull(templateOptionsProvider,
|
this.templateOptionsProvider = checkNotNull(templateOptionsProvider,
|
||||||
"templateOptionsProvider");
|
"templateOptionsProvider");
|
||||||
|
this.nodeRunning = checkNotNull(nodeRunning, "nodeRunning");
|
||||||
|
this.nodeTerminated = checkNotNull(nodeTerminated, "nodeTerminated");
|
||||||
this.utils = checkNotNull(utils, "utils");
|
this.utils = checkNotNull(utils, "utils");
|
||||||
this.executor = checkNotNull(executor, "executor");
|
this.executor = checkNotNull(executor, "executor");
|
||||||
}
|
}
|
||||||
|
@ -141,22 +154,25 @@ public class BaseComputeService implements ComputeService {
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Set<? extends NodeMetadata> runNodesWithTag(String tag, int count, Template template)
|
public Set<? extends NodeMetadata> runNodesWithTag(String tag, int count,
|
||||||
throws RunNodesException {
|
Template template) throws RunNodesException {
|
||||||
checkArgument(tag.indexOf('-') == -1, "tag cannot contain hyphens");
|
checkArgument(tag.indexOf('-') == -1, "tag cannot contain hyphens");
|
||||||
checkNotNull(template.getLocation(), "location");
|
checkNotNull(template.getLocation(), "location");
|
||||||
logger.debug(">> running %d node%s tag(%s) location(%s) image(%s) size(%s) options(%s)",
|
logger
|
||||||
count, count > 1 ? "s" : "", tag, template.getLocation().getId(), template
|
.debug(
|
||||||
.getImage().getProviderId(), template.getSize().getProviderId(), template
|
">> running %d node%s tag(%s) location(%s) image(%s) size(%s) options(%s)",
|
||||||
.getOptions());
|
count, count > 1 ? "s" : "", tag, template.getLocation()
|
||||||
|
.getId(), template.getImage().getProviderId(), template
|
||||||
|
.getSize().getProviderId(), template.getOptions());
|
||||||
Set<NodeMetadata> nodes = Sets.newHashSet();
|
Set<NodeMetadata> nodes = Sets.newHashSet();
|
||||||
Map<NodeMetadata, Exception> badNodes = Maps.newLinkedHashMap();
|
Map<NodeMetadata, Exception> badNodes = Maps.newLinkedHashMap();
|
||||||
Map<?, ListenableFuture<Void>> responses = runNodesAndAddToSetStrategy.execute(tag, count,
|
Map<?, ListenableFuture<Void>> responses = runNodesAndAddToSetStrategy
|
||||||
template, nodes, badNodes);
|
.execute(tag, count, template, nodes, badNodes);
|
||||||
Map<?, Exception> executionExceptions = awaitCompletion(responses, executor, null, logger,
|
Map<?, Exception> executionExceptions = awaitCompletion(responses,
|
||||||
"starting nodes");
|
executor, null, logger, "starting nodes");
|
||||||
if (executionExceptions.size() > 0 || badNodes.size() > 0) {
|
if (executionExceptions.size() > 0 || badNodes.size() > 0) {
|
||||||
throw new RunNodesException(tag, count, template, nodes, executionExceptions, badNodes);
|
throw new RunNodesException(tag, count, template, nodes,
|
||||||
|
executionExceptions, badNodes);
|
||||||
}
|
}
|
||||||
return nodes;
|
return nodes;
|
||||||
}
|
}
|
||||||
|
@ -167,7 +183,8 @@ public class BaseComputeService implements ComputeService {
|
||||||
@Override
|
@Override
|
||||||
public Set<? extends NodeMetadata> runNodesWithTag(String tag, int count,
|
public Set<? extends NodeMetadata> runNodesWithTag(String tag, int count,
|
||||||
TemplateOptions templateOptions) throws RunNodesException {
|
TemplateOptions templateOptions) throws RunNodesException {
|
||||||
return runNodesWithTag(tag, count, templateBuilder().any().options(templateOptions).build());
|
return runNodesWithTag(tag, count, templateBuilder().any().options(
|
||||||
|
templateOptions).build());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -186,7 +203,8 @@ public class BaseComputeService implements ComputeService {
|
||||||
public void destroyNode(String id) {
|
public void destroyNode(String id) {
|
||||||
checkNotNull(id, "id");
|
checkNotNull(id, "id");
|
||||||
logger.debug(">> destroying node(%s)", id);
|
logger.debug(">> destroying node(%s)", id);
|
||||||
boolean successful = destroyNodeStrategy.execute(id);
|
NodeMetadata node = destroyNodeStrategy.execute(id);
|
||||||
|
boolean successful = node == null ? true : nodeTerminated.apply(node);
|
||||||
logger.debug("<< destroyed node(%s) success(%s)", id, successful);
|
logger.debug("<< destroyed node(%s) success(%s)", id, successful);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,12 +212,14 @@ public class BaseComputeService implements ComputeService {
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Set<? extends NodeMetadata> destroyNodesMatching(Predicate<NodeMetadata> filter) {
|
public Set<? extends NodeMetadata> destroyNodesMatching(
|
||||||
|
Predicate<NodeMetadata> filter) {
|
||||||
logger.debug(">> destroying nodes matching(%s)", filter);
|
logger.debug(">> destroying nodes matching(%s)", filter);
|
||||||
Map<NodeMetadata, ListenableFuture<Void>> responses = Maps.newHashMap();
|
Map<NodeMetadata, ListenableFuture<Void>> responses = Maps.newHashMap();
|
||||||
final Set<NodeMetadata> destroyedNodes = Sets.newLinkedHashSet();
|
final Set<NodeMetadata> destroyedNodes = Sets.newLinkedHashSet();
|
||||||
for (final NodeMetadata node : nodesMatchingFilterAndNotTerminated(filter)) {
|
for (final NodeMetadata node : nodesMatchingFilterAndNotTerminated(filter)) {
|
||||||
responses.put(node, makeListenable(executor.submit(new Callable<Void>() {
|
responses.put(node, makeListenable(executor
|
||||||
|
.submit(new Callable<Void>() {
|
||||||
@Override
|
@Override
|
||||||
public Void call() throws Exception {
|
public Void call() throws Exception {
|
||||||
destroyNode(node.getId());
|
destroyNode(node.getId());
|
||||||
|
@ -215,8 +235,8 @@ public class BaseComputeService implements ComputeService {
|
||||||
|
|
||||||
private Iterable<? extends NodeMetadata> nodesMatchingFilterAndNotTerminated(
|
private Iterable<? extends NodeMetadata> nodesMatchingFilterAndNotTerminated(
|
||||||
Predicate<NodeMetadata> filter) {
|
Predicate<NodeMetadata> filter) {
|
||||||
return Iterables.filter(detailsOnAllNodes(), Predicates.and(filter, Predicates
|
return Iterables.filter(detailsOnAllNodes(), Predicates.and(filter,
|
||||||
.not(NodePredicates.TERMINATED)));
|
Predicates.not(NodePredicates.TERMINATED)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -225,7 +245,8 @@ public class BaseComputeService implements ComputeService {
|
||||||
@Override
|
@Override
|
||||||
public Set<? extends ComputeMetadata> listNodes() {
|
public Set<? extends ComputeMetadata> listNodes() {
|
||||||
logger.debug(">> listing nodes");
|
logger.debug(">> listing nodes");
|
||||||
Set<? extends ComputeMetadata> set = Sets.newLinkedHashSet(listNodesStrategy.list());
|
Set<? extends ComputeMetadata> set = Sets
|
||||||
|
.newLinkedHashSet(listNodesStrategy.list());
|
||||||
logger.debug("<< list(%d)", set.size());
|
logger.debug("<< list(%d)", set.size());
|
||||||
return set;
|
return set;
|
||||||
}
|
}
|
||||||
|
@ -234,7 +255,8 @@ public class BaseComputeService implements ComputeService {
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Set<? extends NodeMetadata> listNodesDetailsMatching(Predicate<ComputeMetadata> filter) {
|
public Set<? extends NodeMetadata> listNodesDetailsMatching(
|
||||||
|
Predicate<ComputeMetadata> filter) {
|
||||||
checkNotNull(filter, "filter");
|
checkNotNull(filter, "filter");
|
||||||
logger.debug(">> listing node details matching(%s)", filter);
|
logger.debug(">> listing node details matching(%s)", filter);
|
||||||
Set<? extends NodeMetadata> set = Sets.newLinkedHashSet(listNodesStrategy
|
Set<? extends NodeMetadata> set = Sets.newLinkedHashSet(listNodesStrategy
|
||||||
|
@ -291,7 +313,8 @@ public class BaseComputeService implements ComputeService {
|
||||||
public void rebootNode(String id) {
|
public void rebootNode(String id) {
|
||||||
checkNotNull(id, "id");
|
checkNotNull(id, "id");
|
||||||
logger.debug(">> rebooting node(%s)", id);
|
logger.debug(">> rebooting node(%s)", id);
|
||||||
boolean successful = rebootNodeStrategy.execute(id);
|
NodeMetadata node = rebootNodeStrategy.execute(id);
|
||||||
|
boolean successful = nodeRunning.apply(node);
|
||||||
logger.debug("<< rebooted node(%s) success(%s)", id, successful);
|
logger.debug("<< rebooted node(%s) success(%s)", id, successful);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -304,7 +327,8 @@ public class BaseComputeService implements ComputeService {
|
||||||
|
|
||||||
Map<NodeMetadata, ListenableFuture<Void>> responses = Maps.newHashMap();
|
Map<NodeMetadata, ListenableFuture<Void>> responses = Maps.newHashMap();
|
||||||
for (final NodeMetadata node : nodesMatchingFilterAndNotTerminated(filter)) {
|
for (final NodeMetadata node : nodesMatchingFilterAndNotTerminated(filter)) {
|
||||||
responses.put(node, makeListenable(executor.submit(new Callable<Void>() {
|
responses.put(node, makeListenable(executor
|
||||||
|
.submit(new Callable<Void>() {
|
||||||
@Override
|
@Override
|
||||||
public Void call() throws Exception {
|
public Void call() throws Exception {
|
||||||
rebootNode(node.getId());
|
rebootNode(node.getId());
|
||||||
|
@ -321,7 +345,8 @@ public class BaseComputeService implements ComputeService {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Map<? extends NodeMetadata, ExecResponse> runScriptOnNodesMatching(
|
public Map<? extends NodeMetadata, ExecResponse> runScriptOnNodesMatching(
|
||||||
Predicate<NodeMetadata> filter, byte[] runScript) throws RunScriptOnNodesException {
|
Predicate<NodeMetadata> filter, byte[] runScript)
|
||||||
|
throws RunScriptOnNodesException {
|
||||||
return runScriptOnNodesMatching(filter, runScript, RunScriptOptions.NONE);
|
return runScriptOnNodesMatching(filter, runScript, RunScriptOptions.NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -329,11 +354,13 @@ public class BaseComputeService implements ComputeService {
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Map<NodeMetadata, ExecResponse> runScriptOnNodesMatching(Predicate<NodeMetadata> filter,
|
public Map<NodeMetadata, ExecResponse> runScriptOnNodesMatching(
|
||||||
final byte[] runScript, @Nullable final RunScriptOptions options)
|
Predicate<NodeMetadata> filter, final byte[] runScript,
|
||||||
|
@Nullable final RunScriptOptions options)
|
||||||
throws RunScriptOnNodesException {
|
throws RunScriptOnNodesException {
|
||||||
Iterable<? extends NodeMetadata> nodes = verifyParametersAndListNodes(filter, runScript,
|
Iterable<? extends NodeMetadata> nodes = verifyParametersAndListNodes(
|
||||||
(options != null) ? options : RunScriptOptions.NONE);
|
filter, runScript, (options != null) ? options
|
||||||
|
: RunScriptOptions.NONE);
|
||||||
|
|
||||||
final Map<NodeMetadata, ExecResponse> execs = Maps.newHashMap();
|
final Map<NodeMetadata, ExecResponse> execs = Maps.newHashMap();
|
||||||
|
|
||||||
|
@ -343,16 +370,20 @@ public class BaseComputeService implements ComputeService {
|
||||||
|
|
||||||
for (final NodeMetadata node : nodes) {
|
for (final NodeMetadata node : nodes) {
|
||||||
|
|
||||||
responses.put(node, makeListenable(executor.submit(new Callable<Void>() {
|
responses.put(node, makeListenable(executor
|
||||||
|
.submit(new Callable<Void>() {
|
||||||
@Override
|
@Override
|
||||||
public Void call() throws Exception {
|
public Void call() throws Exception {
|
||||||
try {
|
try {
|
||||||
RunScriptOnNode callable;
|
RunScriptOnNode callable;
|
||||||
if (options.isRunAsRoot())
|
if (options.isRunAsRoot())
|
||||||
callable = utils.runScriptOnNode(node, "computeserv", runScript);
|
callable = utils.runScriptOnNode(node,
|
||||||
|
"computeserv", runScript);
|
||||||
else
|
else
|
||||||
callable = utils.runScriptOnNodeAsDefaultUser(node, "computeserv", runScript);
|
callable = utils.runScriptOnNodeAsDefaultUser(node,
|
||||||
SshClient ssh = utils.createSshClientOncePortIsListeningOnNode(node);
|
"computeserv", runScript);
|
||||||
|
SshClient ssh = utils
|
||||||
|
.createSshClientOncePortIsListeningOnNode(node);
|
||||||
try {
|
try {
|
||||||
ssh.connect();
|
ssh.connect();
|
||||||
callable.setConnection(ssh, logger);
|
callable.setConnection(ssh, logger);
|
||||||
|
@ -370,42 +401,51 @@ public class BaseComputeService implements ComputeService {
|
||||||
}), executor));
|
}), executor));
|
||||||
|
|
||||||
}
|
}
|
||||||
Map<?, Exception> exceptions = awaitCompletion(responses, executor, null, logger,
|
Map<?, Exception> exceptions = awaitCompletion(responses, executor, null,
|
||||||
"starting nodes");
|
logger, "starting nodes");
|
||||||
if (exceptions.size() > 0 || badNodes.size() > 0) {
|
if (exceptions.size() > 0 || badNodes.size() > 0) {
|
||||||
throw new RunScriptOnNodesException(runScript, options, execs, exceptions, badNodes);
|
throw new RunScriptOnNodesException(runScript, options, execs,
|
||||||
|
exceptions, badNodes);
|
||||||
}
|
}
|
||||||
return execs;
|
return execs;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Iterable<? extends NodeMetadata> verifyParametersAndListNodes(
|
private Iterable<? extends NodeMetadata> verifyParametersAndListNodes(
|
||||||
Predicate<NodeMetadata> filter, byte[] runScript, final RunScriptOptions options) {
|
Predicate<NodeMetadata> filter, byte[] runScript,
|
||||||
|
final RunScriptOptions options) {
|
||||||
checkNotNull(filter, "Filter must be provided");
|
checkNotNull(filter, "Filter must be provided");
|
||||||
checkNotNull(runScript,
|
checkNotNull(
|
||||||
|
runScript,
|
||||||
"The script (represented by bytes array - use \"script\".getBytes() must be provided");
|
"The script (represented by bytes array - use \"script\".getBytes() must be provided");
|
||||||
checkNotNull(options, "options");
|
checkNotNull(options, "options");
|
||||||
|
|
||||||
Iterable<? extends NodeMetadata> nodes = Iterables.filter(detailsOnAllNodes(), filter);
|
Iterable<? extends NodeMetadata> nodes = Iterables.filter(
|
||||||
|
detailsOnAllNodes(), filter);
|
||||||
|
|
||||||
return Iterables.transform(nodes, new Function<NodeMetadata, NodeMetadata>() {
|
return Iterables.transform(nodes,
|
||||||
|
new Function<NodeMetadata, NodeMetadata>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NodeMetadata apply(NodeMetadata node) {
|
public NodeMetadata apply(NodeMetadata node) {
|
||||||
|
|
||||||
checkArgument(node.getPublicAddresses().size() > 0, "no public ip addresses on node: "
|
checkArgument(node.getPublicAddresses().size() > 0,
|
||||||
+ node);
|
"no public ip addresses on node: " + node);
|
||||||
if (options.getOverrideCredentials() != null) {
|
if (options.getOverrideCredentials() != null) {
|
||||||
// override the credentials with provided to this method
|
// override the credentials with provided to this
|
||||||
node = ComputeUtils.installNewCredentials(node, options.getOverrideCredentials());
|
// method
|
||||||
|
node = ComputeUtils.installNewCredentials(node, options
|
||||||
|
.getOverrideCredentials());
|
||||||
} else {
|
} else {
|
||||||
// don't override
|
// don't override
|
||||||
checkNotNull(node.getCredentials(),
|
checkNotNull(node.getCredentials(),
|
||||||
"If the default credentials need to be used, they can't be null");
|
"If the default credentials need to be used, they can't be null");
|
||||||
checkNotNull(node.getCredentials().account,
|
checkNotNull(
|
||||||
|
node.getCredentials().account,
|
||||||
"Account name for ssh authentication must be "
|
"Account name for ssh authentication must be "
|
||||||
+ "specified. Try passing RunScriptOptions with new credentials");
|
+ "specified. Try passing RunScriptOptions with new credentials");
|
||||||
checkNotNull(node.getCredentials().key,
|
checkNotNull(
|
||||||
|
node.getCredentials().key,
|
||||||
"Key or password for ssh authentication must be "
|
"Key or password for ssh authentication must be "
|
||||||
+ "specified. Try passing RunScriptOptions with new credentials");
|
+ "specified. Try passing RunScriptOptions with new credentials");
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,10 +24,11 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contains options supported in the {@code ComputeService#runNodesWithTag} operation. <h2>
|
* Contains options supported in the {@code ComputeService#runNodesWithTag}
|
||||||
* Usage</h2> The recommended way to instantiate a TemplateOptions object is to statically import
|
* operation. <h2>
|
||||||
* TemplateOptions.* and invoke a static creation method followed by an instance mutator (if
|
* Usage</h2> The recommended way to instantiate a TemplateOptions object is to
|
||||||
* needed):
|
* statically import TemplateOptions.* and invoke a static creation method
|
||||||
|
* followed by an instance mutator (if needed):
|
||||||
* <p/>
|
* <p/>
|
||||||
* <code>
|
* <code>
|
||||||
* import static org.jclouds.compute.options.TemplateOptions.Builder.*;
|
* import static org.jclouds.compute.options.TemplateOptions.Builder.*;
|
||||||
|
@ -41,7 +42,8 @@ import java.util.Arrays;
|
||||||
*/
|
*/
|
||||||
public class TemplateOptions {
|
public class TemplateOptions {
|
||||||
|
|
||||||
public static final TemplateOptions NONE = new ImmutableTemplateOptions(new TemplateOptions());
|
public static final TemplateOptions NONE = new ImmutableTemplateOptions(
|
||||||
|
new TemplateOptions());
|
||||||
|
|
||||||
public static class ImmutableTemplateOptions extends TemplateOptions {
|
public static class ImmutableTemplateOptions extends TemplateOptions {
|
||||||
private final TemplateOptions delegate;
|
private final TemplateOptions delegate;
|
||||||
|
@ -62,7 +64,13 @@ public class TemplateOptions {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TemplateOptions authorizePublicKey(String publicKey) {
|
public TemplateOptions authorizePublicKey(String publicKey) {
|
||||||
return delegate.authorizePublicKey(publicKey);
|
throw new IllegalArgumentException(
|
||||||
|
"authorizePublicKey is immutable");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TemplateOptions blockUntilRunning(boolean blockUntilRunning) {
|
||||||
|
throw new IllegalArgumentException("blockUntilRunning is immutable");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -100,6 +108,11 @@ public class TemplateOptions {
|
||||||
return delegate.getSeconds();
|
return delegate.getSeconds();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean shouldBlockUntilRunning() {
|
||||||
|
return delegate.shouldBlockUntilRunning();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TemplateOptions inboundPorts(int... ports) {
|
public TemplateOptions inboundPorts(int... ports) {
|
||||||
throw new IllegalArgumentException("ports is immutable");
|
throw new IllegalArgumentException("ports is immutable");
|
||||||
|
@ -141,6 +154,8 @@ public class TemplateOptions {
|
||||||
|
|
||||||
protected boolean includeMetadata;
|
protected boolean includeMetadata;
|
||||||
|
|
||||||
|
protected boolean blockUntilRunning = true;
|
||||||
|
|
||||||
public int getPort() {
|
public int getPort() {
|
||||||
return port;
|
return port;
|
||||||
}
|
}
|
||||||
|
@ -169,6 +184,10 @@ public class TemplateOptions {
|
||||||
return includeMetadata;
|
return includeMetadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean shouldBlockUntilRunning() {
|
||||||
|
return blockUntilRunning;
|
||||||
|
}
|
||||||
|
|
||||||
public <T extends TemplateOptions> T as(Class<T> clazz) {
|
public <T extends TemplateOptions> T as(Class<T> clazz) {
|
||||||
return clazz.cast(this);
|
return clazz.cast(this);
|
||||||
}
|
}
|
||||||
|
@ -177,7 +196,8 @@ public class TemplateOptions {
|
||||||
* When the node is started, wait until the following port is active
|
* When the node is started, wait until the following port is active
|
||||||
*/
|
*/
|
||||||
public TemplateOptions blockOnPort(int port, int seconds) {
|
public TemplateOptions blockOnPort(int port, int seconds) {
|
||||||
checkArgument(port > 0 && port < 65536, "port must be a positive integer < 65535");
|
checkArgument(port > 0 && port < 65536,
|
||||||
|
"port must be a positive integer < 65535");
|
||||||
checkArgument(seconds > 0, "seconds must be a positive integer");
|
checkArgument(seconds > 0, "seconds must be a positive integer");
|
||||||
this.port = port;
|
this.port = port;
|
||||||
this.seconds = seconds;
|
this.seconds = seconds;
|
||||||
|
@ -185,8 +205,8 @@ public class TemplateOptions {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This script will be executed as the root user upon system startup. This script gets a
|
* This script will be executed as the root user upon system startup. This
|
||||||
* prologue, so no #!/bin/bash required, path set up, etc
|
* script gets a prologue, so no #!/bin/bash required, path set up, etc
|
||||||
*/
|
*/
|
||||||
public TemplateOptions runScript(byte[] script) {
|
public TemplateOptions runScript(byte[] script) {
|
||||||
checkArgument(checkNotNull(script, "script").length <= 16 * 1024,
|
checkArgument(checkNotNull(script, "script").length <= 16 * 1024,
|
||||||
|
@ -211,12 +231,25 @@ public class TemplateOptions {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* if true, return when node(s) are NODE_RUNNING, if false, return as soon as the
|
||||||
|
* server is provisioned.
|
||||||
|
* <p/>
|
||||||
|
* default is true
|
||||||
|
*/
|
||||||
|
public TemplateOptions blockUntilRunning(boolean blockUntilRunning) {
|
||||||
|
this.blockUntilRunning = blockUntilRunning;
|
||||||
|
if (!blockUntilRunning)
|
||||||
|
port = seconds = -1;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* authorized an rsa ssh key.
|
* authorized an rsa ssh key.
|
||||||
*/
|
*/
|
||||||
public TemplateOptions authorizePublicKey(String publicKey) {
|
public TemplateOptions authorizePublicKey(String publicKey) {
|
||||||
checkArgument(checkNotNull(publicKey, "publicKey").startsWith("ssh-rsa"),
|
checkArgument(checkNotNull(publicKey, "publicKey")
|
||||||
"key should start with ssh-rsa");
|
.startsWith("ssh-rsa"), "key should start with ssh-rsa");
|
||||||
this.publicKey = publicKey;
|
this.publicKey = publicKey;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -226,7 +259,8 @@ public class TemplateOptions {
|
||||||
*/
|
*/
|
||||||
public TemplateOptions inboundPorts(int... ports) {
|
public TemplateOptions inboundPorts(int... ports) {
|
||||||
for (int port : ports)
|
for (int port : ports)
|
||||||
checkArgument(port > 0 && port < 65536, "port must be a positive integer < 65535");
|
checkArgument(port > 0 && port < 65536,
|
||||||
|
"port must be a positive integer < 65535");
|
||||||
this.inboundPorts = ports;
|
this.inboundPorts = ports;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -254,6 +288,15 @@ public class TemplateOptions {
|
||||||
return options.blockOnPort(port, seconds);
|
return options.blockOnPort(port, seconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see TemplateOptions#blockUntilRunning
|
||||||
|
*/
|
||||||
|
public static TemplateOptions blockUntilRunning(
|
||||||
|
boolean blockUntilRunning) {
|
||||||
|
TemplateOptions options = new TemplateOptions();
|
||||||
|
return options.blockUntilRunning(blockUntilRunning);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see TemplateOptions#runScript
|
* @see TemplateOptions#runScript
|
||||||
*/
|
*/
|
||||||
|
@ -287,9 +330,11 @@ public class TemplateOptions {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "TemplateOptions [inboundPorts=" + Arrays.toString(inboundPorts) + ", privateKey="
|
return "TemplateOptions [inboundPorts=" + Arrays.toString(inboundPorts)
|
||||||
+ (privateKey != null) + ", publicKey=" + (publicKey != null) + ", runScript="
|
+ ", privateKey=" + (privateKey != null) + ", publicKey="
|
||||||
+ (script != null) + ", port:seconds=" + port + ":" + seconds
|
+ (publicKey != null) + ", runScript=" + (script != null)
|
||||||
|
+ ", blockUntilRunning=" + blockUntilRunning
|
||||||
|
+ ", port:seconds=" + port + ":" + seconds
|
||||||
+ ", metadata/details: " + includeMetadata + "]";
|
+ ", metadata/details: " + includeMetadata + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -297,11 +342,14 @@ public class TemplateOptions {
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
final int prime = 31;
|
final int prime = 31;
|
||||||
int result = 1;
|
int result = 1;
|
||||||
|
result = prime * result + (blockUntilRunning ? 1231 : 1237);
|
||||||
result = prime * result + Arrays.hashCode(inboundPorts);
|
result = prime * result + Arrays.hashCode(inboundPorts);
|
||||||
result = prime * result + (includeMetadata ? 1231 : 1237);
|
result = prime * result + (includeMetadata ? 1231 : 1237);
|
||||||
result = prime * result + port;
|
result = prime * result + port;
|
||||||
result = prime * result + ((privateKey == null) ? 0 : privateKey.hashCode());
|
result = prime * result
|
||||||
result = prime * result + ((publicKey == null) ? 0 : publicKey.hashCode());
|
+ ((privateKey == null) ? 0 : privateKey.hashCode());
|
||||||
|
result = prime * result
|
||||||
|
+ ((publicKey == null) ? 0 : publicKey.hashCode());
|
||||||
result = prime * result + Arrays.hashCode(script);
|
result = prime * result + Arrays.hashCode(script);
|
||||||
result = prime * result + seconds;
|
result = prime * result + seconds;
|
||||||
return result;
|
return result;
|
||||||
|
@ -316,6 +364,8 @@ public class TemplateOptions {
|
||||||
if (getClass() != obj.getClass())
|
if (getClass() != obj.getClass())
|
||||||
return false;
|
return false;
|
||||||
TemplateOptions other = (TemplateOptions) obj;
|
TemplateOptions other = (TemplateOptions) obj;
|
||||||
|
if (blockUntilRunning != other.blockUntilRunning)
|
||||||
|
return false;
|
||||||
if (!Arrays.equals(inboundPorts, other.inboundPorts))
|
if (!Arrays.equals(inboundPorts, other.inboundPorts))
|
||||||
return false;
|
return false;
|
||||||
if (includeMetadata != other.includeMetadata)
|
if (includeMetadata != other.includeMetadata)
|
||||||
|
|
|
@ -96,7 +96,7 @@ public class NodePredicates {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return nodes with specified tag that are in the RUNNING state.
|
* Return nodes with specified tag that are in the NODE_RUNNING state.
|
||||||
*
|
*
|
||||||
* @param tag
|
* @param tag
|
||||||
* tag to match the items
|
* tag to match the items
|
||||||
|
@ -121,7 +121,7 @@ public class NodePredicates {
|
||||||
/**
|
/**
|
||||||
* Match nodes with State == RUNNING
|
* Match nodes with State == RUNNING
|
||||||
*/
|
*/
|
||||||
public static final Predicate<NodeMetadata> ACTIVE = new Predicate<NodeMetadata>() {
|
public static final Predicate<NodeMetadata> RUNNING = new Predicate<NodeMetadata>() {
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(NodeMetadata nodeMetadata) {
|
public boolean apply(NodeMetadata nodeMetadata) {
|
||||||
return nodeMetadata.getState() == NodeState.RUNNING;
|
return nodeMetadata.getState() == NodeState.RUNNING;
|
||||||
|
@ -129,12 +129,12 @@ public class NodePredicates {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "ACTIVE";
|
return "RUNNING";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Match nodes with State == TERMINATED
|
* Match nodes with State == NODE_TERMINATED
|
||||||
*/
|
*/
|
||||||
public static final Predicate<NodeMetadata> TERMINATED = new Predicate<NodeMetadata>() {
|
public static final Predicate<NodeMetadata> TERMINATED = new Predicate<NodeMetadata>() {
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
package org.jclouds.compute.predicates;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import org.jclouds.compute.ComputeService;
|
||||||
|
import org.jclouds.compute.domain.NodeMetadata;
|
||||||
|
import org.jclouds.compute.domain.NodeState;
|
||||||
|
import org.jclouds.logging.Logger;
|
||||||
|
|
||||||
|
import com.google.common.base.Predicate;
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Tests to see if a node is active.
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Singleton
|
||||||
|
public class NodeRunning implements Predicate<NodeMetadata> {
|
||||||
|
|
||||||
|
private final ComputeService client;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
protected Logger logger = Logger.NULL;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public NodeRunning(ComputeService client) {
|
||||||
|
this.client = client;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean apply(NodeMetadata node) {
|
||||||
|
logger.trace("looking for state on node %s", checkNotNull(node, "node"));
|
||||||
|
node = refresh(node);
|
||||||
|
if (node == null)
|
||||||
|
return false;
|
||||||
|
logger.trace("%s: looking for node state %s: currently: %s",
|
||||||
|
node.getId(), NodeState.RUNNING, node.getState());
|
||||||
|
if (node.getState() == NodeState.ERROR)
|
||||||
|
throw new IllegalStateException("node " + node.getId()
|
||||||
|
+ " in location " + node.getLocation() + " is in error state");
|
||||||
|
return node.getState() == NodeState.RUNNING;
|
||||||
|
}
|
||||||
|
|
||||||
|
private NodeMetadata refresh(NodeMetadata node) {
|
||||||
|
return client.getNodeMetadata(node.getId());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
package org.jclouds.compute.predicates;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import org.jclouds.compute.ComputeService;
|
||||||
|
import org.jclouds.compute.domain.NodeMetadata;
|
||||||
|
import org.jclouds.compute.domain.NodeState;
|
||||||
|
import org.jclouds.logging.Logger;
|
||||||
|
|
||||||
|
import com.google.common.base.Predicate;
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Tests to see if a node is deleted
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Singleton
|
||||||
|
public class NodeTerminated implements Predicate<NodeMetadata> {
|
||||||
|
|
||||||
|
private final ComputeService client;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
protected Logger logger = Logger.NULL;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public NodeTerminated(ComputeService client) {
|
||||||
|
this.client = client;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean apply(NodeMetadata node) {
|
||||||
|
logger.trace("looking for state on node %s", checkNotNull(node, "node"));
|
||||||
|
node = refresh(node);
|
||||||
|
if (node == null)
|
||||||
|
return true;
|
||||||
|
logger.trace("%s: looking for node state %s: currently: %s",
|
||||||
|
node.getId(), NodeState.TERMINATED, node.getState());
|
||||||
|
return node.getState() == NodeState.TERMINATED;
|
||||||
|
}
|
||||||
|
|
||||||
|
private NodeMetadata refresh(NodeMetadata node) {
|
||||||
|
return client.getNodeMetadata(node.getId());
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,6 +18,11 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.compute.reference;
|
package org.jclouds.compute.reference;
|
||||||
|
|
||||||
|
import javax.inject.Named;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
|
@ -26,5 +31,28 @@ public interface ComputeServiceConstants {
|
||||||
|
|
||||||
public static final String COMPUTE_LOGGER = "jclouds.compute";
|
public static final String COMPUTE_LOGGER = "jclouds.compute";
|
||||||
public static final String LOCAL_PARTITION_GB_PATTERN = "disk_drive/%s/gb";
|
public static final String LOCAL_PARTITION_GB_PATTERN = "disk_drive/%s/gb";
|
||||||
|
public static final String PROPERTY_TIMEOUT_NODE_TERMINATED = "jclouds.compute.timeout.node-terminated";
|
||||||
|
public static final String PROPERTY_TIMEOUT_NODE_RUNNING = "jclouds.compute.timeout.node-running";
|
||||||
|
public static final String PROPERTY_TIMEOUT_SCRIPT_COMPLETE = "jclouds.compute.timeout.script-complete";
|
||||||
|
public static final String PROPERTY_TIMEOUT_PORT_OPEN = "jclouds.compute.timeout.port-open";
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
static class Timeouts {
|
||||||
|
@Inject(optional = true)
|
||||||
|
@Named(PROPERTY_TIMEOUT_NODE_TERMINATED)
|
||||||
|
public long nodeTerminated = 600 * 1000;
|
||||||
|
|
||||||
|
@Inject(optional = true)
|
||||||
|
@Named(PROPERTY_TIMEOUT_NODE_RUNNING)
|
||||||
|
public long nodeRunning = 600 * 1000;
|
||||||
|
|
||||||
|
@Inject(optional = true)
|
||||||
|
@Named(PROPERTY_TIMEOUT_SCRIPT_COMPLETE)
|
||||||
|
public long scriptComplete = 600 * 1000;
|
||||||
|
|
||||||
|
@Inject(optional = true)
|
||||||
|
@Named(PROPERTY_TIMEOUT_PORT_OPEN)
|
||||||
|
public long portOpen = 130 * 1000;
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,15 +19,19 @@
|
||||||
|
|
||||||
package org.jclouds.compute.strategy;
|
package org.jclouds.compute.strategy;
|
||||||
|
|
||||||
|
import org.jclouds.compute.domain.NodeMetadata;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* terminates the node and blocks until it is no longer visible or in the state TERMINATED. If this
|
* terminates the node
|
||||||
* is the last node in a tagset, incidental resources are also destroyed.
|
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public interface DestroyNodeStrategy {
|
public interface DestroyNodeStrategy {
|
||||||
|
|
||||||
boolean execute(String id);
|
/**
|
||||||
|
*
|
||||||
|
* @return null if the node wasn't found
|
||||||
|
*/
|
||||||
|
NodeMetadata execute(String id);
|
||||||
|
|
||||||
}
|
}
|
|
@ -19,14 +19,15 @@
|
||||||
|
|
||||||
package org.jclouds.compute.strategy;
|
package org.jclouds.compute.strategy;
|
||||||
|
|
||||||
|
import org.jclouds.compute.domain.NodeMetadata;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reboots a node unless it is in the state TERMINATED.
|
* Reboots a node unless it is in the state NODE_TERMINATED.
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public interface RebootNodeStrategy {
|
public interface RebootNodeStrategy {
|
||||||
|
|
||||||
boolean execute(String id);
|
NodeMetadata execute(String id);
|
||||||
|
|
||||||
}
|
}
|
|
@ -55,7 +55,8 @@ import com.google.common.util.concurrent.ListenableFuture;
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@Singleton
|
@Singleton
|
||||||
public class EncodeTagIntoNameRunNodesAndAddToSetStrategy implements RunNodesAndAddToSetStrategy {
|
public class EncodeTagIntoNameRunNodesAndAddToSetStrategy implements
|
||||||
|
RunNodesAndAddToSetStrategy {
|
||||||
@Resource
|
@Resource
|
||||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||||
protected Logger logger = Logger.NULL;
|
protected Logger logger = Logger.NULL;
|
||||||
|
@ -67,8 +68,10 @@ public class EncodeTagIntoNameRunNodesAndAddToSetStrategy implements RunNodesAnd
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
protected EncodeTagIntoNameRunNodesAndAddToSetStrategy(
|
protected EncodeTagIntoNameRunNodesAndAddToSetStrategy(
|
||||||
AddNodeWithTagStrategy addNodeWithTagStrategy, ListNodesStrategy listNodesStrategy,
|
AddNodeWithTagStrategy addNodeWithTagStrategy,
|
||||||
@Named("NAMING_CONVENTION") String nodeNamingConvention, ComputeUtils utils,
|
ListNodesStrategy listNodesStrategy,
|
||||||
|
@Named("NAMING_CONVENTION") String nodeNamingConvention,
|
||||||
|
ComputeUtils utils,
|
||||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) {
|
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) {
|
||||||
this.addNodeWithTagStrategy = addNodeWithTagStrategy;
|
this.addNodeWithTagStrategy = addNodeWithTagStrategy;
|
||||||
this.listNodesStrategy = listNodesStrategy;
|
this.listNodesStrategy = listNodesStrategy;
|
||||||
|
@ -78,31 +81,29 @@ public class EncodeTagIntoNameRunNodesAndAddToSetStrategy implements RunNodesAnd
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This implementation gets a list of acceptable node names to encode the tag into, then it
|
* This implementation gets a list of acceptable node names to encode the tag
|
||||||
* simultaneously runs the nodes and applies options to them.
|
* into, then it simultaneously runs the nodes and applies options to them.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Map<?, ListenableFuture<Void>> execute(final String tag, final int count,
|
public Map<?, ListenableFuture<Void>> execute(final String tag,
|
||||||
final Template template, final Set<NodeMetadata> nodes,
|
final int count, final Template template,
|
||||||
|
final Set<NodeMetadata> nodes,
|
||||||
final Map<NodeMetadata, Exception> badNodes) {
|
final Map<NodeMetadata, Exception> badNodes) {
|
||||||
Map<String, ListenableFuture<Void>> responses = Maps.newHashMap();
|
Map<String, ListenableFuture<Void>> responses = Maps.newHashMap();
|
||||||
for (final String name : getNextNames(tag, template, count)) {
|
for (final String name : getNextNames(tag, template, count)) {
|
||||||
responses.put(name, makeListenable(executor.submit(new Callable<Void>() {
|
responses.put(name, makeListenable(executor
|
||||||
|
.submit(new Callable<Void>() {
|
||||||
@Override
|
@Override
|
||||||
public Void call() throws Exception {
|
public Void call() throws Exception {
|
||||||
NodeMetadata node = null;
|
NodeMetadata node = null;
|
||||||
logger.debug(">> starting node(%s) tag(%s)", name, tag);
|
logger.debug(">> starting node(%s) tag(%s)", name, tag);
|
||||||
node = addNodeWithTagStrategy.execute(tag, name, template);
|
node = addNodeWithTagStrategy.execute(tag, name, template);
|
||||||
logger.debug("<< running node(%s)", node.getProviderId());
|
logger.debug("<< %s node(%s)", node.getState(), node
|
||||||
try {
|
.getId());
|
||||||
utils.runOptionsOnNode(node, template.getOptions());
|
utils
|
||||||
logger.debug("<< options applied node(%s)", node.getProviderId());
|
.runOptionsOnNodeAndAddToGoodSetOrPutExceptionIntoBadMap(
|
||||||
nodes.add(node);
|
node, badNodes, nodes, template.getOptions())
|
||||||
} catch (Exception e) {
|
.call();
|
||||||
logger.error(e, "<< error applying options (%s) on node (%s)", template
|
|
||||||
.getOptions(), node.getProviderId());
|
|
||||||
badNodes.put(node, e);
|
|
||||||
}
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}), executor));
|
}), executor));
|
||||||
|
@ -111,18 +112,20 @@ public class EncodeTagIntoNameRunNodesAndAddToSetStrategy implements RunNodesAnd
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find the next node names that can be used. These will be derived from the tag and the
|
* Find the next node names that can be used. These will be derived from the
|
||||||
* template. We will pre-allocate a specified quantity, and attempt to verify that there is no
|
* tag and the template. We will pre-allocate a specified quantity, and
|
||||||
* name conflict with the current service.
|
* attempt to verify that there is no name conflict with the current service.
|
||||||
*
|
*
|
||||||
* @param tag
|
* @param tag
|
||||||
* @param count
|
* @param count
|
||||||
* @param template
|
* @param template
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
protected Set<String> getNextNames(final String tag, final Template template, int count) {
|
protected Set<String> getNextNames(final String tag,
|
||||||
|
final Template template, int count) {
|
||||||
Set<String> names = Sets.newHashSet();
|
Set<String> names = Sets.newHashSet();
|
||||||
Iterable<? extends ComputeMetadata> currentNodes = listNodesStrategy.list();
|
Iterable<? extends ComputeMetadata> currentNodes = listNodesStrategy
|
||||||
|
.list();
|
||||||
int maxTries = 100;
|
int maxTries = 100;
|
||||||
int currentTries = 0;
|
int currentTries = 0;
|
||||||
while (names.size() < count && currentTries++ < maxTries) {
|
while (names.size() < count && currentTries++ < maxTries) {
|
||||||
|
@ -142,15 +145,16 @@ public class EncodeTagIntoNameRunNodesAndAddToSetStrategy implements RunNodesAnd
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a name using a random mechanism that still ties all nodes in a tag together.
|
* Get a name using a random mechanism that still ties all nodes in a tag
|
||||||
|
* together.
|
||||||
*
|
*
|
||||||
* This implementation will pass the tag and a hex formatted random number to the configured
|
* This implementation will pass the tag and a hex formatted random number to
|
||||||
* naming convention.
|
* the configured naming convention.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
protected String getNextName(final String tag, final Template template) {
|
protected String getNextName(final String tag, final Template template) {
|
||||||
return String.format(nodeNamingConvention, tag, Integer.toHexString(new SecureRandom()
|
return String.format(nodeNamingConvention, tag, Integer
|
||||||
.nextInt(4095)));
|
.toHexString(new SecureRandom().nextInt(4095)));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -28,7 +28,7 @@ import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.ConcurrentMap;
|
import java.util.concurrent.ConcurrentMap;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
@ -39,6 +39,7 @@ import javax.inject.Singleton;
|
||||||
import org.jclouds.Constants;
|
import org.jclouds.Constants;
|
||||||
import org.jclouds.compute.ComputeServiceContext;
|
import org.jclouds.compute.ComputeServiceContext;
|
||||||
import org.jclouds.compute.LoadBalancerService;
|
import org.jclouds.compute.LoadBalancerService;
|
||||||
|
import org.jclouds.compute.config.ComputeServiceTimeoutsModule;
|
||||||
import org.jclouds.compute.domain.Architecture;
|
import org.jclouds.compute.domain.Architecture;
|
||||||
import org.jclouds.compute.domain.ComputeMetadata;
|
import org.jclouds.compute.domain.ComputeMetadata;
|
||||||
import org.jclouds.compute.domain.Image;
|
import org.jclouds.compute.domain.Image;
|
||||||
|
@ -52,8 +53,6 @@ import org.jclouds.compute.domain.internal.ImageImpl;
|
||||||
import org.jclouds.compute.domain.internal.NodeMetadataImpl;
|
import org.jclouds.compute.domain.internal.NodeMetadataImpl;
|
||||||
import org.jclouds.compute.internal.ComputeServiceContextImpl;
|
import org.jclouds.compute.internal.ComputeServiceContextImpl;
|
||||||
import org.jclouds.compute.predicates.NodePredicates;
|
import org.jclouds.compute.predicates.NodePredicates;
|
||||||
import org.jclouds.compute.predicates.ScriptStatusReturnsZero;
|
|
||||||
import org.jclouds.compute.predicates.ScriptStatusReturnsZero.CommandUsingClient;
|
|
||||||
import org.jclouds.compute.strategy.AddNodeWithTagStrategy;
|
import org.jclouds.compute.strategy.AddNodeWithTagStrategy;
|
||||||
import org.jclouds.compute.strategy.DestroyNodeStrategy;
|
import org.jclouds.compute.strategy.DestroyNodeStrategy;
|
||||||
import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
|
import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
|
||||||
|
@ -66,14 +65,12 @@ import org.jclouds.domain.LocationScope;
|
||||||
import org.jclouds.domain.internal.LocationImpl;
|
import org.jclouds.domain.internal.LocationImpl;
|
||||||
import org.jclouds.lifecycle.Closer;
|
import org.jclouds.lifecycle.Closer;
|
||||||
import org.jclouds.net.IPSocket;
|
import org.jclouds.net.IPSocket;
|
||||||
import org.jclouds.predicates.RetryablePredicate;
|
|
||||||
import org.jclouds.predicates.SocketOpen;
|
import org.jclouds.predicates.SocketOpen;
|
||||||
import org.jclouds.rest.ResourceNotFoundException;
|
import org.jclouds.rest.ResourceNotFoundException;
|
||||||
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.common.base.Predicate;
|
||||||
import com.google.common.base.Predicates;
|
|
||||||
import com.google.common.base.Throwables;
|
import com.google.common.base.Throwables;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
@ -161,8 +158,8 @@ public class StubComputeServiceContextModule extends AbstractModule {
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
RestContext<ConcurrentMap, ConcurrentMap> provideRestContext(Closer closer) {
|
RestContext<ConcurrentMap, ConcurrentMap> provideRestContext(Closer closer) {
|
||||||
return new RestContextImpl<ConcurrentMap, ConcurrentMap>(closer, nodes, nodes, URI
|
return new RestContextImpl<ConcurrentMap, ConcurrentMap>(closer, nodes,
|
||||||
.create("http://stub"), System.getProperty("user.name"));
|
nodes, URI.create("http://stub"), System.getProperty("user.name"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// NORMAL STUFF
|
// NORMAL STUFF
|
||||||
|
@ -175,21 +172,19 @@ public class StubComputeServiceContextModule extends AbstractModule {
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
|
install(new ComputeServiceTimeoutsModule());
|
||||||
bind(new TypeLiteral<ComputeServiceContext>() {
|
bind(new TypeLiteral<ComputeServiceContext>() {
|
||||||
}).to(new TypeLiteral<ComputeServiceContextImpl<ConcurrentMap, ConcurrentMap>>() {
|
})
|
||||||
|
.to(
|
||||||
|
new TypeLiteral<ComputeServiceContextImpl<ConcurrentMap, ConcurrentMap>>() {
|
||||||
}).in(Scopes.SINGLETON);
|
}).in(Scopes.SINGLETON);
|
||||||
bind(AddNodeWithTagStrategy.class).to(StubAddNodeWithTagStrategy.class);
|
bind(AddNodeWithTagStrategy.class).to(StubAddNodeWithTagStrategy.class);
|
||||||
bind(ListNodesStrategy.class).to(StubListNodesStrategy.class);
|
bind(ListNodesStrategy.class).to(StubListNodesStrategy.class);
|
||||||
bind(GetNodeMetadataStrategy.class).to(StubGetNodeMetadataStrategy.class);
|
bind(GetNodeMetadataStrategy.class).to(StubGetNodeMetadataStrategy.class);
|
||||||
bind(RebootNodeStrategy.class).to(StubRebootNodeStrategy.class);
|
bind(RebootNodeStrategy.class).to(StubRebootNodeStrategy.class);
|
||||||
bind(DestroyNodeStrategy.class).to(StubDestroyNodeStrategy.class);
|
bind(DestroyNodeStrategy.class).to(StubDestroyNodeStrategy.class);
|
||||||
bind(LoadBalancerService.class).toProvider(Providers.<LoadBalancerService> of(null));
|
bind(LoadBalancerService.class).toProvider(
|
||||||
}
|
Providers.<LoadBalancerService> of(null));
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
protected Predicate<IPSocket> socketTester(SocketOpen open) {
|
|
||||||
return new RetryablePredicate<IPSocket>(open, 130, 10, TimeUnit.MILLISECONDS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
|
@ -205,12 +200,14 @@ public class StubComputeServiceContextModule extends AbstractModule {
|
||||||
private NodeState state;
|
private NodeState state;
|
||||||
private final ExecutorService service;
|
private final ExecutorService service;
|
||||||
|
|
||||||
public StubNodeMetadata(String providerId, String name, String id, Location location,
|
public StubNodeMetadata(String providerId, String name, String id,
|
||||||
URI uri, Map<String, String> userMetadata, String tag, Image image, NodeState state,
|
Location location, URI uri, Map<String, String> userMetadata,
|
||||||
Iterable<String> publicAddresses, Iterable<String> privateAddresses,
|
String tag, Image image, NodeState state,
|
||||||
Map<String, String> extra, Credentials credentials, ExecutorService service) {
|
Iterable<String> publicAddresses,
|
||||||
super(providerId, name, id, location, uri, userMetadata, tag, image, state,
|
Iterable<String> privateAddresses, Map<String, String> extra,
|
||||||
publicAddresses, privateAddresses, extra, credentials);
|
Credentials credentials, ExecutorService service) {
|
||||||
|
super(providerId, name, id, location, uri, userMetadata, tag, image,
|
||||||
|
state, publicAddresses, privateAddresses, extra, credentials);
|
||||||
this.setState(state, 0);
|
this.setState(state, 0);
|
||||||
this.service = service;
|
this.service = service;
|
||||||
}
|
}
|
||||||
|
@ -242,7 +239,8 @@ public class StubComputeServiceContextModule extends AbstractModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public static class StubAddNodeWithTagStrategy implements AddNodeWithTagStrategy {
|
public static class StubAddNodeWithTagStrategy implements
|
||||||
|
AddNodeWithTagStrategy {
|
||||||
private final Location location;
|
private final Location location;
|
||||||
private final ExecutorService service;
|
private final ExecutorService service;
|
||||||
private final ConcurrentMap<Integer, StubNodeMetadata> nodes;
|
private final ConcurrentMap<Integer, StubNodeMetadata> nodes;
|
||||||
|
@ -252,15 +250,16 @@ public class StubComputeServiceContextModule extends AbstractModule {
|
||||||
private final String passwordPrefix;
|
private final String passwordPrefix;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public StubAddNodeWithTagStrategy(ConcurrentMap<Integer, StubNodeMetadata> nodes,
|
public StubAddNodeWithTagStrategy(
|
||||||
Location location, @Named(Constants.PROPERTY_USER_THREADS) ExecutorService service,
|
ConcurrentMap<Integer, StubNodeMetadata> nodes, Location location,
|
||||||
|
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService service,
|
||||||
@Named("NODE_ID") Provider<Integer> idProvider,
|
@Named("NODE_ID") Provider<Integer> idProvider,
|
||||||
@Named("PUBLIC_IP_PREFIX") String publicIpPrefix,
|
@Named("PUBLIC_IP_PREFIX") String publicIpPrefix,
|
||||||
@Named("PRIVATE_IP_PREFIX") String privateIpPrefix,
|
@Named("PRIVATE_IP_PREFIX") String privateIpPrefix,
|
||||||
@Named("PASSWORD_PREFIX") String passwordPrefix) {
|
@Named("PASSWORD_PREFIX") String passwordPrefix) {
|
||||||
this.nodes = nodes;
|
this.nodes = nodes;
|
||||||
this.location = location;
|
this.location = location;
|
||||||
this.service = service;
|
this.service = Executors.newCachedThreadPool();
|
||||||
this.idProvider = idProvider;
|
this.idProvider = idProvider;
|
||||||
this.publicIpPrefix = publicIpPrefix;
|
this.publicIpPrefix = publicIpPrefix;
|
||||||
this.privateIpPrefix = privateIpPrefix;
|
this.privateIpPrefix = privateIpPrefix;
|
||||||
|
@ -269,27 +268,31 @@ public class StubComputeServiceContextModule extends AbstractModule {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NodeMetadata execute(String tag, String name, Template template) {
|
public NodeMetadata execute(String tag, String name, Template template) {
|
||||||
checkArgument(location.equals(template.getLocation()), "invalid location: "
|
checkArgument(location.equals(template.getLocation()),
|
||||||
+ template.getLocation());
|
"invalid location: " + template.getLocation());
|
||||||
int id = idProvider.get();
|
int id = idProvider.get();
|
||||||
StubNodeMetadata node = new StubNodeMetadata(id + "", name, id + "", location, null,
|
StubNodeMetadata node = new StubNodeMetadata(id + "", name, id + "",
|
||||||
ImmutableMap.<String, String> of(), tag, template.getImage(), NodeState.PENDING,
|
location, null, ImmutableMap.<String, String> of(), tag,
|
||||||
ImmutableSet.<String> of(publicIpPrefix + id), ImmutableSet
|
template.getImage(), NodeState.PENDING, ImmutableSet
|
||||||
.<String> of(privateIpPrefix + id), ImmutableMap.<String, String> of(),
|
.<String> of(publicIpPrefix + id), ImmutableSet
|
||||||
new Credentials("root", passwordPrefix + id), service);
|
.<String> of(privateIpPrefix + id), ImmutableMap
|
||||||
node.setState(NodeState.RUNNING, 100);
|
.<String, String> of(), new Credentials("root",
|
||||||
|
passwordPrefix + id), service);
|
||||||
nodes.put(id, node);
|
nodes.put(id, node);
|
||||||
|
node.setState(NodeState.RUNNING, 100);
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public static class StubGetNodeMetadataStrategy implements GetNodeMetadataStrategy {
|
public static class StubGetNodeMetadataStrategy implements
|
||||||
|
GetNodeMetadataStrategy {
|
||||||
private final ConcurrentMap<Integer, StubNodeMetadata> nodes;
|
private final ConcurrentMap<Integer, StubNodeMetadata> nodes;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
protected StubGetNodeMetadataStrategy(ConcurrentMap<Integer, StubNodeMetadata> nodes) {
|
protected StubGetNodeMetadataStrategy(
|
||||||
|
ConcurrentMap<Integer, StubNodeMetadata> nodes) {
|
||||||
this.nodes = nodes;
|
this.nodes = nodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -304,7 +307,8 @@ public class StubComputeServiceContextModule extends AbstractModule {
|
||||||
private final ConcurrentMap<Integer, StubNodeMetadata> nodes;
|
private final ConcurrentMap<Integer, StubNodeMetadata> nodes;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
protected StubListNodesStrategy(ConcurrentMap<Integer, StubNodeMetadata> nodes) {
|
protected StubListNodesStrategy(
|
||||||
|
ConcurrentMap<Integer, StubNodeMetadata> nodes) {
|
||||||
this.nodes = nodes;
|
this.nodes = nodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -325,18 +329,19 @@ public class StubComputeServiceContextModule extends AbstractModule {
|
||||||
private final ConcurrentMap<Integer, StubNodeMetadata> nodes;
|
private final ConcurrentMap<Integer, StubNodeMetadata> nodes;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
protected StubRebootNodeStrategy(ConcurrentMap<Integer, StubNodeMetadata> nodes) {
|
protected StubRebootNodeStrategy(
|
||||||
|
ConcurrentMap<Integer, StubNodeMetadata> nodes) {
|
||||||
this.nodes = nodes;
|
this.nodes = nodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean execute(String id) {
|
public StubNodeMetadata execute(String id) {
|
||||||
StubNodeMetadata node = nodes.get(Integer.parseInt(id));
|
StubNodeMetadata node = nodes.get(Integer.parseInt(id));
|
||||||
if (node == null)
|
if (node == null)
|
||||||
throw new ResourceNotFoundException("node not found: " + id);
|
throw new ResourceNotFoundException("node not found: " + id);
|
||||||
node.setState(NodeState.PENDING, 0);
|
node.setState(NodeState.PENDING, 0);
|
||||||
node.setState(NodeState.RUNNING, 50);
|
node.setState(NodeState.RUNNING, 50);
|
||||||
return true;
|
return node;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -346,18 +351,19 @@ public class StubComputeServiceContextModule extends AbstractModule {
|
||||||
private final ExecutorService service;
|
private final ExecutorService service;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
protected StubDestroyNodeStrategy(ConcurrentMap<Integer, StubNodeMetadata> nodes,
|
protected StubDestroyNodeStrategy(
|
||||||
|
ConcurrentMap<Integer, StubNodeMetadata> nodes,
|
||||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService service) {
|
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService service) {
|
||||||
this.nodes = nodes;
|
this.nodes = nodes;
|
||||||
this.service = service;
|
this.service = service;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean execute(String id) {
|
public StubNodeMetadata execute(String id) {
|
||||||
final int nodeId = Integer.parseInt(id);
|
final int nodeId = Integer.parseInt(id);
|
||||||
StubNodeMetadata node = nodes.get(nodeId);
|
StubNodeMetadata node = nodes.get(nodeId);
|
||||||
if (node == null)
|
if (node == null)
|
||||||
return true;
|
return node;
|
||||||
node.setState(NodeState.PENDING, 0);
|
node.setState(NodeState.PENDING, 0);
|
||||||
node.setState(NodeState.TERMINATED, 50);
|
node.setState(NodeState.TERMINATED, 50);
|
||||||
service.execute(new Runnable() {
|
service.execute(new Runnable() {
|
||||||
|
@ -374,7 +380,7 @@ public class StubComputeServiceContextModule extends AbstractModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
return true;
|
return node;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -385,30 +391,24 @@ public class StubComputeServiceContextModule extends AbstractModule {
|
||||||
return "%s-%s";
|
return "%s-%s";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
@Named("NOT_RUNNING")
|
|
||||||
protected Predicate<CommandUsingClient> runScriptRunning(ScriptStatusReturnsZero stateRunning) {
|
|
||||||
return new RetryablePredicate<CommandUsingClient>(Predicates.not(stateRunning), 600, 3,
|
|
||||||
TimeUnit.SECONDS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
protected Set<? extends Size> provideSizes() {
|
protected Set<? extends Size> provideSizes() {
|
||||||
return ImmutableSet.of(new StubSize("small", 1, 1740, 160, ImmutableSet
|
return ImmutableSet.of(new StubSize("small", 1, 1740, 160, ImmutableSet
|
||||||
.of(Architecture.X86_32)), new StubSize("medium", 4, 7680, 850, ImmutableSet
|
.of(Architecture.X86_32)), new StubSize("medium", 4, 7680, 850,
|
||||||
.of(Architecture.X86_64)), new StubSize("large", 8, 15360, 1690, ImmutableSet
|
ImmutableSet.of(Architecture.X86_64)), new StubSize("large", 8,
|
||||||
.of(Architecture.X86_64)));
|
15360, 1690, ImmutableSet.of(Architecture.X86_64)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class StubSize extends org.jclouds.compute.domain.internal.SizeImpl {
|
private static class StubSize extends
|
||||||
|
org.jclouds.compute.domain.internal.SizeImpl {
|
||||||
/** The serialVersionUID */
|
/** The serialVersionUID */
|
||||||
private static final long serialVersionUID = -1842135761654973637L;
|
private static final long serialVersionUID = -1842135761654973637L;
|
||||||
|
|
||||||
StubSize(String type, int cores, int ram, int disk,
|
StubSize(String type, int cores, int ram, int disk,
|
||||||
Iterable<Architecture> supportedArchitectures) {
|
Iterable<Architecture> supportedArchitectures) {
|
||||||
super(type, type, type, null, null, ImmutableMap.<String, String> of(), cores, ram, disk,
|
super(type, type, type, null, null,
|
||||||
|
ImmutableMap.<String, String> of(), cores, ram, disk,
|
||||||
architectureIn(supportedArchitectures));
|
architectureIn(supportedArchitectures));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -416,21 +416,24 @@ public class StubComputeServiceContextModule extends AbstractModule {
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
protected Set<? extends Image> provideImages(Location defaultLocation) {
|
protected Set<? extends Image> provideImages(Location defaultLocation) {
|
||||||
return ImmutableSet.of(new ImageImpl("1", OsFamily.UBUNTU.name(), "1", defaultLocation, null,
|
return ImmutableSet.of(new ImageImpl("1", OsFamily.UBUNTU.name(), "1",
|
||||||
ImmutableMap.<String, String> of(), "stub ubuntu 32", "", OsFamily.UBUNTU,
|
defaultLocation, null, ImmutableMap.<String, String> of(),
|
||||||
"ubuntu 64", Architecture.X86_64, new Credentials("root", null)), new ImageImpl("2",
|
"stub ubuntu 32", "", OsFamily.UBUNTU, "ubuntu 64",
|
||||||
OsFamily.UBUNTU.name(), "2", defaultLocation, null, ImmutableMap
|
Architecture.X86_64, new Credentials("root", null)), new ImageImpl(
|
||||||
.<String, String> of(), "stub ubuntu 64", "", OsFamily.UBUNTU, "ubuntu 64",
|
"2", OsFamily.UBUNTU.name(), "2", defaultLocation, null,
|
||||||
Architecture.X86_64, new Credentials("root", null)), new ImageImpl("3",
|
ImmutableMap.<String, String> of(), "stub ubuntu 64", "",
|
||||||
OsFamily.CENTOS.name(), "3", defaultLocation, null, ImmutableMap
|
OsFamily.UBUNTU, "ubuntu 64", Architecture.X86_64, new Credentials(
|
||||||
.<String, String> of(), "stub centos 64", "", OsFamily.CENTOS, "centos 64",
|
"root", null)), new ImageImpl("3", OsFamily.CENTOS.name(),
|
||||||
|
"3", defaultLocation, null, ImmutableMap.<String, String> of(),
|
||||||
|
"stub centos 64", "", OsFamily.CENTOS, "centos 64",
|
||||||
Architecture.X86_64, new Credentials("root", null)));
|
Architecture.X86_64, new Credentials("root", null)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
Location getLocation() {
|
Location getLocation() {
|
||||||
Location provider = new LocationImpl(LocationScope.PROVIDER, providerName, providerName, null);
|
Location provider = new LocationImpl(LocationScope.PROVIDER,
|
||||||
|
providerName, providerName, null);
|
||||||
return new LocationImpl(LocationScope.ZONE, "memory", "memory", provider);
|
return new LocationImpl(LocationScope.ZONE, "memory", "memory", provider);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,7 @@ import org.jclouds.compute.domain.internal.NodeMetadataImpl;
|
||||||
import org.jclouds.compute.options.TemplateOptions;
|
import org.jclouds.compute.options.TemplateOptions;
|
||||||
import org.jclouds.compute.predicates.ScriptStatusReturnsZero.CommandUsingClient;
|
import org.jclouds.compute.predicates.ScriptStatusReturnsZero.CommandUsingClient;
|
||||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||||
|
import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
|
||||||
import org.jclouds.concurrent.ConcurrentUtils;
|
import org.jclouds.concurrent.ConcurrentUtils;
|
||||||
import org.jclouds.domain.Credentials;
|
import org.jclouds.domain.Credentials;
|
||||||
import org.jclouds.logging.Logger;
|
import org.jclouds.logging.Logger;
|
||||||
|
@ -82,22 +83,30 @@ public class ComputeUtils {
|
||||||
protected final Predicate<CommandUsingClient> runScriptNotRunning;
|
protected final Predicate<CommandUsingClient> runScriptNotRunning;
|
||||||
private final Predicate<IPSocket> socketTester;
|
private final Predicate<IPSocket> socketTester;
|
||||||
private final ExecutorService executor;
|
private final ExecutorService executor;
|
||||||
|
protected final Predicate<NodeMetadata> nodeRunning;
|
||||||
|
private final GetNodeMetadataStrategy getNode;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public ComputeUtils(Predicate<IPSocket> socketTester,
|
public ComputeUtils(
|
||||||
@Named("NOT_RUNNING") Predicate<CommandUsingClient> runScriptNotRunning,
|
Predicate<IPSocket> socketTester,
|
||||||
|
@Named("SCRIPT_COMPLETE") Predicate<CommandUsingClient> runScriptNotRunning,
|
||||||
|
GetNodeMetadataStrategy getNode,
|
||||||
|
@Named("NODE_RUNNING") Predicate<NodeMetadata> nodeRunning,
|
||||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) {
|
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) {
|
||||||
|
this.nodeRunning = nodeRunning;
|
||||||
|
this.getNode = getNode;
|
||||||
this.socketTester = socketTester;
|
this.socketTester = socketTester;
|
||||||
this.runScriptNotRunning = runScriptNotRunning;
|
this.runScriptNotRunning = runScriptNotRunning;
|
||||||
this.executor = executor;
|
this.executor = executor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String createExecutionErrorMessage(Map<?, Exception> executionExceptions) {
|
public static String createExecutionErrorMessage(
|
||||||
|
Map<?, Exception> executionExceptions) {
|
||||||
Formatter fmt = new Formatter().format("Execution failures:%n%n");
|
Formatter fmt = new Formatter().format("Execution failures:%n%n");
|
||||||
int index = 1;
|
int index = 1;
|
||||||
for (Entry<?, Exception> errorMessage : executionExceptions.entrySet()) {
|
for (Entry<?, Exception> errorMessage : executionExceptions.entrySet()) {
|
||||||
fmt.format("%s) %s on %s:%n%s%n%n", index++, errorMessage.getValue().getClass()
|
fmt.format("%s) %s on %s:%n%s%n%n", index++, errorMessage.getValue()
|
||||||
.getSimpleName(), errorMessage.getKey(), Throwables
|
.getClass().getSimpleName(), errorMessage.getKey(), Throwables
|
||||||
.getStackTraceAsString(errorMessage.getValue()));
|
.getStackTraceAsString(errorMessage.getValue()));
|
||||||
}
|
}
|
||||||
return fmt.format("%s error[s]", executionExceptions.size()).toString();
|
return fmt.format("%s error[s]", executionExceptions.size()).toString();
|
||||||
|
@ -105,12 +114,13 @@ public class ComputeUtils {
|
||||||
|
|
||||||
public Map<?, ListenableFuture<Void>> runOptionsOnNodesAndAddToGoodSetOrPutExceptionIntoBadMap(
|
public Map<?, ListenableFuture<Void>> runOptionsOnNodesAndAddToGoodSetOrPutExceptionIntoBadMap(
|
||||||
final TemplateOptions options, Iterable<NodeMetadata> runningNodes,
|
final TemplateOptions options, Iterable<NodeMetadata> runningNodes,
|
||||||
final Set<NodeMetadata> goodNodes, final Map<NodeMetadata, Exception> badNodes) {
|
final Set<NodeMetadata> goodNodes,
|
||||||
|
final Map<NodeMetadata, Exception> badNodes) {
|
||||||
Map<NodeMetadata, ListenableFuture<Void>> responses = Maps.newHashMap();
|
Map<NodeMetadata, ListenableFuture<Void>> responses = Maps.newHashMap();
|
||||||
for (final NodeMetadata node : runningNodes) {
|
for (final NodeMetadata node : runningNodes) {
|
||||||
responses.put(node, makeListenable(executor
|
responses.put(node, makeListenable(executor
|
||||||
.submit(runOptionsOnNodeAndAddToGoodSetOrPutExceptionIntoBadMap(node, badNodes,
|
.submit(runOptionsOnNodeAndAddToGoodSetOrPutExceptionIntoBadMap(
|
||||||
goodNodes, options)), executor));
|
node, badNodes, goodNodes, options)), executor));
|
||||||
}
|
}
|
||||||
return responses;
|
return responses;
|
||||||
}
|
}
|
||||||
|
@ -122,12 +132,12 @@ public class ComputeUtils {
|
||||||
@Override
|
@Override
|
||||||
public Void call() throws Exception {
|
public Void call() throws Exception {
|
||||||
try {
|
try {
|
||||||
runOptionsOnNode(node, options);
|
NodeMetadata node1 = runOptionsOnNode(node, options);
|
||||||
logger.debug("<< options applied node(%s)", node.getProviderId());
|
logger.debug("<< options applied node(%s)", node1.getId());
|
||||||
goodNodes.add(node);
|
goodNodes.add(node1);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.error(e, "<< problem applying options to node(%s): ", node.getProviderId(),
|
logger.error(e, "<< problem applying options to node(%s): ",
|
||||||
Throwables.getRootCause(e).getMessage());
|
node.getId(), Throwables.getRootCause(e).getMessage());
|
||||||
badNodes.put(node, e);
|
badNodes.put(node, e);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
@ -139,10 +149,12 @@ public class ComputeUtils {
|
||||||
Map<? extends NodeMetadata, ? extends Throwable> failedNodes) {
|
Map<? extends NodeMetadata, ? extends Throwable> failedNodes) {
|
||||||
Formatter fmt = new Formatter().format("Node failures:%n%n");
|
Formatter fmt = new Formatter().format("Node failures:%n%n");
|
||||||
int index = 1;
|
int index = 1;
|
||||||
for (Entry<? extends NodeMetadata, ? extends Throwable> errorMessage : failedNodes.entrySet()) {
|
for (Entry<? extends NodeMetadata, ? extends Throwable> errorMessage : failedNodes
|
||||||
fmt.format("%s) %s on node %s:%n%s%n%n", index++, errorMessage.getValue().getClass()
|
.entrySet()) {
|
||||||
.getSimpleName(), errorMessage.getKey().getProviderId(), Throwables
|
fmt.format("%s) %s on node %s:%n%s%n%n", index++, errorMessage
|
||||||
.getStackTraceAsString(errorMessage.getValue()));
|
.getValue().getClass().getSimpleName(), errorMessage.getKey()
|
||||||
|
.getId(), Throwables.getStackTraceAsString(errorMessage
|
||||||
|
.getValue()));
|
||||||
}
|
}
|
||||||
return fmt.format("%s error[s]", failedNodes.size()).toString();
|
return fmt.format("%s error[s]", failedNodes.size()).toString();
|
||||||
}
|
}
|
||||||
|
@ -157,26 +169,41 @@ public class ComputeUtils {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void runOptionsOnNode(NodeMetadata node, TemplateOptions options) {
|
public NodeMetadata runOptionsOnNode(NodeMetadata node,
|
||||||
|
TemplateOptions options) {
|
||||||
|
if (!options.shouldBlockUntilRunning())
|
||||||
|
return node;
|
||||||
|
|
||||||
|
if (nodeRunning.apply(node))
|
||||||
|
node = installNewCredentials(getNode.execute(node.getId()), node
|
||||||
|
.getCredentials());
|
||||||
|
else
|
||||||
|
throw new IllegalStateException(
|
||||||
|
"node didn't achieve the state running: " + node);
|
||||||
|
|
||||||
List<SshCallable<?>> callables = Lists.newArrayList();
|
List<SshCallable<?>> callables = Lists.newArrayList();
|
||||||
if (options.getRunScript() != null) {
|
if (options.getRunScript() != null) {
|
||||||
callables.add(runScriptOnNode(node, "runscript", options.getRunScript()));
|
callables.add(runScriptOnNode(node, "runscript", options
|
||||||
|
.getRunScript()));
|
||||||
}
|
}
|
||||||
if (options.getPublicKey() != null) {
|
if (options.getPublicKey() != null) {
|
||||||
callables.add(authorizeKeyOnNode(node, options.getPublicKey()));
|
callables.add(authorizeKeyOnNode(node, options.getPublicKey()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// changing the key "MUST" come last or else the other commands may fail.
|
// changing the key "MUST" come last or else the other commands may
|
||||||
|
// fail.
|
||||||
if (callables.size() > 0 || options.getPrivateKey() != null) {
|
if (callables.size() > 0 || options.getPrivateKey() != null) {
|
||||||
runCallablesOnNode(node, callables, options.getPrivateKey() != null ? installKeyOnNode(
|
runCallablesOnNode(node, callables,
|
||||||
node, options.getPrivateKey()) : null);
|
options.getPrivateKey() != null ? installKeyOnNode(node, options
|
||||||
|
.getPrivateKey()) : null);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.getPort() > 0) {
|
if (options.getPort() > 0) {
|
||||||
checkNodeHasPublicIps(node);
|
checkNodeHasPublicIps(node);
|
||||||
blockUntilPortIsListeningOnPublicIp(options.getPort(), options.getSeconds(), Iterables
|
blockUntilPortIsListeningOnPublicIp(options.getPort(), options
|
||||||
.get(node.getPublicAddresses(), 0));
|
.getSeconds(), Iterables.get(node.getPublicAddresses(), 0));
|
||||||
}
|
}
|
||||||
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkNodeHasPublicIps(NodeMetadata node) {
|
private void checkNodeHasPublicIps(NodeMetadata node) {
|
||||||
|
@ -184,40 +211,50 @@ public class ComputeUtils {
|
||||||
"node does not have IP addresses configured: " + node);
|
"node does not have IP addresses configured: " + node);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void blockUntilPortIsListeningOnPublicIp(int port, int seconds, String inetAddress) {
|
private void blockUntilPortIsListeningOnPublicIp(int port, int seconds,
|
||||||
logger.debug(">> blocking on port %s:%d for %d seconds", inetAddress, port, seconds);
|
String inetAddress) {
|
||||||
RetryablePredicate<IPSocket> tester = new RetryablePredicate<IPSocket>(socketTester, seconds,
|
logger.debug(">> blocking on port %s:%d for %d seconds", inetAddress,
|
||||||
1, TimeUnit.SECONDS);
|
port, seconds);
|
||||||
|
RetryablePredicate<IPSocket> tester = new RetryablePredicate<IPSocket>(
|
||||||
|
socketTester, seconds, 1, TimeUnit.SECONDS);
|
||||||
IPSocket socket = new IPSocket(inetAddress, port);
|
IPSocket socket = new IPSocket(inetAddress, port);
|
||||||
boolean passed = tester.apply(socket);
|
boolean passed = tester.apply(socket);
|
||||||
if (passed)
|
if (passed)
|
||||||
logger.debug("<< port %s:%d opened", inetAddress, port);
|
logger.debug("<< port %s:%d opened", inetAddress, port);
|
||||||
else
|
else
|
||||||
logger.warn("<< port %s:%d didn't open after %d seconds", inetAddress, port, seconds);
|
logger.warn("<< port %s:%d didn't open after %d seconds", inetAddress,
|
||||||
|
port, seconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
public InstallRSAPrivateKey installKeyOnNode(NodeMetadata node, String privateKey) {
|
public InstallRSAPrivateKey installKeyOnNode(NodeMetadata node,
|
||||||
|
String privateKey) {
|
||||||
return new InstallRSAPrivateKey(node, privateKey);
|
return new InstallRSAPrivateKey(node, privateKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
public AuthorizeRSAPublicKey authorizeKeyOnNode(NodeMetadata node, String publicKey) {
|
public AuthorizeRSAPublicKey authorizeKeyOnNode(NodeMetadata node,
|
||||||
|
String publicKey) {
|
||||||
return new AuthorizeRSAPublicKey(node, publicKey);
|
return new AuthorizeRSAPublicKey(node, publicKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
public RunScriptOnNode runScriptOnNode(NodeMetadata node, String scriptName, byte[] script) {
|
public RunScriptOnNode runScriptOnNode(NodeMetadata node, String scriptName,
|
||||||
|
byte[] script) {
|
||||||
return new RunScriptOnNode(runScriptNotRunning, node, scriptName, script);
|
return new RunScriptOnNode(runScriptNotRunning, node, scriptName, script);
|
||||||
}
|
}
|
||||||
|
|
||||||
public RunScriptOnNode runScriptOnNodeAsDefaultUser(NodeMetadata node, String scriptName,
|
public RunScriptOnNode runScriptOnNodeAsDefaultUser(NodeMetadata node,
|
||||||
byte[] script) {
|
String scriptName, byte[] script) {
|
||||||
return new RunScriptOnNode(runScriptNotRunning, node, scriptName, script, false);
|
return new RunScriptOnNode(runScriptNotRunning, node, scriptName, script,
|
||||||
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<SshCallable<?>, ?> runCallablesOnNode(NodeMetadata node,
|
public Map<SshCallable<?>, ?> runCallablesOnNode(NodeMetadata node,
|
||||||
Iterable<? extends SshCallable<?>> parallel, @Nullable SshCallable<?> last) {
|
Iterable<? extends SshCallable<?>> parallel,
|
||||||
checkState(this.sshFactory != null, "runScript requested, but no SshModule configured");
|
@Nullable SshCallable<?> last) {
|
||||||
|
checkState(this.sshFactory != null,
|
||||||
|
"runScript requested, but no SshModule configured");
|
||||||
checkNodeHasPublicIps(node);
|
checkNodeHasPublicIps(node);
|
||||||
checkNotNull(node.getCredentials().key, "credentials.key for node " + node.getProviderId());
|
checkNotNull(node.getCredentials().key, "credentials.key for node "
|
||||||
|
+ node.getId());
|
||||||
SshClient ssh = createSshClientOncePortIsListeningOnNode(node);
|
SshClient ssh = createSshClientOncePortIsListeningOnNode(node);
|
||||||
try {
|
try {
|
||||||
ssh.connect();
|
ssh.connect();
|
||||||
|
@ -229,7 +266,8 @@ public class ComputeUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<SshCallable<?>, ?> runTasksUsingSshClient(
|
private Map<SshCallable<?>, ?> runTasksUsingSshClient(
|
||||||
Iterable<? extends SshCallable<?>> parallel, SshCallable<?> last, SshClient ssh) {
|
Iterable<? extends SshCallable<?>> parallel, SshCallable<?> last,
|
||||||
|
SshClient ssh) {
|
||||||
Map<SshCallable<?>, Object> responses = Maps.newHashMap();
|
Map<SshCallable<?>, Object> responses = Maps.newHashMap();
|
||||||
if (Iterables.size(parallel) > 0) {
|
if (Iterables.size(parallel) > 0) {
|
||||||
responses.putAll(runCallablesUsingSshClient(parallel, ssh));
|
responses.putAll(runCallablesUsingSshClient(parallel, ssh));
|
||||||
|
@ -246,37 +284,42 @@ public class ComputeUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
public SshClient createSshClientOncePortIsListeningOnNode(NodeMetadata node) {
|
public SshClient createSshClientOncePortIsListeningOnNode(NodeMetadata node) {
|
||||||
IPSocket socket = new IPSocket(Iterables.get(node.getPublicAddresses(), 0), 22);
|
IPSocket socket = new IPSocket(Iterables
|
||||||
|
.get(node.getPublicAddresses(), 0), 22);
|
||||||
socketTester.apply(socket);
|
socketTester.apply(socket);
|
||||||
SshClient ssh = isKeyAuth(node) ? sshFactory.create(socket, node.getCredentials().account,
|
SshClient ssh = isKeyAuth(node) ? sshFactory.create(socket, node
|
||||||
node.getCredentials().key.getBytes()) : sshFactory.create(socket, node
|
.getCredentials().account, node.getCredentials().key.getBytes())
|
||||||
.getCredentials().account, node.getCredentials().key);
|
: sshFactory.create(socket, node.getCredentials().account, node
|
||||||
|
.getCredentials().key);
|
||||||
return ssh;
|
return ssh;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<SshCallable<?>, Object> runCallablesUsingSshClient(
|
private Map<SshCallable<?>, Object> runCallablesUsingSshClient(
|
||||||
Iterable<? extends SshCallable<?>> parallel, SshClient ssh) {
|
Iterable<? extends SshCallable<?>> parallel, SshClient ssh) {
|
||||||
Map<SshCallable<?>, ListenableFuture<?>> parallelResponses = Maps.newHashMap();
|
Map<SshCallable<?>, ListenableFuture<?>> parallelResponses = Maps
|
||||||
|
.newHashMap();
|
||||||
|
|
||||||
for (SshCallable<?> callable : parallel) {
|
for (SshCallable<?> callable : parallel) {
|
||||||
callable.setConnection(ssh, logger);
|
callable.setConnection(ssh, logger);
|
||||||
parallelResponses.put(callable, ConcurrentUtils.makeListenable(executor.submit(callable),
|
parallelResponses.put(callable, ConcurrentUtils.makeListenable(
|
||||||
executor));
|
executor.submit(callable), executor));
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<SshCallable<?>, Exception> exceptions = awaitCompletion(parallelResponses, executor,
|
Map<SshCallable<?>, Exception> exceptions = awaitCompletion(
|
||||||
null, logger, "ssh");
|
parallelResponses, executor, null, logger, "ssh");
|
||||||
if (exceptions.size() > 0)
|
if (exceptions.size() > 0)
|
||||||
throw new RuntimeException(String.format("error invoking callables on nodes: %s",
|
throw new RuntimeException(String.format(
|
||||||
exceptions));
|
"error invoking callables on nodes: %s", exceptions));
|
||||||
Map<SshCallable<?>, Object> newresponses = transform(parallelResponses);
|
Map<SshCallable<?>, Object> newresponses = transform(parallelResponses);
|
||||||
return newresponses;
|
return newresponses;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public <T> Map<SshCallable<?>, T> transform(Map<SshCallable<?>, ListenableFuture<?>> responses) {
|
public <T> Map<SshCallable<?>, T> transform(
|
||||||
|
Map<SshCallable<?>, ListenableFuture<?>> responses) {
|
||||||
Map<SshCallable<?>, T> actualResponses = Maps.newHashMap();
|
Map<SshCallable<?>, T> actualResponses = Maps.newHashMap();
|
||||||
for (Map.Entry<SshCallable<?>, ListenableFuture<?>> entry : responses.entrySet()) {
|
for (Map.Entry<SshCallable<?>, ListenableFuture<?>> entry : responses
|
||||||
|
.entrySet()) {
|
||||||
try {
|
try {
|
||||||
actualResponses.put(entry.getKey(), (T) entry.getValue().get());
|
actualResponses.put(entry.getKey(), (T) entry.getValue().get());
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
|
@ -303,20 +346,24 @@ public class ComputeUtils {
|
||||||
private final boolean runAsRoot;
|
private final boolean runAsRoot;
|
||||||
private Logger logger = Logger.NULL;
|
private Logger logger = Logger.NULL;
|
||||||
|
|
||||||
RunScriptOnNode(@Named("NOT_RUNNING") Predicate<CommandUsingClient> runScriptNotRunning,
|
RunScriptOnNode(
|
||||||
|
@Named("SCRIPT_COMPLETE") Predicate<CommandUsingClient> runScriptNotRunning,
|
||||||
NodeMetadata node, String scriptName, byte[] script) {
|
NodeMetadata node, String scriptName, byte[] script) {
|
||||||
this(runScriptNotRunning, node, scriptName, script, true);
|
this(runScriptNotRunning, node, scriptName, script, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
RunScriptOnNode(@Named("NOT_RUNNING") Predicate<CommandUsingClient> runScriptNotRunning,
|
RunScriptOnNode(
|
||||||
NodeMetadata node, String scriptName, byte[] script, boolean runAsRoot) {
|
@Named("SCRIPT_COMPLETE") Predicate<CommandUsingClient> runScriptNotRunning,
|
||||||
|
NodeMetadata node, String scriptName, byte[] script,
|
||||||
|
boolean runAsRoot) {
|
||||||
this.runScriptNotRunning = runScriptNotRunning;
|
this.runScriptNotRunning = runScriptNotRunning;
|
||||||
this.node = checkNotNull(node, "node");
|
this.node = checkNotNull(node, "node");
|
||||||
this.scriptName = checkNotNull(scriptName, "scriptName");
|
this.scriptName = checkNotNull(scriptName, "scriptName");
|
||||||
this.script = new InitBuilder(scriptName, "/tmp/" + scriptName, "/tmp/" + scriptName,
|
this.script = new InitBuilder(scriptName, "/tmp/" + scriptName,
|
||||||
ImmutableMap.<String, String> of(), Iterables.toArray(Splitter.on("\n").split(
|
"/tmp/" + scriptName, ImmutableMap.<String, String> of(),
|
||||||
new String(checkNotNull(script, "script"))), String.class)).build(
|
Iterables.toArray(Splitter.on("\n").split(
|
||||||
OsFamily.UNIX).getBytes();
|
new String(checkNotNull(script, "script"))), String.class))
|
||||||
|
.build(OsFamily.UNIX).getBytes();
|
||||||
this.runAsRoot = runAsRoot;
|
this.runAsRoot = runAsRoot;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -330,15 +377,18 @@ public class ComputeUtils {
|
||||||
returnVal = runScriptAsRoot();
|
returnVal = runScriptAsRoot();
|
||||||
else
|
else
|
||||||
returnVal = runScriptAsDefaultUser();
|
returnVal = runScriptAsDefaultUser();
|
||||||
runScriptNotRunning.apply(new CommandUsingClient("./" + scriptName + " status", ssh));
|
runScriptNotRunning.apply(new CommandUsingClient("./" + scriptName
|
||||||
|
+ " status", ssh));
|
||||||
logger.debug("<< complete(%d)", returnVal.getExitCode());
|
logger.debug("<< complete(%d)", returnVal.getExitCode());
|
||||||
if (logger.isDebugEnabled() || returnVal.getExitCode() != 0) {
|
if (logger.isDebugEnabled() || returnVal.getExitCode() != 0) {
|
||||||
logger.debug("<< stdout from %s as %s@%s\n%s", scriptName,
|
logger.debug("<< stdout from %s as %s@%s\n%s", scriptName, node
|
||||||
node.getCredentials().account, Iterables.get(node.getPublicAddresses(), 0),
|
.getCredentials().account, Iterables.get(node
|
||||||
ssh.exec("./" + scriptName + " tail").getOutput());
|
.getPublicAddresses(), 0), ssh.exec(
|
||||||
logger.debug("<< stderr from %s as %s@%s\n%s", scriptName,
|
"./" + scriptName + " tail").getOutput());
|
||||||
node.getCredentials().account, Iterables.get(node.getPublicAddresses(), 0),
|
logger.debug("<< stderr from %s as %s@%s\n%s", scriptName, node
|
||||||
ssh.exec("./" + scriptName + " tailerr").getOutput());
|
.getCredentials().account, Iterables.get(node
|
||||||
|
.getPublicAddresses(), 0), ssh.exec(
|
||||||
|
"./" + scriptName + " tailerr").getOutput());
|
||||||
}
|
}
|
||||||
return returnVal;
|
return returnVal;
|
||||||
}
|
}
|
||||||
|
@ -351,24 +401,28 @@ public class ComputeUtils {
|
||||||
|
|
||||||
private ExecResponse runScriptAsRoot() {
|
private ExecResponse runScriptAsRoot() {
|
||||||
if (node.getCredentials().account.equals("root")) {
|
if (node.getCredentials().account.equals("root")) {
|
||||||
logger.debug(">> running %s as %s@%s", scriptName, node.getCredentials().account,
|
logger.debug(">> running %s as %s@%s", scriptName, node
|
||||||
Iterables.get(node.getPublicAddresses(), 0));
|
.getCredentials().account, Iterables.get(node
|
||||||
|
.getPublicAddresses(), 0));
|
||||||
return ssh.exec("./" + scriptName + " start");
|
return ssh.exec("./" + scriptName + " start");
|
||||||
} else if (isKeyAuth(node)) {
|
} else if (isKeyAuth(node)) {
|
||||||
logger.debug(">> running sudo %s as %s@%s", scriptName, node.getCredentials().account,
|
logger.debug(">> running sudo %s as %s@%s", scriptName, node
|
||||||
Iterables.get(node.getPublicAddresses(), 0));
|
.getCredentials().account, Iterables.get(node
|
||||||
|
.getPublicAddresses(), 0));
|
||||||
return ssh.exec("sudo ./" + scriptName + " start");
|
return ssh.exec("sudo ./" + scriptName + " start");
|
||||||
} else {
|
} else {
|
||||||
logger.debug(">> running sudo -S %s as %s@%s", scriptName,
|
logger.debug(">> running sudo -S %s as %s@%s", scriptName, node
|
||||||
node.getCredentials().account, Iterables.get(node.getPublicAddresses(), 0));
|
.getCredentials().account, Iterables.get(node
|
||||||
return ssh.exec(String.format("echo '%s'|sudo -S ./%s", node.getCredentials().key,
|
.getPublicAddresses(), 0));
|
||||||
scriptName + " start"));
|
return ssh.exec(String.format("echo '%s'|sudo -S ./%s", node
|
||||||
|
.getCredentials().key, scriptName + " start"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private ExecResponse runScriptAsDefaultUser() {
|
private ExecResponse runScriptAsDefaultUser() {
|
||||||
logger.debug(">> running script %s as %s@%s", scriptName, node.getCredentials().account,
|
logger.debug(">> running script %s as %s@%s", scriptName, node
|
||||||
Iterables.get(node.getPublicAddresses(), 0));
|
.getCredentials().account, Iterables.get(node
|
||||||
|
.getPublicAddresses(), 0));
|
||||||
return ssh.exec(String.format("./%s", scriptName + " start"));
|
return ssh.exec(String.format("./%s", scriptName + " start"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -378,7 +432,8 @@ public class ComputeUtils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class InstallRSAPrivateKey implements SshCallable<ExecResponse> {
|
public static class InstallRSAPrivateKey implements
|
||||||
|
SshCallable<ExecResponse> {
|
||||||
private SshClient ssh;
|
private SshClient ssh;
|
||||||
private final NodeMetadata node;
|
private final NodeMetadata node;
|
||||||
private final String privateKey;
|
private final String privateKey;
|
||||||
|
@ -393,9 +448,12 @@ public class ComputeUtils {
|
||||||
@Override
|
@Override
|
||||||
public ExecResponse call() throws Exception {
|
public ExecResponse call() throws Exception {
|
||||||
ssh.exec("mkdir .ssh");
|
ssh.exec("mkdir .ssh");
|
||||||
ssh.put(".ssh/id_rsa", new ByteArrayInputStream(privateKey.getBytes()));
|
ssh
|
||||||
logger.debug(">> installing rsa key for %s@%s", node.getCredentials().account, Iterables
|
.put(".ssh/id_rsa", new ByteArrayInputStream(privateKey
|
||||||
.get(node.getPublicAddresses(), 0));
|
.getBytes()));
|
||||||
|
logger.debug(">> installing rsa key for %s@%s",
|
||||||
|
node.getCredentials().account, Iterables.get(node
|
||||||
|
.getPublicAddresses(), 0));
|
||||||
return ssh.exec("chmod 600 .ssh/id_rsa");
|
return ssh.exec("chmod 600 .ssh/id_rsa");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -411,7 +469,8 @@ public class ComputeUtils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class AuthorizeRSAPublicKey implements SshCallable<ExecResponse> {
|
public static class AuthorizeRSAPublicKey implements
|
||||||
|
SshCallable<ExecResponse> {
|
||||||
private SshClient ssh;
|
private SshClient ssh;
|
||||||
private final NodeMetadata node;
|
private final NodeMetadata node;
|
||||||
private final String publicKey;
|
private final String publicKey;
|
||||||
|
@ -426,10 +485,13 @@ public class ComputeUtils {
|
||||||
@Override
|
@Override
|
||||||
public ExecResponse call() throws Exception {
|
public ExecResponse call() throws Exception {
|
||||||
ssh.exec("mkdir .ssh");
|
ssh.exec("mkdir .ssh");
|
||||||
ssh.put(".ssh/id_rsa.pub", new ByteArrayInputStream(publicKey.getBytes()));
|
ssh.put(".ssh/id_rsa.pub", new ByteArrayInputStream(publicKey
|
||||||
logger.debug(">> authorizing rsa public key for %s@%s", node.getCredentials().account,
|
.getBytes()));
|
||||||
Iterables.get(node.getPublicAddresses(), 0));
|
logger.debug(">> authorizing rsa public key for %s@%s", node
|
||||||
ExecResponse returnVal = ssh.exec("cat .ssh/id_rsa.pub >> .ssh/authorized_keys");
|
.getCredentials().account, Iterables.get(node
|
||||||
|
.getPublicAddresses(), 0));
|
||||||
|
ExecResponse returnVal = ssh
|
||||||
|
.exec("cat .ssh/id_rsa.pub >> .ssh/authorized_keys");
|
||||||
returnVal = ssh.exec("chmod 600 .ssh/authorized_keys");
|
returnVal = ssh.exec("chmod 600 .ssh/authorized_keys");
|
||||||
logger.debug("<< complete(%d)", returnVal.getExitCode());
|
logger.debug("<< complete(%d)", returnVal.getExitCode());
|
||||||
return returnVal;
|
return returnVal;
|
||||||
|
@ -449,25 +511,30 @@ public class ComputeUtils {
|
||||||
|
|
||||||
public static boolean isKeyAuth(NodeMetadata createdNode) {
|
public static boolean isKeyAuth(NodeMetadata createdNode) {
|
||||||
return createdNode.getCredentials().key != null
|
return createdNode.getCredentials().key != null
|
||||||
&& createdNode.getCredentials().key.startsWith("-----BEGIN RSA PRIVATE KEY-----");
|
&& createdNode.getCredentials().key
|
||||||
|
.startsWith("-----BEGIN RSA PRIVATE KEY-----");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given the instances of {@link NodeMetadata} (immutable) and {@link Credentials} (immutable),
|
* Given the instances of {@link NodeMetadata} (immutable) and
|
||||||
* returns a new instance of {@link NodeMetadata} that has new credentials
|
* {@link Credentials} (immutable), returns a new instance of
|
||||||
|
* {@link NodeMetadata} that has new credentials
|
||||||
*/
|
*/
|
||||||
public static NodeMetadata installNewCredentials(NodeMetadata node, Credentials newCredentials) {
|
public static NodeMetadata installNewCredentials(NodeMetadata node,
|
||||||
return new NodeMetadataImpl(node.getProviderId(), node.getName(), node.getId(), node
|
Credentials newCredentials) {
|
||||||
.getLocation(), node.getUri(), node.getUserMetadata(), node.getTag(), node
|
return new NodeMetadataImpl(node.getProviderId(), node.getName(), node
|
||||||
.getImage(), node.getState(), node.getPublicAddresses(), node.getPrivateAddresses(),
|
.getId(), node.getLocation(), node.getUri(),
|
||||||
node.getExtra(), newCredentials);
|
node.getUserMetadata(), node.getTag(), node.getImage(), node
|
||||||
|
.getState(), node.getPublicAddresses(), node
|
||||||
|
.getPrivateAddresses(), node.getExtra(), newCredentials);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a set of supported providers. Idea stolen from pallets (supported-clouds). Uses
|
* Gets a set of supported providers. Idea stolen from pallets
|
||||||
* compute.properties to populate the set.
|
* (supported-clouds). Uses compute.properties to populate the set.
|
||||||
*
|
*
|
||||||
* XXX: Pass in extra properties to support ones that aren't in compute.properties
|
* XXX: Pass in extra properties to support ones that aren't in
|
||||||
|
* compute.properties
|
||||||
*/
|
*/
|
||||||
public static Set<String> getSupportedProviders() {
|
public static Set<String> getSupportedProviders() {
|
||||||
Properties properties = new Properties();
|
Properties properties = new Properties();
|
||||||
|
@ -484,7 +551,8 @@ public class ComputeUtils {
|
||||||
for (Object key : keys) {
|
for (Object key : keys) {
|
||||||
String keyString = key.toString();
|
String keyString = key.toString();
|
||||||
if (keyString.endsWith(".contextbuilder")) {
|
if (keyString.endsWith(".contextbuilder")) {
|
||||||
providers.add(keyString.substring(0, keyString.length() - ".contextbuilder".length()));
|
providers.add(keyString.substring(0, keyString.length()
|
||||||
|
- ".contextbuilder".length()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return providers;
|
return providers;
|
||||||
|
|
|
@ -99,8 +99,8 @@ public abstract class BaseComputeServiceLiveTest {
|
||||||
protected Map<String, String> keyPair;
|
protected Map<String, String> keyPair;
|
||||||
|
|
||||||
@BeforeGroups(groups = { "integration", "live" })
|
@BeforeGroups(groups = { "integration", "live" })
|
||||||
public void setupClient() throws InterruptedException, ExecutionException, TimeoutException,
|
public void setupClient() throws InterruptedException, ExecutionException,
|
||||||
IOException {
|
TimeoutException, IOException {
|
||||||
if (tag == null)
|
if (tag == null)
|
||||||
tag = checkNotNull(service, "service");
|
tag = checkNotNull(service, "service");
|
||||||
setupCredentials();
|
setupCredentials();
|
||||||
|
@ -110,28 +110,33 @@ public abstract class BaseComputeServiceLiveTest {
|
||||||
Injector injector = createSshClientInjector();
|
Injector injector = createSshClientInjector();
|
||||||
sshFactory = injector.getInstance(SshClient.Factory.class);
|
sshFactory = injector.getInstance(SshClient.Factory.class);
|
||||||
SocketOpen socketOpen = injector.getInstance(SocketOpen.class);
|
SocketOpen socketOpen = injector.getInstance(SocketOpen.class);
|
||||||
socketTester = new RetryablePredicate<IPSocket>(socketOpen, 60, 1, TimeUnit.SECONDS);
|
socketTester = new RetryablePredicate<IPSocket>(socketOpen, 60, 1,
|
||||||
|
TimeUnit.SECONDS);
|
||||||
injector.injectMembers(socketOpen); // add logger
|
injector.injectMembers(socketOpen); // add logger
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setupKeyPair() throws FileNotFoundException, IOException {
|
protected void setupKeyPair() throws FileNotFoundException, IOException {
|
||||||
String secretKeyFile;
|
String secretKeyFile;
|
||||||
try {
|
try {
|
||||||
secretKeyFile = checkNotNull(System.getProperty("jclouds.test.ssh.keyfile"),
|
secretKeyFile = checkNotNull(System
|
||||||
|
.getProperty("jclouds.test.ssh.keyfile"),
|
||||||
"jclouds.test.ssh.keyfile");
|
"jclouds.test.ssh.keyfile");
|
||||||
} catch (NullPointerException e) {
|
} catch (NullPointerException e) {
|
||||||
secretKeyFile = System.getProperty("user.home") + "/.ssh/id_rsa";
|
secretKeyFile = System.getProperty("user.home") + "/.ssh/id_rsa";
|
||||||
}
|
}
|
||||||
checkSecretKeyFile(secretKeyFile);
|
checkSecretKeyFile(secretKeyFile);
|
||||||
String secret = Files.toString(new File(secretKeyFile), Charsets.UTF_8);
|
String secret = Files.toString(new File(secretKeyFile), Charsets.UTF_8);
|
||||||
assert secret.startsWith("-----BEGIN RSA PRIVATE KEY-----") : "invalid key:\n" + secret;
|
assert secret.startsWith("-----BEGIN RSA PRIVATE KEY-----") : "invalid key:\n"
|
||||||
keyPair = ImmutableMap.<String, String> of("private", secret, "public", Files.toString(
|
+ secret;
|
||||||
new File(secretKeyFile + ".pub"), Charsets.UTF_8));
|
keyPair = ImmutableMap.<String, String> of("private", secret, "public",
|
||||||
|
Files.toString(new File(secretKeyFile + ".pub"), Charsets.UTF_8));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setupCredentials() {
|
protected void setupCredentials() {
|
||||||
user = checkNotNull(System.getProperty("jclouds.test.user"), "jclouds.test.user");
|
user = checkNotNull(System.getProperty("jclouds.test.user"),
|
||||||
password = checkNotNull(System.getProperty("jclouds.test.key"), "jclouds.test.key");
|
"jclouds.test.user");
|
||||||
|
password = checkNotNull(System.getProperty("jclouds.test.key"),
|
||||||
|
"jclouds.test.key");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Injector createSshClientInjector() {
|
protected Injector createSshClientInjector() {
|
||||||
|
@ -141,16 +146,20 @@ public abstract class BaseComputeServiceLiveTest {
|
||||||
private void initializeContextAndClient() throws IOException {
|
private void initializeContextAndClient() throws IOException {
|
||||||
if (context != null)
|
if (context != null)
|
||||||
context.close();
|
context.close();
|
||||||
context = new ComputeServiceContextFactory().createContext(service, user, password,
|
context = new ComputeServiceContextFactory()
|
||||||
ImmutableSet.of(new Log4JLoggingModule(), getSshModule()));
|
.createContext(service, user, password, ImmutableSet.of(
|
||||||
|
new Log4JLoggingModule(), getSshModule()));
|
||||||
client = context.getComputeService();
|
client = context.getComputeService();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkSecretKeyFile(String secretKeyFile) throws FileNotFoundException {
|
private void checkSecretKeyFile(String secretKeyFile)
|
||||||
Utils.checkNotEmpty(secretKeyFile,
|
throws FileNotFoundException {
|
||||||
|
Utils
|
||||||
|
.checkNotEmpty(secretKeyFile,
|
||||||
"System property: [jclouds.test.ssh.keyfile] set to an empty string");
|
"System property: [jclouds.test.ssh.keyfile] set to an empty string");
|
||||||
if (!new File(secretKeyFile).exists()) {
|
if (!new File(secretKeyFile).exists()) {
|
||||||
throw new FileNotFoundException("secretKeyFile not found at: " + secretKeyFile);
|
throw new FileNotFoundException("secretKeyFile not found at: "
|
||||||
|
+ secretKeyFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,7 +184,8 @@ public abstract class BaseComputeServiceLiveTest {
|
||||||
// since surefire and eclipse don't otherwise guarantee the order, we are
|
// since surefire and eclipse don't otherwise guarantee the order, we are
|
||||||
// starting this one alphabetically before create2nodes..
|
// starting this one alphabetically before create2nodes..
|
||||||
@Test(enabled = true, dependsOnMethods = "testImagesCache")
|
@Test(enabled = true, dependsOnMethods = "testImagesCache")
|
||||||
public void testAScriptExecutionAfterBootWithBasicTemplate() throws Exception {
|
public void testAScriptExecutionAfterBootWithBasicTemplate()
|
||||||
|
throws Exception {
|
||||||
String tag = this.tag + "run";
|
String tag = this.tag + "run";
|
||||||
try {
|
try {
|
||||||
client.destroyNodesMatching(NodePredicates.withTag(tag));
|
client.destroyNodesMatching(NodePredicates.withTag(tag));
|
||||||
|
@ -185,18 +195,21 @@ public abstract class BaseComputeServiceLiveTest {
|
||||||
|
|
||||||
TemplateOptions options = client.templateOptions().blockOnPort(22, 120);
|
TemplateOptions options = client.templateOptions().blockOnPort(22, 120);
|
||||||
try {
|
try {
|
||||||
Set<? extends NodeMetadata> nodes = client.runNodesWithTag(tag, 1, options);
|
Set<? extends NodeMetadata> nodes = client.runNodesWithTag(tag, 1,
|
||||||
|
options);
|
||||||
Credentials good = nodes.iterator().next().getCredentials();
|
Credentials good = nodes.iterator().next().getCredentials();
|
||||||
assert good.account != null;
|
assert good.account != null;
|
||||||
assert good.key != null;
|
assert good.key != null;
|
||||||
|
|
||||||
Image image = Iterables.get(nodes, 0).getImage();
|
Image image = Iterables.get(nodes, 0).getImage();
|
||||||
try {
|
try {
|
||||||
Map<? extends NodeMetadata, ExecResponse> responses = runScriptWithCreds(tag, image
|
Map<? extends NodeMetadata, ExecResponse> responses = runScriptWithCreds(
|
||||||
.getOsFamily(), new Credentials(good.account, "romeo"));
|
tag, image.getOsFamily(), new Credentials(good.account,
|
||||||
|
"romeo"));
|
||||||
assert false : "shouldn't pass with a bad password\n" + responses;
|
assert false : "shouldn't pass with a bad password\n" + responses;
|
||||||
} catch (RunScriptOnNodesException e) {
|
} catch (RunScriptOnNodesException e) {
|
||||||
assert Throwables.getRootCause(e).getMessage().contains("Auth fail") : e;
|
assert Throwables.getRootCause(e).getMessage()
|
||||||
|
.contains("Auth fail") : e;
|
||||||
}
|
}
|
||||||
|
|
||||||
runScriptWithCreds(tag, image.getOsFamily(), good);
|
runScriptWithCreds(tag, image.getOsFamily(), good);
|
||||||
|
@ -211,7 +224,8 @@ public abstract class BaseComputeServiceLiveTest {
|
||||||
@Test(enabled = true, dependsOnMethods = "testImagesCache")
|
@Test(enabled = true, dependsOnMethods = "testImagesCache")
|
||||||
public void testTemplateMatch() throws Exception {
|
public void testTemplateMatch() throws Exception {
|
||||||
template = buildTemplate(client.templateBuilder());
|
template = buildTemplate(client.templateBuilder());
|
||||||
Template toMatch = client.templateBuilder().imageId(template.getImage().getId()).build();
|
Template toMatch = client.templateBuilder().imageId(
|
||||||
|
template.getImage().getId()).build();
|
||||||
assertEquals(toMatch.getImage(), template.getImage());
|
assertEquals(toMatch.getImage(), template.getImage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -226,14 +240,14 @@ public abstract class BaseComputeServiceLiveTest {
|
||||||
}
|
}
|
||||||
template = buildTemplate(client.templateBuilder());
|
template = buildTemplate(client.templateBuilder());
|
||||||
|
|
||||||
template.getOptions().installPrivateKey(keyPair.get("private")).authorizePublicKey(
|
template.getOptions().installPrivateKey(keyPair.get("private"))
|
||||||
keyPair.get("public")).runScript(
|
.authorizePublicKey(keyPair.get("public")).runScript(
|
||||||
buildScript(template.getImage().getOsFamily()).getBytes());
|
buildScript(template.getImage().getOsFamily()).getBytes());
|
||||||
try {
|
try {
|
||||||
nodes = Sets.newTreeSet(client.runNodesWithTag(tag, 2, template));
|
nodes = Sets.newTreeSet(client.runNodesWithTag(tag, 2, template));
|
||||||
} catch (RunNodesException e) {
|
} catch (RunNodesException e) {
|
||||||
nodes = Sets.newTreeSet(Iterables.concat(e.getSuccessfulNodes(), e.getNodeErrors()
|
nodes = Sets.newTreeSet(Iterables.concat(e.getSuccessfulNodes(), e
|
||||||
.keySet()));
|
.getNodeErrors().keySet()));
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
assertEquals(nodes.size(), 2);
|
assertEquals(nodes.size(), 2);
|
||||||
|
@ -260,9 +274,11 @@ public abstract class BaseComputeServiceLiveTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(enabled = true, dependsOnMethods = "testCreateTwoNodesWithRunScript")
|
@Test(enabled = true, dependsOnMethods = "testCreateTwoNodesWithRunScript")
|
||||||
public void testCreateAnotherNodeWithANewContextToEnsureSharedMemIsntRequired() throws Exception {
|
public void testCreateAnotherNodeWithANewContextToEnsureSharedMemIsntRequired()
|
||||||
|
throws Exception {
|
||||||
initializeContextAndClient();
|
initializeContextAndClient();
|
||||||
TreeSet<NodeMetadata> nodes = Sets.newTreeSet(client.runNodesWithTag(tag, 1, template));
|
TreeSet<NodeMetadata> nodes = Sets.newTreeSet(client.runNodesWithTag(tag,
|
||||||
|
1, template));
|
||||||
checkNodes(nodes, tag);
|
checkNodes(nodes, tag);
|
||||||
NodeMetadata node = nodes.first();
|
NodeMetadata node = nodes.first();
|
||||||
this.nodes.add(node);
|
this.nodes.add(node);
|
||||||
|
@ -271,28 +287,32 @@ public abstract class BaseComputeServiceLiveTest {
|
||||||
assertEquals(node.getImage(), template.getImage());
|
assertEquals(node.getImage(), template.getImage());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Map<? extends NodeMetadata, ExecResponse> runScriptWithCreds(final String tag,
|
protected Map<? extends NodeMetadata, ExecResponse> runScriptWithCreds(
|
||||||
OsFamily osFamily, Credentials creds) throws RunScriptOnNodesException {
|
final String tag, OsFamily osFamily, Credentials creds)
|
||||||
|
throws RunScriptOnNodesException {
|
||||||
try {
|
try {
|
||||||
return client.runScriptOnNodesMatching(NodePredicates.runningWithTag(tag), buildScript(
|
return client.runScriptOnNodesMatching(NodePredicates
|
||||||
osFamily).getBytes(), RunScriptOptions.Builder.overrideCredentialsWith(creds));
|
.runningWithTag(tag), buildScript(osFamily).getBytes(),
|
||||||
|
RunScriptOptions.Builder.overrideCredentialsWith(creds));
|
||||||
} catch (SshException e) {
|
} catch (SshException e) {
|
||||||
if (Throwables.getRootCause(e).getMessage().contains("Auth fail")) {
|
if (Throwables.getRootCause(e).getMessage().contains("Auth fail")) {
|
||||||
// System.err.printf("bad credentials: %s:%s for %s%n", creds.account, creds.key, client
|
// System.err.printf("bad credentials: %s:%s for %s%n",
|
||||||
|
// creds.account, creds.key, client
|
||||||
// .listNodesDetailsMatching(tag));
|
// .listNodesDetailsMatching(tag));
|
||||||
}
|
}
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void checkNodes(Iterable<? extends NodeMetadata> nodes, String tag) throws IOException {
|
protected void checkNodes(Iterable<? extends NodeMetadata> nodes, String tag)
|
||||||
|
throws IOException {
|
||||||
for (NodeMetadata node : nodes) {
|
for (NodeMetadata node : nodes) {
|
||||||
assertNotNull(node.getProviderId());
|
assertNotNull(node.getProviderId());
|
||||||
assertNotNull(node.getTag());
|
assertNotNull(node.getTag());
|
||||||
assertEquals(node.getTag(), tag);
|
assertEquals(node.getTag(), tag);
|
||||||
assertEquals(node.getState(), NodeState.RUNNING);
|
assertEquals(node.getState(), NodeState.RUNNING);
|
||||||
assert node.getPublicAddresses().size() >= 1 || node.getPrivateAddresses().size() >= 1 : "no ips in"
|
assert node.getPublicAddresses().size() >= 1
|
||||||
+ node;
|
|| node.getPrivateAddresses().size() >= 1 : "no ips in" + node;
|
||||||
assertNotNull(node.getCredentials());
|
assertNotNull(node.getCredentials());
|
||||||
if (node.getCredentials().account != null) {
|
if (node.getCredentials().account != null) {
|
||||||
assertNotNull(node.getCredentials().account);
|
assertNotNull(node.getCredentials().account);
|
||||||
|
@ -323,11 +343,14 @@ public abstract class BaseComputeServiceLiveTest {
|
||||||
case RHEL:
|
case RHEL:
|
||||||
return new StringBuilder()
|
return new StringBuilder()
|
||||||
.append("echo nameserver 208.67.222.222 >> /etc/resolv.conf\n")
|
.append("echo nameserver 208.67.222.222 >> /etc/resolv.conf\n")
|
||||||
.append("echo \"[jdkrepo]\" >> /etc/yum.repos.d/CentOS-Base.repo\n")
|
.append(
|
||||||
.append("echo \"name=jdkrepository\" >> /etc/yum.repos.d/CentOS-Base.repo\n")
|
"echo \"[jdkrepo]\" >> /etc/yum.repos.d/CentOS-Base.repo\n")
|
||||||
|
.append(
|
||||||
|
"echo \"name=jdkrepository\" >> /etc/yum.repos.d/CentOS-Base.repo\n")
|
||||||
.append(
|
.append(
|
||||||
"echo \"baseurl=http://ec2-us-east-mirror.rightscale.com/epel/5/i386/\" >> /etc/yum.repos.d/CentOS-Base.repo\n")
|
"echo \"baseurl=http://ec2-us-east-mirror.rightscale.com/epel/5/i386/\" >> /etc/yum.repos.d/CentOS-Base.repo\n")
|
||||||
.append("echo \"enabled=1\" >> /etc/yum.repos.d/CentOS-Base.repo\n")
|
.append(
|
||||||
|
"echo \"enabled=1\" >> /etc/yum.repos.d/CentOS-Base.repo\n")
|
||||||
.append("yum --nogpgcheck -y install java-1.6.0-openjdk\n")
|
.append("yum --nogpgcheck -y install java-1.6.0-openjdk\n")
|
||||||
.append(
|
.append(
|
||||||
"echo \"export PATH=\\\"/usr/lib/jvm/jre-1.6.0-openjdk/bin/:\\$PATH\\\"\" >> /root/.bashrc\n")
|
"echo \"export PATH=\\\"/usr/lib/jvm/jre-1.6.0-openjdk/bin/:\\$PATH\\\"\" >> /root/.bashrc\n")
|
||||||
|
@ -339,27 +362,36 @@ public abstract class BaseComputeServiceLiveTest {
|
||||||
|
|
||||||
@Test(enabled = true, dependsOnMethods = "testCreateAnotherNodeWithANewContextToEnsureSharedMemIsntRequired")
|
@Test(enabled = true, dependsOnMethods = "testCreateAnotherNodeWithANewContextToEnsureSharedMemIsntRequired")
|
||||||
public void testGet() throws Exception {
|
public void testGet() throws Exception {
|
||||||
Set<? extends NodeMetadata> metadataSet = Sets.newHashSet(Iterables.filter(client
|
Set<? extends NodeMetadata> metadataSet = Sets.newHashSet(Iterables
|
||||||
.listNodesDetailsMatching(NodePredicates.all()), Predicates.and(NodePredicates
|
.filter(client.listNodesDetailsMatching(NodePredicates.all()),
|
||||||
.withTag(tag), Predicates.not(NodePredicates.TERMINATED))));
|
Predicates.and(NodePredicates.withTag(tag), Predicates
|
||||||
|
.not(NodePredicates.TERMINATED))));
|
||||||
for (NodeMetadata node : nodes) {
|
for (NodeMetadata node : nodes) {
|
||||||
metadataSet.remove(node);
|
metadataSet.remove(node);
|
||||||
NodeMetadata metadata = client.getNodeMetadata(node.getId());
|
NodeMetadata metadata = client.getNodeMetadata(node.getId());
|
||||||
assertEquals(metadata.getProviderId(), node.getProviderId());
|
assertEquals(metadata.getProviderId(), node.getProviderId());
|
||||||
assertEquals(metadata.getTag(), node.getTag());
|
assertEquals(metadata.getTag(), node.getTag());
|
||||||
assertLocationSameOrChild(metadata.getLocation(), template.getLocation());
|
assertLocationSameOrChild(metadata.getLocation(), template
|
||||||
|
.getLocation());
|
||||||
assertEquals(metadata.getImage(), template.getImage());
|
assertEquals(metadata.getImage(), template.getImage());
|
||||||
assertEquals(metadata.getState(), NodeState.RUNNING);
|
assertEquals(metadata.getState(), NodeState.RUNNING);
|
||||||
assertEquals(metadata.getPrivateAddresses(), node.getPrivateAddresses());
|
assertEquals(metadata.getPrivateAddresses(), node
|
||||||
|
.getPrivateAddresses());
|
||||||
assertEquals(metadata.getPublicAddresses(), node.getPublicAddresses());
|
assertEquals(metadata.getPublicAddresses(), node.getPublicAddresses());
|
||||||
}
|
}
|
||||||
|
assertNodeZero(metadataSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void assertNodeZero(Set<? extends NodeMetadata> metadataSet) {
|
||||||
assert metadataSet.size() == 0 : String.format(
|
assert metadataSet.size() == 0 : String.format(
|
||||||
"nodes left in set: [%s] which didn't match set: [%s]", metadataSet, nodes);
|
"nodes left in set: [%s] which didn't match set: [%s]",
|
||||||
|
metadataSet, nodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(enabled = true, dependsOnMethods = "testGet")
|
@Test(enabled = true, dependsOnMethods = "testGet")
|
||||||
public void testReboot() throws Exception {
|
public void testReboot() throws Exception {
|
||||||
client.rebootNodesMatching(NodePredicates.withTag(tag));// TODO test validation
|
client.rebootNodesMatching(NodePredicates.withTag(tag));// TODO test
|
||||||
|
// validation
|
||||||
testGet();
|
testGet();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -380,7 +412,8 @@ public abstract class BaseComputeServiceLiveTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testGetNodesWithDetails() throws Exception {
|
public void testGetNodesWithDetails() throws Exception {
|
||||||
for (NodeMetadata node : client.listNodesDetailsMatching(NodePredicates.all())) {
|
for (NodeMetadata node : client.listNodesDetailsMatching(NodePredicates
|
||||||
|
.all())) {
|
||||||
assert node.getProviderId() != null : node;
|
assert node.getProviderId() != null : node;
|
||||||
assert node.getLocation() != null : node;
|
assert node.getLocation() != null : node;
|
||||||
assertEquals(node.getType(), ComputeType.NODE);
|
assertEquals(node.getType(), ComputeType.NODE);
|
||||||
|
@ -440,6 +473,32 @@ public abstract class BaseComputeServiceLiveTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test(enabled = true, dependsOnMethods = "testGet")
|
||||||
|
public void testOptionToNotBlock() throws Exception {
|
||||||
|
String tag = this.tag + "block";
|
||||||
|
try {
|
||||||
|
client.destroyNodesMatching(NodePredicates.withTag(tag));
|
||||||
|
} catch (Exception e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
// no inbound ports
|
||||||
|
TemplateOptions options = client.templateOptions().blockUntilRunning(
|
||||||
|
false).inboundPorts();
|
||||||
|
try {
|
||||||
|
long time = System.currentTimeMillis();
|
||||||
|
Set<? extends NodeMetadata> nodes = client.runNodesWithTag(tag, 1,
|
||||||
|
options);
|
||||||
|
NodeMetadata node = Iterables.getOnlyElement(nodes);
|
||||||
|
assertEquals(node.getState(), NodeState.PENDING);
|
||||||
|
|
||||||
|
long duration = System.currentTimeMillis() - time;
|
||||||
|
assert duration < 30 * 1000 : "duration longer than 30 seconds!: "
|
||||||
|
+ duration / 1000;
|
||||||
|
} finally {
|
||||||
|
client.destroyNodesMatching(NodePredicates.withTag(tag));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void assertProvider(Location provider) {
|
private void assertProvider(Location provider) {
|
||||||
assertEquals(provider.getScope(), LocationScope.PROVIDER);
|
assertEquals(provider.getScope(), LocationScope.PROVIDER);
|
||||||
assertEquals(provider.getParent(), null);
|
assertEquals(provider.getParent(), null);
|
||||||
|
@ -470,12 +529,15 @@ public abstract class BaseComputeServiceLiveTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void doCheckJavaIsInstalledViaSsh(NodeMetadata node) throws IOException {
|
protected void doCheckJavaIsInstalledViaSsh(NodeMetadata node)
|
||||||
IPSocket socket = new IPSocket(Iterables.get(node.getPublicAddresses(), 0), 22);
|
throws IOException {
|
||||||
socketTester.apply(socket); // TODO add transitionTo option that accepts a socket conection
|
IPSocket socket = new IPSocket(Iterables
|
||||||
|
.get(node.getPublicAddresses(), 0), 22);
|
||||||
|
socketTester.apply(socket); // TODO add transitionTo option that accepts
|
||||||
|
// a socket conection
|
||||||
// state.
|
// state.
|
||||||
SshClient ssh = sshFactory.create(socket, node.getCredentials().account, keyPair.get(
|
SshClient ssh = sshFactory.create(socket, node.getCredentials().account,
|
||||||
"private").getBytes());
|
keyPair.get("private").getBytes());
|
||||||
try {
|
try {
|
||||||
ssh.connect();
|
ssh.connect();
|
||||||
ExecResponse hello = ssh.exec("echo hello");
|
ExecResponse hello = ssh.exec("echo hello");
|
||||||
|
@ -489,11 +551,13 @@ public abstract class BaseComputeServiceLiveTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterTest
|
@AfterTest
|
||||||
protected void cleanup() throws InterruptedException, ExecutionException, TimeoutException {
|
protected void cleanup() throws InterruptedException, ExecutionException,
|
||||||
|
TimeoutException {
|
||||||
if (nodes != null) {
|
if (nodes != null) {
|
||||||
client.destroyNodesMatching(NodePredicates.withTag(tag));
|
client.destroyNodesMatching(NodePredicates.withTag(tag));
|
||||||
for (NodeMetadata node : Iterables.filter(client.listNodesDetailsMatching(NodePredicates
|
for (NodeMetadata node : Iterables.filter(client
|
||||||
.all()), NodePredicates.withTag(tag))) {
|
.listNodesDetailsMatching(NodePredicates.all()), NodePredicates
|
||||||
|
.withTag(tag))) {
|
||||||
assert node.getState() == NodeState.TERMINATED : node;
|
assert node.getState() == NodeState.TERMINATED : node;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,10 +31,12 @@ import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentMap;
|
import java.util.concurrent.ConcurrentMap;
|
||||||
|
|
||||||
import org.easymock.IArgumentMatcher;
|
import org.easymock.IArgumentMatcher;
|
||||||
import org.jclouds.compute.domain.Architecture;
|
import org.jclouds.compute.domain.Architecture;
|
||||||
|
import org.jclouds.compute.domain.NodeMetadata;
|
||||||
import org.jclouds.compute.domain.OsFamily;
|
import org.jclouds.compute.domain.OsFamily;
|
||||||
import org.jclouds.compute.domain.Template;
|
import org.jclouds.compute.domain.Template;
|
||||||
import org.jclouds.compute.stub.config.StubComputeServiceContextModule.StubNodeMetadata;
|
import org.jclouds.compute.stub.config.StubComputeServiceContextModule.StubNodeMetadata;
|
||||||
|
@ -64,7 +66,8 @@ import com.google.inject.Module;
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@Test(groups = "live", enabled = true, sequential = true, testName = "stub.StubComputeServiceIntegrationTest")
|
@Test(groups = "live", enabled = true, sequential = true, testName = "stub.StubComputeServiceIntegrationTest")
|
||||||
public class StubComputeServiceIntegrationTest extends BaseComputeServiceLiveTest {
|
public class StubComputeServiceIntegrationTest extends
|
||||||
|
BaseComputeServiceLiveTest {
|
||||||
|
|
||||||
private static final ExecResponse EXEC_GOOD = new ExecResponse("", "", 0);
|
private static final ExecResponse EXEC_GOOD = new ExecResponse("", "", 0);
|
||||||
private static final ExecResponse EXEC_BAD = new ExecResponse("", "", 1);
|
private static final ExecResponse EXEC_BAD = new ExecResponse("", "", 1);
|
||||||
|
@ -82,7 +85,8 @@ public class StubComputeServiceIntegrationTest extends BaseComputeServiceLiveTes
|
||||||
@Test
|
@Test
|
||||||
public void testTemplateBuilder() {
|
public void testTemplateBuilder() {
|
||||||
Template defaultTemplate = client.templateBuilder().build();
|
Template defaultTemplate = client.templateBuilder().build();
|
||||||
assertEquals(defaultTemplate.getImage().getArchitecture(), Architecture.X86_64);
|
assertEquals(defaultTemplate.getImage().getArchitecture(),
|
||||||
|
Architecture.X86_64);
|
||||||
assertEquals(defaultTemplate.getImage().getOsFamily(), OsFamily.UBUNTU);
|
assertEquals(defaultTemplate.getImage().getOsFamily(), OsFamily.UBUNTU);
|
||||||
assertEquals(defaultTemplate.getLocation().getId(), "memory");
|
assertEquals(defaultTemplate.getLocation().getId(), "memory");
|
||||||
assertEquals(defaultTemplate.getSize().getCores(), 4.0d);
|
assertEquals(defaultTemplate.getSize().getCores(), 4.0d);
|
||||||
|
@ -107,17 +111,21 @@ public class StubComputeServiceIntegrationTest extends BaseComputeServiceLiveTes
|
||||||
expect(open.apply(new IPSocket("144.175.1.4", 22))).andReturn(true);
|
expect(open.apply(new IPSocket("144.175.1.4", 22))).andReturn(true);
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
factory.create(eq(new IPSocket("144.175.1.1", 22)), eq("root"), aryEq(keyPair
|
factory.create(eq(new IPSocket("144.175.1.1", 22)),
|
||||||
.get("private").getBytes()))).andReturn(client1).atLeastOnce();
|
eq("root"), aryEq(keyPair.get("private").getBytes())))
|
||||||
|
.andReturn(client1).atLeastOnce();
|
||||||
expect(
|
expect(
|
||||||
factory.create(eq(new IPSocket("144.175.1.2", 22)), eq("root"), aryEq(keyPair
|
factory.create(eq(new IPSocket("144.175.1.2", 22)),
|
||||||
.get("private").getBytes()))).andReturn(client2).atLeastOnce();
|
eq("root"), aryEq(keyPair.get("private").getBytes())))
|
||||||
|
.andReturn(client2).atLeastOnce();
|
||||||
expect(
|
expect(
|
||||||
factory.create(eq(new IPSocket("144.175.1.3", 22)), eq("root"), aryEq(keyPair
|
factory.create(eq(new IPSocket("144.175.1.3", 22)),
|
||||||
.get("private").getBytes()))).andReturn(client3).atLeastOnce();
|
eq("root"), aryEq(keyPair.get("private").getBytes())))
|
||||||
|
.andReturn(client3).atLeastOnce();
|
||||||
expect(
|
expect(
|
||||||
factory.create(eq(new IPSocket("144.175.1.4", 22)), eq("root"), aryEq(keyPair
|
factory.create(eq(new IPSocket("144.175.1.4", 22)),
|
||||||
.get("private").getBytes()))).andReturn(client4).atLeastOnce();
|
eq("root"), aryEq(keyPair.get("private").getBytes())))
|
||||||
|
.andReturn(client4).atLeastOnce();
|
||||||
|
|
||||||
helloAndJava(client1);
|
helloAndJava(client1);
|
||||||
helloAndJava(client2);
|
helloAndJava(client2);
|
||||||
|
@ -139,8 +147,10 @@ public class StubComputeServiceIntegrationTest extends BaseComputeServiceLiveTes
|
||||||
private void helloAndJava(SshClient client) {
|
private void helloAndJava(SshClient client) {
|
||||||
client.connect();
|
client.connect();
|
||||||
|
|
||||||
expect(client.exec("echo hello")).andReturn(new ExecResponse("hello", "", 0));
|
expect(client.exec("echo hello")).andReturn(
|
||||||
expect(client.exec("java -version")).andReturn(new ExecResponse("", "OpenJDK", 0));
|
new ExecResponse("hello", "", 0));
|
||||||
|
expect(client.exec("java -version")).andReturn(
|
||||||
|
new ExecResponse("", "OpenJDK", 0));
|
||||||
|
|
||||||
client.disconnect();
|
client.disconnect();
|
||||||
}
|
}
|
||||||
|
@ -160,21 +170,26 @@ public class StubComputeServiceIntegrationTest extends BaseComputeServiceLiveTes
|
||||||
SshClient client3 = createMock(SshClient.class);
|
SshClient client3 = createMock(SshClient.class);
|
||||||
SshClient client4 = createMock(SshClient.class);
|
SshClient client4 = createMock(SshClient.class);
|
||||||
|
|
||||||
expect(factory.create(new IPSocket("144.175.1.1", 22), "root", "romeo")).andThrow(
|
expect(
|
||||||
new SshException("Auth fail"));
|
factory.create(new IPSocket("144.175.1.1", 22), "root",
|
||||||
expect(factory.create(new IPSocket("144.175.1.1", 22), "root", "password1")).andReturn(
|
"romeo")).andThrow(new SshException("Auth fail"));
|
||||||
client1).atLeastOnce();
|
expect(
|
||||||
|
factory.create(new IPSocket("144.175.1.1", 22), "root",
|
||||||
|
"password1")).andReturn(client1).atLeastOnce();
|
||||||
|
|
||||||
client1.connect();
|
client1.connect();
|
||||||
runScript(client1, "computeserv", 1);
|
runScript(client1, "computeserv", 1);
|
||||||
client1.disconnect();
|
client1.disconnect();
|
||||||
|
|
||||||
expect(factory.create(new IPSocket("144.175.1.2", 22), "root", "password2")).andReturn(
|
expect(
|
||||||
client2).atLeastOnce();
|
factory.create(new IPSocket("144.175.1.2", 22), "root",
|
||||||
expect(factory.create(new IPSocket("144.175.1.3", 22), "root", "password3")).andReturn(
|
"password2")).andReturn(client2).atLeastOnce();
|
||||||
client3).atLeastOnce();
|
expect(
|
||||||
expect(factory.create(new IPSocket("144.175.1.4", 22), "root", "password4")).andReturn(
|
factory.create(new IPSocket("144.175.1.3", 22), "root",
|
||||||
client4).atLeastOnce();
|
"password3")).andReturn(client3).atLeastOnce();
|
||||||
|
expect(
|
||||||
|
factory.create(new IPSocket("144.175.1.4", 22), "root",
|
||||||
|
"password4")).andReturn(client4).atLeastOnce();
|
||||||
|
|
||||||
runScriptAndInstallSsh(client2, "runscript", 2);
|
runScriptAndInstallSsh(client2, "runscript", 2);
|
||||||
runScriptAndInstallSsh(client3, "runscript", 3);
|
runScriptAndInstallSsh(client3, "runscript", 3);
|
||||||
|
@ -189,14 +204,17 @@ public class StubComputeServiceIntegrationTest extends BaseComputeServiceLiveTes
|
||||||
bind(SshClient.Factory.class).toInstance(factory);
|
bind(SshClient.Factory.class).toInstance(factory);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void runScriptAndInstallSsh(SshClient client, String scriptName, int nodeId) {
|
private void runScriptAndInstallSsh(SshClient client,
|
||||||
|
String scriptName, int nodeId) {
|
||||||
client.connect();
|
client.connect();
|
||||||
|
|
||||||
runScript(client, scriptName, nodeId);
|
runScript(client, scriptName, nodeId);
|
||||||
|
|
||||||
expect(client.exec("mkdir .ssh")).andReturn(EXEC_GOOD);
|
expect(client.exec("mkdir .ssh")).andReturn(EXEC_GOOD);
|
||||||
expect(client.exec("cat .ssh/id_rsa.pub >> .ssh/authorized_keys")).andReturn(EXEC_GOOD);
|
expect(client.exec("cat .ssh/id_rsa.pub >> .ssh/authorized_keys"))
|
||||||
expect(client.exec("chmod 600 .ssh/authorized_keys")).andReturn(EXEC_GOOD);
|
.andReturn(EXEC_GOOD);
|
||||||
|
expect(client.exec("chmod 600 .ssh/authorized_keys")).andReturn(
|
||||||
|
EXEC_GOOD);
|
||||||
client.put(eq(".ssh/id_rsa.pub"), isEq(keyPair.get("public")));
|
client.put(eq(".ssh/id_rsa.pub"), isEq(keyPair.get("public")));
|
||||||
|
|
||||||
expect(client.exec("mkdir .ssh")).andReturn(EXEC_GOOD);
|
expect(client.exec("mkdir .ssh")).andReturn(EXEC_GOOD);
|
||||||
|
@ -212,16 +230,24 @@ public class StubComputeServiceIntegrationTest extends BaseComputeServiceLiveTes
|
||||||
client.put(eq("" + scriptName + ""), isEq(initScript(scriptName,
|
client.put(eq("" + scriptName + ""), isEq(initScript(scriptName,
|
||||||
buildScript(OsFamily.UBUNTU))));
|
buildScript(OsFamily.UBUNTU))));
|
||||||
|
|
||||||
expect(client.exec("chmod 755 " + scriptName + "")).andReturn(EXEC_GOOD);
|
expect(client.exec("chmod 755 " + scriptName + "")).andReturn(
|
||||||
|
EXEC_GOOD);
|
||||||
expect(client.getUsername()).andReturn("root").atLeastOnce();
|
expect(client.getUsername()).andReturn("root").atLeastOnce();
|
||||||
expect(client.getHostAddress()).andReturn(nodeId + "").atLeastOnce();
|
expect(client.getHostAddress()).andReturn(nodeId + "")
|
||||||
expect(client.exec("./" + scriptName + " init")).andReturn(EXEC_GOOD);
|
.atLeastOnce();
|
||||||
expect(client.exec("./" + scriptName + " start")).andReturn(EXEC_GOOD);
|
expect(client.exec("./" + scriptName + " init")).andReturn(
|
||||||
expect(client.exec("./" + scriptName + " status")).andReturn(EXEC_GOOD);
|
EXEC_GOOD);
|
||||||
|
expect(client.exec("./" + scriptName + " start")).andReturn(
|
||||||
|
EXEC_GOOD);
|
||||||
|
expect(client.exec("./" + scriptName + " status")).andReturn(
|
||||||
|
EXEC_GOOD);
|
||||||
// next status says the script is done, since not found.
|
// next status says the script is done, since not found.
|
||||||
expect(client.exec("./" + scriptName + " status")).andReturn(EXEC_BAD);
|
expect(client.exec("./" + scriptName + " status")).andReturn(
|
||||||
expect(client.exec("./" + scriptName + " tail")).andReturn(EXEC_GOOD);
|
EXEC_BAD);
|
||||||
expect(client.exec("./" + scriptName + " tailerr")).andReturn(EXEC_GOOD);
|
expect(client.exec("./" + scriptName + " tail")).andReturn(
|
||||||
|
EXEC_GOOD);
|
||||||
|
expect(client.exec("./" + scriptName + " tailerr")).andReturn(
|
||||||
|
EXEC_GOOD);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -233,9 +259,14 @@ public class StubComputeServiceIntegrationTest extends BaseComputeServiceLiveTes
|
||||||
password = "stub";
|
password = "stub";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void assertNodeZero(Set<? extends NodeMetadata> metadataSet) {
|
||||||
|
// TODO: this fails so we override it.
|
||||||
|
}
|
||||||
|
|
||||||
public static String initScript(String scriptName, String script) {
|
public static String initScript(String scriptName, String script) {
|
||||||
return new InitBuilder(scriptName, "/tmp/" + scriptName, "/tmp/" + scriptName, ImmutableMap
|
return new InitBuilder(scriptName, "/tmp/" + scriptName, "/tmp/"
|
||||||
.<String, String> of(), Iterables.toArray(Splitter.on("\n").split(
|
+ scriptName, ImmutableMap.<String, String> of(), Iterables
|
||||||
|
.toArray(Splitter.on("\n").split(
|
||||||
new String(checkNotNull(script, "script"))), String.class))
|
new String(checkNotNull(script, "script"))), String.class))
|
||||||
.build(org.jclouds.scriptbuilder.domain.OsFamily.UNIX);
|
.build(org.jclouds.scriptbuilder.domain.OsFamily.UNIX);
|
||||||
}
|
}
|
||||||
|
@ -248,10 +279,12 @@ public class StubComputeServiceIntegrationTest extends BaseComputeServiceLiveTes
|
||||||
public void testAssignability() throws Exception {
|
public void testAssignability() throws Exception {
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
RestContext<ConcurrentMap<Integer, StubNodeMetadata>, ConcurrentMap<Integer, StubNodeMetadata>> stubContext = new ComputeServiceContextFactory()
|
RestContext<ConcurrentMap<Integer, StubNodeMetadata>, ConcurrentMap<Integer, StubNodeMetadata>> stubContext = new ComputeServiceContextFactory()
|
||||||
.createContext(service, user, password).getProviderSpecificContext();
|
.createContext(service, user, password)
|
||||||
|
.getProviderSpecificContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class InputStreamEquals implements IArgumentMatcher, Serializable {
|
private static class InputStreamEquals implements IArgumentMatcher,
|
||||||
|
Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = 583055160049982067L;
|
private static final long serialVersionUID = 583055160049982067L;
|
||||||
|
|
||||||
|
@ -297,8 +330,8 @@ public class StubComputeServiceIntegrationTest extends BaseComputeServiceLiveTes
|
||||||
if (o == null || !this.getClass().equals(o.getClass()))
|
if (o == null || !this.getClass().equals(o.getClass()))
|
||||||
return false;
|
return false;
|
||||||
InputStreamEquals other = (InputStreamEquals) o;
|
InputStreamEquals other = (InputStreamEquals) o;
|
||||||
return this.expected == null && other.expected == null || this.expected != null
|
return this.expected == null && other.expected == null
|
||||||
&& this.expected.equals(other.expected);
|
|| this.expected != null && this.expected.equals(other.expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -310,8 +343,8 @@ public class StubComputeServiceIntegrationTest extends BaseComputeServiceLiveTes
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void setupKeyPair() throws FileNotFoundException, IOException {
|
protected void setupKeyPair() throws FileNotFoundException, IOException {
|
||||||
keyPair = ImmutableMap.<String, String> of("public", "ssh-rsa", "private",
|
keyPair = ImmutableMap.<String, String> of("public", "ssh-rsa",
|
||||||
"-----BEGIN RSA PRIVATE KEY-----");
|
"private", "-----BEGIN RSA PRIVATE KEY-----");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -4,6 +4,7 @@ import java.util.Set;
|
||||||
|
|
||||||
import org.jclouds.compute.util.ComputeUtils;
|
import org.jclouds.compute.util.ComputeUtils;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test the compute utils.
|
* Test the compute utils.
|
||||||
*
|
*
|
||||||
|
@ -17,10 +18,11 @@ public class ComputeUtilsTest {
|
||||||
* Test some of the currently supported clouds against compute.properties.
|
* Test some of the currently supported clouds against compute.properties.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testSupportedProviders(){
|
public void testSupportedProviders() {
|
||||||
Set<String> providers = ComputeUtils.getSupportedProviders();
|
Set<String> providers = ComputeUtils.getSupportedProviders();
|
||||||
assert providers.contains("rimuhosting");
|
assert providers.contains("rimuhosting");
|
||||||
assert providers.contains("cloudservers");
|
assert providers.contains("cloudservers");
|
||||||
assert providers.contains("gogrid");
|
assert providers.contains("gogrid");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ package org.jclouds.compute.options;
|
||||||
|
|
||||||
import static org.jclouds.compute.options.TemplateOptions.Builder.authorizePublicKey;
|
import static org.jclouds.compute.options.TemplateOptions.Builder.authorizePublicKey;
|
||||||
import static org.jclouds.compute.options.TemplateOptions.Builder.blockOnPort;
|
import static org.jclouds.compute.options.TemplateOptions.Builder.blockOnPort;
|
||||||
|
import static org.jclouds.compute.options.TemplateOptions.Builder.blockUntilRunning;
|
||||||
import static org.jclouds.compute.options.TemplateOptions.Builder.inboundPorts;
|
import static org.jclouds.compute.options.TemplateOptions.Builder.inboundPorts;
|
||||||
import static org.jclouds.compute.options.TemplateOptions.Builder.installPrivateKey;
|
import static org.jclouds.compute.options.TemplateOptions.Builder.installPrivateKey;
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
|
@ -149,4 +150,33 @@ public class TemplateOptionsTest {
|
||||||
assertEquals(options.getInboundPorts()[0], 22);
|
assertEquals(options.getInboundPorts()[0], 22);
|
||||||
assertEquals(options.getInboundPorts()[1], 30);
|
assertEquals(options.getInboundPorts()[1], 30);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testblockUntilRunningDefault() {
|
||||||
|
TemplateOptions options = new TemplateOptions();
|
||||||
|
assertEquals(options.shouldBlockUntilRunning(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testblockUntilRunning() {
|
||||||
|
TemplateOptions options = new TemplateOptions();
|
||||||
|
options.blockUntilRunning(false);
|
||||||
|
assertEquals(options.shouldBlockUntilRunning(), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBlockUntilRunningUnsetsBlockOnPort() {
|
||||||
|
TemplateOptions options = new TemplateOptions();
|
||||||
|
options.blockOnPort(22, 30);
|
||||||
|
options.blockUntilRunning(false);
|
||||||
|
assertEquals(options.shouldBlockUntilRunning(), false);
|
||||||
|
assertEquals(options.getPort(), -1);
|
||||||
|
assertEquals(options.getSeconds(), -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testblockUntilRunningStatic() {
|
||||||
|
TemplateOptions options = blockUntilRunning(false);
|
||||||
|
assertEquals(options.shouldBlockUntilRunning(), false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,24 +34,32 @@ import com.google.common.base.Predicate;
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public class RetryablePredicate<T> implements Predicate<T> {
|
public class RetryablePredicate<T> implements Predicate<T> {
|
||||||
private final int maxWait;
|
private final long maxWait;
|
||||||
private final int checkInterval;
|
private final long period;
|
||||||
private final Predicate<T> predicate;
|
private final Predicate<T> predicate;
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
protected Logger logger = Logger.NULL;
|
protected Logger logger = Logger.NULL;
|
||||||
|
|
||||||
public RetryablePredicate(Predicate<T> predicate, long maxWait, long checkInterval, TimeUnit unit) {
|
public RetryablePredicate(Predicate<T> predicate, long maxWait, long period,
|
||||||
|
TimeUnit unit) {
|
||||||
this.predicate = predicate;
|
this.predicate = predicate;
|
||||||
this.maxWait = (int) unit.toMillis(maxWait);
|
this.maxWait = unit.toMillis(maxWait);
|
||||||
this.checkInterval = (int) unit.toMillis(checkInterval);
|
this.period = unit.toMillis(period);
|
||||||
|
}
|
||||||
|
|
||||||
|
public RetryablePredicate(Predicate<T> predicate, long maxWait) {
|
||||||
|
this.predicate = predicate;
|
||||||
|
this.maxWait = maxWait;
|
||||||
|
this.period = 50l;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(T input) {
|
public boolean apply(T input) {
|
||||||
try {
|
try {
|
||||||
|
long i = 1l;
|
||||||
for (Date end = new Date(System.currentTimeMillis() + maxWait); before(end); Thread
|
for (Date end = new Date(System.currentTimeMillis() + maxWait); before(end); Thread
|
||||||
.sleep(checkInterval)) {
|
.sleep(nextMaxInterval(i++, end))) {
|
||||||
if (predicate.apply(input)) {
|
if (predicate.apply(input)) {
|
||||||
return true;
|
return true;
|
||||||
} else if (atOrAfter(end)) {
|
} else if (atOrAfter(end)) {
|
||||||
|
@ -59,11 +67,18 @@ public class RetryablePredicate<T> implements Predicate<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
logger.warn(e, "predicate %s on %s interrupted, returning false", input, predicate);
|
logger.warn(e, "predicate %s on %s interrupted, returning false",
|
||||||
|
input, predicate);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
long nextMaxInterval(long attempt, Date end) {
|
||||||
|
long interval = (period * (long) Math.pow(attempt, 2l));
|
||||||
|
long max = end.getTime() - System.currentTimeMillis();
|
||||||
|
return (interval > max) ? max : interval;
|
||||||
|
}
|
||||||
|
|
||||||
boolean before(Date end) {
|
boolean before(Date end) {
|
||||||
return new Date().compareTo(end) <= 1;
|
return new Date().compareTo(end) <= 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,6 @@ import static org.jclouds.gogrid.reference.GoGridConstants.PROPERTY_GOGRID_DEFAU
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
@ -37,6 +36,7 @@ import javax.inject.Singleton;
|
||||||
|
|
||||||
import org.jclouds.compute.ComputeServiceContext;
|
import org.jclouds.compute.ComputeServiceContext;
|
||||||
import org.jclouds.compute.LoadBalancerService;
|
import org.jclouds.compute.LoadBalancerService;
|
||||||
|
import org.jclouds.compute.config.ComputeServiceTimeoutsModule;
|
||||||
import org.jclouds.compute.domain.Architecture;
|
import org.jclouds.compute.domain.Architecture;
|
||||||
import org.jclouds.compute.domain.ComputeMetadata;
|
import org.jclouds.compute.domain.ComputeMetadata;
|
||||||
import org.jclouds.compute.domain.Image;
|
import org.jclouds.compute.domain.Image;
|
||||||
|
@ -49,9 +49,8 @@ import org.jclouds.compute.domain.internal.ImageImpl;
|
||||||
import org.jclouds.compute.domain.internal.SizeImpl;
|
import org.jclouds.compute.domain.internal.SizeImpl;
|
||||||
import org.jclouds.compute.internal.ComputeServiceContextImpl;
|
import org.jclouds.compute.internal.ComputeServiceContextImpl;
|
||||||
import org.jclouds.compute.predicates.NodePredicates;
|
import org.jclouds.compute.predicates.NodePredicates;
|
||||||
import org.jclouds.compute.predicates.ScriptStatusReturnsZero;
|
|
||||||
import org.jclouds.compute.predicates.ScriptStatusReturnsZero.CommandUsingClient;
|
|
||||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||||
|
import org.jclouds.compute.reference.ComputeServiceConstants.Timeouts;
|
||||||
import org.jclouds.compute.strategy.AddNodeWithTagStrategy;
|
import org.jclouds.compute.strategy.AddNodeWithTagStrategy;
|
||||||
import org.jclouds.compute.strategy.DestroyNodeStrategy;
|
import org.jclouds.compute.strategy.DestroyNodeStrategy;
|
||||||
import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
|
import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
|
||||||
|
@ -77,7 +76,6 @@ import org.jclouds.predicates.RetryablePredicate;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
import com.google.common.base.Predicates;
|
|
||||||
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.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
|
@ -100,15 +98,20 @@ public class GoGridComputeServiceContextModule extends GoGridContextModule {
|
||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
super.configure();
|
super.configure();
|
||||||
|
install(new ComputeServiceTimeoutsModule());
|
||||||
bind(new TypeLiteral<Function<Server, NodeMetadata>>() {
|
bind(new TypeLiteral<Function<Server, NodeMetadata>>() {
|
||||||
}).to(ServerToNodeMetadata.class);
|
}).to(ServerToNodeMetadata.class);
|
||||||
bind(LoadBalancerService.class).toProvider(Providers.<LoadBalancerService> of(null));
|
bind(LoadBalancerService.class).toProvider(
|
||||||
|
Providers.<LoadBalancerService> of(null));
|
||||||
bind(new TypeLiteral<ComputeServiceContext>() {
|
bind(new TypeLiteral<ComputeServiceContext>() {
|
||||||
}).to(new TypeLiteral<ComputeServiceContextImpl<GoGridClient, GoGridAsyncClient>>() {
|
})
|
||||||
|
.to(
|
||||||
|
new TypeLiteral<ComputeServiceContextImpl<GoGridClient, GoGridAsyncClient>>() {
|
||||||
}).in(Scopes.SINGLETON);
|
}).in(Scopes.SINGLETON);
|
||||||
bind(AddNodeWithTagStrategy.class).to(GoGridAddNodeWithTagStrategy.class);
|
bind(AddNodeWithTagStrategy.class).to(GoGridAddNodeWithTagStrategy.class);
|
||||||
bind(ListNodesStrategy.class).to(GoGridListNodesStrategy.class);
|
bind(ListNodesStrategy.class).to(GoGridListNodesStrategy.class);
|
||||||
bind(GetNodeMetadataStrategy.class).to(GoGridGetNodeMetadataStrategy.class);
|
bind(GetNodeMetadataStrategy.class).to(
|
||||||
|
GoGridGetNodeMetadataStrategy.class);
|
||||||
bind(RebootNodeStrategy.class).to(GoGridRebootNodeStrategy.class);
|
bind(RebootNodeStrategy.class).to(GoGridRebootNodeStrategy.class);
|
||||||
bind(DestroyNodeStrategy.class).to(GoGridDestroyNodeStrategy.class);
|
bind(DestroyNodeStrategy.class).to(GoGridDestroyNodeStrategy.class);
|
||||||
}
|
}
|
||||||
|
@ -129,26 +132,33 @@ public class GoGridComputeServiceContextModule extends GoGridContextModule {
|
||||||
@Singleton
|
@Singleton
|
||||||
public static class GoGridRebootNodeStrategy implements RebootNodeStrategy {
|
public static class GoGridRebootNodeStrategy implements RebootNodeStrategy {
|
||||||
private final GoGridClient client;
|
private final GoGridClient client;
|
||||||
private RetryablePredicate<Server> serverLatestJobCompleted;
|
private final RetryablePredicate<Server> serverLatestJobCompleted;
|
||||||
private RetryablePredicate<Server> serverLatestJobCompletedShort;
|
private RetryablePredicate<Server> serverLatestJobCompletedShort;
|
||||||
|
private final GetNodeMetadataStrategy getNode;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
protected GoGridRebootNodeStrategy(GoGridClient client) {
|
protected GoGridRebootNodeStrategy(GoGridClient client,
|
||||||
|
GetNodeMetadataStrategy getNode, Timeouts timeouts) {
|
||||||
this.client = client;
|
this.client = client;
|
||||||
this.serverLatestJobCompleted = new RetryablePredicate<Server>(
|
this.serverLatestJobCompleted = new RetryablePredicate<Server>(
|
||||||
new ServerLatestJobCompleted(client.getJobServices()), 800, 20, TimeUnit.SECONDS);
|
new ServerLatestJobCompleted(client.getJobServices()),
|
||||||
|
timeouts.nodeRunning * 9l / 10l);
|
||||||
this.serverLatestJobCompletedShort = new RetryablePredicate<Server>(
|
this.serverLatestJobCompletedShort = new RetryablePredicate<Server>(
|
||||||
new ServerLatestJobCompleted(client.getJobServices()), 60, 20, TimeUnit.SECONDS);
|
new ServerLatestJobCompleted(client.getJobServices()),
|
||||||
|
timeouts.nodeRunning * 1l / 10l);
|
||||||
|
this.getNode = getNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean execute(String id) {
|
public NodeMetadata execute(String id) {
|
||||||
Server server = Iterables.getOnlyElement(client.getServerServices().getServersById(
|
Server server = Iterables.getOnlyElement(client.getServerServices()
|
||||||
new Long(id)));
|
.getServersById(new Long(id)));
|
||||||
client.getServerServices().power(server.getName(), PowerCommand.RESTART);
|
client.getServerServices().power(server.getName(),
|
||||||
|
PowerCommand.RESTART);
|
||||||
serverLatestJobCompleted.apply(server);
|
serverLatestJobCompleted.apply(server);
|
||||||
client.getServerServices().power(server.getName(), PowerCommand.START);
|
client.getServerServices().power(server.getName(), PowerCommand.START);
|
||||||
return serverLatestJobCompletedShort.apply(server);
|
serverLatestJobCompletedShort.apply(server);
|
||||||
|
return getNode.execute(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,13 +182,14 @@ public class GoGridComputeServiceContextModule extends GoGridContextModule {
|
||||||
@Override
|
@Override
|
||||||
public Iterable<? extends NodeMetadata> listDetailsOnNodesMatching(
|
public Iterable<? extends NodeMetadata> listDetailsOnNodesMatching(
|
||||||
Predicate<ComputeMetadata> filter) {
|
Predicate<ComputeMetadata> filter) {
|
||||||
return Iterables.filter(Iterables.transform(client.getServerServices().getServerList(),
|
return Iterables.filter(Iterables.transform(client.getServerServices()
|
||||||
serverToNodeMetadata), filter);
|
.getServerList(), serverToNodeMetadata), filter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public static class GoGridGetNodeMetadataStrategy implements GetNodeMetadataStrategy {
|
public static class GoGridGetNodeMetadataStrategy implements
|
||||||
|
GetNodeMetadataStrategy {
|
||||||
private final GoGridClient client;
|
private final GoGridClient client;
|
||||||
private final Function<Server, NodeMetadata> serverToNodeMetadata;
|
private final Function<Server, NodeMetadata> serverToNodeMetadata;
|
||||||
|
|
||||||
|
@ -191,8 +202,8 @@ public class GoGridComputeServiceContextModule extends GoGridContextModule {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NodeMetadata execute(String id) {
|
public NodeMetadata execute(String id) {
|
||||||
Server server = Iterables.getOnlyElement(client.getServerServices().getServersById(
|
Server server = Iterables.getOnlyElement(client.getServerServices()
|
||||||
new Long(checkNotNull(id, "id"))));
|
.getServersById(new Long(checkNotNull(id, "id"))));
|
||||||
return server == null ? null : serverToNodeMetadata.apply(server);
|
return server == null ? null : serverToNodeMetadata.apply(server);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -200,21 +211,21 @@ public class GoGridComputeServiceContextModule extends GoGridContextModule {
|
||||||
@Singleton
|
@Singleton
|
||||||
public static class GoGridDestroyNodeStrategy implements DestroyNodeStrategy {
|
public static class GoGridDestroyNodeStrategy implements DestroyNodeStrategy {
|
||||||
private final GoGridClient client;
|
private final GoGridClient client;
|
||||||
private RetryablePredicate<Server> serverLatestJobCompleted;
|
private final GetNodeMetadataStrategy getNode;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
protected GoGridDestroyNodeStrategy(GoGridClient client) {
|
protected GoGridDestroyNodeStrategy(GoGridClient client,
|
||||||
|
GetNodeMetadataStrategy getNode) {
|
||||||
this.client = client;
|
this.client = client;
|
||||||
this.serverLatestJobCompleted = new RetryablePredicate<Server>(
|
this.getNode = getNode;
|
||||||
new ServerLatestJobCompleted(client.getJobServices()), 800, 20, TimeUnit.SECONDS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean execute(String id) {
|
public NodeMetadata execute(String id) {
|
||||||
Server server = Iterables.getOnlyElement(client.getServerServices().getServersById(
|
Server server = Iterables.getOnlyElement(client.getServerServices()
|
||||||
new Long(id)));
|
.getServersById(new Long(id)));
|
||||||
client.getServerServices().deleteById(server.getId());
|
client.getServerServices().deleteById(server.getId());
|
||||||
return serverLatestJobCompleted.apply(server);
|
return getNode.execute(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -222,18 +233,21 @@ public class GoGridComputeServiceContextModule extends GoGridContextModule {
|
||||||
@Singleton
|
@Singleton
|
||||||
@Provides
|
@Provides
|
||||||
Map<String, NodeState> provideServerToNodeState() {
|
Map<String, NodeState> provideServerToNodeState() {
|
||||||
return ImmutableMap.<String, NodeState> builder().put("On", NodeState.RUNNING).put(
|
return ImmutableMap.<String, NodeState> builder().put("On",
|
||||||
"Starting", NodeState.PENDING).put("Off", NodeState.SUSPENDED).put("Saving",
|
NodeState.RUNNING).put("Starting", NodeState.PENDING).put("Off",
|
||||||
NodeState.PENDING).put("Restarting", NodeState.PENDING).put("Stopping",
|
NodeState.SUSPENDED).put("Saving", NodeState.PENDING).put(
|
||||||
NodeState.PENDING).build();
|
"Restarting", NodeState.PENDING).put("Stopping", NodeState.PENDING)
|
||||||
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds matches to required configurations. GoGrid's documentation only specifies how much RAM
|
* Finds matches to required configurations. GoGrid's documentation only
|
||||||
* one can get with different instance types. The # of cores and disk sizes are purely empyrical
|
* specifies how much RAM one can get with different instance types. The # of
|
||||||
* and aren't guaranteed. However, these are the matches found: Ram: 512MB, CPU: 1 core, HDD: 28
|
* cores and disk sizes are purely empyrical and aren't guaranteed. However,
|
||||||
* GB Ram: 1GB, CPU: 1 core, HDD: 57 GB Ram: 2GB, CPU: 1 core, HDD: 113 GB Ram: 4GB, CPU: 3
|
* these are the matches found: Ram: 512MB, CPU: 1 core, HDD: 28 GB Ram: 1GB,
|
||||||
* cores, HDD: 233 GB Ram: 8GB, CPU: 6 cores, HDD: 462 GB (as of March 2010)
|
* CPU: 1 core, HDD: 57 GB Ram: 2GB, CPU: 1 core, HDD: 113 GB Ram: 4GB, CPU:
|
||||||
|
* 3 cores, HDD: 233 GB Ram: 8GB, CPU: 6 cores, HDD: 462 GB (as of March
|
||||||
|
* 2010)
|
||||||
*
|
*
|
||||||
* @return matched size
|
* @return matched size
|
||||||
*/
|
*/
|
||||||
|
@ -243,9 +257,11 @@ public class GoGridComputeServiceContextModule extends GoGridContextModule {
|
||||||
return new Function<Size, String>() {
|
return new Function<Size, String>() {
|
||||||
@Override
|
@Override
|
||||||
public String apply(Size size) {
|
public String apply(Size size) {
|
||||||
if (size.getRam() >= 8 * 1024 || size.getCores() >= 6 || size.getDisk() >= 450)
|
if (size.getRam() >= 8 * 1024 || size.getCores() >= 6
|
||||||
|
|| size.getDisk() >= 450)
|
||||||
return "8GB";
|
return "8GB";
|
||||||
if (size.getRam() >= 4 * 1024 || size.getCores() >= 3 || size.getDisk() >= 230)
|
if (size.getRam() >= 4 * 1024 || size.getCores() >= 3
|
||||||
|
|| size.getDisk() >= 230)
|
||||||
return "4GB";
|
return "4GB";
|
||||||
if (size.getRam() >= 2 * 1024 || size.getDisk() >= 110)
|
if (size.getRam() >= 2 * 1024 || size.getDisk() >= 110)
|
||||||
return "2GB";
|
return "2GB";
|
||||||
|
@ -258,15 +274,8 @@ public class GoGridComputeServiceContextModule extends GoGridContextModule {
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
@Named("NOT_RUNNING")
|
Location getDefaultLocation(
|
||||||
protected Predicate<CommandUsingClient> runScriptRunning(ScriptStatusReturnsZero stateRunning) {
|
@Named(PROPERTY_GOGRID_DEFAULT_DC) final String defaultDC,
|
||||||
return new RetryablePredicate<CommandUsingClient>(Predicates.not(stateRunning), 600, 3,
|
|
||||||
TimeUnit.SECONDS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
Location getDefaultLocation(@Named(PROPERTY_GOGRID_DEFAULT_DC) final String defaultDC,
|
|
||||||
Set<? extends Location> locations) {
|
Set<? extends Location> locations) {
|
||||||
return Iterables.find(locations, new Predicate<Location>() {
|
return Iterables.find(locations, new Predicate<Location>() {
|
||||||
|
|
||||||
|
@ -280,13 +289,14 @@ public class GoGridComputeServiceContextModule extends GoGridContextModule {
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
Set<? extends Location> getDefaultLocations(GoGridClient sync, LogHolder holder,
|
Set<? extends Location> getDefaultLocations(GoGridClient sync,
|
||||||
Function<ComputeMetadata, String> indexer) {
|
LogHolder holder, Function<ComputeMetadata, String> indexer) {
|
||||||
final Set<Location> locations = Sets.newHashSet();
|
final Set<Location> locations = Sets.newHashSet();
|
||||||
holder.logger.debug(">> providing locations");
|
holder.logger.debug(">> providing locations");
|
||||||
Location parent = new LocationImpl(LocationScope.PROVIDER, providerName, providerName, null);
|
Location parent = new LocationImpl(LocationScope.PROVIDER, providerName,
|
||||||
locations.add(new LocationImpl(LocationScope.ZONE, "SANFRANCISCO", "San Francisco, CA",
|
providerName, null);
|
||||||
parent));
|
locations.add(new LocationImpl(LocationScope.ZONE, "SANFRANCISCO",
|
||||||
|
"San Francisco, CA", parent));
|
||||||
holder.logger.debug("<< locations(%d)", locations.size());
|
holder.logger.debug("<< locations(%d)", locations.size());
|
||||||
return locations;
|
return locations;
|
||||||
}
|
}
|
||||||
|
@ -304,27 +314,28 @@ public class GoGridComputeServiceContextModule extends GoGridContextModule {
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
protected Set<? extends Size> provideSizes(GoGridClient sync, Set<? extends Image> images,
|
protected Set<? extends Size> provideSizes(GoGridClient sync,
|
||||||
LogHolder holder, Function<ComputeMetadata, String> indexer)
|
Set<? extends Image> images, LogHolder holder,
|
||||||
|
Function<ComputeMetadata, String> indexer)
|
||||||
throws InterruptedException, TimeoutException, ExecutionException {
|
throws InterruptedException, TimeoutException, ExecutionException {
|
||||||
final Set<Size> sizes = Sets.newHashSet();
|
final Set<Size> sizes = Sets.newHashSet();
|
||||||
holder.logger.debug(">> providing sizes");
|
holder.logger.debug(">> providing sizes");
|
||||||
|
|
||||||
sizes.add(new SizeImpl("1", "1", "1", null, null, ImmutableMap.<String, String> of(), 0.5,
|
sizes.add(new SizeImpl("1", "1", "1", null, null, ImmutableMap
|
||||||
512, 30, architectureIn(ImmutableSet.<Architecture> of(Architecture.X86_32,
|
.<String, String> of(), 0.5, 512, 30, architectureIn(ImmutableSet
|
||||||
Architecture.X86_64))));
|
.<Architecture> of(Architecture.X86_32, Architecture.X86_64))));
|
||||||
sizes.add(new SizeImpl("2", "2", "2", null, null, ImmutableMap.<String, String> of(), 1,
|
sizes.add(new SizeImpl("2", "2", "2", null, null, ImmutableMap
|
||||||
1024, 60, architectureIn(ImmutableSet.<Architecture> of(Architecture.X86_32,
|
.<String, String> of(), 1, 1024, 60, architectureIn(ImmutableSet
|
||||||
Architecture.X86_64))));
|
.<Architecture> of(Architecture.X86_32, Architecture.X86_64))));
|
||||||
sizes.add(new SizeImpl("3", "3", "3", null, null, ImmutableMap.<String, String> of(), 2,
|
sizes.add(new SizeImpl("3", "3", "3", null, null, ImmutableMap
|
||||||
2048, 120, architectureIn(ImmutableSet.<Architecture> of(Architecture.X86_32,
|
.<String, String> of(), 2, 2048, 120, architectureIn(ImmutableSet
|
||||||
Architecture.X86_64))));
|
.<Architecture> of(Architecture.X86_32, Architecture.X86_64))));
|
||||||
sizes.add(new SizeImpl("4", "4", "4", null, null, ImmutableMap.<String, String> of(), 4,
|
sizes.add(new SizeImpl("4", "4", "4", null, null, ImmutableMap
|
||||||
4096, 240, architectureIn(ImmutableSet.<Architecture> of(Architecture.X86_32,
|
.<String, String> of(), 4, 4096, 240, architectureIn(ImmutableSet
|
||||||
Architecture.X86_64))));
|
.<Architecture> of(Architecture.X86_32, Architecture.X86_64))));
|
||||||
sizes.add(new SizeImpl("5", "5", "5", null, null, ImmutableMap.<String, String> of(), 8,
|
sizes.add(new SizeImpl("5", "5", "5", null, null, ImmutableMap
|
||||||
8192, 480, architectureIn(ImmutableSet.<Architecture> of(Architecture.X86_32,
|
.<String, String> of(), 8, 8192, 480, architectureIn(ImmutableSet
|
||||||
Architecture.X86_64))));
|
.<Architecture> of(Architecture.X86_32, Architecture.X86_64))));
|
||||||
holder.logger.debug("<< sizes(%d)", sizes.size());
|
holder.logger.debug("<< sizes(%d)", sizes.size());
|
||||||
return sizes;
|
return sizes;
|
||||||
}
|
}
|
||||||
|
@ -335,12 +346,14 @@ public class GoGridComputeServiceContextModule extends GoGridContextModule {
|
||||||
protected Logger logger = Logger.NULL;
|
protected Logger logger = Logger.NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final Pattern GOGRID_OS_NAME_PATTERN = Pattern.compile("([a-zA-Z]*)(.*)");
|
public static final Pattern GOGRID_OS_NAME_PATTERN = Pattern
|
||||||
|
.compile("([a-zA-Z]*)(.*)");
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
protected Set<? extends Image> provideImages(final GoGridClient sync, LogHolder holder,
|
protected Set<? extends Image> provideImages(final GoGridClient sync,
|
||||||
Function<ComputeMetadata, String> indexer, Location location,
|
LogHolder holder, Function<ComputeMetadata, String> indexer,
|
||||||
|
Location location,
|
||||||
PopulateDefaultLoginCredentialsForImageStrategy authenticator)
|
PopulateDefaultLoginCredentialsForImageStrategy authenticator)
|
||||||
throws InterruptedException, ExecutionException, TimeoutException {
|
throws InterruptedException, ExecutionException, TimeoutException {
|
||||||
final Set<Image> images = Sets.newHashSet();
|
final Set<Image> images = Sets.newHashSet();
|
||||||
|
@ -348,24 +361,27 @@ public class GoGridComputeServiceContextModule extends GoGridContextModule {
|
||||||
Set<ServerImage> allImages = sync.getImageServices().getImageList();
|
Set<ServerImage> allImages = sync.getImageServices().getImageList();
|
||||||
for (ServerImage from : allImages) {
|
for (ServerImage from : allImages) {
|
||||||
OsFamily os = null;
|
OsFamily os = null;
|
||||||
Architecture arch = (from.getOs().getName().indexOf("64") == -1 && from.getDescription()
|
Architecture arch = (from.getOs().getName().indexOf("64") == -1 && from
|
||||||
.indexOf("64") == -1) ? Architecture.X86_32 : Architecture.X86_64;
|
.getDescription().indexOf("64") == -1) ? Architecture.X86_32
|
||||||
|
: Architecture.X86_64;
|
||||||
String osDescription;
|
String osDescription;
|
||||||
String version = "";
|
String version = "";
|
||||||
|
|
||||||
osDescription = from.getOs().getName();
|
osDescription = from.getOs().getName();
|
||||||
|
|
||||||
String matchedOs = GoGridUtils.parseStringByPatternAndGetNthMatchGroup(from.getOs()
|
String matchedOs = GoGridUtils
|
||||||
.getName(), GOGRID_OS_NAME_PATTERN, 1);
|
.parseStringByPatternAndGetNthMatchGroup(from.getOs().getName(),
|
||||||
|
GOGRID_OS_NAME_PATTERN, 1);
|
||||||
try {
|
try {
|
||||||
os = OsFamily.fromValue(matchedOs.toLowerCase());
|
os = OsFamily.fromValue(matchedOs.toLowerCase());
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
holder.logger.debug("<< didn't match os(%s)", matchedOs);
|
holder.logger.debug("<< didn't match os(%s)", matchedOs);
|
||||||
}
|
}
|
||||||
Credentials defaultCredentials = authenticator.execute(from);
|
Credentials defaultCredentials = authenticator.execute(from);
|
||||||
images.add(new ImageImpl(from.getId() + "", from.getFriendlyName(), from.getId() + "",
|
images.add(new ImageImpl(from.getId() + "", from.getFriendlyName(),
|
||||||
location, null, ImmutableMap.<String, String> of(), from.getDescription(),
|
from.getId() + "", location, null, ImmutableMap
|
||||||
version, os, osDescription, arch, defaultCredentials));
|
.<String, String> of(), from.getDescription(), version,
|
||||||
|
os, osDescription, arch, defaultCredentials));
|
||||||
}
|
}
|
||||||
holder.logger.debug("<< images(%d)", images.size());
|
holder.logger.debug("<< images(%d)", images.size());
|
||||||
return images;
|
return images;
|
||||||
|
|
|
@ -22,7 +22,6 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
@ -30,6 +29,7 @@ import javax.inject.Singleton;
|
||||||
import org.jclouds.compute.domain.NodeMetadata;
|
import org.jclouds.compute.domain.NodeMetadata;
|
||||||
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.reference.ComputeServiceConstants.Timeouts;
|
||||||
import org.jclouds.compute.strategy.AddNodeWithTagStrategy;
|
import org.jclouds.compute.strategy.AddNodeWithTagStrategy;
|
||||||
import org.jclouds.gogrid.GoGridClient;
|
import org.jclouds.gogrid.GoGridClient;
|
||||||
import org.jclouds.gogrid.domain.Ip;
|
import org.jclouds.gogrid.domain.Ip;
|
||||||
|
@ -57,14 +57,17 @@ public class GoGridAddNodeWithTagStrategy implements AddNodeWithTagStrategy {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
protected GoGridAddNodeWithTagStrategy(GoGridClient client,
|
protected GoGridAddNodeWithTagStrategy(GoGridClient client,
|
||||||
Function<Server, NodeMetadata> serverToNodeMetadata, Function<Size, String> sizeToRam) {
|
Function<Server, NodeMetadata> serverToNodeMetadata,
|
||||||
|
Function<Size, String> sizeToRam, Timeouts timeouts) {
|
||||||
this.client = client;
|
this.client = client;
|
||||||
this.serverToNodeMetadata = serverToNodeMetadata;
|
this.serverToNodeMetadata = serverToNodeMetadata;
|
||||||
this.sizeToRam = sizeToRam;
|
this.sizeToRam = sizeToRam;
|
||||||
this.serverLatestJobCompleted = new RetryablePredicate<Server>(new ServerLatestJobCompleted(
|
this.serverLatestJobCompleted = new RetryablePredicate<Server>(
|
||||||
client.getJobServices()), 800, 20, TimeUnit.SECONDS);
|
new ServerLatestJobCompleted(client.getJobServices()),
|
||||||
|
timeouts.nodeRunning * 9l / 10l);
|
||||||
this.serverLatestJobCompletedShort = new RetryablePredicate<Server>(
|
this.serverLatestJobCompletedShort = new RetryablePredicate<Server>(
|
||||||
new ServerLatestJobCompleted(client.getJobServices()), 60, 20, TimeUnit.SECONDS);
|
new ServerLatestJobCompleted(client.getJobServices()),
|
||||||
|
timeouts.nodeRunning * 1l / 10l);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -73,12 +76,15 @@ public class GoGridAddNodeWithTagStrategy implements AddNodeWithTagStrategy {
|
||||||
boolean notStarted = true;
|
boolean notStarted = true;
|
||||||
int numOfRetries = 20;
|
int numOfRetries = 20;
|
||||||
// lock-free consumption of a shared resource: IP address pool
|
// lock-free consumption of a shared resource: IP address pool
|
||||||
while (notStarted) { // TODO: replace with Predicate-based thread collision avoidance for
|
while (notStarted) { // TODO: replace with Predicate-based thread
|
||||||
|
// collision avoidance for
|
||||||
// simplicity
|
// simplicity
|
||||||
Set<Ip> availableIps = client.getIpServices().getIpList(
|
Set<Ip> availableIps = client.getIpServices().getIpList(
|
||||||
new GetIpListOptions().onlyUnassigned().onlyWithType(IpType.PUBLIC));
|
new GetIpListOptions().onlyUnassigned().onlyWithType(
|
||||||
|
IpType.PUBLIC));
|
||||||
if (availableIps.size() == 0)
|
if (availableIps.size() == 0)
|
||||||
throw new RuntimeException("No public IPs available on this account.");
|
throw new RuntimeException(
|
||||||
|
"No public IPs available on this account.");
|
||||||
int ipIndex = new SecureRandom().nextInt(availableIps.size());
|
int ipIndex = new SecureRandom().nextInt(availableIps.size());
|
||||||
Ip availableIp = Iterables.get(availableIps, ipIndex);
|
Ip availableIp = Iterables.get(availableIps, ipIndex);
|
||||||
try {
|
try {
|
||||||
|
@ -90,13 +96,14 @@ public class GoGridAddNodeWithTagStrategy implements AddNodeWithTagStrategy {
|
||||||
notStarted = true;
|
notStarted = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (template.getOptions().shouldBlockUntilRunning()) {
|
||||||
serverLatestJobCompleted.apply(addedServer);
|
serverLatestJobCompleted.apply(addedServer);
|
||||||
|
client.getServerServices().power(addedServer.getName(),
|
||||||
client.getServerServices().power(addedServer.getName(), PowerCommand.START);
|
PowerCommand.START);
|
||||||
serverLatestJobCompletedShort.apply(addedServer);
|
serverLatestJobCompletedShort.apply(addedServer);
|
||||||
|
addedServer = Iterables.getOnlyElement(client.getServerServices()
|
||||||
addedServer = Iterables.getOnlyElement(client.getServerServices().getServersByName(
|
.getServersByName(addedServer.getName()));
|
||||||
addedServer.getName()));
|
}
|
||||||
return serverToNodeMetadata.apply(addedServer);
|
return serverToNodeMetadata.apply(addedServer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -60,13 +60,9 @@ import org.jclouds.http.RequiresHttp;
|
||||||
import org.jclouds.http.annotation.ClientError;
|
import org.jclouds.http.annotation.ClientError;
|
||||||
import org.jclouds.http.annotation.Redirection;
|
import org.jclouds.http.annotation.Redirection;
|
||||||
import org.jclouds.http.annotation.ServerError;
|
import org.jclouds.http.annotation.ServerError;
|
||||||
import org.jclouds.net.IPSocket;
|
|
||||||
import org.jclouds.predicates.RetryablePredicate;
|
|
||||||
import org.jclouds.predicates.SocketOpen;
|
|
||||||
import org.jclouds.rest.ConfiguresRestClient;
|
import org.jclouds.rest.ConfiguresRestClient;
|
||||||
import org.jclouds.rest.config.RestClientModule;
|
import org.jclouds.rest.config.RestClientModule;
|
||||||
|
|
||||||
import com.google.common.base.Predicate;
|
|
||||||
import com.google.common.base.Supplier;
|
import com.google.common.base.Supplier;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
|
@ -80,7 +76,8 @@ import com.google.inject.Provides;
|
||||||
*/
|
*/
|
||||||
@RequiresHttp
|
@RequiresHttp
|
||||||
@ConfiguresRestClient
|
@ConfiguresRestClient
|
||||||
public class GoGridRestClientModule extends RestClientModule<GoGridClient, GoGridAsyncClient> {
|
public class GoGridRestClientModule extends
|
||||||
|
RestClientModule<GoGridClient, GoGridAsyncClient> {
|
||||||
public static final Map<Class<?>, Class<?>> DELEGATE_MAP = ImmutableMap
|
public static final Map<Class<?>, Class<?>> DELEGATE_MAP = ImmutableMap
|
||||||
.<Class<?>, Class<?>> builder()//
|
.<Class<?>, Class<?>> builder()//
|
||||||
.put(GridServerClient.class, GridServerAsyncClient.class)//
|
.put(GridServerClient.class, GridServerAsyncClient.class)//
|
||||||
|
@ -97,7 +94,8 @@ public class GoGridRestClientModule extends RestClientModule<GoGridClient, GoGri
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
@GoGrid
|
@GoGrid
|
||||||
protected URI provideURI(@Named(GoGridConstants.PROPERTY_GOGRID_ENDPOINT) String endpoint) {
|
protected URI provideURI(
|
||||||
|
@Named(GoGridConstants.PROPERTY_GOGRID_ENDPOINT) String endpoint) {
|
||||||
return URI.create(endpoint);
|
return URI.create(endpoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,28 +105,28 @@ public class GoGridRestClientModule extends RestClientModule<GoGridClient, GoGri
|
||||||
return cache.get();
|
return cache.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
protected Predicate<IPSocket> socketTester(SocketOpen open) {
|
|
||||||
return new RetryablePredicate<IPSocket>(open, 130, 1, TimeUnit.SECONDS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
@com.google.inject.name.Named(Constants.PROPERTY_GSON_ADAPTERS)
|
@com.google.inject.name.Named(Constants.PROPERTY_GSON_ADAPTERS)
|
||||||
public Map<Class, Object> provideCustomAdapterBindings() {
|
public Map<Class, Object> provideCustomAdapterBindings() {
|
||||||
Map<Class, Object> bindings = Maps.newHashMap();
|
Map<Class, Object> bindings = Maps.newHashMap();
|
||||||
bindings.put(ObjectType.class, new CustomDeserializers.ObjectTypeAdapter());
|
bindings.put(ObjectType.class,
|
||||||
bindings.put(LoadBalancerOs.class, new CustomDeserializers.LoadBalancerOsAdapter());
|
new CustomDeserializers.ObjectTypeAdapter());
|
||||||
bindings.put(LoadBalancerState.class, new CustomDeserializers.LoadBalancerStateAdapter());
|
bindings.put(LoadBalancerOs.class,
|
||||||
|
new CustomDeserializers.LoadBalancerOsAdapter());
|
||||||
|
bindings.put(LoadBalancerState.class,
|
||||||
|
new CustomDeserializers.LoadBalancerStateAdapter());
|
||||||
bindings.put(LoadBalancerPersistenceType.class,
|
bindings.put(LoadBalancerPersistenceType.class,
|
||||||
new CustomDeserializers.LoadBalancerPersistenceTypeAdapter());
|
new CustomDeserializers.LoadBalancerPersistenceTypeAdapter());
|
||||||
bindings.put(LoadBalancerType.class, new CustomDeserializers.LoadBalancerTypeAdapter());
|
bindings.put(LoadBalancerType.class,
|
||||||
|
new CustomDeserializers.LoadBalancerTypeAdapter());
|
||||||
bindings.put(IpState.class, new CustomDeserializers.IpStateAdapter());
|
bindings.put(IpState.class, new CustomDeserializers.IpStateAdapter());
|
||||||
bindings.put(JobState.class, new CustomDeserializers.JobStateAdapter());
|
bindings.put(JobState.class, new CustomDeserializers.JobStateAdapter());
|
||||||
bindings.put(ServerImageState.class, new CustomDeserializers.ServerImageStateAdapter());
|
bindings.put(ServerImageState.class,
|
||||||
bindings.put(ServerImageType.class, new CustomDeserializers.ServerImageTypeAdapter());
|
new CustomDeserializers.ServerImageStateAdapter());
|
||||||
|
bindings.put(ServerImageType.class,
|
||||||
|
new CustomDeserializers.ServerImageTypeAdapter());
|
||||||
return bindings;
|
return bindings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,7 +135,8 @@ public class GoGridRestClientModule extends RestClientModule<GoGridClient, GoGri
|
||||||
*/
|
*/
|
||||||
@Provides
|
@Provides
|
||||||
@TimeStamp
|
@TimeStamp
|
||||||
Supplier<Long> provideTimeStampCache(@Named(PROPERTY_GOGRID_SESSIONINTERVAL) long seconds) {
|
Supplier<Long> provideTimeStampCache(
|
||||||
|
@Named(PROPERTY_GOGRID_SESSIONINTERVAL) long seconds) {
|
||||||
return new ExpirableSupplier<Long>(new Supplier<Long>() {
|
return new ExpirableSupplier<Long>(new Supplier<Long>() {
|
||||||
public Long get() {
|
public Long get() {
|
||||||
return System.currentTimeMillis() / 1000;
|
return System.currentTimeMillis() / 1000;
|
||||||
|
@ -147,9 +146,12 @@ public class GoGridRestClientModule extends RestClientModule<GoGridClient, GoGri
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void bindErrorHandlers() {
|
protected void bindErrorHandlers() {
|
||||||
bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(GoGridErrorHandler.class);
|
bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(
|
||||||
bind(HttpErrorHandler.class).annotatedWith(ClientError.class).to(GoGridErrorHandler.class);
|
GoGridErrorHandler.class);
|
||||||
bind(HttpErrorHandler.class).annotatedWith(ServerError.class).to(GoGridErrorHandler.class);
|
bind(HttpErrorHandler.class).annotatedWith(ClientError.class).to(
|
||||||
|
GoGridErrorHandler.class);
|
||||||
|
bind(HttpErrorHandler.class).annotatedWith(ServerError.class).to(
|
||||||
|
GoGridErrorHandler.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -46,9 +46,9 @@ public class ServerToNodeMetadataTest {
|
||||||
|
|
||||||
expect(server.getId()).andReturn(1000l).atLeastOnce();
|
expect(server.getId()).andReturn(1000l).atLeastOnce();
|
||||||
expect(server.getName()).andReturn("tag-ff").atLeastOnce();
|
expect(server.getName()).andReturn("tag-ff").atLeastOnce();
|
||||||
expect(server.getState()).andReturn(new Option("RUNNING")).atLeastOnce();
|
expect(server.getState()).andReturn(new Option("NODE_RUNNING")).atLeastOnce();
|
||||||
|
|
||||||
expect(serverStateToNodeState.get("RUNNING")).andReturn(NodeState.RUNNING);
|
expect(serverStateToNodeState.get("NODE_RUNNING")).andReturn(NodeState.RUNNING);
|
||||||
Location location = new LocationImpl(LocationScope.ZONE, "sanfran", "description", null);
|
Location location = new LocationImpl(LocationScope.ZONE, "sanfran", "description", null);
|
||||||
|
|
||||||
Map<String, Credentials> credentialsMap = createMock(Map.class);
|
Map<String, Credentials> credentialsMap = createMock(Map.class);
|
||||||
|
|
|
@ -27,7 +27,6 @@ import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
@ -37,6 +36,7 @@ import javax.inject.Singleton;
|
||||||
import org.jclouds.Constants;
|
import org.jclouds.Constants;
|
||||||
import org.jclouds.compute.ComputeServiceContext;
|
import org.jclouds.compute.ComputeServiceContext;
|
||||||
import org.jclouds.compute.LoadBalancerService;
|
import org.jclouds.compute.LoadBalancerService;
|
||||||
|
import org.jclouds.compute.config.ComputeServiceTimeoutsModule;
|
||||||
import org.jclouds.compute.domain.Architecture;
|
import org.jclouds.compute.domain.Architecture;
|
||||||
import org.jclouds.compute.domain.ComputeMetadata;
|
import org.jclouds.compute.domain.ComputeMetadata;
|
||||||
import org.jclouds.compute.domain.Image;
|
import org.jclouds.compute.domain.Image;
|
||||||
|
@ -50,8 +50,6 @@ import org.jclouds.compute.domain.internal.ImageImpl;
|
||||||
import org.jclouds.compute.domain.internal.SizeImpl;
|
import org.jclouds.compute.domain.internal.SizeImpl;
|
||||||
import org.jclouds.compute.internal.ComputeServiceContextImpl;
|
import org.jclouds.compute.internal.ComputeServiceContextImpl;
|
||||||
import org.jclouds.compute.predicates.NodePredicates;
|
import org.jclouds.compute.predicates.NodePredicates;
|
||||||
import org.jclouds.compute.predicates.ScriptStatusReturnsZero;
|
|
||||||
import org.jclouds.compute.predicates.ScriptStatusReturnsZero.CommandUsingClient;
|
|
||||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||||
import org.jclouds.compute.strategy.AddNodeWithTagStrategy;
|
import org.jclouds.compute.strategy.AddNodeWithTagStrategy;
|
||||||
import org.jclouds.compute.strategy.DestroyNodeStrategy;
|
import org.jclouds.compute.strategy.DestroyNodeStrategy;
|
||||||
|
@ -71,13 +69,9 @@ import org.jclouds.ibmdev.config.IBMDeveloperCloudContextModule;
|
||||||
import org.jclouds.ibmdev.domain.Instance;
|
import org.jclouds.ibmdev.domain.Instance;
|
||||||
import org.jclouds.ibmdev.reference.IBMDeveloperCloudConstants;
|
import org.jclouds.ibmdev.reference.IBMDeveloperCloudConstants;
|
||||||
import org.jclouds.logging.Logger;
|
import org.jclouds.logging.Logger;
|
||||||
import org.jclouds.net.IPSocket;
|
|
||||||
import org.jclouds.predicates.RetryablePredicate;
|
|
||||||
import org.jclouds.predicates.SocketOpen;
|
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
import com.google.common.base.Predicates;
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
|
@ -91,7 +85,8 @@ import com.google.inject.util.Providers;
|
||||||
/**
|
/**
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public class IBMDeveloperCloudComputeServiceContextModule extends IBMDeveloperCloudContextModule {
|
public class IBMDeveloperCloudComputeServiceContextModule extends
|
||||||
|
IBMDeveloperCloudContextModule {
|
||||||
|
|
||||||
private final String providerName;
|
private final String providerName;
|
||||||
|
|
||||||
|
@ -103,6 +98,7 @@ public class IBMDeveloperCloudComputeServiceContextModule extends IBMDeveloperCl
|
||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
super.configure();
|
super.configure();
|
||||||
|
install(new ComputeServiceTimeoutsModule());
|
||||||
bind(new TypeLiteral<Function<Instance, NodeMetadata>>() {
|
bind(new TypeLiteral<Function<Instance, NodeMetadata>>() {
|
||||||
}).to(InstanceToNodeMetadata.class);
|
}).to(InstanceToNodeMetadata.class);
|
||||||
bind(new TypeLiteral<ComputeServiceContext>() {
|
bind(new TypeLiteral<ComputeServiceContext>() {
|
||||||
|
@ -110,18 +106,18 @@ public class IBMDeveloperCloudComputeServiceContextModule extends IBMDeveloperCl
|
||||||
.to(
|
.to(
|
||||||
new TypeLiteral<ComputeServiceContextImpl<IBMDeveloperCloudClient, IBMDeveloperCloudAsyncClient>>() {
|
new TypeLiteral<ComputeServiceContextImpl<IBMDeveloperCloudClient, IBMDeveloperCloudAsyncClient>>() {
|
||||||
}).in(Scopes.SINGLETON);
|
}).in(Scopes.SINGLETON);
|
||||||
bind(AddNodeWithTagStrategy.class).to(IBMDeveloperCloudAddNodeWithTagStrategy.class);
|
bind(AddNodeWithTagStrategy.class).to(
|
||||||
bind(ListNodesStrategy.class).to(IBMDeveloperCloudListNodesStrategy.class);
|
IBMDeveloperCloudAddNodeWithTagStrategy.class);
|
||||||
bind(GetNodeMetadataStrategy.class).to(IBMDeveloperCloudGetNodeMetadataStrategy.class);
|
bind(ListNodesStrategy.class)
|
||||||
bind(RebootNodeStrategy.class).to(IBMDeveloperCloudRebootNodeStrategy.class);
|
.to(IBMDeveloperCloudListNodesStrategy.class);
|
||||||
bind(DestroyNodeStrategy.class).to(IBMDeveloperCloudDestroyNodeStrategy.class);
|
bind(GetNodeMetadataStrategy.class).to(
|
||||||
bind(LoadBalancerService.class).toProvider(Providers.<LoadBalancerService> of(null));
|
IBMDeveloperCloudGetNodeMetadataStrategy.class);
|
||||||
}
|
bind(RebootNodeStrategy.class).to(
|
||||||
|
IBMDeveloperCloudRebootNodeStrategy.class);
|
||||||
@Provides
|
bind(DestroyNodeStrategy.class).to(
|
||||||
@Singleton
|
IBMDeveloperCloudDestroyNodeStrategy.class);
|
||||||
protected Predicate<IPSocket> socketTester(SocketOpen open) {
|
bind(LoadBalancerService.class).toProvider(
|
||||||
return new RetryablePredicate<IPSocket>(open, 130, 1, TimeUnit.SECONDS);
|
Providers.<LoadBalancerService> of(null));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -155,19 +151,23 @@ public class IBMDeveloperCloudComputeServiceContextModule extends IBMDeveloperCl
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
protected CreateKeyPairEncodeTagIntoNameRunNodesAndAddToSet(
|
protected CreateKeyPairEncodeTagIntoNameRunNodesAndAddToSet(
|
||||||
AddNodeWithTagStrategy addNodeWithTagStrategy, ListNodesStrategy listNodesStrategy,
|
AddNodeWithTagStrategy addNodeWithTagStrategy,
|
||||||
@Named("NAMING_CONVENTION") String nodeNamingConvention, ComputeUtils utils,
|
ListNodesStrategy listNodesStrategy,
|
||||||
|
@Named("NAMING_CONVENTION") String nodeNamingConvention,
|
||||||
|
ComputeUtils utils,
|
||||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor,
|
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor,
|
||||||
IBMDeveloperCloudClient client,
|
IBMDeveloperCloudClient client,
|
||||||
@Named("CREDENTIALS") Map<String, String> credentialsMap) {
|
@Named("CREDENTIALS") Map<String, String> credentialsMap) {
|
||||||
super(addNodeWithTagStrategy, listNodesStrategy, nodeNamingConvention, utils, executor);
|
super(addNodeWithTagStrategy, listNodesStrategy, nodeNamingConvention,
|
||||||
|
utils, executor);
|
||||||
this.client = checkNotNull(client, "client");
|
this.client = checkNotNull(client, "client");
|
||||||
this.credentialsMap = checkNotNull(credentialsMap, "credentialsMap");
|
this.credentialsMap = checkNotNull(credentialsMap, "credentialsMap");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<?, ListenableFuture<Void>> execute(String tag, int count, Template template,
|
public Map<?, ListenableFuture<Void>> execute(String tag, int count,
|
||||||
Set<NodeMetadata> nodes, Map<NodeMetadata, Exception> badNodes) {
|
Template template, Set<NodeMetadata> nodes,
|
||||||
|
Map<NodeMetadata, Exception> badNodes) {
|
||||||
String key = template.getOptions().getPublicKey();
|
String key = template.getOptions().getPublicKey();
|
||||||
if (key != null) {
|
if (key != null) {
|
||||||
template.getOptions().dontAuthorizePublicKey();
|
template.getOptions().dontAuthorizePublicKey();
|
||||||
|
@ -178,7 +178,8 @@ public class IBMDeveloperCloudComputeServiceContextModule extends IBMDeveloperCl
|
||||||
client.updatePublicKey(tag, key);
|
client.updatePublicKey(tag, key);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
credentialsMap.put(tag, client.generateKeyPair(tag).getKeyMaterial());
|
credentialsMap.put(tag, client.generateKeyPair(tag)
|
||||||
|
.getKeyMaterial());
|
||||||
}
|
}
|
||||||
return super.execute(tag, count, template, nodes, badNodes);
|
return super.execute(tag, count, template, nodes, badNodes);
|
||||||
}
|
}
|
||||||
|
@ -186,57 +187,58 @@ public class IBMDeveloperCloudComputeServiceContextModule extends IBMDeveloperCl
|
||||||
}
|
}
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public static class IBMDeveloperCloudAddNodeWithTagStrategy implements AddNodeWithTagStrategy {
|
public static class IBMDeveloperCloudAddNodeWithTagStrategy implements
|
||||||
|
AddNodeWithTagStrategy {
|
||||||
|
|
||||||
private final IBMDeveloperCloudClient client;
|
private final IBMDeveloperCloudClient client;
|
||||||
private final Predicate<Instance> instanceActive;
|
|
||||||
private final Function<Instance, NodeMetadata> instanceToNodeMetadata;
|
private final Function<Instance, NodeMetadata> instanceToNodeMetadata;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
protected IBMDeveloperCloudAddNodeWithTagStrategy(IBMDeveloperCloudClient client,
|
protected IBMDeveloperCloudAddNodeWithTagStrategy(
|
||||||
@Named("ACTIVE") Predicate<Instance> instanceActive,
|
IBMDeveloperCloudClient client,
|
||||||
Function<Instance, NodeMetadata> instanceToNodeMetadata) {
|
Function<Instance, NodeMetadata> instanceToNodeMetadata) {
|
||||||
this.client = checkNotNull(client, "client");
|
this.client = checkNotNull(client, "client");
|
||||||
this.instanceActive = checkNotNull(instanceActive, "instanceActive");
|
|
||||||
this.instanceToNodeMetadata = checkNotNull(instanceToNodeMetadata,
|
this.instanceToNodeMetadata = checkNotNull(instanceToNodeMetadata,
|
||||||
"instanceToNodeMetadata");
|
"instanceToNodeMetadata");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NodeMetadata execute(String tag, String name, Template template) {
|
public NodeMetadata execute(String tag, String name, Template template) {
|
||||||
Instance instance = client.createInstanceInLocation(template.getLocation().getId(), name,
|
Instance instance = client.createInstanceInLocation(template
|
||||||
template.getImage().getProviderId(), template.getSize().getProviderId(),
|
.getLocation().getId(), name, template.getImage()
|
||||||
|
.getProviderId(), template.getSize().getProviderId(),
|
||||||
authorizePublicKey(tag));
|
authorizePublicKey(tag));
|
||||||
instanceActive.apply(instance);
|
return instanceToNodeMetadata.apply(client.getInstance(instance
|
||||||
return instanceToNodeMetadata.apply(client.getInstance(instance.getId()));
|
.getId()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public static class IBMDeveloperCloudRebootNodeStrategy implements RebootNodeStrategy {
|
public static class IBMDeveloperCloudRebootNodeStrategy implements
|
||||||
|
RebootNodeStrategy {
|
||||||
|
|
||||||
private final IBMDeveloperCloudClient client;
|
private final IBMDeveloperCloudClient client;
|
||||||
private final Predicate<Instance> instanceActive;
|
private final GetNodeMetadataStrategy getNode;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
protected IBMDeveloperCloudRebootNodeStrategy(IBMDeveloperCloudClient client,
|
protected IBMDeveloperCloudRebootNodeStrategy(
|
||||||
@Named("ACTIVE") Predicate<Instance> instanceActive) {
|
IBMDeveloperCloudClient client, GetNodeMetadataStrategy getNode) {
|
||||||
this.client = checkNotNull(client, "client");
|
this.client = checkNotNull(client, "client");
|
||||||
this.instanceActive = checkNotNull(instanceActive, "instanceActive");
|
this.getNode = checkNotNull(getNode, "getNode");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean execute(String id) {
|
public NodeMetadata execute(String id) {
|
||||||
client.restartInstance(id);
|
client.restartInstance(id);
|
||||||
return instanceActive.apply(client.getInstance(id));
|
return getNode.execute(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
@Provides
|
@Provides
|
||||||
Map<Instance.Status, NodeState> provideServerToNodeState() {
|
Map<Instance.Status, NodeState> provideServerToNodeState() {
|
||||||
return ImmutableMap.<Instance.Status, NodeState> builder().put(Instance.Status.ACTIVE,
|
return ImmutableMap.<Instance.Status, NodeState> builder().put(
|
||||||
NodeState.RUNNING)//
|
Instance.Status.ACTIVE, NodeState.RUNNING)//
|
||||||
.put(Instance.Status.STOPPED, NodeState.SUSPENDED)//
|
.put(Instance.Status.STOPPED, NodeState.SUSPENDED)//
|
||||||
.put(Instance.Status.REMOVED, NodeState.TERMINATED)//
|
.put(Instance.Status.REMOVED, NodeState.TERMINATED)//
|
||||||
.put(Instance.Status.DEPROVISIONING, NodeState.PENDING)//
|
.put(Instance.Status.DEPROVISIONING, NodeState.PENDING)//
|
||||||
|
@ -251,12 +253,14 @@ public class IBMDeveloperCloudComputeServiceContextModule extends IBMDeveloperCl
|
||||||
}
|
}
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public static class IBMDeveloperCloudListNodesStrategy implements ListNodesStrategy {
|
public static class IBMDeveloperCloudListNodesStrategy implements
|
||||||
|
ListNodesStrategy {
|
||||||
private final IBMDeveloperCloudClient client;
|
private final IBMDeveloperCloudClient client;
|
||||||
private final Function<Instance, NodeMetadata> instanceToNodeMetadata;
|
private final Function<Instance, NodeMetadata> instanceToNodeMetadata;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
protected IBMDeveloperCloudListNodesStrategy(IBMDeveloperCloudClient client,
|
protected IBMDeveloperCloudListNodesStrategy(
|
||||||
|
IBMDeveloperCloudClient client,
|
||||||
Function<Instance, NodeMetadata> instanceToNodeMetadata) {
|
Function<Instance, NodeMetadata> instanceToNodeMetadata) {
|
||||||
this.client = client;
|
this.client = client;
|
||||||
this.instanceToNodeMetadata = instanceToNodeMetadata;
|
this.instanceToNodeMetadata = instanceToNodeMetadata;
|
||||||
|
@ -270,18 +274,20 @@ public class IBMDeveloperCloudComputeServiceContextModule extends IBMDeveloperCl
|
||||||
@Override
|
@Override
|
||||||
public Iterable<? extends NodeMetadata> listDetailsOnNodesMatching(
|
public Iterable<? extends NodeMetadata> listDetailsOnNodesMatching(
|
||||||
Predicate<ComputeMetadata> filter) {
|
Predicate<ComputeMetadata> filter) {
|
||||||
return Iterables.filter(Iterables
|
return Iterables.filter(Iterables.transform(client.listInstances(),
|
||||||
.transform(client.listInstances(), instanceToNodeMetadata), filter);
|
instanceToNodeMetadata), filter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public static class IBMDeveloperCloudGetNodeMetadataStrategy implements GetNodeMetadataStrategy {
|
public static class IBMDeveloperCloudGetNodeMetadataStrategy implements
|
||||||
|
GetNodeMetadataStrategy {
|
||||||
private final IBMDeveloperCloudClient client;
|
private final IBMDeveloperCloudClient client;
|
||||||
private final Function<Instance, NodeMetadata> instanceToNodeMetadata;
|
private final Function<Instance, NodeMetadata> instanceToNodeMetadata;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
protected IBMDeveloperCloudGetNodeMetadataStrategy(IBMDeveloperCloudClient client,
|
protected IBMDeveloperCloudGetNodeMetadataStrategy(
|
||||||
|
IBMDeveloperCloudClient client,
|
||||||
Function<Instance, NodeMetadata> instanceToNodeMetadata) {
|
Function<Instance, NodeMetadata> instanceToNodeMetadata) {
|
||||||
this.client = client;
|
this.client = client;
|
||||||
this.instanceToNodeMetadata = instanceToNodeMetadata;
|
this.instanceToNodeMetadata = instanceToNodeMetadata;
|
||||||
|
@ -290,37 +296,31 @@ public class IBMDeveloperCloudComputeServiceContextModule extends IBMDeveloperCl
|
||||||
@Override
|
@Override
|
||||||
public NodeMetadata execute(String id) {
|
public NodeMetadata execute(String id) {
|
||||||
Instance instance = client.getInstance(checkNotNull(id, "id"));
|
Instance instance = client.getInstance(checkNotNull(id, "id"));
|
||||||
return instance == null ? null : instanceToNodeMetadata.apply(instance);
|
return instance == null ? null : instanceToNodeMetadata
|
||||||
|
.apply(instance);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public static class IBMDeveloperCloudDestroyNodeStrategy implements DestroyNodeStrategy {
|
public static class IBMDeveloperCloudDestroyNodeStrategy implements
|
||||||
|
DestroyNodeStrategy {
|
||||||
private final IBMDeveloperCloudClient client;
|
private final IBMDeveloperCloudClient client;
|
||||||
private final Predicate<Instance> instanceRemoved;
|
private final GetNodeMetadataStrategy getNode;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
protected IBMDeveloperCloudDestroyNodeStrategy(IBMDeveloperCloudClient client,
|
protected IBMDeveloperCloudDestroyNodeStrategy(
|
||||||
@Named("REMOVED") Predicate<Instance> instanceRemoved) {
|
IBMDeveloperCloudClient client, GetNodeMetadataStrategy getNode) {
|
||||||
this.client = checkNotNull(client, "client");
|
this.client = checkNotNull(client, "client");
|
||||||
this.instanceRemoved = checkNotNull(instanceRemoved, "instanceRemoved");
|
this.getNode = checkNotNull(getNode, "getNode");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean execute(String id) {
|
public NodeMetadata execute(String id) {
|
||||||
client.deleteInstance(id);
|
client.deleteInstance(id);
|
||||||
return instanceRemoved.apply(client.getInstance(id));
|
return getNode.execute(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
@Named("NOT_RUNNING")
|
|
||||||
protected Predicate<CommandUsingClient> runScriptRunning(ScriptStatusReturnsZero stateRunning) {
|
|
||||||
return new RetryablePredicate<CommandUsingClient>(Predicates.not(stateRunning), 600, 3,
|
|
||||||
TimeUnit.SECONDS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
Location getDefaultLocation(
|
Location getDefaultLocation(
|
||||||
|
@ -338,14 +338,16 @@ public class IBMDeveloperCloudComputeServiceContextModule extends IBMDeveloperCl
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
Set<? extends Location> getAssignableLocations(IBMDeveloperCloudClient sync, LogHolder holder) {
|
Set<? extends Location> getAssignableLocations(IBMDeveloperCloudClient sync,
|
||||||
|
LogHolder holder) {
|
||||||
final Set<Location> assignableLocations = Sets.newHashSet();
|
final Set<Location> assignableLocations = Sets.newHashSet();
|
||||||
holder.logger.debug(">> providing locations");
|
holder.logger.debug(">> providing locations");
|
||||||
Location parent = new LocationImpl(LocationScope.PROVIDER, providerName, providerName, null);
|
Location parent = new LocationImpl(LocationScope.PROVIDER, providerName,
|
||||||
|
providerName, null);
|
||||||
|
|
||||||
for (org.jclouds.ibmdev.domain.Location location : sync.listLocations())
|
for (org.jclouds.ibmdev.domain.Location location : sync.listLocations())
|
||||||
assignableLocations.add(new LocationImpl(LocationScope.ZONE, location.getId(), location
|
assignableLocations.add(new LocationImpl(LocationScope.ZONE, location
|
||||||
.getName(), parent));
|
.getId(), location.getName(), parent));
|
||||||
|
|
||||||
holder.logger.debug("<< locations(%d)", assignableLocations.size());
|
holder.logger.debug("<< locations(%d)", assignableLocations.size());
|
||||||
return assignableLocations;
|
return assignableLocations;
|
||||||
|
@ -353,36 +355,40 @@ public class IBMDeveloperCloudComputeServiceContextModule extends IBMDeveloperCl
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
protected Set<? extends Size> provideSizes(IBMDeveloperCloudClient sync, LogHolder holder,
|
protected Set<? extends Size> provideSizes(IBMDeveloperCloudClient sync,
|
||||||
Map<String, ? extends Location> locations) {
|
LogHolder holder, Map<String, ? extends Location> locations) {
|
||||||
final Set<Size> sizes = Sets.newHashSet();
|
final Set<Size> sizes = Sets.newHashSet();
|
||||||
holder.logger.debug(">> providing sizes");
|
holder.logger.debug(">> providing sizes");
|
||||||
|
|
||||||
for (org.jclouds.ibmdev.domain.Location location : sync.listLocations()) {
|
for (org.jclouds.ibmdev.domain.Location location : sync.listLocations()) {
|
||||||
Location assignedLocation = locations.get(location.getId());
|
Location assignedLocation = locations.get(location.getId());
|
||||||
// TODO we cannot query actual size, yet, so lets make the multipliers work out
|
// TODO we cannot query actual size, yet, so lets make the
|
||||||
|
// multipliers work out
|
||||||
int sizeMultiplier = 1;
|
int sizeMultiplier = 1;
|
||||||
for (String i386 : location.getCapabilities().get(
|
for (String i386 : location.getCapabilities().get(
|
||||||
IBMDeveloperCloudConstants.CAPABILITY_I386).keySet())
|
IBMDeveloperCloudConstants.CAPABILITY_I386).keySet())
|
||||||
sizes.add(buildSize(location, i386, assignedLocation, sizeMultiplier++));
|
sizes.add(buildSize(location, i386, assignedLocation,
|
||||||
|
sizeMultiplier++));
|
||||||
for (String x86_64 : location.getCapabilities().get(
|
for (String x86_64 : location.getCapabilities().get(
|
||||||
IBMDeveloperCloudConstants.CAPABILITY_x86_64).keySet())
|
IBMDeveloperCloudConstants.CAPABILITY_x86_64).keySet())
|
||||||
sizes.add(buildSize(location, x86_64, assignedLocation, sizeMultiplier++));
|
sizes.add(buildSize(location, x86_64, assignedLocation,
|
||||||
|
sizeMultiplier++));
|
||||||
}
|
}
|
||||||
holder.logger.debug("<< sizes(%d)", sizes.size());
|
holder.logger.debug("<< sizes(%d)", sizes.size());
|
||||||
return sizes;
|
return sizes;
|
||||||
}
|
}
|
||||||
|
|
||||||
private SizeImpl buildSize(org.jclouds.ibmdev.domain.Location location, final String id,
|
private SizeImpl buildSize(org.jclouds.ibmdev.domain.Location location,
|
||||||
Location assignedLocation, int multiplier) {
|
final String id, Location assignedLocation, int multiplier) {
|
||||||
return new SizeImpl(id, id, location.getId() + "/" + id, assignedLocation, null, ImmutableMap
|
return new SizeImpl(id, id, location.getId() + "/" + id,
|
||||||
.<String, String> of(), multiplier, multiplier * 1024, multiplier * 10,
|
assignedLocation, null, ImmutableMap.<String, String> of(),
|
||||||
|
multiplier, multiplier * 1024, multiplier * 10,
|
||||||
new Predicate<Image>() {
|
new Predicate<Image>() {
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Image input) {
|
public boolean apply(Image input) {
|
||||||
if (input instanceof IBMImage)
|
if (input instanceof IBMImage)
|
||||||
return IBMImage.class.cast(input).rawImage.getSupportedInstanceTypes()
|
return IBMImage.class.cast(input).rawImage
|
||||||
.contains(id);
|
.getSupportedInstanceTypes().contains(id);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -391,7 +397,8 @@ public class IBMDeveloperCloudComputeServiceContextModule extends IBMDeveloperCl
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
protected Map<String, ? extends Image> provideImageMap(Set<? extends Image> locations) {
|
protected Map<String, ? extends Image> provideImageMap(
|
||||||
|
Set<? extends Image> locations) {
|
||||||
return Maps.uniqueIndex(locations, new Function<Image, String>() {
|
return Maps.uniqueIndex(locations, new Function<Image, String>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -404,7 +411,8 @@ public class IBMDeveloperCloudComputeServiceContextModule extends IBMDeveloperCl
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
protected Map<String, ? extends Location> provideLocationMap(Set<? extends Location> locations) {
|
protected Map<String, ? extends Location> provideLocationMap(
|
||||||
|
Set<? extends Location> locations) {
|
||||||
return Maps.uniqueIndex(locations, new Function<Location, String>() {
|
return Maps.uniqueIndex(locations, new Function<Location, String>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -417,8 +425,9 @@ public class IBMDeveloperCloudComputeServiceContextModule extends IBMDeveloperCl
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
protected Set<? extends Image> provideImages(final IBMDeveloperCloudClient sync,
|
protected Set<? extends Image> provideImages(
|
||||||
LogHolder holder, Map<String, ? extends Location> locations) {
|
final IBMDeveloperCloudClient sync, LogHolder holder,
|
||||||
|
Map<String, ? extends Location> locations) {
|
||||||
final Set<Image> images = Sets.newHashSet();
|
final Set<Image> images = Sets.newHashSet();
|
||||||
holder.logger.debug(">> providing images");
|
holder.logger.debug(">> providing images");
|
||||||
|
|
||||||
|
@ -441,11 +450,13 @@ public class IBMDeveloperCloudComputeServiceContextModule extends IBMDeveloperCl
|
||||||
// TODO manifest fails to parse due to encoding issues in the path
|
// TODO manifest fails to parse due to encoding issues in the path
|
||||||
// TODO get correct default credentials
|
// TODO get correct default credentials
|
||||||
// http://www-180.ibm.com/cloud/enterprise/beta/ram/community/_rlvid.jsp.faces?_rap=pc_DiscussionForum.doDiscussionTopic&_rvip=/community/discussionForum.jsp&guid={DA689AEE-783C-6FE7-6F9F-DFEE9763F806}&v=1&submission=false&fid=1068&tid=1527
|
// http://www-180.ibm.com/cloud/enterprise/beta/ram/community/_rlvid.jsp.faces?_rap=pc_DiscussionForum.doDiscussionTopic&_rvip=/community/discussionForum.jsp&guid={DA689AEE-783C-6FE7-6F9F-DFEE9763F806}&v=1&submission=false&fid=1068&tid=1527
|
||||||
super(in.getId(), in.getName(), in.getId(), location, null, ImmutableMap
|
super(in.getId(), in.getName(), in.getId(), location, null,
|
||||||
.<String, String> of(), in.getDescription(), in.getCreatedTime().getTime() + "",
|
ImmutableMap.<String, String> of(), in.getDescription(), in
|
||||||
(in.getPlatform().indexOf("Redhat") != -1) ? OsFamily.RHEL : OsFamily.SUSE, in
|
.getCreatedTime().getTime()
|
||||||
.getPlatform(),
|
+ "",
|
||||||
(in.getPlatform().indexOf("32") != -1) ? Architecture.X86_32
|
(in.getPlatform().indexOf("Redhat") != -1) ? OsFamily.RHEL
|
||||||
|
: OsFamily.SUSE, in.getPlatform(), (in.getPlatform()
|
||||||
|
.indexOf("32") != -1) ? Architecture.X86_32
|
||||||
: Architecture.X86_64, new Credentials("idcuser", null));
|
: Architecture.X86_64, new Credentials("idcuser", null));
|
||||||
this.rawImage = in;
|
this.rawImage = in;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,6 @@ package org.jclouds.ibmdev.config;
|
||||||
|
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
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;
|
||||||
|
@ -35,16 +34,11 @@ import org.jclouds.http.filters.BasicAuthentication;
|
||||||
import org.jclouds.ibmdev.IBMDeveloperCloud;
|
import org.jclouds.ibmdev.IBMDeveloperCloud;
|
||||||
import org.jclouds.ibmdev.IBMDeveloperCloudAsyncClient;
|
import org.jclouds.ibmdev.IBMDeveloperCloudAsyncClient;
|
||||||
import org.jclouds.ibmdev.IBMDeveloperCloudClient;
|
import org.jclouds.ibmdev.IBMDeveloperCloudClient;
|
||||||
import org.jclouds.ibmdev.domain.Instance;
|
|
||||||
import org.jclouds.ibmdev.handlers.IBMDeveloperCloudErrorHandler;
|
import org.jclouds.ibmdev.handlers.IBMDeveloperCloudErrorHandler;
|
||||||
import org.jclouds.ibmdev.predicates.InstanceActive;
|
|
||||||
import org.jclouds.ibmdev.predicates.InstanceRemovedOrNotFound;
|
|
||||||
import org.jclouds.ibmdev.reference.IBMDeveloperCloudConstants;
|
import org.jclouds.ibmdev.reference.IBMDeveloperCloudConstants;
|
||||||
import org.jclouds.predicates.RetryablePredicate;
|
|
||||||
import org.jclouds.rest.ConfiguresRestClient;
|
import org.jclouds.rest.ConfiguresRestClient;
|
||||||
import org.jclouds.rest.config.RestClientModule;
|
import org.jclouds.rest.config.RestClientModule;
|
||||||
|
|
||||||
import com.google.common.base.Predicate;
|
|
||||||
import com.google.inject.Provides;
|
import com.google.inject.Provides;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -61,13 +55,13 @@ public class IBMDeveloperCloudRestClientModule extends
|
||||||
super(IBMDeveloperCloudClient.class, IBMDeveloperCloudAsyncClient.class);
|
super(IBMDeveloperCloudClient.class, IBMDeveloperCloudAsyncClient.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
public BasicAuthentication provideBasicAuthentication(
|
public BasicAuthentication provideBasicAuthentication(
|
||||||
@Named(IBMDeveloperCloudConstants.PROPERTY_IBMDEVELOPERCLOUD_USER) String user,
|
@Named(IBMDeveloperCloudConstants.PROPERTY_IBMDEVELOPERCLOUD_USER) String user,
|
||||||
@Named(IBMDeveloperCloudConstants.PROPERTY_IBMDEVELOPERCLOUD_PASSWORD) String password,
|
@Named(IBMDeveloperCloudConstants.PROPERTY_IBMDEVELOPERCLOUD_PASSWORD) String password,
|
||||||
EncryptionService encryptionService) throws UnsupportedEncodingException {
|
EncryptionService encryptionService)
|
||||||
|
throws UnsupportedEncodingException {
|
||||||
return new BasicAuthentication(user, password, encryptionService);
|
return new BasicAuthentication(user, password, encryptionService);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,18 +88,4 @@ public class IBMDeveloperCloudRestClientModule extends
|
||||||
install(new IBMDeveloperCloudParserModule());
|
install(new IBMDeveloperCloudParserModule());
|
||||||
super.configure();
|
super.configure();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
@Named("ACTIVE")
|
|
||||||
protected Predicate<Instance> instanceActive(InstanceActive instanceActive) {
|
|
||||||
return new RetryablePredicate<Instance>(instanceActive, 1200, 3, TimeUnit.SECONDS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
@Named("REMOVED")
|
|
||||||
Predicate<Instance> instanceRemoved(InstanceRemovedOrNotFound instanceRemoved) {
|
|
||||||
return new RetryablePredicate<Instance>(instanceRemoved, 5000, 500, TimeUnit.MILLISECONDS);
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -49,12 +49,15 @@ public class InstanceActive implements Predicate<Instance> {
|
||||||
public boolean apply(Instance instance) {
|
public boolean apply(Instance instance) {
|
||||||
logger.trace("looking for state on instance %s", instance);
|
logger.trace("looking for state on instance %s", instance);
|
||||||
instance = client.getInstance(instance.getId());
|
instance = client.getInstance(instance.getId());
|
||||||
if (instance == null || instance.getStatus() == Instance.Status.FAILED)
|
if (instance == null)
|
||||||
return false;
|
return false;
|
||||||
logger.trace("%s: looking for instance state %s: currently: %s", instance.getId(),
|
logger.trace("%s: looking for instance state %s: currently: %s", instance
|
||||||
Instance.Status.ACTIVE, instance.getStatus());
|
.getId(), Instance.Status.ACTIVE, instance.getStatus());
|
||||||
|
if (instance.getStatus() == Instance.Status.FAILED)
|
||||||
|
throw new IllegalStateException("node " + instance.getId()
|
||||||
|
+ " in location " + instance.getLocation()
|
||||||
|
+ " is in a failed state");
|
||||||
return instance.getStatus() == Instance.Status.ACTIVE;
|
return instance.getStatus() == Instance.Status.ACTIVE;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,8 +70,8 @@ import com.google.common.io.Files;
|
||||||
@Test(groups = "live", testName = "ibmdevelopercloud.IBMDeveloperCloudClientLiveTest")
|
@Test(groups = "live", testName = "ibmdevelopercloud.IBMDeveloperCloudClientLiveTest")
|
||||||
public class IBMDeveloperCloudClientLiveTest {
|
public class IBMDeveloperCloudClientLiveTest {
|
||||||
|
|
||||||
private static final ImmutableSet<Software> SOFTWARE = ImmutableSet.<Software> of(new Software(
|
private static final ImmutableSet<Software> SOFTWARE = ImmutableSet
|
||||||
"SUSE Linux Enterprise", "OS", "10 SP2"));
|
.<Software> of(new Software("SUSE Linux Enterprise", "OS", "10 SP2"));
|
||||||
private static final String SIZE = "LARGE";
|
private static final String SIZE = "LARGE";
|
||||||
private IBMDeveloperCloudClient connection;
|
private IBMDeveloperCloudClient connection;
|
||||||
private Location location;
|
private Location location;
|
||||||
|
@ -87,11 +87,14 @@ public class IBMDeveloperCloudClientLiveTest {
|
||||||
|
|
||||||
@BeforeGroups(groups = { "live" })
|
@BeforeGroups(groups = { "live" })
|
||||||
public void setupClient() {
|
public void setupClient() {
|
||||||
user = checkNotNull(System.getProperty("jclouds.test.user"), "jclouds.test.user");
|
user = checkNotNull(System.getProperty("jclouds.test.user"),
|
||||||
String password = checkNotNull(System.getProperty("jclouds.test.key"), "jclouds.test.key");
|
"jclouds.test.user");
|
||||||
|
String password = checkNotNull(System.getProperty("jclouds.test.key"),
|
||||||
|
"jclouds.test.key");
|
||||||
|
|
||||||
connection = (IBMDeveloperCloudClient) IBMDeveloperCloudContextFactory.createContext(user,
|
connection = (IBMDeveloperCloudClient) IBMDeveloperCloudContextFactory
|
||||||
password, new Log4JLoggingModule()).getProviderSpecificContext().getApi();
|
.createContext(user, password, new Log4JLoggingModule())
|
||||||
|
.getProviderSpecificContext().getApi();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -118,7 +121,8 @@ public class IBMDeveloperCloudClientLiveTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testListInstancesFromRequestReturnsNull() throws Exception {
|
public void testListInstancesFromRequestReturnsNull() throws Exception {
|
||||||
Set<? extends Instance> response = connection.listInstancesFromRequest(Long.MAX_VALUE + "");
|
Set<? extends Instance> response = connection
|
||||||
|
.listInstancesFromRequest(Long.MAX_VALUE + "");
|
||||||
assertNull(response);
|
assertNull(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,7 +132,8 @@ public class IBMDeveloperCloudClientLiveTest {
|
||||||
assertNotNull(response);
|
assertNotNull(response);
|
||||||
if (response.size() > 0) {
|
if (response.size() > 0) {
|
||||||
Instance instance = Iterables.get(response, 0);
|
Instance instance = Iterables.get(response, 0);
|
||||||
assertEquals(connection.getInstance(instance.getId()).getId(), instance.getId());
|
assertEquals(connection.getInstance(instance.getId()).getId(),
|
||||||
|
instance.getId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,7 +165,8 @@ public class IBMDeveloperCloudClientLiveTest {
|
||||||
assertNotNull(response);
|
assertNotNull(response);
|
||||||
if (response.size() > 0) {
|
if (response.size() > 0) {
|
||||||
Volume image = Iterables.get(response, 0);
|
Volume image = Iterables.get(response, 0);
|
||||||
assertEquals(connection.getVolume(image.getId()).getId(), image.getId());
|
assertEquals(connection.getVolume(image.getId()).getId(), image
|
||||||
|
.getId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,7 +182,8 @@ public class IBMDeveloperCloudClientLiveTest {
|
||||||
assertNotNull(response);
|
assertNotNull(response);
|
||||||
if (response.size() > 0) {
|
if (response.size() > 0) {
|
||||||
location = Iterables.get(response, 0);
|
location = Iterables.get(response, 0);
|
||||||
assertEquals(connection.getLocation(location.getId()).getId(), location.getId());
|
assertEquals(connection.getLocation(location.getId()).getId(),
|
||||||
|
location.getId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,8 +214,9 @@ public class IBMDeveloperCloudClientLiveTest {
|
||||||
if (instance.getStatus() == Instance.Status.FAILED
|
if (instance.getStatus() == Instance.Status.FAILED
|
||||||
|| instance.getStatus() == Instance.Status.ACTIVE) {
|
|| instance.getStatus() == Instance.Status.ACTIVE) {
|
||||||
connection.deleteInstance(instanceId);
|
connection.deleteInstance(instanceId);
|
||||||
assert new RetryablePredicate<Instance>(new InstanceRemovedOrNotFound(connection),
|
assert new RetryablePredicate<Instance>(
|
||||||
30, 2, TimeUnit.SECONDS).apply(instance) : instance;
|
new InstanceRemovedOrNotFound(connection), 30, 2,
|
||||||
|
TimeUnit.SECONDS).apply(instance) : instance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -221,15 +229,18 @@ public class IBMDeveloperCloudClientLiveTest {
|
||||||
public void testAllocateIpAddress() throws Exception {
|
public void testAllocateIpAddress() throws Exception {
|
||||||
try {
|
try {
|
||||||
ip = connection.allocateAddressInLocation(location.getId());
|
ip = connection.allocateAddressInLocation(location.getId());
|
||||||
|
System.out.println(ip);
|
||||||
assertEquals(ip.getIp(), null);
|
assertEquals(ip.getIp(), null);
|
||||||
// wait up to 30 seconds for this to become "free"
|
// wait up to 30 seconds for this to become "free"
|
||||||
new RetryablePredicate<Address>(new AddressFree(connection), 30, 2, TimeUnit.SECONDS)
|
new RetryablePredicate<Address>(new AddressFree(connection), 30, 2,
|
||||||
.apply(ip);
|
TimeUnit.SECONDS).apply(ip);
|
||||||
refreshIpAndReturnAllAddresses();
|
refreshIpAndReturnAllAddresses();
|
||||||
assertEquals(ip.getInstanceId(), null);
|
assertEquals(ip.getInstanceId(), null);
|
||||||
} catch (IllegalStateException e) {
|
} catch (IllegalStateException e) {
|
||||||
if (HttpResponseException.class.cast(e.getCause()).getResponse().getStatusCode() == 409) {
|
if (HttpResponseException.class.cast(e.getCause()).getResponse()
|
||||||
ip = Iterables.find(connection.listAddresses(), new Predicate<Address>() {
|
.getStatusCode() == 409) {
|
||||||
|
ip = Iterables.find(connection.listAddresses(),
|
||||||
|
new Predicate<Address>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Address input) {
|
public boolean apply(Address input) {
|
||||||
|
@ -246,18 +257,21 @@ public class IBMDeveloperCloudClientLiveTest {
|
||||||
|
|
||||||
Set<? extends Address> allAddresses = refreshIpAndReturnAllAddresses();
|
Set<? extends Address> allAddresses = refreshIpAndReturnAllAddresses();
|
||||||
|
|
||||||
assert (allAddresses.contains(ip)) : String.format("ip %s not in %s", ip, allAddresses);
|
assert (allAddresses.contains(ip)) : String.format("ip %s not in %s", ip,
|
||||||
|
allAddresses);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(enabled = false, dependsOnMethods = "testGetLocation")
|
@Test(enabled = false, dependsOnMethods = "testGetLocation")
|
||||||
public void testCreateVolume() throws Exception {
|
public void testCreateVolume() throws Exception {
|
||||||
try {
|
try {
|
||||||
volume = connection.createVolumeInLocation(location.getId(), TAG, "EXT3", "SMALL");
|
volume = connection.createVolumeInLocation(location.getId(), TAG,
|
||||||
|
"EXT3", "SMALL");
|
||||||
// wait up to 5 minutes for this to become "unmounted"
|
// wait up to 5 minutes for this to become "unmounted"
|
||||||
assert new RetryablePredicate<Volume>(new VolumeUnmounted(connection), 300, 5,
|
assert new RetryablePredicate<Volume>(new VolumeUnmounted(connection),
|
||||||
TimeUnit.SECONDS).apply(volume);
|
300, 5, TimeUnit.SECONDS).apply(volume);
|
||||||
} catch (IllegalStateException e) {
|
} catch (IllegalStateException e) {
|
||||||
if (HttpResponseException.class.cast(e.getCause()).getResponse().getStatusCode() == 409) {
|
if (HttpResponseException.class.cast(e.getCause()).getResponse()
|
||||||
|
.getStatusCode() == 409) {
|
||||||
Set<? extends Volume> volumes = connection.listVolumes();
|
Set<? extends Volume> volumes = connection.listVolumes();
|
||||||
try {
|
try {
|
||||||
volume = Iterables.find(volumes, new Predicate<Volume>() {
|
volume = Iterables.find(volumes, new Predicate<Volume>() {
|
||||||
|
@ -269,7 +283,8 @@ public class IBMDeveloperCloudClientLiveTest {
|
||||||
|
|
||||||
});
|
});
|
||||||
} catch (NoSuchElementException ex) {
|
} catch (NoSuchElementException ex) {
|
||||||
throw new RuntimeException("no unmounted volumes in: " + volumes, e);
|
throw new RuntimeException(
|
||||||
|
"no unmounted volumes in: " + volumes, e);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw e;
|
throw e;
|
||||||
|
@ -291,18 +306,29 @@ public class IBMDeveloperCloudClientLiveTest {
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
assert (allVolumes.contains(volume)) : String.format("volume %s not in %s", volume, volume);
|
assert (allVolumes.contains(volume)) : String.format(
|
||||||
|
"volume %s not in %s", volume, volume);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final String IMAGE_ID = "11";// Rational Insight
|
private static final String IMAGE_ID = "11";// Rational Insight
|
||||||
|
|
||||||
@Test(dependsOnMethods = "testAddPublicKey")
|
@Test(dependsOnMethods = { "testAddPublicKey", "testAllocateIpAddress" })
|
||||||
public void testCreateInstance() throws Exception {
|
public void testCreateInstance() throws Exception {
|
||||||
instance = connection.createInstanceInLocation(location.getId(), TAG, IMAGE_ID, SIZE,
|
for (Instance instance : connection.listInstances()) {
|
||||||
configurationData(
|
try {
|
||||||
|
connection.deleteInstance(instance.getId());
|
||||||
|
} catch (Exception e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
System.err.println(connection.getImage(IMAGE_ID));
|
||||||
|
instance = connection.createInstanceInLocation(location.getId(), TAG,
|
||||||
|
IMAGE_ID, SIZE, configurationData(
|
||||||
ImmutableMap.of("insight_admin_password", "myPassword1",
|
ImmutableMap.of("insight_admin_password", "myPassword1",
|
||||||
"db2_admin_password", "myPassword2", "report_user_password",
|
"db2_admin_password", "myPassword2",
|
||||||
"myPassword3")).authorizePublicKey(key.getName()));
|
"report_user_password", "myPassword3"))
|
||||||
|
.authorizePublicKey(key.getName()).attachIp(ip.getId()));
|
||||||
try {
|
try {
|
||||||
assertIpHostAndStatusNEW(instance);
|
assertIpHostAndStatusNEW(instance);
|
||||||
assertConsistent(instance, TAG);
|
assertConsistent(instance, TAG);
|
||||||
|
@ -315,10 +341,12 @@ public class IBMDeveloperCloudClientLiveTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
long start = System.currentTimeMillis();
|
long start = System.currentTimeMillis();
|
||||||
assert new RetryablePredicate<Instance>(new InstanceActive(connection), 600, 2,
|
assert new RetryablePredicate<Instance>(new InstanceActive(connection),
|
||||||
TimeUnit.SECONDS).apply(instance) : connection.getInstance(instance.getId());
|
600, 2, TimeUnit.SECONDS).apply(instance) : connection
|
||||||
|
.getInstance(instance.getId());
|
||||||
|
|
||||||
System.out.println(((System.currentTimeMillis() - start) / 1000) + " seconds");
|
System.out.println(((System.currentTimeMillis() - start) / 1000)
|
||||||
|
+ " seconds");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
assertIpHostAndStatusACTIVE(instance);
|
assertIpHostAndStatusACTIVE(instance);
|
||||||
|
@ -364,17 +392,20 @@ public class IBMDeveloperCloudClientLiveTest {
|
||||||
/**
|
/**
|
||||||
* cannot run an instance due to 500 errors:
|
* cannot run an instance due to 500 errors:
|
||||||
*
|
*
|
||||||
* http://www-180.ibm.com/cloud/enterprise/beta/ram/community/discussionTopic.faces?guid={
|
* http://www-180.ibm.com/cloud/enterprise/beta/ram/community/discussionTopic
|
||||||
|
* .faces?guid={
|
||||||
* DA689AEE-783C-6FE7-6F9F-DFEE9763F806}&v=1&fid=1068&tid=1523#topic
|
* DA689AEE-783C-6FE7-6F9F-DFEE9763F806}&v=1&fid=1068&tid=1523#topic
|
||||||
*/
|
*/
|
||||||
@Test(enabled = false, dependsOnMethods = { "testAddPublicKey", "testAllocateIpAddress",
|
@Test(enabled = false, dependsOnMethods = { "testAddPublicKey",
|
||||||
"testCreateVolume" })
|
"testAllocateIpAddress", "testCreateVolume" })
|
||||||
public void testCreateInstanceWithVolume() throws Exception {
|
public void testCreateInstanceWithVolume() throws Exception {
|
||||||
instance2 = connection.createInstanceInLocation(location.getId(), TAG, IMAGE_ID, SIZE,
|
instance2 = connection.createInstanceInLocation(location.getId(), TAG,
|
||||||
attachIp(ip.getId()).authorizePublicKey(key.getName()).mountVolume(volume.getId(),
|
IMAGE_ID, SIZE, attachIp(ip.getId()).authorizePublicKey(
|
||||||
"/mnt").configurationData(
|
key.getName()).mountVolume(volume.getId(), "/mnt")
|
||||||
ImmutableMap.of("insight_admin_password", "myPassword1",
|
.configurationData(
|
||||||
"db2_admin_password", "myPassword2", "report_user_password",
|
ImmutableMap.of("insight_admin_password",
|
||||||
|
"myPassword1", "db2_admin_password",
|
||||||
|
"myPassword2", "report_user_password",
|
||||||
"myPassword3")));
|
"myPassword3")));
|
||||||
//
|
//
|
||||||
|
|
||||||
|
@ -410,12 +441,14 @@ public class IBMDeveloperCloudClientLiveTest {
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|
||||||
}
|
}
|
||||||
if (ip != null)
|
|
||||||
try {
|
|
||||||
connection.releaseAddress(ip.getId());
|
|
||||||
} catch (Exception e) {
|
|
||||||
|
|
||||||
}
|
// resource contention on ip addresses... lets save it
|
||||||
|
// if (ip != null)
|
||||||
|
// try {
|
||||||
|
// connection.releaseAddress(ip.getId());
|
||||||
|
// } catch (Exception e) {
|
||||||
|
//
|
||||||
|
// }
|
||||||
if (key != null)
|
if (key != null)
|
||||||
try {
|
try {
|
||||||
connection.deleteKey(key.getName());
|
connection.deleteKey(key.getName());
|
||||||
|
@ -440,14 +473,16 @@ public class IBMDeveloperCloudClientLiveTest {
|
||||||
protected void setupKeyPair() throws FileNotFoundException, IOException {
|
protected void setupKeyPair() throws FileNotFoundException, IOException {
|
||||||
String secretKeyFile;
|
String secretKeyFile;
|
||||||
try {
|
try {
|
||||||
secretKeyFile = checkNotNull(System.getProperty("jclouds.test.ssh.keyfile"),
|
secretKeyFile = checkNotNull(System
|
||||||
|
.getProperty("jclouds.test.ssh.keyfile"),
|
||||||
"jclouds.test.ssh.keyfile");
|
"jclouds.test.ssh.keyfile");
|
||||||
} catch (NullPointerException e) {
|
} catch (NullPointerException e) {
|
||||||
secretKeyFile = System.getProperty("user.home") + "/.ssh/id_rsa";
|
secretKeyFile = System.getProperty("user.home") + "/.ssh/id_rsa";
|
||||||
}
|
}
|
||||||
String secret = Files.toString(new File(secretKeyFile), Charsets.UTF_8);
|
String secret = Files.toString(new File(secretKeyFile), Charsets.UTF_8);
|
||||||
assert secret.startsWith("-----BEGIN RSA PRIVATE KEY-----") : "invalid key:\n" + secret;
|
assert secret.startsWith("-----BEGIN RSA PRIVATE KEY-----") : "invalid key:\n"
|
||||||
keyPair = ImmutableMap.<String, String> of("private", secret, "public", Files.toString(
|
+ secret;
|
||||||
new File(secretKeyFile + ".pub"), Charsets.UTF_8));
|
keyPair = ImmutableMap.<String, String> of("private", secret, "public",
|
||||||
|
Files.toString(new File(secretKeyFile + ".pub"), Charsets.UTF_8));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,6 @@ import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
@ -38,6 +37,7 @@ import javax.inject.Singleton;
|
||||||
import org.jclouds.Constants;
|
import org.jclouds.Constants;
|
||||||
import org.jclouds.compute.ComputeServiceContext;
|
import org.jclouds.compute.ComputeServiceContext;
|
||||||
import org.jclouds.compute.LoadBalancerService;
|
import org.jclouds.compute.LoadBalancerService;
|
||||||
|
import org.jclouds.compute.config.ComputeServiceTimeoutsModule;
|
||||||
import org.jclouds.compute.domain.Architecture;
|
import org.jclouds.compute.domain.Architecture;
|
||||||
import org.jclouds.compute.domain.ComputeMetadata;
|
import org.jclouds.compute.domain.ComputeMetadata;
|
||||||
import org.jclouds.compute.domain.Image;
|
import org.jclouds.compute.domain.Image;
|
||||||
|
@ -54,8 +54,6 @@ import org.jclouds.compute.internal.BaseComputeService;
|
||||||
import org.jclouds.compute.internal.ComputeServiceContextImpl;
|
import org.jclouds.compute.internal.ComputeServiceContextImpl;
|
||||||
import org.jclouds.compute.predicates.ImagePredicates;
|
import org.jclouds.compute.predicates.ImagePredicates;
|
||||||
import org.jclouds.compute.predicates.NodePredicates;
|
import org.jclouds.compute.predicates.NodePredicates;
|
||||||
import org.jclouds.compute.predicates.ScriptStatusReturnsZero;
|
|
||||||
import org.jclouds.compute.predicates.ScriptStatusReturnsZero.CommandUsingClient;
|
|
||||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||||
import org.jclouds.compute.strategy.AddNodeWithTagStrategy;
|
import org.jclouds.compute.strategy.AddNodeWithTagStrategy;
|
||||||
import org.jclouds.compute.strategy.DestroyNodeStrategy;
|
import org.jclouds.compute.strategy.DestroyNodeStrategy;
|
||||||
|
@ -67,7 +65,6 @@ import org.jclouds.domain.Location;
|
||||||
import org.jclouds.domain.LocationScope;
|
import org.jclouds.domain.LocationScope;
|
||||||
import org.jclouds.domain.internal.LocationImpl;
|
import org.jclouds.domain.internal.LocationImpl;
|
||||||
import org.jclouds.logging.Logger;
|
import org.jclouds.logging.Logger;
|
||||||
import org.jclouds.predicates.RetryablePredicate;
|
|
||||||
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.compute.functions.ServerToNodeMetadata;
|
import org.jclouds.rackspace.cloudservers.compute.functions.ServerToNodeMetadata;
|
||||||
|
@ -82,7 +79,6 @@ import org.jclouds.rackspace.reference.RackspaceConstants;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
import com.google.common.base.Predicates;
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
|
@ -92,12 +88,13 @@ import com.google.inject.TypeLiteral;
|
||||||
import com.google.inject.util.Providers;
|
import com.google.inject.util.Providers;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configures the {@link CloudServersComputeServiceContext}; requires {@link BaseComputeService}
|
* Configures the {@link CloudServersComputeServiceContext}; requires
|
||||||
* bound.
|
* {@link BaseComputeService} bound.
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public class CloudServersComputeServiceContextModule extends CloudServersContextModule {
|
public class CloudServersComputeServiceContextModule extends
|
||||||
|
CloudServersContextModule {
|
||||||
private final String providerName;
|
private final String providerName;
|
||||||
|
|
||||||
public CloudServersComputeServiceContextModule(String providerName) {
|
public CloudServersComputeServiceContextModule(String providerName) {
|
||||||
|
@ -107,18 +104,22 @@ public class CloudServersComputeServiceContextModule extends CloudServersContext
|
||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
super.configure();
|
super.configure();
|
||||||
|
install(new ComputeServiceTimeoutsModule());
|
||||||
install(new RackspaceLocationsModule(providerName));
|
install(new RackspaceLocationsModule(providerName));
|
||||||
bind(new TypeLiteral<Function<Server, NodeMetadata>>() {
|
bind(new TypeLiteral<Function<Server, NodeMetadata>>() {
|
||||||
}).to(ServerToNodeMetadata.class);
|
}).to(ServerToNodeMetadata.class);
|
||||||
bind(LoadBalancerService.class).toProvider(Providers.<LoadBalancerService> of(null));
|
bind(LoadBalancerService.class).toProvider(
|
||||||
|
Providers.<LoadBalancerService> of(null));
|
||||||
bind(new TypeLiteral<ComputeServiceContext>() {
|
bind(new TypeLiteral<ComputeServiceContext>() {
|
||||||
})
|
})
|
||||||
.to(
|
.to(
|
||||||
new TypeLiteral<ComputeServiceContextImpl<CloudServersClient, CloudServersAsyncClient>>() {
|
new TypeLiteral<ComputeServiceContextImpl<CloudServersClient, CloudServersAsyncClient>>() {
|
||||||
}).in(Scopes.SINGLETON);
|
}).in(Scopes.SINGLETON);
|
||||||
bind(AddNodeWithTagStrategy.class).to(CloudServersAddNodeWithTagStrategy.class);
|
bind(AddNodeWithTagStrategy.class).to(
|
||||||
|
CloudServersAddNodeWithTagStrategy.class);
|
||||||
bind(ListNodesStrategy.class).to(CloudServersListNodesStrategy.class);
|
bind(ListNodesStrategy.class).to(CloudServersListNodesStrategy.class);
|
||||||
bind(GetNodeMetadataStrategy.class).to(CloudServersGetNodeMetadataStrategy.class);
|
bind(GetNodeMetadataStrategy.class).to(
|
||||||
|
CloudServersGetNodeMetadataStrategy.class);
|
||||||
bind(RebootNodeStrategy.class).to(CloudServersRebootNodeStrategy.class);
|
bind(RebootNodeStrategy.class).to(CloudServersRebootNodeStrategy.class);
|
||||||
bind(DestroyNodeStrategy.class).to(CloudServersDestroyNodeStrategy.class);
|
bind(DestroyNodeStrategy.class).to(CloudServersDestroyNodeStrategy.class);
|
||||||
}
|
}
|
||||||
|
@ -132,87 +133,87 @@ public class CloudServersComputeServiceContextModule extends CloudServersContext
|
||||||
@Provides
|
@Provides
|
||||||
@Named("NAMING_CONVENTION")
|
@Named("NAMING_CONVENTION")
|
||||||
@Singleton
|
@Singleton
|
||||||
String provideNamingConvention(@Named(RackspaceConstants.PROPERTY_RACKSPACE_USER) String account) {
|
String provideNamingConvention(
|
||||||
|
@Named(RackspaceConstants.PROPERTY_RACKSPACE_USER) String account) {
|
||||||
return account + "-%s-%s";
|
return account + "-%s-%s";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public static class CloudServersRebootNodeStrategy implements RebootNodeStrategy {
|
public static class CloudServersRebootNodeStrategy implements
|
||||||
|
RebootNodeStrategy {
|
||||||
private final CloudServersClient client;
|
private final CloudServersClient client;
|
||||||
private final Predicate<Server> serverActive;
|
private final GetNodeMetadataStrategy getNode;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
protected CloudServersRebootNodeStrategy(CloudServersClient client,
|
protected CloudServersRebootNodeStrategy(CloudServersClient client,
|
||||||
@Named("ACTIVE") Predicate<Server> serverActive) {
|
GetNodeMetadataStrategy getNode) {
|
||||||
this.client = client;
|
this.client = client;
|
||||||
this.serverActive = serverActive;
|
this.getNode = getNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean execute(String id) {
|
public NodeMetadata execute(String id) {
|
||||||
int serverId = Integer.parseInt(id);
|
int serverId = Integer.parseInt(id);
|
||||||
// if false server wasn't around in the first place
|
// if false server wasn't around in the first place
|
||||||
client.rebootServer(serverId, RebootType.HARD);
|
client.rebootServer(serverId, RebootType.HARD);
|
||||||
Server server = client.getServer(serverId);
|
return getNode.execute(id);
|
||||||
return server == null ? false : serverActive.apply(server);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public static class CloudServersDestroyNodeStrategy implements DestroyNodeStrategy {
|
public static class CloudServersDestroyNodeStrategy implements
|
||||||
|
DestroyNodeStrategy {
|
||||||
private final CloudServersClient client;
|
private final CloudServersClient client;
|
||||||
private final Predicate<Server> serverDeleted;
|
private final GetNodeMetadataStrategy getNode;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
protected CloudServersDestroyNodeStrategy(CloudServersClient client,
|
protected CloudServersDestroyNodeStrategy(CloudServersClient client,
|
||||||
@Named("DELETED") Predicate<Server> serverDeleted) {
|
GetNodeMetadataStrategy getNode) {
|
||||||
this.client = client;
|
this.client = client;
|
||||||
this.serverDeleted = serverDeleted;
|
this.getNode = getNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean execute(String id) {
|
public NodeMetadata execute(String id) {
|
||||||
int serverId = Integer.parseInt(id);
|
int serverId = Integer.parseInt(id);
|
||||||
// if false server wasn't around in the first place
|
// if false server wasn't around in the first place
|
||||||
if (!client.deleteServer(serverId))
|
client.deleteServer(serverId);
|
||||||
return false;
|
return getNode.execute(id);
|
||||||
Server server = client.getServer(serverId);
|
|
||||||
return server == null ? false : serverDeleted.apply(server);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public static class CloudServersAddNodeWithTagStrategy implements AddNodeWithTagStrategy {
|
public static class CloudServersAddNodeWithTagStrategy implements
|
||||||
|
AddNodeWithTagStrategy {
|
||||||
private final CloudServersClient client;
|
private final CloudServersClient client;
|
||||||
private final Predicate<Server> serverActive;
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
protected CloudServersAddNodeWithTagStrategy(CloudServersClient client,
|
protected CloudServersAddNodeWithTagStrategy(CloudServersClient client) {
|
||||||
@Named("ACTIVE") Predicate<Server> serverActive) {
|
|
||||||
this.client = checkNotNull(client, "client");
|
this.client = checkNotNull(client, "client");
|
||||||
this.serverActive = checkNotNull(serverActive, "serverActive");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NodeMetadata execute(String tag, String name, Template template) {
|
public NodeMetadata execute(String tag, String name, Template template) {
|
||||||
Server server = client.createServer(name, Integer.parseInt(template.getImage()
|
Server server = client.createServer(name, Integer.parseInt(template
|
||||||
.getProviderId()), Integer.parseInt(template.getSize().getProviderId()));
|
.getImage().getProviderId()), Integer.parseInt(template
|
||||||
serverActive.apply(server);
|
.getSize().getProviderId()));
|
||||||
return new NodeMetadataImpl(server.getId() + "", name, server.getId() + "",
|
return new NodeMetadataImpl(server.getId() + "", name, server.getId()
|
||||||
new LocationImpl(LocationScope.HOST, server.getHostId(), server.getHostId(),
|
+ "", new LocationImpl(LocationScope.HOST, server.getHostId(),
|
||||||
template.getLocation()), null, server.getMetadata(), tag, template
|
server.getHostId(), template.getLocation()), null, server
|
||||||
.getImage(), NodeState.RUNNING, server.getAddresses()
|
.getMetadata(), tag, template.getImage(), NodeState.PENDING,
|
||||||
.getPublicAddresses(), server.getAddresses().getPrivateAddresses(),
|
server.getAddresses().getPublicAddresses(), server
|
||||||
ImmutableMap.<String, String> of(),
|
.getAddresses().getPrivateAddresses(), ImmutableMap
|
||||||
new Credentials("root", server.getAdminPass()));
|
.<String, String> of(), new Credentials("root", server
|
||||||
|
.getAdminPass()));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public static class CloudServersListNodesStrategy implements ListNodesStrategy {
|
public static class CloudServersListNodesStrategy implements
|
||||||
|
ListNodesStrategy {
|
||||||
private final CloudServersClient client;
|
private final CloudServersClient client;
|
||||||
private final Function<Server, NodeMetadata> serverToNodeMetadata;
|
private final Function<Server, NodeMetadata> serverToNodeMetadata;
|
||||||
|
|
||||||
|
@ -231,13 +232,15 @@ public class CloudServersComputeServiceContextModule extends CloudServersContext
|
||||||
@Override
|
@Override
|
||||||
public Iterable<? extends NodeMetadata> listDetailsOnNodesMatching(
|
public Iterable<? extends NodeMetadata> listDetailsOnNodesMatching(
|
||||||
Predicate<ComputeMetadata> filter) {
|
Predicate<ComputeMetadata> filter) {
|
||||||
return Iterables.filter(Iterables.transform(client.listServers(ListOptions.Builder
|
return Iterables.filter(Iterables.transform(client
|
||||||
.withDetails()), serverToNodeMetadata), filter);
|
.listServers(ListOptions.Builder.withDetails()),
|
||||||
|
serverToNodeMetadata), filter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public static class CloudServersGetNodeMetadataStrategy implements GetNodeMetadataStrategy {
|
public static class CloudServersGetNodeMetadataStrategy implements
|
||||||
|
GetNodeMetadataStrategy {
|
||||||
|
|
||||||
private final CloudServersClient client;
|
private final CloudServersClient client;
|
||||||
private final Function<Server, NodeMetadata> serverToNodeMetadata;
|
private final Function<Server, NodeMetadata> serverToNodeMetadata;
|
||||||
|
@ -260,8 +263,8 @@ public class CloudServersComputeServiceContextModule extends CloudServersContext
|
||||||
@Singleton
|
@Singleton
|
||||||
@Provides
|
@Provides
|
||||||
Map<ServerStatus, NodeState> provideServerToNodeState() {
|
Map<ServerStatus, NodeState> provideServerToNodeState() {
|
||||||
return ImmutableMap.<ServerStatus, NodeState> builder().put(ServerStatus.ACTIVE,
|
return ImmutableMap.<ServerStatus, NodeState> builder().put(
|
||||||
NodeState.RUNNING)//
|
ServerStatus.ACTIVE, NodeState.RUNNING)//
|
||||||
.put(ServerStatus.SUSPENDED, NodeState.SUSPENDED)//
|
.put(ServerStatus.SUSPENDED, NodeState.SUSPENDED)//
|
||||||
.put(ServerStatus.DELETED, NodeState.TERMINATED)//
|
.put(ServerStatus.DELETED, NodeState.TERMINATED)//
|
||||||
.put(ServerStatus.QUEUE_RESIZE, NodeState.PENDING)//
|
.put(ServerStatus.QUEUE_RESIZE, NodeState.PENDING)//
|
||||||
|
@ -286,14 +289,6 @@ public class CloudServersComputeServiceContextModule extends CloudServersContext
|
||||||
.put(ServerStatus.UNKNOWN, NodeState.UNKNOWN).build();
|
.put(ServerStatus.UNKNOWN, NodeState.UNKNOWN).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
@Named("NOT_RUNNING")
|
|
||||||
protected Predicate<CommandUsingClient> runScriptRunning(ScriptStatusReturnsZero stateRunning) {
|
|
||||||
return new RetryablePredicate<CommandUsingClient>(Predicates.not(stateRunning), 600, 3,
|
|
||||||
TimeUnit.SECONDS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
protected Function<ComputeMetadata, String> indexer() {
|
protected Function<ComputeMetadata, String> indexer() {
|
||||||
|
@ -307,17 +302,19 @@ public class CloudServersComputeServiceContextModule extends CloudServersContext
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
protected Set<? extends Size> provideSizes(CloudServersClient sync, Set<? extends Image> images,
|
protected Set<? extends Size> provideSizes(CloudServersClient sync,
|
||||||
Location location, LogHolder holder,
|
Set<? extends Image> images, Location location, LogHolder holder,
|
||||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor,
|
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor,
|
||||||
Function<ComputeMetadata, String> indexer) throws InterruptedException,
|
Function<ComputeMetadata, String> indexer)
|
||||||
TimeoutException, ExecutionException {
|
throws InterruptedException, TimeoutException, ExecutionException {
|
||||||
final Set<Size> sizes = Sets.newHashSet();
|
final Set<Size> sizes = Sets.newHashSet();
|
||||||
holder.logger.debug(">> providing sizes");
|
holder.logger.debug(">> providing sizes");
|
||||||
for (final Flavor from : sync.listFlavors(ListOptions.Builder.withDetails())) {
|
for (final Flavor from : sync.listFlavors(ListOptions.Builder
|
||||||
sizes.add(new SizeImpl(from.getId() + "", from.getName(), from.getId() + "", location,
|
.withDetails())) {
|
||||||
null, ImmutableMap.<String, String> of(), from.getDisk() / 10, from.getRam(),
|
sizes.add(new SizeImpl(from.getId() + "", from.getName(), from.getId()
|
||||||
from.getDisk(), ImagePredicates.any()));
|
+ "", location, null, ImmutableMap.<String, String> of(), from
|
||||||
|
.getDisk() / 10, from.getRam(), from.getDisk(), ImagePredicates
|
||||||
|
.any()));
|
||||||
}
|
}
|
||||||
holder.logger.debug("<< sizes(%d)", sizes.size());
|
holder.logger.debug("<< sizes(%d)", sizes.size());
|
||||||
return sizes;
|
return sizes;
|
||||||
|
@ -329,12 +326,14 @@ public class CloudServersComputeServiceContextModule extends CloudServersContext
|
||||||
protected Logger logger = Logger.NULL;
|
protected Logger logger = Logger.NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final Pattern RACKSPACE_PATTERN = Pattern.compile("(([^ ]*) .*)");
|
public static final Pattern RACKSPACE_PATTERN = Pattern
|
||||||
|
.compile("(([^ ]*) .*)");
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
protected Set<? extends Image> provideImages(final CloudServersClient sync, Location location,
|
protected Set<? extends Image> provideImages(final CloudServersClient sync,
|
||||||
LogHolder holder, Function<ComputeMetadata, String> indexer)
|
Location location, LogHolder holder,
|
||||||
|
Function<ComputeMetadata, String> indexer)
|
||||||
throws InterruptedException, ExecutionException, TimeoutException {
|
throws InterruptedException, ExecutionException, TimeoutException {
|
||||||
final Set<Image> images = Sets.newHashSet();
|
final Set<Image> images = Sets.newHashSet();
|
||||||
holder.logger.debug(">> providing images");
|
holder.logger.debug(">> providing images");
|
||||||
|
@ -357,9 +356,11 @@ public class CloudServersComputeServiceContextModule extends CloudServersContext
|
||||||
holder.logger.debug("<< didn't match os(%s)", matcher.group(2));
|
holder.logger.debug("<< didn't match os(%s)", matcher.group(2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
images.add(new ImageImpl(from.getId() + "", from.getName(), from.getId() + "", location,
|
images.add(new ImageImpl(from.getId() + "", from.getName(), from
|
||||||
null, ImmutableMap.<String, String> of(), from.getName(), version, os,
|
.getId()
|
||||||
osDescription, arch, new Credentials("root", null)));
|
+ "", location, null, ImmutableMap.<String, String> of(), from
|
||||||
|
.getName(), version, os, osDescription, arch, new Credentials(
|
||||||
|
"root", null)));
|
||||||
}
|
}
|
||||||
holder.logger.debug("<< images(%d)", images.size());
|
holder.logger.debug("<< images(%d)", images.size());
|
||||||
return images;
|
return images;
|
||||||
|
|
|
@ -18,31 +18,17 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.rackspace.cloudservers.config;
|
package org.jclouds.rackspace.cloudservers.config;
|
||||||
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import javax.inject.Named;
|
|
||||||
import javax.inject.Singleton;
|
|
||||||
|
|
||||||
import org.jclouds.http.HttpErrorHandler;
|
import org.jclouds.http.HttpErrorHandler;
|
||||||
import org.jclouds.http.RequiresHttp;
|
import org.jclouds.http.RequiresHttp;
|
||||||
import org.jclouds.http.annotation.ClientError;
|
import org.jclouds.http.annotation.ClientError;
|
||||||
import org.jclouds.http.annotation.Redirection;
|
import org.jclouds.http.annotation.Redirection;
|
||||||
import org.jclouds.http.annotation.ServerError;
|
import org.jclouds.http.annotation.ServerError;
|
||||||
import org.jclouds.net.IPSocket;
|
|
||||||
import org.jclouds.predicates.RetryablePredicate;
|
|
||||||
import org.jclouds.predicates.SocketOpen;
|
|
||||||
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.handlers.ParseCloudServersErrorFromHttpResponse;
|
import org.jclouds.rackspace.cloudservers.handlers.ParseCloudServersErrorFromHttpResponse;
|
||||||
import org.jclouds.rackspace.cloudservers.predicates.ServerActive;
|
|
||||||
import org.jclouds.rackspace.cloudservers.predicates.ServerDeleted;
|
|
||||||
import org.jclouds.rest.ConfiguresRestClient;
|
import org.jclouds.rest.ConfiguresRestClient;
|
||||||
import org.jclouds.rest.config.RestClientModule;
|
import org.jclouds.rest.config.RestClientModule;
|
||||||
|
|
||||||
import com.google.common.base.Predicate;
|
|
||||||
import com.google.inject.Provides;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
|
@ -56,26 +42,6 @@ public class CloudServersRestClientModule extends
|
||||||
super(CloudServersClient.class, CloudServersAsyncClient.class);
|
super(CloudServersClient.class, CloudServersAsyncClient.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
@Named("ACTIVE")
|
|
||||||
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
|
|
||||||
@Singleton
|
|
||||||
protected Predicate<IPSocket> socketTester(SocketOpen open) {
|
|
||||||
return new RetryablePredicate<IPSocket>(open, 130, 1, TimeUnit.SECONDS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void bindErrorHandlers() {
|
protected void bindErrorHandlers() {
|
||||||
bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(
|
bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(
|
||||||
|
|
|
@ -27,7 +27,6 @@ import java.util.NoSuchElementException;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
@ -40,6 +39,7 @@ import javax.inject.Singleton;
|
||||||
import org.jclouds.Constants;
|
import org.jclouds.Constants;
|
||||||
import org.jclouds.compute.ComputeServiceContext;
|
import org.jclouds.compute.ComputeServiceContext;
|
||||||
import org.jclouds.compute.LoadBalancerService;
|
import org.jclouds.compute.LoadBalancerService;
|
||||||
|
import org.jclouds.compute.config.ComputeServiceTimeoutsModule;
|
||||||
import org.jclouds.compute.domain.Architecture;
|
import org.jclouds.compute.domain.Architecture;
|
||||||
import org.jclouds.compute.domain.ComputeMetadata;
|
import org.jclouds.compute.domain.ComputeMetadata;
|
||||||
import org.jclouds.compute.domain.Image;
|
import org.jclouds.compute.domain.Image;
|
||||||
|
@ -55,8 +55,6 @@ import org.jclouds.compute.domain.internal.SizeImpl;
|
||||||
import org.jclouds.compute.internal.ComputeServiceContextImpl;
|
import org.jclouds.compute.internal.ComputeServiceContextImpl;
|
||||||
import org.jclouds.compute.predicates.ImagePredicates;
|
import org.jclouds.compute.predicates.ImagePredicates;
|
||||||
import org.jclouds.compute.predicates.NodePredicates;
|
import org.jclouds.compute.predicates.NodePredicates;
|
||||||
import org.jclouds.compute.predicates.ScriptStatusReturnsZero;
|
|
||||||
import org.jclouds.compute.predicates.ScriptStatusReturnsZero.CommandUsingClient;
|
|
||||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||||
import org.jclouds.compute.strategy.AddNodeWithTagStrategy;
|
import org.jclouds.compute.strategy.AddNodeWithTagStrategy;
|
||||||
import org.jclouds.compute.strategy.DestroyNodeStrategy;
|
import org.jclouds.compute.strategy.DestroyNodeStrategy;
|
||||||
|
@ -68,7 +66,6 @@ import org.jclouds.domain.Location;
|
||||||
import org.jclouds.domain.LocationScope;
|
import org.jclouds.domain.LocationScope;
|
||||||
import org.jclouds.domain.internal.LocationImpl;
|
import org.jclouds.domain.internal.LocationImpl;
|
||||||
import org.jclouds.logging.Logger;
|
import org.jclouds.logging.Logger;
|
||||||
import org.jclouds.predicates.RetryablePredicate;
|
|
||||||
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.config.RimuHostingContextModule;
|
import org.jclouds.rimuhosting.miro.config.RimuHostingContextModule;
|
||||||
|
@ -79,7 +76,6 @@ import org.jclouds.rimuhosting.miro.domain.internal.RunningState;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
import com.google.common.base.Predicates;
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
@ -96,7 +92,8 @@ import com.google.inject.util.Providers;
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public class RimuHostingComputeServiceContextModule extends RimuHostingContextModule {
|
public class RimuHostingComputeServiceContextModule extends
|
||||||
|
RimuHostingContextModule {
|
||||||
private final String providerName;
|
private final String providerName;
|
||||||
|
|
||||||
public RimuHostingComputeServiceContextModule(String providerName) {
|
public RimuHostingComputeServiceContextModule(String providerName) {
|
||||||
|
@ -106,9 +103,11 @@ public class RimuHostingComputeServiceContextModule extends RimuHostingContextMo
|
||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
super.configure();
|
super.configure();
|
||||||
|
install(new ComputeServiceTimeoutsModule());
|
||||||
bind(new TypeLiteral<Function<Server, NodeMetadata>>() {
|
bind(new TypeLiteral<Function<Server, NodeMetadata>>() {
|
||||||
}).to(ServerToNodeMetadata.class);
|
}).to(ServerToNodeMetadata.class);
|
||||||
bind(LoadBalancerService.class).toProvider(Providers.<LoadBalancerService> of(null));
|
bind(LoadBalancerService.class).toProvider(
|
||||||
|
Providers.<LoadBalancerService> of(null));
|
||||||
bind(new TypeLiteral<ComputeServiceContext>() {
|
bind(new TypeLiteral<ComputeServiceContext>() {
|
||||||
})
|
})
|
||||||
.to(
|
.to(
|
||||||
|
@ -116,9 +115,11 @@ public class RimuHostingComputeServiceContextModule extends RimuHostingContextMo
|
||||||
}).in(Scopes.SINGLETON);
|
}).in(Scopes.SINGLETON);
|
||||||
bind(new TypeLiteral<Function<Server, Iterable<String>>>() {
|
bind(new TypeLiteral<Function<Server, Iterable<String>>>() {
|
||||||
}).to(ServerToPublicAddresses.class);
|
}).to(ServerToPublicAddresses.class);
|
||||||
bind(AddNodeWithTagStrategy.class).to(RimuHostingAddNodeWithTagStrategy.class);
|
bind(AddNodeWithTagStrategy.class).to(
|
||||||
|
RimuHostingAddNodeWithTagStrategy.class);
|
||||||
bind(ListNodesStrategy.class).to(RimuHostingListNodesStrategy.class);
|
bind(ListNodesStrategy.class).to(RimuHostingListNodesStrategy.class);
|
||||||
bind(GetNodeMetadataStrategy.class).to(RimuHostingGetNodeMetadataStrategy.class);
|
bind(GetNodeMetadataStrategy.class).to(
|
||||||
|
RimuHostingGetNodeMetadataStrategy.class);
|
||||||
bind(RebootNodeStrategy.class).to(RimuHostingRebootNodeStrategy.class);
|
bind(RebootNodeStrategy.class).to(RimuHostingRebootNodeStrategy.class);
|
||||||
bind(DestroyNodeStrategy.class).to(RimuHostingDestroyNodeStrategy.class);
|
bind(DestroyNodeStrategy.class).to(RimuHostingDestroyNodeStrategy.class);
|
||||||
}
|
}
|
||||||
|
@ -126,8 +127,8 @@ public class RimuHostingComputeServiceContextModule extends RimuHostingContextMo
|
||||||
@Provides
|
@Provides
|
||||||
@Named("DEFAULT")
|
@Named("DEFAULT")
|
||||||
protected TemplateBuilder provideTemplate(TemplateBuilder template) {
|
protected TemplateBuilder provideTemplate(TemplateBuilder template) {
|
||||||
return template.sizeId("MIRO1B").osFamily(UBUNTU).architecture(Architecture.X86_32)
|
return template.sizeId("MIRO1B").osFamily(UBUNTU).architecture(
|
||||||
.imageNameMatches(".*10\\.?04.*");
|
Architecture.X86_32).imageNameMatches(".*10\\.?04.*");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
|
@ -138,84 +139,88 @@ public class RimuHostingComputeServiceContextModule extends RimuHostingContextMo
|
||||||
}
|
}
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public static class RimuHostingRebootNodeStrategy implements RebootNodeStrategy {
|
public static class RimuHostingRebootNodeStrategy implements
|
||||||
|
RebootNodeStrategy {
|
||||||
private final RimuHostingClient client;
|
private final RimuHostingClient client;
|
||||||
|
private final GetNodeMetadataStrategy getNode;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
protected RimuHostingRebootNodeStrategy(RimuHostingClient client) {
|
protected RimuHostingRebootNodeStrategy(RimuHostingClient client,
|
||||||
|
GetNodeMetadataStrategy getNode) {
|
||||||
this.client = client;
|
this.client = client;
|
||||||
|
this.getNode = getNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean execute(String id) {
|
public NodeMetadata execute(String id) {
|
||||||
Long serverId = Long.parseLong(id);
|
Long serverId = Long.parseLong(id);
|
||||||
// if false server wasn't around in the first place
|
// if false server wasn't around in the first place
|
||||||
return client.restartServer(serverId).getState() == RunningState.RUNNING;
|
client.restartServer(serverId).getState();
|
||||||
|
return getNode.execute(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public static class RimuHostingDestroyNodeStrategy implements DestroyNodeStrategy {
|
public static class RimuHostingDestroyNodeStrategy implements
|
||||||
|
DestroyNodeStrategy {
|
||||||
private final RimuHostingClient client;
|
private final RimuHostingClient client;
|
||||||
private final Predicate<Server> serverDestroyed;
|
private final GetNodeMetadataStrategy getNode;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
protected RimuHostingDestroyNodeStrategy(RimuHostingClient client,
|
protected RimuHostingDestroyNodeStrategy(RimuHostingClient client,
|
||||||
@Named("DESTROYED") Predicate<Server> serverDestroyed) {
|
GetNodeMetadataStrategy getNode) {
|
||||||
this.client = client;
|
this.client = client;
|
||||||
this.serverDestroyed = serverDestroyed;
|
this.getNode = getNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean execute(String id) {
|
public NodeMetadata execute(String id) {
|
||||||
Long serverId = Long.parseLong(id);
|
Long serverId = Long.parseLong(id);
|
||||||
client.destroyServer(serverId);
|
client.destroyServer(serverId);
|
||||||
return serverDestroyed.apply(client.getServer(serverId));
|
return getNode.execute(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public static class RimuHostingAddNodeWithTagStrategy implements AddNodeWithTagStrategy {
|
public static class RimuHostingAddNodeWithTagStrategy implements
|
||||||
|
AddNodeWithTagStrategy {
|
||||||
private final RimuHostingClient client;
|
private final RimuHostingClient client;
|
||||||
private final Predicate<Server> serverRunning;
|
|
||||||
private final Function<Server, Iterable<String>> getPublicAddresses;
|
private final Function<Server, Iterable<String>> getPublicAddresses;
|
||||||
private final Map<RunningState, NodeState> runningStateToNodeState;
|
private final Map<RunningState, NodeState> runningStateToNodeState;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
protected RimuHostingAddNodeWithTagStrategy(RimuHostingClient client,
|
protected RimuHostingAddNodeWithTagStrategy(RimuHostingClient client,
|
||||||
@Named("RUNNING") Predicate<Server> serverRunning,
|
|
||||||
Function<Server, Iterable<String>> getPublicAddresses,
|
Function<Server, Iterable<String>> getPublicAddresses,
|
||||||
Map<RunningState, NodeState> runningStateToNodeState) {
|
Map<RunningState, NodeState> runningStateToNodeState) {
|
||||||
this.client = client;
|
this.client = client;
|
||||||
this.serverRunning = serverRunning;
|
|
||||||
this.getPublicAddresses = getPublicAddresses;
|
this.getPublicAddresses = getPublicAddresses;
|
||||||
this.runningStateToNodeState = runningStateToNodeState;
|
this.runningStateToNodeState = runningStateToNodeState;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NodeMetadata execute(String tag, String name, Template template) {
|
public NodeMetadata execute(String tag, String name, Template template) {
|
||||||
NewServerResponse serverResponse = client.createServer(name, checkNotNull(template
|
NewServerResponse serverResponse = client.createServer(name,
|
||||||
.getImage().getProviderId(), "imageId"), checkNotNull(template.getSize()
|
checkNotNull(template.getImage().getProviderId(), "imageId"),
|
||||||
.getProviderId(), "sizeId"));
|
checkNotNull(template.getSize().getProviderId(), "sizeId"));
|
||||||
serverRunning.apply(serverResponse.getServer());
|
|
||||||
Server server = client.getServer(serverResponse.getServer().getId());
|
Server server = client.getServer(serverResponse.getServer().getId());
|
||||||
// we have to lookup the new details in order to retrieve the currently assigned ip
|
NodeMetadata node = new NodeMetadataImpl(server.getId().toString(),
|
||||||
// address.
|
name, server.getId().toString(), template.getLocation(), null,
|
||||||
NodeMetadata node = new NodeMetadataImpl(server.getId().toString(), name, server.getId()
|
ImmutableMap.<String, String> of(), tag, template.getImage(),
|
||||||
.toString(), template.getLocation(), null, ImmutableMap.<String, String> of(),
|
runningStateToNodeState.get(server.getState()),
|
||||||
tag, template.getImage(), runningStateToNodeState.get(server.getState()),
|
getPublicAddresses.apply(server), ImmutableList.<String> of(),
|
||||||
getPublicAddresses.apply(server), ImmutableList.<String> of(), ImmutableMap
|
ImmutableMap.<String, String> of(), new Credentials("root",
|
||||||
.<String, String> of(), new Credentials("root", serverResponse
|
serverResponse.getNewInstanceRequest().getCreateOptions()
|
||||||
.getNewInstanceRequest().getCreateOptions().getPassword()));
|
.getPassword()));
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public static class RimuHostingListNodesStrategy implements ListNodesStrategy {
|
public static class RimuHostingListNodesStrategy implements
|
||||||
|
ListNodesStrategy {
|
||||||
private final RimuHostingClient client;
|
private final RimuHostingClient client;
|
||||||
private final Function<Server, NodeMetadata> serverToNodeMetadata;
|
private final Function<Server, NodeMetadata> serverToNodeMetadata;
|
||||||
|
|
||||||
|
@ -234,14 +239,15 @@ public class RimuHostingComputeServiceContextModule extends RimuHostingContextMo
|
||||||
@Override
|
@Override
|
||||||
public Iterable<? extends NodeMetadata> listDetailsOnNodesMatching(
|
public Iterable<? extends NodeMetadata> listDetailsOnNodesMatching(
|
||||||
Predicate<ComputeMetadata> filter) {
|
Predicate<ComputeMetadata> filter) {
|
||||||
return Iterables.filter(Iterables.transform(client.getServerList(), serverToNodeMetadata),
|
return Iterables.filter(Iterables.transform(client.getServerList(),
|
||||||
filter);
|
serverToNodeMetadata), filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public static class RimuHostingGetNodeMetadataStrategy implements GetNodeMetadataStrategy {
|
public static class RimuHostingGetNodeMetadataStrategy implements
|
||||||
|
GetNodeMetadataStrategy {
|
||||||
|
|
||||||
private final RimuHostingClient client;
|
private final RimuHostingClient client;
|
||||||
private final Function<Server, NodeMetadata> serverToNodeMetadata;
|
private final Function<Server, NodeMetadata> serverToNodeMetadata;
|
||||||
|
@ -264,8 +270,8 @@ public class RimuHostingComputeServiceContextModule extends RimuHostingContextMo
|
||||||
@Singleton
|
@Singleton
|
||||||
@Provides
|
@Provides
|
||||||
Map<RunningState, NodeState> provideServerToNodeState() {
|
Map<RunningState, NodeState> provideServerToNodeState() {
|
||||||
return ImmutableMap.<RunningState, NodeState> builder().put(RunningState.RUNNING,
|
return ImmutableMap.<RunningState, NodeState> builder().put(
|
||||||
NodeState.RUNNING)//
|
RunningState.RUNNING, NodeState.RUNNING)//
|
||||||
.put(RunningState.NOTRUNNING, NodeState.SUSPENDED)//
|
.put(RunningState.NOTRUNNING, NodeState.SUSPENDED)//
|
||||||
.put(RunningState.POWERCYCLING, NodeState.PENDING)//
|
.put(RunningState.POWERCYCLING, NodeState.PENDING)//
|
||||||
.put(RunningState.RESTARTING, NodeState.PENDING)//
|
.put(RunningState.RESTARTING, NodeState.PENDING)//
|
||||||
|
@ -273,7 +279,8 @@ public class RimuHostingComputeServiceContextModule extends RimuHostingContextMo
|
||||||
}
|
}
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
private static class ServerToNodeMetadata implements Function<Server, NodeMetadata> {
|
private static class ServerToNodeMetadata implements
|
||||||
|
Function<Server, NodeMetadata> {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
protected Logger logger = Logger.NULL;
|
protected Logger logger = Logger.NULL;
|
||||||
|
@ -295,17 +302,20 @@ public class RimuHostingComputeServiceContextModule extends RimuHostingContextMo
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Image input) {
|
public boolean apply(Image input) {
|
||||||
return input.getProviderId().equals(instance.getImageId())
|
return input.getProviderId().equals(instance.getImageId())
|
||||||
&& (input.getLocation() == null || input.getLocation().equals(location) || input
|
&& (input.getLocation() == null
|
||||||
|
|| input.getLocation().equals(location) || input
|
||||||
.getLocation().equals(location.getParent()));
|
.getLocation().equals(location.getParent()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
@Inject
|
@Inject
|
||||||
ServerToNodeMetadata(Function<Server, Iterable<String>> getPublicAddresses,
|
ServerToNodeMetadata(
|
||||||
Map<RunningState, NodeState> runningStateToNodeState, Set<? extends Image> images,
|
Function<Server, Iterable<String>> getPublicAddresses,
|
||||||
Set<? extends Location> locations) {
|
Map<RunningState, NodeState> runningStateToNodeState,
|
||||||
this.getPublicAddresses = checkNotNull(getPublicAddresses, "serverStateToNodeState");
|
Set<? extends Image> images, Set<? extends Location> locations) {
|
||||||
|
this.getPublicAddresses = checkNotNull(getPublicAddresses,
|
||||||
|
"serverStateToNodeState");
|
||||||
this.runningStateToNodeState = checkNotNull(runningStateToNodeState,
|
this.runningStateToNodeState = checkNotNull(runningStateToNodeState,
|
||||||
"serverStateToNodeState");
|
"serverStateToNodeState");
|
||||||
this.images = checkNotNull(images, "images");
|
this.images = checkNotNull(images, "images");
|
||||||
|
@ -315,48 +325,47 @@ public class RimuHostingComputeServiceContextModule extends RimuHostingContextMo
|
||||||
@Override
|
@Override
|
||||||
public NodeMetadata apply(Server from) {
|
public NodeMetadata apply(Server from) {
|
||||||
|
|
||||||
Location location = new LocationImpl(LocationScope.ZONE, from.getLocation().getId(), from
|
Location location = new LocationImpl(LocationScope.ZONE, from
|
||||||
.getLocation().getName(), null);
|
.getLocation().getId(), from.getLocation().getName(), null);
|
||||||
String tag = from.getName().replaceAll("-[0-9]+", "");
|
String tag = from.getName().replaceAll("-[0-9]+", "");
|
||||||
Credentials creds = null;
|
Credentials creds = null;
|
||||||
|
|
||||||
Image image = null;
|
Image image = null;
|
||||||
try {
|
try {
|
||||||
image = Iterables.find(images, new FindImageForServer(location, from));
|
image = Iterables.find(images, new FindImageForServer(location,
|
||||||
|
from));
|
||||||
} catch (NoSuchElementException e) {
|
} catch (NoSuchElementException e) {
|
||||||
logger.warn("could not find a matching image for server %s in location %s", from,
|
logger
|
||||||
location);
|
.warn(
|
||||||
|
"could not find a matching image for server %s in location %s",
|
||||||
|
from, location);
|
||||||
}
|
}
|
||||||
NodeState state = runningStateToNodeState.get(from.getState());
|
NodeState state = runningStateToNodeState.get(from.getState());
|
||||||
return new NodeMetadataImpl(from.getId() + "", from.getName(), from.getId() + "",
|
return new NodeMetadataImpl(from.getId() + "", from.getName(), from
|
||||||
location, null, ImmutableMap.<String, String> of(), tag, image, state,
|
.getId()
|
||||||
getPublicAddresses.apply(from), ImmutableList.<String> of(), ImmutableMap
|
+ "", location, null, ImmutableMap.<String, String> of(), tag,
|
||||||
.<String, String> of(), creds);
|
image, state, getPublicAddresses.apply(from), ImmutableList
|
||||||
|
.<String> of(), ImmutableMap.<String, String> of(), creds);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
private static class ServerToPublicAddresses implements Function<Server, Iterable<String>> {
|
private static class ServerToPublicAddresses implements
|
||||||
|
Function<Server, Iterable<String>> {
|
||||||
@Override
|
@Override
|
||||||
public Iterable<String> apply(Server server) {
|
public Iterable<String> apply(Server server) {
|
||||||
return server.getIpAddresses() == null ? ImmutableSet.<String> of() : Iterables.concat(
|
return server.getIpAddresses() == null ? ImmutableSet.<String> of()
|
||||||
ImmutableList.of(server.getIpAddresses().getPrimaryIp()), server.getIpAddresses()
|
: Iterables.concat(ImmutableList.of(server.getIpAddresses()
|
||||||
|
.getPrimaryIp()), server.getIpAddresses()
|
||||||
.getSecondaryIps());
|
.getSecondaryIps());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
@Named("NOT_RUNNING")
|
Location getDefaultLocation(
|
||||||
protected Predicate<CommandUsingClient> runScriptRunning(ScriptStatusReturnsZero stateRunning) {
|
@Named(PROPERTY_RIMUHOSTING_DEFAULT_DC) final String defaultDC,
|
||||||
return new RetryablePredicate<CommandUsingClient>(Predicates.not(stateRunning), 600, 3,
|
|
||||||
TimeUnit.SECONDS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
Location getDefaultLocation(@Named(PROPERTY_RIMUHOSTING_DEFAULT_DC) final String defaultDC,
|
|
||||||
Set<? extends Location> locations) {
|
Set<? extends Location> locations) {
|
||||||
return Iterables.find(locations, new Predicate<Location>() {
|
return Iterables.find(locations, new Predicate<Location>() {
|
||||||
|
|
||||||
|
@ -370,15 +379,17 @@ public class RimuHostingComputeServiceContextModule extends RimuHostingContextMo
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
Set<? extends Location> getDefaultLocations(RimuHostingClient sync, LogHolder holder,
|
Set<? extends Location> getDefaultLocations(RimuHostingClient sync,
|
||||||
Function<ComputeMetadata, String> indexer) {
|
LogHolder holder, Function<ComputeMetadata, String> indexer) {
|
||||||
final Set<Location> locations = Sets.newHashSet();
|
final Set<Location> locations = Sets.newHashSet();
|
||||||
holder.logger.debug(">> providing locations");
|
holder.logger.debug(">> providing locations");
|
||||||
Location provider = new LocationImpl(LocationScope.PROVIDER, providerName, providerName, null);
|
Location provider = new LocationImpl(LocationScope.PROVIDER,
|
||||||
|
providerName, providerName, null);
|
||||||
for (final PricingPlan from : sync.getPricingPlanList()) {
|
for (final PricingPlan from : sync.getPricingPlanList()) {
|
||||||
try {
|
try {
|
||||||
locations.add(new LocationImpl(LocationScope.ZONE, from.getDataCenter().getId(), from
|
locations.add(new LocationImpl(LocationScope.ZONE, from
|
||||||
.getDataCenter().getName(), provider));
|
.getDataCenter().getId(), from.getDataCenter().getName(),
|
||||||
|
provider));
|
||||||
} catch (NullPointerException e) {
|
} catch (NullPointerException e) {
|
||||||
holder.logger.warn("datacenter not present in " + from.getId());
|
holder.logger.warn("datacenter not present in " + from.getId());
|
||||||
}
|
}
|
||||||
|
@ -400,27 +411,30 @@ public class RimuHostingComputeServiceContextModule extends RimuHostingContextMo
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
protected Set<? extends Size> provideSizes(RimuHostingClient sync, Set<? extends Image> images,
|
protected Set<? extends Size> provideSizes(RimuHostingClient sync,
|
||||||
Set<? extends Location> locations, LogHolder holder,
|
Set<? extends Image> images, Set<? extends Location> locations,
|
||||||
|
LogHolder holder,
|
||||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService userExecutor,
|
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService userExecutor,
|
||||||
Function<ComputeMetadata, String> indexer) throws InterruptedException,
|
Function<ComputeMetadata, String> indexer)
|
||||||
TimeoutException, ExecutionException {
|
throws InterruptedException, TimeoutException, ExecutionException {
|
||||||
final Set<Size> sizes = Sets.newHashSet();
|
final Set<Size> sizes = Sets.newHashSet();
|
||||||
holder.logger.debug(">> providing sizes");
|
holder.logger.debug(">> providing sizes");
|
||||||
for (final PricingPlan from : sync.getPricingPlanList()) {
|
for (final PricingPlan from : sync.getPricingPlanList()) {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
final Location location = Iterables.find(locations, new Predicate<Location>() {
|
final Location location = Iterables.find(locations,
|
||||||
|
new Predicate<Location>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Location input) {
|
public boolean apply(Location input) {
|
||||||
return input.getId().equals(from.getDataCenter().getId());
|
return input.getId().equals(
|
||||||
|
from.getDataCenter().getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
sizes.add(new SizeImpl(from.getId(), from.getId(), from.getId(), location, null,
|
sizes.add(new SizeImpl(from.getId(), from.getId(), from.getId(),
|
||||||
ImmutableMap.<String, String> of(), 1, from.getRam(), from.getDiskSize(),
|
location, null, ImmutableMap.<String, String> of(), 1, from
|
||||||
ImagePredicates.any()));
|
.getRam(), from.getDiskSize(), ImagePredicates.any()));
|
||||||
} catch (NullPointerException e) {
|
} catch (NullPointerException e) {
|
||||||
holder.logger.warn("datacenter not present in " + from.getId());
|
holder.logger.warn("datacenter not present in " + from.getId());
|
||||||
}
|
}
|
||||||
|
@ -439,12 +453,13 @@ public class RimuHostingComputeServiceContextModule extends RimuHostingContextMo
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
protected Set<? extends Image> provideImages(final RimuHostingClient sync, LogHolder holder,
|
protected Set<? extends Image> provideImages(final RimuHostingClient sync,
|
||||||
Function<ComputeMetadata, String> indexer) throws InterruptedException,
|
LogHolder holder, Function<ComputeMetadata, String> indexer)
|
||||||
ExecutionException, TimeoutException {
|
throws InterruptedException, ExecutionException, TimeoutException {
|
||||||
final Set<Image> images = Sets.newHashSet();
|
final Set<Image> images = Sets.newHashSet();
|
||||||
holder.logger.debug(">> providing images");
|
holder.logger.debug(">> providing images");
|
||||||
for (final org.jclouds.rimuhosting.miro.domain.Image from : sync.getImageList()) {
|
for (final org.jclouds.rimuhosting.miro.domain.Image from : sync
|
||||||
|
.getImageList()) {
|
||||||
OsFamily os = null;
|
OsFamily os = null;
|
||||||
Architecture arch = from.getId().indexOf("64") == -1 ? Architecture.X86_32
|
Architecture arch = from.getId().indexOf("64") == -1 ? Architecture.X86_32
|
||||||
: Architecture.X86_64;
|
: Architecture.X86_64;
|
||||||
|
@ -462,9 +477,10 @@ public class RimuHostingComputeServiceContextModule extends RimuHostingContextMo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
images.add(new ImageImpl(from.getId(), from.getDescription(), from.getId(), null, null,
|
images.add(new ImageImpl(from.getId(), from.getDescription(), from
|
||||||
ImmutableMap.<String, String> of(), from.getDescription(), version, os,
|
.getId(), null, null, ImmutableMap.<String, String> of(), from
|
||||||
osDescription, arch, new Credentials("root", null)));
|
.getDescription(), version, os, osDescription, arch,
|
||||||
|
new Credentials("root", null)));
|
||||||
}
|
}
|
||||||
holder.logger.debug("<< images(%d)", images.size());
|
holder.logger.debug("<< images(%d)", images.size());
|
||||||
return images;
|
return images;
|
||||||
|
|
|
@ -20,27 +20,19 @@ package org.jclouds.rimuhosting.miro.config;
|
||||||
|
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
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.net.IPSocket;
|
|
||||||
import org.jclouds.predicates.RetryablePredicate;
|
|
||||||
import org.jclouds.predicates.SocketOpen;
|
|
||||||
import org.jclouds.rest.ConfiguresRestClient;
|
import org.jclouds.rest.ConfiguresRestClient;
|
||||||
import org.jclouds.rest.config.RestClientModule;
|
import org.jclouds.rest.config.RestClientModule;
|
||||||
import org.jclouds.rimuhosting.miro.RimuHosting;
|
import org.jclouds.rimuhosting.miro.RimuHosting;
|
||||||
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.domain.Server;
|
|
||||||
import org.jclouds.rimuhosting.miro.filters.RimuHostingAuthentication;
|
import org.jclouds.rimuhosting.miro.filters.RimuHostingAuthentication;
|
||||||
import org.jclouds.rimuhosting.miro.predicates.ServerDestroyed;
|
|
||||||
import org.jclouds.rimuhosting.miro.predicates.ServerRunning;
|
|
||||||
import org.jclouds.rimuhosting.miro.reference.RimuHostingConstants;
|
import org.jclouds.rimuhosting.miro.reference.RimuHostingConstants;
|
||||||
|
|
||||||
import com.google.common.base.Predicate;
|
|
||||||
import com.google.inject.Provides;
|
import com.google.inject.Provides;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -57,26 +49,6 @@ public class RimuHostingRestClientModule extends
|
||||||
super(RimuHostingClient.class, RimuHostingAsyncClient.class);
|
super(RimuHostingClient.class, RimuHostingAsyncClient.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
@Named("RUNNING")
|
|
||||||
protected Predicate<Server> serverRunning(ServerRunning stateRunning) {
|
|
||||||
return new RetryablePredicate<Server>(stateRunning, 600, 1, TimeUnit.SECONDS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
@Named("DESTROYED")
|
|
||||||
protected Predicate<Server> serverDeleted(ServerDestroyed stateDeleted) {
|
|
||||||
return new RetryablePredicate<Server>(stateDeleted, 600, 50, TimeUnit.MILLISECONDS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
protected Predicate<IPSocket> socketTester(SocketOpen open) {
|
|
||||||
return new RetryablePredicate<IPSocket>(open, 130, 1, TimeUnit.SECONDS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
public RimuHostingAuthentication provideRimuHostingAuthentication(
|
public RimuHostingAuthentication provideRimuHostingAuthentication(
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.rimuhosting.miro.domain.internal;
|
package org.jclouds.rimuhosting.miro.domain.internal;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* States an instance can be in.
|
* States an instance can be in.
|
||||||
*
|
*
|
||||||
|
|
|
@ -33,12 +33,13 @@ public class ServerRunning implements Predicate<Server> {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean apply(Server server) {
|
public boolean apply(Server server) {
|
||||||
logger.trace("looking for state on server %s", checkNotNull(server, "server"));
|
logger.trace("looking for state on server %s", checkNotNull(server,
|
||||||
|
"server"));
|
||||||
server = refresh(server);
|
server = refresh(server);
|
||||||
if (server == null)
|
if (server == null)
|
||||||
return false;
|
return false;
|
||||||
logger.trace("%s: looking for server state %s: currently: %s", server.getId(),
|
logger.trace("%s: looking for server state %s: currently: %s", server
|
||||||
RunningState.RUNNING, server.getState());
|
.getId(), RunningState.RUNNING, server.getState());
|
||||||
return server.getState() == RunningState.RUNNING;
|
return server.getState() == RunningState.RUNNING;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,15 +19,22 @@
|
||||||
package org.jclouds.rimuhosting.miro;
|
package org.jclouds.rimuhosting.miro;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
|
import static org.testng.Assert.assertEquals;
|
||||||
import org.jclouds.rimuhosting.miro.domain.*;
|
import static org.testng.Assert.assertNotNull;
|
||||||
import org.jclouds.rimuhosting.miro.domain.internal.RunningState;
|
import static org.testng.Assert.assertTrue;
|
||||||
import static org.testng.Assert.*;
|
|
||||||
import org.testng.annotations.BeforeGroups;
|
|
||||||
import org.testng.annotations.Test;
|
|
||||||
|
|
||||||
import java.util.SortedSet;
|
import java.util.SortedSet;
|
||||||
|
|
||||||
|
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
|
||||||
|
import org.jclouds.rimuhosting.miro.domain.Image;
|
||||||
|
import org.jclouds.rimuhosting.miro.domain.NewServerResponse;
|
||||||
|
import org.jclouds.rimuhosting.miro.domain.PricingPlan;
|
||||||
|
import org.jclouds.rimuhosting.miro.domain.Server;
|
||||||
|
import org.jclouds.rimuhosting.miro.domain.ServerInfo;
|
||||||
|
import org.jclouds.rimuhosting.miro.domain.internal.RunningState;
|
||||||
|
import org.testng.annotations.BeforeGroups;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests behavior of {@code RimuHostingClient}
|
* Tests behavior of {@code RimuHostingClient}
|
||||||
*
|
*
|
||||||
|
@ -40,10 +47,12 @@ public class RimuHostingClientLiveTest {
|
||||||
|
|
||||||
@BeforeGroups(groups = { "live" })
|
@BeforeGroups(groups = { "live" })
|
||||||
public void setupClient() {
|
public void setupClient() {
|
||||||
String password = checkNotNull(System.getProperty("jclouds.test.key"), "jclouds.test.key");
|
String password = checkNotNull(System.getProperty("jclouds.test.key"),
|
||||||
|
"jclouds.test.key");
|
||||||
|
|
||||||
connection = (RimuHostingClient) RimuHostingContextFactory.createContext(password, new Log4JLoggingModule())
|
connection = (RimuHostingClient) RimuHostingContextFactory.createContext(
|
||||||
.getProviderSpecificContext().getApi();
|
password, new Log4JLoggingModule()).getProviderSpecificContext()
|
||||||
|
.getApi();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -73,8 +82,8 @@ public class RimuHostingClientLiveTest {
|
||||||
@Test
|
@Test
|
||||||
public void testLifeCycle() {
|
public void testLifeCycle() {
|
||||||
// Get the first image, we dont really care what it is in this test.
|
// Get the first image, we dont really care what it is in this test.
|
||||||
NewServerResponse serverResponse = connection.createServer("test.ivan.api.com", "lenny",
|
NewServerResponse serverResponse = connection.createServer(
|
||||||
"MIRO1B");
|
"test.ivan.api.com", "lenny", "MIRO1B");
|
||||||
Server server = serverResponse.getServer();
|
Server server = serverResponse.getServer();
|
||||||
// Now we have the server, lets restart it
|
// Now we have the server, lets restart it
|
||||||
assertNotNull(server.getId());
|
assertNotNull(server.getId());
|
||||||
|
|
|
@ -3,7 +3,6 @@ package org.jclouds.vcloud.bluelock.compute;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Named;
|
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import org.jclouds.compute.domain.NodeState;
|
import org.jclouds.compute.domain.NodeState;
|
||||||
|
@ -27,16 +26,18 @@ public class BlueLockVCloudComputeClient extends BaseVCloudComputeClient {
|
||||||
protected BlueLockVCloudComputeClient(
|
protected BlueLockVCloudComputeClient(
|
||||||
PopulateDefaultLoginCredentialsForImageStrategy credentialsProvider,
|
PopulateDefaultLoginCredentialsForImageStrategy credentialsProvider,
|
||||||
VCloudClient client, Predicate<String> successTester,
|
VCloudClient client, Predicate<String> successTester,
|
||||||
@Named("NOT_FOUND") Predicate<VApp> notFoundTester,
|
|
||||||
Map<VAppStatus, NodeState> vAppStatusToNodeState) {
|
Map<VAppStatus, NodeState> vAppStatusToNodeState) {
|
||||||
super(client, successTester, notFoundTester, vAppStatusToNodeState);
|
super(client, successTester, vAppStatusToNodeState);
|
||||||
this.credentialsProvider = credentialsProvider;
|
this.credentialsProvider = credentialsProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Map<String, String> parseAndValidateResponse(String templateId, VApp vAppResponse) {
|
protected Map<String, String> parseAndValidateResponse(String templateId,
|
||||||
Credentials credentials = credentialsProvider.execute(client.getVAppTemplate(templateId));
|
VApp vAppResponse) {
|
||||||
Map<String, String> toReturn = super.parseResponse(templateId, vAppResponse);
|
Credentials credentials = credentialsProvider.execute(client
|
||||||
|
.getVAppTemplate(templateId));
|
||||||
|
Map<String, String> toReturn = super.parseResponse(templateId,
|
||||||
|
vAppResponse);
|
||||||
toReturn.put("username", credentials.account);
|
toReturn.put("username", credentials.account);
|
||||||
toReturn.put("password", credentials.key);
|
toReturn.put("password", credentials.key);
|
||||||
return toReturn;
|
return toReturn;
|
||||||
|
|
|
@ -24,6 +24,7 @@ import static org.jclouds.vcloud.reference.VCloudConstants.PROPERTY_VCLOUD_DEFAU
|
||||||
import static org.jclouds.vcloud.reference.VCloudConstants.PROPERTY_VCLOUD_ENDPOINT;
|
import static org.jclouds.vcloud.reference.VCloudConstants.PROPERTY_VCLOUD_ENDPOINT;
|
||||||
import static org.jclouds.vcloud.reference.VCloudConstants.PROPERTY_VCLOUD_KEY;
|
import static org.jclouds.vcloud.reference.VCloudConstants.PROPERTY_VCLOUD_KEY;
|
||||||
import static org.jclouds.vcloud.reference.VCloudConstants.PROPERTY_VCLOUD_SESSIONINTERVAL;
|
import static org.jclouds.vcloud.reference.VCloudConstants.PROPERTY_VCLOUD_SESSIONINTERVAL;
|
||||||
|
import static org.jclouds.vcloud.reference.VCloudConstants.PROPERTY_VCLOUD_TIMEOUT_TASK_COMPLETED;
|
||||||
import static org.jclouds.vcloud.reference.VCloudConstants.PROPERTY_VCLOUD_USER;
|
import static org.jclouds.vcloud.reference.VCloudConstants.PROPERTY_VCLOUD_USER;
|
||||||
import static org.jclouds.vcloud.reference.VCloudConstants.PROPERTY_VCLOUD_VERSION;
|
import static org.jclouds.vcloud.reference.VCloudConstants.PROPERTY_VCLOUD_VERSION;
|
||||||
import static org.jclouds.vcloud.reference.VCloudConstants.PROPERTY_VCLOUD_XML_NAMESPACE;
|
import static org.jclouds.vcloud.reference.VCloudConstants.PROPERTY_VCLOUD_XML_NAMESPACE;
|
||||||
|
@ -49,9 +50,12 @@ public class VCloudPropertiesBuilder extends PropertiesBuilder {
|
||||||
properties.setProperty(PROPERTY_VCLOUD_XML_SCHEMA,
|
properties.setProperty(PROPERTY_VCLOUD_XML_SCHEMA,
|
||||||
"http://vcloud.safesecureweb.com/ns/vcloud.xsd");
|
"http://vcloud.safesecureweb.com/ns/vcloud.xsd");
|
||||||
properties.setProperty(PROPERTY_VCLOUD_DEFAULT_DHCP_ENABLED, "false");
|
properties.setProperty(PROPERTY_VCLOUD_DEFAULT_DHCP_ENABLED, "false");
|
||||||
properties.setProperty(PROPERTY_VCLOUD_DEFAULT_FENCEMODE, FenceMode.ALLOW_IN_OUT.toString());
|
properties.setProperty(PROPERTY_VCLOUD_DEFAULT_FENCEMODE,
|
||||||
|
FenceMode.ALLOW_IN_OUT.toString());
|
||||||
properties.setProperty("jclouds.dns_name_length_min", "1");
|
properties.setProperty("jclouds.dns_name_length_min", "1");
|
||||||
properties.setProperty("jclouds.dns_name_length_max", "80");
|
properties.setProperty("jclouds.dns_name_length_max", "80");
|
||||||
|
properties.setProperty(PROPERTY_VCLOUD_TIMEOUT_TASK_COMPLETED,
|
||||||
|
180l * 1000l + "");
|
||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,7 +66,8 @@ public class VCloudPropertiesBuilder extends PropertiesBuilder {
|
||||||
|
|
||||||
private void setNs() {
|
private void setNs() {
|
||||||
if (properties.getProperty(PROPERTY_VCLOUD_XML_NAMESPACE) == null)
|
if (properties.getProperty(PROPERTY_VCLOUD_XML_NAMESPACE) == null)
|
||||||
properties.setProperty(PROPERTY_VCLOUD_XML_NAMESPACE, "http://www.vmware.com/vcloud/v"
|
properties.setProperty(PROPERTY_VCLOUD_XML_NAMESPACE,
|
||||||
|
"http://www.vmware.com/vcloud/v"
|
||||||
+ properties.getProperty(PROPERTY_VCLOUD_VERSION));
|
+ properties.getProperty(PROPERTY_VCLOUD_VERSION));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,8 +90,8 @@ public class VCloudPropertiesBuilder extends PropertiesBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
public VCloudPropertiesBuilder withEndpoint(URI endpoint) {
|
public VCloudPropertiesBuilder withEndpoint(URI endpoint) {
|
||||||
properties.setProperty(PROPERTY_VCLOUD_ENDPOINT, checkNotNull(endpoint, "endpoint")
|
properties.setProperty(PROPERTY_VCLOUD_ENDPOINT, checkNotNull(endpoint,
|
||||||
.toString());
|
"endpoint").toString());
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,33 +54,35 @@ public class BaseVCloudComputeClient implements VCloudComputeClient {
|
||||||
|
|
||||||
protected final VCloudClient client;
|
protected final VCloudClient client;
|
||||||
protected final Predicate<String> taskTester;
|
protected final Predicate<String> taskTester;
|
||||||
protected final Predicate<VApp> notFoundTester;
|
|
||||||
protected final Map<VAppStatus, NodeState> vAppStatusToNodeState;
|
protected final Map<VAppStatus, NodeState> vAppStatusToNodeState;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public BaseVCloudComputeClient(VCloudClient client, Predicate<String> successTester,
|
public BaseVCloudComputeClient(VCloudClient client,
|
||||||
@Named("NOT_FOUND") Predicate<VApp> notFoundTester,
|
Predicate<String> successTester,
|
||||||
Map<VAppStatus, NodeState> vAppStatusToNodeState) {
|
Map<VAppStatus, NodeState> vAppStatusToNodeState) {
|
||||||
this.client = client;
|
this.client = client;
|
||||||
this.taskTester = successTester;
|
this.taskTester = successTester;
|
||||||
this.notFoundTester = notFoundTester;
|
|
||||||
this.vAppStatusToNodeState = vAppStatusToNodeState;
|
this.vAppStatusToNodeState = vAppStatusToNodeState;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, String> start(String vDCId, String name, String templateId,
|
public Map<String, String> start(String vDCId, String name,
|
||||||
InstantiateVAppTemplateOptions options, int... portsToOpen) {
|
String templateId, InstantiateVAppTemplateOptions options,
|
||||||
|
int... portsToOpen) {
|
||||||
checkNotNull(options, "options");
|
checkNotNull(options, "options");
|
||||||
|
|
||||||
logger.debug(">> instantiating vApp vDC(%s) name(%s) template(%s) options(%s) ", vDCId, name,
|
logger.debug(
|
||||||
templateId, options);
|
">> instantiating vApp vDC(%s) name(%s) template(%s) options(%s) ",
|
||||||
|
vDCId, name, templateId, options);
|
||||||
|
|
||||||
VApp vAppResponse = client.instantiateVAppTemplateInVDC(vDCId, name, templateId, options);
|
VApp vAppResponse = client.instantiateVAppTemplateInVDC(vDCId, name,
|
||||||
|
templateId, options);
|
||||||
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());
|
||||||
|
|
||||||
Task task = client.deployVApp(vAppResponse.getId());
|
Task task = client.deployVApp(vAppResponse.getId());
|
||||||
|
if (options.shouldBlockOnDeploy()) {
|
||||||
if (!taskTester.apply(task.getId())) {
|
if (!taskTester.apply(task.getId())) {
|
||||||
throw new TaskException("deploy", vAppResponse, task);
|
throw new TaskException("deploy", vAppResponse, task);
|
||||||
}
|
}
|
||||||
|
@ -92,12 +94,15 @@ public class BaseVCloudComputeClient implements VCloudComputeClient {
|
||||||
throw new TaskException("powerOn", vAppResponse, task);
|
throw new TaskException("powerOn", vAppResponse, task);
|
||||||
}
|
}
|
||||||
logger.debug("<< on vApp(%s)", vAppResponse.getId());
|
logger.debug("<< on vApp(%s)", vAppResponse.getId());
|
||||||
|
}
|
||||||
return parseAndValidateResponse(templateId, vAppResponse);
|
return parseAndValidateResponse(templateId, vAppResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Map<String, String> parseAndValidateResponse(String templateId, VApp vAppResponse) {
|
protected Map<String, String> parseAndValidateResponse(String templateId,
|
||||||
|
VApp vAppResponse) {
|
||||||
Map<String, String> response = parseResponse(templateId, vAppResponse);
|
Map<String, String> response = parseResponse(templateId, 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"),
|
||||||
"bad configuration: [username] should be in response");
|
"bad configuration: [username] should be in response");
|
||||||
checkState(response.containsKey("password"),
|
checkState(response.containsKey("password"),
|
||||||
|
@ -105,7 +110,8 @@ public class BaseVCloudComputeClient implements VCloudComputeClient {
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Map<String, String> parseResponse(String templateId, VApp vAppResponse) {
|
protected Map<String, String> parseResponse(String templateId,
|
||||||
|
VApp vAppResponse) {
|
||||||
Map<String, String> config = Maps.newLinkedHashMap();// Allows nulls
|
Map<String, String> config = Maps.newLinkedHashMap();// Allows nulls
|
||||||
config.put("id", vAppResponse.getId());
|
config.put("id", vAppResponse.getId());
|
||||||
config.put("username", null);
|
config.put("username", null);
|
||||||
|
@ -127,22 +133,19 @@ public class BaseVCloudComputeClient implements VCloudComputeClient {
|
||||||
VApp vApp = client.getVApp(id);
|
VApp vApp = client.getVApp(id);
|
||||||
vApp = powerOffVAppIfDeployed(vApp);
|
vApp = powerOffVAppIfDeployed(vApp);
|
||||||
vApp = undeployVAppIfDeployed(vApp);
|
vApp = undeployVAppIfDeployed(vApp);
|
||||||
boolean successful = deleteVApp(vApp);
|
deleteVApp(vApp);
|
||||||
logger.debug("<< deleted vApp(%s) completed(%s)", vApp.getId(), successful);
|
logger.debug("<< deleted vApp(%s)", vApp.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean deleteVApp(VApp vApp) {
|
private void deleteVApp(VApp vApp) {
|
||||||
logger.debug(">> deleting vApp(%s)", vApp.getId());
|
logger.debug(">> deleting vApp(%s)", vApp.getId());
|
||||||
client.deleteVApp(vApp.getId());
|
client.deleteVApp(vApp.getId());
|
||||||
boolean successful = notFoundTester.apply(vApp);
|
|
||||||
return successful;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private VApp undeployVAppIfDeployed(VApp vApp) {
|
private VApp undeployVAppIfDeployed(VApp vApp) {
|
||||||
if (vApp.getStatus().compareTo(VAppStatus.RESOLVED) > 0) {
|
if (vApp.getStatus().compareTo(VAppStatus.RESOLVED) > 0) {
|
||||||
logger
|
logger.debug(">> undeploying vApp(%s), current status: %s", vApp
|
||||||
.debug(">> undeploying vApp(%s), current status: %s", vApp.getId(), vApp
|
.getId(), vApp.getStatus());
|
||||||
.getStatus());
|
|
||||||
Task task = client.undeployVApp(vApp.getId());
|
Task task = client.undeployVApp(vApp.getId());
|
||||||
if (!taskTester.apply(task.getId())) {
|
if (!taskTester.apply(task.getId())) {
|
||||||
throw new TaskException("undeploy", vApp, task);
|
throw new TaskException("undeploy", vApp, task);
|
||||||
|
@ -155,8 +158,8 @@ public class BaseVCloudComputeClient implements VCloudComputeClient {
|
||||||
|
|
||||||
private VApp powerOffVAppIfDeployed(VApp vApp) {
|
private VApp powerOffVAppIfDeployed(VApp vApp) {
|
||||||
if (vApp.getStatus().compareTo(VAppStatus.OFF) > 0) {
|
if (vApp.getStatus().compareTo(VAppStatus.OFF) > 0) {
|
||||||
logger.debug(">> powering off vApp(%s), current status: %s", vApp.getId(), vApp
|
logger.debug(">> powering off vApp(%s), current status: %s", vApp
|
||||||
.getStatus());
|
.getId(), vApp.getStatus());
|
||||||
Task task = client.powerOffVApp(vApp.getId());
|
Task task = client.powerOffVApp(vApp.getId());
|
||||||
if (!taskTester.apply(task.getId())) {
|
if (!taskTester.apply(task.getId())) {
|
||||||
throw new TaskException("powerOff", vApp, task);
|
throw new TaskException("powerOff", vApp, task);
|
||||||
|
@ -174,8 +177,10 @@ public class BaseVCloudComputeClient implements VCloudComputeClient {
|
||||||
private static final long serialVersionUID = 251801929573211256L;
|
private static final long serialVersionUID = 251801929573211256L;
|
||||||
|
|
||||||
public TaskException(String type, VApp vApp, Task task) {
|
public TaskException(String type, VApp vApp, Task task) {
|
||||||
super(String.format("failed to %s vApp %s status %s;task %s status %s", type,
|
super(String.format(
|
||||||
vApp.getId(), vApp.getStatus(), task.getLocation(), task.getStatus()), vApp);
|
"failed to %s vApp %s status %s;task %s status %s", type, vApp
|
||||||
|
.getId(), vApp.getStatus(), task.getLocation(), task
|
||||||
|
.getStatus()), vApp);
|
||||||
this.task = task;
|
this.task = task;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,21 +22,19 @@ import static org.jclouds.compute.domain.OsFamily.UBUNTU;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import org.jclouds.compute.ComputeServiceContext;
|
import org.jclouds.compute.ComputeServiceContext;
|
||||||
import org.jclouds.compute.LoadBalancerService;
|
import org.jclouds.compute.LoadBalancerService;
|
||||||
|
import org.jclouds.compute.config.ComputeServiceTimeoutsModule;
|
||||||
import org.jclouds.compute.domain.ComputeMetadata;
|
import org.jclouds.compute.domain.ComputeMetadata;
|
||||||
import org.jclouds.compute.domain.Image;
|
import org.jclouds.compute.domain.Image;
|
||||||
import org.jclouds.compute.domain.NodeState;
|
import org.jclouds.compute.domain.NodeState;
|
||||||
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.internal.ComputeServiceContextImpl;
|
import org.jclouds.compute.internal.ComputeServiceContextImpl;
|
||||||
import org.jclouds.compute.predicates.ScriptStatusReturnsZero;
|
|
||||||
import org.jclouds.compute.predicates.ScriptStatusReturnsZero.CommandUsingClient;
|
|
||||||
import org.jclouds.compute.strategy.AddNodeWithTagStrategy;
|
import org.jclouds.compute.strategy.AddNodeWithTagStrategy;
|
||||||
import org.jclouds.compute.strategy.DestroyNodeStrategy;
|
import org.jclouds.compute.strategy.DestroyNodeStrategy;
|
||||||
import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
|
import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
|
||||||
|
@ -44,7 +42,6 @@ import org.jclouds.compute.strategy.ListNodesStrategy;
|
||||||
import org.jclouds.compute.strategy.RebootNodeStrategy;
|
import org.jclouds.compute.strategy.RebootNodeStrategy;
|
||||||
import org.jclouds.compute.strategy.RunNodesAndAddToSetStrategy;
|
import org.jclouds.compute.strategy.RunNodesAndAddToSetStrategy;
|
||||||
import org.jclouds.domain.Location;
|
import org.jclouds.domain.Location;
|
||||||
import org.jclouds.predicates.RetryablePredicate;
|
|
||||||
import org.jclouds.vcloud.VCloudAsyncClient;
|
import org.jclouds.vcloud.VCloudAsyncClient;
|
||||||
import org.jclouds.vcloud.VCloudClient;
|
import org.jclouds.vcloud.VCloudClient;
|
||||||
import org.jclouds.vcloud.compute.BaseVCloudComputeClient;
|
import org.jclouds.vcloud.compute.BaseVCloudComputeClient;
|
||||||
|
@ -63,7 +60,6 @@ import org.jclouds.vcloud.endpoints.VCloud;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
import com.google.common.base.Predicates;
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
import com.google.inject.Provides;
|
import com.google.inject.Provides;
|
||||||
|
@ -103,6 +99,7 @@ public class VCloudComputeServiceContextModule extends VCloudContextModule {
|
||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
super.configure();
|
super.configure();
|
||||||
|
install(new ComputeServiceTimeoutsModule());
|
||||||
bind(String.class).annotatedWith(VCloud.class).toInstance(providerName);
|
bind(String.class).annotatedWith(VCloud.class).toInstance(providerName);
|
||||||
bind(AddNodeWithTagStrategy.class).to(VCloudAddNodeWithTagStrategy.class);
|
bind(AddNodeWithTagStrategy.class).to(VCloudAddNodeWithTagStrategy.class);
|
||||||
bind(new TypeLiteral<ComputeServiceContext>() {
|
bind(new TypeLiteral<ComputeServiceContext>() {
|
||||||
|
@ -127,14 +124,6 @@ public class VCloudComputeServiceContextModule extends VCloudContextModule {
|
||||||
return "%s-%s%s";
|
return "%s-%s%s";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
@Named("NOT_RUNNING")
|
|
||||||
protected Predicate<CommandUsingClient> runScriptRunning(ScriptStatusReturnsZero stateRunning) {
|
|
||||||
return new RetryablePredicate<CommandUsingClient>(Predicates.not(stateRunning), 600, 3,
|
|
||||||
TimeUnit.SECONDS);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void bindLoadBalancer() {
|
protected void bindLoadBalancer() {
|
||||||
bind(LoadBalancerService.class).toProvider(Providers.<LoadBalancerService> of(null));
|
bind(LoadBalancerService.class).toProvider(Providers.<LoadBalancerService> of(null));
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,22 +46,26 @@ public class EncodeTemplateIdIntoNameRunNodesAndAddToSetStrategy extends
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
protected EncodeTemplateIdIntoNameRunNodesAndAddToSetStrategy(
|
protected EncodeTemplateIdIntoNameRunNodesAndAddToSetStrategy(
|
||||||
AddNodeWithTagStrategy addNodeWithTagStrategy, ListNodesStrategy listNodesStrategy,
|
AddNodeWithTagStrategy addNodeWithTagStrategy,
|
||||||
@Named("NAMING_CONVENTION") String nodeNamingConvention, ComputeUtils utils,
|
ListNodesStrategy listNodesStrategy,
|
||||||
|
@Named("NAMING_CONVENTION") String nodeNamingConvention,
|
||||||
|
ComputeUtils utils,
|
||||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) {
|
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) {
|
||||||
super(addNodeWithTagStrategy, listNodesStrategy, nodeNamingConvention, utils, executor);
|
super(addNodeWithTagStrategy, listNodesStrategy, nodeNamingConvention,
|
||||||
|
utils, executor);
|
||||||
this.random = new SecureRandom();
|
this.random = new SecureRandom();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a name corresponding to the tag-hex*5 where the first 3 hex correspond to the template id
|
* Get a name corresponding to the tag-hex*5 where the first 3 hex correspond
|
||||||
* and the last a random number
|
* to the template id and the last a random number
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected String getNextName(final String tag, final Template template) {
|
protected String getNextName(final String tag, final Template template) {
|
||||||
return String.format(nodeNamingConvention, tag, Strings.padStart(Integer.toHexString(Integer
|
return String.format(nodeNamingConvention, tag, Strings.padStart(
|
||||||
.parseInt(template.getImage().getProviderId())), 3, '0'), Strings.padStart(Integer
|
Integer.toHexString(Integer.parseInt(template.getImage()
|
||||||
|
.getProviderId())), 3, '0'), Strings.padStart(Integer
|
||||||
.toHexString(random.nextInt(255)), 2, '0'));
|
.toHexString(random.nextInt(255)), 2, '0'));
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -49,7 +49,8 @@ public class VCloudAddNodeWithTagStrategy implements AddNodeWithTagStrategy {
|
||||||
protected final Map<VAppStatus, NodeState> vAppStatusToNodeState;
|
protected final Map<VAppStatus, NodeState> vAppStatusToNodeState;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
protected VCloudAddNodeWithTagStrategy(VCloudClient client, VCloudComputeClient computeClient,
|
protected VCloudAddNodeWithTagStrategy(VCloudClient client,
|
||||||
|
VCloudComputeClient computeClient,
|
||||||
Map<VAppStatus, NodeState> vAppStatusToNodeState) {
|
Map<VAppStatus, NodeState> vAppStatusToNodeState) {
|
||||||
this.client = client;
|
this.client = client;
|
||||||
this.computeClient = computeClient;
|
this.computeClient = computeClient;
|
||||||
|
@ -58,24 +59,28 @@ public class VCloudAddNodeWithTagStrategy implements AddNodeWithTagStrategy {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NodeMetadata execute(String tag, String name, Template template) {
|
public NodeMetadata execute(String tag, String name, Template template) {
|
||||||
|
|
||||||
InstantiateVAppTemplateOptions options = processorCount(
|
InstantiateVAppTemplateOptions options = processorCount(
|
||||||
Double.valueOf(template.getSize().getCores()).intValue()).memory(
|
Double.valueOf(template.getSize().getCores()).intValue()).memory(
|
||||||
template.getSize().getRam()).disk(template.getSize().getDisk() * 1024 * 1024l);
|
template.getSize().getRam()).disk(
|
||||||
Map<String, String> metaMap = computeClient.start(template.getLocation().getId(), name,
|
template.getSize().getDisk() * 1024 * 1024l);
|
||||||
template.getImage().getProviderId(), options, template.getOptions()
|
if (!template.getOptions().shouldBlockUntilRunning())
|
||||||
.getInboundPorts());
|
options.blockOnDeploy(false);
|
||||||
|
Map<String, String> metaMap = computeClient.start(template.getLocation()
|
||||||
|
.getId(), name, template.getImage().getProviderId(), options,
|
||||||
|
template.getOptions().getInboundPorts());
|
||||||
VApp vApp = client.getVApp(metaMap.get("id"));
|
VApp vApp = client.getVApp(metaMap.get("id"));
|
||||||
return newCreateNodeResponse(tag, template, metaMap, vApp);
|
return newCreateNodeResponse(tag, template, metaMap, vApp);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected NodeMetadata newCreateNodeResponse(String tag, Template template,
|
protected NodeMetadata newCreateNodeResponse(String tag, Template template,
|
||||||
Map<String, String> metaMap, VApp vApp) {
|
Map<String, String> metaMap, VApp vApp) {
|
||||||
return new NodeMetadataImpl(vApp.getId(), vApp.getName(), vApp.getId(), template
|
return new NodeMetadataImpl(vApp.getId(), vApp.getName(), vApp.getId(),
|
||||||
.getLocation(), vApp.getLocation(), ImmutableMap.<String, String> of(), tag,
|
template.getLocation(), vApp.getLocation(), ImmutableMap
|
||||||
template.getImage(), vAppStatusToNodeState.get(vApp.getStatus()), computeClient
|
.<String, String> of(), tag, template.getImage(),
|
||||||
.getPublicAddresses(vApp.getId()), computeClient.getPrivateAddresses(vApp
|
vAppStatusToNodeState.get(vApp.getStatus()), computeClient
|
||||||
.getId()), ImmutableMap.<String, String> of(), new Credentials(metaMap
|
.getPublicAddresses(vApp.getId()), computeClient
|
||||||
|
.getPrivateAddresses(vApp.getId()), ImmutableMap
|
||||||
|
.<String, String> of(), new Credentials(metaMap
|
||||||
.get("username"), metaMap.get("password")));
|
.get("username"), metaMap.get("password")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,9 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import org.jclouds.compute.domain.NodeMetadata;
|
||||||
import org.jclouds.compute.strategy.DestroyNodeStrategy;
|
import org.jclouds.compute.strategy.DestroyNodeStrategy;
|
||||||
|
import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
|
||||||
import org.jclouds.vcloud.compute.VCloudComputeClient;
|
import org.jclouds.vcloud.compute.VCloudComputeClient;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -32,16 +34,20 @@ import org.jclouds.vcloud.compute.VCloudComputeClient;
|
||||||
@Singleton
|
@Singleton
|
||||||
public class VCloudDestroyNodeStrategy implements DestroyNodeStrategy {
|
public class VCloudDestroyNodeStrategy implements DestroyNodeStrategy {
|
||||||
protected final VCloudComputeClient computeClient;
|
protected final VCloudComputeClient computeClient;
|
||||||
|
protected final GetNodeMetadataStrategy getNode;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
protected VCloudDestroyNodeStrategy(VCloudComputeClient computeClient) {
|
protected VCloudDestroyNodeStrategy(VCloudComputeClient computeClient,
|
||||||
|
GetNodeMetadataStrategy getNode) {
|
||||||
this.computeClient = computeClient;
|
this.computeClient = computeClient;
|
||||||
|
this.getNode = getNode;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean execute(String id) {
|
public NodeMetadata execute(String id) {
|
||||||
computeClient.stop(checkNotNull(id, "node.id"));
|
computeClient.stop(checkNotNull(id, "node.id"));
|
||||||
return true;
|
return getNode.execute(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -23,6 +23,8 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import org.jclouds.compute.domain.NodeMetadata;
|
||||||
|
import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
|
||||||
import org.jclouds.compute.strategy.RebootNodeStrategy;
|
import org.jclouds.compute.strategy.RebootNodeStrategy;
|
||||||
import org.jclouds.vcloud.VCloudClient;
|
import org.jclouds.vcloud.VCloudClient;
|
||||||
import org.jclouds.vcloud.domain.Task;
|
import org.jclouds.vcloud.domain.Task;
|
||||||
|
@ -36,17 +38,21 @@ import com.google.common.base.Predicate;
|
||||||
public class VCloudRebootNodeStrategy implements RebootNodeStrategy {
|
public class VCloudRebootNodeStrategy implements RebootNodeStrategy {
|
||||||
private final VCloudClient client;
|
private final VCloudClient client;
|
||||||
protected final Predicate<String> taskTester;
|
protected final Predicate<String> taskTester;
|
||||||
|
protected final GetNodeMetadataStrategy getNode;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
protected VCloudRebootNodeStrategy(VCloudClient client, Predicate<String> taskTester) {
|
protected VCloudRebootNodeStrategy(VCloudClient client,
|
||||||
|
Predicate<String> taskTester, GetNodeMetadataStrategy getNode) {
|
||||||
this.client = client;
|
this.client = client;
|
||||||
this.taskTester = taskTester;
|
this.taskTester = taskTester;
|
||||||
|
this.getNode = getNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean execute(String id) {
|
public NodeMetadata execute(String id) {
|
||||||
Task task = client.resetVApp(checkNotNull(id, "node.id"));
|
Task task = client.resetVApp(checkNotNull(id, "node.id"));
|
||||||
return taskTester.apply(task.getId());
|
taskTester.apply(task.getId());
|
||||||
|
return getNode.execute(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -24,6 +24,7 @@ import static org.jclouds.vcloud.reference.VCloudConstants.PROPERTY_VCLOUD_DEFAU
|
||||||
import static org.jclouds.vcloud.reference.VCloudConstants.PROPERTY_VCLOUD_ENDPOINT;
|
import static org.jclouds.vcloud.reference.VCloudConstants.PROPERTY_VCLOUD_ENDPOINT;
|
||||||
import static org.jclouds.vcloud.reference.VCloudConstants.PROPERTY_VCLOUD_KEY;
|
import static org.jclouds.vcloud.reference.VCloudConstants.PROPERTY_VCLOUD_KEY;
|
||||||
import static org.jclouds.vcloud.reference.VCloudConstants.PROPERTY_VCLOUD_SESSIONINTERVAL;
|
import static org.jclouds.vcloud.reference.VCloudConstants.PROPERTY_VCLOUD_SESSIONINTERVAL;
|
||||||
|
import static org.jclouds.vcloud.reference.VCloudConstants.PROPERTY_VCLOUD_TIMEOUT_TASK_COMPLETED;
|
||||||
import static org.jclouds.vcloud.reference.VCloudConstants.PROPERTY_VCLOUD_USER;
|
import static org.jclouds.vcloud.reference.VCloudConstants.PROPERTY_VCLOUD_USER;
|
||||||
import static org.jclouds.vcloud.reference.VCloudConstants.PROPERTY_VCLOUD_VERSION;
|
import static org.jclouds.vcloud.reference.VCloudConstants.PROPERTY_VCLOUD_VERSION;
|
||||||
|
|
||||||
|
@ -49,9 +50,7 @@ import org.jclouds.http.annotation.Redirection;
|
||||||
import org.jclouds.http.annotation.ServerError;
|
import org.jclouds.http.annotation.ServerError;
|
||||||
import org.jclouds.http.filters.BasicAuthentication;
|
import org.jclouds.http.filters.BasicAuthentication;
|
||||||
import org.jclouds.logging.Logger;
|
import org.jclouds.logging.Logger;
|
||||||
import org.jclouds.net.IPSocket;
|
|
||||||
import org.jclouds.predicates.RetryablePredicate;
|
import org.jclouds.predicates.RetryablePredicate;
|
||||||
import org.jclouds.predicates.SocketOpen;
|
|
||||||
import org.jclouds.rest.AsyncClientFactory;
|
import org.jclouds.rest.AsyncClientFactory;
|
||||||
import org.jclouds.rest.AuthorizationException;
|
import org.jclouds.rest.AuthorizationException;
|
||||||
import org.jclouds.rest.ConfiguresRestClient;
|
import org.jclouds.rest.ConfiguresRestClient;
|
||||||
|
@ -61,7 +60,6 @@ import org.jclouds.vcloud.VCloudClient;
|
||||||
import org.jclouds.vcloud.VCloudToken;
|
import org.jclouds.vcloud.VCloudToken;
|
||||||
import org.jclouds.vcloud.domain.NamedResource;
|
import org.jclouds.vcloud.domain.NamedResource;
|
||||||
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;
|
||||||
|
@ -78,7 +76,6 @@ 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;
|
||||||
|
@ -87,7 +84,8 @@ import com.google.common.collect.Iterables;
|
||||||
import com.google.inject.Provides;
|
import com.google.inject.Provides;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configures the VCloud authentication service connection, including logging and http transport.
|
* Configures the VCloud authentication service connection, including logging
|
||||||
|
* and http transport.
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
|
@ -96,7 +94,8 @@ import com.google.inject.Provides;
|
||||||
public abstract class BaseVCloudRestClientModule<S extends VCloudClient, A extends VCloudAsyncClient>
|
public abstract class BaseVCloudRestClientModule<S extends VCloudClient, A extends VCloudAsyncClient>
|
||||||
extends RestClientModule<S, A> {
|
extends RestClientModule<S, A> {
|
||||||
|
|
||||||
public BaseVCloudRestClientModule(Class<S> syncClientType, Class<A> asyncClientType) {
|
public BaseVCloudRestClientModule(Class<S> syncClientType,
|
||||||
|
Class<A> asyncClientType) {
|
||||||
super(syncClientType, asyncClientType);
|
super(syncClientType, asyncClientType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,35 +110,26 @@ public abstract class BaseVCloudRestClientModule<S extends VCloudClient, A exten
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
protected Predicate<IPSocket> socketTester(SocketOpen open) {
|
protected Predicate<String> successTester(TaskSuccess success,
|
||||||
return new RetryablePredicate<IPSocket>(open, 130, 10, TimeUnit.SECONDS);
|
@Named(PROPERTY_VCLOUD_TIMEOUT_TASK_COMPLETED) long completed) {
|
||||||
}
|
return new RetryablePredicate<String>(success, completed);
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
protected Predicate<String> successTester(TaskSuccess success) {
|
|
||||||
return new RetryablePredicate<String>(success, 60 * 30, 10, TimeUnit.SECONDS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
@Named("NOT_FOUND")
|
|
||||||
protected Predicate<VApp> successTester(VAppNotFound notFound) {
|
|
||||||
return new RetryablePredicate<VApp>(notFound, 5, 1, TimeUnit.SECONDS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@VCloudToken
|
@VCloudToken
|
||||||
@Provides
|
@Provides
|
||||||
String provideVCloudToken(Supplier<VCloudSession> cache) {
|
String provideVCloudToken(Supplier<VCloudSession> cache) {
|
||||||
return checkNotNull(cache.get().getVCloudToken(), "No token present in session");
|
return checkNotNull(cache.get().getVCloudToken(),
|
||||||
|
"No token present in session");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Org
|
@Org
|
||||||
@Singleton
|
@Singleton
|
||||||
protected URI provideOrg(Supplier<VCloudSession> cache, @Named(PROPERTY_VCLOUD_USER) String user) {
|
protected URI provideOrg(Supplier<VCloudSession> cache,
|
||||||
|
@Named(PROPERTY_VCLOUD_USER) String user) {
|
||||||
VCloudSession discovery = cache.get();
|
VCloudSession discovery = cache.get();
|
||||||
checkState(discovery.getOrgs().size() > 0, "No orgs present for user: " + user);
|
checkState(discovery.getOrgs().size() > 0, "No orgs present for user: "
|
||||||
|
+ user);
|
||||||
return Iterables.getLast(discovery.getOrgs().values()).getLocation();
|
return Iterables.getLast(discovery.getOrgs().values()).getLocation();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,15 +148,21 @@ public abstract class BaseVCloudRestClientModule<S extends VCloudClient, A exten
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
Supplier<VCloudSession> provideVCloudTokenCache(
|
Supplier<VCloudSession> provideVCloudTokenCache(
|
||||||
@Named(PROPERTY_VCLOUD_SESSIONINTERVAL) long seconds, final VCloudLoginAsyncClient login) {
|
@Named(PROPERTY_VCLOUD_SESSIONINTERVAL) long seconds,
|
||||||
|
final VCloudLoginAsyncClient login) {
|
||||||
return new ExpirableSupplier<VCloudSession>(
|
return new ExpirableSupplier<VCloudSession>(
|
||||||
new RetryOnTimeOutExceptionSupplier<VCloudSession>(new Supplier<VCloudSession>() {
|
new RetryOnTimeOutExceptionSupplier<VCloudSession>(
|
||||||
|
new Supplier<VCloudSession>() {
|
||||||
public VCloudSession get() {
|
public VCloudSession get() {
|
||||||
// http://code.google.com/p/google-guice/issues/detail?id=483
|
// http://code.google.com/p/google-guice/issues/detail?id=483
|
||||||
// guice doesn't remember when singleton providers throw exceptions.
|
// guice doesn't remember when singleton providers throw
|
||||||
// in this case, if describeRegions fails, it is called again for
|
// exceptions.
|
||||||
// each provider method that depends on it. To short-circuit this,
|
// in this case, if describeRegions fails, it is called
|
||||||
// we remember the last exception trusting that guice is single-threaded
|
// again for
|
||||||
|
// each provider method that depends on it. To
|
||||||
|
// short-circuit this,
|
||||||
|
// we remember the last exception trusting that guice is
|
||||||
|
// single-threaded
|
||||||
if (authException != null)
|
if (authException != null)
|
||||||
throw authException;
|
throw authException;
|
||||||
try {
|
try {
|
||||||
|
@ -194,33 +190,38 @@ public abstract class BaseVCloudRestClientModule<S extends VCloudClient, A exten
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
@org.jclouds.vcloud.endpoints.VCloudLogin
|
@org.jclouds.vcloud.endpoints.VCloudLogin
|
||||||
protected URI provideAuthenticationURI(VCloudVersionsAsyncClient versionService,
|
protected URI provideAuthenticationURI(
|
||||||
@Named(PROPERTY_VCLOUD_VERSION) String version) throws InterruptedException,
|
VCloudVersionsAsyncClient versionService,
|
||||||
ExecutionException, TimeoutException {
|
@Named(PROPERTY_VCLOUD_VERSION) String version)
|
||||||
SortedMap<String, URI> versions = versionService.getSupportedVersions().get(180,
|
throws InterruptedException, ExecutionException, TimeoutException {
|
||||||
TimeUnit.SECONDS);
|
SortedMap<String, URI> versions = versionService.getSupportedVersions()
|
||||||
|
.get(180, TimeUnit.SECONDS);
|
||||||
checkState(versions.size() > 0, "No versions present");
|
checkState(versions.size() > 0, "No versions present");
|
||||||
checkState(versions.containsKey(version), "version " + version + " not present in: "
|
checkState(versions.containsKey(version), "version " + version
|
||||||
+ versions);
|
+ " not present in: " + versions);
|
||||||
return versions.get(version);
|
return versions.get(version);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
protected VCloudLoginAsyncClient provideVCloudLogin(AsyncClientFactory factory) {
|
protected VCloudLoginAsyncClient provideVCloudLogin(
|
||||||
|
AsyncClientFactory factory) {
|
||||||
return factory.create(VCloudLoginAsyncClient.class);
|
return factory.create(VCloudLoginAsyncClient.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
protected VCloudVersionsAsyncClient provideVCloudVersions(AsyncClientFactory factory) {
|
protected VCloudVersionsAsyncClient provideVCloudVersions(
|
||||||
|
AsyncClientFactory factory) {
|
||||||
return factory.create(VCloudVersionsAsyncClient.class);
|
return factory.create(VCloudVersionsAsyncClient.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
public BasicAuthentication provideBasicAuthentication(@Named(PROPERTY_VCLOUD_USER) String user,
|
public BasicAuthentication provideBasicAuthentication(
|
||||||
@Named(PROPERTY_VCLOUD_KEY) String key, EncryptionService encryptionService)
|
@Named(PROPERTY_VCLOUD_USER) String user,
|
||||||
|
@Named(PROPERTY_VCLOUD_KEY) String key,
|
||||||
|
EncryptionService encryptionService)
|
||||||
throws UnsupportedEncodingException {
|
throws UnsupportedEncodingException {
|
||||||
return new BasicAuthentication(user, key, encryptionService);
|
return new BasicAuthentication(user, key, encryptionService);
|
||||||
}
|
}
|
||||||
|
@ -248,8 +249,8 @@ public abstract class BaseVCloudRestClientModule<S extends VCloudClient, A exten
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
protected Organization provideOrganization(VCloudClient discovery) throws ExecutionException,
|
protected Organization provideOrganization(VCloudClient discovery)
|
||||||
TimeoutException, InterruptedException {
|
throws ExecutionException, TimeoutException, InterruptedException {
|
||||||
if (authException != null)
|
if (authException != null)
|
||||||
throw authException;
|
throw authException;
|
||||||
try {
|
try {
|
||||||
|
@ -264,29 +265,33 @@ public abstract class BaseVCloudRestClientModule<S extends VCloudClient, A exten
|
||||||
@VDC
|
@VDC
|
||||||
@Singleton
|
@Singleton
|
||||||
protected URI provideDefaultVDC(Organization org) {
|
protected URI provideDefaultVDC(Organization org) {
|
||||||
checkState(org.getVDCs().size() > 0, "No vdcs present in org: " + org.getName());
|
checkState(org.getVDCs().size() > 0, "No vdcs present in org: "
|
||||||
|
+ org.getName());
|
||||||
return Iterables.get(org.getVDCs().values(), 0).getLocation();
|
return Iterables.get(org.getVDCs().values(), 0).getLocation();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Catalog
|
@Catalog
|
||||||
@Singleton
|
@Singleton
|
||||||
protected URI provideCatalog(Organization org, @Named(PROPERTY_VCLOUD_USER) String user) {
|
protected URI provideCatalog(Organization org,
|
||||||
checkState(org.getCatalogs().size() > 0, "No catalogs present in org: " + org.getName());
|
@Named(PROPERTY_VCLOUD_USER) String user) {
|
||||||
|
checkState(org.getCatalogs().size() > 0, "No catalogs present in org: "
|
||||||
|
+ org.getName());
|
||||||
return Iterables.get(org.getCatalogs().values(), 0).getLocation();
|
return Iterables.get(org.getCatalogs().values(), 0).getLocation();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Network
|
@Network
|
||||||
@Singleton
|
@Singleton
|
||||||
protected URI provideDefaultNetwork(VCloudClient client) throws InterruptedException,
|
protected URI provideDefaultNetwork(VCloudClient client)
|
||||||
ExecutionException, TimeoutException {
|
throws InterruptedException, ExecutionException, TimeoutException {
|
||||||
if (authException != null)
|
if (authException != null)
|
||||||
throw authException;
|
throw authException;
|
||||||
try {
|
try {
|
||||||
org.jclouds.vcloud.domain.VDC vDC = client.getDefaultVDC();
|
org.jclouds.vcloud.domain.VDC vDC = client.getDefaultVDC();
|
||||||
Map<String, NamedResource> networks = vDC.getAvailableNetworks();
|
Map<String, NamedResource> networks = vDC.getAvailableNetworks();
|
||||||
checkState(networks.size() > 0, "No networks present in vDC: " + vDC.getName());
|
checkState(networks.size() > 0, "No networks present in vDC: "
|
||||||
|
+ vDC.getName());
|
||||||
return Iterables.get(networks.values(), 0).getLocation();
|
return Iterables.get(networks.values(), 0).getLocation();
|
||||||
} catch (AuthorizationException e) {
|
} catch (AuthorizationException e) {
|
||||||
BaseVCloudRestClientModule.this.authException = e;
|
BaseVCloudRestClientModule.this.authException = e;
|
||||||
|
@ -315,7 +320,8 @@ public abstract class BaseVCloudRestClientModule<S extends VCloudClient, A exten
|
||||||
@TasksList
|
@TasksList
|
||||||
@Singleton
|
@Singleton
|
||||||
protected URI provideDefaultTasksList(Organization org) {
|
protected URI provideDefaultTasksList(Organization org) {
|
||||||
checkState(org.getTasksLists().size() > 0, "No tasks lists present in org: " + org.getName());
|
checkState(org.getTasksLists().size() > 0,
|
||||||
|
"No tasks lists present in org: " + org.getName());
|
||||||
return Iterables.get(org.getTasksLists().values(), 0).getLocation();
|
return Iterables.get(org.getTasksLists().values(), 0).getLocation();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,14 +42,26 @@ public class InstantiateVAppTemplateOptions {
|
||||||
private String fenceMode;
|
private String fenceMode;
|
||||||
private String dhcpEnabled;
|
private String dhcpEnabled;
|
||||||
private String networkName;
|
private String networkName;
|
||||||
|
private boolean blockOnDeploy = true;
|
||||||
private Map<String, String> properties = Maps.newTreeMap();
|
private Map<String, String> properties = Maps.newTreeMap();
|
||||||
|
|
||||||
public InstantiateVAppTemplateOptions productProperty(String key, String value) {
|
public boolean shouldBlockOnDeploy() {
|
||||||
|
return blockOnDeploy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public InstantiateVAppTemplateOptions blockOnDeploy(boolean blockOnDeploy) {
|
||||||
|
this.blockOnDeploy = blockOnDeploy;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public InstantiateVAppTemplateOptions productProperty(String key,
|
||||||
|
String value) {
|
||||||
properties.put(checkNotNull(key, "key"), checkNotNull(value, "value"));
|
properties.put(checkNotNull(key, "key"), checkNotNull(value, "value"));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public InstantiateVAppTemplateOptions productProperties(Map<String, String> properties) {
|
public InstantiateVAppTemplateOptions productProperties(
|
||||||
|
Map<String, String> properties) {
|
||||||
this.properties.putAll(checkNotNull(properties, "properties"));
|
this.properties.putAll(checkNotNull(properties, "properties"));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -88,7 +100,8 @@ public class InstantiateVAppTemplateOptions {
|
||||||
}
|
}
|
||||||
|
|
||||||
public InstantiateVAppTemplateOptions inNetwork(URI networkLocation) {
|
public InstantiateVAppTemplateOptions inNetwork(URI networkLocation) {
|
||||||
this.network = checkNotNull(networkLocation, "networkLocation").toASCIIString();
|
this.network = checkNotNull(networkLocation, "networkLocation")
|
||||||
|
.toASCIIString();
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,6 +139,15 @@ public class InstantiateVAppTemplateOptions {
|
||||||
|
|
||||||
public static class Builder {
|
public static class Builder {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see InstantiateVAppTemplateOptions#blockOnDeploy
|
||||||
|
*/
|
||||||
|
public static InstantiateVAppTemplateOptions blockOnDeploy(
|
||||||
|
boolean blockOnDeploy) {
|
||||||
|
InstantiateVAppTemplateOptions options = new InstantiateVAppTemplateOptions();
|
||||||
|
return options.blockOnDeploy(blockOnDeploy);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see InstantiateVAppTemplateOptions#processorCount(int)
|
* @see InstantiateVAppTemplateOptions#processorCount(int)
|
||||||
*/
|
*/
|
||||||
|
@ -169,7 +191,8 @@ public class InstantiateVAppTemplateOptions {
|
||||||
/**
|
/**
|
||||||
* @see InstantiateVAppTemplateOptions#dhcpEnabled(boolean)
|
* @see InstantiateVAppTemplateOptions#dhcpEnabled(boolean)
|
||||||
*/
|
*/
|
||||||
public static InstantiateVAppTemplateOptions dhcpEnabled(boolean dhcpEnabled) {
|
public static InstantiateVAppTemplateOptions dhcpEnabled(
|
||||||
|
boolean dhcpEnabled) {
|
||||||
InstantiateVAppTemplateOptions options = new InstantiateVAppTemplateOptions();
|
InstantiateVAppTemplateOptions options = new InstantiateVAppTemplateOptions();
|
||||||
return options.dhcpEnabled(dhcpEnabled);
|
return options.dhcpEnabled(dhcpEnabled);
|
||||||
}
|
}
|
||||||
|
@ -177,7 +200,8 @@ public class InstantiateVAppTemplateOptions {
|
||||||
/**
|
/**
|
||||||
* @see InstantiateVAppTemplateOptions#networkName(String)
|
* @see InstantiateVAppTemplateOptions#networkName(String)
|
||||||
*/
|
*/
|
||||||
public static InstantiateVAppTemplateOptions networkName(String networkName) {
|
public static InstantiateVAppTemplateOptions networkName(
|
||||||
|
String networkName) {
|
||||||
InstantiateVAppTemplateOptions options = new InstantiateVAppTemplateOptions();
|
InstantiateVAppTemplateOptions options = new InstantiateVAppTemplateOptions();
|
||||||
return options.networkName(networkName);
|
return options.networkName(networkName);
|
||||||
}
|
}
|
||||||
|
@ -185,7 +209,8 @@ public class InstantiateVAppTemplateOptions {
|
||||||
/**
|
/**
|
||||||
* @see InstantiateVAppTemplateOptions#productProperty(String,String)
|
* @see InstantiateVAppTemplateOptions#productProperty(String,String)
|
||||||
*/
|
*/
|
||||||
public static InstantiateVAppTemplateOptions productProperty(String key, String value) {
|
public static InstantiateVAppTemplateOptions productProperty(String key,
|
||||||
|
String value) {
|
||||||
InstantiateVAppTemplateOptions options = new InstantiateVAppTemplateOptions();
|
InstantiateVAppTemplateOptions options = new InstantiateVAppTemplateOptions();
|
||||||
return options.productProperty(key, value);
|
return options.productProperty(key, value);
|
||||||
}
|
}
|
||||||
|
@ -193,7 +218,8 @@ public class InstantiateVAppTemplateOptions {
|
||||||
/**
|
/**
|
||||||
* @see InstantiateVAppTemplateOptions#setProperties(Map<String, String>)
|
* @see InstantiateVAppTemplateOptions#setProperties(Map<String, String>)
|
||||||
*/
|
*/
|
||||||
public static InstantiateVAppTemplateOptions productProperties(Map<String, String> properties) {
|
public static InstantiateVAppTemplateOptions productProperties(
|
||||||
|
Map<String, String> properties) {
|
||||||
InstantiateVAppTemplateOptions options = new InstantiateVAppTemplateOptions();
|
InstantiateVAppTemplateOptions options = new InstantiateVAppTemplateOptions();
|
||||||
return options.productProperties(properties);
|
return options.productProperties(properties);
|
||||||
}
|
}
|
||||||
|
@ -201,10 +227,12 @@ public class InstantiateVAppTemplateOptions {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "InstantiateVAppTemplateOptions [cpuCount=" + cpuCount + ", memorySizeMegabytes="
|
return "InstantiateVAppTemplateOptions [cpuCount=" + cpuCount
|
||||||
+ memorySizeMegabytes + ", diskSizeKilobytes=" + diskSizeKilobytes + ", network="
|
+ ", memorySizeMegabytes=" + memorySizeMegabytes
|
||||||
+ network + ", networkName=" + networkName + ", fenceMode=" + fenceMode
|
+ ", diskSizeKilobytes=" + diskSizeKilobytes + ", network="
|
||||||
+ ", dhcpEnabled=" + dhcpEnabled + ", properties=" + properties + "]";
|
+ network + ", networkName=" + networkName + ", fenceMode="
|
||||||
|
+ fenceMode + ", dhcpEnabled=" + dhcpEnabled + ", properties="
|
||||||
|
+ properties + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -212,14 +240,21 @@ public class InstantiateVAppTemplateOptions {
|
||||||
final int prime = 31;
|
final int prime = 31;
|
||||||
int result = 1;
|
int result = 1;
|
||||||
result = prime * result + ((cpuCount == null) ? 0 : cpuCount.hashCode());
|
result = prime * result + ((cpuCount == null) ? 0 : cpuCount.hashCode());
|
||||||
result = prime * result + ((dhcpEnabled == null) ? 0 : dhcpEnabled.hashCode());
|
|
||||||
result = prime * result + ((diskSizeKilobytes == null) ? 0 : diskSizeKilobytes.hashCode());
|
|
||||||
result = prime * result + ((fenceMode == null) ? 0 : fenceMode.hashCode());
|
|
||||||
result = prime * result
|
result = prime * result
|
||||||
+ ((memorySizeMegabytes == null) ? 0 : memorySizeMegabytes.hashCode());
|
+ ((dhcpEnabled == null) ? 0 : dhcpEnabled.hashCode());
|
||||||
|
result = prime * result
|
||||||
|
+ ((diskSizeKilobytes == null) ? 0 : diskSizeKilobytes.hashCode());
|
||||||
|
result = prime * result
|
||||||
|
+ ((fenceMode == null) ? 0 : fenceMode.hashCode());
|
||||||
|
result = prime
|
||||||
|
* result
|
||||||
|
+ ((memorySizeMegabytes == null) ? 0 : memorySizeMegabytes
|
||||||
|
.hashCode());
|
||||||
result = prime * result + ((network == null) ? 0 : network.hashCode());
|
result = prime * result + ((network == null) ? 0 : network.hashCode());
|
||||||
result = prime * result + ((networkName == null) ? 0 : networkName.hashCode());
|
result = prime * result
|
||||||
result = prime * result + ((properties == null) ? 0 : properties.hashCode());
|
+ ((networkName == null) ? 0 : networkName.hashCode());
|
||||||
|
result = prime * result
|
||||||
|
+ ((properties == null) ? 0 : properties.hashCode());
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.vcloud.reference;
|
package org.jclouds.vcloud.reference;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configuration properties and constants used in VCloud connections.
|
* Configuration properties and constants used in VCloud connections.
|
||||||
*
|
*
|
||||||
|
@ -51,4 +52,6 @@ public interface VCloudConstants {
|
||||||
public static final String PROPERTY_VCLOUD_XML_NAMESPACE = "jclouds.vcloud.xml.ns";
|
public static final String PROPERTY_VCLOUD_XML_NAMESPACE = "jclouds.vcloud.xml.ns";
|
||||||
public static final String PROPERTY_VCLOUD_XML_SCHEMA = "jclouds.vcloud.xml.schema";
|
public static final String PROPERTY_VCLOUD_XML_SCHEMA = "jclouds.vcloud.xml.schema";
|
||||||
|
|
||||||
|
public static final String PROPERTY_VCLOUD_TIMEOUT_TASK_COMPLETED = "jclouds.vcloud.timeout.task-complete";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,8 @@ public class VCloudComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
||||||
public void testAssignability() throws Exception {
|
public void testAssignability() throws Exception {
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
RestContext<VCloudClient, VCloudAsyncClient> tmContext = new ComputeServiceContextFactory()
|
RestContext<VCloudClient, VCloudAsyncClient> tmContext = new ComputeServiceContextFactory()
|
||||||
.createContext(service, user, password).getProviderSpecificContext();
|
.createContext(service, user, password)
|
||||||
|
.getProviderSpecificContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -55,4 +56,5 @@ public class VCloudComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
||||||
System.out.println(allData.getExtra());
|
System.out.println(allData.getExtra());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -19,6 +19,7 @@
|
||||||
package org.jclouds.vcloud.hostingdotcom;
|
package org.jclouds.vcloud.hostingdotcom;
|
||||||
|
|
||||||
import static org.jclouds.vcloud.reference.VCloudConstants.PROPERTY_VCLOUD_ENDPOINT;
|
import static org.jclouds.vcloud.reference.VCloudConstants.PROPERTY_VCLOUD_ENDPOINT;
|
||||||
|
import static org.jclouds.vcloud.reference.VCloudConstants.PROPERTY_VCLOUD_TIMEOUT_TASK_COMPLETED;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
@ -30,11 +31,15 @@ import org.jclouds.vcloud.VCloudPropertiesBuilder;
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public class HostingDotComVCloudPropertiesBuilder extends VCloudPropertiesBuilder {
|
public class HostingDotComVCloudPropertiesBuilder extends
|
||||||
|
VCloudPropertiesBuilder {
|
||||||
@Override
|
@Override
|
||||||
protected Properties defaultProperties() {
|
protected Properties defaultProperties() {
|
||||||
Properties properties = super.defaultProperties();
|
Properties properties = super.defaultProperties();
|
||||||
properties.setProperty(PROPERTY_VCLOUD_ENDPOINT, "https://vcloud.safesecureweb.com/api");
|
properties.setProperty(PROPERTY_VCLOUD_ENDPOINT,
|
||||||
|
"https://vcloud.safesecureweb.com/api");
|
||||||
|
properties.setProperty(PROPERTY_VCLOUD_TIMEOUT_TASK_COMPLETED,
|
||||||
|
45 * 60 * 1000l + "");
|
||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,6 @@ package org.jclouds.vcloud.hostingdotcom.compute;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Named;
|
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import org.jclouds.compute.domain.NodeState;
|
import org.jclouds.compute.domain.NodeState;
|
||||||
|
@ -23,17 +22,18 @@ import com.google.common.collect.ImmutableMap;
|
||||||
public class HostingDotComVCloudComputeClient extends BaseVCloudComputeClient {
|
public class HostingDotComVCloudComputeClient extends BaseVCloudComputeClient {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
protected HostingDotComVCloudComputeClient(VCloudClient client, Predicate<String> successTester,
|
protected HostingDotComVCloudComputeClient(VCloudClient client,
|
||||||
@Named("NOT_FOUND") Predicate<VApp> notFoundTester,
|
Predicate<String> successTester,
|
||||||
Map<VAppStatus, NodeState> vAppStatusToNodeState) {
|
Map<VAppStatus, NodeState> vAppStatusToNodeState) {
|
||||||
super(client, successTester, notFoundTester, vAppStatusToNodeState);
|
super(client, successTester, vAppStatusToNodeState);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Map<String, String> parseResponse(String templateId, VApp vAppResponse) {
|
protected Map<String, String> parseResponse(String templateId,
|
||||||
|
VApp vAppResponse) {
|
||||||
HostingDotComVApp hVApp = HostingDotComVApp.class.cast(vAppResponse);
|
HostingDotComVApp hVApp = HostingDotComVApp.class.cast(vAppResponse);
|
||||||
return ImmutableMap.<String, String> of("id", vAppResponse.getId(), "username", hVApp
|
return ImmutableMap.<String, String> of("id", vAppResponse.getId(),
|
||||||
.getUsername(), "password", hVApp.getPassword());
|
"username", hVApp.getUsername(), "password", hVApp.getPassword());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -19,40 +19,40 @@
|
||||||
package org.jclouds.vcloud.hostingdotcom.config;
|
package org.jclouds.vcloud.hostingdotcom.config;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import org.jclouds.http.RequiresHttp;
|
import org.jclouds.http.RequiresHttp;
|
||||||
import org.jclouds.predicates.RetryablePredicate;
|
|
||||||
import org.jclouds.rest.ConfiguresRestClient;
|
import org.jclouds.rest.ConfiguresRestClient;
|
||||||
import org.jclouds.vcloud.VCloudAsyncClient;
|
import org.jclouds.vcloud.VCloudAsyncClient;
|
||||||
import org.jclouds.vcloud.VCloudClient;
|
import org.jclouds.vcloud.VCloudClient;
|
||||||
import org.jclouds.vcloud.config.BaseVCloudRestClientModule;
|
import org.jclouds.vcloud.config.BaseVCloudRestClientModule;
|
||||||
import org.jclouds.vcloud.hostingdotcom.HostingDotComVCloudAsyncClient;
|
import org.jclouds.vcloud.hostingdotcom.HostingDotComVCloudAsyncClient;
|
||||||
import org.jclouds.vcloud.hostingdotcom.HostingDotComVCloudClient;
|
import org.jclouds.vcloud.hostingdotcom.HostingDotComVCloudClient;
|
||||||
import org.jclouds.vcloud.predicates.TaskSuccess;
|
|
||||||
|
|
||||||
import com.google.common.base.Predicate;
|
|
||||||
import com.google.inject.Provides;
|
import com.google.inject.Provides;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configures the VCloud authentication service connection, including logging and http transport.
|
* Configures the VCloud authentication service connection, including logging
|
||||||
|
* and http transport.
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@RequiresHttp
|
@RequiresHttp
|
||||||
@ConfiguresRestClient
|
@ConfiguresRestClient
|
||||||
public class HostingDotComVCloudRestClientModule extends
|
public class HostingDotComVCloudRestClientModule
|
||||||
|
extends
|
||||||
BaseVCloudRestClientModule<HostingDotComVCloudClient, HostingDotComVCloudAsyncClient> {
|
BaseVCloudRestClientModule<HostingDotComVCloudClient, HostingDotComVCloudAsyncClient> {
|
||||||
|
|
||||||
public HostingDotComVCloudRestClientModule() {
|
public HostingDotComVCloudRestClientModule() {
|
||||||
super(HostingDotComVCloudClient.class, HostingDotComVCloudAsyncClient.class);
|
super(HostingDotComVCloudClient.class,
|
||||||
|
HostingDotComVCloudAsyncClient.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
protected VCloudAsyncClient provideVCloudAsyncClient(HostingDotComVCloudAsyncClient in) {
|
protected VCloudAsyncClient provideVCloudAsyncClient(
|
||||||
|
HostingDotComVCloudAsyncClient in) {
|
||||||
return in;
|
return in;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,8 +67,4 @@ public class HostingDotComVCloudRestClientModule extends
|
||||||
return URI.create("https://vcloud.safesecureweb.com/network/1990");
|
return URI.create("https://vcloud.safesecureweb.com/network/1990");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Predicate<String> successTester(TaskSuccess success) {
|
|
||||||
return new RetryablePredicate<String>(success, 45, 10, TimeUnit.MINUTES);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,36 +61,47 @@ public class TerremarkVCloudComputeClient extends BaseVCloudComputeClient {
|
||||||
@Inject
|
@Inject
|
||||||
protected TerremarkVCloudComputeClient(TerremarkVCloudClient client,
|
protected TerremarkVCloudComputeClient(TerremarkVCloudClient client,
|
||||||
PopulateDefaultLoginCredentialsForImageStrategy credentialsProvider,
|
PopulateDefaultLoginCredentialsForImageStrategy credentialsProvider,
|
||||||
@Named("PASSWORD") Provider<String> passwordGenerator, Predicate<String> successTester,
|
@Named("PASSWORD") Provider<String> passwordGenerator,
|
||||||
@Named("NOT_FOUND") Predicate<VApp> notFoundTester,
|
Predicate<String> successTester,
|
||||||
Map<VAppStatus, NodeState> vAppStatusToNodeState) {
|
Map<VAppStatus, NodeState> vAppStatusToNodeState) {
|
||||||
super(client, successTester, notFoundTester, vAppStatusToNodeState);
|
super(client, successTester, vAppStatusToNodeState);
|
||||||
this.client = client;
|
this.client = client;
|
||||||
this.credentialsProvider = credentialsProvider;
|
this.credentialsProvider = credentialsProvider;
|
||||||
this.passwordGenerator = passwordGenerator;
|
this.passwordGenerator = passwordGenerator;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Map<String, String> parseAndValidateResponse(String templateId, VApp vAppResponse) {
|
protected Map<String, String> parseAndValidateResponse(String templateId,
|
||||||
Credentials credentials = credentialsProvider.execute(client.getVAppTemplate(templateId));
|
VApp vAppResponse) {
|
||||||
Map<String, String> toReturn = super.parseResponse(templateId, vAppResponse);
|
Credentials credentials = credentialsProvider.execute(client
|
||||||
|
.getVAppTemplate(templateId));
|
||||||
|
Map<String, String> toReturn = super.parseResponse(templateId,
|
||||||
|
vAppResponse);
|
||||||
toReturn.put("username", credentials.account);
|
toReturn.put("username", credentials.account);
|
||||||
toReturn.put("password", credentials.key);
|
toReturn.put("password", credentials.key);
|
||||||
return toReturn;
|
return toReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, String> start(String vDCId, String name, String templateId,
|
public Map<String, String> start(String vDCId, String name,
|
||||||
InstantiateVAppTemplateOptions options, int... portsToOpen) {
|
String templateId, InstantiateVAppTemplateOptions options,
|
||||||
|
int... portsToOpen) {
|
||||||
if (options.getDiskSizeKilobytes() != null) {
|
if (options.getDiskSizeKilobytes() != null) {
|
||||||
logger.warn("trmk does not support resizing the primary disk; unsetting disk size");
|
logger
|
||||||
|
.warn("trmk does not support resizing the primary disk; unsetting disk size");
|
||||||
}
|
}
|
||||||
|
// we only get IP addresses after "deploy"
|
||||||
|
if (portsToOpen.length > 0 && !options.shouldBlockOnDeploy())
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"We cannot open ports on terremark unless we can deploy the vapp");
|
||||||
String password = null;
|
String password = null;
|
||||||
if (client.getVAppTemplate(templateId).getDescription().indexOf("Windows") != -1) {
|
if (client.getVAppTemplate(templateId).getDescription()
|
||||||
|
.indexOf("Windows") != -1) {
|
||||||
password = passwordGenerator.get();
|
password = passwordGenerator.get();
|
||||||
options.getProperties().put("password", password);
|
options.getProperties().put("password", password);
|
||||||
}
|
}
|
||||||
Map<String, String> response = super.start(vDCId, name, templateId, options, portsToOpen);
|
Map<String, String> response = super.start(vDCId, name, templateId,
|
||||||
|
options, portsToOpen);
|
||||||
if (password != null) {
|
if (password != null) {
|
||||||
response = new LinkedHashMap<String, String>(response);
|
response = new LinkedHashMap<String, String>(response);
|
||||||
response.put("password", password);
|
response.put("password", password);
|
||||||
|
@ -103,7 +114,8 @@ public class TerremarkVCloudComputeClient extends BaseVCloudComputeClient {
|
||||||
public String createPublicAddressMappedToPorts(String vAppId, int... ports) {
|
public String createPublicAddressMappedToPorts(String vAppId, int... ports) {
|
||||||
VApp vApp = client.getVApp(vAppId);
|
VApp vApp = client.getVApp(vAppId);
|
||||||
PublicIpAddress ip = null;
|
PublicIpAddress ip = null;
|
||||||
String privateAddress = Iterables.getLast(vApp.getNetworkToAddresses().values());
|
String privateAddress = Iterables.getLast(vApp.getNetworkToAddresses()
|
||||||
|
.values());
|
||||||
for (int port : ports) {
|
for (int port : ports) {
|
||||||
InternetService is = null;
|
InternetService is = null;
|
||||||
Protocol protocol;
|
Protocol protocol;
|
||||||
|
@ -123,48 +135,56 @@ public class TerremarkVCloudComputeClient extends BaseVCloudComputeClient {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (ip == null) {
|
if (ip == null) {
|
||||||
logger.debug(">> creating InternetService in vDC %s:%s:%d", vApp.getVDC().getId(),
|
logger.debug(">> creating InternetService in vDC %s:%s:%d", vApp
|
||||||
protocol, port);
|
.getVDC().getId(), protocol, port);
|
||||||
is = client.addInternetServiceToVDC(vApp.getVDC().getId(), vApp.getName() + "-" + port,
|
is = client.addInternetServiceToVDC(vApp.getVDC().getId(), vApp
|
||||||
protocol, port, withDescription(String.format(
|
.getName()
|
||||||
"port %d access to serverId: %s name: %s", port, vApp.getId(), vApp
|
+ "-" + port, protocol, port, withDescription(String.format(
|
||||||
.getName())));
|
"port %d access to serverId: %s name: %s", port,
|
||||||
|
vApp.getId(), vApp.getName())));
|
||||||
ip = is.getPublicIpAddress();
|
ip = is.getPublicIpAddress();
|
||||||
} else {
|
} else {
|
||||||
logger.debug(">> adding InternetService %s:%s:%d", ip.getAddress(), protocol, port);
|
logger.debug(">> adding InternetService %s:%s:%d", ip.getAddress(),
|
||||||
is = client.addInternetServiceToExistingIp(ip.getId(), vApp.getName() + "-" + port,
|
protocol, port);
|
||||||
protocol, port, withDescription(String.format(
|
is = client.addInternetServiceToExistingIp(ip.getId(), vApp
|
||||||
"port %d access to serverId: %s name: %s", port, vApp.getId(), vApp
|
.getName()
|
||||||
.getName())));
|
+ "-" + port, protocol, port, withDescription(String.format(
|
||||||
|
"port %d access to serverId: %s name: %s", port,
|
||||||
|
vApp.getId(), vApp.getName())));
|
||||||
}
|
}
|
||||||
logger.debug("<< created InternetService(%s) %s:%s:%d", is.getId(), is
|
logger.debug("<< created InternetService(%s) %s:%s:%d", is.getId(), is
|
||||||
.getPublicIpAddress().getAddress(), is.getProtocol(), is.getPort());
|
.getPublicIpAddress().getAddress(), is.getProtocol(), is
|
||||||
logger.debug(">> adding Node %s:%d -> %s:%d", is.getPublicIpAddress().getAddress(), is
|
.getPort());
|
||||||
.getPort(), privateAddress, port);
|
logger.debug(">> adding Node %s:%d -> %s:%d", is.getPublicIpAddress()
|
||||||
Node node = client.addNode(is.getId(), privateAddress, vApp.getName() + "-" + port, port);
|
.getAddress(), is.getPort(), privateAddress, port);
|
||||||
|
Node node = client.addNode(is.getId(), privateAddress, vApp.getName()
|
||||||
|
+ "-" + port, port);
|
||||||
logger.debug("<< added Node(%s)", node.getId());
|
logger.debug("<< added Node(%s)", node.getId());
|
||||||
}
|
}
|
||||||
return ip != null ? ip.getAddress() : null;
|
return ip != null ? ip.getAddress() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Set<PublicIpAddress> deleteInternetServicesAndNodesAssociatedWithVApp(VApp vApp) {
|
private Set<PublicIpAddress> deleteInternetServicesAndNodesAssociatedWithVApp(
|
||||||
|
VApp vApp) {
|
||||||
Set<PublicIpAddress> ipAddresses = Sets.newHashSet();
|
Set<PublicIpAddress> ipAddresses = Sets.newHashSet();
|
||||||
SERVICE: for (InternetService service : client.getAllInternetServicesInVDC(vApp.getVDC()
|
SERVICE: for (InternetService service : client
|
||||||
.getId())) {
|
.getAllInternetServicesInVDC(vApp.getVDC().getId())) {
|
||||||
for (Node node : client.getNodes(service.getId())) {
|
for (Node node : client.getNodes(service.getId())) {
|
||||||
if (vApp.getNetworkToAddresses().containsValue(node.getIpAddress())) {
|
if (vApp.getNetworkToAddresses().containsValue(node.getIpAddress())) {
|
||||||
ipAddresses.add(service.getPublicIpAddress());
|
ipAddresses.add(service.getPublicIpAddress());
|
||||||
logger.debug(">> deleting Node(%s) %s:%d -> %s:%d", node.getId(), service
|
logger.debug(">> deleting Node(%s) %s:%d -> %s:%d",
|
||||||
.getPublicIpAddress().getAddress(), service.getPort(), node.getIpAddress(),
|
node.getId(), service.getPublicIpAddress().getAddress(),
|
||||||
node.getPort());
|
service.getPort(), node.getIpAddress(), node.getPort());
|
||||||
client.deleteNode(node.getId());
|
client.deleteNode(node.getId());
|
||||||
logger.debug("<< deleted Node(%s)", node.getId());
|
logger.debug("<< deleted Node(%s)", node.getId());
|
||||||
SortedSet<Node> nodes = client.getNodes(service.getId());
|
SortedSet<Node> nodes = client.getNodes(service.getId());
|
||||||
if (nodes.size() == 0) {
|
if (nodes.size() == 0) {
|
||||||
logger.debug(">> deleting InternetService(%s) %s:%d", service.getId(), service
|
logger.debug(">> deleting InternetService(%s) %s:%d", service
|
||||||
.getPublicIpAddress().getAddress(), service.getPort());
|
.getId(), service.getPublicIpAddress().getAddress(),
|
||||||
|
service.getPort());
|
||||||
client.deleteInternetService(service.getId());
|
client.deleteInternetService(service.getId());
|
||||||
logger.debug("<< deleted InternetService(%s)", service.getId());
|
logger.debug("<< deleted InternetService(%s)", service
|
||||||
|
.getId());
|
||||||
continue SERVICE;
|
continue SERVICE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -173,13 +193,14 @@ public class TerremarkVCloudComputeClient extends BaseVCloudComputeClient {
|
||||||
return ipAddresses;
|
return ipAddresses;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void deletePublicIpAddressesWithNoServicesAttached(Set<PublicIpAddress> ipAddresses) {
|
private void deletePublicIpAddressesWithNoServicesAttached(
|
||||||
|
Set<PublicIpAddress> ipAddresses) {
|
||||||
IPADDRESS: for (PublicIpAddress address : ipAddresses) {
|
IPADDRESS: for (PublicIpAddress address : ipAddresses) {
|
||||||
SortedSet<InternetService> services = client
|
SortedSet<InternetService> services = client
|
||||||
.getInternetServicesOnPublicIp(address.getId());
|
.getInternetServicesOnPublicIp(address.getId());
|
||||||
if (services.size() == 0) {
|
if (services.size() == 0) {
|
||||||
logger.debug(">> deleting PublicIpAddress(%s) %s", address.getId(), address
|
logger.debug(">> deleting PublicIpAddress(%s) %s", address.getId(),
|
||||||
.getAddress());
|
address.getAddress());
|
||||||
client.deletePublicIp(address.getId());
|
client.deletePublicIp(address.getId());
|
||||||
logger.debug("<< deleted PublicIpAddress(%s)", address.getId());
|
logger.debug("<< deleted PublicIpAddress(%s)", address.getId());
|
||||||
continue IPADDRESS;
|
continue IPADDRESS;
|
||||||
|
@ -188,9 +209,10 @@ public class TerremarkVCloudComputeClient extends BaseVCloudComputeClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* deletes the internet service and nodes associated with the vapp. Deletes the IP address, if
|
* deletes the internet service and nodes associated with the vapp. Deletes
|
||||||
* there are no others using it. Finally, it powers off and deletes the vapp. Note that we do not
|
* the IP address, if there are no others using it. Finally, it powers off
|
||||||
* call undeploy, as terremark does not support the command.
|
* and deletes the vapp. Note that we do not call undeploy, as terremark does
|
||||||
|
* not support the command.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void stop(String id) {
|
public void stop(String id) {
|
||||||
|
@ -198,8 +220,8 @@ public class TerremarkVCloudComputeClient extends BaseVCloudComputeClient {
|
||||||
Set<PublicIpAddress> ipAddresses = deleteInternetServicesAndNodesAssociatedWithVApp(vApp);
|
Set<PublicIpAddress> ipAddresses = deleteInternetServicesAndNodesAssociatedWithVApp(vApp);
|
||||||
deletePublicIpAddressesWithNoServicesAttached(ipAddresses);
|
deletePublicIpAddressesWithNoServicesAttached(ipAddresses);
|
||||||
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
|
||||||
.getStatus());
|
.getId(), vApp.getStatus());
|
||||||
Task task = client.powerOffVApp(vApp.getId());
|
Task task = client.powerOffVApp(vApp.getId());
|
||||||
if (!taskTester.apply(task.getId())) {
|
if (!taskTester.apply(task.getId())) {
|
||||||
throw new TaskException("powerOff", vApp, task);
|
throw new TaskException("powerOff", vApp, task);
|
||||||
|
@ -209,8 +231,7 @@ public class TerremarkVCloudComputeClient extends BaseVCloudComputeClient {
|
||||||
}
|
}
|
||||||
logger.debug(">> deleting vApp(%s)", vApp.getId());
|
logger.debug(">> deleting vApp(%s)", vApp.getId());
|
||||||
client.deleteVApp(id);
|
client.deleteVApp(id);
|
||||||
boolean successful = notFoundTester.apply(vApp);
|
logger.debug("<< deleted vApp(%s))", vApp.getId());
|
||||||
logger.debug("<< deleted vApp(%s) completed(%s)", vApp.getId(), successful);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -223,7 +244,8 @@ public class TerremarkVCloudComputeClient extends BaseVCloudComputeClient {
|
||||||
public Set<String> getPublicAddresses(String id) {
|
public Set<String> getPublicAddresses(String id) {
|
||||||
VApp vApp = client.getVApp(id);
|
VApp vApp = client.getVApp(id);
|
||||||
Set<String> ipAddresses = Sets.newHashSet();
|
Set<String> ipAddresses = Sets.newHashSet();
|
||||||
for (InternetService service : client.getAllInternetServicesInVDC(vApp.getVDC().getId())) {
|
for (InternetService service : client.getAllInternetServicesInVDC(vApp
|
||||||
|
.getVDC().getId())) {
|
||||||
for (Node node : client.getNodes(service.getId())) {
|
for (Node node : client.getNodes(service.getId())) {
|
||||||
if (vApp.getNetworkToAddresses().containsValue(node.getIpAddress())) {
|
if (vApp.getNetworkToAddresses().containsValue(node.getIpAddress())) {
|
||||||
ipAddresses.add(service.getPublicIpAddress().getAddress());
|
ipAddresses.add(service.getPublicIpAddress().getAddress());
|
||||||
|
|
|
@ -51,7 +51,8 @@ public class TerremarkVCloudComputeClientTest {
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Test
|
@Test
|
||||||
public void testStartWindows() throws IOException {
|
public void testStartWindows() throws IOException {
|
||||||
InputStream is = getClass().getResourceAsStream("/terremark/windows_description.txt");
|
InputStream is = getClass().getResourceAsStream(
|
||||||
|
"/terremark/windows_description.txt");
|
||||||
String description = new String(ByteStreams.toByteArray(is));
|
String description = new String(ByteStreams.toByteArray(is));
|
||||||
VAppTemplate template = createMock(VAppTemplate.class);
|
VAppTemplate template = createMock(VAppTemplate.class);
|
||||||
expect(template.getDescription()).andReturn(description).atLeastOnce();
|
expect(template.getDescription()).andReturn(description).atLeastOnce();
|
||||||
|
@ -61,8 +62,9 @@ public class TerremarkVCloudComputeClientTest {
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
client.instantiateVAppTemplateInVDC("vDCId", "name", "templateId",
|
client.instantiateVAppTemplateInVDC("vDCId", "name", "templateId",
|
||||||
new TerremarkInstantiateVAppTemplateOptions().productProperty("password",
|
new TerremarkInstantiateVAppTemplateOptions()
|
||||||
"password"))).andReturn(vApp);
|
.productProperty("password", "password"))).andReturn(
|
||||||
|
vApp);
|
||||||
Task task = createMock(Task.class);
|
Task task = createMock(Task.class);
|
||||||
|
|
||||||
expect(vApp.getId()).andReturn("1").atLeastOnce();
|
expect(vApp.getId()).andReturn("1").atLeastOnce();
|
||||||
|
@ -76,7 +78,8 @@ public class TerremarkVCloudComputeClientTest {
|
||||||
Predicate<VApp> notFoundTester = createMock(Predicate.class);
|
Predicate<VApp> notFoundTester = createMock(Predicate.class);
|
||||||
Map<VAppStatus, NodeState> vAppStatusToNodeState = createMock(Map.class);
|
Map<VAppStatus, NodeState> vAppStatusToNodeState = createMock(Map.class);
|
||||||
|
|
||||||
TerremarkVCloudComputeClient computeClient = new TerremarkVCloudComputeClient(client,
|
TerremarkVCloudComputeClient computeClient = new TerremarkVCloudComputeClient(
|
||||||
|
client,
|
||||||
new ParseVAppTemplateDescriptionToGetDefaultLoginCredentials(),
|
new ParseVAppTemplateDescriptionToGetDefaultLoginCredentials(),
|
||||||
new Provider<String>() {
|
new Provider<String>() {
|
||||||
|
|
||||||
|
@ -85,7 +88,7 @@ public class TerremarkVCloudComputeClientTest {
|
||||||
return "password";
|
return "password";
|
||||||
}
|
}
|
||||||
|
|
||||||
}, successTester, notFoundTester, vAppStatusToNodeState);
|
}, successTester, vAppStatusToNodeState);
|
||||||
|
|
||||||
replay(template);
|
replay(template);
|
||||||
replay(vApp);
|
replay(vApp);
|
||||||
|
@ -95,8 +98,8 @@ public class TerremarkVCloudComputeClientTest {
|
||||||
replay(notFoundTester);
|
replay(notFoundTester);
|
||||||
replay(vAppStatusToNodeState);
|
replay(vAppStatusToNodeState);
|
||||||
|
|
||||||
Map<String, String> response = computeClient.start("vDCId", "name", "templateId",
|
Map<String, String> response = computeClient.start("vDCId", "name",
|
||||||
new TerremarkInstantiateVAppTemplateOptions());
|
"templateId", new TerremarkInstantiateVAppTemplateOptions());
|
||||||
|
|
||||||
assertEquals(response.get("id"), "1");
|
assertEquals(response.get("id"), "1");
|
||||||
assertEquals(response.get("username"), "Administrator");
|
assertEquals(response.get("username"), "Administrator");
|
||||||
|
|
Loading…
Reference in New Issue