Skip to content

Commit

Permalink
Dev: ui_cluster: Support start/stop with --all option or specific node
Browse files Browse the repository at this point in the history
  • Loading branch information
liangxin1300 committed Jun 1, 2021
1 parent aa5f338 commit 23e3ac8
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 36 deletions.
93 changes: 62 additions & 31 deletions crmsh/ui_cluster.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def parse_options(parser, args):
options, args = parser.parse_known_args(list(args))
except:
return None, None
if options.help:
if hasattr(options, 'help') and options.help:
parser.print_help()
return None, None
utils.check_space_option_value(options)
Expand Down Expand Up @@ -87,41 +87,76 @@ def __init__(self):
self._inventory_nodes = None
self._inventory_target = None

def _parse_option_for_nodes(self, action_type, context, *args):
"""
Parse option for nodes
"""
usage_template = """
Specify the node(s) on which to {action_type} cluster service.
If no nodes are specified, {action_type} cluster service on the local node.
If --all is specified, {action_type} cluster service on all nodes"""
parser = ArgParser(description=usage_template.format(action_type=action_type),
usage="{} [--all | <node>... ]".format(action_type),
add_help=False,
formatter_class=RawDescriptionHelpFormatter)
parser.add_argument("-h", "--help", action="store_true", dest="help", help="Show this help message")
parser.add_argument("--all", help="To {} a cluster on all nodes".format(action_type), action="store_true", dest="all")

options, args = parse_options(parser, args)
if options is None or args is None:
raise utils.TerminateSubCommand
if options.all and args:
context.fatal_error("Should either use --all or specific node")

# return local node
if not options.all and not args:
return [utils.this_node()]

member_list = utils.list_cluster_nodes()
if not member_list:
context.fatal_error("Cannot get the node list from cluster")
for node in args:
if node not in member_list:
context.fatal_error("Node \"{}\" is not a cluster node".format(node))

# return node list
return member_list if options.all else args

@command.skill_level('administrator')
def do_start(self, context):
def do_start(self, context, *args):
'''
Starts the cluster services on this node
'''
try:
if utils.service_is_active("pacemaker.service"):
err_buf.info("Cluster services already started")
return
utils.start_service("pacemaker")
if utils.is_qdevice_configured():
utils.start_service("corosync-qdevice")
err_buf.info("Cluster services started")
except IOError as err:
context.fatal_error(str(err))

# TODO: optionally start services on all nodes or specific node
node_list = self._parse_option_for_nodes("start", context, *args)
for node in node_list[:]:
if utils.service_is_active("pacemaker.service", remote_addr=node):
err_buf.info("Cluster services already started on {}".format(node))
node_list.remove(node)
if not node_list:
return
utils.cluster_run_cmd("systemctl start pacemaker.service", node_list)
if utils.is_qdevice_configured():
utils.cluster_run_cmd("systemctl start corosync-qdevice.service", node_list)
for node in node_list:
err_buf.info("Cluster services started on {}".format(node))

@command.skill_level('administrator')
def do_stop(self, context):
def do_stop(self, context, *args):
'''
Stops the cluster services on this node
'''
try:
if not utils.service_is_active("corosync.service"):
err_buf.info("Cluster services already stopped")
return
if utils.service_is_active("corosync-qdevice"):
utils.stop_service("corosync-qdevice")
utils.stop_service("corosync")
err_buf.info("Cluster services stopped")
except IOError as err:
context.fatal_error(str(err))

# TODO: optionally stop services on all nodes or specific node
node_list = self._parse_option_for_nodes("stop", context, *args)
for node in node_list[:]:
if not utils.service_is_active("corosync.service", remote_addr=node):
err_buf.info("Cluster services already stopped on {}".format(node))
node_list.remove(node)
if not node_list:
return
qdevice_cmd = "systemctl is-active --quiet {qs} && systemctl stop {qs} || echo 0".format(qs="corosync-qdevice.service")
utils.cluster_run_cmd(qdevice_cmd, node_list)
utils.cluster_run_cmd("systemctl stop corosync.service", node_list)
for node in node_list:
err_buf.info("Cluster services stopped on {}".format(node))

@command.skill_level('administrator')
def do_restart(self, context):
Expand All @@ -144,8 +179,6 @@ def do_enable(self, context):
except IOError as err:
context.fatal_error(str(err))

# TODO: optionally enable services on all nodes or specific node

@command.skill_level('administrator')
def do_disable(self, context):
'''
Expand All @@ -159,8 +192,6 @@ def do_disable(self, context):
except IOError as err:
context.fatal_error(str(err))

# TODO: optionally disable services on all nodes or specific node

def _args_implicit(self, context, args, name):
'''
handle early non-nvpair arguments as
Expand Down
10 changes: 5 additions & 5 deletions crmsh/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -1747,14 +1747,14 @@ def getname(toks):
raise ValueError("Error listing cluster nodes: %s" % (msg))


def cluster_run_cmd(cmd):
def cluster_run_cmd(cmd, node_list=[]):
"""
Run cmd in cluster nodes
"""
node_list = list_cluster_nodes()
if not node_list:
nodelist = node_list or list_cluster_nodes()
if not nodelist:
raise ValueError("Failed to get node list from cluster")
parallax.parallax_call(node_list, cmd)
return parallax.parallax_call(nodelist, cmd)


def list_cluster_nodes_except_me():
Expand Down Expand Up @@ -2515,7 +2515,7 @@ def _do_action(self, action_type):
raise ValueError("status_type should be {}".format('/'.join(list(self.ACTION_MAP.values()))))

cmd = "systemctl {} {}".format(action_type, self.service_name)
if self.remote_addr:
if self.remote_addr and self.remote_addr != this_node():
prompt_msg = "Run \"{}\" on {}".format(cmd, self.remote_addr)
rc, output, err = run_cmd_on_remote(cmd, self.remote_addr, prompt_msg)
else:
Expand Down

0 comments on commit 23e3ac8

Please sign in to comment.