Commit 8be88413 authored by Dom Sekotill's avatar Dom Sekotill
Browse files

Make docker.Item.get_id return a new ShaID type

There is no actual assertion that ShaID types are SHA-256 hex
represenations, but this should at least help identify where ambiguity
exists.

Closes #17
parent a8f5b750
Loading
Loading
Loading
Loading
Loading
+27 −20
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ from typing import Any
from typing import Iterable
from typing import Iterator
from typing import MutableMapping
from typing import NewType
from typing import Tuple
from typing import TypeVar
from typing import Union
@@ -54,6 +55,8 @@ from .utils import wait

LOCALHOST = ipaddress.IPv4Address(0x7f000001)

ShaID = NewType("ShaID", str)

MountPath = Union[PathLike[bytes], PathLike[str]]
HostMount = tuple[MountPath, MountPath]
NamedMount = tuple[str, MountPath]
@@ -150,20 +153,20 @@ class Item:
	A mix-in for Docker items that can be inspected
	"""

	def __init__(self, ident: str):
		self._id = ident
	def __init__(self, reference: str):
		self.reference = reference

	def get_id(self) -> str:
	def get_id(self) -> ShaID:
		"""
		Return an identifier for the Docker item
		"""
		return self._id
		return self.inspect().path("$.Id", str, ShaID)

	def inspect(self) -> JSONObject:
		"""
		Get the result of inspecting the Docker item
		"""
		with Popen([DOCKER, 'inspect', self.get_id()], stdout=PIPE) as proc:
		with Popen([DOCKER, 'inspect', self.reference], stdout=PIPE) as proc:
			assert proc.stdout is not None
			results = json.load(proc.stdout)
		assert isinstance(results, list)
@@ -176,11 +179,11 @@ class Image(Item):
	Docker image items
	"""

	_cache = dict[str, str]()
	_cache = dict[str, ShaID]()

	T = TypeVar('T', bound='Image')

	def __init__(self, iid: str):
	def __init__(self, iid: ShaID):
		self.iid = iid

	@classmethod
@@ -196,7 +199,7 @@ class Image(Item):
			*(f"--build-arg={arg}={val}" for arg, val in build_args.items() if val is not None),
		]
		docker(*cmd, DOCKER_BUILDKIT='1')
		iid = docker_output(*cmd, '-q', DOCKER_BUILDKIT='1')
		iid = ShaID(docker_output(*cmd, '-q', DOCKER_BUILDKIT='1'))
		return cls(iid)

	@classmethod
@@ -212,16 +215,16 @@ class Image(Item):
		return cls(iid)

	@classmethod
	def _process_image(cls, reference: str) -> str:
	def _process_image(cls, reference: str) -> ShaID:
		report = Item(reference).inspect()
		iid = report.path("$.Id", str)
		iid = report.path("$.Id", str, ShaID)
		cls._cache.update(
			((tag, iid) for tag in report.path("$.RepoTags", list[str])),
			reference=iid,
		)
		return iid

	def get_id(self) -> str:
	def get_id(self) -> ShaID:
		"""
		Return an identifier for the Docker Image
		"""
@@ -264,7 +267,7 @@ class Container(Item):
		self.privileged = privileged
		self.publish = publish
		self.networks = dict[Network, Tuple[str, ...]]()
		self.cid: str|None = None
		self.cid: ShaID|None = None

		if network:
			self.connect(network, *self.DEFAULT_ALIASES)
@@ -309,7 +312,7 @@ class Container(Item):
			and details.path('$.State.Running', bool)
		)

	def get_id(self) -> str:
	def get_id(self) -> ShaID:
		"""
		Return an identifier for the Docker Container
		"""
@@ -346,7 +349,9 @@ class Container(Item):
		else:
			opts.append(b"--network=none")

		self.cid = docker_output(b"container", b"create", *opts, self.image.iid, *self.cmd)
		self.cid = ShaID(
			docker_output(b"container", b"create", *opts, self.image.iid, *self.cmd),
		)
		assert self.cid

		# Disconnect the "none" network specified as the starting network
@@ -485,7 +490,7 @@ class Network(Item):

	def __init__(self, name: str|None = None) -> None:
		self._name = name or f"br{token_hex(6)}"
		self._nid: str|None = None
		self._nid: ShaID|None = None
		self._assigned = set[ipaddress.IPv4Address]()

	def __str__(self) -> str:
@@ -517,7 +522,7 @@ class Network(Item):
		"""
		return self._name

	def get_id(self) -> str:
	def get_id(self) -> ShaID:
		"""
		Return an identifier for the Docker Network
		"""
@@ -533,9 +538,11 @@ class Network(Item):
		subnet = self.get_free_subnet()
		gateway = next(subnet.hosts())
		try:
			self._nid = docker_output(
			self._nid = ShaID(
				docker_output(
					b"network", b"create", self._name,
					f"--subnet={subnet}", f"--gateway={gateway}",
				),
			)
		except CalledProcessError:
			data = exec_io(
@@ -544,7 +551,7 @@ class Network(Item):
			)
			if len(data) == 0:
				raise
			self._nid = data.path("$[0].Id", str)
			self._nid = data.path("$[0].Id", str, ShaID)
			self._assigned.update(
				data.path(
					"$[0].IPAM.Config[*].Gateway",