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.LoadBalancerService;
|
||||
import org.jclouds.compute.config.ComputeServiceTimeoutsModule;
|
||||
import org.jclouds.compute.domain.ComputeMetadata;
|
||||
import org.jclouds.compute.domain.Image;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
|
@ -80,6 +81,7 @@ public class ${providerName}ComputeServiceContextModule extends ${providerName}C
|
|||
@Override
|
||||
protected void configure() {
|
||||
super.configure();
|
||||
install(new ComputeServiceTimeoutsModule());
|
||||
bind(new TypeLiteral<ComputeServiceContext>() {
|
||||
})
|
||||
.to(
|
||||
|
@ -93,12 +95,6 @@ public class ${providerName}ComputeServiceContextModule extends ${providerName}C
|
|||
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
|
||||
*/
|
||||
|
@ -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
|
||||
@Singleton
|
||||
Location getDefaultLocation(Set<? extends Location> locations) {
|
||||
|
|
|
@ -66,18 +66,27 @@ public class EC2ComputeService extends BaseComputeService {
|
|||
|
||||
@Inject
|
||||
protected EC2ComputeService(ComputeServiceContext context,
|
||||
Provider<Set<? extends Image>> images, Provider<Set<? extends Size>> sizes,
|
||||
Provider<Set<? extends Location>> locations, ListNodesStrategy listNodesStrategy,
|
||||
GetNodeMetadataStrategy getNodeMetadataStrategy,
|
||||
RunNodesAndAddToSetStrategy runNodesAndAddToSetStrategy,
|
||||
RebootNodeStrategy rebootNodeStrategy, DestroyNodeStrategy destroyNodeStrategy,
|
||||
Provider<TemplateBuilder> templateBuilderProvider,
|
||||
Provider<TemplateOptions> templateOptionsProvider, ComputeUtils utils,
|
||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor, EC2Client ec2Client,
|
||||
Map<RegionAndName, KeyPair> credentialsMap, Map<RegionAndName, String> securityGroupMap) {
|
||||
super(context, images, sizes, locations, listNodesStrategy, getNodeMetadataStrategy,
|
||||
runNodesAndAddToSetStrategy, rebootNodeStrategy, destroyNodeStrategy,
|
||||
templateBuilderProvider, templateOptionsProvider, utils, executor);
|
||||
Provider<Set<? extends Image>> images,
|
||||
Provider<Set<? extends Size>> sizes,
|
||||
Provider<Set<? extends Location>> locations,
|
||||
ListNodesStrategy listNodesStrategy,
|
||||
GetNodeMetadataStrategy getNodeMetadataStrategy,
|
||||
RunNodesAndAddToSetStrategy runNodesAndAddToSetStrategy,
|
||||
RebootNodeStrategy rebootNodeStrategy,
|
||||
DestroyNodeStrategy destroyNodeStrategy,
|
||||
Provider<TemplateBuilder> templateBuilderProvider,
|
||||
Provider<TemplateOptions> templateOptionsProvider,
|
||||
@Named("NODE_RUNNING") Predicate<NodeMetadata> nodeRunning,
|
||||
@Named("NODE_TERMINATED") Predicate<NodeMetadata> nodeTerminated,
|
||||
ComputeUtils utils,
|
||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService 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.credentialsMap = credentialsMap;
|
||||
this.securityGroupMap = securityGroupMap;
|
||||
|
@ -86,38 +95,46 @@ public class EC2ComputeService extends BaseComputeService {
|
|||
private void deleteSecurityGroup(String region, String tag) {
|
||||
checkNotEmpty(tag, "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);
|
||||
ec2Client.getSecurityGroupServices().deleteSecurityGroupInRegion(region, group);
|
||||
ec2Client.getSecurityGroupServices().deleteSecurityGroupInRegion(
|
||||
region, group);
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
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]+")) {
|
||||
logger.debug(">> deleting keyPair(%s)", keyPair.getKeyName());
|
||||
ec2Client.getKeyPairServices().deleteKeyPairInRegion(region, keyPair.getKeyName());
|
||||
ec2Client.getKeyPairServices().deleteKeyPairInRegion(region,
|
||||
keyPair.getKeyName());
|
||||
// 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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* like {@link BaseComputeService#destroyNodesMatching} except that this will clean implicit
|
||||
* keypairs and security groups.
|
||||
* like {@link BaseComputeService#destroyNodesMatching} except that this will
|
||||
* clean implicit keypairs and security groups.
|
||||
*/
|
||||
@Override
|
||||
public Set<? extends NodeMetadata> destroyNodesMatching(Predicate<NodeMetadata> filter) {
|
||||
public Set<? extends NodeMetadata> destroyNodesMatching(
|
||||
Predicate<NodeMetadata> filter) {
|
||||
Set<? extends NodeMetadata> deadOnes = super.destroyNodesMatching(filter);
|
||||
Map<String, String> regionTags = Maps.newHashMap();
|
||||
for (NodeMetadata nodeMetadata : deadOnes) {
|
||||
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()) {
|
||||
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.Image.ImageType;
|
||||
import org.jclouds.aws.ec2.functions.RunningInstanceToStorageMappingUnix;
|
||||
import org.jclouds.aws.ec2.predicates.InstancePresent;
|
||||
import org.jclouds.aws.ec2.services.InstanceClient;
|
||||
import org.jclouds.compute.ComputeService;
|
||||
import org.jclouds.compute.ComputeServiceContext;
|
||||
import org.jclouds.compute.config.ComputeServiceTimeoutsModule;
|
||||
import org.jclouds.compute.domain.Architecture;
|
||||
import org.jclouds.compute.domain.ComputeMetadata;
|
||||
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.options.TemplateOptions;
|
||||
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.strategy.DestroyLoadBalancerStrategy;
|
||||
import org.jclouds.compute.strategy.DestroyNodeStrategy;
|
||||
|
@ -92,11 +92,9 @@ import org.jclouds.domain.LocationScope;
|
|||
import org.jclouds.domain.internal.LocationImpl;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.predicates.RetryablePredicate;
|
||||
import com.google.inject.name.Names;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.base.Supplier;
|
||||
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.Scopes;
|
||||
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
|
||||
*/
|
||||
|
@ -122,25 +122,40 @@ public class EC2ComputeServiceContextModule extends EC2ContextModule {
|
|||
this.providerName = providerName;
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
@Named("PRESENT")
|
||||
protected Predicate<RunningInstance> instancePresent(InstancePresent present) {
|
||||
return new RetryablePredicate<RunningInstance>(present, 3000, 200,
|
||||
TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
super.configure();
|
||||
install(new ComputeServiceTimeoutsModule());
|
||||
bind(TemplateBuilder.class).to(EC2TemplateBuilderImpl.class);
|
||||
bind(TemplateOptions.class).to(EC2TemplateOptions.class);
|
||||
bind(ComputeService.class).to(EC2ComputeService.class);
|
||||
bind(new TypeLiteral<ComputeServiceContext>() {
|
||||
}).to(new TypeLiteral<ComputeServiceContextImpl<EC2Client, EC2AsyncClient>>() {
|
||||
}).in(Scopes.SINGLETON);
|
||||
bind(LoadBalanceNodesStrategy.class).to(EC2LoadBalanceNodesStrategy.class);
|
||||
bind(DestroyLoadBalancerStrategy.class).to(EC2DestroyLoadBalancerStrategy.class);
|
||||
bind(RunNodesAndAddToSetStrategy.class).to(EC2RunNodesAndAddToSetStrategy.class);
|
||||
})
|
||||
.to(
|
||||
new TypeLiteral<ComputeServiceContextImpl<EC2Client, EC2AsyncClient>>() {
|
||||
}).in(Scopes.SINGLETON);
|
||||
bind(LoadBalanceNodesStrategy.class)
|
||||
.to(EC2LoadBalanceNodesStrategy.class);
|
||||
bind(DestroyLoadBalancerStrategy.class).to(
|
||||
EC2DestroyLoadBalancerStrategy.class);
|
||||
bind(RunNodesAndAddToSetStrategy.class).to(
|
||||
EC2RunNodesAndAddToSetStrategy.class);
|
||||
bind(ListNodesStrategy.class).to(EC2ListNodesStrategy.class);
|
||||
bind(GetNodeMetadataStrategy.class).to(EC2GetNodeMetadataStrategy.class);
|
||||
bind(RebootNodeStrategy.class).to(EC2RebootNodeStrategy.class);
|
||||
bind(DestroyNodeStrategy.class).to(EC2DestroyNodeStrategy.class);
|
||||
bind(new TypeLiteral<Function<RunningInstance, Map<String, String>>>() {
|
||||
}).annotatedWith(Names.named("volumeMapping")).to(RunningInstanceToStorageMappingUnix.class)
|
||||
.in(Scopes.SINGLETON);
|
||||
}).annotatedWith(Names.named("volumeMapping")).to(
|
||||
RunningInstanceToStorageMappingUnix.class).in(Scopes.SINGLETON);
|
||||
}
|
||||
|
||||
@Provides
|
||||
|
@ -160,11 +175,12 @@ public class EC2ComputeServiceContextModule extends EC2ContextModule {
|
|||
@Provides
|
||||
@Named("DEFAULT")
|
||||
protected TemplateBuilder provideTemplate(TemplateBuilder template) {
|
||||
return template.architecture(Architecture.X86_32).osFamily(UBUNTU).imageNameMatches(
|
||||
".*10\\.?04.*");
|
||||
return template.architecture(Architecture.X86_32).osFamily(UBUNTU)
|
||||
.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
|
||||
@Singleton
|
||||
public static class EC2ListNodesStrategy implements ListNodesStrategy {
|
||||
|
@ -178,9 +194,10 @@ public class EC2ComputeServiceContextModule extends EC2ContextModule {
|
|||
private final ExecutorService executor;
|
||||
|
||||
@Inject
|
||||
protected EC2ListNodesStrategy(EC2Client client, @EC2 Map<String, URI> regionMap,
|
||||
RunningInstanceToNodeMetadata runningInstanceToNodeMetadata,
|
||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) {
|
||||
protected EC2ListNodesStrategy(EC2Client client,
|
||||
@EC2 Map<String, URI> regionMap,
|
||||
RunningInstanceToNodeMetadata runningInstanceToNodeMetadata,
|
||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) {
|
||||
this.client = client;
|
||||
this.regionMap = regionMap;
|
||||
this.runningInstanceToNodeMetadata = runningInstanceToNodeMetadata;
|
||||
|
@ -194,42 +211,44 @@ public class EC2ComputeServiceContextModule extends EC2ContextModule {
|
|||
|
||||
@Override
|
||||
public Iterable<? extends NodeMetadata> listDetailsOnNodesMatching(
|
||||
Predicate<ComputeMetadata> filter) {
|
||||
Predicate<ComputeMetadata> filter) {
|
||||
final Set<NodeMetadata> nodes = Sets.newHashSet();
|
||||
|
||||
Map<String, ListenableFuture<?>> parallelResponses = Maps.newHashMap();
|
||||
|
||||
for (final String region : regionMap.keySet()) {
|
||||
parallelResponses.put(region, ConcurrentUtils.makeListenable(executor
|
||||
.submit(new Callable<Void>() {
|
||||
@Override
|
||||
public Void call() throws Exception {
|
||||
Iterables.addAll(nodes, Iterables.transform(Iterables.concat(client
|
||||
.getInstanceServices().describeInstancesInRegion(region)),
|
||||
runningInstanceToNodeMetadata));
|
||||
return null;
|
||||
}
|
||||
}), executor));
|
||||
parallelResponses.put(region, ConcurrentUtils.makeListenable(
|
||||
executor.submit(new Callable<Void>() {
|
||||
@Override
|
||||
public Void call() throws Exception {
|
||||
Iterables.addAll(nodes, Iterables.transform(Iterables
|
||||
.concat(client.getInstanceServices()
|
||||
.describeInstancesInRegion(region)),
|
||||
runningInstanceToNodeMetadata));
|
||||
return null;
|
||||
}
|
||||
}), executor));
|
||||
}
|
||||
Map<String, Exception> exceptions = awaitCompletion(parallelResponses, executor, null,
|
||||
logger, "nodes");
|
||||
Map<String, Exception> exceptions = awaitCompletion(parallelResponses,
|
||||
executor, null, logger, "nodes");
|
||||
|
||||
if (exceptions.size() > 0)
|
||||
throw new RuntimeException(String.format("error parsing nodes in regions: %s",
|
||||
exceptions));
|
||||
throw new RuntimeException(String.format(
|
||||
"error parsing nodes in regions: %s", exceptions));
|
||||
return Iterables.filter(nodes, filter);
|
||||
}
|
||||
}
|
||||
|
||||
@Singleton
|
||||
public static class EC2GetNodeMetadataStrategy implements GetNodeMetadataStrategy {
|
||||
public static class EC2GetNodeMetadataStrategy implements
|
||||
GetNodeMetadataStrategy {
|
||||
|
||||
private final EC2Client client;
|
||||
private final RunningInstanceToNodeMetadata runningInstanceToNodeMetadata;
|
||||
|
||||
@Inject
|
||||
protected EC2GetNodeMetadataStrategy(EC2Client client,
|
||||
RunningInstanceToNodeMetadata runningInstanceToNodeMetadata) {
|
||||
RunningInstanceToNodeMetadata runningInstanceToNodeMetadata) {
|
||||
this.client = client;
|
||||
this.runningInstanceToNodeMetadata = runningInstanceToNodeMetadata;
|
||||
}
|
||||
|
@ -239,8 +258,9 @@ public class EC2ComputeServiceContextModule extends EC2ContextModule {
|
|||
String[] parts = parseHandle(id);
|
||||
String region = parts[0];
|
||||
String instanceId = parts[1];
|
||||
RunningInstance runningInstance = Iterables.getOnlyElement(getAllRunningInstancesInRegion(
|
||||
client.getInstanceServices(), region, instanceId));
|
||||
RunningInstance runningInstance = Iterables
|
||||
.getOnlyElement(getAllRunningInstancesInRegion(client
|
||||
.getInstanceServices(), region, instanceId));
|
||||
return runningInstanceToNodeMetadata.apply(runningInstance);
|
||||
}
|
||||
|
||||
|
@ -249,34 +269,30 @@ public class EC2ComputeServiceContextModule extends EC2ContextModule {
|
|||
@Singleton
|
||||
public static class EC2RebootNodeStrategy implements RebootNodeStrategy {
|
||||
private final InstanceClient client;
|
||||
private final GetNodeMetadataStrategy getNode;
|
||||
|
||||
@Inject
|
||||
protected EC2RebootNodeStrategy(EC2Client client) {
|
||||
protected EC2RebootNodeStrategy(EC2Client client,
|
||||
GetNodeMetadataStrategy getNode) {
|
||||
this.client = client.getInstanceServices();
|
||||
this.getNode = getNode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(String id) {
|
||||
public NodeMetadata execute(String id) {
|
||||
String[] parts = parseHandle(id);
|
||||
String region = parts[0];
|
||||
String instanceId = parts[1];
|
||||
client.rebootInstancesInRegion(region, instanceId);
|
||||
return true;
|
||||
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
|
||||
@Singleton
|
||||
protected final Map<RegionAndName, KeyPair> credentialsMap(CreateUniqueKeyPair in) {
|
||||
protected final Map<RegionAndName, KeyPair> credentialsMap(
|
||||
CreateUniqueKeyPair in) {
|
||||
// doesn't seem to clear when someone issues remove(key)
|
||||
// return new MapMaker().makeComputingMap(in);
|
||||
return Maps.newLinkedHashMap();
|
||||
|
@ -284,7 +300,8 @@ public class EC2ComputeServiceContextModule extends EC2ContextModule {
|
|||
|
||||
@Provides
|
||||
@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)
|
||||
// return new MapMaker().makeComputingMap(in);
|
||||
return Maps.newLinkedHashMap();
|
||||
|
@ -304,28 +321,33 @@ public class EC2ComputeServiceContextModule extends EC2ContextModule {
|
|||
@Provides
|
||||
@Singleton
|
||||
Set<? extends Size> provideSizes() {
|
||||
return ImmutableSet.of(EC2Size.C1_MEDIUM, EC2Size.C1_XLARGE, EC2Size.M1_LARGE,
|
||||
EC2Size.M1_SMALL, EC2Size.M1_XLARGE, EC2Size.M2_XLARGE, EC2Size.M2_2XLARGE,
|
||||
EC2Size.M2_4XLARGE);
|
||||
return ImmutableSet.of(EC2Size.C1_MEDIUM, EC2Size.C1_XLARGE,
|
||||
EC2Size.M1_LARGE, EC2Size.M1_SMALL, EC2Size.M1_XLARGE,
|
||||
EC2Size.M2_XLARGE, EC2Size.M2_2XLARGE, EC2Size.M2_4XLARGE);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
Set<? extends Location> provideLocations(Map<String, String> availabilityZoneToRegionMap) {
|
||||
Location ec2 = new LocationImpl(LocationScope.PROVIDER, providerName, providerName, null);
|
||||
Set<? extends Location> provideLocations(
|
||||
Map<String, String> availabilityZoneToRegionMap) {
|
||||
Location ec2 = new LocationImpl(LocationScope.PROVIDER, providerName,
|
||||
providerName, null);
|
||||
Set<Location> locations = Sets.newLinkedHashSet();
|
||||
for (String zone : availabilityZoneToRegionMap.keySet()) {
|
||||
Location region = new LocationImpl(LocationScope.REGION, availabilityZoneToRegionMap
|
||||
.get(zone), availabilityZoneToRegionMap.get(zone), ec2);
|
||||
Location region = new LocationImpl(LocationScope.REGION,
|
||||
availabilityZoneToRegionMap.get(zone),
|
||||
availabilityZoneToRegionMap.get(zone), ec2);
|
||||
locations.add(region);
|
||||
locations.add(new LocationImpl(LocationScope.ZONE, zone, zone, region));
|
||||
locations
|
||||
.add(new LocationImpl(LocationScope.ZONE, zone, zone, region));
|
||||
}
|
||||
return locations;
|
||||
}
|
||||
|
||||
@Provides
|
||||
@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>() {
|
||||
|
||||
@Override
|
||||
|
@ -352,26 +374,28 @@ public class EC2ComputeServiceContextModule extends EC2ContextModule {
|
|||
}
|
||||
|
||||
@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());
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
protected ConcurrentMap<RegionAndName, Image> provideImageMap(
|
||||
RegionAndIdToImage regionAndIdToImage) {
|
||||
RegionAndIdToImage regionAndIdToImage) {
|
||||
return new MapMaker().makeComputingMap(regionAndIdToImage);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
protected Map<RegionAndName, ? extends Image> provideImages(final EC2Client sync,
|
||||
@EC2 Map<String, URI> regionMap, final LogHolder holder,
|
||||
Function<ComputeMetadata, String> indexer,
|
||||
@Named(PROPERTY_EC2_AMI_OWNERS) final String[] amiOwners, final ImageParser parser,
|
||||
final ConcurrentMap<RegionAndName, Image> images,
|
||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor)
|
||||
throws InterruptedException, ExecutionException, TimeoutException {
|
||||
protected Map<RegionAndName, ? extends Image> provideImages(
|
||||
final EC2Client sync, @EC2 Map<String, URI> regionMap,
|
||||
final LogHolder holder, Function<ComputeMetadata, String> indexer,
|
||||
@Named(PROPERTY_EC2_AMI_OWNERS) final String[] amiOwners,
|
||||
final ImageParser parser,
|
||||
final ConcurrentMap<RegionAndName, Image> images,
|
||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor)
|
||||
throws InterruptedException, ExecutionException, TimeoutException {
|
||||
if (amiOwners.length == 0) {
|
||||
holder.logger.debug(">> no owners specified, skipping image parsing");
|
||||
} else {
|
||||
|
@ -380,30 +404,31 @@ public class EC2ComputeServiceContextModule extends EC2ContextModule {
|
|||
Map<String, ListenableFuture<?>> parallelResponses = Maps.newHashMap();
|
||||
|
||||
for (final String region : regionMap.keySet()) {
|
||||
parallelResponses.put(region, ConcurrentUtils.makeListenable(executor
|
||||
.submit(new Callable<Void>() {
|
||||
@Override
|
||||
public Void call() throws Exception {
|
||||
for (final org.jclouds.aws.ec2.domain.Image from : sync.getAMIServices()
|
||||
.describeImagesInRegion(region, ownedBy(amiOwners))) {
|
||||
Image image = parser.apply(from);
|
||||
if (image != null)
|
||||
images
|
||||
.put(new RegionAndName(region, image.getProviderId()),
|
||||
image);
|
||||
else if (from.getImageType() == ImageType.MACHINE)
|
||||
holder.logger.trace("<< image(%s) didn't parse", from.getId());
|
||||
}
|
||||
return null;
|
||||
parallelResponses.put(region, ConcurrentUtils.makeListenable(
|
||||
executor.submit(new Callable<Void>() {
|
||||
@Override
|
||||
public Void call() throws Exception {
|
||||
for (final org.jclouds.aws.ec2.domain.Image from : sync
|
||||
.getAMIServices().describeImagesInRegion(region,
|
||||
ownedBy(amiOwners))) {
|
||||
Image image = parser.apply(from);
|
||||
if (image != null)
|
||||
images.put(new RegionAndName(region, image
|
||||
.getProviderId()), image);
|
||||
else if (from.getImageType() == ImageType.MACHINE)
|
||||
holder.logger.trace("<< image(%s) didn't parse",
|
||||
from.getId());
|
||||
}
|
||||
}), executor));
|
||||
return null;
|
||||
}
|
||||
}), executor));
|
||||
}
|
||||
Map<String, Exception> exceptions = awaitCompletion(parallelResponses, executor, null,
|
||||
holder.logger, "images");
|
||||
Map<String, Exception> exceptions = awaitCompletion(parallelResponses,
|
||||
executor, null, holder.logger, "images");
|
||||
|
||||
if (exceptions.size() > 0)
|
||||
throw new RuntimeException(String.format("error parsing images in regions: %s",
|
||||
exceptions));
|
||||
throw new RuntimeException(String.format(
|
||||
"error parsing images in regions: %s", exceptions));
|
||||
|
||||
holder.logger.debug("<< images(%d)", images.size());
|
||||
}
|
||||
|
|
|
@ -27,15 +27,12 @@ import javax.inject.Named;
|
|||
import javax.inject.Singleton;
|
||||
|
||||
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.strategy.DestroyNodeStrategy;
|
||||
import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
|
||||
import org.jclouds.logging.Logger;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
|
@ -46,25 +43,22 @@ public class EC2DestroyNodeStrategy implements DestroyNodeStrategy {
|
|||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||
protected Logger logger = Logger.NULL;
|
||||
protected final EC2Client ec2Client;
|
||||
protected final Predicate<RunningInstance> instanceStateTerminated;
|
||||
protected final GetNodeMetadataStrategy getNodeMetadataStrategy;
|
||||
protected final GetNodeMetadataStrategy getNode;
|
||||
|
||||
@Inject
|
||||
protected EC2DestroyNodeStrategy(EC2Client ec2Client,
|
||||
@Named("TERMINATED") Predicate<RunningInstance> instanceStateTerminated,
|
||||
GetNodeMetadataStrategy getNodeMetadataStrategy) {
|
||||
GetNodeMetadataStrategy getNodeMetadataStrategy) {
|
||||
this.ec2Client = ec2Client;
|
||||
this.instanceStateTerminated = instanceStateTerminated;
|
||||
this.getNodeMetadataStrategy = getNodeMetadataStrategy;
|
||||
this.getNode = getNodeMetadataStrategy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(String id) {
|
||||
public NodeMetadata execute(String id) {
|
||||
String[] parts = parseHandle(id);
|
||||
String region = parts[0];
|
||||
String instanceId = parts[1];
|
||||
ec2Client.getInstanceServices().terminateInstancesInRegion(region, instanceId);
|
||||
return instanceStateTerminated.apply(Iterables.getOnlyElement(Iterables.concat(ec2Client
|
||||
.getInstanceServices().describeInstancesInRegion(region, instanceId))));
|
||||
ec2Client.getInstanceServices().terminateInstancesInRegion(region,
|
||||
instanceId);
|
||||
return getNode.execute(id);
|
||||
}
|
||||
}
|
|
@ -20,8 +20,6 @@
|
|||
package org.jclouds.aws.ec2.compute.strategy;
|
||||
|
||||
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 org.jclouds.aws.ec2.compute.util.EC2ComputeUtils.getRegionFromLocationOrNull;
|
||||
import static org.jclouds.aws.ec2.compute.util.EC2ComputeUtils.getZoneFromLocationOrNull;
|
||||
|
@ -58,7 +56,8 @@ import com.google.common.util.concurrent.ListenableFuture;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class EC2RunNodesAndAddToSetStrategy implements RunNodesAndAddToSetStrategy {
|
||||
public class EC2RunNodesAndAddToSetStrategy implements
|
||||
RunNodesAndAddToSetStrategy {
|
||||
|
||||
@Resource
|
||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||
|
@ -69,76 +68,64 @@ public class EC2RunNodesAndAddToSetStrategy implements RunNodesAndAddToSetStrate
|
|||
@VisibleForTesting
|
||||
final CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions createKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions;
|
||||
@VisibleForTesting
|
||||
final Predicate<RunningInstance> instanceStateRunning;
|
||||
@VisibleForTesting
|
||||
final RunningInstanceToNodeMetadata runningInstanceToNodeMetadata;
|
||||
@VisibleForTesting
|
||||
final ComputeUtils utils;
|
||||
|
||||
final Predicate<RunningInstance> instancePresent;
|
||||
|
||||
@Inject
|
||||
EC2RunNodesAndAddToSetStrategy(
|
||||
EC2Client client,
|
||||
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions createKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions,
|
||||
@Named("RUNNING") Predicate<RunningInstance> instanceStateRunning,
|
||||
RunningInstanceToNodeMetadata runningInstanceToNodeMetadata, ComputeUtils utils) {
|
||||
EC2Client client,
|
||||
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions createKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions,
|
||||
@Named("PRESENT") Predicate<RunningInstance> instancePresent,
|
||||
RunningInstanceToNodeMetadata runningInstanceToNodeMetadata,
|
||||
ComputeUtils utils) {
|
||||
this.client = client;
|
||||
this.instancePresent = instancePresent;
|
||||
this.createKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions = createKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions;
|
||||
this.instanceStateRunning = instanceStateRunning;
|
||||
this.runningInstanceToNodeMetadata = runningInstanceToNodeMetadata;
|
||||
this.utils = utils;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<?, ListenableFuture<Void>> execute(String tag, int count, Template template,
|
||||
Set<NodeMetadata> goodNodes, Map<NodeMetadata, Exception> badNodes) {
|
||||
public Map<?, ListenableFuture<Void>> execute(String tag, int count,
|
||||
Template template, Set<NodeMetadata> goodNodes,
|
||||
Map<NodeMetadata, Exception> badNodes) {
|
||||
|
||||
Reservation reservation = createKeyPairAndSecurityGroupsAsNeededThenRunInstances(tag, count,
|
||||
template);
|
||||
Reservation reservation = createKeyPairAndSecurityGroupsAsNeededThenRunInstances(
|
||||
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);
|
||||
|
||||
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
|
||||
Reservation createKeyPairAndSecurityGroupsAsNeededThenRunInstances(String tag, int count,
|
||||
Template template) {
|
||||
Reservation createKeyPairAndSecurityGroupsAsNeededThenRunInstances(
|
||||
String tag, int count, Template template) {
|
||||
String region = getRegionFromLocationOrNull(template.getLocation());
|
||||
String zone = getZoneFromLocationOrNull(template.getLocation());
|
||||
|
||||
RunInstancesOptions instanceOptions = createKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions
|
||||
.execute(region, tag, template);
|
||||
.execute(region, tag, template);
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug(">> running %d instance region(%s) zone(%s) ami(%s) params(%s)", count,
|
||||
region, zone, template.getImage().getProviderId(), instanceOptions
|
||||
.buildFormParameters());
|
||||
logger.debug(
|
||||
">> running %d instance region(%s) zone(%s) ami(%s) params(%s)",
|
||||
count, region, zone, template.getImage().getProviderId(),
|
||||
instanceOptions.buildFormParameters());
|
||||
|
||||
return client.getInstanceServices().runInstancesInRegion(region, zone,
|
||||
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)));
|
||||
template.getImage().getProviderId(), 1, count, instanceOptions);
|
||||
}
|
||||
|
||||
}
|
|
@ -49,11 +49,11 @@ public class EC2ContextModule extends AbstractModule {
|
|||
|
||||
@Provides
|
||||
@Singleton
|
||||
RestContext<EC2Client, EC2AsyncClient> provideContext(Closer closer, EC2AsyncClient defaultApi,
|
||||
EC2Client synchApi, @EC2 URI endPoint,
|
||||
@Named(AWSConstants.PROPERTY_AWS_ACCESSKEYID) String account) {
|
||||
return new RestContextImpl<EC2Client, EC2AsyncClient>(closer, defaultApi, synchApi, endPoint,
|
||||
account);
|
||||
RestContext<EC2Client, EC2AsyncClient> provideContext(Closer closer,
|
||||
EC2AsyncClient defaultApi, EC2Client synchApi, @EC2 URI endPoint,
|
||||
@Named(AWSConstants.PROPERTY_AWS_ACCESSKEYID) String account) {
|
||||
return new RestContextImpl<EC2Client, EC2AsyncClient>(closer, defaultApi,
|
||||
synchApi, endPoint, account);
|
||||
}
|
||||
|
||||
}
|
|
@ -21,7 +21,6 @@ package org.jclouds.aws.ec2.config;
|
|||
import java.net.URI;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.inject.Named;
|
||||
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.ELB;
|
||||
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.services.AMIAsyncClient;
|
||||
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.Redirection;
|
||||
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.RequestSigner;
|
||||
import org.jclouds.rest.config.RestClientModule;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.ImmutableBiMap;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Maps;
|
||||
|
@ -86,50 +78,32 @@ import com.google.inject.Provides;
|
|||
*/
|
||||
@RequiresHttp
|
||||
@ConfiguresRestClient
|
||||
public class EC2RestClientModule extends RestClientModule<EC2Client, EC2AsyncClient> {
|
||||
public class EC2RestClientModule extends
|
||||
RestClientModule<EC2Client, EC2AsyncClient> {
|
||||
public static final Map<Class<?>, Class<?>> DELEGATE_MAP = ImmutableMap
|
||||
.<Class<?>, Class<?>> builder()//
|
||||
.put(AMIClient.class, AMIAsyncClient.class)//
|
||||
.put(ElasticIPAddressClient.class, ElasticIPAddressAsyncClient.class)//
|
||||
.put(InstanceClient.class, InstanceAsyncClient.class)//
|
||||
.put(KeyPairClient.class, KeyPairAsyncClient.class)//
|
||||
.put(SecurityGroupClient.class, SecurityGroupAsyncClient.class)//
|
||||
.put(MonitoringClient.class, MonitoringAsyncClient.class)//
|
||||
.put(AvailabilityZoneAndRegionClient.class, AvailabilityZoneAndRegionAsyncClient.class)//
|
||||
.put(ElasticBlockStoreClient.class, ElasticBlockStoreAsyncClient.class)//
|
||||
.put(ElasticLoadBalancerClient.class, ElasticLoadBalancerAsyncClient.class)//
|
||||
.build();
|
||||
.<Class<?>, Class<?>> builder()//
|
||||
.put(AMIClient.class, AMIAsyncClient.class)//
|
||||
.put(ElasticIPAddressClient.class, ElasticIPAddressAsyncClient.class)//
|
||||
.put(InstanceClient.class, InstanceAsyncClient.class)//
|
||||
.put(KeyPairClient.class, KeyPairAsyncClient.class)//
|
||||
.put(SecurityGroupClient.class, SecurityGroupAsyncClient.class)//
|
||||
.put(MonitoringClient.class, MonitoringAsyncClient.class)//
|
||||
.put(AvailabilityZoneAndRegionClient.class,
|
||||
AvailabilityZoneAndRegionAsyncClient.class)//
|
||||
.put(ElasticBlockStoreClient.class, ElasticBlockStoreAsyncClient.class)//
|
||||
.put(ElasticLoadBalancerClient.class,
|
||||
ElasticLoadBalancerAsyncClient.class)//
|
||||
.build();
|
||||
|
||||
public EC2RestClientModule() {
|
||||
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
|
||||
@Singleton
|
||||
@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);
|
||||
}
|
||||
|
||||
|
@ -137,21 +111,29 @@ public class EC2RestClientModule extends RestClientModule<EC2Client, EC2AsyncCli
|
|||
@Singleton
|
||||
@ELB
|
||||
Map<String, URI> provideELBRegions() {
|
||||
return ImmutableMap.<String, URI> of(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,
|
||||
URI.create("https://elasticloadbalancing.eu-west-1.amazonaws.com"),
|
||||
Region.AP_SOUTHEAST_1, URI
|
||||
return ImmutableMap
|
||||
.<String, URI> of(
|
||||
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,
|
||||
URI
|
||||
.create("https://elasticloadbalancing.eu-west-1.amazonaws.com"),
|
||||
Region.AP_SOUTHEAST_1,
|
||||
URI
|
||||
.create("https://elasticloadbalancing.ap-southeast-1.amazonaws.com"));
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
@EC2
|
||||
String provideCurrentRegion(@EC2 Map<String, URI> regionMap, @EC2 URI currentUri) {
|
||||
ImmutableBiMap<URI, String> map = ImmutableBiMap.<String, URI> builder().putAll(regionMap)
|
||||
.build().inverse();
|
||||
String provideCurrentRegion(@EC2 Map<String, URI> regionMap,
|
||||
@EC2 URI currentUri) {
|
||||
ImmutableBiMap<URI, String> map = ImmutableBiMap.<String, URI> builder()
|
||||
.putAll(regionMap).build().inverse();
|
||||
String region = map.get(currentUri);
|
||||
assert region != null : currentUri + " not in " + map;
|
||||
return region;
|
||||
|
@ -181,11 +163,12 @@ public class EC2RestClientModule extends RestClientModule<EC2Client, EC2AsyncCli
|
|||
@Provides
|
||||
@Singleton
|
||||
Map<String, String> provideAvailabilityZoneToRegions(EC2Client client,
|
||||
@EC2 Map<String, URI> regions) {
|
||||
@EC2 Map<String, URI> regions) {
|
||||
Map<String, String> map = Maps.newHashMap();
|
||||
for (String region : regions.keySet()) {
|
||||
for (AvailabilityZoneInfo zoneInfo : client.getAvailabilityZoneAndRegionServices()
|
||||
.describeAvailabilityZonesInRegion(region)) {
|
||||
for (AvailabilityZoneInfo zoneInfo : client
|
||||
.getAvailabilityZoneAndRegionServices()
|
||||
.describeAvailabilityZonesInRegion(region)) {
|
||||
map.put(zoneInfo.getZone(), region);
|
||||
}
|
||||
}
|
||||
|
@ -195,9 +178,9 @@ public class EC2RestClientModule extends RestClientModule<EC2Client, EC2AsyncCli
|
|||
@Provides
|
||||
@TimeStamp
|
||||
protected String provideTimeStamp(final DateService dateService,
|
||||
@Named(EC2Constants.PROPERTY_AWS_EXPIREINTERVAL) final int expiration) {
|
||||
@Named(EC2Constants.PROPERTY_AWS_EXPIREINTERVAL) final int expiration) {
|
||||
return dateService.iso8601DateFormat(new Date(System.currentTimeMillis()
|
||||
+ (expiration * 1000)));
|
||||
+ (expiration * 1000)));
|
||||
}
|
||||
|
||||
@Provides
|
||||
|
@ -209,25 +192,26 @@ public class EC2RestClientModule extends RestClientModule<EC2Client, EC2AsyncCli
|
|||
@Provides
|
||||
@Singleton
|
||||
@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);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void bindErrorHandlers() {
|
||||
bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(
|
||||
ParseAWSErrorFromXmlContent.class);
|
||||
ParseAWSErrorFromXmlContent.class);
|
||||
bind(HttpErrorHandler.class).annotatedWith(ClientError.class).to(
|
||||
ParseAWSErrorFromXmlContent.class);
|
||||
ParseAWSErrorFromXmlContent.class);
|
||||
bind(HttpErrorHandler.class).annotatedWith(ServerError.class).to(
|
||||
ParseAWSErrorFromXmlContent.class);
|
||||
ParseAWSErrorFromXmlContent.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void bindRetryHandlers() {
|
||||
bind(HttpRetryHandler.class).annotatedWith(Redirection.class).to(
|
||||
AWSRedirectionRetryHandler.class);
|
||||
AWSRedirectionRetryHandler.class);
|
||||
bind(HttpRetryHandler.class).annotatedWith(ClientError.class).to(
|
||||
AWSClientErrorRetryHandler.class);
|
||||
AWSClientErrorRetryHandler.class);
|
||||
}
|
||||
}
|
|
@ -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.inject.Singleton;
|
||||
|
||||
import org.jclouds.aws.AWSResponseException;
|
||||
import org.jclouds.aws.ec2.EC2Client;
|
||||
import org.jclouds.aws.ec2.domain.InstanceState;
|
||||
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;
|
||||
|
@ -54,18 +54,18 @@ public class InstanceStateRunning implements Predicate<RunningInstance> {
|
|||
logger.trace("looking for state on instance %s", instance);
|
||||
try {
|
||||
instance = refresh(instance);
|
||||
logger.trace("%s: looking for instance state %s: currently: %s", instance.getId(),
|
||||
InstanceState.RUNNING, instance.getInstanceState());
|
||||
logger.trace("%s: looking for instance state %s: currently: %s",
|
||||
instance.getId(), InstanceState.RUNNING, instance
|
||||
.getInstanceState());
|
||||
return instance.getInstanceState() == InstanceState.RUNNING;
|
||||
} catch (AWSResponseException e) {
|
||||
if (e.getError().getCode().equals("InvalidInstanceID.NotFound"))
|
||||
return false;
|
||||
throw e;
|
||||
} catch (ResourceNotFoundException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private RunningInstance refresh(RunningInstance instance) {
|
||||
return Iterables.getOnlyElement(Iterables.getOnlyElement(client.getInstanceServices()
|
||||
.describeInstancesInRegion(instance.getRegion(), instance.getId())));
|
||||
return Iterables.getOnlyElement(Iterables.getOnlyElement(client
|
||||
.getInstanceServices().describeInstancesInRegion(
|
||||
instance.getRegion(), instance.getId())));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,29 +63,31 @@ public class ParseAWSErrorFromXmlContent implements HttpErrorHandler {
|
|||
Exception exception = new HttpResponseException(command, response);
|
||||
try {
|
||||
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()) {
|
||||
case 400:
|
||||
if (error.getCode().equals("InvalidAMIID.NotFound")
|
||||
|| error.getCode().equals("InvalidAMIID.Malformed"))
|
||||
exception = new ResourceNotFoundException(error.getMessage(), exception);
|
||||
break;
|
||||
case 401:
|
||||
exception = new AuthorizationException(command.getRequest(), error != null ? error
|
||||
.getMessage() : response.getStatusLine());
|
||||
break;
|
||||
case 404:
|
||||
if (!command.getRequest().getMethod().equals("DELETE")) {
|
||||
String message = error != null ? error.getMessage() : String.format("%s -> %s",
|
||||
command.getRequest().getRequestLine(), response.getStatusLine());
|
||||
String container = command.getRequest().getEndpoint().getHost();
|
||||
String key = command.getRequest().getEndpoint().getPath();
|
||||
if (key == null || key.equals("/"))
|
||||
exception = new ContainerNotFoundException(container, message);
|
||||
else
|
||||
exception = new KeyNotFoundException(container, key, message);
|
||||
}
|
||||
break;
|
||||
case 400:
|
||||
if (error.getCode().endsWith(".NotFound"))
|
||||
exception = new ResourceNotFoundException(error.getMessage(),
|
||||
exception);
|
||||
break;
|
||||
case 401:
|
||||
exception = new AuthorizationException(command.getRequest(),
|
||||
error != null ? error.getMessage() : response.getStatusLine());
|
||||
break;
|
||||
case 404:
|
||||
if (!command.getRequest().getMethod().equals("DELETE")) {
|
||||
String message = error != null ? error.getMessage() : String
|
||||
.format("%s -> %s", command.getRequest().getRequestLine(),
|
||||
response.getStatusLine());
|
||||
String container = command.getRequest().getEndpoint().getHost();
|
||||
String key = command.getRequest().getEndpoint().getPath();
|
||||
if (key == null || key.equals("/"))
|
||||
exception = new ContainerNotFoundException(container, message);
|
||||
else
|
||||
exception = new KeyNotFoundException(container, key, message);
|
||||
}
|
||||
break;
|
||||
}
|
||||
} finally {
|
||||
Closeables.closeQuietly(response.getContent());
|
||||
|
@ -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) {
|
||||
try {
|
||||
String content = Utils.toStringAndClose(response.getContent());
|
||||
if (content != null && content.indexOf('<') >= 0)
|
||||
return utils.parseAWSErrorFromContent(command, response, content);
|
||||
return utils
|
||||
.parseAWSErrorFromContent(command, response, content);
|
||||
} catch (IOException e) {
|
||||
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
|
||||
* <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/>
|
||||
* Generally disabled, as it incurs higher fees.
|
||||
*
|
||||
|
@ -89,41 +90,50 @@ public class CloudApplicationArchitecturesEC2ClientLiveTest {
|
|||
private RetryablePredicate<RunningInstance> runningTester;
|
||||
|
||||
@BeforeGroups(groups = { "live" })
|
||||
public void setupClient() throws InterruptedException, ExecutionException, TimeoutException {
|
||||
String user = checkNotNull(System.getProperty("jclouds.test.user"), "jclouds.test.user");
|
||||
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();
|
||||
public void setupClient() throws InterruptedException, ExecutionException,
|
||||
TimeoutException {
|
||||
String user = checkNotNull(System.getProperty("jclouds.test.user"),
|
||||
"jclouds.test.user");
|
||||
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();
|
||||
client = injector.getInstance(EC2Client.class);
|
||||
sshFactory = injector.getInstance(SshClient.Factory.class);
|
||||
runningTester = new RetryablePredicate<RunningInstance>(new InstanceStateRunning(client),
|
||||
180, 5, TimeUnit.SECONDS);
|
||||
hasIpTester = new RetryablePredicate<RunningInstance>(new InstanceHasIpAddress(client), 180, 5, TimeUnit.SECONDS);
|
||||
runningTester = new RetryablePredicate<RunningInstance>(
|
||||
new InstanceStateRunning(client), 180, 5, TimeUnit.SECONDS);
|
||||
hasIpTester = new RetryablePredicate<RunningInstance>(
|
||||
new InstanceHasIpAddress(client), 180, 5, TimeUnit.SECONDS);
|
||||
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)
|
||||
void testCreateSecurityGroupIngressCidr() throws InterruptedException, ExecutionException,
|
||||
TimeoutException {
|
||||
void testCreateSecurityGroupIngressCidr() throws InterruptedException,
|
||||
ExecutionException, TimeoutException {
|
||||
securityGroupName = instancePrefix + "ingress";
|
||||
|
||||
try {
|
||||
client.getSecurityGroupServices().deleteSecurityGroupInRegion(null, securityGroupName);
|
||||
client.getSecurityGroupServices().deleteSecurityGroupInRegion(null,
|
||||
securityGroupName);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
|
||||
client.getSecurityGroupServices().createSecurityGroupInRegion(null, securityGroupName,
|
||||
securityGroupName);
|
||||
client.getSecurityGroupServices().createSecurityGroupInRegion(null,
|
||||
securityGroupName, securityGroupName);
|
||||
for (int port : new int[] { 80, 443, 22 }) {
|
||||
client.getSecurityGroupServices().authorizeSecurityGroupIngressInRegion(null,
|
||||
securityGroupName, IpProtocol.TCP, port, port, "0.0.0.0/0");
|
||||
client.getSecurityGroupServices()
|
||||
.authorizeSecurityGroupIngressInRegion(null, securityGroupName,
|
||||
IpProtocol.TCP, port, port, "0.0.0.0/0");
|
||||
}
|
||||
}
|
||||
|
||||
@Test(enabled = false)
|
||||
void testCreateKeyPair() throws InterruptedException, ExecutionException, TimeoutException {
|
||||
void testCreateKeyPair() throws InterruptedException, ExecutionException,
|
||||
TimeoutException {
|
||||
String keyName = instancePrefix + "1";
|
||||
try {
|
||||
client.getKeyPairServices().deleteKeyPairInRegion(null, keyName);
|
||||
|
@ -132,7 +142,8 @@ public class CloudApplicationArchitecturesEC2ClientLiveTest {
|
|||
}
|
||||
client.getKeyPairServices().deleteKeyPairInRegion(null, keyName);
|
||||
|
||||
keyPair = client.getKeyPairServices().createKeyPairInRegion(null, keyName);
|
||||
keyPair = client.getKeyPairServices()
|
||||
.createKeyPairInRegion(null, keyName);
|
||||
assertNotNull(keyPair);
|
||||
assertNotNull(keyPair.getKeyMaterial());
|
||||
assertNotNull(keyPair.getKeyFingerprint());
|
||||
|
@ -140,32 +151,40 @@ public class CloudApplicationArchitecturesEC2ClientLiveTest {
|
|||
}
|
||||
|
||||
@Test(enabled = false, dependsOnMethods = { "testCreateKeyPair",
|
||||
"testCreateSecurityGroupIngressCidr" })
|
||||
"testCreateSecurityGroupIngressCidr" })
|
||||
public void testCreateRunningInstance() throws Exception {
|
||||
String script = new ScriptBuilder() // lamp install script
|
||||
.addStatement(exec("runurl run.alestic.com/apt/upgrade"))//
|
||||
.addStatement(exec("runurl run.alestic.com/install/lamp"))//
|
||||
.build(OsFamily.UNIX);
|
||||
.addStatement(exec("runurl run.alestic.com/apt/upgrade"))//
|
||||
.addStatement(exec("runurl run.alestic.com/install/lamp"))//
|
||||
.build(OsFamily.UNIX);
|
||||
|
||||
RunningInstance instance = null;
|
||||
while (instance == null) {
|
||||
try {
|
||||
|
||||
System.out.printf("%d: running instance%n", System.currentTimeMillis());
|
||||
Reservation reservation = client.getInstanceServices().runInstancesInRegion(null, null, // allow
|
||||
// ec2
|
||||
// to
|
||||
// chose
|
||||
// an
|
||||
// availability
|
||||
// zone
|
||||
"ami-ccf615a5", // alestic ami allows auto-invoke of user data scripts
|
||||
1, // minimum instances
|
||||
1, // maximum instances
|
||||
asType(InstanceType.M1_SMALL) // smallest instance size
|
||||
.withKeyName(keyPair.getKeyName()) // key I created above
|
||||
.withSecurityGroup(securityGroupName) // group I created above
|
||||
.withUserData(script.getBytes())); // script to run as root
|
||||
System.out.printf("%d: running instance%n", System
|
||||
.currentTimeMillis());
|
||||
Reservation reservation = client.getInstanceServices()
|
||||
.runInstancesInRegion(null, null, // allow
|
||||
// ec2
|
||||
// to
|
||||
// chose
|
||||
// an
|
||||
// availability
|
||||
// zone
|
||||
"ami-ccf615a5", // alestic ami allows auto-invoke of
|
||||
// user data scripts
|
||||
1, // minimum instances
|
||||
1, // maximum instances
|
||||
asType(InstanceType.M1_SMALL) // smallest instance size
|
||||
.withKeyName(keyPair.getKeyName()) // key I
|
||||
// created
|
||||
// above
|
||||
.withSecurityGroup(securityGroupName) // group I
|
||||
// created
|
||||
// above
|
||||
.withUserData(script.getBytes())); // script to
|
||||
// run as root
|
||||
|
||||
instance = Iterables.getOnlyElement(reservation);
|
||||
|
||||
|
@ -183,45 +202,51 @@ public class CloudApplicationArchitecturesEC2ClientLiveTest {
|
|||
verifyInstanceProperties(script);
|
||||
tryToChangeStuff();
|
||||
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) {
|
||||
assertEquals(script, client.getInstanceServices().getUserDataForInstanceInRegion(null,
|
||||
instanceId));
|
||||
assertEquals(script, client.getInstanceServices()
|
||||
.getUserDataForInstanceInRegion(null, instanceId));
|
||||
|
||||
assertEquals(null, client.getInstanceServices().getRootDeviceNameForInstanceInRegion(null,
|
||||
instanceId));
|
||||
assertEquals(null, client.getInstanceServices()
|
||||
.getRootDeviceNameForInstanceInRegion(null, instanceId));
|
||||
|
||||
assert client.getInstanceServices().getRamdiskForInstanceInRegion(null, instanceId)
|
||||
.startsWith("ari-");
|
||||
assert client.getInstanceServices().getRamdiskForInstanceInRegion(null,
|
||||
instanceId).startsWith("ari-");
|
||||
|
||||
assertEquals(false, client.getInstanceServices().isApiTerminationDisabledForInstanceInRegion(
|
||||
null, instanceId));
|
||||
assertEquals(false, client.getInstanceServices()
|
||||
.isApiTerminationDisabledForInstanceInRegion(null, instanceId));
|
||||
|
||||
assert client.getInstanceServices().getKernelForInstanceInRegion(null, instanceId)
|
||||
.startsWith("aki-");
|
||||
assert client.getInstanceServices().getKernelForInstanceInRegion(null,
|
||||
instanceId).startsWith("aki-");
|
||||
|
||||
assertEquals(InstanceType.M1_SMALL, client.getInstanceServices()
|
||||
.getInstanceTypeForInstanceInRegion(null, instanceId));
|
||||
.getInstanceTypeForInstanceInRegion(null, instanceId));
|
||||
|
||||
assertEquals(InstanceInitiatedShutdownBehavior.TERMINATE, client.getInstanceServices()
|
||||
.getInstanceInitiatedShutdownBehaviorForInstanceInRegion(null, instanceId));
|
||||
assertEquals(InstanceInitiatedShutdownBehavior.TERMINATE, client
|
||||
.getInstanceServices()
|
||||
.getInstanceInitiatedShutdownBehaviorForInstanceInRegion(null,
|
||||
instanceId));
|
||||
|
||||
assertEquals(ImmutableMap.<String, EbsBlockDevice> of(), client.getInstanceServices()
|
||||
.getBlockDeviceMappingForInstanceInRegion(null, instanceId));
|
||||
assertEquals(ImmutableMap.<String, EbsBlockDevice> of(), client
|
||||
.getInstanceServices().getBlockDeviceMappingForInstanceInRegion(
|
||||
null, instanceId));
|
||||
}
|
||||
|
||||
private void setApiTerminationDisabledForInstanceInRegion() {
|
||||
client.getInstanceServices().setApiTerminationDisabledForInstanceInRegion(null, instanceId,
|
||||
true);
|
||||
assertEquals(true, client.getInstanceServices().isApiTerminationDisabledForInstanceInRegion(
|
||||
null, instanceId));
|
||||
client.getInstanceServices().setApiTerminationDisabledForInstanceInRegion(null, instanceId,
|
||||
false);
|
||||
assertEquals(false, client.getInstanceServices().isApiTerminationDisabledForInstanceInRegion(
|
||||
null, instanceId));
|
||||
client.getInstanceServices()
|
||||
.setApiTerminationDisabledForInstanceInRegion(null, instanceId,
|
||||
true);
|
||||
assertEquals(true, client.getInstanceServices()
|
||||
.isApiTerminationDisabledForInstanceInRegion(null, instanceId));
|
||||
client.getInstanceServices()
|
||||
.setApiTerminationDisabledForInstanceInRegion(null, instanceId,
|
||||
false);
|
||||
assertEquals(false, client.getInstanceServices()
|
||||
.isApiTerminationDisabledForInstanceInRegion(null, instanceId));
|
||||
}
|
||||
|
||||
private void tryToChangeStuff() {
|
||||
|
@ -236,8 +261,8 @@ public class CloudApplicationArchitecturesEC2ClientLiveTest {
|
|||
|
||||
private void setUserDataForInstanceInRegion() {
|
||||
try {
|
||||
client.getInstanceServices().setUserDataForInstanceInRegion(null, instanceId,
|
||||
"test".getBytes());
|
||||
client.getInstanceServices().setUserDataForInstanceInRegion(null,
|
||||
instanceId, "test".getBytes());
|
||||
assert false : "shouldn't be allowed, as instance needs to be stopped";
|
||||
} catch (AWSResponseException e) {
|
||||
assertEquals("IncorrectInstanceState", e.getError().getCode());
|
||||
|
@ -246,9 +271,10 @@ public class CloudApplicationArchitecturesEC2ClientLiveTest {
|
|||
|
||||
private void setRamdiskForInstanceInRegion() {
|
||||
try {
|
||||
String ramdisk = client.getInstanceServices().getRamdiskForInstanceInRegion(null,
|
||||
instanceId);
|
||||
client.getInstanceServices().setRamdiskForInstanceInRegion(null, instanceId, ramdisk);
|
||||
String ramdisk = client.getInstanceServices()
|
||||
.getRamdiskForInstanceInRegion(null, instanceId);
|
||||
client.getInstanceServices().setRamdiskForInstanceInRegion(null,
|
||||
instanceId, ramdisk);
|
||||
assert false : "shouldn't be allowed, as instance needs to be stopped";
|
||||
} catch (AWSResponseException e) {
|
||||
assertEquals("IncorrectInstanceState", e.getError().getCode());
|
||||
|
@ -257,9 +283,10 @@ public class CloudApplicationArchitecturesEC2ClientLiveTest {
|
|||
|
||||
private void setKernelForInstanceInRegion() {
|
||||
try {
|
||||
String oldKernel = client.getInstanceServices().getKernelForInstanceInRegion(null,
|
||||
instanceId);
|
||||
client.getInstanceServices().setKernelForInstanceInRegion(null, instanceId, oldKernel);
|
||||
String oldKernel = client.getInstanceServices()
|
||||
.getKernelForInstanceInRegion(null, instanceId);
|
||||
client.getInstanceServices().setKernelForInstanceInRegion(null,
|
||||
instanceId, oldKernel);
|
||||
assert false : "shouldn't be allowed, as instance needs to be stopped";
|
||||
} catch (AWSResponseException e) {
|
||||
assertEquals("IncorrectInstanceState", e.getError().getCode());
|
||||
|
@ -268,8 +295,8 @@ public class CloudApplicationArchitecturesEC2ClientLiveTest {
|
|||
|
||||
private void setInstanceTypeForInstanceInRegion() {
|
||||
try {
|
||||
client.getInstanceServices().setInstanceTypeForInstanceInRegion(null, instanceId,
|
||||
InstanceType.C1_MEDIUM);
|
||||
client.getInstanceServices().setInstanceTypeForInstanceInRegion(null,
|
||||
instanceId, InstanceType.C1_MEDIUM);
|
||||
assert false : "shouldn't be allowed, as instance needs to be stopped";
|
||||
} catch (AWSResponseException e) {
|
||||
assertEquals("IncorrectInstanceState", e.getError().getCode());
|
||||
|
@ -279,8 +306,8 @@ public class CloudApplicationArchitecturesEC2ClientLiveTest {
|
|||
private void setBlockDeviceMappingForInstanceInRegion() {
|
||||
BlockDeviceMapping blockDeviceMapping = new BlockDeviceMapping();
|
||||
try {
|
||||
client.getInstanceServices().setBlockDeviceMappingForInstanceInRegion(null, instanceId,
|
||||
blockDeviceMapping);
|
||||
client.getInstanceServices().setBlockDeviceMappingForInstanceInRegion(
|
||||
null, instanceId, blockDeviceMapping);
|
||||
assert false : "shouldn't be allowed, as instance needs to be ebs based-ami";
|
||||
} catch (AWSResponseException e) {
|
||||
assertEquals("InvalidParameterCombination", e.getError().getCode());
|
||||
|
@ -289,8 +316,9 @@ public class CloudApplicationArchitecturesEC2ClientLiveTest {
|
|||
|
||||
private void setInstanceInitiatedShutdownBehaviorForInstanceInRegion() {
|
||||
try {
|
||||
client.getInstanceServices().setInstanceInitiatedShutdownBehaviorForInstanceInRegion(null,
|
||||
instanceId, InstanceInitiatedShutdownBehavior.STOP);
|
||||
client.getInstanceServices()
|
||||
.setInstanceInitiatedShutdownBehaviorForInstanceInRegion(null,
|
||||
instanceId, InstanceInitiatedShutdownBehavior.STOP);
|
||||
assert false : "shouldn't be allowed, as instance needs to be ebs based-ami";
|
||||
} catch (AWSResponseException e) {
|
||||
assertEquals("UnsupportedInstanceAttribute", e.getError().getCode());
|
||||
|
@ -298,19 +326,22 @@ public class CloudApplicationArchitecturesEC2ClientLiveTest {
|
|||
}
|
||||
|
||||
@Test(enabled = false, dependsOnMethods = "testCreateRunningInstance")
|
||||
void testReboot() throws InterruptedException, ExecutionException, TimeoutException, IOException {
|
||||
void testReboot() throws InterruptedException, ExecutionException,
|
||||
TimeoutException, IOException {
|
||||
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);
|
||||
Thread.sleep(1000);
|
||||
instance = getInstance(instanceId);
|
||||
blockUntilWeCanSshIntoInstance(instance);
|
||||
SshClient ssh = sshFactory.create(new IPSocket(instance.getIpAddress(), 22), "root", keyPair
|
||||
.getKeyMaterial().getBytes());
|
||||
SshClient ssh = sshFactory.create(new IPSocket(instance.getIpAddress(),
|
||||
22), "root", keyPair.getKeyMaterial().getBytes());
|
||||
try {
|
||||
ssh.connect();
|
||||
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 {
|
||||
if (ssh != null)
|
||||
ssh.disconnect();
|
||||
|
@ -318,86 +349,95 @@ public class CloudApplicationArchitecturesEC2ClientLiveTest {
|
|||
}
|
||||
|
||||
@Test(enabled = false, dependsOnMethods = "testReboot")
|
||||
void testElasticIpAddress() throws InterruptedException, ExecutionException, TimeoutException,
|
||||
IOException {
|
||||
address = client.getElasticIPAddressServices().allocateAddressInRegion(null);
|
||||
void testElasticIpAddress() throws InterruptedException, ExecutionException,
|
||||
TimeoutException, IOException {
|
||||
address = client.getElasticIPAddressServices().allocateAddressInRegion(
|
||||
null);
|
||||
assertNotNull(address);
|
||||
|
||||
PublicIpInstanceIdPair compare = Iterables.getLast(client.getElasticIPAddressServices()
|
||||
.describeAddressesInRegion(null, address));
|
||||
PublicIpInstanceIdPair compare = Iterables.getLast(client
|
||||
.getElasticIPAddressServices().describeAddressesInRegion(null,
|
||||
address));
|
||||
|
||||
assertEquals(compare.getPublicIp(), address);
|
||||
assert compare.getInstanceId() == null;
|
||||
|
||||
client.getElasticIPAddressServices().associateAddressInRegion(null, address, instanceId);
|
||||
client.getElasticIPAddressServices().associateAddressInRegion(null,
|
||||
address, instanceId);
|
||||
|
||||
compare = Iterables.getLast(client.getElasticIPAddressServices().describeAddressesInRegion(
|
||||
null, address));
|
||||
compare = Iterables.getLast(client.getElasticIPAddressServices()
|
||||
.describeAddressesInRegion(null, address));
|
||||
|
||||
assertEquals(compare.getPublicIp(), address);
|
||||
assertEquals(compare.getInstanceId(), instanceId);
|
||||
|
||||
Reservation reservation = Iterables.getOnlyElement(client.getInstanceServices()
|
||||
.describeInstancesInRegion(null, instanceId));
|
||||
Reservation reservation = Iterables.getOnlyElement(client
|
||||
.getInstanceServices().describeInstancesInRegion(null, instanceId));
|
||||
|
||||
assertNotNull(Iterables.getOnlyElement(reservation).getIpAddress());
|
||||
assertFalse(Iterables.getOnlyElement(reservation).getIpAddress().equals(address));
|
||||
assertFalse(Iterables.getOnlyElement(reservation).getIpAddress().equals(
|
||||
address));
|
||||
|
||||
doCheckKey(address);
|
||||
|
||||
client.getElasticIPAddressServices().disassociateAddressInRegion(null, address);
|
||||
client.getElasticIPAddressServices().disassociateAddressInRegion(null,
|
||||
address);
|
||||
|
||||
compare = Iterables.getLast(client.getElasticIPAddressServices().describeAddressesInRegion(
|
||||
null, address));
|
||||
compare = Iterables.getLast(client.getElasticIPAddressServices()
|
||||
.describeAddressesInRegion(null, address));
|
||||
|
||||
assertEquals(compare.getPublicIp(), address);
|
||||
assert compare.getInstanceId() == null;
|
||||
|
||||
reservation = Iterables.getOnlyElement(client.getInstanceServices()
|
||||
.describeInstancesInRegion(null, instanceId));
|
||||
// assert reservation.getRunningInstances().last().getIpAddress() == null; TODO
|
||||
.describeInstancesInRegion(null, instanceId));
|
||||
// assert reservation.getRunningInstances().last().getIpAddress() == null;
|
||||
// TODO
|
||||
}
|
||||
|
||||
private RunningInstance blockUntilWeCanSshIntoInstance(RunningInstance instance)
|
||||
throws UnknownHostException {
|
||||
System.out.printf("%d: %s awaiting instance to run %n", System.currentTimeMillis(), instance
|
||||
.getId());
|
||||
private RunningInstance blockUntilWeCanSshIntoInstance(
|
||||
RunningInstance instance) throws UnknownHostException {
|
||||
System.out.printf("%d: %s awaiting instance to run %n", System
|
||||
.currentTimeMillis(), instance.getId());
|
||||
assert runningTester.apply(instance);
|
||||
|
||||
instance = getInstance(instance.getId());
|
||||
|
||||
System.out.printf("%d: %s awaiting instance to have ip assigned %n", System
|
||||
.currentTimeMillis(), instance.getId());
|
||||
System.out.printf("%d: %s awaiting instance to have ip assigned %n",
|
||||
System.currentTimeMillis(), instance.getId());
|
||||
assert hasIpTester.apply(instance);
|
||||
|
||||
System.out.printf("%d: %s awaiting ssh service to start%n", System.currentTimeMillis(),
|
||||
instance.getIpAddress());
|
||||
System.out.printf("%d: %s awaiting ssh service to start%n", System
|
||||
.currentTimeMillis(), instance.getIpAddress());
|
||||
assert socketTester.apply(new IPSocket(instance.getIpAddress(), 22));
|
||||
|
||||
System.out.printf("%d: %s ssh service started%n", System.currentTimeMillis(), instance
|
||||
.getDnsName());
|
||||
System.out.printf("%d: %s ssh service started%n", System
|
||||
.currentTimeMillis(), instance.getDnsName());
|
||||
sshPing(instance);
|
||||
System.out.printf("%d: %s ssh connection made%n", System.currentTimeMillis(), instance
|
||||
.getId());
|
||||
System.out.printf("%d: %s ssh connection made%n", System
|
||||
.currentTimeMillis(), instance.getId());
|
||||
|
||||
System.out.printf("%d: %s awaiting http service to start%n", System.currentTimeMillis(),
|
||||
instance.getIpAddress());
|
||||
System.out.printf("%d: %s awaiting http service to start%n", System
|
||||
.currentTimeMillis(), instance.getIpAddress());
|
||||
assert socketTester.apply(new IPSocket(instance.getIpAddress(), 80));
|
||||
System.out.printf("%d: %s http service started%n", System.currentTimeMillis(), instance
|
||||
.getDnsName());
|
||||
System.out.printf("%d: %s http service started%n", System
|
||||
.currentTimeMillis(), instance.getDnsName());
|
||||
return instance;
|
||||
}
|
||||
|
||||
private RunningInstance getInstance(String instanceId) {
|
||||
// search my account for the instance I just created
|
||||
Set<Reservation> reservations = client.getInstanceServices().describeInstancesInRegion(null,
|
||||
instanceId); // last parameter (ids) narrows the search
|
||||
Set<Reservation> reservations = client.getInstanceServices()
|
||||
.describeInstancesInRegion(null, instanceId); // last parameter
|
||||
// (ids) narrows the
|
||||
// search
|
||||
|
||||
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
|
||||
*/
|
||||
|
@ -413,13 +453,14 @@ public class CloudApplicationArchitecturesEC2ClientLiveTest {
|
|||
}
|
||||
}
|
||||
|
||||
private void doCheckKey(RunningInstance newDetails) throws UnknownHostException {
|
||||
private void doCheckKey(RunningInstance newDetails)
|
||||
throws UnknownHostException {
|
||||
doCheckKey(newDetails.getIpAddress());
|
||||
}
|
||||
|
||||
private void doCheckKey(String address) {
|
||||
SshClient ssh = sshFactory.create(new IPSocket(address, 22), "root", keyPair.getKeyMaterial()
|
||||
.getBytes());
|
||||
SshClient ssh = sshFactory.create(new IPSocket(address, 22), "root",
|
||||
keyPair.getKeyMaterial().getBytes());
|
||||
try {
|
||||
ssh.connect();
|
||||
ExecResponse hello = ssh.exec("echo hello");
|
||||
|
@ -431,15 +472,20 @@ public class CloudApplicationArchitecturesEC2ClientLiveTest {
|
|||
}
|
||||
|
||||
@AfterTest
|
||||
void cleanup() throws InterruptedException, ExecutionException, TimeoutException {
|
||||
void cleanup() throws InterruptedException, ExecutionException,
|
||||
TimeoutException {
|
||||
if (address != null)
|
||||
client.getElasticIPAddressServices().releaseAddressInRegion(null, address);
|
||||
client.getElasticIPAddressServices().releaseAddressInRegion(null,
|
||||
address);
|
||||
if (instanceId != null)
|
||||
client.getInstanceServices().terminateInstancesInRegion(null, instanceId);
|
||||
client.getInstanceServices().terminateInstancesInRegion(null,
|
||||
instanceId);
|
||||
if (keyPair != null)
|
||||
client.getKeyPairServices().deleteKeyPairInRegion(null, keyPair.getKeyName());
|
||||
client.getKeyPairServices().deleteKeyPairInRegion(null,
|
||||
keyPair.getKeyName());
|
||||
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;
|
||||
|
||||
/**
|
||||
* Adapted from the following sources: {@link http://gist.github.com/249915}, {@link http
|
||||
* ://www.capsunlock.net/2009/12/create-ebs-boot-ami.html}
|
||||
* Adapted from the following sources: {@link http://gist.github.com/249915},
|
||||
* {@link http ://www.capsunlock.net/2009/12/create-ebs-boot-ami.html}
|
||||
* <p/>
|
||||
*
|
||||
* 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
|
||||
private static final int VOLUME_SIZE = 2;
|
||||
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 EC2Client client;
|
||||
|
@ -117,58 +119,70 @@ public class EBSBootEC2ClientLiveTest {
|
|||
|
||||
@BeforeGroups(groups = { "live" })
|
||||
public void setupClient() {
|
||||
String user = checkNotNull(System.getProperty("jclouds.test.user"), "jclouds.test.user");
|
||||
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();
|
||||
String user = checkNotNull(System.getProperty("jclouds.test.user"),
|
||||
"jclouds.test.user");
|
||||
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();
|
||||
client = injector.getInstance(EC2Client.class);
|
||||
sshFactory = injector.getInstance(SshClient.Factory.class);
|
||||
SocketOpen socketOpen = injector.getInstance(SocketOpen.class);
|
||||
socketTester = new RetryablePredicate<IPSocket>(socketOpen, 120, 1, TimeUnit.SECONDS);
|
||||
socketTester = new RetryablePredicate<IPSocket>(socketOpen, 120, 1,
|
||||
TimeUnit.SECONDS);
|
||||
|
||||
VolumeAvailable volumeAvailable = injector.getInstance(VolumeAvailable.class);
|
||||
volumeTester = new RetryablePredicate<Volume>(volumeAvailable, 60, 1, 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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
InstanceStateStopped instanceStateStopped = injector
|
||||
.getInstance(InstanceStateStopped.class);
|
||||
stoppedTester = new RetryablePredicate<RunningInstance>(
|
||||
instanceStateStopped, 60, 1, TimeUnit.SECONDS);
|
||||
|
||||
InstanceStateTerminated instanceStateTerminated = injector
|
||||
.getInstance(InstanceStateTerminated.class);
|
||||
terminatedTester = new RetryablePredicate<RunningInstance>(instanceStateTerminated, 60, 1,
|
||||
TimeUnit.SECONDS);
|
||||
.getInstance(InstanceStateTerminated.class);
|
||||
terminatedTester = new RetryablePredicate<RunningInstance>(
|
||||
instanceStateTerminated, 60, 1, TimeUnit.SECONDS);
|
||||
|
||||
injector.injectMembers(socketOpen); // add logger
|
||||
}
|
||||
|
||||
@Test(enabled = false)
|
||||
void testCreateSecurityGroupIngressCidr() throws InterruptedException, ExecutionException,
|
||||
TimeoutException {
|
||||
void testCreateSecurityGroupIngressCidr() throws InterruptedException,
|
||||
ExecutionException, TimeoutException {
|
||||
securityGroupName = INSTANCE_PREFIX + "ingress";
|
||||
|
||||
try {
|
||||
client.getSecurityGroupServices().deleteSecurityGroupInRegion(null, securityGroupName);
|
||||
client.getSecurityGroupServices().deleteSecurityGroupInRegion(null,
|
||||
securityGroupName);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
|
||||
client.getSecurityGroupServices().createSecurityGroupInRegion(null, securityGroupName,
|
||||
securityGroupName);
|
||||
client.getSecurityGroupServices().authorizeSecurityGroupIngressInRegion(null,
|
||||
securityGroupName, IpProtocol.TCP, 80, 80, "0.0.0.0/0");
|
||||
client.getSecurityGroupServices().authorizeSecurityGroupIngressInRegion(null,
|
||||
securityGroupName, IpProtocol.TCP, 443, 443, "0.0.0.0/0");
|
||||
client.getSecurityGroupServices().authorizeSecurityGroupIngressInRegion(null,
|
||||
securityGroupName, IpProtocol.TCP, 22, 22, "0.0.0.0/0");
|
||||
client.getSecurityGroupServices().createSecurityGroupInRegion(null,
|
||||
securityGroupName, securityGroupName);
|
||||
client.getSecurityGroupServices().authorizeSecurityGroupIngressInRegion(
|
||||
null, securityGroupName, IpProtocol.TCP, 80, 80, "0.0.0.0/0");
|
||||
client.getSecurityGroupServices().authorizeSecurityGroupIngressInRegion(
|
||||
null, securityGroupName, IpProtocol.TCP, 443, 443, "0.0.0.0/0");
|
||||
client.getSecurityGroupServices().authorizeSecurityGroupIngressInRegion(
|
||||
null, securityGroupName, IpProtocol.TCP, 22, 22, "0.0.0.0/0");
|
||||
}
|
||||
|
||||
@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.getKeyMaterial());
|
||||
assertNotNull(keyPair.getKeyFingerprint());
|
||||
|
@ -188,28 +203,34 @@ public class EBSBootEC2ClientLiveTest {
|
|||
}
|
||||
|
||||
@Test(enabled = false, dependsOnMethods = { "testCreateKeyPair",
|
||||
"testCreateSecurityGroupIngressCidr" })
|
||||
"testCreateSecurityGroupIngressCidr" })
|
||||
public void testCreateRunningInstance() throws Exception {
|
||||
instance = createInstance(IMAGE_ID);
|
||||
}
|
||||
|
||||
private RunningInstance createInstance(String imageId) throws UnknownHostException {
|
||||
private RunningInstance createInstance(String imageId)
|
||||
throws UnknownHostException {
|
||||
RunningInstance instance = null;
|
||||
while (instance == null) {
|
||||
try {
|
||||
System.out.printf("%d: running instance%n", System.currentTimeMillis());
|
||||
Reservation reservation = client.getInstanceServices().runInstancesInRegion(null, null, // allow
|
||||
// ec2
|
||||
// to
|
||||
// chose
|
||||
// an
|
||||
// availability
|
||||
// zone
|
||||
imageId, 1, // minimum instances
|
||||
1, // maximum instances
|
||||
withKeyName(keyPair.getKeyName())// key I created above
|
||||
.asType(InstanceType.M1_SMALL)// smallest instance size
|
||||
.withSecurityGroup(securityGroupName));// group I created above
|
||||
System.out.printf("%d: running instance%n", System
|
||||
.currentTimeMillis());
|
||||
Reservation reservation = client.getInstanceServices()
|
||||
.runInstancesInRegion(null, null, // allow
|
||||
// ec2
|
||||
// to
|
||||
// chose
|
||||
// an
|
||||
// availability
|
||||
// zone
|
||||
imageId, 1, // minimum instances
|
||||
1, // maximum instances
|
||||
withKeyName(keyPair.getKeyName())// key I created above
|
||||
.asType(InstanceType.M1_SMALL)// smallest instance
|
||||
// size
|
||||
.withSecurityGroup(securityGroupName));// group I
|
||||
// created
|
||||
// above
|
||||
instance = Iterables.getOnlyElement(reservation);
|
||||
} catch (HttpResponseException htpe) {
|
||||
if (htpe.getResponse().getStatusCode() == 400)
|
||||
|
@ -225,55 +246,62 @@ public class EBSBootEC2ClientLiveTest {
|
|||
|
||||
@Test(enabled = false, dependsOnMethods = "testCreateRunningInstance")
|
||||
void testCreateAndAttachVolume() {
|
||||
volume = client.getElasticBlockStoreServices().createVolumeInAvailabilityZone(
|
||||
instance.getAvailabilityZone(), VOLUME_SIZE);
|
||||
System.out.printf("%d: %s awaiting volume to become available%n", System.currentTimeMillis(),
|
||||
volume.getId());
|
||||
volume = client.getElasticBlockStoreServices()
|
||||
.createVolumeInAvailabilityZone(instance.getAvailabilityZone(),
|
||||
VOLUME_SIZE);
|
||||
System.out.printf("%d: %s awaiting volume to become available%n", System
|
||||
.currentTimeMillis(), volume.getId());
|
||||
|
||||
assert volumeTester.apply(volume);
|
||||
|
||||
Attachment attachment = client.getElasticBlockStoreServices().attachVolumeInRegion(
|
||||
instance.getRegion(), volume.getId(), instance.getId(), "/dev/sdh");
|
||||
Attachment attachment = client.getElasticBlockStoreServices()
|
||||
.attachVolumeInRegion(instance.getRegion(), volume.getId(),
|
||||
instance.getId(), "/dev/sdh");
|
||||
|
||||
System.out.printf("%d: %s awaiting attachment to complete%n", System.currentTimeMillis(),
|
||||
attachment.getId());
|
||||
System.out.printf("%d: %s awaiting attachment to complete%n", System
|
||||
.currentTimeMillis(), attachment.getId());
|
||||
|
||||
assert attachTester.apply(attachment);
|
||||
System.out.printf("%d: %s attachment complete%n", System.currentTimeMillis(), attachment
|
||||
.getId());
|
||||
System.out.printf("%d: %s attachment complete%n", System
|
||||
.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
|
||||
void makeScript() {
|
||||
|
||||
mkEbsBoot = new InitBuilder(
|
||||
"mkebsboot",// name of the script
|
||||
"/tmp",// working directory
|
||||
"/tmp/logs",// location of stdout.log and stderr.log
|
||||
ImmutableMap.of("imageDir", "/mnt/tmp", "ebsDevice", "/dev/sdh", "ebsMountPoint",
|
||||
"/mnt/ebs"),// variables used inside of the script
|
||||
"echo creating a filesystem and mounting the ebs volume",// what to execute
|
||||
"{md} {varl}IMAGE_DIR{varr} {varl}EBS_MOUNT_POINT{varr}",
|
||||
"rm -rf {varl}IMAGE_DIR{varr}/*",
|
||||
"yes| mkfs -t ext3 {varl}EBS_DEVICE{varr} 2>&-",
|
||||
"mount {varl}EBS_DEVICE{varr} {varl}EBS_MOUNT_POINT{varr}",
|
||||
"echo making a local working copy of the boot disk",
|
||||
"rsync -ax --exclude /ubuntu/.bash_history --exclude /home/*/.bash_history --exclude /etc/ssh/ssh_host_* --exclude /etc/ssh/moduli --exclude /etc/udev/rules.d/*persistent-net.rules --exclude /var/lib/ec2/* --exclude=/mnt/* --exclude=/proc/* --exclude=/tmp/* --exclude=/dev/log / {varl}IMAGE_DIR{varr}",
|
||||
"echo preparing the local working copy",
|
||||
"touch {varl}IMAGE_DIR{varr}/etc/init.d/ec2-init-user-data",
|
||||
"echo copying the local working copy to the ebs mount",
|
||||
"{cd} {varl}IMAGE_DIR{varr}",
|
||||
"tar -cSf - * | tar xf - -C {varl}EBS_MOUNT_POINT{varr}", "echo size of ebs",
|
||||
"du -sk {varl}EBS_MOUNT_POINT{varr}", "echo size of source",
|
||||
"du -sk {varl}IMAGE_DIR{varr}", "rm -rf {varl}IMAGE_DIR{varr}/*",
|
||||
"umount {varl}EBS_MOUNT_POINT{varr}", "echo " + SCRIPT_END).build(OsFamily.UNIX);
|
||||
"mkebsboot",// name of the script
|
||||
"/tmp",// working directory
|
||||
"/tmp/logs",// location of stdout.log and stderr.log
|
||||
ImmutableMap.of("imageDir", "/mnt/tmp", "ebsDevice", "/dev/sdh",
|
||||
"ebsMountPoint", "/mnt/ebs"),// variables used inside of the
|
||||
// script
|
||||
"echo creating a filesystem and mounting the ebs volume",// what to
|
||||
// execute
|
||||
"{md} {varl}IMAGE_DIR{varr} {varl}EBS_MOUNT_POINT{varr}",
|
||||
"rm -rf {varl}IMAGE_DIR{varr}/*",
|
||||
"yes| mkfs -t ext3 {varl}EBS_DEVICE{varr} 2>&-",
|
||||
"mount {varl}EBS_DEVICE{varr} {varl}EBS_MOUNT_POINT{varr}",
|
||||
"echo making a local working copy of the boot disk",
|
||||
"rsync -ax --exclude /ubuntu/.bash_history --exclude /home/*/.bash_history --exclude /etc/ssh/ssh_host_* --exclude /etc/ssh/moduli --exclude /etc/udev/rules.d/*persistent-net.rules --exclude /var/lib/ec2/* --exclude=/mnt/* --exclude=/proc/* --exclude=/tmp/* --exclude=/dev/log / {varl}IMAGE_DIR{varr}",
|
||||
"echo preparing the local working copy",
|
||||
"touch {varl}IMAGE_DIR{varr}/etc/init.d/ec2-init-user-data",
|
||||
"echo copying the local working copy to the ebs mount",
|
||||
"{cd} {varl}IMAGE_DIR{varr}",
|
||||
"tar -cSf - * | tar xf - -C {varl}EBS_MOUNT_POINT{varr}",
|
||||
"echo size of ebs", "du -sk {varl}EBS_MOUNT_POINT{varr}",
|
||||
"echo size of source", "du -sk {varl}IMAGE_DIR{varr}",
|
||||
"rm -rf {varl}IMAGE_DIR{varr}/*",
|
||||
"umount {varl}EBS_MOUNT_POINT{varr}", "echo " + SCRIPT_END)
|
||||
.build(OsFamily.UNIX);
|
||||
}
|
||||
|
||||
@Test(enabled = false, dependsOnMethods = "testCreateAndAttachVolume")
|
||||
void testBundleInstance() {
|
||||
SshClient ssh = sshFactory.create(new IPSocket(instance.getIpAddress(), 22), "ubuntu",
|
||||
keyPair.getKeyMaterial().getBytes());
|
||||
SshClient ssh = sshFactory.create(new IPSocket(instance.getIpAddress(),
|
||||
22), "ubuntu", keyPair.getKeyMaterial().getBytes());
|
||||
try {
|
||||
ssh.connect();
|
||||
} catch (SshException e) {// try twice in case there is a network timeout
|
||||
|
@ -284,13 +312,13 @@ public class EBSBootEC2ClientLiveTest {
|
|||
ssh.connect();
|
||||
}
|
||||
try {
|
||||
System.out.printf("%d: %s writing ebs script%n", System.currentTimeMillis(), instance
|
||||
.getId());
|
||||
System.out.printf("%d: %s writing ebs script%n", System
|
||||
.currentTimeMillis(), instance.getId());
|
||||
String script = "/tmp/mkebsboot-init.sh";
|
||||
ssh.put(script, new ByteArrayInputStream(mkEbsBoot.getBytes()));
|
||||
|
||||
System.out.printf("%d: %s launching ebs script%n", System.currentTimeMillis(), instance
|
||||
.getId());
|
||||
System.out.printf("%d: %s launching ebs script%n", System
|
||||
.currentTimeMillis(), instance.getId());
|
||||
ssh.exec("chmod 755 " + script);
|
||||
ssh.exec(script + " init");
|
||||
ExecResponse output = ssh.exec("sudo " + script + " start");
|
||||
|
@ -299,8 +327,8 @@ public class EBSBootEC2ClientLiveTest {
|
|||
|
||||
assert !output.getOutput().trim().equals("") : output;
|
||||
|
||||
RetryablePredicate<String> scriptTester = new RetryablePredicate<String>(new ScriptTester(
|
||||
ssh, SCRIPT_END), 600, 10, TimeUnit.SECONDS);
|
||||
RetryablePredicate<String> scriptTester = new RetryablePredicate<String>(
|
||||
new ScriptTester(ssh, SCRIPT_END), 600, 10, TimeUnit.SECONDS);
|
||||
scriptTester.apply(script);
|
||||
} finally {
|
||||
if (ssh != null)
|
||||
|
@ -319,7 +347,8 @@ public class EBSBootEC2ClientLiveTest {
|
|||
|
||||
@Override
|
||||
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");
|
||||
if (output.getOutput().trim().equals("")) {
|
||||
output = ssh.exec(script + " tail");
|
||||
|
@ -329,9 +358,11 @@ public class EBSBootEC2ClientLiveTest {
|
|||
} else {
|
||||
output = ssh.exec(script + " tailerr");
|
||||
String stderr = output.getOutput().trim();
|
||||
throw new RuntimeException(String.format(
|
||||
"script %s ended without token: stdout.log: [%s]; stderr.log: [%s]; ",
|
||||
script, stdout, stderr));
|
||||
throw new RuntimeException(
|
||||
String
|
||||
.format(
|
||||
"script %s ended without token: stdout.log: [%s]; stderr.log: [%s]; ",
|
||||
script, stdout, stderr));
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
@ -342,45 +373,52 @@ public class EBSBootEC2ClientLiveTest {
|
|||
@Test(enabled = false, dependsOnMethods = "testBundleInstance")
|
||||
void testAMIFromBundle() {
|
||||
volume = Iterables.getOnlyElement(client.getElasticBlockStoreServices()
|
||||
.describeVolumesInRegion(volume.getRegion(), volume.getId()));
|
||||
.describeVolumesInRegion(volume.getRegion(), volume.getId()));
|
||||
if (volume.getAttachments().size() > 0) {
|
||||
// should be cleanly unmounted, so force is not necessary.
|
||||
client.getElasticBlockStoreServices().detachVolumeInRegion(instance.getRegion(),
|
||||
volume.getId(), false);
|
||||
System.out.printf("%d: %s awaiting detachment to complete%n", System.currentTimeMillis(),
|
||||
volume.getId());
|
||||
client.getElasticBlockStoreServices().detachVolumeInRegion(
|
||||
instance.getRegion(), volume.getId(), false);
|
||||
System.out.printf("%d: %s awaiting detachment to complete%n", System
|
||||
.currentTimeMillis(), volume.getId());
|
||||
assert volumeTester.apply(volume);
|
||||
} 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(),
|
||||
volume.getId(), withDescription("EBS Ubuntu Hardy"));
|
||||
snapshot = client.getElasticBlockStoreServices().createSnapshotInRegion(
|
||||
volume.getRegion(), volume.getId(),
|
||||
withDescription("EBS Ubuntu Hardy"));
|
||||
|
||||
System.out.printf("%d: %s awaiting snapshot to complete%n", System.currentTimeMillis(),
|
||||
snapshot.getId());
|
||||
System.out.printf("%d: %s awaiting snapshot to complete%n", System
|
||||
.currentTimeMillis(), snapshot.getId());
|
||||
|
||||
assert snapshotTester.apply(snapshot);
|
||||
Image image = Iterables.getOnlyElement(client.getAMIServices().describeImagesInRegion(
|
||||
snapshot.getRegion(), imageIds(IMAGE_ID)));
|
||||
String description = image.getDescription() == null ? "jclouds" : image.getDescription();
|
||||
Image image = Iterables.getOnlyElement(client.getAMIServices()
|
||||
.describeImagesInRegion(snapshot.getRegion(), imageIds(IMAGE_ID)));
|
||||
String description = image.getDescription() == null ? "jclouds" : image
|
||||
.getDescription();
|
||||
|
||||
System.out.printf("%d: %s creating ami from snapshot%n", System.currentTimeMillis(), snapshot
|
||||
.getId());
|
||||
System.out.printf("%d: %s creating ami from snapshot%n", System
|
||||
.currentTimeMillis(), snapshot.getId());
|
||||
|
||||
String amiId = client.getAMIServices().registerUnixImageBackedByEbsInRegion(
|
||||
snapshot.getRegion(),
|
||||
"ebsboot-" + image.getId(),
|
||||
snapshot.getId(),
|
||||
withKernelId(image.getKernelId()).withRamdisk(image.getRamdiskId()).withDescription(
|
||||
description).asArchitecture(Architecture.I386));
|
||||
String amiId = client.getAMIServices()
|
||||
.registerUnixImageBackedByEbsInRegion(
|
||||
snapshot.getRegion(),
|
||||
"ebsboot-" + image.getId(),
|
||||
snapshot.getId(),
|
||||
withKernelId(image.getKernelId()).withRamdisk(
|
||||
image.getRamdiskId()).withDescription(description)
|
||||
.asArchitecture(Architecture.I386));
|
||||
try {
|
||||
ebsImage = Iterables.getOnlyElement(client.getAMIServices().describeImagesInRegion(
|
||||
snapshot.getRegion(), imageIds(amiId)));
|
||||
ebsImage = Iterables.getOnlyElement(client.getAMIServices()
|
||||
.describeImagesInRegion(snapshot.getRegion(), imageIds(amiId)));
|
||||
} catch (AWSResponseException e) {
|
||||
// TODO add a retry handler for this HTTP code 400 and the below error
|
||||
if (e.getError().getClass().equals("InvalidAMIID.NotFound"))
|
||||
ebsImage = Iterables.getOnlyElement(client.getAMIServices().describeImagesInRegion(
|
||||
snapshot.getRegion(), imageIds(amiId)));
|
||||
ebsImage = Iterables
|
||||
.getOnlyElement(client.getAMIServices()
|
||||
.describeImagesInRegion(snapshot.getRegion(),
|
||||
imageIds(amiId)));
|
||||
else
|
||||
throw e;
|
||||
}
|
||||
|
@ -389,22 +427,22 @@ public class EBSBootEC2ClientLiveTest {
|
|||
|
||||
@Test(enabled = false, dependsOnMethods = { "testAMIFromBundle" })
|
||||
public void testInstanceFromEBS() throws Exception {
|
||||
System.out.printf("%d: %s creating instance from ebs-backed ami%n", System
|
||||
.currentTimeMillis(), ebsImage.getId());
|
||||
System.out.printf("%d: %s creating instance from ebs-backed ami%n",
|
||||
System.currentTimeMillis(), ebsImage.getId());
|
||||
|
||||
ebsInstance = createInstance(ebsImage.getId());
|
||||
|
||||
client.getInstanceServices().stopInstancesInRegion(ebsInstance.getRegion(), true,
|
||||
ebsInstance.getId());
|
||||
client.getInstanceServices().stopInstancesInRegion(
|
||||
ebsInstance.getRegion(), true, ebsInstance.getId());
|
||||
|
||||
System.out.printf("%d: %s awaiting instance to stop %n", System.currentTimeMillis(),
|
||||
ebsInstance.getId());
|
||||
System.out.printf("%d: %s awaiting instance to stop %n", System
|
||||
.currentTimeMillis(), ebsInstance.getId());
|
||||
stoppedTester.apply(ebsInstance);
|
||||
tryToChangeStuff();
|
||||
System.out.printf("%d: %s awaiting instance to start %n", System.currentTimeMillis(),
|
||||
ebsInstance.getId());
|
||||
client.getInstanceServices().startInstancesInRegion(ebsInstance.getRegion(),
|
||||
ebsInstance.getId());
|
||||
System.out.printf("%d: %s awaiting instance to start %n", System
|
||||
.currentTimeMillis(), ebsInstance.getId());
|
||||
client.getInstanceServices().startInstancesInRegion(
|
||||
ebsInstance.getRegion(), ebsInstance.getId());
|
||||
ebsInstance = blockUntilWeCanSshIntoInstance(ebsInstance);
|
||||
}
|
||||
|
||||
|
@ -412,8 +450,10 @@ public class EBSBootEC2ClientLiveTest {
|
|||
assertEquals(ebsImage.getImageType(), ImageType.MACHINE);
|
||||
assertEquals(ebsImage.getRootDeviceType(), RootDeviceType.EBS);
|
||||
assertEquals(ebsImage.getRootDeviceName(), "/dev/sda1");
|
||||
assertEquals(ebsImage.getEbsBlockDevices().entrySet(), ImmutableMap.of("/dev/sda1",
|
||||
new Image.EbsBlockDevice(snapshot.getId(), VOLUME_SIZE, true)).entrySet());
|
||||
assertEquals(ebsImage.getEbsBlockDevices().entrySet(), ImmutableMap.of(
|
||||
"/dev/sda1",
|
||||
new Image.EbsBlockDevice(snapshot.getId(), VOLUME_SIZE, true))
|
||||
.entrySet());
|
||||
}
|
||||
|
||||
private void tryToChangeStuff() {
|
||||
|
@ -426,56 +466,59 @@ public class EBSBootEC2ClientLiveTest {
|
|||
}
|
||||
|
||||
private void setUserDataForInstanceInRegion() {
|
||||
client.getInstanceServices().setUserDataForInstanceInRegion(null, ebsInstance.getId(),
|
||||
"test".getBytes());
|
||||
assertEquals("test", client.getInstanceServices().getUserDataForInstanceInRegion(null,
|
||||
ebsInstance.getId()));
|
||||
client.getInstanceServices().setUserDataForInstanceInRegion(null,
|
||||
ebsInstance.getId(), "test".getBytes());
|
||||
assertEquals("test", client.getInstanceServices()
|
||||
.getUserDataForInstanceInRegion(null, ebsInstance.getId()));
|
||||
}
|
||||
|
||||
private void setRamdiskForInstanceInRegion() {
|
||||
String ramdisk = client.getInstanceServices().getRamdiskForInstanceInRegion(null,
|
||||
ebsInstance.getId());
|
||||
client.getInstanceServices()
|
||||
.setRamdiskForInstanceInRegion(null, ebsInstance.getId(), ramdisk);
|
||||
assertEquals(ramdisk, client.getInstanceServices().getRamdiskForInstanceInRegion(null,
|
||||
ebsInstance.getId()));
|
||||
String ramdisk = client.getInstanceServices()
|
||||
.getRamdiskForInstanceInRegion(null, ebsInstance.getId());
|
||||
client.getInstanceServices().setRamdiskForInstanceInRegion(null,
|
||||
ebsInstance.getId(), ramdisk);
|
||||
assertEquals(ramdisk, client.getInstanceServices()
|
||||
.getRamdiskForInstanceInRegion(null, ebsInstance.getId()));
|
||||
}
|
||||
|
||||
private void setKernelForInstanceInRegion() {
|
||||
String oldKernel = client.getInstanceServices().getKernelForInstanceInRegion(null,
|
||||
ebsInstance.getId());
|
||||
client.getInstanceServices().setKernelForInstanceInRegion(null, ebsInstance.getId(),
|
||||
oldKernel);
|
||||
assertEquals(oldKernel, client.getInstanceServices().getKernelForInstanceInRegion(null,
|
||||
ebsInstance.getId()));
|
||||
String oldKernel = client.getInstanceServices()
|
||||
.getKernelForInstanceInRegion(null, ebsInstance.getId());
|
||||
client.getInstanceServices().setKernelForInstanceInRegion(null,
|
||||
ebsInstance.getId(), oldKernel);
|
||||
assertEquals(oldKernel, client.getInstanceServices()
|
||||
.getKernelForInstanceInRegion(null, ebsInstance.getId()));
|
||||
}
|
||||
|
||||
private void setInstanceTypeForInstanceInRegion() {
|
||||
client.getInstanceServices().setInstanceTypeForInstanceInRegion(null, ebsInstance.getId(),
|
||||
InstanceType.C1_MEDIUM);
|
||||
client.getInstanceServices().setInstanceTypeForInstanceInRegion(null,
|
||||
ebsInstance.getId(), InstanceType.C1_MEDIUM);
|
||||
assertEquals(InstanceType.C1_MEDIUM, client.getInstanceServices()
|
||||
.getInstanceTypeForInstanceInRegion(null, ebsInstance.getId()));
|
||||
client.getInstanceServices().setInstanceTypeForInstanceInRegion(null, ebsInstance.getId(),
|
||||
InstanceType.M1_SMALL);
|
||||
.getInstanceTypeForInstanceInRegion(null, ebsInstance.getId()));
|
||||
client.getInstanceServices().setInstanceTypeForInstanceInRegion(null,
|
||||
ebsInstance.getId(), InstanceType.M1_SMALL);
|
||||
assertEquals(InstanceType.M1_SMALL, client.getInstanceServices()
|
||||
.getInstanceTypeForInstanceInRegion(null, ebsInstance.getId()));
|
||||
.getInstanceTypeForInstanceInRegion(null, ebsInstance.getId()));
|
||||
}
|
||||
|
||||
private void setBlockDeviceMappingForInstanceInRegion() {
|
||||
String volumeId = ebsInstance.getEbsBlockDevices().get("/dev/sda1").getVolumeId();
|
||||
String volumeId = ebsInstance.getEbsBlockDevices().get("/dev/sda1")
|
||||
.getVolumeId();
|
||||
|
||||
BlockDeviceMapping blockDeviceMapping = new BlockDeviceMapping();
|
||||
blockDeviceMapping.addEbsBlockDevice("/dev/sda1", new RunningInstance.EbsBlockDevice(
|
||||
volumeId, false));
|
||||
blockDeviceMapping.addEbsBlockDevice("/dev/sda1",
|
||||
new RunningInstance.EbsBlockDevice(volumeId, false));
|
||||
try {
|
||||
client.getInstanceServices().setBlockDeviceMappingForInstanceInRegion(null,
|
||||
ebsInstance.getId(), blockDeviceMapping);
|
||||
client.getInstanceServices().setBlockDeviceMappingForInstanceInRegion(
|
||||
null, ebsInstance.getId(), blockDeviceMapping);
|
||||
|
||||
Map<String, RunningInstance.EbsBlockDevice> devices = client.getInstanceServices()
|
||||
.getBlockDeviceMappingForInstanceInRegion(null, ebsInstance.getId());
|
||||
Map<String, RunningInstance.EbsBlockDevice> devices = client
|
||||
.getInstanceServices().getBlockDeviceMappingForInstanceInRegion(
|
||||
null, ebsInstance.getId());
|
||||
assertEquals(devices.size(), 1);
|
||||
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(deviceName, "/dev/sda1");
|
||||
|
@ -492,27 +535,36 @@ public class EBSBootEC2ClientLiveTest {
|
|||
private void setInstanceInitiatedShutdownBehaviorForInstanceInRegion() {
|
||||
try {
|
||||
|
||||
client.getInstanceServices().setInstanceInitiatedShutdownBehaviorForInstanceInRegion(null,
|
||||
ebsInstance.getId(), InstanceInitiatedShutdownBehavior.STOP);
|
||||
client.getInstanceServices()
|
||||
.setInstanceInitiatedShutdownBehaviorForInstanceInRegion(null,
|
||||
ebsInstance.getId(),
|
||||
InstanceInitiatedShutdownBehavior.STOP);
|
||||
|
||||
assertEquals(InstanceInitiatedShutdownBehavior.STOP, client.getInstanceServices()
|
||||
.getInstanceInitiatedShutdownBehaviorForInstanceInRegion(null,
|
||||
ebsInstance.getId()));
|
||||
client.getInstanceServices().setInstanceInitiatedShutdownBehaviorForInstanceInRegion(null,
|
||||
ebsInstance.getId(), InstanceInitiatedShutdownBehavior.TERMINATE);
|
||||
assertEquals(InstanceInitiatedShutdownBehavior.STOP, client
|
||||
.getInstanceServices()
|
||||
.getInstanceInitiatedShutdownBehaviorForInstanceInRegion(null,
|
||||
ebsInstance.getId()));
|
||||
client.getInstanceServices()
|
||||
.setInstanceInitiatedShutdownBehaviorForInstanceInRegion(null,
|
||||
ebsInstance.getId(),
|
||||
InstanceInitiatedShutdownBehavior.TERMINATE);
|
||||
|
||||
assertEquals(InstanceInitiatedShutdownBehavior.TERMINATE, client.getInstanceServices()
|
||||
.getInstanceInitiatedShutdownBehaviorForInstanceInRegion(null,
|
||||
ebsInstance.getId()));
|
||||
System.out.println("OK: setInstanceInitiatedShutdownBehaviorForInstanceInRegion");
|
||||
assertEquals(InstanceInitiatedShutdownBehavior.TERMINATE, client
|
||||
.getInstanceServices()
|
||||
.getInstanceInitiatedShutdownBehaviorForInstanceInRegion(null,
|
||||
ebsInstance.getId()));
|
||||
System.out
|
||||
.println("OK: setInstanceInitiatedShutdownBehaviorForInstanceInRegion");
|
||||
} catch (Exception e) {
|
||||
System.err.println("setInstanceInitiatedShutdownBehaviorForInstanceInRegion");
|
||||
System.err
|
||||
.println("setInstanceInitiatedShutdownBehaviorForInstanceInRegion");
|
||||
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
|
||||
*/
|
||||
|
@ -528,13 +580,14 @@ public class EBSBootEC2ClientLiveTest {
|
|||
}
|
||||
}
|
||||
|
||||
private void doCheckKey(RunningInstance newDetails) throws UnknownHostException {
|
||||
private void doCheckKey(RunningInstance newDetails)
|
||||
throws UnknownHostException {
|
||||
doCheckKey(newDetails.getIpAddress());
|
||||
}
|
||||
|
||||
private void doCheckKey(String address) {
|
||||
SshClient ssh = sshFactory.create(new IPSocket(address, 22), "ubuntu", keyPair
|
||||
.getKeyMaterial().getBytes());
|
||||
SshClient ssh = sshFactory.create(new IPSocket(address, 22), "ubuntu",
|
||||
keyPair.getKeyMaterial().getBytes());
|
||||
try {
|
||||
ssh.connect();
|
||||
ExecResponse hello = ssh.exec("echo hello");
|
||||
|
@ -545,26 +598,32 @@ public class EBSBootEC2ClientLiveTest {
|
|||
}
|
||||
}
|
||||
|
||||
private RunningInstance blockUntilWeCanSshIntoInstance(RunningInstance instance)
|
||||
throws UnknownHostException {
|
||||
System.out.printf("%d: %s awaiting instance to run %n", System.currentTimeMillis(), instance
|
||||
.getId());
|
||||
private RunningInstance blockUntilWeCanSshIntoInstance(
|
||||
RunningInstance instance) throws UnknownHostException {
|
||||
System.out.printf("%d: %s awaiting instance to run %n", System
|
||||
.currentTimeMillis(), instance.getId());
|
||||
assert runningTester.apply(instance);
|
||||
|
||||
// search my account for the instance I just created
|
||||
Set<Reservation> reservations = client.getInstanceServices().describeInstancesInRegion(
|
||||
instance.getRegion(), instance.getId()); // last parameter (ids) narrows the search
|
||||
Set<Reservation> reservations = client.getInstanceServices()
|
||||
.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(),
|
||||
instance.getIpAddress());
|
||||
System.out.printf("%d: %s awaiting ssh service to start%n", System
|
||||
.currentTimeMillis(), instance.getIpAddress());
|
||||
assert socketTester.apply(new IPSocket(instance.getIpAddress(), 22));
|
||||
System.out.printf("%d: %s ssh service started%n", System.currentTimeMillis(), instance
|
||||
.getDnsName());
|
||||
System.out.printf("%d: %s ssh service started%n", System
|
||||
.currentTimeMillis(), instance.getDnsName());
|
||||
sshPing(instance);
|
||||
System.out.printf("%d: %s ssh connection made%n", System.currentTimeMillis(), instance
|
||||
.getId());
|
||||
System.out.printf("%d: %s ssh connection made%n", System
|
||||
.currentTimeMillis(), instance.getId());
|
||||
return instance;
|
||||
}
|
||||
|
||||
|
@ -572,8 +631,8 @@ public class EBSBootEC2ClientLiveTest {
|
|||
void cleanup() {
|
||||
if (ebsInstance != null) {
|
||||
try {
|
||||
client.getInstanceServices().terminateInstancesInRegion(ebsInstance.getRegion(),
|
||||
ebsInstance.getId());
|
||||
client.getInstanceServices().terminateInstancesInRegion(
|
||||
ebsInstance.getRegion(), ebsInstance.getId());
|
||||
terminatedTester.apply(ebsInstance);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
|
@ -581,7 +640,8 @@ public class EBSBootEC2ClientLiveTest {
|
|||
}
|
||||
if (ebsImage != null) {
|
||||
try {
|
||||
client.getAMIServices().deregisterImageInRegion(ebsImage.getRegion(), ebsImage.getId());
|
||||
client.getAMIServices().deregisterImageInRegion(
|
||||
ebsImage.getRegion(), ebsImage.getId());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
@ -589,16 +649,16 @@ public class EBSBootEC2ClientLiveTest {
|
|||
|
||||
if (snapshot != null) {
|
||||
try {
|
||||
client.getElasticBlockStoreServices().deleteSnapshotInRegion(snapshot.getRegion(),
|
||||
snapshot.getId());
|
||||
client.getElasticBlockStoreServices().deleteSnapshotInRegion(
|
||||
snapshot.getRegion(), snapshot.getId());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (attachment != null) {
|
||||
try {
|
||||
client.getElasticBlockStoreServices().detachVolumeInRegion(volume.getRegion(),
|
||||
volume.getId(), true);
|
||||
client.getElasticBlockStoreServices().detachVolumeInRegion(
|
||||
volume.getRegion(), volume.getId(), true);
|
||||
assert volumeTester.apply(volume);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
|
@ -606,8 +666,8 @@ public class EBSBootEC2ClientLiveTest {
|
|||
}
|
||||
if (instance != null) {
|
||||
try {
|
||||
client.getInstanceServices().terminateInstancesInRegion(instance.getRegion(),
|
||||
instance.getId());
|
||||
client.getInstanceServices().terminateInstancesInRegion(
|
||||
instance.getRegion(), instance.getId());
|
||||
terminatedTester.apply(instance);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
|
@ -615,23 +675,24 @@ public class EBSBootEC2ClientLiveTest {
|
|||
}
|
||||
if (volume != null) {
|
||||
try {
|
||||
client.getElasticBlockStoreServices().deleteVolumeInRegion(volume.getRegion(),
|
||||
volume.getId());
|
||||
client.getElasticBlockStoreServices().deleteVolumeInRegion(
|
||||
volume.getRegion(), volume.getId());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (keyPair != null) {
|
||||
try {
|
||||
client.getKeyPairServices().deleteKeyPairInRegion(keyPair.getRegion(),
|
||||
keyPair.getKeyName());
|
||||
client.getKeyPairServices().deleteKeyPairInRegion(
|
||||
keyPair.getRegion(), keyPair.getKeyName());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (securityGroupName != null) {
|
||||
try {
|
||||
client.getSecurityGroupServices().deleteSecurityGroupInRegion(null, securityGroupName);
|
||||
client.getSecurityGroupServices().deleteSecurityGroupInRegion(null,
|
||||
securityGroupName);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
|
|
@ -63,13 +63,15 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
|||
@Test(enabled = true, dependsOnMethods = "testCorrectAuthException")
|
||||
public void testExtendedOptionsAndLogin() throws Exception {
|
||||
SecurityGroupClient securityGroupClient = EC2Client.class.cast(
|
||||
context.getProviderSpecificContext().getApi()).getSecurityGroupServices();
|
||||
context.getProviderSpecificContext().getApi())
|
||||
.getSecurityGroupServices();
|
||||
|
||||
KeyPairClient keyPairClient = EC2Client.class.cast(
|
||||
context.getProviderSpecificContext().getApi()).getKeyPairServices();
|
||||
context.getProviderSpecificContext().getApi()).getKeyPairServices();
|
||||
|
||||
InstanceClient instanceClient = EC2Client.class.cast(
|
||||
context.getProviderSpecificContext().getApi()).getInstanceServices();
|
||||
context.getProviderSpecificContext().getApi())
|
||||
.getInstanceServices();
|
||||
|
||||
String tag = this.tag + "optionsandlogin";
|
||||
|
||||
|
@ -82,15 +84,17 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
|||
try {
|
||||
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.authorizeSecurityGroupIngressInRegion(null, tag, IpProtocol.TCP, 22,
|
||||
22, "0.0.0.0/0");
|
||||
securityGroupClient.authorizeSecurityGroupIngressInRegion(null, tag,
|
||||
IpProtocol.TCP, 22, 22, "0.0.0.0/0");
|
||||
|
||||
// create a keypair to pass in as well
|
||||
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);
|
||||
assert first.getCredentials() != null : first;
|
||||
assert first.getCredentials().account != null : first;
|
||||
|
@ -102,23 +106,27 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
|||
assertEquals(instance.getKeyName(), tag);
|
||||
|
||||
// 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
|
||||
SecurityGroup group = Iterables.getOnlyElement(securityGroupClient
|
||||
.describeSecurityGroupsInRegion(null, "jclouds#" + tag));
|
||||
.describeSecurityGroupsInRegion(null, "jclouds#" + tag));
|
||||
assert group.getIpPermissions().size() == 0 : group;
|
||||
|
||||
// try to run a script with the original keyPair
|
||||
runScriptWithCreds(tag, first.getImage().getOsFamily(), new Credentials(first
|
||||
.getCredentials().account, result.getKeyMaterial()));
|
||||
runScriptWithCreds(tag, first.getImage().getOsFamily(),
|
||||
new Credentials(first.getCredentials().account, result
|
||||
.getKeyMaterial()));
|
||||
|
||||
} finally {
|
||||
client.destroyNodesMatching(NodePredicates.withTag(tag));
|
||||
if (startedId != null) {
|
||||
// ensure we didn't delete these resources!
|
||||
assertEquals(keyPairClient.describeKeyPairsInRegion(null, tag).size(), 1);
|
||||
assertEquals(securityGroupClient.describeSecurityGroupsInRegion(null, tag).size(), 1);
|
||||
assertEquals(keyPairClient.describeKeyPairsInRegion(null, tag)
|
||||
.size(), 1);
|
||||
assertEquals(securityGroupClient.describeSecurityGroupsInRegion(
|
||||
null, tag).size(), 1);
|
||||
}
|
||||
cleanupExtendedStuff(securityGroupClient, keyPairClient, tag);
|
||||
}
|
||||
|
@ -127,13 +135,15 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
|||
@Test(enabled = true, dependsOnMethods = "testCorrectAuthException")
|
||||
public void testExtendedOptionsNoKeyPair() throws Exception {
|
||||
SecurityGroupClient securityGroupClient = EC2Client.class.cast(
|
||||
context.getProviderSpecificContext().getApi()).getSecurityGroupServices();
|
||||
context.getProviderSpecificContext().getApi())
|
||||
.getSecurityGroupServices();
|
||||
|
||||
KeyPairClient keyPairClient = EC2Client.class.cast(
|
||||
context.getProviderSpecificContext().getApi()).getKeyPairServices();
|
||||
context.getProviderSpecificContext().getApi()).getKeyPairServices();
|
||||
|
||||
InstanceClient instanceClient = EC2Client.class.cast(
|
||||
context.getProviderSpecificContext().getApi()).getInstanceServices();
|
||||
context.getProviderSpecificContext().getApi())
|
||||
.getInstanceServices();
|
||||
|
||||
String tag = this.tag + "optionsnokey";
|
||||
|
||||
|
@ -149,7 +159,8 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
|||
// create the security group
|
||||
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();
|
||||
assert creds == null;
|
||||
|
||||
|
@ -160,31 +171,34 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
|||
assertEquals(instance.getKeyName(), null);
|
||||
|
||||
// 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
|
||||
SecurityGroup group = Iterables.getOnlyElement(securityGroupClient
|
||||
.describeSecurityGroupsInRegion(null, "jclouds#" + tag));
|
||||
.describeSecurityGroupsInRegion(null, "jclouds#" + tag));
|
||||
assert group.getIpPermissions().size() == 0 : group;
|
||||
|
||||
} finally {
|
||||
client.destroyNodesMatching(NodePredicates.withTag(tag));
|
||||
if (startedId != null) {
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
private RunningInstance getInstance(InstanceClient instanceClient, String id) {
|
||||
RunningInstance instance = Iterables.getOnlyElement(Iterables.getOnlyElement(instanceClient
|
||||
.describeInstancesInRegion(null, id)));
|
||||
RunningInstance instance = Iterables
|
||||
.getOnlyElement(Iterables.getOnlyElement(instanceClient
|
||||
.describeInstancesInRegion(null, id)));
|
||||
return instance;
|
||||
}
|
||||
|
||||
private void cleanupExtendedStuff(SecurityGroupClient securityGroupClient,
|
||||
KeyPairClient keyPairClient, String tag) {
|
||||
KeyPairClient keyPairClient, String tag) {
|
||||
try {
|
||||
securityGroupClient.deleteSecurityGroupInRegion(null, tag);
|
||||
} catch (Exception e) {
|
||||
|
|
|
@ -52,7 +52,7 @@ public class ImageParserTest extends BaseEC2HandlerTest {
|
|||
InputStream is = getClass().getResourceAsStream("/ec2/alestic_canonical.xml");
|
||||
|
||||
Set<Image> result = parseImages(is);
|
||||
assertEquals(result.size(), 6);
|
||||
assertEquals(result.size(), 7);
|
||||
|
||||
ImageParser parser = new ImageParser(
|
||||
new EC2PopulateDefaultLoginCredentialsForImageStrategy(), ImmutableSet
|
||||
|
@ -87,6 +87,9 @@ public class ImageParserTest extends BaseEC2HandlerTest {
|
|||
"063491364108"));
|
||||
assertEquals(alesticKarmic.getVersion(), "20090623");
|
||||
|
||||
|
||||
|
||||
|
||||
org.jclouds.compute.domain.Image ubuntuKarmic = parser.apply(Iterables.get(result, 2));
|
||||
|
||||
assertEquals(ubuntuKarmic.getArchitecture(), org.jclouds.compute.domain.Architecture.X86_32);
|
||||
|
@ -120,8 +123,24 @@ public class ImageParserTest extends BaseEC2HandlerTest {
|
|||
"063491364108"));
|
||||
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
|
||||
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",
|
||||
|
|
|
@ -60,18 +60,20 @@ public class EC2RunNodesAndAddToSetStrategyTest {
|
|||
|
||||
@Test
|
||||
public void testZoneAsALocation() {
|
||||
assertRegionAndZoneForLocation(ZONE_AP_SOUTHEAST_1A, Region.AP_SOUTHEAST_1,
|
||||
AvailabilityZone.AP_SOUTHEAST_1A);
|
||||
assertRegionAndZoneForLocation(ZONE_AP_SOUTHEAST_1A,
|
||||
Region.AP_SOUTHEAST_1, AvailabilityZone.AP_SOUTHEAST_1A);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRegionAsALocation() {
|
||||
assertRegionAndZoneForLocation(REGION_AP_SOUTHEAST_1, Region.AP_SOUTHEAST_1, null);
|
||||
assertRegionAndZoneForLocation(REGION_AP_SOUTHEAST_1,
|
||||
Region.AP_SOUTHEAST_1, null);
|
||||
}
|
||||
|
||||
// // fixtures
|
||||
|
||||
public static Iterable<NodeMetadata> containsNodeMetadata(final NodeMetadata in) {
|
||||
public static Iterable<NodeMetadata> containsNodeMetadata(
|
||||
final NodeMetadata in) {
|
||||
reportMatcher(new IArgumentMatcher() {
|
||||
|
||||
@Override
|
||||
|
@ -90,7 +92,8 @@ public class EC2RunNodesAndAddToSetStrategyTest {
|
|||
return null;
|
||||
}
|
||||
|
||||
private void assertRegionAndZoneForLocation(Location location, String region, String zone) {
|
||||
private void assertRegionAndZoneForLocation(Location location,
|
||||
String region, String zone) {
|
||||
String imageId = "ami1";
|
||||
String instanceCreatedId = "instance1";
|
||||
// setup mocks
|
||||
|
@ -99,31 +102,37 @@ public class EC2RunNodesAndAddToSetStrategyTest {
|
|||
InstanceClient instanceClient = createMock(InstanceClient.class);
|
||||
RunInstancesOptions ec2Options = createMock(RunInstancesOptions.class);
|
||||
RunningInstance instance = createMock(RunningInstance.class);
|
||||
Reservation reservation = new Reservation(region, ImmutableSet.<String> of(), ImmutableSet
|
||||
.<RunningInstance> of(instance), "ownerId", "requesterId", "reservationId");
|
||||
Reservation reservation = new Reservation(region, ImmutableSet
|
||||
.<String> of(), ImmutableSet.<RunningInstance> of(instance),
|
||||
"ownerId", "requesterId", "reservationId");
|
||||
NodeMetadata nodeMetadata = createMock(NodeMetadata.class);
|
||||
|
||||
// setup expectations
|
||||
expect(strategy.client.getInstanceServices()).andReturn(instanceClient).atLeastOnce();
|
||||
expect(strategy.client.getInstanceServices()).andReturn(instanceClient)
|
||||
.atLeastOnce();
|
||||
expect(
|
||||
strategy.createKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.execute(region,
|
||||
input.tag, input.template)).andReturn(ec2Options);
|
||||
expect(input.template.getLocation()).andReturn(input.location).atLeastOnce();
|
||||
strategy.createKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions
|
||||
.execute(region, input.tag, input.template)).andReturn(
|
||||
ec2Options);
|
||||
expect(input.template.getLocation()).andReturn(input.location)
|
||||
.atLeastOnce();
|
||||
expect(input.template.getImage()).andReturn(input.image).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(
|
||||
strategy.utils.runOptionsOnNodesAndAddToGoodSetOrPutExceptionIntoBadMap(
|
||||
eq(input.options), containsNodeMetadata(nodeMetadata), eq(input.nodes),
|
||||
eq(input.badNodes))).andReturn(null);
|
||||
instanceClient.runInstancesInRegion(region, zone, imageId, 1,
|
||||
input.count, ec2Options)).andReturn(reservation);
|
||||
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(instanceClient);
|
||||
|
@ -134,7 +143,8 @@ public class EC2RunNodesAndAddToSetStrategyTest {
|
|||
replayStrategy(strategy);
|
||||
|
||||
// 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(instanceClient);
|
||||
|
@ -145,12 +155,12 @@ public class EC2RunNodesAndAddToSetStrategyTest {
|
|||
verifyStrategy(strategy);
|
||||
}
|
||||
|
||||
private static final Location REGION_AP_SOUTHEAST_1 = new LocationImpl(LocationScope.REGION,
|
||||
Region.AP_SOUTHEAST_1, Region.AP_SOUTHEAST_1, new LocationImpl(LocationScope.PROVIDER,
|
||||
"ec2", "ec2", null));
|
||||
private static final Location ZONE_AP_SOUTHEAST_1A = new LocationImpl(LocationScope.ZONE,
|
||||
AvailabilityZone.AP_SOUTHEAST_1A, AvailabilityZone.AP_SOUTHEAST_1A,
|
||||
REGION_AP_SOUTHEAST_1);
|
||||
private static final Location REGION_AP_SOUTHEAST_1 = new LocationImpl(
|
||||
LocationScope.REGION, Region.AP_SOUTHEAST_1, Region.AP_SOUTHEAST_1,
|
||||
new LocationImpl(LocationScope.PROVIDER, "ec2", "ec2", null));
|
||||
private static final Location ZONE_AP_SOUTHEAST_1A = new LocationImpl(
|
||||
LocationScope.ZONE, AvailabilityZone.AP_SOUTHEAST_1A,
|
||||
AvailabilityZone.AP_SOUTHEAST_1A, REGION_AP_SOUTHEAST_1);
|
||||
|
||||
// /////////////////////////////////////////////////////////////////////
|
||||
@SuppressWarnings("unchecked")
|
||||
|
@ -191,7 +201,7 @@ public class EC2RunNodesAndAddToSetStrategyTest {
|
|||
private void verifyStrategy(EC2RunNodesAndAddToSetStrategy strategy) {
|
||||
verify(strategy.createKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions);
|
||||
verify(strategy.client);
|
||||
verify(strategy.instanceStateRunning);
|
||||
verify(strategy.instancePresent);
|
||||
verify(strategy.runningInstanceToNodeMetadata);
|
||||
verify(strategy.utils);
|
||||
}
|
||||
|
@ -204,14 +214,14 @@ public class EC2RunNodesAndAddToSetStrategyTest {
|
|||
RunningInstanceToNodeMetadata runningInstanceToNodeMetadata = createMock(RunningInstanceToNodeMetadata.class);
|
||||
ComputeUtils utils = createMock(ComputeUtils.class);
|
||||
return new EC2RunNodesAndAddToSetStrategy(client,
|
||||
createKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions, instanceStateRunning,
|
||||
runningInstanceToNodeMetadata, utils);
|
||||
createKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions,
|
||||
instanceStateRunning, runningInstanceToNodeMetadata, utils);
|
||||
}
|
||||
|
||||
private void replayStrategy(EC2RunNodesAndAddToSetStrategy strategy) {
|
||||
replay(strategy.createKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions);
|
||||
replay(strategy.client);
|
||||
replay(strategy.instanceStateRunning);
|
||||
replay(strategy.instancePresent);
|
||||
replay(strategy.runningInstanceToNodeMetadata);
|
||||
replay(strategy.utils);
|
||||
}
|
||||
|
|
|
@ -67,6 +67,19 @@
|
|||
<rootDeviceType>instance-store</rootDeviceType>
|
||||
<blockDeviceMapping />
|
||||
</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>
|
||||
<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>
|
||||
|
|
|
@ -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 {
|
||||
|
||||
/**
|
||||
* Tag used for all resources that belong to the same logical group. run, destroy commands are
|
||||
* scoped to tag.
|
||||
* Tag used for all resources that belong to the same logical group. run,
|
||||
* destroy commands are scoped to tag.
|
||||
*
|
||||
* @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();
|
||||
|
||||
/**
|
||||
* If possible, these are returned upon all detail requests. However, it is often the case that
|
||||
* credentials are only available at "run" time.
|
||||
* If possible, these are returned upon all detail requests. However, it is
|
||||
* often the case that credentials are only available at "run" time.
|
||||
*/
|
||||
Credentials getCredentials();
|
||||
|
||||
|
|
|
@ -41,7 +41,8 @@ import com.google.common.collect.Sets;
|
|||
* @author Adrian Cole
|
||||
* @author Ivan Meredith
|
||||
*/
|
||||
public class NodeMetadataImpl extends ComputeMetadataImpl implements NodeMetadata {
|
||||
public class NodeMetadataImpl extends ComputeMetadataImpl implements
|
||||
NodeMetadata {
|
||||
/** The serialVersionUID */
|
||||
private static final long serialVersionUID = 7924307572338157887L;
|
||||
|
||||
|
@ -53,17 +54,19 @@ public class NodeMetadataImpl extends ComputeMetadataImpl implements NodeMetadat
|
|||
private final String tag;
|
||||
private final Image image;
|
||||
|
||||
public NodeMetadataImpl(String providerId, String name, String id, Location location, URI uri,
|
||||
Map<String, String> userMetadata, @Nullable String tag, @Nullable Image image,
|
||||
NodeState state, Iterable<String> publicAddresses,
|
||||
Iterable<String> privateAddresses, Map<String, String> extra,
|
||||
@Nullable Credentials credentials) {
|
||||
public NodeMetadataImpl(String providerId, String name, String id,
|
||||
Location location, URI uri, Map<String, String> userMetadata,
|
||||
@Nullable String tag, @Nullable Image image, NodeState state,
|
||||
Iterable<String> publicAddresses, Iterable<String> privateAddresses,
|
||||
Map<String, String> extra, @Nullable Credentials credentials) {
|
||||
super(ComputeType.NODE, providerId, name, id, location, uri, userMetadata);
|
||||
this.tag = tag;
|
||||
this.image = image;
|
||||
this.state = checkNotNull(state, "state");
|
||||
Iterables.addAll(this.publicAddresses, checkNotNull(publicAddresses, "publicAddresses"));
|
||||
Iterables.addAll(this.privateAddresses, checkNotNull(privateAddresses, "privateAddresses"));
|
||||
Iterables.addAll(this.publicAddresses, checkNotNull(publicAddresses,
|
||||
"publicAddresses"));
|
||||
Iterables.addAll(this.privateAddresses, checkNotNull(privateAddresses,
|
||||
"privateAddresses"));
|
||||
this.extra.putAll(checkNotNull(extra, "extra"));
|
||||
this.credentials = credentials;
|
||||
}
|
||||
|
@ -127,19 +130,22 @@ public class NodeMetadataImpl extends ComputeMetadataImpl implements NodeMetadat
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[id=" + getId() + ", providerId=" + getProviderId() + ", tag=" + getTag() + ", name="
|
||||
+ getName() + ", location=" + getLocation() + ", uri=" + getUri() + ", image="
|
||||
+ getImage() + ", userMetadata=" + getUserMetadata() + ", state=" + getState()
|
||||
+ ", privateAddresses=" + privateAddresses + ", publicAddresses=" + publicAddresses
|
||||
+ ", extra=" + getExtra() + "]";
|
||||
return "[id=" + getId() + ", providerId=" + getProviderId() + ", tag="
|
||||
+ getTag() + ", name=" + getName() + ", location=" + getLocation()
|
||||
+ ", uri=" + getUri() + ", image=" + getImage() + ", userMetadata="
|
||||
+ getUserMetadata() + ", state=" + getState()
|
||||
+ ", privateAddresses=" + privateAddresses + ", publicAddresses="
|
||||
+ publicAddresses + ", extra=" + getExtra() + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = super.hashCode();
|
||||
result = prime * result + ((privateAddresses == null) ? 0 : privateAddresses.hashCode());
|
||||
result = prime * result + ((publicAddresses == null) ? 0 : publicAddresses.hashCode());
|
||||
result = prime * result
|
||||
+ ((privateAddresses == null) ? 0 : privateAddresses.hashCode());
|
||||
result = prime * result
|
||||
+ ((publicAddresses == null) ? 0 : publicAddresses.hashCode());
|
||||
result = prime * result + ((tag == null) ? 0 : tag.hashCode());
|
||||
result = prime * result + ((image == null) ? 0 : image.hashCode());
|
||||
return result;
|
||||
|
|
|
@ -97,34 +97,47 @@ public class BaseComputeService implements ComputeService {
|
|||
protected final DestroyNodeStrategy destroyNodeStrategy;
|
||||
protected final Provider<TemplateBuilder> templateBuilderProvider;
|
||||
protected final Provider<TemplateOptions> templateOptionsProvider;
|
||||
protected final Predicate<NodeMetadata> nodeRunning;
|
||||
protected final Predicate<NodeMetadata> nodeTerminated;
|
||||
protected final ComputeUtils utils;
|
||||
protected final ExecutorService executor;
|
||||
|
||||
@Inject
|
||||
protected BaseComputeService(ComputeServiceContext context,
|
||||
Provider<Set<? extends Image>> images, Provider<Set<? extends Size>> sizes,
|
||||
Provider<Set<? extends Location>> locations, ListNodesStrategy listNodesStrategy,
|
||||
GetNodeMetadataStrategy getNodeMetadataStrategy,
|
||||
RunNodesAndAddToSetStrategy runNodesAndAddToSetStrategy,
|
||||
RebootNodeStrategy rebootNodeStrategy, DestroyNodeStrategy destroyNodeStrategy,
|
||||
Provider<TemplateBuilder> templateBuilderProvider,
|
||||
Provider<TemplateOptions> templateOptionsProvider, ComputeUtils utils,
|
||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) {
|
||||
Provider<Set<? extends Image>> images,
|
||||
Provider<Set<? extends Size>> sizes,
|
||||
Provider<Set<? extends Location>> locations,
|
||||
ListNodesStrategy listNodesStrategy,
|
||||
GetNodeMetadataStrategy getNodeMetadataStrategy,
|
||||
RunNodesAndAddToSetStrategy runNodesAndAddToSetStrategy,
|
||||
RebootNodeStrategy rebootNodeStrategy,
|
||||
DestroyNodeStrategy destroyNodeStrategy,
|
||||
Provider<TemplateBuilder> templateBuilderProvider,
|
||||
Provider<TemplateOptions> templateOptionsProvider,
|
||||
@Named("NODE_RUNNING") Predicate<NodeMetadata> nodeRunning,
|
||||
@Named("NODE_TERMINATED") Predicate<NodeMetadata> nodeTerminated,
|
||||
ComputeUtils utils,
|
||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) {
|
||||
this.context = checkNotNull(context, "context");
|
||||
this.images = checkNotNull(images, "images");
|
||||
this.sizes = checkNotNull(sizes, "sizes");
|
||||
this.locations = checkNotNull(locations, "locations");
|
||||
this.listNodesStrategy = checkNotNull(listNodesStrategy, "listNodesStrategy");
|
||||
this.listNodesStrategy = checkNotNull(listNodesStrategy,
|
||||
"listNodesStrategy");
|
||||
this.getNodeMetadataStrategy = checkNotNull(getNodeMetadataStrategy,
|
||||
"getNodeMetadataStrategy");
|
||||
this.runNodesAndAddToSetStrategy = checkNotNull(runNodesAndAddToSetStrategy,
|
||||
"runNodesAndAddToSetStrategy");
|
||||
this.rebootNodeStrategy = checkNotNull(rebootNodeStrategy, "rebootNodeStrategy");
|
||||
this.destroyNodeStrategy = checkNotNull(destroyNodeStrategy, "destroyNodeStrategy");
|
||||
"getNodeMetadataStrategy");
|
||||
this.runNodesAndAddToSetStrategy = checkNotNull(
|
||||
runNodesAndAddToSetStrategy, "runNodesAndAddToSetStrategy");
|
||||
this.rebootNodeStrategy = checkNotNull(rebootNodeStrategy,
|
||||
"rebootNodeStrategy");
|
||||
this.destroyNodeStrategy = checkNotNull(destroyNodeStrategy,
|
||||
"destroyNodeStrategy");
|
||||
this.templateBuilderProvider = checkNotNull(templateBuilderProvider,
|
||||
"templateBuilderProvider");
|
||||
"templateBuilderProvider");
|
||||
this.templateOptionsProvider = checkNotNull(templateOptionsProvider,
|
||||
"templateOptionsProvider");
|
||||
"templateOptionsProvider");
|
||||
this.nodeRunning = checkNotNull(nodeRunning, "nodeRunning");
|
||||
this.nodeTerminated = checkNotNull(nodeTerminated, "nodeTerminated");
|
||||
this.utils = checkNotNull(utils, "utils");
|
||||
this.executor = checkNotNull(executor, "executor");
|
||||
}
|
||||
|
@ -141,22 +154,25 @@ public class BaseComputeService implements ComputeService {
|
|||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Set<? extends NodeMetadata> runNodesWithTag(String tag, int count, Template template)
|
||||
throws RunNodesException {
|
||||
public Set<? extends NodeMetadata> runNodesWithTag(String tag, int count,
|
||||
Template template) throws RunNodesException {
|
||||
checkArgument(tag.indexOf('-') == -1, "tag cannot contain hyphens");
|
||||
checkNotNull(template.getLocation(), "location");
|
||||
logger.debug(">> running %d node%s tag(%s) location(%s) image(%s) size(%s) options(%s)",
|
||||
count, count > 1 ? "s" : "", tag, template.getLocation().getId(), template
|
||||
.getImage().getProviderId(), template.getSize().getProviderId(), template
|
||||
.getOptions());
|
||||
logger
|
||||
.debug(
|
||||
">> running %d node%s tag(%s) location(%s) image(%s) size(%s) options(%s)",
|
||||
count, count > 1 ? "s" : "", tag, template.getLocation()
|
||||
.getId(), template.getImage().getProviderId(), template
|
||||
.getSize().getProviderId(), template.getOptions());
|
||||
Set<NodeMetadata> nodes = Sets.newHashSet();
|
||||
Map<NodeMetadata, Exception> badNodes = Maps.newLinkedHashMap();
|
||||
Map<?, ListenableFuture<Void>> responses = runNodesAndAddToSetStrategy.execute(tag, count,
|
||||
template, nodes, badNodes);
|
||||
Map<?, Exception> executionExceptions = awaitCompletion(responses, executor, null, logger,
|
||||
"starting nodes");
|
||||
Map<?, ListenableFuture<Void>> responses = runNodesAndAddToSetStrategy
|
||||
.execute(tag, count, template, nodes, badNodes);
|
||||
Map<?, Exception> executionExceptions = awaitCompletion(responses,
|
||||
executor, null, logger, "starting nodes");
|
||||
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;
|
||||
}
|
||||
|
@ -166,8 +182,9 @@ public class BaseComputeService implements ComputeService {
|
|||
*/
|
||||
@Override
|
||||
public Set<? extends NodeMetadata> runNodesWithTag(String tag, int count,
|
||||
TemplateOptions templateOptions) throws RunNodesException {
|
||||
return runNodesWithTag(tag, count, templateBuilder().any().options(templateOptions).build());
|
||||
TemplateOptions templateOptions) throws RunNodesException {
|
||||
return runNodesWithTag(tag, count, templateBuilder().any().options(
|
||||
templateOptions).build());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -175,7 +192,7 @@ public class BaseComputeService implements ComputeService {
|
|||
*/
|
||||
@Override
|
||||
public Set<? extends NodeMetadata> runNodesWithTag(String tag, int count)
|
||||
throws RunNodesException {
|
||||
throws RunNodesException {
|
||||
return runNodesWithTag(tag, count, templateOptions());
|
||||
}
|
||||
|
||||
|
@ -186,7 +203,8 @@ public class BaseComputeService implements ComputeService {
|
|||
public void destroyNode(String id) {
|
||||
checkNotNull(id, "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);
|
||||
}
|
||||
|
||||
|
@ -194,19 +212,21 @@ public class BaseComputeService implements ComputeService {
|
|||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Set<? extends NodeMetadata> destroyNodesMatching(Predicate<NodeMetadata> filter) {
|
||||
public Set<? extends NodeMetadata> destroyNodesMatching(
|
||||
Predicate<NodeMetadata> filter) {
|
||||
logger.debug(">> destroying nodes matching(%s)", filter);
|
||||
Map<NodeMetadata, ListenableFuture<Void>> responses = Maps.newHashMap();
|
||||
final Set<NodeMetadata> destroyedNodes = Sets.newLinkedHashSet();
|
||||
for (final NodeMetadata node : nodesMatchingFilterAndNotTerminated(filter)) {
|
||||
responses.put(node, makeListenable(executor.submit(new Callable<Void>() {
|
||||
@Override
|
||||
public Void call() throws Exception {
|
||||
destroyNode(node.getId());
|
||||
destroyedNodes.add(node);
|
||||
return null;
|
||||
}
|
||||
}), executor));
|
||||
responses.put(node, makeListenable(executor
|
||||
.submit(new Callable<Void>() {
|
||||
@Override
|
||||
public Void call() throws Exception {
|
||||
destroyNode(node.getId());
|
||||
destroyedNodes.add(node);
|
||||
return null;
|
||||
}
|
||||
}), executor));
|
||||
}
|
||||
awaitCompletion(responses, executor, null, logger, "destroying nodes");
|
||||
logger.debug("<< destroyed");
|
||||
|
@ -214,9 +234,9 @@ public class BaseComputeService implements ComputeService {
|
|||
}
|
||||
|
||||
private Iterable<? extends NodeMetadata> nodesMatchingFilterAndNotTerminated(
|
||||
Predicate<NodeMetadata> filter) {
|
||||
return Iterables.filter(detailsOnAllNodes(), Predicates.and(filter, Predicates
|
||||
.not(NodePredicates.TERMINATED)));
|
||||
Predicate<NodeMetadata> filter) {
|
||||
return Iterables.filter(detailsOnAllNodes(), Predicates.and(filter,
|
||||
Predicates.not(NodePredicates.TERMINATED)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -225,7 +245,8 @@ public class BaseComputeService implements ComputeService {
|
|||
@Override
|
||||
public Set<? extends ComputeMetadata> listNodes() {
|
||||
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());
|
||||
return set;
|
||||
}
|
||||
|
@ -234,11 +255,12 @@ public class BaseComputeService implements ComputeService {
|
|||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Set<? extends NodeMetadata> listNodesDetailsMatching(Predicate<ComputeMetadata> filter) {
|
||||
public Set<? extends NodeMetadata> listNodesDetailsMatching(
|
||||
Predicate<ComputeMetadata> filter) {
|
||||
checkNotNull(filter, "filter");
|
||||
logger.debug(">> listing node details matching(%s)", filter);
|
||||
Set<? extends NodeMetadata> set = Sets.newLinkedHashSet(listNodesStrategy
|
||||
.listDetailsOnNodesMatching(filter));
|
||||
.listDetailsOnNodesMatching(filter));
|
||||
logger.debug("<< list(%d)", set.size());
|
||||
return set;
|
||||
}
|
||||
|
@ -291,7 +313,8 @@ public class BaseComputeService implements ComputeService {
|
|||
public void rebootNode(String id) {
|
||||
checkNotNull(id, "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);
|
||||
}
|
||||
|
||||
|
@ -304,13 +327,14 @@ public class BaseComputeService implements ComputeService {
|
|||
|
||||
Map<NodeMetadata, ListenableFuture<Void>> responses = Maps.newHashMap();
|
||||
for (final NodeMetadata node : nodesMatchingFilterAndNotTerminated(filter)) {
|
||||
responses.put(node, makeListenable(executor.submit(new Callable<Void>() {
|
||||
@Override
|
||||
public Void call() throws Exception {
|
||||
rebootNode(node.getId());
|
||||
return null;
|
||||
}
|
||||
}), executor));
|
||||
responses.put(node, makeListenable(executor
|
||||
.submit(new Callable<Void>() {
|
||||
@Override
|
||||
public Void call() throws Exception {
|
||||
rebootNode(node.getId());
|
||||
return null;
|
||||
}
|
||||
}), executor));
|
||||
}
|
||||
awaitCompletion(responses, executor, null, logger, "rebooting nodes");
|
||||
logger.debug("<< rebooted");
|
||||
|
@ -321,7 +345,8 @@ public class BaseComputeService implements ComputeService {
|
|||
*/
|
||||
@Override
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -329,11 +354,13 @@ public class BaseComputeService implements ComputeService {
|
|||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Map<NodeMetadata, ExecResponse> runScriptOnNodesMatching(Predicate<NodeMetadata> filter,
|
||||
final byte[] runScript, @Nullable final RunScriptOptions options)
|
||||
throws RunScriptOnNodesException {
|
||||
Iterable<? extends NodeMetadata> nodes = verifyParametersAndListNodes(filter, runScript,
|
||||
(options != null) ? options : RunScriptOptions.NONE);
|
||||
public Map<NodeMetadata, ExecResponse> runScriptOnNodesMatching(
|
||||
Predicate<NodeMetadata> filter, final byte[] runScript,
|
||||
@Nullable final RunScriptOptions options)
|
||||
throws RunScriptOnNodesException {
|
||||
Iterable<? extends NodeMetadata> nodes = verifyParametersAndListNodes(
|
||||
filter, runScript, (options != null) ? options
|
||||
: RunScriptOptions.NONE);
|
||||
|
||||
final Map<NodeMetadata, ExecResponse> execs = Maps.newHashMap();
|
||||
|
||||
|
@ -343,75 +370,88 @@ public class BaseComputeService implements ComputeService {
|
|||
|
||||
for (final NodeMetadata node : nodes) {
|
||||
|
||||
responses.put(node, makeListenable(executor.submit(new Callable<Void>() {
|
||||
@Override
|
||||
public Void call() throws Exception {
|
||||
try {
|
||||
RunScriptOnNode callable;
|
||||
if (options.isRunAsRoot())
|
||||
callable = utils.runScriptOnNode(node, "computeserv", runScript);
|
||||
else
|
||||
callable = utils.runScriptOnNodeAsDefaultUser(node, "computeserv", runScript);
|
||||
SshClient ssh = utils.createSshClientOncePortIsListeningOnNode(node);
|
||||
try {
|
||||
ssh.connect();
|
||||
callable.setConnection(ssh, logger);
|
||||
execs.put(node, callable.call());
|
||||
} finally {
|
||||
if (ssh != null)
|
||||
ssh.disconnect();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
badNodes.put(node, e);
|
||||
responses.put(node, makeListenable(executor
|
||||
.submit(new Callable<Void>() {
|
||||
@Override
|
||||
public Void call() throws Exception {
|
||||
try {
|
||||
RunScriptOnNode callable;
|
||||
if (options.isRunAsRoot())
|
||||
callable = utils.runScriptOnNode(node,
|
||||
"computeserv", runScript);
|
||||
else
|
||||
callable = utils.runScriptOnNodeAsDefaultUser(node,
|
||||
"computeserv", runScript);
|
||||
SshClient ssh = utils
|
||||
.createSshClientOncePortIsListeningOnNode(node);
|
||||
try {
|
||||
ssh.connect();
|
||||
callable.setConnection(ssh, logger);
|
||||
execs.put(node, callable.call());
|
||||
} finally {
|
||||
if (ssh != null)
|
||||
ssh.disconnect();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
badNodes.put(node, e);
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}), executor));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}), executor));
|
||||
|
||||
}
|
||||
Map<?, Exception> exceptions = awaitCompletion(responses, executor, null, logger,
|
||||
"starting nodes");
|
||||
Map<?, Exception> exceptions = awaitCompletion(responses, executor, null,
|
||||
logger, "starting nodes");
|
||||
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;
|
||||
|
||||
}
|
||||
|
||||
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(runScript,
|
||||
"The script (represented by bytes array - use \"script\".getBytes() must be provided");
|
||||
checkNotNull(
|
||||
runScript,
|
||||
"The script (represented by bytes array - use \"script\".getBytes() must be provided");
|
||||
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
|
||||
public NodeMetadata apply(NodeMetadata node) {
|
||||
@Override
|
||||
public NodeMetadata apply(NodeMetadata node) {
|
||||
|
||||
checkArgument(node.getPublicAddresses().size() > 0, "no public ip addresses on node: "
|
||||
+ node);
|
||||
if (options.getOverrideCredentials() != null) {
|
||||
// override the credentials with provided to this method
|
||||
node = ComputeUtils.installNewCredentials(node, options.getOverrideCredentials());
|
||||
} else {
|
||||
// don't override
|
||||
checkNotNull(node.getCredentials(),
|
||||
"If the default credentials need to be used, they can't be null");
|
||||
checkNotNull(node.getCredentials().account,
|
||||
"Account name for ssh authentication must be "
|
||||
checkArgument(node.getPublicAddresses().size() > 0,
|
||||
"no public ip addresses on node: " + node);
|
||||
if (options.getOverrideCredentials() != null) {
|
||||
// override the credentials with provided to this
|
||||
// method
|
||||
node = ComputeUtils.installNewCredentials(node, options
|
||||
.getOverrideCredentials());
|
||||
} else {
|
||||
// don't override
|
||||
checkNotNull(node.getCredentials(),
|
||||
"If the default credentials need to be used, they can't be null");
|
||||
checkNotNull(
|
||||
node.getCredentials().account,
|
||||
"Account name for ssh authentication must be "
|
||||
+ "specified. Try passing RunScriptOptions with new credentials");
|
||||
checkNotNull(node.getCredentials().key,
|
||||
"Key or password for ssh authentication must be "
|
||||
checkNotNull(
|
||||
node.getCredentials().key,
|
||||
"Key or password for ssh authentication must be "
|
||||
+ "specified. Try passing RunScriptOptions with new credentials");
|
||||
}
|
||||
return node;
|
||||
}
|
||||
});
|
||||
}
|
||||
return node;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private Iterable<? extends NodeMetadata> detailsOnAllNodes() {
|
||||
|
|
|
@ -24,10 +24,11 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Contains options supported in the {@code ComputeService#runNodesWithTag} operation. <h2>
|
||||
* Usage</h2> The recommended way to instantiate a TemplateOptions object is to statically import
|
||||
* TemplateOptions.* and invoke a static creation method followed by an instance mutator (if
|
||||
* needed):
|
||||
* Contains options supported in the {@code ComputeService#runNodesWithTag}
|
||||
* operation. <h2>
|
||||
* Usage</h2> The recommended way to instantiate a TemplateOptions object is to
|
||||
* statically import TemplateOptions.* and invoke a static creation method
|
||||
* followed by an instance mutator (if needed):
|
||||
* <p/>
|
||||
* <code>
|
||||
* import static org.jclouds.compute.options.TemplateOptions.Builder.*;
|
||||
|
@ -41,301 +42,350 @@ import java.util.Arrays;
|
|||
*/
|
||||
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 {
|
||||
private final TemplateOptions delegate;
|
||||
public static class ImmutableTemplateOptions extends TemplateOptions {
|
||||
private final TemplateOptions delegate;
|
||||
|
||||
public ImmutableTemplateOptions(TemplateOptions delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
public ImmutableTemplateOptions(TemplateOptions delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return delegate.toString();
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return delegate.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends TemplateOptions> T as(Class<T> clazz) {
|
||||
return delegate.as(clazz);
|
||||
}
|
||||
@Override
|
||||
public <T extends TemplateOptions> T as(Class<T> clazz) {
|
||||
return delegate.as(clazz);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TemplateOptions authorizePublicKey(String publicKey) {
|
||||
return delegate.authorizePublicKey(publicKey);
|
||||
}
|
||||
@Override
|
||||
public TemplateOptions authorizePublicKey(String publicKey) {
|
||||
throw new IllegalArgumentException(
|
||||
"authorizePublicKey is immutable");
|
||||
}
|
||||
|
||||
@Override
|
||||
public TemplateOptions blockOnPort(int port, int seconds) {
|
||||
throw new IllegalArgumentException("port, seconds are immutable");
|
||||
}
|
||||
@Override
|
||||
public TemplateOptions blockUntilRunning(boolean blockUntilRunning) {
|
||||
throw new IllegalArgumentException("blockUntilRunning is immutable");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getInboundPorts() {
|
||||
return delegate.getInboundPorts();
|
||||
}
|
||||
@Override
|
||||
public TemplateOptions blockOnPort(int port, int seconds) {
|
||||
throw new IllegalArgumentException("port, seconds are immutable");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPort() {
|
||||
return delegate.getPort();
|
||||
}
|
||||
@Override
|
||||
public int[] getInboundPorts() {
|
||||
return delegate.getInboundPorts();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPrivateKey() {
|
||||
return delegate.getPrivateKey();
|
||||
}
|
||||
@Override
|
||||
public int getPort() {
|
||||
return delegate.getPort();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPublicKey() {
|
||||
return delegate.getPublicKey();
|
||||
}
|
||||
@Override
|
||||
public String getPrivateKey() {
|
||||
return delegate.getPrivateKey();
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getRunScript() {
|
||||
return delegate.getRunScript();
|
||||
}
|
||||
@Override
|
||||
public String getPublicKey() {
|
||||
return delegate.getPublicKey();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSeconds() {
|
||||
return delegate.getSeconds();
|
||||
}
|
||||
@Override
|
||||
public byte[] getRunScript() {
|
||||
return delegate.getRunScript();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TemplateOptions inboundPorts(int... ports) {
|
||||
throw new IllegalArgumentException("ports is immutable");
|
||||
}
|
||||
@Override
|
||||
public int getSeconds() {
|
||||
return delegate.getSeconds();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TemplateOptions installPrivateKey(String privateKey) {
|
||||
throw new IllegalArgumentException("privateKey is immutable");
|
||||
}
|
||||
@Override
|
||||
public boolean shouldBlockUntilRunning() {
|
||||
return delegate.shouldBlockUntilRunning();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isIncludeMetadata() {
|
||||
return delegate.isIncludeMetadata();
|
||||
}
|
||||
@Override
|
||||
public TemplateOptions inboundPorts(int... ports) {
|
||||
throw new IllegalArgumentException("ports is immutable");
|
||||
}
|
||||
|
||||
@Override
|
||||
public TemplateOptions runScript(byte[] script) {
|
||||
throw new IllegalArgumentException("withMetadata is immutable");
|
||||
}
|
||||
@Override
|
||||
public TemplateOptions installPrivateKey(String privateKey) {
|
||||
throw new IllegalArgumentException("privateKey is immutable");
|
||||
}
|
||||
|
||||
@Override
|
||||
public TemplateOptions withMetadata() {
|
||||
throw new IllegalArgumentException("withMetadata is immutable");
|
||||
}
|
||||
@Override
|
||||
public boolean isIncludeMetadata() {
|
||||
return delegate.isIncludeMetadata();
|
||||
}
|
||||
|
||||
}
|
||||
@Override
|
||||
public TemplateOptions runScript(byte[] script) {
|
||||
throw new IllegalArgumentException("withMetadata is immutable");
|
||||
}
|
||||
|
||||
protected int[] inboundPorts = new int[] { 22 };
|
||||
@Override
|
||||
public TemplateOptions withMetadata() {
|
||||
throw new IllegalArgumentException("withMetadata is immutable");
|
||||
}
|
||||
|
||||
protected byte[] script;
|
||||
}
|
||||
|
||||
protected String privateKey;
|
||||
protected int[] inboundPorts = new int[] { 22 };
|
||||
|
||||
protected String publicKey;
|
||||
protected byte[] script;
|
||||
|
||||
protected int port = -1;
|
||||
protected String privateKey;
|
||||
|
||||
protected int seconds = -1;
|
||||
protected String publicKey;
|
||||
|
||||
protected boolean includeMetadata;
|
||||
protected int port = -1;
|
||||
|
||||
public int getPort() {
|
||||
return port;
|
||||
}
|
||||
protected int seconds = -1;
|
||||
|
||||
public int getSeconds() {
|
||||
return seconds;
|
||||
}
|
||||
protected boolean includeMetadata;
|
||||
|
||||
public int[] getInboundPorts() {
|
||||
return inboundPorts;
|
||||
}
|
||||
protected boolean blockUntilRunning = true;
|
||||
|
||||
public byte[] getRunScript() {
|
||||
return script;
|
||||
}
|
||||
public int getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
public String getPrivateKey() {
|
||||
return privateKey;
|
||||
}
|
||||
public int getSeconds() {
|
||||
return seconds;
|
||||
}
|
||||
|
||||
public String getPublicKey() {
|
||||
return publicKey;
|
||||
}
|
||||
public int[] getInboundPorts() {
|
||||
return inboundPorts;
|
||||
}
|
||||
|
||||
public boolean isIncludeMetadata() {
|
||||
return includeMetadata;
|
||||
}
|
||||
public byte[] getRunScript() {
|
||||
return script;
|
||||
}
|
||||
|
||||
public <T extends TemplateOptions> T as(Class<T> clazz) {
|
||||
return clazz.cast(this);
|
||||
}
|
||||
public String getPrivateKey() {
|
||||
return privateKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* When the node is started, wait until the following port is active
|
||||
*/
|
||||
public TemplateOptions blockOnPort(int port, int seconds) {
|
||||
checkArgument(port > 0 && port < 65536, "port must be a positive integer < 65535");
|
||||
checkArgument(seconds > 0, "seconds must be a positive integer");
|
||||
this.port = port;
|
||||
this.seconds = seconds;
|
||||
return this;
|
||||
}
|
||||
public String getPublicKey() {
|
||||
return publicKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* This script will be executed as the root user upon system startup. This script gets a
|
||||
* prologue, so no #!/bin/bash required, path set up, etc
|
||||
*/
|
||||
public TemplateOptions runScript(byte[] script) {
|
||||
checkArgument(checkNotNull(script, "script").length <= 16 * 1024,
|
||||
"script cannot be larger than 16kb");
|
||||
this.script = script;
|
||||
return this;
|
||||
}
|
||||
public boolean isIncludeMetadata() {
|
||||
return includeMetadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* replaces the rsa ssh key used at login.
|
||||
*/
|
||||
public TemplateOptions installPrivateKey(String privateKey) {
|
||||
checkArgument(checkNotNull(privateKey, "privateKey").startsWith(
|
||||
"-----BEGIN RSA PRIVATE KEY-----"),
|
||||
"key should start with -----BEGIN RSA PRIVATE KEY-----");
|
||||
this.privateKey = privateKey;
|
||||
return this;
|
||||
}
|
||||
public boolean shouldBlockUntilRunning() {
|
||||
return blockUntilRunning;
|
||||
}
|
||||
|
||||
public TemplateOptions dontAuthorizePublicKey() {
|
||||
this.publicKey = null;
|
||||
return this;
|
||||
}
|
||||
public <T extends TemplateOptions> T as(Class<T> clazz) {
|
||||
return clazz.cast(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* authorized an rsa ssh key.
|
||||
*/
|
||||
public TemplateOptions authorizePublicKey(String publicKey) {
|
||||
checkArgument(checkNotNull(publicKey, "publicKey").startsWith("ssh-rsa"),
|
||||
"key should start with ssh-rsa");
|
||||
this.publicKey = publicKey;
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* When the node is started, wait until the following port is active
|
||||
*/
|
||||
public TemplateOptions blockOnPort(int port, int seconds) {
|
||||
checkArgument(port > 0 && port < 65536,
|
||||
"port must be a positive integer < 65535");
|
||||
checkArgument(seconds > 0, "seconds must be a positive integer");
|
||||
this.port = port;
|
||||
this.seconds = seconds;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the set of ports to public access.
|
||||
*/
|
||||
public TemplateOptions inboundPorts(int... ports) {
|
||||
for (int port : ports)
|
||||
checkArgument(port > 0 && port < 65536, "port must be a positive integer < 65535");
|
||||
this.inboundPorts = ports;
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* This script will be executed as the root user upon system startup. This
|
||||
* script gets a prologue, so no #!/bin/bash required, path set up, etc
|
||||
*/
|
||||
public TemplateOptions runScript(byte[] script) {
|
||||
checkArgument(checkNotNull(script, "script").length <= 16 * 1024,
|
||||
"script cannot be larger than 16kb");
|
||||
this.script = script;
|
||||
return this;
|
||||
}
|
||||
|
||||
public TemplateOptions withMetadata() {
|
||||
this.includeMetadata = true;
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* replaces the rsa ssh key used at login.
|
||||
*/
|
||||
public TemplateOptions installPrivateKey(String privateKey) {
|
||||
checkArgument(checkNotNull(privateKey, "privateKey").startsWith(
|
||||
"-----BEGIN RSA PRIVATE KEY-----"),
|
||||
"key should start with -----BEGIN RSA PRIVATE KEY-----");
|
||||
this.privateKey = privateKey;
|
||||
return this;
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
public TemplateOptions dontAuthorizePublicKey() {
|
||||
this.publicKey = null;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see TemplateOptions#inboundPorts
|
||||
*/
|
||||
public static TemplateOptions inboundPorts(int... ports) {
|
||||
TemplateOptions options = new TemplateOptions();
|
||||
return options.inboundPorts(ports);
|
||||
}
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see TemplateOptions#port
|
||||
*/
|
||||
public static TemplateOptions blockOnPort(int port, int seconds) {
|
||||
TemplateOptions options = new TemplateOptions();
|
||||
return options.blockOnPort(port, seconds);
|
||||
}
|
||||
/**
|
||||
* authorized an rsa ssh key.
|
||||
*/
|
||||
public TemplateOptions authorizePublicKey(String publicKey) {
|
||||
checkArgument(checkNotNull(publicKey, "publicKey")
|
||||
.startsWith("ssh-rsa"), "key should start with ssh-rsa");
|
||||
this.publicKey = publicKey;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see TemplateOptions#runScript
|
||||
*/
|
||||
public static TemplateOptions runScript(byte[] script) {
|
||||
TemplateOptions options = new TemplateOptions();
|
||||
return options.runScript(script);
|
||||
}
|
||||
/**
|
||||
* Opens the set of ports to public access.
|
||||
*/
|
||||
public TemplateOptions inboundPorts(int... ports) {
|
||||
for (int port : ports)
|
||||
checkArgument(port > 0 && port < 65536,
|
||||
"port must be a positive integer < 65535");
|
||||
this.inboundPorts = ports;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see TemplateOptions#installPrivateKey
|
||||
*/
|
||||
public static TemplateOptions installPrivateKey(String rsaKey) {
|
||||
TemplateOptions options = new TemplateOptions();
|
||||
return options.installPrivateKey(rsaKey);
|
||||
}
|
||||
public TemplateOptions withMetadata() {
|
||||
this.includeMetadata = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see TemplateOptions#authorizePublicKey
|
||||
*/
|
||||
public static TemplateOptions authorizePublicKey(String rsaKey) {
|
||||
TemplateOptions options = new TemplateOptions();
|
||||
return options.authorizePublicKey(rsaKey);
|
||||
}
|
||||
public static class Builder {
|
||||
|
||||
public static TemplateOptions withDetails() {
|
||||
TemplateOptions options = new TemplateOptions();
|
||||
return options.withMetadata();
|
||||
}
|
||||
/**
|
||||
* @see TemplateOptions#inboundPorts
|
||||
*/
|
||||
public static TemplateOptions inboundPorts(int... ports) {
|
||||
TemplateOptions options = new TemplateOptions();
|
||||
return options.inboundPorts(ports);
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* @see TemplateOptions#port
|
||||
*/
|
||||
public static TemplateOptions blockOnPort(int port, int seconds) {
|
||||
TemplateOptions options = new TemplateOptions();
|
||||
return options.blockOnPort(port, seconds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TemplateOptions [inboundPorts=" + Arrays.toString(inboundPorts) + ", privateKey="
|
||||
+ (privateKey != null) + ", publicKey=" + (publicKey != null) + ", runScript="
|
||||
+ (script != null) + ", port:seconds=" + port + ":" + seconds
|
||||
+ ", metadata/details: " + includeMetadata + "]";
|
||||
}
|
||||
/**
|
||||
* @see TemplateOptions#blockUntilRunning
|
||||
*/
|
||||
public static TemplateOptions blockUntilRunning(
|
||||
boolean blockUntilRunning) {
|
||||
TemplateOptions options = new TemplateOptions();
|
||||
return options.blockUntilRunning(blockUntilRunning);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + Arrays.hashCode(inboundPorts);
|
||||
result = prime * result + (includeMetadata ? 1231 : 1237);
|
||||
result = prime * result + port;
|
||||
result = prime * result + ((privateKey == null) ? 0 : privateKey.hashCode());
|
||||
result = prime * result + ((publicKey == null) ? 0 : publicKey.hashCode());
|
||||
result = prime * result + Arrays.hashCode(script);
|
||||
result = prime * result + seconds;
|
||||
return result;
|
||||
}
|
||||
/**
|
||||
* @see TemplateOptions#runScript
|
||||
*/
|
||||
public static TemplateOptions runScript(byte[] script) {
|
||||
TemplateOptions options = new TemplateOptions();
|
||||
return options.runScript(script);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
TemplateOptions other = (TemplateOptions) obj;
|
||||
if (!Arrays.equals(inboundPorts, other.inboundPorts))
|
||||
return false;
|
||||
if (includeMetadata != other.includeMetadata)
|
||||
return false;
|
||||
if (port != other.port)
|
||||
return false;
|
||||
if (privateKey == null) {
|
||||
if (other.privateKey != null)
|
||||
return false;
|
||||
} else if (!privateKey.equals(other.privateKey))
|
||||
return false;
|
||||
if (publicKey == null) {
|
||||
if (other.publicKey != null)
|
||||
return false;
|
||||
} else if (!publicKey.equals(other.publicKey))
|
||||
return false;
|
||||
if (!Arrays.equals(script, other.script))
|
||||
return false;
|
||||
if (seconds != other.seconds)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* @see TemplateOptions#installPrivateKey
|
||||
*/
|
||||
public static TemplateOptions installPrivateKey(String rsaKey) {
|
||||
TemplateOptions options = new TemplateOptions();
|
||||
return options.installPrivateKey(rsaKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see TemplateOptions#authorizePublicKey
|
||||
*/
|
||||
public static TemplateOptions authorizePublicKey(String rsaKey) {
|
||||
TemplateOptions options = new TemplateOptions();
|
||||
return options.authorizePublicKey(rsaKey);
|
||||
}
|
||||
|
||||
public static TemplateOptions withDetails() {
|
||||
TemplateOptions options = new TemplateOptions();
|
||||
return options.withMetadata();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TemplateOptions [inboundPorts=" + Arrays.toString(inboundPorts)
|
||||
+ ", privateKey=" + (privateKey != null) + ", publicKey="
|
||||
+ (publicKey != null) + ", runScript=" + (script != null)
|
||||
+ ", blockUntilRunning=" + blockUntilRunning
|
||||
+ ", port:seconds=" + port + ":" + seconds
|
||||
+ ", metadata/details: " + includeMetadata + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + (blockUntilRunning ? 1231 : 1237);
|
||||
result = prime * result + Arrays.hashCode(inboundPorts);
|
||||
result = prime * result + (includeMetadata ? 1231 : 1237);
|
||||
result = prime * result + port;
|
||||
result = prime * result
|
||||
+ ((privateKey == null) ? 0 : privateKey.hashCode());
|
||||
result = prime * result
|
||||
+ ((publicKey == null) ? 0 : publicKey.hashCode());
|
||||
result = prime * result + Arrays.hashCode(script);
|
||||
result = prime * result + seconds;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
TemplateOptions other = (TemplateOptions) obj;
|
||||
if (blockUntilRunning != other.blockUntilRunning)
|
||||
return false;
|
||||
if (!Arrays.equals(inboundPorts, other.inboundPorts))
|
||||
return false;
|
||||
if (includeMetadata != other.includeMetadata)
|
||||
return false;
|
||||
if (port != other.port)
|
||||
return false;
|
||||
if (privateKey == null) {
|
||||
if (other.privateKey != null)
|
||||
return false;
|
||||
} else if (!privateKey.equals(other.privateKey))
|
||||
return false;
|
||||
if (publicKey == null) {
|
||||
if (other.publicKey != null)
|
||||
return false;
|
||||
} else if (!publicKey.equals(other.publicKey))
|
||||
return false;
|
||||
if (!Arrays.equals(script, other.script))
|
||||
return false;
|
||||
if (seconds != other.seconds)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
* tag to match the items
|
||||
|
@ -121,7 +121,7 @@ public class NodePredicates {
|
|||
/**
|
||||
* Match nodes with State == RUNNING
|
||||
*/
|
||||
public static final Predicate<NodeMetadata> ACTIVE = new Predicate<NodeMetadata>() {
|
||||
public static final Predicate<NodeMetadata> RUNNING = new Predicate<NodeMetadata>() {
|
||||
@Override
|
||||
public boolean apply(NodeMetadata nodeMetadata) {
|
||||
return nodeMetadata.getState() == NodeState.RUNNING;
|
||||
|
@ -129,12 +129,12 @@ public class NodePredicates {
|
|||
|
||||
@Override
|
||||
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>() {
|
||||
@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;
|
||||
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
|
@ -26,5 +31,28 @@ public interface ComputeServiceConstants {
|
|||
|
||||
public static final String COMPUTE_LOGGER = "jclouds.compute";
|
||||
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;
|
||||
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
|
||||
/**
|
||||
* terminates the node and blocks until it is no longer visible or in the state TERMINATED. If this
|
||||
* is the last node in a tagset, incidental resources are also destroyed.
|
||||
* terminates the node
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
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;
|
||||
|
||||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
@Singleton
|
||||
public class EncodeTagIntoNameRunNodesAndAddToSetStrategy implements RunNodesAndAddToSetStrategy {
|
||||
public class EncodeTagIntoNameRunNodesAndAddToSetStrategy implements
|
||||
RunNodesAndAddToSetStrategy {
|
||||
@Resource
|
||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||
protected Logger logger = Logger.NULL;
|
||||
|
@ -67,9 +68,11 @@ public class EncodeTagIntoNameRunNodesAndAddToSetStrategy implements RunNodesAnd
|
|||
|
||||
@Inject
|
||||
protected EncodeTagIntoNameRunNodesAndAddToSetStrategy(
|
||||
AddNodeWithTagStrategy addNodeWithTagStrategy, ListNodesStrategy listNodesStrategy,
|
||||
@Named("NAMING_CONVENTION") String nodeNamingConvention, ComputeUtils utils,
|
||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) {
|
||||
AddNodeWithTagStrategy addNodeWithTagStrategy,
|
||||
ListNodesStrategy listNodesStrategy,
|
||||
@Named("NAMING_CONVENTION") String nodeNamingConvention,
|
||||
ComputeUtils utils,
|
||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) {
|
||||
this.addNodeWithTagStrategy = addNodeWithTagStrategy;
|
||||
this.listNodesStrategy = listNodesStrategy;
|
||||
this.nodeNamingConvention = nodeNamingConvention;
|
||||
|
@ -78,51 +81,51 @@ public class EncodeTagIntoNameRunNodesAndAddToSetStrategy implements RunNodesAnd
|
|||
}
|
||||
|
||||
/**
|
||||
* This implementation gets a list of acceptable node names to encode the tag into, then it
|
||||
* simultaneously runs the nodes and applies options to them.
|
||||
* This implementation gets a list of acceptable node names to encode the tag
|
||||
* into, then it simultaneously runs the nodes and applies options to them.
|
||||
*/
|
||||
@Override
|
||||
public Map<?, ListenableFuture<Void>> execute(final String tag, final int count,
|
||||
final Template template, final Set<NodeMetadata> nodes,
|
||||
final Map<NodeMetadata, Exception> badNodes) {
|
||||
public Map<?, ListenableFuture<Void>> execute(final String tag,
|
||||
final int count, final Template template,
|
||||
final Set<NodeMetadata> nodes,
|
||||
final Map<NodeMetadata, Exception> badNodes) {
|
||||
Map<String, ListenableFuture<Void>> responses = Maps.newHashMap();
|
||||
for (final String name : getNextNames(tag, template, count)) {
|
||||
responses.put(name, makeListenable(executor.submit(new Callable<Void>() {
|
||||
@Override
|
||||
public Void call() throws Exception {
|
||||
NodeMetadata node = null;
|
||||
logger.debug(">> starting node(%s) tag(%s)", name, tag);
|
||||
node = addNodeWithTagStrategy.execute(tag, name, template);
|
||||
logger.debug("<< running node(%s)", node.getProviderId());
|
||||
try {
|
||||
utils.runOptionsOnNode(node, template.getOptions());
|
||||
logger.debug("<< options applied node(%s)", node.getProviderId());
|
||||
nodes.add(node);
|
||||
} catch (Exception e) {
|
||||
logger.error(e, "<< error applying options (%s) on node (%s)", template
|
||||
.getOptions(), node.getProviderId());
|
||||
badNodes.put(node, e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}), executor));
|
||||
responses.put(name, makeListenable(executor
|
||||
.submit(new Callable<Void>() {
|
||||
@Override
|
||||
public Void call() throws Exception {
|
||||
NodeMetadata node = null;
|
||||
logger.debug(">> starting node(%s) tag(%s)", name, tag);
|
||||
node = addNodeWithTagStrategy.execute(tag, name, template);
|
||||
logger.debug("<< %s node(%s)", node.getState(), node
|
||||
.getId());
|
||||
utils
|
||||
.runOptionsOnNodeAndAddToGoodSetOrPutExceptionIntoBadMap(
|
||||
node, badNodes, nodes, template.getOptions())
|
||||
.call();
|
||||
return null;
|
||||
}
|
||||
}), executor));
|
||||
}
|
||||
return responses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the next node names that can be used. These will be derived from the tag and the
|
||||
* template. We will pre-allocate a specified quantity, and attempt to verify that there is no
|
||||
* name conflict with the current service.
|
||||
* Find the next node names that can be used. These will be derived from the
|
||||
* tag and the template. We will pre-allocate a specified quantity, and
|
||||
* attempt to verify that there is no name conflict with the current service.
|
||||
*
|
||||
* @param tag
|
||||
* @param count
|
||||
* @param template
|
||||
* @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();
|
||||
Iterable<? extends ComputeMetadata> currentNodes = listNodesStrategy.list();
|
||||
Iterable<? extends ComputeMetadata> currentNodes = listNodesStrategy
|
||||
.list();
|
||||
int maxTries = 100;
|
||||
int currentTries = 0;
|
||||
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
|
||||
* naming convention.
|
||||
* This implementation will pass the tag and a hex formatted random number to
|
||||
* the configured naming convention.
|
||||
*
|
||||
*/
|
||||
protected String getNextName(final String tag, final Template template) {
|
||||
return String.format(nodeNamingConvention, tag, Integer.toHexString(new SecureRandom()
|
||||
.nextInt(4095)));
|
||||
return String.format(nodeNamingConvention, tag, Integer
|
||||
.toHexString(new SecureRandom().nextInt(4095)));
|
||||
}
|
||||
|
||||
}
|
|
@ -28,7 +28,7 @@ import java.util.Set;
|
|||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
@ -39,6 +39,7 @@ import javax.inject.Singleton;
|
|||
import org.jclouds.Constants;
|
||||
import org.jclouds.compute.ComputeServiceContext;
|
||||
import org.jclouds.compute.LoadBalancerService;
|
||||
import org.jclouds.compute.config.ComputeServiceTimeoutsModule;
|
||||
import org.jclouds.compute.domain.Architecture;
|
||||
import org.jclouds.compute.domain.ComputeMetadata;
|
||||
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.internal.ComputeServiceContextImpl;
|
||||
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.DestroyNodeStrategy;
|
||||
import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
|
||||
|
@ -66,14 +65,12 @@ import org.jclouds.domain.LocationScope;
|
|||
import org.jclouds.domain.internal.LocationImpl;
|
||||
import org.jclouds.lifecycle.Closer;
|
||||
import org.jclouds.net.IPSocket;
|
||||
import org.jclouds.predicates.RetryablePredicate;
|
||||
import org.jclouds.predicates.SocketOpen;
|
||||
import org.jclouds.rest.ResourceNotFoundException;
|
||||
import org.jclouds.rest.RestContext;
|
||||
import org.jclouds.rest.internal.RestContextImpl;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
@ -140,7 +137,7 @@ public class StubComputeServiceContextModule extends AbstractModule {
|
|||
|
||||
@Inject
|
||||
public StubSocketOpen(ConcurrentMap<Integer, StubNodeMetadata> nodes,
|
||||
@Named("PUBLIC_IP_PREFIX") String publicIpPrefix) {
|
||||
@Named("PUBLIC_IP_PREFIX") String publicIpPrefix) {
|
||||
this.nodes = nodes;
|
||||
this.publicIpPrefix = publicIpPrefix;
|
||||
}
|
||||
|
@ -161,8 +158,8 @@ public class StubComputeServiceContextModule extends AbstractModule {
|
|||
@Provides
|
||||
@Singleton
|
||||
RestContext<ConcurrentMap, ConcurrentMap> provideRestContext(Closer closer) {
|
||||
return new RestContextImpl<ConcurrentMap, ConcurrentMap>(closer, nodes, nodes, URI
|
||||
.create("http://stub"), System.getProperty("user.name"));
|
||||
return new RestContextImpl<ConcurrentMap, ConcurrentMap>(closer, nodes,
|
||||
nodes, URI.create("http://stub"), System.getProperty("user.name"));
|
||||
}
|
||||
|
||||
// NORMAL STUFF
|
||||
|
@ -175,21 +172,19 @@ public class StubComputeServiceContextModule extends AbstractModule {
|
|||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
protected void configure() {
|
||||
install(new ComputeServiceTimeoutsModule());
|
||||
bind(new TypeLiteral<ComputeServiceContext>() {
|
||||
}).to(new TypeLiteral<ComputeServiceContextImpl<ConcurrentMap, ConcurrentMap>>() {
|
||||
}).in(Scopes.SINGLETON);
|
||||
})
|
||||
.to(
|
||||
new TypeLiteral<ComputeServiceContextImpl<ConcurrentMap, ConcurrentMap>>() {
|
||||
}).in(Scopes.SINGLETON);
|
||||
bind(AddNodeWithTagStrategy.class).to(StubAddNodeWithTagStrategy.class);
|
||||
bind(ListNodesStrategy.class).to(StubListNodesStrategy.class);
|
||||
bind(GetNodeMetadataStrategy.class).to(StubGetNodeMetadataStrategy.class);
|
||||
bind(RebootNodeStrategy.class).to(StubRebootNodeStrategy.class);
|
||||
bind(DestroyNodeStrategy.class).to(StubDestroyNodeStrategy.class);
|
||||
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);
|
||||
bind(LoadBalancerService.class).toProvider(
|
||||
Providers.<LoadBalancerService> of(null));
|
||||
}
|
||||
|
||||
@Provides
|
||||
|
@ -205,12 +200,14 @@ public class StubComputeServiceContextModule extends AbstractModule {
|
|||
private NodeState state;
|
||||
private final ExecutorService service;
|
||||
|
||||
public StubNodeMetadata(String providerId, String name, String id, Location location,
|
||||
URI uri, Map<String, String> userMetadata, String tag, Image image, NodeState state,
|
||||
Iterable<String> publicAddresses, Iterable<String> privateAddresses,
|
||||
Map<String, String> extra, Credentials credentials, ExecutorService service) {
|
||||
super(providerId, name, id, location, uri, userMetadata, tag, image, state,
|
||||
publicAddresses, privateAddresses, extra, credentials);
|
||||
public StubNodeMetadata(String providerId, String name, String id,
|
||||
Location location, URI uri, Map<String, String> userMetadata,
|
||||
String tag, Image image, NodeState state,
|
||||
Iterable<String> publicAddresses,
|
||||
Iterable<String> privateAddresses, Map<String, String> extra,
|
||||
Credentials credentials, ExecutorService service) {
|
||||
super(providerId, name, id, location, uri, userMetadata, tag, image,
|
||||
state, publicAddresses, privateAddresses, extra, credentials);
|
||||
this.setState(state, 0);
|
||||
this.service = service;
|
||||
}
|
||||
|
@ -242,7 +239,8 @@ public class StubComputeServiceContextModule extends AbstractModule {
|
|||
}
|
||||
|
||||
@Singleton
|
||||
public static class StubAddNodeWithTagStrategy implements AddNodeWithTagStrategy {
|
||||
public static class StubAddNodeWithTagStrategy implements
|
||||
AddNodeWithTagStrategy {
|
||||
private final Location location;
|
||||
private final ExecutorService service;
|
||||
private final ConcurrentMap<Integer, StubNodeMetadata> nodes;
|
||||
|
@ -252,15 +250,16 @@ public class StubComputeServiceContextModule extends AbstractModule {
|
|||
private final String passwordPrefix;
|
||||
|
||||
@Inject
|
||||
public StubAddNodeWithTagStrategy(ConcurrentMap<Integer, StubNodeMetadata> nodes,
|
||||
Location location, @Named(Constants.PROPERTY_USER_THREADS) ExecutorService service,
|
||||
@Named("NODE_ID") Provider<Integer> idProvider,
|
||||
@Named("PUBLIC_IP_PREFIX") String publicIpPrefix,
|
||||
@Named("PRIVATE_IP_PREFIX") String privateIpPrefix,
|
||||
@Named("PASSWORD_PREFIX") String passwordPrefix) {
|
||||
public StubAddNodeWithTagStrategy(
|
||||
ConcurrentMap<Integer, StubNodeMetadata> nodes, Location location,
|
||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService service,
|
||||
@Named("NODE_ID") Provider<Integer> idProvider,
|
||||
@Named("PUBLIC_IP_PREFIX") String publicIpPrefix,
|
||||
@Named("PRIVATE_IP_PREFIX") String privateIpPrefix,
|
||||
@Named("PASSWORD_PREFIX") String passwordPrefix) {
|
||||
this.nodes = nodes;
|
||||
this.location = location;
|
||||
this.service = service;
|
||||
this.service = Executors.newCachedThreadPool();
|
||||
this.idProvider = idProvider;
|
||||
this.publicIpPrefix = publicIpPrefix;
|
||||
this.privateIpPrefix = privateIpPrefix;
|
||||
|
@ -269,27 +268,31 @@ public class StubComputeServiceContextModule extends AbstractModule {
|
|||
|
||||
@Override
|
||||
public NodeMetadata execute(String tag, String name, Template template) {
|
||||
checkArgument(location.equals(template.getLocation()), "invalid location: "
|
||||
+ template.getLocation());
|
||||
checkArgument(location.equals(template.getLocation()),
|
||||
"invalid location: " + template.getLocation());
|
||||
int id = idProvider.get();
|
||||
StubNodeMetadata node = new StubNodeMetadata(id + "", name, id + "", location, null,
|
||||
ImmutableMap.<String, String> of(), tag, template.getImage(), NodeState.PENDING,
|
||||
ImmutableSet.<String> of(publicIpPrefix + id), ImmutableSet
|
||||
.<String> of(privateIpPrefix + id), ImmutableMap.<String, String> of(),
|
||||
new Credentials("root", passwordPrefix + id), service);
|
||||
node.setState(NodeState.RUNNING, 100);
|
||||
StubNodeMetadata node = new StubNodeMetadata(id + "", name, id + "",
|
||||
location, null, ImmutableMap.<String, String> of(), tag,
|
||||
template.getImage(), NodeState.PENDING, ImmutableSet
|
||||
.<String> of(publicIpPrefix + id), ImmutableSet
|
||||
.<String> of(privateIpPrefix + id), ImmutableMap
|
||||
.<String, String> of(), new Credentials("root",
|
||||
passwordPrefix + id), service);
|
||||
nodes.put(id, node);
|
||||
node.setState(NodeState.RUNNING, 100);
|
||||
return node;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Singleton
|
||||
public static class StubGetNodeMetadataStrategy implements GetNodeMetadataStrategy {
|
||||
public static class StubGetNodeMetadataStrategy implements
|
||||
GetNodeMetadataStrategy {
|
||||
private final ConcurrentMap<Integer, StubNodeMetadata> nodes;
|
||||
|
||||
@Inject
|
||||
protected StubGetNodeMetadataStrategy(ConcurrentMap<Integer, StubNodeMetadata> nodes) {
|
||||
protected StubGetNodeMetadataStrategy(
|
||||
ConcurrentMap<Integer, StubNodeMetadata> nodes) {
|
||||
this.nodes = nodes;
|
||||
}
|
||||
|
||||
|
@ -304,7 +307,8 @@ public class StubComputeServiceContextModule extends AbstractModule {
|
|||
private final ConcurrentMap<Integer, StubNodeMetadata> nodes;
|
||||
|
||||
@Inject
|
||||
protected StubListNodesStrategy(ConcurrentMap<Integer, StubNodeMetadata> nodes) {
|
||||
protected StubListNodesStrategy(
|
||||
ConcurrentMap<Integer, StubNodeMetadata> nodes) {
|
||||
this.nodes = nodes;
|
||||
}
|
||||
|
||||
|
@ -315,7 +319,7 @@ public class StubComputeServiceContextModule extends AbstractModule {
|
|||
|
||||
@Override
|
||||
public Iterable<? extends NodeMetadata> listDetailsOnNodesMatching(
|
||||
Predicate<ComputeMetadata> filter) {
|
||||
Predicate<ComputeMetadata> filter) {
|
||||
return Iterables.filter(nodes.values(), filter);
|
||||
}
|
||||
}
|
||||
|
@ -325,18 +329,19 @@ public class StubComputeServiceContextModule extends AbstractModule {
|
|||
private final ConcurrentMap<Integer, StubNodeMetadata> nodes;
|
||||
|
||||
@Inject
|
||||
protected StubRebootNodeStrategy(ConcurrentMap<Integer, StubNodeMetadata> nodes) {
|
||||
protected StubRebootNodeStrategy(
|
||||
ConcurrentMap<Integer, StubNodeMetadata> nodes) {
|
||||
this.nodes = nodes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(String id) {
|
||||
public StubNodeMetadata execute(String id) {
|
||||
StubNodeMetadata node = nodes.get(Integer.parseInt(id));
|
||||
if (node == null)
|
||||
throw new ResourceNotFoundException("node not found: " + id);
|
||||
node.setState(NodeState.PENDING, 0);
|
||||
node.setState(NodeState.RUNNING, 50);
|
||||
return true;
|
||||
return node;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -346,18 +351,19 @@ public class StubComputeServiceContextModule extends AbstractModule {
|
|||
private final ExecutorService service;
|
||||
|
||||
@Inject
|
||||
protected StubDestroyNodeStrategy(ConcurrentMap<Integer, StubNodeMetadata> nodes,
|
||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService service) {
|
||||
protected StubDestroyNodeStrategy(
|
||||
ConcurrentMap<Integer, StubNodeMetadata> nodes,
|
||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService service) {
|
||||
this.nodes = nodes;
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(String id) {
|
||||
public StubNodeMetadata execute(String id) {
|
||||
final int nodeId = Integer.parseInt(id);
|
||||
StubNodeMetadata node = nodes.get(nodeId);
|
||||
if (node == null)
|
||||
return true;
|
||||
return node;
|
||||
node.setState(NodeState.PENDING, 0);
|
||||
node.setState(NodeState.TERMINATED, 50);
|
||||
service.execute(new Runnable() {
|
||||
|
@ -374,7 +380,7 @@ public class StubComputeServiceContextModule extends AbstractModule {
|
|||
}
|
||||
|
||||
});
|
||||
return true;
|
||||
return node;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -385,52 +391,49 @@ public class StubComputeServiceContextModule extends AbstractModule {
|
|||
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
|
||||
@Singleton
|
||||
protected Set<? extends Size> provideSizes() {
|
||||
return ImmutableSet.of(new StubSize("small", 1, 1740, 160, ImmutableSet
|
||||
.of(Architecture.X86_32)), new StubSize("medium", 4, 7680, 850, ImmutableSet
|
||||
.of(Architecture.X86_64)), new StubSize("large", 8, 15360, 1690, ImmutableSet
|
||||
.of(Architecture.X86_64)));
|
||||
.of(Architecture.X86_32)), new StubSize("medium", 4, 7680, 850,
|
||||
ImmutableSet.of(Architecture.X86_64)), new StubSize("large", 8,
|
||||
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 */
|
||||
private static final long serialVersionUID = -1842135761654973637L;
|
||||
|
||||
StubSize(String type, int cores, int ram, int disk,
|
||||
Iterable<Architecture> supportedArchitectures) {
|
||||
super(type, type, type, null, null, ImmutableMap.<String, String> of(), cores, ram, disk,
|
||||
architectureIn(supportedArchitectures));
|
||||
Iterable<Architecture> supportedArchitectures) {
|
||||
super(type, type, type, null, null,
|
||||
ImmutableMap.<String, String> of(), cores, ram, disk,
|
||||
architectureIn(supportedArchitectures));
|
||||
}
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
protected Set<? extends Image> provideImages(Location defaultLocation) {
|
||||
return ImmutableSet.of(new ImageImpl("1", OsFamily.UBUNTU.name(), "1", defaultLocation, null,
|
||||
ImmutableMap.<String, String> of(), "stub ubuntu 32", "", OsFamily.UBUNTU,
|
||||
"ubuntu 64", Architecture.X86_64, new Credentials("root", null)), new ImageImpl("2",
|
||||
OsFamily.UBUNTU.name(), "2", defaultLocation, null, ImmutableMap
|
||||
.<String, String> of(), "stub ubuntu 64", "", OsFamily.UBUNTU, "ubuntu 64",
|
||||
Architecture.X86_64, new Credentials("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)));
|
||||
return ImmutableSet.of(new ImageImpl("1", OsFamily.UBUNTU.name(), "1",
|
||||
defaultLocation, null, ImmutableMap.<String, String> of(),
|
||||
"stub ubuntu 32", "", OsFamily.UBUNTU, "ubuntu 64",
|
||||
Architecture.X86_64, new Credentials("root", null)), new ImageImpl(
|
||||
"2", OsFamily.UBUNTU.name(), "2", defaultLocation, null,
|
||||
ImmutableMap.<String, String> of(), "stub ubuntu 64", "",
|
||||
OsFamily.UBUNTU, "ubuntu 64", Architecture.X86_64, new Credentials(
|
||||
"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)));
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -48,6 +48,7 @@ import org.jclouds.compute.domain.internal.NodeMetadataImpl;
|
|||
import org.jclouds.compute.options.TemplateOptions;
|
||||
import org.jclouds.compute.predicates.ScriptStatusReturnsZero.CommandUsingClient;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
|
||||
import org.jclouds.concurrent.ConcurrentUtils;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.logging.Logger;
|
||||
|
@ -82,52 +83,61 @@ public class ComputeUtils {
|
|||
protected final Predicate<CommandUsingClient> runScriptNotRunning;
|
||||
private final Predicate<IPSocket> socketTester;
|
||||
private final ExecutorService executor;
|
||||
protected final Predicate<NodeMetadata> nodeRunning;
|
||||
private final GetNodeMetadataStrategy getNode;
|
||||
|
||||
@Inject
|
||||
public ComputeUtils(Predicate<IPSocket> socketTester,
|
||||
@Named("NOT_RUNNING") Predicate<CommandUsingClient> runScriptNotRunning,
|
||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) {
|
||||
public ComputeUtils(
|
||||
Predicate<IPSocket> socketTester,
|
||||
@Named("SCRIPT_COMPLETE") Predicate<CommandUsingClient> runScriptNotRunning,
|
||||
GetNodeMetadataStrategy getNode,
|
||||
@Named("NODE_RUNNING") Predicate<NodeMetadata> nodeRunning,
|
||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) {
|
||||
this.nodeRunning = nodeRunning;
|
||||
this.getNode = getNode;
|
||||
this.socketTester = socketTester;
|
||||
this.runScriptNotRunning = runScriptNotRunning;
|
||||
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");
|
||||
int index = 1;
|
||||
for (Entry<?, Exception> errorMessage : executionExceptions.entrySet()) {
|
||||
fmt.format("%s) %s on %s:%n%s%n%n", index++, errorMessage.getValue().getClass()
|
||||
.getSimpleName(), errorMessage.getKey(), Throwables
|
||||
.getStackTraceAsString(errorMessage.getValue()));
|
||||
fmt.format("%s) %s on %s:%n%s%n%n", index++, errorMessage.getValue()
|
||||
.getClass().getSimpleName(), errorMessage.getKey(), Throwables
|
||||
.getStackTraceAsString(errorMessage.getValue()));
|
||||
}
|
||||
return fmt.format("%s error[s]", executionExceptions.size()).toString();
|
||||
}
|
||||
|
||||
public Map<?, ListenableFuture<Void>> runOptionsOnNodesAndAddToGoodSetOrPutExceptionIntoBadMap(
|
||||
final TemplateOptions options, Iterable<NodeMetadata> runningNodes,
|
||||
final Set<NodeMetadata> goodNodes, final Map<NodeMetadata, Exception> badNodes) {
|
||||
final TemplateOptions options, Iterable<NodeMetadata> runningNodes,
|
||||
final Set<NodeMetadata> goodNodes,
|
||||
final Map<NodeMetadata, Exception> badNodes) {
|
||||
Map<NodeMetadata, ListenableFuture<Void>> responses = Maps.newHashMap();
|
||||
for (final NodeMetadata node : runningNodes) {
|
||||
responses.put(node, makeListenable(executor
|
||||
.submit(runOptionsOnNodeAndAddToGoodSetOrPutExceptionIntoBadMap(node, badNodes,
|
||||
goodNodes, options)), executor));
|
||||
.submit(runOptionsOnNodeAndAddToGoodSetOrPutExceptionIntoBadMap(
|
||||
node, badNodes, goodNodes, options)), executor));
|
||||
}
|
||||
return responses;
|
||||
}
|
||||
|
||||
public Callable<Void> runOptionsOnNodeAndAddToGoodSetOrPutExceptionIntoBadMap(
|
||||
final NodeMetadata node, final Map<NodeMetadata, Exception> badNodes,
|
||||
final Set<NodeMetadata> goodNodes, final TemplateOptions options) {
|
||||
final NodeMetadata node, final Map<NodeMetadata, Exception> badNodes,
|
||||
final Set<NodeMetadata> goodNodes, final TemplateOptions options) {
|
||||
return new Callable<Void>() {
|
||||
@Override
|
||||
public Void call() throws Exception {
|
||||
try {
|
||||
runOptionsOnNode(node, options);
|
||||
logger.debug("<< options applied node(%s)", node.getProviderId());
|
||||
goodNodes.add(node);
|
||||
NodeMetadata node1 = runOptionsOnNode(node, options);
|
||||
logger.debug("<< options applied node(%s)", node1.getId());
|
||||
goodNodes.add(node1);
|
||||
} catch (Exception e) {
|
||||
logger.error(e, "<< problem applying options to node(%s): ", node.getProviderId(),
|
||||
Throwables.getRootCause(e).getMessage());
|
||||
logger.error(e, "<< problem applying options to node(%s): ",
|
||||
node.getId(), Throwables.getRootCause(e).getMessage());
|
||||
badNodes.put(node, e);
|
||||
}
|
||||
return null;
|
||||
|
@ -136,19 +146,21 @@ public class ComputeUtils {
|
|||
}
|
||||
|
||||
public static String createNodeErrorMessage(
|
||||
Map<? extends NodeMetadata, ? extends Throwable> failedNodes) {
|
||||
Map<? extends NodeMetadata, ? extends Throwable> failedNodes) {
|
||||
Formatter fmt = new Formatter().format("Node failures:%n%n");
|
||||
int index = 1;
|
||||
for (Entry<? extends NodeMetadata, ? extends Throwable> errorMessage : failedNodes.entrySet()) {
|
||||
fmt.format("%s) %s on node %s:%n%s%n%n", index++, errorMessage.getValue().getClass()
|
||||
.getSimpleName(), errorMessage.getKey().getProviderId(), Throwables
|
||||
.getStackTraceAsString(errorMessage.getValue()));
|
||||
for (Entry<? extends NodeMetadata, ? extends Throwable> errorMessage : failedNodes
|
||||
.entrySet()) {
|
||||
fmt.format("%s) %s on node %s:%n%s%n%n", index++, errorMessage
|
||||
.getValue().getClass().getSimpleName(), errorMessage.getKey()
|
||||
.getId(), Throwables.getStackTraceAsString(errorMessage
|
||||
.getValue()));
|
||||
}
|
||||
return fmt.format("%s error[s]", failedNodes.size()).toString();
|
||||
}
|
||||
|
||||
public static Iterable<? extends ComputeMetadata> filterByName(
|
||||
Iterable<? extends ComputeMetadata> nodes, final String name) {
|
||||
Iterable<? extends ComputeMetadata> nodes, final String name) {
|
||||
return Iterables.filter(nodes, new Predicate<ComputeMetadata>() {
|
||||
@Override
|
||||
public boolean apply(ComputeMetadata input) {
|
||||
|
@ -157,67 +169,92 @@ 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();
|
||||
if (options.getRunScript() != null) {
|
||||
callables.add(runScriptOnNode(node, "runscript", options.getRunScript()));
|
||||
callables.add(runScriptOnNode(node, "runscript", options
|
||||
.getRunScript()));
|
||||
}
|
||||
if (options.getPublicKey() != null) {
|
||||
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) {
|
||||
runCallablesOnNode(node, callables, options.getPrivateKey() != null ? installKeyOnNode(
|
||||
node, options.getPrivateKey()) : null);
|
||||
runCallablesOnNode(node, callables,
|
||||
options.getPrivateKey() != null ? installKeyOnNode(node, options
|
||||
.getPrivateKey()) : null);
|
||||
}
|
||||
|
||||
if (options.getPort() > 0) {
|
||||
checkNodeHasPublicIps(node);
|
||||
blockUntilPortIsListeningOnPublicIp(options.getPort(), options.getSeconds(), Iterables
|
||||
.get(node.getPublicAddresses(), 0));
|
||||
blockUntilPortIsListeningOnPublicIp(options.getPort(), options
|
||||
.getSeconds(), Iterables.get(node.getPublicAddresses(), 0));
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
private void checkNodeHasPublicIps(NodeMetadata node) {
|
||||
checkState(node.getPublicAddresses().size() > 0,
|
||||
"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) {
|
||||
logger.debug(">> blocking on port %s:%d for %d seconds", inetAddress, port, seconds);
|
||||
RetryablePredicate<IPSocket> tester = new RetryablePredicate<IPSocket>(socketTester, seconds,
|
||||
1, TimeUnit.SECONDS);
|
||||
private void blockUntilPortIsListeningOnPublicIp(int port, int seconds,
|
||||
String inetAddress) {
|
||||
logger.debug(">> blocking on port %s:%d for %d seconds", inetAddress,
|
||||
port, seconds);
|
||||
RetryablePredicate<IPSocket> tester = new RetryablePredicate<IPSocket>(
|
||||
socketTester, seconds, 1, TimeUnit.SECONDS);
|
||||
IPSocket socket = new IPSocket(inetAddress, port);
|
||||
boolean passed = tester.apply(socket);
|
||||
if (passed)
|
||||
logger.debug("<< port %s:%d opened", inetAddress, port);
|
||||
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);
|
||||
}
|
||||
|
||||
public AuthorizeRSAPublicKey authorizeKeyOnNode(NodeMetadata node, String publicKey) {
|
||||
public AuthorizeRSAPublicKey authorizeKeyOnNode(NodeMetadata node,
|
||||
String 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);
|
||||
}
|
||||
|
||||
public RunScriptOnNode runScriptOnNodeAsDefaultUser(NodeMetadata node, String scriptName,
|
||||
byte[] script) {
|
||||
return new RunScriptOnNode(runScriptNotRunning, node, scriptName, script, false);
|
||||
public RunScriptOnNode runScriptOnNodeAsDefaultUser(NodeMetadata node,
|
||||
String scriptName, byte[] script) {
|
||||
return new RunScriptOnNode(runScriptNotRunning, node, scriptName, script,
|
||||
false);
|
||||
}
|
||||
|
||||
public Map<SshCallable<?>, ?> runCallablesOnNode(NodeMetadata node,
|
||||
Iterable<? extends SshCallable<?>> parallel, @Nullable SshCallable<?> last) {
|
||||
checkState(this.sshFactory != null, "runScript requested, but no SshModule configured");
|
||||
Iterable<? extends SshCallable<?>> parallel,
|
||||
@Nullable SshCallable<?> last) {
|
||||
checkState(this.sshFactory != null,
|
||||
"runScript requested, but no SshModule configured");
|
||||
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);
|
||||
try {
|
||||
ssh.connect();
|
||||
|
@ -229,7 +266,8 @@ public class ComputeUtils {
|
|||
}
|
||||
|
||||
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();
|
||||
if (Iterables.size(parallel) > 0) {
|
||||
responses.putAll(runCallablesUsingSshClient(parallel, ssh));
|
||||
|
@ -246,37 +284,42 @@ public class ComputeUtils {
|
|||
}
|
||||
|
||||
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);
|
||||
SshClient ssh = isKeyAuth(node) ? sshFactory.create(socket, node.getCredentials().account,
|
||||
node.getCredentials().key.getBytes()) : sshFactory.create(socket, node
|
||||
.getCredentials().account, node.getCredentials().key);
|
||||
SshClient ssh = isKeyAuth(node) ? sshFactory.create(socket, node
|
||||
.getCredentials().account, node.getCredentials().key.getBytes())
|
||||
: sshFactory.create(socket, node.getCredentials().account, node
|
||||
.getCredentials().key);
|
||||
return ssh;
|
||||
}
|
||||
|
||||
private Map<SshCallable<?>, Object> runCallablesUsingSshClient(
|
||||
Iterable<? extends SshCallable<?>> parallel, SshClient ssh) {
|
||||
Map<SshCallable<?>, ListenableFuture<?>> parallelResponses = Maps.newHashMap();
|
||||
Iterable<? extends SshCallable<?>> parallel, SshClient ssh) {
|
||||
Map<SshCallable<?>, ListenableFuture<?>> parallelResponses = Maps
|
||||
.newHashMap();
|
||||
|
||||
for (SshCallable<?> callable : parallel) {
|
||||
callable.setConnection(ssh, logger);
|
||||
parallelResponses.put(callable, ConcurrentUtils.makeListenable(executor.submit(callable),
|
||||
executor));
|
||||
parallelResponses.put(callable, ConcurrentUtils.makeListenable(
|
||||
executor.submit(callable), executor));
|
||||
}
|
||||
|
||||
Map<SshCallable<?>, Exception> exceptions = awaitCompletion(parallelResponses, executor,
|
||||
null, logger, "ssh");
|
||||
Map<SshCallable<?>, Exception> exceptions = awaitCompletion(
|
||||
parallelResponses, executor, null, logger, "ssh");
|
||||
if (exceptions.size() > 0)
|
||||
throw new RuntimeException(String.format("error invoking callables on nodes: %s",
|
||||
exceptions));
|
||||
throw new RuntimeException(String.format(
|
||||
"error invoking callables on nodes: %s", exceptions));
|
||||
Map<SshCallable<?>, Object> newresponses = transform(parallelResponses);
|
||||
return newresponses;
|
||||
}
|
||||
|
||||
@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();
|
||||
for (Map.Entry<SshCallable<?>, ListenableFuture<?>> entry : responses.entrySet()) {
|
||||
for (Map.Entry<SshCallable<?>, ListenableFuture<?>> entry : responses
|
||||
.entrySet()) {
|
||||
try {
|
||||
actualResponses.put(entry.getKey(), (T) entry.getValue().get());
|
||||
} catch (InterruptedException e) {
|
||||
|
@ -303,20 +346,24 @@ public class ComputeUtils {
|
|||
private final boolean runAsRoot;
|
||||
private Logger logger = Logger.NULL;
|
||||
|
||||
RunScriptOnNode(@Named("NOT_RUNNING") Predicate<CommandUsingClient> runScriptNotRunning,
|
||||
NodeMetadata node, String scriptName, byte[] script) {
|
||||
RunScriptOnNode(
|
||||
@Named("SCRIPT_COMPLETE") Predicate<CommandUsingClient> runScriptNotRunning,
|
||||
NodeMetadata node, String scriptName, byte[] script) {
|
||||
this(runScriptNotRunning, node, scriptName, script, true);
|
||||
}
|
||||
|
||||
RunScriptOnNode(@Named("NOT_RUNNING") Predicate<CommandUsingClient> runScriptNotRunning,
|
||||
NodeMetadata node, String scriptName, byte[] script, boolean runAsRoot) {
|
||||
RunScriptOnNode(
|
||||
@Named("SCRIPT_COMPLETE") Predicate<CommandUsingClient> runScriptNotRunning,
|
||||
NodeMetadata node, String scriptName, byte[] script,
|
||||
boolean runAsRoot) {
|
||||
this.runScriptNotRunning = runScriptNotRunning;
|
||||
this.node = checkNotNull(node, "node");
|
||||
this.scriptName = checkNotNull(scriptName, "scriptName");
|
||||
this.script = new InitBuilder(scriptName, "/tmp/" + scriptName, "/tmp/" + scriptName,
|
||||
ImmutableMap.<String, String> of(), Iterables.toArray(Splitter.on("\n").split(
|
||||
new String(checkNotNull(script, "script"))), String.class)).build(
|
||||
OsFamily.UNIX).getBytes();
|
||||
this.script = new InitBuilder(scriptName, "/tmp/" + scriptName,
|
||||
"/tmp/" + scriptName, ImmutableMap.<String, String> of(),
|
||||
Iterables.toArray(Splitter.on("\n").split(
|
||||
new String(checkNotNull(script, "script"))), String.class))
|
||||
.build(OsFamily.UNIX).getBytes();
|
||||
this.runAsRoot = runAsRoot;
|
||||
}
|
||||
|
||||
|
@ -330,15 +377,18 @@ public class ComputeUtils {
|
|||
returnVal = runScriptAsRoot();
|
||||
else
|
||||
returnVal = runScriptAsDefaultUser();
|
||||
runScriptNotRunning.apply(new CommandUsingClient("./" + scriptName + " status", ssh));
|
||||
runScriptNotRunning.apply(new CommandUsingClient("./" + scriptName
|
||||
+ " status", ssh));
|
||||
logger.debug("<< complete(%d)", returnVal.getExitCode());
|
||||
if (logger.isDebugEnabled() || returnVal.getExitCode() != 0) {
|
||||
logger.debug("<< stdout from %s as %s@%s\n%s", scriptName,
|
||||
node.getCredentials().account, Iterables.get(node.getPublicAddresses(), 0),
|
||||
ssh.exec("./" + scriptName + " tail").getOutput());
|
||||
logger.debug("<< stderr from %s as %s@%s\n%s", scriptName,
|
||||
node.getCredentials().account, Iterables.get(node.getPublicAddresses(), 0),
|
||||
ssh.exec("./" + scriptName + " tailerr").getOutput());
|
||||
logger.debug("<< stdout from %s as %s@%s\n%s", scriptName, node
|
||||
.getCredentials().account, Iterables.get(node
|
||||
.getPublicAddresses(), 0), ssh.exec(
|
||||
"./" + scriptName + " tail").getOutput());
|
||||
logger.debug("<< stderr from %s as %s@%s\n%s", scriptName, node
|
||||
.getCredentials().account, Iterables.get(node
|
||||
.getPublicAddresses(), 0), ssh.exec(
|
||||
"./" + scriptName + " tailerr").getOutput());
|
||||
}
|
||||
return returnVal;
|
||||
}
|
||||
|
@ -351,24 +401,28 @@ public class ComputeUtils {
|
|||
|
||||
private ExecResponse runScriptAsRoot() {
|
||||
if (node.getCredentials().account.equals("root")) {
|
||||
logger.debug(">> running %s as %s@%s", scriptName, node.getCredentials().account,
|
||||
Iterables.get(node.getPublicAddresses(), 0));
|
||||
logger.debug(">> running %s as %s@%s", scriptName, node
|
||||
.getCredentials().account, Iterables.get(node
|
||||
.getPublicAddresses(), 0));
|
||||
return ssh.exec("./" + scriptName + " start");
|
||||
} else if (isKeyAuth(node)) {
|
||||
logger.debug(">> running sudo %s as %s@%s", scriptName, node.getCredentials().account,
|
||||
Iterables.get(node.getPublicAddresses(), 0));
|
||||
logger.debug(">> running sudo %s as %s@%s", scriptName, node
|
||||
.getCredentials().account, Iterables.get(node
|
||||
.getPublicAddresses(), 0));
|
||||
return ssh.exec("sudo ./" + scriptName + " start");
|
||||
} else {
|
||||
logger.debug(">> running sudo -S %s as %s@%s", scriptName,
|
||||
node.getCredentials().account, Iterables.get(node.getPublicAddresses(), 0));
|
||||
return ssh.exec(String.format("echo '%s'|sudo -S ./%s", node.getCredentials().key,
|
||||
scriptName + " start"));
|
||||
logger.debug(">> running sudo -S %s as %s@%s", scriptName, node
|
||||
.getCredentials().account, Iterables.get(node
|
||||
.getPublicAddresses(), 0));
|
||||
return ssh.exec(String.format("echo '%s'|sudo -S ./%s", node
|
||||
.getCredentials().key, scriptName + " start"));
|
||||
}
|
||||
}
|
||||
|
||||
private ExecResponse runScriptAsDefaultUser() {
|
||||
logger.debug(">> running script %s as %s@%s", scriptName, node.getCredentials().account,
|
||||
Iterables.get(node.getPublicAddresses(), 0));
|
||||
logger.debug(">> running script %s as %s@%s", scriptName, node
|
||||
.getCredentials().account, Iterables.get(node
|
||||
.getPublicAddresses(), 0));
|
||||
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 final NodeMetadata node;
|
||||
private final String privateKey;
|
||||
|
@ -393,9 +448,12 @@ public class ComputeUtils {
|
|||
@Override
|
||||
public ExecResponse call() throws Exception {
|
||||
ssh.exec("mkdir .ssh");
|
||||
ssh.put(".ssh/id_rsa", new ByteArrayInputStream(privateKey.getBytes()));
|
||||
logger.debug(">> installing rsa key for %s@%s", node.getCredentials().account, Iterables
|
||||
.get(node.getPublicAddresses(), 0));
|
||||
ssh
|
||||
.put(".ssh/id_rsa", new ByteArrayInputStream(privateKey
|
||||
.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");
|
||||
}
|
||||
|
||||
|
@ -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 final NodeMetadata node;
|
||||
private final String publicKey;
|
||||
|
@ -426,10 +485,13 @@ public class ComputeUtils {
|
|||
@Override
|
||||
public ExecResponse call() throws Exception {
|
||||
ssh.exec("mkdir .ssh");
|
||||
ssh.put(".ssh/id_rsa.pub", new ByteArrayInputStream(publicKey.getBytes()));
|
||||
logger.debug(">> authorizing rsa public key for %s@%s", node.getCredentials().account,
|
||||
Iterables.get(node.getPublicAddresses(), 0));
|
||||
ExecResponse returnVal = ssh.exec("cat .ssh/id_rsa.pub >> .ssh/authorized_keys");
|
||||
ssh.put(".ssh/id_rsa.pub", new ByteArrayInputStream(publicKey
|
||||
.getBytes()));
|
||||
logger.debug(">> authorizing rsa public key for %s@%s", node
|
||||
.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");
|
||||
logger.debug("<< complete(%d)", returnVal.getExitCode());
|
||||
return returnVal;
|
||||
|
@ -449,31 +511,36 @@ public class ComputeUtils {
|
|||
|
||||
public static boolean isKeyAuth(NodeMetadata createdNode) {
|
||||
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),
|
||||
* returns a new instance of {@link NodeMetadata} that has new credentials
|
||||
* Given the instances of {@link NodeMetadata} (immutable) and
|
||||
* {@link Credentials} (immutable), returns a new instance of
|
||||
* {@link NodeMetadata} that has new credentials
|
||||
*/
|
||||
public static NodeMetadata installNewCredentials(NodeMetadata node, Credentials newCredentials) {
|
||||
return new NodeMetadataImpl(node.getProviderId(), node.getName(), node.getId(), node
|
||||
.getLocation(), node.getUri(), node.getUserMetadata(), node.getTag(), node
|
||||
.getImage(), node.getState(), node.getPublicAddresses(), node.getPrivateAddresses(),
|
||||
node.getExtra(), newCredentials);
|
||||
public static NodeMetadata installNewCredentials(NodeMetadata node,
|
||||
Credentials newCredentials) {
|
||||
return new NodeMetadataImpl(node.getProviderId(), node.getName(), node
|
||||
.getId(), node.getLocation(), node.getUri(),
|
||||
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
|
||||
* compute.properties to populate the set.
|
||||
* Gets a set of supported providers. Idea stolen from pallets
|
||||
* (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() {
|
||||
Properties properties = new Properties();
|
||||
try {
|
||||
properties.load(Resources.newInputStreamSupplier(
|
||||
Resources.getResource("compute.properties")).getInput());
|
||||
Resources.getResource("compute.properties")).getInput());
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
@ -484,7 +551,8 @@ public class ComputeUtils {
|
|||
for (Object key : keys) {
|
||||
String keyString = key.toString();
|
||||
if (keyString.endsWith(".contextbuilder")) {
|
||||
providers.add(keyString.substring(0, keyString.length() - ".contextbuilder".length()));
|
||||
providers.add(keyString.substring(0, keyString.length()
|
||||
- ".contextbuilder".length()));
|
||||
}
|
||||
}
|
||||
return providers;
|
||||
|
|
|
@ -99,8 +99,8 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
protected Map<String, String> keyPair;
|
||||
|
||||
@BeforeGroups(groups = { "integration", "live" })
|
||||
public void setupClient() throws InterruptedException, ExecutionException, TimeoutException,
|
||||
IOException {
|
||||
public void setupClient() throws InterruptedException, ExecutionException,
|
||||
TimeoutException, IOException {
|
||||
if (tag == null)
|
||||
tag = checkNotNull(service, "service");
|
||||
setupCredentials();
|
||||
|
@ -110,28 +110,33 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
Injector injector = createSshClientInjector();
|
||||
sshFactory = injector.getInstance(SshClient.Factory.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
|
||||
}
|
||||
|
||||
protected void setupKeyPair() throws FileNotFoundException, IOException {
|
||||
String secretKeyFile;
|
||||
try {
|
||||
secretKeyFile = checkNotNull(System.getProperty("jclouds.test.ssh.keyfile"),
|
||||
"jclouds.test.ssh.keyfile");
|
||||
secretKeyFile = checkNotNull(System
|
||||
.getProperty("jclouds.test.ssh.keyfile"),
|
||||
"jclouds.test.ssh.keyfile");
|
||||
} catch (NullPointerException e) {
|
||||
secretKeyFile = System.getProperty("user.home") + "/.ssh/id_rsa";
|
||||
}
|
||||
checkSecretKeyFile(secretKeyFile);
|
||||
String secret = Files.toString(new File(secretKeyFile), Charsets.UTF_8);
|
||||
assert secret.startsWith("-----BEGIN RSA PRIVATE KEY-----") : "invalid key:\n" + secret;
|
||||
keyPair = ImmutableMap.<String, String> of("private", secret, "public", Files.toString(
|
||||
new File(secretKeyFile + ".pub"), Charsets.UTF_8));
|
||||
assert secret.startsWith("-----BEGIN RSA PRIVATE KEY-----") : "invalid key:\n"
|
||||
+ secret;
|
||||
keyPair = ImmutableMap.<String, String> of("private", secret, "public",
|
||||
Files.toString(new File(secretKeyFile + ".pub"), Charsets.UTF_8));
|
||||
}
|
||||
|
||||
protected void setupCredentials() {
|
||||
user = checkNotNull(System.getProperty("jclouds.test.user"), "jclouds.test.user");
|
||||
password = checkNotNull(System.getProperty("jclouds.test.key"), "jclouds.test.key");
|
||||
user = checkNotNull(System.getProperty("jclouds.test.user"),
|
||||
"jclouds.test.user");
|
||||
password = checkNotNull(System.getProperty("jclouds.test.key"),
|
||||
"jclouds.test.key");
|
||||
}
|
||||
|
||||
protected Injector createSshClientInjector() {
|
||||
|
@ -141,16 +146,20 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
private void initializeContextAndClient() throws IOException {
|
||||
if (context != null)
|
||||
context.close();
|
||||
context = new ComputeServiceContextFactory().createContext(service, user, password,
|
||||
ImmutableSet.of(new Log4JLoggingModule(), getSshModule()));
|
||||
context = new ComputeServiceContextFactory()
|
||||
.createContext(service, user, password, ImmutableSet.of(
|
||||
new Log4JLoggingModule(), getSshModule()));
|
||||
client = context.getComputeService();
|
||||
}
|
||||
|
||||
private void checkSecretKeyFile(String secretKeyFile) throws FileNotFoundException {
|
||||
Utils.checkNotEmpty(secretKeyFile,
|
||||
"System property: [jclouds.test.ssh.keyfile] set to an empty string");
|
||||
private void checkSecretKeyFile(String secretKeyFile)
|
||||
throws FileNotFoundException {
|
||||
Utils
|
||||
.checkNotEmpty(secretKeyFile,
|
||||
"System property: [jclouds.test.ssh.keyfile] set to an empty string");
|
||||
if (!new File(secretKeyFile).exists()) {
|
||||
throw new FileNotFoundException("secretKeyFile not found at: " + secretKeyFile);
|
||||
throw new FileNotFoundException("secretKeyFile not found at: "
|
||||
+ secretKeyFile);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -160,7 +169,7 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
@Test(enabled = true, expectedExceptions = AuthorizationException.class)
|
||||
public void testCorrectAuthException() throws Exception {
|
||||
new ComputeServiceContextFactory().createContext(service, "MOMMA", "MIA",
|
||||
ImmutableSet.<Module> of(new Log4JLoggingModule())).close();
|
||||
ImmutableSet.<Module> of(new Log4JLoggingModule())).close();
|
||||
}
|
||||
|
||||
@Test(enabled = true)
|
||||
|
@ -175,7 +184,8 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
// since surefire and eclipse don't otherwise guarantee the order, we are
|
||||
// starting this one alphabetically before create2nodes..
|
||||
@Test(enabled = true, dependsOnMethods = "testImagesCache")
|
||||
public void testAScriptExecutionAfterBootWithBasicTemplate() throws Exception {
|
||||
public void testAScriptExecutionAfterBootWithBasicTemplate()
|
||||
throws Exception {
|
||||
String tag = this.tag + "run";
|
||||
try {
|
||||
client.destroyNodesMatching(NodePredicates.withTag(tag));
|
||||
|
@ -185,18 +195,21 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
|
||||
TemplateOptions options = client.templateOptions().blockOnPort(22, 120);
|
||||
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();
|
||||
assert good.account != null;
|
||||
assert good.key != null;
|
||||
|
||||
Image image = Iterables.get(nodes, 0).getImage();
|
||||
try {
|
||||
Map<? extends NodeMetadata, ExecResponse> responses = runScriptWithCreds(tag, image
|
||||
.getOsFamily(), new Credentials(good.account, "romeo"));
|
||||
Map<? extends NodeMetadata, ExecResponse> responses = runScriptWithCreds(
|
||||
tag, image.getOsFamily(), new Credentials(good.account,
|
||||
"romeo"));
|
||||
assert false : "shouldn't pass with a bad password\n" + responses;
|
||||
} 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);
|
||||
|
@ -211,7 +224,8 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
@Test(enabled = true, dependsOnMethods = "testImagesCache")
|
||||
public void testTemplateMatch() throws Exception {
|
||||
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());
|
||||
}
|
||||
|
||||
|
@ -226,14 +240,14 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
}
|
||||
template = buildTemplate(client.templateBuilder());
|
||||
|
||||
template.getOptions().installPrivateKey(keyPair.get("private")).authorizePublicKey(
|
||||
keyPair.get("public")).runScript(
|
||||
buildScript(template.getImage().getOsFamily()).getBytes());
|
||||
template.getOptions().installPrivateKey(keyPair.get("private"))
|
||||
.authorizePublicKey(keyPair.get("public")).runScript(
|
||||
buildScript(template.getImage().getOsFamily()).getBytes());
|
||||
try {
|
||||
nodes = Sets.newTreeSet(client.runNodesWithTag(tag, 2, template));
|
||||
} catch (RunNodesException e) {
|
||||
nodes = Sets.newTreeSet(Iterables.concat(e.getSuccessfulNodes(), e.getNodeErrors()
|
||||
.keySet()));
|
||||
nodes = Sets.newTreeSet(Iterables.concat(e.getSuccessfulNodes(), e
|
||||
.getNodeErrors().keySet()));
|
||||
throw e;
|
||||
}
|
||||
assertEquals(nodes.size(), 2);
|
||||
|
@ -260,9 +274,11 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
}
|
||||
|
||||
@Test(enabled = true, dependsOnMethods = "testCreateTwoNodesWithRunScript")
|
||||
public void testCreateAnotherNodeWithANewContextToEnsureSharedMemIsntRequired() throws Exception {
|
||||
public void testCreateAnotherNodeWithANewContextToEnsureSharedMemIsntRequired()
|
||||
throws Exception {
|
||||
initializeContextAndClient();
|
||||
TreeSet<NodeMetadata> nodes = Sets.newTreeSet(client.runNodesWithTag(tag, 1, template));
|
||||
TreeSet<NodeMetadata> nodes = Sets.newTreeSet(client.runNodesWithTag(tag,
|
||||
1, template));
|
||||
checkNodes(nodes, tag);
|
||||
NodeMetadata node = nodes.first();
|
||||
this.nodes.add(node);
|
||||
|
@ -271,28 +287,32 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
assertEquals(node.getImage(), template.getImage());
|
||||
}
|
||||
|
||||
protected Map<? extends NodeMetadata, ExecResponse> runScriptWithCreds(final String tag,
|
||||
OsFamily osFamily, Credentials creds) throws RunScriptOnNodesException {
|
||||
protected Map<? extends NodeMetadata, ExecResponse> runScriptWithCreds(
|
||||
final String tag, OsFamily osFamily, Credentials creds)
|
||||
throws RunScriptOnNodesException {
|
||||
try {
|
||||
return client.runScriptOnNodesMatching(NodePredicates.runningWithTag(tag), buildScript(
|
||||
osFamily).getBytes(), RunScriptOptions.Builder.overrideCredentialsWith(creds));
|
||||
return client.runScriptOnNodesMatching(NodePredicates
|
||||
.runningWithTag(tag), buildScript(osFamily).getBytes(),
|
||||
RunScriptOptions.Builder.overrideCredentialsWith(creds));
|
||||
} catch (SshException e) {
|
||||
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));
|
||||
}
|
||||
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) {
|
||||
assertNotNull(node.getProviderId());
|
||||
assertNotNull(node.getTag());
|
||||
assertEquals(node.getTag(), tag);
|
||||
assertEquals(node.getState(), NodeState.RUNNING);
|
||||
assert node.getPublicAddresses().size() >= 1 || node.getPrivateAddresses().size() >= 1 : "no ips in"
|
||||
+ node;
|
||||
assert node.getPublicAddresses().size() >= 1
|
||||
|| node.getPrivateAddresses().size() >= 1 : "no ips in" + node;
|
||||
assertNotNull(node.getCredentials());
|
||||
if (node.getCredentials().account != null) {
|
||||
assertNotNull(node.getCredentials().account);
|
||||
|
@ -308,58 +328,70 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
|
||||
protected String buildScript(OsFamily osFamily) {
|
||||
switch (osFamily) {
|
||||
case UBUNTU:
|
||||
return new StringBuilder()//
|
||||
.append("echo nameserver 208.67.222.222 >> /etc/resolv.conf\n")//
|
||||
.append("cp /etc/apt/sources.list /etc/apt/sources.list.old\n")//
|
||||
.append(
|
||||
"sed 's~us.archive.ubuntu.com~mirror.anl.gov/pub~g' /etc/apt/sources.list.old >/etc/apt/sources.list\n")//
|
||||
.append("apt-get update\n")//
|
||||
.append("apt-get install -f -y --force-yes openjdk-6-jdk\n")//
|
||||
.append("wget -qO/usr/bin/runurl run.alestic.com/runurl\n")//
|
||||
.append("chmod 755 /usr/bin/runurl\n")//
|
||||
.toString();
|
||||
case CENTOS:
|
||||
case RHEL:
|
||||
return new StringBuilder()
|
||||
.append("echo nameserver 208.67.222.222 >> /etc/resolv.conf\n")
|
||||
.append("echo \"[jdkrepo]\" >> /etc/yum.repos.d/CentOS-Base.repo\n")
|
||||
.append("echo \"name=jdkrepository\" >> /etc/yum.repos.d/CentOS-Base.repo\n")
|
||||
.append(
|
||||
"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("yum --nogpgcheck -y install java-1.6.0-openjdk\n")
|
||||
.append(
|
||||
"echo \"export PATH=\\\"/usr/lib/jvm/jre-1.6.0-openjdk/bin/:\\$PATH\\\"\" >> /root/.bashrc\n")
|
||||
.toString();
|
||||
default:
|
||||
throw new IllegalArgumentException(osFamily.toString());
|
||||
case UBUNTU:
|
||||
return new StringBuilder()//
|
||||
.append("echo nameserver 208.67.222.222 >> /etc/resolv.conf\n")//
|
||||
.append("cp /etc/apt/sources.list /etc/apt/sources.list.old\n")//
|
||||
.append(
|
||||
"sed 's~us.archive.ubuntu.com~mirror.anl.gov/pub~g' /etc/apt/sources.list.old >/etc/apt/sources.list\n")//
|
||||
.append("apt-get update\n")//
|
||||
.append("apt-get install -f -y --force-yes openjdk-6-jdk\n")//
|
||||
.append("wget -qO/usr/bin/runurl run.alestic.com/runurl\n")//
|
||||
.append("chmod 755 /usr/bin/runurl\n")//
|
||||
.toString();
|
||||
case CENTOS:
|
||||
case RHEL:
|
||||
return new StringBuilder()
|
||||
.append("echo nameserver 208.67.222.222 >> /etc/resolv.conf\n")
|
||||
.append(
|
||||
"echo \"[jdkrepo]\" >> /etc/yum.repos.d/CentOS-Base.repo\n")
|
||||
.append(
|
||||
"echo \"name=jdkrepository\" >> /etc/yum.repos.d/CentOS-Base.repo\n")
|
||||
.append(
|
||||
"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("yum --nogpgcheck -y install java-1.6.0-openjdk\n")
|
||||
.append(
|
||||
"echo \"export PATH=\\\"/usr/lib/jvm/jre-1.6.0-openjdk/bin/:\\$PATH\\\"\" >> /root/.bashrc\n")
|
||||
.toString();
|
||||
default:
|
||||
throw new IllegalArgumentException(osFamily.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@Test(enabled = true, dependsOnMethods = "testCreateAnotherNodeWithANewContextToEnsureSharedMemIsntRequired")
|
||||
public void testGet() throws Exception {
|
||||
Set<? extends NodeMetadata> metadataSet = Sets.newHashSet(Iterables.filter(client
|
||||
.listNodesDetailsMatching(NodePredicates.all()), Predicates.and(NodePredicates
|
||||
.withTag(tag), Predicates.not(NodePredicates.TERMINATED))));
|
||||
Set<? extends NodeMetadata> metadataSet = Sets.newHashSet(Iterables
|
||||
.filter(client.listNodesDetailsMatching(NodePredicates.all()),
|
||||
Predicates.and(NodePredicates.withTag(tag), Predicates
|
||||
.not(NodePredicates.TERMINATED))));
|
||||
for (NodeMetadata node : nodes) {
|
||||
metadataSet.remove(node);
|
||||
NodeMetadata metadata = client.getNodeMetadata(node.getId());
|
||||
assertEquals(metadata.getProviderId(), node.getProviderId());
|
||||
assertEquals(metadata.getTag(), node.getTag());
|
||||
assertLocationSameOrChild(metadata.getLocation(), template.getLocation());
|
||||
assertLocationSameOrChild(metadata.getLocation(), template
|
||||
.getLocation());
|
||||
assertEquals(metadata.getImage(), template.getImage());
|
||||
assertEquals(metadata.getState(), NodeState.RUNNING);
|
||||
assertEquals(metadata.getPrivateAddresses(), node.getPrivateAddresses());
|
||||
assertEquals(metadata.getPrivateAddresses(), node
|
||||
.getPrivateAddresses());
|
||||
assertEquals(metadata.getPublicAddresses(), node.getPublicAddresses());
|
||||
}
|
||||
assertNodeZero(metadataSet);
|
||||
}
|
||||
|
||||
protected void assertNodeZero(Set<? extends NodeMetadata> metadataSet) {
|
||||
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")
|
||||
public void testReboot() throws Exception {
|
||||
client.rebootNodesMatching(NodePredicates.withTag(tag));// TODO test validation
|
||||
client.rebootNodesMatching(NodePredicates.withTag(tag));// TODO test
|
||||
// validation
|
||||
testGet();
|
||||
}
|
||||
|
||||
|
@ -368,7 +400,7 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
TemplateOptions options = new TemplateOptions().withMetadata();
|
||||
Template t = client.templateBuilder().smallest().options(options).build();
|
||||
assert t.getOptions().isIncludeMetadata() : "The metadata option should be 'true' "
|
||||
+ "for the created template";
|
||||
+ "for the created template";
|
||||
}
|
||||
|
||||
public void testListNodes() throws Exception {
|
||||
|
@ -380,7 +412,8 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
}
|
||||
|
||||
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.getLocation() != null : node;
|
||||
assertEquals(node.getType(), ComputeType.NODE);
|
||||
|
@ -394,7 +427,7 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
if (nodeMetadata.getState() == NodeState.RUNNING) {
|
||||
assert nodeMetadata.getPublicAddresses() != null : nodeMetadata;
|
||||
assert nodeMetadata.getPublicAddresses().size() > 0
|
||||
|| nodeMetadata.getPrivateAddresses().size() > 0 : nodeMetadata;
|
||||
|| nodeMetadata.getPrivateAddresses().size() > 0 : nodeMetadata;
|
||||
assertNotNull(nodeMetadata.getPrivateAddresses());
|
||||
}
|
||||
}
|
||||
|
@ -416,30 +449,56 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
assert location != location.getParent() : location;
|
||||
assert location.getScope() != null : location;
|
||||
switch (location.getScope()) {
|
||||
case PROVIDER:
|
||||
assertProvider(location);
|
||||
break;
|
||||
case REGION:
|
||||
assertProvider(location.getParent());
|
||||
break;
|
||||
case ZONE:
|
||||
Location provider = location.getParent().getParent();
|
||||
// zone can be a direct descendant of provider
|
||||
if (provider == null)
|
||||
provider = location.getParent();
|
||||
assertProvider(provider);
|
||||
break;
|
||||
case HOST:
|
||||
Location provider2 = location.getParent().getParent().getParent();
|
||||
// zone can be a direct descendant of provider
|
||||
if (provider2 == null)
|
||||
provider2 = location.getParent().getParent();
|
||||
assertProvider(provider2);
|
||||
break;
|
||||
case PROVIDER:
|
||||
assertProvider(location);
|
||||
break;
|
||||
case REGION:
|
||||
assertProvider(location.getParent());
|
||||
break;
|
||||
case ZONE:
|
||||
Location provider = location.getParent().getParent();
|
||||
// zone can be a direct descendant of provider
|
||||
if (provider == null)
|
||||
provider = location.getParent();
|
||||
assertProvider(provider);
|
||||
break;
|
||||
case HOST:
|
||||
Location provider2 = location.getParent().getParent().getParent();
|
||||
// zone can be a direct descendant of provider
|
||||
if (provider2 == null)
|
||||
provider2 = location.getParent().getParent();
|
||||
assertProvider(provider2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@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) {
|
||||
assertEquals(provider.getScope(), LocationScope.PROVIDER);
|
||||
assertEquals(provider.getParent(), null);
|
||||
|
@ -470,12 +529,15 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
}
|
||||
}
|
||||
|
||||
protected void doCheckJavaIsInstalledViaSsh(NodeMetadata node) throws IOException {
|
||||
IPSocket socket = new IPSocket(Iterables.get(node.getPublicAddresses(), 0), 22);
|
||||
socketTester.apply(socket); // TODO add transitionTo option that accepts a socket conection
|
||||
protected void doCheckJavaIsInstalledViaSsh(NodeMetadata node)
|
||||
throws IOException {
|
||||
IPSocket socket = new IPSocket(Iterables
|
||||
.get(node.getPublicAddresses(), 0), 22);
|
||||
socketTester.apply(socket); // TODO add transitionTo option that accepts
|
||||
// a socket conection
|
||||
// state.
|
||||
SshClient ssh = sshFactory.create(socket, node.getCredentials().account, keyPair.get(
|
||||
"private").getBytes());
|
||||
SshClient ssh = sshFactory.create(socket, node.getCredentials().account,
|
||||
keyPair.get("private").getBytes());
|
||||
try {
|
||||
ssh.connect();
|
||||
ExecResponse hello = ssh.exec("echo hello");
|
||||
|
@ -489,11 +551,13 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
}
|
||||
|
||||
@AfterTest
|
||||
protected void cleanup() throws InterruptedException, ExecutionException, TimeoutException {
|
||||
protected void cleanup() throws InterruptedException, ExecutionException,
|
||||
TimeoutException {
|
||||
if (nodes != null) {
|
||||
client.destroyNodesMatching(NodePredicates.withTag(tag));
|
||||
for (NodeMetadata node : Iterables.filter(client.listNodesDetailsMatching(NodePredicates
|
||||
.all()), NodePredicates.withTag(tag))) {
|
||||
for (NodeMetadata node : Iterables.filter(client
|
||||
.listNodesDetailsMatching(NodePredicates.all()), NodePredicates
|
||||
.withTag(tag))) {
|
||||
assert node.getState() == NodeState.TERMINATED : node;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,10 +31,12 @@ import java.io.FileNotFoundException;
|
|||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.Serializable;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
import org.easymock.IArgumentMatcher;
|
||||
import org.jclouds.compute.domain.Architecture;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.OsFamily;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.compute.stub.config.StubComputeServiceContextModule.StubNodeMetadata;
|
||||
|
@ -64,7 +66,8 @@ import com.google.inject.Module;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
@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_BAD = new ExecResponse("", "", 1);
|
||||
|
@ -82,7 +85,8 @@ public class StubComputeServiceIntegrationTest extends BaseComputeServiceLiveTes
|
|||
@Test
|
||||
public void testTemplateBuilder() {
|
||||
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.getLocation().getId(), "memory");
|
||||
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(
|
||||
factory.create(eq(new IPSocket("144.175.1.1", 22)), eq("root"), aryEq(keyPair
|
||||
.get("private").getBytes()))).andReturn(client1).atLeastOnce();
|
||||
factory.create(eq(new IPSocket("144.175.1.1", 22)),
|
||||
eq("root"), aryEq(keyPair.get("private").getBytes())))
|
||||
.andReturn(client1).atLeastOnce();
|
||||
expect(
|
||||
factory.create(eq(new IPSocket("144.175.1.2", 22)), eq("root"), aryEq(keyPair
|
||||
.get("private").getBytes()))).andReturn(client2).atLeastOnce();
|
||||
factory.create(eq(new IPSocket("144.175.1.2", 22)),
|
||||
eq("root"), aryEq(keyPair.get("private").getBytes())))
|
||||
.andReturn(client2).atLeastOnce();
|
||||
expect(
|
||||
factory.create(eq(new IPSocket("144.175.1.3", 22)), eq("root"), aryEq(keyPair
|
||||
.get("private").getBytes()))).andReturn(client3).atLeastOnce();
|
||||
factory.create(eq(new IPSocket("144.175.1.3", 22)),
|
||||
eq("root"), aryEq(keyPair.get("private").getBytes())))
|
||||
.andReturn(client3).atLeastOnce();
|
||||
expect(
|
||||
factory.create(eq(new IPSocket("144.175.1.4", 22)), eq("root"), aryEq(keyPair
|
||||
.get("private").getBytes()))).andReturn(client4).atLeastOnce();
|
||||
factory.create(eq(new IPSocket("144.175.1.4", 22)),
|
||||
eq("root"), aryEq(keyPair.get("private").getBytes())))
|
||||
.andReturn(client4).atLeastOnce();
|
||||
|
||||
helloAndJava(client1);
|
||||
helloAndJava(client2);
|
||||
|
@ -139,8 +147,10 @@ public class StubComputeServiceIntegrationTest extends BaseComputeServiceLiveTes
|
|||
private void helloAndJava(SshClient client) {
|
||||
client.connect();
|
||||
|
||||
expect(client.exec("echo hello")).andReturn(new ExecResponse("hello", "", 0));
|
||||
expect(client.exec("java -version")).andReturn(new ExecResponse("", "OpenJDK", 0));
|
||||
expect(client.exec("echo hello")).andReturn(
|
||||
new ExecResponse("hello", "", 0));
|
||||
expect(client.exec("java -version")).andReturn(
|
||||
new ExecResponse("", "OpenJDK", 0));
|
||||
|
||||
client.disconnect();
|
||||
}
|
||||
|
@ -160,21 +170,26 @@ public class StubComputeServiceIntegrationTest extends BaseComputeServiceLiveTes
|
|||
SshClient client3 = createMock(SshClient.class);
|
||||
SshClient client4 = createMock(SshClient.class);
|
||||
|
||||
expect(factory.create(new IPSocket("144.175.1.1", 22), "root", "romeo")).andThrow(
|
||||
new SshException("Auth fail"));
|
||||
expect(factory.create(new IPSocket("144.175.1.1", 22), "root", "password1")).andReturn(
|
||||
client1).atLeastOnce();
|
||||
expect(
|
||||
factory.create(new IPSocket("144.175.1.1", 22), "root",
|
||||
"romeo")).andThrow(new SshException("Auth fail"));
|
||||
expect(
|
||||
factory.create(new IPSocket("144.175.1.1", 22), "root",
|
||||
"password1")).andReturn(client1).atLeastOnce();
|
||||
|
||||
client1.connect();
|
||||
runScript(client1, "computeserv", 1);
|
||||
client1.disconnect();
|
||||
|
||||
expect(factory.create(new IPSocket("144.175.1.2", 22), "root", "password2")).andReturn(
|
||||
client2).atLeastOnce();
|
||||
expect(factory.create(new IPSocket("144.175.1.3", 22), "root", "password3")).andReturn(
|
||||
client3).atLeastOnce();
|
||||
expect(factory.create(new IPSocket("144.175.1.4", 22), "root", "password4")).andReturn(
|
||||
client4).atLeastOnce();
|
||||
expect(
|
||||
factory.create(new IPSocket("144.175.1.2", 22), "root",
|
||||
"password2")).andReturn(client2).atLeastOnce();
|
||||
expect(
|
||||
factory.create(new IPSocket("144.175.1.3", 22), "root",
|
||||
"password3")).andReturn(client3).atLeastOnce();
|
||||
expect(
|
||||
factory.create(new IPSocket("144.175.1.4", 22), "root",
|
||||
"password4")).andReturn(client4).atLeastOnce();
|
||||
|
||||
runScriptAndInstallSsh(client2, "runscript", 2);
|
||||
runScriptAndInstallSsh(client3, "runscript", 3);
|
||||
|
@ -189,14 +204,17 @@ public class StubComputeServiceIntegrationTest extends BaseComputeServiceLiveTes
|
|||
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();
|
||||
|
||||
runScript(client, scriptName, nodeId);
|
||||
|
||||
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("chmod 600 .ssh/authorized_keys")).andReturn(EXEC_GOOD);
|
||||
expect(client.exec("cat .ssh/id_rsa.pub >> .ssh/authorized_keys"))
|
||||
.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")));
|
||||
|
||||
expect(client.exec("mkdir .ssh")).andReturn(EXEC_GOOD);
|
||||
|
@ -210,18 +228,26 @@ public class StubComputeServiceIntegrationTest extends BaseComputeServiceLiveTes
|
|||
|
||||
private void runScript(SshClient client, String scriptName, int nodeId) {
|
||||
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.getHostAddress()).andReturn(nodeId + "").atLeastOnce();
|
||||
expect(client.exec("./" + scriptName + " init")).andReturn(EXEC_GOOD);
|
||||
expect(client.exec("./" + scriptName + " start")).andReturn(EXEC_GOOD);
|
||||
expect(client.exec("./" + scriptName + " status")).andReturn(EXEC_GOOD);
|
||||
expect(client.getHostAddress()).andReturn(nodeId + "")
|
||||
.atLeastOnce();
|
||||
expect(client.exec("./" + scriptName + " init")).andReturn(
|
||||
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.
|
||||
expect(client.exec("./" + scriptName + " status")).andReturn(EXEC_BAD);
|
||||
expect(client.exec("./" + scriptName + " tail")).andReturn(EXEC_GOOD);
|
||||
expect(client.exec("./" + scriptName + " tailerr")).andReturn(EXEC_GOOD);
|
||||
expect(client.exec("./" + scriptName + " status")).andReturn(
|
||||
EXEC_BAD);
|
||||
expect(client.exec("./" + scriptName + " tail")).andReturn(
|
||||
EXEC_GOOD);
|
||||
expect(client.exec("./" + scriptName + " tailerr")).andReturn(
|
||||
EXEC_GOOD);
|
||||
}
|
||||
|
||||
};
|
||||
|
@ -233,11 +259,16 @@ public class StubComputeServiceIntegrationTest extends BaseComputeServiceLiveTes
|
|||
password = "stub";
|
||||
}
|
||||
|
||||
protected void assertNodeZero(Set<? extends NodeMetadata> metadataSet) {
|
||||
// TODO: this fails so we override it.
|
||||
}
|
||||
|
||||
public static String initScript(String scriptName, String script) {
|
||||
return new InitBuilder(scriptName, "/tmp/" + scriptName, "/tmp/" + scriptName, ImmutableMap
|
||||
.<String, String> of(), Iterables.toArray(Splitter.on("\n").split(
|
||||
new String(checkNotNull(script, "script"))), String.class))
|
||||
.build(org.jclouds.scriptbuilder.domain.OsFamily.UNIX);
|
||||
return new InitBuilder(scriptName, "/tmp/" + scriptName, "/tmp/"
|
||||
+ scriptName, ImmutableMap.<String, String> of(), Iterables
|
||||
.toArray(Splitter.on("\n").split(
|
||||
new String(checkNotNull(script, "script"))), String.class))
|
||||
.build(org.jclouds.scriptbuilder.domain.OsFamily.UNIX);
|
||||
}
|
||||
|
||||
public static InputStream isEq(String value) {
|
||||
|
@ -248,10 +279,12 @@ public class StubComputeServiceIntegrationTest extends BaseComputeServiceLiveTes
|
|||
public void testAssignability() throws Exception {
|
||||
@SuppressWarnings("unused")
|
||||
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;
|
||||
|
||||
|
@ -297,8 +330,8 @@ public class StubComputeServiceIntegrationTest extends BaseComputeServiceLiveTes
|
|||
if (o == null || !this.getClass().equals(o.getClass()))
|
||||
return false;
|
||||
InputStreamEquals other = (InputStreamEquals) o;
|
||||
return this.expected == null && other.expected == null || this.expected != null
|
||||
&& this.expected.equals(other.expected);
|
||||
return this.expected == null && other.expected == null
|
||||
|| this.expected != null && this.expected.equals(other.expected);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -310,8 +343,8 @@ public class StubComputeServiceIntegrationTest extends BaseComputeServiceLiveTes
|
|||
|
||||
@Override
|
||||
protected void setupKeyPair() throws FileNotFoundException, IOException {
|
||||
keyPair = ImmutableMap.<String, String> of("public", "ssh-rsa", "private",
|
||||
"-----BEGIN RSA PRIVATE KEY-----");
|
||||
keyPair = ImmutableMap.<String, String> of("public", "ssh-rsa",
|
||||
"private", "-----BEGIN RSA PRIVATE KEY-----");
|
||||
}
|
||||
|
||||
}
|
|
@ -4,6 +4,7 @@ import java.util.Set;
|
|||
|
||||
import org.jclouds.compute.util.ComputeUtils;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* Test the compute utils.
|
||||
*
|
||||
|
@ -17,10 +18,11 @@ public class ComputeUtilsTest {
|
|||
* Test some of the currently supported clouds against compute.properties.
|
||||
*/
|
||||
@Test
|
||||
public void testSupportedProviders(){
|
||||
public void testSupportedProviders() {
|
||||
Set<String> providers = ComputeUtils.getSupportedProviders();
|
||||
assert providers.contains("rimuhosting");
|
||||
assert providers.contains("cloudservers");
|
||||
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.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.installPrivateKey;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
@ -33,120 +34,149 @@ import org.testng.annotations.Test;
|
|||
*/
|
||||
public class TemplateOptionsTest {
|
||||
|
||||
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||
public void testinstallPrivateKeyBadFormat() {
|
||||
TemplateOptions options = new TemplateOptions();
|
||||
options.installPrivateKey("whompy");
|
||||
}
|
||||
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||
public void testinstallPrivateKeyBadFormat() {
|
||||
TemplateOptions options = new TemplateOptions();
|
||||
options.installPrivateKey("whompy");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testinstallPrivateKey() {
|
||||
TemplateOptions options = new TemplateOptions();
|
||||
options.installPrivateKey("-----BEGIN RSA PRIVATE KEY-----");
|
||||
assertEquals(options.getPrivateKey(), "-----BEGIN RSA PRIVATE KEY-----");
|
||||
}
|
||||
@Test
|
||||
public void testinstallPrivateKey() {
|
||||
TemplateOptions options = new TemplateOptions();
|
||||
options.installPrivateKey("-----BEGIN RSA PRIVATE KEY-----");
|
||||
assertEquals(options.getPrivateKey(), "-----BEGIN RSA PRIVATE KEY-----");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullinstallPrivateKey() {
|
||||
TemplateOptions options = new TemplateOptions();
|
||||
assertEquals(options.getPrivateKey(), null);
|
||||
}
|
||||
@Test
|
||||
public void testNullinstallPrivateKey() {
|
||||
TemplateOptions options = new TemplateOptions();
|
||||
assertEquals(options.getPrivateKey(), null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testinstallPrivateKeyStatic() {
|
||||
TemplateOptions options = installPrivateKey("-----BEGIN RSA PRIVATE KEY-----");
|
||||
assertEquals(options.getPrivateKey(), "-----BEGIN RSA PRIVATE KEY-----");
|
||||
}
|
||||
@Test
|
||||
public void testinstallPrivateKeyStatic() {
|
||||
TemplateOptions options = installPrivateKey("-----BEGIN RSA PRIVATE KEY-----");
|
||||
assertEquals(options.getPrivateKey(), "-----BEGIN RSA PRIVATE KEY-----");
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void testinstallPrivateKeyNPE() {
|
||||
installPrivateKey(null);
|
||||
}
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void testinstallPrivateKeyNPE() {
|
||||
installPrivateKey(null);
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||
public void testauthorizePublicKeyBadFormat() {
|
||||
TemplateOptions options = new TemplateOptions();
|
||||
options.authorizePublicKey("whompy");
|
||||
}
|
||||
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||
public void testauthorizePublicKeyBadFormat() {
|
||||
TemplateOptions options = new TemplateOptions();
|
||||
options.authorizePublicKey("whompy");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testauthorizePublicKey() {
|
||||
TemplateOptions options = new TemplateOptions();
|
||||
options.authorizePublicKey("ssh-rsa");
|
||||
assertEquals(options.getPublicKey(), "ssh-rsa");
|
||||
}
|
||||
@Test
|
||||
public void testauthorizePublicKey() {
|
||||
TemplateOptions options = new TemplateOptions();
|
||||
options.authorizePublicKey("ssh-rsa");
|
||||
assertEquals(options.getPublicKey(), "ssh-rsa");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullauthorizePublicKey() {
|
||||
TemplateOptions options = new TemplateOptions();
|
||||
assertEquals(options.getPublicKey(), null);
|
||||
}
|
||||
@Test
|
||||
public void testNullauthorizePublicKey() {
|
||||
TemplateOptions options = new TemplateOptions();
|
||||
assertEquals(options.getPublicKey(), null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testauthorizePublicKeyStatic() {
|
||||
TemplateOptions options = authorizePublicKey("ssh-rsa");
|
||||
assertEquals(options.getPublicKey(), "ssh-rsa");
|
||||
}
|
||||
@Test
|
||||
public void testauthorizePublicKeyStatic() {
|
||||
TemplateOptions options = authorizePublicKey("ssh-rsa");
|
||||
assertEquals(options.getPublicKey(), "ssh-rsa");
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void testauthorizePublicKeyNPE() {
|
||||
authorizePublicKey(null);
|
||||
}
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void testauthorizePublicKeyNPE() {
|
||||
authorizePublicKey(null);
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||
public void testblockOnPortBadFormat() {
|
||||
TemplateOptions options = new TemplateOptions();
|
||||
options.blockOnPort(-1, -1);
|
||||
}
|
||||
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||
public void testblockOnPortBadFormat() {
|
||||
TemplateOptions options = new TemplateOptions();
|
||||
options.blockOnPort(-1, -1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testblockOnPort() {
|
||||
TemplateOptions options = new TemplateOptions();
|
||||
options.blockOnPort(22, 30);
|
||||
assertEquals(options.getPort(), 22);
|
||||
assertEquals(options.getSeconds(), 30);
|
||||
@Test
|
||||
public void testblockOnPort() {
|
||||
TemplateOptions options = new TemplateOptions();
|
||||
options.blockOnPort(22, 30);
|
||||
assertEquals(options.getPort(), 22);
|
||||
assertEquals(options.getSeconds(), 30);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullblockOnPort() {
|
||||
TemplateOptions options = new TemplateOptions();
|
||||
assertEquals(options.getPort(), -1);
|
||||
assertEquals(options.getSeconds(), -1);
|
||||
}
|
||||
@Test
|
||||
public void testNullblockOnPort() {
|
||||
TemplateOptions options = new TemplateOptions();
|
||||
assertEquals(options.getPort(), -1);
|
||||
assertEquals(options.getSeconds(), -1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testblockOnPortStatic() {
|
||||
TemplateOptions options = blockOnPort(22, 30);
|
||||
assertEquals(options.getPort(), 22);
|
||||
assertEquals(options.getSeconds(), 30);
|
||||
}
|
||||
@Test
|
||||
public void testblockOnPortStatic() {
|
||||
TemplateOptions options = blockOnPort(22, 30);
|
||||
assertEquals(options.getPort(), 22);
|
||||
assertEquals(options.getSeconds(), 30);
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||
public void testinboundPortsBadFormat() {
|
||||
TemplateOptions options = new TemplateOptions();
|
||||
options.inboundPorts(-1, -1);
|
||||
}
|
||||
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||
public void testinboundPortsBadFormat() {
|
||||
TemplateOptions options = new TemplateOptions();
|
||||
options.inboundPorts(-1, -1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testinboundPorts() {
|
||||
TemplateOptions options = new TemplateOptions();
|
||||
options.inboundPorts(22, 30);
|
||||
assertEquals(options.getInboundPorts()[0], 22);
|
||||
assertEquals(options.getInboundPorts()[1], 30);
|
||||
@Test
|
||||
public void testinboundPorts() {
|
||||
TemplateOptions options = new TemplateOptions();
|
||||
options.inboundPorts(22, 30);
|
||||
assertEquals(options.getInboundPorts()[0], 22);
|
||||
assertEquals(options.getInboundPorts()[1], 30);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDefaultOpen22() {
|
||||
TemplateOptions options = new TemplateOptions();
|
||||
assertEquals(options.getInboundPorts()[0], 22);
|
||||
}
|
||||
@Test
|
||||
public void testDefaultOpen22() {
|
||||
TemplateOptions options = new TemplateOptions();
|
||||
assertEquals(options.getInboundPorts()[0], 22);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testinboundPortsStatic() {
|
||||
TemplateOptions options = inboundPorts(22, 30);
|
||||
assertEquals(options.getInboundPorts()[0], 22);
|
||||
assertEquals(options.getInboundPorts()[1], 30);
|
||||
}
|
||||
@Test
|
||||
public void testinboundPortsStatic() {
|
||||
TemplateOptions options = inboundPorts(22, 30);
|
||||
assertEquals(options.getInboundPorts()[0], 22);
|
||||
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
|
||||
*/
|
||||
public class RetryablePredicate<T> implements Predicate<T> {
|
||||
private final int maxWait;
|
||||
private final int checkInterval;
|
||||
private final long maxWait;
|
||||
private final long period;
|
||||
private final Predicate<T> predicate;
|
||||
|
||||
@Resource
|
||||
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.maxWait = (int) unit.toMillis(maxWait);
|
||||
this.checkInterval = (int) unit.toMillis(checkInterval);
|
||||
this.maxWait = unit.toMillis(maxWait);
|
||||
this.period = unit.toMillis(period);
|
||||
}
|
||||
|
||||
public RetryablePredicate(Predicate<T> predicate, long maxWait) {
|
||||
this.predicate = predicate;
|
||||
this.maxWait = maxWait;
|
||||
this.period = 50l;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(T input) {
|
||||
try {
|
||||
long i = 1l;
|
||||
for (Date end = new Date(System.currentTimeMillis() + maxWait); before(end); Thread
|
||||
.sleep(checkInterval)) {
|
||||
.sleep(nextMaxInterval(i++, end))) {
|
||||
if (predicate.apply(input)) {
|
||||
return true;
|
||||
} else if (atOrAfter(end)) {
|
||||
|
@ -59,11 +67,18 @@ public class RetryablePredicate<T> implements Predicate<T> {
|
|||
}
|
||||
}
|
||||
} 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;
|
||||
}
|
||||
|
||||
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) {
|
||||
return new Date().compareTo(end) <= 1;
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ import com.google.inject.Module;
|
|||
*/
|
||||
@Test
|
||||
public class JavaUrlHttpCommandExecutorServiceIntegrationTest extends
|
||||
BaseHttpCommandExecutorServiceIntegrationTest {
|
||||
BaseHttpCommandExecutorServiceIntegrationTest {
|
||||
|
||||
protected Module createConnectionModule() {
|
||||
return new JavaUrlHttpCommandExecutorServiceModule();
|
||||
|
|
|
@ -26,7 +26,6 @@ import static org.jclouds.gogrid.reference.GoGridConstants.PROPERTY_GOGRID_DEFAU
|
|||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
@ -37,6 +36,7 @@ import javax.inject.Singleton;
|
|||
|
||||
import org.jclouds.compute.ComputeServiceContext;
|
||||
import org.jclouds.compute.LoadBalancerService;
|
||||
import org.jclouds.compute.config.ComputeServiceTimeoutsModule;
|
||||
import org.jclouds.compute.domain.Architecture;
|
||||
import org.jclouds.compute.domain.ComputeMetadata;
|
||||
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.internal.ComputeServiceContextImpl;
|
||||
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.Timeouts;
|
||||
import org.jclouds.compute.strategy.AddNodeWithTagStrategy;
|
||||
import org.jclouds.compute.strategy.DestroyNodeStrategy;
|
||||
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.Predicate;
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
@ -100,15 +98,20 @@ public class GoGridComputeServiceContextModule extends GoGridContextModule {
|
|||
@Override
|
||||
protected void configure() {
|
||||
super.configure();
|
||||
install(new ComputeServiceTimeoutsModule());
|
||||
bind(new TypeLiteral<Function<Server, NodeMetadata>>() {
|
||||
}).to(ServerToNodeMetadata.class);
|
||||
bind(LoadBalancerService.class).toProvider(Providers.<LoadBalancerService> of(null));
|
||||
bind(LoadBalancerService.class).toProvider(
|
||||
Providers.<LoadBalancerService> of(null));
|
||||
bind(new TypeLiteral<ComputeServiceContext>() {
|
||||
}).to(new TypeLiteral<ComputeServiceContextImpl<GoGridClient, GoGridAsyncClient>>() {
|
||||
}).in(Scopes.SINGLETON);
|
||||
})
|
||||
.to(
|
||||
new TypeLiteral<ComputeServiceContextImpl<GoGridClient, GoGridAsyncClient>>() {
|
||||
}).in(Scopes.SINGLETON);
|
||||
bind(AddNodeWithTagStrategy.class).to(GoGridAddNodeWithTagStrategy.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(DestroyNodeStrategy.class).to(GoGridDestroyNodeStrategy.class);
|
||||
}
|
||||
|
@ -129,26 +132,33 @@ public class GoGridComputeServiceContextModule extends GoGridContextModule {
|
|||
@Singleton
|
||||
public static class GoGridRebootNodeStrategy implements RebootNodeStrategy {
|
||||
private final GoGridClient client;
|
||||
private RetryablePredicate<Server> serverLatestJobCompleted;
|
||||
private final RetryablePredicate<Server> serverLatestJobCompleted;
|
||||
private RetryablePredicate<Server> serverLatestJobCompletedShort;
|
||||
private final GetNodeMetadataStrategy getNode;
|
||||
|
||||
@Inject
|
||||
protected GoGridRebootNodeStrategy(GoGridClient client) {
|
||||
protected GoGridRebootNodeStrategy(GoGridClient client,
|
||||
GetNodeMetadataStrategy getNode, Timeouts timeouts) {
|
||||
this.client = client;
|
||||
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>(
|
||||
new ServerLatestJobCompleted(client.getJobServices()), 60, 20, TimeUnit.SECONDS);
|
||||
new ServerLatestJobCompleted(client.getJobServices()),
|
||||
timeouts.nodeRunning * 1l / 10l);
|
||||
this.getNode = getNode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(String id) {
|
||||
Server server = Iterables.getOnlyElement(client.getServerServices().getServersById(
|
||||
new Long(id)));
|
||||
client.getServerServices().power(server.getName(), PowerCommand.RESTART);
|
||||
public NodeMetadata execute(String id) {
|
||||
Server server = Iterables.getOnlyElement(client.getServerServices()
|
||||
.getServersById(new Long(id)));
|
||||
client.getServerServices().power(server.getName(),
|
||||
PowerCommand.RESTART);
|
||||
serverLatestJobCompleted.apply(server);
|
||||
client.getServerServices().power(server.getName(), PowerCommand.START);
|
||||
return serverLatestJobCompletedShort.apply(server);
|
||||
serverLatestJobCompletedShort.apply(server);
|
||||
return getNode.execute(id);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -159,7 +169,7 @@ public class GoGridComputeServiceContextModule extends GoGridContextModule {
|
|||
|
||||
@Inject
|
||||
protected GoGridListNodesStrategy(GoGridClient client,
|
||||
Function<Server, NodeMetadata> serverToNodeMetadata) {
|
||||
Function<Server, NodeMetadata> serverToNodeMetadata) {
|
||||
this.client = client;
|
||||
this.serverToNodeMetadata = serverToNodeMetadata;
|
||||
}
|
||||
|
@ -171,28 +181,29 @@ public class GoGridComputeServiceContextModule extends GoGridContextModule {
|
|||
|
||||
@Override
|
||||
public Iterable<? extends NodeMetadata> listDetailsOnNodesMatching(
|
||||
Predicate<ComputeMetadata> filter) {
|
||||
return Iterables.filter(Iterables.transform(client.getServerServices().getServerList(),
|
||||
serverToNodeMetadata), filter);
|
||||
Predicate<ComputeMetadata> filter) {
|
||||
return Iterables.filter(Iterables.transform(client.getServerServices()
|
||||
.getServerList(), serverToNodeMetadata), filter);
|
||||
}
|
||||
}
|
||||
|
||||
@Singleton
|
||||
public static class GoGridGetNodeMetadataStrategy implements GetNodeMetadataStrategy {
|
||||
public static class GoGridGetNodeMetadataStrategy implements
|
||||
GetNodeMetadataStrategy {
|
||||
private final GoGridClient client;
|
||||
private final Function<Server, NodeMetadata> serverToNodeMetadata;
|
||||
|
||||
@Inject
|
||||
protected GoGridGetNodeMetadataStrategy(GoGridClient client,
|
||||
Function<Server, NodeMetadata> serverToNodeMetadata) {
|
||||
Function<Server, NodeMetadata> serverToNodeMetadata) {
|
||||
this.client = client;
|
||||
this.serverToNodeMetadata = serverToNodeMetadata;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NodeMetadata execute(String id) {
|
||||
Server server = Iterables.getOnlyElement(client.getServerServices().getServersById(
|
||||
new Long(checkNotNull(id, "id"))));
|
||||
Server server = Iterables.getOnlyElement(client.getServerServices()
|
||||
.getServersById(new Long(checkNotNull(id, "id"))));
|
||||
return server == null ? null : serverToNodeMetadata.apply(server);
|
||||
}
|
||||
}
|
||||
|
@ -200,21 +211,21 @@ public class GoGridComputeServiceContextModule extends GoGridContextModule {
|
|||
@Singleton
|
||||
public static class GoGridDestroyNodeStrategy implements DestroyNodeStrategy {
|
||||
private final GoGridClient client;
|
||||
private RetryablePredicate<Server> serverLatestJobCompleted;
|
||||
private final GetNodeMetadataStrategy getNode;
|
||||
|
||||
@Inject
|
||||
protected GoGridDestroyNodeStrategy(GoGridClient client) {
|
||||
protected GoGridDestroyNodeStrategy(GoGridClient client,
|
||||
GetNodeMetadataStrategy getNode) {
|
||||
this.client = client;
|
||||
this.serverLatestJobCompleted = new RetryablePredicate<Server>(
|
||||
new ServerLatestJobCompleted(client.getJobServices()), 800, 20, TimeUnit.SECONDS);
|
||||
this.getNode = getNode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(String id) {
|
||||
Server server = Iterables.getOnlyElement(client.getServerServices().getServersById(
|
||||
new Long(id)));
|
||||
public NodeMetadata execute(String id) {
|
||||
Server server = Iterables.getOnlyElement(client.getServerServices()
|
||||
.getServersById(new Long(id)));
|
||||
client.getServerServices().deleteById(server.getId());
|
||||
return serverLatestJobCompleted.apply(server);
|
||||
return getNode.execute(id);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -222,18 +233,21 @@ public class GoGridComputeServiceContextModule extends GoGridContextModule {
|
|||
@Singleton
|
||||
@Provides
|
||||
Map<String, NodeState> provideServerToNodeState() {
|
||||
return ImmutableMap.<String, NodeState> builder().put("On", NodeState.RUNNING).put(
|
||||
"Starting", NodeState.PENDING).put("Off", NodeState.SUSPENDED).put("Saving",
|
||||
NodeState.PENDING).put("Restarting", NodeState.PENDING).put("Stopping",
|
||||
NodeState.PENDING).build();
|
||||
return ImmutableMap.<String, NodeState> builder().put("On",
|
||||
NodeState.RUNNING).put("Starting", NodeState.PENDING).put("Off",
|
||||
NodeState.SUSPENDED).put("Saving", NodeState.PENDING).put(
|
||||
"Restarting", NodeState.PENDING).put("Stopping", NodeState.PENDING)
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds matches to required configurations. GoGrid's documentation only specifies how much RAM
|
||||
* one can get with different instance types. The # of cores and disk sizes are purely empyrical
|
||||
* and aren't guaranteed. However, these are the matches found: Ram: 512MB, CPU: 1 core, HDD: 28
|
||||
* GB Ram: 1GB, 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)
|
||||
* Finds matches to required configurations. GoGrid's documentation only
|
||||
* specifies how much RAM one can get with different instance types. The # of
|
||||
* cores and disk sizes are purely empyrical and aren't guaranteed. However,
|
||||
* these are the matches found: Ram: 512MB, CPU: 1 core, HDD: 28 GB Ram: 1GB,
|
||||
* 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
|
||||
*/
|
||||
|
@ -243,9 +257,11 @@ public class GoGridComputeServiceContextModule extends GoGridContextModule {
|
|||
return new Function<Size, String>() {
|
||||
@Override
|
||||
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";
|
||||
if (size.getRam() >= 4 * 1024 || size.getCores() >= 3 || size.getDisk() >= 230)
|
||||
if (size.getRam() >= 4 * 1024 || size.getCores() >= 3
|
||||
|| size.getDisk() >= 230)
|
||||
return "4GB";
|
||||
if (size.getRam() >= 2 * 1024 || size.getDisk() >= 110)
|
||||
return "2GB";
|
||||
|
@ -258,16 +274,9 @@ public class GoGridComputeServiceContextModule extends GoGridContextModule {
|
|||
|
||||
@Provides
|
||||
@Singleton
|
||||
@Named("NOT_RUNNING")
|
||||
protected Predicate<CommandUsingClient> runScriptRunning(ScriptStatusReturnsZero stateRunning) {
|
||||
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) {
|
||||
Location getDefaultLocation(
|
||||
@Named(PROPERTY_GOGRID_DEFAULT_DC) final String defaultDC,
|
||||
Set<? extends Location> locations) {
|
||||
return Iterables.find(locations, new Predicate<Location>() {
|
||||
|
||||
@Override
|
||||
|
@ -280,13 +289,14 @@ public class GoGridComputeServiceContextModule extends GoGridContextModule {
|
|||
|
||||
@Provides
|
||||
@Singleton
|
||||
Set<? extends Location> getDefaultLocations(GoGridClient sync, LogHolder holder,
|
||||
Function<ComputeMetadata, String> indexer) {
|
||||
Set<? extends Location> getDefaultLocations(GoGridClient sync,
|
||||
LogHolder holder, Function<ComputeMetadata, String> indexer) {
|
||||
final Set<Location> locations = Sets.newHashSet();
|
||||
holder.logger.debug(">> providing locations");
|
||||
Location parent = new LocationImpl(LocationScope.PROVIDER, providerName, providerName, null);
|
||||
locations.add(new LocationImpl(LocationScope.ZONE, "SANFRANCISCO", "San Francisco, CA",
|
||||
parent));
|
||||
Location parent = new LocationImpl(LocationScope.PROVIDER, providerName,
|
||||
providerName, null);
|
||||
locations.add(new LocationImpl(LocationScope.ZONE, "SANFRANCISCO",
|
||||
"San Francisco, CA", parent));
|
||||
holder.logger.debug("<< locations(%d)", locations.size());
|
||||
return locations;
|
||||
}
|
||||
|
@ -304,27 +314,28 @@ public class GoGridComputeServiceContextModule extends GoGridContextModule {
|
|||
|
||||
@Provides
|
||||
@Singleton
|
||||
protected Set<? extends Size> provideSizes(GoGridClient sync, Set<? extends Image> images,
|
||||
LogHolder holder, Function<ComputeMetadata, String> indexer)
|
||||
throws InterruptedException, TimeoutException, ExecutionException {
|
||||
protected Set<? extends Size> provideSizes(GoGridClient sync,
|
||||
Set<? extends Image> images, LogHolder holder,
|
||||
Function<ComputeMetadata, String> indexer)
|
||||
throws InterruptedException, TimeoutException, ExecutionException {
|
||||
final Set<Size> sizes = Sets.newHashSet();
|
||||
holder.logger.debug(">> providing sizes");
|
||||
|
||||
sizes.add(new SizeImpl("1", "1", "1", null, null, ImmutableMap.<String, String> of(), 0.5,
|
||||
512, 30, architectureIn(ImmutableSet.<Architecture> of(Architecture.X86_32,
|
||||
Architecture.X86_64))));
|
||||
sizes.add(new SizeImpl("2", "2", "2", null, null, ImmutableMap.<String, String> of(), 1,
|
||||
1024, 60, architectureIn(ImmutableSet.<Architecture> of(Architecture.X86_32,
|
||||
Architecture.X86_64))));
|
||||
sizes.add(new SizeImpl("3", "3", "3", null, null, ImmutableMap.<String, String> of(), 2,
|
||||
2048, 120, architectureIn(ImmutableSet.<Architecture> of(Architecture.X86_32,
|
||||
Architecture.X86_64))));
|
||||
sizes.add(new SizeImpl("4", "4", "4", null, null, ImmutableMap.<String, String> of(), 4,
|
||||
4096, 240, architectureIn(ImmutableSet.<Architecture> of(Architecture.X86_32,
|
||||
Architecture.X86_64))));
|
||||
sizes.add(new SizeImpl("5", "5", "5", null, null, ImmutableMap.<String, String> of(), 8,
|
||||
8192, 480, architectureIn(ImmutableSet.<Architecture> of(Architecture.X86_32,
|
||||
Architecture.X86_64))));
|
||||
sizes.add(new SizeImpl("1", "1", "1", null, null, ImmutableMap
|
||||
.<String, String> of(), 0.5, 512, 30, architectureIn(ImmutableSet
|
||||
.<Architecture> of(Architecture.X86_32, Architecture.X86_64))));
|
||||
sizes.add(new SizeImpl("2", "2", "2", null, null, ImmutableMap
|
||||
.<String, String> of(), 1, 1024, 60, architectureIn(ImmutableSet
|
||||
.<Architecture> of(Architecture.X86_32, Architecture.X86_64))));
|
||||
sizes.add(new SizeImpl("3", "3", "3", null, null, ImmutableMap
|
||||
.<String, String> of(), 2, 2048, 120, architectureIn(ImmutableSet
|
||||
.<Architecture> of(Architecture.X86_32, Architecture.X86_64))));
|
||||
sizes.add(new SizeImpl("4", "4", "4", null, null, ImmutableMap
|
||||
.<String, String> of(), 4, 4096, 240, architectureIn(ImmutableSet
|
||||
.<Architecture> of(Architecture.X86_32, Architecture.X86_64))));
|
||||
sizes.add(new SizeImpl("5", "5", "5", null, null, ImmutableMap
|
||||
.<String, String> of(), 8, 8192, 480, architectureIn(ImmutableSet
|
||||
.<Architecture> of(Architecture.X86_32, Architecture.X86_64))));
|
||||
holder.logger.debug("<< sizes(%d)", sizes.size());
|
||||
return sizes;
|
||||
}
|
||||
|
@ -335,37 +346,42 @@ public class GoGridComputeServiceContextModule extends GoGridContextModule {
|
|||
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
|
||||
@Singleton
|
||||
protected Set<? extends Image> provideImages(final GoGridClient sync, LogHolder holder,
|
||||
Function<ComputeMetadata, String> indexer, Location location,
|
||||
PopulateDefaultLoginCredentialsForImageStrategy authenticator)
|
||||
throws InterruptedException, ExecutionException, TimeoutException {
|
||||
protected Set<? extends Image> provideImages(final GoGridClient sync,
|
||||
LogHolder holder, Function<ComputeMetadata, String> indexer,
|
||||
Location location,
|
||||
PopulateDefaultLoginCredentialsForImageStrategy authenticator)
|
||||
throws InterruptedException, ExecutionException, TimeoutException {
|
||||
final Set<Image> images = Sets.newHashSet();
|
||||
holder.logger.debug(">> providing images");
|
||||
Set<ServerImage> allImages = sync.getImageServices().getImageList();
|
||||
for (ServerImage from : allImages) {
|
||||
OsFamily os = null;
|
||||
Architecture arch = (from.getOs().getName().indexOf("64") == -1 && from.getDescription()
|
||||
.indexOf("64") == -1) ? Architecture.X86_32 : Architecture.X86_64;
|
||||
Architecture arch = (from.getOs().getName().indexOf("64") == -1 && from
|
||||
.getDescription().indexOf("64") == -1) ? Architecture.X86_32
|
||||
: Architecture.X86_64;
|
||||
String osDescription;
|
||||
String version = "";
|
||||
|
||||
osDescription = from.getOs().getName();
|
||||
|
||||
String matchedOs = GoGridUtils.parseStringByPatternAndGetNthMatchGroup(from.getOs()
|
||||
.getName(), GOGRID_OS_NAME_PATTERN, 1);
|
||||
String matchedOs = GoGridUtils
|
||||
.parseStringByPatternAndGetNthMatchGroup(from.getOs().getName(),
|
||||
GOGRID_OS_NAME_PATTERN, 1);
|
||||
try {
|
||||
os = OsFamily.fromValue(matchedOs.toLowerCase());
|
||||
} catch (IllegalArgumentException e) {
|
||||
holder.logger.debug("<< didn't match os(%s)", matchedOs);
|
||||
}
|
||||
Credentials defaultCredentials = authenticator.execute(from);
|
||||
images.add(new ImageImpl(from.getId() + "", from.getFriendlyName(), from.getId() + "",
|
||||
location, null, ImmutableMap.<String, String> of(), from.getDescription(),
|
||||
version, os, osDescription, arch, defaultCredentials));
|
||||
images.add(new ImageImpl(from.getId() + "", from.getFriendlyName(),
|
||||
from.getId() + "", location, null, ImmutableMap
|
||||
.<String, String> of(), from.getDescription(), version,
|
||||
os, osDescription, arch, defaultCredentials));
|
||||
}
|
||||
holder.logger.debug("<< images(%d)", images.size());
|
||||
return images;
|
||||
|
|
|
@ -22,7 +22,6 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
@ -30,6 +29,7 @@ import javax.inject.Singleton;
|
|||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.Size;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants.Timeouts;
|
||||
import org.jclouds.compute.strategy.AddNodeWithTagStrategy;
|
||||
import org.jclouds.gogrid.GoGridClient;
|
||||
import org.jclouds.gogrid.domain.Ip;
|
||||
|
@ -57,14 +57,17 @@ public class GoGridAddNodeWithTagStrategy implements AddNodeWithTagStrategy {
|
|||
|
||||
@Inject
|
||||
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.serverToNodeMetadata = serverToNodeMetadata;
|
||||
this.sizeToRam = sizeToRam;
|
||||
this.serverLatestJobCompleted = new RetryablePredicate<Server>(new ServerLatestJobCompleted(
|
||||
client.getJobServices()), 800, 20, TimeUnit.SECONDS);
|
||||
this.serverLatestJobCompleted = new RetryablePredicate<Server>(
|
||||
new ServerLatestJobCompleted(client.getJobServices()),
|
||||
timeouts.nodeRunning * 9l / 10l);
|
||||
this.serverLatestJobCompletedShort = new RetryablePredicate<Server>(
|
||||
new ServerLatestJobCompleted(client.getJobServices()), 60, 20, TimeUnit.SECONDS);
|
||||
new ServerLatestJobCompleted(client.getJobServices()),
|
||||
timeouts.nodeRunning * 1l / 10l);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -73,12 +76,15 @@ public class GoGridAddNodeWithTagStrategy implements AddNodeWithTagStrategy {
|
|||
boolean notStarted = true;
|
||||
int numOfRetries = 20;
|
||||
// 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
|
||||
Set<Ip> availableIps = client.getIpServices().getIpList(
|
||||
new GetIpListOptions().onlyUnassigned().onlyWithType(IpType.PUBLIC));
|
||||
new GetIpListOptions().onlyUnassigned().onlyWithType(
|
||||
IpType.PUBLIC));
|
||||
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());
|
||||
Ip availableIp = Iterables.get(availableIps, ipIndex);
|
||||
try {
|
||||
|
@ -90,21 +96,22 @@ public class GoGridAddNodeWithTagStrategy implements AddNodeWithTagStrategy {
|
|||
notStarted = true;
|
||||
}
|
||||
}
|
||||
serverLatestJobCompleted.apply(addedServer);
|
||||
|
||||
client.getServerServices().power(addedServer.getName(), PowerCommand.START);
|
||||
serverLatestJobCompletedShort.apply(addedServer);
|
||||
|
||||
addedServer = Iterables.getOnlyElement(client.getServerServices().getServersByName(
|
||||
addedServer.getName()));
|
||||
if (template.getOptions().shouldBlockUntilRunning()) {
|
||||
serverLatestJobCompleted.apply(addedServer);
|
||||
client.getServerServices().power(addedServer.getName(),
|
||||
PowerCommand.START);
|
||||
serverLatestJobCompletedShort.apply(addedServer);
|
||||
addedServer = Iterables.getOnlyElement(client.getServerServices()
|
||||
.getServersByName(addedServer.getName()));
|
||||
}
|
||||
return serverToNodeMetadata.apply(addedServer);
|
||||
}
|
||||
|
||||
private Server addServer(String name, Template template, Ip availableIp) {
|
||||
Server addedServer;
|
||||
addedServer = client.getServerServices().addServer(name,
|
||||
checkNotNull(template.getImage().getProviderId()),
|
||||
sizeToRam.apply(template.getSize()), availableIp.getIp());
|
||||
checkNotNull(template.getImage().getProviderId()),
|
||||
sizeToRam.apply(template.getSize()), availableIp.getIp());
|
||||
return addedServer;
|
||||
}
|
||||
}
|
|
@ -60,13 +60,9 @@ import org.jclouds.http.RequiresHttp;
|
|||
import org.jclouds.http.annotation.ClientError;
|
||||
import org.jclouds.http.annotation.Redirection;
|
||||
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.config.RestClientModule;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Maps;
|
||||
|
@ -80,15 +76,16 @@ import com.google.inject.Provides;
|
|||
*/
|
||||
@RequiresHttp
|
||||
@ConfiguresRestClient
|
||||
public class GoGridRestClientModule extends RestClientModule<GoGridClient, GoGridAsyncClient> {
|
||||
public class GoGridRestClientModule extends
|
||||
RestClientModule<GoGridClient, GoGridAsyncClient> {
|
||||
public static final Map<Class<?>, Class<?>> DELEGATE_MAP = ImmutableMap
|
||||
.<Class<?>, Class<?>> builder()//
|
||||
.put(GridServerClient.class, GridServerAsyncClient.class)//
|
||||
.put(GridJobClient.class, GridJobAsyncClient.class)//
|
||||
.put(GridIpClient.class, GridIpAsyncClient.class)//
|
||||
.put(GridLoadBalancerClient.class, GridLoadBalancerAsyncClient.class)//
|
||||
.put(GridImageClient.class, GridImageAsyncClient.class)//
|
||||
.build();
|
||||
.<Class<?>, Class<?>> builder()//
|
||||
.put(GridServerClient.class, GridServerAsyncClient.class)//
|
||||
.put(GridJobClient.class, GridJobAsyncClient.class)//
|
||||
.put(GridIpClient.class, GridIpAsyncClient.class)//
|
||||
.put(GridLoadBalancerClient.class, GridLoadBalancerAsyncClient.class)//
|
||||
.put(GridImageClient.class, GridImageAsyncClient.class)//
|
||||
.build();
|
||||
|
||||
public GoGridRestClientModule() {
|
||||
super(GoGridClient.class, GoGridAsyncClient.class, DELEGATE_MAP);
|
||||
|
@ -97,7 +94,8 @@ public class GoGridRestClientModule extends RestClientModule<GoGridClient, GoGri
|
|||
@Provides
|
||||
@Singleton
|
||||
@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);
|
||||
}
|
||||
|
||||
|
@ -107,28 +105,28 @@ public class GoGridRestClientModule extends RestClientModule<GoGridClient, GoGri
|
|||
return cache.get();
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
protected Predicate<IPSocket> socketTester(SocketOpen open) {
|
||||
return new RetryablePredicate<IPSocket>(open, 130, 1, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Provides
|
||||
@Singleton
|
||||
@com.google.inject.name.Named(Constants.PROPERTY_GSON_ADAPTERS)
|
||||
public Map<Class, Object> provideCustomAdapterBindings() {
|
||||
Map<Class, Object> bindings = Maps.newHashMap();
|
||||
bindings.put(ObjectType.class, new CustomDeserializers.ObjectTypeAdapter());
|
||||
bindings.put(LoadBalancerOs.class, new CustomDeserializers.LoadBalancerOsAdapter());
|
||||
bindings.put(LoadBalancerState.class, new CustomDeserializers.LoadBalancerStateAdapter());
|
||||
bindings.put(ObjectType.class,
|
||||
new CustomDeserializers.ObjectTypeAdapter());
|
||||
bindings.put(LoadBalancerOs.class,
|
||||
new CustomDeserializers.LoadBalancerOsAdapter());
|
||||
bindings.put(LoadBalancerState.class,
|
||||
new CustomDeserializers.LoadBalancerStateAdapter());
|
||||
bindings.put(LoadBalancerPersistenceType.class,
|
||||
new CustomDeserializers.LoadBalancerPersistenceTypeAdapter());
|
||||
bindings.put(LoadBalancerType.class, new CustomDeserializers.LoadBalancerTypeAdapter());
|
||||
new CustomDeserializers.LoadBalancerPersistenceTypeAdapter());
|
||||
bindings.put(LoadBalancerType.class,
|
||||
new CustomDeserializers.LoadBalancerTypeAdapter());
|
||||
bindings.put(IpState.class, new CustomDeserializers.IpStateAdapter());
|
||||
bindings.put(JobState.class, new CustomDeserializers.JobStateAdapter());
|
||||
bindings.put(ServerImageState.class, new CustomDeserializers.ServerImageStateAdapter());
|
||||
bindings.put(ServerImageType.class, new CustomDeserializers.ServerImageTypeAdapter());
|
||||
bindings.put(ServerImageState.class,
|
||||
new CustomDeserializers.ServerImageStateAdapter());
|
||||
bindings.put(ServerImageType.class,
|
||||
new CustomDeserializers.ServerImageTypeAdapter());
|
||||
return bindings;
|
||||
}
|
||||
|
||||
|
@ -137,7 +135,8 @@ public class GoGridRestClientModule extends RestClientModule<GoGridClient, GoGri
|
|||
*/
|
||||
@Provides
|
||||
@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>() {
|
||||
public Long get() {
|
||||
return System.currentTimeMillis() / 1000;
|
||||
|
@ -147,9 +146,12 @@ public class GoGridRestClientModule extends RestClientModule<GoGridClient, GoGri
|
|||
|
||||
@Override
|
||||
protected void bindErrorHandlers() {
|
||||
bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(GoGridErrorHandler.class);
|
||||
bind(HttpErrorHandler.class).annotatedWith(ClientError.class).to(GoGridErrorHandler.class);
|
||||
bind(HttpErrorHandler.class).annotatedWith(ServerError.class).to(GoGridErrorHandler.class);
|
||||
bind(HttpErrorHandler.class).annotatedWith(Redirection.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.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);
|
||||
|
||||
Map<String, Credentials> credentialsMap = createMock(Map.class);
|
||||
|
|
|
@ -27,7 +27,6 @@ import java.util.Map;
|
|||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Inject;
|
||||
|
@ -37,6 +36,7 @@ import javax.inject.Singleton;
|
|||
import org.jclouds.Constants;
|
||||
import org.jclouds.compute.ComputeServiceContext;
|
||||
import org.jclouds.compute.LoadBalancerService;
|
||||
import org.jclouds.compute.config.ComputeServiceTimeoutsModule;
|
||||
import org.jclouds.compute.domain.Architecture;
|
||||
import org.jclouds.compute.domain.ComputeMetadata;
|
||||
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.internal.ComputeServiceContextImpl;
|
||||
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.strategy.AddNodeWithTagStrategy;
|
||||
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.reference.IBMDeveloperCloudConstants;
|
||||
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.Predicate;
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Maps;
|
||||
|
@ -91,7 +85,8 @@ import com.google.inject.util.Providers;
|
|||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class IBMDeveloperCloudComputeServiceContextModule extends IBMDeveloperCloudContextModule {
|
||||
public class IBMDeveloperCloudComputeServiceContextModule extends
|
||||
IBMDeveloperCloudContextModule {
|
||||
|
||||
private final String providerName;
|
||||
|
||||
|
@ -103,25 +98,26 @@ public class IBMDeveloperCloudComputeServiceContextModule extends IBMDeveloperCl
|
|||
@Override
|
||||
protected void configure() {
|
||||
super.configure();
|
||||
install(new ComputeServiceTimeoutsModule());
|
||||
bind(new TypeLiteral<Function<Instance, NodeMetadata>>() {
|
||||
}).to(InstanceToNodeMetadata.class);
|
||||
bind(new TypeLiteral<ComputeServiceContext>() {
|
||||
})
|
||||
.to(
|
||||
new TypeLiteral<ComputeServiceContextImpl<IBMDeveloperCloudClient, IBMDeveloperCloudAsyncClient>>() {
|
||||
}).in(Scopes.SINGLETON);
|
||||
bind(AddNodeWithTagStrategy.class).to(IBMDeveloperCloudAddNodeWithTagStrategy.class);
|
||||
bind(ListNodesStrategy.class).to(IBMDeveloperCloudListNodesStrategy.class);
|
||||
bind(GetNodeMetadataStrategy.class).to(IBMDeveloperCloudGetNodeMetadataStrategy.class);
|
||||
bind(RebootNodeStrategy.class).to(IBMDeveloperCloudRebootNodeStrategy.class);
|
||||
bind(DestroyNodeStrategy.class).to(IBMDeveloperCloudDestroyNodeStrategy.class);
|
||||
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);
|
||||
.to(
|
||||
new TypeLiteral<ComputeServiceContextImpl<IBMDeveloperCloudClient, IBMDeveloperCloudAsyncClient>>() {
|
||||
}).in(Scopes.SINGLETON);
|
||||
bind(AddNodeWithTagStrategy.class).to(
|
||||
IBMDeveloperCloudAddNodeWithTagStrategy.class);
|
||||
bind(ListNodesStrategy.class)
|
||||
.to(IBMDeveloperCloudListNodesStrategy.class);
|
||||
bind(GetNodeMetadataStrategy.class).to(
|
||||
IBMDeveloperCloudGetNodeMetadataStrategy.class);
|
||||
bind(RebootNodeStrategy.class).to(
|
||||
IBMDeveloperCloudRebootNodeStrategy.class);
|
||||
bind(DestroyNodeStrategy.class).to(
|
||||
IBMDeveloperCloudDestroyNodeStrategy.class);
|
||||
bind(LoadBalancerService.class).toProvider(
|
||||
Providers.<LoadBalancerService> of(null));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -149,25 +145,29 @@ public class IBMDeveloperCloudComputeServiceContextModule extends IBMDeveloperCl
|
|||
|
||||
@Singleton
|
||||
public static class CreateKeyPairEncodeTagIntoNameRunNodesAndAddToSet extends
|
||||
EncodeTagIntoNameRunNodesAndAddToSetStrategy {
|
||||
EncodeTagIntoNameRunNodesAndAddToSetStrategy {
|
||||
private final IBMDeveloperCloudClient client;
|
||||
private final Map<String, String> credentialsMap;
|
||||
|
||||
@Inject
|
||||
protected CreateKeyPairEncodeTagIntoNameRunNodesAndAddToSet(
|
||||
AddNodeWithTagStrategy addNodeWithTagStrategy, ListNodesStrategy listNodesStrategy,
|
||||
@Named("NAMING_CONVENTION") String nodeNamingConvention, ComputeUtils utils,
|
||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor,
|
||||
IBMDeveloperCloudClient client,
|
||||
@Named("CREDENTIALS") Map<String, String> credentialsMap) {
|
||||
super(addNodeWithTagStrategy, listNodesStrategy, nodeNamingConvention, utils, executor);
|
||||
AddNodeWithTagStrategy addNodeWithTagStrategy,
|
||||
ListNodesStrategy listNodesStrategy,
|
||||
@Named("NAMING_CONVENTION") String nodeNamingConvention,
|
||||
ComputeUtils utils,
|
||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor,
|
||||
IBMDeveloperCloudClient client,
|
||||
@Named("CREDENTIALS") Map<String, String> credentialsMap) {
|
||||
super(addNodeWithTagStrategy, listNodesStrategy, nodeNamingConvention,
|
||||
utils, executor);
|
||||
this.client = checkNotNull(client, "client");
|
||||
this.credentialsMap = checkNotNull(credentialsMap, "credentialsMap");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<?, ListenableFuture<Void>> execute(String tag, int count, Template template,
|
||||
Set<NodeMetadata> nodes, Map<NodeMetadata, Exception> badNodes) {
|
||||
public Map<?, ListenableFuture<Void>> execute(String tag, int count,
|
||||
Template template, Set<NodeMetadata> nodes,
|
||||
Map<NodeMetadata, Exception> badNodes) {
|
||||
String key = template.getOptions().getPublicKey();
|
||||
if (key != null) {
|
||||
template.getOptions().dontAuthorizePublicKey();
|
||||
|
@ -178,7 +178,8 @@ public class IBMDeveloperCloudComputeServiceContextModule extends IBMDeveloperCl
|
|||
client.updatePublicKey(tag, key);
|
||||
}
|
||||
} else {
|
||||
credentialsMap.put(tag, client.generateKeyPair(tag).getKeyMaterial());
|
||||
credentialsMap.put(tag, client.generateKeyPair(tag)
|
||||
.getKeyMaterial());
|
||||
}
|
||||
return super.execute(tag, count, template, nodes, badNodes);
|
||||
}
|
||||
|
@ -186,78 +187,81 @@ public class IBMDeveloperCloudComputeServiceContextModule extends IBMDeveloperCl
|
|||
}
|
||||
|
||||
@Singleton
|
||||
public static class IBMDeveloperCloudAddNodeWithTagStrategy implements AddNodeWithTagStrategy {
|
||||
public static class IBMDeveloperCloudAddNodeWithTagStrategy implements
|
||||
AddNodeWithTagStrategy {
|
||||
|
||||
private final IBMDeveloperCloudClient client;
|
||||
private final Predicate<Instance> instanceActive;
|
||||
private final Function<Instance, NodeMetadata> instanceToNodeMetadata;
|
||||
|
||||
@Inject
|
||||
protected IBMDeveloperCloudAddNodeWithTagStrategy(IBMDeveloperCloudClient client,
|
||||
@Named("ACTIVE") Predicate<Instance> instanceActive,
|
||||
Function<Instance, NodeMetadata> instanceToNodeMetadata) {
|
||||
protected IBMDeveloperCloudAddNodeWithTagStrategy(
|
||||
IBMDeveloperCloudClient client,
|
||||
Function<Instance, NodeMetadata> instanceToNodeMetadata) {
|
||||
this.client = checkNotNull(client, "client");
|
||||
this.instanceActive = checkNotNull(instanceActive, "instanceActive");
|
||||
this.instanceToNodeMetadata = checkNotNull(instanceToNodeMetadata,
|
||||
"instanceToNodeMetadata");
|
||||
"instanceToNodeMetadata");
|
||||
}
|
||||
|
||||
@Override
|
||||
public NodeMetadata execute(String tag, String name, Template template) {
|
||||
Instance instance = client.createInstanceInLocation(template.getLocation().getId(), name,
|
||||
template.getImage().getProviderId(), template.getSize().getProviderId(),
|
||||
authorizePublicKey(tag));
|
||||
instanceActive.apply(instance);
|
||||
return instanceToNodeMetadata.apply(client.getInstance(instance.getId()));
|
||||
Instance instance = client.createInstanceInLocation(template
|
||||
.getLocation().getId(), name, template.getImage()
|
||||
.getProviderId(), template.getSize().getProviderId(),
|
||||
authorizePublicKey(tag));
|
||||
return instanceToNodeMetadata.apply(client.getInstance(instance
|
||||
.getId()));
|
||||
}
|
||||
}
|
||||
|
||||
@Singleton
|
||||
public static class IBMDeveloperCloudRebootNodeStrategy implements RebootNodeStrategy {
|
||||
public static class IBMDeveloperCloudRebootNodeStrategy implements
|
||||
RebootNodeStrategy {
|
||||
|
||||
private final IBMDeveloperCloudClient client;
|
||||
private final Predicate<Instance> instanceActive;
|
||||
private final GetNodeMetadataStrategy getNode;
|
||||
|
||||
@Inject
|
||||
protected IBMDeveloperCloudRebootNodeStrategy(IBMDeveloperCloudClient client,
|
||||
@Named("ACTIVE") Predicate<Instance> instanceActive) {
|
||||
protected IBMDeveloperCloudRebootNodeStrategy(
|
||||
IBMDeveloperCloudClient client, GetNodeMetadataStrategy getNode) {
|
||||
this.client = checkNotNull(client, "client");
|
||||
this.instanceActive = checkNotNull(instanceActive, "instanceActive");
|
||||
this.getNode = checkNotNull(getNode, "getNode");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(String id) {
|
||||
public NodeMetadata execute(String id) {
|
||||
client.restartInstance(id);
|
||||
return instanceActive.apply(client.getInstance(id));
|
||||
return getNode.execute(id);
|
||||
}
|
||||
}
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
Map<Instance.Status, NodeState> provideServerToNodeState() {
|
||||
return ImmutableMap.<Instance.Status, NodeState> builder().put(Instance.Status.ACTIVE,
|
||||
NodeState.RUNNING)//
|
||||
.put(Instance.Status.STOPPED, NodeState.SUSPENDED)//
|
||||
.put(Instance.Status.REMOVED, NodeState.TERMINATED)//
|
||||
.put(Instance.Status.DEPROVISIONING, NodeState.PENDING)//
|
||||
.put(Instance.Status.FAILED, NodeState.ERROR)//
|
||||
.put(Instance.Status.NEW, NodeState.PENDING)//
|
||||
.put(Instance.Status.PROVISIONING, NodeState.PENDING)//
|
||||
.put(Instance.Status.REJECTED, NodeState.ERROR)//
|
||||
.put(Instance.Status.RESTARTING, NodeState.PENDING)//
|
||||
.put(Instance.Status.STARTING, NodeState.PENDING)//
|
||||
.put(Instance.Status.STOPPING, NodeState.PENDING)//
|
||||
.put(Instance.Status.UNKNOWN, NodeState.UNKNOWN).build();
|
||||
return ImmutableMap.<Instance.Status, NodeState> builder().put(
|
||||
Instance.Status.ACTIVE, NodeState.RUNNING)//
|
||||
.put(Instance.Status.STOPPED, NodeState.SUSPENDED)//
|
||||
.put(Instance.Status.REMOVED, NodeState.TERMINATED)//
|
||||
.put(Instance.Status.DEPROVISIONING, NodeState.PENDING)//
|
||||
.put(Instance.Status.FAILED, NodeState.ERROR)//
|
||||
.put(Instance.Status.NEW, NodeState.PENDING)//
|
||||
.put(Instance.Status.PROVISIONING, NodeState.PENDING)//
|
||||
.put(Instance.Status.REJECTED, NodeState.ERROR)//
|
||||
.put(Instance.Status.RESTARTING, NodeState.PENDING)//
|
||||
.put(Instance.Status.STARTING, NodeState.PENDING)//
|
||||
.put(Instance.Status.STOPPING, NodeState.PENDING)//
|
||||
.put(Instance.Status.UNKNOWN, NodeState.UNKNOWN).build();
|
||||
}
|
||||
|
||||
@Singleton
|
||||
public static class IBMDeveloperCloudListNodesStrategy implements ListNodesStrategy {
|
||||
public static class IBMDeveloperCloudListNodesStrategy implements
|
||||
ListNodesStrategy {
|
||||
private final IBMDeveloperCloudClient client;
|
||||
private final Function<Instance, NodeMetadata> instanceToNodeMetadata;
|
||||
|
||||
@Inject
|
||||
protected IBMDeveloperCloudListNodesStrategy(IBMDeveloperCloudClient client,
|
||||
Function<Instance, NodeMetadata> instanceToNodeMetadata) {
|
||||
protected IBMDeveloperCloudListNodesStrategy(
|
||||
IBMDeveloperCloudClient client,
|
||||
Function<Instance, NodeMetadata> instanceToNodeMetadata) {
|
||||
this.client = client;
|
||||
this.instanceToNodeMetadata = instanceToNodeMetadata;
|
||||
}
|
||||
|
@ -269,20 +273,22 @@ public class IBMDeveloperCloudComputeServiceContextModule extends IBMDeveloperCl
|
|||
|
||||
@Override
|
||||
public Iterable<? extends NodeMetadata> listDetailsOnNodesMatching(
|
||||
Predicate<ComputeMetadata> filter) {
|
||||
return Iterables.filter(Iterables
|
||||
.transform(client.listInstances(), instanceToNodeMetadata), filter);
|
||||
Predicate<ComputeMetadata> filter) {
|
||||
return Iterables.filter(Iterables.transform(client.listInstances(),
|
||||
instanceToNodeMetadata), filter);
|
||||
}
|
||||
}
|
||||
|
||||
@Singleton
|
||||
public static class IBMDeveloperCloudGetNodeMetadataStrategy implements GetNodeMetadataStrategy {
|
||||
public static class IBMDeveloperCloudGetNodeMetadataStrategy implements
|
||||
GetNodeMetadataStrategy {
|
||||
private final IBMDeveloperCloudClient client;
|
||||
private final Function<Instance, NodeMetadata> instanceToNodeMetadata;
|
||||
|
||||
@Inject
|
||||
protected IBMDeveloperCloudGetNodeMetadataStrategy(IBMDeveloperCloudClient client,
|
||||
Function<Instance, NodeMetadata> instanceToNodeMetadata) {
|
||||
protected IBMDeveloperCloudGetNodeMetadataStrategy(
|
||||
IBMDeveloperCloudClient client,
|
||||
Function<Instance, NodeMetadata> instanceToNodeMetadata) {
|
||||
this.client = client;
|
||||
this.instanceToNodeMetadata = instanceToNodeMetadata;
|
||||
}
|
||||
|
@ -290,42 +296,36 @@ public class IBMDeveloperCloudComputeServiceContextModule extends IBMDeveloperCl
|
|||
@Override
|
||||
public NodeMetadata execute(String id) {
|
||||
Instance instance = client.getInstance(checkNotNull(id, "id"));
|
||||
return instance == null ? null : instanceToNodeMetadata.apply(instance);
|
||||
return instance == null ? null : instanceToNodeMetadata
|
||||
.apply(instance);
|
||||
}
|
||||
}
|
||||
|
||||
@Singleton
|
||||
public static class IBMDeveloperCloudDestroyNodeStrategy implements DestroyNodeStrategy {
|
||||
public static class IBMDeveloperCloudDestroyNodeStrategy implements
|
||||
DestroyNodeStrategy {
|
||||
private final IBMDeveloperCloudClient client;
|
||||
private final Predicate<Instance> instanceRemoved;
|
||||
private final GetNodeMetadataStrategy getNode;
|
||||
|
||||
@Inject
|
||||
protected IBMDeveloperCloudDestroyNodeStrategy(IBMDeveloperCloudClient client,
|
||||
@Named("REMOVED") Predicate<Instance> instanceRemoved) {
|
||||
protected IBMDeveloperCloudDestroyNodeStrategy(
|
||||
IBMDeveloperCloudClient client, GetNodeMetadataStrategy getNode) {
|
||||
this.client = checkNotNull(client, "client");
|
||||
this.instanceRemoved = checkNotNull(instanceRemoved, "instanceRemoved");
|
||||
this.getNode = checkNotNull(getNode, "getNode");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(String id) {
|
||||
public NodeMetadata execute(String 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
|
||||
@Singleton
|
||||
Location getDefaultLocation(
|
||||
@Named(PROPERTY_IBMDEVELOPERCLOUD_LOCATION) final String defaultLocation,
|
||||
Set<? extends Location> locations) {
|
||||
@Named(PROPERTY_IBMDEVELOPERCLOUD_LOCATION) final String defaultLocation,
|
||||
Set<? extends Location> locations) {
|
||||
return Iterables.find(locations, new Predicate<Location>() {
|
||||
|
||||
@Override
|
||||
|
@ -338,14 +338,16 @@ public class IBMDeveloperCloudComputeServiceContextModule extends IBMDeveloperCl
|
|||
|
||||
@Provides
|
||||
@Singleton
|
||||
Set<? extends Location> getAssignableLocations(IBMDeveloperCloudClient sync, LogHolder holder) {
|
||||
Set<? extends Location> getAssignableLocations(IBMDeveloperCloudClient sync,
|
||||
LogHolder holder) {
|
||||
final Set<Location> assignableLocations = Sets.newHashSet();
|
||||
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())
|
||||
assignableLocations.add(new LocationImpl(LocationScope.ZONE, location.getId(), location
|
||||
.getName(), parent));
|
||||
assignableLocations.add(new LocationImpl(LocationScope.ZONE, location
|
||||
.getId(), location.getName(), parent));
|
||||
|
||||
holder.logger.debug("<< locations(%d)", assignableLocations.size());
|
||||
return assignableLocations;
|
||||
|
@ -353,45 +355,50 @@ public class IBMDeveloperCloudComputeServiceContextModule extends IBMDeveloperCl
|
|||
|
||||
@Provides
|
||||
@Singleton
|
||||
protected Set<? extends Size> provideSizes(IBMDeveloperCloudClient sync, LogHolder holder,
|
||||
Map<String, ? extends Location> locations) {
|
||||
protected Set<? extends Size> provideSizes(IBMDeveloperCloudClient sync,
|
||||
LogHolder holder, Map<String, ? extends Location> locations) {
|
||||
final Set<Size> sizes = Sets.newHashSet();
|
||||
holder.logger.debug(">> providing sizes");
|
||||
|
||||
for (org.jclouds.ibmdev.domain.Location location : sync.listLocations()) {
|
||||
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;
|
||||
for (String i386 : location.getCapabilities().get(
|
||||
IBMDeveloperCloudConstants.CAPABILITY_I386).keySet())
|
||||
sizes.add(buildSize(location, i386, assignedLocation, sizeMultiplier++));
|
||||
IBMDeveloperCloudConstants.CAPABILITY_I386).keySet())
|
||||
sizes.add(buildSize(location, i386, assignedLocation,
|
||||
sizeMultiplier++));
|
||||
for (String x86_64 : location.getCapabilities().get(
|
||||
IBMDeveloperCloudConstants.CAPABILITY_x86_64).keySet())
|
||||
sizes.add(buildSize(location, x86_64, assignedLocation, sizeMultiplier++));
|
||||
IBMDeveloperCloudConstants.CAPABILITY_x86_64).keySet())
|
||||
sizes.add(buildSize(location, x86_64, assignedLocation,
|
||||
sizeMultiplier++));
|
||||
}
|
||||
holder.logger.debug("<< sizes(%d)", sizes.size());
|
||||
return sizes;
|
||||
}
|
||||
|
||||
private SizeImpl buildSize(org.jclouds.ibmdev.domain.Location location, final String id,
|
||||
Location assignedLocation, int multiplier) {
|
||||
return new SizeImpl(id, id, location.getId() + "/" + id, assignedLocation, null, ImmutableMap
|
||||
.<String, String> of(), multiplier, multiplier * 1024, multiplier * 10,
|
||||
new Predicate<Image>() {
|
||||
@Override
|
||||
public boolean apply(Image input) {
|
||||
if (input instanceof IBMImage)
|
||||
return IBMImage.class.cast(input).rawImage.getSupportedInstanceTypes()
|
||||
.contains(id);
|
||||
return false;
|
||||
}
|
||||
private SizeImpl buildSize(org.jclouds.ibmdev.domain.Location location,
|
||||
final String id, Location assignedLocation, int multiplier) {
|
||||
return new SizeImpl(id, id, location.getId() + "/" + id,
|
||||
assignedLocation, null, ImmutableMap.<String, String> of(),
|
||||
multiplier, multiplier * 1024, multiplier * 10,
|
||||
new Predicate<Image>() {
|
||||
@Override
|
||||
public boolean apply(Image input) {
|
||||
if (input instanceof IBMImage)
|
||||
return IBMImage.class.cast(input).rawImage
|
||||
.getSupportedInstanceTypes().contains(id);
|
||||
return false;
|
||||
}
|
||||
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@Provides
|
||||
@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>() {
|
||||
|
||||
@Override
|
||||
|
@ -404,7 +411,8 @@ public class IBMDeveloperCloudComputeServiceContextModule extends IBMDeveloperCl
|
|||
|
||||
@Provides
|
||||
@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>() {
|
||||
|
||||
@Override
|
||||
|
@ -417,8 +425,9 @@ public class IBMDeveloperCloudComputeServiceContextModule extends IBMDeveloperCl
|
|||
|
||||
@Provides
|
||||
@Singleton
|
||||
protected Set<? extends Image> provideImages(final IBMDeveloperCloudClient sync,
|
||||
LogHolder holder, Map<String, ? extends Location> locations) {
|
||||
protected Set<? extends Image> provideImages(
|
||||
final IBMDeveloperCloudClient sync, LogHolder holder,
|
||||
Map<String, ? extends Location> locations) {
|
||||
final Set<Image> images = Sets.newHashSet();
|
||||
holder.logger.debug(">> providing images");
|
||||
|
||||
|
@ -441,12 +450,14 @@ public class IBMDeveloperCloudComputeServiceContextModule extends IBMDeveloperCl
|
|||
// TODO manifest fails to parse due to encoding issues in the path
|
||||
// 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
|
||||
super(in.getId(), in.getName(), in.getId(), location, null, ImmutableMap
|
||||
.<String, String> of(), in.getDescription(), in.getCreatedTime().getTime() + "",
|
||||
(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));
|
||||
super(in.getId(), in.getName(), in.getId(), location, null,
|
||||
ImmutableMap.<String, String> of(), in.getDescription(), in
|
||||
.getCreatedTime().getTime()
|
||||
+ "",
|
||||
(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));
|
||||
this.rawImage = in;
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,6 @@ package org.jclouds.ibmdev.config;
|
|||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URI;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
@ -35,16 +34,11 @@ import org.jclouds.http.filters.BasicAuthentication;
|
|||
import org.jclouds.ibmdev.IBMDeveloperCloud;
|
||||
import org.jclouds.ibmdev.IBMDeveloperCloudAsyncClient;
|
||||
import org.jclouds.ibmdev.IBMDeveloperCloudClient;
|
||||
import org.jclouds.ibmdev.domain.Instance;
|
||||
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.predicates.RetryablePredicate;
|
||||
import org.jclouds.rest.ConfiguresRestClient;
|
||||
import org.jclouds.rest.config.RestClientModule;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.inject.Provides;
|
||||
|
||||
/**
|
||||
|
@ -55,19 +49,19 @@ import com.google.inject.Provides;
|
|||
@RequiresHttp
|
||||
@ConfiguresRestClient
|
||||
public class IBMDeveloperCloudRestClientModule extends
|
||||
RestClientModule<IBMDeveloperCloudClient, IBMDeveloperCloudAsyncClient> {
|
||||
RestClientModule<IBMDeveloperCloudClient, IBMDeveloperCloudAsyncClient> {
|
||||
|
||||
public IBMDeveloperCloudRestClientModule() {
|
||||
super(IBMDeveloperCloudClient.class, IBMDeveloperCloudAsyncClient.class);
|
||||
}
|
||||
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
public BasicAuthentication provideBasicAuthentication(
|
||||
@Named(IBMDeveloperCloudConstants.PROPERTY_IBMDEVELOPERCLOUD_USER) String user,
|
||||
@Named(IBMDeveloperCloudConstants.PROPERTY_IBMDEVELOPERCLOUD_PASSWORD) String password,
|
||||
EncryptionService encryptionService) throws UnsupportedEncodingException {
|
||||
@Named(IBMDeveloperCloudConstants.PROPERTY_IBMDEVELOPERCLOUD_USER) String user,
|
||||
@Named(IBMDeveloperCloudConstants.PROPERTY_IBMDEVELOPERCLOUD_PASSWORD) String password,
|
||||
EncryptionService encryptionService)
|
||||
throws UnsupportedEncodingException {
|
||||
return new BasicAuthentication(user, password, encryptionService);
|
||||
}
|
||||
|
||||
|
@ -75,18 +69,18 @@ public class IBMDeveloperCloudRestClientModule extends
|
|||
@Singleton
|
||||
@IBMDeveloperCloud
|
||||
protected URI provideURI(
|
||||
@Named(IBMDeveloperCloudConstants.PROPERTY_IBMDEVELOPERCLOUD_ENDPOINT) String endpoint) {
|
||||
@Named(IBMDeveloperCloudConstants.PROPERTY_IBMDEVELOPERCLOUD_ENDPOINT) String endpoint) {
|
||||
return URI.create(endpoint);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void bindErrorHandlers() {
|
||||
bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(
|
||||
IBMDeveloperCloudErrorHandler.class);
|
||||
IBMDeveloperCloudErrorHandler.class);
|
||||
bind(HttpErrorHandler.class).annotatedWith(ClientError.class).to(
|
||||
IBMDeveloperCloudErrorHandler.class);
|
||||
IBMDeveloperCloudErrorHandler.class);
|
||||
bind(HttpErrorHandler.class).annotatedWith(ServerError.class).to(
|
||||
IBMDeveloperCloudErrorHandler.class);
|
||||
IBMDeveloperCloudErrorHandler.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -94,18 +88,4 @@ public class IBMDeveloperCloudRestClientModule extends
|
|||
install(new IBMDeveloperCloudParserModule());
|
||||
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) {
|
||||
logger.trace("looking for state on instance %s", instance);
|
||||
instance = client.getInstance(instance.getId());
|
||||
if (instance == null || instance.getStatus() == Instance.Status.FAILED)
|
||||
if (instance == null)
|
||||
return false;
|
||||
logger.trace("%s: looking for instance state %s: currently: %s", instance.getId(),
|
||||
Instance.Status.ACTIVE, instance.getStatus());
|
||||
logger.trace("%s: looking for instance state %s: currently: %s", instance
|
||||
.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;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -70,8 +70,8 @@ import com.google.common.io.Files;
|
|||
@Test(groups = "live", testName = "ibmdevelopercloud.IBMDeveloperCloudClientLiveTest")
|
||||
public class IBMDeveloperCloudClientLiveTest {
|
||||
|
||||
private static final ImmutableSet<Software> SOFTWARE = ImmutableSet.<Software> of(new Software(
|
||||
"SUSE Linux Enterprise", "OS", "10 SP2"));
|
||||
private static final ImmutableSet<Software> SOFTWARE = ImmutableSet
|
||||
.<Software> of(new Software("SUSE Linux Enterprise", "OS", "10 SP2"));
|
||||
private static final String SIZE = "LARGE";
|
||||
private IBMDeveloperCloudClient connection;
|
||||
private Location location;
|
||||
|
@ -87,11 +87,14 @@ public class IBMDeveloperCloudClientLiveTest {
|
|||
|
||||
@BeforeGroups(groups = { "live" })
|
||||
public void setupClient() {
|
||||
user = checkNotNull(System.getProperty("jclouds.test.user"), "jclouds.test.user");
|
||||
String password = checkNotNull(System.getProperty("jclouds.test.key"), "jclouds.test.key");
|
||||
user = checkNotNull(System.getProperty("jclouds.test.user"),
|
||||
"jclouds.test.user");
|
||||
String password = checkNotNull(System.getProperty("jclouds.test.key"),
|
||||
"jclouds.test.key");
|
||||
|
||||
connection = (IBMDeveloperCloudClient) IBMDeveloperCloudContextFactory.createContext(user,
|
||||
password, new Log4JLoggingModule()).getProviderSpecificContext().getApi();
|
||||
connection = (IBMDeveloperCloudClient) IBMDeveloperCloudContextFactory
|
||||
.createContext(user, password, new Log4JLoggingModule())
|
||||
.getProviderSpecificContext().getApi();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -118,7 +121,8 @@ public class IBMDeveloperCloudClientLiveTest {
|
|||
|
||||
@Test
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -128,7 +132,8 @@ public class IBMDeveloperCloudClientLiveTest {
|
|||
assertNotNull(response);
|
||||
if (response.size() > 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);
|
||||
if (response.size() > 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);
|
||||
if (response.size() > 0) {
|
||||
location = Iterables.get(response, 0);
|
||||
assertEquals(connection.getLocation(location.getId()).getId(), location.getId());
|
||||
assertEquals(connection.getLocation(location.getId()).getId(),
|
||||
location.getId());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -205,10 +212,11 @@ public class IBMDeveloperCloudClientLiveTest {
|
|||
Instance instance = connection.getInstance(instanceId);
|
||||
System.out.println("deleting instance: " + instance);
|
||||
if (instance.getStatus() == Instance.Status.FAILED
|
||||
|| instance.getStatus() == Instance.Status.ACTIVE) {
|
||||
|| instance.getStatus() == Instance.Status.ACTIVE) {
|
||||
connection.deleteInstance(instanceId);
|
||||
assert new RetryablePredicate<Instance>(new InstanceRemovedOrNotFound(connection),
|
||||
30, 2, TimeUnit.SECONDS).apply(instance) : instance;
|
||||
assert new RetryablePredicate<Instance>(
|
||||
new InstanceRemovedOrNotFound(connection), 30, 2,
|
||||
TimeUnit.SECONDS).apply(instance) : instance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -221,22 +229,25 @@ public class IBMDeveloperCloudClientLiveTest {
|
|||
public void testAllocateIpAddress() throws Exception {
|
||||
try {
|
||||
ip = connection.allocateAddressInLocation(location.getId());
|
||||
System.out.println(ip);
|
||||
assertEquals(ip.getIp(), null);
|
||||
// wait up to 30 seconds for this to become "free"
|
||||
new RetryablePredicate<Address>(new AddressFree(connection), 30, 2, TimeUnit.SECONDS)
|
||||
.apply(ip);
|
||||
new RetryablePredicate<Address>(new AddressFree(connection), 30, 2,
|
||||
TimeUnit.SECONDS).apply(ip);
|
||||
refreshIpAndReturnAllAddresses();
|
||||
assertEquals(ip.getInstanceId(), null);
|
||||
} catch (IllegalStateException e) {
|
||||
if (HttpResponseException.class.cast(e.getCause()).getResponse().getStatusCode() == 409) {
|
||||
ip = Iterables.find(connection.listAddresses(), new Predicate<Address>() {
|
||||
if (HttpResponseException.class.cast(e.getCause()).getResponse()
|
||||
.getStatusCode() == 409) {
|
||||
ip = Iterables.find(connection.listAddresses(),
|
||||
new Predicate<Address>() {
|
||||
|
||||
@Override
|
||||
public boolean apply(Address input) {
|
||||
return input.getState() == Address.State.FREE;
|
||||
}
|
||||
@Override
|
||||
public boolean apply(Address input) {
|
||||
return input.getState() == Address.State.FREE;
|
||||
}
|
||||
|
||||
});
|
||||
});
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
|
@ -246,18 +257,21 @@ public class IBMDeveloperCloudClientLiveTest {
|
|||
|
||||
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")
|
||||
public void testCreateVolume() throws Exception {
|
||||
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"
|
||||
assert new RetryablePredicate<Volume>(new VolumeUnmounted(connection), 300, 5,
|
||||
TimeUnit.SECONDS).apply(volume);
|
||||
assert new RetryablePredicate<Volume>(new VolumeUnmounted(connection),
|
||||
300, 5, TimeUnit.SECONDS).apply(volume);
|
||||
} 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();
|
||||
try {
|
||||
volume = Iterables.find(volumes, new Predicate<Volume>() {
|
||||
|
@ -269,7 +283,8 @@ public class IBMDeveloperCloudClientLiveTest {
|
|||
|
||||
});
|
||||
} catch (NoSuchElementException ex) {
|
||||
throw new RuntimeException("no unmounted volumes in: " + volumes, e);
|
||||
throw new RuntimeException(
|
||||
"no unmounted volumes in: " + volumes, e);
|
||||
}
|
||||
} else {
|
||||
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
|
||||
|
||||
@Test(dependsOnMethods = "testAddPublicKey")
|
||||
@Test(dependsOnMethods = { "testAddPublicKey", "testAllocateIpAddress" })
|
||||
public void testCreateInstance() throws Exception {
|
||||
instance = connection.createInstanceInLocation(location.getId(), TAG, IMAGE_ID, SIZE,
|
||||
configurationData(
|
||||
ImmutableMap.of("insight_admin_password", "myPassword1",
|
||||
"db2_admin_password", "myPassword2", "report_user_password",
|
||||
"myPassword3")).authorizePublicKey(key.getName()));
|
||||
for (Instance instance : connection.listInstances()) {
|
||||
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",
|
||||
"db2_admin_password", "myPassword2",
|
||||
"report_user_password", "myPassword3"))
|
||||
.authorizePublicKey(key.getName()).attachIp(ip.getId()));
|
||||
try {
|
||||
assertIpHostAndStatusNEW(instance);
|
||||
assertConsistent(instance, TAG);
|
||||
|
@ -315,10 +341,12 @@ public class IBMDeveloperCloudClientLiveTest {
|
|||
}
|
||||
|
||||
long start = System.currentTimeMillis();
|
||||
assert new RetryablePredicate<Instance>(new InstanceActive(connection), 600, 2,
|
||||
TimeUnit.SECONDS).apply(instance) : connection.getInstance(instance.getId());
|
||||
assert new RetryablePredicate<Instance>(new InstanceActive(connection),
|
||||
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 {
|
||||
assertIpHostAndStatusACTIVE(instance);
|
||||
|
@ -364,18 +392,21 @@ public class IBMDeveloperCloudClientLiveTest {
|
|||
/**
|
||||
* 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
|
||||
*/
|
||||
@Test(enabled = false, dependsOnMethods = { "testAddPublicKey", "testAllocateIpAddress",
|
||||
"testCreateVolume" })
|
||||
@Test(enabled = false, dependsOnMethods = { "testAddPublicKey",
|
||||
"testAllocateIpAddress", "testCreateVolume" })
|
||||
public void testCreateInstanceWithVolume() throws Exception {
|
||||
instance2 = connection.createInstanceInLocation(location.getId(), TAG, IMAGE_ID, SIZE,
|
||||
attachIp(ip.getId()).authorizePublicKey(key.getName()).mountVolume(volume.getId(),
|
||||
"/mnt").configurationData(
|
||||
ImmutableMap.of("insight_admin_password", "myPassword1",
|
||||
"db2_admin_password", "myPassword2", "report_user_password",
|
||||
"myPassword3")));
|
||||
instance2 = connection.createInstanceInLocation(location.getId(), TAG,
|
||||
IMAGE_ID, SIZE, attachIp(ip.getId()).authorizePublicKey(
|
||||
key.getName()).mountVolume(volume.getId(), "/mnt")
|
||||
.configurationData(
|
||||
ImmutableMap.of("insight_admin_password",
|
||||
"myPassword1", "db2_admin_password",
|
||||
"myPassword2", "report_user_password",
|
||||
"myPassword3")));
|
||||
//
|
||||
|
||||
volume = connection.getVolume(volume.getId());
|
||||
|
@ -410,12 +441,14 @@ public class IBMDeveloperCloudClientLiveTest {
|
|||
} 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)
|
||||
try {
|
||||
connection.deleteKey(key.getName());
|
||||
|
@ -440,14 +473,16 @@ public class IBMDeveloperCloudClientLiveTest {
|
|||
protected void setupKeyPair() throws FileNotFoundException, IOException {
|
||||
String secretKeyFile;
|
||||
try {
|
||||
secretKeyFile = checkNotNull(System.getProperty("jclouds.test.ssh.keyfile"),
|
||||
"jclouds.test.ssh.keyfile");
|
||||
secretKeyFile = checkNotNull(System
|
||||
.getProperty("jclouds.test.ssh.keyfile"),
|
||||
"jclouds.test.ssh.keyfile");
|
||||
} catch (NullPointerException e) {
|
||||
secretKeyFile = System.getProperty("user.home") + "/.ssh/id_rsa";
|
||||
}
|
||||
String secret = Files.toString(new File(secretKeyFile), Charsets.UTF_8);
|
||||
assert secret.startsWith("-----BEGIN RSA PRIVATE KEY-----") : "invalid key:\n" + secret;
|
||||
keyPair = ImmutableMap.<String, String> of("private", secret, "public", Files.toString(
|
||||
new File(secretKeyFile + ".pub"), Charsets.UTF_8));
|
||||
assert secret.startsWith("-----BEGIN RSA PRIVATE KEY-----") : "invalid key:\n"
|
||||
+ secret;
|
||||
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.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
@ -38,6 +37,7 @@ import javax.inject.Singleton;
|
|||
import org.jclouds.Constants;
|
||||
import org.jclouds.compute.ComputeServiceContext;
|
||||
import org.jclouds.compute.LoadBalancerService;
|
||||
import org.jclouds.compute.config.ComputeServiceTimeoutsModule;
|
||||
import org.jclouds.compute.domain.Architecture;
|
||||
import org.jclouds.compute.domain.ComputeMetadata;
|
||||
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.predicates.ImagePredicates;
|
||||
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.strategy.AddNodeWithTagStrategy;
|
||||
import org.jclouds.compute.strategy.DestroyNodeStrategy;
|
||||
|
@ -67,7 +65,6 @@ import org.jclouds.domain.Location;
|
|||
import org.jclouds.domain.LocationScope;
|
||||
import org.jclouds.domain.internal.LocationImpl;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.predicates.RetryablePredicate;
|
||||
import org.jclouds.rackspace.cloudservers.CloudServersAsyncClient;
|
||||
import org.jclouds.rackspace.cloudservers.CloudServersClient;
|
||||
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.Predicate;
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Sets;
|
||||
|
@ -92,12 +88,13 @@ import com.google.inject.TypeLiteral;
|
|||
import com.google.inject.util.Providers;
|
||||
|
||||
/**
|
||||
* Configures the {@link CloudServersComputeServiceContext}; requires {@link BaseComputeService}
|
||||
* bound.
|
||||
* Configures the {@link CloudServersComputeServiceContext}; requires
|
||||
* {@link BaseComputeService} bound.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class CloudServersComputeServiceContextModule extends CloudServersContextModule {
|
||||
public class CloudServersComputeServiceContextModule extends
|
||||
CloudServersContextModule {
|
||||
private final String providerName;
|
||||
|
||||
public CloudServersComputeServiceContextModule(String providerName) {
|
||||
|
@ -107,18 +104,22 @@ public class CloudServersComputeServiceContextModule extends CloudServersContext
|
|||
@Override
|
||||
protected void configure() {
|
||||
super.configure();
|
||||
install(new ComputeServiceTimeoutsModule());
|
||||
install(new RackspaceLocationsModule(providerName));
|
||||
bind(new TypeLiteral<Function<Server, NodeMetadata>>() {
|
||||
}).to(ServerToNodeMetadata.class);
|
||||
bind(LoadBalancerService.class).toProvider(Providers.<LoadBalancerService> of(null));
|
||||
bind(LoadBalancerService.class).toProvider(
|
||||
Providers.<LoadBalancerService> of(null));
|
||||
bind(new TypeLiteral<ComputeServiceContext>() {
|
||||
})
|
||||
.to(
|
||||
new TypeLiteral<ComputeServiceContextImpl<CloudServersClient, CloudServersAsyncClient>>() {
|
||||
}).in(Scopes.SINGLETON);
|
||||
bind(AddNodeWithTagStrategy.class).to(CloudServersAddNodeWithTagStrategy.class);
|
||||
.to(
|
||||
new TypeLiteral<ComputeServiceContextImpl<CloudServersClient, CloudServersAsyncClient>>() {
|
||||
}).in(Scopes.SINGLETON);
|
||||
bind(AddNodeWithTagStrategy.class).to(
|
||||
CloudServersAddNodeWithTagStrategy.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(DestroyNodeStrategy.class).to(CloudServersDestroyNodeStrategy.class);
|
||||
}
|
||||
|
@ -132,93 +133,93 @@ public class CloudServersComputeServiceContextModule extends CloudServersContext
|
|||
@Provides
|
||||
@Named("NAMING_CONVENTION")
|
||||
@Singleton
|
||||
String provideNamingConvention(@Named(RackspaceConstants.PROPERTY_RACKSPACE_USER) String account) {
|
||||
String provideNamingConvention(
|
||||
@Named(RackspaceConstants.PROPERTY_RACKSPACE_USER) String account) {
|
||||
return account + "-%s-%s";
|
||||
}
|
||||
|
||||
@Singleton
|
||||
public static class CloudServersRebootNodeStrategy implements RebootNodeStrategy {
|
||||
public static class CloudServersRebootNodeStrategy implements
|
||||
RebootNodeStrategy {
|
||||
private final CloudServersClient client;
|
||||
private final Predicate<Server> serverActive;
|
||||
private final GetNodeMetadataStrategy getNode;
|
||||
|
||||
@Inject
|
||||
protected CloudServersRebootNodeStrategy(CloudServersClient client,
|
||||
@Named("ACTIVE") Predicate<Server> serverActive) {
|
||||
GetNodeMetadataStrategy getNode) {
|
||||
this.client = client;
|
||||
this.serverActive = serverActive;
|
||||
this.getNode = getNode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(String id) {
|
||||
public NodeMetadata execute(String id) {
|
||||
int serverId = Integer.parseInt(id);
|
||||
// if false server wasn't around in the first place
|
||||
client.rebootServer(serverId, RebootType.HARD);
|
||||
Server server = client.getServer(serverId);
|
||||
return server == null ? false : serverActive.apply(server);
|
||||
return getNode.execute(id);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Singleton
|
||||
public static class CloudServersDestroyNodeStrategy implements DestroyNodeStrategy {
|
||||
public static class CloudServersDestroyNodeStrategy implements
|
||||
DestroyNodeStrategy {
|
||||
private final CloudServersClient client;
|
||||
private final Predicate<Server> serverDeleted;
|
||||
private final GetNodeMetadataStrategy getNode;
|
||||
|
||||
@Inject
|
||||
protected CloudServersDestroyNodeStrategy(CloudServersClient client,
|
||||
@Named("DELETED") Predicate<Server> serverDeleted) {
|
||||
GetNodeMetadataStrategy getNode) {
|
||||
this.client = client;
|
||||
this.serverDeleted = serverDeleted;
|
||||
this.getNode = getNode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(String id) {
|
||||
public NodeMetadata execute(String id) {
|
||||
int serverId = Integer.parseInt(id);
|
||||
// if false server wasn't around in the first place
|
||||
if (!client.deleteServer(serverId))
|
||||
return false;
|
||||
Server server = client.getServer(serverId);
|
||||
return server == null ? false : serverDeleted.apply(server);
|
||||
client.deleteServer(serverId);
|
||||
return getNode.execute(id);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Singleton
|
||||
public static class CloudServersAddNodeWithTagStrategy implements AddNodeWithTagStrategy {
|
||||
public static class CloudServersAddNodeWithTagStrategy implements
|
||||
AddNodeWithTagStrategy {
|
||||
private final CloudServersClient client;
|
||||
private final Predicate<Server> serverActive;
|
||||
|
||||
@Inject
|
||||
protected CloudServersAddNodeWithTagStrategy(CloudServersClient client,
|
||||
@Named("ACTIVE") Predicate<Server> serverActive) {
|
||||
protected CloudServersAddNodeWithTagStrategy(CloudServersClient client) {
|
||||
this.client = checkNotNull(client, "client");
|
||||
this.serverActive = checkNotNull(serverActive, "serverActive");
|
||||
}
|
||||
|
||||
@Override
|
||||
public NodeMetadata execute(String tag, String name, Template template) {
|
||||
Server server = client.createServer(name, Integer.parseInt(template.getImage()
|
||||
.getProviderId()), Integer.parseInt(template.getSize().getProviderId()));
|
||||
serverActive.apply(server);
|
||||
return new NodeMetadataImpl(server.getId() + "", name, server.getId() + "",
|
||||
new LocationImpl(LocationScope.HOST, server.getHostId(), server.getHostId(),
|
||||
template.getLocation()), null, server.getMetadata(), tag, template
|
||||
.getImage(), NodeState.RUNNING, server.getAddresses()
|
||||
.getPublicAddresses(), server.getAddresses().getPrivateAddresses(),
|
||||
ImmutableMap.<String, String> of(),
|
||||
new Credentials("root", server.getAdminPass()));
|
||||
Server server = client.createServer(name, Integer.parseInt(template
|
||||
.getImage().getProviderId()), Integer.parseInt(template
|
||||
.getSize().getProviderId()));
|
||||
return new NodeMetadataImpl(server.getId() + "", name, server.getId()
|
||||
+ "", new LocationImpl(LocationScope.HOST, server.getHostId(),
|
||||
server.getHostId(), template.getLocation()), null, server
|
||||
.getMetadata(), tag, template.getImage(), NodeState.PENDING,
|
||||
server.getAddresses().getPublicAddresses(), server
|
||||
.getAddresses().getPrivateAddresses(), ImmutableMap
|
||||
.<String, String> of(), new Credentials("root", server
|
||||
.getAdminPass()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Singleton
|
||||
public static class CloudServersListNodesStrategy implements ListNodesStrategy {
|
||||
public static class CloudServersListNodesStrategy implements
|
||||
ListNodesStrategy {
|
||||
private final CloudServersClient client;
|
||||
private final Function<Server, NodeMetadata> serverToNodeMetadata;
|
||||
|
||||
@Inject
|
||||
protected CloudServersListNodesStrategy(CloudServersClient client,
|
||||
Function<Server, NodeMetadata> serverToNodeMetadata) {
|
||||
Function<Server, NodeMetadata> serverToNodeMetadata) {
|
||||
this.client = client;
|
||||
this.serverToNodeMetadata = serverToNodeMetadata;
|
||||
}
|
||||
|
@ -230,21 +231,23 @@ public class CloudServersComputeServiceContextModule extends CloudServersContext
|
|||
|
||||
@Override
|
||||
public Iterable<? extends NodeMetadata> listDetailsOnNodesMatching(
|
||||
Predicate<ComputeMetadata> filter) {
|
||||
return Iterables.filter(Iterables.transform(client.listServers(ListOptions.Builder
|
||||
.withDetails()), serverToNodeMetadata), filter);
|
||||
Predicate<ComputeMetadata> filter) {
|
||||
return Iterables.filter(Iterables.transform(client
|
||||
.listServers(ListOptions.Builder.withDetails()),
|
||||
serverToNodeMetadata), filter);
|
||||
}
|
||||
}
|
||||
|
||||
@Singleton
|
||||
public static class CloudServersGetNodeMetadataStrategy implements GetNodeMetadataStrategy {
|
||||
public static class CloudServersGetNodeMetadataStrategy implements
|
||||
GetNodeMetadataStrategy {
|
||||
|
||||
private final CloudServersClient client;
|
||||
private final Function<Server, NodeMetadata> serverToNodeMetadata;
|
||||
|
||||
@Inject
|
||||
protected CloudServersGetNodeMetadataStrategy(CloudServersClient client,
|
||||
Function<Server, NodeMetadata> serverToNodeMetadata) {
|
||||
Function<Server, NodeMetadata> serverToNodeMetadata) {
|
||||
this.client = client;
|
||||
this.serverToNodeMetadata = serverToNodeMetadata;
|
||||
}
|
||||
|
@ -260,38 +263,30 @@ public class CloudServersComputeServiceContextModule extends CloudServersContext
|
|||
@Singleton
|
||||
@Provides
|
||||
Map<ServerStatus, NodeState> provideServerToNodeState() {
|
||||
return ImmutableMap.<ServerStatus, NodeState> builder().put(ServerStatus.ACTIVE,
|
||||
NodeState.RUNNING)//
|
||||
.put(ServerStatus.SUSPENDED, NodeState.SUSPENDED)//
|
||||
.put(ServerStatus.DELETED, NodeState.TERMINATED)//
|
||||
.put(ServerStatus.QUEUE_RESIZE, NodeState.PENDING)//
|
||||
.put(ServerStatus.PREP_RESIZE, NodeState.PENDING)//
|
||||
.put(ServerStatus.RESIZE, NodeState.PENDING)//
|
||||
.put(ServerStatus.VERIFY_RESIZE, NodeState.PENDING)//
|
||||
.put(ServerStatus.QUEUE_MOVE, NodeState.PENDING)//
|
||||
.put(ServerStatus.PREP_MOVE, NodeState.PENDING)//
|
||||
.put(ServerStatus.MOVE, NodeState.PENDING)//
|
||||
.put(ServerStatus.VERIFY_MOVE, NodeState.PENDING)//
|
||||
.put(ServerStatus.RESCUE, NodeState.PENDING)//
|
||||
.put(ServerStatus.ERROR, NodeState.ERROR)//
|
||||
.put(ServerStatus.BUILD, NodeState.PENDING)//
|
||||
.put(ServerStatus.RESTORING, NodeState.PENDING)//
|
||||
.put(ServerStatus.PASSWORD, NodeState.PENDING)//
|
||||
.put(ServerStatus.REBUILD, NodeState.PENDING)//
|
||||
.put(ServerStatus.DELETE_IP, NodeState.PENDING)//
|
||||
.put(ServerStatus.SHARE_IP_NO_CONFIG, NodeState.PENDING)//
|
||||
.put(ServerStatus.SHARE_IP, NodeState.PENDING)//
|
||||
.put(ServerStatus.REBOOT, NodeState.PENDING)//
|
||||
.put(ServerStatus.HARD_REBOOT, NodeState.PENDING)//
|
||||
.put(ServerStatus.UNKNOWN, NodeState.UNKNOWN).build();
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
@Named("NOT_RUNNING")
|
||||
protected Predicate<CommandUsingClient> runScriptRunning(ScriptStatusReturnsZero stateRunning) {
|
||||
return new RetryablePredicate<CommandUsingClient>(Predicates.not(stateRunning), 600, 3,
|
||||
TimeUnit.SECONDS);
|
||||
return ImmutableMap.<ServerStatus, NodeState> builder().put(
|
||||
ServerStatus.ACTIVE, NodeState.RUNNING)//
|
||||
.put(ServerStatus.SUSPENDED, NodeState.SUSPENDED)//
|
||||
.put(ServerStatus.DELETED, NodeState.TERMINATED)//
|
||||
.put(ServerStatus.QUEUE_RESIZE, NodeState.PENDING)//
|
||||
.put(ServerStatus.PREP_RESIZE, NodeState.PENDING)//
|
||||
.put(ServerStatus.RESIZE, NodeState.PENDING)//
|
||||
.put(ServerStatus.VERIFY_RESIZE, NodeState.PENDING)//
|
||||
.put(ServerStatus.QUEUE_MOVE, NodeState.PENDING)//
|
||||
.put(ServerStatus.PREP_MOVE, NodeState.PENDING)//
|
||||
.put(ServerStatus.MOVE, NodeState.PENDING)//
|
||||
.put(ServerStatus.VERIFY_MOVE, NodeState.PENDING)//
|
||||
.put(ServerStatus.RESCUE, NodeState.PENDING)//
|
||||
.put(ServerStatus.ERROR, NodeState.ERROR)//
|
||||
.put(ServerStatus.BUILD, NodeState.PENDING)//
|
||||
.put(ServerStatus.RESTORING, NodeState.PENDING)//
|
||||
.put(ServerStatus.PASSWORD, NodeState.PENDING)//
|
||||
.put(ServerStatus.REBUILD, NodeState.PENDING)//
|
||||
.put(ServerStatus.DELETE_IP, NodeState.PENDING)//
|
||||
.put(ServerStatus.SHARE_IP_NO_CONFIG, NodeState.PENDING)//
|
||||
.put(ServerStatus.SHARE_IP, NodeState.PENDING)//
|
||||
.put(ServerStatus.REBOOT, NodeState.PENDING)//
|
||||
.put(ServerStatus.HARD_REBOOT, NodeState.PENDING)//
|
||||
.put(ServerStatus.UNKNOWN, NodeState.UNKNOWN).build();
|
||||
}
|
||||
|
||||
@Provides
|
||||
|
@ -307,17 +302,19 @@ public class CloudServersComputeServiceContextModule extends CloudServersContext
|
|||
|
||||
@Provides
|
||||
@Singleton
|
||||
protected Set<? extends Size> provideSizes(CloudServersClient sync, Set<? extends Image> images,
|
||||
Location location, LogHolder holder,
|
||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor,
|
||||
Function<ComputeMetadata, String> indexer) throws InterruptedException,
|
||||
TimeoutException, ExecutionException {
|
||||
protected Set<? extends Size> provideSizes(CloudServersClient sync,
|
||||
Set<? extends Image> images, Location location, LogHolder holder,
|
||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor,
|
||||
Function<ComputeMetadata, String> indexer)
|
||||
throws InterruptedException, TimeoutException, ExecutionException {
|
||||
final Set<Size> sizes = Sets.newHashSet();
|
||||
holder.logger.debug(">> providing sizes");
|
||||
for (final Flavor from : sync.listFlavors(ListOptions.Builder.withDetails())) {
|
||||
sizes.add(new SizeImpl(from.getId() + "", from.getName(), from.getId() + "", location,
|
||||
null, ImmutableMap.<String, String> of(), from.getDisk() / 10, from.getRam(),
|
||||
from.getDisk(), ImagePredicates.any()));
|
||||
for (final Flavor from : sync.listFlavors(ListOptions.Builder
|
||||
.withDetails())) {
|
||||
sizes.add(new SizeImpl(from.getId() + "", from.getName(), from.getId()
|
||||
+ "", location, null, ImmutableMap.<String, String> of(), from
|
||||
.getDisk() / 10, from.getRam(), from.getDisk(), ImagePredicates
|
||||
.any()));
|
||||
}
|
||||
holder.logger.debug("<< sizes(%d)", sizes.size());
|
||||
return sizes;
|
||||
|
@ -329,17 +326,19 @@ public class CloudServersComputeServiceContextModule extends CloudServersContext
|
|||
protected Logger logger = Logger.NULL;
|
||||
}
|
||||
|
||||
public static final Pattern RACKSPACE_PATTERN = Pattern.compile("(([^ ]*) .*)");
|
||||
public static final Pattern RACKSPACE_PATTERN = Pattern
|
||||
.compile("(([^ ]*) .*)");
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
protected Set<? extends Image> provideImages(final CloudServersClient sync, Location location,
|
||||
LogHolder holder, Function<ComputeMetadata, String> indexer)
|
||||
throws InterruptedException, ExecutionException, TimeoutException {
|
||||
protected Set<? extends Image> provideImages(final CloudServersClient sync,
|
||||
Location location, LogHolder holder,
|
||||
Function<ComputeMetadata, String> indexer)
|
||||
throws InterruptedException, ExecutionException, TimeoutException {
|
||||
final Set<Image> images = Sets.newHashSet();
|
||||
holder.logger.debug(">> providing images");
|
||||
for (final org.jclouds.rackspace.cloudservers.domain.Image from : sync
|
||||
.listImages(ListOptions.Builder.withDetails())) {
|
||||
.listImages(ListOptions.Builder.withDetails())) {
|
||||
OsFamily os = null;
|
||||
Architecture arch = Architecture.X86_64;
|
||||
String osDescription = "";
|
||||
|
@ -357,9 +356,11 @@ public class CloudServersComputeServiceContextModule extends CloudServersContext
|
|||
holder.logger.debug("<< didn't match os(%s)", matcher.group(2));
|
||||
}
|
||||
}
|
||||
images.add(new ImageImpl(from.getId() + "", from.getName(), from.getId() + "", location,
|
||||
null, ImmutableMap.<String, String> of(), from.getName(), version, os,
|
||||
osDescription, arch, new Credentials("root", null)));
|
||||
images.add(new ImageImpl(from.getId() + "", from.getName(), from
|
||||
.getId()
|
||||
+ "", location, null, ImmutableMap.<String, String> of(), from
|
||||
.getName(), version, os, osDescription, arch, new Credentials(
|
||||
"root", null)));
|
||||
}
|
||||
holder.logger.debug("<< images(%d)", images.size());
|
||||
return images;
|
||||
|
|
|
@ -18,31 +18,17 @@
|
|||
*/
|
||||
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.RequiresHttp;
|
||||
import org.jclouds.http.annotation.ClientError;
|
||||
import org.jclouds.http.annotation.Redirection;
|
||||
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.CloudServersClient;
|
||||
import org.jclouds.rackspace.cloudservers.domain.Server;
|
||||
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.config.RestClientModule;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.inject.Provides;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
|
@ -56,26 +42,6 @@ public class CloudServersRestClientModule extends
|
|||
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
|
||||
protected void bindErrorHandlers() {
|
||||
bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(
|
||||
|
|
|
@ -27,7 +27,6 @@ import java.util.NoSuchElementException;
|
|||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
@ -40,6 +39,7 @@ import javax.inject.Singleton;
|
|||
import org.jclouds.Constants;
|
||||
import org.jclouds.compute.ComputeServiceContext;
|
||||
import org.jclouds.compute.LoadBalancerService;
|
||||
import org.jclouds.compute.config.ComputeServiceTimeoutsModule;
|
||||
import org.jclouds.compute.domain.Architecture;
|
||||
import org.jclouds.compute.domain.ComputeMetadata;
|
||||
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.predicates.ImagePredicates;
|
||||
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.strategy.AddNodeWithTagStrategy;
|
||||
import org.jclouds.compute.strategy.DestroyNodeStrategy;
|
||||
|
@ -68,7 +66,6 @@ import org.jclouds.domain.Location;
|
|||
import org.jclouds.domain.LocationScope;
|
||||
import org.jclouds.domain.internal.LocationImpl;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.predicates.RetryablePredicate;
|
||||
import org.jclouds.rimuhosting.miro.RimuHostingAsyncClient;
|
||||
import org.jclouds.rimuhosting.miro.RimuHostingClient;
|
||||
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.Predicate;
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
@ -96,7 +92,8 @@ import com.google.inject.util.Providers;
|
|||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class RimuHostingComputeServiceContextModule extends RimuHostingContextModule {
|
||||
public class RimuHostingComputeServiceContextModule extends
|
||||
RimuHostingContextModule {
|
||||
private final String providerName;
|
||||
|
||||
public RimuHostingComputeServiceContextModule(String providerName) {
|
||||
|
@ -106,19 +103,23 @@ public class RimuHostingComputeServiceContextModule extends RimuHostingContextMo
|
|||
@Override
|
||||
protected void configure() {
|
||||
super.configure();
|
||||
install(new ComputeServiceTimeoutsModule());
|
||||
bind(new TypeLiteral<Function<Server, NodeMetadata>>() {
|
||||
}).to(ServerToNodeMetadata.class);
|
||||
bind(LoadBalancerService.class).toProvider(Providers.<LoadBalancerService> of(null));
|
||||
bind(LoadBalancerService.class).toProvider(
|
||||
Providers.<LoadBalancerService> of(null));
|
||||
bind(new TypeLiteral<ComputeServiceContext>() {
|
||||
})
|
||||
.to(
|
||||
new TypeLiteral<ComputeServiceContextImpl<RimuHostingClient, RimuHostingAsyncClient>>() {
|
||||
}).in(Scopes.SINGLETON);
|
||||
.to(
|
||||
new TypeLiteral<ComputeServiceContextImpl<RimuHostingClient, RimuHostingAsyncClient>>() {
|
||||
}).in(Scopes.SINGLETON);
|
||||
bind(new TypeLiteral<Function<Server, Iterable<String>>>() {
|
||||
}).to(ServerToPublicAddresses.class);
|
||||
bind(AddNodeWithTagStrategy.class).to(RimuHostingAddNodeWithTagStrategy.class);
|
||||
bind(AddNodeWithTagStrategy.class).to(
|
||||
RimuHostingAddNodeWithTagStrategy.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(DestroyNodeStrategy.class).to(RimuHostingDestroyNodeStrategy.class);
|
||||
}
|
||||
|
@ -126,8 +127,8 @@ public class RimuHostingComputeServiceContextModule extends RimuHostingContextMo
|
|||
@Provides
|
||||
@Named("DEFAULT")
|
||||
protected TemplateBuilder provideTemplate(TemplateBuilder template) {
|
||||
return template.sizeId("MIRO1B").osFamily(UBUNTU).architecture(Architecture.X86_32)
|
||||
.imageNameMatches(".*10\\.?04.*");
|
||||
return template.sizeId("MIRO1B").osFamily(UBUNTU).architecture(
|
||||
Architecture.X86_32).imageNameMatches(".*10\\.?04.*");
|
||||
}
|
||||
|
||||
@Provides
|
||||
|
@ -138,90 +139,94 @@ public class RimuHostingComputeServiceContextModule extends RimuHostingContextMo
|
|||
}
|
||||
|
||||
@Singleton
|
||||
public static class RimuHostingRebootNodeStrategy implements RebootNodeStrategy {
|
||||
public static class RimuHostingRebootNodeStrategy implements
|
||||
RebootNodeStrategy {
|
||||
private final RimuHostingClient client;
|
||||
private final GetNodeMetadataStrategy getNode;
|
||||
|
||||
@Inject
|
||||
protected RimuHostingRebootNodeStrategy(RimuHostingClient client) {
|
||||
protected RimuHostingRebootNodeStrategy(RimuHostingClient client,
|
||||
GetNodeMetadataStrategy getNode) {
|
||||
this.client = client;
|
||||
this.getNode = getNode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(String id) {
|
||||
public NodeMetadata execute(String id) {
|
||||
Long serverId = Long.parseLong(id);
|
||||
// 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
|
||||
public static class RimuHostingDestroyNodeStrategy implements DestroyNodeStrategy {
|
||||
public static class RimuHostingDestroyNodeStrategy implements
|
||||
DestroyNodeStrategy {
|
||||
private final RimuHostingClient client;
|
||||
private final Predicate<Server> serverDestroyed;
|
||||
private final GetNodeMetadataStrategy getNode;
|
||||
|
||||
@Inject
|
||||
protected RimuHostingDestroyNodeStrategy(RimuHostingClient client,
|
||||
@Named("DESTROYED") Predicate<Server> serverDestroyed) {
|
||||
GetNodeMetadataStrategy getNode) {
|
||||
this.client = client;
|
||||
this.serverDestroyed = serverDestroyed;
|
||||
this.getNode = getNode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(String id) {
|
||||
public NodeMetadata execute(String id) {
|
||||
Long serverId = Long.parseLong(id);
|
||||
client.destroyServer(serverId);
|
||||
return serverDestroyed.apply(client.getServer(serverId));
|
||||
return getNode.execute(id);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Singleton
|
||||
public static class RimuHostingAddNodeWithTagStrategy implements AddNodeWithTagStrategy {
|
||||
public static class RimuHostingAddNodeWithTagStrategy implements
|
||||
AddNodeWithTagStrategy {
|
||||
private final RimuHostingClient client;
|
||||
private final Predicate<Server> serverRunning;
|
||||
private final Function<Server, Iterable<String>> getPublicAddresses;
|
||||
private final Map<RunningState, NodeState> runningStateToNodeState;
|
||||
|
||||
@Inject
|
||||
protected RimuHostingAddNodeWithTagStrategy(RimuHostingClient client,
|
||||
@Named("RUNNING") Predicate<Server> serverRunning,
|
||||
Function<Server, Iterable<String>> getPublicAddresses,
|
||||
Map<RunningState, NodeState> runningStateToNodeState) {
|
||||
Function<Server, Iterable<String>> getPublicAddresses,
|
||||
Map<RunningState, NodeState> runningStateToNodeState) {
|
||||
this.client = client;
|
||||
this.serverRunning = serverRunning;
|
||||
this.getPublicAddresses = getPublicAddresses;
|
||||
this.runningStateToNodeState = runningStateToNodeState;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NodeMetadata execute(String tag, String name, Template template) {
|
||||
NewServerResponse serverResponse = client.createServer(name, checkNotNull(template
|
||||
.getImage().getProviderId(), "imageId"), checkNotNull(template.getSize()
|
||||
.getProviderId(), "sizeId"));
|
||||
serverRunning.apply(serverResponse.getServer());
|
||||
NewServerResponse serverResponse = client.createServer(name,
|
||||
checkNotNull(template.getImage().getProviderId(), "imageId"),
|
||||
checkNotNull(template.getSize().getProviderId(), "sizeId"));
|
||||
Server server = client.getServer(serverResponse.getServer().getId());
|
||||
// we have to lookup the new details in order to retrieve the currently assigned ip
|
||||
// address.
|
||||
NodeMetadata node = new NodeMetadataImpl(server.getId().toString(), name, server.getId()
|
||||
.toString(), template.getLocation(), null, ImmutableMap.<String, String> of(),
|
||||
tag, template.getImage(), runningStateToNodeState.get(server.getState()),
|
||||
getPublicAddresses.apply(server), ImmutableList.<String> of(), ImmutableMap
|
||||
.<String, String> of(), new Credentials("root", serverResponse
|
||||
.getNewInstanceRequest().getCreateOptions().getPassword()));
|
||||
NodeMetadata node = new NodeMetadataImpl(server.getId().toString(),
|
||||
name, server.getId().toString(), template.getLocation(), null,
|
||||
ImmutableMap.<String, String> of(), tag, template.getImage(),
|
||||
runningStateToNodeState.get(server.getState()),
|
||||
getPublicAddresses.apply(server), ImmutableList.<String> of(),
|
||||
ImmutableMap.<String, String> of(), new Credentials("root",
|
||||
serverResponse.getNewInstanceRequest().getCreateOptions()
|
||||
.getPassword()));
|
||||
return node;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Singleton
|
||||
public static class RimuHostingListNodesStrategy implements ListNodesStrategy {
|
||||
public static class RimuHostingListNodesStrategy implements
|
||||
ListNodesStrategy {
|
||||
private final RimuHostingClient client;
|
||||
private final Function<Server, NodeMetadata> serverToNodeMetadata;
|
||||
|
||||
@Inject
|
||||
protected RimuHostingListNodesStrategy(RimuHostingClient client,
|
||||
Function<Server, NodeMetadata> serverToNodeMetadata) {
|
||||
Function<Server, NodeMetadata> serverToNodeMetadata) {
|
||||
this.client = client;
|
||||
this.serverToNodeMetadata = serverToNodeMetadata;
|
||||
}
|
||||
|
@ -233,22 +238,23 @@ public class RimuHostingComputeServiceContextModule extends RimuHostingContextMo
|
|||
|
||||
@Override
|
||||
public Iterable<? extends NodeMetadata> listDetailsOnNodesMatching(
|
||||
Predicate<ComputeMetadata> filter) {
|
||||
return Iterables.filter(Iterables.transform(client.getServerList(), serverToNodeMetadata),
|
||||
filter);
|
||||
Predicate<ComputeMetadata> filter) {
|
||||
return Iterables.filter(Iterables.transform(client.getServerList(),
|
||||
serverToNodeMetadata), filter);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Singleton
|
||||
public static class RimuHostingGetNodeMetadataStrategy implements GetNodeMetadataStrategy {
|
||||
public static class RimuHostingGetNodeMetadataStrategy implements
|
||||
GetNodeMetadataStrategy {
|
||||
|
||||
private final RimuHostingClient client;
|
||||
private final Function<Server, NodeMetadata> serverToNodeMetadata;
|
||||
|
||||
@Inject
|
||||
protected RimuHostingGetNodeMetadataStrategy(RimuHostingClient client,
|
||||
Function<Server, NodeMetadata> serverToNodeMetadata) {
|
||||
Function<Server, NodeMetadata> serverToNodeMetadata) {
|
||||
this.client = client;
|
||||
this.serverToNodeMetadata = serverToNodeMetadata;
|
||||
}
|
||||
|
@ -264,16 +270,17 @@ public class RimuHostingComputeServiceContextModule extends RimuHostingContextMo
|
|||
@Singleton
|
||||
@Provides
|
||||
Map<RunningState, NodeState> provideServerToNodeState() {
|
||||
return ImmutableMap.<RunningState, NodeState> builder().put(RunningState.RUNNING,
|
||||
NodeState.RUNNING)//
|
||||
.put(RunningState.NOTRUNNING, NodeState.SUSPENDED)//
|
||||
.put(RunningState.POWERCYCLING, NodeState.PENDING)//
|
||||
.put(RunningState.RESTARTING, NodeState.PENDING)//
|
||||
.build();
|
||||
return ImmutableMap.<RunningState, NodeState> builder().put(
|
||||
RunningState.RUNNING, NodeState.RUNNING)//
|
||||
.put(RunningState.NOTRUNNING, NodeState.SUSPENDED)//
|
||||
.put(RunningState.POWERCYCLING, NodeState.PENDING)//
|
||||
.put(RunningState.RESTARTING, NodeState.PENDING)//
|
||||
.build();
|
||||
}
|
||||
|
||||
@Singleton
|
||||
private static class ServerToNodeMetadata implements Function<Server, NodeMetadata> {
|
||||
private static class ServerToNodeMetadata implements
|
||||
Function<Server, NodeMetadata> {
|
||||
|
||||
@Resource
|
||||
protected Logger logger = Logger.NULL;
|
||||
|
@ -295,19 +302,22 @@ public class RimuHostingComputeServiceContextModule extends RimuHostingContextMo
|
|||
@Override
|
||||
public boolean apply(Image input) {
|
||||
return input.getProviderId().equals(instance.getImageId())
|
||||
&& (input.getLocation() == null || input.getLocation().equals(location) || input
|
||||
.getLocation().equals(location.getParent()));
|
||||
&& (input.getLocation() == null
|
||||
|| input.getLocation().equals(location) || input
|
||||
.getLocation().equals(location.getParent()));
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Inject
|
||||
ServerToNodeMetadata(Function<Server, Iterable<String>> getPublicAddresses,
|
||||
Map<RunningState, NodeState> runningStateToNodeState, Set<? extends Image> images,
|
||||
Set<? extends Location> locations) {
|
||||
this.getPublicAddresses = checkNotNull(getPublicAddresses, "serverStateToNodeState");
|
||||
ServerToNodeMetadata(
|
||||
Function<Server, Iterable<String>> getPublicAddresses,
|
||||
Map<RunningState, NodeState> runningStateToNodeState,
|
||||
Set<? extends Image> images, Set<? extends Location> locations) {
|
||||
this.getPublicAddresses = checkNotNull(getPublicAddresses,
|
||||
"serverStateToNodeState");
|
||||
this.runningStateToNodeState = checkNotNull(runningStateToNodeState,
|
||||
"serverStateToNodeState");
|
||||
"serverStateToNodeState");
|
||||
this.images = checkNotNull(images, "images");
|
||||
this.locations = checkNotNull(locations, "locations");
|
||||
}
|
||||
|
@ -315,49 +325,48 @@ public class RimuHostingComputeServiceContextModule extends RimuHostingContextMo
|
|||
@Override
|
||||
public NodeMetadata apply(Server from) {
|
||||
|
||||
Location location = new LocationImpl(LocationScope.ZONE, from.getLocation().getId(), from
|
||||
.getLocation().getName(), null);
|
||||
Location location = new LocationImpl(LocationScope.ZONE, from
|
||||
.getLocation().getId(), from.getLocation().getName(), null);
|
||||
String tag = from.getName().replaceAll("-[0-9]+", "");
|
||||
Credentials creds = null;
|
||||
|
||||
Image image = null;
|
||||
try {
|
||||
image = Iterables.find(images, new FindImageForServer(location, from));
|
||||
image = Iterables.find(images, new FindImageForServer(location,
|
||||
from));
|
||||
} catch (NoSuchElementException e) {
|
||||
logger.warn("could not find a matching image for server %s in location %s", from,
|
||||
location);
|
||||
logger
|
||||
.warn(
|
||||
"could not find a matching image for server %s in location %s",
|
||||
from, location);
|
||||
}
|
||||
NodeState state = runningStateToNodeState.get(from.getState());
|
||||
return new NodeMetadataImpl(from.getId() + "", from.getName(), from.getId() + "",
|
||||
location, null, ImmutableMap.<String, String> of(), tag, image, state,
|
||||
getPublicAddresses.apply(from), ImmutableList.<String> of(), ImmutableMap
|
||||
.<String, String> of(), creds);
|
||||
return new NodeMetadataImpl(from.getId() + "", from.getName(), from
|
||||
.getId()
|
||||
+ "", location, null, ImmutableMap.<String, String> of(), tag,
|
||||
image, state, getPublicAddresses.apply(from), ImmutableList
|
||||
.<String> of(), ImmutableMap.<String, String> of(), creds);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Singleton
|
||||
private static class ServerToPublicAddresses implements Function<Server, Iterable<String>> {
|
||||
private static class ServerToPublicAddresses implements
|
||||
Function<Server, Iterable<String>> {
|
||||
@Override
|
||||
public Iterable<String> apply(Server server) {
|
||||
return server.getIpAddresses() == null ? ImmutableSet.<String> of() : Iterables.concat(
|
||||
ImmutableList.of(server.getIpAddresses().getPrimaryIp()), server.getIpAddresses()
|
||||
.getSecondaryIps());
|
||||
return server.getIpAddresses() == null ? ImmutableSet.<String> of()
|
||||
: Iterables.concat(ImmutableList.of(server.getIpAddresses()
|
||||
.getPrimaryIp()), server.getIpAddresses()
|
||||
.getSecondaryIps());
|
||||
}
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
@Named("NOT_RUNNING")
|
||||
protected Predicate<CommandUsingClient> runScriptRunning(ScriptStatusReturnsZero stateRunning) {
|
||||
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) {
|
||||
Location getDefaultLocation(
|
||||
@Named(PROPERTY_RIMUHOSTING_DEFAULT_DC) final String defaultDC,
|
||||
Set<? extends Location> locations) {
|
||||
return Iterables.find(locations, new Predicate<Location>() {
|
||||
|
||||
@Override
|
||||
|
@ -370,15 +379,17 @@ public class RimuHostingComputeServiceContextModule extends RimuHostingContextMo
|
|||
|
||||
@Provides
|
||||
@Singleton
|
||||
Set<? extends Location> getDefaultLocations(RimuHostingClient sync, LogHolder holder,
|
||||
Function<ComputeMetadata, String> indexer) {
|
||||
Set<? extends Location> getDefaultLocations(RimuHostingClient sync,
|
||||
LogHolder holder, Function<ComputeMetadata, String> indexer) {
|
||||
final Set<Location> locations = Sets.newHashSet();
|
||||
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()) {
|
||||
try {
|
||||
locations.add(new LocationImpl(LocationScope.ZONE, from.getDataCenter().getId(), from
|
||||
.getDataCenter().getName(), provider));
|
||||
locations.add(new LocationImpl(LocationScope.ZONE, from
|
||||
.getDataCenter().getId(), from.getDataCenter().getName(),
|
||||
provider));
|
||||
} catch (NullPointerException e) {
|
||||
holder.logger.warn("datacenter not present in " + from.getId());
|
||||
}
|
||||
|
@ -400,27 +411,30 @@ public class RimuHostingComputeServiceContextModule extends RimuHostingContextMo
|
|||
|
||||
@Provides
|
||||
@Singleton
|
||||
protected Set<? extends Size> provideSizes(RimuHostingClient sync, Set<? extends Image> images,
|
||||
Set<? extends Location> locations, LogHolder holder,
|
||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService userExecutor,
|
||||
Function<ComputeMetadata, String> indexer) throws InterruptedException,
|
||||
TimeoutException, ExecutionException {
|
||||
protected Set<? extends Size> provideSizes(RimuHostingClient sync,
|
||||
Set<? extends Image> images, Set<? extends Location> locations,
|
||||
LogHolder holder,
|
||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService userExecutor,
|
||||
Function<ComputeMetadata, String> indexer)
|
||||
throws InterruptedException, TimeoutException, ExecutionException {
|
||||
final Set<Size> sizes = Sets.newHashSet();
|
||||
holder.logger.debug(">> providing sizes");
|
||||
for (final PricingPlan from : sync.getPricingPlanList()) {
|
||||
try {
|
||||
|
||||
final Location location = Iterables.find(locations, new Predicate<Location>() {
|
||||
final Location location = Iterables.find(locations,
|
||||
new Predicate<Location>() {
|
||||
|
||||
@Override
|
||||
public boolean apply(Location input) {
|
||||
return input.getId().equals(from.getDataCenter().getId());
|
||||
}
|
||||
@Override
|
||||
public boolean apply(Location input) {
|
||||
return input.getId().equals(
|
||||
from.getDataCenter().getId());
|
||||
}
|
||||
|
||||
});
|
||||
sizes.add(new SizeImpl(from.getId(), from.getId(), from.getId(), location, null,
|
||||
ImmutableMap.<String, String> of(), 1, from.getRam(), from.getDiskSize(),
|
||||
ImagePredicates.any()));
|
||||
});
|
||||
sizes.add(new SizeImpl(from.getId(), from.getId(), from.getId(),
|
||||
location, null, ImmutableMap.<String, String> of(), 1, from
|
||||
.getRam(), from.getDiskSize(), ImagePredicates.any()));
|
||||
} catch (NullPointerException e) {
|
||||
holder.logger.warn("datacenter not present in " + from.getId());
|
||||
}
|
||||
|
@ -439,15 +453,16 @@ public class RimuHostingComputeServiceContextModule extends RimuHostingContextMo
|
|||
|
||||
@Provides
|
||||
@Singleton
|
||||
protected Set<? extends Image> provideImages(final RimuHostingClient sync, LogHolder holder,
|
||||
Function<ComputeMetadata, String> indexer) throws InterruptedException,
|
||||
ExecutionException, TimeoutException {
|
||||
protected Set<? extends Image> provideImages(final RimuHostingClient sync,
|
||||
LogHolder holder, Function<ComputeMetadata, String> indexer)
|
||||
throws InterruptedException, ExecutionException, TimeoutException {
|
||||
final Set<Image> images = Sets.newHashSet();
|
||||
holder.logger.debug(">> providing images");
|
||||
for (final org.jclouds.rimuhosting.miro.domain.Image from : sync.getImageList()) {
|
||||
for (final org.jclouds.rimuhosting.miro.domain.Image from : sync
|
||||
.getImageList()) {
|
||||
OsFamily os = null;
|
||||
Architecture arch = from.getId().indexOf("64") == -1 ? Architecture.X86_32
|
||||
: Architecture.X86_64;
|
||||
: Architecture.X86_64;
|
||||
String osDescription = "";
|
||||
String version = "";
|
||||
|
||||
|
@ -462,9 +477,10 @@ public class RimuHostingComputeServiceContextModule extends RimuHostingContextMo
|
|||
}
|
||||
}
|
||||
|
||||
images.add(new ImageImpl(from.getId(), from.getDescription(), from.getId(), null, null,
|
||||
ImmutableMap.<String, String> of(), from.getDescription(), version, os,
|
||||
osDescription, arch, new Credentials("root", null)));
|
||||
images.add(new ImageImpl(from.getId(), from.getDescription(), from
|
||||
.getId(), null, null, ImmutableMap.<String, String> of(), from
|
||||
.getDescription(), version, os, osDescription, arch,
|
||||
new Credentials("root", null)));
|
||||
}
|
||||
holder.logger.debug("<< images(%d)", images.size());
|
||||
return images;
|
||||
|
|
|
@ -20,27 +20,19 @@ package org.jclouds.rimuhosting.miro.config;
|
|||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URI;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
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.config.RestClientModule;
|
||||
import org.jclouds.rimuhosting.miro.RimuHosting;
|
||||
import org.jclouds.rimuhosting.miro.RimuHostingAsyncClient;
|
||||
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.predicates.ServerDestroyed;
|
||||
import org.jclouds.rimuhosting.miro.predicates.ServerRunning;
|
||||
import org.jclouds.rimuhosting.miro.reference.RimuHostingConstants;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.inject.Provides;
|
||||
|
||||
/**
|
||||
|
@ -51,37 +43,17 @@ import com.google.inject.Provides;
|
|||
@RequiresHttp
|
||||
@ConfiguresRestClient
|
||||
public class RimuHostingRestClientModule extends
|
||||
RestClientModule<RimuHostingClient, RimuHostingAsyncClient> {
|
||||
RestClientModule<RimuHostingClient, RimuHostingAsyncClient> {
|
||||
|
||||
public RimuHostingRestClientModule() {
|
||||
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
|
||||
@Singleton
|
||||
public RimuHostingAuthentication provideRimuHostingAuthentication(
|
||||
@Named(RimuHostingConstants.PROPERTY_RIMUHOSTING_APIKEY) String apikey)
|
||||
throws UnsupportedEncodingException {
|
||||
@Named(RimuHostingConstants.PROPERTY_RIMUHOSTING_APIKEY) String apikey)
|
||||
throws UnsupportedEncodingException {
|
||||
return new RimuHostingAuthentication(apikey);
|
||||
}
|
||||
|
||||
|
@ -89,7 +61,7 @@ public class RimuHostingRestClientModule extends
|
|||
@Singleton
|
||||
@RimuHosting
|
||||
protected URI provideURI(
|
||||
@Named(RimuHostingConstants.PROPERTY_RIMUHOSTING_ENDPOINT) String endpoint) {
|
||||
@Named(RimuHostingConstants.PROPERTY_RIMUHOSTING_ENDPOINT) String endpoint) {
|
||||
return URI.create(endpoint);
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
*/
|
||||
package org.jclouds.rimuhosting.miro.domain.internal;
|
||||
|
||||
|
||||
/**
|
||||
* States an instance can be in.
|
||||
*
|
||||
|
|
|
@ -33,12 +33,13 @@ public class ServerRunning implements Predicate<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);
|
||||
if (server == null)
|
||||
return false;
|
||||
logger.trace("%s: looking for server state %s: currently: %s", server.getId(),
|
||||
RunningState.RUNNING, server.getState());
|
||||
logger.trace("%s: looking for server state %s: currently: %s", server
|
||||
.getId(), RunningState.RUNNING, server.getState());
|
||||
return server.getState() == RunningState.RUNNING;
|
||||
}
|
||||
|
||||
|
|
|
@ -19,15 +19,22 @@
|
|||
package org.jclouds.rimuhosting.miro;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
|
||||
import org.jclouds.rimuhosting.miro.domain.*;
|
||||
import org.jclouds.rimuhosting.miro.domain.internal.RunningState;
|
||||
import static org.testng.Assert.*;
|
||||
import org.testng.annotations.BeforeGroups;
|
||||
import org.testng.annotations.Test;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
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}
|
||||
*
|
||||
|
@ -40,10 +47,12 @@ public class RimuHostingClientLiveTest {
|
|||
|
||||
@BeforeGroups(groups = { "live" })
|
||||
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())
|
||||
.getProviderSpecificContext().getApi();
|
||||
connection = (RimuHostingClient) RimuHostingContextFactory.createContext(
|
||||
password, new Log4JLoggingModule()).getProviderSpecificContext()
|
||||
.getApi();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -73,8 +82,8 @@ public class RimuHostingClientLiveTest {
|
|||
@Test
|
||||
public void testLifeCycle() {
|
||||
// Get the first image, we dont really care what it is in this test.
|
||||
NewServerResponse serverResponse = connection.createServer("test.ivan.api.com", "lenny",
|
||||
"MIRO1B");
|
||||
NewServerResponse serverResponse = connection.createServer(
|
||||
"test.ivan.api.com", "lenny", "MIRO1B");
|
||||
Server server = serverResponse.getServer();
|
||||
// Now we have the server, lets restart it
|
||||
assertNotNull(server.getId());
|
||||
|
|
|
@ -3,7 +3,6 @@ package org.jclouds.vcloud.bluelock.compute;
|
|||
import java.util.Map;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.compute.domain.NodeState;
|
||||
|
@ -25,18 +24,20 @@ public class BlueLockVCloudComputeClient extends BaseVCloudComputeClient {
|
|||
|
||||
@Inject
|
||||
protected BlueLockVCloudComputeClient(
|
||||
PopulateDefaultLoginCredentialsForImageStrategy credentialsProvider,
|
||||
VCloudClient client, Predicate<String> successTester,
|
||||
@Named("NOT_FOUND") Predicate<VApp> notFoundTester,
|
||||
Map<VAppStatus, NodeState> vAppStatusToNodeState) {
|
||||
super(client, successTester, notFoundTester, vAppStatusToNodeState);
|
||||
PopulateDefaultLoginCredentialsForImageStrategy credentialsProvider,
|
||||
VCloudClient client, Predicate<String> successTester,
|
||||
Map<VAppStatus, NodeState> vAppStatusToNodeState) {
|
||||
super(client, successTester, vAppStatusToNodeState);
|
||||
this.credentialsProvider = credentialsProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<String, String> parseAndValidateResponse(String templateId, VApp vAppResponse) {
|
||||
Credentials credentials = credentialsProvider.execute(client.getVAppTemplate(templateId));
|
||||
Map<String, String> toReturn = super.parseResponse(templateId, vAppResponse);
|
||||
protected Map<String, String> parseAndValidateResponse(String templateId,
|
||||
VApp vAppResponse) {
|
||||
Credentials credentials = credentialsProvider.execute(client
|
||||
.getVAppTemplate(templateId));
|
||||
Map<String, String> toReturn = super.parseResponse(templateId,
|
||||
vAppResponse);
|
||||
toReturn.put("username", credentials.account);
|
||||
toReturn.put("password", credentials.key);
|
||||
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_KEY;
|
||||
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_VERSION;
|
||||
import static org.jclouds.vcloud.reference.VCloudConstants.PROPERTY_VCLOUD_XML_NAMESPACE;
|
||||
|
@ -47,11 +48,14 @@ public class VCloudPropertiesBuilder extends PropertiesBuilder {
|
|||
properties.setProperty(PROPERTY_VCLOUD_VERSION, "0.8");
|
||||
properties.setProperty(PROPERTY_VCLOUD_SESSIONINTERVAL, 8 * 60 + "");
|
||||
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_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_max", "80");
|
||||
properties.setProperty(PROPERTY_VCLOUD_TIMEOUT_TASK_COMPLETED,
|
||||
180l * 1000l + "");
|
||||
return properties;
|
||||
}
|
||||
|
||||
|
@ -62,8 +66,9 @@ public class VCloudPropertiesBuilder extends PropertiesBuilder {
|
|||
|
||||
private void setNs() {
|
||||
if (properties.getProperty(PROPERTY_VCLOUD_XML_NAMESPACE) == null)
|
||||
properties.setProperty(PROPERTY_VCLOUD_XML_NAMESPACE, "http://www.vmware.com/vcloud/v"
|
||||
+ properties.getProperty(PROPERTY_VCLOUD_VERSION));
|
||||
properties.setProperty(PROPERTY_VCLOUD_XML_NAMESPACE,
|
||||
"http://www.vmware.com/vcloud/v"
|
||||
+ properties.getProperty(PROPERTY_VCLOUD_VERSION));
|
||||
}
|
||||
|
||||
public VCloudPropertiesBuilder(URI endpoint, String id, String secret) {
|
||||
|
@ -85,8 +90,8 @@ public class VCloudPropertiesBuilder extends PropertiesBuilder {
|
|||
}
|
||||
|
||||
public VCloudPropertiesBuilder withEndpoint(URI endpoint) {
|
||||
properties.setProperty(PROPERTY_VCLOUD_ENDPOINT, checkNotNull(endpoint, "endpoint")
|
||||
.toString());
|
||||
properties.setProperty(PROPERTY_VCLOUD_ENDPOINT, checkNotNull(endpoint,
|
||||
"endpoint").toString());
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,58 +54,64 @@ public class BaseVCloudComputeClient implements VCloudComputeClient {
|
|||
|
||||
protected final VCloudClient client;
|
||||
protected final Predicate<String> taskTester;
|
||||
protected final Predicate<VApp> notFoundTester;
|
||||
protected final Map<VAppStatus, NodeState> vAppStatusToNodeState;
|
||||
|
||||
@Inject
|
||||
public BaseVCloudComputeClient(VCloudClient client, Predicate<String> successTester,
|
||||
@Named("NOT_FOUND") Predicate<VApp> notFoundTester,
|
||||
Map<VAppStatus, NodeState> vAppStatusToNodeState) {
|
||||
public BaseVCloudComputeClient(VCloudClient client,
|
||||
Predicate<String> successTester,
|
||||
Map<VAppStatus, NodeState> vAppStatusToNodeState) {
|
||||
this.client = client;
|
||||
this.taskTester = successTester;
|
||||
this.notFoundTester = notFoundTester;
|
||||
this.vAppStatusToNodeState = vAppStatusToNodeState;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> start(String vDCId, String name, String templateId,
|
||||
InstantiateVAppTemplateOptions options, int... portsToOpen) {
|
||||
public Map<String, String> start(String vDCId, String name,
|
||||
String templateId, InstantiateVAppTemplateOptions options,
|
||||
int... portsToOpen) {
|
||||
checkNotNull(options, "options");
|
||||
|
||||
logger.debug(">> instantiating vApp vDC(%s) name(%s) template(%s) options(%s) ", vDCId, name,
|
||||
templateId, options);
|
||||
logger.debug(
|
||||
">> 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(">> deploying vApp(%s)", vAppResponse.getId());
|
||||
|
||||
Task task = client.deployVApp(vAppResponse.getId());
|
||||
if (!taskTester.apply(task.getId())) {
|
||||
throw new TaskException("deploy", vAppResponse, task);
|
||||
}
|
||||
logger.debug("<< deployed vApp(%s)", vAppResponse.getId());
|
||||
if (options.shouldBlockOnDeploy()) {
|
||||
if (!taskTester.apply(task.getId())) {
|
||||
throw new TaskException("deploy", vAppResponse, task);
|
||||
}
|
||||
logger.debug("<< deployed vApp(%s)", vAppResponse.getId());
|
||||
|
||||
logger.debug(">> powering vApp(%s)", vAppResponse.getId());
|
||||
task = client.powerOnVApp(vAppResponse.getId());
|
||||
if (!taskTester.apply(task.getId())) {
|
||||
throw new TaskException("powerOn", vAppResponse, task);
|
||||
logger.debug(">> powering vApp(%s)", vAppResponse.getId());
|
||||
task = client.powerOnVApp(vAppResponse.getId());
|
||||
if (!taskTester.apply(task.getId())) {
|
||||
throw new TaskException("powerOn", vAppResponse, task);
|
||||
}
|
||||
logger.debug("<< on vApp(%s)", vAppResponse.getId());
|
||||
}
|
||||
logger.debug("<< on vApp(%s)", vAppResponse.getId());
|
||||
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);
|
||||
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"),
|
||||
"bad configuration: [username] should be in response");
|
||||
"bad configuration: [username] should be in response");
|
||||
checkState(response.containsKey("password"),
|
||||
"bad configuration: [password] should be in response");
|
||||
"bad configuration: [password] should be in 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
|
||||
config.put("id", vAppResponse.getId());
|
||||
config.put("username", null);
|
||||
|
@ -127,22 +133,19 @@ public class BaseVCloudComputeClient implements VCloudComputeClient {
|
|||
VApp vApp = client.getVApp(id);
|
||||
vApp = powerOffVAppIfDeployed(vApp);
|
||||
vApp = undeployVAppIfDeployed(vApp);
|
||||
boolean successful = deleteVApp(vApp);
|
||||
logger.debug("<< deleted vApp(%s) completed(%s)", vApp.getId(), successful);
|
||||
deleteVApp(vApp);
|
||||
logger.debug("<< deleted vApp(%s)", vApp.getId());
|
||||
}
|
||||
|
||||
private boolean deleteVApp(VApp vApp) {
|
||||
private void deleteVApp(VApp vApp) {
|
||||
logger.debug(">> deleting vApp(%s)", vApp.getId());
|
||||
client.deleteVApp(vApp.getId());
|
||||
boolean successful = notFoundTester.apply(vApp);
|
||||
return successful;
|
||||
}
|
||||
|
||||
private VApp undeployVAppIfDeployed(VApp vApp) {
|
||||
if (vApp.getStatus().compareTo(VAppStatus.RESOLVED) > 0) {
|
||||
logger
|
||||
.debug(">> undeploying vApp(%s), current status: %s", vApp.getId(), vApp
|
||||
.getStatus());
|
||||
logger.debug(">> undeploying vApp(%s), current status: %s", vApp
|
||||
.getId(), vApp.getStatus());
|
||||
Task task = client.undeployVApp(vApp.getId());
|
||||
if (!taskTester.apply(task.getId())) {
|
||||
throw new TaskException("undeploy", vApp, task);
|
||||
|
@ -155,8 +158,8 @@ public class BaseVCloudComputeClient implements VCloudComputeClient {
|
|||
|
||||
private VApp powerOffVAppIfDeployed(VApp vApp) {
|
||||
if (vApp.getStatus().compareTo(VAppStatus.OFF) > 0) {
|
||||
logger.debug(">> powering off vApp(%s), current status: %s", vApp.getId(), vApp
|
||||
.getStatus());
|
||||
logger.debug(">> powering off vApp(%s), current status: %s", vApp
|
||||
.getId(), vApp.getStatus());
|
||||
Task task = client.powerOffVApp(vApp.getId());
|
||||
if (!taskTester.apply(task.getId())) {
|
||||
throw new TaskException("powerOff", vApp, task);
|
||||
|
@ -174,8 +177,10 @@ public class BaseVCloudComputeClient implements VCloudComputeClient {
|
|||
private static final long serialVersionUID = 251801929573211256L;
|
||||
|
||||
public TaskException(String type, VApp vApp, Task task) {
|
||||
super(String.format("failed to %s vApp %s status %s;task %s status %s", type,
|
||||
vApp.getId(), vApp.getStatus(), task.getLocation(), task.getStatus()), vApp);
|
||||
super(String.format(
|
||||
"failed to %s vApp %s status %s;task %s status %s", type, vApp
|
||||
.getId(), vApp.getStatus(), task.getLocation(), task
|
||||
.getStatus()), vApp);
|
||||
this.task = task;
|
||||
}
|
||||
|
||||
|
|
|
@ -22,21 +22,19 @@ import static org.jclouds.compute.domain.OsFamily.UBUNTU;
|
|||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.compute.ComputeServiceContext;
|
||||
import org.jclouds.compute.LoadBalancerService;
|
||||
import org.jclouds.compute.config.ComputeServiceTimeoutsModule;
|
||||
import org.jclouds.compute.domain.ComputeMetadata;
|
||||
import org.jclouds.compute.domain.Image;
|
||||
import org.jclouds.compute.domain.NodeState;
|
||||
import org.jclouds.compute.domain.Size;
|
||||
import org.jclouds.compute.domain.TemplateBuilder;
|
||||
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.DestroyNodeStrategy;
|
||||
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.RunNodesAndAddToSetStrategy;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.predicates.RetryablePredicate;
|
||||
import org.jclouds.vcloud.VCloudAsyncClient;
|
||||
import org.jclouds.vcloud.VCloudClient;
|
||||
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.Predicate;
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.inject.Provides;
|
||||
|
@ -103,6 +99,7 @@ public class VCloudComputeServiceContextModule extends VCloudContextModule {
|
|||
@Override
|
||||
protected void configure() {
|
||||
super.configure();
|
||||
install(new ComputeServiceTimeoutsModule());
|
||||
bind(String.class).annotatedWith(VCloud.class).toInstance(providerName);
|
||||
bind(AddNodeWithTagStrategy.class).to(VCloudAddNodeWithTagStrategy.class);
|
||||
bind(new TypeLiteral<ComputeServiceContext>() {
|
||||
|
@ -127,14 +124,6 @@ public class VCloudComputeServiceContextModule extends VCloudContextModule {
|
|||
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() {
|
||||
bind(LoadBalancerService.class).toProvider(Providers.<LoadBalancerService> of(null));
|
||||
}
|
||||
|
|
|
@ -40,28 +40,32 @@ import com.google.common.base.Strings;
|
|||
*/
|
||||
@Singleton
|
||||
public class EncodeTemplateIdIntoNameRunNodesAndAddToSetStrategy extends
|
||||
EncodeTagIntoNameRunNodesAndAddToSetStrategy {
|
||||
EncodeTagIntoNameRunNodesAndAddToSetStrategy {
|
||||
|
||||
private final SecureRandom random;
|
||||
|
||||
@Inject
|
||||
protected EncodeTemplateIdIntoNameRunNodesAndAddToSetStrategy(
|
||||
AddNodeWithTagStrategy addNodeWithTagStrategy, ListNodesStrategy listNodesStrategy,
|
||||
@Named("NAMING_CONVENTION") String nodeNamingConvention, ComputeUtils utils,
|
||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) {
|
||||
super(addNodeWithTagStrategy, listNodesStrategy, nodeNamingConvention, utils, executor);
|
||||
AddNodeWithTagStrategy addNodeWithTagStrategy,
|
||||
ListNodesStrategy listNodesStrategy,
|
||||
@Named("NAMING_CONVENTION") String nodeNamingConvention,
|
||||
ComputeUtils utils,
|
||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) {
|
||||
super(addNodeWithTagStrategy, listNodesStrategy, nodeNamingConvention,
|
||||
utils, executor);
|
||||
this.random = new SecureRandom();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a name corresponding to the tag-hex*5 where the first 3 hex correspond to the template id
|
||||
* and the last a random number
|
||||
* Get a name corresponding to the tag-hex*5 where the first 3 hex correspond
|
||||
* to the template id and the last a random number
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
protected String getNextName(final String tag, final Template template) {
|
||||
return String.format(nodeNamingConvention, tag, Strings.padStart(Integer.toHexString(Integer
|
||||
.parseInt(template.getImage().getProviderId())), 3, '0'), Strings.padStart(Integer
|
||||
.toHexString(random.nextInt(255)), 2, '0'));
|
||||
return String.format(nodeNamingConvention, tag, Strings.padStart(
|
||||
Integer.toHexString(Integer.parseInt(template.getImage()
|
||||
.getProviderId())), 3, '0'), Strings.padStart(Integer
|
||||
.toHexString(random.nextInt(255)), 2, '0'));
|
||||
}
|
||||
}
|
|
@ -49,8 +49,9 @@ public class VCloudAddNodeWithTagStrategy implements AddNodeWithTagStrategy {
|
|||
protected final Map<VAppStatus, NodeState> vAppStatusToNodeState;
|
||||
|
||||
@Inject
|
||||
protected VCloudAddNodeWithTagStrategy(VCloudClient client, VCloudComputeClient computeClient,
|
||||
Map<VAppStatus, NodeState> vAppStatusToNodeState) {
|
||||
protected VCloudAddNodeWithTagStrategy(VCloudClient client,
|
||||
VCloudComputeClient computeClient,
|
||||
Map<VAppStatus, NodeState> vAppStatusToNodeState) {
|
||||
this.client = client;
|
||||
this.computeClient = computeClient;
|
||||
this.vAppStatusToNodeState = vAppStatusToNodeState;
|
||||
|
@ -58,25 +59,29 @@ public class VCloudAddNodeWithTagStrategy implements AddNodeWithTagStrategy {
|
|||
|
||||
@Override
|
||||
public NodeMetadata execute(String tag, String name, Template template) {
|
||||
|
||||
InstantiateVAppTemplateOptions options = processorCount(
|
||||
Double.valueOf(template.getSize().getCores()).intValue()).memory(
|
||||
template.getSize().getRam()).disk(template.getSize().getDisk() * 1024 * 1024l);
|
||||
Map<String, String> metaMap = computeClient.start(template.getLocation().getId(), name,
|
||||
template.getImage().getProviderId(), options, template.getOptions()
|
||||
.getInboundPorts());
|
||||
Double.valueOf(template.getSize().getCores()).intValue()).memory(
|
||||
template.getSize().getRam()).disk(
|
||||
template.getSize().getDisk() * 1024 * 1024l);
|
||||
if (!template.getOptions().shouldBlockUntilRunning())
|
||||
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"));
|
||||
return newCreateNodeResponse(tag, template, metaMap, vApp);
|
||||
}
|
||||
|
||||
protected NodeMetadata newCreateNodeResponse(String tag, Template template,
|
||||
Map<String, String> metaMap, VApp vApp) {
|
||||
return new NodeMetadataImpl(vApp.getId(), vApp.getName(), vApp.getId(), template
|
||||
.getLocation(), vApp.getLocation(), ImmutableMap.<String, String> of(), tag,
|
||||
template.getImage(), vAppStatusToNodeState.get(vApp.getStatus()), computeClient
|
||||
.getPublicAddresses(vApp.getId()), computeClient.getPrivateAddresses(vApp
|
||||
.getId()), ImmutableMap.<String, String> of(), new Credentials(metaMap
|
||||
.get("username"), metaMap.get("password")));
|
||||
Map<String, String> metaMap, VApp vApp) {
|
||||
return new NodeMetadataImpl(vApp.getId(), vApp.getName(), vApp.getId(),
|
||||
template.getLocation(), vApp.getLocation(), ImmutableMap
|
||||
.<String, String> of(), tag, template.getImage(),
|
||||
vAppStatusToNodeState.get(vApp.getStatus()), computeClient
|
||||
.getPublicAddresses(vApp.getId()), computeClient
|
||||
.getPrivateAddresses(vApp.getId()), ImmutableMap
|
||||
.<String, String> of(), new Credentials(metaMap
|
||||
.get("username"), metaMap.get("password")));
|
||||
}
|
||||
|
||||
}
|
|
@ -23,7 +23,9 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.strategy.DestroyNodeStrategy;
|
||||
import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
|
||||
import org.jclouds.vcloud.compute.VCloudComputeClient;
|
||||
|
||||
/**
|
||||
|
@ -32,16 +34,20 @@ import org.jclouds.vcloud.compute.VCloudComputeClient;
|
|||
@Singleton
|
||||
public class VCloudDestroyNodeStrategy implements DestroyNodeStrategy {
|
||||
protected final VCloudComputeClient computeClient;
|
||||
protected final GetNodeMetadataStrategy getNode;
|
||||
|
||||
@Inject
|
||||
protected VCloudDestroyNodeStrategy(VCloudComputeClient computeClient) {
|
||||
protected VCloudDestroyNodeStrategy(VCloudComputeClient computeClient,
|
||||
GetNodeMetadataStrategy getNode) {
|
||||
this.computeClient = computeClient;
|
||||
this.getNode = getNode;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(String id) {
|
||||
public NodeMetadata execute(String 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.Singleton;
|
||||
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
|
||||
import org.jclouds.compute.strategy.RebootNodeStrategy;
|
||||
import org.jclouds.vcloud.VCloudClient;
|
||||
import org.jclouds.vcloud.domain.Task;
|
||||
|
@ -36,17 +38,21 @@ import com.google.common.base.Predicate;
|
|||
public class VCloudRebootNodeStrategy implements RebootNodeStrategy {
|
||||
private final VCloudClient client;
|
||||
protected final Predicate<String> taskTester;
|
||||
protected final GetNodeMetadataStrategy getNode;
|
||||
|
||||
@Inject
|
||||
protected VCloudRebootNodeStrategy(VCloudClient client, Predicate<String> taskTester) {
|
||||
protected VCloudRebootNodeStrategy(VCloudClient client,
|
||||
Predicate<String> taskTester, GetNodeMetadataStrategy getNode) {
|
||||
this.client = client;
|
||||
this.taskTester = taskTester;
|
||||
this.getNode = getNode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(String id) {
|
||||
public NodeMetadata execute(String 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_KEY;
|
||||
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_VERSION;
|
||||
|
||||
|
@ -49,9 +50,7 @@ import org.jclouds.http.annotation.Redirection;
|
|||
import org.jclouds.http.annotation.ServerError;
|
||||
import org.jclouds.http.filters.BasicAuthentication;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.net.IPSocket;
|
||||
import org.jclouds.predicates.RetryablePredicate;
|
||||
import org.jclouds.predicates.SocketOpen;
|
||||
import org.jclouds.rest.AsyncClientFactory;
|
||||
import org.jclouds.rest.AuthorizationException;
|
||||
import org.jclouds.rest.ConfiguresRestClient;
|
||||
|
@ -61,7 +60,6 @@ import org.jclouds.vcloud.VCloudClient;
|
|||
import org.jclouds.vcloud.VCloudToken;
|
||||
import org.jclouds.vcloud.domain.NamedResource;
|
||||
import org.jclouds.vcloud.domain.Organization;
|
||||
import org.jclouds.vcloud.domain.VApp;
|
||||
import org.jclouds.vcloud.endpoints.Catalog;
|
||||
import org.jclouds.vcloud.endpoints.Network;
|
||||
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.VCloudLoginAsyncClient.VCloudSession;
|
||||
import org.jclouds.vcloud.predicates.TaskSuccess;
|
||||
import org.jclouds.vcloud.predicates.VAppNotFound;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Supplier;
|
||||
|
@ -87,16 +84,18 @@ import com.google.common.collect.Iterables;
|
|||
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
|
||||
*/
|
||||
@RequiresHttp
|
||||
@ConfiguresRestClient
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -111,35 +110,26 @@ public abstract class BaseVCloudRestClientModule<S extends VCloudClient, A exten
|
|||
|
||||
@Provides
|
||||
@Singleton
|
||||
protected Predicate<IPSocket> socketTester(SocketOpen open) {
|
||||
return new RetryablePredicate<IPSocket>(open, 130, 10, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@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);
|
||||
protected Predicate<String> successTester(TaskSuccess success,
|
||||
@Named(PROPERTY_VCLOUD_TIMEOUT_TASK_COMPLETED) long completed) {
|
||||
return new RetryablePredicate<String>(success, completed);
|
||||
}
|
||||
|
||||
@VCloudToken
|
||||
@Provides
|
||||
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
|
||||
@Org
|
||||
@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();
|
||||
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();
|
||||
}
|
||||
|
||||
|
@ -158,30 +148,36 @@ public abstract class BaseVCloudRestClientModule<S extends VCloudClient, A exten
|
|||
@Provides
|
||||
@Singleton
|
||||
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>(
|
||||
new RetryOnTimeOutExceptionSupplier<VCloudSession>(new Supplier<VCloudSession>() {
|
||||
public VCloudSession get() {
|
||||
// http://code.google.com/p/google-guice/issues/detail?id=483
|
||||
// guice doesn't remember when singleton providers throw exceptions.
|
||||
// in this case, if describeRegions fails, it is called 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)
|
||||
throw authException;
|
||||
try {
|
||||
return login.login().get(10, TimeUnit.SECONDS);
|
||||
} catch (AuthorizationException e) {
|
||||
BaseVCloudRestClientModule.this.authException = e;
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
Throwables.propagate(e);
|
||||
assert false : e;
|
||||
return null;
|
||||
new RetryOnTimeOutExceptionSupplier<VCloudSession>(
|
||||
new Supplier<VCloudSession>() {
|
||||
public VCloudSession get() {
|
||||
// http://code.google.com/p/google-guice/issues/detail?id=483
|
||||
// guice doesn't remember when singleton providers throw
|
||||
// exceptions.
|
||||
// in this case, if describeRegions fails, it is called
|
||||
// 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)
|
||||
throw authException;
|
||||
try {
|
||||
return login.login().get(10, TimeUnit.SECONDS);
|
||||
} catch (AuthorizationException e) {
|
||||
BaseVCloudRestClientModule.this.authException = e;
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
Throwables.propagate(e);
|
||||
assert false : e;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}), seconds, TimeUnit.SECONDS);
|
||||
}), seconds, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Provides
|
||||
|
@ -194,34 +190,39 @@ public abstract class BaseVCloudRestClientModule<S extends VCloudClient, A exten
|
|||
@Provides
|
||||
@Singleton
|
||||
@org.jclouds.vcloud.endpoints.VCloudLogin
|
||||
protected URI provideAuthenticationURI(VCloudVersionsAsyncClient versionService,
|
||||
@Named(PROPERTY_VCLOUD_VERSION) String version) throws InterruptedException,
|
||||
ExecutionException, TimeoutException {
|
||||
SortedMap<String, URI> versions = versionService.getSupportedVersions().get(180,
|
||||
TimeUnit.SECONDS);
|
||||
protected URI provideAuthenticationURI(
|
||||
VCloudVersionsAsyncClient versionService,
|
||||
@Named(PROPERTY_VCLOUD_VERSION) String version)
|
||||
throws InterruptedException, ExecutionException, TimeoutException {
|
||||
SortedMap<String, URI> versions = versionService.getSupportedVersions()
|
||||
.get(180, TimeUnit.SECONDS);
|
||||
checkState(versions.size() > 0, "No versions present");
|
||||
checkState(versions.containsKey(version), "version " + version + " not present in: "
|
||||
+ versions);
|
||||
checkState(versions.containsKey(version), "version " + version
|
||||
+ " not present in: " + versions);
|
||||
return versions.get(version);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
protected VCloudLoginAsyncClient provideVCloudLogin(AsyncClientFactory factory) {
|
||||
protected VCloudLoginAsyncClient provideVCloudLogin(
|
||||
AsyncClientFactory factory) {
|
||||
return factory.create(VCloudLoginAsyncClient.class);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
protected VCloudVersionsAsyncClient provideVCloudVersions(AsyncClientFactory factory) {
|
||||
protected VCloudVersionsAsyncClient provideVCloudVersions(
|
||||
AsyncClientFactory factory) {
|
||||
return factory.create(VCloudVersionsAsyncClient.class);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
public BasicAuthentication provideBasicAuthentication(@Named(PROPERTY_VCLOUD_USER) String user,
|
||||
@Named(PROPERTY_VCLOUD_KEY) String key, EncryptionService encryptionService)
|
||||
throws UnsupportedEncodingException {
|
||||
public BasicAuthentication provideBasicAuthentication(
|
||||
@Named(PROPERTY_VCLOUD_USER) String user,
|
||||
@Named(PROPERTY_VCLOUD_KEY) String key,
|
||||
EncryptionService encryptionService)
|
||||
throws UnsupportedEncodingException {
|
||||
return new BasicAuthentication(user, key, encryptionService);
|
||||
}
|
||||
|
||||
|
@ -248,8 +249,8 @@ public abstract class BaseVCloudRestClientModule<S extends VCloudClient, A exten
|
|||
|
||||
@Provides
|
||||
@Singleton
|
||||
protected Organization provideOrganization(VCloudClient discovery) throws ExecutionException,
|
||||
TimeoutException, InterruptedException {
|
||||
protected Organization provideOrganization(VCloudClient discovery)
|
||||
throws ExecutionException, TimeoutException, InterruptedException {
|
||||
if (authException != null)
|
||||
throw authException;
|
||||
try {
|
||||
|
@ -264,29 +265,33 @@ public abstract class BaseVCloudRestClientModule<S extends VCloudClient, A exten
|
|||
@VDC
|
||||
@Singleton
|
||||
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();
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Catalog
|
||||
@Singleton
|
||||
protected URI provideCatalog(Organization org, @Named(PROPERTY_VCLOUD_USER) String user) {
|
||||
checkState(org.getCatalogs().size() > 0, "No catalogs present in org: " + org.getName());
|
||||
protected URI provideCatalog(Organization org,
|
||||
@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();
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Network
|
||||
@Singleton
|
||||
protected URI provideDefaultNetwork(VCloudClient client) throws InterruptedException,
|
||||
ExecutionException, TimeoutException {
|
||||
protected URI provideDefaultNetwork(VCloudClient client)
|
||||
throws InterruptedException, ExecutionException, TimeoutException {
|
||||
if (authException != null)
|
||||
throw authException;
|
||||
try {
|
||||
org.jclouds.vcloud.domain.VDC vDC = client.getDefaultVDC();
|
||||
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();
|
||||
} catch (AuthorizationException e) {
|
||||
BaseVCloudRestClientModule.this.authException = e;
|
||||
|
@ -304,18 +309,19 @@ public abstract class BaseVCloudRestClientModule<S extends VCloudClient, A exten
|
|||
@Override
|
||||
protected void bindErrorHandlers() {
|
||||
bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(
|
||||
ParseVCloudErrorFromHttpResponse.class);
|
||||
ParseVCloudErrorFromHttpResponse.class);
|
||||
bind(HttpErrorHandler.class).annotatedWith(ClientError.class).to(
|
||||
ParseVCloudErrorFromHttpResponse.class);
|
||||
ParseVCloudErrorFromHttpResponse.class);
|
||||
bind(HttpErrorHandler.class).annotatedWith(ServerError.class).to(
|
||||
ParseVCloudErrorFromHttpResponse.class);
|
||||
ParseVCloudErrorFromHttpResponse.class);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@TasksList
|
||||
@Singleton
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,14 +42,26 @@ public class InstantiateVAppTemplateOptions {
|
|||
private String fenceMode;
|
||||
private String dhcpEnabled;
|
||||
private String networkName;
|
||||
private boolean blockOnDeploy = true;
|
||||
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"));
|
||||
return this;
|
||||
}
|
||||
|
||||
public InstantiateVAppTemplateOptions productProperties(Map<String, String> properties) {
|
||||
public InstantiateVAppTemplateOptions productProperties(
|
||||
Map<String, String> properties) {
|
||||
this.properties.putAll(checkNotNull(properties, "properties"));
|
||||
return this;
|
||||
}
|
||||
|
@ -88,7 +100,8 @@ public class InstantiateVAppTemplateOptions {
|
|||
}
|
||||
|
||||
public InstantiateVAppTemplateOptions inNetwork(URI networkLocation) {
|
||||
this.network = checkNotNull(networkLocation, "networkLocation").toASCIIString();
|
||||
this.network = checkNotNull(networkLocation, "networkLocation")
|
||||
.toASCIIString();
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -126,6 +139,15 @@ public class InstantiateVAppTemplateOptions {
|
|||
|
||||
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)
|
||||
*/
|
||||
|
@ -169,7 +191,8 @@ public class InstantiateVAppTemplateOptions {
|
|||
/**
|
||||
* @see InstantiateVAppTemplateOptions#dhcpEnabled(boolean)
|
||||
*/
|
||||
public static InstantiateVAppTemplateOptions dhcpEnabled(boolean dhcpEnabled) {
|
||||
public static InstantiateVAppTemplateOptions dhcpEnabled(
|
||||
boolean dhcpEnabled) {
|
||||
InstantiateVAppTemplateOptions options = new InstantiateVAppTemplateOptions();
|
||||
return options.dhcpEnabled(dhcpEnabled);
|
||||
}
|
||||
|
@ -177,7 +200,8 @@ public class InstantiateVAppTemplateOptions {
|
|||
/**
|
||||
* @see InstantiateVAppTemplateOptions#networkName(String)
|
||||
*/
|
||||
public static InstantiateVAppTemplateOptions networkName(String networkName) {
|
||||
public static InstantiateVAppTemplateOptions networkName(
|
||||
String networkName) {
|
||||
InstantiateVAppTemplateOptions options = new InstantiateVAppTemplateOptions();
|
||||
return options.networkName(networkName);
|
||||
}
|
||||
|
@ -185,7 +209,8 @@ public class InstantiateVAppTemplateOptions {
|
|||
/**
|
||||
* @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();
|
||||
return options.productProperty(key, value);
|
||||
}
|
||||
|
@ -193,7 +218,8 @@ public class InstantiateVAppTemplateOptions {
|
|||
/**
|
||||
* @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();
|
||||
return options.productProperties(properties);
|
||||
}
|
||||
|
@ -201,10 +227,12 @@ public class InstantiateVAppTemplateOptions {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "InstantiateVAppTemplateOptions [cpuCount=" + cpuCount + ", memorySizeMegabytes="
|
||||
+ memorySizeMegabytes + ", diskSizeKilobytes=" + diskSizeKilobytes + ", network="
|
||||
+ network + ", networkName=" + networkName + ", fenceMode=" + fenceMode
|
||||
+ ", dhcpEnabled=" + dhcpEnabled + ", properties=" + properties + "]";
|
||||
return "InstantiateVAppTemplateOptions [cpuCount=" + cpuCount
|
||||
+ ", memorySizeMegabytes=" + memorySizeMegabytes
|
||||
+ ", diskSizeKilobytes=" + diskSizeKilobytes + ", network="
|
||||
+ network + ", networkName=" + networkName + ", fenceMode="
|
||||
+ fenceMode + ", dhcpEnabled=" + dhcpEnabled + ", properties="
|
||||
+ properties + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -212,14 +240,21 @@ public class InstantiateVAppTemplateOptions {
|
|||
final int prime = 31;
|
||||
int result = 1;
|
||||
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
|
||||
+ ((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 + ((networkName == null) ? 0 : networkName.hashCode());
|
||||
result = prime * result + ((properties == null) ? 0 : properties.hashCode());
|
||||
result = prime * result
|
||||
+ ((networkName == null) ? 0 : networkName.hashCode());
|
||||
result = prime * result
|
||||
+ ((properties == null) ? 0 : properties.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
*/
|
||||
package org.jclouds.vcloud.reference;
|
||||
|
||||
|
||||
/**
|
||||
* 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_SCHEMA = "jclouds.vcloud.xml.schema";
|
||||
|
||||
public static final String PROPERTY_VCLOUD_TIMEOUT_TASK_COMPLETED = "jclouds.vcloud.timeout.task-complete";
|
||||
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ public class VCloudComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
|||
@Override
|
||||
public void setServiceDefaults() {
|
||||
System.setProperty("vcloud.endpoint", checkNotNull(System
|
||||
.getProperty("jclouds.test.endpoint"), "jclouds.test.endpoint"));
|
||||
.getProperty("jclouds.test.endpoint"), "jclouds.test.endpoint"));
|
||||
service = "vcloud";
|
||||
}
|
||||
|
||||
|
@ -39,7 +39,8 @@ public class VCloudComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
|||
public void testAssignability() throws Exception {
|
||||
@SuppressWarnings("unused")
|
||||
RestContext<VCloudClient, VCloudAsyncClient> tmContext = new ComputeServiceContextFactory()
|
||||
.createContext(service, user, password).getProviderSpecificContext();
|
||||
.createContext(service, user, password)
|
||||
.getProviderSpecificContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -55,4 +56,5 @@ public class VCloudComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
|||
System.out.println(allData.getExtra());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -19,6 +19,7 @@
|
|||
package org.jclouds.vcloud.hostingdotcom;
|
||||
|
||||
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.util.Properties;
|
||||
|
@ -30,11 +31,15 @@ import org.jclouds.vcloud.VCloudPropertiesBuilder;
|
|||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class HostingDotComVCloudPropertiesBuilder extends VCloudPropertiesBuilder {
|
||||
public class HostingDotComVCloudPropertiesBuilder extends
|
||||
VCloudPropertiesBuilder {
|
||||
@Override
|
||||
protected Properties 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;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,6 @@ package org.jclouds.vcloud.hostingdotcom.compute;
|
|||
import java.util.Map;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.compute.domain.NodeState;
|
||||
|
@ -23,17 +22,18 @@ import com.google.common.collect.ImmutableMap;
|
|||
public class HostingDotComVCloudComputeClient extends BaseVCloudComputeClient {
|
||||
|
||||
@Inject
|
||||
protected HostingDotComVCloudComputeClient(VCloudClient client, Predicate<String> successTester,
|
||||
@Named("NOT_FOUND") Predicate<VApp> notFoundTester,
|
||||
Map<VAppStatus, NodeState> vAppStatusToNodeState) {
|
||||
super(client, successTester, notFoundTester, vAppStatusToNodeState);
|
||||
protected HostingDotComVCloudComputeClient(VCloudClient client,
|
||||
Predicate<String> successTester,
|
||||
Map<VAppStatus, NodeState> vAppStatusToNodeState) {
|
||||
super(client, successTester, vAppStatusToNodeState);
|
||||
}
|
||||
|
||||
@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);
|
||||
return ImmutableMap.<String, String> of("id", vAppResponse.getId(), "username", hVApp
|
||||
.getUsername(), "password", hVApp.getPassword());
|
||||
return ImmutableMap.<String, String> of("id", vAppResponse.getId(),
|
||||
"username", hVApp.getUsername(), "password", hVApp.getPassword());
|
||||
}
|
||||
|
||||
}
|
|
@ -19,40 +19,40 @@
|
|||
package org.jclouds.vcloud.hostingdotcom.config;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.http.RequiresHttp;
|
||||
import org.jclouds.predicates.RetryablePredicate;
|
||||
import org.jclouds.rest.ConfiguresRestClient;
|
||||
import org.jclouds.vcloud.VCloudAsyncClient;
|
||||
import org.jclouds.vcloud.VCloudClient;
|
||||
import org.jclouds.vcloud.config.BaseVCloudRestClientModule;
|
||||
import org.jclouds.vcloud.hostingdotcom.HostingDotComVCloudAsyncClient;
|
||||
import org.jclouds.vcloud.hostingdotcom.HostingDotComVCloudClient;
|
||||
import org.jclouds.vcloud.predicates.TaskSuccess;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
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
|
||||
*/
|
||||
@RequiresHttp
|
||||
@ConfiguresRestClient
|
||||
public class HostingDotComVCloudRestClientModule extends
|
||||
BaseVCloudRestClientModule<HostingDotComVCloudClient, HostingDotComVCloudAsyncClient> {
|
||||
public class HostingDotComVCloudRestClientModule
|
||||
extends
|
||||
BaseVCloudRestClientModule<HostingDotComVCloudClient, HostingDotComVCloudAsyncClient> {
|
||||
|
||||
public HostingDotComVCloudRestClientModule() {
|
||||
super(HostingDotComVCloudClient.class, HostingDotComVCloudAsyncClient.class);
|
||||
super(HostingDotComVCloudClient.class,
|
||||
HostingDotComVCloudAsyncClient.class);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
protected VCloudAsyncClient provideVCloudAsyncClient(HostingDotComVCloudAsyncClient in) {
|
||||
protected VCloudAsyncClient provideVCloudAsyncClient(
|
||||
HostingDotComVCloudAsyncClient in) {
|
||||
return in;
|
||||
}
|
||||
|
||||
|
@ -67,8 +67,4 @@ public class HostingDotComVCloudRestClientModule extends
|
|||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,37 +60,48 @@ public class TerremarkVCloudComputeClient extends BaseVCloudComputeClient {
|
|||
|
||||
@Inject
|
||||
protected TerremarkVCloudComputeClient(TerremarkVCloudClient client,
|
||||
PopulateDefaultLoginCredentialsForImageStrategy credentialsProvider,
|
||||
@Named("PASSWORD") Provider<String> passwordGenerator, Predicate<String> successTester,
|
||||
@Named("NOT_FOUND") Predicate<VApp> notFoundTester,
|
||||
Map<VAppStatus, NodeState> vAppStatusToNodeState) {
|
||||
super(client, successTester, notFoundTester, vAppStatusToNodeState);
|
||||
PopulateDefaultLoginCredentialsForImageStrategy credentialsProvider,
|
||||
@Named("PASSWORD") Provider<String> passwordGenerator,
|
||||
Predicate<String> successTester,
|
||||
Map<VAppStatus, NodeState> vAppStatusToNodeState) {
|
||||
super(client, successTester, vAppStatusToNodeState);
|
||||
this.client = client;
|
||||
this.credentialsProvider = credentialsProvider;
|
||||
this.passwordGenerator = passwordGenerator;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<String, String> parseAndValidateResponse(String templateId, VApp vAppResponse) {
|
||||
Credentials credentials = credentialsProvider.execute(client.getVAppTemplate(templateId));
|
||||
Map<String, String> toReturn = super.parseResponse(templateId, vAppResponse);
|
||||
protected Map<String, String> parseAndValidateResponse(String templateId,
|
||||
VApp vAppResponse) {
|
||||
Credentials credentials = credentialsProvider.execute(client
|
||||
.getVAppTemplate(templateId));
|
||||
Map<String, String> toReturn = super.parseResponse(templateId,
|
||||
vAppResponse);
|
||||
toReturn.put("username", credentials.account);
|
||||
toReturn.put("password", credentials.key);
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> start(String vDCId, String name, String templateId,
|
||||
InstantiateVAppTemplateOptions options, int... portsToOpen) {
|
||||
public Map<String, String> start(String vDCId, String name,
|
||||
String templateId, InstantiateVAppTemplateOptions options,
|
||||
int... portsToOpen) {
|
||||
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;
|
||||
if (client.getVAppTemplate(templateId).getDescription().indexOf("Windows") != -1) {
|
||||
if (client.getVAppTemplate(templateId).getDescription()
|
||||
.indexOf("Windows") != -1) {
|
||||
password = passwordGenerator.get();
|
||||
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) {
|
||||
response = new LinkedHashMap<String, String>(response);
|
||||
response.put("password", password);
|
||||
|
@ -103,68 +114,77 @@ public class TerremarkVCloudComputeClient extends BaseVCloudComputeClient {
|
|||
public String createPublicAddressMappedToPorts(String vAppId, int... ports) {
|
||||
VApp vApp = client.getVApp(vAppId);
|
||||
PublicIpAddress ip = null;
|
||||
String privateAddress = Iterables.getLast(vApp.getNetworkToAddresses().values());
|
||||
String privateAddress = Iterables.getLast(vApp.getNetworkToAddresses()
|
||||
.values());
|
||||
for (int port : ports) {
|
||||
InternetService is = null;
|
||||
Protocol protocol;
|
||||
switch (port) {
|
||||
case 22:
|
||||
protocol = Protocol.TCP;
|
||||
break;
|
||||
case 80:
|
||||
case 8080:
|
||||
protocol = Protocol.HTTP;
|
||||
break;
|
||||
case 443:
|
||||
protocol = Protocol.HTTPS;
|
||||
break;
|
||||
default:
|
||||
protocol = Protocol.HTTP;
|
||||
break;
|
||||
case 22:
|
||||
protocol = Protocol.TCP;
|
||||
break;
|
||||
case 80:
|
||||
case 8080:
|
||||
protocol = Protocol.HTTP;
|
||||
break;
|
||||
case 443:
|
||||
protocol = Protocol.HTTPS;
|
||||
break;
|
||||
default:
|
||||
protocol = Protocol.HTTP;
|
||||
break;
|
||||
}
|
||||
if (ip == null) {
|
||||
logger.debug(">> creating InternetService in vDC %s:%s:%d", vApp.getVDC().getId(),
|
||||
protocol, port);
|
||||
is = client.addInternetServiceToVDC(vApp.getVDC().getId(), vApp.getName() + "-" + port,
|
||||
protocol, port, withDescription(String.format(
|
||||
"port %d access to serverId: %s name: %s", port, vApp.getId(), vApp
|
||||
.getName())));
|
||||
logger.debug(">> creating InternetService in vDC %s:%s:%d", vApp
|
||||
.getVDC().getId(), protocol, port);
|
||||
is = client.addInternetServiceToVDC(vApp.getVDC().getId(), vApp
|
||||
.getName()
|
||||
+ "-" + port, protocol, port, withDescription(String.format(
|
||||
"port %d access to serverId: %s name: %s", port,
|
||||
vApp.getId(), vApp.getName())));
|
||||
ip = is.getPublicIpAddress();
|
||||
} else {
|
||||
logger.debug(">> adding InternetService %s:%s:%d", ip.getAddress(), protocol, port);
|
||||
is = client.addInternetServiceToExistingIp(ip.getId(), vApp.getName() + "-" + port,
|
||||
protocol, port, withDescription(String.format(
|
||||
"port %d access to serverId: %s name: %s", port, vApp.getId(), vApp
|
||||
.getName())));
|
||||
logger.debug(">> adding InternetService %s:%s:%d", ip.getAddress(),
|
||||
protocol, port);
|
||||
is = client.addInternetServiceToExistingIp(ip.getId(), vApp
|
||||
.getName()
|
||||
+ "-" + port, protocol, port, withDescription(String.format(
|
||||
"port %d access to serverId: %s name: %s", port,
|
||||
vApp.getId(), vApp.getName())));
|
||||
}
|
||||
logger.debug("<< created InternetService(%s) %s:%s:%d", is.getId(), is
|
||||
.getPublicIpAddress().getAddress(), is.getProtocol(), is.getPort());
|
||||
logger.debug(">> adding Node %s:%d -> %s:%d", is.getPublicIpAddress().getAddress(), is
|
||||
.getPort(), privateAddress, port);
|
||||
Node node = client.addNode(is.getId(), privateAddress, vApp.getName() + "-" + port, port);
|
||||
.getPublicIpAddress().getAddress(), is.getProtocol(), is
|
||||
.getPort());
|
||||
logger.debug(">> adding Node %s:%d -> %s:%d", is.getPublicIpAddress()
|
||||
.getAddress(), is.getPort(), privateAddress, port);
|
||||
Node node = client.addNode(is.getId(), privateAddress, vApp.getName()
|
||||
+ "-" + port, port);
|
||||
logger.debug("<< added Node(%s)", node.getId());
|
||||
}
|
||||
return ip != null ? ip.getAddress() : null;
|
||||
}
|
||||
|
||||
private Set<PublicIpAddress> deleteInternetServicesAndNodesAssociatedWithVApp(VApp vApp) {
|
||||
private Set<PublicIpAddress> deleteInternetServicesAndNodesAssociatedWithVApp(
|
||||
VApp vApp) {
|
||||
Set<PublicIpAddress> ipAddresses = Sets.newHashSet();
|
||||
SERVICE: for (InternetService service : client.getAllInternetServicesInVDC(vApp.getVDC()
|
||||
.getId())) {
|
||||
SERVICE: for (InternetService service : client
|
||||
.getAllInternetServicesInVDC(vApp.getVDC().getId())) {
|
||||
for (Node node : client.getNodes(service.getId())) {
|
||||
if (vApp.getNetworkToAddresses().containsValue(node.getIpAddress())) {
|
||||
ipAddresses.add(service.getPublicIpAddress());
|
||||
logger.debug(">> deleting Node(%s) %s:%d -> %s:%d", node.getId(), service
|
||||
.getPublicIpAddress().getAddress(), service.getPort(), node.getIpAddress(),
|
||||
node.getPort());
|
||||
logger.debug(">> deleting Node(%s) %s:%d -> %s:%d",
|
||||
node.getId(), service.getPublicIpAddress().getAddress(),
|
||||
service.getPort(), node.getIpAddress(), node.getPort());
|
||||
client.deleteNode(node.getId());
|
||||
logger.debug("<< deleted Node(%s)", node.getId());
|
||||
SortedSet<Node> nodes = client.getNodes(service.getId());
|
||||
if (nodes.size() == 0) {
|
||||
logger.debug(">> deleting InternetService(%s) %s:%d", service.getId(), service
|
||||
.getPublicIpAddress().getAddress(), service.getPort());
|
||||
logger.debug(">> deleting InternetService(%s) %s:%d", service
|
||||
.getId(), service.getPublicIpAddress().getAddress(),
|
||||
service.getPort());
|
||||
client.deleteInternetService(service.getId());
|
||||
logger.debug("<< deleted InternetService(%s)", service.getId());
|
||||
logger.debug("<< deleted InternetService(%s)", service
|
||||
.getId());
|
||||
continue SERVICE;
|
||||
}
|
||||
}
|
||||
|
@ -173,13 +193,14 @@ public class TerremarkVCloudComputeClient extends BaseVCloudComputeClient {
|
|||
return ipAddresses;
|
||||
}
|
||||
|
||||
private void deletePublicIpAddressesWithNoServicesAttached(Set<PublicIpAddress> ipAddresses) {
|
||||
private void deletePublicIpAddressesWithNoServicesAttached(
|
||||
Set<PublicIpAddress> ipAddresses) {
|
||||
IPADDRESS: for (PublicIpAddress address : ipAddresses) {
|
||||
SortedSet<InternetService> services = client
|
||||
.getInternetServicesOnPublicIp(address.getId());
|
||||
.getInternetServicesOnPublicIp(address.getId());
|
||||
if (services.size() == 0) {
|
||||
logger.debug(">> deleting PublicIpAddress(%s) %s", address.getId(), address
|
||||
.getAddress());
|
||||
logger.debug(">> deleting PublicIpAddress(%s) %s", address.getId(),
|
||||
address.getAddress());
|
||||
client.deletePublicIp(address.getId());
|
||||
logger.debug("<< deleted PublicIpAddress(%s)", address.getId());
|
||||
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
|
||||
* there are no others using it. Finally, it powers off and deletes the vapp. Note that we do not
|
||||
* call undeploy, as terremark does not support the command.
|
||||
* deletes the internet service and nodes associated with the vapp. Deletes
|
||||
* the IP address, if there are no others using it. Finally, it powers off
|
||||
* and deletes the vapp. Note that we do not call undeploy, as terremark does
|
||||
* not support the command.
|
||||
*/
|
||||
@Override
|
||||
public void stop(String id) {
|
||||
|
@ -198,8 +220,8 @@ public class TerremarkVCloudComputeClient extends BaseVCloudComputeClient {
|
|||
Set<PublicIpAddress> ipAddresses = deleteInternetServicesAndNodesAssociatedWithVApp(vApp);
|
||||
deletePublicIpAddressesWithNoServicesAttached(ipAddresses);
|
||||
if (vApp.getStatus() != VAppStatus.OFF) {
|
||||
logger.debug(">> powering off vApp(%s), current status: %s", vApp.getId(), vApp
|
||||
.getStatus());
|
||||
logger.debug(">> powering off vApp(%s), current status: %s", vApp
|
||||
.getId(), vApp.getStatus());
|
||||
Task task = client.powerOffVApp(vApp.getId());
|
||||
if (!taskTester.apply(task.getId())) {
|
||||
throw new TaskException("powerOff", vApp, task);
|
||||
|
@ -209,8 +231,7 @@ public class TerremarkVCloudComputeClient extends BaseVCloudComputeClient {
|
|||
}
|
||||
logger.debug(">> deleting vApp(%s)", vApp.getId());
|
||||
client.deleteVApp(id);
|
||||
boolean successful = notFoundTester.apply(vApp);
|
||||
logger.debug("<< deleted vApp(%s) completed(%s)", vApp.getId(), successful);
|
||||
logger.debug("<< deleted vApp(%s))", vApp.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -223,7 +244,8 @@ public class TerremarkVCloudComputeClient extends BaseVCloudComputeClient {
|
|||
public Set<String> getPublicAddresses(String id) {
|
||||
VApp vApp = client.getVApp(id);
|
||||
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())) {
|
||||
if (vApp.getNetworkToAddresses().containsValue(node.getIpAddress())) {
|
||||
ipAddresses.add(service.getPublicIpAddress().getAddress());
|
||||
|
|
|
@ -51,7 +51,8 @@ public class TerremarkVCloudComputeClientTest {
|
|||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
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));
|
||||
VAppTemplate template = createMock(VAppTemplate.class);
|
||||
expect(template.getDescription()).andReturn(description).atLeastOnce();
|
||||
|
@ -60,9 +61,10 @@ public class TerremarkVCloudComputeClientTest {
|
|||
VApp vApp = createMock(VApp.class);
|
||||
|
||||
expect(
|
||||
client.instantiateVAppTemplateInVDC("vDCId", "name", "templateId",
|
||||
new TerremarkInstantiateVAppTemplateOptions().productProperty("password",
|
||||
"password"))).andReturn(vApp);
|
||||
client.instantiateVAppTemplateInVDC("vDCId", "name", "templateId",
|
||||
new TerremarkInstantiateVAppTemplateOptions()
|
||||
.productProperty("password", "password"))).andReturn(
|
||||
vApp);
|
||||
Task task = createMock(Task.class);
|
||||
|
||||
expect(vApp.getId()).andReturn("1").atLeastOnce();
|
||||
|
@ -76,16 +78,17 @@ public class TerremarkVCloudComputeClientTest {
|
|||
Predicate<VApp> notFoundTester = createMock(Predicate.class);
|
||||
Map<VAppStatus, NodeState> vAppStatusToNodeState = createMock(Map.class);
|
||||
|
||||
TerremarkVCloudComputeClient computeClient = new TerremarkVCloudComputeClient(client,
|
||||
new ParseVAppTemplateDescriptionToGetDefaultLoginCredentials(),
|
||||
new Provider<String>() {
|
||||
TerremarkVCloudComputeClient computeClient = new TerremarkVCloudComputeClient(
|
||||
client,
|
||||
new ParseVAppTemplateDescriptionToGetDefaultLoginCredentials(),
|
||||
new Provider<String>() {
|
||||
|
||||
@Override
|
||||
public String get() {
|
||||
return "password";
|
||||
}
|
||||
@Override
|
||||
public String get() {
|
||||
return "password";
|
||||
}
|
||||
|
||||
}, successTester, notFoundTester, vAppStatusToNodeState);
|
||||
}, successTester, vAppStatusToNodeState);
|
||||
|
||||
replay(template);
|
||||
replay(vApp);
|
||||
|
@ -95,8 +98,8 @@ public class TerremarkVCloudComputeClientTest {
|
|||
replay(notFoundTester);
|
||||
replay(vAppStatusToNodeState);
|
||||
|
||||
Map<String, String> response = computeClient.start("vDCId", "name", "templateId",
|
||||
new TerremarkInstantiateVAppTemplateOptions());
|
||||
Map<String, String> response = computeClient.start("vDCId", "name",
|
||||
"templateId", new TerremarkInstantiateVAppTemplateOptions());
|
||||
|
||||
assertEquals(response.get("id"), "1");
|
||||
assertEquals(response.get("username"), "Administrator");
|
||||
|
|
Loading…
Reference in New Issue