@@ -1,3 +1,4 @@
1+{-# LANGUAGE Arrows #-}
1import System.Environment (getArgs)
2import System.Environment (getArgs)
2import Control.Distributed.Process.Backend.Azure
3import Control.Distributed.Process.Backend.Azure
3 ( AzureParameters(azureSshUserName)
4 ( AzureParameters(azureSshUserName)
@@ -8,19 +9,126 @@ import Control.Distributed.Process.Backend.Azure
8 , VirtualMachine(vmName)
9 , VirtualMachine(vmName)
9 , startOnVM
10 , startOnVM
12+import Control.Arrow (returnA)
13+import Control.Applicative ((<$>), (<*>))
14+import Options.Applicative
30+import Options.Applicative.Arrows (runA, asA)
32+--------------------------------------------------------------------------------
33+-- Command line options --
34+--------------------------------------------------------------------------------
36+data AzureOptions = AzureOptions {
37+ subscriptionId :: String
38+ , pathToCert :: FilePath
39+ , pathToKey :: FilePath
43+data SshOptions = SshOptions {
50+ | Start AzureOptions SshOptions String
53+azureOptionsParser :: Parser AzureOptions
54+azureOptionsParser = AzureOptions
55+ <$> strOption ( long "subscription-id"
57+ & help "Azure subscription ID"
59+ <*> strOption ( long "certificate"
61+ & help "X509 certificate"
63+ <*> strOption ( long "private"
65+ & help "Private key in PKCS#1 format"
68+sshOptionsParser :: Parser SshOptions
69+sshOptionsParser = SshOptions
70+ <$> strOption ( long "user"
72+ & help "Remove SSH username"
75+listParser :: Parser Command
76+listParser = List <$> azureOptionsParser
78+startParser :: Parser Command
80+ <$> azureOptionsParser
82+ <*> strOption ( long "vm"
84+ & help "Virtual machine name"
87+commandParser :: Parser Command
88+commandParser = subparser
89+ ( command "list" (info listParser
90+ (progDesc "List Azure cloud services"))
91+ & command "start" (info startParser
92+ (progDesc "Start a new Cloud Haskell node"))
95+--------------------------------------------------------------------------------
97+--------------------------------------------------------------------------------
12main :: IO ()
99main :: IO ()
13−main = do
100+main = do
14− [subscriptionId, pathToCert, pathToKey, user] <- getArgs
101+ cmd <- execParser opts
15− tryConnectToAzure subscriptionId pathToCert pathToKey user
102+ case cmd of
16−
103+ List azureOpts -> do
17−tryConnectToAzure :: String -> String -> String -> String -> IO ()
104+ params <- azureParameters azureOpts Nothing
18−tryConnectToAzure sid pathToCert pathToKey user = do
105+ backend <- initializeBackend params
19− params <- defaultAzureParameters sid pathToCert pathToKey
106+ css <- cloudServices backend
108+ Start azureOpts sshOpts name -> do
109+ params <- azureParameters azureOpts (Just sshOpts)
20− backend <- initializeBackend params { azureSshUserName = user }
110+ backend <- initializeBackend params
21− css <- cloudServices backend
111+ css <- cloudServices backend
22− let ch = head [ vm | vm <- concatMap cloudServiceVMs css
112+ let ch = head [ vm | vm <- concatMap cloudServiceVMs css
23− , vmName vm == "CloudHaskell"
113+ , vmName vm == name
25− print ch
115+ print ch
26− startOnVM backend ch
116+ startOnVM backend ch
118+ opts = info (helper <*> commandParser)
120+ & header "Cloud Haskell backend for Azure"
123+azureParameters :: AzureOptions -> Maybe SshOptions -> IO AzureParameters
124+azureParameters opts Nothing =
125+ defaultAzureParameters (subscriptionId opts)
128+azureParameters opts (Just sshOpts) = do
129+ params <- defaultAzureParameters (subscriptionId opts)
133+ azureSshUserName = remoteUser sshOpts