From e6cfacacfe04cf49b5e8e928fc73a14ce905fb8b Mon Sep 17 00:00:00 2001
From: abhishek
Date: Tue, 21 Sep 2010 10:47:26 -0700
Subject: [PATCH 01/16] some more ipassoc changes
---
scripts/network/domr/ipassoc.sh | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/scripts/network/domr/ipassoc.sh b/scripts/network/domr/ipassoc.sh
index 1988d4c73f1..6df7626a856 100755
--- a/scripts/network/domr/ipassoc.sh
+++ b/scripts/network/domr/ipassoc.sh
@@ -57,11 +57,11 @@ add_one_to_one_nat_entry() {
local dIp=$3
ssh -p 3922 -o StrictHostKeyChecking=no -i $cert root@$dIp "\
iptables -t nat -A PREROUTING -i eth2 -d $publicIp -j DNAT --to-destination $guestIp
- iptables -t nat -A POSTROUTING -o $eth2 -s $guestIp -j SNAT --to-source $publicIp
+ iptables -t nat -A POSTROUTING -o eth2 -s $guestIp -j SNAT --to-source $publicIp
iptables -P FORWARD DROP
iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
- iptables -A FORWARD -i $eth2 -o $eth1 -d $guestIp -m state --state NEW -j ACCEPT
- iptables -A FORWARD -i $eth1 -o $eth2 -s $guestIp -m state --state NEW -j ACCEPT
+ iptables -A FORWARD -i eth2 -o eth0 -d $guestIp -m state --state NEW -j ACCEPT
+ iptables -A FORWARD -i eth0 -o eth2 -s $guestIp -m state --state NEW -j ACCEPT
"
return $?
}
@@ -187,7 +187,10 @@ done
if [ "$Gflag" == "1" ] && [ "$fflag" == "1" ] && [ "$Aflag" == "1" ]
then
add_nat_entry $domRIp $publicIp
- add_one_to_one_nat_entry $guestIp $publicIp $domRIp
+ if [ $? -gt 0 ]
+ then
+ add_one_to_one_nat_entry $guestIp $publicIp $domRIp
+ fi
exit $?
fi
From 37870da95fea300db707aab2671d074301e15c2f Mon Sep 17 00:00:00 2001
From: abhishek
Date: Tue, 21 Sep 2010 14:46:30 -0700
Subject: [PATCH 02/16] bug 3120: incremental fix
---
scripts/network/domr/ipassoc.sh | 6 +++---
server/src/com/cloud/api/commands/AssociateIPAddrCmd.java | 5 +----
2 files changed, 4 insertions(+), 7 deletions(-)
diff --git a/scripts/network/domr/ipassoc.sh b/scripts/network/domr/ipassoc.sh
index 6df7626a856..8afce76e46c 100755
--- a/scripts/network/domr/ipassoc.sh
+++ b/scripts/network/domr/ipassoc.sh
@@ -124,7 +124,7 @@ remove_an_ip () {
fi
}
-#set -x
+set -x
rflag=
iflag=
@@ -184,10 +184,10 @@ do
done
#1:1 NAT
-if [ "$Gflag" == "1" ] && [ "$fflag" == "1" ] && [ "$Aflag" == "1" ]
+if [ "$Gflag" == "1" ]
then
add_nat_entry $domRIp $publicIp
- if [ $? -gt 0 ]
+ if [ $? -eq 0 ]
then
add_one_to_one_nat_entry $guestIp $publicIp $domRIp
fi
diff --git a/server/src/com/cloud/api/commands/AssociateIPAddrCmd.java b/server/src/com/cloud/api/commands/AssociateIPAddrCmd.java
index 8755e42a1eb..046425f438d 100644
--- a/server/src/com/cloud/api/commands/AssociateIPAddrCmd.java
+++ b/server/src/com/cloud/api/commands/AssociateIPAddrCmd.java
@@ -72,10 +72,7 @@ public class AssociateIPAddrCmd extends BaseCmd {
String accountName = (String)params.get(BaseCmd.Properties.ACCOUNT.getName());
Long domainId = (Long)params.get(BaseCmd.Properties.DOMAIN_ID.getName());
Long vmId = (Long)params.get(BaseCmd.Properties.VIRTUAL_MACHINE_ID.getName());
-
- //todo REMOVE
- //vmId = new Long(3);
-
+
String newIpAddr = null;
String errorDesc = null;
Long accountId = null;
From 50c319e19b5b90dc84af6d3f57cc1a912bae9373 Mon Sep 17 00:00:00 2001
From: abhishek
Date: Tue, 21 Sep 2010 14:47:15 -0700
Subject: [PATCH 03/16] bug 3120: incremental checkin
---
scripts/network/domr/ipassoc.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/network/domr/ipassoc.sh b/scripts/network/domr/ipassoc.sh
index 8afce76e46c..2d460bf7e5a 100755
--- a/scripts/network/domr/ipassoc.sh
+++ b/scripts/network/domr/ipassoc.sh
@@ -124,7 +124,7 @@ remove_an_ip () {
fi
}
-set -x
+#set -x
rflag=
iflag=
From 8dcea8c07ecefb60bff3661e284e9dd8f556d2b7 Mon Sep 17 00:00:00 2001
From: Jessica Wang
Date: Tue, 21 Sep 2010 14:48:48 -0700
Subject: [PATCH 04/16] new UI - clear right panel after deleting a volume.
---
ui/new/scripts/cloud.core2.js | 43 ++++++++++++++++------------
ui/new/scripts/cloud.core2.volume.js | 22 +++++++++++++-
2 files changed, 45 insertions(+), 20 deletions(-)
diff --git a/ui/new/scripts/cloud.core2.js b/ui/new/scripts/cloud.core2.js
index 9b307abad5a..eb6c619bb16 100644
--- a/ui/new/scripts/cloud.core2.js
+++ b/ui/new/scripts/cloud.core2.js
@@ -136,24 +136,28 @@ function doActionToDetailsTab(id, $actionLink, apiCommand, listAPIMap) {
dataType: "json",
async: false,
success: function(json) {
- $spinningWheel.hide();
-
- //RecoverVirtualMachine API doesn't return an embedded object on success (Bug 6037)
- //Before Bug 6037 get fixed, use the temporary solution below.
- $.ajax({
- cache: false,
- data: createURL("command="+listAPI+"&id="+id),
- dataType: "json",
- async: false,
- success: function(json) {
- $detailsTab.find("#action_message_box #description").text(label + " action succeeded.");
- $detailsTab.find("#action_message_box").removeClass("error").show();
-
- afterActionSeccessFn(json[listAPIResponse][listAPIResponseObj][0]);
- }
- });
- //After Bug 6037 is fixed, remove temporary solution above and uncomment the line below
- //afterActionSeccessFn(json[listAPIResponse][listAPIResponseObj][0]);
+ $spinningWheel.hide();
+ $detailsTab.find("#action_message_box #description").text(label + " action succeeded.");
+ $detailsTab.find("#action_message_box").removeClass("error").show();
+
+ if(apiCommand.indexOf("command=delete")!=0) {
+ //RecoverVirtualMachine API doesn't return an embedded object on success (Bug 6037)
+ //Before Bug 6037 get fixed, use the temporary solution below.
+ $.ajax({
+ cache: false,
+ data: createURL("command="+listAPI+"&id="+id),
+ dataType: "json",
+ async: false,
+ success: function(json) {
+ afterActionSeccessFn(json[listAPIResponse][listAPIResponseObj][0]);
+ }
+ });
+ //After Bug 6037 is fixed, remove temporary solution above and uncomment the line below
+ //afterActionSeccessFn(json[listAPIResponse][listAPIResponseObj][0]);
+ }
+ else { //apiCommand is deleteXXXXXXX
+ afterActionSeccessFn(id);
+ }
},
error: function(XMLHttpResponse) {
handleErrorInDetailsTab(XMLHttpResponse, $detailsTab, label);
@@ -539,7 +543,8 @@ function clearMiddleMenu() {
}
function clearRightPanel() {
- $("#right_panel_content #action_message_box").hide();
+ $("#right_panel_content #action_message_box").hide();
+ $("#right_panel_content #tab_content_details #action_link #action_menu #action_list").empty();
}
var selected_leftmenu_id = null;
diff --git a/ui/new/scripts/cloud.core2.volume.js b/ui/new/scripts/cloud.core2.volume.js
index 9e3b329e6de..ee9a5edda50 100644
--- a/ui/new/scripts/cloud.core2.volume.js
+++ b/ui/new/scripts/cloud.core2.volume.js
@@ -98,6 +98,21 @@ function volumeJsonToDetailsTab(jsonObj){
template.find("#grid_links_container").show(); //show actions panel
*/
}
+
+function volumeClearRightPanel() {
+ var $detailsTab = $("#right_panel_content #tab_content_details");
+ $detailsTab.find("#id").text("");
+ $detailsTab.find("#name").text("");
+ $detailsTab.find("#zonename").text("");
+ $detailsTab.find("#device_id").text("");
+ $detailsTab.find("#state").text("");
+ $detailsTab.find("#storage").text("");
+ $detailsTab.find("#account").text("");
+ $detailsTab.find("#type").text("");
+ $detailsTab.find("#size").text("");
+ $detailsTab.find("#vm_name").text("");
+ $detailsTab.find("#created").text("");
+}
var volumeActionMap = {
"Detach Disk": {
@@ -118,7 +133,12 @@ var volumeActionMap = {
api: "deleteVolume",
isAsyncJob: false,
inProcessText: "Deleting volume....",
- afterActionSeccessFn: function(){}
+ afterActionSeccessFn: function(id) {
+ var $midmenuItem1 = $("#midmenuItem_"+id);
+ $midmenuItem1.remove();
+ clearRightPanel();
+ volumeClearRightPanel();
+ }
}
}
From 3f9b58bc73f01c49646e07f27ea0227b885a1008 Mon Sep 17 00:00:00 2001
From: Jessica Wang
Date: Tue, 21 Sep 2010 14:55:27 -0700
Subject: [PATCH 05/16] new UI - volume page - hide actions when volume state
is "Creating" or "Corrupted" or volume is attaching to a VM.
---
ui/new/scripts/cloud.core2.volume.js | 47 +++++++++++++---------------
1 file changed, 21 insertions(+), 26 deletions(-)
diff --git a/ui/new/scripts/cloud.core2.volume.js b/ui/new/scripts/cloud.core2.volume.js
index ee9a5edda50..a7739cdbf18 100644
--- a/ui/new/scripts/cloud.core2.volume.js
+++ b/ui/new/scripts/cloud.core2.volume.js
@@ -70,33 +70,28 @@ function volumeJsonToDetailsTab(jsonObj){
//buildActionLinkForDetailsTab("Take Snapshot", volumeActionMap, $actionMenu, volumeListAPIMap); //show take snapshot
//buildActionLinkForDetailsTab("Recurring Snapshot", volumeActionMap, $actionMenu, volumeListAPIMap); //show Recurring Snapshot
-
- if(jsonObj.type=="ROOT") {
- if (jsonObj.vmstate == "Stopped")
- buildActionLinkForDetailsTab("Create Template", volumeActionMap, $actionMenu, volumeListAPIMap); //show create template
- }
- else {
- if (jsonObj.virtualmachineid != null) {
- if (jsonObj.storagetype == "shared" && (jsonObj.vmstate == "Running" || jsonObj.vmstate == "Stopped")) {
- buildActionLinkForDetailsTab("Detach Disk", volumeActionMap, $actionMenu, volumeListAPIMap); //show detach disk
- }
- } else {
- // Disk not attached
- if (jsonObj.storagetype == "shared") {
- buildActionLinkForDetailsTab("Detach Disk", volumeActionMap, $actionMenu, volumeListAPIMap); //show attach disk
-
- if(jsonObj.vmname == null || jsonObj.vmname == "none")
- buildActionLinkForDetailsTab("Delete Volume", volumeActionMap, $actionMenu, volumeListAPIMap); //show delete volume
- }
- }
+
+ if(jsonObj.state != "Creating" && jsonObj.state != "Corrupted" && jsonObj.name != "attaching") {
+ if(jsonObj.type=="ROOT") {
+ if (jsonObj.vmstate == "Stopped")
+ buildActionLinkForDetailsTab("Create Template", volumeActionMap, $actionMenu, volumeListAPIMap); //show create template
+ }
+ else {
+ if (jsonObj.virtualmachineid != null) {
+ if (jsonObj.storagetype == "shared" && (jsonObj.vmstate == "Running" || jsonObj.vmstate == "Stopped")) {
+ buildActionLinkForDetailsTab("Detach Disk", volumeActionMap, $actionMenu, volumeListAPIMap); //show detach disk
+ }
+ } else {
+ // Disk not attached
+ if (jsonObj.storagetype == "shared") {
+ buildActionLinkForDetailsTab("Detach Disk", volumeActionMap, $actionMenu, volumeListAPIMap); //show attach disk
+
+ if(jsonObj.vmname == null || jsonObj.vmname == "none")
+ buildActionLinkForDetailsTab("Delete Volume", volumeActionMap, $actionMenu, volumeListAPIMap); //show delete volume
+ }
+ }
+ }
}
-
- /*
- if(jsonObj.state == "Creating" || jsonObj.state == "Corrupted" || jsonObj.name == "attaching")
- template.find("#grid_links_container").hide(); //hide actions panel
- else
- template.find("#grid_links_container").show(); //show actions panel
- */
}
function volumeClearRightPanel() {
From 2727dc53eb499f53ff146202b6d8588cc708cab3 Mon Sep 17 00:00:00 2001
From: abhishek
Date: Tue, 21 Sep 2010 15:01:57 -0700
Subject: [PATCH 06/16] bug 3120: now we provide a 1:1 nat functionality. we
acquire a public ip from the ui, and if the 1:1 nat option is chosen, provide
a valid vm instance id with it. the backend logic maps this id to a guest ip,
and programs the ip table rules to forward all traffic from the public ip
acquired, to this guest. for tests, try ssh'ing to that host, using something
like ssh root@192.168.30.43 (for this public ip acquired), and you should be
able to log into the guest vm
status 3120: resolved fixed
---
server/src/com/cloud/server/ManagementServerImpl.java | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java
index 2df1bdf1cab..86856f1e5ce 100755
--- a/server/src/com/cloud/server/ManagementServerImpl.java
+++ b/server/src/com/cloud/server/ManagementServerImpl.java
@@ -1569,6 +1569,14 @@ public class ManagementServerImpl implements ManagementServer {
_accountMgr.incrementResourceCount(accountId, ResourceType.public_ip);
}
+ if(vmId!=0){
+ VMInstanceVO vm = _vmInstanceDao.findById(vmId);
+
+ if(vm == null){
+ throw new InvalidParameterValueException("Invalid vm instance id:"+vmId+" specified");
+ }
+ }
+
boolean success = true;
String errorMsg = "";
From d07cac932a0ed57d4adb88ea3c143601f3f0a868 Mon Sep 17 00:00:00 2001
From: abhishek
Date: Tue, 21 Sep 2010 15:17:21 -0700
Subject: [PATCH 07/16] bug 6165: there is a possiblility of the root volume
being null when we search for it, which may be causing a npe in this bug.
enhancing the logic around this status 6165: resolved fixed
---
server/src/com/cloud/api/commands/ListVMsCmd.java | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/server/src/com/cloud/api/commands/ListVMsCmd.java b/server/src/com/cloud/api/commands/ListVMsCmd.java
index 0041fcc31af..a78cbc2e400 100644
--- a/server/src/com/cloud/api/commands/ListVMsCmd.java
+++ b/server/src/com/cloud/api/commands/ListVMsCmd.java
@@ -290,10 +290,13 @@ public class ListVMsCmd extends BaseCmd {
//root device related
VolumeVO rootVolume = getManagementServer().findRootVolume(vmInstance.getId());
- vmData.add(new Pair(BaseCmd.Properties.ROOT_DEVICE_ID.getName(), rootVolume.getDeviceId()));
+ if(rootVolume!=null)
+ {
+ vmData.add(new Pair(BaseCmd.Properties.ROOT_DEVICE_ID.getName(), rootVolume.getDeviceId()));
- StoragePoolVO storagePool = getManagementServer().findPoolById(rootVolume.getPoolId());
- vmData.add(new Pair(BaseCmd.Properties.ROOT_DEVICE_TYPE.getName(), storagePool.getPoolType().toString()));
+ StoragePoolVO storagePool = getManagementServer().findPoolById(rootVolume.getPoolId());
+ vmData.add(new Pair(BaseCmd.Properties.ROOT_DEVICE_TYPE.getName(), storagePool.getPoolType().toString()));
+ }
vmTag[i++] = vmData;
}
From f89e11bb21a0100a70f5755224481b7046dc9741 Mon Sep 17 00:00:00 2001
From: Jessica Wang
Date: Tue, 21 Sep 2010 15:37:22 -0700
Subject: [PATCH 08/16] new UI - volume page - implement take snapshot action.
---
ui/new/jsp/volume.jsp | 6 +++++
ui/new/scripts/cloud.core2.volume.js | 35 ++++++++++++++++++++++++----
2 files changed, 37 insertions(+), 4 deletions(-)
diff --git a/ui/new/jsp/volume.jsp b/ui/new/jsp/volume.jsp
index 179a6f4052d..0b0cd193cda 100644
--- a/ui/new/jsp/volume.jsp
+++ b/ui/new/jsp/volume.jsp
@@ -218,3 +218,9 @@
+
+
+
+ Please confirm you want to create snapshot for this volume.
+
+
diff --git a/ui/new/scripts/cloud.core2.volume.js b/ui/new/scripts/cloud.core2.volume.js
index a7739cdbf18..bba2752634f 100644
--- a/ui/new/scripts/cloud.core2.volume.js
+++ b/ui/new/scripts/cloud.core2.volume.js
@@ -5,7 +5,11 @@ function afterLoadVolumeJSP() {
modal: true,
zIndex: 2000
}));
-
+ activateDialog($("#dialog_create_snapshot").dialog({
+ autoOpen: false,
+ modal: true,
+ zIndex: 2000
+ }));
$.ajax({
data: createURL("command=listOsTypes&response=json"),
@@ -68,7 +72,7 @@ function volumeJsonToDetailsTab(jsonObj){
var $actionMenu = $("#right_panel_content #tab_content_details #action_link #action_menu");
$actionMenu.find("#action_list").empty();
- //buildActionLinkForDetailsTab("Take Snapshot", volumeActionMap, $actionMenu, volumeListAPIMap); //show take snapshot
+ buildActionLinkForDetailsTab("Take Snapshot", volumeActionMap, $actionMenu, volumeListAPIMap); //show take snapshot
//buildActionLinkForDetailsTab("Recurring Snapshot", volumeActionMap, $actionMenu, volumeListAPIMap); //show Recurring Snapshot
if(jsonObj.state != "Creating" && jsonObj.state != "Corrupted" && jsonObj.name != "attaching") {
@@ -134,7 +138,14 @@ var volumeActionMap = {
clearRightPanel();
volumeClearRightPanel();
}
- }
+ },
+ "Take Snapshot": {
+ isAsyncJob: true,
+ asyncJobResponse: "createsnapshotresponse",
+ dialogBeforeActionFn : doTakeSnapshot,
+ inProcessText: "Taking Snapshot....",
+ afterActionSeccessFn: function(){}
+ }
}
var volumeListAPIMap = {
@@ -173,4 +184,20 @@ function doCreateTemplateFromVolume($actionLink, listAPIMap, $detailsTab) {
$(this).dialog("close");
}
}).dialog("open");
-}
\ No newline at end of file
+}
+
+function doTakeSnapshot($actionLink, listAPIMap, $detailsTab) {
+ $("#dialog_create_snapshot")
+ .dialog('option', 'buttons', {
+ "Confirm": function() {
+ $(this).dialog("close");
+
+ var id = $detailsTab.data("jsonObj").id;
+ var apiCommand = "command=createSnapshot&volumeid="+id;
+ doActionToDetailsTab(id, $actionLink, apiCommand, listAPIMap);
+ },
+ "Cancel": function() {
+ $(this).dialog("close");
+ }
+ }).dialog("open");
+}
From 122b0d1aebce0700a53612fa2b23b5a339d7c51c Mon Sep 17 00:00:00 2001
From: abhishek
Date: Tue, 21 Sep 2010 15:48:26 -0700
Subject: [PATCH 09/16] bug 6243: adding a check to return an error in case we
have a null domain id for a non null account status 6243: resolved fixed
---
server/src/com/cloud/api/commands/ListVMsCmd.java | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/server/src/com/cloud/api/commands/ListVMsCmd.java b/server/src/com/cloud/api/commands/ListVMsCmd.java
index a78cbc2e400..59d226340dc 100644
--- a/server/src/com/cloud/api/commands/ListVMsCmd.java
+++ b/server/src/com/cloud/api/commands/ListVMsCmd.java
@@ -118,6 +118,10 @@ public class ListVMsCmd extends BaseCmd {
domainId = account.getDomainId();
}
+ if(account!=null && domainId==null){
+ throw new ServerApiException(BaseCmd.ACCOUNT_ERROR, "Please specify the domain id for this account:"+account.getId());
+ }
+
Long[] accountIds = null;
if (accountId != null) {
accountIds = new Long[1];
From 5d0d69ce486dd89d201528256351ee99eeba8b5c Mon Sep 17 00:00:00 2001
From: abhishek
Date: Tue, 21 Sep 2010 16:02:40 -0700
Subject: [PATCH 10/16] bug 6264: changing the defaults for max volume size to
gb status 6264: resolved fixed
---
server/src/com/cloud/configuration/Config.java | 2 +-
server/src/com/cloud/server/ManagementServerImpl.java | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/server/src/com/cloud/configuration/Config.java b/server/src/com/cloud/configuration/Config.java
index 738921ac271..60f6ee24e15 100644
--- a/server/src/com/cloud/configuration/Config.java
+++ b/server/src/com/cloud/configuration/Config.java
@@ -47,7 +47,7 @@ public enum Config {
StorageOverprovisioningFactor("Storage", StoragePoolAllocator.class, String.class, "storage.overprovisioning.factor", "2", "Used for storage overprovisioning calculation; available storage will be (actualStorageSize * storage.overprovisioning.factor)", null),
StorageStatsInterval("Storage", ManagementServer.class, String.class, "storage.stats.interval", "60000", "The interval in milliseconds when storage stats (per host) are retrieved from agents.", null),
- MaxVolumeSize("Storage", ManagementServer.class, Integer.class, "max.volume.size.gb", "2093049000000", "The maximum size for a volume in bytes (2TB).", null),
+ MaxVolumeSize("Storage", ManagementServer.class, Integer.class, "max.volume.size.gb", "2000", "The maximum size for a volume in gigabytes.", null),
TotalRetries("Storage", AgentManager.class, Integer.class, "total.retries", "4", "The number of times each command sent to a host should be retried in case of failure.", null),
// Network
diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java
index 86856f1e5ce..43648b83946 100755
--- a/server/src/com/cloud/server/ManagementServerImpl.java
+++ b/server/src/com/cloud/server/ManagementServerImpl.java
@@ -478,9 +478,9 @@ public class ManagementServerImpl implements ManagementServer {
// and set them in the right places
String maxVolumeSizeInTbString = _configs.get("max.volume.size.gb");
- long maxVolumeSizeBytes = NumbersUtil.parseLong(maxVolumeSizeInTbString, new Long("2093049000000"));
+ long maxVolumeSizeGBytes = NumbersUtil.parseLong(maxVolumeSizeInTbString, new Long("2000"));
- _maxVolumeSizeInGb = maxVolumeSizeBytes/1000000000;
+ _maxVolumeSizeInGb = maxVolumeSizeGBytes;
_routerRamSize = NumbersUtil.parseInt(_configs.get("router.ram.size"),NetworkManager.DEFAULT_ROUTER_VM_RAMSIZE);
_proxyRamSize = NumbersUtil.parseInt(_configs.get("consoleproxy.ram.size"), ConsoleProxyManager.DEFAULT_PROXY_VM_RAMSIZE);
From 67cfa3582e52fbbece6e3f84f6bc1765c505088c Mon Sep 17 00:00:00 2001
From: Jessica Wang
Date: Tue, 21 Sep 2010 16:18:04 -0700
Subject: [PATCH 11/16] new UI - volume page - implement Recurring Snapshot
action.
---
ui/new/jsp/volume.jsp | 309 +++++++++++++++++++++
ui/new/scripts/cloud.core2.js | 12 +-
ui/new/scripts/cloud.core2.volume.js | 398 ++++++++++++++++++++++++++-
ui/scripts/cloud.core.storage.js | 4 +-
4 files changed, 714 insertions(+), 9 deletions(-)
diff --git a/ui/new/jsp/volume.jsp b/ui/new/jsp/volume.jsp
index 0b0cd193cda..b032a1e5641 100644
--- a/ui/new/jsp/volume.jsp
+++ b/ui/new/jsp/volume.jsp
@@ -224,3 +224,312 @@
Please confirm you want to create snapshot for this volume.
+
+
+
+
+
+
+
+
+ Hourly:
+
+
Please click 'Edit' to set your hourly recurring snapshot schedule
+
+
+ mm Minute(s) Past the Hour
+
+
+
+
+
+
+ Daily:
+
+
Please click 'Edit' to set your daily recurring snapshot schedule
+
+
+ hh : mm
+ AM
+
+
+
+
+
+
+ Weekly:
+
+
Please click 'Edit' to set your weekly recurring snapshot schedule
+
+
+ hh : mm
+ AM
+ day-of-week
+
+
+
+
+
+
+ Monthly:
+
+
Please click 'Edit' to set your monthly recurring snapshot schedule
+
+
+ hh : mm
+ AM
+ day-of-month
+
+
+
+
+
+
+
Cick Edit to Schedule
+
+
+
Edit:
+
Interval Type
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ui/new/scripts/cloud.core2.js b/ui/new/scripts/cloud.core2.js
index eb6c619bb16..6ccae33cbb8 100644
--- a/ui/new/scripts/cloud.core2.js
+++ b/ui/new/scripts/cloud.core2.js
@@ -33,7 +33,8 @@ function buildActionLinkForDetailsTab(label, actionMap, $actionMenu, listAPIMap)
$link.data("isAsyncJob", apiInfo.isAsyncJob);
$link.data("asyncJobResponse", apiInfo.asyncJobResponse);
$link.data("afterActionSeccessFn", apiInfo.afterActionSeccessFn);
- $link.data("dialogBeforeActionFn", apiInfo.dialogBeforeActionFn);
+ $link.data("dialogBeforeActionFn", apiInfo.dialogBeforeActionFn);
+ $link.data("customActionFn", apiInfo.customActionFn);
var $detailsTab = $("#right_panel_content #tab_content_details");
var id = $detailsTab.data("jsonObj").id;
@@ -41,6 +42,13 @@ function buildActionLinkForDetailsTab(label, actionMap, $actionMenu, listAPIMap)
$link.bind("click", function(event) {
$actionMenu.hide();
var $actionLink = $(this);
+
+ var customActionFn = $actionLink.data("customActionFn");
+ if(customActionFn != null) {
+ customActionFn();
+ return false;
+ }
+
var dialogBeforeActionFn = $actionLink.data("dialogBeforeActionFn");
if(dialogBeforeActionFn == null) {
var apiCommand = "command="+$actionLink.data("api")+"&id="+id;
@@ -48,7 +56,7 @@ function buildActionLinkForDetailsTab(label, actionMap, $actionMenu, listAPIMap)
}
else {
dialogBeforeActionFn($actionLink, listAPIMap, $detailsTab);
- }
+ }
return false;
});
}
diff --git a/ui/new/scripts/cloud.core2.volume.js b/ui/new/scripts/cloud.core2.volume.js
index bba2752634f..19f171d1f2c 100644
--- a/ui/new/scripts/cloud.core2.volume.js
+++ b/ui/new/scripts/cloud.core2.volume.js
@@ -10,9 +10,15 @@ function afterLoadVolumeJSP() {
modal: true,
zIndex: 2000
}));
-
+ activateDialog($("#dialog_recurring_snapshot").dialog({
+ width: 735,
+ autoOpen: false,
+ modal: true,
+ zIndex: 2000
+ }));
+
$.ajax({
- data: createURL("command=listOsTypes&response=json"),
+ data: createURL("command=listOsTypes"),
dataType: "json",
success: function(json) {
types = json.listostypesresponse.ostype;
@@ -23,7 +29,220 @@ function afterLoadVolumeJSP() {
}
}
}
- });
+ });
+
+ // *** recurring snapshot dialog - event binding (begin) ******************************
+ $("#dialog_recurring_snapshot").bind("click", function(event) {
+ event.preventDefault();
+ event.stopPropagation();
+
+ var target = event.target;
+ var targetId = target.id;
+ var thisDialog = $(this);
+ var volumeId = thisDialog.data("volumeId");
+ var topPanel = thisDialog.find("#dialog_snapshotleft");
+ var bottomPanel = thisDialog.find("#dialog_snapshotright");
+
+ if(targetId.indexOf("_edit_link")!=-1) {
+ clearBottomPanel();
+ bottomPanel.animate({
+ height: 200
+ }, 1000, function() {}
+ );
+ }
+ else if(targetId.indexOf("_delete_link")!=-1) {
+ clearBottomPanel();
+ var snapshotPolicyId = $("#"+targetId).data("snapshotPolicyId");
+ if(snapshotPolicyId == null || snapshotPolicyId.length==0)
+ return;
+ $.ajax({
+ data: createURL("command=deleteSnapshotPolicies&id="+snapshotPolicyId),
+ dataType: "json",
+ success: function(json) {
+ clearTopPanel($("#"+targetId).data("intervalType"));
+ },
+ error: function(XMLHttpResponse) {
+ handleError(XMLHttpResponse);
+ }
+ });
+ }
+
+ var thisLink;
+ switch(targetId) {
+ case "hourly_edit_link":
+ $("#edit_interval_type").text("Hourly");
+ $("#edit_time_colon, #edit_hour_container, #edit_meridiem_container, #edit_day_of_week_container, #edit_day_of_month_container").hide();
+ $("#edit_past_the_hour, #edit_minute_container").show();
+ thisLink = thisDialog.find("#hourly_edit_link");
+ thisDialog.find("#edit_minute").val(thisLink.data("minute"));
+ thisDialog.find("#edit_max").val(thisLink.data("max"));
+ thisDialog.find("#edit_timezone").val(thisLink.data("timezone"));
+ break;
+ case "daily_edit_link":
+ $("#edit_interval_type").text("Daily");
+ $("#edit_past_the_hour, #edit_day_of_week_container, #edit_day_of_month_container").hide();
+ $("#edit_minute_container, #edit_hour_container, #edit_meridiem_container").show();
+ thisLink = thisDialog.find("#daily_edit_link");
+ thisDialog.find("#edit_minute").val(thisLink.data("minute"));
+ thisDialog.find("#edit_hour").val(thisLink.data("hour12"));
+ thisDialog.find("#edit_meridiem").val(thisLink.data("meridiem"));
+ thisDialog.find("#edit_max").val(thisLink.data("max"));
+ thisDialog.find("#edit_timezone").val(thisLink.data("timezone"));
+ break;
+ case "weekly_edit_link":
+ $("#edit_interval_type").text("Weekly");
+ $("#edit_past_the_hour, #edit_day_of_month_container").hide();
+ $("#edit_minute_container, #edit_hour_container, #edit_meridiem_container, #edit_day_of_week_container").show();
+ thisLink = thisDialog.find("#weekly_edit_link");
+ thisDialog.find("#edit_minute").val(thisLink.data("minute"));
+ thisDialog.find("#edit_hour").val(thisLink.data("hour12"));
+ thisDialog.find("#edit_meridiem").val(thisLink.data("meridiem"));
+ thisDialog.find("#edit_day_of_week").val(thisLink.data("dayOfWeek"));
+ thisDialog.find("#edit_max").val(thisLink.data("max"));
+ thisDialog.find("#edit_timezone").val(thisLink.data("timezone"));
+ break;
+ case "monthly_edit_link":
+ $("#edit_interval_type").text("Monthly");
+ $("#edit_past_the_hour, #edit_day_of_week_container").hide();
+ $("#edit_minute_container, #edit_hour_container, #edit_meridiem_container, #edit_day_of_month_container").show();
+ thisLink = thisDialog.find("#monthly_edit_link");
+ thisDialog.find("#edit_minute").val(thisLink.data("minute"));
+ thisDialog.find("#edit_hour").val(thisLink.data("hour12"));
+ thisDialog.find("#edit_meridiem").val(thisLink.data("meridiem"));
+ thisDialog.find("#edit_day_of_month").val(thisLink.data("dayOfMonth"));
+ thisDialog.find("#edit_max").val(thisLink.data("max"));
+ thisDialog.find("#edit_timezone").val(thisLink.data("timezone"));
+ break;
+ case "apply_button":
+ var intervalType = bottomPanel.find("#edit_interval_type").text().toLowerCase();
+ var minute, hour12, hour24, meridiem, dayOfWeek, dayOfWeekString, dayOfMonth, schedule, max, timezone;
+ switch(intervalType) {
+ case "hourly":
+ var isValid = true;
+ isValid &= validateNumber("Keep # of snapshots", bottomPanel.find("#edit_max"), bottomPanel.find("#edit_max_errormsg"));
+ if (!isValid) return;
+
+ minute = bottomPanel.find("#edit_minute").val();
+ schedule = minute;
+ max = bottomPanel.find("#edit_max").val();
+ timezone = bottomPanel.find("#edit_timezone").val();
+ break;
+
+ case "daily":
+ var isValid = true;
+ isValid &= validateNumber("Keep # of snapshots", bottomPanel.find("#edit_max"), bottomPanel.find("#edit_max_errormsg"));
+ if (!isValid) return;
+
+ minute = bottomPanel.find("#edit_minute").val();
+ hour12 = bottomPanel.find("#edit_hour").val();
+ meridiem = bottomPanel.find("#edit_meridiem").val();
+ if(meridiem=="AM")
+ hour24 = hour12;
+ else //meridiem=="PM"
+ hour24 = (parseInt(hour12)+12).toString();
+ schedule = minute + ":" + hour24;
+ max = bottomPanel.find("#edit_max").val();
+ timezone = bottomPanel.find("#edit_timezone").val();
+ break;
+
+ case "weekly":
+ var isValid = true;
+ isValid &= validateNumber("Keep # of snapshots", bottomPanel.find("#edit_max"), bottomPanel.find("#edit_max_errormsg"));
+ if (!isValid) return;
+
+ minute = bottomPanel.find("#edit_minute").val();
+ hour12 = bottomPanel.find("#edit_hour").val();
+ meridiem = bottomPanel.find("#edit_meridiem").val();
+ if(meridiem=="AM")
+ hour24 = hour12;
+ else //meridiem=="PM"
+ hour24 = (parseInt(hour12)+12).toString();
+ dayOfWeek = bottomPanel.find("#edit_day_of_week").val();
+ dayOfWeekString = bottomPanel.find("#edit_day_of_week option:selected").text();
+ schedule = minute + ":" + hour24 + ":" + dayOfWeek;
+ max = bottomPanel.find("#edit_max").val();
+ timezone = bottomPanel.find("#edit_timezone").val();
+ break;
+
+ case "monthly":
+ var isValid = true;
+ isValid &= validateNumber("Keep # of snapshots", bottomPanel.find("#edit_max"), bottomPanel.find("#edit_max_errormsg"));
+ if (!isValid) return;
+
+ minute = bottomPanel.find("#edit_minute").val();
+ hour12 = bottomPanel.find("#edit_hour").val();
+ meridiem = bottomPanel.find("#edit_meridiem").val();
+ if(meridiem=="AM")
+ hour24 = hour12;
+ else //meridiem=="PM"
+ hour24 = (parseInt(hour12)+12).toString();
+ dayOfMonth = bottomPanel.find("#edit_day_of_month").val();
+ schedule = minute + ":" + hour24 + ":" + dayOfMonth;
+ max = bottomPanel.find("#edit_max").val();
+ timezone = bottomPanel.find("#edit_timezone").val();
+ break;
+ }
+
+ var thisLink;
+ $.ajax({
+ data: createURL("command=createSnapshotPolicy&intervaltype="+intervalType+"&schedule="+schedule+"&volumeid="+volumeId+"&maxsnaps="+max+"&timezone="+encodeURIComponent(timezone)),
+ dataType: "json",
+ success: function(json) {
+ switch(intervalType) {
+ case "hourly":
+ topPanel.find("#dialog_snapshot_hourly_info_unset").hide();
+ topPanel.find("#dialog_snapshot_hourly_info_set").show();
+ topPanel.find("#read_hourly_minute").text(minute);
+ topPanel.find("#read_hourly_timezone").text("("+timezones[timezone]+")");
+ topPanel.find("#read_hourly_max").text(max);
+ topPanel.find("#hourly_edit_link, #hourly_delete_link").data("intervalType", "hourly").data("snapshotPolicyId", json.createsnapshotpolicyresponse.id).data("max",max).data("timezone",timezone).data("minute", minute);
+ break;
+ case "daily":
+ topPanel.find("#dialog_snapshot_daily_info_unset").hide();
+ topPanel.find("#dialog_snapshot_daily_info_set").show();
+ topPanel.find("#read_daily_minute").text(minute);
+ topPanel.find("#read_daily_hour").text(hour12);
+ topPanel.find("#read_daily_meridiem").text(meridiem);
+ topPanel.find("#read_daily_timezone").text("("+timezones[timezone]+")");
+ topPanel.find("#read_daily_max").text(max);
+ topPanel.find("#daily_edit_link, #daily_delete_link").data("intervalType", "daily").data("snapshotPolicyId", json.createsnapshotpolicyresponse.id).data("max",max).data("timezone",timezone).data("minute", minute).data("hour12", hour12).data("meridiem", meridiem);
+ break;
+ case "weekly":
+ topPanel.find("#dialog_snapshot_weekly_info_unset").hide();
+ topPanel.find("#dialog_snapshot_weekly_info_set").show();
+ topPanel.find("#read_weekly_minute").text(minute);
+ topPanel.find("#read_weekly_hour").text(hour12);
+ topPanel.find("#read_weekly_meridiem").text(meridiem);
+ topPanel.find("#read_weekly_timezone").text("("+timezones[timezone]+")");
+ topPanel.find("#read_weekly_day_of_week").text(dayOfWeekString);
+ topPanel.find("#read_weekly_max").text(max);
+ topPanel.find("#weekly_edit_link, #weekly_delete_link").data("intervalType", "weekly").data("snapshotPolicyId", json.createsnapshotpolicyresponse.id).data("max",max).data("timezone",timezone).data("minute", minute).data("hour12", hour12).data("meridiem", meridiem).data("dayOfWeek",dayOfWeek);
+ break;
+ case "monthly":
+ topPanel.find("#dialog_snapshot_monthly_info_unset").hide();
+ topPanel.find("#dialog_snapshot_monthly_info_set").show();
+ topPanel.find("#read_monthly_minute").text(minute);
+ topPanel.find("#read_monthly_hour").text(hour12);
+ topPanel.find("#read_monthly_meridiem").text(meridiem);
+ topPanel.find("#read_monthly_timezone").text("("+timezones[timezone]+")");
+ topPanel.find("#read_monthly_day_of_month").text(toDayOfMonthDesp(dayOfMonth));
+ topPanel.find("#read_monthly_max").text(max);
+ topPanel.find("#monthly_edit_link, #monthly_delete_link").data("intervalType", "monthly").data("snapshotPolicyId", json.createsnapshotpolicyresponse.id).data("max",max).data("timezone",timezone).data("minute", minute).data("hour12", hour12).data("meridiem", meridiem).data("dayOfMonth",dayOfMonth);
+ break;
+ }
+
+ },
+ error: function(XMLHttpResponse) {
+ handleError(XMLHttpResponse);
+ }
+ });
+
+ break;
+
+ }
+ });
+ // *** recurring snapshot dialog - event binding (end) ******************************
+
}
function volumeAfterDetailsTabAction(jsonObj) {
@@ -73,7 +292,7 @@ function volumeJsonToDetailsTab(jsonObj){
$actionMenu.find("#action_list").empty();
buildActionLinkForDetailsTab("Take Snapshot", volumeActionMap, $actionMenu, volumeListAPIMap); //show take snapshot
- //buildActionLinkForDetailsTab("Recurring Snapshot", volumeActionMap, $actionMenu, volumeListAPIMap); //show Recurring Snapshot
+ buildActionLinkForDetailsTab("Recurring Snapshot", volumeActionMap, $actionMenu, volumeListAPIMap); //show Recurring Snapshot
if(jsonObj.state != "Creating" && jsonObj.state != "Corrupted" && jsonObj.name != "attaching") {
if(jsonObj.type=="ROOT") {
@@ -145,7 +364,10 @@ var volumeActionMap = {
dialogBeforeActionFn : doTakeSnapshot,
inProcessText: "Taking Snapshot....",
afterActionSeccessFn: function(){}
- }
+ },
+ "Recurring Snapshot": {
+ customActionFn : doRecurringSnapshot
+ }
}
var volumeListAPIMap = {
@@ -201,3 +423,169 @@ function doTakeSnapshot($actionLink, listAPIMap, $detailsTab) {
}
}).dialog("open");
}
+
+function clearTopPanel(target) { // "target == null" means target at all (hourly + daily + weekly + monthly)
+ var dialogBox = $("#dialog_recurring_snapshot");
+ if(target == "hourly" || target == null) {
+ dialogBox.find("#dialog_snapshot_hourly_info_unset").show();
+ dialogBox.find("#dialog_snapshot_hourly_info_set").hide();
+ dialogBox.find("#read_hourly_max, #read_hourly_minute").text("N/A");
+ dialogBox.find("#hourly_edit_link, #hourly_delete_link").data("intervalType", "hourly").data("max", "").data("timezone", (g_timezone==null)?"Etc/GMT+12":g_timezone).data("minute", "00");
+ }
+ if(target == "daily" || target == null) {
+ dialogBox.find("#dialog_snapshot_daily_info_unset").show();
+ dialogBox.find("#dialog_snapshot_daily_info_set").hide();
+ dialogBox.find("#read_daily_max, #read_daily_minute, #read_daily_hour, #read_daily_meridiem").text("N/A");
+ dialogBox.find("#daily_edit_link, #daily_delete_link").data("intervalType", "daily").data("max", "").data("timezone", (g_timezone==null)?"Etc/GMT+12":g_timezone).data("minute", "00").data("hour12", "00").data("meridiem", "AM");
+ }
+ if(target == "weekly" || target == null) {
+ dialogBox.find("#dialog_snapshot_weekly_info_unset").show();
+ dialogBox.find("#dialog_snapshot_weekly_info_set").hide();
+ dialogBox.find("#read_weekly_max, #read_weekly_minute, #read_weekly_hour, #read_weekly_meridiem, #read_weekly_day_of_week").text("N/A");
+ dialogBox.find("#weekly_edit_link, #weekly_delete_link").data("intervalType", "weekly").data("max", "").data("timezone", (g_timezone==null)?"Etc/GMT+12":g_timezone).data("minute", "00").data("hour12", "00").data("meridiem", "AM").data("dayOfWeek", "1");
+ }
+ if(target == "monthly" || target == null) {
+ dialogBox.find("#dialog_snapshot_monthly_info_unset").show();
+ dialogBox.find("#dialog_snapshot_monthly_info_set").hide();
+ dialogBox.find("#read_monthly_max, #read_monthly_minute, #read_monthly_hour, #read_monthly_meridiem, #read_monthly_day_of_month").text("N/A");
+ dialogBox.find("#monthly_edit_link, #monthly_delete_link").data("intervalType", "monthly").data("max", "").data("timezone", (g_timezone==null)?"Etc/GMT+12":g_timezone).data("minute", "00").data("hour12", "00").data("meridiem", "AM").data("dayOfMonth", "1");
+ }
+}
+
+function clearBottomPanel() {
+ var dialogBox = $("#dialog_recurring_snapshot");
+
+ dialogBox.find("#edit_hour").val("00");
+ cleanErrMsg(dialogBox.find("#edit_hour"), dialogBox.find("#edit_time_errormsg"));
+
+ dialogBox.find("#edit_minute").val("00");
+ cleanErrMsg(dialogBox.find("#edit_minute"), dialogBox.find("#edit_time_errormsg"));
+
+ dialogBox.find("#edit_meridiem").val("AM");
+
+ dialogBox.find("#edit_max").val("");
+ cleanErrMsg(dialogBox.find("#edit_max"), dialogBox.find("#edit_max_errormsg"));
+
+ dialogBox.find("#edit_timezone").val((g_timezone==null)?"Etc/GMT+12":g_timezone);
+ cleanErrMsg(dialogBox.find("#edit_timezone"), dialogBox.find("#edit_timezone_errormsg"));
+
+ dialogBox.find("#edit_day_of_week").val("1");
+ cleanErrMsg(dialogBox.find("#edit_day_of_week"), dialogBox.find("#edit_day_of_week_errormsg"));
+
+ dialogBox.find("#edit_day_of_month").val("1");
+ cleanErrMsg(dialogBox.find("#edit_day_of_month"), dialogBox.find("#edit_day_of_month_errormsg"));
+}
+
+function doRecurringSnapshot() {
+ var $detailsTab = $("#right_panel_content #tab_content_details");
+ var volumeId = $detailsTab.data("jsonObj").id;
+
+ var dialogBox = $("#dialog_recurring_snapshot");
+ clearTopPanel();
+
+ $.ajax({
+ data: createURL("command=listSnapshotPolicies&volumeid="+volumeId),
+ dataType: "json",
+ async: false,
+ success: function(json) {
+ var items = json.listsnapshotpoliciesresponse.snapshotpolicy;
+ if(items!=null && items.length>0) {
+ for(var i=0; i
Date: Tue, 21 Sep 2010 16:57:41 -0700
Subject: [PATCH 12/16] new UI - volumes page - implement add volume action.
---
ui/new/jsp/volume.jsp | 37 ++++++++-
ui/new/scripts/cloud.core2.js | 16 +++-
ui/new/scripts/cloud.core2.template.js | 4 +-
ui/new/scripts/cloud.core2.volume.js | 104 ++++++++++++++++++++++++-
4 files changed, 155 insertions(+), 6 deletions(-)
diff --git a/ui/new/jsp/volume.jsp b/ui/new/jsp/volume.jsp
index b032a1e5641..a4cd0fb3263 100644
--- a/ui/new/jsp/volume.jsp
+++ b/ui/new/jsp/volume.jsp
@@ -532,4 +532,39 @@
-
\ No newline at end of file
+
+
+
+
+
+ Please fill in the following data to add a new volume.
+
+
+
+
diff --git a/ui/new/scripts/cloud.core2.js b/ui/new/scripts/cloud.core2.js
index 6ccae33cbb8..39cf579db7a 100644
--- a/ui/new/scripts/cloud.core2.js
+++ b/ui/new/scripts/cloud.core2.js
@@ -349,8 +349,20 @@ function handleErrorInMidMenu(XMLHttpResponse, $midmenuItem1) {
if(errorMsg.length > 0)
$midmenuItem1.find("#second_row").text(fromdb(errorMsg));
else
- $midmenuItem1.find("#second_row").text("");
-}
+ $midmenuItem1.find("#second_row").html(" ");
+}
+
+function handleAsyncJobFailInMidMenu(errorMsg, $midmenuItem1) {
+ $midmenuItem1.find("#content").removeClass("inaction");
+ $midmenuItem1.find("#spinning_wheel").hide();
+ $midmenuItem1.find("#info_icon").addClass("error").show();
+ $midmenuItem1.find("#first_row").text("Adding failed");
+
+ if(errorMsg.length > 0)
+ $midmenuItem1.find("#second_row").text(fromdb(errorMsg));
+ else
+ $midmenuItem1.find("#second_row").html(" ");
+}
//***** actions for middle menu (end) **************************************************************************
diff --git a/ui/new/scripts/cloud.core2.template.js b/ui/new/scripts/cloud.core2.template.js
index 0bce422868f..a9f14436729 100644
--- a/ui/new/scripts/cloud.core2.template.js
+++ b/ui/new/scripts/cloud.core2.template.js
@@ -16,8 +16,8 @@ function afterLoadTemplateJSP() {
else
$("#dialog_add_template #add_template_featured_container, #dialog_edit_template #edit_template_featured_container").hide();
- $("#midmenu_add_link").show();
-
+ //add button ***
+ $("#midmenu_add_link").show();
$("#midmenu_add_link").unbind("click").bind("click", function(event) {
$("#dialog_add_template")
.dialog('option', 'buttons', {
diff --git a/ui/new/scripts/cloud.core2.volume.js b/ui/new/scripts/cloud.core2.volume.js
index 19f171d1f2c..38e3631b28e 100644
--- a/ui/new/scripts/cloud.core2.volume.js
+++ b/ui/new/scripts/cloud.core2.volume.js
@@ -16,7 +16,12 @@ function afterLoadVolumeJSP() {
modal: true,
zIndex: 2000
}));
-
+ activateDialog($("#dialog_add_volume").dialog({
+ autoOpen: false,
+ modal: true,
+ zIndex: 2000
+ }));
+
$.ajax({
data: createURL("command=listOsTypes"),
dataType: "json",
@@ -30,6 +35,103 @@ function afterLoadVolumeJSP() {
}
}
});
+
+ $.ajax({
+ data: createURL("command=listZones&available=true"+maxPageSize),
+ dataType: "json",
+ success: function(json) {
+ var zones = json.listzonesresponse.zone;
+ var volumeZoneSelect = $("#dialog_add_volume").find("#volume_zone").empty();
+ if (zones != null && zones.length > 0) {
+ for (var i = 0; i < zones.length; i++) {
+ volumeZoneSelect.append("" + sanitizeXSS(zones[i].name) + " ");
+ }
+ }
+ }
+ });
+
+ $.ajax({
+ data: createURL("command=listDiskOfferings"),
+ dataType: "json",
+ success: function(json) {
+ var offerings = json.listdiskofferingsresponse.diskoffering;
+ var volumeDiskOfferingSelect = $("#dialog_add_volume").find("#volume_diskoffering").empty();
+ if (offerings != null && offerings.length > 0) {
+ if (offerings != null && offerings.length > 0) {
+ for (var i = 0; i < offerings.length; i++)
+ volumeDiskOfferingSelect.append("" + sanitizeXSS(offerings[i].displaytext) + " ");
+ }
+ }
+ }
+ });
+
+ //add button ***
+ $("#midmenu_add_link").show();
+ $("#midmenu_add_link").unbind("click").bind("click", function(event) {
+ $("#dialog_add_volume")
+ .dialog('option', 'buttons', {
+ "Add": function() {
+ var thisDialog = $(this);
+
+ // validate values
+ var isValid = true;
+ isValid &= validateString("Name", thisDialog.find("#add_volume_name"), thisDialog.find("#add_volume_name_errormsg"));
+ if (!isValid) return;
+
+ thisDialog.dialog("close");
+
+ var name = trim(thisDialog.find("#add_volume_name").val());
+ var zoneId = thisDialog.find("#volume_zone").val();
+ var diskofferingId = thisDialog.find("#volume_diskoffering").val();
+
+ var $midmenuItem1 = beforeAddingMidMenuItem() ;
+
+ $.ajax({
+ data: createURL("command=createVolume&zoneId="+zoneId+"&name="+encodeURIComponent(name)+"&diskOfferingId="+diskofferingId+"&accountId="+"1"),
+ dataType: "json",
+ success: function(json) {
+ var jobId = json.createvolumeresponse.jobid;
+ var timerKey = "createVolumeJob_"+jobId;
+
+ $("body").everyTime(2000, timerKey, function() {
+ $.ajax({
+ data: createURL("command=queryAsyncJobResult&jobId="+json.createvolumeresponse.jobid),
+ dataType: "json",
+ success: function(json) {
+ var result = json.queryasyncjobresultresponse;
+ if (result.jobstatus == 0) {
+ return; //Job has not completed
+ } else {
+ $("body").stopTime(timerKey);
+ if (result.jobstatus == 1) {
+ // Succeeded
+ volumeToMidmenu(result.volume[0], $midmenuItem1);
+ bindClickToMidMenu($midmenuItem1, volumeToRigntPanel);
+ afterAddingMidMenuItem($midmenuItem1, true);
+ } else if (result.jobstatus == 2) {
+ handleAsyncJobFailInMidMenu(result.jobresult, $midmenuItem1);
+ }
+ }
+ },
+ error: function(XMLHttpResponse) {
+ $("body").stopTime(timerKey);
+ handleErrorInMidMenu(XMLHttpResponse, $midmenuItem1);
+ }
+ });
+ }, 0);
+ },
+ error: function(XMLHttpResponse) {
+ handleErrorInMidMenu(XMLHttpResponse, $midmenuItem1);
+ }
+ });
+ },
+ "Cancel": function() {
+ $(this).dialog("close");
+ }
+ }).dialog("open");
+
+ return false;
+ });
// *** recurring snapshot dialog - event binding (begin) ******************************
$("#dialog_recurring_snapshot").bind("click", function(event) {
From 272d419d3a45667e10e124c9e29947ec3d595326 Mon Sep 17 00:00:00 2001
From: NIKITA
Date: Tue, 21 Sep 2010 17:40:50 -0700
Subject: [PATCH 13/16] Width of action dropdown has been increased
---
ui/new/css/main.css | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/ui/new/css/main.css b/ui/new/css/main.css
index 2e7d0eede73..03f66313d22 100644
--- a/ui/new/css/main.css
+++ b/ui/new/css/main.css
@@ -1701,7 +1701,7 @@ a:hover.search_button {
}
.actionsdropdown_boxlist {
- width:96px;
+ width:197px;
height:auto;
float:left;
margin:0 0 5px 6px;
@@ -1710,7 +1710,7 @@ a:hover.search_button {
}
.actionsdropdown_boxlist li{
- width:94px;
+ width:194px;
height:auto;
float:left;
text-align:left;
@@ -2622,7 +2622,7 @@ a:hover.search_button {
}
.grid_actionsdropdown_box {
- width:109px;
+ width:209px;
height:auto;
float:left;
position:absolute;
From 4e9b1239ce44a1399fd27a2c45eec7cf811b8c5d Mon Sep 17 00:00:00 2001
From: Jessica Wang
Date: Tue, 21 Sep 2010 17:38:41 -0700
Subject: [PATCH 14/16] cross-site scripting - sanitize only value whose type
is string.
---
ui/new/scripts/cloud.core2.js | 2 +-
ui/scripts/cloud.core.js | 2 +-
ui/test/scripts/cloud.core.test.js | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/ui/new/scripts/cloud.core2.js b/ui/new/scripts/cloud.core2.js
index 39cf579db7a..0508c5f8a88 100644
--- a/ui/new/scripts/cloud.core2.js
+++ b/ui/new/scripts/cloud.core2.js
@@ -1250,7 +1250,7 @@ function noNull(val) {
// Prevent cross-site-script(XSS) attack.
// used right before adding user input to the DOM tree. e.g. DOM_element.html(sanitizeXSS(user_input));
function sanitizeXSS(val) {
- if(val == null)
+ if(val == null || typeof(val) != "string")
return val;
val = val.replace(//g, ">"); //replace > whose unicode is \u003e
diff --git a/ui/scripts/cloud.core.js b/ui/scripts/cloud.core.js
index 9c527906e4e..fca118859e2 100644
--- a/ui/scripts/cloud.core.js
+++ b/ui/scripts/cloud.core.js
@@ -626,7 +626,7 @@ function noNull(val) {
// Prevent cross-site-script(XSS) attack.
// used right before adding user input to the DOM tree. e.g. DOM_element.html(sanitizeXSS(user_input));
function sanitizeXSS(val) {
- if(val == null)
+ if(val == null || typeof(val) != "string")
return val;
val = val.replace(//g, ">"); //replace > whose unicode is \u003e
diff --git a/ui/test/scripts/cloud.core.test.js b/ui/test/scripts/cloud.core.test.js
index 0aacfd85a66..364c33add56 100644
--- a/ui/test/scripts/cloud.core.test.js
+++ b/ui/test/scripts/cloud.core.test.js
@@ -102,7 +102,7 @@ function trim(val) {
// Prevent cross-site-script(XSS) attack.
// used right before adding user input to the DOM tree. e.g. DOM_element.html(sanitizeXSS(user_input));
function sanitizeXSS(val) {
- if(val == null)
+ if(val == null || typeof(val) != "string")
return val;
val = val.replace(//g, ">"); //replace > whose unicode is \u003e
From 039cb78173c678e0ea131b70fa636eb8ebe581c4 Mon Sep 17 00:00:00 2001
From: Jessica Wang
Date: Tue, 21 Sep 2010 17:55:40 -0700
Subject: [PATCH 15/16] fix bug 6127 - change text on confirmation box on VM
destroy.
---
ui/scripts/cloud.core.instances.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ui/scripts/cloud.core.instances.js b/ui/scripts/cloud.core.instances.js
index dc31000c00a..bb7062dec70 100644
--- a/ui/scripts/cloud.core.instances.js
+++ b/ui/scripts/cloud.core.instances.js
@@ -402,7 +402,7 @@ function showInstancesTab(p_domainId, p_account) {
break;
case "vm_action_destroy" :
$("#dialog_confirmation")
- .html("Please confirm you want to destroy your virtual machine: "+vmName+" . Destroying your virtual machine would include deleting the ROOT volume and all attached data disk volumes.
")
+ .html("Please confirm you want to destroy your virtual machine: "+vmName+" . Destroying your virtual machine will also delete the ROOT volume, but not attached data disk volumes.
")
.dialog('option', 'buttons', {
"Confirm": function() {
$(this).dialog("close");
From 23bb32dcde885757f26e0c582d060fc1e3d48d28 Mon Sep 17 00:00:00 2001
From: Jessica Wang
Date: Tue, 21 Sep 2010 18:11:10 -0700
Subject: [PATCH 16/16] fix bug 6130 - when attaching volume, running and
stopped VMs not displayed consistently.
---
ui/scripts/cloud.core.storage.js | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/ui/scripts/cloud.core.storage.js b/ui/scripts/cloud.core.storage.js
index 9a0cdecc341..2f8bcf6557f 100644
--- a/ui/scripts/cloud.core.storage.js
+++ b/ui/scripts/cloud.core.storage.js
@@ -75,7 +75,7 @@ function showStorageTab(domainId, targetTab) {
var volumeVmSelect = $("#dialog_attach_volume").find("#volume_vm").empty();
if (instances != null && instances.length > 0) {
for (var i = 0; i < instances.length; i++) {
- volumeVmSelect.append("" + getVmName(instances[i].name, instances[i].displayname)+ " ");
+ volumeVmSelect.append("" + getVmName(instances[i].name, instances[i].displayname) + " ");
}
}
$.ajax({
@@ -86,7 +86,7 @@ function showStorageTab(domainId, targetTab) {
var instances = json.listvirtualmachinesresponse.virtualmachine;
if (instances != null && instances.length > 0) {
for (var i = 0; i < instances.length; i++) {
- volumeVmSelect.append("" + sanitizeXSS(instances[i].name) + " ");
+ volumeVmSelect.append("" + getVmName(instances[i].name, instances[i].displayname) + " ");
}
}
}