docker: don't recreate containers on empty-string property PUTs

Web clients serialize empty form fields as "" while unset values are
stored as None on the node. The bare != diff in the update handler then
sees a phantom change on every full PUT and recreates the container for
nothing -- even when the user only changed a controller-only field such
as netmiko_device_type.

Normalize at the schema boundary ("" -> None for start_command,
environment and extra_hosts; "" -> "/" for console_http_path), make
the setters apply the same canonicalization, and create nodes through
the setters instead of bypassing them in __init__ so both paths store
identical values.
This commit is contained in:
YueGuobin committed 2026-08-21 21:41:47 +08:00
1 parent c3145a9f65
commit 210103058f
3 files changed
+68 -8

No files matched your search

+13 -7
View File
@@ -129,8 +129,10 @@ class DockerVM(BaseNode):
if ":" not in image:
image = f"{image}:latest"
self._image = image
self._start_command = start_command
self._environment = environment
# assign through the property setters so creation and updates apply
# the same value normalization (e.g. "" -> None)
self.start_command = start_command
self.environment = environment
self._cid = None
self._ethernet_adapters = []
self._temporary_directory = None
@@ -138,10 +140,10 @@ class DockerVM(BaseNode):
self._vnc_process = None
self._vncconfig_process = None
self._console_resolution = console_resolution
self._console_http_path = console_http_path
self.console_http_path = console_http_path
self._console_http_port = console_http_port
self._console_websocket = None
self._extra_hosts = extra_hosts
self.extra_hosts = extra_hosts
self._extra_volumes = extra_volumes or []
self._extra_configs = extra_configs or []
self._memory = memory
@@ -288,7 +290,9 @@ class DockerVM(BaseNode):
@console_http_path.setter
def console_http_path(self, path):
self._console_http_path = path
# the canonical "no path" value is "/" so that "", None and "/"
# all compare equal in the update diff
self._console_http_path = path or "/"
@property
def console_http_port(self):
@@ -304,7 +308,8 @@ class DockerVM(BaseNode):
@environment.setter
def environment(self, command):
self._environment = command
# "" and None are the same "no environment variables" value
self._environment = command or None
@property
def extra_hosts(self):
@@ -312,7 +317,8 @@ class DockerVM(BaseNode):
@extra_hosts.setter
def extra_hosts(self, extra_hosts):
self._extra_hosts = extra_hosts
# "" and None are the same "no extra hosts" value
self._extra_hosts = extra_hosts or None
@property
def extra_volumes(self):