@ -5,11 +5,9 @@ const graphql = require("graphql");
const fs = require ( "fs" ) ;
const fs = require ( "fs" ) ;
const path = require ( "path" ) ;
const path = require ( "path" ) ;
const matchOrError = require ( "../match-or-error" ) ;
const upperSnakeCase = require ( "../upper-snake-case" ) ;
const All = require ( "../graphql/symbols/all" ) ;
const createGraphQLInterface = require ( "../graphql/index" ) ;
const createGraphQLInterface = require ( "../graphql/index" ) ;
const { ID , LocalProperties , createDataObject } = require ( "../graphql/data-object" ) ;
const All = require ( "../graphql/symbols/all" ) ;
const loadTypes = require ( "../graphql/type-loader" ) ;
const createLoaders = require ( "./loaders" ) ;
const createLoaders = require ( "./loaders" ) ;
@ -44,132 +42,12 @@ new graphql.GraphQLScalarType({
let schema = graphql . buildSchema ( fs . readFileSync ( path . resolve ( _ _dirname , "../schemas/main.gql" ) , "utf8" ) ) ;
let schema = graphql . buildSchema ( fs . readFileSync ( path . resolve ( _ _dirname , "../schemas/main.gql" ) , "utf8" ) ) ;
function createBlockDevice ( { name , path } ) {
let types = loadTypes ( {
if ( name != null ) {
Drive : require ( "./types/drive" ) ,
path = ` /dev/ ${ name } ` ;
BlockDevice : require ( "./types/block-device" ) ,
} else if ( path != null ) {
LVMPhysicalVolume : require ( "./types/lvm-physical-volume" ) ,
let match = matchOrError ( /^\/dev\/(.+)$/ , path ) ;
LVMVolumeGroup : require ( "./types/lvm-volume-group" ) ,
name = match [ 0 ] ;
} ) ;
}
/* FIXME: parent */
return createDataObject ( {
[ LocalProperties ] : {
path : path
} ,
lsblk : {
[ ID ] : name ,
name : "name" ,
size : "size" ,
mountpoint : "mountpoint" ,
deviceNumber : "deviceNumber" ,
removable : "removable" ,
readOnly : "readOnly" ,
children : ( device ) => {
return device . children . map ( ( child ) => {
return createBlockDevice ( { name : child . name } ) ;
} ) ;
}
}
} ) ;
}
function createPhysicalVolume ( { path } ) {
return createDataObject ( {
[ LocalProperties ] : {
path : path ,
blockDevice : ( ) => {
return createBlockDevice ( { path : path } ) ;
}
} ,
lvmPhysicalVolumes : {
[ ID ] : path ,
volumeGroup : ( volume ) => {
if ( volume . volumeGroup != null ) {
return createVolumeGroup ( { name : volume . volumeGroup } ) ;
}
} ,
format : "format" ,
size : "totalSpace" ,
freeSpace : "freeSpace" ,
duplicate : "isDuplicate" ,
allocatable : "isAllocatable" ,
used : "isUsed" ,
exported : "isExported" ,
missing : "isMissing"
}
} ) ;
}
function createVolumeGroup ( { name } ) {
return createDataObject ( {
[ LocalProperties ] : {
name : name
}
} ) ;
}
function createDrive ( { path } ) {
return createDataObject ( {
[ LocalProperties ] : {
path : path ,
blockDevice : ( ) => {
return createBlockDevice ( { path : path } ) ;
} ,
/* FIXME: allBlockDevices, for representing every single block device that's hosted on this physical drive, linearly. Need to figure out how that works with representation of mdraid arrays, LVM volumes, etc. */
} ,
smartctlScan : {
[ ID ] : path ,
interface : "interface"
} ,
smartctlInfo : {
[ 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 : {
[ ID ] : path ,
smartAttributes : ( attributes ) => {
return attributes . map ( ( attribute ) => {
return Object . assign ( { } , 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" ;
}
}
}
} ) ;
}
module . exports = function ( ) {
module . exports = function ( ) {
return createGraphQLInterface ( schema , { loaderFactory : createLoaders } , {
return createGraphQLInterface ( schema , { loaderFactory : createLoaders } , {
@ -183,7 +61,7 @@ module.exports = function () {
}
}
} ) . then ( ( devices ) => {
} ) . then ( ( devices ) => {
return devices . map ( ( device ) => {
return devices . map ( ( device ) => {
return crea teDrive( { path : device . path } ) ;
return typ es. Drive( { path : device . path } ) ;
} ) ;
} ) ;
} ) ;
} ) ;
}
}
@ -198,7 +76,7 @@ module.exports = function () {
}
}
} ) . then ( ( devices ) => {
} ) . then ( ( devices ) => {
return devices . map ( ( device ) => {
return devices . map ( ( device ) => {
return crea teBlockDevice( { name : device . name } ) ;
return typ es. BlockDevice( { name : device . name } ) ;
} ) ;
} ) ;
} ) ;
} ) ;
} ,
} ,
@ -212,7 +90,7 @@ module.exports = function () {
}
}
} ) . then ( ( volumes ) => {
} ) . then ( ( volumes ) => {
return volumes . map ( ( volume ) => {
return volumes . map ( ( volume ) => {
return crea tePhysicalVolume( { path : volume . path } ) ;
return typ es. LVM PhysicalVolume( { path : volume . path } ) ;
} ) ;
} ) ;
} ) ;
} ) ;
}
}