summaryrefslogtreecommitdiff
path: root/src/Propellor
diff options
context:
space:
mode:
authorJoey Hess2014-06-19 14:41:55 -0400
committerJoey Hess2014-06-19 14:48:15 -0400
commit42594d6b4c14a21efc42e262e52c2c67f30c67c3 (patch)
treea8f8b2f4a2007bd12bc7b81ef788548805ff713f /src/Propellor
parente3b53bf28996ad5eee96c1ca9f9ef39a7d10b358 (diff)
Add --edit to edit a privdata value in $EDITOR
Diffstat (limited to 'src/Propellor')
-rw-r--r--src/Propellor/CmdLine.hs5
-rw-r--r--src/Propellor/PrivData.hs34
-rw-r--r--src/Propellor/Types.hs1
3 files changed, 32 insertions, 8 deletions
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