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