Skip to content

Commit 6eaffcf

Browse files
authored
Set up initial async job scaffolding (#1114)
* chore: set up initial async job scaffolding Signed-off-by: Eric Dobroveanu <[email protected]> * chore: address pr comments Signed-off-by: Eric Dobroveanu <[email protected]> --------- Signed-off-by: Eric Dobroveanu <[email protected]>
1 parent 82f8a09 commit 6eaffcf

File tree

8 files changed

+117
-0
lines changed

8 files changed

+117
-0
lines changed

jobs/async-upload/.dockerignore

Whitespace-only changes.

jobs/async-upload/Dockerfile

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
###############################################################################
2+
# Asynchronous Model-Sync Job image for Kubeflow Model Registry (https://github.com/kubeflow/model-registry/issues/1108)
3+
###############################################################################
4+
5+
FROM ubi10/python-312-minimal AS base
6+
7+
# security/env hardening
8+
ENV PYTHONDONTWRITEBYTECODE=1 \
9+
PYTHONUNBUFFERED=1 \
10+
PIP_NO_CACHE_DIR=off \
11+
PIP_DISABLE_PIP_VERSION_CHECK=on
12+
13+
# Create an unprivileged user
14+
RUN addgroup --system --gid 1000 app \
15+
&& adduser --system --uid 1000 --ingroup app --home /app app
16+
17+
WORKDIR /app
18+
19+
# Copy Python dependencies first to leverage layer caching
20+
COPY requirements.txt .
21+
RUN --mount=type=cache,target=/root/.cache \
22+
apt-get update && apt-get install -y --no-install-recommends ca-certificates \
23+
&& pip install --no-cache-dir -r requirements.txt \
24+
&& apt-get purge -y --auto-remove && rm -rf /var/lib/apt/lists/*
25+
26+
# Copy application source
27+
COPY . .
28+
29+
# Switch to the non-root user for the final image layer
30+
USER 1000:1000
31+
32+
# Add an explicit health-check (K8s will surface this in Pod.status)
33+
HEALTHCHECK --interval=30s --timeout=5s --retries=3 \
34+
CMD python -m job.healthcheck
35+
36+
# OCI-recommended labels
37+
ARG VCS_REF=unknown
38+
ARG BUILD_DATE
39+
LABEL org.opencontainers.image.created=$BUILD_DATE \
40+
org.opencontainers.image.revision=$VCS_REF \
41+
org.opencontainers.image.title="Kubeflow Model Registry Async-Upload Job" \
42+
org.opencontainers.image.description="K8s Job image that copies a model between storage back-ends and registers it in Kubeflow Model Registry." \
43+
org.opencontainers.image.url="https://github.com/kubeflow/model-registry" \
44+
org.opencontainers.image.source="https://github.com/kubeflow/model-registry/tree/main/jobs/async-upload" \
45+
org.opencontainers.image.version="0.1.0" \
46+
org.opencontainers.image.licenses="Apache-2.0" \
47+
org.opencontainers.image.authors="Kubeflow Model Registry maintainers"
48+
49+
# The Job controller will pass CLI flags/ENV-vars described in issue #1108.
50+
ENTRYPOINT ["python", "-m", "job.entrypoint"]

jobs/async-upload/README.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Kubeflow Model Registry – Async Upload Job
2+
3+
> Lightweight, non‑root Python Job containerised for **transferring model artefacts** between storage back‑ends (S3, OCI, PVC, …) and registering them in **Kubeflow Model Registry**. Born out of the discussion in [kubeflow/model-registry #1108](https://github.com/kubeflow/model-registry/issues/1108).
4+
5+
---
6+
7+
## Quick start
8+
9+
```bash
10+
# 1 – Build & tag ( reproducible build args are optional )
11+
docker build \
12+
--build-arg VCS_REF=$(git rev-parse --short HEAD) \
13+
--build-arg BUILD_DATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ") \
14+
-t quay.io/<org>/async-upload-job:$(git rev-parse --short HEAD) .
15+
16+
# 2 – Push to your registry
17+
docker push quay.io/<org>/async-upload-job:<tag>
18+
19+
# TODO: Run locally...
20+
```
21+
22+
## References
23+
24+
- Issue thread : [https://github.com/kubeflow/model-registry/issues/1108](https://github.com/kubeflow/model-registry/issues/1108)
25+
- OCI Image Spec : [https://github.com/opencontainers/image-spec](https://github.com/opencontainers/image-spec)
26+
- Kubernetes Pod Security : [https://kubernetes.io/docs/concepts/security/pod-security-standards/](https://kubernetes.io/docs/concepts/security/pod-security-standards/)

jobs/async-upload/job/__init__.py

Whitespace-only changes.

jobs/async-upload/job/entrypoint.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
def main() -> None:
2+
"""
3+
Placeholder for main entrypoint
4+
5+
TODO: Implement the main entrypoint
6+
"""
7+
print("Hello, world!")
8+
9+
10+
if __name__ == "__main__": # pragma: no cover
11+
main()

jobs/async-upload/job/healthcheck.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import sys
2+
3+
4+
def main() -> None:
5+
"""
6+
Placeholder for a healthcheck endpoint for the k8s api server to validate the job is still running
7+
8+
TODO: Implement healthchecks
9+
"""
10+
sys.exit(0)
11+
12+
13+
if __name__ == "__main__": # pragma: no cover
14+
main()

jobs/async-upload/pyproject.toml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
[project]
2+
name = "async-upload"
3+
version = "0.0.1"
4+
description = "Model Registry Job to upload a Model from a source to a destination"
5+
authors = [
6+
{name = "Your Name",email = "[email protected]"}
7+
]
8+
readme = "README.md"
9+
requires-python = ">=3.10"
10+
dependencies = [
11+
]
12+
13+
14+
[build-system]
15+
requires = ["poetry-core>=2.0.0,<3.0.0"]
16+
build-backend = "poetry.core.masonry.api"

jobs/async-upload/requirements.txt

Whitespace-only changes.

0 commit comments

Comments
 (0)