in pkg/crate/build.go [43:143]
func Build(rootFs fs.FS, spec *cratefile.Config) (*Image, error) {
// Check arguments
if spec == nil {
return nil, errors.New("unable to build a crate with nil specification")
}
log.Bg().Info("Extract container ...", zap.String("container", spec.Container.Path))
// Open container file
cf, err := fs.ReadFile(rootFs, spec.Container.Path)
if err != nil {
return nil, fmt.Errorf("unable to open container '%s': %w", spec.Container.Path, err)
}
// Try to load container
c, err := container.Load(io.LimitReader(bytes.NewBuffer(cf), maxContainerSize))
if err != nil {
return nil, fmt.Errorf("unable to load input container '%s': %w", spec.Container.Path, err)
}
// Check container sealing status
if !container.IsSealed(c) {
log.Bg().Info("Sealing container ...", zap.String("container", spec.Container.Path))
// Seal with appropriate algorithm
sc, err := container.Seal(rand.Reader, c, spec.Container.Identities...)
if err != nil {
return nil, fmt.Errorf("unable to seal container '%s': %w", spec.Container.Path, err)
}
log.Bg().Info("Container sealed ...", zap.String("container", spec.Container.Path))
// Replace container instance by the sealed one
c = sc
}
// Prepare config manifest
cfg := schemav1.NewConfig()
cfg.SetContainers([]string{spec.Container.Name})
// Preapre archives
templateArchives := []*TemplateArchive{}
// Create archives
archiveNames := []string{}
for _, arch := range spec.Archives {
// Clean root path
rootPath := strings.TrimPrefix(arch.RootPath, ".")
rootPath = strings.TrimPrefix(rootPath, "/")
// Restrict sub filesystem
subFs, errFs := fs.Sub(rootFs, rootPath)
if errFs != nil {
return nil, fmt.Errorf("unable to restrict to sub-filesystem: %w", errFs)
}
log.Bg().Info("Creating archive ...", zap.String("archive", arch.Name), zap.String("path", arch.RootPath))
// Create tar.gz archive
var buf bytes.Buffer
if err := archive.Create(subFs, &buf,
archive.ExcludeFiles(arch.ExcludeGlob...),
archive.IncludeFiles(arch.IncludeGlob...),
); err != nil {
return nil, fmt.Errorf("unable to create archive '%s': %w", arch.Name, err)
}
// Add archive format suffix
name := arch.Name
if !strings.HasSuffix(name, ".tar.gz") {
name = fmt.Sprintf("%s.tar.gz", arch.Name)
}
// Add to config manifest
archiveNames = append(archiveNames, name)
// Add layer.
templateArchives = append(templateArchives, &TemplateArchive{
Name: name,
Archive: buf.Bytes(),
})
}
// Update config manifest
cfg.SetTemplates(archiveNames)
// Create
res := &Image{
Config: cfg,
Containers: []*SealedContainer{
{
Name: spec.Container.Name,
Container: c,
},
},
TemplateArchives: templateArchives,
}
// No error
return res, nil
}