]>
git.proxmox.com Git - pve-manager.git/blob - www/manager6/ceph/ServiceList.js
1 Ext
.define('PVE.CephCreateService', {
2 extend
: 'Proxmox.window.Edit',
3 xtype
: 'pveCephCreateService',
7 setNode: function(nodename
) {
9 me
.nodename
= nodename
;
10 me
.url
= `/nodes/${nodename}/ceph/${me.type}/${nodename}`;
18 xtype
: 'pveNodeSelector',
20 fieldLabel
: gettext('Host'),
24 change: function(f
, value
) {
25 let view
= this.up('pveCephCreateService');
32 initComponent: function() {
36 throw "no node name specified";
39 throw "no type specified";
41 me
.setNode(me
.nodename
);
47 Ext
.define('PVE.node.CephServiceController', {
48 extend
: 'Ext.app.ViewController',
49 alias
: 'controller.CephServiceList',
51 render_status
: (value
, metadata
, rec
) => value
,
53 render_version: function(value
, metadata
, rec
) {
54 if (value
=== undefined) {
57 let view
= this.getView();
58 let host
= rec
.data
.host
, nodev
= [0];
59 if (view
.nodeversions
[host
] !== undefined) {
60 nodev
= view
.nodeversions
[host
].version
.parts
;
64 if (PVE
.Utils
.compare_ceph_versions(view
.maxversion
, nodev
) > 0) {
65 icon
= PVE
.Utils
.get_ceph_icon_html('HEALTH_UPGRADE');
66 } else if (PVE
.Utils
.compare_ceph_versions(nodev
, value
) > 0) {
67 icon
= PVE
.Utils
.get_ceph_icon_html('HEALTH_OLD');
68 } else if (view
.mixedversions
) {
69 icon
= PVE
.Utils
.get_ceph_icon_html('HEALTH_OK');
74 getMaxVersions: function(store
, records
, success
) {
75 if (!success
|| records
.length
< 1) {
79 let view
= me
.getView();
81 view
.nodeversions
= records
[0].data
.node
;
83 view
.mixedversions
= false;
84 for (const [_nodename
, data
] of Object
.entries(view
.nodeversions
)) {
85 let res
= PVE
.Utils
.compare_ceph_versions(data
.version
.parts
, view
.maxversion
);
86 if (res
!== 0 && view
.maxversion
.length
> 0) {
87 view
.mixedversions
= true;
90 view
.maxversion
= data
.version
.parts
;
95 init: function(view
) {
96 if (view
.pveSelNode
) {
97 view
.nodename
= view
.pveSelNode
.data
.node
;
100 throw "no node name specified";
104 throw "no type specified";
107 view
.versionsstore
= Ext
.create('Proxmox.data.UpdateStore', {
110 storeid
: `ceph-versions-${view.type}-list${view.nodename}`,
113 url
: "/api2/json/cluster/ceph/metadata?scope=versions",
116 view
.versionsstore
.on('load', this.getMaxVersions
, this);
117 view
.on('destroy', view
.versionsstore
.stopUpdate
);
119 view
.rstore
= Ext
.create('Proxmox.data.UpdateStore', {
122 storeid
: `ceph-${view.type}-list${view.nodename}`,
123 model
: 'ceph-service-list',
126 url
: `/api2/json/nodes/${view.nodename}/ceph/${view.type}`,
130 view
.setStore(Ext
.create('Proxmox.data.DiffStore', {
132 sorters
: [{ property
: 'name' }],
135 if (view
.storeLoadCallback
) {
136 view
.rstore
.on('load', view
.storeLoadCallback
, this);
138 view
.on('destroy', view
.rstore
.stopUpdate
);
140 if (view
.showCephInstallMask
) {
141 PVE
.Utils
.monitor_ceph_installed(view
, view
.rstore
, view
.nodename
, true);
145 service_cmd: function(rec
, cmd
) {
146 let view
= this.getView();
147 if (!rec
.data
.host
) {
148 Ext
.Msg
.alert(gettext('Error'), "entry has no host");
151 let doRequest = function() {
152 Proxmox
.Utils
.API2Request({
153 url
: `/nodes/${rec.data.host}/ceph/${cmd}`,
155 params
: { service
: view
.type
+ '.' + rec
.data
.name
},
156 success: function(response
, options
) {
157 Ext
.create('Proxmox.window.TaskProgress', {
159 upid
: response
.result
.data
,
160 taskDone
: () => view
.rstore
.load(),
163 failure
: (response
, _opts
) => Ext
.Msg
.alert(gettext('Error'), response
.htmlStatus
),
166 if (cmd
=== "stop" && ['mon', 'mds'].includes(view
.type
)) {
167 Proxmox
.Utils
.API2Request({
168 url
: `/nodes/${rec.data.host}/ceph/cmd-safety`,
175 success: function({ result
: { data
} }) {
177 mon
: gettext('Stop MON'),
178 mds
: gettext('Stop MDS'),
182 title
: gettext('Warning'),
183 message
: data
.status
,
184 icon
: Ext
.Msg
.WARNING
,
185 buttons
: Ext
.Msg
.OKCANCEL
,
186 buttonText
: { ok
: stopText
[view
.type
] },
187 fn: function(selection
) {
188 if (selection
=== 'ok') {
197 failure
: (response
, _opts
) => Ext
.Msg
.alert(gettext('Error'), response
.htmlStatus
),
203 onChangeService: function(button
) {
205 let record
= me
.getView().getSelection()[0];
206 me
.service_cmd(record
, button
.action
);
209 showSyslog: function() {
210 let view
= this.getView();
211 let rec
= view
.getSelection()[0];
212 let service
= `ceph-${view.type}@${rec.data.name}`;
213 Ext
.create('Ext.window.Window', {
214 title
: `${gettext('Syslog')}: ${service}`,
221 xtype
: 'proxmoxLogView',
222 url
: `/api2/extjs/nodes/${rec.data.host}/syslog?service=${encodeURIComponent(service)}`,
223 log_select_timespan
: 1,
228 onCreate: function() {
229 let view
= this.getView();
230 Ext
.create('PVE.CephCreateService', {
232 nodename
: view
.nodename
,
233 subject
: view
.getTitle(),
235 taskDone
: () => view
.rstore
.load(),
240 Ext
.define('PVE.node.CephServiceList', {
241 extend
: 'Ext.grid.GridPanel',
242 xtype
: 'pveNodeCephServiceList',
244 onlineHelp
: 'chapter_pveceph',
245 emptyText
: gettext('No such service configured.'),
249 // will be called when the store loads
250 storeLoadCallback
: Ext
.emptyFn
,
252 // if set to true, does shows the ceph install mask if needed
253 showCephInstallMask
: false,
255 controller
: 'CephServiceList',
259 xtype
: 'proxmoxButton',
260 text
: gettext('Start'),
261 iconCls
: 'fa fa-play',
264 enableFn
: rec
=> rec
.data
.state
=== 'stopped' || rec
.data
.state
=== 'unknown',
265 handler
: 'onChangeService',
268 xtype
: 'proxmoxButton',
269 text
: gettext('Stop'),
270 iconCls
: 'fa fa-stop',
272 enableFn
: rec
=> rec
.data
.state
!== 'stopped',
274 handler
: 'onChangeService',
277 xtype
: 'proxmoxButton',
278 text
: gettext('Restart'),
279 iconCls
: 'fa fa-refresh',
282 enableFn
: rec
=> rec
.data
.state
!== 'stopped',
283 handler
: 'onChangeService',
287 text
: gettext('Create'),
288 reference
: 'createButton',
292 text
: gettext('Destroy'),
293 xtype
: 'proxmoxStdRemoveButton',
294 getUrl: function(rec
) {
295 let view
= this.up('grid');
296 if (!rec
.data
.host
) {
297 Ext
.Msg
.alert(gettext('Error'), "entry has no host, cannot build API url");
300 return `/nodes/${rec.data.host}/ceph/${view.type}/${rec.data.name}`;
302 callback: function(options
, success
, response
) {
303 let view
= this.up('grid');
305 Ext
.Msg
.alert(gettext('Error'), response
.htmlStatus
);
308 Ext
.create('Proxmox.window.TaskProgress', {
310 upid
: response
.result
.data
,
311 taskDone
: () => view
.rstore
.load(),
314 handler: function(btn
, event
, rec
) {
316 let view
= me
.up('grid');
317 let doRequest = function() {
318 Proxmox
.button
.StdRemoveButton
.prototype.handler
.call(me
, btn
, event
, rec
);
320 if (view
.type
=== 'mon') {
321 Proxmox
.Utils
.API2Request({
322 url
: `/nodes/${rec.data.host}/ceph/cmd-safety`,
329 success: function({ result
: { data
} }) {
332 title
: gettext('Warning'),
333 message
: data
.status
,
334 icon
: Ext
.Msg
.WARNING
,
335 buttons
: Ext
.Msg
.OKCANCEL
,
336 buttonText
: { ok
: gettext('Destroy MON') },
337 fn: function(selection
) {
338 if (selection
=== 'ok') {
347 failure
: (response
, _opts
) => Ext
.Msg
.alert(gettext('Error'), response
.htmlStatus
),
357 xtype
: 'proxmoxButton',
358 text
: gettext('Syslog'),
360 handler
: 'showSyslog',
366 header
: gettext('Name'),
369 renderer: function(v
) {
370 return this.type
+ '.' + v
;
375 header
: gettext('Host'),
378 renderer: function(v
) {
379 return v
|| Proxmox
.Utils
.unknownText
;
384 header
: gettext('Status'),
387 renderer
: 'render_status',
391 header
: gettext('Address'),
394 renderer: function(v
) {
395 return v
|| Proxmox
.Utils
.unknownText
;
400 header
: gettext('Version'),
403 dataIndex
: 'version',
404 renderer
: 'render_version',
408 initComponent: function() {
411 if (me
.additionalColumns
) {
412 me
.columns
= me
.columns
.concat(me
.additionalColumns
);
419 Ext
.define('ceph-service-list', {
420 extend
: 'Ext.data.Model',
430 'ceph_version_short',
434 calculate
: data
=> PVE
.Utils
.parse_ceph_version(data
),
441 Ext
.define('PVE.node.CephMDSServiceController', {
442 extend
: 'PVE.node.CephServiceController',
443 alias
: 'controller.CephServiceMDSList',
445 render_status
: (value
, mD
, rec
) => rec
.data
.fs_name
? `${value} (${rec.data.fs_name})` : value
,
448 Ext
.define('PVE.node.CephMDSList', {
449 extend
: 'PVE.node.CephServiceList',
450 xtype
: 'pveNodeCephMDSList',
453 type
: 'CephServiceMDSList',