mirror of
https://github.com/mudler/luet.git
synced 2025-09-01 23:37:07 +00:00
Allow to pull specfiles from published repositories
- Interpolates values from the repositories compilespec if present - Automatically merge cache images coming from specified repository when necessary Fixes #194
This commit is contained in:
36
cmd/build.go
36
cmd/build.go
@@ -16,7 +16,6 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
@@ -25,6 +24,7 @@ import (
|
|||||||
"github.com/mudler/luet/pkg/compiler"
|
"github.com/mudler/luet/pkg/compiler"
|
||||||
"github.com/mudler/luet/pkg/compiler/types/artifact"
|
"github.com/mudler/luet/pkg/compiler/types/artifact"
|
||||||
compilerspec "github.com/mudler/luet/pkg/compiler/types/spec"
|
compilerspec "github.com/mudler/luet/pkg/compiler/types/spec"
|
||||||
|
"github.com/mudler/luet/pkg/installer"
|
||||||
|
|
||||||
"github.com/mudler/luet/pkg/compiler/types/compression"
|
"github.com/mudler/luet/pkg/compiler/types/compression"
|
||||||
"github.com/mudler/luet/pkg/compiler/types/options"
|
"github.com/mudler/luet/pkg/compiler/types/options"
|
||||||
@@ -44,17 +44,17 @@ var buildCmd = &cobra.Command{
|
|||||||
Long: `Builds one or more packages from a tree (current directory is implied):
|
Long: `Builds one or more packages from a tree (current directory is implied):
|
||||||
|
|
||||||
$ luet build utils/busybox utils/yq ...
|
$ luet build utils/busybox utils/yq ...
|
||||||
|
|
||||||
Builds all packages
|
Builds all packages
|
||||||
|
|
||||||
$ luet build --all
|
$ luet build --all
|
||||||
|
|
||||||
Builds only the leaf packages:
|
Builds only the leaf packages:
|
||||||
|
|
||||||
$ luet build --full
|
$ luet build --full
|
||||||
|
|
||||||
Build package revdeps:
|
Build package revdeps:
|
||||||
|
|
||||||
$ luet build --revdeps utils/yq
|
$ luet build --revdeps utils/yq
|
||||||
|
|
||||||
Build package without dependencies (needs the images already in the host, or either need to be available online):
|
Build package without dependencies (needs the images already in the host, or either need to be available online):
|
||||||
@@ -69,7 +69,6 @@ Build packages specifying multiple definition trees:
|
|||||||
viper.BindPFlag("destination", cmd.Flags().Lookup("destination"))
|
viper.BindPFlag("destination", cmd.Flags().Lookup("destination"))
|
||||||
viper.BindPFlag("backend", cmd.Flags().Lookup("backend"))
|
viper.BindPFlag("backend", cmd.Flags().Lookup("backend"))
|
||||||
viper.BindPFlag("privileged", cmd.Flags().Lookup("privileged"))
|
viper.BindPFlag("privileged", cmd.Flags().Lookup("privileged"))
|
||||||
viper.BindPFlag("database", cmd.Flags().Lookup("database"))
|
|
||||||
viper.BindPFlag("revdeps", cmd.Flags().Lookup("revdeps"))
|
viper.BindPFlag("revdeps", cmd.Flags().Lookup("revdeps"))
|
||||||
viper.BindPFlag("all", cmd.Flags().Lookup("all"))
|
viper.BindPFlag("all", cmd.Flags().Lookup("all"))
|
||||||
viper.BindPFlag("compression", cmd.Flags().Lookup("compression"))
|
viper.BindPFlag("compression", cmd.Flags().Lookup("compression"))
|
||||||
@@ -101,7 +100,6 @@ Build packages specifying multiple definition trees:
|
|||||||
privileged := viper.GetBool("privileged")
|
privileged := viper.GetBool("privileged")
|
||||||
revdeps := viper.GetBool("revdeps")
|
revdeps := viper.GetBool("revdeps")
|
||||||
all := viper.GetBool("all")
|
all := viper.GetBool("all")
|
||||||
databaseType := viper.GetString("database")
|
|
||||||
compressionType := viper.GetString("compression")
|
compressionType := viper.GetString("compression")
|
||||||
imageRepository := viper.GetString("image-repository")
|
imageRepository := viper.GetString("image-repository")
|
||||||
values := viper.GetStringSlice("values")
|
values := viper.GetStringSlice("values")
|
||||||
@@ -122,26 +120,25 @@ Build packages specifying multiple definition trees:
|
|||||||
LuetCfg.GetLogging().SetLogLevel("error")
|
LuetCfg.GetLogging().SetLogLevel("error")
|
||||||
}
|
}
|
||||||
pretend, _ := cmd.Flags().GetBool("pretend")
|
pretend, _ := cmd.Flags().GetBool("pretend")
|
||||||
|
fromRepo, _ := cmd.Flags().GetBool("from-repositories")
|
||||||
|
|
||||||
compilerSpecs := compilerspec.NewLuetCompilationspecs()
|
compilerSpecs := compilerspec.NewLuetCompilationspecs()
|
||||||
var db pkg.PackageDatabase
|
var db pkg.PackageDatabase
|
||||||
|
|
||||||
compilerBackend, err := compiler.NewBackend(backendType)
|
compilerBackend, err := compiler.NewBackend(backendType)
|
||||||
helpers.CheckErr(err)
|
helpers.CheckErr(err)
|
||||||
|
|
||||||
switch databaseType {
|
db = pkg.NewInMemoryDatabase(false)
|
||||||
case "memory":
|
|
||||||
db = pkg.NewInMemoryDatabase(false)
|
|
||||||
|
|
||||||
case "boltdb":
|
|
||||||
tmpdir, err := ioutil.TempDir("", "package")
|
|
||||||
helpers.CheckErr(err)
|
|
||||||
db = pkg.NewBoltDatabase(tmpdir)
|
|
||||||
|
|
||||||
}
|
|
||||||
defer db.Clean()
|
defer db.Clean()
|
||||||
|
|
||||||
generalRecipe := tree.NewCompilerRecipe(db)
|
generalRecipe := tree.NewCompilerRecipe(db)
|
||||||
|
|
||||||
|
if fromRepo {
|
||||||
|
if err := installer.LoadBuildTree(generalRecipe, db, LuetCfg); err != nil {
|
||||||
|
Warning("errors while loading trees from repositories", err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for _, src := range treePaths {
|
for _, src := range treePaths {
|
||||||
Info("Loading tree", src)
|
Info("Loading tree", src)
|
||||||
helpers.CheckErr(generalRecipe.Load(src))
|
helpers.CheckErr(generalRecipe.Load(src))
|
||||||
@@ -202,7 +199,6 @@ Build packages specifying multiple definition trees:
|
|||||||
}
|
}
|
||||||
} else if !all {
|
} else if !all {
|
||||||
for _, a := range args {
|
for _, a := range args {
|
||||||
|
|
||||||
pack, err := helpers.ParsePackageStr(a)
|
pack, err := helpers.ParsePackageStr(a)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Fatal("Invalid package string ", a, ": ", err.Error())
|
Fatal("Invalid package string ", a, ": ", err.Error())
|
||||||
@@ -310,7 +306,6 @@ func init() {
|
|||||||
buildCmd.Flags().StringSliceP("tree", "t", []string{path}, "Path of the tree to use.")
|
buildCmd.Flags().StringSliceP("tree", "t", []string{path}, "Path of the tree to use.")
|
||||||
buildCmd.Flags().String("backend", "docker", "backend used (docker,img)")
|
buildCmd.Flags().String("backend", "docker", "backend used (docker,img)")
|
||||||
buildCmd.Flags().Bool("privileged", true, "Privileged (Keep permissions)")
|
buildCmd.Flags().Bool("privileged", true, "Privileged (Keep permissions)")
|
||||||
buildCmd.Flags().String("database", "memory", "database used for solving (memory,boltdb)")
|
|
||||||
buildCmd.Flags().Bool("revdeps", false, "Build with revdeps")
|
buildCmd.Flags().Bool("revdeps", false, "Build with revdeps")
|
||||||
buildCmd.Flags().Bool("all", false, "Build all specfiles in the tree")
|
buildCmd.Flags().Bool("all", false, "Build all specfiles in the tree")
|
||||||
buildCmd.Flags().Bool("full", false, "Build all packages (optimized)")
|
buildCmd.Flags().Bool("full", false, "Build all packages (optimized)")
|
||||||
@@ -333,6 +328,7 @@ func init() {
|
|||||||
buildCmd.Flags().Int("solver-attempts", 9000, "Solver maximum attempts")
|
buildCmd.Flags().Int("solver-attempts", 9000, "Solver maximum attempts")
|
||||||
buildCmd.Flags().Bool("solver-concurrent", false, "Use concurrent solver (experimental)")
|
buildCmd.Flags().Bool("solver-concurrent", false, "Use concurrent solver (experimental)")
|
||||||
buildCmd.Flags().Bool("live-output", LuetCfg.GetGeneral().ShowBuildOutput, "Enable live output of the build phase.")
|
buildCmd.Flags().Bool("live-output", LuetCfg.GetGeneral().ShowBuildOutput, "Enable live output of the build phase.")
|
||||||
|
buildCmd.Flags().Bool("from-repositories", false, "Consume the user-defined repositories to pull specfiles from")
|
||||||
|
|
||||||
buildCmd.Flags().Bool("pretend", false, "Just print what packages will be compiled")
|
buildCmd.Flags().Bool("pretend", false, "Just print what packages will be compiled")
|
||||||
buildCmd.Flags().StringArrayP("pull-repository", "p", []string{}, "A list of repositories to pull the cache from")
|
buildCmd.Flags().StringArrayP("pull-repository", "p", []string{}, "A list of repositories to pull the cache from")
|
||||||
|
@@ -70,16 +70,6 @@ To force install a package:
|
|||||||
toInstall = append(toInstall, pack)
|
toInstall = append(toInstall, pack)
|
||||||
}
|
}
|
||||||
|
|
||||||
// This shouldn't be necessary, but we need to unmarshal the repositories to a concrete struct, thus we need to port them back to the Repositories type
|
|
||||||
repos := installer.Repositories{}
|
|
||||||
for _, repo := range LuetCfg.SystemRepositories {
|
|
||||||
if !repo.Enable {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
r := installer.NewSystemRepository(repo)
|
|
||||||
repos = append(repos, r)
|
|
||||||
}
|
|
||||||
|
|
||||||
stype := LuetCfg.Viper.GetString("solver.type")
|
stype := LuetCfg.Viper.GetString("solver.type")
|
||||||
discount := LuetCfg.Viper.GetFloat64("solver.discount")
|
discount := LuetCfg.Viper.GetFloat64("solver.discount")
|
||||||
rate := LuetCfg.Viper.GetFloat64("solver.rate")
|
rate := LuetCfg.Viper.GetFloat64("solver.rate")
|
||||||
@@ -111,6 +101,7 @@ To force install a package:
|
|||||||
}
|
}
|
||||||
|
|
||||||
Debug("Solver", LuetCfg.GetSolverOptions().CompactString())
|
Debug("Solver", LuetCfg.GetSolverOptions().CompactString())
|
||||||
|
repos := installer.SystemRepositories(LuetCfg)
|
||||||
|
|
||||||
// Load config protect configs
|
// Load config protect configs
|
||||||
installer.LoadConfigProtectConfs(LuetCfg)
|
installer.LoadConfigProtectConfs(LuetCfg)
|
||||||
|
4
go.mod
4
go.mod
@@ -20,8 +20,10 @@ require (
|
|||||||
github.com/genuinetools/img v0.5.11
|
github.com/genuinetools/img v0.5.11
|
||||||
github.com/ghodss/yaml v1.0.0
|
github.com/ghodss/yaml v1.0.0
|
||||||
github.com/google/go-containerregistry v0.2.1
|
github.com/google/go-containerregistry v0.2.1
|
||||||
|
github.com/google/renameio v1.0.0
|
||||||
github.com/hashicorp/go-multierror v1.0.0
|
github.com/hashicorp/go-multierror v1.0.0
|
||||||
github.com/hashicorp/go-version v1.2.1
|
github.com/hashicorp/go-version v1.2.1
|
||||||
|
github.com/imdario/mergo v0.3.8
|
||||||
github.com/jedib0t/go-pretty v4.3.0+incompatible
|
github.com/jedib0t/go-pretty v4.3.0+incompatible
|
||||||
github.com/jedib0t/go-pretty/v6 v6.0.5
|
github.com/jedib0t/go-pretty/v6 v6.0.5
|
||||||
github.com/jinzhu/copier v0.0.0-20180308034124-7e38e58719c3
|
github.com/jinzhu/copier v0.0.0-20180308034124-7e38e58719c3
|
||||||
@@ -51,7 +53,7 @@ require (
|
|||||||
github.com/theupdateframework/notary v0.7.0
|
github.com/theupdateframework/notary v0.7.0
|
||||||
go.etcd.io/bbolt v1.3.5
|
go.etcd.io/bbolt v1.3.5
|
||||||
go.uber.org/atomic v1.5.1 // indirect
|
go.uber.org/atomic v1.5.1 // indirect
|
||||||
go.uber.org/multierr v1.4.0 // indirect
|
go.uber.org/multierr v1.4.0
|
||||||
go.uber.org/zap v1.13.0
|
go.uber.org/zap v1.13.0
|
||||||
google.golang.org/grpc v1.29.1
|
google.golang.org/grpc v1.29.1
|
||||||
gopkg.in/yaml.v2 v2.3.0
|
gopkg.in/yaml.v2 v2.3.0
|
||||||
|
2
go.sum
2
go.sum
@@ -493,6 +493,8 @@ github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hf
|
|||||||
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||||
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||||
|
github.com/google/renameio v1.0.0 h1:xhp2CnJmgQmpJU4RY8chagahUq5mbPPAbiSQstKpVMA=
|
||||||
|
github.com/google/renameio v1.0.0/go.mod h1:t/HQoYBZSsWSNK35C6CO/TpPLDVWvxOHboWUAweKUpk=
|
||||||
github.com/google/shlex v0.0.0-20150127133951-6f45313302b9 h1:JM174NTeGNJ2m/oLH3UOWOvWQQKd+BoL3hcSCUWFLt0=
|
github.com/google/shlex v0.0.0-20150127133951-6f45313302b9 h1:JM174NTeGNJ2m/oLH3UOWOvWQQKd+BoL3hcSCUWFLt0=
|
||||||
github.com/google/shlex v0.0.0-20150127133951-6f45313302b9/go.mod h1:RpwtwJQFrIEPstU94h88MWPXP2ektJZ8cZ0YntAmXiE=
|
github.com/google/shlex v0.0.0-20150127133951-6f45313302b9/go.mod h1:RpwtwJQFrIEPstU94h88MWPXP2ektJZ8cZ0YntAmXiE=
|
||||||
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
|
@@ -27,6 +27,7 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/imdario/mergo"
|
||||||
bus "github.com/mudler/luet/pkg/bus"
|
bus "github.com/mudler/luet/pkg/bus"
|
||||||
"github.com/mudler/luet/pkg/compiler/backend"
|
"github.com/mudler/luet/pkg/compiler/backend"
|
||||||
artifact "github.com/mudler/luet/pkg/compiler/types/artifact"
|
artifact "github.com/mudler/luet/pkg/compiler/types/artifact"
|
||||||
@@ -37,6 +38,7 @@ import (
|
|||||||
pkg "github.com/mudler/luet/pkg/package"
|
pkg "github.com/mudler/luet/pkg/package"
|
||||||
"github.com/mudler/luet/pkg/solver"
|
"github.com/mudler/luet/pkg/solver"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
"gopkg.in/yaml.v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
const BuildFile = "build.yaml"
|
const BuildFile = "build.yaml"
|
||||||
@@ -48,19 +50,11 @@ type ArtifactIndex []*artifact.PackageArtifact
|
|||||||
func (i ArtifactIndex) CleanPath() ArtifactIndex {
|
func (i ArtifactIndex) CleanPath() ArtifactIndex {
|
||||||
newIndex := ArtifactIndex{}
|
newIndex := ArtifactIndex{}
|
||||||
for _, art := range i {
|
for _, art := range i {
|
||||||
// FIXME: This is a dup and makes difficult to add attributes to artifacts
|
copy := art.ShallowCopy()
|
||||||
newIndex = append(newIndex, &artifact.PackageArtifact{
|
copy.Path = path.Base(art.Path)
|
||||||
Path: path.Base(art.Path),
|
newIndex = append(newIndex, copy)
|
||||||
SourceAssertion: art.SourceAssertion,
|
|
||||||
CompileSpec: art.CompileSpec,
|
|
||||||
Dependencies: art.Dependencies,
|
|
||||||
CompressionType: art.CompressionType,
|
|
||||||
Checksums: art.Checksums,
|
|
||||||
Files: art.Files,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
return newIndex
|
return newIndex
|
||||||
//Update if exists, otherwise just create
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type LuetCompiler struct {
|
type LuetCompiler struct {
|
||||||
@@ -544,7 +538,7 @@ func (cs *LuetCompiler) resolveExistingImageHash(imageHash string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func LoadArtifactFromYaml(spec *compilerspec.LuetCompilationSpec) (*artifact.PackageArtifact, error) {
|
func LoadArtifactFromYaml(spec *compilerspec.LuetCompilationSpec) (*artifact.PackageArtifact, error) {
|
||||||
metaFile := spec.GetPackage().GetFingerPrint() + ".metadata.yaml"
|
metaFile := spec.GetPackage().GetMetadataFilePath()
|
||||||
dat, err := ioutil.ReadFile(spec.Rel(metaFile))
|
dat, err := ioutil.ReadFile(spec.Rel(metaFile))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "Error reading file "+metaFile)
|
return nil, errors.Wrap(err, "Error reading file "+metaFile)
|
||||||
@@ -731,6 +725,12 @@ func genImageList(refs []string, hash string) []string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (cs *LuetCompiler) compile(concurrency int, keepPermissions bool, p *compilerspec.LuetCompilationSpec) (*artifact.PackageArtifact, error) {
|
func (cs *LuetCompiler) compile(concurrency int, keepPermissions bool, p *compilerspec.LuetCompilationSpec) (*artifact.PackageArtifact, error) {
|
||||||
|
if len(p.BuildOptions.PullImageRepository) != 0 {
|
||||||
|
orig := cs.Options.PullImageRepository
|
||||||
|
cs.Options.PullImageRepository = append(orig, p.BuildOptions.PullImageRepository...)
|
||||||
|
defer func() { cs.Options.PullImageRepository = orig }()
|
||||||
|
}
|
||||||
|
|
||||||
Info(":package: Compiling", p.GetPackage().HumanReadableString(), ".... :coffee:")
|
Info(":package: Compiling", p.GetPackage().HumanReadableString(), ".... :coffee:")
|
||||||
|
|
||||||
Debug(fmt.Sprintf("%s: has images %t, empty package: %t", p.GetPackage().HumanReadableString(), p.HasImageSource(), p.EmptyPackage()))
|
Debug(fmt.Sprintf("%s: has images %t, empty package: %t", p.GetPackage().HumanReadableString(), p.HasImageSource(), p.EmptyPackage()))
|
||||||
@@ -866,7 +866,7 @@ func (cs *LuetCompiler) compile(concurrency int, keepPermissions bool, p *compil
|
|||||||
|
|
||||||
type templatedata map[string]interface{}
|
type templatedata map[string]interface{}
|
||||||
|
|
||||||
func (cs *LuetCompiler) templatePackage(pack pkg.Package) ([]byte, error) {
|
func (cs *LuetCompiler) templatePackage(vals []map[string]interface{}, pack pkg.Package) ([]byte, error) {
|
||||||
|
|
||||||
var dataresult []byte
|
var dataresult []byte
|
||||||
val := pack.Rel(DefinitionFile)
|
val := pack.Rel(DefinitionFile)
|
||||||
@@ -876,7 +876,7 @@ func (cs *LuetCompiler) templatePackage(pack pkg.Package) ([]byte, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "unmarshalling values")
|
return nil, errors.Wrap(err, "unmarshalling values")
|
||||||
}
|
}
|
||||||
cs.Options.BuildValues = []map[string]interface{}{(map[string]interface{})(dst)}
|
cs.Options.BuildValues = append(vals, (map[string]interface{})(dst))
|
||||||
|
|
||||||
if _, err := os.Stat(pack.Rel(CollectionFile)); err == nil {
|
if _, err := os.Stat(pack.Rel(CollectionFile)); err == nil {
|
||||||
val = pack.Rel(CollectionFile)
|
val = pack.Rel(CollectionFile)
|
||||||
@@ -897,14 +897,46 @@ func (cs *LuetCompiler) templatePackage(pack pkg.Package) ([]byte, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
raw := packsRaw.Find(pack.GetName(), pack.GetCategory(), pack.GetVersion())
|
raw := packsRaw.Find(pack.GetName(), pack.GetCategory(), pack.GetVersion())
|
||||||
|
td := templatedata{}
|
||||||
|
if len(vals) > 0 {
|
||||||
|
for _, bv := range vals {
|
||||||
|
current := templatedata(bv)
|
||||||
|
if err := mergo.Merge(&td, current); err != nil {
|
||||||
|
return nil, errors.Wrap(err, "merging values maps")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
dat, err := helpers.RenderHelm(string(dataBuild), raw, dst)
|
if err := mergo.Merge(&td, raw); err != nil {
|
||||||
|
return nil, errors.Wrap(err, "merging values maps")
|
||||||
|
}
|
||||||
|
|
||||||
|
dat, err := helpers.RenderHelm(string(dataBuild), td, dst)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "rendering file "+pack.Rel(BuildFile))
|
return nil, errors.Wrap(err, "rendering file "+pack.Rel(BuildFile))
|
||||||
}
|
}
|
||||||
dataresult = []byte(dat)
|
dataresult = []byte(dat)
|
||||||
} else {
|
} else {
|
||||||
out, err := helpers.RenderFiles(pack.Rel(BuildFile), val, cs.Options.BuildValuesFile...)
|
bv := cs.Options.BuildValuesFile
|
||||||
|
if len(vals) > 0 {
|
||||||
|
valuesdir, err := ioutil.TempDir("", "genvalues")
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "Could not create tempdir")
|
||||||
|
}
|
||||||
|
defer os.RemoveAll(valuesdir) // clean up
|
||||||
|
for _, b := range vals {
|
||||||
|
out, err := yaml.Marshal(b)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "while marshalling values file")
|
||||||
|
}
|
||||||
|
f := filepath.Join(valuesdir, helpers.RandStringRunes(20))
|
||||||
|
if err := ioutil.WriteFile(f, out, os.ModePerm); err != nil {
|
||||||
|
return nil, errors.Wrap(err, "while writing temporary values file")
|
||||||
|
}
|
||||||
|
bv = append([]string{f}, bv...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out, err := helpers.RenderFiles(pack.Rel(BuildFile), val, bv...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "rendering file "+pack.Rel(BuildFile))
|
return nil, errors.Wrap(err, "rendering file "+pack.Rel(BuildFile))
|
||||||
}
|
}
|
||||||
@@ -922,12 +954,43 @@ func (cs *LuetCompiler) FromPackage(p pkg.Package) (*compilerspec.LuetCompilatio
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes, err := cs.templatePackage(pack)
|
opts := options.Compiler{}
|
||||||
|
|
||||||
|
artifactMetadataFile := filepath.Join(p.GetTreeDir(), p.GetMetadataFilePath())
|
||||||
|
|
||||||
|
if fi, err := os.Stat(artifactMetadataFile); err == nil {
|
||||||
|
f, err := os.Open(fi.Name())
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "could not open %s", fi.Name())
|
||||||
|
}
|
||||||
|
dat, err := ioutil.ReadAll(f)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
art, err := artifact.NewPackageArtifactFromYaml(dat)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "could not decode package from yaml")
|
||||||
|
}
|
||||||
|
|
||||||
|
opts = art.CompileSpec.BuildOptions
|
||||||
|
opts.PushImageRepository = ""
|
||||||
|
|
||||||
|
} else if !os.IsNotExist(err) {
|
||||||
|
Debug("error reading already existing artifact metadata file: ", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
bytes, err := cs.templatePackage(opts.BuildValues, pack)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "while rendering package template")
|
return nil, errors.Wrap(err, "while rendering package template")
|
||||||
}
|
}
|
||||||
|
|
||||||
return compilerspec.NewLuetCompilationSpec(bytes, pack)
|
newSpec, err := compilerspec.NewLuetCompilationSpec(bytes, pack)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
newSpec.BuildOptions = opts
|
||||||
|
|
||||||
|
return newSpec, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetBackend returns the current compilation backend
|
// GetBackend returns the current compilation backend
|
||||||
|
@@ -62,6 +62,11 @@ type PackageArtifact struct {
|
|||||||
Files []string `json:"files"`
|
Files []string `json:"files"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *PackageArtifact) ShallowCopy() *PackageArtifact {
|
||||||
|
copy := *p
|
||||||
|
return ©
|
||||||
|
}
|
||||||
|
|
||||||
func NewPackageArtifact(path string) *PackageArtifact {
|
func NewPackageArtifact(path string) *PackageArtifact {
|
||||||
return &PackageArtifact{Path: path, Dependencies: []*PackageArtifact{}, Checksums: Checksums{}, CompressionType: compression.None}
|
return &PackageArtifact{Path: path, Dependencies: []*PackageArtifact{}, Checksums: Checksums{}, CompressionType: compression.None}
|
||||||
}
|
}
|
||||||
@@ -129,7 +134,7 @@ func (a *PackageArtifact) WriteYaml(dst string) error {
|
|||||||
return errors.Wrap(err, "While marshalling for PackageArtifact YAML")
|
return errors.Wrap(err, "While marshalling for PackageArtifact YAML")
|
||||||
}
|
}
|
||||||
|
|
||||||
err = ioutil.WriteFile(filepath.Join(dst, a.CompileSpec.GetPackage().GetFingerPrint()+".metadata.yaml"), data, os.ModePerm)
|
err = ioutil.WriteFile(filepath.Join(dst, a.CompileSpec.GetPackage().GetMetadataFilePath()), data, os.ModePerm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "While writing PackageArtifact YAML")
|
return errors.Wrap(err, "While writing PackageArtifact YAML")
|
||||||
}
|
}
|
||||||
|
@@ -19,6 +19,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"math/rand"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"sort"
|
"sort"
|
||||||
@@ -26,10 +27,41 @@ import (
|
|||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/google/renameio"
|
||||||
copy "github.com/otiai10/copy"
|
copy "github.com/otiai10/copy"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var letterRunes = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
|
||||||
|
|
||||||
|
func RandStringRunes(n int) string {
|
||||||
|
b := make([]rune, n)
|
||||||
|
for i := range b {
|
||||||
|
b[i] = letterRunes[rand.Intn(len(letterRunes))]
|
||||||
|
}
|
||||||
|
return string(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Move(src, dst string) error {
|
||||||
|
f, err := os.Open(src)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
t, err := renameio.TempFile("", dst)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer t.Cleanup()
|
||||||
|
|
||||||
|
_, err = io.Copy(t, f)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return t.CloseAtomicallyReplace()
|
||||||
|
}
|
||||||
|
|
||||||
func OrderFiles(target string, files []string) ([]string, []string) {
|
func OrderFiles(target string, files []string) ([]string, []string) {
|
||||||
|
|
||||||
var newFiles []string
|
var newFiles []string
|
||||||
|
@@ -16,6 +16,7 @@
|
|||||||
package installer
|
package installer
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
@@ -27,6 +28,7 @@ import (
|
|||||||
|
|
||||||
artifact "github.com/mudler/luet/pkg/compiler/types/artifact"
|
artifact "github.com/mudler/luet/pkg/compiler/types/artifact"
|
||||||
compression "github.com/mudler/luet/pkg/compiler/types/compression"
|
compression "github.com/mudler/luet/pkg/compiler/types/compression"
|
||||||
|
"go.uber.org/multierr"
|
||||||
|
|
||||||
"github.com/mudler/luet/pkg/compiler"
|
"github.com/mudler/luet/pkg/compiler"
|
||||||
"github.com/mudler/luet/pkg/config"
|
"github.com/mudler/luet/pkg/config"
|
||||||
@@ -100,6 +102,40 @@ func NewLuetSystemRepositoryMetadata(file string, removeFile bool) (*LuetSystemR
|
|||||||
return ans, nil
|
return ans, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SystemRepositories returns the repositories from the local configuration file
|
||||||
|
func SystemRepositories(c *config.LuetConfig) Repositories {
|
||||||
|
repos := Repositories{}
|
||||||
|
for _, repo := range c.SystemRepositories {
|
||||||
|
if !repo.Enable {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
r := NewSystemRepository(repo)
|
||||||
|
repos = append(repos, r)
|
||||||
|
}
|
||||||
|
return repos
|
||||||
|
}
|
||||||
|
|
||||||
|
// LoadBuildTree loads to the tree the compilation specs from the system repositories
|
||||||
|
func LoadBuildTree(t tree.Builder, db pkg.PackageDatabase, c *config.LuetConfig) error {
|
||||||
|
var reserr error
|
||||||
|
repos := SystemRepositories(c)
|
||||||
|
for _, r := range repos {
|
||||||
|
repodir, err := config.LuetCfg.GetSystem().TempDir(r.Name)
|
||||||
|
if err != nil {
|
||||||
|
reserr = multierr.Append(reserr, err)
|
||||||
|
}
|
||||||
|
if err := r.SyncBuildMetadata(repodir); err != nil {
|
||||||
|
reserr = multierr.Append(reserr, err)
|
||||||
|
}
|
||||||
|
if err := t.Load(filepath.Join(repodir, "tree")); err != nil {
|
||||||
|
reserr = multierr.Append(reserr, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
repos.SyncDatabase(db)
|
||||||
|
|
||||||
|
return reserr
|
||||||
|
}
|
||||||
|
|
||||||
func (m *LuetSystemRepositoryMetadata) WriteFile(path string) error {
|
func (m *LuetSystemRepositoryMetadata) WriteFile(path string) error {
|
||||||
data, err := yaml.Marshal(m)
|
data, err := yaml.Marshal(m)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -471,7 +507,7 @@ func (r *LuetSystemRepository) AddRepositoryFile(src, fileKey, repositoryRoot st
|
|||||||
treeFile, err := r.GetRepositoryFile(fileKey)
|
treeFile, err := r.GetRepositoryFile(fileKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
treeFile = defaults
|
treeFile = defaults
|
||||||
r.SetRepositoryFile(fileKey, treeFile)
|
// r.SetRepositoryFile(fileKey, treeFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
a := artifact.NewPackageArtifact(filepath.Join(repositoryRoot, treeFile.GetFileName()))
|
a := artifact.NewPackageArtifact(filepath.Join(repositoryRoot, treeFile.GetFileName()))
|
||||||
@@ -594,6 +630,70 @@ func (r *LuetSystemRepository) SearchArtefact(p pkg.Package) (*artifact.PackageA
|
|||||||
return nil, errors.New("Not found")
|
return nil, errors.New("Not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *LuetSystemRepository) getRepoFile(c Client, key string) (*artifact.PackageArtifact, error) {
|
||||||
|
|
||||||
|
treeFile, err := r.GetRepositoryFile(key)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "key %s not present in the repository", key)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get Tree
|
||||||
|
downloadedTreeFile, err := c.DownloadFile(treeFile.GetFileName())
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "While downloading "+treeFile.GetFileName())
|
||||||
|
}
|
||||||
|
//defer os.Remove(downloadedTreeFile)
|
||||||
|
|
||||||
|
treeFileArtifact := artifact.NewPackageArtifact(downloadedTreeFile)
|
||||||
|
treeFileArtifact.Checksums = treeFile.GetChecksums()
|
||||||
|
treeFileArtifact.CompressionType = treeFile.GetCompressionType()
|
||||||
|
|
||||||
|
err = treeFileArtifact.Verify()
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "file integrity check failure")
|
||||||
|
}
|
||||||
|
|
||||||
|
return treeFileArtifact, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *LuetSystemRepository) SyncBuildMetadata(path string) error {
|
||||||
|
|
||||||
|
repo, err := r.Sync(false)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "while syncronizing repository")
|
||||||
|
}
|
||||||
|
|
||||||
|
c := repo.Client()
|
||||||
|
if c == nil {
|
||||||
|
return errors.New("no client could be generated from repository")
|
||||||
|
}
|
||||||
|
|
||||||
|
a, err := repo.getRepoFile(c, REPOFILE_COMPILER_TREE_KEY)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed while getting: %s", REPOFILE_COMPILER_TREE_KEY)
|
||||||
|
}
|
||||||
|
|
||||||
|
defer os.RemoveAll(a.Path)
|
||||||
|
|
||||||
|
if err := a.Unpack(filepath.Join(path, "tree"), false); err != nil {
|
||||||
|
return errors.Wrapf(err, "while unpacking: %s", REPOFILE_COMPILER_TREE_KEY)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, ai := range repo.GetTree().GetDatabase().World() {
|
||||||
|
// Retrieve remote repository.yaml for retrieve revision and date
|
||||||
|
file, err := c.DownloadFile(ai.GetMetadataFilePath())
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrapf(err, "while downloading metadata for %s", ai.HumanReadableString())
|
||||||
|
}
|
||||||
|
if err := helpers.Move(file, filepath.Join(path, ai.GetMetadataFilePath())); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (r *LuetSystemRepository) Sync(force bool) (*LuetSystemRepository, error) {
|
func (r *LuetSystemRepository) Sync(force bool) (*LuetSystemRepository, error) {
|
||||||
var repoUpdated bool = false
|
var repoUpdated bool = false
|
||||||
var treefs, metafs string
|
var treefs, metafs string
|
||||||
@@ -612,7 +712,7 @@ func (r *LuetSystemRepository) Sync(force bool) (*LuetSystemRepository, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
repobasedir := config.LuetCfg.GetSystem().GetRepoDatabaseDirPath(r.GetName())
|
repobasedir := config.LuetCfg.GetSystem().GetRepoDatabaseDirPath(r.GetName())
|
||||||
repo, err := r.ReadSpecFile(file)
|
downloadedRepoMeta, err := r.ReadSpecFile(file)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -624,8 +724,8 @@ func (r *LuetSystemRepository) Sync(force bool) (*LuetSystemRepository, error) {
|
|||||||
if !force {
|
if !force {
|
||||||
localRepo, _ := r.ReadSpecFile(filepath.Join(repobasedir, REPOSITORY_SPECFILE))
|
localRepo, _ := r.ReadSpecFile(filepath.Join(repobasedir, REPOSITORY_SPECFILE))
|
||||||
if localRepo != nil {
|
if localRepo != nil {
|
||||||
if localRepo.GetRevision() == repo.GetRevision() &&
|
if localRepo.GetRevision() == downloadedRepoMeta.GetRevision() &&
|
||||||
localRepo.GetLastUpdate() == repo.GetLastUpdate() {
|
localRepo.GetLastUpdate() == downloadedRepoMeta.GetLastUpdate() {
|
||||||
repoUpdated = true
|
repoUpdated = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -652,47 +752,22 @@ func (r *LuetSystemRepository) Sync(force bool) (*LuetSystemRepository, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// POST: treeFile and metaFile are present. I check this inside
|
// treeFile and metaFile must be present, they aren't optional
|
||||||
// ReadSpecFile and NewLuetSystemRepositoryFromYaml
|
|
||||||
treeFile, _ := repo.GetRepositoryFile(REPOFILE_TREE_KEY)
|
|
||||||
metaFile, _ := repo.GetRepositoryFile(REPOFILE_META_KEY)
|
|
||||||
|
|
||||||
if !repoUpdated {
|
if !repoUpdated {
|
||||||
|
|
||||||
// Get Tree
|
treeFileArtifact, err := downloadedRepoMeta.getRepoFile(c, REPOFILE_TREE_KEY)
|
||||||
downloadedTreeFile, err := c.DownloadFile(treeFile.GetFileName())
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "While downloading "+treeFile.GetFileName())
|
return nil, errors.Wrapf(err, "while fetching '%s'", REPOFILE_TREE_KEY)
|
||||||
}
|
|
||||||
defer os.Remove(downloadedTreeFile)
|
|
||||||
|
|
||||||
// Treat the file as artifact, in order to verify it
|
|
||||||
treeFileArtifact := artifact.NewPackageArtifact(downloadedTreeFile)
|
|
||||||
treeFileArtifact.Checksums = treeFile.GetChecksums()
|
|
||||||
treeFileArtifact.CompressionType = treeFile.GetCompressionType()
|
|
||||||
|
|
||||||
err = treeFileArtifact.Verify()
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Wrap(err, "Tree integrity check failure")
|
|
||||||
}
|
}
|
||||||
|
defer os.Remove(treeFileArtifact.Path)
|
||||||
|
|
||||||
Debug("Tree tarball for the repository " + r.GetName() + " downloaded correctly.")
|
Debug("Tree tarball for the repository " + r.GetName() + " downloaded correctly.")
|
||||||
|
|
||||||
// Get Repository Metadata
|
metaFileArtifact, err := downloadedRepoMeta.getRepoFile(c, REPOFILE_META_KEY)
|
||||||
downloadedMeta, err := c.DownloadFile(metaFile.GetFileName())
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "While downloading "+metaFile.GetFileName())
|
return nil, errors.Wrapf(err, "while fetching '%s'", REPOFILE_META_KEY)
|
||||||
}
|
|
||||||
defer os.Remove(downloadedMeta)
|
|
||||||
|
|
||||||
metaFileArtifact := artifact.NewPackageArtifact(downloadedMeta)
|
|
||||||
metaFileArtifact.Checksums = metaFile.GetChecksums()
|
|
||||||
metaFileArtifact.CompressionType = metaFile.GetCompressionType()
|
|
||||||
|
|
||||||
err = metaFileArtifact.Verify()
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Wrap(err, "Metadata integrity check failure")
|
|
||||||
}
|
}
|
||||||
|
defer os.Remove(metaFileArtifact.Path)
|
||||||
|
|
||||||
Debug("Metadata tarball for the repository " + r.GetName() + " downloaded correctly.")
|
Debug("Metadata tarball for the repository " + r.GetName() + " downloaded correctly.")
|
||||||
|
|
||||||
@@ -722,17 +797,17 @@ func (r *LuetSystemRepository) Sync(force bool) (*LuetSystemRepository, error) {
|
|||||||
return nil, errors.Wrap(err, "Error met while unpacking metadata")
|
return nil, errors.Wrap(err, "Error met while unpacking metadata")
|
||||||
}
|
}
|
||||||
|
|
||||||
tsec, _ := strconv.ParseInt(repo.GetLastUpdate(), 10, 64)
|
tsec, _ := strconv.ParseInt(downloadedRepoMeta.GetLastUpdate(), 10, 64)
|
||||||
|
|
||||||
InfoC(
|
InfoC(
|
||||||
aurora.Bold(
|
aurora.Bold(
|
||||||
aurora.Red(":house: Repository "+repo.GetName()+" revision: ")).String() +
|
aurora.Red(":house: Repository "+downloadedRepoMeta.GetName()+" revision: ")).String() +
|
||||||
aurora.Bold(aurora.Green(repo.GetRevision())).String() + " - " +
|
aurora.Bold(aurora.Green(downloadedRepoMeta.GetRevision())).String() + " - " +
|
||||||
aurora.Bold(aurora.Green(time.Unix(tsec, 0).String())).String(),
|
aurora.Bold(aurora.Green(time.Unix(tsec, 0).String())).String(),
|
||||||
)
|
)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
Info("Repository", repo.GetName(), "is already up to date.")
|
Info("Repository", downloadedRepoMeta.GetName(), "is already up to date.")
|
||||||
}
|
}
|
||||||
|
|
||||||
meta, err := NewLuetSystemRepositoryMetadata(
|
meta, err := NewLuetSystemRepositoryMetadata(
|
||||||
@@ -741,7 +816,7 @@ func (r *LuetSystemRepository) Sync(force bool) (*LuetSystemRepository, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "While processing "+REPOSITORY_METAFILE)
|
return nil, errors.Wrap(err, "While processing "+REPOSITORY_METAFILE)
|
||||||
}
|
}
|
||||||
repo.SetIndex(meta.ToArtifactIndex())
|
downloadedRepoMeta.SetIndex(meta.ToArtifactIndex())
|
||||||
|
|
||||||
reciper := tree.NewInstallerRecipe(pkg.NewInMemoryDatabase(false))
|
reciper := tree.NewInstallerRecipe(pkg.NewInMemoryDatabase(false))
|
||||||
err = reciper.Load(treefs)
|
err = reciper.Load(treefs)
|
||||||
@@ -749,29 +824,33 @@ func (r *LuetSystemRepository) Sync(force bool) (*LuetSystemRepository, error) {
|
|||||||
return nil, errors.Wrap(err, "Error met while unpacking rootfs")
|
return nil, errors.Wrap(err, "Error met while unpacking rootfs")
|
||||||
}
|
}
|
||||||
|
|
||||||
repo.SetTree(reciper)
|
downloadedRepoMeta.SetTree(reciper)
|
||||||
repo.SetTreePath(treefs)
|
downloadedRepoMeta.SetTreePath(treefs)
|
||||||
|
|
||||||
// Copy the local available data to the one which was synced
|
// Copy the local available data to the one which was synced
|
||||||
// e.g. locally we can override the type (disk), or priority
|
// e.g. locally we can override the type (disk), or priority
|
||||||
// while remotely it could be advertized differently
|
// while remotely it could be advertized differently
|
||||||
repo.SetUrls(r.GetUrls())
|
r.fill(downloadedRepoMeta)
|
||||||
repo.SetAuthentication(r.GetAuthentication())
|
|
||||||
repo.SetType(r.GetType())
|
|
||||||
repo.SetPriority(r.GetPriority())
|
|
||||||
repo.SetName(r.GetName())
|
|
||||||
repo.SetVerify(r.GetVerify())
|
|
||||||
|
|
||||||
InfoC(
|
InfoC(
|
||||||
aurora.Yellow(":information_source:").String() +
|
aurora.Yellow(":information_source:").String() +
|
||||||
aurora.Magenta("Repository: ").String() +
|
aurora.Magenta("Repository: ").String() +
|
||||||
aurora.Green(aurora.Bold(repo.GetName()).String()).String() +
|
aurora.Green(aurora.Bold(downloadedRepoMeta.GetName()).String()).String() +
|
||||||
aurora.Magenta(" Priority: ").String() +
|
aurora.Magenta(" Priority: ").String() +
|
||||||
aurora.Bold(aurora.Green(repo.GetPriority())).String() +
|
aurora.Bold(aurora.Green(downloadedRepoMeta.GetPriority())).String() +
|
||||||
aurora.Magenta(" Type: ").String() +
|
aurora.Magenta(" Type: ").String() +
|
||||||
aurora.Bold(aurora.Green(repo.GetType())).String(),
|
aurora.Bold(aurora.Green(downloadedRepoMeta.GetType())).String(),
|
||||||
)
|
)
|
||||||
return repo, nil
|
return downloadedRepoMeta, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *LuetSystemRepository) fill(r2 *LuetSystemRepository) {
|
||||||
|
r2.SetUrls(r.GetUrls())
|
||||||
|
r2.SetAuthentication(r.GetAuthentication())
|
||||||
|
r2.SetType(r.GetType())
|
||||||
|
r2.SetPriority(r.GetPriority())
|
||||||
|
r2.SetName(r.GetName())
|
||||||
|
r2.SetVerify(r.GetVerify())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *LuetSystemRepository) Serialize() (*LuetSystemRepositoryMetadata, LuetSystemRepository) {
|
func (r *LuetSystemRepository) Serialize() (*LuetSystemRepositoryMetadata, LuetSystemRepository) {
|
||||||
|
@@ -44,23 +44,22 @@ type dockerRepositoryGenerator struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (l *dockerRepositoryGenerator) Initialize(path string, db pkg.PackageDatabase) ([]*artifact.PackageArtifact, error) {
|
func (l *dockerRepositoryGenerator) Initialize(path string, db pkg.PackageDatabase) ([]*artifact.PackageArtifact, error) {
|
||||||
return generatePackageImages(l.b, l.imagePrefix, path, db, l.imagePush, l.force)
|
|
||||||
}
|
|
||||||
|
|
||||||
func pushImage(b compiler.CompilerBackend, image string, force bool) error {
|
Info("Generating docker images for packages in", l.imagePrefix)
|
||||||
if b.ImageAvailable(image) && !force {
|
|
||||||
Debug("Image", image, "already present, skipping")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return b.Push(backend.Options{ImageName: image})
|
|
||||||
}
|
|
||||||
|
|
||||||
func generatePackageImages(b compiler.CompilerBackend, imagePrefix, path string, db pkg.PackageDatabase, imagePush, force bool) ([]*artifact.PackageArtifact, error) {
|
|
||||||
Info("Generating docker images for packages in", imagePrefix)
|
|
||||||
var art []*artifact.PackageArtifact
|
var art []*artifact.PackageArtifact
|
||||||
var ff = func(currentpath string, info os.FileInfo, err error) error {
|
var ff = func(currentpath string, info os.FileInfo, err error) error {
|
||||||
|
if err != nil {
|
||||||
|
Debug("Skipping", info.Name(), err.Error())
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
if !strings.HasSuffix(info.Name(), ".metadata.yaml") {
|
if strings.HasSuffix(info.Name(), ".metadata.yaml") {
|
||||||
|
a := artifact.NewPackageArtifact(info.Name())
|
||||||
|
imageRepo := fmt.Sprintf("%s:%s", l.imagePrefix, filepath.Base(info.Name()))
|
||||||
|
|
||||||
|
if err := l.pushFileFromArtifact(a, imageRepo); err != nil {
|
||||||
|
return errors.Wrap(err, "while pushing file from artifact")
|
||||||
|
}
|
||||||
return nil // Skip with no errors
|
return nil // Skip with no errors
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,19 +84,19 @@ func generatePackageImages(b compiler.CompilerBackend, imagePrefix, path string,
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
packageImage := fmt.Sprintf("%s:%s", imagePrefix, a.CompileSpec.GetPackage().ImageID())
|
packageImage := fmt.Sprintf("%s:%s", l.imagePrefix, a.CompileSpec.GetPackage().ImageID())
|
||||||
|
|
||||||
if imagePush && b.ImageAvailable(packageImage) && !force {
|
if l.imagePush && l.b.ImageAvailable(packageImage) && !l.force {
|
||||||
Info("Image", packageImage, "already present, skipping. use --force-push to override")
|
Info("Image", packageImage, "already present, skipping. use --force-push to override")
|
||||||
} else {
|
} else {
|
||||||
Info("Generating final image", packageImage,
|
Info("Generating final image", packageImage,
|
||||||
"for package ", a.CompileSpec.GetPackage().HumanReadableString())
|
"for package ", a.CompileSpec.GetPackage().HumanReadableString())
|
||||||
if opts, err := a.GenerateFinalImage(packageImage, b, true); err != nil {
|
if opts, err := a.GenerateFinalImage(packageImage, l.b, true); err != nil {
|
||||||
return errors.Wrap(err, "Failed generating metadata tree"+opts.ImageName)
|
return errors.Wrap(err, "Failed generating metadata tree"+opts.ImageName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if imagePush {
|
if l.imagePush {
|
||||||
if err := pushImage(b, packageImage, force); err != nil {
|
if err := pushImage(l.b, packageImage, l.force); err != nil {
|
||||||
return errors.Wrapf(err, "Failed while pushing image: '%s'", packageImage)
|
return errors.Wrapf(err, "Failed while pushing image: '%s'", packageImage)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -115,13 +114,21 @@ func generatePackageImages(b compiler.CompilerBackend, imagePrefix, path string,
|
|||||||
return art, nil
|
return art, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *dockerRepositoryGenerator) pushFileFromArtifact(a *artifact.PackageArtifact, imageTree string, r *LuetSystemRepository) error {
|
func pushImage(b compiler.CompilerBackend, image string, force bool) error {
|
||||||
|
if b.ImageAvailable(image) && !force {
|
||||||
|
Debug("Image", image, "already present, skipping")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return b.Push(backend.Options{ImageName: image})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *dockerRepositoryGenerator) pushFileFromArtifact(a *artifact.PackageArtifact, imageTree string) error {
|
||||||
Debug("Generating image", imageTree)
|
Debug("Generating image", imageTree)
|
||||||
if opts, err := a.GenerateFinalImage(imageTree, r.GetBackend(), false); err != nil {
|
if opts, err := a.GenerateFinalImage(imageTree, d.b, false); err != nil {
|
||||||
return errors.Wrap(err, "Failed generating metadata tree "+opts.ImageName)
|
return errors.Wrap(err, "Failed generating metadata tree "+opts.ImageName)
|
||||||
}
|
}
|
||||||
if r.PushImages {
|
if d.imagePush {
|
||||||
if err := pushImage(r.GetBackend(), imageTree, true); err != nil {
|
if err := pushImage(d.b, imageTree, true); err != nil {
|
||||||
return errors.Wrapf(err, "Failed while pushing image: '%s'", imageTree)
|
return errors.Wrapf(err, "Failed while pushing image: '%s'", imageTree)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -144,13 +151,13 @@ func (d *dockerRepositoryGenerator) pushRepoMetadata(repospec string, r *LuetSys
|
|||||||
a := artifact.NewPackageArtifact(tempRepoFile)
|
a := artifact.NewPackageArtifact(tempRepoFile)
|
||||||
imageRepo := fmt.Sprintf("%s:%s", d.imagePrefix, REPOSITORY_SPECFILE)
|
imageRepo := fmt.Sprintf("%s:%s", d.imagePrefix, REPOSITORY_SPECFILE)
|
||||||
|
|
||||||
if err := d.pushFileFromArtifact(a, imageRepo, r); err != nil {
|
if err := d.pushFileFromArtifact(a, imageRepo); err != nil {
|
||||||
return errors.Wrap(err, "while pushing file from artifact")
|
return errors.Wrap(err, "while pushing file from artifact")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *dockerRepositoryGenerator) pushImageFromArtifact(a *artifact.PackageArtifact, r *LuetSystemRepository) error {
|
func (d *dockerRepositoryGenerator) pushImageFromArtifact(a *artifact.PackageArtifact, b compiler.CompilerBackend) error {
|
||||||
// we generate a new archive containing the required compressed file.
|
// we generate a new archive containing the required compressed file.
|
||||||
// TODO: Bundle all the extra files in 1 docker image only, instead of an image for each file
|
// TODO: Bundle all the extra files in 1 docker image only, instead of an image for each file
|
||||||
treeArchive, err := artifact.CreateArtifactForFile(a.Path)
|
treeArchive, err := artifact.CreateArtifactForFile(a.Path)
|
||||||
@@ -159,7 +166,7 @@ func (d *dockerRepositoryGenerator) pushImageFromArtifact(a *artifact.PackageArt
|
|||||||
}
|
}
|
||||||
imageTree := fmt.Sprintf("%s:%s", d.imagePrefix, a.GetFileName())
|
imageTree := fmt.Sprintf("%s:%s", d.imagePrefix, a.GetFileName())
|
||||||
|
|
||||||
return d.pushFileFromArtifact(treeArchive, imageTree, r)
|
return d.pushFileFromArtifact(treeArchive, imageTree)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate creates a Docker luet repository
|
// Generate creates a Docker luet repository
|
||||||
@@ -216,7 +223,7 @@ func (d *dockerRepositoryGenerator) Generate(r *LuetSystemRepository, imagePrefi
|
|||||||
|
|
||||||
// we generate a new archive containing the required compressed file.
|
// we generate a new archive containing the required compressed file.
|
||||||
// TODO: Bundle all the extra files in 1 docker image only, instead of an image for each file
|
// TODO: Bundle all the extra files in 1 docker image only, instead of an image for each file
|
||||||
if err := d.pushImageFromArtifact(a, r); err != nil {
|
if err := d.pushImageFromArtifact(a, d.b); err != nil {
|
||||||
return errors.Wrap(err, "error met while pushing runtime tree")
|
return errors.Wrap(err, "error met while pushing runtime tree")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -226,7 +233,7 @@ func (d *dockerRepositoryGenerator) Generate(r *LuetSystemRepository, imagePrefi
|
|||||||
}
|
}
|
||||||
// we generate a new archive containing the required compressed file.
|
// we generate a new archive containing the required compressed file.
|
||||||
// TODO: Bundle all the extra files in 1 docker image only, instead of an image for each file
|
// TODO: Bundle all the extra files in 1 docker image only, instead of an image for each file
|
||||||
if err := d.pushImageFromArtifact(a, r); err != nil {
|
if err := d.pushImageFromArtifact(a, d.b); err != nil {
|
||||||
return errors.Wrap(err, "error met while pushing compiler tree")
|
return errors.Wrap(err, "error met while pushing compiler tree")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -242,7 +249,7 @@ func (d *dockerRepositoryGenerator) Generate(r *LuetSystemRepository, imagePrefi
|
|||||||
return errors.Wrap(err, "failed adding Metadata file to repository")
|
return errors.Wrap(err, "failed adding Metadata file to repository")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := d.pushImageFromArtifact(a, r); err != nil {
|
if err := d.pushImageFromArtifact(a, d.b); err != nil {
|
||||||
return errors.Wrap(err, "error met while pushing docker image from artifact")
|
return errors.Wrap(err, "error met while pushing docker image from artifact")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -113,6 +113,10 @@ type Package interface {
|
|||||||
GetBuildTimestamp() string
|
GetBuildTimestamp() string
|
||||||
|
|
||||||
Clone() Package
|
Clone() Package
|
||||||
|
|
||||||
|
GetMetadataFilePath() string
|
||||||
|
SetTreeDir(s string)
|
||||||
|
GetTreeDir() string
|
||||||
}
|
}
|
||||||
|
|
||||||
type Tree interface {
|
type Tree interface {
|
||||||
@@ -210,6 +214,11 @@ func (t *DefaultPackage) JSON() ([]byte, error) {
|
|||||||
return buffer.Bytes(), err
|
return buffer.Bytes(), err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetMetadataFilePath returns the canonical name of an artifact metadata file
|
||||||
|
func (d *DefaultPackage) GetMetadataFilePath() string {
|
||||||
|
return d.GetFingerPrint() + ".metadata.yaml"
|
||||||
|
}
|
||||||
|
|
||||||
// DefaultPackage represent a standard package definition
|
// DefaultPackage represent a standard package definition
|
||||||
type DefaultPackage struct {
|
type DefaultPackage struct {
|
||||||
ID int `storm:"id,increment" json:"id"` // primary key with auto increment
|
ID int `storm:"id,increment" json:"id"` // primary key with auto increment
|
||||||
@@ -235,6 +244,8 @@ type DefaultPackage struct {
|
|||||||
BuildTimestamp string `json:"buildtimestamp,omitempty"`
|
BuildTimestamp string `json:"buildtimestamp,omitempty"`
|
||||||
|
|
||||||
Labels map[string]string `json:"labels,omitempty"` // Affects YAML field names too.
|
Labels map[string]string `json:"labels,omitempty"` // Affects YAML field names too.
|
||||||
|
|
||||||
|
treeDir string
|
||||||
}
|
}
|
||||||
|
|
||||||
// State represent the package state
|
// State represent the package state
|
||||||
@@ -251,6 +262,12 @@ func NewPackage(name, version string, requires []*DefaultPackage, conflicts []*D
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *DefaultPackage) SetTreeDir(s string) {
|
||||||
|
p.treeDir = s
|
||||||
|
}
|
||||||
|
func (p *DefaultPackage) GetTreeDir() string {
|
||||||
|
return p.treeDir
|
||||||
|
}
|
||||||
func (p *DefaultPackage) String() string {
|
func (p *DefaultPackage) String() string {
|
||||||
b, err := p.JSON()
|
b, err := p.JSON()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@@ -98,6 +98,7 @@ func (r *CompilerRecipe) Load(path string) error {
|
|||||||
}
|
}
|
||||||
// Path is set only internally when tree is loaded from disk
|
// Path is set only internally when tree is loaded from disk
|
||||||
pack.SetPath(filepath.Dir(currentpath))
|
pack.SetPath(filepath.Dir(currentpath))
|
||||||
|
pack.SetTreeDir(path)
|
||||||
|
|
||||||
// Instead of rdeps, have a different tree for build deps.
|
// Instead of rdeps, have a different tree for build deps.
|
||||||
compileDefPath := pack.Rel(CompilerDefinitionFile)
|
compileDefPath := pack.Rel(CompilerDefinitionFile)
|
||||||
@@ -126,18 +127,25 @@ func (r *CompilerRecipe) Load(path string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case CollectionFile:
|
case CollectionFile:
|
||||||
|
|
||||||
dat, err := ioutil.ReadFile(currentpath)
|
dat, err := ioutil.ReadFile(currentpath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "Error reading file "+currentpath)
|
return errors.Wrap(err, "Error reading file "+currentpath)
|
||||||
}
|
}
|
||||||
|
|
||||||
packs, err := pkg.DefaultPackagesFromYaml(dat)
|
packs, err := pkg.DefaultPackagesFromYaml(dat)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "Error reading yaml "+currentpath)
|
return errors.Wrap(err, "Error reading yaml "+currentpath)
|
||||||
}
|
}
|
||||||
|
|
||||||
packsRaw, err := pkg.GetRawPackages(dat)
|
packsRaw, err := pkg.GetRawPackages(dat)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "Error reading raw packages from "+currentpath)
|
||||||
|
}
|
||||||
|
|
||||||
for _, pack := range packs {
|
for _, pack := range packs {
|
||||||
pack.SetPath(filepath.Dir(currentpath))
|
pack.SetPath(filepath.Dir(currentpath))
|
||||||
|
pack.SetTreeDir(path)
|
||||||
|
|
||||||
// Instead of rdeps, have a different tree for build deps.
|
// Instead of rdeps, have a different tree for build deps.
|
||||||
compileDefPath := pack.Rel(CompilerDefinitionFile)
|
compileDefPath := pack.Rel(CompilerDefinitionFile)
|
||||||
@@ -170,9 +178,7 @@ func (r *CompilerRecipe) Load(path string) error {
|
|||||||
return errors.Wrap(err, "Error creating package "+pack.GetName())
|
return errors.Wrap(err, "Error creating package "+pack.GetName())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user