Support Disk Configuration Extension
Project: http://git-wip-us.apache.org/repos/asf/incubator-jclouds/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-jclouds/commit/01f118b4 Tree: http://git-wip-us.apache.org/repos/asf/incubator-jclouds/tree/01f118b4 Diff: http://git-wip-us.apache.org/repos/asf/incubator-jclouds/diff/01f118b4 Branch: refs/heads/1.6.x Commit: 01f118b4ef20a2fd7c889de64290b917882c8be5 Parents: a83564a Author: Everett Toews <[email protected]> Authored: Wed Jul 31 21:11:30 2013 -0500 Committer: Everett Toews <[email protected]> Committed: Thu Aug 1 16:50:43 2013 -0500 ---------------------------------------------------------------------- .../openstack/nova/v2_0/domain/Server.java | 13 ++++- .../nova/v2_0/domain/ServerCreated.java | 35 ++++++++++--- .../nova/v2_0/options/CreateServerOptions.java | 42 +++++++++++++++- .../nova/v2_0/features/ServerApiExpectTest.java | 53 ++++++++++++++++++++ .../nova/v2_0/parse/ParseCreatedServerTest.java | 15 ++++++ .../resources/new_server_disk_config_auto.json | 42 ++++++++++++++++ .../new_server_disk_config_manual.json | 42 ++++++++++++++++ 7 files changed, 232 insertions(+), 10 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/01f118b4/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/domain/Server.java ---------------------------------------------------------------------- diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/domain/Server.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/domain/Server.java index 36f6826..a02cc04 100644 --- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/domain/Server.java +++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/domain/Server.java @@ -25,6 +25,7 @@ import java.util.Map; import javax.inject.Named; import org.jclouds.javax.annotation.Nullable; +import org.jclouds.openstack.nova.v2_0.options.CreateServerOptions; import org.jclouds.openstack.v2_0.domain.Link; import org.jclouds.openstack.v2_0.domain.Resource; @@ -45,6 +46,8 @@ import com.google.common.collect.Multimap; * /> */ public class Server extends Resource { + public final static String DISK_CONFIG_MANUAL = "MANUAL"; + public final static String DISK_CONFIG_AUTO = "AUTO"; /** * Servers contain a status attribute that can be used as an indication of the current server @@ -441,12 +444,18 @@ public class Server extends Resource { } /** - * Disk config attribute from the Disk Config Extension (alias "OS-DCF") + * Disk config attribute from the Disk Config Extension (alias "OS-DCF"). + * One of {@link Server#DISK_CONFIG_AUTO} or {@link Server#DISK_CONFIG_MANUAL}. + * This field is only present if the Disk Config extension is installed. * <p/> - * NOTE: This field is only present if the Disk Config extension is installed + * NOTE: Typically a field like this would be implemented as an enum but this field was + * originally implmented as a String and {@link Server#DISK_CONFIG_AUTO} and + * {@link Server#DISK_CONFIG_MANUAL} were added later as Strings to preserve backwards + * compatibility. * * @see org.jclouds.openstack.nova.v2_0.features.ExtensionApi#getExtensionByAlias * @see org.jclouds.openstack.nova.v2_0.extensions.ExtensionNamespaces#DISK_CONFIG + * @see CreateServerOptions#getDiskConfig() */ public Optional<String> getDiskConfig() { return this.diskConfig; http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/01f118b4/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/domain/ServerCreated.java ---------------------------------------------------------------------- diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/domain/ServerCreated.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/domain/ServerCreated.java index b7ac6c9..13a5590 100644 --- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/domain/ServerCreated.java +++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/domain/ServerCreated.java @@ -20,6 +20,7 @@ import java.beans.ConstructorProperties; import java.util.Set; import org.jclouds.javax.annotation.Nullable; +import org.jclouds.openstack.nova.v2_0.options.CreateServerOptions; import org.jclouds.openstack.v2_0.domain.Link; import org.jclouds.openstack.v2_0.domain.Resource; @@ -47,6 +48,7 @@ public class ServerCreated extends Resource { public static final class Builder extends Resource.Builder<Builder> { protected String adminPass; + protected String diskConfig; /** * @see ServerCreated#getAdminPass() @@ -55,13 +57,21 @@ public class ServerCreated extends Resource { this.adminPass = adminPass; return self(); } + + /** + * @see ServerCreated#getDiskConfig() + */ + public Builder diskConfig(String diskConfig) { + this.diskConfig = diskConfig; + return self(); + } public ServerCreated build() { - return new ServerCreated(id, name, links, adminPass); + return new ServerCreated(id, name, links, adminPass, diskConfig); } public Builder fromServerCreated(ServerCreated in) { - return super.fromResource(in).adminPass(in.getAdminPass().orNull()); + return super.fromResource(in).adminPass(in.getAdminPass().orNull()).diskConfig(in.getDiskConfig().orNull()); } @Override @@ -71,13 +81,16 @@ public class ServerCreated extends Resource { } private final Optional<String> adminPass; + private final Optional<String> diskConfig; @ConstructorProperties({ - "id", "name", "links", "adminPass" + "id", "name", "links", "adminPass", "OS-DCF:diskConfig" }) - protected ServerCreated(String id, @Nullable String name, Set<Link> links, @Nullable String adminPass) { + protected ServerCreated(String id, @Nullable String name, Set<Link> links, @Nullable String adminPass, + @Nullable String diskConfig) { super(id, name, links); this.adminPass = Optional.fromNullable(adminPass); + this.diskConfig = Optional.fromNullable(diskConfig); } /** @@ -87,9 +100,16 @@ public class ServerCreated extends Resource { return this.adminPass; } + /** + * @see CreateServerOptions#getDiskConfig() + */ + public Optional<String> getDiskConfig() { + return this.diskConfig; + } + @Override public int hashCode() { - return Objects.hashCode(adminPass); + return Objects.hashCode(adminPass, diskConfig); } @Override @@ -97,11 +117,12 @@ public class ServerCreated extends Resource { if (this == obj) return true; if (obj == null || getClass() != obj.getClass()) return false; ServerCreated that = ServerCreated.class.cast(obj); - return super.equals(that) && Objects.equal(this.adminPass, that.adminPass); + return super.equals(that) && Objects.equal(this.adminPass, that.adminPass) + && Objects.equal(this.diskConfig, that.diskConfig); } @Override protected ToStringHelper string() { - return super.string().add("adminPass", adminPass.orNull()); + return super.string().add("adminPass", adminPass.orNull()).add("diskConfig", diskConfig.orNull()); } } http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/01f118b4/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/options/CreateServerOptions.java ---------------------------------------------------------------------- diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/options/CreateServerOptions.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/options/CreateServerOptions.java index efa16bf..3ce1fb3 100644 --- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/options/CreateServerOptions.java +++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/options/CreateServerOptions.java @@ -34,6 +34,7 @@ import javax.inject.Named; import org.jclouds.http.HttpRequest; import org.jclouds.openstack.nova.v2_0.NovaApi; +import org.jclouds.openstack.nova.v2_0.domain.Server; import org.jclouds.rest.MapBinder; import org.jclouds.rest.binders.BindToJsonPayload; @@ -109,6 +110,7 @@ public class CreateServerOptions implements MapBinder { private Map<String, String> metadata = ImmutableMap.of(); private List<File> personality = Lists.newArrayList(); private byte[] userData; + private String diskConfig; @Override public boolean equals(Object object) { @@ -119,7 +121,7 @@ public class CreateServerOptions implements MapBinder { final CreateServerOptions other = CreateServerOptions.class.cast(object); return equal(keyName, other.keyName) && equal(securityGroupNames, other.securityGroupNames) && equal(metadata, other.metadata) && equal(personality, other.personality) - && equal(adminPass, other.adminPass); + && equal(adminPass, other.adminPass) && equal(diskConfig, other.diskConfig); } else { return false; } @@ -141,6 +143,8 @@ public class CreateServerOptions implements MapBinder { toString.add("personality", personality); if (adminPass != null) toString.add("adminPassPresent", true); + if (diskConfig != null) + toString.add("diskConfig", diskConfig); toString.add("userData", userData == null ? null : new String(userData)); return toString; } @@ -161,6 +165,8 @@ public class CreateServerOptions implements MapBinder { @Named("security_groups") Set<NamedThingy> securityGroupNames; String user_data; + @Named("OS-DCF:diskConfig") + String diskConfig; private ServerRequest(String name, String imageRef, String flavorRef) { this.name = name; @@ -192,6 +198,9 @@ public class CreateServerOptions implements MapBinder { if (adminPass != null) { server.adminPass = adminPass; } + if (diskConfig != null) { + server.diskConfig = diskConfig; + } return bindToRequest(request, ImmutableMap.of("server", server)); } @@ -320,6 +329,29 @@ public class CreateServerOptions implements MapBinder { this.securityGroupNames = ImmutableSet.copyOf(securityGroupNames); return this; } + + /** + * When you create a server from an image with the diskConfig value set to + * {@link Server#DISK_CONFIG_AUTO}, the server is built with a single partition that is expanded to + * the disk size of the flavor selected. When you set the diskConfig attribute to + * {@link Server#DISK_CONFIG_MANUAL}, the server is built by using the partition scheme and file + * system that is in the source image. + * <p/> + * If the target flavor disk is larger, remaining disk space is left unpartitioned. A server inherits the diskConfig + * attribute from the image from which it is created. However, you can override the diskConfig value when you create + * a server. This field is only present if the Disk Config extension is installed in your OpenStack deployment. + */ + public String getDiskConfig() { + return diskConfig; + } + + /** + * @see #getDiskConfig + */ + public CreateServerOptions diskConfig(String diskConfig) { + this.diskConfig = diskConfig; + return this; + } public static class Builder { @@ -367,6 +399,14 @@ public class CreateServerOptions implements MapBinder { CreateServerOptions options = new CreateServerOptions(); return CreateServerOptions.class.cast(options.securityGroupNames(groupNames)); } + + /** + * @see CreateServerOptions#getDiskConfig + */ + public static CreateServerOptions diskConfig(String diskConfig) { + CreateServerOptions options = new CreateServerOptions(); + return CreateServerOptions.class.cast(options.diskConfig(diskConfig)); + } } @Override http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/01f118b4/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/features/ServerApiExpectTest.java ---------------------------------------------------------------------- diff --git a/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/features/ServerApiExpectTest.java b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/features/ServerApiExpectTest.java index c74a834..b6c0011 100644 --- a/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/features/ServerApiExpectTest.java +++ b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/features/ServerApiExpectTest.java @@ -23,6 +23,7 @@ import static org.testng.Assert.fail; import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpResponse; import org.jclouds.openstack.nova.v2_0.NovaApi; +import org.jclouds.openstack.nova.v2_0.domain.Server; import org.jclouds.openstack.nova.v2_0.internal.BaseNovaApiExpectTest; import org.jclouds.openstack.nova.v2_0.options.CreateServerOptions; import org.jclouds.openstack.nova.v2_0.parse.ParseCreatedServerTest; @@ -127,6 +128,58 @@ public class ServerApiExpectTest extends BaseNovaApiExpectTest { new ParseCreatedServerTest().expected().toString()); } + public void testCreateServerWithDiskConfigAuto() throws Exception { + + HttpRequest createServer = HttpRequest + .builder() + .method("POST") + .endpoint("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/servers") + .addHeader("Accept", "application/json") + .addHeader("X-Auth-Token", authToken) + .payload(payloadFromStringWithContentType( + "{\"server\":{\"name\":\"test-e92\",\"imageRef\":\"1241\",\"flavorRef\":\"100\",\"OS-DCF:diskConfig\":\"AUTO\"}}","application/json")) + .build(); + + + HttpResponse createServerResponse = HttpResponse.builder().statusCode(202).message("HTTP/1.1 202 Accepted") + .payload(payloadFromResourceWithContentType("/new_server_disk_config_auto.json","application/json; charset=UTF-8")).build(); + + + NovaApi apiWithNewServer = requestsSendResponses( + keystoneAuthWithUsernameAndPasswordAndTenantName, responseWithKeystoneAccess, + createServer, createServerResponse); + + assertEquals(apiWithNewServer.getServerApiForZone("az-1.region-a.geo-1").create("test-e92", "1241", + "100", new CreateServerOptions().diskConfig(Server.DISK_CONFIG_AUTO)).toString(), + new ParseCreatedServerTest().expectedWithDiskConfig(Server.DISK_CONFIG_AUTO).toString()); + } + + public void testCreateServerWithDiskConfigManual() throws Exception { + + HttpRequest createServer = HttpRequest + .builder() + .method("POST") + .endpoint("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/servers") + .addHeader("Accept", "application/json") + .addHeader("X-Auth-Token", authToken) + .payload(payloadFromStringWithContentType( + "{\"server\":{\"name\":\"test-e92\",\"imageRef\":\"1241\",\"flavorRef\":\"100\",\"OS-DCF:diskConfig\":\"MANUAL\"}}","application/json")) + .build(); + + + HttpResponse createServerResponse = HttpResponse.builder().statusCode(202).message("HTTP/1.1 202 Accepted") + .payload(payloadFromResourceWithContentType("/new_server_disk_config_manual.json","application/json; charset=UTF-8")).build(); + + + NovaApi apiWithNewServer = requestsSendResponses( + keystoneAuthWithUsernameAndPasswordAndTenantName, responseWithKeystoneAccess, + createServer, createServerResponse); + + assertEquals(apiWithNewServer.getServerApiForZone("az-1.region-a.geo-1").create("test-e92", "1241", + "100", new CreateServerOptions().diskConfig(Server.DISK_CONFIG_MANUAL)).toString(), + new ParseCreatedServerTest().expectedWithDiskConfig(Server.DISK_CONFIG_MANUAL).toString()); + } + public void testCreateImageWhenResponseIs2xx() throws Exception { String serverId = "123"; String imageId = "456"; http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/01f118b4/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/parse/ParseCreatedServerTest.java ---------------------------------------------------------------------- diff --git a/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/parse/ParseCreatedServerTest.java b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/parse/ParseCreatedServerTest.java index 9b6ce0a..3b2a774 100644 --- a/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/parse/ParseCreatedServerTest.java +++ b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/parse/ParseCreatedServerTest.java @@ -59,6 +59,21 @@ public class ParseCreatedServerTest extends BaseItemParserTest<ServerCreated> { } + @SelectJson("server") + @Consumes(MediaType.APPLICATION_JSON) + public ServerCreated expectedWithDiskConfig(String diskConfig) { + return ServerCreated + .builder() + .id("71752") + .name("test-e92") + .adminPass("ZWuHcmTMQ7eXoHeM") + .diskConfig(diskConfig) + .links( + Link.create(Relation.SELF, URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/37936628937291/servers/71752")), + Link.create(Relation.BOOKMARK, URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/37936628937291/servers/71752"))).build(); + + } + protected Injector injector() { return Guice.createInjector(new NovaParserModule(), new GsonModule()); } http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/01f118b4/apis/openstack-nova/src/test/resources/new_server_disk_config_auto.json ---------------------------------------------------------------------- diff --git a/apis/openstack-nova/src/test/resources/new_server_disk_config_auto.json b/apis/openstack-nova/src/test/resources/new_server_disk_config_auto.json new file mode 100644 index 0000000..7238333 --- /dev/null +++ b/apis/openstack-nova/src/test/resources/new_server_disk_config_auto.json @@ -0,0 +1,42 @@ +{ + "server": { + "status": "BUILD(scheduling)", + "updated": "2012-03-19T06:21:13Z", + "hostId": "", + "user_id": "54297837463082", + "name": "test-e92", + "links": [{ + "href": "https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/37936628937291/servers/71752", + "rel": "self" + }, { + "href": "https://az-1.region-a.geo-1.compute.hpcloudsvc.com/37936628937291/servers/71752", + "rel": "bookmark" + }], + "addresses": {}, + "tenant_id": "37936628937291", + "image": { + "id": "1241", + "links": [{ + "href": "https://az-1.region-a.geo-1.compute.hpcloudsvc.com/37936628937291/images/1241", + "rel": "bookmark" + }] + }, + "created": "2012-03-19T06:21:13Z", + "uuid": "47491020-6a78-4f63-9475-23195ac4515c", + "accessIPv4": "", + "accessIPv6": "", + "key_name": null, + "adminPass": "ZWuHcmTMQ7eXoHeM", + "flavor": { + "id": "100", + "links": [{ + "href": "https://az-1.region-a.geo-1.compute.hpcloudsvc.com/37936628937291/flavors/100", + "rel": "bookmark" + }] + }, + "config_drive": "", + "id": 71752, + "metadata": {}, + "OS-DCF:diskConfig": "AUTO" + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/01f118b4/apis/openstack-nova/src/test/resources/new_server_disk_config_manual.json ---------------------------------------------------------------------- diff --git a/apis/openstack-nova/src/test/resources/new_server_disk_config_manual.json b/apis/openstack-nova/src/test/resources/new_server_disk_config_manual.json new file mode 100644 index 0000000..2cfba41 --- /dev/null +++ b/apis/openstack-nova/src/test/resources/new_server_disk_config_manual.json @@ -0,0 +1,42 @@ +{ + "server": { + "status": "BUILD(scheduling)", + "updated": "2012-03-19T06:21:13Z", + "hostId": "", + "user_id": "54297837463082", + "name": "test-e92", + "links": [{ + "href": "https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/37936628937291/servers/71752", + "rel": "self" + }, { + "href": "https://az-1.region-a.geo-1.compute.hpcloudsvc.com/37936628937291/servers/71752", + "rel": "bookmark" + }], + "addresses": {}, + "tenant_id": "37936628937291", + "image": { + "id": "1241", + "links": [{ + "href": "https://az-1.region-a.geo-1.compute.hpcloudsvc.com/37936628937291/images/1241", + "rel": "bookmark" + }] + }, + "created": "2012-03-19T06:21:13Z", + "uuid": "47491020-6a78-4f63-9475-23195ac4515c", + "accessIPv4": "", + "accessIPv6": "", + "key_name": null, + "adminPass": "ZWuHcmTMQ7eXoHeM", + "flavor": { + "id": "100", + "links": [{ + "href": "https://az-1.region-a.geo-1.compute.hpcloudsvc.com/37936628937291/flavors/100", + "rel": "bookmark" + }] + }, + "config_drive": "", + "id": 71752, + "metadata": {}, + "OS-DCF:diskConfig": "MANUAL" + } +} \ No newline at end of file
