Merge branch 'master' of ssh://anthony@git.cloud.com/var/lib/git/cloudstack-oss
@ -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);
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
}
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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)));
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
BIN
ui/new/images/grid_actionloader.gif
Normal file
|
After Width: | Height: | Size: 847 B |
BIN
ui/new/images/gridheader_loadingbg.gif
Normal file
|
After Width: | Height: | Size: 130 B |
|
Before Width: | Height: | Size: 581 B After Width: | Height: | Size: 581 B |
|
Before Width: | Height: | Size: 580 B After Width: | Height: | Size: 580 B |
|
Before Width: | Height: | Size: 352 B After Width: | Height: | Size: 352 B |
|
Before Width: | Height: | Size: 450 B After Width: | Height: | Size: 450 B |
|
Before Width: | Height: | Size: 473 B After Width: | Height: | Size: 473 B |
|
Before Width: | Height: | Size: 400 B After Width: | Height: | Size: 400 B |
BIN
ui/new/images/midmenuicon_network_networkgroup.png
Normal file
|
After Width: | Height: | Size: 542 B |
@ -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 … </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%;">
|
||||
|
||||
@ -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;
|
||||
});
|
||||
|
||||
|
||||
@ -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) *******************************************************************************
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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();
|
||||
|
||||