]>
Commit | Line | Data |
---|---|---|
37e75d86 TL |
1 | Ext.define('PVE.ceph.CephInstallWizardInfo', { |
2 | extend: 'Ext.panel.Panel', | |
3 | xtype: 'pveCephInstallWizardInfo', | |
4 | ||
5 | html: `<h3>Ceph?</h3> | |
6 | <blockquote cite="https://ceph.com/"><p>"<b>Ceph</b> is a unified, | |
f00da0a5 | 7 | distributed storage system, designed for excellent performance, reliability, |
37e75d86 TL |
8 | and scalability."</p></blockquote> |
9 | <p> | |
f00da0a5 DW |
10 | <b>Ceph</b> is currently <b>not installed</b> on this node. This wizard |
11 | will guide you through the installation. Click on the next button below | |
12 | to begin. After the initial installation, the wizard will offer to create | |
13 | an initial configuration. This configuration step is only | |
37e75d86 TL |
14 | needed once per cluster and will be skipped if a config is already present. |
15 | </p> | |
16 | <p> | |
f00da0a5 DW |
17 | Before starting the installation, please take a look at our documentation, |
18 | by clicking the help button below. If you want to gain deeper knowledge about | |
19 | Ceph, visit <a target="_blank" href="https://docs.ceph.com/en/latest/">ceph.com</a>. | |
37e75d86 TL |
20 | </p>`, |
21 | }); | |
22 | ||
c3035c01 TL |
23 | Ext.define('PVE.ceph.CephVersionSelector', { |
24 | extend: 'Ext.form.field.ComboBox', | |
25 | xtype: 'pveCephVersionSelector', | |
26 | ||
27 | fieldLabel: gettext('Ceph version to install'), | |
28 | ||
29 | displayField: 'display', | |
30 | valueField: 'release', | |
31 | ||
32 | queryMode: 'local', | |
33 | editable: false, | |
34 | forceSelection: true, | |
35 | ||
36 | store: { | |
37 | fields: [ | |
38 | 'release', | |
39 | 'version', | |
40 | { | |
41 | name: 'display', | |
42 | calculate: d => `${d.release} (${d.version})`, | |
43 | }, | |
44 | ], | |
45 | proxy: { | |
46 | type: 'memory', | |
47 | reader: { | |
48 | type: 'json', | |
49 | }, | |
50 | }, | |
51 | data: [ | |
719e95c9 | 52 | { release: "quincy", version: "17.2" }, |
41af7c5e | 53 | { release: "reef", version: "18.2" }, |
c3035c01 TL |
54 | ], |
55 | }, | |
56 | }); | |
57 | ||
58 | Ext.define('PVE.ceph.CephHighestVersionDisplay', { | |
59 | extend: 'Ext.form.field.Display', | |
60 | xtype: 'pveCephHighestVersionDisplay', | |
61 | ||
62 | fieldLabel: gettext('Ceph in the cluster'), | |
63 | ||
64 | value: 'unknown', | |
65 | ||
66 | // called on success with (release, versionTxt, versionParts) | |
67 | gotNewestVersion: Ext.emptyFn, | |
68 | ||
69 | initComponent: function() { | |
70 | let me = this; | |
71 | ||
72 | me.callParent(arguments); | |
73 | ||
74 | Proxmox.Utils.API2Request({ | |
75 | method: 'GET', | |
76 | url: '/cluster/ceph/metadata', | |
77 | params: { | |
78 | scope: 'versions', | |
79 | }, | |
80 | waitMsgTarget: me, | |
81 | success: (response) => { | |
82 | let res = response.result; | |
83 | if (!res || !res.data || !res.data.node) { | |
84 | me.setValue( | |
85 | gettext('Could not detect a ceph installation in the cluster'), | |
86 | ); | |
87 | return; | |
88 | } | |
89 | let nodes = res.data.node; | |
90 | if (me.nodename) { | |
91 | // can happen on ceph purge, we do not yet cleanup old version data | |
92 | delete nodes[me.nodename]; | |
93 | } | |
94 | ||
95 | let maxversion = []; | |
96 | let maxversiontext = ""; | |
436f638d | 97 | for (const [_nodename, data] of Object.entries(nodes)) { |
c3035c01 TL |
98 | let version = data.version.parts; |
99 | if (PVE.Utils.compare_ceph_versions(version, maxversion) > 0) { | |
100 | maxversion = version; | |
101 | maxversiontext = data.version.str; | |
102 | } | |
103 | } | |
104 | // FIXME: get from version selector store | |
105 | const major2release = { | |
106 | 13: 'luminous', | |
107 | 14: 'nautilus', | |
108 | 15: 'octopus', | |
109 | 16: 'pacific', | |
719e95c9 | 110 | 17: 'quincy', |
fa3dfb1c | 111 | 18: 'reef', |
8b4f1178 | 112 | 19: 'squid', |
c3035c01 TL |
113 | }; |
114 | let release = major2release[maxversion[0]] || 'unknown'; | |
115 | let newestVersionTxt = `${Ext.String.capitalize(release)} (${maxversiontext})`; | |
116 | ||
117 | if (release === 'unknown') { | |
118 | me.setValue( | |
119 | gettext('Could not detect a ceph installation in the cluster'), | |
120 | ); | |
121 | } else { | |
122 | me.setValue(Ext.String.format( | |
123 | gettext('Newest ceph version in cluster is {0}'), | |
124 | newestVersionTxt, | |
125 | )); | |
126 | } | |
127 | me.gotNewestVersion(release, maxversiontext, maxversion); | |
128 | }, | |
129 | failure: function(response, opts) { | |
130 | Ext.Msg.alert(gettext('Error'), response.htmlStatus); | |
f6710aac | 131 | }, |
c3035c01 TL |
132 | }); |
133 | }, | |
134 | }); | |
135 | ||
4616a55b | 136 | Ext.define('PVE.ceph.CephInstallWizard', { |
80fdf8d2 TL |
137 | extend: 'PVE.window.Wizard', |
138 | alias: 'widget.pveCephInstallWizard', | |
139 | mixins: ['Proxmox.Mixin.CBind'], | |
37e75d86 | 140 | |
80fdf8d2 TL |
141 | resizable: false, |
142 | nodename: undefined, | |
37e75d86 | 143 | |
35ff09a4 TL |
144 | width: 760, // 4:3 |
145 | height: 570, | |
146 | ||
80fdf8d2 TL |
147 | viewModel: { |
148 | data: { | |
149 | nodename: '', | |
39d58bb5 | 150 | cephRelease: 'reef', |
b686fd37 | 151 | cephRepo: 'enterprise', |
80fdf8d2 TL |
152 | configuration: true, |
153 | isInstalled: false, | |
e6a1160f TL |
154 | nodeHasSubscription: true, // avoid warning hint until fully loaded |
155 | allHaveSubscription: true, // avoid warning hint until fully loaded | |
156 | }, | |
157 | formulas: { | |
158 | repoHintHidden: get => get('allHaveSubscription') && get('cephRepo') === 'enterprise', | |
159 | repoHint: function(get) { | |
160 | let repo = get('cephRepo'); | |
161 | let nodeSub = get('nodeHasSubscription'), allSub = get('allHaveSubscription'); | |
162 | ||
163 | if (repo === 'enterprise') { | |
164 | if (!nodeSub) { | |
165 | return gettext('The enterprise repository is enabled, but there is no active subscription!'); | |
166 | } else if (!allSub) { | |
e6a1160f TL |
167 | return gettext('Not all nodes have an active subscription, which is required for cluster-wide enterprise repo access'); |
168 | } | |
169 | return ''; // should be hidden | |
170 | } else if (repo === 'no-subscription') { | |
171 | return allSub | |
172 | ? gettext("Cluster has active subscriptions and would be elligible for using the enterprise repository.") | |
173 | : gettext("The no-subscription repository is not the best choice for production setups."); | |
174 | } else { | |
175 | return gettext('The test repository should only be used for test setups or after consulting the official Proxmox support!'); | |
176 | } | |
177 | }, | |
f6710aac | 178 | }, |
80fdf8d2 TL |
179 | }, |
180 | cbindData: { | |
f6710aac | 181 | nodename: undefined, |
80fdf8d2 | 182 | }, |
37e75d86 | 183 | |
80fdf8d2 TL |
184 | title: gettext('Setup'), |
185 | navigateNext: function() { | |
186 | var tp = this.down('#wizcontent'); | |
187 | var atab = tp.getActiveTab(); | |
8ba2d669 | 188 | |
80fdf8d2 TL |
189 | var next = tp.items.indexOf(atab) + 1; |
190 | var ntab = tp.items.getAt(next); | |
191 | if (ntab) { | |
192 | ntab.enable(); | |
193 | tp.setActiveTab(ntab); | |
194 | } | |
195 | }, | |
8058410f | 196 | setInitialTab: function(index) { |
80fdf8d2 TL |
197 | var tp = this.down('#wizcontent'); |
198 | var initialTab = tp.items.getAt(index); | |
199 | initialTab.enable(); | |
200 | tp.setActiveTab(initialTab); | |
201 | }, | |
202 | onShow: function() { | |
cd56fd55 | 203 | this.callParent(arguments); |
e6a1160f | 204 | let viewModel = this.getViewModel(); |
cd56fd55 TL |
205 | var isInstalled = this.getViewModel().get('isInstalled'); |
206 | if (isInstalled) { | |
e6a1160f | 207 | viewModel.set('configuration', false); |
cd56fd55 TL |
208 | this.setInitialTab(2); |
209 | } | |
e6a1160f TL |
210 | |
211 | PVE.Utils.getClusterSubscriptionLevel().then(subcriptionMap => { | |
212 | viewModel.set('nodeHasSubscription', !!subcriptionMap[this.nodename]); | |
213 | ||
214 | let allHaveSubscription = Object.values(subcriptionMap).every(level => !!level); | |
215 | viewModel.set('allHaveSubscription', allHaveSubscription); | |
216 | }); | |
80fdf8d2 TL |
217 | }, |
218 | items: [ | |
219 | { | |
220 | xtype: 'panel', | |
221 | title: gettext('Info'), | |
222 | viewModel: {}, // needed to inherit parent viewModel data | |
223 | border: false, | |
224 | bodyBorder: false, | |
225 | onlineHelp: 'chapter_pveceph', | |
226 | layout: { | |
227 | type: 'vbox', | |
228 | align: 'stretch', | |
229 | }, | |
230 | defaults: { | |
4616a55b TM |
231 | border: false, |
232 | bodyBorder: false, | |
80fdf8d2 TL |
233 | }, |
234 | items: [ | |
235 | { | |
236 | xtype: 'pveCephInstallWizardInfo', | |
37e75d86 | 237 | }, |
80fdf8d2 TL |
238 | { |
239 | flex: 1, | |
37e75d86 | 240 | }, |
e6a1160f TL |
241 | { |
242 | xtype: 'displayfield', | |
243 | fieldLabel: gettext('Hint'), | |
4bbd64a2 | 244 | labelClsExtra: 'pmx-hint', |
e6a1160f TL |
245 | submitValue: false, |
246 | labelWidth: 50, | |
247 | bind: { | |
248 | value: '{repoHint}', | |
249 | hidden: '{repoHintHidden}', | |
250 | }, | |
251 | }, | |
80fdf8d2 TL |
252 | { |
253 | xtype: 'pveCephHighestVersionDisplay', | |
b686fd37 | 254 | labelWidth: 150, |
8058410f | 255 | cbind: { |
f6710aac | 256 | nodename: '{nodename}', |
37e75d86 | 257 | }, |
80fdf8d2 TL |
258 | gotNewestVersion: function(release, maxversiontext, maxversion) { |
259 | if (release === 'unknown') { | |
260 | return; | |
261 | } | |
262 | let wizard = this.up('pveCephInstallWizard'); | |
263 | wizard.getViewModel().set('cephRelease', release); | |
c3035c01 | 264 | }, |
80fdf8d2 TL |
265 | }, |
266 | { | |
b686fd37 TL |
267 | xtype: 'container', |
268 | layout: 'hbox', | |
269 | defaults: { | |
270 | border: false, | |
271 | layout: 'anchor', | |
272 | flex: 1, | |
80fdf8d2 | 273 | }, |
b686fd37 TL |
274 | items: [{ |
275 | xtype: 'pveCephVersionSelector', | |
276 | labelWidth: 150, | |
277 | padding: '0 10 0 0', | |
278 | submitValue: false, | |
279 | bind: { | |
280 | value: '{cephRelease}', | |
281 | }, | |
282 | listeners: { | |
283 | change: function(field, release) { | |
284 | let wizard = this.up('pveCephInstallWizard'); | |
285 | wizard.down('#next').setText( | |
286 | Ext.String.format(gettext('Start {0} installation'), release), | |
287 | ); | |
288 | }, | |
c3035c01 TL |
289 | }, |
290 | }, | |
b686fd37 TL |
291 | { |
292 | xtype: 'proxmoxKVComboBox', | |
293 | fieldLabel: gettext('Repository'), | |
294 | padding: '0 0 0 10', | |
295 | comboItems: [ | |
296 | ['enterprise', gettext('Enterprise (recommended)')], | |
297 | ['no-subscription', gettext('No-Subscription')], | |
298 | ['test', gettext('Test')], | |
299 | ], | |
300 | labelWidth: 150, | |
301 | submitValue: false, | |
302 | value: 'enterprise', | |
303 | bind: { | |
304 | value: '{cephRepo}', | |
305 | }, | |
306 | }], | |
80fdf8d2 TL |
307 | }, |
308 | ], | |
309 | listeners: { | |
310 | activate: function() { | |
311 | // notify owning container that it should display a help button | |
312 | if (this.onlineHelp) { | |
313 | Ext.GlobalEvents.fireEvent('proxmoxShowHelp', this.onlineHelp); | |
314 | } | |
315 | let wizard = this.up('pveCephInstallWizard'); | |
316 | let release = wizard.getViewModel().get('cephRelease'); | |
317 | wizard.down('#back').hide(true); | |
318 | wizard.down('#next').setText( | |
319 | Ext.String.format(gettext('Start {0} installation'), release), | |
320 | ); | |
321 | }, | |
322 | deactivate: function() { | |
323 | if (this.onlineHelp) { | |
324 | Ext.GlobalEvents.fireEvent('proxmoxHideHelp', this.onlineHelp); | |
325 | } | |
326 | this.up('pveCephInstallWizard').down('#next').setText(gettext('Next')); | |
f6710aac TL |
327 | }, |
328 | }, | |
80fdf8d2 TL |
329 | }, |
330 | { | |
331 | title: gettext('Installation'), | |
332 | xtype: 'panel', | |
333 | layout: 'fit', | |
8058410f | 334 | cbind: { |
f6710aac | 335 | nodename: '{nodename}', |
80fdf8d2 TL |
336 | }, |
337 | viewModel: {}, // needed to inherit parent viewModel data | |
338 | listeners: { | |
339 | afterrender: function() { | |
340 | var me = this; | |
341 | if (this.getViewModel().get('isInstalled')) { | |
f6710aac | 342 | this.mask("Ceph is already installed, click next to create your configuration.", ['pve-static-mask']); |
80fdf8d2 TL |
343 | } else { |
344 | me.down('pveNoVncConsole').fireEvent('activate'); | |
345 | } | |
346 | }, | |
347 | activate: function() { | |
348 | let me = this; | |
349 | const nodename = me.nodename; | |
350 | me.updateStore = Ext.create('Proxmox.data.UpdateStore', { | |
351 | storeid: 'ceph-status-' + nodename, | |
352 | interval: 1000, | |
353 | proxy: { | |
354 | type: 'proxmox', | |
f6710aac | 355 | url: '/api2/json/nodes/' + nodename + '/ceph/status', |
c3035c01 TL |
356 | }, |
357 | listeners: { | |
80fdf8d2 | 358 | load: function(rec, response, success, operation) { |
80fdf8d2 TL |
359 | if (success) { |
360 | me.updateStore.stopUpdate(); | |
361 | me.down('textfield').setValue('success'); | |
362 | } else if (operation.error.statusText.match("not initialized", "i")) { | |
363 | me.updateStore.stopUpdate(); | |
f6710aac | 364 | me.up('pveCephInstallWizard').getViewModel().set('configuration', false); |
80fdf8d2 TL |
365 | me.down('textfield').setValue('success'); |
366 | } else if (operation.error.statusText.match("rados_connect failed", "i")) { | |
367 | me.updateStore.stopUpdate(); | |
f6710aac | 368 | me.up('pveCephInstallWizard').getViewModel().set('configuration', true); |
80fdf8d2 TL |
369 | me.down('textfield').setValue('success'); |
370 | } else if (!operation.error.statusText.match("not installed", "i")) { | |
371 | Proxmox.Utils.setErrorMask(me, operation.error.statusText); | |
372 | } | |
f6710aac TL |
373 | }, |
374 | }, | |
80fdf8d2 TL |
375 | }); |
376 | me.updateStore.startUpdate(); | |
377 | }, | |
378 | destroy: function() { | |
379 | var me = this; | |
380 | if (me.updateStore) { | |
381 | me.updateStore.stopUpdate(); | |
4616a55b | 382 | } |
f6710aac | 383 | }, |
4616a55b | 384 | }, |
80fdf8d2 TL |
385 | items: [ |
386 | { | |
387 | xtype: 'pveNoVncConsole', | |
388 | itemId: 'jsconsole', | |
389 | consoleType: 'cmd', | |
390 | xtermjs: true, | |
391 | cbind: { | |
392 | nodename: '{nodename}', | |
4616a55b | 393 | }, |
80fdf8d2 | 394 | beforeLoad: function() { |
c3035c01 | 395 | let me = this; |
80fdf8d2 TL |
396 | let wizard = me.up('pveCephInstallWizard'); |
397 | let release = wizard.getViewModel().get('cephRelease'); | |
b686fd37 TL |
398 | let repo = wizard.getViewModel().get('cephRepo'); |
399 | me.cmdOpts = `--version\0${release}\0--repository\0${repo}`; | |
4616a55b | 400 | }, |
80fdf8d2 | 401 | cmd: 'ceph_install', |
4616a55b | 402 | }, |
80fdf8d2 TL |
403 | { |
404 | xtype: 'textfield', | |
405 | name: 'installSuccess', | |
406 | value: '', | |
407 | allowBlank: false, | |
408 | submitValue: false, | |
f6710aac TL |
409 | hidden: true, |
410 | }, | |
411 | ], | |
80fdf8d2 TL |
412 | }, |
413 | { | |
414 | xtype: 'inputpanel', | |
415 | title: gettext('Configuration'), | |
416 | onlineHelp: 'chapter_pveceph', | |
5839e002 | 417 | height: 300, |
80fdf8d2 | 418 | cbind: { |
f6710aac | 419 | nodename: '{nodename}', |
4616a55b | 420 | }, |
80fdf8d2 TL |
421 | viewModel: { |
422 | data: { | |
423 | replicas: undefined, | |
f6710aac TL |
424 | minreplicas: undefined, |
425 | }, | |
80fdf8d2 TL |
426 | }, |
427 | listeners: { | |
428 | activate: function() { | |
429 | this.up('pveCephInstallWizard').down('#submit').setText(gettext('Next')); | |
4616a55b | 430 | }, |
5839e002 | 431 | afterrender: function() { |
80fdf8d2 | 432 | if (this.up('pveCephInstallWizard').getViewModel().get('configuration')) { |
f6710aac | 433 | this.mask("Configuration already initialized", ['pve-static-mask']); |
80fdf8d2 TL |
434 | } else { |
435 | this.unmask(); | |
836d66f7 TM |
436 | } |
437 | }, | |
80fdf8d2 TL |
438 | deactivate: function() { |
439 | this.up('pveCephInstallWizard').down('#submit').setText(gettext('Finish')); | |
f6710aac | 440 | }, |
80fdf8d2 TL |
441 | }, |
442 | column1: [ | |
443 | { | |
444 | xtype: 'displayfield', | |
f6710aac | 445 | value: gettext('Ceph cluster configuration') + ':', |
80fdf8d2 TL |
446 | }, |
447 | { | |
448 | xtype: 'proxmoxNetworkSelector', | |
449 | name: 'network', | |
450 | value: '', | |
451 | fieldLabel: 'Public Network IP/CIDR', | |
5f7f0095 | 452 | autoSelect: false, |
80fdf8d2 | 453 | bind: { |
f6710aac | 454 | allowBlank: '{configuration}', |
8ba2d669 | 455 | }, |
80fdf8d2 | 456 | cbind: { |
f6710aac TL |
457 | nodename: '{nodename}', |
458 | }, | |
4616a55b | 459 | }, |
80fdf8d2 TL |
460 | { |
461 | xtype: 'proxmoxNetworkSelector', | |
462 | name: 'cluster-network', | |
463 | fieldLabel: 'Cluster Network IP/CIDR', | |
464 | allowBlank: true, | |
465 | autoSelect: false, | |
466 | emptyText: gettext('Same as Public Network'), | |
467 | cbind: { | |
f6710aac TL |
468 | nodename: '{nodename}', |
469 | }, | |
470 | }, | |
80fdf8d2 TL |
471 | // FIXME: add hint about cluster network and/or reference user to docs?? |
472 | ], | |
473 | column2: [ | |
474 | { | |
475 | xtype: 'displayfield', | |
f6710aac | 476 | value: gettext('First Ceph monitor') + ':', |
80fdf8d2 TL |
477 | }, |
478 | { | |
f25c3855 | 479 | xtype: 'displayfield', |
80fdf8d2 | 480 | fieldLabel: gettext('Monitor node'), |
f25c3855 AL |
481 | cbind: { |
482 | value: '{nodename}', | |
483 | }, | |
80fdf8d2 TL |
484 | }, |
485 | { | |
486 | xtype: 'displayfield', | |
487 | value: gettext('Additional monitors are recommended. They can be created at any time in the Monitor tab.'), | |
f6710aac TL |
488 | userCls: 'pmx-hint', |
489 | }, | |
80fdf8d2 TL |
490 | ], |
491 | advancedColumn1: [ | |
492 | { | |
493 | xtype: 'numberfield', | |
494 | name: 'size', | |
495 | fieldLabel: 'Number of replicas', | |
496 | bind: { | |
f6710aac | 497 | value: '{replicas}', |
4616a55b | 498 | }, |
80fdf8d2 TL |
499 | maxValue: 7, |
500 | minValue: 2, | |
f6710aac | 501 | emptyText: '3', |
80fdf8d2 TL |
502 | }, |
503 | { | |
504 | xtype: 'numberfield', | |
505 | name: 'min_size', | |
506 | fieldLabel: 'Minimum replicas', | |
507 | bind: { | |
508 | maxValue: '{replicas}', | |
f6710aac | 509 | value: '{minreplicas}', |
4616a55b | 510 | }, |
80fdf8d2 TL |
511 | minValue: 2, |
512 | maxValue: 3, | |
513 | setMaxValue: function(value) { | |
514 | this.maxValue = Ext.Number.from(value, 2); | |
515 | // allow enough to avoid split brains with max 'size', but more makes simply no sense | |
516 | if (this.maxValue > 4) { | |
517 | this.maxValue = 4; | |
a19aa238 | 518 | } |
80fdf8d2 TL |
519 | this.toggleSpinners(); |
520 | this.validate(); | |
71798b4b | 521 | }, |
f6710aac TL |
522 | emptyText: '2', |
523 | }, | |
80fdf8d2 TL |
524 | ], |
525 | onGetValues: function(values) { | |
526 | ['cluster-network', 'size', 'min_size'].forEach(function(field) { | |
527 | if (!values[field]) { | |
528 | delete values[field]; | |
8ba2d669 | 529 | } |
80fdf8d2 TL |
530 | }); |
531 | return values; | |
532 | }, | |
533 | onSubmit: function() { | |
534 | var me = this; | |
535 | if (!this.up('pveCephInstallWizard').getViewModel().get('configuration')) { | |
536 | var wizard = me.up('window'); | |
537 | var kv = wizard.getValues(); | |
399ffa76 | 538 | delete kv.delete; |
80fdf8d2 TL |
539 | var nodename = me.nodename; |
540 | delete kv.nodename; | |
541 | Proxmox.Utils.API2Request({ | |
f8b7b9e1 | 542 | url: `/nodes/${nodename}/ceph/init`, |
80fdf8d2 TL |
543 | waitMsgTarget: wizard, |
544 | method: 'POST', | |
545 | params: kv, | |
546 | success: function() { | |
547 | Proxmox.Utils.API2Request({ | |
f25c3855 | 548 | url: `/nodes/${nodename}/ceph/mon/${nodename}`, |
80fdf8d2 TL |
549 | waitMsgTarget: wizard, |
550 | method: 'POST', | |
551 | success: function() { | |
552 | me.up('pveCephInstallWizard').navigateNext(); | |
553 | }, | |
554 | failure: function(response, opts) { | |
555 | Ext.Msg.alert(gettext('Error'), response.htmlStatus); | |
f6710aac | 556 | }, |
80fdf8d2 | 557 | }); |
8134b6b7 | 558 | }, |
80fdf8d2 TL |
559 | failure: function(response, opts) { |
560 | Ext.Msg.alert(gettext('Error'), response.htmlStatus); | |
f6710aac | 561 | }, |
4616a55b | 562 | }); |
80fdf8d2 TL |
563 | } else { |
564 | me.up('pveCephInstallWizard').navigateNext(); | |
4616a55b | 565 | } |
f6710aac | 566 | }, |
80fdf8d2 TL |
567 | }, |
568 | { | |
569 | title: gettext('Success'), | |
570 | xtype: 'panel', | |
571 | border: false, | |
572 | bodyBorder: false, | |
573 | onlineHelp: 'pve_ceph_install', | |
574 | html: '<h3>Installation successful!</h3>'+ | |
f00da0a5 | 575 | '<p>The basic installation and configuration is complete. Depending on your setup, some of the following steps are required to start using Ceph:</p>'+ |
80fdf8d2 TL |
576 | '<ol><li>Install Ceph on other nodes</li>'+ |
577 | '<li>Create additional Ceph Monitors</li>'+ | |
578 | '<li>Create Ceph OSDs</li>'+ | |
579 | '<li>Create Ceph Pools</li></ol>'+ | |
f00da0a5 | 580 | '<p>To learn more, click on the help button below.</p>', |
80fdf8d2 TL |
581 | listeners: { |
582 | activate: function() { | |
583 | // notify owning container that it should display a help button | |
584 | if (this.onlineHelp) { | |
585 | Ext.GlobalEvents.fireEvent('proxmoxShowHelp', this.onlineHelp); | |
586 | } | |
4616a55b | 587 | |
80fdf8d2 TL |
588 | var tp = this.up('#wizcontent'); |
589 | var idx = tp.items.indexOf(this)-1; | |
8058410f | 590 | for (;idx >= 0; idx--) { |
80fdf8d2 TL |
591 | var nc = tp.items.getAt(idx); |
592 | if (nc) { | |
593 | nc.disable(); | |
4616a55b TM |
594 | } |
595 | } | |
596 | }, | |
80fdf8d2 TL |
597 | deactivate: function() { |
598 | if (this.onlineHelp) { | |
599 | Ext.GlobalEvents.fireEvent('proxmoxHideHelp', this.onlineHelp); | |
600 | } | |
f6710aac | 601 | }, |
80fdf8d2 TL |
602 | }, |
603 | onSubmit: function() { | |
604 | var wizard = this.up('pveCephInstallWizard'); | |
605 | wizard.close(); | |
f6710aac TL |
606 | }, |
607 | }, | |
608 | ], | |
c3035c01 | 609 | }); |