Repository: jclouds Updated Branches: refs/heads/master 042222b64 -> 962980cd9
JCLOUDS-1001. Add preemptible support to the Google Compute provider. The Google Compute provider should support preemptible instances. Project: http://git-wip-us.apache.org/repos/asf/jclouds/repo Commit: http://git-wip-us.apache.org/repos/asf/jclouds/commit/962980cd Tree: http://git-wip-us.apache.org/repos/asf/jclouds/tree/962980cd Diff: http://git-wip-us.apache.org/repos/asf/jclouds/diff/962980cd Branch: refs/heads/master Commit: 962980cd9d22fc2e7b54cab45a4d17550d1fb137 Parents: 042222b Author: Michael Wilson <[email protected]> Authored: Tue Sep 15 17:00:01 2015 -0700 Committer: Ignasi Barrera <[email protected]> Committed: Mon Sep 21 22:17:18 2015 +0200 ---------------------------------------------------------------------- providers/google-compute-engine/.gitignore | 1 + .../GoogleComputeEngineServiceAdapter.java | 20 ++++++++++++++++++-- .../GoogleComputeEngineTemplateOptions.java | 17 +++++++++++++++++ .../googlecomputeengine/domain/Instance.java | 9 ++++++--- .../features/InstanceApi.java | 4 +++- .../GoogleComputeEngineServiceLiveTest.java | 5 +++-- .../features/InstanceApiLiveTest.java | 9 +++++++-- .../features/InstanceApiMockTest.java | 6 +++--- .../parse/ParseInstanceTest.java | 2 +- .../src/test/resources/instance_get.json | 3 ++- .../src/test/resources/instance_insert_2.json | 5 +++++ .../test/resources/instance_insert_full.json | 3 ++- .../src/test/resources/instance_insert_ssd.json | 5 +++++ .../src/test/resources/instance_list.json | 3 ++- 14 files changed, 75 insertions(+), 17 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/jclouds/blob/962980cd/providers/google-compute-engine/.gitignore ---------------------------------------------------------------------- diff --git a/providers/google-compute-engine/.gitignore b/providers/google-compute-engine/.gitignore new file mode 100644 index 0000000..c71ea97 --- /dev/null +++ b/providers/google-compute-engine/.gitignore @@ -0,0 +1 @@ +/.apt_generated/ http://git-wip-us.apache.org/repos/asf/jclouds/blob/962980cd/providers/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/GoogleComputeEngineServiceAdapter.java ---------------------------------------------------------------------- diff --git a/providers/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/GoogleComputeEngineServiceAdapter.java b/providers/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/GoogleComputeEngineServiceAdapter.java index 2ef8100..951d186 100644 --- a/providers/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/GoogleComputeEngineServiceAdapter.java +++ b/providers/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/GoogleComputeEngineServiceAdapter.java @@ -139,6 +139,8 @@ public final class GoogleComputeEngineServiceAdapter tags.add(naming.name(ports)); } + Scheduling scheduling = getScheduling(options); + NewInstance newInstance = new NewInstance.Builder( name, template.getHardware().getUri(), // machineType network, @@ -146,6 +148,7 @@ public final class GoogleComputeEngineServiceAdapter .description(group) .tags(Tags.create(null, ImmutableList.copyOf(tags))) .serviceAccounts(options.serviceAccounts()) + .scheduling(scheduling) .build(); // Add metadata from template and for ssh key and image id @@ -177,8 +180,8 @@ public final class GoogleComputeEngineServiceAdapter null, // disks newInstance.metadata(), // metadata newInstance.serviceAccounts(), // serviceAccounts - Scheduling.create(OnHostMaintenance.MIGRATE, true) // scheduling - )); + scheduling) // scheduling + ); checkState(instanceVisible.apply(instance), "instance %s is not api visible!", instance.get()); // Add lookup for InstanceToNodeMetadata @@ -315,4 +318,17 @@ public final class GoogleComputeEngineServiceAdapter return null; } + + public Scheduling getScheduling(GoogleComputeEngineTemplateOptions options) { + OnHostMaintenance onHostMaintenance = OnHostMaintenance.MIGRATE; + boolean automaticRestart = true; + + // Preemptible instances cannot use a MIGRATE maintenance strategy or automatic restarts + if (options.preemptible()) { + onHostMaintenance = OnHostMaintenance.TERMINATE; + automaticRestart = false; + } + + return Scheduling.create(onHostMaintenance, automaticRestart, options.preemptible()); + } } http://git-wip-us.apache.org/repos/asf/jclouds/blob/962980cd/providers/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/options/GoogleComputeEngineTemplateOptions.java ---------------------------------------------------------------------- diff --git a/providers/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/options/GoogleComputeEngineTemplateOptions.java b/providers/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/options/GoogleComputeEngineTemplateOptions.java index a2cbd1f..5f4a2ad 100644 --- a/providers/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/options/GoogleComputeEngineTemplateOptions.java +++ b/providers/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/options/GoogleComputeEngineTemplateOptions.java @@ -30,6 +30,7 @@ public final class GoogleComputeEngineTemplateOptions extends TemplateOptions { private boolean autoCreateKeyPair = true; private List<ServiceAccount> serviceAccounts; private String bootDiskType; + private boolean preemptible = false; @Override public GoogleComputeEngineTemplateOptions clone() { @@ -46,6 +47,7 @@ public final class GoogleComputeEngineTemplateOptions extends TemplateOptions { eTo.autoCreateKeyPair(autoCreateKeyPair()); eTo.serviceAccounts(serviceAccounts()); eTo.bootDiskType(bootDiskType()); + eTo.preemptible(preemptible()); } } @@ -91,6 +93,21 @@ public final class GoogleComputeEngineTemplateOptions extends TemplateOptions { } /** + * Sets whether the resulting instance should be preemptible. + */ + public GoogleComputeEngineTemplateOptions preemptible(boolean preemptible) { + this.preemptible = preemptible; + return this; + } + + /** + * Gets whether the resulting instance should be preemptible. + */ + public boolean preemptible() { + return preemptible; + } + + /** * Gets the list of service accounts, with their specified scopes, that will be authorize on created instances. */ public List<ServiceAccount> serviceAccounts(){ http://git-wip-us.apache.org/repos/asf/jclouds/blob/962980cd/providers/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Instance.java ---------------------------------------------------------------------- diff --git a/providers/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Instance.java b/providers/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Instance.java index dcbc344..5ae8f53 100644 --- a/providers/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Instance.java +++ b/providers/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Instance.java @@ -186,16 +186,19 @@ public abstract class Instance { * If you would like your instance to be restarted, set the automaticRestart flag to true. * Your instance may be restarted more than once, and it may be restarted outside the window * of maintenance events. + * If you would like your instance to be preemptible, set the preemptible flag to true. */ TERMINATE } public abstract OnHostMaintenance onHostMaintenance(); public abstract boolean automaticRestart(); + public abstract boolean preemptible(); - @SerializedNames({ "onHostMaintenance", "automaticRestart" }) - public static Scheduling create(OnHostMaintenance onHostMaintenance, boolean automaticRestart) { - return new AutoValue_Instance_Scheduling(onHostMaintenance, automaticRestart); + @SerializedNames({ "onHostMaintenance", "automaticRestart", "preemptible" }) + public static Scheduling create(OnHostMaintenance onHostMaintenance, boolean automaticRestart, + boolean preemptible) { + return new AutoValue_Instance_Scheduling(onHostMaintenance, automaticRestart, preemptible); } Scheduling() { http://git-wip-us.apache.org/repos/asf/jclouds/blob/962980cd/providers/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/InstanceApi.java ---------------------------------------------------------------------- diff --git a/providers/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/InstanceApi.java b/providers/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/InstanceApi.java index 5405de2..a884558 100644 --- a/providers/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/InstanceApi.java +++ b/providers/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/InstanceApi.java @@ -242,6 +242,7 @@ public interface InstanceApi { * @param automaticRestart Defines whether the Instance should be automatically * restarted when it is terminated by Compute Engine (not terminated by user). * Used when onHostMaintenance is set to TERMINATE. + * @param preemptible Defines whether the Instance should be launched as spot instance * @return */ @Named("Instances:setScheduling") @@ -250,7 +251,8 @@ public interface InstanceApi { @MapBinder(BindToJsonPayload.class) Operation setScheduling(@PathParam("instance") String instanceName, @PayloadParam("onHostMaintenance") Scheduling.OnHostMaintenance onHostMaintenance, - @PayloadParam("automaticRestart") boolean automaticRestart); + @PayloadParam("automaticRestart") boolean automaticRestart, + @PayloadParam("preemptible") boolean preemptible); /** * This method starts an instance that was stopped using the using the {@link #stop(String)} method. http://git-wip-us.apache.org/repos/asf/jclouds/blob/962980cd/providers/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/GoogleComputeEngineServiceLiveTest.java ---------------------------------------------------------------------- diff --git a/providers/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/GoogleComputeEngineServiceLiveTest.java b/providers/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/GoogleComputeEngineServiceLiveTest.java index 804e6e8..67cf15e 100644 --- a/providers/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/GoogleComputeEngineServiceLiveTest.java +++ b/providers/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/GoogleComputeEngineServiceLiveTest.java @@ -74,12 +74,12 @@ public class GoogleComputeEngineServiceLiveTest extends BaseComputeServiceLiveTe } } - public void testCreateNodeWithSsd() throws Exception { + public void testCreatePreemptibleNodeWithSsd() throws Exception { String group = this.group + "ssd"; try { TemplateOptions options = client.templateOptions(); - options.as(GoogleComputeEngineTemplateOptions.class).bootDiskType("pd-ssd"); + options.as(GoogleComputeEngineTemplateOptions.class).bootDiskType("pd-ssd").preemptible(true); // create a node Set<? extends NodeMetadata> nodes = @@ -92,6 +92,7 @@ public class GoogleComputeEngineServiceLiveTest extends BaseComputeServiceLiveTe Instance instance = api.instancesInZone(node.getLocation().getId()).get(node.getName()); Disk disk = api.disksInZone(node.getLocation().getId()).get(toName(instance.disks().get(0).source())); assertTrue(disk.type().toString().endsWith("pd-ssd")); + assertTrue(instance.scheduling().preemptible()); } finally { client.destroyNodesMatching(NodePredicates.inGroup(group)); http://git-wip-us.apache.org/repos/asf/jclouds/blob/962980cd/providers/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/InstanceApiLiveTest.java ---------------------------------------------------------------------- diff --git a/providers/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/InstanceApiLiveTest.java b/providers/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/InstanceApiLiveTest.java index 5200c3a..e29633b 100644 --- a/providers/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/InstanceApiLiveTest.java +++ b/providers/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/InstanceApiLiveTest.java @@ -18,6 +18,7 @@ package org.jclouds.googlecomputeengine.features; import static org.jclouds.googlecomputeengine.options.ListOptions.Builder.filter; import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertTrue; @@ -109,7 +110,7 @@ public class InstanceApiLiveTest extends BaseGoogleComputeEngineApiLiveTest { .description("description") .tags(Tags.create(null, ImmutableList.of("tag1"))) .serviceAccounts(ImmutableList.of(ServiceAccount.create("default", ImmutableList.of("https://www.googleapis.com/auth/compute")))) - .scheduling(Scheduling.create(OnHostMaintenance.MIGRATE, true)) + .scheduling(Scheduling.create(OnHostMaintenance.MIGRATE, true, false)) .build(); return api; @@ -132,6 +133,7 @@ public class InstanceApiLiveTest extends BaseGoogleComputeEngineApiLiveTest { assertEquals(instance.description(), "description"); assertEquals(instance.serviceAccounts().get(0).scopes(), ImmutableList.of("https://www.googleapis.com/auth/compute")); assertTrue(instance.scheduling().automaticRestart()); + assertFalse(instance.scheduling().preemptible()); assertEquals(instance.scheduling().onHostMaintenance(), OnHostMaintenance.MIGRATE); } @@ -205,12 +207,15 @@ public class InstanceApiLiveTest extends BaseGoogleComputeEngineApiLiveTest { public void testSetScheduling() { Instance instance = api().get(INSTANCE_NAME); assertEquals(instance.scheduling().automaticRestart(), true); + assertEquals(instance.scheduling().preemptible(), false); assertEquals(instance.scheduling().onHostMaintenance(), Scheduling.OnHostMaintenance.MIGRATE); - assertOperationDoneSuccessfully(api().setScheduling(INSTANCE_NAME, Scheduling.OnHostMaintenance.TERMINATE, false)); + assertOperationDoneSuccessfully(api().setScheduling(INSTANCE_NAME, Scheduling.OnHostMaintenance.TERMINATE, false, + false)); Instance instanceAltered = api().get(INSTANCE_NAME); assertEquals(instanceAltered.scheduling().automaticRestart(), false); + assertEquals(instanceAltered.scheduling().preemptible(), false); assertEquals(instanceAltered.scheduling().onHostMaintenance(), Scheduling.OnHostMaintenance.TERMINATE); } http://git-wip-us.apache.org/repos/asf/jclouds/blob/962980cd/providers/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/InstanceApiMockTest.java ---------------------------------------------------------------------- diff --git a/providers/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/InstanceApiMockTest.java b/providers/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/InstanceApiMockTest.java index 5cbc78f..1fb2e1b 100644 --- a/providers/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/InstanceApiMockTest.java +++ b/providers/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/InstanceApiMockTest.java @@ -227,11 +227,11 @@ public class InstanceApiMockTest extends BaseGoogleComputeEngineApiMockTest { public void setScheduling() throws Exception { server.enqueue(jsonResponse("/zone_operation.json")); - assertEquals(instanceApi().setScheduling("test-1", OnHostMaintenance.TERMINATE, true), + assertEquals(instanceApi().setScheduling("test-1", OnHostMaintenance.TERMINATE, true, false), new ParseZoneOperationTest().expected(url("/projects"))); assertSent(server, "POST", "/projects/party/zones/us-central1-a/instances/test-1/setScheduling", - "{\"onHostMaintenance\": \"TERMINATE\",\"automaticRestart\": true}"); + "{\"onHostMaintenance\": \"TERMINATE\",\"automaticRestart\": true,\"preemptible\": false}"); } public void start_test() throws Exception { @@ -279,7 +279,7 @@ public class InstanceApiMockTest extends BaseGoogleComputeEngineApiMockTest { .metadata(Metadata.create().put("aKey", "aValue")) .serviceAccounts(ImmutableList.of(ServiceAccount.create("default", ImmutableList.of("https://www.googleapis.com/auth/compute")))) - .scheduling(Scheduling.create(OnHostMaintenance.MIGRATE, true)) + .scheduling(Scheduling.create(OnHostMaintenance.MIGRATE, true, false)) .build(); assertEquals(instanceApi().create(newInstance), new ParseZoneOperationTest().expected(url("/projects"))); http://git-wip-us.apache.org/repos/asf/jclouds/blob/962980cd/providers/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/parse/ParseInstanceTest.java ---------------------------------------------------------------------- diff --git a/providers/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/parse/ParseInstanceTest.java b/providers/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/parse/ParseInstanceTest.java index 2a75143..59a6534 100644 --- a/providers/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/parse/ParseInstanceTest.java +++ b/providers/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/parse/ParseInstanceTest.java @@ -88,7 +88,7 @@ public class ParseInstanceTest extends BaseGoogleComputeEngineParseTest<Instance .put("aKey", "aValue") .put("jclouds-delete-boot-disk", "true"), // metadata ImmutableList.of(ServiceAccount.create("default", ImmutableList.of("myscope"))), // serviceAccounts - Instance.Scheduling.create(OnHostMaintenance.MIGRATE, false) // scheduling + Instance.Scheduling.create(OnHostMaintenance.MIGRATE, false, false) // scheduling ); } } http://git-wip-us.apache.org/repos/asf/jclouds/blob/962980cd/providers/google-compute-engine/src/test/resources/instance_get.json ---------------------------------------------------------------------- diff --git a/providers/google-compute-engine/src/test/resources/instance_get.json b/providers/google-compute-engine/src/test/resources/instance_get.json index 7da215d..cd831a4 100644 --- a/providers/google-compute-engine/src/test/resources/instance_get.json +++ b/providers/google-compute-engine/src/test/resources/instance_get.json @@ -69,6 +69,7 @@ }, "scheduling": { "onHostMaintenance": "MIGRATE", - "automaticRestart": false + "automaticRestart": false, + "preemptible": false } } http://git-wip-us.apache.org/repos/asf/jclouds/blob/962980cd/providers/google-compute-engine/src/test/resources/instance_insert_2.json ---------------------------------------------------------------------- diff --git a/providers/google-compute-engine/src/test/resources/instance_insert_2.json b/providers/google-compute-engine/src/test/resources/instance_insert_2.json index 012e172..12129d8 100644 --- a/providers/google-compute-engine/src/test/resources/instance_insert_2.json +++ b/providers/google-compute-engine/src/test/resources/instance_insert_2.json @@ -35,5 +35,10 @@ "value": "test" } ] + }, + "scheduling": { + "onHostMaintenance": "MIGRATE", + "automaticRestart": true, + "preemptible": false } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/jclouds/blob/962980cd/providers/google-compute-engine/src/test/resources/instance_insert_full.json ---------------------------------------------------------------------- diff --git a/providers/google-compute-engine/src/test/resources/instance_insert_full.json b/providers/google-compute-engine/src/test/resources/instance_insert_full.json index 61302df..6979eee 100644 --- a/providers/google-compute-engine/src/test/resources/instance_insert_full.json +++ b/providers/google-compute-engine/src/test/resources/instance_insert_full.json @@ -42,6 +42,7 @@ ], "scheduling": { "onHostMaintenance": "MIGRATE", - "automaticRestart": true + "automaticRestart": true, + "preemptible": false } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/jclouds/blob/962980cd/providers/google-compute-engine/src/test/resources/instance_insert_ssd.json ---------------------------------------------------------------------- diff --git a/providers/google-compute-engine/src/test/resources/instance_insert_ssd.json b/providers/google-compute-engine/src/test/resources/instance_insert_ssd.json index 7a5080d..92e8efa 100644 --- a/providers/google-compute-engine/src/test/resources/instance_insert_ssd.json +++ b/providers/google-compute-engine/src/test/resources/instance_insert_ssd.json @@ -36,5 +36,10 @@ "value": "test" } ] + }, + "scheduling": { + "onHostMaintenance": "MIGRATE", + "automaticRestart": true, + "preemptible": false } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/jclouds/blob/962980cd/providers/google-compute-engine/src/test/resources/instance_list.json ---------------------------------------------------------------------- diff --git a/providers/google-compute-engine/src/test/resources/instance_list.json b/providers/google-compute-engine/src/test/resources/instance_list.json index 5a068fc..88860a1 100644 --- a/providers/google-compute-engine/src/test/resources/instance_list.json +++ b/providers/google-compute-engine/src/test/resources/instance_list.json @@ -74,7 +74,8 @@ }, "scheduling": { "onHostMaintenance": "MIGRATE", - "automaticRestart": false + "automaticRestart": false, + "preemptible": false } } ]
