mirror of https://github.com/apache/jclouds.git
added exceptions to ssh commands and changed interface to not index on id, since ids are not guaranteed unique
This commit is contained in:
parent
0d61930192
commit
239519c8ca
|
@ -22,7 +22,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||
import static com.google.common.util.concurrent.Futures.compose;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
|
@ -80,7 +80,7 @@ public class AtmosAsyncBlobStore extends BaseAsyncBlobStore {
|
|||
@Inject
|
||||
AtmosAsyncBlobStore(BlobStoreContext context, BlobStoreUtils blobUtils,
|
||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService service,
|
||||
Location defaultLocation, Map<String, ? extends Location> locations,
|
||||
Location defaultLocation, Set<? extends Location> locations,
|
||||
|
||||
AtmosStorageAsyncClient async, AtmosStorageClient sync, ObjectToBlob object2Blob,
|
||||
ObjectToBlobMetadata object2BlobMd, BlobToObject blob2Object,
|
||||
|
|
|
@ -20,7 +20,7 @@ package org.jclouds.atmosonline.saas.blobstore;
|
|||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Provider;
|
||||
|
@ -65,8 +65,8 @@ public class AtmosBlobStore extends BaseBlobStore {
|
|||
|
||||
@Inject
|
||||
AtmosBlobStore(BlobStoreContext context, BlobStoreUtils blobUtils, Location defaultLocation,
|
||||
Map<String, ? extends Location> locations, AtmosStorageClient sync,
|
||||
ObjectToBlob object2Blob, ObjectToBlobMetadata object2BlobMd, BlobToObject blob2Object,
|
||||
Set<? extends Location> locations, AtmosStorageClient sync, ObjectToBlob object2Blob,
|
||||
ObjectToBlobMetadata object2BlobMd, BlobToObject blob2Object,
|
||||
BlobStoreListOptionsToListOptions container2ContainerListOptions,
|
||||
DirectoryEntryListToResourceMetadataList container2ResourceList,
|
||||
EncryptionService encryptionService, BlobToHttpGetOptions blob2ObjectGetOptions,
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
package org.jclouds.atmosonline.saas.blobstore.config;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
||||
|
@ -39,7 +39,7 @@ import org.jclouds.domain.Location;
|
|||
import org.jclouds.domain.LocationScope;
|
||||
import org.jclouds.domain.internal.LocationImpl;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.inject.Provides;
|
||||
import com.google.inject.Scopes;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
@ -78,7 +78,7 @@ public class AtmosBlobStoreContextModule extends AtmosStorageContextModule {
|
|||
|
||||
@Provides
|
||||
@Singleton
|
||||
Map<String, ? extends Location> provideLocations(Location location) {
|
||||
return ImmutableMap.of(location.getId(), location);
|
||||
Set<? extends Location> provideLocations(Location location) {
|
||||
return ImmutableSet.of(location);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
package org.jclouds.aws.ec2.compute;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
@ -64,10 +65,9 @@ public class EC2ComputeService extends BaseComputeService {
|
|||
|
||||
@Inject
|
||||
protected EC2ComputeService(ComputeServiceContext context,
|
||||
Provider<Map<String, ? extends Image>> images,
|
||||
Provider<Map<String, ? extends Size>> sizes,
|
||||
Provider<Map<String, ? extends Location>> locations,
|
||||
ListNodesStrategy listNodesStrategy, GetNodeMetadataStrategy getNodeMetadataStrategy,
|
||||
Provider<Set<? extends Image>> images, Provider<Set<? extends Size>> sizes,
|
||||
Provider<Set<? extends Location>> locations, ListNodesStrategy listNodesStrategy,
|
||||
GetNodeMetadataStrategy getNodeMetadataStrategy,
|
||||
RunNodesAndAddToSetStrategy runNodesAndAddToSetStrategy,
|
||||
RebootNodeStrategy rebootNodeStrategy, DestroyNodeStrategy destroyNodeStrategy,
|
||||
Provider<TemplateBuilder> templateBuilderProvider, ComputeUtils utils,
|
||||
|
@ -101,7 +101,7 @@ public class EC2ComputeService extends BaseComputeService {
|
|||
logger.debug(">> deleting keyPair(%s)", tag);
|
||||
ec2Client.getKeyPairServices().deleteKeyPairInRegion(region, keyPair.getKeyName());
|
||||
credentialsMap.remove(new RegionTag(region, keyPair.getKeyName())); // TODO: test this
|
||||
// clear happens
|
||||
// clear happens
|
||||
logger.debug("<< deleted keyPair(%s)", keyPair.getKeyName());
|
||||
}
|
||||
}
|
||||
|
@ -110,7 +110,7 @@ public class EC2ComputeService extends BaseComputeService {
|
|||
@Override
|
||||
public void destroyNodesWithTag(String tag) {
|
||||
super.destroyNodesWithTag(tag);
|
||||
Iterable<? extends NodeMetadata> nodes = Iterables.filter(getNodesWithTag(tag).values(),
|
||||
Iterable<? extends NodeMetadata> nodes = Iterables.filter(listNodesWithTag(tag),
|
||||
new Predicate<NodeMetadata>() {
|
||||
@Override
|
||||
public boolean apply(NodeMetadata input) {
|
||||
|
|
|
@ -254,32 +254,37 @@ public class EC2ComputeServiceContextModule extends EC2ContextModule {
|
|||
|
||||
@Provides
|
||||
@Singleton
|
||||
Map<String, ? extends Size> provideSizes(Function<ComputeMetadata, String> indexer) {
|
||||
return Maps.uniqueIndex(ImmutableSet.of(EC2Size.C1_MEDIUM, EC2Size.C1_XLARGE,
|
||||
EC2Size.M1_LARGE, EC2Size.M1_SMALL, EC2Size.M1_XLARGE, EC2Size.M2_XLARGE,
|
||||
EC2Size.M2_2XLARGE, EC2Size.M2_4XLARGE), indexer);
|
||||
Set<? extends Size> provideSizes() {
|
||||
return ImmutableSet.of(EC2Size.C1_MEDIUM, EC2Size.C1_XLARGE, EC2Size.M1_LARGE,
|
||||
EC2Size.M1_SMALL, EC2Size.M1_XLARGE, EC2Size.M2_XLARGE, EC2Size.M2_2XLARGE,
|
||||
EC2Size.M2_4XLARGE);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
Map<String, ? extends Location> provideLocations(Map<String, String> availabilityZoneToRegionMap) {
|
||||
Set<? extends Location> provideLocations(Map<String, String> availabilityZoneToRegionMap) {
|
||||
Location ec2 = new LocationImpl(LocationScope.PROVIDER, providerName, providerName, null);
|
||||
Map<String, Location> locations = Maps.newLinkedHashMap();
|
||||
for (String region : availabilityZoneToRegionMap.values()) {
|
||||
locations.put(region, new LocationImpl(LocationScope.REGION, region, region, ec2));
|
||||
}
|
||||
|
||||
Set<Location> locations = Sets.newLinkedHashSet();
|
||||
for (String zone : availabilityZoneToRegionMap.keySet()) {
|
||||
locations.put(zone, new LocationImpl(LocationScope.ZONE, zone, zone, locations
|
||||
.get(availabilityZoneToRegionMap.get(zone))));
|
||||
Location region = new LocationImpl(LocationScope.REGION, availabilityZoneToRegionMap
|
||||
.get(zone), availabilityZoneToRegionMap.get(zone), ec2);
|
||||
locations.add(region);
|
||||
locations.add(new LocationImpl(LocationScope.ZONE, zone, zone, region));
|
||||
}
|
||||
return locations;
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
Location getDefaultLocation(@EC2 String region, Map<String, ? extends Location> map) {
|
||||
return map.get(region);
|
||||
Location getDefaultLocation(@EC2 final String region, Set<? extends Location> set) {
|
||||
return Iterables.find(set, new Predicate<Location>() {
|
||||
|
||||
@Override
|
||||
public boolean apply(Location input) {
|
||||
return input.getId().equals(region);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
private static class LogHolder {
|
||||
|
@ -297,7 +302,7 @@ public class EC2ComputeServiceContextModule extends EC2ContextModule {
|
|||
|
||||
@Provides
|
||||
@Singleton
|
||||
protected Map<String, ? extends Image> provideImages(final EC2Client sync,
|
||||
protected Set<? extends Image> provideImages(final EC2Client sync,
|
||||
@EC2 Map<String, URI> regionMap, LogHolder holder,
|
||||
Function<ComputeMetadata, String> indexer,
|
||||
@Named(PROPERTY_EC2_AMI_OWNERS) String[] amiOwners, ImageParser parser)
|
||||
|
@ -316,6 +321,6 @@ public class EC2ComputeServiceContextModule extends EC2ContextModule {
|
|||
}
|
||||
}
|
||||
holder.logger.debug("<< images(%d)", images.size());
|
||||
return Maps.uniqueIndex(images, indexer);
|
||||
return images;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,6 +21,8 @@ package org.jclouds.aws.ec2.compute.functions;
|
|||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
@ -38,10 +40,14 @@ import org.jclouds.compute.reference.ComputeServiceConstants;
|
|||
import org.jclouds.compute.strategy.PopulateDefaultLoginCredentialsForImageStrategy;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.domain.LocationScope;
|
||||
import org.jclouds.domain.internal.LocationImpl;
|
||||
import org.jclouds.logging.Logger;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
|
@ -61,18 +67,21 @@ public class ImageParser implements Function<org.jclouds.aws.ec2.domain.Image, I
|
|||
.build();
|
||||
|
||||
private final PopulateDefaultLoginCredentialsForImageStrategy credentialProvider;
|
||||
private final Map<String, ? extends Location> locations;
|
||||
private final Set<? extends Location> locations;
|
||||
|
||||
private final Location defaultLocation;
|
||||
|
||||
@Inject
|
||||
ImageParser(PopulateDefaultLoginCredentialsForImageStrategy credentialProvider,
|
||||
Map<String, ? extends Location> locations) {
|
||||
Set<? extends Location> locations, Location defaultLocation) {
|
||||
this.credentialProvider = checkNotNull(credentialProvider, "credentialProvider");
|
||||
this.locations = checkNotNull(locations, "locations");
|
||||
this.defaultLocation = checkNotNull(defaultLocation, "defaultLocation");
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Image apply(org.jclouds.aws.ec2.domain.Image from) {
|
||||
public Image apply(final org.jclouds.aws.ec2.domain.Image from) {
|
||||
if (from.getImageLocation().indexOf("test") != -1) {
|
||||
logger.trace("skipping test image(%s)", from.getId());
|
||||
return null;
|
||||
|
@ -102,10 +111,26 @@ public class ImageParser implements Function<org.jclouds.aws.ec2.domain.Image, I
|
|||
}
|
||||
Credentials defaultCredentials = credentialProvider.execute(from);
|
||||
|
||||
Location location = null;
|
||||
try {
|
||||
location = Iterables.find(locations, new Predicate<Location>() {
|
||||
|
||||
@Override
|
||||
public boolean apply(Location input) {
|
||||
return input.getId().equals(from.getRegion());
|
||||
}
|
||||
|
||||
});
|
||||
} catch (NoSuchElementException e) {
|
||||
System.err.printf("unknown region %s for image %s; not in %s", from.getRegion(), from
|
||||
.getId(), locations);
|
||||
location = new LocationImpl(LocationScope.REGION, from.getRegion(), from.getRegion(),
|
||||
defaultLocation.getParent());
|
||||
}
|
||||
return new ImageImpl(
|
||||
from.getId(),
|
||||
name,
|
||||
locations.get(from.getRegion()),
|
||||
location,
|
||||
null,
|
||||
ImmutableMap.<String, String> of("owner", from.getImageOwnerId()),
|
||||
description,
|
||||
|
@ -114,5 +139,6 @@ public class ImageParser implements Function<org.jclouds.aws.ec2.domain.Image, I
|
|||
osDescription,
|
||||
from.getArchitecture() == org.jclouds.aws.ec2.domain.Image.Architecture.I386 ? Architecture.X86_32
|
||||
: Architecture.X86_64, defaultCredentials);
|
||||
|
||||
}
|
||||
}
|
|
@ -24,8 +24,10 @@ import static org.jclouds.util.Utils.nullSafeSet;
|
|||
import java.net.InetAddress;
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
@ -43,9 +45,11 @@ import org.jclouds.compute.domain.internal.NodeMetadataImpl;
|
|||
import org.jclouds.compute.strategy.PopulateDefaultLoginCredentialsForImageStrategy;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.logging.Logger;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Maps;
|
||||
|
@ -55,6 +59,27 @@ import com.google.common.collect.Maps;
|
|||
*/
|
||||
@Singleton
|
||||
public class RunningInstanceToNodeMetadata implements Function<RunningInstance, NodeMetadata> {
|
||||
|
||||
@Resource
|
||||
protected Logger logger = Logger.NULL;
|
||||
|
||||
private static class FindImageForInstance implements Predicate<Image> {
|
||||
private final Location location;
|
||||
private final RunningInstance instance;
|
||||
|
||||
private FindImageForInstance(Location location, RunningInstance instance) {
|
||||
this.location = location;
|
||||
this.instance = instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Image input) {
|
||||
return input.getId().equals(instance.getImageId())
|
||||
&& (input.getLocation() == null || input.getLocation().equals(location) || input
|
||||
.getLocation().equals(location.getParent()));
|
||||
}
|
||||
}
|
||||
|
||||
private static final Map<InstanceState, NodeState> instanceToNodeState = ImmutableMap
|
||||
.<InstanceState, NodeState> builder().put(InstanceState.PENDING, NodeState.PENDING)
|
||||
.put(InstanceState.RUNNING, NodeState.RUNNING).put(InstanceState.SHUTTING_DOWN,
|
||||
|
@ -63,14 +88,17 @@ public class RunningInstanceToNodeMetadata implements Function<RunningInstance,
|
|||
private final AMIClient amiClient;
|
||||
private final Map<RegionTag, KeyPair> credentialsMap;
|
||||
private final PopulateDefaultLoginCredentialsForImageStrategy credentialProvider;
|
||||
private final Map<String, ? extends Image> images;
|
||||
private final Map<String, ? extends Location> locations;
|
||||
private final Set<? extends Image> images;
|
||||
private final Set<? extends Location> locations;
|
||||
private final Function<RunningInstance, Map<String, String>> instanceToStorageMapping;
|
||||
|
||||
@Inject
|
||||
RunningInstanceToNodeMetadata(AMIClient amiClient, Map<RegionTag, KeyPair> credentialsMap,
|
||||
RunningInstanceToNodeMetadata(
|
||||
AMIClient amiClient,
|
||||
Map<RegionTag, KeyPair> credentialsMap,
|
||||
PopulateDefaultLoginCredentialsForImageStrategy credentialProvider,
|
||||
Map<String, ? extends Image> images, Map<String, ? extends Location> locations,
|
||||
Set<? extends Image> images,
|
||||
Set<? extends Location> locations,
|
||||
@Named("volumeMapping") Function<RunningInstance, Map<String, String>> instanceToStorageMapping) {
|
||||
this.amiClient = checkNotNull(amiClient, "amiClient");
|
||||
this.credentialsMap = checkNotNull(credentialsMap, "credentialsMap");
|
||||
|
@ -81,7 +109,7 @@ public class RunningInstanceToNodeMetadata implements Function<RunningInstance,
|
|||
}
|
||||
|
||||
@Override
|
||||
public NodeMetadata apply(RunningInstance instance) {
|
||||
public NodeMetadata apply(final RunningInstance instance) {
|
||||
String id = checkNotNull(instance, "instance").getId();
|
||||
String name = null; // user doesn't determine a node name;
|
||||
URI uri = null; // no uri to get rest access to host info
|
||||
|
@ -102,13 +130,28 @@ public class RunningInstanceToNodeMetadata implements Function<RunningInstance,
|
|||
Set<InetAddress> publicAddresses = nullSafeSet(instance.getIpAddress());
|
||||
Set<InetAddress> privateAddresses = nullSafeSet(instance.getPrivateIpAddress());
|
||||
|
||||
String locationId = instance.getAvailabilityZone();
|
||||
final String locationId = instance.getAvailabilityZone();
|
||||
|
||||
Map<String, String> extra = getExtra(instance);
|
||||
|
||||
return new NodeMetadataImpl(id, name, locations.get(locationId), uri, userMetadata, tag,
|
||||
images.get(instance.getImageId()), state, publicAddresses, privateAddresses, extra,
|
||||
credentials);
|
||||
final Location location = Iterables.find(locations, new Predicate<Location>() {
|
||||
|
||||
@Override
|
||||
public boolean apply(Location input) {
|
||||
return input.getId().equals(locationId);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
Image image = null;
|
||||
try {
|
||||
image = Iterables.find(images, new FindImageForInstance(location, instance));
|
||||
} catch (NoSuchElementException e) {
|
||||
logger.warn("could not find a matching image for instance %s in location %s", instance,
|
||||
location);
|
||||
}
|
||||
return new NodeMetadataImpl(id, name, location, uri, userMetadata, tag, image, state,
|
||||
publicAddresses, privateAddresses, extra, credentials);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -114,18 +114,19 @@ public class EC2RunNodesAndAddToSetStrategy implements RunNodesAndAddToSetStrate
|
|||
|
||||
@Override
|
||||
public Map<?, ListenableFuture<Void>> execute(final String tag, final int count,
|
||||
final Template template, final Set<NodeMetadata> nodes) {
|
||||
final Template template, final Set<NodeMetadata> nodes,
|
||||
final Map<NodeMetadata, Exception> badNodes) {
|
||||
checkArgument(template.getSize() instanceof EC2Size,
|
||||
"unexpected image type. should be EC2Size, was: " + template.getSize().getClass());
|
||||
EC2Size ec2Size = EC2Size.class.cast(template.getSize());
|
||||
|
||||
// parse the availability zone of the request
|
||||
String zone = template.getLocation().getScope() == LocationScope.ZONE ? template.getLocation().getId()
|
||||
: null;
|
||||
String zone = template.getLocation().getScope() == LocationScope.ZONE ? template
|
||||
.getLocation().getId() : null;
|
||||
|
||||
// if the location has a parent, it must be an availability zone.
|
||||
String region = zone == null ? template.getLocation().getId() :
|
||||
template.getLocation().getParent().getId();
|
||||
String region = zone == null ? template.getLocation().getId() : template.getLocation()
|
||||
.getParent().getId();
|
||||
|
||||
// get or create incidental resources
|
||||
// TODO race condition. we were using MapMaker, but it doesn't seem to refresh properly when
|
||||
|
@ -174,8 +175,7 @@ public class EC2RunNodesAndAddToSetStrategy implements RunNodesAndAddToSetStrate
|
|||
} catch (Exception e) {
|
||||
logger.error(e, "<< problem applying options to node(%s): ", node.getId(),
|
||||
Throwables.getRootCause(e).getMessage());
|
||||
if (!template.getOptions().shouldDestroyOnError())
|
||||
nodes.add(computeService.getNodeMetadata(node));
|
||||
badNodes.put(computeService.getNodeMetadata(node), e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -49,13 +49,18 @@ import com.google.common.collect.Sets;
|
|||
* />
|
||||
*/
|
||||
public class DescribeImagesResponseHandler extends ParseSax.HandlerWithResult<Set<Image>> {
|
||||
|
||||
@Inject
|
||||
public DescribeImagesResponseHandler(@EC2 String defaultRegion) {
|
||||
this.defaultRegion = defaultRegion;
|
||||
}
|
||||
|
||||
@Resource
|
||||
protected Logger logger = Logger.NULL;
|
||||
@Inject
|
||||
@EC2
|
||||
String defaultRegion;
|
||||
|
||||
private Set<Image> contents = Sets.newLinkedHashSet();
|
||||
private StringBuilder currentText = new StringBuilder();
|
||||
private final String defaultRegion;
|
||||
|
||||
private Architecture architecture;
|
||||
private String name;
|
||||
|
@ -149,10 +154,10 @@ public class DescribeImagesResponseHandler extends ParseSax.HandlerWithResult<Se
|
|||
String region = EC2Utils.findRegionInArgsOrNull(request);
|
||||
if (region == null)
|
||||
region = defaultRegion;
|
||||
contents.add(new Image(region, architecture,
|
||||
this.name, description, imageId, imageLocation, imageOwnerId, imageState,
|
||||
imageType, isPublic, productCodes, kernelId, platform, ramdiskId,
|
||||
rootDeviceType, rootDeviceName, ebsBlockDevices));
|
||||
contents.add(new Image(region, architecture, this.name, description, imageId,
|
||||
imageLocation, imageOwnerId, imageState, imageType, isPublic, productCodes,
|
||||
kernelId, platform, ramdiskId, rootDeviceType, rootDeviceName,
|
||||
ebsBlockDevices));
|
||||
} catch (NullPointerException e) {
|
||||
logger.warn(e, "malformed image: %s", imageId);
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ package org.jclouds.aws.s3.blobstore;
|
|||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.util.concurrent.Futures.compose;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.SortedSet;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
|
@ -84,8 +84,8 @@ public class S3AsyncBlobStore extends BaseAsyncBlobStore {
|
|||
@Inject
|
||||
S3AsyncBlobStore(BlobStoreContext context, BlobStoreUtils blobUtils,
|
||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService service,
|
||||
Location defaultLocation, Map<String, ? extends Location> locations,
|
||||
S3AsyncClient async, S3Client sync, BucketToResourceMetadata bucket2ResourceMd,
|
||||
Location defaultLocation, Set<? extends Location> locations, S3AsyncClient async,
|
||||
S3Client sync, BucketToResourceMetadata bucket2ResourceMd,
|
||||
ContainerToBucketListOptions container2BucketListOptions,
|
||||
BucketToResourceList bucket2ResourceList, ObjectToBlob object2Blob,
|
||||
BlobToHttpGetOptions blob2ObjectGetOptions, BlobToObject blob2Object,
|
||||
|
|
|
@ -20,7 +20,7 @@ package org.jclouds.aws.s3.blobstore;
|
|||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.SortedSet;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
@ -75,7 +75,7 @@ public class S3BlobStore extends BaseBlobStore {
|
|||
|
||||
@Inject
|
||||
S3BlobStore(BlobStoreContext context, BlobStoreUtils blobUtils, Location defaultLocation,
|
||||
Map<String, ? extends Location> locations, S3Client sync,
|
||||
Set<? extends Location> locations, S3Client sync,
|
||||
BucketToResourceMetadata bucket2ResourceMd,
|
||||
ContainerToBucketListOptions container2BucketListOptions,
|
||||
BucketToResourceList bucket2ResourceList, ObjectToBlob object2Blob,
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
*/
|
||||
package org.jclouds.aws.s3.blobstore.config;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
@ -39,8 +38,8 @@ import org.jclouds.domain.Location;
|
|||
import org.jclouds.domain.LocationScope;
|
||||
import org.jclouds.domain.internal.LocationImpl;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.inject.Provides;
|
||||
import com.google.inject.Scopes;
|
||||
|
@ -72,24 +71,26 @@ public class S3BlobStoreContextModule extends S3ContextModule {
|
|||
|
||||
@Provides
|
||||
@Singleton
|
||||
Location getDefaultLocation(@S3 String region, Map<String, ? extends Location> locations) {
|
||||
return locations.get(region.toString());
|
||||
Location getDefaultLocation(@S3 final String region, Set<? extends Location> locations) {
|
||||
return Iterables.find(locations, new Predicate<Location>() {
|
||||
|
||||
@Override
|
||||
public boolean apply(Location input) {
|
||||
return input.getId().equals(region);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
Map<String, ? extends Location> provideLocations(@S3 Set<String> regions) {
|
||||
Set<? extends Location> provideLocations(@S3 Set<String> regions) {
|
||||
Set<Location> locations = Sets.newHashSet();
|
||||
Location s3 = new LocationImpl(LocationScope.PROVIDER, providerName, providerName, null);
|
||||
for (String zone : regions) {
|
||||
locations
|
||||
.add(new LocationImpl(LocationScope.REGION, zone.toString(), zone.toString(), s3));
|
||||
}
|
||||
return Maps.uniqueIndex(locations, new Function<Location, String>() {
|
||||
@Override
|
||||
public String apply(Location from) {
|
||||
return from.getId();
|
||||
}
|
||||
});
|
||||
return locations;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,8 @@
|
|||
*/
|
||||
package org.jclouds.aws.s3.blobstore.functions;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Inject;
|
||||
|
@ -35,6 +36,8 @@ import org.jclouds.domain.Location;
|
|||
import org.jclouds.logging.Logger;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
|
@ -42,13 +45,13 @@ import com.google.common.base.Function;
|
|||
@Singleton
|
||||
public class BucketToResourceMetadata implements Function<BucketMetadata, StorageMetadata> {
|
||||
private final S3Client client;
|
||||
private final Map<String, ? extends Location> locations;
|
||||
private final Set<? extends Location> locations;
|
||||
|
||||
@Resource
|
||||
protected Logger logger = Logger.NULL;
|
||||
|
||||
@Inject
|
||||
BucketToResourceMetadata(S3Client client, Map<String, ? extends Location> locations) {
|
||||
BucketToResourceMetadata(S3Client client, Set<? extends Location> locations) {
|
||||
this.client = client;
|
||||
this.locations = locations;
|
||||
}
|
||||
|
@ -58,12 +61,20 @@ public class BucketToResourceMetadata implements Function<BucketMetadata, Storag
|
|||
to.setName(from.getName());
|
||||
to.setType(StorageType.CONTAINER);
|
||||
try {
|
||||
String region = client.getBucketLocation(from.getName());
|
||||
final String region = client.getBucketLocation(from.getName());
|
||||
if (region != null) {
|
||||
Location location = locations.get(region.toString());
|
||||
if (location == null)
|
||||
try {
|
||||
to.setLocation(Iterables.find(locations, new Predicate<Location>() {
|
||||
|
||||
@Override
|
||||
public boolean apply(Location input) {
|
||||
return input.getId().equals(region.toString());
|
||||
}
|
||||
|
||||
}));
|
||||
} catch (NoSuchElementException e) {
|
||||
logger.error("could not get location for region %s in %s", region, locations);
|
||||
to.setLocation(location);
|
||||
}
|
||||
} else {
|
||||
logger.error("could not get region for %s", from.getName());
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
|||
|
||||
@Test
|
||||
public void testTemplateBuilderCanUseImageId() {
|
||||
client.templateBuilder().imageId(Iterables.get(client.getImages().keySet(), 0)).build();
|
||||
client.templateBuilder().imageId(Iterables.get(client.listImages(), 0).getId()).build();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -41,7 +41,6 @@ import org.jclouds.domain.internal.LocationImpl;
|
|||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
|
@ -116,10 +115,10 @@ public class EC2ComputeServiceTest {
|
|||
.<String, String> newHashMap(), "description", "1.0", null, "ubuntu",
|
||||
Architecture.X86_64, new Credentials("root", null));
|
||||
|
||||
return new TemplateBuilderImpl(ImmutableMap.of("us-east-1", location), ImmutableMap.of(
|
||||
"ami-image", image), Maps.uniqueIndex(ImmutableSet.of(EC2Size.C1_MEDIUM,
|
||||
EC2Size.C1_XLARGE, EC2Size.M1_LARGE, EC2Size.M1_SMALL, EC2Size.M1_XLARGE,
|
||||
EC2Size.M2_XLARGE, EC2Size.M2_2XLARGE, EC2Size.M2_4XLARGE), indexer()), location) {
|
||||
return new TemplateBuilderImpl(ImmutableSet.of(location), ImmutableSet.of(image),
|
||||
ImmutableSet.of(EC2Size.C1_MEDIUM, EC2Size.C1_XLARGE, EC2Size.M1_LARGE,
|
||||
EC2Size.M1_SMALL, EC2Size.M1_XLARGE, EC2Size.M2_XLARGE, EC2Size.M2_2XLARGE,
|
||||
EC2Size.M2_4XLARGE), location) {
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -32,11 +32,14 @@ import org.jclouds.aws.ec2.xml.BaseEC2HandlerTest;
|
|||
import org.jclouds.aws.ec2.xml.DescribeImagesResponseHandler;
|
||||
import org.jclouds.compute.domain.OsFamily;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.domain.LocationScope;
|
||||
import org.jclouds.domain.internal.LocationImpl;
|
||||
import org.jclouds.http.functions.ParseSax;
|
||||
import org.jclouds.rest.internal.GeneratedHttpRequest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
/**
|
||||
|
@ -52,15 +55,15 @@ public class ImageParserTest extends BaseEC2HandlerTest {
|
|||
assertEquals(result.size(), 6);
|
||||
|
||||
ImageParser parser = new ImageParser(
|
||||
new EC2PopulateDefaultLoginCredentialsForImageStrategy(), ImmutableMap
|
||||
.<String, Location> of());
|
||||
new EC2PopulateDefaultLoginCredentialsForImageStrategy(), ImmutableSet
|
||||
.<Location> of(defaultLocation), defaultLocation);
|
||||
org.jclouds.compute.domain.Image ubuntuHardy = parser.apply(Iterables.get(result, 0));
|
||||
|
||||
assertEquals(ubuntuHardy.getArchitecture(), org.jclouds.compute.domain.Architecture.X86_32);
|
||||
assertEquals(ubuntuHardy.getDescription(),
|
||||
"ubuntu-images-us/ubuntu-hardy-8.04-i386-server-20091130.manifest.xml");
|
||||
assertEquals(ubuntuHardy.getId(), "ami-7e28ca17");
|
||||
assertEquals(ubuntuHardy.getLocation(), null);
|
||||
assertEquals(ubuntuHardy.getLocation(), defaultLocation);
|
||||
assertEquals(ubuntuHardy.getName(), "8.04");
|
||||
assertEquals(ubuntuHardy.getOsDescription(),
|
||||
"ubuntu-images-us/ubuntu-hardy-8.04-i386-server-20091130.manifest.xml");
|
||||
|
@ -75,7 +78,7 @@ public class ImageParserTest extends BaseEC2HandlerTest {
|
|||
assertEquals(alesticKarmic.getDescription(),
|
||||
"alestic/ubuntu-9.10-karmic-base-20090623.manifest.xml");
|
||||
assertEquals(alesticKarmic.getId(), "ami-19a34270");
|
||||
assertEquals(alesticKarmic.getLocation(), null);
|
||||
assertEquals(alesticKarmic.getLocation(), defaultLocation);
|
||||
assertEquals(alesticKarmic.getName(), "9.10");
|
||||
assertEquals(alesticKarmic.getOsDescription(),
|
||||
"alestic/ubuntu-9.10-karmic-base-20090623.manifest.xml");
|
||||
|
@ -90,7 +93,7 @@ public class ImageParserTest extends BaseEC2HandlerTest {
|
|||
assertEquals(ubuntuKarmic.getDescription(),
|
||||
"ubuntu-images-us/ubuntu-karmic-9.10-i386-server-20100121.manifest.xml");
|
||||
assertEquals(ubuntuKarmic.getId(), "ami-bb709dd2");
|
||||
assertEquals(ubuntuKarmic.getLocation(), null);
|
||||
assertEquals(ubuntuKarmic.getLocation(), defaultLocation);
|
||||
assertEquals(ubuntuKarmic.getName(), "9.10");
|
||||
assertEquals(ubuntuKarmic.getOsDescription(),
|
||||
"ubuntu-images-us/ubuntu-karmic-9.10-i386-server-20100121.manifest.xml");
|
||||
|
@ -108,7 +111,7 @@ public class ImageParserTest extends BaseEC2HandlerTest {
|
|||
assertEquals(alesticHardy.getDescription(),
|
||||
"alestic/ubuntu-8.04-hardy-base-20080905.manifest.xml");
|
||||
assertEquals(alesticHardy.getId(), "ami-c0fa1ea9");
|
||||
assertEquals(alesticHardy.getLocation(), null);
|
||||
assertEquals(alesticHardy.getLocation(), defaultLocation);
|
||||
assertEquals(alesticHardy.getName(), "8.04");
|
||||
assertEquals(alesticHardy.getOsDescription(),
|
||||
"alestic/ubuntu-8.04-hardy-base-20080905.manifest.xml");
|
||||
|
@ -121,14 +124,17 @@ public class ImageParserTest extends BaseEC2HandlerTest {
|
|||
assert parser.apply(Iterables.get(result, 5)) == null;
|
||||
}
|
||||
|
||||
private Location defaultLocation = new LocationImpl(LocationScope.REGION, "us-east-1",
|
||||
"us-east-1", null);
|
||||
|
||||
public void testParseVostokImage() {
|
||||
InputStream is = getClass().getResourceAsStream("/ec2/vostok.xml");
|
||||
|
||||
Set<Image> result = parseImages(is);
|
||||
|
||||
ImageParser parser = new ImageParser(
|
||||
new EC2PopulateDefaultLoginCredentialsForImageStrategy(), ImmutableMap
|
||||
.<String, Location> of());
|
||||
new EC2PopulateDefaultLoginCredentialsForImageStrategy(), ImmutableSet
|
||||
.<Location> of(defaultLocation), defaultLocation);
|
||||
|
||||
org.jclouds.compute.domain.Image image = parser.apply(Iterables.get(result, 0));
|
||||
|
||||
|
@ -136,7 +142,7 @@ public class ImageParserTest extends BaseEC2HandlerTest {
|
|||
assertEquals(image.getDescription(),
|
||||
"vostok-builds/vostok-0.95-5622/vostok-0.95-5622.manifest.xml");
|
||||
assertEquals(image.getId(), "ami-870de2ee");
|
||||
assertEquals(image.getLocation(), null);
|
||||
assertEquals(image.getLocation(), defaultLocation);
|
||||
assertEquals(image.getName(), "");
|
||||
assertEquals(image.getOsDescription(),
|
||||
"vostok-builds/vostok-0.95-5622/vostok-0.95-5622.manifest.xml");
|
||||
|
|
|
@ -20,7 +20,6 @@ package org.jclouds.aws.ec2.compute.functions;
|
|||
|
||||
import static org.easymock.EasyMock.expect;
|
||||
import static org.easymock.classextension.EasyMock.createMock;
|
||||
import static org.easymock.classextension.EasyMock.createNiceMock;
|
||||
import static org.easymock.classextension.EasyMock.replay;
|
||||
import static org.easymock.classextension.EasyMock.verify;
|
||||
import static org.jclouds.aws.ec2.options.DescribeImagesOptions.Builder.imageIds;
|
||||
|
@ -29,6 +28,7 @@ import static org.testng.Assert.assertEquals;
|
|||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jclouds.aws.domain.Region;
|
||||
import org.jclouds.aws.ec2.compute.domain.RegionTag;
|
||||
|
@ -62,19 +62,19 @@ public class RunningInstanceToNodeMetadataTest {
|
|||
throws UnknownHostException {
|
||||
AMIClient amiClient = createMock(AMIClient.class);
|
||||
Map<RegionTag, KeyPair> credentialsMap = createMock(Map.class);
|
||||
Map<String, org.jclouds.compute.domain.Image> images = createMock(Map.class);
|
||||
Map<String, Location> locations = createMock(Map.class);
|
||||
org.jclouds.compute.domain.Image jcImage = createMock(org.jclouds.compute.domain.Image.class);
|
||||
|
||||
Set<org.jclouds.compute.domain.Image> images = ImmutableSet
|
||||
.<org.jclouds.compute.domain.Image> of(jcImage);
|
||||
|
||||
Location location = new LocationImpl(LocationScope.ZONE, "us-east-1a", "description", null);
|
||||
Set<Location> locations = ImmutableSet.<Location> of(location);
|
||||
PopulateDefaultLoginCredentialsForImageStrategy credentialProvider = createMock(PopulateDefaultLoginCredentialsForImageStrategy.class);
|
||||
RunningInstance instance = createMock(RunningInstance.class);
|
||||
|
||||
expect(instance.getId()).andReturn("id").atLeastOnce();
|
||||
expect(instance.getKeyName()).andReturn(null).atLeastOnce();
|
||||
expect(instance.getInstanceState()).andReturn(InstanceState.RUNNING);
|
||||
Location location = new LocationImpl(LocationScope.ZONE, "us-east-1a", "description", null);
|
||||
expect(locations.get("us-east-1a")).andReturn(location);
|
||||
|
||||
org.jclouds.compute.domain.Image jcImage = createNiceMock(org.jclouds.compute.domain.Image.class);
|
||||
expect(images.get("imageId")).andReturn(jcImage);
|
||||
|
||||
expect(instance.getIpAddress()).andReturn(
|
||||
InetAddress.getByAddress(new byte[] { 12, 10, 10, 1 }));
|
||||
|
@ -84,32 +84,32 @@ public class RunningInstanceToNodeMetadataTest {
|
|||
expect(instance.getAvailabilityZone()).andReturn(AvailabilityZone.US_EAST_1A).atLeastOnce();
|
||||
|
||||
expect(instance.getImageId()).andReturn("imageId").atLeastOnce();
|
||||
expect(jcImage.getId()).andReturn("imageId").atLeastOnce();
|
||||
expect(jcImage.getLocation()).andReturn(location).atLeastOnce();
|
||||
|
||||
expect(instance.getInstanceType()).andReturn(InstanceType.C1_XLARGE).atLeastOnce();
|
||||
|
||||
replay(jcImage);
|
||||
replay(amiClient);
|
||||
replay(credentialsMap);
|
||||
replay(credentialProvider);
|
||||
replay(instance);
|
||||
replay(images);
|
||||
replay(locations);
|
||||
|
||||
RunningInstanceToNodeMetadata parser = new RunningInstanceToNodeMetadata(amiClient,
|
||||
credentialsMap, credentialProvider, images, locations,
|
||||
new RunningInstanceToStorageMappingUnix());
|
||||
|
||||
NodeMetadata metadata = parser.apply(instance);
|
||||
assertEquals(metadata.getLocation(), location);
|
||||
assertEquals(metadata.getLocation(), locations.iterator().next());
|
||||
assertEquals(metadata.getImage(), jcImage);
|
||||
assertEquals(metadata.getTag(), "NOTAG-id");
|
||||
assertEquals(metadata.getCredentials(), null);
|
||||
|
||||
verify(jcImage);
|
||||
verify(amiClient);
|
||||
verify(credentialsMap);
|
||||
verify(credentialProvider);
|
||||
verify(instance);
|
||||
verify(images);
|
||||
verify(locations);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
@ -118,8 +118,6 @@ public class RunningInstanceToNodeMetadataTest {
|
|||
throws UnknownHostException {
|
||||
AMIClient amiClient = createMock(AMIClient.class);
|
||||
Map<RegionTag, KeyPair> credentialsMap = createMock(Map.class);
|
||||
Map<String, org.jclouds.compute.domain.Image> images = createMock(Map.class);
|
||||
Map<String, Location> locations = createMock(Map.class);
|
||||
|
||||
PopulateDefaultLoginCredentialsForImageStrategy credentialProvider = createMock(PopulateDefaultLoginCredentialsForImageStrategy.class);
|
||||
RunningInstance instance = createMock(RunningInstance.class);
|
||||
|
@ -130,10 +128,10 @@ public class RunningInstanceToNodeMetadataTest {
|
|||
expect(instance.getInstanceState()).andReturn(InstanceState.RUNNING);
|
||||
|
||||
Location location = new LocationImpl(LocationScope.ZONE, "us-east-1a", "description", null);
|
||||
expect(locations.get("us-east-1a")).andReturn(location);
|
||||
|
||||
org.jclouds.compute.domain.Image jcImage = createNiceMock(org.jclouds.compute.domain.Image.class);
|
||||
expect(images.get("imageId")).andReturn(jcImage);
|
||||
Set<Location> locations = ImmutableSet.<Location> of(location);
|
||||
org.jclouds.compute.domain.Image jcImage = createMock(org.jclouds.compute.domain.Image.class);
|
||||
Set<org.jclouds.compute.domain.Image> images = ImmutableSet
|
||||
.<org.jclouds.compute.domain.Image> of(jcImage);
|
||||
|
||||
expect(instance.getIpAddress()).andReturn(
|
||||
InetAddress.getByAddress(new byte[] { 12, 10, 10, 1 }));
|
||||
|
@ -143,6 +141,8 @@ public class RunningInstanceToNodeMetadataTest {
|
|||
expect(instance.getRegion()).andReturn(Region.US_EAST_1).atLeastOnce();
|
||||
|
||||
expect(instance.getImageId()).andReturn("imageId").atLeastOnce();
|
||||
expect(jcImage.getId()).andReturn("imageId").atLeastOnce();
|
||||
expect(jcImage.getLocation()).andReturn(location).atLeastOnce();
|
||||
|
||||
expect(amiClient.describeImagesInRegion(Region.US_EAST_1, imageIds("imageId"))).andReturn(
|
||||
ImmutableSet.<Image> of(image));
|
||||
|
@ -160,8 +160,7 @@ public class RunningInstanceToNodeMetadataTest {
|
|||
replay(credentialsMap);
|
||||
replay(credentialProvider);
|
||||
replay(instance);
|
||||
replay(images);
|
||||
replay(locations);
|
||||
replay(jcImage);
|
||||
|
||||
RunningInstanceToNodeMetadata parser = new RunningInstanceToNodeMetadata(amiClient,
|
||||
credentialsMap, credentialProvider, images, locations,
|
||||
|
@ -175,12 +174,12 @@ public class RunningInstanceToNodeMetadataTest {
|
|||
|
||||
assertEquals(metadata.getCredentials(), new Credentials("user", "pass"));
|
||||
|
||||
verify(jcImage);
|
||||
verify(amiClient);
|
||||
verify(credentialsMap);
|
||||
verify(credentialProvider);
|
||||
verify(instance);
|
||||
verify(images);
|
||||
verify(locations);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -27,7 +27,6 @@ import java.util.Set;
|
|||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.jclouds.aws.domain.Region;
|
||||
import org.jclouds.aws.ec2.EC2AsyncClient;
|
||||
import org.jclouds.aws.ec2.EC2Client;
|
||||
import org.jclouds.aws.ec2.EC2ContextFactory;
|
||||
|
|
|
@ -22,7 +22,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||
import static com.google.common.util.concurrent.Futures.compose;
|
||||
import static org.jclouds.azure.storage.options.ListOptions.Builder.includeMetadata;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
@ -77,7 +77,7 @@ public class AzureAsyncBlobStore extends BaseAsyncBlobStore {
|
|||
@Inject
|
||||
AzureAsyncBlobStore(BlobStoreContext context, BlobStoreUtils blobUtils,
|
||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService service,
|
||||
Location defaultLocation, Map<String, ? extends Location> locations,
|
||||
Location defaultLocation, Set<? extends Location> locations,
|
||||
|
||||
AzureBlobAsyncClient async, ContainerToResourceMetadata container2ResourceMd,
|
||||
ListOptionsToListBlobsOptions blobStore2AzureContainerListOptions,
|
||||
|
|
|
@ -21,7 +21,7 @@ package org.jclouds.azure.storage.blob.blobstore;
|
|||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.jclouds.azure.storage.options.ListOptions.Builder.includeMetadata;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
@ -68,7 +68,7 @@ public class AzureBlobStore extends BaseBlobStore {
|
|||
|
||||
@Inject
|
||||
AzureBlobStore(BlobStoreContext context, BlobStoreUtils blobUtils, Location defaultLocation,
|
||||
Map<String, ? extends Location> locations, AzureBlobClient sync,
|
||||
Set<? extends Location> locations, AzureBlobClient sync,
|
||||
ContainerToResourceMetadata container2ResourceMd,
|
||||
ListOptionsToListBlobsOptions blobStore2AzureContainerListOptions,
|
||||
ListBlobsResponseToResourceList azure2BlobStoreResourceList,
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
package org.jclouds.azure.storage.blob.blobstore.config;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
||||
|
@ -39,7 +39,7 @@ import org.jclouds.domain.Location;
|
|||
import org.jclouds.domain.LocationScope;
|
||||
import org.jclouds.domain.internal.LocationImpl;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.inject.Provides;
|
||||
import com.google.inject.Scopes;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
@ -72,7 +72,7 @@ public class AzureBlobStoreContextModule extends AzureBlobContextModule {
|
|||
|
||||
@Provides
|
||||
@Singleton
|
||||
Map<String, ? extends Location> provideLocations(Location location) {
|
||||
return ImmutableMap.of(location.getId(), location);
|
||||
Set<? extends Location> provideLocations(Location location) {
|
||||
return ImmutableSet.of(location);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -135,7 +135,7 @@ Options can also be specified for extension modules
|
|||
"Retrieve the available container locations for the blobstore context."
|
||||
([] (locations *blobstore*))
|
||||
([#^BlobStore blobstore]
|
||||
(seq-from-immutable-set (.getAssignableLocations blobstore))))
|
||||
(seq (.listAssignableLocations blobstore))))
|
||||
|
||||
(defn create-container
|
||||
"Create a container."
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
package org.jclouds.blobstore;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
|
@ -49,9 +49,9 @@ public interface AsyncBlobStore {
|
|||
Blob newBlob(String name);
|
||||
|
||||
/**
|
||||
* @see BlobStore#getAssignableLocations
|
||||
* @see BlobStore#listAssignableLocations
|
||||
*/
|
||||
ListenableFuture<? extends Map<String, ? extends Location>> getAssignableLocations();
|
||||
ListenableFuture<? extends Set<? extends Location>> listAssignableLocations();
|
||||
|
||||
/**
|
||||
* @see BlobStore#list
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
package org.jclouds.blobstore;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
|
@ -50,12 +50,12 @@ public interface BlobStore {
|
|||
Blob newBlob(String name);
|
||||
|
||||
/**
|
||||
* The get locations command returns all the valid locations for containers. 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 get locations command returns all the valid locations for containers. 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.
|
||||
*/
|
||||
Map<String, ? extends Location> getAssignableLocations();
|
||||
Set<? extends Location> listAssignableLocations();
|
||||
|
||||
/**
|
||||
* Lists all root-level resources available to the account.
|
||||
|
|
|
@ -38,6 +38,7 @@ import java.util.Collection;
|
|||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
import java.util.Map.Entry;
|
||||
|
@ -112,7 +113,7 @@ public class TransientAsyncBlobStore extends BaseAsyncBlobStore {
|
|||
IfDirectoryReturnNameStrategy ifDirectoryReturnName, Blob.Factory blobFactory,
|
||||
BlobStoreUtils blobUtils,
|
||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService service,
|
||||
Location defaultLocation, Map<String, Location> locations) {
|
||||
Location defaultLocation, Set<Location> locations) {
|
||||
super(context, blobUtils, service, defaultLocation, locations);
|
||||
this.blobFactory = blobFactory;
|
||||
this.dateService = dateService;
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
package org.jclouds.blobstore.config;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
|
@ -30,7 +30,7 @@ import org.jclouds.blobstore.domain.Blob;
|
|||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.util.Jsr330;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Provides;
|
||||
import com.google.inject.Scopes;
|
||||
|
@ -55,7 +55,7 @@ public class TransientBlobStoreModule extends AbstractModule {
|
|||
|
||||
@Provides
|
||||
@Singleton
|
||||
Map<String, Location> provideLocations(Location defaultLocation) {
|
||||
return ImmutableMap.<String, Location> of(defaultLocation.getId(), defaultLocation);
|
||||
Set<Location> provideLocations(Location defaultLocation) {
|
||||
return ImmutableSet.of( defaultLocation);
|
||||
}
|
||||
}
|
|
@ -24,7 +24,7 @@ import static com.google.common.util.concurrent.Futures.immediateFuture;
|
|||
import static org.jclouds.blobstore.options.ListContainerOptions.Builder.recursive;
|
||||
import static org.jclouds.concurrent.ConcurrentUtils.makeListenable;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
|
@ -58,12 +58,12 @@ public abstract class BaseAsyncBlobStore implements AsyncBlobStore {
|
|||
protected final BlobStoreUtils blobUtils;
|
||||
protected final ExecutorService service;
|
||||
protected final Location defaultLocation;
|
||||
protected final Map<String, ? extends Location> locations;
|
||||
protected final Set<? extends Location> locations;
|
||||
|
||||
@Inject
|
||||
protected BaseAsyncBlobStore(BlobStoreContext context, BlobStoreUtils blobUtils,
|
||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService service,
|
||||
Location defaultLocation, Map<String, ? extends Location> locations) {
|
||||
Location defaultLocation, Set<? extends Location> locations) {
|
||||
this.context = checkNotNull(context, "context");
|
||||
this.blobUtils = checkNotNull(blobUtils, "blobUtils");
|
||||
this.service = checkNotNull(service, "service");
|
||||
|
@ -271,7 +271,7 @@ public abstract class BaseAsyncBlobStore implements AsyncBlobStore {
|
|||
}
|
||||
|
||||
@Override
|
||||
public ListenableFuture<? extends Map<String, ? extends Location>> getAssignableLocations() {
|
||||
public ListenableFuture<? extends Set<? extends Location>> listAssignableLocations() {
|
||||
return immediateFuture(locations);
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ package org.jclouds.blobstore.internal;
|
|||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.jclouds.blobstore.options.ListContainerOptions.Builder.recursive;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
|
@ -48,11 +48,11 @@ public abstract class BaseBlobStore implements BlobStore {
|
|||
protected final BlobStoreContext context;
|
||||
protected final BlobStoreUtils blobUtils;
|
||||
protected final Location defaultLocation;
|
||||
protected final Map<String, ? extends Location> locations;
|
||||
protected final Set<? extends Location> locations;
|
||||
|
||||
@Inject
|
||||
protected BaseBlobStore(BlobStoreContext context, BlobStoreUtils blobUtils,
|
||||
Location defaultLocation, Map<String, ? extends Location> locations) {
|
||||
Location defaultLocation, Set<? extends Location> locations) {
|
||||
this.context = checkNotNull(context, "context");
|
||||
this.blobUtils = checkNotNull(blobUtils, "blobUtils");
|
||||
this.defaultLocation = checkNotNull(defaultLocation, "defaultLocation");
|
||||
|
@ -213,7 +213,7 @@ public abstract class BaseBlobStore implements BlobStore {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Map<String, ? extends Location> getAssignableLocations() {
|
||||
public Set<? extends Location> listAssignableLocations() {
|
||||
return locations;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,6 @@ package org.jclouds.blobstore.integration.internal;
|
|||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.jclouds.blobstore.domain.PageSet;
|
||||
import org.jclouds.blobstore.domain.StorageMetadata;
|
||||
|
@ -47,7 +46,7 @@ public class BaseServiceIntegrationTest extends BaseBlobStoreIntegrationTest {
|
|||
|
||||
@Test(groups = { "integration", "live" })
|
||||
public void testAllLocations() throws InterruptedException {
|
||||
for (final Location location : context.getBlobStore().getAssignableLocations().values()) {
|
||||
for (final Location location : context.getBlobStore().listAssignableLocations()) {
|
||||
final String containerName = getScratchContainerName();
|
||||
try {
|
||||
System.err.printf(" >> creating container in location %s%n", location);
|
||||
|
@ -77,32 +76,31 @@ public class BaseServiceIntegrationTest extends BaseBlobStoreIntegrationTest {
|
|||
|
||||
@Test(groups = { "integration", "live" })
|
||||
public void testGetAssignableLocations() throws Exception {
|
||||
for (Entry<String, ? extends Location> location : context.getBlobStore()
|
||||
.getAssignableLocations().entrySet()) {
|
||||
System.err.printf("location %s%n", location.getValue());
|
||||
assertEquals(location.getKey(), location.getValue().getId());
|
||||
assert location.getValue().getId() != null : location;
|
||||
assert location.getValue() != location.getValue().getParent() : location;
|
||||
assert location.getValue().getScope() != null : location;
|
||||
switch (location.getValue().getScope()) {
|
||||
for (Location location : context.getBlobStore()
|
||||
.listAssignableLocations()) {
|
||||
System.err.printf("location %s%n", location);
|
||||
assert location.getId() != null : location;
|
||||
assert location != location.getParent() : location;
|
||||
assert location.getScope() != null : location;
|
||||
switch (location.getScope()) {
|
||||
case PROVIDER:
|
||||
assertProvider(location.getValue());
|
||||
assertProvider(location);
|
||||
break;
|
||||
case REGION:
|
||||
assertProvider(location.getValue().getParent());
|
||||
assertProvider(location.getParent());
|
||||
break;
|
||||
case ZONE:
|
||||
Location provider = location.getValue().getParent().getParent();
|
||||
Location provider = location.getParent().getParent();
|
||||
// zone can be a direct descendant of provider
|
||||
if (provider == null)
|
||||
provider = location.getValue().getParent();
|
||||
provider = location.getParent();
|
||||
assertProvider(provider);
|
||||
break;
|
||||
case HOST:
|
||||
Location provider2 = location.getValue().getParent().getParent().getParent();
|
||||
Location provider2 = location.getParent().getParent().getParent();
|
||||
// zone can be a direct descendant of provider
|
||||
if (provider2 == null)
|
||||
provider2 = location.getValue().getParent().getParent();
|
||||
provider2 = location.getParent().getParent();
|
||||
assertProvider(provider2);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -117,11 +117,11 @@ See http://code.google.com/p/jclouds for details."
|
|||
"Retrieve the available compute locations for the compute context."
|
||||
([] (locations *compute*))
|
||||
([#^ComputeService compute]
|
||||
(seq-from-immutable-set (.getAssignableLocations compute))))
|
||||
(seq (.listAssignableLocations compute))))
|
||||
|
||||
(defn nodes-with-tag
|
||||
[#^String tag #^ComputeService compute]
|
||||
(seq-from-immutable-set (.getNodesWithTag compute tag)))
|
||||
(seq (.listNodesWithTag compute tag)))
|
||||
|
||||
(def #^{:private true} list-nodes-map
|
||||
{ :with-details #(when %2 (.withDetails %1)) })
|
||||
|
@ -139,20 +139,20 @@ See http://code.google.com/p/jclouds for details."
|
|||
((list-nodes-map k) lno v)
|
||||
lno)
|
||||
(GetNodesOptions.) options)]
|
||||
(seq-from-immutable-set (.getNodes compute-or-tag list-nodes-options)))
|
||||
(seq (.listNodes compute-or-tag list-nodes-options)))
|
||||
(nodes-with-tag compute-or-tag *compute*))))
|
||||
|
||||
(defn images
|
||||
"Retrieve the available images for the compute context."
|
||||
([] (images *compute*))
|
||||
([#^ComputeService compute]
|
||||
(seq-from-immutable-set (.getImages compute))))
|
||||
(seq (.listImages compute))))
|
||||
|
||||
(defn sizes
|
||||
"Retrieve the available node sizes for the compute context."
|
||||
([] (sizes *compute*))
|
||||
([#^ComputeService compute]
|
||||
(seq-from-immutable-set (.getSizes compute))))
|
||||
(seq (.listSizes compute))))
|
||||
|
||||
(defn default-template
|
||||
([] (default-template *compute*))
|
||||
|
@ -193,7 +193,7 @@ See http://code.google.com/p/jclouds for details."
|
|||
tag count (default-template compute-or-template) compute-or-template)
|
||||
(run-nodes tag count compute-or-template *compute*)))
|
||||
([tag count template #^ComputeService compute]
|
||||
(seq-from-immutable-set
|
||||
(seq
|
||||
(.runNodesWithTag compute tag count template))))
|
||||
|
||||
(defn run-node
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
package org.jclouds.compute;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jclouds.compute.domain.ComputeMetadata;
|
||||
import org.jclouds.compute.domain.Image;
|
||||
|
@ -54,14 +55,14 @@ public interface ComputeService {
|
|||
TemplateBuilder templateBuilder();
|
||||
|
||||
/**
|
||||
* The get sizes command shows you the options including virtual cpu count, memory, and disks.
|
||||
* The list sizes 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 sizes by ID, conceding that in some clouds the "id" is not used.
|
||||
*/
|
||||
Map<String, ? extends Size> getSizes();
|
||||
Set<? extends Size> listSizes();
|
||||
|
||||
/**
|
||||
* Images define the operating system and metadata related to a node. In some clouds, Images are
|
||||
|
@ -70,27 +71,27 @@ public interface ComputeService {
|
|||
* TemplateBuilder as opposed to choosing an image explicitly. The getImages() command returns a
|
||||
* map of images by id.
|
||||
*/
|
||||
Map<String, ? extends Image> getImages();
|
||||
Set<? extends Image> listImages();
|
||||
|
||||
/**
|
||||
* all nodes available to the current user by id. If possible, the returned set will include
|
||||
* {@link NodeMetadata} objects.
|
||||
*/
|
||||
Map<String, ? extends ComputeMetadata> getNodes();
|
||||
Set<? extends ComputeMetadata> listNodes();
|
||||
|
||||
/**
|
||||
/**
|
||||
* all nodes available to the current user by id. If possible, the returned set will include
|
||||
* {@link NodeMetadata} objects.
|
||||
*/
|
||||
Map<String, ? extends ComputeMetadata> getNodes(GetNodesOptions options);
|
||||
Set<? extends ComputeMetadata> listNodes(GetNodesOptions options);
|
||||
|
||||
/**
|
||||
* The get locations command returns all the valid locations for nodes. A location has a scope,
|
||||
* 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.
|
||||
*/
|
||||
Map<String, ? extends Location> getAssignableLocations();
|
||||
Set<? extends Location> listAssignableLocations();
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -122,8 +123,13 @@ public interface ComputeService {
|
|||
* @param template
|
||||
* - how to configure the nodes
|
||||
* @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.
|
||||
*/
|
||||
Map<String, ? extends NodeMetadata> runNodesWithTag(String tag, int count, Template template);
|
||||
Set<? extends NodeMetadata> runNodesWithTag(String tag, int count, Template template)
|
||||
throws RunNodesException;
|
||||
|
||||
/**
|
||||
* destroy the node. If it is the only node in a tag set, the dependent resources will also be
|
||||
|
@ -159,27 +165,32 @@ public interface ComputeService {
|
|||
*
|
||||
* @param tag
|
||||
*/
|
||||
Map<String, ? extends NodeMetadata> getNodesWithTag(String tag);
|
||||
|
||||
/**
|
||||
* Runs the script without any additional options
|
||||
*
|
||||
* @see #runScriptOnNodesWithTag(String,
|
||||
* byte[], org.jclouds.compute.options.RunScriptOptions)
|
||||
*/
|
||||
Map<String, ExecResponse> runScriptOnNodesWithTag(String tag,
|
||||
byte[] runScript);
|
||||
Set<? extends NodeMetadata> listNodesWithTag(String tag);
|
||||
|
||||
/**
|
||||
* Run the script on all nodes with the specific tag.
|
||||
*
|
||||
* @param tag tag to look up the nodes
|
||||
* @param runScript script to run in byte format. If the script is a string, use
|
||||
* {@link String#getBytes()} to retrieve the bytes
|
||||
* @param options nullable options to how to run the script
|
||||
* @return map with node identifiers and corresponding responses
|
||||
*/
|
||||
Map<String, ExecResponse> runScriptOnNodesWithTag(String tag,
|
||||
byte[] runScript, RunScriptOptions options);
|
||||
* Runs the script without any additional options
|
||||
*
|
||||
* @see #runScriptOnNodesWithTag(String, byte[], org.jclouds.compute.options.RunScriptOptions)
|
||||
*/
|
||||
Map<NodeMetadata, ExecResponse> runScriptOnNodesWithTag(String tag, byte[] runScript)
|
||||
throws RunScriptOnNodesException;
|
||||
|
||||
/**
|
||||
* Run the script on all nodes with the specific tag.
|
||||
*
|
||||
* @param tag
|
||||
* tag to look up the nodes
|
||||
* @param runScript
|
||||
* script to run in byte format. If the script is a string, use
|
||||
* {@link String#getBytes()} to retrieve the bytes
|
||||
* @param options
|
||||
* nullable options to how to run the script
|
||||
* @return map with node identifiers and corresponding responses
|
||||
* @throws RunScriptOnNodesException
|
||||
* when there's a problem running the script on the nodes. Note that successful and
|
||||
* failed nodes are a part of this exception, so be sure to inspect this carefully.
|
||||
*/
|
||||
Map<NodeMetadata, ExecResponse> runScriptOnNodesWithTag(String tag, byte[] runScript,
|
||||
RunScriptOptions options) throws RunScriptOnNodesException;
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,99 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.compute;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.compute.util.ComputeUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class RunNodesException extends Exception {
|
||||
|
||||
/** The serialVersionUID */
|
||||
private static final long serialVersionUID = -2272965726680821281L;
|
||||
private final String tag;
|
||||
private final int count;
|
||||
private final Template template;
|
||||
private final Set<? extends NodeMetadata> successfulNodes;
|
||||
private final Map<? extends NodeMetadata, ? extends Throwable> failedNodes;
|
||||
private final Map<?, Exception> executionExceptions;
|
||||
|
||||
public RunNodesException(String tag, int count, Template template,
|
||||
Set<? extends NodeMetadata> successfulNodes, Map<?, Exception> executionExceptions,
|
||||
Map<? extends NodeMetadata, ? extends Throwable> failedNodes) {
|
||||
super(
|
||||
String
|
||||
.format(
|
||||
"error running %d node%s tag(%s) location(%s) image(%s) size(%s) options(%s)%n%s%n%s",
|
||||
count, count > 1 ? "s" : "", tag, template.getLocation().getId(),
|
||||
template.getImage().getId(), template.getSize().getId(), template
|
||||
.getOptions(), ComputeUtils
|
||||
.createExecutionErrorMessage(executionExceptions),
|
||||
ComputeUtils.createNodeErrorMessage(failedNodes)));
|
||||
this.tag = tag;
|
||||
this.count = count;
|
||||
this.template = template;
|
||||
this.successfulNodes = successfulNodes;
|
||||
this.failedNodes = failedNodes;
|
||||
this.executionExceptions = executionExceptions;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return Nodes that performed startup without error
|
||||
*/
|
||||
public Set<? extends NodeMetadata> getSuccessfulNodes() {
|
||||
return successfulNodes;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return Nodes that performed startup without error, but incurred problems applying options
|
||||
*/
|
||||
public Map<?, ? extends Throwable> getExecutionErrors() {
|
||||
return executionExceptions;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return Nodes that performed startup without error, but incurred problems applying options
|
||||
*/
|
||||
public Map<? extends NodeMetadata, ? extends Throwable> getNodeErrors() {
|
||||
return failedNodes;
|
||||
}
|
||||
|
||||
public String getTag() {
|
||||
return tag;
|
||||
}
|
||||
|
||||
public int getCount() {
|
||||
return count;
|
||||
}
|
||||
|
||||
public Template getTemplate() {
|
||||
return template;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.compute;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.options.RunScriptOptions;
|
||||
import org.jclouds.compute.util.ComputeUtils;
|
||||
import org.jclouds.ssh.ExecResponse;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class RunScriptOnNodesException extends Exception {
|
||||
|
||||
/** The serialVersionUID */
|
||||
private static final long serialVersionUID = -2272965726680821281L;
|
||||
private final String tag;
|
||||
private final byte[] runScript;
|
||||
private final RunScriptOptions options;
|
||||
private final Map<NodeMetadata, ExecResponse> successfulNodes;
|
||||
private final Map<? extends NodeMetadata, ? extends Throwable> failedNodes;
|
||||
private final Map<?, Exception> executionExceptions;
|
||||
|
||||
public RunScriptOnNodesException(String tag, final byte[] runScript,
|
||||
@Nullable final RunScriptOptions options,
|
||||
Map<NodeMetadata, ExecResponse> successfulNodes, Map<?, Exception> executionExceptions,
|
||||
Map<? extends NodeMetadata, ? extends Throwable> failedNodes) {
|
||||
super(String.format("error runScript on node tag(%s) options(%s) exceptions: %s", tag,
|
||||
options, ComputeUtils.createExecutionErrorMessage(executionExceptions), ComputeUtils
|
||||
.createNodeErrorMessage(failedNodes)));
|
||||
this.tag = tag;
|
||||
this.runScript = runScript;
|
||||
this.options = options;
|
||||
this.successfulNodes = successfulNodes;
|
||||
this.failedNodes = failedNodes;
|
||||
this.executionExceptions = executionExceptions;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return Nodes that performed ssh without error
|
||||
*/
|
||||
public Map<NodeMetadata, ExecResponse> getSuccessfulNodes() {
|
||||
return successfulNodes;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return Nodes that performed startup without error, but incurred problems applying options
|
||||
*/
|
||||
public Map<?, ? extends Throwable> getExecutionErrors() {
|
||||
return executionExceptions;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return Nodes that performed startup without error, but incurred problems applying options
|
||||
*/
|
||||
public Map<? extends NodeMetadata, ? extends Throwable> getNodeErrors() {
|
||||
return failedNodes;
|
||||
}
|
||||
|
||||
public String getTag() {
|
||||
return tag;
|
||||
}
|
||||
|
||||
public byte[] getRunScript() {
|
||||
return runScript;
|
||||
}
|
||||
|
||||
public RunScriptOptions getOptions() {
|
||||
return options;
|
||||
}
|
||||
|
||||
}
|
|
@ -31,7 +31,6 @@ import static org.jclouds.util.Utils.checkNotEmpty;
|
|||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
|
@ -45,6 +44,8 @@ import javax.inject.Singleton;
|
|||
import org.jclouds.Constants;
|
||||
import org.jclouds.compute.ComputeService;
|
||||
import org.jclouds.compute.ComputeServiceContext;
|
||||
import org.jclouds.compute.RunNodesException;
|
||||
import org.jclouds.compute.RunScriptOnNodesException;
|
||||
import org.jclouds.compute.domain.ComputeMetadata;
|
||||
import org.jclouds.compute.domain.ComputeType;
|
||||
import org.jclouds.compute.domain.Image;
|
||||
|
@ -62,13 +63,14 @@ import org.jclouds.compute.strategy.ListNodesStrategy;
|
|||
import org.jclouds.compute.strategy.RebootNodeStrategy;
|
||||
import org.jclouds.compute.strategy.RunNodesAndAddToSetStrategy;
|
||||
import org.jclouds.compute.util.ComputeUtils;
|
||||
import org.jclouds.compute.util.ComputeUtils.RunScriptOnNode;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.logging.Logger;
|
||||
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.collect.ImmutableMap;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
|
@ -86,9 +88,9 @@ public class BaseComputeService implements ComputeService {
|
|||
protected Logger logger = Logger.NULL;
|
||||
|
||||
protected final ComputeServiceContext context;
|
||||
protected final Provider<Map<String, ? extends Image>> images;
|
||||
protected final Provider<Map<String, ? extends Size>> sizes;
|
||||
protected final Provider<Map<String, ? extends Location>> locations;
|
||||
protected final Provider<Set<? extends Image>> images;
|
||||
protected final Provider<Set<? extends Size>> sizes;
|
||||
protected final Provider<Set<? extends Location>> locations;
|
||||
protected final ListNodesStrategy listNodesStrategy;
|
||||
protected final GetNodeMetadataStrategy getNodeMetadataStrategy;
|
||||
protected final RunNodesAndAddToSetStrategy runNodesAndAddToSetStrategy;
|
||||
|
@ -112,26 +114,11 @@ public class BaseComputeService implements ComputeService {
|
|||
|
||||
};
|
||||
|
||||
public static Function<ComputeMetadata, String> METADATA_TO_ID = new Function<ComputeMetadata, String>() {
|
||||
@Override
|
||||
public String apply(ComputeMetadata from) {
|
||||
return from.getId();
|
||||
}
|
||||
};
|
||||
|
||||
public static Function<ComputeMetadata, String> METADATA_TO_NAME = new Function<ComputeMetadata, String>() {
|
||||
@Override
|
||||
public String apply(ComputeMetadata from) {
|
||||
return from.getName();
|
||||
}
|
||||
};
|
||||
|
||||
@Inject
|
||||
protected BaseComputeService(ComputeServiceContext context,
|
||||
Provider<Map<String, ? extends Image>> images,
|
||||
Provider<Map<String, ? extends Size>> sizes,
|
||||
Provider<Map<String, ? extends Location>> locations,
|
||||
ListNodesStrategy listNodesStrategy, GetNodeMetadataStrategy getNodeMetadataStrategy,
|
||||
Provider<Set<? extends Image>> images, Provider<Set<? extends Size>> sizes,
|
||||
Provider<Set<? extends Location>> locations, ListNodesStrategy listNodesStrategy,
|
||||
GetNodeMetadataStrategy getNodeMetadataStrategy,
|
||||
RunNodesAndAddToSetStrategy runNodesAndAddToSetStrategy,
|
||||
RebootNodeStrategy rebootNodeStrategy, DestroyNodeStrategy destroyNodeStrategy,
|
||||
Provider<TemplateBuilder> templateBuilderProvider, ComputeUtils utils,
|
||||
|
@ -159,28 +146,23 @@ public class BaseComputeService implements ComputeService {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Map<String, ? extends NodeMetadata> runNodesWithTag(final String tag, int count,
|
||||
final Template template) {
|
||||
public Set<? extends NodeMetadata> runNodesWithTag(final String tag, int count,
|
||||
final Template template) throws RunNodesException {
|
||||
checkArgument(tag.indexOf('-') == -1, "tag cannot contain hyphens");
|
||||
checkNotNull(template.getLocation(), "location");
|
||||
logger.debug(">> running %d node%s tag(%s) location(%s) image(%s) size(%s) options(%s)",
|
||||
count, count > 1 ? "s" : "", tag, template.getLocation().getId(), template
|
||||
.getImage().getId(), template.getSize().getId(), template.getOptions());
|
||||
final Set<NodeMetadata> nodes = Sets.newHashSet();
|
||||
final Map<NodeMetadata, Exception> badNodes = Maps.newLinkedHashMap();
|
||||
Map<?, ListenableFuture<Void>> responses = runNodesAndAddToSetStrategy.execute(tag, count,
|
||||
template, nodes);
|
||||
Map<?, Exception> exceptions = awaitCompletion(responses, executor, null, logger,
|
||||
template, nodes, badNodes);
|
||||
Map<?, Exception> executionExceptions = awaitCompletion(responses, executor, null, logger,
|
||||
"starting nodes");
|
||||
if (exceptions.size() > 0 && template.getOptions().shouldDestroyOnError()) {
|
||||
ImmutableMap<?, ? extends ComputeMetadata> currentNodes = Maps.uniqueIndex(
|
||||
listNodesStrategy.execute(GetNodesOptions.NONE), METADATA_TO_ID);
|
||||
for (Entry<?, Exception> entry : exceptions.entrySet()) {
|
||||
logger.error(entry.getValue(), "<< error applying nodes(%s) [%s] destroying ", entry
|
||||
.getKey(), entry.getValue().getMessage());
|
||||
destroyNode(currentNodes.get(entry.getKey()));
|
||||
}
|
||||
if (executionExceptions.size() > 0 || badNodes.size() > 0) {
|
||||
throw new RunNodesException(tag, count, template, nodes, executionExceptions, badNodes);
|
||||
}
|
||||
return Maps.uniqueIndex(nodes, METADATA_TO_ID);
|
||||
return nodes;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -196,14 +178,14 @@ public class BaseComputeService implements ComputeService {
|
|||
@Override
|
||||
public void destroyNodesWithTag(String tag) { // TODO parallel
|
||||
logger.debug(">> destroying nodes by tag(%s)", tag);
|
||||
Iterable<? extends NodeMetadata> nodesToDestroy = Iterables.filter(doGetNodesWithTag(tag)
|
||||
.values(), new Predicate<NodeMetadata>() {
|
||||
@Override
|
||||
public boolean apply(NodeMetadata input) {
|
||||
return input.getState() != NodeState.TERMINATED;
|
||||
Iterable<? extends NodeMetadata> nodesToDestroy = Iterables.filter(doListNodesWithTag(tag),
|
||||
new Predicate<NodeMetadata>() {
|
||||
@Override
|
||||
public boolean apply(NodeMetadata input) {
|
||||
return input.getState() != NodeState.TERMINATED;
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
Map<NodeMetadata, ListenableFuture<Void>> responses = Maps.newHashMap();
|
||||
for (final NodeMetadata node : nodesToDestroy) {
|
||||
responses.put(node, makeListenable(executor.submit(new Callable<Void>() {
|
||||
|
@ -219,69 +201,59 @@ public class BaseComputeService implements ComputeService {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Map<String, ? extends ComputeMetadata> getNodes() {
|
||||
logger.debug(">> listing servers");
|
||||
ImmutableMap<String, ? extends ComputeMetadata> map = Maps.uniqueIndex(listNodesStrategy
|
||||
.execute(GetNodesOptions.NONE), METADATA_TO_ID);
|
||||
logger.debug("<< list(%d)", map.size());
|
||||
return map;
|
||||
public Set<? extends ComputeMetadata> listNodes() {
|
||||
return listNodes(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, ? extends ComputeMetadata> getNodes(GetNodesOptions options) {
|
||||
public Set<? extends ComputeMetadata> listNodes(GetNodesOptions options) {
|
||||
logger.debug(">> listing servers");
|
||||
if(options == null){
|
||||
options = GetNodesOptions.NONE;
|
||||
if (options == null) {
|
||||
options = GetNodesOptions.NONE;
|
||||
}
|
||||
ImmutableMap<String, ? extends ComputeMetadata> map = Maps.uniqueIndex(listNodesStrategy
|
||||
.execute(options), METADATA_TO_ID);
|
||||
logger.debug("<< list(%d)", map.size());
|
||||
return map;
|
||||
Set<? extends ComputeMetadata> set = Sets
|
||||
.newLinkedHashSet(listNodesStrategy.execute(options));
|
||||
logger.debug("<< list(%d)", set.size());
|
||||
return set;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the result of {@link ListNodesStrategy#execute} is a set of nodes, then return them.
|
||||
* Otherwise iteratively call {@link #getNodeMetadata}
|
||||
*/
|
||||
protected Map<String, ? extends NodeMetadata> doGetNodesWithTag(final String tag) {
|
||||
Iterable<? extends NodeMetadata> nodes = Iterables.filter(Iterables.transform(
|
||||
listNodesStrategy.execute(GetNodesOptions.NONE), new Function<ComputeMetadata, NodeMetadata>() {
|
||||
|
||||
@Override
|
||||
public NodeMetadata apply(ComputeMetadata from) {
|
||||
return from instanceof NodeMetadata ? NodeMetadata.class.cast(from)
|
||||
: getNodeMetadata(from);
|
||||
}
|
||||
|
||||
}), new Predicate<NodeMetadata>() {
|
||||
protected Set<? extends NodeMetadata> doListNodesWithTag(final String tag) {
|
||||
return Sets.newHashSet(Iterables.filter(Iterables.transform(listNodesStrategy
|
||||
.execute(GetNodesOptions.NONE), new Function<ComputeMetadata, NodeMetadata>() {
|
||||
|
||||
@Override
|
||||
public boolean apply(NodeMetadata input) {
|
||||
return tag.equals(input.getTag());
|
||||
public NodeMetadata apply(ComputeMetadata from) {
|
||||
return from instanceof NodeMetadata ? NodeMetadata.class.cast(from)
|
||||
: getNodeMetadata(from);
|
||||
}
|
||||
|
||||
});
|
||||
return Maps.uniqueIndex(Iterables.filter(nodes, new NodeMatchesTag(tag)), METADATA_TO_ID);
|
||||
}), new NodeMatchesTag(tag)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, ? extends NodeMetadata> getNodesWithTag(String tag) {
|
||||
public Set<? extends NodeMetadata> listNodesWithTag(String tag) {
|
||||
logger.debug(">> listing nodes by tag(%s)", tag);
|
||||
Map<String, ? extends NodeMetadata> nodes = doGetNodesWithTag(tag);
|
||||
Set<? extends NodeMetadata> nodes = doListNodesWithTag(tag);
|
||||
logger.debug("<< list(%d)", nodes.size());
|
||||
return nodes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, ? extends Size> getSizes() {
|
||||
public Set<? extends Size> listSizes() {
|
||||
return sizes.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, ? extends Image> getImages() {
|
||||
public Set<? extends Image> listImages() {
|
||||
return images.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, ? extends Location> getAssignableLocations() {
|
||||
public Set<? extends Location> listAssignableLocations() {
|
||||
return locations.get();
|
||||
}
|
||||
|
||||
|
@ -310,14 +282,14 @@ public class BaseComputeService implements ComputeService {
|
|||
@Override
|
||||
public void rebootNodesWithTag(String tag) { // TODO parallel
|
||||
logger.debug(">> rebooting nodes by tag(%s)", tag);
|
||||
Iterable<? extends NodeMetadata> nodesToReboot = Iterables.filter(doGetNodesWithTag(tag)
|
||||
.values(), new Predicate<NodeMetadata>() {
|
||||
@Override
|
||||
public boolean apply(NodeMetadata input) {
|
||||
return input.getState() != NodeState.TERMINATED;
|
||||
Iterable<? extends NodeMetadata> nodesToReboot = Iterables.filter(doListNodesWithTag(tag),
|
||||
new Predicate<NodeMetadata>() {
|
||||
@Override
|
||||
public boolean apply(NodeMetadata input) {
|
||||
return input.getState() != NodeState.TERMINATED;
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
Map<NodeMetadata, ListenableFuture<Void>> responses = Maps.newHashMap();
|
||||
for (final NodeMetadata node : nodesToReboot) {
|
||||
responses.put(node, makeListenable(executor.submit(new Callable<Void>() {
|
||||
|
@ -333,9 +305,11 @@ public class BaseComputeService implements ComputeService {
|
|||
}
|
||||
|
||||
/**
|
||||
* @throws RunScriptOnNodesException
|
||||
* @see #runScriptOnNodesWithTag(String, byte[], org.jclouds.compute.options.RunScriptOptions)
|
||||
*/
|
||||
public Map<String, ExecResponse> runScriptOnNodesWithTag(String tag, byte[] runScript) {
|
||||
public Map<NodeMetadata, ExecResponse> runScriptOnNodesWithTag(String tag, byte[] runScript)
|
||||
throws RunScriptOnNodesException {
|
||||
return runScriptOnNodesWithTag(tag, runScript, RunScriptOptions.NONE);
|
||||
}
|
||||
|
||||
|
@ -350,46 +324,94 @@ public class BaseComputeService implements ComputeService {
|
|||
* @param options
|
||||
* nullable options to how to run the script, whether to override credentials
|
||||
* @return map with node identifiers and corresponding responses
|
||||
* @throws RunScriptOnNodesException
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public Map<String, ExecResponse> runScriptOnNodesWithTag(String tag, byte[] runScript,
|
||||
@Nullable RunScriptOptions options) {
|
||||
public Map<NodeMetadata, ExecResponse> runScriptOnNodesWithTag(String tag,
|
||||
final byte[] runScript, @Nullable final RunScriptOptions options)
|
||||
throws RunScriptOnNodesException {
|
||||
Iterable<? extends NodeMetadata> nodes = verifyParametersAndGetNodes(tag, runScript,
|
||||
(options != null) ? options : RunScriptOptions.NONE);
|
||||
final Map<NodeMetadata, ExecResponse> execs = Maps.newHashMap();
|
||||
|
||||
final Map<NodeMetadata, Exception> badNodes = Maps.newLinkedHashMap();
|
||||
|
||||
Map<NodeMetadata, ListenableFuture<Void>> responses = Maps.newHashMap();
|
||||
|
||||
for (final NodeMetadata node : nodes) {
|
||||
|
||||
responses.put(node, makeListenable(executor.submit(new Callable<Void>() {
|
||||
@Override
|
||||
public Void call() throws Exception {
|
||||
try {
|
||||
RunScriptOnNode callable;
|
||||
if (options.isRunAsRoot())
|
||||
callable = utils.runScriptOnNode(node, "computeserv", runScript);
|
||||
else
|
||||
callable = utils.runScriptOnNodeAsDefaultUser(node, "computeserv", runScript);
|
||||
SshClient ssh = utils.createSshClientOncePortIsListeningOnNode(node);
|
||||
try {
|
||||
ssh.connect();
|
||||
callable.setConnection(ssh, logger);
|
||||
execs.put(node, callable.call());
|
||||
} finally {
|
||||
if (ssh != null)
|
||||
ssh.disconnect();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
badNodes.put(node, e);
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}), executor));
|
||||
|
||||
}
|
||||
Map<?, Exception> exceptions = awaitCompletion(responses, executor, null, logger,
|
||||
"starting nodes");
|
||||
if (exceptions.size() > 0 || badNodes.size() > 0) {
|
||||
throw new RunScriptOnNodesException(tag, runScript, options, execs, exceptions, badNodes);
|
||||
}
|
||||
return execs;
|
||||
}
|
||||
|
||||
private Iterable<? extends NodeMetadata> verifyParametersAndGetNodes(String tag,
|
||||
byte[] runScript, final RunScriptOptions options) {
|
||||
checkNotEmpty(tag, "Tag must be provided");
|
||||
checkNotNull(runScript,
|
||||
"The script (represented by bytes array - use \"script\".getBytes() must be provided");
|
||||
if (options == null)
|
||||
options = RunScriptOptions.NONE;
|
||||
checkNotNull(options, "options");
|
||||
Iterable<? extends NodeMetadata> nodes = Iterables.filter(listNodesWithTag(tag),
|
||||
new Predicate<NodeMetadata>() {
|
||||
|
||||
Map<String, ? extends NodeMetadata> nodes = getNodesWithTag(tag);
|
||||
Map<String, ExecResponse> responses = Maps.newHashMap();
|
||||
@Override
|
||||
public boolean apply(NodeMetadata input) {
|
||||
return input.getState() == NodeState.RUNNING;
|
||||
}
|
||||
|
||||
for (NodeMetadata node : nodes.values()) {
|
||||
if (NodeState.RUNNING != node.getState())
|
||||
continue; // make sure the node is active
|
||||
});
|
||||
return Iterables.transform(nodes, new Function<NodeMetadata, NodeMetadata>() {
|
||||
|
||||
if (options.getOverrideCredentials() != null) {
|
||||
// override the credentials with provided to this method
|
||||
node = ComputeUtils.installNewCredentials(node, options.getOverrideCredentials());
|
||||
} else {
|
||||
// don't override
|
||||
checkNotNull(node.getCredentials(),
|
||||
"If the default credentials need to be used, they can't be null");
|
||||
checkNotNull(node.getCredentials().account, "Account name for ssh authentication must be " +
|
||||
"specified. Try passing RunScriptOptions with new credentials");
|
||||
checkNotNull(node.getCredentials().key, "Key or password for ssh authentication must be " +
|
||||
"specified. Try passing RunScriptOptions with new credentials");
|
||||
@Override
|
||||
public NodeMetadata apply(NodeMetadata node) {
|
||||
|
||||
checkArgument(node.getPublicAddresses().size() > 0, "no public ip addresses on node: "
|
||||
+ node);
|
||||
if (options.getOverrideCredentials() != null) {
|
||||
// override the credentials with provided to this method
|
||||
node = ComputeUtils.installNewCredentials(node, options.getOverrideCredentials());
|
||||
} else {
|
||||
// don't override
|
||||
checkNotNull(node.getCredentials(),
|
||||
"If the default credentials need to be used, they can't be null");
|
||||
checkNotNull(node.getCredentials().account,
|
||||
"Account name for ssh authentication must be "
|
||||
+ "specified. Try passing RunScriptOptions with new credentials");
|
||||
checkNotNull(node.getCredentials().key,
|
||||
"Key or password for ssh authentication must be "
|
||||
+ "specified. Try passing RunScriptOptions with new credentials");
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
ComputeUtils.SshCallable<?> callable;
|
||||
if (options.isRunAsRoot())
|
||||
callable = utils.runScriptOnNode(node, "computeserv.sh", runScript);
|
||||
else
|
||||
callable = utils.runScriptOnNodeAsDefaultUser(node, "computeserv.sh", runScript);
|
||||
|
||||
Map<ComputeUtils.SshCallable<?>, ?> scriptRunResults = utils.runCallablesOnNode(node, Sets
|
||||
.newHashSet(callable), null);
|
||||
responses.put(node.getId(), (ExecResponse) scriptRunResults.get(callable));
|
||||
}
|
||||
return responses;
|
||||
});
|
||||
}
|
||||
}
|
|
@ -18,11 +18,10 @@
|
|||
*/
|
||||
package org.jclouds.compute.internal;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Inject;
|
||||
|
@ -61,9 +60,9 @@ public class TemplateBuilderImpl implements TemplateBuilder {
|
|||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||
protected Logger logger = Logger.NULL;
|
||||
|
||||
private final Map<String, ? extends Image> images;
|
||||
private final Map<String, ? extends Size> sizes;
|
||||
private final Map<String, ? extends Location> locations;
|
||||
private final Set<? extends Image> images;
|
||||
private final Set<? extends Size> sizes;
|
||||
private final Set<? extends Location> locations;
|
||||
@VisibleForTesting
|
||||
OsFamily os;
|
||||
@VisibleForTesting
|
||||
|
@ -97,9 +96,8 @@ public class TemplateBuilderImpl implements TemplateBuilder {
|
|||
private TemplateOptions options = TemplateOptions.NONE;
|
||||
|
||||
@Inject
|
||||
protected TemplateBuilderImpl(Map<String, ? extends Location> locations,
|
||||
Map<String, ? extends Image> images, Map<String, ? extends Size> sizes,
|
||||
Location defaultLocation) {
|
||||
protected TemplateBuilderImpl(Set<? extends Location> locations, Set<? extends Image> images,
|
||||
Set<? extends Size> sizes, Location defaultLocation) {
|
||||
this.locations = locations;
|
||||
this.images = images;
|
||||
this.sizes = sizes;
|
||||
|
@ -363,8 +361,6 @@ public class TemplateBuilderImpl implements TemplateBuilder {
|
|||
*/
|
||||
@Override
|
||||
public TemplateBuilder locationId(final String locationId) {
|
||||
checkArgument(locations.get(checkNotNull(locationId, "locationId")) != null, "locationId "
|
||||
+ locationId + " not configured in: " + locations.keySet());
|
||||
this.locationId = locationId;
|
||||
return this;
|
||||
}
|
||||
|
@ -395,7 +391,7 @@ public class TemplateBuilderImpl implements TemplateBuilder {
|
|||
logger.debug(">> searching params(%s)", this);
|
||||
Image image;
|
||||
try {
|
||||
image = DEFAULT_IMAGE_ORDERING.max(Iterables.filter(images.values(), imagePredicate));
|
||||
image = DEFAULT_IMAGE_ORDERING.max(Iterables.filter(images, imagePredicate));
|
||||
} catch (NoSuchElementException exception) {
|
||||
throw new NoSuchElementException("image didn't match: " + toString() + "\n" + images);
|
||||
}
|
||||
|
@ -410,12 +406,19 @@ public class TemplateBuilderImpl implements TemplateBuilder {
|
|||
sizeOrdering = Ordering.compound(ImmutableList.of(BY_CORES_ORDERING, sizeOrdering));
|
||||
Size size;
|
||||
try {
|
||||
size = sizeOrdering.max(Iterables.filter(sizes.values(), sizePredicate));
|
||||
size = sizeOrdering.max(Iterables.filter(sizes, sizePredicate));
|
||||
} catch (NoSuchElementException exception) {
|
||||
throw new NoSuchElementException("size didn't match: " + toString() + "\n" + sizes);
|
||||
}
|
||||
logger.debug("<< matched size(%s)", size);
|
||||
Location location = locations.get(locationId);
|
||||
Location location = Iterables.find(locations, new Predicate<Location>() {
|
||||
|
||||
@Override
|
||||
public boolean apply(Location input) {
|
||||
return input.getId().equals(locationId);
|
||||
}
|
||||
|
||||
});
|
||||
logger.debug("<< matched location(%s)", location);
|
||||
return new TemplateImpl(image, size, location, options);
|
||||
}
|
||||
|
|
|
@ -83,4 +83,10 @@ public class RunScriptOptions {
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "RunScriptOptions [overridingCredentials=" + (overridingCredentials != null)
|
||||
+ ", runAsRoot=" + runAsRoot + "]";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -32,8 +32,6 @@ public class TemplateOptions {
|
|||
|
||||
private String publicKey;
|
||||
|
||||
private boolean destroyOnError;
|
||||
|
||||
private int port = -1;
|
||||
|
||||
private int seconds = -1;
|
||||
|
@ -64,10 +62,6 @@ public class TemplateOptions {
|
|||
return publicKey;
|
||||
}
|
||||
|
||||
public boolean shouldDestroyOnError() {
|
||||
return destroyOnError;
|
||||
}
|
||||
|
||||
public boolean isIncludeMetadata() {
|
||||
return includeMetadata;
|
||||
}
|
||||
|
@ -83,14 +77,6 @@ public class TemplateOptions {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* If there is an error applying options after creating the node, destroy it.
|
||||
*/
|
||||
public TemplateOptions destroyOnError() {
|
||||
this.destroyOnError = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* This script will be executed as the root user upon system startup. This script gets a
|
||||
* prologue, so no #!/bin/bash required, path set up, etc
|
||||
|
@ -139,13 +125,6 @@ public class TemplateOptions {
|
|||
}
|
||||
|
||||
public static class Builder {
|
||||
/**
|
||||
* @see TemplateOptions#destroyOnError
|
||||
*/
|
||||
public static TemplateOptions destroyOnError() {
|
||||
TemplateOptions options = new TemplateOptions();
|
||||
return options.destroyOnError();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see TemplateOptions#inboundPorts
|
||||
|
@ -198,7 +177,7 @@ public class TemplateOptions {
|
|||
public String toString() {
|
||||
return "TemplateOptions [inboundPorts=" + Arrays.toString(inboundPorts) + ", privateKey="
|
||||
+ (privateKey != null) + ", publicKey=" + (publicKey != null) + ", runScript="
|
||||
+ (script != null) + ", destroyOnError=" + destroyOnError + ", port:seconds=" + port
|
||||
+ ":" + seconds + ", metadata/details: " + includeMetadata + "]";
|
||||
+ (script != null) + ", port:seconds=" + port + ":" + seconds
|
||||
+ ", metadata/details: " + includeMetadata + "]";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,5 +38,5 @@ import com.google.inject.ImplementedBy;
|
|||
public interface RunNodesAndAddToSetStrategy {
|
||||
|
||||
Map<?, ListenableFuture<Void>> execute(String tag, int count, Template template,
|
||||
Set<NodeMetadata> nodes);
|
||||
Set<NodeMetadata> nodes, Map<NodeMetadata, Exception> badNodes);
|
||||
}
|
|
@ -36,7 +36,6 @@ import org.jclouds.Constants;
|
|||
import org.jclouds.compute.domain.ComputeMetadata;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.compute.internal.BaseComputeService;
|
||||
import org.jclouds.compute.options.GetNodesOptions;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.compute.strategy.AddNodeWithTagStrategy;
|
||||
|
@ -45,6 +44,8 @@ import org.jclouds.compute.strategy.RunNodesAndAddToSetStrategy;
|
|||
import org.jclouds.compute.util.ComputeUtils;
|
||||
import org.jclouds.logging.Logger;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
|
@ -83,7 +84,8 @@ public class EncodeTagIntoNameRunNodesAndAddToSetStrategy implements RunNodesAnd
|
|||
*/
|
||||
@Override
|
||||
public Map<?, ListenableFuture<Void>> execute(final String tag, final int count,
|
||||
final Template template, final Set<NodeMetadata> nodes) {
|
||||
final Template template, final Set<NodeMetadata> nodes,
|
||||
final Map<NodeMetadata, Exception> badNodes) {
|
||||
Map<String, ListenableFuture<Void>> responses = Maps.newHashMap();
|
||||
for (final String name : getNextNames(tag, template, count)) {
|
||||
responses.put(name, makeListenable(executor.submit(new Callable<Void>() {
|
||||
|
@ -100,8 +102,7 @@ public class EncodeTagIntoNameRunNodesAndAddToSetStrategy implements RunNodesAnd
|
|||
} catch (Exception e) {
|
||||
logger.error(e, "<< error applying options (%s) on node (%s)", template
|
||||
.getOptions(), node.getId());
|
||||
if (!template.getOptions().shouldDestroyOnError())
|
||||
nodes.add(node);
|
||||
badNodes.put(node, e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -122,11 +123,20 @@ public class EncodeTagIntoNameRunNodesAndAddToSetStrategy implements RunNodesAnd
|
|||
*/
|
||||
protected Set<String> getNextNames(final String tag, final Template template, int count) {
|
||||
Set<String> names = Sets.newHashSet();
|
||||
Map<String, ? extends ComputeMetadata> currentNodes = Maps.uniqueIndex(listNodesStrategy
|
||||
.execute(GetNodesOptions.NONE), BaseComputeService.METADATA_TO_NAME);
|
||||
while (names.size() < count) {
|
||||
String name = getNextName(tag, template);
|
||||
if (!currentNodes.containsKey(name)) {
|
||||
Iterable<? extends ComputeMetadata> currentNodes = listNodesStrategy
|
||||
.execute(GetNodesOptions.NONE);
|
||||
int maxTries = 100;
|
||||
int currentTries = 0;
|
||||
while (names.size() < count && currentTries++ < maxTries) {
|
||||
final String name = getNextName(tag, template);
|
||||
if (!Iterables.any(currentNodes, new Predicate<ComputeMetadata>() {
|
||||
|
||||
@Override
|
||||
public boolean apply(ComputeMetadata input) {
|
||||
return name.equals(input.getName());
|
||||
}
|
||||
|
||||
})) {
|
||||
names.add(name);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,15 +24,16 @@ import static org.jclouds.concurrent.ConcurrentUtils.awaitCompletion;
|
|||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.ConnectException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.Comparator;
|
||||
import java.util.Formatter;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
@ -84,7 +85,28 @@ public class ComputeUtils {
|
|||
private final Predicate<InetSocketAddress> socketTester;
|
||||
private final ExecutorService executor;
|
||||
|
||||
private int sshRetries = 3;
|
||||
public static String createExecutionErrorMessage(Map<?, Exception> executionExceptions) {
|
||||
Formatter fmt = new Formatter().format("Execution failures:%n%n");
|
||||
int index = 1;
|
||||
for (Entry<?, Exception> errorMessage : executionExceptions.entrySet()) {
|
||||
fmt.format("%s) %s on %s:%n%s%n%n", index++, errorMessage.getValue().getClass()
|
||||
.getSimpleName(), errorMessage.getKey(), Throwables
|
||||
.getStackTraceAsString(errorMessage.getValue()));
|
||||
}
|
||||
return fmt.format("%s error[s]", executionExceptions.size()).toString();
|
||||
}
|
||||
|
||||
public static String createNodeErrorMessage(
|
||||
Map<? extends NodeMetadata, ? extends Throwable> failedNodes) {
|
||||
Formatter fmt = new Formatter().format("Node failures:%n%n");
|
||||
int index = 1;
|
||||
for (Entry<? extends NodeMetadata, ? extends Throwable> errorMessage : failedNodes.entrySet()) {
|
||||
fmt.format("%s) %s on node %s:%n%s%n%n", index++, errorMessage.getValue().getClass()
|
||||
.getSimpleName(), errorMessage.getKey().getId(), Throwables
|
||||
.getStackTraceAsString(errorMessage.getValue()));
|
||||
}
|
||||
return fmt.format("%s error[s]", failedNodes.size()).toString();
|
||||
}
|
||||
|
||||
@Inject
|
||||
public ComputeUtils(Predicate<InetSocketAddress> socketTester,
|
||||
|
@ -117,7 +139,7 @@ public class ComputeUtils {
|
|||
public void runOptionsOnNode(NodeMetadata node, TemplateOptions options) {
|
||||
List<SshCallable<?>> callables = Lists.newArrayList();
|
||||
if (options.getRunScript() != null) {
|
||||
callables.add(runScriptOnNode(node, "runscript.sh", options.getRunScript()));
|
||||
callables.add(runScriptOnNode(node, "runscript", options.getRunScript()));
|
||||
}
|
||||
if (options.getPublicKey() != null) {
|
||||
callables.add(authorizeKeyOnNode(node, options.getPublicKey()));
|
||||
|
@ -168,60 +190,60 @@ public class ComputeUtils {
|
|||
Iterable<? extends SshCallable<?>> parallel, @Nullable SshCallable<?> last) {
|
||||
checkState(this.sshFactory != null, "runScript requested, but no SshModule configured");
|
||||
checkNotNull(node.getCredentials().key, "credentials.key for node " + node.getId());
|
||||
SshClient ssh = createSshClientOncePortIsListeningOnNode(node);
|
||||
try {
|
||||
ssh.connect();
|
||||
return runTasksUsingSshClient(parallel, last, ssh);
|
||||
} finally {
|
||||
if (ssh != null)
|
||||
ssh.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
private Map<SshCallable<?>, ?> runTasksUsingSshClient(
|
||||
Iterable<? extends SshCallable<?>> parallel, SshCallable<?> last, SshClient ssh) {
|
||||
Map<SshCallable<?>, Object> responses = Maps.newHashMap();
|
||||
if (Iterables.size(parallel) > 0) {
|
||||
responses.putAll(runCallablesUsingSshClient(parallel, ssh));
|
||||
}
|
||||
if (last != null) {
|
||||
last.setConnection(ssh, logger);
|
||||
try {
|
||||
responses.put(last, last.call());
|
||||
} catch (Exception e) {
|
||||
Throwables.propagate(e);
|
||||
}
|
||||
}
|
||||
return responses;
|
||||
}
|
||||
|
||||
public SshClient createSshClientOncePortIsListeningOnNode(NodeMetadata node) {
|
||||
InetSocketAddress socket = new InetSocketAddress(Iterables.get(node.getPublicAddresses(), 0),
|
||||
22);
|
||||
socketTester.apply(socket);
|
||||
SshClient ssh = isKeyAuth(node) ? sshFactory.create(socket, node.getCredentials().account,
|
||||
node.getCredentials().key.getBytes()) : sshFactory.create(socket, node
|
||||
.getCredentials().account, node.getCredentials().key);
|
||||
for (int i = 0; i < sshRetries; i++) {
|
||||
try {
|
||||
ssh.connect();
|
||||
Map<SshCallable<?>, ListenableFuture<?>> responses = Maps.newHashMap();
|
||||
return ssh;
|
||||
}
|
||||
|
||||
for (SshCallable<?> callable : parallel) {
|
||||
callable.setConnection(ssh, logger);
|
||||
responses.put(callable, ConcurrentUtils.makeListenable(executor.submit(callable),
|
||||
executor));
|
||||
}
|
||||
private Map<SshCallable<?>, Object> runCallablesUsingSshClient(
|
||||
Iterable<? extends SshCallable<?>> parallel, SshClient ssh) {
|
||||
Map<SshCallable<?>, ListenableFuture<?>> parallelResponses = Maps.newHashMap();
|
||||
|
||||
Map<SshCallable<?>, Exception> exceptions = awaitCompletion(responses, executor, null,
|
||||
logger, "ssh");
|
||||
if (exceptions.size() > 0)
|
||||
throw new RuntimeException(String.format("error invoking callables on host %s: %s",
|
||||
socket, exceptions));
|
||||
if (last != null) {
|
||||
last.setConnection(ssh, logger);
|
||||
try {
|
||||
last.call();
|
||||
} catch (Exception e) {
|
||||
Throwables.propagate(e);
|
||||
}
|
||||
}
|
||||
return transform(responses);
|
||||
} catch (RuntimeException from) {
|
||||
if (i + 1 == sshRetries)
|
||||
throw Throwables.propagate(from);
|
||||
if (Iterables.size(Iterables.filter(Throwables.getCausalChain(from),
|
||||
ConnectException.class)) >= 1// auth fail sometimes happens in EC2
|
||||
|| Throwables.getRootCause(from).getMessage().indexOf("Auth fail") != -1
|
||||
|| Throwables.getRootCause(from).getMessage().indexOf("invalid privatekey") != -1) {
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
} catch (InterruptedException e) {
|
||||
throw Throwables.propagate(e);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
throw Throwables.propagate(from);
|
||||
} finally {
|
||||
if (ssh != null)
|
||||
ssh.disconnect();
|
||||
}
|
||||
for (SshCallable<?> callable : parallel) {
|
||||
callable.setConnection(ssh, logger);
|
||||
parallelResponses.put(callable, ConcurrentUtils.makeListenable(executor.submit(callable),
|
||||
executor));
|
||||
}
|
||||
throw new RuntimeException(String.format("Couldn't connect to node %s and run the script",
|
||||
node.getId()));
|
||||
|
||||
Map<SshCallable<?>, Exception> exceptions = awaitCompletion(parallelResponses, executor,
|
||||
null, logger, "ssh");
|
||||
if (exceptions.size() > 0)
|
||||
throw new RuntimeException(String.format("error invoking callables on nodes: %s",
|
||||
exceptions));
|
||||
Map<SshCallable<?>, Object> newresponses = transform(parallelResponses);
|
||||
return newresponses;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
@ -240,6 +262,8 @@ public class ComputeUtils {
|
|||
}
|
||||
|
||||
public static interface SshCallable<T> extends Callable<T> {
|
||||
NodeMetadata getNode();
|
||||
|
||||
void setConnection(SshClient ssh, Logger logger);
|
||||
}
|
||||
|
||||
|
@ -254,14 +278,7 @@ public class ComputeUtils {
|
|||
|
||||
RunScriptOnNode(@Named("NOT_RUNNING") Predicate<CommandUsingClient> runScriptNotRunning,
|
||||
NodeMetadata node, String scriptName, byte[] script) {
|
||||
this.runScriptNotRunning = runScriptNotRunning;
|
||||
this.node = checkNotNull(node, "node");
|
||||
this.scriptName = checkNotNull(scriptName, "scriptName");
|
||||
this.script = new InitBuilder("runscript", "/tmp", "/tmp", ImmutableMap
|
||||
.<String, String> of(), Iterables.toArray(Splitter.on("\n").split(
|
||||
new String(checkNotNull(script, "script"))), String.class)).build(OsFamily.UNIX)
|
||||
.getBytes();
|
||||
this.runAsRoot = true;
|
||||
this(runScriptNotRunning, node, scriptName, script, true);
|
||||
}
|
||||
|
||||
RunScriptOnNode(@Named("NOT_RUNNING") Predicate<CommandUsingClient> runScriptNotRunning,
|
||||
|
@ -269,10 +286,10 @@ public class ComputeUtils {
|
|||
this.runScriptNotRunning = runScriptNotRunning;
|
||||
this.node = checkNotNull(node, "node");
|
||||
this.scriptName = checkNotNull(scriptName, "scriptName");
|
||||
this.script = new InitBuilder("runscript", "/tmp", "/tmp", ImmutableMap
|
||||
.<String, String> of(), Iterables.toArray(Splitter.on("\n").split(
|
||||
new String(checkNotNull(script, "script"))), String.class)).build(OsFamily.UNIX)
|
||||
.getBytes();
|
||||
this.script = new InitBuilder(scriptName, "/tmp/" + scriptName, "/tmp/" + scriptName,
|
||||
ImmutableMap.<String, String> of(), Iterables.toArray(Splitter.on("\n").split(
|
||||
new String(checkNotNull(script, "script"))), String.class)).build(
|
||||
OsFamily.UNIX).getBytes();
|
||||
this.runAsRoot = runAsRoot;
|
||||
}
|
||||
|
||||
|
@ -329,6 +346,11 @@ public class ComputeUtils {
|
|||
Iterables.get(node.getPublicAddresses(), 0).getHostAddress());
|
||||
return ssh.exec(String.format("./%s", scriptName + " start"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public NodeMetadata getNode() {
|
||||
return node;
|
||||
}
|
||||
}
|
||||
|
||||
public static class InstallRSAPrivateKey implements SshCallable<ExecResponse> {
|
||||
|
@ -358,6 +380,10 @@ public class ComputeUtils {
|
|||
this.ssh = checkNotNull(ssh, "ssh");
|
||||
}
|
||||
|
||||
@Override
|
||||
public NodeMetadata getNode() {
|
||||
return node;
|
||||
}
|
||||
}
|
||||
|
||||
public static class AuthorizeRSAPublicKey implements SshCallable<ExecResponse> {
|
||||
|
@ -390,6 +416,10 @@ public class ComputeUtils {
|
|||
this.ssh = checkNotNull(ssh, "ssh");
|
||||
}
|
||||
|
||||
@Override
|
||||
public NodeMetadata getNode() {
|
||||
return node;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isKeyAuth(NodeMetadata createdNode) {
|
||||
|
@ -434,4 +464,5 @@ public class ComputeUtils {
|
|||
}
|
||||
return providers;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -31,7 +31,6 @@ import java.util.NoSuchElementException;
|
|||
import java.util.Set;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
@ -155,9 +154,9 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
|
||||
@Test(enabled = true, dependsOnMethods = "testCorrectAuthException")
|
||||
public void testImagesCache() throws Exception {
|
||||
client.getImages();
|
||||
client.listImages();
|
||||
long time = System.currentTimeMillis();
|
||||
client.getImages();
|
||||
client.listImages();
|
||||
long duration = System.currentTimeMillis() - time;
|
||||
assert duration < 1000 : String.format("%dms to get images", duration);
|
||||
}
|
||||
|
@ -183,7 +182,7 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
template.getOptions().installPrivateKey(keyPair.get("private")).authorizePublicKey(
|
||||
keyPair.get("public")).runScript(
|
||||
buildScript(template.getImage().getOsFamily()).getBytes());
|
||||
nodes = Sets.newTreeSet(client.runNodesWithTag(tag, 2, template).values());
|
||||
nodes = Sets.newTreeSet(client.runNodesWithTag(tag, 2, template));
|
||||
assertEquals(nodes.size(), 2);
|
||||
checkNodes(nodes, tag);
|
||||
NodeMetadata node1 = nodes.first();
|
||||
|
@ -210,8 +209,7 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
@Test(enabled = true, dependsOnMethods = "testCreateTwoNodesWithRunScript")
|
||||
public void testCreateAnotherNodeWithANewContextToEnsureSharedMemIsntRequired() throws Exception {
|
||||
initializeContextAndClient();
|
||||
TreeSet<NodeMetadata> nodes = Sets.newTreeSet(client.runNodesWithTag(tag, 1, template)
|
||||
.values());
|
||||
TreeSet<NodeMetadata> nodes = Sets.newTreeSet(client.runNodesWithTag(tag, 1, template));
|
||||
checkNodes(nodes, tag);
|
||||
NodeMetadata node = nodes.first();
|
||||
this.nodes.add(node);
|
||||
|
@ -226,13 +224,13 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
Template simpleTemplate = buildTemplate(client.templateBuilder());
|
||||
simpleTemplate.getOptions().blockOnPort(22, 120);
|
||||
try {
|
||||
Map<String, ? extends NodeMetadata> nodes = client.runNodesWithTag(tag, 1, simpleTemplate);
|
||||
Credentials good = nodes.values().iterator().next().getCredentials();
|
||||
Set<? extends NodeMetadata> nodes = client.runNodesWithTag(tag, 1, simpleTemplate);
|
||||
Credentials good = nodes.iterator().next().getCredentials();
|
||||
assert good.account != null;
|
||||
|
||||
try {
|
||||
Map<String, ExecResponse> responses = runScriptWithCreds(tag, simpleTemplate.getImage()
|
||||
.getOsFamily(), new Credentials(good.account, "romeo"));
|
||||
Map<NodeMetadata, ExecResponse> responses = runScriptWithCreds(tag, simpleTemplate
|
||||
.getImage().getOsFamily(), new Credentials(good.account, "romeo"));
|
||||
assert false : "shouldn't pass with a bad password\n" + responses;
|
||||
} catch (SshException e) {
|
||||
assert Throwables.getRootCause(e).getMessage().contains("Auth fail") : e;
|
||||
|
@ -240,22 +238,22 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
|
||||
runScriptWithCreds(tag, simpleTemplate.getImage().getOsFamily(), good);
|
||||
|
||||
checkNodes(nodes.values(), tag);
|
||||
checkNodes(nodes, tag);
|
||||
|
||||
} finally {
|
||||
client.destroyNodesWithTag(tag);
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String, ExecResponse> runScriptWithCreds(String tag, OsFamily osFamily,
|
||||
Credentials creds) {
|
||||
private Map<NodeMetadata, ExecResponse> runScriptWithCreds(String tag, OsFamily osFamily,
|
||||
Credentials creds) throws RunScriptOnNodesException {
|
||||
try {
|
||||
return client.runScriptOnNodesWithTag(tag, buildScript(osFamily).getBytes(),
|
||||
RunScriptOptions.Builder.overrideCredentialsWith(creds));
|
||||
} catch (SshException e) {
|
||||
if (Throwables.getRootCause(e).getMessage().contains("Auth fail")) {
|
||||
System.err.printf("bad credentials: %s:%s for %s%n", creds.account, creds.key, client
|
||||
.getNodesWithTag(tag));
|
||||
.listNodesWithTag(tag));
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
|
@ -316,7 +314,7 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
@Test(enabled = true, dependsOnMethods = "testCreateAnotherNodeWithANewContextToEnsureSharedMemIsntRequired")
|
||||
public void testGet() throws Exception {
|
||||
Set<? extends NodeMetadata> metadataSet = Sets.newHashSet(Iterables.filter(client
|
||||
.getNodesWithTag(tag).values(), Predicates.not(new Predicate<NodeMetadata>() {
|
||||
.listNodesWithTag(tag), Predicates.not(new Predicate<NodeMetadata>() {
|
||||
@Override
|
||||
public boolean apply(NodeMetadata input) {
|
||||
return input.getState() == NodeState.TERMINATED;
|
||||
|
@ -352,23 +350,20 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
}
|
||||
|
||||
public void testListNodes() throws Exception {
|
||||
for (Entry<String, ? extends ComputeMetadata> node : client.getNodes().entrySet()) {
|
||||
assertEquals(node.getKey(), node.getValue().getId());
|
||||
assert node.getValue().getId() != null;
|
||||
assert node.getValue().getLocation() != null;
|
||||
assertEquals(node.getValue().getType(), ComputeType.NODE);
|
||||
for (ComputeMetadata node : client.listNodes()) {
|
||||
assert node.getId() != null;
|
||||
assert node.getLocation() != null;
|
||||
assertEquals(node.getType(), ComputeType.NODE);
|
||||
}
|
||||
}
|
||||
|
||||
public void testGetNodesWithDetails() throws Exception {
|
||||
for (Entry<String, ? extends ComputeMetadata> node : client.getNodes(
|
||||
new GetNodesOptions().withDetails()).entrySet()) {
|
||||
assertEquals(node.getKey(), node.getValue().getId());
|
||||
assert node.getValue().getId() != null : node;
|
||||
assert node.getValue().getLocation() != null : node;
|
||||
assertEquals(node.getValue().getType(), ComputeType.NODE);
|
||||
assert node.getValue() instanceof NodeMetadata;
|
||||
NodeMetadata nodeMetadata = (NodeMetadata) node.getValue();
|
||||
for (ComputeMetadata node : client.listNodes(new GetNodesOptions().withDetails())) {
|
||||
assert node.getId() != null : node;
|
||||
assert node.getLocation() != null : node;
|
||||
assertEquals(node.getType(), ComputeType.NODE);
|
||||
assert node instanceof NodeMetadata;
|
||||
NodeMetadata nodeMetadata = (NodeMetadata) node;
|
||||
assert nodeMetadata.getId() != null : nodeMetadata;
|
||||
// nullable
|
||||
// assert nodeMetadata.getImage() != null : node;
|
||||
|
@ -384,41 +379,39 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
}
|
||||
|
||||
public void testListImages() throws Exception {
|
||||
for (Entry<String, ? extends Image> image : client.getImages().entrySet()) {
|
||||
assertEquals(image.getKey(), image.getValue().getId());
|
||||
assert image.getValue().getId() != null : image;
|
||||
// image.getValue().getLocationId() can be null, if it is a location-free image
|
||||
assertEquals(image.getValue().getType(), ComputeType.IMAGE);
|
||||
for (Image image : client.listImages()) {
|
||||
assert image.getId() != null : image;
|
||||
// image.getLocationId() can be null, if it is a location-free image
|
||||
assertEquals(image.getType(), ComputeType.IMAGE);
|
||||
}
|
||||
}
|
||||
|
||||
@Test(groups = { "integration", "live" })
|
||||
public void testGetAssignableLocations() throws Exception {
|
||||
for (Entry<String, ? extends Location> location : client.getAssignableLocations().entrySet()) {
|
||||
System.err.printf("location %s%n", location.getValue());
|
||||
assertEquals(location.getKey(), location.getValue().getId());
|
||||
assert location.getValue().getId() != null : location;
|
||||
assert location.getValue() != location.getValue().getParent() : location;
|
||||
assert location.getValue().getScope() != null : location;
|
||||
switch (location.getValue().getScope()) {
|
||||
for (Location location : client.listAssignableLocations()) {
|
||||
System.err.printf("location %s%n", location);
|
||||
assert location.getId() != null : location;
|
||||
assert location != location.getParent() : location;
|
||||
assert location.getScope() != null : location;
|
||||
switch (location.getScope()) {
|
||||
case PROVIDER:
|
||||
assertProvider(location.getValue());
|
||||
assertProvider(location);
|
||||
break;
|
||||
case REGION:
|
||||
assertProvider(location.getValue().getParent());
|
||||
assertProvider(location.getParent());
|
||||
break;
|
||||
case ZONE:
|
||||
Location provider = location.getValue().getParent().getParent();
|
||||
Location provider = location.getParent().getParent();
|
||||
// zone can be a direct descendant of provider
|
||||
if (provider == null)
|
||||
provider = location.getValue().getParent();
|
||||
provider = location.getParent();
|
||||
assertProvider(provider);
|
||||
break;
|
||||
case HOST:
|
||||
Location provider2 = location.getValue().getParent().getParent().getParent();
|
||||
Location provider2 = location.getParent().getParent().getParent();
|
||||
// zone can be a direct descendant of provider
|
||||
if (provider2 == null)
|
||||
provider2 = location.getValue().getParent().getParent();
|
||||
provider2 = location.getParent().getParent();
|
||||
assertProvider(provider2);
|
||||
break;
|
||||
}
|
||||
|
@ -431,14 +424,13 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
}
|
||||
|
||||
public void testListSizes() throws Exception {
|
||||
for (Entry<String, ? extends Size> size : client.getSizes().entrySet()) {
|
||||
assertEquals(size.getKey(), size.getValue().getId());
|
||||
assert size.getValue().getId() != null;
|
||||
assert size.getValue().getCores() > 0;
|
||||
assert size.getValue().getDisk() > 0;
|
||||
assert size.getValue().getRam() > 0;
|
||||
assert size.getValue().getSupportedArchitectures() != null;
|
||||
assertEquals(size.getValue().getType(), ComputeType.SIZE);
|
||||
for (Size size : client.listSizes()) {
|
||||
assert size.getId() != null;
|
||||
assert size.getCores() > 0;
|
||||
assert size.getDisk() > 0;
|
||||
assert size.getRam() > 0;
|
||||
assert size.getSupportedArchitectures() != null;
|
||||
assertEquals(size.getType(), ComputeType.SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -480,7 +472,7 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
protected void cleanup() throws InterruptedException, ExecutionException, TimeoutException {
|
||||
if (nodes != null) {
|
||||
client.destroyNodesWithTag(tag);
|
||||
for (NodeMetadata node : client.getNodesWithTag(tag).values()) {
|
||||
for (NodeMetadata node : client.listNodesWithTag(tag)) {
|
||||
assert node.getState() == NodeState.TERMINATED : node;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ import org.jclouds.domain.LocationScope;
|
|||
import org.jclouds.domain.internal.LocationImpl;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -40,8 +40,8 @@ public class TemplateBuilderImplTest {
|
|||
|
||||
@Test
|
||||
public void testImageIdNullsEverythingElse() {
|
||||
TemplateBuilderImpl template = new TemplateBuilderImpl(ImmutableMap.<String, Location> of(),
|
||||
ImmutableMap.<String, Image> of(), ImmutableMap.<String, Size> of(),
|
||||
TemplateBuilderImpl template = new TemplateBuilderImpl(ImmutableSet.<Location> of(),
|
||||
ImmutableSet.<Image> of(), ImmutableSet.<Size> of(),
|
||||
new LocationImpl(LocationScope.REGION, " id", "description", null));
|
||||
template.architecture(Architecture.X86_32);
|
||||
template.imageDescriptionMatches("imageDescriptionMatches");
|
||||
|
|
|
@ -57,9 +57,6 @@ Ensure the module is on the classpath. You are maybe missing a dependency on
|
|||
(filter (complement nil?)
|
||||
(map (comp instantiate module-lookup) modules)))))
|
||||
|
||||
(defn seq-from-immutable-set [#^ImmutableSet set]
|
||||
(map #(.getValue %) set))
|
||||
|
||||
(defn dashed [a]
|
||||
(apply str (interpose "-" (map string/lower-case (re-seq #"[A-Z][^A-Z]*" a)))))
|
||||
|
||||
|
|
|
@ -25,7 +25,10 @@ import java.util.Locale;
|
|||
import java.util.SimpleTimeZone;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import org.jclouds.date.DateService;
|
||||
import org.jclouds.logging.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -35,23 +38,26 @@ import org.jclouds.date.DateService;
|
|||
* @author James Murty
|
||||
*/
|
||||
public class SimpleDateFormatDateService implements DateService {
|
||||
|
||||
@Resource
|
||||
protected Logger logger = Logger.NULL;
|
||||
/*
|
||||
* Use default Java Date/SimpleDateFormat classes for date manipulation, but be *very* careful to
|
||||
* guard against the lack of thread safety.
|
||||
*/
|
||||
//@GuardedBy("this")
|
||||
// @GuardedBy("this")
|
||||
private static final SimpleDateFormat iso8601SecondsSimpleDateFormat = new SimpleDateFormat(
|
||||
"yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US);
|
||||
|
||||
//@GuardedBy("this")
|
||||
// @GuardedBy("this")
|
||||
private static final SimpleDateFormat iso8601SimpleDateFormat = new SimpleDateFormat(
|
||||
"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US);
|
||||
|
||||
//@GuardedBy("this")
|
||||
// @GuardedBy("this")
|
||||
private static final SimpleDateFormat rfc822SimpleDateFormat = new SimpleDateFormat(
|
||||
"EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
|
||||
|
||||
//@GuardedBy("this")
|
||||
// @GuardedBy("this")
|
||||
private static final SimpleDateFormat cSimpleDateFormat = new SimpleDateFormat(
|
||||
"EEE MMM dd HH:mm:ss '+0000' yyyy", Locale.US);
|
||||
|
||||
|
@ -134,6 +140,8 @@ public class SimpleDateFormatDateService implements DateService {
|
|||
public static final Pattern NANOS_TO_MILLIS_PATTERN = Pattern
|
||||
.compile(".*[0-9][0-9][0-9][0-9][0-9][0-9]");
|
||||
|
||||
public static final Pattern TZ_PATTERN = Pattern.compile(".*[+][0-9][0-9]:[0-9][0-9]");
|
||||
|
||||
private String trimNanosToMillis(String toParse) {
|
||||
if (NANOS_TO_MILLIS_PATTERN.matcher(toParse).matches())
|
||||
toParse = toParse.substring(0, toParse.length() - 3) + 'Z';
|
||||
|
@ -143,6 +151,10 @@ public class SimpleDateFormatDateService implements DateService {
|
|||
public static final Pattern SECOND_PATTERN = Pattern.compile(".*[0-2][0-9]:00");
|
||||
|
||||
private String trimTZ(String toParse) {
|
||||
if (TZ_PATTERN.matcher(toParse).matches()) {
|
||||
logger.warn("trimming tz from %s", toParse);
|
||||
toParse = toParse.substring(0, toParse.length() - 6) + 'Z';
|
||||
}
|
||||
if (toParse.length() == 25 && SECOND_PATTERN.matcher(toParse).matches())
|
||||
toParse = toParse.substring(0, toParse.length() - 6) + 'Z';
|
||||
return toParse;
|
||||
|
|
|
@ -38,6 +38,8 @@ public class MapHttp4xxCodesToExceptions implements Function<Exception, Object>
|
|||
switch (responseException.getResponse().getStatusCode()) {
|
||||
case 401:
|
||||
throw new AuthorizationException(from);
|
||||
case 403:
|
||||
throw new AuthorizationException(from);
|
||||
case 404:
|
||||
throw new ResourceNotFoundException(from);
|
||||
}
|
||||
|
|
|
@ -58,15 +58,18 @@ public class DateServiceTest extends PerformanceTest {
|
|||
|
||||
protected class TestData {
|
||||
public final String iso8601DateString;
|
||||
public final String iso8601DateStringTz;
|
||||
|
||||
public final String iso8601SecondsDateString;
|
||||
public final String rfc822DateString;
|
||||
public final String cDateString;
|
||||
|
||||
public final Date date;
|
||||
|
||||
TestData(String iso8601, String iso8601Seconds, String rfc822, String cDateString,
|
||||
Date dateTime) {
|
||||
TestData(String iso8601, String iso8601DateStringTz, String iso8601Seconds, String rfc822,
|
||||
String cDateString, Date dateTime) {
|
||||
this.iso8601DateString = iso8601;
|
||||
this.iso8601DateStringTz = iso8601DateStringTz;
|
||||
this.iso8601SecondsDateString = iso8601Seconds;
|
||||
this.rfc822DateString = rfc822;
|
||||
this.cDateString = cDateString;
|
||||
|
@ -77,21 +80,21 @@ public class DateServiceTest extends PerformanceTest {
|
|||
public DateServiceTest() {
|
||||
// Constant time test values, each TestData item must contain matching times!
|
||||
testData = new TestData[] {
|
||||
new TestData("2009-03-12T02:00:07.000Z", "2009-03-12T02:00:07Z",
|
||||
"Thu, 12 Mar 2009 02:00:07 GMT", "Thu Mar 12 02:00:07 +0000 2009",
|
||||
new Date(1236823207000l)),
|
||||
new TestData("2009-03-14T04:00:07.000Z", "2009-03-14T04:00:07Z",
|
||||
"Sat, 14 Mar 2009 04:00:07 GMT", "Thu Mar 14 04:00:07 +0000 2009",
|
||||
new Date(1237003207000l)),
|
||||
new TestData("2009-03-16T06:00:07.000Z", "2009-03-16T06:00:07Z",
|
||||
"Mon, 16 Mar 2009 06:00:07 GMT", "Thu Mar 16 06:00:07 +0000 2009",
|
||||
new Date(1237183207000l)),
|
||||
new TestData("2009-03-18T08:00:07.000Z", "2009-03-18T08:00:07Z",
|
||||
"Wed, 18 Mar 2009 08:00:07 GMT", "Thu Mar 18 08:00:07 +0000 2009",
|
||||
new Date(1237363207000l)),
|
||||
new TestData("2009-03-20T10:00:07.000Z", "2009-03-20T10:00:07Z",
|
||||
"Fri, 20 Mar 2009 10:00:07 GMT", "Thu Mar 20 10:00:07 +0000 2009",
|
||||
new Date(1237543207000l)) };
|
||||
new TestData("2009-03-12T02:00:07.000Z", "2009-03-12T02:00:07+04:00",
|
||||
"2009-03-12T02:00:07Z", "Thu, 12 Mar 2009 02:00:07 GMT",
|
||||
"Thu Mar 12 02:00:07 +0000 2009", new Date(1236823207000l)),
|
||||
new TestData("2009-03-14T04:00:07.000Z", "2009-03-14T04:00:07Z+04:00",
|
||||
"2009-03-14T04:00:07Z", "Sat, 14 Mar 2009 04:00:07 GMT",
|
||||
"Thu Mar 14 04:00:07 +0000 2009", new Date(1237003207000l)),
|
||||
new TestData("2009-03-16T06:00:07.000Z", "2009-03-16T06:00:07Z+04:00",
|
||||
"2009-03-16T06:00:07Z", "Mon, 16 Mar 2009 06:00:07 GMT",
|
||||
"Thu Mar 16 06:00:07 +0000 2009", new Date(1237183207000l)),
|
||||
new TestData("2009-03-18T08:00:07.000Z", "2009-03-18T08:00:07Z+04:00",
|
||||
"2009-03-18T08:00:07Z", "Wed, 18 Mar 2009 08:00:07 GMT",
|
||||
"Thu Mar 18 08:00:07 +0000 2009", new Date(1237363207000l)),
|
||||
new TestData("2009-03-20T10:00:07.000Z", "2009-03-20T10:00:07Z+04:00",
|
||||
"2009-03-20T10:00:07Z", "Fri, 20 Mar 2009 10:00:07 GMT",
|
||||
"Thu Mar 20 10:00:07 +0000 2009", new Date(1237543207000l)) };
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -99,6 +102,11 @@ public class DateServiceTest extends PerformanceTest {
|
|||
Date dsDate = dateService.iso8601DateParse(testData[0].iso8601DateString);
|
||||
assertEquals(dsDate, testData[0].date);
|
||||
}
|
||||
@Test
|
||||
public void testIso8601DateParseTz() throws ExecutionException, InterruptedException {
|
||||
Date dsDate = dateService.iso8601SecondsDateParse(testData[0].iso8601DateStringTz);
|
||||
assertEquals(dsDate, testData[0].date);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIso8601SecondsDateParse() throws ExecutionException, InterruptedException {
|
||||
|
|
|
@ -24,6 +24,7 @@ import static com.google.common.base.Preconditions.checkState;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.ConnectException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
|
@ -40,6 +41,8 @@ import org.jclouds.ssh.SshClient;
|
|||
import org.jclouds.ssh.SshException;
|
||||
import org.jclouds.util.Utils;
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.io.Closeables;
|
||||
import com.jcraft.jsch.ChannelExec;
|
||||
import com.jcraft.jsch.ChannelSftp;
|
||||
|
@ -75,6 +78,7 @@ public class JschSshClient implements SshClient {
|
|||
private final int port;
|
||||
private final String username;
|
||||
private final String password;
|
||||
private int sshRetries = 3;
|
||||
|
||||
@Resource
|
||||
protected Logger logger = Logger.NULL;
|
||||
|
@ -177,15 +181,37 @@ public class JschSshClient implements SshClient {
|
|||
java.util.Properties config = new java.util.Properties();
|
||||
config.put("StrictHostKeyChecking", "no");
|
||||
session.setConfig(config);
|
||||
try {
|
||||
session.connect();
|
||||
} catch (JSchException e) {
|
||||
throw new SshException(String.format("%s@%s:%d: Error connecting to session.", username,
|
||||
host.getHostAddress(), port), e);
|
||||
RETRY_LOOP: for (int i = 0; i < sshRetries; i++) {
|
||||
try {
|
||||
session.connect();
|
||||
break RETRY_LOOP;
|
||||
} catch (Exception from) {
|
||||
String rootMessage = Throwables.getRootCause(from).getMessage();
|
||||
if (i + 1 == sshRetries)
|
||||
throw propagate(from);
|
||||
if (Iterables.size(Iterables.filter(Throwables.getCausalChain(from),
|
||||
ConnectException.class)) >= 1
|
||||
|| rootMessage.indexOf("Auth fail") != -1// auth fail sometimes happens in EC2
|
||||
|| rootMessage.indexOf("invalid data") != -1
|
||||
|| rootMessage.indexOf("invalid privatekey") != -1) {
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
} catch (InterruptedException e) {
|
||||
throw propagate(e);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
throw propagate(from);
|
||||
}
|
||||
}
|
||||
logger.debug("%s@%s:%d: Session connected.", username, host.getHostAddress(), port);
|
||||
}
|
||||
|
||||
private SshException propagate(Exception e) {
|
||||
throw new SshException(String.format("%s@%s:%d: Error connecting to session.", username, host
|
||||
.getHostAddress(), port), e);
|
||||
}
|
||||
|
||||
@PreDestroy
|
||||
public void disconnect() {
|
||||
if (session != null && session.isConnected())
|
||||
|
|
|
@ -23,14 +23,18 @@
|
|||
*/
|
||||
package org.jclouds.gogrid;
|
||||
|
||||
import org.jclouds.PropertiesBuilder;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.jclouds.gogrid.reference.GoGridConstants.*;
|
||||
import static org.jclouds.gogrid.reference.GoGridConstants.PROPERTY_GOGRID_DEFAULT_DC;
|
||||
import static org.jclouds.gogrid.reference.GoGridConstants.PROPERTY_GOGRID_ENDPOINT;
|
||||
import static org.jclouds.gogrid.reference.GoGridConstants.PROPERTY_GOGRID_PASSWORD;
|
||||
import static org.jclouds.gogrid.reference.GoGridConstants.PROPERTY_GOGRID_SESSIONINTERVAL;
|
||||
import static org.jclouds.gogrid.reference.GoGridConstants.PROPERTY_GOGRID_USER;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.jclouds.PropertiesBuilder;
|
||||
|
||||
/**
|
||||
* Builds properties used in GoGrid Clients
|
||||
*
|
||||
|
@ -44,7 +48,7 @@ public class GoGridPropertiesBuilder extends PropertiesBuilder {
|
|||
Properties properties = super.defaultProperties();
|
||||
properties.setProperty(PROPERTY_GOGRID_ENDPOINT, "https://api.gogrid.com/api");
|
||||
properties.setProperty(PROPERTY_GOGRID_SESSIONINTERVAL, 60 + "");
|
||||
|
||||
properties.setProperty(PROPERTY_GOGRID_DEFAULT_DC, "SANFRANCISCO");
|
||||
return properties;
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
package org.jclouds.gogrid.compute.config;
|
||||
|
||||
import static org.jclouds.compute.domain.OsFamily.CENTOS;
|
||||
import static org.jclouds.gogrid.reference.GoGridConstants.PROPERTY_GOGRID_DEFAULT_DC;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
|
@ -82,7 +83,6 @@ import com.google.common.base.Predicates;
|
|||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.inject.Provides;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
@ -279,13 +279,21 @@ public class GoGridComputeServiceContextModule extends GoGridContextModule {
|
|||
|
||||
@Provides
|
||||
@Singleton
|
||||
Location getDefaultLocation(Map<String, ? extends Location> locations) {
|
||||
return locations.get("SANFRANCISCO");
|
||||
Location getDefaultLocation(@Named(PROPERTY_GOGRID_DEFAULT_DC) final String defaultDC,
|
||||
Set<? extends Location> locations) {
|
||||
return Iterables.find(locations, new Predicate<Location>() {
|
||||
|
||||
@Override
|
||||
public boolean apply(Location input) {
|
||||
return input.getId().equals(defaultDC);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
Map<String, ? extends Location> getDefaultLocations(GoGridClient sync, LogHolder holder,
|
||||
Set<? extends Location> getDefaultLocations(GoGridClient sync, LogHolder holder,
|
||||
Function<ComputeMetadata, String> indexer) {
|
||||
final Set<Location> locations = Sets.newHashSet();
|
||||
holder.logger.debug(">> providing locations");
|
||||
|
@ -293,13 +301,7 @@ public class GoGridComputeServiceContextModule extends GoGridContextModule {
|
|||
locations.add(new LocationImpl(LocationScope.ZONE, "SANFRANCISCO", "San Francisco, CA",
|
||||
parent));
|
||||
holder.logger.debug("<< locations(%d)", locations.size());
|
||||
return Maps.uniqueIndex(locations, new Function<Location, String>() {
|
||||
|
||||
@Override
|
||||
public String apply(Location from) {
|
||||
return from.getId();
|
||||
}
|
||||
});
|
||||
return locations;
|
||||
}
|
||||
|
||||
@Provides
|
||||
|
@ -315,10 +317,9 @@ public class GoGridComputeServiceContextModule extends GoGridContextModule {
|
|||
|
||||
@Provides
|
||||
@Singleton
|
||||
protected Map<String, ? extends Size> provideSizes(GoGridClient sync,
|
||||
Map<String, ? extends Image> images, LogHolder holder,
|
||||
Function<ComputeMetadata, String> indexer) throws InterruptedException,
|
||||
TimeoutException, ExecutionException {
|
||||
protected Set<? extends Size> provideSizes(GoGridClient sync, Set<? extends Image> images,
|
||||
LogHolder holder, Function<ComputeMetadata, String> indexer)
|
||||
throws InterruptedException, TimeoutException, ExecutionException {
|
||||
final Set<Size> sizes = Sets.newHashSet();
|
||||
holder.logger.debug(">> providing sizes");
|
||||
|
||||
|
@ -333,7 +334,7 @@ public class GoGridComputeServiceContextModule extends GoGridContextModule {
|
|||
sizes.add(new SizeImpl("5", "5", null, null, ImmutableMap.<String, String> of(), 6, 8192,
|
||||
462, ImmutableSet.<Architecture> of(Architecture.X86_32, Architecture.X86_64)));
|
||||
holder.logger.debug("<< sizes(%d)", sizes.size());
|
||||
return Maps.uniqueIndex(sizes, indexer);
|
||||
return sizes;
|
||||
}
|
||||
|
||||
private static class LogHolder {
|
||||
|
@ -346,7 +347,7 @@ public class GoGridComputeServiceContextModule extends GoGridContextModule {
|
|||
|
||||
@Provides
|
||||
@Singleton
|
||||
protected Map<String, ? extends Image> provideImages(final GoGridClient sync, LogHolder holder,
|
||||
protected Set<? extends Image> provideImages(final GoGridClient sync, LogHolder holder,
|
||||
Function<ComputeMetadata, String> indexer, Location location,
|
||||
PopulateDefaultLoginCredentialsForImageStrategy authenticator)
|
||||
throws InterruptedException, ExecutionException, TimeoutException {
|
||||
|
@ -375,6 +376,6 @@ public class GoGridComputeServiceContextModule extends GoGridContextModule {
|
|||
osDescription, arch, defaultCredentials));
|
||||
}
|
||||
holder.logger.debug("<< images(%d)", images.size());
|
||||
return Maps.uniqueIndex(images, indexer);
|
||||
return images;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,10 +22,12 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||
|
||||
import java.net.InetAddress;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
|
@ -37,11 +39,14 @@ import org.jclouds.domain.Credentials;
|
|||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.gogrid.domain.Server;
|
||||
import org.jclouds.gogrid.services.GridServerClient;
|
||||
import org.jclouds.logging.Logger;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
/**
|
||||
* @author Oleksiy Yarmula
|
||||
|
@ -50,14 +55,33 @@ import com.google.common.collect.ImmutableSet;
|
|||
public class ServerToNodeMetadata implements Function<Server, NodeMetadata> {
|
||||
public static final Pattern ALL_BEFORE_HYPHEN_HEX = Pattern.compile("([^-]+)-[0-9a-f]+");
|
||||
|
||||
@Resource
|
||||
protected Logger logger = Logger.NULL;
|
||||
private final Map<String, NodeState> serverStateToNodeState;
|
||||
private final GridServerClient client;
|
||||
private final Location location;
|
||||
private final Map<String, ? extends Image> images;
|
||||
private final Set<? extends Image> images;
|
||||
|
||||
private static class FindImageForServer implements Predicate<Image> {
|
||||
private final Location location;
|
||||
private final Server instance;
|
||||
|
||||
private FindImageForServer(Location location, Server instance) {
|
||||
this.location = location;
|
||||
this.instance = instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Image input) {
|
||||
return input.getId().equals(instance.getImage().getId() + "")
|
||||
&& (input.getLocation() == null || input.getLocation().equals(location) || input
|
||||
.getLocation().equals(location.getParent()));
|
||||
}
|
||||
}
|
||||
|
||||
@Inject
|
||||
ServerToNodeMetadata(Map<String, NodeState> serverStateToNodeState, GridServerClient client,
|
||||
Map<String, ? extends Image> images, Location location) {
|
||||
Set<? extends Image> images, Location location) {
|
||||
this.serverStateToNodeState = checkNotNull(serverStateToNodeState, "serverStateToNodeState");
|
||||
this.client = checkNotNull(client, "client");
|
||||
this.images = checkNotNull(images, "images");
|
||||
|
@ -71,8 +95,16 @@ public class ServerToNodeMetadata implements Function<Server, NodeMetadata> {
|
|||
Set<InetAddress> ipSet = ImmutableSet.of(from.getIp().getIp());
|
||||
NodeState state = serverStateToNodeState.get(from.getState().getName());
|
||||
Credentials creds = client.getServerCredentialsList().get(from.getName());
|
||||
Image image = null;
|
||||
try {
|
||||
image = Iterables.find(images, new FindImageForServer(location, from));
|
||||
} catch (NoSuchElementException e) {
|
||||
logger
|
||||
.warn("could not find a matching image for server %s in location %s", from,
|
||||
location);
|
||||
}
|
||||
return new NodeMetadataImpl(from.getId() + "", from.getName(), location, null, ImmutableMap
|
||||
.<String, String> of(), tag, images.get(from.getImage().getId() + ""), state, ipSet,
|
||||
ImmutableList.<InetAddress> of(), ImmutableMap.<String, String> of(), creds);
|
||||
.<String, String> of(), tag, image, state, ipSet, ImmutableList.<InetAddress> of(),
|
||||
ImmutableMap.<String, String> of(), creds);
|
||||
}
|
||||
}
|
|
@ -29,12 +29,13 @@ package org.jclouds.gogrid.reference;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
public interface GoGridConstants {
|
||||
public static final String PROPERTY_GOGRID_ENDPOINT = "jclouds.gogrid.endpoint";
|
||||
public static final String PROPERTY_GOGRID_USER = "jclouds.gogrid.api.key";
|
||||
public static final String PROPERTY_GOGRID_PASSWORD = "jclouds.gogrid.secret";
|
||||
/**
|
||||
* how long do we wait before obtaining a new timestamp for requests.
|
||||
*/
|
||||
public static final String PROPERTY_GOGRID_SESSIONINTERVAL = "jclouds.gogrid.sessioninterval";
|
||||
public static final String PROPERTY_GOGRID_ENDPOINT = "jclouds.gogrid.endpoint";
|
||||
public static final String PROPERTY_GOGRID_USER = "jclouds.gogrid.api.key";
|
||||
public static final String PROPERTY_GOGRID_PASSWORD = "jclouds.gogrid.secret";
|
||||
/**
|
||||
* how long do we wait before obtaining a new timestamp for requests.
|
||||
*/
|
||||
public static final String PROPERTY_GOGRID_SESSIONINTERVAL = "jclouds.gogrid.sessioninterval";
|
||||
public static final String PROPERTY_GOGRID_DEFAULT_DC = "jclouds.gogrid.defaultdc";
|
||||
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import static org.testng.Assert.assertEquals;
|
|||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.NodeState;
|
||||
|
@ -23,6 +24,8 @@ import org.jclouds.gogrid.domain.ServerImage;
|
|||
import org.jclouds.gogrid.services.GridServerClient;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
|
@ -34,7 +37,9 @@ public class ServerToNodeMetadataTest {
|
|||
public void testApplySetsTagFromNameAndCredentialsFromName() throws UnknownHostException {
|
||||
GridServerClient client = createMock(GridServerClient.class);
|
||||
Map<String, NodeState> serverStateToNodeState = createMock(Map.class);
|
||||
Map<String, org.jclouds.compute.domain.Image> images = createMock(Map.class);
|
||||
org.jclouds.compute.domain.Image jcImage = createMock(org.jclouds.compute.domain.Image.class);
|
||||
|
||||
Set<org.jclouds.compute.domain.Image> images = ImmutableSet.of(jcImage);
|
||||
Server server = createMock(Server.class);
|
||||
|
||||
expect(server.getId()).andReturn(1000l).atLeastOnce();
|
||||
|
@ -54,16 +59,15 @@ public class ServerToNodeMetadataTest {
|
|||
ServerImage image = createMock(ServerImage.class);
|
||||
expect(server.getImage()).andReturn(image).atLeastOnce();
|
||||
expect(image.getId()).andReturn(2000l).atLeastOnce();
|
||||
|
||||
org.jclouds.compute.domain.Image jcImage = createMock(org.jclouds.compute.domain.Image.class);
|
||||
expect(images.get("2000")).andReturn(jcImage);
|
||||
expect(jcImage.getId()).andReturn("2000").atLeastOnce();
|
||||
expect(jcImage.getLocation()).andReturn(location).atLeastOnce();
|
||||
|
||||
replay(client);
|
||||
replay(serverStateToNodeState);
|
||||
replay(server);
|
||||
replay(image);
|
||||
replay(jcImage);
|
||||
replay(credentialsMap);
|
||||
replay(images);
|
||||
|
||||
ServerToNodeMetadata parser = new ServerToNodeMetadata(serverStateToNodeState, client,
|
||||
images, location);
|
||||
|
@ -79,7 +83,8 @@ public class ServerToNodeMetadataTest {
|
|||
verify(image);
|
||||
verify(credentialsMap);
|
||||
verify(server);
|
||||
verify(images);
|
||||
verify(jcImage);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -21,7 +21,6 @@ package org.jclouds.rackspace.cloudfiles.blobstore;
|
|||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.util.concurrent.Futures.compose;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
|
@ -81,7 +80,7 @@ public class CloudFilesAsyncBlobStore extends BaseAsyncBlobStore {
|
|||
@Inject
|
||||
CloudFilesAsyncBlobStore(BlobStoreContext context, BlobStoreUtils blobUtils,
|
||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService service,
|
||||
Location defaultLocation, Map<String, ? extends Location> locations,
|
||||
Location defaultLocation, Set<? extends Location> locations,
|
||||
CloudFilesClient sync, CloudFilesAsyncClient async,
|
||||
ContainerToResourceMetadata container2ResourceMd,
|
||||
BlobStoreListContainerOptionsToListContainerOptions container2ContainerListOptions,
|
||||
|
|
|
@ -20,7 +20,6 @@ package org.jclouds.rackspace.cloudfiles.blobstore;
|
|||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
@ -70,7 +69,7 @@ public class CloudFilesBlobStore extends BaseBlobStore {
|
|||
|
||||
@Inject
|
||||
CloudFilesBlobStore(BlobStoreContext context, BlobStoreUtils blobUtils,
|
||||
Location defaultLocation, Map<String, ? extends Location> locations,
|
||||
Location defaultLocation, Set<? extends Location> locations,
|
||||
CloudFilesClient sync, ContainerToResourceMetadata container2ResourceMd,
|
||||
BlobStoreListContainerOptionsToListContainerOptions container2ContainerListOptions,
|
||||
ContainerToResourceList container2ResourceList, ObjectToBlob object2Blob,
|
||||
|
|
|
@ -87,7 +87,6 @@ import com.google.common.base.Predicates;
|
|||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.inject.Provides;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
@ -303,8 +302,8 @@ public class CloudServersComputeServiceContextModule extends CloudServersContext
|
|||
|
||||
@Provides
|
||||
@Singleton
|
||||
protected Map<String, ? extends Size> provideSizes(CloudServersClient sync,
|
||||
Map<String, ? extends Image> images, Location location, LogHolder holder,
|
||||
protected Set<? extends Size> provideSizes(CloudServersClient sync, Set<? extends Image> images,
|
||||
Location location, LogHolder holder,
|
||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor,
|
||||
Function<ComputeMetadata, String> indexer) throws InterruptedException,
|
||||
TimeoutException, ExecutionException {
|
||||
|
@ -316,7 +315,7 @@ public class CloudServersComputeServiceContextModule extends CloudServersContext
|
|||
ImmutableSet.<Architecture> of(Architecture.X86_32, Architecture.X86_64)));
|
||||
}
|
||||
holder.logger.debug("<< sizes(%d)", sizes.size());
|
||||
return Maps.uniqueIndex(sizes, indexer);
|
||||
return sizes;
|
||||
}
|
||||
|
||||
private static class LogHolder {
|
||||
|
@ -329,8 +328,8 @@ public class CloudServersComputeServiceContextModule extends CloudServersContext
|
|||
|
||||
@Provides
|
||||
@Singleton
|
||||
protected Map<String, ? extends Image> provideImages(final CloudServersClient sync,
|
||||
Location location, LogHolder holder, Function<ComputeMetadata, String> indexer)
|
||||
protected Set<? extends Image> provideImages(final CloudServersClient sync, Location location,
|
||||
LogHolder holder, Function<ComputeMetadata, String> indexer)
|
||||
throws InterruptedException, ExecutionException, TimeoutException {
|
||||
final Set<Image> images = Sets.newHashSet();
|
||||
holder.logger.debug(">> providing images");
|
||||
|
@ -358,6 +357,6 @@ public class CloudServersComputeServiceContextModule extends CloudServersContext
|
|||
new Credentials("root", null)));
|
||||
}
|
||||
holder.logger.debug("<< images(%d)", images.size());
|
||||
return Maps.uniqueIndex(images, indexer);
|
||||
return images;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,9 +21,12 @@ package org.jclouds.rackspace.cloudservers.compute.functions;
|
|||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.jclouds.compute.domain.Image;
|
||||
|
@ -33,11 +36,14 @@ import org.jclouds.compute.domain.internal.NodeMetadataImpl;
|
|||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.domain.LocationScope;
|
||||
import org.jclouds.domain.internal.LocationImpl;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.rackspace.cloudservers.domain.Server;
|
||||
import org.jclouds.rackspace.cloudservers.domain.ServerStatus;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
|
@ -47,11 +53,31 @@ public class ServerToNodeMetadata implements Function<Server, NodeMetadata> {
|
|||
.compile("[^-]+-([^-]+)-[0-9a-f]+");
|
||||
private final Location location;
|
||||
private final Map<ServerStatus, NodeState> serverToNodeState;
|
||||
private final Map<String, ? extends Image> images;
|
||||
private final Set<? extends Image> images;
|
||||
|
||||
@Resource
|
||||
protected Logger logger = Logger.NULL;
|
||||
|
||||
private static class FindImageForServer implements Predicate<Image> {
|
||||
private final Location location;
|
||||
private final Server instance;
|
||||
|
||||
private FindImageForServer(Location location, Server instance) {
|
||||
this.location = location;
|
||||
this.instance = instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Image input) {
|
||||
return input.getId().equals(instance.getImageId() + "")
|
||||
&& (input.getLocation() == null || input.getLocation().equals(
|
||||
location.getParent()));
|
||||
}
|
||||
}
|
||||
|
||||
@Inject
|
||||
ServerToNodeMetadata(Map<ServerStatus, NodeState> serverStateToNodeState,
|
||||
Map<String, ? extends Image> images, Location location) {
|
||||
Set<? extends Image> images, Location location) {
|
||||
this.serverToNodeState = checkNotNull(serverStateToNodeState, "serverStateToNodeState");
|
||||
this.images = checkNotNull(images, "images");
|
||||
this.location = checkNotNull(location, "location");
|
||||
|
@ -62,10 +88,19 @@ public class ServerToNodeMetadata implements Function<Server, NodeMetadata> {
|
|||
Matcher matcher = SECOND_FIELD_DELIMETED_BY_HYPHEN_ENDING_IN_HYPHEN_HEX.matcher(from
|
||||
.getName());
|
||||
final String tag = matcher.find() ? matcher.group(1) : null;
|
||||
return new NodeMetadataImpl(from.getId() + "", from.getName(), new LocationImpl(
|
||||
LocationScope.HOST, from.getHostId(), from.getHostId(), location), null, from
|
||||
.getMetadata(), tag, images.get(from.getImageId().toString()), serverToNodeState
|
||||
.get(from.getStatus()), from.getAddresses().getPublicAddresses(), from
|
||||
.getAddresses().getPrivateAddresses(), ImmutableMap.<String, String> of(), null);
|
||||
Location host = new LocationImpl(LocationScope.HOST, from.getHostId(), from.getHostId(),
|
||||
location);
|
||||
Image image = null;
|
||||
try {
|
||||
image = Iterables.find(images, new FindImageForServer(host, from));
|
||||
} catch (NoSuchElementException e) {
|
||||
logger
|
||||
.warn("could not find a matching image for server %s in location %s", from,
|
||||
location);
|
||||
}
|
||||
return new NodeMetadataImpl(from.getId() + "", from.getName(), host, null,
|
||||
from.getMetadata(), tag, image, serverToNodeState.get(from.getStatus()), from
|
||||
.getAddresses().getPublicAddresses(), from.getAddresses()
|
||||
.getPrivateAddresses(), ImmutableMap.<String, String> of(), null);
|
||||
}
|
||||
}
|
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
package org.jclouds.rackspace.config;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
||||
|
@ -27,7 +27,7 @@ import org.jclouds.domain.LocationScope;
|
|||
import org.jclouds.domain.internal.LocationImpl;
|
||||
import org.jclouds.http.RequiresHttp;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Provides;
|
||||
|
||||
|
@ -57,7 +57,7 @@ public class RackspaceLocationsModule extends AbstractModule {
|
|||
|
||||
@Provides
|
||||
@Singleton
|
||||
Map<String, ? extends Location> provideLocations(Location location) {
|
||||
return ImmutableMap.of(location.getId(), location);
|
||||
Set<? extends Location> provideLocations(Location location) {
|
||||
return ImmutableSet.of(location);
|
||||
}
|
||||
}
|
|
@ -34,7 +34,9 @@ public class ServerToNodeMetadataTest {
|
|||
@Test
|
||||
public void testApplySetsTagFromNameAndSetsMetadata() throws UnknownHostException {
|
||||
Map<ServerStatus, NodeState> serverStateToNodeState = createMock(Map.class);
|
||||
Map<String, org.jclouds.compute.domain.Image> images = createMock(Map.class);
|
||||
org.jclouds.compute.domain.Image jcImage = createMock(org.jclouds.compute.domain.Image.class);
|
||||
|
||||
Set<org.jclouds.compute.domain.Image> images = ImmutableSet.of(jcImage);
|
||||
Server server = createMock(Server.class);
|
||||
|
||||
expect(server.getId()).andReturn(10000).atLeastOnce();
|
||||
|
@ -60,14 +62,13 @@ public class ServerToNodeMetadataTest {
|
|||
expect(addresses.getPrivateAddresses()).andReturn(privateAddresses);
|
||||
|
||||
expect(server.getImageId()).andReturn(2000).atLeastOnce();
|
||||
|
||||
org.jclouds.compute.domain.Image jcImage = createMock(org.jclouds.compute.domain.Image.class);
|
||||
expect(images.get("2000")).andReturn(jcImage);
|
||||
expect(jcImage.getId()).andReturn("2000").atLeastOnce();
|
||||
expect(jcImage.getLocation()).andReturn(provider).atLeastOnce();
|
||||
|
||||
replay(addresses);
|
||||
replay(jcImage);
|
||||
replay(serverStateToNodeState);
|
||||
replay(server);
|
||||
replay(images);
|
||||
|
||||
ServerToNodeMetadata parser = new ServerToNodeMetadata(serverStateToNodeState, images,
|
||||
provider);
|
||||
|
@ -85,7 +86,7 @@ public class ServerToNodeMetadataTest {
|
|||
verify(addresses);
|
||||
verify(serverStateToNodeState);
|
||||
verify(server);
|
||||
verify(images);
|
||||
verify(jcImage);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ package org.jclouds.rimuhosting.miro;
|
|||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.jclouds.rimuhosting.miro.reference.RimuHostingConstants.PROPERTY_RIMUHOSTING_APIKEY;
|
||||
import static org.jclouds.rimuhosting.miro.reference.RimuHostingConstants.PROPERTY_RIMUHOSTING_DEFAULT_DC;
|
||||
import static org.jclouds.rimuhosting.miro.reference.RimuHostingConstants.PROPERTY_RIMUHOSTING_ENDPOINT;
|
||||
|
||||
import java.net.URI;
|
||||
|
@ -37,6 +38,7 @@ public class RimuHostingPropertiesBuilder extends PropertiesBuilder {
|
|||
protected Properties defaultProperties() {
|
||||
Properties properties = super.defaultProperties();
|
||||
properties.setProperty(PROPERTY_RIMUHOSTING_ENDPOINT, "https://rimuhosting.com/r");
|
||||
properties.setProperty(PROPERTY_RIMUHOSTING_DEFAULT_DC, "DCDALLAS");
|
||||
return properties;
|
||||
}
|
||||
|
||||
|
|
|
@ -20,10 +20,12 @@ package org.jclouds.rimuhosting.miro.compute.config;
|
|||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.jclouds.compute.domain.OsFamily.UBUNTU;
|
||||
import static org.jclouds.rimuhosting.miro.reference.RimuHostingConstants.PROPERTY_RIMUHOSTING_DEFAULT_DC;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
@ -85,7 +87,6 @@ import com.google.common.collect.ImmutableList;
|
|||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.inject.Provides;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
@ -259,17 +260,37 @@ public class RimuHostingComputeServiceContextModule extends RimuHostingContextMo
|
|||
|
||||
@Singleton
|
||||
private static class ServerToNodeMetadata implements Function<Server, NodeMetadata> {
|
||||
|
||||
@Resource
|
||||
protected Logger logger = Logger.NULL;
|
||||
private final Function<Server, Iterable<InetAddress>> getPublicAddresses;
|
||||
private final Map<RunningState, NodeState> runningStateToNodeState;
|
||||
private final Map<String, ? extends Image> images;
|
||||
private final Set<? extends Image> images;
|
||||
@SuppressWarnings("unused")
|
||||
private final Map<String, ? extends Location> locations;
|
||||
private final Set<? extends Location> locations;
|
||||
|
||||
private static class FindImageForServer implements Predicate<Image> {
|
||||
private final Location location;
|
||||
private final Server instance;
|
||||
|
||||
private FindImageForServer(Location location, Server instance) {
|
||||
this.location = location;
|
||||
this.instance = instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Image input) {
|
||||
return input.getId().equals(instance.getImageId())
|
||||
&& (input.getLocation() == null || input.getLocation().equals(location) || input
|
||||
.getLocation().equals(location.getParent()));
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Inject
|
||||
ServerToNodeMetadata(Function<Server, Iterable<InetAddress>> getPublicAddresses,
|
||||
Map<RunningState, NodeState> runningStateToNodeState,
|
||||
Map<String, ? extends Image> images, Map<String, ? extends Location> locations) {
|
||||
Map<RunningState, NodeState> runningStateToNodeState, Set<? extends Image> images,
|
||||
Set<? extends Location> locations) {
|
||||
this.getPublicAddresses = checkNotNull(getPublicAddresses, "serverStateToNodeState");
|
||||
this.runningStateToNodeState = checkNotNull(runningStateToNodeState,
|
||||
"serverStateToNodeState");
|
||||
|
@ -284,10 +305,18 @@ public class RimuHostingComputeServiceContextModule extends RimuHostingContextMo
|
|||
.getLocation().getName(), null);
|
||||
String tag = from.getName().replaceAll("-[0-9]+", "");
|
||||
Credentials creds = null;
|
||||
|
||||
Image image = null;
|
||||
try {
|
||||
image = Iterables.find(images, new FindImageForServer(location, from));
|
||||
} catch (NoSuchElementException e) {
|
||||
logger.warn("could not find a matching image for server %s in location %s", from,
|
||||
location);
|
||||
}
|
||||
NodeState state = runningStateToNodeState.get(from.getState());
|
||||
return new NodeMetadataImpl(from.getId() + "", from.getName(), location, null,
|
||||
ImmutableMap.<String, String> of(), tag, images.get(from.getImageId()), state,
|
||||
getPublicAddresses.apply(from), ImmutableList.<InetAddress> of(), ImmutableMap
|
||||
ImmutableMap.<String, String> of(), tag, image, state, getPublicAddresses
|
||||
.apply(from), ImmutableList.<InetAddress> of(), ImmutableMap
|
||||
.<String, String> of(), creds);
|
||||
|
||||
}
|
||||
|
@ -333,13 +362,21 @@ public class RimuHostingComputeServiceContextModule extends RimuHostingContextMo
|
|||
|
||||
@Provides
|
||||
@Singleton
|
||||
Location getDefaultLocation(Map<String, ? extends Location> locations) {
|
||||
return locations.get("DCDALLAS");
|
||||
Location getDefaultLocation(@Named(PROPERTY_RIMUHOSTING_DEFAULT_DC) final String defaultDC,
|
||||
Set<? extends Location> locations) {
|
||||
return Iterables.find(locations, new Predicate<Location>() {
|
||||
|
||||
@Override
|
||||
public boolean apply(Location input) {
|
||||
return input.getId().equals(defaultDC);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
Map<String, ? extends Location> getDefaultLocations(RimuHostingClient sync, LogHolder holder,
|
||||
Set<? extends Location> getDefaultLocations(RimuHostingClient sync, LogHolder holder,
|
||||
Function<ComputeMetadata, String> indexer) {
|
||||
final Set<Location> locations = Sets.newHashSet();
|
||||
holder.logger.debug(">> providing locations");
|
||||
|
@ -353,13 +390,7 @@ public class RimuHostingComputeServiceContextModule extends RimuHostingContextMo
|
|||
}
|
||||
}
|
||||
holder.logger.debug("<< locations(%d)", locations.size());
|
||||
return Maps.uniqueIndex(locations, new Function<Location, String>() {
|
||||
|
||||
@Override
|
||||
public String apply(Location from) {
|
||||
return from.getId();
|
||||
}
|
||||
});
|
||||
return locations;
|
||||
}
|
||||
|
||||
@Provides
|
||||
|
@ -375,25 +406,33 @@ public class RimuHostingComputeServiceContextModule extends RimuHostingContextMo
|
|||
|
||||
@Provides
|
||||
@Singleton
|
||||
protected Map<String, ? extends Size> provideSizes(RimuHostingClient sync,
|
||||
Map<String, ? extends Image> images, Map<String, ? extends Location> locations,
|
||||
LogHolder holder, @Named(Constants.PROPERTY_USER_THREADS) ExecutorService userExecutor,
|
||||
protected Set<? extends Size> provideSizes(RimuHostingClient sync, Set<? extends Image> images,
|
||||
Set<? extends Location> locations, LogHolder holder,
|
||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService userExecutor,
|
||||
Function<ComputeMetadata, String> indexer) throws InterruptedException,
|
||||
TimeoutException, ExecutionException {
|
||||
final Set<Size> sizes = Sets.newHashSet();
|
||||
holder.logger.debug(">> providing sizes");
|
||||
for (final PricingPlan from : sync.getPricingPlanList()) {
|
||||
try {
|
||||
sizes.add(new SizeImpl(from.getId(), from.getId(), locations.get(from.getDataCenter()
|
||||
.getId()), null, ImmutableMap.<String, String> of(), 1, from.getRam(), from
|
||||
.getDiskSize(), ImmutableSet.<Architecture> of(Architecture.X86_32,
|
||||
Architecture.X86_64)));
|
||||
|
||||
final Location location = Iterables.find(locations, new Predicate<Location>() {
|
||||
|
||||
@Override
|
||||
public boolean apply(Location input) {
|
||||
return input.getId().equals(from.getDataCenter().getId());
|
||||
}
|
||||
|
||||
});
|
||||
sizes.add(new SizeImpl(from.getId(), from.getId(), location, null, ImmutableMap
|
||||
.<String, String> of(), 1, from.getRam(), from.getDiskSize(), ImmutableSet
|
||||
.<Architecture> of(Architecture.X86_32, Architecture.X86_64)));
|
||||
} catch (NullPointerException e) {
|
||||
holder.logger.warn("datacenter not present in " + from.getId());
|
||||
}
|
||||
}
|
||||
holder.logger.debug("<< sizes(%d)", sizes.size());
|
||||
return Maps.uniqueIndex(sizes, indexer);
|
||||
return sizes;
|
||||
}
|
||||
|
||||
private static class LogHolder {
|
||||
|
@ -406,9 +445,9 @@ public class RimuHostingComputeServiceContextModule extends RimuHostingContextMo
|
|||
|
||||
@Provides
|
||||
@Singleton
|
||||
protected Map<String, ? extends Image> provideImages(final RimuHostingClient sync,
|
||||
LogHolder holder, Function<ComputeMetadata, String> indexer)
|
||||
throws InterruptedException, ExecutionException, TimeoutException {
|
||||
protected Set<? extends Image> provideImages(final RimuHostingClient sync, LogHolder holder,
|
||||
Function<ComputeMetadata, String> indexer) throws InterruptedException,
|
||||
ExecutionException, TimeoutException {
|
||||
final Set<Image> images = Sets.newHashSet();
|
||||
holder.logger.debug(">> providing images");
|
||||
for (final org.jclouds.rimuhosting.miro.domain.Image from : sync.getImageList()) {
|
||||
|
@ -434,7 +473,7 @@ public class RimuHostingComputeServiceContextModule extends RimuHostingContextMo
|
|||
new Credentials("root", null)));
|
||||
}
|
||||
holder.logger.debug("<< images(%d)", images.size());
|
||||
return Maps.uniqueIndex(images, indexer);
|
||||
return images;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -26,4 +26,6 @@ package org.jclouds.rimuhosting.miro.reference;
|
|||
public interface RimuHostingConstants {
|
||||
public static final String PROPERTY_RIMUHOSTING_ENDPOINT = "jclouds.rimuhosting.endpoint";
|
||||
public static final String PROPERTY_RIMUHOSTING_APIKEY = "jclouds.rimuhosting.password";
|
||||
public static final String PROPERTY_RIMUHOSTING_DEFAULT_DC = "jclouds.rimuhosting.defaultdc";
|
||||
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ import org.apache.tools.ant.Project;
|
|||
import org.apache.tools.ant.Task;
|
||||
import org.jclouds.compute.ComputeService;
|
||||
import org.jclouds.compute.ComputeServiceContext;
|
||||
import org.jclouds.compute.RunNodesException;
|
||||
import org.jclouds.compute.domain.ComputeMetadata;
|
||||
import org.jclouds.compute.domain.Image;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
|
@ -90,14 +91,19 @@ public class ComputeTask extends Task {
|
|||
for (String action : Splitter.on(',').split(actions)) {
|
||||
Action act = Action.valueOf(CaseFormat.LOWER_HYPHEN.to(CaseFormat.UPPER_UNDERSCORE,
|
||||
action));
|
||||
invokeActionOnService(act, context.getComputeService());
|
||||
try {
|
||||
invokeActionOnService(act, context.getComputeService());
|
||||
} catch (RunNodesException e) {
|
||||
throw new BuildException(e);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
context.close();
|
||||
}
|
||||
}
|
||||
|
||||
private void invokeActionOnService(Action action, ComputeService computeService) {
|
||||
private void invokeActionOnService(Action action, ComputeService computeService)
|
||||
throws RunNodesException {
|
||||
switch (action) {
|
||||
case CREATE:
|
||||
case GET:
|
||||
|
@ -140,7 +146,7 @@ public class ComputeTask extends Task {
|
|||
|
||||
private void listDetails(ComputeService computeService) {
|
||||
log("list details");
|
||||
for (ComputeMetadata node : computeService.getNodes().values()) {// TODO
|
||||
for (ComputeMetadata node : computeService.listNodes()) {// TODO
|
||||
// parallel
|
||||
logDetails(computeService, node);
|
||||
}
|
||||
|
@ -148,7 +154,7 @@ public class ComputeTask extends Task {
|
|||
|
||||
private void listImages(ComputeService computeService) {
|
||||
log("list images");
|
||||
for (Image image : computeService.getImages().values()) {// TODO
|
||||
for (Image image : computeService.listImages()) {// TODO
|
||||
log(String
|
||||
.format(
|
||||
" image location=%s, id=%s, name=%s, version=%s, arch=%s, osfam=%s, osdesc=%s, desc=%s",
|
||||
|
@ -160,7 +166,7 @@ public class ComputeTask extends Task {
|
|||
|
||||
private void listSizes(ComputeService computeService) {
|
||||
log("list sizes");
|
||||
for (Size size : computeService.getSizes().values()) {// TODO
|
||||
for (Size size : computeService.listSizes()) {// TODO
|
||||
log(String.format(" size id=%s, cores=%s, ram=%s, disk=%s", size.getId(), size
|
||||
.getCores(), size.getRam(), size.getDisk()));
|
||||
}
|
||||
|
@ -168,7 +174,7 @@ public class ComputeTask extends Task {
|
|||
|
||||
private void listLocations(ComputeService computeService) {
|
||||
log("list locations");
|
||||
for (Location location : computeService.getAssignableLocations().values()) {// TODO
|
||||
for (Location location : computeService.listAssignableLocations()) {// TODO
|
||||
log(String.format(" location id=%s, scope=%s, description=%s, parent=%s", location
|
||||
.getId(), location.getScope(), location.getDescription(), location.getParent()));
|
||||
}
|
||||
|
@ -176,13 +182,13 @@ public class ComputeTask extends Task {
|
|||
|
||||
private void list(ComputeService computeService) {
|
||||
log("list");
|
||||
for (ComputeMetadata node : computeService.getNodes().values()) {
|
||||
for (ComputeMetadata node : computeService.listNodes()) {
|
||||
log(String.format(" location=%s, id=%s, tag=%s", node.getLocation(), node.getId(), node
|
||||
.getName()));
|
||||
}
|
||||
}
|
||||
|
||||
private void create(ComputeService computeService) {
|
||||
private void create(ComputeService computeService) throws RunNodesException {
|
||||
String tag = nodeElement.getTag();
|
||||
|
||||
log(String.format("create tag: %s, count: %d, size: %s, os: %s", tag, nodeElement.getCount(),
|
||||
|
@ -191,7 +197,7 @@ public class ComputeTask extends Task {
|
|||
Template template = createTemplateFromElement(nodeElement, computeService);
|
||||
|
||||
for (NodeMetadata createdNode : computeService.runNodesWithTag(tag, nodeElement.getCount(),
|
||||
template).values()) {
|
||||
template)) {
|
||||
logDetails(computeService, createdNode);
|
||||
addNodeDetailsAsProjectProperties(createdNode);
|
||||
}
|
||||
|
@ -218,7 +224,7 @@ public class ComputeTask extends Task {
|
|||
|
||||
private void get(ComputeService computeService) {
|
||||
log(String.format("get tag: %s", nodeElement.getTag()));
|
||||
for (ComputeMetadata node : computeService.getNodesWithTag(nodeElement.getTag()).values()) {
|
||||
for (ComputeMetadata node : computeService.listNodesWithTag(nodeElement.getTag())) {
|
||||
logDetails(computeService, node);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ package org.jclouds.vcloud.bluelock.compute;
|
|||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jclouds.compute.domain.Architecture;
|
||||
import org.jclouds.compute.domain.Image;
|
||||
|
@ -54,7 +55,7 @@ public class BlueLockVCloudComputeServiceLiveTest extends VCloudComputeServiceLi
|
|||
@Override
|
||||
public void testListImages() throws Exception {
|
||||
super.testListImages();
|
||||
Map<String, ? extends Image> images = client.getImages();
|
||||
Set<? extends Image> images = client.listImages();
|
||||
assertEquals(images.size(), 5);
|
||||
// TODO verify parsing works
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ import static org.jclouds.compute.domain.OsFamily.UBUNTU;
|
|||
import static org.jclouds.vcloud.options.InstantiateVAppTemplateOptions.Builder.processorCount;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
@ -97,6 +98,7 @@ import com.google.common.base.Predicates;
|
|||
import com.google.common.base.Supplier;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
|
@ -145,7 +147,7 @@ public class VCloudComputeServiceContextModule extends VCloudContextModule {
|
|||
@Provides
|
||||
@Named("NAMING_CONVENTION")
|
||||
@Singleton
|
||||
String provideNamingConvention() {
|
||||
protected String provideNamingConvention() {
|
||||
return "%s-%s%s";
|
||||
}
|
||||
|
||||
|
@ -232,8 +234,10 @@ public class VCloudComputeServiceContextModule extends VCloudContextModule {
|
|||
@Inject
|
||||
protected VCloudListNodesStrategy(VCloudClient client, VCloudComputeClient computeClient,
|
||||
Map<VAppStatus, NodeState> vAppStatusToNodeState, GetExtra getExtra,
|
||||
Map<String, ? extends Location> locations, Map<String, ? extends Image> images) {
|
||||
super(client, computeClient, vAppStatusToNodeState, getExtra, locations, images);
|
||||
FindLocationForResourceInVDC findLocationForResourceInVDC,
|
||||
Set<? extends Image> images) {
|
||||
super(client, computeClient, vAppStatusToNodeState, getExtra,
|
||||
findLocationForResourceInVDC, images);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -273,9 +277,10 @@ public class VCloudComputeServiceContextModule extends VCloudContextModule {
|
|||
@Inject
|
||||
protected VCloudGetNodeMetadataStrategy(VCloudClient client,
|
||||
VCloudComputeClient computeClient, Map<VAppStatus, NodeState> vAppStatusToNodeState,
|
||||
GetExtra getExtra, Map<String, ? extends Location> locations,
|
||||
Map<String, ? extends Image> images) {
|
||||
super(client, computeClient, vAppStatusToNodeState, getExtra, locations, images);
|
||||
GetExtra getExtra, FindLocationForResourceInVDC findLocationForResourceInVDC,
|
||||
Set<? extends Image> images) {
|
||||
super(client, computeClient, vAppStatusToNodeState, getExtra,
|
||||
findLocationForResourceInVDC, images);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -311,9 +316,9 @@ public class VCloudComputeServiceContextModule extends VCloudContextModule {
|
|||
|
||||
@Provides
|
||||
@Singleton
|
||||
protected Map<String, ? extends Image> provideImages(final VCloudClient client,
|
||||
protected Set<? extends Image> provideImages(final VCloudClient client,
|
||||
final PopulateDefaultLoginCredentialsForImageStrategy credentialsProvider,
|
||||
final Map<String, ? extends Location> locations, LogHolder holder,
|
||||
LogHolder holder, final FindLocationForResourceInVDC findLocationForResourceInVDC,
|
||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor,
|
||||
Function<ComputeMetadata, String> indexer) throws InterruptedException,
|
||||
ExecutionException, TimeoutException {
|
||||
|
@ -339,11 +344,15 @@ public class VCloudComputeServiceContextModule extends VCloudContextModule {
|
|||
Architecture arch = resource.getName().indexOf("64") == -1 ? Architecture.X86_32
|
||||
: Architecture.X86_64;
|
||||
VAppTemplate template = client.getVAppTemplate(resource.getId());
|
||||
|
||||
Location location = findLocationForResourceInVDC.apply(resource, vDC
|
||||
.getId());
|
||||
|
||||
images.add(new ImageImpl(resource.getId(), template.getName(),
|
||||
locations.get(vDC.getId()), template.getLocation(),
|
||||
ImmutableMap.<String, String> of(), template
|
||||
.getDescription(), "", myOs, template.getName(),
|
||||
arch, new Credentials("root", null)));
|
||||
location, template.getLocation(), ImmutableMap
|
||||
.<String, String> of(), template.getDescription(),
|
||||
"", myOs, template.getName(), arch, new Credentials("root",
|
||||
null)));
|
||||
return null;
|
||||
}
|
||||
}), executor));
|
||||
|
@ -353,7 +362,7 @@ public class VCloudComputeServiceContextModule extends VCloudContextModule {
|
|||
ConcurrentUtils.awaitCompletion(responses, executor, null, holder.logger,
|
||||
"vAppTemplates in " + vDC);
|
||||
}
|
||||
return Maps.uniqueIndex(images, indexer);
|
||||
return images;
|
||||
}
|
||||
|
||||
@Provides
|
||||
|
@ -369,17 +378,15 @@ public class VCloudComputeServiceContextModule extends VCloudContextModule {
|
|||
|
||||
@Provides
|
||||
@Singleton
|
||||
Map<String, ? extends Location> provideLocations(Supplier<VCloudSession> cache,
|
||||
VCloudClient client) {
|
||||
Set<? extends Location> provideLocations(Supplier<VCloudSession> cache, VCloudClient client) {
|
||||
Location provider = new LocationImpl(LocationScope.PROVIDER, providerName, providerName, null);
|
||||
Map<String, Location> locations = Maps.newLinkedHashMap();
|
||||
Set<Location> locations = Sets.newLinkedHashSet();
|
||||
|
||||
for (NamedResource org : cache.get().getOrgs().values()) {
|
||||
Location orgL = new LocationImpl(LocationScope.REGION, org.getId(), org.getName(),
|
||||
provider);
|
||||
for (NamedResource vdc : client.getOrganization(org.getId()).getVDCs().values()) {
|
||||
locations.put(vdc.getId(), new LocationImpl(LocationScope.ZONE, vdc.getId(), vdc
|
||||
.getName(), orgL));
|
||||
locations.add(new LocationImpl(LocationScope.ZONE, vdc.getId(), vdc.getName(), orgL));
|
||||
}
|
||||
}
|
||||
return locations;
|
||||
|
@ -387,14 +394,22 @@ public class VCloudComputeServiceContextModule extends VCloudContextModule {
|
|||
|
||||
@Provides
|
||||
@Singleton
|
||||
Location getVDC(VCloudClient client, Map<String, ? extends Location> locations) {
|
||||
return locations.get(client.getDefaultVDC().getId());
|
||||
Location getVDC(VCloudClient client, Set<? extends Location> locations) {
|
||||
final String vdc = client.getDefaultVDC().getId();
|
||||
return Iterables.find(locations, new Predicate<Location>() {
|
||||
|
||||
@Override
|
||||
public boolean apply(Location input) {
|
||||
return input.getId().equals(vdc);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
protected Map<String, ? extends Size> provideSizes(Function<ComputeMetadata, String> indexer,
|
||||
VCloudClient client, Map<String, ? extends Image> images, LogHolder holder,
|
||||
protected Set<? extends Size> provideSizes(Function<ComputeMetadata, String> indexer,
|
||||
VCloudClient client, Set<? extends Image> images, LogHolder holder,
|
||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor)
|
||||
throws InterruptedException, TimeoutException, ExecutionException {
|
||||
Set<Size> sizes = Sets.newHashSet();
|
||||
|
@ -403,6 +418,42 @@ public class VCloudComputeServiceContextModule extends VCloudContextModule {
|
|||
sizes.add(new SizeImpl(String.format("cpu=%d,ram=%s,disk=%d", cpus, ram, 10), null,
|
||||
null, null, ImmutableMap.<String, String> of(), cpus, ram, 10, ImmutableSet
|
||||
.<Architecture> of(Architecture.X86_32, Architecture.X86_64)));
|
||||
return Maps.uniqueIndex(sizes, indexer);
|
||||
return sizes;
|
||||
}
|
||||
|
||||
public static class FindLocationForResourceInVDC {
|
||||
|
||||
@Resource
|
||||
protected Logger logger = Logger.NULL;
|
||||
|
||||
final Set<? extends Location> locations;
|
||||
final Location defaultLocation;
|
||||
|
||||
@Inject
|
||||
public FindLocationForResourceInVDC(Set<? extends Location> locations,
|
||||
Location defaultLocation) {
|
||||
this.locations = locations;
|
||||
this.defaultLocation = defaultLocation;
|
||||
}
|
||||
|
||||
public Location apply(final NamedResource resource, final String vdcId) {
|
||||
Location location = null;
|
||||
try {
|
||||
location = Iterables.find(locations, new Predicate<Location>() {
|
||||
|
||||
@Override
|
||||
public boolean apply(Location input) {
|
||||
return input.getId().equals(vdcId);
|
||||
}
|
||||
|
||||
});
|
||||
} catch (NoSuchElementException e) {
|
||||
logger.error("unknown vdc %s for %s %s; not in %s", vdcId, resource.getType(), resource
|
||||
.getId(), locations);
|
||||
location = new LocationImpl(LocationScope.ZONE, vdcId, vdcId, defaultLocation
|
||||
.getParent());
|
||||
}
|
||||
return location;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,24 +21,33 @@ package org.jclouds.vcloud.compute.functions;
|
|||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.compute.domain.Image;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.NodeState;
|
||||
import org.jclouds.compute.domain.internal.NodeMetadataImpl;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.vcloud.VCloudClient;
|
||||
import org.jclouds.vcloud.compute.BaseVCloudComputeClient;
|
||||
import org.jclouds.vcloud.compute.VCloudComputeClient;
|
||||
import org.jclouds.vcloud.compute.config.VCloudComputeServiceContextModule.FindLocationForResourceInVDC;
|
||||
import org.jclouds.vcloud.domain.VApp;
|
||||
import org.jclouds.vcloud.domain.VAppStatus;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
/**
|
||||
* Configures the {@link VCloudComputeServiceContext}; requires {@link BaseVCloudComputeClient}
|
||||
|
@ -48,28 +57,31 @@ import com.google.common.collect.ImmutableMap;
|
|||
*/
|
||||
@Singleton
|
||||
public class VCloudGetNodeMetadata {
|
||||
|
||||
@Resource
|
||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||
public Logger logger = Logger.NULL;
|
||||
protected final VCloudClient client;
|
||||
protected final VCloudComputeClient computeClient;
|
||||
protected final Map<String, ? extends Image> images;
|
||||
protected final Map<String, ? extends Location> locations;
|
||||
protected final Set<? extends Image> images;
|
||||
protected final FindLocationForResourceInVDC findLocationForResourceInVDC;
|
||||
protected final GetExtra getExtra;
|
||||
protected final Map<VAppStatus, NodeState> vAppStatusToNodeState;
|
||||
|
||||
// hex [][][] are templateId, last two are instanceId
|
||||
public static final Pattern TAG_PATTERN_WITH_TEMPLATE = Pattern
|
||||
.compile("([^-]+)-([0-9a-f][0-9a-f][0-9a-f])[0-9a-f]+");
|
||||
.compile("([^-]+)-?([0-9a-f][0-9a-f][0-9a-f])[0-9a-f]+");
|
||||
|
||||
public static final Pattern TAG_PATTERN_WITHOUT_TEMPLATE = Pattern.compile("([^-]+)-[0-9]+");
|
||||
public static final Pattern TAG_PATTERN_WITHOUT_TEMPLATE = Pattern.compile("([^-]+)-?[0-9]+");
|
||||
|
||||
@Inject
|
||||
protected VCloudGetNodeMetadata(VCloudClient client, VCloudComputeClient computeClient,
|
||||
Map<VAppStatus, NodeState> vAppStatusToNodeState, GetExtra getExtra,
|
||||
Map<String, ? extends Location> locations, Map<String, ? extends Image> images) {
|
||||
FindLocationForResourceInVDC findLocationForResourceInVDC, Set<? extends Image> images) {
|
||||
this.client = checkNotNull(client, "client");
|
||||
this.images = checkNotNull(images, "images");
|
||||
this.getExtra = checkNotNull(getExtra, "getExtra");
|
||||
this.locations = checkNotNull(locations, "locations");
|
||||
this.findLocationForResourceInVDC = checkNotNull(findLocationForResourceInVDC,
|
||||
"findLocationForResourceInVDC");
|
||||
this.computeClient = checkNotNull(computeClient, "computeClient");
|
||||
this.vAppStatusToNodeState = checkNotNull(vAppStatusToNodeState, "vAppStatusToNodeState");
|
||||
}
|
||||
|
@ -80,11 +92,26 @@ public class VCloudGetNodeMetadata {
|
|||
String tag = null;
|
||||
Image image = null;
|
||||
Matcher matcher = TAG_PATTERN_WITH_TEMPLATE.matcher(vApp.getName());
|
||||
|
||||
final Location location = findLocationForResourceInVDC.apply(vApp, vDCId);
|
||||
if (matcher.find()) {
|
||||
tag = matcher.group(1);
|
||||
String templateIdInHexWithoutLeadingZeros = matcher.group(2).replaceAll("^[0]+", "");
|
||||
String templateId = Integer.parseInt(templateIdInHexWithoutLeadingZeros, 16) + "";
|
||||
image = images.get(templateId);
|
||||
final String templateId = Integer.parseInt(templateIdInHexWithoutLeadingZeros, 16) + "";
|
||||
try {
|
||||
image = Iterables.find(images, new Predicate<Image>() {
|
||||
|
||||
@Override
|
||||
public boolean apply(Image input) {
|
||||
return input.getId().equals(templateId) && input.getLocation().equals(location);
|
||||
}
|
||||
|
||||
});
|
||||
} catch (NoSuchElementException e) {
|
||||
logger.warn(
|
||||
"could not find a matching image for vapp %s; vapptemplate %s in location %s",
|
||||
vApp, templateId, location);
|
||||
}
|
||||
} else {
|
||||
matcher = TAG_PATTERN_WITHOUT_TEMPLATE.matcher(vApp.getName());
|
||||
if (matcher.find()) {
|
||||
|
@ -93,9 +120,9 @@ public class VCloudGetNodeMetadata {
|
|||
tag = "NOTAG-" + vApp.getName();
|
||||
}
|
||||
}
|
||||
return new NodeMetadataImpl(vApp.getId(), vApp.getName(), locations.get(vDCId), vApp
|
||||
.getLocation(), ImmutableMap.<String, String> of(), tag, image,
|
||||
vAppStatusToNodeState.get(vApp.getStatus()), computeClient.getPublicAddresses(id),
|
||||
computeClient.getPrivateAddresses(id), getExtra.apply(vApp), null);
|
||||
return new NodeMetadataImpl(vApp.getId(), vApp.getName(), location, vApp.getLocation(),
|
||||
ImmutableMap.<String, String> of(), tag, image, vAppStatusToNodeState.get(vApp
|
||||
.getStatus()), computeClient.getPublicAddresses(id), computeClient
|
||||
.getPrivateAddresses(id), getExtra.apply(vApp), null);
|
||||
}
|
||||
}
|
|
@ -42,12 +42,15 @@ import com.google.common.base.Strings;
|
|||
public class EncodeTemplateIdIntoNameRunNodesAndAddToSetStrategy extends
|
||||
EncodeTagIntoNameRunNodesAndAddToSetStrategy {
|
||||
|
||||
private final SecureRandom random;
|
||||
|
||||
@Inject
|
||||
protected EncodeTemplateIdIntoNameRunNodesAndAddToSetStrategy(
|
||||
AddNodeWithTagStrategy addNodeWithTagStrategy, ListNodesStrategy listNodesStrategy,
|
||||
@Named("NAMING_CONVENTION") String nodeNamingConvention, ComputeUtils utils,
|
||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) {
|
||||
super(addNodeWithTagStrategy, listNodesStrategy, nodeNamingConvention, utils, executor);
|
||||
this.random = new SecureRandom();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -59,6 +62,6 @@ public class EncodeTemplateIdIntoNameRunNodesAndAddToSetStrategy extends
|
|||
protected String getNextName(final String tag, final Template template) {
|
||||
return String.format(nodeNamingConvention, tag, Strings.padStart(Integer.toHexString(Integer
|
||||
.parseInt(template.getImage().getId())), 3, '0'), Strings.padStart(Integer
|
||||
.toHexString(new SecureRandom().nextInt(255)), 2, '0'));
|
||||
.toHexString(random.nextInt(255)), 2, '0'));
|
||||
}
|
||||
}
|
|
@ -3,8 +3,6 @@ package org.jclouds.vcloud.compute;
|
|||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.jclouds.compute.BaseComputeServiceLiveTest;
|
||||
import org.jclouds.compute.ComputeServiceContextFactory;
|
||||
import org.jclouds.compute.domain.ComputeMetadata;
|
||||
|
@ -46,12 +44,11 @@ public class VCloudComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
|||
|
||||
@Override
|
||||
public void testListNodes() throws Exception {
|
||||
for (Entry<String, ? extends ComputeMetadata> node : client.getNodes().entrySet()) {
|
||||
assertEquals(node.getKey(), node.getValue().getId());
|
||||
assert node.getValue().getId() != null;
|
||||
assert node.getValue().getLocation() != null;
|
||||
assertEquals(node.getValue().getType(), ComputeType.NODE);
|
||||
NodeMetadata allData = client.getNodeMetadata(node.getValue());
|
||||
for (ComputeMetadata node : client.listNodes()) {
|
||||
assert node.getId() != null;
|
||||
assert node.getLocation() != null;
|
||||
assertEquals(node.getType(), ComputeType.NODE);
|
||||
NodeMetadata allData = client.getNodeMetadata(node);
|
||||
assert allData.getExtra().get("processor/count") != null;
|
||||
assert allData.getExtra().get("disk_drive/1/kb") != null;
|
||||
assert allData.getExtra().get("memory/mb") != null;
|
||||
|
|
|
@ -37,8 +37,11 @@ import org.jclouds.compute.domain.ComputeMetadata;
|
|||
import org.jclouds.compute.domain.Image;
|
||||
import org.jclouds.compute.domain.NodeState;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.domain.LocationScope;
|
||||
import org.jclouds.domain.internal.LocationImpl;
|
||||
import org.jclouds.vcloud.VCloudClient;
|
||||
import org.jclouds.vcloud.compute.VCloudComputeClient;
|
||||
import org.jclouds.vcloud.compute.config.VCloudComputeServiceContextModule.FindLocationForResourceInVDC;
|
||||
import org.jclouds.vcloud.compute.config.VCloudComputeServiceContextModule.VCloudListNodesStrategy;
|
||||
import org.jclouds.vcloud.compute.functions.GetExtra;
|
||||
import org.jclouds.vcloud.domain.NamedResource;
|
||||
|
@ -52,7 +55,7 @@ import org.jclouds.vcloud.domain.internal.VAppImpl;
|
|||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableListMultimap;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.ImmutableSortedSet;
|
||||
import com.google.common.collect.ListMultimap;
|
||||
import com.google.common.collect.Maps;
|
||||
|
@ -112,10 +115,14 @@ public class VCloudComputeServiceContextModuleTest {
|
|||
replay(client);
|
||||
replay(computeClient);
|
||||
|
||||
Map<String, ? extends Location> locations = ImmutableMap.of();
|
||||
Map<String, ? extends Image> images= ImmutableMap.of();
|
||||
Location vdcL = new LocationImpl(LocationScope.ZONE, "1", "1", null);
|
||||
Set<? extends Location> locations = ImmutableSet.of(vdcL);
|
||||
|
||||
Set<? extends Image> images = ImmutableSet.of();
|
||||
FindLocationForResourceInVDC findLocationForResourceInVDC = new FindLocationForResourceInVDC(
|
||||
locations, null);
|
||||
VCloudListNodesStrategy strategy = new VCloudListNodesStrategy(client, computeClient,
|
||||
vAppStatusToNodeState, getExtra, locations, images);
|
||||
vAppStatusToNodeState, getExtra, findLocationForResourceInVDC, images);
|
||||
|
||||
Set<ComputeMetadata> nodes = Sets.newHashSet();
|
||||
NamedResource vdc = new NamedResourceImpl("1", null, null, null);
|
||||
|
|
|
@ -113,9 +113,9 @@ public class TerremarkVCloudComputeServiceContextModule extends VCloudComputeSer
|
|||
* query the catalog.
|
||||
*/
|
||||
@Override
|
||||
protected Map<String, ? extends Image> provideImages(final VCloudClient client,
|
||||
protected Set<? extends Image> provideImages(final VCloudClient client,
|
||||
final PopulateDefaultLoginCredentialsForImageStrategy credentialsProvider,
|
||||
final Map<String, ? extends Location> locations, LogHolder holder,
|
||||
LogHolder holder, final FindLocationForResourceInVDC findLocationForResourceInVDC,
|
||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor,
|
||||
Function<ComputeMetadata, String> indexer) throws InterruptedException,
|
||||
ExecutionException, TimeoutException {
|
||||
|
@ -145,11 +145,15 @@ public class TerremarkVCloudComputeServiceContextModule extends VCloudComputeSer
|
|||
: Architecture.X86_64;
|
||||
VAppTemplate template = client.getVAppTemplate(item.getEntity()
|
||||
.getId());
|
||||
|
||||
Location location = findLocationForResourceInVDC.apply(resource, vDC
|
||||
.getId());
|
||||
|
||||
images.add(new ImageImpl(resource.getId(), template.getName(),
|
||||
locations.get(vDC.getId()), template.getLocation(),
|
||||
ImmutableMap.<String, String> of(), template
|
||||
.getDescription(), "", myOs, template.getName(),
|
||||
arch, credentialsProvider.execute(template)));
|
||||
location, template.getLocation(), ImmutableMap
|
||||
.<String, String> of(), template.getDescription(),
|
||||
"", myOs, template.getName(), arch, credentialsProvider
|
||||
.execute(template)));
|
||||
return null;
|
||||
}
|
||||
}), executor));
|
||||
|
@ -158,20 +162,19 @@ public class TerremarkVCloudComputeServiceContextModule extends VCloudComputeSer
|
|||
}
|
||||
ConcurrentUtils.awaitCompletion(responses, executor, null, holder.logger, "vAppTemplates in "
|
||||
+ vDC);
|
||||
return Maps.uniqueIndex(images, indexer);
|
||||
return images;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<String, ? extends Size> provideSizes(Function<ComputeMetadata, String> indexer,
|
||||
VCloudClient client, Map<String, ? extends Image> images, LogHolder holder,
|
||||
protected Set<? extends Size> provideSizes(Function<ComputeMetadata, String> indexer,
|
||||
VCloudClient client, Set<? extends Image> images, LogHolder holder,
|
||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor)
|
||||
throws InterruptedException, TimeoutException, ExecutionException {
|
||||
Image anyImage = Iterables.get(images.values(), 0);
|
||||
Image anyImage = Iterables.get(images, 0);
|
||||
holder.logger.debug(">> providing sizes");
|
||||
SortedSet<Size> sizes = Sets.newTreeSet(Iterables.transform(TerremarkVCloudClient.class.cast(
|
||||
client).getComputeOptionsOfCatalogItem(anyImage.getId()), sizeConverter));
|
||||
holder.logger.debug("<< sizes(%d)", sizes.size());
|
||||
return Maps.uniqueIndex(sizes, indexer);
|
||||
return sizes;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -21,8 +21,6 @@ package org.jclouds.vcloud.terremark.compute;
|
|||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.jclouds.compute.ComputeServiceContextFactory;
|
||||
import org.jclouds.compute.domain.Architecture;
|
||||
import org.jclouds.compute.domain.ComputeType;
|
||||
|
@ -78,14 +76,13 @@ public class TerremarkVCloudComputeServiceLiveTest extends VCloudComputeServiceL
|
|||
|
||||
@Override
|
||||
public void testListImages() throws Exception {
|
||||
for (Entry<String, ? extends Image> image : client.getImages().entrySet()) {
|
||||
assertEquals(image.getKey(), image.getValue().getId());
|
||||
assert image.getValue().getId() != null : image;
|
||||
// image.getValue().getLocationId() can be null, if it is a location-free image
|
||||
assertEquals(image.getValue().getType(), ComputeType.IMAGE);
|
||||
assert image.getValue().getDefaultCredentials().account != null : image;
|
||||
if (image.getValue().getOsFamily() != OsFamily.WINDOWS)
|
||||
assert image.getValue().getDefaultCredentials().key != null : image;
|
||||
for (Image image : client.listImages()) {
|
||||
assert image.getId() != null : image;
|
||||
// image.getLocationId() can be null, if it is a location-free image
|
||||
assertEquals(image.getType(), ComputeType.IMAGE);
|
||||
assert image.getDefaultCredentials().account != null : image;
|
||||
if (image.getOsFamily() != OsFamily.WINDOWS)
|
||||
assert image.getDefaultCredentials().key != null : image;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue