Add Docker-style image tagging and decouple content / repositories - #425
Add Docker-style image tagging and decouple content / repositories#425chruffins wants to merge 19 commits into
Conversation
8fe5d5f to
6c6cb0f
Compare
-->
✱ stlc build✅ go code · compare
✅ python code · compare
✅ typescript code · compare
Diagnostics: ❗ 0 new / 1 total error, 💡 0 new / 5 total note
Build metadata
This comment is auto-generated by stlc and is kept up to date as you push. |
|
companion PR here: kernel/hypeman-cli#65 |
5fc6e04 to
fe0fa4e
Compare
|
mentioned to assess this directory layout: and if the migration is worth it or if we should stick to existing for now. un-requesting review until pinged again. |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit efe820a. Configure here.
| return os.Rename(diskTempPath, path) | ||
| }); err != nil { | ||
| return fmt.Errorf("install image disk: %w", err) | ||
| } |
There was a problem hiding this comment.
Rootfs install rename can fail
Medium Severity
Converted rootfs is now written under system/builds and moved into images/ with os.Rename. os.Rename cannot cross filesystems, so a split dataDir layout (separate volume or bind-mount for images/) makes every convert fail after a successful export. The temp file is then deleted, so the work is discarded and retry hits the same error.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit efe820a. Configure here.


summary
Kernel browser sessions and app deployments run as VM-backed instances. This PR adds Docker-style local image tagging and separates immutable bootable image content from mutable repository/tag references.
A ready Hypeman image can be retagged and pushed without pulling or reconverting it. One converted rootfs is stored per content digest, while repository tags remain lightweight references. Existing legacy image trees remain readable during the migration.
1. pre-existing flows + new flows
existing pull and lookup flow
new local tagging flow
Example:
Tagging does not pull or reconvert the image. The companion CLI changes are in
kernel/hypeman-cli#65.2. changes to the data model
There is no database schema or migration.
The API adds:
The endpoint returns explicit errors for invalid references, missing sources, and non-ready sources.
The logical ownership model is now:
The existing image metadata format remains compatible. Tags are represented by filesystem references rather than a new database table.
This matches the app platform’s existing deployment identity: deployments retain both an image reference and an image digest. The reference is a mutable lookup name; the digest identifies the immutable image used by the VM.
3. changes to filesystem layout
legacy layout
On macOS, the rootfs uses
rootfs.ext4.content-addressed layout
The content directory owns the converted rootfs. Repository/tag paths are references and do not contain another copy of the image.
Readers support both layouts:
4. why change the filesystem layout
protect the bootable browser artifact
Hypeman converts OCI layers into an EROFS or EXT4 disk that boots the browser VM. That converted disk is the expensive runtime artifact; names such as
chrome:stableand deployment-specific tags are only references to it.Multiple names should not create multiple bootable disks or change the bytes used to start a browser session.
keep app deployment identity immutable
The app platform stores an image digest for deployments and app versions. A deployment must be able to start, roll back, or be recreated from the same digest even after a mutable tag moves forward.
Content-addressed storage makes the digest the local content owner and keeps aliases from creating separate image copies.
support host-local caching
Browser sessions and app invocations may run on different hosts over their lifetimes. A host can receive or prewarm a digest, materialize whatever repository/tag reference it needs, and start the VM from the same cached rootfs.
The host does not need to preserve every repository name that previously referenced the image.
make cleanup and accounting correct
Deleting one tag must not delete content still needed by another tag, app version, browser session, or digest-only reference. Separating content from references lets cleanup retain a digest until its final reference disappears.
Hard-linked aliases can also be counted once by physical inode, so repository aliases do not inflate disk usage.
preserve compatibility and enable promotion
Existing legacy images are readable without an offline migration. Cross-repository tagging promotes legacy content by hard-linking the rootfs into the shared directory, writing shared metadata, atomically installing references, and removing the duplicate legacy tree.
The shared content boundary also provides a clear future home for digest-level prewarming, eviction, verification, replication, backup, and restore.
validation
mkfs.erofs, registry access, and host virtualization supportNote
High Risk
Reworks on-disk image layout, tagging, deletion, and disk accounting—core VM boot artifacts. Dual-layout promotion and shared-content cleanup can leak or drop images if layout selection is wrong.
Overview
Adds Docker-style local tagging so a ready image can be retagged (including across repositories) without pulling or reconverting. New
POST /images/{name}/tagmaps invalid names to 400, missing sources to 404, and non-ready images to 409.Image storage now separates immutable digest content (
images/content/<digest>) from repository/tag references (images/repositories/...). Cross-repo tags promote legacy trees by hard-linking the rootfs, rewriting tags, and removing the duplicate digest directory. Readers keep using a complete legacy image until shared content is ready.Deletes only drop shared content when nothing else references it (other tags, in-flight pulls, or digest-only records). Disk accounting counts hard-linked aliases once.
GetImage/DeleteImagenow honor the requested reference so digest aliases in another repo delete the right tags.Reviewed by Cursor Bugbot for commit efe820a. Bugbot is set up for automated code reviews on this repo. Configure here.