]> git.proxmox.com Git - pve-manager.git/blob - www/manager6/window/Restore.js
ui: window/Migrate: avoid triggering another info request if already in-progress
[pve-manager.git] / www / manager6 / window / Restore.js
1 Ext.define('PVE.window.Restore', {
2 extend: 'Ext.window.Window', // fixme: Proxmox.window.Edit?
3
4 resizable: false,
5
6 controller: {
7 xclass: 'Ext.app.ViewController',
8 control: {
9 '#liveRestore': {
10 change: function(el, newVal) {
11 let liveWarning = this.lookupReference('liveWarning');
12 liveWarning.setHidden(!newVal);
13 let start = this.lookupReference('start');
14 start.setDisabled(newVal);
15 },
16 },
17 },
18 },
19
20 initComponent: function() {
21 var me = this;
22
23 if (!me.nodename) {
24 throw "no node name specified";
25 }
26
27 if (!me.volid) {
28 throw "no volume ID specified";
29 }
30
31 if (!me.vmtype) {
32 throw "no vmtype specified";
33 }
34
35 var storagesel = Ext.create('PVE.form.StorageSelector', {
36 nodename: me.nodename,
37 name: 'storage',
38 value: '',
39 fieldLabel: gettext('Storage'),
40 storageContent: me.vmtype === 'lxc' ? 'rootdir' : 'images',
41 // when restoring a container without specifying a storage, the backend defaults
42 // to 'local', which is unintuitive and 'rootdir' might not even be allowed on it
43 allowBlank: me.vmtype !== 'lxc',
44 emptyText: me.vmtype === 'lxc' ? '' : gettext('From backup configuration'),
45 autoSelect: me.vmtype === 'lxc',
46 });
47
48 var IDfield;
49 if (me.vmid) {
50 IDfield = Ext.create('Ext.form.field.Display', {
51 name: 'vmid',
52 value: me.vmid,
53 fieldLabel: me.vmtype === 'lxc' ? 'CT' : 'VM',
54 });
55 } else {
56 IDfield = Ext.create('PVE.form.GuestIDSelector', {
57 name: 'vmid',
58 guestType: me.vmtype,
59 loadNextFreeID: true,
60 validateExists: false,
61 });
62 }
63
64 var items = [
65 {
66 xtype: 'displayfield',
67 value: me.volidText || me.volid,
68 fieldLabel: gettext('Source'),
69 },
70 storagesel,
71 IDfield,
72 {
73 xtype: 'pveBandwidthField',
74 name: 'bwlimit',
75 backendUnit: 'KiB',
76 allowZero: true,
77 fieldLabel: gettext('Bandwidth Limit'),
78 emptyText: gettext('Defaults to target storage restore limit'),
79 autoEl: {
80 tag: 'div',
81 'data-qtip': gettext("Use '0' to disable all bandwidth limits."),
82 },
83 },
84 {
85 xtype: 'fieldcontainer',
86 layout: 'hbox',
87 items: [{
88 xtype: 'proxmoxcheckbox',
89 name: 'unique',
90 fieldLabel: gettext('Unique'),
91 hidden: !!me.vmid,
92 flex: 1,
93 autoEl: {
94 tag: 'div',
95 'data-qtip': gettext('Autogenerate unique properties, e.g., MAC addresses'),
96 },
97 checked: false,
98 },
99 {
100 xtype: 'proxmoxcheckbox',
101 name: 'start',
102 reference: 'start',
103 flex: 1,
104 fieldLabel: gettext('Start after restore'),
105 labelWidth: 105,
106 checked: false,
107 }],
108 },
109 ];
110
111 if (me.vmtype === 'lxc') {
112 items.push(
113 {
114 xtype: 'radiogroup',
115 fieldLabel: gettext('Privilege Level'),
116 reference: 'noVNCScalingGroup',
117 height: '15px', // renders faster with value assigned
118 layout: {
119 type: 'hbox',
120 algin: 'stretch',
121 },
122 autoEl: {
123 tag: 'div',
124 'data-qtip':
125 gettext('Choose if you want to keep or override the privilege level of the restored Container.'),
126 },
127 items: [
128 {
129 xtype: 'radiofield',
130 name: 'unprivileged',
131 inputValue: 'keep',
132 boxLabel: gettext('From Backup'),
133 flex: 1,
134 checked: true,
135 },
136 {
137 xtype: 'radiofield',
138 name: 'unprivileged',
139 inputValue: '1',
140 boxLabel: gettext('Unprivileged'),
141 flex: 1,
142 },
143 {
144 xtype: 'radiofield',
145 name: 'unprivileged',
146 inputValue: '0',
147 boxLabel: gettext('Privileged'),
148 flex: 1,
149 //margin: '0 0 0 10',
150 },
151 ],
152 },
153 );
154 } else if (me.vmtype === 'qemu') {
155 items.push({
156 xtype: 'proxmoxcheckbox',
157 name: 'live-restore',
158 itemId: 'liveRestore',
159 flex: 1,
160 fieldLabel: gettext('Live restore'),
161 checked: false,
162 hidden: !me.isPBS,
163 // align checkbox with 'start' if 'unique' is hidden
164 labelWidth: me.vmid ? 105 : 100,
165 });
166 items.push({
167 xtype: 'displayfield',
168 reference: 'liveWarning',
169 // TODO: Remove once more tested/stable?
170 value: gettext('Note: If anything goes wrong during the live-restore, new data written by the VM may be lost.'),
171 userCls: 'pmx-hint',
172 hidden: true,
173 });
174 }
175
176 me.formPanel = Ext.create('Ext.form.Panel', {
177 bodyPadding: 10,
178 border: false,
179 fieldDefaults: {
180 labelWidth: 100,
181 anchor: '100%',
182 },
183 items: items,
184 });
185
186 var form = me.formPanel.getForm();
187
188 var doRestore = function(url, params) {
189 Proxmox.Utils.API2Request({
190 url: url,
191 params: params,
192 method: 'POST',
193 waitMsgTarget: me,
194 failure: function(response, opts) {
195 Ext.Msg.alert(gettext('Error'), response.htmlStatus);
196 },
197 success: function(response, options) {
198 var upid = response.result.data;
199
200 var win = Ext.create('Proxmox.window.TaskViewer', {
201 upid: upid,
202 });
203 win.show();
204 me.close();
205 },
206 });
207 };
208
209 var submitBtn = Ext.create('Ext.Button', {
210 text: gettext('Restore'),
211 handler: function() {
212 var values = form.getValues();
213
214 var params = {
215 vmid: me.vmid || values.vmid,
216 force: me.vmid ? 1 : 0,
217 };
218 if (values.unique) { params.unique = 1; }
219 if (values.start && !values['live-restore']) { params.start = 1; }
220 if (values['live-restore']) { params['live-restore'] = 1; }
221 if (values.storage) { params.storage = values.storage; }
222
223 if (values.bwlimit !== undefined) {
224 params.bwlimit = values.bwlimit;
225 }
226
227 var url;
228 var msg;
229 if (me.vmtype === 'lxc') {
230 url = '/nodes/' + me.nodename + '/lxc';
231 params.ostemplate = me.volid;
232 params.restore = 1;
233 if (values.unprivileged !== 'keep') {
234 params.unprivileged = values.unprivileged;
235 }
236 msg = Proxmox.Utils.format_task_description('vzrestore', params.vmid);
237 } else if (me.vmtype === 'qemu') {
238 url = '/nodes/' + me.nodename + '/qemu';
239 params.archive = me.volid;
240 msg = Proxmox.Utils.format_task_description('qmrestore', params.vmid);
241 } else {
242 throw 'unknown VM type';
243 }
244
245 if (me.vmid) {
246 msg += '. ' + gettext('This will permanently erase current VM data.');
247 Ext.Msg.confirm(gettext('Confirm'), msg, function(btn) {
248 if (btn !== 'yes') {
249 return;
250 }
251 doRestore(url, params);
252 });
253 } else {
254 doRestore(url, params);
255 }
256 },
257 });
258
259 form.on('validitychange', function(f, valid) {
260 submitBtn.setDisabled(!valid);
261 });
262
263 var title = gettext('Restore') + ": " + (
264 me.vmtype === 'lxc' ? 'CT' : 'VM');
265
266 if (me.vmid) {
267 title += " " + me.vmid;
268 }
269
270 Ext.apply(me, {
271 title: title,
272 width: 500,
273 modal: true,
274 layout: 'auto',
275 border: false,
276 items: [me.formPanel],
277 buttons: [submitBtn],
278 });
279
280 me.callParent();
281 },
282 });