2014-11-18 22:42:36 +00:00
|
|
|
module Propellor.Ssh where
|
|
|
|
|
|
|
|
import Propellor
|
|
|
|
import Utility.SafeCommand
|
|
|
|
import Utility.UserInfo
|
|
|
|
|
|
|
|
import System.PosixCompat
|
|
|
|
import Data.Time.Clock.POSIX
|
|
|
|
|
|
|
|
-- Parameters can be passed to both ssh and scp, to enable a ssh connection
|
|
|
|
-- caching socket.
|
|
|
|
--
|
|
|
|
-- If the socket already exists, check if its mtime is older than 10
|
|
|
|
-- minutes, and if so stop that ssh process, in order to not try to
|
|
|
|
-- use an old stale connection. (atime would be nicer, but there's
|
|
|
|
-- a good chance a laptop uses noatime)
|
2014-11-22 20:20:02 +00:00
|
|
|
sshCachingParams :: HostName -> IO [CommandParam]
|
|
|
|
sshCachingParams hn = do
|
2014-11-18 22:42:36 +00:00
|
|
|
home <- myHomeDir
|
|
|
|
let cachedir = home </> ".ssh" </> "propellor"
|
|
|
|
createDirectoryIfMissing False cachedir
|
|
|
|
let socketfile = cachedir </> hn ++ ".sock"
|
2014-11-22 20:20:02 +00:00
|
|
|
let ps =
|
|
|
|
[ Param "-o"
|
|
|
|
, Param ("ControlPath=" ++ socketfile)
|
|
|
|
, Params "-o ControlMaster=auto -o ControlPersist=yes"
|
2014-11-18 22:42:36 +00:00
|
|
|
]
|
|
|
|
|
|
|
|
maybe noop (expireold ps socketfile)
|
|
|
|
=<< catchMaybeIO (getFileStatus socketfile)
|
|
|
|
|
|
|
|
return ps
|
|
|
|
|
|
|
|
where
|
|
|
|
expireold ps f s = do
|
|
|
|
now <- truncate <$> getPOSIXTime :: IO Integer
|
|
|
|
if modificationTime s > fromIntegral now - tenminutes
|
|
|
|
then touchFile f
|
|
|
|
else do
|
|
|
|
void $ boolSystem "ssh" $
|
|
|
|
[ Params "-O stop" ] ++ ps ++
|
|
|
|
[ Param "localhost" ]
|
|
|
|
nukeFile f
|
|
|
|
tenminutes = 600
|