mirror of
https://github.com/mudler/luet.git
synced 2025-09-16 07:10:29 +00:00
Generate artifact delta from layer diffs
This commit is contained in:
@@ -15,6 +15,20 @@
|
||||
|
||||
package compiler
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
. "github.com/mudler/luet/pkg/logger"
|
||||
|
||||
"github.com/mudler/luet/pkg/helpers"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type PackageArtifact struct {
|
||||
Path string
|
||||
}
|
||||
@@ -30,3 +44,74 @@ func (a *PackageArtifact) GetPath() string {
|
||||
func (a *PackageArtifact) SetPath(p string) {
|
||||
a.Path = p
|
||||
}
|
||||
|
||||
type CopyJob struct {
|
||||
Src, Dst string
|
||||
}
|
||||
|
||||
func worker(i int, wg *sync.WaitGroup, s <-chan CopyJob) {
|
||||
defer wg.Done()
|
||||
|
||||
for job := range s {
|
||||
Info("#"+strconv.Itoa(i), "copying", job.Src, "to", job.Dst)
|
||||
if dir, err := helpers.IsDirectory(job.Src); err == nil && dir {
|
||||
err = helpers.CopyDir(job.Src, job.Dst)
|
||||
if err != nil {
|
||||
Fatal("Error copying dir", job, err)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if !helpers.Exists(job.Dst) {
|
||||
if err := helpers.CopyFile(job.Src, job.Dst); err != nil {
|
||||
Fatal("Error copying", job, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ExtractArtifactFromDelta extracts deltas from ArtifactLayer from an image in tar format
|
||||
func ExtractArtifactFromDelta(src, dst string, layers []ArtifactLayer, concurrency int, keepPerms bool) (Artifact, error) {
|
||||
|
||||
archive, err := ioutil.TempDir(os.TempDir(), "archive")
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Error met while creating tempdir for archive")
|
||||
}
|
||||
defer os.RemoveAll(archive) // clean up
|
||||
|
||||
if strings.HasSuffix(src, ".tar") {
|
||||
rootfs, err := ioutil.TempDir(os.TempDir(), "rootfs")
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Error met while creating tempdir for rootfs")
|
||||
}
|
||||
defer os.RemoveAll(rootfs) // clean up
|
||||
err = helpers.Untar(src, rootfs, keepPerms)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Error met while unpacking rootfs")
|
||||
}
|
||||
src = rootfs
|
||||
}
|
||||
|
||||
toCopy := make(chan CopyJob)
|
||||
|
||||
var wg = new(sync.WaitGroup)
|
||||
for i := 0; i < concurrency; i++ {
|
||||
wg.Add(1)
|
||||
go worker(i, wg, toCopy)
|
||||
}
|
||||
|
||||
for _, l := range layers {
|
||||
// Consider d.Additions (and d.Changes? - warn at least) only
|
||||
for _, a := range l.Diffs.Additions {
|
||||
toCopy <- CopyJob{Src: filepath.Join(src, a.Name), Dst: filepath.Join(archive, a.Name)}
|
||||
}
|
||||
}
|
||||
close(toCopy)
|
||||
wg.Wait()
|
||||
|
||||
err = helpers.Tar(archive, dst)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Error met while creating package archive")
|
||||
}
|
||||
return NewPackageArtifact(dst), nil
|
||||
}
|
||||
|
Reference in New Issue
Block a user