"use strict" ;
const Promise = require ( "bluebird" ) ;
const dlayerSource = require ( "../../packages/dlayer-source" ) ;
const treecutter = require ( "../../packages/treecutter" ) ;
const upperSnakeCase = require ( "../../packages/upper-snake-case" ) ;
const types = require ( "./" ) ;
module . exports = function Drive ( { path } ) {
return dlayerSource . withSources ( {
path : path ,
blockDevice : async function ( _ , { $getProperty } ) {
if ( await $getProperty ( this , "interface" ) === "nvme" ) {
return null ;
} else {
return types . BlockDevice ( { path : path } ) ;
}
} ,
allBlockDevices : async function ( _ , { $getProperty , sources } ) {
return Promise . try ( async ( ) => {
if ( await $getProperty ( this , "interface" ) === "nvme" ) {
return Promise . try ( ( ) => {
return sources . nvmeListNamespaces . load ( path ) ;
} ) . map ( ( namespaceID ) => {
return ` ${ path } n ${ namespaceID } ` ;
} ) ;
} else {
return [ path ] ;
}
} ) . then ( ( rootPaths ) => {
let queries = rootPaths . map ( ( path ) => ( { path : path } ) ) ;
return sources . lsblk . loadMany ( queries ) ;
} ) . map ( ( blockDeviceTree ) => {
return treecutter . map ( blockDeviceTree , ( device ) => types . BlockDevice ( device ) ) ;
} ) . then ( ( resultArray ) => {
// Treecutter always returns an array, regardless of whether the input was an array or not, so we need to flatten it since we will only ever have a single root entry per rootPath query here
return resultArray . flat ( ) ;
} ) ;
} ,
$sources : {
// lsblk: {
// [dlayerSource.ID]: { path },
// },
smartctlScan : {
[ dlayerSource . ID ] : path ,
interface : "interface"
} ,
smartctlInfo : {
[ dlayerSource . ID ] : path ,
model : "model" ,
modelFamily : "modelFamily" ,
smartAvailable : "smartAvailable" ,
smartEnabled : "smartEnabled" ,
serialNumber : "serialNumber" ,
wwn : "wwn" ,
firmwareVersion : "firmwareVersion" ,
size : "size" ,
rpm : "rpm" ,
logicalSectorSize : ( device ) => device . sectorSizes . logical ,
physicalSectorSize : ( device ) => device . sectorSizes . physical ,
formFactor : "formFactor" ,
ataVersion : "ataVersion" ,
sataVersion : "sataVersion"
} ,
smartctlAttributes : {
[ dlayerSource . ID ] : path ,
smartAttributes : ( attributes ) => {
return attributes . map ( ( attribute ) => {
return {
... attribute ,
type : upperSnakeCase ( attribute . type ) ,
updatedWhen : upperSnakeCase ( attribute . updatedWhen )
} ;
} ) ;
} ,
smartHealth : ( attributes ) => {
let failed = attributes . filter ( ( item ) => {
return ( item . failingNow === true || item . failedBefore === true ) ;
} ) ;
let deteriorating = attributes . filter ( ( item ) => {
return ( item . type === "preFail" && item . worstValueSeen < 100 ) ;
} ) ;
if ( failed . length > 0 ) {
return "FAILING" ;
} else if ( deteriorating . length > 0 ) {
return "DETERIORATING" ;
} else {
return "HEALTHY" ;
}
}
}
}
} ) ;
} ;