mirror of https://github.com/apache/jclouds.git
Merge remote branch 'origin'
This commit is contained in:
commit
81c954c26c
|
@ -56,6 +56,8 @@ import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
|
|||
import org.jclouds.compute.strategy.ListNodesStrategy;
|
||||
import org.jclouds.compute.strategy.RebootNodeStrategy;
|
||||
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.domain.Credentials;
|
||||
import org.jclouds.domain.Location;
|
||||
|
@ -82,16 +84,19 @@ public class EC2ComputeService extends BaseComputeService {
|
|||
@Memoized Supplier<Set<? extends Location>> locations, ListNodesStrategy listNodesStrategy,
|
||||
GetNodeMetadataStrategy getNodeMetadataStrategy, RunNodesAndAddToSetStrategy runNodesAndAddToSetStrategy,
|
||||
RebootNodeStrategy rebootNodeStrategy, DestroyNodeStrategy destroyNodeStrategy,
|
||||
ResumeNodeStrategy startNodeStrategy, SuspendNodeStrategy stopNodeStrategy,
|
||||
Provider<TemplateBuilder> templateBuilderProvider, Provider<TemplateOptions> templateOptionsProvider,
|
||||
@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,
|
||||
Map<RegionAndName, KeyPair> credentialsMap, @Named("SECURITY") Map<RegionAndName, String> securityGroupMap,
|
||||
@Named("PLACEMENT") Map<RegionAndName, String> placementGroupMap,
|
||||
@Named("DELETED") Predicate<PlacementGroup> placementGroupDeleted) {
|
||||
super(context, credentialStore, images, sizes, locations, listNodesStrategy, getNodeMetadataStrategy,
|
||||
runNodesAndAddToSetStrategy, rebootNodeStrategy, destroyNodeStrategy, templateBuilderProvider,
|
||||
templateOptionsProvider, nodeRunning, nodeTerminated, utils, timeouts, executor);
|
||||
runNodesAndAddToSetStrategy, rebootNodeStrategy, destroyNodeStrategy, startNodeStrategy,
|
||||
stopNodeStrategy, templateBuilderProvider, templateOptionsProvider, nodeRunning, nodeTerminated,
|
||||
nodeSuspended, utils, timeouts, executor);
|
||||
this.ec2Client = ec2Client;
|
||||
this.credentialsMap = credentialsMap;
|
||||
this.securityGroupMap = securityGroupMap;
|
||||
|
|
|
@ -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.EC2RebootNodeStrategy;
|
||||
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.strategy.AddNodeWithTagStrategy;
|
||||
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.RebootNodeStrategy;
|
||||
import org.jclouds.compute.strategy.RunNodesAndAddToSetStrategy;
|
||||
import org.jclouds.compute.strategy.ResumeNodeStrategy;
|
||||
import org.jclouds.compute.strategy.SuspendNodeStrategy;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
|
@ -76,4 +80,14 @@ public class EC2BindComputeStrategiesByClass extends BindComputeStrategiesByClas
|
|||
return EC2RebootNodeStrategy.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<? extends ResumeNodeStrategy> defineStartNodeStrategy() {
|
||||
return EC2ResumeNodeStrategy.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<? extends SuspendNodeStrategy> defineStopNodeStrategy() {
|
||||
return EC2SuspendNodeStrategy.class;
|
||||
}
|
||||
|
||||
}
|
|
@ -91,7 +91,7 @@ public class RunningInstanceToNodeMetadata implements Function<RunningInstance,
|
|||
builder.id(instance.getRegion() + "/" + providerId);
|
||||
String tag = getTagForInstance(instance);
|
||||
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.publicAddresses(nullSafeSet(instance.getIpAddress()));
|
||||
builder.privateAddresses(nullSafeSet(instance.getPrivateIpAddress()));
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -111,8 +111,8 @@ public class EC2RunNodesAndAddToSetStrategy implements RunNodesAndAddToSetStrate
|
|||
populateCredentials(reservation);
|
||||
}
|
||||
|
||||
return utils.runOptionsOnNodesAndAddToGoodSetOrPutExceptionIntoBadMap(template.getOptions(),
|
||||
transform(reservation, runningInstanceToNodeMetadata), goodNodes, badNodes);
|
||||
return utils.runOptionsOnNodesAndAddToGoodSetOrPutExceptionIntoBadMap(template.getOptions(), transform(
|
||||
reservation, runningInstanceToNodeMetadata), goodNodes, badNodes);
|
||||
}
|
||||
|
||||
protected void populateCredentials(Reservation<? extends RunningInstance> reservation) {
|
||||
|
@ -120,7 +120,7 @@ public class EC2RunNodesAndAddToSetStrategy implements RunNodesAndAddToSetStrate
|
|||
Credentials credentials = instanceToCredentials.apply(instance1);
|
||||
if (credentials != null)
|
||||
for (RunningInstance instance : reservation)
|
||||
credentialStore.put(instance.getRegion() + "/" + instance.getId(), credentials);
|
||||
credentialStore.put("node#" + instance.getRegion() + "/" + instance.getId(), credentials);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -33,6 +33,7 @@ import org.jclouds.compute.RunNodesException;
|
|||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.OperatingSystem;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.scriptbuilder.domain.OsFamily;
|
||||
import org.jclouds.scriptbuilder.domain.Statement;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
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
|
||||
// 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
|
||||
// configured for amz. Note we are getting temporary access to a private blob.
|
||||
|
|
|
@ -76,8 +76,8 @@ public class CredentialsStoredInBlobStoreTest {
|
|||
computeContext.close();
|
||||
|
||||
// recreate the compute context with the same map and ensure it still works!
|
||||
computeContext = new ComputeServiceContextFactory().createContext("stub", "foo", "bar",
|
||||
Collections.singleton(new CredentialStoreModule(credentialsMap)));
|
||||
computeContext = new ComputeServiceContextFactory().createContext("stub", "foo", "bar", Collections
|
||||
.singleton(new CredentialStoreModule(credentialsMap)));
|
||||
|
||||
verifyCredentialsFromNodesAreInContext(nodes, computeContext);
|
||||
|
||||
|
@ -88,7 +88,7 @@ public class CredentialsStoredInBlobStoreTest {
|
|||
// verify each node's credential is in the map.
|
||||
assertEquals(computeContext.credentialStore().size(), 10);
|
||||
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
|
||||
|
|
|
@ -90,6 +90,7 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
|||
protected void assertDefaultWorks() {
|
||||
Template defaultTemplate = client.templateBuilder().build();
|
||||
assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true);
|
||||
assertEquals(defaultTemplate.getImage().getOperatingSystem().getVersion(), "0.9.9-beta");
|
||||
assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.AMZN_LINUX);
|
||||
assertEquals(getCores(defaultTemplate.getHardware()), 1.0d);
|
||||
}
|
||||
|
|
|
@ -82,14 +82,14 @@ public class EC2TemplateBuilderLiveTest {
|
|||
.<Module> of(new Log4JLoggingModule()), setupProperties());
|
||||
|
||||
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());
|
||||
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().getFamily(), OsFamily.UBUNTU);
|
||||
assertEquals(template.getImage().getVersion(), "20100921");
|
||||
assertEquals(template.getImage().getVersion(), "20101027");
|
||||
assertEquals(template.getImage().getUserMetadata().get("rootDeviceType"), "instance-store");
|
||||
assertEquals(template.getLocation().getId(), "us-east-1");
|
||||
assertEquals(getCores(template.getHardware()), 1.0d);
|
||||
|
@ -135,7 +135,7 @@ public class EC2TemplateBuilderLiveTest {
|
|||
|
||||
Template defaultTemplate = newContext.getComputeService().templateBuilder().build();
|
||||
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().getFamily(), OsFamily.AMZN_LINUX);
|
||||
assertEquals(defaultTemplate.getImage().getUserMetadata().get("rootDeviceType"), "ebs");
|
||||
|
|
|
@ -75,7 +75,7 @@ public class RunningInstanceToNodeMetadataTest {
|
|||
|
||||
RunningInstanceToNodeMetadata parser = createNodeParser(ImmutableSet.<Hardware> of(), ImmutableSet
|
||||
.<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");
|
||||
|
||||
|
|
|
@ -92,7 +92,7 @@ public class EC2RunNodesAndAddToSetStrategyTest {
|
|||
return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
@SuppressWarnings( { "unchecked" })
|
||||
private void assertRegionAndZoneForLocation(Location location, String region, String zone) {
|
||||
String imageId = "ami1";
|
||||
String instanceCreatedId = "instance1";
|
||||
|
@ -102,9 +102,8 @@ public class EC2RunNodesAndAddToSetStrategyTest {
|
|||
InstanceClient instanceClient = createMock(InstanceClient.class);
|
||||
RunInstancesOptions ec2Options = createMock(RunInstancesOptions.class);
|
||||
RunningInstance instance = createMock(RunningInstance.class);
|
||||
Reservation<? extends RunningInstance> reservation = new Reservation<RunningInstance>(region,
|
||||
ImmutableSet.<String> of(), ImmutableSet.<RunningInstance> of(instance), "ownerId", "requesterId",
|
||||
"reservationId");
|
||||
Reservation<? extends RunningInstance> reservation = new Reservation<RunningInstance>(region, ImmutableSet
|
||||
.<String> of(), ImmutableSet.<RunningInstance> of(instance), "ownerId", "requesterId", "reservationId");
|
||||
NodeMetadata nodeMetadata = createMock(NodeMetadata.class);
|
||||
|
||||
// setup expectations
|
||||
|
@ -119,10 +118,10 @@ public class EC2RunNodesAndAddToSetStrategyTest {
|
|||
(Reservation) reservation);
|
||||
expect(instance.getId()).andReturn(instanceCreatedId).atLeastOnce();
|
||||
// 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(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(input.template.getOptions()).andReturn(input.options).atLeastOnce();
|
||||
|
|
|
@ -26,7 +26,6 @@ import static com.google.common.collect.Lists.newArrayList;
|
|||
import static com.google.common.collect.Sets.newTreeSet;
|
||||
import static org.jclouds.compute.ComputeTestUtils.buildScript;
|
||||
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.assertNotNull;
|
||||
|
||||
|
@ -110,8 +109,8 @@ public class PlacementGroupClientLiveTest {
|
|||
public void setupClient() throws FileNotFoundException, IOException {
|
||||
setupCredentials();
|
||||
Properties overrides = setupProperties();
|
||||
context = new ComputeServiceContextFactory().createContext(provider,
|
||||
ImmutableSet.<Module> of(new Log4JLoggingModule()), overrides);
|
||||
context = new ComputeServiceContextFactory().createContext(provider, ImmutableSet
|
||||
.<Module> of(new Log4JLoggingModule()), overrides);
|
||||
keyPair = setupKeyPair();
|
||||
|
||||
client = EC2Client.class.cast(context.getProviderSpecificContext().getApi());
|
||||
|
@ -195,7 +194,7 @@ public class PlacementGroupClientLiveTest {
|
|||
assertEquals(template.getImage().getId(), "us-east-1/ami-7ea24a17");
|
||||
|
||||
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";
|
||||
context.getComputeService().destroyNodesMatching(NodePredicates.withTag(tag));
|
||||
|
|
|
@ -37,12 +37,12 @@ import org.jclouds.aws.ec2.domain.Reservation;
|
|||
import org.jclouds.aws.ec2.domain.RunningInstance;
|
||||
import org.jclouds.aws.ec2.predicates.InstanceStateRunning;
|
||||
import org.jclouds.net.IPSocket;
|
||||
import org.jclouds.predicates.InetSocketAddressConnect;
|
||||
import org.jclouds.predicates.RetryablePredicate;
|
||||
import org.jclouds.rest.RestContext;
|
||||
import org.jclouds.rest.RestContextFactory;
|
||||
import org.jclouds.scriptbuilder.ScriptBuilder;
|
||||
import org.jclouds.scriptbuilder.domain.OsFamily;
|
||||
import org.jclouds.ssh.jsch.predicates.InetSocketAddressConnect;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
|
|
@ -64,17 +64,33 @@ public class ParseAzureStorageErrorFromXmlContent implements HttpErrorHandler {
|
|||
|
||||
public void handleError(HttpCommand command, HttpResponse response) {
|
||||
Exception exception = new HttpResponseException(command, response);
|
||||
String message = null;
|
||||
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()) {
|
||||
case 401:
|
||||
exception = new AuthorizationException(command.getRequest(), error != null ? error
|
||||
.getMessage() : response.getStatusLine());
|
||||
exception = new AuthorizationException(command.getRequest(), message);
|
||||
break;
|
||||
case 404:
|
||||
|
||||
if (!command.getRequest().getMethod().equals("DELETE")) {
|
||||
String message = error != null ? error.getMessage() : String.format("%s -> %s",
|
||||
command.getRequest().getRequestLine(), response.getStatusLine());
|
||||
String path = command.getRequest().getEndpoint().getPath();
|
||||
Matcher matcher = CONTAINER_PATH.matcher(path);
|
||||
if (matcher.find()) {
|
||||
|
@ -82,15 +98,14 @@ public class ParseAzureStorageErrorFromXmlContent implements HttpErrorHandler {
|
|||
} else {
|
||||
matcher = CONTAINER_KEY_PATH.matcher(path);
|
||||
if (matcher.find()) {
|
||||
exception = new KeyNotFoundException(matcher.group(1), matcher.group(2),
|
||||
message);
|
||||
exception = new KeyNotFoundException(matcher.group(1), matcher.group(2), message);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
exception = error != null ? new AzureStorageResponseException(command, response,
|
||||
error) : new HttpResponseException(command, response);
|
||||
case 411:
|
||||
exception = new IllegalArgumentException(message);
|
||||
break;
|
||||
}
|
||||
} finally {
|
||||
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;
|
||||
}
|
||||
}
|
|
@ -81,11 +81,9 @@ public class AzureBlobClientLiveTest {
|
|||
|
||||
protected void setupCredentials() {
|
||||
identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
|
||||
credential = checkNotNull(System.getProperty("test." + provider + ".credential"), "test." + provider
|
||||
+ ".credential");
|
||||
endpoint = checkNotNull(System.getProperty("test." + provider + ".endpoint"), "test." + provider + ".endpoint");
|
||||
apiversion = checkNotNull(System.getProperty("test." + provider + ".apiversion"), "test." + provider
|
||||
+ ".apiversion");
|
||||
credential = System.getProperty("test." + provider + ".credential");
|
||||
endpoint = System.getProperty("test." + provider + ".endpoint");
|
||||
apiversion = System.getProperty("test." + provider + ".apiversion");
|
||||
}
|
||||
|
||||
protected Properties setupProperties() {
|
||||
|
@ -93,8 +91,11 @@ public class AzureBlobClientLiveTest {
|
|||
overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
|
||||
overrides.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true");
|
||||
overrides.setProperty(provider + ".identity", identity);
|
||||
if (credential != null)
|
||||
overrides.setProperty(provider + ".credential", credential);
|
||||
if (endpoint != null)
|
||||
overrides.setProperty(provider + ".endpoint", endpoint);
|
||||
if (apiversion != null)
|
||||
overrides.setProperty(provider + ".apiversion", apiversion);
|
||||
return overrides;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -234,6 +234,30 @@ See http://code.google.com/p/jclouds for details."
|
|||
([id #^ComputeService compute]
|
||||
(.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
|
||||
"Reboot all the nodes with the given tag."
|
||||
([tag] (reboot-nodes-with-tag tag *compute*))
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
[org.jclouds.ssh SshClient ExecResponse]
|
||||
com.google.inject.Module
|
||||
com.google.common.collect.ImmutableSet
|
||||
org.jclouds.domain.Credentials
|
||||
org.jclouds.net.IPSocket
|
||||
[org.jclouds.compute ComputeService ComputeServiceContextFactory StandaloneComputeServiceContextSpec]
|
||||
[java.util Set Map]
|
||||
|
@ -51,6 +52,10 @@
|
|||
(^void destroyNode [this ^String id]
|
||||
())
|
||||
(^void rebootNode [this ^String id]
|
||||
())
|
||||
(^void suspendNode [this ^String id]
|
||||
())
|
||||
(^void resumeNode [this ^String id]
|
||||
()))))
|
||||
|
||||
(defn compute-context [^RestContextSpec spec]
|
||||
|
@ -75,6 +80,9 @@
|
|||
[ctor]
|
||||
(reify
|
||||
org.jclouds.ssh.SshClient$Factory
|
||||
(^org.jclouds.ssh.SshClient create
|
||||
[_ ^IPSocket socket ^Credentials credentials]
|
||||
(ctor socket credentials))
|
||||
(^org.jclouds.ssh.SshClient create
|
||||
[_ ^IPSocket socket ^String username ^String password-or-key]
|
||||
(ctor socket username password-or-key))
|
||||
|
|
|
@ -63,52 +63,48 @@ public interface ComputeService {
|
|||
TemplateOptions templateOptions();
|
||||
|
||||
/**
|
||||
* The list hardware profiles command shows you the options including virtual cpu count,
|
||||
* memory, and disks. cpu count is not a portable quantity across clouds, as
|
||||
* they are measured differently. However, it is a good indicator of relative
|
||||
* speed within a cloud. memory is measured in megabytes and disks in
|
||||
* gigabytes.
|
||||
* The list hardware profiles command shows you the options including virtual cpu count, memory,
|
||||
* and disks. cpu count is not a portable quantity across clouds, as they are measured
|
||||
* differently. However, it is a good indicator of relative speed within a cloud. memory is
|
||||
* measured in megabytes and disks in gigabytes.
|
||||
*
|
||||
* @return a map of hardware profiles by ID, conceding that in some clouds the "id" is
|
||||
* not used.
|
||||
* @return a map of hardware profiles by ID, conceding that in some clouds the "id" is not used.
|
||||
*/
|
||||
Set<? extends Hardware> listHardwareProfiles();
|
||||
|
||||
/**
|
||||
* Images define the operating system and metadata related to a node. In some
|
||||
* clouds, Images are bound to a specific region, and their identifiers are
|
||||
* different across these regions. For this reason, you should consider
|
||||
* matching image requirements like operating system family with
|
||||
* TemplateBuilder as opposed to choosing an image explicitly. The
|
||||
* getImages() command returns a map of images by id.
|
||||
* Images define the operating system and metadata related to a node. In some clouds, Images are
|
||||
* bound to a specific region, and their identifiers are different across these regions. For this
|
||||
* reason, you should consider matching image requirements like operating system family with
|
||||
* TemplateBuilder as opposed to choosing an image explicitly. The getImages() command returns a
|
||||
* map of images by id.
|
||||
*/
|
||||
Set<? extends Image> listImages();
|
||||
|
||||
/**
|
||||
* all nodes available to the current user by id. If possible, the returned
|
||||
* set will include {@link NodeMetadata} objects.
|
||||
* all nodes available to the current user by id. If possible, the returned set will include
|
||||
* {@link NodeMetadata} objects.
|
||||
*/
|
||||
Set<? extends ComputeMetadata> listNodes();
|
||||
|
||||
/**
|
||||
* The list locations command returns all the valid locations for nodes. A
|
||||
* location has a scope, which is typically region or zone. A region is a
|
||||
* general area, like eu-west, where a zone is similar to a datacenter. If a
|
||||
* location has a parent, that implies it is within that location. For
|
||||
* example a location can be a rack, whose parent is likely to be a zone.
|
||||
* The list locations command returns all the valid locations for nodes. A location has a scope,
|
||||
* which is typically region or zone. A region is a general area, like eu-west, where a zone is
|
||||
* similar to a datacenter. If a location has a parent, that implies it is within that location.
|
||||
* For example a location can be a rack, whose parent is likely to be a zone.
|
||||
*/
|
||||
Set<? extends Location> listAssignableLocations();
|
||||
|
||||
/**
|
||||
*
|
||||
* The compute api treats nodes as a group based on a tag you specify. Using
|
||||
* this tag, you can choose to operate one or many nodes as a logical unit
|
||||
* without regard to the implementation details of the cloud.
|
||||
* The compute api treats nodes as a group based on a tag you specify. Using this tag, you can
|
||||
* choose to operate one or many nodes as a logical unit without regard to the implementation
|
||||
* details of the cloud.
|
||||
* <p/>
|
||||
*
|
||||
* The set that is returned will include credentials you can use to ssh into
|
||||
* the nodes. The "key" part of the credentials is either a password or a
|
||||
* private key. You have to inspect the value to determine this.
|
||||
* The set that is returned will include credentials you can use to ssh into the nodes. The "key"
|
||||
* part of the credentials is either a password or a private key. You have to inspect the value
|
||||
* to determine this.
|
||||
*
|
||||
* <pre>
|
||||
* if (node.getCredentials().key.startsWith("-----BEGIN RSA PRIVATE KEY-----"))
|
||||
|
@ -116,11 +112,11 @@ public interface ComputeService {
|
|||
* </pre>
|
||||
*
|
||||
* <p/>
|
||||
* Note. if all you want to do is execute a script at bootup, you should
|
||||
* consider use of the runscript option.
|
||||
* Note. if all you want to do is execute a script at bootup, you should consider use of the
|
||||
* runscript option.
|
||||
* <p/>
|
||||
* If resources such as security groups are needed, they will be reused or
|
||||
* created for you. Inbound port 22 will always be opened up.
|
||||
* If resources such as security groups are needed, they will be reused or created for you.
|
||||
* Inbound port 22 will always be opened up.
|
||||
*
|
||||
* @param tag
|
||||
* - 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.
|
||||
*
|
||||
* @throws RunNodesException
|
||||
* when there's a problem applying options to nodes. Note that
|
||||
* successful and failed nodes are a part of this exception, so be
|
||||
* sure to inspect this carefully.
|
||||
* when there's a problem applying options to nodes. Note that successful and failed
|
||||
* nodes are a part of this exception, so be sure to inspect this carefully.
|
||||
*/
|
||||
Set<? extends NodeMetadata> runNodesWithTag(String tag, int count, Template template) throws RunNodesException;
|
||||
|
||||
/**
|
||||
* Like {@link ComputeService#runNodesWithTag(String,int,Template)}, except
|
||||
* that the template is default, equivalent to {@code
|
||||
* templateBuilder().any().options(templateOptions)}.
|
||||
* Like {@link ComputeService#runNodesWithTag(String,int,Template)}, except that the template is
|
||||
* default, equivalent to {@code templateBuilder().any().options(templateOptions)}.
|
||||
*/
|
||||
Set<? extends NodeMetadata> runNodesWithTag(String tag, int count, TemplateOptions templateOptions)
|
||||
throws RunNodesException;
|
||||
|
||||
/**
|
||||
* Like {@link ComputeService#runNodesWithTag(String,int,TemplateOptions)},
|
||||
* except that the options are default, as specified in
|
||||
* {@link ComputeService#templateOptions}.
|
||||
* Like {@link ComputeService#runNodesWithTag(String,int,TemplateOptions)}, except that the
|
||||
* options are default, as specified in {@link ComputeService#templateOptions}.
|
||||
*/
|
||||
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
|
||||
* dependent resources will also be destroyed.
|
||||
* resume the node from {@link org.jclouds.compute.domain.NodeState#SUSPENDED suspended} state,
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* nodes matching the filter are treated as a logical set. Using the delete
|
||||
* command, you can save time by removing the nodes in parallel. When the
|
||||
* last node in a set is destroyed, any indirect resources it uses, such as
|
||||
* keypairs, are also destroyed.
|
||||
* nodes matching the filter are treated as a logical set. Using the delete command, you can save
|
||||
* time by removing the nodes in parallel. When the last node in a set is destroyed, any indirect
|
||||
* resources it uses, such as keypairs, are also destroyed.
|
||||
*
|
||||
* @return list of nodes destroyed
|
||||
*/
|
||||
|
@ -174,8 +197,8 @@ public interface ComputeService {
|
|||
void rebootNode(String id);
|
||||
|
||||
/**
|
||||
* nodes matching the filter are treated as a logical set. Using this
|
||||
* command, you can save time by rebooting the nodes in parallel.
|
||||
* nodes matching the filter are treated as a logical set. Using this command, you can save time
|
||||
* by rebooting the nodes in parallel.
|
||||
*/
|
||||
void rebootNodesMatching(Predicate<NodeMetadata> filter);
|
||||
|
||||
|
@ -185,8 +208,8 @@ public interface ComputeService {
|
|||
NodeMetadata getNodeMetadata(String id);
|
||||
|
||||
/**
|
||||
* get all nodes including details such as image and ip addresses even if it
|
||||
* incurs extra requests to the service.
|
||||
* get all nodes including details such as image and ip addresses even if it incurs extra
|
||||
* requests to the service.
|
||||
*
|
||||
* @param filter
|
||||
* how to select the nodes you are interested in details on.
|
||||
|
@ -207,13 +230,11 @@ public interface ComputeService {
|
|||
* Run the script on all nodes with the specific tag.
|
||||
*
|
||||
* @param filter
|
||||
* Predicate-based filter to define on which nodes the script is to
|
||||
* be executed
|
||||
* Predicate-based filter to define on which nodes the script is to be executed
|
||||
* @param runScript
|
||||
* payload containing the script to run
|
||||
* @param options
|
||||
* nullable options to how to run the script, whether to override
|
||||
* credentials
|
||||
* nullable options to how to run the script, whether to override credentials
|
||||
* @return map with node identifiers and corresponding responses
|
||||
* @throws RunScriptOnNodesException
|
||||
* if anything goes wrong during script execution
|
||||
|
|
|
@ -36,27 +36,29 @@ public interface ComputeServiceAdapter<N, H, I, L> {
|
|||
/**
|
||||
* {@link ComputeService#runNodesWithTag(String, int, Template)} generates the parameters passed
|
||||
* 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
|
||||
* its credentials in the supplied map.
|
||||
* <p/>
|
||||
* Note that it is intentional to return the library native node object, as generic type
|
||||
*
|
||||
* <h4>note</h4> 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
|
||||
* {@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
|
||||
* used to aggregate nodes with identical configuration
|
||||
* @param name
|
||||
* unique supplied name for the node, which has the tag encoded into it.
|
||||
* @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.
|
||||
* @param credentialStore
|
||||
* once the node is started, its login user and password will be encoded based on the
|
||||
* node {@code id}
|
||||
* once the node is resumeed, its login user and password must be stored keyed on
|
||||
* {@code node#id}.
|
||||
* @return library-native representation of a node.
|
||||
*
|
||||
* @see ComputeService#runNodesWithTag(String, int, Template)
|
||||
* @see ComputeServiceContext#getCredentialStore
|
||||
*/
|
||||
N runNodeWithTagAndNameAndStoreCredentials(String tag, String name, Template template,
|
||||
Map<String, Credentials> credentialStore);
|
||||
|
@ -92,6 +94,10 @@ public interface ComputeServiceAdapter<N, H, I, L> {
|
|||
|
||||
void rebootNode(String id);
|
||||
|
||||
void resumeNode(String id);
|
||||
|
||||
void suspendNode(String id);
|
||||
|
||||
Iterable<N> listNodes();
|
||||
|
||||
}
|
|
@ -50,13 +50,26 @@ public interface ComputeServiceContext {
|
|||
|
||||
/**
|
||||
* 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
|
||||
* could access this externally.
|
||||
*
|
||||
* of the resource with a namespace prefix (ex. {@code node#}. We are testing this approach for
|
||||
* 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
|
||||
Map<String, Credentials> getCredentialStore();
|
||||
|
||||
/**
|
||||
* @see ComputeServiceContext#getCredentialStore
|
||||
*/
|
||||
@Beta
|
||||
Map<String, Credentials> credentialStore();
|
||||
|
||||
|
|
|
@ -21,9 +21,11 @@ package org.jclouds.compute;
|
|||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.internal.UtilsImpl;
|
||||
import org.jclouds.ssh.SshClient;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.inject.ImplementedBy;
|
||||
|
||||
/**
|
||||
|
@ -37,4 +39,9 @@ public interface Utils extends org.jclouds.rest.Utils {
|
|||
|
||||
@Nullable
|
||||
SshClient.Factory sshFactory();
|
||||
|
||||
/**
|
||||
* @return function that gets an ssh client for a node that is available via ssh.
|
||||
*/
|
||||
Function<NodeMetadata, SshClient> sshForNode();
|
||||
}
|
||||
|
|
|
@ -24,7 +24,6 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||
import java.util.Collections;
|
||||
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.util.ComputeServiceUtils;
|
||||
import org.jclouds.compute.util.ComputeServiceUtils.SshCallable;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.scriptbuilder.InitBuilder;
|
||||
|
@ -33,6 +32,7 @@ import org.jclouds.scriptbuilder.domain.Statement;
|
|||
import org.jclouds.ssh.ExecResponse;
|
||||
import org.jclouds.ssh.SshClient;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
/**
|
||||
|
@ -77,8 +77,9 @@ public class InitAndStartScriptOnNode implements SshCallable<ExecResponse> {
|
|||
|
||||
protected ExecResponse runCommand(String command) {
|
||||
ExecResponse returnVal;
|
||||
logger.debug(">> running [%s] as %s@%s", command.replace(node.getCredentials().credential, "XXXXX"), node
|
||||
.getCredentials().identity, Iterables.get(node.getPublicAddresses(), 0));
|
||||
logger.debug(">> running [%s] as %s@%s", command.replace(node.getAdminPassword() != null ? node
|
||||
.getAdminPassword() : "XXXXX", "XXXXX"), node.getCredentials().identity, Iterables.get(node
|
||||
.getPublicAddresses(), 0));
|
||||
returnVal = ssh.exec(command);
|
||||
return returnVal;
|
||||
}
|
||||
|
@ -89,15 +90,15 @@ public class InitAndStartScriptOnNode implements SshCallable<ExecResponse> {
|
|||
this.ssh = checkNotNull(ssh, "ssh");
|
||||
}
|
||||
|
||||
protected String execScriptAsRoot(String action) {
|
||||
@VisibleForTesting
|
||||
public String execScriptAsRoot(String action) {
|
||||
String command;
|
||||
if (node.getCredentials().identity.equals("root")) {
|
||||
command = "./" + init.getInstanceName() + " " + action;
|
||||
} else if (ComputeServiceUtils.isKeyAuth(node)) {
|
||||
command = "sudo ./" + init.getInstanceName() + " " + action;
|
||||
} else if (node.getAdminPassword() != null) {
|
||||
command = String.format("echo '%s'|sudo -S ./%s %s", node.getAdminPassword(), init.getInstanceName(), action);
|
||||
} else {
|
||||
command = String.format("echo '%s'|sudo -S ./%s %s", node.getCredentials().credential, init.getInstanceName(),
|
||||
action);
|
||||
command = "sudo ./" + init.getInstanceName() + " " + action;
|
||||
}
|
||||
return command;
|
||||
}
|
||||
|
|
|
@ -34,10 +34,13 @@ import org.jclouds.compute.LoadBalancerService;
|
|||
import org.jclouds.compute.domain.ComputeMetadata;
|
||||
import org.jclouds.compute.domain.Hardware;
|
||||
import org.jclouds.compute.domain.Image;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.TemplateBuilder;
|
||||
import org.jclouds.compute.functions.CreateSshClientOncePortIsListeningOnNode;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.rest.AuthorizationException;
|
||||
import org.jclouds.rest.suppliers.RetryOnTimeOutButNotOnAuthorizationExceptionSupplier;
|
||||
import org.jclouds.ssh.SshClient;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Supplier;
|
||||
|
@ -47,6 +50,7 @@ import com.google.inject.AbstractModule;
|
|||
import com.google.inject.Injector;
|
||||
import com.google.inject.Provides;
|
||||
import com.google.inject.Scopes;
|
||||
import com.google.inject.TypeLiteral;
|
||||
import com.google.inject.util.Providers;
|
||||
|
||||
/**
|
||||
|
@ -58,6 +62,8 @@ public abstract class BaseComputeServiceContextModule extends AbstractModule {
|
|||
protected void configure() {
|
||||
install(new ComputeServiceTimeoutsModule());
|
||||
bindLoadBalancerService();
|
||||
bind(new TypeLiteral<Function<NodeMetadata, SshClient>>() {
|
||||
}).to(CreateSshClientOncePortIsListeningOnNode.class);
|
||||
}
|
||||
|
||||
protected void bindLoadBalancerService() {
|
||||
|
|
|
@ -25,6 +25,8 @@ import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
|
|||
import org.jclouds.compute.strategy.ListNodesStrategy;
|
||||
import org.jclouds.compute.strategy.RebootNodeStrategy;
|
||||
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 com.google.inject.AbstractModule;
|
||||
|
@ -42,6 +44,8 @@ public abstract class BindComputeStrategiesByClass extends AbstractModule {
|
|||
bindListNodesStrategy(defineListNodesStrategy());
|
||||
bindGetNodeMetadataStrategy(defineGetNodeMetadataStrategy());
|
||||
bindRebootNodeStrategy(defineRebootNodeStrategy());
|
||||
bindStartNodeStrategy(defineStartNodeStrategy());
|
||||
bindStopNodeStrategy(defineStopNodeStrategy());
|
||||
bindDestroyNodeStrategy(defineDestroyNodeStrategy());
|
||||
}
|
||||
|
||||
|
@ -64,6 +68,14 @@ public abstract class BindComputeStrategiesByClass extends AbstractModule {
|
|||
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) {
|
||||
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 ResumeNodeStrategy> defineStartNodeStrategy();
|
||||
|
||||
protected abstract Class<? extends SuspendNodeStrategy> defineStopNodeStrategy();
|
||||
|
||||
protected abstract Class<? extends GetNodeMetadataStrategy> defineGetNodeMetadataStrategy();
|
||||
|
||||
protected abstract Class<? extends ListNodesStrategy> defineListNodesStrategy();
|
||||
|
|
|
@ -26,13 +26,12 @@ import javax.inject.Singleton;
|
|||
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.predicates.NodeRunning;
|
||||
import org.jclouds.compute.predicates.NodeSuspended;
|
||||
import org.jclouds.compute.predicates.NodeTerminated;
|
||||
import org.jclouds.compute.predicates.ScriptStatusReturnsZero;
|
||||
import org.jclouds.compute.predicates.ScriptStatusReturnsZero.CommandUsingClient;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants.Timeouts;
|
||||
import org.jclouds.net.IPSocket;
|
||||
import org.jclouds.predicates.RetryablePredicate;
|
||||
import org.jclouds.predicates.SocketOpen;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.inject.AbstractModule;
|
||||
|
@ -61,6 +60,15 @@ public class ComputeServiceTimeoutsModule extends AbstractModule {
|
|||
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
|
||||
@Singleton
|
||||
@Named("SCRIPT_COMPLETE")
|
||||
|
@ -69,12 +77,6 @@ public class ComputeServiceTimeoutsModule extends AbstractModule {
|
|||
not(stateRunning), timeouts.scriptComplete);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
protected Predicate<IPSocket> socketTester(SocketOpen open, Timeouts timeouts) {
|
||||
return timeouts.portOpen == 0 ? open : new RetryablePredicate<IPSocket>(open, timeouts.portOpen);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
|
||||
|
|
|
@ -38,6 +38,8 @@ import org.jclouds.compute.strategy.DestroyNodeStrategy;
|
|||
import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
|
||||
import org.jclouds.compute.strategy.ListNodesStrategy;
|
||||
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.suppliers.DefaultLocationSupplier;
|
||||
import org.jclouds.domain.Location;
|
||||
|
@ -156,6 +158,18 @@ public class StandaloneComputeServiceContextModule<N, H, I, L> extends BaseCompu
|
|||
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
|
||||
public static enum IdentityFunction implements Function<Object, Object> {
|
||||
INSTANCE;
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
|
||||
package org.jclouds.compute.domain;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.jclouds.compute.domain.internal.ImageImpl;
|
||||
import org.jclouds.domain.Credentials;
|
||||
|
||||
|
@ -48,6 +50,17 @@ public interface Image extends ComputeMetadata {
|
|||
*/
|
||||
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
|
||||
*/
|
||||
|
|
|
@ -37,6 +37,8 @@ public class ImageBuilder extends ComputeMetadataBuilder {
|
|||
private OperatingSystem operatingSystem;
|
||||
private String version;
|
||||
private String description;
|
||||
@Nullable
|
||||
private String adminPassword;
|
||||
private Credentials defaultCredentials;
|
||||
|
||||
public ImageBuilder() {
|
||||
|
@ -58,6 +60,11 @@ public class ImageBuilder extends ComputeMetadataBuilder {
|
|||
return this;
|
||||
}
|
||||
|
||||
public ImageBuilder adminPassword(@Nullable String adminPassword) {
|
||||
this.adminPassword = adminPassword;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ImageBuilder defaultCredentials(@Nullable Credentials defaultCredentials) {
|
||||
this.defaultCredentials = defaultCredentials;
|
||||
return this;
|
||||
|
@ -101,7 +108,14 @@ public class ImageBuilder extends ComputeMetadataBuilder {
|
|||
@Override
|
||||
public Image build() {
|
||||
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());
|
||||
}
|
||||
|
||||
}
|
|
@ -70,6 +70,28 @@ public interface NodeMetadata extends ComputeMetadata {
|
|||
*/
|
||||
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.
|
||||
*/
|
||||
|
@ -80,10 +102,4 @@ public interface NodeMetadata extends ComputeMetadata {
|
|||
*/
|
||||
Set<String> getPrivateAddresses();
|
||||
|
||||
/**
|
||||
* If possible, these are returned upon all detail requests. However, it is often the case that
|
||||
* credentials are only available at "run" time.
|
||||
*/
|
||||
Credentials getCredentials();
|
||||
|
||||
}
|
|
@ -42,9 +42,12 @@ public class NodeMetadataBuilder extends ComputeMetadataBuilder {
|
|||
private Set<String> publicAddresses = Sets.newLinkedHashSet();
|
||||
private Set<String> privateAddresses = Sets.newLinkedHashSet();
|
||||
@Nullable
|
||||
private String adminPassword;
|
||||
@Nullable
|
||||
private Credentials credentials;
|
||||
@Nullable
|
||||
private String tag;
|
||||
private int loginPort = 22;
|
||||
@Nullable
|
||||
private String imageId;
|
||||
@Nullable
|
||||
|
@ -56,6 +59,11 @@ public class NodeMetadataBuilder extends ComputeMetadataBuilder {
|
|||
super(ComputeType.NODE);
|
||||
}
|
||||
|
||||
public NodeMetadataBuilder loginPort(int loginPort) {
|
||||
this.loginPort = loginPort;
|
||||
return this;
|
||||
}
|
||||
|
||||
public NodeMetadataBuilder state(NodeState state) {
|
||||
this.state = checkNotNull(state, "state");
|
||||
return this;
|
||||
|
@ -76,6 +84,11 @@ public class NodeMetadataBuilder extends ComputeMetadataBuilder {
|
|||
return this;
|
||||
}
|
||||
|
||||
public NodeMetadataBuilder adminPassword(@Nullable String adminPassword) {
|
||||
this.adminPassword = adminPassword;
|
||||
return this;
|
||||
}
|
||||
|
||||
public NodeMetadataBuilder tag(@Nullable String tag) {
|
||||
this.tag = tag;
|
||||
return this;
|
||||
|
@ -134,15 +147,16 @@ public class NodeMetadataBuilder extends ComputeMetadataBuilder {
|
|||
@Override
|
||||
public NodeMetadata build() {
|
||||
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) {
|
||||
return new NodeMetadataBuilder().providerId(node.getProviderId()).name(node.getName()).id(node.getId())
|
||||
.location(node.getLocation()).uri(node.getUri()).userMetadata(node.getUserMetadata()).tag(node.getTag())
|
||||
.hardware(node.getHardware()).imageId(node.getImageId()).operatingSystem(node.getOperatingSystem())
|
||||
.state(node.getState()).publicAddresses(node.getPublicAddresses())
|
||||
.privateAddresses(node.getPrivateAddresses()).credentials(node.getCredentials());
|
||||
return new NodeMetadataBuilder().providerId(node.getProviderId()).name(node.getName()).id(node.getId()).location(
|
||||
node.getLocation()).uri(node.getUri()).userMetadata(node.getUserMetadata()).tag(node.getTag()).hardware(
|
||||
node.getHardware()).imageId(node.getImageId()).operatingSystem(node.getOperatingSystem()).state(
|
||||
node.getState()).loginPort(node.getLoginPort()).publicAddresses(node.getPublicAddresses())
|
||||
.privateAddresses(node.getPrivateAddresses()).adminPassword(node.getAdminPassword()).credentials(
|
||||
node.getCredentials());
|
||||
}
|
||||
|
||||
}
|
|
@ -43,15 +43,18 @@ public class ImageImpl extends ComputeMetadataImpl implements Image {
|
|||
private final OperatingSystem operatingSystem;
|
||||
private final String version;
|
||||
private final String description;
|
||||
@Nullable
|
||||
private final String adminPassword;
|
||||
private final Credentials defaultCredentials;
|
||||
|
||||
public ImageImpl(String providerId, String name, String id, Location location, URI uri,
|
||||
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);
|
||||
this.operatingSystem = checkNotNull(operatingSystem, "operatingSystem");
|
||||
this.version = version;
|
||||
this.description = checkNotNull(description, "description");
|
||||
this.adminPassword = adminPassword;
|
||||
this.defaultCredentials = defaultCredentials;
|
||||
}
|
||||
|
||||
|
@ -87,6 +90,14 @@ public class ImageImpl extends ComputeMetadataImpl implements Image {
|
|||
return defaultCredentials;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String getAdminPassword() {
|
||||
return adminPassword;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[id=" + getId() + ", name=" + getName() + ", operatingSystem=" + operatingSystem + ", description="
|
||||
|
@ -99,6 +110,7 @@ public class ImageImpl extends ComputeMetadataImpl implements Image {
|
|||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = super.hashCode();
|
||||
result = prime * result + ((adminPassword == null) ? 0 : adminPassword.hashCode());
|
||||
result = prime * result + ((defaultCredentials == null) ? 0 : defaultCredentials.hashCode());
|
||||
result = prime * result + ((description == null) ? 0 : description.hashCode());
|
||||
result = prime * result + ((operatingSystem == null) ? 0 : operatingSystem.hashCode());
|
||||
|
@ -115,6 +127,11 @@ public class ImageImpl extends ComputeMetadataImpl implements Image {
|
|||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
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 (other.defaultCredentials != null)
|
||||
return false;
|
||||
|
|
|
@ -47,9 +47,12 @@ public class NodeMetadataImpl extends ComputeMetadataImpl implements NodeMetadat
|
|||
private static final long serialVersionUID = 7924307572338157887L;
|
||||
|
||||
private final NodeState state;
|
||||
private final int loginPort;
|
||||
private final Set<String> publicAddresses;
|
||||
private final Set<String> privateAddresses;
|
||||
@Nullable
|
||||
private final String adminPassword;
|
||||
@Nullable
|
||||
private final Credentials credentials;
|
||||
@Nullable
|
||||
private final String tag;
|
||||
|
@ -61,17 +64,20 @@ public class NodeMetadataImpl extends ComputeMetadataImpl implements NodeMetadat
|
|||
private final OperatingSystem os;
|
||||
|
||||
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,
|
||||
@Nullable OperatingSystem os, NodeState state, Iterable<String> publicAddresses,
|
||||
Iterable<String> privateAddresses, @Nullable Credentials credentials) {
|
||||
Map<String, String> userMetadata, @Nullable String tag, @Nullable Hardware hardware,
|
||||
@Nullable String imageId, @Nullable OperatingSystem os, NodeState state, int loginPort,
|
||||
Iterable<String> publicAddresses, Iterable<String> privateAddresses, @Nullable String adminPassword,
|
||||
@Nullable Credentials credentials) {
|
||||
super(ComputeType.NODE, providerId, name, id, location, uri, userMetadata);
|
||||
this.tag = tag;
|
||||
this.hardware = hardware;
|
||||
this.imageId = imageId;
|
||||
this.os = os;
|
||||
this.state = checkNotNull(state, "state");
|
||||
this.loginPort = loginPort;
|
||||
this.publicAddresses = ImmutableSet.copyOf(checkNotNull(publicAddresses, "publicAddresses"));
|
||||
this.privateAddresses = ImmutableSet.copyOf(checkNotNull(privateAddresses, "privateAddresses"));
|
||||
this.adminPassword = adminPassword;
|
||||
this.credentials = credentials;
|
||||
}
|
||||
|
||||
|
@ -91,6 +97,14 @@ public class NodeMetadataImpl extends ComputeMetadataImpl implements NodeMetadat
|
|||
return hardware;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String getAdminPassword() {
|
||||
return adminPassword;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
@ -123,6 +137,14 @@ public class NodeMetadataImpl extends ComputeMetadataImpl implements NodeMetadat
|
|||
return state;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public int getLoginPort() {
|
||||
return this.loginPort;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
@ -143,21 +165,24 @@ public class NodeMetadataImpl extends ComputeMetadataImpl implements NodeMetadat
|
|||
public String toString() {
|
||||
return "[id=" + getId() + ", providerId=" + getProviderId() + ", tag=" + getTag() + ", name=" + getName()
|
||||
+ ", location=" + getLocation() + ", uri=" + getUri() + ", imageId=" + getImageId() + ", os="
|
||||
+ getOperatingSystem() + ", state=" + getState() + ", privateAddresses=" + privateAddresses
|
||||
+ ", publicAddresses=" + publicAddresses + ", hardware=" + getHardware() + ", loginUser="
|
||||
+ ((credentials != null) ? credentials.identity : null) + ", userMetadata=" + getUserMetadata() + "]";
|
||||
+ getOperatingSystem() + ", state=" + getState() + ", loginPort=" + getLoginPort()
|
||||
+ ", privateAddresses=" + privateAddresses + ", publicAddresses=" + publicAddresses + ", hardware="
|
||||
+ getHardware() + ", loginUser=" + ((credentials != null) ? credentials.identity : null)
|
||||
+ ", userMetadata=" + getUserMetadata() + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = super.hashCode();
|
||||
result = prime * result + loginPort;
|
||||
result = prime * result + ((privateAddresses == null) ? 0 : privateAddresses.hashCode());
|
||||
result = prime * result + ((publicAddresses == null) ? 0 : publicAddresses.hashCode());
|
||||
result = prime * result + ((tag == null) ? 0 : tag.hashCode());
|
||||
result = prime * result + ((imageId == null) ? 0 : imageId.hashCode());
|
||||
result = prime * result + ((hardware == null) ? 0 : hardware.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());
|
||||
return result;
|
||||
}
|
||||
|
@ -171,6 +196,8 @@ public class NodeMetadataImpl extends ComputeMetadataImpl implements NodeMetadat
|
|||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
NodeMetadataImpl other = (NodeMetadataImpl) obj;
|
||||
if (loginPort != other.loginPort)
|
||||
return false;
|
||||
if (privateAddresses == null) {
|
||||
if (other.privateAddresses != null)
|
||||
return false;
|
||||
|
@ -201,6 +228,11 @@ public class NodeMetadataImpl extends ComputeMetadataImpl implements NodeMetadat
|
|||
return false;
|
||||
} else if (!os.equals(other.os))
|
||||
return false;
|
||||
if (adminPassword == null) {
|
||||
if (other.adminPassword != null)
|
||||
return false;
|
||||
} else if (!adminPassword.equals(other.adminPassword))
|
||||
return false;
|
||||
if (credentials == null) {
|
||||
if (other.credentials != null)
|
||||
return false;
|
||||
|
|
|
@ -399,16 +399,16 @@ public class TemplateBuilderImpl implements TemplateBuilder {
|
|||
};
|
||||
static final Ordering<Image> DEFAULT_IMAGE_ORDERING = new Ordering<Image>() {
|
||||
public int compare(Image left, Image right) {
|
||||
return ComparisonChain.start()
|
||||
.compare(left.getName(), right.getName(), Ordering.<String> natural().nullsLast())
|
||||
.compare(left.getVersion(), right.getVersion(), Ordering.<String> natural().nullsLast())
|
||||
.compare(left.getOperatingSystem().getName(), right.getOperatingSystem().getName(),//
|
||||
Ordering.<String> natural().nullsLast())
|
||||
.compare(left.getOperatingSystem().getVersion(), right.getOperatingSystem().getVersion(),//
|
||||
Ordering.<String> natural().nullsLast())
|
||||
.compare(left.getOperatingSystem().getDescription(), right.getOperatingSystem().getDescription(),//
|
||||
Ordering.<String> natural().nullsLast())
|
||||
.compare(left.getOperatingSystem().getArch(), right.getOperatingSystem().getArch()).result();
|
||||
return ComparisonChain.start().compare(left.getName(), right.getName(),
|
||||
Ordering.<String> natural().nullsLast()).compare(left.getVersion(), right.getVersion(),
|
||||
Ordering.<String> natural().nullsLast()).compare(left.getOperatingSystem().getName(),
|
||||
right.getOperatingSystem().getName(),//
|
||||
Ordering.<String> natural().nullsLast()).compare(left.getOperatingSystem().getVersion(),
|
||||
right.getOperatingSystem().getVersion(),//
|
||||
Ordering.<String> natural().nullsLast()).compare(left.getOperatingSystem().getDescription(),
|
||||
right.getOperatingSystem().getDescription(),//
|
||||
Ordering.<String> natural().nullsLast()).compare(left.getOperatingSystem().getArch(),
|
||||
right.getOperatingSystem().getArch()).result();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -427,19 +427,23 @@ public class TemplateBuilderImpl implements TemplateBuilder {
|
|||
*/
|
||||
@Override
|
||||
public TemplateBuilder fromHardware(Hardware hardware) {
|
||||
if (hardware.getLocation() != null)
|
||||
if (currentLocationWiderThan(hardware.getLocation()))
|
||||
this.location = hardware.getLocation();
|
||||
this.minCores = getCores(hardware);
|
||||
this.minRam = hardware.getRam();
|
||||
return this;
|
||||
}
|
||||
|
||||
private boolean currentLocationWiderThan(Location location) {
|
||||
return this.location == null || (location != null && this.location.getScope().compareTo(location.getScope()) < 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public TemplateBuilder fromImage(Image image) {
|
||||
if (image.getLocation() != null)
|
||||
if (currentLocationWiderThan(image.getLocation()))
|
||||
this.location = image.getLocation();
|
||||
if (image.getOperatingSystem().getFamily() != null)
|
||||
this.osFamily = image.getOperatingSystem().getFamily();
|
||||
|
@ -830,8 +834,9 @@ public class TemplateBuilderImpl implements TemplateBuilder {
|
|||
@VisibleForTesting
|
||||
boolean nothingChangedExceptOptions() {
|
||||
return osFamily == null && location == null && imageId == null && hardwareId == null && osName == null
|
||||
&& osDescription == null && imageVersion == null && osVersion == null && osArch == null && os64Bit == null
|
||||
&& imageName == null && imageDescription == null && minCores == 0 && minRam == 0 && !biggest && !fastest;
|
||||
&& osDescription == null && imageVersion == null && osVersion == null && osArch == null
|
||||
&& os64Bit == null && imageName == null && imageDescription == null && minCores == 0 && minRam == 0
|
||||
&& !biggest && !fastest;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -845,10 +850,10 @@ public class TemplateBuilderImpl implements TemplateBuilder {
|
|||
@Override
|
||||
public String toString() {
|
||||
return "[biggest=" + biggest + ", fastest=" + fastest + ", imageName=" + imageName + ", imageDescription="
|
||||
+ imageDescription + ", imageId=" + imageId + ", imageVersion=" + imageVersion + ", location=" + location
|
||||
+ ", minCores=" + minCores + ", minRam=" + minRam + ", osFamily=" + osFamily + ", osName=" + osName
|
||||
+ ", osDescription=" + osDescription + ", osVersion=" + osVersion + ", osArch=" + osArch + ", os64Bit="
|
||||
+ os64Bit + ", hardwareId=" + hardwareId + "]";
|
||||
+ imageDescription + ", imageId=" + imageId + ", imageVersion=" + imageVersion + ", location="
|
||||
+ location + ", minCores=" + minCores + ", minRam=" + minRam + ", osFamily=" + osFamily + ", osName="
|
||||
+ osName + ", osDescription=" + osDescription + ", osVersion=" + osVersion + ", osArch=" + osArch
|
||||
+ ", os64Bit=" + os64Bit + ", hardwareId=" + hardwareId + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
|
@ -74,7 +74,9 @@ import org.jclouds.compute.strategy.DestroyNodeStrategy;
|
|||
import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
|
||||
import org.jclouds.compute.strategy.ListNodesStrategy;
|
||||
import org.jclouds.compute.strategy.RebootNodeStrategy;
|
||||
import org.jclouds.compute.strategy.ResumeNodeStrategy;
|
||||
import org.jclouds.compute.strategy.RunNodesAndAddToSetStrategy;
|
||||
import org.jclouds.compute.strategy.SuspendNodeStrategy;
|
||||
import org.jclouds.compute.util.ComputeUtils;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.domain.Location;
|
||||
|
@ -111,10 +113,13 @@ public class BaseComputeService implements ComputeService {
|
|||
protected final RunNodesAndAddToSetStrategy runNodesAndAddToSetStrategy;
|
||||
protected final RebootNodeStrategy rebootNodeStrategy;
|
||||
protected final DestroyNodeStrategy destroyNodeStrategy;
|
||||
protected final ResumeNodeStrategy resumeNodeStrategy;
|
||||
protected final SuspendNodeStrategy suspendNodeStrategy;
|
||||
protected final Provider<TemplateBuilder> templateBuilderProvider;
|
||||
protected final Provider<TemplateOptions> templateOptionsProvider;
|
||||
protected final Predicate<NodeMetadata> nodeRunning;
|
||||
protected final Predicate<NodeMetadata> nodeTerminated;
|
||||
protected final Predicate<NodeMetadata> nodeSuspended;
|
||||
protected final ComputeUtils utils;
|
||||
protected final Timeouts timeouts;
|
||||
protected final ExecutorService executor;
|
||||
|
@ -126,9 +131,11 @@ public class BaseComputeService implements ComputeService {
|
|||
@Memoized Supplier<Set<? extends Location>> locations, ListNodesStrategy listNodesStrategy,
|
||||
GetNodeMetadataStrategy getNodeMetadataStrategy, RunNodesAndAddToSetStrategy runNodesAndAddToSetStrategy,
|
||||
RebootNodeStrategy rebootNodeStrategy, DestroyNodeStrategy destroyNodeStrategy,
|
||||
ResumeNodeStrategy resumeNodeStrategy, SuspendNodeStrategy suspendNodeStrategy,
|
||||
Provider<TemplateBuilder> templateBuilderProvider, Provider<TemplateOptions> templateOptionsProvider,
|
||||
@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) {
|
||||
this.context = checkNotNull(context, "context");
|
||||
this.credentialStore = checkNotNull(credentialStore, "credentialStore");
|
||||
|
@ -139,11 +146,14 @@ public class BaseComputeService implements ComputeService {
|
|||
this.getNodeMetadataStrategy = checkNotNull(getNodeMetadataStrategy, "getNodeMetadataStrategy");
|
||||
this.runNodesAndAddToSetStrategy = checkNotNull(runNodesAndAddToSetStrategy, "runNodesAndAddToSetStrategy");
|
||||
this.rebootNodeStrategy = checkNotNull(rebootNodeStrategy, "rebootNodeStrategy");
|
||||
this.resumeNodeStrategy = checkNotNull(resumeNodeStrategy, "resumeNodeStrategy");
|
||||
this.suspendNodeStrategy = checkNotNull(suspendNodeStrategy, "suspendNodeStrategy");
|
||||
this.destroyNodeStrategy = checkNotNull(destroyNodeStrategy, "destroyNodeStrategy");
|
||||
this.templateBuilderProvider = checkNotNull(templateBuilderProvider, "templateBuilderProvider");
|
||||
this.templateOptionsProvider = checkNotNull(templateOptionsProvider, "templateOptionsProvider");
|
||||
this.nodeRunning = checkNotNull(nodeRunning, "nodeRunning");
|
||||
this.nodeTerminated = checkNotNull(nodeTerminated, "nodeTerminated");
|
||||
this.nodeSuspended = checkNotNull(nodeSuspended, "nodeSuspended");
|
||||
this.utils = checkNotNull(utils, "utils");
|
||||
this.timeouts = checkNotNull(timeouts, "timeouts");
|
||||
this.executor = checkNotNull(executor, "executor");
|
||||
|
@ -174,10 +184,10 @@ public class BaseComputeService implements ComputeService {
|
|||
Set<NodeMetadata> nodes = newHashSet();
|
||||
Map<NodeMetadata, Exception> badNodes = newLinkedHashMap();
|
||||
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()))
|
||||
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) {
|
||||
throw new RunNodesException(tag, count, template, nodes, executionExceptions, badNodes);
|
||||
}
|
||||
|
@ -227,7 +237,7 @@ public class BaseComputeService implements ComputeService {
|
|||
}, timeouts.nodeRunning, 1000, TimeUnit.MILLISECONDS);
|
||||
boolean successful = tester.apply(id) && (node.get() == null || nodeTerminated.apply(node.get()));
|
||||
if (successful)
|
||||
credentialStore.remove("node/" + id);
|
||||
credentialStore.remove("node#" + id);
|
||||
logger.debug("<< destroyed node(%s) success(%s)", id, successful);
|
||||
}
|
||||
|
||||
|
@ -357,6 +367,66 @@ public class BaseComputeService implements ComputeService {
|
|||
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}
|
||||
*/
|
||||
|
|
|
@ -26,14 +26,17 @@ import javax.inject.Singleton;
|
|||
|
||||
import org.jclouds.Constants;
|
||||
import org.jclouds.compute.Utils;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.crypto.Crypto;
|
||||
import org.jclouds.date.DateService;
|
||||
import org.jclouds.json.Json;
|
||||
import org.jclouds.logging.Logger.LoggerFactory;
|
||||
import org.jclouds.rest.HttpAsyncClient;
|
||||
import org.jclouds.rest.HttpClient;
|
||||
import org.jclouds.ssh.SshClient;
|
||||
import org.jclouds.ssh.SshClient.Factory;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
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 {
|
||||
@Inject(optional = true)
|
||||
private Factory sshFactory;
|
||||
private final Function<NodeMetadata, SshClient> sshForNode;
|
||||
|
||||
@Inject
|
||||
UtilsImpl(Json json, HttpClient simpleClient, HttpAsyncClient simpleAsyncClient,
|
||||
Crypto encryption, DateService date,
|
||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService userThreads,
|
||||
@Named(Constants.PROPERTY_IO_WORKER_THREADS) ExecutorService ioThreads,
|
||||
LoggerFactory loggerFactory) {
|
||||
super(json, simpleClient, simpleAsyncClient, encryption, date, userThreads, ioThreads,
|
||||
loggerFactory);
|
||||
UtilsImpl(Json json, HttpClient simpleClient, HttpAsyncClient simpleAsyncClient, Crypto encryption,
|
||||
DateService date, @Named(Constants.PROPERTY_USER_THREADS) ExecutorService userThreads,
|
||||
@Named(Constants.PROPERTY_IO_WORKER_THREADS) ExecutorService ioThreads, LoggerFactory loggerFactory,
|
||||
Function<NodeMetadata, SshClient> sshForNode) {
|
||||
super(json, simpleClient, simpleAsyncClient, encryption, date, userThreads, ioThreads, loggerFactory);
|
||||
this.sshForNode = sshForNode;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -65,4 +68,9 @@ public class UtilsImpl extends org.jclouds.rest.internal.UtilsImpl implements Ut
|
|||
return sshFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Function<NodeMetadata, SshClient> sshForNode() {
|
||||
return sshForNode;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
|
@ -19,52 +19,24 @@
|
|||
|
||||
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.
|
||||
* Tests to see if a node is running.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class NodeRunning implements Predicate<NodeMetadata> {
|
||||
|
||||
private final ComputeService client;
|
||||
|
||||
@Resource
|
||||
protected Logger logger = Logger.NULL;
|
||||
public class NodeRunning extends NodePresentAndInIntendedState {
|
||||
|
||||
@Inject
|
||||
public NodeRunning(ComputeService client) {
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
public boolean apply(NodeMetadata node) {
|
||||
logger.trace("looking for state on node %s", checkNotNull(node, "node"));
|
||||
node = refresh(node);
|
||||
if (node == null)
|
||||
return false;
|
||||
logger.trace("%s: looking for node state %s: currently: %s",
|
||||
node.getId(), NodeState.RUNNING, node.getState());
|
||||
if (node.getState() == NodeState.ERROR)
|
||||
throw new IllegalStateException("node " + node.getId()
|
||||
+ " in location " + node.getLocation() + " is in error state");
|
||||
return node.getState() == NodeState.RUNNING;
|
||||
}
|
||||
|
||||
private NodeMetadata refresh(NodeMetadata node) {
|
||||
return client.getNodeMetadata(node.getId());
|
||||
super(NodeState.RUNNING, client);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,30 +17,26 @@
|
|||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.gogrid.util;
|
||||
package org.jclouds.compute.predicates;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.compute.ComputeService;
|
||||
import org.jclouds.compute.domain.NodeState;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
|
||||
/**
|
||||
* @author Oleksiy Yarmula
|
||||
*/
|
||||
public class GoGridUtils {
|
||||
|
||||
/**
|
||||
* 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
|
||||
* Tests to see if a node is suspended.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public static String parseStringByPatternAndGetNthMatchGroup(String stringToParse, Pattern pattern, int nthGroup) {
|
||||
Matcher osVersionMatcher = pattern.matcher(stringToParse);
|
||||
if (osVersionMatcher.find()) {
|
||||
return osVersionMatcher.group(nthGroup);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@Singleton
|
||||
public class NodeSuspended extends NodePresentAndInIntendedState {
|
||||
|
||||
@Inject
|
||||
public NodeSuspended(ComputeService client) {
|
||||
super(NodeState.SUSPENDED, client);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -34,6 +34,7 @@ public interface ComputeServiceConstants {
|
|||
public static final String LOCAL_PARTITION_GB_PATTERN = "disk_drive/%s/gb";
|
||||
public static final String PROPERTY_TIMEOUT_NODE_TERMINATED = "jclouds.compute.timeout.node-terminated";
|
||||
public static final String PROPERTY_TIMEOUT_NODE_RUNNING = "jclouds.compute.timeout.node-running";
|
||||
public static final String PROPERTY_TIMEOUT_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_PORT_OPEN = "jclouds.compute.timeout.port-open";
|
||||
/**
|
||||
|
@ -52,6 +53,10 @@ public interface ComputeServiceConstants {
|
|||
@Named(PROPERTY_TIMEOUT_NODE_RUNNING)
|
||||
public long nodeRunning = 1200 * 1000;
|
||||
|
||||
@Inject(optional = true)
|
||||
@Named(PROPERTY_TIMEOUT_NODE_SUSPENDED)
|
||||
public long nodeSuspended = 30 * 1000;
|
||||
|
||||
@Inject(optional = true)
|
||||
@Named(PROPERTY_TIMEOUT_SCRIPT_COMPLETE)
|
||||
public long scriptComplete = 600 * 1000;
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
|
@ -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);
|
||||
|
||||
}
|
|
@ -41,6 +41,8 @@ import org.jclouds.compute.strategy.DestroyNodeStrategy;
|
|||
import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
|
||||
import org.jclouds.compute.strategy.ListNodesStrategy;
|
||||
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.logging.Logger;
|
||||
|
||||
|
@ -54,7 +56,7 @@ import com.google.common.collect.Iterables;
|
|||
*/
|
||||
@Singleton
|
||||
public class AdaptingComputeServiceStrategies<N, H, I, L> implements AddNodeWithTagStrategy, DestroyNodeStrategy,
|
||||
GetNodeMetadataStrategy, ListNodesStrategy, RebootNodeStrategy {
|
||||
GetNodeMetadataStrategy, ListNodesStrategy, RebootNodeStrategy, ResumeNodeStrategy, SuspendNodeStrategy {
|
||||
@Resource
|
||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||
protected Logger logger = Logger.NULL;
|
||||
|
@ -101,6 +103,34 @@ public class AdaptingComputeServiceStrategies<N, H, I, L> implements AddNodeWith
|
|||
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
|
||||
public NodeMetadata destroyNode(String id) {
|
||||
|
||||
|
|
|
@ -91,8 +91,8 @@ public class StubComputeServiceAdapter implements JCloudsNativeComputeServiceAda
|
|||
builder.privateAddresses(ImmutableSet.<String> of(privateIpPrefix + id));
|
||||
builder.credentials(new Credentials("root", passwordPrefix + id));
|
||||
NodeMetadata node = builder.build();
|
||||
credentialStore.put("node#" + node.getId(), node.getCredentials());
|
||||
nodes.put(node.getId(), node);
|
||||
credentialStore.put(node.getId(), node.getCredentials());
|
||||
StubComputeServiceDependenciesModule.setState(node, NodeState.RUNNING, 100);
|
||||
return node;
|
||||
}
|
||||
|
@ -100,8 +100,8 @@ public class StubComputeServiceAdapter implements JCloudsNativeComputeServiceAda
|
|||
@Override
|
||||
public Iterable<Hardware> listHardwareProfiles() {
|
||||
return ImmutableSet.<Hardware> of(StubComputeServiceDependenciesModule.stub("small", 1, 1740, 160),
|
||||
StubComputeServiceDependenciesModule.stub("medium", 4, 7680, 850),
|
||||
StubComputeServiceDependenciesModule.stub("large", 8, 15360, 1690));
|
||||
StubComputeServiceDependenciesModule.stub("medium", 4, 7680, 850), StubComputeServiceDependenciesModule
|
||||
.stub("large", 8, 15360, 1690));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -109,29 +109,15 @@ public class StubComputeServiceAdapter implements JCloudsNativeComputeServiceAda
|
|||
Location zone = location.get().getParent();
|
||||
String parentId = zone.getId();
|
||||
Credentials defaultCredentials = new Credentials("root", null);
|
||||
return ImmutableSet
|
||||
.<Image> of(
|
||||
new ImageBuilder()
|
||||
.providerId("1")
|
||||
.name(OsFamily.UBUNTU.name())
|
||||
.id(parentId + "/1")
|
||||
.location(zone)
|
||||
.operatingSystem(
|
||||
return ImmutableSet.<Image> of(new ImageBuilder().providerId("1").name(OsFamily.UBUNTU.name())
|
||||
.id(parentId + "/1").location(zone).operatingSystem(
|
||||
new OperatingSystem(OsFamily.UBUNTU, "ubuntu 32", null, "X86_32", "ubuntu 32", false))
|
||||
.description("stub ubuntu 32").defaultCredentials(defaultCredentials).build(), //
|
||||
new ImageBuilder()
|
||||
.providerId("2")
|
||||
.name(OsFamily.UBUNTU.name())
|
||||
.id(parentId + "/2")
|
||||
.location(zone)
|
||||
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(), //
|
||||
new ImageBuilder()
|
||||
.providerId("3")
|
||||
.name(OsFamily.CENTOS.name())
|
||||
.id(parentId + "/3")
|
||||
.location(zone)
|
||||
new ImageBuilder().providerId("3").name(OsFamily.CENTOS.name()).id(parentId + "/3").location(zone)
|
||||
.operatingSystem(
|
||||
new OperatingSystem(OsFamily.CENTOS, "centos 64", null, "X86_64", "centos 64", true))
|
||||
.description("stub centos 64").defaultCredentials(defaultCredentials).build() //
|
||||
|
@ -189,4 +175,30 @@ public class StubComputeServiceAdapter implements JCloudsNativeComputeServiceAda
|
|||
StubComputeServiceDependenciesModule.setState(node, NodeState.PENDING, 0);
|
||||
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);
|
||||
}
|
||||
}
|
|
@ -19,15 +19,8 @@
|
|||
|
||||
package org.jclouds.compute.stub.config;
|
||||
|
||||
import org.jclouds.compute.ComputeServiceAdapter;
|
||||
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.domain.Location;
|
||||
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -43,8 +36,6 @@ public class StubComputeServiceContextModule extends JCloudsNativeStandaloneComp
|
|||
@Override
|
||||
protected void configure() {
|
||||
install(new StubComputeServiceDependenciesModule());
|
||||
bind(new TypeLiteral<ComputeServiceAdapter<NodeMetadata, Hardware, Image, Location>>() {
|
||||
}).to(StubComputeServiceAdapter.class);
|
||||
super.configure();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,10 +19,15 @@
|
|||
|
||||
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.collect.Iterables.concat;
|
||||
import static com.google.common.collect.Iterables.filter;
|
||||
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.util.Utils.getSupportedProvidersOfType;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Formatter;
|
||||
|
@ -33,6 +38,7 @@ import java.util.concurrent.Callable;
|
|||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
||||
import org.jclouds.compute.ComputeServiceContextBuilder;
|
||||
import org.jclouds.compute.domain.ComputeMetadata;
|
||||
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.Processor;
|
||||
import org.jclouds.compute.domain.Volume;
|
||||
import org.jclouds.compute.predicates.RetryIfSocketNotYetOpen;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.net.IPSocket;
|
||||
import org.jclouds.scriptbuilder.domain.Statement;
|
||||
import org.jclouds.scriptbuilder.domain.Statements;
|
||||
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.collect.ImmutableMap;
|
||||
|
||||
|
@ -212,13 +220,33 @@ public class ComputeServiceUtils {
|
|||
void setConnection(SshClient ssh, Logger logger);
|
||||
}
|
||||
|
||||
public static boolean isKeyAuth(NodeMetadata createdNode) {
|
||||
return createdNode.getCredentials().credential != null
|
||||
&& createdNode.getCredentials().credential.startsWith("-----BEGIN RSA PRIVATE KEY-----");
|
||||
public static Iterable<String> getSupportedProviders() {
|
||||
return getSupportedProvidersOfType(ComputeServiceContextBuilder.class);
|
||||
}
|
||||
|
||||
public static Iterable<String> getSupportedProviders() {
|
||||
return Utils.getSupportedProvidersOfType(ComputeServiceContextBuilder.class);
|
||||
public static IPSocket findReachableSocketOnNode(RetryIfSocketNotYetOpen socketTester, final NodeMetadata node,
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -19,9 +19,12 @@
|
|||
|
||||
package org.jclouds.compute.util;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
import static org.jclouds.compute.util.ComputeServiceUtils.isKeyAuth;
|
||||
import static com.google.common.base.Throwables.getRootCause;
|
||||
import static com.google.common.base.Throwables.propagate;
|
||||
import static com.google.common.collect.Iterables.size;
|
||||
import static com.google.common.collect.Lists.newArrayList;
|
||||
import static com.google.common.collect.Maps.newHashMap;
|
||||
import static org.jclouds.compute.util.ComputeServiceUtils.findReachableSocketOnNode;
|
||||
import static org.jclouds.concurrent.FutureIterables.awaitCompletion;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -31,11 +34,11 @@ import java.util.concurrent.Callable;
|
|||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Provider;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.Constants;
|
||||
|
@ -45,14 +48,13 @@ import org.jclouds.compute.domain.NodeMetadata;
|
|||
import org.jclouds.compute.domain.NodeMetadataBuilder;
|
||||
import org.jclouds.compute.options.RunScriptOptions;
|
||||
import org.jclouds.compute.options.TemplateOptions;
|
||||
import org.jclouds.compute.predicates.RetryIfSocketNotYetOpen;
|
||||
import org.jclouds.compute.predicates.ScriptStatusReturnsZero.CommandUsingClient;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants.Timeouts;
|
||||
import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
|
||||
import org.jclouds.compute.util.ComputeServiceUtils.SshCallable;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.net.IPSocket;
|
||||
import org.jclouds.predicates.RetryablePredicate;
|
||||
import org.jclouds.scriptbuilder.domain.AuthorizeRSAPublicKey;
|
||||
import org.jclouds.scriptbuilder.domain.InstallRSAPrivateKey;
|
||||
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.SshClient;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
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;
|
||||
|
||||
/**
|
||||
|
@ -76,20 +75,20 @@ public class ComputeUtils {
|
|||
@Resource
|
||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||
protected Logger logger = Logger.NULL;
|
||||
@Inject(optional = true)
|
||||
protected SshClient.Factory sshFactory;
|
||||
protected final Function<NodeMetadata, SshClient> sshFactory;
|
||||
protected final Predicate<CommandUsingClient> runScriptNotRunning;
|
||||
protected final Predicate<IPSocket> socketTester;
|
||||
protected final Provider<RetryIfSocketNotYetOpen> socketTester;
|
||||
protected final ExecutorService executor;
|
||||
protected final Predicate<NodeMetadata> nodeRunning;
|
||||
protected final GetNodeMetadataStrategy getNode;
|
||||
protected final Timeouts timeouts;
|
||||
|
||||
@Inject
|
||||
public ComputeUtils(Predicate<IPSocket> socketTester,
|
||||
public ComputeUtils(Provider<RetryIfSocketNotYetOpen> socketTester, Function<NodeMetadata, SshClient> sshFactory,
|
||||
@Named("SCRIPT_COMPLETE") Predicate<CommandUsingClient> runScriptNotRunning, GetNodeMetadataStrategy getNode,
|
||||
Timeouts timeouts, @Named("NODE_RUNNING") Predicate<NodeMetadata> nodeRunning,
|
||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) {
|
||||
this.sshFactory = sshFactory;
|
||||
this.nodeRunning = nodeRunning;
|
||||
this.timeouts = timeouts;
|
||||
this.getNode = getNode;
|
||||
|
@ -101,7 +100,7 @@ public class ComputeUtils {
|
|||
public Map<?, Future<Void>> runOptionsOnNodesAndAddToGoodSetOrPutExceptionIntoBadMap(final TemplateOptions options,
|
||||
Iterable<NodeMetadata> runningNodes, final Set<NodeMetadata> goodNodes,
|
||||
final Map<NodeMetadata, Exception> badNodes) {
|
||||
Map<NodeMetadata, Future<Void>> responses = Maps.newHashMap();
|
||||
Map<NodeMetadata, Future<Void>> responses = newHashMap();
|
||||
for (final NodeMetadata node : runningNodes) {
|
||||
responses.put(node, executor.submit(runOptionsOnNodeAndAddToGoodSetOrPutExceptionIntoBadMap(node, badNodes,
|
||||
goodNodes, options)));
|
||||
|
@ -119,8 +118,7 @@ public class ComputeUtils {
|
|||
logger.debug("<< options applied node(%s)", node1.getId());
|
||||
goodNodes.add(node1);
|
||||
} catch (Exception e) {
|
||||
logger.error(e, "<< problem applying options to node(%s): ", node.getId(), Throwables.getRootCause(e)
|
||||
.getMessage());
|
||||
logger.error(e, "<< problem applying options to node(%s): ", node.getId(), getRootCause(e).getMessage());
|
||||
badNodes.put(node, e);
|
||||
}
|
||||
return null;
|
||||
|
@ -133,17 +131,17 @@ public class ComputeUtils {
|
|||
return node;
|
||||
|
||||
if (nodeRunning.apply(node))
|
||||
node = NodeMetadataBuilder.fromNodeMetadata(getNode.getNode(node.getId()))
|
||||
.credentials(node.getCredentials()).build();
|
||||
node = NodeMetadataBuilder.fromNodeMetadata(getNode.getNode(node.getId())).credentials(node.getCredentials())
|
||||
.build();
|
||||
else
|
||||
throw new IllegalStateException(String.format(
|
||||
"node didn't achieve the state running on node %s within %d seconds, final state: %s", node.getId(),
|
||||
timeouts.nodeRunning / 1000, node.getState()));
|
||||
List<Statement> bootstrap = Lists.newArrayList();
|
||||
if (options.getRunScript() != null)
|
||||
bootstrap.add(options.getRunScript());
|
||||
List<Statement> bootstrap = newArrayList();
|
||||
if (options.getPublicKey() != null)
|
||||
bootstrap.add(new AuthorizeRSAPublicKey(options.getPublicKey()));
|
||||
if (options.getRunScript() != null)
|
||||
bootstrap.add(options.getRunScript());
|
||||
if (options.getPrivateKey() != null)
|
||||
bootstrap.add(new InstallRSAPrivateKey(options.getPrivateKey()));
|
||||
if (bootstrap.size() >= 1)
|
||||
|
@ -151,14 +149,10 @@ public class ComputeUtils {
|
|||
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) {
|
||||
InitAndStartScriptOnNode callable = generateScript(node, runScript, options);
|
||||
ExecResponse response;
|
||||
SshClient ssh = createSshClientOncePortIsListeningOnNode(node);
|
||||
SshClient ssh = sshFactory.apply(node);
|
||||
try {
|
||||
ssh.connect();
|
||||
callable.setConnection(ssh, logger);
|
||||
|
@ -168,24 +162,11 @@ public class ComputeUtils {
|
|||
ssh.disconnect();
|
||||
}
|
||||
if (options.getPort() > 0) {
|
||||
checkNodeHasPublicIps(node);
|
||||
blockUntilPortIsListeningOnPublicIp(options.getPort(), options.getSeconds(),
|
||||
Iterables.get(node.getPublicAddresses(), 0));
|
||||
findReachableSocketOnNode(socketTester.get().seconds(options.getSeconds()), node, options.getPort());
|
||||
}
|
||||
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) {
|
||||
return options.shouldBlockOnComplete() ? new RunScriptOnNode(runScriptNotRunning, node, options.getTaskName(),
|
||||
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,
|
||||
@Nullable SshCallable<?> last) {
|
||||
checkState(this.sshFactory != null, "runScript requested, but no SshModule configured");
|
||||
checkNodeHasPublicIps(node);
|
||||
checkNotNull(node.getCredentials(), "credentials for node " + node.getName());
|
||||
checkNotNull(node.getCredentials().credential, "credentials.credential for node " + node.getName());
|
||||
SshClient ssh = createSshClientOncePortIsListeningOnNode(node);
|
||||
SshClient ssh = sshFactory.apply(node);
|
||||
try {
|
||||
ssh.connect();
|
||||
return runTasksUsingSshClient(parallel, last, ssh);
|
||||
|
@ -210,8 +187,8 @@ public class ComputeUtils {
|
|||
|
||||
private Map<SshCallable<?>, ?> runTasksUsingSshClient(Iterable<SshCallable<?>> parallel, SshCallable<?> last,
|
||||
SshClient ssh) {
|
||||
Map<SshCallable<?>, Object> responses = Maps.newHashMap();
|
||||
if (Iterables.size(parallel) > 0) {
|
||||
Map<SshCallable<?>, Object> responses = newHashMap();
|
||||
if (size(parallel) > 0) {
|
||||
responses.putAll(runCallablesUsingSshClient(parallel, ssh));
|
||||
}
|
||||
if (last != null) {
|
||||
|
@ -219,24 +196,15 @@ public class ComputeUtils {
|
|||
try {
|
||||
responses.put(last, last.call());
|
||||
} catch (Exception e) {
|
||||
Throwables.propagate(e);
|
||||
propagate(e);
|
||||
}
|
||||
}
|
||||
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
|
||||
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) {
|
||||
callable.setConnection(ssh, logger);
|
||||
|
@ -252,14 +220,14 @@ public class ComputeUtils {
|
|||
|
||||
@SuppressWarnings("unchecked")
|
||||
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()) {
|
||||
try {
|
||||
actualResponses.put(entry.getKey(), (T) entry.getValue().get());
|
||||
} catch (InterruptedException e) {
|
||||
throw Throwables.propagate(e);
|
||||
throw propagate(e);
|
||||
} catch (ExecutionException e) {
|
||||
throw Throwables.propagate(e);
|
||||
throw propagate(e);
|
||||
}
|
||||
}
|
||||
return actualResponses;
|
||||
|
|
|
@ -22,6 +22,7 @@ package org.jclouds.ssh;
|
|||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.PreDestroy;
|
||||
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.io.Payload;
|
||||
import org.jclouds.net.IPSocket;
|
||||
|
||||
|
@ -31,9 +32,24 @@ import org.jclouds.net.IPSocket;
|
|||
public interface SshClient {
|
||||
|
||||
interface Factory {
|
||||
/**
|
||||
* please use {@link Factory#create(IPSocket, Credentials)}
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Deprecated
|
||||
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, Credentials credentials);
|
||||
|
||||
}
|
||||
|
||||
String getUsername();
|
||||
|
|
|
@ -74,6 +74,7 @@ import org.jclouds.net.IPSocket;
|
|||
import org.jclouds.predicates.RetryablePredicate;
|
||||
import org.jclouds.predicates.SocketOpen;
|
||||
import org.jclouds.rest.AuthorizationException;
|
||||
import org.jclouds.scriptbuilder.domain.OsFamily;
|
||||
import org.jclouds.ssh.ExecResponse;
|
||||
import org.jclouds.ssh.SshClient;
|
||||
import org.jclouds.ssh.SshException;
|
||||
|
@ -82,7 +83,9 @@ import org.testng.annotations.BeforeGroups;
|
|||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Module;
|
||||
|
||||
|
@ -158,8 +161,8 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
if (context != null)
|
||||
context.close();
|
||||
Properties props = setupProperties();
|
||||
context = new ComputeServiceContextFactory().createContext(provider,
|
||||
ImmutableSet.of(new Log4JLoggingModule(), getSshModule()), props);
|
||||
context = new ComputeServiceContextFactory().createContext(provider, ImmutableSet.of(new Log4JLoggingModule(),
|
||||
getSshModule()), props);
|
||||
client = context.getComputeService();
|
||||
}
|
||||
|
||||
|
@ -170,8 +173,8 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
public void testCorrectAuthException() throws Exception {
|
||||
ComputeServiceContext context = null;
|
||||
try {
|
||||
context = new ComputeServiceContextFactory().createContext(provider, "MOMMA", "MIA",
|
||||
ImmutableSet.<Module> of(new Log4JLoggingModule()));
|
||||
context = new ComputeServiceContextFactory().createContext(provider, "MOMMA", "MIA", ImmutableSet
|
||||
.<Module> of(new Log4JLoggingModule()));
|
||||
context.getComputeService().listNodes();
|
||||
} catch (AuthorizationException e) {
|
||||
throw e;
|
||||
|
@ -236,37 +239,11 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
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) {
|
||||
ComputeTestUtils.checkHttpGet(context.utils().http(), node, 8080);
|
||||
}
|
||||
|
||||
@Test(enabled = true, dependsOnMethods = "testCreateAndRunAService")
|
||||
@Test(enabled = true, dependsOnMethods = "testCompareSizes")
|
||||
public void testCreateTwoNodesWithRunScript() throws Exception {
|
||||
try {
|
||||
client.destroyNodesMatching(withTag(tag));
|
||||
|
@ -299,7 +276,7 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
template = buildTemplate(client.templateBuilder());
|
||||
|
||||
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) {
|
||||
|
@ -310,8 +287,8 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
protected void checkOsMatchesTemplate(NodeMetadata node) {
|
||||
if (node.getOperatingSystem() != null)
|
||||
assert node.getOperatingSystem().getFamily().equals(template.getImage().getOperatingSystem().getFamily()) : String
|
||||
.format("expecting family %s but got %s", template.getImage().getOperatingSystem().getFamily(),
|
||||
node.getOperatingSystem());
|
||||
.format("expecting family %s but got %s", template.getImage().getOperatingSystem().getFamily(), node
|
||||
.getOperatingSystem());
|
||||
}
|
||||
|
||||
void assertLocationSameOrChild(Location test, Location expected) {
|
||||
|
@ -339,14 +316,14 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
public void testCredentialsCache() throws Exception {
|
||||
initializeContextAndClient();
|
||||
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,
|
||||
Credentials creds) throws RunScriptOnNodesException {
|
||||
try {
|
||||
return client.runScriptOnNodesMatching(runningWithTag(tag), newStringPayload(buildScript(os)),
|
||||
overrideCredentialsWith(creds).nameTask("runScriptWithCreds"));
|
||||
return client.runScriptOnNodesMatching(runningWithTag(tag), newStringPayload(buildScript(os).render(
|
||||
OsFamily.UNIX)), overrideCredentialsWith(creds).nameTask("runScriptWithCreds"));
|
||||
} catch (SshException e) {
|
||||
throw e;
|
||||
}
|
||||
|
@ -358,7 +335,8 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
assertNotNull(node.getTag());
|
||||
assertEquals(node.getTag(), tag);
|
||||
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;
|
||||
assertNotNull(node.getCredentials());
|
||||
if (node.getCredentials().identity != null) {
|
||||
|
@ -375,8 +353,8 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
|
||||
@Test(enabled = true, dependsOnMethods = "testCreateAnotherNodeWithANewContextToEnsureSharedMemIsntRequired")
|
||||
public void testGet() throws Exception {
|
||||
Map<String, ? extends NodeMetadata> metadataMap = newLinkedHashMap(uniqueIndex(
|
||||
filter(client.listNodesDetailsMatching(all()), and(withTag(tag), not(TERMINATED))),
|
||||
Map<String, ? extends NodeMetadata> metadataMap = newLinkedHashMap(uniqueIndex(filter(client
|
||||
.listNodesDetailsMatching(all()), and(withTag(tag), not(TERMINATED))),
|
||||
new Function<NodeMetadata, String>() {
|
||||
|
||||
@Override
|
||||
|
@ -412,13 +390,25 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
testGet();
|
||||
}
|
||||
|
||||
@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";
|
||||
@Test(enabled = true, dependsOnMethods = "testReboot")
|
||||
public void testSuspendResume() throws Exception {
|
||||
client.suspendNodesMatching(withTag(tag));
|
||||
Set<? extends NodeMetadata> stoppedNodes = refreshNodes();
|
||||
|
||||
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 {
|
||||
for (ComputeMetadata node : client.listNodes()) {
|
||||
assert node.getProviderId() != null;
|
||||
|
@ -427,6 +417,7 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Test(enabled = true, dependsOnMethods = "testSuspendResume")
|
||||
public void testGetNodesWithDetails() throws Exception {
|
||||
for (NodeMetadata node : client.listNodesDetailsMatching(all())) {
|
||||
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 {
|
||||
for (Image image : client.listImages()) {
|
||||
assert image.getProviderId() != null : image;
|
||||
|
@ -487,7 +524,6 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Test(enabled = true, dependsOnMethods = "testGet")
|
||||
public void testOptionToNotBlock() throws Exception {
|
||||
String tag = this.tag + "block";
|
||||
try {
|
||||
|
@ -564,26 +600,14 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
}
|
||||
|
||||
protected void doCheckJavaIsInstalledViaSsh(NodeMetadata node) throws IOException {
|
||||
IPSocket socket = new IPSocket(get(node.getPublicAddresses(), 0), 22);
|
||||
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());
|
||||
SshClient ssh = context.utils().sshForNode().apply(node);
|
||||
try {
|
||||
ssh.connect();
|
||||
ExecResponse hello = ssh.exec("echo hello");
|
||||
assertEquals(hello.getOutput().trim(), "hello");
|
||||
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 {
|
||||
if (ssh != null)
|
||||
ssh.disconnect();
|
||||
|
@ -593,11 +617,7 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
@AfterTest
|
||||
protected void cleanup() throws InterruptedException, ExecutionException, TimeoutException {
|
||||
if (nodes != null) {
|
||||
client.destroyNodesMatching(withTag(tag));
|
||||
for (NodeMetadata node : filter(client.listNodesDetailsMatching(all()), withTag(tag))) {
|
||||
assert node.getState() == NodeState.TERMINATED : node;
|
||||
assertEquals(context.getCredentialStore().get(node.getId()), null);
|
||||
}
|
||||
testDestroyNodes();
|
||||
}
|
||||
context.close();
|
||||
}
|
||||
|
|
|
@ -19,7 +19,11 @@
|
|||
|
||||
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.testng.Assert.assertEquals;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
|
@ -27,18 +31,15 @@ import java.lang.reflect.UndeclaredThrowableException;
|
|||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
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.OperatingSystem;
|
||||
import org.jclouds.compute.predicates.OperatingSystemPredicates;
|
||||
import org.jclouds.rest.HttpClient;
|
||||
import org.jclouds.scriptbuilder.domain.Statement;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.io.Files;
|
||||
import static com.google.common.collect.Iterables.get;
|
||||
|
||||
/**
|
||||
* utilities helpful in testing compute providers
|
||||
|
@ -46,15 +47,8 @@ import static com.google.common.collect.Iterables.get;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
public class ComputeTestUtils {
|
||||
public static String buildScript(OperatingSystem os) {
|
||||
if (OperatingSystemPredicates.supportsApt().apply(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 Statement buildScript(OperatingSystem os) {
|
||||
return RunScriptData.installJavaAndCurl(os);
|
||||
}
|
||||
|
||||
public static Map<String, String> setupKeyPair() throws FileNotFoundException, IOException {
|
||||
|
@ -67,8 +61,8 @@ public class ComputeTestUtils {
|
|||
checkSecretKeyFile(secretKeyFile);
|
||||
String secret = Files.toString(new File(secretKeyFile), Charsets.UTF_8);
|
||||
assert secret.startsWith("-----BEGIN RSA PRIVATE KEY-----") : "invalid key:\n" + secret;
|
||||
return ImmutableMap.<String, String> of("private", secret, "public",
|
||||
Files.toString(new File(secretKeyFile + ".pub"), Charsets.UTF_8));
|
||||
return ImmutableMap.<String, String> of("private", secret, "public", Files.toString(new File(secretKeyFile
|
||||
+ ".pub"), Charsets.UTF_8));
|
||||
}
|
||||
|
||||
public static void checkSecretKeyFile(String secretKeyFile) throws FileNotFoundException {
|
||||
|
|
|
@ -19,9 +19,11 @@
|
|||
|
||||
package org.jclouds.compute;
|
||||
|
||||
import static org.jclouds.compute.util.ComputeServiceUtils.execHttpResponse;
|
||||
import static org.jclouds.compute.util.ComputeServiceUtils.extractTargzIntoDirectory;
|
||||
import static org.jclouds.scriptbuilder.domain.Statements.exec;
|
||||
import static org.jclouds.scriptbuilder.domain.Statements.interpret;
|
||||
import static org.jclouds.scriptbuilder.domain.Statements.newStatementList;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
|
@ -43,7 +45,7 @@ public class RunScriptData {
|
|||
|
||||
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))
|
||||
return APT_RUN_SCRIPT;
|
||||
else if (OperatingSystemPredicates.supportsYum().apply(os))
|
||||
|
@ -61,46 +63,58 @@ public class RunScriptData {
|
|||
jbossHome,
|
||||
jbossHome,
|
||||
envVariables,
|
||||
ImmutableList.<Statement> of(
|
||||
new AuthorizeRSAPublicKey(publicKey),
|
||||
exec(installJavaAndCurl(os)),
|
||||
exec("rm -rf /var/cache/apt /usr/lib/vmware-tools"),// jeos hasn't enough room!
|
||||
ImmutableList
|
||||
.<Statement> of(
|
||||
new AuthorizeRSAPublicKey(publicKey),//
|
||||
installJavaAndCurl(os),//
|
||||
// just in case iptables are being used, try to open 8080
|
||||
exec("iptables -I INPUT 1 -p tcp --dport 8080 -j ACCEPT"),//
|
||||
// TODO gogrid rules only allow ports 22, 3389, 80 and 443.
|
||||
// the above rule will be ignored, so we have to apply this
|
||||
// directly
|
||||
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)),
|
||||
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;
|
||||
}
|
||||
|
||||
public static final String APT_RUN_SCRIPT = new StringBuilder()//
|
||||
public static String aptInstall = "apt-get install -f -y -qq --force-yes";
|
||||
|
||||
public static String installAfterUpdatingIfNotPresent(String cmd) {
|
||||
String aptInstallCmd = aptInstall + " " + cmd;
|
||||
return String.format("which %s || (%s || (apt-get update && %s))", cmd, aptInstallCmd, aptInstallCmd);
|
||||
}
|
||||
|
||||
public static final Statement APT_RUN_SCRIPT = newStatementList(//
|
||||
exec(installAfterUpdatingIfNotPresent("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("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();
|
||||
// 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 String YUM_RUN_SCRIPT = new StringBuilder()
|
||||
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 \"[jdkrepo]\" >> /etc/yum.repos.d/CentOS-Base.repo\n") //
|
||||
.append("echo \"name=jdkrepository\" >> /etc/yum.repos.d/CentOS-Base.repo\n") //
|
||||
.append(
|
||||
"echo \"baseurl=http://ec2-us-east-mirror.rightscale.com/epel/5/i386/\" >> /etc/yum.repos.d/CentOS-Base.repo\n")//
|
||||
.append("echo \"enabled=1\" >> /etc/yum.repos.d/CentOS-Base.repo\n")//
|
||||
.append("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();
|
||||
.append("echo \"export PATH=\\\"\\$JAVA_HOME/bin/:\\$PATH\\\"\" >> /root/.bashrc")//
|
||||
.toString()));
|
||||
|
||||
public static final String ZYPPER_RUN_SCRIPT = new StringBuilder()//
|
||||
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();
|
||||
.toString());
|
||||
}
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
|
||||
package org.jclouds.compute;
|
||||
|
||||
import static org.easymock.EasyMock.aryEq;
|
||||
import static org.easymock.EasyMock.eq;
|
||||
import static org.easymock.EasyMock.expect;
|
||||
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.OsFamily;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.io.Payload;
|
||||
import org.jclouds.net.IPSocket;
|
||||
import org.jclouds.predicates.RetryablePredicate;
|
||||
|
@ -120,15 +120,14 @@ public class StubComputeServiceIntegrationTest extends BaseComputeServiceLiveTes
|
|||
SshClient client4 = createMock(SshClient.class);
|
||||
SshClient client5 = createMock(SshClient.class);
|
||||
|
||||
expect(factory.create(new IPSocket("144.175.1.1", 22), "root", "password1")).andReturn(client1)
|
||||
.atLeastOnce();
|
||||
expect(factory.create(new IPSocket("144.175.1.1", 22), new Credentials("root", "password1"))).andReturn(
|
||||
client1);
|
||||
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(
|
||||
client2).times(2);
|
||||
expect(factory.create(new IPSocket("144.175.1.2", 22), new Credentials("root", "romeo"))).andThrow(
|
||||
new SshException("Auth fail"));
|
||||
expect(factory.create(new IPSocket("144.175.1.2", 22), "root", "password2")).andReturn(client2)
|
||||
.atLeastOnce();
|
||||
|
||||
client2.connect();
|
||||
try {
|
||||
runScript(client2, "runScriptWithCreds", Utils.toStringAndClose(StubComputeServiceIntegrationTest.class
|
||||
|
@ -138,32 +137,32 @@ public class StubComputeServiceIntegrationTest extends BaseComputeServiceLiveTes
|
|||
}
|
||||
client2.disconnect();
|
||||
|
||||
expect(factory.create(new IPSocket("144.175.1.3", 22), "root", "password3")).andReturn(client3)
|
||||
.atLeastOnce();
|
||||
expect(factory.create(new IPSocket("144.175.1.4", 22), "root", "password4")).andReturn(client4)
|
||||
.atLeastOnce();
|
||||
expect(factory.create(new IPSocket("144.175.1.5", 22), "root", "password5")).andReturn(client5)
|
||||
.atLeastOnce();
|
||||
expect(factory.create(new IPSocket("144.175.1.3", 22), new Credentials("root", "password3"))).andReturn(
|
||||
client3).times(2);
|
||||
expect(factory.create(new IPSocket("144.175.1.4", 22), new Credentials("root", "password4"))).andReturn(
|
||||
client4).times(2);
|
||||
expect(factory.create(new IPSocket("144.175.1.5", 22), new Credentials("root", "password5"))).andReturn(
|
||||
client5).times(2);
|
||||
|
||||
runScriptAndInstallSsh(client3, "bootstrap", 3);
|
||||
runScriptAndInstallSsh(client4, "bootstrap", 4);
|
||||
runScriptAndInstallSsh(client5, "bootstrap", 5);
|
||||
|
||||
expect(
|
||||
factory.create(eq(new IPSocket("144.175.1.1", 22)), eq("root"), aryEq(keyPair.get("private")
|
||||
.getBytes()))).andReturn(client1).atLeastOnce();
|
||||
factory.create(eq(new IPSocket("144.175.1.1", 22)), eq(new Credentials("root", keyPair
|
||||
.get("private"))))).andReturn(client1);
|
||||
expect(
|
||||
factory.create(eq(new IPSocket("144.175.1.2", 22)), eq("root"), aryEq(keyPair.get("private")
|
||||
.getBytes()))).andReturn(client2).atLeastOnce();
|
||||
factory.create(eq(new IPSocket("144.175.1.2", 22)), eq(new Credentials("root", keyPair
|
||||
.get("private"))))).andReturn(client2);
|
||||
expect(
|
||||
factory.create(eq(new IPSocket("144.175.1.3", 22)), eq("root"), aryEq(keyPair.get("private")
|
||||
.getBytes()))).andReturn(client3).atLeastOnce();
|
||||
factory.create(eq(new IPSocket("144.175.1.3", 22)), eq(new Credentials("root", keyPair
|
||||
.get("private"))))).andReturn(client3);
|
||||
expect(
|
||||
factory.create(eq(new IPSocket("144.175.1.4", 22)), eq("root"), aryEq(keyPair.get("private")
|
||||
.getBytes()))).andReturn(client4).atLeastOnce();
|
||||
factory.create(eq(new IPSocket("144.175.1.4", 22)), eq(new Credentials("root", keyPair
|
||||
.get("private"))))).andReturn(client4);
|
||||
expect(
|
||||
factory.create(eq(new IPSocket("155.175.1.5", 22)), eq("root"), aryEq(keyPair.get("private")
|
||||
.getBytes()))).andReturn(client5).atLeastOnce();
|
||||
factory.create(eq(new IPSocket("144.175.1.5", 22)), eq(new Credentials("root", keyPair
|
||||
.get("private"))))).andReturn(client5);
|
||||
|
||||
helloAndJava(client2);
|
||||
helloAndJava(client3);
|
||||
|
@ -362,11 +361,31 @@ public class StubComputeServiceIntegrationTest extends BaseComputeServiceLiveTes
|
|||
super.testReboot();
|
||||
}
|
||||
|
||||
@Test(enabled = true, dependsOnMethods = "testReboot")
|
||||
public void testSuspendResume() throws Exception {
|
||||
super.testSuspendResume();
|
||||
}
|
||||
|
||||
@Test(enabled = true, dependsOnMethods = { "testImagesCache" })
|
||||
public void testTemplateMatch() throws Exception {
|
||||
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
|
||||
protected void cleanup() throws InterruptedException, ExecutionException, TimeoutException {
|
||||
super.cleanup();
|
||||
|
|
|
@ -39,6 +39,7 @@ import org.jclouds.compute.domain.TemplateBuilder;
|
|||
import org.jclouds.compute.options.TemplateOptions;
|
||||
import org.jclouds.compute.predicates.ImagePredicates;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.domain.LocationScope;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
|
@ -54,7 +55,7 @@ public class TemplateBuilderImplTest {
|
|||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void tesResolveImages() {
|
||||
public void testResolveImages() {
|
||||
Location defaultLocation = createMock(Location.class);
|
||||
Image image = createMock(Image.class);
|
||||
OperatingSystem os = createMock(OperatingSystem.class);
|
||||
|
@ -202,6 +203,8 @@ public class TemplateBuilderImplTest {
|
|||
expect(os.getArch()).andReturn(null).atLeastOnce();
|
||||
expect(os.is64Bit()).andReturn(false).atLeastOnce();
|
||||
|
||||
expect(defaultLocation.getScope()).andReturn(LocationScope.PROVIDER).atLeastOnce();
|
||||
|
||||
replay(image);
|
||||
replay(os);
|
||||
replay(defaultTemplate);
|
||||
|
@ -257,6 +260,8 @@ public class TemplateBuilderImplTest {
|
|||
expect(os.getArch()).andReturn(null).atLeastOnce();
|
||||
expect(os.is64Bit()).andReturn(false).atLeastOnce();
|
||||
|
||||
expect(defaultLocation.getScope()).andReturn(LocationScope.PROVIDER).atLeastOnce();
|
||||
|
||||
replay(image);
|
||||
replay(os);
|
||||
replay(defaultTemplate);
|
||||
|
@ -359,6 +364,70 @@ public class TemplateBuilderImplTest {
|
|||
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")
|
||||
@Test
|
||||
public void testSuppliedLocationWithNoOptions() {
|
||||
|
|
|
@ -76,18 +76,17 @@ END_OF_SCRIPT
|
|||
# add desired commands from the user
|
||||
cat >> $INSTANCE_HOME/bootstrap.sh <<'END_OF_SCRIPT'
|
||||
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
|
||||
cat >> ~/.ssh/authorized_keys <<'END_OF_FILE'
|
||||
ssh-rsa
|
||||
END_OF_FILE
|
||||
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
|
||||
rm ~/.ssh/id_rsa
|
||||
cat >> ~/.ssh/id_rsa <<'END_OF_FILE'
|
||||
|
|
|
@ -63,14 +63,15 @@ init)
|
|||
ssh-rsa
|
||||
END_OF_FILE
|
||||
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
|
||||
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
|
||||
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 -)
|
||||
mkdir -p /usr/local/jboss
|
||||
mv /usr/local/jboss-*/* /usr/local/jboss
|
||||
|
|
|
@ -76,12 +76,12 @@ END_OF_SCRIPT
|
|||
# add desired commands from the user
|
||||
cat >> $INSTANCE_HOME/runScriptWithCreds.sh <<'END_OF_SCRIPT'
|
||||
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
|
||||
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
|
||||
echo "export PATH=\"\$JAVA_HOME/bin/:\$PATH\"" >> /root/.bashrc
|
||||
|
||||
|
||||
END_OF_SCRIPT
|
||||
|
|
|
@ -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;
|
||||
|
||||
import java.io.IOException;
|
||||
|
|
|
@ -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;
|
||||
|
||||
import java.io.IOException;
|
||||
|
|
|
@ -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;
|
||||
|
||||
import java.io.IOException;
|
||||
|
|
|
@ -65,7 +65,9 @@ public class ExceptionParsingListenableFuture<T> implements ListenableFuture<T>
|
|||
}
|
||||
|
||||
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 {
|
||||
|
|
|
@ -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;
|
||||
|
||||
import java.util.Collections;
|
||||
|
|
|
@ -61,8 +61,8 @@ public class Credentials {
|
|||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((identity == null) ? 0 : identity.hashCode());
|
||||
result = prime * result + ((credential == null) ? 0 : credential.hashCode());
|
||||
result = prime * result + ((identity == null) ? 0 : identity.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -72,20 +72,19 @@ public class Credentials {
|
|||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
if (!(obj instanceof Credentials))
|
||||
return false;
|
||||
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 (other.credential != null)
|
||||
return false;
|
||||
} else if (!credential.equals(other.credential))
|
||||
return false;
|
||||
|
||||
if (identity == null) {
|
||||
if (other.identity != null)
|
||||
return false;
|
||||
} else if (!identity.equals(other.identity))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,6 @@ package org.jclouds.http.functions;
|
|||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
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 java.io.InputStream;
|
||||
|
@ -30,7 +29,6 @@ import java.io.StringReader;
|
|||
import javax.annotation.Resource;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.jclouds.http.HttpException;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.logging.Logger;
|
||||
|
@ -38,14 +36,15 @@ import org.jclouds.rest.InvocationContext;
|
|||
import org.jclouds.rest.internal.GeneratedHttpRequest;
|
||||
import org.jclouds.util.Utils;
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXParseException;
|
||||
import org.xml.sax.XMLReader;
|
||||
import org.xml.sax.helpers.DefaultHandler;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
/**
|
||||
* This object will parse the body of an HttpResponse and return the result of
|
||||
* type <T> back to the caller.
|
||||
* This object will parse the body of an HttpResponse and return the result of type <T> back to the
|
||||
* caller.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
|
@ -108,6 +107,7 @@ public class ParseSax<T> implements Function<HttpResponse, T>, InvocationContext
|
|||
public T parse(InputSource from) {
|
||||
try {
|
||||
checkNotNull(from, "xml inputsource");
|
||||
from.setEncoding("UTF-8");
|
||||
parser.setContentHandler(getHandler());
|
||||
// This method should accept documents with a BOM (Byte-order mark)
|
||||
parser.parse(from);
|
||||
|
@ -118,16 +118,25 @@ public class ParseSax<T> implements Function<HttpResponse, T>, InvocationContext
|
|||
}
|
||||
|
||||
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) {
|
||||
StringBuilder message = new StringBuilder();
|
||||
message.append("Error parsing input for ").append(request.getRequestLine()).append(": ");
|
||||
message.append(e.getMessage());
|
||||
message.append(exceptionMessage);
|
||||
logger.error(e, message.toString());
|
||||
throw new HttpException(message.toString(), e);
|
||||
throw new RuntimeException(message.toString(), e);
|
||||
} else {
|
||||
propagate(e);
|
||||
assert false : "should have propagated: " + e;
|
||||
return null;
|
||||
logger.error(e, exceptionMessage.toString());
|
||||
throw new RuntimeException(exceptionMessage.toString(), e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -136,8 +145,7 @@ public class ParseSax<T> implements Function<HttpResponse, T>, InvocationContext
|
|||
}
|
||||
|
||||
/**
|
||||
* Handler that produces a useable domain object accessible after parsing
|
||||
* completes.
|
||||
* Handler that produces a useable domain object accessible after parsing completes.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
|
|
|
@ -219,20 +219,22 @@ public class JavaUrlHttpCommandExecutorService extends BaseHttpCommandExecutorSe
|
|||
// writeTo will close the output stream
|
||||
try {
|
||||
request.getPayload().writeTo(connection.getOutputStream());
|
||||
} catch (IOException e){
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
throw e;
|
||||
}
|
||||
} else {
|
||||
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;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Only disconnect if there is no content, as disconnecting will throw away
|
||||
* unconsumed content.
|
||||
* Only disconnect if there is no content, as disconnecting will throw away unconsumed content.
|
||||
*/
|
||||
@Override
|
||||
protected void cleanup(HttpURLConnection connection) {
|
||||
|
|
|
@ -95,7 +95,7 @@ public abstract class Wire {
|
|||
out = new FileBackedOutputStream(limit);
|
||||
long bytesRead = ByteStreams.copy(instream, out);
|
||||
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());
|
||||
return out.getSupplier().getInput();
|
||||
} catch (IOException e) {
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.ssh.jsch.predicates;
|
||||
package org.jclouds.predicates;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
|
@ -29,7 +29,6 @@ import javax.inject.Singleton;
|
|||
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.net.IPSocket;
|
||||
import org.jclouds.predicates.SocketOpen;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
|
|
@ -47,10 +47,10 @@ import java.util.Comparator;
|
|||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
@ -58,6 +58,8 @@ import javax.annotation.Nullable;
|
|||
import javax.annotation.Resource;
|
||||
|
||||
import org.jclouds.PropertiesBuilder;
|
||||
import org.jclouds.crypto.Pems;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.rest.AuthorizationException;
|
||||
import org.jclouds.rest.RestContextBuilder;
|
||||
|
@ -246,15 +248,14 @@ public class Utils {
|
|||
}
|
||||
|
||||
/**
|
||||
* Encode the given string with the given encoding, if possible. If the
|
||||
* encoding fails with {@link UnsupportedEncodingException}, log a warning
|
||||
* and fall back to the system's default encoding.
|
||||
* Encode the given string with the given encoding, if possible. If the encoding fails with
|
||||
* {@link UnsupportedEncodingException}, log a warning and fall back to the system's default
|
||||
* encoding.
|
||||
*
|
||||
* @param str
|
||||
* what to encode
|
||||
* @param charsetName
|
||||
* the name of a supported {@link java.nio.charset.Charset
|
||||
* </code>charset<code>}
|
||||
* the name of a supported {@link java.nio.charset.Charset </code>charset<code>}
|
||||
* @return properly encoded String.
|
||||
*/
|
||||
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
|
||||
* very unlikely event the encoding fails with
|
||||
* {@link UnsupportedEncodingException}, log a warning and fall back to the
|
||||
* system's default encoding.
|
||||
* Encode the given string with the UTF-8 encoding, the sane default. In the very unlikely event
|
||||
* the encoding fails with {@link UnsupportedEncodingException}, log a warning and fall back to
|
||||
* the system's default encoding.
|
||||
*
|
||||
* @param str
|
||||
* what to encode
|
||||
|
@ -322,8 +322,7 @@ public class Utils {
|
|||
}
|
||||
|
||||
/**
|
||||
* Will throw an exception if the argument is null or empty. Accepts a custom
|
||||
* error message.
|
||||
* Will throw an exception if the argument is null or empty. Accepts a custom error message.
|
||||
*
|
||||
* @param nullableString
|
||||
* 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
|
||||
* (supported-clouds). Uses rest.properties to populate the set.
|
||||
* Gets a set of supported providers. Idea stolen from pallets (supported-clouds). Uses
|
||||
* rest.properties to populate the set.
|
||||
*
|
||||
*/
|
||||
public static Iterable<String> getSupportedProviders() {
|
||||
|
@ -344,8 +343,8 @@ public class Utils {
|
|||
}
|
||||
|
||||
/**
|
||||
* Gets a set of supported providers. Idea stolen from pallets
|
||||
* (supported-clouds). Uses rest.properties to populate the set.
|
||||
* Gets a set of supported providers. Idea stolen from pallets (supported-clouds). Uses
|
||||
* rest.properties to populate the set.
|
||||
*
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
|
@ -468,4 +467,24 @@ public class Utils {
|
|||
}
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -32,8 +32,8 @@ import org.testng.annotations.Test;
|
|||
public class CredentialsTest {
|
||||
|
||||
public void testAzure() {
|
||||
Credentials creds = Credentials.parse(URI
|
||||
.create("compute://identity:Base64==@azureblob/container-hyphen/prefix"));
|
||||
Credentials creds = Credentials
|
||||
.parse(URI.create("compute://identity:Base64==@azureblob/container-hyphen/prefix"));
|
||||
assertEquals(creds.identity, "identity");
|
||||
assertEquals(creds.credential, "Base64==");
|
||||
}
|
||||
|
@ -46,36 +46,31 @@ public class CredentialsTest {
|
|||
}
|
||||
|
||||
public void testDollar() {
|
||||
Credentials creds = Credentials.parse(URI
|
||||
.create("compute://user%40domain:pa%24sword@hostingdotcom"));
|
||||
Credentials creds = Credentials.parse(URI.create("compute://user%40domain:pa%24sword@hostingdotcom"));
|
||||
assertEquals(creds.identity, "user@domain");
|
||||
assertEquals(creds.credential, "pa$sword");
|
||||
}
|
||||
|
||||
public void testTerremark() {
|
||||
Credentials creds = Credentials.parse(URI
|
||||
.create("compute://user%40domain:password@terremark"));
|
||||
Credentials creds = Credentials.parse(URI.create("compute://user%40domain:password@terremark"));
|
||||
assertEquals(creds.identity, "user@domain");
|
||||
assertEquals(creds.credential, "password");
|
||||
}
|
||||
|
||||
public void testTerremark2() {
|
||||
Credentials creds = Credentials.parse(URI
|
||||
.create("compute://user%40domain:passw%40rd@terremark"));
|
||||
Credentials creds = Credentials.parse(URI.create("compute://user%40domain:passw%40rd@terremark"));
|
||||
assertEquals(creds.identity, "user@domain");
|
||||
assertEquals(creds.credential, "passw@rd");
|
||||
}
|
||||
|
||||
public void testTerremark3() {
|
||||
Credentials creds = Credentials.parse(URI
|
||||
.create("compute://user%40domain:AbC%21%40943%21@terremark"));
|
||||
Credentials creds = Credentials.parse(URI.create("compute://user%40domain:AbC%21%40943%21@terremark"));
|
||||
assertEquals(creds.identity, "user@domain");
|
||||
assertEquals(creds.credential, "AbC!@943!");
|
||||
}
|
||||
|
||||
public void testCloudFiles() {
|
||||
Credentials creds = Credentials.parse(URI
|
||||
.create("compute://identity:h3c@cloudfiles/container-hyphen/prefix"));
|
||||
Credentials creds = Credentials.parse(URI.create("compute://identity:h3c@cloudfiles/container-hyphen/prefix"));
|
||||
assertEquals(creds.identity, "identity");
|
||||
assertEquals(creds.credential, "h3c");
|
||||
|
||||
|
@ -83,18 +78,22 @@ public class CredentialsTest {
|
|||
|
||||
public void testS3() {
|
||||
|
||||
Credentials creds = Credentials
|
||||
.parse(URI.create("compute://0AB:aA%2B%2F0@s3/buck-et/prefix"));
|
||||
Credentials creds = Credentials.parse(URI.create("compute://0AB:aA%2B%2F0@s3/buck-et/prefix"));
|
||||
assertEquals(creds.identity, "0AB");
|
||||
assertEquals(creds.credential, "aA+/0");
|
||||
}
|
||||
|
||||
public void testS3Space() {
|
||||
|
||||
Credentials creds = Credentials.parse(URI
|
||||
.create("compute://0AB:aA%2B%2F0@s3/buck-et/pre%20fix"));
|
||||
Credentials creds = Credentials.parse(URI.create("compute://0AB:aA%2B%2F0@s3/buck-et/pre%20fix"));
|
||||
assertEquals(creds.identity, "0AB");
|
||||
assertEquals(creds.credential, "aA+/0");
|
||||
}
|
||||
|
||||
public void testSubClassEquals() {
|
||||
Credentials creds = new Credentials("user", "pass");
|
||||
assertEquals(creds, new Credentials("user", "pass") {
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -68,7 +68,7 @@ public abstract class BaseHttpErrorHandlerTest {
|
|||
|
||||
HttpCommand command = createMock(HttpCommand.class);
|
||||
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();
|
||||
command.setException(classEq(expected));
|
||||
|
|
|
@ -34,6 +34,7 @@ import static org.jclouds.util.Utils.toStringAndClose;
|
|||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
@ -64,6 +65,8 @@ import org.testng.annotations.Optional;
|
|||
import org.testng.annotations.Parameters;
|
||||
|
||||
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.inject.Injector;
|
||||
import com.google.inject.Module;
|
||||
|
@ -138,8 +141,7 @@ public abstract class BaseJettyTest {
|
|||
response.getWriter().println("test");
|
||||
} else if (request.getMethod().equals("HEAD")) {
|
||||
/*
|
||||
* NOTE: by HTML specification, HEAD response MUST NOT include a
|
||||
* body
|
||||
* NOTE: by HTML specification, HEAD response MUST NOT include a body
|
||||
*/
|
||||
response.setContentType("text/xml");
|
||||
response.setStatus(HttpServletResponse.SC_OK);
|
||||
|
@ -220,8 +222,7 @@ public abstract class BaseJettyTest {
|
|||
}
|
||||
} else if (request.getMethod().equals("HEAD")) {
|
||||
/*
|
||||
* NOTE: by HTML specification, HEAD response MUST NOT include a
|
||||
* body
|
||||
* NOTE: by HTML specification, HEAD response MUST NOT include a body
|
||||
*/
|
||||
response.setContentType("text/xml");
|
||||
response.setStatus(HttpServletResponse.SC_OK);
|
||||
|
@ -309,8 +310,20 @@ public abstract class BaseJettyTest {
|
|||
return false;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
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);
|
||||
((Request) request).setHandled(true);
|
||||
return true;
|
||||
|
|
|
@ -25,6 +25,7 @@ import static org.testng.Assert.assertEquals;
|
|||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.rest.AuthorizationException;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
|
@ -42,6 +43,33 @@ import com.google.inject.spi.Message;
|
|||
@Test(groups = "unit", testName = "jclouds.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() {
|
||||
AuthorizationException aex = createMock(AuthorizationException.class);
|
||||
Message message = new Message(ImmutableList.of(), "test", aex);
|
||||
|
|
|
@ -19,16 +19,19 @@
|
|||
|
||||
package org.jclouds.ssh.jsch.config;
|
||||
|
||||
import static org.jclouds.util.Utils.isPrivateKeyCredential;
|
||||
|
||||
import javax.inject.Named;
|
||||
|
||||
import org.jclouds.Constants;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.http.handlers.BackoffLimitedRetryHandler;
|
||||
import org.jclouds.net.IPSocket;
|
||||
import org.jclouds.predicates.InetSocketAddressConnect;
|
||||
import org.jclouds.predicates.SocketOpen;
|
||||
import org.jclouds.ssh.ConfiguresSshClient;
|
||||
import org.jclouds.ssh.SshClient;
|
||||
import org.jclouds.ssh.jsch.JschSshClient;
|
||||
import org.jclouds.ssh.jsch.predicates.InetSocketAddressConnect;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Inject;
|
||||
|
@ -74,5 +77,10 @@ public class JschSshClientModule extends AbstractModule {
|
|||
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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -26,6 +26,7 @@ import java.io.FileInputStream;
|
|||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.io.Payload;
|
||||
import org.jclouds.io.Payloads;
|
||||
import org.jclouds.net.IPSocket;
|
||||
|
@ -110,10 +111,10 @@ public class JschSshClientLiveTest {
|
|||
SshClient.Factory factory = i.getInstance(SshClient.Factory.class);
|
||||
SshClient connection;
|
||||
if (sshKeyFile != null && !sshKeyFile.trim().equals("")) {
|
||||
connection = factory.create(new IPSocket(sshHost, port), sshUser, Utils.toStringAndClose(
|
||||
new FileInputStream(sshKeyFile)).getBytes());
|
||||
connection = factory.create(new IPSocket(sshHost, port),
|
||||
new Credentials(sshUser, Utils.toStringAndClose(new FileInputStream(sshKeyFile))));
|
||||
} else {
|
||||
connection = factory.create(new IPSocket(sshHost, port), sshUser, sshPass);
|
||||
connection = factory.create(new IPSocket(sshHost, port), new Credentials(sshUser, sshPass));
|
||||
}
|
||||
connection.connect();
|
||||
return connection;
|
||||
|
|
|
@ -23,6 +23,7 @@ import java.io.IOException;
|
|||
import java.net.ConnectException;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.net.IPSocket;
|
||||
import org.jclouds.ssh.SshClient;
|
||||
import org.jclouds.ssh.jsch.config.JschSshClientModule;
|
||||
|
@ -51,8 +52,8 @@ public class JschSshClientTest {
|
|||
protected JschSshClient createClient() throws UnknownHostException {
|
||||
Injector i = Guice.createInjector(module());
|
||||
SshClient.Factory factory = i.getInstance(SshClient.Factory.class);
|
||||
JschSshClient ssh = JschSshClient.class.cast(factory.create(new IPSocket("localhost", 22),
|
||||
"username", "password"));
|
||||
JschSshClient ssh = JschSshClient.class.cast(factory.create(new IPSocket("localhost", 22), new Credentials(
|
||||
"username", "password")));
|
||||
return ssh;
|
||||
}
|
||||
|
||||
|
@ -68,10 +69,8 @@ public class JschSshClientTest {
|
|||
}
|
||||
|
||||
public void testExceptionMessagesRetry() {
|
||||
assert ssh.shouldRetry(new JSchException(
|
||||
"Session.connect: java.io.IOException: End of IO Stream Read"));
|
||||
assert ssh.shouldRetry(new JSchException("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: java.net.SocketException: Connection reset"));
|
||||
assert ssh.shouldRetry(new JSchException("Session.connect: java.net.SocketException: Connection reset"));
|
||||
}
|
||||
}
|
|
@ -21,6 +21,7 @@ package org.jclouds.ssh.jsch.config;
|
|||
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.net.IPSocket;
|
||||
import org.jclouds.ssh.SshClient;
|
||||
import org.jclouds.ssh.jsch.JschSshClient;
|
||||
|
@ -41,7 +42,7 @@ public class JschSshClientModuleTest {
|
|||
|
||||
Injector i = Guice.createInjector(new JschSshClientModule());
|
||||
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;
|
||||
}
|
||||
}
|
|
@ -25,11 +25,13 @@ import org.jclouds.compute.strategy.DestroyNodeStrategy;
|
|||
import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
|
||||
import org.jclouds.compute.strategy.ListNodesStrategy;
|
||||
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.GoGridDestroyNodeStrategy;
|
||||
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.GoGridRebootNodeStrategy;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -59,6 +61,16 @@ public class GoGridBindComputeStrategiesByClass extends BindComputeStrategiesByC
|
|||
|
||||
@Override
|
||||
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;
|
||||
}
|
||||
}
|
|
@ -26,6 +26,8 @@ import org.jclouds.compute.domain.NodeMetadata;
|
|||
import org.jclouds.compute.reference.ComputeServiceConstants.Timeouts;
|
||||
import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
|
||||
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.domain.PowerCommand;
|
||||
import org.jclouds.gogrid.domain.Server;
|
||||
|
@ -39,14 +41,14 @@ import com.google.common.collect.Iterables;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class GoGridRebootNodeStrategy implements RebootNodeStrategy {
|
||||
public class GoGridLifeCycleStrategy implements RebootNodeStrategy, ResumeNodeStrategy, SuspendNodeStrategy {
|
||||
private final GoGridClient client;
|
||||
private final RetryablePredicate<Server> serverLatestJobCompleted;
|
||||
private final RetryablePredicate<Server> serverLatestJobCompletedShort;
|
||||
private final GetNodeMetadataStrategy getNode;
|
||||
|
||||
@Inject
|
||||
protected GoGridRebootNodeStrategy(GoGridClient client, GetNodeMetadataStrategy getNode, Timeouts timeouts) {
|
||||
protected GoGridLifeCycleStrategy(GoGridClient client, GetNodeMetadataStrategy getNode, Timeouts timeouts) {
|
||||
this.client = client;
|
||||
this.serverLatestJobCompleted = new RetryablePredicate<Server>(new ServerLatestJobCompleted(client
|
||||
.getJobServices()), timeouts.nodeRunning * 9l / 10l);
|
||||
|
@ -57,11 +59,30 @@ public class GoGridRebootNodeStrategy implements RebootNodeStrategy {
|
|||
|
||||
@Override
|
||||
public NodeMetadata rebootNode(String id) {
|
||||
executeCommandOnServer(PowerCommand.RESTART, 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);
|
||||
serverLatestJobCompletedShort.apply(server);
|
||||
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);
|
||||
}
|
||||
}
|
|
@ -20,6 +20,7 @@
|
|||
package org.jclouds.gogrid.compute.suppliers;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
@ -35,7 +36,6 @@ import org.jclouds.compute.reference.ComputeServiceConstants;
|
|||
import org.jclouds.compute.strategy.PopulateDefaultLoginCredentialsForImageStrategy;
|
||||
import org.jclouds.gogrid.GoGridClient;
|
||||
import org.jclouds.gogrid.domain.ServerImage;
|
||||
import org.jclouds.gogrid.util.GoGridUtils;
|
||||
import org.jclouds.logging.Logger;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
|
@ -47,7 +47,8 @@ import com.google.common.collect.Sets;
|
|||
*/
|
||||
@Singleton
|
||||
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
|
||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||
|
@ -84,18 +85,29 @@ public class GoGridImageSupplier implements Supplier<Set<? extends Image>> {
|
|||
OsFamily osFamily = null;
|
||||
String osName = from.getOs().getName();
|
||||
String osArch = from.getArchitecture().getDescription();
|
||||
String osVersion = null;// TODO
|
||||
String osVersion = parseVersion(osName);
|
||||
String osDescription = from.getOs().getDescription();
|
||||
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());
|
||||
if (matcher.find()) {
|
||||
try {
|
||||
osFamily = OsFamily.fromValue(matchedOs.toLowerCase());
|
||||
osFamily = OsFamily.fromValue(matcher.group(1).toLowerCase());
|
||||
} catch (IllegalArgumentException e) {
|
||||
logger.debug("<< didn't match os(%s)", matchedOs);
|
||||
logger.debug("<< didn't match os(%s)", from.getName());
|
||||
}
|
||||
}
|
||||
|
||||
// TODO determine DC images are in
|
||||
OperatingSystem os = new OperatingSystem(osFamily, osName, osVersion, osArch, osDescription, is64Bit);
|
||||
return os;
|
||||
}
|
||||
|
||||
static String parseVersion(String name) {
|
||||
Matcher matcher = GOGRID_VERSION_PATTERN.matcher(name);
|
||||
if (matcher.find()) {
|
||||
return matcher.group(1);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -59,11 +59,11 @@ import org.jclouds.gogrid.predicates.ServerLatestJobCompleted;
|
|||
import org.jclouds.http.handlers.BackoffLimitedRetryHandler;
|
||||
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
|
||||
import org.jclouds.net.IPSocket;
|
||||
import org.jclouds.predicates.InetSocketAddressConnect;
|
||||
import org.jclouds.predicates.RetryablePredicate;
|
||||
import org.jclouds.rest.RestContext;
|
||||
import org.jclouds.ssh.SshClient;
|
||||
import org.jclouds.ssh.jsch.JschSshClient;
|
||||
import org.jclouds.ssh.jsch.predicates.InetSocketAddressConnect;
|
||||
import org.testng.SkipException;
|
||||
import org.testng.TestException;
|
||||
import org.testng.annotations.AfterTest;
|
||||
|
@ -82,7 +82,7 @@ import com.google.inject.Module;
|
|||
*
|
||||
* @author Oleksiy Yarmula
|
||||
*/
|
||||
@Test(enabled = false, groups = "live", testName = "gogrid.GoGridLiveTest")
|
||||
@Test(enabled = true, groups = "live", testName = "gogrid.GoGridLiveTest")
|
||||
public class GoGridLiveTestDisabled {
|
||||
|
||||
private GoGridClient client;
|
||||
|
|
|
@ -45,6 +45,7 @@ public class GoGridComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
|||
public void testTemplateBuilder() {
|
||||
Template defaultTemplate = client.templateBuilder().build();
|
||||
assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true);
|
||||
assertEquals(defaultTemplate.getImage().getOperatingSystem().getVersion(), "5.3");
|
||||
assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.CENTOS);
|
||||
assertEquals(defaultTemplate.getLocation().getId(), "1");
|
||||
assertEquals(getCores(defaultTemplate.getHardware()), 0.5d);
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
||||
}
|
|
@ -300,7 +300,7 @@
|
|||
<testSourceDirectories>
|
||||
<testSourceDirectory>src/test/clojure</testSourceDirectory>
|
||||
</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>
|
||||
<compileDeclaredNamespaceOnly>true</compileDeclaredNamespaceOnly>
|
||||
<testDeclaredNamespaceOnly>false</testDeclaredNamespaceOnly>
|
||||
|
@ -326,7 +326,7 @@
|
|||
<goal>test</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<argLine>-Xmx512m -Xms256m -Xss128k</argLine>
|
||||
<argLine>-Xmx512m -Xms256m -Djava.awt.headless=true -XX:MaxPermSize=256m -Xss256k</argLine>
|
||||
<parallel>tests</parallel>
|
||||
<threadCount>5</threadCount>
|
||||
<!-- note that the groups/excluded groups don't work due to some problem
|
||||
|
|
|
@ -25,11 +25,13 @@ import org.jclouds.compute.strategy.DestroyNodeStrategy;
|
|||
import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
|
||||
import org.jclouds.compute.strategy.ListNodesStrategy;
|
||||
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.CloudServersDestroyNodeStrategy;
|
||||
import org.jclouds.rackspace.cloudservers.compute.strategy.CloudServersGetNodeMetadataStrategy;
|
||||
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
|
||||
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;
|
||||
}
|
||||
}
|
|
@ -40,7 +40,7 @@ import com.google.common.base.Function;
|
|||
@Singleton
|
||||
public class CloudServersImageToOperatingSystem implements
|
||||
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
|
||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||
|
@ -58,12 +58,14 @@ public class CloudServersImageToOperatingSystem implements
|
|||
osFamily = OsFamily.RHEL;
|
||||
} else if (from.getName().indexOf("Oracle EL") != -1) {
|
||||
osFamily = OsFamily.OEL;
|
||||
} else if (matcher.find()) {
|
||||
}
|
||||
if (matcher.find()) {
|
||||
try {
|
||||
osFamily = OsFamily.fromValue(matcher.group(2).toLowerCase());
|
||||
} catch (IllegalArgumentException e) {
|
||||
logger.debug("<< didn't match os(%s)", matcher.group(2));
|
||||
}
|
||||
osVersion = matcher.group(3);
|
||||
}
|
||||
OperatingSystem os = new OperatingSystem(osFamily, osName, osVersion, osArch, osDescription, is64Bit);
|
||||
return os;
|
||||
|
|
|
@ -115,7 +115,7 @@ public class ServerToNodeMetadata implements Function<Server, NodeMetadata> {
|
|||
builder.state(serverToNodeState.get(from.getStatus()));
|
||||
builder.publicAddresses(from.getAddresses().getPublicAddresses());
|
||||
builder.privateAddresses(from.getAddresses().getPrivateAddresses());
|
||||
builder.credentials(credentialStore.get(from.getId() + ""));
|
||||
builder.credentials(credentialStore.get("node#" + from.getId()));
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
|
|
|
@ -54,9 +54,9 @@ public class CloudServersAddNodeWithTagStrategy implements AddNodeWithTagStrateg
|
|||
|
||||
@Override
|
||||
public NodeMetadata addNodeWithTag(String tag, String name, Template template) {
|
||||
Server from = client.createServer(name, Integer.parseInt(template.getImage().getProviderId()),
|
||||
Integer.parseInt(template.getHardware().getProviderId()));
|
||||
credentialStore.put(from.getId() + "", new Credentials("root", from.getAdminPass()));
|
||||
Server from = client.createServer(name, Integer.parseInt(template.getImage().getProviderId()), Integer
|
||||
.parseInt(template.getHardware().getProviderId()));
|
||||
credentialStore.put("node#" + from.getId(), new Credentials("root", from.getAdminPass()));
|
||||
return serverToNodeMetadata.apply(from);
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,8 @@ import javax.inject.Singleton;
|
|||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
|
||||
import org.jclouds.compute.strategy.RebootNodeStrategy;
|
||||
import org.jclouds.compute.strategy.ResumeNodeStrategy;
|
||||
import org.jclouds.compute.strategy.SuspendNodeStrategy;
|
||||
import org.jclouds.rackspace.cloudservers.CloudServersClient;
|
||||
import org.jclouds.rackspace.cloudservers.domain.RebootType;
|
||||
|
||||
|
@ -32,12 +34,12 @@ import org.jclouds.rackspace.cloudservers.domain.RebootType;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class CloudServersRebootNodeStrategy implements RebootNodeStrategy {
|
||||
public class CloudServersLifeCycleStrategy implements RebootNodeStrategy, SuspendNodeStrategy, ResumeNodeStrategy {
|
||||
private final CloudServersClient client;
|
||||
private final GetNodeMetadataStrategy getNode;
|
||||
|
||||
@Inject
|
||||
protected CloudServersRebootNodeStrategy(CloudServersClient client, GetNodeMetadataStrategy getNode) {
|
||||
protected CloudServersLifeCycleStrategy(CloudServersClient client, GetNodeMetadataStrategy getNode) {
|
||||
this.client = client;
|
||||
this.getNode = getNode;
|
||||
}
|
||||
|
@ -50,4 +52,14 @@ public class CloudServersRebootNodeStrategy implements RebootNodeStrategy {
|
|||
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");
|
||||
}
|
||||
|
||||
}
|
|
@ -117,7 +117,7 @@ public class RackspaceAuthenticationRestModule extends AbstractModule {
|
|||
@Provides
|
||||
@Singleton
|
||||
@CloudFiles
|
||||
protected URI provideStorageUrl(AuthenticationResponse response) {
|
||||
protected URI providestroageUrl(AuthenticationResponse response) {
|
||||
return response.getStorageUrl();
|
||||
}
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@ import java.util.Set;
|
|||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.jclouds.Constants;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.http.HttpResponseException;
|
||||
import org.jclouds.io.Payload;
|
||||
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);
|
||||
socketTester.apply(socket);
|
||||
|
||||
SshClient client = sshFactory.create(socket, "root", pass);
|
||||
SshClient client = sshFactory.create(socket, new Credentials("root", pass));
|
||||
try {
|
||||
client.connect();
|
||||
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 {
|
||||
IPSocket socket = new IPSocket(Iterables.get(details.getAddresses().getPublicAddresses(), 0), 22);
|
||||
socketTester.apply(socket);
|
||||
SshClient client = sshFactory.create(socket, "root", pass);
|
||||
SshClient client = sshFactory.create(socket, new Credentials("root", pass));
|
||||
try {
|
||||
client.connect();
|
||||
return client.exec(command);
|
||||
|
|
|
@ -52,6 +52,7 @@ public class CloudServersComputeServiceLiveTest extends BaseComputeServiceLiveTe
|
|||
public void testTemplateBuilder() {
|
||||
Template defaultTemplate = client.templateBuilder().build();
|
||||
assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true);
|
||||
assertEquals(defaultTemplate.getImage().getOperatingSystem().getVersion(), "9.10");
|
||||
assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.UBUNTU);
|
||||
assertEquals(defaultTemplate.getLocation().getId(), "DFW1");
|
||||
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();
|
||||
}
|
||||
|
||||
}
|
|
@ -44,7 +44,7 @@ public class CloudServersImageToImageTest {
|
|||
new ImageBuilder()
|
||||
.name("CentOS 5.2")
|
||||
.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))
|
||||
.ids("2").version("1286712000000").build());
|
||||
}
|
||||
|
|
|
@ -68,7 +68,7 @@ public class ServerToNodeMetadataTest {
|
|||
Server server = ParseServerFromJsonResponseTest.parseServer();
|
||||
|
||||
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));
|
||||
|
||||
NodeMetadata metadata = parser.apply(server);
|
||||
|
@ -123,8 +123,8 @@ public class ServerToNodeMetadataTest {
|
|||
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(
|
||||
"NOTAG-sample-server").imageId("2").operatingSystem(
|
||||
new OperatingSystemBuilder().family(OsFamily.CENTOS).description("CentOS 5.2").is64Bit(true).build())
|
||||
.id("1234").providerId("1234").name("sample-server").location(
|
||||
new OperatingSystemBuilder().family(OsFamily.CENTOS).description("CentOS 5.2").version("5.2").is64Bit(
|
||||
true).build()).id("1234").providerId("1234").name("sample-server").location(
|
||||
new LocationImpl(LocationScope.HOST, "e4d909c290d0fb1ca068ffaddf22cbd0",
|
||||
"e4d909c290d0fb1ca068ffaddf22cbd0", new LocationImpl(LocationScope.ZONE, "dallas",
|
||||
"description", null))).userMetadata(
|
||||
|
@ -152,8 +152,8 @@ public class ServerToNodeMetadataTest {
|
|||
ImmutableList.of(new Processor(1.0, 1.0))).ram(256).volumes(
|
||||
ImmutableList.of(new VolumeBuilder().type(Volume.Type.LOCAL).size(10.0f).durable(true)
|
||||
.bootDevice(true).build())).build()).operatingSystem(
|
||||
new OperatingSystemBuilder().family(OsFamily.CENTOS).description("CentOS 5.2").is64Bit(true).build())
|
||||
.id("1234").providerId("1234").name("sample-server").location(
|
||||
new OperatingSystemBuilder().family(OsFamily.CENTOS).description("CentOS 5.2").version("5.2").is64Bit(
|
||||
true).build()).id("1234").providerId("1234").name("sample-server").location(
|
||||
new LocationImpl(LocationScope.HOST, "e4d909c290d0fb1ca068ffaddf22cbd0",
|
||||
"e4d909c290d0fb1ca068ffaddf22cbd0", new LocationImpl(LocationScope.ZONE, "dallas",
|
||||
"description", null))).userMetadata(
|
||||
|
|
|
@ -161,12 +161,12 @@
|
|||
<category name="jclouds.ssh">
|
||||
<priority value="DEBUG" />
|
||||
<appender-ref ref="ASYNCSSH" />
|
||||
</category><!--
|
||||
</category>
|
||||
<category name="jclouds.wire">
|
||||
<priority value="DEBUG" />
|
||||
<appender-ref ref="ASYNCWIRE" />
|
||||
</category>
|
||||
--><category name="jclouds.blobstore">
|
||||
<category name="jclouds.blobstore">
|
||||
<priority value="DEBUG" />
|
||||
<appender-ref ref="ASYNCBLOBSTORE" />
|
||||
</category>
|
||||
|
|
|
@ -139,7 +139,7 @@ public interface RimuHostingAsyncClient {
|
|||
ListenableFuture<ServerInfo> restartServer(@PathParam("id") Long id);
|
||||
|
||||
/**
|
||||
* @see RimuHostingClient#destoryServer
|
||||
* @see RimuHostingClient#destroyServer
|
||||
*/
|
||||
@DELETE
|
||||
@Path("/orders/order-{id}-blah/vps")
|
||||
|
|
|
@ -6,11 +6,13 @@ import org.jclouds.compute.strategy.DestroyNodeStrategy;
|
|||
import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
|
||||
import org.jclouds.compute.strategy.ListNodesStrategy;
|
||||
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.RimuHostingDestroyNodeStrategy;
|
||||
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.RimuHostingRebootNodeStrategy;
|
||||
|
||||
public class RimuHostingBindComputeStrategiesByClass extends BindComputeStrategiesByClass {
|
||||
@Override
|
||||
|
@ -35,6 +37,16 @@ public class RimuHostingBindComputeStrategiesByClass extends BindComputeStrategi
|
|||
|
||||
@Override
|
||||
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;
|
||||
}
|
||||
}
|
|
@ -45,7 +45,7 @@ public class RimuHostingComputeServiceContextModule extends BaseComputeServiceCo
|
|||
|
||||
@Override
|
||||
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");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -105,7 +105,7 @@ public class ServerToNodeMetadata implements Function<Server, NodeMetadata> {
|
|||
builder.hardware(null);// TODO
|
||||
builder.state(runningStateToNodeState.get(from.getState()));
|
||||
builder.publicAddresses(getPublicAddresses.apply(from));
|
||||
builder.credentials(credentialStore.get(from.getId() + ""));
|
||||
builder.credentials(credentialStore.get("node#" + from.getId()));
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue