This daemon will take over cluster maintenance as per our design document. As it will heavily depend on the monitoring daemon, it will only be enabled (at configure time) if the monitoring daemon is enabled as well. It will also run as the same user and group.
In this commit only the plain daemon is added with the only supported request being the question for the supported protocol versions. Signed-off-by: Klaus Aehlig <[email protected]> --- .gitignore | 1 + Makefile.am | 10 ++- daemons/daemon-util.in | 2 +- doc/examples/ganeti.default | 1 + doc/examples/ganeti.default-debug | 1 + doc/examples/systemd/ganeti-maintd.service.in | 18 ++++++ src/Ganeti/Constants.hs | 7 +++ src/Ganeti/MaintD/Server.hs | 89 +++++++++++++++++++++++++++ src/Ganeti/Runtime.hs | 6 ++ src/ganeti-maintd.hs | 47 ++++++++++++++ test/hs/Test/Ganeti/Runtime.hs | 2 + test/py/daemon-util_unittest.bash | 4 +- 12 files changed, 182 insertions(+), 6 deletions(-) create mode 100644 doc/examples/systemd/ganeti-maintd.service.in create mode 100644 src/Ganeti/MaintD/Server.hs create mode 100644 src/ganeti-maintd.hs diff --git a/.gitignore b/.gitignore index e653ffc..0d19ea9 100644 --- a/.gitignore +++ b/.gitignore @@ -167,6 +167,7 @@ /src/ganeti-kvmd /src/ganeti-luxid /src/ganeti-metad +/src/ganeti-maintd /src/ganeti-mond /src/rpc-test diff --git a/Makefile.am b/Makefile.am index 936cdf4..240628c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -151,6 +151,7 @@ HS_DIRS = \ src/Ganeti/JQueue \ src/Ganeti/Locking \ src/Ganeti/Logging \ + src/Ganeti/MaintD \ src/Ganeti/Monitoring \ src/Ganeti/Metad \ src/Ganeti/Objects \ @@ -352,6 +353,7 @@ CLEANFILES = \ src/ganeti-confd \ src/ganeti-wconfd \ src/ganeti-luxid \ + src/ganeti-maintd \ src/ganeti-metad \ src/ganeti-mond \ .hpc/*.mix src/*.tix test/hs/*.tix *.tix \ @@ -371,7 +373,7 @@ clean-local: HS_GENERATED_FILES = $(HS_PROGS) src/hluxid src/ganeti-luxid \ src/hconfd src/ganeti-confd if ENABLE_MOND -HS_GENERATED_FILES += src/ganeti-mond +HS_GENERATED_FILES += src/ganeti-mond src/ganeti-maintd endif if ENABLE_METADATA HS_GENERATED_FILES += src/ganeti-metad @@ -410,6 +412,7 @@ BUILT_EXAMPLES = \ doc/examples/systemd/ganeti-kvmd.service \ doc/examples/systemd/ganeti-luxid.service \ doc/examples/systemd/ganeti-metad.service \ + doc/examples/systemd/ganeti-maintd.service \ doc/examples/systemd/ganeti-mond.service \ doc/examples/systemd/ganeti-noded.service \ doc/examples/systemd/ganeti-rapi.service \ @@ -767,7 +770,7 @@ HS_COMPILE_PROGS = \ src/hs2py \ src/rpc-test if ENABLE_MOND -HS_COMPILE_PROGS += src/ganeti-mond +HS_COMPILE_PROGS += src/ganeti-mond src/ganeti-maintd endif if ENABLE_METADATA HS_COMPILE_PROGS += src/ganeti-metad @@ -969,6 +972,7 @@ HS_LIB_SRCS = \ src/Ganeti/Logging/Lifted.hs \ src/Ganeti/Logging/WriterLog.hs \ src/Ganeti/Luxi.hs \ + src/Ganeti/MaintD/Server.hs \ src/Ganeti/Network.hs \ src/Ganeti/Objects.hs \ src/Ganeti/Objects/BitArray.hs \ @@ -1478,7 +1482,7 @@ src/ganeti-confd: src/hconfd cp -f $< $@ if ENABLE_MOND -nodist_sbin_SCRIPTS += src/ganeti-mond +nodist_sbin_SCRIPTS += src/ganeti-mond src/ganeti-maintd endif if ENABLE_METADATA diff --git a/daemons/daemon-util.in b/daemons/daemon-util.in index 6af85c2..e49472e 100644 --- a/daemons/daemon-util.in +++ b/daemons/daemon-util.in @@ -56,7 +56,7 @@ _mond_enabled() { } if _mond_enabled; then - DAEMONS+=( ganeti-mond ) + DAEMONS+=( ganeti-mond ganeti-maintd) fi # The full list of all daemons we know about diff --git a/doc/examples/ganeti.default b/doc/examples/ganeti.default index 281423b..51512a3 100644 --- a/doc/examples/ganeti.default +++ b/doc/examples/ganeti.default @@ -4,3 +4,4 @@ RAPI_ARGS="" CONFD_ARGS="" WCONFD_ARGS="" LUXID_ARGS="" +MAINTD_ARGS="" diff --git a/doc/examples/ganeti.default-debug b/doc/examples/ganeti.default-debug index e53edec..a91efc7 100644 --- a/doc/examples/ganeti.default-debug +++ b/doc/examples/ganeti.default-debug @@ -4,3 +4,4 @@ RAPI_ARGS="-d" CONFD_ARGS="-d" WCONFD_ARGS="-d" LUXID_ARGS="-d" +MAINTD_ARGS="-d" diff --git a/doc/examples/systemd/ganeti-maintd.service.in b/doc/examples/systemd/ganeti-maintd.service.in new file mode 100644 index 0000000..f7e906e --- /dev/null +++ b/doc/examples/systemd/ganeti-maintd.service.in @@ -0,0 +1,18 @@ +[Unit] +Description = Ganeti maintenance daemon (maintd) +Documentation = man:ganeti-maintd(8) +Requires = ganeti-common.service +After = ganeti-common.service +PartOf = ganeti-master.target +ConditionPathExists = @LOCALSTATEDIR@/lib/ganeti/config.data + +[Service] +Type = simple +User = @GNTMONDUSER@ +Group = @GNTMONDGROUP@ +ExecStart = @SBINDIR@/ganeti-maintd -f +Restart = on-failure +SuccessExitStatus = 0 11 + +[Install] +WantedBy = ganeti-master.target ganeti.target diff --git a/src/Ganeti/Constants.hs b/src/Ganeti/Constants.hs index da5233f..8c98e1f 100644 --- a/src/Ganeti/Constants.hs +++ b/src/Ganeti/Constants.hs @@ -367,6 +367,9 @@ metad = Runtime.daemonName GanetiMetad mond :: String mond = Runtime.daemonName GanetiMond +maintd :: String +maintd = Runtime.daemonName GanetiMaintd + noded :: String noded = Runtime.daemonName GanetiNoded @@ -398,6 +401,9 @@ defaultConfdPort = 1814 defaultMondPort :: Int defaultMondPort = 1815 +defaultMaintdPort :: Int +defaultMaintdPort = 1816 + defaultMetadPort :: Int defaultMetadPort = 80 @@ -413,6 +419,7 @@ daemonsPorts = [ (confd, (Udp, defaultConfdPort)) , (metad, (Tcp, defaultMetadPort)) , (mond, (Tcp, defaultMondPort)) + , (maintd, (Tcp, defaultMaintdPort)) , (noded, (Tcp, defaultNodedPort)) , (rapi, (Tcp, defaultRapiPort)) , (ssh, (Tcp, 22)) diff --git a/src/Ganeti/MaintD/Server.hs b/src/Ganeti/MaintD/Server.hs new file mode 100644 index 0000000..6442650 --- /dev/null +++ b/src/Ganeti/MaintD/Server.hs @@ -0,0 +1,89 @@ +{-# LANGUAGE OverloadedStrings #-} + +{-| Implementation of the Ganeti maintenenace server. + +-} + +{- + +Copyright (C) 2015 Google Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +1. Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +-} + +module Ganeti.MaintD.Server + ( options + , main + , checkMain + , prepMain + ) where + +import Control.Applicative ((<|>)) +import Snap.Core (Snap, method, Method(GET), ifTop) +import Snap.Http.Server (httpServe) +import Snap.Http.Server.Config (Config) + +import qualified Ganeti.Constants as C +import Ganeti.Daemon ( OptType, CheckFn, PrepFn, MainFn, oDebug + , oNoVoting, oYesDoIt, oPort, oBindAddress, oNoDaemonize) +import Ganeti.Daemon.Utils (handleMasterVerificationOptions) +import Ganeti.Runtime (GanetiDaemon(GanetiMaintd)) +import Ganeti.Utils.Http (httpConfFromOpts, plainJSON, error404) + +-- | Options list and functions. +options :: [OptType] +options = + [ oNoDaemonize + , oDebug + , oPort C.defaultMaintdPort + , oBindAddress + , oNoVoting + , oYesDoIt + ] + +-- | Type alias for checkMain results. +type CheckResult = () + +-- | Type alias for prepMain results +type PrepResult = Config Snap () + +-- | The information to serve via HTTP +httpInterface :: Snap () +httpInterface = ifTop (method GET $ plainJSON [1 :: Int]) + <|> error404 + +-- | Check function for luxid. +checkMain :: CheckFn CheckResult +checkMain = handleMasterVerificationOptions + +-- | Prepare function for luxid. +prepMain :: PrepFn CheckResult PrepResult +prepMain opts _ = httpConfFromOpts GanetiMaintd opts + +-- | Main function. +main :: MainFn CheckResult PrepResult +main _ _ httpConf = + httpServe httpConf httpInterface diff --git a/src/Ganeti/Runtime.hs b/src/Ganeti/Runtime.hs index 01f3885..60a8848 100644 --- a/src/Ganeti/Runtime.hs +++ b/src/Ganeti/Runtime.hs @@ -75,6 +75,7 @@ data GanetiDaemon = GanetiMasterd | GanetiWConfd | GanetiKvmd | GanetiLuxid + | GanetiMaintd | GanetiMond deriving (Show, Enum, Bounded, Eq, Ord) @@ -103,6 +104,7 @@ daemonName GanetiConfd = "ganeti-confd" daemonName GanetiWConfd = "ganeti-wconfd" daemonName GanetiKvmd = "ganeti-kvmd" daemonName GanetiLuxid = "ganeti-luxid" +daemonName GanetiMaintd = "ganeti-maintd" daemonName GanetiMond = "ganeti-mond" -- | Returns whether the daemon only runs on the master node. @@ -115,6 +117,7 @@ daemonOnlyOnMaster GanetiConfd = False daemonOnlyOnMaster GanetiWConfd = True daemonOnlyOnMaster GanetiKvmd = False daemonOnlyOnMaster GanetiLuxid = True +daemonOnlyOnMaster GanetiMaintd = True daemonOnlyOnMaster GanetiMond = False -- | Returns the log file base for a daemon. @@ -127,6 +130,7 @@ daemonLogBase GanetiConfd = "conf-daemon" daemonLogBase GanetiWConfd = "wconf-daemon" daemonLogBase GanetiKvmd = "kvm-daemon" daemonLogBase GanetiLuxid = "luxi-daemon" +daemonLogBase GanetiMaintd = "maintenance-daemon" daemonLogBase GanetiMond = "monitoring-daemon" -- | Returns the configured user name for a daemon. @@ -139,6 +143,7 @@ daemonUser GanetiConfd = AutoConf.confdUser daemonUser GanetiWConfd = AutoConf.wconfdUser daemonUser GanetiKvmd = AutoConf.kvmdUser daemonUser GanetiLuxid = AutoConf.luxidUser +daemonUser GanetiMaintd = AutoConf.mondUser daemonUser GanetiMond = AutoConf.mondUser -- | Returns the configured group for a daemon. @@ -151,6 +156,7 @@ daemonGroup (DaemonGroup GanetiConfd) = AutoConf.confdGroup daemonGroup (DaemonGroup GanetiWConfd) = AutoConf.wconfdGroup daemonGroup (DaemonGroup GanetiLuxid) = AutoConf.luxidGroup daemonGroup (DaemonGroup GanetiKvmd) = AutoConf.kvmdGroup +daemonGroup (DaemonGroup GanetiMaintd) = AutoConf.mondGroup daemonGroup (DaemonGroup GanetiMond) = AutoConf.mondGroup daemonGroup (ExtraGroup DaemonsGroup) = AutoConf.daemonsGroup daemonGroup (ExtraGroup AdminGroup) = AutoConf.adminGroup diff --git a/src/ganeti-maintd.hs b/src/ganeti-maintd.hs new file mode 100644 index 0000000..caa76fc --- /dev/null +++ b/src/ganeti-maintd.hs @@ -0,0 +1,47 @@ +{-| Ganeti maintenance agent daemon + +-} + +{- + +Copyright (C) 2015 Google Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +1. Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +-} + +module Main (main) where + +import Ganeti.Daemon +import Ganeti.Runtime +import qualified Ganeti.MaintD.Server as S + +-- | Main function. +main :: IO () +main = + genericMain GanetiMaintd S.options + S.checkMain + S.prepMain + S.main diff --git a/test/hs/Test/Ganeti/Runtime.hs b/test/hs/Test/Ganeti/Runtime.hs index ee48e0e..3e49dd6 100644 --- a/test/hs/Test/Ganeti/Runtime.hs +++ b/test/hs/Test/Ganeti/Runtime.hs @@ -97,6 +97,7 @@ case_UsersGroups = do \ constants.KVMD_USER,\n\ \ constants.LUXID_USER,\n\ \ constants.MOND_USER,\n\ + \ constants.MOND_USER,\n\ \ ]\n\ \groups = [constants.MASTERD_GROUP,\n\ \ constants.METAD_GROUP,\n\ @@ -107,6 +108,7 @@ case_UsersGroups = do \ constants.KVMD_GROUP,\n\ \ constants.LUXID_GROUP,\n\ \ constants.MOND_GROUP,\n\ + \ constants.MOND_GROUP,\n\ \ constants.DAEMONS_GROUP,\n\ \ constants.ADMIN_GROUP,\n\ \ ]\n\ diff --git a/test/py/daemon-util_unittest.bash b/test/py/daemon-util_unittest.bash index 1437713..84fd6f3 100755 --- a/test/py/daemon-util_unittest.bash +++ b/test/py/daemon-util_unittest.bash @@ -45,8 +45,8 @@ DAEMONS_LIST="noded confd wconfd rapi luxid kvmd" STOPDAEMONS_LIST="kvmd luxid rapi wconfd confd noded" if grep -q '^ENABLE_MOND = True' lib/_constants.py; then - DAEMONS_LIST="$DAEMONS_LIST mond" - STOPDAEMONS_LIST="mond $STOPDAEMONS_LIST" + DAEMONS_LIST="$DAEMONS_LIST mond maintd" + STOPDAEMONS_LIST="maintd mond $STOPDAEMONS_LIST" fi STOPDAEMONS_LIST="metad $STOPDAEMONS_LIST" -- 2.4.3.573.g4eafbef
