You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jclouds.apache.org by na...@apache.org on 2014/10/27 16:59:28 UTC

git commit: JCLOUDS-761: Delete disk if image operation fails in ElasticStack

Repository: jclouds
Updated Branches:
  refs/heads/master 2a5928b55 -> c73ed64fd


JCLOUDS-761: Delete disk if image operation fails in ElasticStack


Project: http://git-wip-us.apache.org/repos/asf/jclouds/repo
Commit: http://git-wip-us.apache.org/repos/asf/jclouds/commit/c73ed64f
Tree: http://git-wip-us.apache.org/repos/asf/jclouds/tree/c73ed64f
Diff: http://git-wip-us.apache.org/repos/asf/jclouds/diff/c73ed64f

Branch: refs/heads/master
Commit: c73ed64fd021fb64e2c7be7f00c2e3248ea5cc0f
Parents: 2a5928b
Author: Ignasi Barrera <na...@apache.org>
Authored: Mon Oct 27 10:29:49 2014 +0100
Committer: Ignasi Barrera <na...@apache.org>
Committed: Mon Oct 27 16:58:03 2014 +0100

----------------------------------------------------------------------
 .../ElasticStackComputeServiceAdapter.java      |   9 +-
 .../ElasticStackComputeServiceAdapterTest.java  | 114 +++++++++++++++++++
 2 files changed, 122 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jclouds/blob/c73ed64f/apis/elasticstack/src/main/java/org/jclouds/elasticstack/compute/ElasticStackComputeServiceAdapter.java
----------------------------------------------------------------------
diff --git a/apis/elasticstack/src/main/java/org/jclouds/elasticstack/compute/ElasticStackComputeServiceAdapter.java b/apis/elasticstack/src/main/java/org/jclouds/elasticstack/compute/ElasticStackComputeServiceAdapter.java
index 9c04e8b..53894d5 100644
--- a/apis/elasticstack/src/main/java/org/jclouds/elasticstack/compute/ElasticStackComputeServiceAdapter.java
+++ b/apis/elasticstack/src/main/java/org/jclouds/elasticstack/compute/ElasticStackComputeServiceAdapter.java
@@ -118,7 +118,14 @@ public class ElasticStackComputeServiceAdapter implements
       }
 
       logger.debug(">> imaging boot drive source(%s)", template.getImage().getId());
-      client.imageDrive(template.getImage().getId(), drive.getUuid(), ImageConversionType.GUNZIP);
+      try {
+         client.imageDrive(template.getImage().getId(), drive.getUuid(), ImageConversionType.GUNZIP);
+      } catch (IllegalStateException ex) {
+         logger.debug(">> could not image drive(%s). Cleaning up resources. [%s]", drive.getUuid(), ex.getMessage());
+         client.destroyDrive(drive.getUuid());
+         throw ex;
+      }
+
       boolean ready = driveNotClaimed.apply(drive);
       if (!ready) {
          client.destroyDrive(drive.getUuid());

http://git-wip-us.apache.org/repos/asf/jclouds/blob/c73ed64f/apis/elasticstack/src/test/java/org/jclouds/elasticstack/compute/ElasticStackComputeServiceAdapterTest.java
----------------------------------------------------------------------
diff --git a/apis/elasticstack/src/test/java/org/jclouds/elasticstack/compute/ElasticStackComputeServiceAdapterTest.java b/apis/elasticstack/src/test/java/org/jclouds/elasticstack/compute/ElasticStackComputeServiceAdapterTest.java
new file mode 100644
index 0000000..70ce180
--- /dev/null
+++ b/apis/elasticstack/src/test/java/org/jclouds/elasticstack/compute/ElasticStackComputeServiceAdapterTest.java
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF 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.elasticstack.compute;
+
+import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.expectLastCall;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+
+import java.util.Map;
+import java.util.UUID;
+
+import org.easymock.EasyMock;
+import org.jclouds.compute.domain.Hardware;
+import org.jclouds.compute.domain.HardwareBuilder;
+import org.jclouds.compute.domain.Image;
+import org.jclouds.compute.domain.Image.Status;
+import org.jclouds.compute.domain.ImageBuilder;
+import org.jclouds.compute.domain.OperatingSystem;
+import org.jclouds.compute.domain.Processor;
+import org.jclouds.compute.domain.Template;
+import org.jclouds.compute.domain.Volume.Type;
+import org.jclouds.compute.domain.VolumeBuilder;
+import org.jclouds.compute.domain.internal.TemplateImpl;
+import org.jclouds.compute.options.TemplateOptions;
+import org.jclouds.domain.LocationBuilder;
+import org.jclouds.domain.LocationScope;
+import org.jclouds.elasticstack.ElasticStackApi;
+import org.jclouds.elasticstack.domain.DriveInfo;
+import org.jclouds.elasticstack.domain.DriveMetrics;
+import org.jclouds.elasticstack.domain.ImageConversionType;
+import org.jclouds.elasticstack.domain.WellKnownImage;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+import org.testng.collections.Maps;
+
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.common.base.Supplier;
+import com.google.common.base.Suppliers;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+import com.google.common.util.concurrent.MoreExecutors;
+
+@Test(groups = "unit", testName = "ElasticStackComputeServiceAdapterTest")
+public class ElasticStackComputeServiceAdapterTest {
+
+   private Image image;
+   private Hardware hardware;
+   private Template template;
+
+   @BeforeMethod
+   public void setup() {
+      image = new ImageBuilder().ids("mock").operatingSystem(OperatingSystem.builder().description("mock").build())
+            .status(Status.AVAILABLE).build();
+      hardware = new HardwareBuilder().ids("mock").volume(new VolumeBuilder().type(Type.LOCAL).size(1.0f).build())
+            .processor(new Processor(1.0, 1.0)).build();
+      template = new TemplateImpl(image, hardware, new LocationBuilder().id("mock").scope(LocationScope.PROVIDER)
+            .description("mock").build(), TemplateOptions.NONE);
+   }
+
+   @Test(expectedExceptions = IllegalStateException.class, expectedExceptionsMessageRegExp = "imageDrive call failed")
+   public void testDiskIsDestroyedIfImageFails() {
+      Supplier<Map<String, WellKnownImage>> preInstalledImageSupplier = Suppliers.ofInstance(Maps
+            .<String, WellKnownImage> newHashMap());
+      LoadingCache<String, DriveInfo> driveCache = CacheBuilder.newBuilder().build(
+            new CacheLoader<String, DriveInfo>() {
+               @Override
+               public DriveInfo load(String key) throws Exception {
+                  throw new IllegalStateException("cache should not be used");
+               }
+            });
+
+      ElasticStackApi api = EasyMock.createMock(ElasticStackApi.class);
+      Predicate<DriveInfo> driveNotClaimed = Predicates.alwaysTrue();
+      DriveInfo mockDrive = new DriveInfo.Builder().uuid(UUID.randomUUID().toString()).name("mock")
+            .metrics(new DriveMetrics.Builder().build()).build();
+
+      expect(api.createDrive(anyObject(DriveInfo.class))).andReturn(mockDrive);
+      api.imageDrive(image.getId(), mockDrive.getUuid(), ImageConversionType.GUNZIP);
+      // Set a custom exception message to make sure the exception is thrown at the right point
+      expectLastCall().andThrow(new IllegalStateException("imageDrive call failed"));
+      api.destroyDrive(mockDrive.getUuid());
+      expectLastCall();
+
+      replay(api);
+
+      ElasticStackComputeServiceAdapter adapter = new ElasticStackComputeServiceAdapter(api, driveNotClaimed,
+            preInstalledImageSupplier, driveCache, "12345678", MoreExecutors.sameThreadExecutor());
+
+      try {
+         adapter.createNodeWithGroupEncodedIntoName("mock-group", "mock-name", template);
+      } catch (IllegalStateException ex) {
+         verify(api);
+         throw ex;
+      }
+   }
+}