Verified Commit 9801123f authored by Dom Sekotill's avatar Dom Sekotill
Browse files

Change alias behaviour in Container.{connect,disconnect}

Aliases passed to `Container.connect()` are now unioned with already
present aliases.  `Container.disconnect()` also now takes aliases as
arguments which, if provided, are removed from the active aliases; the
network is only disconnected once there are no more aliases.  This is
intended to allow containers to have aliases that are managed by other,
dependent resources.
parent fd490f11
Loading
Loading
Loading
Loading
+19 −7
Original line number Diff line number Diff line
@@ -275,7 +275,7 @@ class Container:
		self.entrypoint = entrypoint
		self.privileged = privileged
		self.publish = publish
		self.networks = dict[Network, tuple[IPAddress, tuple[str, ...]]]()
		self.networks = dict[Network, tuple[IPAddress, set[str]]]()
		self.cid: ShaID|None = None

		if network:
@@ -407,7 +407,7 @@ class Container:
	def connect(
		self,
		network: Network,
		*aliases: str,
		*new_aliases: str,
		address: ipaddress.IPv4Address|ipaddress.IPv6Address|None = None,
	) -> None:
		"""
@@ -416,8 +416,12 @@ class Container:
		Any aliases supplied will be resolvable to the container by other containers on the
		network.
		"""
		aliases = set(new_aliases)

		if network in self.networks:
			if self.networks[network][1] == aliases:
			_, cur_aliases = self.networks[network]
			aliases.update(cur_aliases)
			if aliases == cur_aliases:
				return
			if self.cid is not None:
				docker(b"network", b"disconnect", str(network), self.cid)
@@ -443,14 +447,22 @@ class Container:
		)
		docker(b"network", b"connect", *opts, str(network), contrid)

	def disconnect(self, network: Network) -> None:
	def disconnect(self, network: Network, *rm_aliases: str) -> None:
		"""
		Disconnect the container from a Docker network
		Disconnect the container from a Docker network or optionally unregister aliases

		For backwards compatibility, if no aliases are provided the network is disconnected
		immediately; otherwise the provided aliases are removed from the registered aliases
		and the network only disconnected once there are no remaining aliases.

		Raises `KeyError` if the network was not connected to with `Container.connect()`.
		"""
		del self.networks[network]
		if self.cid is not None:
		address, aliases = self.networks.pop(network)
		aliases.difference_update(rm_aliases)
		if rm_aliases and aliases:
			# Removed some, but not all aliases; re-add modified network details
			self.networks[network] = address, aliases
		elif self.cid is not None:
			docker(b"network", b"disconnect", str(network), self.cid)

	def show_logs(self) -> None: