Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions ocp_resources/node_network_configuration_policy.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from ocp_resources.node_network_state import NodeNetworkState
from ocp_resources.resource import Resource, ResourceEditor
from timeout_sampler import TimeoutExpiredError, TimeoutSampler, TimeoutWatch, retry
from typing import Any

IPV4_STR = "ipv4"
IPV6_STR = "ipv6"
Expand Down Expand Up @@ -323,17 +324,10 @@ def _absent_interface(self):
if self.ports:
self.add_ports()

# The current time-stamp of the NNCP's available status will change after the NNCP is updated, therefore
# it must be fetched and stored before the update, and compared with the new time-stamp after.
initial_success_status_time = self._get_last_successful_transition_time()
ResourceEditor(
patches={self: {"spec": {"desiredState": {"interfaces": self.desired_state["interfaces"]}}}}
).update()

# If the NNCP failed on setup, then its tear-down AVAIALBLE status will necessarily be the first.
if initial_success_status_time:
self._wait_for_nncp_status_update(initial_transition_time=initial_success_status_time)

def _get_last_successful_transition_time(self) -> str | None:
for condition in self.instance.status.conditions:
if (
Expand All @@ -360,6 +354,12 @@ def _wait_for_nncp_status_update(self, initial_transition_time: str) -> bool:
return True
return False

def update(self, resource_dict: dict[str, Any]) -> None:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIK, the call to update() from _absent_interface() goes through here.
If I am indeed correct, then I think that your PR, which presents a more robust solution because it covers all the cases of calling nncp.update() (and not only the specific case of removing an interface on teardown) should include removal of the time-stamp verification in _absent_interface.
WDYT?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The update call in the _absent_interfaces method currently uses the update method of the ResourceEditor object instead of the NNCP object. I can replace it with the new update method of NNCP and remove the related logic accordingly.
Maybe in a follow up PR?

Copy link
Contributor

@yossisegev yossisegev Mar 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's what I initially thought as well, but then I followed the flow and found that although ResourceEditor does not inherit from Resource, the update() flow does go through update() of Resource class.
IIRC, if you visually trace the code, eventually you can trace the code that leads to that (it's quite cumbersome).
Anyway, to make sure I ran a little check now:
I added this print to Resource.update():

self.logger.info("\n\n******************* going via Resource.update() *******************\n\n")

Then I ran a test that involves NNCP creation and teardown, and indeed found this print in the teardown flow:

-------------------------------------------------------------------------------------------------------------------------- TEARDOWN --------------------------------------------------------------------------------------------------------------------------
2025-03-27T15:49:55.436437 timeout_sampler INFO Elapsed time: 0.00023365020751953125 [0:00:00.000234]
2025-03-27T15:49:55.436839 timeout_sampler INFO Waiting for 60 seconds [0:01:00], retry every 1 seconds. (Function: tests.network.utils.<locals>.lambda: nncp.status)
2025-03-27T15:49:55.646993 timeout_sampler INFO Elapsed time: 0.0002613067626953125 [0:00:00.000261]
2025-03-27T15:49:55.647681 ocp_resources.resource INFO Trying to get client via new_client_from_config
2025-03-27T15:49:55.671476 ocp_resources.resource INFO kind: NodeNetworkState api version: nmstate.io/v1beta1
2025-03-27T15:49:56.875371 ocp_resources.resource INFO ResourceEdits: Updating data for resource NodeNetworkConfigurationPolicy restart-nmstate-net-ys-419-lrlqb-worker-0-qlz29
2025-03-27T15:49:56.875511 ocp_resources NodeNetworkConfigurationPolicy INFO 

******************* going via Resource.update() *******************


2025-03-27T15:49:56.875573 ocp_resources NodeNetworkConfigurationPolicy INFO Update NodeNetworkConfigurationPolicy restart-nmstate-net-ys-419-lrlqb-worker-0-qlz29:
{'spec': {'desiredState': {'interfaces': [{'name': 'br-nmstate', 'type': 'linux-bridge', 'state': 'absent', 'bridge': {'options': {'stp': {'enabled': False}}, 'port': [{'name': 'enp5s0'}]}, 'ipv4': {'enabled': False, 'dhcp': False, 'auto-dns': True}, 'ipv6': {'enabled': False, 'dhcp': False, 'auto-dns': True, 'autoconf': False}}, {'name': 'enp5s0', 'type': 'ethernet', 'state': 'up', 'ipv4': {'dhcp': False, 'enabled': False}, 'ipv6': {'autoconf': False, 'dhcp': False, 'enabled': False}}]}}, 'metadata': {'name': 'restart-nmstate-net-ys-419-lrlqb-worker-0-qlz29'}}
2025-03-27T15:49:57.080747 timeout_sampler INFO Waiting for 60 seconds [0:01:00], retry every 5 seconds. (Function: ocp_resources.node_network_configuration_policy._wait_for_nncp_status_update Args: (<utilities.network.LinuxBridgeNodeNetworkConfigurationPolicy object at 0x7f1ce7233fb0>,) Kwargs: {'initial_transition_time': '2025-03-27T13:49:52Z'})
2025-03-27T15:50:02.507453 timeout_sampler INFO Elapsed time: 5.198873996734619 [0:00:05.198874]

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @sbahar619 .
Please resolve this comment (the author can do that, the reviewer cannot).

initial_success_status_time = self._get_last_successful_transition_time()
super().update(resource_dict=resource_dict)
if resource_dict.get("spec") and initial_success_status_time:
self._wait_for_nncp_status_update(initial_transition_time=initial_success_status_time)

@property
def status(self):
for condition in self.instance.status.conditions:
Expand Down