@@ -1,5 +1,7 @@
1{-# LANGUAGE Arrows #-}
1{-# LANGUAGE Arrows #-}
2import System.Environment (getArgs)
2import System.Environment (getArgs)
3+import System.Exit (exitSuccess, exitFailure)
4+import Control.Monad (unless)
3import Control.Distributed.Process.Backend.Azure
5import Control.Distributed.Process.Backend.Azure
4 ( AzureParameters(azureSshUserName)
6 ( AzureParameters(azureSshUserName)
5 , defaultAzureParameters
7 , defaultAzureParameters
@@ -7,7 +9,7 @@ import Control.Distributed.Process.Backend.Azure
7 , cloudServices
9 , cloudServices
8 , CloudService(cloudServiceVMs)
10 , CloudService(cloudServiceVMs)
9 , VirtualMachine(vmName)
11 , VirtualMachine(vmName)
10− , startOnVM
12+ , Backend(copyToVM, checkMD5)
12import Control.Arrow (returnA)
14import Control.Arrow (returnA)
13import Control.Applicative ((<$>), (<*>))
15import Control.Applicative ((<$>), (<*>))
@@ -26,6 +28,7 @@ import Options.Applicative
27 , fullDesc
29 , fullDesc
30import Options.Applicative.Arrows (runA, asA)
33import Options.Applicative.Arrows (runA, asA)
@@ -46,8 +49,20 @@ data SshOptions = SshOptions {
46 deriving Show
49 deriving Show
48data Command =
51data Command =
53+ azureOptions :: AzureOptions
49− List AzureOptions
56+ azureOptions :: AzureOptions
57+ , sshOptions :: SshOptions
58+ , virtualMachine :: String
50− | Start AzureOptions SshOptions String
61+ azureOptions :: AzureOptions
62+ , sshOptions :: SshOptions
63+ , virtualMachine :: String
51 deriving Show
66 deriving Show
53azureOptionsParser :: Parser AzureOptions
68azureOptionsParser :: Parser AzureOptions
@@ -75,8 +90,8 @@ sshOptionsParser = SshOptions
75listParser :: Parser Command
90listParser :: Parser Command
76listParser = List <$> azureOptionsParser
91listParser = List <$> azureOptionsParser
78−startParser :: Parser Command
93+copyToParser :: Parser Command
79−startParser = Start
94+copyToParser = CopyTo
80 <$> azureOptionsParser
95 <$> azureOptionsParser
81 <*> sshOptionsParser
96 <*> sshOptionsParser
82 <*> strOption ( long "vm"
97 <*> strOption ( long "vm"
@@ -84,12 +99,26 @@ startParser = Start
84 & help "Virtual machine name"
99 & help "Virtual machine name"
102+checkMD5Parser :: Parser Command
103+checkMD5Parser = CheckMD5
104+ <$> azureOptionsParser
105+ <*> sshOptionsParser
106+ <*> strOption ( long "vm"
108+ & help "Virtual machine name"
110+ <*> switch ( long "status"
111+ & help "Don't output anything, status code shows success"
87commandParser :: Parser Command
114commandParser :: Parser Command
88commandParser = subparser
115commandParser = subparser
89 ( command "list" (info listParser
116 ( command "list" (info listParser
90 (progDesc "List Azure cloud services"))
117 (progDesc "List Azure cloud services"))
91− & command "start" (info startParser
118+ & command "install" (info copyToParser
92− (progDesc "Start a new Cloud Haskell node"))
119+ (progDesc "Install the executable on a virtual machine"))
120+ & command "md5" (info checkMD5Parser
121+ (progDesc "Check if the remote and local MD5 hash match"))
95--------------------------------------------------------------------------------
124--------------------------------------------------------------------------------
@@ -100,20 +129,37 @@ main :: IO ()
100main = do
129main = do
101 cmd <- execParser opts
130 cmd <- execParser opts
102 case cmd of
131 case cmd of
103− List azureOpts -> do
132+ List {} -> do
104− params <- azureParameters azureOpts Nothing
133+ params <- azureParameters (azureOptions cmd) Nothing
105 backend <- initializeBackend params
134 backend <- initializeBackend params
106 css <- cloudServices backend
135 css <- cloudServices backend
107 mapM_ print css
136 mapM_ print css
108− Start azureOpts sshOpts name -> do
137+ CopyTo {} -> do
109− params <- azureParameters azureOpts (Just sshOpts)
138+ params <- azureParameters (azureOptions cmd) (Just (sshOptions cmd))
110 backend <- initializeBackend params
139 backend <- initializeBackend params
111 css <- cloudServices backend
140 css <- cloudServices backend
112 let ch = head [ vm | vm <- concatMap cloudServiceVMs css
141 let ch = head [ vm | vm <- concatMap cloudServiceVMs css
113− , vmName vm == name
142+ , vmName vm == virtualMachine cmd
115 print ch
144 print ch
116− startOnVM backend ch
145+ copyToVM backend ch
147+ params <- azureParameters (azureOptions cmd) (Just (sshOptions cmd))
148+ backend <- initializeBackend params
149+ css <- cloudServices backend
150+ let ch = head [ vm | vm <- concatMap cloudServiceVMs css
151+ , vmName vm == virtualMachine cmd
153+ match <- checkMD5 backend ch
156+ unless (status cmd) $
157+ putStrLn "Local and remote MD5 hash match"
160+ unless (status cmd) $
161+ putStrLn "Local and remote MD5 hash do NOT match"
118 opts = info (helper <*> commandParser)
164 opts = info (helper <*> commandParser)
119 ( fullDesc
165 ( fullDesc