Skip to content

Commit e0cb446

Browse files
committed
Prepare shared pods for multiple NAD attachments
Render secondary pod network annotations from a NAD list and scope pre_provision pod sharing to the regular or UDN test family. Resolve UDN secondary addresses by the test's exact NAD so a shared pod does not select an unrelated secondary interface. Preserve the existing regular NAD behavior. Signed-off-by: Venkat Kunaparaju <vkunaparaju@nvidia.com>
1 parent 0756089 commit e0cb446

2 files changed

Lines changed: 32 additions & 24 deletions

File tree

manifests/pod-secondary-network.yaml.j2

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ metadata:
88
tft-pod-name: {{ pod_name }}
99
tft-network: secondary
1010
annotations:
11-
k8s.v1.cni.cncf.io/networks: {{ secondary_network_nad }}
11+
k8s.v1.cni.cncf.io/networks: {{ secondary_network_nads }}
1212
spec:
1313
nodeSelector:
1414
kubernetes.io/hostname: {{ node_name }}

task.py

Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,16 @@ def _get_template_args_test_image(self) -> str:
404404
"""Get the test image, auto-selecting RDMA image for ib-* test types."""
405405
return tftbase.get_tft_test_image_for_type(self.ts.connection.test_type)
406406

407+
def _shares_pre_provisioned_secondary_pod(self) -> bool:
408+
tft = self.ts.cfg_descr.get_tft()
409+
if not tft.pre_provision:
410+
return False
411+
is_udn = self.ts.test_case_id.is_udn
412+
return any(
413+
tc.info.uses_secondary_network_pod and tc.is_udn == is_udn
414+
for tc in tft.test_cases
415+
)
416+
407417
def _get_effective_secondary_network_nad(self) -> str:
408418
if self.ts.test_case_id.is_udn_localnet:
409419
return f"{self.get_namespace()}/tft-localnet"
@@ -419,9 +429,20 @@ def _get_effective_secondary_network_nad(self) -> str:
419429
or self.ts.connection.effective_secondary_network_nad
420430
)
421431

432+
def _get_pod_secondary_network_nads(self) -> tuple[str, ...]:
433+
if (
434+
self._get_node_secondary_network_nad()
435+
or self.ts.connection.secondary_network_nad
436+
or self.ts.test_case_id.info.uses_secondary_network_pod
437+
or self._shares_pre_provisioned_secondary_pod()
438+
):
439+
return (self._get_effective_secondary_network_nad(),)
440+
return ()
441+
422442
def get_template_args(self) -> dict[str, str | list[str] | bool]:
423443
resource_name = self.get_resource_name()
424444
conn = self.ts.connection
445+
pod_secondary_network_nads = self._get_pod_secondary_network_nads()
425446
has_resources = any(
426447
v is not None
427448
for v in (
@@ -444,6 +465,7 @@ def get_template_args(self) -> dict[str, str | list[str] | bool]:
444465
"capabilities_pod": _j(self._get_template_args_capabilities_pod()),
445466
"port": self._get_template_args_port(),
446467
"secondary_network_nad": _j(self._get_effective_secondary_network_nad()),
468+
"secondary_network_nads": _j(",".join(pod_secondary_network_nads)),
447469
"use_secondary_network": (
448470
bool(self._get_node_secondary_network_nad())
449471
or bool(self.ts.connection.secondary_network_nad)
@@ -636,6 +658,8 @@ def get_pod_ip(self) -> str:
636658
)
637659
pod_ip = y["status"]["podIP"]
638660
elif self.uses_secondary_ip:
661+
if self.ts.test_case_id.is_udn:
662+
pod_ip = None
639663
network_status_str = y["metadata"]["annotations"][
640664
"k8s.v1.cni.cncf.io/network-status"
641665
]
@@ -662,30 +686,18 @@ def get_primary_ip(self) -> str:
662686
return pod_ip
663687

664688
def get_secondary_ip(self) -> str:
689+
if self.ts.test_case_id.is_udn:
690+
ip_address = self.get_pod_ip()
691+
logger.info(f"Secondary IP: {ip_address}")
692+
return ip_address
693+
665694
jsonpath = "{.metadata.annotations.k8s\\.ovn\\.org\\/pod-networks}"
666695
r = self.run_oc(
667696
f"get pod {self.pod_name} -o jsonpath='{jsonpath}'", die_on_error=True
668697
)
669698

670699
y = yaml.safe_load(r.out)
671700

672-
if self.ts.test_case_id.is_udn:
673-
if not isinstance(y, dict):
674-
raise RuntimeError(
675-
f"k8s.ovn.org/pod-networks annotation for pod {self.pod_name} "
676-
f"is not a valid dict (got {type(y).__name__})"
677-
)
678-
for net_info in y.values():
679-
if net_info.get("role") == "secondary":
680-
ip_address_with_cidr = typing.cast(str, net_info["ip_address"])
681-
ip_address = ip_address_with_cidr.split("/")[0]
682-
logger.info(f"Secondary IP: {ip_address}")
683-
return ip_address
684-
raise RuntimeError(
685-
f"Could not find UDN secondary IP for pod {self.pod_name} "
686-
f"in k8s.ovn.org/pod-networks annotation"
687-
)
688-
689701
nad = self._get_effective_secondary_network_nad()
690702
ip_address_with_cidr = typing.cast(str, y[nad]["ip_address"])
691703
ip_address = ip_address_with_cidr.split("/")[0] if ip_address_with_cidr else ""
@@ -1127,9 +1139,7 @@ def __init__(self, ts: TestSettings):
11271139
in_file_template = ""
11281140
pod_name = EXTERNAL_PERF_SERVER
11291141
elif pod_type == PodType.SECONDARY or (
1130-
pod_type == PodType.NORMAL
1131-
and ts.cfg_descr.get_tft().pre_provision
1132-
and ts.cfg_descr.get_tft().uses_secondary_network_pod
1142+
pod_type == PodType.NORMAL and self._shares_pre_provisioned_secondary_pod()
11331143
):
11341144
in_file_template = "pod-secondary-network.yaml.j2"
11351145
pod_name = f"normal-pod-secondary-server-{port}"
@@ -1444,9 +1454,7 @@ def __init__(self, ts: TestSettings, server: ServerTask):
14441454
port = server.port
14451455

14461456
if pod_type == PodType.SECONDARY or (
1447-
pod_type == PodType.NORMAL
1448-
and ts.cfg_descr.get_tft().pre_provision
1449-
and ts.cfg_descr.get_tft().uses_secondary_network_pod
1457+
pod_type == PodType.NORMAL and self._shares_pre_provisioned_secondary_pod()
14501458
):
14511459
in_file_template = "pod-secondary-network.yaml.j2"
14521460
pod_name = f"normal-pod-secondary-{node_location}-client"

0 commit comments

Comments
 (0)