mirror of https://github.com/apache/jclouds.git
Issue 204: add template description, Issue 162: update to correct image and location details
This commit is contained in:
parent
b36d68417c
commit
79c54e9f45
|
@ -40,6 +40,11 @@ public interface Image extends ComputeMetadata {
|
||||||
*/
|
*/
|
||||||
String getVersion();
|
String getVersion();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of the image.
|
||||||
|
*/
|
||||||
|
String getDescription();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Operating System
|
* Operating System
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -98,15 +98,20 @@ public interface TemplateBuilder {
|
||||||
*/
|
*/
|
||||||
TemplateBuilder osDescriptionMatches(String osDescriptionRegex);
|
TemplateBuilder osDescriptionMatches(String osDescriptionRegex);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configure this template to have an image name that matches the regular expression
|
||||||
|
*/
|
||||||
|
TemplateBuilder imageNameMatches(String imageNameRegex);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configure this template to have an image version that matches the regular expression
|
* Configure this template to have an image version that matches the regular expression
|
||||||
*/
|
*/
|
||||||
TemplateBuilder imageVersionMatches(String imageVersionRegex);
|
TemplateBuilder imageVersionMatches(String imageVersionRegex);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configure this template to have a description that matches the regular expression
|
* Configure this template to have an image description that matches the regular expression
|
||||||
*/
|
*/
|
||||||
TemplateBuilder imageDescriptionMatches(String descriptionRegex);
|
TemplateBuilder imageDescriptionMatches(String imageDescriptionRegex);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configure this template to require the minimum cores below
|
* Configure this template to require the minimum cores below
|
||||||
|
|
|
@ -44,6 +44,7 @@ public class ImageImpl extends ComputeMetadataImpl implements Image {
|
||||||
private static final long serialVersionUID = 7856744554191025307L;
|
private static final long serialVersionUID = 7856744554191025307L;
|
||||||
|
|
||||||
private final String version;
|
private final String version;
|
||||||
|
private final String description;
|
||||||
private final OsFamily osFamily;
|
private final OsFamily osFamily;
|
||||||
private final String osDescription;
|
private final String osDescription;
|
||||||
private final Architecture architecture;
|
private final Architecture architecture;
|
||||||
|
@ -54,6 +55,7 @@ public class ImageImpl extends ComputeMetadataImpl implements Image {
|
||||||
super(ComputeType.IMAGE, id, name, locationId, uri, userMetadata);
|
super(ComputeType.IMAGE, id, name, locationId, uri, userMetadata);
|
||||||
this.version = checkNotNull(version, "version");
|
this.version = checkNotNull(version, "version");
|
||||||
this.osFamily = osFamily;
|
this.osFamily = osFamily;
|
||||||
|
this.description = checkNotNull(description, "description");
|
||||||
this.osDescription = checkNotNull(osDescription, "osDescription");
|
this.osDescription = checkNotNull(osDescription, "osDescription");
|
||||||
this.architecture = checkNotNull(architecture, "architecture");
|
this.architecture = checkNotNull(architecture, "architecture");
|
||||||
}
|
}
|
||||||
|
@ -66,6 +68,14 @@ public class ImageImpl extends ComputeMetadataImpl implements Image {
|
||||||
return version;
|
return version;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
|
@ -93,8 +103,9 @@ public class ImageImpl extends ComputeMetadataImpl implements Image {
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "[id=" + getId() + ", name=" + getName() + ", locationId=" + getLocationId()
|
return "[id=" + getId() + ", name=" + getName() + ", locationId=" + getLocationId()
|
||||||
+ ", architecture=" + architecture + ", osDescription=" + osDescription
|
+ ", architecture=" + architecture + ", description=" + description
|
||||||
+ ", osFamily=" + osFamily + ", version=" + version + "]";
|
+ ", osDescription=" + osDescription + ", osFamily=" + osFamily + ", version="
|
||||||
|
+ version + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -102,6 +113,7 @@ public class ImageImpl extends ComputeMetadataImpl implements Image {
|
||||||
final int prime = 31;
|
final int prime = 31;
|
||||||
int result = super.hashCode();
|
int result = super.hashCode();
|
||||||
result = prime * result + ((architecture == null) ? 0 : architecture.hashCode());
|
result = prime * result + ((architecture == null) ? 0 : architecture.hashCode());
|
||||||
|
result = prime * result + ((description == null) ? 0 : description.hashCode());
|
||||||
result = prime * result + ((osDescription == null) ? 0 : osDescription.hashCode());
|
result = prime * result + ((osDescription == null) ? 0 : osDescription.hashCode());
|
||||||
result = prime * result + ((osFamily == null) ? 0 : osFamily.hashCode());
|
result = prime * result + ((osFamily == null) ? 0 : osFamily.hashCode());
|
||||||
result = prime * result + ((version == null) ? 0 : version.hashCode());
|
result = prime * result + ((version == null) ? 0 : version.hashCode());
|
||||||
|
@ -122,6 +134,11 @@ public class ImageImpl extends ComputeMetadataImpl implements Image {
|
||||||
return false;
|
return false;
|
||||||
} else if (!architecture.equals(other.architecture))
|
} else if (!architecture.equals(other.architecture))
|
||||||
return false;
|
return false;
|
||||||
|
if (description == null) {
|
||||||
|
if (other.description != null)
|
||||||
|
return false;
|
||||||
|
} else if (!description.equals(other.description))
|
||||||
|
return false;
|
||||||
if (osDescription == null) {
|
if (osDescription == null) {
|
||||||
if (other.osDescription != null)
|
if (other.osDescription != null)
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -53,6 +53,7 @@ public class TemplateBuilderImpl implements TemplateBuilder {
|
||||||
private String osDescription;
|
private String osDescription;
|
||||||
private String imageVersion;
|
private String imageVersion;
|
||||||
private String imageName;
|
private String imageName;
|
||||||
|
private String imageDescription;
|
||||||
|
|
||||||
private double minCores;
|
private double minCores;
|
||||||
private int minRam;
|
private int minRam;
|
||||||
|
@ -127,8 +128,11 @@ public class TemplateBuilderImpl implements TemplateBuilder {
|
||||||
if (input.getOsDescription() == null)
|
if (input.getOsDescription() == null)
|
||||||
returnVal = false;
|
returnVal = false;
|
||||||
else
|
else
|
||||||
returnVal = input.getOsDescription().contains(osDescription) ||
|
returnVal = input.getOsDescription().contains(osDescription)
|
||||||
input.getOsDescription().matches(osDescription); /*note: matches() expects a regex!*/
|
|| input.getOsDescription().matches(osDescription); /*
|
||||||
|
* note: matches()
|
||||||
|
* expects a regex!
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
return returnVal;
|
return returnVal;
|
||||||
}
|
}
|
||||||
|
@ -159,7 +163,19 @@ public class TemplateBuilderImpl implements TemplateBuilder {
|
||||||
return returnVal;
|
return returnVal;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
private final Predicate<Image> imageDescriptionPredicate = new Predicate<Image>() {
|
||||||
|
@Override
|
||||||
|
public boolean apply(Image input) {
|
||||||
|
boolean returnVal = true;
|
||||||
|
if (imageDescription != null) {
|
||||||
|
if (input.getName() == null)
|
||||||
|
returnVal = false;
|
||||||
|
else
|
||||||
|
returnVal = input.getName().matches(imageDescription);
|
||||||
|
}
|
||||||
|
return returnVal;
|
||||||
|
}
|
||||||
|
};
|
||||||
private final Predicate<Size> sizeIdPredicate = new Predicate<Size>() {
|
private final Predicate<Size> sizeIdPredicate = new Predicate<Size>() {
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Size input) {
|
public boolean apply(Size input) {
|
||||||
|
@ -177,7 +193,7 @@ public class TemplateBuilderImpl implements TemplateBuilder {
|
||||||
|
|
||||||
private final Predicate<Image> imagePredicate = Predicates.and(idPredicate, locationPredicate,
|
private final Predicate<Image> imagePredicate = Predicates.and(idPredicate, locationPredicate,
|
||||||
osPredicate, imageArchPredicate, osDescriptionPredicate, imageVersionPredicate,
|
osPredicate, imageArchPredicate, osDescriptionPredicate, imageVersionPredicate,
|
||||||
imageNamePredicate);
|
imageNamePredicate, imageDescriptionPredicate);
|
||||||
|
|
||||||
private final Predicate<Size> sizeArchPredicate = new Predicate<Size>() {
|
private final Predicate<Size> sizeArchPredicate = new Predicate<Size>() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -221,9 +237,10 @@ public class TemplateBuilderImpl implements TemplateBuilder {
|
||||||
return ComparisonChain.start().compare(left.getName(), right.getName(),
|
return ComparisonChain.start().compare(left.getName(), right.getName(),
|
||||||
Ordering.<String> natural().nullsLast()).compare(left.getVersion(),
|
Ordering.<String> natural().nullsLast()).compare(left.getVersion(),
|
||||||
right.getVersion(), Ordering.<String> natural().nullsLast()).compare(
|
right.getVersion(), Ordering.<String> natural().nullsLast()).compare(
|
||||||
left.getOsDescription(), right.getOsDescription(),
|
left.getDescription(), right.getDescription(),
|
||||||
Ordering.<String> natural().nullsLast()).compare(left.getArchitecture(),
|
Ordering.<String> natural().nullsLast()).compare(left.getOsDescription(),
|
||||||
right.getArchitecture()).result();
|
right.getOsDescription(), Ordering.<String> natural().nullsLast()).compare(
|
||||||
|
left.getArchitecture(), right.getArchitecture()).result();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -258,6 +275,10 @@ public class TemplateBuilderImpl implements TemplateBuilder {
|
||||||
this.locationId = image.getLocationId();
|
this.locationId = image.getLocationId();
|
||||||
if (image.getOsFamily() != null)
|
if (image.getOsFamily() != null)
|
||||||
this.os = image.getOsFamily();
|
this.os = image.getOsFamily();
|
||||||
|
if (image.getName() != null)
|
||||||
|
this.imageName = image.getName();
|
||||||
|
if (image.getDescription() != null)
|
||||||
|
this.imageDescription = image.getDescription();
|
||||||
if (image.getOsDescription() != null)
|
if (image.getOsDescription() != null)
|
||||||
this.osDescription = image.getOsDescription();
|
this.osDescription = image.getOsDescription();
|
||||||
if (image.getVersion() != null)
|
if (image.getVersion() != null)
|
||||||
|
@ -365,12 +386,21 @@ public class TemplateBuilderImpl implements TemplateBuilder {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public TemplateBuilder imageNameMatches(String nameRegex) {
|
||||||
|
this.imageName = nameRegex;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public TemplateBuilder imageDescriptionMatches(String descriptionRegex) {
|
public TemplateBuilder imageDescriptionMatches(String descriptionRegex) {
|
||||||
this.imageName = descriptionRegex;
|
this.imageDescription = descriptionRegex;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -430,11 +460,11 @@ public class TemplateBuilderImpl implements TemplateBuilder {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "[arch=" + arch + ", biggest=" + biggest + ", fastest=" + fastest
|
return "[arch=" + arch + ", biggest=" + biggest + ", fastest=" + fastest + ", imageName="
|
||||||
+ ", imageDescription=" + imageName + ", imageId=" + imageId + ", imageVersion="
|
+ imageName + ", imageDescription=" + imageDescription + ", imageId=" + imageId
|
||||||
+ imageVersion + ", location=" + locationId + ", minCores=" + minCores + ", minRam="
|
+ ", imageVersion=" + imageVersion + ", location=" + locationId + ", minCores="
|
||||||
+ minRam + ", os=" + os + ", osDescription=" + osDescription + ", sizeId=" + sizeId
|
+ minCores + ", minRam=" + minRam + ", os=" + os + ", osDescription="
|
||||||
+ "]";
|
+ osDescription + ", sizeId=" + sizeId + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,39 +18,8 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.gogrid.config;
|
package org.jclouds.gogrid.config;
|
||||||
|
|
||||||
import com.google.common.base.*;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import com.google.common.collect.*;
|
|
||||||
import com.google.inject.Provides;
|
|
||||||
import com.google.inject.TypeLiteral;
|
|
||||||
import org.jclouds.compute.ComputeService;
|
|
||||||
import org.jclouds.compute.ComputeServiceContext;
|
|
||||||
import org.jclouds.compute.domain.*;
|
|
||||||
import org.jclouds.compute.domain.internal.ImageImpl;
|
|
||||||
import org.jclouds.compute.domain.internal.NodeMetadataImpl;
|
|
||||||
import org.jclouds.compute.domain.internal.SizeImpl;
|
|
||||||
import org.jclouds.compute.internal.ComputeServiceContextImpl;
|
|
||||||
import org.jclouds.compute.predicates.RunScriptRunning;
|
|
||||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
|
||||||
import org.jclouds.compute.strategy.*;
|
|
||||||
import org.jclouds.domain.Credentials;
|
|
||||||
import org.jclouds.domain.Location;
|
|
||||||
import org.jclouds.domain.LocationScope;
|
|
||||||
import org.jclouds.domain.internal.LocationImpl;
|
|
||||||
import org.jclouds.gogrid.GoGridAsyncClient;
|
|
||||||
import org.jclouds.gogrid.GoGridClient;
|
|
||||||
import org.jclouds.gogrid.domain.*;
|
|
||||||
import org.jclouds.gogrid.options.GetIpListOptions;
|
|
||||||
import org.jclouds.gogrid.predicates.ServerLatestJobCompleted;
|
|
||||||
import org.jclouds.gogrid.util.GoGridUtils;
|
|
||||||
import org.jclouds.logging.Logger;
|
|
||||||
import org.jclouds.predicates.RetryablePredicate;
|
|
||||||
import org.jclouds.rest.RestContext;
|
|
||||||
import org.jclouds.ssh.SshClient;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import javax.inject.Named;
|
|
||||||
import javax.inject.Singleton;
|
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
|
@ -59,397 +28,430 @@ import java.util.Set;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import javax.annotation.Resource;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Named;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import org.jclouds.compute.ComputeService;
|
||||||
|
import org.jclouds.compute.ComputeServiceContext;
|
||||||
|
import org.jclouds.compute.domain.Architecture;
|
||||||
|
import org.jclouds.compute.domain.ComputeMetadata;
|
||||||
|
import org.jclouds.compute.domain.Image;
|
||||||
|
import org.jclouds.compute.domain.NodeMetadata;
|
||||||
|
import org.jclouds.compute.domain.NodeState;
|
||||||
|
import org.jclouds.compute.domain.OsFamily;
|
||||||
|
import org.jclouds.compute.domain.Size;
|
||||||
|
import org.jclouds.compute.domain.Template;
|
||||||
|
import org.jclouds.compute.domain.internal.ImageImpl;
|
||||||
|
import org.jclouds.compute.domain.internal.NodeMetadataImpl;
|
||||||
|
import org.jclouds.compute.domain.internal.SizeImpl;
|
||||||
|
import org.jclouds.compute.internal.ComputeServiceContextImpl;
|
||||||
|
import org.jclouds.compute.predicates.RunScriptRunning;
|
||||||
|
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||||
|
import org.jclouds.compute.strategy.AddNodeWithTagStrategy;
|
||||||
|
import org.jclouds.compute.strategy.DestroyNodeStrategy;
|
||||||
|
import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
|
||||||
|
import org.jclouds.compute.strategy.ListNodesStrategy;
|
||||||
|
import org.jclouds.compute.strategy.RebootNodeStrategy;
|
||||||
|
import org.jclouds.domain.Credentials;
|
||||||
|
import org.jclouds.domain.Location;
|
||||||
|
import org.jclouds.domain.LocationScope;
|
||||||
|
import org.jclouds.domain.internal.LocationImpl;
|
||||||
|
import org.jclouds.gogrid.GoGridAsyncClient;
|
||||||
|
import org.jclouds.gogrid.GoGridClient;
|
||||||
|
import org.jclouds.gogrid.domain.Ip;
|
||||||
|
import org.jclouds.gogrid.domain.IpType;
|
||||||
|
import org.jclouds.gogrid.domain.PowerCommand;
|
||||||
|
import org.jclouds.gogrid.domain.Server;
|
||||||
|
import org.jclouds.gogrid.domain.ServerImage;
|
||||||
|
import org.jclouds.gogrid.options.GetIpListOptions;
|
||||||
|
import org.jclouds.gogrid.predicates.ServerLatestJobCompleted;
|
||||||
|
import org.jclouds.gogrid.util.GoGridUtils;
|
||||||
|
import org.jclouds.logging.Logger;
|
||||||
|
import org.jclouds.predicates.RetryablePredicate;
|
||||||
|
import org.jclouds.rest.RestContext;
|
||||||
|
import org.jclouds.ssh.SshClient;
|
||||||
|
|
||||||
|
import com.google.common.base.CharMatcher;
|
||||||
|
import com.google.common.base.Function;
|
||||||
|
import com.google.common.base.Predicate;
|
||||||
|
import com.google.common.base.Predicates;
|
||||||
|
import com.google.common.base.Throwables;
|
||||||
|
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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Oleksiy Yarmula
|
* @author Oleksiy Yarmula
|
||||||
*/
|
*/
|
||||||
public class GoGridComputeServiceContextModule extends GoGridContextModule {
|
public class GoGridComputeServiceContextModule extends GoGridContextModule {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
super.configure();
|
super.configure();
|
||||||
bind(new TypeLiteral<Function<Server, NodeMetadata>>() {
|
bind(new TypeLiteral<Function<Server, NodeMetadata>>() {
|
||||||
}).to(ServerToNodeMetadata.class);
|
}).to(ServerToNodeMetadata.class);
|
||||||
bind(AddNodeWithTagStrategy.class).to(GoGridAddNodeWithTagStrategy.class);
|
bind(AddNodeWithTagStrategy.class).to(GoGridAddNodeWithTagStrategy.class);
|
||||||
bind(ListNodesStrategy.class).to(GoGridListNodesStrategy.class);
|
bind(ListNodesStrategy.class).to(GoGridListNodesStrategy.class);
|
||||||
bind(GetNodeMetadataStrategy.class).to(GoGridGetNodeMetadataStrategy.class);
|
bind(GetNodeMetadataStrategy.class).to(GoGridGetNodeMetadataStrategy.class);
|
||||||
bind(RebootNodeStrategy.class).to(GoGridRebootNodeStrategy.class);
|
bind(RebootNodeStrategy.class).to(GoGridRebootNodeStrategy.class);
|
||||||
bind(DestroyNodeStrategy.class).to(GoGridDestroyNodeStrategy.class);
|
bind(DestroyNodeStrategy.class).to(GoGridDestroyNodeStrategy.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Named("NAMING_CONVENTION")
|
@Named("NAMING_CONVENTION")
|
||||||
@Singleton
|
@Singleton
|
||||||
String provideNamingConvention() {
|
String provideNamingConvention() {
|
||||||
return "%s-%d";
|
return "%s-%d";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public static class GoGridAddNodeWithTagStrategy implements AddNodeWithTagStrategy {
|
public static class GoGridAddNodeWithTagStrategy implements AddNodeWithTagStrategy {
|
||||||
private final GoGridClient client;
|
private final GoGridClient client;
|
||||||
private final Function<Size, String> sizeToRam;
|
private final Function<Size, String> sizeToRam;
|
||||||
private final Function<Server, NodeMetadata> serverToNodeMetadata;
|
private final Function<Server, NodeMetadata> serverToNodeMetadata;
|
||||||
private RetryablePredicate<Server> serverLatestJobCompleted;
|
private RetryablePredicate<Server> serverLatestJobCompleted;
|
||||||
private RetryablePredicate<Server> serverLatestJobCompletedShort;
|
private RetryablePredicate<Server> serverLatestJobCompletedShort;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
protected GoGridAddNodeWithTagStrategy(GoGridClient client,
|
protected GoGridAddNodeWithTagStrategy(GoGridClient client,
|
||||||
Function<Server, NodeMetadata> serverToNodeMetadata,
|
Function<Server, NodeMetadata> serverToNodeMetadata, Function<Size, String> sizeToRam) {
|
||||||
Function<Size, String> sizeToRam) {
|
this.client = client;
|
||||||
this.client = client;
|
this.serverToNodeMetadata = serverToNodeMetadata;
|
||||||
this.serverToNodeMetadata = serverToNodeMetadata;
|
this.sizeToRam = sizeToRam;
|
||||||
this.sizeToRam = sizeToRam;
|
this.serverLatestJobCompleted = new RetryablePredicate<Server>(
|
||||||
this.serverLatestJobCompleted = new RetryablePredicate<Server>(
|
new ServerLatestJobCompleted(client.getJobServices()), 800, 20, TimeUnit.SECONDS);
|
||||||
new ServerLatestJobCompleted(client.getJobServices()),
|
this.serverLatestJobCompletedShort = new RetryablePredicate<Server>(
|
||||||
800, 20, TimeUnit.SECONDS);
|
new ServerLatestJobCompleted(client.getJobServices()), 60, 20, TimeUnit.SECONDS);
|
||||||
this.serverLatestJobCompletedShort = new RetryablePredicate<Server>(
|
}
|
||||||
new ServerLatestJobCompleted(client.getJobServices()),
|
|
||||||
60, 20, TimeUnit.SECONDS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NodeMetadata execute(String tag, String name, Template template) {
|
public NodeMetadata execute(String tag, String name, Template template) {
|
||||||
Server addedServer = null;
|
Server addedServer = null;
|
||||||
boolean notStarted = true;
|
boolean notStarted = true;
|
||||||
int numOfRetries = 20;
|
int numOfRetries = 20;
|
||||||
// lock-free consumption of a shared resource: IP address pool
|
// lock-free consumption of a shared resource: IP address pool
|
||||||
while(notStarted) { // TODO: replace with Predicate-based thread collision avoidance for simplicity
|
while (notStarted) { // TODO: replace with Predicate-based thread collision avoidance for
|
||||||
Set<Ip> availableIps =
|
// simplicity
|
||||||
client.getIpServices().getIpList(new GetIpListOptions().onlyUnassigned().onlyWithType(IpType.PUBLIC));
|
Set<Ip> availableIps = client.getIpServices().getIpList(
|
||||||
if(availableIps.size() == 0) throw new RuntimeException("No public IPs available on this account.");
|
new GetIpListOptions().onlyUnassigned().onlyWithType(IpType.PUBLIC));
|
||||||
int ipIndex = new SecureRandom().nextInt(availableIps.size());
|
if (availableIps.size() == 0)
|
||||||
Ip availableIp = Iterables.get(availableIps, ipIndex);
|
throw new RuntimeException("No public IPs available on this account.");
|
||||||
try {
|
int ipIndex = new SecureRandom().nextInt(availableIps.size());
|
||||||
addedServer = client.getServerServices().addServer(name, checkNotNull(template.getImage().getId()),
|
Ip availableIp = Iterables.get(availableIps, ipIndex);
|
||||||
sizeToRam.apply(template.getSize()), availableIp.getIp());
|
|
||||||
notStarted = false;
|
|
||||||
} catch(Exception e) {
|
|
||||||
if(--numOfRetries == 0) Throwables.propagate(e);
|
|
||||||
notStarted = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
serverLatestJobCompleted.apply(addedServer);
|
|
||||||
|
|
||||||
client.getServerServices().power(addedServer.getName(), PowerCommand.START);
|
|
||||||
serverLatestJobCompletedShort.apply(addedServer);
|
|
||||||
|
|
||||||
addedServer = Iterables.getOnlyElement(
|
|
||||||
client.getServerServices().getServersByName(addedServer.getName())
|
|
||||||
);
|
|
||||||
return serverToNodeMetadata.apply(addedServer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Singleton
|
|
||||||
public static class GoGridRebootNodeStrategy implements RebootNodeStrategy {
|
|
||||||
private final GoGridClient client;
|
|
||||||
private RetryablePredicate<Server> serverLatestJobCompleted;
|
|
||||||
private RetryablePredicate<Server> serverLatestJobCompletedShort;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
protected GoGridRebootNodeStrategy(GoGridClient client) {
|
|
||||||
this.client = client;
|
|
||||||
this.serverLatestJobCompleted = new RetryablePredicate<Server>(
|
|
||||||
new ServerLatestJobCompleted(client.getJobServices()),
|
|
||||||
800, 20, TimeUnit.SECONDS);
|
|
||||||
this.serverLatestJobCompletedShort = new RetryablePredicate<Server>(
|
|
||||||
new ServerLatestJobCompleted(client.getJobServices()),
|
|
||||||
60, 20, TimeUnit.SECONDS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean execute(ComputeMetadata node) {
|
|
||||||
Server server =
|
|
||||||
Iterables.getOnlyElement(client.getServerServices().getServersByName(node.getName()));
|
|
||||||
client.getServerServices().power(server.getName(), PowerCommand.RESTART);
|
|
||||||
serverLatestJobCompleted.apply(server);
|
|
||||||
client.getServerServices().power(server.getName(), PowerCommand.START);
|
|
||||||
return serverLatestJobCompletedShort.apply(server);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Singleton
|
|
||||||
public static class GoGridListNodesStrategy implements ListNodesStrategy {
|
|
||||||
private final GoGridClient client;
|
|
||||||
private final Function<Server, NodeMetadata> serverToNodeMetadata;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
protected GoGridListNodesStrategy(GoGridClient client,
|
|
||||||
Function<Server, NodeMetadata> serverToNodeMetadata) {
|
|
||||||
this.client = client;
|
|
||||||
this.serverToNodeMetadata = serverToNodeMetadata;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Iterable<? extends ComputeMetadata> execute() {
|
|
||||||
return Iterables.transform(client.getServerServices().getServerList(), serverToNodeMetadata);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Singleton
|
|
||||||
public static class GoGridGetNodeMetadataStrategy implements GetNodeMetadataStrategy {
|
|
||||||
private final GoGridClient client;
|
|
||||||
private final Function<Server, NodeMetadata> serverToNodeMetadata;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
protected GoGridGetNodeMetadataStrategy(GoGridClient client,
|
|
||||||
Function<Server, NodeMetadata> serverToNodeMetadata) {
|
|
||||||
this.client = client;
|
|
||||||
this.serverToNodeMetadata = serverToNodeMetadata;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public NodeMetadata execute(ComputeMetadata node) {
|
|
||||||
Server server = Iterables.getOnlyElement(
|
|
||||||
client.getServerServices().getServersByName(node.getName())
|
|
||||||
);
|
|
||||||
return server == null ? null : serverToNodeMetadata.apply(server);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Singleton
|
|
||||||
public static class GoGridDestroyNodeStrategy implements DestroyNodeStrategy {
|
|
||||||
private final GoGridClient client;
|
|
||||||
private RetryablePredicate<Server> serverLatestJobCompleted;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
protected GoGridDestroyNodeStrategy(GoGridClient client) {
|
|
||||||
this.client = client;
|
|
||||||
this.serverLatestJobCompleted = new RetryablePredicate<Server>(
|
|
||||||
new ServerLatestJobCompleted(client.getJobServices()),
|
|
||||||
800, 20, TimeUnit.SECONDS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean execute(ComputeMetadata node) {
|
|
||||||
Server server = Iterables.getOnlyElement(
|
|
||||||
client.getServerServices().getServersByName(node.getName()));
|
|
||||||
client.getServerServices().deleteByName(server.getName());
|
|
||||||
return serverLatestJobCompleted.apply(server);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Singleton
|
|
||||||
@Provides
|
|
||||||
Map<String, NodeState> provideServerToNodeState() {
|
|
||||||
return ImmutableMap.<String, NodeState> builder()
|
|
||||||
.put("On", NodeState.RUNNING)
|
|
||||||
.put("Starting", NodeState.PENDING)
|
|
||||||
.put("Off", NodeState.SUSPENDED)
|
|
||||||
.put("Saving", NodeState.PENDING)
|
|
||||||
.put("Restarting", NodeState.PENDING)
|
|
||||||
.put("Stopping", NodeState.PENDING)
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Singleton
|
|
||||||
@Provides
|
|
||||||
Function<String, InetAddress> provideStringIpToInetAddress() {
|
|
||||||
return new Function<String, InetAddress>() {
|
|
||||||
@Override
|
|
||||||
public InetAddress apply(String from) {
|
|
||||||
try {
|
|
||||||
return InetAddress.getByName(from);
|
|
||||||
} catch (UnknownHostException e) {
|
|
||||||
// TODO: log the failure.
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Finds matches to required configurations.
|
|
||||||
* GoGrid's documentation only specifies how much RAM one can get with
|
|
||||||
* different instance types. The # of cores and disk sizes are purely
|
|
||||||
* empyrical and aren't guaranteed.
|
|
||||||
* However, these are the matches found:
|
|
||||||
* Ram: 512MB, CPU: 1 core, HDD: 28 GB
|
|
||||||
* Ram: 1GB, CPU: 1 core, HDD: 57 GB
|
|
||||||
* Ram: 2GB, CPU: 1 core, HDD: 113 GB
|
|
||||||
* Ram: 4GB, CPU: 3 cores, HDD: 233 GB
|
|
||||||
* Ram: 8GB, CPU: 6 cores, HDD: 462 GB
|
|
||||||
* @return matched size
|
|
||||||
*/
|
|
||||||
@Singleton
|
|
||||||
@Provides
|
|
||||||
Function<Size, String> provideSizeToRam() {
|
|
||||||
return new Function<Size, String>() {
|
|
||||||
@Override
|
|
||||||
public String apply(Size size) {
|
|
||||||
if(size.getRam() >= 8 * 1024 || size.getCores() >= 6 || size.getDisk() >= 450) return "8GB";
|
|
||||||
if(size.getRam() >= 4 * 1024 || size.getCores() >= 3 || size.getDisk() >= 230) return "4GB";
|
|
||||||
if(size.getRam() >= 2 * 1024 || size.getDisk() >= 110) return "2GB";
|
|
||||||
if(size.getRam() >= 1024 || size.getDisk() >= 55) return "1GB";
|
|
||||||
return "512MB"; /*smallest*/
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Singleton
|
|
||||||
private static class ServerToNodeMetadata implements Function<Server, NodeMetadata> {
|
|
||||||
private final Map<String, NodeState> serverStateToNodeState;
|
|
||||||
private final Function<String, InetAddress> stringIpToInetAddress;
|
|
||||||
private final GoGridClient client;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
ServerToNodeMetadata(Map<String, NodeState> serverStateToNodeState,
|
|
||||||
Function<String, InetAddress> stringIpToInetAddress,
|
|
||||||
GoGridClient client) {
|
|
||||||
this.serverStateToNodeState = serverStateToNodeState;
|
|
||||||
this.stringIpToInetAddress = stringIpToInetAddress;
|
|
||||||
this.client = client;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public NodeMetadata apply(Server from) {
|
|
||||||
String locationId = "Unavailable";
|
|
||||||
String tag = CharMatcher.JAVA_LETTER.retainFrom(from.getName());
|
|
||||||
Credentials creds = client.getServerServices().getServerCredentialsList().get(from.getName());
|
|
||||||
Set<InetAddress> ipSet =
|
|
||||||
ImmutableSet.of(stringIpToInetAddress.apply(from.getIp().getIp()));
|
|
||||||
NodeState state = serverStateToNodeState.get(from.getState().getName());
|
|
||||||
|
|
||||||
return new NodeMetadataImpl(from.getId() + "", from.getName(), locationId, null,
|
|
||||||
ImmutableMap.<String, String> of(), tag, state,
|
|
||||||
ipSet,
|
|
||||||
ImmutableList.<InetAddress> of(), ImmutableMap.<String, String> of(), creds);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
ComputeServiceContext provideContext(ComputeService computeService,
|
|
||||||
RestContext<GoGridAsyncClient, GoGridClient> context) {
|
|
||||||
return new ComputeServiceContextImpl<GoGridAsyncClient, GoGridClient>(
|
|
||||||
computeService, context);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
@Named("NOT_RUNNING")
|
|
||||||
protected Predicate<SshClient> runScriptRunning(RunScriptRunning stateRunning) {
|
|
||||||
return new RetryablePredicate<SshClient>(Predicates.not(stateRunning), 600, 3,
|
|
||||||
TimeUnit.SECONDS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
Location getDefaultLocation(Map<String, ? extends Location> locations) {
|
|
||||||
return locations.get("SANJOSE");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
Map<String, ? extends Location> getDefaultLocations(GoGridClient sync, LogHolder holder,
|
|
||||||
Function<ComputeMetadata, String> indexer) {
|
|
||||||
final Set<Location> locations = Sets.newHashSet();
|
|
||||||
holder.logger.debug(">> providing empty locations because gogrid doesnt have any");
|
|
||||||
locations.add(new LocationImpl(LocationScope.REGION, "SANJOSE", "GoGrid doesnt support locations so using " +
|
|
||||||
"a made up one to comply with API", "Santa Clara County", true));
|
|
||||||
holder.logger.debug("<< locations(%d)", locations.size());
|
|
||||||
return Maps.uniqueIndex(locations, new Function<Location, String>() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String apply(Location from) {
|
|
||||||
return from.getId();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
protected Function<ComputeMetadata, String> indexer() {
|
|
||||||
return new Function<ComputeMetadata, String>() {
|
|
||||||
@Override
|
|
||||||
public String apply(ComputeMetadata from) {
|
|
||||||
return from.getId();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@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 {
|
|
||||||
final Set<Size> sizes = Sets.newHashSet();
|
|
||||||
holder.logger.debug(">> providing sizes");
|
|
||||||
|
|
||||||
sizes.add(new SizeImpl("1", "1", null, null,
|
|
||||||
ImmutableMap.<String, String> of(), 1, 512, 28,
|
|
||||||
ImmutableSet.<Architecture> of(Architecture.X86_32,
|
|
||||||
Architecture.X86_64)));
|
|
||||||
sizes.add(new SizeImpl("2", "2", null, null,
|
|
||||||
ImmutableMap.<String, String> of(), 1, 1024, 57,
|
|
||||||
ImmutableSet.<Architecture> of(Architecture.X86_32,
|
|
||||||
Architecture.X86_64)));
|
|
||||||
sizes.add(new SizeImpl("3", "3", null, null,
|
|
||||||
ImmutableMap.<String, String> of(), 1, 2048, 113,
|
|
||||||
ImmutableSet.<Architecture> of(Architecture.X86_32,
|
|
||||||
Architecture.X86_64)));
|
|
||||||
sizes.add(new SizeImpl("4", "4", null, null,
|
|
||||||
ImmutableMap.<String, String> of(), 3, 4096, 233,
|
|
||||||
ImmutableSet.<Architecture> of(Architecture.X86_32,
|
|
||||||
Architecture.X86_64)));
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class LogHolder {
|
|
||||||
@Resource
|
|
||||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
|
||||||
protected Logger logger = Logger.NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final Pattern GOGRID_OS_NAME_PATTERN = Pattern.compile("([a-zA-Z]*)(.*)");
|
|
||||||
public static final Pattern GOGRID_OS_VERSION_PATTERN = Pattern.compile("([a-zA-Z\\s]*)(\\d(\\.)*\\d+)");
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
protected Map<String, ? extends Image> provideImages(final GoGridClient sync,
|
|
||||||
LogHolder holder, Function<ComputeMetadata, String> indexer)
|
|
||||||
throws InterruptedException, ExecutionException, TimeoutException {
|
|
||||||
final Set<Image> images = Sets.newHashSet();
|
|
||||||
holder.logger.debug(">> providing images");
|
|
||||||
Set<ServerImage> allImages = sync.getImageServices().getImageList();
|
|
||||||
for (ServerImage from : allImages) {
|
|
||||||
OsFamily os = null;
|
|
||||||
Architecture arch = (from.getOs().getName().indexOf("64") == -1 &&
|
|
||||||
from.getDescription().indexOf("64") == -1) ?
|
|
||||||
Architecture.X86_32 : Architecture.X86_64;
|
|
||||||
String osDescription;
|
|
||||||
String version = "";
|
|
||||||
|
|
||||||
osDescription = from.getOs().getName();
|
|
||||||
|
|
||||||
String matchedOs = GoGridUtils.parseStringByPatternAndGetNthMatchGroup(from.getOs().getName(),
|
|
||||||
GOGRID_OS_NAME_PATTERN, 1);
|
|
||||||
try {
|
try {
|
||||||
os = OsFamily.fromValue(matchedOs.toLowerCase());
|
addedServer = client.getServerServices().addServer(name,
|
||||||
} catch (IllegalArgumentException e) {
|
checkNotNull(template.getImage().getId()),
|
||||||
holder.logger.debug("<< didn't match os(%s)", matchedOs);
|
sizeToRam.apply(template.getSize()), availableIp.getIp());
|
||||||
|
notStarted = false;
|
||||||
|
} catch (Exception e) {
|
||||||
|
if (--numOfRetries == 0)
|
||||||
|
Throwables.propagate(e);
|
||||||
|
notStarted = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
serverLatestJobCompleted.apply(addedServer);
|
||||||
|
|
||||||
version = GoGridUtils.parseStringByPatternAndGetNthMatchGroup(from.getOs().getName(),
|
client.getServerServices().power(addedServer.getName(), PowerCommand.START);
|
||||||
GOGRID_OS_VERSION_PATTERN, 2);
|
serverLatestJobCompletedShort.apply(addedServer);
|
||||||
|
|
||||||
images.add(new ImageImpl(from.getName(), from.getDescription(), null, null, ImmutableMap
|
addedServer = Iterables.getOnlyElement(client.getServerServices().getServersByName(
|
||||||
.<String, String> of(), from.getDescription(), version, os, osDescription, arch));
|
addedServer.getName()));
|
||||||
}
|
return serverToNodeMetadata.apply(addedServer);
|
||||||
holder.logger.debug("<< images(%d)", images.size());
|
}
|
||||||
return Maps.uniqueIndex(images, indexer);
|
}
|
||||||
}
|
|
||||||
|
@Singleton
|
||||||
|
public static class GoGridRebootNodeStrategy implements RebootNodeStrategy {
|
||||||
|
private final GoGridClient client;
|
||||||
|
private RetryablePredicate<Server> serverLatestJobCompleted;
|
||||||
|
private RetryablePredicate<Server> serverLatestJobCompletedShort;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
protected GoGridRebootNodeStrategy(GoGridClient client) {
|
||||||
|
this.client = client;
|
||||||
|
this.serverLatestJobCompleted = new RetryablePredicate<Server>(
|
||||||
|
new ServerLatestJobCompleted(client.getJobServices()), 800, 20, TimeUnit.SECONDS);
|
||||||
|
this.serverLatestJobCompletedShort = new RetryablePredicate<Server>(
|
||||||
|
new ServerLatestJobCompleted(client.getJobServices()), 60, 20, TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean execute(ComputeMetadata node) {
|
||||||
|
Server server = Iterables.getOnlyElement(client.getServerServices().getServersByName(
|
||||||
|
node.getName()));
|
||||||
|
client.getServerServices().power(server.getName(), PowerCommand.RESTART);
|
||||||
|
serverLatestJobCompleted.apply(server);
|
||||||
|
client.getServerServices().power(server.getName(), PowerCommand.START);
|
||||||
|
return serverLatestJobCompletedShort.apply(server);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
public static class GoGridListNodesStrategy implements ListNodesStrategy {
|
||||||
|
private final GoGridClient client;
|
||||||
|
private final Function<Server, NodeMetadata> serverToNodeMetadata;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
protected GoGridListNodesStrategy(GoGridClient client,
|
||||||
|
Function<Server, NodeMetadata> serverToNodeMetadata) {
|
||||||
|
this.client = client;
|
||||||
|
this.serverToNodeMetadata = serverToNodeMetadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterable<? extends ComputeMetadata> execute() {
|
||||||
|
return Iterables.transform(client.getServerServices().getServerList(),
|
||||||
|
serverToNodeMetadata);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
public static class GoGridGetNodeMetadataStrategy implements GetNodeMetadataStrategy {
|
||||||
|
private final GoGridClient client;
|
||||||
|
private final Function<Server, NodeMetadata> serverToNodeMetadata;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
protected GoGridGetNodeMetadataStrategy(GoGridClient client,
|
||||||
|
Function<Server, NodeMetadata> serverToNodeMetadata) {
|
||||||
|
this.client = client;
|
||||||
|
this.serverToNodeMetadata = serverToNodeMetadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NodeMetadata execute(ComputeMetadata node) {
|
||||||
|
Server server = Iterables.getOnlyElement(client.getServerServices().getServersByName(
|
||||||
|
node.getName()));
|
||||||
|
return server == null ? null : serverToNodeMetadata.apply(server);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
public static class GoGridDestroyNodeStrategy implements DestroyNodeStrategy {
|
||||||
|
private final GoGridClient client;
|
||||||
|
private RetryablePredicate<Server> serverLatestJobCompleted;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
protected GoGridDestroyNodeStrategy(GoGridClient client) {
|
||||||
|
this.client = client;
|
||||||
|
this.serverLatestJobCompleted = new RetryablePredicate<Server>(
|
||||||
|
new ServerLatestJobCompleted(client.getJobServices()), 800, 20, TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean execute(ComputeMetadata node) {
|
||||||
|
Server server = Iterables.getOnlyElement(client.getServerServices().getServersByName(
|
||||||
|
node.getName()));
|
||||||
|
client.getServerServices().deleteByName(server.getName());
|
||||||
|
return serverLatestJobCompleted.apply(server);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
@Provides
|
||||||
|
Map<String, NodeState> provideServerToNodeState() {
|
||||||
|
return ImmutableMap.<String, NodeState> builder().put("On", NodeState.RUNNING).put(
|
||||||
|
"Starting", NodeState.PENDING).put("Off", NodeState.SUSPENDED).put("Saving",
|
||||||
|
NodeState.PENDING).put("Restarting", NodeState.PENDING).put("Stopping",
|
||||||
|
NodeState.PENDING).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
@Provides
|
||||||
|
Function<String, InetAddress> provideStringIpToInetAddress() {
|
||||||
|
return new Function<String, InetAddress>() {
|
||||||
|
@Override
|
||||||
|
public InetAddress apply(String from) {
|
||||||
|
try {
|
||||||
|
return InetAddress.getByName(from);
|
||||||
|
} catch (UnknownHostException e) {
|
||||||
|
// TODO: log the failure.
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds matches to required configurations. GoGrid's documentation only specifies how much RAM
|
||||||
|
* one can get with different instance types. The # of cores and disk sizes are purely empyrical
|
||||||
|
* and aren't guaranteed. However, these are the matches found: Ram: 512MB, CPU: 1 core, HDD: 28
|
||||||
|
* GB Ram: 1GB, CPU: 1 core, HDD: 57 GB Ram: 2GB, CPU: 1 core, HDD: 113 GB Ram: 4GB, CPU: 3
|
||||||
|
* cores, HDD: 233 GB Ram: 8GB, CPU: 6 cores, HDD: 462 GB
|
||||||
|
*
|
||||||
|
* @return matched size
|
||||||
|
*/
|
||||||
|
@Singleton
|
||||||
|
@Provides
|
||||||
|
Function<Size, String> provideSizeToRam() {
|
||||||
|
return new Function<Size, String>() {
|
||||||
|
@Override
|
||||||
|
public String apply(Size size) {
|
||||||
|
if (size.getRam() >= 8 * 1024 || size.getCores() >= 6 || size.getDisk() >= 450)
|
||||||
|
return "8GB";
|
||||||
|
if (size.getRam() >= 4 * 1024 || size.getCores() >= 3 || size.getDisk() >= 230)
|
||||||
|
return "4GB";
|
||||||
|
if (size.getRam() >= 2 * 1024 || size.getDisk() >= 110)
|
||||||
|
return "2GB";
|
||||||
|
if (size.getRam() >= 1024 || size.getDisk() >= 55)
|
||||||
|
return "1GB";
|
||||||
|
return "512MB"; /* smallest */
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
private static class ServerToNodeMetadata implements Function<Server, NodeMetadata> {
|
||||||
|
private final Map<String, NodeState> serverStateToNodeState;
|
||||||
|
private final Function<String, InetAddress> stringIpToInetAddress;
|
||||||
|
private final GoGridClient client;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
ServerToNodeMetadata(Map<String, NodeState> serverStateToNodeState,
|
||||||
|
Function<String, InetAddress> stringIpToInetAddress, GoGridClient client) {
|
||||||
|
this.serverStateToNodeState = serverStateToNodeState;
|
||||||
|
this.stringIpToInetAddress = stringIpToInetAddress;
|
||||||
|
this.client = client;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NodeMetadata apply(Server from) {
|
||||||
|
String locationId = "Unavailable";
|
||||||
|
String tag = CharMatcher.JAVA_LETTER.retainFrom(from.getName());
|
||||||
|
Credentials creds = client.getServerServices().getServerCredentialsList().get(
|
||||||
|
from.getName());
|
||||||
|
Set<InetAddress> ipSet = ImmutableSet
|
||||||
|
.of(stringIpToInetAddress.apply(from.getIp().getIp()));
|
||||||
|
NodeState state = serverStateToNodeState.get(from.getState().getName());
|
||||||
|
|
||||||
|
return new NodeMetadataImpl(from.getId() + "", from.getName(), locationId, null,
|
||||||
|
ImmutableMap.<String, String> of(), tag, state, ipSet, ImmutableList
|
||||||
|
.<InetAddress> of(), ImmutableMap.<String, String> of(), creds);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
ComputeServiceContext provideContext(ComputeService computeService,
|
||||||
|
RestContext<GoGridAsyncClient, GoGridClient> context) {
|
||||||
|
return new ComputeServiceContextImpl<GoGridAsyncClient, GoGridClient>(computeService, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
@Named("NOT_RUNNING")
|
||||||
|
protected Predicate<SshClient> runScriptRunning(RunScriptRunning stateRunning) {
|
||||||
|
return new RetryablePredicate<SshClient>(Predicates.not(stateRunning), 600, 3,
|
||||||
|
TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
Location getDefaultLocation(Map<String, ? extends Location> locations) {
|
||||||
|
return locations.get("SANFRANCISCO");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
Map<String, ? extends Location> getDefaultLocations(GoGridClient sync, LogHolder holder,
|
||||||
|
Function<ComputeMetadata, String> indexer) {
|
||||||
|
final Set<Location> locations = Sets.newHashSet();
|
||||||
|
holder.logger.debug(">> providing locations");
|
||||||
|
locations.add(new LocationImpl(LocationScope.ZONE, "SANFRANCISCO", "San Francisco, CA", null,
|
||||||
|
true));
|
||||||
|
holder.logger.debug("<< locations(%d)", locations.size());
|
||||||
|
return Maps.uniqueIndex(locations, new Function<Location, String>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String apply(Location from) {
|
||||||
|
return from.getId();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
protected Function<ComputeMetadata, String> indexer() {
|
||||||
|
return new Function<ComputeMetadata, String>() {
|
||||||
|
@Override
|
||||||
|
public String apply(ComputeMetadata from) {
|
||||||
|
return from.getId();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@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 {
|
||||||
|
final Set<Size> sizes = Sets.newHashSet();
|
||||||
|
holder.logger.debug(">> providing sizes");
|
||||||
|
|
||||||
|
sizes.add(new SizeImpl("1", "1", null, null, ImmutableMap.<String, String> of(), 1, 512, 28,
|
||||||
|
ImmutableSet.<Architecture> of(Architecture.X86_32, Architecture.X86_64)));
|
||||||
|
sizes.add(new SizeImpl("2", "2", null, null, ImmutableMap.<String, String> of(), 1, 1024, 57,
|
||||||
|
ImmutableSet.<Architecture> of(Architecture.X86_32, Architecture.X86_64)));
|
||||||
|
sizes.add(new SizeImpl("3", "3", null, null, ImmutableMap.<String, String> of(), 1, 2048,
|
||||||
|
113, ImmutableSet.<Architecture> of(Architecture.X86_32, Architecture.X86_64)));
|
||||||
|
sizes.add(new SizeImpl("4", "4", null, null, ImmutableMap.<String, String> of(), 3, 4096,
|
||||||
|
233, ImmutableSet.<Architecture> of(Architecture.X86_32, Architecture.X86_64)));
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class LogHolder {
|
||||||
|
@Resource
|
||||||
|
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||||
|
protected Logger logger = Logger.NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final Pattern GOGRID_OS_NAME_PATTERN = Pattern.compile("([a-zA-Z]*)(.*)");
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
protected Map<String, ? extends Image> provideImages(final GoGridClient sync, LogHolder holder,
|
||||||
|
Function<ComputeMetadata, String> indexer, Location location)
|
||||||
|
throws InterruptedException, ExecutionException, TimeoutException {
|
||||||
|
final Set<Image> images = Sets.newHashSet();
|
||||||
|
holder.logger.debug(">> providing images");
|
||||||
|
Set<ServerImage> allImages = sync.getImageServices().getImageList();
|
||||||
|
for (ServerImage from : allImages) {
|
||||||
|
OsFamily os = null;
|
||||||
|
Architecture arch = (from.getOs().getName().indexOf("64") == -1 && from.getDescription()
|
||||||
|
.indexOf("64") == -1) ? Architecture.X86_32 : Architecture.X86_64;
|
||||||
|
String osDescription;
|
||||||
|
String version = "";
|
||||||
|
|
||||||
|
osDescription = from.getOs().getName();
|
||||||
|
|
||||||
|
String matchedOs = GoGridUtils.parseStringByPatternAndGetNthMatchGroup(from.getOs()
|
||||||
|
.getName(), GOGRID_OS_NAME_PATTERN, 1);
|
||||||
|
try {
|
||||||
|
os = OsFamily.fromValue(matchedOs.toLowerCase());
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
holder.logger.debug("<< didn't match os(%s)", matchedOs);
|
||||||
|
}
|
||||||
|
|
||||||
|
images.add(new ImageImpl(from.getId() + "", from.getFriendlyName(), location.getId(), null,
|
||||||
|
ImmutableMap.<String, String> of(), from.getDescription(), version, os,
|
||||||
|
osDescription, arch));
|
||||||
|
}
|
||||||
|
holder.logger.debug("<< images(%d)", images.size());
|
||||||
|
return Maps.uniqueIndex(images, indexer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,9 +21,9 @@ package org.jclouds.gogrid;
|
||||||
import static org.jclouds.compute.domain.OsFamily.CENTOS;
|
import static org.jclouds.compute.domain.OsFamily.CENTOS;
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
import static org.testng.Assert.assertTrue;
|
import static org.testng.Assert.assertTrue;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import com.google.common.base.Predicate;
|
|
||||||
import org.jclouds.compute.BaseComputeServiceLiveTest;
|
import org.jclouds.compute.BaseComputeServiceLiveTest;
|
||||||
import org.jclouds.compute.ComputeService;
|
import org.jclouds.compute.ComputeService;
|
||||||
import org.jclouds.compute.ComputeServiceContextFactory;
|
import org.jclouds.compute.ComputeServiceContextFactory;
|
||||||
|
@ -34,82 +34,84 @@ import org.jclouds.compute.domain.Template;
|
||||||
import org.jclouds.compute.domain.TemplateBuilder;
|
import org.jclouds.compute.domain.TemplateBuilder;
|
||||||
import org.jclouds.rest.RestContext;
|
import org.jclouds.rest.RestContext;
|
||||||
import org.jclouds.ssh.jsch.config.JschSshClientModule;
|
import org.jclouds.ssh.jsch.config.JschSshClientModule;
|
||||||
import org.testng.annotations.AfterClass;
|
|
||||||
import org.testng.annotations.BeforeClass;
|
import org.testng.annotations.BeforeClass;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.base.Predicate;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Oleksiy Yarmula
|
* @author Oleksiy Yarmula
|
||||||
*/
|
*/
|
||||||
@Test(groups = "live", enabled = true, sequential = true, testName = "gogrid.GoGridComputeServiceLiveTest")
|
@Test(groups = "live", enabled = true, sequential = true, testName = "gogrid.GoGridComputeServiceLiveTest")
|
||||||
public class GoGridComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
public class GoGridComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
@Override
|
@Override
|
||||||
public void setServiceDefaults() {
|
public void setServiceDefaults() {
|
||||||
service = "gogrid";
|
service = "gogrid";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String buildScript() {
|
public String buildScript() {
|
||||||
return
|
return new StringBuilder()
|
||||||
new StringBuilder()//
|
//
|
||||||
.append("echo nameserver 208.67.222.222 >> /etc/resolv.conf\n")//
|
.append("echo nameserver 208.67.222.222 >> /etc/resolv.conf\n")
|
||||||
.append("echo \"[jdkrepo]\" >> /etc/yum.repos.d/CentOS-Base.repo\n")
|
//
|
||||||
.append("echo \"name=jdkrepository\" >> /etc/yum.repos.d/CentOS-Base.repo\n")
|
.append("echo \"[jdkrepo]\" >> /etc/yum.repos.d/CentOS-Base.repo\n")
|
||||||
.append("echo \"baseurl=http://ec2-us-east-mirror.rightscale.com/epel/5/i386/\" >> /etc/yum.repos.d/CentOS-Base.repo\n")
|
.append("echo \"name=jdkrepository\" >> /etc/yum.repos.d/CentOS-Base.repo\n")
|
||||||
.append("echo \"enabled=1\" >> /etc/yum.repos.d/CentOS-Base.repo\n")
|
.append(
|
||||||
.append("yum -y install java-1.6.0-openjdk\n")
|
"echo \"baseurl=http://ec2-us-east-mirror.rightscale.com/epel/5/i386/\" >> /etc/yum.repos.d/CentOS-Base.repo\n")
|
||||||
.append("echo \"export PATH=\\\"/usr/lib/jvm/jre-1.6.0-openjdk/bin/:\\$PATH\\\"\" >> /root/.bashrc\n")
|
.append("echo \"enabled=1\" >> /etc/yum.repos.d/CentOS-Base.repo\n")
|
||||||
.toString();
|
.append("yum -y install java-1.6.0-openjdk\n")
|
||||||
}
|
.append(
|
||||||
|
"echo \"export PATH=\\\"/usr/lib/jvm/jre-1.6.0-openjdk/bin/:\\$PATH\\\"\" >> /root/.bashrc\n")
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
|
||||||
protected Template buildTemplate(TemplateBuilder templateBuilder) {
|
protected Template buildTemplate(TemplateBuilder templateBuilder) {
|
||||||
return templateBuilder.osFamily(CENTOS).imageId("centos5.3_32_base").smallest().build();
|
return templateBuilder.osFamily(CENTOS).imageDescriptionMatches(".*w/ None.*").smallest()
|
||||||
}
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected JschSshClientModule getSshModule() {
|
protected JschSshClientModule getSshModule() {
|
||||||
return new JschSshClientModule();
|
return new JschSshClientModule();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testAssignability() throws Exception {
|
public void testAssignability() throws Exception {
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
RestContext<GoGridAsyncClient, GoGridClient> goGridContext = new ComputeServiceContextFactory()
|
RestContext<GoGridAsyncClient, GoGridClient> goGridContext = new ComputeServiceContextFactory()
|
||||||
.createContext(service, user, password).getProviderSpecificContext();
|
.createContext(service, user, password).getProviderSpecificContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(enabled = true)
|
@Test(enabled = true)
|
||||||
public void endToEndComputeServiceTest() {
|
public void endToEndComputeServiceTest() {
|
||||||
ComputeService service = context.getComputeService();
|
ComputeService service = context.getComputeService();
|
||||||
Template t = service.templateBuilder().minRam(1024).imageId(
|
Template t = service.templateBuilder().minRam(1024).imageId("1532").build();
|
||||||
"GSI-6890f8b6-c8fb-4ac1-bc33-2563eb4e29d2").build();
|
|
||||||
|
|
||||||
int originalSize = service.getNodes().size();
|
int originalSize = service.getNodes().size();
|
||||||
|
|
||||||
assertEquals(t.getImage().getId(), "GSI-6890f8b6-c8fb-4ac1-bc33-2563eb4e29d2");
|
assertEquals(t.getImage().getId(), "1532");
|
||||||
service.runNodesWithTag(this.service, 1, t);
|
service.runNodesWithTag(this.service, 1, t);
|
||||||
|
|
||||||
Map<String, ? extends ComputeMetadata> nodes = service.getNodes();
|
Map<String, ? extends ComputeMetadata> nodes = service.getNodes();
|
||||||
assertEquals(nodes.size(), originalSize + 1, "size should've been larger by 1");
|
assertEquals(nodes.size(), originalSize + 1, "size should've been larger by 1");
|
||||||
|
|
||||||
ComputeMetadata node = Iterables.find(nodes.values(), new Predicate<ComputeMetadata>() {
|
ComputeMetadata node = Iterables.find(nodes.values(), new Predicate<ComputeMetadata>() {
|
||||||
@Override public boolean apply(ComputeMetadata computeMetadata) {
|
@Override
|
||||||
return computeMetadata.getName().startsWith(GoGridComputeServiceLiveTest.this.service);
|
public boolean apply(ComputeMetadata computeMetadata) {
|
||||||
}
|
return computeMetadata.getName().startsWith(GoGridComputeServiceLiveTest.this.service);
|
||||||
});
|
}
|
||||||
|
});
|
||||||
|
|
||||||
NodeMetadata nodeMetadata = service.getNodeMetadata(node);
|
NodeMetadata nodeMetadata = service.getNodeMetadata(node);
|
||||||
assertEquals(nodeMetadata.getPublicAddresses().size(), 1,
|
assertEquals(nodeMetadata.getPublicAddresses().size(), 1,
|
||||||
"There must be 1 public address for the node");
|
"There must be 1 public address for the node");
|
||||||
assertTrue(nodeMetadata.getName().startsWith(this.service));
|
assertTrue(nodeMetadata.getName().startsWith(this.service));
|
||||||
service.rebootNode(nodeMetadata); // blocks until finished
|
service.rebootNode(nodeMetadata); // blocks until finished
|
||||||
|
|
||||||
assertEquals(service.getNodeMetadata(nodeMetadata).getState(), NodeState.RUNNING);
|
assertEquals(service.getNodeMetadata(nodeMetadata).getState(), NodeState.RUNNING);
|
||||||
service.destroyNode(nodeMetadata);
|
service.destroyNode(nodeMetadata);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -149,9 +149,12 @@ public class ComputeTask extends Task {
|
||||||
private void listImages(ComputeService computeService) {
|
private void listImages(ComputeService computeService) {
|
||||||
log("list images");
|
log("list images");
|
||||||
for (Image image : computeService.getImages().values()) {// TODO
|
for (Image image : computeService.getImages().values()) {// TODO
|
||||||
log(String.format(" image location=%s, id=%s, version=%s, arch=%s, osfam=%s, desc=%s",
|
log(String
|
||||||
image.getLocationId(), image.getId(), image.getVersion(),
|
.format(
|
||||||
image.getArchitecture(), image.getOsFamily(), image.getOsDescription()));
|
" image location=%s, id=%s, name=%s, version=%s, arch=%s, osfam=%s, osdesc=%s, desc=%s",
|
||||||
|
image.getLocationId(), image.getId(), image.getName(), image
|
||||||
|
.getVersion(), image.getArchitecture(), image.getOsFamily(),
|
||||||
|
image.getOsDescription(), image.getDescription()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue