mirror of
https://github.com/GNS3/gns3-server.git
synced 2026-11-04 06:21:15 +02:00
docker: graceful stop for vendor NOS containers (SIGTERM + 60s grace)
DockerVM.stop() terminated containers with an immediate SIGKILL — fine
for init.sh-based containers whose state is persisted beforehand, but a
systemd NOS (Cisco XRd, SR Linux) needs a graceful shutdown and treats
the abrupt kill as an unclean shutdown (exit 137 on every stop).
Extract the final termination into _terminate_container() and override
it in VendorDockerVM: POST /containers/{id}/stop?t=60 sends SIGTERM and
waits for systemd to stop services; Docker itself SIGKILLs the
container once the grace period expires, so no fallback is needed.
Docker's 304 (already stopped) is swallowed.
This commit is contained in:
4 files changed
+103
-16
No files matched your search
@@ -1206,12 +1206,8 @@ class DockerVM(BaseNode):
|
||||
|
||||
state = await self._get_container_state()
|
||||
if state != "stopped" and state != "exited":
|
||||
# SIGKILL immediately. GNS3 has already persisted container state
|
||||
# (permissions via _fix_permissions, /gns3volumes) before this
|
||||
# point, and the business process (often an interactive shell)
|
||||
# ignores SIGTERM — so a stop grace period buys nothing but latency.
|
||||
try:
|
||||
await self.manager.query("POST", f"containers/{self._cid}/kill")
|
||||
await self._terminate_container()
|
||||
log.debug(f"Docker container '{self._name}' [{self._image}] stopped")
|
||||
except DockerHttp409Error:
|
||||
# Container is already stopped
|
||||
@@ -1222,6 +1218,18 @@ class DockerVM(BaseNode):
|
||||
return
|
||||
self.status = "stopped"
|
||||
|
||||
async def _terminate_container(self):
|
||||
"""
|
||||
Final termination of a still-running container: immediate SIGKILL.
|
||||
GNS3 has already persisted container state (permissions via
|
||||
_fix_permissions, /gns3volumes) before this point, and the business
|
||||
process (often an interactive shell) ignores SIGTERM — a stop grace
|
||||
period buys nothing but latency. Vendor NOS containers override this
|
||||
with a graceful SIGTERM shutdown (see VendorDockerVM).
|
||||
"""
|
||||
|
||||
await self.manager.query("POST", f"containers/{self._cid}/kill")
|
||||
|
||||
async def pause(self):
|
||||
"""
|
||||
Pauses this Docker container.
|
||||
|
||||
Reference in new issue
Block a user