]> git.proxmox.com Git - pve-manager.git/blob - www/manager6/storage/BackupView.js
bdaf85c8ddd618b0a401586ac3b3a098fd16b166
[pve-manager.git] / www / manager6 / storage / BackupView.js
1 Ext.define('PVE.storage.BackupView', {
2 extend: 'PVE.storage.ContentView',
3
4 alias: 'widget.pveStorageBackupView',
5
6 showColumns: ['name', 'notes', 'protected', 'date', 'format', 'size'],
7
8 initComponent: function() {
9 let me = this;
10
11 let nodename = me.nodename = me.pveSelNode.data.node;
12 if (!nodename) {
13 throw "no node name specified";
14 }
15
16 let storage = me.storage = me.pveSelNode.data.storage;
17 if (!storage) {
18 throw "no storage ID specified";
19 }
20
21 me.content = 'backup';
22
23 let sm = me.sm = Ext.create('Ext.selection.RowModel', {});
24
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) {
56 Ext.create('PVE.window.Prune', {
57 autoShow: true,
58 nodename,
59 storage,
60 backup_id: this.vmid,
61 backup_type: this.vmtype,
62 listeners: {
63 destroy: () => me.store.load(),
64 },
65 });
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
77 let isPBS = me.pluginType === 'pbs';
78
79 me.tbar = [
80 {
81 xtype: 'proxmoxButton',
82 text: gettext('Restore'),
83 selModel: sm,
84 disabled: true,
85 handler: function(b, e, rec) {
86 let vmtype;
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
95 Ext.create('PVE.window.Restore', {
96 autoShow: true,
97 nodename,
98 volid: rec.data.volid,
99 volidText: PVE.Utils.render_storage_content(rec.data.volid, {}, rec),
100 vmtype,
101 isPBS,
102 listeners: {
103 destroy: () => me.store.load(),
104 },
105 });
106 },
107 },
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(
131 {
132 xtype: 'proxmoxButton',
133 text: gettext('Show Configuration'),
134 disabled: true,
135 selModel: sm,
136 handler: function(b, e, rec) {
137 Ext.create('PVE.window.BackupConfig', {
138 autoShow: true,
139 volume: rec.data.volid,
140 pveSelNode: me.pveSelNode,
141 });
142 },
143 },
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', {
152 autoShow: true,
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: {
169 destroy: () => me.store.load(),
170 },
171 });
172 },
173 },
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 },
185 failure: response => Ext.Msg.alert('Error', response.htmlStatus),
186 success: () => {
187 me.store.load({
188 callback: () => sm.fireEvent('selectionchange', sm, [record]),
189 });
190 },
191 });
192 },
193 },
194 '-',
195 pruneButton,
196 );
197
198 me.extraColumns = {};
199
200 if (isPBS) {
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,
208 },
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__;
220 },
221 },
222 };
223 }
224
225 me.extraColumns.vmid = {
226 header: gettext('VMID'),
227 dataIndex: 'vmid',
228 hidden: true,
229 sorter: (a, b) => (a.data.vmid ?? 0) - (b.data.vmid ?? 0),
230 };
231
232 me.callParent();
233
234 me.store.getSorters().clear();
235 me.store.setSorters([
236 {
237 property: 'vdate',
238 direction: 'DESC',
239 },
240 ]);
241 },
242 });