@@ -24,7 +24,7 @@ import System.Environment (getEnv)
2424import System.FilePath ((</>), takeFileName)
2525import System.Environment.Executable (getExecutablePath)
2626import System.IO (stdout, hFlush)
27−import Data.Binary (encode, decode)
27+import Data.Binary (Binary(get, put), encode, decode)
2828import Data.Digest.Pure.MD5 (md5, MD5Digest)
2929import qualified Data.ByteString as BSS
3030 ( ByteString
@@ -43,7 +43,7 @@ import qualified Data.ByteString.Lazy as BSL
4343 )
4444import qualified Data.ByteString.Lazy.Char8 as BSLC (unpack)
4545import Data.Typeable (Typeable)
46−import Control.Applicative ((<$>))
46+import Control.Applicative ((<$>), (<*>))
4747import Control.Monad (void, unless)
4848import Control.Monad.Reader (MonadReader, ReaderT, runReaderT, ask)
4949import Control.Exception (Exception, catches, Handler(Handler), throwIO)
@@ -125,6 +125,19 @@ data AzureParameters = AzureParameters {
125125 , azureSshLocalPath :: FilePath
126126 }
127127
128+instance Binary AzureParameters where
129+ put params = do
130+ put (azureSetup params)
131+ put (azureSshUserName params)
132+ put (azureSshPublicKey params)
133+ put (azureSshPrivateKey params)
134+ put (azureSshPassphrase params)
135+ put (azureSshKnownHosts params)
136+ put (azureSshRemotePath params)
137+ put (azureSshLocalPath params)
138+ get =
139+ AzureParameters <$> get <*> get <*> get <*> get <*> get <*> get <*> get <*> get
140+
128141-- | Create default azure parameters
129142defaultAzureParameters :: String -- ^ Azure subscription ID
130143 -> FilePath -- ^ Path to X509 certificate
@@ -155,8 +168,8 @@ initializeBackend params cloudService =
155168 findVMs = apiFindVMs params cloudService
156169 , copyToVM = apiCopyToVM params
157170 , checkMD5 = apiCheckMD5 params
158− , callOnVM = apiCallOnVM params
159− , spawnOnVM = apiSpawnOnVM params
171+ , callOnVM = apiCallOnVM params cloudService
172+ , spawnOnVM = apiSpawnOnVM params cloudService
160173 }
161174
162175-- | Find virtual machines
@@ -175,21 +188,26 @@ apiCopyToVM params vm =
175188
176189-- | Call a process on a VM
177190apiCallOnVM :: AzureParameters
191+ -> String
178192 -> VirtualMachine
179193 -> String
180194 -> ProcessPair a
181195 -> IO a
182−apiCallOnVM params vm port ppair =
196+apiCallOnVM params cloudService vm port ppair =
183197 withSSH2 params vm $ \s -> do
184198 let exe = "PATH=. " ++ azureSshRemotePath params
185199 ++ " onvm run "
186200 ++ " --host " ++ vmIpAddress vm
187201 ++ " --port " ++ port
202+ ++ " --cloud-service " ++ cloudService
188203 ++ " 2>&1"
204+ let paramsEnc = encode params
189205 (status, r) <- SSH.withChannelBy (SSH.openChannelSession s) id $ \ch -> do
190206 SSH.channelExecute ch exe
191− _ <- SSH.writeChannel ch (encodeInt32 (BSL.length rprocEnc))
192− _ <- SSH.writeAllChannel ch rprocEnc
207+ SSH.writeChannel ch (encodeInt32 (BSL.length rprocEnc))
208+ SSH.writeAllChannel ch rprocEnc
209+ SSH.writeChannel ch (encodeInt32 (BSL.length paramsEnc))
210+ SSH.writeAllChannel ch paramsEnc
193211 runLocalProcess (ppairLocal ppair) ch
194212 if status == 0
195213 then return r
@@ -199,22 +217,28 @@ apiCallOnVM params vm port ppair =
199217 rprocEnc = encode (ppairRemote ppair)
200218
201219apiSpawnOnVM :: AzureParameters
220+ -> String
202221 -> VirtualMachine
203222 -> String
204223 -> Closure (Backend -> Process ())
205224 -> IO ()
206−apiSpawnOnVM params vm port proc =
225+apiSpawnOnVM params cloudService vm port proc =
207226 withSSH2 params vm $ \s -> do
227+ -- TODO: reduce duplication with apiCallOnVM
208228 let exe = "PATH=. " ++ azureSshRemotePath params
209229 ++ " onvm run "
210230 ++ " --host " ++ vmIpAddress vm
211231 ++ " --port " ++ port
232+ ++ " --cloud-service " ++ cloudService
212233 ++ " --background "
213234 ++ " 2>&1"
235+ let paramsEnc = encode params
214236 (status, r) <- SSH.withChannelBy (SSH.openChannelSession s) id $ \ch -> do
215237 SSH.channelExecute ch exe
216− _ <- SSH.writeChannel ch (encodeInt32 (BSL.length procEnc))
217− _ <- SSH.writeAllChannel ch procEnc
238+ SSH.writeChannel ch (encodeInt32 (BSL.length procEnc))
239+ SSH.writeAllChannel ch procEnc
240+ SSH.writeChannel ch (encodeInt32 (BSL.length paramsEnc))
241+ SSH.writeAllChannel ch paramsEnc
218242 SSH.channelSendEOF ch
219243 SSH.readAllChannel ch
220244 unless (status == 0) $ error (BSLC.unpack r)