Skip to content

Commit

Permalink
converter: support appending files to bootstrap layer
Browse files Browse the repository at this point in the history
Support `AppendFiles` option on converter.Merge method,
`AppendFiles` specifies the files that need to be appended
to the bootstrap layer.

This option allows the user to place some files in the nydus
bootstrap layer, for example, the user can place metadata
info generated at build time, e.g. named `image/metadata.json`.

And this usage does not affect the `image/image.boot` bootstrap
file that is accessed by the nydus runtime.

Signed-off-by: Yan Song <yansong.ys@antgroup.com>
  • Loading branch information
imeoer committed Apr 25, 2024
1 parent 7835988 commit 38134c1
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 29 deletions.
16 changes: 15 additions & 1 deletion pkg/converter/convert_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"github.com/containerd/containerd/archive"
"github.com/containerd/containerd/archive/compression"
"github.com/containerd/containerd/content"
"github.com/containerd/containerd/content/local"
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/images"
"github.com/containerd/containerd/images/converter"
Expand Down Expand Up @@ -624,10 +625,23 @@ func Merge(ctx context.Context, layers []Layer, dest io.Writer, opt MergeOption)
return nil, errors.Wrap(err, "merge bootstrap")
}

bootstrapRa, err := local.OpenReader(targetBootstrapPath)
if err != nil {
return nil, errors.Wrap(err, "open bootstrap reader")
}
defer bootstrapRa.Close()

files := append([]File{
{
Name: EntryBootstrap,
Reader: content.NewReader(bootstrapRa),
Size: bootstrapRa.Size(),
},
}, opt.AppendFiles...)
var rc io.ReadCloser

if opt.WithTar {
rc, err = packToTar(targetBootstrapPath, fmt.Sprintf("image/%s", EntryBootstrap), false)
rc, err = packToTar(files, false)
if err != nil {
return nil, errors.Wrap(err, "pack bootstrap to tar")
}
Expand Down
2 changes: 2 additions & 0 deletions pkg/converter/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,8 @@ type MergeOption struct {
Timeout *time.Duration
// Encrypt encrypts the bootstrap layer if it's specified.
Encrypt Encrypter
// AppendFiles specifies the files that need to be appended to the bootstrap layer.
AppendFiles []File
}

type UnpackOption struct {
Expand Down
49 changes: 21 additions & 28 deletions pkg/converter/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,19 @@ import (
"encoding/json"
"fmt"
"io"
"os"
"path/filepath"

"github.com/containerd/containerd/content"
"github.com/opencontainers/go-digest"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
)

type File struct {
Name string
Reader io.Reader
Size int64
}

type writeCloser struct {
closed bool
io.WriteCloser
Expand Down Expand Up @@ -83,33 +88,21 @@ func newSeekReader(ra io.ReaderAt) *seekReader {
}
}

// packToTar makes .tar(.gz) stream of file named `name` and return reader.
func packToTar(src string, name string, compress bool) (io.ReadCloser, error) {
fi, err := os.Stat(src)
if err != nil {
return nil, err
}

// packToTar packs files to .tar(.gz) stream then return reader.
func packToTar(files []File, compress bool) (io.ReadCloser, error) {

Check failure on line 92 in pkg/converter/utils.go

View workflow job for this annotation

GitHub Actions / Build and Lint

packToTar - result 1 (error) is always nil (unparam)
dirHdr := &tar.Header{
Name: filepath.Dir(name),
Name: "image",
Mode: 0755,
Typeflag: tar.TypeDir,
}

hdr := &tar.Header{
Name: name,
Mode: 0444,
Size: fi.Size(),
}

reader, writer := io.Pipe()

go func() {
// Prepare targz writer
var tw *tar.Writer
var gw *gzip.Writer
var err error
var file *os.File

if compress {
gw = gzip.NewWriter(writer)
Expand Down Expand Up @@ -140,23 +133,23 @@ func packToTar(src string, name string, compress bool) (io.ReadCloser, error) {
writer.CloseWithError(finalErr)
}()

file, err = os.Open(src)
if err != nil {
return
}
defer file.Close()

// Write targz stream
if err = tw.WriteHeader(dirHdr); err != nil {
return
}

if err = tw.WriteHeader(hdr); err != nil {
return
}

if _, err = io.Copy(tw, file); err != nil {
return
for _, file := range files {
hdr := tar.Header{
Name: filepath.Join("image", file.Name),
Mode: 0444,
Size: file.Size,
}
if err = tw.WriteHeader(&hdr); err != nil {
return
}
if _, err = io.Copy(tw, file.Reader); err != nil {
return
}
}
}()

Expand Down

0 comments on commit 38134c1

Please sign in to comment.