Skip to content

Commit 34281ad

Browse files
scripts: add an abstraction for the args that depend on each other and validate them in one place
1 parent 670369f commit 34281ad

File tree

4 files changed

+116
-82
lines changed

4 files changed

+116
-82
lines changed

scripts/prod/restart_all_nodes_together.py

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,12 @@
77
import urllib.request
88
from update_config_and_restart_nodes_lib import (
99
ApolloArgsParserBuilder,
10+
NamespaceAndInstructionArgs,
1011
RestartStrategy,
1112
Service,
1213
get_configmap,
13-
get_context_list_from_args,
1414
get_current_block_number,
1515
get_logs_explorer_url,
16-
get_namespace_list_from_args,
1716
parse_config_from_yaml,
1817
print_colored,
1918
update_config_and_restart_nodes,
@@ -107,12 +106,8 @@ def main():
107106
"consensus_manager_config.immediate_active_height": next_block_number,
108107
}
109108

110-
namespace_list = get_namespace_list_from_args(args)
111-
context_list = get_context_list_from_args(args)
112-
if context_list is not None:
113-
assert len(namespace_list) == len(
114-
context_list
115-
), "namespace_list and context_list must have the same length"
109+
namespace_list = NamespaceAndInstructionArgs.get_namespace_list_from_args(args)
110+
context_list = NamespaceAndInstructionArgs.get_context_list_from_args(args)
116111

117112
# Generate logs explorer URLs if needed
118113
post_restart_instructions = []
@@ -131,11 +126,13 @@ def main():
131126

132127
update_config_and_restart_nodes(
133128
config_overrides,
134-
namespace_list,
129+
NamespaceAndInstructionArgs(
130+
namespace_list,
131+
context_list,
132+
post_restart_instructions,
133+
),
135134
Service.Core,
136-
context_list,
137135
RestartStrategy.ALL_AT_ONCE,
138-
post_restart_instructions,
139136
)
140137

141138

scripts/prod/set_node_revert_mode.py

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,11 @@
66
import urllib.parse
77
from update_config_and_restart_nodes_lib import (
88
ApolloArgsParserBuilder,
9+
NamespaceAndInstructionArgs,
910
RestartStrategy,
1011
Service,
11-
get_context_list_from_args,
1212
get_current_block_number,
1313
get_logs_explorer_url,
14-
get_namespace_list_from_args,
1514
print_colored,
1615
print_error,
1716
update_config_and_restart_nodes,
@@ -46,20 +45,22 @@ def set_revert_mode(
4645
}
4746

4847
post_restart_instructions = []
49-
for namespace, context in zip(namespace_list, context_list):
48+
for namespace, context in zip(namespace_list, context_list or [None] * len(namespace_list)):
5049
url = get_logs_explorer_url_for_revert(namespace, revert_up_to_block, project_name)
5150

5251
post_restart_instructions.append(
5352
f"Please check logs and verify that revert has completed (both in the batcher and for sync). Logs URL: {url}"
5453
)
55-
54+
namespace_and_instruction_args = NamespaceAndInstructionArgs(
55+
namespace_list,
56+
context_list,
57+
post_restart_instructions,
58+
)
5659
update_config_and_restart_nodes(
5760
config_overrides,
58-
namespace_list,
61+
namespace_and_instruction_args,
5962
Service.Core,
60-
context_list,
6163
restart_strategy,
62-
post_restart_instructions,
6364
)
6465

6566

@@ -155,8 +156,8 @@ def main():
155156
print_error("Error: --revert-up-to-block (-b) cannot be set when disabling revert.")
156157
sys.exit(1)
157158

158-
namespace_list = get_namespace_list_from_args(args)
159-
context_list = get_context_list_from_args(args)
159+
namespace_list = NamespaceAndInstructionArgs.get_namespace_list_from_args(args)
160+
context_list = NamespaceAndInstructionArgs.get_context_list_from_args(args)
160161

161162
should_disable_revert = not args.revert_only
162163
if should_revert:

scripts/prod/update_config_and_restart_nodes.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,8 @@
88
from update_config_and_restart_nodes_lib import (
99
ApolloArgsParserBuilder,
1010
Colors,
11+
NamespaceAndInstructionArgs,
1112
Service,
12-
get_context_list_from_args,
13-
get_namespace_list_from_args,
1413
print_colored,
1514
print_error,
1615
update_config_and_restart_nodes,
@@ -153,11 +152,13 @@ def main():
153152

154153
update_config_and_restart_nodes(
155154
config_overrides,
156-
get_namespace_list_from_args(args),
155+
NamespaceAndInstructionArgs(
156+
NamespaceAndInstructionArgs.get_namespace_list_from_args(args),
157+
NamespaceAndInstructionArgs.get_context_list_from_args(args),
158+
None,
159+
),
157160
args.service,
158-
get_context_list_from_args(args),
159161
args.restart_strategy,
160-
None,
161162
)
162163

163164

scripts/prod/update_config_and_restart_nodes_lib.py

Lines changed: 92 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -211,35 +211,6 @@ def validate_arguments(args: argparse.Namespace) -> None:
211211
sys.exit(1)
212212

213213

214-
def get_namespace_list_from_args(
215-
args: argparse.Namespace,
216-
) -> list[str]:
217-
"""Get a list of namespaces based on the arguments"""
218-
if args.namespace_list:
219-
return args.namespace_list
220-
221-
return [
222-
f"{args.namespace_prefix}-{i}"
223-
for i in range(args.start_index, args.start_index + args.num_nodes)
224-
]
225-
226-
227-
def get_context_list_from_args(
228-
args: argparse.Namespace,
229-
) -> list[str]:
230-
"""Get a list of contexts based on the arguments"""
231-
if args.cluster_list:
232-
return args.cluster_list
233-
234-
if args.cluster_prefix is None:
235-
return None
236-
237-
return [
238-
f"{args.cluster_prefix}-{i}"
239-
for i in range(args.start_index, args.start_index + args.num_nodes)
240-
]
241-
242-
243214
def get_logs_explorer_url(
244215
query: str,
245216
project_name: Optional[str] = None,
@@ -510,45 +481,106 @@ def restart_pod(
510481
sys.exit(1)
511482

512483

484+
class NamespaceAndInstructionArgs:
485+
def __init__(
486+
self,
487+
namespace_list: list[str],
488+
cluster_list: Optional[list[str]],
489+
instruction_list: Optional[list[str]] = None,
490+
):
491+
assert (
492+
namespace_list is not None and len(namespace_list) > 0
493+
), "Namespace list cannot be None or empty."
494+
self.namespace_list = namespace_list
495+
assert cluster_list is None or len(cluster_list) == len(
496+
namespace_list
497+
), "cluster_list must have the same length as namespace_list"
498+
self.cluster_list = cluster_list
499+
assert instruction_list is None or len(namespace_list) == len(
500+
instruction_list
501+
), "instruction_list must have the same length as namespace_list"
502+
self.instruction_list = instruction_list
503+
504+
def size(self) -> int:
505+
return len(self.namespace_list)
506+
507+
def get_namespace(self, index: int) -> str:
508+
return self.namespace_list[index]
509+
510+
def get_cluster(self, index: int) -> Optional[str]:
511+
return self.cluster_list[index] if self.cluster_list else None
512+
513+
def get_instruction(self, index: int) -> Optional[str]:
514+
return self.instruction_list[index] if self.instruction_list else None
515+
516+
@staticmethod
517+
def get_namespace_list_from_args(
518+
args: argparse.Namespace,
519+
) -> list[str]:
520+
"""Get a list of namespaces based on the arguments"""
521+
if args.namespace_list:
522+
return args.namespace_list
523+
524+
return [
525+
f"{args.namespace_prefix}-{i}"
526+
for i in range(args.start_index, args.start_index + args.num_nodes)
527+
]
528+
529+
@staticmethod
530+
def get_context_list_from_args(
531+
args: argparse.Namespace,
532+
) -> list[str]:
533+
"""Get a list of contexts based on the arguments"""
534+
if args.cluster_list:
535+
return args.cluster_list
536+
537+
if args.cluster_prefix is None:
538+
return None
539+
540+
return [
541+
f"{args.cluster_prefix}-{i}"
542+
for i in range(args.start_index, args.start_index + args.num_nodes)
543+
]
544+
545+
513546
def update_config_and_restart_nodes(
514547
config_overrides: dict[str, Any],
515-
namespace_list: list[str],
548+
namespace_and_instruction_args: NamespaceAndInstructionArgs,
516549
service: Service,
517-
cluster_list: Optional[list[str]],
518550
restart_strategy: RestartStrategy,
519-
# TODO(guy.f): Add more abstraction to restart strategy so that the instructions are abstracted as part of it.
520-
post_restart_instructions: Optional[list[str]] = None,
521551
) -> None:
522552
assert config_overrides is not None, "config_overrides must be provided"
523-
assert namespace_list is not None and len(namespace_list) > 0, "namespaces must be provided"
524-
525-
if post_restart_instructions is not None:
526-
assert len(post_restart_instructions) == len(
527-
namespace_list
528-
), f"post_restart_instructions must have the same length as namespace_list. logs_explorer_urls: {len(post_restart_instructions)}, namespace_list: {len(namespace_list)}"
553+
assert (
554+
namespace_and_instruction_args.namespace_list is not None
555+
and len(namespace_and_instruction_args.namespace_list) > 0
556+
), "namespaces must be provided"
529557

530-
if not cluster_list:
558+
if not namespace_and_instruction_args.cluster_list:
531559
print_colored(
532560
"cluster-prefix/cluster-list not provided. Assuming all nodes are on the current cluster",
533561
Colors.RED,
534562
)
535-
else:
536-
assert len(cluster_list) == len(
537-
namespace_list
538-
), f"cluster_list must have the same number of values as namespace_list. cluster_list: {cluster_list}, namespace_list: {namespace_list}"
539563

540564
# Store original and updated configs for all nodes
541565
configs = []
542566

543567
# Process each node's configuration
544-
for index, namespace in enumerate(namespace_list):
545-
cluster = cluster_list[index] if cluster_list else None
568+
for index in range(namespace_and_instruction_args.size()):
569+
namespace = namespace_and_instruction_args.get_namespace(index)
570+
cluster = namespace_and_instruction_args.get_cluster(index)
571+
546572
print_colored(
547573
f"\nProcessing node for namespace {namespace} (cluster: {cluster if cluster else 'current cluster'})..."
548574
)
549575

550576
# Get current config and normalize it (e.g. " vs ') to ensure not showing bogus diffs.
551-
original_config = normalize_config(get_configmap(namespace, cluster, service))
577+
original_config = normalize_config(
578+
get_configmap(
579+
namespace,
580+
cluster,
581+
service,
582+
)
583+
)
552584

553585
# Update config
554586
updated_config = update_config_values(original_config, config_overrides)
@@ -567,19 +599,22 @@ def update_config_and_restart_nodes(
567599
print_colored("\nApplying configurations...")
568600
for index, config in enumerate(configs):
569601
print(f"Applying config {index}...")
570-
apply_configmap(
571-
config["updated"],
572-
namespace_list[index],
573-
index,
574-
cluster_list[index] if cluster_list else None,
575-
)
602+
# apply_configmap(
603+
# config["updated"],
604+
# namespace_and_instruction_args.get_namespace(index),
605+
# index,
606+
# namespace_and_instruction_args.get_cluster(index),
607+
# )
576608

577609
if restart_strategy != RestartStrategy.NO_RESTART:
578610
for index, config in enumerate(configs):
579-
restart_pod(
580-
namespace_list[index], service, index, cluster_list[index] if cluster_list else None
581-
)
582-
instructions = post_restart_instructions[index] if post_restart_instructions else None
611+
# restart_pod(
612+
# namespace_and_instruction_args.get_namespace(index),
613+
# service,
614+
# index,
615+
# namespace_and_instruction_args.get_cluster(index),
616+
# )
617+
instructions = namespace_and_instruction_args.get_instruction(index)
583618
print_colored(f"Restarted pod.\n{instructions if instructions else ''} ", Colors.YELLOW)
584619
if restart_strategy == RestartStrategy.ONE_BY_ONE:
585620
# Don't ask in the case of the last job.

0 commit comments

Comments
 (0)