Skip to content
Open
Show file tree
Hide file tree
Changes from 59 commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
81dfce0
Add payload accessibility
Jrice1317 Apr 20, 2026
749abd4
First pass
Jrice1317 Apr 22, 2026
d60e4b3
Revert shar changes
Jrice1317 Apr 22, 2026
c3524ba
Fix logic with building on non-native platforms
Jrice1317 Apr 22, 2026
df67edf
Add mamba logic
Jrice1317 Apr 22, 2026
b71c8f9
Require base image to be provided in construct.yaml
Jrice1317 May 6, 2026
ec455fa
Update docker_build.py
Jrice1317 May 6, 2026
1fd5f98
Use existing vars in template
Jrice1317 May 6, 2026
5028672
Add docker as installer type
Jrice1317 May 6, 2026
487d802
Add example construct.yaml for tests
Jrice1317 May 6, 2026
c46044a
Add test
Jrice1317 May 6, 2026
ae648a5
Add clean command
Jrice1317 May 6, 2026
539500c
Call proper docker command in test
Jrice1317 May 6, 2026
43ca213
Fix pre-commit errors
Jrice1317 May 6, 2026
0bf8de5
Add docstring to beginning of file
Jrice1317 May 6, 2026
9f20cbe
Use schema vars properly
Jrice1317 May 6, 2026
65f9fd8
Use correct image name in test
Jrice1317 May 6, 2026
4fd0868
Update docs
Jrice1317 May 6, 2026
8b10804
Add news file
Jrice1317 May 6, 2026
01a9982
Do not generate file extension .docker
Jrice1317 May 6, 2026
d86ee52
Fix typos
Jrice1317 May 6, 2026
5784073
Always use sh for docker
Jrice1317 May 6, 2026
b2ff9d5
Pre-commit fix
Jrice1317 May 6, 2026
f97e163
Remove docker from os_allowed
Jrice1317 May 6, 2026
15a8b1f
Regenerate schema
Jrice1317 May 6, 2026
a5704bb
Add docker_build to schema
Jrice1317 May 6, 2026
8db9e96
Make whitespace adjustments
Jrice1317 May 8, 2026
6d1d118
Fix logic regarding base image requirement
Jrice1317 May 8, 2026
f65ecf3
Make image portable
Jrice1317 May 8, 2026
989fb30
Update wording
Jrice1317 May 8, 2026
7338b72
Update docs
Jrice1317 May 8, 2026
120d135
Revert to using one path
Jrice1317 May 8, 2026
be48dd1
Revert back to docker load
Jrice1317 May 8, 2026
18b7001
Add output
Jrice1317 May 8, 2026
583191d
Apply suggestions from code review
Jrice1317 May 14, 2026
b047963
Update logic
Jrice1317 May 14, 2026
80ee0a7
Merge branch 'docker-implementation' of https://github.com/Jrice1317/…
Jrice1317 May 14, 2026
2dbe4eb
Change wording in schema
Jrice1317 May 14, 2026
c1876f5
Be more descriptive
Jrice1317 May 15, 2026
c0ab7cb
Be more generalized
Jrice1317 May 15, 2026
963126c
Use multiline block
Jrice1317 May 15, 2026
40475f9
Refine logic
Jrice1317 May 15, 2026
9fea3d4
Move check to main if docker installed for building image
Jrice1317 May 15, 2026
1720895
Change docker_build to docker_image
Jrice1317 May 15, 2026
8735a9a
Expand tests
Jrice1317 May 15, 2026
56957c2
Pre-commit fixes
Jrice1317 May 15, 2026
ceb9a3c
Change logic
Jrice1317 May 15, 2026
511ade6
Update docs
Jrice1317 May 15, 2026
c10fe4d
Fix whitespace in template
Jrice1317 May 18, 2026
f50394f
Remove redundant logic and improve wording
Jrice1317 May 18, 2026
9ba611f
Fix test
Jrice1317 May 18, 2026
c0b7fd3
Update docs
Jrice1317 May 18, 2026
3fec340
Make tests linux only
Jrice1317 May 18, 2026
15413f2
Remove restriction on docker_tag and apply code review suggestions
Jrice1317 May 20, 2026
1b534dc
Add cross-build support to tests
Jrice1317 May 20, 2026
6998d3d
Update the docs
Jrice1317 May 20, 2026
c0e7735
Fix typo
Jrice1317 May 20, 2026
2a6c4cc
Add output for debugging
Jrice1317 May 20, 2026
0b5ce84
Add docker buildx check to utils
Jrice1317 May 20, 2026
e75758d
Apply code review suggestions and update docs
Jrice1317 May 22, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion CONSTRUCT.md
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ The type of the installer being created. Possible values are:
- `sh`: shell-based installer for Linux or macOS
- `pkg`: macOS GUI installer built with Apple's `pkgbuild`
- `exe`: Windows GUI installer built with NSIS
- `docker`: generates a `Dockerfile` or image of the installation environment.

The default type is `sh` on Linux and macOS, and `exe` on Windows. A special
value of `all` builds _both_ `sh` and `pkg` installers on macOS, as well
Expand Down Expand Up @@ -419,7 +420,7 @@ is `${HOME}/<NAME>` (or, if `HOME` is not set, `/opt/<NAME>`). On Windows,
this is used only for "Just Me" installations; for "All Users" installations,
use the `default_prefix_all_users` key. If not provided, the default prefix
is `%USERPROFILE%\<NAME>`. Environment variables will be expanded at
install time.
install time. If creating a Docker output, the default is `/opt/<NAME>` and can be overridden during the Docker build process.

### `default_prefix_domain_user`

Expand Down Expand Up @@ -679,6 +680,29 @@ freeze_base:
message: "This base environment is frozen and cannot be modified."
```

### `docker_base_image`

Required to use docker-related features.
Base image to use for docker builds and Dockerfiles. This can be any valid docker image reference, including a tag and/or digest.
For example: `debian:13.4-slim@sha256:abc123...`.

### `docker_tag`

Tag to use for the docker image.
If not provided, it will default to `<name>:<version>`.
Has no effect if not using the `docker_image` feature.

### `docker_labels`

Additional labels to add to the built docker image.
The labels `org.opencontainers.image.title` and `org.opencontainers.image.version`
are set automatically from `name` and `version`.

### `docker_image`

If set, builds a docker image using the Dockerfile generated by constructor and saves it as a portable tarball either uncompressed or compressed.
``<name>-<version>-<platform>-<arch>-docker.tar`` will be created in the output docker directory.


## Available selectors
- `aarch64`
Expand Down
27 changes: 26 additions & 1 deletion constructor/_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class InstallerTypes(StrEnum):
EXE = "exe"
PKG = "pkg"
SH = "sh"
DOCKER = "docker"


class PkgDomains(StrEnum):
Expand Down Expand Up @@ -403,6 +404,7 @@ class ConstructorConfiguration(BaseModel):
- `sh`: shell-based installer for Linux or macOS
- `pkg`: macOS GUI installer built with Apple's `pkgbuild`
- `exe`: Windows GUI installer built with NSIS
- `docker`: generates a `Dockerfile` or image of the installation environment.

The default type is `sh` on Linux and macOS, and `exe` on Windows. A special
value of `all` builds _both_ `sh` and `pkg` installers on macOS, as well
Expand Down Expand Up @@ -588,7 +590,7 @@ class ConstructorConfiguration(BaseModel):
this is used only for "Just Me" installations; for "All Users" installations,
use the `default_prefix_all_users` key. If not provided, the default prefix
is `%USERPROFILE%\\<NAME>`. Environment variables will be expanded at
install time.
install time. If creating a Docker output, the default is `/opt/<NAME>` and can be overridden during the Docker build process.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should mention which variable to use to override it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok

"""
default_prefix_domain_user: NonEmptyStr | None = None
"""
Expand Down Expand Up @@ -853,6 +855,29 @@ class ConstructorConfiguration(BaseModel):
message: "This base environment is frozen and cannot be modified."
```
"""
docker_base_image: Annotated[str, Field(min_length=1)] | None = None
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of prefixing all fields with docker_*, would it make more sense to make docker its own key with all other properties being a subkey? I know that's not our current convention, so I'm not 100% sure about that.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree it could be cleaner, but unless we can do a broader refactor, I think docker_* keeps things consistent with how it's handled today.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, please volunteer me if/when we can do a schema refactor. (:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sticking with the current schema is a fair choice. A schema refactor would constitute a major breaking change that I don't foresee ourselves doing unless we absolutely have to.

"""
Required to use docker-related features.
Base image to use for docker builds and Dockerfiles. This can be any valid docker image reference, including a tag and/or digest.
For example: `debian:13.4-slim@sha256:abc123...`.
"""
docker_tag: NonEmptyStr | None = None
"""
Tag to use for the docker image.
If not provided, it will default to `<name>:<version>`.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to provide a default here? docker build runs with a tag, too.

Will this require docker_build (or whatever successor you choose) to be set?

Copy link
Copy Markdown
Contributor Author

@Jrice1317 Jrice1317 May 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should. It's handled in the script, but I could add something like Has no effect if `docker_build` or `docker_output` is not set.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I actually wrote the opposite of what I meant to write: docker build runs without a tag, too. So, tagging the image isn't necessarily required for it to work. Definitely disclose in the schema when that option has no effect for the docker installer type.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To clarify, it is highly suggested that a tag be used with docker build. The only thing is that it is not required for the user to come up with that tag because it will default to miniconda3:25.1.1 for example. Please let me know if that default is sufficient or if something like miniconda3-25.1.1:linux-arm64 would be better.

Copy link
Copy Markdown
Contributor Author

@Jrice1317 Jrice1317 May 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if there's a limit on characters for the tag name, but the latter is definitely more descriptive. 😄

Has no effect if not using the `docker_image` feature.
"""
docker_labels: dict[NonEmptyStr, NonEmptyStr] = {}
"""
Additional labels to add to the built docker image.
The labels `org.opencontainers.image.title` and `org.opencontainers.image.version`
are set automatically from `name` and `version`.
"""
docker_image: Literal["tar", "gz", "zst"] | None = None
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we add explicit NotImplementedError for those values that are not yet implemented? I see in the PR it says:

(gz, zst) are defined in the schema but not yet implemented.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch!

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We shouldn't allow inputs we don't support. It's okay to only allow "tar" for now. Also, should we call it docker_image_format? I feel like that's more descriptive.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, and we don't allow inputs we don't support and"tar" is the only one allowed because we reject anything outside of tar with a NotImplementedError. gz and zst are left intentionally as placeholders to document the planned formats so the research isn't lost and users understand the direction. The other compressions including bz2 may be used as well, but they would need to be used manually. Eventually, constructor could handle this, but I think it's better suited for a different PR. Is this wording better?

    docker_image: Literal["tar", "gz", "zst"] | None = None
    """
    If set, builds a docker image using the Dockerfile generated by constructor and saves it as a portable file. Currently, only ``tar``(uncompressed) is supported. Additional formats (``gz``, ``zst``) are planned for future releases.
``<name>-<version>-<platform>-docker.<extension>`` will be created in the output directory.
    """

As far as the docker_image_format, it is more descriptive, but I think docker_image communicates that the user is opting into having the image built, which feels right — the name is the feature toggle, not just a format selector. docker_image_format reads more like a sub-option for something already enabled.

"""
If set, builds a docker image using the Dockerfile generated by constructor and saves it as a portable tarball either uncompressed or compressed.
``<name>-<version>-<platform>-<arch>-docker.tar`` will be created in the output docker directory.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
``<name>-<version>-<platform>-<arch>-docker.tar`` will be created in the output docker directory.
``<name>-<version>-<platform>-<arch>-docker.<extension>`` will be created in the output docker directory.

"""


def fix_descriptions(obj):
Expand Down
66 changes: 63 additions & 3 deletions constructor/data/construct.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,8 @@
"all",
"exe",
"pkg",
"sh"
"sh",
"docker"
],
"title": "InstallerTypes",
"type": "string"
Expand Down Expand Up @@ -607,7 +608,7 @@
}
],
"default": null,
"description": "Set default install prefix. On Linux, if not provided, the default prefix is `${HOME}/<NAME>` (or, if `HOME` is not set, `/opt/<NAME>`). On Windows, this is used only for \"Just Me\" installations; for \"All Users\" installations, use the `default_prefix_all_users` key. If not provided, the default prefix is `%USERPROFILE%\\<NAME>`. Environment variables will be expanded at install time.",
"description": "Set default install prefix. On Linux, if not provided, the default prefix is `${HOME}/<NAME>` (or, if `HOME` is not set, `/opt/<NAME>`). On Windows, this is used only for \"Just Me\" installations; for \"All Users\" installations, use the `default_prefix_all_users` key. If not provided, the default prefix is `%USERPROFILE%\\<NAME>`. Environment variables will be expanded at install time. If creating a Docker output, the default is `/opt/<NAME>` and can be overridden during the Docker build process.",
"title": "Default Prefix"
},
"default_prefix_all_users": {
Expand Down Expand Up @@ -638,6 +639,65 @@
"description": "Set default installation prefix for domain users. If not provided, the installation prefix for domain users will be `%LOCALAPPDATA%\\<NAME>`. By default, it is different from the `default_prefix` value to avoid installing the distribution into the roaming profile. Environment variables will be expanded at install time. Windows only.",
"title": "Default Prefix Domain User"
},
"docker_base_image": {
"anyOf": [
{
"minLength": 1,
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Required to use docker-related features. Base image to use for docker builds and Dockerfiles. This can be any valid docker image reference, including a tag and/or digest. For example: `debian:13.4-slim@sha256:abc123...`.",
"title": "Docker Base Image"
},
"docker_image": {
"anyOf": [
{
"enum": [
"tar",
"gz",
"zst"
],
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "If set, builds a docker image using the Dockerfile generated by constructor and saves it as a portable tarball either uncompressed or compressed. ``<name>-<version>-<platform>-<arch>-docker.tar`` will be created in the output docker directory.",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the format <name>-<version>-<platform>-<arch> true?
From what I could see in the code it looks like:

tag = info.get("docker_tag", f"{info['name'].lower()}:{info['version']}")

"title": "Docker Image"
},
"docker_labels": {
"additionalProperties": {
"minLength": 1,
"type": "string"
},
"default": {},
"description": "Additional labels to add to the built docker image. The labels `org.opencontainers.image.title` and `org.opencontainers.image.version` are set automatically from `name` and `version`.",
"propertyNames": {
"minLength": 1
},
"title": "Docker Labels",
"type": "object"
},
"docker_tag": {
"anyOf": [
{
"minLength": 1,
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "Tag to use for the docker image. If not provided, it will default to `<name>:<version>`. Has no effect if not using the `docker_image` feature.",
"title": "Docker Tag"
},
"environment": {
"anyOf": [
{
Expand Down Expand Up @@ -864,7 +924,7 @@
}
],
"default": null,
"description": "The type of the installer being created. Possible values are:\n- `sh`: shell-based installer for Linux or macOS\n- `pkg`: macOS GUI installer built with Apple's `pkgbuild`\n- `exe`: Windows GUI installer built with NSIS\nThe default type is `sh` on Linux and macOS, and `exe` on Windows. A special value of `all` builds _both_ `sh` and `pkg` installers on macOS, as well as `sh` on Linux and `exe` on Windows.",
"description": "The type of the installer being created. Possible values are:\n- `sh`: shell-based installer for Linux or macOS\n- `pkg`: macOS GUI installer built with Apple's `pkgbuild`\n- `exe`: Windows GUI installer built with NSIS\n- `docker`: generates a `Dockerfile` or image of the installation environment.\nThe default type is `sh` on Linux and macOS, and `exe` on Windows. A special value of `all` builds _both_ `sh` and `pkg` installers on macOS, as well as `sh` on Linux and `exe` on Windows.",
"title": "Installer Type"
},
"keep_pkgs": {
Expand Down
166 changes: 166 additions & 0 deletions constructor/docker_build.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
"""Logic for creating a Dockerfile and/or building portable Docker images from Constructor installers."""

import logging
import shutil
import subprocess
import tempfile
from pathlib import Path

from jinja2 import Template

from . import __version__

logger = logging.getLogger(__name__)

TEMPLATE_PATH = Path(__file__).parent / "dockerfile_template.tmpl"

DOCKER_PLATFORM_MAP = {
"linux-64": "linux/amd64",
"linux-aarch64": "linux/arm64",
"linux-armv7l": "linux/arm/v7",
"linux-32": "linux/386",
"linux-ppc64le": "linux/ppc64le",
"linux-s390x": "linux/s390x",
}


def generate_dockerfile(info: dict, docker_dir: Path) -> Path:
"""
Render the Dockerfile template and write it to the Docker build directory.

Parameters
----------
info: dict
Constructor installer info dict.
docker_dir: Path
Path to the Docker build directory returned by prepare_docker_context().

Returns
-------
Path
Path to the generated Dockerfile.
"""
from .conda_interface import MatchSpec

specs = {MatchSpec(spec).name for spec in info.get("specs", ())}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
specs = {MatchSpec(spec).name for spec in info.get("specs", ())}
specs = {MatchSpec(spec).name for spec in info.get("specs", ())}
has_mamba = "mamba" in specs

That will make things more clear later. Should probably also be done with conda because not every installation has conda or mamba.

has_mamba = "mamba" in specs

docker_template = Template(TEMPLATE_PATH.read_text())

rendered_dockerfile = docker_template.render(
constructor_version=__version__,
base_image=info.get("docker_base_image"),
default_prefix=info.get("default_prefix", f"/opt/{info['name'].lower()}"),
Comment thread
Jrice1317 marked this conversation as resolved.
installer_filename=Path(info["_outpath"]).name,
name=info["name"],
version=info["version"],
labels=info.get("docker_labels", {}),
init_cmd="$PREFIX/bin/mamba shell" if has_mamba else "$PREFIX/bin/python -m conda",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is still assuming that either mamba or conda must be in the base environment. This is not necessarily true. We need to implement the same has_conda check as for mamba. Also note that mamba v1 uses a different init command than mamba v2.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. Moving this to the template and adding a v1 fallback

register_envs=info.get("register_envs"),
keep_pkgs=info.get("keep_pkgs"),
)

logger.info("Writing Dockerfile...")
dockerfile_path = docker_dir / "Dockerfile"
dockerfile_path.write_text(rendered_dockerfile)
return dockerfile_path


def build_image(info: dict, docker_dir: Path) -> Path:
"""Optionally build the docker image from the generated Dockerfile.
Currently supported on linux and macOS platforms.

Parameters
----------
info: dict
Constructor installer info dict.
docker_dir: Path
Path to the Docker directory containing the Docker outputs.

Returns
-------
Path
Path to the saved Docker image tarball.

"""
if not (docker_platform := DOCKER_PLATFORM_MAP.get(info["_platform"])):
raise RuntimeError(
f"Unsupported platform for Docker build: {info['_platform']}. "
f"Supported platforms are: {', '.join(DOCKER_PLATFORM_MAP.keys())}."
)

tag = info.get("docker_tag", f"{info['name'].lower()}:{info['version']}")
tarball_dest = docker_dir / f"{Path(info['_outpath']).stem}-docker.tar"

cmd = [
"docker",
"buildx",
"build",
str(docker_dir),
"--platform",
docker_platform,
"-t",
tag,
Comment thread
Jrice1317 marked this conversation as resolved.
"--load",
]

logger.info("Building Docker image: '%s'", tag)
try:
subprocess.run(cmd, check=True)
except subprocess.CalledProcessError as e:
# Gather diagnostics on failure
docker_version = subprocess.run(["docker", "--version"], capture_output=True, text=True)
buildx_version = subprocess.run(
["docker", "buildx", "version"], capture_output=True, text=True
)
buildx_ls = subprocess.run(["docker", "buildx", "ls"], capture_output=True, text=True)
raise RuntimeError(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we have such detailed error reporting for docker build, but not docker save? All this version output seems noisy and the command is already included in a the default traceback of a CalledProcessError as far as I know.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can provide some context here, I suggested to add that to debug unrecognized argument --platform yesterday which revealed that docker buildx was not available as a command on the Runner.

I'm OK removing/keeping it - hopefully we dont need to debug issues like that again in the future.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

has_docker_buildx() catches missing buildx at startup, but if this continues to expand, build failures can come from many other sources. The diagnostics only run on failure and have already proven useful in CI. If we're voting, I'd like to keep them.

f"Docker build failed.\n"
f"Command: {cmd}\n"
f"Docker version: {docker_version.stdout.strip()}\n"
f"Buildx version: {buildx_version.stdout.strip() or buildx_version.stderr.strip()}\n"
f"Buildx builders: {buildx_ls.stdout.strip()}"
) from e

logger.info("Saving Docker image to tarball: '%s'", tarball_dest)
subprocess.run(["docker", "save", tag, "-o", str(tarball_dest)], check=True)
subprocess.run(["docker", "rmi", tag], check=False)
return tarball_dest


def create(info: dict, verbose: bool = False) -> None:
"""Build a Docker output
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add something to the doc string describing where the SH installer is coming from?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure!


Parameters
----------
info: dict
Constructor installer info dict.
verbose: bool, optional
If ``True``, enables verbose logging.
Defaults to ``False``.

"""
with tempfile.TemporaryDirectory() as temp_dir:
docker_tmp_dir = Path(temp_dir)

installer_path = Path(info["_outpath"])
if not installer_path.exists():
raise RuntimeError(f"Expected .sh installer not found: {installer_path}")
shutil.copy(installer_path, docker_tmp_dir / installer_path.name)
logger.info("Copied installer to build directory.")

generate_dockerfile(info, docker_tmp_dir)

if info.get("docker_image") == "tar":
tarball = build_image(info, docker_tmp_dir)
shutil.copy(tarball, Path(info["_output_dir"]) / tarball.name)
else:
output_dir = Path(info["_output_dir"]) / installer_path.stem
output_dir.mkdir(parents=True, exist_ok=True)
shutil.copy(docker_tmp_dir / "Dockerfile", output_dir / "Dockerfile")
shutil.copy(
docker_tmp_dir / Path(info["_outpath"]).name,
output_dir / Path(info["_outpath"]).name,
)

logger.info("Docker output complete. Docker directory: '%s'", info["_output_dir"])
Loading
Loading