]>
Commit | Line | Data |
---|---|---|
1665b840 FE |
1 | Ext.define('PVE.storage.BackupView', { |
2 | extend: 'PVE.storage.ContentView', | |
3 | ||
4 | alias: 'widget.pveStorageBackupView', | |
5 | ||
61cf2658 | 6 | showColumns: ['name', 'notes', 'protected', 'date', 'format', 'size'], |
c0eadd55 | 7 | |
1665b840 | 8 | initComponent: function() { |
7b696d5a | 9 | let me = this; |
1665b840 | 10 | |
7b696d5a | 11 | let nodename = me.nodename = me.pveSelNode.data.node; |
1665b840 FE |
12 | if (!nodename) { |
13 | throw "no node name specified"; | |
14 | } | |
15 | ||
7b696d5a | 16 | let storage = me.storage = me.pveSelNode.data.storage; |
1665b840 FE |
17 | if (!storage) { |
18 | throw "no storage ID specified"; | |
19 | } | |
20 | ||
21 | me.content = 'backup'; | |
22 | ||
7b696d5a | 23 | let sm = me.sm = Ext.create('Ext.selection.RowModel', {}); |
1665b840 | 24 | |
e969d187 FE |
25 | let pruneButton = Ext.create('Proxmox.button.Button', { |
26 | text: gettext('Prune group'), | |
27 | disabled: true, | |
28 | selModel: sm, | |
29 | setBackupGroup: function(backup) { | |
30 | if (backup) { | |
31 | let name = backup.text; | |
32 | let vmid = backup.vmid; | |
33 | let format = backup.format; | |
34 | ||
35 | let vmtype; | |
36 | if (name.startsWith('vzdump-lxc-') || format === "pbs-ct") { | |
37 | vmtype = 'lxc'; | |
38 | } else if (name.startsWith('vzdump-qemu-') || format === "pbs-vm") { | |
39 | vmtype = 'qemu'; | |
40 | } | |
41 | ||
42 | if (vmid && vmtype) { | |
43 | this.setText(gettext('Prune group') + ` ${vmtype}/${vmid}`); | |
44 | this.vmid = vmid; | |
45 | this.vmtype = vmtype; | |
46 | this.setDisabled(false); | |
47 | return; | |
48 | } | |
49 | } | |
50 | this.setText(gettext('Prune group')); | |
51 | this.vmid = null; | |
52 | this.vmtype = null; | |
53 | this.setDisabled(true); | |
54 | }, | |
55 | handler: function(b, e, rec) { | |
7b696d5a TL |
56 | Ext.create('PVE.window.Prune', { |
57 | autoShow: true, | |
58 | nodename, | |
59 | storage, | |
e969d187 FE |
60 | backup_id: this.vmid, |
61 | backup_type: this.vmtype, | |
7b696d5a TL |
62 | listeners: { |
63 | destroy: () => me.store.load(), | |
64 | }, | |
e969d187 | 65 | }); |
e969d187 FE |
66 | }, |
67 | }); | |
68 | ||
69 | me.on('selectionchange', function(model, srecords, eOpts) { | |
70 | if (srecords.length === 1) { | |
71 | pruneButton.setBackupGroup(srecords[0].data); | |
72 | } else { | |
73 | pruneButton.setBackupGroup(null); | |
74 | } | |
75 | }); | |
76 | ||
878bbf0b SR |
77 | let isPBS = me.pluginType === 'pbs'; |
78 | ||
1665b840 FE |
79 | me.tbar = [ |
80 | { | |
81 | xtype: 'proxmoxButton', | |
82 | text: gettext('Restore'), | |
83 | selModel: sm, | |
84 | disabled: true, | |
1665b840 | 85 | handler: function(b, e, rec) { |
7b696d5a | 86 | let vmtype; |
1665b840 FE |
87 | if (PVE.Utils.volume_is_qemu_backup(rec.data.volid, rec.data.format)) { |
88 | vmtype = 'qemu'; | |
89 | } else if (PVE.Utils.volume_is_lxc_backup(rec.data.volid, rec.data.format)) { | |
90 | vmtype = 'lxc'; | |
91 | } else { | |
92 | return; | |
93 | } | |
94 | ||
7b696d5a TL |
95 | Ext.create('PVE.window.Restore', { |
96 | autoShow: true, | |
97 | nodename, | |
1665b840 FE |
98 | volid: rec.data.volid, |
99 | volidText: PVE.Utils.render_storage_content(rec.data.volid, {}, rec), | |
7b696d5a TL |
100 | vmtype, |
101 | isPBS, | |
102 | listeners: { | |
103 | destroy: () => me.store.load(), | |
104 | }, | |
1665b840 | 105 | }); |
f6710aac | 106 | }, |
1665b840 | 107 | }, |
6e339db1 TL |
108 | ]; |
109 | if (isPBS) { | |
110 | me.tbar.push({ | |
111 | xtype: 'proxmoxButton', | |
112 | text: gettext('File Restore'), | |
113 | disabled: true, | |
114 | selModel: sm, | |
115 | handler: function(b, e, rec) { | |
116 | let isVMArchive = PVE.Utils.volume_is_qemu_backup(rec.data.volid, rec.data.format); | |
117 | Ext.create('Proxmox.window.FileBrowser', { | |
118 | title: gettext('File Restore') + " - " + rec.data.text, | |
119 | listURL: `/api2/json/nodes/localhost/storage/${me.storage}/file-restore/list`, | |
120 | downloadURL: `/api2/json/nodes/localhost/storage/${me.storage}/file-restore/download`, | |
121 | extraParams: { | |
122 | volume: rec.data.volid, | |
123 | }, | |
124 | archive: isVMArchive ? 'all' : undefined, | |
125 | autoShow: true, | |
126 | }); | |
127 | }, | |
128 | }); | |
129 | } | |
130 | me.tbar.push( | |
1665b840 FE |
131 | { |
132 | xtype: 'proxmoxButton', | |
133 | text: gettext('Show Configuration'), | |
134 | disabled: true, | |
135 | selModel: sm, | |
f6710aac | 136 | handler: function(b, e, rec) { |
7b696d5a TL |
137 | Ext.create('PVE.window.BackupConfig', { |
138 | autoShow: true, | |
1665b840 | 139 | volume: rec.data.volid, |
f6710aac | 140 | pveSelNode: me.pveSelNode, |
1665b840 | 141 | }); |
f6710aac | 142 | }, |
1665b840 | 143 | }, |
74b6a959 TL |
144 | { |
145 | xtype: 'proxmoxButton', | |
146 | text: gettext('Edit Notes'), | |
147 | disabled: true, | |
148 | selModel: sm, | |
149 | handler: function(b, e, rec) { | |
150 | let volid = rec.data.volid; | |
151 | Ext.create('Proxmox.window.Edit', { | |
7b696d5a | 152 | autoShow: true, |
74b6a959 TL |
153 | autoLoad: true, |
154 | width: 600, | |
155 | height: 400, | |
156 | resizable: true, | |
157 | title: gettext('Notes'), | |
158 | url: `/api2/extjs/nodes/${nodename}/storage/${me.storage}/content/${volid}`, | |
159 | layout: 'fit', | |
160 | items: [ | |
161 | { | |
162 | xtype: 'textarea', | |
163 | layout: 'fit', | |
164 | name: 'notes', | |
165 | height: '100%', | |
166 | }, | |
167 | ], | |
168 | listeners: { | |
7b696d5a | 169 | destroy: () => me.store.load(), |
74b6a959 | 170 | }, |
7b696d5a | 171 | }); |
74b6a959 TL |
172 | }, |
173 | }, | |
b4818ea7 FE |
174 | { |
175 | xtype: 'proxmoxButton', | |
176 | text: gettext('Change Protection'), | |
177 | disabled: true, | |
178 | handler: function(button, event, record) { | |
179 | const volid = record.data.volid; | |
180 | Proxmox.Utils.API2Request({ | |
181 | url: `/api2/extjs/nodes/${nodename}/storage/${me.storage}/content/${volid}`, | |
182 | method: 'PUT', | |
183 | waitMsgTarget: me, | |
184 | params: { 'protected': record.data.protected ? 0 : 1 }, | |
7b696d5a | 185 | failure: response => Ext.Msg.alert('Error', response.htmlStatus), |
73e1cfa9 CH |
186 | success: () => { |
187 | me.store.load({ | |
188 | callback: () => sm.fireEvent('selectionchange', sm, [record]), | |
189 | }); | |
190 | }, | |
b4818ea7 FE |
191 | }); |
192 | }, | |
193 | }, | |
6e339db1 | 194 | '-', |
e969d187 | 195 | pruneButton, |
6e339db1 | 196 | ); |
1665b840 | 197 | |
73ea065a DC |
198 | me.extraColumns = {}; |
199 | ||
878bbf0b | 200 | if (isPBS) { |
73ea065a DC |
201 | me.extraColumns.encrypted = { |
202 | header: gettext('Encrypted'), | |
203 | dataIndex: 'encrypted', | |
204 | renderer: PVE.Utils.render_backup_encryption, | |
205 | sorter: { | |
206 | property: 'encrypted', | |
207 | transform: encrypted => encrypted ? 1 : 0, | |
a4b87129 | 208 | }, |
73ea065a DC |
209 | }; |
210 | me.extraColumns.verification = { | |
211 | header: gettext('Verify State'), | |
212 | dataIndex: 'verification', | |
213 | renderer: PVE.Utils.render_backup_verification, | |
214 | sorter: { | |
215 | property: 'verification', | |
216 | transform: value => { | |
217 | let state = value?.state ?? 'none'; | |
218 | let order = PVE.Utils.verificationStateOrder; | |
219 | return order[state] ?? order.__default__; | |
fdde857a | 220 | }, |
f6710aac | 221 | }, |
a4b87129 TL |
222 | }; |
223 | } | |
224 | ||
63d74bb6 | 225 | me.extraColumns.vmid = { |
4a884655 | 226 | header: 'VMID', |
63d74bb6 DC |
227 | dataIndex: 'vmid', |
228 | hidden: true, | |
229 | sorter: (a, b) => (a.data.vmid ?? 0) - (b.data.vmid ?? 0), | |
230 | }; | |
231 | ||
1665b840 | 232 | me.callParent(); |
9082d8d0 FE |
233 | |
234 | me.store.getSorters().clear(); | |
235 | me.store.setSorters([ | |
9082d8d0 FE |
236 | { |
237 | property: 'vdate', | |
238 | direction: 'DESC', | |
239 | }, | |
240 | ]); | |
1665b840 FE |
241 | }, |
242 | }); |