Revision 3af1359f

b/.gitignore
140 140
/src/ganeti-confd
141 141
/src/ganeti-kvmd
142 142
/src/ganeti-luxid
143
/src/ganeti-metad
143 144
/src/ganeti-mond
144 145
/src/rpc-test
145 146

  
b/Makefile.am
595 595
# Haskell programs to be compiled by "make really-all"
596 596
HS_COMPILE_PROGS= \
597 597
	src/ganeti-kvmd \
598
	src/ganeti-metad \
598 599
	src/ganeti-mond \
599 600
	src/hconfd \
600 601
	src/hluxid \
......
713 714
	src/Ganeti/Logging.hs \
714 715
	src/Ganeti/Luxi.hs \
715 716
	src/Ganeti/Monitoring/Server.hs \
717
	src/Ganeti/Metad.hs \
716 718
	src/Ganeti/Network.hs \
717 719
	src/Ganeti/Objects.hs \
718 720
	src/Ganeti/OpCodes.hs \
......
1072 1074
nodist_sbin_SCRIPTS += src/ganeti-confd
1073 1075
nodist_sbin_SCRIPTS += src/ganeti-luxid
1074 1076
nodist_sbin_SCRIPTS += src/ganeti-kvmd
1077
nodist_sbin_SCRIPTS += src/ganeti-metad
1075 1078
endif
1076 1079

  
1077 1080
if ENABLE_MOND
......
1849 1852
	    -DADMIN_GROUP="$(ADMIN_GROUP)" \
1850 1853
	    -DMASTERD_USER="$(MASTERD_USER)" \
1851 1854
	    -DMASTERD_GROUP="$(MASTERD_GROUP)" \
1855
	    -DMETAD_USER="$(METAD_USER)" \
1856
	    -DMETAD_GROUP="$(METAD_GROUP)" \
1852 1857
	    -DRAPI_USER="$(RAPI_USER)" \
1853 1858
	    -DRAPI_GROUP="$(RAPI_GROUP)" \
1854 1859
	    -DCONFD_USER="$(CONFD_USER)" \
b/configure.ac
225 225
    [ to change the default)]
226 226
  )],
227 227
  [user_masterd="${withval}masterd";
228
   user_metad="${withval}metad";
228 229
   user_rapi="${withval}rapi";
229 230
   user_confd="${withval}confd";
230 231
   user_kvmd="$user_default";
......
232 233
   user_noded="$user_default";
233 234
   user_mond="$user_default"],
234 235
  [user_masterd="$user_default";
236
   user_metad="$user_default";
235 237
   user_rapi="$user_default";
236 238
   user_confd="$user_default";
237 239
   user_kvmd="$user_default";
......
239 241
   user_noded="$user_default";
240 242
   user_mond="$user_default"])
241 243
AC_SUBST(MASTERD_USER, $user_masterd)
244
AC_SUBST(METAD_USER, $user_metad)
242 245
AC_SUBST(RAPI_USER, $user_rapi)
243 246
AC_SUBST(CONFD_USER, $user_confd)
244 247
AC_SUBST(KVMD_USER, $user_kvmd)
......
259 262
   group_kvmd="$group_default";
260 263
   group_luxid="${withval}luxid";
261 264
   group_masterd="${withval}masterd";
265
   group_metad="${withval}metad";
262 266
   group_noded="$group_default";
263 267
   group_daemons="${withval}daemons";
264 268
   group_mond="$group_default"],
......
268 272
   group_kvmd="$group_default";
269 273
   group_luxid="$group_default";
270 274
   group_masterd="$group_default";
275
   group_metad="$group_default";
271 276
   group_noded="$group_default";
272 277
   group_daemons="$group_default";
273 278
   group_mond="$group_default"])
......
277 282
AC_SUBST(KVMD_GROUP, $group_kvmd)
278 283
AC_SUBST(LUXID_GROUP, $group_luxid)
279 284
AC_SUBST(MASTERD_GROUP, $group_masterd)
285
AC_SUBST(METAD_GROUP, $group_metad)
280 286
AC_SUBST(NODED_GROUP, $group_noded)
281 287
AC_SUBST(DAEMONS_GROUP, $group_daemons)
282 288
AC_SUBST(MOND_GROUP, $group_mond)
283 289

  
284 290
# Print the config to the user
285 291
AC_MSG_NOTICE([Running ganeti-masterd as $group_masterd:$group_masterd])
292
AC_MSG_NOTICE([Running ganeti-metad as $group_metad:$group_metad])
286 293
AC_MSG_NOTICE([Running ganeti-rapi as $user_rapi:$group_rapi])
287 294
AC_MSG_NOTICE([Running ganeti-confd as $user_confd:$group_confd])
288 295
AC_MSG_NOTICE([Running ganeti-luxid as $user_luxid:$group_luxid])
b/src/AutoConf.hs.in
7 7

  
8 8
{-
9 9

  
10
Copyright (C) 2013 Google Inc.
10
Copyright (C) 2013, 2014 Google Inc.
11 11

  
12 12
This program is free software; you can redistribute it and/or modify
13 13
it under the terms of the GNU General Public License as published by
......
157 157
masterdGroup :: String
158 158
masterdGroup = "MASTERD_GROUP"
159 159

  
160
metadUser :: String
161
metadUser = "METAD_USER"
162

  
163
metadGroup :: String
164
metadGroup = "METAD_GROUP"
165

  
160 166
rapiUser :: String
161 167
rapiUser = "RAPI_USER"
162 168

  
b/src/Ganeti/Constants.hs
200 200
masterdGroup :: String
201 201
masterdGroup = Runtime.daemonGroup (DaemonGroup GanetiMasterd)
202 202

  
203
metadUser :: String
204
metadUser = Runtime.daemonUser GanetiMetad
205

  
206
metadGroup :: String
207
metadGroup = Runtime.daemonGroup (DaemonGroup GanetiMetad)
208

  
203 209
rapiUser :: String
204 210
rapiUser = Runtime.daemonUser GanetiRapi
205 211

  
......
335 341
masterd :: String
336 342
masterd = Runtime.daemonName GanetiMasterd
337 343

  
344
metad :: String
345
metad = Runtime.daemonName GanetiMetad
346

  
338 347
mond :: String
339 348
mond = Runtime.daemonName GanetiMond
340 349

  
......
365 374
defaultMondPort :: Int
366 375
defaultMondPort = 1815
367 376

  
377
defaultMetadPort :: Int
378
defaultMetadPort = 8080
379

  
368 380
defaultNodedPort :: Int
369 381
defaultNodedPort = 1811
370 382

  
......
373 385

  
374 386
daemonsPorts :: Map String (Protocol, Int)
375 387
daemonsPorts =
376
  Map.fromList [(confd, (Udp, defaultConfdPort)),
377
                (mond, (Tcp, defaultMondPort)),
378
                (noded, (Tcp, defaultNodedPort)),
379
                (rapi, (Tcp, defaultRapiPort)),
380
                (ssh, (Tcp, 22))]
388
  Map.fromList
389
  [ (confd, (Udp, defaultConfdPort))
390
  , (metad, (Tcp, defaultMetadPort))
391
  , (mond, (Tcp, defaultMondPort))
392
  , (noded, (Tcp, defaultNodedPort))
393
  , (rapi, (Tcp, defaultRapiPort))
394
  , (ssh, (Tcp, 22))
395
  ]
381 396

  
382 397
firstDrbdPort :: Int
383 398
firstDrbdPort = 11000
b/src/Ganeti/Metad.hs
1
{-| Metadata daemon
2

  
3
-}
4

  
5
{-
6

  
7
Copyright (C) 2014 Google Inc.
8

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

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

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

  
24
-}
25

  
26
module Ganeti.Metad (start) where
27

  
28
import Control.Applicative
29
import Control.Monad.IO.Class (liftIO)
30
import qualified Data.ByteString.Char8 as ByteString (pack, unpack)
31
import Snap.Core
32
import Snap.Http.Server
33

  
34
import Ganeti.Daemon
35
import qualified Ganeti.Constants as Constants
36
import qualified Ganeti.Logging as Logging
37
import Ganeti.Runtime (GanetiDaemon(..), ExtraLogReason(..))
38
import qualified Ganeti.Runtime as Runtime
39

  
40
type MetaM = Snap ()
41

  
42
error404 :: MetaM
43
error404 = do
44
  modifyResponse . setResponseStatus 404 $ ByteString.pack "Not found"
45
  writeBS $ ByteString.pack "Resource not found"
46

  
47
handleMetadata :: Method -> String -> String -> String -> MetaM
48
handleMetadata GET  "ganeti" "latest" "meta_data.json" =
49
  liftIO $ Logging.logInfo "ganeti metadata"
50
handleMetadata GET  "ganeti" "latest" "os/parameters.json" =
51
  liftIO $ Logging.logInfo "ganeti OS parameters"
52
handleMetadata GET  "ganeti" "latest" "read" =
53
  liftIO $ Logging.logInfo "ganeti READ"
54
handleMetadata POST "ganeti" "latest" "write" =
55
  liftIO $ Logging.logInfo "ganeti WRITE"
56
handleMetadata _ _ _ _ = error404
57

  
58
routeMetadata :: MetaM
59
routeMetadata =
60
  route [ (providerRoute1, dispatchMetadata)
61
        , (providerRoute2, dispatchMetadata)
62
        ] <|> dispatchMetadata
63
  where provider = "provider"
64
        version  = "version"
65

  
66
        providerRoute1 = ByteString.pack $ ':':provider ++ "/" ++ ':':version
67
        providerRoute2 = ByteString.pack $ ':':version
68

  
69
        getParamString :: String -> Snap String
70
        getParamString =
71
          fmap (maybe "" ByteString.unpack) . getParam . ByteString.pack
72

  
73
        dispatchMetadata =
74
          do m <- rqMethod <$> getRequest
75
             p <- getParamString provider
76
             v <- getParamString version
77
             r <- ByteString.unpack . rqPathInfo <$> getRequest
78
             handleMetadata m p v r
79

  
80
defaultHttpConf :: DaemonOptions -> FilePath -> FilePath -> Config Snap ()
81
defaultHttpConf opts accessLog errorLog =
82
  maybe id (setBind . ByteString.pack) (optBindAddress opts) .
83
  setAccessLog (ConfigFileLog accessLog) .
84
  setCompression False .
85
  setErrorLog (ConfigFileLog errorLog) .
86
  setPort (maybe Constants.defaultMetadPort fromIntegral (optPort opts)) .
87
  setVerbose False $
88
  emptyConfig
89

  
90
start :: DaemonOptions -> IO ()
91
start opts = do
92
  accessLog <- Runtime.daemonsExtraLogFile GanetiMetad AccessLog
93
  errorLog <- Runtime.daemonsExtraLogFile GanetiMetad ErrorLog
94
  httpServe (defaultHttpConf opts accessLog errorLog) routeMetadata
b/src/Ganeti/Runtime.hs
4 4

  
5 5
{-
6 6

  
7
Copyright (C) 2011, 2012, 2013 Google Inc.
7
Copyright (C) 2011, 2012, 2013, 2014 Google Inc.
8 8

  
9 9
This program is free software; you can redistribute it and/or modify
10 10
it under the terms of the GNU General Public License as published by
......
60 60
import AutoConf
61 61

  
62 62
data GanetiDaemon = GanetiMasterd
63
                  | GanetiMetad
63 64
                  | GanetiNoded
64 65
                  | GanetiRapi
65 66
                  | GanetiConfd
......
81 82
-- | Returns the daemon name for a given daemon.
82 83
daemonName :: GanetiDaemon -> String
83 84
daemonName GanetiMasterd = "ganeti-masterd"
85
daemonName GanetiMetad   = "ganeti-metad"
84 86
daemonName GanetiNoded   = "ganeti-noded"
85 87
daemonName GanetiRapi    = "ganeti-rapi"
86 88
daemonName GanetiConfd   = "ganeti-confd"
......
91 93
-- | Returns whether the daemon only runs on the master node.
92 94
daemonOnlyOnMaster :: GanetiDaemon -> Bool
93 95
daemonOnlyOnMaster GanetiMasterd = True
96
daemonOnlyOnMaster GanetiMetad   = False
94 97
daemonOnlyOnMaster GanetiNoded   = False
95 98
daemonOnlyOnMaster GanetiRapi    = False
96 99
daemonOnlyOnMaster GanetiConfd   = False
......
101 104
-- | Returns the log file base for a daemon.
102 105
daemonLogBase :: GanetiDaemon -> String
103 106
daemonLogBase GanetiMasterd = "master-daemon"
107
daemonLogBase GanetiMetad   = "meta-daemon"
104 108
daemonLogBase GanetiNoded   = "node-daemon"
105 109
daemonLogBase GanetiRapi    = "rapi-daemon"
106 110
daemonLogBase GanetiConfd   = "conf-daemon"
......
111 115
-- | Returns the configured user name for a daemon.
112 116
daemonUser :: GanetiDaemon -> String
113 117
daemonUser GanetiMasterd = AutoConf.masterdUser
118
daemonUser GanetiMetad   = AutoConf.metadUser
114 119
daemonUser GanetiNoded   = AutoConf.nodedUser
115 120
daemonUser GanetiRapi    = AutoConf.rapiUser
116 121
daemonUser GanetiConfd   = AutoConf.confdUser
......
121 126
-- | Returns the configured group for a daemon.
122 127
daemonGroup :: GanetiGroup -> String
123 128
daemonGroup (DaemonGroup GanetiMasterd) = AutoConf.masterdGroup
129
daemonGroup (DaemonGroup GanetiMetad)   = AutoConf.metadGroup
124 130
daemonGroup (DaemonGroup GanetiNoded)   = AutoConf.nodedGroup
125 131
daemonGroup (DaemonGroup GanetiRapi)    = AutoConf.rapiGroup
126 132
daemonGroup (DaemonGroup GanetiConfd)   = AutoConf.confdGroup
b/src/ganeti-metad.hs
1
{-| Metadata daemon.
2

  
3
-}
4

  
5
{-
6

  
7
Copyright (C) 2014 Google Inc.
8

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

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

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

  
24
-}
25

  
26
module Main (main) where
27

  
28
import qualified Ganeti.Constants as Constants
29
import Ganeti.Daemon (OptType)
30
import qualified Ganeti.Daemon as Daemon
31
import qualified Ganeti.Metad as Metad
32
import qualified Ganeti.Runtime as Runtime
33

  
34
options :: [OptType]
35
options =
36
  [ Daemon.oBindAddress
37
  , Daemon.oDebug
38
  , Daemon.oNoDaemonize
39
  , Daemon.oNoUserChecks
40
  , Daemon.oPort Constants.defaultMetadPort
41
  ]
42

  
43
main :: IO ()
44
main =
45
  Daemon.genericMain Runtime.GanetiMetad options
46
    (\_ -> return . Right $ ())
47
    (\_ _ -> return ())
48
    (\opts _ _ -> Metad.start opts)
b/test/hs/Test/Ganeti/Runtime.hs
85 85
              \         constants.CONFD_USER,\n\
86 86
              \         constants.KVMD_USER,\n\
87 87
              \         constants.LUXID_USER,\n\
88
              \         constants.METAD_USER,\n\
88 89
              \         constants.MOND_USER,\n\
89 90
              \        ]\n\
90 91
              \groups = [constants.MASTERD_GROUP,\n\
......
93 94
              \          constants.CONFD_GROUP,\n\
94 95
              \          constants.KVMD_GROUP,\n\
95 96
              \          constants.LUXID_GROUP,\n\
97
              \          constants.METAD_GROUP,\n\
96 98
              \          constants.MOND_GROUP,\n\
97 99
              \          constants.DAEMONS_GROUP,\n\
98 100
              \          constants.ADMIN_GROUP,\n\

Also available in: Unified diff