From 9fe92bba9c73fb6674a28b571a639da3579a0555 Mon Sep 17 00:00:00 2001 From: Amelia Crate Date: Tue, 5 May 2026 15:57:40 -0500 Subject: [PATCH] cpio: add FromLayers for multi-layer CPIO archives Extract recordsFromLayer helper and add FromLayers function that converts multiple container layers into a single CPIO archive with a shared dedup writer. Co-Authored-By: Claude Opus 4.6 (1M context) --- pkg/cpio/layer.go | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/pkg/cpio/layer.go b/pkg/cpio/layer.go index 828c522ca..e99f2ad5d 100644 --- a/pkg/cpio/layer.go +++ b/pkg/cpio/layer.go @@ -26,6 +26,24 @@ import ( // FromLayer converts a container layer to CPIO format. func FromLayer(layer v1.Layer, dest io.Writer) error { + return FromLayers([]v1.Layer{layer}, dest) +} + +// FromLayers converts multiple container layers to a single CPIO archive. +func FromLayers(layers []v1.Layer, dest io.Writer) error { + w := cpio.NewDedupWriter(cpio.Newc.Writer(dest)) + + for _, layer := range layers { + if err := recordsFromLayer(layer, w); err != nil { + return err + } + } + + return w.WriteRecord(cpio.TrailerRecord) +} + +// recordsFromLayer reads tar entries from a layer and writes them as CPIO records. +func recordsFromLayer(layer v1.Layer, w cpio.RecordWriter) error { // Open the filesystem layer to walk through the file. u, err := layer.Uncompressed() if err != nil { @@ -35,8 +53,6 @@ func FromLayer(layer v1.Layer, dest io.Writer) error { tarReader := tar.NewReader(u) - w := cpio.NewDedupWriter(cpio.Newc.Writer(dest)) - // Iterate through the tar archive entries for { header, err := tarReader.Next() @@ -95,5 +111,5 @@ func FromLayer(layer v1.Layer, dest io.Writer) error { } } - return w.WriteRecord(cpio.TrailerRecord) + return nil }