propellor spin

This commit is contained in:
Joey Hess 2014-06-19 14:41:55 -04:00
parent e3b53bf289
commit 9372ecc6c6
Failed to extract signature
4 changed files with 37 additions and 8 deletions

6
debian/changelog vendored
View File

@ -1,3 +1,9 @@
propellor (0.7.1) UNRELEASED; urgency=medium
* Add --edit to edit a privdata value in $EDITOR.
-- Joey Hess <joeyh@debian.org> Thu, 19 Jun 2014 14:27:21 -0400
propellor (0.7.0) unstable; urgency=medium propellor (0.7.0) unstable; urgency=medium
* combineProperties no longer stops when a property fails; now it continues * combineProperties no longer stops when a property fails; now it continues

View File

@ -26,9 +26,10 @@ usage = do
, " propellor" , " propellor"
, " propellor hostname" , " propellor hostname"
, " propellor --spin hostname" , " propellor --spin hostname"
, " propellor --add-key keyid"
, " propellor --set hostname field" , " propellor --set hostname field"
, " propellor --dump hostname field" , " propellor --dump hostname field"
, " propellor --add-key keyid" , " propellor --edit hostname field"
] ]
exitFailure exitFailure
@ -41,6 +42,7 @@ processCmdLine = go =<< getArgs
go ("--add-key":k:[]) = return $ AddKey k go ("--add-key":k:[]) = return $ AddKey k
go ("--set":h:f:[]) = withprivfield f (return . Set h) go ("--set":h:f:[]) = withprivfield f (return . Set h)
go ("--dump":h:f:[]) = withprivfield f (return . Dump 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 go ("--continue":s:[]) = case readish s of
Just cmdline -> return $ Continue cmdline Just cmdline -> return $ Continue cmdline
Nothing -> errorMessage "--continue serialization failure" Nothing -> errorMessage "--continue serialization failure"
@ -71,6 +73,7 @@ defaultMain hostlist = do
go _ (Continue cmdline) = go False cmdline go _ (Continue cmdline) = go False cmdline
go _ (Set hn field) = setPrivData hn field go _ (Set hn field) = setPrivData hn field
go _ (Dump hn field) = dumpPrivData hn field go _ (Dump hn field) = dumpPrivData hn field
go _ (Edit hn field) = editPrivData hn field
go _ (AddKey keyid) = addKey keyid go _ (AddKey keyid) = addKey keyid
go _ (Chain hn) = withhost hn $ \h -> do go _ (Chain hn) = withhost hn $ \h -> do
r <- runPropellor h $ ensureProperties $ hostProperties h r <- runPropellor h $ ensureProperties $ hostProperties h

View File

@ -10,6 +10,7 @@ import System.Directory
import Data.Maybe import Data.Maybe
import Data.List import Data.List
import Control.Monad import Control.Monad
import Control.Monad.IfElse
import "mtl" Control.Monad.Reader import "mtl" Control.Monad.Reader
import Propellor.Types import Propellor.Types
@ -21,6 +22,8 @@ import Utility.Process
import Utility.Tmp import Utility.Tmp
import Utility.SafeCommand import Utility.SafeCommand
import Utility.Misc import Utility.Misc
import Utility.FileMode
import Utility.Env
-- | When the specified PrivDataField is available on the host Propellor -- | When the specified PrivDataField is available on the host Propellor
-- is provisioning, it provies the data to the action. Otherwise, it prints -- is provisioning, it provies the data to the action. Otherwise, it prints
@ -46,11 +49,19 @@ getPrivData field = do
setPrivData :: HostName -> PrivDataField -> IO () setPrivData :: HostName -> PrivDataField -> IO ()
setPrivData host field = do setPrivData host field = do
putStrLn "Enter private data on stdin; ctrl-D when done:" 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
setPrivDataTo :: HostName -> PrivDataField -> String -> IO ()
setPrivDataTo host field value = do
makePrivDataDir makePrivDataDir
let f = privDataFile host let f = privDataFile host
m <- decryptPrivData host m <- decryptPrivData host
let m' = M.insert field value m let m' = M.insert field (chomp value) m
gpgEncrypt f (show m') gpgEncrypt f (show m')
putStrLn "Private data set." putStrLn "Private data set."
void $ boolSystem "git" [Param "add", File f] void $ boolSystem "git" [Param "add", File f]
@ -59,11 +70,19 @@ setPrivData host field = do
| end s == "\n" = chomp (beginning s) | end s == "\n" = chomp (beginning s)
| otherwise = s | otherwise = s
dumpPrivData :: HostName -> PrivDataField -> IO () getPrivDataFor :: HostName -> PrivDataField -> IO (Maybe String)
dumpPrivData host field = go . M.lookup field =<< decryptPrivData host getPrivDataFor host field = M.lookup field <$> decryptPrivData host
where
go Nothing = error "Requested privdata is not set." editPrivData :: HostName -> PrivDataField -> IO ()
go (Just s) = putStrLn s editPrivData host field = do
v <- getPrivDataFor host field
v' <- withTmpFile "propellorXXXX" $ \f _h -> do
maybe noop (writeFileProtected f) v
editor <- getEnvDefault "EDITOR" "vi"
unlessM (boolSystem editor [File f]) $
error "Editor failed; aborting."
readFile f
setPrivDataTo host field v'
decryptPrivData :: HostName -> IO (M.Map PrivDataField String) decryptPrivData :: HostName -> IO (M.Map PrivDataField String)
decryptPrivData host = fromMaybe M.empty . readish decryptPrivData host = fromMaybe M.empty . readish

View File

@ -137,6 +137,7 @@ data CmdLine
| Boot HostName | Boot HostName
| Set HostName PrivDataField | Set HostName PrivDataField
| Dump HostName PrivDataField | Dump HostName PrivDataField
| Edit HostName PrivDataField
| AddKey String | AddKey String
| Continue CmdLine | Continue CmdLine
| Chain HostName | Chain HostName