mirror of
https://git.proxmox.com/git/pve-manager
synced 2025-10-04 11:36:22 +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;
|
right: 0px;
|
||||||
background-color: #555;
|
background-color: #555;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.install-mask {
|
||||||
|
background-color: rgb(245, 245, 245);
|
||||||
|
color: #000;
|
||||||
|
}
|
@ -83,6 +83,7 @@ JSSRC= \
|
|||||||
window/BackupConfig.js \
|
window/BackupConfig.js \
|
||||||
window/Settings.js \
|
window/Settings.js \
|
||||||
window/StartupEdit.js \
|
window/StartupEdit.js \
|
||||||
|
window/CephInstall.js \
|
||||||
panel/NotesView.js \
|
panel/NotesView.js \
|
||||||
grid/ResourceGrid.js \
|
grid/ResourceGrid.js \
|
||||||
grid/PoolMembers.js \
|
grid/PoolMembers.js \
|
||||||
@ -101,6 +102,8 @@ JSSRC= \
|
|||||||
ceph/Status.js \
|
ceph/Status.js \
|
||||||
ceph/StatusDetail.js \
|
ceph/StatusDetail.js \
|
||||||
ceph/Config.js \
|
ceph/Config.js \
|
||||||
|
ceph/Log.js \
|
||||||
|
ceph/CephInstallWizard.js \
|
||||||
node/Disks.js \
|
node/Disks.js \
|
||||||
node/LVM.js \
|
node/LVM.js \
|
||||||
node/LVMThin.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,
|
waitMsgTarget: me,
|
||||||
failure: function(response, opts) {
|
failure: function(response, opts) {
|
||||||
me.update(gettext('Error') + " " + response.htmlStatus);
|
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) {
|
success: function(response, opts) {
|
||||||
var data = response.result.data;
|
var data = response.result.data;
|
||||||
|
@ -15,6 +15,14 @@ Ext.define('PVE.node.CephCrushMap', {
|
|||||||
waitMsgTarget: me,
|
waitMsgTarget: me,
|
||||||
failure: function(response, opts) {
|
failure: function(response, opts) {
|
||||||
me.update(gettext('Error') + " " + response.htmlStatus);
|
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) {
|
success: function(response, opts) {
|
||||||
var data = response.result.data;
|
var data = response.result.data;
|
||||||
|
@ -161,7 +161,17 @@ Ext.define('PVE.NodeCephFSPanel', {
|
|||||||
order: 'DESC'
|
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.rstore.on('load', this.onLoad, this);
|
||||||
view.on('destroy', view.rstore.stopUpdate);
|
view.on('destroy', view.rstore.stopUpdate);
|
||||||
},
|
},
|
||||||
@ -244,7 +254,17 @@ Ext.define('PVE.NodeCephFSPanel', {
|
|||||||
order: 'DESC'
|
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.rstore.on('load', this.onLoad, this);
|
||||||
view.on('destroy', view.rstore.stopUpdate);
|
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'}]
|
sorters: [{ property: 'name'}]
|
||||||
});
|
});
|
||||||
|
|
||||||
Proxmox.Utils.monStoreErrors(me, rstore);
|
|
||||||
|
|
||||||
var service_cmd = function(cmd) {
|
var service_cmd = function(cmd) {
|
||||||
var rec = sm.getSelection()[0];
|
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();
|
me.callParent();
|
||||||
}
|
}
|
||||||
}, function() {
|
}, function() {
|
||||||
|
@ -281,7 +281,14 @@ Ext.define('PVE.node.CephOsdTree', {
|
|||||||
waitMsgTarget: me,
|
waitMsgTarget: me,
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
failure: function(response, opts) {
|
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) {
|
success: function(response, opts) {
|
||||||
sm.deselectAll();
|
sm.deselectAll();
|
||||||
|
@ -164,7 +164,17 @@ Ext.define('PVE.node.CephPoolList', {
|
|||||||
|
|
||||||
var store = Ext.create('Proxmox.data.DiffStore', { rstore: rstore });
|
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({
|
var create_btn = new Ext.Button({
|
||||||
text: gettext('Create'),
|
text: gettext('Create'),
|
||||||
|
@ -308,7 +308,18 @@ Ext.define('PVE.node.CephStatus', {
|
|||||||
me.version = me.sp.get('ceph-version');
|
me.version = me.sp.get('ceph-version');
|
||||||
me.change_version(me.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.mon(me.store, 'load', me.updateAll, me);
|
||||||
me.on('destroy', me.store.stopUpdate);
|
me.on('destroy', me.store.stopUpdate);
|
||||||
me.store.startUpdate();
|
me.store.startUpdate();
|
||||||
|
@ -375,8 +375,9 @@ Ext.define('PVE.node.Config', {
|
|||||||
iconCls: 'fa fa-list',
|
iconCls: 'fa fa-list',
|
||||||
groups: ['ceph'],
|
groups: ['ceph'],
|
||||||
onlineHelp: 'chapter_pveceph',
|
onlineHelp: 'chapter_pveceph',
|
||||||
xtype: 'proxmoxLogView',
|
xtype: 'cephLogView',
|
||||||
url: "/api2/extjs/nodes/" + nodename + "/ceph/log"
|
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