From 8be1cd533f57c1dc94644f76968a389006017089 Mon Sep 17 00:00:00 2001 From: theboringstuff <39027092+theboringstuff@users.noreply.github.com> Date: Mon, 30 Jun 2025 10:16:21 +0500 Subject: [PATCH 1/4] fix printing --- sm-client | 50 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 32 insertions(+), 18 deletions(-) diff --git a/sm-client b/sm-client index 4ecedc88..f97c1474 100755 --- a/sm-client +++ b/sm-client @@ -53,28 +53,42 @@ This site: args: argparse.Namespace - def print_service_order(sm_dict: SMClusterState, cmd, site): """ Show service list ordered by dependency in debug mode""" + if cmd == "status" or cmd == "list": + # status is collected in parallel for all services, there is no order + return + stage = 0 logging.debug("Service order by dependency:") - for mod_i in [ i for i in settings.sm_conf.get_modules() if i not in settings.default_module]: #@todo to rework module support - logging.debug("--------------------") - for service_name in sm_dict.get_module_services(sm_dict.get_available_sites()[0],mod_i): #@todo if not - logging.debug(f"{service_name}") - - ts = copy.deepcopy(sm_dict.globals[settings.default_module]['ts']) - while ts and ts.is_active(): # process all services one by one in sorted by dependency - stage += 1 - logging.debug(f"------ Stage {stage} -------") - for serv in ts.get_ready(): - serv_sequence_info = "" if cmd not in settings.dr_processing_cmd else \ - "( " + " ".join(map(lambda site_mode: f"-> {site_mode[1]} on {site_mode[0]}", - sm_dict.get_dr_operation_sequence(serv, cmd, site))) + " )" - logging.debug(f"{serv} {serv_sequence_info}") - ts.done(serv) - logging.debug("Done. ----------------") - + for elem in settings.module_flow: + module, states = list(elem.items())[0] + if cmd in ['standby', 'disable', 'return'] and (states and states == ['active']): + continue + if cmd == 'active' and (states and set(states) == {'standby', 'disable'}): + continue + + ts = copy.deepcopy(sm_dict.globals[module]['ts']) + while ts and ts.is_active(): # process all services one by one in sorted by dependency + stage += 1 + logging.debug(f"------ Stage {stage} -------") + for serv in ts.get_ready(): + if cmd in settings.dr_processing_cmd: + if states: + actual_site = site + if states[0] == "standby" and cmd == "move": + actual_site = settings.sm_conf.get_opposite_site(site) + if states[0] == "active" and cmd == "stop": + actual_site = settings.sm_conf.get_opposite_site(site) + logging.debug(f"{serv}: {states[0]} on {actual_site}") + else: + site_mode_list = sm_dict.get_dr_operation_sequence(serv, cmd, site) + info = " -> ".join(map(lambda site_mode: f"{site_mode[1]} on {site_mode[0]}", site_mode_list)) + logging.debug(f"{serv}: {info}") + else: + logging.debug(f"{serv}: {cmd} on {site}") + ts.done(serv) + logging.debug("------ Done ------") def run(services: list = None, cmd="", site=""): """ Business Logic - implements main flow """ From ef8eb578ee2d726135dbf2e5221fa6bd408fcf23 Mon Sep 17 00:00:00 2001 From: theboringstuff <39027092+theboringstuff@users.noreply.github.com> Date: Mon, 30 Jun 2025 10:17:15 +0500 Subject: [PATCH 2/4] fix comment --- sm-client | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sm-client b/sm-client index f97c1474..10998f8a 100755 --- a/sm-client +++ b/sm-client @@ -56,7 +56,7 @@ args: argparse.Namespace def print_service_order(sm_dict: SMClusterState, cmd, site): """ Show service list ordered by dependency in debug mode""" if cmd == "status" or cmd == "list": - # status is collected in parallel for all services, there is no order + # status and list are collected in parallel for all services, there is no order return stage = 0 From 49f3ce91c3a97a1ed1e74c038d2ccaff96d86277 Mon Sep 17 00:00:00 2001 From: theboringstuff <39027092+theboringstuff@users.noreply.github.com> Date: Mon, 30 Jun 2025 10:54:35 +0500 Subject: [PATCH 3/4] refactoring and comments --- sm-client | 41 ++++++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/sm-client b/sm-client index 10998f8a..6b1e7c72 100755 --- a/sm-client +++ b/sm-client @@ -62,32 +62,43 @@ def print_service_order(sm_dict: SMClusterState, cmd, site): stage = 0 logging.debug("Service order by dependency:") for elem in settings.module_flow: - module, states = list(elem.items())[0] - if cmd in ['standby', 'disable', 'return'] and (states and states == ['active']): + flow, flow_cmds = list(elem.items())[0] + # if particular flow performs only particular cmds, + # which are not relevant for current cmd, then we skip this flow + if cmd in ['standby', 'disable', 'return'] and (flow_cmds and flow_cmds == ['active']): continue - if cmd == 'active' and (states and set(states) == {'standby', 'disable'}): + if cmd == 'active' and (flow_cmds and set(flow_cmds) == {'standby', 'disable'}): continue - ts = copy.deepcopy(sm_dict.globals[module]['ts']) - while ts and ts.is_active(): # process all services one by one in sorted by dependency + # we process all services in this flow in the services order. + # services order is controlled by ts (TopologicalSorter) + ts = copy.deepcopy(sm_dict.globals[flow]['ts']) + while ts and ts.is_active(): stage += 1 logging.debug(f"------ Stage {stage} -------") - for serv in ts.get_ready(): + + # for each svc, print operations which are going to be performed for this svc + stage_services = ts.get_ready() + for svc in stage_services: + # svc operation looks like: "$svc: $cmd on $site", with optional " -> $opposite_cmd on $opposite_site" + # the actual look depends on current cmd (if it is DR cmd or per-site cmd), provided site and current flow_cmds if cmd in settings.dr_processing_cmd: - if states: + if flow_cmds: actual_site = site - if states[0] == "standby" and cmd == "move": + if flow_cmds[0] == "standby" and cmd == "move": actual_site = settings.sm_conf.get_opposite_site(site) - if states[0] == "active" and cmd == "stop": + if flow_cmds[0] == "active" and cmd == "stop": actual_site = settings.sm_conf.get_opposite_site(site) - logging.debug(f"{serv}: {states[0]} on {actual_site}") + logging.debug(f"{svc}: {flow_cmds[0]} on {actual_site}") else: - site_mode_list = sm_dict.get_dr_operation_sequence(serv, cmd, site) - info = " -> ".join(map(lambda site_mode: f"{site_mode[1]} on {site_mode[0]}", site_mode_list)) - logging.debug(f"{serv}: {info}") + site_cmd_seq = sm_dict.get_dr_operation_sequence(svc, cmd, site) + operation = " -> ".join(map(lambda site_cmd: f"{site_cmd[1]} on {site_cmd[0]}", site_cmd_seq)) + logging.debug(f"{svc}: {operation}") else: - logging.debug(f"{serv}: {cmd} on {site}") - ts.done(serv) + logging.debug(f"{svc}: {cmd} on {site}") + + # mark svc as done, so next time TopologicalSorter will give us next stage, if any left for this flow + ts.done(svc) logging.debug("------ Done ------") def run(services: list = None, cmd="", site=""): From b1055e1c4d4e09ea484d2cc0589ea5dabf41f845 Mon Sep 17 00:00:00 2001 From: theboringstuff <39027092+theboringstuff@users.noreply.github.com> Date: Mon, 30 Jun 2025 16:51:32 +0500 Subject: [PATCH 4/4] deduplicate --- sm-client | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sm-client b/sm-client index 6b1e7c72..51747e8e 100755 --- a/sm-client +++ b/sm-client @@ -85,9 +85,9 @@ def print_service_order(sm_dict: SMClusterState, cmd, site): if cmd in settings.dr_processing_cmd: if flow_cmds: actual_site = site - if flow_cmds[0] == "standby" and cmd == "move": - actual_site = settings.sm_conf.get_opposite_site(site) - if flow_cmds[0] == "active" and cmd == "stop": + is_standby_during_move = flow_cmds[0] == "standby" and cmd == "move" + is_active_during_stop = flow_cmds[0] == "active" and cmd == "stop" + if is_standby_during_move or is_active_during_stop: actual_site = settings.sm_conf.get_opposite_site(site) logging.debug(f"{svc}: {flow_cmds[0]} on {actual_site}") else: