Server.hs 3.53 KB
Newer Older
Petr Pudlak's avatar
Petr Pudlak committed
1
2
3
4
5
6
7
8
9
10
11
12
{-# LANGUAGE TemplateHaskell #-}

{-| The implementation of Ganeti WConfd daemon server.

As TemplateHaskell require that splices be defined in a separate
module, we combine all the TemplateHaskell functionality that HTools
needs in this module (except the one for unittests).

-}

{-

Klaus Aehlig's avatar
Klaus Aehlig committed
13
Copyright (C) 2013, 2014 Google Inc.
Petr Pudlak's avatar
Petr Pudlak committed
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.

-}

module Ganeti.WConfd.Server where

Klaus Aehlig's avatar
Klaus Aehlig committed
34
import Control.Concurrent (forkIO)
Petr Pudlak's avatar
Petr Pudlak committed
35
36
37
import Control.Exception
import Control.Monad
import Control.Monad.Error
38
import System.Directory (doesFileExist)
Petr Pudlak's avatar
Petr Pudlak committed
39
40
41

import Ganeti.BasicTypes
import Ganeti.Daemon
Klaus Aehlig's avatar
Klaus Aehlig committed
42
import Ganeti.Logging (logInfo, logDebug)
43
import Ganeti.Locking.Locks
44
import Ganeti.Locking.Waiting
Petr Pudlak's avatar
Petr Pudlak committed
45
46
47
48
49
50
import qualified Ganeti.Path as Path
import Ganeti.THH.RPC
import Ganeti.UDSServer

import Ganeti.Runtime
import Ganeti.WConfd.ConfigState
51
import Ganeti.WConfd.ConfigWriter
Petr Pudlak's avatar
Petr Pudlak committed
52
import Ganeti.WConfd.Core
Klaus Aehlig's avatar
Klaus Aehlig committed
53
import Ganeti.WConfd.DeathDetection (cleanupLocksTask)
Petr Pudlak's avatar
Petr Pudlak committed
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
import Ganeti.WConfd.Monad

handler :: DaemonHandle -> RpcServer WConfdMonadInt
handler ch = $( mkRpcM exportedFunctions )


-- | Type alias for prepMain results
type PrepResult = (Server, DaemonHandle)

-- | Check function for luxid.
checkMain :: CheckFn ()
checkMain _ = return $ Right ()

-- | Prepare function for luxid.
prepMain :: PrepFn () PrepResult
prepMain _ _ = do
  socket_path <- Path.defaultWConfdSocket
  cleanupSocket socket_path
  s <- describeError "binding to the socket" Nothing (Just socket_path)
73
         $ connectServer serverConfig True socket_path
74

Petr Pudlak's avatar
Petr Pudlak committed
75
76
77
  -- TODO: Lock the configuration file so that running the daemon twice fails?
  conf_file <- Path.clusterConfFile

78
79
  lock_file <- Path.lockStatusFile
  lock_file_present <- doesFileExist lock_file
80
  unless lock_file_present
81
    $ logInfo "No saved lock status; assuming all locks free"
82
83
84
  dh <- toErrorBase
        . withErrorT (strMsg . ("Initialization of the daemon failed" ++)
                             . show) $ do
85
    ents <- getEnts
86
    (cdata, cstat) <- loadConfigFromFile conf_file
87
88
    lock <- if lock_file_present
              then loadLockAllocation lock_file
89
              else return emptyWaiting
90
91
    mkDaemonHandle conf_file
                   (mkConfigState cdata)
92
                   lock
93
                   (saveConfigAsyncTask conf_file cstat)
94
                   (distMCsAsyncTask ents conf_file)
95
                   distSSConfAsyncTask
96
                   (writeLocksAsyncTask lock_file)
Petr Pudlak's avatar
Petr Pudlak committed
97
98
99

  return (s, dh)

100
101
serverConfig :: ServerConfig
serverConfig = ServerConfig GanetiLuxid $ ConnectConfig 60 60
Petr Pudlak's avatar
Petr Pudlak committed
102
103
104

-- | Main function.
main :: MainFn () PrepResult
Klaus Aehlig's avatar
Klaus Aehlig committed
105
106
107
main _ _ (server, dh) = do
  logDebug "Starting the cleanup task"
  _ <- forkIO $ runWConfdMonadInt cleanupLocksTask dh
Petr Pudlak's avatar
Petr Pudlak committed
108
109
110
111
112
113
114
115
116
117
118
119
  finally
    (forever $ runWConfdMonadInt (listener (handler dh) server) dh)
    (liftIO $ closeServer server)


-- | Options list and functions.
options :: [OptType]
options =
  [ oNoDaemonize
  , oNoUserChecks
  , oDebug
  , oSyslogUsage
120
  , oForceNode
Petr Pudlak's avatar
Petr Pudlak committed
121
  ]