mirror of
https://github.com/apache/jclouds.git
synced 2025-02-08 19:15:24 +00:00
Merge pull request #200 from ahgittin/cloudstack-templates
Cloudstack volumes and snapshots improvements
This commit is contained in:
commit
dfd4861c3a
@ -48,6 +48,18 @@ public class BindTemplateMetadataToQueryParams implements Binder {
|
|||||||
request = ModifyRequest.addQueryParam(request, "name", metadata.getName(), uriBuilderProvider.get());
|
request = ModifyRequest.addQueryParam(request, "name", metadata.getName(), uriBuilderProvider.get());
|
||||||
request = ModifyRequest.addQueryParam(request, "ostypeid", metadata.getOsTypeId(), uriBuilderProvider.get());
|
request = ModifyRequest.addQueryParam(request, "ostypeid", metadata.getOsTypeId(), uriBuilderProvider.get());
|
||||||
request = ModifyRequest.addQueryParam(request, "displaytext", metadata.getDisplayText(), uriBuilderProvider.get());
|
request = ModifyRequest.addQueryParam(request, "displaytext", metadata.getDisplayText(), uriBuilderProvider.get());
|
||||||
|
if (metadata.getSnapshotId() != null) {
|
||||||
|
request = ModifyRequest.addQueryParam(request, "snapshotid", metadata.getSnapshotId(), uriBuilderProvider.get());
|
||||||
|
}
|
||||||
|
if (metadata.getVolumeId() != null) {
|
||||||
|
request = ModifyRequest.addQueryParam(request, "volumeid", metadata.getVolumeId(), uriBuilderProvider.get());
|
||||||
|
}
|
||||||
|
if (metadata.getVirtualMachineId() != null) {
|
||||||
|
request = ModifyRequest.addQueryParam(request, "virtualmachineid", metadata.getVirtualMachineId(), uriBuilderProvider.get());
|
||||||
|
}
|
||||||
|
if (metadata.getPasswordEnabled() != null) {
|
||||||
|
request = ModifyRequest.addQueryParam(request, "passwordenabled", metadata.getPasswordEnabled(), uriBuilderProvider.get());
|
||||||
|
}
|
||||||
return request;
|
return request;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,11 +18,13 @@
|
|||||||
*/
|
*/
|
||||||
package org.jclouds.cloudstack.domain;
|
package org.jclouds.cloudstack.domain;
|
||||||
|
|
||||||
import com.google.gson.annotations.SerializedName;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import com.google.common.base.CaseFormat;
|
||||||
|
import com.google.common.base.Objects;
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Richard Downer
|
* @author Richard Downer
|
||||||
@ -48,7 +50,7 @@ public class Snapshot implements Comparable<Snapshot> {
|
|||||||
private State state;
|
private State state;
|
||||||
private long volumeId;
|
private long volumeId;
|
||||||
private String volumeName;
|
private String volumeName;
|
||||||
private String volumeType;
|
private Volume.VolumeType volumeType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param id ID of the snapshot
|
* @param id ID of the snapshot
|
||||||
@ -157,27 +159,37 @@ public class Snapshot implements Comparable<Snapshot> {
|
|||||||
/**
|
/**
|
||||||
* @param volumeType type of the disk volume
|
* @param volumeType type of the disk volume
|
||||||
*/
|
*/
|
||||||
public Builder volumeType(String volumeType) {
|
public Builder volumeType(Volume.VolumeType volumeType) {
|
||||||
this.volumeType = volumeType;
|
this.volumeType = volumeType;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Snapshot build() {
|
||||||
|
return new Snapshot(id, account, created, domain, domainId, interval, jobId,
|
||||||
|
jobStatus, name, snapshotType, state, volumeId, volumeName, volumeType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static enum State {
|
}
|
||||||
|
|
||||||
BackedUp, Creating, BackingUp, UNRECOGNIZED;
|
public enum State {
|
||||||
|
|
||||||
public static State fromValue(String type) {
|
BACKED_UP, CREATING, BACKING_UP, UNRECOGNIZED;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, name());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static State fromValue(String state) {
|
||||||
try {
|
try {
|
||||||
return valueOf(checkNotNull(type, "type"));
|
return valueOf(CaseFormat.UPPER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, checkNotNull(state, "state")));
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
return UNRECOGNIZED;
|
return UNRECOGNIZED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static enum Type {
|
public enum Type {
|
||||||
|
|
||||||
MANUAL, RECURRING, UNRECOGNIZED;
|
MANUAL, RECURRING, UNRECOGNIZED;
|
||||||
|
|
||||||
@ -190,7 +202,7 @@ public class Snapshot implements Comparable<Snapshot> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static enum Interval {
|
public enum Interval {
|
||||||
|
|
||||||
HOURLY, DAILY, WEEKLY, MONTHLY, template, none, UNRECOGNIZED;
|
HOURLY, DAILY, WEEKLY, MONTHLY, template, none, UNRECOGNIZED;
|
||||||
|
|
||||||
@ -224,7 +236,25 @@ public class Snapshot implements Comparable<Snapshot> {
|
|||||||
@SerializedName("volumename")
|
@SerializedName("volumename")
|
||||||
private String volumeName;
|
private String volumeName;
|
||||||
@SerializedName("volumetype")
|
@SerializedName("volumetype")
|
||||||
private String volumeType; // FIXME: replace this with a proper enumerated type (blocked until volume API implemented)
|
private Volume.VolumeType volumeType;
|
||||||
|
|
||||||
|
public Snapshot(long id, String account, Date created, String domain, long domainId, Interval interval, long jobId,
|
||||||
|
String jobStatus, String name, Type snapshotType, State state, long volumeId, String volumeName, Volume.VolumeType volumeType) {
|
||||||
|
this.id = id;
|
||||||
|
this.account = account;
|
||||||
|
this.created = created;
|
||||||
|
this.domain = domain;
|
||||||
|
this.domainId = domainId;
|
||||||
|
this.interval = interval;
|
||||||
|
this.jobId = jobId;
|
||||||
|
this.jobStatus = jobStatus;
|
||||||
|
this.name = name;
|
||||||
|
this.snapshotType = snapshotType;
|
||||||
|
this.state = state;
|
||||||
|
this.volumeId = volumeId;
|
||||||
|
this.volumeName = volumeName;
|
||||||
|
this.volumeType = volumeType;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* present only for serializer
|
* present only for serializer
|
||||||
@ -326,7 +356,7 @@ public class Snapshot implements Comparable<Snapshot> {
|
|||||||
/**
|
/**
|
||||||
* @return type of the disk volume
|
* @return type of the disk volume
|
||||||
*/
|
*/
|
||||||
public String getVolumeType() {
|
public Volume.VolumeType getVolumeType() {
|
||||||
return volumeType;
|
return volumeType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -335,22 +365,22 @@ public class Snapshot implements Comparable<Snapshot> {
|
|||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
|
||||||
Snapshot snapshot = (Snapshot) o;
|
Snapshot that = (Snapshot) o;
|
||||||
|
|
||||||
if (domainId != snapshot.domainId) return false;
|
if (!Objects.equal(domainId, that.domainId)) return false;
|
||||||
if (id != snapshot.id) return false;
|
if (!Objects.equal(id, that.id)) return false;
|
||||||
if (jobId != snapshot.jobId) return false;
|
if (!Objects.equal(jobId, that.jobId)) return false;
|
||||||
if (volumeId != snapshot.volumeId) return false;
|
if (!Objects.equal(volumeId, that.volumeId)) return false;
|
||||||
if (account != null ? !account.equals(snapshot.account) : snapshot.account != null) return false;
|
if (!Objects.equal(account, that.account)) return false;
|
||||||
if (created != null ? !created.equals(snapshot.created) : snapshot.created != null) return false;
|
if (!Objects.equal(created, that.created)) return false;
|
||||||
if (domain != null ? !domain.equals(snapshot.domain) : snapshot.domain != null) return false;
|
if (!Objects.equal(domain, that.domain)) return false;
|
||||||
if (interval != snapshot.interval) return false;
|
if (!Objects.equal(interval, that.interval)) return false;
|
||||||
if (jobStatus != null ? !jobStatus.equals(snapshot.jobStatus) : snapshot.jobStatus != null) return false;
|
if (!Objects.equal(jobStatus, that.jobStatus)) return false;
|
||||||
if (name != null ? !name.equals(snapshot.name) : snapshot.name != null) return false;
|
if (!Objects.equal(name, that.name)) return false;
|
||||||
if (snapshotType != snapshot.snapshotType) return false;
|
if (!Objects.equal(snapshotType, that.snapshotType)) return false;
|
||||||
if (state != snapshot.state) return false;
|
if (!Objects.equal(state, that.state)) return false;
|
||||||
if (volumeName != null ? !volumeName.equals(snapshot.volumeName) : snapshot.volumeName != null) return false;
|
if (!Objects.equal(volumeName, that.volumeName)) return false;
|
||||||
if (volumeType != null ? !volumeType.equals(snapshot.volumeType) : snapshot.volumeType != null) return false;
|
if (!Objects.equal(volumeType, that.volumeType)) return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -86,6 +86,9 @@ public class SnapshotPolicy implements Comparable<SnapshotPolicy> {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SnapshotPolicy build() {
|
||||||
|
return new SnapshotPolicy(id, interval, numberToRetain, schedule, timezone, volumeId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private long id;
|
private long id;
|
||||||
@ -98,6 +101,15 @@ public class SnapshotPolicy implements Comparable<SnapshotPolicy> {
|
|||||||
@SerializedName("volumeid")
|
@SerializedName("volumeid")
|
||||||
private long volumeId;
|
private long volumeId;
|
||||||
|
|
||||||
|
public SnapshotPolicy(long id, Snapshot.Interval interval, long numberToRetain, String schedule, String timezone, long volumeId) {
|
||||||
|
this.id = id;
|
||||||
|
this.interval = interval;
|
||||||
|
this.numberToRetain = numberToRetain;
|
||||||
|
this.schedule = schedule;
|
||||||
|
this.timezone = timezone;
|
||||||
|
this.volumeId = volumeId;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* present only for serializer
|
* present only for serializer
|
||||||
*/
|
*/
|
||||||
|
@ -211,6 +211,7 @@ public class Template implements Comparable<Template> {
|
|||||||
|
|
||||||
USER, BUILTIN, UNRECOGNIZED;
|
USER, BUILTIN, UNRECOGNIZED;
|
||||||
|
|
||||||
|
//TODO do we need camel case routines (e.g. see enums in VirtualMachine) ?
|
||||||
public static Type fromValue(String type) {
|
public static Type fromValue(String type) {
|
||||||
try {
|
try {
|
||||||
return valueOf(checkNotNull(type, "type"));
|
return valueOf(checkNotNull(type, "type"));
|
||||||
|
@ -18,6 +18,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.jclouds.cloudstack.domain;
|
package org.jclouds.cloudstack.domain;
|
||||||
|
|
||||||
|
import com.google.common.base.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Richard Downer
|
* @author Richard Downer
|
||||||
*/
|
*/
|
||||||
@ -28,13 +30,17 @@ public class TemplateMetadata {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Builder {
|
public static class Builder {
|
||||||
|
|
||||||
private String name;
|
private String name;
|
||||||
private long osTypeId;
|
private long osTypeId;
|
||||||
private String displayText;
|
private String displayText;
|
||||||
|
private Long snapshotId;
|
||||||
|
private Long volumeId;
|
||||||
|
private Long virtualMachineId;
|
||||||
|
private Boolean passwordEnabled;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param name the name of the template
|
* @param name
|
||||||
|
* the name of the template
|
||||||
*/
|
*/
|
||||||
public Builder name(String name) {
|
public Builder name(String name) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
@ -42,7 +48,8 @@ public class TemplateMetadata {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param osTypeId the ID of the OS Type that best represents the OS of this template.
|
* @param osTypeId
|
||||||
|
* the ID of the OS Type that best represents the OS of this template.
|
||||||
*/
|
*/
|
||||||
public Builder osTypeId(long osTypeId) {
|
public Builder osTypeId(long osTypeId) {
|
||||||
this.osTypeId = osTypeId;
|
this.osTypeId = osTypeId;
|
||||||
@ -50,15 +57,58 @@ public class TemplateMetadata {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param displayText the display text of the template. This is usually used for display purposes.
|
* @param displayText
|
||||||
|
* the display text of the template. This is usually used for display purposes.
|
||||||
*/
|
*/
|
||||||
public Builder displayText(String displayText) {
|
public Builder displayText(String displayText) {
|
||||||
this.displayText = displayText;
|
this.displayText = displayText;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param snapshotId
|
||||||
|
* the ID of the snapshot the template is being created from.
|
||||||
|
* Either this parameter, or volumeId has to be passed in
|
||||||
|
*/
|
||||||
|
public Builder snapshotId(Long snapshotId) {
|
||||||
|
this.snapshotId = snapshotId;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param volumeId
|
||||||
|
* the ID of the disk volume the template is being created from.
|
||||||
|
* Either this parameter, or snapshotId has to be passed in
|
||||||
|
*/
|
||||||
|
public Builder volumeId(Long volumeId) {
|
||||||
|
this.volumeId = volumeId;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param virtualMachineId
|
||||||
|
* the ID of the disk volume the template is being created from
|
||||||
|
*/
|
||||||
|
public Builder virtualMachineId(Long virtualMachineId) {
|
||||||
|
this.virtualMachineId = virtualMachineId;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the template supports the password reset feature.
|
||||||
|
*/
|
||||||
|
public Builder passwordEnabled() {
|
||||||
|
this.passwordEnabled = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public TemplateMetadata build() {
|
public TemplateMetadata build() {
|
||||||
return new TemplateMetadata(name, osTypeId, displayText);
|
TemplateMetadata template = new TemplateMetadata(name, osTypeId, displayText);
|
||||||
|
template.setPasswordEnabled(passwordEnabled);
|
||||||
|
template.setSnapshotId(snapshotId);
|
||||||
|
template.setVirtualMachineId(virtualMachineId);
|
||||||
|
template.setVolumeId(volumeId);
|
||||||
|
return template;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,6 +116,11 @@ public class TemplateMetadata {
|
|||||||
private long osTypeId;
|
private long osTypeId;
|
||||||
private String displayText;
|
private String displayText;
|
||||||
|
|
||||||
|
private Long snapshotId;
|
||||||
|
private Long volumeId;
|
||||||
|
private Long virtualMachineId;;
|
||||||
|
private Boolean passwordEnabled;
|
||||||
|
|
||||||
public TemplateMetadata(String name, long osTypeId, String displayText) {
|
public TemplateMetadata(String name, long osTypeId, String displayText) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.osTypeId = osTypeId;
|
this.osTypeId = osTypeId;
|
||||||
@ -78,6 +133,50 @@ public class TemplateMetadata {
|
|||||||
TemplateMetadata() {
|
TemplateMetadata() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the ID of the snapshot the template is being created from
|
||||||
|
*/
|
||||||
|
public Long getSnapshotId() {
|
||||||
|
return snapshotId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSnapshotId(Long snapshotId) {
|
||||||
|
this.snapshotId = snapshotId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the ID of the disk volume the template is being created from
|
||||||
|
*/
|
||||||
|
public Long getVolumeId() {
|
||||||
|
return volumeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVolumeId(Long volumeId) {
|
||||||
|
this.volumeId = volumeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Optional, VM ID
|
||||||
|
*/
|
||||||
|
public Long getVirtualMachineId() {
|
||||||
|
return virtualMachineId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVirtualMachineId(Long virtualMachineId) {
|
||||||
|
this.virtualMachineId = virtualMachineId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if the template supports the password reset feature; default is false
|
||||||
|
*/
|
||||||
|
public Boolean getPasswordEnabled() {
|
||||||
|
return passwordEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPasswordEnabled(Boolean passwordEnabled) {
|
||||||
|
this.passwordEnabled = passwordEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the name of the template
|
* @return the name of the template
|
||||||
*/
|
*/
|
||||||
@ -106,28 +205,24 @@ public class TemplateMetadata {
|
|||||||
|
|
||||||
TemplateMetadata that = (TemplateMetadata) o;
|
TemplateMetadata that = (TemplateMetadata) o;
|
||||||
|
|
||||||
if (osTypeId != that.osTypeId) return false;
|
if (!Objects.equal(osTypeId, that.osTypeId)) return false;
|
||||||
if (displayText != null ? !displayText.equals(that.displayText) : that.displayText != null) return false;
|
if (!Objects.equal(snapshotId, that.snapshotId)) return false;
|
||||||
if (name != null ? !name.equals(that.name) : that.name != null) return false;
|
if (!Objects.equal(volumeId, that.volumeId)) return false;
|
||||||
|
if (!Objects.equal(virtualMachineId, that.virtualMachineId)) return false;
|
||||||
|
if (!Objects.equal(passwordEnabled, that.passwordEnabled)) return false;
|
||||||
|
if (!Objects.equal(displayText, that.displayText)) return false;
|
||||||
|
if (!Objects.equal(name, that.name)) return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
int result = name != null ? name.hashCode() : 0;
|
return Objects.hashCode(name, displayText, osTypeId, snapshotId, volumeId, passwordEnabled, virtualMachineId);
|
||||||
result = 31 * result + (int) (osTypeId ^ (osTypeId >>> 32));
|
|
||||||
result = 31 * result + (displayText != null ? displayText.hashCode() : 0);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "[" +
|
return "[" + "name='" + name + '\'' + ", osTypeId=" + osTypeId + ", displayText='" + displayText + '\'' + ']';
|
||||||
"name='" + name + '\'' +
|
|
||||||
", osTypeId=" + osTypeId +
|
|
||||||
", displayText='" + displayText + '\'' +
|
|
||||||
']';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -955,18 +955,23 @@ public class VirtualMachine implements Comparable<VirtualMachine> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "[id=" + id + ", account=" + account + ", cpuCount=" + cpuCount + ", cpuSpeed=" + cpuSpeed + ", cpuUsed="
|
return "[id=" + id
|
||||||
+ cpuUsed + ", displayName=" + displayName + ", created=" + created + ", domain=" + domain + ", domainId="
|
// + ", account=" + account + ", cpuCount=" + cpuCount + ", cpuSpeed=" + cpuSpeed + ", cpuUsed=" + cpuUsed
|
||||||
+ domainId + ", usesVirtualNetwork=" + usesVirtualNetwork + ", group=" + group + ", groupId=" + groupId
|
+ ", displayName=" + displayName + ", created=" + created
|
||||||
+ ", guestOSId=" + guestOSId + ", HAEnabled=" + HAEnabled + ", hostId=" + hostId + ", hostname=" + hostname
|
// + ", domain=" + domain + ", domainId="
|
||||||
+ ", IPAddress=" + IPAddress + ", ISODisplayText=" + ISODisplayText + ", ISOId=" + ISOId + ", ISOName="
|
// + domainId + ", usesVirtualNetwork=" + usesVirtualNetwork + ", group=" + group + ", groupId=" + groupId
|
||||||
+ ISOName + ", jobId=" + jobId + ", jobStatus=" + jobStatus + ", memory=" + memory + ", name=" + name
|
// + ", guestOSId=" + guestOSId + ", HAEnabled=" + HAEnabled + ", hostId=" + hostId + ", hostname=" + hostname
|
||||||
+ ", networkKbsRead=" + networkKbsRead + ", networkKbsWrite=" + networkKbsWrite + ", password=" + password
|
+ ", IPAddress=" + IPAddress
|
||||||
+ ", passwordEnabled=" + passwordEnabled + ", rootDeviceId=" + rootDeviceId + ", rootDeviceType="
|
// + ", ISODisplayText=" + ISODisplayText + ", ISOId=" + ISOId + ", ISOName="
|
||||||
+ rootDeviceType + ", serviceOfferingId=" + serviceOfferingId + ", serviceOfferingName="
|
// + ISOName + ", jobId=" + jobId + ", jobStatus=" + jobStatus + ", memory=" + memory + ", name=" + name
|
||||||
+ serviceOfferingName + ", state=" + state + ", templateDisplayText=" + templateDisplayText
|
// + ", networkKbsRead=" + networkKbsRead + ", networkKbsWrite=" + networkKbsWrite + ", password=" + password
|
||||||
+ ", templateId=" + templateId + ", templateName=" + templateName + ", zoneId=" + zoneId + ", zoneName="
|
// + ", passwordEnabled=" + passwordEnabled + ", rootDeviceId=" + rootDeviceId + ", rootDeviceType="
|
||||||
+ zoneName + ", nics=" + nics + ", hypervisor=" + hypervisor + ", securityGroups=" + securityGroups + "]";
|
// + rootDeviceType + ", serviceOfferingId=" + serviceOfferingId + ", serviceOfferingName=" + serviceOfferingName
|
||||||
|
+ ", state=" + state
|
||||||
|
// + ", templateDisplayText=" + templateDisplayText
|
||||||
|
// + ", templateId=" + templateId + ", templateName=" + templateName + ", zoneId=" + zoneId + ", zoneName="
|
||||||
|
// + zoneName + ", nics=" + nics + ", hypervisor=" + hypervisor + ", securityGroups=" + securityGroups
|
||||||
|
+ "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -24,6 +24,9 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.jclouds.cloudstack.domain.VirtualMachine.State;
|
||||||
|
|
||||||
|
import com.google.common.base.CaseFormat;
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
@ -61,9 +64,8 @@ public class Volume implements Comparable<Volume> {
|
|||||||
private String serviceOfferingName;
|
private String serviceOfferingName;
|
||||||
private long size;
|
private long size;
|
||||||
private long snapshotId;
|
private long snapshotId;
|
||||||
private String state;
|
private State state;
|
||||||
private String storage;
|
private String storage;
|
||||||
// TODO enum
|
|
||||||
private String storageType;
|
private String storageType;
|
||||||
private VolumeType type;
|
private VolumeType type;
|
||||||
private long virtualMachineId;
|
private long virtualMachineId;
|
||||||
@ -173,7 +175,7 @@ public class Volume implements Comparable<Volume> {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder state(String state) {
|
public Builder state(State state) {
|
||||||
this.state = state;
|
this.state = state;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -231,11 +233,6 @@ public class Volume implements Comparable<Volume> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// for deserialization
|
|
||||||
Volume() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private long id;
|
private long id;
|
||||||
private Date attached;
|
private Date attached;
|
||||||
private Date created;
|
private Date created;
|
||||||
@ -257,7 +254,6 @@ public class Volume implements Comparable<Volume> {
|
|||||||
@SerializedName("jobid")
|
@SerializedName("jobid")
|
||||||
private long jobId;
|
private long jobId;
|
||||||
@SerializedName("jobstatus")
|
@SerializedName("jobstatus")
|
||||||
//TODO Change to enum
|
|
||||||
private String jobStatus;
|
private String jobStatus;
|
||||||
private String name;
|
private String name;
|
||||||
@SerializedName("serviceofferingdisplaytext")
|
@SerializedName("serviceofferingdisplaytext")
|
||||||
@ -269,9 +265,10 @@ public class Volume implements Comparable<Volume> {
|
|||||||
private long size;
|
private long size;
|
||||||
@SerializedName("snapshotid")
|
@SerializedName("snapshotid")
|
||||||
private long snapshotId;
|
private long snapshotId;
|
||||||
private String state;
|
private State state;
|
||||||
private String storage;
|
private String storage;
|
||||||
@SerializedName("storagetype")
|
@SerializedName("storagetype")
|
||||||
|
// MAYDO: this should perhaps be an enum; only value I have seen is "shared"
|
||||||
private String storageType;
|
private String storageType;
|
||||||
private VolumeType type;
|
private VolumeType type;
|
||||||
@SerializedName("virtualmachineid")
|
@SerializedName("virtualmachineid")
|
||||||
@ -291,7 +288,7 @@ public class Volume implements Comparable<Volume> {
|
|||||||
String diskOfferingDisplayText, long diskOfferingId, String diskOfferingName,
|
String diskOfferingDisplayText, long diskOfferingId, String diskOfferingName,
|
||||||
String domain, long domainId, String hypervisor, boolean extractable, long jobId,
|
String domain, long domainId, String hypervisor, boolean extractable, long jobId,
|
||||||
String jobStatus, String name, String serviceOfferingDisplayText, long serviceOfferingId,
|
String jobStatus, String name, String serviceOfferingDisplayText, long serviceOfferingId,
|
||||||
String serviceOfferingName, long size, long snapshotId, String state, String storage,
|
String serviceOfferingName, long size, long snapshotId, State state, String storage,
|
||||||
String storageType, VolumeType type, long virtualMachineId, String vmDisplayName, String vmName,
|
String storageType, VolumeType type, long virtualMachineId, String vmDisplayName, String vmName,
|
||||||
VirtualMachine.State vmState, long zoneId, String zoneName) {
|
VirtualMachine.State vmState, long zoneId, String zoneName) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
@ -326,6 +323,10 @@ public class Volume implements Comparable<Volume> {
|
|||||||
this.zoneName = zoneName;
|
this.zoneName = zoneName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// for deserialization
|
||||||
|
Volume() {
|
||||||
|
}
|
||||||
|
|
||||||
public long getId() {
|
public long getId() {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
@ -334,7 +335,6 @@ public class Volume implements Comparable<Volume> {
|
|||||||
return attached;
|
return attached;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Date getCreated() {
|
public Date getCreated() {
|
||||||
return created;
|
return created;
|
||||||
}
|
}
|
||||||
@ -407,7 +407,7 @@ public class Volume implements Comparable<Volume> {
|
|||||||
return snapshotId;
|
return snapshotId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getState() {
|
public State getState() {
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -535,6 +535,40 @@ public class Volume implements Comparable<Volume> {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return getClass().getCanonicalName()+"["+id+"; "+name+"; "+vmState+"]";
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum State {
|
||||||
|
|
||||||
|
/** indicates that the volume record is created in the DB, but not on the backend */
|
||||||
|
ALLOCATED,
|
||||||
|
/** the volume is being created on the backend */
|
||||||
|
CREATING,
|
||||||
|
/** the volume is ready to be used */
|
||||||
|
READY,
|
||||||
|
/** the volume is destroyed (either as a result of deleteVolume command for DataDisk or as a part of destroyVm) */
|
||||||
|
DESTROYED,
|
||||||
|
/** the volume has failed somehow, e.g. during creation (in cloudstack development) */
|
||||||
|
FAILED,
|
||||||
|
|
||||||
|
UNRECOGNIZED;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, name());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static State fromValue(String state) {
|
||||||
|
try {
|
||||||
|
return valueOf(CaseFormat.UPPER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, checkNotNull(state, "state")));
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
return UNRECOGNIZED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public enum VolumeType {
|
public enum VolumeType {
|
||||||
ROOT(0),
|
ROOT(0),
|
||||||
DATADISK(1),
|
DATADISK(1),
|
||||||
|
@ -49,6 +49,7 @@ import org.jclouds.cloudstack.predicates.VirtualMachineDestroyed;
|
|||||||
import org.jclouds.cloudstack.predicates.VirtualMachineRunning;
|
import org.jclouds.cloudstack.predicates.VirtualMachineRunning;
|
||||||
import org.jclouds.cloudstack.strategy.BlockUntilJobCompletesAndReturnResult;
|
import org.jclouds.cloudstack.strategy.BlockUntilJobCompletesAndReturnResult;
|
||||||
import org.jclouds.compute.BaseVersionedServiceLiveTest;
|
import org.jclouds.compute.BaseVersionedServiceLiveTest;
|
||||||
|
import org.jclouds.compute.ComputeService;
|
||||||
import org.jclouds.compute.ComputeServiceContextFactory;
|
import org.jclouds.compute.ComputeServiceContextFactory;
|
||||||
import org.jclouds.compute.domain.ExecResponse;
|
import org.jclouds.compute.domain.ExecResponse;
|
||||||
import org.jclouds.domain.Credentials;
|
import org.jclouds.domain.Credentials;
|
||||||
@ -130,6 +131,7 @@ public class BaseCloudStackClientLiveTest extends BaseVersionedServiceLiveTest {
|
|||||||
protected String prefix = System.getProperty("user.name");
|
protected String prefix = System.getProperty("user.name");
|
||||||
|
|
||||||
protected CloudStackContext computeContext;
|
protected CloudStackContext computeContext;
|
||||||
|
protected ComputeService computeClient;
|
||||||
protected RestContext<CloudStackClient, CloudStackAsyncClient> context;
|
protected RestContext<CloudStackClient, CloudStackAsyncClient> context;
|
||||||
protected CloudStackClient client;
|
protected CloudStackClient client;
|
||||||
protected CloudStackClient adminClient;
|
protected CloudStackClient adminClient;
|
||||||
@ -173,8 +175,10 @@ public class BaseCloudStackClientLiveTest extends BaseVersionedServiceLiveTest {
|
|||||||
public void setupClient() {
|
public void setupClient() {
|
||||||
setupCredentials();
|
setupCredentials();
|
||||||
|
|
||||||
computeContext = CloudStackContext.class.cast(new ComputeServiceContextFactory().createContext(provider,
|
computeContext = CloudStackContext.class.cast(new ComputeServiceContextFactory(setupRestProperties()).
|
||||||
ImmutableSet.<Module> of(new Log4JLoggingModule(), new SshjSshClientModule()), setupProperties()));
|
createContext(provider, ImmutableSet.<Module> of(
|
||||||
|
new Log4JLoggingModule(), new SshjSshClientModule()), setupProperties()));
|
||||||
|
computeClient = computeContext.getComputeService();
|
||||||
context = computeContext.getProviderSpecificContext();
|
context = computeContext.getProviderSpecificContext();
|
||||||
client = context.getApi();
|
client = context.getApi();
|
||||||
user = verifyCurrentUserIsOfType(context, Account.Type.USER);
|
user = verifyCurrentUserIsOfType(context, Account.Type.USER);
|
||||||
@ -182,9 +186,9 @@ public class BaseCloudStackClientLiveTest extends BaseVersionedServiceLiveTest {
|
|||||||
domainAdminEnabled = setupAdminProperties() != null;
|
domainAdminEnabled = setupAdminProperties() != null;
|
||||||
|
|
||||||
if (domainAdminEnabled) {
|
if (domainAdminEnabled) {
|
||||||
domainAdminComputeContext = CloudStackContext.class.cast(new ComputeServiceContextFactory().createContext(
|
domainAdminComputeContext = CloudStackContext.class.cast(new ComputeServiceContextFactory(setupRestProperties()).
|
||||||
provider, ImmutableSet.<Module> of(new Log4JLoggingModule(), new SshjSshClientModule()),
|
createContext(provider, ImmutableSet.<Module> of(
|
||||||
setupAdminProperties()));
|
new Log4JLoggingModule(), new SshjSshClientModule()), setupAdminProperties()));
|
||||||
domainAdminContext = domainAdminComputeContext.getDomainContext();
|
domainAdminContext = domainAdminComputeContext.getDomainContext();
|
||||||
domainAdminClient = domainAdminContext.getApi();
|
domainAdminClient = domainAdminContext.getApi();
|
||||||
domainAdminUser = verifyCurrentUserIsOfType(domainAdminContext, Account.Type.DOMAIN_ADMIN);
|
domainAdminUser = verifyCurrentUserIsOfType(domainAdminContext, Account.Type.DOMAIN_ADMIN);
|
||||||
|
@ -28,9 +28,15 @@ import static org.testng.AssertJUnit.assertTrue;
|
|||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
import org.jclouds.cloudstack.domain.AsyncCreateResponse;
|
import org.jclouds.cloudstack.domain.AsyncCreateResponse;
|
||||||
import org.jclouds.cloudstack.domain.Snapshot;
|
import org.jclouds.cloudstack.domain.Snapshot;
|
||||||
|
import org.jclouds.cloudstack.domain.Volume;
|
||||||
import org.jclouds.cloudstack.options.ListSnapshotsOptions;
|
import org.jclouds.cloudstack.options.ListSnapshotsOptions;
|
||||||
|
import org.jclouds.logging.Logger;
|
||||||
|
import org.jclouds.predicates.PredicateCallable;
|
||||||
|
import org.jclouds.predicates.Retryables;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
@ -40,11 +46,13 @@ import com.google.common.collect.Iterables;
|
|||||||
/**
|
/**
|
||||||
* Tests behavior of {@code SnapshotClient}
|
* Tests behavior of {@code SnapshotClient}
|
||||||
*
|
*
|
||||||
* @author grkvlt@apache.org
|
* @author grkvlt@apache.org, Alex Heneveld
|
||||||
*/
|
*/
|
||||||
@Test(groups = "live", singleThreaded = true, testName = "SnapshotClientLiveTest")
|
@Test(groups = "live", singleThreaded = true, testName = "SnapshotClientLiveTest")
|
||||||
public class SnapshotClientLiveTest extends BaseCloudStackClientLiveTest {
|
public class SnapshotClientLiveTest extends BaseCloudStackClientLiveTest {
|
||||||
|
|
||||||
|
@Resource Logger logger = Logger.NULL;
|
||||||
|
|
||||||
public void testListSnapshots() {
|
public void testListSnapshots() {
|
||||||
Set<Snapshot> snapshots = client.getSnapshotClient().listSnapshots();
|
Set<Snapshot> snapshots = client.getSnapshotClient().listSnapshots();
|
||||||
assertNotNull(snapshots);
|
assertNotNull(snapshots);
|
||||||
@ -102,24 +110,30 @@ public class SnapshotClientLiveTest extends BaseCloudStackClientLiveTest {
|
|||||||
assertNull(found);
|
assertNull(found);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected Volume getPreferredVolume() {
|
||||||
|
for (Volume candidate : client.getVolumeClient().listVolumes()) {
|
||||||
|
if (candidate.getState() == Volume.State.READY)
|
||||||
|
return candidate;
|
||||||
|
}
|
||||||
|
throw new AssertionError("No suitable Volume found.");
|
||||||
|
}
|
||||||
|
|
||||||
public void testCreateSnapshotFromVolume() {
|
public void testCreateSnapshotFromVolume() {
|
||||||
// Pick some volume
|
final Volume volume = getPreferredVolume(); //fail fast if none
|
||||||
long volumeId = Iterables.get(client.getVolumeClient().listVolumes(), 0).getId();
|
|
||||||
|
|
||||||
Snapshot snapshot = null;
|
Snapshot snapshot = Retryables.retryGettingResultOrFailing(new PredicateCallable<Snapshot>() {
|
||||||
while (snapshot == null) {
|
public Snapshot call() {
|
||||||
try {
|
logger.info("creating snapshot from volume %s", volume);
|
||||||
AsyncCreateResponse job = client.getSnapshotClient().createSnapshot(volumeId);
|
AsyncCreateResponse job = client.getSnapshotClient().createSnapshot(volume.getId());
|
||||||
assertTrue(jobComplete.apply(job.getJobId()));
|
assertTrue(jobComplete.apply(job.getJobId()));
|
||||||
snapshot = findSnapshotWithId(job.getId());
|
return findSnapshotWithId(job.getId());
|
||||||
} catch (IllegalStateException e) {
|
|
||||||
// TODO snapshot creation failed - retry?
|
|
||||||
}
|
}
|
||||||
|
protected void onFailure() {
|
||||||
|
logger.info("failed creating snapshot (retrying): %s", getLastFailure());
|
||||||
}
|
}
|
||||||
|
}, null, 60*1000, "failed to create snapshot");
|
||||||
|
logger.info("created snapshot %s from volume %s", snapshot, volume);
|
||||||
checkSnapshot(snapshot);
|
checkSnapshot(snapshot);
|
||||||
|
|
||||||
// Delete the snapshot
|
|
||||||
client.getSnapshotClient().deleteSnapshot(snapshot.getId());
|
client.getSnapshotClient().deleteSnapshot(snapshot.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ import static org.jclouds.cloudstack.options.ListTemplatesOptions.Builder.zoneId
|
|||||||
import static org.testng.Assert.*;
|
import static org.testng.Assert.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests behavior of {@code TemplateClientLiveTest}
|
* Tests behavior of {@code TemplateClient}
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
|
@ -18,31 +18,46 @@
|
|||||||
*/
|
*/
|
||||||
package org.jclouds.cloudstack.features;
|
package org.jclouds.cloudstack.features;
|
||||||
|
|
||||||
import static com.google.common.collect.Iterables.*;
|
import static org.testng.AssertJUnit.assertEquals;
|
||||||
import static org.testng.AssertJUnit.*;
|
import static org.testng.AssertJUnit.assertFalse;
|
||||||
|
import static org.testng.AssertJUnit.assertNotNull;
|
||||||
|
import static org.testng.AssertJUnit.assertNotSame;
|
||||||
|
import static org.testng.AssertJUnit.assertNull;
|
||||||
|
import static org.testng.AssertJUnit.assertTrue;
|
||||||
|
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
|
import org.jclouds.cloudstack.CloudStackClient;
|
||||||
import org.jclouds.cloudstack.domain.AsyncCreateResponse;
|
import org.jclouds.cloudstack.domain.AsyncCreateResponse;
|
||||||
|
import org.jclouds.cloudstack.domain.DiskOffering;
|
||||||
import org.jclouds.cloudstack.domain.Snapshot;
|
import org.jclouds.cloudstack.domain.Snapshot;
|
||||||
|
import org.jclouds.cloudstack.domain.VirtualMachine;
|
||||||
import org.jclouds.cloudstack.domain.Volume;
|
import org.jclouds.cloudstack.domain.Volume;
|
||||||
import org.jclouds.cloudstack.domain.Zone;
|
import org.jclouds.cloudstack.domain.Zone;
|
||||||
import org.jclouds.cloudstack.options.ListVolumesOptions;
|
import org.jclouds.cloudstack.options.ListVolumesOptions;
|
||||||
|
import org.jclouds.logging.Logger;
|
||||||
|
import org.jclouds.predicates.PredicateCallable;
|
||||||
|
import org.jclouds.predicates.Retryables;
|
||||||
import org.testng.annotations.BeforeMethod;
|
import org.testng.annotations.BeforeMethod;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Function;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests behavior of {@code VolumeClient}
|
* Tests behavior of {@code VolumeClient}
|
||||||
*
|
*
|
||||||
* @author Vijay Kiran
|
* @author Vijay Kiran, Alex Heneveld
|
||||||
*/
|
*/
|
||||||
@Test(groups = "live", singleThreaded = true, testName = "VolumeClientLiveTest")
|
@Test(groups = "live", singleThreaded = true, testName = "VolumeClientLiveTest")
|
||||||
public class VolumeClientLiveTest extends BaseCloudStackClientLiveTest {
|
public class VolumeClientLiveTest extends BaseCloudStackClientLiveTest {
|
||||||
protected String prefix = System.getProperty("user.name");
|
|
||||||
|
@Resource Logger logger = Logger.NULL;
|
||||||
|
|
||||||
|
protected String prefix = System.getProperty("user.name")+"-"+getClass().getSimpleName();
|
||||||
|
|
||||||
private long zoneId;
|
private long zoneId;
|
||||||
|
|
||||||
@ -111,114 +126,141 @@ public class VolumeClientLiveTest extends BaseCloudStackClientLiveTest {
|
|||||||
assertNull(found);
|
assertNull(found);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testCreateVolumeFromDiskofferingInZoneAndDeleteVolume() {
|
protected DiskOffering getPreferredDiskOffering() {
|
||||||
// Pick some disk offering
|
for (DiskOffering candidate : client.getOfferingClient().listDiskOfferings()) {
|
||||||
long diskOfferingId = Iterables.get(client.getOfferingClient().listDiskOfferings(), 0).getId();
|
//any will do
|
||||||
|
return candidate;
|
||||||
|
}
|
||||||
|
throw new AssertionError("No suitable DiskOffering found.");
|
||||||
|
}
|
||||||
|
protected Snapshot getPreferredSnapshot() {
|
||||||
|
for (Snapshot candidate : client.getSnapshotClient().listSnapshots()) {
|
||||||
|
if (candidate.getState()==Snapshot.State.BACKED_UP)
|
||||||
|
return candidate;
|
||||||
|
}
|
||||||
|
throw new AssertionError("No suitable Snapshot found.");
|
||||||
|
}
|
||||||
|
|
||||||
Volume volume = null;
|
protected VirtualMachine getPreferredVirtualMachine() {
|
||||||
while (volume == null) {
|
for (VirtualMachine candidate : client.getVirtualMachineClient().listVirtualMachines()) {
|
||||||
try {
|
// this is a guess::
|
||||||
AsyncCreateResponse job = client.getVolumeClient().createVolumeFromDiskOfferingInZone(prefix + "-jclouds-volume",
|
if (candidate.getState()==VirtualMachine.State.RUNNING || candidate.getState()==VirtualMachine.State.STOPPED)
|
||||||
diskOfferingId, zoneId);
|
return candidate;
|
||||||
|
}
|
||||||
|
throw new AssertionError("No suitable VirtualMachine found.");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Volume createPreferredVolumeFromDisk() {
|
||||||
|
return Retryables.retryGettingResultOrFailing(new PredicateCallable<Volume>() {
|
||||||
|
public Volume call() {
|
||||||
|
AsyncCreateResponse job = client.getVolumeClient().createVolumeFromDiskOfferingInZone(
|
||||||
|
prefix+"-jclouds-volume", getPreferredDiskOffering().getId(), zoneId);
|
||||||
assertTrue(jobComplete.apply(job.getJobId()));
|
assertTrue(jobComplete.apply(job.getJobId()));
|
||||||
volume = findVolumeWithId(job.getId());
|
logger.info("created volume "+job.getId());
|
||||||
} catch (IllegalStateException e) {
|
return findVolumeWithId(job.getId());
|
||||||
// TODO volume creation failed - retry?
|
|
||||||
}
|
}
|
||||||
|
}, null, 60*1000, "failed to create volume");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testCreateVolumeFromDiskofferingInZoneAndDeleteVolume() {
|
||||||
|
logger.info("testCreateVolumeFromDiskofferingInZoneAndDeleteVolume");
|
||||||
|
Volume volume = createPreferredVolumeFromDisk();
|
||||||
checkVolume(volume);
|
checkVolume(volume);
|
||||||
|
|
||||||
// Delete the volume
|
|
||||||
client.getVolumeClient().deleteVolume(volume.getId());
|
client.getVolumeClient().deleteVolume(volume.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** test requires that a VM exist */
|
||||||
public void testCreateVolumeFromDiskofferingInZoneAndAttachVolumeToVirtualMachineAndDetachAndDelete() {
|
public void testCreateVolumeFromDiskofferingInZoneAndAttachVolumeToVirtualMachineAndDetachAndDelete() {
|
||||||
// Pick some disk offering
|
logger.info("testCreateVolumeFromDiskofferingInZoneAndAttachVolumeToVirtualMachineAndDetachAndDelete");
|
||||||
long diskOfferingId = Iterables.get(client.getOfferingClient().listDiskOfferings(), 0).getId();
|
final Volume volume = createPreferredVolumeFromDisk();
|
||||||
|
|
||||||
Volume volume = null;
|
|
||||||
while (volume == null) {
|
|
||||||
try {
|
try {
|
||||||
AsyncCreateResponse job = client.getVolumeClient().createVolumeFromDiskOfferingInZone(prefix + "-jclouds-volume",
|
|
||||||
diskOfferingId, zoneId);
|
|
||||||
assertTrue(jobComplete.apply(job.getJobId()));
|
|
||||||
volume = findVolumeWithId(job.getId());
|
|
||||||
} catch (IllegalStateException e) {
|
|
||||||
// TODO volume creation failed - retry?
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
checkVolume(volume);
|
checkVolume(volume);
|
||||||
long virtualMachineId = Iterables.get(client.getVirtualMachineClient().listVirtualMachines(), 0).getId();
|
|
||||||
|
|
||||||
// Attach Volume
|
final VirtualMachine virtualMachine = getPreferredVirtualMachine();
|
||||||
Volume attachedVolume = null;
|
|
||||||
while (attachedVolume == null) {
|
Volume attachedVolume = Retryables.retryGettingResultOrFailing(new PredicateCallable<Volume>() {
|
||||||
try {
|
public Volume call() {
|
||||||
AsyncCreateResponse job = client.getVolumeClient().attachVolume(volume.getId(), virtualMachineId);
|
logger.info("attaching volume %s to vm %s", volume, virtualMachine);
|
||||||
|
AsyncCreateResponse job = client.getVolumeClient().attachVolume(volume.getId(), virtualMachine.getId());
|
||||||
assertTrue(jobComplete.apply(job.getJobId()));
|
assertTrue(jobComplete.apply(job.getJobId()));
|
||||||
attachedVolume = findVolumeWithId(volume.getId());
|
return findVolumeWithId(volume.getId());
|
||||||
assertEquals(virtualMachineId, attachedVolume.getVirtualMachineId());
|
}
|
||||||
|
int failures=0;
|
||||||
|
protected void onFailure() {
|
||||||
|
logger.info("failed attaching volume (retrying): %s", getLastFailure());
|
||||||
|
if (failures++==0) logger.warn(getLastFailure(), "first failure attaching volume");
|
||||||
|
}
|
||||||
|
}, null, 60*1000, "failed to attach volume");
|
||||||
|
checkVolume(attachedVolume);
|
||||||
|
assertEquals(virtualMachine.getId(), attachedVolume.getVirtualMachineId());
|
||||||
assertNotNull(attachedVolume.getAttached());
|
assertNotNull(attachedVolume.getAttached());
|
||||||
} catch (IllegalStateException e) {
|
|
||||||
// TODO volume creation failed - retry?
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Detach Volume
|
Volume detachedVolume = Retryables.retryGettingResultOrFailing(new PredicateCallable<Volume>() {
|
||||||
Volume detachedVolume = null;
|
public Volume call() {
|
||||||
while (detachedVolume == null) {
|
logger.info("detaching volume %s from vm %s", volume, virtualMachine);
|
||||||
try {
|
|
||||||
AsyncCreateResponse job = client.getVolumeClient().detachVolume(volume.getId());
|
AsyncCreateResponse job = client.getVolumeClient().detachVolume(volume.getId());
|
||||||
assertTrue(jobComplete.apply(job.getJobId()));
|
assertTrue(jobComplete.apply(job.getJobId()));
|
||||||
detachedVolume = findVolumeWithId(volume.getId());
|
return findVolumeWithId(volume.getId());
|
||||||
|
}
|
||||||
|
protected void onFailure() {
|
||||||
|
logger.debug("failed detaching volume (retrying): %s", getLastFailure());
|
||||||
|
}
|
||||||
|
}, null, 60*1000, "failed to detach volume");
|
||||||
checkVolume(detachedVolume);
|
checkVolume(detachedVolume);
|
||||||
} catch (IllegalStateException e) {
|
assertNull(detachedVolume.getAttached());
|
||||||
//TODO volume creation failed - retry?
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cleanup
|
} finally {
|
||||||
client.getVolumeClient().deleteVolume(volume.getId());
|
client.getVolumeClient().deleteVolume(volume.getId());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void testCreateVolumeFromSnapshotInZoneAndDeleteVolume() {
|
public void testCreateVolumeFromSnapshotInZoneAndDeleteVolume() {
|
||||||
Set<Snapshot> snapshots = client.getSnapshotClient().listSnapshots();
|
logger.info("testCreateVolumeFromSnapshotInZoneAndDeleteVolume (takes ~3m)");
|
||||||
assertNotNull(snapshots);
|
assertNotNull(getPreferredSnapshot());
|
||||||
assertFalse(snapshots.isEmpty());
|
Volume volume = Retryables.retryGettingResultOrFailing(new PredicateCallable<Volume>() {
|
||||||
long snapshotId = Iterables.get(snapshots, 0).getId();
|
public Volume call() {
|
||||||
|
AsyncCreateResponse job = client.getVolumeClient().createVolumeFromSnapshotInZone(
|
||||||
Volume volume = null;
|
prefix+"-jclouds-volume", getPreferredSnapshot().getId(), zoneId);
|
||||||
while (volume == null) {
|
|
||||||
try {
|
|
||||||
AsyncCreateResponse job = client.getVolumeClient().createVolumeFromSnapshotInZone(prefix + "-jclouds-volume",
|
|
||||||
snapshotId, zoneId);
|
|
||||||
assertTrue(jobComplete.apply(job.getJobId()));
|
assertTrue(jobComplete.apply(job.getJobId()));
|
||||||
volume = findVolumeWithId(job.getId());
|
return findVolumeWithId(job.getId());
|
||||||
} catch (IllegalStateException e) {
|
|
||||||
// TODO volume creation failed - retry?
|
|
||||||
}
|
}
|
||||||
|
protected void onFailure() {
|
||||||
|
logger.debug("failed creating volume (retrying): %s", getLastFailure());
|
||||||
}
|
}
|
||||||
|
}, null, 60*1000, "failed to create volume");
|
||||||
|
|
||||||
checkVolume(volume);
|
checkVolume(volume);
|
||||||
|
|
||||||
// Delete the volume
|
|
||||||
client.getVolumeClient().deleteVolume(volume.getId());
|
client.getVolumeClient().deleteVolume(volume.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkVolume(final Volume volume) {
|
static void checkVolume(final Volume volume) {
|
||||||
assertNotNull(volume.getId());
|
assertNotNull(volume.getId());
|
||||||
assertNotNull(volume.getName());
|
assertNotNull(volume.getName());
|
||||||
assertNotSame(Volume.VolumeType.UNRECOGNIZED, volume.getType());
|
assertNotSame(Volume.VolumeType.UNRECOGNIZED, volume.getType());
|
||||||
}
|
}
|
||||||
|
|
||||||
private Volume findVolumeWithId(final long id) {
|
Volume findVolumeWithId(final long id) {
|
||||||
return find(client.getVolumeClient().listVolumes(), new Predicate<Volume>() {
|
return findVolumeWithId(client, id);
|
||||||
@Override
|
|
||||||
public boolean apply(Volume arg0) {
|
|
||||||
return arg0.getId() == id;
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
static Volume findVolumeWithId(final CloudStackClient client, final long id) {
|
||||||
|
for (Volume v: client.getVolumeClient().listVolumes())
|
||||||
|
if (v.getId()==id) return v;
|
||||||
|
throw new NoSuchElementException("no volume with id "+id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// //uncomment to force a cleanup of volumes (since test failures can leave messes)
|
||||||
|
// public void deleteAllWeUsed() {
|
||||||
|
// for (Volume v: client.getVolumeClient().listVolumes()) {
|
||||||
|
// if (v.getName().startsWith(prefix)) {
|
||||||
|
// logger.warn("found apparent detritus, deleting: %s", v);
|
||||||
|
// try {
|
||||||
|
// client.getVolumeClient().deleteVolume(v.getId());
|
||||||
|
// } catch (Exception e) {
|
||||||
|
// logger.warn(e, "failed to delete %s: %s", v, e);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user