mirror of
https://git.proxmox.com/git/pve-manager
synced 2025-10-04 07:48:57 +00:00
added basic ability to install ceph via gui
Signed-off-by: Tim Marx <t.marx@proxmox.com> Reviewed-by: Dominik Csapak <d.csapak@proxmox.com>
This commit is contained in:
parent
b945c7c1be
commit
4616a55b37
@ -582,3 +582,8 @@ table.osds td:first-of-type {
|
||||
right: 0px;
|
||||
background-color: #555;
|
||||
}
|
||||
|
||||
.install-mask {
|
||||
background-color: rgb(245, 245, 245);
|
||||
color: #000;
|
||||
}
|
@ -83,6 +83,7 @@ JSSRC= \
|
||||
window/BackupConfig.js \
|
||||
window/Settings.js \
|
||||
window/StartupEdit.js \
|
||||
window/CephInstall.js \
|
||||
panel/NotesView.js \
|
||||
grid/ResourceGrid.js \
|
||||
grid/PoolMembers.js \
|
||||
@ -101,6 +102,8 @@ JSSRC= \
|
||||
ceph/Status.js \
|
||||
ceph/StatusDetail.js \
|
||||
ceph/Config.js \
|
||||
ceph/Log.js \
|
||||
ceph/CephInstallWizard.js \
|
||||
node/Disks.js \
|
||||
node/LVM.js \
|
||||
node/LVMThin.js \
|
||||
|
@ -1102,6 +1102,52 @@ Ext.define('PVE.Utils', { utilities: {
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
handleStoreErrorOrMask: function(me, store, regex, callback) {
|
||||
|
||||
me.mon(store, 'load', function (proxy, response, success, operation) {
|
||||
|
||||
if (success) {
|
||||
Proxmox.Utils.setErrorMask(me, false);
|
||||
return;
|
||||
}
|
||||
var msg;
|
||||
|
||||
if (operation.error.statusText) {
|
||||
if (operation.error.statusText.match(regex)) {
|
||||
callback(me, operation.error);
|
||||
return;
|
||||
} else {
|
||||
msg = operation.error.statusText + ' (' + operation.error.status + ')';
|
||||
}
|
||||
} else {
|
||||
msg = gettext('Connection error');
|
||||
}
|
||||
Proxmox.Utils.setErrorMask(me, msg);
|
||||
});
|
||||
},
|
||||
|
||||
showCephInstallOrMask: function(container, msg, nodename, callback){
|
||||
var regex = new RegExp("not (installed|initialized)", "i");
|
||||
if (msg.match(regex)) {
|
||||
if (Proxmox.UserName === 'root@pam') {
|
||||
container.el.mask();
|
||||
if (!container.down('pveCephInstallWindow')){
|
||||
var win = Ext.create('PVE.ceph.Install', {
|
||||
nodename: nodename
|
||||
});
|
||||
container.add(win);
|
||||
win.show();
|
||||
callback(win);
|
||||
}
|
||||
} else {
|
||||
container.mask(Ext.String.format(gettext('{0} not installed.') + gettext(' Log in as root to install.'), 'Ceph'), ['pve-static-mask']);
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
267
www/manager6/ceph/CephInstallWizard.js
Normal file
267
www/manager6/ceph/CephInstallWizard.js
Normal file
@ -0,0 +1,267 @@
|
||||
Ext.define('PVE.ceph.CephInstallWizard', {
|
||||
extend: 'PVE.window.Wizard',
|
||||
alias: 'widget.pveCephInstallWizard',
|
||||
mixins: ['Proxmox.Mixin.CBind'],
|
||||
resizable: false,
|
||||
nodename: undefined,
|
||||
viewModel: {
|
||||
data: {
|
||||
nodename: ''
|
||||
}
|
||||
},
|
||||
cbindData: {
|
||||
nodename: undefined
|
||||
},
|
||||
title: gettext('Installation'),
|
||||
items: [
|
||||
{
|
||||
title: gettext('Info'),
|
||||
xtype: 'panel',
|
||||
border: false,
|
||||
bodyBorder: false,
|
||||
onlineHelp: 'chapter_pveceph',
|
||||
html: '<h3>Ceph?</h3>'+
|
||||
'<blockquote cite="https://ceph.com/"><p>"<b>Ceph</b> is a unified, distributed storage system designed for excellent performance, reliability and scalability."</p></blockquote>'+
|
||||
'<p><b>Ceph</b> is currently <b>not installed</b> on this node, click on the next button below to start the installation.'+
|
||||
' This wizard will guide you through the necessary steps, after the initial installation you will be offered to create a initial configuration.'+
|
||||
' The configuration step is only needed once per cluster and will be skipped if a config is already present.</p>'+
|
||||
'<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>',
|
||||
listeners: {
|
||||
activate: function() {
|
||||
// notify owning container that it should display a help button
|
||||
if (this.onlineHelp) {
|
||||
Ext.GlobalEvents.fireEvent('proxmoxShowHelp', this.onlineHelp);
|
||||
}
|
||||
this.up('pveCephInstallWizard').down('#back').hide(true);
|
||||
},
|
||||
deactivate: function() {
|
||||
if (this.onlineHelp) {
|
||||
Ext.GlobalEvents.fireEvent('proxmoxHideHelp', this.onlineHelp);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
title: gettext('Installation'),
|
||||
xtype: 'panel',
|
||||
layout: 'fit',
|
||||
cbind:{
|
||||
nodename: '{nodename}'
|
||||
},
|
||||
listeners: {
|
||||
afterrender: function() {
|
||||
var me = this;
|
||||
me.down('pveNoVncConsole').fireEvent('activate');
|
||||
},
|
||||
activate: function() {
|
||||
var me = this;
|
||||
var nodename = me.nodename;
|
||||
me.updateStore = Ext.create('Proxmox.data.UpdateStore', {
|
||||
storeid: 'ceph-status-' + nodename,
|
||||
interval: 1000,
|
||||
proxy: {
|
||||
type: 'proxmox',
|
||||
url: '/api2/json/nodes/' + nodename + '/ceph/status'
|
||||
},
|
||||
listeners: {
|
||||
load: function(rec, response, success, operation) {
|
||||
var wizard = me.up('#wizcontent');
|
||||
var tabs = wizard.items;
|
||||
var lastTab = tabs.items[tabs.length-1];
|
||||
if (success) {
|
||||
me.updateStore.stopUpdate();
|
||||
lastTab.enable();
|
||||
wizard.setActiveTab(lastTab);
|
||||
} else if (operation.error.statusText.match("not initialized", "i")) {
|
||||
me.updateStore.stopUpdate();
|
||||
me.down('textfield').setValue('success');
|
||||
} else if (operation.error.statusText.match("rados_connect failed", "i")) {
|
||||
me.updateStore.stopUpdate();
|
||||
lastTab.enable();
|
||||
wizard.setActiveTab(lastTab);
|
||||
} else if (!operation.error.statusText.match("not installed", "i")) {
|
||||
Proxmox.Utils.setErrorMask(me, operation.error.statusText);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
me.updateStore.startUpdate();
|
||||
},
|
||||
destroy: function() {
|
||||
var me = this;
|
||||
if (me.updateStore) {
|
||||
me.updateStore.stopUpdate();
|
||||
}
|
||||
}
|
||||
},
|
||||
items: [
|
||||
{
|
||||
itemId: 'jsconsole',
|
||||
consoleType: 'cmd',
|
||||
xtermjs: true,
|
||||
xtype: 'pveNoVncConsole',
|
||||
cbind:{
|
||||
nodename: '{nodename}'
|
||||
},
|
||||
cmd: 'ceph_install'
|
||||
},
|
||||
{
|
||||
xtype: 'textfield',
|
||||
name: 'installSuccess',
|
||||
value: '',
|
||||
allowBlank: false,
|
||||
submitValue: false,
|
||||
hidden: true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
xtype: 'inputpanel',
|
||||
title: gettext('Configuration'),
|
||||
onlineHelp: 'chapter_pveceph',
|
||||
cbind: {
|
||||
nodename: '{nodename}'
|
||||
},
|
||||
listeners: {
|
||||
activate: function() {
|
||||
this.up('pveCephInstallWizard').down('#submit').setText(gettext('Next'));
|
||||
},
|
||||
deactivate: function() {
|
||||
this.up('pveCephInstallWizard').down('#submit').setText(gettext('Finish'));
|
||||
}
|
||||
},
|
||||
column1: [
|
||||
{
|
||||
xtype: 'displayfield',
|
||||
name: 'nodename',
|
||||
fieldLabel: gettext('Node'),
|
||||
cbind: {
|
||||
value: '{nodename}'
|
||||
},
|
||||
padding: 5
|
||||
},
|
||||
{
|
||||
xtype: 'textfield',
|
||||
name: 'network',
|
||||
vtype: 'IPCIDRAddress',
|
||||
value: '',
|
||||
fieldLabel: 'Network IPv4/CIDR',
|
||||
allowBlank: false
|
||||
},
|
||||
{
|
||||
xtype: 'textfield',
|
||||
name: 'cluster-network',
|
||||
vtype: 'IPCIDRAddress',
|
||||
fieldLabel: 'Cluster-Network IPv4/CIDR',
|
||||
allowBlank: true,
|
||||
emptyText: gettext('default')
|
||||
}
|
||||
],
|
||||
advancedColumn1: [
|
||||
{
|
||||
xtype: 'numberfield',
|
||||
name: 'size',
|
||||
fieldLabel: gettext('Number of replicas'),
|
||||
value: '',
|
||||
maxValue: 7,
|
||||
minValue: 1,
|
||||
allowBlank: true,
|
||||
emptyText: gettext('default')
|
||||
},
|
||||
{
|
||||
xtype: 'numberfield',
|
||||
name: 'min_size',
|
||||
fieldLabel: gettext('Minimum replicas'),
|
||||
value: '',
|
||||
maxValue: 7,
|
||||
minValue: 1,
|
||||
allowBlank: true,
|
||||
emptyText: gettext('default')
|
||||
},
|
||||
{
|
||||
xtype: 'numberfield',
|
||||
name: 'pg_bits',
|
||||
fieldLabel: 'Placement group bits',
|
||||
value: '',
|
||||
maxValue: 14,
|
||||
minValue: 6,
|
||||
allowBlank: true,
|
||||
emptyText: gettext('default')
|
||||
}
|
||||
],
|
||||
onGetValues: function(values) {
|
||||
['cluster-network', 'size', 'min_size', 'pg_bits'].forEach(function(field) {
|
||||
if (!values[field]) {
|
||||
delete values[field];
|
||||
}
|
||||
});
|
||||
return values;
|
||||
},
|
||||
onSubmit: function() {
|
||||
var me = this;
|
||||
var wizard = me.up('window');
|
||||
var kv = wizard.getValues();
|
||||
delete kv['delete'];
|
||||
var nodename = me.nodename;
|
||||
delete kv.nodename;
|
||||
Proxmox.Utils.API2Request({
|
||||
url: '/nodes/'+nodename+'/ceph/init',
|
||||
waitMsgTarget: wizard,
|
||||
method: 'POST',
|
||||
params: kv,
|
||||
success: function() {
|
||||
var tp = me.up('#wizcontent');
|
||||
var atab = tp.getActiveTab();
|
||||
|
||||
var next = tp.items.indexOf(atab) + 1;
|
||||
var ntab = tp.items.getAt(next);
|
||||
if (ntab) {
|
||||
ntab.enable();
|
||||
tp.setActiveTab(ntab);
|
||||
}
|
||||
},
|
||||
failure: function(response, opts) {
|
||||
Ext.Msg.alert(gettext('Error'), response.htmlStatus);
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
{
|
||||
title: gettext('Success'),
|
||||
xtype: 'panel',
|
||||
border: false,
|
||||
bodyBorder: false,
|
||||
onlineHelp: 'pve_ceph_install',
|
||||
html: '<h3>Installation successful!</h3>'+
|
||||
'<p>The basic installation and configuration is completed, depending on your setup some of the following steps are required to start using Ceph:</p>'+
|
||||
'<ul><li>Creating Ceph Monitors</li><li>Creating Ceph OSDs</li><li>Creating Ceph Pools</li></ul>'+
|
||||
'<p>To learn more click on the help button below.</p>',
|
||||
listeners: {
|
||||
activate: function() {
|
||||
// notify owning container that it should display a help button
|
||||
if (this.onlineHelp) {
|
||||
Ext.GlobalEvents.fireEvent('proxmoxShowHelp', this.onlineHelp);
|
||||
}
|
||||
|
||||
var tp = this.up('#wizcontent');
|
||||
var idx = tp.items.indexOf(this)-1;
|
||||
for(;idx >= 0;idx--) {
|
||||
var nc = tp.items.getAt(idx);
|
||||
if (nc) {
|
||||
nc.disable();
|
||||
}
|
||||
}
|
||||
},
|
||||
deactivate: function() {
|
||||
if (this.onlineHelp) {
|
||||
Ext.GlobalEvents.fireEvent('proxmoxHideHelp', this.onlineHelp);
|
||||
}
|
||||
}
|
||||
},
|
||||
onSubmit: function() {
|
||||
var wizard = this.up('pveCephInstallWizard');
|
||||
wizard.close();
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
@ -14,6 +14,15 @@ Ext.define('PVE.node.CephConfig', {
|
||||
waitMsgTarget: me,
|
||||
failure: function(response, opts) {
|
||||
me.update(gettext('Error') + " " + response.htmlStatus);
|
||||
var msg = response.htmlStatus;
|
||||
PVE.Utils.showCephInstallOrMask(me.ownerCt, msg, me.pveSelNode.data.node,
|
||||
function(win){
|
||||
me.mon(win, 'cephInstallWindowClosed', function(){
|
||||
me.load();
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
},
|
||||
success: function(response, opts) {
|
||||
var data = response.result.data;
|
||||
|
@ -15,6 +15,14 @@ Ext.define('PVE.node.CephCrushMap', {
|
||||
waitMsgTarget: me,
|
||||
failure: function(response, opts) {
|
||||
me.update(gettext('Error') + " " + response.htmlStatus);
|
||||
var msg = response.htmlStatus;
|
||||
PVE.Utils.showCephInstallOrMask(me.ownerCt, msg, me.pveSelNode.data.node,
|
||||
function(win){
|
||||
me.mon(win, 'cephInstallWindowClosed', function(){
|
||||
me.load();
|
||||
});
|
||||
}
|
||||
);
|
||||
},
|
||||
success: function(response, opts) {
|
||||
var data = response.result.data;
|
||||
|
@ -161,7 +161,17 @@ Ext.define('PVE.NodeCephFSPanel', {
|
||||
order: 'DESC'
|
||||
}
|
||||
}));
|
||||
Proxmox.Utils.monStoreErrors(view, view.rstore);
|
||||
var regex = new RegExp("not (installed|initialized)", "i");
|
||||
PVE.Utils.handleStoreErrorOrMask(view, view.rstore, regex, function(me, error){
|
||||
me.rstore.stopUpdate();
|
||||
PVE.Utils.showCephInstallOrMask(me.ownerCt, error.statusText, view.nodename,
|
||||
function(win){
|
||||
me.mon(win, 'cephInstallWindowClosed', function(){
|
||||
me.rstore.startUpdate();
|
||||
});
|
||||
}
|
||||
);
|
||||
});
|
||||
view.rstore.on('load', this.onLoad, this);
|
||||
view.on('destroy', view.rstore.stopUpdate);
|
||||
},
|
||||
@ -244,7 +254,17 @@ Ext.define('PVE.NodeCephFSPanel', {
|
||||
order: 'DESC'
|
||||
}
|
||||
}));
|
||||
Proxmox.Utils.monStoreErrors(view, view.rstore);
|
||||
var regex = new RegExp("not (installed|initialized)", "i");
|
||||
PVE.Utils.handleStoreErrorOrMask(view, view.rstore, regex, function(me, error){
|
||||
me.rstore.stopUpdate();
|
||||
PVE.Utils.showCephInstallOrMask(me.ownerCt, error.statusText, view.nodename,
|
||||
function(win){
|
||||
me.mon(win, 'cephInstallWindowClosed', function(){
|
||||
me.rstore.startUpdate();
|
||||
});
|
||||
}
|
||||
);
|
||||
});
|
||||
view.rstore.on('load', this.onLoad, this);
|
||||
view.on('destroy', view.rstore.stopUpdate);
|
||||
},
|
||||
|
60
www/manager6/ceph/Log.js
Normal file
60
www/manager6/ceph/Log.js
Normal file
@ -0,0 +1,60 @@
|
||||
Ext.define('PVE.ceph.Log', {
|
||||
extend: 'Proxmox.panel.LogView',
|
||||
xtype: 'cephLogView',
|
||||
nodename: undefined,
|
||||
doAttemptLoad: function(start) {
|
||||
var me = this;
|
||||
|
||||
var req_params = {
|
||||
start: start,
|
||||
limit: me.pageSize
|
||||
};
|
||||
|
||||
if (me.log_select_timespan) {
|
||||
// always show log until the end of the selected day
|
||||
req_params.until = Ext.Date.format(me.until_date, 'Y-m-d') + ' 23:59:59';
|
||||
req_params.since = Ext.Date.format(me.since_date, 'Y-m-d');
|
||||
}
|
||||
|
||||
Proxmox.Utils.API2Request({
|
||||
url: me.url,
|
||||
params: req_params,
|
||||
method: 'GET',
|
||||
success: function(response) {
|
||||
Proxmox.Utils.setErrorMask(me, false);
|
||||
var list = response.result.data;
|
||||
var total = response.result.total;
|
||||
var first = 0, last = 0;
|
||||
var text = '';
|
||||
Ext.Array.each(list, function(item) {
|
||||
if (!first|| item.n < first) {
|
||||
first = item.n;
|
||||
}
|
||||
if (!last || item.n > last) {
|
||||
last = item.n;
|
||||
}
|
||||
text = text + Ext.htmlEncode(item.t) + "<br>";
|
||||
});
|
||||
|
||||
if (first && last && total) {
|
||||
me.updateView(first -1 , last -1, total, text);
|
||||
} else {
|
||||
me.updateView(0, 0, 0, '');
|
||||
}
|
||||
},
|
||||
failure: function(response) {
|
||||
var msg = response.htmlStatus;
|
||||
var windowShow = PVE.Utils.showCephInstallOrMask(me, msg, me.nodename,
|
||||
function(win){
|
||||
me.mon(win, 'cephInstallWindowClosed', function(){
|
||||
me.doAttemptLoad(0);
|
||||
});
|
||||
}
|
||||
);
|
||||
if (!windowShow) {
|
||||
Proxmox.Utils.setErrorMask(me, msg);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
@ -82,7 +82,6 @@ Ext.define('PVE.node.CephMonList', {
|
||||
sorters: [{ property: 'name'}]
|
||||
});
|
||||
|
||||
Proxmox.Utils.monStoreErrors(me, rstore);
|
||||
|
||||
var service_cmd = function(cmd) {
|
||||
var rec = sm.getSelection()[0];
|
||||
@ -211,6 +210,18 @@ Ext.define('PVE.node.CephMonList', {
|
||||
}
|
||||
});
|
||||
|
||||
var regex = new RegExp("not (installed|initialized)", "i");
|
||||
PVE.Utils.handleStoreErrorOrMask(me, rstore, regex, function(me, error){
|
||||
me.store.rstore.stopUpdate();
|
||||
PVE.Utils.showCephInstallOrMask(me, error.statusText, nodename,
|
||||
function(win){
|
||||
me.mon(win, 'cephInstallWindowClosed', function(){
|
||||
me.store.rstore.startUpdate();
|
||||
});
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
me.callParent();
|
||||
}
|
||||
}, function() {
|
||||
|
@ -281,7 +281,14 @@ Ext.define('PVE.node.CephOsdTree', {
|
||||
waitMsgTarget: me,
|
||||
method: 'GET',
|
||||
failure: function(response, opts) {
|
||||
Proxmox.Utils.setErrorMask(me, response.htmlStatus);
|
||||
var msg = response.htmlStatus;
|
||||
PVE.Utils.showCephInstallOrMask(me, msg, me.pveSelNode.data.node,
|
||||
function(win){
|
||||
me.mon(win, 'cephInstallWindowClosed', function(){
|
||||
reload();
|
||||
});
|
||||
}
|
||||
);
|
||||
},
|
||||
success: function(response, opts) {
|
||||
sm.deselectAll();
|
||||
|
@ -164,7 +164,17 @@ Ext.define('PVE.node.CephPoolList', {
|
||||
|
||||
var store = Ext.create('Proxmox.data.DiffStore', { rstore: rstore });
|
||||
|
||||
Proxmox.Utils.monStoreErrors(me, rstore);
|
||||
var regex = new RegExp("not (installed|initialized)", "i");
|
||||
PVE.Utils.handleStoreErrorOrMask(me, rstore, regex, function(me, error){
|
||||
me.store.rstore.stopUpdate();
|
||||
PVE.Utils.showCephInstallOrMask(me, error.statusText, nodename,
|
||||
function(win){
|
||||
me.mon(win, 'cephInstallWindowClosed', function(){
|
||||
me.store.rstore.startUpdate();
|
||||
});
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
var create_btn = new Ext.Button({
|
||||
text: gettext('Create'),
|
||||
|
@ -308,7 +308,18 @@ Ext.define('PVE.node.CephStatus', {
|
||||
me.version = me.sp.get('ceph-version');
|
||||
me.change_version(me.version);
|
||||
|
||||
Proxmox.Utils.monStoreErrors(me,me.store);
|
||||
var regex = new RegExp("not (installed|initialized)", "i");
|
||||
PVE.Utils.handleStoreErrorOrMask(me, me.store, regex, function(me, error){
|
||||
me.store.stopUpdate();
|
||||
PVE.Utils.showCephInstallOrMask(me, error.statusText, nodename,
|
||||
function(win){
|
||||
me.mon(win, 'cephInstallWindowClosed', function(){
|
||||
me.store.startUpdate();
|
||||
});
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
me.mon(me.store, 'load', me.updateAll, me);
|
||||
me.on('destroy', me.store.stopUpdate);
|
||||
me.store.startUpdate();
|
||||
|
@ -375,8 +375,9 @@ Ext.define('PVE.node.Config', {
|
||||
iconCls: 'fa fa-list',
|
||||
groups: ['ceph'],
|
||||
onlineHelp: 'chapter_pveceph',
|
||||
xtype: 'proxmoxLogView',
|
||||
url: "/api2/extjs/nodes/" + nodename + "/ceph/log"
|
||||
xtype: 'cephLogView',
|
||||
url: "/api2/extjs/nodes/" + nodename + "/ceph/log",
|
||||
nodename: nodename
|
||||
});
|
||||
}
|
||||
|
||||
|
66
www/manager6/window/CephInstall.js
Normal file
66
www/manager6/window/CephInstall.js
Normal file
@ -0,0 +1,66 @@
|
||||
/*jslint confusion: true*/
|
||||
Ext.define('PVE.ceph.Install', {
|
||||
extend: 'Ext.window.Window',
|
||||
xtype: 'pveCephInstallWindow',
|
||||
mixins: ['Proxmox.Mixin.CBind'],
|
||||
|
||||
width: 220,
|
||||
header: false,
|
||||
resizable: false,
|
||||
draggable: false,
|
||||
modal: true,
|
||||
nodename: undefined,
|
||||
shadow: false,
|
||||
border: false,
|
||||
bodyBorder: false,
|
||||
closable: false,
|
||||
cls: 'install-mask',
|
||||
bodyCls: 'install-mask',
|
||||
layout: {
|
||||
align: 'stretch',
|
||||
pack: 'center',
|
||||
type: 'vbox'
|
||||
},
|
||||
viewModel: {
|
||||
parent: null,
|
||||
data: {
|
||||
cephVersion: 'luminous'
|
||||
},
|
||||
formulas: {
|
||||
buttonText: function (get){
|
||||
return gettext('Install Ceph-') + get('cephVersion');
|
||||
}
|
||||
}
|
||||
},
|
||||
items: [
|
||||
{
|
||||
html: '<p class="install-mask">' + Ext.String.format(gettext('{0} is not installed on this node.'), 'Ceph') + '<br>' +
|
||||
gettext('Would you like to install it now?') + '</p>',
|
||||
border: false,
|
||||
padding: 5,
|
||||
bodyCls: 'install-mask'
|
||||
|
||||
},
|
||||
{
|
||||
xtype: 'button',
|
||||
bind: {
|
||||
text: '{buttonText}'
|
||||
},
|
||||
cbind: {
|
||||
nodename: '{nodename}'
|
||||
},
|
||||
handler: function() {
|
||||
var me = this.up('pveCephInstallWindow');
|
||||
var win = Ext.create('PVE.ceph.CephInstallWizard',{
|
||||
nodename: me.nodename
|
||||
});
|
||||
win.show();
|
||||
me.mon(win,'beforeClose', function(){
|
||||
me.fireEvent("cephInstallWindowClosed");
|
||||
me.close();
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
Loading…
Reference in New Issue
Block a user