From 42594d6b4c14a21efc42e262e52c2c67f30c67c3 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Thu, 19 Jun 2014 14:41:55 -0400 Subject: Add --edit to edit a privdata value in $EDITOR --- src/Propellor/CmdLine.hs | 5 ++++- src/Propellor/PrivData.hs | 34 +++++++++++++++++++++++++++------- src/Propellor/Types.hs | 1 + 3 files changed, 32 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/Propellor/CmdLine.hs b/src/Propellor/CmdLine.hs index 32e97316..c084355b 100644 --- a/src/Propellor/CmdLine.hs +++ b/src/Propellor/CmdLine.hs @@ -26,9 +26,10 @@ usage = do , " propellor" , " propellor hostname" , " propellor --spin hostname" + , " propellor --add-key keyid" , " propellor --set hostname field" , " propellor --dump hostname field" - , " propellor --add-key keyid" + , " propellor --edit hostname field" ] exitFailure @@ -41,6 +42,7 @@ processCmdLine = go =<< getArgs go ("--add-key":k:[]) = return $ AddKey k go ("--set":h:f:[]) = withprivfield f (return . Set h) go ("--dump":h:f:[]) = withprivfield f (return . Dump h) + go ("--edit":h:f:[]) = withprivfield f (return . Edit h) go ("--continue":s:[]) = case readish s of Just cmdline -> return $ Continue cmdline Nothing -> errorMessage "--continue serialization failure" @@ -71,6 +73,7 @@ defaultMain hostlist = do go _ (Continue cmdline) = go False cmdline go _ (Set hn field) = setPrivData hn field go _ (Dump hn field) = dumpPrivData hn field + go _ (Edit hn field) = editPrivData hn field go _ (AddKey keyid) = addKey keyid go _ (Chain hn) = withhost hn $ \h -> do r <- runPropellor h $ ensureProperties $ hostProperties h diff --git a/src/Propellor/PrivData.hs b/src/Propellor/PrivData.hs index 5ddbdcff..fec6acc3 100644 --- a/src/Propellor/PrivData.hs +++ b/src/Propellor/PrivData.hs @@ -10,6 +10,7 @@ import System.Directory import Data.Maybe import Data.List import Control.Monad +import Control.Monad.IfElse import "mtl" Control.Monad.Reader import Propellor.Types @@ -21,6 +22,8 @@ import Utility.Process import Utility.Tmp import Utility.SafeCommand import Utility.Misc +import Utility.FileMode +import Utility.Env -- | When the specified PrivDataField is available on the host Propellor -- is provisioning, it provies the data to the action. Otherwise, it prints @@ -46,11 +49,31 @@ getPrivData field = do setPrivData :: HostName -> PrivDataField -> IO () setPrivData host field = do putStrLn "Enter private data on stdin; ctrl-D when done:" - value <- chomp <$> hGetContentsStrict stdin + setPrivDataTo host field =<< hGetContentsStrict stdin + +dumpPrivData :: HostName -> PrivDataField -> IO () +dumpPrivData host field = + maybe (error "Requested privdata is not set.") putStrLn + =<< getPrivDataFor host field + +editPrivData :: HostName -> PrivDataField -> IO () +editPrivData host field = do + v <- getPrivDataFor host field + v' <- withTmpFile "propellorXXXX" $ \f h -> do + hClose h + maybe noop (writeFileProtected f) v + editor <- getEnvDefault "EDITOR" "vi" + unlessM (boolSystem editor [File f]) $ + error "Editor failed; aborting." + readFile f + setPrivDataTo host field v' + +setPrivDataTo :: HostName -> PrivDataField -> String -> IO () +setPrivDataTo host field value = do makePrivDataDir let f = privDataFile host m <- decryptPrivData host - let m' = M.insert field value m + let m' = M.insert field (chomp value) m gpgEncrypt f (show m') putStrLn "Private data set." void $ boolSystem "git" [Param "add", File f] @@ -59,11 +82,8 @@ setPrivData host field = do | end s == "\n" = chomp (beginning s) | otherwise = s -dumpPrivData :: HostName -> PrivDataField -> IO () -dumpPrivData host field = go . M.lookup field =<< decryptPrivData host - where - go Nothing = error "Requested privdata is not set." - go (Just s) = putStrLn s +getPrivDataFor :: HostName -> PrivDataField -> IO (Maybe String) +getPrivDataFor host field = M.lookup field <$> decryptPrivData host decryptPrivData :: HostName -> IO (M.Map PrivDataField String) decryptPrivData host = fromMaybe M.empty . readish diff --git a/src/Propellor/Types.hs b/src/Propellor/Types.hs index 383797a9..740996be 100644 --- a/src/Propellor/Types.hs +++ b/src/Propellor/Types.hs @@ -137,6 +137,7 @@ data CmdLine | Boot HostName | Set HostName PrivDataField | Dump HostName PrivDataField + | Edit HostName PrivDataField | AddKey String | Continue CmdLine | Chain HostName -- cgit v1.2.3