mirror of https://github.com/apache/jclouds.git
refactored runScript logic
This commit is contained in:
parent
c34b973af3
commit
0455e0f509
|
@ -28,6 +28,7 @@ import java.util.Set;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Named;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import org.jclouds.collect.Memoized;
|
import org.jclouds.collect.Memoized;
|
||||||
|
@ -37,6 +38,7 @@ import org.jclouds.compute.domain.NodeMetadata;
|
||||||
import org.jclouds.compute.domain.NodeMetadataBuilder;
|
import org.jclouds.compute.domain.NodeMetadataBuilder;
|
||||||
import org.jclouds.compute.domain.NodeState;
|
import org.jclouds.compute.domain.NodeState;
|
||||||
import org.jclouds.compute.domain.OperatingSystem;
|
import org.jclouds.compute.domain.OperatingSystem;
|
||||||
|
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||||
import org.jclouds.domain.Credentials;
|
import org.jclouds.domain.Credentials;
|
||||||
import org.jclouds.domain.Location;
|
import org.jclouds.domain.Location;
|
||||||
import org.jclouds.domain.LocationScope;
|
import org.jclouds.domain.LocationScope;
|
||||||
|
@ -55,15 +57,16 @@ import com.google.common.collect.Iterables;
|
||||||
*/
|
*/
|
||||||
@Singleton
|
@Singleton
|
||||||
public class ServerToNodeMetadata implements Function<Server, NodeMetadata> {
|
public class ServerToNodeMetadata implements Function<Server, NodeMetadata> {
|
||||||
|
@Resource
|
||||||
|
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||||
|
protected Logger logger = Logger.NULL;
|
||||||
|
|
||||||
protected final Supplier<Location> location;
|
protected final Supplier<Location> location;
|
||||||
protected final Map<String, Credentials> credentialStore;
|
protected final Map<String, Credentials> credentialStore;
|
||||||
protected final Map<ServerStatus, NodeState> serverToNodeState;
|
protected final Map<ServerStatus, NodeState> serverToNodeState;
|
||||||
protected final Supplier<Set<? extends Image>> images;
|
protected final Supplier<Set<? extends Image>> images;
|
||||||
protected final Supplier<Set<? extends Hardware>> hardwares;
|
protected final Supplier<Set<? extends Hardware>> hardwares;
|
||||||
|
|
||||||
@Resource
|
|
||||||
protected Logger logger = Logger.NULL;
|
|
||||||
|
|
||||||
private static class FindImageForServer implements Predicate<Image> {
|
private static class FindImageForServer implements Predicate<Image> {
|
||||||
private final Server instance;
|
private final Server instance;
|
||||||
|
|
||||||
|
|
|
@ -22,8 +22,8 @@ package org.jclouds.ec2.compute;
|
||||||
import static com.google.common.base.Preconditions.checkState;
|
import static com.google.common.base.Preconditions.checkState;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.Map.Entry;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
@ -49,8 +49,8 @@ import org.jclouds.compute.strategy.ListNodesStrategy;
|
||||||
import org.jclouds.compute.strategy.RebootNodeStrategy;
|
import org.jclouds.compute.strategy.RebootNodeStrategy;
|
||||||
import org.jclouds.compute.strategy.ResumeNodeStrategy;
|
import org.jclouds.compute.strategy.ResumeNodeStrategy;
|
||||||
import org.jclouds.compute.strategy.RunNodesAndAddToSetStrategy;
|
import org.jclouds.compute.strategy.RunNodesAndAddToSetStrategy;
|
||||||
|
import org.jclouds.compute.strategy.RunStatementOnNodeAndAddToGoodMapOrPutExceptionIntoBadMap;
|
||||||
import org.jclouds.compute.strategy.SuspendNodeStrategy;
|
import org.jclouds.compute.strategy.SuspendNodeStrategy;
|
||||||
import org.jclouds.compute.util.ComputeUtils;
|
|
||||||
import org.jclouds.domain.Credentials;
|
import org.jclouds.domain.Credentials;
|
||||||
import org.jclouds.domain.Location;
|
import org.jclouds.domain.Location;
|
||||||
import org.jclouds.ec2.EC2Client;
|
import org.jclouds.ec2.EC2Client;
|
||||||
|
@ -89,15 +89,16 @@ public class EC2ComputeService extends BaseComputeService {
|
||||||
Provider<TemplateBuilder> templateBuilderProvider, Provider<TemplateOptions> templateOptionsProvider,
|
Provider<TemplateBuilder> templateBuilderProvider, Provider<TemplateOptions> templateOptionsProvider,
|
||||||
@Named("NODE_RUNNING") Predicate<NodeMetadata> nodeRunning,
|
@Named("NODE_RUNNING") Predicate<NodeMetadata> nodeRunning,
|
||||||
@Named("NODE_TERMINATED") Predicate<NodeMetadata> nodeTerminated,
|
@Named("NODE_TERMINATED") Predicate<NodeMetadata> nodeTerminated,
|
||||||
@Named("NODE_SUSPENDED") Predicate<NodeMetadata> nodeSuspended, ComputeUtils utils, Timeouts timeouts,
|
@Named("NODE_SUSPENDED") Predicate<NodeMetadata> nodeSuspended,
|
||||||
|
RunStatementOnNodeAndAddToGoodMapOrPutExceptionIntoBadMap.Factory statementRunner, Timeouts timeouts,
|
||||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor, EC2Client ec2Client,
|
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor, EC2Client ec2Client,
|
||||||
Map<RegionAndName, KeyPair> credentialsMap, @Named("SECURITY") Map<RegionAndName, String> securityGroupMap,
|
Map<RegionAndName, KeyPair> credentialsMap, @Named("SECURITY") Map<RegionAndName, String> securityGroupMap,
|
||||||
@Named("PLACEMENT") Map<RegionAndName, String> placementGroupMap,
|
@Named("PLACEMENT") Map<RegionAndName, String> placementGroupMap,
|
||||||
@Named("DELETED") Predicate<PlacementGroup> placementGroupDeleted) {
|
@Named("DELETED") Predicate<PlacementGroup> placementGroupDeleted) {
|
||||||
super(context, credentialStore, images, sizes, locations, listNodesStrategy, getNodeMetadataStrategy,
|
super(context, credentialStore, images, sizes, locations, listNodesStrategy, getNodeMetadataStrategy,
|
||||||
runNodesAndAddToSetStrategy, rebootNodeStrategy, destroyNodeStrategy, startNodeStrategy, stopNodeStrategy,
|
runNodesAndAddToSetStrategy, rebootNodeStrategy, destroyNodeStrategy, startNodeStrategy,
|
||||||
templateBuilderProvider, templateOptionsProvider, nodeRunning, nodeTerminated, nodeSuspended, utils,
|
stopNodeStrategy, templateBuilderProvider, templateOptionsProvider, nodeRunning, nodeTerminated,
|
||||||
timeouts, executor);
|
nodeSuspended, statementRunner, timeouts, executor);
|
||||||
this.ec2Client = ec2Client;
|
this.ec2Client = ec2Client;
|
||||||
this.credentialsMap = credentialsMap;
|
this.credentialsMap = credentialsMap;
|
||||||
this.securityGroupMap = securityGroupMap;
|
this.securityGroupMap = securityGroupMap;
|
||||||
|
@ -129,8 +130,8 @@ public class EC2ComputeService extends BaseComputeService {
|
||||||
} catch (UnsupportedOperationException e) {
|
} catch (UnsupportedOperationException e) {
|
||||||
} catch (HttpResponseException e) {
|
} catch (HttpResponseException e) {
|
||||||
// Eucalyptus does not support placement groups yet.
|
// Eucalyptus does not support placement groups yet.
|
||||||
if (!(e.getResponse().getStatusCode() == 400 && context.getProviderSpecificContext().getProvider()
|
if (!(e.getResponse().getStatusCode() == 400 && context.getProviderSpecificContext().getProvider().equals(
|
||||||
.equals("eucalyptus")))
|
"eucalyptus")))
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,7 @@ import javax.inject.Named;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import org.jclouds.aws.util.AWSUtils;
|
import org.jclouds.aws.util.AWSUtils;
|
||||||
|
import org.jclouds.compute.config.CustomizationResponse;
|
||||||
import org.jclouds.compute.domain.NodeMetadata;
|
import org.jclouds.compute.domain.NodeMetadata;
|
||||||
import org.jclouds.compute.domain.Template;
|
import org.jclouds.compute.domain.Template;
|
||||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||||
|
@ -52,6 +53,7 @@ import com.google.common.base.Function;
|
||||||
import com.google.common.base.Joiner;
|
import com.google.common.base.Joiner;
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
|
import com.google.common.collect.Multimap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* creates futures that correlate to
|
* creates futures that correlate to
|
||||||
|
@ -68,7 +70,7 @@ public class EC2RunNodesAndAddToSetStrategy implements RunNodesAndAddToSetStrate
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
final EC2Client client;
|
final EC2Client client;
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
final CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions createKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions;
|
final CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions createKeyPairAndSecurityGroupsAsNeededAndReturncustomize;
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
final Function<RunningInstance, NodeMetadata> runningInstanceToNodeMetadata;
|
final Function<RunningInstance, NodeMetadata> runningInstanceToNodeMetadata;
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
|
@ -80,14 +82,14 @@ public class EC2RunNodesAndAddToSetStrategy implements RunNodesAndAddToSetStrate
|
||||||
@Inject
|
@Inject
|
||||||
EC2RunNodesAndAddToSetStrategy(
|
EC2RunNodesAndAddToSetStrategy(
|
||||||
EC2Client client,
|
EC2Client client,
|
||||||
CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions createKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions,
|
CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions createKeyPairAndSecurityGroupsAsNeededAndReturncustomize,
|
||||||
@Named("PRESENT") Predicate<RunningInstance> instancePresent,
|
@Named("PRESENT") Predicate<RunningInstance> instancePresent,
|
||||||
Function<RunningInstance, NodeMetadata> runningInstanceToNodeMetadata,
|
Function<RunningInstance, NodeMetadata> runningInstanceToNodeMetadata,
|
||||||
Function<RunningInstance, Credentials> instanceToCredentials, Map<String, Credentials> credentialStore,
|
Function<RunningInstance, Credentials> instanceToCredentials, Map<String, Credentials> credentialStore,
|
||||||
ComputeUtils utils) {
|
ComputeUtils utils) {
|
||||||
this.client = client;
|
this.client = client;
|
||||||
this.instancePresent = instancePresent;
|
this.instancePresent = instancePresent;
|
||||||
this.createKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions = createKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions;
|
this.createKeyPairAndSecurityGroupsAsNeededAndReturncustomize = createKeyPairAndSecurityGroupsAsNeededAndReturncustomize;
|
||||||
this.runningInstanceToNodeMetadata = runningInstanceToNodeMetadata;
|
this.runningInstanceToNodeMetadata = runningInstanceToNodeMetadata;
|
||||||
this.instanceToCredentials = instanceToCredentials;
|
this.instanceToCredentials = instanceToCredentials;
|
||||||
this.credentialStore = credentialStore;
|
this.credentialStore = credentialStore;
|
||||||
|
@ -96,7 +98,7 @@ public class EC2RunNodesAndAddToSetStrategy implements RunNodesAndAddToSetStrate
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<?, Future<Void>> execute(String tag, int count, Template template, Set<NodeMetadata> goodNodes,
|
public Map<?, Future<Void>> execute(String tag, int count, Template template, Set<NodeMetadata> goodNodes,
|
||||||
Map<NodeMetadata, Exception> badNodes) {
|
Map<NodeMetadata, Exception> badNodes, Multimap<NodeMetadata, CustomizationResponse> customizationResponses) {
|
||||||
|
|
||||||
Reservation<? extends RunningInstance> reservation = createKeyPairAndSecurityGroupsAsNeededThenRunInstances(tag,
|
Reservation<? extends RunningInstance> reservation = createKeyPairAndSecurityGroupsAsNeededThenRunInstances(tag,
|
||||||
count, template);
|
count, template);
|
||||||
|
@ -111,8 +113,8 @@ public class EC2RunNodesAndAddToSetStrategy implements RunNodesAndAddToSetStrate
|
||||||
populateCredentials(reservation);
|
populateCredentials(reservation);
|
||||||
}
|
}
|
||||||
|
|
||||||
return utils.runOptionsOnNodesAndAddToGoodSetOrPutExceptionIntoBadMap(template.getOptions(), transform(
|
return utils.customizeNodesAndAddToGoodMapOrPutExceptionIntoBadMap(template.getOptions(), transform(reservation,
|
||||||
reservation, runningInstanceToNodeMetadata), goodNodes, badNodes);
|
runningInstanceToNodeMetadata), goodNodes, badNodes, customizationResponses);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void populateCredentials(Reservation<? extends RunningInstance> reservation) {
|
protected void populateCredentials(Reservation<? extends RunningInstance> reservation) {
|
||||||
|
@ -129,7 +131,7 @@ public class EC2RunNodesAndAddToSetStrategy implements RunNodesAndAddToSetStrate
|
||||||
String region = AWSUtils.getRegionFromLocationOrNull(template.getLocation());
|
String region = AWSUtils.getRegionFromLocationOrNull(template.getLocation());
|
||||||
String zone = getZoneFromLocationOrNull(template.getLocation());
|
String zone = getZoneFromLocationOrNull(template.getLocation());
|
||||||
|
|
||||||
RunInstancesOptions instanceOptions = createKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.execute(region,
|
RunInstancesOptions instanceOptions = createKeyPairAndSecurityGroupsAsNeededAndReturncustomize.execute(region,
|
||||||
tag, template);
|
tag, template);
|
||||||
|
|
||||||
if (EC2TemplateOptions.class.cast(template.getOptions()).isMonitoringEnabled())
|
if (EC2TemplateOptions.class.cast(template.getOptions()).isMonitoringEnabled())
|
||||||
|
|
|
@ -29,8 +29,6 @@ import java.util.concurrent.ExecutorService;
|
||||||
|
|
||||||
import javax.inject.Provider;
|
import javax.inject.Provider;
|
||||||
|
|
||||||
import org.jclouds.ec2.EC2Client;
|
|
||||||
import org.jclouds.ec2.services.PlacementGroupClient;
|
|
||||||
import org.jclouds.compute.ComputeServiceContext;
|
import org.jclouds.compute.ComputeServiceContext;
|
||||||
import org.jclouds.compute.reference.ComputeServiceConstants.Timeouts;
|
import org.jclouds.compute.reference.ComputeServiceConstants.Timeouts;
|
||||||
import org.jclouds.compute.strategy.DestroyNodeStrategy;
|
import org.jclouds.compute.strategy.DestroyNodeStrategy;
|
||||||
|
@ -39,8 +37,10 @@ import org.jclouds.compute.strategy.ListNodesStrategy;
|
||||||
import org.jclouds.compute.strategy.RebootNodeStrategy;
|
import org.jclouds.compute.strategy.RebootNodeStrategy;
|
||||||
import org.jclouds.compute.strategy.ResumeNodeStrategy;
|
import org.jclouds.compute.strategy.ResumeNodeStrategy;
|
||||||
import org.jclouds.compute.strategy.RunNodesAndAddToSetStrategy;
|
import org.jclouds.compute.strategy.RunNodesAndAddToSetStrategy;
|
||||||
|
import org.jclouds.compute.strategy.RunStatementOnNodeAndAddToGoodMapOrPutExceptionIntoBadMap;
|
||||||
import org.jclouds.compute.strategy.SuspendNodeStrategy;
|
import org.jclouds.compute.strategy.SuspendNodeStrategy;
|
||||||
import org.jclouds.compute.util.ComputeUtils;
|
import org.jclouds.ec2.EC2Client;
|
||||||
|
import org.jclouds.ec2.services.PlacementGroupClient;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
|
@ -62,8 +62,9 @@ public class EC2ComputeServiceTest {
|
||||||
createMock(DestroyNodeStrategy.class), createMock(ResumeNodeStrategy.class),
|
createMock(DestroyNodeStrategy.class), createMock(ResumeNodeStrategy.class),
|
||||||
createMock(SuspendNodeStrategy.class), createMock(Provider.class), createMock(Provider.class),
|
createMock(SuspendNodeStrategy.class), createMock(Provider.class), createMock(Provider.class),
|
||||||
createMock(Predicate.class), createMock(Predicate.class), createMock(Predicate.class),
|
createMock(Predicate.class), createMock(Predicate.class), createMock(Predicate.class),
|
||||||
createMock(ComputeUtils.class), createMock(Timeouts.class), createMock(ExecutorService.class), client,
|
createMock(RunStatementOnNodeAndAddToGoodMapOrPutExceptionIntoBadMap.Factory.class),
|
||||||
createMock(Map.class), createMock(Map.class), createMock(Map.class), createMock(Predicate.class));
|
createMock(Timeouts.class), createMock(ExecutorService.class), client, createMock(Map.class),
|
||||||
|
createMock(Map.class), createMock(Map.class), createMock(Predicate.class));
|
||||||
|
|
||||||
PlacementGroupClient placementClient = createMock(PlacementGroupClient.class);
|
PlacementGroupClient placementClient = createMock(PlacementGroupClient.class);
|
||||||
|
|
||||||
|
|
|
@ -100,15 +100,15 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
|
||||||
replay(strategy);
|
replay(strategy);
|
||||||
|
|
||||||
// run
|
// run
|
||||||
RunInstancesOptions runOptions = strategy.execute(region, tag, template);
|
RunInstancesOptions customize = strategy.execute(region, tag, template);
|
||||||
assertEquals(runOptions.buildQueryParameters(), ImmutableMultimap.<String, String> of());
|
assertEquals(customize.buildQueryParameters(), ImmutableMultimap.<String, String> of());
|
||||||
assertEquals(
|
assertEquals(
|
||||||
runOptions.buildFormParameters().entries(),
|
customize.buildFormParameters().entries(),
|
||||||
ImmutableMultimap.<String, String> of("InstanceType", size.getProviderId(), "SecurityGroup.1",
|
ImmutableMultimap.<String, String> of("InstanceType", size.getProviderId(), "SecurityGroup.1",
|
||||||
generatedGroup, "KeyName", systemGeneratedKeyPairName).entries());
|
generatedGroup, "KeyName", systemGeneratedKeyPairName).entries());
|
||||||
assertEquals(runOptions.buildMatrixParameters(), ImmutableMultimap.<String, String> of());
|
assertEquals(customize.buildMatrixParameters(), ImmutableMultimap.<String, String> of());
|
||||||
assertEquals(runOptions.buildRequestHeaders(), ImmutableMultimap.<String, String> of());
|
assertEquals(customize.buildRequestHeaders(), ImmutableMultimap.<String, String> of());
|
||||||
assertEquals(runOptions.buildStringPayload(), null);
|
assertEquals(customize.buildStringPayload(), null);
|
||||||
|
|
||||||
// verify mocks
|
// verify mocks
|
||||||
verify(options);
|
verify(options);
|
||||||
|
@ -159,16 +159,16 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
|
||||||
replay(strategy);
|
replay(strategy);
|
||||||
|
|
||||||
// run
|
// run
|
||||||
RunInstancesOptions runOptions = strategy.execute(region, tag, template);
|
RunInstancesOptions customize = strategy.execute(region, tag, template);
|
||||||
assertEquals(runOptions.buildQueryParameters(), ImmutableMultimap.<String, String> of());
|
assertEquals(customize.buildQueryParameters(), ImmutableMultimap.<String, String> of());
|
||||||
assertEquals(
|
assertEquals(
|
||||||
runOptions.buildFormParameters().entries(),
|
customize.buildFormParameters().entries(),
|
||||||
ImmutableMultimap.<String, String> of("InstanceType", size.getProviderId(), "SecurityGroup.1",
|
ImmutableMultimap.<String, String> of("InstanceType", size.getProviderId(), "SecurityGroup.1",
|
||||||
generatedGroup, "KeyName", systemGeneratedKeyPairName, "Placement.GroupName", generatedGroup)
|
generatedGroup, "KeyName", systemGeneratedKeyPairName, "Placement.GroupName", generatedGroup)
|
||||||
.entries());
|
.entries());
|
||||||
assertEquals(runOptions.buildMatrixParameters(), ImmutableMultimap.<String, String> of());
|
assertEquals(customize.buildMatrixParameters(), ImmutableMultimap.<String, String> of());
|
||||||
assertEquals(runOptions.buildRequestHeaders(), ImmutableMultimap.<String, String> of());
|
assertEquals(customize.buildRequestHeaders(), ImmutableMultimap.<String, String> of());
|
||||||
assertEquals(runOptions.buildStringPayload(), null);
|
assertEquals(customize.buildStringPayload(), null);
|
||||||
|
|
||||||
// verify mocks
|
// verify mocks
|
||||||
verify(options);
|
verify(options);
|
||||||
|
@ -219,16 +219,16 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
|
||||||
replay(strategy);
|
replay(strategy);
|
||||||
|
|
||||||
// run
|
// run
|
||||||
RunInstancesOptions runOptions = strategy.execute(region, tag, template);
|
RunInstancesOptions customize = strategy.execute(region, tag, template);
|
||||||
assertEquals(runOptions.buildQueryParameters(), ImmutableMultimap.<String, String> of());
|
assertEquals(customize.buildQueryParameters(), ImmutableMultimap.<String, String> of());
|
||||||
assertEquals(
|
assertEquals(
|
||||||
runOptions.buildFormParameters().entries(),
|
customize.buildFormParameters().entries(),
|
||||||
ImmutableMultimap.<String, String> of("InstanceType", size.getProviderId(), "SecurityGroup.1",
|
ImmutableMultimap.<String, String> of("InstanceType", size.getProviderId(), "SecurityGroup.1",
|
||||||
generatedGroup, "KeyName", systemGeneratedKeyPairName, "Placement.GroupName", generatedGroup)
|
generatedGroup, "KeyName", systemGeneratedKeyPairName, "Placement.GroupName", generatedGroup)
|
||||||
.entries());
|
.entries());
|
||||||
assertEquals(runOptions.buildMatrixParameters(), ImmutableMultimap.<String, String> of());
|
assertEquals(customize.buildMatrixParameters(), ImmutableMultimap.<String, String> of());
|
||||||
assertEquals(runOptions.buildRequestHeaders(), ImmutableMultimap.<String, String> of());
|
assertEquals(customize.buildRequestHeaders(), ImmutableMultimap.<String, String> of());
|
||||||
assertEquals(runOptions.buildStringPayload(), null);
|
assertEquals(customize.buildStringPayload(), null);
|
||||||
|
|
||||||
// verify mocks
|
// verify mocks
|
||||||
verify(options);
|
verify(options);
|
||||||
|
@ -274,15 +274,15 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
|
||||||
replay(strategy);
|
replay(strategy);
|
||||||
|
|
||||||
// run
|
// run
|
||||||
RunInstancesOptions runOptions = strategy.execute(region, tag, template);
|
RunInstancesOptions customize = strategy.execute(region, tag, template);
|
||||||
assertEquals(runOptions.buildQueryParameters(), ImmutableMultimap.<String, String> of());
|
assertEquals(customize.buildQueryParameters(), ImmutableMultimap.<String, String> of());
|
||||||
assertEquals(
|
assertEquals(
|
||||||
runOptions.buildFormParameters().entries(),
|
customize.buildFormParameters().entries(),
|
||||||
ImmutableMultimap.<String, String> of("InstanceType", size.getProviderId(), "SubnetId", "1", "KeyName",
|
ImmutableMultimap.<String, String> of("InstanceType", size.getProviderId(), "SubnetId", "1", "KeyName",
|
||||||
systemGeneratedKeyPairName).entries());
|
systemGeneratedKeyPairName).entries());
|
||||||
assertEquals(runOptions.buildMatrixParameters(), ImmutableMultimap.<String, String> of());
|
assertEquals(customize.buildMatrixParameters(), ImmutableMultimap.<String, String> of());
|
||||||
assertEquals(runOptions.buildRequestHeaders(), ImmutableMultimap.<String, String> of());
|
assertEquals(customize.buildRequestHeaders(), ImmutableMultimap.<String, String> of());
|
||||||
assertEquals(runOptions.buildStringPayload(), null);
|
assertEquals(customize.buildStringPayload(), null);
|
||||||
|
|
||||||
// verify mocks
|
// verify mocks
|
||||||
verify(options);
|
verify(options);
|
||||||
|
@ -331,15 +331,15 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT
|
||||||
replay(strategy);
|
replay(strategy);
|
||||||
|
|
||||||
// run
|
// run
|
||||||
RunInstancesOptions runOptions = strategy.execute(region, tag, template);
|
RunInstancesOptions customize = strategy.execute(region, tag, template);
|
||||||
assertEquals(runOptions.buildQueryParameters(), ImmutableMultimap.<String, String> of());
|
assertEquals(customize.buildQueryParameters(), ImmutableMultimap.<String, String> of());
|
||||||
assertEquals(
|
assertEquals(
|
||||||
runOptions.buildFormParameters().entries(),
|
customize.buildFormParameters().entries(),
|
||||||
ImmutableMultimap.<String, String> of("InstanceType", size.getProviderId(), "SecurityGroup.1", "group",
|
ImmutableMultimap.<String, String> of("InstanceType", size.getProviderId(), "SecurityGroup.1", "group",
|
||||||
"KeyName", systemGeneratedKeyPairName, "UserData", Base64.encodeBytes("hello".getBytes())).entries());
|
"KeyName", systemGeneratedKeyPairName, "UserData", Base64.encodeBytes("hello".getBytes())).entries());
|
||||||
assertEquals(runOptions.buildMatrixParameters(), ImmutableMultimap.<String, String> of());
|
assertEquals(customize.buildMatrixParameters(), ImmutableMultimap.<String, String> of());
|
||||||
assertEquals(runOptions.buildRequestHeaders(), ImmutableMultimap.<String, String> of());
|
assertEquals(customize.buildRequestHeaders(), ImmutableMultimap.<String, String> of());
|
||||||
assertEquals(runOptions.buildStringPayload(), null);
|
assertEquals(customize.buildStringPayload(), null);
|
||||||
|
|
||||||
// verify mocks
|
// verify mocks
|
||||||
verify(options);
|
verify(options);
|
||||||
|
|
|
@ -31,6 +31,7 @@ import java.util.Set;
|
||||||
|
|
||||||
import org.easymock.IArgumentMatcher;
|
import org.easymock.IArgumentMatcher;
|
||||||
import org.jclouds.aws.domain.Region;
|
import org.jclouds.aws.domain.Region;
|
||||||
|
import org.jclouds.compute.config.CustomizationResponse;
|
||||||
import org.jclouds.compute.domain.Hardware;
|
import org.jclouds.compute.domain.Hardware;
|
||||||
import org.jclouds.compute.domain.Image;
|
import org.jclouds.compute.domain.Image;
|
||||||
import org.jclouds.compute.domain.NodeMetadata;
|
import org.jclouds.compute.domain.NodeMetadata;
|
||||||
|
@ -54,6 +55,7 @@ import com.google.common.base.Function;
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
|
import com.google.common.collect.Multimap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
|
@ -102,15 +104,14 @@ public class EC2RunNodesAndAddToSetStrategyTest {
|
||||||
InstanceClient instanceClient = createMock(InstanceClient.class);
|
InstanceClient instanceClient = createMock(InstanceClient.class);
|
||||||
RunInstancesOptions ec2Options = createMock(RunInstancesOptions.class);
|
RunInstancesOptions ec2Options = createMock(RunInstancesOptions.class);
|
||||||
RunningInstance instance = createMock(RunningInstance.class);
|
RunningInstance instance = createMock(RunningInstance.class);
|
||||||
Reservation<? extends RunningInstance> reservation = new Reservation<RunningInstance>(region,
|
Reservation<? extends RunningInstance> reservation = new Reservation<RunningInstance>(region, ImmutableSet
|
||||||
ImmutableSet.<String> of(), ImmutableSet.<RunningInstance> of(instance), "ownerId", "requesterId",
|
.<String> of(), ImmutableSet.<RunningInstance> of(instance), "ownerId", "requesterId", "reservationId");
|
||||||
"reservationId");
|
|
||||||
NodeMetadata nodeMetadata = createMock(NodeMetadata.class);
|
NodeMetadata nodeMetadata = createMock(NodeMetadata.class);
|
||||||
|
|
||||||
// setup expectations
|
// setup expectations
|
||||||
expect(strategy.client.getInstanceServices()).andReturn(instanceClient).atLeastOnce();
|
expect(strategy.client.getInstanceServices()).andReturn(instanceClient).atLeastOnce();
|
||||||
expect(
|
expect(
|
||||||
strategy.createKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.execute(region, input.tag,
|
strategy.createKeyPairAndSecurityGroupsAsNeededAndReturncustomize.execute(region, input.tag,
|
||||||
input.template)).andReturn(ec2Options);
|
input.template)).andReturn(ec2Options);
|
||||||
expect(input.template.getLocation()).andReturn(input.location).atLeastOnce();
|
expect(input.template.getLocation()).andReturn(input.location).atLeastOnce();
|
||||||
expect(input.template.getImage()).andReturn(input.image).atLeastOnce();
|
expect(input.template.getImage()).andReturn(input.image).atLeastOnce();
|
||||||
|
@ -130,8 +131,9 @@ public class EC2RunNodesAndAddToSetStrategyTest {
|
||||||
|
|
||||||
expect(strategy.runningInstanceToNodeMetadata.apply(instance)).andReturn(nodeMetadata);
|
expect(strategy.runningInstanceToNodeMetadata.apply(instance)).andReturn(nodeMetadata);
|
||||||
expect(
|
expect(
|
||||||
strategy.utils.runOptionsOnNodesAndAddToGoodSetOrPutExceptionIntoBadMap(eq(input.options),
|
strategy.utils.customizeNodesAndAddToGoodMapOrPutExceptionIntoBadMap(eq(input.options),
|
||||||
containsNodeMetadata(nodeMetadata), eq(input.nodes), eq(input.badNodes))).andReturn(null);
|
containsNodeMetadata(nodeMetadata), eq(input.nodes), eq(input.badNodes),
|
||||||
|
eq(input.customization))).andReturn(null);
|
||||||
|
|
||||||
// replay mocks
|
// replay mocks
|
||||||
replay(instanceClient);
|
replay(instanceClient);
|
||||||
|
@ -142,7 +144,7 @@ public class EC2RunNodesAndAddToSetStrategyTest {
|
||||||
replayStrategy(strategy);
|
replayStrategy(strategy);
|
||||||
|
|
||||||
// run
|
// run
|
||||||
strategy.execute(input.tag, input.count, input.template, input.nodes, input.badNodes);
|
strategy.execute(input.tag, input.count, input.template, input.nodes, input.badNodes, input.customization);
|
||||||
|
|
||||||
// verify mocks
|
// verify mocks
|
||||||
verify(instanceClient);
|
verify(instanceClient);
|
||||||
|
@ -166,6 +168,7 @@ public class EC2RunNodesAndAddToSetStrategyTest {
|
||||||
Template template = createMock(Template.class);
|
Template template = createMock(Template.class);
|
||||||
Set<NodeMetadata> nodes = createMock(Set.class);
|
Set<NodeMetadata> nodes = createMock(Set.class);
|
||||||
Map<NodeMetadata, Exception> badNodes = createMock(Map.class);
|
Map<NodeMetadata, Exception> badNodes = createMock(Map.class);
|
||||||
|
Multimap<NodeMetadata, CustomizationResponse> customization = createMock(Multimap.class);
|
||||||
Hardware hardware = createMock(Hardware.class);
|
Hardware hardware = createMock(Hardware.class);
|
||||||
Image image = createMock(Image.class);
|
Image image = createMock(Image.class);
|
||||||
final Location location;
|
final Location location;
|
||||||
|
@ -181,6 +184,7 @@ public class EC2RunNodesAndAddToSetStrategyTest {
|
||||||
replay(image);
|
replay(image);
|
||||||
replay(nodes);
|
replay(nodes);
|
||||||
replay(badNodes);
|
replay(badNodes);
|
||||||
|
replay(customization);
|
||||||
replay(options);
|
replay(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,12 +194,13 @@ public class EC2RunNodesAndAddToSetStrategyTest {
|
||||||
verify(image);
|
verify(image);
|
||||||
verify(nodes);
|
verify(nodes);
|
||||||
verify(badNodes);
|
verify(badNodes);
|
||||||
|
verify(customization);
|
||||||
verify(options);
|
verify(options);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void verifyStrategy(EC2RunNodesAndAddToSetStrategy strategy) {
|
private void verifyStrategy(EC2RunNodesAndAddToSetStrategy strategy) {
|
||||||
verify(strategy.createKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions);
|
verify(strategy.createKeyPairAndSecurityGroupsAsNeededAndReturncustomize);
|
||||||
verify(strategy.client);
|
verify(strategy.client);
|
||||||
verify(strategy.instancePresent);
|
verify(strategy.instancePresent);
|
||||||
verify(strategy.runningInstanceToNodeMetadata);
|
verify(strategy.runningInstanceToNodeMetadata);
|
||||||
|
@ -207,18 +212,18 @@ public class EC2RunNodesAndAddToSetStrategyTest {
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private EC2RunNodesAndAddToSetStrategy setupStrategy() {
|
private EC2RunNodesAndAddToSetStrategy setupStrategy() {
|
||||||
EC2Client client = createMock(EC2Client.class);
|
EC2Client client = createMock(EC2Client.class);
|
||||||
CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions createKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions = createMock(CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class);
|
CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions createKeyPairAndSecurityGroupsAsNeededAndReturncustomize = createMock(CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class);
|
||||||
Predicate<RunningInstance> instanceStateRunning = createMock(Predicate.class);
|
Predicate<RunningInstance> instanceStateRunning = createMock(Predicate.class);
|
||||||
RunningInstanceToNodeMetadata runningInstanceToNodeMetadata = createMock(RunningInstanceToNodeMetadata.class);
|
RunningInstanceToNodeMetadata runningInstanceToNodeMetadata = createMock(RunningInstanceToNodeMetadata.class);
|
||||||
Function<RunningInstance, Credentials> instanceToCredentials = createMock(Function.class);
|
Function<RunningInstance, Credentials> instanceToCredentials = createMock(Function.class);
|
||||||
Map<String, Credentials> credentialStore = createMock(Map.class);
|
Map<String, Credentials> credentialStore = createMock(Map.class);
|
||||||
ComputeUtils utils = createMock(ComputeUtils.class);
|
ComputeUtils utils = createMock(ComputeUtils.class);
|
||||||
return new EC2RunNodesAndAddToSetStrategy(client, createKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions,
|
return new EC2RunNodesAndAddToSetStrategy(client, createKeyPairAndSecurityGroupsAsNeededAndReturncustomize,
|
||||||
instanceStateRunning, runningInstanceToNodeMetadata, instanceToCredentials, credentialStore, utils);
|
instanceStateRunning, runningInstanceToNodeMetadata, instanceToCredentials, credentialStore, utils);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void replayStrategy(EC2RunNodesAndAddToSetStrategy strategy) {
|
private void replayStrategy(EC2RunNodesAndAddToSetStrategy strategy) {
|
||||||
replay(strategy.createKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions);
|
replay(strategy.createKeyPairAndSecurityGroupsAsNeededAndReturncustomize);
|
||||||
replay(strategy.client);
|
replay(strategy.client);
|
||||||
replay(strategy.instancePresent);
|
replay(strategy.instancePresent);
|
||||||
replay(strategy.runningInstanceToNodeMetadata);
|
replay(strategy.runningInstanceToNodeMetadata);
|
||||||
|
|
|
@ -45,8 +45,8 @@ import org.jclouds.compute.strategy.ListNodesStrategy;
|
||||||
import org.jclouds.compute.strategy.RebootNodeStrategy;
|
import org.jclouds.compute.strategy.RebootNodeStrategy;
|
||||||
import org.jclouds.compute.strategy.ResumeNodeStrategy;
|
import org.jclouds.compute.strategy.ResumeNodeStrategy;
|
||||||
import org.jclouds.compute.strategy.RunNodesAndAddToSetStrategy;
|
import org.jclouds.compute.strategy.RunNodesAndAddToSetStrategy;
|
||||||
|
import org.jclouds.compute.strategy.RunStatementOnNodeAndAddToGoodMapOrPutExceptionIntoBadMap;
|
||||||
import org.jclouds.compute.strategy.SuspendNodeStrategy;
|
import org.jclouds.compute.strategy.SuspendNodeStrategy;
|
||||||
import org.jclouds.compute.util.ComputeUtils;
|
|
||||||
import org.jclouds.domain.Credentials;
|
import org.jclouds.domain.Credentials;
|
||||||
import org.jclouds.domain.Location;
|
import org.jclouds.domain.Location;
|
||||||
import org.jclouds.vcloud.terremark.compute.domain.KeyPairCredentials;
|
import org.jclouds.vcloud.terremark.compute.domain.KeyPairCredentials;
|
||||||
|
@ -75,13 +75,14 @@ public class TerremarkVCloudComputeService extends BaseComputeService {
|
||||||
Provider<TemplateBuilder> templateBuilderProvider, Provider<TemplateOptions> templateOptionsProvider,
|
Provider<TemplateBuilder> templateBuilderProvider, Provider<TemplateOptions> templateOptionsProvider,
|
||||||
@Named("NODE_RUNNING") Predicate<NodeMetadata> nodeRunning,
|
@Named("NODE_RUNNING") Predicate<NodeMetadata> nodeRunning,
|
||||||
@Named("NODE_TERMINATED") Predicate<NodeMetadata> nodeTerminated,
|
@Named("NODE_TERMINATED") Predicate<NodeMetadata> nodeTerminated,
|
||||||
@Named("NODE_SUSPENDED") Predicate<NodeMetadata> nodeSuspended, ComputeUtils utils, Timeouts timeouts,
|
@Named("NODE_SUSPENDED") Predicate<NodeMetadata> nodeSuspended,
|
||||||
|
RunStatementOnNodeAndAddToGoodMapOrPutExceptionIntoBadMap.Factory statementRunner, Timeouts timeouts,
|
||||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor, CleanupOrphanKeys cleanupOrphanKeys,
|
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor, CleanupOrphanKeys cleanupOrphanKeys,
|
||||||
ConcurrentMap<OrgAndName, KeyPairCredentials> credentialsMap, NodeMetadataToOrgAndName nodeToOrgAndName) {
|
ConcurrentMap<OrgAndName, KeyPairCredentials> credentialsMap, NodeMetadataToOrgAndName nodeToOrgAndName) {
|
||||||
super(context, credentialStore, images, sizes, locations, listNodesStrategy, getNodeMetadataStrategy,
|
super(context, credentialStore, images, sizes, locations, listNodesStrategy, getNodeMetadataStrategy,
|
||||||
runNodesAndAddToSetStrategy, rebootNodeStrategy, destroyNodeStrategy, resumeNodeStrategy,
|
runNodesAndAddToSetStrategy, rebootNodeStrategy, destroyNodeStrategy, resumeNodeStrategy,
|
||||||
suspendNodeStrategy, templateBuilderProvider, templateOptionsProvider, nodeRunning, nodeTerminated,
|
suspendNodeStrategy, templateBuilderProvider, templateOptionsProvider, nodeRunning, nodeTerminated,
|
||||||
nodeSuspended, utils, timeouts, executor);
|
nodeSuspended, statementRunner, timeouts, executor);
|
||||||
this.cleanupOrphanKeys = cleanupOrphanKeys;
|
this.cleanupOrphanKeys = cleanupOrphanKeys;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -115,14 +115,6 @@ public class TerremarkVCloudComputeServiceContextModule extends VCloudExpressCom
|
||||||
return new ConcurrentHashMap<OrgAndName, KeyPairCredentials>();
|
return new ConcurrentHashMap<OrgAndName, KeyPairCredentials>();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO
|
|
||||||
// @Override
|
|
||||||
// protected void bindLoadBalancer() {
|
|
||||||
// bind(LoadBalanceNodesStrategy.class).to(TerremarkLoadBalanceNodesStrategy.class);
|
|
||||||
// bind(DestroyLoadBalancerStrategy.class).to(TerremarkDestroyLoadBalancerStrategy.class);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
|
|
||||||
@Named("PASSWORD")
|
@Named("PASSWORD")
|
||||||
@Provides
|
@Provides
|
||||||
String providePassword(SecureRandom random) {
|
String providePassword(SecureRandom random) {
|
||||||
|
|
|
@ -30,15 +30,18 @@ import javax.inject.Named;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import org.jclouds.Constants;
|
import org.jclouds.Constants;
|
||||||
|
import org.jclouds.compute.config.CustomizationResponse;
|
||||||
import org.jclouds.compute.domain.NodeMetadata;
|
import org.jclouds.compute.domain.NodeMetadata;
|
||||||
import org.jclouds.compute.domain.Template;
|
import org.jclouds.compute.domain.Template;
|
||||||
import org.jclouds.compute.strategy.AddNodeWithTagStrategy;
|
import org.jclouds.compute.strategy.AddNodeWithTagStrategy;
|
||||||
|
import org.jclouds.compute.strategy.CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap;
|
||||||
import org.jclouds.compute.strategy.ListNodesStrategy;
|
import org.jclouds.compute.strategy.ListNodesStrategy;
|
||||||
import org.jclouds.compute.strategy.impl.EncodeTagIntoNameRunNodesAndAddToSetStrategy;
|
import org.jclouds.compute.strategy.impl.EncodeTagIntoNameRunNodesAndAddToSetStrategy;
|
||||||
import org.jclouds.compute.util.ComputeUtils;
|
|
||||||
import org.jclouds.domain.LocationScope;
|
import org.jclouds.domain.LocationScope;
|
||||||
import org.jclouds.vcloud.terremark.compute.options.TerremarkVCloudTemplateOptions;
|
import org.jclouds.vcloud.terremark.compute.options.TerremarkVCloudTemplateOptions;
|
||||||
|
|
||||||
|
import com.google.common.collect.Multimap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* creates futures that correlate to
|
* creates futures that correlate to
|
||||||
*
|
*
|
||||||
|
@ -50,23 +53,27 @@ public class TerremarkEncodeTagIntoNameRunNodesAndAddToSetStrategy extends Encod
|
||||||
private final CreateNewKeyPairUnlessUserSpecifiedOtherwise createNewKeyPairUnlessUserSpecifiedOtherwise;
|
private final CreateNewKeyPairUnlessUserSpecifiedOtherwise createNewKeyPairUnlessUserSpecifiedOtherwise;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
protected TerremarkEncodeTagIntoNameRunNodesAndAddToSetStrategy(AddNodeWithTagStrategy addNodeWithTagStrategy,
|
protected TerremarkEncodeTagIntoNameRunNodesAndAddToSetStrategy(
|
||||||
ListNodesStrategy listNodesStrategy, @Named("NAMING_CONVENTION") String nodeNamingConvention,
|
AddNodeWithTagStrategy addNodeWithTagStrategy,
|
||||||
ComputeUtils utils, @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor,
|
ListNodesStrategy listNodesStrategy,
|
||||||
|
@Named("NAMING_CONVENTION") String nodeNamingConvention,
|
||||||
|
CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap.Factory customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory,
|
||||||
|
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor,
|
||||||
CreateNewKeyPairUnlessUserSpecifiedOtherwise createNewKeyPairUnlessUserSpecifiedOtherwise) {
|
CreateNewKeyPairUnlessUserSpecifiedOtherwise createNewKeyPairUnlessUserSpecifiedOtherwise) {
|
||||||
super(addNodeWithTagStrategy, listNodesStrategy, nodeNamingConvention, utils, executor);
|
super(addNodeWithTagStrategy, listNodesStrategy, nodeNamingConvention, executor,
|
||||||
|
customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory);
|
||||||
this.createNewKeyPairUnlessUserSpecifiedOtherwise = createNewKeyPairUnlessUserSpecifiedOtherwise;
|
this.createNewKeyPairUnlessUserSpecifiedOtherwise = createNewKeyPairUnlessUserSpecifiedOtherwise;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<?, Future<Void>> execute(String tag, int count, Template template, Set<NodeMetadata> nodes,
|
public Map<?, Future<Void>> execute(String tag, int count, Template template, Set<NodeMetadata> goodNodes,
|
||||||
Map<NodeMetadata, Exception> badNodes) {
|
Map<NodeMetadata, Exception> badNodes, Multimap<NodeMetadata, CustomizationResponse> customizationResponses) {
|
||||||
assert template.getLocation().getParent().getScope() == LocationScope.REGION : "template location should have a parent of org, which should be mapped to region: "
|
assert template.getLocation().getParent().getScope() == LocationScope.REGION : "template location should have a parent of org, which should be mapped to region: "
|
||||||
+ template.getLocation();
|
+ template.getLocation();
|
||||||
String orgId = template.getLocation().getParent().getId();
|
String orgId = template.getLocation().getParent().getId();
|
||||||
assert orgId.startsWith("http") : "parent id should be a rest url: " + template.getLocation().getParent();
|
assert orgId.startsWith("http") : "parent id should be a rest url: " + template.getLocation().getParent();
|
||||||
createNewKeyPairUnlessUserSpecifiedOtherwise.execute(URI.create(orgId), tag, template.getImage()
|
createNewKeyPairUnlessUserSpecifiedOtherwise.execute(URI.create(orgId), tag, template.getImage()
|
||||||
.getDefaultCredentials().identity, template.getOptions().as(TerremarkVCloudTemplateOptions.class));
|
.getDefaultCredentials().identity, template.getOptions().as(TerremarkVCloudTemplateOptions.class));
|
||||||
return super.execute(tag, count, template, nodes, badNodes);
|
return super.execute(tag, count, template, goodNodes, badNodes, customizationResponses);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -23,9 +23,9 @@ import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.jclouds.compute.domain.ComputeMetadata;
|
import org.jclouds.compute.domain.ComputeMetadata;
|
||||||
|
import org.jclouds.compute.domain.Hardware;
|
||||||
import org.jclouds.compute.domain.Image;
|
import org.jclouds.compute.domain.Image;
|
||||||
import org.jclouds.compute.domain.NodeMetadata;
|
import org.jclouds.compute.domain.NodeMetadata;
|
||||||
import org.jclouds.compute.domain.Hardware;
|
|
||||||
import org.jclouds.compute.domain.Template;
|
import org.jclouds.compute.domain.Template;
|
||||||
import org.jclouds.compute.domain.TemplateBuilder;
|
import org.jclouds.compute.domain.TemplateBuilder;
|
||||||
import org.jclouds.compute.internal.BaseComputeService;
|
import org.jclouds.compute.internal.BaseComputeService;
|
||||||
|
@ -33,6 +33,7 @@ import org.jclouds.compute.options.RunScriptOptions;
|
||||||
import org.jclouds.compute.options.TemplateOptions;
|
import org.jclouds.compute.options.TemplateOptions;
|
||||||
import org.jclouds.domain.Location;
|
import org.jclouds.domain.Location;
|
||||||
import org.jclouds.io.Payload;
|
import org.jclouds.io.Payload;
|
||||||
|
import org.jclouds.scriptbuilder.domain.Statement;
|
||||||
import org.jclouds.ssh.ExecResponse;
|
import org.jclouds.ssh.ExecResponse;
|
||||||
|
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
|
@ -238,11 +239,12 @@ public interface ComputeService {
|
||||||
* org.jclouds.compute.options.RunScriptOptions)
|
* org.jclouds.compute.options.RunScriptOptions)
|
||||||
* @see org.jclouds.compute.predicates.NodePredicates#runningWithTag(String)
|
* @see org.jclouds.compute.predicates.NodePredicates#runningWithTag(String)
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
Map<? extends NodeMetadata, ExecResponse> runScriptOnNodesMatching(Predicate<NodeMetadata> filter, Payload runScript)
|
Map<? extends NodeMetadata, ExecResponse> runScriptOnNodesMatching(Predicate<NodeMetadata> filter, Payload runScript)
|
||||||
throws RunScriptOnNodesException;
|
throws RunScriptOnNodesException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run the script on all nodes with the specific tag.
|
* Run the script on all nodes with the specific predicate.
|
||||||
*
|
*
|
||||||
* @param filter
|
* @param filter
|
||||||
* Predicate-based filter to define on which nodes the script is to be executed
|
* Predicate-based filter to define on which nodes the script is to be executed
|
||||||
|
@ -257,7 +259,46 @@ public interface ComputeService {
|
||||||
* @see org.jclouds.compute.predicates.NodePredicates#runningWithTag(String)
|
* @see org.jclouds.compute.predicates.NodePredicates#runningWithTag(String)
|
||||||
* @see org.jclouds.io.Payloads
|
* @see org.jclouds.io.Payloads
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
Map<? extends NodeMetadata, ExecResponse> runScriptOnNodesMatching(Predicate<NodeMetadata> filter,
|
Map<? extends NodeMetadata, ExecResponse> runScriptOnNodesMatching(Predicate<NodeMetadata> filter,
|
||||||
Payload runScript, RunScriptOptions options) throws RunScriptOnNodesException;
|
Payload runScript, RunScriptOptions options) throws RunScriptOnNodesException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run the script on all nodes with the specific predicate.
|
||||||
|
*
|
||||||
|
* @param filter
|
||||||
|
* Predicate-based filter to define on which nodes the script is to be executed
|
||||||
|
* @param runScript
|
||||||
|
* string containing the script to run
|
||||||
|
* @param options
|
||||||
|
* nullable options to how to run the script, whether to override credentials
|
||||||
|
* @return map with node identifiers and corresponding responses
|
||||||
|
* @throws RunScriptOnNodesException
|
||||||
|
* if anything goes wrong during script execution
|
||||||
|
*
|
||||||
|
* @see org.jclouds.compute.predicates.NodePredicates#runningWithTag(String)
|
||||||
|
* @see org.jclouds.scriptbuilder.domain.Statements
|
||||||
|
*/
|
||||||
|
Map<? extends NodeMetadata, ExecResponse> runScriptOnNodesMatching(Predicate<NodeMetadata> filter, String runScript,
|
||||||
|
RunScriptOptions options) throws RunScriptOnNodesException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run the script on all nodes with the specific predicate.
|
||||||
|
*
|
||||||
|
* @param filter
|
||||||
|
* Predicate-based filter to define on which nodes the script is to be executed
|
||||||
|
* @param runScript
|
||||||
|
* statement containing the script to run
|
||||||
|
* @param options
|
||||||
|
* nullable options to how to run the script, whether to override credentials
|
||||||
|
* @return map with node identifiers and corresponding responses
|
||||||
|
* @throws RunScriptOnNodesException
|
||||||
|
* if anything goes wrong during script execution
|
||||||
|
*
|
||||||
|
* @see org.jclouds.compute.predicates.NodePredicates#runningWithTag(String)
|
||||||
|
* @see org.jclouds.scriptbuilder.domain.Statements
|
||||||
|
*/
|
||||||
|
Map<? extends NodeMetadata, ExecResponse> runScriptOnNodesMatching(Predicate<NodeMetadata> filter,
|
||||||
|
Statement runScript, RunScriptOptions options) throws RunScriptOnNodesException;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ import javax.annotation.Nullable;
|
||||||
|
|
||||||
import org.jclouds.compute.domain.NodeMetadata;
|
import org.jclouds.compute.domain.NodeMetadata;
|
||||||
import org.jclouds.compute.options.RunScriptOptions;
|
import org.jclouds.compute.options.RunScriptOptions;
|
||||||
import org.jclouds.io.Payload;
|
import org.jclouds.scriptbuilder.domain.Statement;
|
||||||
import org.jclouds.ssh.ExecResponse;
|
import org.jclouds.ssh.ExecResponse;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -39,13 +39,13 @@ public class RunScriptOnNodesException extends Exception {
|
||||||
|
|
||||||
/** The serialVersionUID */
|
/** The serialVersionUID */
|
||||||
private static final long serialVersionUID = -2272965726680821281L;
|
private static final long serialVersionUID = -2272965726680821281L;
|
||||||
private final Payload runScript;
|
private final Statement runScript;
|
||||||
private final RunScriptOptions options;
|
private final RunScriptOptions options;
|
||||||
private final Map<NodeMetadata, ExecResponse> successfulNodes;
|
private final Map<NodeMetadata, ExecResponse> successfulNodes;
|
||||||
private final Map<? extends NodeMetadata, ? extends Throwable> failedNodes;
|
private final Map<? extends NodeMetadata, ? extends Throwable> failedNodes;
|
||||||
private final Map<?, Exception> executionExceptions;
|
private final Map<?, Exception> executionExceptions;
|
||||||
|
|
||||||
public RunScriptOnNodesException(final Payload runScript, @Nullable final RunScriptOptions options,
|
public RunScriptOnNodesException(Statement runScript, @Nullable RunScriptOptions options,
|
||||||
Map<NodeMetadata, ExecResponse> successfulNodes, Map<?, Exception> executionExceptions,
|
Map<NodeMetadata, ExecResponse> successfulNodes, Map<?, Exception> executionExceptions,
|
||||||
Map<? extends NodeMetadata, ? extends Throwable> failedNodes) {
|
Map<? extends NodeMetadata, ? extends Throwable> failedNodes) {
|
||||||
super(String.format("error runScript on filtered nodes options(%s)%n%s%n%s", options,
|
super(String.format("error runScript on filtered nodes options(%s)%n%s%n%s", options,
|
||||||
|
@ -66,8 +66,7 @@ public class RunScriptOnNodesException extends Exception {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @return Nodes that performed startup without error, but incurred problems
|
* @return Nodes that performed startup without error, but incurred problems applying options
|
||||||
* applying options
|
|
||||||
*/
|
*/
|
||||||
public Map<?, ? extends Throwable> getExecutionErrors() {
|
public Map<?, ? extends Throwable> getExecutionErrors() {
|
||||||
return executionExceptions;
|
return executionExceptions;
|
||||||
|
@ -75,14 +74,13 @@ public class RunScriptOnNodesException extends Exception {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @return Nodes that performed startup without error, but incurred problems
|
* @return Nodes that performed startup without error, but incurred problems applying options
|
||||||
* applying options
|
|
||||||
*/
|
*/
|
||||||
public Map<? extends NodeMetadata, ? extends Throwable> getNodeErrors() {
|
public Map<? extends NodeMetadata, ? extends Throwable> getNodeErrors() {
|
||||||
return failedNodes;
|
return failedNodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Payload getRunScript() {
|
public Statement getRunScript() {
|
||||||
return runScript;
|
return runScript;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,9 +22,15 @@ package org.jclouds.compute.callables;
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Named;
|
||||||
|
|
||||||
import org.jclouds.compute.domain.NodeMetadata;
|
import org.jclouds.compute.domain.NodeMetadata;
|
||||||
import org.jclouds.compute.util.ComputeServiceUtils.SshCallable;
|
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||||
import org.jclouds.logging.Logger;
|
import org.jclouds.logging.Logger;
|
||||||
import org.jclouds.scriptbuilder.InitBuilder;
|
import org.jclouds.scriptbuilder.InitBuilder;
|
||||||
import org.jclouds.scriptbuilder.domain.OsFamily;
|
import org.jclouds.scriptbuilder.domain.OsFamily;
|
||||||
|
@ -33,23 +39,51 @@ import org.jclouds.ssh.ExecResponse;
|
||||||
import org.jclouds.ssh.SshClient;
|
import org.jclouds.ssh.SshClient;
|
||||||
|
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
|
import com.google.common.base.Function;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
|
import com.google.inject.assistedinject.Assisted;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public class InitAndStartScriptOnNode implements SshCallable<ExecResponse> {
|
public class StartInitScriptOnNode implements Callable<ExecResponse> {
|
||||||
protected SshClient ssh;
|
@Resource
|
||||||
protected final NodeMetadata node;
|
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||||
protected final InitBuilder init;
|
|
||||||
protected final boolean runAsRoot;
|
|
||||||
protected Logger logger = Logger.NULL;
|
protected Logger logger = Logger.NULL;
|
||||||
|
|
||||||
public InitAndStartScriptOnNode(NodeMetadata node, String name, Statement script, boolean runAsRoot) {
|
public interface Factory {
|
||||||
|
@Named("blocking")
|
||||||
|
StartInitScriptOnNode blockOnComplete(NodeMetadata node, @Nullable String name, Statement script,
|
||||||
|
boolean runAsRoot);
|
||||||
|
|
||||||
|
@Named("nonblocking")
|
||||||
|
StartInitScriptOnNode dontBlockOnComplete(NodeMetadata node, @Nullable String name, Statement script,
|
||||||
|
boolean runAsRoot);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected final Function<NodeMetadata, SshClient> sshFactory;
|
||||||
|
protected final NodeMetadata node;
|
||||||
|
protected final Statement init;
|
||||||
|
protected final String name;
|
||||||
|
protected final boolean runAsRoot;
|
||||||
|
|
||||||
|
protected SshClient ssh;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public StartInitScriptOnNode(Function<NodeMetadata, SshClient> sshFactory, @Assisted NodeMetadata node,
|
||||||
|
@Assisted @Nullable String name, @Assisted Statement script, @Assisted boolean runAsRoot) {
|
||||||
|
this.sshFactory = checkNotNull(sshFactory, "sshFactory");
|
||||||
this.node = checkNotNull(node, "node");
|
this.node = checkNotNull(node, "node");
|
||||||
|
if (name == null) {
|
||||||
|
if (checkNotNull(script, "script") instanceof InitBuilder)
|
||||||
|
name = InitBuilder.class.cast(script).getInstanceName();
|
||||||
|
else
|
||||||
|
name = "jclouds-script-" + System.currentTimeMillis();
|
||||||
|
}
|
||||||
this.init = checkNotNull(script, "script") instanceof InitBuilder ? InitBuilder.class.cast(script)
|
this.init = checkNotNull(script, "script") instanceof InitBuilder ? InitBuilder.class.cast(script)
|
||||||
: createInitScript(checkNotNull(name, "name"), script);
|
: createInitScript(checkNotNull(name, "name"), script);
|
||||||
|
this.name = checkNotNull(name, "name");
|
||||||
this.runAsRoot = runAsRoot;
|
this.runAsRoot = runAsRoot;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,13 +94,28 @@ public class InitAndStartScriptOnNode implements SshCallable<ExecResponse> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ExecResponse call() {
|
public ExecResponse call() {
|
||||||
ssh.put(init.getInstanceName(), init.render(OsFamily.UNIX));
|
ssh = sshFactory.apply(node);
|
||||||
ssh.exec("chmod 755 " + init.getInstanceName());
|
try {
|
||||||
|
ssh.connect();
|
||||||
|
return doCall();
|
||||||
|
} finally {
|
||||||
|
if (ssh != null)
|
||||||
|
ssh.disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ssh client is initialized through this call.
|
||||||
|
*/
|
||||||
|
protected ExecResponse doCall() {
|
||||||
|
ssh.put(name, init.render(OsFamily.UNIX));
|
||||||
|
ssh.exec("chmod 755 " + name);
|
||||||
runAction("init");
|
runAction("init");
|
||||||
return runAction("start");
|
return runAction("start");
|
||||||
}
|
}
|
||||||
|
|
||||||
private ExecResponse runAction(String action) {
|
protected ExecResponse runAction(String action) {
|
||||||
ExecResponse returnVal;
|
ExecResponse returnVal;
|
||||||
String command = (runAsRoot) ? execScriptAsRoot(action) : execScriptAsDefaultUser(action);
|
String command = (runAsRoot) ? execScriptAsRoot(action) : execScriptAsDefaultUser(action);
|
||||||
returnVal = runCommand(command);
|
returnVal = runCommand(command);
|
||||||
|
@ -84,30 +133,23 @@ public class InitAndStartScriptOnNode implements SshCallable<ExecResponse> {
|
||||||
return returnVal;
|
return returnVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setConnection(SshClient ssh, Logger logger) {
|
|
||||||
this.logger = checkNotNull(logger, "logger");
|
|
||||||
this.ssh = checkNotNull(ssh, "ssh");
|
|
||||||
}
|
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
public String execScriptAsRoot(String action) {
|
public String execScriptAsRoot(String action) {
|
||||||
String command;
|
String command;
|
||||||
if (node.getCredentials().identity.equals("root")) {
|
if (node.getCredentials().identity.equals("root")) {
|
||||||
command = "./" + init.getInstanceName() + " " + action;
|
command = "./" + name + " " + action;
|
||||||
} else if (node.getAdminPassword() != null) {
|
} else if (node.getAdminPassword() != null) {
|
||||||
command = String.format("echo '%s'|sudo -S ./%s %s", node.getAdminPassword(), init.getInstanceName(), action);
|
command = String.format("echo '%s'|sudo -S ./%s %s", node.getAdminPassword(), name, action);
|
||||||
} else {
|
} else {
|
||||||
command = "sudo ./" + init.getInstanceName() + " " + action;
|
command = "sudo ./" + name + " " + action;
|
||||||
}
|
}
|
||||||
return command;
|
return command;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String execScriptAsDefaultUser(String action) {
|
protected String execScriptAsDefaultUser(String action) {
|
||||||
return "./" + init.getInstanceName() + " " + action;
|
return "./" + name + " " + action;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public NodeMetadata getNode() {
|
public NodeMetadata getNode() {
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
|
@ -19,40 +19,48 @@
|
||||||
|
|
||||||
package org.jclouds.compute.callables;
|
package org.jclouds.compute.callables;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
|
|
||||||
import org.jclouds.compute.domain.NodeMetadata;
|
import org.jclouds.compute.domain.NodeMetadata;
|
||||||
import org.jclouds.compute.predicates.ScriptStatusReturnsZero.CommandUsingClient;
|
import org.jclouds.compute.predicates.ScriptStatusReturnsZero.CommandUsingClient;
|
||||||
import org.jclouds.scriptbuilder.domain.Statement;
|
import org.jclouds.scriptbuilder.domain.Statement;
|
||||||
import org.jclouds.ssh.ExecResponse;
|
import org.jclouds.ssh.ExecResponse;
|
||||||
|
import org.jclouds.ssh.SshClient;
|
||||||
|
|
||||||
|
import com.google.common.base.Function;
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
|
import com.google.inject.assistedinject.Assisted;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public class RunScriptOnNode extends InitAndStartScriptOnNode {
|
public class StartInitScriptOnNodeAndBlockUntilComplete extends StartInitScriptOnNode {
|
||||||
protected final Predicate<CommandUsingClient> runScriptNotRunning;
|
protected final Predicate<CommandUsingClient> runScriptNotRunning;
|
||||||
|
|
||||||
public RunScriptOnNode(@Named("SCRIPT_COMPLETE") Predicate<CommandUsingClient> runScriptNotRunning,
|
@Inject
|
||||||
NodeMetadata node, String scriptName, Statement script, boolean runAsRoot) {
|
public StartInitScriptOnNodeAndBlockUntilComplete(
|
||||||
super(node, scriptName, script, runAsRoot);
|
@Named("SCRIPT_COMPLETE") Predicate<CommandUsingClient> runScriptNotRunning,
|
||||||
this.runScriptNotRunning = runScriptNotRunning;
|
Function<NodeMetadata, SshClient> sshFactory, @Assisted NodeMetadata node, @Assisted String scriptName,
|
||||||
|
@Assisted Statement script, @Assisted boolean runAsRoot) {
|
||||||
|
super(sshFactory, node, scriptName, script, runAsRoot);
|
||||||
|
this.runScriptNotRunning = checkNotNull(runScriptNotRunning, "runScriptNotRunning");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ExecResponse call() {
|
public ExecResponse doCall() {
|
||||||
ExecResponse returnVal = super.call();
|
ExecResponse returnVal = super.doCall();
|
||||||
boolean complete = runScriptNotRunning.apply(new CommandUsingClient("./" + init.getInstanceName() + " status", ssh));
|
boolean complete = runScriptNotRunning.apply(new CommandUsingClient("./" + name + " status", ssh));
|
||||||
logger.debug("<< complete(%s)", complete);
|
logger.debug("<< complete(%s)", complete);
|
||||||
if (logger.isDebugEnabled() || returnVal.getExitCode() != 0) {
|
if (logger.isDebugEnabled() || returnVal.getExitCode() != 0) {
|
||||||
logger.debug("<< stdout from %s as %s@%s\n%s", init.getInstanceName(), node.getCredentials().identity, Iterables.get(node
|
logger.debug("<< stdout from %s as %s@%s\n%s", name, node.getCredentials().identity, Iterables.get(node
|
||||||
.getPublicAddresses(), 0), ssh.exec("./" + init.getInstanceName() + " tail").getOutput());
|
.getPublicAddresses(), 0), ssh.exec("./" + name + " tail").getOutput());
|
||||||
logger.debug("<< stderr from %s as %s@%s\n%s", init.getInstanceName(), node.getCredentials().identity, Iterables.get(node
|
logger.debug("<< stderr from %s as %s@%s\n%s", name, node.getCredentials().identity, Iterables.get(node
|
||||||
.getPublicAddresses(), 0), ssh.exec("./" + init.getInstanceName() + " tailerr").getOutput());
|
.getPublicAddresses(), 0), ssh.exec("./" + name + " tailerr").getOutput());
|
||||||
}
|
}
|
||||||
return returnVal;
|
return returnVal;
|
||||||
}
|
}
|
|
@ -24,12 +24,15 @@ import static org.jclouds.compute.domain.OsFamily.UBUNTU;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import org.jclouds.collect.Memoized;
|
import org.jclouds.collect.Memoized;
|
||||||
|
import org.jclouds.compute.callables.StartInitScriptOnNode;
|
||||||
|
import org.jclouds.compute.callables.StartInitScriptOnNodeAndBlockUntilComplete;
|
||||||
import org.jclouds.compute.domain.ComputeMetadata;
|
import org.jclouds.compute.domain.ComputeMetadata;
|
||||||
import org.jclouds.compute.domain.Hardware;
|
import org.jclouds.compute.domain.Hardware;
|
||||||
import org.jclouds.compute.domain.Image;
|
import org.jclouds.compute.domain.Image;
|
||||||
|
@ -37,11 +40,17 @@ import org.jclouds.compute.domain.NodeMetadata;
|
||||||
import org.jclouds.compute.domain.OsFamily;
|
import org.jclouds.compute.domain.OsFamily;
|
||||||
import org.jclouds.compute.domain.TemplateBuilder;
|
import org.jclouds.compute.domain.TemplateBuilder;
|
||||||
import org.jclouds.compute.functions.CreateSshClientOncePortIsListeningOnNode;
|
import org.jclouds.compute.functions.CreateSshClientOncePortIsListeningOnNode;
|
||||||
|
import org.jclouds.compute.functions.TemplateOptionsToStatement;
|
||||||
|
import org.jclouds.compute.options.TemplateOptions;
|
||||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||||
|
import org.jclouds.compute.strategy.CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap;
|
||||||
|
import org.jclouds.compute.strategy.RunStatementOnNodeAndAddToGoodMapOrPutExceptionIntoBadMap;
|
||||||
|
import org.jclouds.compute.util.ComputeServiceUtils;
|
||||||
import org.jclouds.domain.Location;
|
import org.jclouds.domain.Location;
|
||||||
import org.jclouds.json.Json;
|
import org.jclouds.json.Json;
|
||||||
import org.jclouds.rest.AuthorizationException;
|
import org.jclouds.rest.AuthorizationException;
|
||||||
import org.jclouds.rest.suppliers.RetryOnTimeOutButNotOnAuthorizationExceptionSupplier;
|
import org.jclouds.rest.suppliers.RetryOnTimeOutButNotOnAuthorizationExceptionSupplier;
|
||||||
|
import org.jclouds.scriptbuilder.domain.Statement;
|
||||||
import org.jclouds.ssh.SshClient;
|
import org.jclouds.ssh.SshClient;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
|
@ -52,6 +61,8 @@ import com.google.inject.AbstractModule;
|
||||||
import com.google.inject.Injector;
|
import com.google.inject.Injector;
|
||||||
import com.google.inject.Provides;
|
import com.google.inject.Provides;
|
||||||
import com.google.inject.TypeLiteral;
|
import com.google.inject.TypeLiteral;
|
||||||
|
import com.google.inject.assistedinject.FactoryModuleBuilder;
|
||||||
|
import com.google.inject.name.Names;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -63,6 +74,23 @@ public abstract class BaseComputeServiceContextModule extends AbstractModule {
|
||||||
install(new ComputeServiceTimeoutsModule());
|
install(new ComputeServiceTimeoutsModule());
|
||||||
bind(new TypeLiteral<Function<NodeMetadata, SshClient>>() {
|
bind(new TypeLiteral<Function<NodeMetadata, SshClient>>() {
|
||||||
}).to(CreateSshClientOncePortIsListeningOnNode.class);
|
}).to(CreateSshClientOncePortIsListeningOnNode.class);
|
||||||
|
bind(new TypeLiteral<Function<TemplateOptions, Statement>>() {
|
||||||
|
}).to(TemplateOptionsToStatement.class);
|
||||||
|
|
||||||
|
install(new FactoryModuleBuilder().implement(StartInitScriptOnNode.class, Names.named("blocking"),
|
||||||
|
StartInitScriptOnNodeAndBlockUntilComplete.class).implement(StartInitScriptOnNode.class,
|
||||||
|
Names.named("nonblocking"), StartInitScriptOnNode.class).build(StartInitScriptOnNode.Factory.class));
|
||||||
|
|
||||||
|
install(new FactoryModuleBuilder().implement(new TypeLiteral<Callable<Void>>() {
|
||||||
|
}, CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap.class).implement(
|
||||||
|
new TypeLiteral<Function<NodeMetadata, Void>>() {
|
||||||
|
}, CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap.class).build(
|
||||||
|
CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap.Factory.class));
|
||||||
|
|
||||||
|
install(new FactoryModuleBuilder().implement(new TypeLiteral<Callable<Void>>() {
|
||||||
|
}, RunStatementOnNodeAndAddToGoodMapOrPutExceptionIntoBadMap.class).build(
|
||||||
|
RunStatementOnNodeAndAddToGoodMapOrPutExceptionIntoBadMap.Factory.class));
|
||||||
|
requestStaticInjection(ComputeServiceUtils.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Designates information related to customization of a resource.
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
public interface CustomizationResponse {
|
||||||
|
|
||||||
|
}
|
|
@ -53,7 +53,6 @@ public class JCloudsNativeComputeServiceAdapterContextModule<S, A> extends
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
bind(new TypeLiteral<ComputeServiceAdapter<NodeMetadata, Hardware, Image, Location>>() {
|
bind(new TypeLiteral<ComputeServiceAdapter<NodeMetadata, Hardware, Image, Location>>() {
|
||||||
}).to(adapter);
|
}).to(adapter);
|
||||||
bind(IdentityFunction.class).toInstance(IdentityFunction.INSTANCE);
|
|
||||||
bind(new TypeLiteral<Function<NodeMetadata, NodeMetadata>>() {
|
bind(new TypeLiteral<Function<NodeMetadata, NodeMetadata>>() {
|
||||||
}).to((Class) IdentityFunction.class);
|
}).to((Class) IdentityFunction.class);
|
||||||
bind(new TypeLiteral<Function<Image, Image>>() {
|
bind(new TypeLiteral<Function<Image, Image>>() {
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 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.functions;
|
||||||
|
|
||||||
|
import static com.google.common.collect.Lists.newArrayList;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import org.jclouds.compute.options.TemplateOptions;
|
||||||
|
import org.jclouds.scriptbuilder.InitBuilder;
|
||||||
|
import org.jclouds.scriptbuilder.domain.AuthorizeRSAPublicKey;
|
||||||
|
import org.jclouds.scriptbuilder.domain.InstallRSAPrivateKey;
|
||||||
|
import org.jclouds.scriptbuilder.domain.Statement;
|
||||||
|
import org.jclouds.scriptbuilder.domain.StatementList;
|
||||||
|
|
||||||
|
import com.google.common.base.Function;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Singleton
|
||||||
|
public class TemplateOptionsToStatement implements Function<TemplateOptions, Statement> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Statement apply(TemplateOptions options) {
|
||||||
|
List<Statement> bootstrap = newArrayList();
|
||||||
|
if (options.getPublicKey() != null)
|
||||||
|
bootstrap.add(new AuthorizeRSAPublicKey(options.getPublicKey()));
|
||||||
|
if (options.getRunScript() != null)
|
||||||
|
bootstrap.add(options.getRunScript());
|
||||||
|
if (options.getPrivateKey() != null)
|
||||||
|
bootstrap.add(new InstallRSAPrivateKey(options.getPrivateKey()));
|
||||||
|
if (bootstrap.size() >= 1) {
|
||||||
|
if (options.getTaskName() == null && !(options.getRunScript() instanceof InitBuilder))
|
||||||
|
options.nameTask("bootstrap");
|
||||||
|
return bootstrap.size() == 1 ? bootstrap.get(0) : new StatementList(bootstrap);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -27,10 +27,8 @@ import static com.google.common.base.Predicates.notNull;
|
||||||
import static com.google.common.collect.Iterables.concat;
|
import static com.google.common.collect.Iterables.concat;
|
||||||
import static com.google.common.collect.Iterables.filter;
|
import static com.google.common.collect.Iterables.filter;
|
||||||
import static com.google.common.collect.Iterables.transform;
|
import static com.google.common.collect.Iterables.transform;
|
||||||
import static com.google.common.collect.Maps.newHashMap;
|
|
||||||
import static com.google.common.collect.Maps.newLinkedHashMap;
|
import static com.google.common.collect.Maps.newLinkedHashMap;
|
||||||
import static com.google.common.collect.Sets.filter;
|
import static com.google.common.collect.Sets.filter;
|
||||||
import static com.google.common.collect.Sets.newHashSet;
|
|
||||||
import static com.google.common.collect.Sets.newLinkedHashSet;
|
import static com.google.common.collect.Sets.newLinkedHashSet;
|
||||||
import static com.google.common.util.concurrent.Futures.immediateFuture;
|
import static com.google.common.util.concurrent.Futures.immediateFuture;
|
||||||
import static org.jclouds.compute.predicates.NodePredicates.TERMINATED;
|
import static org.jclouds.compute.predicates.NodePredicates.TERMINATED;
|
||||||
|
@ -38,6 +36,7 @@ import static org.jclouds.compute.predicates.NodePredicates.all;
|
||||||
import static org.jclouds.concurrent.FutureIterables.awaitCompletion;
|
import static org.jclouds.concurrent.FutureIterables.awaitCompletion;
|
||||||
import static org.jclouds.concurrent.FutureIterables.transformParallel;
|
import static org.jclouds.concurrent.FutureIterables.transformParallel;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
|
@ -59,6 +58,7 @@ import org.jclouds.compute.ComputeService;
|
||||||
import org.jclouds.compute.ComputeServiceContext;
|
import org.jclouds.compute.ComputeServiceContext;
|
||||||
import org.jclouds.compute.RunNodesException;
|
import org.jclouds.compute.RunNodesException;
|
||||||
import org.jclouds.compute.RunScriptOnNodesException;
|
import org.jclouds.compute.RunScriptOnNodesException;
|
||||||
|
import org.jclouds.compute.config.CustomizationResponse;
|
||||||
import org.jclouds.compute.domain.ComputeMetadata;
|
import org.jclouds.compute.domain.ComputeMetadata;
|
||||||
import org.jclouds.compute.domain.Hardware;
|
import org.jclouds.compute.domain.Hardware;
|
||||||
import org.jclouds.compute.domain.Image;
|
import org.jclouds.compute.domain.Image;
|
||||||
|
@ -76,13 +76,14 @@ import org.jclouds.compute.strategy.ListNodesStrategy;
|
||||||
import org.jclouds.compute.strategy.RebootNodeStrategy;
|
import org.jclouds.compute.strategy.RebootNodeStrategy;
|
||||||
import org.jclouds.compute.strategy.ResumeNodeStrategy;
|
import org.jclouds.compute.strategy.ResumeNodeStrategy;
|
||||||
import org.jclouds.compute.strategy.RunNodesAndAddToSetStrategy;
|
import org.jclouds.compute.strategy.RunNodesAndAddToSetStrategy;
|
||||||
|
import org.jclouds.compute.strategy.RunStatementOnNodeAndAddToGoodMapOrPutExceptionIntoBadMap;
|
||||||
import org.jclouds.compute.strategy.SuspendNodeStrategy;
|
import org.jclouds.compute.strategy.SuspendNodeStrategy;
|
||||||
import org.jclouds.compute.util.ComputeUtils;
|
|
||||||
import org.jclouds.domain.Credentials;
|
import org.jclouds.domain.Credentials;
|
||||||
import org.jclouds.domain.Location;
|
import org.jclouds.domain.Location;
|
||||||
import org.jclouds.io.Payload;
|
import org.jclouds.io.Payload;
|
||||||
import org.jclouds.logging.Logger;
|
import org.jclouds.logging.Logger;
|
||||||
import org.jclouds.predicates.RetryablePredicate;
|
import org.jclouds.predicates.RetryablePredicate;
|
||||||
|
import org.jclouds.scriptbuilder.domain.Statement;
|
||||||
import org.jclouds.scriptbuilder.domain.Statements;
|
import org.jclouds.scriptbuilder.domain.Statements;
|
||||||
import org.jclouds.ssh.ExecResponse;
|
import org.jclouds.ssh.ExecResponse;
|
||||||
import org.jclouds.util.Strings2;
|
import org.jclouds.util.Strings2;
|
||||||
|
@ -90,6 +91,9 @@ import org.jclouds.util.Strings2;
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
import com.google.common.base.Supplier;
|
import com.google.common.base.Supplier;
|
||||||
|
import com.google.common.base.Throwables;
|
||||||
|
import com.google.common.collect.LinkedHashMultimap;
|
||||||
|
import com.google.common.collect.Multimap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -104,24 +108,25 @@ public class BaseComputeService implements ComputeService {
|
||||||
|
|
||||||
protected final ComputeServiceContext context;
|
protected final ComputeServiceContext context;
|
||||||
protected final Map<String, Credentials> credentialStore;
|
protected final Map<String, Credentials> credentialStore;
|
||||||
protected final Supplier<Set<? extends Image>> images;
|
|
||||||
protected final Supplier<Set<? extends Hardware>> hardwareProfiles;
|
private final Supplier<Set<? extends Image>> images;
|
||||||
protected final Supplier<Set<? extends Location>> locations;
|
private final Supplier<Set<? extends Hardware>> hardwareProfiles;
|
||||||
protected final ListNodesStrategy listNodesStrategy;
|
private final Supplier<Set<? extends Location>> locations;
|
||||||
protected final GetNodeMetadataStrategy getNodeMetadataStrategy;
|
private final ListNodesStrategy listNodesStrategy;
|
||||||
protected final RunNodesAndAddToSetStrategy runNodesAndAddToSetStrategy;
|
private final GetNodeMetadataStrategy getNodeMetadataStrategy;
|
||||||
protected final RebootNodeStrategy rebootNodeStrategy;
|
private final RunNodesAndAddToSetStrategy runNodesAndAddToSetStrategy;
|
||||||
protected final DestroyNodeStrategy destroyNodeStrategy;
|
private final RebootNodeStrategy rebootNodeStrategy;
|
||||||
protected final ResumeNodeStrategy resumeNodeStrategy;
|
private final DestroyNodeStrategy destroyNodeStrategy;
|
||||||
protected final SuspendNodeStrategy suspendNodeStrategy;
|
private final ResumeNodeStrategy resumeNodeStrategy;
|
||||||
protected final Provider<TemplateBuilder> templateBuilderProvider;
|
private final SuspendNodeStrategy suspendNodeStrategy;
|
||||||
protected final Provider<TemplateOptions> templateOptionsProvider;
|
private final Provider<TemplateBuilder> templateBuilderProvider;
|
||||||
protected final Predicate<NodeMetadata> nodeRunning;
|
private final Provider<TemplateOptions> templateOptionsProvider;
|
||||||
protected final Predicate<NodeMetadata> nodeTerminated;
|
private final Predicate<NodeMetadata> nodeRunning;
|
||||||
protected final Predicate<NodeMetadata> nodeSuspended;
|
private final Predicate<NodeMetadata> nodeTerminated;
|
||||||
protected final ComputeUtils utils;
|
private final Predicate<NodeMetadata> nodeSuspended;
|
||||||
protected final Timeouts timeouts;
|
private final RunStatementOnNodeAndAddToGoodMapOrPutExceptionIntoBadMap.Factory statementRunner;
|
||||||
protected final ExecutorService executor;
|
private final Timeouts timeouts;
|
||||||
|
private final ExecutorService executor;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
protected BaseComputeService(ComputeServiceContext context, Map<String, Credentials> credentialStore,
|
protected BaseComputeService(ComputeServiceContext context, Map<String, Credentials> credentialStore,
|
||||||
|
@ -134,7 +139,8 @@ public class BaseComputeService implements ComputeService {
|
||||||
Provider<TemplateBuilder> templateBuilderProvider, Provider<TemplateOptions> templateOptionsProvider,
|
Provider<TemplateBuilder> templateBuilderProvider, Provider<TemplateOptions> templateOptionsProvider,
|
||||||
@Named("NODE_RUNNING") Predicate<NodeMetadata> nodeRunning,
|
@Named("NODE_RUNNING") Predicate<NodeMetadata> nodeRunning,
|
||||||
@Named("NODE_TERMINATED") Predicate<NodeMetadata> nodeTerminated,
|
@Named("NODE_TERMINATED") Predicate<NodeMetadata> nodeTerminated,
|
||||||
@Named("NODE_SUSPENDED") Predicate<NodeMetadata> nodeSuspended, ComputeUtils utils, Timeouts timeouts,
|
@Named("NODE_SUSPENDED") Predicate<NodeMetadata> nodeSuspended,
|
||||||
|
RunStatementOnNodeAndAddToGoodMapOrPutExceptionIntoBadMap.Factory statementRunner, Timeouts timeouts,
|
||||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) {
|
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) {
|
||||||
this.context = checkNotNull(context, "context");
|
this.context = checkNotNull(context, "context");
|
||||||
this.credentialStore = checkNotNull(credentialStore, "credentialStore");
|
this.credentialStore = checkNotNull(credentialStore, "credentialStore");
|
||||||
|
@ -153,7 +159,7 @@ public class BaseComputeService implements ComputeService {
|
||||||
this.nodeRunning = checkNotNull(nodeRunning, "nodeRunning");
|
this.nodeRunning = checkNotNull(nodeRunning, "nodeRunning");
|
||||||
this.nodeTerminated = checkNotNull(nodeTerminated, "nodeTerminated");
|
this.nodeTerminated = checkNotNull(nodeTerminated, "nodeTerminated");
|
||||||
this.nodeSuspended = checkNotNull(nodeSuspended, "nodeSuspended");
|
this.nodeSuspended = checkNotNull(nodeSuspended, "nodeSuspended");
|
||||||
this.utils = checkNotNull(utils, "utils");
|
this.statementRunner = checkNotNull(statementRunner, "statementRunner");
|
||||||
this.timeouts = checkNotNull(timeouts, "timeouts");
|
this.timeouts = checkNotNull(timeouts, "timeouts");
|
||||||
this.executor = checkNotNull(executor, "executor");
|
this.executor = checkNotNull(executor, "executor");
|
||||||
}
|
}
|
||||||
|
@ -177,17 +183,20 @@ public class BaseComputeService implements ComputeService {
|
||||||
logger.debug(">> running %d node%s tag(%s) location(%s) image(%s) hardwareProfile(%s) options(%s)", count,
|
logger.debug(">> running %d node%s tag(%s) location(%s) image(%s) hardwareProfile(%s) options(%s)", count,
|
||||||
count > 1 ? "s" : "", tag, template.getLocation().getId(), template.getImage().getId(), template
|
count > 1 ? "s" : "", tag, template.getLocation().getId(), template.getImage().getId(), template
|
||||||
.getHardware().getId(), template.getOptions());
|
.getHardware().getId(), template.getOptions());
|
||||||
Set<NodeMetadata> nodes = newHashSet();
|
Set<NodeMetadata> goodNodes = newLinkedHashSet();
|
||||||
Map<NodeMetadata, Exception> badNodes = newLinkedHashMap();
|
Map<NodeMetadata, Exception> badNodes = newLinkedHashMap();
|
||||||
Map<?, Future<Void>> responses = runNodesAndAddToSetStrategy.execute(tag, count, template, nodes, badNodes);
|
Multimap<NodeMetadata, CustomizationResponse> customizationResponses = LinkedHashMultimap.create();
|
||||||
Map<?, Exception> executionExceptions = awaitCompletion(responses, executor, null, logger, "resumeing nodes");
|
|
||||||
for (NodeMetadata node : concat(nodes, badNodes.keySet()))
|
Map<?, Future<Void>> responses = runNodesAndAddToSetStrategy.execute(tag, count, template, goodNodes, badNodes,
|
||||||
|
customizationResponses);
|
||||||
|
Map<?, Exception> executionExceptions = awaitCompletion(responses, executor, null, logger, "resuming nodes");
|
||||||
|
for (NodeMetadata node : concat(goodNodes, badNodes.keySet()))
|
||||||
if (node.getCredentials() != null)
|
if (node.getCredentials() != null)
|
||||||
credentialStore.put("node#" + node.getId(), node.getCredentials());
|
credentialStore.put("node#" + node.getId(), node.getCredentials());
|
||||||
if (executionExceptions.size() > 0 || badNodes.size() > 0) {
|
if (executionExceptions.size() > 0 || badNodes.size() > 0) {
|
||||||
throw new RunNodesException(tag, count, template, nodes, executionExceptions, badNodes);
|
throw new RunNodesException(tag, count, template, goodNodes, executionExceptions, badNodes);
|
||||||
}
|
}
|
||||||
return nodes;
|
return goodNodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -436,47 +445,54 @@ public class BaseComputeService implements ComputeService {
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Map<NodeMetadata, ExecResponse> runScriptOnNodesMatching(Predicate<NodeMetadata> filter,
|
public Map<NodeMetadata, ExecResponse> runScriptOnNodesMatching(Predicate<NodeMetadata> filter, Payload runScript,
|
||||||
final Payload runScript, @Nullable final RunScriptOptions options) throws RunScriptOnNodesException {
|
@Nullable RunScriptOptions options) throws RunScriptOnNodesException {
|
||||||
|
try {
|
||||||
|
return runScriptOnNodesMatching(filter, Statements.exec(Strings2.toStringAndClose(checkNotNull(runScript,
|
||||||
|
"runScript").getInput())), options);
|
||||||
|
} catch (IOException e) {
|
||||||
|
Throwables.propagate(e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Map<NodeMetadata, ExecResponse> runScriptOnNodesMatching(Predicate<NodeMetadata> filter, String runScript,
|
||||||
|
@Nullable RunScriptOptions options) throws RunScriptOnNodesException {
|
||||||
|
return runScriptOnNodesMatching(filter, Statements.exec(checkNotNull(runScript, "runScript")), options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Map<NodeMetadata, ExecResponse> runScriptOnNodesMatching(Predicate<NodeMetadata> filter, Statement runScript,
|
||||||
|
@Nullable RunScriptOptions options) throws RunScriptOnNodesException {
|
||||||
|
|
||||||
checkNotNull(filter, "Filter must be provided");
|
checkNotNull(filter, "Filter must be provided");
|
||||||
checkNotNull(runScript, "runScript");
|
checkNotNull(runScript, "runScript");
|
||||||
checkNotNull(options, "options");
|
checkNotNull(options, "options");
|
||||||
if (options.getTaskName() == null)
|
|
||||||
options.nameTask("jclouds-script-" + System.currentTimeMillis());
|
|
||||||
|
|
||||||
Iterable<? extends NodeMetadata> nodes = filter(detailsOnAllNodes(), filter);
|
Iterable<? extends NodeMetadata> nodes = filter(detailsOnAllNodes(), filter);
|
||||||
|
|
||||||
final Map<NodeMetadata, ExecResponse> execs = newHashMap();
|
Map<NodeMetadata, ExecResponse> goodNodes = newLinkedHashMap();
|
||||||
final Map<NodeMetadata, Future<Void>> responses = newHashMap();
|
Map<NodeMetadata, Exception> badNodes = newLinkedHashMap();
|
||||||
final Map<NodeMetadata, Exception> badNodes = newLinkedHashMap();
|
|
||||||
|
Map<NodeMetadata, Future<Void>> responses = newLinkedHashMap();
|
||||||
nodes = filterNodesWhoCanRunScripts(nodes, badNodes, options.getOverrideCredentials());
|
nodes = filterNodesWhoCanRunScripts(nodes, badNodes, options.getOverrideCredentials());
|
||||||
|
|
||||||
for (final NodeMetadata node : nodes) {
|
for (NodeMetadata node : nodes) {
|
||||||
|
responses.put(node, executor.submit(statementRunner.create(node, runScript, options, goodNodes, badNodes)));
|
||||||
responses.put(node, executor.submit(new Callable<Void>() {
|
|
||||||
@Override
|
|
||||||
public Void call() throws Exception {
|
|
||||||
try {
|
|
||||||
ExecResponse response = utils.runScriptOnNode(node, Statements.exec(Strings2.toStringAndClose(runScript
|
|
||||||
.getInput())), options);
|
|
||||||
if (response != null)
|
|
||||||
execs.put(node, response);
|
|
||||||
} catch (Exception e) {
|
|
||||||
badNodes.put(node, e);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}));
|
|
||||||
|
|
||||||
}
|
|
||||||
Map<?, Exception> exceptions = awaitCompletion(responses, executor, null, logger, "running script on nodes");
|
Map<?, Exception> exceptions = awaitCompletion(responses, executor, null, logger, "running script on nodes");
|
||||||
if (exceptions.size() > 0 || badNodes.size() > 0) {
|
if (exceptions.size() > 0 || badNodes.size() > 0) {
|
||||||
throw new RunScriptOnNodesException(runScript, options, execs, exceptions, badNodes);
|
throw new RunScriptOnNodesException(runScript, options, goodNodes, exceptions, badNodes);
|
||||||
}
|
}
|
||||||
|
return goodNodes;
|
||||||
return execs;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,162 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 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.strategy;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
import static com.google.common.base.Preconditions.checkState;
|
||||||
|
import static com.google.common.base.Throwables.getRootCause;
|
||||||
|
import static org.jclouds.compute.util.ComputeServiceUtils.findReachableSocketOnNode;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.inject.Named;
|
||||||
|
|
||||||
|
import org.jclouds.compute.callables.StartInitScriptOnNode;
|
||||||
|
import org.jclouds.compute.config.CustomizationResponse;
|
||||||
|
import org.jclouds.compute.domain.NodeMetadata;
|
||||||
|
import org.jclouds.compute.options.TemplateOptions;
|
||||||
|
import org.jclouds.compute.predicates.RetryIfSocketNotYetOpen;
|
||||||
|
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||||
|
import org.jclouds.compute.reference.ComputeServiceConstants.Timeouts;
|
||||||
|
import org.jclouds.logging.Logger;
|
||||||
|
import org.jclouds.scriptbuilder.domain.Statement;
|
||||||
|
import org.jclouds.ssh.ExecResponse;
|
||||||
|
|
||||||
|
import com.google.common.base.Function;
|
||||||
|
import com.google.common.base.Predicate;
|
||||||
|
import com.google.common.collect.Multimap;
|
||||||
|
import com.google.inject.assistedinject.Assisted;
|
||||||
|
import com.google.inject.assistedinject.AssistedInject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
public class CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap implements Callable<Void>,
|
||||||
|
Function<NodeMetadata, Void> {
|
||||||
|
public static interface Factory {
|
||||||
|
Callable<Void> create(TemplateOptions options, NodeMetadata node, Set<NodeMetadata> goodNodes,
|
||||||
|
Map<NodeMetadata, Exception> badNodes,
|
||||||
|
Multimap<NodeMetadata, CustomizationResponse> customizationResponses);
|
||||||
|
|
||||||
|
Function<NodeMetadata, Void> create(TemplateOptions options, Set<NodeMetadata> goodNodes,
|
||||||
|
Map<NodeMetadata, Exception> badNodes,
|
||||||
|
Multimap<NodeMetadata, CustomizationResponse> customizationResponses);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||||
|
protected Logger logger = Logger.NULL;
|
||||||
|
|
||||||
|
private final Predicate<NodeMetadata> nodeRunning;
|
||||||
|
private final ScriptInvokerForNodeAndStatement scriptInvokerForNodeAndStatement;
|
||||||
|
private final GetNodeMetadataStrategy getNode;
|
||||||
|
private final RetryIfSocketNotYetOpen socketTester;
|
||||||
|
private final Timeouts timeouts;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private final Statement statement;
|
||||||
|
private final TemplateOptions options;
|
||||||
|
private NodeMetadata node;
|
||||||
|
private final Set<NodeMetadata> goodNodes;
|
||||||
|
private final Map<NodeMetadata, Exception> badNodes;
|
||||||
|
private final Multimap<NodeMetadata, CustomizationResponse> customizationResponses;
|
||||||
|
|
||||||
|
private transient boolean tainted;
|
||||||
|
|
||||||
|
@AssistedInject
|
||||||
|
public CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap(
|
||||||
|
@Named("NODE_RUNNING") Predicate<NodeMetadata> nodeRunning, GetNodeMetadataStrategy getNode,
|
||||||
|
RetryIfSocketNotYetOpen socketTester, Timeouts timeouts,
|
||||||
|
Function<TemplateOptions, Statement> templateOptionsToStatement,
|
||||||
|
ScriptInvokerForNodeAndStatement scriptInvokerForNodeAndStatement, @Assisted TemplateOptions options,
|
||||||
|
@Assisted @Nullable NodeMetadata node, @Assisted Set<NodeMetadata> goodNodes,
|
||||||
|
@Assisted Map<NodeMetadata, Exception> badNodes,
|
||||||
|
@Assisted Multimap<NodeMetadata, CustomizationResponse> customizationResponses) {
|
||||||
|
this.statement = checkNotNull(templateOptionsToStatement, "templateOptionsToStatement").apply(
|
||||||
|
checkNotNull(options, "options"));
|
||||||
|
this.nodeRunning = checkNotNull(nodeRunning, "nodeRunning");
|
||||||
|
this.scriptInvokerForNodeAndStatement = checkNotNull(scriptInvokerForNodeAndStatement,
|
||||||
|
"scriptInvokerForNodeAndStatement");
|
||||||
|
this.getNode = checkNotNull(getNode, "getNode");
|
||||||
|
this.socketTester = checkNotNull(socketTester, "socketTester");
|
||||||
|
this.timeouts = checkNotNull(timeouts, "timeouts");
|
||||||
|
this.node = node;
|
||||||
|
this.options = checkNotNull(options, "options");
|
||||||
|
this.goodNodes = checkNotNull(goodNodes, "goodNodes");
|
||||||
|
this.badNodes = checkNotNull(badNodes, "badNodes");
|
||||||
|
this.customizationResponses = checkNotNull(customizationResponses, "customizationResponses");
|
||||||
|
}
|
||||||
|
|
||||||
|
@AssistedInject
|
||||||
|
public CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap(
|
||||||
|
@Named("NODE_RUNNING") Predicate<NodeMetadata> nodeRunning, GetNodeMetadataStrategy getNode,
|
||||||
|
RetryIfSocketNotYetOpen socketTester, Timeouts timeouts,
|
||||||
|
Function<TemplateOptions, Statement> templateOptionsToStatement,
|
||||||
|
ScriptInvokerForNodeAndStatement scriptInvokerForNodeAndStatement, @Assisted TemplateOptions options,
|
||||||
|
@Assisted Set<NodeMetadata> goodNodes, @Assisted Map<NodeMetadata, Exception> badNodes,
|
||||||
|
@Assisted Multimap<NodeMetadata, CustomizationResponse> customizationResponses) {
|
||||||
|
this(nodeRunning, getNode, socketTester, timeouts, templateOptionsToStatement, scriptInvokerForNodeAndStatement,
|
||||||
|
options, null, goodNodes, badNodes, customizationResponses);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void call() {
|
||||||
|
checkState(!tainted, "this object is not designed to be reused: %s", toString());
|
||||||
|
tainted = true;
|
||||||
|
try {
|
||||||
|
if (options.shouldBlockUntilRunning()) {
|
||||||
|
if (nodeRunning.apply(node)) {
|
||||||
|
node = getNode.getNode(node.getId());
|
||||||
|
} else {
|
||||||
|
throw new IllegalStateException(String.format(
|
||||||
|
"node didn't achieve the state running on node %s within %d seconds, final state: %s", node
|
||||||
|
.getId(), timeouts.nodeRunning / 1000, node.getState()));
|
||||||
|
}
|
||||||
|
if (statement != null) {
|
||||||
|
StartInitScriptOnNode scriptInstructions = scriptInvokerForNodeAndStatement.create(node, statement,
|
||||||
|
options);
|
||||||
|
ExecResponse exec = scriptInstructions.call();
|
||||||
|
customizationResponses.put(node, exec);
|
||||||
|
}
|
||||||
|
if (options.getPort() > 0) {
|
||||||
|
findReachableSocketOnNode(socketTester.seconds(options.getSeconds()), node, options.getPort());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
logger.debug("<< options applied node(%s)", node.getId());
|
||||||
|
goodNodes.add(node);
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error(e, "<< problem applying options to node(%s): ", node.getId(), getRootCause(e).getMessage());
|
||||||
|
badNodes.put(node, e);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void apply(NodeMetadata input) {
|
||||||
|
this.node = input;
|
||||||
|
call();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -21,12 +21,14 @@ package org.jclouds.compute.strategy;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
|
import org.jclouds.compute.config.CustomizationResponse;
|
||||||
import org.jclouds.compute.domain.NodeMetadata;
|
import org.jclouds.compute.domain.NodeMetadata;
|
||||||
import org.jclouds.compute.domain.Template;
|
import org.jclouds.compute.domain.Template;
|
||||||
import org.jclouds.compute.strategy.impl.EncodeTagIntoNameRunNodesAndAddToSetStrategy;
|
import org.jclouds.compute.strategy.impl.EncodeTagIntoNameRunNodesAndAddToSetStrategy;
|
||||||
|
|
||||||
import java.util.concurrent.Future;
|
import com.google.common.collect.Multimap;
|
||||||
import com.google.inject.ImplementedBy;
|
import com.google.inject.ImplementedBy;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -37,6 +39,6 @@ import com.google.inject.ImplementedBy;
|
||||||
@ImplementedBy(EncodeTagIntoNameRunNodesAndAddToSetStrategy.class)
|
@ImplementedBy(EncodeTagIntoNameRunNodesAndAddToSetStrategy.class)
|
||||||
public interface RunNodesAndAddToSetStrategy {
|
public interface RunNodesAndAddToSetStrategy {
|
||||||
|
|
||||||
Map<?, Future<Void>> execute(String tag, int count, Template template,
|
Map<?, Future<Void>> execute(String tag, int count, Template template, Set<NodeMetadata> goodNodes,
|
||||||
Set<NodeMetadata> nodes, Map<NodeMetadata, Exception> badNodes);
|
Map<NodeMetadata, Exception> badNodes, Multimap<NodeMetadata, CustomizationResponse> customizationResponses);
|
||||||
}
|
}
|
|
@ -0,0 +1,108 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 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.strategy;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
import static com.google.common.base.Preconditions.checkState;
|
||||||
|
import static com.google.common.base.Throwables.getRootCause;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.inject.Named;
|
||||||
|
|
||||||
|
import org.jclouds.compute.callables.StartInitScriptOnNode;
|
||||||
|
import org.jclouds.compute.domain.NodeMetadata;
|
||||||
|
import org.jclouds.compute.options.RunScriptOptions;
|
||||||
|
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||||
|
import org.jclouds.logging.Logger;
|
||||||
|
import org.jclouds.scriptbuilder.domain.Statement;
|
||||||
|
import org.jclouds.ssh.ExecResponse;
|
||||||
|
|
||||||
|
import com.google.inject.assistedinject.Assisted;
|
||||||
|
import com.google.inject.assistedinject.AssistedInject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
public class RunStatementOnNodeAndAddToGoodMapOrPutExceptionIntoBadMap implements Callable<Void> {
|
||||||
|
public static interface Factory {
|
||||||
|
Callable<Void> create(NodeMetadata node, Statement statement, RunScriptOptions options,
|
||||||
|
Map<NodeMetadata, ExecResponse> goodNodes, Map<NodeMetadata, Exception> badNodes);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||||
|
protected Logger logger = Logger.NULL;
|
||||||
|
// NOTE this is mutable
|
||||||
|
protected NodeMetadata node;
|
||||||
|
private final Map<NodeMetadata, Exception> badNodes;
|
||||||
|
private final Map<NodeMetadata, ExecResponse> goodNodes;
|
||||||
|
private final RunScriptOptions options;
|
||||||
|
|
||||||
|
protected final Statement statement;
|
||||||
|
private final ScriptInvokerForNodeAndStatement scriptInvokerForNodeAndStatement;
|
||||||
|
private transient boolean tainted;
|
||||||
|
|
||||||
|
@AssistedInject
|
||||||
|
public RunStatementOnNodeAndAddToGoodMapOrPutExceptionIntoBadMap(
|
||||||
|
ScriptInvokerForNodeAndStatement scriptInvokerForNodeAndStatement, @Assisted NodeMetadata node,
|
||||||
|
@Assisted @Nullable Statement statement, @Assisted RunScriptOptions options,
|
||||||
|
@Assisted Map<NodeMetadata, ExecResponse> goodNodes, @Assisted Map<NodeMetadata, Exception> badNodes) {
|
||||||
|
this.statement = checkNotNull(statement, "statement");
|
||||||
|
this.scriptInvokerForNodeAndStatement = checkNotNull(scriptInvokerForNodeAndStatement,
|
||||||
|
"scriptInvokerForNodeAndStatement");
|
||||||
|
this.node = node;
|
||||||
|
this.badNodes = checkNotNull(badNodes, "badNodes");
|
||||||
|
this.goodNodes = checkNotNull(goodNodes, "goodNodes");
|
||||||
|
this.options = checkNotNull(options, "options");
|
||||||
|
}
|
||||||
|
|
||||||
|
@AssistedInject
|
||||||
|
public RunStatementOnNodeAndAddToGoodMapOrPutExceptionIntoBadMap(
|
||||||
|
ScriptInvokerForNodeAndStatement scriptInvokerForNodeAndStatement, @Assisted @Nullable Statement statement,
|
||||||
|
@Assisted RunScriptOptions options, @Assisted Map<NodeMetadata, ExecResponse> goodNodes,
|
||||||
|
@Assisted Map<NodeMetadata, Exception> badNodes) {
|
||||||
|
this(scriptInvokerForNodeAndStatement, null, statement, options, goodNodes, badNodes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void call() {
|
||||||
|
checkState(node != null, "node must be set");
|
||||||
|
checkState(!tainted, "this object is not designed to be reused: %s", toString());
|
||||||
|
tainted = true;
|
||||||
|
try {
|
||||||
|
StartInitScriptOnNode scriptInstructions = scriptInvokerForNodeAndStatement.create(node, statement, options);
|
||||||
|
ExecResponse exec = scriptInstructions.call();
|
||||||
|
logger.trace("<< script output for node(%s): %s", node.getId(), exec);
|
||||||
|
logger.debug("<< options applied node(%s)", node.getId());
|
||||||
|
goodNodes.put(node, exec);
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error(e, "<< problem applying options to node(%s): ", node.getId(), getRootCause(e).getMessage());
|
||||||
|
badNodes.put(node, e);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 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.strategy;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import org.jclouds.compute.callables.StartInitScriptOnNode;
|
||||||
|
import org.jclouds.compute.domain.NodeMetadata;
|
||||||
|
import org.jclouds.compute.options.RunScriptOptions;
|
||||||
|
import org.jclouds.scriptbuilder.domain.Statement;
|
||||||
|
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Singleton
|
||||||
|
public class ScriptInvokerForNodeAndStatement {
|
||||||
|
|
||||||
|
private final StartInitScriptOnNode.Factory initAndStartScriptOnNodeFactory;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public ScriptInvokerForNodeAndStatement(StartInitScriptOnNode.Factory initAndStartScriptOnNodeFactory) {
|
||||||
|
this.initAndStartScriptOnNodeFactory = checkNotNull(initAndStartScriptOnNodeFactory,
|
||||||
|
"initAndStartScriptOnNodeFactory");
|
||||||
|
}
|
||||||
|
|
||||||
|
public StartInitScriptOnNode create(NodeMetadata node, Statement runScript, RunScriptOptions options) {
|
||||||
|
checkNotNull(node, "node");
|
||||||
|
checkNotNull(runScript, "runScript");
|
||||||
|
checkNotNull(options, "options");
|
||||||
|
return options.shouldBlockOnComplete() ? initAndStartScriptOnNodeFactory.blockOnComplete(node, options
|
||||||
|
.getTaskName(), runScript, options.shouldRunAsRoot()) : initAndStartScriptOnNodeFactory
|
||||||
|
.dontBlockOnComplete(node, options.getTaskName(), runScript, options.shouldRunAsRoot());
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,6 +19,13 @@
|
||||||
|
|
||||||
package org.jclouds.compute.strategy.impl;
|
package org.jclouds.compute.strategy.impl;
|
||||||
|
|
||||||
|
import static com.google.common.base.Objects.toStringHelper;
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
import static com.google.common.collect.Iterables.any;
|
||||||
|
import static com.google.common.collect.Maps.newLinkedHashMap;
|
||||||
|
import static com.google.common.collect.Sets.newLinkedHashSet;
|
||||||
|
import static org.jclouds.concurrent.Futures.compose;
|
||||||
|
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
@ -32,20 +39,19 @@ import javax.inject.Named;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import org.jclouds.Constants;
|
import org.jclouds.Constants;
|
||||||
|
import org.jclouds.compute.config.CustomizationResponse;
|
||||||
import org.jclouds.compute.domain.ComputeMetadata;
|
import org.jclouds.compute.domain.ComputeMetadata;
|
||||||
import org.jclouds.compute.domain.NodeMetadata;
|
import org.jclouds.compute.domain.NodeMetadata;
|
||||||
import org.jclouds.compute.domain.Template;
|
import org.jclouds.compute.domain.Template;
|
||||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||||
import org.jclouds.compute.strategy.AddNodeWithTagStrategy;
|
import org.jclouds.compute.strategy.AddNodeWithTagStrategy;
|
||||||
|
import org.jclouds.compute.strategy.CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap;
|
||||||
import org.jclouds.compute.strategy.ListNodesStrategy;
|
import org.jclouds.compute.strategy.ListNodesStrategy;
|
||||||
import org.jclouds.compute.strategy.RunNodesAndAddToSetStrategy;
|
import org.jclouds.compute.strategy.RunNodesAndAddToSetStrategy;
|
||||||
import org.jclouds.compute.util.ComputeUtils;
|
|
||||||
import org.jclouds.logging.Logger;
|
import org.jclouds.logging.Logger;
|
||||||
|
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Multimap;
|
||||||
import com.google.common.collect.Maps;
|
|
||||||
import com.google.common.collect.Sets;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* creates futures that correlate to
|
* creates futures that correlate to
|
||||||
|
@ -54,24 +60,54 @@ import com.google.common.collect.Sets;
|
||||||
*/
|
*/
|
||||||
@Singleton
|
@Singleton
|
||||||
public class EncodeTagIntoNameRunNodesAndAddToSetStrategy implements RunNodesAndAddToSetStrategy {
|
public class EncodeTagIntoNameRunNodesAndAddToSetStrategy implements RunNodesAndAddToSetStrategy {
|
||||||
|
|
||||||
|
private class AddNode implements Callable<NodeMetadata> {
|
||||||
|
private final String name;
|
||||||
|
private final String tag;
|
||||||
|
private final Template template;
|
||||||
|
|
||||||
|
private AddNode(String name, String tag, Template template) {
|
||||||
|
this.name = checkNotNull(name, "name");
|
||||||
|
this.tag = checkNotNull(tag, "tag");
|
||||||
|
this.template = checkNotNull(template, "template");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NodeMetadata call() throws Exception {
|
||||||
|
NodeMetadata node = null;
|
||||||
|
logger.debug(">> starting node(%s) tag(%s)", name, tag);
|
||||||
|
node = addNodeWithTagStrategy.addNodeWithTag(tag, name, template);
|
||||||
|
logger.debug("<< %s node(%s)", node.getState(), node.getId());
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return toStringHelper(this).add("name", name).add("tag", tag).add("template", template).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||||
protected Logger logger = Logger.NULL;
|
protected Logger logger = Logger.NULL;
|
||||||
protected final AddNodeWithTagStrategy addNodeWithTagStrategy;
|
protected final AddNodeWithTagStrategy addNodeWithTagStrategy;
|
||||||
protected final ListNodesStrategy listNodesStrategy;
|
protected final ListNodesStrategy listNodesStrategy;
|
||||||
protected final String nodeNamingConvention;
|
protected final String nodeNamingConvention;
|
||||||
protected final ComputeUtils utils;
|
|
||||||
protected final ExecutorService executor;
|
protected final ExecutorService executor;
|
||||||
|
protected final CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap.Factory customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
protected EncodeTagIntoNameRunNodesAndAddToSetStrategy(AddNodeWithTagStrategy addNodeWithTagStrategy,
|
protected EncodeTagIntoNameRunNodesAndAddToSetStrategy(
|
||||||
ListNodesStrategy listNodesStrategy, @Named("NAMING_CONVENTION") String nodeNamingConvention,
|
AddNodeWithTagStrategy addNodeWithTagStrategy,
|
||||||
ComputeUtils utils, @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) {
|
ListNodesStrategy listNodesStrategy,
|
||||||
|
@Named("NAMING_CONVENTION") String nodeNamingConvention,
|
||||||
|
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor,
|
||||||
|
CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap.Factory customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory) {
|
||||||
this.addNodeWithTagStrategy = addNodeWithTagStrategy;
|
this.addNodeWithTagStrategy = addNodeWithTagStrategy;
|
||||||
this.listNodesStrategy = listNodesStrategy;
|
this.listNodesStrategy = listNodesStrategy;
|
||||||
this.nodeNamingConvention = nodeNamingConvention;
|
this.nodeNamingConvention = nodeNamingConvention;
|
||||||
this.utils = utils;
|
|
||||||
this.executor = executor;
|
this.executor = executor;
|
||||||
|
this.customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory = customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -79,22 +115,13 @@ public class EncodeTagIntoNameRunNodesAndAddToSetStrategy implements RunNodesAnd
|
||||||
* simultaneously runs the nodes and applies options to them.
|
* simultaneously runs the nodes and applies options to them.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Map<?, Future<Void>> execute(final String tag, final int count, final Template template,
|
public Map<?, Future<Void>> execute(String tag, int count, Template template, Set<NodeMetadata> goodNodes,
|
||||||
final Set<NodeMetadata> nodes, final Map<NodeMetadata, Exception> badNodes) {
|
Map<NodeMetadata, Exception> badNodes, Multimap<NodeMetadata, CustomizationResponse> customizationResponses) {
|
||||||
Map<String, Future<Void>> responses = Maps.newHashMap();
|
Map<String, Future<Void>> responses = newLinkedHashMap();
|
||||||
for (final String name : getNextNames(tag, template, count)) {
|
for (String name : getNextNames(tag, template, count)) {
|
||||||
responses.put(name, executor.submit(new Callable<Void>() {
|
responses.put(name, compose(executor.submit(new AddNode(name, tag, template)),
|
||||||
@Override
|
customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory.create(template.getOptions(),
|
||||||
public Void call() throws Exception {
|
goodNodes, badNodes, customizationResponses), executor));
|
||||||
NodeMetadata node = null;
|
|
||||||
logger.debug(">> starting node(%s) tag(%s)", name, tag);
|
|
||||||
node = addNodeWithTagStrategy.addNodeWithTag(tag, name, template);
|
|
||||||
logger.debug("<< %s node(%s)", node.getState(), node.getId());
|
|
||||||
utils.runOptionsOnNodeAndAddToGoodSetOrPutExceptionIntoBadMap(node, badNodes, nodes,
|
|
||||||
template.getOptions()).call();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
return responses;
|
return responses;
|
||||||
}
|
}
|
||||||
|
@ -110,13 +137,13 @@ public class EncodeTagIntoNameRunNodesAndAddToSetStrategy implements RunNodesAnd
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
protected Set<String> getNextNames(final String tag, final Template template, int count) {
|
protected Set<String> getNextNames(final String tag, final Template template, int count) {
|
||||||
Set<String> names = Sets.newHashSet();
|
Set<String> names = newLinkedHashSet();
|
||||||
Iterable<? extends ComputeMetadata> currentNodes = listNodesStrategy.listNodes();
|
Iterable<? extends ComputeMetadata> currentNodes = listNodesStrategy.listNodes();
|
||||||
int maxTries = 100;
|
int maxTries = 100;
|
||||||
int currentTries = 0;
|
int currentTries = 0;
|
||||||
while (names.size() < count && currentTries++ < maxTries) {
|
while (names.size() < count && currentTries++ < maxTries) {
|
||||||
final String name = getNextName(tag, template);
|
final String name = getNextName(tag, template);
|
||||||
if (!Iterables.any(currentNodes, new Predicate<ComputeMetadata>() {
|
if (!any(currentNodes, new Predicate<ComputeMetadata>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(ComputeMetadata input) {
|
public boolean apply(ComputeMetadata input) {
|
||||||
|
|
|
@ -31,12 +31,14 @@ import static org.jclouds.scriptbuilder.domain.Statements.pipeHttpResponseToBash
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.Formatter;
|
import java.util.Formatter;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
|
||||||
import java.util.NoSuchElementException;
|
import java.util.NoSuchElementException;
|
||||||
import java.util.concurrent.Callable;
|
import java.util.Map.Entry;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.inject.Named;
|
||||||
|
|
||||||
import org.jclouds.compute.ComputeServiceContextBuilder;
|
import org.jclouds.compute.ComputeServiceContextBuilder;
|
||||||
import org.jclouds.compute.domain.ComputeMetadata;
|
import org.jclouds.compute.domain.ComputeMetadata;
|
||||||
import org.jclouds.compute.domain.Hardware;
|
import org.jclouds.compute.domain.Hardware;
|
||||||
|
@ -45,13 +47,13 @@ import org.jclouds.compute.domain.OsFamily;
|
||||||
import org.jclouds.compute.domain.Processor;
|
import org.jclouds.compute.domain.Processor;
|
||||||
import org.jclouds.compute.domain.Volume;
|
import org.jclouds.compute.domain.Volume;
|
||||||
import org.jclouds.compute.predicates.RetryIfSocketNotYetOpen;
|
import org.jclouds.compute.predicates.RetryIfSocketNotYetOpen;
|
||||||
|
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||||
import org.jclouds.http.HttpRequest;
|
import org.jclouds.http.HttpRequest;
|
||||||
import org.jclouds.logging.Logger;
|
import org.jclouds.logging.Logger;
|
||||||
import org.jclouds.net.IPSocket;
|
import org.jclouds.net.IPSocket;
|
||||||
import org.jclouds.rest.Providers;
|
import org.jclouds.rest.Providers;
|
||||||
import org.jclouds.scriptbuilder.domain.Statement;
|
import org.jclouds.scriptbuilder.domain.Statement;
|
||||||
import org.jclouds.scriptbuilder.domain.Statements;
|
import org.jclouds.scriptbuilder.domain.Statements;
|
||||||
import org.jclouds.ssh.SshClient;
|
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
|
@ -104,9 +106,23 @@ public class ComputeServiceUtils {
|
||||||
return extractZipIntoDirectory(new HttpRequest("GET", zip), directory);
|
return extractZipIntoDirectory(new HttpRequest("GET", zip), directory);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||||
|
protected static Logger logger = Logger.NULL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @return NOTAG#+from if tag cannot be parsed
|
||||||
|
*/
|
||||||
public static String parseTagFromName(String from) {
|
public static String parseTagFromName(String from) {
|
||||||
Matcher matcher = DELIMETED_BY_HYPHEN_ENDING_IN_HYPHEN_HEX.matcher(from);
|
Matcher matcher = DELIMETED_BY_HYPHEN_ENDING_IN_HYPHEN_HEX.matcher(from);
|
||||||
return matcher.find() ? matcher.group(1) : "NOTAG#" + from;
|
String returnVal = matcher.find() ? matcher.group(1) : "NOTAG#" + from;
|
||||||
|
if (logger.isTraceEnabled()) {
|
||||||
|
if (returnVal.startsWith("NOTAG#"))
|
||||||
|
logger.trace("failed to parse tag from name %s", from);
|
||||||
|
}
|
||||||
|
return returnVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static double getCores(Hardware input) {
|
public static double getCores(Hardware input) {
|
||||||
|
@ -147,8 +163,8 @@ public class ComputeServiceUtils {
|
||||||
Formatter fmt = new Formatter().format("Execution failures:%n%n");
|
Formatter fmt = new Formatter().format("Execution failures:%n%n");
|
||||||
int index = 1;
|
int index = 1;
|
||||||
for (Entry<?, Exception> errorMessage : executionExceptions.entrySet()) {
|
for (Entry<?, Exception> errorMessage : executionExceptions.entrySet()) {
|
||||||
fmt.format("%s) %s on %s:%n%s%n%n", index++, errorMessage.getValue().getClass().getSimpleName(),
|
fmt.format("%s) %s on %s:%n%s%n%n", index++, errorMessage.getValue().getClass().getSimpleName(), errorMessage
|
||||||
errorMessage.getKey(), getStackTraceAsString(errorMessage.getValue()));
|
.getKey(), getStackTraceAsString(errorMessage.getValue()));
|
||||||
}
|
}
|
||||||
return fmt.format("%s error[s]", executionExceptions.size()).toString();
|
return fmt.format("%s error[s]", executionExceptions.size()).toString();
|
||||||
}
|
}
|
||||||
|
@ -173,12 +189,6 @@ public class ComputeServiceUtils {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static interface SshCallable<T> extends Callable<T> {
|
|
||||||
NodeMetadata getNode();
|
|
||||||
|
|
||||||
void setConnection(SshClient ssh, Logger logger);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Iterable<String> getSupportedProviders() {
|
public static Iterable<String> getSupportedProviders() {
|
||||||
return Providers.getSupportedProvidersOfType(ComputeServiceContextBuilder.class);
|
return Providers.getSupportedProvidersOfType(ComputeServiceContextBuilder.class);
|
||||||
}
|
}
|
||||||
|
@ -188,8 +198,7 @@ public class ComputeServiceUtils {
|
||||||
checkNodeHasIps(node);
|
checkNodeHasIps(node);
|
||||||
IPSocket socket = null;
|
IPSocket socket = null;
|
||||||
try {
|
try {
|
||||||
socket = find(
|
socket = find(transform(concat(node.getPublicAddresses(), node.getPrivateAddresses()),
|
||||||
transform(concat(node.getPublicAddresses(), node.getPrivateAddresses()),
|
|
||||||
new Function<String, IPSocket>() {
|
new Function<String, IPSocket>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -19,53 +19,24 @@
|
||||||
|
|
||||||
package org.jclouds.compute.util;
|
package org.jclouds.compute.util;
|
||||||
|
|
||||||
import static com.google.common.base.Throwables.getRootCause;
|
import static com.google.common.collect.Maps.newLinkedHashMap;
|
||||||
import static com.google.common.base.Throwables.propagate;
|
|
||||||
import static com.google.common.collect.Iterables.size;
|
|
||||||
import static com.google.common.collect.Lists.newArrayList;
|
|
||||||
import static com.google.common.collect.Maps.newHashMap;
|
|
||||||
import static org.jclouds.compute.util.ComputeServiceUtils.findReachableSocketOnNode;
|
|
||||||
import static org.jclouds.concurrent.FutureIterables.awaitCompletion;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.Callable;
|
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.inject.Inject;
|
||||||
import javax.annotation.Resource;
|
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
import javax.inject.Provider;
|
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import org.jclouds.Constants;
|
import org.jclouds.Constants;
|
||||||
import org.jclouds.compute.callables.InitAndStartScriptOnNode;
|
import org.jclouds.compute.config.CustomizationResponse;
|
||||||
import org.jclouds.compute.callables.RunScriptOnNode;
|
|
||||||
import org.jclouds.compute.domain.NodeMetadata;
|
import org.jclouds.compute.domain.NodeMetadata;
|
||||||
import org.jclouds.compute.domain.NodeMetadataBuilder;
|
|
||||||
import org.jclouds.compute.options.RunScriptOptions;
|
|
||||||
import org.jclouds.compute.options.TemplateOptions;
|
import org.jclouds.compute.options.TemplateOptions;
|
||||||
import org.jclouds.compute.predicates.RetryIfSocketNotYetOpen;
|
import org.jclouds.compute.strategy.CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap;
|
||||||
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.GetNodeMetadataStrategy;
|
|
||||||
import org.jclouds.compute.util.ComputeServiceUtils.SshCallable;
|
|
||||||
import org.jclouds.logging.Logger;
|
|
||||||
import org.jclouds.scriptbuilder.InitBuilder;
|
|
||||||
import org.jclouds.scriptbuilder.domain.AuthorizeRSAPublicKey;
|
|
||||||
import org.jclouds.scriptbuilder.domain.InstallRSAPrivateKey;
|
|
||||||
import org.jclouds.scriptbuilder.domain.Statement;
|
|
||||||
import org.jclouds.scriptbuilder.domain.StatementList;
|
|
||||||
import org.jclouds.ssh.ExecResponse;
|
|
||||||
import org.jclouds.ssh.SshClient;
|
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.collect.Multimap;
|
||||||
import com.google.common.base.Predicate;
|
|
||||||
import com.google.inject.Inject;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -73,168 +44,26 @@ import com.google.inject.Inject;
|
||||||
*/
|
*/
|
||||||
@Singleton
|
@Singleton
|
||||||
public class ComputeUtils {
|
public class ComputeUtils {
|
||||||
@Resource
|
private final CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap.Factory customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory;
|
||||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
private final ExecutorService executor;
|
||||||
protected Logger logger = Logger.NULL;
|
|
||||||
protected final Function<NodeMetadata, SshClient> sshFactory;
|
|
||||||
protected final Predicate<CommandUsingClient> runScriptNotRunning;
|
|
||||||
protected final Provider<RetryIfSocketNotYetOpen> socketTester;
|
|
||||||
protected final ExecutorService executor;
|
|
||||||
protected final Predicate<NodeMetadata> nodeRunning;
|
|
||||||
protected final GetNodeMetadataStrategy getNode;
|
|
||||||
protected final Timeouts timeouts;
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public ComputeUtils(Provider<RetryIfSocketNotYetOpen> socketTester, Function<NodeMetadata, SshClient> sshFactory,
|
public ComputeUtils(
|
||||||
@Named("SCRIPT_COMPLETE") Predicate<CommandUsingClient> runScriptNotRunning, GetNodeMetadataStrategy getNode,
|
CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap.Factory customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory,
|
||||||
Timeouts timeouts, @Named("NODE_RUNNING") Predicate<NodeMetadata> nodeRunning,
|
|
||||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) {
|
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) {
|
||||||
this.sshFactory = sshFactory;
|
this.customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory = customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory;
|
||||||
this.nodeRunning = nodeRunning;
|
|
||||||
this.timeouts = timeouts;
|
|
||||||
this.getNode = getNode;
|
|
||||||
this.socketTester = socketTester;
|
|
||||||
this.runScriptNotRunning = runScriptNotRunning;
|
|
||||||
this.executor = executor;
|
this.executor = executor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<?, Future<Void>> runOptionsOnNodesAndAddToGoodSetOrPutExceptionIntoBadMap(final TemplateOptions options,
|
public Map<?, Future<Void>> customizeNodesAndAddToGoodMapOrPutExceptionIntoBadMap(TemplateOptions options,
|
||||||
Iterable<NodeMetadata> runningNodes, final Set<NodeMetadata> goodNodes,
|
Iterable<NodeMetadata> runningNodes, Set<NodeMetadata> goodNodes, Map<NodeMetadata, Exception> badNodes,
|
||||||
final Map<NodeMetadata, Exception> badNodes) {
|
Multimap<NodeMetadata, CustomizationResponse> customizationResponses) {
|
||||||
Map<NodeMetadata, Future<Void>> responses = newHashMap();
|
Map<NodeMetadata, Future<Void>> responses = newLinkedHashMap();
|
||||||
for (final NodeMetadata node : runningNodes) {
|
for (NodeMetadata node : runningNodes) {
|
||||||
responses.put(node, executor.submit(runOptionsOnNodeAndAddToGoodSetOrPutExceptionIntoBadMap(node, badNodes,
|
responses.put(node, executor.submit(customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory.create(
|
||||||
goodNodes, options)));
|
options, node, goodNodes, badNodes, customizationResponses)));
|
||||||
}
|
}
|
||||||
return responses;
|
return responses;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Callable<Void> runOptionsOnNodeAndAddToGoodSetOrPutExceptionIntoBadMap(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 {
|
|
||||||
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.getId(), getRootCause(e).getMessage());
|
|
||||||
badNodes.put(node, e);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public NodeMetadata runOptionsOnNode(NodeMetadata node, TemplateOptions options) {
|
|
||||||
if (!options.shouldBlockUntilRunning())
|
|
||||||
return node;
|
|
||||||
|
|
||||||
if (nodeRunning.apply(node))
|
|
||||||
node = NodeMetadataBuilder.fromNodeMetadata(getNode.getNode(node.getId())).credentials(node.getCredentials())
|
|
||||||
.build();
|
|
||||||
else
|
|
||||||
throw new IllegalStateException(String.format(
|
|
||||||
"node didn't achieve the state running on node %s within %d seconds, final state: %s", node.getId(),
|
|
||||||
timeouts.nodeRunning / 1000, node.getState()));
|
|
||||||
List<Statement> bootstrap = newArrayList();
|
|
||||||
if (options.getPublicKey() != null)
|
|
||||||
bootstrap.add(new AuthorizeRSAPublicKey(options.getPublicKey()));
|
|
||||||
if (options.getRunScript() != null)
|
|
||||||
bootstrap.add(options.getRunScript());
|
|
||||||
if (options.getPrivateKey() != null)
|
|
||||||
bootstrap.add(new InstallRSAPrivateKey(options.getPrivateKey()));
|
|
||||||
if (bootstrap.size() >= 1) {
|
|
||||||
if (options.getTaskName() == null && !(options.getRunScript() instanceof InitBuilder))
|
|
||||||
options.nameTask("bootstrap");
|
|
||||||
runScriptOnNode(node, bootstrap.size() == 1 ? bootstrap.get(0) : new StatementList(bootstrap), options);
|
|
||||||
}
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ExecResponse runScriptOnNode(NodeMetadata node, Statement runScript, RunScriptOptions options) {
|
|
||||||
InitAndStartScriptOnNode callable = generateScript(node, runScript, options);
|
|
||||||
ExecResponse response;
|
|
||||||
SshClient ssh = sshFactory.apply(node);
|
|
||||||
try {
|
|
||||||
ssh.connect();
|
|
||||||
callable.setConnection(ssh, logger);
|
|
||||||
response = callable.call();
|
|
||||||
} finally {
|
|
||||||
if (ssh != null)
|
|
||||||
ssh.disconnect();
|
|
||||||
}
|
|
||||||
if (options.getPort() > 0) {
|
|
||||||
findReachableSocketOnNode(socketTester.get().seconds(options.getSeconds()), node, options.getPort());
|
|
||||||
}
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
|
|
||||||
public InitAndStartScriptOnNode generateScript(NodeMetadata node, Statement script, RunScriptOptions options) {
|
|
||||||
return options.shouldBlockOnComplete() ? new RunScriptOnNode(runScriptNotRunning, node, options.getTaskName(),
|
|
||||||
script, options.shouldRunAsRoot()) : new InitAndStartScriptOnNode(node, options.getTaskName(), script,
|
|
||||||
options.shouldRunAsRoot());
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<SshCallable<?>, ?> runCallablesOnNode(NodeMetadata node, Iterable<SshCallable<?>> parallel,
|
|
||||||
@Nullable SshCallable<?> last) {
|
|
||||||
SshClient ssh = sshFactory.apply(node);
|
|
||||||
try {
|
|
||||||
ssh.connect();
|
|
||||||
return runTasksUsingSshClient(parallel, last, ssh);
|
|
||||||
} finally {
|
|
||||||
if (ssh != null)
|
|
||||||
ssh.disconnect();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Map<SshCallable<?>, ?> runTasksUsingSshClient(Iterable<SshCallable<?>> parallel, SshCallable<?> last,
|
|
||||||
SshClient ssh) {
|
|
||||||
Map<SshCallable<?>, Object> responses = newHashMap();
|
|
||||||
if (size(parallel) > 0) {
|
|
||||||
responses.putAll(runCallablesUsingSshClient(parallel, ssh));
|
|
||||||
}
|
|
||||||
if (last != null) {
|
|
||||||
last.setConnection(ssh, logger);
|
|
||||||
try {
|
|
||||||
responses.put(last, last.call());
|
|
||||||
} catch (Exception e) {
|
|
||||||
propagate(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return responses;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO refactor
|
|
||||||
private Map<SshCallable<?>, Object> runCallablesUsingSshClient(Iterable<SshCallable<?>> parallel, SshClient ssh) {
|
|
||||||
Map<SshCallable<?>, Future<?>> parallelResponses = newHashMap();
|
|
||||||
|
|
||||||
for (SshCallable<?> callable : parallel) {
|
|
||||||
callable.setConnection(ssh, logger);
|
|
||||||
parallelResponses.put(callable, executor.submit(callable));
|
|
||||||
}
|
|
||||||
|
|
||||||
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));
|
|
||||||
Map<SshCallable<?>, Object> newresponses = transform(parallelResponses);
|
|
||||||
return newresponses;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public <T> Map<SshCallable<?>, T> transform(Map<SshCallable<?>, Future<?>> responses) {
|
|
||||||
Map<SshCallable<?>, T> actualResponses = newHashMap();
|
|
||||||
for (Map.Entry<SshCallable<?>, Future<?>> entry : responses.entrySet()) {
|
|
||||||
try {
|
|
||||||
actualResponses.put(entry.getKey(), (T) entry.getValue().get());
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
throw propagate(e);
|
|
||||||
} catch (ExecutionException e) {
|
|
||||||
throw propagate(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return actualResponses;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,10 +19,12 @@
|
||||||
|
|
||||||
package org.jclouds.ssh;
|
package org.jclouds.ssh;
|
||||||
|
|
||||||
|
import org.jclouds.compute.config.CustomizationResponse;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public class ExecResponse {
|
public class ExecResponse implements CustomizationResponse {
|
||||||
|
|
||||||
private final String error;
|
private final String error;
|
||||||
private final String output;
|
private final String output;
|
||||||
|
|
|
@ -38,7 +38,6 @@ import static org.jclouds.compute.predicates.NodePredicates.all;
|
||||||
import static org.jclouds.compute.predicates.NodePredicates.runningWithTag;
|
import static org.jclouds.compute.predicates.NodePredicates.runningWithTag;
|
||||||
import static org.jclouds.compute.predicates.NodePredicates.withTag;
|
import static org.jclouds.compute.predicates.NodePredicates.withTag;
|
||||||
import static org.jclouds.compute.util.ComputeServiceUtils.getCores;
|
import static org.jclouds.compute.util.ComputeServiceUtils.getCores;
|
||||||
import static org.jclouds.io.Payloads.newStringPayload;
|
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
import static org.testng.Assert.assertNotNull;
|
import static org.testng.Assert.assertNotNull;
|
||||||
|
|
||||||
|
@ -75,7 +74,6 @@ import org.jclouds.predicates.RetryablePredicate;
|
||||||
import org.jclouds.predicates.SocketOpen;
|
import org.jclouds.predicates.SocketOpen;
|
||||||
import org.jclouds.rest.AuthorizationException;
|
import org.jclouds.rest.AuthorizationException;
|
||||||
import org.jclouds.rest.RestContextFactory;
|
import org.jclouds.rest.RestContextFactory;
|
||||||
import org.jclouds.scriptbuilder.domain.OsFamily;
|
|
||||||
import org.jclouds.ssh.ExecResponse;
|
import org.jclouds.ssh.ExecResponse;
|
||||||
import org.jclouds.ssh.SshClient;
|
import org.jclouds.ssh.SshClient;
|
||||||
import org.jclouds.ssh.SshException;
|
import org.jclouds.ssh.SshException;
|
||||||
|
@ -159,8 +157,8 @@ public abstract class BaseComputeServiceLiveTest {
|
||||||
if (context != null)
|
if (context != null)
|
||||||
context.close();
|
context.close();
|
||||||
Properties props = setupProperties();
|
Properties props = setupProperties();
|
||||||
context = new ComputeServiceContextFactory(getRestProperties()).createContext(provider,
|
context = new ComputeServiceContextFactory(getRestProperties()).createContext(provider, ImmutableSet.of(
|
||||||
ImmutableSet.of(new Log4JLoggingModule(), getSshModule()), props);
|
new Log4JLoggingModule(), getSshModule()), props);
|
||||||
client = context.getComputeService();
|
client = context.getComputeService();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,8 +178,8 @@ public abstract class BaseComputeServiceLiveTest {
|
||||||
public void testCorrectAuthException() throws Exception {
|
public void testCorrectAuthException() throws Exception {
|
||||||
ComputeServiceContext context = null;
|
ComputeServiceContext context = null;
|
||||||
try {
|
try {
|
||||||
context = new ComputeServiceContextFactory().createContext(provider, "MOMMA", "MIA",
|
context = new ComputeServiceContextFactory().createContext(provider, "MOMMA", "MIA", ImmutableSet
|
||||||
ImmutableSet.<Module> of(new Log4JLoggingModule()));
|
.<Module> of(new Log4JLoggingModule()));
|
||||||
context.getComputeService().listNodes();
|
context.getComputeService().listNodes();
|
||||||
} catch (AuthorizationException e) {
|
} catch (AuthorizationException e) {
|
||||||
throw e;
|
throw e;
|
||||||
|
@ -294,8 +292,8 @@ public abstract class BaseComputeServiceLiveTest {
|
||||||
protected void checkOsMatchesTemplate(NodeMetadata node) {
|
protected void checkOsMatchesTemplate(NodeMetadata node) {
|
||||||
if (node.getOperatingSystem() != null)
|
if (node.getOperatingSystem() != null)
|
||||||
assert node.getOperatingSystem().getFamily().equals(template.getImage().getOperatingSystem().getFamily()) : String
|
assert node.getOperatingSystem().getFamily().equals(template.getImage().getOperatingSystem().getFamily()) : String
|
||||||
.format("expecting family %s but got %s", template.getImage().getOperatingSystem().getFamily(),
|
.format("expecting family %s but got %s", template.getImage().getOperatingSystem().getFamily(), node
|
||||||
node.getOperatingSystem());
|
.getOperatingSystem());
|
||||||
}
|
}
|
||||||
|
|
||||||
void assertLocationSameOrChild(Location test, Location expected) {
|
void assertLocationSameOrChild(Location test, Location expected) {
|
||||||
|
@ -329,9 +327,8 @@ public abstract class BaseComputeServiceLiveTest {
|
||||||
protected Map<? extends NodeMetadata, ExecResponse> runScriptWithCreds(final String tag, OperatingSystem os,
|
protected Map<? extends NodeMetadata, ExecResponse> runScriptWithCreds(final String tag, OperatingSystem os,
|
||||||
Credentials creds) throws RunScriptOnNodesException {
|
Credentials creds) throws RunScriptOnNodesException {
|
||||||
try {
|
try {
|
||||||
return client.runScriptOnNodesMatching(runningWithTag(tag),
|
return client.runScriptOnNodesMatching(runningWithTag(tag), buildScript(os), overrideCredentialsWith(creds)
|
||||||
newStringPayload(buildScript(os).render(OsFamily.UNIX)),
|
.nameTask("runScriptWithCreds"));
|
||||||
overrideCredentialsWith(creds).nameTask("runScriptWithCreds"));
|
|
||||||
} catch (SshException e) {
|
} catch (SshException e) {
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
@ -361,8 +358,8 @@ public abstract class BaseComputeServiceLiveTest {
|
||||||
|
|
||||||
@Test(enabled = true, dependsOnMethods = "testCreateAnotherNodeWithANewContextToEnsureSharedMemIsntRequired")
|
@Test(enabled = true, dependsOnMethods = "testCreateAnotherNodeWithANewContextToEnsureSharedMemIsntRequired")
|
||||||
public void testGet() throws Exception {
|
public void testGet() throws Exception {
|
||||||
Map<String, ? extends NodeMetadata> metadataMap = newLinkedHashMap(uniqueIndex(
|
Map<String, ? extends NodeMetadata> metadataMap = newLinkedHashMap(uniqueIndex(filter(client
|
||||||
filter(client.listNodesDetailsMatching(all()), and(withTag(tag), not(TERMINATED))),
|
.listNodesDetailsMatching(all()), and(withTag(tag), not(TERMINATED))),
|
||||||
new Function<NodeMetadata, String>() {
|
new Function<NodeMetadata, String>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -453,7 +450,9 @@ public abstract class BaseComputeServiceLiveTest {
|
||||||
|
|
||||||
@Test(enabled = true, dependsOnMethods = { "testListNodes", "testGetNodesWithDetails" })
|
@Test(enabled = true, dependsOnMethods = { "testListNodes", "testGetNodesWithDetails" })
|
||||||
public void testDestroyNodes() {
|
public void testDestroyNodes() {
|
||||||
client.destroyNodesMatching(withTag(tag));
|
int toDestroy = refreshNodes().size();
|
||||||
|
Set<? extends NodeMetadata> destroyed = client.destroyNodesMatching(withTag(tag));
|
||||||
|
assertEquals(toDestroy, destroyed.size());
|
||||||
for (NodeMetadata node : filter(client.listNodesDetailsMatching(all()), withTag(tag))) {
|
for (NodeMetadata node : filter(client.listNodesDetailsMatching(all()), withTag(tag))) {
|
||||||
assert node.getState() == NodeState.TERMINATED : node;
|
assert node.getState() == NodeState.TERMINATED : node;
|
||||||
assertEquals(context.getCredentialStore().get("node#" + node.getId()), null);
|
assertEquals(context.getCredentialStore().get("node#" + node.getId()), null);
|
||||||
|
|
|
@ -361,17 +361,17 @@ public class StubComputeServiceIntegrationTest extends BaseComputeServiceLiveTes
|
||||||
super.testTemplateMatch();
|
super.testTemplateMatch();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Test(enabled = true, dependsOnMethods = "testSuspendResume")
|
||||||
public void testGetNodesWithDetails() throws Exception {
|
public void testGetNodesWithDetails() throws Exception {
|
||||||
super.testGetNodesWithDetails();
|
super.testGetNodesWithDetails();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Test(enabled = true, dependsOnMethods = "testSuspendResume")
|
||||||
public void testListNodes() throws Exception {
|
public void testListNodes() throws Exception {
|
||||||
super.testListNodes();
|
super.testListNodes();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Test(enabled = true, dependsOnMethods = { "testListNodes", "testGetNodesWithDetails" })
|
||||||
public void testDestroyNodes() {
|
public void testDestroyNodes() {
|
||||||
super.testDestroyNodes();
|
super.testDestroyNodes();
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.jclouds.compute.util;
|
package org.jclouds.compute.util;
|
||||||
|
|
||||||
|
import static org.jclouds.compute.util.ComputeServiceUtils.parseTagFromName;
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
@ -38,6 +39,11 @@ import com.google.common.collect.ImmutableMultimap;
|
||||||
@Test(groups = "unit")
|
@Test(groups = "unit")
|
||||||
public class ComputeServiceUtilsTest {
|
public class ComputeServiceUtilsTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testParseTagFromName() {
|
||||||
|
assertEquals(parseTagFromName("gogrid--849"), "gogrid-");
|
||||||
|
|
||||||
|
}
|
||||||
@Test
|
@Test
|
||||||
public void testExecHttpResponse() {
|
public void testExecHttpResponse() {
|
||||||
HttpRequest request = new HttpRequest("GET", URI.create("https://adriancolehappy.s3.amazonaws.com/java/install"),
|
HttpRequest request = new HttpRequest("GET", URI.create("https://adriancolehappy.s3.amazonaws.com/java/install"),
|
||||||
|
|
|
@ -83,7 +83,6 @@ echo nameserver 208.67.222.222 >> /etc/resolv.conf
|
||||||
rm -rf /var/cache/apt /usr/lib/vmware-tools
|
rm -rf /var/cache/apt /usr/lib/vmware-tools
|
||||||
echo "export PATH=\"\$JAVA_HOME/bin/:\$PATH\"" >> /root/.bashrc
|
echo "export PATH=\"\$JAVA_HOME/bin/:\$PATH\"" >> /root/.bashrc
|
||||||
|
|
||||||
|
|
||||||
END_OF_SCRIPT
|
END_OF_SCRIPT
|
||||||
|
|
||||||
# add runscript footer
|
# add runscript footer
|
||||||
|
|
|
@ -78,6 +78,11 @@
|
||||||
<artifactId>jersey-core</artifactId>
|
<artifactId>jersey-core</artifactId>
|
||||||
<version>1.4</version>
|
<version>1.4</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.inject.extensions</groupId>
|
||||||
|
<artifactId>guice-assistedinject</artifactId>
|
||||||
|
<version>3.0-rc2</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.google.inject</groupId>
|
<groupId>com.google.inject</groupId>
|
||||||
<artifactId>guice</artifactId>
|
<artifactId>guice</artifactId>
|
||||||
|
|
|
@ -75,7 +75,7 @@ public class AWSEC2TemplateBuilderLiveTest extends BaseTemplateBuilderLiveTest {
|
||||||
assertEquals(template.getImage().getOperatingSystem().getVersion(), "10.10");
|
assertEquals(template.getImage().getOperatingSystem().getVersion(), "10.10");
|
||||||
assertEquals(template.getImage().getOperatingSystem().is64Bit(), false);
|
assertEquals(template.getImage().getOperatingSystem().is64Bit(), false);
|
||||||
assertEquals(template.getImage().getOperatingSystem().getFamily(), OsFamily.UBUNTU);
|
assertEquals(template.getImage().getOperatingSystem().getFamily(), OsFamily.UBUNTU);
|
||||||
assertEquals(template.getImage().getVersion(), "20110115");
|
assertEquals(template.getImage().getVersion(), "20110122");
|
||||||
assertEquals(template.getImage().getUserMetadata().get("rootDeviceType"), "instance-store");
|
assertEquals(template.getImage().getUserMetadata().get("rootDeviceType"), "instance-store");
|
||||||
assertEquals(template.getLocation().getId(), "us-east-1");
|
assertEquals(template.getLocation().getId(), "us-east-1");
|
||||||
assertEquals(getCores(template.getHardware()), 1.0d);
|
assertEquals(getCores(template.getHardware()), 1.0d);
|
||||||
|
|
|
@ -31,7 +31,6 @@ public class SkaliCloudMalaysiaComputeServiceLiveTest extends ElasticStackComput
|
||||||
|
|
||||||
public SkaliCloudMalaysiaComputeServiceLiveTest() {
|
public SkaliCloudMalaysiaComputeServiceLiveTest() {
|
||||||
provider = "skalicloud-sdg-my";
|
provider = "skalicloud-sdg-my";
|
||||||
tag = "skalicloud";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,11 +19,14 @@
|
||||||
|
|
||||||
package org.jclouds.slicehost.compute.config;
|
package org.jclouds.slicehost.compute.config;
|
||||||
|
|
||||||
|
import static org.jclouds.compute.domain.OsFamily.UBUNTU;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import org.jclouds.compute.config.BaseComputeServiceContextModule;
|
import org.jclouds.compute.config.BaseComputeServiceContextModule;
|
||||||
|
import org.jclouds.compute.domain.TemplateBuilder;
|
||||||
import org.jclouds.compute.internal.BaseComputeService;
|
import org.jclouds.compute.internal.BaseComputeService;
|
||||||
import org.jclouds.domain.Location;
|
import org.jclouds.domain.Location;
|
||||||
import org.jclouds.domain.LocationScope;
|
import org.jclouds.domain.LocationScope;
|
||||||
|
@ -31,6 +34,7 @@ import org.jclouds.domain.internal.LocationImpl;
|
||||||
import org.jclouds.location.Provider;
|
import org.jclouds.location.Provider;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import com.google.inject.Injector;
|
||||||
import com.google.inject.Provides;
|
import com.google.inject.Provides;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -39,6 +43,10 @@ import com.google.inject.Provides;
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public class SlicehostComputeServiceContextModule extends BaseComputeServiceContextModule {
|
public class SlicehostComputeServiceContextModule extends BaseComputeServiceContextModule {
|
||||||
|
@Override
|
||||||
|
protected TemplateBuilder provideTemplate(Injector injector, TemplateBuilder template) {
|
||||||
|
return template.osFamily(UBUNTU).osVersionMatches("10.04").osDescriptionMatches("^((?!MGC).)*$").os64Bit(true);
|
||||||
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
|
|
|
@ -64,7 +64,6 @@ public class TerremarkVCloudExpressTemplateBuilderLiveTest extends BaseTemplateB
|
||||||
assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true);
|
assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true);
|
||||||
assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.UBUNTU);
|
assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.UBUNTU);
|
||||||
assertEquals(getCores(defaultTemplate.getHardware()), 1.0d);
|
assertEquals(getCores(defaultTemplate.getHardware()), 1.0d);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -0,0 +1,170 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
|
||||||
|
|
||||||
|
Copyright (C) 2010 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.
|
||||||
|
====================================================================
|
||||||
|
-->
|
||||||
|
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
|
||||||
|
|
||||||
|
<!--
|
||||||
|
For more configuration infromation and examples see the Apache
|
||||||
|
Log4j website: http://logging.apache.org/log4j/
|
||||||
|
-->
|
||||||
|
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"
|
||||||
|
debug="false">
|
||||||
|
|
||||||
|
<!-- A time/date based rolling appender -->
|
||||||
|
<appender name="WIREFILE" class="org.apache.log4j.DailyRollingFileAppender">
|
||||||
|
<param name="File" value="target/test-data/jclouds-wire.log" />
|
||||||
|
<param name="Append" value="true" />
|
||||||
|
|
||||||
|
<!-- Rollover at midnight each day -->
|
||||||
|
<param name="DatePattern" value="'.'yyyy-MM-dd" />
|
||||||
|
|
||||||
|
<param name="Threshold" value="TRACE" />
|
||||||
|
|
||||||
|
<layout class="org.apache.log4j.PatternLayout">
|
||||||
|
<!-- The default pattern: Date Priority [Category] Message\n -->
|
||||||
|
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
|
||||||
|
|
||||||
|
<!--
|
||||||
|
The full pattern: Date MS Priority [Category]
|
||||||
|
(Thread:NDC) Message\n <param name="ConversionPattern"
|
||||||
|
value="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
|
||||||
|
-->
|
||||||
|
</layout>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<!-- A time/date based rolling appender -->
|
||||||
|
<appender name="FILE" class="org.apache.log4j.DailyRollingFileAppender">
|
||||||
|
<param name="File" value="target/test-data/jclouds.log" />
|
||||||
|
<param name="Append" value="true" />
|
||||||
|
|
||||||
|
<!-- Rollover at midnight each day -->
|
||||||
|
<param name="DatePattern" value="'.'yyyy-MM-dd" />
|
||||||
|
|
||||||
|
<param name="Threshold" value="TRACE" />
|
||||||
|
|
||||||
|
<layout class="org.apache.log4j.PatternLayout">
|
||||||
|
<!-- The default pattern: Date Priority [Category] Message\n -->
|
||||||
|
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
|
||||||
|
|
||||||
|
<!--
|
||||||
|
The full pattern: Date MS Priority [Category]
|
||||||
|
(Thread:NDC) Message\n <param name="ConversionPattern"
|
||||||
|
value="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
|
||||||
|
-->
|
||||||
|
</layout>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<!-- A time/date based rolling appender -->
|
||||||
|
<appender name="COMPUTEFILE" class="org.apache.log4j.DailyRollingFileAppender">
|
||||||
|
<param name="File" value="target/test-data/jclouds-compute.log" />
|
||||||
|
<param name="Append" value="true" />
|
||||||
|
|
||||||
|
<!-- Rollover at midnight each day -->
|
||||||
|
<param name="DatePattern" value="'.'yyyy-MM-dd" />
|
||||||
|
|
||||||
|
<param name="Threshold" value="TRACE" />
|
||||||
|
|
||||||
|
<layout class="org.apache.log4j.PatternLayout">
|
||||||
|
<!-- The default pattern: Date Priority [Category] Message\n -->
|
||||||
|
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
|
||||||
|
|
||||||
|
<!--
|
||||||
|
The full pattern: Date MS Priority [Category]
|
||||||
|
(Thread:NDC) Message\n <param name="ConversionPattern"
|
||||||
|
value="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
|
||||||
|
-->
|
||||||
|
</layout>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<!-- A time/date based rolling appender -->
|
||||||
|
<appender name="SSHFILE" class="org.apache.log4j.DailyRollingFileAppender">
|
||||||
|
<param name="File" value="target/test-data/jclouds-ssh.log" />
|
||||||
|
<param name="Append" value="true" />
|
||||||
|
|
||||||
|
<!-- Rollover at midnight each day -->
|
||||||
|
<param name="DatePattern" value="'.'yyyy-MM-dd" />
|
||||||
|
|
||||||
|
<param name="Threshold" value="TRACE" />
|
||||||
|
|
||||||
|
<layout class="org.apache.log4j.PatternLayout">
|
||||||
|
<!-- The default pattern: Date Priority [Category] Message\n -->
|
||||||
|
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
|
||||||
|
|
||||||
|
<!--
|
||||||
|
The full pattern: Date MS Priority [Category]
|
||||||
|
(Thread:NDC) Message\n <param name="ConversionPattern"
|
||||||
|
value="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
|
||||||
|
-->
|
||||||
|
</layout>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<appender name="ASYNCCOMPUTE" class="org.apache.log4j.AsyncAppender">
|
||||||
|
<appender-ref ref="COMPUTEFILE" />
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<appender name="ASYNCSSH" class="org.apache.log4j.AsyncAppender">
|
||||||
|
<appender-ref ref="SSHFILE" />
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<appender name="ASYNC" class="org.apache.log4j.AsyncAppender">
|
||||||
|
<appender-ref ref="FILE" />
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<appender name="ASYNCWIRE" class="org.apache.log4j.AsyncAppender">
|
||||||
|
<appender-ref ref="WIREFILE" />
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<!-- ================ -->
|
||||||
|
<!-- Limit categories -->
|
||||||
|
<!-- ================ -->
|
||||||
|
|
||||||
|
<category name="org.jclouds">
|
||||||
|
<priority value="DEBUG" />
|
||||||
|
<appender-ref ref="ASYNC" />
|
||||||
|
</category>
|
||||||
|
|
||||||
|
<category name="jclouds.headers">
|
||||||
|
<priority value="DEBUG" />
|
||||||
|
<appender-ref ref="ASYNCWIRE" />
|
||||||
|
</category>
|
||||||
|
|
||||||
|
<category name="jclouds.ssh">
|
||||||
|
<priority value="DEBUG" />
|
||||||
|
<appender-ref ref="ASYNCSSH" />
|
||||||
|
</category>
|
||||||
|
|
||||||
|
<category name="jclouds.wire">
|
||||||
|
<priority value="DEBUG" />
|
||||||
|
<appender-ref ref="ASYNCWIRE" />
|
||||||
|
</category>
|
||||||
|
|
||||||
|
<category name="jclouds.compute">
|
||||||
|
<priority value="TRACE" />
|
||||||
|
<appender-ref ref="ASYNCCOMPUTE" />
|
||||||
|
</category>
|
||||||
|
<!-- ======================= -->
|
||||||
|
<!-- Setup the Root category -->
|
||||||
|
<!-- ======================= -->
|
||||||
|
|
||||||
|
<root>
|
||||||
|
<priority value="WARN" />
|
||||||
|
</root>
|
||||||
|
|
||||||
|
</log4j:configuration>
|
Loading…
Reference in New Issue