]>
Commit | Line | Data |
---|---|---|
d7683c68 | 1 | Ext.define('PVE.window.Restore', { |
9fccc702 | 2 | extend: 'Ext.window.Window', // fixme: Proxmox.window.Edit? |
d7683c68 DM |
3 | |
4 | resizable: false, | |
5 | ||
878bbf0b SR |
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 | ||
8058410f | 20 | initComponent: function() { |
d7683c68 DM |
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'), | |
53e3ea84 | 40 | storageContent: me.vmtype === 'lxc' ? 'rootdir' : 'images', |
6fe863ba FE |
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', | |
53e3ea84 | 44 | emptyText: me.vmtype === 'lxc' ? '' : gettext('From backup configuration'), |
6fe863ba | 45 | autoSelect: me.vmtype === 'lxc', |
d7683c68 DM |
46 | }); |
47 | ||
ed416f20 EK |
48 | var IDfield; |
49 | if (me.vmid) { | |
50 | IDfield = Ext.create('Ext.form.field.Display', { | |
51 | name: 'vmid', | |
52 | value: me.vmid, | |
53e3ea84 | 53 | fieldLabel: me.vmtype === 'lxc' ? 'CT' : 'VM', |
ed416f20 EK |
54 | }); |
55 | } else { | |
56 | IDfield = Ext.create('PVE.form.GuestIDSelector', { | |
57 | name: 'vmid', | |
58 | guestType: me.vmtype, | |
677bb0e8 | 59 | loadNextFreeID: true, |
f6710aac | 60 | validateExists: false, |
ed416f20 EK |
61 | }); |
62 | } | |
63 | ||
9cf2e84b DM |
64 | var items = [ |
65 | { | |
66 | xtype: 'displayfield', | |
67 | value: me.volidText || me.volid, | |
f6710aac | 68 | fieldLabel: gettext('Source'), |
9cf2e84b DM |
69 | }, |
70 | storagesel, | |
9fa4ce6d TL |
71 | IDfield, |
72 | { | |
a331258a | 73 | xtype: 'pveBandwidthField', |
9fa4ce6d | 74 | name: 'bwlimit', |
0545b2a5 | 75 | backendUnit: 'KiB', |
9ae4a024 FE |
76 | allowZero: true, |
77 | fieldLabel: gettext('Bandwidth Limit'), | |
9fa4ce6d TL |
78 | emptyText: gettext('Defaults to target storage restore limit'), |
79 | autoEl: { | |
80 | tag: 'div', | |
f6710aac TL |
81 | 'data-qtip': gettext("Use '0' to disable all bandwidth limits."), |
82 | }, | |
c517e212 | 83 | }, |
8b030d08 | 84 | { |
24c55f41 TL |
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', | |
f6710aac | 95 | 'data-qtip': gettext('Autogenerate unique properties, e.g., MAC addresses'), |
24c55f41 | 96 | }, |
f6710aac | 97 | checked: false, |
8b030d08 | 98 | }, |
24c55f41 TL |
99 | { |
100 | xtype: 'proxmoxcheckbox', | |
101 | name: 'start', | |
878bbf0b | 102 | reference: 'start', |
24c55f41 TL |
103 | flex: 1, |
104 | fieldLabel: gettext('Start after restore'), | |
105 | labelWidth: 105, | |
f6710aac | 106 | checked: false, |
24c55f41 TL |
107 | }], |
108 | }, | |
9cf2e84b DM |
109 | ]; |
110 | ||
111 | if (me.vmtype === 'lxc') { | |
112 | items.push({ | |
896c0d50 | 113 | xtype: 'proxmoxcheckbox', |
9cf2e84b | 114 | name: 'unprivileged', |
a1892701 | 115 | value: true, |
f6710aac | 116 | fieldLabel: gettext('Unprivileged container'), |
9cf2e84b | 117 | }); |
878bbf0b SR |
118 | } else if (me.vmtype === 'qemu') { |
119 | items.push({ | |
120 | xtype: 'proxmoxcheckbox', | |
121 | name: 'live-restore', | |
122 | itemId: 'liveRestore', | |
123 | flex: 1, | |
124 | fieldLabel: gettext('Live restore'), | |
125 | checked: false, | |
126 | hidden: !me.isPBS, | |
127 | // align checkbox with 'start' if 'unique' is hidden | |
128 | labelWidth: me.vmid ? 105 : 100, | |
129 | }); | |
130 | items.push({ | |
131 | xtype: 'displayfield', | |
132 | reference: 'liveWarning', | |
133 | // TODO: Remove once more tested/stable? | |
52b31ee3 | 134 | value: gettext('Note: If anything goes wrong during the live-restore, new data written by the VM will be lost.'), |
878bbf0b SR |
135 | userCls: 'pmx-hint', |
136 | hidden: true, | |
137 | }); | |
9cf2e84b DM |
138 | } |
139 | ||
d7683c68 DM |
140 | me.formPanel = Ext.create('Ext.form.Panel', { |
141 | bodyPadding: 10, | |
142 | border: false, | |
143 | fieldDefaults: { | |
144 | labelWidth: 100, | |
f6710aac | 145 | anchor: '100%', |
d7683c68 | 146 | }, |
f6710aac | 147 | items: items, |
d7683c68 DM |
148 | }); |
149 | ||
150 | var form = me.formPanel.getForm(); | |
151 | ||
152 | var doRestore = function(url, params) { | |
e7ade592 | 153 | Proxmox.Utils.API2Request({ |
d7683c68 DM |
154 | url: url, |
155 | params: params, | |
156 | method: 'POST', | |
157 | waitMsgTarget: me, | |
8058410f | 158 | failure: function(response, opts) { |
d7683c68 DM |
159 | Ext.Msg.alert(gettext('Error'), response.htmlStatus); |
160 | }, | |
161 | success: function(response, options) { | |
162 | var upid = response.result.data; | |
2a4971d8 | 163 | |
8cbc11a7 | 164 | var win = Ext.create('Proxmox.window.TaskViewer', { |
f6710aac | 165 | upid: upid, |
d7683c68 DM |
166 | }); |
167 | win.show(); | |
168 | me.close(); | |
f6710aac | 169 | }, |
d7683c68 DM |
170 | }); |
171 | }; | |
172 | ||
173 | var submitBtn = Ext.create('Ext.Button', { | |
174 | text: gettext('Restore'), | |
8058410f | 175 | handler: function() { |
d7683c68 DM |
176 | var values = form.getValues(); |
177 | ||
178 | var params = { | |
d7683c68 | 179 | vmid: me.vmid || values.vmid, |
f6710aac | 180 | force: me.vmid ? 1 : 0, |
d7683c68 | 181 | }; |
c517e212 | 182 | if (values.unique) { params.unique = 1; } |
878bbf0b SR |
183 | if (values.start && !values['live-restore']) { params.start = 1; } |
184 | if (values['live-restore']) { params['live-restore'] = 1; } | |
6fe863ba | 185 | if (values.storage) { params.storage = values.storage; } |
d7683c68 | 186 | |
9fa4ce6d | 187 | if (values.bwlimit !== undefined) { |
0545b2a5 | 188 | params.bwlimit = values.bwlimit; |
9fa4ce6d TL |
189 | } |
190 | ||
d7683c68 | 191 | var url; |
16152937 | 192 | var msg; |
a00a9ffd AG |
193 | if (me.vmtype === 'lxc') { |
194 | url = '/nodes/' + me.nodename + '/lxc'; | |
d7683c68 DM |
195 | params.ostemplate = me.volid; |
196 | params.restore = 1; | |
9cf2e84b | 197 | if (values.unprivileged) { params.unprivileged = 1; } |
e7ade592 | 198 | msg = Proxmox.Utils.format_task_description('vzrestore', params.vmid); |
d7683c68 DM |
199 | } else if (me.vmtype === 'qemu') { |
200 | url = '/nodes/' + me.nodename + '/qemu'; | |
201 | params.archive = me.volid; | |
e7ade592 | 202 | msg = Proxmox.Utils.format_task_description('qmrestore', params.vmid); |
d7683c68 DM |
203 | } else { |
204 | throw 'unknown VM type'; | |
205 | } | |
206 | ||
207 | if (me.vmid) { | |
16152937 | 208 | msg += '. ' + gettext('This will permanently erase current VM data.'); |
d7683c68 DM |
209 | Ext.Msg.confirm(gettext('Confirm'), msg, function(btn) { |
210 | if (btn !== 'yes') { | |
211 | return; | |
212 | } | |
213 | doRestore(url, params); | |
214 | }); | |
215 | } else { | |
216 | doRestore(url, params); | |
217 | } | |
f6710aac | 218 | }, |
d7683c68 DM |
219 | }); |
220 | ||
221 | form.on('validitychange', function(f, valid) { | |
222 | submitBtn.setDisabled(!valid); | |
223 | }); | |
224 | ||
8058410f | 225 | var title = gettext('Restore') + ": " + ( |
53e3ea84 | 226 | me.vmtype === 'lxc' ? 'CT' : 'VM'); |
185a77e5 DM |
227 | |
228 | if (me.vmid) { | |
229 | title += " " + me.vmid; | |
230 | } | |
d7683c68 DM |
231 | |
232 | Ext.apply(me, { | |
233 | title: title, | |
234 | width: 500, | |
235 | modal: true, | |
236 | layout: 'auto', | |
237 | border: false, | |
8058410f TL |
238 | items: [me.formPanel], |
239 | buttons: [submitBtn], | |
d7683c68 DM |
240 | }); |
241 | ||
242 | me.callParent(); | |
f6710aac | 243 | }, |
d7683c68 | 244 | }); |