feat(builder): Add rootfs implementation for reading OCI images - #413
craciunoiuc wants to merge 1 commit into
Conversation
|
let me know if these single use functions you want to inline I found them significant enough to keep separate for now |
There was a problem hiding this comment.
Pull request overview
Adds support in the builder to treat OCI image references (registry, OCI layout, OCI archive) as rootfs sources, including logic to unpack regular OCI layers into a rootfs and to use a Unikraft-specific initrd component when present.
Changes:
- Detect OCI rootfs sources via URI schemes and route
BuildRootfsto a new OCI implementation. - Implement
buildRootfsOCIto load OCI images per requested platform, flatten layers into a directory, and package into CPIO/EROFS. - Update kraftfile-to-buildopts translation and expand unit/integration-style tests for OCI sources.
Reviewed changes
Copilot reviewed 6 out of 7 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| internal/builder/rootfs.go | Adds OCI source detection + buildRootfsOCI (load, platform match, layer flatten, repack). |
| internal/builder/rootfs_test.go | Adds DetectSourceType tests for OCI schemes and integration-style rootfs OCI tests. |
| internal/builder/rootfs_oci_test.go | Adds helpers to generate local OCI archives used by tests. |
| internal/builder/kraftfile.go | Avoids filepath-joining when rootfs/ROM source is an OCI reference or explicitly typed OCI. |
| internal/builder/kraftfile_test.go | Adds coverage for OCI paths/types in kraftfile-to-buildopts conversion. |
| go.mod | Pulls in new (indirect) deps required by containerd/v2 usage. |
| go.sum | Updates sums for newly introduced transitive dependencies. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
90f96a2 to
ae59715
Compare
c3ae0df to
fe4bd3f
Compare
4ba3dbf to
e7d40aa
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.
Suppressed comments (2)
internal/builder/rootfs.go:57
cfg.Labels = opts.Labelsoverwrites any labels coming from the base image config even whenopts.Labelsisnil/unset, which loses inherited labels for OCI-rootfs builds (and any other path that usesapplyConfigOverrides). Consider only overriding labels when the caller actually provided them (e.g.,if opts.Labels != nil { ... }), or merge maps so explicitly-provided keys override while preserving the rest.
func applyConfigOverrides(base ocispec.ImageConfig, opts BuildOpts) ocispec.ImageConfig {
cfg := base
if opts.Cmd != nil {
cfg.Cmd = opts.Cmd
}
if opts.Env != nil {
env := make([]string, 0, len(opts.Env)+len(cfg.Env))
for _, kv := range opts.Env {
env = append(env, fmt.Sprintf("%s=%s", kv.Key, kv.Value))
}
cfg.Env = append(env, cfg.Env...)
}
cfg.Labels = opts.Labels
return cfg
}
internal/builder/rootfs_oci_test.go:90
- In OCI image config,
RootFS.DiffIDsare expected to be the digests of the uncompressed layer tar streams (diffIDs), while the manifest layer descriptors typically use the digest of the (often compressed) blob. HerediffIDsare derived fromdesc.Digest(fromtarGzipLayer), which makes the fixture OCI config non-spec-compliant and could break consumers that validate diffIDs. Consider computing diffIDs from the uncompressed tar bytes (or streaming hasher before gzip) while keepingdesc.Digestfor the compressed blob.
diffIDs := make([]digest.Digest, 0, len(layerDescs))
for _, desc := range layerDescs {
diffIDs = append(diffIDs, desc.Digest)
}
config := ocispec.Image{
Platform: ocispec.Platform{
Architecture: "amd64",
OS: "linux",
},
Config: ocispec.ImageConfig{
Cmd: []string{"/bin/sh"},
},
RootFS: ocispec.RootFS{
Type: "layers",
DiffIDs: diffIDs,
},
}
e7d40aa to
5efd1e1
Compare
5efd1e1 to
2205c26
Compare
|
Code changed quite a bit cause there were 80 commits merged since I last touched this. |
9428442 to
f8d3856
Compare
There was a problem hiding this comment.
🟡 Changes recommended
There are a couple of concrete correctness/UX issues in the new shared helper logic (label override semantics and OCI source conflict validation) that should be addressed before approval.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
- Files reviewed: 7/8 changed files
- Comments generated: 2
- Review effort level: Lite
craciunoiuc
left a comment
There was a problem hiding this comment.
Comment removal comments
36f9018 to
871b81c
Compare
| // the layers and that the result is re-packaged into the requested rootfs | ||
| // format. | ||
| func TestRootfsOCIRegularImageIntegration(t *testing.T) { | ||
| const ref = "index.docker.io/library/hello-world:latest" |
There was a problem hiding this comment.
Four integration tests now pull hello-world from Docker Hub anonymously, which is rate limited per-IP and will flake in CI eventually.
suggestion: Maybe we should build an image using SharedImage for this? Then it's on index.unikraft.io with no rate limits.
There was a problem hiding this comment.
There was a problem hiding this comment.
alternatively 4.18 which is unchanged since 2024
There was a problem hiding this comment.
Why can't we mirror it temporarily? And just delete it? Why does it need to be standard?
I ideally don't want dependencies on ye olde kraftkit stuff.
There was a problem hiding this comment.
(It's actually a build of the go bindings for using the xen xl library 🤓 )
Ok, but then where would that sit? A new project? I currently know only of the kraftkit.sh where we put regular docker images (note: there are not the user/ukc projects)
Should we create a new one cli? or?
871b81c to
b642075
Compare
Uses buildkit to download and use OCI images. Works with both regular images, and Unikraft images. Unikraft images have their rootfs already packaged so we fast forward. Signed-off-by: Cezar Craciunoiu <cezar@unikraft.io>
b642075 to
a8fe5b5
Compare

Tested work and it seemed fine. Pasting again uses:
Case 1:
Case 2:
You can use these prefixes:oci://,oci-layout://,oci-archive://taken fromimage-spec:We decided to use only the oci type variable.
Also needs another bump to the gomod.Closes: TOOL-1073
Depends-on: unikraft-cloud/x#400