diff --git a/cmd/box/exec.go b/cmd/box/exec.go index 40eb5e5f..32a2e109 100644 --- a/cmd/box/exec.go +++ b/cmd/box/exec.go @@ -21,8 +21,8 @@ import ( b64 "encoding/base64" + "github.com/mudler/luet/cmd/util" "github.com/mudler/luet/pkg/box" - . "github.com/mudler/luet/pkg/logger" "github.com/spf13/cobra" ) @@ -54,18 +54,18 @@ func NewBoxExecCommand() *cobra.Command { args = ss } - Info("Executing", args, "in", rootfs) + util.DefaultContext.Info("Executing", args, "in", rootfs) b := box.NewBox(entrypoint, args, mounts, envs, rootfs, stdin, stdout, stderr) err := b.Run() if err != nil { - Fatal(err) + util.DefaultContext.Fatal(err) } }, } path, err := os.Getwd() if err != nil { - Fatal(err) + util.DefaultContext.Fatal(err) } ans.Flags().String("rootfs", path, "Rootfs path") ans.Flags().Bool("stdin", false, "Attach to stdin") diff --git a/cmd/build.go b/cmd/build.go index 5dece17f..b8b5800f 100644 --- a/cmd/build.go +++ b/cmd/build.go @@ -29,8 +29,6 @@ import ( "github.com/mudler/luet/pkg/compiler/types/compression" "github.com/mudler/luet/pkg/compiler/types/options" - . "github.com/mudler/luet/pkg/config" - . "github.com/mudler/luet/pkg/logger" pkg "github.com/mudler/luet/pkg/package" "github.com/mudler/luet/pkg/solver" tree "github.com/mudler/luet/pkg/tree" @@ -94,7 +92,7 @@ Build packages specifying multiple definition trees: treePaths := viper.GetStringSlice("tree") dst := viper.GetString("destination") - concurrency := LuetCfg.GetGeneral().Concurrency + concurrency := util.DefaultContext.Config.GetGeneral().Concurrency backendType := viper.GetString("backend") privileged := viper.GetBool("privileged") revdeps := viper.GetBool("revdeps") @@ -117,7 +115,7 @@ Build packages specifying multiple definition trees: out, _ := cmd.Flags().GetString("output") if out != "terminal" { - LuetCfg.GetLogging().SetLogLevel("error") + util.DefaultContext.Config.GetLogging().SetLogLevel("error") } pretend, _ := cmd.Flags().GetBool("pretend") fromRepo, _ := cmd.Flags().GetBool("from-repositories") @@ -125,7 +123,7 @@ Build packages specifying multiple definition trees: compilerSpecs := compilerspec.NewLuetCompilationspecs() var db pkg.PackageDatabase - compilerBackend, err := compiler.NewBackend(backendType) + compilerBackend, err := compiler.NewBackend(util.DefaultContext, backendType) helpers.CheckErr(err) db = pkg.NewInMemoryDatabase(false) @@ -134,24 +132,24 @@ Build packages specifying multiple definition trees: generalRecipe := tree.NewCompilerRecipe(db) if fromRepo { - if err := installer.LoadBuildTree(generalRecipe, db, LuetCfg); err != nil { - Warning("errors while loading trees from repositories", err.Error()) + if err := installer.LoadBuildTree(generalRecipe, db, util.DefaultContext); err != nil { + util.DefaultContext.Warning("errors while loading trees from repositories", err.Error()) } } for _, src := range treePaths { - Info("Loading tree", src) + util.DefaultContext.Info("Loading tree", src) helpers.CheckErr(generalRecipe.Load(src)) } - Info("Building in", dst) + util.DefaultContext.Info("Building in", dst) - opts := util.SetSolverConfig() + opts := util.SetSolverConfig(util.DefaultContext) pullRepo, _ := cmd.Flags().GetStringArray("pull-repository") - LuetCfg.GetGeneral().ShowBuildOutput = viper.GetBool("general.show_build_output") + util.DefaultContext.Config.GetGeneral().ShowBuildOutput = viper.GetBool("general.show_build_output") - Debug("Solver", opts.CompactString()) + util.DefaultContext.Debug("Solver", opts.CompactString()) opts.Options = solver.Options{Type: solver.SingleCoreSimple, Concurrency: concurrency} @@ -163,13 +161,14 @@ Build packages specifying multiple definition trees: options.WithPullRepositories(pullRepo), options.WithPushRepository(imageRepository), options.Rebuild(rebuild), - options.WithTemplateFolder(util.TemplateFolders(fromRepo, treePaths)), + options.WithTemplateFolder(util.TemplateFolders(util.DefaultContext, fromRepo, treePaths)), options.WithSolverOptions(*opts), options.Wait(wait), options.OnlyTarget(onlyTarget), options.PullFirst(pull), options.KeepImg(keepImages), options.OnlyDeps(onlydeps), + options.WithContext(util.DefaultContext), options.BackendArgs(backendArgs), options.Concurrency(concurrency), options.WithCompressionType(compression.Implementation(compressionType)), @@ -178,10 +177,10 @@ Build packages specifying multiple definition trees: if full { specs, err := luetCompiler.FromDatabase(generalRecipe.GetDatabase(), true, dst) if err != nil { - Fatal(err.Error()) + util.DefaultContext.Fatal(err.Error()) } for _, spec := range specs { - Info(":package: Selecting ", spec.GetPackage().GetName(), spec.GetPackage().GetVersion()) + util.DefaultContext.Info(":package: Selecting ", spec.GetPackage().GetName(), spec.GetPackage().GetVersion()) compilerSpecs.Add(spec) } @@ -189,12 +188,12 @@ Build packages specifying multiple definition trees: for _, a := range args { pack, err := helpers.ParsePackageStr(a) if err != nil { - Fatal("Invalid package string ", a, ": ", err.Error()) + util.DefaultContext.Fatal("Invalid package string ", a, ": ", err.Error()) } spec, err := luetCompiler.FromPackage(pack) if err != nil { - Fatal("Error: " + err.Error()) + util.DefaultContext.Fatal("Error: " + err.Error()) } spec.SetOutputPath(dst) @@ -206,9 +205,9 @@ Build packages specifying multiple definition trees: for _, p := range w { spec, err := luetCompiler.FromPackage(p) if err != nil { - Fatal("Error: " + err.Error()) + util.DefaultContext.Fatal("Error: " + err.Error()) } - Info(":package: Selecting ", p.GetName(), p.GetVersion()) + util.DefaultContext.Info(":package: Selecting ", p.GetName(), p.GetVersion()) spec.SetOutputPath(dst) compilerSpecs.Add(spec) } @@ -267,7 +266,7 @@ Build packages specifying multiple definition trees: fmt.Println(string(j2)) case "terminal": for _, p := range results.Packages { - Info(p.String()) + util.DefaultContext.Info(p.String()) } } } else { @@ -276,12 +275,12 @@ Build packages specifying multiple definition trees: } if len(errs) != 0 { for _, e := range errs { - Error("Error: " + e.Error()) + util.DefaultContext.Error("Error: " + e.Error()) } - Fatal("Bailing out") + util.DefaultContext.Fatal("Bailing out") } for _, a := range artifact { - Info("Artifact generated:", a.Path) + util.DefaultContext.Info("Artifact generated:", a.Path) } }, } @@ -289,7 +288,7 @@ Build packages specifying multiple definition trees: func init() { path, err := os.Getwd() if err != nil { - Fatal(err) + util.DefaultContext.Fatal(err) } buildCmd.Flags().StringSliceP("tree", "t", []string{path}, "Path of the tree to use.") @@ -316,7 +315,7 @@ func init() { buildCmd.Flags().Float32("solver-discount", 1.0, "Solver discount rate") buildCmd.Flags().Int("solver-attempts", 9000, "Solver maximum attempts") 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", util.DefaultContext.Config.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("rebuild", false, "To combine with --pull. Allows to rebuild the target package even if an image is available, against a local values file") buildCmd.Flags().Bool("pretend", false, "Just print what packages will be compiled") diff --git a/cmd/cleanup.go b/cmd/cleanup.go index d3570ba4..0c7ed4c8 100644 --- a/cmd/cleanup.go +++ b/cmd/cleanup.go @@ -21,9 +21,7 @@ import ( "path/filepath" "github.com/mudler/luet/cmd/util" - . "github.com/mudler/luet/pkg/config" fileHelper "github.com/mudler/luet/pkg/helpers/file" - . "github.com/mudler/luet/pkg/logger" "github.com/spf13/cobra" ) @@ -37,13 +35,13 @@ var cleanupCmd = &cobra.Command{ }, Run: func(cmd *cobra.Command, args []string) { var cleaned int = 0 - util.SetSystemConfig() + util.SetSystemConfig(util.DefaultContext) // Check if cache dir exists - if fileHelper.Exists(LuetCfg.GetSystem().GetSystemPkgsCacheDirPath()) { + if fileHelper.Exists(util.DefaultContext.Config.GetSystem().GetSystemPkgsCacheDirPath()) { - files, err := ioutil.ReadDir(LuetCfg.GetSystem().GetSystemPkgsCacheDirPath()) + files, err := ioutil.ReadDir(util.DefaultContext.Config.GetSystem().GetSystemPkgsCacheDirPath()) if err != nil { - Fatal("Error on read cachedir ", err.Error()) + util.DefaultContext.Fatal("Error on read cachedir ", err.Error()) } for _, file := range files { @@ -51,20 +49,20 @@ var cleanupCmd = &cobra.Command{ continue } - if LuetCfg.GetGeneral().Debug { - Info("Removing ", file.Name()) + if util.DefaultContext.Config.GetGeneral().Debug { + util.DefaultContext.Info("Removing ", file.Name()) } err := os.RemoveAll( - filepath.Join(LuetCfg.GetSystem().GetSystemPkgsCacheDirPath(), file.Name())) + filepath.Join(util.DefaultContext.Config.GetSystem().GetSystemPkgsCacheDirPath(), file.Name())) if err != nil { - Fatal("Error on removing", file.Name()) + util.DefaultContext.Fatal("Error on removing", file.Name()) } cleaned++ } } - Info("Cleaned: ", cleaned, "packages.") + util.DefaultContext.Info("Cleaned: ", cleaned, "packages.") }, } diff --git a/cmd/config.go b/cmd/config.go index 95eb99ee..55b67a3f 100644 --- a/cmd/config.go +++ b/cmd/config.go @@ -18,8 +18,7 @@ package cmd import ( "fmt" - config "github.com/mudler/luet/pkg/config" - . "github.com/mudler/luet/pkg/logger" + "github.com/mudler/luet/cmd/util" "github.com/spf13/cobra" ) @@ -30,9 +29,9 @@ var configCmd = &cobra.Command{ Long: `Show luet configuration`, Aliases: []string{"c"}, Run: func(cmd *cobra.Command, args []string) { - data, err := config.LuetCfg.YAML() + data, err := util.DefaultContext.Config.YAML() if err != nil { - Fatal(err.Error()) + util.DefaultContext.Fatal(err.Error()) } fmt.Println(string(data)) diff --git a/cmd/create-repo.go b/cmd/create-repo.go index 0e30389c..20631a89 100644 --- a/cmd/create-repo.go +++ b/cmd/create-repo.go @@ -19,9 +19,9 @@ import ( "path/filepath" helpers "github.com/mudler/luet/cmd/helpers" + "github.com/mudler/luet/cmd/util" "github.com/mudler/luet/pkg/compiler" "github.com/mudler/luet/pkg/compiler/types/compression" - . "github.com/mudler/luet/pkg/config" installer "github.com/mudler/luet/pkg/installer" // . "github.com/mudler/luet/pkg/logger" @@ -96,7 +96,7 @@ Create a repository from the metadata description defined in the luet.yaml confi treeFile := installer.NewDefaultTreeRepositoryFile() metaFile := installer.NewDefaultMetaRepositoryFile() - compilerBackend, err := compiler.NewBackend(backendType) + compilerBackend, err := compiler.NewBackend(util.DefaultContext, backendType) helpers.CheckErr(err) force := viper.GetBool("force-push") imagePush := viper.GetBool("push-images") @@ -106,16 +106,16 @@ Create a repository from the metadata description defined in the luet.yaml confi installer.WithPushImages(imagePush), installer.WithForce(force), installer.FromRepository(fromRepo), - installer.WithConfig(LuetCfg), installer.WithImagePrefix(dst), installer.WithDatabase(pkg.NewInMemoryDatabase(false)), installer.WithCompilerBackend(compilerBackend), installer.FromMetadata(viper.GetBool("from-metadata")), + installer.WithContext(util.DefaultContext), } if source_repo != "" { // Search for system repository - lrepo, err := LuetCfg.GetSystemRepository(source_repo) + lrepo, err := util.DefaultContext.Config.GetSystemRepository(source_repo) helpers.CheckErr(err) if len(treePaths) <= 0 { @@ -167,7 +167,7 @@ Create a repository from the metadata description defined in the luet.yaml confi repo.SetRepositoryFile(installer.REPOFILE_TREE_KEY, treeFile) repo.SetRepositoryFile(installer.REPOFILE_META_KEY, metaFile) - err = repo.Write(dst, reset, true) + err = repo.Write(util.DefaultContext, dst, reset, true) helpers.CheckErr(err) }, diff --git a/cmd/database/create.go b/cmd/database/create.go index c938165c..955e2e55 100644 --- a/cmd/database/create.go +++ b/cmd/database/create.go @@ -21,11 +21,8 @@ import ( "github.com/mudler/luet/cmd/util" artifact "github.com/mudler/luet/pkg/api/core/types/artifact" - . "github.com/mudler/luet/pkg/logger" pkg "github.com/mudler/luet/pkg/package" - . "github.com/mudler/luet/pkg/config" - "github.com/spf13/cobra" ) @@ -50,35 +47,35 @@ For reference, inspect a "metadata.yaml" file generated while running "luet buil }, Run: func(cmd *cobra.Command, args []string) { - util.SetSystemConfig() - systemDB := LuetCfg.GetSystemDB() + util.SetSystemConfig(util.DefaultContext) + systemDB := util.DefaultContext.Config.GetSystemDB() for _, a := range args { dat, err := ioutil.ReadFile(a) if err != nil { - Fatal("Failed reading ", a, ": ", err.Error()) + util.DefaultContext.Fatal("Failed reading ", a, ": ", err.Error()) } art, err := artifact.NewPackageArtifactFromYaml(dat) if err != nil { - Fatal("Failed reading yaml ", a, ": ", err.Error()) + util.DefaultContext.Fatal("Failed reading yaml ", a, ": ", err.Error()) } files := art.Files // Check if the package is already present if p, err := systemDB.FindPackage(art.CompileSpec.GetPackage()); err == nil && p.GetName() != "" { - Fatal("Package", art.CompileSpec.GetPackage().HumanReadableString(), + util.DefaultContext.Fatal("Package", art.CompileSpec.GetPackage().HumanReadableString(), " already present.") } if _, err := systemDB.CreatePackage(art.CompileSpec.GetPackage()); err != nil { - Fatal("Failed to create ", a, ": ", err.Error()) + util.DefaultContext.Fatal("Failed to create ", a, ": ", err.Error()) } if err := systemDB.SetPackageFiles(&pkg.PackageFile{PackageFingerprint: art.CompileSpec.GetPackage().GetFingerPrint(), Files: files}); err != nil { - Fatal("Failed setting package files for ", a, ": ", err.Error()) + util.DefaultContext.Fatal("Failed setting package files for ", a, ": ", err.Error()) } - Info(art.CompileSpec.GetPackage().HumanReadableString(), " created") + util.DefaultContext.Info(art.CompileSpec.GetPackage().HumanReadableString(), " created") } }, diff --git a/cmd/database/get.go b/cmd/database/get.go index b48522b4..2043226a 100644 --- a/cmd/database/get.go +++ b/cmd/database/get.go @@ -22,8 +22,6 @@ import ( "github.com/mudler/luet/cmd/util" "gopkg.in/yaml.v2" - . "github.com/mudler/luet/pkg/config" - "github.com/spf13/cobra" ) @@ -43,9 +41,9 @@ To return also files: }, Run: func(cmd *cobra.Command, args []string) { showFiles, _ := cmd.Flags().GetBool("files") - util.SetSystemConfig() + util.SetSystemConfig(util.DefaultContext) - systemDB := LuetCfg.GetSystemDB() + systemDB := util.DefaultContext.Config.GetSystemDB() for _, a := range args { pack, err := helpers.ParsePackageStr(a) diff --git a/cmd/database/remove.go b/cmd/database/remove.go index 86b24760..1934064a 100644 --- a/cmd/database/remove.go +++ b/cmd/database/remove.go @@ -16,11 +16,8 @@ package cmd_database import ( - . "github.com/mudler/luet/pkg/logger" - helpers "github.com/mudler/luet/cmd/helpers" "github.com/mudler/luet/cmd/util" - . "github.com/mudler/luet/pkg/config" "github.com/spf13/cobra" ) @@ -40,22 +37,22 @@ This commands takes multiple packages as arguments and prunes their entries from util.BindSystemFlags(cmd) }, Run: func(cmd *cobra.Command, args []string) { - util.SetSystemConfig() + util.SetSystemConfig(util.DefaultContext) - systemDB := LuetCfg.GetSystemDB() + systemDB := util.DefaultContext.Config.GetSystemDB() for _, a := range args { pack, err := helpers.ParsePackageStr(a) if err != nil { - Fatal("Invalid package string ", a, ": ", err.Error()) + util.DefaultContext.Fatal("Invalid package string ", a, ": ", err.Error()) } if err := systemDB.RemovePackage(pack); err != nil { - Fatal("Failed removing ", a, ": ", err.Error()) + util.DefaultContext.Fatal("Failed removing ", a, ": ", err.Error()) } if err := systemDB.RemovePackageFiles(pack); err != nil { - Fatal("Failed removing files for ", a, ": ", err.Error()) + util.DefaultContext.Fatal("Failed removing files for ", a, ": ", err.Error()) } } diff --git a/cmd/exec.go b/cmd/exec.go index 3d50f12b..0b06146f 100644 --- a/cmd/exec.go +++ b/cmd/exec.go @@ -20,8 +20,8 @@ import ( b64 "encoding/base64" + "github.com/mudler/luet/cmd/util" "github.com/mudler/luet/pkg/box" - . "github.com/mudler/luet/pkg/logger" "github.com/pkg/errors" "github.com/spf13/cobra" ) @@ -55,12 +55,12 @@ var execCmd = &cobra.Command{ args = ss } - Info("Executing", args, "in", rootfs) + util.DefaultContext.Info("Executing", args, "in", rootfs) b := box.NewBox(entrypoint, args, mounts, envs, rootfs, stdin, stdout, stderr) err := b.Exec() if err != nil { - Fatal(errors.Wrap(err, fmt.Sprintf("entrypoint: %s rootfs: %s", entrypoint, rootfs))) + util.DefaultContext.Fatal(errors.Wrap(err, fmt.Sprintf("entrypoint: %s rootfs: %s", entrypoint, rootfs))) } }, } @@ -68,7 +68,7 @@ var execCmd = &cobra.Command{ func init() { path, err := os.Getwd() if err != nil { - Fatal(err) + util.DefaultContext.Fatal(err) } execCmd.Hidden = true execCmd.Flags().String("rootfs", path, "Rootfs path") diff --git a/cmd/helpers/cli.go b/cmd/helpers/cli.go index 467c634a..899e5811 100644 --- a/cmd/helpers/cli.go +++ b/cmd/helpers/cli.go @@ -22,9 +22,8 @@ import ( "regexp" "strings" - . "github.com/mudler/luet/pkg/logger" - _gentoo "github.com/Sabayon/pkgs-checker/pkg/gentoo" + "github.com/mudler/luet/cmd/util" pkg "github.com/mudler/luet/pkg/package" ) @@ -126,6 +125,6 @@ func ParsePackageStr(p string) (*pkg.DefaultPackage, error) { func CheckErr(err error) { if err != nil { - Fatal(err) + util.DefaultContext.Fatal(err) } } diff --git a/cmd/helpers/cli_suite_test.go b/cmd/helpers/cli_suite_test.go index 8cdf72be..4b644fd1 100644 --- a/cmd/helpers/cli_suite_test.go +++ b/cmd/helpers/cli_suite_test.go @@ -18,14 +18,11 @@ package cmd_helpers_test import ( "testing" - . "github.com/mudler/luet/cmd/util" - . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) func TestSolver(t *testing.T) { RegisterFailHandler(Fail) - LoadConfig() RunSpecs(t, "CLI helpers test Suite") } diff --git a/cmd/install.go b/cmd/install.go index cecff51b..62381a77 100644 --- a/cmd/install.go +++ b/cmd/install.go @@ -15,13 +15,12 @@ package cmd import ( + "github.com/mudler/luet/pkg/api/core/types" installer "github.com/mudler/luet/pkg/installer" "github.com/mudler/luet/pkg/solver" helpers "github.com/mudler/luet/cmd/helpers" "github.com/mudler/luet/cmd/util" - . "github.com/mudler/luet/pkg/config" - . "github.com/mudler/luet/pkg/logger" pkg "github.com/mudler/luet/pkg/package" "github.com/spf13/cobra" @@ -62,7 +61,7 @@ To force install a package: for _, a := range args { pack, err := helpers.ParsePackageStr(a) if err != nil { - Fatal("Invalid package string ", a, ": ", err.Error()) + util.DefaultContext.Fatal("Invalid package string ", a, ": ", err.Error()) } toInstall = append(toInstall, pack) } @@ -75,25 +74,25 @@ To force install a package: finalizerEnvs, _ := cmd.Flags().GetStringArray("finalizer-env") relax, _ := cmd.Flags().GetBool("relax") - util.SetSystemConfig() - util.SetSolverConfig() + util.SetSystemConfig(util.DefaultContext) + util.SetSolverConfig(util.DefaultContext) - LuetCfg.GetSolverOptions().Implementation = solver.SingleCoreSimple + util.DefaultContext.Config.GetSolverOptions().Implementation = solver.SingleCoreSimple - Debug("Solver", LuetCfg.GetSolverOptions().CompactString()) + util.DefaultContext.Debug("Solver", util.DefaultContext.Config.GetSolverOptions().CompactString()) // Load config protect configs - installer.LoadConfigProtectConfs(LuetCfg) + util.DefaultContext.Config.LoadConfigProtect(util.DefaultContext) // Load finalizer runtime environments - err := util.SetCliFinalizerEnvs(finalizerEnvs) + err := util.SetCliFinalizerEnvs(util.DefaultContext, finalizerEnvs) if err != nil { - Fatal(err.Error()) + util.DefaultContext.Fatal(err.Error()) } inst := installer.NewLuetInstaller(installer.LuetInstallerOptions{ - Concurrency: LuetCfg.GetGeneral().Concurrency, - SolverOptions: *LuetCfg.GetSolverOptions(), + Concurrency: util.DefaultContext.Config.GetGeneral().Concurrency, + SolverOptions: *util.DefaultContext.Config.GetSolverOptions(), NoDeps: nodeps, Force: force, OnlyDeps: onlydeps, @@ -101,13 +100,14 @@ To force install a package: DownloadOnly: downloadOnly, Ask: !yes, Relaxed: relax, - PackageRepositories: LuetCfg.SystemRepositories, + PackageRepositories: util.DefaultContext.Config.SystemRepositories, + Context: util.DefaultContext, }) - system := &installer.System{Database: LuetCfg.GetSystemDB(), Target: LuetCfg.GetSystem().Rootfs} + system := &installer.System{Database: util.DefaultContext.Config.GetSystemDB(), Target: util.DefaultContext.Config.GetSystem().Rootfs} err = inst.Install(toInstall, system) if err != nil { - Fatal("Error: " + err.Error()) + util.DefaultContext.Fatal("Error: " + err.Error()) } }, } @@ -117,7 +117,7 @@ func init() { installCmd.Flags().String("system-target", "", "System rootpath") installCmd.Flags().String("system-engine", "", "System DB engine") - installCmd.Flags().String("solver-type", "", "Solver strategy ( Defaults none, available: "+AvailableResolvers+" )") + installCmd.Flags().String("solver-type", "", "Solver strategy ( Defaults none, available: "+types.AvailableResolvers+" )") installCmd.Flags().Float32("solver-rate", 0.7, "Solver learning rate") installCmd.Flags().Float32("solver-discount", 1.0, "Solver discount rate") installCmd.Flags().Int("solver-attempts", 9000, "Solver maximum attempts") diff --git a/cmd/pack.go b/cmd/pack.go index 7a1b307e..8ef493e7 100644 --- a/cmd/pack.go +++ b/cmd/pack.go @@ -20,11 +20,10 @@ import ( "time" helpers "github.com/mudler/luet/cmd/helpers" + "github.com/mudler/luet/cmd/util" "github.com/mudler/luet/pkg/api/core/types/artifact" "github.com/mudler/luet/pkg/compiler/types/compression" compilerspec "github.com/mudler/luet/pkg/compiler/types/spec" - . "github.com/mudler/luet/pkg/config" - . "github.com/mudler/luet/pkg/logger" "github.com/spf13/cobra" "github.com/spf13/viper" @@ -53,17 +52,17 @@ Afterwards, you can use the content generated and associate it with a tree and a dst := viper.GetString("destination") compressionType := viper.GetString("compression") - concurrency := LuetCfg.GetGeneral().Concurrency + concurrency := util.DefaultContext.Config.GetGeneral().Concurrency if len(args) != 1 { - Fatal("You must specify a package name") + util.DefaultContext.Fatal("You must specify a package name") } packageName := args[0] p, err := helpers.ParsePackageStr(packageName) if err != nil { - Fatal("Invalid package string ", packageName, ": ", err.Error()) + util.DefaultContext.Fatal("Invalid package string ", packageName, ": ", err.Error()) } spec := &compilerspec.LuetCompilationSpec{Package: p} @@ -71,18 +70,18 @@ Afterwards, you can use the content generated and associate it with a tree and a a.CompressionType = compression.Implementation(compressionType) err = a.Compress(sourcePath, concurrency) if err != nil { - Fatal("failed compressing ", packageName, ": ", err.Error()) + util.DefaultContext.Fatal("failed compressing ", packageName, ": ", err.Error()) } a.CompileSpec = spec filelist, err := a.FileList() if err != nil { - Fatal("failed generating file list for ", packageName, ": ", err.Error()) + util.DefaultContext.Fatal("failed generating file list for ", packageName, ": ", err.Error()) } a.Files = filelist a.CompileSpec.GetPackage().SetBuildTimestamp(time.Now().String()) err = a.WriteYAML(dst) if err != nil { - Fatal("failed writing metadata yaml file for ", packageName, ": ", err.Error()) + util.DefaultContext.Fatal("failed writing metadata yaml file for ", packageName, ": ", err.Error()) } }, } @@ -90,7 +89,7 @@ Afterwards, you can use the content generated and associate it with a tree and a func init() { path, err := os.Getwd() if err != nil { - Fatal(err) + util.DefaultContext.Fatal(err) } packCmd.Flags().String("source", path, "Source folder") packCmd.Flags().String("destination", path, "Destination folder") diff --git a/cmd/reclaim.go b/cmd/reclaim.go index 48a67e8a..f12377ad 100644 --- a/cmd/reclaim.go +++ b/cmd/reclaim.go @@ -18,9 +18,6 @@ import ( "github.com/mudler/luet/cmd/util" installer "github.com/mudler/luet/pkg/installer" - . "github.com/mudler/luet/pkg/config" - . "github.com/mudler/luet/pkg/logger" - "github.com/spf13/cobra" "github.com/spf13/viper" ) @@ -39,23 +36,24 @@ var reclaimCmd = &cobra.Command{ It scans the target file system, and if finds a match with a package available in the repositories, it marks as installed in the system database. `, Run: func(cmd *cobra.Command, args []string) { - util.SetSystemConfig() + util.SetSystemConfig(util.DefaultContext) force := viper.GetBool("force") - Debug("Solver", LuetCfg.GetSolverOptions().CompactString()) + util.DefaultContext.Debug("Solver", util.DefaultContext.Config.GetSolverOptions().CompactString()) inst := installer.NewLuetInstaller(installer.LuetInstallerOptions{ - Concurrency: LuetCfg.GetGeneral().Concurrency, + Concurrency: util.DefaultContext.Config.GetGeneral().Concurrency, Force: force, PreserveSystemEssentialData: true, - PackageRepositories: LuetCfg.SystemRepositories, + PackageRepositories: util.DefaultContext.Config.SystemRepositories, + Context: util.DefaultContext, }) - system := &installer.System{Database: LuetCfg.GetSystemDB(), Target: LuetCfg.GetSystem().Rootfs} + system := &installer.System{Database: util.DefaultContext.Config.GetSystemDB(), Target: util.DefaultContext.Config.GetSystem().Rootfs} err := inst.Reclaim(system) if err != nil { - Fatal("Error: " + err.Error()) + util.DefaultContext.Fatal("Error: " + err.Error()) } }, } diff --git a/cmd/reinstall.go b/cmd/reinstall.go index 0d3c4d57..75f8b6a6 100644 --- a/cmd/reinstall.go +++ b/cmd/reinstall.go @@ -15,13 +15,12 @@ package cmd import ( + "github.com/mudler/luet/pkg/api/core/types" installer "github.com/mudler/luet/pkg/installer" "github.com/mudler/luet/pkg/solver" helpers "github.com/mudler/luet/cmd/helpers" "github.com/mudler/luet/cmd/util" - . "github.com/mudler/luet/pkg/config" - . "github.com/mudler/luet/pkg/logger" pkg "github.com/mudler/luet/pkg/package" "github.com/spf13/cobra" @@ -54,42 +53,43 @@ var reinstallCmd = &cobra.Command{ downloadOnly, _ := cmd.Flags().GetBool("download-only") - util.SetSystemConfig() + util.SetSystemConfig(util.DefaultContext) for _, a := range args { pack, err := helpers.ParsePackageStr(a) if err != nil { - Fatal("Invalid package string ", a, ": ", err.Error()) + util.DefaultContext.Fatal("Invalid package string ", a, ": ", err.Error()) } toUninstall = append(toUninstall, pack) toAdd = append(toAdd, pack) } - util.SetSolverConfig() + util.SetSolverConfig(util.DefaultContext) - LuetCfg.GetSolverOptions().Implementation = solver.SingleCoreSimple + util.DefaultContext.Config.GetSolverOptions().Implementation = solver.SingleCoreSimple - Debug("Solver", LuetCfg.GetSolverOptions().CompactString()) + util.DefaultContext.Debug("Solver", util.DefaultContext.Config.GetSolverOptions().CompactString()) // Load config protect configs - installer.LoadConfigProtectConfs(LuetCfg) + util.DefaultContext.Config.LoadConfigProtect(util.DefaultContext) inst := installer.NewLuetInstaller(installer.LuetInstallerOptions{ - Concurrency: LuetCfg.GetGeneral().Concurrency, - SolverOptions: *LuetCfg.GetSolverOptions(), + Concurrency: util.DefaultContext.Config.GetGeneral().Concurrency, + SolverOptions: *util.DefaultContext.Config.GetSolverOptions(), NoDeps: true, Force: force, OnlyDeps: onlydeps, PreserveSystemEssentialData: true, Ask: !yes, DownloadOnly: downloadOnly, - PackageRepositories: LuetCfg.SystemRepositories, + Context: util.DefaultContext, + PackageRepositories: util.DefaultContext.Config.SystemRepositories, }) - system := &installer.System{Database: LuetCfg.GetSystemDB(), Target: LuetCfg.GetSystem().Rootfs} + system := &installer.System{Database: util.DefaultContext.Config.GetSystemDB(), Target: util.DefaultContext.Config.GetSystem().Rootfs} err := inst.Swap(toUninstall, toAdd, system) if err != nil { - Fatal("Error: " + err.Error()) + util.DefaultContext.Fatal("Error: " + err.Error()) } }, } @@ -100,7 +100,7 @@ func init() { reinstallCmd.Flags().String("system-target", "", "System rootpath") reinstallCmd.Flags().String("system-engine", "", "System DB engine") - reinstallCmd.Flags().String("solver-type", "", "Solver strategy ( Defaults none, available: "+AvailableResolvers+" )") + reinstallCmd.Flags().String("solver-type", "", "Solver strategy ( Defaults none, available: "+types.AvailableResolvers+" )") reinstallCmd.Flags().Float32("solver-rate", 0.7, "Solver learning rate") reinstallCmd.Flags().Float32("solver-discount", 1.0, "Solver discount rate") reinstallCmd.Flags().Int("solver-attempts", 9000, "Solver maximum attempts") diff --git a/cmd/replace.go b/cmd/replace.go index 0a8f9336..641c097c 100644 --- a/cmd/replace.go +++ b/cmd/replace.go @@ -15,13 +15,13 @@ package cmd import ( + "github.com/mudler/luet/pkg/api/core/types" installer "github.com/mudler/luet/pkg/installer" "github.com/mudler/luet/pkg/solver" helpers "github.com/mudler/luet/cmd/helpers" "github.com/mudler/luet/cmd/util" - . "github.com/mudler/luet/pkg/config" - . "github.com/mudler/luet/pkg/logger" + pkg "github.com/mudler/luet/pkg/package" "github.com/spf13/cobra" @@ -57,12 +57,12 @@ var replaceCmd = &cobra.Command{ yes := viper.GetBool("yes") downloadOnly, _ := cmd.Flags().GetBool("download-only") - util.SetSystemConfig() - util.SetSolverConfig() + util.SetSystemConfig(util.DefaultContext) + util.SetSolverConfig(util.DefaultContext) for _, a := range args { pack, err := helpers.ParsePackageStr(a) if err != nil { - Fatal("Invalid package string ", a, ": ", err.Error()) + util.DefaultContext.Fatal("Invalid package string ", a, ": ", err.Error()) } toUninstall = append(toUninstall, pack) } @@ -70,34 +70,35 @@ var replaceCmd = &cobra.Command{ for _, a := range f { pack, err := helpers.ParsePackageStr(a) if err != nil { - Fatal("Invalid package string ", a, ": ", err.Error()) + util.DefaultContext.Fatal("Invalid package string ", a, ": ", err.Error()) } toAdd = append(toAdd, pack) } - LuetCfg.GetSolverOptions().Implementation = solver.SingleCoreSimple + util.DefaultContext.Config.GetSolverOptions().Implementation = solver.SingleCoreSimple - Debug("Solver", LuetCfg.GetSolverOptions().CompactString()) + util.DefaultContext.Debug("Solver", util.DefaultContext.Config.GetSolverOptions().CompactString()) // Load config protect configs - installer.LoadConfigProtectConfs(LuetCfg) + util.DefaultContext.Config.LoadConfigProtect(util.DefaultContext) inst := installer.NewLuetInstaller(installer.LuetInstallerOptions{ - Concurrency: LuetCfg.GetGeneral().Concurrency, - SolverOptions: *LuetCfg.GetSolverOptions(), + Concurrency: util.DefaultContext.Config.GetGeneral().Concurrency, + SolverOptions: *util.DefaultContext.Config.GetSolverOptions(), NoDeps: nodeps, Force: force, OnlyDeps: onlydeps, PreserveSystemEssentialData: true, Ask: !yes, DownloadOnly: downloadOnly, - PackageRepositories: LuetCfg.SystemRepositories, + PackageRepositories: util.DefaultContext.Config.SystemRepositories, + Context: util.DefaultContext, }) - system := &installer.System{Database: LuetCfg.GetSystemDB(), Target: LuetCfg.GetSystem().Rootfs} + system := &installer.System{Database: util.DefaultContext.Config.GetSystemDB(), Target: util.DefaultContext.Config.GetSystem().Rootfs} err := inst.Swap(toUninstall, toAdd, system) if err != nil { - Fatal("Error: " + err.Error()) + util.DefaultContext.Fatal("Error: " + err.Error()) } }, } @@ -108,7 +109,7 @@ func init() { replaceCmd.Flags().String("system-target", "", "System rootpath") replaceCmd.Flags().String("system-engine", "", "System DB engine") - replaceCmd.Flags().String("solver-type", "", "Solver strategy ( Defaults none, available: "+AvailableResolvers+" )") + replaceCmd.Flags().String("solver-type", "", "Solver strategy ( Defaults none, available: "+types.AvailableResolvers+" )") replaceCmd.Flags().Float32("solver-rate", 0.7, "Solver learning rate") replaceCmd.Flags().Float32("solver-discount", 1.0, "Solver discount rate") replaceCmd.Flags().Int("solver-attempts", 9000, "Solver maximum attempts") diff --git a/cmd/repo/list.go b/cmd/repo/list.go index c1c31f32..909f965b 100644 --- a/cmd/repo/list.go +++ b/cmd/repo/list.go @@ -22,10 +22,10 @@ import ( "strconv" "time" - . "github.com/mudler/luet/pkg/config" + "github.com/mudler/luet/cmd/util" installer "github.com/mudler/luet/pkg/installer" + "github.com/pterm/pterm" - . "github.com/logrusorgru/aurora" "github.com/spf13/cobra" ) @@ -43,7 +43,7 @@ func NewRepoListCommand() *cobra.Command { quiet, _ := cmd.Flags().GetBool("quiet") repoType, _ := cmd.Flags().GetString("type") - for _, repo := range LuetCfg.SystemRepositories { + for _, repo := range util.DefaultContext.Config.SystemRepositories { if enable && !repo.Enable { continue } @@ -58,17 +58,17 @@ func NewRepoListCommand() *cobra.Command { fmt.Println(repo.Name) } else { if repo.Enable { - repoColor = Bold(BrightGreen(repo.Name)).String() + repoColor = pterm.LightGreen(repo.Name) } else { - repoColor = Bold(BrightRed(repo.Name)).String() + repoColor = pterm.LightRed(repo.Name) } if repo.Description != "" { - repoText = Yellow(repo.Description).String() + repoText = pterm.LightYellow(repo.Description) } else { - repoText = Yellow(repo.Urls[0]).String() + repoText = pterm.LightYellow(repo.Urls[0]) } - repobasedir := LuetCfg.GetSystem().GetRepoDatabaseDirPath(repo.Name) + repobasedir := util.DefaultContext.Config.GetSystem().GetRepoDatabaseDirPath(repo.Name) if repo.Cached { r := installer.NewSystemRepository(repo) @@ -76,8 +76,8 @@ func NewRepoListCommand() *cobra.Command { installer.REPOSITORY_SPECFILE)) if localRepo != nil { tsec, _ := strconv.ParseInt(localRepo.GetLastUpdate(), 10, 64) - repoRevision = Bold(Red(localRepo.GetRevision())).String() + - " - " + Bold(Green(time.Unix(tsec, 0).String())).String() + repoRevision = pterm.LightRed(localRepo.GetRevision()) + + " - " + pterm.LightGreen(time.Unix(tsec, 0).String()) } } diff --git a/cmd/repo/update.go b/cmd/repo/update.go index 5a7c6d84..96065871 100644 --- a/cmd/repo/update.go +++ b/cmd/repo/update.go @@ -17,9 +17,8 @@ package cmd_repo import ( - . "github.com/mudler/luet/pkg/config" + "github.com/mudler/luet/cmd/util" installer "github.com/mudler/luet/pkg/installer" - . "github.com/mudler/luet/pkg/logger" "github.com/spf13/cobra" ) @@ -45,27 +44,27 @@ $> luet repo update repo1 repo2 if len(args) > 0 { for _, rname := range args { - repo, err := LuetCfg.GetSystemRepository(rname) + repo, err := util.DefaultContext.Config.GetSystemRepository(rname) if err != nil && !ignore { - Fatal(err.Error()) + util.DefaultContext.Fatal(err.Error()) } else if err != nil { continue } r := installer.NewSystemRepository(*repo) - _, err = r.Sync(force) + _, err = r.Sync(util.DefaultContext, force) if err != nil && !ignore { - Fatal("Error on sync repository " + rname + ": " + err.Error()) + util.DefaultContext.Fatal("Error on sync repository " + rname + ": " + err.Error()) } } } else { - for _, repo := range LuetCfg.SystemRepositories { + for _, repo := range util.DefaultContext.Config.SystemRepositories { if repo.Cached && repo.Enable { r := installer.NewSystemRepository(repo) - _, err := r.Sync(force) + _, err := r.Sync(util.DefaultContext, force) if err != nil && !ignore { - Fatal("Error on sync repository " + r.GetName() + ": " + err.Error()) + util.DefaultContext.Fatal("Error on sync repository " + r.GetName() + ": " + err.Error()) } } } diff --git a/cmd/root.go b/cmd/root.go index 8137bd43..49edd587 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -19,31 +19,27 @@ import ( "fmt" "os" - "github.com/marcsauter/single" "github.com/mudler/luet/cmd/util" bus "github.com/mudler/luet/pkg/bus" - config "github.com/mudler/luet/pkg/config" - . "github.com/mudler/luet/pkg/logger" "github.com/spf13/cobra" "github.com/spf13/viper" ) var cfgFile string var Verbose bool -var LockedCommands = []string{"install", "uninstall", "upgrade"} const ( LuetCLIVersion = "0.18.1" LuetEnvPrefix = "LUET" - license = ` - Luet Copyright (C) 2019-2021 Ettore Di Giacinto - This program comes with ABSOLUTELY NO WARRANTY. - This is free software, and you are welcome to redistribute it - under certain conditions. - ` ) +var license = []string{ + "Luet Copyright (C) 2019-2021 Ettore Di Giacinto", + "This program comes with ABSOLUTELY NO WARRANTY.", + "This is free software, and you are welcome to redistribute it under certain conditions.", +} + // Build time and commit information. // // ⚠️ WARNING: should only be set by "-ldflags". @@ -56,44 +52,6 @@ func version() string { return fmt.Sprintf("%s-g%s %s", LuetCLIVersion, BuildCommit, BuildTime) } -var bannerCommands = []string{"install", "build", "uninstall", "upgrade"} - -func displayVersionBanner() { - display := false - if len(os.Args) > 1 { - for _, c := range bannerCommands { - if os.Args[1] == c { - display = true - } - } - } - if display { - util.IntroScreen() - Info("Luet version", version()) - Info(license) - } -} - -func handleLock() { - if os.Getenv("LUET_NOLOCK") != "true" { - if len(os.Args) > 1 { - for _, lockedCmd := range LockedCommands { - if os.Args[1] == lockedCmd { - s := single.New("luet") - if err := s.CheckLock(); err != nil && err == single.ErrAlreadyRunning { - Fatal("another instance of the app is already running, exiting") - } else if err != nil { - // Another error occurred, might be worth handling it as well - Fatal("failed to acquire exclusive app lock:", err.Error()) - } - defer s.TryUnlock() - break - } - } - } - } -} - // RootCmd represents the base command when called without any subcommands var RootCmd = &cobra.Command{ Use: "luet", @@ -123,18 +81,18 @@ To build a package, from a tree definition: `, Version: version(), PersistentPreRun: func(cmd *cobra.Command, args []string) { - - _, err := util.LoadConfig() + err := util.InitContext(util.DefaultContext) if err != nil { - Fatal("failed to load configuration:", err.Error()) + util.DefaultContext.Error("failed to load configuration:", err.Error()) } + util.DisplayVersionBanner(util.DefaultContext, util.IntroScreen, version, license) // Initialize tmpdir prefix. TODO: Move this with LoadConfig // directly on sub command to ensure the creation only when it's // needed. - err = config.LuetCfg.GetSystem().InitTmpDir() + err = util.DefaultContext.Config.GetSystem().InitTmpDir() if err != nil { - Fatal("failed on init tmp basedir:", err.Error()) + util.DefaultContext.Fatal("failed on init tmp basedir:", err.Error()) } viper.BindPFlag("plugin", cmd.Flags().Lookup("plugin")) @@ -143,17 +101,17 @@ To build a package, from a tree definition: bus.Manager.Initialize(plugin...) if len(bus.Manager.Plugins) != 0 { - Info(":lollipop:Enabled plugins:") + util.DefaultContext.Info(":lollipop:Enabled plugins:") for _, p := range bus.Manager.Plugins { - Info("\t:arrow_right:", p.Name) + util.DefaultContext.Info("\t:arrow_right:", p.Name) } } }, PersistentPostRun: func(cmd *cobra.Command, args []string) { // Cleanup all tmp directories used by luet - err := config.LuetCfg.GetSystem().CleanupTmpDir() + err := util.DefaultContext.Config.GetSystem().CleanupTmpDir() if err != nil { - Warning("failed on cleanup tmpdir:", err.Error()) + util.DefaultContext.Warning("failed on cleanup tmpdir:", err.Error()) } }, SilenceErrors: true, @@ -162,9 +120,7 @@ To build a package, from a tree definition: // Execute adds all child commands to the root command sets flags appropriately. // This is called by main.main(). It only needs to happen once to the rootCmd. func Execute() { - - handleLock() - displayVersionBanner() + util.HandleLock(util.DefaultContext) if err := RootCmd.Execute(); err != nil { fmt.Println(err) @@ -173,5 +129,5 @@ func Execute() { } func init() { - util.InitViper(RootCmd) + util.InitViper(util.DefaultContext, RootCmd) } diff --git a/cmd/search.go b/cmd/search.go index 74e9bbdb..8781e24b 100644 --- a/cmd/search.go +++ b/cmd/search.go @@ -19,13 +19,11 @@ import ( "strings" "github.com/ghodss/yaml" - "github.com/jedib0t/go-pretty/table" - "github.com/jedib0t/go-pretty/v6/list" "github.com/mudler/luet/cmd/util" - . "github.com/mudler/luet/pkg/config" + "github.com/mudler/luet/pkg/api/core/types" installer "github.com/mudler/luet/pkg/installer" - . "github.com/mudler/luet/pkg/logger" pkg "github.com/mudler/luet/pkg/package" + "github.com/pterm/pterm" "github.com/spf13/cobra" "github.com/spf13/viper" ) @@ -48,28 +46,47 @@ func (r PackageResult) String() string { return fmt.Sprintf("%s/%s-%s required for %s", r.Category, r.Name, r.Version, r.Target) } -var rows table.Row = table.Row{"Package", "Category", "Name", "Version", "Repository", "Description", "License", "URI"} +var rows []string = []string{"Package", "Category", "Name", "Version", "Repository", "License"} -func packageToRow(repo string, p pkg.Package) table.Row { - return table.Row{p.HumanReadableString(), p.GetCategory(), p.GetName(), p.GetVersion(), repo, p.GetDescription(), p.GetLicense(), strings.Join(p.GetURI(), "\n")} +func packageToRow(repo string, p pkg.Package) []string { + return []string{p.HumanReadableString(), p.GetCategory(), p.GetName(), p.GetVersion(), repo, p.GetLicense()} } -func packageToList(l list.Writer, repo string, p pkg.Package) { - l.AppendItem(p.HumanReadableString()) - l.Indent() - l.AppendItem(fmt.Sprintf("Category: %s", p.GetCategory())) - l.AppendItem(fmt.Sprintf("Name: %s", p.GetName())) - l.AppendItem(fmt.Sprintf("Version: %s", p.GetVersion())) - l.AppendItem(fmt.Sprintf("Description: %s", p.GetDescription())) - l.AppendItem(fmt.Sprintf("Repository: %s ", repo)) - l.AppendItem(fmt.Sprintf("Uri: %s ", strings.Join(p.GetURI(), "\n"))) - l.UnIndent() +func packageToList(l *util.ListWriter, repo string, p pkg.Package) { + l.AppendItem(pterm.BulletListItem{ + Level: 0, Text: p.HumanReadableString(), + TextStyle: pterm.NewStyle(pterm.FgCyan), Bullet: ">", BulletStyle: pterm.NewStyle(pterm.FgYellow), + }) + l.AppendItem(pterm.BulletListItem{ + Level: 1, Text: fmt.Sprintf("Category: %s", p.GetCategory()), + Bullet: "->", BulletStyle: pterm.NewStyle(pterm.FgDarkGray), + }) + l.AppendItem(pterm.BulletListItem{ + Level: 1, Text: fmt.Sprintf("Name: %s", p.GetName()), + Bullet: "->", BulletStyle: pterm.NewStyle(pterm.FgDarkGray), + }) + l.AppendItem(pterm.BulletListItem{ + Level: 1, Text: fmt.Sprintf("Version: %s", p.GetVersion()), + Bullet: "->", BulletStyle: pterm.NewStyle(pterm.FgDarkGray), + }) + l.AppendItem(pterm.BulletListItem{ + Level: 1, Text: fmt.Sprintf("Description: %s", p.GetDescription()), + Bullet: "->", BulletStyle: pterm.NewStyle(pterm.FgDarkGray), + }) + l.AppendItem(pterm.BulletListItem{ + Level: 1, Text: fmt.Sprintf("Repository: %s ", repo), + Bullet: "->", BulletStyle: pterm.NewStyle(pterm.FgDarkGray), + }) + l.AppendItem(pterm.BulletListItem{ + Level: 1, Text: fmt.Sprintf("Uri: %s ", strings.Join(p.GetURI(), " ")), + Bullet: "->", BulletStyle: pterm.NewStyle(pterm.FgDarkGray), + }) } -func searchLocally(term string, l list.Writer, t table.Writer, label, labelMatch, revdeps, hidden bool) Results { +func searchLocally(term string, l *util.ListWriter, t *util.TableWriter, label, labelMatch, revdeps, hidden bool) Results { var results Results - system := &installer.System{Database: LuetCfg.GetSystemDB(), Target: LuetCfg.GetSystem().Rootfs} + system := &installer.System{Database: util.DefaultContext.Config.GetSystemDB(), Target: util.DefaultContext.Config.GetSystem().Rootfs} var err error iMatches := pkg.Packages{} @@ -82,7 +99,7 @@ func searchLocally(term string, l list.Writer, t table.Writer, label, labelMatch } if err != nil { - Fatal("Error: " + err.Error()) + util.DefaultContext.Fatal("Error: " + err.Error()) } for _, pack := range iMatches { @@ -126,22 +143,23 @@ func searchLocally(term string, l list.Writer, t table.Writer, label, labelMatch return results } -func searchOnline(term string, l list.Writer, t table.Writer, label, labelMatch, revdeps, hidden bool) Results { +func searchOnline(term string, l *util.ListWriter, t *util.TableWriter, label, labelMatch, revdeps, hidden bool) Results { var results Results inst := installer.NewLuetInstaller( installer.LuetInstallerOptions{ - Concurrency: LuetCfg.GetGeneral().Concurrency, - SolverOptions: *LuetCfg.GetSolverOptions(), - PackageRepositories: LuetCfg.SystemRepositories, + Concurrency: util.DefaultContext.Config.GetGeneral().Concurrency, + SolverOptions: *util.DefaultContext.Config.GetSolverOptions(), + PackageRepositories: util.DefaultContext.Config.SystemRepositories, + Context: util.DefaultContext, }, ) synced, err := inst.SyncRepositories() if err != nil { - Fatal("Error: " + err.Error()) + util.DefaultContext.Fatal("Error: " + err.Error()) } - Info("--- Search results (" + term + "): ---") + util.DefaultContext.Info("--- Search results (" + term + "): ---") matches := []installer.PackageMatch{} if label { @@ -192,15 +210,15 @@ func searchOnline(term string, l list.Writer, t table.Writer, label, labelMatch, } return results } -func searchLocalFiles(term string, l list.Writer, t table.Writer) Results { +func searchLocalFiles(term string, l *util.ListWriter, t *util.TableWriter) Results { var results Results - Info("--- Search results (" + term + "): ---") + util.DefaultContext.Info("--- Search results (" + term + "): ---") - matches, _ := LuetCfg.GetSystemDB().FindPackageByFile(term) + matches, _ := util.DefaultContext.Config.GetSystemDB().FindPackageByFile(term) for _, pack := range matches { t.AppendRow(packageToRow("system", pack)) packageToList(l, "system", pack) - f, _ := LuetCfg.GetSystemDB().GetPackageFiles(pack) + f, _ := util.DefaultContext.Config.GetSystemDB().GetPackageFiles(pack) results.Packages = append(results.Packages, PackageResult{ Name: pack.GetName(), @@ -215,22 +233,23 @@ func searchLocalFiles(term string, l list.Writer, t table.Writer) Results { return results } -func searchFiles(term string, l list.Writer, t table.Writer) Results { +func searchFiles(term string, l *util.ListWriter, t *util.TableWriter) Results { var results Results inst := installer.NewLuetInstaller( installer.LuetInstallerOptions{ - Concurrency: LuetCfg.GetGeneral().Concurrency, - SolverOptions: *LuetCfg.GetSolverOptions(), - PackageRepositories: LuetCfg.SystemRepositories, + Concurrency: util.DefaultContext.Config.GetGeneral().Concurrency, + SolverOptions: *util.DefaultContext.Config.GetSolverOptions(), + PackageRepositories: util.DefaultContext.Config.SystemRepositories, + Context: util.DefaultContext, }, ) synced, err := inst.SyncRepositories() if err != nil { - Fatal("Error: " + err.Error()) + util.DefaultContext.Fatal("Error: " + err.Error()) } - Info("--- Search results (" + term + "): ---") + util.DefaultContext.Info("--- Search results (" + term + "): ---") matches := []installer.PackageMatch{} @@ -297,7 +316,7 @@ Search can also return results in the terminal in different ways: as terminal ou Run: func(cmd *cobra.Command, args []string) { var results Results if len(args) > 1 { - Fatal("Wrong number of arguments (expected 1)") + util.DefaultContext.Fatal("Wrong number of arguments (expected 1)") } else if len(args) == 0 { args = []string{"."} } @@ -310,18 +329,18 @@ Search can also return results in the terminal in different ways: as terminal ou tableMode, _ := cmd.Flags().GetBool("table") files, _ := cmd.Flags().GetBool("files") - util.SetSystemConfig() - util.SetSolverConfig() + util.SetSystemConfig(util.DefaultContext) + util.SetSolverConfig(util.DefaultContext) out, _ := cmd.Flags().GetString("output") if out != "terminal" { - LuetCfg.GetLogging().SetLogLevel("error") + util.DefaultContext.Config.GetLogging().SetLogLevel("error") } - l := list.NewWriter() - t := table.NewWriter() - t.AppendHeader(rows) - Debug("Solver", LuetCfg.GetSolverOptions().CompactString()) + l := &util.ListWriter{} + t := &util.TableWriter{} + t.AppendRow(rows) + util.DefaultContext.Debug("Solver", util.DefaultContext.Config.GetSolverOptions().CompactString()) switch { case files && installed: @@ -334,14 +353,10 @@ Search can also return results in the terminal in different ways: as terminal ou results = searchLocally(args[0], l, t, searchWithLabel, searchWithLabelMatch, revdeps, hidden) } - t.AppendFooter(rows) - t.SetStyle(table.StyleColoredBright) - - l.SetStyle(list.StyleConnectedRounded) if tableMode { - Info(t.Render()) + t.Render() } else { - Info(l.Render()) + l.Render() } y, err := yaml.Marshal(results) @@ -370,7 +385,7 @@ func init() { searchCmd.Flags().String("system-engine", "", "System DB engine") searchCmd.Flags().Bool("installed", false, "Search between system packages") - searchCmd.Flags().String("solver-type", "", "Solver strategy ( Defaults none, available: "+AvailableResolvers+" )") + searchCmd.Flags().String("solver-type", "", "Solver strategy ( Defaults none, available: "+types.AvailableResolvers+" )") searchCmd.Flags().StringP("output", "o", "terminal", "Output format ( Defaults: terminal, available: json,yaml )") searchCmd.Flags().Float32("solver-rate", 0.7, "Solver learning rate") searchCmd.Flags().Float32("solver-discount", 1.0, "Solver discount rate") diff --git a/cmd/serve-repo.go b/cmd/serve-repo.go index fda8767c..0555cd48 100644 --- a/cmd/serve-repo.go +++ b/cmd/serve-repo.go @@ -18,7 +18,7 @@ import ( "net/http" "os" - . "github.com/mudler/luet/pkg/logger" + "github.com/mudler/luet/cmd/util" "github.com/spf13/cobra" "github.com/spf13/viper" @@ -41,15 +41,15 @@ var serverepoCmd = &cobra.Command{ http.Handle("/", http.FileServer(http.Dir(dir))) - Info("Serving ", dir, " on HTTP port: ", port) - Fatal(http.ListenAndServe(address+":"+port, nil)) + util.DefaultContext.Info("Serving ", dir, " on HTTP port: ", port) + util.DefaultContext.Fatal(http.ListenAndServe(address+":"+port, nil)) }, } func init() { path, err := os.Getwd() if err != nil { - Fatal(err) + util.DefaultContext.Fatal(err) } serverepoCmd.Flags().String("dir", path, "Packages folder (output from build)") serverepoCmd.Flags().String("port", "9090", "Listening port") diff --git a/cmd/tree/bump.go b/cmd/tree/bump.go index 34e565f0..2f159b52 100644 --- a/cmd/tree/bump.go +++ b/cmd/tree/bump.go @@ -19,7 +19,7 @@ package cmd_tree import ( "fmt" - . "github.com/mudler/luet/pkg/logger" + "github.com/mudler/luet/cmd/util" spectooling "github.com/mudler/luet/pkg/spectooling" tree "github.com/mudler/luet/pkg/tree" version "github.com/mudler/luet/pkg/versioner" @@ -36,7 +36,7 @@ func NewTreeBumpCommand() *cobra.Command { PreRun: func(cmd *cobra.Command, args []string) { df, _ := cmd.Flags().GetString("definition-file") if df == "" { - Fatal("Mandatory definition.yaml path missing.") + util.DefaultContext.Fatal("Mandatory definition.yaml path missing.") } }, Run: func(cmd *cobra.Command, args []string) { @@ -45,34 +45,34 @@ func NewTreeBumpCommand() *cobra.Command { pkgVersion, _ := cmd.Flags().GetString("pkg-version") pack, err := tree.ReadDefinitionFile(spec) if err != nil { - Fatal(err.Error()) + util.DefaultContext.Fatal(err.Error()) } if pkgVersion != "" { validator := &version.WrappedVersioner{} err := validator.Validate(pkgVersion) if err != nil { - Fatal("Invalid version string: " + err.Error()) + util.DefaultContext.Fatal("Invalid version string: " + err.Error()) } pack.SetVersion(pkgVersion) } else { // Retrieve version build section with Gentoo parser err = pack.BumpBuildVersion() if err != nil { - Fatal("Error on increment build version: " + err.Error()) + util.DefaultContext.Fatal("Error on increment build version: " + err.Error()) } } if toStdout { data, err := spectooling.NewDefaultPackageSanitized(&pack).Yaml() if err != nil { - Fatal("Error on yaml conversion: " + err.Error()) + util.DefaultContext.Fatal("Error on yaml conversion: " + err.Error()) } fmt.Println(string(data)) } else { err = tree.WriteDefinitionFile(&pack, spec) if err != nil { - Fatal("Error on write definition file: " + err.Error()) + util.DefaultContext.Fatal("Error on write definition file: " + err.Error()) } fmt.Printf("Bumped package %s/%s-%s.\n", pack.Category, pack.Name, pack.Version) diff --git a/cmd/tree/images.go b/cmd/tree/images.go index f470432f..3dcfac53 100644 --- a/cmd/tree/images.go +++ b/cmd/tree/images.go @@ -20,15 +20,13 @@ import ( "fmt" "os" - //. "github.com/mudler/luet/pkg/config" "github.com/ghodss/yaml" helpers "github.com/mudler/luet/cmd/helpers" "github.com/mudler/luet/cmd/util" "github.com/mudler/luet/pkg/compiler" "github.com/mudler/luet/pkg/compiler/backend" "github.com/mudler/luet/pkg/compiler/types/options" - . "github.com/mudler/luet/pkg/config" - . "github.com/mudler/luet/pkg/logger" + pkg "github.com/mudler/luet/pkg/package" "github.com/mudler/luet/pkg/solver" tree "github.com/mudler/luet/pkg/tree" @@ -45,11 +43,11 @@ func NewTreeImageCommand() *cobra.Command { PreRun: func(cmd *cobra.Command, args []string) { t, _ := cmd.Flags().GetStringArray("tree") if len(t) == 0 { - Fatal("Mandatory tree param missing.") + util.DefaultContext.Fatal("Mandatory tree param missing.") } if len(args) != 1 { - Fatal("Expects one package as parameter") + util.DefaultContext.Fatal("Expects one package as parameter") } util.BindValuesFlags(cmd) viper.BindPFlag("image-repository", cmd.Flags().Lookup("image-repository")) @@ -65,7 +63,7 @@ func NewTreeImageCommand() *cobra.Command { out, _ := cmd.Flags().GetString("output") if out != "terminal" { - LuetCfg.GetLogging().SetLogLevel("error") + util.DefaultContext.Config.GetLogging().SetLogLevel("error") } reciper := tree.NewCompilerRecipe(pkg.NewInMemoryDatabase(false)) @@ -73,20 +71,21 @@ func NewTreeImageCommand() *cobra.Command { for _, t := range treePath { err := reciper.Load(t) if err != nil { - Fatal("Error on load tree ", err) + util.DefaultContext.Fatal("Error on load tree ", err) } } - compilerBackend := backend.NewSimpleDockerBackend() + compilerBackend := backend.NewSimpleDockerBackend(util.DefaultContext) - opts := *LuetCfg.GetSolverOptions() + opts := *util.DefaultContext.Config.GetSolverOptions() opts.Options = solver.Options{Type: solver.SingleCoreSimple, Concurrency: 1} luetCompiler := compiler.NewLuetCompiler( compilerBackend, reciper.GetDatabase(), options.WithBuildValues(values), + options.WithContext(util.DefaultContext), options.WithPushRepository(imageRepository), options.WithPullRepositories(pullRepo), - options.WithTemplateFolder(util.TemplateFolders(false, treePath)), + options.WithTemplateFolder(util.TemplateFolders(util.DefaultContext, false, treePath)), options.WithSolverOptions(opts), ) @@ -94,18 +93,18 @@ func NewTreeImageCommand() *cobra.Command { pack, err := helpers.ParsePackageStr(a) if err != nil { - Fatal("Invalid package string ", a, ": ", err.Error()) + util.DefaultContext.Fatal("Invalid package string ", a, ": ", err.Error()) } spec, err := luetCompiler.FromPackage(pack) if err != nil { - Fatal("Error: " + err.Error()) + util.DefaultContext.Fatal("Error: " + err.Error()) } ht := compiler.NewHashTree(reciper.GetDatabase()) hashtree, err := ht.Query(luetCompiler, spec) if err != nil { - Fatal("Error: " + err.Error()) + util.DefaultContext.Fatal("Error: " + err.Error()) } for _, assertion := range hashtree.Solution { //highly dependent on the order @@ -145,7 +144,7 @@ func NewTreeImageCommand() *cobra.Command { } path, err := os.Getwd() if err != nil { - Fatal(err) + util.DefaultContext.Fatal(err) } ans.Flags().StringP("output", "o", "terminal", "Output format ( Defaults: terminal, available: json,yaml )") ans.Flags().StringArrayP("tree", "t", []string{path}, "Path of the tree to use.") diff --git a/cmd/tree/pkglist.go b/cmd/tree/pkglist.go index a2d90960..f27242a0 100644 --- a/cmd/tree/pkglist.go +++ b/cmd/tree/pkglist.go @@ -21,11 +21,9 @@ import ( "os" "sort" - //. "github.com/mudler/luet/pkg/config" "github.com/ghodss/yaml" helpers "github.com/mudler/luet/cmd/helpers" - . "github.com/mudler/luet/pkg/config" - . "github.com/mudler/luet/pkg/logger" + "github.com/mudler/luet/cmd/util" pkg "github.com/mudler/luet/pkg/package" "github.com/mudler/luet/pkg/solver" tree "github.com/mudler/luet/pkg/tree" @@ -75,13 +73,13 @@ func NewTreePkglistCommand() *cobra.Command { PreRun: func(cmd *cobra.Command, args []string) { t, _ := cmd.Flags().GetStringArray("tree") if len(t) == 0 { - Fatal("Mandatory tree param missing.") + util.DefaultContext.Fatal("Mandatory tree param missing.") } revdeps, _ := cmd.Flags().GetBool("revdeps") deps, _ := cmd.Flags().GetBool("deps") if revdeps && deps { - Fatal("Both revdeps and deps option used. Choice only one.") + util.DefaultContext.Fatal("Both revdeps and deps option used. Choice only one.") } }, @@ -98,7 +96,7 @@ func NewTreePkglistCommand() *cobra.Command { out, _ := cmd.Flags().GetString("output") if out != "terminal" { - LuetCfg.GetLogging().SetLogLevel("error") + util.DefaultContext.Config.GetLogging().SetLogLevel("error") } var reciper tree.Builder @@ -111,7 +109,7 @@ func NewTreePkglistCommand() *cobra.Command { for _, t := range treePath { err := reciper.Load(t) if err != nil { - Fatal("Error on load tree ", err) + util.DefaultContext.Fatal("Error on load tree ", err) } } @@ -126,11 +124,11 @@ func NewTreePkglistCommand() *cobra.Command { regExcludes, err := helpers.CreateRegexArray(excludes) if err != nil { - Fatal(err.Error()) + util.DefaultContext.Fatal(err.Error()) } regMatches, err := helpers.CreateRegexArray(matches) if err != nil { - Fatal(err.Error()) + util.DefaultContext.Fatal(err.Error()) } plist := make([]string, 0) @@ -194,12 +192,12 @@ func NewTreePkglistCommand() *cobra.Command { solution, err := depSolver.Install(pkg.Packages{p}) if err != nil { - Fatal(err.Error()) + util.DefaultContext.Fatal(err.Error()) } ass := solution.SearchByName(p.GetPackageName()) solution, err = solution.Order(reciper.GetDatabase(), ass.Package.GetFingerPrint()) if err != nil { - Fatal(err.Error()) + util.DefaultContext.Fatal(err.Error()) } for _, pa := range solution { @@ -270,7 +268,7 @@ func NewTreePkglistCommand() *cobra.Command { } path, err := os.Getwd() if err != nil { - Fatal(err) + util.DefaultContext.Fatal(err) } ans.Flags().BoolP("buildtime", "b", false, "Build time match") ans.Flags().StringP("output", "o", "terminal", "Output format ( Defaults: terminal, available: json,yaml )") diff --git a/cmd/tree/validate.go b/cmd/tree/validate.go index 53de24c1..972e0dbd 100644 --- a/cmd/tree/validate.go +++ b/cmd/tree/validate.go @@ -26,8 +26,8 @@ import ( "sync" helpers "github.com/mudler/luet/cmd/helpers" - . "github.com/mudler/luet/pkg/config" - . "github.com/mudler/luet/pkg/logger" + "github.com/mudler/luet/cmd/util" + pkg "github.com/mudler/luet/pkg/package" "github.com/mudler/luet/pkg/solver" tree "github.com/mudler/luet/pkg/tree" @@ -104,7 +104,7 @@ func validatePackage(p pkg.Package, checkType string, opts *ValidateOpts, recipe } else { errstr = "No packages" } - Error(fmt.Sprintf("[%9s] %s/%s-%s: Broken. No versions could be found by database %s", + util.DefaultContext.Error(fmt.Sprintf("[%9s] %s/%s-%s: Broken. No versions could be found by database %s", checkType, p.GetCategory(), p.GetName(), p.GetVersion(), errstr, @@ -134,7 +134,7 @@ func validatePackage(p pkg.Package, checkType string, opts *ValidateOpts, recipe p.GetCategory(), p.GetName(), p.GetVersion(), err.Error(), ) - Error(errstr) + util.DefaultContext.Error(errstr) return errors.New(errstr) } @@ -173,7 +173,7 @@ func validatePackage(p pkg.Package, checkType string, opts *ValidateOpts, recipe } } - Info(fmt.Sprintf("[%9s] Checking package ", checkType)+ + util.DefaultContext.Info(fmt.Sprintf("[%9s] Checking package ", checkType)+ fmt.Sprintf("%s/%s-%s", p.GetCategory(), p.GetName(), p.GetVersion()), "with", len(p.GetRequires()), "dependencies and", len(p.GetConflicts()), "conflicts.") @@ -201,7 +201,7 @@ func validatePackage(p pkg.Package, checkType string, opts *ValidateOpts, recipe } else { errstr = "No packages" } - Error(fmt.Sprintf("[%9s] %s/%s-%s: Broken Dep %s/%s-%s - %s", + util.DefaultContext.Error(fmt.Sprintf("[%9s] %s/%s-%s: Broken Dep %s/%s-%s - %s", checkType, p.GetCategory(), p.GetName(), p.GetVersion(), r.GetCategory(), r.GetName(), r.GetVersion(), @@ -221,12 +221,12 @@ func validatePackage(p pkg.Package, checkType string, opts *ValidateOpts, recipe } else { - Debug(fmt.Sprintf("[%9s] Find packages for dep", checkType), + util.DefaultContext.Debug(fmt.Sprintf("[%9s] Find packages for dep", checkType), fmt.Sprintf("%s/%s-%s", r.GetCategory(), r.GetName(), r.GetVersion())) if opts.WithSolver { - Info(fmt.Sprintf("[%9s] :soap: [%2d/%2d] %s/%s-%s: %s/%s-%s", + util.DefaultContext.Info(fmt.Sprintf("[%9s] :soap: [%2d/%2d] %s/%s-%s: %s/%s-%s", checkType, idx+1, len(all), p.GetCategory(), p.GetName(), p.GetVersion(), @@ -236,15 +236,15 @@ func validatePackage(p pkg.Package, checkType string, opts *ValidateOpts, recipe // Check if the solver is already been done for the deep _, err := cacheDeps.Get(r.HashFingerprint("")) if err == nil { - Debug(fmt.Sprintf("[%9s] :direct_hit: Cache Hit for dep", checkType), + util.DefaultContext.Debug(fmt.Sprintf("[%9s] :direct_hit: Cache Hit for dep", checkType), fmt.Sprintf("%s/%s-%s", r.GetCategory(), r.GetName(), r.GetVersion())) continue } - Spinner(22) + util.DefaultContext.Spinner() solution, err := depSolver.Install(pkg.Packages{r}) ass := solution.SearchByName(r.GetPackageName()) - SpinnerStop() + util.DefaultContext.SpinnerStop() if err == nil { if ass == nil { @@ -255,7 +255,7 @@ func validatePackage(p pkg.Package, checkType string, opts *ValidateOpts, recipe r.GetCategory(), r.GetName(), r.GetVersion(), )) - if LuetCfg.GetGeneral().Debug { + if util.DefaultContext.Config.GetGeneral().Debug { for idx, pa := range solution { fmt.Println(fmt.Sprintf("[%9s] %s/%s-%s: solution %d: %s", checkType, @@ -264,7 +264,7 @@ func validatePackage(p pkg.Package, checkType string, opts *ValidateOpts, recipe } } - Error(ans.Error()) + util.DefaultContext.Error(ans.Error()) opts.IncrBrokenDeps() validpkg = false } else { @@ -274,7 +274,7 @@ func validatePackage(p pkg.Package, checkType string, opts *ValidateOpts, recipe if err != nil { - Error(fmt.Sprintf("[%9s] %s/%s-%s: solver broken for dep %s/%s-%s - %s", + util.DefaultContext.Error(fmt.Sprintf("[%9s] %s/%s-%s: solver broken for dep %s/%s-%s - %s", checkType, p.GetCategory(), p.GetName(), p.GetVersion(), r.GetCategory(), r.GetName(), r.GetVersion(), @@ -376,28 +376,28 @@ func initOpts(opts *ValidateOpts, onlyRuntime, onlyBuildtime, withSolver bool, t opts.BuildtimeCacheDeps = pkg.NewInMemoryDatabase(false).(*pkg.InMemoryDatabase) for _, treePath := range treePaths { - Info(fmt.Sprintf("Loading :deciduous_tree: %s...", treePath)) + util.DefaultContext.Info(fmt.Sprintf("Loading :deciduous_tree: %s...", treePath)) if opts.BuildtimeReciper != nil { err = opts.BuildtimeReciper.Load(treePath) if err != nil { - Fatal("Error on load tree ", err) + util.DefaultContext.Fatal("Error on load tree ", err) } } if opts.RuntimeReciper != nil { err = opts.RuntimeReciper.Load(treePath) if err != nil { - Fatal("Error on load tree ", err) + util.DefaultContext.Fatal("Error on load tree ", err) } } } opts.RegExcludes, err = helpers.CreateRegexArray(opts.Excludes) if err != nil { - Fatal(err.Error()) + util.DefaultContext.Fatal(err.Error()) } opts.RegMatches, err = helpers.CreateRegexArray(opts.Matches) if err != nil { - Fatal(err.Error()) + util.DefaultContext.Fatal(err.Error()) } } @@ -417,16 +417,16 @@ func NewTreeValidateCommand() *cobra.Command { onlyBuildtime, _ := cmd.Flags().GetBool("only-buildtime") if len(treePaths) < 1 { - Fatal("Mandatory tree param missing.") + util.DefaultContext.Fatal("Mandatory tree param missing.") } if onlyRuntime && onlyBuildtime { - Fatal("Both --only-runtime and --only-buildtime options are not possibile.") + util.DefaultContext.Fatal("Both --only-runtime and --only-buildtime options are not possibile.") } }, Run: func(cmd *cobra.Command, args []string) { var reciper tree.Builder - concurrency := LuetCfg.GetGeneral().Concurrency + concurrency := util.DefaultContext.Config.GetGeneral().Concurrency withSolver, _ := cmd.Flags().GetBool("with-solver") onlyRuntime, _ := cmd.Flags().GetBool("only-runtime") @@ -472,18 +472,18 @@ func NewTreeValidateCommand() *cobra.Command { // fmt.Println("Broken packages:", brokenPkgs, "(", brokenDeps, "deps ).") if len(stringerrs) != 0 { - Error(fmt.Sprintf("Found %d broken packages and %d broken deps.", + util.DefaultContext.Error(fmt.Sprintf("Found %d broken packages and %d broken deps.", opts.BrokenPkgs, opts.BrokenDeps)) - Fatal("Errors: " + strconv.Itoa(len(stringerrs))) + util.DefaultContext.Fatal("Errors: " + strconv.Itoa(len(stringerrs))) } else { - Info("All good! :white_check_mark:") + util.DefaultContext.Info("All good! :white_check_mark:") os.Exit(0) } }, } path, err := os.Getwd() if err != nil { - Fatal(err) + util.DefaultContext.Fatal(err) } ans.Flags().Bool("only-runtime", false, "Check only runtime dependencies.") ans.Flags().Bool("only-buildtime", false, "Check only buildtime dependencies.") diff --git a/cmd/uninstall.go b/cmd/uninstall.go index 72d5492e..79c93bd6 100644 --- a/cmd/uninstall.go +++ b/cmd/uninstall.go @@ -17,9 +17,8 @@ package cmd import ( helpers "github.com/mudler/luet/cmd/helpers" "github.com/mudler/luet/cmd/util" - . "github.com/mudler/luet/pkg/config" + "github.com/mudler/luet/pkg/api/core/types" installer "github.com/mudler/luet/pkg/installer" - . "github.com/mudler/luet/pkg/logger" pkg "github.com/mudler/luet/pkg/package" "github.com/mudler/luet/pkg/solver" @@ -45,7 +44,7 @@ var uninstallCmd = &cobra.Command{ pack, err := helpers.ParsePackageStr(a) if err != nil { - Fatal("Invalid package string ", a, ": ", err.Error()) + util.DefaultContext.Fatal("Invalid package string ", a, ": ", err.Error()) } toRemove = append(toRemove, pack) } @@ -58,21 +57,21 @@ var uninstallCmd = &cobra.Command{ yes := viper.GetBool("yes") keepProtected, _ := cmd.Flags().GetBool("keep-protected-files") - util.SetSystemConfig() - util.SetSolverConfig() + util.SetSystemConfig(util.DefaultContext) + util.SetSolverConfig(util.DefaultContext) - LuetCfg.ConfigProtectSkip = !keepProtected + util.DefaultContext.Config.ConfigProtectSkip = !keepProtected - LuetCfg.GetSolverOptions().Implementation = solver.SingleCoreSimple + util.DefaultContext.Config.GetSolverOptions().Implementation = solver.SingleCoreSimple - Debug("Solver", LuetCfg.GetSolverOptions().CompactString()) + util.DefaultContext.Debug("Solver", util.DefaultContext.Config.GetSolverOptions().CompactString()) // Load config protect configs - installer.LoadConfigProtectConfs(LuetCfg) + util.DefaultContext.Config.LoadConfigProtect(util.DefaultContext) inst := installer.NewLuetInstaller(installer.LuetInstallerOptions{ - Concurrency: LuetCfg.GetGeneral().Concurrency, - SolverOptions: *LuetCfg.GetSolverOptions(), + Concurrency: util.DefaultContext.Config.GetGeneral().Concurrency, + SolverOptions: *util.DefaultContext.Config.GetSolverOptions(), NoDeps: nodeps, Force: force, FullUninstall: full, @@ -80,12 +79,13 @@ var uninstallCmd = &cobra.Command{ CheckConflicts: checkconflicts, Ask: !yes, PreserveSystemEssentialData: true, + Context: util.DefaultContext, }) - system := &installer.System{Database: LuetCfg.GetSystemDB(), Target: LuetCfg.GetSystem().Rootfs} + system := &installer.System{Database: util.DefaultContext.Config.GetSystemDB(), Target: util.DefaultContext.Config.GetSystem().Rootfs} if err := inst.Uninstall(system, toRemove...); err != nil { - Fatal("Error: " + err.Error()) + util.DefaultContext.Fatal("Error: " + err.Error()) } }, } @@ -96,7 +96,7 @@ func init() { uninstallCmd.Flags().String("system-target", "", "System rootpath") uninstallCmd.Flags().String("system-engine", "", "System DB engine") - uninstallCmd.Flags().String("solver-type", "", "Solver strategy ( Defaults none, available: "+AvailableResolvers+" )") + uninstallCmd.Flags().String("solver-type", "", "Solver strategy ( Defaults none, available: "+types.AvailableResolvers+" )") uninstallCmd.Flags().Float32("solver-rate", 0.7, "Solver learning rate") uninstallCmd.Flags().Float32("solver-discount", 1.0, "Solver discount rate") uninstallCmd.Flags().Int("solver-attempts", 9000, "Solver maximum attempts") diff --git a/cmd/upgrade.go b/cmd/upgrade.go index a291cb9e..32ff924c 100644 --- a/cmd/upgrade.go +++ b/cmd/upgrade.go @@ -16,9 +16,8 @@ package cmd import ( "github.com/mudler/luet/cmd/util" - . "github.com/mudler/luet/pkg/config" + "github.com/mudler/luet/pkg/api/core/types" installer "github.com/mudler/luet/pkg/installer" - . "github.com/mudler/luet/pkg/logger" "github.com/mudler/luet/pkg/solver" "github.com/spf13/cobra" @@ -47,19 +46,19 @@ var upgradeCmd = &cobra.Command{ yes := viper.GetBool("yes") downloadOnly, _ := cmd.Flags().GetBool("download-only") - util.SetSystemConfig() - opts := util.SetSolverConfig() + util.SetSystemConfig(util.DefaultContext) + opts := util.SetSolverConfig(util.DefaultContext) - LuetCfg.GetSolverOptions().Implementation = solver.SingleCoreSimple + util.DefaultContext.Config.GetSolverOptions().Implementation = solver.SingleCoreSimple - Debug("Solver", opts.CompactString()) + util.DefaultContext.Debug("Solver", opts.CompactString()) // Load config protect configs - installer.LoadConfigProtectConfs(LuetCfg) + util.DefaultContext.Config.LoadConfigProtect(util.DefaultContext) inst := installer.NewLuetInstaller(installer.LuetInstallerOptions{ - Concurrency: LuetCfg.GetGeneral().Concurrency, - SolverOptions: *LuetCfg.GetSolverOptions(), + Concurrency: util.DefaultContext.Config.GetGeneral().Concurrency, + SolverOptions: *util.DefaultContext.Config.GetSolverOptions(), Force: force, FullUninstall: full, NoDeps: nodeps, @@ -69,12 +68,13 @@ var upgradeCmd = &cobra.Command{ PreserveSystemEssentialData: true, Ask: !yes, DownloadOnly: downloadOnly, - PackageRepositories: LuetCfg.SystemRepositories, + PackageRepositories: util.DefaultContext.Config.SystemRepositories, + Context: util.DefaultContext, }) - system := &installer.System{Database: LuetCfg.GetSystemDB(), Target: LuetCfg.GetSystem().Rootfs} + system := &installer.System{Database: util.DefaultContext.Config.GetSystemDB(), Target: util.DefaultContext.Config.GetSystem().Rootfs} if err := inst.Upgrade(system); err != nil { - Fatal("Error: " + err.Error()) + util.DefaultContext.Fatal("Error: " + err.Error()) } }, } @@ -84,7 +84,7 @@ func init() { upgradeCmd.Flags().String("system-target", "", "System rootpath") upgradeCmd.Flags().String("system-engine", "", "System DB engine") - upgradeCmd.Flags().String("solver-type", "", "Solver strategy ( Defaults none, available: "+AvailableResolvers+" )") + upgradeCmd.Flags().String("solver-type", "", "Solver strategy ( Defaults none, available: "+types.AvailableResolvers+" )") upgradeCmd.Flags().Float32("solver-rate", 0.7, "Solver learning rate") upgradeCmd.Flags().Float32("solver-discount", 1.0, "Solver discount rate") upgradeCmd.Flags().Int("solver-attempts", 9000, "Solver maximum attempts") diff --git a/cmd/util.go b/cmd/util.go index f3790672..156c4fe4 100644 --- a/cmd/util.go +++ b/cmd/util.go @@ -23,9 +23,8 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/go-units" - config "github.com/mudler/luet/pkg/config" + "github.com/mudler/luet/cmd/util" "github.com/mudler/luet/pkg/helpers/docker" - . "github.com/mudler/luet/pkg/logger" "github.com/spf13/cobra" ) @@ -42,7 +41,7 @@ func NewUnpackCommand() *cobra.Command { PreRun: func(cmd *cobra.Command, args []string) { if len(args) != 2 { - Fatal("Expects an image and a path") + util.DefaultContext.Fatal("Expects an image and a path") } }, @@ -51,7 +50,7 @@ func NewUnpackCommand() *cobra.Command { image := args[0] destination, err := filepath.Abs(args[1]) if err != nil { - Error("Invalid path %s", destination) + util.DefaultContext.Error("Invalid path %s", destination) os.Exit(1) } @@ -63,12 +62,12 @@ func NewUnpackCommand() *cobra.Command { identity, _ := cmd.Flags().GetString("auth-identity-token") registryToken, _ := cmd.Flags().GetString("auth-registry-token") - temp, err := config.LuetCfg.GetSystem().TempDir("contentstore") + temp, err := util.DefaultContext.Config.GetSystem().TempDir("contentstore") if err != nil { - Fatal("Cannot create a tempdir", err.Error()) + util.DefaultContext.Fatal("Cannot create a tempdir", err.Error()) } - Info("Downloading", image, "to", destination) + util.DefaultContext.Info("Downloading", image, "to", destination) auth := &types.AuthConfig{ Username: user, Password: pass, @@ -80,11 +79,11 @@ func NewUnpackCommand() *cobra.Command { info, err := docker.DownloadAndExtractDockerImage(temp, image, destination, auth, verify) if err != nil { - Error(err.Error()) + util.DefaultContext.Error(err.Error()) os.Exit(1) } - Info(fmt.Sprintf("Pulled: %s %s", info.Target.Digest, info.Name)) - Info(fmt.Sprintf("Size: %s", units.BytesSize(float64(info.Target.Size)))) + util.DefaultContext.Info(fmt.Sprintf("Pulled: %s %s", info.Target.Digest, info.Name)) + util.DefaultContext.Info(fmt.Sprintf("Size: %s", units.BytesSize(float64(info.Target.Size)))) }, } diff --git a/cmd/util/cli.go b/cmd/util/cli.go index 85420b86..df1376ca 100644 --- a/cmd/util/cli.go +++ b/cmd/util/cli.go @@ -17,18 +17,24 @@ package util import ( "errors" + "os" "path/filepath" "strings" + "github.com/marcsauter/single" "github.com/pterm/pterm" "github.com/spf13/cobra" "github.com/spf13/viper" - "github.com/mudler/luet/pkg/config" - . "github.com/mudler/luet/pkg/config" + "github.com/mudler/luet/pkg/api/core/types" "github.com/mudler/luet/pkg/installer" ) +var DefaultContext = types.NewContext() + +var lockedCommands = []string{"install", "uninstall", "upgrade"} +var bannerCommands = []string{"install", "build", "uninstall", "upgrade"} + func BindSystemFlags(cmd *cobra.Command) { viper.BindPFlag("system.database_path", cmd.Flags().Lookup("system-dbpath")) viper.BindPFlag("system.rootfs", cmd.Flags().Lookup("system-target")) @@ -50,28 +56,28 @@ func ValuesFlags() []string { return viper.GetStringSlice("values") } -func SetSystemConfig() { +func SetSystemConfig(ctx *types.Context) { dbpath := viper.GetString("system.database_path") rootfs := viper.GetString("system.rootfs") engine := viper.GetString("system.database_engine") - LuetCfg.System.DatabaseEngine = engine - LuetCfg.System.DatabasePath = dbpath - LuetCfg.System.SetRootFS(rootfs) + ctx.Config.System.DatabaseEngine = engine + ctx.Config.System.DatabasePath = dbpath + ctx.Config.System.SetRootFS(rootfs) } -func SetSolverConfig() (c *config.LuetSolverOptions) { +func SetSolverConfig(ctx *types.Context) (c *types.LuetSolverOptions) { stype := viper.GetString("solver.type") discount := viper.GetFloat64("solver.discount") rate := viper.GetFloat64("solver.rate") attempts := viper.GetInt("solver.max_attempts") - LuetCfg.GetSolverOptions().Type = stype - LuetCfg.GetSolverOptions().LearnRate = float32(rate) - LuetCfg.GetSolverOptions().Discount = float32(discount) - LuetCfg.GetSolverOptions().MaxAttempts = attempts + ctx.Config.GetSolverOptions().Type = stype + ctx.Config.GetSolverOptions().LearnRate = float32(rate) + ctx.Config.GetSolverOptions().Discount = float32(discount) + ctx.Config.GetSolverOptions().MaxAttempts = attempts - return &config.LuetSolverOptions{ + return &types.LuetSolverOptions{ Type: stype, LearnRate: float32(rate), Discount: float32(discount), @@ -79,7 +85,7 @@ func SetSolverConfig() (c *config.LuetSolverOptions) { } } -func SetCliFinalizerEnvs(finalizerEnvs []string) error { +func SetCliFinalizerEnvs(ctx *types.Context, finalizerEnvs []string) error { if len(finalizerEnvs) > 0 { for _, v := range finalizerEnvs { idx := strings.Index(v, "=") @@ -87,7 +93,7 @@ func SetCliFinalizerEnvs(finalizerEnvs []string) error { return errors.New("Found invalid runtime finalizer environment: " + v) } - LuetCfg.SetFinalizerEnv(v[0:idx], v[idx+1:]) + ctx.Config.SetFinalizerEnv(v[0:idx], v[idx+1:]) } } @@ -96,13 +102,13 @@ func SetCliFinalizerEnvs(finalizerEnvs []string) error { } // TemplateFolders returns the default folders which holds shared template between packages in a given tree path -func TemplateFolders(fromRepo bool, treePaths []string) []string { +func TemplateFolders(ctx *types.Context, fromRepo bool, treePaths []string) []string { templateFolders := []string{} for _, t := range treePaths { templateFolders = append(templateFolders, filepath.Join(t, "templates")) } if fromRepo { - for _, s := range installer.SystemRepositories(LuetCfg.SystemRepositories) { + for _, s := range installer.SystemRepositories(ctx.Config.SystemRepositories) { templateFolders = append(templateFolders, filepath.Join(s.TreePath, "templates")) } } @@ -119,3 +125,42 @@ func IntroScreen() { pterm.DefaultCenter.Print(pterm.DefaultHeader.WithFullWidth().WithBackgroundStyle(pterm.NewStyle(pterm.BgLightBlue)).WithMargin(10).Sprint("Luet - 0-deps container-based package manager")) } + +func HandleLock(c *types.Context) { + if os.Getenv("LUET_NOLOCK") != "true" { + if len(os.Args) > 1 { + for _, lockedCmd := range lockedCommands { + if os.Args[1] == lockedCmd { + s := single.New("luet") + if err := s.CheckLock(); err != nil && err == single.ErrAlreadyRunning { + c.Fatal("another instance of the app is already running, exiting") + } else if err != nil { + // Another error occurred, might be worth handling it as well + c.Fatal("failed to acquire exclusive app lock:", err.Error()) + } + defer s.TryUnlock() + break + } + } + } + } +} + +func DisplayVersionBanner(c *types.Context, banner func(), version func() string, license []string) { + display := false + if len(os.Args) > 1 { + for _, c := range bannerCommands { + if os.Args[1] == c { + display = true + } + } + } + if display { + banner() + pterm.DefaultCenter.Print(version()) + for _, l := range license { + pterm.DefaultCenter.Print(l) + + } + } +} diff --git a/cmd/util/config.go b/cmd/util/config.go index bc9a4a37..81879391 100644 --- a/cmd/util/config.go +++ b/cmd/util/config.go @@ -1,3 +1,18 @@ +// Copyright © 2021 Ettore Di Giacinto +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, see . + package util import ( @@ -9,13 +24,10 @@ import ( "strings" extensions "github.com/mudler/cobra-extensions" - . "github.com/mudler/luet/pkg/logger" + "github.com/mudler/luet/pkg/api/core/types" - "github.com/mudler/luet/pkg/config" helpers "github.com/mudler/luet/pkg/helpers" fileHelper "github.com/mudler/luet/pkg/helpers/file" - "github.com/mudler/luet/pkg/helpers/terminal" - repo "github.com/mudler/luet/pkg/repository" "github.com/spf13/cobra" "github.com/spf13/viper" @@ -29,6 +41,7 @@ var cfgFile string // initConfig reads in config file and ENV variables if set. func initConfig() { + setDefaults(viper.GetViper()) // Luet support these priorities on read configuration file: // - command line option (if available) // - $PWD/.luet.yaml @@ -46,7 +59,7 @@ func initConfig() { // Retrieve pwd directory pwdDir, err := os.Getwd() if err != nil { - Error(err) + fmt.Println(err) os.Exit(1) } homeDir := helpers.GetHomeDir() @@ -69,56 +82,31 @@ func initConfig() { replacer := strings.NewReplacer(".", "__") viper.SetEnvKeyReplacer(replacer) viper.SetTypeByDefaultValue(true) + // If a config file is found, read it in. + viper.ReadInConfig() + } -func LoadConfig() (cc config.LuetConfig, err error) { - setDefaults(viper.GetViper()) - initConfig() +// InitContext inits the context by parsing the configurations from viper +// this is meant to be run before each command to be able to parse any override from +// the CLI/ENV +func InitContext(ctx *types.Context) (err error) { - // If a config file is found, read it in. - err = viper.ReadInConfig() + err = viper.Unmarshal(&ctx.Config) if err != nil { return } - err = viper.Unmarshal(&cc) + // Inits the context with the configurations loaded + // It reads system repositories, sets logging, and all the + // context which is required to perform luet actions + err = ctx.Init() if err != nil { return } - if terminal.IsTerminal(os.Stdout) { - noSpinner := viper.GetBool("no_spinner") - InitAurora() - if !noSpinner { - NewSpinner() - } - noColor := viper.GetBool("logging.color") - if noColor { - fmt.Println("Disabling color") - NoColor() - } - } else { - fmt.Println("Not a terminal, disabling color") - NoColor() - } - - Debug("Using config file:", viper.ConfigFileUsed()) - - if cc.GetLogging().EnableLogFile && cc.GetLogging().Path != "" { - // Init zap logger - err = ZapLogger() - if err != nil { - return - } - } - - // Load repositories - err = repo.LoadRepositories(&cc) - if err != nil { - return - } - - config.LuetCfg = &cc + // no_spinner is not mapped in our configs + ctx.NoSpinner = viper.GetBool("no_spinner") return } @@ -133,8 +121,6 @@ func setDefaults(viper *viper.Viper) { viper.SetDefault("general.concurrency", runtime.NumCPU()) viper.SetDefault("general.debug", false) viper.SetDefault("general.show_build_output", false) - viper.SetDefault("general.spinner_ms", 100) - viper.SetDefault("general.spinner_charset", 22) viper.SetDefault("general.fatal_warnings", false) u, err := user.Current() @@ -158,7 +144,7 @@ func setDefaults(viper *viper.Viper) { viper.SetDefault("config_from_host", true) viper.SetDefault("cache_repositories", []string{}) viper.SetDefault("system_repositories", []string{}) - viper.SetDefault("finalizer_envs", make(map[string]string, 0)) + viper.SetDefault("finalizer_envs", make(map[string]string)) viper.SetDefault("solver.type", "") viper.SetDefault("solver.rate", 0.7) @@ -166,7 +152,9 @@ func setDefaults(viper *viper.Viper) { viper.SetDefault("solver.max_attempts", 9000) } -func InitViper(RootCmd *cobra.Command) { +// InitViper inits a new viper +// this is meant to be run just once at beginning to setup the root command +func InitViper(ctx *types.Context, RootCmd *cobra.Command) { cobra.OnInitialize(initConfig) pflags := RootCmd.PersistentFlags() pflags.StringVar(&cfgFile, "config", "", "config file (default is $HOME/.luet.yaml)") @@ -174,11 +162,11 @@ func InitViper(RootCmd *cobra.Command) { pflags.Bool("fatal", false, "Enables Warnings to exit") pflags.Bool("enable-logfile", false, "Enable log to file") pflags.Bool("no-spinner", false, "Disable spinner.") - pflags.Bool("color", config.LuetCfg.GetLogging().Color, "Enable/Disable color.") - pflags.Bool("emoji", config.LuetCfg.GetLogging().EnableEmoji, "Enable/Disable emoji.") - pflags.Bool("skip-config-protect", config.LuetCfg.ConfigProtectSkip, + pflags.Bool("color", ctx.Config.GetLogging().Color, "Enable/Disable color.") + pflags.Bool("emoji", ctx.Config.GetLogging().EnableEmoji, "Enable/Disable emoji.") + pflags.Bool("skip-config-protect", ctx.Config.ConfigProtectSkip, "Disable config protect analysis.") - pflags.StringP("logfile", "l", config.LuetCfg.GetLogging().Path, + pflags.StringP("logfile", "l", ctx.Config.GetLogging().Path, "Logfile path. Empty value disable log to file.") pflags.StringSlice("plugin", []string{}, "A list of runtime plugins to load") @@ -186,9 +174,9 @@ func InitViper(RootCmd *cobra.Command) { // Check if i can retrieve user informations. _, err := user.Current() if err != nil { - Warning("failed to retrieve user identity:", err.Error()) + ctx.Warning("failed to retrieve user identity:", err.Error()) } - pflags.Bool("same-owner", config.LuetCfg.GetGeneral().SameOwner, "Maintain same owner on uncompress.") + pflags.Bool("same-owner", ctx.Config.GetGeneral().SameOwner, "Maintain same owner on uncompress.") pflags.Int("concurrency", runtime.NumCPU(), "Concurrency") viper.BindPFlag("logging.color", pflags.Lookup("color")) @@ -213,5 +201,4 @@ func InitViper(RootCmd *cobra.Command) { cobraCmd := ex.CobraCommand() RootCmd.AddCommand(cobraCmd) } - } diff --git a/pkg/repository/repository_suite_test.go b/cmd/util/search.go similarity index 53% rename from pkg/repository/repository_suite_test.go rename to cmd/util/search.go index 2c587a95..57d8a9c6 100644 --- a/pkg/repository/repository_suite_test.go +++ b/cmd/util/search.go @@ -1,5 +1,4 @@ -// Copyright © 2019 Ettore Di Giacinto -// Daniele Rondina +// Copyright © 2021 Ettore Di Giacinto // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -14,19 +13,30 @@ // You should have received a copy of the GNU General Public License along // with this program; if not, see . -package repository_test +package util -import ( - "testing" +import "github.com/pterm/pterm" - . "github.com/mudler/luet/cmd/util" - - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" -) - -func TestSolver(t *testing.T) { - RegisterFailHandler(Fail) - LoadConfig() - RunSpecs(t, "Repository Suite") +type TableWriter struct { + td pterm.TableData +} + +func (l *TableWriter) AppendRow(item []string) { + l.td = append(l.td, item) +} + +func (l *TableWriter) Render() { + pterm.DefaultTable.WithHasHeader().WithData(l.td).Render() +} + +type ListWriter struct { + bb []pterm.BulletListItem +} + +func (l *ListWriter) AppendItem(item pterm.BulletListItem) { + l.bb = append(l.bb, item) +} + +func (l *ListWriter) Render() { + pterm.DefaultBulletList.WithItems(l.bb).Render() } diff --git a/pkg/config/config_protect.go b/pkg/api/core/config/config_protect.go similarity index 93% rename from pkg/config/config_protect.go rename to pkg/api/core/config/config_protect.go index 228488c3..42777acd 100644 --- a/pkg/config/config_protect.go +++ b/pkg/api/core/config/config_protect.go @@ -65,10 +65,7 @@ func (c *ConfigProtect) GetAnnotationDir() string { return c.AnnotationDir } -func (c *ConfigProtect) Map(files []string) { - if LuetCfg.ConfigProtectSkip { - return - } +func (c *ConfigProtect) Map(files []string, protected []ConfigProtectConfFile) { for _, file := range files { @@ -76,8 +73,8 @@ func (c *ConfigProtect) Map(files []string) { file = "/" + file } - if len(LuetCfg.GetConfigProtectConfFiles()) > 0 { - for _, conf := range LuetCfg.GetConfigProtectConfFiles() { + if len(protected) > 0 { + for _, conf := range protected { for _, dir := range conf.Directories { // Note file is without / at begin (on unpack) if strings.HasPrefix(file, filepath.Clean(dir)) { diff --git a/pkg/config/config_protect_test.go b/pkg/api/core/config/config_protect_test.go similarity index 89% rename from pkg/config/config_protect_test.go rename to pkg/api/core/config/config_protect_test.go index 8ce93248..43183c8d 100644 --- a/pkg/config/config_protect_test.go +++ b/pkg/api/core/config/config_protect_test.go @@ -17,7 +17,8 @@ package config_test import ( - config "github.com/mudler/luet/pkg/config" + config "github.com/mudler/luet/pkg/api/core/config" + "github.com/mudler/luet/pkg/api/core/types" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" @@ -28,7 +29,7 @@ var _ = Describe("Config", func() { Context("Test config protect", func() { It("Protect1", func() { - + ctx := types.NewContext() files := []string{ "etc/foo/my.conf", "usr/bin/foo", @@ -36,7 +37,7 @@ var _ = Describe("Config", func() { } cp := config.NewConfigProtect("/etc") - cp.Map(files) + cp.Map(files, ctx.Config.ConfigProtectConfFiles) Expect(cp.Protected("etc/foo/my.conf")).To(BeTrue()) Expect(cp.Protected("/etc/foo/my.conf")).To(BeTrue()) @@ -58,6 +59,7 @@ var _ = Describe("Config", func() { }) It("Protect2", func() { + ctx := types.NewContext() files := []string{ "etc/foo/my.conf", @@ -66,7 +68,7 @@ var _ = Describe("Config", func() { } cp := config.NewConfigProtect("") - cp.Map(files) + cp.Map(files, ctx.Config.ConfigProtectConfFiles) Expect(cp.Protected("etc/foo/my.conf")).To(BeFalse()) Expect(cp.Protected("/etc/foo/my.conf")).To(BeFalse()) @@ -84,6 +86,7 @@ var _ = Describe("Config", func() { }) It("Protect3: Annotation dir without initial slash", func() { + ctx := types.NewContext() files := []string{ "etc/foo/my.conf", @@ -92,7 +95,7 @@ var _ = Describe("Config", func() { } cp := config.NewConfigProtect("etc") - cp.Map(files) + cp.Map(files, ctx.Config.ConfigProtectConfFiles) Expect(cp.Protected("etc/foo/my.conf")).To(BeTrue()) Expect(cp.Protected("/etc/foo/my.conf")).To(BeTrue()) diff --git a/pkg/config/config_suite_test.go b/pkg/api/core/config/config_suite_test.go similarity index 94% rename from pkg/config/config_suite_test.go rename to pkg/api/core/config/config_suite_test.go index 84565876..875feb73 100644 --- a/pkg/config/config_suite_test.go +++ b/pkg/api/core/config/config_suite_test.go @@ -19,14 +19,11 @@ package config_test import ( "testing" - . "github.com/mudler/luet/cmd/util" - . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) func TestSolver(t *testing.T) { RegisterFailHandler(Fail) - LoadConfig() RunSpecs(t, "Config Suite") } diff --git a/pkg/api/core/types/artifact/artifact.go b/pkg/api/core/types/artifact/artifact.go index f46b6fb6..682090b1 100644 --- a/pkg/api/core/types/artifact/artifact.go +++ b/pkg/api/core/types/artifact/artifact.go @@ -36,16 +36,17 @@ import ( "strings" "sync" + config "github.com/mudler/luet/pkg/api/core/config" + types "github.com/mudler/luet/pkg/api/core/types" bus "github.com/mudler/luet/pkg/bus" backend "github.com/mudler/luet/pkg/compiler/backend" compression "github.com/mudler/luet/pkg/compiler/types/compression" compilerspec "github.com/mudler/luet/pkg/compiler/types/spec" - . "github.com/mudler/luet/pkg/config" "github.com/mudler/luet/pkg/helpers" fileHelper "github.com/mudler/luet/pkg/helpers/file" - . "github.com/mudler/luet/pkg/logger" pkg "github.com/mudler/luet/pkg/package" "github.com/mudler/luet/pkg/solver" + "github.com/pkg/errors" yaml "gopkg.in/yaml.v2" ) @@ -115,7 +116,6 @@ func (a *PackageArtifact) WriteYAML(dst string) error { if err != nil { return errors.Wrapf(err, "getting runtime package for '%s'", a.CompileSpec.Package.HumanReadableString()) } - Debug(fmt.Sprintf("embedding runtime package (%s) definition to artifact metadata", a.CompileSpec.Package.HumanReadableString())) a.Runtime = runtime } @@ -163,12 +163,12 @@ COPY . /` } // CreateArtifactForFile creates a new artifact from the given file -func CreateArtifactForFile(s string, opts ...func(*PackageArtifact)) (*PackageArtifact, error) { +func CreateArtifactForFile(ctx *types.Context, s string, opts ...func(*PackageArtifact)) (*PackageArtifact, error) { if _, err := os.Stat(s); os.IsNotExist(err) { return nil, errors.Wrap(err, "artifact path doesn't exist") } fileName := path.Base(s) - archive, err := LuetCfg.GetSystem().TempDir("archive") + archive, err := ctx.Config.GetSystem().TempDir("archive") if err != nil { return nil, errors.Wrap(err, "error met while creating tempdir for "+s) } @@ -178,7 +178,7 @@ func CreateArtifactForFile(s string, opts ...func(*PackageArtifact)) (*PackageAr return nil, errors.Wrapf(err, "error while copying %s to %s", s, dst) } - artifact, err := LuetCfg.GetSystem().TempDir("artifact") + artifact, err := ctx.Config.GetSystem().TempDir("artifact") if err != nil { return nil, errors.Wrap(err, "error met while creating tempdir for "+s) } @@ -196,9 +196,9 @@ type ImageBuilder interface { } // GenerateFinalImage takes an artifact and builds a Docker image with its content -func (a *PackageArtifact) GenerateFinalImage(imageName string, b ImageBuilder, keepPerms bool) (backend.Options, error) { +func (a *PackageArtifact) GenerateFinalImage(ctx *types.Context, imageName string, b ImageBuilder, keepPerms bool) (backend.Options, error) { builderOpts := backend.Options{} - archive, err := LuetCfg.GetSystem().TempDir("archive") + archive, err := ctx.Config.GetSystem().TempDir("archive") if err != nil { return builderOpts, errors.Wrap(err, "error met while creating tempdir for "+a.Path) } @@ -211,7 +211,7 @@ func (a *PackageArtifact) GenerateFinalImage(imageName string, b ImageBuilder, k return builderOpts, errors.Wrap(err, "error met while creating tempdir for "+a.Path) } - if err := a.Unpack(uncompressedFiles, keepPerms); err != nil { + if err := a.Unpack(ctx, uncompressedFiles, keepPerms); err != nil { return builderOpts, errors.Wrap(err, "error met while uncompressing artifact "+a.Path) } @@ -281,7 +281,7 @@ func (a *PackageArtifact) Compress(src string, concurrency int) error { } os.RemoveAll(a.Path) // Remove original - Debug("Removed artifact", a.Path) + // Debug("Removed artifact", a.Path) a.Path = zstdFile return nil @@ -315,7 +315,7 @@ func (a *PackageArtifact) Compress(src string, concurrency int) error { } w.Close() os.RemoveAll(a.Path) // Remove original - Debug("Removed artifact", a.Path) + // Debug("Removed artifact", a.Path) // a.CompressedPath = gzipfile a.Path = gzipfile return nil @@ -369,72 +369,74 @@ func hashFileContent(path string) (string, error) { return base64.URLEncoding.EncodeToString(h.Sum(nil)), nil } -func tarModifierWrapperFunc(dst, path string, header *tar.Header, content io.Reader) (*tar.Header, []byte, error) { - // If the destination path already exists I rename target file name with postfix. - var destPath string +func tarModifierWrapperFunc(ctx *types.Context) func(dst, path string, header *tar.Header, content io.Reader) (*tar.Header, []byte, error) { + return func(dst, path string, header *tar.Header, content io.Reader) (*tar.Header, []byte, error) { + // If the destination path already exists I rename target file name with postfix. + var destPath string - // Read data. TODO: We need change archive callback to permit to return a Reader - buffer := bytes.Buffer{} - if content != nil { - if _, err := buffer.ReadFrom(content); err != nil { - return nil, nil, err - } - } - tarHash := hashContent(buffer.Bytes()) - - // If file is not present on archive but is defined on mods - // I receive the callback. Prevent nil exception. - if header != nil { - switch header.Typeflag { - case tar.TypeReg: - destPath = filepath.Join(dst, path) - default: - // Nothing to do. I return original reader - return header, buffer.Bytes(), nil - } - - existingHash := "" - f, err := os.Lstat(destPath) - if err == nil { - Debug("File exists already, computing hash for", destPath) - hash, herr := hashFileContent(destPath) - if herr == nil { - existingHash = hash + // Read data. TODO: We need change archive callback to permit to return a Reader + buffer := bytes.Buffer{} + if content != nil { + if _, err := buffer.ReadFrom(content); err != nil { + return nil, nil, err } } + tarHash := hashContent(buffer.Bytes()) - Debug("Existing file hash: ", existingHash, "Tar file hashsum: ", tarHash) - // We want to protect file only if the hash of the files are differing OR the file size are - differs := (existingHash != "" && existingHash != tarHash) || (err != nil && f != nil && header.Size != f.Size()) - // Check if exists - if fileHelper.Exists(destPath) && differs { - for i := 1; i < 1000; i++ { - name := filepath.Join(filepath.Join(filepath.Dir(path), - fmt.Sprintf("._cfg%04d_%s", i, filepath.Base(path)))) + // If file is not present on archive but is defined on mods + // I receive the callback. Prevent nil exception. + if header != nil { + switch header.Typeflag { + case tar.TypeReg: + destPath = filepath.Join(dst, path) + default: + // Nothing to do. I return original reader + return header, buffer.Bytes(), nil + } - if fileHelper.Exists(name) { - continue + existingHash := "" + f, err := os.Lstat(destPath) + if err == nil { + ctx.Debug("File exists already, computing hash for", destPath) + hash, herr := hashFileContent(destPath) + if herr == nil { + existingHash = hash + } + } + + ctx.Debug("Existing file hash: ", existingHash, "Tar file hashsum: ", tarHash) + // We want to protect file only if the hash of the files are differing OR the file size are + differs := (existingHash != "" && existingHash != tarHash) || (err != nil && f != nil && header.Size != f.Size()) + // Check if exists + if fileHelper.Exists(destPath) && differs { + for i := 1; i < 1000; i++ { + name := filepath.Join(filepath.Join(filepath.Dir(path), + fmt.Sprintf("._cfg%04d_%s", i, filepath.Base(path)))) + + if fileHelper.Exists(name) { + continue + } + ctx.Info(fmt.Sprintf("Found protected file %s. Creating %s.", destPath, + filepath.Join(dst, name))) + return &tar.Header{ + Mode: header.Mode, + Typeflag: header.Typeflag, + PAXRecords: header.PAXRecords, + Name: name, + }, buffer.Bytes(), nil } - Info(fmt.Sprintf("Found protected file %s. Creating %s.", destPath, - filepath.Join(dst, name))) - return &tar.Header{ - Mode: header.Mode, - Typeflag: header.Typeflag, - PAXRecords: header.PAXRecords, - Name: name, - }, buffer.Bytes(), nil } } - } - return header, buffer.Bytes(), nil + return header, buffer.Bytes(), nil + } } -func (a *PackageArtifact) GetProtectFiles() []string { +func (a *PackageArtifact) GetProtectFiles(ctx *types.Context) []string { ans := []string{} annotationDir := "" - if !LuetCfg.ConfigProtectSkip { + if !ctx.Config.ConfigProtectSkip { // a.CompileSpec could be nil when artifact.Unpack is used for tree tarball if a.CompileSpec != nil && @@ -446,8 +448,8 @@ func (a *PackageArtifact) GetProtectFiles() []string { } // TODO: check if skip this if we have a.CompileSpec nil - cp := NewConfigProtect(annotationDir) - cp.Map(a.Files) + cp := config.NewConfigProtect(annotationDir) + cp.Map(a.Files, ctx.Config.GetConfigProtectConfFiles()) // NOTE: for unpack we need files path without initial / ans = cp.GetProtectFiles(false) @@ -457,15 +459,15 @@ func (a *PackageArtifact) GetProtectFiles() []string { } // Unpack Untar and decompress (TODO) to the given path -func (a *PackageArtifact) Unpack(dst string, keepPerms bool) error { +func (a *PackageArtifact) Unpack(ctx *types.Context, dst string, keepPerms bool) error { if !strings.HasPrefix(dst, "/") { return errors.New("destination must be an absolute path") } // Create - protectedFiles := a.GetProtectFiles() + protectedFiles := a.GetProtectFiles(ctx) - tarModifier := helpers.NewTarModifierWrapper(dst, tarModifierWrapperFunc) + tarModifier := helpers.NewTarModifierWrapper(dst, tarModifierWrapperFunc(ctx)) switch a.CompressionType { case compression.Zstandard: @@ -497,7 +499,7 @@ func (a *PackageArtifact) Unpack(dst string, keepPerms bool) error { } err = helpers.UntarProtect(a.Path+".uncompressed", dst, - LuetCfg.GetGeneral().SameOwner, protectedFiles, tarModifier) + ctx.Config.GetGeneral().SameOwner, protectedFiles, tarModifier) if err != nil { return err } @@ -530,14 +532,14 @@ func (a *PackageArtifact) Unpack(dst string, keepPerms bool) error { } err = helpers.UntarProtect(a.Path+".uncompressed", dst, - LuetCfg.GetGeneral().SameOwner, protectedFiles, tarModifier) + ctx.Config.GetGeneral().SameOwner, protectedFiles, tarModifier) if err != nil { return err } return nil // Defaults to tar only (covers when "none" is supplied) default: - return helpers.UntarProtect(a.Path, dst, LuetCfg.GetGeneral().SameOwner, + return helpers.UntarProtect(a.Path, dst, ctx.Config.GetGeneral().SameOwner, protectedFiles, tarModifier) } return errors.New("Compression type must be supplied") @@ -630,15 +632,15 @@ type CopyJob struct { Artifact string } -func worker(i int, wg *sync.WaitGroup, s <-chan CopyJob) { +func worker(ctx *types.Context, i int, wg *sync.WaitGroup, s <-chan CopyJob) { defer wg.Done() for job := range s { _, err := os.Lstat(job.Dst) if err != nil { - Debug("Copying ", job.Src) + ctx.Debug("Copying ", job.Src) if err := fileHelper.DeepCopyFile(job.Src, job.Dst); err != nil { - Warning("Error copying", job, err) + ctx.Warning("Error copying", job, err) } } } @@ -649,7 +651,6 @@ func compileRegexes(regexes []string) []*regexp.Regexp { for _, i := range regexes { r, e := regexp.Compile(i) if e != nil { - Warning("Failed compiling regex:", e) continue } result = append(result, r) @@ -674,16 +675,16 @@ type ArtifactLayer struct { } // ExtractArtifactFromDelta extracts deltas from ArtifactLayer from an image in tar format -func ExtractArtifactFromDelta(src, dst string, layers []ArtifactLayer, concurrency int, keepPerms bool, includes []string, excludes []string, t compression.Implementation) (*PackageArtifact, error) { +func ExtractArtifactFromDelta(ctx *types.Context, src, dst string, layers []ArtifactLayer, concurrency int, keepPerms bool, includes []string, excludes []string, t compression.Implementation) (*PackageArtifact, error) { - archive, err := LuetCfg.GetSystem().TempDir("archive") + archive, err := ctx.Config.GetSystem().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 := LuetCfg.GetSystem().TempDir("rootfs") + rootfs, err := ctx.Config.GetSystem().TempDir("rootfs") if err != nil { return nil, errors.Wrap(err, "Error met while creating tempdir for rootfs") } @@ -700,7 +701,7 @@ func ExtractArtifactFromDelta(src, dst string, layers []ArtifactLayer, concurren var wg = new(sync.WaitGroup) for i := 0; i < concurrency; i++ { wg.Add(1) - go worker(i, wg, toCopy) + go worker(ctx, i, wg, toCopy) } // Handle includes in spec. If specified they filter what gets in the package @@ -719,10 +720,10 @@ func ExtractArtifactFromDelta(src, dst string, layers []ArtifactLayer, concurren } } for _, a := range l.Diffs.Changes { - Debug("File ", a.Name, " changed") + ctx.Debug("File ", a.Name, " changed") } for _, a := range l.Diffs.Deletions { - Debug("File ", a.Name, " deleted") + ctx.Debug("File ", a.Name, " deleted") } } @@ -740,10 +741,10 @@ func ExtractArtifactFromDelta(src, dst string, layers []ArtifactLayer, concurren toCopy <- CopyJob{Src: filepath.Join(src, a.Name), Dst: filepath.Join(archive, a.Name), Artifact: a.Name} } for _, a := range l.Diffs.Changes { - Debug("File ", a.Name, " changed") + ctx.Debug("File ", a.Name, " changed") } for _, a := range l.Diffs.Deletions { - Debug("File ", a.Name, " deleted") + ctx.Debug("File ", a.Name, " deleted") } } @@ -768,10 +769,10 @@ func ExtractArtifactFromDelta(src, dst string, layers []ArtifactLayer, concurren } } for _, a := range l.Diffs.Changes { - Debug("File ", a.Name, " changed") + ctx.Debug("File ", a.Name, " changed") } for _, a := range l.Diffs.Deletions { - Debug("File ", a.Name, " deleted") + ctx.Debug("File ", a.Name, " deleted") } } @@ -780,14 +781,14 @@ func ExtractArtifactFromDelta(src, dst string, layers []ArtifactLayer, concurren for _, l := range layers { // Consider d.Additions (and d.Changes? - warn at least) only for _, a := range l.Diffs.Additions { - Debug("File ", a.Name, " added") + ctx.Debug("File ", a.Name, " added") toCopy <- CopyJob{Src: filepath.Join(src, a.Name), Dst: filepath.Join(archive, a.Name), Artifact: a.Name} } for _, a := range l.Diffs.Changes { - Debug("File ", a.Name, " changed") + ctx.Debug("File ", a.Name, " changed") } for _, a := range l.Diffs.Deletions { - Debug("File ", a.Name, " deleted") + ctx.Debug("File ", a.Name, " deleted") } } } diff --git a/pkg/api/core/types/artifact/artifact_suite_test.go b/pkg/api/core/types/artifact/artifact_suite_test.go index 39bf5c63..f252a999 100644 --- a/pkg/api/core/types/artifact/artifact_suite_test.go +++ b/pkg/api/core/types/artifact/artifact_suite_test.go @@ -18,14 +18,11 @@ package artifact_test import ( "testing" - . "github.com/mudler/luet/cmd/util" - . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) func TestArtifact(t *testing.T) { RegisterFailHandler(Fail) - LoadConfig() RunSpecs(t, "Artifact Suite") } diff --git a/pkg/api/core/types/artifact/artifact_test.go b/pkg/api/core/types/artifact/artifact_test.go index e5049d76..14592077 100644 --- a/pkg/api/core/types/artifact/artifact_test.go +++ b/pkg/api/core/types/artifact/artifact_test.go @@ -20,11 +20,13 @@ import ( "os" "path/filepath" + "github.com/mudler/luet/pkg/api/core/types" . "github.com/mudler/luet/pkg/api/core/types/artifact" "github.com/mudler/luet/pkg/compiler" . "github.com/mudler/luet/pkg/compiler/backend" backend "github.com/mudler/luet/pkg/compiler/backend" compression "github.com/mudler/luet/pkg/compiler/types/compression" + "github.com/mudler/luet/pkg/compiler/types/options" compilerspec "github.com/mudler/luet/pkg/compiler/types/spec" . "github.com/mudler/luet/pkg/compiler" @@ -38,6 +40,7 @@ import ( var _ = Describe("Artifact", func() { Context("Simple package build definition", func() { + ctx := types.NewContext() It("Generates a verified delta", func() { generalRecipe := tree.NewGeneralRecipe(pkg.NewInMemoryDatabase(false)) @@ -47,7 +50,7 @@ var _ = Describe("Artifact", func() { Expect(len(generalRecipe.GetDatabase().GetPackages())).To(Equal(1)) - cc := NewLuetCompiler(nil, generalRecipe.GetDatabase()) + cc := NewLuetCompiler(nil, generalRecipe.GetDatabase(), options.WithContext(types.NewContext())) lspec, err := cc.FromPackage(&pkg.DefaultPackage{Name: "enman", Category: "app-admin", Version: "1.4.0"}) Expect(err).ToNot(HaveOccurred()) @@ -81,7 +84,7 @@ WORKDIR /luetbuild ENV PACKAGE_NAME=enman ENV PACKAGE_VERSION=1.4.0 ENV PACKAGE_CATEGORY=app-admin`)) - b := NewSimpleDockerBackend() + b := NewSimpleDockerBackend(ctx) opts := backend.Options{ ImageName: "luet/base", SourcePath: tmpdir, @@ -115,7 +118,7 @@ RUN echo bar > /test2`)) Expect(b.BuildImage(opts2)).ToNot(HaveOccurred()) Expect(b.ExportImage(opts2)).ToNot(HaveOccurred()) Expect(fileHelper.Exists(filepath.Join(tmpdir, "output2.tar"))).To(BeTrue()) - diffs, err := compiler.GenerateChanges(b, opts, opts2) + diffs, err := compiler.GenerateChanges(ctx, b, opts, opts2) Expect(err).ToNot(HaveOccurred()) artifacts := []ArtifactNode{{ @@ -139,7 +142,7 @@ RUN echo bar > /test2`)) err = b.ExtractRootfs(backend.Options{ImageName: "test", Destination: rootfs}, false) Expect(err).ToNot(HaveOccurred()) - a, err := ExtractArtifactFromDelta(rootfs, filepath.Join(tmpdir, "package.tar"), diffs, 2, false, []string{}, []string{}, compression.None) + a, err := ExtractArtifactFromDelta(ctx, rootfs, filepath.Join(tmpdir, "package.tar"), diffs, 2, false, []string{}, []string{}, compression.None) Expect(err).ToNot(HaveOccurred()) Expect(fileHelper.Exists(filepath.Join(tmpdir, "package.tar"))).To(BeTrue()) err = helpers.Untar(a.Path, unpacked, false) @@ -164,7 +167,7 @@ RUN echo bar > /test2`)) }) It("Generates packages images", func() { - b := NewSimpleDockerBackend() + b := NewSimpleDockerBackend(ctx) imageprefix := "foo/" testString := []byte(`funky test data`) @@ -190,7 +193,7 @@ RUN echo bar > /test2`)) err = a.Compress(tmpdir, 1) Expect(err).ToNot(HaveOccurred()) resultingImage := imageprefix + "foo--1.0" - opts, err := a.GenerateFinalImage(resultingImage, b, false) + opts, err := a.GenerateFinalImage(ctx, resultingImage, b, false) Expect(err).ToNot(HaveOccurred()) Expect(opts.ImageName).To(Equal(resultingImage)) @@ -215,7 +218,7 @@ RUN echo bar > /test2`)) }) It("Generates empty packages images", func() { - b := NewSimpleDockerBackend() + b := NewSimpleDockerBackend(ctx) imageprefix := "foo/" tmpdir, err := ioutil.TempDir(os.TempDir(), "artifact") @@ -232,7 +235,7 @@ RUN echo bar > /test2`)) err = a.Compress(tmpdir, 1) Expect(err).ToNot(HaveOccurred()) resultingImage := imageprefix + "foo--1.0" - opts, err := a.GenerateFinalImage(resultingImage, b, false) + opts, err := a.GenerateFinalImage(ctx, resultingImage, b, false) Expect(err).ToNot(HaveOccurred()) Expect(opts.ImageName).To(Equal(resultingImage)) diff --git a/pkg/api/core/types/artifact/cache_test.go b/pkg/api/core/types/artifact/cache_test.go index 38a7e3a1..4452a167 100644 --- a/pkg/api/core/types/artifact/cache_test.go +++ b/pkg/api/core/types/artifact/cache_test.go @@ -20,6 +20,7 @@ import ( "os" "path/filepath" + types "github.com/mudler/luet/pkg/api/core/types" . "github.com/mudler/luet/pkg/api/core/types/artifact" compilerspec "github.com/mudler/luet/pkg/compiler/types/spec" fileHelper "github.com/mudler/luet/pkg/helpers/file" @@ -58,8 +59,8 @@ var _ = Describe("Cache", func() { Expect(err).ToNot(HaveOccurred()) b := NewPackageArtifact(path) - - err = b.Unpack(tmpdir, false) + ctx := types.NewContext() + err = b.Unpack(ctx, tmpdir, false) Expect(err).ToNot(HaveOccurred()) Expect(fileHelper.Exists(filepath.Join(tmpdir, "foo"))).To(BeTrue()) diff --git a/pkg/config/config.go b/pkg/api/core/types/config.go similarity index 65% rename from pkg/config/config.go rename to pkg/api/core/types/config.go index 54c6957f..a3d12fe2 100644 --- a/pkg/config/config.go +++ b/pkg/api/core/types/config.go @@ -15,17 +15,18 @@ // You should have received a copy of the GNU General Public License along // with this program; if not, see . -package config +package types import ( "fmt" "io/ioutil" "os" + "path" "path/filepath" + "regexp" "strings" - "time" - types "github.com/mudler/luet/pkg/api/core/types" + "github.com/mudler/luet/pkg/api/core/config" fileHelper "github.com/mudler/luet/pkg/helpers/file" pkg "github.com/mudler/luet/pkg/package" solver "github.com/mudler/luet/pkg/solver" @@ -34,7 +35,6 @@ import ( "gopkg.in/yaml.v2" ) -var LuetCfg = &LuetConfig{} var AvailableResolvers = strings.Join([]string{solver.QLearningResolverType}, " ") type LuetLoggingConfig struct { @@ -46,7 +46,7 @@ type LuetLoggingConfig struct { JsonFormat bool `mapstructure:"json_format"` // Log level - Level string `mapstructure:"level"` + Level LogLevel `mapstructure:"level"` // Enable emoji EnableEmoji bool `mapstructure:"enable_emoji"` @@ -59,8 +59,6 @@ type LuetGeneralConfig struct { Concurrency int `yaml:"concurrency,omitempty" mapstructure:"concurrency"` Debug bool `yaml:"debug,omitempty" mapstructure:"debug"` ShowBuildOutput bool `yaml:"show_build_output,omitempty" mapstructure:"show_build_output"` - SpinnerMs int `yaml:"spinner_ms,omitempty" mapstructure:"spinner_ms"` - SpinnerCharset int `yaml:"spinner_charset,omitempty" mapstructure:"spinner_charset"` FatalWarns bool `yaml:"fatal_warnings,omitempty" mapstructure:"fatal_warnings"` } @@ -171,33 +169,33 @@ type LuetConfig struct { System LuetSystemConfig `yaml:"system" mapstructure:"system"` Solver LuetSolverOptions `yaml:"solver,omitempty" mapstructure:"solver"` - RepositoriesConfDir []string `yaml:"repos_confdir,omitempty" mapstructure:"repos_confdir"` - ConfigProtectConfDir []string `yaml:"config_protect_confdir,omitempty" mapstructure:"config_protect_confdir"` - ConfigProtectSkip bool `yaml:"config_protect_skip,omitempty" mapstructure:"config_protect_skip"` - ConfigFromHost bool `yaml:"config_from_host,omitempty" mapstructure:"config_from_host"` - SystemRepositories types.LuetRepositories `yaml:"repositories,omitempty" mapstructure:"repositories"` + RepositoriesConfDir []string `yaml:"repos_confdir,omitempty" mapstructure:"repos_confdir"` + ConfigProtectConfDir []string `yaml:"config_protect_confdir,omitempty" mapstructure:"config_protect_confdir"` + ConfigProtectSkip bool `yaml:"config_protect_skip,omitempty" mapstructure:"config_protect_skip"` + ConfigFromHost bool `yaml:"config_from_host,omitempty" mapstructure:"config_from_host"` + SystemRepositories LuetRepositories `yaml:"repositories,omitempty" mapstructure:"repositories"` FinalizerEnvs []LuetKV `json:"finalizer_envs,omitempty" yaml:"finalizer_envs,omitempty" mapstructure:"finalizer_envs,omitempty"` - ConfigProtectConfFiles []ConfigProtectConfFile `yaml:"-" mapstructure:"-"` + ConfigProtectConfFiles []config.ConfigProtectConfFile `yaml:"-" mapstructure:"-"` } func (c *LuetConfig) GetSystemDB() pkg.PackageDatabase { - switch LuetCfg.GetSystem().DatabaseEngine { + switch c.GetSystem().DatabaseEngine { case "boltdb": return pkg.NewBoltDatabase( - filepath.Join(LuetCfg.GetSystem().GetSystemRepoDatabaseDirPath(), "luet.db")) + filepath.Join(c.GetSystem().GetSystemRepoDatabaseDirPath(), "luet.db")) default: return pkg.NewInMemoryDatabase(true) } } -func (c *LuetConfig) AddSystemRepository(r types.LuetRepository) { +func (c *LuetConfig) AddSystemRepository(r LuetRepository) { c.SystemRepositories = append(c.SystemRepositories, r) } func (c *LuetConfig) GetFinalizerEnvsMap() map[string]string { - ans := make(map[string]string, 0) + ans := make(map[string]string) for _, kv := range c.FinalizerEnvs { ans[kv.Key] = kv.Value @@ -268,20 +266,81 @@ func (c *LuetConfig) YAML() ([]byte, error) { return yaml.Marshal(c) } -func (c *LuetConfig) GetConfigProtectConfFiles() []ConfigProtectConfFile { +func (c *LuetConfig) GetConfigProtectConfFiles() []config.ConfigProtectConfFile { return c.ConfigProtectConfFiles } -func (c *LuetConfig) AddConfigProtectConfFile(file *ConfigProtectConfFile) { +func (c *LuetConfig) AddConfigProtectConfFile(file *config.ConfigProtectConfFile) { if c.ConfigProtectConfFiles == nil { - c.ConfigProtectConfFiles = []ConfigProtectConfFile{*file} + c.ConfigProtectConfFiles = []config.ConfigProtectConfFile{*file} } else { c.ConfigProtectConfFiles = append(c.ConfigProtectConfFiles, *file) } } -func (c *LuetConfig) GetSystemRepository(name string) (*types.LuetRepository, error) { - var ans *types.LuetRepository = nil +func (c *LuetConfig) LoadRepositories(ctx *Context) error { + var regexRepo = regexp.MustCompile(`.yml$|.yaml$`) + var err error + rootfs := "" + + // Respect the rootfs param on read repositories + if !c.ConfigFromHost { + rootfs, err = c.GetSystem().GetRootFsAbs() + if err != nil { + return err + } + } + + for _, rdir := range c.RepositoriesConfDir { + + rdir = filepath.Join(rootfs, rdir) + + ctx.Debug("Parsing Repository Directory", rdir, "...") + + files, err := ioutil.ReadDir(rdir) + if err != nil { + ctx.Debug("Skip dir", rdir, ":", err.Error()) + continue + } + + for _, file := range files { + if file.IsDir() { + continue + } + + if !regexRepo.MatchString(file.Name()) { + ctx.Debug("File", file.Name(), "skipped.") + continue + } + + content, err := ioutil.ReadFile(path.Join(rdir, file.Name())) + if err != nil { + ctx.Warning("On read file", file.Name(), ":", err.Error()) + ctx.Warning("File", file.Name(), "skipped.") + continue + } + + r, err := LoadRepository(content) + if err != nil { + ctx.Warning("On parse file", file.Name(), ":", err.Error()) + ctx.Warning("File", file.Name(), "skipped.") + continue + } + + if r.Name == "" || len(r.Urls) == 0 || r.Type == "" { + ctx.Warning("Invalid repository ", file.Name()) + ctx.Warning("File", file.Name(), "skipped.") + continue + } + + c.AddSystemRepository(*r) + } + } + return nil +} + +func (c *LuetConfig) GetSystemRepository(name string) (*LuetRepository, error) { + var ans *LuetRepository = nil for idx, repo := range c.SystemRepositories { if repo.Name == name { @@ -296,15 +355,78 @@ func (c *LuetConfig) GetSystemRepository(name string) (*types.LuetRepository, er return ans, nil } -func (c *LuetGeneralConfig) GetSpinnerMs() time.Duration { - duration, err := time.ParseDuration(fmt.Sprintf("%dms", c.SpinnerMs)) - if err != nil { - return 100 * time.Millisecond +func (c *LuetConfig) LoadConfigProtect(ctx *Context) error { + var regexConfs = regexp.MustCompile(`.yml$`) + var err error + + rootfs := "" + + // Respect the rootfs param on read repositories + if !c.ConfigFromHost { + rootfs, err = c.GetSystem().GetRootFsAbs() + if err != nil { + return err + } } - return duration + + for _, cdir := range c.ConfigProtectConfDir { + cdir = filepath.Join(rootfs, cdir) + + ctx.Debug("Parsing Config Protect Directory", cdir, "...") + + files, err := ioutil.ReadDir(cdir) + if err != nil { + ctx.Debug("Skip dir", cdir, ":", err.Error()) + continue + } + + for _, file := range files { + if file.IsDir() { + continue + } + + if !regexConfs.MatchString(file.Name()) { + ctx.Debug("File", file.Name(), "skipped.") + continue + } + + content, err := ioutil.ReadFile(path.Join(cdir, file.Name())) + if err != nil { + ctx.Warning("On read file", file.Name(), ":", err.Error()) + ctx.Warning("File", file.Name(), "skipped.") + continue + } + + r, err := loadConfigProtectConFile(file.Name(), content) + if err != nil { + ctx.Warning("On parse file", file.Name(), ":", err.Error()) + ctx.Warning("File", file.Name(), "skipped.") + continue + } + + if r.Name == "" || len(r.Directories) == 0 { + ctx.Warning("Invalid config protect file", file.Name()) + ctx.Warning("File", file.Name(), "skipped.") + continue + } + + c.AddConfigProtectConfFile(r) + } + } + return nil + } -func (c *LuetLoggingConfig) SetLogLevel(s string) { +func loadConfigProtectConFile(filename string, data []byte) (*config.ConfigProtectConfFile, error) { + ans := config.NewConfigProtectConfFile(filename) + err := yaml.Unmarshal(data, &ans) + if err != nil { + return nil, err + } + return ans, nil +} + +func (c *LuetLoggingConfig) SetLogLevel(s LogLevel) { c.Level = s } diff --git a/pkg/api/core/types/config_suite_test.go b/pkg/api/core/types/config_suite_test.go index 19b1a4f6..9abc4e08 100644 --- a/pkg/api/core/types/config_suite_test.go +++ b/pkg/api/core/types/config_suite_test.go @@ -18,14 +18,11 @@ package types_test import ( "testing" - . "github.com/mudler/luet/cmd/util" - . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) func TestAPITypes(t *testing.T) { RegisterFailHandler(Fail) - LoadConfig() RunSpecs(t, "Types Suite") } diff --git a/pkg/api/core/types/config_test.go b/pkg/api/core/types/config_test.go new file mode 100644 index 00000000..484c9f5b --- /dev/null +++ b/pkg/api/core/types/config_test.go @@ -0,0 +1,89 @@ +// Copyright © 2019-2020 Ettore Di Giacinto +// Daniele Rondina +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, see . + +package types_test + +import ( + "os" + "path/filepath" + "strings" + + types "github.com/mudler/luet/pkg/api/core/types" + fileHelper "github.com/mudler/luet/pkg/helpers/file" + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" +) + +var _ = Describe("Config", func() { + Context("Load Repository1", func() { + ctx := types.NewContext() + + ctx.Config.RepositoriesConfDir = []string{ + "../../../../tests/fixtures/repos.conf.d", + } + err := ctx.Config.LoadRepositories(ctx) + + It("Check Load Repository 1", func() { + Expect(err).Should(BeNil()) + Expect(len(ctx.Config.SystemRepositories)).Should(Equal(2)) + Expect(ctx.Config.SystemRepositories[0].Name).Should(Equal("test1")) + Expect(ctx.Config.SystemRepositories[0].Priority).Should(Equal(999)) + Expect(ctx.Config.SystemRepositories[0].Type).Should(Equal("disk")) + Expect(len(ctx.Config.SystemRepositories[0].Urls)).Should(Equal(1)) + Expect(ctx.Config.SystemRepositories[0].Urls[0]).Should(Equal("tests/repos/test1")) + }) + + It("Chec Load Repository 2", func() { + Expect(err).Should(BeNil()) + Expect(len(ctx.Config.SystemRepositories)).Should(Equal(2)) + Expect(ctx.Config.SystemRepositories[1].Name).Should(Equal("test2")) + Expect(ctx.Config.SystemRepositories[1].Priority).Should(Equal(1000)) + Expect(ctx.Config.SystemRepositories[1].Type).Should(Equal("disk")) + Expect(len(ctx.Config.SystemRepositories[1].Urls)).Should(Equal(1)) + Expect(ctx.Config.SystemRepositories[1].Urls[0]).Should(Equal("tests/repos/test2")) + }) + }) + Context("Simple temporary directory creation", func() { + + It("Create Temporary directory", func() { + ctx := types.NewContext() + + ctx.Config.GetSystem().TmpDirBase = os.TempDir() + "/tmpluet" + + tmpDir, err := ctx.Config.GetSystem().TempDir("test1") + Expect(err).ToNot(HaveOccurred()) + Expect(strings.HasPrefix(tmpDir, filepath.Join(os.TempDir(), "tmpluet"))).To(BeTrue()) + Expect(fileHelper.Exists(tmpDir)).To(BeTrue()) + + defer os.RemoveAll(tmpDir) + }) + + It("Create Temporary file", func() { + ctx := types.NewContext() + + ctx.Config.GetSystem().TmpDirBase = os.TempDir() + "/tmpluet" + + tmpFile, err := ctx.Config.GetSystem().TempFile("testfile1") + Expect(err).ToNot(HaveOccurred()) + Expect(strings.HasPrefix(tmpFile.Name(), filepath.Join(os.TempDir(), "tmpluet"))).To(BeTrue()) + Expect(fileHelper.Exists(tmpFile.Name())).To(BeTrue()) + + defer os.Remove(tmpFile.Name()) + }) + + }) + +}) diff --git a/pkg/api/core/types/context.go b/pkg/api/core/types/context.go new file mode 100644 index 00000000..7943aa13 --- /dev/null +++ b/pkg/api/core/types/context.go @@ -0,0 +1,380 @@ +// Copyright © 2021 Ettore Di Giacinto +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, see . + +package types + +import ( + "context" + "fmt" + "os" + "path" + "path/filepath" + "regexp" + "runtime" + "strings" + "sync" + + "github.com/kyokomi/emoji" + "github.com/mudler/luet/pkg/helpers/terminal" + "github.com/pterm/pterm" + "go.uber.org/zap" + "go.uber.org/zap/zapcore" +) + +const ( + ErrorLevel LogLevel = "error" + WarningLevel LogLevel = "warning" + InfoLevel LogLevel = "info" + SuccessLevel LogLevel = "success" + FatalLevel LogLevel = "fatal" +) + +type Context struct { + context.Context + Config *LuetConfig + IsTerminal bool + NoSpinner bool + + s *pterm.SpinnerPrinter + spinnerLock sync.Mutex + z *zap.Logger +} + +func NewContext() *Context { + return &Context{ + IsTerminal: terminal.IsTerminal(os.Stdout), + Config: &LuetConfig{ + ConfigFromHost: true, + Logging: LuetLoggingConfig{}, + General: LuetGeneralConfig{}, + System: LuetSystemConfig{ + DatabasePath: filepath.Join("var", "db", "packages"), + TmpDirBase: filepath.Join(os.TempDir(), "tmpluet")}, + Solver: LuetSolverOptions{}, + }, + s: pterm.DefaultSpinner.WithShowTimer(false).WithRemoveWhenDone(true), + } +} + +func (c *Context) Init() (err error) { + if c.IsTerminal { + if !c.Config.Logging.Color { + c.Debug("Disabling colors") + c.NoColor() + } + } else { + c.Debug("Not a terminal, disabling colors") + c.NoColor() + } + + c.Debug("Colors", c.Config.GetLogging().Color) + c.Debug("Logging level", c.Config.GetLogging().Level) + c.Debug("Debug mode", c.Config.GetGeneral().Debug) + + if c.Config.GetLogging().EnableLogFile && c.Config.GetLogging().Path != "" { + // Init zap logger + err = c.InitZap() + if err != nil { + return + } + } + + // Load repositories + err = c.Config.LoadRepositories(c) + if err != nil { + return + } + return +} + +func (c *Context) NoColor() { + pterm.DisableColor() +} + +func (c *Context) Ask() bool { + var input string + + c.Info("Do you want to continue with this operation? [y/N]: ") + _, err := fmt.Scanln(&input) + if err != nil { + return false + } + input = strings.ToLower(input) + + if input == "y" || input == "yes" { + return true + } + return false +} + +func (c *Context) InitZap() error { + var err error + if c.z == nil { + // TODO: test permission for open logfile. + cfg := zap.NewProductionConfig() + cfg.OutputPaths = []string{c.Config.GetLogging().Path} + cfg.Level = c.Config.GetLogging().Level.ZapLevel() + cfg.ErrorOutputPaths = []string{} + if c.Config.GetLogging().JsonFormat { + cfg.Encoding = "json" + } else { + cfg.Encoding = "console" + } + cfg.DisableCaller = true + cfg.DisableStacktrace = true + cfg.EncoderConfig.TimeKey = "time" + cfg.EncoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder + + c.z, err = cfg.Build() + if err != nil { + fmt.Fprint(os.Stderr, "Error on initialize file logger: "+err.Error()+"\n") + return err + } + } + + return nil +} + +// Spinner starts the spinner +func (c *Context) Spinner() { + if !c.IsTerminal || c.NoSpinner { + return + } + + c.spinnerLock.Lock() + defer c.spinnerLock.Unlock() + var confLevel int + if c.Config.GetGeneral().Debug { + confLevel = 3 + } else { + confLevel = c.Config.GetLogging().Level.ToNumber() + } + if 2 > confLevel { + return + } + + if !c.s.IsActive { + c.s, _ = c.s.Start() + } +} + +func (c *Context) Screen(text string) { + pterm.DefaultHeader.WithBackgroundStyle(pterm.NewStyle(pterm.BgLightBlue)).WithMargin(2).Println(text) + //pterm.DefaultCenter.Print(pterm.DefaultHeader.WithFullWidth().WithBackgroundStyle(pterm.NewStyle(pterm.BgLightBlue)).WithMargin(10).Sprint(text)) +} + +func (c *Context) SpinnerText(suffix, prefix string) { + if !c.IsTerminal || c.NoSpinner { + return + } + + c.spinnerLock.Lock() + defer c.spinnerLock.Unlock() + if c.Config.GetGeneral().Debug { + fmt.Printf("%s %s\n", + suffix, prefix, + ) + } else { + c.s.UpdateText(suffix + prefix) + } +} + +func (c *Context) SpinnerStop() { + if !c.IsTerminal { + return + } + + c.spinnerLock.Lock() + defer c.spinnerLock.Unlock() + var confLevel int + if c.Config.GetGeneral().Debug { + confLevel = 3 + } else { + confLevel = c.Config.GetLogging().Level.ToNumber() + } + if 2 > confLevel { + return + } + if c.s != nil { + c.s.Success() + } +} + +func (c *Context) log2File(level LogLevel, msg string) { + switch level { + case FatalLevel: + c.z.Fatal(msg) + case ErrorLevel: + c.z.Error(msg) + case WarningLevel: + c.z.Warn(msg) + case InfoLevel, SuccessLevel: + c.z.Info(msg) + default: + c.z.Debug(msg) + } +} + +func (c *Context) Msg(level LogLevel, ln bool, msg ...interface{}) { + var message string + var confLevel, msgLevel int + + if c.Config.GetGeneral().Debug { + confLevel = 3 + pterm.EnableDebugMessages() + } else { + confLevel = c.Config.GetLogging().Level.ToNumber() + } + msgLevel = level.ToNumber() + + if msgLevel > confLevel { + return + } + + for _, m := range msg { + message += " " + fmt.Sprintf("%v", m) + } + + // Color message + levelMsg := message + + if c.Config.GetLogging().Color { + switch level { + case WarningLevel: + levelMsg = pterm.LightYellow(":construction: warning" + message) + case InfoLevel, SuccessLevel: + levelMsg = pterm.LightGreen(message) + case ErrorLevel: + levelMsg = pterm.Red(message) + default: + levelMsg = pterm.Blue(message) + } + } + + // Strip emoji if needed + if c.Config.GetLogging().EnableEmoji && c.IsTerminal { + levelMsg = emoji.Sprint(levelMsg) + } else { + re := regexp.MustCompile(`[:][\w]+[:]`) + levelMsg = re.ReplaceAllString(levelMsg, "") + } + + if c.z != nil { + c.log2File(level, message) + } + + // Print the message based on the level + switch level { + case SuccessLevel: + if ln { + pterm.Success.Println(levelMsg) + } else { + pterm.Success.Print(levelMsg) + } + case InfoLevel: + if ln { + pterm.Info.Println(levelMsg) + } else { + pterm.Info.Print(levelMsg) + } + case WarningLevel: + if ln { + pterm.Warning.Println(levelMsg) + } else { + pterm.Warning.Print(levelMsg) + } + case ErrorLevel: + if ln { + pterm.Error.Println(levelMsg) + } else { + pterm.Error.Print(levelMsg) + } + case FatalLevel: + if ln { + pterm.Fatal.Println(levelMsg) + } else { + pterm.Fatal.Print(levelMsg) + } + default: + if ln { + pterm.Debug.Println(levelMsg) + } else { + pterm.Debug.Print(levelMsg) + } + } +} + +func (c *Context) Warning(mess ...interface{}) { + c.Msg("warning", true, mess...) + if c.Config.GetGeneral().FatalWarns { + os.Exit(2) + } +} + +func (c *Context) Debug(mess ...interface{}) { + pc, file, line, ok := runtime.Caller(1) + if ok { + mess = append([]interface{}{fmt.Sprintf("(%s:#%d:%v)", + path.Base(file), line, runtime.FuncForPC(pc).Name())}, mess...) + } + c.Msg("debug", true, mess...) +} + +func (c *Context) Info(mess ...interface{}) { + c.Msg("info", true, mess...) +} + +func (c *Context) Success(mess ...interface{}) { + c.Msg("success", true, mess...) +} + +func (c *Context) Error(mess ...interface{}) { + c.Msg("error", true, mess...) +} + +func (c *Context) Fatal(mess ...interface{}) { + c.Error(mess...) + os.Exit(1) +} + +type LogLevel string + +func (level LogLevel) ToNumber() int { + switch level { + case ErrorLevel, FatalLevel: + return 0 + case WarningLevel: + return 1 + case InfoLevel, SuccessLevel: + return 2 + default: // debug + return 3 + } +} + +func (level LogLevel) ZapLevel() zap.AtomicLevel { + switch level { + case FatalLevel: + return zap.NewAtomicLevelAt(zap.FatalLevel) + case ErrorLevel: + return zap.NewAtomicLevelAt(zap.ErrorLevel) + case WarningLevel: + return zap.NewAtomicLevelAt(zap.WarnLevel) + case InfoLevel, SuccessLevel: + return zap.NewAtomicLevelAt(zap.InfoLevel) + default: + return zap.NewAtomicLevelAt(zap.DebugLevel) + } +} diff --git a/pkg/api/core/types/repository_test.go b/pkg/api/core/types/repository_test.go index ecc064fa..94130cb2 100644 --- a/pkg/api/core/types/repository_test.go +++ b/pkg/api/core/types/repository_test.go @@ -18,7 +18,7 @@ package types_test import ( "runtime" - . "github.com/mudler/luet/pkg/api/core/types" + types "github.com/mudler/luet/pkg/api/core/types" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) @@ -26,23 +26,23 @@ import ( var _ = Describe("Types", func() { Context("Repository detects underlying arch", func() { It("is enabled if arch is matching", func() { - r := LuetRepository{Arch: runtime.GOARCH} + r := types.LuetRepository{Arch: runtime.GOARCH} Expect(r.Enabled()).To(BeTrue()) }) It("is disabled if arch is NOT matching", func() { - r := LuetRepository{Arch: "foo"} + r := types.LuetRepository{Arch: "foo"} Expect(r.Enabled()).To(BeFalse()) }) It("is enabled if arch is NOT matching and enabled is true", func() { - r := LuetRepository{Arch: "foo", Enable: true} + r := types.LuetRepository{Arch: "foo", Enable: true} Expect(r.Enabled()).To(BeTrue()) }) It("enabled is true", func() { - r := LuetRepository{Enable: true} + r := types.LuetRepository{Enable: true} Expect(r.Enabled()).To(BeTrue()) }) It("enabled is false", func() { - r := LuetRepository{Enable: false} + r := types.LuetRepository{Enable: false} Expect(r.Enabled()).To(BeFalse()) }) }) diff --git a/pkg/compiler/backend.go b/pkg/compiler/backend.go index 93ddaf54..d6d091b7 100644 --- a/pkg/compiler/backend.go +++ b/pkg/compiler/backend.go @@ -7,23 +7,21 @@ import ( "path/filepath" "strings" + "github.com/mudler/luet/pkg/api/core/types" artifact "github.com/mudler/luet/pkg/api/core/types/artifact" "github.com/mudler/luet/pkg/compiler/backend" - "github.com/mudler/luet/pkg/config" "github.com/pkg/errors" - - . "github.com/mudler/luet/pkg/logger" ) -func NewBackend(s string) (CompilerBackend, error) { +func NewBackend(ctx *types.Context, s string) (CompilerBackend, error) { var compilerBackend CompilerBackend switch s { case backend.ImgBackend: - compilerBackend = backend.NewSimpleImgBackend() + compilerBackend = backend.NewSimpleImgBackend(ctx) case backend.DockerBackend: - compilerBackend = backend.NewSimpleDockerBackend() + compilerBackend = backend.NewSimpleDockerBackend(ctx) default: return nil, errors.New("invalid backend. Unsupported") } @@ -73,11 +71,11 @@ type CompilerBackend interface { // } // } // ] -func GenerateChanges(b CompilerBackend, fromImage, toImage backend.Options) ([]artifact.ArtifactLayer, error) { +func GenerateChanges(ctx *types.Context, b CompilerBackend, fromImage, toImage backend.Options) ([]artifact.ArtifactLayer, error) { res := artifact.ArtifactLayer{FromImage: fromImage.ImageName, ToImage: toImage.ImageName} - tmpdiffs, err := config.LuetCfg.GetSystem().TempDir("extraction") + tmpdiffs, err := ctx.Config.GetSystem().TempDir("extraction") if err != nil { return []artifact.ArtifactLayer{}, errors.Wrap(err, "Error met while creating tempdir for rootfs") } @@ -99,7 +97,7 @@ func GenerateChanges(b CompilerBackend, fromImage, toImage backend.Options) ([]a ImageName: fromImage.ImageName, Destination: srcRootFS, } - Debug("Extracting source image", fromImage.ImageName) + ctx.Debug("Extracting source image", fromImage.ImageName) err = b.ExtractRootfs(srcImageExtract, false) // No need to keep permissions as we just collect file diffs if err != nil { return []artifact.ArtifactLayer{}, errors.Wrap(err, "Error met while unpacking src image "+fromImage.ImageName) @@ -109,7 +107,7 @@ func GenerateChanges(b CompilerBackend, fromImage, toImage backend.Options) ([]a ImageName: toImage.ImageName, Destination: dstRootFS, } - Debug("Extracting destination image", toImage.ImageName) + ctx.Debug("Extracting destination image", toImage.ImageName) err = b.ExtractRootfs(dstImageExtract, false) if err != nil { return []artifact.ArtifactLayer{}, errors.Wrap(err, "Error met while unpacking dst image "+toImage.ImageName) @@ -182,10 +180,10 @@ func GenerateChanges(b CompilerBackend, fromImage, toImage backend.Options) ([]a diffs := []artifact.ArtifactLayer{res} - if config.LuetCfg.GetGeneral().Debug { + if ctx.Config.GetGeneral().Debug { summary := ComputeArtifactLayerSummary(diffs) for _, l := range summary.Layers { - Debug(fmt.Sprintf("Diff %s -> %s: add %d (%d bytes), del %d (%d bytes), change %d (%d bytes)", + ctx.Debug(fmt.Sprintf("Diff %s -> %s: add %d (%d bytes), del %d (%d bytes), change %d (%d bytes)", l.FromImage, l.ToImage, l.AddFiles, l.AddSizes, l.DelFiles, l.DelSizes, diff --git a/pkg/compiler/backend/backend_suite_test.go b/pkg/compiler/backend/backend_suite_test.go index 40367241..3a636f33 100644 --- a/pkg/compiler/backend/backend_suite_test.go +++ b/pkg/compiler/backend/backend_suite_test.go @@ -18,14 +18,11 @@ package backend_test import ( "testing" - . "github.com/mudler/luet/cmd/util" - . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) func TestSolver(t *testing.T) { RegisterFailHandler(Fail) - LoadConfig() RunSpecs(t, "Backend Suite") } diff --git a/pkg/compiler/backend/common.go b/pkg/compiler/backend/common.go index a9327f2c..033d15e5 100644 --- a/pkg/compiler/backend/common.go +++ b/pkg/compiler/backend/common.go @@ -18,8 +18,7 @@ package backend import ( "os/exec" - "github.com/mudler/luet/pkg/config" - . "github.com/mudler/luet/pkg/logger" + "github.com/mudler/luet/pkg/api/core/types" "github.com/google/go-containerregistry/pkg/crane" "github.com/pkg/errors" @@ -44,17 +43,17 @@ type Options struct { BackendArgs []string } -func runCommand(cmd *exec.Cmd) error { +func runCommand(ctx *types.Context, cmd *exec.Cmd) error { output := "" - buffered := !config.LuetCfg.GetGeneral().ShowBuildOutput - writer := NewBackendWriter(buffered) + buffered := !ctx.Config.GetGeneral().ShowBuildOutput + writer := NewBackendWriter(buffered, ctx) cmd.Stdout = writer cmd.Stderr = writer if buffered { - Spinner(32) - defer SpinnerStop() + ctx.Spinner() + defer ctx.SpinnerStop() } err := cmd.Start() diff --git a/pkg/compiler/backend/simpledocker.go b/pkg/compiler/backend/simpledocker.go index 193ceaf1..a49cf37e 100644 --- a/pkg/compiler/backend/simpledocker.go +++ b/pkg/compiler/backend/simpledocker.go @@ -23,64 +23,66 @@ import ( "path/filepath" "strings" + "github.com/mudler/luet/pkg/api/core/types" bus "github.com/mudler/luet/pkg/bus" fileHelper "github.com/mudler/luet/pkg/helpers/file" capi "github.com/mudler/docker-companion/api" "github.com/mudler/luet/pkg/helpers" - . "github.com/mudler/luet/pkg/logger" "github.com/pkg/errors" ) -type SimpleDocker struct{} +type SimpleDocker struct { + ctx *types.Context +} -func NewSimpleDockerBackend() *SimpleDocker { - return &SimpleDocker{} +func NewSimpleDockerBackend(ctx *types.Context) *SimpleDocker { + return &SimpleDocker{ctx: ctx} } // TODO: Missing still: labels, and build args expansion -func (*SimpleDocker) BuildImage(opts Options) error { +func (s *SimpleDocker) BuildImage(opts Options) error { name := opts.ImageName bus.Manager.Publish(bus.EventImagePreBuild, opts) buildarg := genBuildCommand(opts) - Info(":whale2: Building image " + name) + s.ctx.Info(":whale2: Building image " + name) cmd := exec.Command("docker", buildarg...) cmd.Dir = opts.SourcePath - err := runCommand(cmd) + err := runCommand(s.ctx, cmd) if err != nil { return err } - Info(":whale: Building image " + name + " done") + s.ctx.Info(":whale: Building image " + name + " done") bus.Manager.Publish(bus.EventImagePostBuild, opts) return nil } -func (*SimpleDocker) CopyImage(src, dst string) error { - Debug(":whale: Tagging image:", src, "->", dst) +func (s *SimpleDocker) CopyImage(src, dst string) error { + s.ctx.Debug(":whale: Tagging image:", src, "->", dst) cmd := exec.Command("docker", "tag", src, dst) out, err := cmd.CombinedOutput() if err != nil { return errors.Wrap(err, "Failed tagging image: "+string(out)) } - Info(":whale: Tagged image:", src, "->", dst) + s.ctx.Info(":whale: Tagged image:", src, "->", dst) return nil } -func (*SimpleDocker) DownloadImage(opts Options) error { +func (s *SimpleDocker) DownloadImage(opts Options) error { name := opts.ImageName bus.Manager.Publish(bus.EventImagePrePull, opts) buildarg := []string{"pull", name} - Debug(":whale: Downloading image " + name) + s.ctx.Debug(":whale: Downloading image " + name) - Spinner(22) - defer SpinnerStop() + s.ctx.Spinner() + defer s.ctx.SpinnerStop() cmd := exec.Command("docker", buildarg...) out, err := cmd.CombinedOutput() @@ -88,20 +90,20 @@ func (*SimpleDocker) DownloadImage(opts Options) error { return errors.Wrap(err, "Failed pulling image: "+string(out)) } - Info(":whale: Downloaded image:", name) + s.ctx.Info(":whale: Downloaded image:", name) bus.Manager.Publish(bus.EventImagePostPull, opts) return nil } -func (*SimpleDocker) ImageExists(imagename string) bool { +func (s *SimpleDocker) ImageExists(imagename string) bool { buildarg := []string{"inspect", "--type=image", imagename} - Debug(":whale: Checking existance of docker image: " + imagename) + s.ctx.Debug(":whale: Checking existance of docker image: " + imagename) cmd := exec.Command("docker", buildarg...) out, err := cmd.CombinedOutput() if err != nil { - Debug("Image not present") - Debug(string(out)) + s.ctx.Debug("Image not present") + s.ctx.Debug(string(out)) return false } return true @@ -111,31 +113,31 @@ func (*SimpleDocker) ImageAvailable(imagename string) bool { return imageAvailable(imagename) } -func (*SimpleDocker) RemoveImage(opts Options) error { +func (s *SimpleDocker) RemoveImage(opts Options) error { name := opts.ImageName buildarg := []string{"rmi", name} out, err := exec.Command("docker", buildarg...).CombinedOutput() if err != nil { return errors.Wrap(err, "Failed removing image: "+string(out)) } - Info(":whale: Removed image:", name) + s.ctx.Info(":whale: Removed image:", name) //Info(string(out)) return nil } -func (*SimpleDocker) Push(opts Options) error { +func (s *SimpleDocker) Push(opts Options) error { name := opts.ImageName pusharg := []string{"push", name} bus.Manager.Publish(bus.EventImagePrePush, opts) - Spinner(22) - defer SpinnerStop() + s.ctx.Spinner() + defer s.ctx.SpinnerStop() out, err := exec.Command("docker", pusharg...).CombinedOutput() if err != nil { return errors.Wrap(err, "Failed pushing image: "+string(out)) } - Info(":whale: Pushed image:", name) + s.ctx.Info(":whale: Pushed image:", name) bus.Manager.Publish(bus.EventImagePostPush, opts) //Info(string(out)) @@ -155,22 +157,22 @@ func (s *SimpleDocker) ImageDefinitionToTar(opts Options) error { return nil } -func (*SimpleDocker) ExportImage(opts Options) error { +func (s *SimpleDocker) ExportImage(opts Options) error { name := opts.ImageName path := opts.Destination buildarg := []string{"save", name, "-o", path} - Debug(":whale: Saving image " + name) + s.ctx.Debug(":whale: Saving image " + name) - Spinner(22) - defer SpinnerStop() + s.ctx.Spinner() + defer s.ctx.SpinnerStop() out, err := exec.Command("docker", buildarg...).CombinedOutput() if err != nil { return errors.Wrap(err, "Failed exporting image: "+string(out)) } - Debug(":whale: Exported image:", name) + s.ctx.Debug(":whale: Exported image:", name) return nil } @@ -196,15 +198,13 @@ func (b *SimpleDocker) ExtractRootfs(opts Options, keepPerms bool) error { imageExport := filepath.Join(tempexport, "image.tar") - Spinner(22) - defer SpinnerStop() + b.ctx.Spinner() + defer b.ctx.SpinnerStop() if err := b.ExportImage(Options{ImageName: name, Destination: imageExport}); err != nil { return errors.Wrap(err, "failed while extracting rootfs for "+name) } - SpinnerStop() - src := imageExport if src == "" && opts.ImageName != "" { diff --git a/pkg/compiler/backend/simpledocker_test.go b/pkg/compiler/backend/simpledocker_test.go index 3ba17857..8411fc91 100644 --- a/pkg/compiler/backend/simpledocker_test.go +++ b/pkg/compiler/backend/simpledocker_test.go @@ -16,6 +16,7 @@ package backend_test import ( + "github.com/mudler/luet/pkg/api/core/types" "github.com/mudler/luet/pkg/api/core/types/artifact" "github.com/mudler/luet/pkg/compiler" . "github.com/mudler/luet/pkg/compiler" @@ -35,6 +36,7 @@ import ( var _ = Describe("Docker backend", func() { Context("Simple Docker backend satisfies main interface functionalities", func() { + ctx := types.NewContext() It("Builds and generate tars", func() { generalRecipe := tree.NewGeneralRecipe(pkg.NewInMemoryDatabase(false)) @@ -69,7 +71,7 @@ WORKDIR /luetbuild ENV PACKAGE_NAME=enman ENV PACKAGE_VERSION=1.4.0 ENV PACKAGE_CATEGORY=app-admin`)) - b := NewSimpleDockerBackend() + b := NewSimpleDockerBackend(ctx) opts := backend.Options{ ImageName: "luet/base", SourcePath: tmpdir, @@ -115,7 +117,7 @@ RUN echo bar > /test2`)) artifacts = append(artifacts, artifact.ArtifactNode{Name: "/test", Size: 4}) artifacts = append(artifacts, artifact.ArtifactNode{Name: "/test2", Size: 4}) - Expect(compiler.GenerateChanges(b, opts, opts2)).To(Equal( + Expect(compiler.GenerateChanges(ctx, b, opts, opts2)).To(Equal( []artifact.ArtifactLayer{{ FromImage: "luet/base", ToImage: "test", @@ -137,7 +139,7 @@ RUN echo bar > /test2`)) }) It("Detects available images", func() { - b := NewSimpleDockerBackend() + b := NewSimpleDockerBackend(ctx) Expect(b.ImageAvailable("quay.io/mocaccino/extra")).To(BeTrue()) Expect(b.ImageAvailable("ubuntu:20.10")).To(BeTrue()) Expect(b.ImageAvailable("igjo5ijgo25nho52")).To(BeFalse()) diff --git a/pkg/compiler/backend/simpleimg.go b/pkg/compiler/backend/simpleimg.go index 5c052771..2c875c1c 100644 --- a/pkg/compiler/backend/simpleimg.go +++ b/pkg/compiler/backend/simpleimg.go @@ -20,64 +20,65 @@ import ( "os/exec" "strings" + "github.com/mudler/luet/pkg/api/core/types" bus "github.com/mudler/luet/pkg/bus" - . "github.com/mudler/luet/pkg/logger" - "github.com/pkg/errors" ) -type SimpleImg struct{} +type SimpleImg struct { + ctx *types.Context +} -func NewSimpleImgBackend() *SimpleImg { - return &SimpleImg{} +func NewSimpleImgBackend(ctx *types.Context) *SimpleImg { + return &SimpleImg{ctx: ctx} } // TODO: Missing still: labels, and build args expansion -func (*SimpleImg) BuildImage(opts Options) error { +func (s *SimpleImg) BuildImage(opts Options) error { name := opts.ImageName bus.Manager.Publish(bus.EventImagePreBuild, opts) buildarg := genBuildCommand(opts) - Info(":tea: Building image " + name) + s.ctx.Info(":tea: Building image " + name) cmd := exec.Command("img", buildarg...) cmd.Dir = opts.SourcePath - err := runCommand(cmd) + err := runCommand(s.ctx, cmd) if err != nil { return err } bus.Manager.Publish(bus.EventImagePostBuild, opts) - Info(":tea: Building image " + name + " done") + s.ctx.Info(":tea: Building image " + name + " done") return nil } -func (*SimpleImg) RemoveImage(opts Options) error { +func (s *SimpleImg) RemoveImage(opts Options) error { name := opts.ImageName buildarg := []string{"rm", name} - Spinner(22) - defer SpinnerStop() + s.ctx.Spinner() + defer s.ctx.SpinnerStop() out, err := exec.Command("img", buildarg...).CombinedOutput() if err != nil { return errors.Wrap(err, "Failed removing image: "+string(out)) } - Info(":tea: Image " + name + " removed") + s.ctx.Info(":tea: Image " + name + " removed") return nil } -func (*SimpleImg) DownloadImage(opts Options) error { +func (s *SimpleImg) DownloadImage(opts Options) error { name := opts.ImageName bus.Manager.Publish(bus.EventImagePrePull, opts) buildarg := []string{"pull", name} - Debug(":tea: Downloading image " + name) + s.ctx.Debug(":tea: Downloading image " + name) - Spinner(22) - defer SpinnerStop() + s.ctx.Spinner() + defer s.ctx.SpinnerStop() cmd := exec.Command("img", buildarg...) out, err := cmd.CombinedOutput() @@ -85,27 +86,27 @@ func (*SimpleImg) DownloadImage(opts Options) error { return errors.Wrap(err, "Failed downloading image: "+string(out)) } - Info(":tea: Image " + name + " downloaded") + s.ctx.Info(":tea: Image " + name + " downloaded") bus.Manager.Publish(bus.EventImagePostPull, opts) return nil } -func (*SimpleImg) CopyImage(src, dst string) error { - Spinner(22) - defer SpinnerStop() +func (s *SimpleImg) CopyImage(src, dst string) error { + s.ctx.Spinner() + defer s.ctx.SpinnerStop() - Debug(":tea: Tagging image", src, dst) + s.ctx.Debug(":tea: Tagging image", src, dst) cmd := exec.Command("img", "tag", src, dst) out, err := cmd.CombinedOutput() if err != nil { return errors.Wrap(err, "Failed tagging image: "+string(out)) } - Info(":tea: Image " + dst + " tagged") + s.ctx.Info(":tea: Image " + dst + " tagged") return nil } -func (*SimpleImg) ImageAvailable(imagename string) bool { +func (s *SimpleImg) ImageAvailable(imagename string) bool { return imageAvailable(imagename) } @@ -135,20 +136,20 @@ func (s *SimpleImg) ImageDefinitionToTar(opts Options) error { return nil } -func (*SimpleImg) ExportImage(opts Options) error { +func (s *SimpleImg) ExportImage(opts Options) error { name := opts.ImageName path := opts.Destination buildarg := []string{"save", "-o", path, name} - Debug(":tea: Saving image " + name) + s.ctx.Debug(":tea: Saving image " + name) - Spinner(22) - defer SpinnerStop() + s.ctx.Spinner() + defer s.ctx.SpinnerStop() out, err := exec.Command("img", buildarg...).CombinedOutput() if err != nil { return errors.Wrap(err, "Failed exporting image: "+string(out)) } - Info(":tea: Image " + name + " saved") + s.ctx.Info(":tea: Image " + name + " saved") return nil } @@ -166,20 +167,20 @@ func (s *SimpleImg) ExtractRootfs(opts Options, keepPerms bool) error { os.RemoveAll(path) buildarg := []string{"unpack", "-o", path, name} - Debug(":tea: Extracting image " + name) + s.ctx.Debug(":tea: Extracting image " + name) - Spinner(22) - defer SpinnerStop() + s.ctx.Spinner() + defer s.ctx.SpinnerStop() out, err := exec.Command("img", buildarg...).CombinedOutput() if err != nil { return errors.Wrap(err, "Failed extracting image: "+string(out)) } - Debug(":tea: Image " + name + " extracted") + s.ctx.Debug(":tea: Image " + name + " extracted") return nil } -func (*SimpleImg) Push(opts Options) error { +func (s *SimpleImg) Push(opts Options) error { name := opts.ImageName bus.Manager.Publish(bus.EventImagePrePush, opts) @@ -188,9 +189,9 @@ func (*SimpleImg) Push(opts Options) error { if err != nil { return errors.Wrap(err, "Failed pushing image: "+string(out)) } - Info(":tea: Pushed image:", name) + s.ctx.Info(":tea: Pushed image:", name) bus.Manager.Publish(bus.EventImagePostPush, opts) - //Info(string(out)) + //s.ctx.Info(string(out)) return nil } diff --git a/pkg/compiler/backend/writer.go b/pkg/compiler/backend/writer.go index db30a1b5..65196193 100644 --- a/pkg/compiler/backend/writer.go +++ b/pkg/compiler/backend/writer.go @@ -19,18 +19,20 @@ package backend import ( "bytes" - . "github.com/mudler/luet/pkg/logger" + "github.com/mudler/luet/pkg/api/core/types" ) type BackendWriter struct { BufferedOutput bool Buffer *bytes.Buffer + ctx *types.Context } -func NewBackendWriter(buffered bool) *BackendWriter { +func NewBackendWriter(buffered bool, ctx *types.Context) *BackendWriter { return &BackendWriter{ BufferedOutput: buffered, Buffer: &bytes.Buffer{}, + ctx: ctx, } } @@ -39,7 +41,7 @@ func (b *BackendWriter) Write(p []byte) (int, error) { return b.Buffer.Write(p) } - Msg("info", false, false, (string(p))) + b.ctx.Msg("info", false, (string(p))) return len(p), nil } diff --git a/pkg/compiler/backend_test.go b/pkg/compiler/backend_test.go index 768d452e..6aa7768f 100644 --- a/pkg/compiler/backend_test.go +++ b/pkg/compiler/backend_test.go @@ -16,6 +16,7 @@ package compiler_test import ( + "github.com/mudler/luet/pkg/api/core/types" . "github.com/mudler/luet/pkg/compiler" . "github.com/mudler/luet/pkg/compiler/backend" @@ -25,9 +26,9 @@ import ( var _ = Describe("Docker image diffs", func() { var b CompilerBackend - + ctx := types.NewContext() BeforeEach(func() { - b = NewSimpleDockerBackend() + b = NewSimpleDockerBackend(ctx) }) Context("Generate diffs from docker images", func() { @@ -38,7 +39,7 @@ var _ = Describe("Docker image diffs", func() { err := b.DownloadImage(opts) Expect(err).ToNot(HaveOccurred()) - layers, err := GenerateChanges(b, opts, opts) + layers, err := GenerateChanges(ctx, b, opts, opts) Expect(err).ToNot(HaveOccurred()) Expect(len(layers)).To(Equal(1)) Expect(len(layers[0].Diffs.Additions)).To(Equal(0)) @@ -56,7 +57,7 @@ var _ = Describe("Docker image diffs", func() { }) Expect(err).ToNot(HaveOccurred()) - layers, err := GenerateChanges(b, Options{ + layers, err := GenerateChanges(ctx, b, Options{ ImageName: "quay.io/mocaccino/micro", }, Options{ ImageName: "quay.io/mocaccino/extra", diff --git a/pkg/compiler/compiler.go b/pkg/compiler/compiler.go index 9540d92a..f4df7efe 100644 --- a/pkg/compiler/compiler.go +++ b/pkg/compiler/compiler.go @@ -29,6 +29,7 @@ import ( "sync" "time" + "github.com/mudler/luet/pkg/api/core/types" artifact "github.com/mudler/luet/pkg/api/core/types/artifact" bus "github.com/mudler/luet/pkg/bus" "github.com/mudler/luet/pkg/compiler/backend" @@ -36,7 +37,6 @@ import ( compilerspec "github.com/mudler/luet/pkg/compiler/types/spec" "github.com/mudler/luet/pkg/helpers" fileHelper "github.com/mudler/luet/pkg/helpers/file" - . "github.com/mudler/luet/pkg/logger" pkg "github.com/mudler/luet/pkg/package" "github.com/mudler/luet/pkg/solver" @@ -80,12 +80,12 @@ func NewLuetCompiler(backend CompilerBackend, db pkg.PackageDatabase, compilerOp // The CompilerRecipe will gives us a tree with only build deps listed. c := NewCompiler(compilerOpts...) + if c.Options.Context == nil { + c.Options.Context = types.NewContext() + } // c.Options.BackendType c.Backend = backend c.Database = db - // c.CompilerRecipe = &tree.CompilerRecipe{ - // Recipe: tree.Recipe{Database: db}, - // } return c } @@ -112,7 +112,7 @@ func (cs *LuetCompiler) CompileWithReverseDeps(keepPermissions bool, ps *compile return artifacts, err } - Info(":ant: Resolving reverse dependencies") + cs.Options.Context.Info(":ant: Resolving reverse dependencies") toCompile := compilerspec.NewLuetCompilationspecs() for _, a := range artifacts { @@ -130,7 +130,7 @@ func (cs *LuetCompiler) CompileWithReverseDeps(keepPermissions bool, ps *compile uniques := toCompile.Unique().Remove(ps) for _, u := range uniques.All() { - Info(" :arrow_right_hook:", u.GetPackage().GetName(), ":leaves:", u.GetPackage().GetVersion(), "(", u.GetPackage().GetCategory(), ")") + cs.Options.Context.Info(" :arrow_right_hook:", u.GetPackage().GetName(), ":leaves:", u.GetPackage().GetVersion(), "(", u.GetPackage().GetCategory(), ")") } artifacts2, err := cs.CompileParallel(keepPermissions, uniques) @@ -202,9 +202,9 @@ func (cs *LuetCompiler) stripFromRootfs(includes []string, rootfs string, includ if include && !match || !include && match { toRemove = append(toRemove, currentpath) - Debug(":scissors: Removing file", currentpath) + cs.Options.Context.Debug(":scissors: Removing file", currentpath) } else { - Debug(":sun: Matched file", currentpath) + cs.Options.Context.Debug(":sun: Matched file", currentpath) } return nil @@ -218,7 +218,7 @@ func (cs *LuetCompiler) stripFromRootfs(includes []string, rootfs string, includ for _, s := range toRemove { e := os.RemoveAll(s) if e != nil { - Warning("Failed removing", s, e.Error()) + cs.Options.Context.Warning("Failed removing", s, e.Error()) return e } } @@ -240,7 +240,7 @@ func (cs *LuetCompiler) unpackFs(concurrency int, keepPermissions bool, p *compi } if p.GetPackageDir() != "" { - Info(":tophat: Packing from output dir", p.GetPackageDir()) + cs.Options.Context.Info(":tophat: Packing from output dir", p.GetPackageDir()) rootfs = filepath.Join(rootfs, p.GetPackageDir()) } @@ -279,18 +279,18 @@ func (cs *LuetCompiler) unpackDelta(concurrency int, keepPermissions bool, p *co } } - Info(pkgTag, ":hammer: Generating delta") - diffs, err := GenerateChanges(cs.Backend, builderOpts, runnerOpts) + cs.Options.Context.Info(pkgTag, ":hammer: Generating delta") + diffs, err := GenerateChanges(cs.Options.Context, 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") + cs.Options.Context.Debug("Extracting image to grab files from delta") 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 := artifact.ExtractArtifactFromDelta(rootfs, p.Rel(p.GetPackage().GetFingerPrint()+".package.tar"), diffs, concurrency, keepPermissions, p.GetIncludes(), p.GetExcludes(), cs.Options.CompressionType) + artifact, err := artifact.ExtractArtifactFromDelta(cs.Options.Context, 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") } @@ -335,7 +335,7 @@ func (cs *LuetCompiler) buildPackageImage(image, buildertaggedImage, packageImag if len(p.GetRetrieve()) > 0 { err := p.CopyRetrieves(buildDir) if err != nil { - Warning("Failed copying retrieves", err.Error()) + cs.Options.Context.Warning("Failed copying retrieves", err.Error()) } } @@ -381,8 +381,8 @@ func (cs *LuetCompiler) buildPackageImage(image, buildertaggedImage, packageImag if err == nil { buildImage = false } else { - Warning("Failed to download '" + opts.ImageName + "'. Will keep going and build the image unless you use --fatal") - Warning(err.Error()) + cs.Options.Context.Warning("Failed to download '" + opts.ImageName + "'. Will keep going and build the image unless you use --fatal") + cs.Options.Context.Warning(err.Error()) } } if buildImage { @@ -399,7 +399,7 @@ func (cs *LuetCompiler) buildPackageImage(image, buildertaggedImage, packageImag } // SKIPBUILD // if len(p.GetPreBuildSteps()) != 0 { - Info(pkgTag, ":whale: Generating 'builder' image from", image, "as", buildertaggedImage, "with prelude steps") + cs.Options.Context.Info(pkgTag, ":whale: Generating 'builder' image from", image, "as", buildertaggedImage, "with prelude steps") if err := buildAndPush(builderOpts); err != nil { return builderOpts, runnerOpts, errors.Wrapf(err, "Could not push image: %s %s", image, builderOpts.DockerFileName) } @@ -407,7 +407,7 @@ func (cs *LuetCompiler) buildPackageImage(image, buildertaggedImage, packageImag // Even if we might not have any steps to build, we do that so we can tag the image used in this moment and use that to cache it in a registry, or in the system. // acting as a docker tag. - Info(pkgTag, ":whale: Generating 'package' image from", buildertaggedImage, "as", packageImage, "with build steps") + cs.Options.Context.Info(pkgTag, ":whale: Generating 'package' image from", buildertaggedImage, "as", packageImage, "with build steps") if err := buildAndPush(runnerOpts); err != nil { return builderOpts, runnerOpts, errors.Wrapf(err, "Could not push image: %s %s", image, runnerOpts.DockerFileName) } @@ -422,7 +422,7 @@ func (cs *LuetCompiler) genArtifact(p *compilerspec.LuetCompilationSpec, builder var rootfs string var err error pkgTag := ":package: " + p.GetPackage().HumanReadableString() - Debug(pkgTag, "Generating artifact") + cs.Options.Context.Debug(pkgTag, "Generating artifact") // We can't generate delta in this case. It implies the package is a virtual, and nothing has to be done really if p.EmptyPackage() { fakePackage := p.Rel(p.GetPackage().GetFingerPrint() + ".package.tar") @@ -447,7 +447,7 @@ func (cs *LuetCompiler) genArtifact(p *compilerspec.LuetCompilationSpec, builder if err != nil { return a, errors.Wrap(err, "Failed while writing metadata file") } - Info(pkgTag, " :white_check_mark: done (empty virtual package)") + cs.Options.Context.Info(pkgTag, " :white_check_mark: done (empty virtual package)") return a, nil } @@ -477,7 +477,7 @@ func (cs *LuetCompiler) genArtifact(p *compilerspec.LuetCompilationSpec, builder if err != nil { return a, errors.Wrap(err, "Failed while writing metadata file") } - Info(pkgTag, " :white_check_mark: Done") + cs.Options.Context.Info(pkgTag, " :white_check_mark: Done") return a, nil } @@ -486,12 +486,12 @@ func (cs *LuetCompiler) waitForImages(images []string) { if cs.Options.PullFirst && cs.Options.Wait { available, _ := oneOfImagesAvailable(images, cs.Backend) if !available { - Info(fmt.Sprintf("Waiting for image %s to be available... :zzz:", images)) - Spinner(32) - defer SpinnerStop() + cs.Options.Context.Info(fmt.Sprintf("Waiting for image %s to be available... :zzz:", images)) + cs.Options.Context.Spinner() + defer cs.Options.Context.SpinnerStop() for !available { available, _ = oneOfImagesAvailable(images, cs.Backend) - Info(fmt.Sprintf("Image %s not available yet, sleeping", images)) + cs.Options.Context.Info(fmt.Sprintf("Image %s not available yet, sleeping", images)) time.Sleep(5 * time.Second) } } @@ -517,7 +517,7 @@ func oneOfImagesAvailable(images []string, b CompilerBackend) (bool, string) { func (cs *LuetCompiler) findImageHash(imageHash string, p *compilerspec.LuetCompilationSpec) string { var resolvedImage string - Debug("Resolving image hash for", p.Package.HumanReadableString(), "hash", imageHash, "Pull repositories", p.BuildOptions.PullImageRepository) + cs.Options.Context.Debug("Resolving image hash for", p.Package.HumanReadableString(), "hash", imageHash, "Pull repositories", p.BuildOptions.PullImageRepository) toChecklist := append([]string{fmt.Sprintf("%s:%s", cs.Options.PushImageRepository, imageHash)}, genImageList(p.BuildOptions.PullImageRepository, imageHash)...) if exists, which := oneOfImagesExists(toChecklist, cs.Backend); exists { @@ -558,20 +558,20 @@ func LoadArtifactFromYaml(spec *compilerspec.LuetCompilationSpec) (*artifact.Pac 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. - Debug("Get image artifact for", p.Package.HumanReadableString(), "hash", hash, "Pull repositories", p.BuildOptions.PullImageRepository) + cs.Options.Context.Debug("Get image artifact for", p.Package.HumanReadableString(), "hash", hash, "Pull repositories", p.BuildOptions.PullImageRepository) toChecklist := append([]string{fmt.Sprintf("%s:%s", cs.Options.PushImageRepository, hash)}, genImageList(p.BuildOptions.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("Package reloaded from YAML. Skipping build") + cs.Options.Context.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") + cs.Options.Context.Debug("Image available, returning empty artifact") return &artifact.PackageArtifact{}, nil } @@ -610,17 +610,17 @@ func (cs *LuetCompiler) compileWithImage(image, builderHash string, packageTagHa // if buildertaggedImage == "" { // buildertaggedImage = fmt.Sprintf("%s:%s", cs.Options.PushImageRepository, buildertaggedImage) // generated = true - // // Debug(pkgTag, "Creating intermediary image", buildertaggedImage, "from", image) + // // cs.Options.Context.Debug(pkgTag, "Creating intermediary image", buildertaggedImage, "from", image) // } if cs.Options.PullFirst && !cs.Options.Rebuild { - Debug("Checking if an image is already available") + cs.Options.Context.Debug("Checking if an image is already available") // FIXUP here. If packageimage hash exists and pull is true, generate package resolved := cs.resolveExistingImageHash(packageTagHash, p) - Debug("Resolved: " + resolved) - Debug("Expected remote: " + resolved) - Debug("Package image: " + packageImage) - Debug("Resolved builder image: " + builderResolved) + cs.Options.Context.Debug("Resolved: " + resolved) + cs.Options.Context.Debug("Expected remote: " + resolved) + cs.Options.Context.Debug("Package image: " + packageImage) + cs.Options.Context.Debug("Resolved builder image: " + builderResolved) // a remote image is there already remoteImageAvailable := resolved != packageImage && remoteBuildertaggedImage != builderResolved @@ -629,13 +629,13 @@ func (cs *LuetCompiler) compileWithImage(image, builderHash string, packageTagHa switch { case remoteImageAvailable: - Debug("Images available remotely for", p.Package.HumanReadableString(), "generating artifact from remote images:", resolved) + cs.Options.Context.Debug("Images available remotely for", p.Package.HumanReadableString(), "generating artifact from remote images:", resolved) return cs.genArtifact(p, backend.Options{ImageName: builderResolved}, backend.Options{ImageName: resolved}, concurrency, keepPermissions) case localImageAvailable: - Debug("Images locally available for", p.Package.HumanReadableString(), "generating artifact from image:", resolved) + cs.Options.Context.Debug("Images locally available for", p.Package.HumanReadableString(), "generating artifact from image:", resolved) return cs.genArtifact(p, backend.Options{ImageName: remoteBuildertaggedImage}, backend.Options{ImageName: packageImage}, concurrency, keepPermissions) default: - Debug("Images not available for", p.Package.HumanReadableString()) + cs.Options.Context.Debug("Images not available for", p.Package.HumanReadableString()) } } @@ -649,10 +649,10 @@ func (cs *LuetCompiler) compileWithImage(image, builderHash string, packageTagHa defer func() { // We keep them around, so to not reload them from the tar (which should be the "correct way") and we automatically share the same layers if err := cs.Backend.RemoveImage(builderOpts); err != nil { - Warning("Could not remove image ", builderOpts.ImageName) + cs.Options.Context.Warning("Could not remove image ", builderOpts.ImageName) } if err := cs.Backend.RemoveImage(runnerOpts); err != nil { - Warning("Could not remove image ", runnerOpts.ImageName) + cs.Options.Context.Warning("Could not remove image ", runnerOpts.ImageName) } }() } @@ -787,22 +787,22 @@ func genImageList(refs []string, hash string) []string { } func (cs *LuetCompiler) inheritSpecBuildOptions(p *compilerspec.LuetCompilationSpec) { - Debug(p.GetPackage().HumanReadableString(), "Build options before inherit", p.BuildOptions) + cs.Options.Context.Debug(p.GetPackage().HumanReadableString(), "Build options before inherit", p.BuildOptions) // Append push repositories from buildpsec buildoptions as pull if found. // This allows to resolve the hash automatically if we pulled the metadata from // repositories that are advertizing their cache. if len(p.BuildOptions.PushImageRepository) != 0 { p.BuildOptions.PullImageRepository = append(p.BuildOptions.PullImageRepository, p.BuildOptions.PushImageRepository) - Debug("Inheriting pull repository from PushImageRepository buildoptions", p.BuildOptions.PullImageRepository) + cs.Options.Context.Debug("Inheriting pull repository from PushImageRepository buildoptions", p.BuildOptions.PullImageRepository) } if len(cs.Options.PullImageRepository) != 0 { p.BuildOptions.PullImageRepository = append(p.BuildOptions.PullImageRepository, cs.Options.PullImageRepository...) - Debug("Inheriting pull repository from PullImageRepository buildoptions", p.BuildOptions.PullImageRepository) + cs.Options.Context.Debug("Inheriting pull repository from PullImageRepository buildoptions", p.BuildOptions.PullImageRepository) } - Debug(p.GetPackage().HumanReadableString(), "Build options after inherit", p.BuildOptions) + cs.Options.Context.Debug(p.GetPackage().HumanReadableString(), "Build options after inherit", p.BuildOptions) } func (cs *LuetCompiler) getSpecHash(pkgs pkg.DefaultPackages, salt string) (string, error) { @@ -831,7 +831,7 @@ func (cs *LuetCompiler) resolveFinalImages(concurrency int, keepPermissions bool var fromPackages pkg.DefaultPackages if p.RequiresFinalImages { - Info(joinTag, "Generating a parent image from final packages") + cs.Options.Context.Info(joinTag, "Generating a parent image from final packages") fromPackages = p.Package.GetRequires() } else { // No source image to resolve @@ -844,15 +844,15 @@ func (cs *LuetCompiler) resolveFinalImages(concurrency int, keepPermissions bool return errors.Wrap(err, "could not generate image hash") } - Info(joinTag, "Searching existing image with hash", overallFp) + cs.Options.Context.Info(joinTag, "Searching existing image with hash", overallFp) image := cs.findImageHash(overallFp, p) if image != "" { - Info("Image already found", image) + cs.Options.Context.Info("Image already found", image) p.SetImage(image) return nil } - Info(joinTag, "Image not found. Generating image join with hash ", overallFp) + cs.Options.Context.Info(joinTag, "Image not found. Generating image join with hash ", overallFp) // Make sure there is an output path if err := os.MkdirAll(p.GetOutputPath(), os.ModePerm); err != nil { @@ -867,7 +867,7 @@ func (cs *LuetCompiler) resolveFinalImages(concurrency int, keepPermissions bool defer os.RemoveAll(joinDir) // clean up for _, p := range fromPackages { - Info(joinTag, ":arrow_right_hook:", p.HumanReadableString(), ":leaves:") + cs.Options.Context.Info(joinTag, ":arrow_right_hook:", p.HumanReadableString(), ":leaves:") } current := 0 @@ -876,7 +876,7 @@ func (cs *LuetCompiler) resolveFinalImages(concurrency int, keepPermissions bool if c != nil && c.Name != "" && c.Version != "" { joinTag2 := fmt.Sprintf("%s %d/%d ⤑ :hammer: build %s", joinTag, current, len(p.Package.GetRequires()), c.HumanReadableString()) - Info(joinTag2, "compilation starts") + cs.Options.Context.Info(joinTag2, "compilation starts") spec, err := cs.FromPackage(c) if err != nil { return errors.Wrap(err, "while generating images to join from") @@ -891,11 +891,11 @@ func (cs *LuetCompiler) resolveFinalImages(concurrency int, keepPermissions bool return errors.Wrap(err, "failed building join image") } - err = artifact.Unpack(joinDir, keepPermissions) + err = artifact.Unpack(cs.Options.Context, joinDir, keepPermissions) if err != nil { return errors.Wrap(err, "failed building join image") } - Info(joinTag2, ":white_check_mark: Done") + cs.Options.Context.Info(joinTag2, ":white_check_mark: Done") } } @@ -905,7 +905,7 @@ func (cs *LuetCompiler) resolveFinalImages(concurrency int, keepPermissions bool } defer os.RemoveAll(joinDir) // clean up - Info(joinTag, ":droplet: generating artifact for source image of", p.GetPackage().HumanReadableString()) + cs.Options.Context.Info(joinTag, ":droplet: generating artifact for source image of", p.GetPackage().HumanReadableString()) // After unpack, create a new artifact and a new final image from it. // no need to compress, as we are going to toss it away. @@ -915,18 +915,18 @@ func (cs *LuetCompiler) resolveFinalImages(concurrency int, keepPermissions bool } joinImageName := fmt.Sprintf("%s:%s", cs.Options.PushImageRepository, overallFp) - Info(joinTag, ":droplet: generating image from artifact", joinImageName) - opts, err := a.GenerateFinalImage(joinImageName, cs.Backend, keepPermissions) + cs.Options.Context.Info(joinTag, ":droplet: generating image from artifact", joinImageName) + opts, err := a.GenerateFinalImage(cs.Options.Context, joinImageName, cs.Backend, keepPermissions) if err != nil { return errors.Wrap(err, "could not create final image") } if cs.Options.Push { - Info(joinTag, ":droplet: pushing image from artifact", joinImageName) + cs.Options.Context.Info(joinTag, ":droplet: pushing image from artifact", joinImageName) if err = cs.Backend.Push(opts); err != nil { return errors.Wrapf(err, "Could not push image: %s %s", image, opts.DockerFileName) } } - Info(joinTag, ":droplet: Consuming image", joinImageName) + cs.Options.Context.Info(joinTag, ":droplet: Consuming image", joinImageName) p.SetImage(joinImageName) return nil } @@ -936,7 +936,7 @@ func (cs *LuetCompiler) resolveMultiStageImages(concurrency int, keepPermissions copyTag := ">:droplet: copy<" if len(p.Copy) != 0 { - Info(copyTag, "Package has multi-stage copy, generating required images") + cs.Options.Context.Info(copyTag, "Package has multi-stage copy, generating required images") } current := 0 @@ -946,7 +946,7 @@ func (cs *LuetCompiler) resolveMultiStageImages(concurrency int, keepPermissions if c.Package != nil && c.Package.Name != "" && c.Package.Version != "" { copyTag2 := fmt.Sprintf("%s %d/%d ⤑ :hammer: build %s", copyTag, current, len(p.Copy), c.Package.HumanReadableString()) - Info(copyTag2, "generating multi-stage images for", c.Package.HumanReadableString()) + cs.Options.Context.Info(copyTag2, "generating multi-stage images for", c.Package.HumanReadableString()) spec, err := cs.FromPackage(c.Package) if err != nil { return errors.Wrap(err, "while generating images to copy from") @@ -965,7 +965,7 @@ func (cs *LuetCompiler) resolveMultiStageImages(concurrency int, keepPermissions Source: c.Source, Destination: c.Destination, }) - Info(copyTag2, ":white_check_mark: Done") + cs.Options.Context.Info(copyTag2, ":white_check_mark: Done") } else { resolvedCopyFields = append(resolvedCopyFields, c) } @@ -975,7 +975,7 @@ func (cs *LuetCompiler) resolveMultiStageImages(concurrency int, keepPermissions } func (cs *LuetCompiler) compile(concurrency int, keepPermissions bool, generateFinalArtifact *bool, generateDependenciesFinalArtifact *bool, p *compilerspec.LuetCompilationSpec) (*artifact.PackageArtifact, error) { - Info(":package: Compiling", p.GetPackage().HumanReadableString(), ".... :coffee:") + cs.Options.Context.Info(":package: Compiling", p.GetPackage().HumanReadableString(), ".... :coffee:") //Before multistage : join - same as multistage, but keep artifacts, join them, create a new one and generate a final image. // When the image is there, use it as a source here, in place of GetImage(). @@ -987,7 +987,7 @@ func (cs *LuetCompiler) compile(concurrency int, keepPermissions bool, generateF return nil, errors.Wrap(err, "while resolving multi-stage images") } - Debug(fmt.Sprintf("%s: has images %t, empty package: %t", p.GetPackage().HumanReadableString(), p.HasImageSource(), p.EmptyPackage())) + cs.Options.Context.Debug(fmt.Sprintf("%s: has images %t, empty package: %t", p.GetPackage().HumanReadableString(), p.HasImageSource(), p.EmptyPackage())) if !p.HasImageSource() && !p.EmptyPackage() { return nil, fmt.Errorf( @@ -1056,22 +1056,22 @@ func (cs *LuetCompiler) compile(concurrency int, keepPermissions bool, generateF buildTarget := !cs.Options.OnlyDeps if buildDeps { - Info(":deciduous_tree: Build dependencies for " + p.GetPackage().HumanReadableString()) + cs.Options.Context.Info(":deciduous_tree: Build dependencies for " + p.GetPackage().HumanReadableString()) for _, assertion := range dependencies { //highly dependent on the order depsN++ - Info(" :arrow_right_hook:", assertion.Package.HumanReadableString(), ":leaves:") + cs.Options.Context.Info(" :arrow_right_hook:", assertion.Package.HumanReadableString(), ":leaves:") } for _, assertion := range dependencies { //highly dependent on the order currentN++ pkgTag := fmt.Sprintf(":package: %d/%d %s ⤑ :hammer: build %s", currentN, depsN, p.GetPackage().HumanReadableString(), assertion.Package.HumanReadableString()) - Info(pkgTag, " starts") + cs.Options.Context.Info(pkgTag, " starts") compileSpec, err := cs.FromPackage(assertion.Package) if err != nil { return nil, errors.Wrap(err, "Error while generating compilespec for "+assertion.Package.GetName()) } compileSpec.BuildOptions.PullImageRepository = append(compileSpec.BuildOptions.PullImageRepository, p.BuildOptions.PullImageRepository...) - Debug("PullImage repos:", compileSpec.BuildOptions.PullImageRepository) + cs.Options.Context.Debug("PullImage repos:", compileSpec.BuildOptions.PullImageRepository) compileSpec.SetOutputPath(p.GetOutputPath()) @@ -1096,20 +1096,20 @@ func (cs *LuetCompiler) compile(concurrency int, keepPermissions bool, generateF return nil, errors.Wrap(err, "failed looking for dependency in hashtree") } - Debug(pkgTag, " :arrow_right_hook: :whale: Builder image from hash", assertion.Hash.BuildHash) - Debug(pkgTag, " :arrow_right_hook: :whale: Package image from hash", assertion.Hash.PackageHash) + cs.Options.Context.Debug(pkgTag, " :arrow_right_hook: :whale: Builder image from hash", assertion.Hash.BuildHash) + cs.Options.Context.Debug(pkgTag, " :arrow_right_hook: :whale: Package image from hash", assertion.Hash.PackageHash) var sourceImage string if compileSpec.GetImage() != "" { - Debug(pkgTag, " :wrench: Compiling "+compileSpec.GetPackage().HumanReadableString()+" from image") + cs.Options.Context.Debug(pkgTag, " :wrench: Compiling "+compileSpec.GetPackage().HumanReadableString()+" from image") sourceImage = compileSpec.GetImage() } else { // for the source instead, pick an image and a buildertaggedImage from hashes if they exists. // otherways fallback to the pushed repo // Resolve images from the hashtree sourceImage = cs.resolveExistingImageHash(assertion.Hash.BuildHash, compileSpec) - Debug(pkgTag, " :wrench: Compiling "+compileSpec.GetPackage().HumanReadableString()+" from tree") + cs.Options.Context.Debug(pkgTag, " :wrench: Compiling "+compileSpec.GetPackage().HumanReadableString()+" from tree") } a, err := cs.compileWithImage( @@ -1128,7 +1128,7 @@ func (cs *LuetCompiler) compile(concurrency int, keepPermissions bool, generateF a.PackageCacheImage = assertion.Hash.PackageHash - Info(pkgTag, ":white_check_mark: Done") + cs.Options.Context.Info(pkgTag, ":white_check_mark: Done") bus.Manager.Publish(bus.EventPackagePostBuild, struct { CompileSpec *compilerspec.LuetCompilationSpec @@ -1148,8 +1148,8 @@ func (cs *LuetCompiler) compile(concurrency int, keepPermissions bool, generateF localGenerateArtifact = *generateFinalArtifact } resolvedSourceImage := cs.resolveExistingImageHash(packageHashTree.SourceHash, p) - Info(":rocket: All dependencies are satisfied, building package requested by the user", p.GetPackage().HumanReadableString()) - Info(":package:", p.GetPackage().HumanReadableString(), " Using image: ", resolvedSourceImage) + cs.Options.Context.Info(":rocket: All dependencies are satisfied, building package requested by the user", p.GetPackage().HumanReadableString()) + cs.Options.Context.Info(":package:", p.GetPackage().HumanReadableString(), " Using image: ", resolvedSourceImage) a, err := cs.compileWithImage(resolvedSourceImage, packageHashTree.BuilderImageHash, targetAssertion.Hash.PackageHash, concurrency, keepPermissions, cs.Options.KeepImg, p, localGenerateArtifact) if err != nil { return a, err @@ -1271,7 +1271,7 @@ func (cs *LuetCompiler) FromPackage(p pkg.Package) (*compilerspec.LuetCompilatio opts := options.Compiler{} artifactMetadataFile := filepath.Join(pack.GetTreeDir(), "..", pack.GetMetadataFilePath()) - Debug("Checking if metadata file is present", artifactMetadataFile) + cs.Options.Context.Debug("Checking if metadata file is present", artifactMetadataFile) if _, err := os.Stat(artifactMetadataFile); err == nil { f, err := os.Open(artifactMetadataFile) if err != nil { @@ -1286,14 +1286,14 @@ func (cs *LuetCompiler) FromPackage(p pkg.Package) (*compilerspec.LuetCompilatio return nil, errors.Wrap(err, "could not decode package from yaml") } - Debug("Read build options:", art.CompileSpec.BuildOptions, "from", artifactMetadataFile) + cs.Options.Context.Debug("Read build options:", art.CompileSpec.BuildOptions, "from", artifactMetadataFile) if art.CompileSpec.BuildOptions != nil { opts = *art.CompileSpec.BuildOptions } } else if !os.IsNotExist(err) { - Debug("error reading artifact metadata file: ", err.Error()) + cs.Options.Context.Debug("error reading artifact metadata file: ", err.Error()) } else if os.IsNotExist(err) { - Debug("metadata file not present, skipping", artifactMetadataFile) + cs.Options.Context.Debug("metadata file not present, skipping", artifactMetadataFile) } // Update processed build values diff --git a/pkg/compiler/compiler_suite_test.go b/pkg/compiler/compiler_suite_test.go index 59978f3f..242f57fd 100644 --- a/pkg/compiler/compiler_suite_test.go +++ b/pkg/compiler/compiler_suite_test.go @@ -18,14 +18,11 @@ package compiler_test import ( "testing" - . "github.com/mudler/luet/cmd/util" - . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) func TestSolver(t *testing.T) { RegisterFailHandler(Fail) - LoadConfig() RunSpecs(t, "Compiler Suite") } diff --git a/pkg/compiler/compiler_test.go b/pkg/compiler/compiler_test.go index 6bfb99c7..48f5399a 100644 --- a/pkg/compiler/compiler_test.go +++ b/pkg/compiler/compiler_test.go @@ -19,6 +19,7 @@ import ( "io/ioutil" "os" + "github.com/mudler/luet/pkg/api/core/types" . "github.com/mudler/luet/pkg/compiler" sd "github.com/mudler/luet/pkg/compiler/backend" "github.com/mudler/luet/pkg/compiler/types/compression" @@ -33,6 +34,8 @@ import ( ) var _ = Describe("Compiler", func() { + ctx := types.NewContext() + Context("Simple package build definition", func() { It("Compiles it correctly", func() { generalRecipe := tree.NewCompilerRecipe(pkg.NewInMemoryDatabase(false)) @@ -42,7 +45,7 @@ var _ = Describe("Compiler", func() { Expect(len(generalRecipe.GetDatabase().GetPackages())).To(Equal(3)) - compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(), generalRecipe.GetDatabase(), options.Concurrency(2)) + compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(ctx), generalRecipe.GetDatabase(), options.Concurrency(2), options.WithContext(types.NewContext())) spec, err := compiler.FromPackage(&pkg.DefaultPackage{Name: "b", Category: "test", Version: "1.0"}) Expect(err).ToNot(HaveOccurred()) @@ -85,7 +88,7 @@ var _ = Describe("Compiler", func() { Expect(len(generalRecipe.GetDatabase().GetPackages())).To(Equal(3)) - compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(), generalRecipe.GetDatabase(), options.Concurrency(2)) + compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(ctx), generalRecipe.GetDatabase(), options.Concurrency(2), options.WithContext(types.NewContext())) spec, err := compiler.FromPackage(&pkg.DefaultPackage{Name: "c", Category: "test", Version: "1.2"}) Expect(err).ToNot(HaveOccurred()) @@ -115,7 +118,7 @@ var _ = Describe("Compiler", func() { Expect(len(generalRecipe.GetDatabase().GetPackages())).To(Equal(3)) - compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(), generalRecipe.GetDatabase(), options.Concurrency(2)) + compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(ctx), generalRecipe.GetDatabase(), options.Concurrency(2), options.WithContext(types.NewContext())) spec, err := compiler.FromPackage(&pkg.DefaultPackage{Name: "c", Category: "test", Version: "1.2"}) Expect(err).ToNot(HaveOccurred()) @@ -147,7 +150,7 @@ var _ = Describe("Compiler", func() { Expect(len(generalRecipe.GetDatabase().GetPackages())).To(Equal(3)) - compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(), generalRecipe.GetDatabase(), options.Concurrency(1)) + compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(ctx), generalRecipe.GetDatabase(), options.Concurrency(1), options.WithContext(types.NewContext())) spec, err := compiler.FromPackage(&pkg.DefaultPackage{Name: "b", Category: "test", Version: "1.0"}) Expect(err).ToNot(HaveOccurred()) @@ -181,7 +184,7 @@ var _ = Describe("Compiler", func() { err = generalRecipe.Load("../../tests/fixtures/templates") Expect(err).ToNot(HaveOccurred()) - compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(), generalRecipe.GetDatabase()) + compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(ctx), generalRecipe.GetDatabase(), options.WithContext(types.NewContext())) Expect(len(generalRecipe.GetDatabase().GetPackages())).To(Equal(1)) pkg, err := generalRecipe.GetDatabase().FindPackage(&pkg.DefaultPackage{Name: "b", Category: "test", Version: "1.0"}) @@ -205,7 +208,7 @@ var _ = Describe("Compiler", func() { Expect(len(generalRecipe.GetDatabase().GetPackages())).To(Equal(4)) - compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(), generalRecipe.GetDatabase(), options.Concurrency(2)) + compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(ctx), generalRecipe.GetDatabase(), options.Concurrency(2), options.WithContext(types.NewContext())) spec, err := compiler.FromPackage(&pkg.DefaultPackage{Name: "c", Category: "test", Version: "1.0"}) Expect(err).ToNot(HaveOccurred()) @@ -261,7 +264,7 @@ var _ = Describe("Compiler", func() { Expect(len(generalRecipe.GetDatabase().GetPackages())).To(Equal(2)) - compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(), generalRecipe.GetDatabase(), options.Concurrency(1)) + compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(ctx), generalRecipe.GetDatabase(), options.Concurrency(1), options.WithContext(types.NewContext())) spec, err := compiler.FromPackage(&pkg.DefaultPackage{Name: "extra", Category: "layer", Version: "1.0"}) Expect(err).ToNot(HaveOccurred()) @@ -302,7 +305,7 @@ var _ = Describe("Compiler", func() { Expect(len(generalRecipe.GetDatabase().GetPackages())).To(Equal(1)) - compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(), generalRecipe.GetDatabase()) + compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(ctx), generalRecipe.GetDatabase()) spec, err := compiler.FromPackage(&pkg.DefaultPackage{Name: "b", Category: "test", Version: "1.0"}) Expect(err).ToNot(HaveOccurred()) @@ -336,7 +339,7 @@ var _ = Describe("Compiler", func() { Expect(len(generalRecipe.GetDatabase().GetPackages())).To(Equal(1)) - compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(), generalRecipe.GetDatabase()) + compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(ctx), generalRecipe.GetDatabase()) spec, err := compiler.FromPackage(&pkg.DefaultPackage{Name: "b", Category: "test", Version: "1.0"}) Expect(err).ToNot(HaveOccurred()) @@ -371,7 +374,7 @@ var _ = Describe("Compiler", func() { Expect(len(generalRecipe.GetDatabase().GetPackages())).To(Equal(1)) - compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(), generalRecipe.GetDatabase()) + compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(ctx), generalRecipe.GetDatabase()) spec, err := compiler.FromPackage(&pkg.DefaultPackage{Name: "b", Category: "test", Version: "1.0"}) Expect(err).ToNot(HaveOccurred()) @@ -406,7 +409,7 @@ var _ = Describe("Compiler", func() { Expect(len(generalRecipe.GetDatabase().GetPackages())).To(Equal(2)) - compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(), generalRecipe.GetDatabase()) + compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(ctx), generalRecipe.GetDatabase()) spec, err := compiler.FromPackage(&pkg.DefaultPackage{Name: "b", Category: "test", Version: "1.0"}) Expect(err).ToNot(HaveOccurred()) @@ -439,7 +442,7 @@ var _ = Describe("Compiler", func() { Expect(len(generalRecipe.GetDatabase().GetPackages())).To(Equal(2)) - compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(), generalRecipe.GetDatabase()) + compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(ctx), generalRecipe.GetDatabase()) spec, err := compiler.FromPackage(&pkg.DefaultPackage{Name: "b", Category: "test", Version: "1.0"}) Expect(err).ToNot(HaveOccurred()) @@ -472,7 +475,7 @@ var _ = Describe("Compiler", func() { Expect(len(generalRecipe.GetDatabase().GetPackages())).To(Equal(2)) - compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(), generalRecipe.GetDatabase()) + compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(ctx), generalRecipe.GetDatabase()) spec, err := compiler.FromPackage(&pkg.DefaultPackage{Name: "b", Category: "test", Version: "1.0"}) Expect(err).ToNot(HaveOccurred()) @@ -509,7 +512,7 @@ var _ = Describe("Compiler", func() { Expect(len(generalRecipe.GetDatabase().GetPackages())).To(Equal(3)) - compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(), generalRecipe.GetDatabase()) + compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(ctx), generalRecipe.GetDatabase()) spec, err := compiler.FromPackage(&pkg.DefaultPackage{Name: "pkgs-checker", Category: "package", Version: "9999"}) Expect(err).ToNot(HaveOccurred()) @@ -549,7 +552,7 @@ var _ = Describe("Compiler", func() { Expect(len(generalRecipe.GetDatabase().GetPackages())).To(Equal(3)) - compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(), generalRecipe.GetDatabase()) + compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(ctx), generalRecipe.GetDatabase()) spec, err := compiler.FromPackage(&pkg.DefaultPackage{Name: "d", Category: "test", Version: "1.0"}) Expect(err).ToNot(HaveOccurred()) @@ -592,7 +595,7 @@ var _ = Describe("Compiler", func() { Expect(len(generalRecipe.GetDatabase().GetPackages())).To(Equal(3)) - compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(), generalRecipe.GetDatabase()) + compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(ctx), generalRecipe.GetDatabase()) spec, err := compiler.FromPackage(&pkg.DefaultPackage{Name: "d", Category: "test", Version: "1.0"}) Expect(err).ToNot(HaveOccurred()) @@ -633,7 +636,7 @@ var _ = Describe("Compiler", func() { Expect(len(generalRecipe.GetDatabase().GetPackages())).To(Equal(3)) - compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(), generalRecipe.GetDatabase()) + compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(ctx), generalRecipe.GetDatabase()) spec, err := compiler.FromPackage(&pkg.DefaultPackage{Name: "extra", Category: "layer", Version: "0.1"}) Expect(err).ToNot(HaveOccurred()) @@ -667,7 +670,7 @@ var _ = Describe("Compiler", func() { Expect(err).ToNot(HaveOccurred()) Expect(len(generalRecipe.GetDatabase().GetPackages())).To(Equal(10)) - compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(), generalRecipe.GetDatabase()) + compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(ctx), generalRecipe.GetDatabase()) spec, err := compiler.FromPackage(&pkg.DefaultPackage{Name: "vhba", Category: "sys-fs-5.4.2", Version: "20190410"}) Expect(err).ToNot(HaveOccurred()) @@ -695,7 +698,7 @@ var _ = Describe("Compiler", func() { Expect(len(generalRecipe.GetDatabase().GetPackages())).To(Equal(10)) - compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(), generalRecipe.GetDatabase()) + compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(ctx), generalRecipe.GetDatabase()) spec, err := compiler.FromPackage(&pkg.DefaultPackage{Name: "vhba", Category: "sys-fs-5.4.2", Version: "20190410"}) Expect(err).ToNot(HaveOccurred()) @@ -734,7 +737,7 @@ var _ = Describe("Compiler", func() { Expect(len(generalRecipe.GetDatabase().GetPackages())).To(Equal(4)) - compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(), generalRecipe.GetDatabase()) + compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(ctx), generalRecipe.GetDatabase()) spec, err := compiler.FromPackage(&pkg.DefaultPackage{Name: "b", Category: "test", Version: "1.0"}) @@ -786,7 +789,7 @@ var _ = Describe("Compiler", func() { Expect(len(generalRecipe.GetDatabase().GetPackages())).To(Equal(3)) - compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(), generalRecipe.GetDatabase(), options.Concurrency(2)) + compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(ctx), generalRecipe.GetDatabase(), options.Concurrency(2), options.WithContext(types.NewContext())) spec, err := compiler.FromPackage(&pkg.DefaultPackage{Name: "c", Category: "test", Version: "1.0"}) Expect(err).ToNot(HaveOccurred()) @@ -828,7 +831,7 @@ var _ = Describe("Compiler", func() { Expect(len(generalRecipe.GetDatabase().GetPackages())).To(Equal(2)) - compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(), generalRecipe.GetDatabase()) + compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(ctx), generalRecipe.GetDatabase()) spec, err := compiler.FromPackage(&pkg.DefaultPackage{Name: "runtime", Category: "layer", Version: "0.1"}) Expect(err).ToNot(HaveOccurred()) @@ -860,7 +863,7 @@ var _ = Describe("Compiler", func() { Expect(len(generalRecipe.GetDatabase().GetPackages())).To(Equal(2)) - compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(), generalRecipe.GetDatabase()) + compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(ctx), generalRecipe.GetDatabase()) spec, err := compiler.FromPackage(&pkg.DefaultPackage{ Name: "dironly", @@ -913,7 +916,7 @@ var _ = Describe("Compiler", func() { Expect(len(generalRecipe.GetDatabase().GetPackages())).To(Equal(2)) - compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(), generalRecipe.GetDatabase()) + compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(ctx), generalRecipe.GetDatabase(), options.WithContext(types.NewContext())) spec, err := compiler.FromPackage(&pkg.DefaultPackage{Name: "runtime", Category: "layer", Version: "0.1"}) Expect(err).ToNot(HaveOccurred()) @@ -932,7 +935,7 @@ var _ = Describe("Compiler", func() { Expect(len(artifacts[0].Dependencies)).To(Equal(1)) Expect(fileHelper.Exists(spec.Rel("runtime-layer-0.1.package.tar.gz"))).To(BeTrue()) Expect(fileHelper.Exists(spec.Rel("runtime-layer-0.1.package.tar"))).To(BeFalse()) - Expect(artifacts[0].Unpack(tmpdir, false)).ToNot(HaveOccurred()) + Expect(artifacts[0].Unpack(ctx, tmpdir, false)).ToNot(HaveOccurred()) // Expect(helpers.Untar(spec.Rel("runtime-layer-0.1.package.tar"), tmpdir, false)).ToNot(HaveOccurred()) Expect(fileHelper.Exists(spec.Rel("bin/busybox"))).To(BeTrue()) Expect(fileHelper.Exists(spec.Rel("var"))).ToNot(BeTrue()) @@ -948,7 +951,7 @@ var _ = Describe("Compiler", func() { err := generalRecipe.Load("../../tests/fixtures/includeimage") Expect(err).ToNot(HaveOccurred()) Expect(len(generalRecipe.GetDatabase().GetPackages())).To(Equal(2)) - compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(), generalRecipe.GetDatabase()) + compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(ctx), generalRecipe.GetDatabase(), options.WithContext(types.NewContext())) specs, err := compiler.FromDatabase(generalRecipe.GetDatabase(), true, "") Expect(err).ToNot(HaveOccurred()) @@ -967,7 +970,7 @@ var _ = Describe("Compiler", func() { Expect(len(generalRecipe.GetDatabase().GetPackages())).To(Equal(2)) - compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(), generalRecipe.GetDatabase()) + compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(ctx), generalRecipe.GetDatabase(), options.WithContext(types.NewContext())) spec, err := compiler.FromPackage(&pkg.DefaultPackage{Name: "runtime", Category: "layer", Version: "0.1"}) Expect(err).ToNot(HaveOccurred()) diff --git a/pkg/compiler/imagehashtree.go b/pkg/compiler/imagehashtree.go index ae51a1ca..8b4dffc2 100644 --- a/pkg/compiler/imagehashtree.go +++ b/pkg/compiler/imagehashtree.go @@ -18,8 +18,8 @@ package compiler import ( "fmt" + "github.com/mudler/luet/pkg/api/core/types" compilerspec "github.com/mudler/luet/pkg/compiler/types/spec" - "github.com/mudler/luet/pkg/config" pkg "github.com/mudler/luet/pkg/package" "github.com/mudler/luet/pkg/solver" "github.com/pkg/errors" @@ -32,7 +32,7 @@ import ( // which identifies a Package in a HashTree type ImageHashTree struct { Database pkg.PackageDatabase - SolverOptions config.LuetSolverOptions + SolverOptions types.LuetSolverOptions } // PackageImageHashTree represent the Package into a given image hash tree diff --git a/pkg/compiler/imagehashtree_test.go b/pkg/compiler/imagehashtree_test.go index 1a092062..61707fb4 100644 --- a/pkg/compiler/imagehashtree_test.go +++ b/pkg/compiler/imagehashtree_test.go @@ -16,6 +16,7 @@ package compiler_test import ( + "github.com/mudler/luet/pkg/api/core/types" . "github.com/mudler/luet/pkg/compiler" sd "github.com/mudler/luet/pkg/compiler/backend" "github.com/mudler/luet/pkg/compiler/types/options" @@ -26,15 +27,16 @@ import ( ) var _ = Describe("ImageHashTree", func() { + ctx := types.NewContext() generalRecipe := tree.NewCompilerRecipe(pkg.NewInMemoryDatabase(false)) - compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(), generalRecipe.GetDatabase(), options.Concurrency(2)) + compiler := NewLuetCompiler(sd.NewSimpleDockerBackend(ctx), generalRecipe.GetDatabase(), options.Concurrency(2)) hashtree := NewHashTree(generalRecipe.GetDatabase()) Context("Simple package definition", func() { BeforeEach(func() { generalRecipe = tree.NewCompilerRecipe(pkg.NewInMemoryDatabase(false)) err := generalRecipe.Load("../../tests/fixtures/buildable") Expect(err).ToNot(HaveOccurred()) - compiler = NewLuetCompiler(sd.NewSimpleDockerBackend(), generalRecipe.GetDatabase(), options.Concurrency(2)) + compiler = NewLuetCompiler(sd.NewSimpleDockerBackend(ctx), generalRecipe.GetDatabase(), options.Concurrency(2)) hashtree = NewHashTree(generalRecipe.GetDatabase()) }) @@ -60,7 +62,7 @@ var _ = Describe("ImageHashTree", func() { err := generalRecipe.Load("../../tests/fixtures/upgrade_old_repo_revision") Expect(err).ToNot(HaveOccurred()) - compiler = NewLuetCompiler(sd.NewSimpleDockerBackend(), generalRecipe.GetDatabase(), options.Concurrency(2)) + compiler = NewLuetCompiler(sd.NewSimpleDockerBackend(ctx), generalRecipe.GetDatabase(), options.Concurrency(2)) hashtree = NewHashTree(generalRecipe.GetDatabase()) }) @@ -103,7 +105,7 @@ var _ = Describe("ImageHashTree", func() { //Definition of A here is slightly changed in the steps build.yaml file (1 character only) err := generalRecipe.Load("../../tests/fixtures/upgrade_old_repo_revision_content_changed") Expect(err).ToNot(HaveOccurred()) - compiler = NewLuetCompiler(sd.NewSimpleDockerBackend(), generalRecipe.GetDatabase(), options.Concurrency(2)) + compiler = NewLuetCompiler(sd.NewSimpleDockerBackend(ctx), generalRecipe.GetDatabase(), options.Concurrency(2)) hashtree = NewHashTree(generalRecipe.GetDatabase()) }) diff --git a/pkg/compiler/types/options/compiler_options.go b/pkg/compiler/types/options/compiler_options.go index 5c90b36f..280fa1a5 100644 --- a/pkg/compiler/types/options/compiler_options.go +++ b/pkg/compiler/types/options/compiler_options.go @@ -18,8 +18,8 @@ package options import ( "runtime" + "github.com/mudler/luet/pkg/api/core/types" "github.com/mudler/luet/pkg/compiler/types/compression" - "github.com/mudler/luet/pkg/config" "github.com/mudler/luet/pkg/solver" ) @@ -33,7 +33,7 @@ type Compiler struct { Wait bool OnlyDeps bool NoDeps bool - SolverOptions config.LuetSolverOptions + SolverOptions types.LuetSolverOptions BuildValuesFile []string BuildValues []map[string]interface{} @@ -46,6 +46,8 @@ type Compiler struct { // TemplatesFolder. should default to tree/templates TemplatesFolder []string + + Context *types.Context } func NewDefaultCompiler() *Compiler { @@ -58,7 +60,7 @@ func NewDefaultCompiler() *Compiler { Concurrency: runtime.NumCPU(), OnlyDeps: false, NoDeps: false, - SolverOptions: config.LuetSolverOptions{Options: solver.Options{Concurrency: 1, Type: solver.SingleCoreSimple}}, + SolverOptions: types.LuetSolverOptions{Options: solver.Options{Concurrency: 1, Type: solver.SingleCoreSimple}}, } } @@ -201,9 +203,16 @@ func WithCompressionType(t compression.Implementation) func(cfg *Compiler) error } } -func WithSolverOptions(c config.LuetSolverOptions) func(cfg *Compiler) error { +func WithSolverOptions(c types.LuetSolverOptions) func(cfg *Compiler) error { return func(cfg *Compiler) error { cfg.SolverOptions = c return nil } } + +func WithContext(c *types.Context) func(cfg *Compiler) error { + return func(cfg *Compiler) error { + cfg.Context = c + return nil + } +} diff --git a/pkg/compiler/types/spec/spec_suite_test.go b/pkg/compiler/types/spec/spec_suite_test.go index a911417f..aec182ce 100644 --- a/pkg/compiler/types/spec/spec_suite_test.go +++ b/pkg/compiler/types/spec/spec_suite_test.go @@ -18,14 +18,11 @@ package compilerspec_test import ( "testing" - . "github.com/mudler/luet/cmd/util" - . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) func TestSpec(t *testing.T) { RegisterFailHandler(Fail) - LoadConfig() RunSpecs(t, "Spec Suite") } diff --git a/pkg/config/config_test.go b/pkg/config/config_test.go deleted file mode 100644 index 9ca41ebe..00000000 --- a/pkg/config/config_test.go +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright © 2019-2020 Ettore Di Giacinto -// Daniele Rondina -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License along -// with this program; if not, see . - -package config_test - -import ( - "os" - "path/filepath" - "strings" - - config "github.com/mudler/luet/pkg/config" - fileHelper "github.com/mudler/luet/pkg/helpers/file" - - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" -) - -var _ = Describe("Config", func() { - - Context("Simple temporary directory creation", func() { - - It("Create Temporary directory", func() { - // PRE: tmpdir_base contains default value. - - tmpDir, err := config.LuetCfg.GetSystem().TempDir("test1") - Expect(err).ToNot(HaveOccurred()) - Expect(strings.HasPrefix(tmpDir, filepath.Join(os.TempDir(), "tmpluet"))).To(BeTrue()) - Expect(fileHelper.Exists(tmpDir)).To(BeTrue()) - - defer os.RemoveAll(tmpDir) - }) - - It("Create Temporary file", func() { - // PRE: tmpdir_base contains default value. - - tmpFile, err := config.LuetCfg.GetSystem().TempFile("testfile1") - Expect(err).ToNot(HaveOccurred()) - Expect(strings.HasPrefix(tmpFile.Name(), filepath.Join(os.TempDir(), "tmpluet"))).To(BeTrue()) - Expect(fileHelper.Exists(tmpFile.Name())).To(BeTrue()) - - defer os.Remove(tmpFile.Name()) - }) - - It("Config1", func() { - cfg := config.LuetCfg - - cfg.GetLogging().Color = false - Expect(cfg.GetLogging().Color).To(BeFalse()) - }) - - }) - -}) diff --git a/pkg/helpers/helpers_suite_test.go b/pkg/helpers/helpers_suite_test.go index 83bdc96c..d314ffad 100644 --- a/pkg/helpers/helpers_suite_test.go +++ b/pkg/helpers/helpers_suite_test.go @@ -18,14 +18,11 @@ package helpers_test import ( "testing" - . "github.com/mudler/luet/cmd/util" - . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) func TestSolver(t *testing.T) { RegisterFailHandler(Fail) - LoadConfig() RunSpecs(t, "Helpers Suite") } diff --git a/pkg/installer/cli.go b/pkg/installer/cli.go index 8596ce1c..c3e0f2ab 100644 --- a/pkg/installer/cli.go +++ b/pkg/installer/cli.go @@ -36,6 +36,7 @@ func packsToList(p pkg.Packages) string { } func printList(p pkg.Packages) { + fmt.Println() d := pterm.TableData{{"Program Name", "Version", "License"}} for _, m := range p { d = append(d, []string{ @@ -43,9 +44,12 @@ func printList(p pkg.Packages) { pterm.LightGreen(m.GetVersion()), m.GetLicense()}) } pterm.DefaultTable.WithHasHeader().WithData(d).Render() + fmt.Println() } func printUpgradeList(install, uninstall pkg.Packages) { + fmt.Println() + d := pterm.TableData{{"Old version", "New version", "License"}} for _, m := range uninstall { if p, err := install.Find(m.GetPackageName()); err == nil { @@ -64,6 +68,8 @@ func printUpgradeList(install, uninstall pkg.Packages) { } } pterm.DefaultTable.WithHasHeader().WithData(d).Render() + fmt.Println() + } func printMatchUpgrade(artefacts map[string]ArtifactMatch, uninstall pkg.Packages) { @@ -77,6 +83,7 @@ func printMatchUpgrade(artefacts map[string]ArtifactMatch, uninstall pkg.Package } func printMatches(artefacts map[string]ArtifactMatch) { + fmt.Println() d := pterm.TableData{{"Program Name", "Version", "License", "Repository"}} for _, m := range artefacts { d = append(d, []string{ @@ -84,14 +91,5 @@ func printMatches(artefacts map[string]ArtifactMatch) { pterm.LightGreen(m.Package.GetVersion()), m.Package.GetLicense(), m.Repository.Name}) } pterm.DefaultTable.WithHasHeader().WithData(d).Render() -} - -func matchesToList(artefacts map[string]ArtifactMatch) string { - var packs []string - - for fingerprint, match := range artefacts { - packs = append(packs, fmt.Sprintf("%s (%s)", fingerprint, match.Repository.GetName())) - } - sort.Strings(packs) - return strings.Join(packs, " ") + fmt.Println() } diff --git a/pkg/installer/client/client_suite_test.go b/pkg/installer/client/client_suite_test.go index f6d3bd79..597891f5 100644 --- a/pkg/installer/client/client_suite_test.go +++ b/pkg/installer/client/client_suite_test.go @@ -18,19 +18,11 @@ package client_test import ( "testing" - . "github.com/mudler/luet/cmd/util" - config "github.com/mudler/luet/pkg/config" - . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) func TestClient(t *testing.T) { RegisterFailHandler(Fail) - LoadConfig() - // Set temporary directory for rootfs - config.LuetCfg.GetSystem().Rootfs = "/tmp/luet-root" - // Force dynamic path for packages cache - config.LuetCfg.GetSystem().PkgsCachePath = "" RunSpecs(t, "Client Suite") } diff --git a/pkg/installer/client/docker.go b/pkg/installer/client/docker.go index d2c68a99..63d9458b 100644 --- a/pkg/installer/client/docker.go +++ b/pkg/installer/client/docker.go @@ -26,11 +26,11 @@ import ( "github.com/docker/go-units" "github.com/pkg/errors" + luetTypes "github.com/mudler/luet/pkg/api/core/types" "github.com/mudler/luet/pkg/api/core/types/artifact" - "github.com/mudler/luet/pkg/config" + "github.com/mudler/luet/pkg/helpers/docker" fileHelper "github.com/mudler/luet/pkg/helpers/file" - . "github.com/mudler/luet/pkg/logger" ) const ( @@ -40,18 +40,19 @@ const ( type DockerClient struct { RepoData RepoData auth *types.AuthConfig - verify bool Cache *artifact.ArtifactCache + context *luetTypes.Context } -func NewDockerClient(r RepoData) *DockerClient { +func NewDockerClient(r RepoData, ctx *luetTypes.Context) *DockerClient { auth := &types.AuthConfig{} dat, _ := json.Marshal(r.Authentication) json.Unmarshal(dat, auth) return &DockerClient{RepoData: r, auth: auth, - Cache: artifact.NewCache(config.LuetCfg.GetSystem().GetSystemPkgsCacheDirPath()), + Cache: artifact.NewCache(ctx.Config.GetSystem().GetSystemPkgsCacheDirPath()), + context: ctx, } } @@ -59,8 +60,8 @@ func (c *DockerClient) DownloadArtifact(a *artifact.PackageArtifact) (*artifact. //var u *url.URL = nil var err error - Spinner(22) - defer SpinnerStop() + c.context.Spinner() + defer c.context.SpinnerStop() resultingArtifact := a.ShallowCopy() artifactName := path.Base(a.Path) @@ -81,16 +82,16 @@ func (c *DockerClient) DownloadArtifact(a *artifact.PackageArtifact) (*artifact. resultingArtifact = a resultingArtifact.Path = fileName resultingArtifact.Checksums = artifact.Checksums{} - Debug("Use artifact", artifactName, "from cache.") + c.context.Debug("Use artifact", artifactName, "from cache.") } else { - temp, err := config.LuetCfg.GetSystem().TempDir("image") + temp, err := c.context.Config.GetSystem().TempDir("image") if err != nil { return nil, err } defer os.RemoveAll(temp) - tempArtifact, err := config.LuetCfg.GetSystem().TempFile("artifact") + tempArtifact, err := c.context.Config.GetSystem().TempFile("artifact") if err != nil { return nil, err } @@ -98,43 +99,43 @@ func (c *DockerClient) DownloadArtifact(a *artifact.PackageArtifact) (*artifact. for _, uri := range c.RepoData.Urls { imageName := fmt.Sprintf("%s:%s", uri, a.CompileSpec.GetPackage().ImageID()) - Info("Downloading image", imageName) + c.context.Info("Downloading image", imageName) - contentstore, err := config.LuetCfg.GetSystem().TempDir("contentstore") + contentstore, err := c.context.Config.GetSystem().TempDir("contentstore") if err != nil { - Warning("Cannot create contentstore", err.Error()) + c.context.Warning("Cannot create contentstore", err.Error()) continue } // imageName := fmt.Sprintf("%s/%s", uri, artifact.GetCompileSpec().GetPackage().GetPackageImageName()) info, err := docker.DownloadAndExtractDockerImage(contentstore, imageName, temp, c.auth, c.RepoData.Verify) if err != nil { - Warning(fmt.Sprintf(errImageDownloadMsg, imageName, err.Error())) + c.context.Warning(fmt.Sprintf(errImageDownloadMsg, imageName, err.Error())) continue } - Info(fmt.Sprintf("Pulled: %s", info.Target.Digest)) - Info(fmt.Sprintf("Size: %s", units.BytesSize(float64(info.Target.Size)))) - Debug("\nCompressing result ", filepath.Join(temp), "to", tempArtifact.Name()) + c.context.Info(fmt.Sprintf("Pulled: %s", info.Target.Digest)) + c.context.Info(fmt.Sprintf("Size: %s", units.BytesSize(float64(info.Target.Size)))) + c.context.Debug("\nCompressing result ", filepath.Join(temp), "to", tempArtifact.Name()) // We discard checksum, that are checked while during pull and unpack resultingArtifact.Checksums = artifact.Checksums{} resultingArtifact.Path = tempArtifact.Name() // First set to cache file err = resultingArtifact.Compress(temp, 1) if err != nil { - Error(fmt.Sprintf("Failed compressing package %s: %s", imageName, err.Error())) + c.context.Error(fmt.Sprintf("Failed compressing package %s: %s", imageName, err.Error())) continue } _, _, err = c.Cache.Put(resultingArtifact) if err != nil { - Error(fmt.Sprintf("Failed storing package %s from cache: %s", imageName, err.Error())) + c.context.Error(fmt.Sprintf("Failed storing package %s from cache: %s", imageName, err.Error())) continue } fileName, err := c.Cache.Get(resultingArtifact) if err != nil { - Error(fmt.Sprintf("Failed getting package %s from cache: %s", imageName, err.Error())) + c.context.Error(fmt.Sprintf("Failed getting package %s from cache: %s", imageName, err.Error())) continue } @@ -159,36 +160,36 @@ func (c *DockerClient) DownloadFile(name string) (string, error) { // Files should be in URI/repository: ok := false - temp, err = config.LuetCfg.GetSystem().TempDir("tree") + temp, err = c.context.Config.GetSystem().TempDir("tree") if err != nil { return "", err } for _, uri := range c.RepoData.Urls { - file, err = config.LuetCfg.GetSystem().TempFile("DockerClient") + file, err = c.context.Config.GetSystem().TempFile("DockerClient") if err != nil { continue } - contentstore, err = config.LuetCfg.GetSystem().TempDir("contentstore") + contentstore, err = c.context.Config.GetSystem().TempDir("contentstore") if err != nil { - Warning("Cannot create contentstore", err.Error()) + c.context.Warning("Cannot create contentstore", err.Error()) continue } imageName := fmt.Sprintf("%s:%s", uri, docker.StripInvalidStringsFromImage(name)) - Info("Downloading", imageName) + c.context.Info("Downloading", imageName) info, err := docker.DownloadAndExtractDockerImage(contentstore, imageName, temp, c.auth, c.RepoData.Verify) if err != nil { - Warning(fmt.Sprintf(errImageDownloadMsg, imageName, err.Error())) + c.context.Warning(fmt.Sprintf(errImageDownloadMsg, imageName, err.Error())) continue } - Info(fmt.Sprintf("Pulled: %s", info.Target.Digest)) - Info(fmt.Sprintf("Size: %s", units.BytesSize(float64(info.Target.Size)))) + c.context.Info(fmt.Sprintf("Pulled: %s", info.Target.Digest)) + c.context.Info(fmt.Sprintf("Size: %s", units.BytesSize(float64(info.Target.Size)))) - Debug("\nCopying file ", filepath.Join(temp, name), "to", file.Name()) + c.context.Debug("\nCopying file ", filepath.Join(temp, name), "to", file.Name()) err = fileHelper.CopyFile(filepath.Join(temp, name), file.Name()) if err != nil { continue diff --git a/pkg/installer/client/docker_test.go b/pkg/installer/client/docker_test.go index c3d8a4d4..c2cc9f8a 100644 --- a/pkg/installer/client/docker_test.go +++ b/pkg/installer/client/docker_test.go @@ -1,4 +1,4 @@ -// Copyright © 2019 Ettore Di Giacinto +// Copyright © 2019-2021 Ettore Di Giacinto // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -20,6 +20,7 @@ import ( "os" "path/filepath" + "github.com/mudler/luet/pkg/api/core/types" "github.com/mudler/luet/pkg/api/core/types/artifact" compilerspec "github.com/mudler/luet/pkg/compiler/types/spec" fileHelper "github.com/mudler/luet/pkg/helpers/file" @@ -37,6 +38,8 @@ import ( // mount/unmount layers. var _ = Describe("Docker client", func() { Context("With repository", func() { + ctx := types.NewContext() + repoImage := os.Getenv("UNIT_TEST_DOCKER_IMAGE") var repoURL []string var c *DockerClient @@ -45,7 +48,7 @@ var _ = Describe("Docker client", func() { Skip("UNIT_TEST_DOCKER_IMAGE not specified") } repoURL = []string{repoImage} - c = NewDockerClient(RepoData{Urls: repoURL}) + c = NewDockerClient(RepoData{Urls: repoURL}, ctx) }) It("Downloads single files", func() { @@ -70,7 +73,8 @@ var _ = Describe("Docker client", func() { tmpdir, err := ioutil.TempDir("", "test") Expect(err).ToNot(HaveOccurred()) defer os.RemoveAll(tmpdir) // clean up - Expect(f.Unpack(tmpdir, false)).ToNot(HaveOccurred()) + + Expect(f.Unpack(ctx, tmpdir, false)).ToNot(HaveOccurred()) Expect(fileHelper.Read(filepath.Join(tmpdir, "c"))).To(Equal("c\n")) Expect(fileHelper.Read(filepath.Join(tmpdir, "cd"))).To(Equal("c\n")) os.RemoveAll(f.Path) diff --git a/pkg/installer/client/http.go b/pkg/installer/client/http.go index bf39b7ef..adf926ed 100644 --- a/pkg/installer/client/http.go +++ b/pkg/installer/client/http.go @@ -26,26 +26,27 @@ import ( "strconv" "time" + "github.com/mudler/luet/pkg/api/core/types" "github.com/mudler/luet/pkg/api/core/types/artifact" - . "github.com/mudler/luet/pkg/logger" "github.com/pkg/errors" "github.com/pterm/pterm" "github.com/cavaliercoder/grab" - "github.com/mudler/luet/pkg/config" ) type HttpClient struct { RepoData RepoData Cache *artifact.ArtifactCache + context *types.Context ProgressBarArea *pterm.AreaPrinter } -func NewHttpClient(r RepoData) *HttpClient { +func NewHttpClient(r RepoData, ctx *types.Context) *HttpClient { return &HttpClient{ RepoData: r, - Cache: artifact.NewCache(config.LuetCfg.GetSystem().GetSystemPkgsCacheDirPath()), + Cache: artifact.NewCache(ctx.Config.GetSystem().GetSystemPkgsCacheDirPath()), + context: ctx, } } @@ -96,7 +97,7 @@ func Round(input float64) float64 { func (c *HttpClient) DownloadFile(p string) (string, error) { var file *os.File = nil var downloaded bool - temp, err := config.LuetCfg.GetSystem().TempDir("download") + temp, err := c.context.Config.GetSystem().TempDir("download") if err != nil { return "", err } @@ -105,13 +106,13 @@ func (c *HttpClient) DownloadFile(p string) (string, error) { client := NewGrabClient() for _, uri := range c.RepoData.Urls { - file, err = config.LuetCfg.GetSystem().TempFile("HttpClient") + file, err = c.context.Config.GetSystem().TempFile("HttpClient") if err != nil { - Debug("Failed downloading", p, "from", uri) + c.context.Debug("Failed downloading", p, "from", uri) continue } - Debug("Downloading artifact", p, "from", uri) + c.context.Debug("Downloading artifact", p, "from", uri) u, err := url.Parse(uri) if err != nil { @@ -143,6 +144,7 @@ func (c *HttpClient) DownloadFile(p string) (string, error) { //pb.Increment() pb.Increment().Current = int(resp.BytesComplete()) case <-resp.Done: + pb.Increment().Current = int(resp.BytesComplete()) // download is complete break download_loop } @@ -152,7 +154,7 @@ func (c *HttpClient) DownloadFile(p string) (string, error) { continue } - Info("Downloaded", p, "of", + c.context.Info("Downloaded", p, "of", fmt.Sprintf("%.2f", (float64(resp.BytesComplete())/1000)/1000), "MB (", fmt.Sprintf("%.2f", (float64(resp.BytesPerSecond())/1024)/1024), "MiB/s )") pb.Stop() @@ -175,7 +177,7 @@ func (c *HttpClient) DownloadArtifact(a *artifact.PackageArtifact) (*artifact.Pa // Check if file is already in cache if err == nil { newart.Path = fileName - Debug("Use artifact", artifactName, "from cache.") + c.context.Debug("Use artifact", artifactName, "from cache.") } else { d, err := c.DownloadFile(artifactName) if err != nil { diff --git a/pkg/installer/client/http_test.go b/pkg/installer/client/http_test.go index 6bf7b24e..a842ec85 100644 --- a/pkg/installer/client/http_test.go +++ b/pkg/installer/client/http_test.go @@ -1,4 +1,4 @@ -// Copyright © 2019 Ettore Di Giacinto +// Copyright © 2019-2021 Ettore Di Giacinto // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -22,6 +22,7 @@ import ( "os" "path/filepath" + "github.com/mudler/luet/pkg/api/core/types" "github.com/mudler/luet/pkg/api/core/types/artifact" fileHelper "github.com/mudler/luet/pkg/helpers/file" . "github.com/mudler/luet/pkg/installer/client" @@ -31,6 +32,7 @@ import ( var _ = Describe("Http client", func() { Context("With repository", func() { + ctx := types.NewContext() It("Downloads single files", func() { // setup small staticfile webserver with content @@ -43,7 +45,7 @@ var _ = Describe("Http client", func() { err = ioutil.WriteFile(filepath.Join(tmpdir, "test.txt"), []byte(`test`), os.ModePerm) Expect(err).ToNot(HaveOccurred()) - c := NewHttpClient(RepoData{Urls: []string{ts.URL}}) + c := NewHttpClient(RepoData{Urls: []string{ts.URL}}, ctx) path, err := c.DownloadFile("test.txt") Expect(err).ToNot(HaveOccurred()) Expect(fileHelper.Read(path)).To(Equal("test")) @@ -61,7 +63,7 @@ var _ = Describe("Http client", func() { err = ioutil.WriteFile(filepath.Join(tmpdir, "test.txt"), []byte(`test`), os.ModePerm) Expect(err).ToNot(HaveOccurred()) - c := NewHttpClient(RepoData{Urls: []string{ts.URL}}) + c := NewHttpClient(RepoData{Urls: []string{ts.URL}}, ctx) path, err := c.DownloadArtifact(&artifact.PackageArtifact{Path: "test.txt"}) Expect(err).ToNot(HaveOccurred()) Expect(fileHelper.Read(path.Path)).To(Equal("test")) diff --git a/pkg/installer/client/interface.go b/pkg/installer/client/interface.go index 7bc5867d..9352e95b 100644 --- a/pkg/installer/client/interface.go +++ b/pkg/installer/client/interface.go @@ -1,4 +1,4 @@ -// Copyright © 2019 Ettore Di Giacinto +// Copyright © 2019-2021 Ettore Di Giacinto // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by diff --git a/pkg/installer/client/local.go b/pkg/installer/client/local.go index 9c93618f..ffc4df2c 100644 --- a/pkg/installer/client/local.go +++ b/pkg/installer/client/local.go @@ -1,4 +1,4 @@ -// Copyright © 2020-2021 Ettore Di Giacinto +// Copyright © 2019-2021 Ettore Di Giacinto // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -20,22 +20,23 @@ import ( "path" "path/filepath" + "github.com/mudler/luet/pkg/api/core/types" "github.com/mudler/luet/pkg/api/core/types/artifact" - "github.com/mudler/luet/pkg/config" fileHelper "github.com/mudler/luet/pkg/helpers/file" - . "github.com/mudler/luet/pkg/logger" "github.com/pkg/errors" ) type LocalClient struct { RepoData RepoData Cache *artifact.ArtifactCache + context *types.Context } -func NewLocalClient(r RepoData) *LocalClient { +func NewLocalClient(r RepoData, ctx *types.Context) *LocalClient { return &LocalClient{ - Cache: artifact.NewCache(config.LuetCfg.GetSystem().GetSystemPkgsCacheDirPath()), + Cache: artifact.NewCache(ctx.Config.GetSystem().GetSystemPkgsCacheDirPath()), RepoData: r, + context: ctx, } } @@ -49,7 +50,7 @@ func (c *LocalClient) DownloadArtifact(a *artifact.PackageArtifact) (*artifact.P // Check if file is already in cache if err == nil { newart.Path = fileName - Debug("Use artifact", artifactName, "from cache.") + c.context.Debug("Use artifact", artifactName, "from cache.") } else { d, err := c.DownloadFile(artifactName) if err != nil { @@ -69,8 +70,8 @@ func (c *LocalClient) DownloadFile(name string) (string, error) { rootfs := "" - if !config.LuetCfg.ConfigFromHost { - rootfs, err = config.LuetCfg.GetSystem().GetRootFsAbs() + if !c.context.Config.ConfigFromHost { + rootfs, err = c.context.Config.GetSystem().GetRootFsAbs() if err != nil { return "", err } @@ -81,8 +82,8 @@ func (c *LocalClient) DownloadFile(name string) (string, error) { uri = filepath.Join(rootfs, uri) - Info("Downloading file", name, "from", uri) - file, err = config.LuetCfg.GetSystem().TempFile("localclient") + c.context.Info("Copying file", name, "from", uri) + file, err = c.context.Config.GetSystem().TempFile("localclient") if err != nil { continue } diff --git a/pkg/installer/client/local_test.go b/pkg/installer/client/local_test.go index 486d75df..e0bdab16 100644 --- a/pkg/installer/client/local_test.go +++ b/pkg/installer/client/local_test.go @@ -1,4 +1,4 @@ -// Copyright © 2019 Ettore Di Giacinto +// Copyright © 2019-2021 Ettore Di Giacinto // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -20,6 +20,7 @@ import ( "os" "path/filepath" + "github.com/mudler/luet/pkg/api/core/types" "github.com/mudler/luet/pkg/api/core/types/artifact" fileHelper "github.com/mudler/luet/pkg/helpers/file" . "github.com/mudler/luet/pkg/installer/client" @@ -29,6 +30,8 @@ import ( var _ = Describe("Local client", func() { Context("With repository", func() { + ctx := types.NewContext() + It("Downloads single files", func() { tmpdir, err := ioutil.TempDir("", "test") Expect(err).ToNot(HaveOccurred()) @@ -38,7 +41,7 @@ var _ = Describe("Local client", func() { err = ioutil.WriteFile(filepath.Join(tmpdir, "test.txt"), []byte(`test`), os.ModePerm) Expect(err).ToNot(HaveOccurred()) - c := NewLocalClient(RepoData{Urls: []string{tmpdir}}) + c := NewLocalClient(RepoData{Urls: []string{tmpdir}}, ctx) path, err := c.DownloadFile("test.txt") Expect(err).ToNot(HaveOccurred()) Expect(fileHelper.Read(path)).To(Equal("test")) @@ -54,7 +57,7 @@ var _ = Describe("Local client", func() { err = ioutil.WriteFile(filepath.Join(tmpdir, "test.txt"), []byte(`test`), os.ModePerm) Expect(err).ToNot(HaveOccurred()) - c := NewLocalClient(RepoData{Urls: []string{tmpdir}}) + c := NewLocalClient(RepoData{Urls: []string{tmpdir}}, ctx) path, err := c.DownloadArtifact(&artifact.PackageArtifact{Path: "test.txt"}) Expect(err).ToNot(HaveOccurred()) Expect(fileHelper.Read(path.Path)).To(Equal("test")) diff --git a/pkg/installer/config_protect.go b/pkg/installer/config_protect.go deleted file mode 100644 index 6ec3d5c8..00000000 --- a/pkg/installer/config_protect.go +++ /dev/null @@ -1,100 +0,0 @@ -// Copyright © 2019-2020 Ettore Di Giacinto -// Daniele Rondina -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License along -// with this program; if not, see . - -package installer - -import ( - "io/ioutil" - "path" - "path/filepath" - "regexp" - - "github.com/ghodss/yaml" - - . "github.com/mudler/luet/pkg/config" - . "github.com/mudler/luet/pkg/logger" -) - -func LoadConfigProtectConfs(c *LuetConfig) error { - var regexConfs = regexp.MustCompile(`.yml$`) - var err error - - rootfs := "" - - // Respect the rootfs param on read repositories - if !c.ConfigFromHost { - rootfs, err = c.GetSystem().GetRootFsAbs() - if err != nil { - return err - } - } - - for _, cdir := range c.ConfigProtectConfDir { - cdir = filepath.Join(rootfs, cdir) - - Debug("Parsing Config Protect Directory", cdir, "...") - - files, err := ioutil.ReadDir(cdir) - if err != nil { - Debug("Skip dir", cdir, ":", err.Error()) - continue - } - - for _, file := range files { - if file.IsDir() { - continue - } - - if !regexConfs.MatchString(file.Name()) { - Debug("File", file.Name(), "skipped.") - continue - } - - content, err := ioutil.ReadFile(path.Join(cdir, file.Name())) - if err != nil { - Warning("On read file", file.Name(), ":", err.Error()) - Warning("File", file.Name(), "skipped.") - continue - } - - r, err := LoadConfigProtectConFile(file.Name(), content) - if err != nil { - Warning("On parse file", file.Name(), ":", err.Error()) - Warning("File", file.Name(), "skipped.") - continue - } - - if r.Name == "" || len(r.Directories) == 0 { - Warning("Invalid config protect file", file.Name()) - Warning("File", file.Name(), "skipped.") - continue - } - - c.AddConfigProtectConfFile(r) - } - } - return nil - -} - -func LoadConfigProtectConFile(filename string, data []byte) (*ConfigProtectConfFile, error) { - ans := NewConfigProtectConfFile(filename) - err := yaml.Unmarshal(data, &ans) - if err != nil { - return nil, err - } - return ans, nil -} diff --git a/pkg/installer/finalizer.go b/pkg/installer/finalizer.go index 94e57e7d..f42f0340 100644 --- a/pkg/installer/finalizer.go +++ b/pkg/installer/finalizer.go @@ -1,4 +1,4 @@ -// Copyright © 2019 Ettore Di Giacinto +// Copyright © 2019-2021 Ettore Di Giacinto // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -20,9 +20,8 @@ import ( "os/exec" "github.com/ghodss/yaml" + "github.com/mudler/luet/pkg/api/core/types" box "github.com/mudler/luet/pkg/box" - . "github.com/mudler/luet/pkg/config" - . "github.com/mudler/luet/pkg/logger" "github.com/pkg/errors" ) @@ -33,7 +32,7 @@ type LuetFinalizer struct { Uninstall []string `json:"uninstall"` // TODO: Where to store? } -func (f *LuetFinalizer) RunInstall(s *System) error { +func (f *LuetFinalizer) RunInstall(ctx *types.Context, s *System) error { var cmd string var args []string if len(f.Shell) == 0 { @@ -49,17 +48,17 @@ func (f *LuetFinalizer) RunInstall(s *System) error { for _, c := range f.Install { toRun := append(args, c) - Info(":shell: Executing finalizer on ", s.Target, cmd, toRun) + ctx.Info(":shell: Executing finalizer on ", s.Target, cmd, toRun) if s.Target == string(os.PathSeparator) { cmd := exec.Command(cmd, toRun...) - cmd.Env = LuetCfg.GetFinalizerEnvs() + cmd.Env = ctx.Config.GetFinalizerEnvs() stdoutStderr, err := cmd.CombinedOutput() if err != nil { return errors.Wrap(err, "Failed running command: "+string(stdoutStderr)) } - Info(string(stdoutStderr)) + ctx.Info(string(stdoutStderr)) } else { - b := box.NewBox(cmd, toRun, []string{}, LuetCfg.GetFinalizerEnvs(), s.Target, false, true, true) + b := box.NewBox(cmd, toRun, []string{}, ctx.Config.GetFinalizerEnvs(), s.Target, false, true, true) err := b.Run() if err != nil { return errors.Wrap(err, "Failed running command ") @@ -70,15 +69,15 @@ func (f *LuetFinalizer) RunInstall(s *System) error { } // TODO: We don't store uninstall finalizers ?! -func (f *LuetFinalizer) RunUnInstall() error { +func (f *LuetFinalizer) RunUnInstall(ctx *types.Context) error { for _, c := range f.Uninstall { - Debug("finalizer:", "sh", "-c", c) + ctx.Debug("finalizer:", "sh", "-c", c) cmd := exec.Command("sh", "-c", c) stdoutStderr, err := cmd.CombinedOutput() if err != nil { return errors.Wrap(err, "Failed running command: "+string(stdoutStderr)) } - Info(string(stdoutStderr)) + ctx.Info(string(stdoutStderr)) } return nil } diff --git a/pkg/installer/installer.go b/pkg/installer/installer.go index 52eae45b..95508dae 100644 --- a/pkg/installer/installer.go +++ b/pkg/installer/installer.go @@ -1,4 +1,4 @@ -// Copyright © 2019 Ettore Di Giacinto +// Copyright © 2019-2021 Ettore Di Giacinto // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -24,15 +24,15 @@ import ( "strings" "sync" + "github.com/mudler/luet/pkg/api/core/config" + "github.com/mudler/luet/pkg/api/core/types" artifact "github.com/mudler/luet/pkg/api/core/types/artifact" "github.com/mudler/luet/pkg/bus" - "github.com/mudler/luet/pkg/config" "github.com/mudler/luet/pkg/helpers" fileHelper "github.com/mudler/luet/pkg/helpers/file" "github.com/mudler/luet/pkg/helpers/match" "github.com/mudler/luet/pkg/installer/client" - . "github.com/mudler/luet/pkg/logger" pkg "github.com/mudler/luet/pkg/package" "github.com/mudler/luet/pkg/solver" "github.com/pterm/pterm" @@ -41,7 +41,7 @@ import ( ) type LuetInstallerOptions struct { - SolverOptions config.LuetSolverOptions + SolverOptions types.LuetSolverOptions Concurrency int NoDeps bool OnlyDeps bool @@ -54,6 +54,8 @@ type LuetInstallerOptions struct { DownloadOnly bool Relaxed bool PackageRepositories types.LuetRepositories + + Context *types.Context } type LuetInstaller struct { @@ -127,26 +129,26 @@ func (l *LuetInstaller) computeUpgrade(syncedRepos Repositories, s *System) (pkg // Upgrade upgrades a System based on the Installer options. Returns error in case of failure func (l *LuetInstaller) Upgrade(s *System) error { - + l.Options.Context.Screen("Upgrade") syncedRepos, err := l.SyncRepositories() if err != nil { return err } - Info(":thinking: Computing upgrade, please hang tight... :zzz:") + l.Options.Context.Info(":thinking: Computing upgrade, please hang tight... :zzz:") if l.Options.UpgradeNewRevisions { - Info(":memo: note: will consider new build revisions while upgrading") + l.Options.Context.Info(":memo: note: will consider new build revisions while upgrading") } return l.checkAndUpgrade(syncedRepos, s) } func (l *LuetInstaller) SyncRepositories() (Repositories, error) { - Spinner(32) - defer SpinnerStop() + l.Options.Context.Spinner() + defer l.Options.Context.SpinnerStop() syncedRepos := Repositories{} for _, r := range SystemRepositories(l.Options.PackageRepositories) { - repo, err := r.Sync(false) + repo, err := r.Sync(l.Options.Context, false) if err != nil { return nil, errors.Wrap(err, "Failed syncing repository: "+r.GetName()) } @@ -204,7 +206,7 @@ func (l *LuetInstaller) computeSwap(o Option, syncedRepos Repositories, toRemove packs, err := l.computeUninstall(o, systemAfterChanges, toRemove...) if err != nil && !o.Force { - Error("Failed computing uninstall for ", packsToList(toRemove)) + l.Options.Context.Error("Failed computing uninstall for ", packsToList(toRemove)) return nil, nil, nil, nil, errors.Wrap(err, "computing uninstall "+packsToList(toRemove)) } for _, p := range packs { @@ -230,19 +232,19 @@ func (l *LuetInstaller) swap(o Option, syncedRepos Repositories, toRemove pkg.Pa if l.Options.Ask { // if len(toRemove) > 0 { - // Info(":recycle: Packages that are going to be removed from the system:\n ", Yellow(packsToList(toRemove)).BgBlack().String()) + // l.Options.Context.Info(":recycle: Packages that are going to be removed from the system:\n ", Yellow(packsToList(toRemove)).BgBlack().String()) // } // if len(match) > 0 { - // Info("Packages that are going to be installed in the system:") - // // Info("Packages that are going to be installed in the system: \n ", Green(matchesToList(match)).BgBlack().String()) + // l.Options.Context.Info("Packages that are going to be installed in the system:") + // // l.Options.Context.Info("Packages that are going to be installed in the system: \n ", Green(matchesToList(match)).BgBlack().String()) // printMatches(match) // } - Info(":zap: Proposed version changes to the system:\n ") + l.Options.Context.Info(":zap: Proposed version changes to the system:\n ") printMatchUpgrade(match, toRemove) - Info("By going forward, you are also accepting the licenses of the packages that you are going to install in your system.") - if Ask() { + l.Options.Context.Info("By going forward, you are also accepting the licenses of the packages that you are going to install in your system.") + if l.Options.Context.Ask() { l.Options.Ask = false // Don't prompt anymore } else { return errors.New("Aborted by user") @@ -258,7 +260,7 @@ func (l *LuetInstaller) swap(o Option, syncedRepos Repositories, toRemove pkg.Pa if !l.Options.Force { return errors.Wrap(err, "file conflict found") } else { - Warning("file conflict found", err.Error()) + l.Options.Context.Warning("file conflict found", err.Error()) } } @@ -284,7 +286,7 @@ func (l *LuetInstaller) swap(o Option, syncedRepos Repositories, toRemove pkg.Pa return errors.Wrap(err, "failed getting package to finalize") } - return s.ExecuteFinalizers(toFinalize) + return s.ExecuteFinalizers(l.Options.Context, toFinalize) } type Option struct { @@ -347,17 +349,17 @@ func (l *LuetInstaller) installerOpWorker(i int, wg *sync.WaitGroup, c <-chan in for p := range c { if p.Uninstall.Package != nil { - Debug("Replacing package inplace") + l.Options.Context.Debug("Replacing package inplace") toUninstall, uninstall, err := l.generateUninstallFn(p.Uninstall.Option, s, p.Uninstall.Package) if err != nil { - Error("Failed to generate Uninstall function for" + err.Error()) + l.Options.Context.Error("Failed to generate Uninstall function for" + err.Error()) continue //return errors.Wrap(err, "while computing uninstall") } err = uninstall() if err != nil { - Error("Failed uninstall for ", packsToList(toUninstall)) + l.Options.Context.Error("Failed uninstall for ", packsToList(toUninstall)) continue //return errors.Wrap(err, "uninstalling "+packsToList(toUninstall)) } @@ -377,7 +379,7 @@ func (l *LuetInstaller) installerOpWorker(i int, wg *sync.WaitGroup, c <-chan in s, ) if err != nil { - Error(err) + l.Options.Context.Error(err) } } } @@ -447,10 +449,10 @@ func (l *LuetInstaller) checkAndUpgrade(r Repositories, s *System) error { // SpinnerStop() if len(toInstall) == 0 && len(uninstall) == 0 { - Info("Nothing to upgrade") + l.Options.Context.Info("Nothing to upgrade") return nil } else { - Info(":zap: Proposed version changes to the system:\n ") + l.Options.Context.Info(":zap: Proposed version changes to the system:\n ") printUpgradeList(toInstall, uninstall) } @@ -471,8 +473,8 @@ func (l *LuetInstaller) checkAndUpgrade(r Repositories, s *System) error { } if l.Options.Ask { - Info("By going forward, you are also accepting the licenses of the packages that you are going to install in your system.") - if Ask() { + l.Options.Context.Info("By going forward, you are also accepting the licenses of the packages that you are going to install in your system.") + if l.Options.Context.Ask() { l.Options.Ask = false // Don't prompt anymore return l.swap(o, r, uninstall, toInstall, s) } else { @@ -484,14 +486,14 @@ func (l *LuetInstaller) checkAndUpgrade(r Repositories, s *System) error { } func (l *LuetInstaller) Install(cp pkg.Packages, s *System) error { - Screen("Install") + l.Options.Context.Screen("Install") syncedRepos, err := l.SyncRepositories() if err != nil { return err } if len(s.Database.World()) > 0 && !l.Options.Relaxed { - Info(":thinking: Checking for available upgrades") + l.Options.Context.Info(":thinking: Checking for available upgrades") if err := l.checkAndUpgrade(syncedRepos, s); err != nil { return errors.Wrap(err, "while checking upgrades before install") } @@ -511,7 +513,7 @@ func (l *LuetInstaller) Install(cp pkg.Packages, s *System) error { // Check if we have to process something, or return to the user an error if len(match) == 0 { - Info("No packages to install") + l.Options.Context.Info("No packages to install") return nil } // Resolvers might decide to remove some packages from being installed @@ -536,18 +538,18 @@ func (l *LuetInstaller) Install(cp pkg.Packages, s *System) error { } if !found { - return fmt.Errorf("Package '%s' not found", p.HumanReadableString()) + return fmt.Errorf("package '%s' not found", p.HumanReadableString()) } } } - Info("Packages that are going to be installed in the system:") - //Info("Packages that are going to be installed in the system: \n ", Green(matchesToList(match)).BgBlack().String()) + l.Options.Context.Info("Packages that are going to be installed in the system:") + //l.Options.Context.Info("Packages that are going to be installed in the system: \n ", Green(matchesToList(match)).BgBlack().String()) printMatches(match) if l.Options.Ask { - Info("By going forward, you are also accepting the licenses of the packages that you are going to install in your system.") - if Ask() { + l.Options.Context.Info("By going forward, you are also accepting the licenses of the packages that you are going to install in your system.") + if l.Options.Context.Ask() { l.Options.Ask = false // Don't prompt anymore return l.install(o, syncedRepos, match, packages, assertions, allRepos, s) } else { @@ -596,7 +598,7 @@ func (l *LuetInstaller) Reclaim(s *System) error { for _, repo := range syncedRepos { for _, artefact := range repo.GetIndex() { - Debug("Checking if", + l.Options.Context.Debug("Checking if", artefact.CompileSpec.GetPackage().HumanReadableString(), "from", repo.GetName(), "is installed") FILES: @@ -606,7 +608,7 @@ func (l *LuetInstaller) Reclaim(s *System) error { if err != nil { return err } - Info(":mag: Found package:", p.HumanReadableString()) + l.Options.Context.Info(":mag: Found package:", p.HumanReadableString()) toMerge = append(toMerge, ArtifactMatch{Artifact: artefact, Package: p}) break FILES } @@ -619,7 +621,7 @@ func (l *LuetInstaller) Reclaim(s *System) error { vers, _ := s.Database.FindPackageVersions(pack) if len(vers) >= 1 { - Warning("Filtering out package " + pack.HumanReadableString() + ", already reclaimed") + l.Options.Context.Warning("Filtering out package " + pack.HumanReadableString() + ", already reclaimed") continue } _, err := s.Database.CreatePackage(pack) @@ -627,9 +629,9 @@ func (l *LuetInstaller) Reclaim(s *System) error { return errors.Wrap(err, "Failed creating package") } s.Database.SetPackageFiles(&pkg.PackageFile{PackageFingerprint: pack.GetFingerPrint(), Files: match.Artifact.Files}) - Info(":zap:Reclaimed package:", pack.HumanReadableString()) + l.Options.Context.Info(":zap:Reclaimed package:", pack.HumanReadableString()) } - Info("Done!") + l.Options.Context.Info("Done!") return nil } @@ -645,7 +647,7 @@ func (l *LuetInstaller) computeInstall(o Option, syncedRepos Repositories, cp pk vers, _ := s.Database.FindPackageVersions(pi) if len(vers) >= 1 { - // Warning("Filtering out package " + pi.HumanReadableString() + ", it has other versions already installed. Uninstall one of them first ") + // l.Options.Context.Warning("Filtering out package " + pi.HumanReadableString() + ", it has other versions already installed. Uninstall one of them first ") continue //return errors.New("Package " + pi.GetFingerPrint() + " has other versions already installed. Uninstall one of them first: " + strings.Join(vers, " ")) @@ -727,7 +729,7 @@ func (l *LuetInstaller) computeInstall(o Option, syncedRepos Repositories, cp pk func (l *LuetInstaller) getFinalizers(allRepos pkg.PackageDatabase, solution solver.PackagesAssertions, toInstall map[string]ArtifactMatch, nodeps bool) ([]pkg.Package, error) { var toFinalize []pkg.Package if !nodeps { - // TODO: Lower those errors as warning + // TODO: Lower those errors as l.Options.Context.Warning for _, w := range toInstall { // Finalizers needs to run in order and in sequence. ordered, err := solution.Order(allRepos, w.Package.GetFingerPrint()) @@ -765,7 +767,7 @@ func (l *LuetInstaller) getFinalizers(allRepos pkg.PackageDatabase, solution sol } func (l *LuetInstaller) checkFileconflicts(toInstall map[string]ArtifactMatch, checkSystem bool, s *System) error { - Info("Checking for file conflicts..") + l.Options.Context.Info("Checking for file conflicts..") defer s.Clean() // Release memory filesToInstall := []string{} @@ -819,7 +821,7 @@ func (l *LuetInstaller) install(o Option, syncedRepos Repositories, toInstall ma if !l.Options.Force { return errors.Wrap(err, "file conflict found") } else { - Warning("file conflict found", err.Error()) + l.Options.Context.Warning("file conflict found", err.Error()) } } } @@ -862,12 +864,12 @@ func (l *LuetInstaller) install(o Option, syncedRepos Repositories, toInstall ma return errors.Wrap(err, "failed getting package to finalize") } - return s.ExecuteFinalizers(toFinalize) + return s.ExecuteFinalizers(l.Options.Context, toFinalize) } func (l *LuetInstaller) downloadPackage(a ArtifactMatch, area *pterm.AreaPrinter) (*artifact.PackageArtifact, error) { - cli := a.Repository.Client() + cli := a.Repository.Client(l.Options.Context) switch v := cli.(type) { case *client.HttpClient: @@ -898,7 +900,7 @@ func (l *LuetInstaller) installPackage(m ArtifactMatch, s *System) error { return errors.Wrap(err, "Could not open package archive") } - err = a.Unpack(s.Target, true) + err = a.Unpack(l.Options.Context, s.Target, true) if err != nil && !l.Options.Force { return errors.Wrap(err, "Error met while unpacking rootfs") } @@ -915,10 +917,10 @@ func (l *LuetInstaller) downloadWorker(i int, wg *sync.WaitGroup, c <-chan Artif // TODO: Keep trace of what was added from the tar, and save it into system _, err := l.downloadPackage(p, area) if err != nil { - Error("Failed downloading package "+p.Package.GetName(), err.Error()) + l.Options.Context.Error("Failed downloading package "+p.Package.GetName(), err.Error()) return errors.Wrap(err, "Failed downloading package "+p.Package.GetName()) } else { - Success(":package: Package ", p.Package.HumanReadableString(), "downloaded") + l.Options.Context.Success(":package: Package ", p.Package.HumanReadableString(), "downloaded") } pb.Increment() @@ -935,26 +937,26 @@ func (l *LuetInstaller) installerWorker(i int, wg *sync.WaitGroup, c <-chan Arti err := l.installPackage(p, s) if err != nil && !l.Options.Force { //TODO: Uninstall, rollback. - Fatal("Failed installing package "+p.Package.GetName(), err.Error()) + l.Options.Context.Fatal("Failed installing package "+p.Package.GetName(), err.Error()) return errors.Wrap(err, "Failed installing package "+p.Package.GetName()) } if err == nil { - Info(":package: Package ", p.Package.HumanReadableString(), "installed") + l.Options.Context.Info(":package: Package ", p.Package.HumanReadableString(), "installed") } else if err != nil && l.Options.Force { - Info(":package: Package ", p.Package.HumanReadableString(), "installed with failures (forced install)") + l.Options.Context.Info(":package: Package ", p.Package.HumanReadableString(), "installed with failures (forced install)") } } return nil } -func checkAndPrunePath(path string) { +func checkAndPrunePath(ctx *types.Context, path string) { // check if now the target path is empty targetPath := filepath.Dir(path) fi, err := os.Lstat(targetPath) if err != nil { - // Warning("Dir not found (it was before?) ", err.Error()) + // l.Options.Context.Warning("Dir not found (it was before?) ", err.Error()) return } @@ -962,24 +964,27 @@ func checkAndPrunePath(path string) { case mode.IsDir(): files, err := ioutil.ReadDir(targetPath) if err != nil { - Warning("Failed reading folder", targetPath, err.Error()) + ctx.Warning("Failed reading folder", targetPath, err.Error()) + return } if len(files) != 0 { - Debug("Preserving not-empty folder", targetPath) + ctx.Debug("Preserving not-empty folder", targetPath) return } } if err = os.Remove(targetPath); err != nil { - Warning("Failed removing file (maybe not present in the system target anymore ?)", targetPath, err.Error()) + ctx.Warning("Failed removing file (maybe not present in the system target anymore ?)", targetPath, err.Error()) } } // We will try to cleanup every path from the file, if the folders left behind are empty -func pruneEmptyFilePath(path string) { - checkAndPrunePath(path) +func pruneEmptyFilePath(ctx *types.Context, path string) { + checkAndPrunePath(ctx, path) // A path is for e.g. /usr/bin/bar - // we want to create an array as "/usr", "/usr/bin", "/usr/bin/bar" + // we want to create an array + // as "/usr", "/usr/bin", "/usr/bin/bar", + // excluding the target (in the case above was /) paths := strings.Split(path, string(os.PathSeparator)) currentPath := filepath.Join(string(os.PathSeparator), paths[0]) allPaths := []string{currentPath} @@ -989,7 +994,7 @@ func pruneEmptyFilePath(path string) { } match.ReverseAny(allPaths) for _, p := range allPaths { - checkAndPrunePath(p) + checkAndPrunePath(ctx, p) } } @@ -1002,7 +1007,7 @@ func (l *LuetInstaller) uninstall(p pkg.Package, s *System) error { return errors.Wrap(err, "Failed getting installed files") } - if !config.LuetCfg.ConfigProtectSkip { + if !l.Options.Context.Config.ConfigProtectSkip { if p.HasAnnotation(string(pkg.ConfigProtectAnnnotation)) { dir, ok := p.GetAnnotations()[string(pkg.ConfigProtectAnnnotation)] @@ -1012,7 +1017,7 @@ func (l *LuetInstaller) uninstall(p pkg.Package, s *System) error { } cp = config.NewConfigProtect(annotationDir) - cp.Map(files) + cp.Map(files, l.Options.Context.Config.GetConfigProtectConfFiles()) } toRemove, notPresent := fileHelper.OrderFiles(s.Target, files) @@ -1021,56 +1026,56 @@ func (l *LuetInstaller) uninstall(p pkg.Package, s *System) error { for _, f := range toRemove { target := filepath.Join(s.Target, f) - if !config.LuetCfg.ConfigProtectSkip && cp.Protected(f) { - Debug("Preserving protected file:", f) + if !l.Options.Context.Config.ConfigProtectSkip && cp.Protected(f) { + l.Options.Context.Debug("Preserving protected file:", f) continue } - Debug("Removing", target) + l.Options.Context.Debug("Removing", target) if l.Options.PreserveSystemEssentialData && - strings.HasPrefix(f, config.LuetCfg.GetSystem().GetSystemPkgsCacheDirPath()) || - strings.HasPrefix(f, config.LuetCfg.GetSystem().GetSystemRepoDatabaseDirPath()) { - Warning("Preserve ", f, " which is required by luet ( you have to delete it manually if you really need to)") + strings.HasPrefix(f, l.Options.Context.Config.GetSystem().GetSystemPkgsCacheDirPath()) || + strings.HasPrefix(f, l.Options.Context.Config.GetSystem().GetSystemRepoDatabaseDirPath()) { + l.Options.Context.Warning("Preserve ", f, " which is required by luet ( you have to delete it manually if you really need to)") continue } fi, err := os.Lstat(target) if err != nil { - Warning("File not found (it was before?) ", err.Error()) + l.Options.Context.Warning("File not found (it was before?) ", err.Error()) continue } switch mode := fi.Mode(); { case mode.IsDir(): files, err := ioutil.ReadDir(target) if err != nil { - Warning("Failed reading folder", target, err.Error()) + l.Options.Context.Warning("Failed reading folder", target, err.Error()) } if len(files) != 0 { - Debug("Preserving not-empty folder", target) + l.Options.Context.Debug("Preserving not-empty folder", target) continue } } if err = os.Remove(target); err != nil { - Warning("Failed removing file (maybe not present in the system target anymore ?)", target, err.Error()) + l.Options.Context.Warning("Failed removing file (maybe not present in the system target anymore ?)", target, err.Error()) } - pruneEmptyFilePath(target) + pruneEmptyFilePath(l.Options.Context, target) } for _, f := range notPresent { target := filepath.Join(s.Target, f) - if !config.LuetCfg.ConfigProtectSkip && cp.Protected(f) { - Debug("Preserving protected file:", f) + if !l.Options.Context.Config.ConfigProtectSkip && cp.Protected(f) { + l.Options.Context.Debug("Preserving protected file:", f) continue } if err = os.Remove(target); err != nil { - Debug("Failed removing file (not present in the system target)", target, err.Error()) + l.Options.Context.Debug("Failed removing file (not present in the system target)", target, err.Error()) } - pruneEmptyFilePath(target) + pruneEmptyFilePath(l.Options.Context, target) } err = s.Database.RemovePackageFiles(p) @@ -1084,7 +1089,7 @@ func (l *LuetInstaller) uninstall(p pkg.Package, s *System) error { bus.Manager.Publish(bus.EventPackageUnInstall, p) - Info(":recycle: ", p.GetFingerPrint(), "Removed :heavy_check_mark:") + l.Options.Context.Info(":recycle: ", p.HumanReadableString(), "Removed :heavy_check_mark:") return nil } @@ -1124,9 +1129,7 @@ func (l *LuetInstaller) computeUninstall(o Option, s *System, packs ...pkg.Packa } } - for _, p := range solution { - toUninstall = append(toUninstall, p) - } + toUninstall = append(toUninstall, solution...) } else { toUninstall = append(toUninstall, packs...) } @@ -1160,8 +1163,9 @@ func (l *LuetInstaller) generateUninstallFn(o Option, s *System, packs ...pkg.Pa } func (l *LuetInstaller) Uninstall(s *System, packs ...pkg.Package) error { + l.Options.Context.Screen("Uninstall") - Spinner(32) + l.Options.Context.Spinner() o := Option{ FullUninstall: l.Options.FullUninstall, Force: l.Options.Force, @@ -1172,17 +1176,17 @@ func (l *LuetInstaller) Uninstall(s *System, packs ...pkg.Package) error { if err != nil { return errors.Wrap(err, "while computing uninstall") } - SpinnerStop() + l.Options.Context.SpinnerStop() if len(toUninstall) == 0 { - Info("Nothing to do") + l.Options.Context.Info("Nothing to do") return nil } if l.Options.Ask { - Info(":recycle: Packages that are going to be removed from the system:") + l.Options.Context.Info(":recycle: Packages that are going to be removed from the system:") printList(toUninstall) - if Ask() { + if l.Options.Context.Ask() { l.Options.Ask = false // Don't prompt anymore return uninstall() } else { diff --git a/pkg/installer/installer_suite_test.go b/pkg/installer/installer_suite_test.go index aeaad6fd..e14aee8c 100644 --- a/pkg/installer/installer_suite_test.go +++ b/pkg/installer/installer_suite_test.go @@ -18,19 +18,11 @@ package installer_test import ( "testing" - . "github.com/mudler/luet/cmd/util" - config "github.com/mudler/luet/pkg/config" - . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) func TestInstaller(t *testing.T) { RegisterFailHandler(Fail) - LoadConfig() - // Set temporary directory for rootfs - config.LuetCfg.GetSystem().Rootfs = "/tmp/luet-root" - // Force dynamic path for packages cache - config.LuetCfg.GetSystem().PkgsCachePath = "" RunSpecs(t, "Installer Suite") } diff --git a/pkg/installer/installer_test.go b/pkg/installer/installer_test.go index 9a124130..f2b30f57 100644 --- a/pkg/installer/installer_test.go +++ b/pkg/installer/installer_test.go @@ -46,11 +46,17 @@ func stubRepo(tmpdir, tree string) (*LuetSystemRepository, error) { WithPriority(1), WithSource(tmpdir), WithTree(tree), + WithContext(types.NewContext()), WithDatabase(pkg.NewInMemoryDatabase(false)), ) } var _ = Describe("Installer", func() { + ctx := types.NewContext() + + BeforeEach(func() { + ctx = types.NewContext() + }) Context("Writes a repository definition", func() { It("Writes a repo and can install packages from it", func() { @@ -67,7 +73,7 @@ var _ = Describe("Installer", func() { Expect(len(generalRecipe.GetDatabase().GetPackages())).To(Equal(3)) - c := compiler.NewLuetCompiler(backend.NewSimpleDockerBackend(), + c := compiler.NewLuetCompiler(backend.NewSimpleDockerBackend(ctx), generalRecipe.GetDatabase(), options.Concurrency(2)) @@ -109,7 +115,7 @@ var _ = Describe("Installer", func() { Expect(fileHelper.Exists(spec.Rel("repository.yaml"))).ToNot(BeTrue()) Expect(fileHelper.Exists(spec.Rel(TREE_TARBALL + ".gz"))).ToNot(BeTrue()) Expect(fileHelper.Exists(spec.Rel(REPOSITORY_METAFILE + ".tar"))).ToNot(BeTrue()) - err = repo.Write(tmpdir, false, false) + err = repo.Write(ctx, tmpdir, false, false) Expect(err).ToNot(HaveOccurred()) Expect(fileHelper.Exists(spec.Rel("repository.yaml"))).To(BeTrue()) @@ -131,7 +137,7 @@ urls: `), pkg.NewInMemoryDatabase(false)) Expect(err).ToNot(HaveOccurred()) inst := NewLuetInstaller(LuetInstallerOptions{ - Concurrency: 1, + Concurrency: 1, Context: ctx, PackageRepositories: types.LuetRepositories{*repo2.LuetRepository}, }) Expect(repo.GetUrls()[0]).To(Equal(tmpdir)) @@ -185,7 +191,7 @@ urls: Expect(len(generalRecipe.GetDatabase().GetPackages())).To(Equal(3)) - c := compiler.NewLuetCompiler(backend.NewSimpleDockerBackend(), + c := compiler.NewLuetCompiler(backend.NewSimpleDockerBackend(ctx), generalRecipe.GetDatabase(), options.Concurrency(2)) spec, err := c.FromPackage(&pkg.DefaultPackage{Name: "b", Category: "test", Version: "1.0"}) @@ -231,7 +237,7 @@ urls: Expect(fileHelper.Exists(spec.Rel("repository.yaml"))).ToNot(BeTrue()) Expect(fileHelper.Exists(spec.Rel(TREE_TARBALL + ".gz"))).ToNot(BeTrue()) Expect(fileHelper.Exists(spec.Rel(REPOSITORY_METAFILE + ".tar"))).ToNot(BeTrue()) - err = repo.Write(tmpdir, false, false) + err = repo.Write(ctx, tmpdir, false, false) Expect(err).ToNot(HaveOccurred()) Expect(fileHelper.Exists(spec.Rel("repository.yaml"))).To(BeTrue()) @@ -254,7 +260,7 @@ urls: Expect(err).ToNot(HaveOccurred()) inst := NewLuetInstaller(LuetInstallerOptions{ - Concurrency: 1, + Concurrency: 1, Context: ctx, PackageRepositories: types.LuetRepositories{*repo2.LuetRepository}, }) Expect(repo.GetUrls()[0]).To(Equal(tmpdir)) @@ -308,7 +314,7 @@ urls: Expect(len(generalRecipe.GetDatabase().GetPackages())).To(Equal(3)) - c := compiler.NewLuetCompiler(backend.NewSimpleDockerBackend(), generalRecipe.GetDatabase(), + c := compiler.NewLuetCompiler(backend.NewSimpleDockerBackend(ctx), generalRecipe.GetDatabase(), options.Concurrency(2)) spec, err := c.FromPackage(&pkg.DefaultPackage{Name: "b", Category: "test", Version: "1.0"}) @@ -358,7 +364,7 @@ urls: Expect(fileHelper.Exists(spec.Rel("repository.yaml"))).ToNot(BeTrue()) Expect(fileHelper.Exists(spec.Rel(TREE_TARBALL + ".gz"))).ToNot(BeTrue()) Expect(fileHelper.Exists(spec.Rel(REPOSITORY_METAFILE + ".tar"))).ToNot(BeTrue()) - err = repo.Write(tmpdir, false, false) + err = repo.Write(ctx, tmpdir, false, false) Expect(err).ToNot(HaveOccurred()) Expect(fileHelper.Exists(spec.Rel("repository.yaml"))).To(BeTrue()) @@ -380,7 +386,7 @@ urls: `), pkg.NewInMemoryDatabase(false)) Expect(err).ToNot(HaveOccurred()) inst := NewLuetInstaller(LuetInstallerOptions{ - Concurrency: 1, + Concurrency: 1, Context: ctx, PackageRepositories: types.LuetRepositories{*repo2.LuetRepository}, }) Expect(repo.GetUrls()[0]).To(Equal(tmpdir)) @@ -437,7 +443,7 @@ urls: Expect(len(generalRecipe.GetDatabase().GetPackages())).To(Equal(3)) - c := compiler.NewLuetCompiler(backend.NewSimpleDockerBackend(), generalRecipe.GetDatabase(), + c := compiler.NewLuetCompiler(backend.NewSimpleDockerBackend(ctx), generalRecipe.GetDatabase(), options.Concurrency(2)) spec, err := c.FromPackage(&pkg.DefaultPackage{Name: "b", Category: "test", Version: "1.0"}) @@ -487,7 +493,7 @@ urls: Expect(fileHelper.Exists(spec.Rel("repository.yaml"))).ToNot(BeTrue()) Expect(fileHelper.Exists(spec.Rel(TREE_TARBALL + ".gz"))).ToNot(BeTrue()) Expect(fileHelper.Exists(spec.Rel(REPOSITORY_METAFILE + ".tar"))).ToNot(BeTrue()) - err = repo.Write(tmpdir, false, false) + err = repo.Write(ctx, tmpdir, false, false) Expect(err).ToNot(HaveOccurred()) Expect(fileHelper.Exists(spec.Rel("repository.yaml"))).To(BeTrue()) @@ -510,7 +516,7 @@ urls: Expect(err).ToNot(HaveOccurred()) inst := NewLuetInstaller(LuetInstallerOptions{ - Concurrency: 1, + Concurrency: 1, Context: ctx, PackageRepositories: types.LuetRepositories{*repo2.LuetRepository}, }) Expect(repo.GetUrls()[0]).To(Equal(tmpdir)) @@ -536,7 +542,7 @@ urls: Expect(len(generalRecipe2.GetDatabase().GetPackages())).To(Equal(1)) - c = compiler.NewLuetCompiler(backend.NewSimpleDockerBackend(), generalRecipe2.GetDatabase(), options.Concurrency(2)) + c = compiler.NewLuetCompiler(backend.NewSimpleDockerBackend(ctx), generalRecipe2.GetDatabase(), options.Concurrency(2)) spec, err = c.FromPackage(&pkg.DefaultPackage{Name: "alpine", Category: "seed", Version: "1.0"}) Expect(err).ToNot(HaveOccurred()) @@ -551,7 +557,7 @@ urls: repo, err = stubRepo(tmpdir2, "../../tests/fixtures/alpine") Expect(err).ToNot(HaveOccurred()) - err = repo.Write(tmpdir2, false, false) + err = repo.Write(ctx, tmpdir2, false, false) Expect(err).ToNot(HaveOccurred()) fakeroot, err = ioutil.TempDir("", "fakeroot") @@ -567,7 +573,7 @@ urls: `), pkg.NewInMemoryDatabase(false)) Expect(err).ToNot(HaveOccurred()) inst = NewLuetInstaller(LuetInstallerOptions{ - Concurrency: 1, + Concurrency: 1, Context: ctx, PackageRepositories: types.LuetRepositories{*repo2.LuetRepository}, }) Expect(repo.GetUrls()[0]).To(Equal(tmpdir2)) @@ -597,7 +603,7 @@ urls: Expect(len(generalRecipe.GetDatabase().GetPackages())).To(Equal(4)) - c := compiler.NewLuetCompiler(backend.NewSimpleDockerBackend(), generalRecipe.GetDatabase(), options.Concurrency(2)) + c := compiler.NewLuetCompiler(backend.NewSimpleDockerBackend(ctx), generalRecipe.GetDatabase(), options.Concurrency(2)) spec, err := c.FromPackage(&pkg.DefaultPackage{Name: "b", Category: "test", Version: "1.0"}) Expect(err).ToNot(HaveOccurred()) @@ -626,7 +632,7 @@ urls: Expect(fileHelper.Exists(spec.Rel("repository.yaml"))).ToNot(BeTrue()) Expect(fileHelper.Exists(spec.Rel(TREE_TARBALL + ".gz"))).ToNot(BeTrue()) Expect(fileHelper.Exists(spec.Rel(REPOSITORY_METAFILE + ".tar"))).ToNot(BeTrue()) - err = repo.Write(tmpdir, false, false) + err = repo.Write(ctx, tmpdir, false, false) Expect(err).ToNot(HaveOccurred()) Expect(fileHelper.Exists(spec.Rel("repository.yaml"))).To(BeTrue()) @@ -648,7 +654,7 @@ urls: `), pkg.NewInMemoryDatabase(false)) Expect(err).ToNot(HaveOccurred()) inst := NewLuetInstaller(LuetInstallerOptions{ - Concurrency: 1, + Concurrency: 1, Context: ctx, PackageRepositories: types.LuetRepositories{*repo2.LuetRepository}, }) Expect(repo.GetUrls()[0]).To(Equal(tmpdir)) @@ -716,8 +722,8 @@ urls: Expect(len(generalRecipe.GetDatabase().GetPackages())).To(Equal(3)) Expect(len(generalRecipeNewRepo.GetDatabase().GetPackages())).To(Equal(3)) - c := compiler.NewLuetCompiler(backend.NewSimpleDockerBackend(), generalRecipe.GetDatabase(), options.Concurrency(2)) - c2 := compiler.NewLuetCompiler(backend.NewSimpleDockerBackend(), generalRecipeNewRepo.GetDatabase()) + c := compiler.NewLuetCompiler(backend.NewSimpleDockerBackend(ctx), generalRecipe.GetDatabase(), options.Concurrency(2)) + c2 := compiler.NewLuetCompiler(backend.NewSimpleDockerBackend(ctx), generalRecipeNewRepo.GetDatabase()) spec, err := c.FromPackage(&pkg.DefaultPackage{Name: "b", Category: "test", Version: "1.0"}) Expect(err).ToNot(HaveOccurred()) @@ -753,12 +759,12 @@ urls: Expect(fileHelper.Exists(spec.Rel("repository.yaml"))).ToNot(BeTrue()) Expect(fileHelper.Exists(spec.Rel(TREE_TARBALL + ".gz"))).ToNot(BeTrue()) Expect(fileHelper.Exists(spec.Rel(REPOSITORY_METAFILE + ".tar"))).ToNot(BeTrue()) - err = repo.Write(tmpdir, false, false) + err = repo.Write(ctx, tmpdir, false, false) Expect(err).ToNot(HaveOccurred()) repoupgrade, err := stubRepo(tmpdirnewrepo, "../../tests/fixtures/upgrade_new_repo") Expect(err).ToNot(HaveOccurred()) - err = repoupgrade.Write(tmpdirnewrepo, false, false) + err = repoupgrade.Write(ctx, tmpdirnewrepo, false, false) Expect(err).ToNot(HaveOccurred()) fakeroot, err := ioutil.TempDir("", "fakeroot") @@ -783,7 +789,7 @@ urls: `), pkg.NewInMemoryDatabase(false)) Expect(err).ToNot(HaveOccurred()) inst := NewLuetInstaller(LuetInstallerOptions{ - Concurrency: 1, + Concurrency: 1, Context: ctx, PackageRepositories: types.LuetRepositories{*repo2.LuetRepository}, }) Expect(repo.GetUrls()[0]).To(Equal(tmpdir)) @@ -852,7 +858,7 @@ urls: Expect(len(generalRecipe.GetDatabase().GetPackages())).To(Equal(4)) c := compiler.NewLuetCompiler( - backend.NewSimpleDockerBackend(), + backend.NewSimpleDockerBackend(ctx), generalRecipe.GetDatabase(), options.Concurrency(2), options.WithCompressionType(compression.GZip), @@ -884,7 +890,7 @@ urls: Expect(fileHelper.Exists(spec.Rel("repository.yaml"))).ToNot(BeTrue()) Expect(fileHelper.Exists(spec.Rel(TREE_TARBALL + ".gz"))).ToNot(BeTrue()) Expect(fileHelper.Exists(spec.Rel(REPOSITORY_METAFILE + ".tar"))).ToNot(BeTrue()) - err = repo.Write(tmpdir, false, false) + err = repo.Write(ctx, tmpdir, false, false) Expect(err).ToNot(HaveOccurred()) Expect(fileHelper.Exists(spec.Rel("b-test-1.1.package.tar.gz"))).To(BeTrue()) Expect(fileHelper.Exists(spec.Rel("b-test-1.1.package.tar"))).ToNot(BeTrue()) @@ -909,7 +915,7 @@ urls: Expect(err).ToNot(HaveOccurred()) inst := NewLuetInstaller(LuetInstallerOptions{ - Concurrency: 1, + Concurrency: 1, Context: ctx, PackageRepositories: types.LuetRepositories{*repo2.LuetRepository}, }) @@ -974,7 +980,7 @@ urls: systemDB := pkg.NewBoltDatabase(filepath.Join(bolt, "db.db")) system := &System{Database: systemDB, Target: fakeroot} - inst := NewLuetInstaller(LuetInstallerOptions{Concurrency: 1, CheckConflicts: true}) + inst := NewLuetInstaller(LuetInstallerOptions{Concurrency: 1, Context: ctx, CheckConflicts: true}) D := pkg.NewPackage("D", "", []*pkg.DefaultPackage{}, []*pkg.DefaultPackage{}) B := pkg.NewPackage("calamares", "", []*pkg.DefaultPackage{D}, []*pkg.DefaultPackage{}) @@ -1017,7 +1023,7 @@ urls: Expect(len(generalRecipe.GetDatabase().GetPackages())).To(Equal(4)) - c := compiler.NewLuetCompiler(backend.NewSimpleDockerBackend(), generalRecipe.GetDatabase(), + c := compiler.NewLuetCompiler(backend.NewSimpleDockerBackend(ctx), generalRecipe.GetDatabase(), options.Concurrency(2), options.WithCompressionType(compression.GZip)) @@ -1046,7 +1052,7 @@ urls: Expect(fileHelper.Exists(spec.Rel("repository.yaml"))).ToNot(BeTrue()) Expect(fileHelper.Exists(spec.Rel(TREE_TARBALL + ".gz"))).ToNot(BeTrue()) Expect(fileHelper.Exists(spec.Rel(REPOSITORY_METAFILE + ".tar"))).ToNot(BeTrue()) - err = repo.Write(tmpdir, false, false) + err = repo.Write(ctx, tmpdir, false, false) Expect(err).ToNot(HaveOccurred()) Expect(fileHelper.Exists(spec.Rel("b-test-1.1.package.tar.gz"))).To(BeTrue()) Expect(fileHelper.Exists(spec.Rel("b-test-1.1.package.tar"))).ToNot(BeTrue()) @@ -1071,7 +1077,7 @@ urls: Expect(err).ToNot(HaveOccurred()) inst := NewLuetInstaller(LuetInstallerOptions{ - Concurrency: 1, + Concurrency: 1, Context: ctx, PackageRepositories: types.LuetRepositories{*repo2.LuetRepository}, }) @@ -1126,7 +1132,7 @@ urls: Expect(len(generalRecipe.GetDatabase().GetPackages())).To(Equal(3)) - c := compiler.NewLuetCompiler(backend.NewSimpleDockerBackend(), generalRecipe.GetDatabase(), + c := compiler.NewLuetCompiler(backend.NewSimpleDockerBackend(ctx), generalRecipe.GetDatabase(), options.WithCompressionType(compression.GZip)) spec, err := c.FromPackage(&pkg.DefaultPackage{Name: "b", Category: "test", Version: "1.0"}) @@ -1151,7 +1157,7 @@ urls: Expect(fileHelper.Exists(spec.Rel("repository.yaml"))).ToNot(BeTrue()) Expect(fileHelper.Exists(spec.Rel(TREE_TARBALL + ".gz"))).ToNot(BeTrue()) Expect(fileHelper.Exists(spec.Rel(REPOSITORY_METAFILE + ".tar"))).ToNot(BeTrue()) - err = repo.Write(tmpdir, false, false) + err = repo.Write(ctx, tmpdir, false, false) Expect(err).ToNot(HaveOccurred()) Expect(fileHelper.Exists(spec.Rel("repository.yaml"))).To(BeTrue()) @@ -1174,7 +1180,7 @@ urls: Expect(err).ToNot(HaveOccurred()) inst := NewLuetInstaller(LuetInstallerOptions{ - Concurrency: 1, + Concurrency: 1, Context: ctx, PackageRepositories: types.LuetRepositories{*repo2.LuetRepository}, }) @@ -1221,7 +1227,7 @@ urls: Expect(len(generalRecipe2.GetDatabase().GetPackages())).To(Equal(3)) - c = compiler.NewLuetCompiler(backend.NewSimpleDockerBackend(), generalRecipe2.GetDatabase()) + c = compiler.NewLuetCompiler(backend.NewSimpleDockerBackend(ctx), generalRecipe2.GetDatabase()) spec, err = c.FromPackage(&pkg.DefaultPackage{Name: "b", Category: "test", Version: "1.1"}) Expect(err).ToNot(HaveOccurred()) @@ -1238,7 +1244,7 @@ urls: repo, err = stubRepo(tmpdir2, "../../tests/fixtures/upgrade_new_repo") Expect(err).ToNot(HaveOccurred()) Expect(repo.GetName()).To(Equal("test")) - err = repo.Write(tmpdir2, false, false) + err = repo.Write(ctx, tmpdir2, false, false) Expect(err).ToNot(HaveOccurred()) repo2, err = NewLuetSystemRepositoryFromYaml([]byte(` @@ -1251,7 +1257,7 @@ urls: Expect(err).ToNot(HaveOccurred()) inst = NewLuetInstaller(LuetInstallerOptions{ - Concurrency: 1, + Concurrency: 1, Context: ctx, PackageRepositories: types.LuetRepositories{*repo2.LuetRepository}, }) diff --git a/pkg/installer/repository.go b/pkg/installer/repository.go index cdf4fe7f..278db4ba 100644 --- a/pkg/installer/repository.go +++ b/pkg/installer/repository.go @@ -1,4 +1,4 @@ -// Copyright © 2019 Ettore Di Giacinto +// Copyright © 2019-2021 Ettore Di Giacinto // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -34,9 +34,7 @@ import ( "github.com/mudler/luet/pkg/api/core/types" "github.com/mudler/luet/pkg/compiler" - "github.com/mudler/luet/pkg/config" "github.com/mudler/luet/pkg/installer/client" - . "github.com/mudler/luet/pkg/logger" pkg "github.com/mudler/luet/pkg/package" tree "github.com/mudler/luet/pkg/tree" @@ -117,15 +115,15 @@ func SystemRepositories(t types.LuetRepositories) Repositories { } // LoadBuildTree loads to the tree the compilation specs from the system repositories -func LoadBuildTree(t tree.Builder, db pkg.PackageDatabase, c *config.LuetConfig) error { +func LoadBuildTree(t tree.Builder, db pkg.PackageDatabase, ctx *types.Context) error { var reserr error - repos := SystemRepositories(c.SystemRepositories) + repos := SystemRepositories(ctx.Config.SystemRepositories) for _, r := range repos { - repodir, err := config.LuetCfg.GetSystem().TempDir(r.Name) + repodir, err := ctx.Config.GetSystem().TempDir(r.Name) if err != nil { reserr = multierr.Append(reserr, err) } - if err := r.SyncBuildMetadata(repodir); err != nil { + if err := r.SyncBuildMetadata(ctx, repodir); err != nil { reserr = multierr.Append(reserr, err) } @@ -279,12 +277,12 @@ func GenerateRepository(p ...RepositoryOption) (*LuetSystemRepository, error) { generalRecipe := tree.NewCompilerRecipe(repodb) if c.FromRepository { - if err := LoadBuildTree(generalRecipe, repodb, c.config); err != nil { - Warning("errors while loading trees from repositories", err.Error()) + if err := LoadBuildTree(generalRecipe, repodb, c.context); err != nil { + c.context.Warning("errors while loading trees from repositories", err.Error()) } if err := repodb.Clone(tempTree); err != nil { - Warning("errors while cloning trees from repositories", err.Error()) + c.context.Warning("errors while cloning trees from repositories", err.Error()) } } @@ -317,7 +315,7 @@ func GenerateRepository(p ...RepositoryOption) (*LuetSystemRepository, error) { return nil } if _, err := runtimeTree.FindPackage(art.CompileSpec.Package); err != nil && art.CompileSpec.Package.Name != "" { - Debug("Adding", art.CompileSpec.Package.HumanReadableString(), "from metadata file", currentpath) + c.context.Debug("Adding", art.CompileSpec.Package.HumanReadableString(), "from metadata file", currentpath) if art.Runtime != nil && art.Runtime.Name != "" { runtimeTree.CreatePackage(art.Runtime) } else { @@ -350,7 +348,7 @@ func GenerateRepository(p ...RepositoryOption) (*LuetSystemRepository, error) { imagePrefix: c.ImagePrefix, } - if err := repo.initialize(c.Src); err != nil { + if err := repo.initialize(c.context, c.Src); err != nil { return nil, errors.Wrap(err, "while building repository artifact index") } @@ -380,8 +378,8 @@ func (r *LuetSystemRepository) SetPriority(n int) { r.LuetRepository.Priority = n } -func (r *LuetSystemRepository) initialize(src string) error { - generator, err := r.getGenerator() +func (r *LuetSystemRepository) initialize(ctx *types.Context, src string) error { + generator, err := r.getGenerator(ctx) if err != nil { return errors.Wrap(err, "while constructing repository generator") } @@ -523,12 +521,12 @@ func (r *LuetSystemRepository) BumpRevision(repospec string, resetRevision bool) // AddMetadata adds the repository serialized content into the metadata key of the repository // It writes the serialized content to repospec, and writes the repository.meta.yaml file into dst -func (r *LuetSystemRepository) AddMetadata(repospec, dst string) (*artifact.PackageArtifact, error) { +func (r *LuetSystemRepository) AddMetadata(ctx *types.Context, repospec, dst string) (*artifact.PackageArtifact, error) { // Create Metadata struct and serialized repository meta, serialized := r.Serialize() // Create metadata file and repository file - metaTmpDir, err := config.LuetCfg.GetSystem().TempDir("metadata") + metaTmpDir, err := ctx.Config.GetSystem().TempDir("metadata") defer os.RemoveAll(metaTmpDir) // clean up if err != nil { return nil, errors.Wrap(err, "Error met while creating tempdir for metadata") @@ -560,9 +558,9 @@ func (r *LuetSystemRepository) AddMetadata(repospec, dst string) (*artifact.Pack // AddTree adds a tree.Builder with the given key to the repository. // It will generate an artifact which will be then embedded in the repository manifest // It returns the generated artifacts and an error -func (r *LuetSystemRepository) AddTree(t tree.Builder, dst, key string, f LuetRepositoryFile) (*artifact.PackageArtifact, error) { +func (r *LuetSystemRepository) AddTree(ctx *types.Context, t tree.Builder, dst, key string, f LuetRepositoryFile) (*artifact.PackageArtifact, error) { // Create tree and repository file - archive, err := config.LuetCfg.GetSystem().TempDir("archive") + archive, err := ctx.Config.GetSystem().TempDir("archive") if err != nil { return nil, errors.Wrap(err, "Error met while creating tempdir for archive") } @@ -649,17 +647,18 @@ type RepositoryGenerator interface { Initialize(string, pkg.PackageDatabase) ([]*artifact.PackageArtifact, error) } -func (r *LuetSystemRepository) getGenerator() (RepositoryGenerator, error) { +func (r *LuetSystemRepository) getGenerator(ctx *types.Context) (RepositoryGenerator, error) { var rg RepositoryGenerator switch r.GetType() { case DiskRepositoryType, HttpRepositoryType: - rg = &localRepositoryGenerator{} + rg = &localRepositoryGenerator{context: ctx} case DockerRepositoryType: rg = &dockerRepositoryGenerator{ b: r.Backend, imagePrefix: r.imagePrefix, imagePush: r.PushImages, force: r.ForcePush, + context: ctx, } default: return nil, errors.New("invalid repository type") @@ -668,8 +667,8 @@ func (r *LuetSystemRepository) getGenerator() (RepositoryGenerator, error) { } // Write writes the repository metadata to the supplied destination -func (r *LuetSystemRepository) Write(dst string, resetRevision, force bool) error { - rg, err := r.getGenerator() +func (r *LuetSystemRepository) Write(ctx *types.Context, dst string, resetRevision, force bool) error { + rg, err := r.getGenerator(ctx) if err != nil { return err } @@ -677,16 +676,16 @@ func (r *LuetSystemRepository) Write(dst string, resetRevision, force bool) erro return rg.Generate(r, dst, resetRevision) } -func (r *LuetSystemRepository) Client() Client { +func (r *LuetSystemRepository) Client(ctx *types.Context) Client { switch r.GetType() { case DiskRepositoryType: - return client.NewLocalClient(client.RepoData{Urls: r.GetUrls()}) + return client.NewLocalClient(client.RepoData{Urls: r.GetUrls()}, ctx) case HttpRepositoryType: return client.NewHttpClient( client.RepoData{ Urls: r.GetUrls(), Authentication: r.GetAuthentication(), - }) + }, ctx) case DockerRepositoryType: return client.NewDockerClient( @@ -694,7 +693,7 @@ func (r *LuetSystemRepository) Client() Client { Urls: r.GetUrls(), Authentication: r.GetAuthentication(), Verify: r.Verify, - }) + }, ctx) } return nil } @@ -736,14 +735,14 @@ func (r *LuetSystemRepository) getRepoFile(c Client, key string) (*artifact.Pack } -func (r *LuetSystemRepository) SyncBuildMetadata(path string) error { +func (r *LuetSystemRepository) SyncBuildMetadata(ctx *types.Context, path string) error { - repo, err := r.Sync(false) + repo, err := r.Sync(ctx, false) if err != nil { return errors.Wrap(err, "while syncronizing repository") } - c := repo.Client() + c := repo.Client(ctx) if c == nil { return errors.New("no client could be generated from repository") } @@ -755,7 +754,7 @@ func (r *LuetSystemRepository) SyncBuildMetadata(path string) error { defer os.RemoveAll(a.Path) - if err := a.Unpack(filepath.Join(path, "tree"), false); err != nil { + if err := a.Unpack(ctx, filepath.Join(path, "tree"), false); err != nil { return errors.Wrapf(err, "while unpacking: %s", REPOFILE_COMPILER_TREE_KEY) } @@ -773,13 +772,12 @@ func (r *LuetSystemRepository) SyncBuildMetadata(path string) error { return nil } -func (r *LuetSystemRepository) Sync(force bool) (*LuetSystemRepository, error) { +func (r *LuetSystemRepository) Sync(ctx *types.Context, force bool) (*LuetSystemRepository, error) { var repoUpdated bool = false var treefs, metafs string - aurora := GetAurora() - Debug("Sync of the repository", r.Name, "in progress...") - c := r.Client() + ctx.Debug("Sync of the repository", r.Name, "in progress...") + c := r.Client(ctx) if c == nil { return nil, errors.New("no client could be generated from repository") } @@ -787,10 +785,10 @@ func (r *LuetSystemRepository) Sync(force bool) (*LuetSystemRepository, error) { // Retrieve remote repository.yaml for retrieve revision and date file, err := c.DownloadFile(REPOSITORY_SPECFILE) if err != nil { - return nil, errors.Wrap(err, "While downloading "+REPOSITORY_SPECFILE) + return nil, errors.Wrap(err, "while downloading "+REPOSITORY_SPECFILE) } - repobasedir := config.LuetCfg.GetSystem().GetRepoDatabaseDirPath(r.GetName()) + repobasedir := ctx.Config.GetSystem().GetRepoDatabaseDirPath(r.GetName()) downloadedRepoMeta, err := r.ReadSpecFile(file) if err != nil { return nil, err @@ -821,11 +819,11 @@ func (r *LuetSystemRepository) Sync(force bool) (*LuetSystemRepository, error) { } } else { - treefs, err = config.LuetCfg.GetSystem().TempDir("treefs") + treefs, err = ctx.Config.GetSystem().TempDir("treefs") if err != nil { return nil, errors.Wrap(err, "Error met while creating tempdir for rootfs") } - metafs, err = config.LuetCfg.GetSystem().TempDir("metafs") + metafs, err = ctx.Config.GetSystem().TempDir("metafs") if err != nil { return nil, errors.Wrap(err, "Error met whilte creating tempdir for metafs") } @@ -840,7 +838,7 @@ func (r *LuetSystemRepository) Sync(force bool) (*LuetSystemRepository, error) { } defer os.Remove(treeFileArtifact.Path) - Debug("Tree tarball for the repository " + r.GetName() + " downloaded correctly.") + ctx.Debug("Tree tarball for the repository " + r.GetName() + " downloaded correctly.") metaFileArtifact, err := downloadedRepoMeta.getRepoFile(c, REPOFILE_META_KEY) if err != nil { @@ -848,7 +846,7 @@ func (r *LuetSystemRepository) Sync(force bool) (*LuetSystemRepository, error) { } defer os.Remove(metaFileArtifact.Path) - Debug("Metadata tarball for the repository " + r.GetName() + " downloaded correctly.") + ctx.Debug("Metadata tarball for the repository " + r.GetName() + " downloaded correctly.") if r.Cached { // Copy updated repository.yaml file to repo dir now that the tree is synced. @@ -861,9 +859,9 @@ func (r *LuetSystemRepository) Sync(force bool) (*LuetSystemRepository, error) { // Remove previous meta dir os.RemoveAll(metafs) } - Debug("Decompress tree of the repository " + r.Name + "...") + ctx.Debug("Decompress tree of the repository " + r.Name + "...") - err = treeFileArtifact.Unpack(treefs, true) + err = treeFileArtifact.Unpack(ctx, treefs, true) if err != nil { return nil, errors.Wrap(err, "Error met while unpacking tree") } @@ -871,22 +869,21 @@ func (r *LuetSystemRepository) Sync(force bool) (*LuetSystemRepository, error) { // FIXME: It seems that tar with only one file doesn't create destination // directory. I create directory directly for now. os.MkdirAll(metafs, os.ModePerm) - err = metaFileArtifact.Unpack(metafs, true) + err = metaFileArtifact.Unpack(ctx, metafs, true) if err != nil { return nil, errors.Wrap(err, "Error met while unpacking metadata") } tsec, _ := strconv.ParseInt(downloadedRepoMeta.GetLastUpdate(), 10, 64) - InfoC( - aurora.Bold( - aurora.Red(":house: Repository "+downloadedRepoMeta.GetName()+" revision: ")).String() + - aurora.Bold(aurora.Green(downloadedRepoMeta.GetRevision())).String() + " - " + - aurora.Bold(aurora.Green(time.Unix(tsec, 0).String())).String(), - ) + ctx.Info( + fmt.Sprintf(":house: Repository %s revision: %d (%s)", + downloadedRepoMeta.GetName(), + downloadedRepoMeta.GetRevision(), + time.Unix(tsec, 0).String())) } else { - Info("Repository", downloadedRepoMeta.GetName(), "is already up to date.") + ctx.Info("Repository", downloadedRepoMeta.GetName(), "is already up to date.") } meta, err := NewLuetSystemRepositoryMetadata( @@ -910,16 +907,11 @@ func (r *LuetSystemRepository) Sync(force bool) (*LuetSystemRepository, error) { // e.g. locally we can override the type (disk), or priority // while remotely it could be advertized differently r.fill(downloadedRepoMeta) - - InfoC( - aurora.Yellow(":information_source:").String() + - aurora.Magenta("Repository: ").String() + - aurora.Green(aurora.Bold(downloadedRepoMeta.GetName()).String()).String() + - aurora.Magenta(" Priority: ").String() + - aurora.Bold(aurora.Green(downloadedRepoMeta.GetPriority())).String() + - aurora.Magenta(" Type: ").String() + - aurora.Bold(aurora.Green(downloadedRepoMeta.GetType())).String(), - ) + ctx.Info( + fmt.Sprintf(":information_source: Repository: %s Priority: %d Type: %s", + downloadedRepoMeta.GetName(), + downloadedRepoMeta.GetPriority(), + downloadedRepoMeta.GetType())) return downloadedRepoMeta, nil } diff --git a/pkg/installer/repository_docker.go b/pkg/installer/repository_docker.go index 2d03972a..bc94cd57 100644 --- a/pkg/installer/repository_docker.go +++ b/pkg/installer/repository_docker.go @@ -24,14 +24,13 @@ import ( "strings" "time" + "github.com/mudler/luet/pkg/api/core/types" artifact "github.com/mudler/luet/pkg/api/core/types/artifact" "github.com/mudler/luet/pkg/bus" compiler "github.com/mudler/luet/pkg/compiler" "github.com/mudler/luet/pkg/compiler/backend" - "github.com/mudler/luet/pkg/config" "github.com/mudler/luet/pkg/helpers" "github.com/mudler/luet/pkg/helpers/docker" - . "github.com/mudler/luet/pkg/logger" pkg "github.com/mudler/luet/pkg/package" "github.com/pkg/errors" @@ -41,18 +40,19 @@ type dockerRepositoryGenerator struct { b compiler.CompilerBackend imagePrefix string imagePush, force bool + context *types.Context } func (l *dockerRepositoryGenerator) Initialize(path string, db pkg.PackageDatabase) ([]*artifact.PackageArtifact, error) { - Info("Generating docker images for packages in", l.imagePrefix) + l.context.Info("Generating docker images for packages in", l.imagePrefix) var art []*artifact.PackageArtifact var ff = func(currentpath string, info os.FileInfo, err error) error { if err != nil { - Debug("Skipping", info.Name(), err.Error()) + l.context.Debug("Skipping", info.Name(), err.Error()) return nil } if info.IsDir() { - Debug("Skipping directories") + l.context.Debug("Skipping directories") return nil } @@ -80,7 +80,7 @@ func (l *dockerRepositoryGenerator) Initialize(path string, db pkg.PackageDataba // We want to include packages that are ONLY referenced in the tree. // the ones which aren't should be deleted. (TODO: by another cli command?) if _, notfound := db.FindPackage(a.CompileSpec.Package); notfound != nil { - Debug(fmt.Sprintf("Package %s not found in tree. Ignoring it.", + l.context.Debug(fmt.Sprintf("Package %s not found in tree. Ignoring it.", a.CompileSpec.Package.HumanReadableString())) return nil } @@ -88,16 +88,16 @@ func (l *dockerRepositoryGenerator) Initialize(path string, db pkg.PackageDataba packageImage := fmt.Sprintf("%s:%s", l.imagePrefix, a.CompileSpec.GetPackage().ImageID()) if l.imagePush && l.b.ImageAvailable(packageImage) && !l.force { - Info("Image", packageImage, "already present, skipping. use --force-push to override") + l.context.Info("Image", packageImage, "already present, skipping. use --force-push to override") } else { - Info("Generating final image", packageImage, + l.context.Info("Generating final image", packageImage, "for package ", a.CompileSpec.GetPackage().HumanReadableString()) - if opts, err := a.GenerateFinalImage(packageImage, l.b, true); err != nil { + if opts, err := a.GenerateFinalImage(l.context, packageImage, l.b, true); err != nil { return errors.Wrap(err, "Failed generating metadata tree"+opts.ImageName) } } if l.imagePush { - if err := pushImage(l.b, packageImage, l.force); err != nil { + if err := pushImage(l.context, l.b, packageImage, l.force); err != nil { return errors.Wrapf(err, "Failed while pushing image: '%s'", packageImage) } } @@ -115,21 +115,21 @@ func (l *dockerRepositoryGenerator) Initialize(path string, db pkg.PackageDataba return art, nil } -func pushImage(b compiler.CompilerBackend, image string, force bool) error { +func pushImage(ctx *types.Context, b compiler.CompilerBackend, image string, force bool) error { if b.ImageAvailable(image) && !force { - Debug("Image", image, "already present, skipping") + ctx.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) - if opts, err := a.GenerateFinalImage(imageTree, d.b, false); err != nil { + d.context.Debug("Generating image", imageTree) + if opts, err := a.GenerateFinalImage(d.context, imageTree, d.b, false); err != nil { return errors.Wrap(err, "Failed generating metadata tree "+opts.ImageName) } if d.imagePush { - if err := pushImage(d.b, imageTree, true); err != nil { + if err := pushImage(d.context, d.b, imageTree, true); err != nil { return errors.Wrapf(err, "Failed while pushing image: '%s'", imageTree) } } @@ -138,7 +138,7 @@ func (d *dockerRepositoryGenerator) pushFileFromArtifact(a *artifact.PackageArti func (d *dockerRepositoryGenerator) pushRepoMetadata(repospec string, r *LuetSystemRepository) error { // create temp dir for metafile - metaDir, err := config.LuetCfg.GetSystem().TempDir("metadata") + metaDir, err := d.context.Config.GetSystem().TempDir("metadata") if err != nil { return errors.Wrap(err, "Error met while creating tempdir for metadata") } @@ -161,13 +161,13 @@ func (d *dockerRepositoryGenerator) pushRepoMetadata(repospec string, r *LuetSys func (d *dockerRepositoryGenerator) pushImageFromArtifact(a *artifact.PackageArtifact, b compiler.CompilerBackend, checkIfExists bool) error { // 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 - treeArchive, err := artifact.CreateArtifactForFile(a.Path) + treeArchive, err := artifact.CreateArtifactForFile(d.context, a.Path) if err != nil { return errors.Wrap(err, "failed generating checksums for tree") } imageTree := fmt.Sprintf("%s:%s", d.imagePrefix, docker.StripInvalidStringsFromImage(a.GetFileName())) if checkIfExists && d.imagePush && d.b.ImageAvailable(imageTree) && !d.force { - Info("Image", imageTree, "already present, skipping. use --force-push to override") + d.context.Info("Image", imageTree, "already present, skipping. use --force-push to override") return nil } else { return d.pushFileFromArtifact(treeArchive, imageTree) @@ -184,7 +184,7 @@ func (d *dockerRepositoryGenerator) Generate(r *LuetSystemRepository, imagePrefi r.LastUpdate = strconv.FormatInt(time.Now().Unix(), 10) - repoTemp, err := config.LuetCfg.GetSystem().TempDir("repo") + repoTemp, err := d.context.Config.GetSystem().TempDir("repo") if err != nil { return errors.Wrap(err, "error met while creating tempdir for repository") } @@ -207,7 +207,7 @@ func (d *dockerRepositoryGenerator) Generate(r *LuetSystemRepository, imagePrefi return err } - Info(fmt.Sprintf( + d.context.Info(fmt.Sprintf( "For repository %s creating revision %d and last update %s...", r.Name, r.Revision, r.LastUpdate, )) @@ -221,7 +221,7 @@ func (d *dockerRepositoryGenerator) Generate(r *LuetSystemRepository, imagePrefi }) // Create tree and repository file - a, err := r.AddTree(r.GetTree(), repoTemp, REPOFILE_TREE_KEY, NewDefaultTreeRepositoryFile()) + a, err := r.AddTree(d.context, r.GetTree(), repoTemp, REPOFILE_TREE_KEY, NewDefaultTreeRepositoryFile()) if err != nil { return errors.Wrap(err, "error met while adding runtime tree to repository") } @@ -232,7 +232,7 @@ func (d *dockerRepositoryGenerator) Generate(r *LuetSystemRepository, imagePrefi return errors.Wrap(err, "error met while pushing runtime tree") } - a, err = r.AddTree(r.BuildTree, repoTemp, REPOFILE_COMPILER_TREE_KEY, NewDefaultCompilerTreeRepositoryFile()) + a, err = r.AddTree(d.context, r.BuildTree, repoTemp, REPOFILE_COMPILER_TREE_KEY, NewDefaultCompilerTreeRepositoryFile()) if err != nil { return errors.Wrap(err, "error met while adding compiler tree to repository") } @@ -243,13 +243,13 @@ func (d *dockerRepositoryGenerator) Generate(r *LuetSystemRepository, imagePrefi } // create temp dir for metafile - metaDir, err := config.LuetCfg.GetSystem().TempDir("metadata") + metaDir, err := d.context.Config.GetSystem().TempDir("metadata") if err != nil { return errors.Wrap(err, "error met while creating tempdir for metadata") } defer os.RemoveAll(metaDir) // clean up - a, err = r.AddMetadata(repospec, metaDir) + a, err = r.AddMetadata(d.context, repospec, metaDir) if err != nil { return errors.Wrap(err, "failed adding Metadata file to repository") } diff --git a/pkg/installer/repository_local.go b/pkg/installer/repository_local.go index 04930367..a3d12bf8 100644 --- a/pkg/installer/repository_local.go +++ b/pkg/installer/repository_local.go @@ -24,26 +24,26 @@ import ( "strings" "time" + "github.com/mudler/luet/pkg/api/core/types" artifact "github.com/mudler/luet/pkg/api/core/types/artifact" - . "github.com/mudler/luet/pkg/logger" pkg "github.com/mudler/luet/pkg/package" "github.com/mudler/luet/pkg/bus" "github.com/pkg/errors" ) -type localRepositoryGenerator struct{} +type localRepositoryGenerator struct{ context *types.Context } func (l *localRepositoryGenerator) Initialize(path string, db pkg.PackageDatabase) ([]*artifact.PackageArtifact, error) { - return buildPackageIndex(path, db) + return buildPackageIndex(l.context, path, db) } -func buildPackageIndex(path string, db pkg.PackageDatabase) ([]*artifact.PackageArtifact, error) { +func buildPackageIndex(ctx *types.Context, path string, db pkg.PackageDatabase) ([]*artifact.PackageArtifact, error) { var art []*artifact.PackageArtifact var ff = func(currentpath string, info os.FileInfo, err error) error { if err != nil { - Debug("Failed walking", err.Error()) + ctx.Debug("Failed walking", err.Error()) return err } @@ -64,7 +64,7 @@ func buildPackageIndex(path string, db pkg.PackageDatabase) ([]*artifact.Package // We want to include packages that are ONLY referenced in the tree. // the ones which aren't should be deleted. (TODO: by another cli command?) if _, notfound := db.FindPackage(a.CompileSpec.GetPackage()); notfound != nil { - Debug(fmt.Sprintf("Package %s not found in tree. Ignoring it.", + ctx.Debug(fmt.Sprintf("Package %s not found in tree. Ignoring it.", a.CompileSpec.GetPackage().HumanReadableString())) return nil } @@ -83,7 +83,7 @@ func buildPackageIndex(path string, db pkg.PackageDatabase) ([]*artifact.Package } // Generate creates a Local luet repository -func (*localRepositoryGenerator) Generate(r *LuetSystemRepository, dst string, resetRevision bool) error { +func (g *localRepositoryGenerator) Generate(r *LuetSystemRepository, dst string, resetRevision bool) error { err := os.MkdirAll(dst, os.ModePerm) if err != nil { return err @@ -96,7 +96,7 @@ func (*localRepositoryGenerator) Generate(r *LuetSystemRepository, dst string, r return err } - Info(fmt.Sprintf( + g.context.Info(fmt.Sprintf( "Repository %s: creating revision %d and last update %s...", r.Name, r.Revision, r.LastUpdate, )) @@ -109,15 +109,15 @@ func (*localRepositoryGenerator) Generate(r *LuetSystemRepository, dst string, r Path: dst, }) - if _, err := r.AddTree(r.GetTree(), dst, REPOFILE_TREE_KEY, NewDefaultTreeRepositoryFile()); err != nil { + if _, err := r.AddTree(g.context, r.GetTree(), dst, REPOFILE_TREE_KEY, NewDefaultTreeRepositoryFile()); err != nil { return errors.Wrap(err, "error met while adding runtime tree to repository") } - if _, err := r.AddTree(r.BuildTree, dst, REPOFILE_COMPILER_TREE_KEY, NewDefaultCompilerTreeRepositoryFile()); err != nil { + if _, err := r.AddTree(g.context, r.BuildTree, dst, REPOFILE_COMPILER_TREE_KEY, NewDefaultCompilerTreeRepositoryFile()); err != nil { return errors.Wrap(err, "error met while adding compiler tree to repository") } - if _, err := r.AddMetadata(repospec, dst); err != nil { + if _, err := r.AddMetadata(g.context, repospec, dst); err != nil { return errors.Wrap(err, "failed adding Metadata file to repository") } diff --git a/pkg/installer/repository_options.go b/pkg/installer/repository_options.go index 75322c1d..023fde3e 100644 --- a/pkg/installer/repository_options.go +++ b/pkg/installer/repository_options.go @@ -16,8 +16,8 @@ package installer import ( + "github.com/mudler/luet/pkg/api/core/types" "github.com/mudler/luet/pkg/compiler" - "github.com/mudler/luet/pkg/config" pkg "github.com/mudler/luet/pkg/package" ) @@ -33,7 +33,7 @@ type RepositoryConfig struct { CompilerBackend compiler.CompilerBackend ImagePrefix string - config *config.LuetConfig + context *types.Context PushImages, Force, FromRepository, FromMetadata bool } @@ -51,9 +51,9 @@ func (cfg *RepositoryConfig) Apply(opts ...RepositoryOption) error { return nil } -func WithConfig(c *config.LuetConfig) func(cfg *RepositoryConfig) error { +func WithContext(c *types.Context) func(cfg *RepositoryConfig) error { return func(cfg *RepositoryConfig) error { - cfg.config = c + cfg.context = c return nil } } diff --git a/pkg/installer/repository_test.go b/pkg/installer/repository_test.go index da26e55a..4b43e4ec 100644 --- a/pkg/installer/repository_test.go +++ b/pkg/installer/repository_test.go @@ -28,6 +28,7 @@ import ( artifact "github.com/mudler/luet/pkg/api/core/types/artifact" "github.com/mudler/luet/pkg/compiler" backend "github.com/mudler/luet/pkg/compiler/backend" + "github.com/mudler/luet/pkg/compiler/types/options" compilerspec "github.com/mudler/luet/pkg/compiler/types/spec" "github.com/mudler/luet/pkg/helpers" fileHelper "github.com/mudler/luet/pkg/helpers/file" @@ -49,14 +50,16 @@ func dockerStubRepo(tmpdir, tree, image string, push, force bool) (*LuetSystemRe WithSource(tmpdir), WithTree(tree), WithDatabase(pkg.NewInMemoryDatabase(false)), - WithCompilerBackend(backend.NewSimpleDockerBackend()), + WithCompilerBackend(backend.NewSimpleDockerBackend(types.NewContext())), WithImagePrefix(image), WithPushImages(push), + WithContext(types.NewContext()), WithForce(force)) } var _ = Describe("Repository", func() { Context("Generation", func() { + ctx := types.NewContext() It("Generate repository metadata", func() { tmpdir, err := ioutil.TempDir("", "tree") @@ -70,7 +73,7 @@ var _ = Describe("Repository", func() { Expect(len(generalRecipe.GetDatabase().GetPackages())).To(Equal(3)) - compiler := compiler.NewLuetCompiler(backend.NewSimpleDockerBackend(), generalRecipe.GetDatabase()) + compiler := compiler.NewLuetCompiler(backend.NewSimpleDockerBackend(ctx), generalRecipe.GetDatabase()) spec, err := compiler.FromPackage(&pkg.DefaultPackage{Name: "b", Category: "test", Version: "1.0"}) Expect(err).ToNot(HaveOccurred()) @@ -110,7 +113,7 @@ var _ = Describe("Repository", func() { Expect(fileHelper.Exists(spec.Rel(REPOSITORY_SPECFILE))).ToNot(BeTrue()) Expect(fileHelper.Exists(spec.Rel(TREE_TARBALL + ".gz"))).ToNot(BeTrue()) Expect(fileHelper.Exists(spec.Rel(REPOSITORY_METAFILE + ".tar"))).ToNot(BeTrue()) - err = repo.Write(tmpdir, false, true) + err = repo.Write(ctx, tmpdir, false, true) Expect(err).ToNot(HaveOccurred()) Expect(fileHelper.Exists(spec.Rel(REPOSITORY_SPECFILE))).To(BeTrue()) @@ -137,11 +140,11 @@ var _ = Describe("Repository", func() { Expect(len(generalRecipe2.GetDatabase().GetPackages())).To(Equal(1)) Expect(len(generalRecipe.GetDatabase().GetPackages())).To(Equal(3)) - compiler2 := compiler.NewLuetCompiler(backend.NewSimpleDockerBackend(), generalRecipe2.GetDatabase()) + compiler2 := compiler.NewLuetCompiler(backend.NewSimpleDockerBackend(ctx), generalRecipe2.GetDatabase(), options.WithContext(types.NewContext())) spec2, err := compiler2.FromPackage(&pkg.DefaultPackage{Name: "alpine", Category: "seed", Version: "1.0"}) Expect(err).ToNot(HaveOccurred()) - compiler := compiler.NewLuetCompiler(backend.NewSimpleDockerBackend(), generalRecipe.GetDatabase()) + compiler := compiler.NewLuetCompiler(backend.NewSimpleDockerBackend(ctx), generalRecipe.GetDatabase(), options.WithContext(types.NewContext())) spec, err := compiler.FromPackage(&pkg.DefaultPackage{Name: "b", Category: "test", Version: "1.0"}) Expect(err).ToNot(HaveOccurred()) @@ -190,7 +193,7 @@ var _ = Describe("Repository", func() { Expect(fileHelper.Exists(spec.Rel(REPOSITORY_SPECFILE))).ToNot(BeTrue()) Expect(fileHelper.Exists(spec.Rel(TREE_TARBALL + ".gz"))).ToNot(BeTrue()) Expect(fileHelper.Exists(spec.Rel(REPOSITORY_METAFILE + ".tar"))).ToNot(BeTrue()) - err = repo.Write(tmpdir, false, true) + err = repo.Write(ctx, tmpdir, false, true) Expect(err).ToNot(HaveOccurred()) Expect(fileHelper.Exists(spec.Rel(REPOSITORY_SPECFILE))).To(BeTrue()) @@ -206,7 +209,7 @@ urls: - "`+tmpdir+`" `), pkg.NewInMemoryDatabase(false)) Expect(err).ToNot(HaveOccurred()) - repos, err := repository.Sync(true) + repos, err := repository.Sync(ctx, true) Expect(err).ToNot(HaveOccurred()) _, err = repos.GetTree().GetDatabase().FindPackage(spec.GetPackage()) @@ -234,11 +237,11 @@ urls: Expect(len(generalRecipe2.GetDatabase().GetPackages())).To(Equal(1)) Expect(len(generalRecipe.GetDatabase().GetPackages())).To(Equal(3)) - compiler2 := compiler.NewLuetCompiler(backend.NewSimpleDockerBackend(), generalRecipe2.GetDatabase()) + compiler2 := compiler.NewLuetCompiler(backend.NewSimpleDockerBackend(ctx), generalRecipe2.GetDatabase(), options.WithContext(ctx)) spec2, err := compiler2.FromPackage(&pkg.DefaultPackage{Name: "alpine", Category: "seed", Version: "1.0"}) Expect(err).ToNot(HaveOccurred()) - compiler := compiler.NewLuetCompiler(backend.NewSimpleDockerBackend(), generalRecipe.GetDatabase()) + compiler := compiler.NewLuetCompiler(backend.NewSimpleDockerBackend(ctx), generalRecipe.GetDatabase(), options.WithContext(ctx)) spec, err := compiler.FromPackage(&pkg.DefaultPackage{Name: "b", Category: "test", Version: "1.0"}) Expect(err).ToNot(HaveOccurred()) @@ -291,6 +294,7 @@ urls: WithSource(tmpdir), FromMetadata(true), // Enabling from metadata makes the package visible WithTree("../../tests/fixtures/buildable"), + WithContext(ctx), WithDatabase(pkg.NewInMemoryDatabase(false)), ) Expect(err).ToNot(HaveOccurred()) @@ -298,7 +302,7 @@ urls: Expect(fileHelper.Exists(spec.Rel(REPOSITORY_SPECFILE))).ToNot(BeTrue()) Expect(fileHelper.Exists(spec.Rel(TREE_TARBALL + ".gz"))).ToNot(BeTrue()) Expect(fileHelper.Exists(spec.Rel(REPOSITORY_METAFILE + ".tar"))).ToNot(BeTrue()) - err = repo.Write(tmpdir, false, true) + err = repo.Write(ctx, tmpdir, false, true) Expect(err).ToNot(HaveOccurred()) Expect(fileHelper.Exists(spec.Rel(REPOSITORY_SPECFILE))).To(BeTrue()) @@ -314,7 +318,7 @@ urls: - "`+tmpdir+`" `), pkg.NewInMemoryDatabase(false)) Expect(err).ToNot(HaveOccurred()) - repos, err := repository.Sync(true) + repos, err := repository.Sync(ctx, true) Expect(err).ToNot(HaveOccurred()) _, err = repos.GetTree().GetDatabase().FindPackage(spec.GetPackage()) @@ -345,15 +349,16 @@ urls: }) Context("Docker repository", func() { repoImage := os.Getenv("UNIT_TEST_DOCKER_IMAGE_REPOSITORY") - + ctx := types.NewContext() BeforeEach(func() { if repoImage == "" { Skip("UNIT_TEST_DOCKER_IMAGE_REPOSITORY not specified") } + ctx = types.NewContext() }) It("generates images", func() { - b := backend.NewSimpleDockerBackend() + b := backend.NewSimpleDockerBackend(ctx) tmpdir, err := ioutil.TempDir("", "tree") Expect(err).ToNot(HaveOccurred()) defer os.RemoveAll(tmpdir) // clean up @@ -365,7 +370,8 @@ urls: Expect(len(generalRecipe.GetDatabase().GetPackages())).To(Equal(3)) - localcompiler := compiler.NewLuetCompiler(backend.NewSimpleDockerBackend(), generalRecipe.GetDatabase()) + localcompiler := compiler.NewLuetCompiler( + backend.NewSimpleDockerBackend(ctx), generalRecipe.GetDatabase(), options.WithContext(ctx)) spec, err := localcompiler.FromPackage(&pkg.DefaultPackage{Name: "b", Category: "test", Version: "1.0"}) Expect(err).ToNot(HaveOccurred()) @@ -392,7 +398,7 @@ urls: Expect(fileHelper.Exists(spec.Rel(REPOSITORY_SPECFILE))).ToNot(BeTrue()) Expect(fileHelper.Exists(spec.Rel(TREE_TARBALL + ".gz"))).ToNot(BeTrue()) Expect(fileHelper.Exists(spec.Rel(REPOSITORY_METAFILE + ".tar"))).ToNot(BeTrue()) - err = repo.Write(repoImage, false, true) + err = repo.Write(ctx, repoImage, false, true) Expect(err).ToNot(HaveOccurred()) Expect(b.ImageAvailable(fmt.Sprintf("%s:%s", repoImage, "tree.tar.gz"))).To(BeTrue()) @@ -404,7 +410,7 @@ urls: Expect(err).ToNot(HaveOccurred()) defer os.RemoveAll(extracted) // clean up - c := repo.Client() + c := repo.Client(ctx) f, err := c.DownloadFile("repository.yaml") Expect(err).ToNot(HaveOccurred()) @@ -422,12 +428,12 @@ urls: }) Expect(err).ToNot(HaveOccurred()) - Expect(a.Unpack(extracted, false)).ToNot(HaveOccurred()) + Expect(a.Unpack(ctx, extracted, false)).ToNot(HaveOccurred()) Expect(fileHelper.Read(filepath.Join(extracted, "test6"))).To(Equal("artifact6\n")) }) It("generates images of virtual packages", func() { - b := backend.NewSimpleDockerBackend() + b := backend.NewSimpleDockerBackend(ctx) tmpdir, err := ioutil.TempDir("", "tree") Expect(err).ToNot(HaveOccurred()) defer os.RemoveAll(tmpdir) // clean up @@ -439,7 +445,8 @@ urls: Expect(len(generalRecipe.GetDatabase().GetPackages())).To(Equal(5)) - localcompiler := compiler.NewLuetCompiler(backend.NewSimpleDockerBackend(), generalRecipe.GetDatabase()) + localcompiler := compiler.NewLuetCompiler( + backend.NewSimpleDockerBackend(ctx), generalRecipe.GetDatabase(), options.WithContext(ctx)) spec, err := localcompiler.FromPackage(&pkg.DefaultPackage{Name: "a", Category: "test", Version: "1.99"}) Expect(err).ToNot(HaveOccurred()) @@ -463,7 +470,7 @@ urls: Expect(fileHelper.Exists(spec.Rel(REPOSITORY_SPECFILE))).ToNot(BeTrue()) Expect(fileHelper.Exists(spec.Rel(TREE_TARBALL + ".gz"))).ToNot(BeTrue()) Expect(fileHelper.Exists(spec.Rel(REPOSITORY_METAFILE + ".tar"))).ToNot(BeTrue()) - err = repo.Write(repoImage, false, true) + err = repo.Write(ctx, repoImage, false, true) Expect(err).ToNot(HaveOccurred()) Expect(b.ImageAvailable(fmt.Sprintf("%s:%s", repoImage, "tree.tar.gz"))).To(BeTrue()) @@ -475,7 +482,7 @@ urls: Expect(err).ToNot(HaveOccurred()) defer os.RemoveAll(extracted) // clean up - c := repo.Client() + c := repo.Client(ctx) f, err := c.DownloadFile("repository.yaml") Expect(err).ToNot(HaveOccurred()) @@ -493,7 +500,7 @@ urls: }) Expect(err).ToNot(HaveOccurred()) - Expect(a.Unpack(extracted, false)).ToNot(HaveOccurred()) + Expect(a.Unpack(ctx, extracted, false)).ToNot(HaveOccurred()) Expect(fileHelper.DirectoryIsEmpty(extracted)).To(BeFalse()) content, err := ioutil.ReadFile(filepath.Join(extracted, ".virtual")) diff --git a/pkg/installer/system.go b/pkg/installer/system.go index 6e37b4e5..2db4479e 100644 --- a/pkg/installer/system.go +++ b/pkg/installer/system.go @@ -4,9 +4,9 @@ import ( "sync" "github.com/hashicorp/go-multierror" + "github.com/mudler/luet/pkg/api/core/types" "github.com/mudler/luet/pkg/helpers" fileHelper "github.com/mudler/luet/pkg/helpers/file" - . "github.com/mudler/luet/pkg/logger" pkg "github.com/mudler/luet/pkg/package" "github.com/mudler/luet/pkg/tree" ) @@ -22,32 +22,30 @@ func (s *System) World() (pkg.Packages, error) { return s.Database.World(), nil } -type templatedata map[string]interface{} - -func (s *System) ExecuteFinalizers(packs []pkg.Package) error { +func (s *System) ExecuteFinalizers(ctx *types.Context, packs []pkg.Package) error { var errs error executedFinalizer := map[string]bool{} for _, p := range packs { if fileHelper.Exists(p.Rel(tree.FinalizerFile)) { out, err := helpers.RenderFiles(helpers.ChartFile(p.Rel(tree.FinalizerFile)), p.Rel(pkg.PackageDefinitionFile)) if err != nil { - Warning("Failed rendering finalizer for ", p.HumanReadableString(), err.Error()) + ctx.Warning("Failed rendering finalizer for ", p.HumanReadableString(), err.Error()) errs = multierror.Append(errs, err) continue } if _, exists := executedFinalizer[p.GetFingerPrint()]; !exists { executedFinalizer[p.GetFingerPrint()] = true - Info("Executing finalizer for " + p.HumanReadableString()) + ctx.Info("Executing finalizer for " + p.HumanReadableString()) finalizer, err := NewLuetFinalizerFromYaml([]byte(out)) if err != nil { - Warning("Failed reading finalizer for ", p.HumanReadableString(), err.Error()) + ctx.Warning("Failed reading finalizer for ", p.HumanReadableString(), err.Error()) errs = multierror.Append(errs, err) continue } - err = finalizer.RunInstall(s) + err = finalizer.RunInstall(ctx, s) if err != nil { - Warning("Failed running finalizer for ", p.HumanReadableString(), err.Error()) + ctx.Warning("Failed running finalizer for ", p.HumanReadableString(), err.Error()) errs = multierror.Append(errs, err) continue } @@ -79,15 +77,11 @@ func (s *System) Clean() { } func (s *System) ExistsPackageFile(file string) (bool, pkg.Package, error) { - Debug("Checking if file ", file, "belongs to any package") s.buildFileIndex() s.Lock() defer s.Unlock() if p, exists := s.fileIndex[file]; exists { - Debug(file, "belongs already to", p.HumanReadableString()) - return exists, p, nil } - Debug(file, "doesn't belong to any package") return false, nil, nil } diff --git a/pkg/logger/logger.go b/pkg/logger/logger.go deleted file mode 100644 index 88c5676b..00000000 --- a/pkg/logger/logger.go +++ /dev/null @@ -1,329 +0,0 @@ -package logger - -import ( - "fmt" - "os" - "path" - "regexp" - "runtime" - "strings" - - "sync" - - . "github.com/mudler/luet/pkg/config" - - "github.com/kyokomi/emoji" - . "github.com/logrusorgru/aurora" - "github.com/pterm/pterm" - "go.uber.org/zap" - "go.uber.org/zap/zapcore" -) - -var s *pterm.SpinnerPrinter -var z *zap.Logger = nil -var aurora Aurora = nil -var spinnerLock = sync.Mutex{} - -func NewSpinner() { - if s == nil { - s = pterm.DefaultSpinner.WithShowTimer(false).WithRemoveWhenDone(true) - } -} - -func InitAurora() { - if aurora == nil { - aurora = NewAurora(LuetCfg.GetLogging().Color) - } -} - -func GetAurora() Aurora { - return aurora -} - -func NoColor() { - pterm.DisableColor() -} - -func Ask() bool { - var input string - - Info("Do you want to continue with this operation? [y/N]: ") - _, err := fmt.Scanln(&input) - if err != nil { - return false - } - input = strings.ToLower(input) - - if input == "y" || input == "yes" { - return true - } - return false -} - -func ZapLogger() error { - var err error - if z == nil { - // TODO: test permission for open logfile. - cfg := zap.NewProductionConfig() - cfg.OutputPaths = []string{LuetCfg.GetLogging().Path} - cfg.Level = level2AtomicLevel(LuetCfg.GetLogging().Level) - cfg.ErrorOutputPaths = []string{} - if LuetCfg.GetLogging().JsonFormat { - cfg.Encoding = "json" - } else { - cfg.Encoding = "console" - } - cfg.DisableCaller = true - cfg.DisableStacktrace = true - cfg.EncoderConfig.TimeKey = "time" - cfg.EncoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder - - z, err = cfg.Build() - if err != nil { - fmt.Fprint(os.Stderr, "Error on initialize file logger: "+err.Error()+"\n") - return err - } - } - - return nil -} - -func Spinner(i int) { - spinnerLock.Lock() - defer spinnerLock.Unlock() - var confLevel int - if LuetCfg.GetGeneral().Debug { - confLevel = 3 - } else { - confLevel = level2Number(LuetCfg.GetLogging().Level) - } - if 2 > confLevel { - return - } - if i > 43 { - i = 43 - } - - if s != nil && !s.IsActive { - // s.UpdateCharSet(spinner.CharSets[i]) - //s.Start() // Start the spinner - // time.Sleep(second) - // for i := 14; i > 0; i-- { - // if i > 1 { - // introSpinner.UpdateText("Waiting for " + strconv.Itoa(i) + " seconds...") - // } else { - // introSpinner.UpdateText("Waiting for " + strconv.Itoa(i) + " second...") - // } - // time.Sleep(second) - // } - // s = introSpinner - s, _ = s.Start() - //introSpinner.Stop() - } -} - -func Screen(text string) { - pterm.DefaultHeader.WithBackgroundStyle(pterm.NewStyle(pterm.BgLightBlue)).WithMargin(2).Println(text) - //pterm.DefaultCenter.Print(pterm.DefaultHeader.WithFullWidth().WithBackgroundStyle(pterm.NewStyle(pterm.BgLightBlue)).WithMargin(10).Sprint(text)) -} - -func SpinnerText(suffix, prefix string) { - if s != nil { - spinnerLock.Lock() - defer spinnerLock.Unlock() - if LuetCfg.GetGeneral().Debug { - fmt.Println(fmt.Sprintf("%s %s", - Bold(Cyan(prefix)).String(), - Bold(Magenta(suffix)).BgBlack().String(), - )) - } else { - s.UpdateText(suffix + prefix) - - } - } -} - -func SpinnerStop() { - spinnerLock.Lock() - defer spinnerLock.Unlock() - var confLevel int - if LuetCfg.GetGeneral().Debug { - confLevel = 3 - } else { - confLevel = level2Number(LuetCfg.GetLogging().Level) - } - if 2 > confLevel { - return - } - if s != nil { - s.Success() - } -} - -func level2Number(level string) int { - switch level { - case "error": - return 0 - case "warning": - return 1 - case "info": - return 2 - case "success": - return 3 - default: - return 4 - } -} - -func log2File(level, msg string) { - switch level { - case "error": - z.Error(msg) - case "warning": - z.Warn(msg) - case "info", "success": - z.Info(msg) - default: - z.Debug(msg) - } -} - -func level2AtomicLevel(level string) zap.AtomicLevel { - switch level { - case "error": - return zap.NewAtomicLevelAt(zap.ErrorLevel) - case "warning": - return zap.NewAtomicLevelAt(zap.WarnLevel) - case "info", "success": - return zap.NewAtomicLevelAt(zap.InfoLevel) - default: - return zap.NewAtomicLevelAt(zap.DebugLevel) - } -} - -func init() { - InitAurora() -} - -func Msg(level string, withoutColor, ln bool, msg ...interface{}) { - var message string - var confLevel, msgLevel int - - if LuetCfg.GetGeneral().Debug { - confLevel = 3 - } else { - confLevel = level2Number(LuetCfg.GetLogging().Level) - } - msgLevel = level2Number(level) - if msgLevel > confLevel { - return - } - - for _, m := range msg { - message += " " + fmt.Sprintf("%v", m) - } - - var levelMsg string - - if withoutColor || !LuetCfg.GetLogging().Color { - levelMsg = message - } else { - switch level { - case "warning": - levelMsg = Yellow(":construction: warning" + message).BgBlack().String() - case "debug": - levelMsg = White(message).BgBlack().String() - case "info", "success": - levelMsg = message - case "error": - levelMsg = Red(message).String() - } - } - - if LuetCfg.GetLogging().EnableEmoji { - levelMsg = emoji.Sprint(levelMsg) - } else { - re := regexp.MustCompile(`[:][\w]+[:]`) - levelMsg = re.ReplaceAllString(levelMsg, "") - } - - if z != nil { - log2File(level, message) - } - - if ln { - switch level { - case "info": - pterm.Info.Println(levelMsg) - case "success": - pterm.Success.Println(levelMsg) - case "warning": - pterm.Warning.Println(levelMsg) - case "error": - pterm.Error.Println(levelMsg) - case "fatal": - pterm.Fatal.Println(levelMsg) - default: - fmt.Println(levelMsg) - } - // - } else { - switch level { - case "success": - pterm.Success.Print(levelMsg) - case "info": - pterm.Info.Print(levelMsg) - case "warning": - pterm.Warning.Print(levelMsg) - case "error": - pterm.Error.Print(levelMsg) - case "fatal": - pterm.Fatal.Print(levelMsg) - default: - fmt.Print(levelMsg) - } - - } - -} - -func Warning(mess ...interface{}) { - Msg("warning", false, true, mess...) - if LuetCfg.GetGeneral().FatalWarns { - os.Exit(2) - } -} - -func Debug(mess ...interface{}) { - pc, file, line, ok := runtime.Caller(1) - if ok { - mess = append([]interface{}{fmt.Sprintf("DEBUG (%s:#%d:%v)", - path.Base(file), line, runtime.FuncForPC(pc).Name())}, mess...) - } - Msg("debug", false, true, mess...) -} - -func DebugC(mess ...interface{}) { - Msg("debug", true, true, mess...) -} - -func Info(mess ...interface{}) { - Msg("info", false, true, mess...) -} - -func Success(mess ...interface{}) { - Msg("success", false, true, mess...) -} - -func InfoC(mess ...interface{}) { - Msg("info", true, true, mess...) -} - -func Error(mess ...interface{}) { - Msg("error", false, true, mess...) -} - -func Fatal(mess ...interface{}) { - Error(mess...) - os.Exit(1) -} diff --git a/pkg/package/package_suite_test.go b/pkg/package/package_suite_test.go index c7d7130b..edca8444 100644 --- a/pkg/package/package_suite_test.go +++ b/pkg/package/package_suite_test.go @@ -18,14 +18,11 @@ package pkg_test import ( "testing" - . "github.com/mudler/luet/cmd/util" - . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) func TestSolver(t *testing.T) { RegisterFailHandler(Fail) - LoadConfig() RunSpecs(t, "Package Suite") } diff --git a/pkg/repository/loader.go b/pkg/repository/loader.go deleted file mode 100644 index dcb8b024..00000000 --- a/pkg/repository/loader.go +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright © 2019 Ettore Di Giacinto -// Daniele Rondina -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License along -// with this program; if not, see . - -package repository - -import ( - "io/ioutil" - "path" - "path/filepath" - "regexp" - - "github.com/mudler/luet/pkg/api/core/types" - - . "github.com/mudler/luet/pkg/config" - . "github.com/mudler/luet/pkg/logger" -) - -func LoadRepositories(c *LuetConfig) error { - var regexRepo = regexp.MustCompile(`.yml$|.yaml$`) - var err error - rootfs := "" - - // Respect the rootfs param on read repositories - if !c.ConfigFromHost { - rootfs, err = c.GetSystem().GetRootFsAbs() - if err != nil { - return err - } - } - - for _, rdir := range c.RepositoriesConfDir { - - rdir = filepath.Join(rootfs, rdir) - - Debug("Parsing Repository Directory", rdir, "...") - - files, err := ioutil.ReadDir(rdir) - if err != nil { - Debug("Skip dir", rdir, ":", err.Error()) - continue - } - - for _, file := range files { - if file.IsDir() { - continue - } - - if !regexRepo.MatchString(file.Name()) { - Debug("File", file.Name(), "skipped.") - continue - } - - content, err := ioutil.ReadFile(path.Join(rdir, file.Name())) - if err != nil { - Warning("On read file", file.Name(), ":", err.Error()) - Warning("File", file.Name(), "skipped.") - continue - } - - r, err := types.LoadRepository(content) - if err != nil { - Warning("On parse file", file.Name(), ":", err.Error()) - Warning("File", file.Name(), "skipped.") - continue - } - - if r.Name == "" || len(r.Urls) == 0 || r.Type == "" { - Warning("Invalid repository ", file.Name()) - Warning("File", file.Name(), "skipped.") - continue - } - - c.AddSystemRepository(*r) - } - } - return nil -} diff --git a/pkg/repository/repository_test.go b/pkg/repository/repository_test.go deleted file mode 100644 index 9ee94d60..00000000 --- a/pkg/repository/repository_test.go +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright © 2019 Ettore Di Giacinto -// Daniele Rondina -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License along -// with this program; if not, see . - -package repository_test - -import ( - . "github.com/mudler/luet/pkg/config" - . "github.com/mudler/luet/pkg/repository" - - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" -) - -var _ = Describe("Repository", func() { - Context("Load Repository1", func() { - cfg := &LuetConfig{} - cfg.RepositoriesConfDir = []string{ - "../../tests/fixtures/repos.conf.d", - } - err := LoadRepositories(cfg) - - It("Chec Load Repository 1", func() { - Expect(err).Should(BeNil()) - Expect(len(cfg.SystemRepositories)).Should(Equal(2)) - Expect(cfg.SystemRepositories[0].Name).Should(Equal("test1")) - Expect(cfg.SystemRepositories[0].Priority).Should(Equal(999)) - Expect(cfg.SystemRepositories[0].Type).Should(Equal("disk")) - Expect(len(cfg.SystemRepositories[0].Urls)).Should(Equal(1)) - Expect(cfg.SystemRepositories[0].Urls[0]).Should(Equal("tests/repos/test1")) - }) - - It("Chec Load Repository 2", func() { - Expect(err).Should(BeNil()) - Expect(len(cfg.SystemRepositories)).Should(Equal(2)) - Expect(cfg.SystemRepositories[1].Name).Should(Equal("test2")) - Expect(cfg.SystemRepositories[1].Priority).Should(Equal(1000)) - Expect(cfg.SystemRepositories[1].Type).Should(Equal("disk")) - Expect(len(cfg.SystemRepositories[1].Urls)).Should(Equal(1)) - Expect(cfg.SystemRepositories[1].Urls[0]).Should(Equal("tests/repos/test2")) - }) - }) -}) diff --git a/pkg/solver/solver_suite_test.go b/pkg/solver/solver_suite_test.go index 61b507f3..c7548c56 100644 --- a/pkg/solver/solver_suite_test.go +++ b/pkg/solver/solver_suite_test.go @@ -18,14 +18,11 @@ package solver_test import ( "testing" - . "github.com/mudler/luet/cmd/util" - . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) func TestSolver(t *testing.T) { RegisterFailHandler(Fail) - LoadConfig() RunSpecs(t, "Solver Suite") } diff --git a/pkg/spectooling/spectooling_suite_test.go b/pkg/spectooling/spectooling_suite_test.go index 94f62b80..9d0f680d 100644 --- a/pkg/spectooling/spectooling_suite_test.go +++ b/pkg/spectooling/spectooling_suite_test.go @@ -19,14 +19,11 @@ package spectooling_test import ( "testing" - . "github.com/mudler/luet/cmd/util" - . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) func TestSolver(t *testing.T) { RegisterFailHandler(Fail) - LoadConfig() RunSpecs(t, "Spec Tooling Suite") } diff --git a/pkg/tree/tree_suite_test.go b/pkg/tree/tree_suite_test.go index b602e4aa..d75ebaf3 100644 --- a/pkg/tree/tree_suite_test.go +++ b/pkg/tree/tree_suite_test.go @@ -18,14 +18,11 @@ package tree_test import ( "testing" - . "github.com/mudler/luet/cmd/util" - . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) func TestTree(t *testing.T) { RegisterFailHandler(Fail) - LoadConfig() RunSpecs(t, "Tree Suite") } diff --git a/pkg/versioner/versioner_suite_test.go b/pkg/versioner/versioner_suite_test.go index c68e1b76..b0723726 100644 --- a/pkg/versioner/versioner_suite_test.go +++ b/pkg/versioner/versioner_suite_test.go @@ -18,14 +18,11 @@ package version_test import ( "testing" - . "github.com/mudler/luet/cmd/util" - . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) func TestVersioner(t *testing.T) { RegisterFailHandler(Fail) - LoadConfig() RunSpecs(t, "Versioner Suite") } diff --git a/tests/integration/01_simple.sh b/tests/integration/01_simple.sh index 3ee600d6..54cfb5b4 100755 --- a/tests/integration/01_simple.sh +++ b/tests/integration/01_simple.sh @@ -66,6 +66,7 @@ testInstall() { testReInstall() { output=$(luet install -y --config $tmpdir/luet.yaml test/c@1.0) + echo "$output" installst=$? assertEquals 'install test successfully' "$installst" "0" assertContains 'contains warning' "$output" 'No packages to install'