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

This commit is contained in:
edison 2010-09-07 14:45:05 -07:00
commit 55332a65a6
29 changed files with 294 additions and 184 deletions

View File

@ -210,4 +210,6 @@ public interface AgentManager extends Manager {
public boolean reconnect(final long hostId) throws AgentUnavailableException;
public List<HostVO> discoverHosts(long dcId, Long podId, Long clusterId, URI url, String username, String password) throws DiscoveryException;
Answer easySend(Long hostId, Command cmd, int timeout);
}

View File

@ -3480,8 +3480,12 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR
return false;
return true;
}
protected String callHostPlugin(String plugin, String cmd, String... params) {
//default time out is 300 s
return callHostPluginWithTimeOut(plugin, cmd, 300, params);
}
protected String callHostPluginWithTimeOut(String plugin, String cmd, int timeout, String... params) {
Map<String, String> args = new HashMap<String, String>();
Session slaveSession = null;
Connection slaveConn = null;
@ -3493,7 +3497,7 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR
// TODO Auto-generated catch block
e.printStackTrace();
}
slaveConn = new Connection(slaveUrl, 1800);
slaveConn = new Connection(slaveUrl, timeout);
slaveSession = Session.slaveLocalLoginWithPassword(slaveConn, _username, _password);
if (s_logger.isDebugEnabled()) {
@ -6205,7 +6209,7 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR
checksum = "";
}
String result = callHostPlugin("vmopsSnapshot", "post_create_private_template", "remoteTemplateMountPath", remoteTemplateMountPath, "templateDownloadFolder", templateDownloadFolder,
String result = callHostPluginWithTimeOut("vmopsSnapshot", "post_create_private_template", 110*60, "remoteTemplateMountPath", remoteTemplateMountPath, "templateDownloadFolder", templateDownloadFolder,
"templateInstallFolder", templateInstallFolder, "templateFilename", templateFilename, "templateName", templateName, "templateDescription", templateDescription,
"checksum", checksum, "virtualSize", String.valueOf(virtualSize), "templateId", String.valueOf(templateId));
@ -6243,7 +6247,7 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR
// Each argument is put in a separate line for readability.
// Using more lines does not harm the environment.
String results = callHostPlugin("vmopsSnapshot", "backupSnapshot", "primaryStorageSRUuid", primaryStorageSRUuid, "dcId", dcId.toString(), "accountId", accountId.toString(), "volumeId",
String results = callHostPluginWithTimeOut("vmopsSnapshot", "backupSnapshot", 110*60, "primaryStorageSRUuid", primaryStorageSRUuid, "dcId", dcId.toString(), "accountId", accountId.toString(), "volumeId",
volumeId.toString(), "secondaryStorageMountPath", secondaryStorageMountPath, "snapshotUuid", snapshotUuid, "prevSnapshotUuid", prevSnapshotUuid, "prevBackupUuid",
prevBackupUuid, "isFirstSnapshotOfRootVolume", isFirstSnapshotOfRootVolume.toString(), "isISCSI", isISCSI.toString());
@ -6346,7 +6350,7 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR
String failureString = "Could not create volume from " + backedUpSnapshotUuid;
templatePath = (templatePath == null) ? "" : templatePath;
String results = callHostPlugin("vmopsSnapshot", "createVolumeFromSnapshot", "dcId", dcId.toString(), "accountId", accountId.toString(), "volumeId", volumeId.toString(),
String results = callHostPluginWithTimeOut("vmopsSnapshot","createVolumeFromSnapshot", 110*60, "dcId", dcId.toString(), "accountId", accountId.toString(), "volumeId", volumeId.toString(),
"secondaryStorageMountPath", secondaryStorageMountPath, "backedUpSnapshotUuid", backedUpSnapshotUuid, "templatePath", templatePath, "templateDownloadFolder",
templateDownloadFolder, "isISCSI", isISCSI.toString());

View File

@ -1132,11 +1132,16 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory {
}
}
}
@Override
public Answer easySend(final Long hostId, final Command cmd) {
return easySend(hostId, cmd, _wait);
}
@Override
public Answer easySend(final Long hostId, final Command cmd) {
public Answer easySend(final Long hostId, final Command cmd, int timeout) {
try {
final Answer answer = send(hostId, cmd, _wait);
final Answer answer = send(hostId, cmd, timeout);
if (answer == null) {
s_logger.warn("send returns null answer");
return null;

View File

@ -37,7 +37,6 @@ import com.cloud.dc.DataCenterVO;
import com.cloud.dc.HostPodVO;
import com.cloud.dc.dao.HostPodDao;
import com.cloud.offering.NetworkOffering;
import com.cloud.offering.NetworkOffering.GuestIpType;
import com.cloud.offering.ServiceOffering;
import com.cloud.service.ServiceOfferingVO;
import com.cloud.service.dao.ServiceOfferingDao;
@ -50,7 +49,6 @@ import com.cloud.utils.DateUtil;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.Pair;
import com.cloud.utils.component.Inject;
import com.cloud.utils.db.GlobalLock;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.vm.State;
import com.cloud.vm.UserVmVO;
@ -76,7 +74,6 @@ public class UserConcentratedAllocator implements PodAllocator {
@Inject VMInstanceDao _vmInstanceDao;
Random _rand = new Random(System.currentTimeMillis());
private final GlobalLock m_capacityCheckLock = GlobalLock.getInternLock("capacity.check");
private int _hoursToSkipStoppedVMs = 24;
private int _secStorageVmRamSize = 1024;
@ -156,30 +153,14 @@ public class UserConcentratedAllocator implements PodAllocator {
private boolean dataCenterAndPodHasEnoughCapacity(long dataCenterId, long podId, long capacityNeeded, short capacityType, long[] hostCandidate) {
List<CapacityVO> capacities = null;
if (m_capacityCheckLock.lock(120)) { // 2 minutes
try {
SearchCriteria<CapacityVO> sc = _capacityDao.createSearchCriteria();
sc.addAnd("capacityType", SearchCriteria.Op.EQ, capacityType);
sc.addAnd("dataCenterId", SearchCriteria.Op.EQ, dataCenterId);
sc.addAnd("podId", SearchCriteria.Op.EQ, podId);
capacities = _capacityDao.search(sc, null);
} finally {
m_capacityCheckLock.unlock();
}
} else {
s_logger.error("Unable to acquire synchronization lock for pod allocation");
// we now try to enforce reservation-style allocation, waiting time has been adjusted
// to 2 minutes
return false;
/*
// If we can't lock the table, just return that there is enough capacity and allow instance creation to fail on the agent
// if there is not enough capacity. All that does is skip the optimization of checking for capacity before sending the
// command to the agent.
return true;
*/
}
SearchCriteria<CapacityVO> sc = _capacityDao.createSearchCriteria();
sc.addAnd("capacityType", SearchCriteria.Op.EQ, capacityType);
sc.addAnd("dataCenterId", SearchCriteria.Op.EQ, dataCenterId);
sc.addAnd("podId", SearchCriteria.Op.EQ, podId);
s_logger.trace("Executing search");
capacities = _capacityDao.search(sc, null);
s_logger.trace("Done with a search");
boolean enoughCapacity = false;
if (capacities != null) {

View File

@ -65,8 +65,9 @@ import com.cloud.storage.dao.VolumeDao;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.Pair;
import com.cloud.utils.component.ComponentLocator;
import com.cloud.utils.db.GlobalLock;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.Transaction;
import com.cloud.vm.ConsoleProxyVO;
import com.cloud.vm.DomainRouterVO;
import com.cloud.vm.SecondaryStorageVmVO;
@ -118,8 +119,6 @@ public class AlertManagerImpl implements AlertManager {
private double _publicIPCapacityThreshold = 0.75;
private double _privateIPCapacityThreshold = 0.75;
private final GlobalLock m_capacityCheckLock = GlobalLock.getInternLock("capacity.check");
@Override
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
_name = name;
@ -319,7 +318,7 @@ public class AlertManagerImpl implements AlertManager {
}
}
@Override
@Override @DB
public void recalculateCapacity() {
// FIXME: the right way to do this is to register a listener (see RouterStatsListener, VMSyncListener)
// for the vm sync state. The listener model has connects/disconnects to keep things in sync much better
@ -435,25 +434,23 @@ public class AlertManagerImpl implements AlertManager {
newCapacities.add(newPrivateIPCapacity);
}
if (m_capacityCheckLock.lock(5)) { // 5 second timeout
try {
// delete the old records
_capacityDao.clearNonStorageCapacities();
Transaction txn = Transaction.currentTxn();
try {
txn.start();
// delete the old records
_capacityDao.clearNonStorageCapacities();
for (CapacityVO newCapacity : newCapacities) {
_capacityDao.persist(newCapacity);
}
} finally {
m_capacityCheckLock.unlock();
}
if (s_logger.isTraceEnabled()) {
s_logger.trace("done recalculating system capacity");
}
} else {
if (s_logger.isTraceEnabled()) {
s_logger.trace("Skipping capacity check, unable to lock the capacity table for recalculation.");
}
for (CapacityVO newCapacity : newCapacities) {
s_logger.trace("Executing capacity update");
_capacityDao.persist(newCapacity);
s_logger.trace("Done with capacity update");
}
txn.commit();
} catch (Exception ex) {
txn.rollback();
s_logger.error("Unable to start transaction for capacity update");
}finally {
txn.close();
}
}

View File

@ -182,6 +182,14 @@ public class ListVMsCmd extends BaseCmd {
}
for (UserVm vmInstance : virtualMachines) {
//if the account is deleted, do not return the user vm
Account currentVmAccount = getManagementServer().getAccount(vmInstance.getAccountId());
if(currentVmAccount.getRemoved()!=null)
{
continue; //not returning this vm
}
List<Pair<String, Object>> vmData = new ArrayList<Pair<String, Object>>();
AsyncJobVO asyncJob = getManagementServer().findInstancePendingAsyncJob("vm_instance", vmInstance.getId());
if(asyncJob != null) {

View File

@ -61,6 +61,7 @@ import com.cloud.utils.component.ComponentLocator;
import com.cloud.utils.concurrency.NamedThreadFactory;
import com.cloud.utils.db.GlobalLock;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.Transaction;
import com.cloud.vm.UserVmManager;
import com.cloud.vm.UserVmVO;
import com.cloud.vm.VmStats;
@ -99,7 +100,7 @@ public class StatsCollector {
long storageStatsInterval = -1L;
long volumeStatsInterval = -1L;
private final GlobalLock m_capacityCheckLock = GlobalLock.getInternLock("capacity.check");
//private final GlobalLock m_capacityCheckLock = GlobalLock.getInternLock("capacity.check");
public static StatsCollector getInstance() {
return s_instance;
@ -335,32 +336,25 @@ public class StatsCollector {
// _capacityDao.persist(capacity);
}
if (m_capacityCheckLock.lock(5)) { // 5 second timeout
if (s_logger.isTraceEnabled()) {
s_logger.trace("recalculating system storage capacity");
}
try {
// now update the capacity table with the new stats
// FIXME: the right way to do this is to register a listener (see RouterStatsListener)
// for the host stats, send the Watch<something>Command at a regular interval
// to collect the stats from an agent and update the database as needed. The
// listener model has connects/disconnects to keep things in sync much better
// than this model right now
_capacityDao.clearStorageCapacities();
Transaction txn = Transaction.open(Transaction.CLOUD_DB);
try {
if (s_logger.isTraceEnabled()) {
s_logger.trace("recalculating system storage capacity");
}
txn.start();
_capacityDao.clearStorageCapacities();
for (CapacityVO newCapacity : newCapacities) {
_capacityDao.persist(newCapacity);
}
} finally {
m_capacityCheckLock.unlock();
}
if (s_logger.isTraceEnabled()) {
s_logger.trace("done recalculating system storage capacity");
}
} else {
if (s_logger.isTraceEnabled()) {
s_logger.trace("not recalculating system storage capacity, unable to lock capacity table");
}
for (CapacityVO newCapacity : newCapacities) {
s_logger.trace("Executing capacity update");
_capacityDao.persist(newCapacity);
s_logger.trace("Done with capacity update");
}
txn.commit();
} catch (Exception ex) {
txn.rollback();
s_logger.error("Unable to start transaction for storage capacity update");
}finally {
txn.close();
}
} catch (Throwable t) {
s_logger.error("Error trying to retrieve storage stats", t);

View File

@ -19,11 +19,7 @@ package com.cloud.storage;
import java.net.URI;
import java.net.UnknownHostException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.Enumeration;
@ -33,7 +29,6 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TimeZone;
import java.util.UUID;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
@ -94,9 +89,9 @@ import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceInUseException;
import com.cloud.exception.StorageUnavailableException;
import com.cloud.host.Host;
import com.cloud.host.Host.Type;
import com.cloud.host.HostVO;
import com.cloud.host.Status;
import com.cloud.host.Host.Type;
import com.cloud.host.dao.DetailsDao;
import com.cloud.host.dao.HostDao;
import com.cloud.hypervisor.Hypervisor;
@ -127,12 +122,9 @@ import com.cloud.user.Account;
import com.cloud.user.AccountManager;
import com.cloud.user.AccountVO;
import com.cloud.user.User;
import com.cloud.user.UserContext;
import com.cloud.user.UserVO;
import com.cloud.user.dao.AccountDao;
import com.cloud.user.dao.UserDao;
import com.cloud.uservm.UserVm;
import com.cloud.utils.DateUtil;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.Pair;
import com.cloud.utils.component.Adapters;
@ -1805,7 +1797,8 @@ public class StorageManagerImpl implements StorageManager {
}
}
s_logger.debug("Trying to execute Command: " + cmd + " on host: " + hostId + " try: " + tryCount);
answer = _agentMgr.send(hostId, cmd);
// set 120 min timeout for storage related command
answer = _agentMgr.send(hostId, cmd, 120*60*1000);
if (answer != null && answer.getResult()) {
return answer;
@ -1963,8 +1956,6 @@ public class StorageManagerImpl implements StorageManager {
{
boolean destroyVolumes = false;
long count = 1;
long consoleProxyId = 0;
long ssvmId = 0;
try
{
//1. Get the primary storage record
@ -2023,9 +2014,20 @@ public class StorageManagerImpl implements StorageManager {
{
if(destroyVolumes)
{
//proxy vm is stopped, and we have another ps available
//get the id for restart
consoleProxyId = vmInstance.getId();
//create a dummy event
long eventId1 = saveScheduledEvent(User.UID_SYSTEM, Account.ACCOUNT_ID_SYSTEM, EventTypes.EVENT_PROXY_START, "starting console proxy with Id: "+vmInstance.getId());
//Restore config val for consoleproxy.restart to true
_configMgr.updateConfiguration(userId, "consoleproxy.restart", "true");
if(_consoleProxyMgr.startProxy(vmInstance.getId(), eventId1)==null)
{
s_logger.warn("There was an error starting the console proxy id: "+vmInstance.getId()+" on another storage pool, cannot enable primary storage maintenance");
primaryStorage.setStatus(Status.ErrorInMaintenance);
_storagePoolDao.persist(primaryStorage);
return false;
}
}
}
}
@ -2064,9 +2066,15 @@ public class StorageManagerImpl implements StorageManager {
{
if(destroyVolumes)
{
//ss vm is stopped, and we have another ps available
//get the id for restart
ssvmId = vmInstance.getId();
//create a dummy event and restart the ssvm immediately
long eventId = saveScheduledEvent(User.UID_SYSTEM, Account.ACCOUNT_ID_SYSTEM, EventTypes.EVENT_SSVM_START, "starting ssvm with Id: "+vmInstance.getId());
if(_secStorageMgr.startSecStorageVm(vmInstance.getId(), eventId)==null)
{
s_logger.warn("There was an error starting the ssvm id: "+vmInstance.getId()+" on another storage pool, cannot enable primary storage maintenance");
primaryStorage.setStatus(Status.ErrorInMaintenance);
_storagePoolDao.persist(primaryStorage);
return false;
}
}
}
@ -2100,34 +2108,7 @@ public class StorageManagerImpl implements StorageManager {
_volsDao.remove(vol.getId());
}
//5. Restart all the system vms conditionally
if(destroyVolumes) //this means we have another ps. Ok to restart
{
//create a dummy event
long eventId = saveScheduledEvent(User.UID_SYSTEM, Account.ACCOUNT_ID_SYSTEM, EventTypes.EVENT_SSVM_START, "starting ssvm with Id: "+ssvmId);
if(_secStorageMgr.startSecStorageVm(ssvmId, eventId)==null)
{
s_logger.warn("There was an error starting the ssvm id: "+ssvmId+" on another storage pool, cannot enable primary storage maintenance");
primaryStorage.setStatus(Status.ErrorInMaintenance);
_storagePoolDao.persist(primaryStorage);
return false;
}
//create a dummy event
long eventId1 = saveScheduledEvent(User.UID_SYSTEM, Account.ACCOUNT_ID_SYSTEM, EventTypes.EVENT_PROXY_START, "starting console proxy with Id: "+consoleProxyId);
//Restore config val for consoleproxy.restart to true
_configMgr.updateConfiguration(userId, "consoleproxy.restart", "true");
if(_consoleProxyMgr.startProxy(consoleProxyId, eventId1)==null)
{
s_logger.warn("There was an error starting the console proxy id: "+consoleProxyId+" on another storage pool, cannot enable primary storage maintenance");
primaryStorage.setStatus(Status.ErrorInMaintenance);
_storagePoolDao.persist(primaryStorage);
return false; }
}
//6. Update the status
//5. Update the status
primaryStorage.setStatus(Status.Maintenance);
_storagePoolDao.persist(primaryStorage);

View File

@ -142,7 +142,12 @@ public abstract class AbstractStoragePoolAllocator extends AdapterBase implement
return false;
}
//if pool is NOT in up state, return false
if(!pool.getStatus().equals(com.cloud.host.Status.Up))//this is the pool status
{
return false;
}
// Check that the pool type is correct
if (!poolIsCorrectType(dskCh, pool, vm, offering)) {
return false;

View File

@ -236,7 +236,8 @@ public class TemplateManagerImpl implements TemplateManager {
s_logger.debug("Downloading " + templateId + " via " + vo.getHostId());
}
dcmd.setLocalPath(vo.getLocalPath());
DownloadAnswer answer = (DownloadAnswer)_agentMgr.easySend(vo.getHostId(), dcmd);
// set 120 min timeout for this command
DownloadAnswer answer = (DownloadAnswer)_agentMgr.easySend(vo.getHostId(), dcmd, 120*60*1000);
if (answer != null) {
templateStoragePoolRef.setDownloadPercent(templateStoragePoolRef.getDownloadPercent());
templateStoragePoolRef.setDownloadState(answer.getDownloadStatus());

View File

@ -171,7 +171,8 @@ def ifaces():
def ip(iface):
status,lines = commands.getstatusoutput('LANG=C /sbin/ip address show %s'%iface)
assert status == 0
if status != 0: return False
#used to say: assert status == 0 but it caused a bug in ifaces without IP
lines = [ l for l in lines.splitlines() if l.startswith(' inet ') ]
if not lines: return None
toks = lines[0].split()

View File

@ -25,7 +25,7 @@ long milliseconds = new Date().getTime();
- Default Cloud.com styling of the site. This file contains the easiest portion of the site
that can be styled to your companie's need such as logo, top navigation, and dialogs.
-->
<link rel= "stylesheet" href="css/cloud_custom.css" type="text/css" />
<link rel="stylesheet" href="css/cloud_custom.css" type="text/css" />
<!-- Javascripts -->

View File

@ -1467,7 +1467,7 @@ a:visited {
height:auto;
float:left;
margin:0 0 5px 10px;
padding:0;
padding:0 0 10px 0;
list-style:none;
}
@ -1479,7 +1479,7 @@ a:visited {
color:#CCC;
font-size:11px;
font-weight:normal;
margin:6px 0 0 0;
margin:8px 0 0 0;
padding:0;
list-style:none;
}
@ -1998,7 +1998,39 @@ a:visited {
color:#a90000;
}
.thanks box {
.grid_header {
width:100%;
height:20px;
float:left;
background:url(../images/grid_headerbg.gif) repeat-x top left;
margin:0;
padding:0;
}
.grid_header_title {
width:auto;
height:auto;
float:left;
margin:4px 0 0 10px;
display:inline;
color:#434343;
text-align:left;
font-weight:bold;
font-size:11px;
padding:0;
}
.grid_actionbox {
width:33px;
height:15px;
float:right;
background:url(../images/gird_actions.gif) no-repeat top left;
margin:2px 10px 0 0;
padding:0;
cursor:pointer;
cursor:hand;
}
.grid_actionbox:hover {
background:url(../images/gird_actions_hover.gif) no-repeat top left;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 182 B

View File

@ -12,6 +12,14 @@
%>
<!-- account detail panel (begin) -->
<div class="main_title" id="right_panel_header">
<!--
<div class="main_titleicon">
<img src="images/instancetitle_icons.gif" alt="Instance" /></div>
-->
<h1>Account
</h1>
</div>
<div class="contentbox" id="right_panel_content">
<div class="info_detailbox errorbox" id="after_action_info_container" style="display:none">
<p id="after_action_info"></p>

View File

@ -12,6 +12,14 @@
%>
<!-- alert detail panel (begin) -->
<div class="main_title" id="right_panel_header">
<!--
<div class="main_titleicon">
<img src="images/instancetitle_icons.gif" alt="Instance" /></div>
-->
<h1>Alert
</h1>
</div>
<div class="contentbox" id="right_panel_content">
<div class="info_detailbox errorbox" id="after_action_info_container" style="display:none">
<p id="after_action_info"></p>

View File

@ -12,6 +12,14 @@
%>
<!-- event detail panel (begin) -->
<div class="main_title" id="right_panel_header">
<!--
<div class="main_titleicon">
<img src="images/instancetitle_icons.gif" alt="Instance" /></div>
-->
<h1>Event
</h1>
</div>
<div class="contentbox" id="right_panel_content">
<div class="info_detailbox errorbox" id="after_action_info_container" style="display:none">
<p id="after_action_info"></p>

View File

@ -15,7 +15,7 @@
<div class="main_title" id="right_panel_header">
<div class="main_titleicon">
<img src="images/instancetitle_icons.gif" alt="Instance" /></div>
<h1 id="vm_name">
<h1 id="vm_name">Instance
</h1>
</div>
<div class="contentbox" id="right_panel_content">
@ -30,7 +30,8 @@
<div class="content_tabs off">
<%=t.t("Statistics")%></div>
</div>
<div class="grid_container">
<!--VM details start here-->
<div class="grid_container" style="display:none;">
<div class="grid_rows odd">
<div class="vm_statusbox">
<div class="vm_consolebox">
@ -139,6 +140,52 @@
</div>
</div>
</div>
<!--VM details ends here-->
<!--Volume start here-->
<div class="grid_container" style="display:block;">
<div class="grid_header">
<div class="grid_header_title">i-2-7-JW</div>
<div class="grid_actionbox"></div>
</div>
<div class="grid_rows even">
<div class="grid_row_cell" style="width: 20%;">
<div class="row_celltitles">
ID:</div>
</div>
<div class="grid_row_cell" style="width: 79%;">
<div class="row_celltitles">6</div>
</div>
</div>
<div class="grid_rows odd">
<div class="grid_row_cell" style="width: 20%;">
<div class="row_celltitles">
Type:</div>
</div>
<div class="grid_row_cell" style="width: 79%;">
<div class="row_celltitles">Root (Shared)</div>
</div>
</div>
<div class="grid_rows even">
<div class="grid_row_cell" style="width: 20%;">
<div class="row_celltitles">
Size:</div>
</div>
<div class="grid_row_cell" style="width: 79%;">
<div class="row_celltitles">8 GB</div>
</div>
</div>
<div class="grid_rows odd">
<div class="grid_row_cell" style="width: 20%;">
<div class="row_celltitles">
Created:</div>
</div>
<div class="grid_row_cell" style="width: 79%;">
<div class="row_celltitles">09/03/2010 15:06:04</div>
</div>
</div>
</div>
</div>
<!-- VM detail panel (end) -->
<!-- VM wizard (begin)-->

View File

@ -12,6 +12,14 @@
%>
<!-- snapshot detail panel (begin) -->
<div class="main_title" id="right_panel_header">
<!--
<div class="main_titleicon">
<img src="images/instancetitle_icons.gif" alt="Instance" /></div>
-->
<h1>Snapshot
</h1>
</div>
<div class="contentbox" id="right_panel_content">
<div class="info_detailbox errorbox" id="after_action_info_container" style="display:none">
<p id="after_action_info"></p>

View File

@ -12,6 +12,14 @@
%>
<!-- volume detail panel (begin) -->
<div class="main_title" id="right_panel_header">
<!--
<div class="main_titleicon">
<img src="images/instancetitle_icons.gif" alt="Instance" /></div>
-->
<h1>Volume
</h1>
</div>
<div class="contentbox" id="right_panel_content">
<div class="info_detailbox errorbox" id="after_action_info_container" style="display:none">
<p id="after_action_info"></p>

View File

@ -2,8 +2,8 @@ function loadAccountToRigntPanelFn($rightPanelContent) {
var jsonObj = $rightPanelContent.data("jsonObj");
var $rightPanelContent = $("#right_panel_content");
$rightPanelContent.find("#role").text(toRole(jsonObj.accounttype));
$rightPanelContent.find("#account").text(jsonObj.name);
$rightPanelContent.find("#domain").text(jsonObj.domain);
$rightPanelContent.find("#account").text(fromdb(jsonObj.name));
$rightPanelContent.find("#domain").text(fromdb(jsonObj.domain));
$rightPanelContent.find("#vm_total").text(jsonObj.vmtotal);
$rightPanelContent.find("#ip_total").text(jsonObj.iptotal);
$rightPanelContent.find("#bytes_received").text(jsonObj.receivedbytes);

View File

@ -1,11 +1,11 @@
function loadEventToRigntPanelFn($rightPanelContent) {
var jsonObj = $rightPanelContent.data("jsonObj");
var $rightPanelContent = $("#right_panel_content");
$rightPanelContent.find("#username").text(jsonObj.username);
$rightPanelContent.find("#account").text(jsonObj.account);
$rightPanelContent.find("#username").text(fromdb(jsonObj.username));
$rightPanelContent.find("#account").text(fromdb(jsonObj.account));
$rightPanelContent.find("#type").text(jsonObj.type);
$rightPanelContent.find("#level").text(jsonObj.level);
$rightPanelContent.find("#description").text(jsonObj.description);
$rightPanelContent.find("#description").text(fromdb(jsonObj.description));
$rightPanelContent.find("#state").text(jsonObj.state);
setDateField(jsonObj.created, $rightPanelContent.find("#created"));
}

View File

@ -9,7 +9,11 @@ $(document).ready(function() {
if(ui.newContent.length==0) //collapse
ui.oldHeader.find("#arrow_icon").removeClass("open").addClass("close");
else //expand
ui.newHeader.find("#arrow_icon").removeClass("close").addClass("open");
ui.newHeader.find("#arrow_icon").removeClass("close").addClass("open");
//collapse submenu instanceGroup under menu instance
$("#leftmenu_instance_group_header").find("#arrow_icon").removeClass("open").addClass("close");
$("#leftmenu_instance_group_container").empty();
}
});
$("#accordion_menu").show();

View File

@ -108,7 +108,7 @@ function clickInstanceGroupHeader($arrowIcon) {
if (isos != null && isos.length > 0) {
isoSelect.empty();
for (var i = 0; i < isos.length; i++) {
isoSelect.append("<option value='"+isos[i].id+"'>"+sanitizeXSS(isos[i].displaytext)+"</option>");;
isoSelect.append("<option value='"+isos[i].id+"'>"+fromdb(isos[i].displaytext)+"</option>");;
}
}
}
@ -196,7 +196,7 @@ function clickInstanceGroupHeader($arrowIcon) {
var name = trim(thisDialog.find("#change_instance_name").val());
for(var id in selectedItemIds) {
var apiCommand = "command=updateVirtualMachine&id="+id+"&displayName="+encodeURIComponent(escape(name));
var apiCommand = "command=updateVirtualMachine&id="+id+"&displayName="+todb(name);
doAction(id, $t, apiCommand, listAPIMap);
}
},
@ -217,7 +217,7 @@ function clickInstanceGroupHeader($arrowIcon) {
if (offerings != null && offerings.length > 0) {
for (var i = 0; i < offerings.length; i++) {
var option = $("<option value='" + offerings[i].id + "'>" + sanitizeXSS(unescape(offerings[i].displaytext)) + "</option>").data("name", sanitizeXSS(unescape(offerings[i].name)));
var option = $("<option value='" + offerings[i].id + "'>" + fromdb(offerings[i].displaytext) + "</option>").data("name", fromdb(offerings[i].name));
offeringSelect.append(option);
}
}
@ -264,7 +264,7 @@ function clickInstanceGroupHeader($arrowIcon) {
var $midMenuItem = selectedItemIds[id];
var jsonObj = $midMenuItem.data("jsonObj");
var group = trim(thisDialog.find("#change_group_name").val());
var apiCommand = "command=updateVirtualMachine&id="+id+"&group="+encodeURIComponent(group);
var apiCommand = "command=updateVirtualMachine&id="+id+"&group="+todb(group);
doAction(id, $t, apiCommand, listAPIMap);
}
},
@ -384,21 +384,21 @@ function clickInstanceGroupHeader($arrowIcon) {
var jsonObj = $t.data("jsonObj");
var vmName = getVmName(jsonObj.name, jsonObj.displayname);
$rightPanelHeader.find("#vm_name").text(vmName);
$rightPanelHeader.find("#vm_name").text(fromdb(vmName));
updateVirtualMachineStateInRightPanel(jsonObj.state);
$rightPanelContent.find("#ipAddress").text(jsonObj.ipaddress);
$rightPanelContent.find("#zoneName").text(jsonObj.zonename);
$rightPanelContent.find("#templateName").text(jsonObj.templatename);
$rightPanelContent.find("#serviceOfferingName").text(jsonObj.serviceofferingname);
$rightPanelContent.find("#zoneName").text(fromdb(jsonObj.zonename));
$rightPanelContent.find("#templateName").text(fromdb(jsonObj.templatename));
$rightPanelContent.find("#serviceOfferingName").text(fromdb(jsonObj.serviceofferingname));
if(jsonObj.haenable == "true")
$rightPanelContent.find("#ha").removeClass("cross_icon").addClass("tick_icon").show();
else
$rightPanelContent.find("#ha").removeClass("tick_icon").addClass("cross_icon").show();
$rightPanelContent.find("#created").text(jsonObj.created);
$rightPanelContent.find("#account").text(jsonObj.account);
$rightPanelContent.find("#domain").text(jsonObj.domain);
$rightPanelContent.find("#hostName").text(jsonObj.hostname);
$rightPanelContent.find("#group").text(jsonObj.group);
$rightPanelContent.find("#account").text(fromdb(jsonObj.account));
$rightPanelContent.find("#domain").text(fromdb(jsonObj.domain));
$rightPanelContent.find("#hostName").text(fromdb(jsonObj.hostname));
$rightPanelContent.find("#group").text(fromdb(jsonObj.group));
if(jsonObj.isoid != null && jsonObj.isoid.length > 0)
$rightPanelContent.find("#iso").removeClass("cross_icon").addClass("tick_icon").show();
else
@ -452,7 +452,7 @@ function clickInstanceGroupHeader($arrowIcon) {
var instance = instances[i];
var instanceGroup = instance.group;
if(instanceGroup == null || instanceGroup == "")
instanceGroup = "(no group name)";
instanceGroup = noGroupName;
if(instanceGroup != groupName)
continue;
var $midmenuItemVm1 = $midmenuItemVm.clone();
@ -558,7 +558,7 @@ function clickInstanceGroupHeader($arrowIcon) {
var $zoneSelect = $vmPopup.find("#wizard_zone").empty();
if (zones != null && zones.length > 0) {
for (var i = 0; i < zones.length; i++) {
$zoneSelect.append("<option value='" + zones[i].id + "'>" + sanitizeXSS(zones[i].name) + "</option>");
$zoneSelect.append("<option value='" + zones[i].id + "'>" + fromdb(zones[i].name) + "</option>");
}
}
listTemplatesInVmPopup();
@ -582,15 +582,15 @@ function clickInstanceGroupHeader($arrowIcon) {
var $t = $serviceOfferingTemplate.clone();
$t.find("input:radio[name=service_offering_radio]").val(offerings[i].id);
$t.find("#name").text(sanitizeXSS(unescape(offerings[i].name)));
$t.find("#description").text(sanitizeXSS(unescape(offerings[i].displaytext)));
$t.find("#name").text(fromdb(offerings[i].name));
$t.find("#description").text(fromdb(offerings[i].displaytext));
if (i > 0)
$t.find("input:radio[name=service_offering_radio]").removeAttr("checked");
//if(i == 0)
// $t.find("input:radio[name=service_offering_radio]").attr("checked", true);
//var listItem = $("<li><input class='radio' type='radio' name='service' id='service' value='"+offerings[i].id+"'" + checked + "/><label style='width:500px;font-size:11px;' for='service'>"+sanitizeXSS(unescape(offerings[i].displaytext))+"</label></li>");
//var listItem = $("<li><input class='radio' type='radio' name='service' id='service' value='"+offerings[i].id+"'" + checked + "/><label style='width:500px;font-size:11px;' for='service'>"+fromdb(offerings[i].displaytext)+"</label></li>");
$container.append($t.show());
}
//Safari and Chrome are not smart enough to make checkbox checked if html markup is appended by JQuery.append(). So, the following 2 lines are added.
@ -628,8 +628,8 @@ function clickInstanceGroupHeader($arrowIcon) {
for (var i = 0; i < offerings.length; i++) {
var $t = $existingDiskOfferingTemplate.clone();
$t.find("input:radio").attr("name","data_disk_offering_radio").val(offerings[i].id).removeAttr("checked");
$t.find("#name").text(sanitizeXSS(unescape(noNull(offerings[i].name))));
$t.find("#description").text(sanitizeXSS(noNull(unescape(offerings[i].displaytext))));
$t.find("#name").text(fromdb(noNull(offerings[i].name)));
$t.find("#description").text(fromdb(offerings[i].displaytext));
$dataDiskOfferingContainer.append($t.show());
}
}
@ -655,8 +655,8 @@ function clickInstanceGroupHeader($arrowIcon) {
$t.find("input:radio").attr("name","root_disk_offering_radio").val(offerings[i].id);
if(i > 0) //default is the 1st existing disk offering. If there is no existing disk offering, default to "custom" radio button
$t.find("input:radio").removeAttr("checked");
$t.find("#name").text(sanitizeXSS(unescape(noNull(offerings[i].name))));
$t.find("#description").text(sanitizeXSS(noNull(unescape(offerings[i].displaytext))));
$t.find("#name").text(fromdb(offerings[i].name));
$t.find("#description").text(fromdb(offerings[i].displaytext));
$rootDiskOfferingContainer.append($t.show());
}
}
@ -684,14 +684,14 @@ function clickInstanceGroupHeader($arrowIcon) {
var html =
"<li>"
+"<input class='radio' type='radio' name='rootdisk' id='rootdisk' value='"+offerings[i].id+"'" + ((i==0)?"checked":"") + "/>"
+"<label style='width:500px;font-size:11px;' for='disk'>"+sanitizeXSS(unescape(offerings[i].displaytext))+"</label>"
+"<label style='width:500px;font-size:11px;' for='disk'>"+fromdb(offerings[i].displaytext)+"</label>"
+"</li>";
$("#wizard_root_disk_offering").append(html);
var html2 =
"<li>"
+"<input class='radio' type='radio' name='datadisk' id='datadisk' value='"+offerings[i].id+"'" + "/>"
+"<label style='width:500px;font-size:11px;' for='disk'>"+sanitizeXSS(unescape(offerings[i].displaytext))+"</label>"
+"<label style='width:500px;font-size:11px;' for='disk'>"+fromdb(offerings[i].displaytext)+"</label>"
+"</li>";
$("#wizard_data_disk_offering").append(html2);
}
@ -843,8 +843,8 @@ function clickInstanceGroupHeader($arrowIcon) {
var html = '<div class="'+divClass+'" id="'+items[i].id+'">'
+'<div class="'+getIconForOS(items[i].ostypename)+'"></div>'
+'<div class="rev_wiztemp_listtext">'+sanitizeXSS(items[i].displaytext)+'</div>'
+'<div class="rev_wiztemp_ownertext">'+sanitizeXSS(items[i].account)+'</div>'
+'<div class="rev_wiztemp_listtext">'+fromdb(items[i].displaytext)+'</div>'
+'<div class="rev_wiztemp_ownertext">'+fromdb(items[i].account)+'</div>'
+'</div>';
container.append(html);
}
@ -1067,11 +1067,11 @@ function clickInstanceGroupHeader($arrowIcon) {
var name = trim($thisPopup.find("#wizard_vm_name").val());
if (name != null && name.length > 0)
moreCriteria.push("&displayname="+encodeURIComponent(name));
moreCriteria.push("&displayname="+todb(name));
var group = trim($thisPopup.find("#wizard_vm_group").val());
if (group != null && group.length > 0)
moreCriteria.push("&group="+encodeURIComponent(group));
moreCriteria.push("&group="+todb(group));
vmWizardClose();
@ -1131,7 +1131,7 @@ function clickInstanceGroupHeader($arrowIcon) {
// Failed
$t.find("#vm_name").text("Adding failed");
$t.find("#info_icon").addClass("error").show();
$t.data("afterActionInfo", ("Adding failed. Reason: " + sanitizeXSS(result.jobresult)));
$t.data("afterActionInfo", ("Adding failed. Reason: " + fromdb(result.jobresult)));
$t.bind("click", function(event) {
$rightPanelContent.find("#after_action_info").text($(this).data("afterActionInfo"));
$rightPanelContent.find("#after_action_info_container").addClass("errorbox");

View File

@ -165,6 +165,14 @@ function createURL(url) {
return url +"&response=json&sessionkey=" + g_sessionKey;
}
function fromdb(val) {
return sanitizeXSS(unescape(noNull(val)));
}
function todb(val) {
return encodeURIComponent(escape(display));
}
@ -790,16 +798,16 @@ function sanitizeXSS(val) {
function getVmName(p_vmName, p_vmDisplayname) {
if(p_vmDisplayname == null)
return sanitizeXSS(p_vmName);
return sanitizeXSS(unescape(p_vmName));
var vmName = null;
if (isAdmin()) {
if (p_vmDisplayname != p_vmName) {
vmName = p_vmName + "(" + sanitizeXSS(p_vmDisplayname) + ")";
vmName = p_vmName + "(" + sanitizeXSS(unescape(p_vmDisplayname)) + ")";
} else {
vmName = p_vmName;
}
} else {
vmName = sanitizeXSS(p_vmDisplayname);
vmName = sanitizeXSS(unescape(p_vmDisplayname));
}
return vmName;
}

View File

@ -4,11 +4,11 @@ function loadSnapshotToRigntPanelFn($rightPanelContent) {
var $rightPanelContent = $("#right_panel_content");
$rightPanelContent.find("#id").text(jsonObj.id);
$rightPanelContent.find("#name").text(jsonObj.name);
$rightPanelContent.find("#volume_name").text(jsonObj.volumename);
$rightPanelContent.find("#name").text(fromdb(jsonObj.name));
$rightPanelContent.find("#volume_name").text(fromdb(jsonObj.volumename));
$rightPanelContent.find("#interval_type").text(jsonObj.intervaltype);
$rightPanelContent.find("#account").text(jsonObj.account);
$rightPanelContent.find("#domain").text(jsonObj.domain);
$rightPanelContent.find("#account").text(fromdb(jsonObj.account));
$rightPanelContent.find("#domain").text(fromdb(jsonObj.domain));
setDateField(jsonObj.created, $rightPanelContent.find("#created"));
}

View File

@ -4,14 +4,14 @@ function loadVolumeToRigntPanelFn($rightPanelContent) {
var $rightPanelContent = $("#right_panel_content");
$rightPanelContent.find("#id").text(jsonObj.id);
$rightPanelContent.find("#name").text(jsonObj.name);
$rightPanelContent.find("#zonename").text(jsonObj.zonename);
$rightPanelContent.find("#name").text(fromdb(jsonObj.name));
$rightPanelContent.find("#zonename").text(fromdb(jsonObj.zonename));
$rightPanelContent.find("#device_id").text(jsonObj.deviceid);
$rightPanelContent.find("#state").text(jsonObj.state);
$rightPanelContent.find("#storage").text(jsonObj.storage);
$rightPanelContent.find("#account").text(jsonObj.account);
$rightPanelContent.find("#storage").text(fromdb(jsonObj.storage));
$rightPanelContent.find("#account").text(fromdb(jsonObj.account));
$rightPanelContent.find("#type").text(noNull(jsonObj.type) + " (" + noNull(jsonObj.storagetype) + " storage)");
$rightPanelContent.find("#type").text(jsonObj.type + " (" + jsonObj.storagetype + " storage)");
$rightPanelContent.find("#size").text((jsonObj.size == "0") ? "" : convertBytes(jsonObj.size));
if (jsonObj.virtualmachineid == null)