Skip to content

Commit 04be961

Browse files
scripts: add an abstraction for the args that depend on each other and validate them in one place
1 parent 2fc24e1 commit 04be961

File tree

4 files changed

+113
-82
lines changed

4 files changed

+113
-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: 89 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,
@@ -511,45 +482,103 @@ def restart_pod(
511482
sys.exit(1)
512483

513484

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

531-
if not cluster_list:
556+
if not namespace_and_instruction_args.cluster_list:
532557
print_colored(
533558
"cluster-prefix/cluster-list not provided. Assuming all nodes are on the current cluster",
534559
Colors.RED,
535560
)
536-
else:
537-
assert len(cluster_list) == len(
538-
namespace_list
539-
), f"cluster_list must have the same number of values as namespace_list. cluster_list: {cluster_list}, namespace_list: {namespace_list}"
540561

541562
# Store original and updated configs for all nodes
542563
configs = []
543564

544565
# Process each node's configuration
545-
for index, namespace in enumerate(namespace_list):
546-
cluster = cluster_list[index] if cluster_list else None
566+
for index in range(namespace_and_instruction_args.size()):
567+
namespace = namespace_and_instruction_args.get_namespace(index)
568+
cluster = namespace_and_instruction_args.get_cluster(index)
569+
547570
print_colored(
548571
f"\nProcessing node for namespace {namespace} (cluster: {cluster if cluster else 'current cluster'})..."
549572
)
550573

551574
# Get current config and normalize it (e.g. " vs ') to ensure not showing bogus diffs.
552-
original_config = normalize_config(get_configmap(namespace, cluster, service))
575+
original_config = normalize_config(
576+
get_configmap(
577+
namespace,
578+
cluster,
579+
service,
580+
)
581+
)
553582

554583
# Update config
555584
updated_config = update_config_values(original_config, config_overrides)
@@ -568,19 +597,22 @@ def update_config_and_restart_nodes(
568597
print_colored("\nApplying configurations...")
569598
for index, config in enumerate(configs):
570599
print(f"Applying config {index}...")
571-
apply_configmap(
572-
config["updated"],
573-
namespace_list[index],
574-
index,
575-
cluster_list[index] if cluster_list else None,
576-
)
600+
# apply_configmap(
601+
# config["updated"],
602+
# namespace_and_instruction_args.get_namespace(index),
603+
# index,
604+
# namespace_and_instruction_args.get_cluster(index),
605+
# )
577606

578607
if restart_strategy != RestartStrategy.NO_RESTART:
579608
for index, config in enumerate(configs):
580-
restart_pod(
581-
namespace_list[index], service, index, cluster_list[index] if cluster_list else None
582-
)
583-
instructions = post_restart_instructions[index] if post_restart_instructions else None
609+
# restart_pod(
610+
# namespace_and_instruction_args.get_namespace(index),
611+
# service,
612+
# index,
613+
# namespace_and_instruction_args.get_cluster(index),
614+
# )
615+
instructions = namespace_and_instruction_args.get_instruction(index)
584616
print_colored(f"Restarted pod.\n{instructions if instructions else ''} ", Colors.YELLOW)
585617
if restart_strategy == RestartStrategy.ONE_BY_ONE:
586618
# Don't ask in the case of the last job.

0 commit comments

Comments
 (0)