diff --git a/server/src/com/cloud/api/commands/CreateVolumeCmd.java b/server/src/com/cloud/api/commands/CreateVolumeCmd.java index 31ec30f5c70..4cfb29a6139 100644 --- a/server/src/com/cloud/api/commands/CreateVolumeCmd.java +++ b/server/src/com/cloud/api/commands/CreateVolumeCmd.java @@ -163,6 +163,9 @@ public class CreateVolumeCmd extends BaseAsyncCreateCmd { if (volume.getPoolId() != null) { response.setStoragePoolName(ApiDBUtils.findStoragePoolById(volume.getPoolId()).getName()); } + + // if the volume was created from a snapshot, snapshotId will be set so we pass it back in the response + response.setSnapshotId(getSnapshotId()); response.setZoneId(volume.getDataCenterId()); response.setZoneName(ApiDBUtils.findZoneById(volume.getDataCenterId()).getName()); diff --git a/server/src/com/cloud/api/commands/DeployVMCmd.java b/server/src/com/cloud/api/commands/DeployVMCmd.java index 565dfa693b4..818748f0ad2 100644 --- a/server/src/com/cloud/api/commands/DeployVMCmd.java +++ b/server/src/com/cloud/api/commands/DeployVMCmd.java @@ -40,7 +40,7 @@ import com.cloud.user.UserContext; import com.cloud.uservm.UserVm; import com.cloud.vm.InstanceGroupVO; -@Implementation(createMethod="createVirtualMachine", method="startVirtualMachine", manager=Manager.UserVmManager, description="Creates and automatically starts a virtual machine based on a service offering, disk offering, and template.") +@Implementation(method="deployVirtualMachine", description="Creates and automatically starts a virtual machine based on a service offering, disk offering, and template.") public class DeployVMCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(DeployVMCmd.class.getName()); diff --git a/server/src/com/cloud/api/response/VolumeResponse.java b/server/src/com/cloud/api/response/VolumeResponse.java index 8a2099d380f..8d5b643da63 100644 --- a/server/src/com/cloud/api/response/VolumeResponse.java +++ b/server/src/com/cloud/api/response/VolumeResponse.java @@ -101,6 +101,9 @@ public class VolumeResponse extends BaseResponse { @SerializedName("storage") @Param(description="name of the primary storage hosting the disk volume") private String storagePoolName; + @SerializedName("snapshotid") @Param(description="ID of the snapshot from which this volume was created") + private Long snapshotId; + public Long getId() { return id; } @@ -308,4 +311,12 @@ public class VolumeResponse extends BaseResponse { public void setStoragePoolName(String storagePoolName) { this.storagePoolName = storagePoolName; } + + public Long getSnapshotId() { + return snapshotId; + } + + public void setSnapshotId(Long snapshotId) { + this.snapshotId = snapshotId; + } } diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index 8e4b680ab54..842e0330602 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -73,7 +73,6 @@ import com.cloud.api.commands.PreparePrimaryStorageForMaintenanceCmd; import com.cloud.api.commands.UpdateStoragePoolCmd; import com.cloud.async.AsyncInstanceCreateStatus; import com.cloud.async.AsyncJobManager; -import com.cloud.async.executor.VolumeOperationParam.VolumeOp; import com.cloud.capacity.CapacityVO; import com.cloud.capacity.dao.CapacityDao; import com.cloud.configuration.Config; @@ -507,7 +506,7 @@ public class StorageManagerImpl implements StorageManager { @DB protected Pair createVolumeFromSnapshot(VolumeVO volume, SnapshotVO snapshot, VMTemplateVO template, long virtualsize) { VolumeVO createdVolume = null; - Long volumeId = null; + Long volumeId = volume.getId(); String volumeFolder = null; @@ -524,7 +523,7 @@ public class StorageManagerImpl implements StorageManager { DiskOfferingVO diskOffering = _diskOfferingDao.findById(volume.getDiskOfferingId()); DataCenterVO dc = _dcDao.findById(volume.getDataCenterId()); - DiskProfile dskCh = createDiskCharacteristics(volume, template, dc, diskOffering); + DiskProfile dskCh = new DiskProfile(volume, diskOffering, template.getHypervisorType()); int retry = 0; // Determine what pod to store the volume in @@ -624,7 +623,7 @@ public class StorageManagerImpl implements StorageManager { VolumeVO originalVolume = _volsDao.findById(origVolumeId); // NOTE: Original volume could be destroyed and removed. VMTemplateVO template = null; if (originalVolume != null) { - template = _templateDao.findById(originalVolume.getTemplateId()); + template = _templateDao.findById(originalVolume.getTemplateId()); } // everything went well till now @@ -1669,15 +1668,18 @@ public class StorageManagerImpl implements StorageManager { throw rae; } + Long zoneId = null; + Long diskOfferingId = null; + Long size = null; // validate input parameters before creating the volume if (cmd.getSnapshotId() == null) { - Long zoneId = cmd.getZoneId(); + zoneId = cmd.getZoneId(); if ((zoneId == null)) { throw new InvalidParameterValueException("Missing parameter, zoneid must be specified."); } - Long diskOfferingId = cmd.getDiskOfferingId(); - Long size = cmd.getSize(); + diskOfferingId = cmd.getDiskOfferingId(); + size = cmd.getSize(); if ((diskOfferingId == null) && (size == null)) { throw new InvalidParameterValueException("Missing parameter(s),either a positive volume size or a valid disk offering id must be specified."); } else if ((diskOfferingId == null) && (size != null)) { @@ -1696,6 +1698,7 @@ public class StorageManagerImpl implements StorageManager { if ((diskOffering == null) || !DiskOfferingVO.Type.Disk.equals(diskOffering.getType())) { throw new InvalidParameterValueException("Please specify a valid disk offering."); } + size = diskOffering.getDiskSize(); } } else { Long snapshotId = cmd.getSnapshotId(); @@ -1703,7 +1706,12 @@ public class StorageManagerImpl implements StorageManager { if (snapshotCheck == null) { throw new ServerApiException (BaseCmd.SNAPSHOT_INVALID_PARAM_ERROR, "unable to find a snapshot with id " + snapshotId); } - + + VolumeVO vol = _volsDao.findById(snapshotCheck.getVolumeId()); + zoneId = vol.getDataCenterId(); + diskOfferingId = vol.getDiskOfferingId(); + size = vol.getSize(); + if (account != null) { if (isAdmin(account.getType())) { Account snapshotOwner = _accountDao.findById(snapshotCheck.getAccountId()); @@ -1715,13 +1723,6 @@ public class StorageManagerImpl implements StorageManager { } } } - - Long zoneId = cmd.getZoneId(); - // Check that the zone is valid - DataCenterVO zone = _dcDao.findById(zoneId); - if (zone == null) { - throw new InvalidParameterValueException("Please specify a valid zone."); - } // Check that there is a shared primary storage pool in the specified zone List storagePools = _storagePoolDao.listByDataCenterId(zoneId); @@ -1754,7 +1755,8 @@ public class StorageManagerImpl implements StorageManager { volume.setAccountId(targetAccount.getId()); volume.setDomainId(((account == null) ? Domain.ROOT_DOMAIN : account.getDomainId())); volume.setMirrorState(MirrorState.NOT_MIRRORED); - volume.setDiskOfferingId(cmd.getDiskOfferingId()); + volume.setDiskOfferingId(diskOfferingId); + volume.setSize(size); volume.setStorageResourceType(StorageResourceType.STORAGE_POOL); volume.setInstanceId(null); volume.setUpdated(new Date()); diff --git a/ui/new/css/main.css b/ui/new/css/main.css index c6dddd43198..b1c2a5547f9 100644 --- a/ui/new/css/main.css +++ b/ui/new/css/main.css @@ -1859,8 +1859,8 @@ a:hover.search_button { } .help_dropdown_box { - width:209px; - height:200px; + width:400px; + height:400px; float:left; position:absolute; background:#FFF repeat top left; @@ -1873,7 +1873,7 @@ a:hover.search_button { } .help_dropdown_box_titlebox { - width:190px; + width:380px; height:auto; float:left; margin:8px 0 0 10px; @@ -1912,26 +1912,78 @@ a:hover.search_button { } .help_dropdown_box_textbox { - width:190px; - height:140px; + width:380px; + height:340px; float:left; margin:0 0 0 10px; padding:0; - overflow-y:auto; overflow-y:scroll; + overflow-y:auto; overflow-x:hidden; +} + + +.help_dropdown_box_textbox a { + color:#2c8bbc; + font-size:11px; + font-weight:normal; + text-align:left; + margin:0; + padding:0; + text-decoration:underline; +} + +.help_dropdown_box_textbox a:link, .help_dropdown_box_textbox a:visited { + text-decoration:underline; } + +.help_dropdown_box_textbox a:hover { + text-decoration:underline; + color:#333; +} + + + +.help_dropdown_box_textbox ul { + width:350px; + height:auto; + float:left; + margin:12px 0 0 0; + padding:0; +} + +.help_dropdown_box_textbox li { + width:350px; + height:auto; + float:left; + background:url(../images/arrow.png) no-repeat top left; + margin:5px 0 0 0; + padding:0 0 0 16px; + font-size:11px; +} + +.help_dropdown_box_textbox h3{ + width:360px; + height:auto; + float:left; + color:#0D4861; + font-size:12px; + font-weight:normal; + text-align:left; + margin:12px 0 0 0; + padding:0; +} .help_dropdown_box_textbox p{ - width:190px; + width:360px; height:auto; float:left; color:#333; font-size:11px; font-weight:normal; text-align:left; - margin:12px 0 0 0; + margin:8px 0 0 0; padding:0; } diff --git a/ui/new/images/arrow.png b/ui/new/images/arrow.png new file mode 100644 index 00000000000..8fe85df567a Binary files /dev/null and b/ui/new/images/arrow.png differ diff --git a/ui/new/index.jsp b/ui/new/index.jsp index d83cd339f8f..9833a974946 100644 --- a/ui/new/index.jsp +++ b/ui/new/index.jsp @@ -273,6 +273,21 @@ long milliseconds = new Date().getTime();
+ + + +

Start VM

+

Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged.

+ + +

Stop VM

+

Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged.

It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.

+ +

Destroy VM

Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged.

It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.

diff --git a/ui/new/jsp/instance.jsp b/ui/new/jsp/instance.jsp index 12338d81ac1..e826901cb2f 100644 --- a/ui/new/jsp/instance.jsp +++ b/ui/new/jsp/instance.jsp @@ -26,7 +26,7 @@ <%=t.t("Volume")%>
<%=t.t("Statistics")%>
-
+
@@ -183,7 +183,7 @@ -