Skip to content

Commit 803bb00

Browse files
committed
fix(merge): add blob.meta to bootstrap in merge function
Signed-off-by: Fan Shang <[email protected]>
1 parent c9b930c commit 803bb00

File tree

1 file changed

+110
-15
lines changed

1 file changed

+110
-15
lines changed

pkg/converter/convert_unix.go

Lines changed: 110 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -564,12 +564,27 @@ func Merge(ctx context.Context, layers []Layer, dest io.Writer, opt MergeOption)
564564
}
565565
defer os.RemoveAll(workDir)
566566

567-
getBootstrapPath := func(layerIdx int) string {
568-
digestHex := layers[layerIdx].Digest.Hex()
569-
if originalDigest := layers[layerIdx].OriginalDigest; originalDigest != nil {
570-
return filepath.Join(workDir, originalDigest.Hex())
567+
getLayerPath := func(layerIdx int, suffix string) string {
568+
var digestHex string
569+
if suffix == "" && layers[layerIdx].OriginalDigest != nil {
570+
digestHex = layers[layerIdx].OriginalDigest.Hex()
571+
} else {
572+
digestHex = layers[layerIdx].Digest.Hex()
571573
}
572-
return filepath.Join(workDir, digestHex)
574+
return filepath.Join(workDir, digestHex+suffix)
575+
}
576+
577+
unpackLayerEntry := func(layerIdx int, entryName string, filePath string) error {
578+
file, err := os.Create(filePath)
579+
if err != nil {
580+
return errors.Wrapf(err, "create %s file", entryName)
581+
}
582+
defer file.Close()
583+
584+
if _, err := UnpackEntry(layers[layerIdx].ReaderAt, entryName, file); err != nil {
585+
return errors.Wrapf(err, "unpack %s", entryName)
586+
}
587+
return nil
573588
}
574589

575590
eg, _ := errgroup.WithContext(ctx)
@@ -578,7 +593,7 @@ func Merge(ctx context.Context, layers []Layer, dest io.Writer, opt MergeOption)
578593
rafsBlobSizes := []int64{}
579594
rafsBlobTOCDigests := []string{}
580595
for idx := range layers {
581-
sourceBootstrapPaths = append(sourceBootstrapPaths, getBootstrapPath(idx))
596+
sourceBootstrapPaths = append(sourceBootstrapPaths, getLayerPath(idx, ""))
582597
if layers[idx].OriginalDigest != nil {
583598
rafsBlobTOCDigest, err := calcBlobTOCDigest(layers[idx].ReaderAt)
584599
if err != nil {
@@ -588,17 +603,22 @@ func Merge(ctx context.Context, layers []Layer, dest io.Writer, opt MergeOption)
588603
rafsBlobDigests = append(rafsBlobDigests, layers[idx].Digest.Hex())
589604
rafsBlobSizes = append(rafsBlobSizes, layers[idx].ReaderAt.Size())
590605
}
606+
591607
eg.Go(func(idx int) func() error {
592608
return func() error {
593609
// Use the hex hash string of whole tar blob as the bootstrap name.
594-
bootstrap, err := os.Create(getBootstrapPath(idx))
595-
if err != nil {
596-
return errors.Wrap(err, "create source bootstrap")
610+
if err := unpackLayerEntry(idx, EntryBootstrap, getLayerPath(idx, "")); err != nil {
611+
return err
597612
}
598-
defer bootstrap.Close()
599613

600-
if _, err := UnpackEntry(layers[idx].ReaderAt, EntryBootstrap, bootstrap); err != nil {
601-
return errors.Wrap(err, "unpack nydus tar")
614+
if opt.FsVersion == "6" {
615+
if err := unpackLayerEntry(idx, EntryBlobMeta, getLayerPath(idx, ".blob.meta")); err != nil {
616+
fmt.Printf("Warning: Failed to extract blob.meta.header for layer %d: %v\n", idx, err)
617+
}
618+
619+
if err := unpackLayerEntry(idx, EntryBlobMetaHeader, getLayerPath(idx, ".blob.meta.header")); err != nil {
620+
fmt.Printf("Warning: Failed to extract blob.meta.header for layer %d: %v\n", idx, err)
621+
}
602622
}
603623

604624
return nil
@@ -637,13 +657,89 @@ func Merge(ctx context.Context, layers []Layer, dest io.Writer, opt MergeOption)
637657
}
638658
defer bootstrapRa.Close()
639659

640-
files := append([]File{
660+
files := []File{
641661
{
642662
Name: EntryBootstrap,
643663
Reader: content.NewReader(bootstrapRa),
644664
Size: bootstrapRa.Size(),
645665
},
646-
}, opt.AppendFiles...)
666+
}
667+
668+
if opt.FsVersion == "6" {
669+
metaRas := make([]io.Closer, 0, len(layers)*2)
670+
defer func() {
671+
for _, closer := range metaRas {
672+
closer.Close()
673+
}
674+
}()
675+
676+
for idx := range layers {
677+
digestHex := layers[idx].Digest.Hex()
678+
blobMetaPath := getLayerPath(idx, ".blob.meta")
679+
blobMetaHeaderPath := getLayerPath(idx, ".blob.meta.header")
680+
681+
metaContent, err := os.ReadFile(blobMetaPath)
682+
if err != nil {
683+
return nil, errors.Wrap(err, "read blob.meta")
684+
}
685+
686+
headerContent, err := os.ReadFile(blobMetaHeaderPath)
687+
if err != nil {
688+
return nil, errors.Wrap(err, "read blob.meta.header")
689+
}
690+
uncompressedSize := len(metaContent)
691+
alignedUncompressedSize := (uncompressedSize + 4095) &^ 4095
692+
totalSize := alignedUncompressedSize + len(headerContent)
693+
694+
if totalSize == 0 {
695+
fmt.Printf("Warning: blob data for layer %s is empty, skipping\n", digestHex)
696+
}
697+
698+
assembledFileName := fmt.Sprintf("%s.blob.meta", digestHex)
699+
assembledFilePath := filepath.Join(workDir, assembledFileName)
700+
701+
if err := func() error {
702+
f, err := os.Create(assembledFilePath)
703+
if err != nil {
704+
return err
705+
}
706+
defer f.Close()
707+
708+
if _, err := f.Write(metaContent); err != nil {
709+
return err
710+
}
711+
712+
if padding := alignedUncompressedSize - uncompressedSize; padding > 0 {
713+
if _, err := f.Write(make([]byte, padding)); err != nil {
714+
return err
715+
}
716+
}
717+
718+
if _, err := f.Write(headerContent); err != nil {
719+
return err
720+
}
721+
722+
return f.Sync()
723+
}(); err != nil {
724+
return nil, errors.Wrap(err, "write blob meta file")
725+
}
726+
727+
assembledRa, err := local.OpenReader(assembledFilePath)
728+
if err != nil {
729+
return nil, errors.Wrap(err, "open blob meta file")
730+
}
731+
732+
metaRas = append(metaRas, assembledRa)
733+
734+
files = append(files, File{
735+
Name: assembledFileName,
736+
Reader: content.NewReader(assembledRa),
737+
Size: int64(totalSize),
738+
})
739+
}
740+
}
741+
742+
files = append(files, opt.AppendFiles...)
647743
var rc io.ReadCloser
648744

649745
if opt.WithTar {
@@ -661,7 +757,6 @@ func Merge(ctx context.Context, layers []Layer, dest io.Writer, opt MergeOption)
661757
if _, err = io.CopyBuffer(dest, rc, *buffer); err != nil {
662758
return nil, errors.Wrap(err, "copy merged bootstrap")
663759
}
664-
665760
return blobDigests, nil
666761
}
667762

0 commit comments

Comments
 (0)