summaryrefslogtreecommitdiff
path: root/src/Propellor/Ssh.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Propellor/Ssh.hs')
-rw-r--r--src/Propellor/Ssh.hs43
1 files changed, 43 insertions, 0 deletions
diff --git a/src/Propellor/Ssh.hs b/src/Propellor/Ssh.hs
new file mode 100644
index 00000000..969517a8
--- /dev/null
+++ b/src/Propellor/Ssh.hs
@@ -0,0 +1,43 @@
+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)
+sshCachingParams :: HostName -> IO [CommandParam]
+sshCachingParams hn = do
+ home <- myHomeDir
+ let cachedir = home </> ".ssh" </> "propellor"
+ createDirectoryIfMissing False cachedir
+ let socketfile = cachedir </> hn ++ ".sock"
+ let ps =
+ [ Param "-o", Param ("ControlPath=" ++ socketfile)
+ , Params "-o ControlMaster=auto -o ControlPersist=yes"
+ ]
+
+ 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