]>
git.proxmox.com Git - pve-manager.git/blob - www/manager6/ceph/CephInstallWizard.js
1 Ext
. define ( 'PVE.ceph.CephInstallWizardInfo' , {
2 extend
: 'Ext.panel.Panel' ,
3 xtype
: 'pveCephInstallWizardInfo' ,
6 <blockquote cite="https://ceph.com/"><p>"<b>Ceph</b> is a unified,
7 distributed storage system, designed for excellent performance, reliability,
8 and scalability."</p></blockquote>
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
14 needed once per cluster and will be skipped if a config is already present.
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>.
23 Ext
. define ( 'PVE.ceph.CephVersionSelector' , {
24 extend
: 'Ext.form.field.ComboBox' ,
25 xtype
: 'pveCephVersionSelector' ,
27 fieldLabel
: gettext ( 'Ceph version to install' ),
29 displayField
: 'display' ,
30 valueField
: 'release' ,
42 calculate
: d
=> ` ${d.release} ( ${d.version} )` ,
52 { release
: "octopus" , version
: "15.2" },
53 { release
: "pacific" , version
: "16.2" },
58 Ext
. define ( 'PVE.ceph.CephHighestVersionDisplay' , {
59 extend
: 'Ext.form.field.Display' ,
60 xtype
: 'pveCephHighestVersionDisplay' ,
62 fieldLabel
: gettext ( 'Ceph in the cluster' ),
66 // called on success with (release, versionTxt, versionParts)
67 gotNewestVersion
: Ext
. emptyFn
,
69 initComponent : function () {
72 me
. callParent ( arguments
);
74 Proxmox
. Utils
. API2Request ({
76 url
: '/cluster/ceph/metadata' ,
81 success
: ( response
) => {
82 let res
= response
. result
;
83 if (! res
|| ! res
. data
|| ! res
. data
. node
) {
85 gettext ( 'Could not detect a ceph installation in the cluster' ),
89 let nodes
= res
. data
. node
;
91 // can happen on ceph purge, we do not yet cleanup old version data
92 delete nodes
[ me
. nodename
];
96 let maxversiontext
= "" ;
97 for ( const [ _nodename
, data
] of Object
. entries ( nodes
)) {
98 let version
= data
. version
. parts
;
99 if ( PVE
. Utils
. compare_ceph_versions ( version
, maxversion
) > 0 ) {
100 maxversion
= version
;
101 maxversiontext
= data
. version
. str
;
104 // FIXME: get from version selector store
105 const major2release
= {
111 let release
= major2release
[ maxversion
[ 0 ]] || 'unknown' ;
112 let newestVersionTxt
= ` ${Ext.String.capitalize(release)} ( ${maxversiontext} )` ;
114 if ( release
=== 'unknown' ) {
116 gettext ( 'Could not detect a ceph installation in the cluster' ),
119 me
. setValue ( Ext
. String
. format (
120 gettext ( 'Newest ceph version in cluster is {0}' ),
124 me
. gotNewestVersion ( release
, maxversiontext
, maxversion
);
126 failure : function ( response
, opts
) {
127 Ext
. Msg
. alert ( gettext ( 'Error' ), response
. htmlStatus
);
133 Ext
. define ( 'PVE.ceph.CephInstallWizard' , {
134 extend
: 'PVE.window.Wizard' ,
135 alias
: 'widget.pveCephInstallWizard' ,
136 mixins
: [ 'Proxmox.Mixin.CBind' ],
144 cephRelease
: 'pacific' ,
153 title
: gettext ( 'Setup' ),
154 navigateNext : function () {
155 var tp
= this . down ( '#wizcontent' );
156 var atab
= tp
. getActiveTab ();
158 var next
= tp
. items
. indexOf ( atab
) + 1 ;
159 var ntab
= tp
. items
. getAt ( next
);
162 tp
. setActiveTab ( ntab
);
165 setInitialTab : function ( index
) {
166 var tp
= this . down ( '#wizcontent' );
167 var initialTab
= tp
. items
. getAt ( index
);
169 tp
. setActiveTab ( initialTab
);
172 this . callParent ( arguments
);
173 var isInstalled
= this . getViewModel (). get ( 'isInstalled' );
175 this . getViewModel (). set ( 'configuration' , false );
176 this . setInitialTab ( 2 );
182 title
: gettext ( 'Info' ),
183 viewModel
: {}, // needed to inherit parent viewModel data
186 onlineHelp
: 'chapter_pveceph' ,
197 xtype
: 'pveCephInstallWizardInfo' ,
203 xtype
: 'pveCephHighestVersionDisplay' ,
206 nodename
: '{nodename}' ,
208 gotNewestVersion : function ( release
, maxversiontext
, maxversion
) {
209 if ( release
=== 'unknown' ) {
212 let wizard
= this . up ( 'pveCephInstallWizard' );
213 wizard
. getViewModel (). set ( 'cephRelease' , release
);
217 xtype
: 'pveCephVersionSelector' ,
221 value
: '{cephRelease}' ,
224 change : function ( field
, release
) {
225 let wizard
= this . up ( 'pveCephInstallWizard' );
226 wizard
. down ( '#next' ). setText (
227 Ext
. String
. format ( gettext ( 'Start {0} installation' ), release
),
234 activate : function () {
235 // notify owning container that it should display a help button
236 if ( this . onlineHelp
) {
237 Ext
. GlobalEvents
. fireEvent ( 'proxmoxShowHelp' , this . onlineHelp
);
239 let wizard
= this . up ( 'pveCephInstallWizard' );
240 let release
= wizard
. getViewModel (). get ( 'cephRelease' );
241 wizard
. down ( '#back' ). hide ( true );
242 wizard
. down ( '#next' ). setText (
243 Ext
. String
. format ( gettext ( 'Start {0} installation' ), release
),
246 deactivate : function () {
247 if ( this . onlineHelp
) {
248 Ext
. GlobalEvents
. fireEvent ( 'proxmoxHideHelp' , this . onlineHelp
);
250 this . up ( 'pveCephInstallWizard' ). down ( '#next' ). setText ( gettext ( 'Next' ));
255 title
: gettext ( 'Installation' ),
259 nodename
: '{nodename}' ,
261 viewModel
: {}, // needed to inherit parent viewModel data
263 afterrender : function () {
265 if ( this . getViewModel (). get ( 'isInstalled' )) {
266 this . mask ( "Ceph is already installed, click next to create your configuration." , [ 'pve-static-mask' ]);
268 me
. down ( 'pveNoVncConsole' ). fireEvent ( 'activate' );
271 activate : function () {
273 const nodename
= me
. nodename
;
274 me
. updateStore
= Ext
. create ( 'Proxmox.data.UpdateStore' , {
275 storeid
: 'ceph-status-' + nodename
,
279 url
: '/api2/json/nodes/' + nodename
+ '/ceph/status' ,
282 load : function ( rec
, response
, success
, operation
) {
284 me
. updateStore
. stopUpdate ();
285 me
. down ( 'textfield' ). setValue ( 'success' );
286 } else if ( operation
. error
. statusText
. match ( "not initialized" , "i" )) {
287 me
. updateStore
. stopUpdate ();
288 me
. up ( 'pveCephInstallWizard' ). getViewModel (). set ( 'configuration' , false );
289 me
. down ( 'textfield' ). setValue ( 'success' );
290 } else if ( operation
. error
. statusText
. match ( "rados_connect failed" , "i" )) {
291 me
. updateStore
. stopUpdate ();
292 me
. up ( 'pveCephInstallWizard' ). getViewModel (). set ( 'configuration' , true );
293 me
. down ( 'textfield' ). setValue ( 'success' );
294 } else if (! operation
. error
. statusText
. match ( "not installed" , "i" )) {
295 Proxmox
. Utils
. setErrorMask ( me
, operation
. error
. statusText
);
300 me
. updateStore
. startUpdate ();
302 destroy : function () {
304 if ( me
. updateStore
) {
305 me
. updateStore
. stopUpdate ();
311 xtype
: 'pveNoVncConsole' ,
316 nodename
: '{nodename}' ,
318 beforeLoad : function () {
320 let wizard
= me
. up ( 'pveCephInstallWizard' );
321 let release
= wizard
. getViewModel (). get ( 'cephRelease' );
322 me
. cmdOpts
= `--version\0 ${release} ` ;
328 name
: 'installSuccess' ,
338 title
: gettext ( 'Configuration' ),
339 onlineHelp
: 'chapter_pveceph' ,
341 nodename
: '{nodename}' ,
346 minreplicas
: undefined ,
350 activate : function () {
351 this . up ( 'pveCephInstallWizard' ). down ( '#submit' ). setText ( gettext ( 'Next' ));
353 beforeshow : function () {
354 if ( this . up ( 'pveCephInstallWizard' ). getViewModel (). get ( 'configuration' )) {
355 this . mask ( "Configuration already initialized" , [ 'pve-static-mask' ]);
360 deactivate : function () {
361 this . up ( 'pveCephInstallWizard' ). down ( '#submit' ). setText ( gettext ( 'Finish' ));
366 xtype
: 'displayfield' ,
367 value
: gettext ( 'Ceph cluster configuration' ) + ':' ,
370 xtype
: 'proxmoxNetworkSelector' ,
373 fieldLabel
: 'Public Network IP/CIDR' ,
375 allowBlank
: '{configuration}' ,
378 nodename
: '{nodename}' ,
382 xtype
: 'proxmoxNetworkSelector' ,
383 name
: 'cluster-network' ,
384 fieldLabel
: 'Cluster Network IP/CIDR' ,
387 emptyText
: gettext ( 'Same as Public Network' ),
389 nodename
: '{nodename}' ,
392 // FIXME: add hint about cluster network and/or reference user to docs??
396 xtype
: 'displayfield' ,
397 value
: gettext ( 'First Ceph monitor' ) + ':' ,
400 xtype
: 'pveNodeSelector' ,
401 fieldLabel
: gettext ( 'Monitor node' ),
407 xtype
: 'displayfield' ,
408 value
: gettext ( 'Additional monitors are recommended. They can be created at any time in the Monitor tab.' ),
414 xtype
: 'numberfield' ,
416 fieldLabel
: 'Number of replicas' ,
425 xtype
: 'numberfield' ,
427 fieldLabel
: 'Minimum replicas' ,
429 maxValue
: '{replicas}' ,
430 value
: '{minreplicas}' ,
434 setMaxValue : function ( value
) {
435 this . maxValue
= Ext
. Number
. from ( value
, 2 );
436 // allow enough to avoid split brains with max 'size', but more makes simply no sense
437 if ( this . maxValue
> 4 ) {
440 this . toggleSpinners ();
446 onGetValues : function ( values
) {
447 [ 'cluster-network' , 'size' , 'min_size' ]. forEach ( function ( field
) {
448 if (! values
[ field
]) {
449 delete values
[ field
];
454 onSubmit : function () {
456 if (! this . up ( 'pveCephInstallWizard' ). getViewModel (). get ( 'configuration' )) {
457 var wizard
= me
. up ( 'window' );
458 var kv
= wizard
. getValues ();
460 var monNode
= kv
[ 'mon-node' ];
461 delete kv
[ 'mon-node' ];
462 var nodename
= me
. nodename
;
464 Proxmox
. Utils
. API2Request ({
465 url
: `/nodes/ ${nodename} /ceph/init` ,
466 waitMsgTarget
: wizard
,
469 success : function () {
470 Proxmox
. Utils
. API2Request ({
471 url
: `/nodes/ ${monNode} /ceph/mon/ ${monNode} ` ,
472 waitMsgTarget
: wizard
,
474 success : function () {
475 me
. up ( 'pveCephInstallWizard' ). navigateNext ();
477 failure : function ( response
, opts
) {
478 Ext
. Msg
. alert ( gettext ( 'Error' ), response
. htmlStatus
);
482 failure : function ( response
, opts
) {
483 Ext
. Msg
. alert ( gettext ( 'Error' ), response
. htmlStatus
);
487 me
. up ( 'pveCephInstallWizard' ). navigateNext ();
492 title
: gettext ( 'Success' ),
496 onlineHelp
: 'pve_ceph_install' ,
497 html
: '<h3>Installation successful!</h3>' +
498 '<p>The basic installation and configuration is complete. Depending on your setup, some of the following steps are required to start using Ceph:</p>' +
499 '<ol><li>Install Ceph on other nodes</li>' +
500 '<li>Create additional Ceph Monitors</li>' +
501 '<li>Create Ceph OSDs</li>' +
502 '<li>Create Ceph Pools</li></ol>' +
503 '<p>To learn more, click on the help button below.</p>' ,
505 activate : function () {
506 // notify owning container that it should display a help button
507 if ( this . onlineHelp
) {
508 Ext
. GlobalEvents
. fireEvent ( 'proxmoxShowHelp' , this . onlineHelp
);
511 var tp
= this . up ( '#wizcontent' );
512 var idx
= tp
. items
. indexOf ( this )- 1 ;
513 for (; idx
>= 0 ; idx
--) {
514 var nc
= tp
. items
. getAt ( idx
);
520 deactivate : function () {
521 if ( this . onlineHelp
) {
522 Ext
. GlobalEvents
. fireEvent ( 'proxmoxHideHelp' , this . onlineHelp
);
526 onSubmit : function () {
527 var wizard
= this . up ( 'pveCephInstallWizard' );