]> git.proxmox.com Git - pve-manager.git/blame - www/manager6/qemu/Clone.js
use Proxmox.Utils instead of PVE.Utils
[pve-manager.git] / www / manager6 / qemu / Clone.js
CommitLineData
f5226cd9
DM
1Ext.define('PVE.window.Clone', {
2 extend: 'Ext.window.Window',
3
4 resizable: false,
5
6 isTemplate: false,
7
ff79a116
DM
8 onlineHelp: 'qm_copy_and_clone',
9
26693bb9
EK
10 controller: {
11 xclass: 'Ext.app.ViewController',
12 control: {
13 'panel[reference=cloneform]': {
14 validitychange: 'disableSubmit'
15 }
16 },
17 disableSubmit: function(form) {
18 this.lookupReference('submitBtn').setDisabled(!form.isValid());
19 }
20 },
21
4e2b6cc8
EK
22 statics: {
23 // display a snapshot selector only if needed
24 wrap: function(nodename, vmid, isTemplate) {
e7ade592 25 Proxmox.Utils.API2Request({
4e2b6cc8
EK
26 url: '/nodes/' + nodename + '/qemu/' + vmid +'/snapshot',
27 failure: function(response, opts) {
28 Ext.Msg.alert('Error', response.htmlStatus);
29 },
30 success: function(response, opts) {
31 var snapshotList = response.result.data;
32 var hasSnapshots = snapshotList.length === 1 &&
33 snapshotList[0].name === 'current' ? false : true;
34
35 Ext.create('PVE.window.Clone', {
36 nodename: nodename,
37 vmid: vmid,
38 isTemplate: isTemplate,
39 hasSnapshots: hasSnapshots
40 }).show();
41 }
42 });
43 }
44 },
2f3c5c38 45
f5226cd9
DM
46 create_clone: function(values) {
47 var me = this;
48
406ac585 49 var params = { newid: values.newvmid };
f5226cd9 50
406ac585
EK
51 if (values.snapname && values.snapname !== 'current') {
52 params.snapname = values.snapname;
53 }
f5226cd9
DM
54
55 if (values.pool) {
56 params.pool = values.pool;
57 }
58
59 if (values.name) {
60 params.name = values.name;
61 }
62
63 if (values.target) {
64 params.target = values.target;
65 }
66
67 if (values.clonemode === 'copy') {
68 params.full = 1;
1490ff3d
DC
69 if (values.hdstorage) {
70 params.storage = values.hdstorage;
f5226cd9
DM
71 if (values.diskformat) {
72 params.format = values.diskformat;
73 }
74 }
75 }
76
e7ade592 77 Proxmox.Utils.API2Request({
f5226cd9
DM
78 params: params,
79 url: '/nodes/' + me.nodename + '/qemu/' + me.vmid + '/clone',
80 waitMsgTarget: me,
81 method: 'POST',
82 failure: function(response, opts) {
83 Ext.Msg.alert('Error', response.htmlStatus);
84 },
85 success: function(response, options) {
86 me.close();
87 }
88 });
89
90 },
91
44494b4c 92 // disable the Storage selector when clone mode is linked clone
f5226cd9
DM
93 updateVisibility: function() {
94 var me = this;
406ac585 95 var clonemode = me.lookupReference('clonemodesel').getValue();
1490ff3d
DC
96 var disksel = me.lookup('diskselector');
97 disksel.setDisabled(clonemode === 'clone');
f5226cd9
DM
98 },
99
26693bb9 100 // add to the list of valid nodes each node where
44494b4c 101 // all the VM disks are available
f5226cd9
DM
102 verifyFeature: function() {
103 var me = this;
406ac585
EK
104
105 var snapname = me.lookupReference('snapshotsel').getValue();
106 var clonemode = me.lookupReference('clonemodesel').getValue();
f5226cd9
DM
107
108 var params = { feature: clonemode };
109 if (snapname !== 'current') {
110 params.snapname = snapname;
111 }
112
e7ade592 113 Proxmox.Utils.API2Request({
f5226cd9
DM
114 waitMsgTarget: me,
115 url: '/nodes/' + me.nodename + '/qemu/' + me.vmid + '/feature',
116 params: params,
117 method: 'GET',
118 failure: function(response, opts) {
0057ea5c 119 me.lookupReference('submitBtn').setDisabled(true);
f5226cd9
DM
120 Ext.Msg.alert('Error', response.htmlStatus);
121 },
122 success: function(response, options) {
406ac585 123 var res = response.result.data;
f5226cd9 124
406ac585
EK
125 me.lookupReference('targetsel').allowedNodes = res.nodes;
126 me.lookupReference('targetsel').validate();
f5226cd9
DM
127 }
128 });
129 },
130
131 initComponent : function() {
f5226cd9
DM
132 var me = this;
133
134 if (!me.nodename) {
135 throw "no node name specified";
136 }
137
138 if (!me.vmid) {
139 throw "no VM ID specified";
140 }
141
142 if (!me.snapname) {
143 me.snapname = 'current';
144 }
145
406ac585
EK
146 var titletext = me.isTemplate ? "Template" : "VM";
147 me.title = "Clone " + titletext + " " + me.vmid;
148
f5226cd9
DM
149 var col1 = [];
150 var col2 = [];
151
406ac585
EK
152 col1.push({
153 xtype: 'pveNodeSelector',
f5226cd9 154 name: 'target',
406ac585 155 reference: 'targetsel',
f5226cd9
DM
156 fieldLabel: gettext('Target node'),
157 selectCurNode: true,
158 allowBlank: false,
406ac585
EK
159 onlineValidator: true,
160 listeners: {
161 change: function(f, value) {
1490ff3d 162 me.lookupReference('hdstorage').setTargetNode(value);
406ac585
EK
163 }
164 }
f5226cd9
DM
165 });
166
f5226cd9
DM
167 var modelist = [['copy', gettext('Full Clone')]];
168 if (me.isTemplate) {
169 modelist.push(['clone', gettext('Linked Clone')]);
170 }
171
406ac585
EK
172 col1.push({
173 xtype: 'pveGuestIDSelector',
174 name: 'newvmid',
175 guestType: 'qemu',
176 value: '',
177 loadNextFreeID: true,
178 validateExists: false
179 },
180 {
181 xtype: 'textfield',
182 name: 'name',
183 allowBlank: true,
184 fieldLabel: gettext('Name')
185 },
186 {
187 xtype: 'pvePoolSelector',
188 fieldLabel: gettext('Resource Pool'),
189 name: 'pool',
190 value: '',
191 allowBlank: true
192 }
193 );
f5226cd9 194
406ac585
EK
195 col2.push({
196 xtype: 'pveKVComboBox',
197 fieldLabel: gettext('Mode'),
198 name: 'clonemode',
199 reference: 'clonemodesel',
200 allowBlank: false,
201 hidden: !me.isTemplate,
202 value: me.isTemplate ? 'clone' : 'copy',
203 comboItems: modelist,
204 listeners: {
205 change: function(t, value) {
206 me.updateVisibility();
207 me.verifyFeature();
208 }
209 }
210 },
211 {
212 xtype: 'PVE.form.SnapshotSelector',
f5226cd9 213 name: 'snapname',
406ac585 214 reference: 'snapshotsel',
f5226cd9 215 fieldLabel: gettext('Snapshot'),
406ac585
EK
216 nodename: me.nodename,
217 vmid: me.vmid,
2f3c5c38 218 hidden: me.isTemplate || !me.hasSnapshots ? true : false,
406ac585 219 disabled: false,
f5226cd9
DM
220 allowBlank: false,
221 value : me.snapname,
222 listeners: {
223 change: function(f, value) {
224 me.verifyFeature();
225 }
226 }
406ac585
EK
227 },
228 {
1490ff3d
DC
229 xtype: 'pveDiskStorageSelector',
230 reference: 'diskselector',
406ac585 231 nodename: me.nodename,
1490ff3d
DC
232 autoSelect: false,
233 hideSize: true,
234 hideSelection: true,
235 storageLabel: gettext('Target Storage'),
406ac585 236 allowBlank: true,
1490ff3d 237 storageContent: 'images',
f4f9e662 238 emptyText: gettext('Same as source'),
1490ff3d 239 disabled: me.isTemplate ? true : false // because default mode is clone for templates
f5226cd9
DM
240 });
241
406ac585 242 var formPanel = Ext.create('Ext.form.Panel', {
f5226cd9 243 bodyPadding: 10,
26693bb9 244 reference: 'cloneform',
f5226cd9
DM
245 border: false,
246 layout: 'column',
247 defaultType: 'container',
248 columns: 2,
249 fieldDefaults: {
250 labelWidth: 100,
251 anchor: '100%'
252 },
253 items: [
254 {
255 columnWidth: 0.5,
256 padding: '0 10 0 0',
257 layout: 'anchor',
258 items: col1
259 },
260 {
261 columnWidth: 0.5,
262 padding: '0 0 0 10',
263 layout: 'anchor',
264 items: col2
265 }
266 ]
267 });
268
f5226cd9
DM
269 Ext.apply(me, {
270 modal: true,
271 width: 600,
272 height: 250,
273 border: false,
274 layout: 'fit',
406ac585
EK
275 buttons: [ {
276 xtype: 'pveHelpButton',
277 listenToGlobalEvent: false,
278 hidden: false,
279 onlineHelp: me.onlineHelp
280 },
281 '->',
282 {
283 reference: 'submitBtn',
284 text: gettext('Clone'),
285 disabled: true,
286 handler: function() {
287 var cloneForm = me.lookupReference('cloneform');
288 if (cloneForm.isValid()) {
289 me.create_clone(cloneForm.getValues());
290 }
291 }
292 } ],
293 items: [ formPanel ]
f5226cd9
DM
294 });
295
296 me.callParent();
297
298 me.verifyFeature();
299 }
300});