Merge branch 'master' of ssh://anthony@git.cloud.com/var/lib/git/cloudstack-oss

This commit is contained in:
anthony 2010-09-10 15:14:19 -07:00
commit 55ebf465f6
24 changed files with 209 additions and 133 deletions

View File

@ -2200,4 +2200,5 @@ public interface ManagementServer {
VolumeVO findVolumeByInstanceAndDeviceId(long instanceId, long deviceId);
VolumeVO getRootVolume(Long instanceId);
long getPsMaintenanceCount(long podId);
boolean isPoolUp(long instanceId);
}

View File

@ -103,5 +103,7 @@ public interface StoragePoolDao extends GenericDao<StoragePoolVO, Long> {
long countBy(long podId, Status... statuses);
List<StoragePoolVO> findIfDuplicatePoolsExistByUUID(String uuid);
List<StoragePoolVO> listPoolsByStatus(Status status);
}

View File

@ -59,6 +59,7 @@ public class StoragePoolDaoImpl extends GenericDaoBase<StoragePoolVO, Long> imp
protected final SearchBuilder<StoragePoolVO> HostPathDcSearch;
protected final SearchBuilder<StoragePoolVO> DcPodAnyClusterSearch;
protected final SearchBuilder<StoragePoolVO> DeleteLvmSearch;
protected final SearchBuilder<StoragePoolVO> StatusSearch;
protected final GenericSearchBuilder<StoragePoolVO, Long> MaintenanceCountSearch;
@ -109,6 +110,10 @@ public class StoragePoolDaoImpl extends GenericDaoBase<StoragePoolVO, Long> imp
HostSearch.and("host", HostSearch.entity().getHostAddress(), SearchCriteria.Op.EQ);
HostSearch.done();
StatusSearch = createSearchBuilder();
StatusSearch.and("status",StatusSearch.entity().getStatus(),SearchCriteria.Op.EQ);
StatusSearch.done();
HostPathDcPodSearch = createSearchBuilder();
HostPathDcPodSearch.and("hostAddress", HostPathDcPodSearch.entity().getHostAddress(), SearchCriteria.Op.EQ);
HostPathDcPodSearch.and("path", HostPathDcPodSearch.entity().getPath(), SearchCriteria.Op.EQ);
@ -183,6 +188,13 @@ public class StoragePoolDaoImpl extends GenericDaoBase<StoragePoolVO, Long> imp
sc.setParameters("host", hostFqdnOrIp);
return listBy(sc);
}
@Override
public List<StoragePoolVO> listPoolsByStatus(Status status){
SearchCriteria<StoragePoolVO> sc = StatusSearch.create();
sc.setParameters("status", status);
return listBy(sc);
}
@Override
public StoragePoolVO findPoolByHostPath(long datacenterId, Long podId, String host, String path) {

View File

@ -185,8 +185,9 @@ public class CreateVolumeCmd extends BaseCmd {
if(s_logger.isDebugEnabled())
s_logger.debug("CreateVolume command has been accepted, job id: " + jobId);
}
long volumeId = waitInstanceCreation(jobId);
List<Pair<String, Object>> returnValues = new ArrayList<Pair<String, Object>>();
returnValues.add(new Pair<String, Object>(BaseCmd.Properties.JOB_ID.getName(), Long.valueOf(jobId)));
returnValues.add(new Pair<String, Object>(BaseCmd.Properties.VOLUME_ID.getName(), Long.valueOf(volumeId)));

View File

@ -73,7 +73,7 @@ public class PreparePrimaryStorageForMaintenanceCmd extends BaseCmd {
}
if(getManagementServer().getPsMaintenanceCount(storagePool.getPodId()) > 0){
throw new ServerApiException(BaseCmd.INTERNAL_ERROR,"There already exist other storage pools in maintenance");
throw new ServerApiException(BaseCmd.INTERNAL_ERROR,"There already exist other storage pools in maintenance process");
}
long jobId = 0;

View File

@ -78,7 +78,10 @@ public class StartVMCmd extends BaseCmd {
throw new ServerApiException(BaseCmd.PARAM_ERROR, "Invalid virtual machine id (" + vmId + ") given, unable to start virtual machine.");
}
}
if(!getManagementServer().isPoolUp(vmId)){
throw new ServerApiException(BaseCmd.INTERNAL_ERROR,"Storage pool for this vm is under maintenance");
}
if (userId == null) {
userId = Long.valueOf(1);
}

View File

@ -1762,11 +1762,22 @@ public class ManagementServerImpl implements ManagementServer {
// Check that there is a shared primary storage pool in the specified zone
List<StoragePoolVO> storagePools = _poolDao.listByDataCenterId(zoneId);
boolean sharedPoolExists = false;
boolean readyPoolExists = false;
for (StoragePoolVO storagePool : storagePools) {
if (storagePool.isShared()) {
sharedPoolExists = true;
}
//check if there are any pools in the UP state
//if not, throw an error
if(storagePool.getStatus().equals(Status.Up)){
readyPoolExists = true;
}
}
if(!readyPoolExists){
throw new InternalErrorException("There are no ready pools for volume creation");
}
// Check that there is at least one host in the specified zone
@ -8722,7 +8733,31 @@ public class ManagementServerImpl implements ManagementServer {
@Override
public long getPsMaintenanceCount(long podId){
return _poolDao.countBy(podId, Status.Maintenance);
List<StoragePoolVO> poolsInTransition = new ArrayList<StoragePoolVO>();
poolsInTransition.addAll(_poolDao.listPoolsByStatus(Status.Maintenance));
poolsInTransition.addAll(_poolDao.listPoolsByStatus(Status.PrepareForMaintenance));
poolsInTransition.addAll(_poolDao.listPoolsByStatus(Status.ErrorInMaintenance));
if(poolsInTransition==null)
return 0;
else
return poolsInTransition.size();
}
@Override
public boolean isPoolUp(long instanceId){
VolumeVO rootVolume = _volumeDao.findByInstance(instanceId).get(0);
if(rootVolume!=null){
Status poolStatus = _poolDao.findById(rootVolume.getPoolId()).getStatus();
if(!poolStatus.equals(Status.Up))
return false;
else
return true;
}
return false;
}
}

View File

@ -440,7 +440,9 @@ public class StorageManagerImpl implements StorageManager {
for (StoragePoolHostVO poolHost: poolHosts) {
try {
return _agentMgr.send(poolHost.getHostId(), cmds, stopOnError);
Answer[] answerRet = _agentMgr.send(poolHost.getHostId(), cmds, stopOnError);
return answerRet;
} catch (AgentUnavailableException e) {
s_logger.debug("Moving on because unable to send to " + poolHost.getHostId() + " due to " + e.getMessage());
} catch (OperationTimedoutException e) {
@ -1664,7 +1666,7 @@ public class StorageManagerImpl implements StorageManager {
_asyncMgr.updateAsyncJobAttachment(job.getId(), "volume", volume.getId());
_asyncMgr.updateAsyncJobStatus(job.getId(), BaseCmd.PROGRESS_INSTANCE_CREATED, volume.getId());
}
List<StoragePoolVO> poolsToAvoid = new ArrayList<StoragePoolVO>();
Set<Long> podsToAvoid = new HashSet<Long>();
Pair<HostPodVO, Long> pod = null;
@ -2007,9 +2009,9 @@ public class StorageManagerImpl implements StorageManager {
//check to see if other ps exist
//if they do, then we can migrate over the system vms to them
//if they dont, then just stop all vms on this one
count = _storagePoolDao.countBy(primaryStorage.getPodId(), Status.Up);
List<StoragePoolVO> upPools = _storagePoolDao.listPoolsByStatus(Status.Up);
if(count == 0)
if(upPools==null || upPools.size()==0)
restart = false;
//2. Get a list of all the volumes within this storage pool

View File

@ -2141,6 +2141,41 @@ a:visited {
background:url(../images/grid_actions_hover.png) no-repeat top left;
}
.gridheader_loaderbox {
width:auto;
height:20px;
float:right;
position:absolute;
background:#99b2c3 url(../images/gridheader_loadingbg.gif) repeat-x top left;
border-left:1px solid #999;
margin:0px 0 0 0;
padding:0;
z-index:1001;
right:0;
}
.gridheader_loaderbox p{
width:auto;
height:auto;
float:left;
color:#FFF;
font-size:11px;
font-weight:bold;
margin:2px 5px 0 5px;
display:inline;
padding:0;
}
.gridheader_loader {
width:16px;
height:16px;
float:left;
background:url(../images/grid_actionloader.gif) no-repeat top left;
margin:0 0 0 5px;
display:inline;
padding:0;
}
.grid_editbox {
width:27px;
height:17px;

Binary file not shown.

After

Width:  |  Height:  |  Size: 847 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 B

View File

Before

Width:  |  Height:  |  Size: 581 B

After

Width:  |  Height:  |  Size: 581 B

View File

Before

Width:  |  Height:  |  Size: 580 B

After

Width:  |  Height:  |  Size: 580 B

View File

Before

Width:  |  Height:  |  Size: 352 B

After

Width:  |  Height:  |  Size: 352 B

View File

Before

Width:  |  Height:  |  Size: 450 B

After

Width:  |  Height:  |  Size: 450 B

View File

Before

Width:  |  Height:  |  Size: 473 B

After

Width:  |  Height:  |  Size: 473 B

View File

Before

Width:  |  Height:  |  Size: 400 B

After

Width:  |  Height:  |  Size: 400 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 542 B

View File

@ -145,17 +145,21 @@
<!--Volume tab (start)-->
<div style="display:none;" id="tab_content_volume">
<!--
<div class="grid_container" id="volume_tab_template" style="display:block">
<div class="grid_header">
<div class="grid_header_title" id="name"></div>
<div class="grid_actionbox" id="volume_action_link">
<div class="grid_actionbox" id="volume_action_link" style="display:block;">
<div class="grid_actionsdropdown_box" id="volume_action_menu" style="display: none;">
<ul class="actionsdropdown_boxlist" id="action_list">
<li> <a href="#"> Delete </a> </li>
<li> <a href="#"> Attach Disk </a> </li>
</ul>
</div>
</div>
<div class="gridheader_loaderbox">
<div class="gridheader_loader"></div>
<p> Creating Template &hellip; </p>
</div>
</div>
<div class="grid_rows even">
@ -194,8 +198,9 @@
<div class="row_celltitles" id="created"></div>
</div>
</div>
</div>
-->
</div>
</div>
<!--Volume tab (end)-->
@ -773,7 +778,9 @@
<ul class="actionsdropdown_boxlist" id="action_list">
</ul>
</div>
</div>
</div>
</div>
<div class="grid_rows even">
<div class="grid_row_cell" style="width: 20%;">

View File

@ -19,36 +19,28 @@ $(document).ready(function() {
$("#midmenu_container").selectable({
selecting: function(event, ui) {
if(ui.selecting.id.indexOf("midmenuItem") != -1) {
var $t = $("#"+ui.selecting.id);
if($t.find("#content").hasClass("inaction") == false) { //only items not in action are allowed to be selected
var id =$t.data("id");
selectedItemIds[id] = $t;
$t.find("#content").addClass("selected");
var $midmenuItem1 = $("#"+ui.selecting.id);
if($midmenuItem1.find("#content").hasClass("inaction") == false) { //only items not in action are allowed to be selected
var id =$midmenuItem1.data("id");
selectedItemsInMidMenu[id] = $midmenuItem1;
$midmenuItem1.find("#content").addClass("selected");
}
var toRightPanelFn = $t.data("toRightPanelFn");
toRightPanelFn($t);
var toRightPanelFn = $midmenuItem1.data("toRightPanelFn");
toRightPanelFn($midmenuItem1);
}
},
unselecting: function(event, ui) {
if(ui.unselecting.id.indexOf("midmenuItem") != -1) {
var $t = $("#"+ui.unselecting.id);
var id = $t.data("id");
if(id in selectedItemIds) {
delete selectedItemIds[id];
$t.find("#content").removeClass("selected");
var $midmenuItem1 = $("#"+ui.unselecting.id);
var id = $midmenuItem1.data("id");
if(id in selectedItemsInMidMenu) {
delete selectedItemsInMidMenu[id];
$midmenuItem1.find("#content").removeClass("selected");
}
}
}
});
var $rightPanel = $("#right_panel");
var $addLink = $("#add_link");
//var $actionLink = $("#action_link");
//var $actionMenu = $("#action_menu");
//var $actionList = $("#action_menu #action_list");
var $midmenuContainer = $("#midmenu_container");
//var $actionListItem = $("#action_list_item");
$("#leftmenu_instance_group_header").bind("click", function(event) {
var $arrowIcon = $(this).find("#arrow_icon");
clickInstanceGroupHeader($arrowIcon);
@ -75,14 +67,16 @@ $(document).ready(function() {
data: createURL("command="+apiName+"&response=json"),
dataType: "json",
success: function(json) {
$midmenuContainer.empty();
$("#midmenu_container").empty();
selectedItemsInMidMenu = {};
var items = json[jsonResponse1][jsonResponse2];
if(items != null && items.length > 0) {
for(var i=0; i<items.length;i++) {
var item = items[i];
var $midmenuItem1 = $midmenuItem.clone();
jsonToMidmenu(item, $midmenuItem1, propertyForFirstRow, propertyForSecondRow, toRightPanelFn);
$midmenuContainer.append($midmenuItem1.show());
$("#midmenu_container").append($midmenuItem1.show());
}
}
}
@ -100,11 +94,11 @@ $(document).ready(function() {
$("#action_link").bind("mouseover", function(event) {
$("#action_menu").show();
$(this).find("#action_menu").show();
return false;
});
$("#action_link").bind("mouseout", function(event) {
$("#action_menu").hide();
$(this).find("#action_menu").hide();
return false;
});

View File

@ -2,16 +2,8 @@ function clickInstanceGroupHeader($arrowIcon) {
//***** VM Detail (begin) ******************************************************************************
var $vmPopup
var $rightPanelHeader;
var $rightPanelContent;
var $instanceGroupContainer = $("#leftmenu_instance_group_container");
var $instanceGroupTemplate = $("#leftmenu_instance_group_template");
//var $actionLink = $("#action_link");
//var $actionMenu = $("#action_menu");
//var $actionList = $("#action_menu #action_list");
var $midmenuContainer = $("#midmenu_container");
//var $actionListItem = $("#action_list_item");
var $rightPanelContent;
var $midmenuItem = $("#midmenu_item");
var noGroupName = "(no group name)";
@ -98,7 +90,7 @@ function clickInstanceGroupHeader($arrowIcon) {
}
}
function doAttachISO($t, selectedItemIds, vmListAPIMap) {
function doAttachISO($t, selectedItemsInMidMenu, vmListAPIMap) {
$.ajax({
data: createURL("command=listIsos&isReady=true"),
dataType: "json",
@ -125,9 +117,9 @@ function clickInstanceGroupHeader($arrowIcon) {
$("#dialog_alert").dialog("open");
return false;
}
for(var id in selectedItemIds) {
for(var id in selectedItemsInMidMenu) {
var apiCommand = "command=attachIso&virtualmachineid="+id+"&id="+isoId;
doAction(id, $t, apiCommand, vmListAPIMap);
doActionForMidMenu(id, $t, apiCommand, vmListAPIMap);
}
},
"Cancel": function() {
@ -136,15 +128,15 @@ function clickInstanceGroupHeader($arrowIcon) {
}).dialog("open");
}
function doDetachISO($t, selectedItemIds, vmListAPIMap) {
function doDetachISO($t, selectedItemsInMidMenu, vmListAPIMap) {
$("#dialog_confirmation")
.html("<p>Please confirm you want to detach an ISO from the virtual machine(s)</p>")
.dialog('option', 'buttons', {
"Confirm": function() {
$(this).dialog("close");
for(var id in selectedItemIds) {
for(var id in selectedItemsInMidMenu) {
var apiCommand = "command=detachIso&virtualmachineid="+id;
doAction(id, $t, apiCommand, vmListAPIMap);
doActionForMidMenu(id, $t, apiCommand, vmListAPIMap);
}
},
"Cancel": function() {
@ -153,14 +145,14 @@ function clickInstanceGroupHeader($arrowIcon) {
}).dialog("open");
}
function doResetPassword($t, selectedItemIds, vmListAPIMap) {
function doResetPassword($t, selectedItemsInMidMenu, vmListAPIMap) {
$("#dialog_confirmation")
.html("<p>Please confirm you want to change the ROOT password for your virtual machine(s)</p>")
.dialog('option', 'buttons', {
"Confirm": function() {
$(this).dialog("close");
for(var id in selectedItemIds) {
var $midMenuItem = selectedItemIds[id];
for(var id in selectedItemsInMidMenu) {
var $midMenuItem = selectedItemsInMidMenu[id];
var jsonObj = $midMenuItem.data("jsonObj");
if(jsonObj.state != "Stopped") {
$midMenuItem.find("#info_icon").addClass("error").show();
@ -173,7 +165,7 @@ function clickInstanceGroupHeader($arrowIcon) {
continue;
}
var apiCommand = "command=resetPasswordForVirtualMachine&id="+id;
doAction(id, $t, apiCommand, vmListAPIMap);
doActionForMidMenu(id, $t, apiCommand, vmListAPIMap);
}
},
"Cancel": function() {
@ -182,7 +174,7 @@ function clickInstanceGroupHeader($arrowIcon) {
}).dialog("open");
}
function doChangeName($t, selectedItemIds, vmListAPIMap) {
function doChangeName($t, selectedItemsInMidMenu, vmListAPIMap) {
$("#dialog_change_name")
.dialog('option', 'buttons', {
"Confirm": function() {
@ -196,9 +188,9 @@ function clickInstanceGroupHeader($arrowIcon) {
var name = trim(thisDialog.find("#change_instance_name").val());
for(var id in selectedItemIds) {
for(var id in selectedItemsInMidMenu) {
var apiCommand = "command=updateVirtualMachine&id="+id+"&displayName="+todb(name);
doAction(id, $t, apiCommand, vmListAPIMap);
doActionForMidMenu(id, $t, apiCommand, vmListAPIMap);
}
},
"Cancel": function() {
@ -207,7 +199,7 @@ function clickInstanceGroupHeader($arrowIcon) {
}).dialog("open");
}
function doChangeService($t, selectedItemIds, vmListAPIMap) {
function doChangeService($t, selectedItemsInMidMenu, vmListAPIMap) {
$.ajax({
//data: createURL("command=listServiceOfferings&VirtualMachineId="+vmId), //can not specifiy VirtualMachineId since we allow multiple-item-selection.
data: createURL("command=listServiceOfferings"), //can not specifiy VirtualMachineId since we support multiple-item-selection.
@ -231,8 +223,8 @@ function clickInstanceGroupHeader($arrowIcon) {
var thisDialog = $(this);
thisDialog.dialog("close");
for(var id in selectedItemIds) {
var $midMenuItem = selectedItemIds[id];
for(var id in selectedItemsInMidMenu) {
var $midMenuItem = selectedItemsInMidMenu[id];
var jsonObj = $midMenuItem.data("jsonObj");
if(jsonObj.state != "Stopped") {
$midMenuItem.find("#info_icon").addClass("error").show();
@ -240,7 +232,7 @@ function clickInstanceGroupHeader($arrowIcon) {
continue;
}
var apiCommand = "command=changeServiceForVirtualMachine&id="+id+"&serviceOfferingId="+thisDialog.find("#change_service_offerings").val();
doAction(id, $t, apiCommand, vmListAPIMap);
doActionForMidMenu(id, $t, apiCommand, vmListAPIMap);
}
},
"Cancel": function() {
@ -249,7 +241,7 @@ function clickInstanceGroupHeader($arrowIcon) {
}).dialog("open");
}
function doChangeGroup($t, selectedItemIds, vmListAPIMap) {
function doChangeGroup($t, selectedItemsInMidMenu, vmListAPIMap) {
$("#dialog_change_group")
.dialog('option', 'buttons', {
"Confirm": function() {
@ -261,12 +253,12 @@ function clickInstanceGroupHeader($arrowIcon) {
isValid &= validateString("Group", thisDialog.find("#change_group_name"), thisDialog.find("#change_group_name_errormsg"), true); //group name is optional
if (!isValid) return;
for(var id in selectedItemIds) {
var $midMenuItem = selectedItemIds[id];
for(var id in selectedItemsInMidMenu) {
var $midMenuItem = selectedItemsInMidMenu[id];
var jsonObj = $midMenuItem.data("jsonObj");
var group = trim(thisDialog.find("#change_group_name").val());
var apiCommand = "command=updateVirtualMachine&id="+id+"&group="+todb(group);
doAction(id, $t, apiCommand, vmListAPIMap);
doActionForMidMenu(id, $t, apiCommand, vmListAPIMap);
}
},
"Cancel": function() {
@ -275,7 +267,7 @@ function clickInstanceGroupHeader($arrowIcon) {
}).dialog("open");
}
function doEnableHA($t, selectedItemIds, vmListAPIMap) {
function doEnableHA($t, selectedItemsInMidMenu, vmListAPIMap) {
var message = "<p>Please confirm you want to enable HA for your virtual machine. Once HA is enabled, your Virtual Instance will be automatically restarted in the event it is detected to have failed.</p>";
$("#dialog_confirmation")
@ -283,11 +275,11 @@ function clickInstanceGroupHeader($arrowIcon) {
.dialog('option', 'buttons', {
"Confirm": function() {
$(this).dialog("close");
for(var id in selectedItemIds) {
var $midMenuItem = selectedItemIds[id];
for(var id in selectedItemsInMidMenu) {
var $midMenuItem = selectedItemsInMidMenu[id];
var jsonObj = $midMenuItem.data("jsonObj");
var apiCommand = "command=updateVirtualMachine&id="+id+"&haenable=true";
doAction(id, $t, apiCommand, vmListAPIMap);
doActionForMidMenu(id, $t, apiCommand, vmListAPIMap);
}
},
"Cancel": function() {
@ -296,7 +288,7 @@ function clickInstanceGroupHeader($arrowIcon) {
}).dialog("open");
}
function doDisableHA($t, selectedItemIds, vmListAPIMap) {
function doDisableHA($t, selectedItemsInMidMenu, vmListAPIMap) {
var message = "<p>Please confirm you want to disable HA for your virtual machine. Once HA is disabled, your Virtual Instance will no longer be be automatically restarted in the event of a failure.</p>";
$("#dialog_confirmation")
@ -304,11 +296,11 @@ function clickInstanceGroupHeader($arrowIcon) {
.dialog('option', 'buttons', {
"Confirm": function() {
$(this).dialog("close");
for(var id in selectedItemIds) {
var $midMenuItem = selectedItemIds[id];
for(var id in selectedItemsInMidMenu) {
var $midMenuItem = selectedItemsInMidMenu[id];
var jsonObj = $midMenuItem.data("jsonObj");
var apiCommand = "command=updateVirtualMachine&id="+id+"&haenable=false";
doAction(id, $t, apiCommand, vmListAPIMap);
doActionForMidMenu(id, $t, apiCommand, vmListAPIMap);
}
},
"Cancel": function() {
@ -445,11 +437,11 @@ function clickInstanceGroupHeader($arrowIcon) {
setDateField(json.created, template.find("#created"));
if(json.type=="ROOT") { //"create template" is allowed(when stopped), "detach disk" is disallowed.
//if (json.vmstate == "Stopped")
buildActionLink("Create Template", volumeActionMap, $("#volume_action_menu"), volumeListAPIMap);
if (json.vmstate == "Stopped")
buildActionLink("Create Template", volumeActionMap, template.find("#volume_action_menu"), volumeListAPIMap);
}
else { //json.type=="DATADISK": "detach disk" is allowed, "create template" is disallowed.
buildActionLink("Detach Disk", volumeActionMap, $("#volume_action_menu"), volumeListAPIMap);
buildActionLink("Detach Disk", volumeActionMap, template.find("#volume_action_menu"), volumeListAPIMap);
}
}
@ -480,12 +472,14 @@ function clickInstanceGroupHeader($arrowIcon) {
}
for(var i=0; i < instanceGroupArray.length; i++) {
if(instanceGroupArray[i]!=null && instanceGroupArray[i].length>0) {
var $groupTemplate = $instanceGroupTemplate.clone().show();
var $groupTemplate = $("#leftmenu_instance_group_template").clone().show();
$groupTemplate.find("#group_name").text(instanceGroupArray[i]);
$groupTemplate.bind("click", function(event) {
//$(this).removeClass("leftmenu_content").addClass("leftmenu_content_selected");
$("#midmenu_container").empty();
selectedItemsInMidMenu = {};
var groupName = $(this).find("#group_name").text();
$.ajax({
@ -511,7 +505,7 @@ function clickInstanceGroupHeader($arrowIcon) {
return false;
});
$instanceGroupContainer.append($groupTemplate);
$("#leftmenu_instance_group_container").append($groupTemplate);
}
}
@ -525,7 +519,7 @@ function clickInstanceGroupHeader($arrowIcon) {
}
else if($arrowIcon.hasClass("open") == true) {
$arrowIcon.removeClass("open").addClass("close");
$instanceGroupContainer.empty();
$("#leftmenu_instance_group_container").empty();
}
//***** VM Detail (end) ********************************************************************************
$("#right_panel").load("jsp/instance.jsp", function() {
@ -1203,11 +1197,11 @@ function clickInstanceGroupHeader($arrowIcon) {
//***** Volume tab (begin) *****************************************************************************
$("#volume_action_link").bind("mouseover", function(event) {
$("#volume_action_menu").show();
$(this).find("#volume_action_menu").show();
return false;
});
$("#volume_action_link").bind("mouseout", function(event) {
$("#volume_action_menu").hide();
$(this).find("#volume_action_menu").hide();
return false;
});
//***** Volume tab (end) *******************************************************************************

View File

@ -20,7 +20,7 @@
// Version: @VERSION@
var selectedItemIds = {};
var selectedItemsInMidMenu = {};
function buildActionLink(label, actionMap, $actionMenu, listAPIMap) {
var apiInfo = actionMap[label];
@ -38,21 +38,21 @@ function buildActionLink(label, actionMap, $actionMenu, listAPIMap) {
var $actionLink = $(this);
var dialogBeforeActionFn = $actionLink.data("dialogBeforeActionFn");
if(dialogBeforeActionFn == null) {
for(var id in selectedItemIds) {
for(var id in selectedItemsInMidMenu) {
var apiCommand = "command="+$actionLink.data("api")+"&id="+id;
doAction(id, $actionLink, apiCommand, listAPIMap);
doActionForMidMenu(id, $actionLink, apiCommand, listAPIMap);
}
}
else {
dialogBeforeActionFn($actionLink, selectedItemIds, listAPIMap);
dialogBeforeActionFn($actionLink, selectedItemsInMidMenu, listAPIMap);
}
selectedItemIds = {}; //clear selected items for action
selectedItemsInMidMenu = {}; //clear selected items for action
return false;
});
}
function doAction(id, $actionLink, apiCommand, listAPIMap) {
function doActionForMidMenu(id, $actionLink, apiCommand, listAPIMap) {
var label = $actionLink.data("label");
var isAsyncJob = $actionLink.data("isAsyncJob");
var asyncJobResponse = $actionLink.data("asyncJobResponse");
@ -113,45 +113,16 @@ function doAction(id, $actionLink, apiCommand, listAPIMap) {
}
},
error: function(XMLHttpResponse) {
$("body").stopTime(timerKey);
$midmenuItem.find("#content").removeClass("inaction");
$midmenuItem.find("#spinning_wheel").hide();
$midmenuItem.find("#info_icon").addClass("error").show();
var errorMsg = "";
if(XMLHttpResponse.responseText != null & XMLHttpResponse.responseText.length > 0) {
var start = XMLHttpResponse.responseText.indexOf("h1") + 3;
var end = XMLHttpResponse.responseText.indexOf("</h1");
errorMsg = XMLHttpResponse.responseText.substring(start, end);
}
if(errorMsg.length > 0)
$midmenuItem.data("afterActionInfo", ((label + " action failed. Reason: " + sanitizeXSS(unescape(errorMsg)))));
else
$midmenuItem.data("afterActionInfo", (label + " action failed."));
//handleError(XMLHttpResponse);
$("body").stopTime(timerKey);
handleErrorInMidMenu(XMLHttpResponse, $midmenuItem);
}
});
},
0
);
},
error: function(XMLHttpResponse) {
$midmenuItem.find("#content").removeClass("inaction");
$midmenuItem.find("#spinning_wheel").hide();
$midmenuItem.find("#info_icon").addClass("error").show();
$midmenuItem.data("afterActionInfo", (label + " action failed."));
var errorMsg = "";
if(XMLHttpResponse.responseText != null & XMLHttpResponse.responseText.length > 0) {
var start = XMLHttpResponse.responseText.indexOf("h1") + 3;
var end = XMLHttpResponse.responseText.indexOf("</h1");
errorMsg = XMLHttpResponse.responseText.substring(start, end);
}
if(errorMsg.length > 0)
$midmenuItem.data("afterActionInfo", ((label + " action failed. Reason: " + sanitizeXSS(unescape(errorMsg)))));
else
$midmenuItem.data("afterActionInfo", (label + " action failed."));
//handleError(XMLHttpResponse);
error: function(XMLHttpResponse) {
handleErrorInMidMenu(XMLHttpResponse, $midmenuItem);
}
});
}
@ -178,20 +149,37 @@ function doAction(id, $actionLink, apiCommand, listAPIMap) {
$midmenuItem.find("#info_icon").removeClass("error").show();
$midmenuItem.data("afterActionInfo", (label + " action succeeded."));
afterActionSeccessFn(json[listAPIResponse][listAPIResponseObj][0], $midmenuItem);
},
error: function(XMLHttpResponse) {
$midmenuItem.find("#info_icon").addClass("error").show();
$midmenuItem.data("afterActionInfo", (label + " action failed. Reason: " + sanitizeXSS(result.jobresult)));
}
});
//After Bug 6037 is fixed, remove temporary solution above and uncomment the line below
//afterActionSeccessFn(json[listAPIResponse][listAPIResponseObj][0], $midmenuItem);
}
},
error: function(XMLHttpResponse) {
handleErrorInMidMenu(XMLHttpResponse, $midmenuItem);
}
});
}
//Sync job (end) *****
}
function handleErrorInMidMenu(XMLHttpResponse, $midmenuItem) {
$midmenuItem.find("#content").removeClass("inaction");
$midmenuItem.find("#spinning_wheel").hide();
$midmenuItem.find("#info_icon").addClass("error").show();
var errorMsg = "";
if(XMLHttpResponse.responseText != null & XMLHttpResponse.responseText.length > 0) {
var start = XMLHttpResponse.responseText.indexOf("h1") + 3;
var end = XMLHttpResponse.responseText.indexOf("</h1");
errorMsg = XMLHttpResponse.responseText.substring(start, end);
}
if(errorMsg.length > 0)
$midmenuItem.data("afterActionInfo", ((label + " action failed. Reason: " + sanitizeXSS(unescape(errorMsg)))));
else
$midmenuItem.data("afterActionInfo", (label + " action failed."));
}
function createURL(url) {
return url +"&response=json&sessionkey=" + g_sessionKey;
}

View File

@ -67,8 +67,8 @@ function doCreateTemplate($t, selectedItemIds, listAPIMap) {
var password = thisDialog.find("#create_template_password").val();
for(var id in selectedItemIds) {
var apiCommand = "command=createTemplate&volumeId="+id+"&name="+encodeURIComponent(name)+"&displayText="+encodeURIComponent(desc)+"&osTypeId="+osType+"&isPublic="+isPublic+"&passwordEnabled="+password;
doAction(id, $t, apiCommand, listAPIMap);
var apiCommand = "command=createTemplate&volumeId="+id+"&name="+encodeURIComponent(name)+"&displayText="+encodeURIComponent(desc)+"&osTypeId="+osType+"&isPublic="+isPublic+"&passwordEnabled="+password;
doAction(id, $t, apiCommand, listAPIMap);
}
},
"Cancel": function() {

View File

@ -274,8 +274,10 @@ function showStorageTab(domainId, targetTab) {
setDateField(json.created, template.find("#volume_created"));
if(json.type=="ROOT") {
} else {
// DataDisk
if (json.vmstate == "Stopped")
template.find("#volume_action_create_template_span").show();
}
else { //json.type=="DATADISK": "detach disk" is allowed, "create template" is disallowed.
if (json.virtualmachineid != undefined) {
if (json.storagetype == "shared" && (json.vmstate == "Running" || json.vmstate == "Stopped")) {
template.find("#volume_action_detach_span").show();