Signed-off-by: Alexandre Derumier <aderum...@odiso.com> --- www/manager/Makefile | 1 + www/manager/qemu/Clone.js | 268 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 269 insertions(+) create mode 100644 www/manager/qemu/Clone.js
diff --git a/www/manager/Makefile b/www/manager/Makefile index a4feb40..9e84ef1 100644 --- a/www/manager/Makefile +++ b/www/manager/Makefile @@ -102,6 +102,7 @@ JSSRC= \ qemu/ScsiHwEdit.js \ qemu/Options.js \ qemu/Snapshot.js \ + qemu/Clone.js \ qemu/SnapshotTree.js \ qemu/Config.js \ qemu/CreateWizard.js \ diff --git a/www/manager/qemu/Clone.js b/www/manager/qemu/Clone.js new file mode 100644 index 0000000..70b3a99 --- /dev/null +++ b/www/manager/qemu/Clone.js @@ -0,0 +1,268 @@ +Ext.define('PVE.window.Clone', { + extend: 'Ext.window.Window', + + resizable: false, + + + create_clone: function(snapname, name, newvmid, clonemode, storage, format, diskarray) { + var me = this; + + params = { name: name, clonefrom: me.vmid, vmid: newvmid, clonemode: clonemode }; + + if (snapname && snapname !== 'current') { + params.snapname = snapname; + } + + if (clonemode === 'copy' && storage){ + + Ext.Array.each(diskarray, function(disk) { + var myformat = format ? format : ''; + params[disk] = storage + ':' + myformat; + }); + } + + + + PVE.Utils.API2Request({ + params: params, + url: '/nodes/' + me.nodename + '/qemu', + waitMsgTarget: me, + method: 'POST', + failure: function(response, opts) { + Ext.Msg.alert('Error', response.htmlStatus); + }, + success: function(response, options) { + me.close(); + } + }); + + }, + + compute_sel1: function(clonefeature, istemplate, snapname) { + var me = this; + var list = []; + list.push(['copy', 'Copy Clone']); + + if((clonefeature && istemplate === 1 && snapname === 'current') || (clonefeature && !istemplate && snapname !== 'current')){ + list.push(['clone', 'Linked Clone']); + } + me.kv1.store.loadData(list); + + if((clonefeature && istemplate === 1 && snapname === 'current') || (clonefeature && !istemplate && snapname !== 'current')){ + me.kv1.setValue('clone'); + }else{ + me.kv1.setValue('copy'); + } + }, + + initComponent : function() { + var me = this; + + var diskarray = []; + + if (!me.nodename) { + throw "no node name specified"; + } + + if (!me.vmid) { + throw "no VM ID specified"; + } + + me.snapshotsel = Ext.create('PVE.form.SnapshotSelector', { + name: 'snapname', + fieldLabel: 'Snapshot', + nodename: me.nodename, + vmid: me.vmid, + disabled: false, + hidden: me.istemplate ? true : false, + allowBlank: false, + value : me.snapname, + listeners: { + change: function(f, value) { + + var clonefeature; + var snapname = value; + //check if linked clone feature is available + var params = { feature: 'clone' }; + if (value !== 'current') { + params.snapname = snapname; + } + + PVE.Utils.API2Request({ + waitMsgTarget: me, + url: '/nodes/' + me.nodename + '/qemu/' + me.vmid + '/feature', + params: params, + method: 'GET', + success: function(response, options) { + var res = response.result.data; + + if (res === 1) { + clonefeature = 1; + } + me.compute_sel1(clonefeature, me.istemplate, snapname); + } + }); + } + } + }); + + var items = []; + + items.push(me.snapshotsel); + + items.push( + { + xtype: 'pveVMIDSelector', + name: 'newvmid', + value: '', + loadNextFreeVMID: true, + validateExists: false + }, + { + xtype: 'textfield', + name: 'name', + allowBlank: false, + fieldLabel: 'Name', + } + ); + + me.hdstoragesel = Ext.create('PVE.form.StorageSelector', { + name: 'hdstorage', + nodename: me.nodename, + fieldLabel: 'Target Storage', + storageContent: 'images', + autoSelect: me.insideWizard, + allowBlank: true, + disabled: true, + hidden: false, + listeners: { + change: function(f, value) { + var rec = f.store.getById(value); + if (rec.data.type === 'iscsi') { + me.formatsel.setValue('raw'); + me.formatsel.setDisabled(true); + } else if (rec.data.type === 'lvm' || + rec.data.type === 'rbd' || + rec.data.type === 'sheepdog' || + rec.data.type === 'nexenta' + ) { + me.formatsel.setValue('raw'); + me.formatsel.setDisabled(true); + } else { + me.formatsel.setDisabled(false); + } + + } + } + + }); + + me.formatsel = Ext.create('PVE.form.DiskFormatSelector', { + name: 'diskformat', + fieldLabel: gettext('Format'), + value: 'raw', + disabled: true, + hidden: false, + allowBlank: false + }); + + me.kv1 = Ext.create('PVE.form.KVComboBox', { + fieldLabel: 'Clone Mode', + name: 'clonemode', + allowBlank: false, + data: [] + }); + + me.mon(me.kv1, 'change', function(t, value) { + if (value === 'copy') { + me.hdstoragesel.setDisabled(false); + }else{ + me.hdstoragesel.setDisabled(true); + me.formatsel.setDisabled(true); + } + }); + + + items.push(me.kv1); + items.push(me.hdstoragesel); + items.push(me.formatsel); + + me.formPanel = Ext.create('Ext.form.Panel', { + bodyPadding: 10, + border: false, + fieldDefaults: { + labelWidth: 100, + anchor: '100%' + }, + items: items + }); + + var form = me.formPanel.getForm(); + + var submitBtn; + + var titletext = me.istemplate ? "Template" : "VM"; + me.title = "Clone " + titletext + " " + me.vmid; + submitBtn = Ext.create('Ext.Button', { + text: gettext('Clone'), + handler: function() { + if (form.isValid()) { + var values = form.getValues(); + me.create_clone(values.snapname, values.name, values.newvmid, values.clonemode, values.hdstorage, values.diskformat, diskarray); + } + } + }); + + + Ext.apply(me, { + modal: true, + width: 350, + height: 250, + border: false, + layout: 'fit', + buttons: [ submitBtn ], + items: [ me.formPanel ] + }); + + + me.callParent(); + + if (!me.snapname) { + return; + } + + me.compute_sel1(me.clonefeature, me.istemplate, me.snapname); + + var url; + + if (me.snapsname) { + url = '/nodes/' + me.nodename + '/qemu/' + me.vmid + "/snapshot/" + me.snapname + '/config'; + } else { + url = '/nodes/' + me.nodename + '/qemu/' + me.vmid + '/config'; + } + + + PVE.Utils.API2Request({ + url: url, + waitMsgTarget: me, + method: 'GET', + failure: function(response, opts) { + Ext.Msg.alert('Error', response.htmlStatus); + me.close(); + }, + success: function(response, options) { + var data = response.result.data; + Ext.Object.each(data, function(key, value) { + + var drive = PVE.Parser.parseQemuDrive(key, value); + if (drive) { + var match = drive.file.match(/^([^:]+):/); + if (match) { + diskarray.push(key); + } + } + }); + } + }); + } +}); -- 1.7.10.4 _______________________________________________ pve-devel mailing list pve-devel@pve.proxmox.com http://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel