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