2016-09-06 17:59:40 +03:00
Ext . define ( 'PVE.node.DiskList' , {
extend : 'Ext.grid.GridPanel' ,
alias : 'widget.pveNodeDiskList' ,
emptyText : gettext ( 'No Disks found' ) ,
2016-11-08 12:50:46 +03:00
stateful : true ,
stateId : 'grid-node-disks' ,
2016-09-06 17:59:40 +03:00
columns : [
{
header : gettext ( 'Device' ) ,
width : 100 ,
sortable : true ,
dataIndex : 'devpath'
} ,
{
header : gettext ( 'Type' ) ,
width : 80 ,
sortable : true ,
dataIndex : 'type' ,
renderer : function ( v ) {
if ( v === 'ssd' ) {
return 'SSD' ;
} else if ( v === 'hdd' ) {
return 'Hard Disk' ;
} else if ( v === 'usb' ) {
return 'USB' ;
} else {
return gettext ( 'Unknown' ) ;
}
}
} ,
{
header : gettext ( 'Usage' ) ,
width : 80 ,
sortable : false ,
renderer : function ( v , metaData , rec ) {
2017-08-04 17:32:49 +03:00
if ( rec ) {
if ( rec . data . osdid >= 0 ) {
var bluestore = '' ;
if ( rec . data . bluestore === 1 ) {
bluestore = ' (Bluestore)' ;
}
return "Ceph osd." + rec . data . osdid . toString ( ) + bluestore ;
}
var types = [ ] ;
if ( rec . data . journals > 0 ) {
types . push ( 'Journal' ) ;
}
if ( rec . data . db > 0 ) {
types . push ( 'DB' ) ;
}
if ( rec . data . wal > 0 ) {
types . push ( 'WAL' ) ;
}
if ( types . length > 0 ) {
return 'Ceph (' + types . join ( ', ' ) + ')' ;
}
2016-09-06 17:59:40 +03:00
}
2017-08-04 17:32:49 +03:00
2018-01-15 17:18:09 +03:00
return v || Proxmox . Utils . noText ;
2016-09-06 17:59:40 +03:00
} ,
dataIndex : 'used'
} ,
{
header : gettext ( 'Size' ) ,
width : 100 ,
align : 'right' ,
sortable : true ,
2018-01-15 17:18:09 +03:00
renderer : Proxmox . Utils . format _size ,
2016-09-06 17:59:40 +03:00
dataIndex : 'size'
} ,
{
2017-03-01 13:34:07 +03:00
header : 'GPT' ,
2016-09-06 17:59:40 +03:00
width : 60 ,
align : 'right' ,
renderer : function ( value ) {
if ( value ) {
2018-01-15 17:18:09 +03:00
return Proxmox . Utils . yesText ;
2016-09-06 17:59:40 +03:00
} else {
2018-01-15 17:18:09 +03:00
return Proxmox . Utils . noText ;
2016-09-06 17:59:40 +03:00
}
} ,
dataIndex : 'gpt'
} ,
{
header : gettext ( 'Vendor' ) ,
width : 100 ,
sortable : true ,
2016-10-04 14:39:35 +03:00
renderer : Ext . String . htmlEncode ,
2016-09-06 17:59:40 +03:00
dataIndex : 'vendor'
} ,
{
header : gettext ( 'Model' ) ,
width : 200 ,
sortable : true ,
2016-10-04 14:39:35 +03:00
renderer : Ext . String . htmlEncode ,
2016-09-06 17:59:40 +03:00
dataIndex : 'model'
} ,
{
header : gettext ( 'Serial' ) ,
width : 200 ,
sortable : true ,
2016-10-04 14:39:35 +03:00
renderer : Ext . String . htmlEncode ,
2016-09-06 17:59:40 +03:00
dataIndex : 'serial'
} ,
{
header : 'S.M.A.R.T.' ,
width : 100 ,
sortable : true ,
2016-10-04 14:39:35 +03:00
renderer : Ext . String . htmlEncode ,
2016-09-06 17:59:40 +03:00
dataIndex : 'health'
} ,
{
header : 'Wearout' ,
width : 100 ,
sortable : true ,
dataIndex : 'wearout' ,
renderer : function ( value ) {
if ( Ext . isNumeric ( value ) ) {
return ( 100 - value ) . toString ( ) + '%' ;
}
return 'N/A' ;
}
}
] ,
initComponent : function ( ) {
/*jslint confusion: true */
var me = this ;
var nodename = me . pveSelNode . data . node ;
if ( ! nodename ) {
throw "no node name specified" ;
}
var sm = Ext . create ( 'Ext.selection.RowModel' , { } ) ;
var store = Ext . create ( 'Ext.data.Store' , {
storeid : 'node-disk-list' + nodename ,
model : 'node-disk-list' ,
proxy : {
2017-12-11 16:46:51 +03:00
type : 'proxmox' ,
2016-09-06 17:59:40 +03:00
url : "/api2/json/nodes/" + nodename + "/disks/list"
} ,
sorters : [
{
property : 'dev' ,
direction : 'ASC'
}
]
} ) ;
2018-01-15 17:18:08 +03:00
var reloadButton = Ext . create ( 'Proxmox.button.Button' , {
2016-09-06 17:59:40 +03:00
text : gettext ( 'Reload' ) ,
handler : function ( ) {
me . store . load ( ) ;
}
} ) ;
2018-01-15 17:18:08 +03:00
var smartButton = Ext . create ( 'Proxmox.button.Button' , {
2016-09-06 17:59:40 +03:00
text : gettext ( 'Show S.M.A.R.T. values' ) ,
selModel : sm ,
enableFn : function ( ) {
return ! ! sm . getSelection ( ) . length ;
} ,
disabled : true ,
handler : function ( ) {
var rec = sm . getSelection ( ) [ 0 ] ;
var win = Ext . create ( 'PVE.DiskSmartWindow' , {
nodename : nodename ,
dev : rec . data . devpath
} ) ;
win . show ( ) ;
}
} ) ;
2018-01-15 17:18:08 +03:00
var initButton = Ext . create ( 'Proxmox.button.Button' , {
2016-09-06 17:59:40 +03:00
text : gettext ( 'Initialize Disk with GPT' ) ,
selModel : sm ,
enableFn : function ( ) {
var selection = sm . getSelection ( ) ;
if ( ! selection . length || selection [ 0 ] . data . used ) {
return false ;
} else {
return true ;
}
} ,
disabled : true ,
handler : function ( ) {
var rec = sm . getSelection ( ) [ 0 ] ;
2018-01-15 17:18:09 +03:00
Proxmox . Utils . API2Request ( {
2016-09-06 17:59:40 +03:00
url : '/api2/extjs/nodes/' + nodename + '/disks/initgpt' ,
waitMsgTarget : me ,
method : 'POST' ,
params : { disk : rec . data . devpath } ,
failure : function ( response , options ) {
Ext . Msg . alert ( gettext ( 'Error' ) , response . htmlStatus ) ;
} ,
success : function ( response , options ) {
var upid = response . result . data ;
2017-12-06 20:30:16 +03:00
var win = Ext . create ( 'Proxmox.window.TaskProgress' , {
2016-09-06 17:59:40 +03:00
upid : upid
} ) ;
win . show ( ) ;
}
} ) ;
}
} ) ;
2016-10-04 14:39:36 +03:00
me . loadCount = 1 ; // avoid duplicate loadmask
2018-01-15 17:18:09 +03:00
Proxmox . Utils . monStoreErrors ( me , store ) ;
2016-10-04 14:39:36 +03:00
2016-09-06 17:59:40 +03:00
Ext . apply ( me , {
store : store ,
selModel : sm ,
tbar : [ reloadButton , smartButton , initButton ] ,
listeners : {
itemdblclick : function ( ) {
var rec = sm . getSelection ( ) [ 0 ] ;
var win = Ext . create ( 'PVE.DiskSmartWindow' , {
nodename : nodename ,
dev : rec . data . devpath
} ) ;
win . show ( ) ;
}
}
} ) ;
me . callParent ( ) ;
me . store . load ( ) ;
}
} , function ( ) {
Ext . define ( 'node-disk-list' , {
extend : 'Ext.data.Model' ,
fields : [ 'devpath' , 'used' , { name : 'size' , type : 'number' } ,
{ name : 'osdid' , type : 'number' } ,
'vendor' , 'model' , 'serial' , 'rpm' , 'type' , 'health' , 'wearout' ] ,
idProperty : 'devpath'
} ) ;
} ) ;
Ext . define ( 'PVE.DiskSmartWindow' , {
extend : 'Ext.window.Window' ,
alias : 'widget.pveSmartWindow' ,
modal : true ,
items : [
{
xtype : 'gridpanel' ,
layout : {
type : 'fit'
} ,
emptyText : gettext ( 'No S.M.A.R.T. Values' ) ,
scrollable : true ,
flex : 1 ,
itemId : 'smarts' ,
reserveScrollbar : true ,
columns : [
{ text : 'ID' , dataIndex : 'id' , width : 50 } ,
2016-10-04 14:39:35 +03:00
{ text : gettext ( 'Attribute' ) , flex : 1 , dataIndex : 'name' , renderer : Ext . String . htmlEncode } ,
{ text : gettext ( 'Value' ) , dataIndex : 'raw' , renderer : Ext . String . htmlEncode } ,
2016-09-06 17:59:40 +03:00
{ text : gettext ( 'Normalized' ) , dataIndex : 'value' , width : 60 } ,
{ text : gettext ( 'Threshold' ) , dataIndex : 'threshold' , width : 60 } ,
{ text : gettext ( 'Worst' ) , dataIndex : 'worst' , width : 60 } ,
{ text : gettext ( 'Flags' ) , dataIndex : 'flags' } ,
2016-10-04 14:39:35 +03:00
{ text : gettext ( 'Failing' ) , dataIndex : 'fail' , renderer : Ext . String . htmlEncode }
2016-09-06 17:59:40 +03:00
]
2016-10-04 14:39:37 +03:00
} ,
{
xtype : 'component' ,
itemId : 'text' ,
layout : {
type : 'fit'
} ,
hidden : true ,
style : {
'background-color' : 'white' ,
'white-space' : 'pre' ,
'font-family' : 'monospace'
}
2016-09-06 17:59:40 +03:00
}
] ,
buttons : [
{
text : gettext ( 'Reload' ) ,
name : 'reload' ,
handler : function ( ) {
var me = this ;
me . up ( 'window' ) . store . reload ( ) ;
}
} ,
{
text : gettext ( 'Close' ) ,
name : 'close' ,
handler : function ( ) {
var me = this ;
me . up ( 'window' ) . close ( ) ;
}
}
] ,
layout : {
type : 'vbox' ,
align : 'stretch'
} ,
width : 800 ,
height : 500 ,
minWidth : 600 ,
minHeight : 400 ,
bodyPadding : 5 ,
title : gettext ( 'S.M.A.R.T. Values' ) ,
initComponent : function ( ) {
var me = this ;
var nodename = me . nodename ;
if ( ! nodename ) {
throw "no node name specified" ;
}
var dev = me . dev ;
if ( ! dev ) {
throw "no device specified" ;
}
me . store = Ext . create ( 'Ext.data.Store' , {
2016-10-04 14:39:36 +03:00
model : 'disk-smart' ,
2016-09-06 17:59:40 +03:00
proxy : {
2017-12-11 16:46:51 +03:00
type : 'proxmox' ,
2016-09-06 17:59:40 +03:00
url : "/api2/json/nodes/" + nodename + "/disks/smart?disk=" + dev
}
} ) ;
me . callParent ( ) ;
2016-10-04 14:39:36 +03:00
var grid = me . down ( '#smarts' ) ;
2016-10-04 14:39:37 +03:00
var text = me . down ( '#text' ) ;
2016-10-04 14:39:36 +03:00
2018-01-15 17:18:09 +03:00
Proxmox . Utils . monStoreErrors ( grid , me . store ) ;
2016-10-04 14:39:36 +03:00
me . mon ( me . store , 'load' , function ( s , records , success ) {
if ( success && records . length > 0 ) {
var rec = records [ 0 ] ;
2016-10-04 14:39:37 +03:00
switch ( rec . data . type ) {
case 'text' :
grid . setVisible ( false ) ;
text . setVisible ( true ) ;
text . setHtml ( Ext . String . htmlEncode ( rec . data . text ) ) ;
break ;
default :
// includes 'ata'
// cannot use empty case because
// of jslint
grid . setVisible ( true ) ;
text . setVisible ( false ) ;
grid . setStore ( rec . attributes ( ) ) ;
break ;
}
2016-10-04 14:39:36 +03:00
}
} ) ;
2016-09-06 17:59:40 +03:00
me . store . load ( ) ;
}
} , function ( ) {
Ext . define ( 'disk-smart' , {
extend : 'Ext.data.Model' ,
fields : [
2016-10-04 14:39:37 +03:00
{ name : 'health' } ,
{ name : 'type' } ,
{ name : 'text' }
2016-09-06 17:59:40 +03:00
] ,
hasMany : { model : 'smart-attribute' , name : 'attributes' }
} ) ;
Ext . define ( 'smart-attribute' , {
extend : 'Ext.data.Model' ,
fields : [
{ name : 'id' , type : 'number' } , 'name' , 'value' , 'worst' , 'threshold' , 'flags' , 'fail' , 'raw'
2016-12-06 18:26:41 +03:00
]
2016-09-06 17:59:40 +03:00
} ) ;
} ) ;