diff --git a/ui/css/cloudstack3.css b/ui/css/cloudstack3.css
index b3b7490825f..a85dee1d909 100644
--- a/ui/css/cloudstack3.css
+++ b/ui/css/cloudstack3.css
@@ -12343,12 +12343,14 @@ div.ui-dialog div.autoscaler div.field-group div.form-container form div.form-it
}
.snapshot .icon,
-.takeSnapshot .icon {
+.takeSnapshot .icon,
+.storageSnapshot .icon {
background-position: -36px -91px;
}
.snapshot:hover .icon,
-.takeSnapshot:hover .icon {
+.takeSnapshot:hover .icon,
+.storageSnapshot:hover .icon {
background-position: -36px -673px;
}
diff --git a/ui/css/src/scss/components/action-icons.scss b/ui/css/src/scss/components/action-icons.scss
index c35645d3a0d..686b6e395bd 100644
--- a/ui/css/src/scss/components/action-icons.scss
+++ b/ui/css/src/scss/components/action-icons.scss
@@ -173,12 +173,14 @@
}
.snapshot .icon,
-.takeSnapshot .icon {
+.takeSnapshot .icon,
+.storageSnapshot .icon {
background-position: -36px -91px;
}
.snapshot:hover .icon,
-.takeSnapshot:hover .icon {
+.takeSnapshot:hover .icon,
+.storageSnapshot:hover .icon {
background-position: -36px -673px;
}
diff --git a/ui/l10n/de_DE.js b/ui/l10n/de_DE.js
index cae753e7e40..13e96b58a6f 100644
--- a/ui/l10n/de_DE.js
+++ b/ui/l10n/de_DE.js
@@ -297,6 +297,7 @@ var dictionary = {
"label.action.vmsnapshot.create": "VM-Schnappschuss machen",
"label.action.vmsnapshot.delete": "VM-Schnappschuss löschen",
"label.action.vmsnapshot.revert": "Auf VM-Schnappschuss zurückkehren",
+ "label.action.vmstoragesnapshot.create":"VM Speicher-Schnappschuss machen",
"label.actions": "Aktionen",
"label.activate.project": "Projekt aktivieren",
"label.active.sessions": "Aktive Sitzungen",
@@ -1891,6 +1892,7 @@ var dictionary = {
"message.action.vmsnapshot.create": "Please confirm that you want to take a snapshot of this instance.
Please notice that the instance will be paused during the snapshoting, and resumed after snapshotting, if it runs on KVM.",
"message.action.vmsnapshot.delete": "Bitte bestätigen Sie, dass Sie diesen VM Schnappschuss löschen wollen.",
"message.action.vmsnapshot.revert": "VM-Schnappschuss zurücksetzen",
+ "message.action.vmstoragesnapshot.create":"Bitte wählen Sie einen Speicher aus, für den ein Schnappschuss erstellt werden soll.",
"message.activate.project": "Sind Sie sicher, dass Sie dieses Projekt aktivieren wollen?",
"message.add.VPN.gateway": "Bitte bestätigen Sie, dass sie ein VPN Gateway hinzufügen wollen.",
"message.add.cluster": "Hinzufügen eines vom Hypervisor verwaltender Clusters für Zone , Pod ",
diff --git a/ui/l10n/en.js b/ui/l10n/en.js
index db269250860..aca4d998fbc 100644
--- a/ui/l10n/en.js
+++ b/ui/l10n/en.js
@@ -301,6 +301,7 @@ var dictionary = {
"label.action.vmsnapshot.create":"Take VM Snapshot",
"label.action.vmsnapshot.delete":"Delete VM snapshot",
"label.action.vmsnapshot.revert":"Revert to VM snapshot",
+"label.action.vmstoragesnapshot.create":"Take VM volume snapshot",
"label.actions":"Actions",
"label.activate.project":"Activate Project",
"label.active.sessions":"Active Sessions",
@@ -533,7 +534,7 @@ var dictionary = {
"label.cidr":"CIDR",
"label.cidr.account":"CIDR or Account/Security Group",
"label.cidr.list":"Source CIDR",
- "label.cidr.destination.list":"Destination CIDR",
+"label.cidr.destination.list":"Destination CIDR",
"label.cisco.nexus1000v.ip.address":"Nexus 1000v IP Address",
"label.cisco.nexus1000v.password":"Nexus 1000v Password",
"label.cisco.nexus1000v.username":"Nexus 1000v Username",
@@ -1960,6 +1961,7 @@ var dictionary = {
"message.action.vmsnapshot.create":"Please confirm that you want to take a snapshot of this instance.
Please notice that the instance will be paused during the snapshoting, and resumed after snapshotting, if it runs on KVM.",
"message.action.vmsnapshot.delete":"Please confirm that you want to delete this VM snapshot.
Please notice that the instance will be paused before the snapshot deletion, and resumed after deletion, if it runs on KVM.",
"message.action.vmsnapshot.revert":"Revert VM snapshot",
+"message.action.vmstoragesnapshot.create":"Please choose a volume that you want to take a snapshot of.",
"message.activate.project":"Are you sure you want to activate this project?",
"message.add.VPN.gateway":"Please confirm that you want to add a VPN Gateway",
"message.add.cluster":"Add a hypervisor managed cluster for zone , pod ",
diff --git a/ui/scripts/docs.js b/ui/scripts/docs.js
index aef5e77efbc..b032d4eaf3e 100755
--- a/ui/scripts/docs.js
+++ b/ui/scripts/docs.js
@@ -310,6 +310,13 @@ cloudStack.docs = {
helpCreateInstanceSnapshotMemory: {
desc: 'Check this to include CPU/memory state. Does not quiesce the VM. If not checked, the snapshot contain only volumes.'
},
+ // Create instance storage snapshot
+ helpCreateInstanceStorageSnapshotVolume: {
+ desc: 'Choose a volume that you want to take a snapshot of'
+ },
+ helpCreateInstanceStorageSnapshotName: {
+ desc: 'Give the snapshot a name. A unique name will be automatically generated if you leave this blank'
+ },
// Add disk offering
helpDiskOfferingName: {
desc: 'Any desired name for the offering',
diff --git a/ui/scripts/instances.js b/ui/scripts/instances.js
index c0693f7ef98..4cc1dbb18be 100644
--- a/ui/scripts/instances.js
+++ b/ui/scripts/instances.js
@@ -1054,6 +1054,111 @@
}
},
snapshot: vmSnapshotAction(),
+ storageSnapshot: {
+ messages: {
+ notification: function() {
+ return 'label.action.take.snapshot';
+ }
+ },
+ label: 'label.action.vmstoragesnapshot.create',
+ createForm: {
+ title: 'label.action.vmstoragesnapshot.create',
+ desc: 'message.action.vmstoragesnapshot.create',
+ fields: {
+ volume: {
+ label: 'label.volume',
+ docID: 'helpCreateInstanceStorageSnapshotVolume',
+ select: function(args) {
+ var items = [];
+ var data = {
+ virtualMachineId: args.context.instances[0].id
+ };
+
+ $.ajax({
+ url: createURL('listVolumes'),
+ data: data,
+ dataType: 'json',
+ async: false,
+ success: function(json) {
+ var volumes = json.listvolumesresponse.volume;
+ args.context['volumes'] = volumes;
+ $(volumes).each(function(index, volume) {
+ items.push({
+ id: volume.id,
+ description: volume.name
+ });
+ });
+
+ args.response.success({
+ data: items
+ });
+ }
+ });
+ }
+ },
+ quiescevm: {
+ label: 'label.quiesce.vm',
+ isBoolean: true,
+ dependsOn: 'volume',
+ isHidden: function(args) {
+ var selectedVolumeId = $('div[role=dialog] form .form-item[rel=volume] select').val();
+ for (var i = 0; i < args.context.volumes.length; i++) {
+ var volume = args.context.volumes[i];
+ if (volume.id === selectedVolumeId) {
+ return volume.quiescevm !== true;
+ }
+ }
+ return false;
+ }
+ },
+ name: {
+ label: 'label.name',
+ docID: 'helpCreateInstanceStorageSnapshotName',
+ isInput: true
+ },
+ asyncBackup: {
+ label: 'label.async.backup',
+ isBoolean: true
+ }
+ }
+ },
+ action: function(args) {
+ var data = {
+ volumeId: args.data.volume,
+ quiescevm: args.data.quiescevm === 'on',
+ asyncBackup: args.data.asyncBackup === 'on'
+ };
+ if (args.data.name != null && args.data.name.length > 0) {
+ $.extend(data, {
+ name: args.data.name
+ });
+ }
+ $.ajax({
+ url: createURL('createSnapshot'),
+ data: data,
+ dataType: 'json',
+ async: true,
+ success: function(json) {
+ var jid = json.createsnapshotresponse.jobid;
+ args.response.success({
+ _custom: {
+ jobId: jid,
+ onComplete: function(json) {
+ var volumeId = json.queryasyncjobresultresponse.jobresult.snapshot.volumeid;
+ var snapshotId = json.queryasyncjobresultresponse.jobresult.snapshot.id;
+ cloudStack.dialog.notice({
+ message: 'Created snapshot for volume ' + volumeId + ' with snapshot ID ' + snapshotId
+ });
+ }
+ }
+ });
+ }
+ });
+ },
+ notification: {
+ poll: pollAsyncJobResult
+ }
+ },
destroy: vmDestroyAction(),
expunge: {
label: 'label.action.expunge.instance',
@@ -3437,6 +3542,7 @@
if (jsonObj.hypervisor != 'LXC') {
allowedActions.push("snapshot");
+ allowedActions.push("storageSnapshot");
}
allowedActions.push("destroy");
@@ -3474,6 +3580,7 @@
if (jsonObj.hypervisor != 'KVM' && jsonObj.hypervisor != 'LXC') {
allowedActions.push("snapshot");
+ allowedActions.push("storageSnapshot");
}
allowedActions.push("scaleUp"); //when vm is stopped, scaleUp is supported for all hypervisors