Commit 5c55b5f1 authored by Dom Sekotill's avatar Dom Sekotill
Browse files

Delay container network connection

parent 3deea14a
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:
		"""