]>
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
) {
286 me
. updateStore
. stopUpdate ();
287 me
. down ( 'textfield' ). setValue ( 'success' );
288 } else if ( operation
. error
. statusText
. match ( "not initialized" , "i" )) {
289 me
. updateStore
. stopUpdate ();
290 me
. up ( 'pveCephInstallWizard' ). getViewModel (). set ( 'configuration' , false );
291 me
. down ( 'textfield' ). setValue ( 'success' );
292 } else if ( operation
. error
. statusText
. match ( "rados_connect failed" , "i" )) {
293 me
. updateStore
. stopUpdate ();
294 me
. up ( 'pveCephInstallWizard' ). getViewModel (). set ( 'configuration' , true );
295 me
. down ( 'textfield' ). setValue ( 'success' );
296 } else if (! operation
. error
. statusText
. match ( "not installed" , "i" )) {
297 Proxmox
. Utils
. setErrorMask ( me
, operation
. error
. statusText
);
302 me
. updateStore
. startUpdate ();
304 destroy : function () {
306 if ( me
. updateStore
) {
307 me
. updateStore
. stopUpdate ();
313 xtype
: 'pveNoVncConsole' ,
318 nodename
: '{nodename}' ,
320 beforeLoad : function () {
322 let wizard
= me
. up ( 'pveCephInstallWizard' );
323 let release
= wizard
. getViewModel (). get ( 'cephRelease' );
324 me
. cmdOpts
= `--version\0 ${release} ` ;
330 name
: 'installSuccess' ,
340 title
: gettext ( 'Configuration' ),
341 onlineHelp
: 'chapter_pveceph' ,
343 nodename
: '{nodename}'
348 minreplicas
: undefined
352 activate : function () {
353 this . up ( 'pveCephInstallWizard' ). down ( '#submit' ). setText ( gettext ( 'Next' ));
355 beforeshow : function () {
356 if ( this . up ( 'pveCephInstallWizard' ). getViewModel (). get ( 'configuration' )) {
357 this . mask ( "Configuration already initialized" ,[ 'pve-static-mask' ]);
362 deactivate : function () {
363 this . up ( 'pveCephInstallWizard' ). down ( '#submit' ). setText ( gettext ( 'Finish' ));
368 xtype
: 'displayfield' ,
369 value
: gettext ( 'Ceph cluster configuration' ) + ':'
372 xtype
: 'proxmoxNetworkSelector' ,
375 fieldLabel
: 'Public Network IP/CIDR' ,
377 allowBlank
: '{configuration}'
380 nodename
: '{nodename}'
384 xtype
: 'proxmoxNetworkSelector' ,
385 name
: 'cluster-network' ,
386 fieldLabel
: 'Cluster Network IP/CIDR' ,
389 emptyText
: gettext ( 'Same as Public Network' ),
391 nodename
: '{nodename}'
394 // FIXME: add hint about cluster network and/or reference user to docs??
398 xtype
: 'displayfield' ,
399 value
: gettext ( 'First Ceph monitor' ) + ':'
402 xtype
: 'pveNodeSelector' ,
403 fieldLabel
: gettext ( 'Monitor node' ),
409 xtype
: 'displayfield' ,
410 value
: gettext ( 'Additional monitors are recommended. They can be created at any time in the Monitor tab.' ),
416 xtype
: 'numberfield' ,
418 fieldLabel
: 'Number of replicas' ,
427 xtype
: 'numberfield' ,
429 fieldLabel
: 'Minimum replicas' ,
431 maxValue
: '{replicas}' ,
432 value
: '{minreplicas}'
436 setMaxValue : function ( value
) {
437 this . maxValue
= Ext
. Number
. from ( value
, 2 );
438 // allow enough to avoid split brains with max 'size', but more makes simply no sense
439 if ( this . maxValue
> 4 ) {
442 this . toggleSpinners ();
448 onGetValues : function ( values
) {
449 [ 'cluster-network' , 'size' , 'min_size' ]. forEach ( function ( field
) {
450 if (! values
[ field
]) {
451 delete values
[ field
];
456 onSubmit : function () {
458 if (! this . up ( 'pveCephInstallWizard' ). getViewModel (). get ( 'configuration' )) {
459 var wizard
= me
. up ( 'window' );
460 var kv
= wizard
. getValues ();
462 var monNode
= kv
[ 'mon-node' ];
463 delete kv
[ 'mon-node' ];
464 var nodename
= me
. nodename
;
466 Proxmox
. Utils
. API2Request ({
467 url
: '/nodes/' + nodename
+ '/ceph/init' ,
468 waitMsgTarget
: wizard
,
471 success : function () {
472 Proxmox
. Utils
. API2Request ({
473 url
: '/nodes/' + monNode
+ '/ceph/mon/' + monNode
,
474 waitMsgTarget
: wizard
,
476 success : function () {
477 me
. up ( 'pveCephInstallWizard' ). navigateNext ();
479 failure : function ( response
, opts
) {
480 Ext
. Msg
. alert ( gettext ( 'Error' ), response
. htmlStatus
);
484 failure : function ( response
, opts
) {
485 Ext
. Msg
. alert ( gettext ( 'Error' ), response
. htmlStatus
);
490 me
. up ( 'pveCephInstallWizard' ). navigateNext ();
495 title
: gettext ( 'Success' ),
499 onlineHelp
: 'pve_ceph_install' ,
500 html
: '<h3>Installation successful!</h3>' +
501 '<p>The basic installation and configuration is complete. Depending on your setup, some of the following steps are required to start using Ceph:</p>' +
502 '<ol><li>Install Ceph on other nodes</li>' +
503 '<li>Create additional Ceph Monitors</li>' +
504 '<li>Create Ceph OSDs</li>' +
505 '<li>Create Ceph Pools</li></ol>' +
506 '<p>To learn more, click on the help button below.</p>' ,
508 activate : function () {
509 // notify owning container that it should display a help button
510 if ( this . onlineHelp
) {
511 Ext
. GlobalEvents
. fireEvent ( 'proxmoxShowHelp' , this . onlineHelp
);
514 var tp
= this . up ( '#wizcontent' );
515 var idx
= tp
. items
. indexOf ( this )- 1 ;
516 for (; idx
>= 0 ; idx
--) {
517 var nc
= tp
. items
. getAt ( idx
);
523 deactivate : function () {
524 if ( this . onlineHelp
) {
525 Ext
. GlobalEvents
. fireEvent ( 'proxmoxHideHelp' , this . onlineHelp
);
529 onSubmit : function () {
530 var wizard
= this . up ( 'pveCephInstallWizard' );