Merge remote branch 'origin'

This commit is contained in:
Andrew Phillips 2010-11-01 18:12:38 +01:00
commit 81c954c26c
186 changed files with 4210 additions and 1429 deletions

View File

@ -56,6 +56,8 @@ import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
import org.jclouds.compute.strategy.ListNodesStrategy; import org.jclouds.compute.strategy.ListNodesStrategy;
import org.jclouds.compute.strategy.RebootNodeStrategy; import org.jclouds.compute.strategy.RebootNodeStrategy;
import org.jclouds.compute.strategy.RunNodesAndAddToSetStrategy; import org.jclouds.compute.strategy.RunNodesAndAddToSetStrategy;
import org.jclouds.compute.strategy.ResumeNodeStrategy;
import org.jclouds.compute.strategy.SuspendNodeStrategy;
import org.jclouds.compute.util.ComputeUtils; 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;
@ -82,16 +84,19 @@ public class EC2ComputeService extends BaseComputeService {
@Memoized Supplier<Set<? extends Location>> locations, ListNodesStrategy listNodesStrategy, @Memoized Supplier<Set<? extends Location>> locations, ListNodesStrategy listNodesStrategy,
GetNodeMetadataStrategy getNodeMetadataStrategy, RunNodesAndAddToSetStrategy runNodesAndAddToSetStrategy, GetNodeMetadataStrategy getNodeMetadataStrategy, RunNodesAndAddToSetStrategy runNodesAndAddToSetStrategy,
RebootNodeStrategy rebootNodeStrategy, DestroyNodeStrategy destroyNodeStrategy, RebootNodeStrategy rebootNodeStrategy, DestroyNodeStrategy destroyNodeStrategy,
ResumeNodeStrategy startNodeStrategy, SuspendNodeStrategy stopNodeStrategy,
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, ComputeUtils utils, Timeouts timeouts, @Named("NODE_TERMINATED") Predicate<NodeMetadata> nodeTerminated,
@Named("NODE_SUSPENDED") Predicate<NodeMetadata> nodeSuspended, ComputeUtils utils, 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, templateBuilderProvider, runNodesAndAddToSetStrategy, rebootNodeStrategy, destroyNodeStrategy, startNodeStrategy,
templateOptionsProvider, nodeRunning, nodeTerminated, utils, timeouts, executor); stopNodeStrategy, templateBuilderProvider, templateOptionsProvider, nodeRunning, nodeTerminated,
nodeSuspended, utils, timeouts, executor);
this.ec2Client = ec2Client; this.ec2Client = ec2Client;
this.credentialsMap = credentialsMap; this.credentialsMap = credentialsMap;
this.securityGroupMap = securityGroupMap; this.securityGroupMap = securityGroupMap;

View File

@ -24,6 +24,8 @@ import org.jclouds.aws.ec2.compute.strategy.EC2GetNodeMetadataStrategy;
import org.jclouds.aws.ec2.compute.strategy.EC2ListNodesStrategy; import org.jclouds.aws.ec2.compute.strategy.EC2ListNodesStrategy;
import org.jclouds.aws.ec2.compute.strategy.EC2RebootNodeStrategy; import org.jclouds.aws.ec2.compute.strategy.EC2RebootNodeStrategy;
import org.jclouds.aws.ec2.compute.strategy.EC2RunNodesAndAddToSetStrategy; import org.jclouds.aws.ec2.compute.strategy.EC2RunNodesAndAddToSetStrategy;
import org.jclouds.aws.ec2.compute.strategy.EC2ResumeNodeStrategy;
import org.jclouds.aws.ec2.compute.strategy.EC2SuspendNodeStrategy;
import org.jclouds.compute.config.BindComputeStrategiesByClass; import org.jclouds.compute.config.BindComputeStrategiesByClass;
import org.jclouds.compute.strategy.AddNodeWithTagStrategy; import org.jclouds.compute.strategy.AddNodeWithTagStrategy;
import org.jclouds.compute.strategy.DestroyNodeStrategy; import org.jclouds.compute.strategy.DestroyNodeStrategy;
@ -31,6 +33,8 @@ import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
import org.jclouds.compute.strategy.ListNodesStrategy; import org.jclouds.compute.strategy.ListNodesStrategy;
import org.jclouds.compute.strategy.RebootNodeStrategy; import org.jclouds.compute.strategy.RebootNodeStrategy;
import org.jclouds.compute.strategy.RunNodesAndAddToSetStrategy; import org.jclouds.compute.strategy.RunNodesAndAddToSetStrategy;
import org.jclouds.compute.strategy.ResumeNodeStrategy;
import org.jclouds.compute.strategy.SuspendNodeStrategy;
/** /**
* @author Adrian Cole * @author Adrian Cole
@ -76,4 +80,14 @@ public class EC2BindComputeStrategiesByClass extends BindComputeStrategiesByClas
return EC2RebootNodeStrategy.class; return EC2RebootNodeStrategy.class;
} }
@Override
protected Class<? extends ResumeNodeStrategy> defineStartNodeStrategy() {
return EC2ResumeNodeStrategy.class;
}
@Override
protected Class<? extends SuspendNodeStrategy> defineStopNodeStrategy() {
return EC2SuspendNodeStrategy.class;
}
} }

View File

@ -91,7 +91,7 @@ public class RunningInstanceToNodeMetadata implements Function<RunningInstance,
builder.id(instance.getRegion() + "/" + providerId); builder.id(instance.getRegion() + "/" + providerId);
String tag = getTagForInstance(instance); String tag = getTagForInstance(instance);
builder.tag(tag); builder.tag(tag);
builder.credentials(credentialStore.get(instance.getRegion() + "/" + providerId)); builder.credentials(credentialStore.get("node#" + instance.getRegion() + "/" + providerId));
builder.state(instanceToNodeState.get(instance.getInstanceState())); builder.state(instanceToNodeState.get(instance.getInstanceState()));
builder.publicAddresses(nullSafeSet(instance.getIpAddress())); builder.publicAddresses(nullSafeSet(instance.getIpAddress()));
builder.privateAddresses(nullSafeSet(instance.getPrivateIpAddress())); builder.privateAddresses(nullSafeSet(instance.getPrivateIpAddress()));

View File

@ -0,0 +1,57 @@
/**
*
* 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.aws.ec2.compute.strategy;
import static org.jclouds.aws.ec2.util.EC2Utils.parseHandle;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.aws.ec2.EC2Client;
import org.jclouds.aws.ec2.services.InstanceClient;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
import org.jclouds.compute.strategy.ResumeNodeStrategy;
/**
*
* @author Adrian Cole
*/
@Singleton
public class EC2ResumeNodeStrategy implements ResumeNodeStrategy {
private final InstanceClient client;
private final GetNodeMetadataStrategy getNode;
@Inject
protected EC2ResumeNodeStrategy(EC2Client client, GetNodeMetadataStrategy getNode) {
this.client = client.getInstanceServices();
this.getNode = getNode;
}
@Override
public NodeMetadata resumeNode(String id) {
String[] parts = parseHandle(id);
String region = parts[0];
String instanceId = parts[1];
client.startInstancesInRegion(region, instanceId);
return getNode.getNode(id);
}
}

View File

@ -79,12 +79,12 @@ public class EC2RunNodesAndAddToSetStrategy implements RunNodesAndAddToSetStrate
@Inject @Inject
EC2RunNodesAndAddToSetStrategy( EC2RunNodesAndAddToSetStrategy(
EC2Client client, EC2Client client,
CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions createKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions, CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions createKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions,
@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.createKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions = createKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions;
@ -96,10 +96,10 @@ 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) {
Reservation<? extends RunningInstance> reservation = createKeyPairAndSecurityGroupsAsNeededThenRunInstances(tag, Reservation<? extends RunningInstance> reservation = createKeyPairAndSecurityGroupsAsNeededThenRunInstances(tag,
count, template); count, template);
Iterable<String> ids = transform(reservation, instanceToId); Iterable<String> ids = transform(reservation, instanceToId);
@ -111,8 +111,8 @@ public class EC2RunNodesAndAddToSetStrategy implements RunNodesAndAddToSetStrate
populateCredentials(reservation); populateCredentials(reservation);
} }
return utils.runOptionsOnNodesAndAddToGoodSetOrPutExceptionIntoBadMap(template.getOptions(), return utils.runOptionsOnNodesAndAddToGoodSetOrPutExceptionIntoBadMap(template.getOptions(), transform(
transform(reservation, runningInstanceToNodeMetadata), goodNodes, badNodes); reservation, runningInstanceToNodeMetadata), goodNodes, badNodes);
} }
protected void populateCredentials(Reservation<? extends RunningInstance> reservation) { protected void populateCredentials(Reservation<? extends RunningInstance> reservation) {
@ -120,27 +120,27 @@ public class EC2RunNodesAndAddToSetStrategy implements RunNodesAndAddToSetStrate
Credentials credentials = instanceToCredentials.apply(instance1); Credentials credentials = instanceToCredentials.apply(instance1);
if (credentials != null) if (credentials != null)
for (RunningInstance instance : reservation) for (RunningInstance instance : reservation)
credentialStore.put(instance.getRegion() + "/" + instance.getId(), credentials); credentialStore.put("node#" + instance.getRegion() + "/" + instance.getId(), credentials);
} }
@VisibleForTesting @VisibleForTesting
Reservation<? extends RunningInstance> createKeyPairAndSecurityGroupsAsNeededThenRunInstances(String tag, int count, Reservation<? extends RunningInstance> createKeyPairAndSecurityGroupsAsNeededThenRunInstances(String tag, int count,
Template template) { Template template) {
String region = getRegionFromLocationOrNull(template.getLocation()); String region = getRegionFromLocationOrNull(template.getLocation());
String zone = getZoneFromLocationOrNull(template.getLocation()); String zone = getZoneFromLocationOrNull(template.getLocation());
RunInstancesOptions instanceOptions = createKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.execute(region, RunInstancesOptions instanceOptions = createKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.execute(region,
tag, template); tag, template);
if (EC2TemplateOptions.class.cast(template.getOptions()).isMonitoringEnabled()) if (EC2TemplateOptions.class.cast(template.getOptions()).isMonitoringEnabled())
instanceOptions.enableMonitoring(); instanceOptions.enableMonitoring();
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
logger.debug(">> running %d instance region(%s) zone(%s) ami(%s) params(%s)", count, region, zone, template logger.debug(">> running %d instance region(%s) zone(%s) ami(%s) params(%s)", count, region, zone, template
.getImage().getProviderId(), instanceOptions.buildFormParameters()); .getImage().getProviderId(), instanceOptions.buildFormParameters());
return client.getInstanceServices().runInstancesInRegion(region, zone, template.getImage().getProviderId(), 1, return client.getInstanceServices().runInstancesInRegion(region, zone, template.getImage().getProviderId(), 1,
count, instanceOptions); count, instanceOptions);
} }
} }

View File

@ -0,0 +1,57 @@
/**
*
* 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.aws.ec2.compute.strategy;
import static org.jclouds.aws.ec2.util.EC2Utils.parseHandle;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.aws.ec2.EC2Client;
import org.jclouds.aws.ec2.services.InstanceClient;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
import org.jclouds.compute.strategy.SuspendNodeStrategy;
/**
*
* @author Adrian Cole
*/
@Singleton
public class EC2SuspendNodeStrategy implements SuspendNodeStrategy {
private final InstanceClient client;
private final GetNodeMetadataStrategy getNode;
@Inject
protected EC2SuspendNodeStrategy(EC2Client client, GetNodeMetadataStrategy getNode) {
this.client = client.getInstanceServices();
this.getNode = getNode;
}
@Override
public NodeMetadata suspendNode(String id) {
String[] parts = parseHandle(id);
String region = parts[0];
String instanceId = parts[1];
client.stopInstancesInRegion(region, true, instanceId);
return getNode.getNode(id);
}
}

View File

@ -33,6 +33,7 @@ import org.jclouds.compute.RunNodesException;
import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.OperatingSystem; import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequest;
import org.jclouds.scriptbuilder.domain.OsFamily;
import org.jclouds.scriptbuilder.domain.Statement; import org.jclouds.scriptbuilder.domain.Statement;
import org.testng.annotations.BeforeClass; import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -82,7 +83,7 @@ public class ComputeAndBlobStoreTogetherHappilyLiveTest extends BlobStoreAndComp
// using jclouds ability to detect operating systems before we launch them, we can avoid // using jclouds ability to detect operating systems before we launch them, we can avoid
// the bad practice of assuming everything is ubuntu. // the bad practice of assuming everything is ubuntu.
uploadBlob(tag, "openjdk/install", buildScript(defaultOperatingSystem)); uploadBlob(tag, "openjdk/install", buildScript(defaultOperatingSystem).render(OsFamily.UNIX));
// instead of hard-coding to amazon s3, we can use any blobstore, conceding this test is // instead of hard-coding to amazon s3, we can use any blobstore, conceding this test is
// configured for amz. Note we are getting temporary access to a private blob. // configured for amz. Note we are getting temporary access to a private blob.

View File

@ -68,7 +68,7 @@ public class CredentialsStoredInBlobStoreTest {
public void testWeCanUseBlobStoreToStoreCredentialsAcrossContexts() throws RunNodesException, IOException { public void testWeCanUseBlobStoreToStoreCredentialsAcrossContexts() throws RunNodesException, IOException {
ComputeServiceContext computeContext = new ComputeServiceContextFactory().createContext("stub", "foo", "bar", ComputeServiceContext computeContext = new ComputeServiceContextFactory().createContext("stub", "foo", "bar",
ImmutableSet.of(new CredentialStoreModule(credentialsMap))); ImmutableSet.of(new CredentialStoreModule(credentialsMap)));
Set<? extends NodeMetadata> nodes = computeContext.getComputeService().runNodesWithTag("foo", 10); Set<? extends NodeMetadata> nodes = computeContext.getComputeService().runNodesWithTag("foo", 10);
@ -76,19 +76,19 @@ public class CredentialsStoredInBlobStoreTest {
computeContext.close(); computeContext.close();
// recreate the compute context with the same map and ensure it still works! // recreate the compute context with the same map and ensure it still works!
computeContext = new ComputeServiceContextFactory().createContext("stub", "foo", "bar", computeContext = new ComputeServiceContextFactory().createContext("stub", "foo", "bar", Collections
Collections.singleton(new CredentialStoreModule(credentialsMap))); .singleton(new CredentialStoreModule(credentialsMap)));
verifyCredentialsFromNodesAreInContext(nodes, computeContext); verifyCredentialsFromNodesAreInContext(nodes, computeContext);
} }
protected void verifyCredentialsFromNodesAreInContext(Set<? extends NodeMetadata> nodes, protected void verifyCredentialsFromNodesAreInContext(Set<? extends NodeMetadata> nodes,
ComputeServiceContext computeContext) throws IOException { ComputeServiceContext computeContext) throws IOException {
// verify each node's credential is in the map. // verify each node's credential is in the map.
assertEquals(computeContext.credentialStore().size(), 10); assertEquals(computeContext.credentialStore().size(), 10);
for (NodeMetadata node : nodes) { for (NodeMetadata node : nodes) {
assertEquals(computeContext.credentialStore().get(node.getId()), node.getCredentials()); assertEquals(computeContext.credentialStore().get("node#" + node.getId()), node.getCredentials());
} }
// verify the credentials are in the backing store and of a known json format // verify the credentials are in the backing store and of a known json format
@ -96,7 +96,7 @@ public class CredentialsStoredInBlobStoreTest {
for (Entry<String, InputStream> entry : credentialsMap.entrySet()) { for (Entry<String, InputStream> entry : credentialsMap.entrySet()) {
Credentials credentials = computeContext.credentialStore().get(entry.getKey()); Credentials credentials = computeContext.credentialStore().get(entry.getKey());
assertEquals(Utils.toStringAndClose(entry.getValue()), String.format( assertEquals(Utils.toStringAndClose(entry.getValue()), String.format(
"{\"identity\":\"%s\",\"credential\":\"%s\"}", credentials.identity, credentials.credential)); "{\"identity\":\"%s\",\"credential\":\"%s\"}", credentials.identity, credentials.credential));
} }
} }
} }

View File

@ -90,6 +90,7 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest {
protected void assertDefaultWorks() { protected void assertDefaultWorks() {
Template defaultTemplate = client.templateBuilder().build(); Template defaultTemplate = client.templateBuilder().build();
assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true); assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true);
assertEquals(defaultTemplate.getImage().getOperatingSystem().getVersion(), "0.9.9-beta");
assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.AMZN_LINUX); assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.AMZN_LINUX);
assertEquals(getCores(defaultTemplate.getHardware()), 1.0d); assertEquals(getCores(defaultTemplate.getHardware()), 1.0d);
} }

View File

@ -82,14 +82,14 @@ public class EC2TemplateBuilderLiveTest {
.<Module> of(new Log4JLoggingModule()), setupProperties()); .<Module> of(new Log4JLoggingModule()), setupProperties());
Template template = newContext.getComputeService().templateBuilder().hardwareId(InstanceType.M1_SMALL) Template template = newContext.getComputeService().templateBuilder().hardwareId(InstanceType.M1_SMALL)
.osVersionMatches("10.04").imageDescriptionMatches("ubuntu-images").osFamily(OsFamily.UBUNTU).build(); .osVersionMatches("10.10").imageDescriptionMatches("ubuntu-images").osFamily(OsFamily.UBUNTU).build();
System.out.println(template.getHardware()); System.out.println(template.getHardware());
assert (template.getImage().getProviderId().startsWith("ami-")) : template; assert (template.getImage().getProviderId().startsWith("ami-")) : template;
assertEquals(template.getImage().getOperatingSystem().getVersion(), "10.04"); 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(), "20100921"); assertEquals(template.getImage().getVersion(), "20101027");
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);
@ -135,7 +135,7 @@ public class EC2TemplateBuilderLiveTest {
Template defaultTemplate = newContext.getComputeService().templateBuilder().build(); Template defaultTemplate = newContext.getComputeService().templateBuilder().build();
assert (defaultTemplate.getImage().getProviderId().startsWith("ami-")) : defaultTemplate; assert (defaultTemplate.getImage().getProviderId().startsWith("ami-")) : defaultTemplate;
assertEquals(defaultTemplate.getImage().getOperatingSystem().getVersion(), "0.9.8-beta"); assertEquals(defaultTemplate.getImage().getOperatingSystem().getVersion(), "0.9.9-beta");
assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true); assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true);
assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.AMZN_LINUX); assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.AMZN_LINUX);
assertEquals(defaultTemplate.getImage().getUserMetadata().get("rootDeviceType"), "ebs"); assertEquals(defaultTemplate.getImage().getUserMetadata().get("rootDeviceType"), "ebs");

View File

@ -75,7 +75,7 @@ public class RunningInstanceToNodeMetadataTest {
RunningInstanceToNodeMetadata parser = createNodeParser(ImmutableSet.<Hardware> of(), ImmutableSet RunningInstanceToNodeMetadata parser = createNodeParser(ImmutableSet.<Hardware> of(), ImmutableSet
.<Location> of(), ImmutableSet.<Image> of(), ImmutableMap.<String, Credentials> of( .<Location> of(), ImmutableSet.<Image> of(), ImmutableMap.<String, Credentials> of(
"us-east-1/i-9slweygo", creds)); "node#us-east-1/i-9slweygo", creds));
RunningInstance server = firstInstanceFromResource("/ec2/describe_instances_nova.xml"); RunningInstance server = firstInstanceFromResource("/ec2/describe_instances_nova.xml");

View File

@ -92,7 +92,7 @@ public class EC2RunNodesAndAddToSetStrategyTest {
return null; return null;
} }
@SuppressWarnings({ "unchecked" }) @SuppressWarnings( { "unchecked" })
private void assertRegionAndZoneForLocation(Location location, String region, String zone) { private void assertRegionAndZoneForLocation(Location location, String region, String zone) {
String imageId = "ami1"; String imageId = "ami1";
String instanceCreatedId = "instance1"; String instanceCreatedId = "instance1";
@ -102,27 +102,26 @@ 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.createKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.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();
expect(input.image.getProviderId()).andReturn(imageId).atLeastOnce(); expect(input.image.getProviderId()).andReturn(imageId).atLeastOnce();
expect(instanceClient.runInstancesInRegion(region, zone, imageId, 1, input.count, ec2Options)).andReturn( expect(instanceClient.runInstancesInRegion(region, zone, imageId, 1, input.count, ec2Options)).andReturn(
(Reservation) reservation); (Reservation) reservation);
expect(instance.getId()).andReturn(instanceCreatedId).atLeastOnce(); expect(instance.getId()).andReturn(instanceCreatedId).atLeastOnce();
// simulate a lazy credentials fetch // simulate a lazy credentials fetch
Credentials creds = new Credentials("foo","bar"); Credentials creds = new Credentials("foo", "bar");
expect(strategy.instanceToCredentials.apply(instance)).andReturn(creds); expect(strategy.instanceToCredentials.apply(instance)).andReturn(creds);
expect(instance.getRegion()).andReturn(region); expect(instance.getRegion()).andReturn(region);
expect(strategy.credentialStore.put(region + "/" + instanceCreatedId, creds)).andReturn(null); expect(strategy.credentialStore.put("node#" + region + "/" + instanceCreatedId, creds)).andReturn(null);
expect(strategy.instancePresent.apply(instance)).andReturn(true); expect(strategy.instancePresent.apply(instance)).andReturn(true);
expect(input.template.getOptions()).andReturn(input.options).atLeastOnce(); expect(input.template.getOptions()).andReturn(input.options).atLeastOnce();
@ -130,8 +129,8 @@ 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.runOptionsOnNodesAndAddToGoodSetOrPutExceptionIntoBadMap(eq(input.options),
containsNodeMetadata(nodeMetadata), eq(input.nodes), eq(input.badNodes))).andReturn(null); containsNodeMetadata(nodeMetadata), eq(input.nodes), eq(input.badNodes))).andReturn(null);
// replay mocks // replay mocks
replay(instanceClient); replay(instanceClient);
@ -154,9 +153,9 @@ public class EC2RunNodesAndAddToSetStrategyTest {
} }
private static final Location REGION_AP_SOUTHEAST_1 = new LocationImpl(LocationScope.REGION, Region.AP_SOUTHEAST_1, private static final Location REGION_AP_SOUTHEAST_1 = new LocationImpl(LocationScope.REGION, Region.AP_SOUTHEAST_1,
Region.AP_SOUTHEAST_1, new LocationImpl(LocationScope.PROVIDER, "ec2", "ec2", null)); Region.AP_SOUTHEAST_1, new LocationImpl(LocationScope.PROVIDER, "ec2", "ec2", null));
private static final Location ZONE_AP_SOUTHEAST_1A = new LocationImpl(LocationScope.ZONE, private static final Location ZONE_AP_SOUTHEAST_1A = new LocationImpl(LocationScope.ZONE,
AvailabilityZone.AP_SOUTHEAST_1A, AvailabilityZone.AP_SOUTHEAST_1A, REGION_AP_SOUTHEAST_1); AvailabilityZone.AP_SOUTHEAST_1A, AvailabilityZone.AP_SOUTHEAST_1A, REGION_AP_SOUTHEAST_1);
// ///////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@ -214,7 +213,7 @@ public class EC2RunNodesAndAddToSetStrategyTest {
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, createKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions,
instanceStateRunning, runningInstanceToNodeMetadata, instanceToCredentials, credentialStore, utils); instanceStateRunning, runningInstanceToNodeMetadata, instanceToCredentials, credentialStore, utils);
} }
private void replayStrategy(EC2RunNodesAndAddToSetStrategy strategy) { private void replayStrategy(EC2RunNodesAndAddToSetStrategy strategy) {

View File

@ -26,7 +26,6 @@ import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.collect.Sets.newTreeSet; import static com.google.common.collect.Sets.newTreeSet;
import static org.jclouds.compute.ComputeTestUtils.buildScript; import static org.jclouds.compute.ComputeTestUtils.buildScript;
import static org.jclouds.compute.ComputeTestUtils.setupKeyPair; import static org.jclouds.compute.ComputeTestUtils.setupKeyPair;
import static org.jclouds.scriptbuilder.domain.Statements.exec;
import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertNotNull;
@ -89,10 +88,10 @@ public class PlacementGroupClientLiveTest {
protected void setupCredentials() { protected void setupCredentials() {
identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity"); identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
credential = checkNotNull(System.getProperty("test." + provider + ".credential"), "test." + provider credential = checkNotNull(System.getProperty("test." + provider + ".credential"), "test." + provider
+ ".credential"); + ".credential");
endpoint = checkNotNull(System.getProperty("test." + provider + ".endpoint"), "test." + provider + ".endpoint"); endpoint = checkNotNull(System.getProperty("test." + provider + ".endpoint"), "test." + provider + ".endpoint");
apiversion = checkNotNull(System.getProperty("test." + provider + ".apiversion"), "test." + provider apiversion = checkNotNull(System.getProperty("test." + provider + ".apiversion"), "test." + provider
+ ".apiversion"); + ".apiversion");
} }
protected Properties setupProperties() { protected Properties setupProperties() {
@ -110,14 +109,14 @@ public class PlacementGroupClientLiveTest {
public void setupClient() throws FileNotFoundException, IOException { public void setupClient() throws FileNotFoundException, IOException {
setupCredentials(); setupCredentials();
Properties overrides = setupProperties(); Properties overrides = setupProperties();
context = new ComputeServiceContextFactory().createContext(provider, context = new ComputeServiceContextFactory().createContext(provider, ImmutableSet
ImmutableSet.<Module> of(new Log4JLoggingModule()), overrides); .<Module> of(new Log4JLoggingModule()), overrides);
keyPair = setupKeyPair(); keyPair = setupKeyPair();
client = EC2Client.class.cast(context.getProviderSpecificContext().getApi()); client = EC2Client.class.cast(context.getProviderSpecificContext().getApi());
availableTester = new RetryablePredicate<PlacementGroup>(new PlacementGroupAvailable(client), 60, 1, availableTester = new RetryablePredicate<PlacementGroup>(new PlacementGroupAvailable(client), 60, 1,
TimeUnit.SECONDS); TimeUnit.SECONDS);
deletedTester = new RetryablePredicate<PlacementGroup>(new PlacementGroupDeleted(client), 60, 1, TimeUnit.SECONDS); deletedTester = new RetryablePredicate<PlacementGroup>(new PlacementGroupDeleted(client), 60, 1, TimeUnit.SECONDS);
} }
@ -126,12 +125,12 @@ public class PlacementGroupClientLiveTest {
void testDescribe() { void testDescribe() {
for (String region : newArrayList(Region.US_EAST_1)) { for (String region : newArrayList(Region.US_EAST_1)) {
SortedSet<PlacementGroup> allResults = newTreeSet(client.getPlacementGroupServices() SortedSet<PlacementGroup> allResults = newTreeSet(client.getPlacementGroupServices()
.describePlacementGroupsInRegion(region)); .describePlacementGroupsInRegion(region));
assertNotNull(allResults); assertNotNull(allResults);
if (allResults.size() >= 1) { if (allResults.size() >= 1) {
PlacementGroup group = allResults.last(); PlacementGroup group = allResults.last();
SortedSet<PlacementGroup> result = newTreeSet(client.getPlacementGroupServices() SortedSet<PlacementGroup> result = newTreeSet(client.getPlacementGroupServices()
.describePlacementGroupsInRegion(region, group.getName())); .describePlacementGroupsInRegion(region, group.getName()));
assertNotNull(result); assertNotNull(result);
PlacementGroup compare = result.last(); PlacementGroup compare = result.last();
assertEquals(compare, group); assertEquals(compare, group);
@ -160,7 +159,7 @@ public class PlacementGroupClientLiveTest {
private void verifyPlacementGroup(String groupName) { private void verifyPlacementGroup(String groupName) {
assert availableTester.apply(new PlacementGroup(Region.US_EAST_1, groupName, "cluster", State.PENDING)) : group; assert availableTester.apply(new PlacementGroup(Region.US_EAST_1, groupName, "cluster", State.PENDING)) : group;
Set<PlacementGroup> oneResult = client.getPlacementGroupServices().describePlacementGroupsInRegion(null, Set<PlacementGroup> oneResult = client.getPlacementGroupServices().describePlacementGroupsInRegion(null,
groupName); groupName);
assertNotNull(oneResult); assertNotNull(oneResult);
assertEquals(oneResult.size(), 1); assertEquals(oneResult.size(), 1);
group = oneResult.iterator().next(); group = oneResult.iterator().next();
@ -195,7 +194,7 @@ public class PlacementGroupClientLiveTest {
assertEquals(template.getImage().getId(), "us-east-1/ami-7ea24a17"); assertEquals(template.getImage().getId(), "us-east-1/ami-7ea24a17");
template.getOptions().installPrivateKey(keyPair.get("private")).authorizePublicKey(keyPair.get("public")) template.getOptions().installPrivateKey(keyPair.get("private")).authorizePublicKey(keyPair.get("public"))
.runScript(exec(buildScript(template.getImage().getOperatingSystem()))); .runScript(buildScript(template.getImage().getOperatingSystem()));
String tag = PREFIX + "cccluster"; String tag = PREFIX + "cccluster";
context.getComputeService().destroyNodesMatching(NodePredicates.withTag(tag)); context.getComputeService().destroyNodesMatching(NodePredicates.withTag(tag));
@ -205,7 +204,7 @@ public class PlacementGroupClientLiveTest {
NodeMetadata node = getOnlyElement(nodes); NodeMetadata node = getOnlyElement(nodes);
getOnlyElement(getOnlyElement(client.getInstanceServices().describeInstancesInRegion(null, getOnlyElement(getOnlyElement(client.getInstanceServices().describeInstancesInRegion(null,
node.getProviderId()))); node.getProviderId())));
} catch (RunNodesException e) { } catch (RunNodesException e) {
System.err.println(e.getNodeErrors().keySet()); System.err.println(e.getNodeErrors().keySet());

View File

@ -37,12 +37,12 @@ import org.jclouds.aws.ec2.domain.Reservation;
import org.jclouds.aws.ec2.domain.RunningInstance; import org.jclouds.aws.ec2.domain.RunningInstance;
import org.jclouds.aws.ec2.predicates.InstanceStateRunning; import org.jclouds.aws.ec2.predicates.InstanceStateRunning;
import org.jclouds.net.IPSocket; import org.jclouds.net.IPSocket;
import org.jclouds.predicates.InetSocketAddressConnect;
import org.jclouds.predicates.RetryablePredicate; import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.rest.RestContext; import org.jclouds.rest.RestContext;
import org.jclouds.rest.RestContextFactory; import org.jclouds.rest.RestContextFactory;
import org.jclouds.scriptbuilder.ScriptBuilder; import org.jclouds.scriptbuilder.ScriptBuilder;
import org.jclouds.scriptbuilder.domain.OsFamily; import org.jclouds.scriptbuilder.domain.OsFamily;
import org.jclouds.ssh.jsch.predicates.InetSocketAddressConnect;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;

View File

@ -64,17 +64,33 @@ public class ParseAzureStorageErrorFromXmlContent implements HttpErrorHandler {
public void handleError(HttpCommand command, HttpResponse response) { public void handleError(HttpCommand command, HttpResponse response) {
Exception exception = new HttpResponseException(command, response); Exception exception = new HttpResponseException(command, response);
String message = null;
try { try {
AzureStorageError error = parseErrorFromContentOrNull(command, response); if (response.getPayload() != null) {
String contentType = response.getPayload().getContentMetadata().getContentType();
if (contentType != null && (contentType.indexOf("xml") != -1 || contentType.indexOf("unknown") != -1)) {
AzureStorageError error = utils.parseAzureStorageErrorFromContent(command, response, response
.getPayload().getInput());
if (error != null) {
message = error.getMessage();
exception = new AzureStorageResponseException(command, response, error);
}
} else {
try {
message = Utils.toStringAndClose(response.getPayload().getInput());
} catch (IOException e) {
}
}
}
message = message != null ? message : String.format("%s -> %s", command.getRequest().getRequestLine(),
response.getStatusLine());
switch (response.getStatusCode()) { switch (response.getStatusCode()) {
case 401: case 401:
exception = new AuthorizationException(command.getRequest(), error != null ? error exception = new AuthorizationException(command.getRequest(), message);
.getMessage() : response.getStatusLine());
break; break;
case 404: case 404:
if (!command.getRequest().getMethod().equals("DELETE")) { if (!command.getRequest().getMethod().equals("DELETE")) {
String message = error != null ? error.getMessage() : String.format("%s -> %s",
command.getRequest().getRequestLine(), response.getStatusLine());
String path = command.getRequest().getEndpoint().getPath(); String path = command.getRequest().getEndpoint().getPath();
Matcher matcher = CONTAINER_PATH.matcher(path); Matcher matcher = CONTAINER_PATH.matcher(path);
if (matcher.find()) { if (matcher.find()) {
@ -82,15 +98,14 @@ public class ParseAzureStorageErrorFromXmlContent implements HttpErrorHandler {
} else { } else {
matcher = CONTAINER_KEY_PATH.matcher(path); matcher = CONTAINER_KEY_PATH.matcher(path);
if (matcher.find()) { if (matcher.find()) {
exception = new KeyNotFoundException(matcher.group(1), matcher.group(2), exception = new KeyNotFoundException(matcher.group(1), matcher.group(2), message);
message);
} }
} }
} }
break; break;
default: case 411:
exception = error != null ? new AzureStorageResponseException(command, response, exception = new IllegalArgumentException(message);
error) : new HttpResponseException(command, response); break;
} }
} finally { } finally {
releasePayload(response); releasePayload(response);
@ -98,17 +113,4 @@ public class ParseAzureStorageErrorFromXmlContent implements HttpErrorHandler {
} }
} }
AzureStorageError parseErrorFromContentOrNull(HttpCommand command, HttpResponse response) {
if (response.getPayload() != null) {
try {
String content = Utils.toStringAndClose(response.getPayload().getInput());
if (content != null && content.indexOf('<') >= 0)
return utils.parseAzureStorageErrorFromContent(command, response, Utils
.toInputStream(content));
} catch (IOException e) {
logger.warn(e, "exception reading error from response", response);
}
}
return null;
}
} }

View File

@ -81,11 +81,9 @@ public class AzureBlobClientLiveTest {
protected void setupCredentials() { protected void setupCredentials() {
identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity"); identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
credential = checkNotNull(System.getProperty("test." + provider + ".credential"), "test." + provider credential = System.getProperty("test." + provider + ".credential");
+ ".credential"); endpoint = System.getProperty("test." + provider + ".endpoint");
endpoint = checkNotNull(System.getProperty("test." + provider + ".endpoint"), "test." + provider + ".endpoint"); apiversion = System.getProperty("test." + provider + ".apiversion");
apiversion = checkNotNull(System.getProperty("test." + provider + ".apiversion"), "test." + provider
+ ".apiversion");
} }
protected Properties setupProperties() { protected Properties setupProperties() {
@ -93,9 +91,12 @@ public class AzureBlobClientLiveTest {
overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true"); overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
overrides.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true"); overrides.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true");
overrides.setProperty(provider + ".identity", identity); overrides.setProperty(provider + ".identity", identity);
overrides.setProperty(provider + ".credential", credential); if (credential != null)
overrides.setProperty(provider + ".endpoint", endpoint); overrides.setProperty(provider + ".credential", credential);
overrides.setProperty(provider + ".apiversion", apiversion); if (endpoint != null)
overrides.setProperty(provider + ".endpoint", endpoint);
if (apiversion != null)
overrides.setProperty(provider + ".apiversion", apiversion);
return overrides; return overrides;
} }

View File

@ -0,0 +1,105 @@
/**
*
* 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.azure.storage.handlers;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.reportMatcher;
import static org.easymock.classextension.EasyMock.createMock;
import static org.easymock.classextension.EasyMock.replay;
import static org.easymock.classextension.EasyMock.verify;
import java.net.URI;
import org.easymock.IArgumentMatcher;
import org.jclouds.azure.storage.filters.SharedKeyLiteAuthentication;
import org.jclouds.http.HttpCommand;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse;
import org.jclouds.http.functions.config.SaxParserModule;
import org.jclouds.io.Payloads;
import org.jclouds.util.Utils;
import org.testng.annotations.Test;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
/**
*
* @author Adrian Cole
*/
@Test(groups = { "unit" })
public class ParseAzureErrorFromXmlContentTest {
@Test
public void test411WithTextHtmlIllegalArgumentException() {
assertCodeMakes("PUT", URI
.create("https://jclouds.blob.core.windows.net/adriancole-azureblob-413790770?restype=container"), 411,
"Length Required", "text/html; charset=us-ascii", "<HTML><HEAD><TITLE>Length Required</TITLE>\r\n",
IllegalArgumentException.class);
}
private void assertCodeMakes(String method, URI uri, int statusCode, String message, String contentType,
String content, Class<? extends Exception> expected) {
ParseAzureStorageErrorFromXmlContent function = Guice.createInjector(new SaxParserModule(), new AbstractModule() {
@Override
protected void configure() {
bind(SharedKeyLiteAuthentication.class).toInstance(createMock(SharedKeyLiteAuthentication.class));
}
}).getInstance(ParseAzureStorageErrorFromXmlContent.class);
HttpCommand command = createMock(HttpCommand.class);
HttpRequest request = new HttpRequest(method, uri);
HttpResponse response = new HttpResponse(statusCode, message, Payloads.newInputStreamPayload(Utils
.toInputStream(content)));
response.getPayload().getContentMetadata().setContentType(contentType);
expect(command.getRequest()).andReturn(request).atLeastOnce();
command.setException(classEq(expected));
replay(command);
function.handleError(command, response);
verify(command);
}
public static Exception classEq(final Class<? extends Exception> in) {
reportMatcher(new IArgumentMatcher() {
@Override
public void appendTo(StringBuffer buffer) {
buffer.append("classEq(");
buffer.append(in);
buffer.append(")");
}
@Override
public boolean matches(Object arg) {
return arg.getClass() == in;
}
});
return null;
}
}

View File

@ -234,6 +234,30 @@ See http://code.google.com/p/jclouds for details."
([id #^ComputeService compute] ([id #^ComputeService compute]
(.getNodeMetadata compute id))) (.getNodeMetadata compute id)))
(defn suspend-nodes-with-tag
"Reboot all the nodes with the given tag."
([tag] (suspend-nodes-with-tag tag *compute*))
([#^String tag #^ComputeService compute]
(.suspendNodesMatching compute (NodePredicates/withTag tag))))
(defn suspend-node
"Suspend a node, given its id."
([id] (suspend-node id *compute*))
([id #^ComputeService compute]
(.suspendNode compute id)))
(defn resume-nodes-with-tag
"Suspend all the nodes with the given tag."
([tag] (resume-nodes-with-tag tag *compute*))
([#^String tag #^ComputeService compute]
(.resumeNodesMatching compute (NodePredicates/withTag tag))))
(defn resume-node
"Resume a node, given its id."
([id] (resume-node id *compute*))
([id #^ComputeService compute]
(.resumeNode compute id)))
(defn reboot-nodes-with-tag (defn reboot-nodes-with-tag
"Reboot all the nodes with the given tag." "Reboot all the nodes with the given tag."
([tag] (reboot-nodes-with-tag tag *compute*)) ([tag] (reboot-nodes-with-tag tag *compute*))

View File

@ -23,6 +23,7 @@
[org.jclouds.ssh SshClient ExecResponse] [org.jclouds.ssh SshClient ExecResponse]
com.google.inject.Module com.google.inject.Module
com.google.common.collect.ImmutableSet com.google.common.collect.ImmutableSet
org.jclouds.domain.Credentials
org.jclouds.net.IPSocket org.jclouds.net.IPSocket
[org.jclouds.compute ComputeService ComputeServiceContextFactory StandaloneComputeServiceContextSpec] [org.jclouds.compute ComputeService ComputeServiceContextFactory StandaloneComputeServiceContextSpec]
[java.util Set Map] [java.util Set Map]
@ -51,6 +52,10 @@
(^void destroyNode [this ^String id] (^void destroyNode [this ^String id]
()) ())
(^void rebootNode [this ^String id] (^void rebootNode [this ^String id]
())
(^void suspendNode [this ^String id]
())
(^void resumeNode [this ^String id]
())))) ()))))
(defn compute-context [^RestContextSpec spec] (defn compute-context [^RestContextSpec spec]
@ -75,6 +80,9 @@
[ctor] [ctor]
(reify (reify
org.jclouds.ssh.SshClient$Factory org.jclouds.ssh.SshClient$Factory
(^org.jclouds.ssh.SshClient create
[_ ^IPSocket socket ^Credentials credentials]
(ctor socket credentials))
(^org.jclouds.ssh.SshClient create (^org.jclouds.ssh.SshClient create
[_ ^IPSocket socket ^String username ^String password-or-key] [_ ^IPSocket socket ^String username ^String password-or-key]
(ctor socket username password-or-key)) (ctor socket username password-or-key))

View File

@ -63,52 +63,48 @@ public interface ComputeService {
TemplateOptions templateOptions(); TemplateOptions templateOptions();
/** /**
* The list hardware profiles command shows you the options including virtual cpu count, * The list hardware profiles command shows you the options including virtual cpu count, memory,
* memory, and disks. cpu count is not a portable quantity across clouds, as * and disks. cpu count is not a portable quantity across clouds, as they are measured
* they are measured differently. However, it is a good indicator of relative * differently. However, it is a good indicator of relative speed within a cloud. memory is
* speed within a cloud. memory is measured in megabytes and disks in * measured in megabytes and disks in gigabytes.
* gigabytes.
* *
* @return a map of hardware profiles by ID, conceding that in some clouds the "id" is * @return a map of hardware profiles by ID, conceding that in some clouds the "id" is not used.
* not used.
*/ */
Set<? extends Hardware> listHardwareProfiles(); Set<? extends Hardware> listHardwareProfiles();
/** /**
* Images define the operating system and metadata related to a node. In some * Images define the operating system and metadata related to a node. In some clouds, Images are
* clouds, Images are bound to a specific region, and their identifiers are * bound to a specific region, and their identifiers are different across these regions. For this
* different across these regions. For this reason, you should consider * reason, you should consider matching image requirements like operating system family with
* matching image requirements like operating system family with * TemplateBuilder as opposed to choosing an image explicitly. The getImages() command returns a
* TemplateBuilder as opposed to choosing an image explicitly. The * map of images by id.
* getImages() command returns a map of images by id.
*/ */
Set<? extends Image> listImages(); Set<? extends Image> listImages();
/** /**
* all nodes available to the current user by id. If possible, the returned * all nodes available to the current user by id. If possible, the returned set will include
* set will include {@link NodeMetadata} objects. * {@link NodeMetadata} objects.
*/ */
Set<? extends ComputeMetadata> listNodes(); Set<? extends ComputeMetadata> listNodes();
/** /**
* The list locations command returns all the valid locations for nodes. A * The list locations command returns all the valid locations for nodes. A location has a scope,
* location has a scope, which is typically region or zone. A region is a * which is typically region or zone. A region is a general area, like eu-west, where a zone is
* general area, like eu-west, where a zone is similar to a datacenter. If a * similar to a datacenter. If a location has a parent, that implies it is within that location.
* location has a parent, that implies it is within that location. For * For example a location can be a rack, whose parent is likely to be a zone.
* example a location can be a rack, whose parent is likely to be a zone.
*/ */
Set<? extends Location> listAssignableLocations(); Set<? extends Location> listAssignableLocations();
/** /**
* *
* The compute api treats nodes as a group based on a tag you specify. Using * The compute api treats nodes as a group based on a tag you specify. Using this tag, you can
* this tag, you can choose to operate one or many nodes as a logical unit * choose to operate one or many nodes as a logical unit without regard to the implementation
* without regard to the implementation details of the cloud. * details of the cloud.
* <p/> * <p/>
* *
* The set that is returned will include credentials you can use to ssh into * The set that is returned will include credentials you can use to ssh into the nodes. The "key"
* the nodes. The "key" part of the credentials is either a password or a * part of the credentials is either a password or a private key. You have to inspect the value
* private key. You have to inspect the value to determine this. * to determine this.
* *
* <pre> * <pre>
* if (node.getCredentials().key.startsWith("-----BEGIN RSA PRIVATE KEY-----")) * if (node.getCredentials().key.startsWith("-----BEGIN RSA PRIVATE KEY-----"))
@ -116,11 +112,11 @@ public interface ComputeService {
* </pre> * </pre>
* *
* <p/> * <p/>
* Note. if all you want to do is execute a script at bootup, you should * Note. if all you want to do is execute a script at bootup, you should consider use of the
* consider use of the runscript option. * runscript option.
* <p/> * <p/>
* If resources such as security groups are needed, they will be reused or * If resources such as security groups are needed, they will be reused or created for you.
* created for you. Inbound port 22 will always be opened up. * Inbound port 22 will always be opened up.
* *
* @param tag * @param tag
* - common identifier to group nodes by, cannot contain hyphens * - common identifier to group nodes by, cannot contain hyphens
@ -131,38 +127,65 @@ public interface ComputeService {
* @return all of the nodes the api was able to launch in a running state. * @return all of the nodes the api was able to launch in a running state.
* *
* @throws RunNodesException * @throws RunNodesException
* when there's a problem applying options to nodes. Note that * when there's a problem applying options to nodes. Note that successful and failed
* successful and failed nodes are a part of this exception, so be * nodes are a part of this exception, so be sure to inspect this carefully.
* sure to inspect this carefully.
*/ */
Set<? extends NodeMetadata> runNodesWithTag(String tag, int count, Template template) throws RunNodesException; Set<? extends NodeMetadata> runNodesWithTag(String tag, int count, Template template) throws RunNodesException;
/** /**
* Like {@link ComputeService#runNodesWithTag(String,int,Template)}, except * Like {@link ComputeService#runNodesWithTag(String,int,Template)}, except that the template is
* that the template is default, equivalent to {@code * default, equivalent to {@code templateBuilder().any().options(templateOptions)}.
* templateBuilder().any().options(templateOptions)}.
*/ */
Set<? extends NodeMetadata> runNodesWithTag(String tag, int count, TemplateOptions templateOptions) Set<? extends NodeMetadata> runNodesWithTag(String tag, int count, TemplateOptions templateOptions)
throws RunNodesException; throws RunNodesException;
/** /**
* Like {@link ComputeService#runNodesWithTag(String,int,TemplateOptions)}, * Like {@link ComputeService#runNodesWithTag(String,int,TemplateOptions)}, except that the
* except that the options are default, as specified in * options are default, as specified in {@link ComputeService#templateOptions}.
* {@link ComputeService#templateOptions}.
*/ */
Set<? extends NodeMetadata> runNodesWithTag(String tag, int count) throws RunNodesException; Set<? extends NodeMetadata> runNodesWithTag(String tag, int count) throws RunNodesException;
/** /**
* destroy the node, given its id. If it is the only node in a tag set, the * resume the node from {@link org.jclouds.compute.domain.NodeState#SUSPENDED suspended} state,
* dependent resources will also be destroyed. * given its id.
*/
void resumeNode(String id);
/**
* nodes matching the filter are treated as a logical set. Using the resume command, you can save
* time by resumeing the nodes in parallel.
*
* @throws UnsupportedOperationException
* if the underlying provider doesn't support suspend/resume
*/
void resumeNodesMatching(Predicate<NodeMetadata> filter);
/**
* suspend the node, given its id. This will result in
* {@link org.jclouds.compute.domain.NodeState#SUSPENDED suspended} state.
*
* @throws UnsupportedOperationException
* if the underlying provider doesn't support suspend/resume
*/
void suspendNode(String id);
/**
* nodes matching the filter are treated as a logical set. Using the suspend command, you can
* save time by suspending the nodes in parallel.
*
*/
void suspendNodesMatching(Predicate<NodeMetadata> filter);
/**
* destroy the node, given its id. If it is the only node in a tag set, the dependent resources
* will also be destroyed.
*/ */
void destroyNode(String id); void destroyNode(String id);
/** /**
* nodes matching the filter are treated as a logical set. Using the delete * nodes matching the filter are treated as a logical set. Using the delete command, you can save
* command, you can save time by removing the nodes in parallel. When the * time by removing the nodes in parallel. When the last node in a set is destroyed, any indirect
* last node in a set is destroyed, any indirect resources it uses, such as * resources it uses, such as keypairs, are also destroyed.
* keypairs, are also destroyed.
* *
* @return list of nodes destroyed * @return list of nodes destroyed
*/ */
@ -174,8 +197,8 @@ public interface ComputeService {
void rebootNode(String id); void rebootNode(String id);
/** /**
* nodes matching the filter are treated as a logical set. Using this * nodes matching the filter are treated as a logical set. Using this command, you can save time
* command, you can save time by rebooting the nodes in parallel. * by rebooting the nodes in parallel.
*/ */
void rebootNodesMatching(Predicate<NodeMetadata> filter); void rebootNodesMatching(Predicate<NodeMetadata> filter);
@ -185,8 +208,8 @@ public interface ComputeService {
NodeMetadata getNodeMetadata(String id); NodeMetadata getNodeMetadata(String id);
/** /**
* get all nodes including details such as image and ip addresses even if it * get all nodes including details such as image and ip addresses even if it incurs extra
* incurs extra requests to the service. * requests to the service.
* *
* @param filter * @param filter
* how to select the nodes you are interested in details on. * how to select the nodes you are interested in details on.
@ -196,24 +219,22 @@ public interface ComputeService {
/** /**
* Runs the script without any additional options * Runs the script without any additional options
* *
* @see #runScriptOnNodesMatching(Predicate, Payload, * @see #runScriptOnNodesMatching(Predicate, Payload,
* 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)
*/ */
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 tag.
* *
* @param filter * @param filter
* Predicate-based filter to define on which nodes the script is to * Predicate-based filter to define on which nodes the script is to be executed
* be executed
* @param runScript * @param runScript
* payload containing the script to run * payload containing the script to run
* @param options * @param options
* nullable options to how to run the script, whether to override * nullable options to how to run the script, whether to override credentials
* credentials
* @return map with node identifiers and corresponding responses * @return map with node identifiers and corresponding responses
* @throws RunScriptOnNodesException * @throws RunScriptOnNodesException
* if anything goes wrong during script execution * if anything goes wrong during script execution
@ -222,6 +243,6 @@ public interface ComputeService {
* @see org.jclouds.io.Payloads * @see org.jclouds.io.Payloads
*/ */
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;
} }

View File

@ -36,30 +36,32 @@ public interface ComputeServiceAdapter<N, H, I, L> {
/** /**
* {@link ComputeService#runNodesWithTag(String, int, Template)} generates the parameters passed * {@link ComputeService#runNodesWithTag(String, int, Template)} generates the parameters passed
* into this method such that each node in the set has a unique name. * into this method such that each node in the set has a unique name.
* <p/> *
* Your responsibility is to create a node with the underlying library and return after storing * <h4>note</h4> It is intentional to return the library native node object, as generic type
* its credentials in the supplied map.
* <p/>
* Note that it is intentional to return the library native node object, as generic type
* {@code N}. If you are not using library-native objects (such as libvirt {@code Domain}) use * {@code N}. If you are not using library-native objects (such as libvirt {@code Domain}) use
* {@link JCloudsNativeComputeServiceAdapter} instead. * {@link JCloudsNativeComputeServiceAdapter} instead.
* *
* <h4>note</h4> Your responsibility is to create a node with the underlying library and return
* after storing its credentials in the supplied map corresponding to
* {@link ComputeServiceContext#getCredentialStore credentialStore}
*
* @param tag * @param tag
* used to aggregate nodes with identical configuration * used to aggregate nodes with identical configuration
* @param name * @param name
* unique supplied name for the node, which has the tag encoded into it. * unique supplied name for the node, which has the tag encoded into it.
* @param template * @param template
* includes {@code imageId}, {@code locationId}, and {@code hardwareId} used to start * includes {@code imageId}, {@code locationId}, and {@code hardwareId} used to resume
* the instance. * the instance.
* @param credentialStore * @param credentialStore
* once the node is started, its login user and password will be encoded based on the * once the node is resumeed, its login user and password must be stored keyed on
* node {@code id} * {@code node#id}.
* @return library-native representation of a node. * @return library-native representation of a node.
* *
* @see ComputeService#runNodesWithTag(String, int, Template) * @see ComputeService#runNodesWithTag(String, int, Template)
* @see ComputeServiceContext#getCredentialStore
*/ */
N runNodeWithTagAndNameAndStoreCredentials(String tag, String name, Template template, N runNodeWithTagAndNameAndStoreCredentials(String tag, String name, Template template,
Map<String, Credentials> credentialStore); Map<String, Credentials> credentialStore);
/** /**
* Hardware profiles describe available cpu, memory, and disk configurations that can be used to * Hardware profiles describe available cpu, memory, and disk configurations that can be used to
@ -92,6 +94,10 @@ public interface ComputeServiceAdapter<N, H, I, L> {
void rebootNode(String id); void rebootNode(String id);
void resumeNode(String id);
void suspendNode(String id);
Iterable<N> listNodes(); Iterable<N> listNodes();
} }

View File

@ -50,13 +50,26 @@ public interface ComputeServiceContext {
/** /**
* retrieves a list of credentials for resources created within this context, keyed on {@code id} * retrieves a list of credentials for resources created within this context, keyed on {@code id}
* of the resource. We are testing this approach for resources such as compute nodes, where you * of the resource with a namespace prefix (ex. {@code node#}. We are testing this approach for
* could access this externally. * resources such as compute nodes, where you could access this externally.
* * <p/>
* <h4>accessing credentials for a node</h4>
* <p/>
* the key is in the form {@code node#id}.
* <ul>
* <li>if the node id is {@code 8}, then the key will be {@code node#8}</li>
* <li>if the node id is {@code us-east-1/i-asdfdas}, then the key will be {@code
* node#us-east-1/i-asdfdas}</li>
* <li>if the node id is {@code http://cloud/instances/1}, then the key will be {@code
* node#http://cloud/instances/1}</li>
* </ul>
*/ */
@Beta @Beta
Map<String, Credentials> getCredentialStore(); Map<String, Credentials> getCredentialStore();
/**
* @see ComputeServiceContext#getCredentialStore
*/
@Beta @Beta
Map<String, Credentials> credentialStore(); Map<String, Credentials> credentialStore();

View File

@ -21,9 +21,11 @@ package org.jclouds.compute;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.internal.UtilsImpl; import org.jclouds.compute.internal.UtilsImpl;
import org.jclouds.ssh.SshClient; import org.jclouds.ssh.SshClient;
import com.google.common.base.Function;
import com.google.inject.ImplementedBy; import com.google.inject.ImplementedBy;
/** /**
@ -37,4 +39,9 @@ public interface Utils extends org.jclouds.rest.Utils {
@Nullable @Nullable
SshClient.Factory sshFactory(); SshClient.Factory sshFactory();
/**
* @return function that gets an ssh client for a node that is available via ssh.
*/
Function<NodeMetadata, SshClient> sshForNode();
} }

View File

@ -24,7 +24,6 @@ import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Collections; import java.util.Collections;
import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.util.ComputeServiceUtils;
import org.jclouds.compute.util.ComputeServiceUtils.SshCallable; import org.jclouds.compute.util.ComputeServiceUtils.SshCallable;
import org.jclouds.logging.Logger; import org.jclouds.logging.Logger;
import org.jclouds.scriptbuilder.InitBuilder; import org.jclouds.scriptbuilder.InitBuilder;
@ -33,6 +32,7 @@ import org.jclouds.scriptbuilder.domain.Statement;
import org.jclouds.ssh.ExecResponse; 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.collect.Iterables; import com.google.common.collect.Iterables;
/** /**
@ -77,8 +77,9 @@ public class InitAndStartScriptOnNode implements SshCallable<ExecResponse> {
protected ExecResponse runCommand(String command) { protected ExecResponse runCommand(String command) {
ExecResponse returnVal; ExecResponse returnVal;
logger.debug(">> running [%s] as %s@%s", command.replace(node.getCredentials().credential, "XXXXX"), node logger.debug(">> running [%s] as %s@%s", command.replace(node.getAdminPassword() != null ? node
.getCredentials().identity, Iterables.get(node.getPublicAddresses(), 0)); .getAdminPassword() : "XXXXX", "XXXXX"), node.getCredentials().identity, Iterables.get(node
.getPublicAddresses(), 0));
returnVal = ssh.exec(command); returnVal = ssh.exec(command);
return returnVal; return returnVal;
} }
@ -89,15 +90,15 @@ public class InitAndStartScriptOnNode implements SshCallable<ExecResponse> {
this.ssh = checkNotNull(ssh, "ssh"); this.ssh = checkNotNull(ssh, "ssh");
} }
protected String execScriptAsRoot(String action) { @VisibleForTesting
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 = "./" + init.getInstanceName() + " " + action;
} else if (ComputeServiceUtils.isKeyAuth(node)) { } else if (node.getAdminPassword() != null) {
command = "sudo ./" + init.getInstanceName() + " " + action; command = String.format("echo '%s'|sudo -S ./%s %s", node.getAdminPassword(), init.getInstanceName(), action);
} else { } else {
command = String.format("echo '%s'|sudo -S ./%s %s", node.getCredentials().credential, init.getInstanceName(), command = "sudo ./" + init.getInstanceName() + " " + action;
action);
} }
return command; return command;
} }

View File

@ -34,10 +34,13 @@ import org.jclouds.compute.LoadBalancerService;
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;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.TemplateBuilder; import org.jclouds.compute.domain.TemplateBuilder;
import org.jclouds.compute.functions.CreateSshClientOncePortIsListeningOnNode;
import org.jclouds.domain.Location; import org.jclouds.domain.Location;
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.ssh.SshClient;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.google.common.base.Supplier; import com.google.common.base.Supplier;
@ -47,6 +50,7 @@ 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.Scopes; import com.google.inject.Scopes;
import com.google.inject.TypeLiteral;
import com.google.inject.util.Providers; import com.google.inject.util.Providers;
/** /**
@ -58,6 +62,8 @@ public abstract class BaseComputeServiceContextModule extends AbstractModule {
protected void configure() { protected void configure() {
install(new ComputeServiceTimeoutsModule()); install(new ComputeServiceTimeoutsModule());
bindLoadBalancerService(); bindLoadBalancerService();
bind(new TypeLiteral<Function<NodeMetadata, SshClient>>() {
}).to(CreateSshClientOncePortIsListeningOnNode.class);
} }
protected void bindLoadBalancerService() { protected void bindLoadBalancerService() {

View File

@ -25,6 +25,8 @@ import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
import org.jclouds.compute.strategy.ListNodesStrategy; import org.jclouds.compute.strategy.ListNodesStrategy;
import org.jclouds.compute.strategy.RebootNodeStrategy; import org.jclouds.compute.strategy.RebootNodeStrategy;
import org.jclouds.compute.strategy.RunNodesAndAddToSetStrategy; import org.jclouds.compute.strategy.RunNodesAndAddToSetStrategy;
import org.jclouds.compute.strategy.ResumeNodeStrategy;
import org.jclouds.compute.strategy.SuspendNodeStrategy;
import org.jclouds.compute.strategy.impl.EncodeTagIntoNameRunNodesAndAddToSetStrategy; import org.jclouds.compute.strategy.impl.EncodeTagIntoNameRunNodesAndAddToSetStrategy;
import com.google.inject.AbstractModule; import com.google.inject.AbstractModule;
@ -42,6 +44,8 @@ public abstract class BindComputeStrategiesByClass extends AbstractModule {
bindListNodesStrategy(defineListNodesStrategy()); bindListNodesStrategy(defineListNodesStrategy());
bindGetNodeMetadataStrategy(defineGetNodeMetadataStrategy()); bindGetNodeMetadataStrategy(defineGetNodeMetadataStrategy());
bindRebootNodeStrategy(defineRebootNodeStrategy()); bindRebootNodeStrategy(defineRebootNodeStrategy());
bindStartNodeStrategy(defineStartNodeStrategy());
bindStopNodeStrategy(defineStopNodeStrategy());
bindDestroyNodeStrategy(defineDestroyNodeStrategy()); bindDestroyNodeStrategy(defineDestroyNodeStrategy());
} }
@ -64,6 +68,14 @@ public abstract class BindComputeStrategiesByClass extends AbstractModule {
bind(RebootNodeStrategy.class).to(clazz).in(Scopes.SINGLETON); bind(RebootNodeStrategy.class).to(clazz).in(Scopes.SINGLETON);
} }
protected void bindStartNodeStrategy(Class<? extends ResumeNodeStrategy> clazz) {
bind(ResumeNodeStrategy.class).to(clazz).in(Scopes.SINGLETON);
}
protected void bindStopNodeStrategy(Class<? extends SuspendNodeStrategy> clazz) {
bind(SuspendNodeStrategy.class).to(clazz).in(Scopes.SINGLETON);
}
protected void bindGetNodeMetadataStrategy(Class<? extends GetNodeMetadataStrategy> clazz) { protected void bindGetNodeMetadataStrategy(Class<? extends GetNodeMetadataStrategy> clazz) {
bind(GetNodeMetadataStrategy.class).to(clazz).in(Scopes.SINGLETON); bind(GetNodeMetadataStrategy.class).to(clazz).in(Scopes.SINGLETON);
} }
@ -85,6 +97,10 @@ public abstract class BindComputeStrategiesByClass extends AbstractModule {
protected abstract Class<? extends RebootNodeStrategy> defineRebootNodeStrategy(); protected abstract Class<? extends RebootNodeStrategy> defineRebootNodeStrategy();
protected abstract Class<? extends ResumeNodeStrategy> defineStartNodeStrategy();
protected abstract Class<? extends SuspendNodeStrategy> defineStopNodeStrategy();
protected abstract Class<? extends GetNodeMetadataStrategy> defineGetNodeMetadataStrategy(); protected abstract Class<? extends GetNodeMetadataStrategy> defineGetNodeMetadataStrategy();
protected abstract Class<? extends ListNodesStrategy> defineListNodesStrategy(); protected abstract Class<? extends ListNodesStrategy> defineListNodesStrategy();

View File

@ -26,13 +26,12 @@ import javax.inject.Singleton;
import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.predicates.NodeRunning; import org.jclouds.compute.predicates.NodeRunning;
import org.jclouds.compute.predicates.NodeSuspended;
import org.jclouds.compute.predicates.NodeTerminated; import org.jclouds.compute.predicates.NodeTerminated;
import org.jclouds.compute.predicates.ScriptStatusReturnsZero; import org.jclouds.compute.predicates.ScriptStatusReturnsZero;
import org.jclouds.compute.predicates.ScriptStatusReturnsZero.CommandUsingClient; import org.jclouds.compute.predicates.ScriptStatusReturnsZero.CommandUsingClient;
import org.jclouds.compute.reference.ComputeServiceConstants.Timeouts; import org.jclouds.compute.reference.ComputeServiceConstants.Timeouts;
import org.jclouds.net.IPSocket;
import org.jclouds.predicates.RetryablePredicate; import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.predicates.SocketOpen;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
import com.google.inject.AbstractModule; import com.google.inject.AbstractModule;
@ -50,7 +49,7 @@ public class ComputeServiceTimeoutsModule extends AbstractModule {
@Named("NODE_RUNNING") @Named("NODE_RUNNING")
protected Predicate<NodeMetadata> nodeRunning(NodeRunning stateRunning, Timeouts timeouts) { protected Predicate<NodeMetadata> nodeRunning(NodeRunning stateRunning, Timeouts timeouts) {
return timeouts.nodeRunning == 0 ? stateRunning : new RetryablePredicate<NodeMetadata>(stateRunning, return timeouts.nodeRunning == 0 ? stateRunning : new RetryablePredicate<NodeMetadata>(stateRunning,
timeouts.nodeRunning); timeouts.nodeRunning);
} }
@Provides @Provides
@ -58,7 +57,16 @@ public class ComputeServiceTimeoutsModule extends AbstractModule {
@Named("NODE_TERMINATED") @Named("NODE_TERMINATED")
protected Predicate<NodeMetadata> serverTerminated(NodeTerminated stateTerminated, Timeouts timeouts) { protected Predicate<NodeMetadata> serverTerminated(NodeTerminated stateTerminated, Timeouts timeouts) {
return timeouts.nodeTerminated == 0 ? stateTerminated : new RetryablePredicate<NodeMetadata>(stateTerminated, return timeouts.nodeTerminated == 0 ? stateTerminated : new RetryablePredicate<NodeMetadata>(stateTerminated,
timeouts.nodeTerminated); timeouts.nodeTerminated);
}
@Provides
@Singleton
@Named("NODE_SUSPENDED")
protected Predicate<NodeMetadata> serverSuspended(NodeSuspended stateSuspended, Timeouts timeouts) {
return timeouts.nodeSuspended == 0 ? stateSuspended : new RetryablePredicate<NodeMetadata>(stateSuspended,
timeouts.nodeSuspended);
} }
@Provides @Provides
@ -66,13 +74,7 @@ public class ComputeServiceTimeoutsModule extends AbstractModule {
@Named("SCRIPT_COMPLETE") @Named("SCRIPT_COMPLETE")
protected Predicate<CommandUsingClient> runScriptRunning(ScriptStatusReturnsZero stateRunning, Timeouts timeouts) { protected Predicate<CommandUsingClient> runScriptRunning(ScriptStatusReturnsZero stateRunning, Timeouts timeouts) {
return timeouts.scriptComplete == 0 ? not(stateRunning) : new RetryablePredicate<CommandUsingClient>( return timeouts.scriptComplete == 0 ? not(stateRunning) : new RetryablePredicate<CommandUsingClient>(
not(stateRunning), timeouts.scriptComplete); not(stateRunning), timeouts.scriptComplete);
}
@Provides
@Singleton
protected Predicate<IPSocket> socketTester(SocketOpen open, Timeouts timeouts) {
return timeouts.portOpen == 0 ? open : new RetryablePredicate<IPSocket>(open, timeouts.portOpen);
} }
@Override @Override

View File

@ -38,6 +38,8 @@ import org.jclouds.compute.strategy.DestroyNodeStrategy;
import org.jclouds.compute.strategy.GetNodeMetadataStrategy; import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
import org.jclouds.compute.strategy.ListNodesStrategy; 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.SuspendNodeStrategy;
import org.jclouds.compute.strategy.impl.AdaptingComputeServiceStrategies; import org.jclouds.compute.strategy.impl.AdaptingComputeServiceStrategies;
import org.jclouds.compute.suppliers.DefaultLocationSupplier; import org.jclouds.compute.suppliers.DefaultLocationSupplier;
import org.jclouds.domain.Location; import org.jclouds.domain.Location;
@ -82,7 +84,7 @@ public class StandaloneComputeServiceContextModule<N, H, I, L> extends BaseCompu
@Provides @Provides
@Singleton @Singleton
protected Supplier<Set<? extends Hardware>> provideHardware(final ComputeServiceAdapter<N, H, I, L> adapter, protected Supplier<Set<? extends Hardware>> provideHardware(final ComputeServiceAdapter<N, H, I, L> adapter,
Function<H, Hardware> transformer) { Function<H, Hardware> transformer) {
return new TransformingSetSupplier<H, Hardware>(new Supplier<Iterable<H>>() { return new TransformingSetSupplier<H, Hardware>(new Supplier<Iterable<H>>() {
@Override @Override
@ -96,7 +98,7 @@ public class StandaloneComputeServiceContextModule<N, H, I, L> extends BaseCompu
@Provides @Provides
@Singleton @Singleton
protected Supplier<Set<? extends Image>> provideImages(final ComputeServiceAdapter<N, H, I, L> adapter, protected Supplier<Set<? extends Image>> provideImages(final ComputeServiceAdapter<N, H, I, L> adapter,
Function<I, Image> transformer) { Function<I, Image> transformer) {
return new TransformingSetSupplier<I, Image>(new Supplier<Iterable<I>>() { return new TransformingSetSupplier<I, Image>(new Supplier<Iterable<I>>() {
@Override @Override
@ -115,7 +117,7 @@ public class StandaloneComputeServiceContextModule<N, H, I, L> extends BaseCompu
@Provides @Provides
@Singleton @Singleton
protected Supplier<Set<? extends Location>> provideLocations(final ComputeServiceAdapter<N, H, I, L> adapter, protected Supplier<Set<? extends Location>> provideLocations(final ComputeServiceAdapter<N, H, I, L> adapter,
Function<L, Location> transformer) { Function<L, Location> transformer) {
return new TransformingSetSupplier<L, Location>(new Supplier<Iterable<L>>() { return new TransformingSetSupplier<L, Location>(new Supplier<Iterable<L>>() {
@Override @Override
@ -156,6 +158,18 @@ public class StandaloneComputeServiceContextModule<N, H, I, L> extends BaseCompu
return in; return in;
} }
@Provides
@Singleton
protected ResumeNodeStrategy defineStartNodeStrategy(AdaptingComputeServiceStrategies<N, H, I, L> in) {
return in;
}
@Provides
@Singleton
protected SuspendNodeStrategy defineStopNodeStrategy(AdaptingComputeServiceStrategies<N, H, I, L> in) {
return in;
}
// enum singleton pattern // enum singleton pattern
public static enum IdentityFunction implements Function<Object, Object> { public static enum IdentityFunction implements Function<Object, Object> {
INSTANCE; INSTANCE;

View File

@ -19,6 +19,8 @@
package org.jclouds.compute.domain; package org.jclouds.compute.domain;
import javax.annotation.Nullable;
import org.jclouds.compute.domain.internal.ImageImpl; import org.jclouds.compute.domain.internal.ImageImpl;
import org.jclouds.domain.Credentials; import org.jclouds.domain.Credentials;
@ -48,6 +50,17 @@ public interface Image extends ComputeMetadata {
*/ */
String getDescription(); String getDescription();
/**
* secures access to root with a password. This password is required to access either the console
* or run sudo as root.
* <p/>
* ex. {@code echo 'password' |sudo -S command}
*
* @return root or console password, if configured, or null.
*/
@Nullable
String getAdminPassword();
/** /**
* Default credentials for the current image * Default credentials for the current image
*/ */

View File

@ -37,6 +37,8 @@ public class ImageBuilder extends ComputeMetadataBuilder {
private OperatingSystem operatingSystem; private OperatingSystem operatingSystem;
private String version; private String version;
private String description; private String description;
@Nullable
private String adminPassword;
private Credentials defaultCredentials; private Credentials defaultCredentials;
public ImageBuilder() { public ImageBuilder() {
@ -58,6 +60,11 @@ public class ImageBuilder extends ComputeMetadataBuilder {
return this; return this;
} }
public ImageBuilder adminPassword(@Nullable String adminPassword) {
this.adminPassword = adminPassword;
return this;
}
public ImageBuilder defaultCredentials(@Nullable Credentials defaultCredentials) { public ImageBuilder defaultCredentials(@Nullable Credentials defaultCredentials) {
this.defaultCredentials = defaultCredentials; this.defaultCredentials = defaultCredentials;
return this; return this;
@ -101,7 +108,14 @@ public class ImageBuilder extends ComputeMetadataBuilder {
@Override @Override
public Image build() { public Image build() {
return new ImageImpl(providerId, name, id, location, uri, userMetadata, operatingSystem, description, version, return new ImageImpl(providerId, name, id, location, uri, userMetadata, operatingSystem, description, version,
defaultCredentials); adminPassword, defaultCredentials);
}
public static ImageBuilder fromImage(Image image) {
return new ImageBuilder().providerId(image.getProviderId()).name(image.getName()).id(image.getId()).location(
image.getLocation()).uri(image.getUri()).userMetadata(image.getUserMetadata()).version(
image.getVersion()).description(image.getDescription()).operatingSystem(image.getOperatingSystem())
.adminPassword(image.getAdminPassword()).defaultCredentials(image.getDefaultCredentials());
} }
} }

View File

@ -43,7 +43,7 @@ public interface NodeMetadata extends ComputeMetadata {
* *
*/ */
String getTag(); String getTag();
/** /**
* *
* The harware this node is running, if possible to determine. * The harware this node is running, if possible to determine.
@ -70,6 +70,28 @@ public interface NodeMetadata extends ComputeMetadata {
*/ */
NodeState getState(); NodeState getState();
/**
* @return the TCP port used for terminal connections. Generally, this is port 22 for ssh.
*/
int getLoginPort();
/**
* secures access to root with a password. This password is required to access either the console
* or run sudo as root.
* <p/>
* ex. {@code echo 'password' |sudo -S command}
*
* @return root or console password, if configured, or null.
*/
@Nullable
String getAdminPassword();
/**
* If possible, these are returned upon all detail requests. However, it is often the case that
* credentials are only available at "run" time.
*/
Credentials getCredentials();
/** /**
* All public IP addresses, potentially including shared ips. * All public IP addresses, potentially including shared ips.
*/ */
@ -80,10 +102,4 @@ public interface NodeMetadata extends ComputeMetadata {
*/ */
Set<String> getPrivateAddresses(); Set<String> getPrivateAddresses();
/**
* If possible, these are returned upon all detail requests. However, it is often the case that
* credentials are only available at "run" time.
*/
Credentials getCredentials();
} }

View File

@ -42,9 +42,12 @@ public class NodeMetadataBuilder extends ComputeMetadataBuilder {
private Set<String> publicAddresses = Sets.newLinkedHashSet(); private Set<String> publicAddresses = Sets.newLinkedHashSet();
private Set<String> privateAddresses = Sets.newLinkedHashSet(); private Set<String> privateAddresses = Sets.newLinkedHashSet();
@Nullable @Nullable
private String adminPassword;
@Nullable
private Credentials credentials; private Credentials credentials;
@Nullable @Nullable
private String tag; private String tag;
private int loginPort = 22;
@Nullable @Nullable
private String imageId; private String imageId;
@Nullable @Nullable
@ -56,6 +59,11 @@ public class NodeMetadataBuilder extends ComputeMetadataBuilder {
super(ComputeType.NODE); super(ComputeType.NODE);
} }
public NodeMetadataBuilder loginPort(int loginPort) {
this.loginPort = loginPort;
return this;
}
public NodeMetadataBuilder state(NodeState state) { public NodeMetadataBuilder state(NodeState state) {
this.state = checkNotNull(state, "state"); this.state = checkNotNull(state, "state");
return this; return this;
@ -76,6 +84,11 @@ public class NodeMetadataBuilder extends ComputeMetadataBuilder {
return this; return this;
} }
public NodeMetadataBuilder adminPassword(@Nullable String adminPassword) {
this.adminPassword = adminPassword;
return this;
}
public NodeMetadataBuilder tag(@Nullable String tag) { public NodeMetadataBuilder tag(@Nullable String tag) {
this.tag = tag; this.tag = tag;
return this; return this;
@ -134,15 +147,16 @@ public class NodeMetadataBuilder extends ComputeMetadataBuilder {
@Override @Override
public NodeMetadata build() { public NodeMetadata build() {
return new NodeMetadataImpl(providerId, name, id, location, uri, userMetadata, tag, hardware, imageId, os, state, return new NodeMetadataImpl(providerId, name, id, location, uri, userMetadata, tag, hardware, imageId, os, state,
publicAddresses, privateAddresses, credentials); loginPort, publicAddresses, privateAddresses, adminPassword, credentials);
} }
public static NodeMetadataBuilder fromNodeMetadata(NodeMetadata node) { public static NodeMetadataBuilder fromNodeMetadata(NodeMetadata node) {
return new NodeMetadataBuilder().providerId(node.getProviderId()).name(node.getName()).id(node.getId()) return new NodeMetadataBuilder().providerId(node.getProviderId()).name(node.getName()).id(node.getId()).location(
.location(node.getLocation()).uri(node.getUri()).userMetadata(node.getUserMetadata()).tag(node.getTag()) node.getLocation()).uri(node.getUri()).userMetadata(node.getUserMetadata()).tag(node.getTag()).hardware(
.hardware(node.getHardware()).imageId(node.getImageId()).operatingSystem(node.getOperatingSystem()) node.getHardware()).imageId(node.getImageId()).operatingSystem(node.getOperatingSystem()).state(
.state(node.getState()).publicAddresses(node.getPublicAddresses()) node.getState()).loginPort(node.getLoginPort()).publicAddresses(node.getPublicAddresses())
.privateAddresses(node.getPrivateAddresses()).credentials(node.getCredentials()); .privateAddresses(node.getPrivateAddresses()).adminPassword(node.getAdminPassword()).credentials(
node.getCredentials());
} }
} }

View File

@ -43,15 +43,18 @@ public class ImageImpl extends ComputeMetadataImpl implements Image {
private final OperatingSystem operatingSystem; private final OperatingSystem operatingSystem;
private final String version; private final String version;
private final String description; private final String description;
@Nullable
private final String adminPassword;
private final Credentials defaultCredentials; private final Credentials defaultCredentials;
public ImageImpl(String providerId, String name, String id, Location location, URI uri, public ImageImpl(String providerId, String name, String id, Location location, URI uri,
Map<String, String> userMetadata, OperatingSystem operatingSystem, String description, Map<String, String> userMetadata, OperatingSystem operatingSystem, String description,
@Nullable String version, @Nullable Credentials defaultCredentials) { @Nullable String version, @Nullable String adminPassword, @Nullable Credentials defaultCredentials) {
super(ComputeType.IMAGE, providerId, name, id, location, uri, userMetadata); super(ComputeType.IMAGE, providerId, name, id, location, uri, userMetadata);
this.operatingSystem = checkNotNull(operatingSystem, "operatingSystem"); this.operatingSystem = checkNotNull(operatingSystem, "operatingSystem");
this.version = version; this.version = version;
this.description = checkNotNull(description, "description"); this.description = checkNotNull(description, "description");
this.adminPassword = adminPassword;
this.defaultCredentials = defaultCredentials; this.defaultCredentials = defaultCredentials;
} }
@ -87,18 +90,27 @@ public class ImageImpl extends ComputeMetadataImpl implements Image {
return defaultCredentials; return defaultCredentials;
} }
/**
* {@inheritDoc}
*/
@Override
public String getAdminPassword() {
return adminPassword;
}
@Override @Override
public String toString() { public String toString() {
return "[id=" + getId() + ", name=" + getName() + ", operatingSystem=" + operatingSystem + ", description=" return "[id=" + getId() + ", name=" + getName() + ", operatingSystem=" + operatingSystem + ", description="
+ description + ", version=" + version + ", location=" + getLocation() + ", loginUser=" + description + ", version=" + version + ", location=" + getLocation() + ", loginUser="
+ ((defaultCredentials != null) ? defaultCredentials.identity : null) + ", userMetadata=" + ((defaultCredentials != null) ? defaultCredentials.identity : null) + ", userMetadata="
+ getUserMetadata() + "]"; + getUserMetadata() + "]";
} }
@Override @Override
public int hashCode() { public int hashCode() {
final int prime = 31; final int prime = 31;
int result = super.hashCode(); int result = super.hashCode();
result = prime * result + ((adminPassword == null) ? 0 : adminPassword.hashCode());
result = prime * result + ((defaultCredentials == null) ? 0 : defaultCredentials.hashCode()); result = prime * result + ((defaultCredentials == null) ? 0 : defaultCredentials.hashCode());
result = prime * result + ((description == null) ? 0 : description.hashCode()); result = prime * result + ((description == null) ? 0 : description.hashCode());
result = prime * result + ((operatingSystem == null) ? 0 : operatingSystem.hashCode()); result = prime * result + ((operatingSystem == null) ? 0 : operatingSystem.hashCode());
@ -115,6 +127,11 @@ public class ImageImpl extends ComputeMetadataImpl implements Image {
if (getClass() != obj.getClass()) if (getClass() != obj.getClass())
return false; return false;
ImageImpl other = (ImageImpl) obj; ImageImpl other = (ImageImpl) obj;
if (adminPassword == null) {
if (other.adminPassword != null)
return false;
} else if (!adminPassword.equals(other.adminPassword))
return false;
if (defaultCredentials == null) { if (defaultCredentials == null) {
if (other.defaultCredentials != null) if (other.defaultCredentials != null)
return false; return false;

View File

@ -47,9 +47,12 @@ public class NodeMetadataImpl extends ComputeMetadataImpl implements NodeMetadat
private static final long serialVersionUID = 7924307572338157887L; private static final long serialVersionUID = 7924307572338157887L;
private final NodeState state; private final NodeState state;
private final int loginPort;
private final Set<String> publicAddresses; private final Set<String> publicAddresses;
private final Set<String> privateAddresses; private final Set<String> privateAddresses;
@Nullable @Nullable
private final String adminPassword;
@Nullable
private final Credentials credentials; private final Credentials credentials;
@Nullable @Nullable
private final String tag; private final String tag;
@ -61,17 +64,20 @@ public class NodeMetadataImpl extends ComputeMetadataImpl implements NodeMetadat
private final OperatingSystem os; private final OperatingSystem os;
public NodeMetadataImpl(String providerId, String name, String id, Location location, URI uri, public NodeMetadataImpl(String providerId, String name, String id, Location location, URI uri,
Map<String, String> userMetadata, @Nullable String tag, @Nullable Hardware hardware, @Nullable String imageId, Map<String, String> userMetadata, @Nullable String tag, @Nullable Hardware hardware,
@Nullable OperatingSystem os, NodeState state, Iterable<String> publicAddresses, @Nullable String imageId, @Nullable OperatingSystem os, NodeState state, int loginPort,
Iterable<String> privateAddresses, @Nullable Credentials credentials) { Iterable<String> publicAddresses, Iterable<String> privateAddresses, @Nullable String adminPassword,
@Nullable Credentials credentials) {
super(ComputeType.NODE, providerId, name, id, location, uri, userMetadata); super(ComputeType.NODE, providerId, name, id, location, uri, userMetadata);
this.tag = tag; this.tag = tag;
this.hardware = hardware; this.hardware = hardware;
this.imageId = imageId; this.imageId = imageId;
this.os = os; this.os = os;
this.state = checkNotNull(state, "state"); this.state = checkNotNull(state, "state");
this.loginPort = loginPort;
this.publicAddresses = ImmutableSet.copyOf(checkNotNull(publicAddresses, "publicAddresses")); this.publicAddresses = ImmutableSet.copyOf(checkNotNull(publicAddresses, "publicAddresses"));
this.privateAddresses = ImmutableSet.copyOf(checkNotNull(privateAddresses, "privateAddresses")); this.privateAddresses = ImmutableSet.copyOf(checkNotNull(privateAddresses, "privateAddresses"));
this.adminPassword = adminPassword;
this.credentials = credentials; this.credentials = credentials;
} }
@ -91,6 +97,14 @@ public class NodeMetadataImpl extends ComputeMetadataImpl implements NodeMetadat
return hardware; return hardware;
} }
/**
* {@inheritDoc}
*/
@Override
public String getAdminPassword() {
return adminPassword;
}
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@ -123,6 +137,14 @@ public class NodeMetadataImpl extends ComputeMetadataImpl implements NodeMetadat
return state; return state;
} }
/**
* {@inheritDoc}
*/
@Override
public int getLoginPort() {
return this.loginPort;
}
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@ -142,22 +164,25 @@ public class NodeMetadataImpl extends ComputeMetadataImpl implements NodeMetadat
@Override @Override
public String toString() { public String toString() {
return "[id=" + getId() + ", providerId=" + getProviderId() + ", tag=" + getTag() + ", name=" + getName() return "[id=" + getId() + ", providerId=" + getProviderId() + ", tag=" + getTag() + ", name=" + getName()
+ ", location=" + getLocation() + ", uri=" + getUri() + ", imageId=" + getImageId() + ", os=" + ", location=" + getLocation() + ", uri=" + getUri() + ", imageId=" + getImageId() + ", os="
+ getOperatingSystem() + ", state=" + getState() + ", privateAddresses=" + privateAddresses + getOperatingSystem() + ", state=" + getState() + ", loginPort=" + getLoginPort()
+ ", publicAddresses=" + publicAddresses + ", hardware=" + getHardware() + ", loginUser=" + ", privateAddresses=" + privateAddresses + ", publicAddresses=" + publicAddresses + ", hardware="
+ ((credentials != null) ? credentials.identity : null) + ", userMetadata=" + getUserMetadata() + "]"; + getHardware() + ", loginUser=" + ((credentials != null) ? credentials.identity : null)
+ ", userMetadata=" + getUserMetadata() + "]";
} }
@Override @Override
public int hashCode() { public int hashCode() {
final int prime = 31; final int prime = 31;
int result = super.hashCode(); int result = super.hashCode();
result = prime * result + loginPort;
result = prime * result + ((privateAddresses == null) ? 0 : privateAddresses.hashCode()); result = prime * result + ((privateAddresses == null) ? 0 : privateAddresses.hashCode());
result = prime * result + ((publicAddresses == null) ? 0 : publicAddresses.hashCode()); result = prime * result + ((publicAddresses == null) ? 0 : publicAddresses.hashCode());
result = prime * result + ((tag == null) ? 0 : tag.hashCode()); result = prime * result + ((tag == null) ? 0 : tag.hashCode());
result = prime * result + ((imageId == null) ? 0 : imageId.hashCode()); result = prime * result + ((imageId == null) ? 0 : imageId.hashCode());
result = prime * result + ((hardware == null) ? 0 : hardware.hashCode()); result = prime * result + ((hardware == null) ? 0 : hardware.hashCode());
result = prime * result + ((os == null) ? 0 : os.hashCode()); result = prime * result + ((os == null) ? 0 : os.hashCode());
result = prime * result + ((adminPassword == null) ? 0 : adminPassword.hashCode());
result = prime * result + ((credentials == null) ? 0 : credentials.hashCode()); result = prime * result + ((credentials == null) ? 0 : credentials.hashCode());
return result; return result;
} }
@ -171,6 +196,8 @@ public class NodeMetadataImpl extends ComputeMetadataImpl implements NodeMetadat
if (getClass() != obj.getClass()) if (getClass() != obj.getClass())
return false; return false;
NodeMetadataImpl other = (NodeMetadataImpl) obj; NodeMetadataImpl other = (NodeMetadataImpl) obj;
if (loginPort != other.loginPort)
return false;
if (privateAddresses == null) { if (privateAddresses == null) {
if (other.privateAddresses != null) if (other.privateAddresses != null)
return false; return false;
@ -201,6 +228,11 @@ public class NodeMetadataImpl extends ComputeMetadataImpl implements NodeMetadat
return false; return false;
} else if (!os.equals(other.os)) } else if (!os.equals(other.os))
return false; return false;
if (adminPassword == null) {
if (other.adminPassword != null)
return false;
} else if (!adminPassword.equals(other.adminPassword))
return false;
if (credentials == null) { if (credentials == null) {
if (other.credentials != null) if (other.credentials != null)
return false; return false;

View File

@ -116,9 +116,9 @@ public class TemplateBuilderImpl implements TemplateBuilder {
@Inject @Inject
protected TemplateBuilderImpl(@Memoized Supplier<Set<? extends Location>> locations, protected TemplateBuilderImpl(@Memoized Supplier<Set<? extends Location>> locations,
@Memoized Supplier<Set<? extends Image>> images, @Memoized Supplier<Set<? extends Hardware>> hardwares, @Memoized Supplier<Set<? extends Image>> images, @Memoized Supplier<Set<? extends Hardware>> hardwares,
Supplier<Location> defaultLocation2, Provider<TemplateOptions> optionsProvider, Supplier<Location> defaultLocation2, Provider<TemplateOptions> optionsProvider,
@Named("DEFAULT") Provider<TemplateBuilder> defaultTemplateProvider) { @Named("DEFAULT") Provider<TemplateBuilder> defaultTemplateProvider) {
this.locations = locations; this.locations = locations;
this.images = images; this.images = images;
this.hardwares = hardwares; this.hardwares = hardwares;
@ -140,7 +140,7 @@ public class TemplateBuilderImpl implements TemplateBuilder {
boolean returnVal = true; boolean returnVal = true;
if (location != null && input.getLocation() != null) if (location != null && input.getLocation() != null)
returnVal = location.equals(input.getLocation()) || location.getParent() != null returnVal = location.equals(input.getLocation()) || location.getParent() != null
&& location.getParent().equals(input.getLocation()); && location.getParent().equals(input.getLocation());
return returnVal; return returnVal;
} }
@ -214,7 +214,7 @@ public class TemplateBuilderImpl implements TemplateBuilder {
returnVal = false; returnVal = false;
else else
returnVal = input.getDescription().contains(osDescription) returnVal = input.getDescription().contains(osDescription)
|| input.getDescription().matches(osDescription); || input.getDescription().matches(osDescription);
} }
return returnVal; return returnVal;
} }
@ -328,8 +328,8 @@ public class TemplateBuilderImpl implements TemplateBuilder {
returnVal = false; returnVal = false;
else else
returnVal = input.getDescription().equals(imageDescription) returnVal = input.getDescription().equals(imageDescription)
|| input.getDescription().contains(imageDescription) || input.getDescription().contains(imageDescription)
|| input.getDescription().matches(imageDescription); || input.getDescription().matches(imageDescription);
} }
return returnVal; return returnVal;
} }
@ -384,12 +384,12 @@ public class TemplateBuilderImpl implements TemplateBuilder {
} }
}; };
private final Predicate<Hardware> hardwarePredicate = and(hardwareIdPredicate, locationPredicate, private final Predicate<Hardware> hardwarePredicate = and(hardwareIdPredicate, locationPredicate,
hardwareCoresPredicate, hardwareRamPredicate); hardwareCoresPredicate, hardwareRamPredicate);
static final Ordering<Hardware> DEFAULT_SIZE_ORDERING = new Ordering<Hardware>() { static final Ordering<Hardware> DEFAULT_SIZE_ORDERING = new Ordering<Hardware>() {
public int compare(Hardware left, Hardware right) { public int compare(Hardware left, Hardware right) {
return ComparisonChain.start().compare(getCores(left), getCores(right)).compare(left.getRam(), right.getRam()) return ComparisonChain.start().compare(getCores(left), getCores(right)).compare(left.getRam(), right.getRam())
.compare(getSpace(left), getSpace(right)).result(); .compare(getSpace(left), getSpace(right)).result();
} }
}; };
static final Ordering<Hardware> BY_CORES_ORDERING = new Ordering<Hardware>() { static final Ordering<Hardware> BY_CORES_ORDERING = new Ordering<Hardware>() {
@ -399,16 +399,16 @@ public class TemplateBuilderImpl implements TemplateBuilder {
}; };
static final Ordering<Image> DEFAULT_IMAGE_ORDERING = new Ordering<Image>() { static final Ordering<Image> DEFAULT_IMAGE_ORDERING = new Ordering<Image>() {
public int compare(Image left, Image right) { public int compare(Image left, Image right) {
return ComparisonChain.start() return ComparisonChain.start().compare(left.getName(), right.getName(),
.compare(left.getName(), right.getName(), Ordering.<String> natural().nullsLast()) Ordering.<String> natural().nullsLast()).compare(left.getVersion(), right.getVersion(),
.compare(left.getVersion(), right.getVersion(), Ordering.<String> natural().nullsLast()) Ordering.<String> natural().nullsLast()).compare(left.getOperatingSystem().getName(),
.compare(left.getOperatingSystem().getName(), right.getOperatingSystem().getName(),// right.getOperatingSystem().getName(),//
Ordering.<String> natural().nullsLast()) Ordering.<String> natural().nullsLast()).compare(left.getOperatingSystem().getVersion(),
.compare(left.getOperatingSystem().getVersion(), right.getOperatingSystem().getVersion(),// right.getOperatingSystem().getVersion(),//
Ordering.<String> natural().nullsLast()) Ordering.<String> natural().nullsLast()).compare(left.getOperatingSystem().getDescription(),
.compare(left.getOperatingSystem().getDescription(), right.getOperatingSystem().getDescription(),// right.getOperatingSystem().getDescription(),//
Ordering.<String> natural().nullsLast()) Ordering.<String> natural().nullsLast()).compare(left.getOperatingSystem().getArch(),
.compare(left.getOperatingSystem().getArch(), right.getOperatingSystem().getArch()).result(); right.getOperatingSystem().getArch()).result();
} }
}; };
@ -427,19 +427,23 @@ public class TemplateBuilderImpl implements TemplateBuilder {
*/ */
@Override @Override
public TemplateBuilder fromHardware(Hardware hardware) { public TemplateBuilder fromHardware(Hardware hardware) {
if (hardware.getLocation() != null) if (currentLocationWiderThan(hardware.getLocation()))
this.location = hardware.getLocation(); this.location = hardware.getLocation();
this.minCores = getCores(hardware); this.minCores = getCores(hardware);
this.minRam = hardware.getRam(); this.minRam = hardware.getRam();
return this; return this;
} }
private boolean currentLocationWiderThan(Location location) {
return this.location == null || (location != null && this.location.getScope().compareTo(location.getScope()) < 0);
}
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override @Override
public TemplateBuilder fromImage(Image image) { public TemplateBuilder fromImage(Image image) {
if (image.getLocation() != null) if (currentLocationWiderThan(image.getLocation()))
this.location = image.getLocation(); this.location = image.getLocation();
if (image.getOperatingSystem().getFamily() != null) if (image.getOperatingSystem().getFamily() != null)
this.osFamily = image.getOperatingSystem().getFamily(); this.osFamily = image.getOperatingSystem().getFamily();
@ -539,7 +543,7 @@ public class TemplateBuilderImpl implements TemplateBuilder {
Iterable<? extends Image> supportedImages = filter(images, buildImagePredicate()); Iterable<? extends Image> supportedImages = filter(images, buildImagePredicate());
if (Iterables.size(supportedImages) == 0) if (Iterables.size(supportedImages) == 0)
throw new NoSuchElementException(String.format( throw new NoSuchElementException(String.format(
"no image matched predicate %s images that didn't match below:\n%s", imagePredicate, images)); "no image matched predicate %s images that didn't match below:\n%s", imagePredicate, images));
Hardware hardware = resolveSize(hardwareSorter(), supportedImages); Hardware hardware = resolveSize(hardwareSorter(), supportedImages);
Image image = resolveImage(hardware, supportedImages); Image image = resolveImage(hardware, supportedImages);
logger.debug("<< matched image(%s)", image); logger.debug("<< matched image(%s)", image);
@ -552,29 +556,29 @@ public class TemplateBuilderImpl implements TemplateBuilder {
Hardware hardware; Hardware hardware;
try { try {
Iterable<? extends Hardware> hardwaresThatAreCompatibleWithOurImages = filter(hardwaresl, Iterable<? extends Hardware> hardwaresThatAreCompatibleWithOurImages = filter(hardwaresl,
new Predicate<Hardware>() { new Predicate<Hardware>() {
@Override @Override
public boolean apply(final Hardware hardware) { public boolean apply(final Hardware hardware) {
return Iterables.any(images, new Predicate<Image>() { return Iterables.any(images, new Predicate<Image>() {
@Override @Override
public boolean apply(Image input) { public boolean apply(Image input) {
return hardware.supportsImage().apply(input); return hardware.supportsImage().apply(input);
} }
@Override @Override
public String toString() { public String toString() {
return "hardware(" + hardware + ").supportsImage()"; return "hardware(" + hardware + ").supportsImage()";
} }
}); });
} }
}); });
hardware = hardwareOrdering.max(filter(hardwaresThatAreCompatibleWithOurImages, hardwarePredicate)); hardware = hardwareOrdering.max(filter(hardwaresThatAreCompatibleWithOurImages, hardwarePredicate));
} catch (NoSuchElementException exception) { } catch (NoSuchElementException exception) {
throw new NoSuchElementException("hardwares don't support any images: " + toString() + "\n" + hardwaresl throw new NoSuchElementException("hardwares don't support any images: " + toString() + "\n" + hardwaresl
+ "\n" + images); + "\n" + images);
} }
logger.debug("<< matched hardware(%s)", hardware); logger.debug("<< matched hardware(%s)", hardware);
return hardware; return hardware;
@ -682,7 +686,7 @@ public class TemplateBuilderImpl implements TemplateBuilder {
// looks verbose, but explicit <Image> type needed for this to compile // looks verbose, but explicit <Image> type needed for this to compile
// properly // properly
Predicate<Image> imagePredicate = predicates.size() == 1 ? Iterables.<Predicate<Image>> get(predicates, 0) Predicate<Image> imagePredicate = predicates.size() == 1 ? Iterables.<Predicate<Image>> get(predicates, 0)
: Predicates.<Image> and(predicates); : Predicates.<Image> and(predicates);
return imagePredicate; return imagePredicate;
} }
@ -830,8 +834,9 @@ public class TemplateBuilderImpl implements TemplateBuilder {
@VisibleForTesting @VisibleForTesting
boolean nothingChangedExceptOptions() { boolean nothingChangedExceptOptions() {
return osFamily == null && location == null && imageId == null && hardwareId == null && osName == null return osFamily == null && location == null && imageId == null && hardwareId == null && osName == null
&& osDescription == null && imageVersion == null && osVersion == null && osArch == null && os64Bit == null && osDescription == null && imageVersion == null && osVersion == null && osArch == null
&& imageName == null && imageDescription == null && minCores == 0 && minRam == 0 && !biggest && !fastest; && os64Bit == null && imageName == null && imageDescription == null && minCores == 0 && minRam == 0
&& !biggest && !fastest;
} }
/** /**
@ -845,10 +850,10 @@ public class TemplateBuilderImpl implements TemplateBuilder {
@Override @Override
public String toString() { public String toString() {
return "[biggest=" + biggest + ", fastest=" + fastest + ", imageName=" + imageName + ", imageDescription=" return "[biggest=" + biggest + ", fastest=" + fastest + ", imageName=" + imageName + ", imageDescription="
+ imageDescription + ", imageId=" + imageId + ", imageVersion=" + imageVersion + ", location=" + location + imageDescription + ", imageId=" + imageId + ", imageVersion=" + imageVersion + ", location="
+ ", minCores=" + minCores + ", minRam=" + minRam + ", osFamily=" + osFamily + ", osName=" + osName + location + ", minCores=" + minCores + ", minRam=" + minRam + ", osFamily=" + osFamily + ", osName="
+ ", osDescription=" + osDescription + ", osVersion=" + osVersion + ", osArch=" + osArch + ", os64Bit=" + osName + ", osDescription=" + osDescription + ", osVersion=" + osVersion + ", osArch=" + osArch
+ os64Bit + ", hardwareId=" + hardwareId + "]"; + ", os64Bit=" + os64Bit + ", hardwareId=" + hardwareId + "]";
} }
@Override @Override

View File

@ -0,0 +1,60 @@
/**
*
* 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.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import javax.inject.Singleton;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.predicates.RetryIfSocketNotYetOpen;
import org.jclouds.compute.util.ComputeServiceUtils;
import org.jclouds.net.IPSocket;
import org.jclouds.ssh.SshClient;
import com.google.common.base.Function;
import com.google.inject.Inject;
/**
*
* @author Adrian Cole
*
*/
@Singleton
public class CreateSshClientOncePortIsListeningOnNode implements Function<NodeMetadata, SshClient> {
@Inject(optional = true)
SshClient.Factory sshFactory;
private final RetryIfSocketNotYetOpen socketTester;
@Inject
public CreateSshClientOncePortIsListeningOnNode(RetryIfSocketNotYetOpen socketTester) {
this.socketTester = socketTester;
}
@Override
public SshClient apply(NodeMetadata node) {
checkState(sshFactory != null, "ssh requested, but no SshModule configured");
checkNotNull(node.getCredentials(), "credentials for node " + node.getName());
checkNotNull(node.getCredentials().credential, "credentials.credential for node " + node.getName());
IPSocket socket = ComputeServiceUtils.findReachableSocketOnNode(socketTester, node, node.getLoginPort());
return sshFactory.create(socket, node.getCredentials());
}
}

View File

@ -74,7 +74,9 @@ import org.jclouds.compute.strategy.DestroyNodeStrategy;
import org.jclouds.compute.strategy.GetNodeMetadataStrategy; import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
import org.jclouds.compute.strategy.ListNodesStrategy; 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.RunNodesAndAddToSetStrategy; import org.jclouds.compute.strategy.RunNodesAndAddToSetStrategy;
import org.jclouds.compute.strategy.SuspendNodeStrategy;
import org.jclouds.compute.util.ComputeUtils; 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;
@ -111,10 +113,13 @@ public class BaseComputeService implements ComputeService {
protected final RunNodesAndAddToSetStrategy runNodesAndAddToSetStrategy; protected final RunNodesAndAddToSetStrategy runNodesAndAddToSetStrategy;
protected final RebootNodeStrategy rebootNodeStrategy; protected final RebootNodeStrategy rebootNodeStrategy;
protected final DestroyNodeStrategy destroyNodeStrategy; protected final DestroyNodeStrategy destroyNodeStrategy;
protected final ResumeNodeStrategy resumeNodeStrategy;
protected final SuspendNodeStrategy suspendNodeStrategy;
protected final Provider<TemplateBuilder> templateBuilderProvider; protected final Provider<TemplateBuilder> templateBuilderProvider;
protected final Provider<TemplateOptions> templateOptionsProvider; protected final Provider<TemplateOptions> templateOptionsProvider;
protected final Predicate<NodeMetadata> nodeRunning; protected final Predicate<NodeMetadata> nodeRunning;
protected final Predicate<NodeMetadata> nodeTerminated; protected final Predicate<NodeMetadata> nodeTerminated;
protected final Predicate<NodeMetadata> nodeSuspended;
protected final ComputeUtils utils; protected final ComputeUtils utils;
protected final Timeouts timeouts; protected final Timeouts timeouts;
protected final ExecutorService executor; protected final ExecutorService executor;
@ -126,9 +131,11 @@ public class BaseComputeService implements ComputeService {
@Memoized Supplier<Set<? extends Location>> locations, ListNodesStrategy listNodesStrategy, @Memoized Supplier<Set<? extends Location>> locations, ListNodesStrategy listNodesStrategy,
GetNodeMetadataStrategy getNodeMetadataStrategy, RunNodesAndAddToSetStrategy runNodesAndAddToSetStrategy, GetNodeMetadataStrategy getNodeMetadataStrategy, RunNodesAndAddToSetStrategy runNodesAndAddToSetStrategy,
RebootNodeStrategy rebootNodeStrategy, DestroyNodeStrategy destroyNodeStrategy, RebootNodeStrategy rebootNodeStrategy, DestroyNodeStrategy destroyNodeStrategy,
ResumeNodeStrategy resumeNodeStrategy, SuspendNodeStrategy suspendNodeStrategy,
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, ComputeUtils utils, Timeouts timeouts, @Named("NODE_TERMINATED") Predicate<NodeMetadata> nodeTerminated,
@Named("NODE_SUSPENDED") Predicate<NodeMetadata> nodeSuspended, ComputeUtils utils, 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");
@ -139,11 +146,14 @@ public class BaseComputeService implements ComputeService {
this.getNodeMetadataStrategy = checkNotNull(getNodeMetadataStrategy, "getNodeMetadataStrategy"); this.getNodeMetadataStrategy = checkNotNull(getNodeMetadataStrategy, "getNodeMetadataStrategy");
this.runNodesAndAddToSetStrategy = checkNotNull(runNodesAndAddToSetStrategy, "runNodesAndAddToSetStrategy"); this.runNodesAndAddToSetStrategy = checkNotNull(runNodesAndAddToSetStrategy, "runNodesAndAddToSetStrategy");
this.rebootNodeStrategy = checkNotNull(rebootNodeStrategy, "rebootNodeStrategy"); this.rebootNodeStrategy = checkNotNull(rebootNodeStrategy, "rebootNodeStrategy");
this.resumeNodeStrategy = checkNotNull(resumeNodeStrategy, "resumeNodeStrategy");
this.suspendNodeStrategy = checkNotNull(suspendNodeStrategy, "suspendNodeStrategy");
this.destroyNodeStrategy = checkNotNull(destroyNodeStrategy, "destroyNodeStrategy"); this.destroyNodeStrategy = checkNotNull(destroyNodeStrategy, "destroyNodeStrategy");
this.templateBuilderProvider = checkNotNull(templateBuilderProvider, "templateBuilderProvider"); this.templateBuilderProvider = checkNotNull(templateBuilderProvider, "templateBuilderProvider");
this.templateOptionsProvider = checkNotNull(templateOptionsProvider, "templateOptionsProvider"); this.templateOptionsProvider = checkNotNull(templateOptionsProvider, "templateOptionsProvider");
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.utils = checkNotNull(utils, "utils"); this.utils = checkNotNull(utils, "utils");
this.timeouts = checkNotNull(timeouts, "timeouts"); this.timeouts = checkNotNull(timeouts, "timeouts");
this.executor = checkNotNull(executor, "executor"); this.executor = checkNotNull(executor, "executor");
@ -174,10 +184,10 @@ public class BaseComputeService implements ComputeService {
Set<NodeMetadata> nodes = newHashSet(); Set<NodeMetadata> nodes = newHashSet();
Map<NodeMetadata, Exception> badNodes = newLinkedHashMap(); Map<NodeMetadata, Exception> badNodes = newLinkedHashMap();
Map<?, Future<Void>> responses = runNodesAndAddToSetStrategy.execute(tag, count, template, nodes, badNodes); Map<?, Future<Void>> responses = runNodesAndAddToSetStrategy.execute(tag, count, template, nodes, badNodes);
Map<?, Exception> executionExceptions = awaitCompletion(responses, executor, null, logger, "starting nodes"); Map<?, Exception> executionExceptions = awaitCompletion(responses, executor, null, logger, "resumeing nodes");
for (NodeMetadata node : concat(nodes, badNodes.keySet())) for (NodeMetadata node : concat(nodes, 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, nodes, executionExceptions, badNodes);
} }
@ -227,7 +237,7 @@ public class BaseComputeService implements ComputeService {
}, timeouts.nodeRunning, 1000, TimeUnit.MILLISECONDS); }, timeouts.nodeRunning, 1000, TimeUnit.MILLISECONDS);
boolean successful = tester.apply(id) && (node.get() == null || nodeTerminated.apply(node.get())); boolean successful = tester.apply(id) && (node.get() == null || nodeTerminated.apply(node.get()));
if (successful) if (successful)
credentialStore.remove("node/" + id); credentialStore.remove("node#" + id);
logger.debug("<< destroyed node(%s) success(%s)", id, successful); logger.debug("<< destroyed node(%s) success(%s)", id, successful);
} }
@ -357,6 +367,66 @@ public class BaseComputeService implements ComputeService {
logger.debug("<< rebooted"); logger.debug("<< rebooted");
} }
/**
* {@inheritDoc}
*/
@Override
public void resumeNode(String id) {
checkNotNull(id, "id");
logger.debug(">> resumeing node(%s)", id);
NodeMetadata node = resumeNodeStrategy.resumeNode(id);
boolean successful = nodeRunning.apply(node);
logger.debug("<< resumeed node(%s) success(%s)", id, successful);
}
/**
* {@inheritDoc}
*/
@Override
public void resumeNodesMatching(Predicate<NodeMetadata> filter) {
logger.debug(">> resumeing nodes matching(%s)", filter);
transformParallel(nodesMatchingFilterAndNotTerminated(filter), new Function<NodeMetadata, Future<Void>>() {
// TODO use native async
@Override
public Future<Void> apply(NodeMetadata from) {
resumeNode(from.getId());
return immediateFuture(null);
}
}, executor, null, logger, "resumeing nodes");
logger.debug("<< resumeed");
}
/**
* {@inheritDoc}
*/
@Override
public void suspendNode(String id) {
checkNotNull(id, "id");
logger.debug(">> suspendping node(%s)", id);
NodeMetadata node = suspendNodeStrategy.suspendNode(id);
boolean successful = nodeSuspended.apply(node);
logger.debug("<< suspendped node(%s) success(%s)", id, successful);
}
/**
* {@inheritDoc}
*/
@Override
public void suspendNodesMatching(Predicate<NodeMetadata> filter) {
logger.debug(">> suspending nodes matching(%s)", filter);
transformParallel(nodesMatchingFilterAndNotTerminated(filter), new Function<NodeMetadata, Future<Void>>() {
// TODO use native async
@Override
public Future<Void> apply(NodeMetadata from) {
suspendNode(from.getId());
return immediateFuture(null);
}
}, executor, null, logger, "suspending nodes");
logger.debug("<< suspended");
}
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */

View File

@ -26,14 +26,17 @@ import javax.inject.Singleton;
import org.jclouds.Constants; import org.jclouds.Constants;
import org.jclouds.compute.Utils; import org.jclouds.compute.Utils;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.crypto.Crypto; import org.jclouds.crypto.Crypto;
import org.jclouds.date.DateService; import org.jclouds.date.DateService;
import org.jclouds.json.Json; import org.jclouds.json.Json;
import org.jclouds.logging.Logger.LoggerFactory; import org.jclouds.logging.Logger.LoggerFactory;
import org.jclouds.rest.HttpAsyncClient; import org.jclouds.rest.HttpAsyncClient;
import org.jclouds.rest.HttpClient; import org.jclouds.rest.HttpClient;
import org.jclouds.ssh.SshClient;
import org.jclouds.ssh.SshClient.Factory; import org.jclouds.ssh.SshClient.Factory;
import com.google.common.base.Function;
import com.google.inject.Inject; import com.google.inject.Inject;
/** /**
@ -44,15 +47,15 @@ import com.google.inject.Inject;
public class UtilsImpl extends org.jclouds.rest.internal.UtilsImpl implements Utils { public class UtilsImpl extends org.jclouds.rest.internal.UtilsImpl implements Utils {
@Inject(optional = true) @Inject(optional = true)
private Factory sshFactory; private Factory sshFactory;
private final Function<NodeMetadata, SshClient> sshForNode;
@Inject @Inject
UtilsImpl(Json json, HttpClient simpleClient, HttpAsyncClient simpleAsyncClient, UtilsImpl(Json json, HttpClient simpleClient, HttpAsyncClient simpleAsyncClient, Crypto encryption,
Crypto encryption, DateService date, DateService date, @Named(Constants.PROPERTY_USER_THREADS) ExecutorService userThreads,
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService userThreads, @Named(Constants.PROPERTY_IO_WORKER_THREADS) ExecutorService ioThreads, LoggerFactory loggerFactory,
@Named(Constants.PROPERTY_IO_WORKER_THREADS) ExecutorService ioThreads, Function<NodeMetadata, SshClient> sshForNode) {
LoggerFactory loggerFactory) { super(json, simpleClient, simpleAsyncClient, encryption, date, userThreads, ioThreads, loggerFactory);
super(json, simpleClient, simpleAsyncClient, encryption, date, userThreads, ioThreads, this.sshForNode = sshForNode;
loggerFactory);
} }
@Override @Override
@ -65,4 +68,9 @@ public class UtilsImpl extends org.jclouds.rest.internal.UtilsImpl implements Ut
return sshFactory; return sshFactory;
} }
@Override
public Function<NodeMetadata, SshClient> sshForNode() {
return sshForNode;
}
} }

View File

@ -0,0 +1,70 @@
/**
*
* 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.predicates;
import static com.google.common.base.Preconditions.checkNotNull;
import javax.annotation.Resource;
import javax.inject.Singleton;
import org.jclouds.compute.ComputeService;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.NodeState;
import org.jclouds.logging.Logger;
import com.google.common.base.Predicate;
import com.google.inject.Inject;
/**
*
* Tests to see if a node is active.
*
* @author Adrian Cole
*/
@Singleton
public class NodePresentAndInIntendedState implements Predicate<NodeMetadata> {
private final ComputeService client;
private final NodeState intended;
@Resource
protected Logger logger = Logger.NULL;
@Inject
public NodePresentAndInIntendedState(NodeState intended, ComputeService client) {
this.intended = intended;
this.client = client;
}
public boolean apply(NodeMetadata node) {
logger.trace("looking for state on node %s", checkNotNull(node, "node"));
node = refresh(node);
if (node == null)
return false;
logger.trace("%s: looking for node state %s: currently: %s", node.getId(), intended, node.getState());
if (node.getState() == NodeState.ERROR)
throw new IllegalStateException("node " + node.getId() + " in location " + node.getLocation()
+ " is in error state");
return node.getState() == intended;
}
private NodeMetadata refresh(NodeMetadata node) {
return client.getNodeMetadata(node.getId());
}
}

View File

@ -19,52 +19,24 @@
package org.jclouds.compute.predicates; package org.jclouds.compute.predicates;
import static com.google.common.base.Preconditions.checkNotNull;
import javax.annotation.Resource;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.jclouds.compute.ComputeService; import org.jclouds.compute.ComputeService;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.NodeState; import org.jclouds.compute.domain.NodeState;
import org.jclouds.logging.Logger;
import com.google.common.base.Predicate;
import com.google.inject.Inject; import com.google.inject.Inject;
/** /**
* *
* Tests to see if a node is active. * Tests to see if a node is running.
* *
* @author Adrian Cole * @author Adrian Cole
*/ */
@Singleton @Singleton
public class NodeRunning implements Predicate<NodeMetadata> { public class NodeRunning extends NodePresentAndInIntendedState {
private final ComputeService client;
@Resource
protected Logger logger = Logger.NULL;
@Inject @Inject
public NodeRunning(ComputeService client) { public NodeRunning(ComputeService client) {
this.client = client; super(NodeState.RUNNING, client);
}
public boolean apply(NodeMetadata node) {
logger.trace("looking for state on node %s", checkNotNull(node, "node"));
node = refresh(node);
if (node == null)
return false;
logger.trace("%s: looking for node state %s: currently: %s",
node.getId(), NodeState.RUNNING, node.getState());
if (node.getState() == NodeState.ERROR)
throw new IllegalStateException("node " + node.getId()
+ " in location " + node.getLocation() + " is in error state");
return node.getState() == NodeState.RUNNING;
}
private NodeMetadata refresh(NodeMetadata node) {
return client.getNodeMetadata(node.getId());
} }
} }

View File

@ -17,30 +17,26 @@
* ==================================================================== * ====================================================================
*/ */
package org.jclouds.gogrid.util; package org.jclouds.compute.predicates;
import java.util.regex.Matcher; import javax.inject.Singleton;
import java.util.regex.Pattern;
import org.jclouds.compute.ComputeService;
import org.jclouds.compute.domain.NodeState;
import com.google.inject.Inject;
/** /**
* @author Oleksiy Yarmula *
* Tests to see if a node is suspended.
*
* @author Adrian Cole
*/ */
public class GoGridUtils { @Singleton
public class NodeSuspended extends NodePresentAndInIntendedState {
/**
* Matches nth group or returns null.
*
* @param stringToParse string that the pattern will be applied to
* @param pattern regular expression {@link java.util.regex.Pattern pattern}
* @param nthGroup number of the group to extract / return
* @return matched group or null
*/
public static String parseStringByPatternAndGetNthMatchGroup(String stringToParse, Pattern pattern, int nthGroup) {
Matcher osVersionMatcher = pattern.matcher(stringToParse);
if (osVersionMatcher.find()) {
return osVersionMatcher.group(nthGroup);
}
return null;
}
@Inject
public NodeSuspended(ComputeService client) {
super(NodeState.SUSPENDED, client);
}
} }

View File

@ -0,0 +1,86 @@
/**
*
* 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.predicates;
import java.util.concurrent.TimeUnit;
import javax.annotation.Resource;
import javax.inject.Inject;
import javax.inject.Named;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.compute.reference.ComputeServiceConstants.Timeouts;
import org.jclouds.logging.Logger;
import org.jclouds.net.IPSocket;
import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.predicates.SocketOpen;
import com.google.common.base.Predicate;
/**
*
*
* Not singleton as seconds are mutable
*
* @author Adrian Cole
*
*/
public class RetryIfSocketNotYetOpen implements Predicate<IPSocket> {
@Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
private Logger logger = Logger.NULL;
private final SocketOpen socketTester;
private long seconds;
public RetryIfSocketNotYetOpen seconds(long seconds) {
this.seconds = seconds;
return this;
}
@Inject
public RetryIfSocketNotYetOpen(SocketOpen socketTester, Timeouts timeouts) {
this.socketTester = socketTester;
this.seconds = timeouts.portOpen;
}
public RetryIfSocketNotYetOpen(SocketOpen socketTester, Logger logger, long seconds) {
this.socketTester = socketTester;
this.logger = logger;
this.seconds = seconds;
}
@Override
public String toString() {
return "retryIfSocketNotYetOpen(" + seconds + ")";
}
@Override
public boolean apply(IPSocket socket) {
logger.debug(">> blocking on socket %s for %d seconds", socket, seconds);
RetryablePredicate<IPSocket> tester = new RetryablePredicate<IPSocket>(socketTester, seconds, 1, TimeUnit.SECONDS);
boolean passed = tester.apply(socket);
if (passed)
logger.debug("<< socket %s opened", socket);
else
logger.warn("<< socket %s didn't open after %d seconds", socket, seconds);
return passed;
}
}

View File

@ -34,6 +34,7 @@ public interface ComputeServiceConstants {
public static final String LOCAL_PARTITION_GB_PATTERN = "disk_drive/%s/gb"; public static final String LOCAL_PARTITION_GB_PATTERN = "disk_drive/%s/gb";
public static final String PROPERTY_TIMEOUT_NODE_TERMINATED = "jclouds.compute.timeout.node-terminated"; public static final String PROPERTY_TIMEOUT_NODE_TERMINATED = "jclouds.compute.timeout.node-terminated";
public static final String PROPERTY_TIMEOUT_NODE_RUNNING = "jclouds.compute.timeout.node-running"; public static final String PROPERTY_TIMEOUT_NODE_RUNNING = "jclouds.compute.timeout.node-running";
public static final String PROPERTY_TIMEOUT_NODE_SUSPENDED = "jclouds.compute.timeout.node-suspended";
public static final String PROPERTY_TIMEOUT_SCRIPT_COMPLETE = "jclouds.compute.timeout.script-complete"; public static final String PROPERTY_TIMEOUT_SCRIPT_COMPLETE = "jclouds.compute.timeout.script-complete";
public static final String PROPERTY_TIMEOUT_PORT_OPEN = "jclouds.compute.timeout.port-open"; public static final String PROPERTY_TIMEOUT_PORT_OPEN = "jclouds.compute.timeout.port-open";
/** /**
@ -51,7 +52,11 @@ public interface ComputeServiceConstants {
@Inject(optional = true) @Inject(optional = true)
@Named(PROPERTY_TIMEOUT_NODE_RUNNING) @Named(PROPERTY_TIMEOUT_NODE_RUNNING)
public long nodeRunning = 1200 * 1000; public long nodeRunning = 1200 * 1000;
@Inject(optional = true)
@Named(PROPERTY_TIMEOUT_NODE_SUSPENDED)
public long nodeSuspended = 30 * 1000;
@Inject(optional = true) @Inject(optional = true)
@Named(PROPERTY_TIMEOUT_SCRIPT_COMPLETE) @Named(PROPERTY_TIMEOUT_SCRIPT_COMPLETE)
public long scriptComplete = 600 * 1000; public long scriptComplete = 600 * 1000;

View File

@ -0,0 +1,33 @@
/**
*
* 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 org.jclouds.compute.domain.NodeMetadata;
/**
* Resumes a node from the state {@link org.jclouds.compute.domain.NodeState#SUSPENDED suspended}
*
* @author Adrian Cole
*/
public interface ResumeNodeStrategy {
NodeMetadata resumeNode(String id);
}

View File

@ -0,0 +1,33 @@
/**
*
* 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 org.jclouds.compute.domain.NodeMetadata;
/**
* Reboots a node unless it is in the state {@link org.jclouds.compute.domain.NodeState#SUSPENDED suspended}
*
* @author Adrian Cole
*/
public interface SuspendNodeStrategy {
NodeMetadata suspendNode(String id);
}

View File

@ -41,6 +41,8 @@ import org.jclouds.compute.strategy.DestroyNodeStrategy;
import org.jclouds.compute.strategy.GetNodeMetadataStrategy; import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
import org.jclouds.compute.strategy.ListNodesStrategy; 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.SuspendNodeStrategy;
import org.jclouds.domain.Credentials; import org.jclouds.domain.Credentials;
import org.jclouds.logging.Logger; import org.jclouds.logging.Logger;
@ -54,7 +56,7 @@ import com.google.common.collect.Iterables;
*/ */
@Singleton @Singleton
public class AdaptingComputeServiceStrategies<N, H, I, L> implements AddNodeWithTagStrategy, DestroyNodeStrategy, public class AdaptingComputeServiceStrategies<N, H, I, L> implements AddNodeWithTagStrategy, DestroyNodeStrategy,
GetNodeMetadataStrategy, ListNodesStrategy, RebootNodeStrategy { GetNodeMetadataStrategy, ListNodesStrategy, RebootNodeStrategy, ResumeNodeStrategy, SuspendNodeStrategy {
@Resource @Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER) @Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL; protected Logger logger = Logger.NULL;
@ -65,7 +67,7 @@ public class AdaptingComputeServiceStrategies<N, H, I, L> implements AddNodeWith
@Inject @Inject
public AdaptingComputeServiceStrategies(Map<String, Credentials> credentialStore, public AdaptingComputeServiceStrategies(Map<String, Credentials> credentialStore,
ComputeServiceAdapter<N, H, I, L> client, Function<N, NodeMetadata> nodeMetadataAdapter) { ComputeServiceAdapter<N, H, I, L> client, Function<N, NodeMetadata> nodeMetadataAdapter) {
this.credentialStore = checkNotNull(credentialStore, "credentialStore"); this.credentialStore = checkNotNull(credentialStore, "credentialStore");
this.client = checkNotNull(client, "client"); this.client = checkNotNull(client, "client");
this.nodeMetadataAdapter = checkNotNull(nodeMetadataAdapter, "nodeMetadataAdapter"); this.nodeMetadataAdapter = checkNotNull(nodeMetadataAdapter, "nodeMetadataAdapter");
@ -101,6 +103,34 @@ public class AdaptingComputeServiceStrategies<N, H, I, L> implements AddNodeWith
return node; return node;
} }
@Override
public NodeMetadata resumeNode(String id) {
NodeMetadata node = getNode(id);
if (node == null || node.getState() == NodeState.TERMINATED || node.getState() == NodeState.RUNNING)
return node;
logger.debug(">> resuming node(%s)", id);
client.resumeNode(id);
logger.debug("<< resumed node(%s)", id);
return node;
}
@Override
public NodeMetadata suspendNode(String id) {
NodeMetadata node = getNode(id);
if (node == null || node.getState() == NodeState.TERMINATED || node.getState() == NodeState.SUSPENDED)
return node;
logger.debug(">> suspending node(%s)", id);
client.suspendNode(id);
logger.debug("<< suspended node(%s)", id);
return node;
}
@Override @Override
public NodeMetadata destroyNode(String id) { public NodeMetadata destroyNode(String id) {
@ -124,8 +154,8 @@ public class AdaptingComputeServiceStrategies<N, H, I, L> implements AddNodeWith
checkState(name != null && name.indexOf(tag) != -1, "name should have %s encoded into it", tag); checkState(name != null && name.indexOf(tag) != -1, "name should have %s encoded into it", tag);
logger.debug(">> instantiating node location(%s) name(%s) image(%s) hardware(%s)", logger.debug(">> instantiating node location(%s) name(%s) image(%s) hardware(%s)",
template.getLocation().getId(), name, template.getImage().getProviderId(), template.getHardware() template.getLocation().getId(), name, template.getImage().getProviderId(), template.getHardware()
.getProviderId()); .getProviderId());
N from = client.runNodeWithTagAndNameAndStoreCredentials(tag, name, template, credentialStore); N from = client.runNodeWithTagAndNameAndStoreCredentials(tag, name, template, credentialStore);
NodeMetadata node = nodeMetadataAdapter.apply(from); NodeMetadata node = nodeMetadataAdapter.apply(from);

View File

@ -63,9 +63,9 @@ public class StubComputeServiceAdapter implements JCloudsNativeComputeServiceAda
@Inject @Inject
public StubComputeServiceAdapter(ConcurrentMap<String, NodeMetadata> nodes, Supplier<Location> location, public StubComputeServiceAdapter(ConcurrentMap<String, NodeMetadata> nodes, Supplier<Location> location,
@Named("NODE_ID") Provider<Integer> idProvider, @Named("PUBLIC_IP_PREFIX") String publicIpPrefix, @Named("NODE_ID") Provider<Integer> idProvider, @Named("PUBLIC_IP_PREFIX") String publicIpPrefix,
@Named("PRIVATE_IP_PREFIX") String privateIpPrefix, @Named("PASSWORD_PREFIX") String passwordPrefix, @Named("PRIVATE_IP_PREFIX") String privateIpPrefix, @Named("PASSWORD_PREFIX") String passwordPrefix,
@org.jclouds.rest.annotations.Provider String providerName) { @org.jclouds.rest.annotations.Provider String providerName) {
this.nodes = nodes; this.nodes = nodes;
this.location = location; this.location = location;
this.idProvider = idProvider; this.idProvider = idProvider;
@ -77,7 +77,7 @@ public class StubComputeServiceAdapter implements JCloudsNativeComputeServiceAda
@Override @Override
public NodeMetadata runNodeWithTagAndNameAndStoreCredentials(String tag, String name, Template template, public NodeMetadata runNodeWithTagAndNameAndStoreCredentials(String tag, String name, Template template,
Map<String, Credentials> credentialStore) { Map<String, Credentials> credentialStore) {
NodeMetadataBuilder builder = new NodeMetadataBuilder(); NodeMetadataBuilder builder = new NodeMetadataBuilder();
String id = idProvider.get() + ""; String id = idProvider.get() + "";
builder.ids(id); builder.ids(id);
@ -91,8 +91,8 @@ public class StubComputeServiceAdapter implements JCloudsNativeComputeServiceAda
builder.privateAddresses(ImmutableSet.<String> of(privateIpPrefix + id)); builder.privateAddresses(ImmutableSet.<String> of(privateIpPrefix + id));
builder.credentials(new Credentials("root", passwordPrefix + id)); builder.credentials(new Credentials("root", passwordPrefix + id));
NodeMetadata node = builder.build(); NodeMetadata node = builder.build();
credentialStore.put("node#" + node.getId(), node.getCredentials());
nodes.put(node.getId(), node); nodes.put(node.getId(), node);
credentialStore.put(node.getId(), node.getCredentials());
StubComputeServiceDependenciesModule.setState(node, NodeState.RUNNING, 100); StubComputeServiceDependenciesModule.setState(node, NodeState.RUNNING, 100);
return node; return node;
} }
@ -100,8 +100,8 @@ public class StubComputeServiceAdapter implements JCloudsNativeComputeServiceAda
@Override @Override
public Iterable<Hardware> listHardwareProfiles() { public Iterable<Hardware> listHardwareProfiles() {
return ImmutableSet.<Hardware> of(StubComputeServiceDependenciesModule.stub("small", 1, 1740, 160), return ImmutableSet.<Hardware> of(StubComputeServiceDependenciesModule.stub("small", 1, 1740, 160),
StubComputeServiceDependenciesModule.stub("medium", 4, 7680, 850), StubComputeServiceDependenciesModule.stub("medium", 4, 7680, 850), StubComputeServiceDependenciesModule
StubComputeServiceDependenciesModule.stub("large", 8, 15360, 1690)); .stub("large", 8, 15360, 1690));
} }
@Override @Override
@ -109,34 +109,20 @@ public class StubComputeServiceAdapter implements JCloudsNativeComputeServiceAda
Location zone = location.get().getParent(); Location zone = location.get().getParent();
String parentId = zone.getId(); String parentId = zone.getId();
Credentials defaultCredentials = new Credentials("root", null); Credentials defaultCredentials = new Credentials("root", null);
return ImmutableSet return ImmutableSet.<Image> of(new ImageBuilder().providerId("1").name(OsFamily.UBUNTU.name())
.<Image> of( .id(parentId + "/1").location(zone).operatingSystem(
new ImageBuilder() new OperatingSystem(OsFamily.UBUNTU, "ubuntu 32", null, "X86_32", "ubuntu 32", false))
.providerId("1") .description("stub ubuntu 32").defaultCredentials(defaultCredentials).build(), //
.name(OsFamily.UBUNTU.name()) new ImageBuilder().providerId("2").name(OsFamily.UBUNTU.name()).id(parentId + "/2").location(zone)
.id(parentId + "/1")
.location(zone)
.operatingSystem( .operatingSystem(
new OperatingSystem(OsFamily.UBUNTU, "ubuntu 32", null, "X86_32", "ubuntu 32", false)) new OperatingSystem(OsFamily.UBUNTU, "ubuntu 64", null, "X86_64", "ubuntu 64", true))
.description("stub ubuntu 32").defaultCredentials(defaultCredentials).build(), //
new ImageBuilder()
.providerId("2")
.name(OsFamily.UBUNTU.name())
.id(parentId + "/2")
.location(zone)
.operatingSystem(
new OperatingSystem(OsFamily.UBUNTU, "ubuntu 64", null, "X86_64", "ubuntu 64", true))
.description("stub ubuntu 64").defaultCredentials(defaultCredentials).build(), // .description("stub ubuntu 64").defaultCredentials(defaultCredentials).build(), //
new ImageBuilder() new ImageBuilder().providerId("3").name(OsFamily.CENTOS.name()).id(parentId + "/3").location(zone)
.providerId("3")
.name(OsFamily.CENTOS.name())
.id(parentId + "/3")
.location(zone)
.operatingSystem( .operatingSystem(
new OperatingSystem(OsFamily.CENTOS, "centos 64", null, "X86_64", "centos 64", true)) new OperatingSystem(OsFamily.CENTOS, "centos 64", null, "X86_64", "centos 64", true))
.description("stub centos 64").defaultCredentials(defaultCredentials).build() // .description("stub centos 64").defaultCredentials(defaultCredentials).build() //
); );
} }
@Override @Override
@ -148,9 +134,9 @@ public class StubComputeServiceAdapter implements JCloudsNativeComputeServiceAda
public Iterable<Location> listLocations() { public Iterable<Location> listLocations() {
Location provider = new LocationImpl(LocationScope.PROVIDER, providerName, providerName, null); Location provider = new LocationImpl(LocationScope.PROVIDER, providerName, providerName, null);
Location region = new LocationImpl(LocationScope.REGION, providerName + "region", providerName + "region", Location region = new LocationImpl(LocationScope.REGION, providerName + "region", providerName + "region",
provider); provider);
return ImmutableSet.<Location> of(new LocationImpl(LocationScope.ZONE, providerName + "zone", providerName return ImmutableSet.<Location> of(new LocationImpl(LocationScope.ZONE, providerName + "zone", providerName
+ "zone", region)); + "zone", region));
} }
@Override @Override
@ -189,4 +175,30 @@ public class StubComputeServiceAdapter implements JCloudsNativeComputeServiceAda
StubComputeServiceDependenciesModule.setState(node, NodeState.PENDING, 0); StubComputeServiceDependenciesModule.setState(node, NodeState.PENDING, 0);
StubComputeServiceDependenciesModule.setState(node, NodeState.RUNNING, 50); StubComputeServiceDependenciesModule.setState(node, NodeState.RUNNING, 50);
} }
@Override
public void resumeNode(String id) {
NodeMetadata node = nodes.get(id);
if (node == null)
throw new ResourceNotFoundException("node not found: " + id);
if (node.getState() == NodeState.RUNNING)
return;
if (node.getState() != NodeState.SUSPENDED)
throw new IllegalStateException("to resume a node, it must be in suspended state, not: " + node.getState());
StubComputeServiceDependenciesModule.setState(node, NodeState.PENDING, 0);
StubComputeServiceDependenciesModule.setState(node, NodeState.RUNNING, 50);
}
@Override
public void suspendNode(String id) {
NodeMetadata node = nodes.get(id);
if (node == null)
throw new ResourceNotFoundException("node not found: " + id);
if (node.getState() == NodeState.SUSPENDED)
return;
if (node.getState() != NodeState.RUNNING)
throw new IllegalStateException("to suspend a node, it must be in running state, not: " + node.getState());
StubComputeServiceDependenciesModule.setState(node, NodeState.PENDING, 0);
StubComputeServiceDependenciesModule.setState(node, NodeState.SUSPENDED, 50);
}
} }

View File

@ -19,15 +19,8 @@
package org.jclouds.compute.stub.config; package org.jclouds.compute.stub.config;
import org.jclouds.compute.ComputeServiceAdapter;
import org.jclouds.compute.config.JCloudsNativeStandaloneComputeServiceContextModule; import org.jclouds.compute.config.JCloudsNativeStandaloneComputeServiceContextModule;
import org.jclouds.compute.domain.Hardware;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.concurrent.SingleThreaded; import org.jclouds.concurrent.SingleThreaded;
import org.jclouds.domain.Location;
import com.google.inject.TypeLiteral;
/** /**
* *
@ -43,8 +36,6 @@ public class StubComputeServiceContextModule extends JCloudsNativeStandaloneComp
@Override @Override
protected void configure() { protected void configure() {
install(new StubComputeServiceDependenciesModule()); install(new StubComputeServiceDependenciesModule());
bind(new TypeLiteral<ComputeServiceAdapter<NodeMetadata, Hardware, Image, Location>>() {
}).to(StubComputeServiceAdapter.class);
super.configure(); super.configure();
} }
} }

View File

@ -19,10 +19,15 @@
package org.jclouds.compute.util; package org.jclouds.compute.util;
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.base.Throwables.getStackTraceAsString; import static com.google.common.base.Throwables.getStackTraceAsString;
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.find; import static com.google.common.collect.Iterables.find;
import static com.google.common.collect.Iterables.size;
import static com.google.common.collect.Iterables.transform;
import static org.jclouds.scriptbuilder.domain.Statements.pipeHttpResponseToBash; import static org.jclouds.scriptbuilder.domain.Statements.pipeHttpResponseToBash;
import static org.jclouds.util.Utils.getSupportedProvidersOfType;
import java.net.URI; import java.net.URI;
import java.util.Formatter; import java.util.Formatter;
@ -33,6 +38,7 @@ import java.util.concurrent.Callable;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
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;
@ -40,13 +46,15 @@ import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.OsFamily; 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.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.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 org.jclouds.ssh.SshClient;
import org.jclouds.util.Utils;
import com.google.common.base.Function;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
@ -212,13 +220,33 @@ public class ComputeServiceUtils {
void setConnection(SshClient ssh, Logger logger); void setConnection(SshClient ssh, Logger logger);
} }
public static boolean isKeyAuth(NodeMetadata createdNode) { public static Iterable<String> getSupportedProviders() {
return createdNode.getCredentials().credential != null return getSupportedProvidersOfType(ComputeServiceContextBuilder.class);
&& createdNode.getCredentials().credential.startsWith("-----BEGIN RSA PRIVATE KEY-----");
} }
public static Iterable<String> getSupportedProviders() { public static IPSocket findReachableSocketOnNode(RetryIfSocketNotYetOpen socketTester, final NodeMetadata node,
return Utils.getSupportedProvidersOfType(ComputeServiceContextBuilder.class); final int port) {
checkNodeHasIps(node);
IPSocket socket = null;
try {
socket = find(
transform(concat(node.getPublicAddresses(), node.getPrivateAddresses()),
new Function<String, IPSocket>() {
@Override
public IPSocket apply(String from) {
return new IPSocket(from, port);
}
}), socketTester);
} catch (NoSuchElementException e) {
throw new RuntimeException(String.format("could not connect to any ip address port %d on node %s", port, node));
}
return socket;
}
public static void checkNodeHasIps(NodeMetadata node) {
checkState(size(concat(node.getPublicAddresses(), node.getPrivateAddresses())) > 0,
"node does not have IP addresses configured: " + node);
} }
} }

View File

@ -19,9 +19,12 @@
package org.jclouds.compute.util; package org.jclouds.compute.util;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Throwables.getRootCause;
import static com.google.common.base.Preconditions.checkState; import static com.google.common.base.Throwables.propagate;
import static org.jclouds.compute.util.ComputeServiceUtils.isKeyAuth; 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 static org.jclouds.concurrent.FutureIterables.awaitCompletion;
import java.util.List; import java.util.List;
@ -31,11 +34,11 @@ import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException; 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 java.util.concurrent.TimeUnit;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.annotation.Resource; 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;
@ -45,14 +48,13 @@ import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.NodeMetadataBuilder; import org.jclouds.compute.domain.NodeMetadataBuilder;
import org.jclouds.compute.options.RunScriptOptions; 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.predicates.ScriptStatusReturnsZero.CommandUsingClient; import org.jclouds.compute.predicates.ScriptStatusReturnsZero.CommandUsingClient;
import org.jclouds.compute.reference.ComputeServiceConstants; import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.compute.reference.ComputeServiceConstants.Timeouts; import org.jclouds.compute.reference.ComputeServiceConstants.Timeouts;
import org.jclouds.compute.strategy.GetNodeMetadataStrategy; import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
import org.jclouds.compute.util.ComputeServiceUtils.SshCallable; import org.jclouds.compute.util.ComputeServiceUtils.SshCallable;
import org.jclouds.logging.Logger; import org.jclouds.logging.Logger;
import org.jclouds.net.IPSocket;
import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.scriptbuilder.domain.AuthorizeRSAPublicKey; import org.jclouds.scriptbuilder.domain.AuthorizeRSAPublicKey;
import org.jclouds.scriptbuilder.domain.InstallRSAPrivateKey; import org.jclouds.scriptbuilder.domain.InstallRSAPrivateKey;
import org.jclouds.scriptbuilder.domain.Statement; import org.jclouds.scriptbuilder.domain.Statement;
@ -60,11 +62,8 @@ import org.jclouds.scriptbuilder.domain.StatementList;
import org.jclouds.ssh.ExecResponse; import org.jclouds.ssh.ExecResponse;
import org.jclouds.ssh.SshClient; 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.base.Throwables;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.inject.Inject; import com.google.inject.Inject;
/** /**
@ -76,20 +75,20 @@ public class ComputeUtils {
@Resource @Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER) @Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL; protected Logger logger = Logger.NULL;
@Inject(optional = true) protected final Function<NodeMetadata, SshClient> sshFactory;
protected SshClient.Factory sshFactory;
protected final Predicate<CommandUsingClient> runScriptNotRunning; protected final Predicate<CommandUsingClient> runScriptNotRunning;
protected final Predicate<IPSocket> socketTester; protected final Provider<RetryIfSocketNotYetOpen> socketTester;
protected final ExecutorService executor; protected final ExecutorService executor;
protected final Predicate<NodeMetadata> nodeRunning; protected final Predicate<NodeMetadata> nodeRunning;
protected final GetNodeMetadataStrategy getNode; protected final GetNodeMetadataStrategy getNode;
protected final Timeouts timeouts; protected final Timeouts timeouts;
@Inject @Inject
public ComputeUtils(Predicate<IPSocket> socketTester, public ComputeUtils(Provider<RetryIfSocketNotYetOpen> socketTester, Function<NodeMetadata, SshClient> sshFactory,
@Named("SCRIPT_COMPLETE") Predicate<CommandUsingClient> runScriptNotRunning, GetNodeMetadataStrategy getNode, @Named("SCRIPT_COMPLETE") Predicate<CommandUsingClient> runScriptNotRunning, GetNodeMetadataStrategy getNode,
Timeouts timeouts, @Named("NODE_RUNNING") Predicate<NodeMetadata> nodeRunning, 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.nodeRunning = nodeRunning; this.nodeRunning = nodeRunning;
this.timeouts = timeouts; this.timeouts = timeouts;
this.getNode = getNode; this.getNode = getNode;
@ -101,7 +100,7 @@ public class ComputeUtils {
public Map<?, Future<Void>> runOptionsOnNodesAndAddToGoodSetOrPutExceptionIntoBadMap(final TemplateOptions options, public Map<?, Future<Void>> runOptionsOnNodesAndAddToGoodSetOrPutExceptionIntoBadMap(final TemplateOptions options,
Iterable<NodeMetadata> runningNodes, final Set<NodeMetadata> goodNodes, Iterable<NodeMetadata> runningNodes, final Set<NodeMetadata> goodNodes,
final Map<NodeMetadata, Exception> badNodes) { final Map<NodeMetadata, Exception> badNodes) {
Map<NodeMetadata, Future<Void>> responses = Maps.newHashMap(); Map<NodeMetadata, Future<Void>> responses = newHashMap();
for (final NodeMetadata node : runningNodes) { for (final NodeMetadata node : runningNodes) {
responses.put(node, executor.submit(runOptionsOnNodeAndAddToGoodSetOrPutExceptionIntoBadMap(node, badNodes, responses.put(node, executor.submit(runOptionsOnNodeAndAddToGoodSetOrPutExceptionIntoBadMap(node, badNodes,
goodNodes, options))); goodNodes, options)));
@ -119,8 +118,7 @@ public class ComputeUtils {
logger.debug("<< options applied node(%s)", node1.getId()); logger.debug("<< options applied node(%s)", node1.getId());
goodNodes.add(node1); goodNodes.add(node1);
} catch (Exception e) { } catch (Exception e) {
logger.error(e, "<< problem applying options to node(%s): ", node.getId(), Throwables.getRootCause(e) logger.error(e, "<< problem applying options to node(%s): ", node.getId(), getRootCause(e).getMessage());
.getMessage());
badNodes.put(node, e); badNodes.put(node, e);
} }
return null; return null;
@ -133,17 +131,17 @@ public class ComputeUtils {
return node; return node;
if (nodeRunning.apply(node)) if (nodeRunning.apply(node))
node = NodeMetadataBuilder.fromNodeMetadata(getNode.getNode(node.getId())) node = NodeMetadataBuilder.fromNodeMetadata(getNode.getNode(node.getId())).credentials(node.getCredentials())
.credentials(node.getCredentials()).build(); .build();
else else
throw new IllegalStateException(String.format( throw new IllegalStateException(String.format(
"node didn't achieve the state running on node %s within %d seconds, final state: %s", node.getId(), "node didn't achieve the state running on node %s within %d seconds, final state: %s", node.getId(),
timeouts.nodeRunning / 1000, node.getState())); timeouts.nodeRunning / 1000, node.getState()));
List<Statement> bootstrap = Lists.newArrayList(); List<Statement> bootstrap = newArrayList();
if (options.getRunScript() != null)
bootstrap.add(options.getRunScript());
if (options.getPublicKey() != null) if (options.getPublicKey() != null)
bootstrap.add(new AuthorizeRSAPublicKey(options.getPublicKey())); bootstrap.add(new AuthorizeRSAPublicKey(options.getPublicKey()));
if (options.getRunScript() != null)
bootstrap.add(options.getRunScript());
if (options.getPrivateKey() != null) if (options.getPrivateKey() != null)
bootstrap.add(new InstallRSAPrivateKey(options.getPrivateKey())); bootstrap.add(new InstallRSAPrivateKey(options.getPrivateKey()));
if (bootstrap.size() >= 1) if (bootstrap.size() >= 1)
@ -151,14 +149,10 @@ public class ComputeUtils {
return node; return node;
} }
public void checkNodeHasPublicIps(NodeMetadata node) {
checkState(node.getPublicAddresses().size() > 0, "node does not have IP addresses configured: " + node);
}
public ExecResponse runScriptOnNode(NodeMetadata node, Statement runScript, RunScriptOptions options) { public ExecResponse runScriptOnNode(NodeMetadata node, Statement runScript, RunScriptOptions options) {
InitAndStartScriptOnNode callable = generateScript(node, runScript, options); InitAndStartScriptOnNode callable = generateScript(node, runScript, options);
ExecResponse response; ExecResponse response;
SshClient ssh = createSshClientOncePortIsListeningOnNode(node); SshClient ssh = sshFactory.apply(node);
try { try {
ssh.connect(); ssh.connect();
callable.setConnection(ssh, logger); callable.setConnection(ssh, logger);
@ -168,24 +162,11 @@ public class ComputeUtils {
ssh.disconnect(); ssh.disconnect();
} }
if (options.getPort() > 0) { if (options.getPort() > 0) {
checkNodeHasPublicIps(node); findReachableSocketOnNode(socketTester.get().seconds(options.getSeconds()), node, options.getPort());
blockUntilPortIsListeningOnPublicIp(options.getPort(), options.getSeconds(),
Iterables.get(node.getPublicAddresses(), 0));
} }
return response; return response;
} }
public void blockUntilPortIsListeningOnPublicIp(int port, int seconds, String inetAddress) {
logger.debug(">> blocking on port %s:%d for %d seconds", inetAddress, port, seconds);
RetryablePredicate<IPSocket> tester = new RetryablePredicate<IPSocket>(socketTester, seconds, 1, TimeUnit.SECONDS);
IPSocket socket = new IPSocket(inetAddress, port);
boolean passed = tester.apply(socket);
if (passed)
logger.debug("<< port %s:%d opened", inetAddress, port);
else
logger.warn("<< port %s:%d didn't open after %d seconds", inetAddress, port, seconds);
}
public InitAndStartScriptOnNode generateScript(NodeMetadata node, Statement script, RunScriptOptions options) { public InitAndStartScriptOnNode generateScript(NodeMetadata node, Statement script, RunScriptOptions options) {
return options.shouldBlockOnComplete() ? new RunScriptOnNode(runScriptNotRunning, node, options.getTaskName(), return options.shouldBlockOnComplete() ? new RunScriptOnNode(runScriptNotRunning, node, options.getTaskName(),
script, options.shouldRunAsRoot()) : new InitAndStartScriptOnNode(node, options.getTaskName(), script, script, options.shouldRunAsRoot()) : new InitAndStartScriptOnNode(node, options.getTaskName(), script,
@ -194,11 +175,7 @@ public class ComputeUtils {
public Map<SshCallable<?>, ?> runCallablesOnNode(NodeMetadata node, Iterable<SshCallable<?>> parallel, public Map<SshCallable<?>, ?> runCallablesOnNode(NodeMetadata node, Iterable<SshCallable<?>> parallel,
@Nullable SshCallable<?> last) { @Nullable SshCallable<?> last) {
checkState(this.sshFactory != null, "runScript requested, but no SshModule configured"); SshClient ssh = sshFactory.apply(node);
checkNodeHasPublicIps(node);
checkNotNull(node.getCredentials(), "credentials for node " + node.getName());
checkNotNull(node.getCredentials().credential, "credentials.credential for node " + node.getName());
SshClient ssh = createSshClientOncePortIsListeningOnNode(node);
try { try {
ssh.connect(); ssh.connect();
return runTasksUsingSshClient(parallel, last, ssh); return runTasksUsingSshClient(parallel, last, ssh);
@ -210,8 +187,8 @@ public class ComputeUtils {
private Map<SshCallable<?>, ?> runTasksUsingSshClient(Iterable<SshCallable<?>> parallel, SshCallable<?> last, private Map<SshCallable<?>, ?> runTasksUsingSshClient(Iterable<SshCallable<?>> parallel, SshCallable<?> last,
SshClient ssh) { SshClient ssh) {
Map<SshCallable<?>, Object> responses = Maps.newHashMap(); Map<SshCallable<?>, Object> responses = newHashMap();
if (Iterables.size(parallel) > 0) { if (size(parallel) > 0) {
responses.putAll(runCallablesUsingSshClient(parallel, ssh)); responses.putAll(runCallablesUsingSshClient(parallel, ssh));
} }
if (last != null) { if (last != null) {
@ -219,24 +196,15 @@ public class ComputeUtils {
try { try {
responses.put(last, last.call()); responses.put(last, last.call());
} catch (Exception e) { } catch (Exception e) {
Throwables.propagate(e); propagate(e);
} }
} }
return responses; return responses;
} }
public SshClient createSshClientOncePortIsListeningOnNode(NodeMetadata node) {
IPSocket socket = new IPSocket(Iterables.get(node.getPublicAddresses(), 0), 22);
socketTester.apply(socket);
SshClient ssh = isKeyAuth(node) ? sshFactory.create(socket, node.getCredentials().identity,
node.getCredentials().credential.getBytes()) : sshFactory.create(socket, node.getCredentials().identity,
node.getCredentials().credential);
return ssh;
}
// TODO refactor // TODO refactor
private Map<SshCallable<?>, Object> runCallablesUsingSshClient(Iterable<SshCallable<?>> parallel, SshClient ssh) { private Map<SshCallable<?>, Object> runCallablesUsingSshClient(Iterable<SshCallable<?>> parallel, SshClient ssh) {
Map<SshCallable<?>, Future<?>> parallelResponses = Maps.newHashMap(); Map<SshCallable<?>, Future<?>> parallelResponses = newHashMap();
for (SshCallable<?> callable : parallel) { for (SshCallable<?> callable : parallel) {
callable.setConnection(ssh, logger); callable.setConnection(ssh, logger);
@ -252,14 +220,14 @@ public class ComputeUtils {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <T> Map<SshCallable<?>, T> transform(Map<SshCallable<?>, Future<?>> responses) { public <T> Map<SshCallable<?>, T> transform(Map<SshCallable<?>, Future<?>> responses) {
Map<SshCallable<?>, T> actualResponses = Maps.newHashMap(); Map<SshCallable<?>, T> actualResponses = newHashMap();
for (Map.Entry<SshCallable<?>, Future<?>> entry : responses.entrySet()) { for (Map.Entry<SshCallable<?>, Future<?>> entry : responses.entrySet()) {
try { try {
actualResponses.put(entry.getKey(), (T) entry.getValue().get()); actualResponses.put(entry.getKey(), (T) entry.getValue().get());
} catch (InterruptedException e) { } catch (InterruptedException e) {
throw Throwables.propagate(e); throw propagate(e);
} catch (ExecutionException e) { } catch (ExecutionException e) {
throw Throwables.propagate(e); throw propagate(e);
} }
} }
return actualResponses; return actualResponses;

View File

@ -22,6 +22,7 @@ package org.jclouds.ssh;
import javax.annotation.PostConstruct; import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy; import javax.annotation.PreDestroy;
import org.jclouds.domain.Credentials;
import org.jclouds.io.Payload; import org.jclouds.io.Payload;
import org.jclouds.net.IPSocket; import org.jclouds.net.IPSocket;
@ -31,9 +32,24 @@ import org.jclouds.net.IPSocket;
public interface SshClient { public interface SshClient {
interface Factory { interface Factory {
/**
* please use {@link Factory#create(IPSocket, Credentials)}
*
* @return
*/
@Deprecated
SshClient create(IPSocket socket, String username, String password); SshClient create(IPSocket socket, String username, String password);
/**
* please use {@link Factory#create(IPSocket, Credentials)}
*
* @return
*/
@Deprecated
SshClient create(IPSocket socket, String username, byte[] privateKey); SshClient create(IPSocket socket, String username, byte[] privateKey);
SshClient create(IPSocket socket, Credentials credentials);
} }
String getUsername(); String getUsername();

View File

@ -74,6 +74,7 @@ import org.jclouds.net.IPSocket;
import org.jclouds.predicates.RetryablePredicate; 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.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;
@ -82,7 +83,9 @@ import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import com.google.common.base.Function; import com.google.common.base.Function;
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.inject.Guice; import com.google.inject.Guice;
import com.google.inject.Module; import com.google.inject.Module;
@ -158,8 +161,8 @@ public abstract class BaseComputeServiceLiveTest {
if (context != null) if (context != null)
context.close(); context.close();
Properties props = setupProperties(); Properties props = setupProperties();
context = new ComputeServiceContextFactory().createContext(provider, context = new ComputeServiceContextFactory().createContext(provider, ImmutableSet.of(new Log4JLoggingModule(),
ImmutableSet.of(new Log4JLoggingModule(), getSshModule()), props); getSshModule()), props);
client = context.getComputeService(); client = context.getComputeService();
} }
@ -170,8 +173,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;
@ -214,7 +217,7 @@ public abstract class BaseComputeServiceLiveTest {
OperatingSystem os = get(nodes, 0).getOperatingSystem(); OperatingSystem os = get(nodes, 0).getOperatingSystem();
try { try {
Map<? extends NodeMetadata, ExecResponse> responses = runScriptWithCreds(tag, os, new Credentials( Map<? extends NodeMetadata, ExecResponse> responses = runScriptWithCreds(tag, os, new Credentials(
good.identity, "romeo")); good.identity, "romeo"));
assert false : "shouldn't pass with a bad password\n" + responses; assert false : "shouldn't pass with a bad password\n" + responses;
} catch (RunScriptOnNodesException e) { } catch (RunScriptOnNodesException e) {
assert getRootCause(e).getMessage().contains("Auth fail") : e; assert getRootCause(e).getMessage().contains("Auth fail") : e;
@ -236,37 +239,11 @@ public abstract class BaseComputeServiceLiveTest {
assertEquals(toMatch.getImage(), template.getImage()); assertEquals(toMatch.getImage(), template.getImage());
} }
@Test(enabled = true, dependsOnMethods = "testCompareSizes")
public void testCreateAndRunAService() throws Exception {
String tag = this.tag + "service";
try {
client.destroyNodesMatching(withTag(tag));
} catch (Exception e) {
}
template = client.templateBuilder().options(blockOnComplete(false).blockOnPort(8080, 600).inboundPorts(22, 8080))
.build();
// note this is a dependency on the template resolution
template.getOptions().runScript(
RunScriptData.createScriptInstallAndStartJBoss(keyPair.get("public"), template.getImage()
.getOperatingSystem()));
try {
NodeMetadata node = getOnlyElement(client.runNodesWithTag(tag, 1, template));
checkHttpGet(node);
} finally {
client.destroyNodesMatching(withTag(tag));
}
}
protected void checkHttpGet(NodeMetadata node) { protected void checkHttpGet(NodeMetadata node) {
ComputeTestUtils.checkHttpGet(context.utils().http(), node, 8080); ComputeTestUtils.checkHttpGet(context.utils().http(), node, 8080);
} }
@Test(enabled = true, dependsOnMethods = "testCreateAndRunAService") @Test(enabled = true, dependsOnMethods = "testCompareSizes")
public void testCreateTwoNodesWithRunScript() throws Exception { public void testCreateTwoNodesWithRunScript() throws Exception {
try { try {
client.destroyNodesMatching(withTag(tag)); client.destroyNodesMatching(withTag(tag));
@ -299,7 +276,7 @@ public abstract class BaseComputeServiceLiveTest {
template = buildTemplate(client.templateBuilder()); template = buildTemplate(client.templateBuilder());
template.getOptions().installPrivateKey(keyPair.get("private")).authorizePublicKey(keyPair.get("public")) template.getOptions().installPrivateKey(keyPair.get("private")).authorizePublicKey(keyPair.get("public"))
.runScript(newStringPayload(buildScript(template.getImage().getOperatingSystem()))); .runScript(buildScript(template.getImage().getOperatingSystem()));
} }
protected void checkImageIdMatchesTemplate(NodeMetadata node) { protected void checkImageIdMatchesTemplate(NodeMetadata node) {
@ -310,8 +287,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) {
@ -339,14 +316,14 @@ public abstract class BaseComputeServiceLiveTest {
public void testCredentialsCache() throws Exception { public void testCredentialsCache() throws Exception {
initializeContextAndClient(); initializeContextAndClient();
for (NodeMetadata node : nodes) for (NodeMetadata node : nodes)
assert (context.getCredentialStore().get(node.getId()) != null) : "credentials for " + node.getId(); assert (context.getCredentialStore().get("node#" + node.getId()) != null) : "credentials for " + node.getId();
} }
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), newStringPayload(buildScript(os)), return client.runScriptOnNodesMatching(runningWithTag(tag), newStringPayload(buildScript(os).render(
overrideCredentialsWith(creds).nameTask("runScriptWithCreds")); OsFamily.UNIX)), overrideCredentialsWith(creds).nameTask("runScriptWithCreds"));
} catch (SshException e) { } catch (SshException e) {
throw e; throw e;
} }
@ -358,7 +335,8 @@ public abstract class BaseComputeServiceLiveTest {
assertNotNull(node.getTag()); assertNotNull(node.getTag());
assertEquals(node.getTag(), tag); assertEquals(node.getTag(), tag);
assertEquals(node.getState(), NodeState.RUNNING); assertEquals(node.getState(), NodeState.RUNNING);
assertEquals(context.getCredentialStore().get(node.getId()), node.getCredentials()); Credentials fromStore = context.getCredentialStore().get("node#" + node.getId());
assertEquals(fromStore, node.getCredentials());
assert node.getPublicAddresses().size() >= 1 || node.getPrivateAddresses().size() >= 1 : "no ips in" + node; assert node.getPublicAddresses().size() >= 1 || node.getPrivateAddresses().size() >= 1 : "no ips in" + node;
assertNotNull(node.getCredentials()); assertNotNull(node.getCredentials());
if (node.getCredentials().identity != null) { if (node.getCredentials().identity != null) {
@ -375,16 +353,16 @@ 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
public String apply(NodeMetadata from) { public String apply(NodeMetadata from) {
return from.getId(); return from.getId();
} }
})); }));
for (NodeMetadata node : nodes) { for (NodeMetadata node : nodes) {
metadataMap.remove(node.getId()); metadataMap.remove(node.getId());
NodeMetadata metadata = client.getNodeMetadata(node.getId()); NodeMetadata metadata = client.getNodeMetadata(node.getId());
@ -402,7 +380,7 @@ public abstract class BaseComputeServiceLiveTest {
protected void assertNodeZero(Collection<? extends NodeMetadata> metadataSet) { protected void assertNodeZero(Collection<? extends NodeMetadata> metadataSet) {
assert metadataSet.size() == 0 : String.format("nodes left in set: [%s] which didn't match set: [%s]", assert metadataSet.size() == 0 : String.format("nodes left in set: [%s] which didn't match set: [%s]",
metadataSet, nodes); metadataSet, nodes);
} }
@Test(enabled = true, dependsOnMethods = "testGet") @Test(enabled = true, dependsOnMethods = "testGet")
@ -412,13 +390,25 @@ public abstract class BaseComputeServiceLiveTest {
testGet(); testGet();
} }
@Test(enabled = true/* , dependsOnMethods = "testCompareSizes" */) @Test(enabled = true, dependsOnMethods = "testReboot")
public void testTemplateOptions() throws Exception { public void testSuspendResume() throws Exception {
TemplateOptions options = new TemplateOptions().withMetadata(); client.suspendNodesMatching(withTag(tag));
Template t = client.templateBuilder().smallest().options(options).build(); Set<? extends NodeMetadata> stoppedNodes = refreshNodes();
assert t.getOptions().isIncludeMetadata() : "The metadata option should be 'true' " + "for the created template";
assert Iterables.all(stoppedNodes, new Predicate<NodeMetadata>() {
@Override
public boolean apply(NodeMetadata input) {
return input.getState() == NodeState.SUSPENDED;
}
}) : nodes;
client.resumeNodesMatching(withTag(tag));
testGet();
} }
@Test(enabled = true, dependsOnMethods = "testSuspendResume")
public void testListNodes() throws Exception { public void testListNodes() throws Exception {
for (ComputeMetadata node : client.listNodes()) { for (ComputeMetadata node : client.listNodes()) {
assert node.getProviderId() != null; assert node.getProviderId() != null;
@ -427,6 +417,7 @@ public abstract class BaseComputeServiceLiveTest {
} }
} }
@Test(enabled = true, dependsOnMethods = "testSuspendResume")
public void testGetNodesWithDetails() throws Exception { public void testGetNodesWithDetails() throws Exception {
for (NodeMetadata node : client.listNodesDetailsMatching(all())) { for (NodeMetadata node : client.listNodesDetailsMatching(all())) {
assert node.getProviderId() != null : node; assert node.getProviderId() != null : node;
@ -447,6 +438,52 @@ public abstract class BaseComputeServiceLiveTest {
} }
} }
@Test(enabled = true, dependsOnMethods = { "testListNodes", "testGetNodesWithDetails" })
public void testDestroyNodes() {
client.destroyNodesMatching(withTag(tag));
for (NodeMetadata node : filter(client.listNodesDetailsMatching(all()), withTag(tag))) {
assert node.getState() == NodeState.TERMINATED : node;
assertEquals(context.getCredentialStore().get("node#" + node.getId()), null);
}
}
private Set<? extends NodeMetadata> refreshNodes() {
return filter(client.listNodesDetailsMatching(all()), and(withTag(tag), not(TERMINATED)));
}
@Test(enabled = true)
public void testCreateAndRunAService() throws Exception {
String tag = this.tag + "service";
try {
client.destroyNodesMatching(withTag(tag));
} catch (Exception e) {
}
template = client.templateBuilder().options(blockOnComplete(false).blockOnPort(8080, 600).inboundPorts(22, 8080))
.build();
// note this is a dependency on the template resolution
template.getOptions().runScript(
RunScriptData.createScriptInstallAndStartJBoss(keyPair.get("public"), template.getImage()
.getOperatingSystem()));
try {
NodeMetadata node = getOnlyElement(client.runNodesWithTag(tag, 1, template));
checkHttpGet(node);
} finally {
client.destroyNodesMatching(withTag(tag));
}
}
@Test(enabled = true/* , dependsOnMethods = "testCompareSizes" */)
public void testTemplateOptions() throws Exception {
TemplateOptions options = new TemplateOptions().withMetadata();
Template t = client.templateBuilder().smallest().options(options).build();
assert t.getOptions().isIncludeMetadata() : "The metadata option should be 'true' " + "for the created template";
}
public void testListImages() throws Exception { public void testListImages() throws Exception {
for (Image image : client.listImages()) { for (Image image : client.listImages()) {
assert image.getProviderId() != null : image; assert image.getProviderId() != null : image;
@ -463,31 +500,30 @@ public abstract class BaseComputeServiceLiveTest {
assert location != location.getParent() : location; assert location != location.getParent() : location;
assert location.getScope() != null : location; assert location.getScope() != null : location;
switch (location.getScope()) { switch (location.getScope()) {
case PROVIDER: case PROVIDER:
assertProvider(location); assertProvider(location);
break; break;
case REGION: case REGION:
assertProvider(location.getParent()); assertProvider(location.getParent());
break; break;
case ZONE: case ZONE:
Location provider = location.getParent().getParent(); Location provider = location.getParent().getParent();
// zone can be a direct descendant of provider // zone can be a direct descendant of provider
if (provider == null) if (provider == null)
provider = location.getParent(); provider = location.getParent();
assertProvider(provider); assertProvider(provider);
break; break;
case HOST: case HOST:
Location provider2 = location.getParent().getParent().getParent(); Location provider2 = location.getParent().getParent().getParent();
// zone can be a direct descendant of provider // zone can be a direct descendant of provider
if (provider2 == null) if (provider2 == null)
provider2 = location.getParent().getParent(); provider2 = location.getParent().getParent();
assertProvider(provider2); assertProvider(provider2);
break; break;
} }
} }
} }
@Test(enabled = true, dependsOnMethods = "testGet")
public void testOptionToNotBlock() throws Exception { public void testOptionToNotBlock() throws Exception {
String tag = this.tag + "block"; String tag = this.tag + "block";
try { try {
@ -564,26 +600,14 @@ public abstract class BaseComputeServiceLiveTest {
} }
protected void doCheckJavaIsInstalledViaSsh(NodeMetadata node) throws IOException { protected void doCheckJavaIsInstalledViaSsh(NodeMetadata node) throws IOException {
IPSocket socket = new IPSocket(get(node.getPublicAddresses(), 0), 22); SshClient ssh = context.utils().sshForNode().apply(node);
socketTester.apply(socket); // TODO add transitionTo option that accepts
// a socket conection
// state.
SshClient ssh = (node.getCredentials().credential != null && !node.getCredentials().credential
.startsWith("-----BEGIN RSA PRIVATE KEY-----")) ? context.utils().sshFactory()
.create(socket, node.getCredentials().identity, node.getCredentials().credential) : context
.utils()
.sshFactory()
.create(
socket,
node.getCredentials().identity,
node.getCredentials().credential != null ? node.getCredentials().credential.getBytes() : keyPair.get(
"private").getBytes());
try { try {
ssh.connect(); ssh.connect();
ExecResponse hello = ssh.exec("echo hello"); ExecResponse hello = ssh.exec("echo hello");
assertEquals(hello.getOutput().trim(), "hello"); assertEquals(hello.getOutput().trim(), "hello");
ExecResponse exec = ssh.exec("java -version"); ExecResponse exec = ssh.exec("java -version");
assert exec.getError().indexOf("1.6") != -1 || exec.getOutput().indexOf("1.6") != -1 : exec; assert exec.getError().indexOf("1.6") != -1 || exec.getOutput().indexOf("1.6") != -1 : exec + "\n"
+ ssh.exec("cat /tmp/bootstrap/stdout.log /tmp/bootstrap/stderr.log");
} finally { } finally {
if (ssh != null) if (ssh != null)
ssh.disconnect(); ssh.disconnect();
@ -593,11 +617,7 @@ public abstract class BaseComputeServiceLiveTest {
@AfterTest @AfterTest
protected void cleanup() throws InterruptedException, ExecutionException, TimeoutException { protected void cleanup() throws InterruptedException, ExecutionException, TimeoutException {
if (nodes != null) { if (nodes != null) {
client.destroyNodesMatching(withTag(tag)); testDestroyNodes();
for (NodeMetadata node : filter(client.listNodesDetailsMatching(all()), withTag(tag))) {
assert node.getState() == NodeState.TERMINATED : node;
assertEquals(context.getCredentialStore().get(node.getId()), null);
}
} }
context.close(); context.close();
} }

View File

@ -19,7 +19,11 @@
package org.jclouds.compute; package org.jclouds.compute;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.Iterables.get;
import static org.jclouds.util.Utils.checkNotEmpty; import static org.jclouds.util.Utils.checkNotEmpty;
import static org.testng.Assert.assertEquals;
import java.io.File; import java.io.File;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
@ -27,18 +31,15 @@ import java.lang.reflect.UndeclaredThrowableException;
import java.net.URI; import java.net.URI;
import java.util.Map; import java.util.Map;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
import static org.testng.Assert.assertEquals;
import static com.google.common.base.Preconditions.checkNotNull;
import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.OperatingSystem; import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.compute.predicates.OperatingSystemPredicates;
import org.jclouds.rest.HttpClient; import org.jclouds.rest.HttpClient;
import org.jclouds.scriptbuilder.domain.Statement;
import com.google.common.base.Charsets; import com.google.common.base.Charsets;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.common.io.Files; import com.google.common.io.Files;
import static com.google.common.collect.Iterables.get;
/** /**
* utilities helpful in testing compute providers * utilities helpful in testing compute providers
@ -46,15 +47,8 @@ import static com.google.common.collect.Iterables.get;
* @author Adrian Cole * @author Adrian Cole
*/ */
public class ComputeTestUtils { public class ComputeTestUtils {
public static String buildScript(OperatingSystem os) { public static Statement buildScript(OperatingSystem os) {
if (OperatingSystemPredicates.supportsApt().apply(os)) return RunScriptData.installJavaAndCurl(os);
return RunScriptData.APT_RUN_SCRIPT;
else if (OperatingSystemPredicates.supportsYum().apply(os))
return RunScriptData.YUM_RUN_SCRIPT;
else if (OperatingSystemPredicates.supportsZypper().apply(os))
return RunScriptData.ZYPPER_RUN_SCRIPT;
else
throw new IllegalArgumentException("don't know how to handle" + os.toString());
} }
public static Map<String, String> setupKeyPair() throws FileNotFoundException, IOException { public static Map<String, String> setupKeyPair() throws FileNotFoundException, IOException {
@ -67,8 +61,8 @@ public class ComputeTestUtils {
checkSecretKeyFile(secretKeyFile); checkSecretKeyFile(secretKeyFile);
String secret = Files.toString(new File(secretKeyFile), Charsets.UTF_8); String secret = Files.toString(new File(secretKeyFile), Charsets.UTF_8);
assert secret.startsWith("-----BEGIN RSA PRIVATE KEY-----") : "invalid key:\n" + secret; assert secret.startsWith("-----BEGIN RSA PRIVATE KEY-----") : "invalid key:\n" + secret;
return ImmutableMap.<String, String> of("private", secret, "public", return ImmutableMap.<String, String> of("private", secret, "public", Files.toString(new File(secretKeyFile
Files.toString(new File(secretKeyFile + ".pub"), Charsets.UTF_8)); + ".pub"), Charsets.UTF_8));
} }
public static void checkSecretKeyFile(String secretKeyFile) throws FileNotFoundException { public static void checkSecretKeyFile(String secretKeyFile) throws FileNotFoundException {

View File

@ -19,9 +19,11 @@
package org.jclouds.compute; package org.jclouds.compute;
import static org.jclouds.compute.util.ComputeServiceUtils.execHttpResponse;
import static org.jclouds.compute.util.ComputeServiceUtils.extractTargzIntoDirectory; import static org.jclouds.compute.util.ComputeServiceUtils.extractTargzIntoDirectory;
import static org.jclouds.scriptbuilder.domain.Statements.exec; import static org.jclouds.scriptbuilder.domain.Statements.exec;
import static org.jclouds.scriptbuilder.domain.Statements.interpret; import static org.jclouds.scriptbuilder.domain.Statements.interpret;
import static org.jclouds.scriptbuilder.domain.Statements.newStatementList;
import java.net.URI; import java.net.URI;
import java.util.Map; import java.util.Map;
@ -43,7 +45,7 @@ public class RunScriptData {
private static String jbossHome = "/usr/local/jboss"; private static String jbossHome = "/usr/local/jboss";
public static String installJavaAndCurl(OperatingSystem os) { public static Statement installJavaAndCurl(OperatingSystem os) {
if (os == null || OperatingSystemPredicates.supportsApt().apply(os)) if (os == null || OperatingSystemPredicates.supportsApt().apply(os))
return APT_RUN_SCRIPT; return APT_RUN_SCRIPT;
else if (OperatingSystemPredicates.supportsYum().apply(os)) else if (OperatingSystemPredicates.supportsYum().apply(os))
@ -57,50 +59,62 @@ public class RunScriptData {
public static Statement createScriptInstallAndStartJBoss(String publicKey, OperatingSystem os) { public static Statement createScriptInstallAndStartJBoss(String publicKey, OperatingSystem os) {
Map<String, String> envVariables = ImmutableMap.of("jbossHome", jbossHome); Map<String, String> envVariables = ImmutableMap.of("jbossHome", jbossHome);
Statement toReturn = new InitBuilder( Statement toReturn = new InitBuilder(
"jboss", "jboss",
jbossHome, jbossHome,
jbossHome, jbossHome,
envVariables, envVariables,
ImmutableList.<Statement> of( ImmutableList
new AuthorizeRSAPublicKey(publicKey), .<Statement> of(
exec(installJavaAndCurl(os)), new AuthorizeRSAPublicKey(publicKey),//
exec("rm -rf /var/cache/apt /usr/lib/vmware-tools"),// jeos hasn't enough room! installJavaAndCurl(os),//
extractTargzIntoDirectory( // just in case iptables are being used, try to open 8080
URI.create("http://commondatastorage.googleapis.com/jclouds-repo/jboss-as-distribution-6.0.0.20100911-M5.tar.gz"), exec("iptables -I INPUT 1 -p tcp --dport 8080 -j ACCEPT"),//
"/usr/local"), exec("{md} " + jbossHome), exec("mv /usr/local/jboss-*/* " + jbossHome), // TODO gogrid rules only allow ports 22, 3389, 80 and 443.
exec("chmod -R oug+r+w " + jbossHome)), // the above rule will be ignored, so we have to apply this
ImmutableList // directly
.<Statement> of(interpret("java -Xms128m -Xmx512m -XX:MaxPermSize=256m -Dorg.jboss.resolver.warning=true -Dsun.rmi.dgc.client.gcInterval=3600000 -Dsun.rmi.dgc.server.gcInterval=3600000 -Djava.endorsed.dirs=lib/endorsed -classpath bin/run.jar org.jboss.Main -b 0.0.0.0"))); exec("iptables -I RH-Firewall-1-INPUT 1 -p tcp --dport 8080 -j ACCEPT"),//
exec("iptables-save"),//
extractTargzIntoDirectory(
URI
.create("http://commondatastorage.googleapis.com/jclouds-repo/jboss-as-distribution-6.0.0.20100911-M5.tar.gz"),
"/usr/local"), exec("{md} " + jbossHome), exec("mv /usr/local/jboss-*/* "
+ jbossHome),//
exec("chmod -R oug+r+w " + jbossHome)),//
ImmutableList
.<Statement> of(interpret("java -Xms128m -Xmx512m -XX:MaxPermSize=256m -Dorg.jboss.resolver.warning=true -Dsun.rmi.dgc.client.gcInterval=3600000 -Dsun.rmi.dgc.server.gcInterval=3600000 -Djava.endorsed.dirs=lib/endorsed -classpath bin/run.jar org.jboss.Main -b 0.0.0.0")));
return toReturn; return toReturn;
} }
public static final String APT_RUN_SCRIPT = new StringBuilder()// public static String aptInstall = "apt-get install -f -y -qq --force-yes";
.append("echo nameserver 208.67.222.222 >> /etc/resolv.conf\n")//
.append("cp /etc/apt/sources.list /etc/apt/sources.list.old\n")//
.append(
"sed 's~us.archive.ubuntu.com~mirror.anl.gov/pub~g' /etc/apt/sources.list.old >/etc/apt/sources.list\n")//
.append("which curl || apt-get update -y -qq && apt-get install -f -y -qq --force-yes curl\n")//
.append(
"(which java && java -fullversion 2>&1|egrep -q 1.6 ) || apt-get install -f -y -qq --force-yes openjdk-6-jre\n")//
.append("rm -rf /var/cache/apt /usr/lib/vmware-tools\n")// jeos hasn't enough room!
.toString();
public static final String YUM_RUN_SCRIPT = new StringBuilder() public static String installAfterUpdatingIfNotPresent(String cmd) {
.append("echo nameserver 208.67.222.222 >> /etc/resolv.conf\n") // String aptInstallCmd = aptInstall + " " + cmd;
.append("echo \"[jdkrepo]\" >> /etc/yum.repos.d/CentOS-Base.repo\n") // return String.format("which %s || (%s || (apt-get update && %s))", cmd, aptInstallCmd, aptInstallCmd);
.append("echo \"name=jdkrepository\" >> /etc/yum.repos.d/CentOS-Base.repo\n") // }
.append(
"echo \"baseurl=http://ec2-us-east-mirror.rightscale.com/epel/5/i386/\" >> /etc/yum.repos.d/CentOS-Base.repo\n")//
.append("echo \"enabled=1\" >> /etc/yum.repos.d/CentOS-Base.repo\n")//
.append("which curl ||yum --nogpgcheck -y install curl\n")//
.append(
"(which java && java -fullversion 2>&1|egrep -q 1.6 ) || yum --nogpgcheck -y install java-1.6.0-openjdk&&")//
.append("echo \"export PATH=\\\"/usr/lib/jvm/jre-1.6.0-openjdk/bin/:\\$PATH\\\"\" >> /root/.bashrc\n")//
.toString();
public static final String ZYPPER_RUN_SCRIPT = new StringBuilder()// public static final Statement APT_RUN_SCRIPT = newStatementList(//
.append("echo nameserver 208.67.222.222 >> /etc/resolv.conf\n")// exec(installAfterUpdatingIfNotPresent("curl")),//
.append("which curl || zypper install curl\n")// exec("(which java && java -fullversion 2>&1|egrep -q 1.6 ) ||"),//
.append("(which java && java -fullversion 2>&1|egrep -q 1.6 ) || zypper install java-1.6.0-openjdk\n")// execHttpResponse(URI.create("http://whirr.s3.amazonaws.com/0.2.0-incubating-SNAPSHOT/sun/java/install")),//
.toString(); exec(new StringBuilder()//
.append("echo nameserver 208.67.222.222 >> /etc/resolv.conf\n")//
// jeos hasn't enough room!
.append("rm -rf /var/cache/apt /usr/lib/vmware-tools\n")//
.append("echo \"export PATH=\\\"\\$JAVA_HOME/bin/:\\$PATH\\\"\" >> /root/.bashrc")//
.toString()));
public static final Statement YUM_RUN_SCRIPT = newStatementList(
exec("which curl ||yum --nogpgcheck -y install curl"),//
exec("(which java && java -fullversion 2>&1|egrep -q 1.6 ) ||"),//
execHttpResponse(URI.create("http://whirr.s3.amazonaws.com/0.2.0-incubating-SNAPSHOT/sun/java/install")),//
exec(new StringBuilder()//
.append("echo nameserver 208.67.222.222 >> /etc/resolv.conf\n") //
.append("echo \"export PATH=\\\"\\$JAVA_HOME/bin/:\\$PATH\\\"\" >> /root/.bashrc")//
.toString()));
public static final Statement ZYPPER_RUN_SCRIPT = exec(new StringBuilder()//
.append("echo nameserver 208.67.222.222 >> /etc/resolv.conf\n")//
.append("which curl || zypper install curl\n")//
.append("(which java && java -fullversion 2>&1|egrep -q 1.6 ) || zypper install java-1.6.0-openjdk\n")//
.toString());
} }

View File

@ -19,7 +19,6 @@
package org.jclouds.compute; package org.jclouds.compute;
import static org.easymock.EasyMock.aryEq;
import static org.easymock.EasyMock.eq; import static org.easymock.EasyMock.eq;
import static org.easymock.EasyMock.expect; import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.reportMatcher; import static org.easymock.EasyMock.reportMatcher;
@ -41,6 +40,7 @@ import org.easymock.IArgumentMatcher;
import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.OsFamily; import org.jclouds.compute.domain.OsFamily;
import org.jclouds.compute.domain.Template; import org.jclouds.compute.domain.Template;
import org.jclouds.domain.Credentials;
import org.jclouds.io.Payload; import org.jclouds.io.Payload;
import org.jclouds.net.IPSocket; import org.jclouds.net.IPSocket;
import org.jclouds.predicates.RetryablePredicate; import org.jclouds.predicates.RetryablePredicate;
@ -120,50 +120,49 @@ public class StubComputeServiceIntegrationTest extends BaseComputeServiceLiveTes
SshClient client4 = createMock(SshClient.class); SshClient client4 = createMock(SshClient.class);
SshClient client5 = createMock(SshClient.class); SshClient client5 = createMock(SshClient.class);
expect(factory.create(new IPSocket("144.175.1.1", 22), "root", "password1")).andReturn(client1) expect(factory.create(new IPSocket("144.175.1.1", 22), new Credentials("root", "password1"))).andReturn(
.atLeastOnce(); client1);
runScriptAndService(client1, 1); runScriptAndService(client1, 1);
expect(factory.create(new IPSocket("144.175.1.2", 22), "root", "romeo")).andThrow( expect(factory.create(new IPSocket("144.175.1.2", 22), new Credentials("root", "password2"))).andReturn(
new SshException("Auth fail")); client2).times(2);
expect(factory.create(new IPSocket("144.175.1.2", 22), "root", "password2")).andReturn(client2) expect(factory.create(new IPSocket("144.175.1.2", 22), new Credentials("root", "romeo"))).andThrow(
.atLeastOnce(); new SshException("Auth fail"));
client2.connect(); client2.connect();
try { try {
runScript(client2, "runScriptWithCreds", Utils.toStringAndClose(StubComputeServiceIntegrationTest.class runScript(client2, "runScriptWithCreds", Utils.toStringAndClose(StubComputeServiceIntegrationTest.class
.getResourceAsStream("/runscript.sh")), 2); .getResourceAsStream("/runscript.sh")), 2);
} catch (IOException e) { } catch (IOException e) {
Throwables.propagate(e); Throwables.propagate(e);
} }
client2.disconnect(); client2.disconnect();
expect(factory.create(new IPSocket("144.175.1.3", 22), "root", "password3")).andReturn(client3) expect(factory.create(new IPSocket("144.175.1.3", 22), new Credentials("root", "password3"))).andReturn(
.atLeastOnce(); client3).times(2);
expect(factory.create(new IPSocket("144.175.1.4", 22), "root", "password4")).andReturn(client4) expect(factory.create(new IPSocket("144.175.1.4", 22), new Credentials("root", "password4"))).andReturn(
.atLeastOnce(); client4).times(2);
expect(factory.create(new IPSocket("144.175.1.5", 22), "root", "password5")).andReturn(client5) expect(factory.create(new IPSocket("144.175.1.5", 22), new Credentials("root", "password5"))).andReturn(
.atLeastOnce(); client5).times(2);
runScriptAndInstallSsh(client3, "bootstrap", 3); runScriptAndInstallSsh(client3, "bootstrap", 3);
runScriptAndInstallSsh(client4, "bootstrap", 4); runScriptAndInstallSsh(client4, "bootstrap", 4);
runScriptAndInstallSsh(client5, "bootstrap", 5); runScriptAndInstallSsh(client5, "bootstrap", 5);
expect( expect(
factory.create(eq(new IPSocket("144.175.1.1", 22)), eq("root"), aryEq(keyPair.get("private") factory.create(eq(new IPSocket("144.175.1.1", 22)), eq(new Credentials("root", keyPair
.getBytes()))).andReturn(client1).atLeastOnce(); .get("private"))))).andReturn(client1);
expect( expect(
factory.create(eq(new IPSocket("144.175.1.2", 22)), eq("root"), aryEq(keyPair.get("private") factory.create(eq(new IPSocket("144.175.1.2", 22)), eq(new Credentials("root", keyPair
.getBytes()))).andReturn(client2).atLeastOnce(); .get("private"))))).andReturn(client2);
expect( expect(
factory.create(eq(new IPSocket("144.175.1.3", 22)), eq("root"), aryEq(keyPair.get("private") factory.create(eq(new IPSocket("144.175.1.3", 22)), eq(new Credentials("root", keyPair
.getBytes()))).andReturn(client3).atLeastOnce(); .get("private"))))).andReturn(client3);
expect( expect(
factory.create(eq(new IPSocket("144.175.1.4", 22)), eq("root"), aryEq(keyPair.get("private") factory.create(eq(new IPSocket("144.175.1.4", 22)), eq(new Credentials("root", keyPair
.getBytes()))).andReturn(client4).atLeastOnce(); .get("private"))))).andReturn(client4);
expect( expect(
factory.create(eq(new IPSocket("155.175.1.5", 22)), eq("root"), aryEq(keyPair.get("private") factory.create(eq(new IPSocket("144.175.1.5", 22)), eq(new Credentials("root", keyPair
.getBytes()))).andReturn(client5).atLeastOnce(); .get("private"))))).andReturn(client5);
helloAndJava(client2); helloAndJava(client2);
helloAndJava(client3); helloAndJava(client3);
@ -185,7 +184,7 @@ public class StubComputeServiceIntegrationTest extends BaseComputeServiceLiveTes
try { try {
runScript(client, "jboss", Utils.toStringAndClose(StubComputeServiceIntegrationTest.class runScript(client, "jboss", Utils.toStringAndClose(StubComputeServiceIntegrationTest.class
.getResourceAsStream("/initscript_with_jboss.sh")), nodeId); .getResourceAsStream("/initscript_with_jboss.sh")), nodeId);
} catch (IOException e) { } catch (IOException e) {
Throwables.propagate(e); Throwables.propagate(e);
} }
@ -199,7 +198,7 @@ public class StubComputeServiceIntegrationTest extends BaseComputeServiceLiveTes
try { try {
runScript(client, scriptName, Utils.toStringAndClose(StubComputeServiceIntegrationTest.class runScript(client, scriptName, Utils.toStringAndClose(StubComputeServiceIntegrationTest.class
.getResourceAsStream("/initscript_with_java.sh")), nodeId); .getResourceAsStream("/initscript_with_java.sh")), nodeId);
} catch (IOException e) { } catch (IOException e) {
Throwables.propagate(e); Throwables.propagate(e);
} }
@ -252,7 +251,7 @@ public class StubComputeServiceIntegrationTest extends BaseComputeServiceLiveTes
public void testAssignability() throws Exception { public void testAssignability() throws Exception {
@SuppressWarnings("unused") @SuppressWarnings("unused")
RestContext<ConcurrentMap<String, NodeMetadata>, ConcurrentMap<String, NodeMetadata>> stubContext = new ComputeServiceContextFactory() RestContext<ConcurrentMap<String, NodeMetadata>, ConcurrentMap<String, NodeMetadata>> stubContext = new ComputeServiceContextFactory()
.createContext(provider, identity, credential).getProviderSpecificContext(); .createContext(provider, identity, credential).getProviderSpecificContext();
} }
private static class PayloadEquals implements IArgumentMatcher, Serializable { private static class PayloadEquals implements IArgumentMatcher, Serializable {
@ -299,7 +298,7 @@ public class StubComputeServiceIntegrationTest extends BaseComputeServiceLiveTes
return false; return false;
PayloadEquals other = (PayloadEquals) o; PayloadEquals other = (PayloadEquals) o;
return this.expected == null && other.expected == null || this.expected != null return this.expected == null && other.expected == null || this.expected != null
&& this.expected.equals(other.expected); && this.expected.equals(other.expected);
} }
@Override @Override
@ -362,11 +361,31 @@ public class StubComputeServiceIntegrationTest extends BaseComputeServiceLiveTes
super.testReboot(); super.testReboot();
} }
@Test(enabled = true, dependsOnMethods = "testReboot")
public void testSuspendResume() throws Exception {
super.testSuspendResume();
}
@Test(enabled = true, dependsOnMethods = { "testImagesCache" }) @Test(enabled = true, dependsOnMethods = { "testImagesCache" })
public void testTemplateMatch() throws Exception { public void testTemplateMatch() throws Exception {
super.testTemplateMatch(); super.testTemplateMatch();
} }
@Override
public void testGetNodesWithDetails() throws Exception {
super.testGetNodesWithDetails();
}
@Override
public void testListNodes() throws Exception {
super.testListNodes();
}
@Override
public void testDestroyNodes() {
super.testDestroyNodes();
}
@Override @Override
protected void cleanup() throws InterruptedException, ExecutionException, TimeoutException { protected void cleanup() throws InterruptedException, ExecutionException, TimeoutException {
super.cleanup(); super.cleanup();

View File

@ -39,6 +39,7 @@ import org.jclouds.compute.domain.TemplateBuilder;
import org.jclouds.compute.options.TemplateOptions; import org.jclouds.compute.options.TemplateOptions;
import org.jclouds.compute.predicates.ImagePredicates; import org.jclouds.compute.predicates.ImagePredicates;
import org.jclouds.domain.Location; import org.jclouds.domain.Location;
import org.jclouds.domain.LocationScope;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import com.google.common.base.Supplier; import com.google.common.base.Supplier;
@ -54,7 +55,7 @@ public class TemplateBuilderImplTest {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Test @Test
public void tesResolveImages() { public void testResolveImages() {
Location defaultLocation = createMock(Location.class); Location defaultLocation = createMock(Location.class);
Image image = createMock(Image.class); Image image = createMock(Image.class);
OperatingSystem os = createMock(OperatingSystem.class); OperatingSystem os = createMock(OperatingSystem.class);
@ -202,6 +203,8 @@ public class TemplateBuilderImplTest {
expect(os.getArch()).andReturn(null).atLeastOnce(); expect(os.getArch()).andReturn(null).atLeastOnce();
expect(os.is64Bit()).andReturn(false).atLeastOnce(); expect(os.is64Bit()).andReturn(false).atLeastOnce();
expect(defaultLocation.getScope()).andReturn(LocationScope.PROVIDER).atLeastOnce();
replay(image); replay(image);
replay(os); replay(os);
replay(defaultTemplate); replay(defaultTemplate);
@ -257,6 +260,8 @@ public class TemplateBuilderImplTest {
expect(os.getArch()).andReturn(null).atLeastOnce(); expect(os.getArch()).andReturn(null).atLeastOnce();
expect(os.is64Bit()).andReturn(false).atLeastOnce(); expect(os.is64Bit()).andReturn(false).atLeastOnce();
expect(defaultLocation.getScope()).andReturn(LocationScope.PROVIDER).atLeastOnce();
replay(image); replay(image);
replay(os); replay(os);
replay(defaultTemplate); replay(defaultTemplate);
@ -359,6 +364,70 @@ public class TemplateBuilderImplTest {
return template; return template;
} }
@SuppressWarnings("unchecked")
@Test
public void testSuppliedImageLocationWiderThanDefault() {
TemplateOptions from = provideTemplateOptions();
Location defaultLocation = createMock(Location.class);
Image image = createMock(Image.class);
Hardware hardware = new HardwareBuilder().id("hardwareId").supportsImage(ImagePredicates.idEquals("foo")).build();
Supplier<Set<? extends Location>> locations = Suppliers.<Set<? extends Location>> ofInstance(ImmutableSet
.<Location> of(defaultLocation));
Supplier<Set<? extends Image>> images = Suppliers.<Set<? extends Image>> ofInstance(ImmutableSet
.<Image> of(image));
Supplier<Set<? extends Hardware>> hardwares = Suppliers.<Set<? extends Hardware>> ofInstance(ImmutableSet
.<Hardware> of(hardware));
Location imageLocation = createMock(Location.class);
OperatingSystem os = createMock(OperatingSystem.class);
Provider<TemplateOptions> optionsProvider = createMock(Provider.class);
Provider<TemplateBuilder> templateBuilderProvider = createMock(Provider.class);
TemplateOptions defaultOptions = createMock(TemplateOptions.class);
expect(optionsProvider.get()).andReturn(from).atLeastOnce();
expect(defaultLocation.getId()).andReturn("location").atLeastOnce();
expect(image.getId()).andReturn("foo").atLeastOnce();
expect(image.getLocation()).andReturn(defaultLocation).atLeastOnce();
expect(image.getOperatingSystem()).andReturn(os).atLeastOnce();
expect(image.getName()).andReturn(null).atLeastOnce();
expect(image.getDescription()).andReturn(null).atLeastOnce();
expect(image.getVersion()).andReturn(null).atLeastOnce();
expect(os.getName()).andReturn(null).atLeastOnce();
expect(os.getVersion()).andReturn(null).atLeastOnce();
expect(os.getFamily()).andReturn(null).atLeastOnce();
expect(os.getDescription()).andReturn(null).atLeastOnce();
expect(os.getArch()).andReturn(null).atLeastOnce();
expect(os.is64Bit()).andReturn(false).atLeastOnce();
expect(defaultLocation.getScope()).andReturn(LocationScope.HOST).atLeastOnce();
replay(defaultOptions);
replay(imageLocation);
replay(image);
replay(os);
replay(defaultLocation);
replay(optionsProvider);
replay(templateBuilderProvider);
TemplateBuilderImpl template = createTemplateBuilder(null, locations, images, hardwares, defaultLocation,
optionsProvider, templateBuilderProvider);
assertEquals(template.imageId("foo").locationId("location").build().getLocation(), defaultLocation);
verify(defaultOptions);
verify(imageLocation);
verify(image);
verify(os);
verify(defaultLocation);
verify(optionsProvider);
verify(templateBuilderProvider);
}
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Test @Test
public void testSuppliedLocationWithNoOptions() { public void testSuppliedLocationWithNoOptions() {

View File

@ -76,18 +76,17 @@ END_OF_SCRIPT
# add desired commands from the user # add desired commands from the user
cat >> $INSTANCE_HOME/bootstrap.sh <<'END_OF_SCRIPT' cat >> $INSTANCE_HOME/bootstrap.sh <<'END_OF_SCRIPT'
cd $INSTANCE_HOME cd $INSTANCE_HOME
echo nameserver 208.67.222.222 >> /etc/resolv.conf
cp /etc/apt/sources.list /etc/apt/sources.list.old
sed 's~us.archive.ubuntu.com~mirror.anl.gov/pub~g' /etc/apt/sources.list.old >/etc/apt/sources.list
which curl || apt-get update -y -qq && apt-get install -f -y -qq --force-yes curl
(which java && java -fullversion 2>&1|egrep -q 1.6 ) || apt-get install -f -y -qq --force-yes openjdk-6-jre
rm -rf /var/cache/apt /usr/lib/vmware-tools
mkdir -p ~/.ssh mkdir -p ~/.ssh
cat >> ~/.ssh/authorized_keys <<'END_OF_FILE' cat >> ~/.ssh/authorized_keys <<'END_OF_FILE'
ssh-rsa ssh-rsa
END_OF_FILE END_OF_FILE
chmod 600 ~/.ssh/authorized_keys chmod 600 ~/.ssh/authorized_keys
which curl || (apt-get install -f -y -qq --force-yes curl || (apt-get update && apt-get install -f -y -qq --force-yes curl))
(which java && java -fullversion 2>&1|egrep -q 1.6 ) ||
curl -X GET -s --retry 20 http://whirr.s3.amazonaws.com/0.2.0-incubating-SNAPSHOT/sun/java/install |(bash)
echo nameserver 208.67.222.222 >> /etc/resolv.conf
rm -rf /var/cache/apt /usr/lib/vmware-tools
echo "export PATH=\"\$JAVA_HOME/bin/:\$PATH\"" >> /root/.bashrc
mkdir -p ~/.ssh mkdir -p ~/.ssh
rm ~/.ssh/id_rsa rm ~/.ssh/id_rsa
cat >> ~/.ssh/id_rsa <<'END_OF_FILE' cat >> ~/.ssh/id_rsa <<'END_OF_FILE'

View File

@ -63,14 +63,15 @@ init)
ssh-rsa ssh-rsa
END_OF_FILE END_OF_FILE
chmod 600 ~/.ssh/authorized_keys chmod 600 ~/.ssh/authorized_keys
which curl || (apt-get install -f -y -qq --force-yes curl || (apt-get update && apt-get install -f -y -qq --force-yes curl))
(which java && java -fullversion 2>&1|egrep -q 1.6 ) ||
curl -X GET -s --retry 20 http://whirr.s3.amazonaws.com/0.2.0-incubating-SNAPSHOT/sun/java/install |(bash)
echo nameserver 208.67.222.222 >> /etc/resolv.conf echo nameserver 208.67.222.222 >> /etc/resolv.conf
cp /etc/apt/sources.list /etc/apt/sources.list.old
sed 's~us.archive.ubuntu.com~mirror.anl.gov/pub~g' /etc/apt/sources.list.old >/etc/apt/sources.list
which curl || apt-get update -y -qq && apt-get install -f -y -qq --force-yes curl
(which java && java -fullversion 2>&1|egrep -q 1.6 ) || apt-get install -f -y -qq --force-yes openjdk-6-jre
rm -rf /var/cache/apt /usr/lib/vmware-tools
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
iptables -I INPUT 1 -p tcp --dport 8080 -j ACCEPT
iptables -I RH-Firewall-1-INPUT 1 -p tcp --dport 8080 -j ACCEPT
iptables-save
curl -X GET -s --retry 20 http://commondatastorage.googleapis.com/jclouds-repo/jboss-as-distribution-6.0.0.20100911-M5.tar.gz |(mkdir -p /usr/local &&cd /usr/local &&tar -xpzf -) curl -X GET -s --retry 20 http://commondatastorage.googleapis.com/jclouds-repo/jboss-as-distribution-6.0.0.20100911-M5.tar.gz |(mkdir -p /usr/local &&cd /usr/local &&tar -xpzf -)
mkdir -p /usr/local/jboss mkdir -p /usr/local/jboss
mv /usr/local/jboss-*/* /usr/local/jboss mv /usr/local/jboss-*/* /usr/local/jboss

View File

@ -76,12 +76,12 @@ END_OF_SCRIPT
# add desired commands from the user # add desired commands from the user
cat >> $INSTANCE_HOME/runScriptWithCreds.sh <<'END_OF_SCRIPT' cat >> $INSTANCE_HOME/runScriptWithCreds.sh <<'END_OF_SCRIPT'
cd $INSTANCE_HOME cd $INSTANCE_HOME
which curl || (apt-get install -f -y -qq --force-yes curl || (apt-get update && apt-get install -f -y -qq --force-yes curl))
(which java && java -fullversion 2>&1|egrep -q 1.6 ) ||
curl -X GET -s --retry 20 http://whirr.s3.amazonaws.com/0.2.0-incubating-SNAPSHOT/sun/java/install |(bash)
echo nameserver 208.67.222.222 >> /etc/resolv.conf echo nameserver 208.67.222.222 >> /etc/resolv.conf
cp /etc/apt/sources.list /etc/apt/sources.list.old
sed 's~us.archive.ubuntu.com~mirror.anl.gov/pub~g' /etc/apt/sources.list.old >/etc/apt/sources.list
which curl || apt-get update -y -qq && apt-get install -f -y -qq --force-yes curl
(which java && java -fullversion 2>&1|egrep -q 1.6 ) || apt-get install -f -y -qq --force-yes openjdk-6-jre
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
END_OF_SCRIPT END_OF_SCRIPT

View File

@ -17,6 +17,22 @@
* ==================================================================== * ====================================================================
*/ */
/*
* Copyright (C) 2010 Google Inc.
*
* 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 com.google.gson; package com.google.gson;
import java.io.IOException; import java.io.IOException;

View File

@ -17,6 +17,22 @@
* ==================================================================== * ====================================================================
*/ */
/*
* Copyright (C) 2010 Google Inc.
*
* 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 com.google.gson; package com.google.gson;
import java.io.IOException; import java.io.IOException;

View File

@ -17,6 +17,31 @@
* ==================================================================== * ====================================================================
*/ */
/****************************************************************************
* Copyright (c) 1998-2009 AOL LLC.
*
* 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.
*
****************************************************************************
*
* @author: zhang
* @version: $Revision$
* @created: Apr 24, 2009
*
* Description: A KeySpec for PKCS#1 encoded RSA private key
*
****************************************************************************/
package net.oauth.signature.pem; package net.oauth.signature.pem;
import java.io.IOException; import java.io.IOException;

View File

@ -65,7 +65,9 @@ public class ExceptionParsingListenableFuture<T> implements ListenableFuture<T>
} }
private T attemptConvert(Exception e) { private T attemptConvert(Exception e) {
return function.apply(e instanceof ExecutionException ? (Exception) e.getCause() : e); if (e instanceof ExecutionException && e.getCause() instanceof Exception)
return function.apply((Exception) e.getCause());
return function.apply(e);
} }
public T get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { public T get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {

View File

@ -17,6 +17,22 @@
* ==================================================================== * ====================================================================
*/ */
/*
* Copyright (C) 2007 Google Inc.
*
* 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.concurrent; package org.jclouds.concurrent;
import java.util.Collections; import java.util.Collections;

View File

@ -61,8 +61,8 @@ public class Credentials {
public int hashCode() { public int hashCode() {
final int prime = 31; final int prime = 31;
int result = 1; int result = 1;
result = prime * result + ((identity == null) ? 0 : identity.hashCode());
result = prime * result + ((credential == null) ? 0 : credential.hashCode()); result = prime * result + ((credential == null) ? 0 : credential.hashCode());
result = prime * result + ((identity == null) ? 0 : identity.hashCode());
return result; return result;
} }
@ -72,20 +72,19 @@ public class Credentials {
return true; return true;
if (obj == null) if (obj == null)
return false; return false;
if (getClass() != obj.getClass()) if (!(obj instanceof Credentials))
return false; return false;
Credentials other = (Credentials) obj; Credentials other = (Credentials) obj;
if (identity == null) {
if (other.identity != null)
return false;
} else if (!identity.equals(other.identity))
return false;
if (credential == null) { if (credential == null) {
if (other.credential != null) if (other.credential != null)
return false; return false;
} else if (!credential.equals(other.credential)) } else if (!credential.equals(other.credential))
return false; return false;
if (identity == null) {
if (other.identity != null)
return false;
} else if (!identity.equals(other.identity))
return false;
return true; return true;
} }

View File

@ -21,7 +21,6 @@ package org.jclouds.http.functions;
import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Throwables.propagate;
import static com.google.common.io.Closeables.closeQuietly; import static com.google.common.io.Closeables.closeQuietly;
import java.io.InputStream; import java.io.InputStream;
@ -30,7 +29,6 @@ import java.io.StringReader;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.inject.Inject; import javax.inject.Inject;
import org.jclouds.http.HttpException;
import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse; import org.jclouds.http.HttpResponse;
import org.jclouds.logging.Logger; import org.jclouds.logging.Logger;
@ -38,14 +36,15 @@ import org.jclouds.rest.InvocationContext;
import org.jclouds.rest.internal.GeneratedHttpRequest; import org.jclouds.rest.internal.GeneratedHttpRequest;
import org.jclouds.util.Utils; import org.jclouds.util.Utils;
import org.xml.sax.InputSource; import org.xml.sax.InputSource;
import org.xml.sax.SAXParseException;
import org.xml.sax.XMLReader; import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler; import org.xml.sax.helpers.DefaultHandler;
import com.google.common.base.Function; import com.google.common.base.Function;
/** /**
* This object will parse the body of an HttpResponse and return the result of * This object will parse the body of an HttpResponse and return the result of type <T> back to the
* type <T> back to the caller. * caller.
* *
* @author Adrian Cole * @author Adrian Cole
*/ */
@ -108,6 +107,7 @@ public class ParseSax<T> implements Function<HttpResponse, T>, InvocationContext
public T parse(InputSource from) { public T parse(InputSource from) {
try { try {
checkNotNull(from, "xml inputsource"); checkNotNull(from, "xml inputsource");
from.setEncoding("UTF-8");
parser.setContentHandler(getHandler()); parser.setContentHandler(getHandler());
// This method should accept documents with a BOM (Byte-order mark) // This method should accept documents with a BOM (Byte-order mark)
parser.parse(from); parser.parse(from);
@ -118,16 +118,25 @@ public class ParseSax<T> implements Function<HttpResponse, T>, InvocationContext
} }
private T addRequestDetailsToException(Exception e) { private T addRequestDetailsToException(Exception e) {
String exceptionMessage = e.getMessage();
if (e instanceof SAXParseException) {
SAXParseException parseException = (SAXParseException) e;
String systemId = parseException.getSystemId();
if (systemId == null) {
systemId = "";
}
exceptionMessage = String.format("Error on line %d of document %s: %s", systemId, parseException
.getLineNumber(), parseException.getMessage());
}
if (request != null) { if (request != null) {
StringBuilder message = new StringBuilder(); StringBuilder message = new StringBuilder();
message.append("Error parsing input for ").append(request.getRequestLine()).append(": "); message.append("Error parsing input for ").append(request.getRequestLine()).append(": ");
message.append(e.getMessage()); message.append(exceptionMessage);
logger.error(e, message.toString()); logger.error(e, message.toString());
throw new HttpException(message.toString(), e); throw new RuntimeException(message.toString(), e);
} else { } else {
propagate(e); logger.error(e, exceptionMessage.toString());
assert false : "should have propagated: " + e; throw new RuntimeException(exceptionMessage.toString(), e);
return null;
} }
} }
@ -136,8 +145,7 @@ public class ParseSax<T> implements Function<HttpResponse, T>, InvocationContext
} }
/** /**
* Handler that produces a useable domain object accessible after parsing * Handler that produces a useable domain object accessible after parsing completes.
* completes.
* *
* @author Adrian Cole * @author Adrian Cole
*/ */

View File

@ -85,11 +85,11 @@ public class JavaUrlHttpCommandExecutorService extends BaseHttpCommandExecutorSe
@Inject @Inject
public JavaUrlHttpCommandExecutorService(HttpUtils utils, public JavaUrlHttpCommandExecutorService(HttpUtils utils,
@Named(Constants.PROPERTY_IO_WORKER_THREADS) ExecutorService ioWorkerExecutor, @Named(Constants.PROPERTY_IO_WORKER_THREADS) ExecutorService ioWorkerExecutor,
DelegatingRetryHandler retryHandler, IOExceptionRetryHandler ioRetryHandler, DelegatingRetryHandler retryHandler, IOExceptionRetryHandler ioRetryHandler,
DelegatingErrorHandler errorHandler, HttpWire wire, @Named("untrusted") HostnameVerifier verifier, DelegatingErrorHandler errorHandler, HttpWire wire, @Named("untrusted") HostnameVerifier verifier,
@Named("untrusted") Supplier<SSLContext> untrustedSSLContextProvider) throws SecurityException, @Named("untrusted") Supplier<SSLContext> untrustedSSLContextProvider) throws SecurityException,
NoSuchFieldException { NoSuchFieldException {
super(utils, ioWorkerExecutor, retryHandler, ioRetryHandler, errorHandler, wire); super(utils, ioWorkerExecutor, retryHandler, ioRetryHandler, errorHandler, wire);
if (utils.getMaxConnections() > 0) if (utils.getMaxConnections() > 0)
System.setProperty("http.maxConnections", String.valueOf(checkNotNull(utils, "utils").getMaxConnections())); System.setProperty("http.maxConnections", String.valueOf(checkNotNull(utils, "utils").getMaxConnections()));
@ -218,21 +218,23 @@ public class JavaUrlHttpCommandExecutorService extends BaseHttpCommandExecutorSe
} }
// writeTo will close the output stream // writeTo will close the output stream
try { try {
request.getPayload().writeTo(connection.getOutputStream()); request.getPayload().writeTo(connection.getOutputStream());
} catch (IOException e){ } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
throw e; throw e;
} }
} else { } else {
connection.setRequestProperty(HttpHeaders.CONTENT_LENGTH, "0"); connection.setRequestProperty(HttpHeaders.CONTENT_LENGTH, "0");
// for some reason POST/PUT undoes the content length header above.
if (connection.getRequestMethod().equals("POST") || connection.getRequestMethod().equals("PUT"))
connection.setChunkedStreamingMode(0);
} }
return connection; return connection;
} }
/** /**
* Only disconnect if there is no content, as disconnecting will throw away * Only disconnect if there is no content, as disconnecting will throw away unconsumed content.
* unconsumed content.
*/ */
@Override @Override
protected void cleanup(HttpURLConnection connection) { protected void cleanup(HttpURLConnection connection) {

View File

@ -95,7 +95,7 @@ public abstract class Wire {
out = new FileBackedOutputStream(limit); out = new FileBackedOutputStream(limit);
long bytesRead = ByteStreams.copy(instream, out); long bytesRead = ByteStreams.copy(instream, out);
if (bytesRead >= limit) if (bytesRead >= limit)
logger.warn("over limit %d/%d: wrote temp file", bytesRead, limit); logger.debug("over limit %d/%d: wrote temp file", bytesRead, limit);
wire(header, out.getSupplier().getInput()); wire(header, out.getSupplier().getInput());
return out.getSupplier().getInput(); return out.getSupplier().getInput();
} catch (IOException e) { } catch (IOException e) {

View File

@ -17,7 +17,7 @@
* ==================================================================== * ====================================================================
*/ */
package org.jclouds.ssh.jsch.predicates; package org.jclouds.predicates;
import java.io.IOException; import java.io.IOException;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
@ -29,7 +29,6 @@ import javax.inject.Singleton;
import org.jclouds.logging.Logger; import org.jclouds.logging.Logger;
import org.jclouds.net.IPSocket; import org.jclouds.net.IPSocket;
import org.jclouds.predicates.SocketOpen;
import com.google.inject.Inject; import com.google.inject.Inject;

View File

@ -47,10 +47,10 @@ import java.util.Comparator;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import java.util.Properties; import java.util.Properties;
import java.util.Set; import java.util.Set;
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;
@ -58,6 +58,8 @@ import javax.annotation.Nullable;
import javax.annotation.Resource; import javax.annotation.Resource;
import org.jclouds.PropertiesBuilder; import org.jclouds.PropertiesBuilder;
import org.jclouds.crypto.Pems;
import org.jclouds.domain.Credentials;
import org.jclouds.logging.Logger; import org.jclouds.logging.Logger;
import org.jclouds.rest.AuthorizationException; import org.jclouds.rest.AuthorizationException;
import org.jclouds.rest.RestContextBuilder; import org.jclouds.rest.RestContextBuilder;
@ -246,15 +248,14 @@ public class Utils {
} }
/** /**
* Encode the given string with the given encoding, if possible. If the * Encode the given string with the given encoding, if possible. If the encoding fails with
* encoding fails with {@link UnsupportedEncodingException}, log a warning * {@link UnsupportedEncodingException}, log a warning and fall back to the system's default
* and fall back to the system's default encoding. * encoding.
* *
* @param str * @param str
* what to encode * what to encode
* @param charsetName * @param charsetName
* the name of a supported {@link java.nio.charset.Charset * the name of a supported {@link java.nio.charset.Charset </code>charset<code>}
* </code>charset<code>}
* @return properly encoded String. * @return properly encoded String.
*/ */
public static byte[] encodeString(String str, String charsetName) { public static byte[] encodeString(String str, String charsetName) {
@ -268,10 +269,9 @@ public class Utils {
} }
/** /**
* Encode the given string with the UTF-8 encoding, the sane default. In the * Encode the given string with the UTF-8 encoding, the sane default. In the very unlikely event
* very unlikely event the encoding fails with * the encoding fails with {@link UnsupportedEncodingException}, log a warning and fall back to
* {@link UnsupportedEncodingException}, log a warning and fall back to the * the system's default encoding.
* system's default encoding.
* *
* @param str * @param str
* what to encode * what to encode
@ -322,8 +322,7 @@ public class Utils {
} }
/** /**
* Will throw an exception if the argument is null or empty. Accepts a custom * Will throw an exception if the argument is null or empty. Accepts a custom error message.
* error message.
* *
* @param nullableString * @param nullableString
* string to verify. Can be null or empty. * string to verify. Can be null or empty.
@ -335,8 +334,8 @@ public class Utils {
} }
/** /**
* Gets a set of supported providers. Idea stolen from pallets * Gets a set of supported providers. Idea stolen from pallets (supported-clouds). Uses
* (supported-clouds). Uses rest.properties to populate the set. * rest.properties to populate the set.
* *
*/ */
public static Iterable<String> getSupportedProviders() { public static Iterable<String> getSupportedProviders() {
@ -344,8 +343,8 @@ public class Utils {
} }
/** /**
* Gets a set of supported providers. Idea stolen from pallets * Gets a set of supported providers. Idea stolen from pallets (supported-clouds). Uses
* (supported-clouds). Uses rest.properties to populate the set. * rest.properties to populate the set.
* *
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@ -468,4 +467,24 @@ public class Utils {
} }
return modules; return modules;
} }
public static boolean isPrivateKeyCredential(Credentials credentials) {
return credentials != null
&& credentials.credential != null
&& (credentials.credential.startsWith(Pems.PRIVATE_PKCS1_MARKER) || credentials.credential
.startsWith(Pems.PRIVATE_PKCS8_MARKER));
}
public static Credentials overrideCredentialsIfSupplied(Credentials defaultCredentials,
@Nullable Credentials overridingCredentials) {
if (overridingCredentials == null)
return defaultCredentials;
String identity = overridingCredentials.identity != null ? overridingCredentials.identity : checkNotNull(
defaultCredentials, "defaultCredentials").identity;
String credential = overridingCredentials.credential != null ? overridingCredentials.credential : checkNotNull(
defaultCredentials, "defaultCredentials").credential;
return new Credentials(identity, credential);
}
} }

View File

@ -32,8 +32,8 @@ import org.testng.annotations.Test;
public class CredentialsTest { public class CredentialsTest {
public void testAzure() { public void testAzure() {
Credentials creds = Credentials.parse(URI Credentials creds = Credentials
.create("compute://identity:Base64==@azureblob/container-hyphen/prefix")); .parse(URI.create("compute://identity:Base64==@azureblob/container-hyphen/prefix"));
assertEquals(creds.identity, "identity"); assertEquals(creds.identity, "identity");
assertEquals(creds.credential, "Base64=="); assertEquals(creds.credential, "Base64==");
} }
@ -46,36 +46,31 @@ public class CredentialsTest {
} }
public void testDollar() { public void testDollar() {
Credentials creds = Credentials.parse(URI Credentials creds = Credentials.parse(URI.create("compute://user%40domain:pa%24sword@hostingdotcom"));
.create("compute://user%40domain:pa%24sword@hostingdotcom"));
assertEquals(creds.identity, "user@domain"); assertEquals(creds.identity, "user@domain");
assertEquals(creds.credential, "pa$sword"); assertEquals(creds.credential, "pa$sword");
} }
public void testTerremark() { public void testTerremark() {
Credentials creds = Credentials.parse(URI Credentials creds = Credentials.parse(URI.create("compute://user%40domain:password@terremark"));
.create("compute://user%40domain:password@terremark"));
assertEquals(creds.identity, "user@domain"); assertEquals(creds.identity, "user@domain");
assertEquals(creds.credential, "password"); assertEquals(creds.credential, "password");
} }
public void testTerremark2() { public void testTerremark2() {
Credentials creds = Credentials.parse(URI Credentials creds = Credentials.parse(URI.create("compute://user%40domain:passw%40rd@terremark"));
.create("compute://user%40domain:passw%40rd@terremark"));
assertEquals(creds.identity, "user@domain"); assertEquals(creds.identity, "user@domain");
assertEquals(creds.credential, "passw@rd"); assertEquals(creds.credential, "passw@rd");
} }
public void testTerremark3() { public void testTerremark3() {
Credentials creds = Credentials.parse(URI Credentials creds = Credentials.parse(URI.create("compute://user%40domain:AbC%21%40943%21@terremark"));
.create("compute://user%40domain:AbC%21%40943%21@terremark"));
assertEquals(creds.identity, "user@domain"); assertEquals(creds.identity, "user@domain");
assertEquals(creds.credential, "AbC!@943!"); assertEquals(creds.credential, "AbC!@943!");
} }
public void testCloudFiles() { public void testCloudFiles() {
Credentials creds = Credentials.parse(URI Credentials creds = Credentials.parse(URI.create("compute://identity:h3c@cloudfiles/container-hyphen/prefix"));
.create("compute://identity:h3c@cloudfiles/container-hyphen/prefix"));
assertEquals(creds.identity, "identity"); assertEquals(creds.identity, "identity");
assertEquals(creds.credential, "h3c"); assertEquals(creds.credential, "h3c");
@ -83,18 +78,22 @@ public class CredentialsTest {
public void testS3() { public void testS3() {
Credentials creds = Credentials Credentials creds = Credentials.parse(URI.create("compute://0AB:aA%2B%2F0@s3/buck-et/prefix"));
.parse(URI.create("compute://0AB:aA%2B%2F0@s3/buck-et/prefix"));
assertEquals(creds.identity, "0AB"); assertEquals(creds.identity, "0AB");
assertEquals(creds.credential, "aA+/0"); assertEquals(creds.credential, "aA+/0");
} }
public void testS3Space() { public void testS3Space() {
Credentials creds = Credentials.parse(URI Credentials creds = Credentials.parse(URI.create("compute://0AB:aA%2B%2F0@s3/buck-et/pre%20fix"));
.create("compute://0AB:aA%2B%2F0@s3/buck-et/pre%20fix"));
assertEquals(creds.identity, "0AB"); assertEquals(creds.identity, "0AB");
assertEquals(creds.credential, "aA+/0"); assertEquals(creds.credential, "aA+/0");
} }
public void testSubClassEquals() {
Credentials creds = new Credentials("user", "pass");
assertEquals(creds, new Credentials("user", "pass") {
});
}
} }

View File

@ -68,7 +68,7 @@ public abstract class BaseHttpErrorHandlerTest {
HttpCommand command = createMock(HttpCommand.class); HttpCommand command = createMock(HttpCommand.class);
HttpRequest request = new HttpRequest(method, uri); HttpRequest request = new HttpRequest(method, uri);
HttpResponse response = new HttpResponse(statusCode, null, Payloads.newStringPayload(content)); HttpResponse response = new HttpResponse(statusCode, message, Payloads.newStringPayload(content));
expect(command.getRequest()).andReturn(request).atLeastOnce(); expect(command.getRequest()).andReturn(request).atLeastOnce();
command.setException(classEq(expected)); command.setException(classEq(expected));

View File

@ -34,6 +34,7 @@ import static org.jclouds.util.Utils.toStringAndClose;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.Enumeration;
import java.util.Map; import java.util.Map;
import java.util.Properties; import java.util.Properties;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
@ -64,6 +65,8 @@ import org.testng.annotations.Optional;
import org.testng.annotations.Parameters; import org.testng.annotations.Parameters;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.Multimap;
import com.google.common.io.InputSupplier; import com.google.common.io.InputSupplier;
import com.google.inject.Injector; import com.google.inject.Injector;
import com.google.inject.Module; import com.google.inject.Module;
@ -94,7 +97,7 @@ public abstract class BaseJettyTest {
Handler server1Handler = new AbstractHandler() { Handler server1Handler = new AbstractHandler() {
public void handle(String target, HttpServletRequest request, HttpServletResponse response, int dispatch) public void handle(String target, HttpServletRequest request, HttpServletResponse response, int dispatch)
throws IOException, ServletException { throws IOException, ServletException {
if (failIfNoContentLength(request, response)) { if (failIfNoContentLength(request, response)) {
return; return;
} else if (target.indexOf("sleep") > 0) { } else if (target.indexOf("sleep") > 0) {
@ -138,8 +141,7 @@ public abstract class BaseJettyTest {
response.getWriter().println("test"); response.getWriter().println("test");
} else if (request.getMethod().equals("HEAD")) { } else if (request.getMethod().equals("HEAD")) {
/* /*
* NOTE: by HTML specification, HEAD response MUST NOT include a * NOTE: by HTML specification, HEAD response MUST NOT include a body
* body
*/ */
response.setContentType("text/xml"); response.setContentType("text/xml");
response.setStatus(HttpServletResponse.SC_OK); response.setStatus(HttpServletResponse.SC_OK);
@ -185,7 +187,7 @@ public abstract class BaseJettyTest {
} }
} else { } else {
for (String header : new String[] { "Content-Disposition", HttpHeaders.CONTENT_LANGUAGE, for (String header : new String[] { "Content-Disposition", HttpHeaders.CONTENT_LANGUAGE,
HttpHeaders.CONTENT_ENCODING }) HttpHeaders.CONTENT_ENCODING })
if (request.getHeader(header) != null) { if (request.getHeader(header) != null) {
response.addHeader("x-" + header, request.getHeader(header)); response.addHeader("x-" + header, request.getHeader(header));
} }
@ -206,7 +208,7 @@ public abstract class BaseJettyTest {
protected void setupAndStartSSLServer(final int testPort) throws Exception { protected void setupAndStartSSLServer(final int testPort) throws Exception {
Handler server2Handler = new AbstractHandler() { Handler server2Handler = new AbstractHandler() {
public void handle(String target, HttpServletRequest request, HttpServletResponse response, int dispatch) public void handle(String target, HttpServletRequest request, HttpServletResponse response, int dispatch)
throws IOException, ServletException { throws IOException, ServletException {
if (request.getMethod().equals("PUT")) { if (request.getMethod().equals("PUT")) {
if (request.getContentLength() > 0) { if (request.getContentLength() > 0) {
response.setStatus(HttpServletResponse.SC_OK); response.setStatus(HttpServletResponse.SC_OK);
@ -220,8 +222,7 @@ public abstract class BaseJettyTest {
} }
} else if (request.getMethod().equals("HEAD")) { } else if (request.getMethod().equals("HEAD")) {
/* /*
* NOTE: by HTML specification, HEAD response MUST NOT include a * NOTE: by HTML specification, HEAD response MUST NOT include a body
* body
*/ */
response.setContentType("text/xml"); response.setContentType("text/xml");
response.setStatus(HttpServletResponse.SC_OK); response.setStatus(HttpServletResponse.SC_OK);
@ -261,12 +262,12 @@ public abstract class BaseJettyTest {
} }
public static RestContextBuilder<IntegrationTestClient, IntegrationTestAsyncClient> newBuilder(int testPort, public static RestContextBuilder<IntegrationTestClient, IntegrationTestAsyncClient> newBuilder(int testPort,
Properties properties, Module... connectionModules) { Properties properties, Module... connectionModules) {
properties.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true"); properties.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
properties.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true"); properties.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true");
RestContextSpec<IntegrationTestClient, IntegrationTestAsyncClient> contextSpec = contextSpec("test", RestContextSpec<IntegrationTestClient, IntegrationTestAsyncClient> contextSpec = contextSpec("test",
"http://localhost:" + testPort, "1", "identity", null, IntegrationTestClient.class, "http://localhost:" + testPort, "1", "identity", null, IntegrationTestClient.class,
IntegrationTestAsyncClient.class, ImmutableSet.<Module> copyOf(connectionModules)); IntegrationTestAsyncClient.class, ImmutableSet.<Module> copyOf(connectionModules));
return createContextBuilder(contextSpec, properties); return createContextBuilder(contextSpec, properties);
} }
@ -300,7 +301,7 @@ public abstract class BaseJettyTest {
} }
protected boolean redirectEveryTwentyRequests(HttpServletRequest request, HttpServletResponse response) protected boolean redirectEveryTwentyRequests(HttpServletRequest request, HttpServletResponse response)
throws IOException { throws IOException {
if (cycle.incrementAndGet() % 20 == 0) { if (cycle.incrementAndGet() % 20 == 0) {
response.sendRedirect("http://localhost:" + (testPort + 1) + "/"); response.sendRedirect("http://localhost:" + (testPort + 1) + "/");
((Request) request).setHandled(true); ((Request) request).setHandled(true);
@ -309,8 +310,20 @@ public abstract class BaseJettyTest {
return false; return false;
} }
@SuppressWarnings("unchecked")
protected boolean failIfNoContentLength(HttpServletRequest request, HttpServletResponse response) throws IOException { protected boolean failIfNoContentLength(HttpServletRequest request, HttpServletResponse response) throws IOException {
if (request.getHeader(CONTENT_LENGTH) == null) { Multimap<String, String> realHeaders = LinkedHashMultimap.create();
Enumeration headers = request.getHeaderNames();
while (headers.hasMoreElements()) {
String header = headers.nextElement().toString();
Enumeration values = request.getHeaders(header);
while (values.hasMoreElements()) {
realHeaders.put(header, values.nextElement().toString());
}
}
if (realHeaders.get(CONTENT_LENGTH) == null) {
response.getWriter().println("no content length!");
response.getWriter().println(realHeaders.toString());
response.sendError(500); response.sendError(500);
((Request) request).setHandled(true); ((Request) request).setHandled(true);
return true; return true;

View File

@ -25,6 +25,7 @@ import static org.testng.Assert.assertEquals;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
import org.jclouds.domain.Credentials;
import org.jclouds.rest.AuthorizationException; import org.jclouds.rest.AuthorizationException;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -42,6 +43,33 @@ import com.google.inject.spi.Message;
@Test(groups = "unit", testName = "jclouds.UtilsTest") @Test(groups = "unit", testName = "jclouds.UtilsTest")
public class UtilsTest { public class UtilsTest {
public void testOverridingCredentialsWhenOverridingIsNull() {
Credentials defaultCredentials = new Credentials("foo", "bar");
Credentials overridingCredentials = null;
assertEquals(Utils.overrideCredentialsIfSupplied(defaultCredentials, overridingCredentials), defaultCredentials);
}
public void testOverridingCredentialsWhenOverridingLoginIsNull() {
Credentials defaultCredentials = new Credentials("foo", "bar");
Credentials overridingCredentials = new Credentials(null, "baz");
assertEquals(Utils.overrideCredentialsIfSupplied(defaultCredentials, overridingCredentials), new Credentials(
"foo", "baz"));
}
public void testOverridingCredentialsWhenOverridingCredentialIsNull() {
Credentials defaultCredentials = new Credentials("foo", "bar");
Credentials overridingCredentials = new Credentials("fooble", null);
assertEquals(Utils.overrideCredentialsIfSupplied(defaultCredentials, overridingCredentials), new Credentials(
"fooble", "bar"));
}
public void testOverridingCredentialsWhenOverridingCredentialsAreNull() {
Credentials defaultCredentials = new Credentials("foo", "bar");
Credentials overridingCredentials = new Credentials(null, null);
assertEquals(Utils.overrideCredentialsIfSupplied(defaultCredentials, overridingCredentials), new Credentials(
"foo", "bar"));
}
public void testGetCause() { public void testGetCause() {
AuthorizationException aex = createMock(AuthorizationException.class); AuthorizationException aex = createMock(AuthorizationException.class);
Message message = new Message(ImmutableList.of(), "test", aex); Message message = new Message(ImmutableList.of(), "test", aex);

View File

@ -19,16 +19,19 @@
package org.jclouds.ssh.jsch.config; package org.jclouds.ssh.jsch.config;
import static org.jclouds.util.Utils.isPrivateKeyCredential;
import javax.inject.Named; import javax.inject.Named;
import org.jclouds.Constants; import org.jclouds.Constants;
import org.jclouds.domain.Credentials;
import org.jclouds.http.handlers.BackoffLimitedRetryHandler; import org.jclouds.http.handlers.BackoffLimitedRetryHandler;
import org.jclouds.net.IPSocket; import org.jclouds.net.IPSocket;
import org.jclouds.predicates.InetSocketAddressConnect;
import org.jclouds.predicates.SocketOpen; import org.jclouds.predicates.SocketOpen;
import org.jclouds.ssh.ConfiguresSshClient; import org.jclouds.ssh.ConfiguresSshClient;
import org.jclouds.ssh.SshClient; import org.jclouds.ssh.SshClient;
import org.jclouds.ssh.jsch.JschSshClient; import org.jclouds.ssh.jsch.JschSshClient;
import org.jclouds.ssh.jsch.predicates.InetSocketAddressConnect;
import com.google.inject.AbstractModule; import com.google.inject.AbstractModule;
import com.google.inject.Inject; import com.google.inject.Inject;
@ -74,5 +77,10 @@ public class JschSshClientModule extends AbstractModule {
return client; return client;
} }
@Override
public SshClient create(IPSocket socket, Credentials credentials) {
return isPrivateKeyCredential(credentials) ? create(socket, credentials.identity,
credentials.credential.getBytes()) : create(socket, credentials.identity, credentials.credential);
}
} }
} }

View File

@ -26,6 +26,7 @@ import java.io.FileInputStream;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import org.jclouds.domain.Credentials;
import org.jclouds.io.Payload; import org.jclouds.io.Payload;
import org.jclouds.io.Payloads; import org.jclouds.io.Payloads;
import org.jclouds.net.IPSocket; import org.jclouds.net.IPSocket;
@ -101,7 +102,7 @@ public class JschSshClientLiveTest {
@Override @Override
public void put(String path, String contents) { public void put(String path, String contents) {
} }
}; };
@ -110,10 +111,10 @@ public class JschSshClientLiveTest {
SshClient.Factory factory = i.getInstance(SshClient.Factory.class); SshClient.Factory factory = i.getInstance(SshClient.Factory.class);
SshClient connection; SshClient connection;
if (sshKeyFile != null && !sshKeyFile.trim().equals("")) { if (sshKeyFile != null && !sshKeyFile.trim().equals("")) {
connection = factory.create(new IPSocket(sshHost, port), sshUser, Utils.toStringAndClose( connection = factory.create(new IPSocket(sshHost, port),
new FileInputStream(sshKeyFile)).getBytes()); new Credentials(sshUser, Utils.toStringAndClose(new FileInputStream(sshKeyFile))));
} else { } else {
connection = factory.create(new IPSocket(sshHost, port), sshUser, sshPass); connection = factory.create(new IPSocket(sshHost, port), new Credentials(sshUser, sshPass));
} }
connection.connect(); connection.connect();
return connection; return connection;

View File

@ -23,6 +23,7 @@ import java.io.IOException;
import java.net.ConnectException; import java.net.ConnectException;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import org.jclouds.domain.Credentials;
import org.jclouds.net.IPSocket; import org.jclouds.net.IPSocket;
import org.jclouds.ssh.SshClient; import org.jclouds.ssh.SshClient;
import org.jclouds.ssh.jsch.config.JschSshClientModule; import org.jclouds.ssh.jsch.config.JschSshClientModule;
@ -51,8 +52,8 @@ public class JschSshClientTest {
protected JschSshClient createClient() throws UnknownHostException { protected JschSshClient createClient() throws UnknownHostException {
Injector i = Guice.createInjector(module()); Injector i = Guice.createInjector(module());
SshClient.Factory factory = i.getInstance(SshClient.Factory.class); SshClient.Factory factory = i.getInstance(SshClient.Factory.class);
JschSshClient ssh = JschSshClient.class.cast(factory.create(new IPSocket("localhost", 22), JschSshClient ssh = JschSshClient.class.cast(factory.create(new IPSocket("localhost", 22), new Credentials(
"username", "password")); "username", "password")));
return ssh; return ssh;
} }
@ -68,10 +69,8 @@ public class JschSshClientTest {
} }
public void testExceptionMessagesRetry() { public void testExceptionMessagesRetry() {
assert ssh.shouldRetry(new JSchException( assert ssh.shouldRetry(new JSchException("Session.connect: java.io.IOException: End of IO Stream Read"));
"Session.connect: java.io.IOException: End of IO Stream Read"));
assert ssh.shouldRetry(new JSchException("Session.connect: invalid data")); assert ssh.shouldRetry(new JSchException("Session.connect: invalid data"));
assert ssh.shouldRetry(new JSchException( assert ssh.shouldRetry(new JSchException("Session.connect: java.net.SocketException: Connection reset"));
"Session.connect: java.net.SocketException: Connection reset"));
} }
} }

View File

@ -21,6 +21,7 @@ package org.jclouds.ssh.jsch.config;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import org.jclouds.domain.Credentials;
import org.jclouds.net.IPSocket; import org.jclouds.net.IPSocket;
import org.jclouds.ssh.SshClient; import org.jclouds.ssh.SshClient;
import org.jclouds.ssh.jsch.JschSshClient; import org.jclouds.ssh.jsch.JschSshClient;
@ -41,7 +42,7 @@ public class JschSshClientModuleTest {
Injector i = Guice.createInjector(new JschSshClientModule()); Injector i = Guice.createInjector(new JschSshClientModule());
SshClient.Factory factory = i.getInstance(SshClient.Factory.class); SshClient.Factory factory = i.getInstance(SshClient.Factory.class);
SshClient connection = factory.create(new IPSocket("localhost", 22), "username", "password"); SshClient connection = factory.create(new IPSocket("localhost", 22), new Credentials("username", "password"));
assert connection instanceof JschSshClient; assert connection instanceof JschSshClient;
} }
} }

View File

@ -25,11 +25,13 @@ import org.jclouds.compute.strategy.DestroyNodeStrategy;
import org.jclouds.compute.strategy.GetNodeMetadataStrategy; import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
import org.jclouds.compute.strategy.ListNodesStrategy; 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.SuspendNodeStrategy;
import org.jclouds.gogrid.compute.strategy.GoGridAddNodeWithTagStrategy; import org.jclouds.gogrid.compute.strategy.GoGridAddNodeWithTagStrategy;
import org.jclouds.gogrid.compute.strategy.GoGridDestroyNodeStrategy; import org.jclouds.gogrid.compute.strategy.GoGridDestroyNodeStrategy;
import org.jclouds.gogrid.compute.strategy.GoGridGetNodeMetadataStrategy; import org.jclouds.gogrid.compute.strategy.GoGridGetNodeMetadataStrategy;
import org.jclouds.gogrid.compute.strategy.GoGridLifeCycleStrategy;
import org.jclouds.gogrid.compute.strategy.GoGridListNodesStrategy; import org.jclouds.gogrid.compute.strategy.GoGridListNodesStrategy;
import org.jclouds.gogrid.compute.strategy.GoGridRebootNodeStrategy;
/** /**
* *
@ -59,6 +61,16 @@ public class GoGridBindComputeStrategiesByClass extends BindComputeStrategiesByC
@Override @Override
protected Class<? extends RebootNodeStrategy> defineRebootNodeStrategy() { protected Class<? extends RebootNodeStrategy> defineRebootNodeStrategy() {
return GoGridRebootNodeStrategy.class; return GoGridLifeCycleStrategy.class;
}
@Override
protected Class<? extends ResumeNodeStrategy> defineStartNodeStrategy() {
return GoGridLifeCycleStrategy.class;
}
@Override
protected Class<? extends SuspendNodeStrategy> defineStopNodeStrategy() {
return GoGridLifeCycleStrategy.class;
} }
} }

View File

@ -26,6 +26,8 @@ import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.reference.ComputeServiceConstants.Timeouts; import org.jclouds.compute.reference.ComputeServiceConstants.Timeouts;
import org.jclouds.compute.strategy.GetNodeMetadataStrategy; import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
import org.jclouds.compute.strategy.RebootNodeStrategy; import org.jclouds.compute.strategy.RebootNodeStrategy;
import org.jclouds.compute.strategy.ResumeNodeStrategy;
import org.jclouds.compute.strategy.SuspendNodeStrategy;
import org.jclouds.gogrid.GoGridClient; import org.jclouds.gogrid.GoGridClient;
import org.jclouds.gogrid.domain.PowerCommand; import org.jclouds.gogrid.domain.PowerCommand;
import org.jclouds.gogrid.domain.Server; import org.jclouds.gogrid.domain.Server;
@ -39,14 +41,14 @@ import com.google.common.collect.Iterables;
* @author Adrian Cole * @author Adrian Cole
*/ */
@Singleton @Singleton
public class GoGridRebootNodeStrategy implements RebootNodeStrategy { public class GoGridLifeCycleStrategy implements RebootNodeStrategy, ResumeNodeStrategy, SuspendNodeStrategy {
private final GoGridClient client; private final GoGridClient client;
private final RetryablePredicate<Server> serverLatestJobCompleted; private final RetryablePredicate<Server> serverLatestJobCompleted;
private final RetryablePredicate<Server> serverLatestJobCompletedShort; private final RetryablePredicate<Server> serverLatestJobCompletedShort;
private final GetNodeMetadataStrategy getNode; private final GetNodeMetadataStrategy getNode;
@Inject @Inject
protected GoGridRebootNodeStrategy(GoGridClient client, GetNodeMetadataStrategy getNode, Timeouts timeouts) { protected GoGridLifeCycleStrategy(GoGridClient client, GetNodeMetadataStrategy getNode, Timeouts timeouts) {
this.client = client; this.client = client;
this.serverLatestJobCompleted = new RetryablePredicate<Server>(new ServerLatestJobCompleted(client this.serverLatestJobCompleted = new RetryablePredicate<Server>(new ServerLatestJobCompleted(client
.getJobServices()), timeouts.nodeRunning * 9l / 10l); .getJobServices()), timeouts.nodeRunning * 9l / 10l);
@ -57,11 +59,30 @@ public class GoGridRebootNodeStrategy implements RebootNodeStrategy {
@Override @Override
public NodeMetadata rebootNode(String id) { public NodeMetadata rebootNode(String id) {
executeCommandOnServer(PowerCommand.RESTART, id);
Server server = Iterables.getOnlyElement(client.getServerServices().getServersById(new Long(id))); Server server = Iterables.getOnlyElement(client.getServerServices().getServersById(new Long(id)));
client.getServerServices().power(server.getName(), PowerCommand.RESTART);
serverLatestJobCompleted.apply(server);
client.getServerServices().power(server.getName(), PowerCommand.START); client.getServerServices().power(server.getName(), PowerCommand.START);
serverLatestJobCompletedShort.apply(server); serverLatestJobCompletedShort.apply(server);
return getNode.getNode(id); return getNode.getNode(id);
} }
@Override
public NodeMetadata resumeNode(String id) {
executeCommandOnServer(PowerCommand.START, id);
return getNode.getNode(id);
}
@Override
public NodeMetadata suspendNode(String id) {
executeCommandOnServer(PowerCommand.STOP, id);
return getNode.getNode(id);
}
private boolean executeCommandOnServer(PowerCommand command, String id) {
Server server = Iterables.getOnlyElement(client.getServerServices().getServersById(new Long(id)));
client.getServerServices().power(server.getName(), command);
return serverLatestJobCompleted.apply(server);
}
} }

View File

@ -20,6 +20,7 @@
package org.jclouds.gogrid.compute.suppliers; package org.jclouds.gogrid.compute.suppliers;
import java.util.Set; import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import javax.annotation.Resource; import javax.annotation.Resource;
@ -35,7 +36,6 @@ import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.compute.strategy.PopulateDefaultLoginCredentialsForImageStrategy; import org.jclouds.compute.strategy.PopulateDefaultLoginCredentialsForImageStrategy;
import org.jclouds.gogrid.GoGridClient; import org.jclouds.gogrid.GoGridClient;
import org.jclouds.gogrid.domain.ServerImage; import org.jclouds.gogrid.domain.ServerImage;
import org.jclouds.gogrid.util.GoGridUtils;
import org.jclouds.logging.Logger; import org.jclouds.logging.Logger;
import com.google.common.base.Supplier; import com.google.common.base.Supplier;
@ -47,7 +47,8 @@ import com.google.common.collect.Sets;
*/ */
@Singleton @Singleton
public class GoGridImageSupplier implements Supplier<Set<? extends Image>> { public class GoGridImageSupplier implements Supplier<Set<? extends Image>> {
public static final Pattern GOGRID_OS_NAME_PATTERN = Pattern.compile("([a-zA-Z]*)(.*)"); public static final Pattern GOGRID_OS_PATTERN = Pattern.compile("([a-zA-Z]*).*");
public static final Pattern GOGRID_VERSION_PATTERN = Pattern.compile(".* ([0-9.]+) .*");
@Resource @Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER) @Named(ComputeServiceConstants.COMPUTE_LOGGER)
@ -84,18 +85,29 @@ public class GoGridImageSupplier implements Supplier<Set<? extends Image>> {
OsFamily osFamily = null; OsFamily osFamily = null;
String osName = from.getOs().getName(); String osName = from.getOs().getName();
String osArch = from.getArchitecture().getDescription(); String osArch = from.getArchitecture().getDescription();
String osVersion = null;// TODO String osVersion = parseVersion(osName);
String osDescription = from.getOs().getDescription(); String osDescription = from.getOs().getDescription();
boolean is64Bit = (from.getOs().getName().indexOf("64") != -1 || from.getDescription().indexOf("64") != -1); boolean is64Bit = (from.getOs().getName().indexOf("64") != -1 || from.getDescription().indexOf("64") != -1);
String matchedOs = GoGridUtils.parseStringByPatternAndGetNthMatchGroup(osName, GOGRID_OS_NAME_PATTERN, 1); Matcher matcher = GOGRID_OS_PATTERN.matcher(from.getName());
try { if (matcher.find()) {
osFamily = OsFamily.fromValue(matchedOs.toLowerCase()); try {
} catch (IllegalArgumentException e) { osFamily = OsFamily.fromValue(matcher.group(1).toLowerCase());
logger.debug("<< didn't match os(%s)", matchedOs); } catch (IllegalArgumentException e) {
logger.debug("<< didn't match os(%s)", from.getName());
}
} }
// TODO determine DC images are in // TODO determine DC images are in
OperatingSystem os = new OperatingSystem(osFamily, osName, osVersion, osArch, osDescription, is64Bit); OperatingSystem os = new OperatingSystem(osFamily, osName, osVersion, osArch, osDescription, is64Bit);
return os; return os;
} }
static String parseVersion(String name) {
Matcher matcher = GOGRID_VERSION_PATTERN.matcher(name);
if (matcher.find()) {
return matcher.group(1);
}
return null;
}
} }

View File

@ -59,11 +59,11 @@ import org.jclouds.gogrid.predicates.ServerLatestJobCompleted;
import org.jclouds.http.handlers.BackoffLimitedRetryHandler; import org.jclouds.http.handlers.BackoffLimitedRetryHandler;
import org.jclouds.logging.log4j.config.Log4JLoggingModule; import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.net.IPSocket; import org.jclouds.net.IPSocket;
import org.jclouds.predicates.InetSocketAddressConnect;
import org.jclouds.predicates.RetryablePredicate; import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.rest.RestContext; import org.jclouds.rest.RestContext;
import org.jclouds.ssh.SshClient; import org.jclouds.ssh.SshClient;
import org.jclouds.ssh.jsch.JschSshClient; import org.jclouds.ssh.jsch.JschSshClient;
import org.jclouds.ssh.jsch.predicates.InetSocketAddressConnect;
import org.testng.SkipException; import org.testng.SkipException;
import org.testng.TestException; import org.testng.TestException;
import org.testng.annotations.AfterTest; import org.testng.annotations.AfterTest;
@ -82,7 +82,7 @@ import com.google.inject.Module;
* *
* @author Oleksiy Yarmula * @author Oleksiy Yarmula
*/ */
@Test(enabled = false, groups = "live", testName = "gogrid.GoGridLiveTest") @Test(enabled = true, groups = "live", testName = "gogrid.GoGridLiveTest")
public class GoGridLiveTestDisabled { public class GoGridLiveTestDisabled {
private GoGridClient client; private GoGridClient client;

View File

@ -45,6 +45,7 @@ public class GoGridComputeServiceLiveTest extends BaseComputeServiceLiveTest {
public void testTemplateBuilder() { public void testTemplateBuilder() {
Template defaultTemplate = client.templateBuilder().build(); Template defaultTemplate = client.templateBuilder().build();
assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true); assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true);
assertEquals(defaultTemplate.getImage().getOperatingSystem().getVersion(), "5.3");
assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.CENTOS); assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.CENTOS);
assertEquals(defaultTemplate.getLocation().getId(), "1"); assertEquals(defaultTemplate.getLocation().getId(), "1");
assertEquals(getCores(defaultTemplate.getHardware()), 0.5d); assertEquals(getCores(defaultTemplate.getHardware()), 0.5d);

View File

@ -0,0 +1,37 @@
/**
*
* 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.gogrid.compute.suppliers;
import static org.testng.Assert.assertEquals;
import org.testng.annotations.Test;
/**
*
* @author Adrian Cole
*/
public class GoGridImageSupplierTest {
@Test
public void testParseVersion() {
assertEquals(GoGridImageSupplier.parseVersion("CentOS 5.3 (64-bit)"), "5.3");
}
}

View File

@ -300,7 +300,7 @@
<testSourceDirectories> <testSourceDirectories>
<testSourceDirectory>src/test/clojure</testSourceDirectory> <testSourceDirectory>src/test/clojure</testSourceDirectory>
</testSourceDirectories> </testSourceDirectories>
<clojureOptions>-Xmx512m -Djava.awt.headless=true -XX:MaxPermSize=256m</clojureOptions> <clojureOptions>-Xmx512m -Djava.awt.headless=true -XX:MaxPermSize=256m -Xss256k</clojureOptions>
<warnOnReflection>true</warnOnReflection> <warnOnReflection>true</warnOnReflection>
<compileDeclaredNamespaceOnly>true</compileDeclaredNamespaceOnly> <compileDeclaredNamespaceOnly>true</compileDeclaredNamespaceOnly>
<testDeclaredNamespaceOnly>false</testDeclaredNamespaceOnly> <testDeclaredNamespaceOnly>false</testDeclaredNamespaceOnly>
@ -326,7 +326,7 @@
<goal>test</goal> <goal>test</goal>
</goals> </goals>
<configuration> <configuration>
<argLine>-Xmx512m -Xms256m -Xss128k</argLine> <argLine>-Xmx512m -Xms256m -Djava.awt.headless=true -XX:MaxPermSize=256m -Xss256k</argLine>
<parallel>tests</parallel> <parallel>tests</parallel>
<threadCount>5</threadCount> <threadCount>5</threadCount>
<!-- note that the groups/excluded groups don't work due to some problem <!-- note that the groups/excluded groups don't work due to some problem

View File

@ -25,11 +25,13 @@ import org.jclouds.compute.strategy.DestroyNodeStrategy;
import org.jclouds.compute.strategy.GetNodeMetadataStrategy; import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
import org.jclouds.compute.strategy.ListNodesStrategy; 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.SuspendNodeStrategy;
import org.jclouds.rackspace.cloudservers.compute.strategy.CloudServersAddNodeWithTagStrategy; import org.jclouds.rackspace.cloudservers.compute.strategy.CloudServersAddNodeWithTagStrategy;
import org.jclouds.rackspace.cloudservers.compute.strategy.CloudServersDestroyNodeStrategy; import org.jclouds.rackspace.cloudservers.compute.strategy.CloudServersDestroyNodeStrategy;
import org.jclouds.rackspace.cloudservers.compute.strategy.CloudServersGetNodeMetadataStrategy; import org.jclouds.rackspace.cloudservers.compute.strategy.CloudServersGetNodeMetadataStrategy;
import org.jclouds.rackspace.cloudservers.compute.strategy.CloudServersListNodesStrategy; import org.jclouds.rackspace.cloudservers.compute.strategy.CloudServersListNodesStrategy;
import org.jclouds.rackspace.cloudservers.compute.strategy.CloudServersRebootNodeStrategy; import org.jclouds.rackspace.cloudservers.compute.strategy.CloudServersLifeCycleStrategy;
/** /**
* *
@ -60,6 +62,16 @@ public class CloudServersBindComputeStrategiesByClass extends BindComputeStrateg
@Override @Override
protected Class<? extends RebootNodeStrategy> defineRebootNodeStrategy() { protected Class<? extends RebootNodeStrategy> defineRebootNodeStrategy() {
return CloudServersRebootNodeStrategy.class; return CloudServersLifeCycleStrategy.class;
}
@Override
protected Class<? extends ResumeNodeStrategy> defineStartNodeStrategy() {
return CloudServersLifeCycleStrategy.class;
}
@Override
protected Class<? extends SuspendNodeStrategy> defineStopNodeStrategy() {
return CloudServersLifeCycleStrategy.class;
} }
} }

View File

@ -40,7 +40,7 @@ import com.google.common.base.Function;
@Singleton @Singleton
public class CloudServersImageToOperatingSystem implements public class CloudServersImageToOperatingSystem implements
Function<org.jclouds.rackspace.cloudservers.domain.Image, OperatingSystem> { Function<org.jclouds.rackspace.cloudservers.domain.Image, OperatingSystem> {
public static final Pattern RACKSPACE_PATTERN = Pattern.compile("(([^ ]*) .*)"); public static final Pattern RACKSPACE_PATTERN = Pattern.compile("(([^ ]*) ([0-9.]+) ?.*)");
@Resource @Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER) @Named(ComputeServiceConstants.COMPUTE_LOGGER)
@ -58,12 +58,14 @@ public class CloudServersImageToOperatingSystem implements
osFamily = OsFamily.RHEL; osFamily = OsFamily.RHEL;
} else if (from.getName().indexOf("Oracle EL") != -1) { } else if (from.getName().indexOf("Oracle EL") != -1) {
osFamily = OsFamily.OEL; osFamily = OsFamily.OEL;
} else if (matcher.find()) { }
if (matcher.find()) {
try { try {
osFamily = OsFamily.fromValue(matcher.group(2).toLowerCase()); osFamily = OsFamily.fromValue(matcher.group(2).toLowerCase());
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
logger.debug("<< didn't match os(%s)", matcher.group(2)); logger.debug("<< didn't match os(%s)", matcher.group(2));
} }
osVersion = matcher.group(3);
} }
OperatingSystem os = new OperatingSystem(osFamily, osName, osVersion, osArch, osDescription, is64Bit); OperatingSystem os = new OperatingSystem(osFamily, osName, osVersion, osArch, osDescription, is64Bit);
return os; return os;

View File

@ -115,7 +115,7 @@ public class ServerToNodeMetadata implements Function<Server, NodeMetadata> {
builder.state(serverToNodeState.get(from.getStatus())); builder.state(serverToNodeState.get(from.getStatus()));
builder.publicAddresses(from.getAddresses().getPublicAddresses()); builder.publicAddresses(from.getAddresses().getPublicAddresses());
builder.privateAddresses(from.getAddresses().getPrivateAddresses()); builder.privateAddresses(from.getAddresses().getPrivateAddresses());
builder.credentials(credentialStore.get(from.getId() + "")); builder.credentials(credentialStore.get("node#" + from.getId()));
return builder.build(); return builder.build();
} }

View File

@ -46,7 +46,7 @@ public class CloudServersAddNodeWithTagStrategy implements AddNodeWithTagStrateg
@Inject @Inject
protected CloudServersAddNodeWithTagStrategy(CloudServersClient client, Map<String, Credentials> credentialStore, protected CloudServersAddNodeWithTagStrategy(CloudServersClient client, Map<String, Credentials> credentialStore,
Function<Server, NodeMetadata> serverToNodeMetadata) { Function<Server, NodeMetadata> serverToNodeMetadata) {
this.client = checkNotNull(client, "client"); this.client = checkNotNull(client, "client");
this.credentialStore = checkNotNull(credentialStore, "credentialStore"); this.credentialStore = checkNotNull(credentialStore, "credentialStore");
this.serverToNodeMetadata = checkNotNull(serverToNodeMetadata, "serverToNodeMetadata"); this.serverToNodeMetadata = checkNotNull(serverToNodeMetadata, "serverToNodeMetadata");
@ -54,9 +54,9 @@ public class CloudServersAddNodeWithTagStrategy implements AddNodeWithTagStrateg
@Override @Override
public NodeMetadata addNodeWithTag(String tag, String name, Template template) { public NodeMetadata addNodeWithTag(String tag, String name, Template template) {
Server from = client.createServer(name, Integer.parseInt(template.getImage().getProviderId()), Server from = client.createServer(name, Integer.parseInt(template.getImage().getProviderId()), Integer
Integer.parseInt(template.getHardware().getProviderId())); .parseInt(template.getHardware().getProviderId()));
credentialStore.put(from.getId() + "", new Credentials("root", from.getAdminPass())); credentialStore.put("node#" + from.getId(), new Credentials("root", from.getAdminPass()));
return serverToNodeMetadata.apply(from); return serverToNodeMetadata.apply(from);
} }

View File

@ -25,6 +25,8 @@ import javax.inject.Singleton;
import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.strategy.GetNodeMetadataStrategy; import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
import org.jclouds.compute.strategy.RebootNodeStrategy; import org.jclouds.compute.strategy.RebootNodeStrategy;
import org.jclouds.compute.strategy.ResumeNodeStrategy;
import org.jclouds.compute.strategy.SuspendNodeStrategy;
import org.jclouds.rackspace.cloudservers.CloudServersClient; import org.jclouds.rackspace.cloudservers.CloudServersClient;
import org.jclouds.rackspace.cloudservers.domain.RebootType; import org.jclouds.rackspace.cloudservers.domain.RebootType;
@ -32,12 +34,12 @@ import org.jclouds.rackspace.cloudservers.domain.RebootType;
* @author Adrian Cole * @author Adrian Cole
*/ */
@Singleton @Singleton
public class CloudServersRebootNodeStrategy implements RebootNodeStrategy { public class CloudServersLifeCycleStrategy implements RebootNodeStrategy, SuspendNodeStrategy, ResumeNodeStrategy {
private final CloudServersClient client; private final CloudServersClient client;
private final GetNodeMetadataStrategy getNode; private final GetNodeMetadataStrategy getNode;
@Inject @Inject
protected CloudServersRebootNodeStrategy(CloudServersClient client, GetNodeMetadataStrategy getNode) { protected CloudServersLifeCycleStrategy(CloudServersClient client, GetNodeMetadataStrategy getNode) {
this.client = client; this.client = client;
this.getNode = getNode; this.getNode = getNode;
} }
@ -50,4 +52,14 @@ public class CloudServersRebootNodeStrategy implements RebootNodeStrategy {
return getNode.getNode(id); return getNode.getNode(id);
} }
@Override
public NodeMetadata suspendNode(String id) {
throw new UnsupportedOperationException("suspend not supported");
}
@Override
public NodeMetadata resumeNode(String id) {
throw new UnsupportedOperationException("resume not supported");
}
} }

View File

@ -117,7 +117,7 @@ public class RackspaceAuthenticationRestModule extends AbstractModule {
@Provides @Provides
@Singleton @Singleton
@CloudFiles @CloudFiles
protected URI provideStorageUrl(AuthenticationResponse response) { protected URI providestroageUrl(AuthenticationResponse response) {
return response.getStorageUrl(); return response.getStorageUrl();
} }

View File

@ -36,6 +36,7 @@ import java.util.Set;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.jclouds.Constants; import org.jclouds.Constants;
import org.jclouds.domain.Credentials;
import org.jclouds.http.HttpResponseException; import org.jclouds.http.HttpResponseException;
import org.jclouds.io.Payload; import org.jclouds.io.Payload;
import org.jclouds.logging.log4j.config.Log4JLoggingModule; import org.jclouds.logging.log4j.config.Log4JLoggingModule;
@ -407,7 +408,7 @@ public class CloudServersClientLiveTest {
IPSocket socket = new IPSocket(Iterables.get(newDetails.getAddresses().getPublicAddresses(), 0), 22); IPSocket socket = new IPSocket(Iterables.get(newDetails.getAddresses().getPublicAddresses(), 0), 22);
socketTester.apply(socket); socketTester.apply(socket);
SshClient client = sshFactory.create(socket, "root", pass); SshClient client = sshFactory.create(socket, new Credentials("root", pass));
try { try {
client.connect(); client.connect();
Payload etcPasswd = client.get("/etc/jclouds.txt"); Payload etcPasswd = client.get("/etc/jclouds.txt");
@ -422,7 +423,7 @@ public class CloudServersClientLiveTest {
private ExecResponse exec(Server details, String pass, String command) throws IOException { private ExecResponse exec(Server details, String pass, String command) throws IOException {
IPSocket socket = new IPSocket(Iterables.get(details.getAddresses().getPublicAddresses(), 0), 22); IPSocket socket = new IPSocket(Iterables.get(details.getAddresses().getPublicAddresses(), 0), 22);
socketTester.apply(socket); socketTester.apply(socket);
SshClient client = sshFactory.create(socket, "root", pass); SshClient client = sshFactory.create(socket, new Credentials("root", pass));
try { try {
client.connect(); client.connect();
return client.exec(command); return client.exec(command);

View File

@ -52,6 +52,7 @@ public class CloudServersComputeServiceLiveTest extends BaseComputeServiceLiveTe
public void testTemplateBuilder() { public void testTemplateBuilder() {
Template defaultTemplate = client.templateBuilder().build(); Template defaultTemplate = client.templateBuilder().build();
assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true); assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true);
assertEquals(defaultTemplate.getImage().getOperatingSystem().getVersion(), "9.10");
assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.UBUNTU); assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.UBUNTU);
assertEquals(defaultTemplate.getLocation().getId(), "DFW1"); assertEquals(defaultTemplate.getLocation().getId(), "DFW1");
assertEquals(getCores(defaultTemplate.getHardware()), 1.0d); assertEquals(getCores(defaultTemplate.getHardware()), 1.0d);
@ -76,4 +77,9 @@ public class CloudServersComputeServiceLiveTest extends BaseComputeServiceLiveTe
} }
} }
@Test(expectedExceptions = UnsupportedOperationException.class)
public void testSuspendResume() throws Exception {
super.testSuspendResume();
}
} }

View File

@ -44,7 +44,7 @@ public class CloudServersImageToImageTest {
new ImageBuilder() new ImageBuilder()
.name("CentOS 5.2") .name("CentOS 5.2")
.operatingSystem( .operatingSystem(
new OperatingSystemBuilder().family(OsFamily.CENTOS).description("CentOS 5.2").is64Bit(true) new OperatingSystemBuilder().family(OsFamily.CENTOS).version("5.2").description("CentOS 5.2").is64Bit(true)
.build()).description("CentOS 5.2").defaultCredentials(new Credentials("root", null)) .build()).description("CentOS 5.2").defaultCredentials(new Credentials("root", null))
.ids("2").version("1286712000000").build()); .ids("2").version("1286712000000").build());
} }

View File

@ -68,7 +68,7 @@ public class ServerToNodeMetadataTest {
Server server = ParseServerFromJsonResponseTest.parseServer(); Server server = ParseServerFromJsonResponseTest.parseServer();
ServerToNodeMetadata parser = new ServerToNodeMetadata(serverStateToNodeState, ImmutableMap ServerToNodeMetadata parser = new ServerToNodeMetadata(serverStateToNodeState, ImmutableMap
.<String, Credentials> of("1234", creds), Suppliers.<Set<? extends Image>> ofInstance(images), Suppliers .<String, Credentials> of("node#1234", creds), Suppliers.<Set<? extends Image>> ofInstance(images), Suppliers
.ofInstance(provider), Suppliers.<Set<? extends Hardware>> ofInstance(hardwares)); .ofInstance(provider), Suppliers.<Set<? extends Hardware>> ofInstance(hardwares));
NodeMetadata metadata = parser.apply(server); NodeMetadata metadata = parser.apply(server);
@ -123,12 +123,12 @@ public class ServerToNodeMetadataTest {
assertEquals(metadata, new NodeMetadataBuilder().state(NodeState.PENDING).publicAddresses( assertEquals(metadata, new NodeMetadataBuilder().state(NodeState.PENDING).publicAddresses(
ImmutableSet.of("67.23.10.132", "67.23.10.131")).privateAddresses(ImmutableSet.of("10.176.42.16")).tag( ImmutableSet.of("67.23.10.132", "67.23.10.131")).privateAddresses(ImmutableSet.of("10.176.42.16")).tag(
"NOTAG-sample-server").imageId("2").operatingSystem( "NOTAG-sample-server").imageId("2").operatingSystem(
new OperatingSystemBuilder().family(OsFamily.CENTOS).description("CentOS 5.2").is64Bit(true).build()) new OperatingSystemBuilder().family(OsFamily.CENTOS).description("CentOS 5.2").version("5.2").is64Bit(
.id("1234").providerId("1234").name("sample-server").location( true).build()).id("1234").providerId("1234").name("sample-server").location(
new LocationImpl(LocationScope.HOST, "e4d909c290d0fb1ca068ffaddf22cbd0", new LocationImpl(LocationScope.HOST, "e4d909c290d0fb1ca068ffaddf22cbd0",
"e4d909c290d0fb1ca068ffaddf22cbd0", new LocationImpl(LocationScope.ZONE, "dallas", "e4d909c290d0fb1ca068ffaddf22cbd0", new LocationImpl(LocationScope.ZONE, "dallas",
"description", null))).userMetadata( "description", null))).userMetadata(
ImmutableMap.of("Server Label", "Web Head 1", "Image Version", "2.1")).build()); ImmutableMap.of("Server Label", "Web Head 1", "Image Version", "2.1")).build());
} }
@ -152,11 +152,11 @@ public class ServerToNodeMetadataTest {
ImmutableList.of(new Processor(1.0, 1.0))).ram(256).volumes( ImmutableList.of(new Processor(1.0, 1.0))).ram(256).volumes(
ImmutableList.of(new VolumeBuilder().type(Volume.Type.LOCAL).size(10.0f).durable(true) ImmutableList.of(new VolumeBuilder().type(Volume.Type.LOCAL).size(10.0f).durable(true)
.bootDevice(true).build())).build()).operatingSystem( .bootDevice(true).build())).build()).operatingSystem(
new OperatingSystemBuilder().family(OsFamily.CENTOS).description("CentOS 5.2").is64Bit(true).build()) new OperatingSystemBuilder().family(OsFamily.CENTOS).description("CentOS 5.2").version("5.2").is64Bit(
.id("1234").providerId("1234").name("sample-server").location( true).build()).id("1234").providerId("1234").name("sample-server").location(
new LocationImpl(LocationScope.HOST, "e4d909c290d0fb1ca068ffaddf22cbd0", new LocationImpl(LocationScope.HOST, "e4d909c290d0fb1ca068ffaddf22cbd0",
"e4d909c290d0fb1ca068ffaddf22cbd0", new LocationImpl(LocationScope.ZONE, "dallas", "e4d909c290d0fb1ca068ffaddf22cbd0", new LocationImpl(LocationScope.ZONE, "dallas",
"description", null))).userMetadata( "description", null))).userMetadata(
ImmutableMap.of("Server Label", "Web Head 1", "Image Version", "2.1")).build()); ImmutableMap.of("Server Label", "Web Head 1", "Image Version", "2.1")).build());
} }
} }

View File

@ -161,12 +161,12 @@
<category name="jclouds.ssh"> <category name="jclouds.ssh">
<priority value="DEBUG" /> <priority value="DEBUG" />
<appender-ref ref="ASYNCSSH" /> <appender-ref ref="ASYNCSSH" />
</category><!-- </category>
<category name="jclouds.wire"> <category name="jclouds.wire">
<priority value="DEBUG" /> <priority value="DEBUG" />
<appender-ref ref="ASYNCWIRE" /> <appender-ref ref="ASYNCWIRE" />
</category> </category>
--><category name="jclouds.blobstore"> <category name="jclouds.blobstore">
<priority value="DEBUG" /> <priority value="DEBUG" />
<appender-ref ref="ASYNCBLOBSTORE" /> <appender-ref ref="ASYNCBLOBSTORE" />
</category> </category>

View File

@ -139,7 +139,7 @@ public interface RimuHostingAsyncClient {
ListenableFuture<ServerInfo> restartServer(@PathParam("id") Long id); ListenableFuture<ServerInfo> restartServer(@PathParam("id") Long id);
/** /**
* @see RimuHostingClient#destoryServer * @see RimuHostingClient#destroyServer
*/ */
@DELETE @DELETE
@Path("/orders/order-{id}-blah/vps") @Path("/orders/order-{id}-blah/vps")

View File

@ -6,11 +6,13 @@ import org.jclouds.compute.strategy.DestroyNodeStrategy;
import org.jclouds.compute.strategy.GetNodeMetadataStrategy; import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
import org.jclouds.compute.strategy.ListNodesStrategy; 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.SuspendNodeStrategy;
import org.jclouds.rimuhosting.miro.compute.strategy.RimuHostingAddNodeWithTagStrategy; import org.jclouds.rimuhosting.miro.compute.strategy.RimuHostingAddNodeWithTagStrategy;
import org.jclouds.rimuhosting.miro.compute.strategy.RimuHostingDestroyNodeStrategy; import org.jclouds.rimuhosting.miro.compute.strategy.RimuHostingDestroyNodeStrategy;
import org.jclouds.rimuhosting.miro.compute.strategy.RimuHostingGetNodeMetadataStrategy; import org.jclouds.rimuhosting.miro.compute.strategy.RimuHostingGetNodeMetadataStrategy;
import org.jclouds.rimuhosting.miro.compute.strategy.RimuHostingLifeCycleStrategy;
import org.jclouds.rimuhosting.miro.compute.strategy.RimuHostingListNodesStrategy; import org.jclouds.rimuhosting.miro.compute.strategy.RimuHostingListNodesStrategy;
import org.jclouds.rimuhosting.miro.compute.strategy.RimuHostingRebootNodeStrategy;
public class RimuHostingBindComputeStrategiesByClass extends BindComputeStrategiesByClass { public class RimuHostingBindComputeStrategiesByClass extends BindComputeStrategiesByClass {
@Override @Override
@ -35,6 +37,16 @@ public class RimuHostingBindComputeStrategiesByClass extends BindComputeStrategi
@Override @Override
protected Class<? extends RebootNodeStrategy> defineRebootNodeStrategy() { protected Class<? extends RebootNodeStrategy> defineRebootNodeStrategy() {
return RimuHostingRebootNodeStrategy.class; return RimuHostingLifeCycleStrategy.class;
}
@Override
protected Class<? extends ResumeNodeStrategy> defineStartNodeStrategy() {
return RimuHostingLifeCycleStrategy.class;
}
@Override
protected Class<? extends SuspendNodeStrategy> defineStopNodeStrategy() {
return RimuHostingLifeCycleStrategy.class;
} }
} }

View File

@ -45,7 +45,7 @@ public class RimuHostingComputeServiceContextModule extends BaseComputeServiceCo
@Override @Override
protected TemplateBuilder provideTemplate(Injector injector, TemplateBuilder template) { protected TemplateBuilder provideTemplate(Injector injector, TemplateBuilder template) {
return template.hardwareId("MIRO1B").osFamily(UBUNTU).os64Bit(false).imageNameMatches(".*10\\.?04.*"); return template.hardwareId("MIRO1B").osFamily(UBUNTU).os64Bit(false).osVersionMatches("9.10");
} }
} }

View File

@ -105,7 +105,7 @@ public class ServerToNodeMetadata implements Function<Server, NodeMetadata> {
builder.hardware(null);// TODO builder.hardware(null);// TODO
builder.state(runningStateToNodeState.get(from.getState())); builder.state(runningStateToNodeState.get(from.getState()));
builder.publicAddresses(getPublicAddresses.apply(from)); builder.publicAddresses(getPublicAddresses.apply(from));
builder.credentials(credentialStore.get(from.getId() + "")); builder.credentials(credentialStore.get("node#" + from.getId()));
return builder.build(); return builder.build();
} }

Some files were not shown because too many files have changed in this diff Show More