Revision 152e05e1 htools/Ganeti/Daemon.hs

b/htools/Ganeti/Daemon.hs
33 33
  , oNoUserChecks
34 34
  , oDebug
35 35
  , oPort
36
  , oBindAddress
36 37
  , parseArgs
38
  , parseAddress
37 39
  , writePidFile
38 40
  , genericMain
39 41
  ) where
......
41 43
import Control.Monad
42 44
import qualified Data.Version
43 45
import Data.Word
46
import qualified Network.Socket as Socket
44 47
import System.Console.GetOpt
45 48
import System.Exit
46 49
import System.Environment
......
59 62
import Ganeti.HTools.Utils
60 63
import qualified Ganeti.HTools.Version as Version(version)
61 64
import qualified Ganeti.Constants as C
65
import qualified Ganeti.Ssconf as Ssconf
62 66

  
63 67
-- * Data types
64 68

  
......
70 74
  , optPort         :: Maybe Word16   -- ^ Override for the network port
71 75
  , optDebug        :: Bool           -- ^ Enable debug messages
72 76
  , optNoUserChecks :: Bool           -- ^ Ignore user checks
77
  , optBindAddress  :: Maybe String   -- ^ Override for the bind address
73 78
  }
74 79

  
75 80
-- | Default values for the command line options.
......
81 86
  , optPort         = Nothing
82 87
  , optDebug        = False
83 88
  , optNoUserChecks = False
89
  , optBindAddress  = Nothing
84 90
  }
85 91

  
86 92
-- | Abrreviation for the option type.
......
130 136
             (\port opts -> Ok opts { optPort = Just port }) "PORT")
131 137
            ("Network port (default: " ++ show def ++ ")")
132 138

  
139
oBindAddress :: OptType
140
oBindAddress = Option "b" ["bind"]
141
               (ReqArg (\addr opts -> Ok opts { optBindAddress = Just addr })
142
                "ADDR")
143
               "Bind address (default depends on cluster configuration)"
144

  
133 145
-- | Usage info.
134 146
usageHelp :: String -> [OptType] -> String
135 147
usageHelp progname =
......
194 206
  _ <- createSession
195 207
  return ()
196 208

  
209
-- | Computes the default bind address for a given family.
210
defaultBindAddr :: Int                  -- ^ The port we want
211
                -> Socket.Family        -- ^ The cluster IP family
212
                -> Result (Socket.Family, Socket.SockAddr)
213
defaultBindAddr port Socket.AF_INET =
214
  Ok $ (Socket.AF_INET,
215
        Socket.SockAddrInet (fromIntegral port) Socket.iNADDR_ANY)
216
defaultBindAddr port Socket.AF_INET6 =
217
  Ok $ (Socket.AF_INET6,
218
        Socket.SockAddrInet6 (fromIntegral port) 0 Socket.iN6ADDR_ANY 0)
219
defaultBindAddr _ fam = Bad $ "Unsupported address family: " ++ show fam
220

  
221
-- | Default hints for the resolver
222
resolveAddrHints :: Maybe Socket.AddrInfo
223
resolveAddrHints =
224
  Just Socket.defaultHints { Socket.addrFlags = [Socket.AI_NUMERICHOST,
225
                                                 Socket.AI_NUMERICSERV] }
226

  
227
-- | Resolves a numeric address.
228
resolveAddr :: Int -> String -> IO (Result (Socket.Family, Socket.SockAddr))
229
resolveAddr port str = do
230
  resolved <- Socket.getAddrInfo resolveAddrHints (Just str) (Just (show port))
231
  return $ case resolved of
232
             [] -> Bad "Invalid results from lookup?"
233
             best:_ -> Ok $ (Socket.addrFamily best, Socket.addrAddress best)
234

  
235
-- | Based on the options, compute the socket address to use for the
236
-- daemon.
237
parseAddress :: DaemonOptions      -- ^ Command line options
238
             -> Int                -- ^ Default port for this daemon
239
             -> IO (Result (Socket.Family, Socket.SockAddr))
240
parseAddress opts defport = do
241
  let port = maybe defport fromIntegral $ optPort opts
242
  def_family <- Ssconf.getPrimaryIPFamily Nothing
243
  ainfo <- case optBindAddress opts of
244
             Nothing -> return (def_family >>= defaultBindAddr port)
245
             Just saddr -> catch (resolveAddr port saddr)
246
                           (annotateIOError $ "Invalid address " ++ saddr)
247
  return ainfo
248

  
197 249
-- | Run an I/O action as a daemon.
198 250
--
199 251
-- WARNING: this only works in single-threaded mode (either using the

Also available in: Unified diff