JCLOUDS-138. Add CloudStackImageExtension support.

This commit is contained in:
Andrew Bayer 2013-06-20 16:59:13 -07:00
parent ccb4323986
commit a906f9f4ec
13 changed files with 432 additions and 0 deletions

View File

@ -31,6 +31,7 @@ import javax.inject.Singleton;
import org.jclouds.cloudstack.CloudStackClient;
import org.jclouds.cloudstack.compute.CloudStackComputeService;
import org.jclouds.cloudstack.compute.extensions.CloudStackImageExtension;
import org.jclouds.cloudstack.compute.functions.OrphanedGroupsByZoneId;
import org.jclouds.cloudstack.compute.functions.ServiceOfferingToHardware;
import org.jclouds.cloudstack.compute.functions.TemplateToImage;
@ -73,6 +74,7 @@ import org.jclouds.compute.ComputeServiceAdapter;
import org.jclouds.compute.config.ComputeServiceAdapterContextModule;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.compute.extensions.ImageExtension;
import org.jclouds.compute.options.TemplateOptions;
import org.jclouds.domain.Location;
import org.jclouds.rest.AuthorizationException;
@ -80,6 +82,7 @@ import org.jclouds.rest.suppliers.MemoizedRetryOnTimeOutButNotOnAuthorizationExc
import com.google.common.base.Function;
import com.google.common.base.Objects;
import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.google.common.base.Supplier;
import com.google.common.cache.CacheBuilder;
@ -136,6 +139,9 @@ public class CloudStackComputeServiceContextModule extends
bind(new TypeLiteral<Function<Set<? extends NodeMetadata>, Multimap<String, String>>>() {
}).to(OrphanedGroupsByZoneId.class);
bind(new TypeLiteral<ImageExtension>() {
}).to(CloudStackImageExtension.class);
// to have the compute service adapter override default locations
install(new LocationsFromComputeServiceAdapterModule<VirtualMachine, ServiceOffering, Template, Zone>(){});
}
@ -252,4 +258,10 @@ public class CloudStackComputeServiceContextModule extends
NetworkType.ADVANCED, new AdvancedNetworkOptionsConverter(),
NetworkType.BASIC, new BasicNetworkOptionsConverter());
}
@Override
protected Optional<ImageExtension> provideImageExtension(Injector i) {
return Optional.of(i.getInstance(ImageExtension.class));
}
}

View File

@ -0,0 +1,163 @@
/*
* 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.cloudstack.compute.extensions;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.collect.Iterables.find;
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_IMAGE_AVAILABLE;
import static org.jclouds.location.predicates.LocationPredicates.idEquals;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.atomic.AtomicReference;
import javax.annotation.Resource;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.Constants;
import org.jclouds.cloudstack.CloudStackClient;
import org.jclouds.cloudstack.domain.AsyncCreateResponse;
import org.jclouds.cloudstack.domain.Template;
import org.jclouds.cloudstack.domain.TemplateMetadata;
import org.jclouds.cloudstack.domain.VirtualMachine;
import org.jclouds.cloudstack.domain.Volume;
import org.jclouds.cloudstack.options.CreateTemplateOptions;
import org.jclouds.cloudstack.options.ListVolumesOptions;
import org.jclouds.cloudstack.strategy.BlockUntilJobCompletesAndReturnResult;
import org.jclouds.collect.Memoized;
import org.jclouds.compute.domain.CloneImageTemplate;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.ImageBuilder;
import org.jclouds.compute.domain.ImageTemplate;
import org.jclouds.compute.domain.ImageTemplateBuilder;
import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.compute.extensions.ImageExtension;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.domain.Location;
import org.jclouds.logging.Logger;
import com.google.common.base.Predicate;
import com.google.common.base.Supplier;
import com.google.common.collect.Iterables;
import com.google.common.util.concurrent.Atomics;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.UncheckedTimeoutException;
/**
* CloudStack implementation of {@link ImageExtension}
*
* @author Andrew Bayer
*
*/
@Singleton
public class CloudStackImageExtension implements ImageExtension {
@Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL;
private final CloudStackClient client;
private final ListeningExecutorService userExecutor;
private final Supplier<Set<? extends Location>> locations;
private final Predicate<AtomicReference<Image>> imageAvailablePredicate;
private final BlockUntilJobCompletesAndReturnResult blockUntilJobCompletesAndReturnResult;
private final Predicate<String> jobComplete;
@Inject
public CloudStackImageExtension(CloudStackClient client,
@Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor,
@Memoized Supplier<Set<? extends Location>> locations,
@Named(TIMEOUT_IMAGE_AVAILABLE) Predicate<AtomicReference<Image>> imageAvailablePredicate,
BlockUntilJobCompletesAndReturnResult blockUntilJobCompletesAndReturnResult,
Predicate<String> jobComplete) {
this.client = checkNotNull(client, "client");
this.userExecutor = checkNotNull(userExecutor, "userExecutor");
this.locations = checkNotNull(locations, "locations");
this.imageAvailablePredicate = checkNotNull(imageAvailablePredicate, "imageAvailablePredicate");
this.blockUntilJobCompletesAndReturnResult = checkNotNull(blockUntilJobCompletesAndReturnResult,
"blockUntilJobCompletesAndReturnResult");
this.jobComplete = checkNotNull(jobComplete, "jobComplete");
}
@Override
public ImageTemplate buildImageTemplateFromNode(String name, String id) {
VirtualMachine vm = client.getVirtualMachineClient().getVirtualMachine(id);
if (vm == null)
throw new NoSuchElementException("Cannot find vm with id: " + id);
CloneImageTemplate template = new ImageTemplateBuilder.CloneImageTemplateBuilder().nodeId(id).name(name).build();
return template;
}
@Override
public ListenableFuture<Image> createImage(ImageTemplate template) {
checkState(template instanceof CloneImageTemplate,
" cloudstack only currently supports creating images through cloning.");
CloneImageTemplate cloneTemplate = (CloneImageTemplate) template;
VirtualMachine vm = client.getVirtualMachineClient().getVirtualMachine(cloneTemplate.getSourceNodeId());
String stopJob = client.getVirtualMachineClient().stopVirtualMachine(vm.getId());
jobComplete.apply(stopJob);
Set<Volume> volumes = client.getVolumeClient().listVolumes(ListVolumesOptions.Builder.virtualMachineId(vm.getId()));
Volume volume = Iterables.getOnlyElement(volumes);
CreateTemplateOptions options = CreateTemplateOptions.Builder.volumeId(volume.getId());
AsyncCreateResponse templateJob = client.getTemplateClient().createTemplate(TemplateMetadata.builder()
.name(cloneTemplate.getName())
.osTypeId(vm.getGuestOSId())
.displayText(cloneTemplate.getName())
.build(), options);
Template newTemplate = blockUntilJobCompletesAndReturnResult.<Template>apply(templateJob);
logger.info(">> Registered new template %s, waiting for it to become available.", newTemplate.getId());
final AtomicReference<Image> image = Atomics.newReference(new ImageBuilder()
.location(find(locations.get(), idEquals(vm.getZoneId())))
.id(newTemplate.getId())
.providerId(newTemplate.getId())
.description(cloneTemplate.getName())
.operatingSystem(OperatingSystem.builder().description(cloneTemplate.getName()).build())
.status(Image.Status.PENDING).build());
return userExecutor.submit(new Callable<Image>() {
@Override
public Image call() throws Exception {
if (imageAvailablePredicate.apply(image))
return image.get();
// TODO: get rid of the expectation that the image will be available, as it is very brittle
throw new UncheckedTimeoutException("Image was not created within the time limit: " + image.get());
}
});
}
@Override
public boolean deleteImage(String id) {
try {
AsyncCreateResponse deleteJob = client.getTemplateClient().deleteTemplate(id);
jobComplete.apply(deleteJob.getJobId());
return true;
} catch (Exception e) {
return false;
}
}
}

View File

@ -0,0 +1,200 @@
/*
* 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.cloudstack.compute.extensions;
import static org.testng.Assert.assertEquals;
import java.util.Map;
import java.util.Properties;
import org.jclouds.cloudstack.CloudStackContext;
import org.jclouds.cloudstack.compute.CloudStackComputeService;
import org.jclouds.cloudstack.internal.BaseCloudStackComputeServiceContextExpectTest;
import org.jclouds.compute.ComputeService;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.ImageTemplate;
import org.jclouds.compute.extensions.ImageExtension;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse;
import org.testng.annotations.Test;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMap.Builder;
import com.google.common.util.concurrent.Futures;
import com.google.inject.Injector;
import com.google.inject.Module;
/**
*
* @author Andrew Bayer
*/
@Test(groups = "unit", testName = "CloudStackImageExtensionExpectTest")
public class CloudStackImageExtensionExpectTest extends BaseCloudStackComputeServiceContextExpectTest<ComputeService> {
@Override
protected Properties setupProperties() {
Properties overrides = super.setupProperties();
overrides.setProperty("jclouds.zones", "MTV-Zone1");
return overrides;
}
public void testCreateImage() {
HttpRequest listVM = HttpRequest.builder().method("GET")
.endpoint("http://localhost:8080/client/api")
.addQueryParam("response", "json")
.addQueryParam("command", "listVirtualMachines")
.addQueryParam("listAll", "true")
.addQueryParam("id", "3239ade9-fd25-405c-8eda-59f0313a3fb0")
.addQueryParam("apiKey", "APIKEY")
.addQueryParam("signature", "Qq7Br3qNsyr5ifWZHIrLAslhwm0%3D")
.addHeader("Accept", "application/json")
.build();
HttpResponse listVMResponse = HttpResponse.builder().statusCode(200)
.payload(payloadFromResource("/listvirtualmachinesresponse-imageextension.json"))
.build();
HttpRequest stopVM = HttpRequest.builder().method("GET")
.endpoint("http://localhost:8080/client/api")
.addQueryParam("response", "json")
.addQueryParam("command", "stopVirtualMachine")
.addQueryParam("id", "3239ade9-fd25-405c-8eda-59f0313a3fb0")
.addQueryParam("apiKey", "APIKEY")
.addQueryParam("signature", "y9vxRK61K8sDoWtvSJHIx5WO9AE%3D")
.addHeader("Accept", "application/json")
.build();
HttpResponse stopVMResponse = HttpResponse.builder().statusCode(200)
.payload(payloadFromResource("/stopvirtualmachineresponse-imageextension.json"))
.build();
HttpRequest stopAsyncJobResult = HttpRequest.builder().method("GET")
.endpoint("http://localhost:8080/client/api")
.addQueryParam("response", "json")
.addQueryParam("command", "queryAsyncJobResult")
.addQueryParam("jobid", "a7d5127b-24a2-4a44-a4a7-25a6d057b453")
.addQueryParam("apiKey", "APIKEY")
.addQueryParam("signature", "CVpnN%2FSbx%2FMCOOyj%2FoVAt3bn684%3D")
.addHeader("Accept", "application/json")
.build();
HttpResponse stopAsyncJobResultResponse = HttpResponse.builder().statusCode(200)
.payload(payloadFromResource("/queryasyncjobresultresponse-stopvirtualmachine-imageextension.json"))
.build();
HttpRequest listVolumes = HttpRequest.builder().method("GET")
.endpoint("http://localhost:8080/client/api")
.addQueryParam("response", "json")
.addQueryParam("command", "listVolumes")
.addQueryParam("listAll", "true")
.addQueryParam("virtualmachineid", "3239ade9-fd25-405c-8eda-59f0313a3fb0")
.addQueryParam("apiKey", "APIKEY")
.addQueryParam("signature", "drLPf9NE9ROZPOfeDkASiKa50t8%3D")
.addHeader("Accept", "application/json")
.build();
HttpResponse listVolumesResponse = HttpResponse.builder().statusCode(200)
.payload(payloadFromResource("/listvolumesresponse-imageextension.json"))
.build();
HttpRequest createTemplate = HttpRequest.builder().method("GET")
.endpoint("http://localhost:8080/client/api")
.addQueryParam("response", "json")
.addQueryParam("command", "createTemplate")
.addQueryParam("volumeid", "fe1ada16-57a0-40ae-b577-01a153690fb4")
.addQueryParam("name", "temp-template-ignore")
.addQueryParam("ostypeid", "45de18f1-87c6-4646-8099-95c61f2a300a")
.addQueryParam("displaytext", "temp-template-ignore")
.addQueryParam("apiKey", "APIKEY")
.addQueryParam("signature", "madHsBgxjYbM6JnZKYWajOlfPlY%3D")
.addHeader("Accept", "application/json")
.build();
HttpResponse createTemplateResponse = HttpResponse.builder().statusCode(200)
.payload(payloadFromResource("/createtemplateresponse-imageextension.json"))
.build();
HttpRequest createAsyncJobResult = HttpRequest.builder().method("GET")
.endpoint("http://localhost:8080/client/api")
.addQueryParam("response", "json")
.addQueryParam("command", "queryAsyncJobResult")
.addQueryParam("jobid", "4e345230-8fcc-48a3-8a37-c5fe960df671")
.addQueryParam("apiKey", "APIKEY")
.addQueryParam("signature", "6mTKL9fjz7bn6C7tOaZBzKdZwHs%3D")
.addHeader("Accept", "application/json")
.build();
HttpResponse createAsyncJobResultResponse = HttpResponse.builder().statusCode(200)
.payload(payloadFromResource("/queryasyncjobresultresponse-createtemplate-imageextension.json"))
.build();
HttpRequest getTemplate = HttpRequest.builder().method("GET")
.endpoint("http://localhost:8080/client/api")
.addQueryParam("response", "json")
.addQueryParam("command", "listTemplates")
.addQueryParam("listAll", "true")
.addQueryParam("templatefilter", "executable")
.addQueryParam("id", "3dc6ce25-a6cf-4d60-a664-3499993b511b")
.addQueryParam("apiKey", "APIKEY")
.addQueryParam("signature", "dXv%2Bl04EDd7hmrWv5CdW8v298RE%3D")
.addHeader("Accept", "application/json")
.build();
HttpResponse getTemplateResponse = HttpResponse.builder().statusCode(200)
.payload(payloadFromResource("/listtemplatesresponse-imageextension.json"))
.build();
Map<HttpRequest, HttpResponse> requestResponseMap = ImmutableMap.<HttpRequest, HttpResponse> builder()
.put(listTemplates, listTemplatesResponse)
.put(listOsTypes, listOsTypesResponse)
.put(listOsCategories, listOsCategoriesResponse)
.put(listZones, listZonesResponse)
.put(listServiceOfferings, listServiceOfferingsResponse)
.put(listAccounts, listAccountsResponse)
.put(listNetworks, listNetworksResponse)
.put(getZone, getZoneResponse)
.put(listVM, listVMResponse)
.put(stopVM, stopVMResponse)
.put(stopAsyncJobResult, stopAsyncJobResultResponse)
.put(listVolumes, listVolumesResponse)
.put(createTemplate, createTemplateResponse)
.put(createAsyncJobResult, createAsyncJobResultResponse)
.put(getTemplate, getTemplateResponse)
.build();
ImageExtension apiThatCreatesImage = requestsSendResponses(requestResponseMap).getImageExtension().get();
ImageTemplate newImageTemplate = apiThatCreatesImage.buildImageTemplateFromNode("temp-template-ignore", "3239ade9-fd25-405c-8eda-59f0313a3fb0");
Image image = Futures.getUnchecked(apiThatCreatesImage.createImage(newImageTemplate));
assertEquals(image.getId(), "3dc6ce25-a6cf-4d60-a664-3499993b511b");
}
@Override
public ComputeService createClient(Function<HttpRequest, HttpResponse> fn, Module module, Properties props) {
return clientFrom(createInjector(fn, module, props).getInstance(CloudStackContext.class));
}
@Override
protected ComputeService clientFrom(CloudStackContext context) {
return context.getComputeService();
}
}

View File

@ -0,0 +1,44 @@
/*
* 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.cloudstack.compute.extensions;
import org.jclouds.compute.extensions.ImageExtension;
import org.jclouds.compute.extensions.internal.BaseImageExtensionLiveTest;
import org.jclouds.sshj.config.SshjSshClientModule;
import org.testng.annotations.Test;
import com.google.inject.Module;
/**
* Live test for CloudStack {@link ImageExtension} implementation.
*
* @author Andrew Bayer
*
*/
@Test(groups = "live", singleThreaded = true, testName = "CloudStackImageExtensionLiveTest")
public class CloudStackImageExtensionLiveTest extends BaseImageExtensionLiveTest {
public CloudStackImageExtensionLiveTest() {
provider = "cloudstack";
}
@Override
protected Module getSshModule() {
return new SshjSshClientModule();
}
}

View File

@ -0,0 +1 @@
{ "createtemplateresponse" : {"id":"3dc6ce25-a6cf-4d60-a664-3499993b511b","jobid":"4e345230-8fcc-48a3-8a37-c5fe960df671"} }

View File

@ -0,0 +1 @@
{ "createtemplateresponse" : {"id":"3dc6ce25-a6cf-4d60-a664-3499993b511b","jobid":"4e345230-8fcc-48a3-8a37-c5fe960df671"} }

View File

@ -0,0 +1 @@
{ "listtemplatesresponse" : { "count":1 ,"template" : [ {"id":"3dc6ce25-a6cf-4d60-a664-3499993b511b","name":"temp-template-ignore","displaytext":"sometext","ispublic":false,"created":"2013-06-21T12:37:01-0700","isready":true,"passwordenabled":false,"format":"QCOW2","isfeatured":false,"crossZones":false,"ostypeid":"be820210-c741-4c36-9ba1-f38363bd37d5","ostypename":"CentOS 5.6 (32-bit)","account":"andrew","zoneid":"1","zonename":"San Jose 1","status":"Download Complete","size":26843545600,"templatetype":"USER","hypervisor":"KVM","domain":"ROOT","domainid":"41a4917b-7952-499d-ba7f-4c57464d3dc8","isextractable":false,"checksum":"6dd5d7f073ff951b033a8cadb877bde2","sourcetemplateid":"9d597afb-4d3d-4a69-bf45-f95b0d1ee160"} ] } }

View File

@ -0,0 +1,2 @@
{ "listvirtualmachinesresponse" : { "count":1 ,"virtualmachine" : [
{"id":"3239ade9-fd25-405c-8eda-59f0313a3fb0","name":"apb-cent32-bld","displayname":"apb-cent32-bld","account":"andrew","domainid":"41a4917b-7952-499d-ba7f-4c57464d3dc8","domain":"ROOT","created":"2013-04-16T16:25:57-0700","state":"Stopped","haenable":false,"zoneid":"1","zonename":"San Jose 1","hostid":"0","templateid":"9d597afb-4d3d-4a69-bf45-f95b0d1ee160","templatename":"centos-6.2-x32-template","templatedisplaytext":"CentOS 6.2 x32 Template","passwordenabled":false,"serviceofferingid":"7cc4f8c3-7c56-4155-9916-9f42072ea712","serviceofferingname":"Tiny","cpunumber":1,"cpuspeed":1600,"memory":1024,"cpuused":"0.01%","networkkbsread":319420,"networkkbswrite":3,"guestosid":"45de18f1-87c6-4646-8099-95c61f2a300a","rootdeviceid":0,"rootdevicetype":"Filesystem","securitygroup":[{"id":"50288900-28eb-4d7f-9c33-e4c26e3b66d2","name":"default","description":"Default Security Group"}],"nic":[{"id":"fd65b6fd-2c3e-4c8a-a0bc-6a5db4e8007a","networkid":"0c82cd9f-ca64-4df4-9300-b33d81562403","netmask":"255.255.254.0","gateway":"10.20.92.3","ipaddress":"10.20.92.96","traffictype":"Guest","type":"Shared","isdefault":true,"macaddress":"06:ec:68:00:0f:04"}],"hypervisor":"KVM","instancename":"i-4-69942-VM"} ] } }

View File

@ -0,0 +1,2 @@
{ "listvolumesresponse" : { "count":1 ,"volume" : [
{"id":"fe1ada16-57a0-40ae-b577-01a153690fb4","name":"ROOT-69942","zoneid":"1","zonename":"San Jose 1","type":"ROOT","deviceid":0,"virtualmachineid":"3239ade9-fd25-405c-8eda-59f0313a3fb0","vmname":"apb-cent32-bld","vmdisplayname":"apb-cent32-bld","vmstate":"Stopped","size":139264,"created":"2013-04-16T16:25:57-0700","state":"Ready","account":"andrew","domainid":"41a4917b-7952-499d-ba7f-4c57464d3dc8","domain":"ROOT","storagetype":"local","hypervisor":"KVM","storage":"c2422.halxg.cloudera.com","destroyed":false,"serviceofferingid":"7cc4f8c3-7c56-4155-9916-9f42072ea712","serviceofferingname":"Tiny","serviceofferingdisplaytext":"Tiny (1 core, 1GB RAM)","isextractable":false} ] } }

View File

@ -0,0 +1 @@
{ "listvolumesresponse" : { "count":1 ,"volume" : [ {"id":"fe1ada16-57a0-40ae-b577-01a153690fb4","name":"ROOT-69942","zoneid":"7dbc4787-ec2f-498d-95f0-848c8c81e5da","zonename":"MTV-Zone1","type":"ROOT","deviceid":0,"virtualmachineid":"3239ade9-fd25-405c-8eda-59f0313a3fb0","vmname":"apb-cent32-bld","vmdisplayname":"apb-cent32-bld","vmstate":"Stopped","size":139264,"created":"2013-04-16T16:25:57-0700","state":"Ready","account":"andrew","domainid":"41a4917b-7952-499d-ba7f-4c57464d3dc8","domain":"ROOT","storagetype":"local","hypervisor":"KVM","storage":"c2422.halxg.cloudera.com","destroyed":false,"serviceofferingid":"7cc4f8c3-7c56-4155-9916-9f42072ea712","serviceofferingname":"Tiny","serviceofferingdisplaytext":"Tiny (1 core, 1GB RAM)","isextractable":false} ] } }

View File

@ -0,0 +1,2 @@
{ "queryasyncjobresultresponse" :
{"accountid":"ee092437-d681-499e-b78b-f4e449128247","userid":"0c9608c8-188c-47df-a934-d66dc96b96e3","cmd":"com.cloud.api.commands.CreateTemplateCmd","jobstatus":1,"jobprocstatus":0,"jobresultcode":0,"jobresulttype":"object","jobresult":{"template":{"id":"3dc6ce25-a6cf-4d60-a664-3499993b511b","name":"temp-template-ignore","displaytext":"temp-template-ignore","ispublic":false,"created":"2013-06-21T12:37:01-0700","isready":true,"passwordenabled":false,"format":"QCOW2","isfeatured":false,"crossZones":false,"ostypeid":"be820210-c741-4c36-9ba1-f38363bd37d5","ostypename":"CentOS 5.6 (32-bit)","account":"andrew","zoneid":"1","zonename":"San Jose 1","status":"Download Complete","size":26843545600,"templatetype":"USER","hypervisor":"KVM","domain":"ROOT","domainid":"41a4917b-7952-499d-ba7f-4c57464d3dc8","isextractable":false,"checksum":"6dd5d7f073ff951b033a8cadb877bde2","sourcetemplateid":"9d597afb-4d3d-4a69-bf45-f95b0d1ee160"}},"created":"2013-06-21T12:31:33-0700","jobid":"4e345230-8fcc-48a3-8a37-c5fe960df671"} }

View File

@ -0,0 +1,2 @@
{ "queryasyncjobresultresponse" :
{"accountid":"ee092437-d681-499e-b78b-f4e449128247","userid":"0c9608c8-188c-47df-a934-d66dc96b96e3","cmd":"com.cloud.api.commands.StopVMCmd","jobstatus":1,"jobprocstatus":0,"jobresultcode":0,"jobresulttype":"object","jobresult":{"virtualmachine":{"id":"3239ade9-fd25-405c-8eda-59f0313a3fb0","name":"apb-cent32-bld","displayname":"apb-cent32-bld","account":"andrew","domainid":"41a4917b-7952-499d-ba7f-4c57464d3dc8","domain":"ROOT","created":"2013-04-16T16:25:57-0700","state":"Stopped","haenable":false,"zoneid":"1","zonename":"San Jose 1","hostid":"0","templateid":"9d597afb-4d3d-4a69-bf45-f95b0d1ee160","templatename":"centos-6.2-x32-template","templatedisplaytext":"CentOS 6.2 x32 Template","passwordenabled":false,"serviceofferingid":"7cc4f8c3-7c56-4155-9916-9f42072ea712","serviceofferingname":"Tiny","cpunumber":1,"cpuspeed":1600,"memory":1024,"cpuused":"-65.18%","networkkbsread":319420,"networkkbswrite":3,"guestosid":"45de18f1-87c6-4646-8099-95c61f2a300a","rootdeviceid":0,"rootdevicetype":"Filesystem","securitygroup":[{"id":"50288900-28eb-4d7f-9c33-e4c26e3b66d2","name":"default","description":"Default Security Group"}],"nic":[{"id":"fd65b6fd-2c3e-4c8a-a0bc-6a5db4e8007a","networkid":"0c82cd9f-ca64-4df4-9300-b33d81562403","netmask":"255.255.254.0","gateway":"10.20.92.3","ipaddress":"10.20.92.96","traffictype":"Guest","type":"Shared","isdefault":true,"macaddress":"06:ec:68:00:0f:04"}],"hypervisor":"KVM","instancename":"i-4-69942-VM"}},"created":"2013-06-21T12:49:59-0700","jobid":"a7d5127b-24a2-4a44-a4a7-25a6d057b453"} }

View File

@ -0,0 +1 @@
{ "stopvirtualmachineresponse" : {"jobid":"a7d5127b-24a2-4a44-a4a7-25a6d057b453"} }