Skip to content

Commit

Permalink
wait on systemd if wait=True, otherwise error to stderr
Browse files Browse the repository at this point in the history
  • Loading branch information
TheRealFalcon committed Dec 12, 2023
1 parent a55996b commit f398fb2
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 16 deletions.
26 changes: 16 additions & 10 deletions cloudinit/cmd/status.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ def handle_status_args(name, args) -> int:
"""Handle calls to 'cloud-init status' as a subcommand."""
# Read configured paths
paths = read_cfg_paths()
details = get_status_details(paths)
details = get_status_details(paths, args.wait)
if args.wait:
while details.status in (
UXAppStatus.NOT_RUN,
Expand All @@ -148,7 +148,7 @@ def handle_status_args(name, args) -> int:
if args.format == "tabular":
sys.stdout.write(".")
sys.stdout.flush()
details = get_status_details(paths)
details = get_status_details(paths, args.wait)
sleep(0.25)
details_dict: Dict[str, Union[None, str, List[str], Dict[str, Any]]] = {
"datasource": details.datasource,
Expand Down Expand Up @@ -329,7 +329,7 @@ def _get_error_or_running_from_systemd() -> Optional[UXAppStatus]:


def _get_error_or_running_from_systemd_with_retry(
existing_status, max_wait=5
existing_status: UXAppStatus, *, wait: bool
) -> Optional[UXAppStatus]:
"""Get systemd status and retry if dbus isn't ready.
Expand All @@ -338,8 +338,7 @@ def _get_error_or_running_from_systemd_with_retry(
then we should retry on systemd status so we don't incorrectly report
error state while cloud-init is still running.
"""
start_time = time.time()
while time.time() - start_time < max_wait:
while True:
try:
return _get_error_or_running_from_systemd()
except subp.ProcessExecutionError:
Expand All @@ -348,16 +347,21 @@ def _get_error_or_running_from_systemd_with_retry(
UXAppStatus.RUNNING,
):
return None
sleep(0.25)
if wait:
sleep(0.25)
else:
break
print(
f"Failed to get status from systemd after {max_wait} seconds. "
"Cloud-init may still be running.",
"Failed to get status from systemd. "
"Cloud-init status may be inaccurate.",
file=sys.stderr,
)
return None


def get_status_details(paths: Optional[Paths] = None) -> StatusDetails:
def get_status_details(
paths: Optional[Paths] = None, wait: bool = False
) -> StatusDetails:
"""Return a dict with status, details and errors.
@param paths: An initialized cloudinit.helpers.paths object.
Expand Down Expand Up @@ -428,7 +432,9 @@ def get_status_details(paths: Optional[Paths] = None) -> StatusDetails:
UXAppStatus.NOT_RUN,
UXAppStatus.DISABLED,
):
systemd_status = _get_error_or_running_from_systemd_with_retry(status)
systemd_status = _get_error_or_running_from_systemd_with_retry(
status, wait
)
if systemd_status:
status = systemd_status

Expand Down
12 changes: 6 additions & 6 deletions tests/unittests/cmd/test_status.py
Original file line number Diff line number Diff line change
Expand Up @@ -960,7 +960,7 @@ def test_exception_while_running(self, mocker, capsys):
)
assert (
_get_error_or_running_from_systemd_with_retry(
UXAppStatus.RUNNING, max_wait=1000
UXAppStatus.RUNNING, wait=True
)
is None
)
Expand Down Expand Up @@ -988,14 +988,14 @@ def test_retry(self, mocker, capsys):
)
assert (
_get_error_or_running_from_systemd_with_retry(
UXAppStatus.ERROR, max_wait=1000
UXAppStatus.ERROR, wait=True
)
is UXAppStatus.RUNNING
)
assert 3 == m_subp.call_count
assert "Failed to get status" not in capsys.readouterr().err

def test_retry_timeout(self, mocker, capsys):
def test_retry_no_wait(self, mocker, capsys):
m_subp = mocker.patch(
f"{M_PATH}subp.subp",
side_effect=subp.ProcessExecutionError(
Expand All @@ -1006,12 +1006,12 @@ def test_retry_timeout(self, mocker, capsys):
mocker.patch("time.time", side_effect=[1, 2, 50])
assert (
_get_error_or_running_from_systemd_with_retry(
UXAppStatus.ERROR, max_wait=5
UXAppStatus.ERROR, wait=False
)
is None
)
assert 1 == m_subp.call_count
assert (
"Failed to get status from systemd after 5 seconds. "
"Cloud-init may still be running."
"Failed to get status from systemd. "
"Cloud-init status may be inaccurate."
) in capsys.readouterr().err

0 comments on commit f398fb2

Please sign in to comment.