[pve-devel] [PATCH v6 manager 6/6] added basic ability to install ceph via gui
Tim Marx
t.marx at proxmox.com
Wed Feb 27 15:01:23 CET 2019
Signed-off-by: Tim Marx <t.marx at proxmox.com>
---
www/css/ext6-pve.css | 5 +
www/manager6/Makefile | 3 +
www/manager6/Utils.js | 31 ++++
www/manager6/ceph/CephInstallWizard.js | 259 +++++++++++++++++++++++++++++++++
www/manager6/ceph/Config.js | 16 ++
www/manager6/ceph/Crush.js | 16 ++
www/manager6/ceph/FS.js | 42 +++++-
www/manager6/ceph/Log.js | 70 +++++++++
www/manager6/ceph/Monitor.js | 19 ++-
www/manager6/ceph/OSD.js | 19 ++-
www/manager6/ceph/Pool.js | 18 ++-
www/manager6/ceph/Status.js | 21 ++-
www/manager6/node/Config.js | 5 +-
www/manager6/window/CephInstall.js | 66 +++++++++
14 files changed, 582 insertions(+), 8 deletions(-)
create mode 100644 www/manager6/ceph/CephInstallWizard.js
create mode 100644 www/manager6/ceph/Log.js
create mode 100644 www/manager6/window/CephInstall.js
diff --git a/www/css/ext6-pve.css b/www/css/ext6-pve.css
index 174511ac..7ac35603 100644
--- a/www/css/ext6-pve.css
+++ b/www/css/ext6-pve.css
@@ -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;
+}
\ No newline at end of file
diff --git a/www/manager6/Makefile b/www/manager6/Makefile
index e75f0de6..db5ced2d 100644
--- a/www/manager6/Makefile
+++ b/www/manager6/Makefile
@@ -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 \
diff --git a/www/manager6/Utils.js b/www/manager6/Utils.js
index b9fa25b7..83ff8a3e 100644
--- a/www/manager6/Utils.js
+++ b/www/manager6/Utils.js
@@ -1091,6 +1091,37 @@ Ext.define('PVE.Utils', { utilities: {
return;
}
}
+ },
+
+ handleStoreErrorOrMask: function(me, store, regex, callback) {
+
+ if (!(store.proxy instanceof Proxmox.RestProxy)) {
+ throw "Proxy must implement afterload event!";
+ }
+
+ me.mon(store.proxy, 'afterload', function (proxy, request, success) {
+
+ if (success) {
+ Proxmox.Utils.setErrorMask(me, false);
+ return;
+ }
+ var msg;
+ /*jslint nomen: true */
+ var operation = request._operation;
+ var error = operation.getError();
+
+ if (error.statusText) {
+ if (error.statusText.match(regex)) {
+ callback(me, error);
+ return;
+ } else {
+ msg = error.statusText + ' (' + error.status + ')';
+ }
+ } else {
+ msg = gettext('Connection error');
+ }
+ Proxmox.Utils.setErrorMask(me, msg);
+ });
}
},
diff --git a/www/manager6/ceph/CephInstallWizard.js b/www/manager6/ceph/CephInstallWizard.js
new file mode 100644
index 00000000..a6789a88
--- /dev/null
+++ b/www/manager6/ceph/CephInstallWizard.js
@@ -0,0 +1,259 @@
+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 nessecery steps, after the inital installation you will be offered to create a inital configuration.'+
+ ' The configuration step is only needed once per cluster and will be skipped if a config is already present.</p>'+
+ '<p>If you want to learn more visit <a href="http://docs.ceph.com/docs/master/">ceph.com</a> or click 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);
+ }
+ },
+ 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.store = Ext.create('Proxmox.data.UpdateStore', {
+ storeid: 'ceph-status-' + nodename,
+ interval: 1000,
+ proxy: {
+ type: 'proxmox',
+ url: '/api2/json/nodes/' + nodename + '/ceph/status',
+ listeners: {
+ exception: function(proxy, response, options){
+
+ if(response.statusText.match("not initialized", "i")){
+ me.store.stopUpdate();
+ me.down('textfield').setValue('success');
+ } else if (!response.statusText.match("not installed", "i")) {
+ me.store.stopUpdate();
+ var wizard = me.up('#wizcontent');
+ var tabs = wizard.items;
+ var lastTab = tabs.items[tabs.length-1];
+ lastTab.enable();
+ wizard.setActiveTab(lastTab);
+ }
+ }
+ }
+ },
+ listeners: {
+ load: function(rec, response, success){
+ if(success){
+ me.store.stopUpdate();
+ var wizard = me.up('#wizcontent');
+ var tabs = wizard.items;
+ var lastTab = tabs.items[tabs.length-1];
+ lastTab.enable();
+ wizard.setActiveTab(lastTab);
+ }
+ }
+ }
+ });
+ me.store.startUpdate();
+ },
+ destroy: function(){
+ var me = this;
+ me.store.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: 'chapter_pveceph',
+ html: '<h3>Installation successfull!</h3>',
+ listeners: {
+ activate: function() {
+ // notify owning container that it should display a help button
+ if (this.onlineHelp) {
+ Ext.GlobalEvents.fireEvent('proxmoxShowHelp', this.onlineHelp);
+ }
+ },
+ deactivate: function() {
+ if (this.onlineHelp) {
+ Ext.GlobalEvents.fireEvent('proxmoxHideHelp', this.onlineHelp);
+ }
+ }
+ },
+ onSubmit: function() {
+ var wizard = this.up('pveCephInstallWizard');
+ wizard.close();
+ }
+ }
+ ]
+ });
\ No newline at end of file
diff --git a/www/manager6/ceph/Config.js b/www/manager6/ceph/Config.js
index 04124684..447a9682 100644
--- a/www/manager6/ceph/Config.js
+++ b/www/manager6/ceph/Config.js
@@ -14,6 +14,22 @@ Ext.define('PVE.node.CephConfig', {
waitMsgTarget: me,
failure: function(response, opts) {
me.update(gettext('Error') + " " + response.htmlStatus);
+ var msg = response.htmlStatus;
+ var regex = new RegExp("(not installed|not initialized)", "i");
+ if (msg.match(regex)) {
+ if (Proxmox.UserName === 'root at pam') {
+ me.ownerCt.el.mask();
+ if (!me.ownerCt.down('pveCephInstallWindow')){
+ var win = Ext.create('PVE.ceph.Install', {
+ nodename: me.pveSelNode.data.node
+ });
+ me.ownerCt.add(win);
+ win.show();
+ }
+ } else {
+ me.ownerCt.mask(Ext.String.format(gettext('{0} not installed.') + gettext(' Log in as root to install.'), 'Ceph'), ['pve-static-mask']);
+ }
+ }
},
success: function(response, opts) {
var data = response.result.data;
diff --git a/www/manager6/ceph/Crush.js b/www/manager6/ceph/Crush.js
index ebd46c83..7cdfdf6d 100644
--- a/www/manager6/ceph/Crush.js
+++ b/www/manager6/ceph/Crush.js
@@ -15,6 +15,22 @@ Ext.define('PVE.node.CephCrushMap', {
waitMsgTarget: me,
failure: function(response, opts) {
me.update(gettext('Error') + " " + response.htmlStatus);
+ var msg = response.htmlStatus;
+ var regex = new RegExp("(not installed|not initialized)", "i");
+ if (msg.match(regex)) {
+ if (Proxmox.UserName === 'root at pam') {
+ me.ownerCt.el.mask();
+ if (!me.ownerCt.down('pveCephInstallWindow')){
+ var win = Ext.create('PVE.ceph.Install', {
+ nodename: me.pveSelNode.data.node
+ });
+ me.ownerCt.add(win);
+ win.show();
+ }
+ } else {
+ me.ownerCt.mask(Ext.String.format(gettext('{0} not installed.') + gettext(' Log in as root to install.'), 'Ceph'), ['pve-static-mask']);
+ }
+ }
},
success: function(response, opts) {
var data = response.result.data;
diff --git a/www/manager6/ceph/FS.js b/www/manager6/ceph/FS.js
index a1c34d73..bff1837b 100644
--- a/www/manager6/ceph/FS.js
+++ b/www/manager6/ceph/FS.js
@@ -161,7 +161,26 @@ Ext.define('PVE.NodeCephFSPanel', {
order: 'DESC'
}
}));
- Proxmox.Utils.monStoreErrors(view, view.rstore);
+ var regex = new RegExp("(not installed|not initialized)", "i");
+ PVE.Utils.handleStoreErrorOrMask(view, view.rstore, regex, function(me, error){
+ me.rstore.stopUpdate();
+ if (Proxmox.UserName === 'root at pam') {
+ me.ownerCt.el.mask();
+
+ if (!me.ownerCt.down('pveCephInstallWindow')){
+ var win = Ext.create('PVE.ceph.Install', {
+ nodename: view.nodename
+ });
+ me.ownerCt.add(win);
+ me.ownerCt.mon(win, 'cephInstallWindowClosed', function(){
+ me.rstore.startUpdate();
+ });
+ win.show();
+ }
+ } else {
+ me.ownerCt.mask(Ext.String.format(gettext('{0} not installed.') + gettext(' Log in as root to install.'), 'Ceph'), ['pve-static-mask']);
+ }
+ });
view.rstore.on('load', this.onLoad, this);
view.on('destroy', view.rstore.stopUpdate);
},
@@ -244,7 +263,26 @@ Ext.define('PVE.NodeCephFSPanel', {
order: 'DESC'
}
}));
- Proxmox.Utils.monStoreErrors(view, view.rstore);
+ var regex = new RegExp("(not installed|not initialized)", "i");
+ PVE.Utils.handleStoreErrorOrMask(view, view.rstore, regex, function(me, error){
+ me.rstore.stopUpdate();
+ if (Proxmox.UserName === 'root at pam') {
+ me.ownerCt.el.mask();
+
+ if (!me.ownerCt.down('pveCephInstallWindow')){
+ var win = Ext.create('PVE.ceph.Install', {
+ nodename: view.nodename
+ });
+ me.ownerCt.add(win);
+ me.ownerCt.mon(win, 'cephInstallWindowClosed', function(){
+ me.rstore.startUpdate();
+ });
+ win.show();
+ }
+ } else {
+ me.ownerCt.mask(Ext.String.format(gettext('{0} not installed.') + gettext(' Log in as root to install.'), 'Ceph'), ['pve-static-mask']);
+ }
+ });
view.rstore.on('load', this.onLoad, this);
view.on('destroy', view.rstore.stopUpdate);
},
diff --git a/www/manager6/ceph/Log.js b/www/manager6/ceph/Log.js
new file mode 100644
index 00000000..25178923
--- /dev/null
+++ b/www/manager6/ceph/Log.js
@@ -0,0 +1,70 @@
+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 regex = new RegExp("(not installed|not initialized)", "i");
+ if (msg.match(regex)) {
+ if (Proxmox.UserName === 'root at pam') {
+ me.el.mask();
+
+ if (!me.down('pveCephInstallWindow')){
+ var win = Ext.create('PVE.ceph.Install', {
+ nodename: me.nodename
+ });
+ me.add(win);
+ win.show();
+ }
+
+ } else {
+ me.mask(Ext.String.format(gettext('{0} not installed.') + gettext(' Log in as root to install.'), 'Ceph'), ['pve-static-mask']);
+ }
+
+ } else {
+ Proxmox.Utils.setErrorMask(me, msg);
+ }
+ }
+ });
+ }
+});
\ No newline at end of file
diff --git a/www/manager6/ceph/Monitor.js b/www/manager6/ceph/Monitor.js
index a3a18a83..476ed8cc 100644
--- a/www/manager6/ceph/Monitor.js
+++ b/www/manager6/ceph/Monitor.js
@@ -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,24 @@ Ext.define('PVE.node.CephMonList', {
}
});
+ var regex = new RegExp("(not installed|not initialized)", "i");
+ PVE.Utils.handleStoreErrorOrMask(me, rstore, regex, function(me, error){
+ me.store.rstore.stopUpdate();
+ if (Proxmox.UserName === 'root at pam') {
+ me.el.mask();
+ var win = Ext.create('PVE.ceph.Install', {
+ nodename: nodename
+ });
+ me.add(win);
+ me.mon(win, 'cephInstallWindowClosed', function(){
+ me.store.rstore.startUpdate();
+ });
+ win.show();
+ } else {
+ me.el.mask(Ext.String.format(gettext('{0} not installed.') + gettext(' Log in as root to install.'), 'Ceph'), ['pve-static-mask']);
+ }
+ });
+
me.callParent();
}
}, function() {
diff --git a/www/manager6/ceph/OSD.js b/www/manager6/ceph/OSD.js
index 144fab7e..f635cbd6 100644
--- a/www/manager6/ceph/OSD.js
+++ b/www/manager6/ceph/OSD.js
@@ -281,7 +281,24 @@ Ext.define('PVE.node.CephOsdTree', {
waitMsgTarget: me,
method: 'GET',
failure: function(response, opts) {
- Proxmox.Utils.setErrorMask(me, response.htmlStatus);
+ var msg = response.htmlStatus;
+ var regex = new RegExp("(not installed|not initialized)", "i");
+ if (msg.match(regex)) {
+ if (Proxmox.UserName === 'root at pam') {
+ me.el.mask();
+ if (!me.down('pveCephInstallWindow')){
+ var win = Ext.create('PVE.ceph.Install', {
+ nodename: me.pveSelNode.data.node
+ });
+ me.add(win);
+ win.show();
+ }
+ } else {
+ me.mask(Ext.String.format(gettext('{0} not installed.') + gettext(' Log in as root to install.'), 'Ceph'), ['pve-static-mask']);
+ }
+ } else {
+ Proxmox.Utils.setErrorMask(me, msg);
+ }
},
success: function(response, opts) {
sm.deselectAll();
diff --git a/www/manager6/ceph/Pool.js b/www/manager6/ceph/Pool.js
index 27eba024..c7dd2248 100644
--- a/www/manager6/ceph/Pool.js
+++ b/www/manager6/ceph/Pool.js
@@ -164,7 +164,23 @@ 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|not initialized)", "i");
+ PVE.Utils.handleStoreErrorOrMask(me, rstore, regex, function(me, error){
+ me.store.rstore.stopUpdate();
+ if (Proxmox.UserName === 'root at pam') {
+ me.el.mask();
+ var win = Ext.create('PVE.ceph.Install', {
+ nodename: nodename
+ });
+ me.add(win);
+ me.mon(win, 'cephInstallWindowClosed', function(){
+ me.store.rstore.startUpdate();
+ });
+ win.show();
+ } else {
+ me.el.mask(Ext.String.format(gettext('{0} not installed.') + gettext(' Log in as root to install.'), 'Ceph'), ['pve-static-mask']);
+ }
+ });
var create_btn = new Ext.Button({
text: gettext('Create'),
diff --git a/www/manager6/ceph/Status.js b/www/manager6/ceph/Status.js
index 78fa1cf8..ea4e27e7 100644
--- a/www/manager6/ceph/Status.js
+++ b/www/manager6/ceph/Status.js
@@ -308,7 +308,26 @@ 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|not initialized)", "i");
+ PVE.Utils.handleStoreErrorOrMask(me, me.store, regex, function(me, error){
+ me.store.stopUpdate();
+ if (Proxmox.UserName === 'root at pam') {
+ me.el.mask();
+ if (!me.down('PVE.ceph.Install')){
+ var win = Ext.create('PVE.ceph.Install', {
+ nodename: nodename
+ });
+ me.add(win);
+ me.mon(win, 'cephInstallWindowClosed', function(){
+ me.store.startUpdate();
+ });
+ win.show();
+ }
+ } else {
+ me.el.mask(Ext.String.format(gettext('{0} not installed.') + gettext(' Log in as root to install.'), 'Ceph'), ['pve-static-mask']);
+ }
+ });
+
me.mon(me.store, 'load', me.updateAll, me);
me.on('destroy', me.store.stopUpdate);
me.store.startUpdate();
diff --git a/www/manager6/node/Config.js b/www/manager6/node/Config.js
index f9a62670..831d2e02 100644
--- a/www/manager6/node/Config.js
+++ b/www/manager6/node/Config.js
@@ -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
});
}
diff --git a/www/manager6/window/CephInstall.js b/www/manager6/window/CephInstall.js
new file mode 100644
index 00000000..20ecdd16
--- /dev/null
+++ b/www/manager6/window/CephInstall.js
@@ -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();
+ });
+
+ }
+ }
+ ]
+});
--
2.11.0
More information about the pve-devel
mailing list