An `Image` whose dependencies have been resolved. Attributes: image: The underlying `Image`. acquired: Whether the image is available locally. dependencies: A mapping from dependency name to `ResolvedImage` for each of the images that `image` depends upon.
| 956 | |
| 957 | |
| 958 | class ResolvedImage: |
| 959 | """An `Image` whose dependencies have been resolved. |
| 960 | |
| 961 | Attributes: |
| 962 | image: The underlying `Image`. |
| 963 | acquired: Whether the image is available locally. |
| 964 | dependencies: A mapping from dependency name to `ResolvedImage` for |
| 965 | each of the images that `image` depends upon. |
| 966 | """ |
| 967 | |
| 968 | def __init__(self, image: Image, dependencies: Iterable["ResolvedImage"]): |
| 969 | self.image = image |
| 970 | self.acquired = False |
| 971 | self.dependencies = {} |
| 972 | for d in dependencies: |
| 973 | self.dependencies[d.name] = d |
| 974 | |
| 975 | def __repr__(self) -> str: |
| 976 | return f"ResolvedImage<{self.spec()}>" |
| 977 | |
| 978 | @property |
| 979 | def name(self) -> str: |
| 980 | """The name of the underlying image.""" |
| 981 | return self.image.name |
| 982 | |
| 983 | @property |
| 984 | def publish(self) -> bool: |
| 985 | """Whether the underlying image should be pushed to Docker Hub.""" |
| 986 | return self.image.publish |
| 987 | |
| 988 | @cache |
| 989 | def spec(self) -> str: |
| 990 | """Return the "spec" for the image. |
| 991 | |
| 992 | A spec is the unique identifier for the image given its current |
| 993 | fingerprint. It is a valid Docker Hub name. |
| 994 | """ |
| 995 | return self.image.docker_name(tag=f"mzbuild-{self.fingerprint()}") |
| 996 | |
| 997 | def write_dockerfile(self) -> IO[bytes]: |
| 998 | """Render the Dockerfile without mzbuild directives. |
| 999 | |
| 1000 | Returns: |
| 1001 | file: A handle to a temporary file containing the adjusted |
| 1002 | Dockerfile.""" |
| 1003 | with open(self.image.path / "Dockerfile", "rb") as f: |
| 1004 | lines = f.readlines() |
| 1005 | f = TemporaryFile() |
| 1006 | for line in lines: |
| 1007 | match = Image._DOCKERFILE_MZFROM_RE.match(line) |
| 1008 | if match: |
| 1009 | image = match.group(1).decode() |
| 1010 | spec = self.dependencies[image].spec() |
| 1011 | line = Image._DOCKERFILE_MZFROM_RE.sub(b"FROM %b" % spec.encode(), line) |
| 1012 | f.write(line) |
| 1013 | f.seek(0) |
| 1014 | return f |
| 1015 |