summaryrefslogtreecommitdiff
path: root/Annex/Ssh.hs
blob: 6893f94ef4ce21fe71ebed5aaeddfc90dca9410f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
{- git-annex remote access with ssh
 -
 - Copyright 2011 Joey Hess <joey@kitenet.net>
 -
 - Licensed under the GNU GPL version 3 or higher.
 -}

module Annex.Ssh where

import Control.Monad.State (liftIO)

import qualified Git
import Utility.SafeCommand
import Types
import Config
import Annex.UUID

{- Generates parameters to ssh to a repository's host and run a command.
 - Caller is responsible for doing any neccessary shellEscaping of the
 - passed command. -}
sshToRepo :: Git.Repo -> [CommandParam] -> Annex [CommandParam]
sshToRepo repo sshcmd = do
	s <- getConfig repo "ssh-options" ""
	let sshoptions = map Param (words s)
	let sshport = case Git.urlPort repo of
		Nothing -> []
		Just p -> [Param "-p", Param (show p)]
	let sshhost = Param $ Git.urlHostUser repo
	return $ sshoptions ++ sshport ++ [sshhost] ++ sshcmd

{- Generates parameters to run a git-annex-shell command on a remote
 - repository. -}
git_annex_shell :: Git.Repo -> String -> [CommandParam] -> Annex (Maybe (FilePath, [CommandParam]))
git_annex_shell r command params
	| not $ Git.repoIsUrl r = return $ Just (shellcmd, shellopts)
	| Git.repoIsSsh r = do
		uuid <- getRepoUUID r
		sshparams <- sshToRepo r [Param $ sshcmd uuid ]
		return $ Just ("ssh", sshparams)
	| otherwise = return Nothing
	where
		dir = Git.workTree r
		shellcmd = "git-annex-shell"
		shellopts = Param command : File dir : params
		sshcmd uuid = unwords $
			shellcmd : map shellEscape (toCommand shellopts) ++
			uuidcheck uuid
		uuidcheck NoUUID = []
		uuidcheck (UUID u) = ["--uuid", u]

{- Uses a supplied function (such as boolSystem) to run a git-annex-shell
 - command on a remote.
 -
 - Or, if the remote does not support running remote commands, returns
 - a specified error value. -}
onRemote 
	:: Git.Repo
	-> (FilePath -> [CommandParam] -> IO a, a)
	-> String
	-> [CommandParam]
	-> Annex a
onRemote r (with, errorval) command params = do
	s <- git_annex_shell r command params
	case s of
		Just (c, ps) -> liftIO $ with c ps
		Nothing -> return errorval