hafnia 0.1.26__tar.gz → 0.1.27__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {hafnia-0.1.26 → hafnia-0.1.27}/.github/workflows/publish_docker.yaml +1 -1
- {hafnia-0.1.26 → hafnia-0.1.27}/PKG-INFO +1 -1
- {hafnia-0.1.26 → hafnia-0.1.27}/pyproject.toml +1 -1
- {hafnia-0.1.26 → hafnia-0.1.27}/src/hafnia/platform/builder.py +25 -19
- {hafnia-0.1.26 → hafnia-0.1.27}/uv.lock +1 -1
- {hafnia-0.1.26 → hafnia-0.1.27}/.devcontainer/devcontainer.json +0 -0
- {hafnia-0.1.26 → hafnia-0.1.27}/.devcontainer/hooks/post_create +0 -0
- {hafnia-0.1.26 → hafnia-0.1.27}/.github/dependabot.yaml +0 -0
- {hafnia-0.1.26 → hafnia-0.1.27}/.github/workflows/Dockerfile +0 -0
- {hafnia-0.1.26 → hafnia-0.1.27}/.github/workflows/build.yaml +0 -0
- {hafnia-0.1.26 → hafnia-0.1.27}/.github/workflows/check_release.yaml +0 -0
- {hafnia-0.1.26 → hafnia-0.1.27}/.github/workflows/ci_cd.yaml +0 -0
- {hafnia-0.1.26 → hafnia-0.1.27}/.github/workflows/lint.yaml +0 -0
- {hafnia-0.1.26 → hafnia-0.1.27}/.github/workflows/publish_pypi.yaml +0 -0
- {hafnia-0.1.26 → hafnia-0.1.27}/.github/workflows/tests.yaml +0 -0
- {hafnia-0.1.26 → hafnia-0.1.27}/.gitignore +0 -0
- {hafnia-0.1.26 → hafnia-0.1.27}/.pre-commit-config.yaml +0 -0
- {hafnia-0.1.26 → hafnia-0.1.27}/.python-version +0 -0
- {hafnia-0.1.26 → hafnia-0.1.27}/.vscode/extensions.json +0 -0
- {hafnia-0.1.26 → hafnia-0.1.27}/.vscode/launch.json +0 -0
- {hafnia-0.1.26 → hafnia-0.1.27}/.vscode/settings.json +0 -0
- {hafnia-0.1.26 → hafnia-0.1.27}/LICENSE +0 -0
- {hafnia-0.1.26 → hafnia-0.1.27}/README.md +0 -0
- {hafnia-0.1.26 → hafnia-0.1.27}/docs/cli.md +0 -0
- {hafnia-0.1.26 → hafnia-0.1.27}/docs/release.md +0 -0
- {hafnia-0.1.26 → hafnia-0.1.27}/examples/dataset_builder.py +0 -0
- {hafnia-0.1.26 → hafnia-0.1.27}/examples/example_load_dataset.py +0 -0
- {hafnia-0.1.26 → hafnia-0.1.27}/examples/example_logger.py +0 -0
- {hafnia-0.1.26 → hafnia-0.1.27}/examples/example_torchvision_dataloader.py +0 -0
- {hafnia-0.1.26 → hafnia-0.1.27}/src/cli/__init__.py +0 -0
- {hafnia-0.1.26 → hafnia-0.1.27}/src/cli/__main__.py +0 -0
- {hafnia-0.1.26 → hafnia-0.1.27}/src/cli/config.py +0 -0
- {hafnia-0.1.26 → hafnia-0.1.27}/src/cli/consts.py +0 -0
- {hafnia-0.1.26 → hafnia-0.1.27}/src/cli/data_cmds.py +0 -0
- {hafnia-0.1.26 → hafnia-0.1.27}/src/cli/experiment_cmds.py +0 -0
- {hafnia-0.1.26 → hafnia-0.1.27}/src/cli/profile_cmds.py +0 -0
- {hafnia-0.1.26 → hafnia-0.1.27}/src/cli/recipe_cmds.py +0 -0
- {hafnia-0.1.26 → hafnia-0.1.27}/src/cli/runc_cmds.py +0 -0
- {hafnia-0.1.26 → hafnia-0.1.27}/src/hafnia/__init__.py +0 -0
- {hafnia-0.1.26 → hafnia-0.1.27}/src/hafnia/data/__init__.py +0 -0
- {hafnia-0.1.26 → hafnia-0.1.27}/src/hafnia/data/factory.py +0 -0
- {hafnia-0.1.26 → hafnia-0.1.27}/src/hafnia/experiment/__init__.py +0 -0
- {hafnia-0.1.26 → hafnia-0.1.27}/src/hafnia/experiment/hafnia_logger.py +0 -0
- {hafnia-0.1.26 → hafnia-0.1.27}/src/hafnia/http.py +0 -0
- {hafnia-0.1.26 → hafnia-0.1.27}/src/hafnia/log.py +0 -0
- {hafnia-0.1.26 → hafnia-0.1.27}/src/hafnia/platform/__init__.py +0 -0
- {hafnia-0.1.26 → hafnia-0.1.27}/src/hafnia/platform/download.py +0 -0
- {hafnia-0.1.26 → hafnia-0.1.27}/src/hafnia/platform/experiment.py +0 -0
- {hafnia-0.1.26 → hafnia-0.1.27}/src/hafnia/torch_helpers.py +0 -0
- {hafnia-0.1.26 → hafnia-0.1.27}/src/hafnia/utils.py +0 -0
- {hafnia-0.1.26 → hafnia-0.1.27}/tests/test_builder.py +0 -0
- {hafnia-0.1.26 → hafnia-0.1.27}/tests/test_check_example_scripts.py +0 -0
- {hafnia-0.1.26 → hafnia-0.1.27}/tests/test_cli.py +0 -0
- {hafnia-0.1.26 → hafnia-0.1.27}/tests/test_hafnia_logger.py +0 -0
- {hafnia-0.1.26 → hafnia-0.1.27}/tests/test_samples.py +0 -0
- {hafnia-0.1.26 → hafnia-0.1.27}/tests/test_utils.py +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import json
|
|
2
2
|
import os
|
|
3
|
+
import re
|
|
3
4
|
import subprocess
|
|
4
|
-
import tempfile
|
|
5
5
|
import zipfile
|
|
6
6
|
from hashlib import sha256
|
|
7
7
|
from pathlib import Path
|
|
@@ -58,7 +58,7 @@ def buildx_available() -> bool:
|
|
|
58
58
|
return False
|
|
59
59
|
|
|
60
60
|
|
|
61
|
-
def build_dockerfile(dockerfile: str, docker_context: str, docker_tag: str
|
|
61
|
+
def build_dockerfile(dockerfile: str, docker_context: str, docker_tag: str) -> None:
|
|
62
62
|
"""
|
|
63
63
|
Build a Docker image using the provided Dockerfile.
|
|
64
64
|
|
|
@@ -73,12 +73,12 @@ def build_dockerfile(dockerfile: str, docker_context: str, docker_tag: str, meta
|
|
|
73
73
|
|
|
74
74
|
cmd = ["docker", "build", "--platform", "linux/amd64", "-t", docker_tag, "-f", dockerfile]
|
|
75
75
|
|
|
76
|
-
remote_cache = os.getenv("
|
|
76
|
+
remote_cache = os.getenv("EXPERIMENT_CACHE_ECR")
|
|
77
77
|
cloud_mode = os.getenv("HAFNIA_CLOUD", "false").lower() in ["true", "1", "yes"]
|
|
78
78
|
|
|
79
79
|
if buildx_available():
|
|
80
80
|
cmd.insert(1, "buildx")
|
|
81
|
-
cmd += ["--build-arg", "BUILDKIT_INLINE_CACHE=1"
|
|
81
|
+
cmd += ["--build-arg", "BUILDKIT_INLINE_CACHE=1"]
|
|
82
82
|
if cloud_mode:
|
|
83
83
|
cmd += ["--push"]
|
|
84
84
|
if remote_cache:
|
|
@@ -91,11 +91,27 @@ def build_dockerfile(dockerfile: str, docker_context: str, docker_tag: str, meta
|
|
|
91
91
|
cmd.append(docker_context)
|
|
92
92
|
sys_logger.debug("Build cmd: `{}`".format(" ".join(cmd)))
|
|
93
93
|
sys_logger.info(f"Building and pushing Docker image with BuildKit (buildx); cache repo: {remote_cache or 'none'}")
|
|
94
|
+
result = None
|
|
95
|
+
output = ""
|
|
96
|
+
errors = []
|
|
94
97
|
try:
|
|
95
|
-
subprocess.run(cmd, check=True)
|
|
98
|
+
result = subprocess.run(cmd, check=True, capture_output=True, text=True)
|
|
99
|
+
output = (result.stdout or "") + (result.stderr or "")
|
|
96
100
|
except subprocess.CalledProcessError as e:
|
|
97
|
-
|
|
98
|
-
|
|
101
|
+
output = (e.stdout or "") + (e.stderr or "")
|
|
102
|
+
error_pattern = r"ERROR: (.+?)(?:\n|$)"
|
|
103
|
+
errors = re.findall(error_pattern, output)
|
|
104
|
+
if not errors:
|
|
105
|
+
raise RuntimeError(f"Docker build failed: {output}")
|
|
106
|
+
if re.search(r"image tag '([^']+)' already exists", errors[-1]):
|
|
107
|
+
sys_logger.warning("Image {} already exists in the registry.".format(docker_tag.rsplit("/")[-1]))
|
|
108
|
+
return
|
|
109
|
+
raise RuntimeError(f"Docker build failed: {output}")
|
|
110
|
+
finally:
|
|
111
|
+
stage_pattern = r"^.*\[\d+/\d+\][^\n]*"
|
|
112
|
+
stages = re.findall(stage_pattern, output, re.MULTILINE)
|
|
113
|
+
user_logger.info("\n".join(stages))
|
|
114
|
+
sys_logger.debug(output)
|
|
99
115
|
|
|
100
116
|
|
|
101
117
|
def check_registry(docker_image: str) -> Optional[str]:
|
|
@@ -127,18 +143,8 @@ def build_image(metadata: Dict, registry_repo: str, state_file: str = "state.jso
|
|
|
127
143
|
docker_image = f"{registry_repo}:{metadata['digest']}"
|
|
128
144
|
image_exists = check_registry(docker_image) is not None
|
|
129
145
|
if image_exists:
|
|
130
|
-
sys_logger.info(
|
|
146
|
+
sys_logger.info("Image {} already exists in the registry.".format(docker_image.rsplit("/")[-1]))
|
|
131
147
|
else:
|
|
132
|
-
|
|
133
|
-
meta_file = meta_tmp.name
|
|
134
|
-
build_dockerfile(
|
|
135
|
-
metadata["dockerfile"], Path(metadata["dockerfile"]).parent.as_posix(), docker_image, meta_file
|
|
136
|
-
)
|
|
137
|
-
with open(meta_file) as m:
|
|
138
|
-
try:
|
|
139
|
-
build_meta = json.load(m)
|
|
140
|
-
metadata["local_digest"] = build_meta["containerimage.digest"]
|
|
141
|
-
except Exception:
|
|
142
|
-
metadata["local_digest"] = ""
|
|
148
|
+
build_dockerfile(metadata["dockerfile"], Path(metadata["dockerfile"]).parent.as_posix(), docker_image)
|
|
143
149
|
metadata.update({"image_tag": docker_image, "image_exists": image_exists})
|
|
144
150
|
Path(state_file).write_text(json.dumps(metadata, indent=2))
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|