Skip to content
Permalink
Browse files
Adding copyFrom option to Glance
  • Loading branch information
demobox committed Oct 21, 2014
1 parent 9b19cde commit 9e2049dbd1a72922446e832b548e0a102d79d26d
Showing 3 changed files with 112 additions and 15 deletions.
@@ -37,6 +37,8 @@
*/
public class CreateImageOptions extends UpdateImageOptions {

public static final String COPY_FROM = "x-glance-api-copy-from";

/**
* When present, Glance will use the supplied identifier for the image instead of generating one. If the identifier
* already exists in that Glance node, then a 409 Conflict will be returned by Glance. The value of the header must
@@ -47,6 +49,14 @@ public CreateImageOptions id(String id) {
return this;
}

/**
* @param url the url of the image to be copied
*/
public UpdateImageOptions copyFrom(String url) {
headers.put(COPY_FROM, url);
return this;
}

public static class Builder {
/**
* @see org.jclouds.openstack.glance.v1_0.options.CreateImageOptions#id
@@ -131,5 +141,13 @@ public static CreateImageOptions owner(String owner) {
public static CreateImageOptions property(String key, String value) {
return CreateImageOptions.class.cast(new CreateImageOptions().property(key, value));
}

/**
* @see org.jclouds.openstack.glance.v1_0.options.CreateImageOptions#copyFrom(String)
*/
public static CreateImageOptions copyFrom(String url) {
return CreateImageOptions.class.cast(new CreateImageOptions().copyFrom(url));
}

}
}
@@ -16,6 +16,7 @@
*/
package org.jclouds.openstack.glance.v1_0.features;

import static org.jclouds.openstack.glance.v1_0.options.CreateImageOptions.Builder.copyFrom;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNull;
@@ -223,6 +224,28 @@ public void testCreateWhenResponseIs4xx() throws Exception {
apiWhenExist.getImageApi("az-1.region-a.geo-1").create("test", new StringPayload("somedata"));
}

public void testImageCreateCopyFrom() throws Exception {
HttpRequest get = HttpRequest.builder().method("POST")
.endpoint("https://glance.jclouds.org:9292/v1.0/images")
.addHeader("x-image-meta-name", "test")
.addHeader("Accept", MediaType.APPLICATION_JSON)
.addHeader("x-glance-api-copy-from", "http://1.1.1.1/Installs/Templates/tiny/tinylinux-v2.qcow2")
.addHeader("X-Auth-Token", authToken)
.payload(payloadFromStringWithContentType("", MediaType.APPLICATION_OCTET_STREAM)).build();

HttpResponse createResponse = HttpResponse.builder().statusCode(200)
.payload(payloadFromResource("/image.json")).build();

GlanceApi apiWhenExist = requestsSendResponses(keystoneAuthWithUsernameAndPassword,
responseWithKeystoneAccess, versionNegotiationRequest, versionNegotiationResponse,
get, createResponse);

assertEquals(apiWhenExist.getConfiguredRegions(), ImmutableSet.of("az-1.region-a.geo-1"));

assertEquals(apiWhenExist.getImageApi("az-1.region-a.geo-1").create("test", new StringPayload(""), copyFrom("http://1.1.1.1/Installs/Templates/tiny/tinylinux-v2.qcow2")),
new ParseImageDetailsTest().expected());
}

public void testReserveWhenResponseIs2xx() throws Exception {
HttpRequest get = HttpRequest.builder().method("POST")
.endpoint("https://glance.jclouds.org:9292/v1.0/images")
@@ -18,12 +18,15 @@


import static org.jclouds.openstack.glance.v1_0.options.CreateImageOptions.Builder.containerFormat;
import static org.jclouds.openstack.glance.v1_0.options.CreateImageOptions.Builder.copyFrom;
import static org.jclouds.openstack.glance.v1_0.options.CreateImageOptions.Builder.diskFormat;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;

import java.util.Random;
import java.util.Set;

import com.google.common.collect.ImmutableList;
import org.jclouds.io.payloads.StringPayload;
import org.jclouds.openstack.glance.v1_0.domain.ContainerFormat;
import org.jclouds.openstack.glance.v1_0.domain.DiskFormat;
@@ -32,13 +35,34 @@
import org.jclouds.openstack.glance.v1_0.internal.BaseGlanceApiLiveTest;
import org.jclouds.openstack.glance.v1_0.options.ListImageOptions;
import org.jclouds.openstack.glance.v1_0.options.UpdateImageOptions;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

import com.google.common.collect.Iterables;

@Test(groups = "live", testName = "ImageApiLiveTest")
@Test(groups = "live", testName = "ImageApiLiveTest", singleThreaded = true)
public class ImageApiLiveTest extends BaseGlanceApiLiveTest {

public static final String IMAGE_NAME_PREFIX = "jclouds-live-test-";

public static String imageName;
public static String updatedImageName;

@BeforeClass
public void init() {
Random random = new Random();
imageName = IMAGE_NAME_PREFIX + random.nextInt();
updatedImageName = IMAGE_NAME_PREFIX + random.nextInt();
}

@AfterTest
public void tearDown() {
for (String region : api.getConfiguredRegions()) {
cleanImagesByRegionAndName(region, imageName, updatedImageName);
}
}

@Test
public void testList() throws Exception {
for (String region : api.getConfiguredRegions()) {
@@ -89,25 +113,25 @@ public void testCreateUpdateAndDeleteImage() {
StringPayload imageData = new StringPayload("This isn't really an image!");
for (String region : api.getConfiguredRegions()) {
ImageApi imageApi = api.getImageApi(region);
ImageDetails details = imageApi.create("jclouds-live-test", imageData, diskFormat(DiskFormat.RAW), containerFormat(ContainerFormat.BARE));
assertEquals(details.getName(), "jclouds-live-test");
ImageDetails details = imageApi.create(imageName, imageData, diskFormat(DiskFormat.RAW), containerFormat(ContainerFormat.BARE));
assertEquals(details.getName(), imageName);
assertEquals(details.getSize().get().longValue(), imageData.getRawContent().length());

details = imageApi.update(details.getId(), UpdateImageOptions.Builder.name("jclouds-live-test2"), UpdateImageOptions.Builder.minDisk(10));
assertEquals(details.getName(), "jclouds-live-test2");
details = imageApi.update(details.getId(), UpdateImageOptions.Builder.name(updatedImageName), UpdateImageOptions.Builder.minDisk(10));
assertEquals(details.getName(), updatedImageName);
assertEquals(details.getMinDisk(), 10);

Image fromListing = imageApi.list(
ListImageOptions.Builder.containerFormat(ContainerFormat.BARE).name("jclouds-live-test2").limit(2))
ListImageOptions.Builder.containerFormat(ContainerFormat.BARE).name(updatedImageName).limit(2))
.get(0);
assertEquals(fromListing.getId(), details.getId());
assertEquals(fromListing.getSize(), details.getSize());

assertEquals(Iterables.getOnlyElement(imageApi.listInDetail(ListImageOptions.Builder.name("jclouds-live-test2"))), details);
assertEquals(Iterables.getOnlyElement(imageApi.listInDetail(ListImageOptions.Builder.name(updatedImageName))), details);

assertTrue(imageApi.delete(details.getId()));

assertTrue(imageApi.list(ListImageOptions.Builder.name("jclouds-live-test2")).isEmpty());
assertTrue(imageApi.list(ListImageOptions.Builder.name(updatedImageName)).isEmpty());
}
}

@@ -116,24 +140,56 @@ public void testReserveUploadAndDeleteImage() {
StringPayload imageData = new StringPayload("This isn't an image!");
for (String region : api.getConfiguredRegions()) {
ImageApi imageApi = api.getImageApi(region);
ImageDetails details = imageApi.reserve("jclouds-live-res-test", diskFormat(DiskFormat.RAW), containerFormat(ContainerFormat.BARE));
assertEquals(details.getName(), "jclouds-live-res-test");
ImageDetails details = imageApi.reserve(imageName, diskFormat(DiskFormat.RAW), containerFormat(ContainerFormat.BARE));
assertEquals(details.getName(), imageName);

details = imageApi.upload(details.getId(), imageData, UpdateImageOptions.Builder.name("jclouds-live-res-test2"), UpdateImageOptions.Builder.minDisk(10));
assertEquals(details.getName(), "jclouds-live-res-test2");
details = imageApi.upload(details.getId(), imageData, UpdateImageOptions.Builder.name(updatedImageName), UpdateImageOptions.Builder.minDisk(10));
assertEquals(details.getName(), updatedImageName);
assertEquals(details.getSize().get().longValue(), imageData.getRawContent().length());
assertEquals(details.getMinDisk(), 10);

Image fromListing = Iterables.getOnlyElement(imageApi.list(ListImageOptions.Builder.name("jclouds-live-res-test2").limit(2).containerFormat(ContainerFormat.BARE)));
Image fromListing = Iterables.getOnlyElement(imageApi.list(ListImageOptions.Builder.name(updatedImageName).limit(2).containerFormat(ContainerFormat.BARE)));
assertEquals(fromListing.getId(), details.getId());
assertEquals(fromListing.getSize(), details.getSize());

assertEquals(Iterables.getOnlyElement(imageApi.listInDetail(ListImageOptions.Builder.name("jclouds-live-res-test2"))), details);
assertEquals(Iterables.getOnlyElement(imageApi.listInDetail(ListImageOptions.Builder.name(updatedImageName))), details);

assertTrue(imageApi.delete(details.getId()));

assertTrue(imageApi.list(ListImageOptions.Builder.name("jclouds-live-res-test2")).isEmpty());
assertTrue(imageApi.list(ListImageOptions.Builder.name(updatedImageName)).isEmpty());
}
}

@Test
public void testCreateImageCopyFromLocation() {
StringPayload imageData = new StringPayload("");
for (String region : api.getConfiguredRegions()) {
ImageApi imageApi = api.getImageApi(region);
ImageDetails details = imageApi.create(imageName, imageData, diskFormat(DiskFormat.RAW), containerFormat(ContainerFormat.BARE), copyFrom("http://10.5.5.121/Installs/Templates/tiny/tinylinux-v2.qcow2"));
assertEquals(details.getName(), imageName);

Image fromListing = imageApi.get(details.getId());

assertEquals(fromListing.getId(), details.getId());
assertEquals(fromListing.getSize(), details.getSize());
assertEquals(fromListing.getContainerFormat(), details.getContainerFormat());
assertEquals(fromListing.getDiskFormat(), details.getDiskFormat());
assertEquals(fromListing.getSize(), details.getSize());

assertTrue(imageApi.delete(details.getId()));
assertTrue(imageApi.list(ListImageOptions.Builder.name(imageName)).isEmpty());
}
}

private void cleanImagesByRegionAndName(String region, String... imageNames) {
ImageApi imageApi = api.getImageApi(region);

for (String imageName : imageNames) {
ImmutableList<Image> images = imageApi.list(ListImageOptions.Builder.name(imageName)).toList();

for (Image image : images) {
imageApi.delete(image.getId());
}
}
}
}

0 comments on commit 9e2049d

Please sign in to comment.