org.jclouds.cloudsigma.compute.CloudSigmaComputeServiceAdapter Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of cloudsigma Show documentation
Show all versions of cloudsigma Show documentation
ComputeService binding to the CloudSigma API
The newest version!
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you 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.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.Iterables.contains;
import static com.google.common.collect.Iterables.filter;
import static org.jclouds.concurrent.FutureIterables.transformParallel;
import javax.annotation.Resource;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.Constants;
import org.jclouds.cloudsigma.CloudSigmaClient;
import org.jclouds.cloudsigma.compute.options.CloudSigmaTemplateOptions;
import org.jclouds.cloudsigma.domain.AffinityType;
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.Location;
import org.jclouds.domain.LoginCredentials;
import org.jclouds.logging.Logger;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSet.Builder;
import com.google.common.collect.Iterables;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.UncheckedExecutionException;
/**
* defines the connection between the {@link CloudSigmaClient} implementation
* and the jclouds {@link ComputeService}
*
*/
@Singleton
public class CloudSigmaComputeServiceAdapter implements
ComputeServiceAdapter {
private static final Predicate PREINSTALLED_DISK = Predicates.and(Predicates.notNull(),
new Predicate() {
@Override
public boolean apply(DriveInfo drive) {
return drive.getType().equals(DriveType.DISK) && drive.getDriveType().contains("preinstalled");
}
});
private final CloudSigmaClient client;
private final Predicate driveNotClaimed;
private final String defaultVncPassword;
private final LoadingCache cache;
private final ListeningExecutorService userExecutor;
@Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL;
@Inject
public CloudSigmaComputeServiceAdapter(CloudSigmaClient client, Predicate driveNotClaimed,
@Named(CloudSigmaConstants.PROPERTY_VNC_PASSWORD) String defaultVncPassword,
LoadingCache cache, @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor) {
this.client = checkNotNull(client, "client");
this.driveNotClaimed = checkNotNull(driveNotClaimed, "driveNotClaimed");
this.defaultVncPassword = checkNotNull(defaultVncPassword, "defaultVncPassword");
checkArgument(defaultVncPassword.length() <= 8, "vnc passwords should be less that 8 characters!");
this.cache = checkNotNull(cache, "cache");
this.userExecutor = checkNotNull(userExecutor, "userExecutor");
}
@Override
public NodeAndInitialCredentials createNodeWithGroupEncodedIntoName(String tag, String name, Template template) {
long bootSize = (long) (template.getHardware().getVolumes().get(0).getSize() * 1024 * 1024 * 1024l);
AffinityType affinityType = AffinityType.HDD;
if (template.getOptions() instanceof CloudSigmaTemplateOptions) {
CloudSigmaTemplateOptions options = CloudSigmaTemplateOptions.class.cast(template.getOptions());
affinityType = options.getDiskDriveAffinity();
}
logger.debug(">> imaging boot drive source(%s) bytes(%d) affinityType(%s)",
template.getImage().getId(), bootSize, affinityType);
DriveInfo drive = client.cloneDrive(template.getImage().getId(), template.getImage().getId(),
new CloneDriveOptions().size(bootSize).affinity(affinityType));
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());
return new NodeAndInitialCredentials(from, from.getUuid(), LoginCredentials.builder()
.password(defaultVncPassword).authenticateSudo(true).build());
}
@Override
public Iterable listHardwareProfiles() {
Builder hardware = ImmutableSet.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) cpu / 100;
String id = String.format("cpu=%f,ram=%s,disk=%f", cpu, ram, size);
hardware.add(new HardwareBuilder().supportsImage(new Predicate() {
@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))).hypervisor("kvm")
.volumes(ImmutableList.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 listImages() {
return FluentIterable.from(transformParallel(client.listStandardDrives(),
new Function>() {
@Override
public ListenableFuture apply(String input) {
try {
return Futures.immediateFuture(cache.getUnchecked(input));
} catch (CacheLoader.InvalidCacheLoadException e) {
logger.debug("drive %s not found", input);
} catch (UncheckedExecutionException e) {
logger.warn(e, "error finding drive %s: %s", input, e.getMessage());
}
return Futures.immediateFuture(null);
}
@Override
public String toString() {
return "seedDriveCache()";
}
}, userExecutor, null, logger, "drives")).filter(PREINSTALLED_DISK);
}
@SuppressWarnings("unchecked")
@Override
public Iterable listNodes() {
return (Iterable) client.listServerInfo();
}
@Override
public Iterable listNodesByIds(final Iterable ids) {
return filter(listNodes(), new Predicate() {
@Override
public boolean apply(ServerInfo server) {
return contains(ids, server.getUuid());
}
});
}
@Override
public Iterable listLocations() {
// Not using the adapter to determine locations
return ImmutableSet.of();
}
@Override
public ServerInfo getNode(String id) {
return client.getServerInfo(id);
}
@Override
public DriveInfo getImage(String id) {
return client.getDriveInfo(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);
}
}