@@ -11,6 +11,7 @@ import Control.Monad.IO.Class (liftIO)
1111import Data.Attoparsec.ByteString.Char8 as A
1212import qualified Data.ByteString.Char8 as BC8
1313import Data.Default
14+import Data.List (sort)
1415import Data.Maybe
1516import Data.Monoid
1617import qualified Data.Text as T
@@ -52,7 +53,8 @@ deployInit thunkPtr configDir deployDir sshKeyPath hostnames = do
5253
5354deployPush :: MonadObelisk m => FilePath -> m ()
5455deployPush deployPath = do
55− host <- liftIO $ fmap (T.unpack . T.strip) $ T.readFile $ deployPath </> "backend_hosts"
56+ let backendHosts = deployPath </> "backend_hosts"
57+ host <- liftIO $ fmap (T.unpack . T.strip) $ T.readFile backendHosts
5658 let srcPath = deployPath </> "src"
5759 build = do
5860 buildOutput <- nixBuild $ def
@@ -78,13 +80,17 @@ deployPush deployPath = do
7880 return Nothing
7981 _ -> return Nothing
8082 forM_ result $ \res -> do
81− let deployAndSwitch outputPath sshAgentEnv = do
83+ let knownHostsPath = deployPath </> "backend_known_hosts"
84+ sshOpts = ["-o", "UserKnownHostsFile=" <> knownHostsPath, "-o", "StrictHostKeyChecking=yes"]
85+ deployAndSwitch outputPath sshAgentEnv = do
8286 withSpinner "Adding ssh key" $ do
8387 callProcess' sshAgentEnv "ssh-add" [deployPath </> "ssh_key"]
88+ liftIO $ writeFile knownHostsPath . sortLines =<< sshKeyScan backendHosts
8489 withSpinner "Uploading closure" $ do
85− callProcess' sshAgentEnv "nix-copy-closure" ["-v", "--to", "root@" <> host, "--gzip", outputPath]
90+ let nixSshEnv = ("NIX_SSHOPTS", unwords sshOpts) : sshAgentEnv
91+ callProcess' nixSshEnv "nix-copy-closure" ["-v", "--to", "root@" <> host, "--gzip", outputPath]
8692 withSpinner "Switching to new configuration" $ do
87− callProcess' sshAgentEnv "ssh"
93+ callProcess' sshAgentEnv "ssh" $ sshOpts <>
8894 [ "root@" <> host
8995 , unwords
9096 [ "nix-env -p /nix/var/nix/profiles/system --set " <> outputPath
@@ -121,3 +127,8 @@ sshAgent = do
121127 _ <- A.string ";" >> A.endOfLine <|> void (A.string ";")
122128 return (BC8.unpack key, BC8.unpack val)
123129
130+sshKeyScan :: String -> IO String
131+sshKeyScan hostsPath = readProcess "ssh-keyscan" ["-f", hostsPath] mempty
132+
133+sortLines :: String -> String
134+sortLines = unlines . sort . lines