File size: 2,353 Bytes
b727f11
 
 
 
 
 
 
 
 
 
f1b51ae
 
b727f11
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
"""Check every published image layer for private core source or Git metadata."""

import argparse
from pathlib import PurePosixPath
import subprocess
import tarfile


def is_private_path(name, *, empty_file=False):
    parts = PurePosixPath(name).parts
    if PurePosixPath(name).name == "decompile-verify-declarations":
        return True
    if "verifier" in parts:
        return True
    if name.lstrip("./").startswith("home/user/app/core/"):
        return True
    if ".git" in parts:
        # uv creates an empty sdists-v9/.git sentinel to stop build tools from
        # discovering an enclosing repository. It is not repository metadata.
        sentinel = (".cache", "uv", "sdists-v9", ".git")
        if tuple(parts[-4:]) == sentinel and empty_file:
            return False
        return True
    return False


def main():
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("image")
    args = parser.parse_args()
    process = subprocess.Popen(["docker", "image", "save", args.image], stdout=subprocess.PIPE)
    failures, layers = [], 0
    with tarfile.open(fileobj=process.stdout, mode="r|") as archive:
        for member in archive:
            if not member.isfile():
                continue
            # Docker's OCI archive stores filesystem layers as tar blobs.
            if member.name.endswith(".tar") or member.name.startswith("blobs/sha256/"):
                blob = archive.extractfile(member)
                try:
                    with tarfile.open(fileobj=blob, mode="r|*") as layer:
                        layers += 1
                        for item in layer:
                            if is_private_path(item.name, empty_file=item.isfile() and item.size == 0):
                                failures.append(item.name)
                except tarfile.ReadError:
                    # OCI manifests/config blobs are JSON, not filesystem layers.
                    pass
    if process.wait() != 0:
        raise SystemExit("docker image save failed")
    if not layers:
        raise SystemExit("no image filesystem layers were inspected")
    if failures:
        raise SystemExit("private paths found in image layers: " + ", ".join(failures))
    print(f"Inspected {layers} image layers: no private verifier source or Git metadata.")


if __name__ == "__main__":
    main()