Commit 36c9f812 authored by Dom Sekotill's avatar Dom Sekotill
Browse files

Merge branch '30-delay-container-network-connection' into 'release/0.3.x'

Delay actual container network connection until creation

See merge request !13
parents 3deea14a 5c55b5f1
Loading
Loading
Loading
Loading
Loading
+25 −12
Original line number Diff line number Diff line
#  Copyright 2021-2022  Dominik Sekotill <dom.sekotill@kodo.org.uk>
#  Copyright 2021-2023  Dominik Sekotill <dom.sekotill@kodo.org.uk>
#
#  This Source Code Form is subject to the terms of the Mozilla Public
#  License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -33,7 +33,6 @@ from typing import Any
from typing import Iterable
from typing import Iterator
from typing import MutableMapping
from typing import Tuple
from typing import TypeVar
from typing import Union
from typing import cast
@@ -260,7 +259,7 @@ class Container(Item):
		self.entrypoint = entrypoint
		self.privileged = privileged
		self.publish = publish
		self.networks = dict[Network, Tuple[str, ...]]()
		self.networks = dict[Network, tuple[IPAddress, tuple[str, ...]]]()
		self.cid: str|None = None

		if network:
@@ -349,6 +348,10 @@ class Container(Item):
		if not self.publish:
			docker_quiet(b"network", b"disconnect", b"none", self.cid)

		# Connect any pre-configured networks
		for network, (address, aliases) in self.networks.items():
			self._connect_network(self.cid, network, address, aliases)

		return self.cid

	def start(self) -> None:
@@ -387,22 +390,32 @@ class Container(Item):
		Any aliases supplied will be resolvable to the container by other containers on the
		network.
		"""
		cid = self.get_id()
		opts = [f'--alias={a}' for a in aliases]
		if network in self.networks:
			if self.networks[network][1] == aliases:
				return
			if self.cid is not None:
				docker(b"network", b"disconnect", str(network), self.cid)

		if address is None:
			address = network.reserve_address()
		self.networks[network] = address, aliases

		if self.cid is not None:
			self._connect_network(self.cid, network, address, aliases)

	@staticmethod
	def _connect_network(
		contrid: str,
		network: Network,
		address: IPAddress,
		aliases: Iterable[str],
	) -> None:
		opts = [f'--alias={a}' for a in aliases]
		opts.append(
			f"--ip={address}" if isinstance(address, ipaddress.IPv4Address) else
			f"--ip6={address}",
		)

		if network in self.networks:
			if self.networks[network] == aliases:
				return
			docker(b"network", b"disconnect", str(network), cid)
		docker(b"network", b"connect", *opts, str(network), cid)
		self.networks[network] = aliases
		docker(b"network", b"connect", *opts, str(network), contrid)

	def show_logs(self) -> None:
		"""