mirror of
https://github.com/mudler/luet.git
synced 2025-09-03 00:06:36 +00:00
Refactor compiler and annotate buildoptions into compiler metadata
This allows to later pick up values used during build of each package
This commit is contained in:
@@ -19,6 +19,7 @@ import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
|
||||
"regexp"
|
||||
@@ -27,13 +28,14 @@ import (
|
||||
"time"
|
||||
|
||||
bus "github.com/mudler/luet/pkg/bus"
|
||||
yaml "gopkg.in/yaml.v2"
|
||||
|
||||
"github.com/mudler/luet/pkg/compiler/backend"
|
||||
artifact "github.com/mudler/luet/pkg/compiler/types/artifact"
|
||||
"github.com/mudler/luet/pkg/compiler/types/options"
|
||||
compilerspec "github.com/mudler/luet/pkg/compiler/types/spec"
|
||||
"github.com/mudler/luet/pkg/helpers"
|
||||
. "github.com/mudler/luet/pkg/logger"
|
||||
pkg "github.com/mudler/luet/pkg/package"
|
||||
"github.com/mudler/luet/pkg/solver"
|
||||
"github.com/mudler/luet/pkg/tree"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
@@ -41,63 +43,55 @@ const BuildFile = "build.yaml"
|
||||
const DefinitionFile = "definition.yaml"
|
||||
const CollectionFile = "collection.yaml"
|
||||
|
||||
type LuetCompiler struct {
|
||||
*tree.CompilerRecipe
|
||||
Backend CompilerBackend
|
||||
Database pkg.PackageDatabase
|
||||
PushImageRepository string
|
||||
PullImageRepository []string
|
||||
type ArtifactIndex []*artifact.PackageArtifact
|
||||
|
||||
PullFirst, KeepImg, Clean bool
|
||||
Concurrency int
|
||||
CompressionType CompressionImplementation
|
||||
Options CompilerOptions
|
||||
SolverOptions solver.Options
|
||||
BackedArgs []string
|
||||
func (i ArtifactIndex) CleanPath() ArtifactIndex {
|
||||
newIndex := ArtifactIndex{}
|
||||
for _, art := range i {
|
||||
// FIXME: This is a dup and makes difficult to add attributes to artifacts
|
||||
newIndex = append(newIndex, &artifact.PackageArtifact{
|
||||
Path: path.Base(art.Path),
|
||||
SourceAssertion: art.SourceAssertion,
|
||||
CompileSpec: art.CompileSpec,
|
||||
Dependencies: art.Dependencies,
|
||||
CompressionType: art.CompressionType,
|
||||
Checksums: art.Checksums,
|
||||
Files: art.Files,
|
||||
})
|
||||
}
|
||||
return newIndex
|
||||
//Update if exists, otherwise just create
|
||||
}
|
||||
|
||||
func NewLuetCompiler(backend CompilerBackend, db pkg.PackageDatabase, opt *CompilerOptions, solvopts solver.Options) Compiler {
|
||||
type LuetCompiler struct {
|
||||
//*tree.CompilerRecipe
|
||||
Backend CompilerBackend
|
||||
Database pkg.PackageDatabase
|
||||
Options options.Compiler
|
||||
}
|
||||
|
||||
func NewCompiler(p ...options.Option) *LuetCompiler {
|
||||
c := options.NewDefaultCompiler()
|
||||
c.Apply(p...)
|
||||
|
||||
return &LuetCompiler{Options: *c}
|
||||
}
|
||||
|
||||
func NewLuetCompiler(backend CompilerBackend, db pkg.PackageDatabase, compilerOpts ...options.Option) *LuetCompiler {
|
||||
// The CompilerRecipe will gives us a tree with only build deps listed.
|
||||
|
||||
if len(opt.PullImageRepository) == 0 {
|
||||
opt.PullImageRepository = []string{opt.PushImageRepository}
|
||||
}
|
||||
c := NewCompiler(compilerOpts...)
|
||||
// c.Options.BackendType
|
||||
c.Backend = backend
|
||||
c.Database = db
|
||||
// c.CompilerRecipe = &tree.CompilerRecipe{
|
||||
// Recipe: tree.Recipe{Database: db},
|
||||
// }
|
||||
|
||||
return &LuetCompiler{
|
||||
Backend: backend,
|
||||
CompilerRecipe: &tree.CompilerRecipe{
|
||||
Recipe: tree.Recipe{Database: db},
|
||||
},
|
||||
Database: db,
|
||||
PushImageRepository: opt.PushImageRepository,
|
||||
PullImageRepository: opt.PullImageRepository,
|
||||
PullFirst: opt.PullFirst,
|
||||
CompressionType: opt.CompressionType,
|
||||
KeepImg: opt.KeepImg,
|
||||
Concurrency: opt.Concurrency,
|
||||
Options: *opt,
|
||||
SolverOptions: solvopts,
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
// SetBackendArgs sets arbitrary backend arguments.
|
||||
// Those for example can be commands passed to the docker daemon during build phase,
|
||||
// as build-args, etc.
|
||||
func (cs *LuetCompiler) SetBackendArgs(args []string) {
|
||||
cs.BackedArgs = args
|
||||
}
|
||||
|
||||
// SetConcurrency sets the compiler concurrency
|
||||
func (cs *LuetCompiler) SetConcurrency(i int) {
|
||||
cs.Concurrency = i
|
||||
}
|
||||
|
||||
// SetCompressionType sets the compiler compression type for resulting artifacts
|
||||
func (cs *LuetCompiler) SetCompressionType(t CompressionImplementation) {
|
||||
cs.CompressionType = t
|
||||
}
|
||||
|
||||
func (cs *LuetCompiler) compilerWorker(i int, wg *sync.WaitGroup, cspecs chan CompilationSpec, a *[]Artifact, m *sync.Mutex, concurrency int, keepPermissions bool, errors chan error) {
|
||||
func (cs *LuetCompiler) compilerWorker(i int, wg *sync.WaitGroup, cspecs chan *compilerspec.LuetCompilationSpec, a *[]*artifact.PackageArtifact, m *sync.Mutex, concurrency int, keepPermissions bool, errors chan error) {
|
||||
defer wg.Done()
|
||||
|
||||
for s := range cspecs {
|
||||
@@ -113,17 +107,17 @@ func (cs *LuetCompiler) compilerWorker(i int, wg *sync.WaitGroup, cspecs chan Co
|
||||
}
|
||||
|
||||
// CompileWithReverseDeps compiles the supplied compilationspecs and their reverse dependencies
|
||||
func (cs *LuetCompiler) CompileWithReverseDeps(keepPermissions bool, ps CompilationSpecs) ([]Artifact, []error) {
|
||||
func (cs *LuetCompiler) CompileWithReverseDeps(keepPermissions bool, ps *compilerspec.LuetCompilationspecs) ([]*artifact.PackageArtifact, []error) {
|
||||
artifacts, err := cs.CompileParallel(keepPermissions, ps)
|
||||
if len(err) != 0 {
|
||||
return artifacts, err
|
||||
}
|
||||
|
||||
Info(":ant: Resolving reverse dependencies")
|
||||
toCompile := NewLuetCompilationspecs()
|
||||
toCompile := compilerspec.NewLuetCompilationspecs()
|
||||
for _, a := range artifacts {
|
||||
|
||||
revdeps := a.GetCompileSpec().GetPackage().Revdeps(cs.Database)
|
||||
revdeps := a.CompileSpec.GetPackage().Revdeps(cs.Database)
|
||||
for _, r := range revdeps {
|
||||
spec, asserterr := cs.FromPackage(r)
|
||||
if err != nil {
|
||||
@@ -146,15 +140,15 @@ func (cs *LuetCompiler) CompileWithReverseDeps(keepPermissions bool, ps Compilat
|
||||
|
||||
// CompileParallel compiles the supplied compilationspecs in parallel
|
||||
// to note, no specific heuristic is implemented, and the specs are run in parallel as they are.
|
||||
func (cs *LuetCompiler) CompileParallel(keepPermissions bool, ps CompilationSpecs) ([]Artifact, []error) {
|
||||
all := make(chan CompilationSpec)
|
||||
artifacts := []Artifact{}
|
||||
func (cs *LuetCompiler) CompileParallel(keepPermissions bool, ps *compilerspec.LuetCompilationspecs) ([]*artifact.PackageArtifact, []error) {
|
||||
all := make(chan *compilerspec.LuetCompilationSpec)
|
||||
artifacts := []*artifact.PackageArtifact{}
|
||||
mutex := &sync.Mutex{}
|
||||
errors := make(chan error, ps.Len())
|
||||
var wg = new(sync.WaitGroup)
|
||||
for i := 0; i < cs.Concurrency; i++ {
|
||||
for i := 0; i < cs.Options.Concurrency; i++ {
|
||||
wg.Add(1)
|
||||
go cs.compilerWorker(i, wg, all, &artifacts, mutex, cs.Concurrency, keepPermissions, errors)
|
||||
go cs.compilerWorker(i, wg, all, &artifacts, mutex, cs.Options.Concurrency, keepPermissions, errors)
|
||||
}
|
||||
|
||||
for _, p := range ps.All() {
|
||||
@@ -233,7 +227,7 @@ func (cs *LuetCompiler) stripFromRootfs(includes []string, rootfs string, includ
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cs *LuetCompiler) unpackFs(concurrency int, keepPermissions bool, p CompilationSpec, runnerOpts CompilerBackendOptions) (Artifact, error) {
|
||||
func (cs *LuetCompiler) unpackFs(concurrency int, keepPermissions bool, p *compilerspec.LuetCompilationSpec, runnerOpts backend.Options) (*artifact.PackageArtifact, error) {
|
||||
|
||||
rootfs, err := ioutil.TempDir(p.GetOutputPath(), "rootfs")
|
||||
if err != nil {
|
||||
@@ -241,7 +235,7 @@ func (cs *LuetCompiler) unpackFs(concurrency int, keepPermissions bool, p Compil
|
||||
}
|
||||
defer os.RemoveAll(rootfs) // clean up
|
||||
|
||||
err = cs.Backend.ExtractRootfs(CompilerBackendOptions{
|
||||
err = cs.Backend.ExtractRootfs(backend.Options{
|
||||
ImageName: runnerOpts.ImageName, Destination: rootfs}, keepPermissions)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Could not extract rootfs")
|
||||
@@ -260,18 +254,18 @@ func (cs *LuetCompiler) unpackFs(concurrency int, keepPermissions bool, p Compil
|
||||
// strip from excludes
|
||||
cs.stripFromRootfs(p.GetExcludes(), rootfs, false)
|
||||
}
|
||||
artifact := NewPackageArtifact(p.Rel(p.GetPackage().GetFingerPrint() + ".package.tar"))
|
||||
artifact.SetCompressionType(cs.CompressionType)
|
||||
a := artifact.NewPackageArtifact(p.Rel(p.GetPackage().GetFingerPrint() + ".package.tar"))
|
||||
a.CompressionType = cs.Options.CompressionType
|
||||
|
||||
if err := artifact.Compress(rootfs, concurrency); err != nil {
|
||||
if err := a.Compress(rootfs, concurrency); err != nil {
|
||||
return nil, errors.Wrap(err, "Error met while creating package archive")
|
||||
}
|
||||
|
||||
artifact.SetCompileSpec(p)
|
||||
return artifact, nil
|
||||
a.CompileSpec = p
|
||||
return a, nil
|
||||
}
|
||||
|
||||
func (cs *LuetCompiler) unpackDelta(concurrency int, keepPermissions bool, p CompilationSpec, builderOpts, runnerOpts CompilerBackendOptions) (Artifact, error) {
|
||||
func (cs *LuetCompiler) unpackDelta(concurrency int, keepPermissions bool, p *compilerspec.LuetCompilationSpec, builderOpts, runnerOpts backend.Options) (*artifact.PackageArtifact, error) {
|
||||
|
||||
rootfs, err := ioutil.TempDir(p.GetOutputPath(), "rootfs")
|
||||
if err != nil {
|
||||
@@ -288,30 +282,30 @@ func (cs *LuetCompiler) unpackDelta(concurrency int, keepPermissions bool, p Com
|
||||
}
|
||||
|
||||
Info(pkgTag, ":hammer: Generating delta")
|
||||
diffs, err := cs.Backend.Changes(builderOpts, runnerOpts)
|
||||
diffs, err := GenerateChanges(cs.Backend, builderOpts, runnerOpts)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Could not generate changes from layers")
|
||||
}
|
||||
|
||||
Debug("Extracting image to grab files from delta")
|
||||
if err := cs.Backend.ExtractRootfs(CompilerBackendOptions{
|
||||
if err := cs.Backend.ExtractRootfs(backend.Options{
|
||||
ImageName: runnerOpts.ImageName, Destination: rootfs}, keepPermissions); err != nil {
|
||||
return nil, errors.Wrap(err, "Could not extract rootfs")
|
||||
}
|
||||
artifact, err := ExtractArtifactFromDelta(rootfs, p.Rel(p.GetPackage().GetFingerPrint()+".package.tar"), diffs, concurrency, keepPermissions, p.GetIncludes(), p.GetExcludes(), cs.CompressionType)
|
||||
artifact, err := artifact.ExtractArtifactFromDelta(rootfs, p.Rel(p.GetPackage().GetFingerPrint()+".package.tar"), diffs, concurrency, keepPermissions, p.GetIncludes(), p.GetExcludes(), cs.Options.CompressionType)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Could not generate deltas")
|
||||
}
|
||||
|
||||
artifact.SetCompileSpec(p)
|
||||
artifact.CompileSpec = p
|
||||
return artifact, nil
|
||||
}
|
||||
|
||||
func (cs *LuetCompiler) buildPackageImage(image, buildertaggedImage, packageImage string,
|
||||
concurrency int, keepPermissions bool,
|
||||
p CompilationSpec) (CompilerBackendOptions, CompilerBackendOptions, error) {
|
||||
p *compilerspec.LuetCompilationSpec) (backend.Options, backend.Options, error) {
|
||||
|
||||
var runnerOpts, builderOpts CompilerBackendOptions
|
||||
var runnerOpts, builderOpts backend.Options
|
||||
|
||||
pkgTag := ":package: " + p.GetPackage().HumanReadableString()
|
||||
|
||||
@@ -325,7 +319,7 @@ func (cs *LuetCompiler) buildPackageImage(image, buildertaggedImage, packageImag
|
||||
fp := p.GetPackage().HashFingerprint(helpers.StripRegistryFromImage(packageImage))
|
||||
|
||||
if buildertaggedImage == "" {
|
||||
buildertaggedImage = cs.PushImageRepository + ":builder-" + fp
|
||||
buildertaggedImage = cs.Options.PushImageRepository + ":builder-" + fp
|
||||
Debug(pkgTag, "Creating intermediary image", buildertaggedImage, "from", image)
|
||||
}
|
||||
|
||||
@@ -375,22 +369,22 @@ func (cs *LuetCompiler) buildPackageImage(image, buildertaggedImage, packageImag
|
||||
return builderOpts, runnerOpts, errors.Wrap(err, "Could not generate image definition")
|
||||
}
|
||||
|
||||
builderOpts = CompilerBackendOptions{
|
||||
builderOpts = backend.Options{
|
||||
ImageName: buildertaggedImage,
|
||||
SourcePath: buildDir,
|
||||
DockerFileName: p.GetPackage().GetFingerPrint() + "-builder.dockerfile",
|
||||
Destination: p.Rel(p.GetPackage().GetFingerPrint() + "-builder.image.tar"),
|
||||
BackendArgs: cs.BackedArgs,
|
||||
BackendArgs: cs.Options.BackendArgs,
|
||||
}
|
||||
runnerOpts = CompilerBackendOptions{
|
||||
runnerOpts = backend.Options{
|
||||
ImageName: packageImage,
|
||||
SourcePath: buildDir,
|
||||
DockerFileName: p.GetPackage().GetFingerPrint() + ".dockerfile",
|
||||
Destination: p.Rel(p.GetPackage().GetFingerPrint() + ".image.tar"),
|
||||
BackendArgs: cs.BackedArgs,
|
||||
BackendArgs: cs.Options.BackendArgs,
|
||||
}
|
||||
|
||||
buildAndPush := func(opts CompilerBackendOptions) error {
|
||||
buildAndPush := func(opts backend.Options) error {
|
||||
buildImage := true
|
||||
if cs.Options.PullFirst {
|
||||
err := cs.Backend.DownloadImage(opts)
|
||||
@@ -430,10 +424,10 @@ func (cs *LuetCompiler) buildPackageImage(image, buildertaggedImage, packageImag
|
||||
return builderOpts, runnerOpts, nil
|
||||
}
|
||||
|
||||
func (cs *LuetCompiler) genArtifact(p CompilationSpec, builderOpts, runnerOpts CompilerBackendOptions, concurrency int, keepPermissions bool) (Artifact, error) {
|
||||
func (cs *LuetCompiler) genArtifact(p *compilerspec.LuetCompilationSpec, builderOpts, runnerOpts backend.Options, concurrency int, keepPermissions bool) (*artifact.PackageArtifact, error) {
|
||||
|
||||
// generate Artifact
|
||||
var artifact Artifact
|
||||
// generate *artifact.PackageArtifact
|
||||
var a *artifact.PackageArtifact
|
||||
var rootfs string
|
||||
var err error
|
||||
pkgTag := ":package: " + p.GetPackage().HumanReadableString()
|
||||
@@ -448,53 +442,53 @@ func (cs *LuetCompiler) genArtifact(p CompilationSpec, builderOpts, runnerOpts C
|
||||
}
|
||||
defer os.RemoveAll(rootfs) // clean up
|
||||
|
||||
artifact := NewPackageArtifact(fakePackage)
|
||||
artifact.SetCompressionType(cs.CompressionType)
|
||||
a := artifact.NewPackageArtifact(fakePackage)
|
||||
a.CompressionType = cs.Options.CompressionType
|
||||
|
||||
if err := artifact.Compress(rootfs, concurrency); err != nil {
|
||||
if err := a.Compress(rootfs, concurrency); err != nil {
|
||||
return nil, errors.Wrap(err, "Error met while creating package archive")
|
||||
}
|
||||
|
||||
artifact.SetCompileSpec(p)
|
||||
artifact.GetCompileSpec().GetPackage().SetBuildTimestamp(time.Now().String())
|
||||
a.CompileSpec = p
|
||||
a.CompileSpec.GetPackage().SetBuildTimestamp(time.Now().String())
|
||||
|
||||
err = artifact.WriteYaml(p.GetOutputPath())
|
||||
err = a.WriteYaml(p.GetOutputPath())
|
||||
if err != nil {
|
||||
return artifact, errors.Wrap(err, "Failed while writing metadata file")
|
||||
return a, errors.Wrap(err, "Failed while writing metadata file")
|
||||
}
|
||||
Info(pkgTag, " :white_check_mark: done (empty virtual package)")
|
||||
return artifact, nil
|
||||
return a, nil
|
||||
}
|
||||
|
||||
if p.UnpackedPackage() {
|
||||
// Take content of container as a base for our package files
|
||||
artifact, err = cs.unpackFs(concurrency, keepPermissions, p, runnerOpts)
|
||||
a, err = cs.unpackFs(concurrency, keepPermissions, p, runnerOpts)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Error met while extracting image")
|
||||
}
|
||||
} else {
|
||||
// Generate delta between the two images
|
||||
artifact, err = cs.unpackDelta(concurrency, keepPermissions, p, builderOpts, runnerOpts)
|
||||
a, err = cs.unpackDelta(concurrency, keepPermissions, p, builderOpts, runnerOpts)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Error met while generating delta")
|
||||
}
|
||||
}
|
||||
|
||||
filelist, err := artifact.FileList()
|
||||
filelist, err := a.FileList()
|
||||
if err != nil {
|
||||
return artifact, errors.Wrap(err, "Failed getting package list")
|
||||
return a, errors.Wrap(err, "Failed getting package list")
|
||||
}
|
||||
|
||||
artifact.SetFiles(filelist)
|
||||
artifact.GetCompileSpec().GetPackage().SetBuildTimestamp(time.Now().String())
|
||||
a.Files = filelist
|
||||
a.CompileSpec.GetPackage().SetBuildTimestamp(time.Now().String())
|
||||
|
||||
err = artifact.WriteYaml(p.GetOutputPath())
|
||||
err = a.WriteYaml(p.GetOutputPath())
|
||||
if err != nil {
|
||||
return artifact, errors.Wrap(err, "Failed while writing metadata file")
|
||||
return a, errors.Wrap(err, "Failed while writing metadata file")
|
||||
}
|
||||
Info(pkgTag, " :white_check_mark: Done")
|
||||
|
||||
return artifact, nil
|
||||
return a, nil
|
||||
}
|
||||
|
||||
func (cs *LuetCompiler) waitForImages(images []string) {
|
||||
@@ -532,8 +526,8 @@ func oneOfImagesAvailable(images []string, b CompilerBackend) (bool, string) {
|
||||
|
||||
func (cs *LuetCompiler) resolveExistingImageHash(imageHash string) string {
|
||||
var resolvedImage string
|
||||
toChecklist := append([]string{fmt.Sprintf("%s:%s", cs.PushImageRepository, imageHash)},
|
||||
genImageList(cs.PullImageRepository, imageHash)...)
|
||||
toChecklist := append([]string{fmt.Sprintf("%s:%s", cs.Options.PushImageRepository, imageHash)},
|
||||
genImageList(cs.Options.PullImageRepository, imageHash)...)
|
||||
if exists, which := oneOfImagesExists(toChecklist, cs.Backend); exists {
|
||||
resolvedImage = which
|
||||
}
|
||||
@@ -544,28 +538,43 @@ func (cs *LuetCompiler) resolveExistingImageHash(imageHash string) string {
|
||||
}
|
||||
|
||||
if resolvedImage == "" {
|
||||
resolvedImage = fmt.Sprintf("%s:%s", cs.PushImageRepository, imageHash)
|
||||
resolvedImage = fmt.Sprintf("%s:%s", cs.Options.PushImageRepository, imageHash)
|
||||
}
|
||||
return resolvedImage
|
||||
}
|
||||
|
||||
func (cs *LuetCompiler) getImageArtifact(hash string, p CompilationSpec) (Artifact, error) {
|
||||
func LoadArtifactFromYaml(spec *compilerspec.LuetCompilationSpec) (*artifact.PackageArtifact, error) {
|
||||
metaFile := spec.GetPackage().GetFingerPrint() + ".metadata.yaml"
|
||||
dat, err := ioutil.ReadFile(spec.Rel(metaFile))
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Error reading file "+metaFile)
|
||||
}
|
||||
art, err := artifact.NewPackageArtifactFromYaml(dat)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Error writing file "+metaFile)
|
||||
}
|
||||
// It is relative, set it back to abs
|
||||
art.Path = spec.Rel(art.Path)
|
||||
return art, nil
|
||||
}
|
||||
|
||||
func (cs *LuetCompiler) getImageArtifact(hash string, p *compilerspec.LuetCompilationSpec) (*artifact.PackageArtifact, error) {
|
||||
// we check if there is an available image with the given hash and
|
||||
// we return a full artifact if can be loaded locally.
|
||||
|
||||
toChecklist := append([]string{fmt.Sprintf("%s:%s", cs.PushImageRepository, hash)},
|
||||
genImageList(cs.PullImageRepository, hash)...)
|
||||
toChecklist := append([]string{fmt.Sprintf("%s:%s", cs.Options.PushImageRepository, hash)},
|
||||
genImageList(cs.Options.PullImageRepository, hash)...)
|
||||
|
||||
exists, _ := oneOfImagesExists(toChecklist, cs.Backend)
|
||||
if art, err := LoadArtifactFromYaml(p); err == nil && exists { // If YAML is correctly loaded, and both images exists, no reason to rebuild.
|
||||
Debug("Artifact reloaded from YAML. Skipping build")
|
||||
Debug("Package reloaded from YAML. Skipping build")
|
||||
return art, nil
|
||||
}
|
||||
cs.waitForImages(toChecklist)
|
||||
available, _ := oneOfImagesAvailable(toChecklist, cs.Backend)
|
||||
if exists || (cs.Options.PullFirst && available) {
|
||||
Debug("Image available, returning empty artifact")
|
||||
return &PackageArtifact{}, nil
|
||||
return &artifact.PackageArtifact{}, nil
|
||||
}
|
||||
|
||||
return nil, errors.New("artifact not found")
|
||||
@@ -578,13 +587,13 @@ func (cs *LuetCompiler) getImageArtifact(hash string, p CompilationSpec) (Artifa
|
||||
func (cs *LuetCompiler) compileWithImage(image, buildertaggedImage string, packageTagHash string,
|
||||
concurrency int,
|
||||
keepPermissions, keepImg bool,
|
||||
p CompilationSpec, generateArtifact bool) (Artifact, error) {
|
||||
p *compilerspec.LuetCompilationSpec, generateArtifact bool) (*artifact.PackageArtifact, error) {
|
||||
|
||||
// If it is a virtual, check if we have to generate an empty artifact or not.
|
||||
if generateArtifact && p.IsVirtual() {
|
||||
return cs.genArtifact(p, CompilerBackendOptions{}, CompilerBackendOptions{}, concurrency, keepPermissions)
|
||||
return cs.genArtifact(p, backend.Options{}, backend.Options{}, concurrency, keepPermissions)
|
||||
} else if p.IsVirtual() {
|
||||
return &PackageArtifact{}, nil
|
||||
return &artifact.PackageArtifact{}, nil
|
||||
}
|
||||
|
||||
if !generateArtifact {
|
||||
@@ -597,7 +606,7 @@ func (cs *LuetCompiler) compileWithImage(image, buildertaggedImage string, packa
|
||||
}
|
||||
|
||||
// always going to point at the destination from the repo defined
|
||||
packageImage := fmt.Sprintf("%s:%s", cs.PushImageRepository, packageTagHash)
|
||||
packageImage := fmt.Sprintf("%s:%s", cs.Options.PushImageRepository, packageTagHash)
|
||||
builderOpts, runnerOpts, err := cs.buildPackageImage(image, buildertaggedImage, packageImage, concurrency, keepPermissions, p)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed building package image")
|
||||
@@ -616,7 +625,7 @@ func (cs *LuetCompiler) compileWithImage(image, buildertaggedImage string, packa
|
||||
}
|
||||
|
||||
if !generateArtifact {
|
||||
return &PackageArtifact{}, nil
|
||||
return &artifact.PackageArtifact{}, nil
|
||||
}
|
||||
|
||||
return cs.genArtifact(p, builderOpts, runnerOpts, concurrency, keepPermissions)
|
||||
@@ -624,8 +633,8 @@ func (cs *LuetCompiler) compileWithImage(image, buildertaggedImage string, packa
|
||||
|
||||
// FromDatabase returns all the available compilation specs from a database. If the minimum flag is returned
|
||||
// it will be computed a minimal subset that will guarantees that all packages are built ( if not targeting a single package explictly )
|
||||
func (cs *LuetCompiler) FromDatabase(db pkg.PackageDatabase, minimum bool, dst string) ([]CompilationSpec, error) {
|
||||
compilerSpecs := NewLuetCompilationspecs()
|
||||
func (cs *LuetCompiler) FromDatabase(db pkg.PackageDatabase, minimum bool, dst string) ([]*compilerspec.LuetCompilationSpec, error) {
|
||||
compilerSpecs := compilerspec.NewLuetCompilationspecs()
|
||||
|
||||
w := db.World()
|
||||
|
||||
@@ -649,11 +658,11 @@ func (cs *LuetCompiler) FromDatabase(db pkg.PackageDatabase, minimum bool, dst s
|
||||
}
|
||||
|
||||
// ComputeMinimumCompilableSet strips specs that are eventually compiled by leafs
|
||||
func (cs *LuetCompiler) ComputeMinimumCompilableSet(p ...CompilationSpec) ([]CompilationSpec, error) {
|
||||
func (cs *LuetCompiler) ComputeMinimumCompilableSet(p ...*compilerspec.LuetCompilationSpec) ([]*compilerspec.LuetCompilationSpec, error) {
|
||||
// Generate a set with all the deps of the provided specs
|
||||
// we will use that set to remove the deps from the list of provided compilation specs
|
||||
allDependencies := solver.PackagesAssertions{} // Get all packages that will be in deps
|
||||
result := []CompilationSpec{}
|
||||
result := []*compilerspec.LuetCompilationSpec{}
|
||||
for _, spec := range p {
|
||||
ass, err := cs.ComputeDepTree(spec)
|
||||
if err != nil {
|
||||
@@ -673,9 +682,9 @@ func (cs *LuetCompiler) ComputeMinimumCompilableSet(p ...CompilationSpec) ([]Com
|
||||
|
||||
// ComputeDepTree computes the dependency tree of a compilation spec and returns solver assertions
|
||||
// in order to be able to compile the spec.
|
||||
func (cs *LuetCompiler) ComputeDepTree(p CompilationSpec) (solver.PackagesAssertions, error) {
|
||||
func (cs *LuetCompiler) ComputeDepTree(p *compilerspec.LuetCompilationSpec) (solver.PackagesAssertions, error) {
|
||||
|
||||
s := solver.NewResolver(cs.SolverOptions, pkg.NewInMemoryDatabase(false), cs.Database, pkg.NewInMemoryDatabase(false), cs.Options.SolverOptions.Resolver())
|
||||
s := solver.NewResolver(cs.Options.SolverOptions.Options, pkg.NewInMemoryDatabase(false), cs.Database, pkg.NewInMemoryDatabase(false), cs.Options.SolverOptions.Resolver())
|
||||
|
||||
solution, err := s.Install(pkg.Packages{p.GetPackage()})
|
||||
if err != nil {
|
||||
@@ -704,13 +713,13 @@ func (cs *LuetCompiler) ComputeDepTree(p CompilationSpec) (solver.PackagesAssert
|
||||
|
||||
// Compile is a non-parallel version of CompileParallel. It builds the compilation specs and generates
|
||||
// an artifact
|
||||
func (cs *LuetCompiler) Compile(keepPermissions bool, p CompilationSpec) (Artifact, error) {
|
||||
func (cs *LuetCompiler) Compile(keepPermissions bool, p *compilerspec.LuetCompilationSpec) (*artifact.PackageArtifact, error) {
|
||||
asserts, err := cs.ComputeDepTree(p)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
p.SetSourceAssertion(asserts)
|
||||
return cs.compile(cs.Concurrency, keepPermissions, p)
|
||||
return cs.compile(cs.Options.Concurrency, keepPermissions, p)
|
||||
}
|
||||
|
||||
func genImageList(refs []string, hash string) []string {
|
||||
@@ -721,7 +730,7 @@ func genImageList(refs []string, hash string) []string {
|
||||
return res
|
||||
}
|
||||
|
||||
func (cs *LuetCompiler) compile(concurrency int, keepPermissions bool, p CompilationSpec) (Artifact, error) {
|
||||
func (cs *LuetCompiler) compile(concurrency int, keepPermissions bool, p *compilerspec.LuetCompilationSpec) (*artifact.PackageArtifact, error) {
|
||||
Info(":package: Compiling", p.GetPackage().HumanReadableString(), ".... :coffee:")
|
||||
|
||||
Debug(fmt.Sprintf("%s: has images %t, empty package: %t", p.GetPackage().HumanReadableString(), p.HasImageSource(), p.EmptyPackage()))
|
||||
@@ -736,17 +745,20 @@ func (cs *LuetCompiler) compile(concurrency int, keepPermissions bool, p Compila
|
||||
targetAssertion := p.GetSourceAssertion().Search(p.GetPackage().GetFingerPrint())
|
||||
|
||||
bus.Manager.Publish(bus.EventPackagePreBuild, struct {
|
||||
CompileSpec CompilationSpec
|
||||
CompileSpec *compilerspec.LuetCompilationSpec
|
||||
Assert solver.PackageAssert
|
||||
}{
|
||||
CompileSpec: p,
|
||||
Assert: *targetAssertion,
|
||||
})
|
||||
|
||||
// Update compilespec build options
|
||||
p.SetBuildOptions(cs.Options)
|
||||
|
||||
// - If image is set we just generate a plain dockerfile
|
||||
// Treat last case (easier) first. The image is provided and we just compute a plain dockerfile with the images listed as above
|
||||
if p.GetImage() != "" {
|
||||
return cs.compileWithImage(p.GetImage(), "", targetAssertion.Hash.PackageHash, concurrency, keepPermissions, cs.KeepImg, p, true)
|
||||
return cs.compileWithImage(p.GetImage(), "", targetAssertion.Hash.PackageHash, concurrency, keepPermissions, cs.Options.KeepImg, p, true)
|
||||
}
|
||||
|
||||
// - If image is not set, we read a base_image. Then we will build one image from it to kick-off our build based
|
||||
@@ -755,7 +767,7 @@ func (cs *LuetCompiler) compile(concurrency int, keepPermissions bool, p Compila
|
||||
// - We later on compute an hash used to identify the image, so each similar deptree keeps the same build image.
|
||||
|
||||
dependencies := p.GetSourceAssertion().Drop(p.GetPackage()) // at this point we should have a flattened list of deps to build, including all of them (with all constraints propagated already)
|
||||
departifacts := []Artifact{} // TODO: Return this somehow
|
||||
departifacts := []*artifact.PackageArtifact{} // TODO: Return this somehow
|
||||
var lastHash string
|
||||
depsN := 0
|
||||
currentN := 0
|
||||
@@ -781,7 +793,7 @@ func (cs *LuetCompiler) compile(concurrency int, keepPermissions bool, p Compila
|
||||
Debug(pkgTag, " :arrow_right_hook: :whale: Package image from hash", assertion.Hash.PackageHash)
|
||||
|
||||
bus.Manager.Publish(bus.EventPackagePreBuild, struct {
|
||||
CompileSpec CompilationSpec
|
||||
CompileSpec *compilerspec.LuetCompilationSpec
|
||||
Assert solver.PackageAssert
|
||||
}{
|
||||
CompileSpec: compileSpec,
|
||||
@@ -796,30 +808,30 @@ func (cs *LuetCompiler) compile(concurrency int, keepPermissions bool, p Compila
|
||||
if compileSpec.GetImage() != "" {
|
||||
Debug(pkgTag, " :wrench: Compiling "+compileSpec.GetPackage().HumanReadableString()+" from image")
|
||||
|
||||
artifact, err := cs.compileWithImage(compileSpec.GetImage(), resolvedBuildImage, assertion.Hash.PackageHash, concurrency, keepPermissions, cs.KeepImg, compileSpec, packageDeps)
|
||||
a, err := cs.compileWithImage(compileSpec.GetImage(), resolvedBuildImage, assertion.Hash.PackageHash, concurrency, keepPermissions, cs.Options.KeepImg, compileSpec, packageDeps)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Failed compiling "+compileSpec.GetPackage().HumanReadableString())
|
||||
}
|
||||
departifacts = append(departifacts, artifact)
|
||||
departifacts = append(departifacts, a)
|
||||
Info(pkgTag, ":white_check_mark: Done")
|
||||
continue
|
||||
}
|
||||
|
||||
Debug(pkgTag, " :wrench: Compiling "+compileSpec.GetPackage().HumanReadableString()+" from tree")
|
||||
artifact, err := cs.compileWithImage(resolvedBuildImage, "", assertion.Hash.PackageHash, concurrency, keepPermissions, cs.KeepImg, compileSpec, packageDeps)
|
||||
a, err := cs.compileWithImage(resolvedBuildImage, "", assertion.Hash.PackageHash, concurrency, keepPermissions, cs.Options.KeepImg, compileSpec, packageDeps)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Failed compiling "+compileSpec.GetPackage().HumanReadableString())
|
||||
}
|
||||
|
||||
bus.Manager.Publish(bus.EventPackagePostBuild, struct {
|
||||
CompileSpec CompilationSpec
|
||||
Artifact Artifact
|
||||
CompileSpec *compilerspec.LuetCompilationSpec
|
||||
Artifact *artifact.PackageArtifact
|
||||
}{
|
||||
CompileSpec: compileSpec,
|
||||
Artifact: artifact,
|
||||
Artifact: a,
|
||||
})
|
||||
|
||||
departifacts = append(departifacts, artifact)
|
||||
departifacts = append(departifacts, a)
|
||||
Info(pkgTag, ":white_check_mark: Done")
|
||||
}
|
||||
|
||||
@@ -831,22 +843,22 @@ func (cs *LuetCompiler) compile(concurrency int, keepPermissions bool, p Compila
|
||||
resolvedBuildImage := cs.resolveExistingImageHash(lastHash)
|
||||
Info(":rocket: All dependencies are satisfied, building package requested by the user", p.GetPackage().HumanReadableString())
|
||||
Info(":package:", p.GetPackage().HumanReadableString(), " Using image: ", resolvedBuildImage)
|
||||
artifact, err := cs.compileWithImage(resolvedBuildImage, "", targetAssertion.Hash.PackageHash, concurrency, keepPermissions, cs.KeepImg, p, true)
|
||||
a, err := cs.compileWithImage(resolvedBuildImage, "", targetAssertion.Hash.PackageHash, concurrency, keepPermissions, cs.Options.KeepImg, p, true)
|
||||
if err != nil {
|
||||
return artifact, err
|
||||
return a, err
|
||||
}
|
||||
artifact.SetDependencies(departifacts)
|
||||
artifact.SetSourceAssertion(p.GetSourceAssertion())
|
||||
a.Dependencies = departifacts
|
||||
a.SourceAssertion = p.GetSourceAssertion()
|
||||
|
||||
bus.Manager.Publish(bus.EventPackagePostBuild, struct {
|
||||
CompileSpec CompilationSpec
|
||||
Artifact Artifact
|
||||
CompileSpec *compilerspec.LuetCompilationSpec
|
||||
Artifact *artifact.PackageArtifact
|
||||
}{
|
||||
CompileSpec: p,
|
||||
Artifact: artifact,
|
||||
Artifact: a,
|
||||
})
|
||||
|
||||
return artifact, err
|
||||
return a, err
|
||||
} else {
|
||||
return departifacts[len(departifacts)-1], nil
|
||||
}
|
||||
@@ -857,8 +869,15 @@ type templatedata map[string]interface{}
|
||||
func (cs *LuetCompiler) templatePackage(pack pkg.Package) ([]byte, error) {
|
||||
|
||||
var dataresult []byte
|
||||
|
||||
val := pack.Rel(DefinitionFile)
|
||||
|
||||
// Update processed build values
|
||||
dst, err := helpers.UnMarshalValues(cs.Options.BuildValuesFile)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "unmarshalling values")
|
||||
}
|
||||
cs.Options.BuildValues = []map[string]interface{}{(map[string]interface{})(dst)}
|
||||
|
||||
if _, err := os.Stat(pack.Rel(CollectionFile)); err == nil {
|
||||
val = pack.Rel(CollectionFile)
|
||||
|
||||
@@ -879,11 +898,6 @@ func (cs *LuetCompiler) templatePackage(pack pkg.Package) ([]byte, error) {
|
||||
|
||||
raw := packsRaw.Find(pack.GetName(), pack.GetCategory(), pack.GetVersion())
|
||||
|
||||
dst, err := helpers.UnMarshalValues(cs.Options.BuildValuesFile)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "unmarshalling values")
|
||||
}
|
||||
|
||||
dat, err := helpers.RenderHelm(string(dataBuild), raw, dst)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "rendering file "+pack.Rel(BuildFile))
|
||||
@@ -896,12 +910,12 @@ func (cs *LuetCompiler) templatePackage(pack pkg.Package) ([]byte, error) {
|
||||
}
|
||||
dataresult = []byte(out)
|
||||
}
|
||||
return dataresult, nil
|
||||
|
||||
return dataresult, nil
|
||||
}
|
||||
|
||||
// FromPackage returns a compilation spec from a package definition
|
||||
func (cs *LuetCompiler) FromPackage(p pkg.Package) (CompilationSpec, error) {
|
||||
func (cs *LuetCompiler) FromPackage(p pkg.Package) (*compilerspec.LuetCompilationSpec, error) {
|
||||
|
||||
pack, err := cs.Database.FindPackageCandidate(p)
|
||||
if err != nil {
|
||||
@@ -913,7 +927,7 @@ func (cs *LuetCompiler) FromPackage(p pkg.Package) (CompilationSpec, error) {
|
||||
return nil, errors.Wrap(err, "while rendering package template")
|
||||
}
|
||||
|
||||
return NewLuetCompilationSpec(bytes, pack)
|
||||
return compilerspec.NewLuetCompilationSpec(bytes, pack)
|
||||
}
|
||||
|
||||
// GetBackend returns the current compilation backend
|
||||
|
Reference in New Issue
Block a user