From 88400f64415cfcdca340bece74004b28aef27dd5 Mon Sep 17 00:00:00 2001 From: andreisavu Date: Sun, 15 Jan 2012 20:06:02 +0200 Subject: [PATCH] Add TemplateOptions to create SSD Drives on CloudSigma providers --- .../CloudSigmaComputeServiceAdapter.java | 16 +- .../CloudSigmaTemplateBuilderImpl.java | 46 +++ ...CloudSigmaComputeServiceContextModule.java | 11 + .../functions/ServerInfoToNodeMetadata.java | 5 +- .../options/CloudSigmaTemplateOptions.java | 349 ++++++++++++++++++ ...loudSigmaZurichComputeServiceLiveTest.java | 48 +++ 6 files changed, 468 insertions(+), 7 deletions(-) create mode 100644 apis/cloudsigma/src/main/java/org/jclouds/cloudsigma/compute/CloudSigmaTemplateBuilderImpl.java create mode 100644 apis/cloudsigma/src/main/java/org/jclouds/cloudsigma/compute/options/CloudSigmaTemplateOptions.java diff --git a/apis/cloudsigma/src/main/java/org/jclouds/cloudsigma/compute/CloudSigmaComputeServiceAdapter.java b/apis/cloudsigma/src/main/java/org/jclouds/cloudsigma/compute/CloudSigmaComputeServiceAdapter.java index d67a7986be..6886561e46 100644 --- a/apis/cloudsigma/src/main/java/org/jclouds/cloudsigma/compute/CloudSigmaComputeServiceAdapter.java +++ b/apis/cloudsigma/src/main/java/org/jclouds/cloudsigma/compute/CloudSigmaComputeServiceAdapter.java @@ -32,6 +32,8 @@ 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; @@ -69,7 +71,7 @@ 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 @@ -109,9 +111,15 @@ public class CloudSigmaComputeServiceAdapter implements @Override public NodeAndInitialCredentials createNodeWithGroupEncodedIntoName(String tag, String name, Template template) { 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); + 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)); + new CloneDriveOptions().size(bootSize).affinity(affinityType)); boolean success = driveNotClaimed.apply(drive); logger.debug("<< image(%s) complete(%s)", drive.getUuid(), success); if (!success) { @@ -152,7 +160,7 @@ public class CloudSigmaComputeServiceAdapter implements } }).ids(id).ram(ram).processors(ImmutableList.of(new Processor(1, cpu))) - .volumes(ImmutableList. of(new VolumeImpl(size, true, true))).build()); + .volumes(ImmutableList.of(new VolumeImpl(size, true, true))).build()); } return hardware.build(); } diff --git a/apis/cloudsigma/src/main/java/org/jclouds/cloudsigma/compute/CloudSigmaTemplateBuilderImpl.java b/apis/cloudsigma/src/main/java/org/jclouds/cloudsigma/compute/CloudSigmaTemplateBuilderImpl.java new file mode 100644 index 0000000000..57a31f2d05 --- /dev/null +++ b/apis/cloudsigma/src/main/java/org/jclouds/cloudsigma/compute/CloudSigmaTemplateBuilderImpl.java @@ -0,0 +1,46 @@ +/** + * 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 com.google.common.base.Supplier; +import org.jclouds.collect.Memoized; +import org.jclouds.compute.domain.Hardware; +import org.jclouds.compute.domain.Image; +import org.jclouds.compute.domain.TemplateBuilder; +import org.jclouds.compute.domain.internal.TemplateBuilderImpl; +import org.jclouds.compute.options.TemplateOptions; +import org.jclouds.domain.Location; + +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Provider; +import java.util.Set; + +/** + * @author Andrei Savu + */ +public class CloudSigmaTemplateBuilderImpl extends TemplateBuilderImpl { + @Inject + public CloudSigmaTemplateBuilderImpl(@Memoized Supplier> locations, + @Memoized Supplier> images, @Memoized Supplier> hardwares, + Supplier defaultLocation2, @Named("DEFAULT") Provider optionsProvider, + @Named("DEFAULT") Provider defaultTemplateProvider) { + super(locations, images, hardwares, defaultLocation2, optionsProvider, defaultTemplateProvider); + } +} diff --git a/apis/cloudsigma/src/main/java/org/jclouds/cloudsigma/compute/config/CloudSigmaComputeServiceContextModule.java b/apis/cloudsigma/src/main/java/org/jclouds/cloudsigma/compute/config/CloudSigmaComputeServiceContextModule.java index 730ec4f3a3..29d62af92b 100644 --- a/apis/cloudsigma/src/main/java/org/jclouds/cloudsigma/compute/config/CloudSigmaComputeServiceContextModule.java +++ b/apis/cloudsigma/src/main/java/org/jclouds/cloudsigma/compute/config/CloudSigmaComputeServiceContextModule.java @@ -26,12 +26,14 @@ 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.CloudSigmaTemplateBuilderImpl; 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.compute.options.CloudSigmaTemplateOptions; import org.jclouds.cloudsigma.domain.Device; import org.jclouds.cloudsigma.domain.DriveInfo; import org.jclouds.cloudsigma.domain.Server; @@ -46,6 +48,7 @@ import org.jclouds.compute.domain.OsFamily; import org.jclouds.compute.domain.OsFamilyVersion64Bit; import org.jclouds.compute.domain.TemplateBuilder; import org.jclouds.compute.domain.Volume; +import org.jclouds.compute.options.TemplateOptions; import org.jclouds.compute.reference.ComputeServiceConstants; import org.jclouds.domain.Location; import org.jclouds.functions.IdentityFunction; @@ -104,6 +107,8 @@ public class CloudSigmaComputeServiceContextModule }).to(ParseOsFamilyVersion64BitFromImageName.class); bind(new TypeLiteral>() { }).to(OnlyLocationOrFirstZone.class); + bind(TemplateBuilder.class) + .to(CloudSigmaTemplateBuilderImpl.class); } @Provides @@ -134,4 +139,10 @@ public class CloudSigmaComputeServiceContextModule return new RetryablePredicate(Predicates.not(driveClaimed), timeouts.nodeRunning, 1000, TimeUnit.MILLISECONDS); } + + @Provides + @Singleton + protected TemplateOptions templateOptions() { + return new CloudSigmaTemplateOptions(); + } } \ No newline at end of file diff --git a/apis/cloudsigma/src/main/java/org/jclouds/cloudsigma/compute/functions/ServerInfoToNodeMetadata.java b/apis/cloudsigma/src/main/java/org/jclouds/cloudsigma/compute/functions/ServerInfoToNodeMetadata.java index 4c433c92c4..7e6bfc88dd 100644 --- a/apis/cloudsigma/src/main/java/org/jclouds/cloudsigma/compute/functions/ServerInfoToNodeMetadata.java +++ b/apis/cloudsigma/src/main/java/org/jclouds/cloudsigma/compute/functions/ServerInfoToNodeMetadata.java @@ -21,7 +21,6 @@ package org.jclouds.cloudsigma.compute.functions; import static com.google.common.base.Preconditions.checkNotNull; import static org.jclouds.compute.util.ComputeServiceUtils.parseGroupFromName; -import java.util.List; import java.util.Map; import java.util.Set; @@ -102,7 +101,7 @@ public class ServerInfoToNodeMetadata implements Function of(from.getVnc().getIp())); builder.privateAddresses(ImmutableSet. of()); @@ -133,7 +132,7 @@ public class ServerInfoToNodeMetadata implements Function userMetadata) { + CloudSigmaTemplateOptions options = new CloudSigmaTemplateOptions(); + return CloudSigmaTemplateOptions.class.cast(options.userMetadata(userMetadata)); + } + + @Deprecated + public static CloudSigmaTemplateOptions overrideLoginUserWith(String user) { + CloudSigmaTemplateOptions options = new CloudSigmaTemplateOptions(); + return options.overrideLoginUserWith(user); + } + + public static CloudSigmaTemplateOptions overrideLoginUser(String user) { + CloudSigmaTemplateOptions options = new CloudSigmaTemplateOptions(); + return options.overrideLoginUser(user); + } + + public static CloudSigmaTemplateOptions overrideLoginPassword(String password) { + CloudSigmaTemplateOptions options = new CloudSigmaTemplateOptions(); + return options.overrideLoginPassword(password); + } + + public static CloudSigmaTemplateOptions overrideLoginPrivateKey(String privateKey) { + CloudSigmaTemplateOptions options = new CloudSigmaTemplateOptions(); + return options.overrideLoginPrivateKey(privateKey); + } + + public static CloudSigmaTemplateOptions overrideAuthenticateSudo(boolean authenticateSudo) { + CloudSigmaTemplateOptions options = new CloudSigmaTemplateOptions(); + return options.overrideAuthenticateSudo(authenticateSudo); + } + + @Deprecated + public static CloudSigmaTemplateOptions overrideLoginCredentialWith(String credential) { + CloudSigmaTemplateOptions options = new CloudSigmaTemplateOptions(); + return options.overrideLoginCredentialWith(credential); + } + + @Deprecated + public static CloudSigmaTemplateOptions overrideCredentialsWith(Credentials credentials) { + CloudSigmaTemplateOptions options = new CloudSigmaTemplateOptions(); + return options.overrideCredentialsWith(credentials); + } + + public static CloudSigmaTemplateOptions overrideLoginCredentials(LoginCredentials credentials) { + CloudSigmaTemplateOptions options = new CloudSigmaTemplateOptions(); + return options.overrideLoginCredentials(credentials); + } + } + + // methods that only facilitate returning the correct object type + + /** + * {@inheritDoc} + */ + @Override + public CloudSigmaTemplateOptions blockOnPort(int port, int seconds) { + return CloudSigmaTemplateOptions.class.cast(super.blockOnPort(port, seconds)); + } + + /** + * {@inheritDoc} + */ + @Override + public CloudSigmaTemplateOptions inboundPorts(int... ports) { + return CloudSigmaTemplateOptions.class.cast(super.inboundPorts(ports)); + } + + /** + * {@inheritDoc} + */ + @Override + public CloudSigmaTemplateOptions authorizePublicKey(String publicKey) { + return CloudSigmaTemplateOptions.class.cast(super.authorizePublicKey(publicKey)); + } + + /** + * {@inheritDoc} + */ + @Override + public CloudSigmaTemplateOptions installPrivateKey(String privateKey) { + return CloudSigmaTemplateOptions.class.cast(super.installPrivateKey(privateKey)); + } + + /** + * {@inheritDoc} + */ + @Deprecated + @Override + public CloudSigmaTemplateOptions runScript(Payload script) { + return CloudSigmaTemplateOptions.class.cast(super.runScript(script)); + } + + /** + * {@inheritDoc} + */ + @Override + public CloudSigmaTemplateOptions blockUntilRunning(boolean blockUntilRunning) { + return CloudSigmaTemplateOptions.class.cast(super.blockUntilRunning(blockUntilRunning)); + } + + /** + * {@inheritDoc} + */ + @Override + public CloudSigmaTemplateOptions dontAuthorizePublicKey() { + return CloudSigmaTemplateOptions.class.cast(super.dontAuthorizePublicKey()); + } + + /** + * {@inheritDoc} + */ + @Override + public CloudSigmaTemplateOptions nameTask(String name) { + return CloudSigmaTemplateOptions.class.cast(super.nameTask(name)); + } + + /** + * {@inheritDoc} + */ + @Override + public CloudSigmaTemplateOptions runAsRoot(boolean runAsRoot) { + return CloudSigmaTemplateOptions.class.cast(super.runAsRoot(runAsRoot)); + } + + /** + * {@inheritDoc} + */ + @Override + public CloudSigmaTemplateOptions runScript(Statement script) { + return CloudSigmaTemplateOptions.class.cast(super.runScript(script)); + } + + /** + * {@inheritDoc} + */ + @Deprecated + @Override + public CloudSigmaTemplateOptions overrideCredentialsWith(Credentials overridingCredentials) { + return CloudSigmaTemplateOptions.class.cast(super.overrideCredentialsWith(overridingCredentials)); + } + + /** + * {@inheritDoc} + */ + @Deprecated + @Override + public CloudSigmaTemplateOptions overrideLoginUserWith(String loginUser) { + return CloudSigmaTemplateOptions.class.cast(super.overrideLoginUserWith(loginUser)); + } + + /** + * {@inheritDoc} + */ + @Deprecated + @Override + public CloudSigmaTemplateOptions overrideLoginCredentialWith(String loginCredential) { + return CloudSigmaTemplateOptions.class.cast(super.overrideLoginCredentialWith(loginCredential)); + } + + /** + * {@inheritDoc} + */ + @Override + public CloudSigmaTemplateOptions overrideLoginCredentials(LoginCredentials overridingCredentials) { + return CloudSigmaTemplateOptions.class.cast(super.overrideLoginCredentials(overridingCredentials)); + } + + /** + * {@inheritDoc} + */ + @Override + public CloudSigmaTemplateOptions overrideLoginPassword(String password) { + return CloudSigmaTemplateOptions.class.cast(super.overrideLoginPassword(password)); + } + + /** + * {@inheritDoc} + */ + @Override + public CloudSigmaTemplateOptions overrideLoginPrivateKey(String privateKey) { + return CloudSigmaTemplateOptions.class.cast(super.overrideLoginPrivateKey(privateKey)); + } + + /** + * {@inheritDoc} + */ + @Override + public CloudSigmaTemplateOptions overrideLoginUser(String loginUser) { + return CloudSigmaTemplateOptions.class.cast(super.overrideLoginUser(loginUser)); + } + + /** + * {@inheritDoc} + */ + @Override + public CloudSigmaTemplateOptions overrideAuthenticateSudo(boolean authenticateSudo) { + return CloudSigmaTemplateOptions.class.cast(super.overrideAuthenticateSudo(authenticateSudo)); + } + + /** + * {@inheritDoc} + */ + @Override + public CloudSigmaTemplateOptions userMetadata(Map userMetadata) { + return CloudSigmaTemplateOptions.class.cast(super.userMetadata(userMetadata)); + } + + /** + * {@inheritDoc} + */ + @Override + public CloudSigmaTemplateOptions userMetadata(String key, String value) { + return CloudSigmaTemplateOptions.class.cast(super.userMetadata(key, value)); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + + CloudSigmaTemplateOptions that = (CloudSigmaTemplateOptions) o; + + if (diskDriveAffinity != that.diskDriveAffinity) return false; + + return true; + } + + @Override + public int hashCode() { + int result = super.hashCode(); + result = 31 * result + (diskDriveAffinity != null ? diskDriveAffinity.hashCode() : 0); + return result; + } + + @Override + public String toString() { + return "CloudSigmaTemplateOptions{" + + "diskDriveAffinity=" + diskDriveAffinity + + '}'; + } +} diff --git a/providers/cloudsigma-zrh/src/test/java/org/jclouds/cloudsigma/compute/CloudSigmaZurichComputeServiceLiveTest.java b/providers/cloudsigma-zrh/src/test/java/org/jclouds/cloudsigma/compute/CloudSigmaZurichComputeServiceLiveTest.java index 02213e0ac3..fd25db453e 100644 --- a/providers/cloudsigma-zrh/src/test/java/org/jclouds/cloudsigma/compute/CloudSigmaZurichComputeServiceLiveTest.java +++ b/providers/cloudsigma-zrh/src/test/java/org/jclouds/cloudsigma/compute/CloudSigmaZurichComputeServiceLiveTest.java @@ -18,8 +18,26 @@ */ package org.jclouds.cloudsigma.compute; +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.ServerInfo; +import org.jclouds.compute.RunNodesException; +import org.jclouds.compute.domain.NodeMetadata; +import org.jclouds.compute.domain.Template; +import org.jclouds.compute.domain.TemplateBuilder; import org.testng.annotations.Test; +import java.util.Set; + +import static com.google.common.collect.Iterables.contains; +import static com.google.common.collect.Iterables.get; +import static org.jclouds.cloudsigma.compute.options.CloudSigmaTemplateOptions.Builder.diskDriveAffinity; +import static org.jclouds.compute.predicates.NodePredicates.inGroup; +import static org.testng.Assert.assertTrue; + /** * * @author Adrian Cole @@ -31,4 +49,34 @@ public class CloudSigmaZurichComputeServiceLiveTest extends CloudSigmaComputeSer provider = "cloudsigma-zrh"; } + @Test + public void testStartNodeWithSSD() throws RunNodesException { + String group = this.group + "-ssd"; + + TemplateBuilder builder = client.templateBuilder(); + assert builder instanceof CloudSigmaTemplateBuilderImpl; + + Template template = builder.options(diskDriveAffinity(AffinityType.SSD)).build(); + assert template.getOptions() instanceof CloudSigmaTemplateOptions; + + try { + Set nodes = client.createNodesInGroup(group, 1, template); + NodeMetadata node = get(nodes, 0); + + CloudSigmaClient api = CloudSigmaClient.class.cast(client.getContext() + .getProviderSpecificContext().getApi()); + + // Note: I wanted to use node.getHardware().getVolumes() but there is no + // way to go from a Volume to a DriveInfo + + ServerInfo serverInfo = api.getServerInfo(node.getId()); + Device rootDevice = get(serverInfo.getDevices().values(), 0); + DriveInfo driveInfo = api.getDriveInfo(rootDevice.getDriveUuid()); + assertTrue(contains(driveInfo.getTags(), "affinity:ssd")); + + } finally { + client.destroyNodesMatching(inGroup(group)); + } + } + }