You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by mi...@apache.org on 2012/08/30 09:20:37 UTC
[2/2] Initial commit of vm snapshots feature for xenserver and vmware
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/33f690f1/setup/db/create-schema.sql
----------------------------------------------------------------------
diff --git a/setup/db/create-schema.sql b/setup/db/create-schema.sql
index fa933e3..eded40d 100755
--- a/setup/db/create-schema.sql
+++ b/setup/db/create-schema.sql
@@ -2363,5 +2363,51 @@ CREATE TABLE `cloud`.`nicira_nvp_nic_map` (
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+CREATE TABLE `cloud`.`vm_snapshots` (
+ `id` bigint(20) unsigned NOT NULL auto_increment COMMENT 'Primary Key',
+ `uuid` varchar(40) NOT NULL,
+ `snapshot_uuid` varchar(40) default NULL,
+ `name` varchar(255) NOT NULL,
+ `display_name` varchar(255) default NULL,
+ `description` varchar(255) default NULL,
+ `vm_id` bigint(20) unsigned NOT NULL,
+ `account_id` bigint(20) unsigned NOT NULL,
+ `service_offering_id` bigint(20) unsigned NOT NULL,
+ `domain_id` bigint(20) unsigned NOT NULL,
+ `memory` int(1) unsigned NOT NULL,
+ `state` varchar(32) NOT NULL,
+ `created` datetime default NULL,
+ `removed` datetime default NULL,
+ PRIMARY KEY (`id`),
+ CONSTRAINT UNIQUE KEY `uc_vm_snapshots_uuid` (`uuid`),
+ INDEX `vm_snapshots_name` (`name`),
+ INDEX `vm_snapshots_vm_id` (`vm_id`),
+ INDEX `vm_snapshots_account_id` (`account_id`),
+ INDEX `vm_snapshots_display_name` (`display_name`),
+ INDEX `vm_snapshots_removed` (`removed`),
+ CONSTRAINT `fk_vm_snapshots_vm_id__vm_instance_id` FOREIGN KEY `fk_vm_snapshots_vm_id__vm_instance_id` (`vm_id`) REFERENCES `vm_instance` (`id`),
+ CONSTRAINT `fk_vm_snapshots_account_id__account_id` FOREIGN KEY `fk_vm_snapshots_account_id__account_id` (`account_id`) REFERENCES `account` (`id`),
+ CONSTRAINT `fk_vm_snapshots_service_offering_id__service_offering_id` FOREIGN KEY `fk_vm_snapshots_service_offering_id__service_offering_id` (`service_offering_id`) REFERENCES `service_offering` (`id`),
+ CONSTRAINT `fk_vm_snapshots_domain_id__domain_id` FOREIGN KEY `fk_vm_snapshots_domain_id__domain_id` (`domain_id`) REFERENCES `domain` (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+CREATE TABLE `cloud`.`vm_snapshot_volume` (
+ `id` bigint(20) unsigned NOT NULL auto_increment COMMENT 'Primary Key',
+ `uuid` varchar(40) NOT NULL,
+ `volume_path` varchar(255) default NULL,
+ `vm_snapshot_id` bigint(20) unsigned NOT NULL,
+ `snapshot_of` bigint(20) unsigned NOT NULL,
+ `volume_type` varchar(10) NOT NULL,
+ `created` datetime default NULL,
+ `removed` datetime default NULL,
+ PRIMARY KEY (`id`),
+ CONSTRAINT UNIQUE KEY `uc_vm_snapshot_volume_uuid` (`uuid`),
+ INDEX `i_vm_snapshot_volume__removed` (`removed`),
+ INDEX `i_vm_snapshot_volume__snapshot_of` (`snapshot_of`),
+ INDEX `i_vm_snapshot_volume__volume_type` (`volume_type`),
+ CONSTRAINT `fk_vm_snapshot_volume_id__vm_snapshots_id` FOREIGN KEY `fk_vm_snapshot_volume_id__vm_snapshots_id` (`vm_snapshot_id`) REFERENCES `vm_snapshots` (`id`),
+ CONSTRAINT `fk_vm_snapshot_snapshot_of__volumes_id` FOREIGN KEY `fk_vm_snapshot_snapshot_of__volumes_id` (`snapshot_of`) REFERENCES `volumes` (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
SET foreign_key_checks = 1;
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/33f690f1/ui/index.jsp
----------------------------------------------------------------------
diff --git a/ui/index.jsp b/ui/index.jsp
index 7a5489c..203c426 100644
--- a/ui/index.jsp
+++ b/ui/index.jsp
@@ -1637,6 +1637,7 @@ under the License.
<script type="text/javascript" src="scripts/ui-custom/zoneWizard.js?t=<%=now%>"></script>
<script type="text/javascript" src="scripts/system.js?t=<%=now%>"></script>
<script type="text/javascript" src="scripts/domains.js?t=<%=now%>"></script>
+ <script type="text/javascript" src="scripts/vm_snapshots.js?t=<%=now%>"></script>
</body>
</html>
<jsp:include page="dictionary.jsp" />
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/33f690f1/ui/scripts/instances.js
----------------------------------------------------------------------
diff --git a/ui/scripts/instances.js b/ui/scripts/instances.js
index 345f456..0f0d0f4 100644
--- a/ui/scripts/instances.js
+++ b/ui/scripts/instances.js
@@ -205,6 +205,7 @@
poll: pollAsyncJobResult
}
},
+
destroy: {
label: 'label.action.destroy.instance',
messages: {
@@ -317,7 +318,7 @@
detailView: {
name: 'Instance details',
- viewAll: { path: 'storage.volumes', label: 'label.volumes' },
+ viewAll: [{ path: 'storage.volumes', label: 'label.volumes' }, { path: 'vmsnapshots', label: 'VM Snapshots' } ],
tabFilter: function(args) {
var hiddenTabs = [];
var zoneNetworktype;
@@ -485,6 +486,71 @@
poll: pollAsyncJobResult
}
},
+
+ snapshot: {
+ messages: {
+ notification: function(args) {
+ return 'label.action.take.snapshot';
+ }
+ },
+ label: 'label.action.take.snapshot',
+ addRow: 'false',
+ createForm: {
+ title: 'label.action.take.snapshot',
+ fields: {
+ name: {
+ label: 'label.name',
+ isInput: true
+ },
+ description: {
+ label: 'label.description',
+ isTextarea: true
+ },
+ snapshotMemory: {
+ label: 'snapshot.memory',
+ isBoolean: true,
+ isChecked: false
+ }
+ }
+ },
+ action: function(args) {
+ //hongtu
+ var array1 = [];
+ array1.push("&snapshotmemory=" + (args.data.snapshotMemory == "on"));
+ var displayname = args.data.name;
+ if (displayname != null && displayname.length > 0) {
+ array1.push("&name=" + todb(displayname));
+ }
+ var description = args.data.description;
+ if (description != null && description.length > 0) {
+ array1.push("&description=" + todb(description));
+ }
+ $.ajax({
+ url: createURL("createVMSnapshot&vmId=" + args.context.instances[0].id + array1.join("")),
+ dataType: "json",
+ async: true,
+ success: function(json) {
+ var jid = json.createvmsnapshotresponse.jobid;
+ args.response.success({
+ _custom: {
+ jobId: jid,
+ getUpdatedItem: function(json) {
+ return json.queryasyncjobresultresponse.jobresult.virtualmachine;
+ },
+ getActionFilter: function() {
+ return vmActionfilter;
+ }
+ }
+ });
+ }
+ });
+
+ },
+ notification: {
+ pool: pollAsyncJobResult
+ }
+ },
+
destroy: {
label: 'label.action.destroy.instance',
messages: {
@@ -1281,6 +1347,7 @@
else if (jsonObj.state == 'Running') {
allowedActions.push("stop");
allowedActions.push("restart");
+ allowedActions.push("snapshot");
allowedActions.push("destroy");
allowedActions.push("changeService");
@@ -1304,7 +1371,7 @@
allowedActions.push("edit");
allowedActions.push("start");
allowedActions.push("destroy");
-
+ allowedActions.push("snapshot");
if(isAdmin())
allowedActions.push("migrateToAnotherStorage");
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/33f690f1/ui/scripts/ui/widgets/detailView.js
----------------------------------------------------------------------
diff --git a/ui/scripts/ui/widgets/detailView.js b/ui/scripts/ui/widgets/detailView.js
index fc2ae45..00d3188 100644
--- a/ui/scripts/ui/widgets/detailView.js
+++ b/ui/scripts/ui/widgets/detailView.js
@@ -850,14 +850,20 @@
$actions.prependTo($firstRow.closest('div.detail-group').closest('.details'));
}
if (detailViewArgs.viewAll && showViewAll) {
+
+ if( !(detailViewArgs.viewAll instanceof Array)){
+ detailViewArgs.viewAll = [detailViewArgs.viewAll];
+ }
+ $.each(detailViewArgs.viewAll, function(n, view){
$('<div>')
.addClass('view-all')
.append(
$('<a>')
.attr({ href: '#' })
- .data('detail-view-link-view-all', detailViewArgs.viewAll)
+ .css('padding','0 1px')
+ .data('detail-view-link-view-all', view)
.append(
- $('<span>').html(_l('label.view') + ' ' + _l(detailViewArgs.viewAll.label))
+ $('<span>').html(_l('label.view') + ' ' + _l(view.label))
)
)
.append(
@@ -866,9 +872,10 @@
.appendTo(
$('<td>')
.addClass('view-all')
+ .css('padding','9px 3px 8px 0')
.appendTo($actions.find('tr'))
);
-
+ });
}
}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/33f690f1/vmware-base/src/com/cloud/hypervisor/vmware/mo/HostMO.java
----------------------------------------------------------------------
diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/HostMO.java b/vmware-base/src/com/cloud/hypervisor/vmware/mo/HostMO.java
index 3557048..2946620 100755
--- a/vmware-base/src/com/cloud/hypervisor/vmware/mo/HostMO.java
+++ b/vmware-base/src/com/cloud/hypervisor/vmware/mo/HostMO.java
@@ -58,6 +58,8 @@ import com.vmware.vim25.PropertySpec;
import com.vmware.vim25.SelectionSpec;
import com.vmware.vim25.TraversalSpec;
import com.vmware.vim25.VirtualMachineConfigSpec;
+import com.vmware.vim25.VirtualMachineSnapshotInfo;
+import com.vmware.vim25.VirtualMachineSnapshotTree;
import com.vmware.vim25.VirtualNicManagerNetConfig;
import com.vmware.vim25.NasDatastoreInfo;
@@ -952,4 +954,20 @@ public class HostMO extends BaseMO implements VmwareHypervisorHost {
HostRuntimeInfo runtimeInfo = (HostRuntimeInfo)_context.getServiceUtil().getDynamicProperty(_mor, "runtime");
return runtimeInfo.getConnectionState() == HostSystemConnectionState.connected;
}
+
+ public boolean revertToSnapshot(ManagedObjectReference morSnapshot)
+ throws Exception {
+ ManagedObjectReference morTask = _context.getService()
+ .revertToSnapshot_Task(morSnapshot, _mor, false);
+ String result = _context.getServiceUtil().waitForTask(morTask);
+ if (result.equals("sucess")) {
+ _context.waitForTaskProgressDone(morTask);
+ return true;
+ } else {
+ s_logger.error("VMware revert to snapshot failed due to "
+ + TaskMO.getTaskFailureInfo(_context, morTask));
+ }
+
+ return false;
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/33f690f1/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java
----------------------------------------------------------------------
diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java b/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java
index cd54127..d36814d 100644
--- a/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java
+++ b/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java
@@ -405,6 +405,26 @@ public class VirtualMachineMO extends BaseMO {
return false;
}
+ public boolean revertToSnapshot(String snapshotName) throws Exception {
+ ManagedObjectReference morSnapshot = getSnapshotMor(snapshotName);
+ if (morSnapshot == null) {
+ s_logger.warn("Unable to find snapshot: " + snapshotName);
+ return false;
+ }
+ ManagedObjectReference morTask = _context.getService()
+ .revertToSnapshot_Task(morSnapshot, _mor, null);
+ String result = _context.getServiceUtil().waitForTask(morTask);
+ if (result.equals("sucess")) {
+ _context.waitForTaskProgressDone(morTask);
+ return true;
+ } else {
+ s_logger.error("VMware revert to snapshot failed due to "
+ + TaskMO.getTaskFailureInfo(_context, morTask));
+ }
+
+ return false;
+ }
+
public boolean removeAllSnapshots() throws Exception {
VirtualMachineSnapshotInfo snapshotInfo = getSnapshotInfo();