hsfacter-0.1.0.0: Facter.hs
module Facter where
import Data.Char
import Data.List
import Text.Printf
import qualified Data.Set as Set
storageunits = [ ("", 0), ("K", 1), ("M", 2), ("G", 3), ("T", 4) ]
getPrefix :: Int -> String
getPrefix n | null fltr = error $ "Could not get unit prefix for order " ++ (show n)
| otherwise = fst $ head fltr
where fltr = filter (\(_, x) -> x == n) storageunits
getOrder :: String -> Int
getOrder n | null fltr = error $ "Could not get order for unit prefix " ++ (show n)
| otherwise = snd $ head fltr
where
nu = map toUpper n
fltr = filter (\(x, _) -> x == nu) storageunits
normalizeUnit :: (Double, Int) -> Double -> (Double, Int)
normalizeUnit (unit, order) base | unit > base = normalizeUnit (unit/base, order + 1) base
| otherwise = (unit, order)
storagedesc :: (String, String) -> String
storagedesc (ssize, unit) = let
size = (read ssize) :: Double
uprefix | unit == "B" = ""
| otherwise = [head unit]
uorder = getOrder uprefix
(osize, oorder) = normalizeUnit (size, uorder) 1024
in printf "%.2f %sB" osize (getPrefix oorder)
factRAM = do
meminfo <- readFile "/proc/meminfo" >>= return . map words . lines
let memtotal = ginfo "MemTotal:"
memfree = ginfo "MemFree:"
swapfree = ginfo "SwapFree:"
swaptotal = ginfo "SwapTotal:"
ginfo st = sdesc $ head $ filter (\(x:xs) -> x == st) meminfo
sdesc [_, size, unit] = storagedesc (size, unit)
return [("memorysize", memtotal), ("memoryfree", memfree), ("swapfree", swapfree), ("swapsize", swaptotal)]
factNET = do
return [("ipaddress", "192.168.0.1")]
factOS :: IO [(String, String)]
factOS = do
lsb <- readFile "/etc/lsb-release" >>= return . map (break (== '=')) . lines
hostname <- readFile "/proc/sys/kernel/hostname" >>= return . head . lines
let getval st | null filtered = "?"
| otherwise = rvalue
where filtered = filter (\(k,_) -> k == st) lsb
value = (tail . snd . head) filtered
rvalue | head value == '"' = read value
| otherwise = value
release = getval "DISTRIB_RELEASE"
distid = getval "DISTRIB_ID"
maj | release == "?" = "?"
| otherwise = fst $ break (== '.') release
osfam | distid == "Ubuntu" = "Debian"
| otherwise = distid
return [ ("lsbdistid" , distid)
, ("operatingsystem" , distid)
, ("lsbdistrelease" , release)
, ("operatingsystemrelease" , release)
, ("lsbmajdistrelease" , maj)
, ("osfamily" , osfam)
, ("hostname" , hostname)
, ("lsbdistcodename" , getval "DISTRIB_CODENAME")
, ("lsbdistdescription" , getval "DISTRIB_DESCRIPTION")
]
factMountPoints :: IO [(String, String)]
factMountPoints = do
mountinfo <- readFile "/proc/mounts" >>= return . map words . lines
let ignorefs = Set.fromList
["NFS", "nfs", "nfs4", "nfsd", "afs", "binfmt_misc", "proc", "smbfs",
"autofs", "iso9660", "ncpfs", "coda", "devpts", "ftpfs", "devfs",
"mfs", "shfs", "sysfs", "cifs", "lustre_lite", "tmpfs", "usbfs", "udf",
"fusectl", "fuse.snapshotfs", "rpc_pipefs", "configfs", "devtmpfs",
"debugfs", "securityfs", "ecryptfs", "fuse.gvfs-fuse-daemon", "rootfs"
]
goodlines = filter (\x -> not $ Set.member (x !! 2) ignorefs) mountinfo
goodfs = map (\x -> x !! 1) goodlines
return [("mountpoints", intercalate " " goodfs)]
version = return [("facterversion", "0.1"),("environment","test")]
allFacts :: IO [(String, String)]
allFacts = mapM id [factNET, factRAM, factOS, version, factMountPoints] >>= return . concat