imagedeck - a catalog for a whole ISO library
=============================================
Techlosoft "ISO + Boot Workshop" line, Team variant.
A team file share accumulates dozens of .iso files with names like
final_v2_REAL.iso, ubuntu_backup_DO_NOT_DELETE.iso and copy_of_copy.iso.
imagedeck indexes the entire folder - path, size, mtime, SHA-256, ISO 9660
volume identifier and El Torito bootability - into a persistent JSON catalog,
then answers the questions that only exist at library scale:
* which of these are byte-identical duplicates wasting disk?
* which have changed, appeared or vanished since the last scan?
* which of them are not bootable?
* is this new download something we already have, and under what name?
A single-image inspector cannot answer any of those. That is the whole point
of this tool.
QUICK START
-----------
imagedeck index /srv/isos --catalog isos.json --recursive
imagedeck list --catalog isos.json
imagedeck duplicates --catalog isos.json
imagedeck diff --catalog isos.json /srv/isos
imagedeck find --catalog isos.json --file ~/Downloads/final_v2_REAL.iso
COMMANDS
--------
index
--catalog FILE [--recursive] [--json]
Scan every *.iso under and write the catalog. Records path, size,
mtime, SHA-256, volume identifier, system identifier, El Torito boot
record (present / absent, platform, boot catalog LBA, per-entry detail)
and whether the volume declares more data than the file actually holds.
A file that cannot be parsed is listed under SKIPPED and the scan
continues with the next file; a bad file never aborts the run.
list --catalog FILE [--bootable | --unbootable] [--json]
Show the catalogued library, optionally filtered by bootability.
--bootable and --unbootable are complementary and mutually exclusive.
duplicates --catalog FILE [--json]
Group images by SHA-256. Only byte-identical files are grouped; images
that merely share a size or a volume identifier are never grouped.
Reports each group, its members and (copies - 1) x size reclaimable
bytes, plus the library-wide total.
diff --catalog FILE [--json]
Compare the catalog against as it is right now and report ADDED,
REMOVED and CHANGED (same path, different SHA-256). The scan mirrors the
--recursive setting recorded in the catalog. Exits 2 if anything
differs, 0 if nothing does, so it drops straight into a cron job or a
CI check.
find --catalog FILE (--sha256 H | --file F) [--json]
"Do we already have this?" Either look up a known 64-character hex
digest, or hand it a candidate file: imagedeck hashes the file and tells
you whether that content is already in the library and under which
name(s).
help, -h, --help
Usage. Exits 0. A bad invocation prints usage to stderr and exits 1.
Flags may appear before or after positional arguments.
EXIT CODES
----------
0 success (for diff: the directory matches the catalog)
1 error
2 diff only: the directory differs from the catalog
WHAT IS IMPLEMENTED
-------------------
* ISO 9660 Primary Volume Descriptor parsing from raw bytes: the CD001
magic and descriptor set scan starting at sector 16 (offset 32768), the
32-byte space-padded volume identifier, the system identifier, logical
block size and volume space size.
* El Torito detection: the Boot Record Volume Descriptor at sector 17
(offset 34816) with boot system identifier "EL TORITO SPECIFICATION", the
boot catalog pointer at offset 0x47, the validation entry (0x55AA key),
the default boot entry, and section headers (0x90/0x91) with their
section entries. Platform is reported as BIOS, UEFI, both, or none, and
per-entry media type / load segment / sector count / load RBA are stored
in the catalog.
* Whole-file SHA-256 of every image, streamed in 1 MiB chunks.
* Truncation flagging: an image whose volume space size x block size
exceeds the file size is reported as TRUNCATED (an interrupted download)
while still being catalogued.
* A persistent JSON catalog, written atomically (temp file + rename) and
versioned, that survives between runs.
* Machine-readable --json on index, list, duplicates, diff and find.
* Recursive or single-level directory scanning.
* Go standard library only. No third-party dependencies, no cgo, no
external helper binaries, nothing mounted.
READ-ONLY GUARANTEE
-------------------
Disc images are opened with a plain read-only open and are only ever read.
The catalog file named by --catalog is the only thing imagedeck writes, and
it is written via a temporary file in the same directory followed by a
rename, so an interrupted run cannot leave a half-written catalog. Nothing
is ever written into the scanned directory unless you deliberately point
--catalog inside it.
WHAT IS *NOT* IMPLEMENTED
-------------------------
* No Joliet and no Rock Ridge. Only plain ISO 9660 fields are read, so the
volume identifier is the ISO 9660 one; long/Unicode names and their
supplementary volume descriptors are ignored.
* No file extraction and no directory listing inside an image. imagedeck
never walks the on-disc directory records - that is ISOPilot's job.
* No media writing, no USB creation, no burning, no mounting, no virtual
drives, no ISO editing or authoring. Writing bootable media is on
RescueUSB's roadmap, not here.
* No verification of an image against a vendor-published checksum. The
catalog records what the bytes hash to; it has no idea what they were
supposed to hash to.
* No UDF, no hybrid-partition-table analysis, no MBR/GPT inspection, no
checking that an El Torito boot image actually boots. Bootability here
means "a valid El Torito boot record and catalog exist and mark at least
one entry bootable" - it is a structural claim, not a runtime test.
* The catalog is a plain local file. There is no sharing, no locking, no
concurrency control, no server and no merge. Two people indexing the same
catalog path at the same time will have the last writer win.
* Only files whose name ends in .iso (any case) are considered. An image
named .img or .bin is not picked up.
* Symlinks are not followed as directories and non-regular files are
skipped. Very large libraries are hashed serially, single-threaded.
ROADMAP
-------
1. A shared team catalog service, so one indexed library is visible to the
whole team, with locking, per-user history and an audit trail of who
added or replaced which image - replacing today's single local file.
2. Joliet and Rock Ridge support, so the catalog can record the long
Unicode volume and file names modern images actually ship with.
3. Automatic checksum verification against vendor-published hashes: fetch
the distributor's SHA256SUMS, match catalogued images against it, and
flag any image in the library that does not match its official digest.
CATALOG FORMAT
--------------
A single JSON object: tool, catalog_version, root, recursive, indexed
(RFC3339 UTC), images, entries[] and failures[]. Each entry carries path,
size, modified, sha256, volume_id, system_id, declared_bytes, truncated,
bootable, boot_platform, boot_catalog_lba and boot_entries[]. Paths are
absolute. The format is versioned; a file without "tool": "imagedeck" is
rejected rather than misread.
BUILDING
--------
go build -o imagedeck .
Standard library only, so this works with GOPROXY=off and no module cache.
Prebuilt binaries are in dist/ for windows-amd64, darwin-arm64,
darwin-amd64 and linux-amd64.