Skip to content

Commit c0844d0

Browse files
committed
fix: support OCI images (wsl and podman)
1 parent b62881e commit c0844d0

2 files changed

Lines changed: 44 additions & 42 deletions

File tree

ddiff.py

Lines changed: 41 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,9 @@
3535
ddiff_container_name = os.getenv("DDIFF_CONTAINER_NAME", "ddiff-registry")
3636
ddiff_register_volume = os.getenv("DDIFF_REGISTRY_VOLUME")
3737
ddiff_disable_repository = os.getenv("DDIFF_DISABLE_RESPOSITORY", False)
38-
ddiff_force_skopeo = os.getenv("DDIFF_FORCE_SKOPEO", "").lower() in ["1", "true", "yes", "on"]
3938
ddiff_force_podman = os.getenv("DDIFF_FORCE_PODMAN", "").lower() in ["1", "true", "yes", "on"]
4039

4140
container_runtime = "docker"
42-
container_transport = "docker-daemon"
4341
push_pull_with_skopeo = False
4442

4543
def print_debug(*args):
@@ -50,8 +48,11 @@ def print_error(*args):
5048
raise RuntimeError
5149

5250
def run_command(cmd, capture_output=False):
53-
result = subprocess.run(cmd, shell=True, text=True, capture_output=capture_output)
54-
return result.stdout.strip() if capture_output else None
51+
try:
52+
result = subprocess.run(cmd, shell=True, text=True, capture_output=capture_output, check=True)
53+
return result.stdout.strip() if capture_output else None
54+
except subprocess.CalledProcessError as e:
55+
print_error(f"Command failed: {cmd}\nExit code: {e.returncode}")
5556

5657
# def get_registry_info():
5758
# cmd = f"docker inspect --format '{{{{range .Mounts}}}}{{{{if eq .Type \"bind\"}}}}{{{{println .Source}}}}{{{{end}}}}{{{{end}}}}' {ddiff_container_name}"
@@ -69,8 +70,11 @@ def _prepare_tag(tag):
6970
return tag
7071

7172
def _request_manifest(tag):
72-
repo, version_tag = tag.split(":")
73-
manifest_url = f"{ddiff_url}/v2/{repo}/manifests/{version_tag}"
73+
if "@" in tag: # For OCI images
74+
repo, reference = tag.split("@", 1)
75+
else: # For docker v2 images
76+
repo, reference = tag.split(":", 1)
77+
manifest_url = f"{ddiff_url}/v2/{repo}/manifests/{reference}"
7478

7579
req = urllib.request.Request(manifest_url)
7680
req.add_header("Accept", ACCEPT_MANIFEST_TYPES)
@@ -203,16 +207,24 @@ def run_registry():
203207
cmd = f"{container_runtime} run -it -d -p{ddiff_port}:5000 {volume_arg} --name {ddiff_container_name}{tls_verify_flag} registry:2.8.3"
204208
run_command(cmd)
205209

210+
def _skopeo_source_ref(host_tag):
211+
"""Return the correct skopeo source transport:reference for Podman."""
212+
# Podman stores short names under the localhost/ prefix in containers-storage
213+
if not host_tag.startswith("localhost/"):
214+
host_tag = f"localhost/{host_tag}"
215+
return f"containers-storage:{host_tag}"
216+
206217
def push_images(tags):
207218
print_debug("Pushing to the registry...")
208219
for host_tag in tags:
209220
registry_tag = f"{ddiff_url_base}/{_prepare_tag(host_tag)}"
210221
if push_pull_with_skopeo:
211222
run_command(
212223
f"skopeo copy --dest-tls-verify=false --format=v2s2 "
213-
f"{container_transport}:{host_tag} docker://{registry_tag}"
224+
f"{_skopeo_source_ref(host_tag)} docker://{registry_tag}"
214225
)
215226
else:
227+
assert container_runtime == "docker", "Only docker is supported without skopeo"
216228
run_command(f"docker tag {host_tag} {registry_tag}")
217229
run_command(f"docker push {registry_tag}")
218230
run_command(f"docker rmi {registry_tag}")
@@ -225,9 +237,10 @@ def pull_images(tags):
225237
if push_pull_with_skopeo:
226238
run_command(
227239
f"skopeo copy --src-tls-verify=false "
228-
f"docker://{registry_tag} {container_transport}:{host_tag}"
240+
f"docker://{registry_tag} {_skopeo_source_ref(host_tag)}"
229241
)
230242
else:
243+
assert container_runtime == "docker", "Only docker is supported without skopeo"
231244
run_command(f"docker pull {registry_tag}")
232245
run_command(f"docker tag {registry_tag} {host_tag}")
233246
run_command(f"docker rmi {registry_tag}")
@@ -323,12 +336,19 @@ def load_image(base_tag, image_tarball):
323336

324337
shutil.rmtree(input_dir)
325338

326-
if "localhost" in ddiff_url:
339+
if "localhost" in ddiff_url:
327340
print_debug("Pulling image from the registry...")
328341
registry_tag = f"{ddiff_url_base}/{target_tag}"
329-
run_command(f"docker pull {registry_tag}")
330-
run_command(f"docker tag {registry_tag} {target_tag}")
331-
run_command(f"docker rmi {registry_tag}")
342+
if push_pull_with_skopeo:
343+
run_command(
344+
f"skopeo copy --src-tls-verify=false "
345+
f"docker://{registry_tag} {_skopeo_source_ref(target_tag)}"
346+
)
347+
else:
348+
assert container_runtime == "docker", "Only docker is supported without skopeo"
349+
run_command(f"docker pull {registry_tag}")
350+
run_command(f"docker tag {registry_tag} {target_tag}")
351+
run_command(f"docker rmi {registry_tag}")
332352
print_debug(f"The image {target_tag} is sucessfully pulled on the host.\nIf you will not inherit {target_tag} in future, you can delete the image.")
333353
else:
334354
print_debug(f"The image {target_tag} is sucessfully pulled on the host.")
@@ -345,8 +365,8 @@ def build_image(build_args):
345365
if arg == "--diff":
346366
do_diff = True
347367
build_args[i] = ""
348-
if container_runtime == "docker":
349-
build_args.append("--provenance=false")
368+
# if container_runtime == "docker":
369+
# build_args.append("--provenance=false")
350370
assert not target_tag is None
351371

352372
# Fall back to docker build
@@ -369,7 +389,6 @@ def list_blobs(tag):
369389
# Download manifest
370390
manifest, _ = _request_manifest(tag)
371391

372-
373392
# Check blobs
374393
blobs = _parse_blob_list(manifest)
375394
print("=== blobs ===")
@@ -384,26 +403,22 @@ def list_blobs(tag):
384403
sys.exit(0)
385404

386405
container_runtime = "podman"
387-
container_transport = "containers-storage"
388406
push_pull_with_skopeo = True
389407
if ddiff_force_podman:
390408
print_debug("DDIFF_FORCE_PODMAN is enabled. Switching to podman mode.")
391409
else:
392410
print_debug("Docker command not found. Switching to podman mode.")
393-
elif ddiff_force_skopeo:
394-
push_pull_with_skopeo = True
395-
print_debug("DDIFF_FORCE_SKOPEO is enabled. Using skopeo for push/pull.")
396411

397412
if len(sys.argv) < 2 or not sys.argv[1] in ["server", "push", "pull", "diff", "load", "build", "list"]:
398413
print("Usage: ddiff [command] [args...]")
399414
print("Commands:")
400-
print(" server - Run the registry server (set DDIFF_REGISTRY_VOLUME)")
401-
print(" push <tag 1> ... <tag n> - Push one or more images")
402-
print(" pull <tag 1> ... <tag n> - Pull one or more images")
403-
print(" diff <base> <target> - Diff the target image from the base image")
404-
print(" load <tar file> - Load the target image from diff file")
405-
print(" build <args> - Build the image and diff from base (FROM ...)")
406-
print(" list <tag> - List up blobs of the given image")
415+
print(" server - Run the registry server (set DDIFF_REGISTRY_VOLUME)")
416+
print(" push <tag 1> ... <tag n> - Push one or more images")
417+
print(" pull <tag 1> ... <tag n> - Pull one or more images")
418+
print(" diff <base> <target> - Diff the target image from the base image")
419+
print(" load (<base tag>) <tar file> - Load the target image from diff file")
420+
print(" build <args> - Build the image and diff from base (FROM ...)")
421+
print(" list <tag> - List up blobs of the given image")
407422
sys.exit(1)
408423

409424
command = sys.argv[1]

test/test_ddiff_backends.sh

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -213,17 +213,7 @@ run_docker_mode() {
213213
python3 curl docker
214214
}
215215

216-
# Test 2: docker-skopeo mode
217-
# Inject: DDIFF_FORCE_SKOPEO=1
218-
# Expect: ddiff log contains "DDIFF_FORCE_SKOPEO is enabled"
219-
run_docker_skopeo_mode() {
220-
run_case \
221-
"docker-skopeo" \
222-
"docker" \
223-
"DDIFF_FORCE_SKOPEO" "1" "DDIFF_FORCE_SKOPEO is enabled" \
224-
5611 5612 \
225-
python3 curl docker skopeo
226-
}
216+
227217

228218
# Test 3: podman mode
229219
# Inject: DDIFF_FORCE_PODMAN=1
@@ -240,19 +230,16 @@ run_podman_mode() {
240230
run_selected_cases() {
241231
local target="$1"
242232
case "$target" in
243-
all|docker|docker-skopeo|podman) ;;
233+
all|docker|podman) ;;
244234
*)
245-
echo "Usage: $0 [all|docker|docker-skopeo|podman]"
235+
echo "Usage: $0 [all|docker|podman]"
246236
exit 2
247237
;;
248238
esac
249239

250240
if [[ "$target" == "all" || "$target" == "docker" ]]; then
251241
run_docker_mode
252242
fi
253-
if [[ "$target" == "all" || "$target" == "docker-skopeo" ]]; then
254-
run_docker_skopeo_mode
255-
fi
256243
if [[ "$target" == "all" || "$target" == "podman" ]]; then
257244
run_podman_mode
258245
fi

0 commit comments

Comments
 (0)