Skip to content
Open
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
32 changes: 32 additions & 0 deletions docs/api.clients.servers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,38 @@ ServersClient
==================


Waiting for a graceful shutdown
-------------------------------

The shutdown action sends an ACPI request to the guest operating system.
:meth:`~hcloud.actions.client.BoundAction.wait_until_finished` waits for that
request to be sent, rather than for the guest to stop. Before changing the
server type or performing another operation that requires a stopped server,
reload its status until it is :attr:`~hcloud.servers.domain.Server.STATUS_OFF`.

For an existing :class:`~hcloud.servers.client.BoundServer` named ``server``,
the following example checks the status at most 60 times. It raises a timeout
instead of continuing if the guest does not shut down::

from time import sleep

from hcloud.servers.domain import Server

server.shutdown().wait_until_finished()
for attempt in range(60):
server.reload()
if server.status == Server.STATUS_OFF:
break
if attempt < 59:
sleep(1)
else:
raise TimeoutError("Server did not shut down after 60 status checks")

A guest may ignore the request, for example if it does not handle ACPI.
Choose the polling interval and limit to suit the workload. A forced
:meth:`~hcloud.servers.client.BoundServer.power_off` cuts power without a clean
guest shutdown; this example does not fall back to it automatically.

.. autoclass:: hcloud.servers.client.ServersClient
:members:

Expand Down
20 changes: 20 additions & 0 deletions hcloud/servers/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,10 @@ def power_on(self) -> BoundAction:
def reboot(self) -> BoundAction:
"""Reboots a server gracefully by sending an ACPI request.

The returned action finishes when the request has been sent. Waiting
for it does not guarantee that the guest operating system has rebooted
or that its services are ready. The guest may ignore ACPI requests.

Comment on lines +282 to +285

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
The returned action finishes when the request has been sent. Waiting
for it does not guarantee that the guest operating system has rebooted
or that its services are ready. The guest may ignore ACPI requests.
The returned action finishes when the ACPI request has been sent. Waiting
for it does not guarantee that the guest operating system has rebooted
or that its services are ready. The guest may ignore ACPI requests.

:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
"""
return self._client.reboot(self)
Expand All @@ -293,6 +297,12 @@ def reset(self) -> BoundAction:
def shutdown(self) -> BoundAction:
"""Shuts down a server gracefully by sending an ACPI shutdown request.

The returned action finishes when the request has been sent, not when
the guest operating system has stopped. After waiting for the action,
reload the server and poll its status until it is ``off`` before an
operation that requires a stopped server. The guest may ignore ACPI,
so polling should have a timeout.
Comment on lines +300 to +304

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
The returned action finishes when the request has been sent, not when
the guest operating system has stopped. After waiting for the action,
reload the server and poll its status until it is ``off`` before an
operation that requires a stopped server. The guest may ignore ACPI,
so polling should have a timeout.
The returned action finishes when the ACPI request has been sent, not when
the guest operating system has stopped. After waiting for the action,
reload the server and poll its status until it is ``off`` before an
operation that requires a stopped server. The guest may ignore ACPI,
so polling should have a timeout.


:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
"""
return self._client.shutdown(self)
Expand Down Expand Up @@ -861,6 +871,10 @@ def power_on(self, server: Server | BoundServer) -> BoundAction:
def reboot(self, server: Server | BoundServer) -> BoundAction:
"""Reboots a server gracefully by sending an ACPI request.

The returned action finishes when the request has been sent. Waiting
for it does not guarantee that the guest operating system has rebooted
or that its services are ready. The guest may ignore ACPI requests.

Comment on lines +874 to +877

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
The returned action finishes when the request has been sent. Waiting
for it does not guarantee that the guest operating system has rebooted
or that its services are ready. The guest may ignore ACPI requests.
The returned action finishes when the ACPI request has been sent. Waiting
for it does not guarantee that the guest operating system has rebooted
or that its services are ready. The guest may ignore ACPI requests.

:param server: :class:`BoundServer <hcloud.servers.client.BoundServer>` or :class:`Server <hcloud.servers.domain.Server>`
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
"""
Expand All @@ -885,6 +899,12 @@ def reset(self, server: Server | BoundServer) -> BoundAction:
def shutdown(self, server: Server | BoundServer) -> BoundAction:
"""Shuts down a server gracefully by sending an ACPI shutdown request.

The returned action finishes when the request has been sent, not when
the guest operating system has stopped. After waiting for the action,
reload the server and poll its status until it is ``off`` before an
operation that requires a stopped server. The guest may ignore ACPI,
so polling should have a timeout.
Comment on lines +902 to +906

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
The returned action finishes when the request has been sent, not when
the guest operating system has stopped. After waiting for the action,
reload the server and poll its status until it is ``off`` before an
operation that requires a stopped server. The guest may ignore ACPI,
so polling should have a timeout.
The returned action finishes when the ACPI request has been sent, not when
the guest operating system has stopped. After waiting for the action,
reload the server and poll its status until it is ``off`` before an
operation that requires a stopped server. The guest may ignore ACPI,
so polling should have a timeout.


:param server: :class:`BoundServer <hcloud.servers.client.BoundServer>` or :class:`Server <hcloud.servers.domain.Server>`
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
"""
Expand Down
Loading