Commit ba8e831a authored by Helga Velroyen's avatar Helga Velroyen

Run functions while (some) daemons are stopped

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: default avatarHelga Velroyen <helgav@google.com>
Reviewed-by: default avatarKlaus Aehlig <aehlig@google.com>
parent 3ad10ad1
...@@ -267,6 +267,7 @@ __all__ = [ ...@@ -267,6 +267,7 @@ __all__ = [
"JobSubmittedException", "JobSubmittedException",
"ParseTimespec", "ParseTimespec",
"RunWhileClusterStopped", "RunWhileClusterStopped",
"RunWhileDaemonsStopped",
"SubmitOpCode", "SubmitOpCode",
"SubmitOpCodeToDrainedQueue", "SubmitOpCodeToDrainedQueue",
"SubmitOrSend", "SubmitOrSend",
...@@ -2935,12 +2936,12 @@ def GenericInstanceCreate(mode, opts, args): ...@@ -2935,12 +2936,12 @@ def GenericInstanceCreate(mode, opts, args):
return 0 return 0
class _RunWhileClusterStoppedHelper(object): class _RunWhileDaemonsStoppedHelper(object):
"""Helper class for L{RunWhileClusterStopped} to simplify state management """Helper class for L{RunWhileDaemonsStopped} to simplify state management
""" """
def __init__(self, feedback_fn, cluster_name, master_node, def __init__(self, feedback_fn, cluster_name, master_node,
online_nodes, ssh_ports): online_nodes, ssh_ports, exclude_daemons):
"""Initializes this class. """Initializes this class.
@type feedback_fn: callable @type feedback_fn: callable
...@@ -2953,6 +2954,10 @@ class _RunWhileClusterStoppedHelper(object): ...@@ -2953,6 +2954,10 @@ class _RunWhileClusterStoppedHelper(object):
@param online_nodes: List of names of online nodes @param online_nodes: List of names of online nodes
@type ssh_ports: list @type ssh_ports: list
@param ssh_ports: List of SSH ports of online nodes @param ssh_ports: List of SSH ports of online nodes
@type exclude_daemons: list of string
@param exclude_daemons: list of daemons to shutdown
@param exclude_daemons: list of daemons that will be restarted after
all others are shutdown
""" """
self.feedback_fn = feedback_fn self.feedback_fn = feedback_fn
...@@ -2966,6 +2971,8 @@ class _RunWhileClusterStoppedHelper(object): ...@@ -2966,6 +2971,8 @@ class _RunWhileClusterStoppedHelper(object):
self.nonmaster_nodes = [name for name in online_nodes self.nonmaster_nodes = [name for name in online_nodes
if name != master_node] if name != master_node]
self.exclude_daemons = exclude_daemons
assert self.master_node not in self.nonmaster_nodes assert self.master_node not in self.nonmaster_nodes
def _RunCmd(self, node_name, cmd): def _RunCmd(self, node_name, cmd):
...@@ -3017,6 +3024,13 @@ class _RunWhileClusterStoppedHelper(object): ...@@ -3017,6 +3024,13 @@ class _RunWhileClusterStoppedHelper(object):
for node_name in self.online_nodes: for node_name in self.online_nodes:
self.feedback_fn("Stopping daemons on %s" % node_name) self.feedback_fn("Stopping daemons on %s" % node_name)
self._RunCmd(node_name, [pathutils.DAEMON_UTIL, "stop-all"]) 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 # All daemons are shut down now
try: try:
...@@ -3029,18 +3043,31 @@ class _RunWhileClusterStoppedHelper(object): ...@@ -3029,18 +3043,31 @@ class _RunWhileClusterStoppedHelper(object):
finally: finally:
# Start cluster again, master node last # Start cluster again, master node last
for node_name in self.nonmaster_nodes + [self.master_node]: 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.feedback_fn("Starting daemons on %s" % node_name)
self._RunCmd(node_name, [pathutils.DAEMON_UTIL, "start-all"]) self._RunCmd(node_name, [pathutils.DAEMON_UTIL, "start-all"])
finally: finally:
# Resume watcher # Resume watcher
watcher_block.Close() 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. """Calls a function while all cluster daemons are stopped.
@type feedback_fn: callable @type feedback_fn: callable
@param feedback_fn: Feedback function @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 @type fn: callable
@param fn: Function to be called when daemons are stopped @param fn: Function to be called when daemons are stopped
...@@ -3060,9 +3087,24 @@ def RunWhileClusterStopped(feedback_fn, fn, *args): ...@@ -3060,9 +3087,24 @@ def RunWhileClusterStopped(feedback_fn, fn, *args):
del cl del cl
assert master_node in online_nodes 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, @type feedback_fn: callable
online_nodes, ssh_ports).Call(fn, *args) @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, def GenerateTable(headers, fields, separator, data,
......
...@@ -132,7 +132,7 @@ NODED_CERT_MODE = 0440 ...@@ -132,7 +132,7 @@ NODED_CERT_MODE = 0440
RESTRICTED_COMMANDS_LOCK_FILE = LOCK_DIR + "/ganeti-restricted-commands.lock" RESTRICTED_COMMANDS_LOCK_FILE = LOCK_DIR + "/ganeti-restricted-commands.lock"
#: Lock file for watcher, locked in shared mode by watcher; lock in exclusive #: 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" WATCHER_LOCK_FILE = LOCK_DIR + "/ganeti-watcher.lock"
#: Status file for per-group watcher, locked in exclusive mode by watcher #: Status file for per-group watcher, locked in exclusive mode by watcher
......
...@@ -375,6 +375,11 @@ rapi = Runtime.daemonName GanetiRapi ...@@ -375,6 +375,11 @@ rapi = Runtime.daemonName GanetiRapi
kvmd :: String kvmd :: String
kvmd = Runtime.daemonName GanetiKvmd 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 :: FrozenSet String
daemons = daemons =
ConstantUtils.mkSet ConstantUtils.mkSet
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment