-- | Maintainer: 2016 Evan Cofsky <evan@theunixman.com>
-- 
-- Functions running zfs processes.

module Propellor.Property.ZFS.Process where

import Propellor.Base
import Utility.Split

import Data.List

-- | Gets the properties of a ZFS volume.
zfsGetProperties ::  ZFS -> IO ZFSProperties
zfsGetProperties :: ZFS -> IO ZFSProperties
zfsGetProperties ZFS
z =
	let plist :: [[Char]] -> ZFSProperties
plist = [([Char], [Char])] -> ZFSProperties
fromPropertyList ([([Char], [Char])] -> ZFSProperties)
-> ([[Char]] -> [([Char], [Char])]) -> [[Char]] -> ZFSProperties
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([[Char]] -> ([Char], [Char])) -> [[[Char]]] -> [([Char], [Char])]
forall a b. (a -> b) -> [a] -> [b]
map (\([Char]
_:[Char]
k:[Char]
v:[[Char]]
_) -> ([Char]
k, [Char]
v)) ([[[Char]]] -> [([Char], [Char])])
-> ([[Char]] -> [[[Char]]]) -> [[Char]] -> [([Char], [Char])]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (([Char] -> [[Char]]) -> [[Char]] -> [[[Char]]]
forall a b. (a -> b) -> [a] -> [b]
map ([Char] -> [Char] -> [[Char]]
forall a. Eq a => [a] -> [a] -> [[a]]
split [Char]
"\t"))
	in [[Char]] -> ZFSProperties
plist ([[Char]] -> ZFSProperties) -> IO [[Char]] -> IO ZFSProperties
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Char] -> [Maybe [Char]] -> ZFS -> IO [[Char]]
runZfs [Char]
"get" [[Char] -> Maybe [Char]
forall a. a -> Maybe a
Just [Char]
"-H", [Char] -> Maybe [Char]
forall a. a -> Maybe a
Just [Char]
"-p", [Char] -> Maybe [Char]
forall a. a -> Maybe a
Just [Char]
"all"] ZFS
z

zfsExists :: ZFS -> IO Bool
zfsExists :: ZFS -> IO Bool
zfsExists ZFS
z = (Bool -> Bool) -> [Bool] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any Bool -> Bool
forall a. a -> a
id ([Bool] -> Bool) -> ([[Char]] -> [Bool]) -> [[Char]] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Char] -> Bool) -> [[Char]] -> [Bool]
forall a b. (a -> b) -> [a] -> [b]
map ([Char] -> [Char] -> Bool
forall a. Eq a => [a] -> [a] -> Bool
isInfixOf (ZFS -> [Char]
zfsName ZFS
z))
	([[Char]] -> Bool) -> IO [[Char]] -> IO Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Char] -> [Maybe [Char]] -> ZFS -> IO [[Char]]
runZfs [Char]
"list" [[Char] -> Maybe [Char]
forall a. a -> Maybe a
Just [Char]
"-H"] ZFS
z

-- | Runs the zfs command with the arguments.
--
-- Runs the command with -H which will skip the header line and
-- separate all fields with tabs.
--
-- Replaces Nothing in the argument list with the ZFS pool/dataset.
runZfs :: String -> [Maybe String] -> ZFS -> IO [String]
runZfs :: [Char] -> [Maybe [Char]] -> ZFS -> IO [[Char]]
runZfs [Char]
cmd [Maybe [Char]]
args ZFS
z = [Char] -> [[Char]]
lines ([Char] -> [[Char]]) -> IO [Char] -> IO [[Char]]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ([Char] -> [[Char]] -> IO [Char])
-> ([Char], [[Char]]) -> IO [Char]
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry [Char] -> [[Char]] -> IO [Char]
readProcess ([Char] -> [Maybe [Char]] -> ZFS -> ([Char], [[Char]])
zfsCommand [Char]
cmd [Maybe [Char]]
args ZFS
z)

-- | Return the ZFS command line suitable for readProcess or cmdProperty.
zfsCommand :: String -> [Maybe String] -> ZFS -> (String, [String])
zfsCommand :: [Char] -> [Maybe [Char]] -> ZFS -> ([Char], [[Char]])
zfsCommand [Char]
cmd [Maybe [Char]]
args ZFS
z = ([Char]
"zfs", [Char]
cmd[Char] -> [[Char]] -> [[Char]]
forall a. a -> [a] -> [a]
:((Maybe [Char] -> [Char]) -> [Maybe [Char]] -> [[Char]]
forall a b. (a -> b) -> [a] -> [b]
map ([Char] -> ([Char] -> [Char]) -> Maybe [Char] -> [Char]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (ZFS -> [Char]
zfsName ZFS
z) [Char] -> [Char]
forall a. a -> a
id) [Maybe [Char]]
args))