]> git.proxmox.com Git - pve-manager.git/blob - www/manager6/window/Prune.js
ui: window/Migrate: avoid triggering another info request if already in-progress
[pve-manager.git] / www / manager6 / window / Prune.js
1 Ext.define('pve-prune-list', {
2 extend: 'Ext.data.Model',
3 fields: [
4 'type',
5 'vmid',
6 {
7 name: 'ctime',
8 type: 'date',
9 dateFormat: 'timestamp',
10 },
11 ],
12 });
13
14 Ext.define('PVE.PruneInputPanel', {
15 extend: 'Proxmox.panel.InputPanel',
16 alias: 'widget.pvePruneInputPanel',
17 mixins: ['Proxmox.Mixin.CBind'],
18
19 onGetValues: function(values) {
20 let me = this;
21
22 // the API expects a single prune-backups property string
23 let pruneBackups = PVE.Parser.printPropertyString(values);
24 values = {
25 'prune-backups': pruneBackups,
26 'type': me.backup_type,
27 'vmid': me.backup_id,
28 };
29
30 return values;
31 },
32
33 controller: {
34 xclass: 'Ext.app.ViewController',
35
36 init: function(view) {
37 if (!view.url) {
38 throw "no url specified";
39 }
40 if (!view.backup_type) {
41 throw "no backup_type specified";
42 }
43 if (!view.backup_id) {
44 throw "no backup_id specified";
45 }
46
47 this.reload(); // initial load
48 },
49
50 reload: function() {
51 let view = this.getView();
52
53 // helper to allow showing why a backup is kept
54 let addKeepReasons = function(backups, params) {
55 const rules = [
56 'keep-last',
57 'keep-hourly',
58 'keep-daily',
59 'keep-weekly',
60 'keep-monthly',
61 'keep-yearly',
62 'keep-all', // when all keep options are not set
63 ];
64 let counter = {};
65
66 backups.sort(function(a, b) {
67 return a.ctime < b.ctime;
68 });
69
70 let ruleIndex = -1;
71 let nextRule = function() {
72 let rule;
73 do {
74 ruleIndex++;
75 rule = rules[ruleIndex];
76 } while (!params[rule] && rule !== 'keep-all');
77 counter[rule] = 0;
78 return rule;
79 };
80
81 let rule = nextRule();
82 for (let backup of backups) {
83 if (backup.mark === 'keep') {
84 counter[rule]++;
85 if (rule !== 'keep-all') {
86 backup.keepReason = rule + ': ' + counter[rule];
87 if (counter[rule] >= params[rule]) {
88 rule = nextRule();
89 }
90 } else {
91 backup.keepReason = rule;
92 }
93 }
94 }
95 };
96
97 let params = view.getValues();
98 let keepParams = PVE.Parser.parsePropertyString(params["prune-backups"]);
99
100 Proxmox.Utils.API2Request({
101 url: view.url,
102 method: "GET",
103 params: params,
104 callback: function() {
105 // for easy breakpoint setting
106 },
107 failure: function(response, opts) {
108 Ext.Msg.alert(gettext('Error'), response.htmlStatus);
109 },
110 success: function(response, options) {
111 var data = response.result.data;
112 addKeepReasons(data, keepParams);
113 view.pruneStore.setData(data);
114 },
115 });
116 },
117
118 control: {
119 field: { change: 'reload' },
120 },
121 },
122
123 column1: [
124 {
125 xtype: 'pmxPruneKeepField',
126 name: 'keep-last',
127 fieldLabel: gettext('keep-last'),
128 },
129 {
130 xtype: 'pmxPruneKeepField',
131 name: 'keep-hourly',
132 fieldLabel: gettext('keep-hourly'),
133 },
134 {
135 xtype: 'pmxPruneKeepField',
136 name: 'keep-daily',
137 fieldLabel: gettext('keep-daily'),
138 },
139 {
140 xtype: 'pmxPruneKeepField',
141 name: 'keep-weekly',
142 fieldLabel: gettext('keep-weekly'),
143 },
144 {
145 xtype: 'pmxPruneKeepField',
146 name: 'keep-monthly',
147 fieldLabel: gettext('keep-monthly'),
148 },
149 {
150 xtype: 'pmxPruneKeepField',
151 name: 'keep-yearly',
152 fieldLabel: gettext('keep-yearly'),
153 },
154 ],
155
156 initComponent: function() {
157 var me = this;
158
159 me.pruneStore = Ext.create('Ext.data.Store', {
160 model: 'pve-prune-list',
161 sorters: { property: 'ctime', direction: 'DESC' },
162 });
163
164 me.column2 = [
165 {
166 xtype: 'grid',
167 height: 200,
168 store: me.pruneStore,
169 columns: [
170 {
171 header: gettext('Backup Time'),
172 sortable: true,
173 dataIndex: 'ctime',
174 renderer: function(value, metaData, record) {
175 let text = Ext.Date.format(value, 'Y-m-d H:i:s');
176 if (record.data.mark === 'remove') {
177 return '<div style="text-decoration: line-through;">'+ text +'</div>';
178 } else {
179 return text;
180 }
181 },
182 flex: 1,
183 },
184 {
185 text: 'Keep (reason)',
186 dataIndex: 'mark',
187 renderer: function(value, metaData, record) {
188 if (record.data.mark === 'keep') {
189 return 'true (' + record.data.keepReason + ')';
190 } else if (record.data.mark === 'protected') {
191 return 'true (renamed)';
192 } else {
193 return 'false';
194 }
195 },
196 flex: 1,
197 },
198 ],
199 },
200 ];
201
202 me.callParent();
203 },
204 });
205
206 Ext.define('PVE.window.Prune', {
207 extend: 'Proxmox.window.Edit',
208
209 method: 'DELETE',
210 submitText: gettext("Prune"),
211
212 fieldDefaults: { labelWidth: 130 },
213
214 isCreate: true,
215
216 initComponent: function() {
217 var me = this;
218
219 if (!me.nodename) {
220 throw "no nodename specified";
221 }
222 if (!me.storage) {
223 throw "no storage specified";
224 }
225 if (!me.backup_type) {
226 throw "no backup_type specified";
227 }
228 if (me.backup_type !== 'qemu' && me.backup_type !== 'lxc') {
229 throw "unknown backup type: " + me.backup_type;
230 }
231 if (!me.backup_id) {
232 throw "no backup_id specified";
233 }
234
235 let title = Ext.String.format(
236 gettext("Prune Backups for '{0}' on Storage '{1}'"),
237 me.backup_type + '/' + me.backup_id,
238 me.storage,
239 );
240
241 Ext.apply(me, {
242 url: '/api2/extjs/nodes/' + me.nodename + '/storage/' + me.storage + "/prunebackups",
243 title: title,
244 items: [
245 {
246 xtype: 'pvePruneInputPanel',
247 url: '/api2/extjs/nodes/' + me.nodename + '/storage/' + me.storage + "/prunebackups",
248 backup_type: me.backup_type,
249 backup_id: me.backup_id,
250 storage: me.storage,
251 },
252 ],
253 });
254
255 me.callParent();
256 },
257 });