Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

skopeo end-to-end scenario #2

Merged
merged 1 commit into from
Dec 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
9 changes: 8 additions & 1 deletion .github/workflows/e2e.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ on:

jobs:
e2e-skopeo:
name: E2E using CNCF Distribution Registry
name: E2E using Skopeo
runs-on: ubuntu-24.04
steps:
- name: Checkout repository
Expand All @@ -27,6 +27,13 @@ jobs:
- name: Install dependencies
run: |
make install
- name: Start Kind Cluster
uses: helm/kind-action@v1
with:
cluster_name: kind
- name: Start distribution-registry
run: |
./e2e/deploy_distribution_registry.sh
- name: Run E2E tests
run: |
make test-e2e-skopeo
17 changes: 17 additions & 0 deletions e2e/deploy_distribution_registry.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/bin/bash

SCRIPT_DIR="$(dirname "$(realpath "$BASH_SOURCE")")"
set -e

kubectl apply -f "${SCRIPT_DIR}/distribution-registry/"

echo "Waiting for Deployment..."
kubectl wait --for=condition=available deployment/distribution-registry-test-deployment --timeout=5m
kubectl logs deployment/distribution-registry-test-deployment
echo "Deployment looks ready."

echo "Starting port-forward..."
kubectl port-forward service/distribution-registry-test-service 5001:5001 &
PID=$!
sleep 2
echo "I have launched port-forward in background with: $PID."
59 changes: 59 additions & 0 deletions e2e/distribution-registry/distribution-registry.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: distribution-registry-test-deployment
labels:
app: distribution-registry-test
spec:
replicas: 1
selector:
matchLabels:
app: distribution-registry-test
template:
metadata:
labels:
app: distribution-registry-test
spec:
containers:
- name: distribution-registry-test
image: docker.io/library/registry:2
args:
- /etc/docker/registry/config.yml
env:
- name: REGISTRY_HTTP_ADDR
value: 0.0.0.0:5001
ports:
- containerPort: 5001
volumeMounts:
- mountPath: /var/lib/registry
name: distribution-registry-storage
volumes:
- name: distribution-registry-storage
persistentVolumeClaim:
claimName: distribution-registry-pvc
---
apiVersion: v1
kind: Service
metadata:
name: distribution-registry-test-service
labels:
app: distribution-registry-test
spec:
selector:
app: distribution-registry-test
ports:
- protocol: TCP
port: 5001
targetPort: 5001
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: distribution-registry-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 100Mi
7 changes: 7 additions & 0 deletions olot/backend/skopeo.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,14 @@
def is_skopeo() -> bool :
return shutil.which("skopeo") is not None


def skopeo_pull(base_image: str, dest: typing.Union[str, os.PathLike]):
if isinstance(dest, os.PathLike):
dest = str(dest)
return subprocess.run(["skopeo", "copy", "--multi-arch", "all", "docker://"+base_image, "oci:"+dest+":latest"], check=True)


def skopeo_push(src: typing.Union[str, os.PathLike], oci_ref: str):
if isinstance(src, os.PathLike):
src = str(src)
return subprocess.run(["skopeo", "copy", "--multi-arch", "all", "--dest-tls-verify=false", "--dest-no-creds", "oci:"+src+":latest", "docker://"+oci_ref], check=True)
214 changes: 213 additions & 1 deletion poetry.lock

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,32 @@ description = "oci layers on top"
authors = ["tarilabs <[email protected]>"]
readme = "README.md"


[tool.poetry.dependencies]
python = "^3.9"
click = "^8.1.7"
pydantic = "^2.10.3"


[tool.poetry.scripts]
olot = "olot.cli:cli"


[tool.poetry.group.test.dependencies]
pytest = "^8.3.4"


[tool.pytest.ini_options]
markers = [
"e2e_skopeo: end-to-end testing with skopeo",
]


[tool.poetry.group.dev.dependencies]
datamodel-code-generator = "^0.26.3"
ruff = "^0.6.1"
mypy = "^1.11.1"
docker = "^7.1.0"


[build-system]
Expand Down
40 changes: 37 additions & 3 deletions tests/backend/test_skopeo.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@

import os
import subprocess
import docker # type: ignore
from pathlib import Path
import pytest
from olot.backend.skopeo import is_skopeo, skopeo_pull
from olot.basics import check_ocilayout, read_ocilayout_root_index
from olot.backend.skopeo import is_skopeo, skopeo_pull, skopeo_push
from olot.basics import check_ocilayout, oci_layers_on_top, read_ocilayout_root_index

@pytest.mark.e2e_skopeo
def test_is_skopeo():
Expand All @@ -24,3 +27,34 @@ def test_skopeo_pull(tmp_path):
assert manifest0.digest == "sha256:d437889e826ecce2116ac711469bd09b1bb3c64d45055cbf23a6f8f3db223b8b"
assert manifest0.size == 491


@pytest.mark.e2e_skopeo
def test_skopeo_scenario(tmp_path):
"""Test skopeo with an end-to-end scenario
"""
skopeo_pull("quay.io/mmortari/hello-world-wait", tmp_path)
model_joblib = Path(__file__).parent / ".." / "data" / "model.joblib"
model_files = [
model_joblib,
Path(__file__).parent / ".." / "data" / "hello.md",
]
oci_layers_on_top(tmp_path, model_files)
skopeo_push(tmp_path, "localhost:5001/nstestorg/modelcar")

# show what has been copied in Container Registry
subprocess.run(["skopeo","list-tags","--tls-verify=false","docker://localhost:5001/nstestorg/modelcar"], check=True)

# copy from Container Registry to Docker daemon for local running the modelcar as-is
result = subprocess.run("skopeo inspect --tls-verify=false --raw docker://localhost:5001/nstestorg/modelcar | jq -r '.manifests[] | select(.platform.architecture == \"amd64\") | .digest'", shell=True, text=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
assert result.returncode == 0
digest = result.stdout.strip()
print(digest)
# use by convention the linux/amd64
subprocess.run(["skopeo", "copy", "--src-tls-verify=false", f"docker://localhost:5001/nstestorg/modelcar@{digest}", "docker-daemon:localhost:5001/nstestorg/modelcar:latest"], check=True)
client = docker.from_env()
container = client.containers.run("localhost:5001/nstestorg/modelcar", detach=True)
print(container.logs())
_, stat = container.get_archive('/models/model.joblib')
print(str(stat["size"]))
# assert the model.joblib from the KServe modelcar is in expected location (above) and expected size
assert stat["size"] == os.stat(model_joblib).st_size
Loading