2014-11-18 17:29:50 +00:00
|
|
|
-- | This is a simple line-based protocol used for communication between
|
|
|
|
-- a local and remote propellor. It's sent over a ssh channel, and lines of
|
|
|
|
-- the protocol can be interspersed with other, non-protocol lines
|
2014-11-18 21:57:04 +00:00
|
|
|
-- that should be passed through to be displayed.
|
2014-11-19 02:10:50 +00:00
|
|
|
--
|
|
|
|
-- Avoid making backwards-incompatible changes to this protocol,
|
|
|
|
-- since propellor needs to use this protocol to update itself to new
|
|
|
|
-- versions speaking newer versions of the protocol.
|
2014-11-18 17:29:50 +00:00
|
|
|
|
|
|
|
module Propellor.Protocol where
|
|
|
|
|
|
|
|
import Data.List
|
|
|
|
|
|
|
|
import Propellor
|
|
|
|
|
2014-11-22 04:22:19 +00:00
|
|
|
data Stage = NeedGitClone | NeedRepoUrl | NeedPrivData | NeedGitPush | NeedPrecompiled
|
2014-11-18 17:29:50 +00:00
|
|
|
deriving (Read, Show, Eq)
|
|
|
|
|
|
|
|
type Marker = String
|
|
|
|
type Marked = String
|
|
|
|
|
|
|
|
statusMarker :: Marker
|
|
|
|
statusMarker = "STATUS"
|
|
|
|
|
|
|
|
privDataMarker :: String
|
|
|
|
privDataMarker = "PRIVDATA "
|
|
|
|
|
2014-11-18 17:59:50 +00:00
|
|
|
repoUrlMarker :: String
|
|
|
|
repoUrlMarker = "REPOURL "
|
|
|
|
|
2014-11-18 19:05:15 +00:00
|
|
|
gitPushMarker :: String
|
|
|
|
gitPushMarker = "GITPUSH"
|
|
|
|
|
2014-11-18 17:29:50 +00:00
|
|
|
toMarked :: Marker -> String -> String
|
2014-11-18 19:15:56 +00:00
|
|
|
toMarked = (++)
|
2014-11-18 17:29:50 +00:00
|
|
|
|
2014-11-18 17:32:33 +00:00
|
|
|
fromMarked :: Marker -> Marked -> Maybe String
|
|
|
|
fromMarked marker s
|
|
|
|
| marker `isPrefixOf` s = Just $ drop (length marker) s
|
|
|
|
| otherwise = Nothing
|
|
|
|
|
2014-11-18 17:29:50 +00:00
|
|
|
sendMarked :: Handle -> Marker -> String -> IO ()
|
|
|
|
sendMarked h marker s = do
|
2015-01-05 23:40:27 +00:00
|
|
|
debug ["sent marked", marker]
|
2015-01-05 23:42:59 +00:00
|
|
|
sendMarked' h marker s
|
|
|
|
|
|
|
|
sendMarked' :: Handle -> Marker -> String -> IO ()
|
|
|
|
sendMarked' h marker s = do
|
2014-11-18 17:29:50 +00:00
|
|
|
-- Prefix string with newline because sometimes a
|
2014-11-18 17:32:33 +00:00
|
|
|
-- incomplete line has been output, and the marker needs to
|
|
|
|
-- come at the start of a line.
|
2014-11-18 17:29:50 +00:00
|
|
|
hPutStrLn h ("\n" ++ toMarked marker s)
|
|
|
|
hFlush h
|
|
|
|
|
|
|
|
getMarked :: Handle -> Marker -> IO (Maybe String)
|
|
|
|
getMarked h marker = go =<< catchMaybeIO (hGetLine h)
|
|
|
|
where
|
|
|
|
go Nothing = return Nothing
|
2014-11-18 19:17:12 +00:00
|
|
|
go (Just l) = case fromMarked marker l of
|
2014-11-18 21:57:04 +00:00
|
|
|
Nothing -> do
|
2014-11-18 22:13:42 +00:00
|
|
|
unless (null l) $
|
|
|
|
hPutStrLn stderr l
|
2014-11-18 21:57:04 +00:00
|
|
|
getMarked h marker
|
2015-01-05 23:40:27 +00:00
|
|
|
Just v -> do
|
|
|
|
debug ["received marked", marker]
|
|
|
|
return (Just v)
|
2014-11-18 18:09:18 +00:00
|
|
|
|
|
|
|
req :: Stage -> Marker -> (String -> IO ()) -> IO ()
|
|
|
|
req stage marker a = do
|
2015-01-05 23:42:59 +00:00
|
|
|
debug ["requested marked", marker]
|
|
|
|
sendMarked' stdout statusMarker (show stage)
|
2014-11-18 18:09:18 +00:00
|
|
|
maybe noop a =<< getMarked stdin marker
|