]>
Commit | Line | Data |
---|---|---|
787ae72a DM |
1 | /* |
2 | * Workspace base class | |
3 | * | |
4 | * popup login window when auth fails (call onLogin handler) | |
5 | * update (re-login) ticket every 15 minutes | |
6 | * | |
7 | */ | |
8 | ||
9 | Ext.define('PVE.Workspace', { | |
10 | extend: 'Ext.container.Viewport', | |
11 | ||
12 | title: 'Proxmox Virtual Environment', | |
13 | ||
14 | loginData: null, // Data from last login call | |
15 | ||
16 | onLogin: function(loginData) {}, | |
17 | ||
18 | // private | |
19 | updateLoginData: function(loginData) { | |
20 | var me = this; | |
21 | me.loginData = loginData; | |
22 | PVE.CSRFPreventionToken = loginData.CSRFPreventionToken; | |
23 | PVE.UserName = loginData.username; | |
24 | ||
25 | if (loginData.cap) { | |
26 | Ext.state.Manager.set('GuiCap', loginData.cap); | |
27 | } | |
28 | ||
29 | // creates a session cookie (expire = null) | |
30 | // that way the cookie gets deleted after browser window close | |
31 | Ext.util.Cookies.set('PVEAuthCookie', loginData.ticket, null, '/', null, true); | |
32 | me.onLogin(loginData); | |
33 | }, | |
34 | ||
35 | // private | |
36 | showLogin: function() { | |
37 | var me = this; | |
38 | ||
39 | PVE.Utils.authClear(); | |
40 | PVE.UserName = null; | |
41 | me.loginData = null; | |
42 | ||
43 | if (!me.login) { | |
44 | me.login = Ext.create('PVE.window.LoginWindow', { | |
45 | handler: function(data) { | |
46 | me.login = null; | |
47 | me.updateLoginData(data); | |
48 | PVE.Utils.checked_command(function() {}); // display subscription status | |
49 | } | |
50 | }); | |
51 | } | |
52 | me.onLogin(null); | |
53 | me.login.show(); | |
54 | }, | |
55 | ||
56 | initComponent : function() { | |
57 | var me = this; | |
58 | ||
59 | Ext.tip.QuickTipManager.init(); | |
60 | ||
61 | // fixme: what about other errors | |
62 | Ext.Ajax.on('requestexception', function(conn, response, options) { | |
63 | if (response.status == 401) { // auth failure | |
64 | me.showLogin(); | |
65 | } | |
66 | }); | |
67 | ||
787ae72a DM |
68 | me.callParent(); |
69 | ||
70 | if (!PVE.Utils.authOK()) { | |
71 | me.showLogin(); | |
72 | } else { | |
73 | if (me.loginData) { | |
74 | me.onLogin(me.loginData); | |
75 | } | |
76 | } | |
77 | ||
78 | Ext.TaskManager.start({ | |
79 | run: function() { | |
80 | var ticket = PVE.Utils.authOK(); | |
81 | if (!ticket || !PVE.UserName) { | |
82 | return; | |
83 | } | |
84 | ||
85 | Ext.Ajax.request({ | |
86 | params: { | |
87 | username: PVE.UserName, | |
88 | password: ticket | |
89 | }, | |
90 | url: '/api2/json/access/ticket', | |
91 | method: 'POST', | |
92 | success: function(response, opts) { | |
93 | var obj = Ext.decode(response.responseText); | |
94 | me.updateLoginData(obj.data); | |
95 | } | |
96 | }); | |
97 | }, | |
98 | interval: 15*60*1000 | |
99 | }); | |
100 | ||
101 | } | |
102 | }); | |
103 | ||
104 | Ext.define('PVE.ConsoleWorkspace', { | |
105 | extend: 'PVE.Workspace', | |
106 | ||
107 | alias: ['widget.pveConsoleWorkspace'], | |
108 | ||
109 | title: gettext('Console'), | |
110 | ||
111 | initComponent : function() { | |
ec0bd652 DC |
112 | // novnc is a string in param |
113 | // but a boolean in content | |
114 | /*jslint confusion: true*/ | |
787ae72a DM |
115 | var me = this; |
116 | ||
117 | var param = Ext.Object.fromQueryString(window.location.search); | |
118 | var consoleType = me.consoleType || param.console; | |
119 | ||
120 | param.novnc = (param.novnc === '1') ? true : false; | |
121 | ||
122 | var content; | |
123 | if (consoleType === 'kvm') { | |
124 | me.title = "VM " + param.vmid; | |
125 | if (param.vmname) { | |
126 | me.title += " ('" + param.vmname + "')"; | |
127 | } | |
128 | content = { | |
129 | xtype: 'pveKVMConsole', | |
130 | novnc: param.novnc, | |
131 | vmid: param.vmid, | |
132 | nodename: param.node, | |
133 | vmname: param.vmname, | |
134 | toplevel: true | |
135 | }; | |
136 | } else if (consoleType === 'lxc') { | |
137 | me.title = "CT " + param.vmid; | |
138 | if (param.vmname) { | |
139 | me.title += " ('" + param.vmname + "')"; | |
140 | } | |
141 | content = { | |
142 | xtype: 'pveLxcConsole', | |
143 | novnc: param.novnc, | |
144 | vmid: param.vmid, | |
145 | nodename: param.node, | |
146 | vmname: param.vmname, | |
147 | toplevel: true | |
148 | }; | |
149 | } else if (consoleType === 'shell') { | |
150 | me.title = "node '" + param.node + "'"; | |
151 | content = { | |
152 | xtype: 'pveShell', | |
153 | novnc: param.novnc, | |
154 | nodename: param.node, | |
155 | toplevel: true | |
156 | }; | |
157 | } else if (consoleType === 'upgrade') { | |
158 | me.title = Ext.String.format(gettext('System upgrade on node {0}'), "'" + param.node + "'"); | |
159 | content = { | |
160 | xtype: 'pveShell', | |
161 | novnc: param.novnc, | |
162 | nodename: param.node, | |
163 | ugradeSystem: true, | |
164 | toplevel: true | |
165 | }; | |
166 | } else { | |
167 | content = { | |
168 | border: false, | |
169 | bodyPadding: 10, | |
170 | html: gettext('Error') + ': No such console type' | |
171 | }; | |
172 | } | |
173 | ||
174 | Ext.apply(me, { | |
175 | layout: { type: 'fit' }, | |
176 | border: false, | |
177 | items: [ content ] | |
178 | }); | |
179 | ||
180 | me.callParent(); | |
181 | } | |
182 | }); | |
183 | ||
184 | Ext.define('PVE.StdWorkspace', { | |
185 | extend: 'PVE.Workspace', | |
186 | ||
187 | alias: ['widget.pveStdWorkspace'], | |
188 | ||
189 | // private | |
190 | setContent: function(comp) { | |
191 | var me = this; | |
192 | ||
193 | var cont = me.child('#content'); | |
834ba9e4 DC |
194 | |
195 | var lay = cont.getLayout(); | |
196 | ||
197 | var cur = lay.getActiveItem(); | |
787ae72a DM |
198 | |
199 | if (comp) { | |
200 | PVE.Utils.setErrorMask(cont, false); | |
201 | comp.border = false; | |
202 | cont.add(comp); | |
834ba9e4 DC |
203 | if (cur !== null && lay.getNext()) { |
204 | lay.next(); | |
205 | var task = Ext.create('Ext.util.DelayedTask', function(){ | |
206 | cont.remove(cur); | |
207 | }); | |
208 | task.delay(10); | |
209 | } | |
210 | } | |
787ae72a DM |
211 | // else { |
212 | // TODO: display something useful | |
213 | ||
214 | // Note:: error mask has wrong zindex, so we do not | |
215 | // use that - see bug 114 | |
216 | // PVE.Utils.setErrorMask(cont, 'nothing selected'); | |
217 | //} | |
218 | }, | |
219 | ||
220 | selectById: function(nodeid) { | |
221 | var me = this; | |
222 | var tree = me.down('pveResourceTree'); | |
223 | tree.selectById(nodeid); | |
224 | }, | |
225 | ||
226 | checkVmMigration: function(record) { | |
227 | var me = this; | |
228 | var tree = me.down('pveResourceTree'); | |
229 | tree.checkVmMigration(record); | |
230 | }, | |
231 | ||
232 | onLogin: function(loginData) { | |
233 | var me = this; | |
234 | ||
235 | me.updateUserInfo(); | |
236 | ||
237 | if (loginData) { | |
238 | PVE.data.ResourceStore.startUpdate(); | |
239 | ||
240 | PVE.Utils.API2Request({ | |
241 | url: '/version', | |
242 | method: 'GET', | |
243 | success: function(response) { | |
244 | PVE.VersionInfo = response.result.data; | |
245 | me.updateVersionInfo(); | |
246 | } | |
247 | }); | |
248 | } | |
249 | }, | |
250 | ||
251 | updateUserInfo: function() { | |
252 | var me = this; | |
253 | ||
254 | var ui = me.query('#userinfo')[0]; | |
255 | ||
256 | if (PVE.UserName) { | |
257 | var msg = Ext.String.format(gettext("You are logged in as {0}"), "'" + PVE.UserName + "'"); | |
258 | ui.update('<div class="x-unselectable" style="white-space:nowrap;">' + msg + '</div>'); | |
259 | } else { | |
260 | ui.update(''); | |
261 | } | |
6a71fe01 | 262 | ui.updateLayout(); |
787ae72a DM |
263 | }, |
264 | ||
265 | updateVersionInfo: function() { | |
266 | var me = this; | |
267 | ||
268 | var ui = me.query('#versioninfo')[0]; | |
269 | ||
270 | if (PVE.VersionInfo) { | |
271 | var version = PVE.VersionInfo.version + '-' + PVE.VersionInfo.release + '/' + | |
272 | PVE.VersionInfo.repoid; | |
f76884fd | 273 | ui.update('Proxmox Virtual Environment ' + version); |
787ae72a | 274 | } else { |
cbf55439 | 275 | ui.update('Proxmox Virtual Environment'); |
787ae72a | 276 | } |
6a71fe01 | 277 | ui.updateLayout(); |
787ae72a DM |
278 | }, |
279 | ||
280 | initComponent : function() { | |
281 | var me = this; | |
282 | ||
283 | Ext.History.init(); | |
284 | ||
285 | var sprovider = Ext.create('PVE.StateProvider'); | |
286 | Ext.state.Manager.setProvider(sprovider); | |
287 | ||
aeb5e2f6 | 288 | var selview = Ext.create('PVE.form.ViewSelector'); |
787ae72a DM |
289 | |
290 | var rtree = Ext.createWidget('pveResourceTree', { | |
291 | viewFilter: selview.getViewFilter(), | |
292 | flex: 1, | |
aeb5e2f6 EK |
293 | selModel: { |
294 | selType: 'treemodel', | |
787ae72a DM |
295 | listeners: { |
296 | selectionchange: function(sm, selected) { | |
297 | var comp; | |
298 | var tlckup = { | |
299 | root: 'PVE.dc.Config', | |
300 | node: 'PVE.node.Config', | |
301 | qemu: 'PVE.qemu.Config', | |
302 | lxc: 'PVE.lxc.Config', | |
303 | storage: 'PVE.storage.Browser', | |
304 | pool: 'pvePoolConfig' | |
305 | }; | |
306 | ||
307 | if (selected.length > 0) { | |
308 | var n = selected[0]; | |
309 | comp = { | |
310 | xtype: tlckup[n.data.type || 'root'] || | |
311 | 'pvePanelConfig', | |
312 | layout: { type: 'fit' }, | |
313 | showSearch: (n.data.id === 'root') || | |
314 | Ext.isDefined(n.data.groupbyid), | |
315 | pveSelNode: n, | |
316 | workspace: me, | |
317 | viewFilter: selview.getViewFilter() | |
318 | }; | |
319 | PVE.curSelectedNode = n; | |
320 | } | |
321 | ||
322 | me.setContent(comp); | |
323 | } | |
324 | } | |
aeb5e2f6 | 325 | } |
787ae72a DM |
326 | }); |
327 | ||
328 | selview.on('select', function(combo, records) { | |
fb387756 | 329 | if (records) { |
787ae72a DM |
330 | var view = combo.getViewFilter(); |
331 | rtree.setViewFilter(view); | |
332 | } | |
333 | }); | |
334 | ||
335 | var caps = sprovider.get('GuiCap'); | |
336 | ||
337 | var createVM = Ext.createWidget('button', { | |
338 | pack: 'end', | |
f01259ee | 339 | margin: '3 5 0 0', |
787ae72a | 340 | baseCls: 'x-btn', |
d1f155b8 | 341 | iconCls: 'fa fa-desktop', |
787ae72a DM |
342 | text: gettext("Create VM"), |
343 | disabled: !caps.vms['VM.Allocate'], | |
344 | handler: function() { | |
345 | var wiz = Ext.create('PVE.qemu.CreateWizard', {}); | |
346 | wiz.show(); | |
347 | } | |
348 | }); | |
349 | ||
350 | var createCT = Ext.createWidget('button', { | |
351 | pack: 'end', | |
f01259ee | 352 | margin: '3 5 0 0', |
787ae72a | 353 | baseCls: 'x-btn', |
d1f155b8 | 354 | iconCls: 'fa fa-cube', |
787ae72a DM |
355 | text: gettext("Create CT"), |
356 | disabled: !caps.vms['VM.Allocate'], | |
357 | handler: function() { | |
358 | var wiz = Ext.create('PVE.lxc.CreateWizard', {}); | |
359 | wiz.show(); | |
360 | } | |
361 | }); | |
362 | ||
363 | sprovider.on('statechange', function(sp, key, value) { | |
364 | if (key === 'GuiCap' && value) { | |
365 | caps = value; | |
366 | createVM.setDisabled(!caps.vms['VM.Allocate']); | |
367 | createCT.setDisabled(!caps.vms['VM.Allocate']); | |
368 | } | |
369 | }); | |
370 | ||
371 | Ext.apply(me, { | |
372 | layout: { type: 'border' }, | |
373 | border: false, | |
374 | items: [ | |
375 | { | |
376 | region: 'north', | |
787ae72a DM |
377 | layout: { |
378 | type: 'hbox', | |
f76884fd | 379 | align: 'middle' |
787ae72a DM |
380 | }, |
381 | baseCls: 'x-plain', | |
382 | defaults: { | |
383 | baseCls: 'x-plain' | |
384 | }, | |
385 | border: false, | |
f76884fd | 386 | margin: '2 0 2 5', |
787ae72a DM |
387 | items: [ |
388 | { | |
787ae72a DM |
389 | html: '<a class="x-unselectable" target=_blank href="http://www.proxmox.com">' + |
390 | '<img height=30 width=209 src="/pve2/images/proxmox_logo.png"/></a>' | |
391 | }, | |
392 | { | |
393 | minWidth: 200, | |
394 | flex: 1, | |
395 | id: 'versioninfo', | |
5fc9bddb | 396 | html: 'Proxmox Virtual Environment' |
787ae72a DM |
397 | }, |
398 | { | |
399 | pack: 'end', | |
f76884fd | 400 | margin: '0 10 0 0', |
787ae72a DM |
401 | id: 'userinfo', |
402 | stateful: false | |
403 | }, | |
6a7465ae EK |
404 | createVM, |
405 | createCT, | |
787ae72a DM |
406 | { |
407 | pack: 'end', | |
f76884fd | 408 | margin: '0 5 0 0', |
787ae72a DM |
409 | xtype: 'button', |
410 | baseCls: 'x-btn', | |
d1f155b8 | 411 | iconCls: 'fa fa-sign-out', |
787ae72a DM |
412 | text: gettext("Logout"), |
413 | handler: function() { | |
414 | PVE.data.ResourceStore.stopUpdate(); | |
415 | me.showLogin(); | |
416 | me.setContent(); | |
417 | var rt = me.down('pveResourceTree'); | |
418 | rt.clearTree(); | |
419 | } | |
6a7465ae | 420 | } |
787ae72a DM |
421 | ] |
422 | }, | |
423 | { | |
424 | region: 'center', | |
425 | id: 'content', | |
426 | xtype: 'container', | |
834ba9e4 | 427 | layout: { type: 'card' }, |
787ae72a DM |
428 | border: false, |
429 | stateful: false, | |
f01259ee | 430 | margin: '0 5 0 0', |
787ae72a DM |
431 | items: [] |
432 | }, | |
433 | { | |
434 | region: 'west', | |
435 | xtype: 'container', | |
436 | border: false, | |
437 | layout: { type: 'vbox', align: 'stretch' }, | |
f01259ee | 438 | margin: '0 0 0 5', |
787ae72a DM |
439 | split: true, |
440 | width: 200, | |
441 | items: [ selview, rtree ] | |
442 | }, | |
443 | { | |
80e8b725 | 444 | xtype: 'pveStatusPanel', |
787ae72a | 445 | region: 'south', |
f01259ee | 446 | margin:'0 5 5 5', |
787ae72a DM |
447 | height: 200, |
448 | split:true | |
449 | } | |
450 | ] | |
451 | }); | |
452 | ||
453 | me.callParent(); | |
454 | ||
455 | me.updateUserInfo(); | |
456 | } | |
457 | }); | |
458 |