Issue 419: computeservice support for cloudsigma

This commit is contained in:
Adrian Cole 2010-12-20 14:39:25 +01:00
parent 5587fc6635
commit 9de014e354
21 changed files with 1052 additions and 51 deletions

View File

@ -29,20 +29,20 @@ import javax.ws.rs.PathParam;
import javax.ws.rs.core.MediaType;
import org.jclouds.cloudsigma.binders.BindCloneDriveOptionsToPlainTextString;
import org.jclouds.cloudsigma.domain.DriveInfo;
import org.jclouds.cloudsigma.functions.KeyValuesDelimitedByBlankLinesToDriveInfo;
import org.jclouds.cloudsigma.functions.KeyValuesDelimitedByBlankLinesToServerInfo;
import org.jclouds.cloudsigma.functions.ListOfKeyValuesDelimitedByBlankLinesToDriveInfoSet;
import org.jclouds.cloudsigma.functions.ListOfKeyValuesDelimitedByBlankLinesToServerInfoSet;
import org.jclouds.cloudsigma.options.CloneDriveOptions;
import org.jclouds.cloudsigma.binders.BindDriveDataToPlainTextString;
import org.jclouds.cloudsigma.binders.BindDriveToPlainTextString;
import org.jclouds.cloudsigma.binders.BindServerToPlainTextString;
import org.jclouds.cloudsigma.domain.Drive;
import org.jclouds.cloudsigma.domain.DriveData;
import org.jclouds.cloudsigma.domain.DriveInfo;
import org.jclouds.cloudsigma.domain.Server;
import org.jclouds.cloudsigma.domain.ServerInfo;
import org.jclouds.cloudsigma.functions.KeyValuesDelimitedByBlankLinesToDriveInfo;
import org.jclouds.cloudsigma.functions.KeyValuesDelimitedByBlankLinesToServerInfo;
import org.jclouds.cloudsigma.functions.ListOfKeyValuesDelimitedByBlankLinesToDriveInfoSet;
import org.jclouds.cloudsigma.functions.ListOfKeyValuesDelimitedByBlankLinesToServerInfoSet;
import org.jclouds.cloudsigma.functions.SplitNewlines;
import org.jclouds.cloudsigma.options.CloneDriveOptions;
import org.jclouds.http.filters.BasicAuthentication;
import org.jclouds.rest.annotations.BinderParam;
import org.jclouds.rest.annotations.ExceptionParser;
@ -98,7 +98,7 @@ public interface CloudSigmaAsyncClient {
@ResponseParser(KeyValuesDelimitedByBlankLinesToDriveInfo.class)
@Path("/drives/{uuid}/clone")
@MapBinder(BindCloneDriveOptionsToPlainTextString.class)
ListenableFuture<? extends DriveInfo> cloneDrive(@PathParam("uuid") String sourceUuid,
ListenableFuture<DriveInfo> cloneDrive(@PathParam("uuid") String sourceUuid,
@MapPayloadParam("name") String newName, CloneDriveOptions... options);
/**
@ -107,7 +107,7 @@ public interface CloudSigmaAsyncClient {
@GET
@Path("/drives/info")
@ResponseParser(ListOfKeyValuesDelimitedByBlankLinesToDriveInfoSet.class)
ListenableFuture<Set<? extends org.jclouds.cloudsigma.domain.DriveInfo>> listDriveInfo();
ListenableFuture<Set<org.jclouds.cloudsigma.domain.DriveInfo>> listDriveInfo();
/**
* @see CloudSigmaClient#getDriveInfo
@ -116,7 +116,7 @@ public interface CloudSigmaAsyncClient {
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@ResponseParser(KeyValuesDelimitedByBlankLinesToDriveInfo.class)
@Path("/drives/{uuid}/info")
ListenableFuture<? extends DriveInfo> getDriveInfo(@PathParam("uuid") String uuid);
ListenableFuture<DriveInfo> getDriveInfo(@PathParam("uuid") String uuid);
/**
* @see CloudSigmaClient#createDrive
@ -125,7 +125,7 @@ public interface CloudSigmaAsyncClient {
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@ResponseParser(KeyValuesDelimitedByBlankLinesToDriveInfo.class)
@Path("/drives/create")
ListenableFuture<? extends DriveInfo> createDrive(@BinderParam(BindDriveToPlainTextString.class) Drive createDrive);
ListenableFuture<DriveInfo> createDrive(@BinderParam(BindDriveToPlainTextString.class) Drive createDrive);
/**
* @see CloudSigmaClient#setDriveData
@ -133,7 +133,7 @@ public interface CloudSigmaAsyncClient {
@POST
@ResponseParser(KeyValuesDelimitedByBlankLinesToDriveInfo.class)
@Path("/drives/{uuid}/set")
ListenableFuture<? extends DriveInfo> setDriveData(@PathParam("uuid") String uuid,
ListenableFuture<DriveInfo> setDriveData(@PathParam("uuid") String uuid,
@BinderParam(BindDriveDataToPlainTextString.class) DriveData createDrive);
/**
@ -143,7 +143,7 @@ public interface CloudSigmaAsyncClient {
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@ResponseParser(KeyValuesDelimitedByBlankLinesToServerInfo.class)
@Path("/servers/create")
ListenableFuture<? extends ServerInfo> createServer(
ListenableFuture<ServerInfo> createServer(
@BinderParam(BindServerToPlainTextString.class) Server createServer);
/**
@ -152,7 +152,7 @@ public interface CloudSigmaAsyncClient {
@GET
@Path("/servers/info")
@ResponseParser(ListOfKeyValuesDelimitedByBlankLinesToServerInfoSet.class)
ListenableFuture<Set<? extends ServerInfo>> listServerInfo();
ListenableFuture<Set<ServerInfo>> listServerInfo();
/**
* @see CloudSigmaClient#getServerInfo
@ -161,7 +161,7 @@ public interface CloudSigmaAsyncClient {
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@ResponseParser(KeyValuesDelimitedByBlankLinesToServerInfo.class)
@Path("/servers/{uuid}/info")
ListenableFuture<? extends ServerInfo> getServerInfo(@PathParam("uuid") String uuid);
ListenableFuture<ServerInfo> getServerInfo(@PathParam("uuid") String uuid);
/**
* @see CloudSigmaClient#setServerConfiguration
@ -170,7 +170,7 @@ public interface CloudSigmaAsyncClient {
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@ResponseParser(KeyValuesDelimitedByBlankLinesToServerInfo.class)
@Path("/servers/{uuid}/set")
ListenableFuture<? extends ServerInfo> setServerConfiguration(@PathParam("uuid") String uuid,
ListenableFuture<ServerInfo> setServerConfiguration(@PathParam("uuid") String uuid,
@BinderParam(BindServerToPlainTextString.class) Server setServer);
/**

View File

@ -22,13 +22,13 @@ package org.jclouds.cloudsigma;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.jclouds.cloudsigma.domain.DriveInfo;
import org.jclouds.cloudsigma.options.CloneDriveOptions;
import org.jclouds.concurrent.Timeout;
import org.jclouds.cloudsigma.domain.Drive;
import org.jclouds.cloudsigma.domain.DriveData;
import org.jclouds.cloudsigma.domain.DriveInfo;
import org.jclouds.cloudsigma.domain.Server;
import org.jclouds.cloudsigma.domain.ServerInfo;
import org.jclouds.cloudsigma.options.CloneDriveOptions;
import org.jclouds.concurrent.Timeout;
/**
* Provides synchronous access to CloudSigma.

View File

@ -22,8 +22,9 @@ package org.jclouds.cloudsigma;
import java.util.List;
import java.util.Properties;
import org.jclouds.cloudsigma.compute.config.CloudSigmaComputeServiceContextModule;
import org.jclouds.cloudsigma.config.CloudSigmaRestClientModule;
import org.jclouds.rest.RestContextBuilder;
import org.jclouds.compute.ComputeServiceContextBuilder;
import com.google.inject.Module;
@ -31,13 +32,17 @@ import com.google.inject.Module;
*
* @author Adrian Cole
*/
public class CloudSigmaContextBuilder extends
RestContextBuilder<CloudSigmaClient, CloudSigmaAsyncClient> {
public class CloudSigmaContextBuilder extends ComputeServiceContextBuilder<CloudSigmaClient, CloudSigmaAsyncClient> {
public CloudSigmaContextBuilder(Properties props) {
super(CloudSigmaClient.class, CloudSigmaAsyncClient.class, props);
}
@Override
protected void addContextModule(List<Module> modules) {
modules.add(new CloudSigmaComputeServiceContextModule());
}
protected void addClientModule(List<Module> modules) {
modules.add(new CloudSigmaRestClientModule());
}

View File

@ -30,8 +30,8 @@ import javax.inject.Singleton;
import javax.ws.rs.core.MediaType;
import org.jclouds.cloudsigma.CloudSigmaAsyncClient;
import org.jclouds.cloudsigma.options.CloneDriveOptions;
import org.jclouds.cloudsigma.functions.ListOfMapsToListOfKeyValuesDelimitedByBlankLines;
import org.jclouds.cloudsigma.options.CloneDriveOptions;
import org.jclouds.http.HttpRequest;
import org.jclouds.rest.MapBinder;
import org.jclouds.rest.internal.GeneratedHttpRequest;

View File

@ -0,0 +1,231 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.cloudsigma.compute;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.Iterables.filter;
import static org.jclouds.concurrent.FutureIterables.transformParallel;
import java.net.URI;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import javax.annotation.Resource;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.Constants;
import org.jclouds.cloudsigma.CloudSigmaAsyncClient;
import org.jclouds.cloudsigma.CloudSigmaClient;
import org.jclouds.cloudsigma.domain.Device;
import org.jclouds.cloudsigma.domain.DriveInfo;
import org.jclouds.cloudsigma.domain.DriveType;
import org.jclouds.cloudsigma.domain.Server;
import org.jclouds.cloudsigma.domain.ServerInfo;
import org.jclouds.cloudsigma.options.CloneDriveOptions;
import org.jclouds.cloudsigma.reference.CloudSigmaConstants;
import org.jclouds.cloudsigma.util.Servers;
import org.jclouds.compute.ComputeService;
import org.jclouds.compute.ComputeServiceAdapter;
import org.jclouds.compute.domain.Hardware;
import org.jclouds.compute.domain.HardwareBuilder;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.Processor;
import org.jclouds.compute.domain.Template;
import org.jclouds.compute.domain.Volume;
import org.jclouds.compute.domain.internal.VolumeImpl;
import org.jclouds.compute.reference.ComputeServiceConstants;
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 org.jclouds.rest.annotations.Provider;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSet.Builder;
/**
* defines the connection between the {@link CloudSigmaClient} implementation and the jclouds
* {@link ComputeService}
*
*/
@Singleton
public class CloudSigmaComputeServiceAdapter implements
ComputeServiceAdapter<ServerInfo, Hardware, DriveInfo, Location> {
private static final Predicate<DriveInfo> PREINSTALLED_DISK = Predicates.and(Predicates.notNull(),
new Predicate<DriveInfo>() {
@Override
public boolean apply(DriveInfo drive) {
return drive.getType().equals(DriveType.DISK) && drive.getDriveType().contains("preinstalled");
}
});
private final CloudSigmaClient client;
private final CloudSigmaAsyncClient aclient;
private final Predicate<DriveInfo> driveNotClaimed;
private final String providerName;
private final URI providerURI;
private final String defaultVncPassword;
private final Map<String, DriveInfo> cache;
private final ExecutorService executor;
@Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL;
@Inject
public CloudSigmaComputeServiceAdapter(CloudSigmaClient client, CloudSigmaAsyncClient aclient,
Predicate<DriveInfo> driveNotClaimed, @Provider String providerName, @Provider URI providerURI,
@Named(CloudSigmaConstants.PROPERTY_VNC_PASSWORD) String defaultVncPassword, Map<String, DriveInfo> cache,
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) {
this.client = checkNotNull(client, "client");
this.aclient = checkNotNull(aclient, "aclient");
this.driveNotClaimed = checkNotNull(driveNotClaimed, "driveNotClaimed");
this.providerName = checkNotNull(providerName, "providerName");
this.providerURI = checkNotNull(providerURI, "providerURI");
this.defaultVncPassword = checkNotNull(defaultVncPassword, "defaultVncPassword");
this.cache = checkNotNull(cache, "cache");
this.executor = checkNotNull(executor, "executor");
}
@Override
public ServerInfo runNodeWithTagAndNameAndStoreCredentials(String tag, String name, Template template,
Map<String, Credentials> credentialStore) {
long bootSize = (long) (template.getHardware().getVolumes().get(0).getSize() * 1024 * 1024 * 1024l);
logger.debug(">> imaging boot drive source(%s) bytes(%d)", template.getImage().getId(), bootSize);
DriveInfo drive = client.cloneDrive(template.getImage().getId(), template.getImage().getId(),
new CloneDriveOptions().size(bootSize));
boolean success = driveNotClaimed.apply(drive);
logger.debug("<< image(%s) complete(%s)", drive.getUuid(), success);
if (!success) {
client.destroyDrive(drive.getUuid());
throw new IllegalStateException("could not image drive in time!");
}
Server toCreate = Servers.small(name, drive.getUuid(), defaultVncPassword).mem(template.getHardware().getRam())
.cpu((int) (template.getHardware().getProcessors().get(0).getSpeed())).build();
logger.debug(">> creating server");
ServerInfo from = client.createServer(toCreate);
logger.debug("<< created server(%s)", from.getUuid());
logger.debug(">> starting server(%s)", from.getUuid());
client.startServer(from.getUuid());
// store the credentials so that later functions can use them
credentialStore.put(from.getUuid() + "", new Credentials("cloudsigma", "cloudsigma"));
return from;
}
@Override
public Iterable<Hardware> listHardwareProfiles() {
Builder<Hardware> hardware = ImmutableSet.<Hardware> builder();
for (double cpu : new double[] { 1000, 5000, 10000, 20000 })
for (int ram : new int[] { 512, 1024, 4 * 1024, 16 * 1024, 32 * 1024 }) {
final float size = (float) ram * 10 / 1024;
String id = String.format("cpu=%f,ram=%s,disk=%f", cpu, ram, size);
hardware.add(new HardwareBuilder().supportsImage(new Predicate<Image>() {
@Override
public boolean apply(Image input) {
String toParse = input.getUserMetadata().get("size");
return (toParse != null && new Float(toParse) <= size);
}
@Override
public String toString() {
return "sizeLessThanOrEqual(" + size + ")";
}
}).ids(id).ram(ram).processors(ImmutableList.of(new Processor(1, cpu)))
.volumes(ImmutableList.<Volume> of(new VolumeImpl(size, true, true))).build());
}
return hardware.build();
}
/**
* look up the current standard images and do not error out, if they are not found.
*/
@Override
public Iterable<DriveInfo> listImages() {
Iterable<DriveInfo> drives = transformParallel(client.listStandardDrives(),
new Function<String, Future<DriveInfo>>() {
@Override
public Future<DriveInfo> apply(String input) {
return aclient.getDriveInfo(input);
}
}, executor, null, logger, "drives");
Iterable<DriveInfo> returnVal = filter(drives, PREINSTALLED_DISK);
for (DriveInfo drive : returnVal)
cache.put(drive.getUuid(), drive);
return returnVal;
}
@SuppressWarnings("unchecked")
@Override
public Iterable<ServerInfo> listNodes() {
return (Iterable<ServerInfo>) client.listServerInfo();
}
@Override
public Iterable<Location> listLocations() {
return ImmutableSet.<Location> of(new LocationImpl(LocationScope.PROVIDER, providerName, providerURI
.toASCIIString(), null));
}
@Override
public ServerInfo getNode(String id) {
return client.getServerInfo(id);
}
@Override
public void destroyNode(String id) {
ServerInfo server = getNode(id);
if (server != null) {
client.stopServer(id);
client.destroyServer(id);
for (Device dev : server.getDevices().values())
client.destroyDrive(dev.getDriveUuid());
}
}
@Override
public void rebootNode(String id) {
client.resetServer(id);
}
@Override
public void resumeNode(String id) {
client.startServer(id);
}
@Override
public void suspendNode(String id) {
client.stopServer(id);
}
}

View File

@ -0,0 +1,140 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.cloudsigma.compute.config;
import static org.jclouds.compute.domain.OsFamily.UBUNTU;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.cloudsigma.CloudSigmaAsyncClient;
import org.jclouds.cloudsigma.CloudSigmaClient;
import org.jclouds.cloudsigma.compute.CloudSigmaComputeServiceAdapter;
import org.jclouds.cloudsigma.compute.functions.ParseOsFamilyVersion64BitFromImageName;
import org.jclouds.cloudsigma.compute.functions.PreinstalledDiskToImage;
import org.jclouds.cloudsigma.compute.functions.ServerInfoToNodeMetadata;
import org.jclouds.cloudsigma.compute.functions.ServerInfoToNodeMetadata.DeviceToVolume;
import org.jclouds.cloudsigma.compute.functions.ServerInfoToNodeMetadata.FindImageForId;
import org.jclouds.cloudsigma.compute.functions.ServerInfoToNodeMetadata.GetImageIdFromServer;
import org.jclouds.cloudsigma.domain.Device;
import org.jclouds.cloudsigma.domain.DriveInfo;
import org.jclouds.cloudsigma.domain.Server;
import org.jclouds.cloudsigma.domain.ServerInfo;
import org.jclouds.cloudsigma.predicates.DriveClaimed;
import org.jclouds.compute.ComputeServiceAdapter;
import org.jclouds.compute.config.ComputeServiceAdapterContextModule;
import org.jclouds.compute.config.JCloudsNativeComputeServiceAdapterContextModule.IdentityFunction;
import org.jclouds.compute.domain.Hardware;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.TemplateBuilder;
import org.jclouds.compute.domain.Volume;
import org.jclouds.compute.domain.os.OsFamilyVersion64Bit;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.compute.suppliers.DefaultLocationSupplier;
import org.jclouds.domain.Location;
import org.jclouds.predicates.RetryablePredicate;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.base.Supplier;
import com.google.common.collect.MapMaker;
import com.google.inject.Injector;
import com.google.inject.Provides;
import com.google.inject.TypeLiteral;
/**
*
* @author Adrian Cole
*/
public class CloudSigmaComputeServiceContextModule
extends
ComputeServiceAdapterContextModule<CloudSigmaClient, CloudSigmaAsyncClient, ServerInfo, Hardware, DriveInfo, Location> {
public CloudSigmaComputeServiceContextModule() {
super(CloudSigmaClient.class, CloudSigmaAsyncClient.class);
}
@Override
protected TemplateBuilder provideTemplate(Injector injector, TemplateBuilder template) {
return template.osFamily(UBUNTU).osVersionMatches("10.04").os64Bit(true).minRam(1024);
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
protected void configure() {
super.configure();
bind(new TypeLiteral<ComputeServiceAdapter<ServerInfo, Hardware, DriveInfo, Location>>() {
}).to(CloudSigmaComputeServiceAdapter.class);
bind(IdentityFunction.class).toInstance(IdentityFunction.INSTANCE);
bind(new TypeLiteral<Supplier<Location>>() {
}).to(DefaultLocationSupplier.class);
bind(new TypeLiteral<Function<ServerInfo, NodeMetadata>>() {
}).to(ServerInfoToNodeMetadata.class);
bind(new TypeLiteral<Function<Hardware, Hardware>>() {
}).to((Class) IdentityFunction.class);
bind(new TypeLiteral<Function<DriveInfo, Image>>() {
}).to(PreinstalledDiskToImage.class);
bind(new TypeLiteral<Function<Location, Location>>() {
}).to((Class) IdentityFunction.class);
bind(new TypeLiteral<Function<Device, Volume>>() {
}).to(DeviceToVolume.class);
bind(new TypeLiteral<Function<Server, String>>() {
}).to(GetImageIdFromServer.class);
bind(new TypeLiteral<Function<String, Image>>() {
}).to(FindImageForId.class);
bind(new TypeLiteral<Function<String, OsFamilyVersion64Bit>>() {
}).to(ParseOsFamilyVersion64BitFromImageName.class);
}
@Provides
@Singleton
protected Map<String, DriveInfo> cache(GetDrive getDrive) {
return new MapMaker().makeComputingMap(getDrive);
}
@Singleton
public static class GetDrive implements Function<String, DriveInfo> {
private final CloudSigmaClient client;
@Inject
public GetDrive(CloudSigmaClient client) {
this.client = client;
}
@Override
public DriveInfo apply(String input) {
return client.getDriveInfo(input);
}
}
@Provides
@Singleton
protected Predicate<DriveInfo> supplyDriveUnclaimed(DriveClaimed driveClaimed,
ComputeServiceConstants.Timeouts timeouts) {
return new RetryablePredicate<DriveInfo>(Predicates.not(driveClaimed), timeouts.nodeRunning, 1000,
TimeUnit.MILLISECONDS);
}
}

View File

@ -0,0 +1,81 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.cloudsigma.compute.functions;
import static com.google.common.base.Predicates.and;
import static com.google.common.base.Predicates.containsPattern;
import static com.google.common.base.Predicates.not;
import static com.google.common.base.Predicates.or;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.inject.Singleton;
import org.jclouds.compute.domain.OsFamily;
import org.jclouds.compute.domain.os.OsFamilyVersion64Bit;
import com.google.common.base.Function;
/**
* Defaults to version null and 64bit, if the operating system is unrecognized and the pattern
* "32bit" isn't in the string.
*
* @author Adrian Cole
*
*/
@Singleton
public class ParseOsFamilyVersion64BitFromImageName implements Function<String, OsFamilyVersion64Bit> {
// ex CentOS 5.5 Linux 64bit Preinstalled System with AppFirst Monitoring
public static final Pattern PATTERN = Pattern.compile("([^ ]+)[^0-9]([0-9.]+) .*");
@Override
public OsFamilyVersion64Bit apply(String input) {
boolean is64Bit = and(not(containsPattern("32bit")),
or(containsPattern("64bit"), not(containsPattern("Windows")))).apply(input);
if (input.contains("Windows")) {
String version = null;
Matcher matcher = Pattern.compile(".*(20[01][0-9] R[1-9]).*").matcher(input);
if (matcher.find()) {
version = matcher.group(1);
} else {
matcher = Pattern.compile(".*(20[01][0-9]).*").matcher(input);
if (matcher.find())
version = matcher.group(1);
}
return new OsFamilyVersion64Bit(OsFamily.WINDOWS, version, is64Bit);
} else {
Matcher matcher = PATTERN.matcher(input);
if (matcher.find()) {
OsFamily fam = OsFamily.fromValue(matcher.group(1).toLowerCase());
String version = matcher.group(2);
switch (fam) {
case UNRECOGNIZED:
return new OsFamilyVersion64Bit(OsFamily.UNRECOGNIZED, null, is64Bit);
case WINDOWS:
}
return new OsFamilyVersion64Bit(fam, version, is64Bit);
} else {
return new OsFamilyVersion64Bit(OsFamily.UNRECOGNIZED, null, is64Bit);
}
}
}
}

View File

@ -0,0 +1,66 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.cloudsigma.compute.functions;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.cloudsigma.domain.DriveInfo;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.ImageBuilder;
import org.jclouds.compute.domain.OperatingSystemBuilder;
import org.jclouds.compute.domain.os.OsFamilyVersion64Bit;
import org.jclouds.domain.Credentials;
import org.jclouds.domain.Location;
import com.google.common.base.Function;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableMap;
/**
* @author Adrian Cole
*/
@Singleton
public class PreinstalledDiskToImage implements Function<DriveInfo, Image> {
private final Supplier<Location> locationSupplier;
private final Function<String, OsFamilyVersion64Bit> imageParser;
@Inject
public PreinstalledDiskToImage(Supplier<Location> locationSupplier,
Function<String, OsFamilyVersion64Bit> imageParser) {
this.locationSupplier = locationSupplier;
this.imageParser = imageParser;
}
@Override
public Image apply(DriveInfo drive) {
if (drive.getName() == null)
return null;
String description = drive.getDescription() != null ? drive.getDescription() : drive.getName();
OperatingSystemBuilder builder = new OperatingSystemBuilder();
OsFamilyVersion64Bit parsed = imageParser.apply(drive.getName());
builder.name(drive.getName()).description(description).is64Bit(parsed.is64Bit).version(parsed.version)
.family(parsed.family);
return new ImageBuilder().ids(drive.getUuid())
.userMetadata(ImmutableMap.<String, String> of("size", drive.getSize() / 1024 / 1024 / 1024 + ""))
.defaultCredentials(new Credentials("cloudsigma", "cloudsigma")).location(locationSupplier.get())
.name(drive.getName()).description(description).operatingSystem(builder.build()).version("").build();
}
}

View File

@ -0,0 +1,183 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.cloudsigma.compute.functions;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.compute.util.ComputeServiceUtils.parseTagFromName;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.cloudsigma.domain.Device;
import org.jclouds.cloudsigma.domain.DriveInfo;
import org.jclouds.cloudsigma.domain.Server;
import org.jclouds.cloudsigma.domain.ServerInfo;
import org.jclouds.cloudsigma.domain.ServerStatus;
import org.jclouds.collect.FindResourceInSet;
import org.jclouds.collect.Memoized;
import org.jclouds.compute.domain.HardwareBuilder;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.NodeMetadataBuilder;
import org.jclouds.compute.domain.NodeState;
import org.jclouds.compute.domain.Processor;
import org.jclouds.compute.domain.Volume;
import org.jclouds.compute.domain.VolumeBuilder;
import org.jclouds.domain.Credentials;
import org.jclouds.domain.Location;
import com.google.common.base.Function;
import com.google.common.base.Supplier;
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 Adrian Cole
*/
@Singleton
public class ServerInfoToNodeMetadata implements Function<ServerInfo, NodeMetadata> {
public static final Map<ServerStatus, NodeState> serverStatusToNodeState = ImmutableMap
.<ServerStatus, NodeState> builder().put(ServerStatus.ACTIVE, NodeState.RUNNING)//
.put(ServerStatus.STOPPED, NodeState.SUSPENDED)//
.put(ServerStatus.PAUSED, NodeState.SUSPENDED)//
.put(ServerStatus.DUMPED, NodeState.PENDING)//
.put(ServerStatus.DEAD, NodeState.TERMINATED)//
.put(ServerStatus.UNRECOGNIZED, NodeState.UNRECOGNIZED)//
.build();
private final Function<Server, String> getImageIdFromServer;
private final Function<String, Image> findImageForId;
private final Map<String, Credentials> credentialStore;
private final Supplier<Location> locationSupplier;
private final Function<Device, Volume> deviceToVolume;
@Inject
ServerInfoToNodeMetadata(Map<String, Credentials> credentialStore, Function<Server, String> getImageIdFromServer,
Function<String, Image> findImageForId, Function<Device, Volume> deviceToVolume,
Supplier<Location> locationSupplier) {
this.credentialStore = checkNotNull(credentialStore, "credentialStore");
this.locationSupplier = checkNotNull(locationSupplier, "locationSupplier");
this.deviceToVolume = checkNotNull(deviceToVolume, "deviceToVolume");
this.findImageForId = checkNotNull(findImageForId, "findImageForId");
this.getImageIdFromServer = checkNotNull(getImageIdFromServer, "getImageIdFromServer");
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public NodeMetadata apply(ServerInfo from) {
NodeMetadataBuilder builder = new NodeMetadataBuilder();
builder.ids(from.getUuid());
builder.name(from.getName());
builder.location(locationSupplier.get());
builder.tag(parseTagFromName(from.getName()));
String imageId = getImageIdFromServer.apply(from);
if (imageId != null) {
Image image = findImageForId.apply(imageId);
if (image != null) {
builder.operatingSystem(image.getOperatingSystem());
}
}
builder.hardware(new HardwareBuilder().ids(from.getUuid())
.processors(ImmutableList.of(new Processor(1, from.getCpu()))).ram(from.getMem())
.volumes((List) ImmutableList.of(Iterables.transform(from.getDevices().values(), deviceToVolume))).build());
builder.state(serverStatusToNodeState.get(from.getStatus()));
builder.publicAddresses(ImmutableSet.<String> of(from.getVnc().getIp()));
builder.privateAddresses(ImmutableSet.<String> of());
builder.credentials(credentialStore.get(from.getUuid()));
// note sudo password!
builder.adminPassword(from.getVnc().getPassword());
return builder.build();
}
@Singleton
public static final class DeviceToVolume implements Function<Device, Volume> {
private final Map<String, DriveInfo> cache;
@Inject
public DeviceToVolume(Map<String, DriveInfo> cache) {
this.cache = checkNotNull(cache, "cache");
}
@Override
public Volume apply(Device input) {
VolumeBuilder builder = new VolumeBuilder();
builder.id(input.getId());
DriveInfo drive = cache.get(input.getDriveUuid());
if (drive != null) {
builder.size(drive.getSize() / 1024 / 1024f);
}
return new VolumeBuilder().durable(true).type(Volume.Type.NAS).build();
}
}
/**
* When we create the boot drive of the server, by convention we set the name to the image it
* came from.
*
* @author Adrian Cole
*
*/
@Singleton
public static class GetImageIdFromServer implements Function<Server, String> {
private final Map<String, DriveInfo> cache;
@Inject
public GetImageIdFromServer(Map<String, DriveInfo> cache) {
this.cache = cache;
}
@Override
public String apply(Server from) {
String imageId = null;
String bootDeviceId = Iterables.get(from.getBootDeviceIds(), 0);
Device bootDevice = from.getDevices().get(bootDeviceId);
if (bootDevice != null) {
try {
imageId = cache.get(bootDevice.getDriveUuid()).getName();
} catch (NullPointerException e) {
}
}
return imageId;
}
}
@Singleton
public static class FindImageForId extends FindResourceInSet<String, Image> {
@Inject
public FindImageForId(@Memoized Supplier<Set<? extends Image>> images) {
super(images);
}
@Override
public boolean matches(String from, Image input) {
return input.getProviderId().equals(from);
}
}
}

View File

@ -25,7 +25,6 @@ import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.cloudsigma.domain.DriveInfo;
import org.jclouds.cloudsigma.functions.ListOfKeyValuesDelimitedByBlankLinesToListOfMaps;
import org.jclouds.http.HttpResponse;
import org.jclouds.http.functions.ReturnStringIf2xx;

View File

@ -25,7 +25,6 @@ import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.cloudsigma.domain.ServerInfo;
import org.jclouds.cloudsigma.functions.ListOfKeyValuesDelimitedByBlankLinesToListOfMaps;
import org.jclouds.http.HttpResponse;
import org.jclouds.http.functions.ReturnStringIf2xx;

View File

@ -25,17 +25,17 @@ import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Properties;
import org.jclouds.cloudsigma.functions.KeyValuesDelimitedByBlankLinesToDriveInfo;
import org.jclouds.cloudsigma.functions.KeyValuesDelimitedByBlankLinesToServerInfo;
import org.jclouds.cloudsigma.functions.ListOfKeyValuesDelimitedByBlankLinesToDriveInfoSet;
import org.jclouds.cloudsigma.functions.ListOfKeyValuesDelimitedByBlankLinesToServerInfoSet;
import org.jclouds.cloudsigma.options.CloneDriveOptions;
import org.jclouds.cloudsigma.binders.BindServerToPlainTextStringTest;
import org.jclouds.cloudsigma.domain.CreateDriveRequest;
import org.jclouds.cloudsigma.domain.Drive;
import org.jclouds.cloudsigma.domain.DriveData;
import org.jclouds.cloudsigma.domain.Server;
import org.jclouds.cloudsigma.functions.KeyValuesDelimitedByBlankLinesToDriveInfo;
import org.jclouds.cloudsigma.functions.KeyValuesDelimitedByBlankLinesToServerInfo;
import org.jclouds.cloudsigma.functions.ListOfKeyValuesDelimitedByBlankLinesToDriveInfoSet;
import org.jclouds.cloudsigma.functions.ListOfKeyValuesDelimitedByBlankLinesToServerInfoSet;
import org.jclouds.cloudsigma.functions.SplitNewlines;
import org.jclouds.cloudsigma.options.CloneDriveOptions;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.filters.BasicAuthentication;
import org.jclouds.http.functions.ReleasePayloadAndReturn;

View File

@ -44,13 +44,13 @@ import org.jclouds.cloudsigma.domain.ServerStatus;
import org.jclouds.cloudsigma.options.CloneDriveOptions;
import org.jclouds.cloudsigma.predicates.DriveClaimed;
import org.jclouds.cloudsigma.util.Servers;
import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.domain.Credentials;
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.net.IPSocket;
import org.jclouds.predicates.InetSocketAddressConnect;
import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.rest.RestContext;
import org.jclouds.rest.RestContextFactory;
import org.jclouds.ssh.ExecResponse;
import org.jclouds.ssh.SshClient;
import org.jclouds.ssh.jsch.config.JschSshClientModule;
@ -112,11 +112,8 @@ public class CloudSigmaClientLiveTest {
public void setupClient() {
setupCredentials();
Properties overrides = setupProperties();
// context = new ComputeServiceContextFactory().createContext(provider,
// ImmutableSet.<Module> of(new Log4JLoggingModule()),
// overrides).getProviderSpecificContext();
context = new RestContextFactory().createContext(provider, ImmutableSet.<Module> of(new Log4JLoggingModule()),
overrides);
context = new ComputeServiceContextFactory().createContext(provider,
ImmutableSet.<Module> of(new Log4JLoggingModule()), overrides).getProviderSpecificContext();
client = context.getApi();
driveNotClaimed = new RetryablePredicate<DriveInfo>(Predicates.not(new DriveClaimed(client)), maxDriveImageTime,
@ -159,9 +156,13 @@ public class CloudSigmaClientLiveTest {
@Test
public void testGetDrive() throws Exception {
for (String driveUUID : client.listDrives()) {
for (String driveUUID : client.listStandardDrives()) {
assert !"".equals(driveUUID);
assertNotNull(client.getDriveInfo(driveUUID));
DriveInfo drive = client.getDriveInfo(driveUUID);
assertNotNull(drive);
assert !drive.getType().equals(DriveType.UNRECOGNIZED) : drive;
if (drive.getType() == DriveType.DISK && drive.getDriveType().contains("preinstalled"))
System.out.println(drive.getName());
}
}

View File

@ -0,0 +1,39 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.cloudsigma.compute;
import org.jclouds.compute.BaseComputeServiceLiveTest;
import org.jclouds.ssh.jsch.config.JschSshClientModule;
import org.testng.annotations.Test;
/**
* @author Adrian Cole
*/
@Test(groups = "live")
public class CloudSigmaComputeServiceLiveTest extends BaseComputeServiceLiveTest {
public CloudSigmaComputeServiceLiveTest() {
provider = "cloudsigma";
}
@Override
protected JschSshClientModule getSshModule() {
return new JschSshClientModule();
}
}

View File

@ -0,0 +1,56 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.cloudsigma.compute;
import org.jclouds.compute.BaseTemplateBuilderLiveTest;
import org.jclouds.compute.domain.OsFamily;
import org.jclouds.compute.domain.os.OsFamilyVersion64Bit;
import org.testng.annotations.Test;
import com.google.common.base.Predicate;
/**
*
* @author Adrian Cole
*/
@Test(groups = "live")
public class CloudSigmaTemplateBuilderLiveTest extends BaseTemplateBuilderLiveTest {
public CloudSigmaTemplateBuilderLiveTest() {
provider = "cloudsigma";
}
@Override
protected Predicate<OsFamilyVersion64Bit> defineUnsupportedOperatingSystems() {
return new Predicate<OsFamilyVersion64Bit>() {
@Override
public boolean apply(OsFamilyVersion64Bit input) {
return ((input.family == OsFamily.RHEL) || //
(input.family == OsFamily.CENTOS && !(input.version.equals("5.5") && input.is64Bit)) || //
(input.family == OsFamily.UBUNTU && !(input.version.matches("10.[01][04]") && input.is64Bit)) || //
(input.family == OsFamily.WINDOWS && !((input.version.equals("2008 R2") && input.is64Bit)
|| (input.version.equals("2008") && !input.is64Bit) || (input.version.equals("2003")))) //
);
}
};
}
}

View File

@ -28,11 +28,7 @@ import org.jclouds.cloudsigma.domain.Device;
import org.jclouds.cloudsigma.domain.DriveMetrics;
import org.jclouds.cloudsigma.domain.NIC;
import org.jclouds.cloudsigma.domain.ServerMetrics;
import org.jclouds.cloudsigma.functions.MapToDevices;
import org.jclouds.cloudsigma.functions.MapToDevices.DeviceToId;
import org.jclouds.cloudsigma.functions.MapToDriveMetrics;
import org.jclouds.cloudsigma.functions.MapToNICs;
import org.jclouds.cloudsigma.functions.MapToServerMetrics;
import org.jclouds.http.HttpResponse;
import org.jclouds.io.Payloads;
import org.testng.annotations.Test;

View File

@ -29,11 +29,7 @@ import org.jclouds.cloudsigma.domain.DriveMetrics;
import org.jclouds.cloudsigma.domain.NIC;
import org.jclouds.cloudsigma.domain.ServerInfo;
import org.jclouds.cloudsigma.domain.ServerMetrics;
import org.jclouds.cloudsigma.functions.MapToDevices;
import org.jclouds.cloudsigma.functions.MapToDevices.DeviceToId;
import org.jclouds.cloudsigma.functions.MapToDriveMetrics;
import org.jclouds.cloudsigma.functions.MapToNICs;
import org.jclouds.cloudsigma.functions.MapToServerMetrics;
import org.jclouds.http.HttpResponse;
import org.jclouds.io.Payloads;
import org.testng.annotations.Test;

View File

@ -34,12 +34,7 @@ import org.jclouds.cloudsigma.domain.ServerInfo;
import org.jclouds.cloudsigma.domain.ServerMetrics;
import org.jclouds.cloudsigma.domain.ServerStatus;
import org.jclouds.cloudsigma.domain.VNC;
import org.jclouds.cloudsigma.functions.ListOfKeyValuesDelimitedByBlankLinesToListOfMaps;
import org.jclouds.cloudsigma.functions.MapToDevices;
import org.jclouds.cloudsigma.functions.MapToDevices.DeviceToId;
import org.jclouds.cloudsigma.functions.MapToDriveMetrics;
import org.jclouds.cloudsigma.functions.MapToNICs;
import org.jclouds.cloudsigma.functions.MapToServerMetrics;
import org.jclouds.util.Utils;
import org.testng.annotations.Test;

View File

@ -0,0 +1,75 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.cloudsigma.functions;
import static com.google.common.collect.Iterables.transform;
import static com.google.common.collect.Lists.newArrayList;
import static org.testng.Assert.assertEquals;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import java.util.Map.Entry;
import org.jclouds.cloudsigma.compute.functions.ParseOsFamilyVersion64BitFromImageName;
import org.jclouds.compute.domain.os.OsFamilyVersion64Bit;
import org.jclouds.json.Json;
import org.jclouds.json.internal.GsonWrapper;
import org.jclouds.util.Utils;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import com.google.common.base.Function;
import com.google.gson.Gson;
import com.google.inject.TypeLiteral;
/**
*
* @author Adrian Cole
*/
@Test(groups = "unit")
public class ParseOsFamilyVersion64BitFromImageNameTest {
Json json = new GsonWrapper(new Gson());
@DataProvider(name = "data")
public Object[][] createData() throws IOException {
InputStream is = ParseOsFamilyVersion64BitFromImageNameTest.class.getResourceAsStream("/osmatches.json");
Map<String, OsFamilyVersion64Bit> values = json.fromJson(Utils.toStringAndClose(is),
new TypeLiteral<Map<String, OsFamilyVersion64Bit>>() {
}.getType());
return newArrayList(
transform(values.entrySet(), new Function<Map.Entry<String, OsFamilyVersion64Bit>, Object[]>() {
@Override
public Object[] apply(Entry<String, OsFamilyVersion64Bit> input) {
return new Object[] { input.getKey(), input.getValue() };
}
})).toArray(new Object[][] {});
}
ParseOsFamilyVersion64BitFromImageName parser = new ParseOsFamilyVersion64BitFromImageName();
@Test(dataProvider = "data")
public void test(String input, OsFamilyVersion64Bit expected) {
assertEquals(parser.apply(input), expected);
}
}

View File

@ -24,7 +24,6 @@ import static org.testng.Assert.assertEquals;
import java.io.InputStream;
import java.util.Set;
import org.jclouds.cloudsigma.functions.SplitNewlines;
import org.jclouds.http.HttpResponse;
import org.jclouds.io.Payloads;
import org.testng.annotations.Test;

View File

@ -0,0 +1,140 @@
{
"Ubuntu 10.04 Server Edition Linux 64bit with Plesk": {
"family": "UBUNTU",
"version": "10.04",
"is64Bit": true
},
"CentOS 5.5 Linux 64bit Preinstalled System": {
"family": "CENTOS",
"version": "5.5",
"is64Bit": true
},
"Windows Server Standard 2008 R2 64bit English": {
"family": "WINDOWS",
"version": "2008 R2",
"is64Bit": true
},
"Ubuntu 10.04 Server Edition Linux 64bit": {
"family": "UBUNTU",
"version": "10.04",
"is64Bit": true
},
"Windows Server 2008 Standard 32bit English": {
"family": "WINDOWS",
"version": "2008",
"is64Bit": false
},
"Windows Server 2008 Standard 32bit English pub": {
"family": "WINDOWS",
"version": "2008",
"is64Bit": false
},
"Fedora 14 Linux 64bit Preinstalled System": {
"family": "FEDORA",
"version": "14",
"is64Bit": true
},
"CentOS 5.5 Linux 64bit Preinstalled System with AppFirst Monitoring pub": {
"family": "CENTOS",
"version": "5.5",
"is64Bit": true
},
"Ubuntu 10.10 Server Edition LAMP Linux 64bit Preinstalled System": {
"family": "UBUNTU",
"version": "10.10",
"is64Bit": true
},
"Ubuntu 10.10 Server Edition Linux 64bit Preinstalled System": {
"family": "UBUNTU",
"version": "10.10",
"is64Bit": true
},
"Windows Server Web 2008 R2 64bit English": {
"family": "WINDOWS",
"version": "2008 R2",
"is64Bit": true
},
"SQL Server Standard 2008 R2 - Windows Server Standard 2008 R2 - 64bit English": {
"family": "WINDOWS",
"version": "2008 R2",
"is64Bit": true
},
"Ubuntu 10.10 Desktop Edition 64bit Preinstalled System": {
"family": "UBUNTU",
"version": "10.10",
"is64Bit": true
},
"Ubuntu 10.04 Desktop Edition Linux 64bit Preinstalled System": {
"family": "UBUNTU",
"version": "10.04",
"is64Bit": true
},
"Debian 5.0 Preinstalled": {
"family": "DEBIAN",
"version": "5.0",
"is64Bit": true
},
"pfSense 2.0 BETA4-20101127-031119 Preinstalled System": {
"family": "UNRECOGNIZED",
"version": null,
"is64Bit": true
},
"FreeBSD 8.1 Preinstalled Base System": {
"family": "FREEBSD",
"version": "8.1",
"is64Bit": true
},
"CentOS 5.5 Linux 64bit Preinstalled System with AppFirst Monitoring": {
"family": "CENTOS",
"version": "5.5",
"is64Bit": true
},
"Fedora 13 Linux 64bit Preinstalled System": {
"family": "FEDORA",
"version": "13",
"is64Bit": true
},
"Windows Server 2003 Standard 32bit English": {
"family": "WINDOWS",
"version": "2003",
"is64Bit": false
},
"Windows Server 2003 Standard 64bit English": {
"family": "WINDOWS",
"version": "2003",
"is64Bit": true
},
"Debian 5.0 Preinstalled without X": {
"family": "DEBIAN",
"version": "5.0",
"is64Bit": true
}
}