Skip to content

Oracle-bm-timeout-fix #456

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jan 17, 2025
Merged
Show file tree
Hide file tree
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
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1!10.6.1
1!10.7.0
1 change: 1 addition & 0 deletions pycloudlib/ec2/instance.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class EC2Instance(BaseInstance):
"""EC2 backed instance."""

_type = "ec2"
ready_timeout = 40 # To keep backwards compatibility (will lower soon)
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
ready_timeout = 40 # To keep backwards compatibility (will lower soon)
ready_timeout = 40 # To keep backwards compatibility (will lower soon)

(this is a joke, don't actually apply this)


def __init__(self, key_pair, client, instance, *, username: Optional[str] = None):
"""Set up instance.
Expand Down
7 changes: 0 additions & 7 deletions pycloudlib/ibm_classic/instance.py
Original file line number Diff line number Diff line change
Expand Up @@ -285,13 +285,6 @@ def is_started():
logger.info("Instance %s started", self.name)
self._instance = self._vs_manager.get_instance(self.id)

def wait(self, **kwargs):
"""Wait for instance to be up and cloud-init to be complete."""
logger.info("Waiting for instance %s to be ready", self.name)
self._wait_for_instance_start(**kwargs)
self._wait_for_execute(timeout=180)
self._wait_for_cloudinit()

def wait_for_restart(self, old_boot_id):
"""Wait for instance to be restarted and cloud-init to be complete.

Expand Down
26 changes: 19 additions & 7 deletions pycloudlib/instance.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class BaseInstance(ABC):
"""Base instance object."""

_type = "base"
ready_timeout = 10 # Time to wait for instance to be ready after provisioning (in minutes)

def __init__(self, key_pair, username: Optional[str] = None):
"""Set up instance."""
Expand Down Expand Up @@ -160,10 +161,23 @@ def _wait_for_instance_start(self, **kwargs):
detecting when an instance has started through their API.
"""

def wait(self, **kwargs):
"""Wait for instance to be up and cloud-init to be complete."""
def wait(
self,
ready_timeout: Optional[int] = None,
**kwargs,
):
"""
Wait for instance to be up and cloud-init to be complete.

Args:
ready_timeout (int): maximum time to wait for the instance to be ready for ssh after
instance provisioning is complete

Raises:
PycloudlibTimeoutError: If the instance is not ready after the timeout
"""
self._wait_for_instance_start(**kwargs)
self._wait_for_execute()
self._wait_for_execute(timeout=ready_timeout)
self._wait_for_cloudinit()

def wait_for_restart(self, old_boot_id):
Expand Down Expand Up @@ -478,7 +492,7 @@ def _tmpfile(self):
self._tmp_count += 1
return path

def _wait_for_execute(self, old_boot_id=None, timeout: int = 40):
def _wait_for_execute(self, old_boot_id=None, timeout: Optional[int] = None):
"""
Wait until we can execute a command in the instance.

Expand All @@ -492,9 +506,7 @@ def _wait_for_execute(self, old_boot_id=None, timeout: int = 40):
"""
self._log.info("_wait_for_execute to complete")

# Wait 40 minutes before failing. AWS EC2 metal instances can take
# over 20 minutes to start or restart, so we shouldn't lower
# this timeout
timeout = timeout or self.ready_timeout
start = time.time()
end = start + timeout * 60
while time.time() < end:
Expand Down
6 changes: 4 additions & 2 deletions pycloudlib/oci/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

from oci.retry import DEFAULT_RETRY_STRATEGY # pylint: disable=E0611,E0401

from pycloudlib.errors import PycloudlibError
from pycloudlib.errors import PycloudlibError, PycloudlibTimeoutError

if TYPE_CHECKING:
import oci
Expand All @@ -33,6 +33,8 @@ def wait_till_ready(
func_kwargs: Dictionary with keyword arguments to pass to the function
Returns:
The updated version of the current_data
Raises:
PycloudlibTimeoutError: If the desired state is not reached in time
"""
if func_kwargs is None:
func_kwargs = {}
Expand All @@ -42,7 +44,7 @@ def wait_till_ready(
if current_data.lifecycle_state == desired_state:
return current_data
time.sleep(1)
raise PycloudlibError(
raise PycloudlibTimeoutError(
"Expected {} state, but found {} after waiting {} seconds. "
"Check OCI console for more details".format(
desired_state, current_data.lifecycle_state, sleep_seconds
Expand Down
8 changes: 4 additions & 4 deletions tests/unit_tests/test_instance.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,9 @@ def test_wait_execute_failure(
):
"""Test wait calls when execute command fails."""
instance = concrete_instance_cls(key_pair=None)
m_time.side_effect = [1, 1, 2, 40 * 60, 40 * 60 + 1]
m_time.side_effect = [1, 1, 2, 10 * 60, 10 * 60 + 1]
m_execute.side_effect = execute_effect
expected_msg = "Instance can't be reached after 40 minutes. Failed to obtain new boot id"
expected_msg = "Instance can't be reached after 10 minutes. Failed to obtain new boot id"
expected_call_args = [mock.call("cat /proc/sys/kernel/random/boot_id", no_log=True)] * 2

with pytest.raises(PycloudlibTimeoutError) as excinfo:
Expand Down Expand Up @@ -190,8 +190,8 @@ def test_boot_id_failure(
"""Test wait calls when execute command fails."""
m_execute.side_effect = execute_side_effect
instance = concrete_instance_cls(key_pair=None)
m_time.side_effect = [1, 1, 2, 40 * 60, 40 * 60 + 1]
expected_msg = "Instance can't be reached after 40 minutes. Failed to obtain new boot id"
m_time.side_effect = [1, 1, 2, 10 * 60, 10 * 60 + 1]
expected_msg = "Instance can't be reached after 10 minutes. Failed to obtain new boot id"
expected_call_args = [mock.call("cat /proc/sys/kernel/random/boot_id", no_log=True)] * 2

with pytest.raises(PycloudlibTimeoutError) as excinfo:
Expand Down
Loading