]>
Commit | Line | Data |
---|---|---|
06694509 DM |
1 | Ext.define('Proxmox.window.TaskProgress', { |
2 | extend: 'Ext.window.Window', | |
3 | alias: 'widget.proxmoxTaskProgress', | |
4 | ||
fde8e8bb TL |
5 | taskDone: Ext.emptyFn, |
6 | ||
5dc3b0fa TL |
7 | width: 300, |
8 | layout: 'auto', | |
9 | modal: true, | |
10 | bodyPadding: 5, | |
11 | ||
06694509 | 12 | initComponent: function() { |
05a977a2 | 13 | let me = this; |
06694509 DM |
14 | |
15 | if (!me.upid) { | |
16 | throw "no task specified"; | |
17 | } | |
18 | ||
05a977a2 | 19 | let task = Proxmox.Utils.parse_task_upid(me.upid); |
06694509 | 20 | |
05a977a2 | 21 | let statstore = Ext.create('Proxmox.data.ObjectStore', { |
5dc3b0fa | 22 | url: `/api2/json/nodes/${task.node}/tasks/${encodeURIComponent(me.upid)}/status`, |
06694509 DM |
23 | interval: 1000, |
24 | rows: { | |
25 | status: { defaultValue: 'unknown' }, | |
01031528 TL |
26 | exitstatus: { defaultValue: 'unknown' }, |
27 | }, | |
06694509 DM |
28 | }); |
29 | ||
13fc756d | 30 | me.on('destroy', statstore.stopUpdate); |
06694509 | 31 | |
05a977a2 TL |
32 | let getObjectValue = function(key, defaultValue) { |
33 | let rec = statstore.getById(key); | |
06694509 DM |
34 | if (rec) { |
35 | return rec.data.value; | |
36 | } | |
37 | return defaultValue; | |
38 | }; | |
39 | ||
d17aa32e | 40 | let pbar = Ext.create('Ext.ProgressBar'); |
06694509 DM |
41 | |
42 | me.mon(statstore, 'load', function() { | |
05a977a2 | 43 | let status = getObjectValue('status'); |
06694509 | 44 | if (status === 'stopped') { |
05a977a2 TL |
45 | let exitstatus = getObjectValue('exitstatus'); |
46 | if (exitstatus === 'OK') { | |
06694509 DM |
47 | pbar.reset(); |
48 | pbar.updateText("Done!"); | |
49 | Ext.Function.defer(me.close, 1000, me); | |
50 | } else { | |
51 | me.close(); | |
52 | Ext.Msg.alert('Task failed', exitstatus); | |
53 | } | |
05a977a2 | 54 | me.taskDone(exitstatus === 'OK'); |
06694509 DM |
55 | } |
56 | }); | |
57 | ||
05a977a2 | 58 | let descr = Proxmox.Utils.format_task_description(task.type, task.id); |
06694509 DM |
59 | |
60 | Ext.apply(me, { | |
d7139140 | 61 | title: gettext('Task') + ': ' + descr, |
06694509 DM |
62 | items: pbar, |
63 | buttons: [ | |
13fc756d | 64 | { |
06694509 | 65 | text: gettext('Details'), |
13fc756d | 66 | handler: function() { |
5dc3b0fa TL |
67 | Ext.create('Proxmox.window.TaskViewer', { |
68 | autoShow: true, | |
fde8e8bb | 69 | taskDone: me.taskDone, |
01031528 | 70 | upid: me.upid, |
06694509 | 71 | }); |
06694509 | 72 | me.close(); |
01031528 TL |
73 | }, |
74 | }, | |
75 | ], | |
06694509 DM |
76 | }); |
77 | ||
78 | me.callParent(); | |
79 | ||
80 | statstore.startUpdate(); | |
81 | ||
d17aa32e | 82 | pbar.wait({ text: gettext('running...') }); |
01031528 | 83 | }, |
06694509 DM |
84 | }); |
85 | ||
06694509 DM |
86 | Ext.define('Proxmox.window.TaskViewer', { |
87 | extend: 'Ext.window.Window', | |
88 | alias: 'widget.proxmoxTaskViewer', | |
89 | ||
641df09e TL |
90 | extraTitle: '', // string to prepend after the generic task title |
91 | ||
fde8e8bb TL |
92 | taskDone: Ext.emptyFn, |
93 | ||
06694509 | 94 | initComponent: function() { |
05a977a2 | 95 | let me = this; |
06694509 DM |
96 | |
97 | if (!me.upid) { | |
98 | throw "no task specified"; | |
99 | } | |
100 | ||
05a977a2 | 101 | let task = Proxmox.Utils.parse_task_upid(me.upid); |
06694509 | 102 | |
05a977a2 | 103 | let statgrid; |
06694509 | 104 | |
05a977a2 | 105 | let rows = { |
06694509 DM |
106 | status: { |
107 | header: gettext('Status'), | |
108 | defaultValue: 'unknown', | |
109 | renderer: function(value) { | |
05a977a2 | 110 | if (value !== 'stopped') { |
06694509 DM |
111 | return value; |
112 | } | |
05a977a2 | 113 | let es = statgrid.getObjectValue('exitstatus'); |
06694509 DM |
114 | if (es) { |
115 | return value + ': ' + es; | |
116 | } | |
05a977a2 | 117 | return 'unknown'; |
01031528 | 118 | }, |
06694509 | 119 | }, |
13fc756d | 120 | exitstatus: { |
01031528 | 121 | visible: false, |
06694509 DM |
122 | }, |
123 | type: { | |
124 | header: gettext('Task type'), | |
01031528 | 125 | required: true, |
06694509 DM |
126 | }, |
127 | user: { | |
128 | header: gettext('User name'), | |
8e3f2973 TL |
129 | renderer: function(value) { |
130 | let user = value; | |
131 | let tokenid = statgrid.getObjectValue('tokenid'); | |
132 | if (tokenid) { | |
133 | user += `!${tokenid} (API Token)`; | |
134 | } | |
135 | return Ext.String.htmlEncode(user); | |
136 | }, | |
01031528 | 137 | required: true, |
06694509 | 138 | }, |
c2ad5266 FG |
139 | tokenid: { |
140 | header: gettext('API Token'), | |
141 | renderer: Ext.String.htmlEncode, | |
8e3f2973 | 142 | visible: false, |
c2ad5266 | 143 | }, |
06694509 DM |
144 | node: { |
145 | header: gettext('Node'), | |
01031528 | 146 | required: true, |
06694509 DM |
147 | }, |
148 | pid: { | |
149 | header: gettext('Process ID'), | |
01031528 | 150 | required: true, |
06694509 | 151 | }, |
21efafeb TL |
152 | task_id: { |
153 | header: gettext('Task ID'), | |
154 | }, | |
06694509 DM |
155 | starttime: { |
156 | header: gettext('Start Time'), | |
13fc756d | 157 | required: true, |
01031528 | 158 | renderer: Proxmox.Utils.render_timestamp, |
06694509 DM |
159 | }, |
160 | upid: { | |
92d1c20d DC |
161 | header: gettext('Unique task ID'), |
162 | renderer: Ext.String.htmlEncode, | |
01031528 | 163 | }, |
06694509 DM |
164 | }; |
165 | ||
c9d603af DC |
166 | if (me.endtime) { |
167 | if (typeof me.endtime === 'object') { | |
168 | // convert to epoch | |
169 | me.endtime = parseInt(me.endtime.getTime()/1000, 10); | |
170 | } | |
171 | rows.endtime = { | |
172 | header: gettext('End Time'), | |
173 | required: true, | |
174 | renderer: function() { | |
175 | return Proxmox.Utils.render_timestamp(me.endtime); | |
176 | }, | |
177 | }; | |
178 | } | |
179 | ||
180 | rows.duration = { | |
181 | header: gettext('Duration'), | |
182 | required: true, | |
183 | renderer: function() { | |
184 | let starttime = statgrid.getObjectValue('starttime'); | |
185 | let endtime = me.endtime || Date.now()/1000; | |
186 | let duration = endtime - starttime; | |
187 | return Proxmox.Utils.format_duration_human(duration); | |
188 | }, | |
189 | }; | |
190 | ||
05a977a2 | 191 | let statstore = Ext.create('Proxmox.data.ObjectStore', { |
7b8eff31 | 192 | url: `/api2/json/nodes/${task.node}/tasks/${encodeURIComponent(me.upid)}/status`, |
06694509 | 193 | interval: 1000, |
01031528 | 194 | rows: rows, |
06694509 DM |
195 | }); |
196 | ||
13fc756d | 197 | me.on('destroy', statstore.stopUpdate); |
06694509 | 198 | |
05a977a2 | 199 | let stop_task = function() { |
06694509 | 200 | Proxmox.Utils.API2Request({ |
7b8eff31 | 201 | url: `/nodes/${task.node}/tasks/${encodeURIComponent(me.upid)}`, |
06694509 DM |
202 | waitMsgTarget: me, |
203 | method: 'DELETE', | |
ba4ab766 | 204 | failure: response => Ext.Msg.alert(gettext('Error'), response.htmlStatus), |
06694509 DM |
205 | }); |
206 | }; | |
207 | ||
05a977a2 | 208 | let stop_btn1 = new Ext.Button({ |
06694509 DM |
209 | text: gettext('Stop'), |
210 | disabled: true, | |
01031528 | 211 | handler: stop_task, |
06694509 DM |
212 | }); |
213 | ||
05a977a2 | 214 | let stop_btn2 = new Ext.Button({ |
06694509 DM |
215 | text: gettext('Stop'), |
216 | disabled: true, | |
01031528 | 217 | handler: stop_task, |
06694509 DM |
218 | }); |
219 | ||
220 | statgrid = Ext.create('Proxmox.grid.ObjectGrid', { | |
221 | title: gettext('Status'), | |
222 | layout: 'fit', | |
01031528 | 223 | tbar: [stop_btn1], |
06694509 DM |
224 | rstore: statstore, |
225 | rows: rows, | |
01031528 | 226 | border: false, |
06694509 DM |
227 | }); |
228 | ||
45110c16 DT |
229 | let downloadBtn = new Ext.Button({ |
230 | text: gettext('Download'), | |
231 | iconCls: 'fa fa-download', | |
7b8eff31 TL |
232 | handler: () => Proxmox.Utils.downloadAsFile( |
233 | `/api2/json/nodes/${task.node}/tasks/${encodeURIComponent(me.upid)}/log?download=1`), | |
45110c16 DT |
234 | }); |
235 | ||
236 | ||
05a977a2 | 237 | let logView = Ext.create('Proxmox.panel.LogView', { |
06694509 | 238 | title: gettext('Output'), |
45110c16 | 239 | tbar: [stop_btn2, '->', downloadBtn], |
06694509 | 240 | border: false, |
45110c16 | 241 | url: `/api2/extjs/nodes/${task.node}/tasks/${encodeURIComponent(me.upid)}/log`, |
06694509 DM |
242 | }); |
243 | ||
244 | me.mon(statstore, 'load', function() { | |
05a977a2 | 245 | let status = statgrid.getObjectValue('status'); |
13fc756d | 246 | |
06694509 | 247 | if (status === 'stopped') { |
06694509 | 248 | logView.scrollToEnd = false; |
65bb3b67 | 249 | logView.requestUpdate(); |
06694509 | 250 | statstore.stopUpdate(); |
05a977a2 | 251 | me.taskDone(statgrid.getObjectValue('exitstatus') === 'OK'); |
06694509 DM |
252 | } |
253 | ||
254 | stop_btn1.setDisabled(status !== 'running'); | |
255 | stop_btn2.setDisabled(status !== 'running'); | |
45110c16 | 256 | downloadBtn.setDisabled(status === 'running'); |
06694509 DM |
257 | }); |
258 | ||
259 | statstore.startUpdate(); | |
260 | ||
261 | Ext.apply(me, { | |
641df09e | 262 | title: "Task viewer: " + task.desc + me.extraTitle, |
06694509 | 263 | width: 800, |
be3e4b4c | 264 | height: 500, |
06694509 DM |
265 | layout: 'fit', |
266 | modal: true, | |
267 | items: [{ | |
268 | xtype: 'tabpanel', | |
269 | region: 'center', | |
01031528 TL |
270 | items: [logView, statgrid], |
271 | }], | |
06694509 DM |
272 | }); |
273 | ||
274 | me.callParent(); | |
275 | ||
276 | logView.fireEvent('show', logView); | |
01031528 | 277 | }, |
06694509 DM |
278 | }); |
279 |