feat(builder): Add rootfs implementation for reading OCI images - #413
feat(builder): Add rootfs implementation for reading OCI images#413craciunoiuc 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
| return nil, fmt.Errorf("could not open flattened rootfs image as filesystem: %w", err) | ||
| } | ||
|
|
||
| f, err := os.CreateTemp("", "unikraft-rootfs-*."+string(opts.Rootfs.Format)) |
There was a problem hiding this comment.
We need to start to think if we want to start moving these image build operations into the local directory
Tmpfs gets really crowded when we chuck so many image artifacts into it
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,
},
}
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>
e7d40aa to
5efd1e1
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