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();