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

This commit is contained in:
Abhinandan Prateek 2011-12-23 08:05:41 +05:30
commit 764742ecac
39 changed files with 402 additions and 306 deletions

View File

@ -34,7 +34,7 @@ import com.cloud.user.Account;
@Implementation(description = "Adds Swift.", responseObject = HostResponse.class)
public class AddSwiftCmd extends BaseCmd {
public static final Logger s_logger = Logger.getLogger(AddSwiftCmd.class.getName());
private static final String s_name = "addSwiftresponse";
private static final String s_name = "addswiftresponse";
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////

View File

@ -35,9 +35,9 @@ import com.cloud.storage.Swift;
import com.cloud.user.Account;
@Implementation(description = "List Swift.", responseObject = HostResponse.class)
public class ListSwiftCmd extends BaseCmd {
public static final Logger s_logger = Logger.getLogger(ListSwiftCmd.class.getName());
private static final String s_name = "ListSwiftresponse";
public class ListSwiftsCmd extends BaseCmd {
public static final Logger s_logger = Logger.getLogger(ListSwiftsCmd.class.getName());
private static final String s_name = "listswiftresponse";
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
@ -67,7 +67,7 @@ public class ListSwiftCmd extends BaseCmd {
@Override
public void execute(){
List<? extends Swift> result = _resourceService.listSwift(this);
List<? extends Swift> result = _resourceService.listSwifts(this);
ListResponse<SwiftResponse> response = new ListResponse<SwiftResponse>();
List<SwiftResponse> swiftResponses = new ArrayList<SwiftResponse>();

View File

@ -25,7 +25,7 @@ import com.cloud.api.commands.AddSecondaryStorageCmd;
import com.cloud.api.commands.AddSwiftCmd;
import com.cloud.api.commands.CancelMaintenanceCmd;
import com.cloud.api.commands.DeleteClusterCmd;
import com.cloud.api.commands.ListSwiftCmd;
import com.cloud.api.commands.ListSwiftsCmd;
import com.cloud.api.commands.PrepareForMaintenanceCmd;
import com.cloud.api.commands.ReconnectHostCmd;
import com.cloud.api.commands.UpdateHostCmd;
@ -94,5 +94,5 @@ public interface ResourceService {
List<HypervisorType> getSupportedHypervisorTypes(long zoneId);
List<? extends Swift> listSwift(ListSwiftCmd cmd);
List<? extends Swift> listSwifts(ListSwiftsCmd cmd);
}

View File

@ -181,7 +181,7 @@ listCapacity=com.cloud.api.commands.ListCapacityCmd;3
#### swift commands^M
addSwift=com.cloud.api.commands.AddSwiftCmd;1
listSwift=com.cloud.api.commands.ListSwiftCmd;1
listSwifts=com.cloud.api.commands.ListSwiftsCmd;1
#### host commands

View File

@ -24,10 +24,6 @@ BuildRoot: %{_tmppath}/%{name}-%{_ver}-%{release}-build
BuildRequires: java-1.6.0-openjdk-devel
BuildRequires: tomcat6
BuildRequires: ws-commons-util
#BuildRequires: commons-codec
#BuildRequires: commons-dbcp
#BuildRequires: commons-collections
BuildRequires: commons-httpclient
BuildRequires: jpackage-utils
BuildRequires: gcc
BuildRequires: glibc-devel
@ -148,7 +144,6 @@ Requires: %{name}-python = %{version}
# Requires: %{name}-agent
Requires: tomcat6
Requires: ws-commons-util
#Requires: commons-codec
Requires: jpackage-utils
Requires: sudo
Requires: /sbin/service
@ -165,12 +160,6 @@ Requires: apache-commons-collections
Requires: jakarta-commons-httpclient
%endif
%if 0%{?rhel} >= 5
Requires: commons-dbcp
Requires: commons-collection
Requires: commons-httpclient
%endif
Group: System Environment/Libraries
%description client
The Cloud.com management server is the central point of coordination,
@ -272,11 +261,7 @@ Requires: java >= 1.6.0
Requires: %{name}-utils = %{version}, %{name}-core = %{version}, %{name}-deps = %{version}, %{name}-agent-libs = %{version}
Requires: python
Requires: %{name}-python = %{version}
Requires: commons-httpclient
#Requires: commons-codec
Requires: commons-collections
Requires: commons-pool
Requires: commons-dbcp
Requires: jakarta-commons-logging
Requires: jpackage-utils
Requires: %{name}-daemonize

View File

@ -418,6 +418,7 @@ setup_redundant_router() {
cp /root/redundant_router/primary-backup.sh.templ $rrouter_bin_path/primary-backup.sh
cp /root/redundant_router/heartbeat.sh.templ $rrouter_bin_path/heartbeat.sh
cp /root/redundant_router/check_heartbeat.sh.templ $rrouter_bin_path/check_heartbeat.sh
cp /root/redundant_router/arping_gateways.sh.templ $rrouter_bin_path/arping_gateways.sh
cp /root/redundant_router/check_bumpup.sh $rrouter_bin_path/
cp /root/redundant_router/disable_pubip.sh $rrouter_bin_path/
cp /root/redundant_router/checkrouter.sh.templ /root/checkrouter.sh
@ -446,6 +447,7 @@ setup_redundant_router() {
sed -i "s/\[RROUTER_LOG\]/$rrouter_log_str/g" $rrouter_bin_path/fault.sh
sed -i "s/\[RROUTER_LOG\]/$rrouter_log_str/g" $rrouter_bin_path/primary-backup.sh
sed -i "s/\[RROUTER_LOG\]/$rrouter_log_str/g" $rrouter_bin_path/check_heartbeat.sh
sed -i "s/\[RROUTER_LOG\]/$rrouter_log_str/g" $rrouter_bin_path/arping_gateways.sh
sed -i "s/\[RROUTER_LOG\]/$rrouter_log_str/g" /root/checkrouter.sh
chmod a+x $rrouter_bin_path/*.sh

View File

@ -0,0 +1,10 @@
ip link|grep BROADCAST|grep -v eth0|grep -v eth1|cut -d ":" -f 2 > /tmp/iflist
while read i
do
ip addr show $i|grep "inet " > /tmp/iplist_$i
while read line
do
ip=`echo $line|cut -d " " -f 2|cut -d "/" -f 1`
arping -I $i -A $ip -c 2 >> [RROUTER_LOG] 2>&1
done < /tmp/iplist_$i
done < /tmp/iflist

View File

@ -31,9 +31,7 @@ if [ $ret -ne 0 ]
then
echo Fail to switch conntrackd mode, but try to continue working >> [RROUTER_LOG]
fi
ping -n -c 3 [GATEWAY] >> [RROUTER_LOG] 2>&1 &
sleep 3
pkill ping
[RROUTER_BIN_PATH]/arping_gateways.sh
echo Status: MASTER >> [RROUTER_LOG]
releaseLockFile $lock $locked

View File

@ -430,8 +430,6 @@ def default_ebtables_rules():
util.pread2(['ebtables', '-A', 'DEFAULT_EBTABLES', '-p', 'IPv6', '-j', 'DROP'])
# deny vlan
util.pread2(['ebtables', '-A', 'DEFAULT_EBTABLES', '-p', '802_1Q', '-j', 'DROP'])
# deny all other 802. frames
util.pread2(['ebtables', '-A', 'FORWARD', '-j', 'DROP'])
except:
util.SMlog('Chain DEFAULT_EBTABLES already exists')

View File

@ -54,7 +54,7 @@ import com.cloud.api.commands.AddSecondaryStorageCmd;
import com.cloud.api.commands.AddSwiftCmd;
import com.cloud.api.commands.CancelMaintenanceCmd;
import com.cloud.api.commands.DeleteClusterCmd;
import com.cloud.api.commands.ListSwiftCmd;
import com.cloud.api.commands.ListSwiftsCmd;
import com.cloud.api.commands.PrepareForMaintenanceCmd;
import com.cloud.api.commands.ReconnectHostCmd;
import com.cloud.api.commands.UpdateHostCmd;
@ -518,8 +518,8 @@ public class ResourceManagerImpl implements ResourceManager, ResourceService, Ma
}
@Override
public List<SwiftVO> listSwift(ListSwiftCmd cmd) {
return _swiftMgr.listSwift(cmd);
public List<SwiftVO> listSwifts(ListSwiftsCmd cmd) {
return _swiftMgr.listSwifts(cmd);
}
private List<HostVO> discoverHostsFull(Long dcId, Long podId, Long clusterId, String clusterName, String url, String username, String password, String hypervisorType, List<String> hostTags,

View File

@ -112,7 +112,6 @@ import com.cloud.host.Host;
import com.cloud.host.HostVO;
import com.cloud.host.Status;
import com.cloud.host.dao.HostDao;
import com.cloud.host.dao.HostDetailsDao;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.hypervisor.HypervisorGuruManager;
import com.cloud.network.NetworkManager;
@ -135,6 +134,7 @@ import com.cloud.storage.dao.StoragePoolWorkDao;
import com.cloud.storage.dao.VMTemplateDao;
import com.cloud.storage.dao.VMTemplateHostDao;
import com.cloud.storage.dao.VMTemplatePoolDao;
import com.cloud.storage.dao.VMTemplateSwiftDao;
import com.cloud.storage.dao.VolumeDao;
import com.cloud.storage.listener.StoragePoolMonitor;
import com.cloud.storage.secondary.SecondaryStorageVmManager;
@ -236,6 +236,8 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag
@Inject
protected VMTemplatePoolDao _vmTemplatePoolDao = null;
@Inject
protected VMTemplateSwiftDao _vmTemplateSwiftDao = null;
@Inject
protected VMTemplateDao _vmTemplateDao = null;
@Inject
protected StoragePoolHostDao _poolHostDao = null;
@ -2515,14 +2517,20 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag
sc.setParameters("id", template.getId());
sc.setParameters("state", com.cloud.storage.VMTemplateStorageResourceAssoc.Status.DOWNLOADED);
sc.setJoinParameters("host", "dcId", vm.getDataCenterIdToDeployIn());
List<VMTemplateHostVO> sss = _vmTemplateHostDao.search(sc, null);
if (sss.size() == 0) {
throw new CloudRuntimeException("Template " + template.getName() + " has not been completely downloaded to zone " + vm.getDataCenterIdToDeployIn());
List<VMTemplateSwiftVO> tsvs = _vmTemplateSwiftDao.listByTemplateId(template.getId());
Long size = null;
if (tsvs != null && tsvs.size() > 0) {
size = tsvs.get(0).getSize();
}
if (size == null) {
List<VMTemplateHostVO> sss = _vmTemplateHostDao.search(sc, null);
if (sss == null || sss.size() == 0) {
throw new CloudRuntimeException("Template " + template.getName() + " has not been completely downloaded to zone " + vm.getDataCenterIdToDeployIn());
}
size = sss.get(0).getSize();
}
VMTemplateHostVO ss = sss.get(0);
VolumeVO vol = new VolumeVO(type, name, vm.getDataCenterIdToDeployIn(), owner.getDomainId(), owner.getId(), offering.getId(), ss.getSize());
VolumeVO vol = new VolumeVO(type, name, vm.getDataCenterIdToDeployIn(), owner.getDomainId(), owner.getId(), offering.getId(), size);
if (vm != null) {
vol.setInstanceId(vm.getId());
}

View File

@ -30,6 +30,6 @@ public interface VMTemplateZoneDao extends GenericDao<VMTemplateZoneVO, Long> {
public VMTemplateZoneVO findByZoneTemplate(long zoneId, long templateId);
public List<VMTemplateZoneVO> listByZoneTemplate(long zoneId, long templateId);
public List<VMTemplateZoneVO> listByZoneTemplate(Long zoneId, long templateId);
}

View File

@ -77,9 +77,11 @@ public class VMTemplateZoneDaoImpl extends GenericDaoBase<VMTemplateZoneVO, Long
}
@Override
public List<VMTemplateZoneVO> listByZoneTemplate(long zoneId, long templateId) {
SearchCriteria<VMTemplateZoneVO> sc = ZoneTemplateSearch.create();
sc.setParameters("zone_id", zoneId);
public List<VMTemplateZoneVO> listByZoneTemplate(Long zoneId, long templateId) {
SearchCriteria<VMTemplateZoneVO> sc = ZoneTemplateSearch.create();
if (zoneId != null) {
sc.setParameters("zone_id", zoneId);
}
sc.setParameters("template_id", templateId);
return listBy(sc);
}

View File

@ -30,7 +30,7 @@ import com.cloud.agent.api.to.SwiftTO;
import com.cloud.api.commands.AddSwiftCmd;
import com.cloud.api.commands.DeleteIsoCmd;
import com.cloud.api.commands.DeleteTemplateCmd;
import com.cloud.api.commands.ListSwiftCmd;
import com.cloud.api.commands.ListSwiftsCmd;
import com.cloud.exception.DiscoveryException;
import com.cloud.storage.Swift;
import com.cloud.storage.SwiftVO;
@ -57,5 +57,5 @@ public interface SwiftManager extends Manager {
Long chooseZoneForTmpltExtract(Long tmpltId);
List<SwiftVO> listSwift(ListSwiftCmd cmd);
}
List<SwiftVO> listSwifts(ListSwiftsCmd cmd);
}

View File

@ -42,7 +42,7 @@ import com.cloud.agent.api.to.SwiftTO;
import com.cloud.api.commands.AddSwiftCmd;
import com.cloud.api.commands.DeleteIsoCmd;
import com.cloud.api.commands.DeleteTemplateCmd;
import com.cloud.api.commands.ListSwiftCmd;
import com.cloud.api.commands.ListSwiftsCmd;
import com.cloud.configuration.Config;
import com.cloud.configuration.dao.ConfigurationDao;
import com.cloud.dc.DataCenterVO;
@ -266,7 +266,7 @@ public class SwiftManagerImpl implements SwiftManager {
}
@Override
public List<SwiftVO> listSwift(ListSwiftCmd cmd) {
public List<SwiftVO> listSwifts(ListSwiftsCmd cmd) {
if (cmd.getId() == null) {
return _swiftDao.listAll();
} else {

View File

@ -95,6 +95,7 @@ import com.cloud.storage.VMTemplateStorageResourceAssoc;
import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
import com.cloud.storage.VMTemplateSwiftVO;
import com.cloud.storage.VMTemplateVO;
import com.cloud.storage.VMTemplateZoneVO;
import com.cloud.storage.VolumeVO;
import com.cloud.storage.dao.SnapshotDao;
import com.cloud.storage.dao.StoragePoolDao;
@ -1160,6 +1161,14 @@ public class TemplateManagerImpl implements TemplateManager, Manager, TemplateSe
boolean result = adapter.delete(profile);
if (result){
if (cmd.getZoneId() == null && _swiftMgr.isSwiftEnabled()) {
List<VMTemplateZoneVO> templateZones = _tmpltZoneDao.listByZoneTemplate(null, templateId);
if (templateZones != null) {
for (VMTemplateZoneVO templateZone : templateZones) {
_tmpltZoneDao.remove(templateZone.getId());
}
}
}
return true;
}else{
throw new CloudRuntimeException("Failed to delete template");
@ -1191,10 +1200,18 @@ public class TemplateManagerImpl implements TemplateManager, Manager, TemplateSe
}
TemplateAdapter adapter = getAdapter(template.getHypervisorType());
TemplateProfile profile = adapter.prepareDelete(cmd);
boolean result = adapter.delete(profile);
if (result){
return true;
}else{
boolean result = adapter.delete(profile);
if (result) {
if (cmd.getZoneId() == null && _swiftMgr.isSwiftEnabled()) {
List<VMTemplateZoneVO> templateZones = _tmpltZoneDao.listByZoneTemplate(null, templateId);
if (templateZones != null) {
for (VMTemplateZoneVO templateZone : templateZones) {
_tmpltZoneDao.remove(templateZone.getId());
}
}
}
return true;
} else {
throw new CloudRuntimeException("Failed to delete ISO");
}
}

View File

@ -61,6 +61,6 @@ update host_details set name='privateip' where host_id in (select id from host w
INSERT IGNORE INTO configuration VALUES ('Advanced', 'DEFAULT', 'management-server', 'vmware.root.disk.controller', 'ide', 'Specify the default disk controller for root volumes, valid values are scsi, ide');
INSERT IGNORE INTO configuration VALUES ('Advanced', 'DEFAULT', 'management-server', 'vm.destory.forcestop', 'false', 'On destory, force-stop takes this value');
INSERT IGNORE INTO configuration VALUES ('Network', 'DEFAULT', 'management-server', 'network.lock.timeout', '600', 'Lock wait timeout (seconds) while implementing network');
INSERT IGNORE INTO configuration VALUES ('Network', 'DEFAULT', 'management-server', 'network.disable.rpfilter','true','disable rp_filter on Domain Router VM public interfaces.');

View File

@ -53,7 +53,6 @@ INSERT IGNORE INTO configuration VALUES ('Network', 'DEFAULT', 'management-serve
INSERT IGNORE INTO configuration VALUES ('Network', 'DEFAULT', 'management-server', 'network.loadbalancer.haproxy.stats.uri','/admin?stats','Load Balancer(haproxy) uri.');
INSERT IGNORE INTO configuration VALUES ('Network', 'DEFAULT', 'management-server', 'network.loadbalancer.haproxy.stats.auth','admin1:AdMiN123','Load Balancer(haproxy) authetication string in the format username:password');
INSERT IGNORE INTO configuration VALUES ('Network', 'DEFAULT', 'management-server', 'network.loadbalancer.haproxy.stats.port','8081','Load Balancer(haproxy) stats port number.');
INSERT IGNORE INTO configuration VALUES ('Network', 'DEFAULT', 'management-server', 'network.disable.rpfilter','true','disable rp_filter on Domain Router VM public interfaces.');
INSERT IGNORE INTO configuration VALUES ('Advanced', 'DEFAULT', 'NetworkManager', 'use.external.dns', 'false', 'Bypass the cloudstack DHCP/DNS server vm name service, use zone external dns1 and dns2');
INSERT IGNORE INTO configuration VALUES ('Advanced', 'DEFAULT', 'management-server', 'network.loadbalancer.basiczone.elb.enabled', 'false', 'Whether the load balancing service is enabled for basic zones');
INSERT IGNORE INTO configuration VALUES ('Advanced', 'DEFAULT', 'management-server', 'network.loadbalancer.basiczone.elb.gc.interval.minutes', '120', 'Garbage collection interval to destroy unused ELB vms in minutes. Minimum of 5');

View File

@ -35,7 +35,6 @@ INSERT IGNORE INTO configuration VALUES ('Network', 'DEFAULT', 'management-serve
INSERT IGNORE INTO configuration VALUES ('Network', 'DEFAULT', 'management-server', 'network.loadbalancer.haproxy.stats.uri','/admin?stats','Load Balancer(haproxy) uri.');
INSERT IGNORE INTO configuration VALUES ('Network', 'DEFAULT', 'management-server', 'network.loadbalancer.haproxy.stats.auth','admin1:AdMiN123','Load Balancer(haproxy) authetication string in the format username:password');
INSERT IGNORE INTO configuration VALUES ('Network', 'DEFAULT', 'management-server', 'network.loadbalancer.haproxy.stats.port','8081','Load Balancer(haproxy) stats port number.');
INSERT IGNORE INTO configuration VALUES ('Network', 'DEFAULT', 'management-server', 'network.disable.rpfilter','true','disable rp_filter on Domain Router VM public interfaces.');
INSERT IGNORE INTO configuration VALUES ('Advanced', 'DEFAULT', 'NetworkManager', 'use.external.dns', 'false', 'Bypass the cloudstack DHCP/DNS server vm name service, use zone external dns1 and dns2');
INSERT IGNORE INTO configuration VALUES ('Advanced', 'DEFAULT', 'management-server', 'network.loadbalancer.basiczone.elb.enabled', 'false', 'Whether the load balancing service is enabled for basic zones');
INSERT IGNORE INTO configuration VALUES ('Advanced', 'DEFAULT', 'management-server', 'network.loadbalancer.basiczone.elb.gc.interval.minutes', '120', 'Garbage collection interval to destroy unused ELB vms in minutes. Minimum of 5');

View File

@ -29,6 +29,14 @@ body {
font-family: sans-serif;
height: 769px !important;
overflow: auto;
background: #FFFFFF;
}
body.install-wizard {
font-family: sans-serif;
height: 769px !important;
overflow: auto;
background: #FFFFFF url(../images/bg-login.png);
}
#container {
@ -354,7 +362,7 @@ body.login {
color: #4A4A4A;
font-size: 15px;
line-height: 23px;
background: url(../images/bg-transparent-white.png);
background: url(../images/bg-gradient-white-transparent.png) repeat-x -114px -270px;
}
.install-wizard .step ul li {
@ -383,15 +391,15 @@ body.login {
.install-wizard .body {
width: 1012px;
height: 626px;
height: 762px;
margin: -352px auto auto;
z-index: 10;
background: #FFFFFF -114px -141px;
/*+box-shadow:0px -7px 10px #C6C6C6;*/
-moz-box-shadow: 0px -7px 10px #C6C6C6;
-webkit-box-shadow: 0px -7px 10px #C6C6C6;
-o-box-shadow: 0px -7px 10px #C6C6C6;
box-shadow: 0px -7px 10px #C6C6C6;
background: url(../images/bg-gradient-white-transparent.png) repeat-x -114px -141px;
/*+box-shadow:0px -3px 4px #CFCFCF;*/
-moz-box-shadow: 0px -3px 4px #CFCFCF;
-webkit-box-shadow: 0px -3px 4px #CFCFCF;
-o-box-shadow: 0px -3px 4px #CFCFCF;
box-shadow: 0px -3px 4px #CFCFCF;
}
.install-wizard h2 {
@ -602,11 +610,11 @@ body.login {
-webkit-text-shadow: 0px 1px 0px #FFFFFF;
-o-text-shadow: 0px 1px 0px #FFFFFF;
text-shadow: 0px 1px 0px #FFFFFF;
/*+box-shadow:inset 0px 1px 5px #FFFFFF;*/
-moz-box-shadow: inset 0px 1px 5px #FFFFFF;
-webkit-box-shadow: inset 0px 1px 5px #FFFFFF;
-o-box-shadow: inset 0px 1px 5px #FFFFFF;
box-shadow: inset 0px 1px 5px #FFFFFF;
/*+box-shadow:0px 5px 9px #9F9F9F;*/
-moz-box-shadow: 0px 5px 9px #9F9F9F;
-webkit-box-shadow: 0px 5px 9px #9F9F9F;
-o-box-shadow: 0px 5px 9px #9F9F9F;
box-shadow: 0px 5px 9px #9F9F9F;
}
.install-wizard .step .setup-form .title {
@ -2006,11 +2014,11 @@ div.toolbar div.text-search div.search-bar {
z-index: 4;
position: relative;
border-right: 1px solid #8B8989;
/*+border-radius:3px 0 0 3px;*/
-moz-border-radius: 3px 0 0 3px;
-webkit-border-radius: 3px 0 0 3px;
-khtml-border-radius: 3px 0 0 3px;
border-radius: 3px 0 0 3px;
/*+border-radius:4px 0 0 4px;*/
-moz-border-radius: 4px 0 0 4px;
-webkit-border-radius: 4px 0 0 4px;
-khtml-border-radius: 4px 0 0 4px;
border-radius: 4px 0 0 4px;
}
div.toolbar div.text-search div.search-bar input {
@ -2261,7 +2269,15 @@ div.list-view div.toolbar div.section-switcher div.section-select {
div.list-view div.toolbar div.section-switcher div.section-select select {
width: 142px;
height: 21px;
margin-right: 13px;
font-size: 12px;
border: 1px solid #808080;
/*+border-radius:4px;*/
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
-khtml-border-radius: 4px;
border-radius: 4px 4px 4px 4px;
}
div.list-view div.toolbar div.section-switcher div.section-select label {
@ -2306,6 +2322,7 @@ div.toolbar div.filters select {
-khtml-border-radius: 4px;
border-radius: 4px 4px 4px 4px;
padding: 0px 0 0;
margin: 1px 0 0;
}
#breadcrumbs {
@ -4430,7 +4447,7 @@ label.error {
float: left;
display: block;
clear: both;
margin: 0 0 0 58px;
margin: 12px 0 0 58px;
/*+placement:shift 0px -6px;*/
position: relative;
left: 0px;
@ -4446,6 +4463,10 @@ label.error {
font-size: 11px;
margin-right: 9px;
margin-left: 2px;
/*+placement:shift;*/
position: relative;
left: 0;
top: 0;
}
.multi-wizard.instance-wizard .select-iso .wizard-step-conditional.select-iso .content .select.selected {
@ -4468,6 +4489,12 @@ label.error {
z-index: 10;
}
.multi-wizard .select-iso .ui-tabs ul {
float: left;
left: 0px;
top: 1px;
}
.multi-wizard .ui-tabs ul li.first a {
border-left: 1px solid #E2DDDD;
}
@ -4910,6 +4937,10 @@ label.error {
margin: 0 0 0 11px;
}
.multi-wizard.instance-wizard .select-network .select.new-network label.error {
display: none !important;
}
.multi-wizard.instance-wizard .select-network .select.new-network .secondary-input {
width: 97px;
padding: 13px 0 17px;

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

View File

@ -236,7 +236,7 @@
<div class="field name hide-if-unselected">
<div class="name">Name</div>
<div class="value">
<input type="text" name="new-network-name" />
<input type="text" class="required" name="new-network-name" />
</div>
</div>

View File

@ -23,9 +23,9 @@
storage: {},
network: {},
templates: {},
events: {},
accounts: {},
domains: {},
events: {},
system: {},
projects: {},
'global-settings': {},
@ -92,9 +92,9 @@
dataType: "json",
async: false,
success: function(json) {
/* g_supportELB: "guest" à¥à¤ˆ ips are allocated on guest network (so use 'forvirtualnetwork' = false)
/* g_supportELB: "guest" à¥à¤à¥à¤ˆ ips are allocated on guest network (so use 'forvirtualnetwork' = false)
* g_supportELB: "public" - ips are allocated on public network (so use 'forvirtualnetwork' = true)
* g_supportELB: "false" à¥à¤ˆ no ELB support
* g_supportELB: "false" à¥à¤à¥à¤ˆ no ELB support
*/
g_capabilities = json.listcapabilitiesresponse.capability;
g_supportELB = json.listcapabilitiesresponse.capability.supportELB.toString(); //convert boolean to string if it's boolean

View File

@ -969,18 +969,24 @@
action: function(args) {
var formData = args.data;
var inputData = {};
var services = {};
var serviceProviderMap = {};
var serviceCapabilityMap = {};
$.each(formData, function(key, value) {
var serviceData = key.split('.');
if (serviceData.length > 1) {
if (serviceData.length > 1) {
if (serviceData[0] == 'service' &&
serviceData[2] == 'isEnabled' &&
value == 'on') { // Services field
services[serviceData[1]] = formData[
serviceProviderMap[serviceData[1]] = formData[
'service.' + serviceData[1] + '.provider'
];
}
else if (serviceData[0] == 'service' &&
serviceData[2].indexOf('Capability') != -1 &&
value == 'on') { // Services field
serviceCapabilityMap[serviceData[1]] = serviceData[2];
}
} else if (value != '') { // Normal data
inputData[key] = value;
@ -988,7 +994,7 @@
});
// Make supported services list
inputData['supportedServices'] = $.map(services, function(value, key) {
inputData['supportedServices'] = $.map(serviceProviderMap, function(value, key) {
return key;
}).join(',');
@ -1000,12 +1006,25 @@
// Make service provider map
var serviceProviderIndex = 0;
$.each(services, function(key, value) {
$.each(serviceProviderMap, function(key, value) {
inputData['serviceProviderList[' + serviceProviderIndex + '].service'] = key;
inputData['serviceProviderList[' + serviceProviderIndex + '].provider'] = value;
serviceProviderIndex++;
});
var serviceCapabilityIndex = 0;
$.each(serviceCapabilityMap, function(key, value) {
var capabilityType = null;
if(value == "redundantRouterCapability")
capabilityType = "RedundantRouter";
if(capabilityType != null) {
inputData['serviceCapabilityList[' + serviceCapabilityIndex + '].service'] = key;
inputData['serviceCapabilityList[' + serviceCapabilityIndex + '].capabilitytype'] = capabilityType;
inputData['serviceCapabilityList[' + serviceCapabilityIndex + '].capabilityvalue'] = true;
serviceCapabilityIndex++;
}
});
$.ajax({
url: createURL('createNetworkOffering'),
data: inputData,
@ -1153,6 +1172,11 @@
});
}
},
"service.SourceNat.redundantRouterCapability" : {
label: "Redundant router capability",
isBoolean: true
},
tags: { label: 'Tags' }
}

View File

@ -392,7 +392,7 @@
error: function(XMLHttpResponse) {
isCreateNetworkSuccessful = false;
var errorMsg = "Failed to create new network, unable to proceed to deploy VM. Error: " + parseXMLHttpResponse(XMLHttpResponse);
alert(errorMsg);
//alert(errorMsg);
args.response.error(errorMsg); //args.response.error(errorMsg) here doesn't show errorMsg. Waiting for Brian to fix it. use alert(errorMsg) to show errorMsg for now.
}
});
@ -460,8 +460,7 @@
);
},
error: function(XMLHttpResponse) {
//args.response.error(); //wait for Brian to implement
alert("Failed to deploy VM.");
args.response.error(parseXMLHttpResponse(XMLHttpResponse)); //wait for Brian to implement
}
});
}
@ -1648,7 +1647,6 @@
allowedActions.push("detachISO");
allowedActions.push("resetPassword");
allowedActions.push("changeService");
if(jsonObj.hypervisor == "BareMetal") {
allowedActions.push("createTemplate");

View File

@ -530,8 +530,8 @@
});
},
error: function(data) {
args.response.error(parseXMLHttpResponse(data));
error: function(json) {
args.response.error(parseXMLHttpResponse(json));
}
});
},

View File

@ -18,13 +18,13 @@
success: function(json) {
updatedResources++;
if (updatedResources == totalResources) {
args.response.success();
args.response.success();
}
}
});
});
},
dataProvider: function(args) {
$.ajax({
url: createURL('listResourceLimits'),
@ -70,7 +70,7 @@
});
}
});
}
},
@ -80,9 +80,9 @@
$.ajax({
url: createURL('listVirtualMachines'),
success: function(json) {
var instances = json.listvirtualmachinesresponse.virtualmachine ?
var instances = json.listvirtualmachinesresponse.virtualmachine ?
json.listvirtualmachinesresponse.virtualmachine : [];
dataFns.storage($.extend(data, {
runningInstances: $.grep(instances, function(instance) {
return instance.state == 'Running';
@ -124,7 +124,7 @@
id: network.networkofferingid
},
success: function(json) {
totalBandwidth +=
totalBandwidth +=
json.listnetworkofferingsresponse.networkoffering[0].networkrate;
}
});
@ -142,7 +142,7 @@
url: createURL('listPublicIpAddresses'),
success: function(json) {
dataFns.loadBalancingRules($.extend(data, {
totalIPAddresses: json.listpublicipaddressesresponse ?
totalIPAddresses: json.listpublicipaddressesresponse.count ?
json.listpublicipaddressesresponse.count : 0
}));
}
@ -154,7 +154,7 @@
url: createURL('listLoadBalancerRules'),
success: function(json) {
dataFns.portForwardingRules($.extend(data, {
totalLoadBalancers: json.listloadbalancerrulesresponse ?
totalLoadBalancers: json.listloadbalancerrulesresponse.count ?
json.listloadbalancerrulesresponse.count : 0
}));
}
@ -166,7 +166,7 @@
url: createURL('listPortForwardingRules'),
success: function(json) {
dataFns.users($.extend(data, {
totalPortForwards: json.listportforwardingrulesresponse ?
totalPortForwards: json.listportforwardingrulesresponse.count ?
json.listportforwardingrulesresponse.count : 0
}));
}
@ -193,13 +193,19 @@
events: function(data) {
$.ajax({
url: createURL('listEvents', { ignoreProject: true }),
data: {
page: 1,
pageSize: 8
},
success: function(json) {
var events = json.listeventsresponse.event;
complete($.extend(data, {
events: $.map(events, function(event) {
return {
date: event.created.substr(5, 2) + '/' + event.created.substr(8, 2) + '/' + event.created.substr(2, 2),
date: event.created.substr(5, 2) +
'/' + event.created.substr(8, 2) +
'/' + event.created.substr(2, 2),
desc: event.description
};
})
@ -381,7 +387,7 @@
actionPreFilter: function(args) {
if (!cloudStack.context.projects &&
args.context.multiRule[0].role != 'Admin') { // This is for the new project wizard
return ['destroy'];
return ['destroy'];
}
if (args.context.multiRule[0].role != 'Admin') {
@ -489,10 +495,10 @@
data.listprojectsresponse.project ?
data.listprojectsresponse.project : [],
function(elem) {
return $.extend(elem, {
displayText: elem.displaytext
});
})
return $.extend(elem, {
displayText: elem.displaytext
});
})
});
}
});
@ -812,14 +818,14 @@
var projectsActionFilter = function(args) {
var allowedActions = ['destroy'];
if (args.context.item.account == cloudStack.context.users[0].account || args.context.users[0].role == '1') {
if (args.context.item.state == 'Suspended') {
allowedActions.push('enable');
} else if (args.context.item.state == 'Active') {
allowedActions.push('disable');
}
return allowedActions;
}

View File

@ -142,6 +142,9 @@
}
}
);
},
error: function(json) {
args.response.error(parseXMLHttpResponse(json));
}
});
},

View File

@ -4322,6 +4322,10 @@
{jobId: jid}
}
);
},
error: function(json) {
args.response.error(parseXMLHttpResponse(json));
}
});
},

View File

@ -1,4 +1,4 @@
(function(cloudStack, testData) {
(function(cloudStack, $, testData) {
cloudStack.sections.templates = {
title: 'Templates',
@ -290,18 +290,13 @@
copyTemplate: {
label: 'Copy template',
addRow: 'false',
messages: {
confirm: function(args) {
return 'Are you sure you want to copy template?';
},
success: function(args) {
return 'Template is being copied.';
},
notification: function(args) {
return 'Copying template';
},
complete: function(args) {
return 'Template has been copied.';
}
},
createForm: {
@ -310,6 +305,7 @@
fields: {
destinationZoneId: {
label: 'Destination zone',
validation: { required: true },
select: function(args) {
$.ajax({
url: createURL("listZones&available=true"),
@ -317,12 +313,21 @@
async: true,
success: function(json) {
args.response.success({
data: $.map(json.listzonesresponse.zone, function(zone) {
return {
id: zone.id,
description: zone.name
};
})
data: $.map(
$.grep(
json.listzonesresponse.zone ? json.listzonesresponse.zone : [],
function(zone) {
return zone.id != args.context.templates[0].zoneid;
}
),
function(zone) {
return {
id: zone.id,
description: zone.name
};
}
)
});
}
});
@ -562,6 +567,7 @@
fields: {
destinationZoneId: {
label: 'Destination zone',
validation: { required: true },
select: function(args) {
$.ajax({
url: createURL("listZones&available=true"),
@ -804,13 +810,23 @@
}
],
dataProvider: function(args) {
args.response.success(
{
actionFilter: templateActionfilter,
data:args.context.templates[0]
}
);
dataProvider: function(args) {
var jsonObj = args.context.templates[0];
var apiCmd = "listTemplates&templatefilter=self&id=" + jsonObj.id;
if(jsonObj.zoneid != null)
apiCmd = apiCmd + "&zoneid=" + jsonObj.zoneid;
$.ajax({
url: createURL(apiCmd),
dataType: "json",
success: function(json) {
args.response.success({
actionFilter: templateActionfilter,
data: json.listtemplatesresponse.template[0]
});
}
});
}
}
}
@ -995,19 +1011,14 @@
confirm: function(args) {
return 'Are you sure you want to copy ISO?';
},
success: function(args) {
return 'ISO is being copied.';
},
notification: function(args) {
return 'Copying ISO';
},
complete: function(args) {
return 'ISO has been copied.';
}
},
createForm: {
title: 'Copy ISO',
desc: '',
addRow: 'false',
fields: {
destinationZoneId: {
label: 'Destination zone',
@ -1493,12 +1504,22 @@
],
dataProvider: function(args) {
args.response.success(
{
actionFilter: isoActionfilter,
data:args.context.isos[0]
}
);
var jsonObj = args.context.isos[0];
var apiCmd = "listIsos&isofilter=self&id="+jsonObj.id;
if(jsonObj.zoneid != null)
apiCmd = apiCmd + "&zoneid="+jsonObj.zoneid;
$.ajax({
url: createURL(apiCmd),
dataType: "json",
success: function(json) {
args.response.success({
actionFilter: isoActionfilter,
data: json.listisosresponse.iso[0]
});
}
});
}
}
}
@ -1609,4 +1630,4 @@
return allowedActions;
}
})(cloudStack, testData);
})(cloudStack, jQuery, testData);

View File

@ -13,6 +13,7 @@
*/
var complete = function() {
$installWizard.remove();
$('html body').removeClass('install-wizard');
args.complete();
};
@ -379,7 +380,7 @@
tooltipID: 'addZone',
diagram: '.part.zone',
prevStepID: 'addZoneIntro',
nextStepID: 'addPod',
nextStepID: 'addPodIntro',
form: {
name: { label: 'Name', validation: { required: true } },
dns1: { label: 'DNS 1', validation: { required: true } },
@ -430,7 +431,7 @@
id: 'add-guest-network',
stateID: 'guestNetwork',
tooltipID: 'addGuestNetwork',
diagram: '.part.zone',
diagram: '.part.zone, .part.pod',
prevStepID: 'addPod',
nextStepID: 'addClusterIntro',
form: {
@ -734,6 +735,7 @@
var initialStep = steps.intro().addClass('step');
showDiagram('');
$('html body').addClass('install-wizard');
$installWizard.append(
elems.header(),

View File

@ -583,7 +583,11 @@
// Next button
if ($target.closest('div.button.next').size()) {
if (!$form.valid()) return false;
if (!$form.valid()) {
if ($form.find('input.error:visible, select.error:visible').size()) {
return false;
}
}
showStep($steps.filter(':visible').index() + 2);

View File

@ -4,7 +4,7 @@
* User management multi-edit
*/
userManagement: function(args) {
var multiEdit = !args.useInvites ?
var multiEdit = !args.useInvites ?
cloudStack.projects.addUserForm :
cloudStack.projects.inviteForm;
@ -62,7 +62,7 @@
} else {
$item.hide().html(value).fadeIn();
}
});
});
}
});
}
@ -85,8 +85,10 @@
};
// Only show management tabs to owner of project
if (cloudStack.context.projects &&
(cloudStack.context.projects[0].account == cloudStack.context.users[0].account)) {
if (isAdmin() || (
cloudStack.context.projects &&
(cloudStack.context.projects[0].account == cloudStack.context.users[0].account)
)) {
tabs.users = function() {
return $('<div>').addClass('management').data('tab-title', 'Users');
};
@ -94,14 +96,14 @@
if (g_capabilities.projectinviterequired) {
tabs.invitations = function() {
return $('<div>').addClass('management-invite').data('tab-title', 'Invitations');
};
};
}
tabs.resources = function() {
var $resources = $('<div>').addClass('resources').data('tab-title', 'Resources');
var $form = $('<form>');
var $submit = $('<input>').attr({
type: 'submit'
type: 'submit'
}).val('Apply');
cloudStack.projects.resourceManagement.dataProvider({
@ -118,7 +120,7 @@
name: resource.type,
value: resource.value
}).addClass('required');
$field.append($label, $input);
$field.appendTo($form);
});
@ -147,7 +149,7 @@
}
}
});
return false;
});
@ -156,7 +158,7 @@
}
}
});
return $resources;
};
}
@ -167,14 +169,15 @@
// Make UI tabs
$.each(tabs, function(tabName, tab) {
var $tab = $('<li>').appendTo($tabs.find('ul:first'));
var $tabContent = tab();
var $tabLink = $('<a>')
.attr({ href: '#project-view-dashboard-' + tabName })
.html(tab().data('tab-title'))
.html($tabContent.data('tab-title'))
.appendTo($tab);
var $content = $('<div>')
.appendTo($tabs)
.attr({ id: 'project-view-dashboard-' + tabName })
.append(tab);
.append($tabContent);
});
$tabs.find('ul li:first').addClass('first');
@ -252,7 +255,7 @@
var project = args.data;
$(window).trigger('cloudStack.fullRefresh');
$loading.remove();
// Confirmation
@ -346,7 +349,7 @@
var $instanceRow = args.$instanceRow;
$instanceRow.animate({ opacity: 0.5 });
cloudStack.projects.addUserForm.actions.destroy.action({
context: $.extend(true, {}, cloudStack.context, {
projects: [project],
@ -388,9 +391,16 @@
$('.ui-dialog, .overlay').remove();
});
$laterButton.click(function() {
$(':ui-dialog, .overlay').remove();
return false;
});
return $review;
});
});
$laterButton.html('Close').appendTo($userManagement);
return $userManagement;
});

View File

@ -123,6 +123,18 @@
var $target = $(event.target);
var $projectSwitcher = $(this);
var $container = $('html body');
var $navDisabled = $(
$.map([
'projects',
'accounts',
'domains',
'system',
'global-settings',
'configuration'
], function(id) {
return '#navigation li.' + id;
}).join(',')
);
if ($target.closest('.select.project-view').size()) {
$('#cloudStack3-container').addClass('project-view');
@ -131,14 +143,12 @@
.siblings().removeClass('active');
// Activate project view
$('#navigation li.projects').addClass('disabled').attr({
title: 'Projects can only be edited outside of project view.'
});
$navDisabled.hide();
cloudStack.uiCustom.projects({
$projectSelect: $projectSelect.hide().find('select')
});
} else {
$('#navigation li.projects').removeClass('disabled').attr('title', '');
$navDisabled.show();
$('#cloudStack3-container').removeClass('project-view');
$projectSwitcher.removeClass('alt');
$projectSelect.hide();

View File

@ -259,8 +259,7 @@
var getFormValues = function() {
var formValues = {};
$.each(args.form.fields, function(key) {
});
$.each(args.form.fields, function(key) {});
};
// Setup form validation
@ -277,7 +276,7 @@
if (!$formContainer.find('form').valid()) {
// Ignore hidden field validation
if ($formContainer.find('input.error:visible').size()) {
if ($formContainer.find('input.error:visible, select.error:visible').size()) {
return false;
}
}

View File

@ -1,39 +1,44 @@
(function($, cloudStack) {
var event = cloudStack.ui.event = {};
// Attach element to a specific event type
event.elem = function(widget, elem, $elem, extraData) {
// Setup DOM metadata
var data = { cloudStack: {} };
data.cloudStack[widget] = {
elem: elem
};
if (extraData) $.extend(data.cloudStack[widget], extraData);
cloudStack.ui.event = {
// Attach element to specific event type
elem: function(widget, elem, $elem, extraData) {
// Setup DOM metadata
var data = { cloudStack: {} };
data.cloudStack[widget] = {
elem: elem
};
if (extraData) $.extend(data.cloudStack[widget], extraData);
return $elem
.addClass('cloudStack-elem')
.addClass(widget)
.data(data);
};
return $elem
.addClass('cloudStack-elem')
.addClass(widget)
.data(data);
},
// Create widget-based event
event.bind = function(widget, events) {
return function(event) {
var $target = $(event.target);
var $widget, $elem;
var data, elem;
// Create widget-based event
bind: function(widget, events) {
return function(event) {
var $target = $(event.target);
var $widget, $elem;
var data, elem;
$elem = $target.closest('.cloudStack-elem.' + widget);
if (!$elem.size())
return true;
$elem = $target.closest('.cloudStack-elem.' + widget);
if (!$elem.size())
return true;
$widget = $('.cloudStack-widget.' + widget);
data = $elem.data('cloudStack')[widget];
elem = data.elem;
$widget = $('.cloudStack-widget.' + widget);
data = $elem.data('cloudStack')[widget];
elem = data.elem;
events[elem]($elem, $widget, data);
events[elem]($elem, $widget, data);
return false;
};
return false;
};
},
// Trigger CloudStack UI event (cloudStack.*)
call: function(eventName, data) {
$(window).trigger('cloudStack.' + eventName, data);
}
};
})(jQuery, cloudStack);

View File

@ -1,53 +1,4 @@
(function($, cloudStack) {
/**
* Add 'pending' notification
*/
var addNotification = function(notification, success, successArgs, error, errorArgs) {
if (!notification) {
success(successArgs);
return false;
};
var $notifications = $('div.notifications');
if (!notification.poll) {
$notifications.notifications('add', {
section: notification.section,
desc: notification.desc,
interval: 0,
poll: function(args) { success(successArgs); args.complete(); }
});
} else {
$notifications.notifications('add', {
section: notification.section,
desc: notification.desc,
interval: 2000,
_custom: notification._custom,
poll: function(args) {
var complete = args.complete;
var notificationError = args.error;
notification.poll({
_custom: args._custom,
complete: function(args) {
success($.extend(successArgs, args));
complete(args);
},
error: function(args) {
error($.extend(errorArgs, args));
notificationError(args);
return cloudStack.dialog.error;
}
});
}
});
}
return true;
};
var replaceListViewItem = function($detailView, newData) {
var $row = $detailView.data('list-view-row');
@ -141,7 +92,7 @@
notification.desc = messages.notification(args.messageArgs);
notification._custom = args._custom;
addNotification(
cloudStack.ui.notifications.add(
notification,
// Success
@ -158,7 +109,9 @@
{},
// Error
function(args) {}
function(args) {
$loading.remove();
}
);
}
});
@ -181,7 +134,7 @@
if (additional && additional.success) additional.success(args);
// Setup notification
addNotification(
cloudStack.ui.notifications.add(
notification,
function(args) {
if ($detailView.is(':visible')) {
@ -208,13 +161,12 @@
// Error
function(args) {
$loading.remove();
}
);
},
error: function(args) {
// if (args.message)
// cloudStack.dialog.notice({ message: args.message });
$loading.remove();
}
}
});
@ -368,13 +320,13 @@
if (!action.notification) {
convertInputs($inputs);
addNotification(
cloudStack.ui.notifications.add(
notificationArgs, function() {}, []
);
replaceListViewItem($detailView, data);
} else {
$loading.appendTo($detailView);
addNotification(
cloudStack.ui.notifications.add(
$.extend(true, {}, action.notification, notificationArgs),
function(args) {
replaceListViewItem($detailView, data);

View File

@ -2,53 +2,6 @@
* Create dynamic list view based on data callbacks
*/
(function($, cloudStack) {
/**
* Add 'pending' notification
*/
var addNotification = function(notification, success, successArgs, error, errorArgs) {
if (!notification) {
success(successArgs);
return false;
};
var $notifications = $('div.notifications');
if (!notification.poll) {
$notifications.notifications('add', {
section: notification.section,
desc: notification.desc,
interval: 0,
poll: function(args) { success(successArgs); args.complete(); }
});
} else {
$notifications.notifications('add', {
section: notification.section,
desc: notification.desc,
interval: 5000,
_custom: notification._custom,
poll: function(args) {
var complete = args.complete;
var notificationError = args.error;
notification.poll({
_custom: args._custom,
complete: function(args) {
success($.extend(successArgs, args));
complete(args);
},
error: function(args) {
error($.extend(errorArgs, args));
notificationError(args);
}
});
}
});
}
return true;
};
var uiActions = {
standard: function($instanceRow, args, additional) {
var listViewArgs = $instanceRow.closest('div.list-view').data('view-args');
@ -110,7 +63,7 @@
notification.desc = messages.notification(args.messageArgs);
notification._custom = args._custom;
addNotification(
cloudStack.ui.notifications.add(
notification,
function(args) {
if ($item.is(':visible')) {
@ -174,7 +127,7 @@
if (additional && additional.success) additional.success(args);
addNotification(
cloudStack.ui.notifications.add(
notification,
// Success
@ -233,8 +186,8 @@
);
},
error: function(message) {
if ($.isPlainObject(args.action.createForm)
&& args.action.addRow != 'false') {
if (($.isPlainObject(args.action.createForm) && args.action.addRow != 'false') ||
(!args.action.createForm && args.action.addRow == 'true')) {
$instanceRow.remove();
}
@ -428,15 +381,14 @@
var newName = $editInput.val();
showLabel(newName, {
success: function() {
addNotification(
cloudStack.ui.notifications.add(
{
section: $instanceRow.closest('div.view').data('view-args').id,
desc: newName ? 'Set value of ' + $instanceRow.find('td.name span').html() + ' to ' + newName :
desc: newName ?
'Set value of ' + $instanceRow.find('td.name span').html() + ' to ' + newName :
'Unset value for ' + $instanceRow.find('td.name span').html()
},
function(args) {
},
function(args) {},
[{ name: newName }]
);
}

View File

@ -213,6 +213,10 @@
}
};
/**
* Define notification widget -- this is basically represented in a
* notifications icon, that contains a pop-up list of notifications
*/
$.fn.notifications = function(method, args) {
var $attachTo = this;
var $total = $attachTo.find('div.total span');
@ -230,7 +234,60 @@
return this;
};
// Events
/**
* Notifications UI helpers
*/
cloudStack.ui.notifications = {
add: function(notification, success, successArgs, error, errorArgs) {
if (!notification) {
success(successArgs);
return false;
};
var $notifications = $('div.notifications');
if (!notification.poll) {
cloudStack.ui.event.call('addNotification', {
section: notification.section,
desc: notification.desc,
interval: 0,
poll: function(args) { success(successArgs); args.complete(); }
});
} else {
cloudStack.ui.event.call('addNotification', {
section: notification.section,
desc: notification.desc,
interval: 5000,
_custom: notification._custom,
poll: function(args) {
var complete = args.complete;
var notificationError = args.error;
notification.poll({
_custom: args._custom,
complete: function(args) {
success($.extend(successArgs, args));
complete(args);
},
error: function(args) {
error($.extend(errorArgs, args));
notificationError(args);
}
});
}
});
}
return true;
}
};
// Setup notification listener -- accepts same args as
$(window).bind('cloudStack.addNotification', function(event, data) {
$('.notifications').notifications('add', data);
});
$(document).click(function(event) {
var $target = $(event.target);
var $attachTo, $popup;