Add -l/--list-images to discover OCI archives in a directory

list_oci_images() (src/oci_image.cpp) scans a directory non-recursively
for *.tar/*.tar.* files and, for each one that's a valid OCI Image
Layout archive, derives a name:tag from its index.json manifest
annotations -- io.containerd.image.name if present (a full reference),
else org.opencontainers.image.ref.name (conventionally just a bare
tag for skopeo/podman-produced archives). Falls back to the archive's
filename (.tar and any compression suffix stripped) for the name and
"latest" for the tag. Files that aren't OCI archives are skipped
quietly, since a directory scan is expected to hit unrelated tars.

-l/--list-images <directory> wires this into the CLI, printing
"name:tag<TAB>filename" per image. This is also why --log-level lost
its short form last session: -l needed to be free for this.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-20 15:06:32 +00:00
parent 529a96c89c
commit 94ae5b36a2
4 changed files with 178 additions and 11 deletions
+15
View File
@@ -42,3 +42,18 @@ bool extract_blob_to_file(const std::filesystem::path& tar_path,
// Strips the "sha256:" algorithm prefix from a digest string, e.g.
// "sha256:abcd" -> "abcd". Returns the input unchanged if there is no such prefix.
std::string oci_digest_hex(std::string_view digest);
struct OciImageRef {
std::string name;
std::string tag;
std::filesystem::path path; // the archive file this was found in
};
// Scans `dir` (non-recursively) for files matching *.tar or *.tar.*, and for each one
// that's a valid OCI Image Layout archive, determines an image name/tag from its
// index.json manifest annotations (io.containerd.image.name or
// org.opencontainers.image.ref.name), falling back to the archive's filename (with
// .tar and any compression suffix stripped) for the name and "latest" for the tag.
// Files that aren't valid OCI archives are silently skipped. Returns nullopt if `dir`
// isn't a readable directory; an empty vector is a valid result (nothing matched).
std::optional<std::vector<OciImageRef>> list_oci_images(const std::filesystem::path& dir);