summaryrefslogtreecommitdiff
path: root/src/Propellor/Ssh.hs
diff options
context:
space:
mode:
authorJoey Hess2014-11-18 18:42:36 -0400
committerJoey Hess2014-11-18 18:42:36 -0400
commit47bcd4e1306b808311f39f398b0e539700e5efc6 (patch)
tree0b8e4e9d0679e3abe7c2cf72b16b4229d5d3ef4f /src/Propellor/Ssh.hs
parent45592b442b02c41993c9c62eb7f06bcb1267c117 (diff)
factor out ssh module
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