2014-04-06 23:06:03 +00:00
|
|
|
{- git-remote-daemon, git-annex-shell over ssh transport
|
|
|
|
-
|
|
|
|
- Copyright 2014 Joey Hess <joey@kitenet.net>
|
|
|
|
-
|
|
|
|
- Licensed under the GNU GPL version 3 or higher.
|
|
|
|
-}
|
|
|
|
|
|
|
|
module RemoteDaemon.Transport.Ssh (transport) where
|
|
|
|
|
|
|
|
import Common.Annex
|
|
|
|
import RemoteDaemon.Types
|
2014-04-08 17:41:36 +00:00
|
|
|
import RemoteDaemon.Common
|
2014-04-06 23:06:03 +00:00
|
|
|
import Remote.Helper.Ssh
|
2014-04-08 17:41:36 +00:00
|
|
|
import qualified RemoteDaemon.Transport.Ssh.Types as SshRemote
|
2014-04-06 23:06:03 +00:00
|
|
|
import Utility.SimpleProtocol
|
|
|
|
import Git.Command
|
|
|
|
|
|
|
|
import Control.Concurrent.Chan
|
|
|
|
import Control.Concurrent.Async
|
|
|
|
import System.Process (std_in, std_out)
|
|
|
|
|
|
|
|
transport :: Transport
|
2014-04-08 17:41:36 +00:00
|
|
|
transport r remotename transporthandle ichan ochan = do
|
|
|
|
v <- liftAnnex transporthandle $ git_annex_shell r "notifychanges" [] []
|
2014-04-06 23:06:03 +00:00
|
|
|
case v of
|
|
|
|
Nothing -> noop
|
2014-04-08 17:41:36 +00:00
|
|
|
Just (cmd, params) -> go cmd (toCommand params)
|
2014-04-06 23:06:03 +00:00
|
|
|
where
|
|
|
|
go cmd params = do
|
|
|
|
(Just toh, Just fromh, _, pid) <- createProcess (proc cmd params)
|
|
|
|
{ std_in = CreatePipe
|
|
|
|
, std_out = CreatePipe
|
|
|
|
}
|
|
|
|
|
|
|
|
let shutdown = do
|
|
|
|
hClose toh
|
|
|
|
hClose fromh
|
|
|
|
void $ waitForProcess pid
|
|
|
|
send DISCONNECTED
|
|
|
|
|
|
|
|
let fromshell = forever $ do
|
|
|
|
l <- hGetLine fromh
|
|
|
|
case parseMessage l of
|
|
|
|
Just SshRemote.READY -> send CONNECTED
|
2014-04-08 17:41:36 +00:00
|
|
|
Just (SshRemote.CHANGED shas) ->
|
|
|
|
whenM (checkNewShas transporthandle shas) $
|
|
|
|
fetch
|
2014-04-06 23:06:03 +00:00
|
|
|
Nothing -> shutdown
|
|
|
|
|
|
|
|
-- The only control message that matters is STOP.
|
|
|
|
--
|
|
|
|
-- Note that a CHANGED control message is not handled;
|
|
|
|
-- we don't push to the ssh remote. The assistant
|
|
|
|
-- and git-annex sync both handle pushes, so there's no
|
|
|
|
-- need to do it here.
|
|
|
|
let handlecontrol = forever $ do
|
|
|
|
msg <- readChan ichan
|
|
|
|
case msg of
|
|
|
|
STOP -> ioError (userError "done")
|
|
|
|
_ -> noop
|
|
|
|
|
|
|
|
-- Run both threads until one finishes.
|
|
|
|
void $ tryIO $ concurrently fromshell handlecontrol
|
|
|
|
shutdown
|
|
|
|
|
2014-04-08 17:41:36 +00:00
|
|
|
send msg = writeChan ochan (msg remotename)
|
|
|
|
|
|
|
|
fetch = do
|
|
|
|
send SYNCING
|
|
|
|
ok <- inLocalRepo transporthandle $
|
|
|
|
runBool [Param "fetch", Param remotename]
|
|
|
|
send (DONESYNCING ok)
|