LGTM, thanks On Thu, Mar 5, 2015 at 4:29 PM, 'Klaus Aehlig' via ganeti-devel < [email protected]> wrote:
> > > commit 5394497ccf8ebb6dea00fa07fba5a6eb50ae58f5 > Merge: c578370 6f7fcb8 > Author: Klaus Aehlig <[email protected]> > Date: Thu Mar 5 15:55:24 2015 +0100 > > Merge branch 'stable-2.12' into stable-2.13 > > * stable-2.12 > Only read config if necessary > Always OutDate() the lu's config > Outdate the config when waiting for locks > Support outdating a config > Allow unlocked reading of the config > Also in tests, open fake config before editing > Fix a few haddock comments > > * stable-2.11 > Skip offline nodes in RENEW_CRYPTO jobs > > * stable-2.10 > Remove unused import > Use an old way to instance NFData CollectorData > MonD: force computation of state in stateful collectors > Instance NFData CollectorData > > Semantical Conflicts: > + Readd those OutDate of 8303156e9d35317be0fbf68fe147b3148874408c > that couldn't be part of the > cherry-pick 4a26f3bbbb672647f68dca6b34c2325be8073e2a > + As the type of the state of stateful data collectors has > changed, also add an instance NFData ClockTime. > + Code added in 011924bd75bc27dec07ba9547ab9510a5724a8f8 left > the scope of feedback_fn > > Signed-off-by: Klaus Aehlig <[email protected]> > > diff --cc lib/cmdlib/cluster.py > index 414127a,193f306..5035918 > --- a/lib/cmdlib/cluster.py > +++ b/lib/cmdlib/cluster.py > @@@ -156,6 -130,9 +156,9 @@@ class LUClusterRenewCrypto(NoHooksLU) > self.cfg.AddNodeToCandidateCerts(master_uuid, new_master_digest) > nodes = self.cfg.GetAllNodesInfo() > for (node_uuid, node_info) in nodes.items(): > + if node_info.offline: > - feedback_fn("* Skipping offline node %s" % node_info.name) > ++ logging.info("* Skipping offline node %s", node_info.name) > + continue > if node_uuid != master_uuid: > new_digest = CreateNewClientCert(self, node_uuid) > if node_info.master_candidate: > diff --cc lib/mcpu.py > index 609e240,7446bc1..c83bb35 > --- a/lib/mcpu.py > +++ b/lib/mcpu.py > @@@ -476,10 -412,8 +476,12 @@@ class Processor(object) > else: > request = [[lock, "exclusive"] for lock in locks] > > + if request_only: > + logging.debug("Lock request for level %s is %s", level, request) > + return request > + > + self.cfg.OutDate() > + > if timeout is None: > ## Note: once we are so desperate for locks to request them > ## unconditionally, we no longer care about an original plan > @@@ -568,13 -535,6 +571,14 @@@ > acquiring_locks = level in lu.needed_locks > > if level not in locking.LEVELS: > + if pending: > + self._RequestAndWait(pending, calc_timeout()) > ++ lu.cfg.OutDate() > + lu.wconfdlocks = > self.wconfd.Client().ListLocks(self._wconfdcontext) > + pending = [] > + > + logging.debug("Finished acquiring locks") > + > _VerifyLocks(lu) > > if self._cbs: > @@@ -611,13 -558,6 +615,14 @@@ > # Determine if the acquiring is opportunistic up front > opportunistic = lu.opportunistic_locks[level] > > + dont_collate = lu.dont_collate_locks[level] > + > + if dont_collate and pending: > + self._RequestAndWait(pending, calc_timeout()) > ++ lu.cfg.OutDate() > + lu.wconfdlocks = > self.wconfd.Client().ListLocks(self._wconfdcontext) > + pending = [] > + > if adding_locks and opportunistic: > # We could simultaneously acquire locks opportunistically and add > new > # ones, but that would require altering the API, and no use cases > are > @@@ -648,23 -588,12 +653,24 @@@ > if adding_locks: > needed_locks.extend(_LockList(lu.add_locks[level])) > > - self._AcquireLocks(level, needed_locks, share, opportunistic, > - calc_timeout(), > - opportunistic_count=opportunistic_count) > - lu.wconfdlocks = > self.wconfd.Client().ListLocks(self._wconfdcontext) > - > - result = self._LockAndExecLU(lu, level + 1, calc_timeout) > + timeout = calc_timeout() > + if timeout is not None and not opportunistic: > + pending = pending + self._AcquireLocks(level, needed_locks, > share, > + opportunistic, timeout, > + request_only=True) > + else: > + if pending: > + self._RequestAndWait(pending, calc_timeout()) > ++ lu.cfg.OutDate() > + lu.wconfdlocks = > self.wconfd.Client().ListLocks(self._wconfdcontext) > + pending = [] > + self._AcquireLocks(level, needed_locks, share, opportunistic, > + timeout, > + opportunistic_count=opportunistic_count) > + lu.wconfdlocks = > self.wconfd.Client().ListLocks(self._wconfdcontext) > + > + result = self._LockAndExecLU(lu, level + 1, calc_timeout, > + pending=pending) > finally: > levelname = locking.LEVEL_NAMES[level] > logging.debug("Freeing locks at level %s for %s", > diff --cc src/Ganeti/DataCollectors/Types.hs > index e4db7b8,c2ab6ad..b1414c3 > --- a/src/Ganeti/DataCollectors/Types.hs > +++ b/src/Ganeti/DataCollectors/Types.hs > @@@ -1,4 -1,4 +1,5 @@@ > {-# LANGUAGE TemplateHaskell #-} > ++{-# OPTIONS_GHC -fno-warn-orphans #-} > > {-| Implementation of the Ganeti data collector types. > > @@@ -47,10 -47,10 +48,12 @@@ module Ganeti.DataCollectors.Type > , buildReport > , mergeStatuses > , getCategoryName > + , ReportBuilder(..) > + , DataCollector(..) > ) where > > + import Control.DeepSeq (NFData, rnf) > + import Control.Seq (using, seqFoldable, rdeepseq) > import Data.Char > import Data.Ratio > import qualified Data.Map as Map > @@@ -139,8 -138,27 +142,30 @@@ instance JSON DCVersion wher > readJSON v = fail $ "Invalid JSON value " ++ show v ++ " for type > DCVersion" > > -- | Type for the value field of the `CollectorMap` below. > -data CollectorData = CPULoadData (Seq.Seq (Integer, [Int])) > +data CollectorData = CPULoadData (Seq.Seq (ClockTime, [Int])) > > + {- > + > + Naturally, we want to make CollectorData an instance of NFData as > + follows. > + > + instance NFData CollectorData where > + rnf (CPULoadData x) = rnf x > + > + However, Seq.Seq only became an instance of NFData in version 0.5.0.0 > + of containers (Released 2012). So, for the moment, we use a generic > + way to reduce to normal form. In later versions of Ganeti, where we > + have the infra structure to do so, we will choose implementation > depending > + on the version of the containers library available. > + > + -} > + > ++instance NFData ClockTime where > ++ rnf (TOD x y) = rnf x `seq` rnf y > ++ > + instance NFData CollectorData where > + rnf (CPULoadData x) = (x `using` seqFoldable rdeepseq) `seq` () > + > -- | Type for the map storing the data of the statefull DataCollectors. > type CollectorMap = Map.Map String CollectorData > > diff --cc src/Ganeti/Monitoring/Server.hs > index bd98d35,62074b3..0c3cb0f > --- a/src/Ganeti/Monitoring/Server.hs > +++ b/src/Ganeti/Monitoring/Server.hs > @@@ -42,15 -41,13 +42,17 @@@ module Ganeti.Monitoring.Serve > ) where > > import Control.Applicative > + import Control.DeepSeq (force) > + import Control.Exception.Base (evaluate) > import Control.Monad > import Control.Monad.IO.Class > -import Data.ByteString.Char8 hiding (map, filter, find) > -import Data.List > +import Data.ByteString.Char8 (pack, unpack) > +import Data.Maybe (fromMaybe) > +import Data.List (find) > +import Data.Monoid (mempty) > import qualified Data.Map as Map > +import qualified Data.PSQueue as Queue > +import Network.BSD (getServicePortNumber) > import Snap.Core > import Snap.Http.Server > import qualified Text.JSON as J > > -- > Klaus Aehlig > Google Germany GmbH, Dienerstr. 12, 80331 Muenchen > Registergericht und -nummer: Hamburg, HRB 86891 > Sitz der Gesellschaft: Hamburg > Geschaeftsfuehrer: Graham Law, Christine Elizabeth Flores > Hrvoje Ribicic Ganeti Engineering Google Germany GmbH Dienerstr. 12, 80331, München Registergericht und -nummer: Hamburg, HRB 86891 Sitz der Gesellschaft: Hamburg Geschäftsführer: Graham Law, Christine Elizabeth Flores Steuernummer: 48/725/00206 Umsatzsteueridentifikationsnummer: DE813741370
