]>
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
: "nautilus" , version
: "14.2" },
53 { release
: "octopus" , version
: "15.2" },
54 //{release: "pacific", version: "16.1"},
59 Ext
. define ( 'PVE.ceph.CephHighestVersionDisplay' , {
60 extend
: 'Ext.form.field.Display' ,
61 xtype
: 'pveCephHighestVersionDisplay' ,
63 fieldLabel
: gettext ( 'Ceph in the cluster' ),
67 // called on success with (release, versionTxt, versionParts)
68 gotNewestVersion
: Ext
. emptyFn
,
70 initComponent : function () {
73 me
. callParent ( arguments
);
75 Proxmox
. Utils
. API2Request ({
77 url
: '/cluster/ceph/metadata' ,
82 success
: ( response
) => {
83 let res
= response
. result
;
84 if (! res
|| ! res
. data
|| ! res
. data
. node
) {
86 gettext ( 'Could not detect a ceph installation in the cluster' ),
90 let nodes
= res
. data
. node
;
92 // can happen on ceph purge, we do not yet cleanup old version data
93 delete nodes
[ me
. nodename
];
97 let maxversiontext
= "" ;
98 for ( const [ nodename
, data
] of Object
. entries ( nodes
)) {
99 let version
= data
. version
. parts
;
100 if ( PVE
. Utils
. compare_ceph_versions ( version
, maxversion
) > 0 ) {
101 maxversion
= version
;
102 maxversiontext
= data
. version
. str
;
105 // FIXME: get from version selector store
106 const major2release
= {
112 let release
= major2release
[ maxversion
[ 0 ]] || 'unknown' ;
113 let newestVersionTxt
= ` ${Ext.String.capitalize(release)} ( ${maxversiontext} )` ;
115 if ( release
=== 'unknown' ) {
117 gettext ( 'Could not detect a ceph installation in the cluster' ),
120 me
. setValue ( Ext
. String
. format (
121 gettext ( 'Newest ceph version in cluster is {0}' ),
125 me
. gotNewestVersion ( release
, maxversiontext
, maxversion
);
127 failure : function ( response
, opts
) {
128 Ext
. Msg
. alert ( gettext ( 'Error' ), response
. htmlStatus
);
134 Ext
. define ( 'PVE.ceph.CephInstallWizard' , {
135 extend
: 'PVE.window.Wizard' ,
136 alias
: 'widget.pveCephInstallWizard' ,
137 mixins
: [ 'Proxmox.Mixin.CBind' ],
145 cephRelease
: 'octopus' ,
154 title
: gettext ( 'Setup' ),
155 navigateNext : function () {
156 var tp
= this . down ( '#wizcontent' );
157 var atab
= tp
. getActiveTab ();
159 var next
= tp
. items
. indexOf ( atab
) + 1 ;
160 var ntab
= tp
. items
. getAt ( next
);
163 tp
. setActiveTab ( ntab
);
166 setInitialTab : function ( index
) {
167 var tp
= this . down ( '#wizcontent' );
168 var initialTab
= tp
. items
. getAt ( index
);
170 tp
. setActiveTab ( initialTab
);
173 this . callParent ( arguments
);
174 var isInstalled
= this . getViewModel (). get ( 'isInstalled' );
176 this . getViewModel (). set ( 'configuration' , false );
177 this . setInitialTab ( 2 );
183 title
: gettext ( 'Info' ),
184 viewModel
: {}, // needed to inherit parent viewModel data
187 onlineHelp
: 'chapter_pveceph' ,
198 xtype
: 'pveCephInstallWizardInfo' ,
204 xtype
: 'pveCephHighestVersionDisplay' ,
207 nodename
: '{nodename}' ,
209 gotNewestVersion : function ( release
, maxversiontext
, maxversion
) {
210 if ( release
=== 'unknown' ) {
213 let wizard
= this . up ( 'pveCephInstallWizard' );
214 wizard
. getViewModel (). set ( 'cephRelease' , release
);
218 xtype
: 'pveCephVersionSelector' ,
222 value
: '{cephRelease}' ,
225 change : function ( field
, release
) {
226 let wizard
= this . up ( 'pveCephInstallWizard' );
227 wizard
. down ( '#next' ). setText (
228 Ext
. String
. format ( gettext ( 'Start {0} installation' ), release
),
235 activate : function () {
236 // notify owning container that it should display a help button
237 if ( this . onlineHelp
) {
238 Ext
. GlobalEvents
. fireEvent ( 'proxmoxShowHelp' , this . onlineHelp
);
240 let wizard
= this . up ( 'pveCephInstallWizard' );
241 let release
= wizard
. getViewModel (). get ( 'cephRelease' );
242 wizard
. down ( '#back' ). hide ( true );
243 wizard
. down ( '#next' ). setText (
244 Ext
. String
. format ( gettext ( 'Start {0} installation' ), release
),
247 deactivate : function () {
248 if ( this . onlineHelp
) {
249 Ext
. GlobalEvents
. fireEvent ( 'proxmoxHideHelp' , this . onlineHelp
);
251 this . up ( 'pveCephInstallWizard' ). down ( '#next' ). setText ( gettext ( 'Next' ));
256 title
: gettext ( 'Installation' ),
260 nodename
: '{nodename}' ,
262 viewModel
: {}, // needed to inherit parent viewModel data
264 afterrender : function () {
266 if ( this . getViewModel (). get ( 'isInstalled' )) {
267 this . mask ( "Ceph is already installed, click next to create your configuration." , [ 'pve-static-mask' ]);
269 me
. down ( 'pveNoVncConsole' ). fireEvent ( 'activate' );
272 activate : function () {
274 const nodename
= me
. nodename
;
275 me
. updateStore
= Ext
. create ( 'Proxmox.data.UpdateStore' , {
276 storeid
: 'ceph-status-' + nodename
,
280 url
: '/api2/json/nodes/' + nodename
+ '/ceph/status' ,
283 load : function ( rec
, response
, success
, operation
) {
285 me
. updateStore
. stopUpdate ();
286 me
. down ( 'textfield' ). setValue ( 'success' );
287 } else if ( operation
. error
. statusText
. match ( "not initialized" , "i" )) {
288 me
. updateStore
. stopUpdate ();
289 me
. up ( 'pveCephInstallWizard' ). getViewModel (). set ( 'configuration' , false );
290 me
. down ( 'textfield' ). setValue ( 'success' );
291 } else if ( operation
. error
. statusText
. match ( "rados_connect failed" , "i" )) {
292 me
. updateStore
. stopUpdate ();
293 me
. up ( 'pveCephInstallWizard' ). getViewModel (). set ( 'configuration' , true );
294 me
. down ( 'textfield' ). setValue ( 'success' );
295 } else if (! operation
. error
. statusText
. match ( "not installed" , "i" )) {
296 Proxmox
. Utils
. setErrorMask ( me
, operation
. error
. statusText
);
301 me
. updateStore
. startUpdate ();
303 destroy : function () {
305 if ( me
. updateStore
) {
306 me
. updateStore
. stopUpdate ();
312 xtype
: 'pveNoVncConsole' ,
317 nodename
: '{nodename}' ,
319 beforeLoad : function () {
321 let wizard
= me
. up ( 'pveCephInstallWizard' );
322 let release
= wizard
. getViewModel (). get ( 'cephRelease' );
323 me
. cmdOpts
= `--version\0 ${release} ` ;
329 name
: 'installSuccess' ,
339 title
: gettext ( 'Configuration' ),
340 onlineHelp
: 'chapter_pveceph' ,
342 nodename
: '{nodename}' ,
347 minreplicas
: undefined ,
351 activate : function () {
352 this . up ( 'pveCephInstallWizard' ). down ( '#submit' ). setText ( gettext ( 'Next' ));
354 beforeshow : function () {
355 if ( this . up ( 'pveCephInstallWizard' ). getViewModel (). get ( 'configuration' )) {
356 this . mask ( "Configuration already initialized" , [ 'pve-static-mask' ]);
361 deactivate : function () {
362 this . up ( 'pveCephInstallWizard' ). down ( '#submit' ). setText ( gettext ( 'Finish' ));
367 xtype
: 'displayfield' ,
368 value
: gettext ( 'Ceph cluster configuration' ) + ':' ,
371 xtype
: 'proxmoxNetworkSelector' ,
374 fieldLabel
: 'Public Network IP/CIDR' ,
376 allowBlank
: '{configuration}' ,
379 nodename
: '{nodename}' ,
383 xtype
: 'proxmoxNetworkSelector' ,
384 name
: 'cluster-network' ,
385 fieldLabel
: 'Cluster Network IP/CIDR' ,
388 emptyText
: gettext ( 'Same as Public Network' ),
390 nodename
: '{nodename}' ,
393 // FIXME: add hint about cluster network and/or reference user to docs??
397 xtype
: 'displayfield' ,
398 value
: gettext ( 'First Ceph monitor' ) + ':' ,
401 xtype
: 'pveNodeSelector' ,
402 fieldLabel
: gettext ( 'Monitor node' ),
408 xtype
: 'displayfield' ,
409 value
: gettext ( 'Additional monitors are recommended. They can be created at any time in the Monitor tab.' ),
415 xtype
: 'numberfield' ,
417 fieldLabel
: 'Number of replicas' ,
426 xtype
: 'numberfield' ,
428 fieldLabel
: 'Minimum replicas' ,
430 maxValue
: '{replicas}' ,
431 value
: '{minreplicas}' ,
435 setMaxValue : function ( value
) {
436 this . maxValue
= Ext
. Number
. from ( value
, 2 );
437 // allow enough to avoid split brains with max 'size', but more makes simply no sense
438 if ( this . maxValue
> 4 ) {
441 this . toggleSpinners ();
447 onGetValues : function ( values
) {
448 [ 'cluster-network' , 'size' , 'min_size' ]. forEach ( function ( field
) {
449 if (! values
[ field
]) {
450 delete values
[ field
];
455 onSubmit : function () {
457 if (! this . up ( 'pveCephInstallWizard' ). getViewModel (). get ( 'configuration' )) {
458 var wizard
= me
. up ( 'window' );
459 var kv
= wizard
. getValues ();
461 var monNode
= kv
[ 'mon-node' ];
462 delete kv
[ 'mon-node' ];
463 var nodename
= me
. nodename
;
465 Proxmox
. Utils
. API2Request ({
466 url
: '/nodes/' + nodename
+ '/ceph/init' ,
467 waitMsgTarget
: wizard
,
470 success : function () {
471 Proxmox
. Utils
. API2Request ({
472 url
: '/nodes/' + monNode
+ '/ceph/mon/' + monNode
,
473 waitMsgTarget
: wizard
,
475 success : function () {
476 me
. up ( 'pveCephInstallWizard' ). navigateNext ();
478 failure : function ( response
, opts
) {
479 Ext
. Msg
. alert ( gettext ( 'Error' ), response
. htmlStatus
);
483 failure : function ( response
, opts
) {
484 Ext
. Msg
. alert ( gettext ( 'Error' ), response
. htmlStatus
);
488 me
. up ( 'pveCephInstallWizard' ). navigateNext ();
493 title
: gettext ( 'Success' ),
497 onlineHelp
: 'pve_ceph_install' ,
498 html
: '<h3>Installation successful!</h3>' +
499 '<p>The basic installation and configuration is complete. Depending on your setup, some of the following steps are required to start using Ceph:</p>' +
500 '<ol><li>Install Ceph on other nodes</li>' +
501 '<li>Create additional Ceph Monitors</li>' +
502 '<li>Create Ceph OSDs</li>' +
503 '<li>Create Ceph Pools</li></ol>' +
504 '<p>To learn more, click on the help button below.</p>' ,
506 activate : function () {
507 // notify owning container that it should display a help button
508 if ( this . onlineHelp
) {
509 Ext
. GlobalEvents
. fireEvent ( 'proxmoxShowHelp' , this . onlineHelp
);
512 var tp
= this . up ( '#wizcontent' );
513 var idx
= tp
. items
. indexOf ( this )- 1 ;
514 for (; idx
>= 0 ; idx
--) {
515 var nc
= tp
. items
. getAt ( idx
);
521 deactivate : function () {
522 if ( this . onlineHelp
) {
523 Ext
. GlobalEvents
. fireEvent ( 'proxmoxHideHelp' , this . onlineHelp
);
527 onSubmit : function () {
528 var wizard
= this . up ( 'pveCephInstallWizard' );