For the new renew-crypto operation, we need to run functions while most of the daemons are stopped, except for WConfd. This refactors our code a bit and generalizes the method that runs functions while *all* daemons are stopped to one that accepts a list of daemons to not be stopped.
Signed-off-by: Helga Velroyen <[email protected]> --- lib/cli.py | 52 +++++++++++++++++++++++++++++++++++++++++++------ lib/pathutils.py | 2 +- src/Ganeti/Constants.hs | 15 +++++++++----- 3 files changed, 57 insertions(+), 12 deletions(-) diff --git a/lib/cli.py b/lib/cli.py index c51c2a5..195a77b 100644 --- a/lib/cli.py +++ b/lib/cli.py @@ -267,6 +267,7 @@ __all__ = [ "JobSubmittedException", "ParseTimespec", "RunWhileClusterStopped", + "RunWhileDaemonsStopped", "SubmitOpCode", "SubmitOpCodeToDrainedQueue", "SubmitOrSend", @@ -2935,12 +2936,12 @@ def GenericInstanceCreate(mode, opts, args): return 0 -class _RunWhileClusterStoppedHelper(object): - """Helper class for L{RunWhileClusterStopped} to simplify state management +class _RunWhileDaemonsStoppedHelper(object): + """Helper class for L{RunWhileDaemonsStopped} to simplify state management """ def __init__(self, feedback_fn, cluster_name, master_node, - online_nodes, ssh_ports): + online_nodes, ssh_ports, exclude_daemons): """Initializes this class. @type feedback_fn: callable @@ -2953,6 +2954,8 @@ class _RunWhileClusterStoppedHelper(object): @param online_nodes: List of names of online nodes @type ssh_ports: list @param ssh_ports: List of SSH ports of online nodes + @type exclude_daemons: list of string + @param exclude_daemons: list of daemons to shutdown """ self.feedback_fn = feedback_fn @@ -2966,6 +2969,8 @@ class _RunWhileClusterStoppedHelper(object): self.nonmaster_nodes = [name for name in online_nodes if name != master_node] + self.exclude_daemons = exclude_daemons + assert self.master_node not in self.nonmaster_nodes def _RunCmd(self, node_name, cmd): @@ -3017,6 +3022,13 @@ class _RunWhileClusterStoppedHelper(object): for node_name in self.online_nodes: self.feedback_fn("Stopping daemons on %s" % node_name) self._RunCmd(node_name, [pathutils.DAEMON_UTIL, "stop-all"]) + # Starting any daemons listed as exception + for daemon in self.exclude_daemons: + if (daemon in constants.DAEMONS_MASTER and + node_name != self.master_node): + continue + self.feedback_fn("Starting daemon '%s' on %s" % (daemon, node_name)) + self._RunCmd(node_name, [pathutils.DAEMON_UTIL, "start", daemon]) # All daemons are shut down now try: @@ -3029,18 +3041,31 @@ class _RunWhileClusterStoppedHelper(object): finally: # Start cluster again, master node last for node_name in self.nonmaster_nodes + [self.master_node]: + # Stopping any daemons listed as exception. + # This might look unnecessary, but it makes sure that daemon-util + # starts all daemons in the right order. + for daemon in self.exclude_daemons: + if (daemon in constants.DAEMONS_MASTER and + node_name != self.master_node): + continue + self.feedback_fn("Stopping daemon '%s' on %s" % (daemon, node_name)) + self._RunCmd(node_name, [pathutils.DAEMON_UTIL, "stop", daemon]) self.feedback_fn("Starting daemons on %s" % node_name) self._RunCmd(node_name, [pathutils.DAEMON_UTIL, "start-all"]) + finally: # Resume watcher watcher_block.Close() -def RunWhileClusterStopped(feedback_fn, fn, *args): +def RunWhileDaemonsStopped(feedback_fn, exclude_daemons, fn, *args): """Calls a function while all cluster daemons are stopped. @type feedback_fn: callable @param feedback_fn: Feedback function + @type exclude_daemons: list of string + @param exclude_daemons: list of daemons that are NOT stopped. If None, + all daemons will be stopped. @type fn: callable @param fn: Function to be called when daemons are stopped @@ -3060,9 +3085,24 @@ def RunWhileClusterStopped(feedback_fn, fn, *args): del cl assert master_node in online_nodes + if exclude_daemons is None: + exclude_daemons = [] + + return _RunWhileDaemonsStoppedHelper( + feedback_fn, cluster_name, master_node, online_nodes, ssh_ports, + exclude_daemons).Call(fn, *args) + + +def RunWhileClusterStopped(feedback_fn, fn, *args): + """Calls a function while all cluster daemons are stopped. - return _RunWhileClusterStoppedHelper(feedback_fn, cluster_name, master_node, - online_nodes, ssh_ports).Call(fn, *args) + @type feedback_fn: callable + @param feedback_fn: Feedback function + @type fn: callable + @param fn: Function to be called when daemons are stopped + + """ + RunWhileDaemonsStopped(feedback_fn, None, fn, *args) def GenerateTable(headers, fields, separator, data, diff --git a/lib/pathutils.py b/lib/pathutils.py index 0e02142..203df47 100644 --- a/lib/pathutils.py +++ b/lib/pathutils.py @@ -132,7 +132,7 @@ NODED_CERT_MODE = 0440 RESTRICTED_COMMANDS_LOCK_FILE = LOCK_DIR + "/ganeti-restricted-commands.lock" #: Lock file for watcher, locked in shared mode by watcher; lock in exclusive -# mode to block watcher (see L{cli._RunWhileClusterStoppedHelper.Call} +# mode to block watcher (see L{cli._RunWhileDaemonsStoppedHelper.Call} WATCHER_LOCK_FILE = LOCK_DIR + "/ganeti-watcher.lock" #: Status file for per-group watcher, locked in exclusive mode by watcher diff --git a/src/Ganeti/Constants.hs b/src/Ganeti/Constants.hs index dea59a5..9428780 100644 --- a/src/Ganeti/Constants.hs +++ b/src/Ganeti/Constants.hs @@ -375,14 +375,19 @@ rapi = Runtime.daemonName GanetiRapi kvmd :: String kvmd = Runtime.daemonName GanetiKvmd +-- Set of daemons which only run on the master. +-- Keep in sync with the 'daemon-util' script. +daemonsMaster :: FrozenSet String +daemonsMaster = ConstantUtils.mkSet [wconfd, luxid, rapi] + daemons :: FrozenSet String daemons = - ConstantUtils.mkSet [confd, + ConstantUtils.mkSet [noded, + wconfd, + rapi, luxid, - masterd, - mond, - noded, - rapi] + kvmd, + mond] defaultConfdPort :: Int defaultConfdPort = 1814 -- 2.4.3.573.g4eafbef
