]> git.proxmox.com Git - pve-manager.git/blob - www/manager6/ceph/CephInstallWizard.js
followup: reduce wording, less text has better chance to be read
[pve-manager.git] / www / manager6 / ceph / CephInstallWizard.js
1 /*jslint confusion: true*/
2 Ext.define('PVE.ceph.CephInstallWizard', {
3 extend: 'PVE.window.Wizard',
4 alias: 'widget.pveCephInstallWizard',
5 mixins: ['Proxmox.Mixin.CBind'],
6 resizable: false,
7 nodename: undefined,
8 viewModel: {
9 data: {
10 nodename: '',
11 configuration: true,
12 isInstalled: false
13 }
14 },
15 cbindData: {
16 nodename: undefined
17 },
18 title: gettext('Setup'),
19 navigateNext: function() {
20 var tp = this.down('#wizcontent');
21 var atab = tp.getActiveTab();
22
23 var next = tp.items.indexOf(atab) + 1;
24 var ntab = tp.items.getAt(next);
25 if (ntab) {
26 ntab.enable();
27 tp.setActiveTab(ntab);
28 }
29 },
30 setInitialTab: function (index) {
31 var tp = this.down('#wizcontent');
32 var initialTab = tp.items.getAt(index);
33 initialTab.enable();
34 tp.setActiveTab(initialTab);
35 },
36 onShow: function() {
37 this.callParent(arguments);
38 var isInstalled = this.getViewModel().get('isInstalled');
39 if (isInstalled) {
40 this.getViewModel().set('configuration', false);
41 this.setInitialTab(2);
42 }
43 },
44 items: [
45 {
46 title: gettext('Info'),
47 xtype: 'panel',
48 border: false,
49 bodyBorder: false,
50 onlineHelp: 'chapter_pveceph',
51 html: '<h3>Ceph?</h3>'+
52 '<blockquote cite="https://ceph.com/"><p>"<b>Ceph</b> is a unified, distributed storage system designed for excellent performance, reliability and scalability."</p></blockquote>'+
53 '<p><b>Ceph</b> is currently <b>not installed</b> on this node, click on the next button below to start the installation.'+
54 ' This wizard will guide you through the necessary steps, after the initial installation you will be offered to create a initial configuration.'+
55 ' The configuration step is only needed once per cluster and will be skipped if a config is already present.</p>'+
56 '<p>Please take a look at our documentation, by clicking the help button below, before starting the installation, if you want to gain deeper knowledge about Ceph visit <a href="http://docs.ceph.com/docs/master/">ceph.com</a>.</p>',
57 listeners: {
58 activate: function() {
59 // notify owning container that it should display a help button
60 if (this.onlineHelp) {
61 Ext.GlobalEvents.fireEvent('proxmoxShowHelp', this.onlineHelp);
62 }
63 this.up('pveCephInstallWizard').down('#back').hide(true);
64 this.up('pveCephInstallWizard').down('#next').setText(gettext('Start installation'));
65 },
66 deactivate: function() {
67 if (this.onlineHelp) {
68 Ext.GlobalEvents.fireEvent('proxmoxHideHelp', this.onlineHelp);
69 }
70 this.up('pveCephInstallWizard').down('#next').setText(gettext('Next'));
71 }
72 }
73 },
74 {
75 title: gettext('Installation'),
76 xtype: 'panel',
77 layout: 'fit',
78 cbind:{
79 nodename: '{nodename}'
80 },
81 viewModel: {}, // needed to inherit parent viewModel data
82 listeners: {
83 afterrender: function() {
84 var me = this;
85 if (this.getViewModel().get('isInstalled')) {
86 this.mask("Ceph is already installed, click next to create your configuration.",['pve-static-mask']);
87 } else {
88 me.down('pveNoVncConsole').fireEvent('activate');
89 }
90 },
91 activate: function() {
92 var me = this;
93 var nodename = me.nodename;
94 me.updateStore = Ext.create('Proxmox.data.UpdateStore', {
95 storeid: 'ceph-status-' + nodename,
96 interval: 1000,
97 proxy: {
98 type: 'proxmox',
99 url: '/api2/json/nodes/' + nodename + '/ceph/status'
100 },
101 listeners: {
102 load: function(rec, response, success, operation) {
103
104 if (success) {
105 me.updateStore.stopUpdate();
106 me.down('textfield').setValue('success');
107 } else if (operation.error.statusText.match("not initialized", "i")) {
108 me.updateStore.stopUpdate();
109 me.up('pveCephInstallWizard').getViewModel().set('configuration',false);
110 me.down('textfield').setValue('success');
111 } else if (operation.error.statusText.match("rados_connect failed", "i")) {
112 me.updateStore.stopUpdate();
113 me.up('pveCephInstallWizard').getViewModel().set('configuration',true);
114 me.down('textfield').setValue('success');
115 } else if (!operation.error.statusText.match("not installed", "i")) {
116 Proxmox.Utils.setErrorMask(me, operation.error.statusText);
117 }
118 }
119 }
120 });
121 me.updateStore.startUpdate();
122 },
123 destroy: function() {
124 var me = this;
125 if (me.updateStore) {
126 me.updateStore.stopUpdate();
127 }
128 }
129 },
130 items: [
131 {
132 itemId: 'jsconsole',
133 consoleType: 'cmd',
134 xtermjs: true,
135 xtype: 'pveNoVncConsole',
136 cbind:{
137 nodename: '{nodename}'
138 },
139 cmd: 'ceph_install'
140 },
141 {
142 xtype: 'textfield',
143 name: 'installSuccess',
144 value: '',
145 allowBlank: false,
146 submitValue: false,
147 hidden: true
148 }
149 ]
150 },
151 {
152 xtype: 'inputpanel',
153 title: gettext('Configuration'),
154 onlineHelp: 'chapter_pveceph',
155 cbind: {
156 nodename: '{nodename}'
157 },
158 viewModel: {
159 data: {
160 replicas: undefined,
161 minreplicas: undefined
162 }
163 },
164 listeners: {
165 activate: function() {
166 this.up('pveCephInstallWizard').down('#submit').setText(gettext('Next'));
167 },
168 beforeshow: function() {
169 if (this.up('pveCephInstallWizard').getViewModel().get('configuration')) {
170 this.mask("Coniguration already initialized",['pve-static-mask']);
171 } else {
172 this.unmask();
173 }
174 },
175 deactivate: function() {
176 this.up('pveCephInstallWizard').down('#submit').setText(gettext('Finish'));
177 }
178 },
179 column1: [
180 {
181 xtype: 'displayfield',
182 value: gettext('Ceph cluster configuration') + ':'
183 },
184 {
185 xtype: 'textfield',
186 name: 'network',
187 vtype: 'IPCIDRAddress',
188 value: '',
189 fieldLabel: 'Public Network IP/CIDR',
190 bind: {
191 allowBlank: '{configuration}'
192 },
193 setAllowBlank: function(allowBlank) {
194 this.allowBlank = allowBlank;
195 this.validate();
196 }
197 },
198 {
199 xtype: 'textfield',
200 name: 'cluster-network',
201 vtype: 'IPCIDRAddress',
202 fieldLabel: 'Cluster Network IP/CIDR',
203 allowBlank: true,
204 emptyText: gettext('Same as Public Network')
205 }
206 // FIXME: add hint about cluster network and/or reference user to docs??
207 ],
208 column2: [
209 {
210 xtype: 'displayfield',
211 value: gettext('First Ceph monitor') + ':'
212 },
213 {
214 xtype: 'pveNodeSelector',
215 fieldLabel: gettext('Monitor node'),
216 name: 'mon-node',
217 selectCurNode: true,
218 allowBlank: false
219 },
220 {
221 xtype: 'displayfield',
222 value: gettext('Additional monitors are recommended. They can be created at any time in the Monitor tab.'),
223 userCls: 'pve-hint'
224 }
225 ],
226 advancedColumn1: [
227 {
228 xtype: 'numberfield',
229 name: 'size',
230 fieldLabel: 'Number of replicas',
231 bind: {
232 value: '{replicas}'
233 },
234 maxValue: 7,
235 minValue: 2,
236 emptyText: '3'
237 },
238 {
239 xtype: 'numberfield',
240 name: 'min_size',
241 fieldLabel: 'Minimum replicas',
242 bind: {
243 maxValue: '{replicas}',
244 value: '{minreplicas}'
245 },
246 minValue: 2,
247 maxValue: 3,
248 setMaxValue: function(value) {
249 this.maxValue = Ext.Number.from(value, 2);
250 // allow enough to avoid split brains with max 'size', but more makes simply no sense
251 if (this.maxValue > 4) {
252 this.maxValue = 4;
253 }
254 this.toggleSpinners();
255 this.validate();
256 },
257 emptyText: '2'
258 }
259 ],
260 onGetValues: function(values) {
261 ['cluster-network', 'size', 'min_size'].forEach(function(field) {
262 if (!values[field]) {
263 delete values[field];
264 }
265 });
266 return values;
267 },
268 onSubmit: function() {
269 var me = this;
270 if (!this.up('pveCephInstallWizard').getViewModel().get('configuration')) {
271 var wizard = me.up('window');
272 var kv = wizard.getValues();
273 delete kv['delete'];
274 var monNode = kv['mon-node'];
275 delete kv['mon-node'];
276 var nodename = me.nodename;
277 delete kv.nodename;
278 Proxmox.Utils.API2Request({
279 url: '/nodes/' + nodename + '/ceph/init',
280 waitMsgTarget: wizard,
281 method: 'POST',
282 params: kv,
283 success: function() {
284 Proxmox.Utils.API2Request({
285 url: '/nodes/' + monNode + '/ceph/mon',
286 waitMsgTarget: wizard,
287 method: 'POST',
288 success: function() {
289 me.up('pveCephInstallWizard').navigateNext();
290 },
291 failure: function(response, opts) {
292 Ext.Msg.alert(gettext('Error'), response.htmlStatus);
293 }
294 });
295 },
296 failure: function(response, opts) {
297 Ext.Msg.alert(gettext('Error'), response.htmlStatus);
298 }
299 });
300
301 } else {
302 me.up('pveCephInstallWizard').navigateNext();
303 }
304 }
305 },
306 {
307 title: gettext('Success'),
308 xtype: 'panel',
309 border: false,
310 bodyBorder: false,
311 onlineHelp: 'pve_ceph_install',
312 html: '<h3>Installation successful!</h3>'+
313 '<p>The basic installation and configuration is completed, depending on your setup some of the following steps are required to start using Ceph:</p>'+
314 '<ol><li>Install Ceph on other nodes</li>'+
315 '<li>Create additional Ceph Monitors</li>'+
316 '<li>Create Ceph OSDs</li>'+
317 '<li>Create Ceph Pools</li></ol>'+
318 '<p>To learn more click on the help button below.</p>',
319 listeners: {
320 activate: function() {
321 // notify owning container that it should display a help button
322 if (this.onlineHelp) {
323 Ext.GlobalEvents.fireEvent('proxmoxShowHelp', this.onlineHelp);
324 }
325
326 var tp = this.up('#wizcontent');
327 var idx = tp.items.indexOf(this)-1;
328 for(;idx >= 0;idx--) {
329 var nc = tp.items.getAt(idx);
330 if (nc) {
331 nc.disable();
332 }
333 }
334 },
335 deactivate: function() {
336 if (this.onlineHelp) {
337 Ext.GlobalEvents.fireEvent('proxmoxHideHelp', this.onlineHelp);
338 }
339 }
340 },
341 onSubmit: function() {
342 var wizard = this.up('pveCephInstallWizard');
343 wizard.close();
344 }
345 }
346 ]
347 });